From d176bca1e701b902eb18d121ceb441bcfe620b60 Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Wed, 10 Apr 2013 02:13:27 +0200 Subject: [PATCH] Fixed critical out of bounds bug in RB_DrawShaderPasses() --- neo/renderer/RenderProgs.cpp | 93 -------------------------------- neo/renderer/RenderProgs.h | 1 - neo/renderer/tr_backend_draw.cpp | 14 +++-- 3 files changed, 6 insertions(+), 102 deletions(-) diff --git a/neo/renderer/RenderProgs.cpp b/neo/renderer/RenderProgs.cpp index b59579e5..572518e5 100644 --- a/neo/renderer/RenderProgs.cpp +++ b/neo/renderer/RenderProgs.cpp @@ -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 diff --git a/neo/renderer/RenderProgs.h b/neo/renderer/RenderProgs.h index ba97546f..098d7b03 100644 --- a/neo/renderer/RenderProgs.h +++ b/neo/renderer/RenderProgs.h @@ -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& uniforms ); void LoadGLSLProgram( const int programIndex, const int vertexShaderIndex, const int fragmentShaderIndex ); diff --git a/neo/renderer/tr_backend_draw.cpp b/neo/renderer/tr_backend_draw.cpp index 4979ef46..c625b1a4 100644 --- a/neo/renderer/tr_backend_draw.cpp +++ b/neo/renderer/tr_backend_draw.cpp @@ -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++ ) {