From ed23ec247de38565c424cd42977bd1f3a071a9a6 Mon Sep 17 00:00:00 2001 From: dfighter1985 Date: Mon, 2 Sep 2013 21:05:10 +0200 Subject: [PATCH] Render lightmaps with GLSL. --HG-- branch : gsoc2013-dfighter --- .../OpenGL3/driver_glsl_shader_generator.cpp | 63 +++++++++-------- .../nel/src/3d/driver/OpenGL3/driver_opengl.h | 1 - .../driver/OpenGL3/driver_opengl_material.cpp | 69 ++++++++++--------- .../driver/OpenGL3/driver_opengl_program.cpp | 12 ++++ .../driver/OpenGL3/driver_opengl_vertex.cpp | 5 ++ 5 files changed, 90 insertions(+), 60 deletions(-) diff --git a/code/nel/src/3d/driver/OpenGL3/driver_glsl_shader_generator.cpp b/code/nel/src/3d/driver/OpenGL3/driver_glsl_shader_generator.cpp index 5b9fb26c7..ef5246e8b 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_glsl_shader_generator.cpp +++ b/code/nel/src/3d/driver/OpenGL3/driver_glsl_shader_generator.cpp @@ -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; diff --git a/code/nel/src/3d/driver/OpenGL3/driver_opengl.h b/code/nel/src/3d/driver/OpenGL3/driver_opengl.h index d0c391fd8..234e04442 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_opengl.h +++ b/code/nel/src/3d/driver/OpenGL3/driver_opengl.h @@ -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 _LightMapLUT; diff --git a/code/nel/src/3d/driver/OpenGL3/driver_opengl_material.cpp b/code/nel/src/3d/driver/OpenGL3/driver_opengl_material.cpp index 775759285..e4aa2d38c 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_opengl_material.cpp +++ b/code/nel/src/3d/driver/OpenGL3/driver_opengl_material.cpp @@ -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() ) diff --git a/code/nel/src/3d/driver/OpenGL3/driver_opengl_program.cpp b/code/nel/src/3d/driver/OpenGL3/driver_opengl_program.cpp index 64d0a546e..c8fd44b22 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_opengl_program.cpp +++ b/code/nel/src/3d/driver/OpenGL3/driver_opengl_program.cpp @@ -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; diff --git a/code/nel/src/3d/driver/OpenGL3/driver_opengl_vertex.cpp b/code/nel/src/3d/driver/OpenGL3/driver_opengl_vertex.cpp index c023ba67a..1ee446e6b 100644 --- a/code/nel/src/3d/driver/OpenGL3/driver_opengl_vertex.cpp +++ b/code/nel/src/3d/driver/OpenGL3/driver_opengl_vertex.cpp @@ -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 + }