From 75e650432fe1da629e5255049ab4f62e56fc0936 Mon Sep 17 00:00:00 2001 From: kaetemi Date: Sun, 30 Mar 2014 23:44:44 +0200 Subject: [PATCH] GL3: Cleanup and fix lighting state bug in pp --HG-- branch : opengl3 --- .../opengl3/driver_glsl_shader_generator.cpp | 273 +-- .../opengl3/driver_glsl_shader_generator.h | 1 + .../src/3d/driver/opengl3/driver_opengl.cpp | 4 +- .../nel/src/3d/driver/opengl3/driver_opengl.h | 15 +- .../3d/driver/opengl3/driver_opengl_light.cpp | 9 - .../driver/opengl3/driver_opengl_material.cpp | 44 +- .../driver/opengl3/driver_opengl_program.cpp | 1654 +++++++++-------- .../3d/driver/opengl3/driver_opengl_program.h | 74 + .../opengl3/driver_opengl_shader_desc.h | 21 +- .../3d/driver/opengl3/driver_opengl_states.h | 2 - .../opengl3/driver_opengl_vertex_program.cpp | 102 +- code/nel/src/3d/driver/opengl3/stdopengl.h | 2 + 12 files changed, 1121 insertions(+), 1080 deletions(-) create mode 100644 code/nel/src/3d/driver/opengl3/driver_opengl_program.h 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 1678390d9..63df018f4 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 @@ -14,101 +14,17 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -#include "sstream" +#include "stdopengl.h" #include "driver_glsl_shader_generator.h" -#include "nel/3d/vertex_buffer.h" -#include "driver_opengl_shader_desc.h" -namespace -{ - inline bool hasFlag(uint32 data, uint32 flag) - { - if ((data & flag) != 0) - return true; - else - return false; - } +#include - enum AttribOffset - { - Position, - Weight, - Normal, - PrimaryColor, - SecondaryColor, - Fog, - PaletteSkin, - Empty, - TexCoord0, - TexCoord1, - TexCoord2, - TexCoord3, - TexCoord4, - TexCoord5, - TexCoord6, - TexCoord7, - NumOffsets - }; -} +#include "nel/3d/vertex_buffer.h" +#include "driver_opengl_program.h" +#include "driver_opengl_shader_desc.h" namespace NL3D { - uint16 vertexFlags[ CVertexBuffer::NumValue ] = - { - CVertexBuffer::PositionFlag, - CVertexBuffer::WeightFlag, - CVertexBuffer::NormalFlag, - CVertexBuffer::PrimaryColorFlag, - CVertexBuffer::SecondaryColorFlag, - CVertexBuffer::FogFlag, - CVertexBuffer::PaletteSkinFlag, - 0, - CVertexBuffer::TexCoord0Flag, - CVertexBuffer::TexCoord1Flag, - CVertexBuffer::TexCoord2Flag, - CVertexBuffer::TexCoord3Flag, - CVertexBuffer::TexCoord4Flag, - CVertexBuffer::TexCoord5Flag, - CVertexBuffer::TexCoord6Flag, - CVertexBuffer::TexCoord7Flag - }; - - const char *attribNames[ CVertexBuffer::NumValue ] = - { - "position", - "weight", - "normal", - "color", - "color2", - "fog", - "paletteSkin", - "none", - "texCoord0", - "texCoord1", - "texCoord2", - "texCoord3", - "texCoord4", - "texCoord5", - "texCoord6", - "texCoord7" - }; - - const char *texelNames[ SHADER_MAX_TEXTURES ] = - { - "texel0", - "texel1", - "texel2", - "texel3" - }; - - const char *constantNames[ 4 ] = - { - "constant0", - "constant1", - "constant2", - "constant3" - }; - const char *shaderNames[] = { "Normal", @@ -130,6 +46,7 @@ namespace NL3D CGLSLShaderGenerator::~CGLSLShaderGenerator() { + } void CGLSLShaderGenerator::reset() @@ -156,14 +73,23 @@ namespace NL3D for (int i = Weight; i < NumOffsets; i++) { - if (hasFlag(vbFormat, vertexFlags[ i ])) + if (hasFlag(vbFormat, g_VertexFlags[i])) { ss << "smooth in vec4 "; - ss << attribNames[ i ] << ";" << std::endl; + ss << g_AttribNames[i] << ";" << std::endl; } } ss << std::endl; + /*if (desc->lightingEnabled()) // LIGHTING DEBUG + { + generateInvalidPS(); + } + else + { + generateNormalPS(); + }*/ + switch(material->getShader()) { case CMaterial::Normal: @@ -292,7 +218,7 @@ namespace NL3D void CGLSLShaderGenerator::addLightUniformsFS() { - for (int i = 0; i < SHADER_MAX_LIGHTS; i++) + for (int i = 0; i < NL_OPENGL3_MAX_LIGHT; i++) { switch(desc->getLight(i)) { @@ -364,7 +290,7 @@ namespace NL3D ss << "void main(void)" << std::endl; ss << "{" << std::endl; - ss << "vec4 eyePosition = modelView * v" << attribNames[ 0 ] << ";" << std::endl; + ss << "vec4 eyePosition = modelView * v" << g_AttribNames[ 0 ] << ";" << std::endl; if (desc->hasPointLight()) ss << "ecPos4 = eyePosition;" << std::endl; @@ -378,18 +304,18 @@ namespace NL3D ss << "vec4 t = vec4(cubeTexCoords, 1.0);" << std::endl; ss << "t = t * texMatrix0;" << std::endl; ss << "cubeTexCoords = t.xyz;" << std::endl; - ss << "gl_Position = modelViewProjection * v" << attribNames[ 0 ] << ";" << std::endl; + ss << "gl_Position = modelViewProjection * v" << g_AttribNames[ 0 ] << ";" << std::endl; if (desc->lightingEnabled()) addLightsVS(); for (int i = Weight; i < NumOffsets; i++) { - if (hasFlag(vbFormat, vertexFlags[ i ])) + if (hasFlag(vbFormat, g_VertexFlags[i])) { - ss << attribNames[ i ]; + ss << g_AttribNames[i]; ss << " = "; - ss << "v" << attribNames[ i ] << ";" << std::endl; + ss << "v" << g_AttribNames[i] << ";" << std::endl; } } @@ -415,15 +341,15 @@ namespace NL3D ss << "void main(void)" << std::endl; ss << "{" << std::endl; - ss << "gl_Position = modelViewProjection * v" << attribNames[ 0 ] << ";" << std::endl; + ss << "gl_Position = modelViewProjection * v" << g_AttribNames[ 0 ] << ";" << std::endl; for (int i = Weight; i < NumOffsets; i++) { - if (hasFlag(vbFormat, vertexFlags[ i ])) + if (hasFlag(vbFormat, g_VertexFlags[i])) { - ss << attribNames[ i ]; + ss << g_AttribNames[i]; ss << " = "; - ss << "v" << attribNames[ i ] << ";" << std::endl; + ss << "v" << g_AttribNames[i] << ";" << std::endl; } } @@ -514,10 +440,101 @@ namespace NL3D ss << "}" << std::endl; }*/ + void CGLSLShaderGenerator::generateInvalidPS() + { + /*uint sampler = 0; + for (int i = 0; i < IDRV_MAT_MAXTEXTURES; i++) + { + if (desc->getUseTexStage(i)) + ss << "uniform sampler2D sampler" << sampler << ";" << std::endl; + sampler++; + } + + addColor(); + addConstants(); + addAlphaTreshold(); + addFogUniform();*/ + + if (desc->fogEnabled()) + ss << "smooth in vec4 ecPos;" << std::endl; + + ss << std::endl; + + if (desc->lightingEnabled()) + { + addLightUniformsFS(); + addLightInsFS(); + ss << std::endl; + + addLightsFunctionFS(); + ss << std::endl; + } + + /*if (desc->fogEnabled()) + addFogFunction();*/ + + ss << "void main(void)" << std::endl; + ss << "{" << std::endl; + + /*bool textures = false; + sampler = 0; + for (int i = 0; i < IDRV_MAT_MAXTEXTURES; i++) + { + if (desc->getUseTexStage(i)) + { + ss << "vec4 texel" << sampler << " = texture(sampler" << sampler << ","; + + if (!desc->getUseFirstTexCoords()) + ss << g_AttribNames[ TexCoord0 + i ] << ".st);"; + else + ss << g_AttribNames[ TexCoord0 ] << ".st);"; + + ss << std::endl; + + textures = true; + } + sampler++; + } + + bool vertexColor = false; + if (hasFlag(vbFormat, g_VertexFlags[ PrimaryColor ])) + vertexColor = true; + + if (textures && !vertexColor) + ss << "vec4 texel = vec4(1.0, 1.0, 1.0, 1.0);" << std::endl; + else + if (vertexColor) + ss << "vec4 texel = color;" << std::endl; + else + ss << "vec4 texel = vec4(0.5, 0.5, 0.5, 1.0);" << std::endl; + + generateTexEnv(); + + // This is just an idea I had, but it seems to be working. + // Unfortunately it's not documented anywhere I looked in the GL spec, but if I don't have this modulation here, + // the Ryzom UI looks horrific. + if (vertexColor) + ss << "texel = color * texel;" << std::endl;*/ + + ss << "fragColor = vec4(1.0, 1.0, 1.0, 1.0);" << std::endl; + + if (desc->lightingEnabled()) + addLightsFS(); + + ss << "fragColor = fragColor + vec4(0.0, 0.25, 0.0, 0.0);" << std::endl; + + /*if (desc->fogEnabled()) + addFog(); + + addAlphaTest();*/ + + ss << "}" << std::endl; + } + void CGLSLShaderGenerator::generateNormalPS() { uint sampler = 0; - for (int i = 0; i < SHADER_MAX_TEXTURES; i++) + for (int i = 0; i < IDRV_MAT_MAXTEXTURES; i++) { if (desc->getUseTexStage(i)) ss << "uniform sampler2D sampler" << sampler << ";" << std::endl; @@ -552,16 +569,16 @@ namespace NL3D bool textures = false; sampler = 0; - for (int i = 0; i < SHADER_MAX_TEXTURES; i++) + for (int i = 0; i < IDRV_MAT_MAXTEXTURES; i++) { if (desc->getUseTexStage(i)) { ss << "vec4 texel" << sampler << " = texture(sampler" << sampler << ","; if (!desc->getUseFirstTexCoords()) - ss << attribNames[ TexCoord0 + i ] << ".st);"; + ss << g_AttribNames[ TexCoord0 + i ] << ".st);"; else - ss << attribNames[ TexCoord0 ] << ".st);"; + ss << g_AttribNames[ TexCoord0 ] << ".st);"; ss << std::endl; @@ -571,7 +588,7 @@ namespace NL3D } bool vertexColor = false; - if (hasFlag(vbFormat, vertexFlags[ PrimaryColor ])) + if (hasFlag(vbFormat, g_VertexFlags[ PrimaryColor ])) vertexColor = true; if (textures && !vertexColor) @@ -606,7 +623,7 @@ namespace NL3D void CGLSLShaderGenerator::generateTexEnv() { uint32 stage = 0; - for (int i = 0; i < SHADER_MAX_TEXTURES; i++) + for (int i = 0; i < IDRV_MAT_MAXTEXTURES; i++) { if (desc->getUseTexStage(i)) { @@ -623,7 +640,7 @@ namespace NL3D std::string arg1; std::string arg2; - switch(material->_TexEnvs[ stage ].Env.OpRGB) + switch(material->_TexEnvs[stage].Env.OpRGB) { case CMaterial::Replace: { @@ -674,7 +691,7 @@ namespace NL3D buildArg(stage, 0, false, arg0); buildArg(stage, 1, false, arg1); - std::string As = texelNames[ stage ]; + std::string As = g_TexelNames[stage]; As.append(".a"); ss << "texel.rgb = " << arg0 << " * " << As << ";" << std::endl; @@ -711,7 +728,7 @@ namespace NL3D buildArg(stage, 0, false, arg0); buildArg(stage, 1, false, arg1); - std::string As = constantNames[ stage ]; + std::string As = g_ConstantNames[stage]; As.append(".a"); ss << "texel.rgb = " << arg0 << " * " << As << ";" << std::endl; @@ -727,7 +744,7 @@ namespace NL3D std::string arg1; std::string arg2; - switch(material->_TexEnvs[ stage ].Env.OpRGB) + switch(material->_TexEnvs[stage].Env.OpRGB) { case CMaterial::Replace: { @@ -777,7 +794,7 @@ namespace NL3D buildArg(stage, 0, true, arg0); buildArg(stage, 1, true, arg1); - std::string As = texelNames[ stage ]; + std::string As = g_TexelNames[stage]; As.append(".a"); ss << "texel.a = " << arg0 << " * " << As << ";" << std::endl; @@ -814,7 +831,7 @@ namespace NL3D buildArg(stage, 0, true, arg0); buildArg(stage, 1, true, arg1); - std::string As = constantNames[ stage ]; + std::string As = g_ConstantNames[stage]; As.append(".a"); ss << "texel.a = " << arg0 << " * " << As << ";" << std::endl; @@ -851,21 +868,21 @@ namespace NL3D switch(op) { case CMaterial::SrcColor: - ds << texelNames[ stage ] << ".rgb"; + ds << g_TexelNames[stage] << ".rgb"; break; case CMaterial::InvSrcColor: ds << "(vec3(1.0, 1.0, 1.0) - "; - ds << texelNames[ stage ] << ".rgb)"; + ds << g_TexelNames[stage] << ".rgb)"; break; case CMaterial::SrcAlpha: - ds << texelNames[ stage ] << ".a"; + ds << g_TexelNames[stage] << ".a"; break; case CMaterial::InvSrcAlpha: ds << "(1.0 - "; - ds << texelNames[ stage ] << ".a)"; + ds << g_TexelNames[stage] << ".a)"; break; } } @@ -920,19 +937,19 @@ namespace NL3D switch(op) { case CMaterial::SrcColor: - ds << constantNames[ stage ] << ".rgb"; + ds << g_ConstantNames[stage] << ".rgb"; break; case CMaterial::InvSrcColor: - ds << "(vec3(1.0, 1.0, 1.0) - " << constantNames[ stage ] << ".rgb)"; + ds << "(vec3(1.0, 1.0, 1.0) - " << g_ConstantNames[stage] << ".rgb)"; break; case CMaterial::SrcAlpha: - ds << constantNames[ stage ] << ".a"; + ds << g_ConstantNames[stage] << ".a"; break; case CMaterial::InvSrcAlpha: - ds << "(1.0 - " << constantNames[ stage ] << ".a)"; + ds << "(1.0 - " << g_ConstantNames[stage] << ".a)"; break; } break; @@ -950,7 +967,7 @@ namespace NL3D int ntextures = 0; for (int i = TexCoord0; i < TexCoord4; i++) { - if (hasFlag(vbFormat, vertexFlags[ i ])) + if (hasFlag(vbFormat, g_VertexFlags[i])) ntextures++; } @@ -993,11 +1010,11 @@ namespace NL3D { ss << "vec4 texel" << i; ss << " = texture(sampler" << i; - ss << ", " << attribNames[ TexCoord1 ] << ".st);" << std::endl; + ss << ", " << g_AttribNames[ TexCoord1 ] << ".st);" << std::endl; } // Color map UV coords are at position 0 - ss << "vec4 texel" << ntextures - 1 << " = texture(sampler" << ntextures - 1 << ", " << attribNames[ TexCoord0 ] << ".st);" << std::endl; + ss << "vec4 texel" << ntextures - 1 << " = texture(sampler" << ntextures - 1 << ", " << g_AttribNames[ TexCoord0 ] << ".st);" << std::endl; //ss << "vec4 texel = diffuseColor;" << std::endl; //ss << "vec4 texel = vec4(1.0, 1.0, 1.0, 1.0);" << std::endl; @@ -1006,13 +1023,13 @@ namespace NL3D // Lightmaps for (int i = 0; i < ntextures - 1; i++) { - 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 << "texel.rgb = " << g_TexelNames[i] << ".rgb * " << g_ConstantNames[i] << ".rgb + texel.rgb;" << std::endl; + ss << "texel.a = " << g_TexelNames[i] << ".a * texel.a + texel.a;" << std::endl; } // Texture - ss << "texel.rgb = " << texelNames[ ntextures - 1 ] << ".rgb * texel.rgb;" << std::endl; - ss << "texel.a = " << texelNames[ ntextures - 1] << ".a;" << std::endl; + ss << "texel.rgb = " << g_TexelNames[ ntextures - 1 ] << ".rgb * texel.rgb;" << std::endl; + ss << "texel.a = " << g_TexelNames[ ntextures - 1] << ".a;" << std::endl; if (material->_LightMapsMulx2) { diff --git a/code/nel/src/3d/driver/opengl3/driver_glsl_shader_generator.h b/code/nel/src/3d/driver/opengl3/driver_glsl_shader_generator.h index a7f63ee84..1528abca1 100644 --- a/code/nel/src/3d/driver/opengl3/driver_glsl_shader_generator.h +++ b/code/nel/src/3d/driver/opengl3/driver_glsl_shader_generator.h @@ -124,6 +124,7 @@ namespace NL3D /////////////////////////////////////// Pixel Shader generation /////////////////////////////////////// + void generateInvalidPS(); void generateNormalPS(); diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl.cpp b/code/nel/src/3d/driver/opengl3/driver_opengl.cpp index 907b624ee..0eab0a799 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl3/driver_opengl.cpp @@ -487,7 +487,7 @@ bool CDriverGL3::stretchRect(ITexture * /* srcText */, NLMISC::CRect &/* srcRect // *************************************************************************** bool CDriverGL3::supportBloomEffect() const { - return false; // FIXME GL3 + return false; // FIXME GL3 // _Extensions.GLCore; } // *************************************************************************** @@ -1156,7 +1156,7 @@ bool CDriverGL3::supportPerPixelLighting(bool specular) const { H_AUTO_OGL(CDriverGL3_supportPerPixelLighting) - return _Extensions.GLCore; + return false; // FIXME GL3 // _Extensions.GLCore; } // *************************************************************************** diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl.h b/code/nel/src/3d/driver/opengl3/driver_opengl.h index 606a6b167..eae73e208 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl3/driver_opengl.h @@ -1311,9 +1311,6 @@ private: private: - // The last vertex program that was setupped - NLMISC::CRefPtr _LastSetuppedVP; - bool _ForceDXTCCompression; /// Divisor for textureResize (power). uint _ForceTextureResizePower; @@ -1351,13 +1348,13 @@ private: uint32 ppoId; - CVertexProgram *m_UserVertexProgram; - CGeometryProgram *m_UserGeometryProgram; - CPixelProgram *m_UserPixelProgram; + NLMISC::CRefPtr m_UserVertexProgram; + NLMISC::CRefPtr m_UserGeometryProgram; + NLMISC::CRefPtr m_UserPixelProgram; - CVertexProgram *m_DriverVertexProgram; - CGeometryProgram *m_DriverGeometryProgram; - CPixelProgram *m_DriverPixelProgram; + NLMISC::CRefPtr m_DriverVertexProgram; + NLMISC::CRefPtr m_DriverGeometryProgram; + NLMISC::CRefPtr m_DriverPixelProgram; std::set m_VPBuiltinCache; CVPBuiltin m_VPBuiltinCurrent; diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl_light.cpp b/code/nel/src/3d/driver/opengl3/driver_opengl_light.cpp index 949cc651b..2e7f37d22 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_light.cpp +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_light.cpp @@ -200,15 +200,6 @@ void CDriverGL3::setupLightMapDynamicLighting(bool enable) } } -void CDriverGL3::disableAllLights() -{ - for (int i = 0; i < MaxLight; ++i) - { - _UserLightEnable[i] = false; - touchLightVP(i); - } -} - #ifdef NL_STATIC } // NLDRIVERGL3 #endif 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 cf96c6d23..0aed0a99b 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_material.cpp +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_material.cpp @@ -244,6 +244,7 @@ bool CDriverGL3::setupMaterial(CMaterial& mat) } CShaderGL3* pShader; + CMaterial::TShader matShader; GLenum glenum = GL_ZERO; uint32 touched = mat.getTouched(); uint stage; @@ -319,14 +320,25 @@ bool CDriverGL3::setupMaterial(CMaterial& mat) mat.clearTouched(0xFFFFFFFF); } - // Now we can get the supported shader from the cache. - CMaterial::TShader matShader = pShader->SupportedShader; + // 2b. User supplied pixel shader overrides material + //================================== + if (m_UserPixelProgram) + { + matShader = CMaterial::Program; + } + else + { + // Now we can get the supported shader from the cache. + matShader = pShader->SupportedShader; + } + // 2b. Update more shader state + //================================== // if the shader has changed since last time if (matShader != _CurrentMaterialSupportedShader) { // if old was lightmap, restore standard lighting - if (_CurrentMaterialSupportedShader==CMaterial::LightMap) + if (_CurrentMaterialSupportedShader == CMaterial::LightMap) setupLightMapDynamicLighting(false); // if new is lightmap, setup dynamic lighting @@ -335,14 +347,14 @@ bool CDriverGL3::setupMaterial(CMaterial& mat) } // setup the global - _CurrentMaterialSupportedShader= matShader; + _CurrentMaterialSupportedShader = matShader; // 2. Setup / Bind Textures. //========================== // Must setup textures each frame. (need to test if touched). // Must separate texture setup and texture activation in 2 "for"... // because setupTexture() may disable all stage. - if (matShader != CMaterial::Water) + if (matShader != CMaterial::Water && matShader != CMaterial::Program) { for (stage=0 ; stage !CullFace. - uint32 twoSided= mat.getFlags()&IDRV_MAT_DOUBLE_SIDED; - _DriverGLStates.enableCullFace(twoSided==0); + uint32 twoSided = mat.getFlags() & IDRV_MAT_DOUBLE_SIDED; + _DriverGLStates.enableCullFace(twoSided == 0); // Alpha Test Part. //================= - uint32 alphaTest= mat.getFlags()&IDRV_MAT_ALPHA_TEST; + uint32 alphaTest = mat.getFlags() & IDRV_MAT_ALPHA_TEST; _DriverGLStates.enableAlphaTest(alphaTest); if (alphaTest) { @@ -420,9 +433,9 @@ bool CDriverGL3::setupMaterial(CMaterial& mat) // Bind ZBuffer Part. //=================== - _DriverGLStates.enableZWrite(mat.getFlags()&IDRV_MAT_ZWRITE); + _DriverGLStates.enableZWrite(mat.getFlags() & IDRV_MAT_ZWRITE); _DriverGLStates.depthFunc(pShader->ZComp); - _DriverGLStates.setZBias (mat.getZBias () * _OODeltaZ); + _DriverGLStates.setZBias(mat.getZBias() * _OODeltaZ); // Bind Stencil Buffer Part. //=================== @@ -436,12 +449,7 @@ bool CDriverGL3::setupMaterial(CMaterial& mat) //===================== // Light Part. - enableLightingVP(mat.getFlags() & IDRV_MAT_LIGHTING); - - if ((mat.getFlags() & IDRV_MAT_LIGHTING) == 0) - disableAllLights(); - if (mat.getFlags()&IDRV_MAT_LIGHTING) { _DriverGLStates.setEmissive(pShader->PackedEmissive, pShader->Emissive); @@ -454,6 +462,10 @@ bool CDriverGL3::setupMaterial(CMaterial& mat) } else { + // Color unlit + // CRGBA col= mat.getColor(); + // glColor4ub(col.R, col.G, col.B, col.A); + _DriverGLStates.setVertexColorLighted(false); } @@ -479,7 +491,7 @@ bool CDriverGL3::setupMaterial(CMaterial& mat) //===================================== // Textures user matrix - if (matShader == CMaterial::Normal) + if (matShader == CMaterial::Normal || matShader == CMaterial::Program) { setupUserTextureMatrix(inlGetNumTextStages(), mat); } 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 a25874c47..d66449a0a 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_program.cpp +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_program.cpp @@ -15,1069 +15,1105 @@ // along with this program. If not, see . #include "driver_opengl.h" +#include "driver_opengl_program.h" #include "driver_glsl_shader_generator.h" #include "driver_opengl_vertex_buffer_hard.h" #include "nel/3d/dynamic_material.h" #include "nel/3d/usr_shader_manager.h" #include "nel/3d/usr_shader_program.h" -namespace + +namespace NL3D { + +#ifdef NL_STATIC +namespace NLDRIVERGL3 { +#endif + +const uint16 g_VertexFlags[CVertexBuffer::NumValue] = { - const char *constNames[ NL3D::IDRV_MAT_MAXTEXTURES ] = - { - "constant0", - "constant1", - "constant2", - "constant3" - }; + CVertexBuffer::PositionFlag, + CVertexBuffer::WeightFlag, + CVertexBuffer::NormalFlag, + CVertexBuffer::PrimaryColorFlag, + CVertexBuffer::SecondaryColorFlag, + CVertexBuffer::FogFlag, + CVertexBuffer::PaletteSkinFlag, + 0, + CVertexBuffer::TexCoord0Flag, + CVertexBuffer::TexCoord1Flag, + CVertexBuffer::TexCoord2Flag, + CVertexBuffer::TexCoord3Flag, + CVertexBuffer::TexCoord4Flag, + CVertexBuffer::TexCoord5Flag, + CVertexBuffer::TexCoord6Flag, + CVertexBuffer::TexCoord7Flag +}; + +const char *g_AttribNames[CVertexBuffer::NumValue] = +{ + "position", + "weight", + "normal", + "color", + "color2", + "fog", + "paletteSkin", + "none", + "texCoord0", + "texCoord1", + "texCoord2", + "texCoord3", + "texCoord4", + "texCoord5", + "texCoord6", + "texCoord7" +}; + +const char *g_TexelNames[IDRV_MAT_MAXTEXTURES] = +{ + "texel0", + "texel1", + "texel2", + "texel3" +}; +const char *g_ConstantNames[4] = +{ + "constant0", + "constant1", + "constant2", + "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 - }; +bool CDriverGL3::supportVertexProgram(CVertexProgram::TProfile profile) const +{ + if (profile == IProgram::glsl330v) + return true; + else + return false; } -namespace NL3D +bool CDriverGL3::compileVertexProgram(CVertexProgram *program) { - bool CDriverGL3::supportVertexProgram(CVertexProgram::TProfile profile) const + if (program->m_DrvInfo != NULL) + return false; + + IProgram::CSource *src = NULL; + for (int i = 0; i < program->getSourceNb(); i++) { - if (profile == IProgram::glsl330v) - return true; - else - return false; + src = program->getSource(i); + if (src->Profile == IProgram::glsl330v) + break; + + src = NULL; } + if (src == NULL) + return false; - bool CDriverGL3::compileVertexProgram(CVertexProgram *program) - { - if (program->m_DrvInfo != NULL) - return false; + const char *s = src->SourcePtr; + glGetError(); + unsigned int id = nglCreateShaderProgramv(GL_VERTEX_SHADER, 1, &s); + + if (id == 0) + return false; - IProgram::CSource *src = NULL; - for (int i = 0; i < program->getSourceNb(); i++) + GLint ok; + nglGetProgramiv(id, GL_LINK_STATUS, &ok); + if (ok == 0) + { + char errorLog[ 1024 ]; + nglGetProgramInfoLog(id, 1024, NULL, errorLog); + nlwarning("GL3: %s", errorLog); + std::vector lines; + NLMISC::explode(std::string(src->SourcePtr), std::string("\n"), lines); + for (std::vector::size_type i = 0; i < lines.size(); ++i) { - src = program->getSource(i); - if (src->Profile == IProgram::glsl330v) - break; - - src = NULL; + nldebug("GL3: %i: %s", i, lines[i].c_str()); } - if (src == NULL) - return false; + return false; + } - const char *s = src->SourcePtr; - glGetError(); - unsigned int id = nglCreateShaderProgramv(GL_VERTEX_SHADER, 1, &s); - if (id == 0) - return false; + GLenum error = glGetError(); + if (error != GL_NO_ERROR) + return false; - GLint ok; - nglGetProgramiv(id, GL_LINK_STATUS, &ok); - if (ok == 0) - { - char errorLog[ 1024 ]; - nglGetProgramInfoLog(id, 1024, NULL, errorLog); - nlwarning("GL3: %s", errorLog); - std::vector lines; - NLMISC::explode(std::string(src->SourcePtr), std::string("\n"), lines); - for (std::vector::size_type i = 0; i < lines.size(); ++i) - { - nldebug("GL3: %i: %s", i, lines[i].c_str()); - } - return false; - } + ItGPUPrgDrvInfoPtrList it = _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(),(NL3D::IProgramDrvInfos*)NULL); + CVertexProgramDrvInfosGL3 *drvInfo = new CVertexProgramDrvInfosGL3(this, it); + *it = drvInfo; + program->m_DrvInfo = drvInfo; - GLenum error = glGetError(); - if (error != GL_NO_ERROR) - return false; + drvInfo->setProgramId(id); - ItGPUPrgDrvInfoPtrList it = _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(),(NL3D::IProgramDrvInfos*)NULL); - CVertexProgramDrvInfosGL3 *drvInfo = new CVertexProgramDrvInfosGL3(this, it); - *it = drvInfo; + program->buildInfo(src); - program->m_DrvInfo = drvInfo; + return true; +} - drvInfo->setProgramId(id); +bool CDriverGL3::activeVertexProgram(CVertexProgram *program) +{ + return activeVertexProgram(program, false); +} - program->buildInfo(src); +bool CDriverGL3::activeVertexProgram(CVertexProgram *program, bool driver) +{ + if (driver) nlassert(m_UserVertexProgram == NULL); + if (m_DriverVertexProgram == program) return true; - } - bool CDriverGL3::activeVertexProgram(CVertexProgram *program) + if (program == NULL) { - return activeVertexProgram(program, false); + nglUseProgramStages(ppoId, GL_VERTEX_SHADER_BIT, 0); + m_UserVertexProgram = NULL; + m_DriverVertexProgram = NULL; + return true; } - bool CDriverGL3::activeVertexProgram(CVertexProgram *program, bool driver) + IProgramDrvInfos *di = program->m_DrvInfo; + CVertexProgramDrvInfosGL3 *drvInfo = dynamic_cast< CVertexProgramDrvInfosGL3* >(di); + if (drvInfo == NULL) { - if (driver) nlassert(m_UserVertexProgram == NULL); - - if (m_DriverVertexProgram == program) - return true; + m_UserVertexProgram = NULL; + m_DriverVertexProgram = NULL; + return false; + } + glGetError(); - if (program == NULL) - { - nglUseProgramStages(ppoId, GL_VERTEX_SHADER_BIT, 0); - m_UserVertexProgram = NULL; - m_DriverVertexProgram = NULL; - return true; - } + nglUseProgramStages(ppoId, GL_VERTEX_SHADER_BIT, drvInfo->getProgramId()); + GLenum error = glGetError(); + if (error != GL_NO_ERROR) + { + m_UserVertexProgram = NULL; + m_DriverVertexProgram = NULL; + return false; + } - IProgramDrvInfos *di = program->m_DrvInfo; - CVertexProgramDrvInfosGL3 *drvInfo = dynamic_cast< CVertexProgramDrvInfosGL3* >(di); - if (drvInfo == NULL) - return false; - glGetError(); + if (!driver) m_UserVertexProgram = program; + m_DriverVertexProgram = program; + return true; +} - nglUseProgramStages(ppoId, GL_VERTEX_SHADER_BIT, drvInfo->getProgramId()); - GLenum error = glGetError(); - if (error != GL_NO_ERROR) - return false; +bool CDriverGL3::supportPixelProgram(IProgram::TProfile profile) const +{ + if (profile == IProgram::glsl330f) + return true; + else + return false; +} - if (!driver) m_UserVertexProgram = program; - m_DriverVertexProgram = program; +bool CDriverGL3::compilePixelProgram(CPixelProgram *program) +{ + if (program->m_DrvInfo != NULL) + return false; - return true; - } + IProgram::CSource *src = NULL; - bool CDriverGL3::supportPixelProgram(IProgram::TProfile profile) const + for (int i = 0; i < program->getSourceNb(); i++) { - if (profile == IProgram::glsl330f) - return true; - else - return false; + src = program->getSource(i); + if (src->Profile == IProgram::glsl330f) + break; + + src = NULL; } - bool CDriverGL3::compilePixelProgram(CPixelProgram *program) - { - if (program->m_DrvInfo != NULL) - return false; + if (src == NULL) + return false; - IProgram::CSource *src = NULL; + const char *s = src->SourcePtr; + glGetError(); + unsigned int id = nglCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &s); + if (id == 0) + return false; - for (int i = 0; i < program->getSourceNb(); i++) + GLint ok; + nglGetProgramiv(id, GL_LINK_STATUS, &ok); + if (ok == 0) + { + char errorLog[ 1024 ]; + nglGetProgramInfoLog(id, 1024, NULL, errorLog); + nlwarning("GL3: %s", errorLog); + std::vector lines; + NLMISC::explode(std::string(src->SourcePtr), std::string("\n"), lines); + for (std::vector::size_type i = 0; i < lines.size(); ++i) { - src = program->getSource(i); - if (src->Profile == IProgram::glsl330f) - break; - - src = NULL; + nldebug("GL3: %i: %s", i, lines[i].c_str()); } + return false; + } - if (src == NULL) - return false; + GLenum error = glGetError(); + if (error != GL_NO_ERROR) + return false; - const char *s = src->SourcePtr; - glGetError(); - unsigned int id = nglCreateShaderProgramv(GL_FRAGMENT_SHADER, 1, &s); - if (id == 0) - return false; + ItGPUPrgDrvInfoPtrList it = _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IProgramDrvInfos*)NULL); + CPixelProgramDrvInfosGL3 *drvInfo = new CPixelProgramDrvInfosGL3(this, it); + *it = drvInfo; + drvInfo->setProgramId(id); + program->m_DrvInfo = drvInfo; - GLint ok; - nglGetProgramiv(id, GL_LINK_STATUS, &ok); - if (ok == 0) - { - char errorLog[ 1024 ]; - nglGetProgramInfoLog(id, 1024, NULL, errorLog); - nlwarning("GL3: %s", errorLog); - std::vector lines; - NLMISC::explode(std::string(src->SourcePtr), std::string("\n"), lines); - for (std::vector::size_type i = 0; i < lines.size(); ++i) - { - nldebug("GL3: %i: %s", i, lines[i].c_str()); - } - return false; - } + program->buildInfo(src); - GLenum error = glGetError(); - if (error != GL_NO_ERROR) - return false; + return true; +} - ItGPUPrgDrvInfoPtrList it = _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IProgramDrvInfos*)NULL); - CPixelProgramDrvInfosGL3 *drvInfo = new CPixelProgramDrvInfosGL3(this, it); - *it = drvInfo; - drvInfo->setProgramId(id); - program->m_DrvInfo = drvInfo; +bool CDriverGL3::activePixelProgram(CPixelProgram *program) +{ + return activePixelProgram(program, false); +} - program->buildInfo(src); +bool CDriverGL3::activePixelProgram(CPixelProgram *program, bool driver) +{ + if (driver) nlassert(m_UserPixelProgram == NULL); + if (m_DriverPixelProgram == program) return true; - } - bool CDriverGL3::activePixelProgram(CPixelProgram *program) + if (program == NULL) { - return activePixelProgram(program, false); + nglUseProgramStages(ppoId, GL_FRAGMENT_SHADER_BIT, 0); + m_UserPixelProgram = NULL; + m_DriverPixelProgram = NULL; + return true; } - bool CDriverGL3::activePixelProgram(CPixelProgram *program, bool driver) + if (program->m_DrvInfo == NULL) { - if (driver) nlassert(m_UserPixelProgram == NULL); - - if (m_DriverPixelProgram == program) - return true; - - if (program == NULL) - { - nglUseProgramStages(ppoId, GL_FRAGMENT_SHADER_BIT, 0); - m_UserPixelProgram = NULL; - m_DriverPixelProgram = NULL; - return true; - } - - if (program->m_DrvInfo == NULL) - return false; - - IProgramDrvInfos *di = program->m_DrvInfo; - CPixelProgramDrvInfosGL3 *drvInfo = dynamic_cast< CPixelProgramDrvInfosGL3* >(di); - if (drvInfo == NULL) - return false; - glGetError(); + m_UserPixelProgram = NULL; + m_DriverPixelProgram = NULL; + return false; + } + + IProgramDrvInfos *di = program->m_DrvInfo; + CPixelProgramDrvInfosGL3 *drvInfo = dynamic_cast< CPixelProgramDrvInfosGL3* >(di); + if (drvInfo == NULL) + { + m_UserPixelProgram = NULL; + m_DriverPixelProgram = NULL; + return false; + } + glGetError(); - nglUseProgramStages(ppoId, GL_FRAGMENT_SHADER_BIT, drvInfo->getProgramId()); - GLenum error = glGetError(); - if (error != GL_NO_ERROR) - return false; + nglUseProgramStages(ppoId, GL_FRAGMENT_SHADER_BIT, drvInfo->getProgramId()); + GLenum error = glGetError(); + if (error != GL_NO_ERROR) + { + m_UserPixelProgram = NULL; + m_DriverPixelProgram = NULL; + return false; + } - if (!driver) m_UserPixelProgram = program; - m_DriverPixelProgram = program; + if (!driver) m_UserPixelProgram = program; + m_DriverPixelProgram = program; + return true; +} - return true; - } +uint32 CDriverGL3::getProgramId(TProgram program) const +{ + uint32 id = 0; - uint32 CDriverGL3::getProgramId(TProgram program) const + switch(program) { - uint32 id = 0; - - switch(program) + case IDriver::VertexProgram: + if (m_DriverVertexProgram) { - case IDriver::VertexProgram: - if (m_DriverVertexProgram) - { - IProgramDrvInfos *di = m_DriverVertexProgram->m_DrvInfo; - CVertexProgramDrvInfosGL3 *drvInfo = dynamic_cast< CVertexProgramDrvInfosGL3* >(di); - if (drvInfo != NULL) - id = drvInfo->getProgramId(); - } - break; - - case IDriver::PixelProgram: - if (m_DriverPixelProgram) - { - IProgramDrvInfos *di = m_DriverPixelProgram->m_DrvInfo; - CPixelProgramDrvInfosGL3 *drvInfo = dynamic_cast< CPixelProgramDrvInfosGL3* >(di); - if (drvInfo != NULL) - id = drvInfo->getProgramId(); - } - break; - - case IDriver::GeometryProgram: - break; + IProgramDrvInfos *di = m_DriverVertexProgram->m_DrvInfo; + CVertexProgramDrvInfosGL3 *drvInfo = dynamic_cast< CVertexProgramDrvInfosGL3* >(di); + if (drvInfo != NULL) + id = drvInfo->getProgramId(); } + break; - return id; - } - - IProgram* CDriverGL3::getProgram(TProgram program) const - { - switch(program) + case IDriver::PixelProgram: + if (m_DriverPixelProgram) { - case IDriver::VertexProgram: - return m_DriverVertexProgram; - case IDriver::PixelProgram: - return m_DriverPixelProgram; - case IDriver::GeometryProgram: - return m_DriverGeometryProgram; + IProgramDrvInfos *di = m_DriverPixelProgram->m_DrvInfo; + CPixelProgramDrvInfosGL3 *drvInfo = dynamic_cast< CPixelProgramDrvInfosGL3* >(di); + if (drvInfo != NULL) + id = drvInfo->getProgramId(); } + break; - return NULL; + case IDriver::GeometryProgram: + break; } - int CDriverGL3::getUniformLocation(TProgram program, const char *name) - { - uint32 id = getProgramId(program); - return nglGetUniformLocation(id, name); - } + return id; +} - void CDriverGL3::setUniform1f(TProgram program, uint index, float f0) +IProgram* CDriverGL3::getProgram(TProgram program) const +{ + switch(program) { - uint32 id = getProgramId(program); - nglProgramUniform1f(id, index, f0); + case IDriver::VertexProgram: + return m_DriverVertexProgram; + case IDriver::PixelProgram: + return m_DriverPixelProgram; + case IDriver::GeometryProgram: + return m_DriverGeometryProgram; } - void CDriverGL3::setUniform2f(TProgram program, uint index, float f0, float f1) - { - uint32 id = getProgramId(program); - nglProgramUniform2f(id, index, f0, f1); - } + return NULL; +} - void CDriverGL3::setUniform3f(TProgram program, uint index, float f0, float f1, float f2) - { - uint32 id = getProgramId(program); - nglProgramUniform3f(id, index, f0, f1, f2); - } +int CDriverGL3::getUniformLocation(TProgram program, const char *name) +{ + uint32 id = getProgramId(program); + return nglGetUniformLocation(id, name); +} - void CDriverGL3::setUniform4f(TProgram program, uint index, float f0, float f1, float f2, float f3) - { - uint32 id = getProgramId(program); - nglProgramUniform4f(id, index, f0, f1, f2, f3); - } +void CDriverGL3::setUniform1f(TProgram program, uint index, float f0) +{ + uint32 id = getProgramId(program); + nglProgramUniform1f(id, index, f0); +} - void CDriverGL3::setUniform1i(TProgram program, uint index, sint32 i0) - { - uint32 id = getProgramId(program); - nglProgramUniform1i(id, index, i0); - } +void CDriverGL3::setUniform2f(TProgram program, uint index, float f0, float f1) +{ + uint32 id = getProgramId(program); + nglProgramUniform2f(id, index, f0, f1); +} - void CDriverGL3::setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1) - { - uint32 id = getProgramId(program); - nglProgramUniform2i(id, index, i0, i1); - } +void CDriverGL3::setUniform3f(TProgram program, uint index, float f0, float f1, float f2) +{ + uint32 id = getProgramId(program); + nglProgramUniform3f(id, index, f0, f1, f2); +} - void CDriverGL3::setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2) - { - uint32 id = getProgramId(program); - nglProgramUniform3i(id, index, i0, i1, i2); - } +void CDriverGL3::setUniform4f(TProgram program, uint index, float f0, float f1, float f2, float f3) +{ + uint32 id = getProgramId(program); + nglProgramUniform4f(id, index, f0, f1, f2, f3); +} - void CDriverGL3::setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3) - { - uint32 id = getProgramId(program); - nglProgramUniform4i(id, index, i0, i1, i2, i3); - } +void CDriverGL3::setUniform1i(TProgram program, uint index, sint32 i0) +{ + uint32 id = getProgramId(program); + nglProgramUniform1i(id, index, i0); +} - void CDriverGL3::setUniform1ui(TProgram program, uint index, uint32 ui0) - { - uint32 id = getProgramId(program); - nglProgramUniform1ui(id, index, ui0); - } +void CDriverGL3::setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1) +{ + uint32 id = getProgramId(program); + nglProgramUniform2i(id, index, i0, i1); +} - void CDriverGL3::setUniform2ui(TProgram program, uint index, uint32 ui0, uint32 ui1) - { - uint32 id = getProgramId(program); - nglProgramUniform2ui(id, index, ui0, ui1); - } +void CDriverGL3::setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2) +{ + uint32 id = getProgramId(program); + nglProgramUniform3i(id, index, i0, i1, i2); +} - void CDriverGL3::setUniform3ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2) - { - uint32 id = getProgramId(program); - nglProgramUniform3ui(id, index, ui0, ui1, ui2); - } +void CDriverGL3::setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3) +{ + uint32 id = getProgramId(program); + nglProgramUniform4i(id, index, i0, i1, i2, i3); +} - void CDriverGL3::setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3) - { - uint32 id = getProgramId(program); - nglProgramUniform4ui(id, index, ui0, ui1, ui2, ui3); - } +void CDriverGL3::setUniform1ui(TProgram program, uint index, uint32 ui0) +{ + uint32 id = getProgramId(program); + nglProgramUniform1ui(id, index, ui0); +} - void CDriverGL3::setUniform3f(TProgram program, uint index, const CVector &v) - { - uint32 id = getProgramId(program); - nglProgramUniform3f(id, index, v.x, v.y, v.z); - } +void CDriverGL3::setUniform2ui(TProgram program, uint index, uint32 ui0, uint32 ui1) +{ + uint32 id = getProgramId(program); + nglProgramUniform2ui(id, index, ui0, ui1); +} - void CDriverGL3::setUniform4f(TProgram program, uint index, const CVector &v, float f3) - { - uint32 id = getProgramId(program); - nglProgramUniform4f(id, index, v.x, v.y, v.z, f3); - } +void CDriverGL3::setUniform3ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2) +{ + uint32 id = getProgramId(program); + nglProgramUniform3ui(id, index, ui0, ui1, ui2); +} - void CDriverGL3::setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba) - { - uint32 id = getProgramId(program); - nglProgramUniform4f(id, index, rgba.R, rgba.G, rgba.B, rgba.A); - } +void CDriverGL3::setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3) +{ + uint32 id = getProgramId(program); + nglProgramUniform4ui(id, index, ui0, ui1, ui2, ui3); +} - void CDriverGL3::setUniform3x3f(TProgram program, uint index, const float *src) - { - uint32 id = getProgramId(program); - nglProgramUniformMatrix3fv(id, index, 1, false, src); - } +void CDriverGL3::setUniform3f(TProgram program, uint index, const CVector &v) +{ + uint32 id = getProgramId(program); + nglProgramUniform3f(id, index, v.x, v.y, v.z); +} - void CDriverGL3::setUniform4x4f(TProgram program, uint index, const CMatrix &m) - { - uint32 id = getProgramId(program); - nglProgramUniformMatrix4fv(id, index, 1, false, m.get()); - } +void CDriverGL3::setUniform4f(TProgram program, uint index, const CVector &v, float f3) +{ + uint32 id = getProgramId(program); + nglProgramUniform4f(id, index, v.x, v.y, v.z, f3); +} - void CDriverGL3::setUniform4x4f(TProgram program, uint index, const float *src) - { - uint32 id = getProgramId(program); - nglProgramUniformMatrix4fv(id, index, 1, false, src); - } +void CDriverGL3::setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba) +{ + uint32 id = getProgramId(program); + nglProgramUniform4f(id, index, rgba.R, rgba.G, rgba.B, rgba.A); +} - void CDriverGL3::setUniform4fv(TProgram program, uint index, size_t num, const float *src) - { - uint32 id = getProgramId(program); - nglProgramUniform4fv(id, index, num, src); - } +void CDriverGL3::setUniform3x3f(TProgram program, uint index, const float *src) +{ + uint32 id = getProgramId(program); + nglProgramUniformMatrix3fv(id, index, 1, false, src); +} - void CDriverGL3::setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src) - { - uint32 id = getProgramId(program); - nglProgramUniform4iv(id, index, num, src); - } +void CDriverGL3::setUniform4x4f(TProgram program, uint index, const CMatrix &m) +{ + uint32 id = getProgramId(program); + nglProgramUniformMatrix4fv(id, index, 1, false, m.get()); +} - void CDriverGL3::setUniform4uiv(TProgram program, uint index, size_t num, const uint32 *src) - { - uint32 id = getProgramId(program); - nglProgramUniform4uiv(id, index, num, src); - } +void CDriverGL3::setUniform4x4f(TProgram program, uint index, const float *src) +{ + uint32 id = getProgramId(program); + nglProgramUniformMatrix4fv(id, index, 1, false, src); +} - void CDriverGL3::setUniformMatrix(TProgram program, uint index, TMatrix matrix, TTransform transform) - { - uint32 id = getProgramId(program); - CMatrix mat; - +void CDriverGL3::setUniform4fv(TProgram program, uint index, size_t num, const float *src) +{ + uint32 id = getProgramId(program); + nglProgramUniform4fv(id, index, num, src); +} - switch(matrix) - { - case IDriver::ModelView: - mat = _ModelViewMatrix; - break; - case IDriver::Projection: - mat = _GLProjMat; - break; - case IDriver::ModelViewProjection: - mat = _ModelViewMatrix * _GLProjMat; - break; - } +void CDriverGL3::setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src) +{ + uint32 id = getProgramId(program); + nglProgramUniform4iv(id, index, num, src); +} - switch(transform) - { - case IDriver::Inverse: - mat.invert(); - break; - case IDriver::Transpose: - mat.transpose(); - break; - case IDriver::InverseTranspose: - mat.transpose(); - mat.invert(); - break; - } +void CDriverGL3::setUniform4uiv(TProgram program, uint index, size_t num, const uint32 *src) +{ + uint32 id = getProgramId(program); + nglProgramUniform4uiv(id, index, num, src); +} +void CDriverGL3::setUniformMatrix(TProgram program, uint index, TMatrix matrix, TTransform transform) +{ + uint32 id = getProgramId(program); + CMatrix mat; + - nglProgramUniformMatrix4fv(id, index, 1, false, mat.get()); + switch(matrix) + { + case IDriver::ModelView: + mat = _ModelViewMatrix; + break; + case IDriver::Projection: + mat = _GLProjMat; + break; + case IDriver::ModelViewProjection: + mat = _ModelViewMatrix * _GLProjMat; + break; } - void CDriverGL3::setUniformFog(TProgram program, uint index) + switch(transform) { - uint32 id = getProgramId(program); - const float *v = _ModelViewMatrix.get(); - nglProgramUniform4f(id, index, -v[ 2 ], -v[ 6 ], -v[ 10 ], -v[ 4 ]); + case IDriver::Inverse: + mat.invert(); + break; + case IDriver::Transpose: + mat.transpose(); + break; + case IDriver::InverseTranspose: + mat.transpose(); + mat.invert(); + break; } - void CDriverGL3::generateShaderDesc(CShaderDesc &desc, CMaterial &mat) + + nglProgramUniformMatrix4fv(id, index, 1, false, mat.get()); +} + +void CDriverGL3::setUniformFog(TProgram program, uint index) +{ + uint32 id = getProgramId(program); + const float *v = _ModelViewMatrix.get(); + nglProgramUniform4f(id, index, -v[ 2 ], -v[ 6 ], -v[ 10 ], -v[ 4 ]); +} + +void CDriverGL3::generateShaderDesc(CShaderDesc &desc, CMaterial &mat) +{ + desc.setShaderType(mat.getShader()); + desc.setVBFlags(_CurrentVertexBufferHard->VB->getVertexFormat()); + + if (mat.getShader() == CMaterial::LightMap) + desc.setNLightMaps(mat._LightMaps.size()); + + //int i = 0; + + if (mat.getShader() == CMaterial::Normal) { - desc.setShaderType(mat.getShader()); - desc.setVBFlags(_CurrentVertexBufferHard->VB->getVertexFormat()); - - if (mat.getShader() == CMaterial::LightMap) - desc.setNLightMaps(mat._LightMaps.size()); - - //int i = 0; + bool useTextures = false; - if (mat.getShader() == CMaterial::Normal) + int maxTextures = std::min(int(IDRV_MAT_MAXTEXTURES), int(IDRV_MAT_MAXTEXTURES)); + for (int i = 0; i < maxTextures; i++) { - bool useTextures = false; + desc.setTexEnvMode(i, mat.getTexEnvMode(i)); + } - int maxTextures = std::min(int(SHADER_MAX_TEXTURES), int(IDRV_MAT_MAXTEXTURES)); - for (int i = 0; i < maxTextures; i++) + for (int i = 0; i < maxTextures; i++) + { + if (desc.hasVBFlags(g_VertexFlags[ TexCoord0 + i ])) { - desc.setTexEnvMode(i, mat.getTexEnvMode(i)); + desc.setUseTexStage(i, true); + useTextures = true; } + } - for (int i = 0; i < maxTextures; i++) + if (useTextures && !desc.getUseTexStage(1)) + { + for (int i = 1; i < maxTextures; i++) { - if (desc.hasVBFlags(vertexFlags[ TexCoord0 + i ])) + if (mat.getTexture(i) != NULL) { desc.setUseTexStage(i, true); - useTextures = true; + desc.setUseFirstTexCoords(true); } } - - if (useTextures && !desc.getUseTexStage(1)) - { - for (int i = 1; i < maxTextures; i++) - { - if (mat.getTexture(i) != NULL) - { - desc.setUseTexStage(i, true); - desc.setUseFirstTexCoords(true); - } - } - } - else - if (!useTextures) - { - desc.setNoTextures(true); - } } - - if (mat.getAlphaTest()) - { - desc.setAlphaTest(true); - desc.setAlphaTestThreshold(mat.getAlphaTestThreshold()); - } - - if (fogEnabled()) - { - desc.setFog(true); - desc.setFogMode(CShaderDesc::Linear); - } - - int maxLights = std::min(int(SHADER_MAX_LIGHTS), int(MaxLight)); - bool enableLights = false; - for (int i = 0; i < maxLights; i++) + else + if (!useTextures) { - if (!_UserLightEnable[ i ]) - continue; - - enableLights = true; - - switch(_LightMode[ i ]) - { - case CLight::DirectionalLight: - desc.setLight(i, CShaderDesc::Directional); - break; - - case CLight::PointLight: - desc.setLight(i, CShaderDesc::Point); - break; - - case CLight::SpotLight: - desc.setLight(i, CShaderDesc::Spot); - break; - } - + desc.setNoTextures(true); } - - desc.setLighting(enableLights); } - bool CDriverGL3::setupBuiltinPrograms(CMaterial &mat) + if (mat.getAlphaTest()) { - return setupBuiltinVertexProgram() - && setupBuiltinPixelProgram(mat) - && setupUniforms(); + desc.setAlphaTest(true); + desc.setAlphaTestThreshold(mat.getAlphaTestThreshold()); } - bool CDriverGL3::setupBuiltinVertexProgram() + if (m_VPBuiltinCurrent.Fog) { - if (m_UserVertexProgram) return true; + desc.setFog(true); + desc.setFogMode(CShaderDesc::Linear); + } - touchVertexFormatVP(); // TODO + //bool enableLights = false; + for (int i = 0; i < MaxLight; i++) + { + if (!_UserLightEnable[i]) + { + desc.setLight(i, CShaderDesc::Nolight); + continue; + } + //if (!_UserLightEnable[ i ]) + // continue; - if (m_VPBuiltinTouched) + //enableLights = true; + + switch(_LightMode[ i ]) { - generateBuiltinVertexProgram(); - nlassert(m_VPBuiltinCurrent.VertexProgram); - m_VPBuiltinTouched = false; + case CLight::DirectionalLight: + desc.setLight(i, CShaderDesc::Directional); + break; + + case CLight::PointLight: + desc.setLight(i, CShaderDesc::Point); + break; + + case CLight::SpotLight: + desc.setLight(i, CShaderDesc::Spot); + break; } + + } - if (!activeVertexProgram(m_VPBuiltinCurrent.VertexProgram, true)) - return false; + desc.setLighting(/*enableLights && mat.isLighted() &&*/ m_VPBuiltinCurrent.Lighting); +} + +bool CDriverGL3::setupBuiltinPrograms(CMaterial &mat) +{ + return setupBuiltinVertexProgram() + && setupBuiltinPixelProgram(mat) + && setupUniforms(); +} - // GL3 TODO: Here we set the uniforms of the vertex program! +bool CDriverGL3::setupBuiltinVertexProgram() +{ + if (m_UserVertexProgram) return true; - return true; - } + touchVertexFormatVP(); // TODO - bool CDriverGL3::setupBuiltinPixelProgram(CMaterial &mat) + if (m_VPBuiltinTouched) { - if (m_UserPixelProgram) return true; + generateBuiltinVertexProgram(); + nlassert(m_VPBuiltinCurrent.VertexProgram); + m_VPBuiltinTouched = false; + } - // nlassert(!m_UserVertexProgram); // TEMP - // nlassert(!m_UserPixelProgram); // TEMP + if (!activeVertexProgram(m_VPBuiltinCurrent.VertexProgram, true)) + return false; - if (mat.getDynMat() != NULL) - return true; - - // CVertexProgram *vp = NULL; // REMOVED - CPixelProgram *pp = NULL; - SShaderPair sp; + // GL3 TODO: Here we set the uniforms of the vertex program! - CShaderDesc desc; + return true; +} - generateShaderDesc(desc, mat); +bool CDriverGL3::setupBuiltinPixelProgram(CMaterial &mat) +{ + if (m_UserPixelProgram) return true; - // See if we've already generated and compiled this shader - sp = shaderCache.findShader(desc); + // nlassert(!m_UserVertexProgram); // TEMP + // nlassert(!m_UserPixelProgram); // TEMP - // Yes we have! - if (!sp.empty()) - { - /*if (m_UserVertexProgram == NULL) - { - if (!activeVertexProgram(sp.vp, true)) - return false; - }*/ + if (mat.getDynMat() != NULL) + return true; + + // CVertexProgram *vp = NULL; // REMOVED + CPixelProgram *pp = NULL; + SShaderPair sp; - if (m_UserPixelProgram == NULL) - { - if (!activePixelProgram(sp.pp, true)) - return false; - } - } - // No we need to generate it now - else - { - // std::string vs; - std::string ps; - bool cacheShaders = true; - - shaderGenerator->reset(); - shaderGenerator->setMaterial(&mat); - shaderGenerator->setVBFormat(_CurrentVertexBufferHard->VB->getVertexFormat()); - shaderGenerator->setShaderDesc(&desc); - - // If we don't already have a vertex program attached, we'll generate it now - /* if (m_UserVertexProgram == NULL) - { - shaderGenerator->generateVS(vs); - vp = new CVertexProgram(); - { - IProgram::CSource *src = new IProgram::CSource(); - src->Profile = IProgram::glsl330v; - src->DisplayName = ""; - src->setSource(vs); - vp->addSource(src); - } + CShaderDesc desc; - if (!compileVertexProgram(vp)) - { - delete vp; - vp = NULL; - return false; - } + generateShaderDesc(desc, mat); - if (!activeVertexProgram(vp, true)) - { - delete vp; - vp = NULL; - return false; - } - } - else - cacheShaders = false; - */ - - // If we don't already have a pixel program attached, we'll generate it now - if (m_UserPixelProgram == NULL) - { - shaderGenerator->generatePS(ps); - pp = new CPixelProgram(); - { - IProgram::CSource *src = new IProgram::CSource(); - src->Profile = IProgram::glsl330f; - src->DisplayName = ""; - src->setSource(ps); - pp->addSource(src); - } - - if (!compilePixelProgram(pp)) - { - // delete vp; - // vp = NULL; - delete pp; - pp = NULL; - return false; - } + // See if we've already generated and compiled this shader + sp = shaderCache.findShader(desc); - if (!activePixelProgram(pp, true)) - { - // delete vp; - // vp = NULL; - delete pp; - pp = NULL; - return false; - } - } - else - cacheShaders = false; + // Yes we have! + if (!sp.empty()) + { + /*if (m_UserVertexProgram == NULL) + { + if (!activeVertexProgram(sp.vp, true)) + return false; + }*/ - - // If we already have a shader attached we won't cache this shaderpair, since we didn't generate it - if (cacheShaders) - { - sp.vp = NULL; - sp.pp = pp; - desc.setShaders(sp); - shaderCache.cacheShader(desc); - } + if (m_UserPixelProgram == NULL) + { + if (!activePixelProgram(sp.pp, true)) + return false; } - - return true; } - - bool CDriverGL3::setupDynMatProgram(CMaterial& mat, uint pass) + // No we need to generate it now + else { - /* - if ((currentProgram.vp != NULL) && (currentProgram.pp != NULL)) - return true; - - CDynMaterial *m = mat.getDynMat(); - const SRenderPass *rp = m->getPass(pass); - std::string shaderRef; - rp->getShaderRef(shaderRef); - - NL3D::CUsrShaderProgram prg; - - if (!usrShaderManager->getShader(shaderRef, &prg)) - return false; + // std::string vs; + std::string ps; + bool cacheShaders = true; + + shaderGenerator->reset(); + shaderGenerator->setMaterial(&mat); + shaderGenerator->setVBFormat(_CurrentVertexBufferHard->VB->getVertexFormat()); + shaderGenerator->setShaderDesc(&desc); - std::string shaderSource; - std::string log; - std::string name; - - if (currentProgram.vp == NULL) + // If we don't already have a vertex program attached, we'll generate it now + /* if (m_UserVertexProgram == NULL) { - prg.getVP(shaderSource); - prg.getName(name); - - CVertexProgram *vp = new CVertexProgram(); + shaderGenerator->generateVS(vs); + vp = new CVertexProgram(); { IProgram::CSource *src = new IProgram::CSource(); - src->Profile = IProgram::glsl330v; - src->DisplayName = name; - src->setSource(shaderSource.c_str()); + src->Profile = IProgram::glsl330v; + src->DisplayName = ""; + src->setSource(vs); vp->addSource(src); } - + if (!compileVertexProgram(vp)) { delete vp; + vp = NULL; return false; } - if (!activeVertexProgram(vp)) + if (!activeVertexProgram(vp, true)) { delete vp; + vp = NULL; return false; } - - if (currentProgram.dynmatVP != NULL) - delete currentProgram.dynmatVP; - currentProgram.dynmatVP = vp; - } - - if (currentProgram.pp == NULL) + else + cacheShaders = false; + */ + + // If we don't already have a pixel program attached, we'll generate it now + if (m_UserPixelProgram == NULL) { - - CPixelProgram *pp = new CPixelProgram(); - - prg.getFP(shaderSource); + shaderGenerator->generatePS(ps); + pp = new CPixelProgram(); { IProgram::CSource *src = new IProgram::CSource(); - src->Profile = IProgram::glsl330f; - src->DisplayName = name; - src->setSource(shaderSource.c_str()); + src->Profile = IProgram::glsl330f; + src->DisplayName = ""; + src->setSource(ps); pp->addSource(src); } if (!compilePixelProgram(pp)) { + // delete vp; + // vp = NULL; delete pp; + pp = NULL; return false; } - if (!activePixelProgram(pp)) + if (!activePixelProgram(pp, true)) { + // delete vp; + // vp = NULL; delete pp; + pp = NULL; return false; } - - if (currentProgram.dynmatPP != NULL) - delete currentProgram.dynmatPP; - currentProgram.dynmatPP = pp; - } + else + cacheShaders = false; - return true; - */ - return false; + + // If we already have a shader attached we won't cache this shaderpair, since we didn't generate it + if (cacheShaders) + { + sp.vp = NULL; + sp.pp = pp; + desc.setShaders(sp); + shaderCache.cacheShader(desc); + } } - bool CDriverGL3::setupUniforms() - { - setupUniforms(IDriver::VertexProgram); - setupUniforms(IDriver::PixelProgram); + return true; +} + +bool CDriverGL3::setupDynMatProgram(CMaterial& mat, uint pass) +{ + /* + if ((currentProgram.vp != NULL) && (currentProgram.pp != NULL)) return true; - } - void CDriverGL3::setupUniforms(TProgram program) + CDynMaterial *m = mat.getDynMat(); + const SRenderPass *rp = m->getPass(pass); + std::string shaderRef; + rp->getShaderRef(shaderRef); + + NL3D::CUsrShaderProgram prg; + + if (!usrShaderManager->getShader(shaderRef, &prg)) + return false; + + std::string shaderSource; + std::string log; + std::string name; + + if (currentProgram.vp == NULL) { - CMaterial &mat = *_CurrentMaterial; - IProgram *p = getProgram(program); + prg.getVP(shaderSource); + prg.getName(name); - int mvpIndex = p->getUniformIndex(CProgramIndex::ModelViewProjection); - if (mvpIndex != -1) + CVertexProgram *vp = new CVertexProgram(); { - CMatrix mvp = _GLProjMat * _ModelViewMatrix; - setUniform4x4f(program, mvpIndex, mvp); + IProgram::CSource *src = new IProgram::CSource(); + src->Profile = IProgram::glsl330v; + src->DisplayName = name; + src->setSource(shaderSource.c_str()); + vp->addSource(src); } - - int vmIndex = p->getUniformIndex(CProgramIndex::ViewMatrix); - if (vmIndex != -1) + + if (!compileVertexProgram(vp)) { - setUniform4x4f(program, vmIndex, _ViewMtx); + delete vp; + return false; } - int mvIndex = p->getUniformIndex(CProgramIndex::ModelView); - if (mvIndex != -1) + if (!activeVertexProgram(vp)) { - setUniform4x4f(program, mvIndex, _ModelViewMatrix); + delete vp; + return false; } - int nmIdx = p->getUniformIndex(CProgramIndex::NormalMatrix); - if (nmIdx != -1) + if (currentProgram.dynmatVP != NULL) + delete currentProgram.dynmatVP; + currentProgram.dynmatVP = vp; + + } + + if (currentProgram.pp == NULL) + { + + CPixelProgram *pp = new CPixelProgram(); + + prg.getFP(shaderSource); + { + IProgram::CSource *src = new IProgram::CSource(); + src->Profile = IProgram::glsl330f; + src->DisplayName = name; + src->setSource(shaderSource.c_str()); + pp->addSource(src); + } + + if (!compilePixelProgram(pp)) { - // normal matrix is the inverse-transpose of the rotation part of the modelview matrix - // Inverse-transpose of the rotation matrix, is itself - const float *mv = _ModelViewMatrix.get(); - float nm[ 3 * 3 ]; - nm[ 0 ] = mv[ 0 ]; - nm[ 1 ] = mv[ 1 ]; - nm[ 2 ] = mv[ 2 ]; - nm[ 3 ] = mv[ 4 ]; - nm[ 4 ] = mv[ 5 ]; - nm[ 5 ] = mv[ 6 ]; - nm[ 6 ] = mv[ 8 ]; - nm[ 7 ] = mv[ 9 ]; - nm[ 8 ] = mv[ 10 ]; - - setUniform3x3f(program, nmIdx, nm); + delete pp; + return false; } - int fogStartIdx = p->getUniformIndex(CProgramIndex::FogStart); - if (fogStartIdx != -1) + if (!activePixelProgram(pp)) { - setUniform1f(program, fogStartIdx, getFogStart()); + delete pp; + return false; } - int fogEndIdx = p->getUniformIndex(CProgramIndex::FogEnd); - if (fogEndIdx != -1) + if (currentProgram.dynmatPP != NULL) + delete currentProgram.dynmatPP; + currentProgram.dynmatPP = pp; + + } + + return true; + */ + return false; +} + +bool CDriverGL3::setupUniforms() +{ + setupUniforms(IDriver::VertexProgram); + setupUniforms(IDriver::PixelProgram); + return true; +} + +void CDriverGL3::setupUniforms(TProgram program) +{ + CMaterial &mat = *_CurrentMaterial; + IProgram *p = getProgram(program); + + int mvpIndex = p->getUniformIndex(CProgramIndex::ModelViewProjection); + if (mvpIndex != -1) + { + CMatrix mvp = _GLProjMat * _ModelViewMatrix; + setUniform4x4f(program, mvpIndex, mvp); + } + + int vmIndex = p->getUniformIndex(CProgramIndex::ViewMatrix); + if (vmIndex != -1) + { + setUniform4x4f(program, vmIndex, _ViewMtx); + } + + int mvIndex = p->getUniformIndex(CProgramIndex::ModelView); + if (mvIndex != -1) + { + setUniform4x4f(program, mvIndex, _ModelViewMatrix); + } + + int nmIdx = p->getUniformIndex(CProgramIndex::NormalMatrix); + if (nmIdx != -1) + { + // normal matrix is the inverse-transpose of the rotation part of the modelview matrix + // Inverse-transpose of the rotation matrix, is itself + const float *mv = _ModelViewMatrix.get(); + float nm[ 3 * 3 ]; + nm[ 0 ] = mv[ 0 ]; + nm[ 1 ] = mv[ 1 ]; + nm[ 2 ] = mv[ 2 ]; + nm[ 3 ] = mv[ 4 ]; + nm[ 4 ] = mv[ 5 ]; + nm[ 5 ] = mv[ 6 ]; + nm[ 6 ] = mv[ 8 ]; + nm[ 7 ] = mv[ 9 ]; + nm[ 8 ] = mv[ 10 ]; + + setUniform3x3f(program, nmIdx, nm); + } + + int fogStartIdx = p->getUniformIndex(CProgramIndex::FogStart); + if (fogStartIdx != -1) + { + setUniform1f(program, fogStartIdx, getFogStart()); + } + + int fogEndIdx = p->getUniformIndex(CProgramIndex::FogEnd); + if (fogEndIdx != -1) + { + setUniform1f(program, fogEndIdx, getFogEnd()); + } + + int fogColorIdx = p->getUniformIndex(CProgramIndex::FogColor); + if (fogColorIdx != -1) + { + GLfloat glCol[ 4 ]; + CRGBA col = getFogColor(); + glCol[ 0 ] = col.R / 255.0f; + glCol[ 1 ] = col.G / 255.0f; + glCol[ 2 ] = col.B / 255.0f; + glCol[ 3 ] = col.A / 255.0f; + setUniform4f(program, fogColorIdx, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ]); + } + + int colorIndex = p->getUniformIndex(CProgramIndex::Color); + if (colorIndex != -1) + { + GLfloat glCol[ 4 ]; + CRGBA col = mat.getColor(); + glCol[ 0 ] = col.R / 255.0f; + glCol[ 1 ] = col.G / 255.0f; + glCol[ 2 ] = col.B / 255.0f; + glCol[ 3 ] = col.A / 255.0f; + + setUniform4f(program, colorIndex, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ]); + } + + int diffuseIndex = p->getUniformIndex(CProgramIndex::DiffuseColor); + if (diffuseIndex != -1) + { + GLfloat glCol[ 4 ]; + CRGBA col = mat.getDiffuse(); + glCol[ 0 ] = col.R / 255.0f; + glCol[ 1 ] = col.G / 255.0f; + glCol[ 2 ] = col.B / 255.0f; + glCol[ 3 ] = col.A / 255.0f; + + setUniform4f(program, diffuseIndex, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ]); + } + + + int maxLights = std::min(int(MaxLight), int(NL_OPENGL3_MAX_LIGHT)); + for (int i = 0; i < maxLights; i++) + { + if (!_UserLightEnable[ i ]) + continue; + + ////////////////// Temporary insanity /////////////////////////////// + if ((_LightMode[ i ] != CLight::DirectionalLight) && (_LightMode[ i ] != CLight::PointLight)) + continue; + ////////////////////////////////////////////////////////////////////// + + if (_LightMode[ i ] == CLight::DirectionalLight) { - setUniform1f(program, fogEndIdx, getFogEnd()); + int ld = p->getUniformIndex(CProgramIndex::TName(CProgramIndex::Light0DirOrPos + i)); + if (ld != -1) + { + CVector v = -1 * _UserLight[ i ].getDirection(); + setUniform3f(program, ld, v.x, v.y, v.z); + } + } + else + { + int lp = p->getUniformIndex(CProgramIndex::TName(CProgramIndex::Light0DirOrPos + i)); + if (lp != -1) + { + CVector v = _UserLight[ i ].getPosition(); + float pos[ 3 ]; + pos[ 0 ] = v.x - _PZBCameraPos.x; + pos[ 1 ] = v.y - _PZBCameraPos.y; + pos[ 2 ] = v.z - _PZBCameraPos.z; + setUniform3f(program, lp, pos[ 0 ], pos[ 1 ], pos[ 2 ]); + } } - int fogColorIdx = p->getUniformIndex(CProgramIndex::FogColor); - if (fogColorIdx != -1) + int ldc = p->getUniformIndex(CProgramIndex::TName(CProgramIndex::Light0ColDiff + i)); + if (ldc != -1) { GLfloat glCol[ 4 ]; - CRGBA col = getFogColor(); + CRGBA col = _UserLight[ i ].getDiffuse(); glCol[ 0 ] = col.R / 255.0f; glCol[ 1 ] = col.G / 255.0f; glCol[ 2 ] = col.B / 255.0f; glCol[ 3 ] = col.A / 255.0f; - setUniform4f(program, fogColorIdx, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ]); + setUniform4f(program, ldc, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ]); } - int colorIndex = p->getUniformIndex(CProgramIndex::Color); - if (colorIndex != -1) + int lsc = p->getUniformIndex(CProgramIndex::TName(CProgramIndex::Light0ColSpec + i)); + if (lsc != -1) { GLfloat glCol[ 4 ]; - CRGBA col = mat.getColor(); + CRGBA col = _UserLight[ i ].getSpecular(); glCol[ 0 ] = col.R / 255.0f; glCol[ 1 ] = col.G / 255.0f; glCol[ 2 ] = col.B / 255.0f; glCol[ 3 ] = col.A / 255.0f; + setUniform4f(program, lsc, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ]); + } - setUniform4f(program, colorIndex, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ]); + int shl = p->getUniformIndex(CProgramIndex::TName(CProgramIndex::Light0Shininess + i)); + if (shl != -1) + { + setUniform1f(program, shl, mat.getShininess()); } - int diffuseIndex = p->getUniformIndex(CProgramIndex::DiffuseColor); - if (diffuseIndex != -1) + int lac = p->getUniformIndex(CProgramIndex::TName(CProgramIndex::Light0ColAmb + i)); + if (lac != -1) { GLfloat glCol[ 4 ]; - CRGBA col = mat.getDiffuse(); + CRGBA col; + if (mat.getShader() == CMaterial::LightMap) + col = _UserLight[ i ].getAmbiant(); + else + col.add(_UserLight[ i ].getAmbiant(), mat.getEmissive()); + glCol[ 0 ] = col.R / 255.0f; glCol[ 1 ] = col.G / 255.0f; glCol[ 2 ] = col.B / 255.0f; glCol[ 3 ] = col.A / 255.0f; - - setUniform4f(program, diffuseIndex, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ]); + setUniform4f(program, lac, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ]); } - - int maxLights = std::min(int(MaxLight), int(SHADER_MAX_LIGHTS)); - for (int i = 0; i < maxLights; i++) + int lca = p->getUniformIndex(CProgramIndex::TName(CProgramIndex::Light0ConstAttn + i)); + if (lca != -1) { - if (!_UserLightEnable[ i ]) - continue; - - ////////////////// Temporary insanity /////////////////////////////// - if ((_LightMode[ i ] != CLight::DirectionalLight) && (_LightMode[ i ] != CLight::PointLight)) - continue; - ////////////////////////////////////////////////////////////////////// - - if (_LightMode[ i ] == CLight::DirectionalLight) - { - int ld = p->getUniformIndex(CProgramIndex::TName(CProgramIndex::Light0DirOrPos + i)); - if (ld != -1) - { - CVector v = -1 * _UserLight[ i ].getDirection(); - setUniform3f(program, ld, v.x, v.y, v.z); - } - } - else - { - int lp = p->getUniformIndex(CProgramIndex::TName(CProgramIndex::Light0DirOrPos + i)); - if (lp != -1) - { - CVector v = _UserLight[ i ].getPosition(); - float pos[ 3 ]; - pos[ 0 ] = v.x - _PZBCameraPos.x; - pos[ 1 ] = v.y - _PZBCameraPos.y; - pos[ 2 ] = v.z - _PZBCameraPos.z; - setUniform3f(program, lp, pos[ 0 ], pos[ 1 ], pos[ 2 ]); - } - } + setUniform1f(program, lca, _UserLight[ i ].getConstantAttenuation()); + } - int ldc = p->getUniformIndex(CProgramIndex::TName(CProgramIndex::Light0ColDiff + i)); - if (ldc != -1) - { - GLfloat glCol[ 4 ]; - CRGBA col = _UserLight[ i ].getDiffuse(); - glCol[ 0 ] = col.R / 255.0f; - glCol[ 1 ] = col.G / 255.0f; - glCol[ 2 ] = col.B / 255.0f; - glCol[ 3 ] = col.A / 255.0f; - setUniform4f(program, ldc, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ]); - } + int lla = p->getUniformIndex(CProgramIndex::TName(CProgramIndex::Light0LinAttn + i)); + if (lla != -1) + { + setUniform1f(program, lla, _UserLight[ i ].getLinearAttenuation()); + } - int lsc = p->getUniformIndex(CProgramIndex::TName(CProgramIndex::Light0ColSpec + i)); - if (lsc != -1) - { - GLfloat glCol[ 4 ]; - CRGBA col = _UserLight[ i ].getSpecular(); - glCol[ 0 ] = col.R / 255.0f; - glCol[ 1 ] = col.G / 255.0f; - glCol[ 2 ] = col.B / 255.0f; - glCol[ 3 ] = col.A / 255.0f; - setUniform4f(program, lsc, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ]); - } + int lqa = p->getUniformIndex(CProgramIndex::TName(CProgramIndex::Light0QuadAttn + i)); + if (lqa != -1) + { + setUniform1f(program, lqa, _UserLight[ i ].getQuadraticAttenuation()); + } + } - int shl = p->getUniformIndex(CProgramIndex::TName(CProgramIndex::Light0Shininess + i)); - if (shl != -1) - { - setUniform1f(program, shl, mat.getShininess()); - } - int lac = p->getUniformIndex(CProgramIndex::TName(CProgramIndex::Light0ColAmb + i)); - if (lac != -1) + // Lightmaps have special constants + if (mat.getShader() != CMaterial::LightMap) + { + + for (int i = 0; i < IDRV_MAT_MAXTEXTURES; i++) + { + int cl = p->getUniformIndex(CProgramIndex::TName(CProgramIndex::Constant0 + i)); + if (cl != -1) { + CRGBA col = mat._TexEnvs[ i ].ConstantColor; GLfloat glCol[ 4 ]; - CRGBA col; - if (mat.getShader() == CMaterial::LightMap) - col = _UserLight[ i ].getAmbiant(); - else - col.add(_UserLight[ i ].getAmbiant(), mat.getEmissive()); - glCol[ 0 ] = col.R / 255.0f; glCol[ 1 ] = col.G / 255.0f; glCol[ 2 ] = col.B / 255.0f; glCol[ 3 ] = col.A / 255.0f; - setUniform4f(program, lac, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ]); - } - int lca = p->getUniformIndex(CProgramIndex::TName(CProgramIndex::Light0ConstAttn + i)); - if (lca != -1) - { - setUniform1f(program, lca, _UserLight[ i ].getConstantAttenuation()); - } - - int lla = p->getUniformIndex(CProgramIndex::TName(CProgramIndex::Light0LinAttn + i)); - if (lla != -1) - { - setUniform1f(program, lla, _UserLight[ i ].getLinearAttenuation()); - } - - int lqa = p->getUniformIndex(CProgramIndex::TName(CProgramIndex::Light0QuadAttn + i)); - if (lqa != -1) - { - setUniform1f(program, lqa, _UserLight[ i ].getQuadraticAttenuation()); + setUniform4f(program, cl, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ]); } } - - // Lightmaps have special constants - if (mat.getShader() != CMaterial::LightMap) - { - - for (int i = 0; i < IDRV_MAT_MAXTEXTURES; i++) - { - int cl = p->getUniformIndex(CProgramIndex::TName(CProgramIndex::Constant0 + i)); - if (cl != -1) - { - CRGBA col = mat._TexEnvs[ i ].ConstantColor; - GLfloat glCol[ 4 ]; - glCol[ 0 ] = col.R / 255.0f; - glCol[ 1 ] = col.G / 255.0f; - glCol[ 2 ] = col.B / 255.0f; - glCol[ 3 ] = col.A / 255.0f; - - setUniform4f(program, cl, glCol[ 0 ], glCol[ 1 ], glCol[ 2 ], glCol[ 3 ]); - } - } - - } } +} - bool CDriverGL3::initProgramPipeline() - { - ppoId = 0; +bool CDriverGL3::initProgramPipeline() +{ + ppoId = 0; - nglGenProgramPipelines(1, &ppoId); - if (ppoId == 0) - return false; + nglGenProgramPipelines(1, &ppoId); + if (ppoId == 0) + return false; - nglBindProgramPipeline(ppoId); + nglBindProgramPipeline(ppoId); - return true; - } + return true; } +#ifdef NL_STATIC +} // NLDRIVERGL3 +#endif + +} // NL3D +/* end of file */ diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl_program.h b/code/nel/src/3d/driver/opengl3/driver_opengl_program.h new file mode 100644 index 000000000..5c69bf391 --- /dev/null +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_program.h @@ -0,0 +1,74 @@ +// NeL - MMORPG Framework +// Copyright (C) 2014 by authors +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef NL_DRIVER_OPENGL_PROGRAM_H +#define NL_DRIVER_OPENGL_PROGRAM_H + +#include "nel/misc/types_nl.h" + +namespace NL3D { + +#ifdef NL_STATIC +namespace NLDRIVERGL3 { +#endif + +enum TAttribOffset +{ + Position, + Weight, + Normal, + PrimaryColor, + SecondaryColor, + Fog, + PaletteSkin, + Empty, + TexCoord0, + TexCoord1, + TexCoord2, + TexCoord3, + TexCoord4, + TexCoord5, + TexCoord6, + TexCoord7, + NumOffsets +}; + +extern const uint16 g_VertexFlags[CVertexBuffer::NumValue]; +extern const char *g_AttribNames[CVertexBuffer::NumValue]; +extern const char *g_TexelNames[IDRV_MAT_MAXTEXTURES]; +extern const char *g_ConstantNames[4]; + +namespace /* anonymous */ { + +inline bool hasFlag(uint32 data, uint32 flag) +{ + if ((data & flag) != 0) + return true; + else + return false; +} + +} /* anonymous namespace */ + +#ifdef NL_STATIC +} // NLDRIVERGL3 +#endif + +} // NL3D + +#endif // NL_DRIVER_OPENGL_PROGRAM_H + +/* end of file */ 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 62e8ceecf..6bec2cb93 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 @@ -19,9 +19,6 @@ #include "nel/misc/types_nl.h" -#define SHADER_MAX_TEXTURES 4 -#define SHADER_MAX_LIGHTS 8 - namespace NL3D { class CVertexProgram; @@ -86,13 +83,13 @@ namespace NL3D }; CShaderDesc() { - for (int i = 0; i < SHADER_MAX_TEXTURES; i++) + for (int i = 0; i < IDRV_MAT_MAXTEXTURES; i++) texEnvMode[ i ] = 0; - for (int i = 0; i < SHADER_MAX_LIGHTS; i++) + for (int i = 0; i < NL_OPENGL3_MAX_LIGHT; i++) lightMode[ i ] = Nolight; - for (int i = 0; i < SHADER_MAX_TEXTURES; i++) + for (int i = 0; i < IDRV_MAT_MAXTEXTURES; i++) useTextureStage[ i ] = false; useFirstTextureCoordSet = false; noTextures = true; @@ -146,18 +143,18 @@ namespace NL3D if (useFirstTextureCoordSet != o.useFirstTextureCoordSet) return false; - for (int i = 0; i < SHADER_MAX_TEXTURES; i++) + for (int i = 0; i < IDRV_MAT_MAXTEXTURES; i++) if (texEnvMode[ i ] != o.texEnvMode[ i ]) return false; - for (int i = 0; i < SHADER_MAX_TEXTURES; i++) + for (int i = 0; i < IDRV_MAT_MAXTEXTURES; i++) if (useTextureStage[ i ] != o.useTextureStage[ i ]) return false; } if (lightingEnabled()) { - for (int i = 0; i < SHADER_MAX_LIGHTS; i++) + for (int i = 0; i < NL_OPENGL3_MAX_LIGHT; i++) if (lightMode[ i ] != o.lightMode[ i ]) return false; } @@ -258,8 +255,8 @@ namespace NL3D }; uint32 features; - uint32 texEnvMode[ SHADER_MAX_TEXTURES ]; - bool useTextureStage[ SHADER_MAX_TEXTURES ]; + uint32 texEnvMode[ IDRV_MAT_MAXTEXTURES ]; + bool useTextureStage[ IDRV_MAT_MAXTEXTURES ]; bool useFirstTextureCoordSet; bool noTextures; uint32 vbFlags; @@ -267,7 +264,7 @@ namespace NL3D uint32 nlightmaps; float alphaTestTreshold; uint32 fogMode; - TLightMode lightMode[ SHADER_MAX_LIGHTS ]; + TLightMode lightMode[ NL_OPENGL3_MAX_LIGHT ]; bool pointLight; SShaderPair shaderPair; diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl_states.h b/code/nel/src/3d/driver/opengl3/driver_opengl_states.h index 4f20acacd..9eefa2856 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_states.h +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_states.h @@ -26,8 +26,6 @@ namespace NL3D { namespace NLDRIVERGL3 { #endif -#define NL_OPENGL3_MAX_LIGHT 8 - // *************************************************************************** /** * Class for optimizing calls to openGL states, by caching old ones. diff --git a/code/nel/src/3d/driver/opengl3/driver_opengl_vertex_program.cpp b/code/nel/src/3d/driver/opengl3/driver_opengl_vertex_program.cpp index 7e77112eb..6222ef922 100644 --- a/code/nel/src/3d/driver/opengl3/driver_opengl_vertex_program.cpp +++ b/code/nel/src/3d/driver/opengl3/driver_opengl_vertex_program.cpp @@ -23,6 +23,7 @@ #include "nel/3d/light.h" #include "driver_opengl.h" +#include "driver_opengl_program.h" #include "driver_opengl_vertex_buffer_hard.h" namespace NL3D { @@ -51,91 +52,6 @@ bool operator<(const CVPBuiltin &left, const CVPBuiltin &right) namespace { - inline bool hasFlag(uint32 data, uint32 flag) - { - if ((data & flag) != 0) - return true; - else - return false; - } - - enum TAttribOffset - { - Position, - Weight, - Normal, - PrimaryColor, - SecondaryColor, - Fog, - PaletteSkin, - Empty, - TexCoord0, - TexCoord1, - TexCoord2, - TexCoord3, - TexCoord4, - TexCoord5, - TexCoord6, - TexCoord7, - NumOffsets - }; - - const uint16 s_VertexFlags[CVertexBuffer::NumValue] = - { - CVertexBuffer::PositionFlag, - CVertexBuffer::WeightFlag, - CVertexBuffer::NormalFlag, - CVertexBuffer::PrimaryColorFlag, - CVertexBuffer::SecondaryColorFlag, - CVertexBuffer::FogFlag, - CVertexBuffer::PaletteSkinFlag, - 0, - CVertexBuffer::TexCoord0Flag, - CVertexBuffer::TexCoord1Flag, - CVertexBuffer::TexCoord2Flag, - CVertexBuffer::TexCoord3Flag, - CVertexBuffer::TexCoord4Flag, - CVertexBuffer::TexCoord5Flag, - CVertexBuffer::TexCoord6Flag, - CVertexBuffer::TexCoord7Flag - }; - - const char *s_AttribNames[ CVertexBuffer::NumValue ] = - { - "position", - "weight", - "normal", - "color", - "color2", - "fog", - "paletteSkin", - "none", - "texCoord0", - "texCoord1", - "texCoord2", - "texCoord3", - "texCoord4", - "texCoord5", - "texCoord6", - "texCoord7" - }; - - const char *s_TexelNames[ SHADER_MAX_TEXTURES ] = - { - "texel0", - "texel1", - "texel2", - "texel3" - }; - - const char *s_ConstantNames[ 4 ] = - { - "constant0", - "constant1", - "constant2", - "constant3" - }; - void vpLightUniforms(std::stringstream &ss, const CVPBuiltin &desc, int i) { switch (desc.LightMode[i]) @@ -288,13 +204,13 @@ namespace ss << std::endl; for (int i = Position; i < NumOffsets; ++i) - if (hasFlag(desc.VertexFormat, s_VertexFlags[i])) - ss << "layout (location = " << i << ") " << "in vec4 " << "v" << s_AttribNames[i] << ";" << std::endl; + if (hasFlag(desc.VertexFormat, g_VertexFlags[i])) + ss << "layout (location = " << i << ") " << "in vec4 " << "v" << g_AttribNames[i] << ";" << std::endl; ss << std::endl; for (int i = Weight; i < NumOffsets; ++i) - if (hasFlag(desc.VertexFormat, s_VertexFlags[i])) - ss << "smooth out vec4 " << s_AttribNames[i] << ";" << std::endl; + if (hasFlag(desc.VertexFormat, g_VertexFlags[i])) + ss << "smooth out vec4 " << g_AttribNames[i] << ";" << std::endl; ss << std::endl; // if (!useTextures) { @@ -327,10 +243,10 @@ namespace ss << "void main(void)" << std::endl; ss << "{" << std::endl; - ss << "gl_Position = modelViewProjection * " << "v" << s_AttribNames[0] << ";" << std::endl; + ss << "gl_Position = modelViewProjection * " << "v" << g_AttribNames[0] << ";" << std::endl; if (desc.Fog || desc.Lighting) - ss << "ecPos4 = modelView * v" << s_AttribNames[0] << ";" << std::endl; + ss << "ecPos4 = modelView * v" << g_AttribNames[0] << ";" << std::endl; if (desc.Fog) ss << "ecPos = ecPos4;" << std::endl; @@ -344,9 +260,9 @@ namespace for (int i = Weight; i < NumOffsets; i++) { - if (hasFlag(desc.VertexFormat, s_VertexFlags[i])) + if (hasFlag(desc.VertexFormat, g_VertexFlags[i])) { - ss << s_AttribNames[i] << " = " << "v" << s_AttribNames[i] << ";" << std::endl; + ss << g_AttribNames[i] << " = " << "v" << g_AttribNames[i] << ";" << std::endl; } } diff --git a/code/nel/src/3d/driver/opengl3/stdopengl.h b/code/nel/src/3d/driver/opengl3/stdopengl.h index 0010815ed..10d9f47d0 100644 --- a/code/nel/src/3d/driver/opengl3/stdopengl.h +++ b/code/nel/src/3d/driver/opengl3/stdopengl.h @@ -62,3 +62,5 @@ #include "nel/misc/command.h" #include "nel/3d/driver.h" + +#define NL_OPENGL3_MAX_LIGHT 8