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 5df1bfc16..d81143eac 100644 --- a/code/nel/include/nel/3d/meshvp_per_pixel_light.h +++ b/code/nel/include/nel/3d/meshvp_per_pixel_light.h @@ -27,6 +27,7 @@ namespace NL3D { +class CVertexProgramPerPixelLight; /** * This vertex program is used to perform perpixel lighting with meshs. Its outputs are : @@ -49,6 +50,8 @@ namespace NL3D { class CMeshVPPerPixelLight : public IMeshVertexProgram { public: + friend class CVertexProgramPerPixelLight; + /// true if want Specular Lighting. bool SpecularLighting; public: @@ -84,7 +87,7 @@ private: bool _IsPointLight; // enum { NumVp = 8}; - static NLMISC::CSmartPtr _VertexProgram[NumVp]; + static NLMISC::CSmartPtr _VertexProgram[NumVp]; }; } // NL3D diff --git a/code/nel/include/nel/3d/meshvp_wind_tree.h b/code/nel/include/nel/3d/meshvp_wind_tree.h index 4e5d2875a..a19f6b43d 100644 --- a/code/nel/include/nel/3d/meshvp_wind_tree.h +++ b/code/nel/include/nel/3d/meshvp_wind_tree.h @@ -112,7 +112,7 @@ private: /** The 16 versions: Specular or not (0 or 2), + normalize normal or not (0 or 1). * All multiplied by 4, because support from 0 to 3 pointLights activated. (0.., 4.., 8.., 12..) */ - static NLMISC::CSmartPtr _VertexProgram[NumVp]; + static NLMISC::CSmartPtr _VertexProgram[NumVp]; // WindTree Time for this mesh param setup. Stored in mesh because same for all instances. float _CurrentTime[HrcDepth]; diff --git a/code/nel/include/nel/3d/render_trav.h b/code/nel/include/nel/3d/render_trav.h index 76931d68f..fe37b5930 100644 --- a/code/nel/include/nel/3d/render_trav.h +++ b/code/nel/include/nel/3d/render_trav.h @@ -70,7 +70,7 @@ class CWaterModel; #define NL3D_SHADOW_MESH_SKIN_MANAGER_NUMVB 8 /// Container for lighted vertex program. -class CVertexProgramLighted : CVertexProgram +class CVertexProgramLighted : public CVertexProgram { public: static const uint MaxLight = 4; @@ -99,7 +99,7 @@ public: const CIdxLighted &idxLighted() const { return m_IdxLighted; } const CFeaturesLighted &featuresLighted() const { return m_FeaturesLighted; } -private: +protected: CIdxLighted m_IdxLighted; CFeaturesLighted m_FeaturesLighted; diff --git a/code/nel/src/3d/meshvp_per_pixel_light.cpp b/code/nel/src/3d/meshvp_per_pixel_light.cpp index 809dd16c8..a7a04f265 100644 --- a/code/nel/src/3d/meshvp_per_pixel_light.cpp +++ b/code/nel/src/3d/meshvp_per_pixel_light.cpp @@ -32,14 +32,13 @@ namespace NL3D { -NLMISC::CSmartPtr CMeshVPPerPixelLight::_VertexProgram[NumVp]; + +NLMISC::CSmartPtr CMeshVPPerPixelLight::_VertexProgram[NumVp]; // *************************************************************************** // Light VP fragment constants start at 24 static const uint VPLightConstantStart = 24; - - // *************************************************************************** // *************************************************************************** @@ -355,18 +354,33 @@ static const char* PPLightingVPCodeTest = "; ***************************************************************/ +class CVertexProgramPerPixelLight : public CVertexProgramLighted +{ +public: + class CIdx + { + + }; + CVertexProgramPerPixelLight(uint vp); + virtual ~CVertexProgramPerPixelLight() { }; + virtual void buildInfo(); + const CIdx &idx() const { return m_Idx; } +private: + CIdx m_Idx; +}; -//================================================================================= -void CMeshVPPerPixelLight::initInstance(CMeshBaseInstance *mbi) +CVertexProgramPerPixelLight::CVertexProgramPerPixelLight(uint vp) { - // init the vertexProgram code. - static bool vpCreated= false; - if (!vpCreated) - { - vpCreated= true; + // lighted settings + m_FeaturesLighted.SupportSpecular = (vp & 2) != 0; + m_FeaturesLighted.NumActivePointLights = MaxLight - 1; + m_FeaturesLighted.Normalize = false; + m_FeaturesLighted.CtStartNeLVP = VPLightConstantStart; + // nelvp + { // Gives each vp name // Bit 0 : 1 when it is a directionnal light // Bit 1 : 1 when specular is needed @@ -389,34 +403,67 @@ void CMeshVPPerPixelLight::initInstance(CMeshBaseInstance *mbi) }; uint numvp = sizeof(vpName) / sizeof(const char *); - nlassert(NumVp == numvp); // make sure that it is in sync with header..todo : compile time assert :) + nlassert(CMeshVPPerPixelLight::NumVp == numvp); // make sure that it is in sync with header..todo : compile time assert :) + + // \todo yoyo TODO_OPTIM Manage different number of pointLights + // NB: never call getLightVPFragmentNeLVP() with normalize, because already done by PerPixel fragment before. + std::string vpCode = std::string(vpName[vp]) + + std::string("# ***************") // temp for debug + + CRenderTrav::getLightVPFragmentNeLVP( + m_FeaturesLighted.NumActivePointLights, + m_FeaturesLighted.CtStartNeLVP, + m_FeaturesLighted.SupportSpecular, + m_FeaturesLighted.Normalize) + + std::string("# ***************") // temp for debug + + std::string(PPLightingVPCodeEnd); + #ifdef NL_DEBUG + /** For test : parse those programs before they are used. + * As a matter of fact some program will works with the NV_VERTEX_PROGRAM extension, + * but won't with EXT_vertex_shader, because there are some limitations (can't read a temp + * register that hasn't been written before..) + */ + CVPParser vpParser; + CVPParser::TProgram result; + std::string parseOutput; + if (!vpParser.parse(vpCode.c_str(), result, parseOutput)) + { + nlwarning(parseOutput.c_str()); + nlassert(0); + } + #endif + + CSource *source = new CSource(); + source->DisplayName = NLMISC::toString("nelvp/MeshVPPerPixel/%i", vp); + source->Profile = CVertexProgram::nelvp; + source->setSource(vpCode); + addSource(source); + } + + // glsl + { + // TODO_VP_GLSL + } +} + +void CVertexProgramPerPixelLight::buildInfo() +{ + CVertexProgramLighted::buildInfo(); +} + + +//================================================================================= +void CMeshVPPerPixelLight::initInstance(CMeshBaseInstance *mbi) +{ + // init the vertexProgram code. + static bool vpCreated= false; + if (!vpCreated) + { + vpCreated = true; + for (uint vp = 0; vp < NumVp; ++vp) { - // \todo yoyo TODO_OPTIM Manage different number of pointLights - // NB: never call getLightVPFragmentNeLVP() with normalize, because already done by PerPixel fragment before. - std::string vpCode = std::string(vpName[vp]) - + std::string("# ***************") // temp for debug - + CRenderTrav::getLightVPFragmentNeLVP(CRenderTrav::MaxVPLight-1, VPLightConstantStart, (vp & 2) != 0, false) - + std::string("# ***************") // temp for debug - + std::string(PPLightingVPCodeEnd); - #ifdef NL_DEBUG - /** For test : parse those programs before they are used. - * As a matter of fact some program will works with the NV_VERTEX_PROGRAM extension, - * but won't with EXT_vertex_shader, because there are some limitations (can't read a temp - * register that hasn't been written before..) - */ - CVPParser vpParser; - CVPParser::TProgram result; - std::string parseOutput; - if (!vpParser.parse(vpCode.c_str(), result, parseOutput)) - { - nlwarning(parseOutput.c_str()); - nlassert(0); - } - #endif - _VertexProgram[vp] = new CVertexProgram(vpCode.c_str()); + _VertexProgram[vp] = new CVertexProgramPerPixelLight(vp); } - } } @@ -521,7 +568,7 @@ void CMeshVPPerPixelLight::enable(bool enabled, IDriver *drv) | (SpecularLighting ? 2 : 0) | (_IsPointLight ? 1 : 0); // - drv->activeVertexProgram(_VertexProgram[idVP]); + drv->activeVertexProgram((CVertexProgramPerPixelLight *)_VertexProgram[idVP]); } else { diff --git a/code/nel/src/3d/render_trav.cpp b/code/nel/src/3d/render_trav.cpp index eba42e724..5735e71e1 100644 --- a/code/nel/src/3d/render_trav.cpp +++ b/code/nel/src/3d/render_trav.cpp @@ -1170,7 +1170,8 @@ static void strReplaceAll(string &strInOut, const string &tokenSrc, const string void CVertexProgramLighted::buildInfo() { - if (m_FeaturesLighted.CtStartNeLVP != ~0) + CVertexProgram::buildInfo(); + if (profile() == nelvp) { // Fixed uniform locations m_IdxLighted.Ambient = 0;