Пример #1
0
void R_ProgramParameter1i (const char* name, GLint value)
{
	r_progvar_t* v;

	if (!(v = R_ProgramVariable(GL_UNIFORM, name)))
		return;

	qglUniform1i(v->location, value);
}
Пример #2
0
/*
 * R_ProgramParameter1i
 */
void R_ProgramParameter1i(r_uniform1i_t *variable, GLint value) {

	if (!variable || variable->location == -1) {
		Com_Warn("NULL or invalid variable\n");
		return;
	}

	if (variable->value.i == value)
		return;

	qglUniform1i(variable->location, value);
	variable->value.i = value;

	R_GetError(variable->name);
}
Пример #3
0
/*
================================================================================================
idRenderProgManager::LoadGLSLProgram
================================================================================================
*/
void idRenderProgManager::LoadGLSLProgram( const int programIndex, const int vertexShaderIndex, const int fragmentShaderIndex ) {
	glslProgram_t & prog = glslPrograms[programIndex];

	if ( prog.progId != INVALID_PROGID ) {
		return; // Already loaded
	}

	GLuint vertexProgID = ( vertexShaderIndex != -1 ) ? vertexShaders[ vertexShaderIndex ].progId : INVALID_PROGID;
	GLuint fragmentProgID = ( fragmentShaderIndex != -1 ) ? fragmentShaders[ fragmentShaderIndex ].progId : INVALID_PROGID;

	const GLuint program = qglCreateProgram();
	if ( program ) {

		if ( vertexProgID != INVALID_PROGID ) {
			qglAttachShader( program, vertexProgID );
		}

		if ( fragmentProgID != INVALID_PROGID ) {
			qglAttachShader( program, fragmentProgID );
		}

		// bind vertex attribute locations
		for ( int i = 0; attribsPC[i].glsl != NULL; i++ ) {
			if ( ( attribsPC[i].flags & AT_VS_IN ) != 0 ) {
				qglBindAttribLocation( program, attribsPC[i].bind, attribsPC[i].glsl );
			}
		}

		qglLinkProgram( program );

		int infologLength = 0;
		qglGetProgramiv( program, GL_INFO_LOG_LENGTH, &infologLength );
		if ( infologLength > 1 ) {
			char * infoLog = (char *)malloc( infologLength );
			int charsWritten = 0;
			qglGetProgramInfoLog( program, infologLength, &charsWritten, infoLog );

			// catch the strings the ATI and Intel drivers output on success
			if ( strstr( infoLog, "Vertex shader(s) linked, fragment shader(s) linked." ) != NULL || strstr( infoLog, "No errors." ) != NULL ) {
				//idLib::Printf( "render prog %s from %s linked\n", GetName(), GetFileName() );
			} else {
				idLib::Printf( "While linking GLSL program %d with vertexShader %s and fragmentShader %s\n", 
					programIndex, 
					( vertexShaderIndex >= 0 ) ? vertexShaders[vertexShaderIndex].name.c_str() : "<Invalid>", 
					( fragmentShaderIndex >= 0 ) ? fragmentShaders[ fragmentShaderIndex ].name.c_str() : "<Invalid>" );
				idLib::Printf( "%s\n", infoLog );
			}

			free( infoLog );
		}
	}

	int linked = GL_FALSE;
	qglGetProgramiv( program, GL_LINK_STATUS, &linked );
	if ( linked == GL_FALSE ) {
		qglDeleteProgram( program );
		idLib::Error( "While linking GLSL program %d with vertexShader %s and fragmentShader %s\n", 
			programIndex, 
			( vertexShaderIndex >= 0 ) ? vertexShaders[vertexShaderIndex].name.c_str() : "<Invalid>", 
			( fragmentShaderIndex >= 0 ) ? fragmentShaders[ fragmentShaderIndex ].name.c_str() : "<Invalid>" );
		return;
	}

	if ( r_useUniformArrays.GetBool() ) {
		prog.vertexUniformArray = qglGetUniformLocation( program, VERTEX_UNIFORM_ARRAY_NAME );
		prog.fragmentUniformArray = qglGetUniformLocation( program, FRAGMENT_UNIFORM_ARRAY_NAME );

		assert( prog.vertexUniformArray != -1 || vertexShaderIndex < 0 || vertexShaders[vertexShaderIndex].uniforms.Num() == 0 );
		assert( prog.fragmentUniformArray != -1 || fragmentShaderIndex < 0 || fragmentShaders[fragmentShaderIndex].uniforms.Num() == 0 );
	} else {
		// store the uniform locations after we have linked the GLSL program
		prog.uniformLocations.Clear();
		for ( int i = 0; i < RENDERPARM_TOTAL; i++ ) {
			const char * parmName = GetGLSLParmName( i );
			GLint loc = qglGetUniformLocation( program, parmName );
			if ( loc != -1 ) {
				glslUniformLocation_t uniformLocation;
				uniformLocation.parmIndex = i;
				uniformLocation.uniformIndex = loc;
				prog.uniformLocations.Append( uniformLocation );
			}
		}

		// store the USER uniform locations
		for ( int i = 0; i < MAX_GLSL_USER_PARMS; i++ ) {
			const char * parmName = GetGLSLParmName( RENDERPARM_USER + i );
			GLint loc = qglGetUniformLocation( program, parmName );
			if ( loc != -1 ) {
				glslUniformLocation_t uniformLocation;
				uniformLocation.parmIndex = RENDERPARM_USER + i;
				uniformLocation.uniformIndex = loc;
				prog.uniformLocations.Append( uniformLocation );
			}
		}

		// sort the uniforms based on index
		prog.uniformLocations.SortWithTemplate( idSort_QuickUniforms() );
	}

	// get the uniform buffer binding for skinning joint matrices
	GLint blockIndex = qglGetUniformBlockIndex( program, "matrices_ubo" );
	if ( blockIndex != -1 ) {
		qglUniformBlockBinding( program, blockIndex, 0 );
	}

	// set the texture unit locations once for the render program. We only need to do this once since we only link the program once
	qglUseProgram( program );
	for ( int i = 0; i < MAX_PROG_TEXTURE_PARMS; ++i ) {
		GLint loc = qglGetUniformLocation( program, va( "samp%d", i ) );
		if ( loc != -1 ) {
			qglUniform1i( loc, i );
		}
	}

	idStr programName = vertexShaders[ vertexShaderIndex ].name;
	programName.StripFileExtension();
	prog.name = programName;
	prog.progId = program;
	prog.fragmentShaderIndex = fragmentShaderIndex;
	prog.vertexShaderIndex = vertexShaderIndex;
}
Пример #4
0
GLvoid APIENTRY GLDSA_ProgramUniform1iEXT(GLuint program, GLint location, GLint v0)
{
	GL_UseProgram(program);
	qglUniform1i(location, v0);
}