mirror of
https://port.numenaute.org/aleajactaest/khanat-opennel-code.git
synced 2024-11-19 13:46:13 +00:00
Implement new driver interface in OpenGL driver
This commit is contained in:
parent
381ffd1bc6
commit
fd0b45c1db
5 changed files with 793 additions and 758 deletions
|
@ -161,9 +161,9 @@ public:
|
|||
|
||||
enum TProgram
|
||||
{
|
||||
VertexProgram,
|
||||
PixelProgram,
|
||||
GeometryProgram
|
||||
VertexProgram = 0,
|
||||
PixelProgram = 1,
|
||||
GeometryProgram = 2
|
||||
};
|
||||
|
||||
protected:
|
||||
|
@ -1105,19 +1105,17 @@ public:
|
|||
*/
|
||||
virtual bool supportVertexProgram(CVertexProgram::TProfile profile = CVertexProgram::nelvp) const = 0;
|
||||
|
||||
/** Compile the given vertex program, return if successful. Error information is returned as a string.
|
||||
/** Compile the given vertex program, return if successful.
|
||||
* If a vertex program was set active before compilation,
|
||||
* the state of the active vertex program is undefined behaviour afterwards.
|
||||
*/
|
||||
virtual bool compileVertexProgram(CVertexProgram *program, std::string &error) const = 0;
|
||||
virtual bool compileVertexProgram(CVertexProgram *program) = 0;
|
||||
|
||||
/** Set the active vertex program. This will override vertex programs specified in CMaterial render calls.
|
||||
* Also used internally by setupMaterial(CMaterial) when getVertexProgram returns NULL.
|
||||
* The vertex program is activated immediately.
|
||||
*/
|
||||
virtual bool activeVertexProgram(CVertexProgram *program) = 0;
|
||||
|
||||
/** Get the currently active vertex program.
|
||||
*/
|
||||
virtual CVertexProgram *getActiveVertexProgram() const = 0;
|
||||
// @}
|
||||
|
||||
|
||||
|
@ -1134,19 +1132,17 @@ public:
|
|||
*/
|
||||
virtual bool supportPixelProgram(CPixelProgram::TProfile profile) const = 0;
|
||||
|
||||
/** Compile the given pixel program, return if successful. Error information is returned as a string.
|
||||
/** 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 compilePixelProgram(CPixelProgram *program, std::string &error) const = 0;
|
||||
virtual bool compilePixelProgram(CPixelProgram *program) = 0;
|
||||
|
||||
/** Set the active pixel program. This will override pixel programs specified in CMaterial render calls.
|
||||
* Also used internally by setupMaterial(CMaterial) when getPixelProgram returns NULL.
|
||||
* The pixel program is activated immediately.
|
||||
*/
|
||||
virtual bool activePixelProgram(CPixelProgram *program) = 0;
|
||||
|
||||
/** Get the currently active pixel program.
|
||||
*/
|
||||
virtual CPixelProgram *getActivePixelProgram() const = 0;
|
||||
// @}
|
||||
|
||||
|
||||
|
|
|
@ -1299,45 +1299,115 @@ private:
|
|||
|
||||
// @}
|
||||
|
||||
/// \name Vertex program interface
|
||||
|
||||
|
||||
|
||||
|
||||
/// \name Vertex Program
|
||||
// @{
|
||||
|
||||
bool supportVertexProgram () const;
|
||||
bool supportPixelProgram () const;
|
||||
bool supportPixelProgram (CPixelProgram::TProfile profile) const;
|
||||
bool isVertexProgramEmulated () const;
|
||||
bool activeVertexProgram (CVertexProgram *program);
|
||||
bool activePixelProgram (CPixelProgram *program);
|
||||
void setConstant (uint index, float, float, float, float);
|
||||
void setConstant (uint index, double, double, double, double);
|
||||
void setConstant (uint indexStart, const NLMISC::CVector& value);
|
||||
void setConstant (uint indexStart, const NLMISC::CVectorD& value);
|
||||
void setConstant (uint index, uint num, const float *src);
|
||||
void setConstant (uint index, uint num, const double *src);
|
||||
void setConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform);
|
||||
void setConstantFog (uint index);
|
||||
void enableVertexProgramDoubleSidedColor(bool doubleSided);
|
||||
bool supportVertexProgramDoubleSidedColor() const;
|
||||
|
||||
// Pixel program
|
||||
virtual void setPixelProgramConstant (uint index, float, float, float, float);
|
||||
virtual void setPixelProgramConstant (uint index, double, double, double, double);
|
||||
virtual void setPixelProgramConstant (uint index, const NLMISC::CVector& value);
|
||||
virtual void setPixelProgramConstant (uint index, const NLMISC::CVectorD& value);
|
||||
virtual void setPixelProgramConstant (uint index, uint num, const float *src);
|
||||
virtual void setPixelProgramConstant (uint index, uint num, const double *src);
|
||||
virtual void setPixelProgramConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform);
|
||||
// Order of preference
|
||||
// - activeVertexProgram
|
||||
// - CMaterial pass[n] VP (uses activeVertexProgram, but does not override if one already set by code)
|
||||
// - default generic VP that mimics fixed pipeline / no VP with fixed pipeline
|
||||
|
||||
/**
|
||||
* Does the driver supports vertex program, but emulated by CPU ?
|
||||
*/
|
||||
virtual bool isVertexProgramEmulated() const;
|
||||
|
||||
/** Return true if the driver supports the specified vertex program profile.
|
||||
*/
|
||||
virtual bool supportVertexProgram(CVertexProgram::TProfile profile = CVertexProgram::nelvp) const;
|
||||
|
||||
/** Compile the given vertex program, return if successful.
|
||||
* If a vertex program was set active before compilation,
|
||||
* the state of the active vertex program is undefined behaviour afterwards.
|
||||
*/
|
||||
virtual bool compileVertexProgram(CVertexProgram *program);
|
||||
|
||||
/** Set the active vertex program. This will override vertex programs specified in CMaterial render calls.
|
||||
* Also used internally by setupMaterial(CMaterial) when getVertexProgram returns NULL.
|
||||
* The vertex program is activated immediately.
|
||||
*/
|
||||
virtual bool activeVertexProgram(CVertexProgram *program);
|
||||
// @}
|
||||
|
||||
|
||||
|
||||
/// \name Pixel Program
|
||||
// @{
|
||||
|
||||
// Order of preference
|
||||
// - activePixelProgram
|
||||
// - CMaterial pass[n] PP (uses activePixelProgram, but does not override if one already set by code)
|
||||
// - PP generated from CMaterial (uses activePixelProgram, but does not override if one already set by code)
|
||||
|
||||
/** Return true if the driver supports the specified pixel program profile.
|
||||
*/
|
||||
virtual bool supportPixelProgram(CPixelProgram::TProfile profile = CPixelProgram::arbfp1) const;
|
||||
|
||||
/** 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 compilePixelProgram(CPixelProgram *program);
|
||||
|
||||
/** Set the active pixel program. This will override pixel programs specified in CMaterial render calls.
|
||||
* Also used internally by setupMaterial(CMaterial) when getPixelProgram returns NULL.
|
||||
* The pixel program is activated immediately.
|
||||
*/
|
||||
virtual bool activePixelProgram(CPixelProgram *program);
|
||||
// @}
|
||||
|
||||
|
||||
|
||||
/// \name Program parameters
|
||||
// @{
|
||||
// Set parameters
|
||||
virtual void setUniform1f(TProgram program, uint index, float f0);
|
||||
virtual void setUniform2f(TProgram program, uint index, float f0, float f1);
|
||||
virtual void setUniform3f(TProgram program, uint index, float f0, float f1, float f2);
|
||||
virtual void setUniform4f(TProgram program, uint index, float f0, float f1, float f2, float f3);
|
||||
virtual void setUniform1i(TProgram program, uint index, sint32 i0);
|
||||
virtual void setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1);
|
||||
virtual void setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2);
|
||||
virtual void setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3);
|
||||
virtual void setUniform1ui(TProgram program, uint index, uint32 ui0);
|
||||
virtual void setUniform2ui(TProgram program, uint index, uint32 ui0, uint32 ui1);
|
||||
virtual void setUniform3ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2);
|
||||
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 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);
|
||||
virtual void setUniform4uiv(TProgram program, uint index, size_t num, const uint32 *src);
|
||||
// Set builtin parameters
|
||||
virtual void setUniformMatrix(TProgram program, uint index, TMatrix matrix, TTransform transform);
|
||||
virtual void setUniformFog(TProgram program, uint index);
|
||||
// @}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
virtual void enableVertexProgramDoubleSidedColor(bool doubleSided);
|
||||
virtual bool supportVertexProgramDoubleSidedColor() const;
|
||||
|
||||
virtual bool supportMADOperator() const ;
|
||||
|
||||
|
||||
// @}
|
||||
|
||||
/// \name Vertex program implementation
|
||||
// @{
|
||||
bool activeNVVertexProgram (CVertexProgram *program);
|
||||
bool activeARBVertexProgram (CVertexProgram *program);
|
||||
bool activeEXTVertexShader (CVertexProgram *program);
|
||||
|
||||
bool compileNVVertexProgram (CVertexProgram *program);
|
||||
bool compileARBVertexProgram (CVertexProgram *program);
|
||||
bool compileEXTVertexShader (CVertexProgram *program);
|
||||
//@}
|
||||
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ namespace NLDRIVERGL {
|
|||
#endif
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
CPixelProgamDrvInfosGL::CPixelProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it) : IGPUProgramDrvInfos (drv, it)
|
||||
{
|
||||
H_AUTO_OGL(CPixelProgamDrvInfosGL_CPixelProgamDrvInfosGL)
|
||||
|
@ -63,11 +64,7 @@ CPixelProgamDrvInfosGL::CPixelProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoP
|
|||
}
|
||||
|
||||
// ***************************************************************************
|
||||
bool CDriverGL::supportPixelProgram() const
|
||||
{
|
||||
H_AUTO_OGL(CPixelProgamDrvInfosGL_supportPixelProgram)
|
||||
return _Extensions.ARBFragmentProgram;
|
||||
}
|
||||
|
||||
bool CDriverGL::supportPixelProgram(CPixelProgram::TProfile profile) const
|
||||
{
|
||||
H_AUTO_OGL(CPixelProgamDrvInfosGL_supportPixelProgram_profile)
|
||||
|
@ -82,6 +79,7 @@ bool CDriverGL::supportPixelProgram(CPixelProgram::TProfile profile) const
|
|||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
bool CDriverGL::activePixelProgram(CPixelProgram *program)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_activePixelProgram)
|
||||
|
@ -95,59 +93,68 @@ bool CDriverGL::activePixelProgram(CPixelProgram *program)
|
|||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
bool CDriverGL::compilePixelProgram(NL3D::CPixelProgram *program)
|
||||
{
|
||||
// Program setuped ?
|
||||
if (program->_DrvInfo == NULL)
|
||||
{
|
||||
glDisable(GL_FRAGMENT_PROGRAM_ARB);
|
||||
_PixelProgramEnabled = false;
|
||||
|
||||
// Insert into driver list. (so it is deleted when driver is deleted).
|
||||
ItGPUPrgDrvInfoPtrList it = _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL);
|
||||
|
||||
// Create a driver info
|
||||
CPixelProgamDrvInfosGL *drvInfo;
|
||||
*it = drvInfo = new CPixelProgamDrvInfosGL(this, it);
|
||||
// Set the pointer
|
||||
program->_DrvInfo = drvInfo;
|
||||
|
||||
if (!setupPixelProgram(program, drvInfo->ID))
|
||||
{
|
||||
delete drvInfo;
|
||||
program->_DrvInfo = NULL;
|
||||
_GPUPrgDrvInfos.erase(it);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
bool CDriverGL::activeARBPixelProgram(CPixelProgram *program)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_activeARBPixelProgram)
|
||||
|
||||
// Setup or unsetup ?
|
||||
if (program)
|
||||
{
|
||||
// Driver info
|
||||
CPixelProgamDrvInfosGL *drvInfo;
|
||||
|
||||
{
|
||||
// Program setuped ?
|
||||
if (program->_DrvInfo==NULL)
|
||||
{
|
||||
// Insert into driver list. (so it is deleted when driver is deleted).
|
||||
ItGPUPrgDrvInfoPtrList it = _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL);
|
||||
if (!CDriverGL::compilePixelProgram(program)) return false;
|
||||
|
||||
// Create a driver info
|
||||
*it = drvInfo = new CPixelProgamDrvInfosGL(this, it);
|
||||
// Set the pointer
|
||||
program->_DrvInfo = drvInfo;
|
||||
|
||||
if (!setupPixelProgram(program, drvInfo->ID))
|
||||
{
|
||||
delete drvInfo;
|
||||
program->_DrvInfo = NULL;
|
||||
_GPUPrgDrvInfos.erase(it);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Cast the driver info pointer
|
||||
drvInfo=safe_cast<CPixelProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->_DrvInfo);
|
||||
}
|
||||
glEnable( GL_FRAGMENT_PROGRAM_ARB );
|
||||
// Cast the driver info pointer
|
||||
CPixelProgamDrvInfosGL *drvInfo = safe_cast<CPixelProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->_DrvInfo);
|
||||
|
||||
glEnable(GL_FRAGMENT_PROGRAM_ARB);
|
||||
_PixelProgramEnabled = true;
|
||||
nglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, drvInfo->ID );
|
||||
|
||||
glDisable( GL_COLOR_SUM_ARB ); // no specular written
|
||||
nglBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, drvInfo->ID);
|
||||
|
||||
_LastSetuppedPP = program;
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable( GL_FRAGMENT_PROGRAM_ARB );
|
||||
glDisable( GL_COLOR_SUM_ARB );
|
||||
_PixelProgramEnabled = false;
|
||||
glDisable(GL_FRAGMENT_PROGRAM_ARB);
|
||||
_PixelProgramEnabled = false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
bool CDriverGL::setupPixelProgram(CPixelProgram *program, GLuint id/*, bool &specularWritten*/)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setupARBPixelProgram)
|
||||
|
@ -170,9 +177,9 @@ bool CDriverGL::setupPixelProgram(CPixelProgram *program, GLuint id/*, bool &spe
|
|||
}
|
||||
|
||||
// Compile the program
|
||||
nglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, id);
|
||||
nglBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, id);
|
||||
glGetError();
|
||||
nglProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, source->SourceLen, source->SourcePtr);
|
||||
nglProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, source->SourceLen, source->SourcePtr);
|
||||
GLenum err = glGetError();
|
||||
if (err != GL_NO_ERROR)
|
||||
{
|
||||
|
@ -222,136 +229,6 @@ bool CDriverGL::setupPixelProgram(CPixelProgram *program, GLuint id/*, bool &spe
|
|||
return true;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
void CDriverGL::setPixelProgramConstant (uint index, float f0, float f1, float f2, float f3)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setPixelProgramConstant)
|
||||
|
||||
if (_Extensions.ARBFragmentProgram)
|
||||
nglProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, index, f0, f1, f2, f3);
|
||||
}
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
void CDriverGL::setPixelProgramConstant (uint index, double d0, double d1, double d2, double d3)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setPixelProgramConstant)
|
||||
|
||||
if (_Extensions.ARBFragmentProgram)
|
||||
nglProgramEnvParameter4dARB(GL_FRAGMENT_PROGRAM_ARB, index, d0, d1, d2, d3);
|
||||
}
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
void CDriverGL::setPixelProgramConstant (uint index, const NLMISC::CVector& value)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setPixelProgramConstant)
|
||||
|
||||
if (_Extensions.ARBFragmentProgram)
|
||||
nglProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, index, value.x, value.y, value.z, 0);
|
||||
}
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
void CDriverGL::setPixelProgramConstant (uint index, const NLMISC::CVectorD& value)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setPixelProgramConstant)
|
||||
|
||||
if (_Extensions.ARBFragmentProgram)
|
||||
nglProgramEnvParameter4dARB(GL_FRAGMENT_PROGRAM_ARB, index, value.x, value.y, value.z, 0);
|
||||
}
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
void CDriverGL::setPixelProgramConstant (uint index, uint num, const float *src)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setPixelProgramConstant)
|
||||
|
||||
if (_Extensions.ARBFragmentProgram)
|
||||
{
|
||||
for(uint k = 0; k < num; ++k)
|
||||
{
|
||||
nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + k, src + 4 * k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
void CDriverGL::setPixelProgramConstant (uint index, uint num, const double *src)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setPixelProgramConstant)
|
||||
|
||||
if (_Extensions.ARBFragmentProgram)
|
||||
{
|
||||
for(uint k = 0; k < num; ++k)
|
||||
{
|
||||
nglProgramEnvParameter4dvARB(GL_FRAGMENT_PROGRAM_ARB, index + k, src + 4 * k);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
void CDriverGL::setPixelProgramConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setPixelProgramConstantMatrix)
|
||||
|
||||
if (_Extensions.ARBFragmentProgram)
|
||||
{
|
||||
|
||||
// First, ensure that the render setup is correctly setuped.
|
||||
refreshRenderSetup();
|
||||
CMatrix mat;
|
||||
switch (matrix)
|
||||
{
|
||||
case IDriver::ModelView:
|
||||
mat = _ModelViewMatrix;
|
||||
break;
|
||||
case IDriver::Projection:
|
||||
{
|
||||
refreshProjMatrixFromGL();
|
||||
mat = _GLProjMat;
|
||||
}
|
||||
break;
|
||||
case IDriver::ModelViewProjection:
|
||||
refreshProjMatrixFromGL();
|
||||
mat = _GLProjMat * _ModelViewMatrix;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch(transform)
|
||||
{
|
||||
case IDriver::Identity: break;
|
||||
case IDriver::Inverse:
|
||||
mat.invert();
|
||||
break;
|
||||
case IDriver::Transpose:
|
||||
mat.transpose();
|
||||
break;
|
||||
case IDriver::InverseTranspose:
|
||||
mat.invert();
|
||||
mat.transpose();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mat.transpose();
|
||||
float matDatas[16];
|
||||
mat.get(matDatas);
|
||||
|
||||
nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index, matDatas);
|
||||
nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + 1, matDatas + 4);
|
||||
nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + 2, matDatas + 8);
|
||||
nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + 3, matDatas + 12);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef NL_STATIC
|
||||
} // NLDRIVERGL/ES
|
||||
#endif
|
||||
|
|
298
code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp
Normal file
298
code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp
Normal file
|
@ -0,0 +1,298 @@
|
|||
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
|
||||
// Copyright (C) 2010 Winch Gate Property Limited
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as
|
||||
// published by the Free Software Foundation, either version 3 of the
|
||||
// License, or (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
#include "stdopengl.h"
|
||||
|
||||
#include "driver_opengl.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace NLMISC;
|
||||
|
||||
namespace NL3D {
|
||||
|
||||
#ifdef NL_STATIC
|
||||
#ifdef USE_OPENGLES
|
||||
namespace NLDRIVERGLES {
|
||||
#else
|
||||
namespace NLDRIVERGL {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
inline void CDriverGL::setUniform4f(TProgram program, uint index, float f0, float f1, float f2, float f3)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setUniform4f);
|
||||
|
||||
#ifndef USE_OPENGLES
|
||||
switch (program)
|
||||
{
|
||||
case VertexProgram:
|
||||
if (_Extensions.NVVertexProgram)
|
||||
{
|
||||
// Setup constant
|
||||
nglProgramParameter4fNV(GL_VERTEX_PROGRAM_NV, index, f0, f1, f2, f3);
|
||||
}
|
||||
else if (_Extensions.ARBVertexProgram)
|
||||
{
|
||||
nglProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, index, f0, f1, f2, f3);
|
||||
}
|
||||
else if (_Extensions.EXTVertexShader)
|
||||
{
|
||||
float datas[] = { f0, f1, f2, f3 };
|
||||
nglSetInvariantEXT(_EVSConstantHandle + index, GL_FLOAT, datas);
|
||||
}
|
||||
break;
|
||||
case PixelProgram:
|
||||
if (_Extensions.ARBFragmentProgram)
|
||||
{
|
||||
nglProgramEnvParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, index, f0, f1, f2, f3);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void CDriverGL::setUniform4fv(TProgram program, uint index, size_t num, const float *src)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setUniform4fv);
|
||||
|
||||
#ifndef USE_OPENGLES
|
||||
switch (program)
|
||||
{
|
||||
case VertexProgram:
|
||||
if (_Extensions.NVVertexProgram)
|
||||
{
|
||||
nglProgramParameters4fvNV(GL_VERTEX_PROGRAM_NV, index, num, src);
|
||||
}
|
||||
else if (_Extensions.ARBVertexProgram) // ARB pixel and geometry program will only exist when ARB vertex program exists
|
||||
{
|
||||
for (uint k = 0; k < num; ++k)
|
||||
{
|
||||
nglProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, index + k, src + 4 * k);
|
||||
}
|
||||
}
|
||||
else if (_Extensions.EXTVertexShader)
|
||||
{
|
||||
for (uint k = 0; k < num; ++k)
|
||||
{
|
||||
nglSetInvariantEXT(_EVSConstantHandle + index + k, GL_FLOAT, (void *)(src + 4 * k));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PixelProgram:
|
||||
if (_Extensions.ARBFragmentProgram) // ARB pixel and geometry program will only exist when ARB vertex program exists
|
||||
{
|
||||
for (uint k = 0; k < num; ++k)
|
||||
{
|
||||
nglProgramEnvParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, index + k, src + 4 * k);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CDriverGL::setUniform1f(TProgram program, uint index, float f0)
|
||||
{
|
||||
CDriverGL::setUniform4f(program, index, f0, 0.f, 0.f, 0.f);
|
||||
}
|
||||
|
||||
void CDriverGL::setUniform2f(TProgram program, uint index, float f0, float f1)
|
||||
{
|
||||
CDriverGL::setUniform4f(program, index, f0, f1, 0.f, 0.f);
|
||||
}
|
||||
|
||||
void CDriverGL::setUniform3f(TProgram program, uint index, float f0, float f1, float f2)
|
||||
{
|
||||
CDriverGL::setUniform4f(program, index, f0, f1, f2, 0.0f);
|
||||
}
|
||||
|
||||
void CDriverGL::setUniform1i(TProgram program, uint index, sint32 i0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CDriverGL::setUniform2i(TProgram program, uint index, sint32 i0, sint32 i1)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CDriverGL::setUniform3i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CDriverGL::setUniform4i(TProgram program, uint index, sint32 i0, sint32 i1, sint32 i2, sint32 i3)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CDriverGL::setUniform1ui(TProgram program, uint index, uint32 ui0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CDriverGL::setUniform2ui(TProgram program, uint index, uint32 ui0, uint32 ui1)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CDriverGL::setUniform3ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CDriverGL::setUniform4ui(TProgram program, uint index, uint32 ui0, uint32 ui1, uint32 ui2, uint32 ui3)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CDriverGL::setUniform3f(TProgram program, uint index, const NLMISC::CVector& v)
|
||||
{
|
||||
CDriverGL::setUniform4f(program, index, v.x, v.y, v.z, 0.f);
|
||||
}
|
||||
|
||||
void CDriverGL::setUniform4f(TProgram program, uint index, const NLMISC::CVector& v, float f3)
|
||||
{
|
||||
CDriverGL::setUniform4f(program, index, v.x, v.y, v.z, f3);
|
||||
}
|
||||
|
||||
void CDriverGL::setUniform4x4f(TProgram program, uint index, const NLMISC::CMatrix& m)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setUniform4x4f);
|
||||
|
||||
// TODO: Verify this!
|
||||
NLMISC::CMatrix mat = m;
|
||||
mat.transpose();
|
||||
const float *md = mat.get();
|
||||
|
||||
CDriverGL::setUniform4fv(program, index, 4, md);
|
||||
}
|
||||
|
||||
void CDriverGL::setUniform4iv(TProgram program, uint index, size_t num, const sint32 *src)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CDriverGL::setUniform4uiv(TProgram program, uint index, size_t num, const uint32 *src)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const uint CDriverGL::GLMatrix[IDriver::NumMatrix]=
|
||||
{
|
||||
GL_MODELVIEW,
|
||||
GL_PROJECTION,
|
||||
#ifdef USE_OPENGLES
|
||||
GL_MODELVIEW
|
||||
#else
|
||||
GL_MODELVIEW_PROJECTION_NV
|
||||
#endif
|
||||
};
|
||||
|
||||
const uint CDriverGL::GLTransform[IDriver::NumTransform]=
|
||||
{
|
||||
#ifdef USE_OPENGLES
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
#else
|
||||
GL_IDENTITY_NV,
|
||||
GL_INVERSE_NV,
|
||||
GL_TRANSPOSE_NV,
|
||||
GL_INVERSE_TRANSPOSE_NV
|
||||
#endif
|
||||
};
|
||||
|
||||
void CDriverGL::setUniformMatrix(NL3D::IDriver::TProgram program, uint index, NL3D::IDriver::TMatrix matrix, NL3D::IDriver::TTransform transform)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setUniformMatrix);
|
||||
|
||||
#ifndef USE_OPENGLES
|
||||
// Vertex program exist ?
|
||||
if (program == VertexProgram && _Extensions.NVVertexProgram)
|
||||
{
|
||||
// First, ensure that the render setup is correclty setuped.
|
||||
refreshRenderSetup();
|
||||
|
||||
// Track the matrix
|
||||
nglTrackMatrixNV(GL_VERTEX_PROGRAM_NV, index, GLMatrix[matrix], GLTransform[transform]);
|
||||
// Release Track => matrix data is copied.
|
||||
nglTrackMatrixNV(GL_VERTEX_PROGRAM_NV, index, GL_NONE, GL_IDENTITY_NV);
|
||||
}
|
||||
else
|
||||
{
|
||||
// First, ensure that the render setup is correctly setuped.
|
||||
refreshRenderSetup();
|
||||
|
||||
CMatrix mat;
|
||||
switch (matrix)
|
||||
{
|
||||
case IDriver::ModelView:
|
||||
mat = _ModelViewMatrix;
|
||||
break;
|
||||
case IDriver::Projection:
|
||||
{
|
||||
refreshProjMatrixFromGL();
|
||||
mat = _GLProjMat;
|
||||
}
|
||||
break;
|
||||
case IDriver::ModelViewProjection:
|
||||
refreshProjMatrixFromGL();
|
||||
mat = _GLProjMat * _ModelViewMatrix;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch(transform)
|
||||
{
|
||||
case IDriver::Identity: break;
|
||||
case IDriver::Inverse:
|
||||
mat.invert();
|
||||
break;
|
||||
case IDriver::Transpose:
|
||||
mat.transpose();
|
||||
break;
|
||||
case IDriver::InverseTranspose:
|
||||
mat.invert();
|
||||
mat.transpose();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
mat.transpose();
|
||||
const float *md = mat.get();
|
||||
|
||||
CDriverGL::setUniform4fv(program, index, 4, md);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void CDriverGL::setUniformFog(NL3D::IDriver::TProgram program, uint index)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setUniformFog)
|
||||
|
||||
const float *values = _ModelViewMatrix.get();
|
||||
CDriverGL::setUniform4f(program, index, -values[2], -values[6], -values[10], -values[14]);
|
||||
}
|
||||
|
||||
#ifdef NL_STATIC
|
||||
} // NLDRIVERGL/ES
|
||||
#endif
|
||||
|
||||
} // NL3D
|
|
@ -70,23 +70,136 @@ CVertexProgamDrvInfosGL::CVertexProgamDrvInfosGL(CDriverGL *drv, ItGPUPrgDrvInfo
|
|||
|
||||
|
||||
// ***************************************************************************
|
||||
bool CDriverGL::supportVertexProgram () const
|
||||
bool CDriverGL::supportVertexProgram(CVertexProgram::TProfile profile) const
|
||||
{
|
||||
H_AUTO_OGL(CVertexProgamDrvInfosGL_supportVertexProgram)
|
||||
return _Extensions.NVVertexProgram || _Extensions.EXTVertexShader || _Extensions.ARBVertexProgram;
|
||||
return (profile == CVertexProgram::nelvp)
|
||||
&& (_Extensions.NVVertexProgram || _Extensions.EXTVertexShader || _Extensions.ARBVertexProgram);
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
bool CDriverGL::isVertexProgramEmulated () const
|
||||
bool CDriverGL::isVertexProgramEmulated() const
|
||||
{
|
||||
H_AUTO_OGL(CVertexProgamDrvInfosGL_isVertexProgramEmulated)
|
||||
return _Extensions.NVVertexProgramEmulated;
|
||||
}
|
||||
|
||||
bool CDriverGL::compileNVVertexProgram(CVertexProgram *program)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_compileNVVertexProgram);
|
||||
|
||||
#ifndef USE_OPENGLES
|
||||
|
||||
// Driver info
|
||||
CVertexProgamDrvInfosGL *drvInfo;
|
||||
|
||||
nlassert(!program->_DrvInfo);
|
||||
glDisable(GL_VERTEX_PROGRAM_NV);
|
||||
_VertexProgramEnabled = false;
|
||||
|
||||
// Find nelvp
|
||||
CGPUProgramSource *source = NULL;
|
||||
for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i)
|
||||
{
|
||||
if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp)
|
||||
{
|
||||
source = program->getProgramSource()->Sources[i];
|
||||
}
|
||||
}
|
||||
if (!source)
|
||||
{
|
||||
nlwarning("OpenGL driver only supports 'nelvp' profile, vertex program cannot be used");
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Check with our parser if the program will works with other implemented extensions, too. (EXT_vertex_shader ..).
|
||||
* There are some incompatibilities.
|
||||
*/
|
||||
CVPParser parser;
|
||||
CVPParser::TProgram parsedProgram;
|
||||
std::string errorOutput;
|
||||
bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput);
|
||||
if (!result)
|
||||
{
|
||||
nlwarning("Unable to parse a vertex program :");
|
||||
nlwarning(errorOutput.c_str());
|
||||
#ifdef NL_DEBUG
|
||||
nlassert(0);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// Insert into driver list. (so it is deleted when driver is deleted).
|
||||
ItGPUPrgDrvInfoPtrList it = _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL);
|
||||
|
||||
// Create a driver info
|
||||
*it = drvInfo = new CVertexProgamDrvInfosGL(this, it);
|
||||
|
||||
// Set the pointer
|
||||
program->_DrvInfo = drvInfo;
|
||||
|
||||
// Compile the program
|
||||
nglLoadProgramNV(GL_VERTEX_PROGRAM_NV, drvInfo->ID, (GLsizei)source->SourceLen, (const GLubyte*)source->SourcePtr);
|
||||
|
||||
// Get loading error code
|
||||
GLint errorOff;
|
||||
glGetIntegerv(GL_PROGRAM_ERROR_POSITION_NV, &errorOff);
|
||||
|
||||
// Compilation error ?
|
||||
if (errorOff >= 0)
|
||||
{
|
||||
// String length
|
||||
uint length = (uint)source->SourceLen;
|
||||
const char* sString = source->SourcePtr;
|
||||
|
||||
// Line count and char count
|
||||
uint line=1;
|
||||
uint charC=1;
|
||||
|
||||
// Find the line
|
||||
uint offset=0;
|
||||
while ((offset < length) && (offset < (uint)errorOff))
|
||||
{
|
||||
if (sString[offset]=='\n')
|
||||
{
|
||||
line++;
|
||||
charC=1;
|
||||
}
|
||||
else
|
||||
charC++;
|
||||
|
||||
// Next character
|
||||
offset++;
|
||||
}
|
||||
|
||||
// Show the error
|
||||
nlwarning("3D: Vertex program syntax error line %d character %d\n", line, charC);
|
||||
|
||||
// Setup not ok
|
||||
delete drvInfo;
|
||||
program->_DrvInfo = NULL;
|
||||
_GPUPrgDrvInfos.erase(it);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set parameters for assembly programs
|
||||
drvInfo->ParamIndices = source->ParamIndices;
|
||||
|
||||
// Build the feature info
|
||||
program->buildInfo(source->DisplayName.c_str(), source->Features);
|
||||
|
||||
// Setup ok
|
||||
return true;
|
||||
|
||||
#else
|
||||
|
||||
return false;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
bool CDriverGL::activeNVVertexProgram (CVertexProgram *program)
|
||||
bool CDriverGL::activeNVVertexProgram(CVertexProgram *program)
|
||||
{
|
||||
H_AUTO_OGL(CVertexProgamDrvInfosGL_activeNVVertexProgram);
|
||||
|
||||
|
@ -94,120 +207,16 @@ bool CDriverGL::activeNVVertexProgram (CVertexProgram *program)
|
|||
// Setup or unsetup ?
|
||||
if (program)
|
||||
{
|
||||
// Enable vertex program
|
||||
glEnable (GL_VERTEX_PROGRAM_NV);
|
||||
_VertexProgramEnabled= true;
|
||||
|
||||
|
||||
// Driver info
|
||||
CVertexProgamDrvInfosGL *drvInfo;
|
||||
CVertexProgamDrvInfosGL *drvInfo = safe_cast<CVertexProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->_DrvInfo);
|
||||
nlassert(drvInfo);
|
||||
|
||||
// Program setuped ?
|
||||
if (program->_DrvInfo==NULL)
|
||||
{
|
||||
// Find nelvp
|
||||
CGPUProgramSource *source = NULL;
|
||||
for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i)
|
||||
{
|
||||
if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp)
|
||||
{
|
||||
source = program->getProgramSource()->Sources[i];
|
||||
}
|
||||
}
|
||||
if (!source)
|
||||
{
|
||||
nlwarning("OpenGL driver only supports 'nelvp' profile, vertex program cannot be used");
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Check with our parser if the program will works with other implemented extensions, too. (EXT_vertex_shader ..).
|
||||
* There are some incompatibilities.
|
||||
*/
|
||||
CVPParser parser;
|
||||
CVPParser::TProgram parsedProgram;
|
||||
std::string errorOutput;
|
||||
bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput);
|
||||
if (!result)
|
||||
{
|
||||
nlwarning("Unable to parse a vertex program :");
|
||||
nlwarning(errorOutput.c_str());
|
||||
#ifdef NL_DEBUG
|
||||
nlassert(0);
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
// Insert into driver list. (so it is deleted when driver is deleted).
|
||||
ItGPUPrgDrvInfoPtrList it= _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL);
|
||||
|
||||
// Create a driver info
|
||||
*it = drvInfo = new CVertexProgamDrvInfosGL (this, it);
|
||||
|
||||
// Set the pointer
|
||||
program->_DrvInfo=drvInfo;
|
||||
|
||||
// Compile the program
|
||||
nglLoadProgramNV (GL_VERTEX_PROGRAM_NV, drvInfo->ID, (GLsizei)source->SourceLen, (const GLubyte*)source->SourcePtr);
|
||||
|
||||
// Get loading error code
|
||||
GLint errorOff;
|
||||
glGetIntegerv (GL_PROGRAM_ERROR_POSITION_NV, &errorOff);
|
||||
|
||||
// Compilation error ?
|
||||
if (errorOff>=0)
|
||||
{
|
||||
// String length
|
||||
uint length = (uint)source->SourceLen;
|
||||
const char* sString = source->SourcePtr;
|
||||
|
||||
// Line count and char count
|
||||
uint line=1;
|
||||
uint charC=1;
|
||||
|
||||
// Find the line
|
||||
uint offset=0;
|
||||
while ((offset<length)&&(offset<(uint)errorOff))
|
||||
{
|
||||
if (sString[offset]=='\n')
|
||||
{
|
||||
line++;
|
||||
charC=1;
|
||||
}
|
||||
else
|
||||
charC++;
|
||||
|
||||
// Next character
|
||||
offset++;
|
||||
}
|
||||
|
||||
// Show the error
|
||||
nlwarning("3D: Vertex program syntax error line %d character %d\n", line, charC);
|
||||
|
||||
// Disable vertex program
|
||||
glDisable (GL_VERTEX_PROGRAM_NV);
|
||||
_VertexProgramEnabled= false;
|
||||
|
||||
// Setup not ok
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set parameters for assembly programs
|
||||
drvInfo->ParamIndices = source->ParamIndices;
|
||||
|
||||
// Build the feature info
|
||||
program->buildInfo(source->DisplayName.c_str(), source->Features);
|
||||
|
||||
// Setup ok
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Cast the driver info pointer
|
||||
drvInfo=safe_cast<CVertexProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->_DrvInfo);
|
||||
}
|
||||
// Enable vertex program
|
||||
glEnable(GL_VERTEX_PROGRAM_NV);
|
||||
_VertexProgramEnabled = true;
|
||||
|
||||
// Setup this program
|
||||
nglBindProgramNV (GL_VERTEX_PROGRAM_NV, drvInfo->ID);
|
||||
nglBindProgramNV(GL_VERTEX_PROGRAM_NV, drvInfo->ID);
|
||||
_LastSetuppedVP = program;
|
||||
|
||||
// Ok
|
||||
|
@ -216,8 +225,8 @@ bool CDriverGL::activeNVVertexProgram (CVertexProgram *program)
|
|||
else // Unsetup
|
||||
{
|
||||
// Disable vertex program
|
||||
glDisable (GL_VERTEX_PROGRAM_NV);
|
||||
_VertexProgramEnabled= false;
|
||||
glDisable(GL_VERTEX_PROGRAM_NV);
|
||||
_VertexProgramEnabled = false;
|
||||
// Ok
|
||||
return true;
|
||||
}
|
||||
|
@ -1507,207 +1516,273 @@ bool CDriverGL::setupARBVertexProgram (const CVPParser::TProgram &inParsedProgra
|
|||
#endif
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
bool CDriverGL::compileARBVertexProgram(NL3D::CVertexProgram *program)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_compileARBVertexProgram);
|
||||
|
||||
#ifndef USE_OPENGLES
|
||||
|
||||
nlassert(!program->_DrvInfo);
|
||||
glDisable(GL_VERTEX_PROGRAM_ARB);
|
||||
_VertexProgramEnabled = false;
|
||||
|
||||
// Find nelvp
|
||||
CGPUProgramSource *source = NULL;
|
||||
for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i)
|
||||
{
|
||||
if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp)
|
||||
{
|
||||
source = program->getProgramSource()->Sources[i];
|
||||
}
|
||||
}
|
||||
if (!source)
|
||||
{
|
||||
nlwarning("OpenGL driver only supports 'nelvp' profile, vertex program cannot be used");
|
||||
return false;
|
||||
}
|
||||
|
||||
// try to parse the program
|
||||
CVPParser parser;
|
||||
CVPParser::TProgram parsedProgram;
|
||||
std::string errorOutput;
|
||||
bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput);
|
||||
if (!result)
|
||||
{
|
||||
nlwarning("Unable to parse a vertex program.");
|
||||
#ifdef NL_DEBUG
|
||||
nlerror(errorOutput.c_str());
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
// Insert into driver list. (so it is deleted when driver is deleted).
|
||||
ItGPUPrgDrvInfoPtrList it = _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL);
|
||||
|
||||
// Create a driver info
|
||||
CVertexProgamDrvInfosGL *drvInfo;
|
||||
*it = drvInfo = new CVertexProgamDrvInfosGL(this, it);
|
||||
// Set the pointer
|
||||
program->_DrvInfo=drvInfo;
|
||||
|
||||
if (!setupARBVertexProgram(parsedProgram, drvInfo->ID, drvInfo->SpecularWritten))
|
||||
{
|
||||
delete drvInfo;
|
||||
program->_DrvInfo = NULL;
|
||||
_GPUPrgDrvInfos.erase(it);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set parameters for assembly programs
|
||||
drvInfo->ParamIndices = source->ParamIndices;
|
||||
|
||||
// Build the feature info
|
||||
program->buildInfo(source->DisplayName.c_str(), source->Features);
|
||||
|
||||
return true;
|
||||
|
||||
#else
|
||||
|
||||
return false;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
bool CDriverGL::activeARBVertexProgram (CVertexProgram *program)
|
||||
|
||||
bool CDriverGL::activeARBVertexProgram(CVertexProgram *program)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_activeARBVertexProgram);
|
||||
|
||||
#ifndef USE_OPENGLES
|
||||
|
||||
// Setup or unsetup ?
|
||||
if (program)
|
||||
{
|
||||
// Driver info
|
||||
CVertexProgamDrvInfosGL *drvInfo;
|
||||
CVertexProgamDrvInfosGL *drvInfo = safe_cast<CVertexProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->_DrvInfo);
|
||||
nlassert(drvInfo);
|
||||
|
||||
// Program setuped ?
|
||||
if (program->_DrvInfo==NULL)
|
||||
{
|
||||
// Find nelvp
|
||||
CGPUProgramSource *source = NULL;
|
||||
for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i)
|
||||
{
|
||||
if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp)
|
||||
{
|
||||
source = program->getProgramSource()->Sources[i];
|
||||
}
|
||||
}
|
||||
if (!source)
|
||||
{
|
||||
nlwarning("OpenGL driver only supports 'nelvp' profile, vertex program cannot be used");
|
||||
return false;
|
||||
}
|
||||
|
||||
// try to parse the program
|
||||
CVPParser parser;
|
||||
CVPParser::TProgram parsedProgram;
|
||||
std::string errorOutput;
|
||||
bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput);
|
||||
if (!result)
|
||||
{
|
||||
nlwarning("Unable to parse a vertex program.");
|
||||
#ifdef NL_DEBUG
|
||||
nlerror(errorOutput.c_str());
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
// Insert into driver list. (so it is deleted when driver is deleted).
|
||||
ItGPUPrgDrvInfoPtrList it= _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL);
|
||||
|
||||
// Create a driver info
|
||||
*it = drvInfo = new CVertexProgamDrvInfosGL (this, it);
|
||||
// Set the pointer
|
||||
program->_DrvInfo=drvInfo;
|
||||
|
||||
if (!setupARBVertexProgram(parsedProgram, drvInfo->ID, drvInfo->SpecularWritten))
|
||||
{
|
||||
delete drvInfo;
|
||||
program->_DrvInfo = NULL;
|
||||
_GPUPrgDrvInfos.erase(it);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set parameters for assembly programs
|
||||
drvInfo->ParamIndices = source->ParamIndices;
|
||||
|
||||
// Build the feature info
|
||||
program->buildInfo(source->DisplayName.c_str(), source->Features);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Cast the driver info pointer
|
||||
drvInfo=safe_cast<CVertexProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->_DrvInfo);
|
||||
}
|
||||
glEnable( GL_VERTEX_PROGRAM_ARB );
|
||||
_VertexProgramEnabled = true;
|
||||
nglBindProgramARB( GL_VERTEX_PROGRAM_ARB, drvInfo->ID );
|
||||
nglBindProgramARB(GL_VERTEX_PROGRAM_ARB, drvInfo->ID);
|
||||
if (drvInfo->SpecularWritten)
|
||||
{
|
||||
glEnable( GL_COLOR_SUM_ARB );
|
||||
glEnable(GL_COLOR_SUM_ARB);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable( GL_COLOR_SUM_ARB ); // no specular written
|
||||
glDisable(GL_COLOR_SUM_ARB); // no specular written
|
||||
}
|
||||
_LastSetuppedVP = program;
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable( GL_VERTEX_PROGRAM_ARB );
|
||||
glDisable( GL_COLOR_SUM_ARB );
|
||||
glDisable(GL_VERTEX_PROGRAM_ARB);
|
||||
glDisable(GL_COLOR_SUM_ARB);
|
||||
_VertexProgramEnabled = false;
|
||||
}
|
||||
return true;
|
||||
|
||||
#else
|
||||
|
||||
return false;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
bool CDriverGL::activeEXTVertexShader (CVertexProgram *program)
|
||||
|
||||
bool CDriverGL::compileEXTVertexShader(CVertexProgram *program)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_activeEXTVertexShader);
|
||||
|
||||
#ifndef USE_OPENGLES
|
||||
// Setup or unsetup ?
|
||||
if (program)
|
||||
|
||||
nlassert(program->_DrvInfo);
|
||||
glDisable(GL_VERTEX_SHADER_EXT);
|
||||
_VertexProgramEnabled = false;
|
||||
|
||||
// Find nelvp
|
||||
CGPUProgramSource *source = NULL;
|
||||
for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i)
|
||||
{
|
||||
// Driver info
|
||||
CVertexProgamDrvInfosGL *drvInfo;
|
||||
|
||||
// Program setuped ?
|
||||
if (program->_DrvInfo==NULL)
|
||||
if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp)
|
||||
{
|
||||
// Find nelvp
|
||||
CGPUProgramSource *source = NULL;
|
||||
for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i)
|
||||
{
|
||||
if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp)
|
||||
{
|
||||
source = program->getProgramSource()->Sources[i];
|
||||
}
|
||||
}
|
||||
if (!source)
|
||||
{
|
||||
nlwarning("OpenGL driver only supports 'nelvp' profile, vertex program cannot be used");
|
||||
return false;
|
||||
}
|
||||
|
||||
// try to parse the program
|
||||
CVPParser parser;
|
||||
CVPParser::TProgram parsedProgram;
|
||||
std::string errorOutput;
|
||||
bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput);
|
||||
if (!result)
|
||||
{
|
||||
nlwarning("Unable to parse a vertex program.");
|
||||
#ifdef NL_DEBUG
|
||||
nlerror(errorOutput.c_str());
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
FILE *f = fopen(getLogDirectory() + "test.txt", "wb");
|
||||
if (f)
|
||||
{
|
||||
std::string vpText;
|
||||
CVPParser::dump(parsedProgram, vpText);
|
||||
fwrite(vpText.c_str(), vpText.size(), 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
*/
|
||||
|
||||
// Insert into driver list. (so it is deleted when driver is deleted).
|
||||
ItGPUPrgDrvInfoPtrList it= _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL);
|
||||
|
||||
// Create a driver info
|
||||
*it = drvInfo = new CVertexProgamDrvInfosGL (this, it);
|
||||
// Set the pointer
|
||||
program->_DrvInfo=drvInfo;
|
||||
|
||||
if (!setupEXTVertexShader(parsedProgram, drvInfo->ID, drvInfo->Variants, drvInfo->UsedVertexComponents))
|
||||
{
|
||||
delete drvInfo;
|
||||
program->_DrvInfo = NULL;
|
||||
_GPUPrgDrvInfos.erase(it);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set parameters for assembly programs
|
||||
drvInfo->ParamIndices = source->ParamIndices;
|
||||
|
||||
// Build the feature info
|
||||
program->buildInfo(source->DisplayName.c_str(), source->Features);
|
||||
source = program->getProgramSource()->Sources[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Cast the driver info pointer
|
||||
drvInfo=safe_cast<CVertexProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->_DrvInfo);
|
||||
}
|
||||
|
||||
glEnable( GL_VERTEX_SHADER_EXT);
|
||||
_VertexProgramEnabled = true;
|
||||
nglBindVertexShaderEXT( drvInfo->ID );
|
||||
_LastSetuppedVP = program;
|
||||
}
|
||||
else
|
||||
if (!source)
|
||||
{
|
||||
glDisable( GL_VERTEX_SHADER_EXT );
|
||||
_VertexProgramEnabled = false;
|
||||
nlwarning("OpenGL driver only supports 'nelvp' profile, vertex program cannot be used");
|
||||
return false;
|
||||
}
|
||||
|
||||
// try to parse the program
|
||||
CVPParser parser;
|
||||
CVPParser::TProgram parsedProgram;
|
||||
std::string errorOutput;
|
||||
bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput);
|
||||
if (!result)
|
||||
{
|
||||
nlwarning("Unable to parse a vertex program.");
|
||||
#ifdef NL_DEBUG
|
||||
nlerror(errorOutput.c_str());
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
FILE *f = fopen(getLogDirectory() + "test.txt", "wb");
|
||||
if (f)
|
||||
{
|
||||
std::string vpText;
|
||||
CVPParser::dump(parsedProgram, vpText);
|
||||
fwrite(vpText.c_str(), vpText.size(), 1, f);
|
||||
fclose(f);
|
||||
}
|
||||
*/
|
||||
|
||||
// Insert into driver list. (so it is deleted when driver is deleted).
|
||||
ItGPUPrgDrvInfoPtrList it= _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL);
|
||||
|
||||
// Create a driver info
|
||||
CVertexProgamDrvInfosGL *drvInfo;
|
||||
*it = drvInfo = new CVertexProgamDrvInfosGL (this, it);
|
||||
// Set the pointer
|
||||
program->_DrvInfo=drvInfo;
|
||||
|
||||
if (!setupEXTVertexShader(parsedProgram, drvInfo->ID, drvInfo->Variants, drvInfo->UsedVertexComponents))
|
||||
{
|
||||
delete drvInfo;
|
||||
program->_DrvInfo = NULL;
|
||||
_GPUPrgDrvInfos.erase(it);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set parameters for assembly programs
|
||||
drvInfo->ParamIndices = source->ParamIndices;
|
||||
|
||||
// Build the feature info
|
||||
program->buildInfo(source->DisplayName.c_str(), source->Features);
|
||||
|
||||
return true;
|
||||
|
||||
#else
|
||||
|
||||
return false;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
bool CDriverGL::activeVertexProgram (CVertexProgram *program)
|
||||
|
||||
bool CDriverGL::activeEXTVertexShader(CVertexProgram *program)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_activeEXTVertexShader);
|
||||
|
||||
#ifndef USE_OPENGLES
|
||||
|
||||
// Setup or unsetup ?
|
||||
if (program)
|
||||
{
|
||||
// Driver info
|
||||
CVertexProgamDrvInfosGL *drvInfo = safe_cast<CVertexProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->_DrvInfo);
|
||||
nlassert(drvInfo);
|
||||
|
||||
glEnable(GL_VERTEX_SHADER_EXT);
|
||||
_VertexProgramEnabled = true;
|
||||
nglBindVertexShaderEXT(drvInfo->ID);
|
||||
_LastSetuppedVP = program;
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_VERTEX_SHADER_EXT);
|
||||
_VertexProgramEnabled = false;
|
||||
}
|
||||
return true;
|
||||
|
||||
#else
|
||||
|
||||
return false;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
bool CDriverGL::compileVertexProgram(NL3D::CVertexProgram *program)
|
||||
{
|
||||
if (program->_DrvInfo == NULL)
|
||||
{
|
||||
// Extension
|
||||
if (_Extensions.NVVertexProgram)
|
||||
{
|
||||
return compileNVVertexProgram(program);
|
||||
}
|
||||
else if (_Extensions.ARBVertexProgram)
|
||||
{
|
||||
return compileARBVertexProgram(program);
|
||||
}
|
||||
else if (_Extensions.EXTVertexShader)
|
||||
{
|
||||
return compileEXTVertexShader(program);
|
||||
}
|
||||
|
||||
// Can't do anything
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
bool CDriverGL::activeVertexProgram(CVertexProgram *program)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_activeVertexProgram)
|
||||
// Extension here ?
|
||||
|
||||
// Compile if necessary
|
||||
if (program && !CDriverGL::compileVertexProgram(program)) return false;
|
||||
|
||||
// Extension
|
||||
if (_Extensions.NVVertexProgram)
|
||||
{
|
||||
return activeNVVertexProgram(program);
|
||||
|
@ -1725,287 +1800,6 @@ bool CDriverGL::activeVertexProgram (CVertexProgram *program)
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
void CDriverGL::setConstant (uint index, float f0, float f1, float f2, float f3)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setConstant);
|
||||
|
||||
#ifndef USE_OPENGLES
|
||||
// Vertex program exist ?
|
||||
if (_Extensions.NVVertexProgram)
|
||||
{
|
||||
// Setup constant
|
||||
nglProgramParameter4fNV (GL_VERTEX_PROGRAM_NV, index, f0, f1, f2, f3);
|
||||
}
|
||||
else if (_Extensions.ARBVertexProgram)
|
||||
{
|
||||
nglProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, index, f0, f1, f2, f3);
|
||||
}
|
||||
else if (_Extensions.EXTVertexShader)
|
||||
{
|
||||
float datas[] = { f0, f1, f2, f3 };
|
||||
nglSetInvariantEXT(_EVSConstantHandle + index, GL_FLOAT, datas);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
void CDriverGL::setConstant (uint index, double d0, double d1, double d2, double d3)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setConstant);
|
||||
|
||||
#ifndef USE_OPENGLES
|
||||
// Vertex program exist ?
|
||||
if (_Extensions.NVVertexProgram)
|
||||
{
|
||||
// Setup constant
|
||||
nglProgramParameter4dNV (GL_VERTEX_PROGRAM_NV, index, d0, d1, d2, d3);
|
||||
}
|
||||
else if (_Extensions.ARBVertexProgram)
|
||||
{
|
||||
nglProgramEnvParameter4dARB(GL_VERTEX_PROGRAM_ARB, index, d0, d1, d2, d3);
|
||||
}
|
||||
else if (_Extensions.EXTVertexShader)
|
||||
{
|
||||
double datas[] = { d0, d1, d2, d3 };
|
||||
nglSetInvariantEXT(_EVSConstantHandle + index, GL_DOUBLE, datas);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
void CDriverGL::setConstant (uint index, const NLMISC::CVector& value)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setConstant);
|
||||
|
||||
#ifndef USE_OPENGLES
|
||||
// Vertex program exist ?
|
||||
if (_Extensions.NVVertexProgram)
|
||||
{
|
||||
// Setup constant
|
||||
nglProgramParameter4fNV (GL_VERTEX_PROGRAM_NV, index, value.x, value.y, value.z, 0);
|
||||
}
|
||||
else if (_Extensions.ARBVertexProgram)
|
||||
{
|
||||
nglProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, index, value.x, value.y, value.z, 0);
|
||||
}
|
||||
else if (_Extensions.EXTVertexShader)
|
||||
{
|
||||
float datas[] = { value.x, value.y, value.z, 0 };
|
||||
nglSetInvariantEXT(_EVSConstantHandle + index, GL_FLOAT, datas);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
void CDriverGL::setConstant (uint index, const NLMISC::CVectorD& value)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setConstant);
|
||||
|
||||
#ifndef USE_OPENGLES
|
||||
// Vertex program exist ?
|
||||
if (_Extensions.NVVertexProgram)
|
||||
{
|
||||
// Setup constant
|
||||
nglProgramParameter4dNV (GL_VERTEX_PROGRAM_NV, index, value.x, value.y, value.z, 0);
|
||||
}
|
||||
else if (_Extensions.ARBVertexProgram)
|
||||
{
|
||||
nglProgramEnvParameter4dARB(GL_VERTEX_PROGRAM_ARB, index, value.x, value.y, value.z, 0);
|
||||
}
|
||||
else if (_Extensions.EXTVertexShader)
|
||||
{
|
||||
double datas[] = { value.x, value.y, value.z, 0 };
|
||||
nglSetInvariantEXT(_EVSConstantHandle + index, GL_DOUBLE, datas);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
void CDriverGL::setConstant (uint index, uint num, const float *src)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setConstant);
|
||||
|
||||
#ifndef USE_OPENGLES
|
||||
// Vertex program exist ?
|
||||
if (_Extensions.NVVertexProgram)
|
||||
{
|
||||
nglProgramParameters4fvNV(GL_VERTEX_PROGRAM_NV, index, num, src);
|
||||
}
|
||||
else if (_Extensions.ARBVertexProgram)
|
||||
{
|
||||
for(uint k = 0; k < num; ++k)
|
||||
{
|
||||
nglProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, index + k, src + 4 * k);
|
||||
}
|
||||
}
|
||||
else if (_Extensions.EXTVertexShader)
|
||||
{
|
||||
for(uint k = 0; k < num; ++k)
|
||||
{
|
||||
nglSetInvariantEXT(_EVSConstantHandle + index + k, GL_FLOAT, (void *) (src + 4 * k));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
void CDriverGL::setConstant (uint index, uint num, const double *src)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setConstant);
|
||||
|
||||
#ifndef USE_OPENGLES
|
||||
// Vertex program exist ?
|
||||
if (_Extensions.NVVertexProgram)
|
||||
{
|
||||
nglProgramParameters4dvNV(GL_VERTEX_PROGRAM_NV, index, num, src);
|
||||
}
|
||||
else if (_Extensions.ARBVertexProgram)
|
||||
{
|
||||
for(uint k = 0; k < num; ++k)
|
||||
{
|
||||
nglProgramEnvParameter4dvARB(GL_VERTEX_PROGRAM_ARB, index + k, src + 4 * k);
|
||||
}
|
||||
}
|
||||
else if (_Extensions.EXTVertexShader)
|
||||
{
|
||||
for(uint k = 0; k < num; ++k)
|
||||
{
|
||||
nglSetInvariantEXT(_EVSConstantHandle + index + k, GL_DOUBLE, (void *) (src + 4 * k));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
const uint CDriverGL::GLMatrix[IDriver::NumMatrix]=
|
||||
{
|
||||
GL_MODELVIEW,
|
||||
GL_PROJECTION,
|
||||
#ifdef USE_OPENGLES
|
||||
GL_MODELVIEW
|
||||
#else
|
||||
GL_MODELVIEW_PROJECTION_NV
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
const uint CDriverGL::GLTransform[IDriver::NumTransform]=
|
||||
{
|
||||
#ifdef USE_OPENGLES
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
#else
|
||||
GL_IDENTITY_NV,
|
||||
GL_INVERSE_NV,
|
||||
GL_TRANSPOSE_NV,
|
||||
GL_INVERSE_TRANSPOSE_NV
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
void CDriverGL::setConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setConstantMatrix);
|
||||
|
||||
#ifndef USE_OPENGLES
|
||||
// Vertex program exist ?
|
||||
if (_Extensions.NVVertexProgram)
|
||||
{
|
||||
// First, ensure that the render setup is correclty setuped.
|
||||
refreshRenderSetup();
|
||||
|
||||
// Track the matrix
|
||||
nglTrackMatrixNV (GL_VERTEX_PROGRAM_NV, index, GLMatrix[matrix], GLTransform[transform]);
|
||||
// Release Track => matrix data is copied.
|
||||
nglTrackMatrixNV (GL_VERTEX_PROGRAM_NV, index, GL_NONE, GL_IDENTITY_NV);
|
||||
}
|
||||
else
|
||||
{
|
||||
// First, ensure that the render setup is correctly setuped.
|
||||
refreshRenderSetup();
|
||||
CMatrix mat;
|
||||
switch (matrix)
|
||||
{
|
||||
case IDriver::ModelView:
|
||||
mat = _ModelViewMatrix;
|
||||
break;
|
||||
case IDriver::Projection:
|
||||
{
|
||||
refreshProjMatrixFromGL();
|
||||
mat = _GLProjMat;
|
||||
}
|
||||
break;
|
||||
case IDriver::ModelViewProjection:
|
||||
refreshProjMatrixFromGL();
|
||||
mat = _GLProjMat * _ModelViewMatrix;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch(transform)
|
||||
{
|
||||
case IDriver::Identity: break;
|
||||
case IDriver::Inverse:
|
||||
mat.invert();
|
||||
break;
|
||||
case IDriver::Transpose:
|
||||
mat.transpose();
|
||||
break;
|
||||
case IDriver::InverseTranspose:
|
||||
mat.invert();
|
||||
mat.transpose();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
mat.transpose();
|
||||
float matDatas[16];
|
||||
mat.get(matDatas);
|
||||
if (_Extensions.ARBVertexProgram)
|
||||
{
|
||||
nglProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, index, matDatas);
|
||||
nglProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, index + 1, matDatas + 4);
|
||||
nglProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, index + 2, matDatas + 8);
|
||||
nglProgramEnvParameter4fvARB(GL_VERTEX_PROGRAM_ARB, index + 3, matDatas + 12);
|
||||
}
|
||||
else
|
||||
{
|
||||
nglSetInvariantEXT(_EVSConstantHandle + index, GL_FLOAT, matDatas);
|
||||
nglSetInvariantEXT(_EVSConstantHandle + index + 1, GL_FLOAT, matDatas + 4);
|
||||
nglSetInvariantEXT(_EVSConstantHandle + index + 2, GL_FLOAT, matDatas + 8);
|
||||
nglSetInvariantEXT(_EVSConstantHandle + index + 3, GL_FLOAT, matDatas + 12);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
void CDriverGL::setConstantFog (uint index)
|
||||
{
|
||||
H_AUTO_OGL(CDriverGL_setConstantFog)
|
||||
const float *values = _ModelViewMatrix.get();
|
||||
setConstant (index, -values[2], -values[6], -values[10], -values[14]);
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
|
||||
void CDriverGL::enableVertexProgramDoubleSidedColor(bool doubleSided)
|
||||
|
|
Loading…
Reference in a new issue