diff --git a/code/nel/include/nel/3d/gpu_program.h b/code/nel/include/nel/3d/gpu_program.h index 3df13ac3d..ba0afb9e4 100644 --- a/code/nel/include/nel/3d/gpu_program.h +++ b/code/nel/include/nel/3d/gpu_program.h @@ -57,7 +57,7 @@ public: // The virtual dtor is important. virtual ~IGPUProgramDrvInfos(void); - virtual uint getParamIdx(char *name) const { return ~0; }; // STEREO_TODO + virtual uint getParamIdx(char *name) const = 0; }; class CGPUProgramSource; diff --git a/code/nel/include/nel/3d/gpu_program_source.h b/code/nel/include/nel/3d/gpu_program_source.h index 0484b28d2..c51ac67ce 100644 --- a/code/nel/include/nel/3d/gpu_program_source.h +++ b/code/nel/include/nel/3d/gpu_program_source.h @@ -53,11 +53,13 @@ public: /// Minimal required profile for this GPU program IGPUProgram::TProfile Profile; - const char *CodePtr; + const char *SourcePtr; + size_t SourceLen; /// Copy the source code string - inline void setCode(const char *source) { CodeCopy = source; CodePtr = &source[0]; } + inline void setSource(const char *source) { SourceCopy = source; SourcePtr = &SourceCopy[0]; SourceLen = SourceCopy.size(); } /// Set pointer to source code string without copying the string - inline void setCodePtr(const char *sourcePtr) { CodeCopy.clear(); CodePtr = sourcePtr; } + inline void setSourcePtr(const char *sourcePtr, size_t sourceLen) { SourceCopy.clear(); SourcePtr = sourcePtr; SourceLen = sourceLen; } + inline void setSourcePtr(const char *sourcePtr) { SourceCopy.clear(); SourcePtr = sourcePtr; SourceLen = strlen(sourcePtr); } /// CVertexProgramInfo/CPixelProgramInfo/... NeL features uint Features; @@ -66,7 +68,7 @@ public: std::map ParamIndices; private: - std::string CodeCopy; + std::string SourceCopy; }; /* class CGPUProgramSource */ diff --git a/code/nel/src/3d/driver.cpp b/code/nel/src/3d/driver.cpp index 25c9afb63..3bd354a62 100644 --- a/code/nel/src/3d/driver.cpp +++ b/code/nel/src/3d/driver.cpp @@ -33,7 +33,7 @@ namespace NL3D { // *************************************************************************** -const uint32 IDriver::InterfaceVersion = 0x6c; // pixel program interface +const uint32 IDriver::InterfaceVersion = 0x6d; // gpu program interface // *************************************************************************** IDriver::IDriver() : _SyncTexDrvInfos( "IDriver::_SyncTexDrvInfos" ) diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.cpp b/code/nel/src/3d/driver/opengl/driver_opengl.cpp index 92021c65b..a93c05338 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl.cpp @@ -2573,14 +2573,6 @@ CVertexBuffer::TVertexColorType CDriverGL::getVertexColorFormat() const return CVertexBuffer::TRGBA; } -// *************************************************************************** -bool CDriverGL::activeShader(CShader * /* shd */) -{ - H_AUTO_OGL(CDriverGL_activeShader) - - return false; -} - // *************************************************************************** void CDriverGL::startBench (bool wantStandardDeviation, bool quick, bool reset) { diff --git a/code/nel/src/3d/driver/opengl/driver_opengl.h b/code/nel/src/3d/driver/opengl/driver_opengl.h index 08e950b70..5289f2a26 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl.h +++ b/code/nel/src/3d/driver/opengl/driver_opengl.h @@ -406,8 +406,6 @@ public: virtual CMatrix getViewMatrix() const; - virtual bool activeShader(CShader *shd); - virtual void forceNormalize(bool normalize) { _ForceNormalize= normalize; @@ -1349,7 +1347,7 @@ private: /// \name Pixel program implementation // @{ bool activeARBPixelProgram (CPixelProgram *program); - bool setupARBPixelProgram (const CPixelProgram *program, GLuint id/*, bool &specularWritten*/); + bool setupPixelProgram (CPixelProgram *program, GLuint id/*, bool &specularWritten*/); //@} @@ -1530,7 +1528,7 @@ private: }; // *************************************************************************** -class CVertexProgamDrvInfosGL : public IVertexProgramDrvInfos +class CVertexProgamDrvInfosGL : public IGPUProgramDrvInfos { public: // The GL Id. @@ -1551,18 +1549,36 @@ public: // The gl id is auto created here. - CVertexProgamDrvInfosGL (CDriverGL *drv, ItVtxPrgDrvInfoPtrList it); + CVertexProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it); + + virtual uint getParamIdx(char *name) const + { + std::map::const_iterator it = ParamIndices.find(name); + if (it != ParamIndices.end()) return it->second; + return ~0; + }; + + std::map ParamIndices; }; // *************************************************************************** -class CPixelProgamDrvInfosGL : public IPixelProgramDrvInfos +class CPixelProgamDrvInfosGL : public IGPUProgramDrvInfos { public: // The GL Id. GLuint ID; // The gl id is auto created here. - CPixelProgamDrvInfosGL (CDriverGL *drv, ItPixelPrgDrvInfoPtrList it); + CPixelProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it); + + virtual uint getParamIdx(char *name) const + { + std::map::const_iterator it = ParamIndices.find(name); + if (it != ParamIndices.end()) return it->second; + return ~0; + }; + + std::map ParamIndices; }; #ifdef NL_STATIC 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 2bcfc185d..b2867a95a 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,7 +50,7 @@ namespace NLDRIVERGL { #endif // *************************************************************************** -CPixelProgamDrvInfosGL::CPixelProgamDrvInfosGL (CDriverGL *drv, ItPixelPrgDrvInfoPtrList it) : IPixelProgramDrvInfos (drv, it) +CPixelProgamDrvInfosGL::CPixelProgamDrvInfosGL (CDriverGL *drv, ItGPUPrgDrvInfoPtrList it) : IGPUProgramDrvInfos (drv, it) { H_AUTO_OGL(CPixelProgamDrvInfosGL_CPixelProgamDrvInfosGL) // Extension must exist @@ -109,25 +109,25 @@ bool CDriverGL::activeARBPixelProgram(CPixelProgram *program) if (program->_DrvInfo==NULL) { // Insert into driver list. (so it is deleted when driver is deleted). - ItPixelPrgDrvInfoPtrList it= _PixelPrgDrvInfos.insert(_PixelPrgDrvInfos.end(), (NL3D::IPixelProgramDrvInfos*)NULL); + ItGPUPrgDrvInfoPtrList it = _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL); // Create a driver info - *it = drvInfo = new CPixelProgamDrvInfosGL (this, it); + *it = drvInfo = new CPixelProgamDrvInfosGL(this, it); // Set the pointer - program->_DrvInfo=drvInfo; + program->_DrvInfo = drvInfo; - if(!setupARBPixelProgram(program, drvInfo->ID)) + if (!setupPixelProgram(program, drvInfo->ID)) { delete drvInfo; program->_DrvInfo = NULL; - _PixelPrgDrvInfos.erase(it); + _GPUPrgDrvInfos.erase(it); return false; } } else { // Cast the driver info pointer - drvInfo=safe_cast((IPixelProgramDrvInfos*)program->_DrvInfo); + drvInfo=safe_cast((IGPUProgramDrvInfos*)program->_DrvInfo); } glEnable( GL_FRAGMENT_PROGRAM_ARB ); _PixelProgramEnabled = true; @@ -148,15 +148,31 @@ bool CDriverGL::activeARBPixelProgram(CPixelProgram *program) } // *************************************************************************** -bool CDriverGL::setupARBPixelProgram (const CPixelProgram *program, GLuint id/*, bool &specularWritten*/) +bool CDriverGL::setupPixelProgram(CPixelProgram *program, GLuint id/*, bool &specularWritten*/) { H_AUTO_OGL(CDriverGL_setupARBPixelProgram) + + CPixelProgamDrvInfosGL *drvInfo = static_cast((IGPUProgramDrvInfos *)program->_DrvInfo); - const std::string &code = program->getProgram(); + // Find a supported pixel program profile + CGPUProgramSource *source = NULL; + for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i) + { + if (supportPixelProgram(program->getProgramSource()->Sources[i]->Profile)) + { + source = program->getProgramSource()->Sources[i]; + } + } + if (!source) + { + nlwarning("No supported source profile for pixel program"); + return false; + } + // Compile the program nglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, id); glGetError(); - nglProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, code.size(), code.c_str() ); + nglProgramStringARB( GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, source->SourceLen, source->SourcePtr); GLenum err = glGetError(); if (err != GL_NO_ERROR) { @@ -165,25 +181,25 @@ bool CDriverGL::setupARBPixelProgram (const CPixelProgram *program, GLuint id/*, GLint position; glGetIntegerv(GL_PROGRAM_ERROR_POSITION_ARB, &position); nlassert(position != -1); // there was an error.. - nlassert(position < (GLint) code.size()); + nlassert(position < (GLint) source->SourceLen); uint line = 0; - const char *lineStart = program->getProgram().c_str(); + const char *lineStart = source->SourcePtr; for(uint k = 0; k < (uint) position; ++k) { - if (code[k] == '\n') + if (source->SourcePtr[k] == '\n') { - lineStart = code.c_str() + k; + lineStart = source->SourcePtr + k; ++line; } } nlwarning("ARB fragment program parse error at line %d.", (int) line); // search end of line - const char *lineEnd = code.c_str() + code.size(); - for(uint k = position; k < code.size(); ++k) + const char *lineEnd = source->SourcePtr + source->SourceLen; + for(uint k = position; k < source->SourceLen; ++k) { - if (code[k] == '\n') + if (source->SourcePtr[k] == '\n') { - lineEnd = code.c_str() + k; + lineEnd = source->SourcePtr + k; break; } } @@ -196,6 +212,13 @@ bool CDriverGL::setupARBPixelProgram (const CPixelProgram *program, GLuint id/*, nlassert(0); 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; } diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp index 14ed83adb..521a13baf 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp @@ -1151,7 +1151,7 @@ void CDriverGL::toggleGlArraysForEXTVertexShader() CVertexProgram *vp = _LastSetuppedVP; if (vp) { - CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast((IVertexProgramDrvInfos *) vp->_DrvInfo); + CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast((IGPUProgramDrvInfos *) vp->_DrvInfo); if (drvInfo) { // Disable all VertexAttribs. @@ -1396,7 +1396,7 @@ void CDriverGL::setupGlArraysForEXTVertexShader(CVertexBufferInfo &vb) CVertexProgram *vp = _LastSetuppedVP; if (!vp) return; - CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast((IVertexProgramDrvInfos *) vp->_DrvInfo); + CVertexProgamDrvInfosGL *drvInfo = NLMISC::safe_cast((IGPUProgramDrvInfos *) vp->_DrvInfo); if (!drvInfo) return; uint32 flags= vb.VertexFormat; 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 1ddb42a7d..34ae2365a 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 @@ -41,7 +41,7 @@ namespace NLDRIVERGL { #endif // *************************************************************************** -CVertexProgamDrvInfosGL::CVertexProgamDrvInfosGL (CDriverGL *drv, ItVtxPrgDrvInfoPtrList it) : IVertexProgramDrvInfos (drv, it) +CVertexProgamDrvInfosGL::CVertexProgamDrvInfosGL(CDriverGL *drv, ItGPUPrgDrvInfoPtrList it) : IGPUProgramDrvInfos (drv, it) { H_AUTO_OGL(CVertexProgamDrvInfosGL_CVertexProgamDrvInfosGL); @@ -105,13 +105,28 @@ bool CDriverGL::activeNVVertexProgram (CVertexProgram *program) // 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(program->getProgram().c_str(), parsedProgram, errorOutput); + bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput); if (!result) { nlwarning("Unable to parse a vertex program :"); @@ -123,7 +138,7 @@ bool CDriverGL::activeNVVertexProgram (CVertexProgram *program) } // Insert into driver list. (so it is deleted when driver is deleted). - ItVtxPrgDrvInfoPtrList it= _VtxPrgDrvInfos.insert(_VtxPrgDrvInfos.end(), (NL3D::IVertexProgramDrvInfos*)NULL); + ItGPUPrgDrvInfoPtrList it= _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL); // Create a driver info *it = drvInfo = new CVertexProgamDrvInfosGL (this, it); @@ -132,7 +147,7 @@ bool CDriverGL::activeNVVertexProgram (CVertexProgram *program) program->_DrvInfo=drvInfo; // Compile the program - nglLoadProgramNV (GL_VERTEX_PROGRAM_NV, drvInfo->ID, (GLsizei)program->getProgram().length(), (const GLubyte*)program->getProgram().c_str()); + nglLoadProgramNV (GL_VERTEX_PROGRAM_NV, drvInfo->ID, (GLsizei)source->SourceLen, (const GLubyte*)source->SourcePtr); // Get loading error code GLint errorOff; @@ -142,8 +157,8 @@ bool CDriverGL::activeNVVertexProgram (CVertexProgram *program) if (errorOff>=0) { // String length - uint length = (uint)program->getProgram ().length(); - const char* sString= program->getProgram ().c_str(); + uint length = (uint)source->SourceLen; + const char* sString = source->SourcePtr; // Line count and char count uint line=1; @@ -176,13 +191,19 @@ bool CDriverGL::activeNVVertexProgram (CVertexProgram *program) 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((IVertexProgramDrvInfos*)program->_DrvInfo); + drvInfo=safe_cast((IGPUProgramDrvInfos*)program->_DrvInfo); } // Setup this program @@ -1503,11 +1524,26 @@ bool CDriverGL::activeARBVertexProgram (CVertexProgram *program) // 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(program->getProgram().c_str(), parsedProgram, errorOutput); + bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput); if (!result) { nlwarning("Unable to parse a vertex program."); @@ -1517,7 +1553,7 @@ bool CDriverGL::activeARBVertexProgram (CVertexProgram *program) return false; } // Insert into driver list. (so it is deleted when driver is deleted). - ItVtxPrgDrvInfoPtrList it= _VtxPrgDrvInfos.insert(_VtxPrgDrvInfos.end(), (NL3D::IVertexProgramDrvInfos*)NULL); + ItGPUPrgDrvInfoPtrList it= _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL); // Create a driver info *it = drvInfo = new CVertexProgamDrvInfosGL (this, it); @@ -1528,14 +1564,20 @@ bool CDriverGL::activeARBVertexProgram (CVertexProgram *program) { delete drvInfo; program->_DrvInfo = NULL; - _VtxPrgDrvInfos.erase(it); + _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((IVertexProgramDrvInfos*)program->_DrvInfo); + drvInfo=safe_cast((IGPUProgramDrvInfos*)program->_DrvInfo); } glEnable( GL_VERTEX_PROGRAM_ARB ); _VertexProgramEnabled = true; @@ -1577,11 +1619,26 @@ bool CDriverGL::activeEXTVertexShader (CVertexProgram *program) // 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(program->getProgram().c_str(), parsedProgram, errorOutput); + bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput); if (!result) { nlwarning("Unable to parse a vertex program."); @@ -1603,7 +1660,7 @@ bool CDriverGL::activeEXTVertexShader (CVertexProgram *program) */ // Insert into driver list. (so it is deleted when driver is deleted). - ItVtxPrgDrvInfoPtrList it= _VtxPrgDrvInfos.insert(_VtxPrgDrvInfos.end(), (NL3D::IVertexProgramDrvInfos*)NULL); + ItGPUPrgDrvInfoPtrList it= _GPUPrgDrvInfos.insert(_GPUPrgDrvInfos.end(), (NL3D::IGPUProgramDrvInfos*)NULL); // Create a driver info *it = drvInfo = new CVertexProgamDrvInfosGL (this, it); @@ -1614,14 +1671,20 @@ bool CDriverGL::activeEXTVertexShader (CVertexProgram *program) { delete drvInfo; program->_DrvInfo = NULL; - _VtxPrgDrvInfos.erase(it); + _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((IVertexProgramDrvInfos*)program->_DrvInfo); + drvInfo=safe_cast((IGPUProgramDrvInfos*)program->_DrvInfo); } glEnable( GL_VERTEX_SHADER_EXT); diff --git a/code/nel/src/3d/stereo_debugger.cpp b/code/nel/src/3d/stereo_debugger.cpp index 17c5c8c98..509ba4769 100644 --- a/code/nel/src/3d/stereo_debugger.cpp +++ b/code/nel/src/3d/stereo_debugger.cpp @@ -130,7 +130,7 @@ void CStereoDebugger::setDriver(NL3D::UDriver *driver) { nldebug("VR: arbfp1"); source->Profile = IGPUProgram::arbfp1; - source->setCodePtr(a_arbfp1); + source->setSourcePtr(a_arbfp1); m_PixelProgram = new CPixelProgram(sourceCont); } /*else if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0)) diff --git a/code/nel/src/3d/stereo_ovr.cpp b/code/nel/src/3d/stereo_ovr.cpp index 00db2020e..8c8c6ff63 100644 --- a/code/nel/src/3d/stereo_ovr.cpp +++ b/code/nel/src/3d/stereo_ovr.cpp @@ -248,21 +248,21 @@ void CStereoOVR::setDriver(NL3D::UDriver *driver) { nldebug("VR: fp40"); source->Profile = IGPUProgram::fp40; - source->setCodePtr(g_StereoOVR_fp40); + source->setSourcePtr(g_StereoOVR_fp40); m_PixelProgram = new CPixelProgram(sourceCont); } else if (drvInternal->supportPixelProgram(CPixelProgram::arbfp1) && drvInternal->supportBloomEffect() && drvInternal->supportNonPowerOfTwoTextures()) { nldebug("VR: arbfp1"); source->Profile = IGPUProgram::arbfp1; - source->setCodePtr(g_StereoOVR_arbfp1); + source->setSourcePtr(g_StereoOVR_arbfp1); m_PixelProgram = new CPixelProgram(sourceCont); } else if (drvInternal->supportPixelProgram(CPixelProgram::ps_2_0)) { nldebug("VR: ps_2_0"); source->Profile = IGPUProgram::ps_2_0; - source->setCodePtr(g_StereoOVR_ps_2_0); + source->setSourcePtr(g_StereoOVR_ps_2_0); m_PixelProgram = new CPixelProgram(sourceCont); } diff --git a/code/nel/src/3d/vertex_program.cpp b/code/nel/src/3d/vertex_program.cpp index 2f70d51af..d0acbe775 100644 --- a/code/nel/src/3d/vertex_program.cpp +++ b/code/nel/src/3d/vertex_program.cpp @@ -39,7 +39,7 @@ CVertexProgram::CVertexProgram(const char *nelvp) : _Info(NULL) _ProgramSource = new CGPUProgramSourceCont(); _ProgramSource->Sources.push_back(source); source->Profile = IGPUProgram::nelvp; - source->setCode(nelvp); + source->setSource(nelvp); source->Features = 0; }