Fixed critical out of bounds bug in RB_DrawShaderPasses()

This commit is contained in:
Robert Beckebans 2013-04-10 02:13:27 +02:00
parent 3023533e57
commit d176bca1e7
3 changed files with 6 additions and 102 deletions

View file

@ -310,99 +310,6 @@ void idRenderProgManager::LoadFragmentShader( int index )
fragmentShaders[index].progId = ( GLuint ) LoadGLSLShader( GL_FRAGMENT_SHADER, fragmentShaders[index].name, fragmentShaders[index].uniforms );
}
/*
================================================================================================
idRenderProgManager::LoadShader
================================================================================================
*/
GLuint idRenderProgManager::LoadShader( GLenum target, const char* name, const char* startToken )
{
idStr fullPath = "renderprogs\\gl\\";
fullPath += name;
common->Printf( "%s", fullPath.c_str() );
char* fileBuffer = NULL;
fileSystem->ReadFile( fullPath.c_str(), ( void** )&fileBuffer, NULL );
if( fileBuffer == NULL )
{
common->Printf( ": File not found\n" );
return INVALID_PROGID;
}
if( !R_IsInitialized() )
{
common->Printf( ": Renderer not initialized\n" );
fileSystem->FreeFile( fileBuffer );
return INVALID_PROGID;
}
// vertex and fragment shaders are both be present in a single file, so
// scan for the proper header to be the start point, and stamp a 0 in after the end
char* start = strstr( ( char* )fileBuffer, startToken );
if( start == NULL )
{
common->Printf( ": %s not found\n", startToken );
fileSystem->FreeFile( fileBuffer );
return INVALID_PROGID;
}
char* end = strstr( start, "END" );
if( end == NULL )
{
common->Printf( ": END not found for %s\n", startToken );
fileSystem->FreeFile( fileBuffer );
return INVALID_PROGID;
}
end[3] = 0;
idStr program = start;
program.Replace( "vertex.normal", "vertex.attrib[11]" );
program.Replace( "vertex.texcoord[0]", "vertex.attrib[8]" );
program.Replace( "vertex.texcoord", "vertex.attrib[8]" );
GLuint progId;
qglGenProgramsARB( 1, &progId );
qglBindProgramARB( target, progId );
qglGetError();
qglProgramStringARB( target, GL_PROGRAM_FORMAT_ASCII_ARB, program.Length(), program.c_str() );
GLenum err = qglGetError();
GLint ofs = -1;
qglGetIntegerv( GL_PROGRAM_ERROR_POSITION_ARB, &ofs );
if( ( err == GL_INVALID_OPERATION ) || ( ofs != -1 ) )
{
if( err == GL_INVALID_OPERATION )
{
const GLubyte* str = qglGetString( GL_PROGRAM_ERROR_STRING_ARB );
common->Printf( "\nGL_PROGRAM_ERROR_STRING_ARB: %s\n", str );
}
else
{
common->Printf( "\nUNKNOWN ERROR\n" );
}
if( ofs < 0 )
{
common->Printf( "GL_PROGRAM_ERROR_POSITION_ARB < 0\n" );
}
else if( ofs >= program.Length() )
{
common->Printf( "error at end of shader\n" );
}
else
{
common->Printf( "error at %i:\n%s", ofs, program.c_str() + ofs );
}
qglDeleteProgramsARB( 1, &progId );
fileSystem->FreeFile( fileBuffer );
return INVALID_PROGID;
}
common->Printf( "\n" );
fileSystem->FreeFile( fileBuffer );
return progId;
}
/*
================================================================================================
idRenderProgManager::BindShader

View file

@ -368,7 +368,6 @@ protected:
BindShader( builtinShaders[i], builtinShaders[i] );
}
GLuint LoadShader( GLenum target, const char* name, const char* startToken );
bool CompileGLSL( GLenum target, const char* name );
GLuint LoadGLSLShader( GLenum target, const char* name, idList<int>& uniforms );
void LoadGLSLProgram( const int programIndex, const int vertexShaderIndex, const int fragmentShaderIndex );

View file

@ -3,6 +3,7 @@
Doom 3 BFG Edition GPL Source Code
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
Copyright (C) 2013 Robert Beckebans
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
@ -178,13 +179,7 @@ void RB_DrawElementsWithCounters( const drawSurf_t* surf )
if( surf->jointCache )
{
// DG: this happens all the time in the erebus1 map with blendlight.vfp,
// so don't call assert (through verify) here until it's fixed (if fixable)
// else the game crashes on linux when using debug builds
// FIXME: fix this properly if possible?
//if( !verify( renderProgManager.ShaderUsesJoints() ) )
if( ! renderProgManager.ShaderUsesJoints() )
// DG end
if( !verify( renderProgManager.ShaderUsesJoints() ) )
{
return;
}
@ -2271,7 +2266,10 @@ static int RB_DrawShaderPasses( const drawSurf_t* const* const drawSurfs, const
GL_State( stageGLState );
renderProgManager.BindShader( newStage->glslProgram, newStage->glslProgram );
// RB: CRITICAL BUGFIX: changed newStage->glslProgram to vertexProgram and fragmentProgram
// otherwise it will result in an out of bounds crash in RB_DrawElementsWithCounters
renderProgManager.BindShader( newStage->vertexProgram, newStage->fragmentProgram );
// RB end
for( int j = 0; j < newStage->numVertexParms; j++ )
{