Cleanup abstract gpu program interface
This commit is contained in:
parent
fcb0ee720e
commit
057eab4680
21 changed files with 454 additions and 528 deletions
|
@ -1147,6 +1147,33 @@ public:
|
|||
|
||||
|
||||
|
||||
/// \name Geometry Program
|
||||
// @{
|
||||
|
||||
// Order of preference
|
||||
// - activeGeometryProgram
|
||||
// - CMaterial pass[n] PP (uses activeGeometryProgram, but does not override if one already set by code)
|
||||
// - none
|
||||
|
||||
/** Return true if the driver supports the specified pixel program profile.
|
||||
*/
|
||||
virtual bool supportGeometryProgram(CGeometryProgram::TProfile profile) const = 0;
|
||||
|
||||
/** Compile the given pixel program, return if successful.
|
||||
* If a pixel program was set active before compilation,
|
||||
* the state of the active pixel program is undefined behaviour afterwards.
|
||||
*/
|
||||
virtual bool compileGeometryProgram(CGeometryProgram *program) = 0;
|
||||
|
||||
/** Set the active pixel program. This will override pixel programs specified in CMaterial render calls.
|
||||
* Also used internally by setupMaterial(CMaterial) when getGeometryProgram returns NULL.
|
||||
* The pixel program is activated immediately.
|
||||
*/
|
||||
virtual bool activeGeometryProgram(CGeometryProgram *program) = 0;
|
||||
// @}
|
||||
|
||||
|
||||
|
||||
/// \name Program parameters
|
||||
// @{
|
||||
// Set parameters
|
||||
|
|
|
@ -27,52 +27,18 @@
|
|||
#include <nel/misc/types_nl.h>
|
||||
#include <nel/misc/smart_ptr.h>
|
||||
#include <nel/3d/gpu_program.h>
|
||||
#include <nel/3d/gpu_program_source.h>
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace NL3D {
|
||||
|
||||
/**
|
||||
* \brief CGeometryProgramInfo
|
||||
* \date 2013-09-07 15:00GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
* Read-only information structure.
|
||||
*/
|
||||
struct CGeometryProgramInfo
|
||||
{
|
||||
public:
|
||||
std::string DisplayName;
|
||||
|
||||
/*enum TFeatures
|
||||
{
|
||||
|
||||
};*/
|
||||
|
||||
// Bitfield containing features used by this geometry program
|
||||
uint Features;
|
||||
|
||||
// Indices of parameters used by features
|
||||
// ...
|
||||
};
|
||||
|
||||
class CGeometryProgram : public IGPUProgram
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
CGeometryProgram(CGPUProgramSourceCont *programSource);
|
||||
CGeometryProgram();
|
||||
/// Destructor
|
||||
virtual ~CGeometryProgram ();
|
||||
|
||||
/// Build feature information
|
||||
void buildInfo(const char *displayName, uint features);
|
||||
/// Get feature information
|
||||
inline const CGeometryProgramInfo *getInfo() const { return _Info; }
|
||||
|
||||
private:
|
||||
|
||||
/// Feature information
|
||||
CGeometryProgramInfo *_Info;
|
||||
};
|
||||
|
||||
} // NL3D
|
||||
|
|
|
@ -57,11 +57,103 @@ public:
|
|||
// The virtual dtor is important.
|
||||
virtual ~IGPUProgramDrvInfos(void);
|
||||
|
||||
virtual uint getParamIdx(char *name) const = 0;
|
||||
virtual uint getUniformIndex(char *name) const = 0;
|
||||
};
|
||||
|
||||
class CGPUProgramSource;
|
||||
class CGPUProgramSourceCont;
|
||||
#define NL_GPU_PROGRAM_LIGHTS 8
|
||||
|
||||
/// Features exposed by a program. Used to set builtin parameters on user provided shaders
|
||||
struct CGPUProgramFeatures
|
||||
{
|
||||
CGPUProgramFeatures() : DriverFlags(0), MaterialFlags(0) /*, NumLights(0) */ { }
|
||||
|
||||
// Driver builtin parameters
|
||||
enum TDriverFlags
|
||||
{
|
||||
// Matrices
|
||||
ModelView = 0x00000001,
|
||||
ModelViewInverse = 0x00000002,
|
||||
ModelViewTranspose = 0x00000004,
|
||||
ModelViewInverseTranspose = 0x00000008,
|
||||
|
||||
Projection = 0x00000010,
|
||||
ProjectionInverse = 0x00000020,
|
||||
ProjectionTranspose = 0x00000040,
|
||||
ProjectionInverseTranspose = 0x00000080,
|
||||
|
||||
ModelViewProjection = 0x00000100,
|
||||
ModelViewProjectionInverse = 0x00000200,
|
||||
ModelViewProjectionTranspose = 0x00000400,
|
||||
ModelViewProjectionInverseTranspose = 0x00000800,
|
||||
|
||||
//
|
||||
// Rough example, modify as necessary.
|
||||
//
|
||||
|
||||
// Lighting (todo)
|
||||
/// Driver ambient, must be ignored when material ambient is flagged
|
||||
//DriverAmbient = 0x00001000,
|
||||
/// Lights, does not set diffuses if material lights is flagged
|
||||
//DriverLights = 0x00002000,
|
||||
// etcetera
|
||||
|
||||
// Fog (todo)
|
||||
// Fog = ...,
|
||||
};
|
||||
uint32 DriverFlags;
|
||||
// uint NumLights; // number of lights supported by the program (not used yet, modify as necessary)
|
||||
|
||||
enum TMaterialFlags
|
||||
{
|
||||
/// Use the CMaterial texture stages as the textures for a Pixel Program
|
||||
TextureStages = 0x00000001, // <- don't remove this one, it's already used, if you want to split them up into the different stages, then it's ok to change it
|
||||
|
||||
//
|
||||
// Rough example, modify as necessary.
|
||||
//
|
||||
|
||||
// Lighting (todo)
|
||||
/// Material ambient premultiplied with driver ambient
|
||||
//MaterialAmbient = 0x00000002,
|
||||
/// Premultiply lights diffuse with material diffuse, requires driver lights to be flagged
|
||||
//MaterialLights = 0x00000004,
|
||||
// etcetera
|
||||
|
||||
// Add all necessary feature sets used with builtin materials here
|
||||
};
|
||||
// Material builtin parameters
|
||||
uint32 MaterialFlags;
|
||||
};
|
||||
|
||||
/// Stucture used to cache the indices of builtin parameters
|
||||
struct CGPUProgramIndices
|
||||
{
|
||||
uint ModelView;
|
||||
uint ModelViewInverse;
|
||||
uint ModelViewTranspose;
|
||||
uint ModelViewInverseTranspose;
|
||||
|
||||
uint Projection;
|
||||
uint ProjectionInverse;
|
||||
uint ProjectionTranspose;
|
||||
uint ProjectionInverseTranspose;
|
||||
|
||||
uint ModelViewProjection;
|
||||
uint ModelViewProjectionInverse;
|
||||
uint ModelViewProjectionTranspose;
|
||||
uint ModelViewProjectionInverseTranspose;
|
||||
|
||||
//
|
||||
// Rough example, modify as necessary.
|
||||
//
|
||||
//uint Ambient;
|
||||
|
||||
//uint LightType[NL_GPU_PROGRAM_LIGHTS];
|
||||
//uint LightAmbient[NL_GPU_PROGRAM_LIGHTS];
|
||||
//uint LightDiffuse[NL_GPU_PROGRAM_LIGHTS];
|
||||
//uint LightPosition[NL_GPU_PROGRAM_LIGHTS];
|
||||
//uint LightDirection[NL_GPU_PROGRAM_LIGHTS];
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief IGPUProgram
|
||||
|
@ -74,6 +166,8 @@ class IGPUProgram : public NLMISC::CRefCount
|
|||
public:
|
||||
enum TProfile
|
||||
{
|
||||
none = 0,
|
||||
|
||||
// types
|
||||
// Vertex Shader = 0x01
|
||||
// Pixel Shader = 0x02
|
||||
|
@ -123,24 +217,66 @@ public:
|
|||
glsl330g = 0x65030330, // GLSL geometry program version 330
|
||||
};
|
||||
|
||||
struct CSource : public NLMISC::CRefCount
|
||||
{
|
||||
public:
|
||||
std::string DisplayName;
|
||||
|
||||
/// Minimal required profile for this GPU program
|
||||
IGPUProgram::TProfile Profile;
|
||||
|
||||
const char *SourcePtr;
|
||||
size_t SourceLen;
|
||||
/// Copy the source code string
|
||||
inline void setSource(const char *source) { SourceCopy = source; SourcePtr = &SourceCopy[0]; SourceLen = SourceCopy.size(); }
|
||||
/// Set pointer to source code string without copying the string
|
||||
inline void setSourcePtr(const char *sourcePtr, size_t sourceLen) { SourceCopy.clear(); SourcePtr = sourcePtr; SourceLen = sourceLen; }
|
||||
inline void setSourcePtr(const char *sourcePtr) { SourceCopy.clear(); SourcePtr = sourcePtr; SourceLen = strlen(sourcePtr); }
|
||||
|
||||
/// CVertexProgramInfo/CPixelProgramInfo/... NeL features
|
||||
CGPUProgramFeatures Features;
|
||||
|
||||
/// Map with known parameter indices, used for assembly programs
|
||||
std::map<std::string, uint> ParamIndices;
|
||||
|
||||
private:
|
||||
std::string SourceCopy;
|
||||
};
|
||||
|
||||
public:
|
||||
IGPUProgram();
|
||||
IGPUProgram(CGPUProgramSourceCont *programSource);
|
||||
virtual ~IGPUProgram();
|
||||
|
||||
/// Get the idx of a parameter (ogl: uniform, d3d: constant, etcetera) by name. Invalid name returns ~0
|
||||
inline uint getParamIdx(char *name) const { return _DrvInfo->getParamIdx(name); };
|
||||
// Manage the sources, not allowed after compilation.
|
||||
// Add multiple sources using different profiles, the driver will use the first one it supports.
|
||||
inline size_t getSourceNb() const { return m_Sources.size(); };
|
||||
inline CSource *getSource(size_t i) const { return m_Sources[i]; };
|
||||
inline size_t addSource(CSource *source) { nlassert(!m_Source); m_Sources.push_back(source); return (m_Sources.size() - 1); }
|
||||
inline void removeSource(size_t i) { nlassert(!m_Source); m_Sources.erase(m_Sources.begin() + i); }
|
||||
|
||||
/// Get the program
|
||||
inline const CGPUProgramSourceCont *getProgramSource() const { return _ProgramSource; };
|
||||
// Get the idx of a parameter (ogl: uniform, d3d: constant, etcetera) by name. Invalid name returns ~0
|
||||
inline uint getUniformIndex(char *name) const { return m_DrvInfo->getUniformIndex(name); };
|
||||
|
||||
// Get feature information of the current program
|
||||
inline CSource *source() const { return m_Source; };
|
||||
inline const CGPUProgramFeatures &features() const { return m_Source->Features; };
|
||||
inline const CGPUProgramIndices &indices() const { return m_Indices; };
|
||||
inline TProfile profile() const { return m_Source->Profile; }
|
||||
|
||||
// Build feature info, called automatically by the driver after compile succeeds
|
||||
void buildInfo(CSource *source);
|
||||
|
||||
protected:
|
||||
/// The progam source
|
||||
NLMISC::CSmartPtr<CGPUProgramSourceCont> _ProgramSource;
|
||||
std::vector<NLMISC::CSmartPtr<CSource> > m_Sources;
|
||||
|
||||
/// The source used for compilation
|
||||
NLMISC::CSmartPtr<CSource> m_Source;
|
||||
CGPUProgramIndices m_Indices;
|
||||
|
||||
public:
|
||||
/// The driver information. For the driver implementation only.
|
||||
NLMISC::CRefPtr<IGPUProgramDrvInfos> _DrvInfo;
|
||||
NLMISC::CRefPtr<IGPUProgramDrvInfos> m_DrvInfo;
|
||||
|
||||
}; /* class IGPUProgram */
|
||||
|
||||
|
|
|
@ -1,93 +0,0 @@
|
|||
/**
|
||||
* \file gpu_program_source.h
|
||||
* \brief CGPUProgramSource
|
||||
* \date 2013-09-07 14:54GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
* CGPUProgramSource
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013 by authors
|
||||
*
|
||||
* This file is part of NL3D.
|
||||
* NL3D 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.
|
||||
*
|
||||
* NL3D 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 NL3D. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NL3D_GPU_PROGRAM_SOURCE_H
|
||||
#define NL3D_GPU_PROGRAM_SOURCE_H
|
||||
#include <nel/misc/types_nl.h>
|
||||
|
||||
// STL includes
|
||||
|
||||
// NeL includes
|
||||
#include <nel/misc/string_mapper.h>
|
||||
|
||||
// Project includes
|
||||
#include <nel/3d/gpu_program.h>
|
||||
|
||||
namespace NL3D {
|
||||
|
||||
/**
|
||||
* \brief CGPUProgramSource
|
||||
* \date 2013-09-07 14:54GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
* A single GPU program with a specific profile.
|
||||
*/
|
||||
struct CGPUProgramSource : public NLMISC::CRefCount
|
||||
{
|
||||
public:
|
||||
std::string DisplayName;
|
||||
|
||||
/// Minimal required profile for this GPU program
|
||||
IGPUProgram::TProfile Profile;
|
||||
|
||||
const char *SourcePtr;
|
||||
size_t SourceLen;
|
||||
/// Copy the source code string
|
||||
inline void setSource(const char *source) { SourceCopy = source; SourcePtr = &SourceCopy[0]; SourceLen = SourceCopy.size(); }
|
||||
/// Set pointer to source code string without copying the string
|
||||
inline void setSourcePtr(const char *sourcePtr, size_t sourceLen) { SourceCopy.clear(); SourcePtr = sourcePtr; SourceLen = sourceLen; }
|
||||
inline void setSourcePtr(const char *sourcePtr) { SourceCopy.clear(); SourcePtr = sourcePtr; SourceLen = strlen(sourcePtr); }
|
||||
|
||||
/// CVertexProgramInfo/CPixelProgramInfo/... NeL features
|
||||
uint Features;
|
||||
|
||||
/// Map with known parameter indices, used for assembly programs
|
||||
std::map<std::string, uint> ParamIndices;
|
||||
|
||||
private:
|
||||
std::string SourceCopy;
|
||||
|
||||
}; /* class CGPUProgramSource */
|
||||
|
||||
/**
|
||||
* \brief CGPUProgramSourceCont
|
||||
* \date 2013-09-07 14:54GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
* Container for the source code of a single GPU program, allowing
|
||||
* variations in different language profiles.
|
||||
*/
|
||||
struct CGPUProgramSourceCont : public NLMISC::CRefCount
|
||||
{
|
||||
public:
|
||||
std::vector<NLMISC::CSmartPtr<CGPUProgramSource> > Sources;
|
||||
|
||||
}; /* class CGPUProgramSourceCont */
|
||||
|
||||
} /* namespace NL3D */
|
||||
|
||||
#endif /* #ifndef NL3D_GPU_PROGRAM_SOURCE_H */
|
||||
|
||||
/* end of file */
|
|
@ -27,59 +27,18 @@
|
|||
#include <nel/misc/types_nl.h>
|
||||
#include <nel/misc/smart_ptr.h>
|
||||
#include <nel/3d/gpu_program.h>
|
||||
#include <nel/3d/gpu_program_source.h>
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace NL3D {
|
||||
|
||||
/**
|
||||
* \brief CPixelProgramInfo
|
||||
* \date 2013-09-07 15:00GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
* Read-only information structure.
|
||||
*/
|
||||
struct CPixelProgramInfo
|
||||
{
|
||||
public:
|
||||
std::string DisplayName;
|
||||
|
||||
enum TFeatures
|
||||
{
|
||||
/// Use texture stages from CMaterial as texture parameters
|
||||
MaterialTextures = 0x0001,
|
||||
/// Set driver fog parameters on this program
|
||||
Fog = 0x0002,
|
||||
/// Adds an enabled/disabled parameter to the fog, for user shaders
|
||||
DynamicFog = 0x0004,
|
||||
};
|
||||
|
||||
// Bitfield containing features used by this pixel program
|
||||
uint Features;
|
||||
|
||||
// Indices of parameters used by features
|
||||
uint FogEnabledIdx; // (Fog && DynamicFog) nlFogEnabled, fog enabled
|
||||
uint FogStartEndIdx; // (Fog) nlFogStartEnd, start and end of fog
|
||||
uint FogColorIdx; // (Fog) nlFogColor, fog color
|
||||
};
|
||||
|
||||
class CPixelProgram : public IGPUProgram
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
CPixelProgram(CGPUProgramSourceCont *programSource);
|
||||
CPixelProgram();
|
||||
/// Destructor
|
||||
virtual ~CPixelProgram ();
|
||||
|
||||
/// Build feature information
|
||||
void buildInfo(const char *displayName, uint features);
|
||||
/// Get feature information
|
||||
inline const CPixelProgramInfo *getInfo() const { return _Info; }
|
||||
|
||||
private:
|
||||
|
||||
/// Feature information
|
||||
CPixelProgramInfo *_Info;
|
||||
};
|
||||
|
||||
} // NL3D
|
||||
|
|
|
@ -20,84 +20,21 @@
|
|||
#include "nel/misc/types_nl.h"
|
||||
#include "nel/misc/smart_ptr.h"
|
||||
#include "nel/3d/gpu_program.h"
|
||||
#include "nel/3d/gpu_program_source.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace NL3D {
|
||||
|
||||
/**
|
||||
* \brief CVertexProgramInfo
|
||||
* \date 2013-09-07 15:00GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
* Read-only information structure.
|
||||
*/
|
||||
struct CVertexProgramInfo
|
||||
{
|
||||
public:
|
||||
std::string DisplayName;
|
||||
|
||||
enum TFeatures
|
||||
{
|
||||
// World
|
||||
// transform
|
||||
|
||||
// Lights
|
||||
Ambient = 0x0001,
|
||||
Sun = 0x0002,
|
||||
PointLight0 = 0x0004,
|
||||
PointLight1 = 0x0008,
|
||||
PointLight2 = 0x0010,
|
||||
|
||||
// Lights, additional parameters for user shaders
|
||||
/// Adds an enabled/disabled parameter to all of the lights
|
||||
DynamicLights = 0x0020,
|
||||
};
|
||||
|
||||
/// Bitfield containing features used by this vertex program.
|
||||
uint Features;
|
||||
|
||||
/// Indices of parameters used by features.
|
||||
|
||||
/// Lights, NeL supports:
|
||||
/// - Ambient light
|
||||
uint AmbientIdx; // (Ambient)
|
||||
/// - One directional light
|
||||
uint SunDirectionIdx; // (Sun)
|
||||
uint SunDiffuseIdx; // (Sun)
|
||||
/// - Zero to three point lights
|
||||
uint PointLight0PositionIdx; // (PointLight0)
|
||||
uint PointLight0DiffuseIdx; // (PointLight0)
|
||||
uint PointLight1PositionIdx; // (PointLight1)
|
||||
uint PointLight1DiffuseIdx; // (PointLight1)
|
||||
uint PointLight2PositionIdx; // (PointLight2)
|
||||
uint PointLight2DiffuseIdx; // (PointLight2)
|
||||
|
||||
/// DynamicLights
|
||||
uint SunEnabledIdx; // (DynamicLights && Sun)
|
||||
uint PointLight0EnabledIdx; // (DynamicLights && PointLight0)
|
||||
uint PointLight1EnabledIdx; // (DynamicLights && PointLight1)
|
||||
uint PointLight2EnabledIdx; // (DynamicLights && PointLight2)
|
||||
};
|
||||
|
||||
class CVertexProgram : public IGPUProgram
|
||||
{
|
||||
public:
|
||||
/// Constructor
|
||||
CVertexProgram(CGPUProgramSourceCont *programSource);
|
||||
CVertexProgram();
|
||||
CVertexProgram(const char *nelvp);
|
||||
|
||||
/// Destructor
|
||||
virtual ~CVertexProgram ();
|
||||
|
||||
/// Build feature information
|
||||
void buildInfo(const char *displayName, uint features);
|
||||
/// Get feature information
|
||||
inline const CVertexProgramInfo *getInfo() const { return _Info; }
|
||||
|
||||
private:
|
||||
|
||||
/// Feature information
|
||||
CVertexProgramInfo *_Info;
|
||||
};
|
||||
|
||||
} // NL3D
|
||||
|
|
|
@ -169,8 +169,6 @@ SOURCE_GROUP(Driver FILES
|
|||
../../include/nel/3d/geometry_program.h
|
||||
gpu_program.cpp
|
||||
../../include/nel/3d/gpu_program.h
|
||||
gpu_program_source.cpp
|
||||
../../include/nel/3d/gpu_program_source.h
|
||||
gpu_program_params.cpp
|
||||
../../include/nel/3d/gpu_program_params.h)
|
||||
|
||||
|
|
|
@ -309,7 +309,7 @@ public:
|
|||
CVertexProgamDrvInfosD3D(IDriver *drv, ItGPUPrgDrvInfoPtrList it);
|
||||
~CVertexProgamDrvInfosD3D();
|
||||
|
||||
virtual uint getParamIdx(char *name) const
|
||||
virtual uint getUniformIndex(char *name) const
|
||||
{
|
||||
std::map<std::string, uint>::const_iterator it = ParamIndices.find(name);
|
||||
if (it != ParamIndices.end()) return it->second;
|
||||
|
@ -331,7 +331,7 @@ public:
|
|||
CPixelProgramDrvInfosD3D(IDriver *drv, ItGPUPrgDrvInfoPtrList it);
|
||||
~CPixelProgramDrvInfosD3D();
|
||||
|
||||
virtual uint getParamIdx(char *name) const
|
||||
virtual uint getUniformIndex(char *name) const
|
||||
{
|
||||
std::map<std::string, uint>::const_iterator it = ParamIndices.find(name);
|
||||
if (it != ParamIndices.end()) return it->second;
|
||||
|
@ -1156,6 +1156,33 @@ public:
|
|||
|
||||
|
||||
|
||||
/// \name Geometry Program
|
||||
// @{
|
||||
|
||||
// Order of preference
|
||||
// - activeGeometryProgram
|
||||
// - CMaterial pass[n] PP (uses activeGeometryProgram, but does not override if one already set by code)
|
||||
// - none
|
||||
|
||||
/** Return true if the driver supports the specified pixel program profile.
|
||||
*/
|
||||
virtual bool supportGeometryProgram(CGeometryProgram::TProfile profile) const { return false; }
|
||||
|
||||
/** Compile the given pixel program, return if successful.
|
||||
* If a pixel program was set active before compilation,
|
||||
* the state of the active pixel program is undefined behaviour afterwards.
|
||||
*/
|
||||
virtual bool compileGeometryProgram(CGeometryProgram *program) { return false; }
|
||||
|
||||
/** Set the active pixel program. This will override pixel programs specified in CMaterial render calls.
|
||||
* Also used internally by setupMaterial(CMaterial) when getGeometryProgram returns NULL.
|
||||
* The pixel program is activated immediately.
|
||||
*/
|
||||
virtual bool activeGeometryProgram(CGeometryProgram *program) { return false; }
|
||||
// @}
|
||||
|
||||
|
||||
|
||||
/// \name Program parameters
|
||||
// @{
|
||||
// Set parameters
|
||||
|
@ -2078,7 +2105,7 @@ public:
|
|||
{
|
||||
H_AUTO_D3D(CDriverD3D_getPixelProgramD3D);
|
||||
CPixelProgramDrvInfosD3D* d3dPixelProgram;
|
||||
d3dPixelProgram = (CPixelProgramDrvInfosD3D*)(IGPUProgramDrvInfos*)(pixelProgram._DrvInfo);
|
||||
d3dPixelProgram = (CPixelProgramDrvInfosD3D*)(IGPUProgramDrvInfos*)(pixelProgram.m_DrvInfo);
|
||||
return d3dPixelProgram;
|
||||
}
|
||||
|
||||
|
@ -2087,7 +2114,7 @@ public:
|
|||
{
|
||||
H_AUTO_D3D(CDriverD3D_getVertexProgramD3D);
|
||||
CVertexProgamDrvInfosD3D* d3dVertexProgram;
|
||||
d3dVertexProgram = (CVertexProgamDrvInfosD3D*)(IGPUProgramDrvInfos*)(vertexProgram._DrvInfo);
|
||||
d3dVertexProgram = (CVertexProgamDrvInfosD3D*)(IGPUProgramDrvInfos*)(vertexProgram.m_DrvInfo);
|
||||
return d3dVertexProgram;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,15 +66,15 @@ bool CDriverD3D::supportPixelProgram (CPixelProgram::TProfile profile) const
|
|||
bool CDriverD3D::compilePixelProgram(CPixelProgram *program)
|
||||
{
|
||||
// Program setuped ?
|
||||
if (program->_DrvInfo==NULL)
|
||||
if (program->m_DrvInfo==NULL)
|
||||
{
|
||||
// Find a supported pixel program profile
|
||||
CGPUProgramSource *source = NULL;
|
||||
for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i)
|
||||
IGPUProgram::CSource *source = NULL;
|
||||
for (uint i = 0; i < program->getSourceNb(); ++i)
|
||||
{
|
||||
if (supportPixelProgram(program->getProgramSource()->Sources[i]->Profile))
|
||||
if (supportPixelProgram(program->getSource(i)->Profile))
|
||||
{
|
||||
source = program->getProgramSource()->Sources[i];
|
||||
source = program->getSource(i);
|
||||
}
|
||||
}
|
||||
if (!source)
|
||||
|
@ -89,7 +89,7 @@ bool CDriverD3D::compilePixelProgram(CPixelProgram *program)
|
|||
*itPix = drvInfo = new CPixelProgramDrvInfosD3D(this, itPix);
|
||||
|
||||
// Create a driver info structure
|
||||
program->_DrvInfo = *itPix;
|
||||
program->m_DrvInfo = *itPix;
|
||||
|
||||
LPD3DXBUFFER pShader;
|
||||
LPD3DXBUFFER pErrorMsgs;
|
||||
|
@ -109,7 +109,7 @@ bool CDriverD3D::compilePixelProgram(CPixelProgram *program)
|
|||
drvInfo->ParamIndices = source->ParamIndices;
|
||||
|
||||
// Build the feature info
|
||||
program->buildInfo(source->DisplayName.c_str(), source->Features);
|
||||
program->buildInfo(source);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -128,7 +128,7 @@ bool CDriverD3D::activePixelProgram(CPixelProgram *program)
|
|||
{
|
||||
if (!CDriverD3D::compilePixelProgram(program)) return false;
|
||||
|
||||
CPixelProgramDrvInfosD3D *info = static_cast<CPixelProgramDrvInfosD3D *>((IGPUProgramDrvInfos*)program->_DrvInfo);
|
||||
CPixelProgramDrvInfosD3D *info = static_cast<CPixelProgramDrvInfosD3D *>((IGPUProgramDrvInfos*)program->m_DrvInfo);
|
||||
setPixelShader(info->Shader);
|
||||
}
|
||||
else
|
||||
|
|
|
@ -265,15 +265,15 @@ void dump(const CVPParser::TProgram &prg, std::string &dest)
|
|||
bool CDriverD3D::compileVertexProgram(NL3D::CVertexProgram *program)
|
||||
{
|
||||
// Program setuped ?
|
||||
if (program->_DrvInfo == NULL)
|
||||
if (program->m_DrvInfo == NULL)
|
||||
{
|
||||
// Find nelvp
|
||||
CGPUProgramSource *source = NULL;
|
||||
for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i)
|
||||
IGPUProgram::CSource *source = NULL;
|
||||
for (uint i = 0; i < program->getSourceNb(); ++i)
|
||||
{
|
||||
if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp)
|
||||
if (program->getSource(i)->Profile == CVertexProgram::nelvp)
|
||||
{
|
||||
source = program->getProgramSource()->Sources[i];
|
||||
source = program->getSource(i);
|
||||
}
|
||||
}
|
||||
if (!source)
|
||||
|
@ -288,7 +288,7 @@ bool CDriverD3D::compileVertexProgram(NL3D::CVertexProgram *program)
|
|||
*itTex = drvInfo = new CVertexProgamDrvInfosD3D(this, itTex);
|
||||
|
||||
// Create a driver info structure
|
||||
program->_DrvInfo = *itTex;
|
||||
program->m_DrvInfo = *itTex;
|
||||
|
||||
/** Check with our parser if the program will works with other implemented extensions, too. (EXT_vertex_shader ..).
|
||||
* There are some incompatibilities.
|
||||
|
@ -359,7 +359,7 @@ bool CDriverD3D::compileVertexProgram(NL3D::CVertexProgram *program)
|
|||
drvInfo->ParamIndices = source->ParamIndices;
|
||||
|
||||
// Build the feature info
|
||||
program->buildInfo(source->DisplayName.c_str(), source->Features);
|
||||
program->buildInfo(source);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -378,7 +378,7 @@ bool CDriverD3D::activeVertexProgram (CVertexProgram *program)
|
|||
{
|
||||
if (!CDriverD3D::compileVertexProgram(program)) return false;
|
||||
|
||||
CVertexProgamDrvInfosD3D *info = NLMISC::safe_cast<CVertexProgamDrvInfosD3D *>((IGPUProgramDrvInfos*)program->_DrvInfo);
|
||||
CVertexProgamDrvInfosD3D *info = NLMISC::safe_cast<CVertexProgamDrvInfosD3D *>((IGPUProgramDrvInfos*)program->m_DrvInfo);
|
||||
setVertexProgram (info->Shader, program);
|
||||
|
||||
/* D3DRS_FOGSTART and D3DRS_FOGEND must be set with [1, 0] else the fog doesn't work properly on VertexShader and non-VertexShader objects
|
||||
|
|
|
@ -1362,6 +1362,33 @@ private:
|
|||
|
||||
|
||||
|
||||
/// \name Geometry Program
|
||||
// @{
|
||||
|
||||
// Order of preference
|
||||
// - activeGeometryProgram
|
||||
// - CMaterial pass[n] PP (uses activeGeometryProgram, but does not override if one already set by code)
|
||||
// - none
|
||||
|
||||
/** Return true if the driver supports the specified pixel program profile.
|
||||
*/
|
||||
virtual bool supportGeometryProgram(CGeometryProgram::TProfile profile) const { return false; }
|
||||
|
||||
/** Compile the given pixel program, return if successful.
|
||||
* If a pixel program was set active before compilation,
|
||||
* the state of the active pixel program is undefined behaviour afterwards.
|
||||
*/
|
||||
virtual bool compileGeometryProgram(CGeometryProgram *program) { return false; }
|
||||
|
||||
/** Set the active pixel program. This will override pixel programs specified in CMaterial render calls.
|
||||
* Also used internally by setupMaterial(CMaterial) when getGeometryProgram returns NULL.
|
||||
* The pixel program is activated immediately.
|
||||
*/
|
||||
virtual bool activeGeometryProgram(CGeometryProgram *program) { return false; }
|
||||
// @}
|
||||
|
||||
|
||||
|
||||
/// \name Program parameters
|
||||
// @{
|
||||
// Set parameters
|
||||
|
@ -1618,7 +1645,7 @@ public:
|
|||
// The gl id is auto created here.
|
||||
CVertexProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it);
|
||||
|
||||
virtual uint getParamIdx(char *name) const
|
||||
virtual uint getUniformIndex(char *name) const
|
||||
{
|
||||
std::map<std::string, uint>::const_iterator it = ParamIndices.find(name);
|
||||
if (it != ParamIndices.end()) return it->second;
|
||||
|
@ -1638,7 +1665,7 @@ public:
|
|||
// The gl id is auto created here.
|
||||
CPixelProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it);
|
||||
|
||||
virtual uint getParamIdx(char *name) const
|
||||
virtual uint getUniformIndex(char *name) const
|
||||
{
|
||||
std::map<std::string, uint>::const_iterator it = ParamIndices.find(name);
|
||||
if (it != ParamIndices.end()) return it->second;
|
||||
|
|
|
@ -97,7 +97,7 @@ bool CDriverGL::activePixelProgram(CPixelProgram *program)
|
|||
bool CDriverGL::compilePixelProgram(NL3D::CPixelProgram *program)
|
||||
{
|
||||
// Program setuped ?
|
||||
if (program->_DrvInfo == NULL)
|
||||
if (program->m_DrvInfo == NULL)
|
||||
{
|
||||
glDisable(GL_FRAGMENT_PROGRAM_ARB);
|
||||
_PixelProgramEnabled = false;
|
||||
|
@ -109,12 +109,12 @@ bool CDriverGL::compilePixelProgram(NL3D::CPixelProgram *program)
|
|||
CPixelProgamDrvInfosGL *drvInfo;
|
||||
*it = drvInfo = new CPixelProgamDrvInfosGL(this, it);
|
||||
// Set the pointer
|
||||
program->_DrvInfo = drvInfo;
|
||||
program->m_DrvInfo = drvInfo;
|
||||
|
||||
if (!setupPixelProgram(program, drvInfo->ID))
|
||||
{
|
||||
delete drvInfo;
|
||||
program->_DrvInfo = NULL;
|
||||
program->m_DrvInfo = NULL;
|
||||
_GPUPrgDrvInfos.erase(it);
|
||||
return false;
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ bool CDriverGL::activeARBPixelProgram(CPixelProgram *program)
|
|||
if (!CDriverGL::compilePixelProgram(program)) return false;
|
||||
|
||||
// Cast the driver info pointer
|
||||
CPixelProgamDrvInfosGL *drvInfo = safe_cast<CPixelProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->_DrvInfo);
|
||||
CPixelProgamDrvInfosGL *drvInfo = safe_cast<CPixelProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->m_DrvInfo);
|
||||
|
||||
glEnable(GL_FRAGMENT_PROGRAM_ARB);
|
||||
_PixelProgramEnabled = true;
|
||||
|
@ -159,15 +159,15 @@ bool CDriverGL::setupPixelProgram(CPixelProgram *program, GLuint id/*, bool &spe
|
|||
{
|
||||
H_AUTO_OGL(CDriverGL_setupARBPixelProgram)
|
||||
|
||||
CPixelProgamDrvInfosGL *drvInfo = static_cast<CPixelProgamDrvInfosGL *>((IGPUProgramDrvInfos *)program->_DrvInfo);
|
||||
CPixelProgamDrvInfosGL *drvInfo = static_cast<CPixelProgamDrvInfosGL *>((IGPUProgramDrvInfos *)program->m_DrvInfo);
|
||||
|
||||
// Find a supported pixel program profile
|
||||
CGPUProgramSource *source = NULL;
|
||||
for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i)
|
||||
IGPUProgram::CSource *source = NULL;
|
||||
for (uint i = 0; i < program->getSourceNb(); ++i)
|
||||
{
|
||||
if (supportPixelProgram(program->getProgramSource()->Sources[i]->Profile))
|
||||
if (supportPixelProgram(program->getSource(i)->Profile))
|
||||
{
|
||||
source = program->getProgramSource()->Sources[i];
|
||||
source = program->getSource(i);
|
||||
}
|
||||
}
|
||||
if (!source)
|
||||
|
@ -224,7 +224,7 @@ bool CDriverGL::setupPixelProgram(CPixelProgram *program, GLuint id/*, bool &spe
|
|||
drvInfo->ParamIndices = source->ParamIndices;
|
||||
|
||||
// Build the feature info
|
||||
program->buildInfo(source->DisplayName.c_str(), source->Features);
|
||||
program->buildInfo(source);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1151,7 +1151,7 @@ void CDriverGL::toggleGlArraysForEXTVertexShader()
|
|||
CVertexProgram *vp = _LastSetuppedVP;
|
||||
if (vp)
|
||||
{
|
||||
CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast<CVertexProgamDrvInfosGL *>((IGPUProgramDrvInfos *) vp->_DrvInfo);
|
||||
CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast<CVertexProgamDrvInfosGL *>((IGPUProgramDrvInfos *) vp->m_DrvInfo);
|
||||
if (drvInfo)
|
||||
{
|
||||
// Disable all VertexAttribs.
|
||||
|
@ -1396,7 +1396,7 @@ void CDriverGL::setupGlArraysForEXTVertexShader(CVertexBufferInfo &vb)
|
|||
|
||||
CVertexProgram *vp = _LastSetuppedVP;
|
||||
if (!vp) return;
|
||||
CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast<CVertexProgamDrvInfosGL *>((IGPUProgramDrvInfos *) vp->_DrvInfo);
|
||||
CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast<CVertexProgamDrvInfosGL *>((IGPUProgramDrvInfos *) vp->m_DrvInfo);
|
||||
if (!drvInfo) return;
|
||||
|
||||
uint32 flags= vb.VertexFormat;
|
||||
|
|
|
@ -93,17 +93,17 @@ bool CDriverGL::compileNVVertexProgram(CVertexProgram *program)
|
|||
// Driver info
|
||||
CVertexProgamDrvInfosGL *drvInfo;
|
||||
|
||||
nlassert(!program->_DrvInfo);
|
||||
nlassert(!program->m_DrvInfo);
|
||||
glDisable(GL_VERTEX_PROGRAM_NV);
|
||||
_VertexProgramEnabled = false;
|
||||
|
||||
// Find nelvp
|
||||
CGPUProgramSource *source = NULL;
|
||||
for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i)
|
||||
IGPUProgram::CSource *source = NULL;
|
||||
for (uint i = 0; i < program->getSourceNb(); ++i)
|
||||
{
|
||||
if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp)
|
||||
if (program->getSource(i)->Profile == CVertexProgram::nelvp)
|
||||
{
|
||||
source = program->getProgramSource()->Sources[i];
|
||||
source = program->getSource(i);
|
||||
}
|
||||
}
|
||||
if (!source)
|
||||
|
@ -136,7 +136,7 @@ bool CDriverGL::compileNVVertexProgram(CVertexProgram *program)
|
|||
*it = drvInfo = new CVertexProgamDrvInfosGL(this, it);
|
||||
|
||||
// Set the pointer
|
||||
program->_DrvInfo = drvInfo;
|
||||
program->m_DrvInfo = drvInfo;
|
||||
|
||||
// Compile the program
|
||||
nglLoadProgramNV(GL_VERTEX_PROGRAM_NV, drvInfo->ID, (GLsizei)source->SourceLen, (const GLubyte*)source->SourcePtr);
|
||||
|
@ -177,7 +177,7 @@ bool CDriverGL::compileNVVertexProgram(CVertexProgram *program)
|
|||
|
||||
// Setup not ok
|
||||
delete drvInfo;
|
||||
program->_DrvInfo = NULL;
|
||||
program->m_DrvInfo = NULL;
|
||||
_GPUPrgDrvInfos.erase(it);
|
||||
return false;
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ bool CDriverGL::compileNVVertexProgram(CVertexProgram *program)
|
|||
drvInfo->ParamIndices = source->ParamIndices;
|
||||
|
||||
// Build the feature info
|
||||
program->buildInfo(source->DisplayName.c_str(), source->Features);
|
||||
program->buildInfo(source);
|
||||
|
||||
// Setup ok
|
||||
return true;
|
||||
|
@ -208,7 +208,7 @@ bool CDriverGL::activeNVVertexProgram(CVertexProgram *program)
|
|||
if (program)
|
||||
{
|
||||
// Driver info
|
||||
CVertexProgamDrvInfosGL *drvInfo = safe_cast<CVertexProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->_DrvInfo);
|
||||
CVertexProgamDrvInfosGL *drvInfo = safe_cast<CVertexProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->m_DrvInfo);
|
||||
nlassert(drvInfo);
|
||||
|
||||
// Enable vertex program
|
||||
|
@ -1524,17 +1524,17 @@ bool CDriverGL::compileARBVertexProgram(NL3D::CVertexProgram *program)
|
|||
|
||||
#ifndef USE_OPENGLES
|
||||
|
||||
nlassert(!program->_DrvInfo);
|
||||
nlassert(!program->m_DrvInfo);
|
||||
glDisable(GL_VERTEX_PROGRAM_ARB);
|
||||
_VertexProgramEnabled = false;
|
||||
|
||||
// Find nelvp
|
||||
CGPUProgramSource *source = NULL;
|
||||
for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i)
|
||||
IGPUProgram::CSource *source = NULL;
|
||||
for (uint i = 0; i < program->getSourceNb(); ++i)
|
||||
{
|
||||
if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp)
|
||||
if (program->getSource(i)->Profile == CVertexProgram::nelvp)
|
||||
{
|
||||
source = program->getProgramSource()->Sources[i];
|
||||
source = program->getSource(i);
|
||||
}
|
||||
}
|
||||
if (!source)
|
||||
|
@ -1563,12 +1563,12 @@ bool CDriverGL::compileARBVertexProgram(NL3D::CVertexProgram *program)
|
|||
CVertexProgamDrvInfosGL *drvInfo;
|
||||
*it = drvInfo = new CVertexProgamDrvInfosGL(this, it);
|
||||
// Set the pointer
|
||||
program->_DrvInfo=drvInfo;
|
||||
program->m_DrvInfo = drvInfo;
|
||||
|
||||
if (!setupARBVertexProgram(parsedProgram, drvInfo->ID, drvInfo->SpecularWritten))
|
||||
{
|
||||
delete drvInfo;
|
||||
program->_DrvInfo = NULL;
|
||||
program->m_DrvInfo = NULL;
|
||||
_GPUPrgDrvInfos.erase(it);
|
||||
return false;
|
||||
}
|
||||
|
@ -1577,7 +1577,7 @@ bool CDriverGL::compileARBVertexProgram(NL3D::CVertexProgram *program)
|
|||
drvInfo->ParamIndices = source->ParamIndices;
|
||||
|
||||
// Build the feature info
|
||||
program->buildInfo(source->DisplayName.c_str(), source->Features);
|
||||
program->buildInfo(source);
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -1600,7 +1600,7 @@ bool CDriverGL::activeARBVertexProgram(CVertexProgram *program)
|
|||
if (program)
|
||||
{
|
||||
// Driver info
|
||||
CVertexProgamDrvInfosGL *drvInfo = safe_cast<CVertexProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->_DrvInfo);
|
||||
CVertexProgamDrvInfosGL *drvInfo = safe_cast<CVertexProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->m_DrvInfo);
|
||||
nlassert(drvInfo);
|
||||
|
||||
glEnable( GL_VERTEX_PROGRAM_ARB );
|
||||
|
@ -1639,17 +1639,17 @@ bool CDriverGL::compileEXTVertexShader(CVertexProgram *program)
|
|||
|
||||
#ifndef USE_OPENGLES
|
||||
|
||||
nlassert(program->_DrvInfo);
|
||||
nlassert(program->m_DrvInfo);
|
||||
glDisable(GL_VERTEX_SHADER_EXT);
|
||||
_VertexProgramEnabled = false;
|
||||
|
||||
// Find nelvp
|
||||
CGPUProgramSource *source = NULL;
|
||||
for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i)
|
||||
IGPUProgram::CSource *source = NULL;
|
||||
for (uint i = 0; i < program->getSourceNb(); ++i)
|
||||
{
|
||||
if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp)
|
||||
if (program->getSource(i)->Profile == CVertexProgram::nelvp)
|
||||
{
|
||||
source = program->getProgramSource()->Sources[i];
|
||||
source = program->getSource(i);
|
||||
}
|
||||
}
|
||||
if (!source)
|
||||
|
@ -1690,12 +1690,12 @@ bool CDriverGL::compileEXTVertexShader(CVertexProgram *program)
|
|||
CVertexProgamDrvInfosGL *drvInfo;
|
||||
*it = drvInfo = new CVertexProgamDrvInfosGL (this, it);
|
||||
// Set the pointer
|
||||
program->_DrvInfo=drvInfo;
|
||||
program->m_DrvInfo=drvInfo;
|
||||
|
||||
if (!setupEXTVertexShader(parsedProgram, drvInfo->ID, drvInfo->Variants, drvInfo->UsedVertexComponents))
|
||||
{
|
||||
delete drvInfo;
|
||||
program->_DrvInfo = NULL;
|
||||
program->m_DrvInfo = NULL;
|
||||
_GPUPrgDrvInfos.erase(it);
|
||||
return false;
|
||||
}
|
||||
|
@ -1704,7 +1704,7 @@ bool CDriverGL::compileEXTVertexShader(CVertexProgram *program)
|
|||
drvInfo->ParamIndices = source->ParamIndices;
|
||||
|
||||
// Build the feature info
|
||||
program->buildInfo(source->DisplayName.c_str(), source->Features);
|
||||
program->buildInfo(source);
|
||||
|
||||
return true;
|
||||
|
||||
|
@ -1727,7 +1727,7 @@ bool CDriverGL::activeEXTVertexShader(CVertexProgram *program)
|
|||
if (program)
|
||||
{
|
||||
// Driver info
|
||||
CVertexProgamDrvInfosGL *drvInfo = safe_cast<CVertexProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->_DrvInfo);
|
||||
CVertexProgamDrvInfosGL *drvInfo = safe_cast<CVertexProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->m_DrvInfo);
|
||||
nlassert(drvInfo);
|
||||
|
||||
glEnable(GL_VERTEX_SHADER_EXT);
|
||||
|
@ -1751,7 +1751,7 @@ bool CDriverGL::activeEXTVertexShader(CVertexProgram *program)
|
|||
|
||||
bool CDriverGL::compileVertexProgram(NL3D::CVertexProgram *program)
|
||||
{
|
||||
if (program->_DrvInfo == NULL)
|
||||
if (program->m_DrvInfo == NULL)
|
||||
{
|
||||
// Extension
|
||||
if (_Extensions.NVVertexProgram)
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace NL3D
|
|||
|
||||
// ***************************************************************************
|
||||
|
||||
CGeometryProgram::CGeometryProgram(CGPUProgramSourceCont *programSource) : _Info(NULL), IGPUProgram(programSource)
|
||||
CGeometryProgram::CGeometryProgram()
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -41,19 +41,9 @@ CGeometryProgram::CGeometryProgram(CGPUProgramSourceCont *programSource) : _Info
|
|||
|
||||
CGeometryProgram::~CGeometryProgram ()
|
||||
{
|
||||
delete _Info;
|
||||
_Info = NULL;
|
||||
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
void CGeometryProgram::buildInfo(const char *displayName, uint features)
|
||||
{
|
||||
nlassert(_Info == NULL);
|
||||
_Info = new CGeometryProgramInfo();
|
||||
CGeometryProgramInfo *info = _Info;
|
||||
info->DisplayName = displayName;
|
||||
info->Features = features;
|
||||
}
|
||||
|
||||
} // NL3D
|
||||
|
|
|
@ -66,17 +66,144 @@ IGPUProgram::IGPUProgram()
|
|||
|
||||
// ***************************************************************************
|
||||
|
||||
IGPUProgram::IGPUProgram(CGPUProgramSourceCont *programSource) : _ProgramSource(programSource)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
IGPUProgram::~IGPUProgram()
|
||||
{
|
||||
// Must kill the drv mirror of this program.
|
||||
_DrvInfo.kill();
|
||||
m_DrvInfo.kill();
|
||||
}
|
||||
|
||||
void IGPUProgram::buildInfo(CSource *source)
|
||||
{
|
||||
nlassert(!m_Source);
|
||||
|
||||
m_Source = source;
|
||||
|
||||
// Fill index cache
|
||||
CGPUProgramFeatures &features = m_Source->Features;
|
||||
TProfile profile = m_Source->Profile; // for special cases
|
||||
|
||||
if (features.DriverFlags & CGPUProgramFeatures::ModelView)
|
||||
{
|
||||
m_Indices.ModelView = getUniformIndex("nlModelView");
|
||||
if (m_Indices.ModelView == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlModelView' in gpu program '%s', ModelView disabled", source->DisplayName.c_str());
|
||||
features.DriverFlags &= ~CGPUProgramFeatures::ModelView;
|
||||
}
|
||||
}
|
||||
if (features.DriverFlags & CGPUProgramFeatures::ModelViewInverse)
|
||||
{
|
||||
m_Indices.ModelViewInverse = getUniformIndex("nlModelViewInverse");
|
||||
if (m_Indices.ModelViewInverse == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlModelViewInverse' in gpu program '%s', ModelViewInverse disabled", source->DisplayName.c_str());
|
||||
features.DriverFlags &= ~CGPUProgramFeatures::ModelViewInverse;
|
||||
}
|
||||
}
|
||||
if (features.DriverFlags & CGPUProgramFeatures::ModelViewTranspose)
|
||||
{
|
||||
m_Indices.ModelViewTranspose = getUniformIndex("nlModelViewTranspose");
|
||||
if (m_Indices.ModelViewTranspose == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlModelViewTranspose' in gpu program '%s', ModelViewTranspose disabled", source->DisplayName.c_str());
|
||||
features.DriverFlags &= ~CGPUProgramFeatures::ModelViewTranspose;
|
||||
}
|
||||
}
|
||||
if (features.DriverFlags & CGPUProgramFeatures::ModelViewInverseTranspose)
|
||||
{
|
||||
m_Indices.ModelViewInverseTranspose = getUniformIndex("nlModelViewInverseTranspose");
|
||||
if (m_Indices.ModelViewInverseTranspose == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlModelViewInverseTranspose' in gpu program '%s', ModelViewInverseTranspose disabled", source->DisplayName.c_str());
|
||||
features.DriverFlags &= ~CGPUProgramFeatures::ModelViewInverseTranspose;
|
||||
}
|
||||
}
|
||||
if (features.DriverFlags & CGPUProgramFeatures::Projection)
|
||||
{
|
||||
m_Indices.Projection = getUniformIndex("nlProjection");
|
||||
if (m_Indices.Projection == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlProjection' in gpu program '%s', Projection disabled", source->DisplayName.c_str());
|
||||
features.DriverFlags &= ~CGPUProgramFeatures::Projection;
|
||||
}
|
||||
}
|
||||
if (features.DriverFlags & CGPUProgramFeatures::ProjectionInverse)
|
||||
{
|
||||
m_Indices.ProjectionInverse = getUniformIndex("nlProjectionInverse");
|
||||
if (m_Indices.ProjectionInverse == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlProjectionInverse' in gpu program '%s', ProjectionInverse disabled", source->DisplayName.c_str());
|
||||
features.DriverFlags &= ~CGPUProgramFeatures::ProjectionInverse;
|
||||
}
|
||||
}
|
||||
if (features.DriverFlags & CGPUProgramFeatures::ProjectionTranspose)
|
||||
{
|
||||
m_Indices.ProjectionTranspose = getUniformIndex("nlProjectionTranspose");
|
||||
if (m_Indices.ProjectionTranspose == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlProjectionTranspose' in gpu program '%s', ProjectionTranspose disabled", source->DisplayName.c_str());
|
||||
features.DriverFlags &= ~CGPUProgramFeatures::ProjectionTranspose;
|
||||
}
|
||||
}
|
||||
if (features.DriverFlags & CGPUProgramFeatures::ProjectionInverseTranspose)
|
||||
{
|
||||
m_Indices.ProjectionInverseTranspose = getUniformIndex("nlProjectionInverseTranspose");
|
||||
if (m_Indices.ProjectionInverseTranspose == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlProjectionInverseTranspose' in gpu program '%s', ProjectionInverseTranspose disabled", source->DisplayName.c_str());
|
||||
features.DriverFlags &= ~CGPUProgramFeatures::ProjectionInverseTranspose;
|
||||
}
|
||||
}
|
||||
if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjection)
|
||||
{
|
||||
m_Indices.ModelViewProjection = getUniformIndex("nlModelViewProjection");
|
||||
if (m_Indices.ModelViewProjection == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlModelViewProjection' in gpu program '%s', ModelViewProjection disabled", source->DisplayName.c_str());
|
||||
features.DriverFlags &= ~CGPUProgramFeatures::ModelViewProjection;
|
||||
}
|
||||
}
|
||||
if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjectionInverse)
|
||||
{
|
||||
m_Indices.ModelViewProjectionInverse = getUniformIndex("nlModelViewProjectionInverse");
|
||||
if (m_Indices.ModelViewProjectionInverse == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlModelViewProjectionInverse' in gpu program '%s', ModelViewProjectionInverse disabled", source->DisplayName.c_str());
|
||||
features.DriverFlags &= ~CGPUProgramFeatures::ModelViewProjectionInverse;
|
||||
}
|
||||
}
|
||||
if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjectionTranspose)
|
||||
{
|
||||
m_Indices.ModelViewProjectionTranspose = getUniformIndex("nlModelViewProjectionTranspose");
|
||||
if (m_Indices.ModelViewProjectionTranspose == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlModelViewProjectionTranspose' in gpu program '%s', ModelViewProjectionTranspose disabled", source->DisplayName.c_str());
|
||||
features.DriverFlags &= ~CGPUProgramFeatures::ModelViewProjectionTranspose;
|
||||
}
|
||||
}
|
||||
if (features.DriverFlags & CGPUProgramFeatures::ModelViewProjectionInverseTranspose)
|
||||
{
|
||||
m_Indices.ModelViewProjectionInverseTranspose = getUniformIndex("nlModelViewProjectionInverseTranspose");
|
||||
if (m_Indices.ModelViewProjectionInverseTranspose == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlModelViewProjectionInverseTranspose' in gpu program '%s', ModelViewProjectionInverseTranspose disabled", source->DisplayName.c_str());
|
||||
features.DriverFlags &= ~CGPUProgramFeatures::ModelViewProjectionInverseTranspose;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Rough example, modify as necessary.
|
||||
//
|
||||
/*if (features.DriverFlags & CGPUProgramFeatures::DriverAmbient || features.MaterialFlags & CGPUProgramFeatures::MaterialAmbient)
|
||||
{
|
||||
m_Indices.Ambient = getUniformIndex("nlAmbient");
|
||||
if (m_Indices.Ambient == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlAmbient' in gpu program '%s', Ambient disabled", source->DisplayName.c_str());
|
||||
features.DriverFlags &= ~CGPUProgramFeatures::DriverAmbient;
|
||||
features.MaterialFlags &= ~CGPUProgramFeatures::MaterialAmbient;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
} /* namespace NL3D */
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
/**
|
||||
* \file gpu_program_source.cpp
|
||||
* \brief CGPUProgramSource
|
||||
* \date 2013-09-07 14:54GMT
|
||||
* \author Jan Boon (Kaetemi)
|
||||
* CGPUProgramSource
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2013 by authors
|
||||
*
|
||||
* This file is part of NL3D.
|
||||
* NL3D 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.
|
||||
*
|
||||
* NL3D 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 NL3D. If not, see
|
||||
* <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <nel/misc/types_nl.h>
|
||||
#include <nel/3d/gpu_program_source.h>
|
||||
|
||||
// STL includes
|
||||
|
||||
// NeL includes
|
||||
// #include <nel/misc/debug.h>
|
||||
|
||||
// Project includes
|
||||
|
||||
using namespace std;
|
||||
// using namespace NLMISC;
|
||||
|
||||
namespace NL3D {
|
||||
|
||||
void gpu_program_source_cpp_dummy() { }
|
||||
|
||||
} /* namespace NL3D */
|
||||
|
||||
/* end of file */
|
|
@ -32,7 +32,7 @@ namespace NL3D
|
|||
|
||||
// ***************************************************************************
|
||||
|
||||
CPixelProgram::CPixelProgram(CGPUProgramSourceCont *programSource) : _Info(NULL), IGPUProgram(programSource)
|
||||
CPixelProgram::CPixelProgram()
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -41,39 +41,9 @@ CPixelProgram::CPixelProgram(CGPUProgramSourceCont *programSource) : _Info(NULL)
|
|||
|
||||
CPixelProgram::~CPixelProgram ()
|
||||
{
|
||||
delete _Info;
|
||||
_Info = NULL;
|
||||
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
void CPixelProgram::buildInfo(const char *displayName, uint features)
|
||||
{
|
||||
nlassert(_Info == NULL);
|
||||
_Info = new CPixelProgramInfo();
|
||||
CPixelProgramInfo *info = _Info;
|
||||
info->DisplayName = displayName;
|
||||
info->Features = features;
|
||||
if (features & CPixelProgramInfo::Fog)
|
||||
{
|
||||
if (features & CPixelProgramInfo::DynamicFog)
|
||||
{
|
||||
info->FogEnabledIdx = getParamIdx("nlFogEnabled");
|
||||
if (info->FogEnabledIdx == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlFogEnabled' in gpu program '%s', DynamicFog disabled", displayName);
|
||||
info->Features &= ~CPixelProgramInfo::DynamicFog;
|
||||
}
|
||||
}
|
||||
info->FogStartEndIdx = getParamIdx("nlFogStartEnd");
|
||||
info->FogColorIdx = getParamIdx("nlFogColor");
|
||||
if (info->FogStartEndIdx == ~0
|
||||
|| info->FogStartEndIdx == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlFogStartEnd/nlFogColor' in gpu program '%s', Fog disabled", displayName);
|
||||
info->Features &= ~CPixelProgramInfo::Fog;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // NL3D
|
||||
|
|
|
@ -116,10 +116,8 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver)
|
|||
|
||||
NL3D::IDriver *drvInternal = (static_cast<CDriverUser *>(driver))->getDriver();
|
||||
|
||||
CGPUProgramSource *source = new CGPUProgramSource();
|
||||
CGPUProgramSourceCont *sourceCont = new CGPUProgramSourceCont();
|
||||
sourceCont->Sources.push_back(source);
|
||||
source->Features = CPixelProgramInfo::MaterialTextures;
|
||||
IGPUProgram::CSource *source = new IGPUProgram::CSource();
|
||||
source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages;
|
||||
|
||||
/*if (drvInternal->supportPixelProgram(CPixelProgram::fp40) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures())
|
||||
{
|
||||
|
@ -131,7 +129,8 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver)
|
|||
nldebug("VR: arbfp1");
|
||||
source->Profile = IGPUProgram::arbfp1;
|
||||
source->setSourcePtr(a_arbfp1);
|
||||
m_PixelProgram = new CPixelProgram(sourceCont);
|
||||
m_PixelProgram = new CPixelProgram();
|
||||
m_PixelProgram->addSource(source);
|
||||
}
|
||||
/*else if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0))
|
||||
{
|
||||
|
|
|
@ -239,31 +239,37 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver)
|
|||
|
||||
NL3D::IDriver *drvInternal = (static_cast<CDriverUser *>(driver))->getDriver();
|
||||
|
||||
CGPUProgramSource *source = new CGPUProgramSource();
|
||||
CGPUProgramSourceCont *sourceCont = new CGPUProgramSourceCont();
|
||||
sourceCont->Sources.push_back(source);
|
||||
source->Features = CPixelProgramInfo::MaterialTextures;
|
||||
m_PixelProgram = new CPixelProgram();
|
||||
|
||||
IGPUProgram::CSource *source = new IGPUProgram::CSource();
|
||||
source->Features.MaterialFlags = CGPUProgramFeatures::TextureStages;
|
||||
source->Profile = IGPUProgram::none;
|
||||
if (drvInternal->supportPixelProgram(CPixelProgram::fp40) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures())
|
||||
{
|
||||
nldebug("VR: fp40");
|
||||
source->Profile = IGPUProgram::fp40;
|
||||
source->setSourcePtr(g_StereoOVR_fp40);
|
||||
m_PixelProgram = new CPixelProgram(sourceCont);
|
||||
m_PixelProgram->addSource(source);
|
||||
}
|
||||
else if (drvInternal->supportPixelProgram(CPixelProgram::arbfp1) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures())
|
||||
{
|
||||
nldebug("VR: arbfp1");
|
||||
source->Profile = IGPUProgram::arbfp1;
|
||||
source->setSourcePtr(g_StereoOVR_arbfp1);
|
||||
m_PixelProgram = new CPixelProgram(sourceCont);
|
||||
m_PixelProgram->addSource(source);
|
||||
}
|
||||
else if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0))
|
||||
{
|
||||
nldebug("VR: ps_2_0");
|
||||
source->Profile = IGPUProgram::ps_2_0;
|
||||
source->setSourcePtr(g_StereoOVR_ps_2_0);
|
||||
m_PixelProgram = new CPixelProgram(sourceCont);
|
||||
m_PixelProgram->addSource(source);
|
||||
}
|
||||
|
||||
if (!drvInternal->compilePixelProgram(m_PixelProgram))
|
||||
{
|
||||
delete m_PixelProgram;
|
||||
m_PixelProgram = NULL;
|
||||
}
|
||||
|
||||
if (m_PixelProgram)
|
||||
|
|
|
@ -26,129 +26,26 @@ namespace NL3D
|
|||
|
||||
// ***************************************************************************
|
||||
|
||||
CVertexProgram::CVertexProgram(CGPUProgramSourceCont *programSource) : _Info(NULL), IGPUProgram(programSource)
|
||||
CVertexProgram::CVertexProgram()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
CVertexProgram::CVertexProgram(const char *nelvp) : _Info(NULL)
|
||||
CVertexProgram::CVertexProgram(const char *nelvp)
|
||||
{
|
||||
CGPUProgramSource *source = new CGPUProgramSource();
|
||||
_ProgramSource = new CGPUProgramSourceCont();
|
||||
_ProgramSource->Sources.push_back(source);
|
||||
CSource *source = new CSource();
|
||||
source->Profile = IGPUProgram::nelvp;
|
||||
source->setSource(nelvp);
|
||||
source->Features = 0;
|
||||
addSource(source);
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
CVertexProgram::~CVertexProgram ()
|
||||
{
|
||||
delete _Info;
|
||||
_Info = NULL;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
void CVertexProgram::buildInfo(const char *displayName, uint features)
|
||||
{
|
||||
nlassert(_Info == NULL);
|
||||
_Info = new CVertexProgramInfo();
|
||||
CVertexProgramInfo *info = _Info;
|
||||
info->DisplayName = displayName;
|
||||
info->Features = features;
|
||||
if (features & CVertexProgramInfo::Ambient)
|
||||
{
|
||||
info->AmbientIdx = getParamIdx("nlAmbient");
|
||||
if (info->AmbientIdx == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlAmbient' in gpu program '%s', Ambient disabled", displayName);
|
||||
info->Features &= ~CVertexProgramInfo::Ambient;
|
||||
}
|
||||
}
|
||||
if (features & CVertexProgramInfo::Sun)
|
||||
{
|
||||
if (features & CVertexProgramInfo::DynamicLights)
|
||||
{
|
||||
info->SunEnabledIdx = getParamIdx("nlSunEnabled");
|
||||
if (info->SunEnabledIdx == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlSunEnabled' in gpu program '%s', DynamicLights disabled", displayName);
|
||||
info->Features &= ~CVertexProgramInfo::DynamicLights;
|
||||
}
|
||||
}
|
||||
info->SunDirectionIdx = getParamIdx("nlSunDirection");
|
||||
info->SunDiffuseIdx = getParamIdx("nlSunDiffuse");
|
||||
if (info->SunDirectionIdx == ~0
|
||||
|| info->SunDiffuseIdx == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlSunDirection/nlSunDiffuse' in gpu program '%s', Sun disabled", displayName);
|
||||
info->Features &= ~CVertexProgramInfo::Sun;
|
||||
}
|
||||
}
|
||||
if (features & CVertexProgramInfo::PointLight0)
|
||||
{
|
||||
if (features & CVertexProgramInfo::DynamicLights)
|
||||
{
|
||||
info->PointLight0EnabledIdx = getParamIdx("nlPointLight0Enabled");
|
||||
if (info->PointLight0EnabledIdx == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlPointLight0Enabled' in gpu program '%s', DynamicLights disabled", displayName);
|
||||
info->Features &= ~CVertexProgramInfo::DynamicLights;
|
||||
}
|
||||
}
|
||||
info->PointLight0PositionIdx = getParamIdx("nlPointLight0Position");
|
||||
info->PointLight0DiffuseIdx = getParamIdx("nlPointLight0Diffuse");
|
||||
if (info->PointLight0PositionIdx == ~0
|
||||
|| info->PointLight0DiffuseIdx == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlPointLight0Position/nlPointLight0Diffuse' in gpu program '%s', PointLight0 disabled", displayName);
|
||||
info->Features &= ~CVertexProgramInfo::PointLight0;
|
||||
}
|
||||
}
|
||||
if (features & CVertexProgramInfo::PointLight1)
|
||||
{
|
||||
if (features & CVertexProgramInfo::DynamicLights)
|
||||
{
|
||||
info->PointLight1EnabledIdx = getParamIdx("nlPointLight1Enabled");
|
||||
if (info->PointLight1EnabledIdx == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlPointLight1Enabled' in gpu program '%s', DynamicLights disabled", displayName);
|
||||
info->Features &= ~CVertexProgramInfo::DynamicLights;
|
||||
}
|
||||
}
|
||||
info->PointLight1PositionIdx = getParamIdx("nlPointLight1Position");
|
||||
info->PointLight1DiffuseIdx = getParamIdx("nlPointLight1Diffuse");
|
||||
if (info->PointLight1PositionIdx == ~0
|
||||
|| info->PointLight1DiffuseIdx == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlPointLight1Position/nlPointLight1Diffuse' in gpu program '%s', PointLight1 disabled", displayName);
|
||||
info->Features &= ~CVertexProgramInfo::PointLight1;
|
||||
}
|
||||
}
|
||||
if (features & CVertexProgramInfo::PointLight2)
|
||||
{
|
||||
if (features & CVertexProgramInfo::DynamicLights)
|
||||
{
|
||||
info->PointLight2EnabledIdx = getParamIdx("nlPointLight2Enabled");
|
||||
if (info->PointLight2EnabledIdx == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlPointLight2Enabled' in gpu program '%s', DynamicLights disabled", displayName);
|
||||
info->Features &= ~CVertexProgramInfo::DynamicLights;
|
||||
}
|
||||
}
|
||||
info->PointLight2PositionIdx = getParamIdx("nlPointLight2Position");
|
||||
info->PointLight2DiffuseIdx = getParamIdx("nlPointLight2Diffuse");
|
||||
if (info->PointLight2PositionIdx == ~0
|
||||
|| info->PointLight2DiffuseIdx == ~0)
|
||||
{
|
||||
nlwarning("Missing 'nlPointLight2Position/nlPointLight2Diffuse' in gpu program '%s', PointLight2 disabled", displayName);
|
||||
info->Features &= ~CVertexProgramInfo::PointLight2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // NL3D
|
||||
|
|
Loading…
Reference in a new issue