/*
=================
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" );
}
예제 #2
0
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;
}
예제 #3
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");
}
예제 #4
0
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;
}
예제 #5
0
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 );
}
예제 #6
0
/*
=================
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;
}