Пример #1
0
PDGL_API void pdglStencilOp(GLenum fail,
		GLenum zfail, GLenum zpass)
{
	if(pglStencilOp)
		{ pglStencilOp(fail, zfail, zpass); return; }
	pglStencilOp=pdglGetProcAddress("glStencilOp");
	pglStencilOp(fail, zfail, zpass);
}
Пример #2
0
void DrawSurfaceDecals( msurface_t *fa )
{
	decal_t		*p;
	cl_entity_t	*e;

	if( !fa->pdecals ) return;

	e = RI.currententity;
	ASSERT( e != NULL );

	if( e->curstate.rendermode == kRenderNormal || e->curstate.rendermode == kRenderTransAlpha )
	{
		pglDepthMask( GL_FALSE );
		pglEnable( GL_BLEND );

		if( e->curstate.rendermode == kRenderTransAlpha )
			pglDisable( GL_ALPHA_TEST );
	}

	if( e->curstate.rendermode == kRenderTransColor )
		pglEnable( GL_TEXTURE_2D );

	if( e->curstate.rendermode == kRenderTransTexture || e->curstate.rendermode == kRenderTransAdd )
		GL_Cull( GL_NONE );

	pglEnable( GL_POLYGON_OFFSET_FILL );
	pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );

	if( fa->flags & SURF_TRANSPARENT && glState.stencilEnabled )
	{
		mtexinfo_t	*tex = fa->texinfo;

		for( p = fa->pdecals; p; p = p->pnext )
		{
			if( p->texture )
			{
				float *o, *v;
				int i, numVerts;
				o = R_DecalSetupVerts( p, fa, p->texture, &numVerts );

				pglEnable( GL_STENCIL_TEST );
				pglStencilFunc( GL_ALWAYS, 1, 0xFFFFFFFF );
				pglColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );

				pglStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
				pglBegin( GL_POLYGON );

				for( i = 0, v = o; i < numVerts; i++, v += VERTEXSIZE )
				{
					v[5] = ( DotProduct( v, tex->vecs[0] ) + tex->vecs[0][3] ) / tex->texture->width;
					v[6] = ( DotProduct( v, tex->vecs[1] ) + tex->vecs[1][3] ) / tex->texture->height;

					pglTexCoord2f( v[5], v[6] );
					pglVertex3fv( v );
				}

				pglEnd();
				pglStencilOp( GL_KEEP, GL_KEEP, GL_DECR );

				pglEnable( GL_ALPHA_TEST );
				pglBegin( GL_POLYGON );

				for( i = 0, v = o; i < numVerts; i++, v += VERTEXSIZE )
				{
					pglTexCoord2f( v[5], v[6] );
					pglVertex3fv( v );
				}

				pglEnd();
				pglDisable( GL_ALPHA_TEST );

				pglColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
				pglStencilFunc( GL_EQUAL, 0, 0xFFFFFFFF );
				pglStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
			}
		}
	}

	for( p = fa->pdecals; p; p = p->pnext )
	{
		if( p->texture )
		{
			gltexture_t *glt = R_GetTexture( p->texture );

			// normal HL decal with alpha-channel
			if( glt->flags & TF_HAS_ALPHA )
			{
				// draw transparent decals with GL_MODULATE
				if( glt->fogParams[3] > DECAL_TRANSPARENT_THRESHOLD )
					pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
				else pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
				pglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
			}
			else
			{
				// color decal like detail texture. Base color is 127 127 127
				pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
				pglBlendFunc( GL_DST_COLOR, GL_SRC_COLOR );
                              }

			DrawSingleDecal( p, fa );
		}
	}

	if( fa->flags & SURF_TRANSPARENT && glState.stencilEnabled )
		pglDisable( GL_STENCIL_TEST );

	if( e->curstate.rendermode == kRenderNormal || e->curstate.rendermode == kRenderTransAlpha )
	{
		pglDepthMask( GL_TRUE );
		pglDisable( GL_BLEND );

		if( e->curstate.rendermode == kRenderTransAlpha )
			pglEnable( GL_ALPHA_TEST );
	}

	pglDisable( GL_POLYGON_OFFSET_FILL );

	if( e->curstate.rendermode == kRenderTransTexture || e->curstate.rendermode == kRenderTransAdd )
		GL_Cull( GL_FRONT );

	if( e->curstate.rendermode == kRenderTransColor )
		pglDisable( GL_TEXTURE_2D );

	// restore blendfunc here
	if( e->curstate.rendermode == kRenderTransAdd || e->curstate.rendermode == kRenderGlow )
		pglBlendFunc( GL_SRC_ALPHA, GL_ONE );
}