Пример #1
0
/*
** GL_Cull
*/
void GL_Cull( int cullType ) {
	if ( glState.faceCulling == cullType ) {
		return;
	}

	glState.faceCulling = cullType;

	if ( cullType == CT_TWO_SIDED ) {
		qglDisable( GL_CULL_FACE );
	} else
	{
		qglEnable( GL_CULL_FACE );

		if ( cullType == CT_BACK_SIDED ) {
			if ( backEnd.viewParms.isMirror ) {
				qglCullFace( GL_FRONT );
			} else
			{
				qglCullFace( GL_BACK );
			}
		} else
		{
			if ( backEnd.viewParms.isMirror ) {
				qglCullFace( GL_BACK );
			} else
			{
				qglCullFace( GL_FRONT );
			}
		}
	}
}
Пример #2
0
void Terrain_DrawCam( terrainMesh_t *pm ) {
	qglColor3f( 1,1,1 );
	qglPushAttrib( GL_ALL_ATTRIB_BITS );

	if ( g_bPatchWireFrame ) {
		if( pm->bSelected ) {
			qglLineWidth( 2 );
		} else {
			qglLineWidth( 1 );
		}

		qglDisable( GL_CULL_FACE );
		qglPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
		qglDisable( GL_TEXTURE_2D );

		if ( g_PrefsDlg.m_bGLLighting ) {
			qglDisable( GL_LIGHTING );
		}

		DrawTerrain( pm, pm->bSelected, true );

		if ( g_PrefsDlg.m_bGLLighting ) {
			qglEnable( GL_LIGHTING );
		}

		qglEnable( GL_CULL_FACE );
		qglLineWidth( 1 );
	} else {
		qglEnable( GL_CULL_FACE );
		qglCullFace( GL_FRONT );

		// draw the textured polys
		DrawTerrain( pm, pm->bSelected, true );

		// if selected, draw the red tint on the polys
		if( pm->bSelected ) { // && ( g_qeglobals.d_savedinfo.include & INCLUDE_CAMERATINT ) ) {
			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 );

			DrawTerrain( pm, pm->bSelected );

			qglColor3f( 1, 1, 1 );
		}

		// draw the backside poly outlines
		qglCullFace( GL_BACK );
		qglPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
		qglDisable( GL_BLEND );
		DrawTerrain( pm, pm->bSelected, true );
	}

	qglPopAttrib();
}
Пример #3
0
/*
** GL_Cull
*/
void GL_Cull( int cullType ) {
    if ( glState.faceCulling == cullType ) {
        return;
    }

    glState.faceCulling = cullType;

    if ( cullType == CT_TWO_SIDED )
    {
        qglDisable( GL_CULL_FACE );
    }
    else
    {
        qboolean cullFront;
        qglEnable( GL_CULL_FACE );

        cullFront = (cullType == CT_FRONT_SIDED);
        if ( backEnd.viewParms.isMirror )
        {
            cullFront = !cullFront;
        }

        qglCullFace( cullFront ? GL_FRONT : GL_BACK );
    }
}
Пример #4
0
/*
** GL_Cull
*/
void
GL_Cull(int cullType)
{
#ifdef REACTION
	/* Makro - flip culling if needed */
	qbool flip =
		(backEnd.currentEntity != NULL && backEnd.currentEntity->mirrored != qfalse && cullType !=
	CT_TWO_SIDED);
	cullType ^= flip;	/* this assumes CT_BACK_SIDED and CT_FRONT_SIDED are 0 or 1 */
#endif

	if(glState.faceCulling == cullType){
		return;
	}

	glState.faceCulling = cullType;

	if(cullType == CT_TWO_SIDED){
		qglDisable(GL_CULL_FACE);
	}else{
		qbool cullFront;
		qglEnable(GL_CULL_FACE);

		cullFront = (cullType == CT_FRONT_SIDED);
		if(backEnd.viewParms.isMirror && !backEnd.viewParms.isShadowmap){
			cullFront = !cullFront;
		}

		qglCullFace(cullFront ? GL_FRONT : GL_BACK);
	}
}
Пример #5
0
void
R_SetDefaultState(void)
{
	qglClearColor(1, 0, 0.5, 0.5);
	qglCullFace(GL_FRONT);
	qglEnable(GL_TEXTURE_2D);

	qglEnable(GL_ALPHA_TEST);
	qglAlphaFunc(GL_GREATER, 0.666);

	qglDisable(GL_DEPTH_TEST);
	qglDisable(GL_CULL_FACE);
	qglDisable(GL_BLEND);

	qglColor4f(1, 1, 1, 1);

	qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	qglShadeModel(GL_FLAT);

	R_TextureMode(gl_texturemode->string);
	R_TextureAlphaMode(gl_texturealphamode->string);
	R_TextureSolidMode(gl_texturesolidmode->string);

	qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
	qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);

	qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

	qglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	R_TexEnv(GL_REPLACE);

	if (qglPointParameterfEXT)
	{
		float attenuations[3];

		attenuations[0] = gl_particle_att_a->value;
		attenuations[1] = gl_particle_att_b->value;
		attenuations[2] = gl_particle_att_c->value;

		/* GL_POINT_SMOOTH is not implemented by some OpenGL
		   drivers, especially the crappy Mesa3D backends like
		   i915.so. That the points are squares and not circles
		   is not a problem by Quake II! */
		qglEnable(GL_POINT_SMOOTH);
		qglPointParameterfEXT(GL_POINT_SIZE_MIN_EXT,
				gl_particle_min_size->value);
		qglPointParameterfEXT(GL_POINT_SIZE_MAX_EXT,
				gl_particle_max_size->value);
		qglPointParameterfvEXT(GL_DISTANCE_ATTENUATION_EXT, attenuations);
	}

	if (qglColorTableEXT && gl_ext_palettedtexture->value)
	{
		qglEnable(GL_SHARED_TEXTURE_PALETTE_EXT);

		R_SetTexturePalette(d_8to24table);
	}
}
Пример #6
0
/*
======================
RB_SetDefaultGLState

This should initialize all GL state that any part of the entire program
may touch, including the editor.
======================
*/
void RB_SetDefaultGLState( void ) {
	int		i;

	RB_LogComment( "--- R_SetDefaultGLState ---\n" );

	qglClearDepth( 1.0f );
	qglColor4f (1,1,1,1);

	// the vertex array is always enabled
	qglEnableClientState( GL_VERTEX_ARRAY );
	qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
	qglDisableClientState( GL_COLOR_ARRAY );

	//
	// make sure our GL state vector is set correctly
	//
	memset( &backEnd.glState, 0, sizeof( backEnd.glState ) );
	backEnd.glState.forceGlState = true;

	qglColorMask( 1, 1, 1, 1 );

	qglEnable( GL_DEPTH_TEST );
	qglEnable( GL_BLEND );
	qglEnable( GL_SCISSOR_TEST );
	qglEnable( GL_CULL_FACE );
	qglDisable( GL_LIGHTING );
	qglDisable( GL_LINE_STIPPLE );
	qglDisable( GL_STENCIL_TEST );

	qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
	qglDepthMask( GL_TRUE );
	qglDepthFunc( GL_ALWAYS );
 
	qglCullFace( GL_FRONT_AND_BACK );
	qglShadeModel( GL_SMOOTH );

	if ( r_useScissor.GetBool() ) {
		qglScissor( 0, 0, glConfig.vidWidth, glConfig.vidHeight );
	}

	for ( i = glConfig.maxTextureUnits - 1 ; i >= 0 ; i-- ) {
		GL_SelectTexture( i );

		// object linear texgen is our default
		qglTexGenf( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
		qglTexGenf( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
		qglTexGenf( GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );
		qglTexGenf( GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR );

		GL_TexEnv( GL_MODULATE );
		qglDisable( GL_TEXTURE_2D );
		if ( glConfig.texture3DAvailable ) {
			qglDisable( GL_TEXTURE_3D );
		}
		if ( glConfig.cubeMapAvailable ) {
			qglDisable( GL_TEXTURE_CUBE_MAP_EXT );
		}
	}
}
Пример #7
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 );

    //
    // make sure our GL state vector is set correctly
    //
    glState.glStateBits = GLS_DEPTHTEST_DISABLE | GLS_DEPTHMASK_TRUE;
    glState.storedGlState = 0;
    glState.faceCulling = CT_TWO_SIDED;
    glState.faceCullFront = qtrue;

    glState.currentProgram = 0;
    qglUseProgramObjectARB(0);

    if (glRefConfig.vertexArrayObject)
        qglBindVertexArrayARB(0);

    qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
    qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
    glState.currentVao = NULL;
    glState.vertexAttribsEnabled = 0;

    qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
    qglDepthMask( GL_TRUE );
    qglDisable( GL_DEPTH_TEST );
    qglEnable( GL_SCISSOR_TEST );
    qglDisable( GL_CULL_FACE );
    qglDisable( GL_BLEND );

    if (glRefConfig.seamlessCubeMap)
        qglEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);

    // GL_POLYGON_OFFSET_FILL will be glEnable()d when this is used
    qglPolygonOffset( r_offsetFactor->value, r_offsetUnits->value );

    qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f );	// FIXME: get color of sky
}
Пример #8
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;

	qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
	qglDepthMask( GL_TRUE );
	qglDisable( GL_DEPTH_TEST );
	qglEnable( GL_SCISSOR_TEST );
	qglDisable( GL_CULL_FACE );
	qglDisable( GL_BLEND );

	qglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
	qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
	qglClearDepth( 1.0 );

	qglDrawBuffer( GL_FRONT );
#ifdef IOS
	qglClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT );
#else
	qglClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ACCUM_BUFFER_BIT|GL_STENCIL_BUFFER_BIT );
#endif
	qglDrawBuffer( GL_BACK );
#ifdef IOS
	qglClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT );
#else
	qglClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ACCUM_BUFFER_BIT|GL_STENCIL_BUFFER_BIT );
#endif
}
Пример #9
0
/*
 ==================
 GL_CullFace
 ==================
*/
void GL_CullFace (uint mode){

	if (glState.cullMode == mode)
		return;

	glState.cullMode = mode;

	qglCullFace(mode);
}
Пример #10
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 );

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

	glState.vertexAttribsState = 0;
	glState.vertexAttribPointersSet = 0;
	glState.currentProgram = 0;
	qglUseProgramObjectARB(0);

	qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
	qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
	glState.currentVBO = NULL;
	glState.currentIBO = NULL;

	qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
	qglDepthMask( GL_TRUE );
	qglDisable( GL_DEPTH_TEST );
	qglEnable( GL_SCISSOR_TEST );
	qglDisable( GL_CULL_FACE );
	qglDisable( GL_BLEND );

	qglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
	qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
	qglClearDepth( 1.0 );

	qglDrawBuffer( GL_FRONT );
	qglClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ACCUM_BUFFER_BIT|GL_STENCIL_BUFFER_BIT );

	qglDrawBuffer( GL_BACK );
	qglClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_ACCUM_BUFFER_BIT|GL_STENCIL_BUFFER_BIT );
}
Пример #11
0
/*
===================
RB_OutlinesPass

Draws outlines on surfaces with shader.hasOutlines set
===================
*/
static void RB_OutlinesPass( void ) {	

	int		outlines;
	float	outlinesAlpha;

	outlines		= r_outlines->value;
	outlinesAlpha	= r_outlinesAlpha->value;

	if ( !tess.shader->hasOutlines )
		return;	

	if ( !r_outlines->integer )
		return;

	GL_Bind( tr.whiteImage );
	qglColor4f( 0, 0, 0, outlinesAlpha );
		
	GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA );
	qglPolygonMode( GL_BACK, GL_LINE );
	qglLineWidth( outlines + 1 );
			
	qglCullFace( GL_BACK );
		
	qglDisableClientState( GL_COLOR_ARRAY );
	qglDisableClientState( GL_TEXTURE_COORD_ARRAY );

	qglVertexPointer (3, GL_FLOAT, 16, tess.xyz);	// padded for SIMD
			
	if (qglLockArraysEXT) {
		qglLockArraysEXT(0, tess.numVertexes);
		GLimp_LogComment( "glLockArraysEXT\n" );
	}
	
	R_DrawElements( tess.numIndexes, tess.indexes );
		
	if (qglUnlockArraysEXT) {
		qglUnlockArraysEXT();
		GLimp_LogComment( "glUnlockArraysEXT\n" );
	}

	// FIX: Must reset these manually or renderer will b0rk!
	qglCullFace( GL_FRONT ); 
	qglLineWidth( 1 );
}
Пример #12
0
/*
** GL_SetDefaultState
*/
void GL_SetDefaultState( void )
{
	//qglClearColor (1,0, 0.5 , 0.5); // NeVo - f*****g ugly color!
	qglClearColor (0,0,0,1);	// NeVo - clear to black
	qglCullFace(GL_FRONT);
	qglEnable(GL_TEXTURE_2D);

	qglEnable(GL_ALPHA_TEST);
	qglAlphaFunc(GL_GREATER, 0.666);

	qglDisable (GL_DEPTH_TEST);
	qglDisable (GL_CULL_FACE);
	qglDisable (GL_BLEND);

	qglColor4f (1,1,1,1);

	qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
	qglShadeModel (GL_FLAT);

	GL_TextureMode( gl_texturemode->string );
	GL_TextureAlphaMode( gl_texturealphamode->string );
	GL_TextureSolidMode( gl_texturesolidmode->string );

	qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
	qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);

	qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

	qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	GL_TexEnv( GL_REPLACE );

	if ( qglPointParameterfEXT )
	{
		float attenuations[3];

		attenuations[0] = gl_particle_att_a->value;
		attenuations[1] = gl_particle_att_b->value;
		attenuations[2] = gl_particle_att_c->value;

		qglEnable( GL_POINT_SMOOTH );
		qglPointParameterfEXT( GL_POINT_SIZE_MIN_EXT, gl_particle_min_size->value );
		qglPointParameterfEXT( GL_POINT_SIZE_MAX_EXT, gl_particle_max_size->value );
		qglPointParameterfvEXT( GL_DISTANCE_ATTENUATION_EXT, attenuations );
	}

	if ( qglColorTableEXT && gl_ext_palettedtexture->value )
	{
		qglEnable( GL_SHARED_TEXTURE_PALETTE_EXT );

		GL_SetTexturePalette( d_8to24table );
	}

	GL_UpdateSwapInterval();
}
Пример #13
0
/*
** GL_Cull
*/
void GL_Cull( int cullType ) {
	if ( glState.faceCulling == cullType ) {
		return;
	}

	glState.faceCulling = cullType;
	if (backEnd.projection2D){	//don't care, we're in 2d when it's always disabled
		return;	
	}

	if ( cullType == CT_TWO_SIDED ) 
	{
		qglDisable( GL_CULL_FACE );
	} 
	else 
	{
		qglEnable( GL_CULL_FACE );

		if ( cullType == CT_BACK_SIDED )
		{
			if ( backEnd.viewParms.isMirror )
			{
				qglCullFace( GL_FRONT );
			}
			else
			{
				qglCullFace( GL_BACK );
			}
		}
		else
		{
			if ( backEnd.viewParms.isMirror )
			{
				qglCullFace( GL_BACK );
			}
			else
			{
				qglCullFace( GL_FRONT );
			}
		}
	}
}
Пример #14
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;

	qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
	qglDepthMask( GL_TRUE );
	qglDisable( GL_DEPTH_TEST );
	qglEnable( GL_SCISSOR_TEST );
	qglDisable( GL_CULL_FACE );
	qglDisable( GL_BLEND );

#ifdef _NPATCH
	// If n-patches are supported, make sure they are disabled for now
	// Set the initial tesselation level and the interpolation modes
	if ( qglPNTrianglesiATI )
	{
		qglDisable( GL_PN_TRIANGLES_ATI );
		qglPNTrianglesiATI( GL_PN_TRIANGLES_POINT_MODE_ATI, GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI );
		qglPNTrianglesiATI( GL_PN_TRIANGLES_NORMAL_MODE_ATI, GL_PN_TRIANGLES_NORMAL_MODE_QUADRATIC_ATI );
		qglPNTrianglesiATI( GL_PN_TRIANGLES_TESSELATION_LEVEL_ATI, 3 );
	}
#endif // _NPATCH
}
Пример #15
0
/*
** GL_SetDefaultState
*/
void GL_SetDefaultState( void )
{
	qglClearDepth( 1.0f );

	qglCullFace(GL_FRONT);

	qglColor4f (1,1,1,1);

	GL_BindNullTextures();

	if (glRefConfig.framebufferObject)
		GL_BindNullFramebuffers();

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

	//qglShadeModel( GL_SMOOTH );
	qglDepthFunc( GL_LEQUAL );

	//
	// make sure our GL state vector is set correctly
	//
	glState.glStateBits = GLS_DEPTHTEST_DISABLE | GLS_DEPTHMASK_TRUE;
	glState.storedGlState = 0;
	glState.faceCulling = CT_TWO_SIDED;
	glState.faceCullFront = qtrue;

	GL_BindNullProgram();

	if (glRefConfig.vertexArrayObject)
		qglBindVertexArray(0);

	qglBindBuffer(GL_ARRAY_BUFFER, 0);
	qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	glState.currentVao = NULL;
	glState.vertexAttribsEnabled = 0;

	qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
	qglDepthMask( GL_TRUE );
	qglDisable( GL_DEPTH_TEST );
	qglEnable( GL_SCISSOR_TEST );
	qglDisable( GL_CULL_FACE );
	qglDisable( GL_BLEND );

	if (glRefConfig.seamlessCubeMap)
		qglEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);

	// GL_POLYGON_OFFSET_FILL will be glEnable()d when this is used
	qglPolygonOffset( r_offsetFactor->value, r_offsetUnits->value );

	qglClearColor( 0.0f, 0.0f, 0.0f, 1.0f );	// FIXME: get color of sky
}
Пример #16
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;

	glState.vertexAttribsState = 0;
	glState.vertexAttribPointersSet = 0;
	glState.currentProgram = 0;
	qglUseProgramObjectARB(0);

	qglBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
	qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
	glState.currentVBO	= NULL;
	glState.currentIBO	= NULL;

	qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
	qglDepthMask(GL_TRUE);
	qglDisable(GL_DEPTH_TEST);
	qglEnable(GL_SCISSOR_TEST);
	qglDisable(GL_CULL_FACE);
	qglDisable(GL_BLEND);
}
Пример #17
0
/*
** GL_SetDefaultState
*/
void GL_SetDefaultState( void )
{
	qglClearColor (1.0f, 0.0f, 0.5f, 0.5f);
	qglCullFace(GL_FRONT);
	qglEnable(GL_TEXTURE_2D);

	qglEnable(GL_ALPHA_TEST);
	qglAlphaFunc(GL_GREATER, 0.666f);

	qglDisable (GL_DEPTH_TEST);
	qglDisable (GL_CULL_FACE);
	qglDisable (GL_BLEND);

	qglColor4fv(colorWhite);

	qglPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
	qglShadeModel (GL_FLAT);

	GL_TextureMode( gl_texturemode->string );
	GL_TextureAlphaMode( gl_texturealphamode->string );
	GL_TextureSolidMode( gl_texturesolidmode->string );

	qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min);
	qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max);

	qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

	qglBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	GL_TexEnv( GL_REPLACE );

	if ( qglPointParameterfEXT && FLOAT_NE_ZERO(gl_ext_pointparameters->value))
	{
		float attenuations[3];

		attenuations[0] = gl_particle_att_a->value;
		attenuations[1] = gl_particle_att_b->value;
		attenuations[2] = gl_particle_att_c->value;

		qglEnable( GL_POINT_SMOOTH );
		qglPointParameterfEXT( GL_POINT_SIZE_MIN_EXT, gl_particle_min_size->value );
		qglPointParameterfEXT( GL_POINT_SIZE_MAX_EXT, gl_particle_max_size->value );
		qglPointParameterfvEXT( GL_DISTANCE_ATTENUATION_EXT, attenuations );
	}

	gl_swapinterval->modified = true;
	GL_UpdateSwapInterval();
}
Пример #18
0
/*
* RB_Cull
*/
void RB_Cull( int cull )
{
    if( rb.gl.faceCull == cull )
        return;

    if( !cull )
    {
        qglDisable( GL_CULL_FACE );
        rb.gl.faceCull = 0;
        return;
    }

    if( !rb.gl.faceCull )
        qglEnable( GL_CULL_FACE );
    qglCullFace( cull );
    rb.gl.faceCull = cull;
}
Пример #19
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;

	glPixelStorei(GL_PACK_ALIGNMENT, 1);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	//*SEB* ? not the best place !
	glLockArraysEXT   = NULL;
	glUnlockArraysEXT = NULL;

	qglDepthMask(GL_TRUE);
	qglDisable(GL_DEPTH_TEST);
	qglEnable(GL_SCISSOR_TEST);
	qglDisable(GL_CULL_FACE);
	qglDisable(GL_BLEND);
}
Пример #20
0
/*
** GL_Cull
*/
void GL_Cull( int cullType ) {
	if ( glState.faceCulling == cullType ) {
		return;
	}

	if ( cullType == CT_TWO_SIDED ) 
	{
		qglDisable( GL_CULL_FACE );
	} 
	else 
	{
		qboolean cullFront = (cullType == CT_FRONT_SIDED);

		if ( glState.faceCulling == CT_TWO_SIDED )
			qglEnable( GL_CULL_FACE );

		if ( glState.faceCullFront != cullFront )
			qglCullFace( cullFront ? GL_FRONT : GL_BACK );

		glState.faceCullFront = cullFront;
	}

	glState.faceCulling = cullType;
}
Пример #21
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;

#ifdef USE_OPENGLES
	glPixelStorei(GL_PACK_ALIGNMENT, 1);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
#else
	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 USE_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 );
	}
//----(SA)	end
#endif

	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);
	}
}
Пример #22
0
void StencilShadow::RenderShadow()
{
#ifndef DISABLE_STENCILSHADOW
	DWORD lighting, fog, srcblend, destblend, alphablend, zwrite, zfunc, cullmode;

	GL_State(GLS_DEFAULT);

	glw_state->device->GetRenderState( D3DRS_LIGHTING, &lighting );
	glw_state->device->GetRenderState( D3DRS_FOGENABLE, &fog );
	glw_state->device->GetRenderState( D3DRS_SRCBLEND, &srcblend );
	glw_state->device->GetRenderState( D3DRS_DESTBLEND, &destblend );
	glw_state->device->GetRenderState( D3DRS_ALPHABLENDENABLE, &alphablend );
	glw_state->device->GetRenderState( D3DRS_ZWRITEENABLE, &zwrite );
	glw_state->device->GetRenderState( D3DRS_ZFUNC, &zfunc );
	glw_state->device->GetRenderState( D3DRS_CULLMODE, &cullmode );

	pVerts = NULL;
	pExtrusions = NULL;

	GL_Bind( tr.whiteImage );

	glw_state->device->SetRenderState( D3DRS_LIGHTING, FALSE );
	glw_state->device->SetRenderState( D3DRS_FOGENABLE, FALSE );

	glw_state->device->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
	glw_state->device->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO );

    // Disable z-buffer writes (note: z-testing still occurs), and enable the
    // stencil-buffer
    glw_state->device->SetRenderState( D3DRS_ZWRITEENABLE,  FALSE );
    glw_state->device->SetRenderState( D3DRS_STENCILENABLE, TRUE );

    // Don't bother with interpolating color
    glw_state->device->SetRenderState( D3DRS_SHADEMODE,     D3DSHADE_FLAT );

	glw_state->device->SetRenderState( D3DRS_ZFUNC,			D3DCMP_LESS );

    // Set up stencil compare function, reference value, and masks.
    // Stencil test passes if ((ref & mask) cmpfn (stencil & mask)) is true.
    // Note: since we set up the stencil-test to always pass, the STENCILFAIL
    // renderstate is really not needed.
    glw_state->device->SetRenderState( D3DRS_STENCILFUNC,   D3DCMP_ALWAYS );
#ifdef _STENCIL_REVERSE
	glw_state->device->SetRenderState( D3DRS_STENCILZFAIL,  D3DSTENCILOP_INCR );
    glw_state->device->SetRenderState( D3DRS_STENCILFAIL,   D3DSTENCILOP_KEEP );
	glw_state->device->SetRenderState( D3DRS_STENCILPASS,   D3DSTENCILOP_KEEP );
#else
	glw_state->device->SetRenderState( D3DRS_STENCILZFAIL,  D3DSTENCILOP_KEEP );
    glw_state->device->SetRenderState( D3DRS_STENCILFAIL,   D3DSTENCILOP_KEEP );
	glw_state->device->SetRenderState( D3DRS_STENCILPASS,   D3DSTENCILOP_INCR );	
#endif

    // If ztest passes, inc/decrement stencil buffer value
    glw_state->device->SetRenderState( D3DRS_STENCILREF,       0x1 );
    glw_state->device->SetRenderState( D3DRS_STENCILMASK,      0x7f ); //0xffffffff );
    glw_state->device->SetRenderState( D3DRS_STENCILWRITEMASK, 0x7f ); //0xffffffff );

    // Make sure that no pixels get drawn to the frame buffer
    glw_state->device->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE );
    glw_state->device->SetRenderState( D3DRS_COLORWRITEENABLE, 0 );

	glw_state->device->SetTexture(0, NULL);
	glw_state->device->SetTexture(1, NULL);

	// Compute the matrix set
    XGMATRIX matComposite, matProjectionViewport, matWorld;
	glw_state->device->GetProjectionViewportMatrix( &matProjectionViewport );

	XGMatrixMultiply( &matComposite, (XGMATRIX*)glw_state->matrixStack[glwstate_t::MatrixMode_Model]->GetTop(), &matProjectionViewport );

	// Transpose and set the composite matrix.
	XGMatrixTranspose( &matComposite, &matComposite );
	glw_state->device->SetVertexShaderConstant( CV_WORLDVIEWPROJ_0, &matComposite, 4 );

	// Set viewport offsets.
	float fViewportOffsets[4] = { 0.53125f, 0.53125f, 0.0f, 0.0f };
	glw_state->device->SetVertexShaderConstant( CV_VIEWPORT_OFFSETS, &fViewportOffsets, 1 );

	glw_state->device->SetVertexShader(m_dwVertexShaderShadow);

#ifdef _STENCIL_REVERSE
	qglCullFace( GL_FRONT );
#else
	qglCullFace( GL_BACK );
#endif

	BuildEdges();

	// Draw front-side of shadow volume in stencil/z only
	if(m_nIndexes)
        renderObject_Shadow( D3DPT_QUADLIST, m_nIndexes, m_shadowIndexes );
#ifdef _STENCIL_REVERSE
	if(m_nIndexesCap)
        renderObject_Shadow( D3DPT_TRIANGLELIST, m_nIndexesCap, m_shadowIndexesCap );
#endif

	// Now reverse cull order so back sides of shadow volume are written.
#ifdef _STENCIL_REVERSE
	qglCullFace( GL_BACK );
#else
    qglCullFace( GL_FRONT );
#endif

    // Decrement stencil buffer value
#ifdef _STENCIL_REVERSE
	glw_state->device->SetRenderState( D3DRS_STENCILZFAIL, D3DSTENCILOP_DECR );
#else
	glw_state->device->SetRenderState( D3DRS_STENCILPASS, D3DSTENCILOP_DECR );
#endif

	// Draw back-side of shadow volume in stencil/z only
	if(m_nIndexes)
        renderObject_Shadow( D3DPT_QUADLIST, m_nIndexes, m_shadowIndexes );
#ifdef _STENCIL_REVERSE
	if(m_nIndexesCap)
        renderObject_Shadow( D3DPT_TRIANGLELIST, m_nIndexesCap, m_shadowIndexesCap );
#endif

	// Restore render states
	glw_state->device->SetRenderState( D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALL );

    glw_state->device->SetRenderState( D3DRS_SHADEMODE, D3DSHADE_GOURAUD );
	glw_state->device->SetRenderState( D3DRS_STENCILENABLE,    FALSE );
	glw_state->device->SetRenderState( D3DRS_LIGHTING, lighting );
	glw_state->device->SetRenderState( D3DRS_FOGENABLE, fog );
	glw_state->device->SetRenderState( D3DRS_SRCBLEND, srcblend );
	glw_state->device->SetRenderState( D3DRS_DESTBLEND, destblend );
	glw_state->device->SetRenderState( D3DRS_ALPHABLENDENABLE, alphablend );
	glw_state->device->SetRenderState( D3DRS_ZWRITEENABLE, zwrite );
	glw_state->device->SetRenderState( D3DRS_ZFUNC, zfunc );
	glw_state->device->SetRenderState( D3DRS_CULLMODE, cullmode );
#endif
}
Пример #23
0
void RB_DoShadowTessEnd( vec3_t lightPos )
{
#ifndef _XBOX
	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
#endif // _XBOX
}
Пример #24
0
/*
==============
RenderBumpFlat_f

==============
*/
void RenderBumpFlat_f( const idCmdArgs &args ) {
	int		width, height;
	idStr	source;
	int		i;
	idBounds	bounds;
	srfTriangles_t	*mesh;

	// update the screen as we print
	common->SetRefreshOnPrint( true );

	width = height = 256;

	// check options
	for ( i = 1 ; i < args.Argc() - 1; i++ ) {
		const char *s;

		s = args.Argv( i );
		if ( s[0] == '-' ) {
			i++;
			s = args.Argv( i );
		}

		if ( !idStr::Icmp( s, "size" ) ) {
			if ( i + 2 >= args.Argc() ) {
				i = args.Argc();
				break;
			}
			width = atoi( args.Argv( i + 1 ) );
			height = atoi( args.Argv( i + 2 ) );
			i += 2;
		} else {
			common->Printf( "WARNING: Unknown option \"%s\"\n", s );
			break;
		}
	}

	if ( i != ( args.Argc() - 1 ) ) {
		common->Error( "usage: renderBumpFlat [-size width height] asefile" );
		return;
	}

	common->Printf( "Final image size: %i, %i\n", width, height );

	// load the source in "fastload" mode, because we don't
	// need tangent and shadow information
	source = args.Argv( i );

	idRenderModel *highPolyModel = renderModelManager->AllocModel();

	highPolyModel->PartialInitFromFile( source );

	if ( highPolyModel->IsDefaultModel() ) {
		common->Error( "failed to load %s", source.c_str() );
	}

	// combine the high poly model into a single polyset
	if ( highPolyModel->NumSurfaces() != 1 ) {
		highPolyModel = CombineModelSurfaces( highPolyModel );
	}

	// create normals if not present in file
	const modelSurface_t *surf = highPolyModel->Surface( 0 );
	mesh = surf->geometry;

	// bound the entire file
	R_BoundTriSurf( mesh );
	bounds = mesh->bounds;

	SaveWindow();
	ResizeWindow( width, height );

	// for small images, the viewport may be less than the minimum window
	qglViewport( 0, 0, width, height );

	qglEnable( GL_CULL_FACE );
	qglCullFace( GL_FRONT );
	qglDisable( GL_STENCIL_TEST );
	qglDisable( GL_SCISSOR_TEST );
	qglDisable( GL_ALPHA_TEST );
	qglDisable( GL_BLEND );
	qglEnable( GL_DEPTH_TEST );
	qglDisable( GL_TEXTURE_2D );
	qglDepthMask( GL_TRUE );
	qglDepthFunc( GL_LEQUAL );

	qglColor3f( 1, 1, 1 );

	qglMatrixMode( GL_PROJECTION );
	qglLoadIdentity();
	qglOrtho( bounds[0][0], bounds[1][0], bounds[0][2],
		bounds[1][2], -( bounds[0][1] - 1 ), -( bounds[1][1] + 1 ) );

	qglMatrixMode( GL_MODELVIEW );
	qglLoadIdentity();

	// flat maps are automatically anti-aliased

	idStr	filename;
	int		j, k, c;
	byte	*buffer;
	int		*sumBuffer, *colorSumBuffer;
	bool	flat;
	int		sample;

	sumBuffer = (int *)Mem_Alloc( width * height * 4 * 4 );
	memset( sumBuffer, 0, width * height * 4 * 4 );
	buffer = (byte *)Mem_Alloc( width * height * 4 );

	colorSumBuffer = (int *)Mem_Alloc( width * height * 4 * 4 );
	memset( sumBuffer, 0, width * height * 4 * 4 );

	flat = false;
//flat = true;

	for ( sample = 0 ; sample < 16 ; sample++ ) {
		float	xOff, yOff;

		xOff = ( ( sample & 3 ) / 4.0 ) * ( bounds[1][0] - bounds[0][0] ) / width;
		yOff = ( ( sample / 4 ) / 4.0 ) * ( bounds[1][2] - bounds[0][2] ) / height;

		for ( int colorPass = 0 ; colorPass < 2 ; colorPass++ ) {
			qglClearColor(0.5,0.5,0.5,0);
			qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

			qglBegin( GL_TRIANGLES );
			for ( i = 0 ; i < highPolyModel->NumSurfaces() ; i++ ) {
				const modelSurface_t *surf = highPolyModel->Surface( i );

				mesh = surf->geometry;

				if ( colorPass ) {
					// just render the surface color for artist visualization
					for ( j = 0 ; j < mesh->numIndexes ; j+=3 ) {
						for ( k = 0 ; k < 3 ; k++ ) {
							int		v;
							float	*a;

							v = mesh->indexes[j+k];
							qglColor3ubv( mesh->verts[v].color );
							a = mesh->verts[v].xyz.ToFloatPtr();
							qglVertex3f( a[0] + xOff, a[2] + yOff, a[1] );
						}
					}
				} else {
					// render as normal map
					// we can either flat shade from the plane,
					// or smooth shade from the vertex normals
					for ( j = 0 ; j < mesh->numIndexes ; j+=3 ) {
						if ( flat ) {
							idPlane		plane;
							idVec3		*a, *b, *c;
							int			v1, v2, v3;

							v1 = mesh->indexes[j+0];
							v2 = mesh->indexes[j+1];
							v3 = mesh->indexes[j+2];

							a = &mesh->verts[ v1 ].xyz;
							b = &mesh->verts[ v2 ].xyz;
							c = &mesh->verts[ v3 ].xyz;

							plane.FromPoints( *a, *b, *c );

							// NULLNORMAL is used by the artists to force an area to reflect no
							// light at all
							if ( surf->shader->GetSurfaceFlags() & SURF_NULLNORMAL ) {
								qglColor3f( 0.5, 0.5, 0.5 );
							} else {
								qglColor3f( 0.5 + 0.5*plane[0], 0.5 - 0.5*plane[2], 0.5 - 0.5*plane[1] );
							}

							qglVertex3f( (*a)[0] + xOff, (*a)[2] + yOff, (*a)[1] );
							qglVertex3f( (*b)[0] + xOff, (*b)[2] + yOff, (*b)[1] );
							qglVertex3f( (*c)[0] + xOff, (*c)[2] + yOff, (*c)[1] );
						} else {
							for ( k = 0 ; k < 3 ; k++ ) {
								int		v;
								float	*n;
								float	*a;

								v = mesh->indexes[j+k];
								n = mesh->verts[v].normal.ToFloatPtr();

								// NULLNORMAL is used by the artists to force an area to reflect no
								// light at all
								if ( surf->shader->GetSurfaceFlags() & SURF_NULLNORMAL ) {
									qglColor3f( 0.5, 0.5, 0.5 );
								} else {
								// we are going to flip the normal Z direction
									qglColor3f( 0.5 + 0.5*n[0], 0.5 - 0.5*n[2], 0.5 - 0.5*n[1] );
								}

								a = mesh->verts[v].xyz.ToFloatPtr();
								qglVertex3f( a[0] + xOff, a[2] + yOff, a[1] );
							}
						}
					}
				}
			}

			qglEnd();
			qglFlush();
			GLimp_SwapBuffers();
			qglReadPixels( 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer );

			c = width * height;

			if ( colorPass ) {
				// add to the sum buffer
				for ( i = 0 ; i < c ; i++ ) {
					colorSumBuffer[i*4+0] += buffer[i*4+0];
					colorSumBuffer[i*4+1] += buffer[i*4+1];
					colorSumBuffer[i*4+2] += buffer[i*4+2];
					colorSumBuffer[i*4+3] += buffer[i*4+3];
				}
			} else {
				// normalize
				for ( i = 0 ; i < c ; i++ ) {
					idVec3	v;

					v[0] = ( buffer[i*4+0] - 128 ) / 127.0;
					v[1] = ( buffer[i*4+1] - 128 ) / 127.0;
					v[2] = ( buffer[i*4+2] - 128 ) / 127.0;

					v.Normalize();

					buffer[i*4+0] = 128 + 127 * v[0];
					buffer[i*4+1] = 128 + 127 * v[1];
					buffer[i*4+2] = 128 + 127 * v[2];
				}

				// outline into non-drawn areas
				for ( i = 0 ; i < 8 ; i++ ) {
					OutlineNormalMap( buffer, width, height, 128, 128, 128 );
				}

				// add to the sum buffer
				for ( i = 0 ; i < c ; i++ ) {
					sumBuffer[i*4+0] += buffer[i*4+0];
					sumBuffer[i*4+1] += buffer[i*4+1];
					sumBuffer[i*4+2] += buffer[i*4+2];
					sumBuffer[i*4+3] += buffer[i*4+3];
				}
			}
		}
	}

	c = width * height;

	// save out the color map
	for ( i = 0 ; i < c ; i++ ) {
		buffer[i*4+0] = colorSumBuffer[i*4+0] / 16;
		buffer[i*4+1] = colorSumBuffer[i*4+1] / 16;
		buffer[i*4+2] = colorSumBuffer[i*4+2] / 16;
		buffer[i*4+3] = colorSumBuffer[i*4+3] / 16;
	}
	filename = source;
	filename.StripFileExtension();
	filename.Append( "_color.tga" );
	R_VerticalFlip( buffer, width, height );
	R_WriteTGA( filename, buffer, width, height );

	// save out the local map
	// scale the sum buffer back down to the sample buffer
	// we allow this to denormalize
	for ( i = 0 ; i < c ; i++ ) {
		buffer[i*4+0] = sumBuffer[i*4+0] / 16;
		buffer[i*4+1] = sumBuffer[i*4+1] / 16;
		buffer[i*4+2] = sumBuffer[i*4+2] / 16;
		buffer[i*4+3] = sumBuffer[i*4+3] / 16;
	}

	filename = source;
	filename.StripFileExtension();
	filename.Append( "_local.tga" );
	common->Printf( "writing %s (%i,%i)\n", filename.c_str(), width, height );
	R_VerticalFlip( buffer, width, height );
	R_WriteTGA( filename, buffer, width, height );


	// free the model
	renderModelManager->FreeModel( highPolyModel );

	// free our work buffer
	Mem_Free( buffer );
	Mem_Free( sumBuffer );
	Mem_Free( colorSumBuffer );

	RestoreWindow();

	// stop updating the screen as we print
	common->SetRefreshOnPrint( false );

	common->Error( "Completed." );
}
Пример #25
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;

	// 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
	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
	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( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
}
Пример #26
0
/*
=================
R_DrawAliasModel

=================
*/
void R_DrawAliasModel (entity_t *e)
{
	int			i;
	dmdl_t		*paliashdr;
	float		an;
	vec3_t		bbox[8];
	image_t		*skin;

	if ( !( e->flags & RF_WEAPONMODEL ) )
	{
		if ( R_CullAliasModel( bbox, e ) )
			return;
	}

	if ( e->flags & RF_WEAPONMODEL )
	{
		if ( r_lefthand->value == 2 )
			return;
	}

	paliashdr = (dmdl_t *)currentmodel->extradata;

	//
	// get lighting information
	//
	// PMM - rewrote, reordered to handle new shells & mixing
	//
	if ( currententity->flags & ( RF_SHELL_HALF_DAM | RF_SHELL_GREEN | RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE ) )
	{
		// PMM -special case for godmode
		if ( (currententity->flags & RF_SHELL_RED) &&
			(currententity->flags & RF_SHELL_BLUE) &&
			(currententity->flags & RF_SHELL_GREEN) )
		{
			for (i=0 ; i<3 ; i++)
				shadelight[i] = 1.0;
		}
		else if ( currententity->flags & ( RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE ) )
		{
			VectorClear (shadelight);

			if ( currententity->flags & RF_SHELL_RED )
			{
				shadelight[0] = 1.0;
				if (currententity->flags & (RF_SHELL_BLUE|RF_SHELL_DOUBLE) )
					shadelight[2] = 1.0;
			}
			else if ( currententity->flags & RF_SHELL_BLUE )
			{
				if ( currententity->flags & RF_SHELL_DOUBLE )
				{
					shadelight[1] = 1.0;
					shadelight[2] = 1.0;
				}
				else
				{
					shadelight[2] = 1.0;
				}
			}
			else if ( currententity->flags & RF_SHELL_DOUBLE )
			{
				shadelight[0] = 0.9;
				shadelight[1] = 0.7;
			}
		}
		else if ( currententity->flags & ( RF_SHELL_HALF_DAM | RF_SHELL_GREEN ) )
		{
			VectorClear (shadelight);
			// PMM - new colors
			if ( currententity->flags & RF_SHELL_HALF_DAM )
			{
				shadelight[0] = 0.56;
				shadelight[1] = 0.59;
				shadelight[2] = 0.45;
			}
			if ( currententity->flags & RF_SHELL_GREEN )
			{
				shadelight[1] = 1.0;
			}
		}
	}
			//PMM - ok, now flatten these down to range from 0 to 1.0.
	//		max_shell_val = max(shadelight[0], max(shadelight[1], shadelight[2]));
	//		if (max_shell_val > 0)
	//		{
	//			for (i=0; i<3; i++)
	//			{
	//				shadelight[i] = shadelight[i] / max_shell_val;
	//			}
	//		}
	// pmm
	else if ( currententity->flags & RF_FULLBRIGHT )
	{
		for (i=0 ; i<3 ; i++)
			shadelight[i] = 1.0;
	}
	else
	{
		R_LightPoint (currententity->origin, shadelight);

		// player lighting hack for communication back to server
		// big hack!
		if ( currententity->flags & RF_WEAPONMODEL )
		{
			// pick the greatest component, which should be the same
			// as the mono value returned by software
			if (shadelight[0] > shadelight[1])
			{
				if (shadelight[0] > shadelight[2])
					r_lightlevel->value = 150*shadelight[0];
				else
					r_lightlevel->value = 150*shadelight[2];
			}
			else
			{
				if (shadelight[1] > shadelight[2])
					r_lightlevel->value = 150*shadelight[1];
				else
					r_lightlevel->value = 150*shadelight[2];
			}

		}
		
		if ( gl_monolightmap->string[0] != '0' )
		{
			float s = shadelight[0];

			if ( s < shadelight[1] )
				s = shadelight[1];
			if ( s < shadelight[2] )
				s = shadelight[2];

			shadelight[0] = s;
			shadelight[1] = s;
			shadelight[2] = s;
		}
	}

	if ( currententity->flags & RF_MINLIGHT )
	{
		for (i=0 ; i<3 ; i++)
			if (shadelight[i] > 0.1)
				break;
		if (i == 3)
		{
			shadelight[0] = 0.1;
			shadelight[1] = 0.1;
			shadelight[2] = 0.1;
		}
	}

	if ( currententity->flags & RF_GLOW )
	{	// bonus items will pulse with time
		float	scale;
		float	min;

		scale = 0.1 * sin(r_newrefdef.time*7);
		for (i=0 ; i<3 ; i++)
		{
			min = shadelight[i] * 0.8;
			shadelight[i] += scale;
			if (shadelight[i] < min)
				shadelight[i] = min;
		}
	}

// =================
// PGM	ir goggles color override
	if ( r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE)
	{
		shadelight[0] = 1.0;
		shadelight[1] = 0.0;
		shadelight[2] = 0.0;
	}
// PGM	
// =================

	shadedots = r_avertexnormal_dots[((int)(currententity->angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)];
	
	an = currententity->angles[1]/180*M_PI;
	shadevector[0] = cos(-an);
	shadevector[1] = sin(-an);
	shadevector[2] = 1;
	VectorNormalize (shadevector);

	//
	// locate the proper data
	//

	c_alias_polys += paliashdr->num_tris;

	//
	// draw all the triangles
	//
	if (currententity->flags & RF_DEPTHHACK) // hack the depth range to prevent view model from poking into walls
		qglDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin));

	if ( ( currententity->flags & RF_WEAPONMODEL ) && ( r_lefthand->value == 1.0F ) )
	{
		extern void MYgluPerspective( GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar );

		qglMatrixMode( GL_PROJECTION );
		qglPushMatrix();
		qglLoadIdentity();
		qglScalef( -1, 1, 1 );
	    MYgluPerspective( r_newrefdef.fov_y, ( float ) r_newrefdef.width / r_newrefdef.height,  4,  4096);
		qglMatrixMode( GL_MODELVIEW );

		qglCullFace( GL_BACK );
	}

    qglPushMatrix ();
	e->angles[PITCH] = -e->angles[PITCH];	// sigh.
	R_RotateForEntity (e);
	e->angles[PITCH] = -e->angles[PITCH];	// sigh.

	// select skin
	if (currententity->skin)
		skin = currententity->skin;	// custom player skin
	else
	{
		if (currententity->skinnum >= MAX_MD2SKINS)
			skin = currentmodel->skins[0];
		else
		{
			skin = currentmodel->skins[currententity->skinnum];
			if (!skin)
				skin = currentmodel->skins[0];
		}
	}
	if (!skin)
		skin = r_notexture;	// fallback...
	GL_Bind(skin->texnum);

	// draw it

	qglShadeModel (GL_SMOOTH);

	GL_TexEnv( GL_MODULATE );
	if ( currententity->flags & RF_TRANSLUCENT )
	{
		qglEnable (GL_BLEND);
	}


	if ( (currententity->frame >= paliashdr->num_frames) 
		|| (currententity->frame < 0) )
	{
		ri.Con_Printf (PRINT_ALL, "R_DrawAliasModel %s: no such frame %d\n",
			currentmodel->name, currententity->frame);
		currententity->frame = 0;
		currententity->oldframe = 0;
	}

	if ( (currententity->oldframe >= paliashdr->num_frames)
		|| (currententity->oldframe < 0))
	{
		ri.Con_Printf (PRINT_ALL, "R_DrawAliasModel %s: no such oldframe %d\n",
			currentmodel->name, currententity->oldframe);
		currententity->frame = 0;
		currententity->oldframe = 0;
	}

	if ( !r_lerpmodels->value )
		currententity->backlerp = 0;
	GL_DrawAliasFrameLerp (paliashdr, currententity->backlerp);

	GL_TexEnv( GL_REPLACE );
	qglShadeModel (GL_FLAT);

	qglPopMatrix ();

#if 0
	qglDisable( GL_CULL_FACE );
	qglPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
	qglDisable( GL_TEXTURE_2D );
	qglBegin( GL_TRIANGLE_STRIP );
	for ( i = 0; i < 8; i++ )
	{
		qglVertex3fv( bbox[i] );
	}
	qglEnd();
	qglEnable( GL_TEXTURE_2D );
	qglPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
	qglEnable( GL_CULL_FACE );
#endif

	if ( ( currententity->flags & RF_WEAPONMODEL ) && ( r_lefthand->value == 1.0F ) )
	{
		qglMatrixMode( GL_PROJECTION );
		qglPopMatrix();
		qglMatrixMode( GL_MODELVIEW );
		qglCullFace( GL_FRONT );
	}

	if ( currententity->flags & RF_TRANSLUCENT )
	{
		qglDisable (GL_BLEND);
	}

	if (currententity->flags & RF_DEPTHHACK)
		qglDepthRange (gldepthmin, gldepthmax);

#if 1
	if (gl_shadows->value && !(currententity->flags & (RF_TRANSLUCENT | RF_WEAPONMODEL)))
	{
		qglPushMatrix ();
		R_RotateForEntity (e);
		qglDisable (GL_TEXTURE_2D);
		qglEnable (GL_BLEND);
		qglColor4f (0,0,0,0.5);
		GL_DrawAliasShadow (paliashdr, currententity->frame );
		qglEnable (GL_TEXTURE_2D);
		qglDisable (GL_BLEND);
		qglPopMatrix ();
	}
#endif
	qglColor4f (1,1,1,1);
}
Пример #27
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 );

	#ifdef HAVE_GLES
	qglVertexPointer (3, GL_FLOAT, 16, tess.xyz);
	GLboolean text = qglIsEnabled(GL_TEXTURE_COORD_ARRAY);
	GLboolean glcol = qglIsEnabled(GL_COLOR_ARRAY);
	if (text)
		qglDisableClientState( GL_TEXTURE_COORD_ARRAY );
	if (glcol)
		qglDisableClientState( GL_COLOR_ARRAY );
	#endif
	// 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 );

		#ifdef HAVE_GLES
		qglDrawElements(GL_TRIANGLES, idx, GL_UNSIGNED_SHORT, indexes);
		#else
		R_RenderShadowEdges();
		#endif
	} else {
		qglCullFace( GL_BACK );
		qglStencilOp( GL_KEEP, GL_KEEP, GL_INCR );

		R_RenderShadowEdges();

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

		#ifdef HAVE_GLES
		qglDrawElements(GL_TRIANGLES, idx, GL_UNSIGNED_SHORT, indexes);
		#else
		R_RenderShadowEdges();
		#endif
	}


	#ifdef HAVE_GLES
	if (text)
		qglEnableClientState( GL_TEXTURE_COORD_ARRAY );
	if (glcol)
		qglEnableClientState( GL_COLOR_ARRAY );
	#endif
	// reenable writing to the color buffer
	qglColorMask(rgba[0], rgba[1], rgba[2], rgba[3]);
}
Пример #28
0
//R_DRAWCEL
static void R_DrawCel( int numIndexes, const glIndex_t *indexes ) {
	int		primitives;
	
	if(
		//. ignore the 2d projection. do i smell the HUD?
		(backEnd.projection2D == qtrue) ||
		//. ignore general entitites that are sprites. SEE NOTE #3.
		(backEnd.currentEntity->e.reType == RT_SPRITE) ||
		//. ignore these liquids. why? ever see liquid with tris on the surface? exactly. SEE NOTE #4.
		(tess.shader->contentFlags & (CONTENTS_WATER | CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_FOG)) ||
		//. ignore things that are two sided, meaning mostly things that have transparency. SEE NOTE #1.		
		(tess.shader->cullType == CT_TWO_SIDED)
		
		) {
		return;
	}

	primitives = r_primitives->integer;

	// default is to use triangles if compiled vertex arrays are present
	if ( primitives == 0 ) {
		if ( qglLockArraysEXT ) {
			primitives = 2;
		} else {
			primitives = 1;
		}
	}

	//. correction for mirrors. SEE NOTE #2.
	if(backEnd.viewParms.isMirror == qtrue) { qglCullFace (GL_FRONT); }
	else { qglCullFace (GL_BACK); }	

	qglEnable (GL_BLEND);
	qglBlendFunc (GL_SRC_ALPHA ,GL_ONE_MINUS_SRC_ALPHA);
	qglColor3f (0.0f,0.0f,0.0f);
	qglLineWidth( (float) r_celoutline->integer );	

	if(primitives == 2) {
		qglDrawElements( GL_TRIANGLES, numIndexes, GL_INDEX_TYPE, indexes );
	} else if(primitives == 1) {
		R_DrawStripElements( numIndexes,  indexes, qglArrayElement );
	} else if(primitives == 3) {
		R_DrawStripElements( numIndexes,  indexes, R_ArrayElementDiscrete );
	}

	//. correction for mirrors. SEE NOTE #2.
	if(backEnd.viewParms.isMirror == qtrue) { qglCullFace (GL_BACK); }
	else { qglCullFace (GL_FRONT); }
	
	qglDisable (GL_BLEND);
	
	return;

/* Notes

1. this is going to be a pain in the arse. it fixes things like light `beams` from being cel'd but it
also will ignore any other shader set with no culling. this usually is everything that is translucent.
but this is a good hack to clean up the screen untill something more selective comes along. or who knows
group desision might actually be that this is liked. if so i take back calling it a `hack`, lol.
	= bob.

2. mirrors display correctly because the normals of the displayed are inverted of normal space. so to
continue to have them display correctly, we must invert them inversely from a normal inversion.
	= bob.
	
3. this turns off a lot of space hogging sprite cel outlines. picture if you will five people in a small
room all shooting rockets. each smoke puff gets a big black square around it, each explosion gets a big
black square around it, and now nobody can see eachother because everyones screen is solid black.
	= bob.

4. ignoring liquids means you will not get black tris lines all over the top of your liquid. i put this in
after seeing the lava on q3dm7 and water on q3ctf2 that had black lines all over the top, making the
liquids look solid instead of... liquid.
	= bob.

*/
}
Пример #29
0
/*
 ==================
 GL_SetDefaultState
 ==================
*/
void GL_SetDefaultState (){

	int		i;

	QGL_LogPrintf("---------- GL_SetDefaultState ----------\n");

	// Reset the state manager
	glState.projectionMatrixIdentity = true;
	glState.modelviewMatrixIdentity = true;

	for (i = 0; i < MAX_TEXTURE_UNITS; i++)
		glState.textureMatrixIdentity[i] = true;

	for (i = 0; i < MAX_TEXTURE_UNITS; i++)
		glState.texture[i] = NULL;

	glState.program = NULL;
	glState.indexBuffer = NULL;
	glState.vertexBuffer = NULL;

	glState.viewportX = 0;
	glState.viewportY = 0;
	glState.viewportWidth = glConfig.videoWidth;
	glState.viewportHeight = glConfig.videoHeight;

	glState.scissorX = 0;
	glState.scissorY = 0;
	glState.scissorWidth = glConfig.videoWidth;
	glState.scissorHeight = glConfig.videoHeight;

	glState.depthBoundsMin = 0.0f;
	glState.depthBoundsMax = 1.0f;

	glState.texUnit = 0;

	for (i = 0; i < MAX_TEXTURE_UNITS; i++){
		glState.texTarget[i] = 0;

		glState.texEnv[i] = GL_MODULATE;

		glState.texGen[i][0] = GL_OBJECT_LINEAR;
		glState.texGen[i][1] = GL_OBJECT_LINEAR;
		glState.texGen[i][2] = GL_OBJECT_LINEAR;
		glState.texGen[i][3] = GL_OBJECT_LINEAR;
	}

	glState.cullFace = false;
	glState.polygonOffsetFill = false;
	glState.polygonOffsetLine = false;
	glState.blend = false;
	glState.alphaTest = false;
	glState.depthTest = false;
	glState.stencilTest = false;

	for (i = 0; i < MAX_TEXTURE_UNITS; i++){
		glState.textureGen[i][0] = false;
		glState.textureGen[i][1] = false;
		glState.textureGen[i][2] = false;
		glState.textureGen[i][3] = false;
	}

	glState.cullMode = GL_FRONT;
	glState.polygonMode = GL_FILL;
	glState.polygonOffsetFactor = 0.0f;
	glState.polygonOffsetUnits = 0.0f;
	glState.blendSrc = GL_ONE;
	glState.blendDst = GL_ZERO;
	glState.blendMode = GL_FUNC_ADD;
	glState.alphaFunc = GL_GREATER;
	glState.alphaFuncRef = 0.0f;
	glState.depthFunc = GL_LEQUAL;
	glState.stencilFunc[0] = GL_ALWAYS;
	glState.stencilFunc[1] = GL_ALWAYS;
	glState.stencilFuncRef[0] = 0;
	glState.stencilFuncRef[1] = 0;
	glState.stencilFuncMask[0] = 255;
	glState.stencilFuncMask[1] = 255;
	glState.stencilOpFail[0] = GL_KEEP;
	glState.stencilOpFail[1] = GL_KEEP;
	glState.stencilOpZFail[0] = GL_KEEP;
	glState.stencilOpZFail[1] = GL_KEEP;
	glState.stencilOpZPass[0] = GL_KEEP;
	glState.stencilOpZPass[1] = GL_KEEP;
	glState.depthMin = 0.0f;
	glState.depthMax = 1.0f;

	glState.colorMask[0] = GL_TRUE;
	glState.colorMask[1] = GL_TRUE;
	glState.colorMask[2] = GL_TRUE;
	glState.colorMask[3] = GL_TRUE;
	glState.depthMask = GL_TRUE;
	glState.stencilMask[0] = 255;
	glState.stencilMask[1] = 255;

	// Set default state
	qglMatrixMode(GL_PROJECTION);
	qglLoadIdentity();

	qglMatrixMode(GL_MODELVIEW);
	qglLoadIdentity();

	for (i = MAX_TEXTURE_UNITS - 1; i >= 0; i--){
		if (i >= glConfig.maxTextureImageUnits)
			continue;

		if (i >= glConfig.maxTextureUnits){
			qglActiveTexture(GL_TEXTURE0 + i);

			qglBindTexture(GL_TEXTURE_2D, 0);
			qglBindTexture(GL_TEXTURE_3D, 0);
			qglBindTexture(GL_TEXTURE_CUBE_MAP, 0);
			qglBindTexture(GL_TEXTURE_2D_ARRAY, 0);

			continue;
		}

		qglActiveTexture(GL_TEXTURE0 + i);

		qglMatrixMode(GL_TEXTURE);
		qglLoadIdentity();

		qglDisable(GL_TEXTURE_2D);
		qglDisable(GL_TEXTURE_3D);
		qglDisable(GL_TEXTURE_CUBE_MAP);
		qglDisable(GL_TEXTURE_2D_ARRAY);

		qglBindTexture(GL_TEXTURE_2D, 0);
		qglBindTexture(GL_TEXTURE_3D, 0);
		qglBindTexture(GL_TEXTURE_CUBE_MAP, 0);
		qglBindTexture(GL_TEXTURE_2D_ARRAY, 0);

		qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);

		qglDisable(GL_TEXTURE_GEN_S);
		qglDisable(GL_TEXTURE_GEN_T);
		qglDisable(GL_TEXTURE_GEN_R);
		qglDisable(GL_TEXTURE_GEN_Q);

		qglTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
		qglTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
		qglTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
		qglTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
	}

	qglDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS);

	qglUseProgram(0);

	qglBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
	qglBindBuffer(GL_ARRAY_BUFFER, 0);

	qglViewport(0, 0, glConfig.videoWidth, glConfig.videoHeight);

	qglEnable(GL_SCISSOR_TEST);
	qglScissor(0, 0, glConfig.videoWidth, glConfig.videoHeight);

	qglEnable(GL_DEPTH_BOUNDS_TEST_EXT);
	qglDepthBoundsEXT(0.0f, 1.0f);

	qglFrontFace(GL_CCW);

	qglShadeModel(GL_SMOOTH);

	qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

	qglDisable(GL_CULL_FACE);
	qglCullFace(GL_FRONT);

	qglDisable(GL_POLYGON_OFFSET_FILL);
	qglDisable(GL_POLYGON_OFFSET_LINE);
	qglPolygonOffset(0.0f, 0.0f);

	qglDisable(GL_BLEND);
	qglBlendFunc(GL_ONE, GL_ZERO);
	qglBlendEquation(GL_FUNC_ADD);

	qglDisable(GL_ALPHA_TEST);
	qglAlphaFunc(GL_GREATER, 0.0f);

	qglDisable(GL_DEPTH_TEST);
	qglDepthFunc(GL_LEQUAL);

	qglDisable(GL_STENCIL_TEST);
	qglStencilFunc(GL_ALWAYS, 128, 255);
	qglStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

	qglDepthRange(0.0f, 1.0f);

	qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
	qglDepthMask(GL_TRUE);
	qglStencilMask(255);

	qglDisable(GL_DEPTH_CLAMP);

	qglDisable(GL_CLIP_PLANE0);

	if (glConfig.multiSamples > 1){
		qglDisable(GL_MULTISAMPLE);

		qglDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
	}

	qglClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	qglClearDepth(1.0f);
	qglClearStencil(128);

	qglEnableClientState(GL_VERTEX_ARRAY);

	qglDisableVertexAttribArray(GL_ATTRIB_NORMAL);
	qglDisableVertexAttribArray(GL_ATTRIB_TANGENT1);
	qglDisableVertexAttribArray(GL_ATTRIB_TANGENT2);
	qglDisableVertexAttribArray(GL_ATTRIB_TEXCOORD);
	qglDisableVertexAttribArray(GL_ATTRIB_COLOR);

	QGL_LogPrintf("--------------------\n");
}
Пример #30
0
void
R_DrawAliasModel ( entity_t *e )
{
	int i;
	dmdl_t      *paliashdr;
	float an;
	vec3_t bbox [ 8 ];
	image_t     *skin;

	if ( !( e->flags & RF_WEAPONMODEL ) )
	{
		if ( R_CullAliasModel( bbox, e ) )
		{
			return;
		}
	}

	if ( e->flags & RF_WEAPONMODEL )
	{
		if ( gl_lefthand->value == 2 )
		{
			return;
		}
	}

	paliashdr = (dmdl_t *) currentmodel->extradata;

	/* get lighting information */
	if ( currententity->flags & ( RF_SHELL_HALF_DAM | RF_SHELL_GREEN | RF_SHELL_RED | RF_SHELL_BLUE | RF_SHELL_DOUBLE ) )
	{
		VectorClear( shadelight );

		if ( currententity->flags & RF_SHELL_HALF_DAM )
		{
			shadelight [ 0 ] = 0.56;
			shadelight [ 1 ] = 0.59;
			shadelight [ 2 ] = 0.45;
		}

		if ( currententity->flags & RF_SHELL_DOUBLE )
		{
			shadelight [ 0 ] = 0.9;
			shadelight [ 1 ] = 0.7;
		}

		if ( currententity->flags & RF_SHELL_RED )
		{
			shadelight [ 0 ] = 1.0;
		}

		if ( currententity->flags & RF_SHELL_GREEN )
		{
			shadelight [ 1 ] = 1.0;
		}

		if ( currententity->flags & RF_SHELL_BLUE )
		{
			shadelight [ 2 ] = 1.0;
		}
	}
	else if ( currententity->flags & RF_FULLBRIGHT )
	{
		for ( i = 0; i < 3; i++ )
		{
			shadelight [ i ] = 1.0;
		}
	}
	else
	{
		R_LightPoint( currententity->origin, shadelight );

		/* player lighting hack for communication back to server */
		if ( currententity->flags & RF_WEAPONMODEL )
		{
			/* pick the greatest component, which should be the same
			   as the mono value returned by software */
			if ( shadelight [ 0 ] > shadelight [ 1 ] )
			{
				if ( shadelight [ 0 ] > shadelight [ 2 ] )
				{
					gl_lightlevel->value = 150 * shadelight [ 0 ];
				}
				else
				{
					gl_lightlevel->value = 150 * shadelight [ 2 ];
				}
			}
			else
			{
				if ( shadelight [ 1 ] > shadelight [ 2 ] )
				{
					gl_lightlevel->value = 150 * shadelight [ 1 ];
				}
				else
				{
					gl_lightlevel->value = 150 * shadelight [ 2 ];
				}
			}
		}
	}

	if ( currententity->flags & RF_MINLIGHT )
	{
		for ( i = 0; i < 3; i++ )
		{
			if ( shadelight [ i ] > 0.1 )
			{
				break;
			}
		}

		if ( i == 3 )
		{
			shadelight [ 0 ] = 0.1;
			shadelight [ 1 ] = 0.1;
			shadelight [ 2 ] = 0.1;
		}
	}

	if ( currententity->flags & RF_GLOW )
	{
		/* bonus items will pulse with time */
		float scale;
		float min;

		scale = 0.1 * sin( r_newrefdef.time * 7 );

		for ( i = 0; i < 3; i++ )
		{
			min = shadelight [ i ] * 0.8;
			shadelight [ i ] += scale;

			if ( shadelight [ i ] < min )
			{
				shadelight [ i ] = min;
			}
		}
	}

	/* ir goggles color override */
	if ( r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE )
	{
		shadelight [ 0 ] = 1.0;
		shadelight [ 1 ] = 0.0;
		shadelight [ 2 ] = 0.0;
	}

	shadedots =
		r_avertexnormal_dots [ ( (int) ( currententity->angles [ 1 ] * ( SHADEDOT_QUANT / 360.0 ) ) ) & ( SHADEDOT_QUANT - 1 ) ];

	an = currententity->angles [ 1 ] / 180 * M_PI;
	shadevector [ 0 ] = cos( -an );
	shadevector [ 1 ] = sin( -an );
	shadevector [ 2 ] = 1;
	VectorNormalize( shadevector );

	/* locate the proper data */
	c_alias_polys += paliashdr->num_tris;

	/* draw all the triangles */
	if ( currententity->flags & RF_DEPTHHACK ) /* hack the depth range to prevent view model from poking into walls */
	{
		qglDepthRange( gldepthmin, gldepthmin + 0.3 * ( gldepthmax - gldepthmin ) );
	}

	if ( ( currententity->flags & RF_WEAPONMODEL ) && ( gl_lefthand->value == 1.0F ) )
	{
		extern void R_MYgluPerspective ( GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar );

		qglMatrixMode( GL_PROJECTION );
		qglPushMatrix();
		qglLoadIdentity();
		qglScalef( -1, 1, 1 );
		R_MYgluPerspective( r_newrefdef.fov_y, (float) r_newrefdef.width / r_newrefdef.height,  4,  4096 );
		qglMatrixMode( GL_MODELVIEW );

		qglCullFace( GL_BACK );
	}

	qglPushMatrix();
	e->angles [ PITCH ] = -e->angles [ PITCH ];
	R_RotateForEntity( e );
	e->angles [ PITCH ] = -e->angles [ PITCH ];

	/* select skin */
	if ( currententity->skin )
	{
		skin = currententity->skin; /* custom player skin */
	}
	else
	{
		if ( currententity->skinnum >= MAX_MD2SKINS )
		{
			skin = currentmodel->skins [ 0 ];
		}
		else
		{
			skin = currentmodel->skins [ currententity->skinnum ];

			if ( !skin )
			{
				skin = currentmodel->skins [ 0 ];
			}
		}
	}

	if ( !skin )
	{
		skin = r_notexture; /* fallback... */
	}

	R_Bind( skin->texnum );

	/* draw it */
	qglShadeModel( GL_SMOOTH );

	R_TexEnv( GL_MODULATE );

	if ( currententity->flags & RF_TRANSLUCENT )
	{
		qglEnable( GL_BLEND );
	}

	if ( ( currententity->frame >= paliashdr->num_frames ) ||
		 ( currententity->frame < 0 ) )
	{
		ri.Con_Printf( PRINT_ALL, "R_DrawAliasModel %s: no such frame %d\n",
				currentmodel->name, currententity->frame );
		currententity->frame = 0;
		currententity->oldframe = 0;
	}

	if ( ( currententity->oldframe >= paliashdr->num_frames ) ||
		 ( currententity->oldframe < 0 ) )
	{
		ri.Con_Printf( PRINT_ALL, "R_DrawAliasModel %s: no such oldframe %d\n",
				currentmodel->name, currententity->oldframe );
		currententity->frame = 0;
		currententity->oldframe = 0;
	}

	if ( !gl_lerpmodels->value )
	{
		currententity->backlerp = 0;
	}

	R_DrawAliasFrameLerp( paliashdr, currententity->backlerp );

	R_TexEnv( GL_REPLACE );
	qglShadeModel( GL_FLAT );

	qglPopMatrix();

	if ( ( currententity->flags & RF_WEAPONMODEL ) && ( gl_lefthand->value == 1.0F ) )
	{
		qglMatrixMode( GL_PROJECTION );
		qglPopMatrix();
		qglMatrixMode( GL_MODELVIEW );
		qglCullFace( GL_FRONT );
	}

	if ( currententity->flags & RF_TRANSLUCENT )
	{
		qglDisable( GL_BLEND );
	}

	if ( currententity->flags & RF_DEPTHHACK )
	{
		qglDepthRange( gldepthmin, gldepthmax );
	}

	if ( gl_shadows->value &&
		 !( currententity->flags & ( RF_TRANSLUCENT | RF_WEAPONMODEL | RF_NOSHADOW ) ) )
	{
		qglPushMatrix();

		/* don't rotate shadows on ungodly axes */
		qglTranslatef( e->origin [ 0 ], e->origin [ 1 ], e->origin [ 2 ] );
		qglRotatef( e->angles [ 1 ], 0, 0, 1 );

		qglDisable( GL_TEXTURE_2D );
		qglEnable( GL_BLEND );
		qglColor4f( 0, 0, 0, 0.5f );
		R_DrawAliasShadow( paliashdr, currententity->frame );
		qglEnable( GL_TEXTURE_2D );
		qglDisable( GL_BLEND );
		qglPopMatrix();
	}

	qglColor4f( 1, 1, 1, 1 );
}