static void GLSL_PrintInfoLog(GLhandleARB object, qboolean developerOnly) { char *msg; static char msgPart[1024]; int maxLength = 0; int i; int printLevel = developerOnly ? PRINT_DEVELOPER : PRINT_ALL; qglGetObjectParameterivARB(object, GL_OBJECT_INFO_LOG_LENGTH_ARB, &maxLength); if (maxLength <= 0) { ri.Printf(printLevel, "No compile log.\n"); return; } ri.Printf(printLevel, "compile log:\n"); if (maxLength < 1023) { qglGetInfoLogARB(object, maxLength, &maxLength, msgPart); msgPart[maxLength + 1] = '\0'; ri.Printf(printLevel, "%s\n", msgPart); } else { msg = ri.Malloc(maxLength); qglGetInfoLogARB(object, maxLength, &maxLength, msg); for(i = 0; i < maxLength; i += 1024) { Q_strncpyz(msgPart, msg + i, sizeof(msgPart)); ri.Printf(printLevel, "%s\n", msgPart); } ri.Free(msg); } }
static void printGlslLog( GLhandleARB obj ) { int infoLogLength = 0; char infoLog[1024]; int len; qglGetObjectParameterivARB(obj, GL_OBJECT_INFO_LOG_LENGTH_ARB, &infoLogLength); if (infoLogLength > 0) { qglGetInfoLogARB(obj, 1024, &len, infoLog); Com_VPrintf( "%s\n", infoLog ); } }
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; }