Esempio n. 1
0
void DrawSingleDecal( decal_t *pDecal, msurface_t *fa )
{
	float	*v;
	int	i, numVerts;

	v = R_DecalSetupVerts( pDecal, fa, pDecal->texture, &numVerts );
	if( !numVerts ) return;

	GL_Bind( GL_TEXTURE0, pDecal->texture );

	pglBegin( GL_POLYGON );

	for( i = 0; i < numVerts; i++, v += VERTEXSIZE )
	{
		pglTexCoord2f( v[3], v[4] );
		pglVertex3fv( v );
	}

	pglEnd();
}
Esempio n. 2
0
/*
====================
R_BuildMeshForDecal

creates mesh for decal on first rendering
====================
*/
msurfmesh_t *R_DecalCreateMesh( decalinfo_t *decalinfo, decal_t *pdecal, msurface_t *surf )
{
	float		*v;
	uint		i, bufSize;
	qboolean		createSTverts = false;
	int		numVerts, numElems;
	byte		*buffer;
	msurfmesh_t	*mesh;

	if( pdecal->mesh )
	{
		// already have mesh
		return pdecal->mesh;
	}

	v = R_DecalSetupVerts( pdecal, surf, pdecal->texture, &numVerts );
	if( !numVerts ) return NULL;	// probably this never happens

	// allocate mesh
	numElems = (numVerts - 2) * 3;

	bufSize = sizeof( msurfmesh_t ) + numVerts * sizeof( glvert_t ) + numElems * sizeof( word );
	buffer = Mem_Alloc( cls.mempool, bufSize );

	mesh = (msurfmesh_t *)buffer;
	buffer += sizeof( msurfmesh_t );
	mesh->numVerts = numVerts;
	mesh->numElems = numElems;

	// setup pointers
	mesh->verts = (glvert_t *)buffer;
	buffer += numVerts * sizeof( glvert_t );
	mesh->elems = (word *)buffer;
	buffer += numElems * sizeof( word );

	mesh->surf = surf;	// NOTE: meshchains can be linked with one surface

	// create indices
	for( i = 0; i < mesh->numVerts - 2; i++ )
	{
		mesh->elems[i*3+0] = 0;
		mesh->elems[i*3+1] = i + 1;
		mesh->elems[i*3+2] = i + 2;
	}
	#ifdef __arm__
	float inv_w = 1.0f / surf->texinfo->texture->width;
	float inv_h = 1.0f / surf->texinfo->texture->height;
	#endif

	// fill the mesh
	for( i = 0; i < numVerts; i++, v += VERTEXSIZE )
	{
		glvert_t	*out = &mesh->verts[i];
		VectorCopy( v, out->vertex );
		VectorCopy( decalinfo->m_Basis[0], out->tangent );
		VectorCopy( decalinfo->m_Basis[1], out->binormal );
		VectorCopy( decalinfo->m_Basis[2], out->normal );

		out->stcoord[0] = v[3];
		out->stcoord[1] = v[4];
		out->lmcoord[0] = v[5];
		out->lmcoord[1] = v[6];
		out->sccoord[0] = (( DotProduct( v , surf->texinfo->vecs[0] ) + surf->texinfo->vecs[0][3] ) 
		#ifdef __arm__
			* inv_w );
		#else
			/ surf->texinfo->texture->width );
		#endif
		out->sccoord[1] = (( DotProduct( v , surf->texinfo->vecs[1] ) + surf->texinfo->vecs[1][3] ) 
		#ifdef __arm__
			* inv_h );
		#else
			/ surf->texinfo->texture->height );
Esempio n. 3
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 );
}