示例#1
0
/*
** RB_DrawSun
*/
void RB_DrawSun( float scale, shader_t *shader ) {
    float		size;
    float		dist;
    vec3_t		origin, vec1, vec2;
    byte		sunColor[4] = { 255, 255, 255, 255 };

    if ( !backEnd.skyRenderedThisView ) {
        return;
    }

    qglLoadMatrixf( backEnd.viewParms.world.modelMatrix );
    qglTranslatef (backEnd.viewParms.or.origin[0], backEnd.viewParms.or.origin[1], backEnd.viewParms.or.origin[2]);

    dist = 	backEnd.viewParms.zFar / 1.75;		// div sqrt(3)
    size = dist * scale;

    VectorScale( tr.sunDirection, dist, origin );
    PerpendicularVector( vec1, tr.sunDirection );
    CrossProduct( tr.sunDirection, vec1, vec2 );

    VectorScale( vec1, size, vec1 );
    VectorScale( vec2, size, vec2 );

    // farthest depth range
    qglDepthRange( 1.0, 1.0 );

    RB_BeginSurface( shader, 0 );

    RB_AddQuadStamp(origin, vec1, vec2, sunColor);

    RB_EndSurface();

    // back to normal depth range
    qglDepthRange( 0.0, 1.0 );
}
示例#2
0
/*
===============
RB_LeaveDepthHack
===============
*/
void RB_LeaveDepthHack() {
	qglDepthRange( 0, 1 );

	qglMatrixMode(GL_PROJECTION);
	qglLoadMatrixf( backEnd.viewDef->projectionMatrix );
	qglMatrixMode(GL_MODELVIEW);
}
示例#3
0
/*
======================
RB_BindStageTexture
======================
*/
void RB_BindStageTexture( const float *shaderRegisters, const textureStage_t *texture, const drawSurf_t *surf ) {
	// image
	RB_BindVariableStageImage( texture, shaderRegisters );

	// texgens
	if ( texture->texgen == TG_DIFFUSE_CUBE ) {
		qglTexCoordPointer( 3, GL_FLOAT, sizeof( idDrawVert ), ((idDrawVert *)vertexCache.Position( surf->geo->ambientCache ))->normal.ToFloatPtr() );
	}
	if ( texture->texgen == TG_SKYBOX_CUBE || texture->texgen == TG_WOBBLESKY_CUBE ) {
		qglTexCoordPointer( 3, GL_FLOAT, 0, vertexCache.Position( surf->dynamicTexCoords ) );
	}
	if ( texture->texgen == TG_REFLECT_CUBE ) {
		qglEnable( GL_TEXTURE_GEN_S );
		qglEnable( GL_TEXTURE_GEN_T );
		qglEnable( GL_TEXTURE_GEN_R );
		qglTexGenf( GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT );
		qglTexGenf( GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT );
		qglTexGenf( GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT );
		qglEnableClientState( GL_NORMAL_ARRAY );
		qglNormalPointer( GL_FLOAT, sizeof( idDrawVert ), ((idDrawVert *)vertexCache.Position( surf->geo->ambientCache ))->normal.ToFloatPtr() );

		qglMatrixMode( GL_TEXTURE );
		float	mat[16];

		R_TransposeGLMatrix( backEnd.viewDef->worldSpace.modelViewMatrix, mat );

		qglLoadMatrixf( mat );
		qglMatrixMode( GL_MODELVIEW );
	}

	// matrix
	if ( texture->hasMatrix ) {
		RB_LoadShaderTextureMatrix( shaderRegisters, texture );
	}
}
void RB_RenderWorldEffects(void)
{
	float					elapseTime = backEnd.refdef.frametime / 1000.0;

	if (tr.refdef.rdflags & RDF_NOWORLDMODEL || !tr.world || CL_IsRunningInGameCinematic()) 
	{	//  no world rendering or no world
		return;
	}

	SetViewportAndScissor();
	qglMatrixMode(GL_MODELVIEW);
//	qglPushMatrix();
	qglLoadMatrixf( backEnd.viewParms.world.modelMatrix );

	originContents = ri.CM_PointContents(backEnd.viewParms.or.origin, 0);

	if (rainSystem)
	{
		rainSystem->Update(elapseTime);
		rainSystem->Render();
	}

	if (snowSystem)
	{
		snowSystem->Update(elapseTime);
		snowSystem->Render();
	}

//	qglMatrixMode(GL_MODELVIEW);
//	qglPopMatrix();
}
示例#5
0
/*
======================
RB_LoadShaderTextureMatrix
======================
*/
void RB_LoadShaderTextureMatrix( const float *shaderRegisters, const textureStage_t *texture ) {
	float	matrix[16];

	RB_GetShaderTextureMatrix( shaderRegisters, texture, matrix );
	qglMatrixMode( GL_TEXTURE );
	qglLoadMatrixf( matrix );
	qglMatrixMode( GL_MODELVIEW );
}
示例#6
0
/*
===============
RB_EnterModelDepthHack
===============
*/
static void RB_EnterModelDepthHack( float depth ) {
	float matrix[16];

	memcpy( matrix, backEnd.viewDef->projectionMatrix, sizeof( matrix ) );

	matrix[14] -= depth;

	qglMatrixMode( GL_PROJECTION );
	qglLoadMatrixf( matrix );
	qglMatr
示例#7
0
void R_DrawAliasBatchPass (entity_t **ents, int numents, qbool showtris)
{
    int i;
    gltexture_t *lasttexture = NULL;
    gltexture_t *lastfullbright = NULL;

    if (!numents)
        return;

    if (showtris)
        GL_TexEnv (GL_TEXTURE0_ARB, GL_TEXTURE_2D, GL_REPLACE);
    else if (gl_overbright.value)
        GL_TexEnv (GL_TEXTURE0_ARB, GL_TEXTURE_2D, GL_RGB_SCALE_ARB);
    else
        GL_TexEnv (GL_TEXTURE0_ARB, GL_TEXTURE_2D, GL_MODULATE);

    for (i = 0; i < numents; i++)
    {
        entity_t *ent = ents[i];
        aliasstate_t *state = &ent->aliasstate;
        aliashdr_t *hdr = Mod_Extradata (ent->model);

        // we need a separate test for culling here as r_shadows mode doesn't cull
        if (ent->visframe != r_framecount)
            continue;

        if (!showtris && ((state->tx != lasttexture) || (state->fb != lastfullbright)))
        {
            if (state->fb)
            {
                GL_TexEnv (GL_TEXTURE1_ARB, GL_TEXTURE_2D, GL_ADD);
                GL_BindTexture (GL_TEXTURE1_ARB, state->fb);
            }
            else
                GL_TexEnv (GL_TEXTURE1_ARB, GL_TEXTURE_2D, GL_NONE);

            GL_BindTexture (GL_TEXTURE0_ARB, state->tx);

            lasttexture = state->tx;
            lastfullbright = state->fb;
        }

        // OK, this works better in GL... go figure...
        R_DrawAliasModel (ent, hdr, state, showtris);
    }

    GL_TexEnv (GL_TEXTURE1_ARB, GL_TEXTURE_2D, GL_NONE);
    GL_TexEnv (GL_TEXTURE0_ARB, GL_TEXTURE_2D, GL_REPLACE);

    qglColor4f (1, 1, 1, 1);

    // go back to the world matrix
    qglLoadMatrixf (r_world_matrix.m16);
}
/*
===============
RB_EnterModelDepthHack
===============
*/
void RB_EnterModelDepthHack( float depth ) {
	float matrix[16];
	qglDepthRange( 0.0f, 1.0f );
	memcpy( matrix, backEnd.viewDef->projectionMatrix, sizeof( matrix ) );

	matrix[14] -= depth;

	qglMatrixMode( GL_PROJECTION );
	qglLoadMatrixf( matrix );
	qglMatrixMode( GL_MODELVIEW );
}
/*
===============
RB_EnterWeaponDepthHack
===============
*/
void RB_EnterWeaponDepthHack() {
	float matrix[16];
	qglDepthRange( 0.0f, 0.5f );
	memcpy( matrix, backEnd.viewDef->projectionMatrix, sizeof( matrix ) );

	matrix[14] *= 0.25f;

	qglMatrixMode( GL_PROJECTION );
	qglLoadMatrixf( matrix );
	qglMatrixMode( GL_MODELVIEW );
}
示例#10
0
void SetViewportAndScissor( void ) {
	qglMatrixMode(GL_PROJECTION);
	qglLoadMatrixf( backEnd.viewParms.projectionMatrix );
	qglMatrixMode(GL_MODELVIEW);

	// set the window clipping
	qglViewport( backEnd.viewParms.viewportX, backEnd.viewParms.viewportY, 
		backEnd.viewParms.viewportWidth, backEnd.viewParms.viewportHeight );
	qglScissor( backEnd.viewParms.viewportX, backEnd.viewParms.viewportY, 
		backEnd.viewParms.viewportWidth, backEnd.viewParms.viewportHeight );
}
示例#11
0
/*
================
RB_SimpleWorldSetup
================
*/
static void RB_SimpleWorldSetup() {
	backEnd.currentSpace = &backEnd.viewDef->worldSpace;


	qglLoadMatrixf( backEnd.viewDef->worldSpace.modelViewMatrix );

	GL_Scissor( backEnd.viewDef->viewport.x1 + backEnd.viewDef->scissor.x1,
				backEnd.viewDef->viewport.y1 + backEnd.viewDef->scissor.y1,
				backEnd.viewDef->scissor.x2 + 1 - backEnd.viewDef->scissor.x1,
				backEnd.viewDef->scissor.y2 + 1 - backEnd.viewDef->scissor.y1 );
	backEnd.currentScissor = backEnd.viewDef->scissor;
}
示例#12
0
static void SetViewportAndScissor( void ) {
	qglMatrixMode(GL_PROJECTION);
	qglLoadMatrixf( backEnd.viewParms.projectionMatrix );
	qglMatrixMode(GL_MODELVIEW);

	// set the window clipping
	qglViewport( backEnd.viewParms.viewportX, backEnd.viewParms.viewportY, 
		backEnd.viewParms.viewportWidth, backEnd.viewParms.viewportHeight );
	qglScissor( backEnd.viewParms.viewportX, backEnd.viewParms.viewportY, 
		backEnd.viewParms.viewportWidth, backEnd.viewParms.viewportHeight );
	Matrix4Copy(backEnd.viewParms.projectionMatrix, glState.currentProjectionMatrix);
	Matrix4Multiply(glState.currentProjectionMatrix, glState.currentModelViewMatrix, glState.currentModelViewProjectionMatrix);
}
示例#13
0
void R_ScrollSkyMatrix (float speed)
{
    float scroll = cl.time * speed;
    glmatrix texmatrix;

    scroll -= (int) scroll & ~127;
    scroll /= 128.0f;

    qglMatrixMode (GL_TEXTURE);
    GL_IdentityMatrix (&texmatrix);
    GL_TranslateMatrix (&texmatrix, scroll, scroll, 0);
    qglLoadMatrixf (texmatrix.m16);
    qglMatrixMode (GL_MODELVIEW);
}
示例#14
0
/*
===============
RB_EnterWeaponDepthHack
===============
*/
static void RB_EnterWeaponDepthHack() {
	float	matrix[16];

	memcpy( matrix, backEnd.viewDef->projectionMatrix, sizeof( matrix ) );

	const float modelDepthHack = 0.25f;
	matrix[2] *= modelDepthHack;
	matrix[6] *= modelDepthHack;
	matrix[10] *= modelDepthHack;
	matrix[14] *= modelDepthHack;

	qglMatrixMode( GL_PROJECTION );
	qglLoadMatrixf( matrix );
	qglMatrixMode( GL_MODELVIEW );
}
示例#15
0
/*
================
RB_SimpleSurfaceSetup
================
*/
static void RB_SimpleSurfaceSetup( const drawSurf_t *drawSurf ) {
	// change the matrix if needed
	if ( drawSurf->space != backEnd.currentSpace ) {
		qglLoadMatrixf( drawSurf->space->modelViewMatrix );
		backEnd.currentSpace = drawSurf->space;
	}

	// change the scissor if needed
	if ( !backEnd.currentScissor.Equals( drawSurf->scissorRect ) && r_useScissor.GetBool() ) {
		GL_Scissor( backEnd.viewDef->viewport.x1 + drawSurf->scissorRect.x1, 
					backEnd.viewDef->viewport.y1 + drawSurf->scissorRect.y1,
					drawSurf->scissorRect.x2 + 1 - drawSurf->scissorRect.x1,
					drawSurf->scissorRect.y2 + 1 - drawSurf->scissorRect.y1 );
		backEnd.currentScissor = drawSurf->scissorRect;
	}
}
示例#16
0
static void SetViewportAndScissor( void ) {
	qglMatrixMode( GL_PROJECTION );
	qglLoadMatrixf( backEnd.viewParms.projectionMatrix );
	qglMatrixMode( GL_MODELVIEW );

	// set the window clipping
	qglViewport(    backEnd.viewParms.viewportX,
					backEnd.viewParms.viewportY,
					backEnd.viewParms.viewportWidth,
					backEnd.viewParms.viewportHeight );

// TODO: insert handling for widescreen?  (when looking through camera)
	qglScissor(     backEnd.viewParms.viewportX,
					backEnd.viewParms.viewportY,
					backEnd.viewParms.viewportWidth,
					backEnd.viewParms.viewportHeight );
}
// This could be two functions, but I want to keep the number of different API calls to a minimum
void GLRB_SetPortalRendering( qboolean enabled, const float* flipMatrix, const float* plane )
{
    if ( enabled )
    {
        double dplane[4] = {
            plane[0],
            plane[1],
            plane[2],
            plane[3] };

        qglLoadMatrixf( flipMatrix );
        qglClipPlane( GL_CLIP_PLANE0, dplane );
        qglEnable( GL_CLIP_PLANE0 );
    }
    else
    {
        qglDisable( GL_CLIP_PLANE0 );
    }
}
示例#18
0
/*
====================
RB_RenderDrawSurfListWithFunction

The triangle functions can check backEnd.currentSpace != surf->space
to see if they need to perform any new matrix setup.  The modelview
matrix will already have been loaded, and backEnd.currentSpace will
be updated after the triangle function completes.
====================
*/
void RB_RenderDrawSurfListWithFunction( drawSurf_t **drawSurfs, int numDrawSurfs, 
											  void (*triFunc_)( const drawSurf_t *) ) {
	int				i;
	const drawSurf_t		*drawSurf;

	backEnd.currentSpace = NULL;

	for (i = 0  ; i < numDrawSurfs ; i++ ) {
		drawSurf = drawSurfs[i];

		// change the matrix if needed
		if ( drawSurf->space != backEnd.currentSpace ) {
			qglLoadMatrixf( drawSurf->space->modelViewMatrix );
		}

		if ( drawSurf->space->weaponDepthHack ) {
			RB_EnterWeaponDepthHack();
		}

		if ( drawSurf->space->modelDepthHack != 0.0f ) {
			RB_EnterModelDepthHack( drawSurf->space->modelDepthHack );
		}

		// change the scissor if needed
		if ( r_useScissor.GetBool() && !backEnd.currentScissor.Equals( drawSurf->scissorRect ) ) {
			backEnd.currentScissor = drawSurf->scissorRect;
			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 );
		}

		// render it
		triFunc_( drawSurf );

		if ( drawSurf->space->weaponDepthHack || drawSurf->space->modelDepthHack != 0.0f ) {
			RB_LeaveDepthHack();
		}

		backEnd.currentSpace = drawSurf->space;
	}
}
示例#19
0
/*
 ==================
 GL_LoadMatrix
 ==================
*/
void GL_LoadMatrix (uint mode, const mat4_t matrix){

	switch (mode){
	case GL_PROJECTION:
		glState.projectionMatrixIdentity = false;

		break;
	case GL_MODELVIEW:
		glState.modelviewMatrixIdentity = false;

		break;
	case GL_TEXTURE:
		glState.textureMatrixIdentity[glState.texUnit] = false;

		break;
	}

	qglMatrixMode(mode);
	qglLoadMatrixf(matrix);
}
示例#20
0
static void SetViewportAndScissor( void ) {
	qglMatrixMode(GL_PROJECTION);
	qglLoadMatrixf( backEnd.viewParms.projectionMatrix );
	qglMatrixMode(GL_MODELVIEW);

	// set the window clipping
	qglViewport( backEnd.viewParms.viewportX, backEnd.viewParms.viewportY, 
		backEnd.viewParms.viewportWidth, backEnd.viewParms.viewportHeight );

    if(r_subviewScissor->integer)
    {
        qglScissor( backEnd.viewParms.scissorMinX, backEnd.viewParms.scissorMinY, 
            backEnd.viewParms.scissorMaxX - backEnd.viewParms.scissorMinX, 
            backEnd.viewParms.scissorMaxY - backEnd.viewParms.scissorMinY );
    }
    else
    {
        qglScissor( backEnd.viewParms.viewportX, backEnd.viewParms.viewportY, 
            backEnd.viewParms.viewportWidth, backEnd.viewParms.viewportHeight );
    }
}
示例#21
0
void Sky_RenderLayers (void)
{
    glmatrix skymatrix;

    // standard layers
    GL_BindTexture (GL_TEXTURE0_ARB, solidskytexture);
    R_ScrollSkyMatrix (8);

    GL_TexEnv (GL_TEXTURE1_ARB, GL_TEXTURE_2D, GL_DECAL);
    GL_BindTexture (GL_TEXTURE1_ARB, alphaskytexture);
    R_ScrollSkyMatrix (16);

    GL_IdentityMatrix (&skymatrix);
    GL_TranslateMatrix (&skymatrix, -r_origin[0], -r_origin[1], -r_origin[2]);
    GL_ScaleMatrix (&skymatrix, 65536, 65536, 65536);
    qglMultMatrixf (skymatrix.m16);

    GL_SetStreamSource (GLSTREAM_POSITION, 3, GL_FLOAT, sizeof (dpskyvert_t), r_dpskyverts->xyz);
    GL_SetStreamSource (GLSTREAM_COLOR, 0, GL_NONE, 0, NULL);
    GL_SetStreamSource (GLSTREAM_TEXCOORD0, 2, GL_FLOAT, sizeof (dpskyvert_t), r_dpskyverts->st);
    GL_SetStreamSource (GLSTREAM_TEXCOORD1, 2, GL_FLOAT, sizeof (dpskyvert_t), r_dpskyverts->st);
    GL_SetStreamSource (GLSTREAM_TEXCOORD2, 0, GL_NONE, 0, NULL);

    GL_SetIndices (r_dpskyindexes);
    GL_DrawIndexedPrimitive (GL_TRIANGLES, SKYSPHERE_NUMINDEXES, SKYSPHERE_NUMVERTS);

    GL_TexEnv (GL_TEXTURE1_ARB, GL_TEXTURE_2D, GL_NONE);

    qglMatrixMode (GL_TEXTURE);
    qglLoadIdentity ();
    qglMatrixMode (GL_MODELVIEW);

    GL_ActiveTexture (GL_TEXTURE0_ARB);

    qglMatrixMode (GL_TEXTURE);
    qglLoadIdentity ();
    qglMatrixMode (GL_MODELVIEW);

    qglLoadMatrixf (r_world_matrix.m16);
}
示例#22
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) {
	// set the modelview matrix for the viewer
	qglMatrixMode(GL_PROJECTION);
	qglLoadMatrixf( backEnd.viewDef->projectionMatrix );
	qglMatrixMode(GL_MODELVIEW);

	// set the window clipping
	qglViewport( tr.viewportOffset[0] + backEnd.viewDef->viewport.x1, 
		tr.viewportOffset[1] + backEnd.viewDef->viewport.y1, 
		backEnd.viewDef->viewport.x2 + 1 - backEnd.viewDef->viewport.x1,
		backEnd.viewDef->viewport.y2 + 1 - backEnd.viewDef->viewport.y1 );

	// the scissor may be smaller than the viewport for subviews
	qglScissor( tr.viewportOffset[0] + backEnd.viewDef->viewport.x1 + backEnd.viewDef->scissor.x1, 
		tr.viewportOffset[1] + backEnd.viewDef->viewport.y1 + backEnd.viewDef->scissor.y1, 
		backEnd.viewDef->scissor.x2 + 1 - backEnd.viewDef->scissor.x1,
		backEnd.viewDef->scissor.y2 + 1 - backEnd.viewDef->scissor.y1 );
	backEnd.currentScissor = backEnd.viewDef->scissor;

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

	// we don't have to clear the depth / stencil buffer for 2D rendering
	if ( backEnd.viewDef->viewEntitys ) {
		qglStencilMask( 0xff );
		// some cards may have 7 bit stencil buffers, so don't assume this
		// should be 128
		qglClearStencil( 1<<(glConfig.stencilBits-1) );
		qglClear( GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
		qglEnable( GL_DEPTH_TEST );
	} else {
		qglDisable( GL_DEPTH_TEST );
		qglDisable( GL_STENCIL_TEST );
	}

	backEnd.glState.faceCulling = -1;		// force face culling to set next time
	GL_Cull( CT_FRONT_SIDED );

}
示例#23
0
/*
** RB_DrawSun
*/
void RB_DrawSun( void ) {
    float		size;
    float		dist;
    vec3_t		origin, vec1, vec2;
    vec3_t		temp;

    if ( !backEnd.skyRenderedThisView ) {
        return;
    }
    if ( !r_drawSun->integer ) {
        return;
    }
    qglLoadMatrixf( backEnd.viewParms.world.modelMatrix );
    qglTranslatef (backEnd.viewParms.ori.origin[0], backEnd.viewParms.ori.origin[1], backEnd.viewParms.ori.origin[2]);

    dist = 	backEnd.viewParms.zFar / 1.75;		// div sqrt(3)
    size = dist * 0.4;

    VectorScale( tr.sunDirection, dist, origin );
    PerpendicularVector( vec1, tr.sunDirection );
    CrossProduct( tr.sunDirection, vec1, vec2 );

    VectorScale( vec1, size, vec1 );
    VectorScale( vec2, size, vec2 );

    // farthest depth range
    qglDepthRange( 1.0, 1.0 );

    // FIXME: use quad stamp
    RB_BeginSurface( tr.sunShader, tess.fogNum );
    VectorCopy( origin, temp );
    VectorSubtract( temp, vec1, temp );
    VectorSubtract( temp, vec2, temp );
    VectorCopy( temp, tess.xyz[tess.numVertexes] );
    tess.texCoords[tess.numVertexes][0][0] = 0;
    tess.texCoords[tess.numVertexes][0][1] = 0;
    tess.vertexColors[tess.numVertexes][0] = 255;
    tess.vertexColors[tess.numVertexes][1] = 255;
    tess.vertexColors[tess.numVertexes][2] = 255;
    tess.numVertexes++;

    VectorCopy( origin, temp );
    VectorAdd( temp, vec1, temp );
    VectorSubtract( temp, vec2, temp );
    VectorCopy( temp, tess.xyz[tess.numVertexes] );
    tess.texCoords[tess.numVertexes][0][0] = 0;
    tess.texCoords[tess.numVertexes][0][1] = 1;
    tess.vertexColors[tess.numVertexes][0] = 255;
    tess.vertexColors[tess.numVertexes][1] = 255;
    tess.vertexColors[tess.numVertexes][2] = 255;
    tess.numVertexes++;

    VectorCopy( origin, temp );
    VectorAdd( temp, vec1, temp );
    VectorAdd( temp, vec2, temp );
    VectorCopy( temp, tess.xyz[tess.numVertexes] );
    tess.texCoords[tess.numVertexes][0][0] = 1;
    tess.texCoords[tess.numVertexes][0][1] = 1;
    tess.vertexColors[tess.numVertexes][0] = 255;
    tess.vertexColors[tess.numVertexes][1] = 255;
    tess.vertexColors[tess.numVertexes][2] = 255;
    tess.numVertexes++;

    VectorCopy( origin, temp );
    VectorSubtract( temp, vec1, temp );
    VectorAdd( temp, vec2, temp );
    VectorCopy( temp, tess.xyz[tess.numVertexes] );
    tess.texCoords[tess.numVertexes][0][0] = 1;
    tess.texCoords[tess.numVertexes][0][1] = 0;
    tess.vertexColors[tess.numVertexes][0] = 255;
    tess.vertexColors[tess.numVertexes][1] = 255;
    tess.vertexColors[tess.numVertexes][2] = 255;
    tess.numVertexes++;

    tess.indexes[tess.numIndexes++] = 0;
    tess.indexes[tess.numIndexes++] = 1;
    tess.indexes[tess.numIndexes++] = 2;
    tess.indexes[tess.numIndexes++] = 0;
    tess.indexes[tess.numIndexes++] = 2;
    tess.indexes[tess.numIndexes++] = 3;

    RB_EndSurface();

    // back to normal depth range
    qglDepthRange( 0.0, 1.0 );
}
示例#24
0
/*
==================
RB_RenderDrawSurfList
==================
*/
void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
	shader_t		*shader, *oldShader;
	int				fogNum, oldFogNum;
	int				entityNum, oldEntityNum;
	int				dlighted, oldDlighted;
	qboolean		depthRange, oldDepthRange;
	int				i;
	drawSurf_t		*drawSurf;
	int				oldSort;
	float			originalTime;
#ifdef __MACOS__
	int				macEventTime;

	Sys_PumpEvents();		// crutch up the mac's limited buffer queue size

	// we don't want to pump the event loop too often and waste time, so
	// we are going to check every shader change
	macEventTime = ri.Milliseconds() + MAC_EVENT_PUMP_MSEC;
#endif

	// save original time for entity shader offsets
	originalTime = backEnd.refdef.floatTime;

	// clear the z buffer, set the modelview, etc
	RB_BeginDrawingView ();

	// draw everything
	oldEntityNum = -1;
	backEnd.currentEntity = &tr.worldEntity;
	oldShader = NULL;
	oldFogNum = -1;
	oldDepthRange = qfalse;
	oldDlighted = qfalse;
	oldSort = -1;
	depthRange = qfalse;

	backEnd.pc.c_surfaces += numDrawSurfs;

	for (i = 0, drawSurf = drawSurfs ; i < numDrawSurfs ; i++, drawSurf++) {
		if ( drawSurf->sort == oldSort ) {
			// fast path, same as previous sort
			rb_surfaceTable[ *drawSurf->surface ]( drawSurf->surface );
			continue;
		}
		oldSort = drawSurf->sort;
		R_DecomposeSort( drawSurf->sort, &entityNum, &shader, &fogNum, &dlighted );

		//
		// change the tess parameters if needed
		// a "entityMergable" shader is a shader that can have surfaces from seperate
		// entities merged into a single batch, like smoke and blood puff sprites
		if (shader != oldShader || fogNum != oldFogNum || dlighted != oldDlighted 
			|| ( entityNum != oldEntityNum && !shader->entityMergable ) ) {
			if (oldShader != NULL) {
#ifdef __MACOS__	// crutch up the mac's limited buffer queue size
				int		t;

				t = ri.Milliseconds();
				if ( t > macEventTime ) {
					macEventTime = t + MAC_EVENT_PUMP_MSEC;
					Sys_PumpEvents();
				}
#endif
				RB_EndSurface();
			}
			RB_BeginSurface( shader, fogNum );
			oldShader = shader;
			oldFogNum = fogNum;
			oldDlighted = dlighted;
		}

		//
		// change the modelview matrix if needed
		//
		if ( entityNum != oldEntityNum ) {
			depthRange = qfalse;

			if ( entityNum != ENTITYNUM_WORLD ) {
				backEnd.currentEntity = &backEnd.refdef.entities[entityNum];
				backEnd.refdef.floatTime = originalTime - backEnd.currentEntity->e.shaderTime;
				// we have to reset the shaderTime as well otherwise image animations start
				// from the wrong frame
				tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;

				// set up the transformation matrix
				R_RotateForEntity( backEnd.currentEntity, &backEnd.viewParms, &backEnd.or );

				// set up the dynamic lighting if needed
				if ( backEnd.currentEntity->needDlights ) {
					R_TransformDlights( backEnd.refdef.num_dlights, backEnd.refdef.dlights, &backEnd.or );
				}

				if ( backEnd.currentEntity->e.renderfx & RF_DEPTHHACK ) {
					// hack the depth range to prevent view model from poking into walls
					depthRange = qtrue;
				}
			} else {
				backEnd.currentEntity = &tr.worldEntity;
				backEnd.refdef.floatTime = originalTime;
				backEnd.or = backEnd.viewParms.world;
				// we have to reset the shaderTime as well otherwise image animations on
				// the world (like water) continue with the wrong frame
				tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;
				R_TransformDlights( backEnd.refdef.num_dlights, backEnd.refdef.dlights, &backEnd.or );
			}

			qglLoadMatrixf( backEnd.or.modelMatrix );

			//
			// change depthrange if needed
			//
			if ( oldDepthRange != depthRange ) {
				if ( depthRange ) {
					qglDepthRange (0, 0.3);
				} else {
					qglDepthRange (0, 1);
				}
				oldDepthRange = depthRange;
			}

			oldEntityNum = entityNum;
		}

		// add the triangles for this surface
		rb_surfaceTable[ *drawSurf->surface ]( drawSurf->surface );
	}

	backEnd.refdef.floatTime = originalTime;

	// draw the contents of the last shader batch
	if (oldShader != NULL) {
		RB_EndSurface();
	}

	// go back to the world modelview matrix
	qglLoadMatrixf( backEnd.viewParms.world.modelMatrix );
	if ( depthRange ) {
		qglDepthRange (0, 1);
	}

#if 0
	RB_DrawSun();
#endif
	// darken down any stencil shadows
	RB_ShadowFinish();		

	// add light flares on lights that aren't obscured
	RB_RenderFlares();

#ifdef __MACOS__
	Sys_PumpEvents();		// crutch up the mac's limited buffer queue size
#endif
}
示例#25
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 );
	// 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 );

	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 );
		qglClipPlane (GL_CLIP_PLANE0, plane2);
		qglEnable (GL_CLIP_PLANE0);
	} else {
		qglDisable (GL_CLIP_PLANE0);
	}
}
示例#26
0
/*
==================
RB_RenderDrawSurfList
==================
*/
void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
    shader_t		*shader, *oldShader;
    int				fogNum, oldFogNum;
    int				entityNum, oldEntityNum;
    int				dlighted, oldDlighted;
    qboolean		depthRange, oldDepthRange, isCrosshair, wasCrosshair;
    int				i;
    drawSurf_t		*drawSurf;
    int				oldSort;
    float			originalTime;

    // save original time for entity shader offsets
    originalTime = backEnd.refdef.floatTime;

    // clear the z buffer, set the modelview, etc
    RB_BeginDrawingView ();

    // draw everything
    oldEntityNum = -1;
    backEnd.currentEntity = &tr.worldEntity;
    oldShader = NULL;
    oldFogNum = -1;
    oldDepthRange = qfalse;
    wasCrosshair = qfalse;
    oldDlighted = qfalse;
    oldSort = -1;
    depthRange = qfalse;

    backEnd.pc.c_surfaces += numDrawSurfs;

    for (i = 0, drawSurf = drawSurfs ; i < numDrawSurfs ; i++, drawSurf++) {
        if ( drawSurf->sort == oldSort ) {
            // fast path, same as previous sort
            rb_surfaceTable[ *drawSurf->surface ]( drawSurf->surface );
            continue;
        }
        oldSort = drawSurf->sort;
        R_DecomposeSort( drawSurf->sort, &entityNum, &shader, &fogNum, &dlighted );

        //
        // change the tess parameters if needed
        // a "entityMergable" shader is a shader that can have surfaces from seperate
        // entities merged into a single batch, like smoke and blood puff sprites
        if (shader != oldShader || fogNum != oldFogNum || dlighted != oldDlighted
                || ( entityNum != oldEntityNum && !shader->entityMergable ) ) {
            if (oldShader != NULL) {
                RB_EndSurface();
            }
            RB_BeginSurface( shader, fogNum );
            oldShader = shader;
            oldFogNum = fogNum;
            oldDlighted = dlighted;
        }

        //
        // change the modelview matrix if needed
        //
        if ( entityNum != oldEntityNum ) {
            depthRange = isCrosshair = qfalse;

            if ( entityNum != REFENTITYNUM_WORLD ) {
                backEnd.currentEntity = &backEnd.refdef.entities[entityNum];
                backEnd.refdef.floatTime = originalTime - backEnd.currentEntity->e.shaderTime;
                // we have to reset the shaderTime as well otherwise image animations start
                // from the wrong frame
                tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;

                // set up the transformation matrix
                R_RotateForEntity( backEnd.currentEntity, &backEnd.viewParms, &backEnd.or );

                // set up the dynamic lighting if needed
                if ( backEnd.currentEntity->needDlights ) {
                    R_TransformDlights( backEnd.refdef.num_dlights, backEnd.refdef.dlights, &backEnd.or );
                }

                if(backEnd.currentEntity->e.renderfx & RF_DEPTHHACK)
                {
                    // hack the depth range to prevent view model from poking into walls
                    depthRange = qtrue;

                    if(backEnd.currentEntity->e.renderfx & RF_CROSSHAIR)
                        isCrosshair = qtrue;
                }
            } else {
                backEnd.currentEntity = &tr.worldEntity;
                backEnd.refdef.floatTime = originalTime;
                backEnd.or = backEnd.viewParms.world;
                // we have to reset the shaderTime as well otherwise image animations on
                // the world (like water) continue with the wrong frame
                tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;
                R_TransformDlights( backEnd.refdef.num_dlights, backEnd.refdef.dlights, &backEnd.or );
            }

            qglLoadMatrixf( backEnd.or.modelMatrix );

            //
            // change depthrange. Also change projection matrix so first person weapon does not look like coming
            // out of the screen.
            //
            if (oldDepthRange != depthRange || wasCrosshair != isCrosshair)
            {
                if (depthRange)
                {
                    if(backEnd.viewParms.stereoFrame != STEREO_CENTER)
                    {
                        if(isCrosshair)
                        {
                            if(oldDepthRange)
                            {
                                // was not a crosshair but now is, change back proj matrix
                                qglMatrixMode(GL_PROJECTION);
                                qglLoadMatrixf(backEnd.viewParms.projectionMatrix);
                                qglMatrixMode(GL_MODELVIEW);
                            }
                        }
                        else
                        {
                            viewParms_t temp = backEnd.viewParms;

                            R_SetupProjection(&temp, r_znear->value, qfalse);

                            qglMatrixMode(GL_PROJECTION);
                            qglLoadMatrixf(temp.projectionMatrix);
                            qglMatrixMode(GL_MODELVIEW);
                        }
                    }

                    if(!oldDepthRange)
                        qglDepthRange (0, 0.3);
                }
                else
                {
                    if(!wasCrosshair && backEnd.viewParms.stereoFrame != STEREO_CENTER)
                    {
                        qglMatrixMode(GL_PROJECTION);
                        qglLoadMatrixf(backEnd.viewParms.projectionMatrix);
                        qglMatrixMode(GL_MODELVIEW);
                    }

                    qglDepthRange (0, 1);
                }

                oldDepthRange = depthRange;
                wasCrosshair = isCrosshair;
            }

            oldEntityNum = entityNum;
        }

        // add the triangles for this surface
        rb_surfaceTable[ *drawSurf->surface ]( drawSurf->surface );
    }

    backEnd.refdef.floatTime = originalTime;

    // draw the contents of the last shader batch
    if (oldShader != NULL) {
        RB_EndSurface();
    }

    // go back to the world modelview matrix
    qglLoadMatrixf( backEnd.viewParms.world.modelMatrix );
    if ( depthRange ) {
        qglDepthRange (0, 1);
    }

#if 0
    RB_DrawSun();
#endif
    // darken down any stencil shadows
    RB_ShadowFinish();

    // add light flares on lights that aren't obscured
    RB_RenderFlares();
}
示例#27
0
/*
==================
RB_RenderDrawSurfList
==================
*/
void RB_RenderDrawSurfList( drawSurf_t *drawSurfs, int numDrawSurfs ) {
	shader_t        *shader, *oldShader;
	int fogNum, oldFogNum;
	int entityNum, oldEntityNum;
	int dlighted, oldDlighted;
	qboolean depthRange, oldDepthRange;
	int i;
	drawSurf_t      *drawSurf;
	int oldSort;
	float originalTime;
	int oldNumVerts, oldNumIndex;
//GR - tessellation flag
	int atiTess = 0, oldAtiTess;
#ifdef __MACOS__
	int macEventTime;

	Sys_PumpEvents();       // crutch up the mac's limited buffer queue size

	// we don't want to pump the event loop too often and waste time, so
	// we are going to check every shader change
	macEventTime = ri.Milliseconds() + MAC_EVENT_PUMP_MSEC;
#endif

	// save original time for entity shader offsets
	originalTime = backEnd.refdef.floatTime;

	// clear the z buffer, set the modelview, etc
	RB_BeginDrawingView();

	// draw everything
	oldEntityNum = -1;
	backEnd.currentEntity = &tr.worldEntity;
	oldShader = NULL;
	oldFogNum = -1;
	oldDepthRange = qfalse;
	oldDlighted = qfalse;
	oldSort = -1;
	depthRange = qfalse;
// GR - tessellation also forces to draw everything
	oldAtiTess = -1;

	backEnd.pc.c_surfaces += numDrawSurfs;

	for ( i = 0, drawSurf = drawSurfs ; i < numDrawSurfs ; i++, drawSurf++ ) {
		if ( drawSurf->sort == oldSort ) {
			// fast path, same as previous sort
			oldNumVerts = tess.numVertexes;
			oldNumIndex = tess.numIndexes;

			rb_surfaceTable[ *drawSurf->surface ]( drawSurf->surface );
/*
			// RF, convert the newly created vertexes into dust particles, and overwrite
			if (backEnd.currentEntity->e.reFlags & REFLAG_ZOMBIEFX) {
				RB_ZombieFX( 0, drawSurf, oldNumVerts, oldNumIndex );
			}
			else if (backEnd.currentEntity->e.reFlags & REFLAG_ZOMBIEFX2) {
				RB_ZombieFX( 1, drawSurf, oldNumVerts, oldNumIndex );
			}
*/
			continue;
		}
		oldSort = drawSurf->sort;
// GR - also extract tesselation flag
		R_DecomposeSort( drawSurf->sort, &entityNum, &shader, &fogNum, &dlighted, &atiTess );

		//
		// change the tess parameters if needed
		// a "entityMergable" shader is a shader that can have surfaces from seperate
		// entities merged into a single batch, like smoke and blood puff sprites
		if ( shader != oldShader || fogNum != oldFogNum || dlighted != oldDlighted
// GR - force draw on tessellation flag change
			 || ( atiTess != oldAtiTess )
			 || ( entityNum != oldEntityNum && !shader->entityMergable ) ) {
			if ( oldShader != NULL ) {
#ifdef __MACOS__    // crutch up the mac's limited buffer queue size
				int t;

				t = ri.Milliseconds();
				if ( t > macEventTime ) {
					macEventTime = t + MAC_EVENT_PUMP_MSEC;
					Sys_PumpEvents();
				}
#endif
// GR - pass tessellation flag to the shader command
//		make sure to use oldAtiTess!!!
				tess.ATI_tess = ( oldAtiTess == ATI_TESS_TRUFORM );

				RB_EndSurface();
			}
			RB_BeginSurface( shader, fogNum );
			oldShader = shader;
			oldFogNum = fogNum;
			oldDlighted = dlighted;
// GR - update old tessellation flag
			oldAtiTess = atiTess;
		}

		//
		// change the modelview matrix if needed
		//
		if ( entityNum != oldEntityNum ) {
			depthRange = qfalse;

			if ( entityNum != ENTITYNUM_WORLD ) {
				backEnd.currentEntity = &backEnd.refdef.entities[entityNum];
				backEnd.refdef.floatTime = originalTime - backEnd.currentEntity->e.shaderTime;

				// we have to reset the shaderTime as well otherwise image animations start
				// from the wrong frame
//				tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;

				// set up the transformation matrix
				R_RotateForEntity( backEnd.currentEntity, &backEnd.viewParms, &backEnd.or );

				// set up the dynamic lighting if needed
				if ( backEnd.currentEntity->needDlights ) {
					R_TransformDlights( backEnd.refdef.num_dlights, backEnd.refdef.dlights, &backEnd.or );
				}

				if ( backEnd.currentEntity->e.renderfx & RF_DEPTHHACK ) {
					// hack the depth range to prevent view model from poking into walls
					depthRange = qtrue;
				}
			} else {
				backEnd.currentEntity = &tr.worldEntity;
				backEnd.refdef.floatTime = originalTime;
				backEnd.or = backEnd.viewParms.world;

				// we have to reset the shaderTime as well otherwise image animations on
				// the world (like water) continue with the wrong frame
//				tess.shaderTime = backEnd.refdef.floatTime - tess.shader->timeOffset;

				R_TransformDlights( backEnd.refdef.num_dlights, backEnd.refdef.dlights, &backEnd.or );
			}

			qglLoadMatrixf( backEnd.or.modelMatrix );

			//
			// change depthrange if needed
			//
			if ( oldDepthRange != depthRange ) {
				if ( depthRange ) {
					qglDepthRange( 0, 0.3 );
				} else {
					qglDepthRange( 0, 1 );
				}
				oldDepthRange = depthRange;
			}

			oldEntityNum = entityNum;
		}

		// RF, ZOMBIEFX, store the tess indexes, so we can grab the calculated
		// vertex positions and normals, and convert them into dust particles
		oldNumVerts = tess.numVertexes;
		oldNumIndex = tess.numIndexes;

		// add the triangles for this surface
		rb_surfaceTable[ *drawSurf->surface ]( drawSurf->surface );

		// RF, convert the newly created vertexes into dust particles, and overwrite
		if ( backEnd.currentEntity->e.reFlags & REFLAG_ZOMBIEFX ) {
			RB_ZombieFX( 0, drawSurf, oldNumVerts, oldNumIndex );
		} else if ( backEnd.currentEntity->e.reFlags & REFLAG_ZOMBIEFX2 )     {
			RB_ZombieFX( 1, drawSurf, oldNumVerts, oldNumIndex );
		}
	}

	// draw the contents of the last shader batch
	if ( oldShader != NULL ) {
// GR - pass tessellation flag to the shader command
//		make sure to use oldAtiTess!!!
		tess.ATI_tess = ( oldAtiTess == ATI_TESS_TRUFORM );

		RB_EndSurface();
	}

	// go back to the world modelview matrix
	backEnd.currentEntity = &tr.worldEntity;
	backEnd.refdef.floatTime = originalTime;
	backEnd.or = backEnd.viewParms.world;
	R_TransformDlights( backEnd.refdef.num_dlights, backEnd.refdef.dlights, &backEnd.or );

	qglLoadMatrixf( backEnd.viewParms.world.modelMatrix );
	if ( depthRange ) {
		qglDepthRange( 0, 1 );
	}

	// (SA) draw sun
	RB_DrawSun();


	// darken down any stencil shadows
	RB_ShadowFinish();

	// add light flares on lights that aren't obscured
	RB_RenderFlares();

#ifdef __MACOS__
	Sys_PumpEvents();       // crutch up the mac's limited buffer queue size
#endif
}
示例#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];
		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 );
		qglClipPlane( GL_CLIP_PLANE0, plane2 );
		qglEnable( GL_CLIP_PLANE0 );
	} else {
		qglDisable( GL_CLIP_PLANE0 );
	}
}
示例#29
0
void R_DrawAliasShadows (entity_t **ents, int numents, void *meshbuffer)
{
    if (r_shadows.value > 0.01f)
    {
        int i;
        qbool stateset = false;
        byte shadecolor[4] = {0, 0, 0, 128};
//		extern int gl_stencilbits;

        for (i = 0; i < numents; i++)
        {
            entity_t *ent = ents[i];
            glmatrix eshadow;

            if (!(ent->model->flags & MOD_NOSHADOW))
            {
                aliasstate_t *state = &ent->aliasstate;
                aliashdr_t *hdr = Mod_Extradata (ent->model);
                float lheight = state->origin[2] - state->lightspot[2];

                if (!stateset)
                {
                    float *mesh = (float *) meshbuffer;

                    qglDepthMask (GL_FALSE);
                    qglEnable (GL_BLEND);
                    GL_TexEnv (GL_TEXTURE1_ARB, GL_TEXTURE_2D, GL_NONE);
                    GL_TexEnv (GL_TEXTURE0_ARB, GL_TEXTURE_2D, GL_NONE);
                    qglColor4f (0, 0, 0, r_shadows.value);
                    shadecolor[3] = BYTE_CLAMPF (r_shadows.value);

                    /*
                    if (gl_stencilbits)
                    {
                    	qglEnable (GL_STENCIL_TEST);
                    	qglStencilFunc (GL_EQUAL, 1, 2);
                    	qglStencilOp (GL_KEEP, GL_KEEP, GL_INCR);
                    }
                    */

                    GL_SetStreamSource (GLSTREAM_POSITION, 3, GL_FLOAT, sizeof (float) * 4, mesh);
                    GL_SetStreamSource (GLSTREAM_COLOR, 4, GL_UNSIGNED_BYTE, sizeof (float) * 4, &mesh[3]);
                    GL_SetStreamSource (GLSTREAM_TEXCOORD0, 0, GL_NONE, 0, NULL);
                    GL_SetStreamSource (GLSTREAM_TEXCOORD1, 0, GL_NONE, 0, NULL);
                    GL_SetStreamSource (GLSTREAM_TEXCOORD2, 0, GL_NONE, 0, NULL);

                    stateset = true;
                }

                GL_LoadMatrix (&eshadow, &r_world_matrix);

                if (state->origin[0] || state->origin[1] || state->origin[2])
                    GL_TranslateMatrix (&eshadow, state->origin[0], state->origin[1], state->origin[2]);

                GL_TranslateMatrix (&eshadow, 0, 0, -lheight);
                GL_MultiplyMatrix (&eshadow, &shadowmatrix, &eshadow);
                GL_TranslateMatrix (&eshadow, 0, 0, lheight);

                if (state->angles[1]) GL_RotateMatrix (&eshadow, state->angles[1], 0, 0, 1);

                GL_TranslateMatrix (&eshadow, hdr->scale_origin[0], hdr->scale_origin[1], hdr->scale_origin[2]);
                GL_ScaleMatrix (&eshadow, hdr->scale[0], hdr->scale[1], hdr->scale[2]);

                qglLoadMatrixf (eshadow.m16);

                R_DrawAliasShadow (ent, hdr, state, (float *) meshbuffer, (float *) shadecolor);
            }
        }

        if (stateset)
        {
            /*
            if (gl_stencilbits)
            	qglDisable (GL_STENCIL_TEST);
            */

            GL_TexEnv (GL_TEXTURE0_ARB, GL_TEXTURE_2D, GL_REPLACE);
            qglDisable (GL_BLEND);
            qglDepthMask (GL_TRUE);
            qglColor4f (1, 1, 1, 1);

            qglLoadMatrixf (r_world_matrix.m16);
        }
    }
}
示例#30
0
void R_DrawAliasModel (entity_t *ent, aliashdr_t *hdr, aliasstate_t *state, qbool showtris)
{
    int v;
    trivertx_t *verts1, *verts2;
    float	blend, iblend;
    qbool lerping;
    aliasmesh_t *mesh;
    trivertx_t *trivert1;
    trivertx_t *trivert2;
    float lerpnormal[3];
    float alias_forward[3], alias_right[3], alias_up[3];
    float r_plightvec[3], lightvec[3] = {-1, 0, 0};

    r_aliasmesh_t *r_aliasmesh;
    float *r_aliasst;

    // hack the depth range to prevent view model from poking into walls
    if (ent->renderfx & RF_WEAPONMODEL)
        qglDepthRange (QGL_DEPTH_3D_BEGIN, QGL_DEPTH_VM_END);

    ent->angles[0] = -ent->angles[0];	// stupid quake bug
    AngleVectors (ent->angles, alias_forward, alias_right, alias_up);
    ent->angles[0] = -ent->angles[0];	// stupid quake bug

    // rotate the lighting vector into the model's frame of reference
    r_plightvec[0] = DotProduct (lightvec, alias_forward);
    r_plightvec[1] = -DotProduct (lightvec, alias_right);
    r_plightvec[2] = DotProduct (lightvec, alias_up);

    // go back to the world matrix
    GL_LoadMatrix (&ent->matrix, &r_world_matrix);

    if (state->origin[0] || state->origin[1] || state->origin[2])
        GL_TranslateMatrix (&ent->matrix, state->origin[0], state->origin[1], state->origin[2]);

    if (state->angles[1]) GL_RotateMatrix (&ent->matrix, state->angles[1], 0, 0, 1);
    if (state->angles[0]) GL_RotateMatrix (&ent->matrix, -state->angles[0], 0, 1, 0);
    if (state->angles[2]) GL_RotateMatrix (&ent->matrix, state->angles[2], 1, 0, 0);

    GL_TranslateMatrix (&ent->matrix, hdr->scale_origin[0], hdr->scale_origin[1], hdr->scale_origin[2]);
    GL_ScaleMatrix (&ent->matrix, hdr->scale[0], hdr->scale[1], hdr->scale[2]);

    qglLoadMatrixf (ent->matrix.m16);

    r_aliasmesh = (r_aliasmesh_t *) r_meshbuffer;
    r_aliasst = (float *) (r_aliasmesh + hdr->numverts);
    mesh = (aliasmesh_t *) ((byte *) hdr + hdr->aliasmesh);

    if (state->pose1 != state->pose2)
    {
        lerping = true;

        verts1 = (trivertx_t *) ((byte *) hdr + hdr->vertexes + hdr->framevertexsize * state->pose1);
        verts2 = (trivertx_t *) ((byte *) hdr + hdr->vertexes + hdr->framevertexsize * state->pose2);

        blend = state->blend;
        iblend = 1.0f - blend;
    }
    else // poses the same means either 1. the entity has paused its animation, or 2. r_lerpmodels is disabled
    {
        lerping = false;

        verts1 = (trivertx_t *) ((byte *) hdr + hdr->vertexes + hdr->framevertexsize * state->pose1);
        verts2 = verts1;

        blend = iblend = 0; // avoid bogus compiler warning
    }

    GL_SetStreamSource (GLSTREAM_POSITION, 3, GL_FLOAT, sizeof (r_aliasmesh_t), r_aliasmesh->xyz);
    GL_SetStreamSource (GLSTREAM_COLOR, 4, GL_FLOAT, sizeof (r_aliasmesh_t), r_aliasmesh->rgba);

    if (showtris)
    {
        GL_SetStreamSource (GLSTREAM_TEXCOORD0, 0, GL_NONE, 0, NULL);
        GL_SetStreamSource (GLSTREAM_TEXCOORD1, 0, GL_NONE, 0, NULL);
    }
    else
    {
        GL_SetStreamSource (GLSTREAM_TEXCOORD0, 2, GL_FLOAT, 0, r_aliasst);

        if (state->fb)
            GL_SetStreamSource (GLSTREAM_TEXCOORD1, 2, GL_FLOAT, 0, r_aliasst);
        else GL_SetStreamSource (GLSTREAM_TEXCOORD1, 0, GL_NONE, 0, NULL);
    }

    GL_SetStreamSource (GLSTREAM_TEXCOORD2, 0, GL_NONE, 0, NULL);

    if (lerping)
    {
        for (v = 0; v < hdr->numverts; v++, r_aliasmesh++, mesh++)
        {
            trivert1 = &verts1[mesh->vertindex];
            trivert2 = &verts2[mesh->vertindex];

            // interpolate the normals
            lerpnormal[0] = r_avertexnormals[trivert1->lightnormalindex][0] * iblend + r_avertexnormals[trivert2->lightnormalindex][0] * blend;
            lerpnormal[1] = r_avertexnormals[trivert1->lightnormalindex][1] * iblend + r_avertexnormals[trivert2->lightnormalindex][1] * blend;
            lerpnormal[2] = r_avertexnormals[trivert1->lightnormalindex][2] * iblend + r_avertexnormals[trivert2->lightnormalindex][2] * blend;

            mesh->light = DotProduct (lerpnormal, r_plightvec) * -0.5f + 1.0f;

            r_aliasmesh->xyz[0] = trivert1->v[0] * iblend + trivert2->v[0] * blend;
            r_aliasmesh->xyz[1] = trivert1->v[1] * iblend + trivert2->v[1] * blend;
            r_aliasmesh->xyz[2] = trivert1->v[2] * iblend + trivert2->v[2] * blend;
        }
    }
    else
    {
        for (v = 0; v < hdr->numverts; v++, r_aliasmesh++, mesh++)
        {
            trivert1 = &verts1[mesh->vertindex];

            mesh->light = DotProduct (r_avertexnormals[trivert1->lightnormalindex], r_plightvec) * -0.5f + 1.0f;

            r_aliasmesh->xyz[0] = trivert1->v[0];
            r_aliasmesh->xyz[1] = trivert1->v[1];
            r_aliasmesh->xyz[2] = trivert1->v[2];
        }
    }

    // reset these for lighting
    r_aliasmesh = (r_aliasmesh_t *) r_meshbuffer;
    r_aliasst = (float *) (r_aliasmesh + hdr->numverts);
    mesh = (aliasmesh_t *) ((byte *) hdr + hdr->aliasmesh);

    if (showtris)
    {
        for (v = 0; v < hdr->numverts; v++, r_aliasmesh++, mesh++)
        {
            r_aliasmesh->rgba[0] = 1;
            r_aliasmesh->rgba[1] = 1;
            r_aliasmesh->rgba[2] = 1;
            r_aliasmesh->rgba[3] = 1;
        }
    }
    else
    {
        for (v = 0; v < hdr->numverts; v++, r_aliasmesh++, mesh++, r_aliasst += 2)
        {
            r_aliasst[0] = mesh->st[0];
            r_aliasst[1] = mesh->st[1];

            r_aliasmesh->rgba[0] = state->shadelight[0] * mesh->light;
            r_aliasmesh->rgba[1] = state->shadelight[1] * mesh->light;
            r_aliasmesh->rgba[2] = state->shadelight[2] * mesh->light;
            r_aliasmesh->rgba[3] = state->shadelight[3];
        }
    }

    // for testing of light shading
    // glDisable (GL_TEXTURE_2D);
    GL_SetIndices (((byte *) hdr + hdr->indexes));
    GL_DrawIndexedPrimitive (GL_TRIANGLES, hdr->numindexes, hdr->numverts);
    // glEnable (GL_TEXTURE_2D);

    // restore normal depth range
    if (ent->renderfx & RF_WEAPONMODEL)
        qglDepthRange (QGL_DEPTH_3D_BEGIN, QGL_DEPTH_3D_END);
}