/*
=================
R_LinkGLSLShader

links the GLSL vertex and fragment shaders together to form a GLSL program
=================
*/
bool R_LinkGLSLShader( shaderProgram_t *shaderProgram, bool needsAttributes ) {
	GLint linked;

	shaderProgram->program = qglCreateProgramObjectARB( );

	qglAttachObjectARB( shaderProgram->program, shaderProgram->vertexShader );
	qglAttachObjectARB( shaderProgram->program, shaderProgram->fragmentShader );

	if ( needsAttributes ) {
		qglBindAttribLocationARB( shaderProgram->program, 8, "attr_TexCoord" );
		qglBindAttribLocationARB( shaderProgram->program, 9, "attr_Tangent" );
		qglBindAttribLocationARB( shaderProgram->program, 10, "attr_Bitangent" );
		qglBindAttribLocationARB( shaderProgram->program, 11, "attr_Normal" );
	}

	qglLinkProgramARB( shaderProgram->program );

	qglGetObjectParameterivARB( shaderProgram->program, GL_OBJECT_LINK_STATUS_ARB, &linked );
	if ( !linked ) {
		common->Printf( "R_LinkGLSLShader: program failed to link\n" );
		return false;
	}

	return true;
}
Example #2
0
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 );
	}
}
Example #3
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;
}
/*
=================
R_ValidateGLSLProgram

makes sure GLSL program is valid
=================
*/
bool R_ValidateGLSLProgram( shaderProgram_t *shaderProgram ) {
	GLint validProgram;

	qglValidateProgramARB( shaderProgram->program );

	qglGetObjectParameterivARB( shaderProgram->program, GL_OBJECT_VALIDATE_STATUS_ARB, &validProgram );
	if( !validProgram ) {
		common->Printf( "R_ValidateGLSLProgram: program invalid\n" );
		return false;
	}

	return true;
}
Example #5
0
static void GLSL_ValidateProgram(GLhandleARB program)
{
	GLint           validated;

	qglValidateProgramARB(program);

	qglGetObjectParameterivARB(program, GL_OBJECT_VALIDATE_STATUS_ARB, &validated);
	if(!validated)
	{
		GLSL_PrintInfoLog(program, qfalse);
		ri.Printf(PRINT_ALL, "\n");
		ri.Error(ERR_DROP, "shaders failed to validate");
	}
}
Example #6
0
static void GLSL_LinkProgram(GLhandleARB program)
{
	GLint           linked;

	qglLinkProgramARB(program);

	qglGetObjectParameterivARB(program, GL_OBJECT_LINK_STATUS_ARB, &linked);
	if(!linked)
	{
		GLSL_PrintInfoLog(program, qfalse);
		ri.Printf(PRINT_ALL, "\n");
		ri.Error(ERR_DROP, "shaders failed to link");
	}
}
Example #7
0
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;
}
Example #8
0
static void GLSL_ShowProgramUniforms(GLhandleARB program)
{
	int             i, count, size;
	GLenum			type;
	char            uniformName[1000];

	// query the number of active uniforms
	qglGetObjectParameterivARB(program, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &count);

	// Loop over each of the active uniforms, and set their value
	for(i = 0; i < count; i++)
	{
		qglGetActiveUniformARB(program, i, sizeof(uniformName), NULL, &size, &type, uniformName);

		ri.Printf(PRINT_DEVELOPER, "active uniform: '%s'\n", uniformName);
	}
}
Example #9
0
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);
	}
}
Example #10
0
qboolean R_Shader_StartLightPass( unsigned int lightIndex ) {
	GLint valid;
	R_ShaderLight *light = GetLightFromIndex( lightIndex );
	matrix4x4_t *worldToViewMatrix = &r_refdef.lightShader.worldToViewMatrix;
	vec3_t lightPosition, newcolor;
	float f;
	
	assert( light->active  == true );

	// setup cubemap texture generation
	if( gl_support_cubemaps ) {
		matrix4x4_t worldToLightMatrix;
		matrix4x4_t viewToWorldMatrix;
		matrix4x4_t viewToLightMatrix;

		// setup the cubemap
		qglSelectTextureARB( GL_TEXTURE1_ARB );
		glEnable( GL_TEXTURE_CUBE_MAP_ARB );
		glBindTexture( GL_TEXTURE_CUBE_MAP_ARB, GL_LoadCubeTexImage( light->cubemapname, false, true ) ); 
		qglSelectTextureARB( GL_TEXTURE0_ARB );
		
		// invert worldToViewMatrix
		worldToLightMatrix = GetWorldToLightMatrix( light );
		Matrix4x4_Invert_Simple( &viewToWorldMatrix, worldToViewMatrix );
		Matrix4x4_Concat( &viewToLightMatrix, &worldToLightMatrix, &viewToWorldMatrix );

		qglUniformMatrix4fvARB( r_refdef.lightShader.viewToLightMatrix, 1, true, (float *)&viewToLightMatrix.m );
	}

	Matrix4x4_Transform( worldToViewMatrix, light->origin, lightPosition );
	//Con_Printf( "Light distance to origin: %f (vs %f)\n", VectorDistance( light->origin, r_refdef.vieworg ), VectorLength( lightPosition ) );
    
	qglUniform3fvARB( r_refdef.lightShader.lightPosition, 1, lightPosition );
	f = (light->style >= 0 ? d_lightstylevalue[light->style] : 128) * (1.0f / 256.0f) * r_shadow_lightintensityscale.value;
	VectorScale(light->color, f, newcolor);
	qglUniform3fvARB( r_refdef.lightShader.lightColor, 1, newcolor );
	qglUniform1fARB( r_refdef.lightShader.lightMaxDistance, light->maxDistance );

	qglValidateProgramARB( r_refdef.lightShader.programObject );
	qglGetObjectParameterivARB( r_refdef.lightShader.programObject, GL_OBJECT_VALIDATE_STATUS_ARB, &valid );
	return valid == true;
}
Example #11
0
static void GLSL_PrintShaderSource(GLhandleARB object)
{
	char           *msg;
	static char     msgPart[1024];
	int             maxLength = 0;
	int             i;

	qglGetObjectParameterivARB(object, GL_OBJECT_SHADER_SOURCE_LENGTH_ARB, &maxLength);

	msg = ri.Malloc(maxLength);

	qglGetShaderSourceARB(object, maxLength, &maxLength, msg);

	for(i = 0; i < maxLength; i += 1024)
	{
		Q_strncpyz(msgPart, msg + i, sizeof(msgPart));
		ri.Printf(PRINT_ALL, "%s\n", msgPart);
	}

	ri.Free(msg);
}
Example #12
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;
}
Example #13
0
static void GLSL_ShowProgramUniforms(GLhandleARB program)
{
	int             i, count, size;
	GLenum			type;
	char            uniformName[1000];

	// install the executables in the program object as part of current state.
	qglUseProgramObjectARB(program);

	// check for GL Errors

	// query the number of active uniforms
	qglGetObjectParameterivARB(program, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &count);

	// Loop over each of the active uniforms, and set their value
	for(i = 0; i < count; i++)
	{
		qglGetActiveUniformARB(program, i, sizeof(uniformName), NULL, &size, &type, uniformName);

		ri.Printf(PRINT_DEVELOPER, "active uniform: '%s'\n", uniformName);
	}

	qglUseProgramObjectARB(0);
}