From 99a48d5511bd7e2936da6159b199c5387ca2b06b Mon Sep 17 00:00:00 2001 From: kaetemi Date: Mon, 9 Sep 2013 14:43:10 +0200 Subject: [PATCH] Implement new driver interface in OpenGL driver --- code/nel/include/nel/3d/driver.h | 26 +- code/nel/src/3d/driver/opengl/driver_opengl.h | 124 ++- .../opengl/driver_opengl_pixel_program.cpp | 217 +---- .../driver/opengl/driver_opengl_uniform.cpp | 298 ++++++ .../opengl/driver_opengl_vertex_program.cpp | 886 +++++++----------- 5 files changed, 793 insertions(+), 758 deletions(-) create mode 100644 code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp diff --git a/code/nel/include/nel/3d/driver.h b/code/nel/include/nel/3d/driver.h index ca6bc0601..8890a9cc7 100644 --- a/code/nel/include/nel/3d/driver.h +++ b/code/nel/include/nel/3d/driver.h @@ -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; // @} diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index 89b71c931..f70a0627f 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -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); //@} diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp index b2867a95a..31e6ed482 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_pixel_program.cpp @@ -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((IGPUProgramDrvInfos*)program->_DrvInfo); - } - glEnable( GL_FRAGMENT_PROGRAM_ARB ); + // Cast the driver info pointer + CPixelProgamDrvInfosGL *drvInfo = safe_cast((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 diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp new file mode 100644 index 000000000..6b429e706 --- /dev/null +++ b/code/nel/src/3d/driver/opengl/driver_opengl_uniform.cpp @@ -0,0 +1,298 @@ +// NeL - MMORPG Framework +// 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 . + +#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 diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp index 34ae2365a..e0b07af2a 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_vertex_program.cpp @@ -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((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 ((offsetParamIndices = 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((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((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((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((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((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)