コード例 #1
0
ファイル: r_draw.c プロジェクト: postfix/quake2vr
/*
 =============
 R_DrawStretchImage
 =============
 */
void R_DrawStretchImage (int32_t x, int32_t y, int32_t w, int32_t h, image_t *gl, float alpha)
{
    const vec4_t color[4] = {
        {1.0, 1.0, 1.0, alpha},
        {1.0, 1.0, 1.0, alpha},
        {1.0, 1.0, 1.0, alpha},
        {1.0, 1.0, 1.0, alpha}
    };

    const vec3_t verts[4] = {
        {x, y, 0},
        {x+w, y, 0},
        {x+w, y+h, 0},
        {x, y+h, 0}
    };


    if (scrap_dirty)
        Scrap_Upload ();

    // Psychospaz's transparent console support
    if (gl->has_alpha || alpha < 1.0)
    {
        GL_Disable (GL_ALPHA_TEST);
        GL_TexEnv (GL_MODULATE);
        GL_Enable (GL_BLEND);
        GL_DepthMask (false);
    }

    GL_Bind (gl->texnum);

    rb_vertex = rb_index = 0;
    memcpy(&indexArray[rb_index], indices, sizeof(indices));

    rb_index = 6;

    Vector2Set(texCoordArray[0][0], gl->sl, gl->tl);
    Vector2Set(texCoordArray[0][1], gl->sh, gl->tl);
    Vector2Set(texCoordArray[0][2], gl->sh, gl->th);
    Vector2Set(texCoordArray[0][3], gl->sl, gl->th);

    memcpy(vertexArray, verts, sizeof(vec3_t) * 4);
    memcpy(colorArray[rb_vertex], color, sizeof(vec4_t) * 4);

    rb_vertex = 4;

    RB_RenderMeshGeneric (false);

    // Psychospaz's transparent console support
    if (gl->has_alpha || alpha < 1.0)
    {
        GL_DepthMask (true);
        GL_TexEnv (GL_REPLACE);
        GL_Disable (GL_BLEND);
        GL_Enable (GL_ALPHA_TEST);
    }
}
コード例 #2
0
ファイル: r_draw.c プロジェクト: Nephatrine/nephq2
/*
 =============
 R_DrawStretchImage
 =============
 */
void R_DrawStretchImage (int32_t x, int32_t y, int32_t w, int32_t h, image_t *gl, float alpha)
{
    int32_t			i;
    vec2_t		texCoord[4], verts[4];
    
    if (scrap_dirty)
        Scrap_Upload ();
    
    // Psychospaz's transparent console support
    if (gl->has_alpha || alpha < 1.0)
    {
        GL_Disable (GL_ALPHA_TEST);
        GL_TexEnv (GL_MODULATE);
        GL_Enable (GL_BLEND);
        GL_DepthMask (false);
    }
    
    GL_Bind (gl->texnum);
    
    Vector2Set(texCoord[0], gl->sl, gl->tl);
    Vector2Set(texCoord[1], gl->sh, gl->tl);
    Vector2Set(texCoord[2], gl->sh, gl->th);
    Vector2Set(texCoord[3], gl->sl, gl->th);
    
    Vector2Set(verts[0], x, y);
    Vector2Set(verts[1], x+w, y);
    Vector2Set(verts[2], x+w, y+h);
    Vector2Set(verts[3], x, y+h);
    
    rb_vertex = rb_index = 0;
    indexArray[rb_index++] = rb_vertex+0;
    indexArray[rb_index++] = rb_vertex+1;
    indexArray[rb_index++] = rb_vertex+2;
    indexArray[rb_index++] = rb_vertex+0;
    indexArray[rb_index++] = rb_vertex+2;
    indexArray[rb_index++] = rb_vertex+3;
    for (i=0; i<4; i++) {
        VA_SetElem2(texCoordArray[0][rb_vertex], texCoord[i][0], texCoord[i][1]);
        VA_SetElem3(vertexArray[rb_vertex], verts[i][0], verts[i][1], 0);
        VA_SetElem4(colorArray[rb_vertex], 1.0, 1.0, 1.0, alpha);
        rb_vertex++;
    }
    RB_RenderMeshGeneric (false);
    
    // Psychospaz's transparent console support
    if (gl->has_alpha || alpha < 1.0)
    {
        GL_DepthMask (true);
        GL_TexEnv (GL_REPLACE);
        GL_Disable (GL_BLEND);
        GL_Enable (GL_ALPHA_TEST);
    }
}
コード例 #3
0
ファイル: r_draw.c プロジェクト: postfix/quake2vr
/*
======================
R_DrawFill

Fills a box of pixels with a
24-bit color w/ alpha
===========================
*/
void R_DrawFill (int32_t x, int32_t y, int32_t w, int32_t h, int32_t red, int32_t green, int32_t blue, int32_t alpha)
{
    const vec_t r = min(red, 255)*DIV255;
    const vec_t g = min(green, 255)*DIV255;
    const vec_t b = min(blue, 255)*DIV255;
    const vec_t a = max(min(alpha, 255), 1)*DIV255;

    const vec4_t color[4] = {
        {r, g, b, a},
        {r, g, b, a},
        {r, g, b, a},
        {r, g, b, a}
    };


    const vec3_t verts[4] = {
        {x, y, 0},
        {x+w, y, 0},
        {x+w, y+h, 0},
        {x, y+h, 0}
    };

//	GL_DisableTexture (0);
    GL_Disable (GL_ALPHA_TEST);
    GL_TexEnv (GL_MODULATE);
    GL_Enable (GL_BLEND);
    GL_DepthMask   (false);

    GL_Bind (glMedia.whitetexture->texnum);

    rb_vertex = rb_index = 0;

    memcpy(&indexArray[rb_index], indices, sizeof(indices));
    rb_index = 6;

    memcpy(vertexArray, verts, sizeof(vec3_t) * 4);
    memcpy(colorArray, color, sizeof(vec4_t) * 4);

    rb_vertex = 4;

    RB_RenderMeshGeneric (false);

    GL_DepthMask (true);
    GL_Disable (GL_BLEND);
    GL_TexEnv (GL_REPLACE);
    GL_Enable (GL_ALPHA_TEST);
//	GL_EnableTexture (0);
}
コード例 #4
0
ファイル: r_alias_misc.c プロジェクト: postfix/quake2vr
/*
=================
R_SetBlendModeOn
=================
*/
void R_SetBlendModeOn (image_t *skin)
{
	GL_TexEnv( GL_MODULATE );

	if (skin)
		GL_Bind(skin->texnum);

	GL_ShadeModel (GL_SMOOTH);

	if (currententity->flags & RF_TRANSLUCENT)
	{
		GL_DepthMask (false);

		if (currententity->flags & RF_TRANS_ADDITIVE)
		{ 
			GL_BlendFunc   (GL_SRC_ALPHA, GL_ONE);	
			glColor4ub(255, 255, 255, 255);
			GL_ShadeModel (GL_FLAT);
		}
		else
			GL_BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		
		GL_Enable (GL_BLEND);
	}
}
コード例 #5
0
ファイル: gl_pass.cpp プロジェクト: newerthcom/savagerebirth
void Pass::finalize() {
	
	GL_SwitchTexUnit(GL_TEXTURE0_ARB);
	//GL_TextureEnvMode(GL_REPLACE);
	
	if(viewer)
		GL_PopCamera();
	
	//GL_Disable(GL_SCISSOR_TEST);
	
	GL_DepthMask(GL_FALSE);
	GL_Disable(GL_DEPTH_TEST);
	GL_Disable(GL_FOG);
	GL_Disable(GL_ALPHA_TEST);
	
	if(gfx_postProcessing.integer) {
		target->unmakeTarget();
	} else {
		glScreen->unmakeTarget();
	}
	
	GL_Disable(GL_LIGHTING);
	for(lightCount-=1;lightCount>=0;lightCount--)
		GL_Disable(GL_LIGHT0+lightCount);
	
	Cvar_SetVarValue(&gfx_GLSLPass, 0);
	
	glPopAttrib();
	
	//if(gfx_postProcessing.integer && gfx_GLSLQuality.integer>1)
		//glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboTargetBufferId);
#ifdef DEBUG
	GLSL_catchLastError("Pass::finalize(): ");
#endif
}
コード例 #6
0
ファイル: r_alias_misc.c プロジェクト: postfix/quake2vr
/*
=================
R_SetBlendModeOff
=================
*/
void R_SetBlendModeOff (void)
{
	if ( currententity->flags & RF_TRANSLUCENT )
	{
		GL_DepthMask (true);
		GL_Disable(GL_BLEND);
		GL_BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	}
}
コード例 #7
0
ファイル: r_draw.c プロジェクト: Nephatrine/nephq2
/*
======================
R_DrawFill

Fills a box of pixels with a
24-bit color w/ alpha
===========================
*/
void R_DrawFill (int32_t x, int32_t y, int32_t w, int32_t h, int32_t red, int32_t green, int32_t blue, int32_t alpha)
{
	int32_t		i;
	vec2_t	verts[4];

	red = min(red, 255);
	green = min(green, 255);
	blue = min(blue, 255);
	alpha = max(min(alpha, 255), 1);

//	GL_DisableTexture (0);
	GL_Disable (GL_ALPHA_TEST);
	GL_TexEnv (GL_MODULATE);
	GL_Enable (GL_BLEND);
	GL_DepthMask   (false);

	GL_Bind (glMedia.whitetexture->texnum);

	Vector2Set(verts[0], x, y);
	Vector2Set(verts[1], x+w, y);
	Vector2Set(verts[2], x+w, y+h);
	Vector2Set(verts[3], x, y+h);

	rb_vertex = rb_index = 0;
	indexArray[rb_index++] = rb_vertex+0;
	indexArray[rb_index++] = rb_vertex+1;
	indexArray[rb_index++] = rb_vertex+2;
	indexArray[rb_index++] = rb_vertex+0;
	indexArray[rb_index++] = rb_vertex+2;
	indexArray[rb_index++] = rb_vertex+3;
	for (i=0; i<4; i++) {
		VA_SetElem3(vertexArray[rb_vertex], verts[i][0], verts[i][1], 0);
		VA_SetElem4(colorArray[rb_vertex], red*DIV255, green*DIV255, blue*DIV255, alpha*DIV255);
		rb_vertex++;
	}
	RB_RenderMeshGeneric (false);

	GL_DepthMask (true);
	GL_Disable (GL_BLEND);
	GL_TexEnv (GL_REPLACE);
	GL_Enable (GL_ALPHA_TEST);
//	GL_EnableTexture (0);
}
コード例 #8
0
ファイル: r_draw.c プロジェクト: Nephatrine/nephq2
/*
================
R_FlushChars
================
*/
void R_FlushChars (void)
{
	if (rb_vertex == 0 || rb_index == 0) // nothing to flush
		return;

	GL_Disable (GL_ALPHA_TEST);
	GL_TexEnv (GL_MODULATE);
	GL_Enable (GL_BLEND);
	GL_DepthMask (false);
	GL_Bind(draw_chars->texnum);

	RB_RenderMeshGeneric (false);
	char_count = 0;

	GL_DepthMask (true);
	GL_Disable (GL_BLEND);
	GL_TexEnv (GL_REPLACE);
	GL_Enable (GL_ALPHA_TEST);
}
コード例 #9
0
ファイル: r_explosion.c プロジェクト: Hanzo-nex/DarkPlacesRM
static void R_DrawExplosion_TransparentCallback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
{
	int surfacelistindex = 0;
	const int numtriangles = EXPLOSIONTRIS, numverts = EXPLOSIONVERTS;
	GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
	GL_DepthMask(false);
	GL_DepthRange(0, 1);
	GL_PolygonOffset(r_refdef.polygonfactor, r_refdef.polygonoffset);
	GL_DepthTest(true);
	GL_CullFace(r_refdef.view.cullface_back);
	R_EntityMatrix(&identitymatrix);

//	R_Mesh_ResetTextureState();
	R_SetupShader_Generic(explosiontexture, NULL, GL_MODULATE, 1, false, false, false);
	for (surfacelistindex = 0;surfacelistindex < numsurfaces;surfacelistindex++)
	{
		const explosion_t *e = explosion + surfacelist[surfacelistindex];
		// FIXME: this can't properly handle r_refdef.view.colorscale > 1
		GL_Color(e->alpha * r_refdef.view.colorscale, e->alpha * r_refdef.view.colorscale, e->alpha * r_refdef.view.colorscale, 1);
		R_Mesh_PrepareVertices_Generic_Arrays(numverts, e->vert[0], NULL, explosiontexcoord2f[0]);
		R_Mesh_Draw(0, numverts, 0, numtriangles, NULL, NULL, 0, explosiontris[0], NULL, 0);
	}
}
コード例 #10
0
ファイル: r_sprite.c プロジェクト: mczero80/KMQuake2
/*
=================
R_DrawSpriteModel
=================
*/
void R_DrawSpriteModel (entity_t *e)
{
    float			alpha = 1.0f;
    vec2_t			texCoord[4];
    vec3_t			point[4];
    dsprite_t		*psprite;
    dsprframe_t		*frame;
    float			*up, *right;
    int				i;

    // don't even bother culling, because it's just a single
    // polygon without a surface cache

    psprite = (dsprite_t *)currentmodel->extradata;

    e->frame %= psprite->numframes;

    frame = &psprite->frames[e->frame];

    if (!frame) return;

    c_alias_polys += 2;

    // normal sprite
    up = vup;
    right = vright;

    if (e->flags & RF_TRANSLUCENT)
        alpha = e->alpha;

    R_SetVertexRGBScale (true);

    // Psychospaz's additive transparency
    if ((currententity->flags & RF_TRANS_ADDITIVE) && (alpha != 1.0f))
    {
        GL_Enable (GL_BLEND);
        GL_TexEnv (GL_MODULATE);
        GL_Disable (GL_ALPHA_TEST);
        GL_DepthMask (false);
        GL_BlendFunc (GL_SRC_ALPHA, GL_ONE);
    }
    else
    {
        GL_TexEnv (GL_MODULATE);
        if (alpha == 1.0f) {
            GL_Enable (GL_ALPHA_TEST);
            GL_DepthMask (true);
        }
        else {
            GL_BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            GL_DepthMask (false);
            GL_Enable (GL_BLEND);
            GL_Disable (GL_ALPHA_TEST);
        }
    }
    GL_Bind(currentmodel->skins[0][e->frame]->texnum);

    Vector2Set(texCoord[0], 0, 1);
    Vector2Set(texCoord[1], 0, 0);
    Vector2Set(texCoord[2], 1, 0);
    Vector2Set(texCoord[3], 1, 1);

    VectorMA (e->origin, -frame->origin_y, up, point[0]);
    VectorMA (point[0], -frame->origin_x, right, point[0]);

    VectorMA (e->origin, frame->height - frame->origin_y, up, point[1]);
    VectorMA (point[1], -frame->origin_x, right, point[1]);

    VectorMA (e->origin, frame->height - frame->origin_y, up, point[2]);
    VectorMA (point[2], frame->width - frame->origin_x, right, point[2]);

    VectorMA (e->origin, -frame->origin_y, up, point[3]);
    VectorMA (point[3], frame->width - frame->origin_x, right, point[3]);

    rb_vertex = rb_index = 0;
    indexArray[rb_index++] = rb_vertex+0;
    indexArray[rb_index++] = rb_vertex+1;
    indexArray[rb_index++] = rb_vertex+2;
    indexArray[rb_index++] = rb_vertex+0;
    indexArray[rb_index++] = rb_vertex+2;
    indexArray[rb_index++] = rb_vertex+3;
    for (i=0; i<4; i++) {
        VA_SetElem2(texCoordArray[0][rb_vertex], texCoord[i][0], texCoord[i][1]);
        VA_SetElem3(vertexArray[rb_vertex], point[i][0], point[i][1], point[i][2]);
        VA_SetElem4(colorArray[rb_vertex], 1.0f, 1.0f, 1.0f, alpha);
        rb_vertex++;
    }
    RB_DrawArrays ();

    GL_BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    GL_TexEnv (GL_REPLACE);
    GL_DepthMask (true);
    GL_Disable (GL_ALPHA_TEST);
    GL_Disable (GL_BLEND);

    R_SetVertexRGBScale (false);

    RB_DrawMeshTris ();
    rb_vertex = rb_index = 0;
}
コード例 #11
0
ファイル: gl_pass.cpp プロジェクト: newerthcom/savagerebirth
void Pass::setup(GLRenderer *) {
	
	vec4_t ambient = { sunLight.ambient[0] * 0.8, sunLight.ambient[1] * 0.8, sunLight.ambient[2] * 0.95, 1 };
	
	GLSL_reset();
	
	shader = NULL;
	lightCount = 0;
	
	glPushAttrib(attrib_bits);
	
	//GL_Enable(GL_SCISSOR_TEST);
	GL_SwitchTexUnit(GL_TEXTURE0_ARB);
	
	//defaults for pass
	GL_Enable(GL_BLEND);
	GL_BlendFunc(GL_SRC_ALPHA, GL_ONE);
	GL_Enable(GL_CULL_FACE);
	GL_Enable(GL_ALPHA_TEST);
	//glAlphaFunc(GL_GREATER, 0.0);
	GL_ResetColor();
	
	glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	
	//enable the lights for this pass by default
	if(allowLighting()) {
		if(gfx_GLSLQuality.integer <= 1)
			M_MultVec3(ambient, 1.5, ambient);
		
		GL_Enable(GL_LIGHTING);
		glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
		glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, true);
		glShadeModel(GL_SMOOTH);
	}
	//GL_Enable(GL_NORMALIZE);
	
	//framebuffer
	if(gfx_postProcessing.integer) {
		if(!target)
			target = glScreen;
		target->makeTarget();
	} else {
		glScreen->makeTarget();
	}
	
	//depth
	GL_Enable(GL_DEPTH_TEST);
	GL_DepthMask(depthMask);
	GL_DepthFunc(depthFunc);
	
	if(preclearDepth) {
		glClearDepth(1.0);
		glClear(GL_DEPTH_BUFFER_BIT);
	}
	
	if(viewer) {
		vec4_t rect;
		//FIXME: probably should be a data member for configurable pass "windows"
		SET_VEC4(rect, 0, 0, viewer->width, viewer->height);
		
		Scene_SetFrustum(viewer, rect);
		Scene_BuildOccluderList(viewer);
		
		if(gfx_debugCamera.integer>0) {
			camera_t debugcam;
			vec3_t back;
			M_MultVec3(viewer->viewaxis[AXIS_FORWARD], -gfx_debugCamera.integer, back);
			memcpy(&debugcam, viewer, sizeof(camera_t));
			M_AddVec3(debugcam.origin, back, debugcam.origin);
			GL_PushCamera(&debugcam);
		} else {
			GL_PushCamera(viewer);
			//scene_cam = viewer;
		}
		
		//fog
		if (viewer->fog_far > 0 && gfx_fog.integer) 
		{
			vec4_t fog_color = { gfx_fogr.value, gfx_fogg.value, gfx_fogb.value, 0 };
			
			GL_Enable(GL_FOG);
			if(gfx_nicerFog.integer)
			{
				glFogf(GL_FOG_MODE, GL_EXP2);
				glFogf(GL_FOG_DENSITY, 1.5 / viewer->fog_far); // Notaus: old value was fixed at 0.00072 and not appropriate for very foggy maps
			}
			else
			{
				glFogf(GL_FOG_MODE, GL_LINEAR);
			}
			glHint(GL_FOG_HINT, GL_NICEST);
			if (viewer->fog_near > 0 && viewer->fog_far >= viewer->fog_near)
			{
				glFogf(GL_FOG_START, viewer->fog_near);
				glFogf(GL_FOG_END, viewer->fog_far);
				fog_near = viewer->fog_near;
				fog_far = viewer->fog_far;
			}
			else
			{
				glFogf(GL_FOG_START, gfx_fog_near.value);
				glFogf(GL_FOG_END, gfx_fog_far.value);
				fog_near = gfx_fog_near.value;
				fog_far = gfx_fog_far.value;
			}
			glFogfv(GL_FOG_COLOR, fog_color);
		}
		else if (gfx_fog.integer==0) {
			GL_Enable(GL_FOG);
			glFogf(GL_FOG_START, 90000);
			glFogf(GL_FOG_END, 100000);   //shaders make it better just to set this ridiculously far out
		} else {
			GL_Disable(GL_FOG);
		}
		
	} else {
		GL_Disable(GL_FOG);
	}
	
	if(gfx_GLSL.integer)
		Cvar_SetVarValue(&gfx_GLSLPass, 1);
	else
		GL_TexModulate(2.0);
#ifdef DEBUG
	GLSL_catchLastError("Pass::setup()");
#endif
}
コード例 #12
0
/*
 ==================
 GL_Setup3D

 TODO: time is messed up
 ==================
*/
void GL_Setup3D (int time){

	double	clipPlane[4];

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

	backEnd.projection2D = false;

	backEnd.time = time;
	backEnd.floatTime = MS2SEC(Sys_Milliseconds());

	backEnd.viewport.x = backEnd.viewParms.viewport.x;
	backEnd.viewport.y = backEnd.viewParms.viewport.y;
	backEnd.viewport.width = backEnd.viewParms.viewport.width;
	backEnd.viewport.height = backEnd.viewParms.viewport.height;

	backEnd.scissor.x = backEnd.viewParms.scissor.x;
	backEnd.scissor.y = backEnd.viewParms.scissor.y;
	backEnd.scissor.width = backEnd.viewParms.scissor.width;
	backEnd.scissor.height = backEnd.viewParms.scissor.height;

	backEnd.coordScale[0] = 1.0f / backEnd.viewport.width;
	backEnd.coordScale[1] = 1.0f / backEnd.viewport.height;

	backEnd.coordBias[0] = -backEnd.viewport.x * backEnd.coordScale[0];
	backEnd.coordBias[1] = -backEnd.viewport.y * backEnd.coordScale[1];

	backEnd.depthFilling = false;
	backEnd.debugRendering = false;

	backEnd.currentColorCaptured = SORT_BAD;
	backEnd.currentDepthCaptured = false;

	// Set up the viewport
	GL_Viewport(backEnd.viewport);

	// Set up the scissor
	GL_Scissor(backEnd.viewport);

	// Set up the depth bounds
	if (glConfig.depthBoundsTestAvailable)
		GL_DepthBounds(0.0f, 1.0f);

	// Set the projection matrix
	GL_LoadMatrix(GL_PROJECTION, backEnd.viewParms.projectionMatrix);

	// Set the modelview matrix
	GL_LoadIdentity(GL_MODELVIEW);

	// Set the GL state
	GL_PolygonMode(GL_FILL);

	GL_Disable(GL_CULL_FACE);
	GL_Disable(GL_POLYGON_OFFSET_FILL);
	GL_Disable(GL_BLEND);
	GL_Disable(GL_ALPHA_TEST);
	GL_Disable(GL_DEPTH_TEST);
	GL_Disable(GL_STENCIL_TEST);

	GL_DepthRange(0.0f, 1.0f);

	GL_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
	GL_DepthMask(GL_TRUE);
	GL_StencilMask(255);

	// Enable the clip plane if needed
	if (backEnd.viewParms.viewType != VIEW_MIRROR)
		qglDisable(GL_CLIP_PLANE0);
	else {
		clipPlane[0] = -DotProduct(backEnd.viewParms.axis[1], backEnd.viewParms.clipPlane.normal);
		clipPlane[1] = DotProduct(backEnd.viewParms.axis[2], backEnd.viewParms.clipPlane.normal);
		clipPlane[2] = -DotProduct(backEnd.viewParms.axis[0], backEnd.viewParms.clipPlane.normal);
		clipPlane[3] = DotProduct(backEnd.viewParms.origin, backEnd.viewParms.clipPlane.normal) - backEnd.viewParms.clipPlane.dist;

		qglEnable(GL_CLIP_PLANE0);
		qglClipPlane(GL_CLIP_PLANE0, clipPlane);
	}

	// Enable multisampling if available
	if (glConfig.multiSamples > 1)
		qglEnable(GL_MULTISAMPLE);

	// Clear the buffers
	qglClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	qglClearDepth(1.0f);
	qglClearStencil(0);

	if (backEnd.viewParms.primaryView)
		qglClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
	else
		qglClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

	// Check for errors
	if (!r_ignoreGLErrors->integerValue)
		GL_CheckForErrors();

	QGL_LogPrintf("--------------------\n");
}
コード例 #13
0
/*
 ==================
 GL_Setup2D

 TODO: time is messed up
 ==================
*/
void GL_Setup2D (int time){

	mat4_t	projectionMatrix = {2.0f / backEnd.cropWidth, 0.0f, 0.0f, 0.0f, 0.0f, -2.0f / backEnd.cropHeight, 0.0f, 0.0f, 0.0f, 0.0f, -2.0f, 0.0f, -1.0f, 1.0f, -1.0f, 1.0f};

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

	backEnd.projection2D = true;

	backEnd.time = time;
	backEnd.floatTime = MS2SEC(Sys_Milliseconds());

	backEnd.viewport.x = 0;
	backEnd.viewport.y = 0;
	backEnd.viewport.width = backEnd.cropWidth;
	backEnd.viewport.height = backEnd.cropHeight;

	backEnd.scissor.x = 0;
	backEnd.scissor.y = 0;
	backEnd.scissor.width = backEnd.cropWidth;
	backEnd.scissor.height = backEnd.cropHeight;

	backEnd.coordScale[0] = 1.0f / backEnd.viewport.width;
	backEnd.coordScale[1] = 1.0f / backEnd.viewport.height;

	backEnd.coordBias[0] = -backEnd.viewport.x * backEnd.coordScale[0];
	backEnd.coordBias[1] = -backEnd.viewport.y * backEnd.coordScale[1];

	backEnd.depthFilling = false;
	backEnd.debugRendering = false;

	backEnd.currentColorCaptured = SORT_BAD;
	backEnd.currentDepthCaptured = false;

	// Set up the viewport
	GL_Viewport(backEnd.viewport);

	// Set up the scissor
	GL_Scissor(backEnd.viewport);

	// Set up the depth bounds
	if (glConfig.depthBoundsTestAvailable)
		GL_DepthBounds(0.0f, 1.0f);

	// Set the projection matrix
	GL_LoadMatrix(GL_PROJECTION, projectionMatrix);

	// Set the modelview matrix
	GL_LoadIdentity(GL_MODELVIEW);

	// Set the GL state
	GL_PolygonMode(GL_FILL);

	GL_Disable(GL_CULL_FACE);
	GL_Disable(GL_POLYGON_OFFSET_FILL);
	GL_Disable(GL_BLEND);
	GL_Disable(GL_ALPHA_TEST);
	GL_Disable(GL_DEPTH_TEST);
	GL_Disable(GL_STENCIL_TEST);

	GL_DepthRange(0.0f, 1.0f);

	GL_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
	GL_DepthMask(GL_FALSE);
	GL_StencilMask(255);

	// Disable the clip plane
	qglDisable(GL_CLIP_PLANE0);

	// Disable multisampling if available
	if (glConfig.multiSamples > 1)
		qglDisable(GL_MULTISAMPLE);

	// Check for errors
	if (!r_ignoreGLErrors->integerValue)
		GL_CheckForErrors();

	QGL_LogPrintf("--------------------\n");
}
コード例 #14
0
ファイル: r_draw.c プロジェクト: Nephatrine/nephq2
void R_DrawCameraEffect (void)
{
	image_t			*image[2];
	int32_t				x, y, w, h, i, j;
	float			texparms[2][4];
	vec2_t			texCoord[4];
	vec3_t			verts[4];
	renderparms_t	cameraParms;

	image[0] = R_DrawFindPic ("/gfx/2d/screenstatic.tga");
	image[1] = R_DrawFindPic ("/gfx/2d/scanlines.tga");

	if (!image[0] || !image[1])
		return;

	x = y = 0; w = vid.width; h = vid.height;
	GL_Disable (GL_ALPHA_TEST);
	GL_TexEnv (GL_MODULATE);
	GL_Enable (GL_BLEND);
	GL_BlendFunc (GL_DST_COLOR, GL_SRC_COLOR);
	GL_DepthMask   (false);

	VectorSet(verts[0], x, y, 0);
	VectorSet(verts[1], x+w, y, 0);
	VectorSet(verts[2], x+w, y+h, 0);
	VectorSet(verts[3], x, y+h, 0);

	Vector4Set(texparms[0], 2, 2, -30, 10);
	Vector4Set(texparms[1], 1, 10, 0, 0);

	rb_vertex = rb_index = 0;
	indexArray[rb_index++] = rb_vertex+0;
	indexArray[rb_index++] = rb_vertex+1;
	indexArray[rb_index++] = rb_vertex+2;
	indexArray[rb_index++] = rb_vertex+0;
	indexArray[rb_index++] = rb_vertex+2;
	indexArray[rb_index++] = rb_vertex+3;
	rb_vertex = 4;

	for (i=0; i<2; i++)
	{
		GL_Bind (image[i]->texnum);
		Vector2Set(texCoord[0], x/image[i]->width, y/image[i]->height);
		Vector2Set(texCoord[1], (x+w)/image[i]->width, y/image[i]->height);
		Vector2Set(texCoord[2], (x+w)/image[i]->width, (y+h)/image[i]->height);
		Vector2Set(texCoord[3], x/image[i]->width, (y+h)/image[i]->height);
		Mod_SetRenderParmsDefaults (&cameraParms);
		cameraParms.scale_x = texparms[i][0];
		cameraParms.scale_y = texparms[i][1];
		cameraParms.scroll_x = texparms[i][2];
		cameraParms.scroll_y = texparms[i][3];
		RB_ModifyTextureCoords (&texCoord[0][0], &verts[0][0], 4, cameraParms);
		for (j=0; j<4; j++) {
			VA_SetElem2(texCoordArray[0][j], texCoord[j][0], texCoord[j][1]);
			VA_SetElem3(vertexArray[j], verts[j][0], verts[j][1], verts[j][2]);
			VA_SetElem4(colorArray[j], 1, 1, 1, 1);
		}
		RB_DrawArrays ();
	}
	rb_vertex = rb_index = 0;

	GL_DepthMask (true);
	GL_BlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	GL_Disable (GL_BLEND);
	GL_TexEnv (GL_REPLACE);
	GL_Enable (GL_ALPHA_TEST);
}
コード例 #15
0
ファイル: r_draw.c プロジェクト: Nephatrine/nephq2
/*
 =============
 R_DrawScaledImage
 Psychospaz's code for drawing stretched crosshairs
 =============
 */
void R_DrawScaledImage (int32_t x, int32_t y, float scale, float alpha, image_t *gl)
{
    float	xoff, yoff;
    float	scale_x, scale_y;
    int32_t		i;
    vec2_t	texCoord[4], verts[4];
    
    if (scrap_dirty)
        Scrap_Upload ();
    
    // add alpha support
    if (gl->has_alpha || alpha < 1.0)
    {
        GL_Disable (GL_ALPHA_TEST);
        GL_TexEnv (GL_MODULATE);
        GL_Enable (GL_BLEND);
        GL_DepthMask (false);
    }
    
    GL_Bind (gl->texnum);
    
    scale_x = scale_y = scale;
    scale_x *= gl->replace_scale_w; // scale down if replacing a pcx image
    scale_y *= gl->replace_scale_h; // scale down if replacing a pcx image
    
    Vector2Set(texCoord[0], gl->sl, gl->tl);
    Vector2Set(texCoord[1], gl->sh, gl->tl);
    Vector2Set(texCoord[2], gl->sh, gl->th);
    Vector2Set(texCoord[3], gl->sl, gl->th);
    
    xoff = gl->width*scale_x-gl->width;
    yoff = gl->height*scale_y-gl->height;
    
    Vector2Set(verts[0], x, y);
    Vector2Set(verts[1], x+gl->width+xoff, y);
    Vector2Set(verts[2], x+gl->width+xoff, y+gl->height+yoff);
    Vector2Set(verts[3], x, y+gl->height+yoff);
    
    rb_vertex = rb_index = 0;
    indexArray[rb_index++] = rb_vertex+0;
    indexArray[rb_index++] = rb_vertex+1;
    indexArray[rb_index++] = rb_vertex+2;
    indexArray[rb_index++] = rb_vertex+0;
    indexArray[rb_index++] = rb_vertex+2;
    indexArray[rb_index++] = rb_vertex+3;
    for (i=0; i<4; i++) {
        VA_SetElem2(texCoordArray[0][rb_vertex], texCoord[i][0], texCoord[i][1]);
        VA_SetElem3(vertexArray[rb_vertex], verts[i][0], verts[i][1], 0);
        VA_SetElem4(colorArray[rb_vertex], 1.0, 1.0, 1.0, alpha);
        rb_vertex++;
    }
    RB_RenderMeshGeneric (false);
    
    if (gl->has_alpha || alpha < 1.0)
    {
        GL_DepthMask (true);
        GL_TexEnv (GL_REPLACE);
        GL_Disable (GL_BLEND);
        GL_Enable (GL_ALPHA_TEST); // add alpha support
    }
}
コード例 #16
0
ファイル: r_draw.c プロジェクト: postfix/quake2vr
/*
 =============
 R_DrawScaledImage
 Psychospaz's code for drawing stretched crosshairs
 =============
 */
void R_DrawScaledImage (int32_t x, int32_t y, float scale, float alpha, image_t *gl)
{
    float	xoff, yoff;
    float	scale_x, scale_y;

    const vec4_t color[4] = {
        {1.0, 1.0, 1.0, alpha},
        {1.0, 1.0, 1.0, alpha},
        {1.0, 1.0, 1.0, alpha},
        {1.0, 1.0, 1.0, alpha}
    };

    if (scrap_dirty)
        Scrap_Upload ();

    // add alpha support
    if (gl->has_alpha || alpha < 1.0)
    {
        GL_Disable (GL_ALPHA_TEST);
        GL_TexEnv (GL_MODULATE);
        GL_Enable (GL_BLEND);
        GL_DepthMask (false);
    }

    GL_Bind (gl->texnum);

    scale_x = scale_y = scale;
    scale_x *= gl->replace_scale_w; // scale down if replacing a pcx image
    scale_y *= gl->replace_scale_h; // scale down if replacing a pcx image


    xoff = gl->width*scale_x-gl->width;
    yoff = gl->height*scale_y-gl->height;

    rb_vertex = rb_index = 0;

    memcpy(indexArray, indices, sizeof(indices));
    rb_index = 6;

    VA_SetElem2(texCoordArray[0][0], gl->sl, gl->tl);
    VA_SetElem2(texCoordArray[0][1], gl->sh, gl->tl);
    VA_SetElem2(texCoordArray[0][2], gl->sh, gl->th);
    VA_SetElem2(texCoordArray[0][3], gl->sl, gl->th);


    VA_SetElem3(vertexArray[0], x, y, 0);
    VA_SetElem3(vertexArray[1], x+gl->width+xoff, y, 0);
    VA_SetElem3(vertexArray[2], x+gl->width+xoff, y+gl->height+yoff, 0);
    VA_SetElem3(vertexArray[3], x, y+gl->height+yoff, 0);

    memcpy(colorArray, color, sizeof(vec4_t) * 4);

    rb_vertex = 4;


    RB_RenderMeshGeneric (false);

    if (gl->has_alpha || alpha < 1.0)
    {
        GL_DepthMask (true);
        GL_TexEnv (GL_REPLACE);
        GL_Disable (GL_BLEND);
        GL_Enable (GL_ALPHA_TEST); // add alpha support
    }
}
コード例 #17
0
/**
* @brief This routine is responsible for setting the most commonly changed state in Q3.
*/
void GL_State(uint32_t stateBits)
{
	uint32_t diff = stateBits ^ glState.glStateBits;

	if (!diff)
	{
		return;
	}

	// check depthFunc bits
	if (diff & GLS_DEPTHFUNC_BITS)
	{
		switch (stateBits & GLS_DEPTHFUNC_BITS)
		{
		default:
			GL_DepthFunc(GL_LEQUAL);
			break;
		case GLS_DEPTHFUNC_LESS:
			GL_DepthFunc(GL_LESS);
			break;
		case GLS_DEPTHFUNC_EQUAL:
			GL_DepthFunc(GL_EQUAL);
			break;
		}
	}

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

		if (stateBits & (GLS_SRCBLEND_BITS | GLS_DSTBLEND_BITS))
		{
			switch (stateBits & GLS_SRCBLEND_BITS)
			{
			case GLS_SRCBLEND_ZERO:
				srcFactor = GL_ZERO;
				break;
			case GLS_SRCBLEND_ONE:
				srcFactor = GL_ONE;
				break;
			case GLS_SRCBLEND_DST_COLOR:
				srcFactor = GL_DST_COLOR;
				break;
			case GLS_SRCBLEND_ONE_MINUS_DST_COLOR:
				srcFactor = GL_ONE_MINUS_DST_COLOR;
				break;
			case GLS_SRCBLEND_SRC_ALPHA:
				srcFactor = GL_SRC_ALPHA;
				break;
			case GLS_SRCBLEND_ONE_MINUS_SRC_ALPHA:
				srcFactor = GL_ONE_MINUS_SRC_ALPHA;
				break;
			case GLS_SRCBLEND_DST_ALPHA:
				srcFactor = GL_DST_ALPHA;
				break;
			case GLS_SRCBLEND_ONE_MINUS_DST_ALPHA:
				srcFactor = GL_ONE_MINUS_DST_ALPHA;
				break;
			case GLS_SRCBLEND_ALPHA_SATURATE:
				srcFactor = GL_SRC_ALPHA_SATURATE;
				break;
			default:
				srcFactor = GL_ONE;     // to get warning to shut up
				Ren_Drop("GL_State: invalid src blend state bits\n");
				break;
			}

			switch (stateBits & GLS_DSTBLEND_BITS)
			{
			case GLS_DSTBLEND_ZERO:
				dstFactor = GL_ZERO;
				break;
			case GLS_DSTBLEND_ONE:
				dstFactor = GL_ONE;
				break;
			case GLS_DSTBLEND_SRC_COLOR:
				dstFactor = GL_SRC_COLOR;
				break;
			case GLS_DSTBLEND_ONE_MINUS_SRC_COLOR:
				dstFactor = GL_ONE_MINUS_SRC_COLOR;
				break;
			case GLS_DSTBLEND_SRC_ALPHA:
				dstFactor = GL_SRC_ALPHA;
				break;
			case GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA:
				dstFactor = GL_ONE_MINUS_SRC_ALPHA;
				break;
			case GLS_DSTBLEND_DST_ALPHA:
				dstFactor = GL_DST_ALPHA;
				break;
			case GLS_DSTBLEND_ONE_MINUS_DST_ALPHA:
				dstFactor = GL_ONE_MINUS_DST_ALPHA;
				break;
			default:
				dstFactor = GL_ONE;     // to get warning to shut up
				Ren_Drop("GL_State: invalid dst blend state bits\n");
				break;
			}

			glEnable(GL_BLEND);
			GL_BlendFunc(srcFactor, dstFactor);
		}
		else
		{
			glDisable(GL_BLEND);
		}
	}

	// check colormask
	if (diff & GLS_COLORMASK_BITS)
	{
		if (stateBits & GLS_COLORMASK_BITS)
		{
			GL_ColorMask((stateBits & GLS_REDMASK_FALSE) ? GL_FALSE : GL_TRUE,
			             (stateBits & GLS_GREENMASK_FALSE) ? GL_FALSE : GL_TRUE,
			             (stateBits & GLS_BLUEMASK_FALSE) ? GL_FALSE : GL_TRUE,
			             (stateBits & GLS_ALPHAMASK_FALSE) ? GL_FALSE : GL_TRUE);
		}
		else
		{
			GL_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
		}
	}

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

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

	// depthtest
	if (diff & GLS_DEPTHTEST_DISABLE)
	{
		if (stateBits & GLS_DEPTHTEST_DISABLE)
		{
			glDisable(GL_DEPTH_TEST);
		}
		else
		{
			glEnable(GL_DEPTH_TEST);
		}
	}

	// alpha test - deprecated in OpenGL 3.0
#if 0
	if (diff & GLS_ATEST_BITS)
	{
		switch (stateBits & GLS_ATEST_BITS)
		{
		case GLS_ATEST_GT_0:
		case GLS_ATEST_LT_128:
		case GLS_ATEST_GE_128:
			//case GLS_ATEST_GT_CUSTOM:
			glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE);
			break;

		default:
		case 0:
			glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
			break;
		}
	}
#endif

	/*
	if(diff & GLS_ATEST_BITS)
	{
	switch (stateBits & GLS_ATEST_BITS)
	{
	case 0:
	glDisable(GL_ALPHA_TEST);
	break;
	case GLS_ATEST_GT_0:
	glEnable(GL_ALPHA_TEST);
	glAlphaFunc(GL_GREATER, 0.0f);
	break;
	case GLS_ATEST_LT_80:
	glEnable(GL_ALPHA_TEST);
	glAlphaFunc(GL_LESS, 0.5f);
	break;
	case GLS_ATEST_GE_80:
	glEnable(GL_ALPHA_TEST);
	glAlphaFunc(GL_GEQUAL, 0.5f);
	break;
	case GLS_ATEST_GT_CUSTOM:
	// FIXME
	glEnable(GL_ALPHA_TEST);
	glAlphaFunc(GL_GREATER, 0.5f);
	break;
	default:
	assert(0);
	break;
	}
	}
	*/

	// stenciltest
	if (diff & GLS_STENCILTEST_ENABLE)
	{
		if (stateBits & GLS_STENCILTEST_ENABLE)
		{
			glEnable(GL_STENCIL_TEST);
		}
		else
		{
			glDisable(GL_STENCIL_TEST);
		}
	}

	glState.glStateBits = stateBits;
}
コード例 #18
0
ファイル: r_alias.c プロジェクト: ptitSeb/gravitybone-pandora
/*
=============
R_DrawAliasVolumeShadow
based on code from BeefQuake R6
=============
*/
void R_DrawAliasVolumeShadow (maliasmodel_t *paliashdr, vec3_t bbox[8])
{
	vec3_t		light, temp, vecAdd;
	float		dist, highest, lowest, projected_distance;
	float		angle, cosp, sinp, cosy, siny, cosr, sinr, ix, iy, iz;
	int			i, lnum;
	dlight_t	*dl;

	dl = r_newrefdef.dlights;

	VectorSet(vecAdd, 680,0,1024); // set base vector, was 576,0,1024

	// compute average light vector from dlights
	for (i=0, lnum=0; i<r_newrefdef.num_dlights; i++, dl++)
	{
		if (VectorCompare(dl->origin, currententity->origin))
			continue;
		
		VectorSubtract(dl->origin, currententity->origin, temp);
		dist = dl->intensity - VectorLength(temp);
		if (dist <= 0)
			continue;
		
		lnum++;
		// Factor in the intensity of a dlight
		VectorScale (temp, dist*0.25, temp);
		VectorAdd (vecAdd, temp, vecAdd);
	}
	VectorNormalize(vecAdd);
	VectorScale(vecAdd, 1024, vecAdd);

	// get projection distance from lightspot height
	highest = lowest = bbox[0][2];
	for (i=0; i<8; i++) {
		if (bbox[i][2] > highest) highest = bbox[i][2];
		if (bbox[i][2] < lowest) lowest = bbox[i][2];
	}
	projected_distance = (fabs(highest - lightspot[2]) + (highest-lowest)) / vecAdd[2];

	VectorCopy(vecAdd, light);
	
	/*cosy = cos(-currententity->angles[YAW] / 180 * M_PI);
	siny = sin(-currententity->angles[YAW] / 180 * M_PI);

	ix = light[0], iy = light[1];
	light[0] = (cosy * (ix - 0) + siny * (0 - iy) + 0);
	light[1] = (cosy * (iy - 0) + siny * (ix - 0) + 0);
	light[2] += 8;*/

	// reverse-rotate light vector based on angles
	angle = -currententity->angles[PITCH] / 180 * M_PI;
	cosp = cos(angle), sinp = sin(angle);
	angle = -currententity->angles[YAW] / 180 * M_PI;
	cosy = cos(angle), siny = sin(angle);
	angle = currententity->angles[ROLL] / 180 * M_PI; // roll is backwards
	cosr = cos(angle), sinr = sin(angle);

	// rotate for yaw (z axis)
	ix = light[0], iy = light[1];
	light[0] = cosy * ix - siny * iy + 0;
	light[1] = siny * ix + cosy * iy + 0;

	// rotate for pitch (y axis)
	ix = light[0], iz = light[2];
	light[0] = cosp * ix + 0 + sinp * iz;
	light[2] = -sinp * ix + 0 + cosp * iz;

	// rotate for roll (x axis)
	iy = light[1], iz = light[2];
	light[1] = 0 + cosr * iy - sinr * iz;
	light[2] = 0 + sinr * iy + cosr * iz;


	// set up stenciling
	if (!r_shadowvolumes->value)
	{
		qglPushAttrib(GL_STENCIL_BUFFER_BIT); // save stencil buffer
		qglClear(GL_STENCIL_BUFFER_BIT);

		qglColorMask(0,0,0,0);
		GL_DepthMask(0);
		GL_DepthFunc(GL_LESS);

		GL_Enable(GL_STENCIL_TEST);
		qglStencilFunc(GL_ALWAYS, 0, 255);
	//	qglStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
	//	qglStencilMask (255);
	}

	// build shadow volumes and render each to stencil buffer
	for (i=0; i<paliashdr->num_meshes; i++)
	{
		if (paliashdr->meshes[i].skins[currententity->skinnum].renderparms.nodraw
			|| paliashdr->meshes[i].skins[currententity->skinnum].renderparms.alphatest
			|| paliashdr->meshes[i].skins[currententity->skinnum].renderparms.noshadow)
			continue;

		R_BuildShadowVolume (paliashdr, i, light, projected_distance, r_shadowvolumes->value);
		GL_LockArrays (shadow_va);

		if (!r_shadowvolumes->value)
		{
			if (gl_config.atiSeparateStencil && gl_config.extStencilWrap) // Barnes ATI stenciling
			{
				GL_Disable(GL_CULL_FACE);

				qglStencilOpSeparateATI (GL_BACK, GL_KEEP, GL_INCR_WRAP_EXT, GL_KEEP); 
				qglStencilOpSeparateATI (GL_FRONT, GL_KEEP, GL_DECR_WRAP_EXT, GL_KEEP);

				R_DrawShadowVolume ();

				GL_Enable(GL_CULL_FACE);
			}
			else if (gl_config.extStencilTwoSide && gl_config.extStencilWrap) // Echon's two-sided stenciling
			{
				GL_Disable(GL_CULL_FACE);
				qglEnable (GL_STENCIL_TEST_TWO_SIDE_EXT);

				qglActiveStencilFaceEXT (GL_BACK);
				qglStencilOp (GL_KEEP, GL_INCR_WRAP_EXT, GL_KEEP);
				qglActiveStencilFaceEXT (GL_FRONT);
				qglStencilOp (GL_KEEP, GL_DECR_WRAP_EXT, GL_KEEP);

				R_DrawShadowVolume ();

				qglDisable (GL_STENCIL_TEST_TWO_SIDE_EXT);
				GL_Enable(GL_CULL_FACE);
			}
			else
			{	// increment stencil if backface is behind depthbuffer
				GL_CullFace(GL_BACK); // quake is backwards, this culls front faces
				qglStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
				R_DrawShadowVolume ();

				// decrement stencil if frontface is behind depthbuffer
				GL_CullFace(GL_FRONT); // quake is backwards, this culls back faces
				qglStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
				R_DrawShadowVolume ();
			}
		}
		else
			R_DrawShadowVolume ();

		GL_UnlockArrays ();
	}

	// end stenciling and draw stenciled volume
	if (!r_shadowvolumes->value)
	{
		GL_CullFace(GL_FRONT);
		GL_Disable(GL_STENCIL_TEST);
		
		GL_DepthFunc(GL_LEQUAL);
		GL_DepthMask(1);
		qglColorMask(1,1,1,1);
		
		// draw shadows for this model now
		R_ShadowBlend (aliasShadowAlpha * currententity->alpha); // was r_shadowalpha->value
		qglPopAttrib(); // restore stencil buffer
	}
}