示例#1
0
/*
* R_RenderMeshGLSL_Distortion
*/
static void R_RenderMeshGLSL_Distortion( r_glslfeat_t programFeatures )
{
	int i, last_slot;
	unsigned last_framenum;
	int state, tcgen;
	int width = 1, height = 1;
	int program, object;
	mat4x4_t unused;
	cplane_t plane;
	const char *key;
	shaderpass_t *pass = r_back.accumPasses[0];
	image_t *portaltexture[2];
	qboolean frontPlane;

	PlaneFromPoints( r_back.r_triangle0Copy, &plane );
	plane.dist += DotProduct( ri.currententity->origin, plane.normal );
	key = R_PortalKeyForPlane( &plane );
	last_framenum = last_slot = 0;

	for( i = 0; i < 2; i++ )
	{
		int slot;

		portaltexture[i] = NULL;

		slot = R_FindPortalTextureSlot( key, i+1 );
		if( slot )
			portaltexture[i] = r_portaltextures[slot-1];

		if( portaltexture[i] == NULL )
		{
			portaltexture[i] = r_blacktexture;
		}
		else
		{
			width = portaltexture[i]->upload_width;
			height = portaltexture[i]->upload_height;
		}

		// find the most recently updated texture
		if( portaltexture[i]->framenum > last_framenum )
		{
			last_slot = i;
			last_framenum = i;
		}
	}

	// if textures were not updated sequentially, use the most recent one
	// and reset the remaining to black
	if( portaltexture[0]->framenum+1 != portaltexture[1]->framenum )
		portaltexture[(last_slot+1)&1] = r_blacktexture;

	if( pass->anim_frames[0] != r_blankbumptexture )
		programFeatures |= GLSL_DISTORTION_APPLY_DUDV;
	if( ri.params & RP_CLIPPLANE )
		programFeatures |= GLSL_COMMON_APPLY_CLIPPING;
	if( pass->flags & SHADERPASS_GRAYSCALE )
		programFeatures |= GLSL_COMMON_APPLY_GRAYSCALE;
	if( portaltexture[0] != r_blacktexture )
		programFeatures |= GLSL_DISTORTION_APPLY_REFLECTION;
	if( portaltexture[1] != r_blacktexture )
		programFeatures |= GLSL_DISTORTION_APPLY_REFRACTION;

	frontPlane = (PlaneDiff( ri.viewOrigin, &ri.portalPlane ) > 0 ? qtrue : qfalse);

	if( frontPlane )
	{
		if( pass->alphagen.type != ALPHA_GEN_IDENTITY )
			programFeatures |= GLSL_DISTORTION_APPLY_DISTORTION_ALPHA;
	}

	tcgen = pass->tcgen;                // store the original tcgen

	R_BindShaderpass( pass, pass->anim_frames[0], 0, NULL );  // dudvmap

	// calculate the fragment color
	R_ModifyColor( pass, programFeatures & GLSL_DISTORTION_APPLY_DISTORTION_ALPHA ? qtrue : qfalse, qfalse );

	GL_TexEnv( GL_MODULATE );

	// set shaderpass state (blending, depthwrite, etc)
	state = r_back.currentShaderState | ( pass->flags & r_back.currentShaderPassMask ) | GLSTATE_BLEND_MTEX;
	GL_SetState( state );

	if( pass->anim_frames[1] )
	{	// eyeDot
		programFeatures |= GLSL_DISTORTION_APPLY_EYEDOT;

		pass->tcgen = TC_GEN_SVECTORS;
		GL_Bind( 1, pass->anim_frames[1] ); // normalmap
		GL_SetTexCoordArrayMode( GL_TEXTURE_COORD_ARRAY );
		R_VertexTCBase( pass, 1, unused, NULL );
	}

	GL_Bind( 2, portaltexture[0] );            // reflection
	GL_Bind( 3, portaltexture[1] );           // refraction

	pass->tcgen = tcgen;    // restore original tcgen

	// update uniforms
	program = R_RegisterGLSLProgram( pass->program_type, pass->program, NULL, NULL, NULL, 0, programFeatures );
	object = R_GetProgramObject( program );
	if( object )
	{
		qglUseProgramObjectARB( object );

		R_UpdateProgramUniforms( program, ri.viewOrigin, vec3_origin, vec3_origin, NULL, NULL, NULL,
			frontPlane, width, height, 0, 0, 0, 
			colorArrayCopy[0], r_back.overBrightBits, r_back.currentShaderTime, r_back.entityColor );

		R_FlushArrays();

		qglUseProgramObjectARB( 0 );
	}
}
示例#2
0
void GLSL_InitGPUShaders(void)
{
	int             startTime, endTime;
	int i;
	char extradefines[1024];
	int attribs;
	int numGenShaders = 0, numLightShaders = 0, numEtcShaders = 0;

	ri.Printf(PRINT_ALL, "------- GLSL_InitGPUShaders -------\n");

	R_IssuePendingRenderCommands();

	startTime = ri.Milliseconds();

	for (i = 0; i < GENERICDEF_COUNT; i++)
	{
		attribs = ATTR_POSITION | ATTR_TEXCOORD | ATTR_LIGHTCOORD | ATTR_NORMAL | ATTR_COLOR;
		extradefines[0] = '\0';

		if (i & GENERICDEF_USE_DEFORM_VERTEXES)
			Q_strcat(extradefines, 1024, "#define USE_DEFORM_VERTEXES\n");

		if (i & GENERICDEF_USE_TCGEN_AND_TCMOD)
		{
			Q_strcat(extradefines, 1024, "#define USE_TCGEN\n");
			Q_strcat(extradefines, 1024, "#define USE_TCMOD\n");
		}

		if (i & GENERICDEF_USE_VERTEX_ANIMATION)
		{
			Q_strcat(extradefines, 1024, "#define USE_VERTEX_ANIMATION\n");
			attribs |= ATTR_POSITION2 | ATTR_NORMAL2;
		}

		if (i & GENERICDEF_USE_FOG)
			Q_strcat(extradefines, 1024, "#define USE_FOG\n");

		if (i & GENERICDEF_USE_RGBAGEN)
			Q_strcat(extradefines, 1024, "#define USE_RGBAGEN\n");

		if (!GLSL_InitGPUShader(&tr.genericShader[i], "generic", attribs, qtrue, extradefines, qtrue, fallbackShader_generic_vp, fallbackShader_generic_fp))
		{
			ri.Error(ERR_FATAL, "Could not load generic shader!");
		}

		GLSL_InitUniforms(&tr.genericShader[i]);

		qglUseProgramObjectARB(tr.genericShader[i].program);
		GLSL_SetUniformInt(&tr.genericShader[i], UNIFORM_DIFFUSEMAP, TB_DIFFUSEMAP);
		GLSL_SetUniformInt(&tr.genericShader[i], UNIFORM_LIGHTMAP,   TB_LIGHTMAP);
		qglUseProgramObjectARB(0);

		GLSL_FinishGPUShader(&tr.genericShader[i]);

		numGenShaders++;
	}


	attribs = ATTR_POSITION | ATTR_TEXCOORD;

	if (!GLSL_InitGPUShader(&tr.textureColorShader, "texturecolor", attribs, qtrue, NULL, qfalse, fallbackShader_texturecolor_vp, fallbackShader_texturecolor_fp))
	{
		ri.Error(ERR_FATAL, "Could not load texturecolor shader!");
	}

	GLSL_InitUniforms(&tr.textureColorShader);

	qglUseProgramObjectARB(tr.textureColorShader.program);
	GLSL_SetUniformInt(&tr.textureColorShader, UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP);
	qglUseProgramObjectARB(0);

	GLSL_FinishGPUShader(&tr.textureColorShader);

	numEtcShaders++;

	for (i = 0; i < FOGDEF_COUNT; i++)
	{
		attribs = ATTR_POSITION | ATTR_POSITION2 | ATTR_NORMAL | ATTR_NORMAL2 | ATTR_TEXCOORD;
		extradefines[0] = '\0';

		if (i & FOGDEF_USE_DEFORM_VERTEXES)
			Q_strcat(extradefines, 1024, "#define USE_DEFORM_VERTEXES\n");

		if (i & FOGDEF_USE_VERTEX_ANIMATION)
			Q_strcat(extradefines, 1024, "#define USE_VERTEX_ANIMATION\n");

		if (!GLSL_InitGPUShader(&tr.fogShader[i], "fogpass", attribs, qtrue, extradefines, qtrue, fallbackShader_fogpass_vp, fallbackShader_fogpass_fp))
		{
			ri.Error(ERR_FATAL, "Could not load fogpass shader!");
		}

		GLSL_InitUniforms(&tr.fogShader[i]);
		GLSL_FinishGPUShader(&tr.fogShader[i]);

		numEtcShaders++;
	}


	for (i = 0; i < DLIGHTDEF_COUNT; i++)
	{
		attribs = ATTR_POSITION | ATTR_NORMAL | ATTR_TEXCOORD;
		extradefines[0] = '\0';

		if (i & DLIGHTDEF_USE_DEFORM_VERTEXES)
		{
			Q_strcat(extradefines, 1024, "#define USE_DEFORM_VERTEXES\n");
		}

		if (!GLSL_InitGPUShader(&tr.dlightShader[i], "dlight", attribs, qtrue, extradefines, qtrue, fallbackShader_dlight_vp, fallbackShader_dlight_fp))
		{
			ri.Error(ERR_FATAL, "Could not load dlight shader!");
		}

		GLSL_InitUniforms(&tr.dlightShader[i]);

		qglUseProgramObjectARB(tr.dlightShader[i].program);
		GLSL_SetUniformInt(&tr.dlightShader[i], UNIFORM_DIFFUSEMAP, TB_DIFFUSEMAP);
		qglUseProgramObjectARB(0);

		GLSL_FinishGPUShader(&tr.dlightShader[i]);

		numEtcShaders++;
	}


	for (i = 0; i < LIGHTDEF_COUNT; i++)
	{
		int lightType = i & LIGHTDEF_LIGHTTYPE_MASK;
		qboolean fastLight = !(r_normalMapping->integer || r_specularMapping->integer);

		// skip impossible combos
		if ((i & LIGHTDEF_USE_PARALLAXMAP) && !r_parallaxMapping->integer)
			continue;

		if (!lightType && (i & LIGHTDEF_USE_PARALLAXMAP))
			continue;

		if (!lightType && (i & LIGHTDEF_USE_SHADOWMAP))
			continue;

		attribs = ATTR_POSITION | ATTR_TEXCOORD | ATTR_COLOR | ATTR_NORMAL;

		extradefines[0] = '\0';

		if (r_deluxeSpecular->value > 0.000001f)
			Q_strcat(extradefines, 1024, va("#define r_deluxeSpecular %f\n", r_deluxeSpecular->value));

		if (r_specularIsMetallic->value)
			Q_strcat(extradefines, 1024, "#define SPECULAR_IS_METALLIC\n");

		if (r_dlightMode->integer >= 2)
			Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n");

		if (1)
			Q_strcat(extradefines, 1024, "#define SWIZZLE_NORMALMAP\n");

		if (r_hdr->integer && !glRefConfig.floatLightmap)
			Q_strcat(extradefines, 1024, "#define RGBM_LIGHTMAP\n");

		if (lightType)
		{
			Q_strcat(extradefines, 1024, "#define USE_LIGHT\n");

			if (fastLight)
				Q_strcat(extradefines, 1024, "#define USE_FAST_LIGHT\n");

			switch (lightType)
			{
				case LIGHTDEF_USE_LIGHTMAP:
					Q_strcat(extradefines, 1024, "#define USE_LIGHTMAP\n");
					if (r_deluxeMapping->integer && !fastLight)
						Q_strcat(extradefines, 1024, "#define USE_DELUXEMAP\n");
					attribs |= ATTR_LIGHTCOORD | ATTR_LIGHTDIRECTION;
					break;
				case LIGHTDEF_USE_LIGHT_VECTOR:
					Q_strcat(extradefines, 1024, "#define USE_LIGHT_VECTOR\n");
					break;
				case LIGHTDEF_USE_LIGHT_VERTEX:
					Q_strcat(extradefines, 1024, "#define USE_LIGHT_VERTEX\n");
					attribs |= ATTR_LIGHTDIRECTION;
					break;
				default:
					break;
			}

			if (r_normalMapping->integer)
			{
				Q_strcat(extradefines, 1024, "#define USE_NORMALMAP\n");

				if (r_normalMapping->integer == 2)
					Q_strcat(extradefines, 1024, "#define USE_OREN_NAYAR\n");

				if (r_normalMapping->integer == 3)
					Q_strcat(extradefines, 1024, "#define USE_TRIACE_OREN_NAYAR\n");

#ifdef USE_VERT_TANGENT_SPACE
				Q_strcat(extradefines, 1024, "#define USE_VERT_TANGENT_SPACE\n");
				attribs |= ATTR_TANGENT;
#endif

				if ((i & LIGHTDEF_USE_PARALLAXMAP) && !(i & LIGHTDEF_ENTITY) && r_parallaxMapping->integer)
				{
					Q_strcat(extradefines, 1024, "#define USE_PARALLAXMAP\n");
					if (r_parallaxMapping->integer > 1)
						Q_strcat(extradefines, 1024, "#define USE_RELIEFMAP\n");
				}
			}

			if (r_specularMapping->integer)
			{
				Q_strcat(extradefines, 1024, "#define USE_SPECULARMAP\n");

				switch (r_specularMapping->integer)
				{
					case 1:
					default:
						Q_strcat(extradefines, 1024, "#define USE_BLINN\n");
						break;

					case 2:
						Q_strcat(extradefines, 1024, "#define USE_BLINN_FRESNEL\n");
						break;

					case 3:
						Q_strcat(extradefines, 1024, "#define USE_MCAULEY\n");
						break;

					case 4:
						Q_strcat(extradefines, 1024, "#define USE_GOTANDA\n");
						break;

					case 5:
						Q_strcat(extradefines, 1024, "#define USE_LAZAROV\n");
						break;
				}
			}

			if (r_cubeMapping->integer)
				Q_strcat(extradefines, 1024, "#define USE_CUBEMAP\n");
		}

		if (i & LIGHTDEF_USE_SHADOWMAP)
		{
			Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n");

			if (r_sunlightMode->integer == 1)
				Q_strcat(extradefines, 1024, "#define SHADOWMAP_MODULATE\n");
			else if (r_sunlightMode->integer == 2)
				Q_strcat(extradefines, 1024, "#define USE_PRIMARY_LIGHT\n");
		}

		if (i & LIGHTDEF_USE_TCGEN_AND_TCMOD)
		{
			Q_strcat(extradefines, 1024, "#define USE_TCGEN\n");
			Q_strcat(extradefines, 1024, "#define USE_TCMOD\n");
		}

		if (i & LIGHTDEF_ENTITY)
		{
			Q_strcat(extradefines, 1024, "#define USE_VERTEX_ANIMATION\n#define USE_MODELMATRIX\n");
			attribs |= ATTR_POSITION2 | ATTR_NORMAL2;

#ifdef USE_VERT_TANGENT_SPACE
			if (r_normalMapping->integer)
			{
				attribs |= ATTR_TANGENT2;
			}
#endif
		}

		if (!GLSL_InitGPUShader(&tr.lightallShader[i], "lightall", attribs, qtrue, extradefines, qtrue, fallbackShader_lightall_vp, fallbackShader_lightall_fp))
		{
			ri.Error(ERR_FATAL, "Could not load lightall shader!");
		}

		GLSL_InitUniforms(&tr.lightallShader[i]);

		qglUseProgramObjectARB(tr.lightallShader[i].program);
		GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_DIFFUSEMAP,  TB_DIFFUSEMAP);
		GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_LIGHTMAP,    TB_LIGHTMAP);
		GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_NORMALMAP,   TB_NORMALMAP);
		GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_DELUXEMAP,   TB_DELUXEMAP);
		GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_SPECULARMAP, TB_SPECULARMAP);
		GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_SHADOWMAP,   TB_SHADOWMAP);
		GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_CUBEMAP,     TB_CUBEMAP);
		qglUseProgramObjectARB(0);

		GLSL_FinishGPUShader(&tr.lightallShader[i]);

		numLightShaders++;
	}

	attribs = ATTR_POSITION | ATTR_POSITION2 | ATTR_NORMAL | ATTR_NORMAL2 | ATTR_TEXCOORD;

	extradefines[0] = '\0';

	if (!GLSL_InitGPUShader(&tr.shadowmapShader, "shadowfill", attribs, qtrue, extradefines, qtrue, fallbackShader_shadowfill_vp, fallbackShader_shadowfill_fp))
	{
		ri.Error(ERR_FATAL, "Could not load shadowfill shader!");
	}

	GLSL_InitUniforms(&tr.shadowmapShader);
	GLSL_FinishGPUShader(&tr.shadowmapShader);

	numEtcShaders++;

	attribs = ATTR_POSITION | ATTR_NORMAL;
	extradefines[0] = '\0';

#ifndef EMSCRIPTEN
	Q_strcat(extradefines, 1024, "#define USE_PCF\n#define USE_DISCARD\n");

	if (!GLSL_InitGPUShader(&tr.pshadowShader, "pshadow", attribs, qtrue, extradefines, qtrue, fallbackShader_pshadow_vp, fallbackShader_pshadow_fp))
	{
		ri.Error(ERR_FATAL, "Could not load pshadow shader!");
	}

	GLSL_InitUniforms(&tr.pshadowShader);

	qglUseProgramObjectARB(tr.pshadowShader.program);
	GLSL_SetUniformInt(&tr.pshadowShader, UNIFORM_SHADOWMAP, TB_DIFFUSEMAP);
	qglUseProgramObjectARB(0);

	GLSL_FinishGPUShader(&tr.pshadowShader);

	numEtcShaders++;


	attribs = ATTR_POSITION | ATTR_TEXCOORD;
	extradefines[0] = '\0';

	if (!GLSL_InitGPUShader(&tr.down4xShader, "down4x", attribs, qtrue, extradefines, qtrue, fallbackShader_down4x_vp, fallbackShader_down4x_fp))
	{
		ri.Error(ERR_FATAL, "Could not load down4x shader!");
	}

	GLSL_InitUniforms(&tr.down4xShader);

	qglUseProgramObjectARB(tr.down4xShader.program);
	GLSL_SetUniformInt(&tr.down4xShader, UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP);
	qglUseProgramObjectARB(0);

	GLSL_FinishGPUShader(&tr.down4xShader);

	numEtcShaders++;


	attribs = ATTR_POSITION | ATTR_TEXCOORD;
	extradefines[0] = '\0';

	if (!GLSL_InitGPUShader(&tr.bokehShader, "bokeh", attribs, qtrue, extradefines, qtrue, fallbackShader_bokeh_vp, fallbackShader_bokeh_fp))
	{
		ri.Error(ERR_FATAL, "Could not load bokeh shader!");
	}

	GLSL_InitUniforms(&tr.bokehShader);

	qglUseProgramObjectARB(tr.bokehShader.program);
	GLSL_SetUniformInt(&tr.bokehShader, UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP);
	qglUseProgramObjectARB(0);

	GLSL_FinishGPUShader(&tr.bokehShader);

	numEtcShaders++;


	attribs = ATTR_POSITION | ATTR_TEXCOORD;
	extradefines[0] = '\0';

	if (!GLSL_InitGPUShader(&tr.tonemapShader, "tonemap", attribs, qtrue, extradefines, qtrue, fallbackShader_tonemap_vp, fallbackShader_tonemap_fp))
	{
		ri.Error(ERR_FATAL, "Could not load tonemap shader!");
	}

	GLSL_InitUniforms(&tr.tonemapShader);

	qglUseProgramObjectARB(tr.tonemapShader.program);
	GLSL_SetUniformInt(&tr.tonemapShader, UNIFORM_TEXTUREMAP, TB_COLORMAP);
	GLSL_SetUniformInt(&tr.tonemapShader, UNIFORM_LEVELSMAP,  TB_LEVELSMAP);
	qglUseProgramObjectARB(0);

	GLSL_FinishGPUShader(&tr.tonemapShader);

	numEtcShaders++;


	for (i = 0; i < 2; i++)
	{
		attribs = ATTR_POSITION | ATTR_TEXCOORD;
		extradefines[0] = '\0';

		if (!i)
			Q_strcat(extradefines, 1024, "#define FIRST_PASS\n");

		if (!GLSL_InitGPUShader(&tr.calclevels4xShader[i], "calclevels4x", attribs, qtrue, extradefines, qtrue, fallbackShader_calclevels4x_vp, fallbackShader_calclevels4x_fp))
		{
			ri.Error(ERR_FATAL, "Could not load calclevels4x shader!");
		}

		GLSL_InitUniforms(&tr.calclevels4xShader[i]);

		qglUseProgramObjectARB(tr.calclevels4xShader[i].program);
		GLSL_SetUniformInt(&tr.calclevels4xShader[i], UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP);
		qglUseProgramObjectARB(0);

		GLSL_FinishGPUShader(&tr.calclevels4xShader[i]);

		numEtcShaders++;
	}


	attribs = ATTR_POSITION | ATTR_TEXCOORD;
	extradefines[0] = '\0';

	if (r_shadowFilter->integer >= 1)
		Q_strcat(extradefines, 1024, "#define USE_SHADOW_FILTER\n");

	if (r_shadowFilter->integer >= 2)
		Q_strcat(extradefines, 1024, "#define USE_SHADOW_FILTER2\n");

	if (r_shadowCascadeZFar->integer != 0)
		Q_strcat(extradefines, 1024, "#define USE_SHADOW_CASCADE\n");

	Q_strcat(extradefines, 1024, va("#define r_shadowMapSize %f\n", r_shadowMapSize->value));
	Q_strcat(extradefines, 1024, va("#define r_shadowCascadeZFar %f\n", r_shadowCascadeZFar->value));


	if (!GLSL_InitGPUShader(&tr.shadowmaskShader, "shadowmask", attribs, qtrue, extradefines, qtrue, fallbackShader_shadowmask_vp, fallbackShader_shadowmask_fp))
	{
		ri.Error(ERR_FATAL, "Could not load shadowmask shader!");
	}

	GLSL_InitUniforms(&tr.shadowmaskShader);

	qglUseProgramObjectARB(tr.shadowmaskShader.program);
	GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SCREENDEPTHMAP, TB_COLORMAP);
	GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP,  TB_SHADOWMAP);
	GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP2, TB_SHADOWMAP2);
	GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP3, TB_SHADOWMAP3);
	GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP4, TB_SHADOWMAP4);
	qglUseProgramObjectARB(0);

	GLSL_FinishGPUShader(&tr.shadowmaskShader);

	numEtcShaders++;


	attribs = ATTR_POSITION | ATTR_TEXCOORD;
	extradefines[0] = '\0';

	if (!GLSL_InitGPUShader(&tr.ssaoShader, "ssao", attribs, qtrue, extradefines, qtrue, fallbackShader_ssao_vp, fallbackShader_ssao_fp))
	{
		ri.Error(ERR_FATAL, "Could not load ssao shader!");
	}

	GLSL_InitUniforms(&tr.ssaoShader);

	qglUseProgramObjectARB(tr.ssaoShader.program);
	GLSL_SetUniformInt(&tr.ssaoShader, UNIFORM_SCREENDEPTHMAP, TB_COLORMAP);
	qglUseProgramObjectARB(0);

	GLSL_FinishGPUShader(&tr.ssaoShader);

	numEtcShaders++;


	for (i = 0; i < 2; i++)
	{
		attribs = ATTR_POSITION | ATTR_TEXCOORD;
		extradefines[0] = '\0';

		if (i & 1)
			Q_strcat(extradefines, 1024, "#define USE_VERTICAL_BLUR\n");
		else
			Q_strcat(extradefines, 1024, "#define USE_HORIZONTAL_BLUR\n");


		if (!GLSL_InitGPUShader(&tr.depthBlurShader[i], "depthBlur", attribs, qtrue, extradefines, qtrue, fallbackShader_depthblur_vp, fallbackShader_depthblur_fp))
		{
			ri.Error(ERR_FATAL, "Could not load depthBlur shader!");
		}

		GLSL_InitUniforms(&tr.depthBlurShader[i]);

		qglUseProgramObjectARB(tr.depthBlurShader[i].program);
		GLSL_SetUniformInt(&tr.depthBlurShader[i], UNIFORM_SCREENIMAGEMAP, TB_COLORMAP);
		GLSL_SetUniformInt(&tr.depthBlurShader[i], UNIFORM_SCREENDEPTHMAP, TB_LIGHTMAP);
		qglUseProgramObjectARB(0);

		GLSL_FinishGPUShader(&tr.depthBlurShader[i]);

		numEtcShaders++;
	}
#endif

	endTime = ri.Milliseconds();

	ri.Printf(PRINT_ALL, "loaded %i GLSL shaders (%i gen %i light %i etc) in %5.2f seconds\n",
		numGenShaders + numLightShaders + numEtcShaders, numGenShaders, numLightShaders,
		numEtcShaders, (endTime - startTime) / 1000.0);
}
示例#3
0
/*
* R_RenderMeshGLSL_Material
*/
static void R_RenderMeshGLSL_Material( r_glslfeat_t programFeatures )
{
	int i;
	int tcgen, rgbgen;
	int state;
	int program, object;
	image_t *base, *normalmap, *glossmap, *decalmap, *entdecalmap;
	mat4x4_t unused;
	vec3_t lightDir = { 0.0f, 0.0f, 0.0f };
	vec4_t ambient = { 0.0f, 0.0f, 0.0f, 0.0f }, diffuse = { 0.0f, 0.0f, 0.0f, 0.0f };
	float offsetmappingScale, glossExponent;
	const superLightStyle_t *lightStyle = NULL;
	const mfog_t *fog = r_back.colorFog;
	shaderpass_t *pass = r_back.accumPasses[0];
	qboolean applyDecal;

	// handy pointers
	base = pass->anim_frames[0];
	normalmap = pass->anim_frames[1];
	glossmap = pass->anim_frames[2];
	decalmap = pass->anim_frames[3];
	entdecalmap = pass->anim_frames[4];

	tcgen = pass->tcgen;                // store the original tcgen
	rgbgen = pass->rgbgen.type;			// store the original rgbgen

	assert( normalmap );

	if( normalmap->samples == 4 )
		offsetmappingScale = r_offsetmapping_scale->value * r_back.currentShader->offsetmapping_scale;
	else	// no alpha in normalmap, don't bother with offset mapping
		offsetmappingScale = 0;

	if( r_back.currentShader->gloss_exponent )
		glossExponent = r_back.currentShader->gloss_exponent;
	else
		glossExponent = r_lighting_glossexponent->value;

	applyDecal = decalmap != NULL;

	if( ri.params & RP_CLIPPLANE )
		programFeatures |= GLSL_COMMON_APPLY_CLIPPING;
	if( pass->flags & SHADERPASS_GRAYSCALE )
		programFeatures |= GLSL_COMMON_APPLY_GRAYSCALE;

	if( fog )
	{
		programFeatures |= GLSL_COMMON_APPLY_FOG;
		if( fog != ri.fog_eye )
			programFeatures |= GLSL_COMMON_APPLY_FOG2;
		if( GL_IsAlphaBlending( pass->flags & GLSTATE_SRCBLEND_MASK, pass->flags & GLSTATE_DSTBLEND_MASK ) )
			programFeatures |= GLSL_COMMON_APPLY_COLOR_FOG_ALPHA;
	}

	if( r_back.currentMeshBuffer->infokey > 0 && ( rgbgen != RGB_GEN_LIGHTING_DIFFUSE ) )
	{
		if( !( r_offsetmapping->integer & 1 ) ) {
			offsetmappingScale = 0;
		}
		if( ri.params & RP_LIGHTMAP ) {
			programFeatures |= GLSL_MATERIAL_APPLY_BASETEX_ALPHA_ONLY;
		}
		if( ( ri.params & RP_DRAWFLAT ) && !( r_back.currentShader->flags & SHADER_NODRAWFLAT ) ) {
			programFeatures |= GLSL_COMMON_APPLY_DRAWFLAT|GLSL_MATERIAL_APPLY_BASETEX_ALPHA_ONLY;
		}
	}
	else if( ( r_back.currentMeshBuffer->sortkey & 3 ) == MB_POLY )
	{
		// polys
		if( !( r_offsetmapping->integer & 2 ) )
			offsetmappingScale = 0;

		R_BuildTangentVectors( r_backacc.numVerts, vertsArray, normalsArray, coordsArray, r_backacc.numElems/3, elemsArray, inSVectorsArray );
	}
	else
	{
		// models and world lightingDiffuse materials
		if( r_back.currentMeshBuffer->infokey > 0 )
		{
			if( !( r_offsetmapping->integer & 1 ) )
				offsetmappingScale = 0;
			pass->rgbgen.type = RGB_GEN_VERTEX;
		}
		else
		{
			// models
			if( !( r_offsetmapping->integer & 4 ) )
				offsetmappingScale = 0;
#ifdef CELLSHADEDMATERIAL
			programFeatures |= GLSL_MATERIAL_APPLY_CELLSHADING;
#endif
#ifdef HALFLAMBERTLIGHTING
			programFeatures |= GLSL_MATERIAL_APPLY_HALFLAMBERT;
#endif
		}
	}

	// add dynamic lights
	if( r_back.currentDlightBits ) {
		programFeatures |= R_DlightbitsToProgramFeatures();
	}

	pass->tcgen = TC_GEN_BASE;
	R_BindShaderpass( pass, base, 0, &programFeatures );

	// calculate vertex color
	R_ModifyColor( pass, applyDecal, r_back.currentMeshVBO != NULL );

	// since R_ModifyColor has forcefully generated RGBA for the first vertex,
	// set the proper number of color elements here, so GL_COLOR_ARRAY will be enabled
	// before the DrawElements call
	if( !(pass->flags & SHADERPASS_NOCOLORARRAY) )
		r_backacc.numColors = r_backacc.numVerts;

	// convert rgbgen and alphagen to GLSL feature defines
	programFeatures |= R_RGBAlphaGenToProgramFeatures( pass->rgbgen.type, pass->alphagen.type );

	GL_TexEnv( GL_MODULATE );

	// set shaderpass state (blending, depthwrite, etc)
	state = r_back.currentShaderState | ( pass->flags & r_back.currentShaderPassMask ) | GLSTATE_BLEND_MTEX;
	GL_SetState( state );

#if 1
	// don't waste time on processing GLSL programs with zero colormask
	if( ( ri.params & RP_SHADOWMAPVIEW ) & !(programFeatures & GLSL_COMMON_APPLY_BONETRANSFORMS) )
	{
		pass->tcgen = tcgen; // restore original tcgen
		R_FlushArrays();
		return;
	}
#endif

	// we only send S-vectors to GPU and recalc T-vectors as cross product
	// in vertex shader
	pass->tcgen = TC_GEN_SVECTORS;
	GL_Bind( 1, normalmap );         // normalmap
	GL_SetTexCoordArrayMode( GL_TEXTURE_COORD_ARRAY );
	R_VertexTCBase( pass, 1, unused, NULL );

	if( glossmap && r_lighting_glossintensity->value )
	{
		programFeatures |= GLSL_MATERIAL_APPLY_SPECULAR;
		GL_Bind( 2, glossmap ); // gloss
		GL_SetTexCoordArrayMode( 0 );
	}

	if( applyDecal )
	{
		programFeatures |= GLSL_MATERIAL_APPLY_DECAL;

		if( ri.params & RP_LIGHTMAP ) {
			decalmap = r_blacktexture;
			programFeatures |= GLSL_MATERIAL_APPLY_DECAL_ADD;
		}
		else {
			// if no alpha, use additive blending
			if( decalmap->samples == 3 )
				programFeatures |= GLSL_MATERIAL_APPLY_DECAL_ADD;
		}

		GL_Bind( 3, decalmap ); // decal
		GL_SetTexCoordArrayMode( 0 );
	}

	if( entdecalmap )
	{
		programFeatures |= GLSL_MATERIAL_APPLY_ENTITY_DECAL;

		// if no alpha, use additive blending
		if( entdecalmap->samples == 3 )
			programFeatures |= GLSL_MATERIAL_APPLY_ENTITY_DECAL_ADD;

		GL_Bind( 4, entdecalmap ); // decal
		GL_SetTexCoordArrayMode( 0 );
	}

	if( offsetmappingScale > 0 )
		programFeatures |= r_offsetmapping_reliefmapping->integer ? GLSL_MATERIAL_APPLY_RELIEFMAPPING : GLSL_MATERIAL_APPLY_OFFSETMAPPING;

	if( r_back.currentMeshBuffer->infokey > 0 && ( rgbgen != RGB_GEN_LIGHTING_DIFFUSE ) )
	{
		// world surface
		if( r_back.superLightStyle && r_back.superLightStyle->lightmapNum[0] >= 0 )
		{
			lightStyle = r_back.superLightStyle;

			// bind lightmap textures and set program's features for lightstyles
			pass->tcgen = TC_GEN_LIGHTMAP;

			for( i = 0; i < MAX_LIGHTMAPS && lightStyle->lightmapStyles[i] != 255; i++ )
			{
				r_back.lightmapStyleNum[i+4] = i;
				GL_Bind( i+4, r_worldbrushmodel->lightmapImages[lightStyle->lightmapNum[i]] ); // lightmap
				GL_SetTexCoordArrayMode( GL_TEXTURE_COORD_ARRAY );
				R_VertexTCBase( pass, i+4, unused, NULL );
			}

			programFeatures |= ( i * GLSL_MATERIAL_APPLY_LIGHTSTYLE0 );

			if( i == 1 && !mapConfig.lightingIntensity )
			{
				vec_t *rgb = r_lightStyles[lightStyle->lightmapStyles[0]].rgb;

				// GLSL_MATERIAL_APPLY_FB_LIGHTMAP indicates that there's no need to renormalize
				// the lighting vector for specular (saves 3 adds, 3 muls and 1 normalize per pixel)
				if( rgb[0] == 1 && rgb[1] == 1 && rgb[2] == 1 )
					programFeatures |= GLSL_MATERIAL_APPLY_FB_LIGHTMAP;
			}

			if( !VectorCompare( mapConfig.ambient, vec3_origin ) )
			{
				VectorCopy( mapConfig.ambient, ambient );
				programFeatures |= GLSL_MATERIAL_APPLY_AMBIENT_COMPENSATION;
			}
		}
	}
	else
	{
		vec3_t temp;

		programFeatures |= GLSL_MATERIAL_APPLY_DIRECTIONAL_LIGHT;

		if( ( r_back.currentMeshBuffer->sortkey & 3 ) == MB_POLY )
		{
			VectorCopy( r_polys[-r_back.currentMeshBuffer->infokey-1].normal, lightDir );
			Vector4Set( ambient, 0, 0, 0, 0 );
			Vector4Set( diffuse, 1, 1, 1, 1 );
		}
		else if( ri.currententity )
		{
			if( ri.currententity->flags & RF_FULLBRIGHT )
			{
				Vector4Set( ambient, 1, 1, 1, 1 );
				Vector4Set( diffuse, 1, 1, 1, 1 );
			}
			else
			{
				if( r_back.currentMeshBuffer->infokey > 0 )
				{
					programFeatures |= GLSL_MATERIAL_APPLY_DIRECTIONAL_LIGHT_MIX;
					if( r_back.overBrightBits )
						programFeatures |= GLSL_COMMON_APPLY_OVERBRIGHT_SCALING;
				}

				if( ri.currententity->model && ri.currententity != r_worldent )
				{
					// get weighted incoming direction of world and dynamic lights
					R_LightForOrigin( ri.currententity->lightingOrigin, temp, ambient, diffuse, 
						ri.currententity->model->radius * ri.currententity->scale);
				}
				else
				{
					VectorSet( temp, 0.1f, 0.2f, 0.7f );
				}

				if( ri.currententity->flags & RF_MINLIGHT )
				{
					if( ambient[0] <= 0.1f || ambient[1] <= 0.1f || ambient[2] <= 0.1f )
						VectorSet( ambient, 0.1f, 0.1f, 0.1f );
				}

				// rotate direction
				Matrix_TransformVector( ri.currententity->axis, temp, lightDir );
			}
		}
	}

	pass->tcgen = tcgen;    // restore original tcgen
	pass->rgbgen.type = rgbgen;		// restore original rgbgen

	program = R_RegisterGLSLProgram( pass->program_type, pass->program, NULL, 
		r_back.currentShader->name, r_back.currentShader->deforms, r_back.currentShader->numdeforms, programFeatures );
	object = R_GetProgramObject( program );
	if( object )
	{
		qglUseProgramObjectARB( object );

		// update uniforms
		R_UpdateProgramUniforms( program, ri.viewOrigin, vec3_origin, lightDir, ambient, diffuse, lightStyle,
			qtrue, 0, 0, 0, offsetmappingScale, glossExponent, 
			colorArrayCopy[0], r_back.overBrightBits, r_back.currentShaderTime, r_back.entityColor );

		if( programFeatures & GLSL_COMMON_APPLY_FOG )
		{
			cplane_t fogPlane, vpnPlane;

			R_TransformFogPlanes( fog, fogPlane.normal, &fogPlane.dist, vpnPlane.normal, &vpnPlane.dist );

			R_UpdateProgramFogParams( program, fog->shader->fog_color, fog->shader->fog_clearDist,
				fog->shader->fog_dist, &fogPlane, &vpnPlane, ri.fog_dist_to_eye[fog-r_worldbrushmodel->fogs] );
		}

		// submit animation data
		if( programFeatures & GLSL_COMMON_APPLY_BONETRANSFORMS ) {
			R_UpdateProgramBonesParams( program, r_back.currentAnimData->numBones, r_back.currentAnimData->dualQuats );
		}

		// dynamic lights
		if( r_back.currentDlightBits ) {
			R_UpdateProgramLightsParams( program, ri.currententity->origin, ri.currententity->axis, r_back.currentDlightBits );
			r_back.doDynamicLightsPass = qfalse;
		}

		// r_drawflat
		if( programFeatures & GLSL_COMMON_APPLY_DRAWFLAT ) {
			R_UpdateDrawFlatParams( program, r_front.wallColor, r_front.floorColor );
		}

		R_FlushArrays();

		qglUseProgramObjectARB( 0 );
	}
}
/*
==================
RB_GLSL_DrawInteractions
==================
*/
void RB_GLSL_DrawInteractions( void ) {
	viewLight_t *vLight;

	GL_SelectTexture( 0 );
	qglDisableClientState( GL_TEXTURE_COORD_ARRAY );

	//
	// for each light, perform adding and shadowing
	//
	for ( vLight = backEnd.viewDef->viewLights; vLight; vLight = vLight->next ) {
		backEnd.vLight = vLight;

		// do fogging later
		if ( vLight->lightShader->IsFogLight() ) {
			continue;
		}
		if ( vLight->lightShader->IsBlendLight() ) {
			continue;
		}

		// if there are no interactions, get out!
		if ( !vLight->localInteractions && !vLight->globalInteractions && !vLight->translucentInteractions ) {
			continue;
		}

		// clear the stencil buffer if needed
		if ( vLight->globalShadows || vLight->localShadows ) {
			backEnd.currentScissor = vLight->scissorRect;
			if ( r_useScissor.GetBool() ) {
				qglScissor( backEnd.viewDef->viewport.x1 + backEnd.currentScissor.x1, 
					backEnd.viewDef->viewport.y1 + backEnd.currentScissor.y1,
					backEnd.currentScissor.x2 + 1 - backEnd.currentScissor.x1,
					backEnd.currentScissor.y2 + 1 - backEnd.currentScissor.y1 );
			}
			qglClear( GL_STENCIL_BUFFER_BIT );
		} else {
			// no shadows, so no need to read or write the stencil buffer
			// we might in theory want to use GL_ALWAYS instead of disabling
			// completely, to satisfy the invarience rules
			qglStencilFunc( GL_ALWAYS, 128, 255 );
		}

		if ( r_useShadowVertexProgram.GetBool() ) {
			qglUseProgramObjectARB( stencilShadowShader.program );
			RB_StencilShadowPass( vLight->globalShadows );
			RB_GLSL_CreateDrawInteractions( vLight->localInteractions );
			qglUseProgramObjectARB( stencilShadowShader.program );
			RB_StencilShadowPass( vLight->localShadows );
			RB_GLSL_CreateDrawInteractions( vLight->globalInteractions );
			qglUseProgramObjectARB( 0 );	// if there weren't any globalInteractions, it would have stayed on
		} else {
			RB_StencilShadowPass( vLight->globalShadows );
			RB_GLSL_CreateDrawInteractions( vLight->localInteractions );
			RB_StencilShadowPass( vLight->localShadows );
			RB_GLSL_CreateDrawInteractions( vLight->globalInteractions );
		}

		// translucent surfaces never get stencil shadowed
		if ( r_skipTranslucent.GetBool() ) {
			continue;
		}

		qglStencilFunc( GL_ALWAYS, 128, 255 );

		backEnd.depthFunc = GLS_DEPTHFUNC_LESS;
		RB_GLSL_CreateDrawInteractions( vLight->translucentInteractions );
		backEnd.depthFunc = GLS_DEPTHFUNC_EQUAL;
	}

	// disable stencil shadow test
	qglStencilFunc( GL_ALWAYS, 128, 255 );

	GL_SelectTexture( 0 );
	qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
}
/*
==================
RB_GLSL_InitShaders
==================
*/
static bool RB_GLSL_InitShaders( ) {
	// load interation shaders
	R_LoadGLSLShader( "interaction_Dir.vs", &interactionDirShader, GL_VERTEX_SHADER_ARB );
	R_LoadGLSLShader( "interaction_Dir.fs", &interactionDirShader, GL_FRAGMENT_SHADER_ARB );
	if ( !R_LinkGLSLShader( &interactionDirShader, true ) && !R_ValidateGLSLProgram( &interactionDirShader ) ) {
		return false;
	} else {
		// set uniform locations
		interactionDirShader.u_lightCubeTexture = qglGetUniformLocationARB( interactionDirShader.program, "u_lightCubeTexture" );
		interactionDirShader.u_lightProjectionTexture = qglGetUniformLocationARB( interactionDirShader.program, "u_lightProjectionTexture" );
		interactionDirShader.u_lightFalloffTexture = qglGetUniformLocationARB( interactionDirShader.program, "u_lightFalloffTexture" );
		interactionDirShader.u_normalTexture = qglGetUniformLocationARB( interactionDirShader.program, "u_normalTexture" );
		interactionDirShader.u_diffuseTexture = qglGetUniformLocationARB( interactionDirShader.program, "u_diffuseTexture" );
		interactionDirShader.u_specularTexture = qglGetUniformLocationARB( interactionDirShader.program, "u_specularTexture" );
		interactionDirShader.u_ssaoTexture = qglGetUniformLocationARB( interactionDirShader.program, "u_ssaoTexture" );
		interactionDirShader.u_aux0Texture = qglGetUniformLocationARB( interactionDirShader.program, "u_aux0Texture" );
		interactionDirShader.u_aux1Texture = qglGetUniformLocationARB( interactionDirShader.program, "u_aux1Texture" );
		interactionDirShader.u_aux2Texture = qglGetUniformLocationARB( interactionDirShader.program, "u_aux2Texture" );
		interactionDirShader.u_aux3Texture = qglGetUniformLocationARB( interactionDirShader.program, "u_aux3Texture" );
		interactionDirShader.u_aux4Texture = qglGetUniformLocationARB( interactionDirShader.program, "u_aux4Texture" );
		interactionDirShader.u_aux5Texture = qglGetUniformLocationARB( interactionDirShader.program, "u_aux5Texture" );
		interactionDirShader.u_aux6Texture = qglGetUniformLocationARB( interactionDirShader.program, "u_aux6Texture" );
		interactionDirShader.u_aux7Texture = qglGetUniformLocationARB( interactionDirShader.program, "u_aux7Texture" );
		interactionDirShader.u_aux8Texture = qglGetUniformLocationARB( interactionDirShader.program, "u_aux8Texture" );
		interactionDirShader.u_aux9Texture = qglGetUniformLocationARB( interactionDirShader.program, "u_aux9Texture" );

		interactionDirShader.modelMatrix = qglGetUniformLocationARB( interactionDirShader.program, "u_modelMatrix" );

		interactionDirShader.localLightOrigin = qglGetUniformLocationARB( interactionDirShader.program, "u_lightOrigin" );
		interactionDirShader.localViewOrigin = qglGetUniformLocationARB( interactionDirShader.program, "u_viewOrigin" );
		interactionDirShader.lightProjectionS = qglGetUniformLocationARB( interactionDirShader.program, "u_lightProjectionS" );
		interactionDirShader.lightProjectionT = qglGetUniformLocationARB( interactionDirShader.program, "u_lightProjectionT" );
		interactionDirShader.lightProjectionQ = qglGetUniformLocationARB( interactionDirShader.program, "u_lightProjectionQ" );
		interactionDirShader.lightFalloff = qglGetUniformLocationARB( interactionDirShader.program, "u_lightFalloff" );

		interactionDirShader.bumpMatrixS = qglGetUniformLocationARB( interactionDirShader.program, "u_bumpMatrixS" );
		interactionDirShader.bumpMatrixT = qglGetUniformLocationARB( interactionDirShader.program, "u_bumpMatrixT" );
		interactionDirShader.diffuseMatrixS = qglGetUniformLocationARB( interactionDirShader.program, "u_diffuseMatrixS" );
		interactionDirShader.diffuseMatrixT = qglGetUniformLocationARB( interactionDirShader.program, "u_diffuseMatrixT" );
		interactionDirShader.specularMatrixS = qglGetUniformLocationARB( interactionDirShader.program, "u_specularMatrixS" );
		interactionDirShader.specularMatrixT = qglGetUniformLocationARB( interactionDirShader.program, "u_specularMatrixT" );
		interactionDirShader.specularMatrixT = qglGetUniformLocationARB( interactionDirShader.program, "u_specularMatrixT" );

		interactionDirShader.colorMAD = qglGetUniformLocationARB( interactionDirShader.program, "u_colorMAD" );

		interactionDirShader.diffuseColor = qglGetUniformLocationARB( interactionDirShader.program, "u_diffuseColor" );
		interactionDirShader.specularColor = qglGetUniformLocationARB( interactionDirShader.program, "u_specularColor" );

		interactionDirShader.falloffType = qglGetUniformLocationARB( interactionDirShader.program, "u_falloffType" );

		interactionDirShader.specExp = qglGetUniformLocationARB( interactionDirShader.program, "u_specExp" );
	
		interactionDirShader.localParms[0] = qglGetUniformLocationARB( interactionDirShader.program, "u_localParm0" );
		interactionDirShader.localParms[1] = qglGetUniformLocationARB( interactionDirShader.program, "u_localParm1" );
		interactionDirShader.localParms[2] = qglGetUniformLocationARB( interactionDirShader.program, "u_localParm2" );
		interactionDirShader.localParms[3] = qglGetUniformLocationARB( interactionDirShader.program, "u_localParm3" );
		interactionDirShader.localParms[4] = qglGetUniformLocationARB( interactionDirShader.program, "u_localParm4" );
		interactionDirShader.localParms[5] = qglGetUniformLocationARB( interactionDirShader.program, "u_localParm5" );
		interactionDirShader.localParms[6] = qglGetUniformLocationARB( interactionDirShader.program, "u_localParm6" );
		interactionDirShader.localParms[7] = qglGetUniformLocationARB( interactionDirShader.program, "u_localParm7" );

		// set texture locations
		qglUseProgramObjectARB( interactionDirShader.program );
		qglUniform1iARB( interactionDirShader.u_lightCubeTexture, 0 );
		qglUniform1iARB( interactionDirShader.u_lightProjectionTexture, 16 );
		qglUniform1iARB( interactionDirShader.u_lightFalloffTexture, 1 );
		qglUniform1iARB( interactionDirShader.u_normalTexture, 2 );
		qglUniform1iARB( interactionDirShader.u_diffuseTexture, 3 );
		qglUniform1iARB( interactionDirShader.u_specularTexture, 4 );
		qglUniform1iARB( interactionDirShader.u_ssaoTexture, 5 );
		qglUniform1iARB( interactionDirShader.u_aux0Texture, 6 );
		qglUniform1iARB( interactionDirShader.u_aux1Texture, 7 );
		qglUniform1iARB( interactionDirShader.u_aux2Texture, 8 );
		qglUniform1iARB( interactionDirShader.u_aux3Texture, 9 );
		qglUniform1iARB( interactionDirShader.u_aux4Texture, 10 );
		qglUniform1iARB( interactionDirShader.u_aux5Texture, 11 );
		qglUniform1iARB( interactionDirShader.u_aux6Texture, 12 );
		qglUniform1iARB( interactionDirShader.u_aux7Texture, 13 );
		qglUniform1iARB( interactionDirShader.u_aux8Texture, 14 );
		qglUniform1iARB( interactionDirShader.u_aux9Texture, 15 );
		qglUseProgramObjectARB( 0 );
	}

	// load ambient interation shaders
	R_LoadGLSLShader( "interaction_Amb.vs", &interactionAmbShader, GL_VERTEX_SHADER_ARB );
	R_LoadGLSLShader( "interaction_Amb.fs", &interactionAmbShader, GL_FRAGMENT_SHADER_ARB );
	if ( !R_LinkGLSLShader( &interactionAmbShader, true ) && !R_ValidateGLSLProgram( &interactionAmbShader ) ) {
		return false;
	} else {
		// set uniform locations
		interactionAmbShader.u_lightCubeTexture = qglGetUniformLocationARB( interactionAmbShader.program, "u_lightCubeTexture" );
		interactionAmbShader.u_lightFalloffTexture = qglGetUniformLocationARB( interactionAmbShader.program, "u_lightFalloffTexture" );
		interactionAmbShader.u_normalTexture = qglGetUniformLocationARB( interactionAmbShader.program, "u_normalTexture" );
		interactionAmbShader.u_diffuseTexture = qglGetUniformLocationARB( interactionAmbShader.program, "u_diffuseTexture" );
		interactionAmbShader.u_specularTexture = qglGetUniformLocationARB( interactionAmbShader.program, "u_specularTexture" );
		interactionAmbShader.u_ssaoTexture = qglGetUniformLocationARB( interactionAmbShader.program, "u_ssaoTexture" );
		interactionAmbShader.u_aux0Texture = qglGetUniformLocationARB( interactionAmbShader.program, "u_aux0Texture" );
		interactionAmbShader.u_aux1Texture = qglGetUniformLocationARB( interactionAmbShader.program, "u_aux1Texture" );
		interactionAmbShader.u_aux2Texture = qglGetUniformLocationARB( interactionAmbShader.program, "u_aux2Texture" );
		interactionAmbShader.u_aux3Texture = qglGetUniformLocationARB( interactionAmbShader.program, "u_aux3Texture" );
		interactionAmbShader.u_aux4Texture = qglGetUniformLocationARB( interactionAmbShader.program, "u_aux4Texture" );
		interactionAmbShader.u_aux5Texture = qglGetUniformLocationARB( interactionAmbShader.program, "u_aux5Texture" );
		interactionAmbShader.u_aux6Texture = qglGetUniformLocationARB( interactionAmbShader.program, "u_aux6Texture" );
		interactionAmbShader.u_aux7Texture = qglGetUniformLocationARB( interactionAmbShader.program, "u_aux7Texture" );
		interactionAmbShader.u_aux8Texture = qglGetUniformLocationARB( interactionAmbShader.program, "u_aux8Texture" );
		interactionAmbShader.u_aux9Texture = qglGetUniformLocationARB( interactionAmbShader.program, "u_aux9Texture" );

		interactionAmbShader.modelMatrix = qglGetUniformLocationARB( interactionAmbShader.program, "u_modelMatrix" );

		interactionAmbShader.localLightOrigin = qglGetUniformLocationARB( interactionAmbShader.program, "u_lightOrigin" );
		interactionAmbShader.localViewOrigin = qglGetUniformLocationARB( interactionAmbShader.program, "u_viewOrigin" );
		interactionAmbShader.lightProjectionS = qglGetUniformLocationARB( interactionAmbShader.program, "u_lightProjectionS" );
		interactionAmbShader.lightProjectionT = qglGetUniformLocationARB( interactionAmbShader.program, "u_lightProjectionT" );
		interactionAmbShader.lightProjectionQ = qglGetUniformLocationARB( interactionAmbShader.program, "u_lightProjectionQ" );
		interactionAmbShader.lightFalloff = qglGetUniformLocationARB( interactionAmbShader.program, "u_lightFalloff" );

		interactionAmbShader.bumpMatrixS = qglGetUniformLocationARB( interactionAmbShader.program, "u_bumpMatrixS" );
		interactionAmbShader.bumpMatrixT = qglGetUniformLocationARB( interactionAmbShader.program, "u_bumpMatrixT" );
		interactionAmbShader.diffuseMatrixS = qglGetUniformLocationARB( interactionAmbShader.program, "u_diffuseMatrixS" );
		interactionAmbShader.diffuseMatrixT = qglGetUniformLocationARB( interactionAmbShader.program, "u_diffuseMatrixT" );
		interactionAmbShader.specularMatrixS = qglGetUniformLocationARB( interactionAmbShader.program, "u_specularMatrixS" );
		interactionAmbShader.specularMatrixT = qglGetUniformLocationARB( interactionAmbShader.program, "u_specularMatrixT" );

		interactionAmbShader.colorMAD = qglGetUniformLocationARB( interactionAmbShader.program, "u_colorMAD" );

		interactionAmbShader.diffuseColor = qglGetUniformLocationARB( interactionAmbShader.program, "u_diffuseColor" );
		interactionAmbShader.specularColor = qglGetUniformLocationARB( interactionAmbShader.program, "u_specularColor" );

		interactionAmbShader.specExp = qglGetUniformLocationARB( interactionAmbShader.program, "u_specExp" );
	
		interactionAmbShader.localParms[0] = qglGetUniformLocationARB( interactionAmbShader.program, "u_localParm0" );
		interactionAmbShader.localParms[1] = qglGetUniformLocationARB( interactionAmbShader.program, "u_localParm1" );
		interactionAmbShader.localParms[2] = qglGetUniformLocationARB( interactionAmbShader.program, "u_localParm2" );
		interactionAmbShader.localParms[3] = qglGetUniformLocationARB( interactionAmbShader.program, "u_localParm3" );
		interactionAmbShader.localParms[4] = qglGetUniformLocationARB( interactionAmbShader.program, "u_localParm4" );
		interactionAmbShader.localParms[5] = qglGetUniformLocationARB( interactionAmbShader.program, "u_localParm5" );
		interactionAmbShader.localParms[6] = qglGetUniformLocationARB( interactionAmbShader.program, "u_localParm6" );
		interactionAmbShader.localParms[7] = qglGetUniformLocationARB( interactionAmbShader.program, "u_localParm7" );

		// set texture locations
		qglUseProgramObjectARB( interactionAmbShader.program );
		qglUniform1iARB( interactionAmbShader.u_lightCubeTexture, 0 );
		qglUniform1iARB( interactionAmbShader.u_lightFalloffTexture, 1 );
		qglUniform1iARB( interactionAmbShader.u_normalTexture, 2 );
		qglUniform1iARB( interactionAmbShader.u_diffuseTexture, 3 );
		qglUniform1iARB( interactionAmbShader.u_specularTexture, 4 );
		qglUniform1iARB( interactionAmbShader.u_ssaoTexture, 5 );
		qglUniform1iARB( interactionAmbShader.u_aux0Texture, 6 );
		qglUniform1iARB( interactionAmbShader.u_aux1Texture, 7 );
		qglUniform1iARB( interactionAmbShader.u_aux2Texture, 8 );
		qglUniform1iARB( interactionAmbShader.u_aux3Texture, 9 );
		qglUniform1iARB( interactionAmbShader.u_aux4Texture, 10 );
		qglUniform1iARB( interactionAmbShader.u_aux5Texture, 11 );
		qglUniform1iARB( interactionAmbShader.u_aux6Texture, 12 );
		qglUniform1iARB( interactionAmbShader.u_aux7Texture, 13 );
		qglUniform1iARB( interactionAmbShader.u_aux8Texture, 14 );
		qglUniform1iARB( interactionAmbShader.u_aux9Texture, 15 );
		qglUseProgramObjectARB( 0 );
	}

	// load stencil shadow extrusion shaders
	R_LoadGLSLShader( "stencilshadow.vs", &stencilShadowShader, GL_VERTEX_SHADER_ARB );
	R_LoadGLSLShader( "stencilshadow.fs", &stencilShadowShader, GL_FRAGMENT_SHADER_ARB );
	if ( !R_LinkGLSLShader( &stencilShadowShader, false ) && !R_ValidateGLSLProgram( &stencilShadowShader ) ) {
		return false;
	} else {
		// set uniform locations
		stencilShadowShader.localLightOrigin = qglGetUniformLocationARB( stencilShadowShader.program, "u_lightOrigin" );
	}

	return true;
}
示例#6
0
/*
** RB_EndSurface
*/
void RB_EndSurface( qboolean forceDepth ) {
    shaderCommands_t *input;
    GLenum			 prog;
    int				 loc;
    int i,size;
    shaderStage_t	stage;
    image_t			image;
    char			tex[MAX_QPATH];

    input = &tess;

    if ( tess.shader == tr.maskEndShader ) {
        RB_MaskTessFinish();
        return;
    }

    if (input->numIndexes == 0) {
        return;
    }

    if (input->indexes[SHADER_MAX_INDEXES-1] != 0) {
        ri.Error (ERR_DROP, "RB_EndSurface() - SHADER_MAX_INDEXES hit");
    }
    if (input->xyz[SHADER_MAX_VERTEXES-1][0] != 0) {
        ri.Error (ERR_DROP, "RB_EndSurface() - SHADER_MAX_VERTEXES hit");
    }

    if ( tess.shader == tr.shadowShader ) {
        RB_ShadowTessEnd();
        return;
    }

    if ( tess.shader == tr.maskShader ) {
        RB_MaskTessEnd();
        return;
    }

    // for debugging of sort order issues, stop rendering after a given sort value
    if ( r_debugSort->integer && r_debugSort->integer < tess.shader->sort ) {
        return;
    }

    //
    // update performance counters
    //
    backEnd.pc.c_shaders++;
    backEnd.pc.c_vertexes += tess.numVertexes;
    backEnd.pc.c_indexes += tess.numIndexes;
    backEnd.pc.c_totalIndexes += tess.numIndexes * tess.numPasses;

    if(forceDepth) {
        //Force depth testing if we are rendering via draw.Start3D -Hxrmn
        size = sizeof(tess.xstages) / sizeof(tess.xstages[0]);
        for(i=0; i<size; i++) {
            if(tess.xstages[i] != NULL) {
                if(tess.xstages[i]->stateBits & GLS_DEPTHTEST_DISABLE) {
                    tess.xstages[i]->stateBits &= ~GLS_DEPTHTEST_DISABLE;
                }
            }
        }
    }

    //
    // call off to shader specific tess end function
    //

    if(tess.shader->GLSL) {
        prog = getShaderProgram(tess.shader->GLSLName);
        if(prog != -1) {
            qglUseProgramObjectARB(prog);

            if(qglUniform1fARB) {
                loc = qglGetUniformLocationARB(prog, "cgtime");
                qglUniform1fARB(loc, backEnd.refdef.floatTime);
            }

            if(qglUniform3fvARB) {
                loc = qglGetUniformLocationARB(prog, "viewPos");
                qglUniform3fARB(loc,
                                backEnd.refdef.vieworg[0],
                                backEnd.refdef.vieworg[1],
                                backEnd.refdef.vieworg[2]);
            }

            if(qglUniform3fvARB) {
                loc = qglGetUniformLocationARB(prog, "viewNormal");
                qglUniform3fARB(loc,
                                backEnd.refdef.viewaxis[0][0],
                                backEnd.refdef.viewaxis[0][1],
                                backEnd.refdef.viewaxis[0][2]);
            }

            if(qglUniform2fARB) {
                loc = qglGetUniformLocationARB(prog, "fov");
                qglUniform2fARB(loc,
                                backEnd.refdef.fov_x,
                                backEnd.refdef.fov_y);
            }
            /*
            loc = qglGetUniformLocationARB(prog, "texture_0");
            qglUniform1iARB(loc, 0);

            loc = qglGetUniformLocationARB(prog, "texture_1");
            qglUniform1iARB(loc, 1);*/
        }
    }

    //tess.shader->stages[0]->bundle[0].image

    tess.currentStageIteratorFunc();

    if(tess.shader->GLSL) {
        revertShaderProgram();
        qglDisable(GL_TEXTURE0_ARB);
        qglDisable(GL_TEXTURE1_ARB);
        qglDisable(GL_TEXTURE2_ARB);
        qglDisable(GL_TEXTURE3_ARB);
    }

    //
    // draw debugging stuff
    //
    if ( r_showtris->integer ) {
        DrawTris (input);
    }
    if ( r_shownormals->integer ) {
        DrawNormals (input);
    }
    // clear shader so we can tell we don't have any unclosed surfaces
    tess.numIndexes = 0;

    GLimp_LogComment( "----------\n" );
}
/*
=============
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 );
}
示例#8
0
void RB_ColorCorrect( void ) {
	GLint loc;
	GLenum target;
	int width, height;
	int shift;
	float mul;

	if ( !r_enablePostProcess->integer || !r_enableColorCorrect->integer || !glsl ) {
		return;
	}

	GL_SelectTexture(0);
	qglDisable(GL_TEXTURE_2D);
	qglEnable(GL_TEXTURE_RECTANGLE_ARB);

	target = GL_TEXTURE_RECTANGLE_ARB;

	width = glConfig.vidWidth;
	height = glConfig.vidHeight;

	qglBindTexture(target, tr.backBufferTexture);
	qglCopyTexSubImage2D(target, 0, 0, 0, 0, 0, glConfig.vidWidth, glConfig.vidHeight);

	qglMatrixMode(GL_PROJECTION);
	qglLoadIdentity();
	qglMatrixMode(GL_MODELVIEW);
	qglLoadIdentity();

	RB_SetGL2D();
	GL_State( GLS_DEPTHTEST_DISABLE );

    qglUseProgramObjectARB(tr.colorCorrectSp);
	loc = qglGetUniformLocationARB(tr.colorCorrectSp, "p_gammaRecip");
	if (loc < 0) {
		Com_Error(ERR_DROP, "%s() couldn't get p_gammaRecip", __FUNCTION__);
	}
	qglUniform1fARB(loc, (GLfloat)(1.0 / r_gamma->value));

	//mul = r_overBrightBitsValue->value;
	mul = r_overBrightBits->value;
	if (mul < 0.0) {
		mul = 0.0;
	}
	shift = tr.overbrightBits;

	loc = qglGetUniformLocationARB(tr.colorCorrectSp, "p_overbright");
	if (loc < 0) {
		Com_Error(ERR_DROP, "%s() couldn't get p_overbright", __FUNCTION__);
	}
	qglUniform1fARB(loc, (GLfloat)((float)(1 << shift) * mul));

	loc = qglGetUniformLocationARB(tr.colorCorrectSp, "p_contrast");
	if (loc < 0) {
		Com_Error(ERR_DROP, "%s() couldn't get p_contrast", __FUNCTION__);
	}
	qglUniform1fARB(loc, (GLfloat)r_contrast->value);

	loc = qglGetUniformLocationARB(tr.colorCorrectSp, "backBufferTex");
	if (loc < 0) {
		Com_Error(ERR_DROP, "%s() couldn't get backBufferTex", __FUNCTION__);
	}
	qglUniform1iARB(loc, 0);

	qglBegin(GL_QUADS);

	qglTexCoord2i(0, 0);
	qglVertex2i(0, height);

	qglTexCoord2i(width, 0);
	qglVertex2i(width, height);

	qglTexCoord2i(width, height);
	qglVertex2i(width, 0);

	qglTexCoord2i(0, height);
	qglVertex2i(0, 0);

	qglEnd();

	qglUseProgramObjectARB(0);

	qglDisable(GL_TEXTURE_RECTANGLE_ARB);
	qglEnable(GL_TEXTURE_2D);
}
示例#9
0
static void RB_BloomCombine( void ) {
	GLenum target;
	int width, height;
	GLint loc;

	GL_SelectTexture(0);
	qglDisable(GL_TEXTURE_2D);
	qglEnable(GL_TEXTURE_RECTANGLE_ARB);
	target = GL_TEXTURE_RECTANGLE_ARB;

	width = tr.bloomWidth;
	height = tr.bloomHeight;

	qglBindTexture(target, tr.bloomTexture);
	qglCopyTexSubImage2D(target, 0, 0, 0, 0, glConfig.vidHeight - height, width, height);

	qglUseProgramObjectARB(tr.combineSp);

	qglBindTexture(target, tr.backBufferTexture);
	loc = qglGetUniformLocationARB(tr.combineSp, "backBufferTex");
	if (loc < 0) {
		Com_Error(ERR_DROP, "%s() couldn't get backBufferTex", __FUNCTION__);
	}
	qglUniform1iARB(loc, 0);

	GL_SelectTexture(1);
	qglDisable(GL_TEXTURE_2D);
	qglEnable(GL_TEXTURE_RECTANGLE_ARB);

	qglBindTexture(target, tr.bloomTexture);
	loc = qglGetUniformLocationARB(tr.combineSp, "bloomTex");
	if (loc < 0) {
		Com_Error(ERR_DROP, "%s() couldn't get bloomTex", __FUNCTION__);
	}
	qglUniform1iARB(loc, 1);

	loc = qglGetUniformLocationARB(tr.combineSp, "p_bloomsaturation");
	if (loc < 0) {
		Com_Error(ERR_DROP, "%s() couldn't get p_bloomsaturation", __FUNCTION__);
	}
	qglUniform1fARB(loc, (GLfloat)r_BloomSaturation->value);

	loc = qglGetUniformLocationARB(tr.combineSp, "p_scenesaturation");
	if (loc < 0) {
		Com_Error(ERR_DROP, "%s() couldn't get p_scenesaturation", __FUNCTION__);
	}
	qglUniform1fARB(loc, (GLfloat)r_BloomSceneSaturation->value);

	loc = qglGetUniformLocationARB(tr.combineSp, "p_bloomintensity");
	if (loc < 0) {
		Com_Error(ERR_DROP, "%s() couldn't get p_bloomintensity", __FUNCTION__);
	}
	qglUniform1fARB(loc, (GLfloat)r_BloomIntensity->value);

	loc = qglGetUniformLocationARB(tr.combineSp, "p_sceneintensity");
	if (loc < 0) {
		Com_Error(ERR_DROP, "%s() couldn't get p_sceneintensity", __FUNCTION__);
	}
	qglUniform1fARB(loc, (GLfloat)r_BloomSceneIntensity->value);


	width = glConfig.vidWidth;
	height = glConfig.vidHeight;

    qglBegin(GL_QUADS);

	qglMultiTexCoord2iARB(GL_TEXTURE0_ARB, 0, 0);
	qglMultiTexCoord2iARB(GL_TEXTURE1_ARB, 0, 0);
	qglVertex2i(0, height);

	qglMultiTexCoord2iARB(GL_TEXTURE0_ARB, width, 0);
	qglMultiTexCoord2iARB(GL_TEXTURE1_ARB, tr.bloomWidth, 0);
	qglVertex2i(width, height);

	qglMultiTexCoord2iARB(GL_TEXTURE0_ARB, width, height);
	qglMultiTexCoord2iARB(GL_TEXTURE1_ARB, tr.bloomWidth, tr.bloomHeight);
	qglVertex2i(width, 0);

	qglMultiTexCoord2iARB(GL_TEXTURE0_ARB, 0, height);
	qglMultiTexCoord2iARB(GL_TEXTURE1_ARB, 0, tr.bloomHeight);
	qglVertex2i(0, 0);

	qglEnd();

	qglUseProgramObjectARB(0);

	GL_SelectTexture(1);
	qglDisable(GL_TEXTURE_RECTANGLE_ARB);
	qglDisable(GL_TEXTURE_2D);

	GL_SelectTexture(0);
	qglDisable(GL_TEXTURE_RECTANGLE_ARB);
	qglEnable(GL_TEXTURE_2D);
}
示例#10
0
static bool RB_GLSL_InitShaders( ) {
	// load interation shaders
	R_LoadGLSLShader( "interaction.vertex", &interactionShader, GL_VERTEX_SHADER_ARB );
	R_LoadGLSLShader( "interaction.fragment", &interactionShader, GL_FRAGMENT_SHADER_ARB );

	if ( interactionShader.fragmentShader == -1 ||
		 interactionShader.vertexShader == -1 ||
		!R_LinkGLSLShader( &interactionShader, true ) && 
		!R_ValidateGLSLProgram( &interactionShader ) ) 
	{
		if (interactionShader.fragmentShader != -1)
			qglDeleteShader(interactionShader.fragmentShader);
		if (interactionShader.vertexShader != -1)
			qglDeleteShader(interactionShader.vertexShader);
		interactionShader.fragmentShader = -1;
		interactionShader.vertexShader = -1;
		common->Printf( "GLSL interactionShader failed to init.\n" );
		return false;
	} else {
		// set uniform locations
		interactionShader.u_normalTexture = qglGetUniformLocationARB( interactionShader.program, "u_normalTexture" );
		interactionShader.u_lightFalloffTexture = qglGetUniformLocationARB( interactionShader.program, "u_lightFalloffTexture" );
		interactionShader.u_lightProjectionTexture = qglGetUniformLocationARB( interactionShader.program, "u_lightProjectionTexture" );
		interactionShader.u_diffuseTexture = qglGetUniformLocationARB( interactionShader.program, "u_diffuseTexture" );
		interactionShader.u_specularTexture = qglGetUniformLocationARB( interactionShader.program, "u_specularTexture" );

		interactionShader.modelMatrix = qglGetUniformLocationARB( interactionShader.program, "u_modelMatrix" );

		interactionShader.localLightOrigin = qglGetUniformLocationARB( interactionShader.program, "u_lightOrigin" );
		interactionShader.localViewOrigin = qglGetUniformLocationARB( interactionShader.program, "u_viewOrigin" );
		interactionShader.lightProjectionS = qglGetUniformLocationARB( interactionShader.program, "u_lightProjectionS" );
		interactionShader.lightProjectionT = qglGetUniformLocationARB( interactionShader.program, "u_lightProjectionT" );
		interactionShader.lightProjectionQ = qglGetUniformLocationARB( interactionShader.program, "u_lightProjectionQ" );
		interactionShader.lightFalloff = qglGetUniformLocationARB( interactionShader.program, "u_lightFalloff" );

		interactionShader.bumpMatrixS = qglGetUniformLocationARB( interactionShader.program, "u_bumpMatrixS" );
		interactionShader.bumpMatrixT = qglGetUniformLocationARB( interactionShader.program, "u_bumpMatrixT" );
		interactionShader.diffuseMatrixS = qglGetUniformLocationARB( interactionShader.program, "u_diffuseMatrixS" );
		interactionShader.diffuseMatrixT = qglGetUniformLocationARB( interactionShader.program, "u_diffuseMatrixT" );
		interactionShader.specularMatrixS = qglGetUniformLocationARB( interactionShader.program, "u_specularMatrixS" );
		interactionShader.specularMatrixT = qglGetUniformLocationARB( interactionShader.program, "u_specularMatrixT" );

		interactionShader.colorModulate = qglGetUniformLocationARB( interactionShader.program, "u_colorModulate" );
		interactionShader.colorAdd = qglGetUniformLocationARB( interactionShader.program, "u_colorAdd" );

		interactionShader.diffuseColor = qglGetUniformLocationARB( interactionShader.program, "u_diffuseColor" );
		interactionShader.specularColor = qglGetUniformLocationARB( interactionShader.program, "u_specularColor" );

		// set texture locations
		qglUseProgramObjectARB( interactionShader.program );
		qglUniform1iARB( interactionShader.u_normalTexture, 0 );
		qglUniform1iARB( interactionShader.u_lightFalloffTexture, 1 );
		qglUniform1iARB( interactionShader.u_lightProjectionTexture, 2 );
		qglUniform1iARB( interactionShader.u_diffuseTexture, 3 );
		qglUniform1iARB( interactionShader.u_specularTexture, 4 );
		qglUseProgramObjectARB( 0 );
	}

	// load ambient interation shaders
	R_LoadGLSLShader( "ambientInteraction.vertex", &ambientInteractionShader, GL_VERTEX_SHADER_ARB );
	R_LoadGLSLShader( "ambientInteraction.fragment", &ambientInteractionShader, GL_FRAGMENT_SHADER_ARB );
	if ( ambientInteractionShader.fragmentShader == -1 ||
		 ambientInteractionShader.vertexShader == -1 ||
		!R_LinkGLSLShader( &ambientInteractionShader, true ) && !R_ValidateGLSLProgram( &ambientInteractionShader ) ) 
	{
		if (ambientInteractionShader.fragmentShader != -1)
			qglDeleteShader(ambientInteractionShader.fragmentShader);
		if (ambientInteractionShader.vertexShader != -1)
			qglDeleteShader(ambientInteractionShader.vertexShader);
		ambientInteractionShader.fragmentShader = -1;
		ambientInteractionShader.vertexShader = -1;
		common->Printf( "GLSL ambientInteractionShader failed to init.\n" );
		return false;
	} else {
		// set uniform locations
		ambientInteractionShader.u_normalTexture = qglGetUniformLocationARB( ambientInteractionShader.program, "u_normalTexture" );
		ambientInteractionShader.u_lightFalloffTexture = qglGetUniformLocationARB( ambientInteractionShader.program, "u_lightFalloffTexture" );
		ambientInteractionShader.u_lightProjectionTexture = qglGetUniformLocationARB( ambientInteractionShader.program, "u_lightProjectionTexture" );
		ambientInteractionShader.u_diffuseTexture = qglGetUniformLocationARB( ambientInteractionShader.program, "u_diffuseTexture" );

		ambientInteractionShader.modelMatrix = qglGetUniformLocationARB( ambientInteractionShader.program, "u_modelMatrix" );

		ambientInteractionShader.localLightOrigin = qglGetUniformLocationARB( ambientInteractionShader.program, "u_lightOrigin" );
		ambientInteractionShader.lightProjectionS = qglGetUniformLocationARB( ambientInteractionShader.program, "u_lightProjectionS" );
		ambientInteractionShader.lightProjectionT = qglGetUniformLocationARB( ambientInteractionShader.program, "u_lightProjectionT" );
		ambientInteractionShader.lightProjectionQ = qglGetUniformLocationARB( ambientInteractionShader.program, "u_lightProjectionQ" );
		ambientInteractionShader.lightFalloff = qglGetUniformLocationARB( ambientInteractionShader.program, "u_lightFalloff" );

		ambientInteractionShader.bumpMatrixS = qglGetUniformLocationARB( ambientInteractionShader.program, "u_bumpMatrixS" );
		ambientInteractionShader.bumpMatrixT = qglGetUniformLocationARB( ambientInteractionShader.program, "u_bumpMatrixT" );
		ambientInteractionShader.diffuseMatrixS = qglGetUniformLocationARB( ambientInteractionShader.program, "u_diffuseMatrixS" );
		ambientInteractionShader.diffuseMatrixT = qglGetUniformLocationARB( ambientInteractionShader.program, "u_diffuseMatrixT" );

		ambientInteractionShader.colorModulate = qglGetUniformLocationARB( ambientInteractionShader.program, "u_colorModulate" );
		ambientInteractionShader.colorAdd = qglGetUniformLocationARB( ambientInteractionShader.program, "u_colorAdd" );

		ambientInteractionShader.diffuseColor = qglGetUniformLocationARB( ambientInteractionShader.program, "u_diffuseColor" );

		// set texture locations
		qglUseProgramObjectARB( ambientInteractionShader.program );
		qglUniform1iARB( ambientInteractionShader.u_normalTexture, 0 );
		qglUniform1iARB( ambientInteractionShader.u_lightFalloffTexture, 1 );
		qglUniform1iARB( ambientInteractionShader.u_lightProjectionTexture, 2 );
		qglUniform1iARB( ambientInteractionShader.u_diffuseTexture, 3 );
		qglUseProgramObjectARB( 0 );
	}

	// load stencil shadow extrusion shaders
	R_LoadGLSLShader( "stencilshadow.vertex", &stencilShadowShader, GL_VERTEX_SHADER_ARB );
	R_LoadGLSLShader( "stencilshadow.fragment", &stencilShadowShader, GL_FRAGMENT_SHADER_ARB );
	if ( stencilShadowShader.fragmentShader == -1 ||
		 stencilShadowShader.vertexShader == -1 ||
		 !R_LinkGLSLShader( &stencilShadowShader, false ) && !R_ValidateGLSLProgram( &stencilShadowShader ) ) {
		if (stencilShadowShader.fragmentShader != -1)
			qglDeleteShader(stencilShadowShader.fragmentShader);
		if (stencilShadowShader.vertexShader != -1)
			qglDeleteShader(stencilShadowShader.vertexShader);
		stencilShadowShader.fragmentShader = -1;
		stencilShadowShader.vertexShader = -1;
		common->Printf( "GLSL stencilShadowShader failed to init.\n" );
		return false;
	} else {
		// set uniform locations
		stencilShadowShader.localLightOrigin = qglGetUniformLocationARB( stencilShadowShader.program, "u_lightOrigin" );
	}

	return true;
}
示例#11
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 );
}
示例#12
0
void R_Shader_FinishLightRendering() {
	glDisable( GL_BLEND );
	qglUseProgramObjectARB( 0 );
}