Render lightmaps with GLSL.

--HG--
branch : gsoc2013-dfighter
hg/feature/gsoc2013-dfighter
dfighter1985 12 years ago
parent 0ab6322955
commit ed23ec247d

@ -830,17 +830,21 @@ namespace NL3D
void CGLSLShaderGenerator::generateLightMapPS()
{
uint sampler = 0;
for( int i = TexCoord0; i < NumOffsets; i++ )
int ntextures = 0;
for( int i = TexCoord0; i < TexCoord4; i++ )
{
if( hasFlag( vbFormat, vertexFlags[ i ] ) )
{
ss << "uniform sampler2D sampler" << sampler;
ss << ";";
ss << std::endl;
}
sampler++;
ntextures++;
}
for( int i = 0; i < ntextures; i++ )
ss << "uniform sampler2D sampler" << i << ";" << std::endl;
ss << "uniform vec4 constant0;" << std::endl;
ss << "uniform vec4 constant1;" << std::endl;
ss << "uniform vec4 constant2;" << std::endl;
ss << "uniform vec4 constant3;" << std::endl;
ss << std::endl;
ss << "void main( void )" << std::endl;
@ -848,31 +852,36 @@ namespace NL3D
addDiffuse();
addConstants();
// Lightmap UV coords are at position 1
for( int i = 0; i < ntextures - 1; i++ )
{
ss << "vec4 texel" << i;
ss << " = texture2D( sampler" << i;
ss << ", " << attribNames[ TexCoord1 ] << " );" << std::endl;
}
// Color map UV coords are at position 0
ss << "vec4 texel" << ntextures - 1 << " = texture2D( sampler" << ntextures - 1 << ", " << attribNames[ TexCoord0 ] << " );" << std::endl;
sampler = 0;
for( int i = TexCoord0; i < NumOffsets; i++ )
//ss << "vec4 texel = diffuse;" << std::endl;
//ss << "vec4 texel = vec4( 1.0, 1.0, 1.0, 1.0 );" << std::endl;
ss << "vec4 texel = vec4( 0.0, 0.0, 0.0, 0.0 );" << std::endl;
// Lightmaps
for( int i = 0; i < ntextures - 1; i++ )
{
if( hasFlag( vbFormat, vertexFlags[ i ] ) )
{
ss << "vec4 texel" << sampler;
ss << " = texture2D( sampler" << sampler;
ss << ", " << attribNames[ i ] << " );" << std::endl;
}
sampler++;
ss << "texel.rgb = " << texelNames[ i ] << ".rgb * " << constantNames[ i ] << ".rgb + texel.rgb;" << std::endl;
ss << "texel.a = " << texelNames[ i ] << ".a * texel.a + texel.a;" << std::endl;
}
ss << "vec4 texel = diffuse;" << std::endl;
// Texture
ss << "texel.rgb = " << texelNames[ ntextures - 1 ] << ".rgb * texel.rgb;" << std::endl;
ss << "texel.a = " << texelNames[ ntextures - 1] << ".a;" << std::endl;
sampler = 0;
for( int i = TexCoord0; i < NumOffsets; i++ )
if( material->_LightMapsMulx2 )
{
if( hasFlag( vbFormat, vertexFlags[ i ] ) )
{
ss << "texel = ";
ss << texelNames[ sampler ] << " * " << constantNames[ sampler ] << " + texel;" << std::endl;
}
sampler++;
ss << "texel.rgb = texel.rgb * 2.0;" << std::endl;
ss << "texel.a = texel.a * 2.0;" << std::endl;
}
ss << "fragColor = texel;" << std::endl;

@ -1089,7 +1089,6 @@ private:
uint _NLightMaps;
uint _NLightMapPerPass;
uint _NLightMapPass;
bool _LightMapNoMulAddFallBack;
// This array is the LUT from lmapId in [0, _NLightMaps[, to original lightmap id in material.
std::vector<uint> _LightMapLUT;

@ -633,16 +633,6 @@ void CDriverGL3::computeLightMapInfos (const CMaterial &mat)
// Compute how many pass, according to driver caps.
_NLightMapPerPass = inlGetNumTextStages()-1;
// Can do more than 2 texture stages only if NVTextureEnvCombine4 or ATITextureEnvCombine3
if ( !_Extensions.ATITextureEnvCombine3 )
{
_NLightMapPerPass = 1;
_LightMapNoMulAddFallBack= true;
}
else
{
_LightMapNoMulAddFallBack= false;
}
// Number of pass.
_NLightMapPass = (_NLightMaps + _NLightMapPerPass-1)/(_NLightMapPerPass);
@ -682,6 +672,14 @@ sint CDriverGL3::beginLightMapMultiPass ()
return std::max (_NLightMapPass, (uint)1);
}
const char *constNames[ 4 ] =
{
"constant0",
"constant1",
"constant2",
"constant3"
};
// ***************************************************************************
void CDriverGL3::setupLightMapPass(uint pass)
{
@ -736,7 +734,6 @@ void CDriverGL3::setupLightMapPass(uint pass)
// For LMC (lightmap 8Bit compression) compute the total AmbientColor in vertex diffuse
// need only if standard MulADD version
if (!_LightMapNoMulAddFallBack)
{
uint32 r=0;
uint32 g=0;
@ -776,11 +773,7 @@ void CDriverGL3::setupLightMapPass(uint pass)
CRGBA lmapFactor = mat._LightMaps[whichLightMap].Factor;
// Modulate the factor with LightMap compression Diffuse
CRGBA lmcDiff= mat._LightMaps[whichLightMap].LMCDiffuse;
// FallBack if the (very common) extension for MulADD was not found
if(_LightMapNoMulAddFallBack)
{
lmcDiff.addRGBOnly(lmcDiff, mat._LightMaps[whichLightMap].LMCAmbient);
}
lmapFactor.R = (uint8)(((uint32)lmapFactor.R * ((uint32)lmcDiff.R+(lmcDiff.R>>7))) >>8);
lmapFactor.G = (uint8)(((uint32)lmapFactor.G * ((uint32)lmcDiff.G+(lmcDiff.G>>7))) >>8);
lmapFactor.B = (uint8)(((uint32)lmapFactor.B * ((uint32)lmcDiff.B+(lmcDiff.B>>7))) >>8);
@ -794,28 +787,27 @@ void CDriverGL3::setupLightMapPass(uint pass)
{
static CMaterial::CTexEnv stdEnv;
// fallBack if extension MulAdd not found. just mul factor with (Ambient+Diffuse)
if(_LightMapNoMulAddFallBack)
{
// do not use constant color to blend lightmap, but incoming diffuse color, for stage0 only.
GLfloat glcol[4];
convColor(lmapFactor, glcol);
_DriverGLStates.setEmissive(lmapFactor.getPacked(), glcol);
// Leave stage as default env (Modulate with previous)
activateTexEnvMode(stage, stdEnv);
// Setup gen tex off
_DriverGLStates.activeTextureARB(stage);
_DriverGLStates.setTexGenMode(stage, 0);
}
else
{
// Here, we are sure that texEnvCombine4 or texEnvCombine3 is OK.
nlassert( _Extensions.ATITextureEnvCombine3);
// setup constant color with Lightmap factor.
stdEnv.ConstantColor=lmapFactor;
#ifdef GLSL
int cl = getUniformLocation( constNames[ stage ] );
if( cl != -1 )
{
GLfloat glCol[ 4 ];
convColor( lmapFactor, glCol );
setUniform4f( cl, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ] );
}
int tl = getUniformLocation( samplers[ stage ] );
if( tl != -1 )
{
setUniform1i( tl, stage );
}
#endif
activateTexEnvColor(stage, stdEnv);
// Setup env for texture stage.
@ -878,6 +870,14 @@ void CDriverGL3::setupLightMapPass(uint pass)
_DriverGLStates.activeTextureARB(stage);
_DriverGLStates.setTexGenMode(stage, 0);
#ifdef GLSL
int tl = getUniformLocation( samplers[ stage ] );
if( tl != -1 )
{
setUniform1i( tl, stage );
}
#endif
// setup UV, with UV0. Only if needed (cached)
if( !_LastVertexSetupIsLightMap || _LightMapUVMap[stage]!=0 )
{
@ -885,11 +885,14 @@ void CDriverGL3::setupLightMapPass(uint pass)
_LightMapUVMap[stage]= 0;
}
#ifndef GLSL
if (mat._LightMapsMulx2)
{
// Multiply x 2
glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_EXT, 2);
}
#endif
}
}
else
@ -905,11 +908,13 @@ void CDriverGL3::setupLightMapPass(uint pass)
/* If multi-pass, then must setup a black Fog color for 1+ pass (just do it for the pass 1).
This is because Transparency ONE/ONE is used.
*/
#ifndef GLSL
if(pass==1 && _FogEnabled)
{
static GLfloat blackFog[4]= {0,0,0,0};
glFogfv(GL_FOG_COLOR, blackFog);
}
#endif
// Blend is different if the material is blended or not
if( !mat.getBlend() )

@ -213,6 +213,11 @@ namespace NL3D
case CMaterial::Normal:
setupNormalPass();
break;
case CMaterial::LightMap:
beginLightMapMultiPass();
setupLightMapPass( 0 );
break;
}
#endif
@ -221,6 +226,13 @@ namespace NL3D
void CDriverGL3::releaseProgram()
{
switch( _CurrentMaterial->getShader() )
{
case CMaterial::LightMap:
endLightMapMultiPass();
break;
}
delete p;
p = NULL;
vp = NULL;

@ -607,6 +607,8 @@ bool CDriverGL3::renderRawQuads(CMaterial& mat, uint32 startIndex, uint32 numQua
void CDriverGL3::setupUVPtr(uint stage, CVertexBufferInfo &VB, uint uvId)
{
#ifndef GLSL
H_AUTO_OGL(CDriverGL3_setupUVPtr)
// sould not be called with vertex program Array setuped.
nlassert(!_LastSetupGLArrayVertexProgram);
@ -633,6 +635,9 @@ void CDriverGL3::setupUVPtr(uint stage, CVertexBufferInfo &VB, uint uvId)
}
else
_DriverGLStates.enableTexCoordArray(false);
#endif
}

Loading…
Cancel
Save