|
|
|
@ -70,144 +70,153 @@ 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::activeNVVertexProgram (CVertexProgram *program)
|
|
|
|
|
bool CDriverGL::compileNVVertexProgram(CVertexProgram *program)
|
|
|
|
|
{
|
|
|
|
|
H_AUTO_OGL(CVertexProgamDrvInfosGL_activeNVVertexProgram);
|
|
|
|
|
H_AUTO_OGL(CDriverGL_compileNVVertexProgram);
|
|
|
|
|
|
|
|
|
|
#ifndef USE_OPENGLES
|
|
|
|
|
// Setup or unsetup ?
|
|
|
|
|
if (program)
|
|
|
|
|
{
|
|
|
|
|
// Enable vertex program
|
|
|
|
|
glEnable (GL_VERTEX_PROGRAM_NV);
|
|
|
|
|
_VertexProgramEnabled= true;
|
|
|
|
|
|
|
|
|
|
// Driver info
|
|
|
|
|
CVertexProgamDrvInfosGL *drvInfo;
|
|
|
|
|
|
|
|
|
|
// Driver info
|
|
|
|
|
CVertexProgamDrvInfosGL *drvInfo;
|
|
|
|
|
|
|
|
|
|
// Program setuped ?
|
|
|
|
|
if (program->_DrvInfo==NULL)
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
// 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;
|
|
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
/** 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);
|
|
|
|
|
// 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);
|
|
|
|
|
// Create a driver info
|
|
|
|
|
*it = drvInfo = new CVertexProgamDrvInfosGL(this, it);
|
|
|
|
|
|
|
|
|
|
// Set the pointer
|
|
|
|
|
program->_DrvInfo=drvInfo;
|
|
|
|
|
// Set the pointer
|
|
|
|
|
program->_DrvInfo = drvInfo;
|
|
|
|
|
|
|
|
|
|
// Compile the program
|
|
|
|
|
nglLoadProgramNV (GL_VERTEX_PROGRAM_NV, drvInfo->ID, (GLsizei)source->SourceLen, (const GLubyte*)source->SourcePtr);
|
|
|
|
|
// 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);
|
|
|
|
|
// 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;
|
|
|
|
|
|
|
|
|
|
// Compilation error ?
|
|
|
|
|
if (errorOff>=0)
|
|
|
|
|
// 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')
|
|
|
|
|
{
|
|
|
|
|
// String length
|
|
|
|
|
uint length = (uint)source->SourceLen;
|
|
|
|
|
const char* sString = source->SourcePtr;
|
|
|
|
|
line++;
|
|
|
|
|
charC=1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
charC++;
|
|
|
|
|
|
|
|
|
|
// Line count and char count
|
|
|
|
|
uint line=1;
|
|
|
|
|
uint charC=1;
|
|
|
|
|
// Next character
|
|
|
|
|
offset++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Find the line
|
|
|
|
|
uint offset=0;
|
|
|
|
|
while ((offset<length)&&(offset<(uint)errorOff))
|
|
|
|
|
{
|
|
|
|
|
if (sString[offset]=='\n')
|
|
|
|
|
{
|
|
|
|
|
line++;
|
|
|
|
|
charC=1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
charC++;
|
|
|
|
|
// Show the error
|
|
|
|
|
nlwarning("3D: Vertex program syntax error line %d character %d\n", line, charC);
|
|
|
|
|
|
|
|
|
|
// Next character
|
|
|
|
|
offset++;
|
|
|
|
|
}
|
|
|
|
|
// Setup not ok
|
|
|
|
|
delete drvInfo;
|
|
|
|
|
program->_DrvInfo = NULL;
|
|
|
|
|
_GPUPrgDrvInfos.erase(it);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Show the error
|
|
|
|
|
nlwarning("3D: Vertex program syntax error line %d character %d\n", line, charC);
|
|
|
|
|
// Set parameters for assembly programs
|
|
|
|
|
drvInfo->ParamIndices = source->ParamIndices;
|
|
|
|
|
|
|
|
|
|
// Disable vertex program
|
|
|
|
|
glDisable (GL_VERTEX_PROGRAM_NV);
|
|
|
|
|
_VertexProgramEnabled= false;
|
|
|
|
|
// Build the feature info
|
|
|
|
|
program->buildInfo(source->DisplayName.c_str(), source->Features);
|
|
|
|
|
|
|
|
|
|
// Setup not ok
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
// Setup ok
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
// Set parameters for assembly programs
|
|
|
|
|
drvInfo->ParamIndices = source->ParamIndices;
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
// Build the feature info
|
|
|
|
|
program->buildInfo(source->DisplayName.c_str(), source->Features);
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// Setup ok
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Cast the driver info pointer
|
|
|
|
|
drvInfo=safe_cast<CVertexProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->_DrvInfo);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
|
bool CDriverGL::activeNVVertexProgram(CVertexProgram *program)
|
|
|
|
|
{
|
|
|
|
|
H_AUTO_OGL(CVertexProgamDrvInfosGL_activeNVVertexProgram);
|
|
|
|
|
|
|
|
|
|
#ifndef USE_OPENGLES
|
|
|
|
|
// Setup or unsetup ?
|
|
|
|
|
if (program)
|
|
|
|
|
{
|
|
|
|
|
// Driver info
|
|
|
|
|
CVertexProgamDrvInfosGL *drvInfo = safe_cast<CVertexProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->_DrvInfo);
|
|
|
|
|
nlassert(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,503 +1516,288 @@ bool CDriverGL::setupARBVertexProgram (const CVPParser::TProgram &inParsedProgra
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
|
bool CDriverGL::activeARBVertexProgram (CVertexProgram *program)
|
|
|
|
|
|
|
|
|
|
bool CDriverGL::compileARBVertexProgram(NL3D::CVertexProgram *program)
|
|
|
|
|
{
|
|
|
|
|
H_AUTO_OGL(CDriverGL_activeARBVertexProgram);
|
|
|
|
|
H_AUTO_OGL(CDriverGL_compileARBVertexProgram);
|
|
|
|
|
|
|
|
|
|
#ifndef USE_OPENGLES
|
|
|
|
|
// Setup or unsetup ?
|
|
|
|
|
if (program)
|
|
|
|
|
{
|
|
|
|
|
// Driver info
|
|
|
|
|
CVertexProgamDrvInfosGL *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;
|
|
|
|
|
}
|
|
|
|
|
nlassert(!program->_DrvInfo);
|
|
|
|
|
glDisable(GL_VERTEX_PROGRAM_ARB);
|
|
|
|
|
_VertexProgramEnabled = 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 );
|
|
|
|
|
if (drvInfo->SpecularWritten)
|
|
|
|
|
{
|
|
|
|
|
glEnable( GL_COLOR_SUM_ARB );
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
// Find nelvp
|
|
|
|
|
CGPUProgramSource *source = NULL;
|
|
|
|
|
for (uint i = 0; i < program->getProgramSource()->Sources.size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp)
|
|
|
|
|
{
|
|
|
|
|
glDisable( GL_COLOR_SUM_ARB ); // no specular written
|
|
|
|
|
source = program->getProgramSource()->Sources[i];
|
|
|
|
|
}
|
|
|
|
|
_LastSetuppedVP = program;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
if (!source)
|
|
|
|
|
{
|
|
|
|
|
glDisable( GL_VERTEX_PROGRAM_ARB );
|
|
|
|
|
glDisable( GL_COLOR_SUM_ARB );
|
|
|
|
|
_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;
|
|
|
|
|
}
|
|
|
|
|
// 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::activeEXTVertexShader (CVertexProgram *program)
|
|
|
|
|
|
|
|
|
|
bool CDriverGL::activeARBVertexProgram(CVertexProgram *program)
|
|
|
|
|
{
|
|
|
|
|
H_AUTO_OGL(CDriverGL_activeEXTVertexShader);
|
|
|
|
|
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)
|
|
|
|
|
glEnable( GL_VERTEX_PROGRAM_ARB );
|
|
|
|
|
_VertexProgramEnabled = true;
|
|
|
|
|
nglBindProgramARB(GL_VERTEX_PROGRAM_ARB, drvInfo->ID);
|
|
|
|
|
if (drvInfo->SpecularWritten)
|
|
|
|
|
{
|
|
|
|
|
// 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);
|
|
|
|
|
glEnable(GL_COLOR_SUM_ARB);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// Cast the driver info pointer
|
|
|
|
|
drvInfo=safe_cast<CVertexProgamDrvInfosGL*>((IGPUProgramDrvInfos*)program->_DrvInfo);
|
|
|
|
|
glDisable(GL_COLOR_SUM_ARB); // no specular written
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glEnable( GL_VERTEX_SHADER_EXT);
|
|
|
|
|
_VertexProgramEnabled = true;
|
|
|
|
|
nglBindVertexShaderEXT( drvInfo->ID );
|
|
|
|
|
_LastSetuppedVP = program;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
glDisable( GL_VERTEX_SHADER_EXT );
|
|
|
|
|
glDisable(GL_VERTEX_PROGRAM_ARB);
|
|
|
|
|
glDisable(GL_COLOR_SUM_ARB);
|
|
|
|
|
_VertexProgramEnabled = false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
#else
|
|
|
|
|
return false;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
|
bool CDriverGL::activeVertexProgram (CVertexProgram *program)
|
|
|
|
|
{
|
|
|
|
|
H_AUTO_OGL(CDriverGL_activeVertexProgram)
|
|
|
|
|
// Extension here ?
|
|
|
|
|
if (_Extensions.NVVertexProgram)
|
|
|
|
|
{
|
|
|
|
|
return activeNVVertexProgram(program);
|
|
|
|
|
}
|
|
|
|
|
else if (_Extensions.ARBVertexProgram)
|
|
|
|
|
{
|
|
|
|
|
return activeARBVertexProgram(program);
|
|
|
|
|
}
|
|
|
|
|
else if (_Extensions.EXTVertexShader)
|
|
|
|
|
{
|
|
|
|
|
return activeEXTVertexShader(program);
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
// Can't do anything
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
|
|
|
|
|
|
void CDriverGL::setConstant (uint index, float f0, float f1, float f2, float f3)
|
|
|
|
|
bool CDriverGL::compileEXTVertexShader(CVertexProgram *program)
|
|
|
|
|
{
|
|
|
|
|
H_AUTO_OGL(CDriverGL_setConstant);
|
|
|
|
|
H_AUTO_OGL(CDriverGL_activeEXTVertexShader);
|
|
|
|
|
|
|
|
|
|
#ifndef USE_OPENGLES
|
|
|
|
|
// Vertex program exist ?
|
|
|
|
|
if (_Extensions.NVVertexProgram)
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
// Setup constant
|
|
|
|
|
nglProgramParameter4fNV (GL_VERTEX_PROGRAM_NV, index, f0, f1, f2, f3);
|
|
|
|
|
if (program->getProgramSource()->Sources[i]->Profile == CVertexProgram::nelvp)
|
|
|
|
|
{
|
|
|
|
|
source = program->getProgramSource()->Sources[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (_Extensions.ARBVertexProgram)
|
|
|
|
|
if (!source)
|
|
|
|
|
{
|
|
|
|
|
nglProgramEnvParameter4fARB(GL_VERTEX_PROGRAM_ARB, index, f0, f1, f2, f3);
|
|
|
|
|
nlwarning("OpenGL driver only supports 'nelvp' profile, vertex program cannot be used");
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
else if (_Extensions.EXTVertexShader)
|
|
|
|
|
|
|
|
|
|
// try to parse the program
|
|
|
|
|
CVPParser parser;
|
|
|
|
|
CVPParser::TProgram parsedProgram;
|
|
|
|
|
std::string errorOutput;
|
|
|
|
|
bool result = parser.parse(source->SourcePtr, parsedProgram, errorOutput);
|
|
|
|
|
if (!result)
|
|
|
|
|
{
|
|
|
|
|
float datas[] = { f0, f1, f2, f3 };
|
|
|
|
|
nglSetInvariantEXT(_EVSConstantHandle + index, GL_FLOAT, datas);
|
|
|
|
|
nlwarning("Unable to parse a vertex program.");
|
|
|
|
|
#ifdef NL_DEBUG
|
|
|
|
|
nlerror(errorOutput.c_str());
|
|
|
|
|
#endif
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
void CDriverGL::setConstant (uint index, double d0, double d1, double d2, double d3)
|
|
|
|
|
{
|
|
|
|
|
H_AUTO_OGL(CDriverGL_setConstant);
|
|
|
|
|
// Create a driver info
|
|
|
|
|
CVertexProgamDrvInfosGL *drvInfo;
|
|
|
|
|
*it = drvInfo = new CVertexProgamDrvInfosGL (this, it);
|
|
|
|
|
// Set the pointer
|
|
|
|
|
program->_DrvInfo=drvInfo;
|
|
|
|
|
|
|
|
|
|
#ifndef USE_OPENGLES
|
|
|
|
|
// Vertex program exist ?
|
|
|
|
|
if (_Extensions.NVVertexProgram)
|
|
|
|
|
if (!setupEXTVertexShader(parsedProgram, drvInfo->ID, drvInfo->Variants, drvInfo->UsedVertexComponents))
|
|
|
|
|
{
|
|
|
|
|
// 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);
|
|
|
|
|
delete drvInfo;
|
|
|
|
|
program->_DrvInfo = NULL;
|
|
|
|
|
_GPUPrgDrvInfos.erase(it);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set parameters for assembly programs
|
|
|
|
|
drvInfo->ParamIndices = source->ParamIndices;
|
|
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
|
// Build the feature info
|
|
|
|
|
program->buildInfo(source->DisplayName.c_str(), source->Features);
|
|
|
|
|
|
|
|
|
|
void CDriverGL::setConstant (uint index, const NLMISC::CVector& value)
|
|
|
|
|
{
|
|
|
|
|
H_AUTO_OGL(CDriverGL_setConstant);
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
#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)
|
|
|
|
|
bool CDriverGL::activeEXTVertexShader(CVertexProgram *program)
|
|
|
|
|
{
|
|
|
|
|
H_AUTO_OGL(CDriverGL_setConstant);
|
|
|
|
|
H_AUTO_OGL(CDriverGL_activeEXTVertexShader);
|
|
|
|
|
|
|
|
|
|
#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)
|
|
|
|
|
|
|
|
|
|
// Setup or unsetup ?
|
|
|
|
|
if (program)
|
|
|
|
|
{
|
|
|
|
|
nglProgramEnvParameter4dARB(GL_VERTEX_PROGRAM_ARB, index, value.x, value.y, value.z, 0);
|
|
|
|
|
// 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 if (_Extensions.EXTVertexShader)
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
double datas[] = { value.x, value.y, value.z, 0 };
|
|
|
|
|
nglSetInvariantEXT(_EVSConstantHandle + index, GL_DOUBLE, datas);
|
|
|
|
|
glDisable(GL_VERTEX_SHADER_EXT);
|
|
|
|
|
_VertexProgramEnabled = false;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
|
void CDriverGL::setConstant (uint index, uint num, const float *src)
|
|
|
|
|
{
|
|
|
|
|
H_AUTO_OGL(CDriverGL_setConstant);
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
#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)
|
|
|
|
|
bool CDriverGL::compileVertexProgram(NL3D::CVertexProgram *program)
|
|
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
if (program->_DrvInfo == NULL)
|
|
|
|
|
{
|
|
|
|
|
for(uint k = 0; k < num; ++k)
|
|
|
|
|
// Extension
|
|
|
|
|
if (_Extensions.NVVertexProgram)
|
|
|
|
|
{
|
|
|
|
|
nglProgramEnvParameter4dvARB(GL_VERTEX_PROGRAM_ARB, index + k, src + 4 * k);
|
|
|
|
|
return compileNVVertexProgram(program);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (_Extensions.EXTVertexShader)
|
|
|
|
|
{
|
|
|
|
|
for(uint k = 0; k < num; ++k)
|
|
|
|
|
else if (_Extensions.ARBVertexProgram)
|
|
|
|
|
{
|
|
|
|
|
nglSetInvariantEXT(_EVSConstantHandle + index + k, GL_DOUBLE, (void *) (src + 4 * k));
|
|
|
|
|
return compileARBVertexProgram(program);
|
|
|
|
|
}
|
|
|
|
|
else if (_Extensions.EXTVertexShader)
|
|
|
|
|
{
|
|
|
|
|
return compileEXTVertexShader(program);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Can't do anything
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
|
|
|
|
|
|
const uint CDriverGL::GLMatrix[IDriver::NumMatrix]=
|
|
|
|
|
bool CDriverGL::activeVertexProgram(CVertexProgram *program)
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
|
H_AUTO_OGL(CDriverGL_activeVertexProgram)
|
|
|
|
|
|
|
|
|
|
void CDriverGL::setConstantMatrix (uint index, IDriver::TMatrix matrix, IDriver::TTransform transform)
|
|
|
|
|
{
|
|
|
|
|
H_AUTO_OGL(CDriverGL_setConstantMatrix);
|
|
|
|
|
// Compile if necessary
|
|
|
|
|
if (program && !CDriverGL::compileVertexProgram(program)) return false;
|
|
|
|
|
|
|
|
|
|
#ifndef USE_OPENGLES
|
|
|
|
|
// Vertex program exist ?
|
|
|
|
|
// Extension
|
|
|
|
|
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);
|
|
|
|
|
return activeNVVertexProgram(program);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
else if (_Extensions.ARBVertexProgram)
|
|
|
|
|
{
|
|
|
|
|
// 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);
|
|
|
|
|
}
|
|
|
|
|
return activeARBVertexProgram(program);
|
|
|
|
|
}
|
|
|
|
|
else if (_Extensions.EXTVertexShader)
|
|
|
|
|
{
|
|
|
|
|
return activeEXTVertexShader(program);
|
|
|
|
|
}
|
|
|
|
|
#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]);
|
|
|
|
|
// Can't do anything
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ***************************************************************************
|
|
|
|
|