Use lighted vertex program container for per pixel light program

This commit is contained in:
kaetemi 2013-09-13 20:00:20 +02:00
parent 482c13fd1a
commit ba945f30a8
5 changed files with 94 additions and 43 deletions

View file

@ -27,6 +27,7 @@
namespace NL3D { namespace NL3D {
class CVertexProgramPerPixelLight;
/** /**
* This vertex program is used to perform perpixel lighting with meshs. Its outputs are : * This vertex program is used to perform perpixel lighting with meshs. Its outputs are :
@ -49,6 +50,8 @@ namespace NL3D {
class CMeshVPPerPixelLight : public IMeshVertexProgram class CMeshVPPerPixelLight : public IMeshVertexProgram
{ {
public: public:
friend class CVertexProgramPerPixelLight;
/// true if want Specular Lighting. /// true if want Specular Lighting.
bool SpecularLighting; bool SpecularLighting;
public: public:
@ -84,7 +87,7 @@ private:
bool _IsPointLight; bool _IsPointLight;
// //
enum { NumVp = 8}; enum { NumVp = 8};
static NLMISC::CSmartPtr<CVertexProgram> _VertexProgram[NumVp]; static NLMISC::CSmartPtr<CVertexProgramPerPixelLight> _VertexProgram[NumVp];
}; };
} // NL3D } // NL3D

View file

@ -112,7 +112,7 @@ private:
/** The 16 versions: Specular or not (0 or 2), + normalize normal or not (0 or 1). /** 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..) * All multiplied by 4, because support from 0 to 3 pointLights activated. (0.., 4.., 8.., 12..)
*/ */
static NLMISC::CSmartPtr<CVertexProgram> _VertexProgram[NumVp]; static NLMISC::CSmartPtr<CVertexProgram> _VertexProgram[NumVp];
// WindTree Time for this mesh param setup. Stored in mesh because same for all instances. // WindTree Time for this mesh param setup. Stored in mesh because same for all instances.
float _CurrentTime[HrcDepth]; float _CurrentTime[HrcDepth];

View file

@ -70,7 +70,7 @@ class CWaterModel;
#define NL3D_SHADOW_MESH_SKIN_MANAGER_NUMVB 8 #define NL3D_SHADOW_MESH_SKIN_MANAGER_NUMVB 8
/// Container for lighted vertex program. /// Container for lighted vertex program.
class CVertexProgramLighted : CVertexProgram class CVertexProgramLighted : public CVertexProgram
{ {
public: public:
static const uint MaxLight = 4; static const uint MaxLight = 4;
@ -99,7 +99,7 @@ public:
const CIdxLighted &idxLighted() const { return m_IdxLighted; } const CIdxLighted &idxLighted() const { return m_IdxLighted; }
const CFeaturesLighted &featuresLighted() const { return m_FeaturesLighted; } const CFeaturesLighted &featuresLighted() const { return m_FeaturesLighted; }
private: protected:
CIdxLighted m_IdxLighted; CIdxLighted m_IdxLighted;
CFeaturesLighted m_FeaturesLighted; CFeaturesLighted m_FeaturesLighted;

View file

@ -32,14 +32,13 @@
namespace NL3D namespace NL3D
{ {
NLMISC::CSmartPtr<CVertexProgram> CMeshVPPerPixelLight::_VertexProgram[NumVp];
NLMISC::CSmartPtr<CVertexProgramPerPixelLight> CMeshVPPerPixelLight::_VertexProgram[NumVp];
// *************************************************************************** // ***************************************************************************
// Light VP fragment constants start at 24 // Light VP fragment constants start at 24
static const uint VPLightConstantStart = 24; static const uint VPLightConstantStart = 24;
// *************************************************************************** // ***************************************************************************
// *************************************************************************** // ***************************************************************************
@ -355,18 +354,33 @@ static const char* PPLightingVPCodeTest =
"; ";
***************************************************************/ ***************************************************************/
class CVertexProgramPerPixelLight : public CVertexProgramLighted
//=================================================================================
void CMeshVPPerPixelLight::initInstance(CMeshBaseInstance *mbi)
{ {
// init the vertexProgram code. public:
static bool vpCreated= false; class CIdx
if (!vpCreated)
{ {
vpCreated= true;
};
CVertexProgramPerPixelLight(uint vp);
virtual ~CVertexProgramPerPixelLight() { };
virtual void buildInfo();
const CIdx &idx() const { return m_Idx; }
private:
CIdx m_Idx;
};
CVertexProgramPerPixelLight::CVertexProgramPerPixelLight(uint vp)
{
// 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 // Gives each vp name
// Bit 0 : 1 when it is a directionnal light // Bit 0 : 1 when it is a directionnal light
// Bit 1 : 1 when specular is needed // Bit 1 : 1 when specular is needed
@ -389,34 +403,67 @@ void CMeshVPPerPixelLight::initInstance(CMeshBaseInstance *mbi)
}; };
uint numvp = sizeof(vpName) / sizeof(const char *); 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) for (uint vp = 0; vp < NumVp; ++vp)
{ {
// \todo yoyo TODO_OPTIM Manage different number of pointLights _VertexProgram[vp] = new CVertexProgramPerPixelLight(vp);
// 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());
} }
} }
} }
@ -521,7 +568,7 @@ void CMeshVPPerPixelLight::enable(bool enabled, IDriver *drv)
| (SpecularLighting ? 2 : 0) | (SpecularLighting ? 2 : 0)
| (_IsPointLight ? 1 : 0); | (_IsPointLight ? 1 : 0);
// //
drv->activeVertexProgram(_VertexProgram[idVP]); drv->activeVertexProgram((CVertexProgramPerPixelLight *)_VertexProgram[idVP]);
} }
else else
{ {

View file

@ -1170,7 +1170,8 @@ static void strReplaceAll(string &strInOut, const string &tokenSrc, const string
void CVertexProgramLighted::buildInfo() void CVertexProgramLighted::buildInfo()
{ {
if (m_FeaturesLighted.CtStartNeLVP != ~0) CVertexProgram::buildInfo();
if (profile() == nelvp)
{ {
// Fixed uniform locations // Fixed uniform locations
m_IdxLighted.Ambient = 0; m_IdxLighted.Ambient = 0;