void R_ShutdownGamma(void) { if (gammaProgram.program) { if (gammaProgram.vertexShader) { glDetachObjectARB(gammaProgram.program, gammaProgram.vertexShader); qglDeleteObjectARB(gammaProgram.vertexShader); } if (gammaProgram.fragmentShader) { glDetachObjectARB(gammaProgram.program, gammaProgram.fragmentShader); qglDeleteObjectARB(gammaProgram.fragmentShader); } qglDeleteObjectARB(gammaProgram.program); Com_Memset(&gammaProgram, 0, sizeof(shaderProgram_t)); } if (screenImage) { screenImage = NULL; } }
void GLSL_DeleteGPUShader(shaderProgram_t *program) { if(program->program) { if (program->vertexShader) { qglDetachObjectARB(program->program, program->vertexShader); qglDeleteObjectARB(program->vertexShader); } if (program->fragmentShader) { qglDetachObjectARB(program->program, program->fragmentShader); qglDeleteObjectARB(program->fragmentShader); } qglDeleteObjectARB(program->program); if (program->uniformBuffer) { ri.Free(program->uniformBuffer); } Com_Memset(program, 0, sizeof(*program)); } }
static GLhandleARB R_CompileGLSLShader( GLhandleARB programObject, GLenum shaderType, unsigned int sourceStringCount, const char *sourceStrings[] ) { GLhandleARB shaderObject; GLint shaderCompiled; const char *shaderName; int i; char compileLog[ 4096 ]; if( shaderType == GL_VERTEX_SHADER_ARB ) { shaderName = "vertex shader"; } else { shaderName = "fragment shader"; } // run a basic error check for (i = 0 ; i < sourceStringCount ; i++) { if (sourceStrings[i] == 0) { Con_Printf("R_CompileGLSLShader: string #%i of %s is NULL!\n", i, shaderName); return 0; } } // R_CheckError(); shaderObject = qglCreateShaderObjectARB( shaderType ); if( shaderObject == 0 ) { // R_CheckError(); return 0; } if( sourceStringCount != 0 ) { qglShaderSourceARB( shaderObject, sourceStringCount, sourceStrings, NULL); qglCompileShaderARB( shaderObject ); // R_CheckError(); qglGetObjectParameterivARB( shaderObject, GL_OBJECT_COMPILE_STATUS_ARB, &shaderCompiled ); qglGetInfoLogARB( shaderObject, sizeof(compileLog), NULL, compileLog); if( *compileLog ) { Con_Printf("%s compile log:\n%s\n", shaderName, compileLog); } if( !shaderCompiled ) { qglDeleteObjectARB( shaderObject ); // R_CheckError(); return 0; } } // TODO: check whether an empty shader object can be compiled! qglAttachObjectARB( programObject, shaderObject); qglDeleteObjectARB( shaderObject ); //R_CheckError(); return shaderObject; }
static unsigned int R_CompileGLSLProgram(unsigned int vertexstrings_count, const char **vertexstrings_list, unsigned int fragmentstrings_count, const char **fragmentstrings_list) { GLint programLinked; GLhandleARB programObject = 0; char compileLog[4096]; //R_CheckError(); // if (!R.ext.ARB_fragment_shader) if (!gl_support_GLSL_shaders) return 0; programObject = qglCreateProgramObjectARB(); //R_CheckError(); if( programObject == 0 ) { return 0; } if( R_CompileGLSLShader( programObject, GL_VERTEX_SHADER_ARB, vertexstrings_count, vertexstrings_list ) == 0 || R_CompileGLSLShader( programObject, GL_FRAGMENT_SHADER_ARB, fragmentstrings_count, fragmentstrings_list ) == 0 ) { qglDeleteObjectARB( programObject ); // R_CheckError(); return 0; } qglLinkProgramARB( programObject ); // R_CheckError(); qglGetObjectParameterivARB( programObject, GL_OBJECT_LINK_STATUS_ARB, &programLinked ); qglGetInfoLogARB( programObject, sizeof( compileLog ), NULL, compileLog ); if( *compileLog ) { Con_Printf("program link log:\n%s\n", compileLog); // software vertex shader is ok but software fragment shader is WAY // too slow, fail program if so. // NOTE: this string might be ATI specific, but that's ok because the // ATI R300 chip (Radeon 9500-9800/X300) is the most likely to use a // software fragment shader due to low instruction and dependent // texture limits. if (strstr( compileLog, "fragment shader will run in software" )) programLinked = false; } //R_CheckError(); if( !programLinked ) { qglDeleteObjectARB( programObject ); return 0; } //R_CheckError(); return (unsigned int) programObject; }
void R_Shader_Quit(void) { unsigned int * const programObject = &r_refdef.lightShader.programObject; if( *programObject != 0 ) { qglDeleteObjectARB( *programObject ); *programObject = 0; } }
static void R_InitFragmentShader( const char *filename, GLhandleARB *fragmentShader, GLhandleARB *program, GLhandleARB vertexShader, const char *fallbackShader ) { int len; int slen; void *shaderSource; char *text; qboolean fallback = qfalse; if ( !glsl ) { return; } Com_VPrintf( "^5%s ->\n", filename ); *fragmentShader = qglCreateShaderObjectARB( GL_FRAGMENT_SHADER_ARB ); len = ri.FS_ReadFile( filename, &shaderSource ); if ( len <= 0 ) { len = strlen(fallbackShader); if ( len ) { Com_VPrintf( "^1using fallback shader\n" ); //ri.FS_FreeFile(shaderSource); //shaderSource = (void *)fallbackShader; fallback = qtrue; } else { Com_VPrintf( "^1couldn't find file\n" ); R_DeleteGlslShadersAndPrograms(); glsl = qfalse; return; } } slen = strlen(ShaderExtensions); text = (char *)malloc(len + slen + 3); if (!text) { Com_VPrintf( "R_InitFragmentShader() couldn't allocate memory for GLSL shader file\n" ); if ( !fallbackShader ) ri.FS_FreeFile(shaderSource); qglDeleteObjectARB(*fragmentShader); return; } Com_sprintf( text, len + slen + 3, "%s\n%s\n", ShaderExtensions, fallback ? fallbackShader : (char *)shaderSource ); qglShaderSourceARB(*fragmentShader, 1, (const char **)&text, NULL); qglCompileShaderARB(*fragmentShader); printGlslLog(*fragmentShader); if ( !fallbackShader ) ri.FS_FreeFile(shaderSource); free(text); *program = qglCreateProgramObjectARB(); qglAttachObjectARB(*program, vertexShader); qglAttachObjectARB(*program, *fragmentShader); qglLinkProgramARB(*program); printGlslLog(*program); //Com_VPrintf("\n"); }
static int GLSL_CompileGPUShader(GLhandleARB program, GLhandleARB *prevShader, const GLcharARB *buffer, int size, GLenum shaderType) { GLint compiled; GLhandleARB shader; shader = qglCreateShaderObjectARB(shaderType); qglShaderSourceARB(shader, 1, (const GLcharARB **)&buffer, &size); // compile shader qglCompileShaderARB(shader); // check if shader compiled qglGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &compiled); if(!compiled) { GLSL_PrintShaderSource(shader); GLSL_PrintInfoLog(shader, qfalse); ri.Error(ERR_DROP, "Couldn't compile shader"); return 0; } //GLSL_PrintInfoLog(shader, qtrue); //GLSL_PrintShaderSource(shader); if (*prevShader) { qglDetachObjectARB(program, *prevShader); qglDeleteObjectARB(*prevShader); } // attach shader to program qglAttachObjectARB(program, shader); *prevShader = shader; return 1; }
static int GLSL_InitGPUShader2(shaderProgram_t * program, const char *name, int attribs, const char *vpCode, const char *fpCode) { ri.Printf(PRINT_DEVELOPER, "------- GPU shader -------\n"); if(strlen(name) >= MAX_QPATH) { ri.Error(ERR_DROP, "GLSL_InitGPUShader2: \"%s\" is too long", name); } Q_strncpyz(program->name, name, sizeof(program->name)); program->program = qglCreateProgramObjectARB(); program->attribs = attribs; if (!(GLSL_CompileGPUShader(program->program, &program->vertexShader, vpCode, strlen(vpCode), GL_VERTEX_SHADER_ARB))) { ri.Printf(PRINT_ALL, "GLSL_InitGPUShader2: Unable to load \"%s\" as GL_VERTEX_SHADER_ARB\n", name); qglDeleteObjectARB(program->program); return 0; } if(fpCode) { if(!(GLSL_CompileGPUShader(program->program, &program->fragmentShader, fpCode, strlen(fpCode), GL_FRAGMENT_SHADER_ARB))) { ri.Printf(PRINT_ALL, "GLSL_InitGPUShader2: Unable to load \"%s\" as GL_FRAGMENT_SHADER_ARB\n", name); qglDeleteObjectARB(program->program); return 0; } } if(attribs & ATTR_POSITION) qglBindAttribLocationARB(program->program, ATTR_INDEX_POSITION, "attr_Position"); if(attribs & ATTR_TEXCOORD) qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD, "attr_TexCoord0"); if(attribs & ATTR_LIGHTCOORD) qglBindAttribLocationARB(program->program, ATTR_INDEX_LIGHTCOORD, "attr_TexCoord1"); // if(attribs & ATTR_TEXCOORD2) // qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD2, "attr_TexCoord2"); // if(attribs & ATTR_TEXCOORD3) // qglBindAttribLocationARB(program->program, ATTR_INDEX_TEXCOORD3, "attr_TexCoord3"); if(attribs & ATTR_TANGENT) qglBindAttribLocationARB(program->program, ATTR_INDEX_TANGENT, "attr_Tangent"); if(attribs & ATTR_NORMAL) qglBindAttribLocationARB(program->program, ATTR_INDEX_NORMAL, "attr_Normal"); if(attribs & ATTR_COLOR) qglBindAttribLocationARB(program->program, ATTR_INDEX_COLOR, "attr_Color"); if(attribs & ATTR_PAINTCOLOR) qglBindAttribLocationARB(program->program, ATTR_INDEX_PAINTCOLOR, "attr_PaintColor"); if(attribs & ATTR_LIGHTDIRECTION) qglBindAttribLocationARB(program->program, ATTR_INDEX_LIGHTDIRECTION, "attr_LightDirection"); if(attribs & ATTR_POSITION2) qglBindAttribLocationARB(program->program, ATTR_INDEX_POSITION2, "attr_Position2"); if(attribs & ATTR_NORMAL2) qglBindAttribLocationARB(program->program, ATTR_INDEX_NORMAL2, "attr_Normal2"); if(attribs & ATTR_TANGENT2) qglBindAttribLocationARB(program->program, ATTR_INDEX_TANGENT2, "attr_Tangent2"); GLSL_LinkProgram(program->program); return 1; }
void R_DeleteGlslShadersAndPrograms( void ) { if ( !r_enablePostProcess->integer || !glsl ) { return; } // detach qglDetachObjectARB(tr.blurHorizSp, tr.blurHorizFs); qglDetachObjectARB(tr.blurHorizSp, tr.mainVs); qglDetachObjectARB(tr.blurVerticalSp, tr.blurVerticalFs); qglDetachObjectARB(tr.blurVerticalSp, tr.mainVs); qglDetachObjectARB(tr.brightPassSp, tr.brightPassFs); qglDetachObjectARB(tr.brightPassSp, tr.mainVs); qglDetachObjectARB(tr.downSample1Sp, tr.downSample1Fs); qglDetachObjectARB(tr.downSample1Sp, tr.mainVs); qglDetachObjectARB(tr.combineSp, tr.combineFs); qglDetachObjectARB(tr.combineSp, tr.mainVs); qglDetachObjectARB(tr.colorCorrectSp, tr.colorCorrectFs); qglDetachObjectARB(tr.colorCorrectSp, tr.mainVs); // delete qglDeleteObjectARB(tr.blurHorizSp); qglDeleteObjectARB(tr.blurHorizFs); qglDeleteObjectARB(tr.blurVerticalSp); qglDeleteObjectARB(tr.blurVerticalFs); qglDeleteObjectARB(tr.brightPassSp); qglDeleteObjectARB(tr.brightPassFs); qglDeleteObjectARB(tr.downSample1Sp); qglDeleteObjectARB(tr.downSample1Fs); qglDeleteObjectARB(tr.combineSp); qglDeleteObjectARB(tr.combineFs); qglDeleteObjectARB(tr.colorCorrectSp); qglDeleteObjectARB(tr.colorCorrectFs); qglDeleteObjectARB(tr.mainVs); // reset tr.blurHorizSp = 0; tr.blurHorizFs = 0; tr.blurVerticalSp = 0; tr.blurVerticalFs = 0; tr.brightPassSp = 0; tr.brightPassFs = 0; tr.downSample1Sp = 0; tr.downSample1Fs = 0; tr.combineSp = 0; tr.combineFs = 0; tr.colorCorrectSp = 0; tr.colorCorrectFs = 0; tr.mainVs = 0; }