diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index a97606a97..38c0f6c32 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -1191,6 +1191,7 @@ public: virtual void setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3) = 0; virtual void setUniform3f(TProgram program, uint index, const NLMISC::CVector& v) = 0; virtual void setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3) = 0; + virtual void setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba) = 0; virtual void setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m) = 0; virtual void setUniform4fv(TProgram program, uint index, size_t num, const float *src) = 0; virtual void setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src) = 0; diff --git a/code/nel/include/nel/3d/meshvp_per_pixel_light.h b/code/nel/include/nel/3d/meshvp_per_pixel_light.h index d81143eac..a234feddd 100644 --- a/code/nel/include/nel/3d/meshvp_per_pixel_light.h +++ b/code/nel/include/nel/3d/meshvp_per_pixel_light.h @@ -88,6 +88,8 @@ private: // enum { NumVp = 8}; static NLMISC::CSmartPtr _VertexProgram[NumVp]; + + NLMISC::CRefPtr _ActiveVertexProgram; }; } // NL3D diff --git a/code/nel/include/nel/3d/meshvp_wind_tree.h b/code/nel/include/nel/3d/meshvp_wind_tree.h index b33ac7587..2e353da05 100644 --- a/code/nel/include/nel/3d/meshvp_wind_tree.h +++ b/code/nel/include/nel/3d/meshvp_wind_tree.h @@ -116,6 +116,8 @@ private: */ static NLMISC::CSmartPtr _VertexProgram[NumVp]; + NLMISC::CRefPtr _ActiveVertexProgram; + // WindTree Time for this mesh param setup. Stored in mesh because same for all instances. float _CurrentTime[HrcDepth]; double _LastSceneTime; diff --git a/code/nel/include/nel/3d/render_trav.h b/code/nel/include/nel/3d/render_trav.h index fe37b5930..61d62e94c 100644 --- a/code/nel/include/nel/3d/render_trav.h +++ b/code/nel/include/nel/3d/render_trav.h @@ -289,7 +289,7 @@ public: * \param supportSpecular asitsounds. PointLights and dirLight are localViewer * \param invObjectWM the inverse of object matrix: lights are mul by this. Vp compute in object space. */ - void beginVPLightSetup(uint ctStart, bool supportSpecular, const CMatrix &invObjectWM); + void beginVPLightSetup(CVertexProgramLighted *program, const CMatrix &invObjectWM); /** change the driver VP LightSetup constants which depends on material. * \param excludeStrongest This remove the strongest light from the setup. The typical use is to have it computed by using perpixel lighting. @@ -418,12 +418,14 @@ private: mutable uint _StrongestLightIndex; mutable bool _StrongestLightTouched; + // Current vp setuped with beginVPLightSetup() + NLMISC::CRefPtr _VPCurrent; // Current ctStart setuped with beginVPLightSetup() - uint _VPCurrentCtStart; + //uint _VPCurrentCtStart; // Current num of VP lights enabled. uint _VPNumLights; // Current support of specular - bool _VPSupportSpecular; + //bool _VPSupportSpecular; // Sum of all ambiant of all lights + ambiantGlobal. NLMISC::CRGBAF _VPFinalAmbient; // Diffuse/Spec comp of all light / 255. diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.h b/code/nel/src/3d/driver/direct3d/driver_direct3d.h index 80b39f786..d21bef92f 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.h +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.h @@ -1200,6 +1200,7 @@ public: virtual void setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3); virtual void setUniform3f(TProgram program, uint index, const NLMISC::CVector& v); virtual void setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3); + virtual void setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba); virtual void setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m); virtual void setUniform4fv(TProgram program, uint index, size_t num, const float *src); virtual void setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src); diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d_uniform.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d_uniform.cpp index a77a86549..e44780e89 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d_uniform.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d_uniform.cpp @@ -138,6 +138,11 @@ void CDriverD3D::setUniform4f(TProgram program, uint index, const NLMISC::CVecto CDriverD3D::setUniform4f(program, index, v.x, v.y, v.z, f3); } +void CDriverD3D::setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba) +{ + CDriverD3D::setUniform4fv(program, index, 1, &rgba.R); +} + void CDriverD3D::setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m) { H_AUTO_D3D(CDriverD3D_setUniform4x4f); diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index e20d7d4fa..afab8209c 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -1406,6 +1406,7 @@ private: virtual void setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3); virtual void setUniform3f(TProgram program, uint index, const NLMISC::CVector& v); virtual void setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3); + virtual void setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba); virtual void setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m); virtual void setUniform4fv(TProgram program, uint index, size_t num, const float *src); virtual void setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src); diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp index 658b6739a..deee62379 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp @@ -169,6 +169,11 @@ void CDriverGL::setUniform4f(TProgram program, uint index, const NLMISC::CVector CDriverGL::setUniform4f(program, index, v.x, v.y, v.z, f3); } +void CDriverGL::setUniform4f(TProgram program, uint index, const NLMISC::CRGBAF& rgba) +{ + CDriverGL::setUniform4fv(program, index, 1, &rgba.R); +} + void CDriverGL::setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m) { H_AUTO_OGL(CDriverGL_setUniform4x4f); diff --git a/code/nel/src/3d/meshvp_per_pixel_light.cpp b/code/nel/src/3d/meshvp_per_pixel_light.cpp index a7a04f265..cf2d35f39 100644 --- a/code/nel/src/3d/meshvp_per_pixel_light.cpp +++ b/code/nel/src/3d/meshvp_per_pixel_light.cpp @@ -488,9 +488,7 @@ bool CMeshVPPerPixelLight::begin(IDriver *drv, // CRenderTrav *renderTrav= &scene->getRenderTrav(); /// Setup for gouraud lighting - renderTrav->beginVPLightSetup(VPLightConstantStart, - SpecularLighting, - invertedModelMat); + renderTrav->beginVPLightSetup(_ActiveVertexProgram, invertedModelMat); // sint strongestLightIndex = renderTrav->getStrongestLightIndex(); if (strongestLightIndex == -1) return false; // if no strongest light, disable this vertex program @@ -569,10 +567,12 @@ void CMeshVPPerPixelLight::enable(bool enabled, IDriver *drv) | (_IsPointLight ? 1 : 0); // drv->activeVertexProgram((CVertexProgramPerPixelLight *)_VertexProgram[idVP]); + _ActiveVertexProgram = _VertexProgram[idVP]; } else { drv->activeVertexProgram(NULL); + _ActiveVertexProgram = NULL; } _Enabled = enabled; } diff --git a/code/nel/src/3d/meshvp_wind_tree.cpp b/code/nel/src/3d/meshvp_wind_tree.cpp index ca7964ac1..17e847c3e 100644 --- a/code/nel/src/3d/meshvp_wind_tree.cpp +++ b/code/nel/src/3d/meshvp_wind_tree.cpp @@ -354,6 +354,7 @@ bool CMeshVPWindTree::begin(IDriver *driver, CScene *scene, CMeshBaseInstance *m idVP= numPls*4 + idVP; // activate VP. driver->activeVertexProgram(_VertexProgram[idVP]); + _ActiveVertexProgram = _VertexProgram[idVP]; // precompute mesh @@ -373,6 +374,7 @@ void CMeshVPWindTree::end(IDriver *driver) { // Disable the VertexProgram driver->activeVertexProgram(NULL); + _ActiveVertexProgram = NULL; } // *************************************************************************** @@ -398,7 +400,8 @@ void CMeshVPWindTree::setupLighting(CScene *scene, CMeshBaseInstance *mbi, const nlassert(scene != NULL); CRenderTrav *renderTrav= &scene->getRenderTrav(); // setup cte for lighting - renderTrav->beginVPLightSetup(VPLightConstantStart, SpecularLighting, invertedModelMat); + CVertexProgramWindTree *program = _ActiveVertexProgram; + renderTrav->beginVPLightSetup(program, invertedModelMat); } @@ -431,6 +434,7 @@ void CMeshVPWindTree::beginMBRMesh(IDriver *driver, CScene *scene) // activate VP. driver->activeVertexProgram(_VertexProgram[_LastMBRIdVP]); + _ActiveVertexProgram = _VertexProgram[_LastMBRIdVP]; // precompute mesh setupPerMesh(driver, scene); @@ -456,6 +460,7 @@ void CMeshVPWindTree::beginMBRInstance(IDriver *driver, CScene *scene, CMeshBase { _LastMBRIdVP= idVP; driver->activeVertexProgram(_VertexProgram[_LastMBRIdVP]); + _ActiveVertexProgram = _VertexProgram[_LastMBRIdVP]; if (!_VertexProgram[_LastMBRIdVP]->PerMeshSetup) { @@ -474,6 +479,7 @@ void CMeshVPWindTree::endMBRMesh(IDriver *driver) { // Disable the VertexProgram driver->activeVertexProgram(NULL); + _ActiveVertexProgram = NULL; } // *************************************************************************** diff --git a/code/nel/src/3d/render_trav.cpp b/code/nel/src/3d/render_trav.cpp index 5735e71e1..4b43d18e9 100644 --- a/code/nel/src/3d/render_trav.cpp +++ b/code/nel/src/3d/render_trav.cpp @@ -762,13 +762,15 @@ void CRenderTrav::changeLightSetup(CLightContribution *lightContribution, bool // *************************************************************************** -void CRenderTrav::beginVPLightSetup(uint ctStart, bool supportSpecular, const CMatrix &invObjectWM) +void CRenderTrav::beginVPLightSetup(CVertexProgramLighted *program, const CMatrix &invObjectWM) { uint i; nlassert(MaxVPLight==4); _VPNumLights= min(_NumLightEnabled, (uint)MaxVPLight); - _VPCurrentCtStart= ctStart; - _VPSupportSpecular= supportSpecular; + // _VPCurrentCtStart= ctStart; + // _VPSupportSpecular= supportSpecular; + _VPCurrent = program; + bool supportSpecular = program->featuresLighted().SupportSpecular; // Prepare Colors (to be multiplied by material) //================ @@ -786,8 +788,11 @@ void CRenderTrav::beginVPLightSetup(uint ctStart, bool supportSpecular, const C // reset other to 0. for(; isetConstant(_VPCurrentCtStart+1+i, 0.f, 0.f, 0.f, 0.f); + _VPLightDiffuse[i] = CRGBA::Black; + if (program->idxLighted().Diffuse[i] != ~0) + { + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Diffuse[i], 0.f, 0.f, 0.f, 0.f); + } } // Specular. _VPCurrentCtStart+5 to 8 (only if supportSpecular) if(supportSpecular) @@ -800,7 +805,10 @@ void CRenderTrav::beginVPLightSetup(uint ctStart, bool supportSpecular, const C for(; isetConstant(_VPCurrentCtStart+5+i, 0.f, 0.f, 0.f, 0.f); + if (program->idxLighted().Specular[i] != ~0) + { + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Specular[i], 0.f, 0.f, 0.f, 0.f); + } } } @@ -816,40 +824,24 @@ void CRenderTrav::beginVPLightSetup(uint ctStart, bool supportSpecular, const C lightDir= invObjectWM.mulVector(_DriverLight[0].getDirection()); lightDir.normalize(); lightDir= -lightDir; - if(supportSpecular) - { - // Setup lightDir. - Driver->setConstant(_VPCurrentCtStart+9, lightDir); - } - else - { - // Setup lightDir. NB: no specular color! - Driver->setConstant(_VPCurrentCtStart+5, lightDir); - } + Driver->setUniform3f(IDriver::VertexProgram, program->idxLighted().DirOrPos[0], lightDir); // The sun is the same for every instance. // Setup PointLights //================ uint startPLPos; - if(supportSpecular) + if (supportSpecular) { // Setup eye in objectSpace for localViewer - Driver->setConstant(_VPCurrentCtStart+11, eye); - // Start at 12. - startPLPos= 12; - } - else - { - // Start at 6. - startPLPos= 6; + Driver->setUniform3f(IDriver::VertexProgram, program->idxLighted().EyePosition, eye); } // For all pointLight enabled (other are black: don't matter) for(i=1; i<_VPNumLights; i++) { // Setup position of light. CVector lightPos; - lightPos= invObjectWM * _DriverLight[i].getPosition(); - Driver->setConstant(_VPCurrentCtStart+startPLPos+(i-1), lightPos); + lightPos = invObjectWM * _DriverLight[i].getPosition(); + Driver->setUniform3f(IDriver::VertexProgram, program->idxLighted().DirOrPos[i], lightPos); } @@ -860,6 +852,9 @@ void CRenderTrav::beginVPLightSetup(uint ctStart, bool supportSpecular, const C // *************************************************************************** void CRenderTrav::changeVPLightSetupMaterial(const CMaterial &mat, bool excludeStrongest) { + CVertexProgramLighted *program = _VPCurrent; + nlassert(program); + // Must test if at least done one time. if(!_VPMaterialCacheDirty) { @@ -869,7 +864,7 @@ void CRenderTrav::changeVPLightSetupMaterial(const CMaterial &mat, bool exclude _VPMaterialCacheDiffuse == mat.getDiffuse().getPacked() ) { // Same Diffuse part, test if same specular if necessary - if( !_VPSupportSpecular || + if( !program->featuresLighted().SupportSpecular || ( _VPMaterialCacheSpecular == mat.getSpecular().getPacked() && _VPMaterialCacheShininess == mat.getShininess() ) ) { @@ -899,7 +894,7 @@ void CRenderTrav::changeVPLightSetupMaterial(const CMaterial &mat, bool exclude // setup Ambient + Emissive color= _VPFinalAmbient * mat.getAmbient(); color+= mat.getEmissive(); - Driver->setConstant(_VPCurrentCtStart+0, 1, &color.R); + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Ambient, color); // is the strongest light is not excluded, its index should have been setup to _VPNumLights @@ -908,7 +903,7 @@ void CRenderTrav::changeVPLightSetupMaterial(const CMaterial &mat, bool exclude for(i = 0; i < strongestLightIndex; ++i) { color= _VPLightDiffuse[i] * matDiff; - Driver->setConstant(_VPCurrentCtStart+1+i, 1, &color.R); + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Diffuse[i], color); } @@ -917,24 +912,24 @@ void CRenderTrav::changeVPLightSetupMaterial(const CMaterial &mat, bool exclude color= _VPLightDiffuse[i] * matDiff; _StrongestLightDiffuse.set((uint8) (255.f * color.R), (uint8) (255.f * color.G), (uint8) (255.f * color.B), (uint8) (255.f * color.A)); // setup strongest light to black for the gouraud part - Driver->setConstant(_VPCurrentCtStart + 1 + i, 0.f, 0.f, 0.f, 0.f); + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Diffuse[i], 0.f, 0.f, 0.f, 0.f); ++i; // setup other lights for(; i < _VPNumLights; i++) { color= _VPLightDiffuse[i] * matDiff; - Driver->setConstant(_VPCurrentCtStart + 1 + i, 1, &color.R); + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Diffuse[i], color); } } // setup Specular - if(_VPSupportSpecular) + if (program->featuresLighted().SupportSpecular) { for(i = 0; i < strongestLightIndex; ++i) { color= _VPLightSpecular[i] * matSpec; color.A= specExp; - Driver->setConstant(_VPCurrentCtStart+5+i, 1, &color.R); + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Specular[i], color); } if (i != _VPNumLights) @@ -943,14 +938,14 @@ void CRenderTrav::changeVPLightSetupMaterial(const CMaterial &mat, bool exclude _StrongestLightSpecular.set((uint8) (255.f * color.R), (uint8) (255.f * color.G), (uint8) (255.f * color.B), (uint8) (255.f * color.A)); // setup strongest light to black (for gouraud part) - Driver->setConstant(_VPCurrentCtStart + 5 + i, 0.f, 0.f, 0.f, 0.f); + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Specular[i], 0.f, 0.f, 0.f, 0.f); ++i; // setup other lights for(; i < _VPNumLights; i++) { color= _VPLightSpecular[i] * matSpec; color.A= specExp; - Driver->setConstant(_VPCurrentCtStart + 5 + i, 1, &color.R); + Driver->setUniform4f(IDriver::VertexProgram, program->idxLighted().Specular[i], color); } } } @@ -959,10 +954,7 @@ void CRenderTrav::changeVPLightSetupMaterial(const CMaterial &mat, bool exclude static float alphaCte[4]= {0,0,1,0}; alphaCte[3]= matDiff.A; // setup at good place - if(_VPSupportSpecular) - Driver->setConstant(_VPCurrentCtStart+10, 1, alphaCte); - else - Driver->setConstant(_VPCurrentCtStart+9, 1, alphaCte); + Driver->setUniform4fv(IDriver::VertexProgram, program->idxLighted().DiffuseAlpha, 1, alphaCte); } // *************************************************************************** @@ -1174,24 +1166,24 @@ void CVertexProgramLighted::buildInfo() if (profile() == nelvp) { // Fixed uniform locations - m_IdxLighted.Ambient = 0; + m_IdxLighted.Ambient = m_FeaturesLighted.CtStartNeLVP + 0; for (uint i = 0; i < MaxLight; ++i) { - m_IdxLighted.Diffuse[i] = 1 + i; + m_IdxLighted.Diffuse[i] = m_FeaturesLighted.CtStartNeLVP + 1 + i; } if (m_FeaturesLighted.SupportSpecular) { for (uint i = 0; i < MaxLight; ++i) { - m_IdxLighted.Specular[i] = 5 + i; + m_IdxLighted.Specular[i] = m_FeaturesLighted.CtStartNeLVP + 5 + i; } m_IdxLighted.DirOrPos[0] = 9; for (uint i = 1; i < MaxLight; ++i) { - m_IdxLighted.DirOrPos[i] = (12 - 1) + i; + m_IdxLighted.DirOrPos[i] = m_FeaturesLighted.CtStartNeLVP + (12 - 1) + i; } - m_IdxLighted.DiffuseAlpha = 10; - m_IdxLighted.EyePosition = 11; + m_IdxLighted.DiffuseAlpha = m_FeaturesLighted.CtStartNeLVP + 10; + m_IdxLighted.EyePosition = m_FeaturesLighted.CtStartNeLVP + 11; } else { @@ -1201,9 +1193,9 @@ void CVertexProgramLighted::buildInfo() } for (uint i = 0; i < MaxLight; ++i) { - m_IdxLighted.DirOrPos[i] = 5 + i; + m_IdxLighted.DirOrPos[i] = m_FeaturesLighted.CtStartNeLVP + 5 + i; } - m_IdxLighted.DiffuseAlpha = 9; + m_IdxLighted.DiffuseAlpha = m_FeaturesLighted.CtStartNeLVP + 9; m_IdxLighted.EyePosition = ~0; } } @@ -1214,6 +1206,15 @@ void CVertexProgramLighted::buildInfo() // m_IdxLighted.Ambient = getUniformIndex("ambient"); // etc } + + nlassert(m_IdxLighted.Diffuse[0] != ~0); + if (m_FeaturesLighted.SupportSpecular) + { + nlassert(m_IdxLighted.Specular[0] != ~0); + nlassert(m_IdxLighted.EyePosition != ~0); + } + nlassert(m_IdxLighted.DirOrPos[0] != ~0); + nlassert(m_IdxLighted.DiffuseAlpha != ~0); } // generates the lighting part of a vertex program, nelvp profile