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 b42f582f6..f1965d91c 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 @@ -93,7 +93,7 @@ namespace NL3D "texCoord7" }; - const char *texelNames[ 4 ] = + const char *texelNames[ SHADER_MAX_TEXTURES ] = { "texel0", "texel1", @@ -802,16 +802,13 @@ namespace NL3D void CGLSLShaderGenerator::generateNormalPS() { uint sampler = 0; - for( int i = TexCoord0; i < NumOffsets; i++ ) + for( int i = 0; i < SHADER_MAX_TEXTURES; i++ ) { - if( hasFlag( vbFormat, vertexFlags[ i ] ) ) - { - ss << "uniform sampler2D sampler" << sampler; - ss << ";"; - ss << std::endl; - } + if( desc->getUseTexStage( i ) ) + ss << "uniform sampler2D sampler" << sampler << ";" << std::endl; sampler++; } + addColor(); addConstants(); addAlphaTreshold(); @@ -840,13 +837,19 @@ namespace NL3D bool textures = false; sampler = 0; - for( int i = TexCoord0; i < NumOffsets; i++ ) + for( int i = 0; i < SHADER_MAX_TEXTURES; i++ ) { - if( hasFlag( vbFormat, vertexFlags[ i ] ) ) + if( desc->getUseTexStage( i ) ) { - ss << "vec4 texel" << sampler; - ss << " = texture2D( sampler" << sampler << ","; - ss << attribNames[ i ] << " );" << std::endl; + ss << "vec4 texel" << sampler << " = texture2D( sampler" << sampler << ","; + + if( !desc->getUseFirstTexCoords() ) + ss << attribNames[ TexCoord0 + i ] << " );"; + else + ss << attribNames[ TexCoord0 ] << " );"; + + ss << std::endl; + textures = true; } sampler++; @@ -888,14 +891,13 @@ namespace NL3D void CGLSLShaderGenerator::generateTexEnv() { uint32 stage = 0; - for( int i = TexCoord0; i < TexCoord4; i++ ) + for( int i = 0; i < SHADER_MAX_TEXTURES; i++ ) { - if( hasFlag( vbFormat, vertexFlags[ i ] ) ) + if( desc->getUseTexStage( i ) ) { generateTexEnvRGB( stage ); generateTexEnvAlpha( stage ); } - stage++; } } 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 a8b7ba116..b4be7cd0d 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_program.cpp +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_program.cpp @@ -31,6 +31,47 @@ namespace "constant3" }; + + uint16 vertexFlags[ NL3D::CVertexBuffer::NumValue ] = + { + NL3D::CVertexBuffer::PositionFlag, + NL3D::CVertexBuffer::WeightFlag, + NL3D::CVertexBuffer::NormalFlag, + NL3D::CVertexBuffer::PrimaryColorFlag, + NL3D::CVertexBuffer::SecondaryColorFlag, + NL3D::CVertexBuffer::FogFlag, + NL3D::CVertexBuffer::PaletteSkinFlag, + 0, + NL3D::CVertexBuffer::TexCoord0Flag, + NL3D::CVertexBuffer::TexCoord1Flag, + NL3D::CVertexBuffer::TexCoord2Flag, + NL3D::CVertexBuffer::TexCoord3Flag, + NL3D::CVertexBuffer::TexCoord4Flag, + NL3D::CVertexBuffer::TexCoord5Flag, + NL3D::CVertexBuffer::TexCoord6Flag, + NL3D::CVertexBuffer::TexCoord7Flag + }; + + enum AttribOffset + { + Position, + Weight, + Normal, + PrimaryColor, + SecondaryColor, + Fog, + PaletteSkin, + Empty, + TexCoord0, + TexCoord1, + TexCoord2, + TexCoord3, + TexCoord4, + TexCoord5, + TexCoord6, + TexCoord7, + NumOffsets + }; } namespace NL3D @@ -443,15 +484,35 @@ namespace NL3D if( mat.getShader() == CMaterial::LightMap ) desc.setNLightMaps( mat._LightMaps.size() ); - int i = 0; + //int i = 0; if( mat.getShader() == CMaterial::Normal ) { int maxTextures = std::min( int( SHADER_MAX_TEXTURES ), int( IDRV_MAT_MAXTEXTURES ) ); - for( i = 0; i < maxTextures; i++ ) + for( int i = 0; i < maxTextures; i++ ) { desc.setTexEnvMode( i, mat.getTexEnvMode( i ) ); } + + for( int i = 0; i < maxTextures; i++ ) + { + if( desc.hasVBFlags( vertexFlags[ TexCoord0 + i ] ) ) + { + desc.setUseTexStage( i, true ); + } + } + + if( !desc.getUseTexStage( 1 ) ) + { + for( int i = 1; i < maxTextures; i++ ) + { + if( mat.getTexture( i ) != NULL ) + { + desc.setUseTexStage( i, true ); + desc.setUseFirstTexCoords( true ); + } + } + } } if( mat.getAlphaTest() ) diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl_shader_desc.h b/code/nel/src/3d/driver/opengl3/driver_opengl_shader_desc.h index 3942b9165..42735e240 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_shader_desc.h +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_shader_desc.h @@ -92,6 +92,10 @@ namespace NL3D for( int i = 0; i < SHADER_MAX_LIGHTS; i++ ) lightMode[ i ] = Nolight; + for( int i = 0; i < SHADER_MAX_TEXTURES; i++ ) + useTextureStage[ i ] = false; + useFirstTextureCoordSet = false; + features = None; shaderType = Normal; vbFlags = 0; @@ -135,9 +139,16 @@ namespace NL3D if( shaderType == Normal ) { + if( useFirstTextureCoordSet != o.useFirstTextureCoordSet ) + return false; + for( int i = 0; i < SHADER_MAX_TEXTURES; i++ ) if( texEnvMode[ i ] != o.texEnvMode[ i ] ) return false; + + for( int i = 0; i < SHADER_MAX_TEXTURES; i++ ) + if( useTextureStage[ i ] != o.useTextureStage[ i ] ) + return false; } if( lightingEnabled() ) @@ -151,7 +162,21 @@ namespace NL3D } void setTexEnvMode( uint32 index, uint32 mode ){ texEnvMode[ index ] = mode; } + + void setUseFirstTexCoords( bool b ){ useFirstTextureCoordSet = b; } + bool getUseFirstTexCoords() const{ return useFirstTextureCoordSet; } + + void setUseTexStage( uint8 stage, bool b ){ useTextureStage[ stage ] = b; } + bool getUseTexStage( uint8 stage ) const{ return useTextureStage[ stage ]; } + void setVBFlags( uint32 flags ){ vbFlags = flags; } + bool hasVBFlags( uint32 flags ) const{ + if( ( vbFlags & flags ) != 0 ) + return true; + else + return false; + } + void setShaderType( uint32 type ){ shaderType = type; } void setNLightMaps( uint32 n ){ nlightmaps = n; } @@ -227,6 +252,8 @@ namespace NL3D uint32 features; uint32 texEnvMode[ SHADER_MAX_TEXTURES ]; + bool useTextureStage[ SHADER_MAX_TEXTURES ]; + bool useFirstTextureCoordSet; uint32 vbFlags; uint32 shaderType; uint32 nlightmaps;