Exemplo n.º 1
0
/*
===================
RB_StageIteratorLightmappedMultitexture
===================
*/
void RB_StageIteratorLightmappedMultitexture(void)
{
	shaderCommands_t *input  = &tess;
	shader_t         *shader = input->shader;

	// log this call
	if (r_logFile->integer)
	{
		// don't just call LogComment, or we will get
		// a call to va() every frame!
		GLimp_LogComment(va("--- RB_StageIteratorLightmappedMultitexture( %s ) ---\n", tess.shader->name));
	}

	// set GL fog
	SetIteratorFog();

	// set face culling appropriately
	GL_Cull(shader->cullType);

	// set color, pointers, and lock
	GL_State(GLS_DEFAULT);
	qglVertexPointer(3, GL_FLOAT, 16, input->xyz);

#ifdef REPLACE_MODE
	qglDisableClientState(GL_COLOR_ARRAY);
	qglColor3f(1, 1, 1);
	qglShadeModel(GL_FLAT);
#else
	qglEnableClientState(GL_COLOR_ARRAY);
	qglColorPointer(4, GL_UNSIGNED_BYTE, 0, tess.constantColor255);
#endif

	// select base stage
	GL_SelectTexture(0);

	qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
	R_BindAnimatedImage(&tess.xstages[0]->bundle[0]);
	qglTexCoordPointer(2, GL_FLOAT, 8, tess.texCoords0);

	// configure second stage
	GL_SelectTexture(1);
	qglEnable(GL_TEXTURE_2D);
	if (r_lightmap->integer)
	{
		GL_TexEnv(GL_REPLACE);
	}
	else
	{
		GL_TexEnv(GL_MODULATE);
	}

	// modified for snooper
	if (tess.xstages[0]->bundle[1].isLightmap && (backEnd.refdef.rdflags & RDF_SNOOPERVIEW))
	{
		GL_Bind(tr.whiteImage);
	}
	else
	{
		R_BindAnimatedImage(&tess.xstages[0]->bundle[1]);
	}

	qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
	qglTexCoordPointer(2, GL_FLOAT, 8, tess.texCoords1);

	// lock arrays
	if (qglLockArraysEXT)
	{
		qglLockArraysEXT(0, input->numVertexes);
		GLimp_LogComment("glLockArraysEXT\n");
	}

	R_DrawElements(input->numIndexes, input->indexes);

	// disable texturing on TEXTURE1, then select TEXTURE0
	qglDisable(GL_TEXTURE_2D);
	qglDisableClientState(GL_TEXTURE_COORD_ARRAY);

	GL_SelectTexture(0);
#ifdef REPLACE_MODE
	GL_TexEnv(GL_MODULATE);
	qglShadeModel(GL_SMOOTH);
#endif

	// now do any dynamic lighting needed
	//if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE )
	if (tess.dlightBits && tess.shader->fogPass &&
	    !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY)))
	{
		if (r_dynamiclight->integer == 2)
		{
			DynamicLightPass();
		}
		else
		{
			DynamicLightSinglePass();
		}
	}

	// now do fog
	if (tess.fogNum && tess.shader->fogPass)
	{
		RB_FogPass();
	}

	// unlock arrays
	if (qglUnlockArraysEXT)
	{
		qglUnlockArraysEXT();
		GLimp_LogComment("glUnlockArraysEXT\n");
	}
}
Exemplo n.º 2
0
/*
** RB_StageIteratorGeneric
*/
void RB_StageIteratorGeneric( void )
{
    shaderCommands_t *input;
    shader_t		*shader;

    input = &tess;
    shader = input->shader;

    RB_DeformTessGeometry();

    //
    // log this call
    //
    if ( r_logFile->integer )
    {
        // don't just call LogComment, or we will get
        // a call to va() every frame!
        GLimp_LogComment( va("--- RB_StageIteratorGeneric( %s ) ---\n", tess.shader->name) );
    }

    //
    // set face culling appropriately
    //
    GL_Cull( shader->cullType );

    // set polygon offset if necessary
    if ( shader->polygonOffset )
    {
        qglEnable( GL_POLYGON_OFFSET_FILL );
        qglPolygonOffset( r_offsetFactor->value, r_offsetUnits->value );
    }

    //
    // if there is only a single pass then we can enable color
    // and texture arrays before we compile, otherwise we need
    // to avoid compiling those arrays since they will change
    // during multipass rendering
    //
    if ( tess.numPasses > 1 || shader->multitextureEnv )
    {
        setArraysOnce = false;
        qglDisableClientState (GL_COLOR_ARRAY);
        qglDisableClientState (GL_TEXTURE_COORD_ARRAY);
    }
    else
    {
        setArraysOnce = true;

        qglEnableClientState( GL_COLOR_ARRAY);
        qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.svars.colors );

        qglEnableClientState( GL_TEXTURE_COORD_ARRAY);
        qglTexCoordPointer( 2, GL_FLOAT, 0, tess.svars.texcoords[0] );
    }

    //
    // lock XYZ
    //
    qglVertexPointer (3, GL_FLOAT, 16, input->xyz);	// padded for SIMD
    if (qglLockArraysEXT)
    {
        qglLockArraysEXT(0, input->numVertexes);
        GLimp_LogComment( "glLockArraysEXT\n" );
    }

    //
    // enable color and texcoord arrays after the lock if necessary
    //
    if ( !setArraysOnce )
    {
        qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
        qglEnableClientState( GL_COLOR_ARRAY );
    }

    //
    // call shader function
    //
    RB_IterateStagesGeneric( input );

    //
    // now do any dynamic lighting needed
    //
    if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE
            && !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) ) {
        ProjectDlightTexture();
    }

    //
    // now do fog
    //
    if ( tess.fogNum && tess.shader->fogPass ) {
        RB_FogPass();
    }

    //
    // unlock arrays
    //
    if (qglUnlockArraysEXT)
    {
        qglUnlockArraysEXT();
        GLimp_LogComment( "glUnlockArraysEXT\n" );
    }

    //
    // reset polygon offset
    //
    if ( shader->polygonOffset )
    {
        qglDisable( GL_POLYGON_OFFSET_FILL );
    }
}
Exemplo n.º 3
0
/*
** RB_StageIteratorGeneric
*/
void RB_StageIteratorGeneric( void )
{
	shaderCommands_t *input;
	unsigned int vertexAttribs = 0;

	input = &tess;
	
	if (!input->numVertexes || !input->numIndexes)
	{
		return;
	}

	if (tess.useInternalVBO)
	{
		RB_DeformTessGeometry();
	}

	vertexAttribs = RB_CalcShaderVertexAttribs( input );

	if (tess.useInternalVBO)
	{
		RB_UpdateVBOs(vertexAttribs);
	}
	else
	{
		backEnd.pc.c_staticVboDraws++;
	}

	//
	// log this call
	//
	if ( r_logFile->integer ) 
	{
		// don't just call LogComment, or we will get
		// a call to va() every frame!
		GLimp_LogComment( va("--- RB_StageIteratorGeneric( %s ) ---\n", tess.shader->name) );
	}

	//
	// set face culling appropriately
	//
	if ((backEnd.viewParms.flags & VPF_DEPTHSHADOW))
	{
		//GL_Cull( CT_TWO_SIDED );
		
		if (input->shader->cullType == CT_TWO_SIDED)
			GL_Cull( CT_TWO_SIDED );
		else if (input->shader->cullType == CT_FRONT_SIDED)
			GL_Cull( CT_BACK_SIDED );
		else
			GL_Cull( CT_FRONT_SIDED );
		
	}
	else
		GL_Cull( input->shader->cullType );

	// set polygon offset if necessary
	if ( input->shader->polygonOffset )
	{
		qglEnable( GL_POLYGON_OFFSET_FILL );
		qglPolygonOffset( r_offsetFactor->value, r_offsetUnits->value );
	}

	//
	// Set vertex attribs and pointers
	//
	GLSL_VertexAttribsState(vertexAttribs);

	//
	// render depth if in depthfill mode
	//
	if (backEnd.depthFill)
	{
		RB_IterateStagesGeneric( input );

		//
		// reset polygon offset
		//
		if ( input->shader->polygonOffset )
		{
			qglDisable( GL_POLYGON_OFFSET_FILL );
		}

		return;
	}

	//
	// render shadowmap if in shadowmap mode
	//
	if (backEnd.viewParms.flags & VPF_SHADOWMAP)
	{
		if ( input->shader->sort == SS_OPAQUE )
		{
			RB_RenderShadowmap( input );
		}
		//
		// reset polygon offset
		//
		if ( input->shader->polygonOffset )
		{
			qglDisable( GL_POLYGON_OFFSET_FILL );
		}

		return;
	}

	//
	//
	// call shader function
	//
	RB_IterateStagesGeneric( input );

	//
	// pshadows!
	//
	if (glRefConfig.framebufferObject && tess.pshadowBits && tess.shader->sort <= SS_OPAQUE
		&& !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) ) {
		ProjectPshadowVBOGLSL();
	}


	// 
	// now do any dynamic lighting needed
	//
	if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE
		&& !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) ) {
		if (tess.shader->numUnfoggedPasses == 1 && tess.xstages[0]->glslShaderGroup == tr.lightallShader
			&& (tess.xstages[0]->glslShaderIndex & LIGHTDEF_LIGHTTYPE_MASK) && r_dlightMode->integer)
		{
			ForwardDlight();
		}
		else
		{
			ProjectDlightTexture();
		}
	}

	if ((backEnd.viewParms.flags & VPF_USESUNLIGHT) && tess.shader->sort <= SS_OPAQUE 
	//if ((tr.sunShadows || r_forceSunlight->value > 0.0f) && tess.shader->sort <= SS_OPAQUE 
	    && !(tess.shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY) ) && tess.xstages[0]->glslShaderGroup == tr.lightallShader) {
		ForwardSunlight();
	}

	//
	// now do fog
	//
	if ( tess.fogNum && tess.shader->fogPass ) {
		RB_FogPass();
	}

	//
	// reset polygon offset
	//
	if ( input->shader->polygonOffset )
	{
		qglDisable( GL_POLYGON_OFFSET_FILL );
	}
}
Exemplo n.º 4
0
void RB_DoShadowTessEnd( vec3_t lightPos )
{
	int		i;
	int		numTris;
	vec3_t	lightDir;

	// we can only do this if we have enough space in the vertex buffers
	if ( tess.numVertexes >= SHADER_MAX_VERTEXES / 2 ) {
		return;
	}

	if ( glConfig.stencilBits < 4 ) {
		return;
	}

#if 1 //controlled method - try to keep shadows in range so they don't show through so much -rww
	vec3_t	worldxyz;
	vec3_t	entLight;
	float	groundDist;

	VectorCopy( backEnd.currentEntity->lightDir, entLight );
	entLight[2] = 0.0f;
	VectorNormalize(entLight);

	//Oh well, just cast them straight down no matter what onto the ground plane.
	//This presets no chance of screwups and still looks better than a stupid
	//shader blob.
	VectorSet(lightDir, entLight[0]*0.3f, entLight[1]*0.3f, 1.0f);
	// project vertexes away from light direction
	for ( i = 0 ; i < tess.numVertexes ; i++ ) {
		//add or.origin to vert xyz to end up with world oriented coord, then figure
		//out the ground pos for the vert to project the shadow volume to
		VectorAdd(tess.xyz[i], backEnd.ori.origin, worldxyz);
		groundDist = worldxyz[2] - backEnd.currentEntity->e.shadowPlane;
		groundDist += 16.0f; //fudge factor
		VectorMA( tess.xyz[i], -groundDist, lightDir, tess.xyz[i+tess.numVertexes] );
	}
#else
	if (lightPos)
	{
		for ( i = 0 ; i < tess.numVertexes ; i++ )
		{
			tess.xyz[i+tess.numVertexes][0] = tess.xyz[i][0]+(( tess.xyz[i][0]-lightPos[0] )*128.0f);
			tess.xyz[i+tess.numVertexes][1] = tess.xyz[i][1]+(( tess.xyz[i][1]-lightPos[1] )*128.0f);
			tess.xyz[i+tess.numVertexes][2] = tess.xyz[i][2]+(( tess.xyz[i][2]-lightPos[2] )*128.0f);
		}
	}
	else
	{
		VectorCopy( backEnd.currentEntity->lightDir, lightDir );

		// project vertexes away from light direction
		for ( i = 0 ; i < tess.numVertexes ; i++ ) {
			VectorMA( tess.xyz[i], -512, lightDir, tess.xyz[i+tess.numVertexes] );
		}
	}
#endif
	// decide which triangles face the light
	memset( numEdgeDefs, 0, 4 * tess.numVertexes );

	numTris = tess.numIndexes / 3;
	for ( i = 0 ; i < numTris ; i++ ) {
		int		i1, i2, i3;
		vec3_t	d1, d2, normal;
		float	*v1, *v2, *v3;
		float	d;

		i1 = tess.indexes[ i*3 + 0 ];
		i2 = tess.indexes[ i*3 + 1 ];
		i3 = tess.indexes[ i*3 + 2 ];

		v1 = tess.xyz[ i1 ];
		v2 = tess.xyz[ i2 ];
		v3 = tess.xyz[ i3 ];

		if (!lightPos)
		{
			VectorSubtract( v2, v1, d1 );
			VectorSubtract( v3, v1, d2 );
			CrossProduct( d1, d2, normal );

			d = DotProduct( normal, lightDir );
		}
		else
		{
			float planeEq[4];
			planeEq[0] = v1[1]*(v2[2]-v3[2]) + v2[1]*(v3[2]-v1[2]) + v3[1]*(v1[2]-v2[2]);
			planeEq[1] = v1[2]*(v2[0]-v3[0]) + v2[2]*(v3[0]-v1[0]) + v3[2]*(v1[0]-v2[0]);
			planeEq[2] = v1[0]*(v2[1]-v3[1]) + v2[0]*(v3[1]-v1[1]) + v3[0]*(v1[1]-v2[1]);
			planeEq[3] = -( v1[0]*( v2[1]*v3[2] - v3[1]*v2[2] ) +
						v2[0]*(v3[1]*v1[2] - v1[1]*v3[2]) +
						v3[0]*(v1[1]*v2[2] - v2[1]*v1[2]) );

			d = planeEq[0]*lightPos[0]+
				planeEq[1]*lightPos[1]+
				planeEq[2]*lightPos[2]+
				planeEq[3];
		}

		if ( d > 0 ) {
			facing[ i ] = 1;
		} else {
			facing[ i ] = 0;
		}

		// create the edges
		R_AddEdgeDef( i1, i2, facing[ i ] );
		R_AddEdgeDef( i2, i3, facing[ i ] );
		R_AddEdgeDef( i3, i1, facing[ i ] );
	}

	GL_Bind( tr.whiteImage );
	//qglEnable( GL_CULL_FACE );
	GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );

#ifndef _DEBUG_STENCIL_SHADOWS
	qglColor3f( 0.2f, 0.2f, 0.2f );

	// don't write to the color buffer
	qglColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );

	qglEnable( GL_STENCIL_TEST );
	qglStencilFunc( GL_ALWAYS, 1, 255 );
#else
	qglColor3f( 1.0f, 0.0f, 0.0f );
	qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	//qglDisable(GL_DEPTH_TEST);
#endif

#ifdef _STENCIL_REVERSE
	qglDepthFunc(GL_LESS);

	//now using the Carmack Reverse<tm> -rww
	if ( backEnd.viewParms.isMirror ) {
		//qglCullFace( GL_BACK );
		GL_Cull(CT_BACK_SIDED);
		qglStencilOp( GL_KEEP, GL_INCR, GL_KEEP );

		R_RenderShadowEdges();

		//qglCullFace( GL_FRONT );
		GL_Cull(CT_FRONT_SIDED);
		qglStencilOp( GL_KEEP, GL_DECR, GL_KEEP );

		R_RenderShadowEdges();
	} else {
		//qglCullFace( GL_FRONT );
		GL_Cull(CT_FRONT_SIDED);
		qglStencilOp( GL_KEEP, GL_INCR, GL_KEEP );

		R_RenderShadowEdges();

		//qglCullFace( GL_BACK );
		GL_Cull(CT_BACK_SIDED);
		qglStencilOp( GL_KEEP, GL_DECR, GL_KEEP );

		R_RenderShadowEdges();
	}

	qglDepthFunc(GL_LEQUAL);
#else
	// mirrors have the culling order reversed
	if ( backEnd.viewParms.isMirror ) {
		qglCullFace( GL_FRONT );
		qglStencilOp( GL_KEEP, GL_KEEP, GL_INCR );

		R_RenderShadowEdges();

		qglCullFace( GL_BACK );
		qglStencilOp( GL_KEEP, GL_KEEP, GL_DECR );

		R_RenderShadowEdges();
	} else {
		qglCullFace( GL_BACK );
		qglStencilOp( GL_KEEP, GL_KEEP, GL_INCR );

		R_RenderShadowEdges();

		qglCullFace( GL_FRONT );
		qglStencilOp( GL_KEEP, GL_KEEP, GL_DECR );

		R_RenderShadowEdges();
	}
#endif

	// reenable writing to the color buffer
	qglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );

#ifdef _DEBUG_STENCIL_SHADOWS
	qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
#endif
}
Exemplo n.º 5
0
/*
** RB_StageIteratorGeneric
*/
void RB_StageIteratorGeneric( void ) {
	shaderCommands_t *input;

	input = &tess;

	RB_DeformTessGeometry();

	//
	// log this call
	//
	if ( r_logFile->integer ) {
		// don't just call LogComment, or we will get
		// a call to va() every frame!
		GLimp_LogComment( va( "--- RB_StageIteratorGeneric( %s ) ---\n", tess.shader->name ) );
	}

	// set GL fog
	SetIteratorFog();

	if ( qglPNTrianglesiATI && tess.ATI_tess ) {
		// RF< so we can send the normals as an array
		qglEnableClientState( GL_NORMAL_ARRAY );
#ifdef __MACOS__    //DAJ ATI
		qglPNTrianglesiATI( GL_PN_TRIANGLES_ATI, 1 );
#else
		qglEnable( GL_PN_TRIANGLES_ATI ); // ATI PN-Triangles extension
#endif
	}


	//
	// set face culling appropriately
	//
	GL_Cull( input->shader->cullType );

	// set polygon offset if necessary
	if ( input->shader->polygonOffset ) {
		qglEnable( GL_POLYGON_OFFSET_FILL );
		qglPolygonOffset( r_offsetFactor->value, r_offsetUnits->value );
	}

	//
	// if there is only a single pass then we can enable color
	// and texture arrays before we compile, otherwise we need
	// to avoid compiling those arrays since they will change
	// during multipass rendering
	//
	if ( tess.numPasses > 1 || input->shader->multitextureEnv ) {
		setArraysOnce = qfalse;
		qglDisableClientState( GL_COLOR_ARRAY );
		qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
	} else
	{
		setArraysOnce = qtrue;

		qglEnableClientState( GL_COLOR_ARRAY );
		qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.svars.colors );

		qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
		qglTexCoordPointer( 2, GL_FLOAT, 0, tess.svars.texcoords[0] );
	}

	// RF, send normals only if required
	// This must be done first, since we can't change the arrays once they have been
	// locked
	if ( qglPNTrianglesiATI && tess.ATI_tess ) {
		qglNormalPointer( GL_FLOAT, 16, input->normal );
	}

	//
	// lock XYZ
	//
	qglVertexPointer( 3, GL_FLOAT, 16, input->xyz ); // padded for SIMD
	if ( qglLockArraysEXT ) {
		qglLockArraysEXT( 0, input->numVertexes );
		GLimp_LogComment( "glLockArraysEXT\n" );
	}

	//
	// enable color and texcoord arrays after the lock if necessary
	//
	if ( !setArraysOnce ) {
		qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
		qglEnableClientState( GL_COLOR_ARRAY );
	}

	//
	// call shader function
	//
	RB_IterateStagesGeneric( input );

	//
	// now do any dynamic lighting needed
	//
	if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE
		 && !( tess.shader->surfaceFlags & ( SURF_NODLIGHT | SURF_SKY ) ) ) {
		ProjectDlightTexture();
	}

	//
	// now do fog
	//
	if ( tess.fogNum && tess.shader->fogPass ) {
		RB_FogPass();
	}

	//
	// unlock arrays
	//
	if ( qglUnlockArraysEXT ) {
		qglUnlockArraysEXT();
		GLimp_LogComment( "glUnlockArraysEXT\n" );
	}

	//
	// reset polygon offset
	//
	if ( input->shader->polygonOffset ) {
		qglDisable( GL_POLYGON_OFFSET_FILL );
	}

	// turn truform back off
	if ( qglPNTrianglesiATI && tess.ATI_tess ) {
#ifdef __MACOS__    //DAJ ATI
		qglPNTrianglesiATI( GL_PN_TRIANGLES_ATI, 0 );
#else
		qglDisable( GL_PN_TRIANGLES_ATI );    // ATI PN-Triangles extension
#endif
		qglDisableClientState( GL_NORMAL_ARRAY );
	}

}
Exemplo n.º 6
0
void R_BloomBlend ( refdef_t *fd )
{
    if( !(fd->rdflags & RDF_BLOOM) || !r_bloom->value || r_showtris->value )
        return;

    if( !BLOOM_SIZE )
        R_Bloom_InitTextures();

    if( screen_texture_width < BLOOM_SIZE ||
            screen_texture_height < BLOOM_SIZE )
        return;

    //set up full screen workspace
    qglViewport ( 0, 0, vid.width, vid.height );
    GL_TexEnv (GL_REPLACE); // Knightmare added
    GL_Disable (GL_DEPTH_TEST);
    qglMatrixMode (GL_PROJECTION);
    qglLoadIdentity ();
    qglOrtho(0, vid.width, vid.height, 0, -10, 100);
    qglMatrixMode (GL_MODELVIEW);
    qglLoadIdentity ();
    GL_Disable (GL_CULL_FACE);

    GL_Disable (GL_BLEND);
    qglEnable (GL_TEXTURE_2D);

    qglColor4f (1, 1, 1, 1);

    //set up current sizes
    curView_x = fd->x;
    curView_y = fd->y;
    curView_width = fd->width;
    curView_height = fd->height;
    screenText_tcw = ((float)fd->width / (float)screen_texture_width);
    screenText_tch = ((float)fd->height / (float)screen_texture_height);
    if( fd->height > fd->width ) {
        sampleText_tcw = ((float)fd->width / (float)fd->height);
        sampleText_tch = 1.0f;
    } else {
        sampleText_tcw = 1.0f;
        sampleText_tch = ((float)fd->height / (float)fd->width);
    }
    sample_width = BLOOM_SIZE * sampleText_tcw;
    sample_height = BLOOM_SIZE * sampleText_tch;

    //copy the screen space we'll use to work into the backup texture
    GL_Bind(r_bloombackuptexture->texnum);
    qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, r_screenbackuptexture_size * sampleText_tcw, r_screenbackuptexture_size * sampleText_tch);

    //create the bloom image
    R_Bloom_DownsampleView();
    R_Bloom_GeneratexDiamonds( fd );
    //R_Bloom_GeneratexCross();

    //restore the screen-backup to the screen
    GL_Disable(GL_BLEND);
    GL_Bind(r_bloombackuptexture->texnum);
    qglColor4f( 1, 1, 1, 1 );
    R_Bloom_Quad( 0,
                  vid.height - (r_screenbackuptexture_size * sampleText_tch),
                  r_screenbackuptexture_size * sampleText_tcw,
                  r_screenbackuptexture_size * sampleText_tch,
                  sampleText_tcw,
                  sampleText_tch );

    R_Bloom_DrawEffect( fd );

    // Knightmare added
    R_SetupGL ();
    GL_BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    qglEnable (GL_TEXTURE_2D);
    qglColor4f(1,1,1,1);
}
Exemplo n.º 7
0
// If running in stereo, RE_BeginFrame will be called twice for each RE_EndFrame
void RE_BeginFrame( stereoFrame_t stereoFrame ) {
	drawBufferCommand_t	*cmd = NULL;
	colorMaskCommand_t *colcmd = NULL;

	if ( !tr.registered ) {
		return;
	}
	glState.finishCalled = qfalse;

	tr.frameCount++;
	tr.frameSceneNum = 0;

	//
	// do overdraw measurement
	//
	if ( r_measureOverdraw->integer )
	{
		if ( glConfig.stencilBits < 4 )
		{
			ri->Printf( PRINT_ALL, "Warning: not enough stencil bits to measure overdraw: %d\n", glConfig.stencilBits );
			ri->Cvar_Set( "r_measureOverdraw", "0" );
			r_measureOverdraw->modified = qfalse;
		}
		else if ( r_shadows->integer == 2 )
		{
			ri->Printf( PRINT_ALL, "Warning: stencil shadows and overdraw measurement are mutually exclusive\n" );
			ri->Cvar_Set( "r_measureOverdraw", "0" );
			r_measureOverdraw->modified = qfalse;
		}
		else
		{
			R_SyncRenderThread();
			qglEnable( GL_STENCIL_TEST );
			qglStencilMask( ~0U );
			qglClearStencil( 0U );
			qglStencilFunc( GL_ALWAYS, 0U, ~0U );
			qglStencilOp( GL_KEEP, GL_INCR, GL_INCR );
		}
		r_measureOverdraw->modified = qfalse;
	}
	else
	{
		// this is only reached if it was on and is now off
		if ( r_measureOverdraw->modified ) {
			R_SyncRenderThread();
			qglDisable( GL_STENCIL_TEST );
		}
		r_measureOverdraw->modified = qfalse;
	}

	//
	// texturemode stuff
	//
	if ( r_textureMode->modified ) {
		R_SyncRenderThread();
		GL_TextureMode( r_textureMode->string );
		r_textureMode->modified = qfalse;
	}

	//
	// gamma stuff
	//
	if ( r_gamma->modified ) {
		r_gamma->modified = qfalse;

		R_SyncRenderThread();
		R_SetColorMappings();
	}

	// check for errors
	if ( !r_ignoreGLErrors->integer )
	{
		int	err;

		R_SyncRenderThread();
		if ((err = qglGetError()) != GL_NO_ERROR)
			ri->Error(ERR_FATAL, "RE_BeginFrame() - glGetError() failed (0x%x)!", err);
	}

	if (glConfig.stereoEnabled) {
		if( !(cmd = R_GetCommandBuffer(sizeof(*cmd))) )
			return;
			
		cmd->commandId = RC_DRAW_BUFFER;
		
		if ( stereoFrame == STEREO_LEFT ) {
			cmd->buffer = (int)GL_BACK_LEFT;
		} else if ( stereoFrame == STEREO_RIGHT ) {
			cmd->buffer = (int)GL_BACK_RIGHT;
		} else {
			ri->Error( ERR_FATAL, "RE_BeginFrame: Stereo is enabled, but stereoFrame was %i", stereoFrame );
		}
	}
	else
	{
		if(r_anaglyphMode->integer)
		{
			if(r_anaglyphMode->modified)
			{
				// clear both, front and backbuffer.
				qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
				qglClearColor(0.0f, 0.0f, 0.0f, 1.0f);
				
				qglDrawBuffer(GL_FRONT);
				qglClear(GL_COLOR_BUFFER_BIT);
				qglDrawBuffer(GL_BACK);
				qglClear(GL_COLOR_BUFFER_BIT);
				
				r_anaglyphMode->modified = qfalse;
			}
			
			if(stereoFrame == STEREO_LEFT)
			{
				if( !(cmd = R_GetCommandBuffer(sizeof(*cmd))) )
					return;
				
				if( !(colcmd = R_GetCommandBuffer(sizeof(*colcmd))) )
					return;
			}
			else if(stereoFrame == STEREO_RIGHT)
			{
				clearDepthCommand_t *cldcmd;
				
				if( !(cldcmd = R_GetCommandBuffer(sizeof(*cldcmd))) )
					return;

				cldcmd->commandId = RC_CLEARDEPTH;

				if( !(colcmd = R_GetCommandBuffer(sizeof(*colcmd))) )
					return;
			}
			else
				ri->Error( ERR_FATAL, "RE_BeginFrame: Stereo is enabled, but stereoFrame was %i", stereoFrame );

			R_SetColorMode(colcmd->rgba, stereoFrame, r_anaglyphMode->integer);
			colcmd->commandId = RC_COLORMASK;
		}
		else
		{
			if(stereoFrame != STEREO_CENTER)
				ri->Error( ERR_FATAL, "RE_BeginFrame: Stereo is disabled, but stereoFrame was %i", stereoFrame );

			if( !(cmd = R_GetCommandBuffer(sizeof(*cmd))) )
				return;
		}

		if(cmd)
		{
			cmd->commandId = RC_DRAW_BUFFER;

			if(r_anaglyphMode->modified)
			{
				qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
				r_anaglyphMode->modified = qfalse;
			}

			if (!Q_stricmp(r_drawBuffer->string, "GL_FRONT"))
				cmd->buffer = (int)GL_FRONT;
			else
				cmd->buffer = (int)GL_BACK;
		}
	}
	
	tr.refdef.stereoFrame = stereoFrame;
}
Exemplo n.º 8
0
// Renders the input text at the current location with the current color.
// The X position of the current location is used to place the left edge of the text image,
// where the text image bounds are defined as the logical extents of the line of text.
// The Y position of the current location is used to place the bottom of the text image.
// You should offset the Y position by the amount returned by gtk_glwidget_font_descent()
// if you want to place the baseline of the text image at the current Y position.
// Note: A problem with this function is that if the lower left corner of the text falls
// just a hair outside of the viewport (meaning the current raster position is invalid),
// then no text will be rendered.  The solution to this is a very hacky one.  You can search
// Google for "glDrawPixels clipping".
void gtk_glwidget_print_string( const char *s ){
	// The idea for this code initially came from the font-pangoft2.c example that comes with GtkGLExt.

	PangoLayout *layout;
	PangoRectangle log_rect;
	FT_Bitmap bitmap;
	unsigned char *begin_bitmap_buffer;
	GLfloat color[4];
	GLint previous_unpack_alignment;
	GLboolean previous_blend_enabled;
	GLint previous_blend_func_src;
	GLint previous_blend_func_dst;
	GLfloat previous_red_bias;
	GLfloat previous_green_bias;
	GLfloat previous_blue_bias;
	GLfloat previous_alpha_scale;

	if ( !_debug_font_created ) {
		Error( "Programming error: gtk_glwidget_print_string() called but font does not exist; "
			   "you should have called gtk_glwidget_create_font() first" );
	}

	layout = pango_layout_new( ft2_context );
	pango_layout_set_width( layout, -1 ); // -1 no wrapping.  All text on one line.
	pango_layout_set_text( layout, s, -1 ); // -1 null-terminated string.
	pango_layout_get_extents( layout, NULL, &log_rect );

	if ( log_rect.width > 0 && log_rect.height > 0 ) {
		bitmap.rows = font_ascent + font_descent;
		bitmap.width = PANGO_PIXELS_CEIL( log_rect.width );
		bitmap.pitch = -bitmap.width; // Rendering it "upside down" for OpenGL.
		begin_bitmap_buffer = (unsigned char *) g_malloc( bitmap.rows * bitmap.width );
		memset( begin_bitmap_buffer, 0, bitmap.rows * bitmap.width );
		bitmap.buffer = begin_bitmap_buffer + ( bitmap.rows - 1 ) * bitmap.width; // See pitch above.
		bitmap.num_grays = 0xff;
		bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
		pango_ft2_render_layout_subpixel( &bitmap, layout, -log_rect.x,
										  y_offset_bitmap_render_pango_units );
		qglGetFloatv( GL_CURRENT_COLOR, color );

		// Save state.  I didn't see any OpenGL push/pop operations for these.
		// Question: Is saving/restoring this state necessary?  Being safe.
		qglGetIntegerv( GL_UNPACK_ALIGNMENT, &previous_unpack_alignment );
		previous_blend_enabled = qglIsEnabled( GL_BLEND );
		qglGetIntegerv( GL_BLEND_SRC, &previous_blend_func_src );
		qglGetIntegerv( GL_BLEND_DST, &previous_blend_func_dst );
		qglGetFloatv( GL_RED_BIAS, &previous_red_bias );
		qglGetFloatv( GL_GREEN_BIAS, &previous_green_bias );
		qglGetFloatv( GL_BLUE_BIAS, &previous_blue_bias );
		qglGetFloatv( GL_ALPHA_SCALE, &previous_alpha_scale );

		qglPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
		qglEnable( GL_BLEND );
		qglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
		qglPixelTransferf( GL_RED_BIAS, color[0] );
		qglPixelTransferf( GL_GREEN_BIAS, color[1] );
		qglPixelTransferf( GL_BLUE_BIAS, color[2] );
		qglPixelTransferf( GL_ALPHA_SCALE, color[3] );

		qglDrawPixels( bitmap.width, bitmap.rows,
					   GL_ALPHA, GL_UNSIGNED_BYTE, begin_bitmap_buffer );
		g_free( begin_bitmap_buffer );

		// Restore state in reverse order of how we set it.
		qglPixelTransferf( GL_ALPHA_SCALE, previous_alpha_scale );
		qglPixelTransferf( GL_BLUE_BIAS, previous_blue_bias );
		qglPixelTransferf( GL_GREEN_BIAS, previous_green_bias );
		qglPixelTransferf( GL_RED_BIAS, previous_red_bias );
		qglBlendFunc( previous_blend_func_src, previous_blend_func_dst );
		if ( !previous_blend_enabled ) {
			qglDisable( GL_BLEND );
		}
		qglPixelStorei( GL_UNPACK_ALIGNMENT, previous_unpack_alignment );
	}

	g_object_unref( G_OBJECT( layout ) );
}
Exemplo n.º 9
0
/*********
SP_DrawTexture
*********/
void SP_DrawTexture(void* pixels, float width, float height, float vShift)
{
	if (!pixels)
	{
		// Ug.  We were not even able to load the error message texture.
		return;
	}
	
	// Create a texture from the buffered file
	GLuint texid;
	qglGenTextures(1, &texid);
	qglBindTexture(GL_TEXTURE_2D, texid);
	qglTexImage2D(GL_TEXTURE_2D, 0, GL_DDS1_EXT, width, height, 0, GL_DDS1_EXT, GL_UNSIGNED_BYTE, pixels);

	qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
	qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
	qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
	qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );

	// Reset every GL state we've got.  Who knows what state
	// the renderer could be in when this function gets called.
	qglColor3f(1.f, 1.f, 1.f);
#ifdef _XBOX
	if(glw_state->isWidescreen)
		qglViewport(0, 0, 720, 480);
	else
#endif
	qglViewport(0, 0, 640, 480);

	GLboolean alpha = qglIsEnabled(GL_ALPHA_TEST);
	qglDisable(GL_ALPHA_TEST);

	GLboolean blend = qglIsEnabled(GL_BLEND);
	qglDisable(GL_BLEND);

	GLboolean cull = qglIsEnabled(GL_CULL_FACE);
	qglDisable(GL_CULL_FACE);

	GLboolean depth = qglIsEnabled(GL_DEPTH_TEST);
	qglDisable(GL_DEPTH_TEST);

	GLboolean fog = qglIsEnabled(GL_FOG);
	qglDisable(GL_FOG);

	GLboolean lighting = qglIsEnabled(GL_LIGHTING);
	qglDisable(GL_LIGHTING);

	GLboolean offset = qglIsEnabled(GL_POLYGON_OFFSET_FILL);
	qglDisable(GL_POLYGON_OFFSET_FILL);

	GLboolean scissor = qglIsEnabled(GL_SCISSOR_TEST);
	qglDisable(GL_SCISSOR_TEST);

	GLboolean stencil = qglIsEnabled(GL_STENCIL_TEST);
	qglDisable(GL_STENCIL_TEST);

	GLboolean texture = qglIsEnabled(GL_TEXTURE_2D);
	qglEnable(GL_TEXTURE_2D);

	qglMatrixMode(GL_MODELVIEW);
	qglLoadIdentity();
	qglMatrixMode(GL_PROJECTION);
	qglLoadIdentity();
#ifdef _XBOX
	if(glw_state->isWidescreen)
        qglOrtho(0, 720, 0, 480, 0, 1);
	else
#endif
	qglOrtho(0, 640, 0, 480, 0, 1);
	
	qglMatrixMode(GL_TEXTURE0);
	qglLoadIdentity();
	qglMatrixMode(GL_TEXTURE1);
	qglLoadIdentity();

	qglActiveTextureARB(GL_TEXTURE0_ARB);
	qglClientActiveTextureARB(GL_TEXTURE0_ARB);

	memset(&tess, 0, sizeof(tess));

	// Draw the error message
	qglBeginFrame();

	if (!SP_LicenseDone)
	{
		// clear the screen if we haven't done the
		// license yet...
		qglClearColor(0, 0, 0, 1);
		qglClear(GL_COLOR_BUFFER_BIT);
	}

	float x1, x2, y1, y2;
#ifdef _XBOX
	if(glw_state->isWidescreen)
	{
		x1 = 0;
		x2 = 720;
		y1 = 0;
		y2 = 480;
	}
	else {
#endif
	x1 = 0;
	x2 = 640;
	y1 = 0;
	y2 = 480;
#ifdef _XBOX
	}
#endif

	y1 += vShift;
	y2 += vShift;

	qglBeginEXT (GL_TRIANGLE_STRIP, 4, 0, 0, 4, 0);
		qglTexCoord2f( 0,  0 );
		qglVertex2f(x1, y1);
		qglTexCoord2f( 1 ,  0 );
		qglVertex2f(x2, y1);
		qglTexCoord2f( 0, 1 );
		qglVertex2f(x1, y2);
		qglTexCoord2f( 1, 1 );
		qglVertex2f(x2, y2);
	qglEnd();
	
	qglEndFrame();
	qglFlush();

	// Restore (most) of the render states we reset
	if (alpha) qglEnable(GL_ALPHA_TEST);
	else qglDisable(GL_ALPHA_TEST);

	if (blend) qglEnable(GL_BLEND);
	else qglDisable(GL_BLEND);

	if (cull) qglEnable(GL_CULL_FACE);
	else qglDisable(GL_CULL_FACE);

	if (depth) qglEnable(GL_DEPTH_TEST);
	else qglDisable(GL_DEPTH_TEST);

	if (fog) qglEnable(GL_FOG);
	else qglDisable(GL_FOG);

	if (lighting) qglEnable(GL_LIGHTING);
	else qglDisable(GL_LIGHTING);

	if (offset) qglEnable(GL_POLYGON_OFFSET_FILL);
	else qglDisable(GL_POLYGON_OFFSET_FILL);

	if (scissor) qglEnable(GL_SCISSOR_TEST);
	else qglDisable(GL_SCISSOR_TEST);

	if (stencil) qglEnable(GL_STENCIL_TEST);
	else qglDisable(GL_STENCIL_TEST);

	if (texture) qglEnable(GL_TEXTURE_2D);
	else qglDisable(GL_TEXTURE_2D);

	// Kill the texture
	qglDeleteTextures(1, &texid);
}
Exemplo n.º 10
0
void CWind::Render(CWorldEffectsSystem *system)
{
	vec3_t	output;

	if (!mEnabled || !debugShowWind)
	{
		return;
	}

	qglDisable(GL_TEXTURE_2D);
	qglDisable(GL_CULL_FACE);
	GL_State(GLS_ALPHA);

	qglColor4f(1.0, 0.0, 0.0, 0.5);
	qglBegin(GL_QUADS);
	
	VectorMA(mPoint, -(mSize[0]/2.0), mPlanes[0], output);
	VectorMA(output, -(mSize[1]/2.0), mPlanes[1], output);
	VectorMA(output, -(mSize[2]/2.0), mPlanes[2], output);
	qglVertex3fv(output);

	VectorMA(mPoint, -(mSize[0]/2.0), mPlanes[0], output);
	VectorMA(output, (mSize[1]/2.0), mPlanes[1], output);
	VectorMA(output, -(mSize[2]/2.0), mPlanes[2], output);
	qglVertex3fv(output);

	VectorMA(mPoint, -(mSize[0]/2.0), mPlanes[0], output);
	VectorMA(output, (mSize[1]/2.0), mPlanes[1], output);
	VectorMA(output, (mSize[2]/2.0), mPlanes[2], output);
	qglVertex3fv(output);

	VectorMA(mPoint, -(mSize[0]/2.0), mPlanes[0], output);
	VectorMA(output, -(mSize[1]/2.0), mPlanes[1], output);
	VectorMA(output, (mSize[2]/2.0), mPlanes[2], output);
	qglVertex3fv(output);

	
	
	qglColor4f(0.0, 1.0, 0.0, 0.5);
	VectorMA(mPoint, -(mSize[0]/2.0), mPlanes[0], output);
	VectorMA(output, -(mSize[1]/2.0), mPlanes[1], output);
	VectorMA(output, -(mSize[2]/2.0), mPlanes[2], output);
	qglVertex3fv(output);

	VectorMA(mPoint, (mSize[0]/2.0), mPlanes[0], output);
	VectorMA(output, -(mSize[1]/2.0), mPlanes[1], output);
	VectorMA(output, -(mSize[2]/2.0), mPlanes[2], output);
	qglVertex3fv(output);

	VectorMA(mPoint, (mSize[0]/2.0), mPlanes[0], output);
	VectorMA(output, -(mSize[1]/2.0), mPlanes[1], output);
	VectorMA(output, (mSize[2]/2.0), mPlanes[2], output);
	qglVertex3fv(output);

	VectorMA(mPoint, -(mSize[0]/2.0), mPlanes[0], output);
	VectorMA(output, -(mSize[1]/2.0), mPlanes[1], output);
	VectorMA(output, (mSize[2]/2.0), mPlanes[2], output);
	qglVertex3fv(output);
	

	qglColor4f(0.0, 0.0, 1.0, 0.5);
	VectorMA(mPoint, -(mSize[0]/2.0), mPlanes[0], output);
	VectorMA(output, -(mSize[2]/2.0), mPlanes[2], output);
	VectorMA(output, -(mSize[1]/2.0), mPlanes[1], output);
	qglVertex3fv(output);

	VectorMA(mPoint, (mSize[0]/2.0), mPlanes[0], output);
	VectorMA(output, -(mSize[2]/2.0), mPlanes[2], output);
	VectorMA(output, -(mSize[1]/2.0), mPlanes[1], output);
	qglVertex3fv(output);

	VectorMA(mPoint, (mSize[0]/2.0), mPlanes[0], output);
	VectorMA(output, -(mSize[2]/2.0), mPlanes[2], output);
	VectorMA(output, (mSize[1]/2.0), mPlanes[1], output);
	qglVertex3fv(output);

	VectorMA(mPoint, -(mSize[0]/2.0), mPlanes[0], output);
	VectorMA(output, -(mSize[2]/2.0), mPlanes[2], output);
	VectorMA(output, (mSize[1]/2.0), mPlanes[1], output);
	qglVertex3fv(output);
	
	
	qglEnd();

	qglEnable(GL_CULL_FACE);
	qglEnable(GL_TEXTURE_2D);
}
Exemplo n.º 11
0
void CRainSystem::Render(void)
{
	int			i;
	SParticle	*item;
	vec4_t		forward, down, left;
	vec3_t		pos;
//	float		percent;
	float		radius;

	CWorldEffectsSystem::Render();

	if (mFadeAlpha <= 0.0)
	{
		return;
	}

	VectorScale(backEnd.viewParms.or.axis[0], 1, forward);		// forward
	VectorScale(backEnd.viewParms.or.axis[1], 0.2f, left);		// left
	down[0] = 0 - mWindDirection[0] * mRainHeight * mWindAngle;
	down[1] = 0 - mWindDirection[1] * mRainHeight * mWindAngle;
	down[2] = -mRainHeight;

	GL_Bind(mImage);

	GL_State(GLS_ALPHA);
	qglEnable(GL_TEXTURE_2D);
	qglDisable(GL_CULL_FACE);

	qglMatrixMode(GL_MODELVIEW);
	qglPushMatrix();
    qglTranslatef (backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1],  backEnd.viewParms.or.origin[2]);

	item = mRainList;
	qglBegin(GL_TRIANGLES );
	for(i=mMaxRain;i;i--)
	{
/*		percent = (item->pos[1] -(-20.0)) / (20.0 - (-20.0));
		percent *= forward[2];
		if (percent < 0.0)
		{
			radius = 10 * (percent + 1.0);
		}
		else
		{
			radius = 10 * (1.0 - percent);
		}*/
		radius = item->pos[1];
		if (item->pos[2] < 0.0)
		{
//			radius *= 1.0 - (item->pos[2] / 40.0);
			float alpha = mAlpha * (item->pos[1] / -item->pos[2]);

			if (alpha > mAlpha)
			{
				alpha = mAlpha;
			}
			qglColor4f(1.0, 1.0, 1.0, alpha * mFadeAlpha);
		}
		else
		{
			qglColor4f(1.0, 1.0, 1.0, mAlpha * mFadeAlpha);
//			radius *= 1.0 + (item->pos[2] / 20.0);
		}

		pos[0] = sin(item->pos[0]) * radius + (item->pos[2] * mWindDirection[0] * mWindAngle);
		pos[1] = cos(item->pos[0]) * radius + (item->pos[2] * mWindDirection[1] * mWindAngle);
		pos[2] = item->pos[2];

		qglTexCoord2f(1.0, 0.0);
		qglVertex3f(pos[0],
					pos[1],
					pos[2]);

		qglTexCoord2f(0.0, 0.0);
		qglVertex3f(pos[0] + left[0],
					pos[1] + left[1],
					pos[2] + left[2]);
		
		qglTexCoord2f(0.0, 1.0);
		qglVertex3f(pos[0] + down[0] + left[0],
					pos[1] + down[1] + left[1],
					pos[2] + down[2] + left[2]);
		item++;
	}
	qglEnd();

	qglEnable(GL_CULL_FACE);

	qglPopMatrix();
}
Exemplo n.º 12
0
/*
==================
RB_ARB2_DrawInteractions
==================
*/
void RB_ARB2_DrawInteractions( void ) {
	viewLight_t		*vLight;
	const idMaterial	*lightShader;

    //FCS
    int passCount=0;
    
	GL_SelectTexture( 0 );
	qglDisableClientState( GL_TEXTURE_COORD_ARRAY );

    //printf("r_maxLightPasses = %d\n",r_maxLightPasses.GetInteger());
    
	//
	// for each light, perform adding and shadowing
	//
	for ( vLight = backEnd.viewDef->viewLights ; vLight && passCount < r_maxLightPasses.GetInteger(); vLight = vLight->next,passCount++ ) {
		backEnd.vLight = vLight;

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

		if ( !vLight->localInteractions && !vLight->globalInteractions
			&& !vLight->translucentInteractions ) {
			continue;
		}

		lightShader = vLight->lightShader;

		// 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() ) {
			qglEnable( GL_VERTEX_PROGRAM_ARB );
			qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_STENCIL_SHADOW );
			RB_StencilShadowPass( vLight->globalShadows );
			RB_ARB2_CreateDrawInteractions( vLight->localInteractions );
			qglEnable( GL_VERTEX_PROGRAM_ARB );
			qglBindProgramARB( GL_VERTEX_PROGRAM_ARB, VPROG_STENCIL_SHADOW );
			RB_StencilShadowPass( vLight->localShadows );
			RB_ARB2_CreateDrawInteractions( vLight->globalInteractions );
			qglDisable( GL_VERTEX_PROGRAM_ARB );	// if there weren't any globalInteractions, it would have stayed on
		} else {
			RB_StencilShadowPass( vLight->globalShadows );
			RB_ARB2_CreateDrawInteractions( vLight->localInteractions );
			RB_StencilShadowPass( vLight->localShadows );
			RB_ARB2_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_ARB2_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 );
}
Exemplo n.º 13
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);
}
Exemplo n.º 14
0
/*
================
DrawTris

Draws triangle outlines for debugging
================
*/
static void DrawTris(shaderCommands_t *input)
{
	char         *s        = r_trisColor->string;
	vec4_t       trisColor = { 1, 1, 1, 1 };
	unsigned int stateBits = 0;

	GL_Bind(tr.whiteImage);

	if (*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))
	{
		s += 2;
		if (Q_IsHexColorString(s))
		{
			trisColor[0] = ((float)(gethex(*(s)) * 16 + gethex(*(s + 1)))) / 255.00;
			trisColor[1] = ((float)(gethex(*(s + 2)) * 16 + gethex(*(s + 3)))) / 255.00;
			trisColor[2] = ((float)(gethex(*(s + 4)) * 16 + gethex(*(s + 5)))) / 255.00;

			if (Q_HexColorStringHasAlpha(s))
			{
				trisColor[3] = ((float)(gethex(*(s + 6)) * 16 + gethex(*(s + 7)))) / 255.00;
			}
		}
	}
	else
	{
		int  i;
		char *token;

		for (i = 0 ; i < 4 ; i++)
		{
			token = COM_Parse(&s);
			if (token)
			{
				trisColor[i] = atof(token);
			}
			else
			{
				trisColor[i] = 1.f;
			}
		}

		if (!trisColor[3])
		{
			trisColor[3] = 1.f;
		}
	}

	if (trisColor[3] < 1.f)
	{
		stateBits |= (GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA);
	}

	qglColor4fv(trisColor);

	if (r_showtris->integer == 2)
	{
		stateBits |= (GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE);
		GL_State(stateBits);
		qglDepthRange(0, 0);
	}
#ifdef CELSHADING_HACK
	else if (r_showtris->integer == 3)
	{
		stateBits |= (GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE);
		GL_State(stateBits);
		qglEnable(GL_POLYGON_OFFSET_LINE);
		qglPolygonOffset(4.0, 0.5);
		qglLineWidth(5.0);
	}
#endif
	else
	{
		stateBits |= (GLS_POLYMODE_LINE);
		GL_State(stateBits);
		qglEnable(GL_POLYGON_OFFSET_LINE);
		qglPolygonOffset(r_offsetFactor->value, r_offsetUnits->value);
	}

	qglDisableClientState(GL_COLOR_ARRAY);
	qglDisableClientState(GL_TEXTURE_COORD_ARRAY);

	qglVertexPointer(3, GL_FLOAT, 16, input->xyz);   // padded for SIMD

	if (qglLockArraysEXT)
	{
		qglLockArraysEXT(0, input->numVertexes);
		GLimp_LogComment("glLockArraysEXT\n");
	}

	R_DrawElements(input->numIndexes, input->indexes);

	if (qglUnlockArraysEXT)
	{
		qglUnlockArraysEXT();
		GLimp_LogComment("glUnlockArraysEXT\n");
	}
	qglDepthRange(0, 1);
	qglDisable(GL_POLYGON_OFFSET_LINE);
}
Exemplo n.º 15
0
/*
================
rvGEWorkspace::Render

Renders the workspace to the given DC
================
*/
void rvGEWorkspace::Render ( HDC hdc )
{
	int		front;
	int		back;
	float	scale;

	scale = g_ZoomScales[mZoom];

	// Switch GL contexts to our dc
	if (!qwglMakeCurrent( hdc, win32.hGLRC ))
	{
		common->Printf("ERROR: wglMakeCurrent failed.. Error:%i\n", qglGetError());
		common->Printf("Please restart Q3Radiant if the Map view is not working\n");
		return;
	}

	// Prepare the view and clear it
	GL_State( GLS_DEFAULT );
	qglViewport(0, 0, mWindowWidth, mWindowHeight );
	qglScissor(0, 0, mWindowWidth, mWindowHeight );
	qglClearColor ( 0.75f, 0.75f, 0.75f, 0 );

	qglDisable(GL_DEPTH_TEST);
	qglDisable(GL_CULL_FACE);
	qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	// Render the workspace below
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	qglOrtho(0,mWindowWidth, mWindowHeight, 0, -1, 1);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	qglColor3f ( mApplication->GetOptions().GetWorkspaceColor()[0], mApplication->GetOptions().GetWorkspaceColor()[1], mApplication->GetOptions().GetWorkspaceColor()[2] );
	qglBegin ( GL_QUADS );
	qglVertex2f ( mRect.x, mRect.y );
	qglVertex2f ( mRect.x + mRect.w, mRect.y );
	qglVertex2f ( mRect.x + mRect.w, mRect.y + mRect.h );
	qglVertex2f ( mRect.x, mRect.y + mRect.h );
	qglEnd ( );

	// Prepare the renderSystem view to draw the GUI in
	viewDef_t viewDef;
	memset ( &viewDef, 0, sizeof(viewDef) );
	tr.viewDef = &viewDef;
	tr.viewDef->renderView.x = mRect.x;
	tr.viewDef->renderView.y = mWindowHeight - mRect.y - mRect.h;
	tr.viewDef->renderView.width = mRect.w;
	tr.viewDef->renderView.height = mRect.h;
	tr.viewDef->scissor.x1 = 0;
	tr.viewDef->scissor.y1 = 0;
	tr.viewDef->scissor.x2 = mRect.w;
	tr.viewDef->scissor.y2 = mRect.h;
	tr.viewDef->isEditor = true;
	renderSystem->BeginFrame(mWindowWidth, mWindowHeight );

	// Draw the gui
	mInterface->Redraw ( 0 ); // eventLoop->Milliseconds() );

	// We are done using the renderSystem now
	renderSystem->EndFrame( &front, &back );

	if ( mApplication->GetActiveWorkspace ( ) == this )
	{
		mApplication->GetStatusBar().SetTriangles ( backEnd.pc.c_drawIndexes/3 );
	}

	// Prepare the viewport for drawing selections, etc.
	GL_State( GLS_DEFAULT );
	qglDisable( GL_TEXTURE_CUBE_MAP_EXT );
//	qglDisable(GL_BLEND);
	qglDisable(GL_CULL_FACE);

	qglViewport(0, 0, mWindowWidth, mWindowHeight );
	qglScissor(0, 0, mWindowWidth, mWindowHeight );
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	qglOrtho(0,mWindowWidth, mWindowHeight, 0, -1, 1);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	RenderGrid ( );

	mSelections.Render ( );

	qglFinish ( );
	qwglSwapBuffers(hdc);

	qglEnable( GL_TEXTURE_CUBE_MAP_EXT );
	qglEnable( GL_CULL_FACE);
}
Exemplo n.º 16
0
/*
=============
R_CheckCvars

See if some cvars that we watch have changed
=============
*/
static void R_CheckCvars()
{

	// gamma stuff
	if( r_gamma.IsModified() || r_brightness.IsModified() )
	{
		r_gamma.ClearModified();
		r_brightness.ClearModified();
		R_SetColorMappings();
	}
	
	// filtering
	if( r_maxAnisotropicFiltering.IsModified() || r_useTrilinearFiltering.IsModified() || r_lodBias.IsModified() )
	{
		idLib::Printf( "Updating texture filter parameters.\n" );
		r_maxAnisotropicFiltering.ClearModified();
		r_useTrilinearFiltering.ClearModified();
		r_lodBias.ClearModified();
		for( int i = 0 ; i < globalImages->images.Num() ; i++ )
		{
			if( globalImages->images[i] )
			{
				globalImages->images[i]->Bind();
				globalImages->images[i]->SetTexParameters();
			}
		}
	}
	
	extern idCVar r_useSeamlessCubeMap;
	if( r_useSeamlessCubeMap.IsModified() )
	{
		r_useSeamlessCubeMap.ClearModified();
		if( glConfig.seamlessCubeMapAvailable )
		{
			if( r_useSeamlessCubeMap.GetBool() )
			{
				qglEnable( GL_TEXTURE_CUBE_MAP_SEAMLESS );
			}
			else
			{
				qglDisable( GL_TEXTURE_CUBE_MAP_SEAMLESS );
			}
		}
	}
	
	extern idCVar r_useSRGB;
	if( r_useSRGB.IsModified() )
	{
		r_useSRGB.ClearModified();
		if( glConfig.sRGBFramebufferAvailable )
		{
			if( r_useSRGB.GetBool() )
			{
				qglEnable( GL_FRAMEBUFFER_SRGB );
			}
			else
			{
				qglDisable( GL_FRAMEBUFFER_SRGB );
			}
		}
	}
	
	
	if( r_multiSamples.IsModified() )
	{
		if( r_multiSamples.GetInteger() > 0 )
		{
			qglEnable( GL_MULTISAMPLE_ARB );
		}
		else
		{
			qglDisable( GL_MULTISAMPLE_ARB );
		}
	}
	
	// check for changes to logging state
	GLimp_EnableLogging( r_logFile.GetInteger() != 0 );
}
Exemplo n.º 17
0
/*
=================
RB_ShadowTessEnd

triangleFromEdge[ v1 ][ v2 ]


  set triangle from edge( v1, v2, tri )
  if ( facing[ triangleFromEdge[ v1 ][ v2 ] ] && !facing[ triangleFromEdge[ v2 ][ v1 ] ) {
  }
=================
*/
void RB_ShadowTessEnd( void ) {
	int		i;
	int		numTris;
	vec3_t	lightDir;
	GLboolean rgba[4];

	// we can only do this if we have enough space in the vertex buffers
	if ( tess.numVertexes >= SHADER_MAX_VERTEXES / 2 ) {
		return;
	}

	if ( glConfig.stencilBits < 4 ) {
		return;
	}

	VectorCopy( backEnd.currentEntity->lightDir, lightDir );

	// project vertexes away from light direction
	for ( i = 0 ; i < tess.numVertexes ; i++ ) {
		VectorMA( tess.xyz[i], -512, lightDir, tess.xyz[i+tess.numVertexes] );
	}

	// decide which triangles face the light
	Com_Memset( numEdgeDefs, 0, 4 * tess.numVertexes );

	numTris = tess.numIndexes / 3;
	for ( i = 0 ; i < numTris ; i++ ) {
		int		i1, i2, i3;
		vec3_t	d1, d2, normal;
		float	*v1, *v2, *v3;
		float	d;

		i1 = tess.indexes[ i*3 + 0 ];
		i2 = tess.indexes[ i*3 + 1 ];
		i3 = tess.indexes[ i*3 + 2 ];

		v1 = tess.xyz[ i1 ];
		v2 = tess.xyz[ i2 ];
		v3 = tess.xyz[ i3 ];

		VectorSubtract( v2, v1, d1 );
		VectorSubtract( v3, v1, d2 );
		CrossProduct( d1, d2, normal );

		d = DotProduct( normal, lightDir );
		if ( d > 0 ) {
			facing[ i ] = 1;
		} else {
			facing[ i ] = 0;
		}

		// create the edges
		R_AddEdgeDef( i1, i2, facing[ i ] );
		R_AddEdgeDef( i2, i3, facing[ i ] );
		R_AddEdgeDef( i3, i1, facing[ i ] );
	}

	// draw the silhouette edges

	GL_Bind( tr.whiteImage );
	qglEnable( GL_CULL_FACE );
	GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO );
	qglColor3f( 0.2f, 0.2f, 0.2f );

	// don't write to the color buffer
	qglGetBooleanv(GL_COLOR_WRITEMASK, rgba);
	qglColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );

	qglEnable( GL_STENCIL_TEST );
	qglStencilFunc( GL_ALWAYS, 1, 255 );

	// mirrors have the culling order reversed
	if ( backEnd.viewParms.isMirror ) {
		qglCullFace( GL_FRONT );
		qglStencilOp( GL_KEEP, GL_KEEP, GL_INCR );

		R_RenderShadowEdges();

		qglCullFace( GL_BACK );
		qglStencilOp( GL_KEEP, GL_KEEP, GL_DECR );

		R_RenderShadowEdges();
	} else {
		qglCullFace( GL_BACK );
		qglStencilOp( GL_KEEP, GL_KEEP, GL_INCR );

		R_RenderShadowEdges();

		qglCullFace( GL_FRONT );
		qglStencilOp( GL_KEEP, GL_KEEP, GL_DECR );

		R_RenderShadowEdges();
	}


	// reenable writing to the color buffer
	qglColorMask(rgba[0], rgba[1], rgba[2], rgba[3]);
}
Exemplo n.º 18
0
/*
====================
RE_BeginFrame

If running in stereo, RE_BeginFrame will be called twice
for each RE_EndFrame
====================
*/
void RE_BeginFrame( stereoFrame_t stereoFrame ) {
	drawBufferCommand_t	*cmd;

	if ( !tr.registered ) {
		return;
	}
	glState.finishCalled = qfalse;

	tr.frameCount++;
	tr.frameSceneNum = 0;

	//
	// do overdraw measurement
	//
	if ( r_measureOverdraw->integer )
	{
		if ( glConfig.stencilBits < 4 )
		{
			ri.Printf( PRINT_ALL, "Warning: not enough stencil bits to measure overdraw: %d\n", glConfig.stencilBits );
			ri.Cvar_Set( "r_measureOverdraw", "0" );
			r_measureOverdraw->modified = qfalse;
		}
		else if ( r_shadows->integer == 2 )
		{
			ri.Printf( PRINT_ALL, "Warning: stencil shadows and overdraw measurement are mutually exclusive\n" );
			ri.Cvar_Set( "r_measureOverdraw", "0" );
			r_measureOverdraw->modified = qfalse;
		}
		else
		{
			R_SyncRenderThread();
			qglEnable( GL_STENCIL_TEST );
			qglStencilMask( ~0U );
			qglClearStencil( 0U );
			qglStencilFunc( GL_ALWAYS, 0U, ~0U );
			qglStencilOp( GL_KEEP, GL_INCR, GL_INCR );
		}
		r_measureOverdraw->modified = qfalse;
	}
	else
	{
		// this is only reached if it was on and is now off
		if ( r_measureOverdraw->modified ) {
			R_SyncRenderThread();
			qglDisable( GL_STENCIL_TEST );
			r_measureOverdraw->modified = qfalse;
		}
	}

	//
	// texturemode stuff
	//
	if ( r_textureMode->modified || r_ext_texture_filter_anisotropic->modified) {
		R_SyncRenderThread();
		GL_TextureMode( r_textureMode->string );
		r_textureMode->modified = qfalse;
		r_ext_texture_filter_anisotropic->modified = qfalse;
	}

	//
	// gamma stuff
	//
	if ( r_gamma->modified ) {
		r_gamma->modified = qfalse;

		R_SyncRenderThread();
		R_SetColorMappings();
	}

    // check for errors
    if ( !r_ignoreGLErrors->integer ) {
        int	err;

		R_SyncRenderThread();
        if ( ( err = qglGetError() ) != GL_NO_ERROR ) {
            ri.Error( ERR_FATAL, "RE_BeginFrame() - glGetError() failed (0x%x)!\n", err );
        }
    }

	//
	// draw buffer stuff
	//
	cmd = (drawBufferCommand_t *) R_GetCommandBuffer( sizeof( *cmd ) );
	if ( !cmd ) {
		return;
	}
	cmd->commandId = RC_DRAW_BUFFER;

	if ( glConfig.stereoEnabled ) {
		if ( stereoFrame == STEREO_LEFT ) {
			cmd->buffer = (int)GL_BACK_LEFT;
		} else if ( stereoFrame == STEREO_RIGHT ) {
			cmd->buffer = (int)GL_BACK_RIGHT;
		} else {
			ri.Error( ERR_FATAL, "RE_BeginFrame: Stereo is enabled, but stereoFrame was %i", stereoFrame );
		}
	} else {
		if ( stereoFrame != STEREO_CENTER ) {
			ri.Error( ERR_FATAL, "RE_BeginFrame: Stereo is disabled, but stereoFrame was %i", stereoFrame );
		}
		if ( !Q_stricmp( r_drawBuffer->string, "GL_FRONT" ) ) {
			cmd->buffer = (int)GL_FRONT;
		} else {
			cmd->buffer = (int)GL_BACK;
		}
	}
}
Exemplo n.º 19
0
void CCamWnd::Cam_Draw()
{
	brush_t	*brush;
	face_t	*face;
	float	screenaspect;
	float	yfov;
	double	start, end;
	int		i;

	/*
  FILE *f = fopen("g:/nardo/raduffy/editorhack.dat", "w");
  if (f != NULL) {
    fwrite(&m_Camera.origin[0], sizeof(float), 1, f);
    fwrite(&m_Camera.origin[1], sizeof(float), 1, f);
    fwrite(&m_Camera.origin[2], sizeof(float), 1, f);
		fwrite(&m_Camera.angles[PITCH], sizeof(float), 1, f);
		fwrite(&m_Camera.angles[YAW], sizeof(float), 1, f);
    fclose(f);
  }
	*/
	
	if (!active_brushes.next)
		return;	// not valid yet
	
	if (m_Camera.timing)
		start = Sys_DoubleTime ();
	
	//
	// clear
	//
	QE_CheckOpenGLForErrors();
	
	qglViewport(0, 0, m_Camera.width, m_Camera.height);
	qglScissor(0, 0, m_Camera.width, m_Camera.height);
	qglClearColor (g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][0],
		g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][1],
		g_qeglobals.d_savedinfo.colors[COLOR_CAMERABACK][2], 0);
	qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	
	//
	// set up viewpoint
	//
	vec5_t lightPos;
	
	if (g_PrefsDlg.m_bGLLighting)
	{
		qglEnable(GL_LIGHTING);
		//qglEnable(GL_LIGHT0);
		
		lightPos[0] = lightPos[1] = lightPos[2] = 3.5;
		lightPos[3] = 1.0;
		qglLightModelfv(GL_LIGHT_MODEL_AMBIENT, lightPos);
		//qglLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);
		//lightPos[0] = lightPos[1] = lightPos[2] = 3.5;
    //qglLightfv(GL_LIGHT0, GL_AMBIENT, lightPos);
	}
	else
	{
		qglDisable(GL_LIGHTING);
	}
	
	qglMatrixMode(GL_PROJECTION);
	qglLoadIdentity ();
	
	screenaspect = (float)m_Camera.width / m_Camera.height;
	yfov = 2*atan((float)m_Camera.height / m_Camera.width)*180/Q_PI;
	qgluPerspective (yfov,  screenaspect,  2,  8192);
	
	qglRotatef (-90,  1, 0, 0);	    // put Z going up
	qglRotatef (90,  0, 0, 1);	    // put Z going up
	qglRotatef (m_Camera.angles[0],  0, 1, 0);
	qglRotatef (-m_Camera.angles[1],  0, 0, 1);
	qglTranslatef (-m_Camera.origin[0],  -m_Camera.origin[1],  -m_Camera.origin[2]);
	
	Cam_BuildMatrix ();
	
	
	//if (m_Camera.draw_mode == cd_light)
	//{
//	if (g_PrefsDlg.m_bGLLighting)
//	{
//		VectorCopy(m_Camera.origin, lightPos);
//		lightPos[3] = 1;
//		qglLightfv(GL_LIGHT0, GL_POSITION, lightPos);
//	}
	//}
	
	InitCull ();
	
	//
	// draw stuff
	//
	GLfloat lAmbient[] = {1.0, 1.0, 1.0, 1.0};
	
	switch (m_Camera.draw_mode)
	{
	case cd_wire:
		qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
		qglDisable(GL_TEXTURE_2D);
		qglDisable(GL_TEXTURE_1D);
		qglDisable(GL_BLEND);
		qglDisable(GL_DEPTH_TEST);
		qglColor3f(1.0, 1.0, 1.0);
		//		qglEnable (GL_LINE_SMOOTH);
		break;
		
	case cd_solid:
		qglCullFace(GL_FRONT);
		qglEnable(GL_CULL_FACE);
		qglShadeModel (GL_FLAT);
		qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
		qglDisable(GL_TEXTURE_2D);
		qglDisable(GL_BLEND);
		qglEnable(GL_DEPTH_TEST);
		qglDepthFunc (GL_LEQUAL);
		break;
		
	case cd_texture:
		qglCullFace(GL_FRONT);
		qglEnable(GL_CULL_FACE);
		qglShadeModel (GL_FLAT);
		qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
		qglEnable(GL_TEXTURE_2D);
		qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		qglDisable(GL_BLEND);
		qglEnable(GL_DEPTH_TEST);
		qglDepthFunc (GL_LEQUAL);
		break;
		
	case cd_blend:
		qglCullFace(GL_FRONT);
		qglEnable(GL_CULL_FACE);
		qglShadeModel (GL_FLAT);
		qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
		qglEnable(GL_TEXTURE_2D);
		qglTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
		qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		qglDisable(GL_DEPTH_TEST);
		qglEnable (GL_BLEND);
		qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		break;
	}
	
	qglMatrixMode(GL_TEXTURE);
	
	m_nNumTransBrushes = 0;
	
	for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next)
	{
		//DrawLightRadius(brush);
		
		if (CullBrush (brush))
			continue;
		
		if (FilterBrush (brush))
			continue;
		
		if ((brush->brush_faces->texdef.flags & (SURF_TRANS33 | SURF_TRANS66)) || (brush->brush_faces->d_texture->bFromShader && brush->brush_faces->d_texture->fTrans != 1.0))
		{
			m_TransBrushes [ m_nNumTransBrushes++ ] = brush;
		} 
		else 
		{
			//--      if (brush->patchBrush)
			//--			  m_TransBrushes [ m_nNumTransBrushes++ ] = brush;
			//--      else
			Brush_Draw(brush);
		}
		
		
	}
	
	if (g_PrefsDlg.m_bGLLighting)
	{
		qglDisable (GL_LIGHTING);
	}
	
	//
	//qglDepthMask ( 0 ); // Don't write to depth buffer
	qglEnable ( GL_BLEND );
	qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	for ( i = 0; i < m_nNumTransBrushes; i++ ) 
		Brush_Draw (m_TransBrushes[i]);
	
	//qglDepthMask ( 1 ); // Ok, write now
	
	qglMatrixMode(GL_PROJECTION);
	
	//
	// now draw selected brushes
	//
	
	if (g_PrefsDlg.m_bGLLighting)
	{
		qglEnable (GL_LIGHTING);
	}
	
	qglTranslatef (g_qeglobals.d_select_translate[0], g_qeglobals.d_select_translate[1], g_qeglobals.d_select_translate[2]);
	qglMatrixMode(GL_TEXTURE);
	
	brush_t* pList = (g_bClipMode && g_pSplitList) ? g_pSplitList : &selected_brushes;
	// draw normally
	for (brush = pList->next ; brush != pList ; brush=brush->next)
	{
		//DrawLightRadius(brush);
		//if (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint)
		//  continue;
		
		Brush_Draw(brush);
	}
	
	// blend on top
	qglMatrixMode(GL_PROJECTION);
	
	
	qglDisable (GL_LIGHTING);
	qglColor4f(1.0, 0.0, 0.0, 0.3);
	qglEnable (GL_BLEND);
	qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
	qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	qglDisable (GL_TEXTURE_2D);
	for (brush = pList->next ; brush != pList ; brush=brush->next)
	{
		if ( (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint) || 
			(brush->terrainBrush && g_qeglobals.d_select_mode == sel_terrainpoint) )
			continue;
		
		for (face=brush->brush_faces ; face ; face=face->next)
			Face_Draw( face );
	}
	
 
  int nCount = g_ptrSelectedFaces.GetSize();
	if (nCount > 0)
  {
    for (int i = 0; i < nCount; i++)
    {
      face_t *selFace = reinterpret_cast<face_t*>(g_ptrSelectedFaces.GetAt(i));
		  Face_Draw(selFace);
    }
  }
		
	// non-zbuffered outline
	
	qglDisable (GL_BLEND);
	qglDisable (GL_DEPTH_TEST);
	qglPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
	qglColor3f (1, 1, 1);
	for (brush = pList->next ; brush != pList ; brush=brush->next)
	{
		if (g_qeglobals.dontDrawSelectedOutlines || (brush->patchBrush && g_qeglobals.d_select_mode == sel_curvepoint) ||
			(brush->terrainBrush && g_qeglobals.d_select_mode == sel_terrainpoint))
			continue;
		
		for (face=brush->brush_faces ; face ; face=face->next)
			Face_Draw( face );
	}
	
	
	// edge / vertex flags
	
	if (g_qeglobals.d_select_mode == sel_vertex)
	{
		qglPointSize (4);
		qglColor3f (0,1,0);
		qglBegin (GL_POINTS);
		for (i=0 ; i<g_qeglobals.d_numpoints ; i++)
			qglVertex3fv (g_qeglobals.d_points[i]);
		qglEnd ();
		qglPointSize (1);
	}
	else if (g_qeglobals.d_select_mode == sel_edge)
	{
		float	*v1, *v2;
		
		qglPointSize (4);
		qglColor3f (0,0,1);
		qglBegin (GL_POINTS);
		for (i=0 ; i<g_qeglobals.d_numedges ; i++)
		{
			v1 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p1];
			v2 = g_qeglobals.d_points[g_qeglobals.d_edges[i].p2];
			qglVertex3f ( (v1[0]+v2[0])*0.5,(v1[1]+v2[1])*0.5,(v1[2]+v2[2])*0.5);
		}
		qglEnd ();
		qglPointSize (1);
	}
	
	
	g_splineList->draw(static_cast<qboolean>(g_qeglobals.d_select_mode == sel_addpoint || g_qeglobals.d_select_mode == sel_editpoint));
	if (g_qeglobals.selectObject && (g_qeglobals.d_select_mode == sel_addpoint || g_qeglobals.d_select_mode == sel_editpoint)) {
		g_qeglobals.selectObject->drawSelection();
	}

	//
	// draw pointfile
	//

	qglEnable(GL_DEPTH_TEST);
	

	DrawPathLines ();
	
	
	
	if (g_qeglobals.d_pointfile_display_list)
	{
		Pointfile_Draw();
		//		glCallList (g_qeglobals.d_pointfile_display_list);
	}
	
	// bind back to the default texture so that we don't have problems
	// elsewhere using/modifying texture maps between contexts
	qglBindTexture( GL_TEXTURE_2D, 0 );
	
#if 0
	// area selection hack
	if (g_qeglobals.d_select_mode == sel_area)
	{
		qglEnable (GL_BLEND);
		qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		qglColor4f(0.0, 0.0, 1.0, 0.25);
		qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
		qglRectfv(g_qeglobals.d_vAreaTL, g_qeglobals.d_vAreaBR);
		qglDisable (GL_BLEND);
	}
#endif
	
	qglFinish();
	QE_CheckOpenGLForErrors();
	//	Sys_EndWait();
	if (m_Camera.timing)
	{
		end = Sys_DoubleTime ();
		Sys_Printf ("Camera: %i ms\n", (int)(1000*(end-start)));
	}
}
Exemplo n.º 20
0
/*
 * RB_GLSL_IterateStagesGeneric
 * Iterate over each stage of a shader
 */
static void RB_GLSL_IterateStagesGeneric(shaderCommands_t *input) {
	int	stage;

	for(stage = 0; stage < MAX_SHADER_STAGES; stage++) {
		shaderStage_t	*pStage = tess.xstages[stage];
		glslProgram_t	*program;

		if (!pStage || pStage->program == tr.skipProgram)
			break;

		/* set state */
		GL_State(pStage->stateBits);

		/*
		 * this is an ugly hack to work around a GeForce driver
		 * bug with multitexture and clip planes
		 */
		if (backEnd.viewParms.isPortal)
			qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

		if (pStage->program)
			/* use specified program */
			R_GLSL_UseProgram(pStage->program);
		else
			/* use default program */
			R_GLSL_UseProgram(tr.defaultProgram);

		program = tr.programs[glState.currentProgram];

		/* alphaGen */
		if (program->u_AlphaGen > -1)
			R_GLSL_SetUniform_AlphaGen(program, pStage->alphaGen);

		/* ambient light */
		if (program->u_AmbientLight > -1)
			R_GLSL_SetUniform_AmbientLight(program, backEnd.currentEntity->ambientLight);

		/* dynamic light */
		if (program->u_DynamicLight > -1)
			R_GLSL_SetUniform_DynamicLight(program, backEnd.currentEntity->dynamicLight);

		/* light distance */
		if (program->u_LightDistance > -1)
			R_GLSL_SetUniform_LightDistance(program, backEnd.currentEntity->lightDistance);

		/* rgbGen */
		if (program->u_ColorGen > -1)
			R_GLSL_SetUniform_ColorGen(program, pStage->rgbGen);

		/* constant color */
		if (program->u_ConstantColor > -1)
			R_GLSL_SetUniform_ConstantColor(program, pStage->constantColor);

		/* directed light */
		if (program->u_DirectedLight > -1)
			R_GLSL_SetUniform_DirectedLight(program, backEnd.currentEntity->directedLight);

		/* entity color */
		if (program->u_EntityColor > -1)
			R_GLSL_SetUniform_EntityColor(program, backEnd.currentEntity->e.shaderRGBA);

		/* fog color */
		if (program->u_FogColor > -1 && tess.fogNum)
			R_GLSL_SetUniform_FogColor(program, (tr.world->fogs + tess.fogNum)->colorInt);

		/* greyscale */
		if (program->u_Greyscale > -1)
			R_GLSL_SetUniform_Greyscale(program, r_greyscale->integer);

		/* identity light */
		if (program->u_IdentityLight > -1)
			R_GLSL_SetUniform_IdentityLight(program, tr.identityLight);

		/* light direction */
		if (program->u_LightDirection > -1)
			R_GLSL_SetUniform_LightDirection(program, backEnd.currentEntity->lightDir);

		/* model view matrix */
		if (program->u_ModelViewMatrix > -1)
			R_GLSL_SetUniform_ModelViewMatrix(program, glState.currentModelViewMatrix);

		/* model view projection matrix */
		if (program->u_ModelViewProjectionMatrix > -1)
			R_GLSL_SetUniform_ModelViewProjectionMatrix(program, glState.currentModelViewProjectionMatrix);

		/* projection matrix */
		if (program->u_ProjectionMatrix > -1)
			R_GLSL_SetUniform_ProjectionMatrix(program, glState.currentProjectionMatrix);

		/* texture coordinates 0 */
		if (program->u_TCGen0 > -1)
			R_GLSL_SetUniform_TCGen0(program, pStage->bundle[0].tcGen);

		/* texture coordinates 1 */
		if (program->u_TCGen1 > -1)
			R_GLSL_SetUniform_TCGen1(program, pStage->bundle[1].tcGen);

		/* tex env */
		if (program->u_TexEnv > -1) {
			if (r_lightmap->integer)
				R_GLSL_SetUniform_TexEnv(program, GL_REPLACE);
			else
				R_GLSL_SetUniform_TexEnv(program, input->shader->multitextureEnv);
		}

		/* texture unit 0 */
		if (program->u_Texture0 > -1 && pStage->bundle[0].image[0]) {
			GL_SelectTexture(0);

			if (pStage->bundle[0].vertexLightmap && ((r_vertexLight->integer && !r_uiFullScreen->integer) || glConfig.hardwareType == GLHW_PERMEDIA2) && r_lightmap->integer)
				GL_Bind(tr.whiteImage);
			else
				R_BindAnimatedImage(&pStage->bundle[0]);
		}

		/* texture unit 1 */
		if (program->u_Texture1 > -1 && pStage->bundle[1].image[0]) {
			GL_SelectTexture(1);
			qglEnable(GL_TEXTURE_2D);
			R_BindAnimatedImage(&pStage->bundle[1]);
		}

		/* texture unit 2 */
		if (program->u_Texture2 > -1 && pStage->bundle[2].image[0]) {
			GL_SelectTexture(2);
			qglEnable(GL_TEXTURE_2D);
			R_BindAnimatedImage(&pStage->bundle[2]);
		}

		/* texture unit 3 */
		if (program->u_Texture3 > -1 && pStage->bundle[3].image[0]) {
			GL_SelectTexture(3);
			qglEnable(GL_TEXTURE_2D);
			R_BindAnimatedImage(&pStage->bundle[3]);
		}

		/* texture unit 4 */
		if (program->u_Texture4 > -1 && pStage->bundle[4].image[0]) {
			GL_SelectTexture(4);
			qglEnable(GL_TEXTURE_2D);
			R_BindAnimatedImage(&pStage->bundle[4]);
		}

		/* texture unit 5 */
		if (program->u_Texture5 > -1 && pStage->bundle[5].image[0]) {
			GL_SelectTexture(5);
			qglEnable(GL_TEXTURE_2D);
			R_BindAnimatedImage(&pStage->bundle[5]);
		}

		/* texture unit 6 */
		if (program->u_Texture6 > -1 && pStage->bundle[6].image[0]) {
			GL_SelectTexture(6);
			qglEnable(GL_TEXTURE_2D);
			R_BindAnimatedImage(&pStage->bundle[6]);
		}

		/* texture unit 7 */
		if (program->u_Texture7 > -1 && pStage->bundle[7].image[0]) {
			GL_SelectTexture(7);
			qglEnable(GL_TEXTURE_2D);
			R_BindAnimatedImage(&pStage->bundle[7]);
		}

		/* time */
		if (program->u_Time > -1)
			R_GLSL_SetUniform_Time(program, input->shaderTime);

		/* view origin */
		if (program->u_ViewOrigin > -1)
			R_GLSL_SetUniform_ViewOrigin(program, backEnd.or.viewOrigin);

		/* draw */
		R_DrawElements(input->numIndexes, input->indexes);

		/* disable texture unit 7 */
		if (program->u_Texture7 > -1)
			qglDisable(GL_TEXTURE_2D);

		/* disable texture unit 6 */
		if (program->u_Texture6 > -1) {
			GL_SelectTexture(6);
			qglDisable(GL_TEXTURE_2D);
		}

		/* disable texture unit 5 */
		if (program->u_Texture5 > -1) {
			GL_SelectTexture(5);
			qglDisable(GL_TEXTURE_2D);
		}

		/* disable texture unit 4 */
		if (program->u_Texture4 > -1) {
			GL_SelectTexture(4);
			qglDisable(GL_TEXTURE_2D);
		}

		/* disable texture unit 3 */
		if (program->u_Texture3 > -1) {
			GL_SelectTexture(3);
			qglDisable(GL_TEXTURE_2D);
		}

		/* disable texture unit 2 */
		if (program->u_Texture2 > -1) {
			GL_SelectTexture(2);
			qglDisable(GL_TEXTURE_2D);
		}

		/* disable texture unit 1 */
		if (program->u_Texture1 > -1) {
			GL_SelectTexture(1);
			qglDisable(GL_TEXTURE_2D);
			qglDisableClientState(GL_TEXTURE_COORD_ARRAY);
		}

		/* switch to texture unit 0 */
		GL_SelectTexture(0);

		/* allow skipping out to show just lightmaps during development */
		if (r_lightmap->integer && (pStage->bundle[0].isLightmap || pStage->bundle[1].isLightmap || pStage->bundle[0].vertexLightmap))
			break;
	}

	/* switch to standard rendering pipeline */
	R_GLSL_UseProgram(0);
}
Exemplo n.º 21
0
/*
=================
RB_BeginDrawingView

Any mirrored or portaled views have already been drawn, so prepare
to actually render the visible surfaces for this view
=================
*/
void RB_BeginDrawingView (void) {
	int clearBits = 0;

	// sync with gl if needed
	if ( r_finish->integer == 1 && !glState.finishCalled ) {
		qglFinish ();
		glState.finishCalled = qtrue;
	}
	if ( r_finish->integer == 0 ) {
		glState.finishCalled = qtrue;
	}

	// we will need to change the projection matrix before drawing
	// 2D images again
	backEnd.projection2D = qfalse;

	// ensures that depth writes are enabled for the depth clear
	GL_State( GLS_DEFAULT );
	// clear relevant buffers
	clearBits = GL_DEPTH_BUFFER_BIT;

	if ( r_measureOverdraw->integer || r_shadows->integer == 2 )
	{
		clearBits |= GL_STENCIL_BUFFER_BIT;
	}
	if ( r_fastsky->integer && !( backEnd.refdef.rdflags & RDF_NOWORLDMODEL ) )
	{
		clearBits |= GL_COLOR_BUFFER_BIT;	// FIXME: only if sky shaders have been used
#ifdef _DEBUG
		qglClearColor( 0.8f, 0.7f, 0.4f, 1.0f );	// FIXME: get color of sky
#else
		qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f );	// FIXME: get color of sky
#endif
	}
	qglClear( clearBits );

	//
	// set the modelview matrix for the viewer
	//
	SetViewportAndScissor();

	if ( ( backEnd.refdef.rdflags & RDF_HYPERSPACE ) )
	{
		RB_Hyperspace();
		return;
	}
	else
	{
		backEnd.isHyperspace = qfalse;
	}

	glState.faceCulling = -1;		// force face culling to set next time

	// we will only draw a sun if there was sky rendered in this view
	backEnd.skyRenderedThisView = qfalse;

	// clip to the plane of the portal
	if ( backEnd.viewParms.isPortal ) {
		float	plane[4];
		double	plane2[4];

		plane[0] = backEnd.viewParms.portalPlane.normal[0];
		plane[1] = backEnd.viewParms.portalPlane.normal[1];
		plane[2] = backEnd.viewParms.portalPlane.normal[2];
		plane[3] = backEnd.viewParms.portalPlane.dist;

		plane2[0] = DotProduct (backEnd.viewParms.or.axis[0], plane);
		plane2[1] = DotProduct (backEnd.viewParms.or.axis[1], plane);
		plane2[2] = DotProduct (backEnd.viewParms.or.axis[2], plane);
		plane2[3] = DotProduct (plane, backEnd.viewParms.or.origin) - plane[3];

		qglLoadMatrixf( s_flipMatrix );
		Matrix4Copy(s_flipMatrix, glState.currentModelViewMatrix);
		Matrix4Multiply(glState.currentProjectionMatrix, glState.currentModelViewMatrix, glState.currentModelViewProjectionMatrix);
		qglClipPlane (GL_CLIP_PLANE0, plane2);
		qglEnable (GL_CLIP_PLANE0);
	} else {
		qglDisable (GL_CLIP_PLANE0);
	}
}
Exemplo n.º 22
0
/*
 * RB_GLSL_StageIteratorGeneric
 * Stage iterator for GLSL programs
 */
void RB_GLSL_StageIteratorGeneric(void) {
	shaderCommands_t	*input;

	input = &tess;

	/* log this call */
	if (r_logFile->integer) {
		/* don't just call LogComment, or we will get a call to va() every frame! */
		GLimp_LogComment(va("--- R_GLSL_StageIteratorGeneric( %s ) ---\n", input->shader->name));
	}

	/* set face culling appropiately */
	GL_Cull(input->shader->cullType);

	/* set polygon offset if necessary */
	if (input->shader->polygonOffset) {
		qglEnable(GL_POLYGON_OFFSET_FILL);
		qglPolygonOffset(r_offsetFactor->value, r_offsetUnits->value);
	}

	/* set vertex color array */
	qglEnableClientState(GL_COLOR_ARRAY);
	qglColorPointer(4, GL_UNSIGNED_BYTE, 0, input->vertexColors);

	/* set texture coordinate array 0 */
	GL_SelectTexture(0);
	qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
	qglTexCoordPointer(2, GL_FLOAT, 16, input->texCoords[0][0]);

	/* set texture coordinate array 1 */
	GL_SelectTexture(1);
	qglEnableClientState(GL_TEXTURE_COORD_ARRAY);
	qglTexCoordPointer(2, GL_FLOAT, 16, input->texCoords[0][1]);

	/* set vertex normal array */
	qglEnableClientState(GL_NORMAL_ARRAY);
	qglNormalPointer(GL_FLOAT, 16, input->normal);

	/* lock XYZ */
	qglVertexPointer(3, GL_FLOAT, 16, input->xyz); /* padded SIMD */
	if (qglLockArraysEXT) {
		qglLockArraysEXT(0, input->numVertexes);
		GLimp_LogComment("glLockArraysEXT\n");
	}

	RB_GLSL_IterateStagesGeneric(input);

	/* now do any dynamic lighting needed */
	if (input->dlightBits && input->shader->sort <= SS_OPAQUE && !(input->shader->surfaceFlags & (SURF_NODLIGHT | SURF_SKY)))
		ProjectDlightTexture();

	// <-- RiO_Outlines: now do outlines
	RB_OutlinesPass();
	// -->

	/* now do fog */
	if (input->fogNum && input->shader->fogPass)
		RB_FogPass(); // TODO: uses svars which aren't set, so move to program

	/* unlock arrays */
	if (qglUnlockArraysEXT) {
		qglUnlockArraysEXT();
		GLimp_LogComment("glUnlockArraysExt\n");
	}

	/* reset polygon offset */
	if (input->shader->polygonOffset)
		qglDisable(GL_POLYGON_OFFSET_FILL);
}
Exemplo n.º 23
0
void RB_DistortionFill(void)
{
	float alpha = tr_distortionAlpha;
	float spost = 0.0f;
	float spost2 = 0.0f;

	if ( glConfig.stencilBits < 4 )
	{
		return;
	}

	//ok, cap the stupid thing now I guess
	if (!tr_distortionPrePost)
	{
		RB_CaptureScreenImage();
	}

	qglEnable(GL_STENCIL_TEST);
	qglStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
	qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

	qglDisable (GL_CLIP_PLANE0);
	GL_Cull( CT_TWO_SIDED );

	//reset the view matrices and go into ortho mode
	qglMatrixMode(GL_PROJECTION);
	qglPushMatrix();
	qglLoadIdentity();
	qglOrtho(0, glConfig.vidWidth, glConfig.vidHeight, 32, -1, 1);
	qglMatrixMode(GL_MODELVIEW);
	qglPushMatrix();
	qglLoadIdentity();

	if (tr_distortionStretch)
	{ //override
		spost = tr_distortionStretch;
		spost2 = tr_distortionStretch;
	}
	else
	{ //do slow stretchy effect
		spost = sin(tr.refdef.time*0.0005f);
		if (spost < 0.0f)
		{
			spost = -spost;
		}
		spost *= 0.2f;

		spost2 = sin(tr.refdef.time*0.0005f);
		if (spost2 < 0.0f)
		{
			spost2 = -spost2;
		}
		spost2 *= 0.08f;
	}

	if (alpha != 1.0f)
	{ //blend
		GL_State(GLS_SRCBLEND_SRC_ALPHA|GLS_DSTBLEND_SRC_ALPHA);
	}
	else
	{ //be sure to reset the draw state
		GL_State(0);
	}

	qglBegin(GL_QUADS);
		qglColor4f(1.0f, 1.0f, 1.0f, alpha);
		qglTexCoord2f(0+spost2, 1-spost);
		qglVertex2f(0, 0);

		qglTexCoord2f(0+spost2, 0+spost);
		qglVertex2f(0, glConfig.vidHeight);

		qglTexCoord2f(1-spost2, 0+spost);
		qglVertex2f(glConfig.vidWidth, glConfig.vidHeight);

		qglTexCoord2f(1-spost2, 1-spost);
		qglVertex2f(glConfig.vidWidth, 0);
	qglEnd();

	if (tr_distortionAlpha == 1.0f && tr_distortionStretch == 0.0f)
	{ //no overrides
		if (tr_distortionNegate)
		{ //probably the crazy alternate saber trail
			alpha = 0.8f;
			GL_State(GLS_SRCBLEND_ZERO|GLS_DSTBLEND_ONE_MINUS_SRC_COLOR);
		}
		else
		{
			alpha = 0.5f;
			GL_State(GLS_SRCBLEND_SRC_ALPHA|GLS_DSTBLEND_SRC_ALPHA);
		}

		spost = sin(tr.refdef.time*0.0008f);
		if (spost < 0.0f)
		{
			spost = -spost;
		}
		spost *= 0.08f;

		spost2 = sin(tr.refdef.time*0.0008f);
		if (spost2 < 0.0f)
		{
			spost2 = -spost2;
		}
		spost2 *= 0.2f;

		qglBegin(GL_QUADS);
			qglColor4f(1.0f, 1.0f, 1.0f, alpha);
			qglTexCoord2f(0+spost2, 1-spost);
			qglVertex2f(0, 0);

			qglTexCoord2f(0+spost2, 0+spost);
			qglVertex2f(0, glConfig.vidHeight);

			qglTexCoord2f(1-spost2, 0+spost);
			qglVertex2f(glConfig.vidWidth, glConfig.vidHeight);

			qglTexCoord2f(1-spost2, 1-spost);
			qglVertex2f(glConfig.vidWidth, 0);
		qglEnd();
	}

	//pop the view matrices back
	qglMatrixMode(GL_PROJECTION);
	qglPopMatrix();
	qglMatrixMode(GL_MODELVIEW);
	qglPopMatrix();

	qglDisable( GL_STENCIL_TEST );
}
Exemplo n.º 24
0
Arquivo: gl_draw.c Projeto: ZwS/qudos
void
Draw_ScaledPic(int x, int y, float scale, float alpha, char *pic, float red, float green, float blue, qboolean fixcoords, qboolean repscale)
{
	float		xoff, yoff;
	image_t        *gl;

	gl = Draw_FindPic(pic);
	if (!gl) {
		ri.Con_Printf(PRINT_ALL, "Can't find pic: %s\n", pic);
		return;
	}
	if (scrap_dirty)
		Scrap_Upload();

	if (((gl_config.renderer == GL_RENDERER_MCD) || (gl_config.renderer & GL_RENDERER_RENDITION)) && !gl->has_alpha)
		qglDisable(GL_ALPHA_TEST);

	/* add alpha support */
	{
		qglDisable(GL_ALPHA_TEST);

		qglBindTexture(GL_TEXTURE_2D, gl->texnum);

		GL_TexEnv(GL_MODULATE);
		qglColor4f(red, green, blue, alpha);
		qglEnable(GL_BLEND);
		qglDepthMask(false);
	}

	/* NOTE: replace this with shaders as soon as they are supported */
	if (repscale)
		scale *= gl->replace_scale;	/* scale down if replacing a pcx image */

	if (fixcoords) {	/* Knightmare- whether to adjust coordinates for scaling */

		xoff = (gl->width * scale - gl->width) / 2;
		yoff = (gl->height * scale - gl->height) / 2;

		GL_Bind(gl->texnum);
		qglBegin(GL_QUADS);
		qglTexCoord2f(gl->sl, gl->tl);
		qglVertex2f(x - xoff, y - yoff);
		qglTexCoord2f(gl->sh, gl->tl);
		qglVertex2f(x + gl->width + xoff, y - yoff);
		qglTexCoord2f(gl->sh, gl->th);
		qglVertex2f(x + gl->width + xoff, y + gl->height + yoff);
		qglTexCoord2f(gl->sl, gl->th);
		qglVertex2f(x - xoff, y + gl->height + yoff);
		qglEnd();

	} else {
		xoff = gl->width * scale - gl->width;
		yoff = gl->height * scale - gl->height;

		GL_Bind(gl->texnum);
		qglBegin(GL_QUADS);
		qglTexCoord2f(gl->sl, gl->tl);
		qglVertex2f(x, y);
		qglTexCoord2f(gl->sh, gl->tl);
		qglVertex2f(x + gl->width + xoff, y);
		qglTexCoord2f(gl->sh, gl->th);
		qglVertex2f(x + gl->width + xoff, y + gl->height + yoff);
		qglTexCoord2f(gl->sl, gl->th);
		qglVertex2f(x, y + gl->height + yoff);
		qglEnd();
	}

	/* add alpha support */
	{
		qglDepthMask(true);
		GL_TexEnv(GL_REPLACE);
		qglDisable(GL_BLEND);
		qglColor4f(1, 1, 1, 1);

		qglEnable(GL_ALPHA_TEST);
	}

	if (((gl_config.renderer == GL_RENDERER_MCD) || (gl_config.renderer & GL_RENDERER_RENDITION)) && !gl->has_alpha)
		qglEnable(GL_ALPHA_TEST);
}
Exemplo n.º 25
0
/*
** RB_StageIteratorVertexLitTexture
*/
void RB_StageIteratorVertexLitTexture( void ) {
	shaderCommands_t *input;
	shader_t        *shader;

	input = &tess;

	shader = input->shader;

	//
	// compute colors
	//
	RB_CalcDiffuseColor( ( unsigned char * ) tess.svars.colors );

	//
	// log this call
	//
	if ( r_logFile->integer ) {
		// don't just call LogComment, or we will get
		// a call to va() every frame!
		GLimp_LogComment( va( "--- RB_StageIteratorVertexLitTexturedUnfogged( %s ) ---\n", tess.shader->name ) );
	}


	// set GL fog
	SetIteratorFog();

	//
	// set face culling appropriately
	//
	GL_Cull( input->shader->cullType );

	//
	// set arrays and lock
	//
	qglEnableClientState( GL_COLOR_ARRAY );
	qglEnableClientState( GL_TEXTURE_COORD_ARRAY );

	if ( qglPNTrianglesiATI && tess.ATI_tess ) {
#ifdef __MACOS__    //DAJ ATI
		qglPNTrianglesiATI( GL_PN_TRIANGLES_ATI, 1 );
#else
		qglEnable( GL_PN_TRIANGLES_ATI ); // ATI PN-Triangles extension
#endif
		qglEnableClientState( GL_NORMAL_ARRAY );         // RF< so we can send the normals as an array
		qglNormalPointer( GL_FLOAT, 16, input->normal );
	}

	qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.svars.colors );
	qglTexCoordPointer( 2, GL_FLOAT, 16, tess.texCoords[0][0] );
	qglVertexPointer( 3, GL_FLOAT, 16, input->xyz );


	if ( qglLockArraysEXT ) {
		qglLockArraysEXT( 0, input->numVertexes );
		GLimp_LogComment( "glLockArraysEXT\n" );
	}

	//
	// call special shade routine
	//
	R_BindAnimatedImage( &tess.xstages[0]->bundle[0] );
	GL_State( tess.xstages[0]->stateBits );
	R_DrawElements( input->numIndexes, input->indexes );

	//
	// now do any dynamic lighting needed
	//
	if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE ) {
		ProjectDlightTexture();
	}

	//
	// now do fog
	//
	if ( tess.fogNum && tess.shader->fogPass ) {
		RB_FogPass();
	}

	//
	// unlock arrays
	//
	if ( qglUnlockArraysEXT ) {
		qglUnlockArraysEXT();
		GLimp_LogComment( "glUnlockArraysEXT\n" );
	}

	if ( qglPNTrianglesiATI && tess.ATI_tess )
#ifdef __MACOS__ //DAJ ATI{
		qglPNTrianglesiATI( GL_PN_TRIANGLES_ATI, 0 );
	}
Exemplo n.º 26
0
/*
** GL_SetDefaultState
*/
void GL_SetDefaultState( void ) {
	qglClearDepth( 1.0f );

	qglCullFace( GL_FRONT );

	qglColor4f( 1,1,1,1 );

	// initialize downstream texture unit if we're running
	// in a multitexture environment
	if ( qglActiveTextureARB ) {
		GL_SelectTexture( 1 );
		GL_TextureMode( r_textureMode->string );
		GL_TexEnv( GL_MODULATE );
		qglDisable( GL_TEXTURE_2D );
		GL_SelectTexture( 0 );
	}

	qglEnable( GL_TEXTURE_2D );
	GL_TextureMode( r_textureMode->string );
	GL_TexEnv( GL_MODULATE );

	qglShadeModel( GL_SMOOTH );
	qglDepthFunc( GL_LEQUAL );

	// the vertex array is always enabled, but the color and texture
	// arrays are enabled and disabled around the compiled vertex array call
	qglEnableClientState( GL_VERTEX_ARRAY );

	//
	// make sure our GL state vector is set correctly
	//
	glState.glStateBits = GLS_DEPTHTEST_DISABLE | GLS_DEPTHMASK_TRUE;

#ifndef VCMODS_OPENGLES
	qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
#endif
	qglDepthMask( GL_TRUE );
	qglDisable( GL_DEPTH_TEST );
	qglEnable( GL_SCISSOR_TEST );
	qglDisable( GL_CULL_FACE );
	qglDisable( GL_BLEND );

#ifndef VCMODS_OPENGLES
//----(SA)	added.
	// ATI pn_triangles
	if ( qglPNTrianglesiATI ) {
		int maxtess;
		// get max supported tesselation
		qglGetIntegerv( GL_MAX_PN_TRIANGLES_TESSELATION_LEVEL_ATI, (GLint*)&maxtess );
		glConfig.ATIMaxTruformTess = maxtess;
		// cap if necessary
		if ( r_ati_truform_tess->value > maxtess ) {
			ri.Cvar_Set( "r_ati_truform_tess", va( "%d", maxtess ) );
		}

		// set Wolf defaults
		qglPNTrianglesiATI( GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI, r_ati_truform_tess->value );
	}

	if ( glConfig.anisotropicAvailable ) {
		float maxAnisotropy;

		qglGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &maxAnisotropy );
		glConfig.maxAnisotropy = maxAnisotropy;

		// set when rendering
//	   qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, glConfig.maxAnisotropy);
	}

//----(SA)	end
#endif
	
}
Exemplo n.º 27
0
void RB_StageIteratorLightmappedMultitexture( void ) {
    shaderCommands_t *input;
    shader_t		*shader;

    input = &tess;
    shader = input->shader;

    //
    // log this call
    //
    if ( r_logFile->integer ) {
        // don't just call LogComment, or we will get
        // a call to va() every frame!
        GLimp_LogComment( va("--- RB_StageIteratorLightmappedMultitexture( %s ) ---\n", tess.shader->name) );
    }

    //
    // set face culling appropriately
    //
    GL_Cull( shader->cullType );

    //
    // set color, pointers, and lock
    //
    GL_State( GLS_DEFAULT );
    qglVertexPointer( 3, GL_FLOAT, 16, input->xyz );

#ifdef REPLACE_MODE
    qglDisableClientState( GL_COLOR_ARRAY );
    qglColor3f( 1, 1, 1 );
    qglShadeModel( GL_FLAT );
#else
    qglEnableClientState( GL_COLOR_ARRAY );
    qglColorPointer( 4, GL_UNSIGNED_BYTE, 0, tess.constantColor255 );
#endif

    //
    // select base stage
    //
    GL_SelectTexture( 0 );

    qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
    R_BindAnimatedImage( &tess.xstages[0]->bundle[0] );
    qglTexCoordPointer( 2, GL_FLOAT, 16, tess.texCoords[0][0] );

    //
    // configure second stage
    //
    GL_SelectTexture( 1 );
    qglEnable( GL_TEXTURE_2D );
    if ( r_lightmap->integer ) {
        GL_TexEnv( GL_REPLACE );
    } else {
        GL_TexEnv( GL_MODULATE );
    }
    R_BindAnimatedImage( &tess.xstages[0]->bundle[1] );
    qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
    qglTexCoordPointer( 2, GL_FLOAT, 16, tess.texCoords[0][1] );

    //
    // lock arrays
    //
    if ( qglLockArraysEXT ) {
        qglLockArraysEXT(0, input->numVertexes);
        GLimp_LogComment( "glLockArraysEXT\n" );
    }

    R_DrawElements( input->numIndexes, input->indexes );

    //
    // disable texturing on TEXTURE1, then select TEXTURE0
    //
    qglDisable( GL_TEXTURE_2D );
    qglDisableClientState( GL_TEXTURE_COORD_ARRAY );

    GL_SelectTexture( 0 );
#ifdef REPLACE_MODE
    GL_TexEnv( GL_MODULATE );
    qglShadeModel( GL_SMOOTH );
#endif

    //
    // now do any dynamic lighting needed
    //
    if ( tess.dlightBits && tess.shader->sort <= SS_OPAQUE ) {
        ProjectDlightTexture();
    }

    //
    // now do fog
    //
    if ( tess.fogNum && tess.shader->fogPass ) {
        RB_FogPass();
    }

    //
    // unlock arrays
    //
    if ( qglUnlockArraysEXT ) {
        qglUnlockArraysEXT();
        GLimp_LogComment( "glUnlockArraysEXT\n" );
    }
}
Exemplo n.º 28
0
/*
=================
RB_BeginDrawingView

Any mirrored or portaled views have already been drawn, so prepare
to actually render the visible surfaces for this view
=================
*/
void RB_BeginDrawingView( void ) {
	int clearBits = 0;

	// sync with gl if needed
	if ( r_finish->integer == 1 && !glState.finishCalled ) {
		qglFinish();
		glState.finishCalled = qtrue;
	}
	if ( r_finish->integer == 0 ) {
		glState.finishCalled = qtrue;
	}

	// we will need to change the projection matrix before drawing
	// 2D images again
	backEnd.projection2D = qfalse;

	//
	// set the modelview matrix for the viewer
	//
	SetViewportAndScissor();

	// ensures that depth writes are enabled for the depth clear
	GL_State( GLS_DEFAULT );


////////// (SA) modified to ensure one glclear() per frame at most

	// clear relevant buffers
	clearBits = 0;

	if ( r_measureOverdraw->integer || r_shadows->integer == 2 ) {
		clearBits |= GL_STENCIL_BUFFER_BIT;
	}

	if ( r_uiFullScreen->integer ) {
		clearBits = GL_DEPTH_BUFFER_BIT;    // (SA) always just clear depth for menus

	} else if ( skyboxportal ) {
		if ( backEnd.refdef.rdflags & RDF_SKYBOXPORTAL ) {   // portal scene, clear whatever is necessary
			clearBits |= GL_DEPTH_BUFFER_BIT;

			if ( r_fastsky->integer || backEnd.refdef.rdflags & RDF_NOWORLDMODEL ) {  // fastsky: clear color

				// try clearing first with the portal sky fog color, then the world fog color, then finally a default
				clearBits |= GL_COLOR_BUFFER_BIT;
				if ( glfogsettings[FOG_PORTALVIEW].registered ) {
					qglClearColor( glfogsettings[FOG_PORTALVIEW].color[0], glfogsettings[FOG_PORTALVIEW].color[1], glfogsettings[FOG_PORTALVIEW].color[2], glfogsettings[FOG_PORTALVIEW].color[3] );
				} else if ( glfogNum > FOG_NONE && glfogsettings[FOG_CURRENT].registered )      {
					qglClearColor( glfogsettings[FOG_CURRENT].color[0], glfogsettings[FOG_CURRENT].color[1], glfogsettings[FOG_CURRENT].color[2], glfogsettings[FOG_CURRENT].color[3] );
				} else {
//					qglClearColor ( 1.0, 0.0, 0.0, 1.0 );	// red clear for testing portal sky clear
					qglClearColor( 0.5, 0.5, 0.5, 1.0 );
				}
			} else {                                                    // rendered sky (either clear color or draw quake sky)
				if ( glfogsettings[FOG_PORTALVIEW].registered ) {
					qglClearColor( glfogsettings[FOG_PORTALVIEW].color[0], glfogsettings[FOG_PORTALVIEW].color[1], glfogsettings[FOG_PORTALVIEW].color[2], glfogsettings[FOG_PORTALVIEW].color[3] );

					if ( glfogsettings[FOG_PORTALVIEW].clearscreen ) {    // portal fog requests a screen clear (distance fog rather than quake sky)
						clearBits |= GL_COLOR_BUFFER_BIT;
					}
				}

			}
		} else {                                        // world scene with portal sky, don't clear any buffers, just set the fog color if there is one

			clearBits |= GL_DEPTH_BUFFER_BIT;   // this will go when I get the portal sky rendering way out in the zbuffer (or not writing to zbuffer at all)

			if ( glfogNum > FOG_NONE && glfogsettings[FOG_CURRENT].registered ) {
				if ( backEnd.refdef.rdflags & RDF_UNDERWATER ) {
					if ( glfogsettings[FOG_CURRENT].mode == GL_LINEAR ) {
						clearBits |= GL_COLOR_BUFFER_BIT;
					}

				} else if ( !( r_portalsky->integer ) ) {    // portal skies have been manually turned off, clear bg color
					clearBits |= GL_COLOR_BUFFER_BIT;
				}

				qglClearColor( glfogsettings[FOG_CURRENT].color[0], glfogsettings[FOG_CURRENT].color[1], glfogsettings[FOG_CURRENT].color[2], glfogsettings[FOG_CURRENT].color[3] );
			}
		}
	} else {                                              // world scene with no portal sky
		clearBits |= GL_DEPTH_BUFFER_BIT;

		// NERVE - SMF - we don't want to clear the buffer when no world model is specified
		if ( backEnd.refdef.rdflags & RDF_NOWORLDMODEL ) {
			clearBits &= ~GL_COLOR_BUFFER_BIT;
		}
		// -NERVE - SMF
		// (SA) well, this is silly then
		else if ( r_fastsky->integer ) {   //  || backEnd.refdef.rdflags & RDF_NOWORLDMODEL

			clearBits |= GL_COLOR_BUFFER_BIT;

			if ( glfogsettings[FOG_CURRENT].registered ) { // try to clear fastsky with current fog color
				qglClearColor( glfogsettings[FOG_CURRENT].color[0], glfogsettings[FOG_CURRENT].color[1], glfogsettings[FOG_CURRENT].color[2], glfogsettings[FOG_CURRENT].color[3] );
			} else {
//				qglClearColor ( 0.0, 0.0, 1.0, 1.0 );	// blue clear for testing world sky clear
				qglClearColor( 0.5, 0.5, 0.5, 1.0 );
			}
		} else {        // world scene, no portal sky, not fastsky, clear color if fog says to, otherwise, just set the clearcolor
			if ( glfogsettings[FOG_CURRENT].registered ) { // try to clear fastsky with current fog color
				qglClearColor( glfogsettings[FOG_CURRENT].color[0], glfogsettings[FOG_CURRENT].color[1], glfogsettings[FOG_CURRENT].color[2], glfogsettings[FOG_CURRENT].color[3] );

				if ( glfogsettings[FOG_CURRENT].clearscreen ) {   // world fog requests a screen clear (distance fog rather than quake sky)
					clearBits |= GL_COLOR_BUFFER_BIT;
				}
			}
		}
	}


	if ( clearBits ) {
		qglClear( clearBits );
	}

//----(SA)	done

	if ( ( backEnd.refdef.rdflags & RDF_HYPERSPACE ) ) {
		RB_Hyperspace();
		return;
	} else
	{
		backEnd.isHyperspace = qfalse;
	}

	glState.faceCulling = -1;       // force face culling to set next time

	// we will only draw a sun if there was sky rendered in this view
	backEnd.skyRenderedThisView = qfalse;

	// clip to the plane of the portal
	if ( backEnd.viewParms.isPortal ) {
		float plane[4];
		GLdouble plane2[4];

		plane[0] = backEnd.viewParms.portalPlane.normal[0];
		plane[1] = backEnd.viewParms.portalPlane.normal[1];
		plane[2] = backEnd.viewParms.portalPlane.normal[2];
		plane[3] = backEnd.viewParms.portalPlane.dist;

		plane2[0] = DotProduct( backEnd.viewParms.or.axis[0], plane );
		plane2[1] = DotProduct( backEnd.viewParms.or.axis[1], plane );
		plane2[2] = DotProduct( backEnd.viewParms.or.axis[2], plane );
		plane2[3] = DotProduct( plane, backEnd.viewParms.or.origin ) - plane[3];

		qglLoadMatrixf( s_flipMatrix );
		qglClipPlane( GL_CLIP_PLANE0, plane2 );
		qglEnable( GL_CLIP_PLANE0 );
	} else {
		qglDisable( GL_CLIP_PLANE0 );
	}
}
Exemplo n.º 29
0
/*
** GL_State
**
** This routine is responsible for setting the most commonly changed state
** in Q3.
*/
void GL_State( unsigned long stateBits )
{
    unsigned long diff = stateBits ^ glState.glStateBits;

    if ( !diff )
    {
        return;
    }

    //
    // check depthFunc bits
    //
    if ( diff & GLS_DEPTHFUNC_EQUAL )
    {
        if ( stateBits & GLS_DEPTHFUNC_EQUAL )
        {
            qglDepthFunc( GL_EQUAL );
        }
        else
        {
            qglDepthFunc( GL_LEQUAL );
        }
    }

    //
    // check blend bits
    //
    if ( diff & ( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ) )
    {
        GLenum srcFactor = GL_ONE, dstFactor = GL_ONE;

        if ( stateBits & ( GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS ) )
        {
            switch ( stateBits & GLS_SRCBLEND_BITS )
            {
            case GLS_SRCBLEND_ZERO:
                srcFactor = GL_ZERO;
                break;
            case GLS_SRCBLEND_ONE:
                srcFactor = GL_ONE;
                break;
            case GLS_SRCBLEND_DST_COLOR:
                srcFactor = GL_DST_COLOR;
                break;
            case GLS_SRCBLEND_ONE_MINUS_DST_COLOR:
                srcFactor = GL_ONE_MINUS_DST_COLOR;
                break;
            case GLS_SRCBLEND_SRC_ALPHA:
                srcFactor = GL_SRC_ALPHA;
                break;
            case GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA:
                srcFactor = GL_ONE_MINUS_SRC_ALPHA;
                break;
            case GLS_SRCBLEND_DST_ALPHA:
                srcFactor = GL_DST_ALPHA;
                break;
            case GLS_SRCBLEND_ONE_MINUS_DST_ALPHA:
                srcFactor = GL_ONE_MINUS_DST_ALPHA;
                break;
            case GLS_SRCBLEND_ALPHA_SATURATE:
                srcFactor = GL_SRC_ALPHA_SATURATE;
                break;
            default:
                ri.Error( ERR_DROP, "GL_State: invalid src blend state bits" );
                break;
            }

            switch ( stateBits & GLS_DSTBLEND_BITS )
            {
            case GLS_DSTBLEND_ZERO:
                dstFactor = GL_ZERO;
                break;
            case GLS_DSTBLEND_ONE:
                dstFactor = GL_ONE;
                break;
            case GLS_DSTBLEND_SRC_COLOR:
                dstFactor = GL_SRC_COLOR;
                break;
            case GLS_DSTBLEND_ONE_MINUS_SRC_COLOR:
                dstFactor = GL_ONE_MINUS_SRC_COLOR;
                break;
            case GLS_DSTBLEND_SRC_ALPHA:
                dstFactor = GL_SRC_ALPHA;
                break;
            case GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA:
                dstFactor = GL_ONE_MINUS_SRC_ALPHA;
                break;
            case GLS_DSTBLEND_DST_ALPHA:
                dstFactor = GL_DST_ALPHA;
                break;
            case GLS_DSTBLEND_ONE_MINUS_DST_ALPHA:
                dstFactor = GL_ONE_MINUS_DST_ALPHA;
                break;
            default:
                ri.Error( ERR_DROP, "GL_State: invalid dst blend state bits" );
                break;
            }

            qglEnable( GL_BLEND );
            qglBlendFunc( srcFactor, dstFactor );
        }
        else
        {
            qglDisable( GL_BLEND );
        }
    }

    //
    // check depthmask
    //
    if ( diff & GLS_DEPTHMASK_TRUE )
    {
        if ( stateBits & GLS_DEPTHMASK_TRUE )
        {
            qglDepthMask( GL_TRUE );
        }
        else
        {
            qglDepthMask( GL_FALSE );
        }
    }

    //
    // fill/line mode
    //
    if ( diff & GLS_POLYMODE_LINE )
    {
        if ( stateBits & GLS_POLYMODE_LINE )
        {
            qglPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
        }
        else
        {
            qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
        }
    }

    //
    // depthtest
    //
    if ( diff & GLS_DEPTHTEST_DISABLE )
    {
        if ( stateBits & GLS_DEPTHTEST_DISABLE )
        {
            qglDisable( GL_DEPTH_TEST );
        }
        else
        {
            qglEnable( GL_DEPTH_TEST );
        }
    }

    //
    // alpha test
    //
    if ( diff & GLS_ATEST_BITS )
    {
        switch ( stateBits & GLS_ATEST_BITS )
        {
        case 0:
            qglDisable( GL_ALPHA_TEST );
            break;
        case GLS_ATEST_GT_0:
            qglEnable( GL_ALPHA_TEST );
            qglAlphaFunc( GL_GREATER, 0.0f );
            break;
        case GLS_ATEST_LT_80:
            qglEnable( GL_ALPHA_TEST );
            qglAlphaFunc( GL_LESS, 0.5f );
            break;
        case GLS_ATEST_GE_80:
            qglEnable( GL_ALPHA_TEST );
            qglAlphaFunc( GL_GEQUAL, 0.5f );
            break;
        default:
            assert( 0 );
            break;
        }
    }

    glState.glStateBits = stateBits;
}
Exemplo n.º 30
0
/*
=================
RB_BeginDrawingView

Any mirrored or portaled views have already been drawn, so prepare
to actually render the visible surfaces for this view
=================
*/
static void RB_BeginDrawingView (void) {
	int clearBits = GL_DEPTH_BUFFER_BIT;

	// sync with gl if needed
	if ( r_finish->integer == 1 && !glState.finishCalled ) {
		qglFinish ();
		glState.finishCalled = qtrue;
	}
	if ( r_finish->integer == 0 ) {
		glState.finishCalled = qtrue;
	}

	// we will need to change the projection matrix before drawing
	// 2D images again
	backEnd.projection2D = qfalse;

	//
	// set the modelview matrix for the viewer
	//
	SetViewportAndScissor();

	// ensures that depth writes are enabled for the depth clear
	GL_State( GLS_DEFAULT );

	// clear relevant buffers
	if ( r_measureOverdraw->integer || r_shadows->integer == 2 || tr_stencilled )
	{
		clearBits |= GL_STENCIL_BUFFER_BIT;
		tr_stencilled = false;
	}

	if (skyboxportal)
	{
		if ( backEnd.refdef.rdflags & RDF_SKYBOXPORTAL )
		{	// portal scene, clear whatever is necessary
			if (r_fastsky->integer || (backEnd.refdef.rdflags & RDF_NOWORLDMODEL) )
			{	// fastsky: clear color
				// try clearing first with the portal sky fog color, then the world fog color, then finally a default
				clearBits |= GL_COLOR_BUFFER_BIT;
				if (tr.world && tr.world->globalFog != -1)
				{
					const fog_t		*fog = &tr.world->fogs[tr.world->globalFog];
					qglClearColor(fog->parms.color[0],  fog->parms.color[1], fog->parms.color[2], 1.0f );
				}
				else
				{
					qglClearColor ( 0.3f, 0.3f, 0.3f, 1.0 );
				}
			}			
		}
	}
	else
	{
		if ( r_fastsky->integer && !( backEnd.refdef.rdflags & RDF_NOWORLDMODEL ) && !g_bRenderGlowingObjects )
		{
			if (tr.world && tr.world->globalFog != -1)
			{
				const fog_t		*fog = &tr.world->fogs[tr.world->globalFog];
				qglClearColor(fog->parms.color[0],  fog->parms.color[1], fog->parms.color[2], 1.0f );
			}
			else
			{
				qglClearColor( 0.3f, 0.3f, 0.3f, 1 );	// FIXME: get color of sky
			}
			clearBits |= GL_COLOR_BUFFER_BIT;	// FIXME: only if sky shaders have been used
		}
	}

	if ( !( backEnd.refdef.rdflags & RDF_NOWORLDMODEL ) && ( r_DynamicGlow->integer && !g_bRenderGlowingObjects ) )
	{
		if (tr.world && tr.world->globalFog != -1)
		{ //this is because of a bug in multiple scenes I think, it needs to clear for the second scene but it doesn't normally.
			const fog_t		*fog = &tr.world->fogs[tr.world->globalFog];

			qglClearColor(fog->parms.color[0],  fog->parms.color[1], fog->parms.color[2], 1.0f );
			clearBits |= GL_COLOR_BUFFER_BIT;
		}
	}
	// If this pass is to just render the glowing objects, don't clear the depth buffer since
	// we're sharing it with the main scene (since the main scene has already been rendered). -AReis
	if ( g_bRenderGlowingObjects )
	{
		clearBits &= ~GL_DEPTH_BUFFER_BIT;
	}

	if (clearBits)
	{
		qglClear( clearBits );
	}

	if ( ( backEnd.refdef.rdflags & RDF_HYPERSPACE ) )
	{
		RB_Hyperspace();
		return;
	}
	else
	{
		backEnd.isHyperspace = qfalse;
	}

	glState.faceCulling = -1;		// force face culling to set next time

	// we will only draw a sun if there was sky rendered in this view
	backEnd.skyRenderedThisView = qfalse;

	// clip to the plane of the portal
	if ( backEnd.viewParms.isPortal ) {
		float	plane[4];
		double	plane2[4];

		plane[0] = backEnd.viewParms.portalPlane.normal[0];
		plane[1] = backEnd.viewParms.portalPlane.normal[1];
		plane[2] = backEnd.viewParms.portalPlane.normal[2];
		plane[3] = backEnd.viewParms.portalPlane.dist;

		plane2[0] = DotProduct (backEnd.viewParms.ori.axis[0], plane);
		plane2[1] = DotProduct (backEnd.viewParms.ori.axis[1], plane);
		plane2[2] = DotProduct (backEnd.viewParms.ori.axis[2], plane);
		plane2[3] = DotProduct (plane, backEnd.viewParms.ori.origin) - plane[3];

		qglLoadMatrixf( s_flipMatrix );
		qglClipPlane (GL_CLIP_PLANE0, plane2);
		qglEnable (GL_CLIP_PLANE0);
	} else {
		qglDisable (GL_CLIP_PLANE0);
	}
}