/*
=============
RB_GLSL_CreateDrawInteractions
=============
*/
static void RB_GLSL_CreateDrawInteractions( const drawSurf_t *surf ) {
	if ( !surf ) {
		return;
	}

	// perform setup here that will be constant for all interactions
	GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | backEnd.depthFunc );

	// bind the vertex and fragment program
	if ( backEnd.vLight->lightShader->IsAmbientLight() ) {
		qglUseProgramObjectARB( interactionAmbShader.program );
	} else {
		qglUseProgramObjectARB( interactionDirShader.program );
	}

	// enable the vertex arrays
	qglEnableVertexAttribArrayARB( 8 );
	qglEnableVertexAttribArrayARB( 9 );
	qglEnableVertexAttribArrayARB( 10 );
	qglEnableVertexAttribArrayARB( 11 );
	qglEnableClientState( GL_COLOR_ARRAY );

	for ( ; surf; surf = surf->nextOnLight ) {
		// perform setup here that will not change over multiple interaction passes

// ---> sikk - Custom Interaction Shaders: Local Parameters
		const float	*regs;
		regs = surf->shaderRegisters;
		for ( int i = 0; i < surf->material->GetNumInteractionParms(); i++ ) {
			float parm[ 4 ];
			parm[ 0 ] = regs[ surf->material->GetInteractionParm( i, 0 ) ];
			parm[ 1 ] = regs[ surf->material->GetInteractionParm( i, 1 ) ];
			parm[ 2 ] = regs[ surf->material->GetInteractionParm( i, 2 ) ];
			parm[ 3 ] = regs[ surf->material->GetInteractionParm( i, 3 ) ];
			if ( backEnd.vLight->lightShader->IsAmbientLight() ) {
				qglUniform4fvARB( interactionAmbShader.localParms[ i ], 1, parm );
			} else {
				qglUniform4fvARB( interactionDirShader.localParms[ i ], 1, parm );
			}
		}
// <--- sikk - Custom Interaction Shaders: Local Parameters

// ---> sikk - Specular Exponent Scale/Bias
		float parm[ 4 ];
		parm[ 0 ] = surf->material->GetSpecExp( 0 );
		parm[ 1 ] = surf->material->GetSpecExp( 1 );
		parm[ 2 ] = 0.0f;
		parm[ 3 ] = 0.0f;
		if ( backEnd.vLight->lightShader->IsAmbientLight() ) {
			qglUniform4fvARB( interactionAmbShader.specExp, 1, parm );
		} else {
			qglUniform4fvARB( interactionDirShader.specExp, 1, parm );
		}
// <--- sikk - Custom Interaction Shaders: Local Parameters

		// set the vertex pointers
		idDrawVert	*ac = (idDrawVert *)vertexCache.Position( surf->geo->ambientCache );
		qglColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( idDrawVert ), ac->color );
		qglVertexAttribPointerARB( 11, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->normal.ToFloatPtr() );
		qglVertexAttribPointerARB( 10, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[1].ToFloatPtr() );
		qglVertexAttribPointerARB( 9, 3, GL_FLOAT, false, sizeof( idDrawVert ), ac->tangents[0].ToFloatPtr() );
		qglVertexAttribPointerARB( 8, 2, GL_FLOAT, false, sizeof( idDrawVert ), ac->st.ToFloatPtr() );
		qglVertexPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ac->xyz.ToFloatPtr() );

		// set model matrix
		//if ( backEnd.vLight->lightShader->IsAmbientLight() ) {
		//	qglUniformMatrix4fvARB( interactionAmbShader.modelMatrix, 1, false, surf->space->modelMatrix );
		//} else {
		//	qglUniformMatrix4fvARB( interactionDirShader.modelMatrix, 1, false, surf->space->modelMatrix );
		//}

		// this may cause RB_GLSL_DrawInteraction to be executed multiple
		// times with different colors and images if the surface or light have multiple layers
		RB_CreateSingleDrawInteractions( surf, RB_GLSL_DrawInteraction );
	}

	qglDisableVertexAttribArrayARB( 8 );
	qglDisableVertexAttribArrayARB( 9 );
	qglDisableVertexAttribArrayARB( 10 );
	qglDisableVertexAttribArrayARB( 11 );
	qglDisableClientState( GL_COLOR_ARRAY );

	// disable features
// ---> sikk - Auxilary textures for interaction shaders
	// per-surface auxilary texture 0 - 9
	for ( int i = 15; i > 0; i-- ) {
		GL_SelectTextureNoClient( i );
		globalImages->BindNull();
	}
// <--- sikk - Auxilary textures for interaction shaders

	backEnd.glState.currenttmu = -1;
	GL_SelectTexture( 0 );

	qglUseProgramObjectARB( 0 );
}
/*
==================
RB_GLSL_DrawInteraction
==================
*/
static void RB_GLSL_DrawInteraction( const drawInteraction_t *din ) {
	// load all the shader parameters
	if ( din->ambientLight ) {
// ---> sikk - Included non-power-of-two/frag position conversion
		// screen power of two correction factor, assuming the copy to _currentRender
		// also copied an extra row and column for the bilerp
		float parm[ 4 ];
		int w = backEnd.viewDef->viewport.x2 - backEnd.viewDef->viewport.x1 + 1;
		int h = backEnd.viewDef->viewport.y2 - backEnd.viewDef->viewport.y1 + 1;
		parm[0] = (float)w / globalImages->currentRenderImage->uploadWidth;
		parm[1] = (float)h / globalImages->currentRenderImage->uploadHeight;
		parm[2] = parm[0] / w;	// sikk - added - one less fragment shader instruction
		parm[3] = parm[1] / h;	// sikk - added - one less fragment shader instruction
		qglUniform4fvARB( interactionAmbShader.nonPoT, 1, parm );

		// window coord to 0.0 to 1.0 conversion
		parm[0] = 1.0 / w;
		parm[1] = 1.0 / h;
		parm[2] = w;	// sikk - added - can be useful to have resolution size in shader
		parm[3] = h;	// sikk - added - can be useful to have resolution size in shader
		qglUniform4fvARB( interactionAmbShader.invRes, 1, parm );
// <--- sikk - Included non-power-of-two/frag position conversion

		qglUniform4fvARB( interactionAmbShader.localLightOrigin, 1, din->localLightOrigin.ToFloatPtr() );
		qglUniform4fvARB( interactionAmbShader.localViewOrigin, 1, din->localViewOrigin.ToFloatPtr() );
		qglUniform4fvARB( interactionAmbShader.lightProjectionS, 1, din->lightProjection[0].ToFloatPtr() );
		qglUniform4fvARB( interactionAmbShader.lightProjectionT, 1, din->lightProjection[1].ToFloatPtr() );
		qglUniform4fvARB( interactionAmbShader.lightProjectionQ, 1, din->lightProjection[2].ToFloatPtr() );
		qglUniform4fvARB( interactionAmbShader.lightFalloff, 1, din->lightProjection[3].ToFloatPtr() );
		qglUniform4fvARB( interactionAmbShader.bumpMatrixS, 1, din->bumpMatrix[0].ToFloatPtr() );
		qglUniform4fvARB( interactionAmbShader.bumpMatrixT, 1, din->bumpMatrix[1].ToFloatPtr() );
		qglUniform4fvARB( interactionAmbShader.diffuseMatrixS, 1, din->diffuseMatrix[0].ToFloatPtr() );
		qglUniform4fvARB( interactionAmbShader.diffuseMatrixT, 1, din->diffuseMatrix[1].ToFloatPtr() );
		qglUniform4fvARB( interactionAmbShader.specularMatrixS, 1, din->specularMatrix[0].ToFloatPtr() );
		qglUniform4fvARB( interactionAmbShader.specularMatrixT, 1, din->specularMatrix[1].ToFloatPtr() );

// ---> sikk - Include model matrix for to-world-space transformations
		const struct viewEntity_s *space = backEnd.currentSpace;
		qglUniformMatrix4fvARB( interactionAmbShader.modelMatrix, 1, 0, space->modelMatrix );
// <--- sikk - Include model matrix for to-world-space transformations

		static const float ignore[ 4 ]			= {  0.0, 1.0, 1.0, 1.0 };
		static const float modulate[ 4 ]		= {  1.0, 0.0, 1.0, 1.0 };
		static const float inv_modulate[ 4 ]	= { -1.0, 1.0, 1.0, 1.0 };
	
		switch ( din->vertexColor ) {
		case SVC_IGNORE:
			qglUniform4fvARB( interactionAmbShader.colorMAD, 1, ignore );
			break;
		case SVC_MODULATE:
			qglUniform4fvARB( interactionAmbShader.colorMAD, 1, modulate );
			break;
		case SVC_INVERSE_MODULATE:
			qglUniform4fvARB( interactionAmbShader.colorMAD, 1, inv_modulate );
			break;
		}

		// set the constant color
		qglUniform4fvARB( interactionAmbShader.diffuseColor, 1, din->diffuseColor.ToFloatPtr() );
		qglUniform4fvARB( interactionAmbShader.specularColor, 1, din->specularColor.ToFloatPtr() );
	} else {
// ---> sikk - Included non-power-of-two/frag position conversion
		// screen power of two correction factor, assuming the copy to _currentRender
		// also copied an extra row and column for the bilerp
		float parm[ 4 ];
		int w = backEnd.viewDef->viewport.x2 - backEnd.viewDef->viewport.x1 + 1;
		int h = backEnd.viewDef->viewport.y2 - backEnd.viewDef->viewport.y1 + 1;
		parm[0] = (float)w / globalImages->currentRenderImage->uploadWidth;
		parm[1] = (float)h / globalImages->currentRenderImage->uploadHeight;
		parm[2] = parm[0] / w;	// sikk - added - one less fragment shader instruction
		parm[3] = parm[1] / h;	// sikk - added - one less fragment shader instruction
		qglUniform4fvARB( interactionDirShader.nonPoT, 1, parm );

		// window coord to 0.0 to 1.0 conversion
		parm[0] = 1.0 / w;
		parm[1] = 1.0 / h;
		parm[2] = w;	// sikk - added - can be useful to have resolution size in shader
		parm[3] = h;	// sikk - added - can be useful to have resolution size in shader
		qglUniform4fvARB( interactionDirShader.invRes, 1, parm );
// <--- sikk - Included non-power-of-two/frag position conversion

		qglUniform4fvARB( interactionDirShader.localLightOrigin, 1, din->localLightOrigin.ToFloatPtr() );
		qglUniform4fvARB( interactionDirShader.localViewOrigin, 1, din->localViewOrigin.ToFloatPtr() );
		qglUniform4fvARB( interactionDirShader.lightProjectionS, 1, din->lightProjection[0].ToFloatPtr() );
		qglUniform4fvARB( interactionDirShader.lightProjectionT, 1, din->lightProjection[1].ToFloatPtr() );
		qglUniform4fvARB( interactionDirShader.lightProjectionQ, 1, din->lightProjection[2].ToFloatPtr() );
		qglUniform4fvARB( interactionDirShader.lightFalloff, 1, din->lightProjection[3].ToFloatPtr() );
		qglUniform4fvARB( interactionDirShader.bumpMatrixS, 1, din->bumpMatrix[0].ToFloatPtr() );
		qglUniform4fvARB( interactionDirShader.bumpMatrixT, 1, din->bumpMatrix[1].ToFloatPtr() );
		qglUniform4fvARB( interactionDirShader.diffuseMatrixS, 1, din->diffuseMatrix[0].ToFloatPtr() );
		qglUniform4fvARB( interactionDirShader.diffuseMatrixT, 1, din->diffuseMatrix[1].ToFloatPtr() );
		qglUniform4fvARB( interactionDirShader.specularMatrixS, 1, din->specularMatrix[0].ToFloatPtr() );
		qglUniform4fvARB( interactionDirShader.specularMatrixT, 1, din->specularMatrix[1].ToFloatPtr() );

// ---> sikk - Include model matrix for to-world-space transformations
		const struct viewEntity_s *space = backEnd.currentSpace;
		qglUniformMatrix4fvARB( interactionDirShader.modelMatrix, 1, 0, space->modelMatrix );
// <--- sikk - Include model matrix for to-world-space transformations

		if ( !backEnd.vLight->lightDef->parms.pointLight ) {	// 2D Light Shader (projected lights)
			qglUniform1iARB( interactionDirShader.falloffType, 2 );
			//qglUseProgramObjectARB( interactionDirShader.program );
			//qglUniform1iARB( interactionDirShader.u_lightProjectionTexture, 0 );
			//qglUseProgramObjectARB( 0 );
		} else {	// 3D Light Shader (point lights)
			if ( backEnd.vLight->lightDef->parms.parallel ) {	// shader specific for sun light (no attenuation)
				qglUniform1iARB( interactionDirShader.falloffType, 1 );
			} else {											// default quadratic attenuation
				qglUniform1iARB( interactionDirShader.falloffType, 0 );
			}
		}

		static const float ignore[ 4 ]			= {  0.0, 1.0, 1.0, 1.0 };
		static const float modulate[ 4 ]		= {  1.0, 0.0, 1.0, 1.0 };
		static const float inv_modulate[ 4 ]	= { -1.0, 1.0, 1.0, 1.0 };
	
		switch ( din->vertexColor ) {
		case SVC_IGNORE:
			qglUniform4fvARB( interactionDirShader.colorMAD, 1, ignore );
			break;
		case SVC_MODULATE:
			qglUniform4fvARB( interactionDirShader.colorMAD, 1, modulate );
			break;
		case SVC_INVERSE_MODULATE:
			qglUniform4fvARB( interactionDirShader.colorMAD, 1, inv_modulate );
			break;
		}
	
		// set the constant colors
		qglUniform4fvARB( interactionDirShader.diffuseColor, 1, din->diffuseColor.ToFloatPtr() );
		qglUniform4fvARB( interactionDirShader.specularColor, 1, din->specularColor.ToFloatPtr() );
	}

	// set the textures
	// texture 0 will be the light projection texture
	GL_SelectTextureNoClient( 0 );
	din->lightImage->Bind();

	if ( !din->ambientLight ) {
		GL_SelectTextureNoClient( 16 );
		din->lightImage->Bind();
	}

	// texture 1 will be the light falloff texture
	GL_SelectTextureNoClient( 1 );
	din->lightFalloffImage->Bind();

	// texture 1 will be the per-surface bump map
	GL_SelectTextureNoClient( 2 );
	din->bumpImage->Bind();

	// texture 2 is the per-surface diffuse map
	GL_SelectTextureNoClient( 3 );
	din->diffuseImage->Bind();

	// texture 3 is the per-surface specular map
	GL_SelectTextureNoClient( 4 );
	din->specularImage->Bind();

	// texture 4 is the ssao buffer
	GL_SelectTextureNoClient( 5 );
	globalImages->ssaoImage->Bind();

// ---> sikk - Auxilary textures for interaction shaders
	// per-surface auxilary texture 0 - 9
	for ( int i = 0; i < din->surf->material->GetNumInteractionImages(); i++ ) {
		GL_SelectTextureNoClient( i + 6 );
		din->surf->material->GetInteractionImage( i )->Bind();
	}
// <--- sikk - Auxilary textures for interaction shaders

	// draw it
	RB_DrawElementsWithCounters( din->surf->geo );
}
Ejemplo n.º 3
0
/*
==================
RB_GLSL_DrawInteraction
==================
*/
static void RB_GLSL_DrawInteraction( const drawInteraction_t *din ) {
	// load all the shader parameters
	if ( din->ambientLight ) {
		qglUniform4fvARB( ambientInteractionShader.localLightOrigin, 1, din->localLightOrigin.ToFloatPtr() );
		qglUniform4fvARB( ambientInteractionShader.lightProjectionS, 1, din->lightProjection[0].ToFloatPtr() );
		qglUniform4fvARB( ambientInteractionShader.lightProjectionT, 1, din->lightProjection[1].ToFloatPtr() );
		qglUniform4fvARB( ambientInteractionShader.lightProjectionQ, 1, din->lightProjection[2].ToFloatPtr() );
		qglUniform4fvARB( ambientInteractionShader.lightFalloff, 1, din->lightProjection[3].ToFloatPtr() );
		qglUniform4fvARB( ambientInteractionShader.bumpMatrixS, 1, din->bumpMatrix[0].ToFloatPtr() );
		qglUniform4fvARB( ambientInteractionShader.bumpMatrixT, 1, din->bumpMatrix[1].ToFloatPtr() );
		qglUniform4fvARB( ambientInteractionShader.diffuseMatrixS, 1, din->diffuseMatrix[0].ToFloatPtr() );
		qglUniform4fvARB( ambientInteractionShader.diffuseMatrixT, 1, din->diffuseMatrix[1].ToFloatPtr() );

		static const float zero[4] = { 0, 0, 0, 0 };
		static const float one[4] = { 1, 1, 1, 1 };
		static const float negOne[4] = { -1, -1, -1, -1 };

		switch ( din->vertexColor ) {
		case SVC_IGNORE:
			qglUniform4fARB( ambientInteractionShader.colorModulate, zero[0], zero[1], zero[2], zero[3] );
			qglUniform4fARB( ambientInteractionShader.colorAdd, one[0], one[1], one[2], one[3] );
			break;
		case SVC_MODULATE:
			qglUniform4fARB( ambientInteractionShader.colorModulate, one[0], one[1], one[2], one[3] );
			qglUniform4fARB( ambientInteractionShader.colorAdd, zero[0], zero[1], zero[2], zero[3] );
			break;
		case SVC_INVERSE_MODULATE:
			qglUniform4fARB( ambientInteractionShader.colorModulate, negOne[0], negOne[1], negOne[2], negOne[3] );
			qglUniform4fARB( ambientInteractionShader.colorAdd, one[0], one[1], one[2], one[3] );
			break;
		}

		// set the constant color
		qglUniform4fvARB( ambientInteractionShader.diffuseColor, 1, din->diffuseColor.ToFloatPtr() );
	} else {
		qglUniform4fvARB( interactionShader.localLightOrigin, 1, din->localLightOrigin.ToFloatPtr() );
		qglUniform4fvARB( interactionShader.localViewOrigin, 1, din->localViewOrigin.ToFloatPtr() );
		qglUniform4fvARB( interactionShader.lightProjectionS, 1, din->lightProjection[0].ToFloatPtr() );
		qglUniform4fvARB( interactionShader.lightProjectionT, 1, din->lightProjection[1].ToFloatPtr() );
		qglUniform4fvARB( interactionShader.lightProjectionQ, 1, din->lightProjection[2].ToFloatPtr() );
		qglUniform4fvARB( interactionShader.lightFalloff, 1, din->lightProjection[3].ToFloatPtr() );
		qglUniform4fvARB( interactionShader.bumpMatrixS, 1, din->bumpMatrix[0].ToFloatPtr() );
		qglUniform4fvARB( interactionShader.bumpMatrixT, 1, din->bumpMatrix[1].ToFloatPtr() );
		qglUniform4fvARB( interactionShader.diffuseMatrixS, 1, din->diffuseMatrix[0].ToFloatPtr() );
		qglUniform4fvARB( interactionShader.diffuseMatrixT, 1, din->diffuseMatrix[1].ToFloatPtr() );
		qglUniform4fvARB( interactionShader.specularMatrixS, 1, din->specularMatrix[0].ToFloatPtr() );
		qglUniform4fvARB( interactionShader.specularMatrixT, 1, din->specularMatrix[1].ToFloatPtr() );
	
		static const float zero[4] = { 0, 0, 0, 0 };
		static const float one[4] = { 1, 1, 1, 1 };
		static const float negOne[4] = { -1, -1, -1, -1 };
	
		switch ( din->vertexColor ) {
		case SVC_IGNORE:
			qglUniform4fARB( interactionShader.colorModulate, zero[0], zero[1], zero[2], zero[3] );
			qglUniform4fARB( interactionShader.colorAdd, one[0], one[1], one[2], one[3] );
			break;
		case SVC_MODULATE:
			qglUniform4fARB( interactionShader.colorModulate, one[0], one[1], one[2], one[3] );
			qglUniform4fARB( interactionShader.colorAdd, zero[0], zero[1], zero[2], zero[3] );
			break;
		case SVC_INVERSE_MODULATE:
			qglUniform4fARB( interactionShader.colorModulate, negOne[0], negOne[1], negOne[2], negOne[3] );
			qglUniform4fARB( interactionShader.colorAdd, one[0], one[1], one[2], one[3] );
			break;
		}
	
		// set the constant colors
		qglUniform4fvARB( interactionShader.diffuseColor, 1, din->diffuseColor.ToFloatPtr() );
		qglUniform4fvARB( interactionShader.specularColor, 1, din->specularColor.ToFloatPtr() );
	}

	// set the textures

	// texture 0 will be the per-surface bump map
	GL_SelectTextureNoClient( 0 );
	din->bumpImage->Bind();

	// texture 1 will be the light falloff texture
	GL_SelectTextureNoClient( 1 );
	din->lightFalloffImage->Bind();

	// texture 2 will be the light projection texture
	GL_SelectTextureNoClient( 2 );
	din->lightImage->Bind();

	// texture 3 is the per-surface diffuse map
	GL_SelectTextureNoClient( 3 );
	din->diffuseImage->Bind();

	if ( !din->ambientLight ) {
		// texture 4 is the per-surface specular map
		GL_SelectTextureNoClient( 4 );
		din->specularImage->Bind();
	}

	// draw it
	RB_DrawElementsWithCounters( din->surf->geo );
}