/*
==================
RB_NV20_DI_SpecularColorPass

==================
*/
static void RB_NV20_DI_SpecularColorPass(const drawInteraction_t *din)
{
	RB_LogComment("---------- RB_NV20_SpecularColorPass ----------\n");

	GL_State(GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | GLS_ALPHAMASK
	         | backEnd.depthFunc);

	// texture 0 is the normalization cube map for the half angle
#ifdef MACOS_X
	GL_SelectTexture(0);
	qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
#else
	GL_SelectTextureNoClient(0);
#endif
	globalImages->normalCubeMapImage->Bind();

	// texture 1 will be the per-surface bump map
#ifdef MACOS_X
	GL_SelectTexture(1);
	qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
#else
	GL_SelectTextureNoClient(1);
#endif
	din->bumpImage->Bind();

	// texture 2 will be the per-surface specular map
#ifdef MACOS_X
	GL_SelectTexture(2);
	qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
#else
	GL_SelectTextureNoClient(2);
#endif
	din->specularImage->Bind();

	// texture 3 will be the light projected texture
#ifdef MACOS_X
	GL_SelectTexture(3);
	qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
#else
	GL_SelectTextureNoClient(3);
#endif
	din->lightImage->Bind();

	// bind our "fragment program"
	RB_NV20_SpecularColorFragment();

	// override one parameter for inverted vertex color
	if (din->vertexColor == SVC_INVERSE_MODULATE) {
		qglCombinerInputNV(GL_COMBINER3_NV, GL_RGB, GL_VARIABLE_B_NV,
		                   GL_PRIMARY_COLOR_NV, GL_UNSIGNED_INVERT_NV, GL_RGB);
	}

	// draw it
	qglBindProgramARB(GL_VERTEX_PROGRAM_ARB, VPROG_NV20_SPECULAR_COLOR);
	RB_DrawElementsWithCounters(din->surf->geo);
}
/*
==================
RB_NV20_DI_DiffuseAndSpecularColorPass

==================
*/
static void RB_NV20_DI_DiffuseAndSpecularColorPass(const drawInteraction_t *din)
{
	RB_LogComment("---------- RB_NV20_DI_DiffuseAndSpecularColorPass ----------\n");

	GL_State(GLS_SRCBLEND_DST_ALPHA | GLS_DSTBLEND_ONE | GLS_DEPTHMASK | backEnd.depthFunc);

	// texture 0 is the normalization cube map for the half angle
// still bound from RB_NV_BumpAndLightPass
//	GL_SelectTextureNoClient( 0 );
//	GL_Bind( tr.normalCubeMapImage );

	// texture 1 is the per-surface bump map
// still bound from RB_NV_BumpAndLightPass
//	GL_SelectTextureNoClient( 1 );
//	GL_Bind( din->bumpImage );

	// texture 2 is the per-surface diffuse map
#ifdef MACOS_X
	GL_SelectTexture(2);
	qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
#else
	GL_SelectTextureNoClient(2);
#endif
	din->diffuseImage->Bind();

	// texture 3 is the per-surface specular map
#ifdef MACOS_X
	GL_SelectTexture(3);
	qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
#else
	GL_SelectTextureNoClient(3);
#endif
	din->specularImage->Bind();

	// bind our "fragment program"
	RB_NV20_DiffuseAndSpecularColorFragment();

	// draw it
	qglBindProgramARB(GL_VERTEX_PROGRAM_ARB, VPROG_NV20_DIFFUSE_AND_SPECULAR_COLOR);
	RB_DrawElementsWithCounters(din->surf->geo);
}
Beispiel #3
0
/*
==================
RB_ARB2_DrawInteraction
==================
*/
void	RB_ARB2_DrawInteraction( const drawInteraction_t *din ) {
	// load all the vertex program parameters
	qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_ORIGIN, din->localLightOrigin.ToFloatPtr() );
	qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_VIEW_ORIGIN, din->localViewOrigin.ToFloatPtr() );
	qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_S, din->lightProjection[0].ToFloatPtr() );
	qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_T, din->lightProjection[1].ToFloatPtr() );
	qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_PROJECT_Q, din->lightProjection[2].ToFloatPtr() );
	qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_LIGHT_FALLOFF_S, din->lightProjection[3].ToFloatPtr() );
	qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_BUMP_MATRIX_S, din->bumpMatrix[0].ToFloatPtr() );
	qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_BUMP_MATRIX_T, din->bumpMatrix[1].ToFloatPtr() );
	qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_DIFFUSE_MATRIX_S, din->diffuseMatrix[0].ToFloatPtr() );
	qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_DIFFUSE_MATRIX_T, din->diffuseMatrix[1].ToFloatPtr() );
	qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_SPECULAR_MATRIX_S, din->specularMatrix[0].ToFloatPtr() );
	qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_SPECULAR_MATRIX_T, din->specularMatrix[1].ToFloatPtr() );

	// testing fragment based normal mapping
	if ( r_testARBProgram.GetBool() ) {
		qglProgramEnvParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 2, din->localLightOrigin.ToFloatPtr() );
		qglProgramEnvParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 3, din->localViewOrigin.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:
		qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, zero );
		qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, one );
		break;
	case SVC_MODULATE:
		qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, one );
		qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, zero );
		break;
	case SVC_INVERSE_MODULATE:
		qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_MODULATE, negOne );
		qglProgramEnvParameter4fvARB( GL_VERTEX_PROGRAM_ARB, PP_COLOR_ADD, one );
		break;
	}

	// set the constant colors
	qglProgramEnvParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 0, din->diffuseColor.ToFloatPtr() );
	qglProgramEnvParameter4fvARB( GL_FRAGMENT_PROGRAM_ARB, 1, din->specularColor.ToFloatPtr() );

	// set the textures

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

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

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

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

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

	// draw it
	RB_DrawElementsWithCounters( din->surf->geo );
}
Beispiel #4
0
/*
=============
RB_ARB2_CreateDrawInteractions

=============
*/
void RB_ARB2_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 program
	if ( r_testARBProgram.GetBool() ) {
		qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_TEST );
		qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_TEST );
	} else {
		qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_INTERACTION );
		qglBindProgramARB( GL_FRAGMENT_PROGRAM_ARB, FPROG_INTERACTION );
	}

	qglEnable(GL_VERTEX_PROGRAM_ARB);
	qglEnable(GL_FRAGMENT_PROGRAM_ARB);

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

	// texture 0 is the normalization cube map for the vector towards the light
	GL_SelectTextureNoClient( 0 );
	if ( backEnd.vLight->lightShader->IsAmbientLight() ) {
		globalImages->ambientNormalMap->Bind();
	} else {
		globalImages->normalCubeMapImage->Bind();
	}

	// texture 6 is the specular lookup table
	GL_SelectTextureNoClient( 6 );
	if ( r_testARBProgram.GetBool() ) {
		globalImages->specular2DTableImage->Bind();	// variable specularity in alpha channel
	} else {
		globalImages->specularTableImage->Bind();
	}


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

		// 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() );

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

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

	// disable features
	GL_SelectTextureNoClient( 6 );
	globalImages->BindNull();

	GL_SelectTextureNoClient( 5 );
	globalImages->BindNull();

	GL_SelectTextureNoClient( 4 );
	globalImages->BindNull();

	GL_SelectTextureNoClient( 3 );
	globalImages->BindNull();

	GL_SelectTextureNoClient( 2 );
	globalImages->BindNull();

	GL_SelectTextureNoClient( 1 );
	globalImages->BindNull();

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

	qglDisable(GL_VERTEX_PROGRAM_ARB);
	qglDisable(GL_FRAGMENT_PROGRAM_ARB);
}
/*
==================
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 );
}
/*
=============
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 );
}
Beispiel #7
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 );
}
Beispiel #8
0
/*
=============
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() ) {
		if (ambientInteractionShader.program == -1)
			qglUseProgramObjectARB( 0 );
		else
			qglUseProgramObjectARB( ambientInteractionShader.program );
	} else {
		if (interactionShader.program == -1)
			qglUseProgramObjectARB( 0 );
		else
			qglUseProgramObjectARB( interactionShader.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

		// 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( ambientInteractionShader.modelMatrix, 1, false, surf->space->modelMatrix );
		} else {
			qglUniformMatrix4fvARB( interactionShader.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
	GL_SelectTextureNoClient( 4 );
	globalImages->BindNull();

	GL_SelectTextureNoClient( 3 );
	globalImages->BindNull();

	GL_SelectTextureNoClient( 2 );
	globalImages->BindNull();

	GL_SelectTextureNoClient( 1 );
	globalImages->BindNull();

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

	qglUseProgramObjectARB( 0 );
}
/*
=============
RB_NV20_CreateDrawInteractions

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

	qglEnable(GL_VERTEX_PROGRAM_ARB);
	qglEnable(GL_REGISTER_COMBINERS_NV);

#ifdef MACOS_X
	GL_SelectTexture(0);
	qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
#else
	qglDisableClientState(GL_TEXTURE_COORD_ARRAY);

	qglEnableVertexAttribArrayARB(8);
	qglEnableVertexAttribArrayARB(9);
	qglEnableVertexAttribArrayARB(10);
	qglEnableVertexAttribArrayARB(11);
#endif

	for (; surf ; surf=surf->nextOnLight) {
		// set the vertex pointers
		idDrawVert	*ac = (idDrawVert *)vertexCache.Position(surf->geo->ambientCache);
		qglColorPointer(4, GL_UNSIGNED_BYTE, sizeof(idDrawVert), ac->color);
#ifdef MACOS_X
		GL_SelectTexture(0);
		qglTexCoordPointer(2, GL_FLOAT, sizeof(idDrawVert), ac->st.ToFloatPtr());
		GL_SelectTexture(1);
		qglTexCoordPointer(3, GL_FLOAT, sizeof(idDrawVert), ac->tangents[0].ToFloatPtr());
		GL_SelectTexture(2);
		qglTexCoordPointer(3, GL_FLOAT, sizeof(idDrawVert), ac->tangents[1].ToFloatPtr());
		GL_SelectTexture(3);
		qglTexCoordPointer(3, GL_FLOAT, sizeof(idDrawVert), ac->normal.ToFloatPtr());
		GL_SelectTexture(0);
#else
		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());
#endif
		qglVertexPointer(3, GL_FLOAT, sizeof(idDrawVert), ac->xyz.ToFloatPtr());

		RB_CreateSingleDrawInteractions(surf, RB_NV20_DrawInteraction);
	}

#ifndef MACOS_X
	qglDisableVertexAttribArrayARB(8);
	qglDisableVertexAttribArrayARB(9);
	qglDisableVertexAttribArrayARB(10);
	qglDisableVertexAttribArrayARB(11);
#endif

	// disable features
#ifdef MACOS_X
	GL_SelectTexture(3);
	globalImages->BindNull();
	qglDisableClientState(GL_TEXTURE_COORD_ARRAY);

	GL_SelectTexture(2);
	globalImages->BindNull();
	qglDisableClientState(GL_TEXTURE_COORD_ARRAY);

	GL_SelectTexture(1);
	globalImages->BindNull();
	qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
#else
	GL_SelectTextureNoClient(3);
	globalImages->BindNull();

	GL_SelectTextureNoClient(2);
	globalImages->BindNull();

	GL_SelectTextureNoClient(1);
	globalImages->BindNull();
#endif

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

	qglEnableClientState(GL_TEXTURE_COORD_ARRAY);

	qglDisable(GL_VERTEX_PROGRAM_ARB);
	qglDisable(GL_REGISTER_COMBINERS_NV);
}
/*
==================
RB_NV20_DI_BumpAndLightPass

We are going to write alpha as light falloff * ( bump dot light ) * lightProjection
If the light isn't a monoLightShader, the lightProjection will be skipped, because
it will have to be done on an itterated basis
==================
*/
static void RB_NV20_DI_BumpAndLightPass(const drawInteraction_t *din, bool monoLightShader)
{
	RB_LogComment("---------- RB_NV_BumpAndLightPass ----------\n");

	GL_State(GLS_COLORMASK | GLS_DEPTHMASK | backEnd.depthFunc);

	// texture 0 is the normalization cube map
	// GL_TEXTURE0_ARB will be the normalized vector
	// towards the light source
#ifdef MACOS_X
	GL_SelectTexture(0);
	qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
#else
	GL_SelectTextureNoClient(0);
#endif

	if (din->ambientLight) {
		globalImages->ambientNormalMap->Bind();
	} else {
		globalImages->normalCubeMapImage->Bind();
	}

	// texture 1 will be the per-surface bump map
#ifdef MACOS_X
	GL_SelectTexture(1);
	qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
#else
	GL_SelectTextureNoClient(1);
#endif
	din->bumpImage->Bind();

	// texture 2 will be the light falloff texture
#ifdef MACOS_X
	GL_SelectTexture(2);
	qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
#else
	GL_SelectTextureNoClient(2);
#endif
	din->lightFalloffImage->Bind();

	// texture 3 will be the light projection texture
#ifdef MACOS_X
	GL_SelectTexture(3);
	qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
#else
	GL_SelectTextureNoClient(3);
#endif

	if (monoLightShader) {
		din->lightImage->Bind();
	} else {
		// if the projected texture is multi-colored, we
		// will need to do it in subsequent passes
		globalImages->whiteImage->Bind();
	}

	// bind our "fragment program"
	RB_NV20_BumpAndLightFragment();

	// draw it
	qglBindProgramARB(GL_VERTEX_PROGRAM_ARB, VPROG_NV20_BUMP_AND_LIGHT);
	RB_DrawElementsWithCounters(din->surf->geo);
}