/* ================= R_LoadGLSLShader loads GLSL vertex or fragment shaders ================= */ void R_LoadGLSLShader( const char *name, shaderProgram_t *shaderProgram, GLenum type ) { char *fileBuffer; char *buffer; idStr fullPath = "gl2progs/"; fullPath += name; common->Printf( "%s", fullPath.c_str() ); // load the program even if we don't support it, so // fs_copyfiles can generate cross-platform data dumps fileSystem->ReadFile( fullPath.c_str(), (void **)&fileBuffer, NULL ); if ( !fileBuffer ) { common->Printf( ": File not found\n" ); return; } // copy to stack memory and free buffer = (char *)_alloca( strlen( fileBuffer ) + 1 ); strcpy( buffer, fileBuffer ); fileSystem->FreeFile( fileBuffer ); if ( !glConfig.isInitialized ) { return; } switch( type ) { case GL_VERTEX_SHADER_ARB: // create vertex shader shaderProgram->vertexShader = qglCreateShaderObjectARB( GL_VERTEX_SHADER_ARB ); qglShaderSourceARB( shaderProgram->vertexShader, 1, (const GLcharARB **)&buffer, 0 ); qglCompileShaderARB( shaderProgram->vertexShader ); break; case GL_FRAGMENT_SHADER_ARB: // create fragment shader shaderProgram->fragmentShader = qglCreateShaderObjectARB( GL_FRAGMENT_SHADER_ARB ); qglShaderSourceARB( shaderProgram->fragmentShader, 1, (const GLcharARB **)&buffer, 0 ); qglCompileShaderARB( shaderProgram->fragmentShader ); break; default: common->Printf( "R_LoadGLSLShader: no type\n" ); return; } common->Printf( "\n" ); }
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 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; }
void InitGlslShadersAndPrograms( void ) { void *shaderSource; GLenum target; float bloomTextureScale; int ret; if ( !r_enablePostProcess->integer || !glsl ) { return; } GL_SelectTexture(0); qglDisable( GL_TEXTURE_2D ); qglEnable( GL_TEXTURE_RECTANGLE_ARB ); bloomTextureScale = r_BloomTextureScale->value; if ( bloomTextureScale < 0.01 ) { bloomTextureScale = 0.01; } else if ( bloomTextureScale > 1 ) { bloomTextureScale = 1; } target = GL_TEXTURE_RECTANGLE_ARB; tr.bloomWidth = glConfig.vidWidth * bloomTextureScale; tr.bloomHeight = glConfig.vidHeight * bloomTextureScale; qglGenTextures(1, &tr.bloomTexture); qglBindTexture(target, tr.bloomTexture); qglTexImage2D(target, 0, GL_RGBA8, tr.bloomWidth, tr.bloomHeight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); qglTexParameteri(target, GL_TEXTURE_WRAP_S, r_glClampToEdge->integer ? GL_CLAMP_TO_EDGE : GL_CLAMP); qglTexParameteri(target, GL_TEXTURE_WRAP_T, r_glClampToEdge->integer ? GL_CLAMP_TO_EDGE : GL_CLAMP); qglTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); qglTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); target = GL_TEXTURE_RECTANGLE_ARB; qglGenTextures(1, &tr.backBufferTexture); qglBindTexture(target, tr.backBufferTexture); qglTexImage2D(target, 0, GL_RGB8, glConfig.vidWidth, glConfig.vidHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 0); qglTexParameteri(target, GL_TEXTURE_WRAP_S, r_glClampToEdge->integer ? GL_CLAMP_TO_EDGE : GL_CLAMP); qglTexParameteri(target, GL_TEXTURE_WRAP_T, r_glClampToEdge->integer ? GL_CLAMP_TO_EDGE : GL_CLAMP); qglTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); qglTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); qglDisable(GL_TEXTURE_RECTANGLE_ARB); qglEnable(GL_TEXTURE_2D); GL_SelectTexture(0); Com_VPrintf("^5scripts/posteffect.vs ->\n"); ret = ri.FS_ReadFile("scripts/posteffect.vs", &shaderSource); if (ret > 0) { tr.mainVs = qglCreateShaderObjectARB(GL_VERTEX_SHADER_ARB); qglShaderSourceARB(tr.mainVs, 1, (const char **)&shaderSource, NULL); qglCompileShaderARB(tr.mainVs); printGlslLog(tr.mainVs); ri.FS_FreeFile(shaderSource); } else if ( strlen(fallbackShader_posteffect) ) { Com_VPrintf("^1file not found, using fallback shader\n"); //ri.FS_FreeFile(shaderSource); tr.mainVs = qglCreateShaderObjectARB(GL_VERTEX_SHADER_ARB); qglShaderSourceARB(tr.mainVs, 1, &fallbackShader_posteffect, NULL); qglCompileShaderARB(tr.mainVs); printGlslLog(tr.mainVs); } else { Com_VPrintf("^1file not found\n"); glsl = qfalse; R_DeleteGlslShadersAndPrograms(); } R_InitFragmentShader( "scripts/colorcorrect.fs", &tr.colorCorrectFs, &tr.colorCorrectSp, tr.mainVs, fallbackShader_colorcorrect ); R_InitFragmentShader( "scripts/blurhoriz.fs", &tr.blurHorizFs, &tr.blurHorizSp, tr.mainVs, fallbackShader_blurhoriz ); R_InitFragmentShader( "scripts/blurvertical.fs", &tr.blurVerticalFs, &tr.blurVerticalSp, tr.mainVs, fallbackShader_blurvertical ); R_InitFragmentShader( "scripts/brightpass.fs", &tr.brightPassFs, &tr.brightPassSp, tr.mainVs, fallbackShader_brightpass ); R_InitFragmentShader( "scripts/combine.fs", &tr.combineFs, &tr.combineSp, tr.mainVs, fallbackShader_combine ); R_InitFragmentShader( "scripts/downsample1.fs", &tr.downSample1Fs, &tr.downSample1Sp, tr.mainVs, fallbackShader_downsample1 ); }
/* ================= R_LoadGLSLShader loads GLSL vertex or fragment shaders ================= */ bool R_LoadGLSLShader( const char *name, shaderProgram_t *shaderProgram, GLenum type ) { idStr fullPath = "gl2progs/"; fullPath += name; char *fileBuffer; char *buffer; common->Printf( "%s", fullPath.c_str() ); // load the program even if we don't support it, so // fs_copyfiles can generate cross-platform data dumps fileSystem->ReadFile( fullPath.c_str(), (void **)&fileBuffer, NULL ); if ( !fileBuffer ) { common->Printf( ": File not found\n" ); return false; } // copy to stack memory and free buffer = (char *)_alloca( strlen( fileBuffer ) + 1 ); strcpy( buffer, fileBuffer ); fileSystem->FreeFile( fileBuffer ); if ( !glConfig.isInitialized ) { return false; } GLuint shader; switch( type ) { case GL_VERTEX_SHADER_ARB: if (shaderProgram->vertexShader != -1) qglDeleteShader(shaderProgram->vertexShader); shaderProgram->vertexShader = -1; // create vertex shader shader = qglCreateShaderObjectARB( GL_VERTEX_SHADER_ARB ); qglShaderSourceARB( shader, 1, (const GLcharARB **)&buffer, 0 ); qglCompileShaderARB( shader ); break; case GL_FRAGMENT_SHADER_ARB: if (shaderProgram->fragmentShader != -1) qglDeleteShader(shaderProgram->fragmentShader); shaderProgram->fragmentShader = -1; // create fragment shader shader = qglCreateShaderObjectARB( GL_FRAGMENT_SHADER_ARB ); qglShaderSourceARB( shader, 1, (const GLcharARB **)&buffer, 0 ); qglCompileShaderARB( shader ); break; default: common->Printf( "R_LoadGLSLShader: no type\n" ); return false; } GLint logLength; qglGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); if (logLength > 1) { GLchar *log = (GLchar *)malloc(logLength); qglGetShaderInfoLog(shader, logLength, &logLength, log); common->Printf((const char*)log); free(log); } GLint status; qglGetShaderiv(shader, GL_COMPILE_STATUS, &status); if (status == 0) { qglDeleteShader(shader); return false; } switch( type ) { case GL_VERTEX_SHADER_ARB: shaderProgram->vertexShader = shader; break; case GL_FRAGMENT_SHADER_ARB: shaderProgram->fragmentShader = shader; break; } common->Printf( "\n" ); return true; }