コード例 #1
0
ファイル: gl_draw.c プロジェクト: Xash3DLinux/xash3dlinux
/*
=============
R_UploadStretchRaw
=============
*/
void R_UploadStretchRaw( int texture, int cols, int rows, int width, int height, const byte *data )
{
	byte		*raw = NULL;
	gltexture_t	*tex;

	if( !GL_Support( GL_ARB_TEXTURE_NPOT_EXT ))
	{
		// check the dimensions
		width = NearestPOW( width, true );
		height = NearestPOW( height, false );
	}
	else
	{
		width = bound( 128, width, glConfig.max_2d_texture_size );
		height = bound( 128, height, glConfig.max_2d_texture_size );
	}

	if( cols != width || rows != height )
	{
		raw = GL_ResampleTexture( data, cols, rows, width, height, false );
		cols = width;
		rows = height;
	}
	else
	{
		raw = (byte *)data;
	}

	if( cols > glConfig.max_2d_texture_size )
		Host_Error( "R_UploadStretchRaw: size %i exceeds hardware limits\n", cols );
	if( rows > glConfig.max_2d_texture_size )
		Host_Error( "R_UploadStretchRaw: size %i exceeds hardware limits\n", rows );

	tex = R_GetTexture( texture );
	GL_Bind( GL_TEXTURE0, texture );
	tex->width = cols;
	tex->height = rows;

	pglTexImage2D( GL_TEXTURE_2D, 0, tex->format, cols, rows, 0, GL_BGRA, GL_UNSIGNED_BYTE, raw );
	GL_TexFilter( tex, false );
}
コード例 #2
0
ファイル: gl_draw.c プロジェクト: Xash3DLinux/xash3dlinux
/*
=============
R_DrawStretchRaw
=============
*/
void R_DrawStretchRaw( float x, float y, float w, float h, int cols, int rows, const byte *data, qboolean dirty )
{
	byte		*raw = NULL;
	gltexture_t	*tex;

	if( !GL_Support( GL_ARB_TEXTURE_NPOT_EXT ))
	{
		int	width = 1, height = 1;
	
		// check the dimensions
		width = NearestPOW( cols, true );
		height = NearestPOW( rows, false );

		if( cols != width || rows != height )
		{
			raw = GL_ResampleTexture( data, cols, rows, width, height, false );
			cols = width;
			rows = height;
		}
	}
	else
	{
		raw = (byte *)data;
	}

	if( cols > glConfig.max_2d_texture_size )
		Host_Error( "R_DrawStretchRaw: size %i exceeds hardware limits\n", cols );
	if( rows > glConfig.max_2d_texture_size )
		Host_Error( "R_DrawStretchRaw: size %i exceeds hardware limits\n", rows );

	pglDisable( GL_BLEND );
	pglDisable( GL_ALPHA_TEST );
	pglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );

	tex = R_GetTexture( tr.cinTexture );
	GL_Bind( GL_TEXTURE0, tr.cinTexture );

	if( cols == tex->width && rows == tex->height )
	{
		if( dirty )
		{
			pglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_BGRA, GL_UNSIGNED_BYTE, raw );
		}
	}
	else
	{
		tex->width = cols;
		tex->height = rows;
		if( dirty )
		{
			pglTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, cols, rows, 0, GL_BGRA, GL_UNSIGNED_BYTE, raw );
		}
	}

	pglBegin( GL_QUADS );
	pglTexCoord2f( 0, 0 );
	pglVertex2f( x, y );
	pglTexCoord2f( 1, 0 );
	pglVertex2f( x + w, y );
	pglTexCoord2f( 1, 1 );
	pglVertex2f( x + w, y + h );
	pglTexCoord2f( 0, 1 );
	pglVertex2f( x, y + h );
	pglEnd();
}
コード例 #3
0
ファイル: gl_mirror.c プロジェクト: DavidKnight247/xash3d
/*
================
R_DrawMirrors

Draw all viewpasess from mirror position
Mirror textures will be drawn in normal pass
================
*/
void R_DrawMirrors( void )
{
	ref_instance_t	oldRI;
	mplane_t		plane;
	msurface_t	*surf, *surf2;
	int		i, oldframecount;
	mextrasurf_t	*es, *tmp, *mirrorchain;
	vec3_t		forward, right, up;
	vec3_t		origin, angles;
	matrix4x4		mirrormatrix;
	cl_entity_t	*e;
	model_t		*m;
	float		d;

	if( !tr.num_mirror_entities ) return; // mo mirrors for this frame

	oldRI = RI; // make refinst backup
	oldframecount = tr.framecount;

	for( i = 0; i < tr.num_mirror_entities; i++ )
	{
		mirrorchain = tr.mirror_entities[i].chain;

		for( es = mirrorchain; es != NULL; es = es->mirrorchain )
		{
			RI.currententity = e = tr.mirror_entities[i].ent;
			RI.currentmodel = m = RI.currententity->model;

			surf = INFO_SURF( es, m );

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

			// NOTE: copy mirrortexture and mirrormatrix from another surfaces
			// from this entity\world that has same planes and reduce number of viewpasses

			// make sure what we have one pass at least
			if( es != mirrorchain )
			{
				for( tmp = mirrorchain; tmp != es; tmp = tmp->mirrorchain )
				{
					surf2 = INFO_SURF( tmp, m );

					if( !tmp->mirrortexturenum )
						continue;	// not filled?

					if( surf->plane->dist != surf2->plane->dist )
						continue;

					if( !VectorCompare( surf->plane->normal, surf2->plane->normal ))
						continue;

					// found surface with same plane!
					break;
				}

				if( tmp != es && tmp && tmp->mirrortexturenum )
				{
					// just copy reflection texture from surface with same plane
					Matrix4x4_Copy( es->mirrormatrix, tmp->mirrormatrix );
					es->mirrortexturenum = tmp->mirrortexturenum;
					continue;	// pass skiped
				}
			} 

			R_PlaneForMirror( surf, &plane, mirrormatrix );

			d = -2.0f * ( DotProduct( RI.vieworg, plane.normal ) - plane.dist );
			VectorMA( RI.vieworg, d, plane.normal, origin );

			d = -2.0f * DotProduct( RI.vforward, plane.normal );
			VectorMA( RI.vforward, d, plane.normal, forward );
			VectorNormalize( forward );

			d = -2.0f * DotProduct( RI.vright, plane.normal );
			VectorMA( RI.vright, d, plane.normal, right );
			VectorNormalize( right );

			d = -2.0f * DotProduct( RI.vup, plane.normal );
			VectorMA( RI.vup, d, plane.normal, up );
			VectorNormalize( up );

			VectorsAngles( forward, right, up, angles );
			angles[ROLL] = -angles[ROLL];

			RI.params = RP_MIRRORVIEW|RP_CLIPPLANE|RP_OLDVIEWLEAF;

			RI.clipPlane = plane;
			RI.clipFlags |= ( 1<<5 );

			RI.frustum[5] = plane;
			RI.frustum[5].signbits = SignbitsForPlane( RI.frustum[5].normal );
			RI.frustum[5].type = PLANE_NONAXIAL;

			RI.refdef.viewangles[0] = anglemod( angles[0] );
			RI.refdef.viewangles[1] = anglemod( angles[1] );
			RI.refdef.viewangles[2] = anglemod( angles[2] );
			VectorCopy( origin, RI.refdef.vieworg );
			VectorCopy( origin, RI.cullorigin );

			// put pvsorigin before the mirror plane to avoid get full visibility on world mirrors
			if( RI.currententity == clgame.entities )
			{
				VectorMA( es->origin, 1.0f, plane.normal, origin );
			}
			else
			{
				Matrix4x4_VectorTransform( mirrormatrix, es->origin, origin );
				VectorMA( origin, 1.0f, plane.normal, origin );
			}

			VectorCopy( origin, RI.pvsorigin );

			// combine two leafs from client and mirror views
			r_viewleaf = Mod_PointInLeaf( oldRI.pvsorigin, cl.worldmodel->nodes );
			r_viewleaf2 = Mod_PointInLeaf( RI.pvsorigin, cl.worldmodel->nodes );

			if( GL_Support( GL_ARB_TEXTURE_NPOT_EXT ))
			{
				// allow screen size
				RI.viewport[2] = bound( 96, RI.viewport[2], 1024 );
				RI.viewport[3] = bound( 72, RI.viewport[3], 768 );
			}
			else
			{
				RI.viewport[2] = NearestPOW( RI.viewport[2], true );
				RI.viewport[3] = NearestPOW( RI.viewport[3], true );
				RI.viewport[2] = bound( 128, RI.viewport[2], 1024 );
				RI.viewport[3] = bound( 64, RI.viewport[3], 512 );
			}

			tr.framecount++;
			R_RenderScene( &RI.refdef );
			r_stats.c_mirror_passes++;

			es->mirrortexturenum = R_AllocateMirrorTexture();

			// create personal projection matrix for mirror
			if( VectorIsNull( e->origin ) && VectorIsNull( e->angles ))
			{
				Matrix4x4_Copy( es->mirrormatrix, RI.worldviewProjectionMatrix );
			}
			else
			{
				Matrix4x4_ConcatTransforms( RI.modelviewMatrix, RI.worldviewMatrix, mirrormatrix );
				Matrix4x4_Concat( es->mirrormatrix, RI.projectionMatrix, RI.modelviewMatrix );
			}			

			RI = oldRI; // restore ref instance
		}

		// clear chain for this entity
		for( es = mirrorchain; es != NULL; )
		{
			tmp = es->mirrorchain;
			es->mirrorchain = NULL;
			es = tmp;
		}

		tr.mirror_entities[i].chain = NULL; // done
		tr.mirror_entities[i].ent = NULL;
	}

	r_oldviewleaf = r_viewleaf = NULL;	// force markleafs next frame
	tr.framecount = oldframecount;	// restore real framecount
	tr.num_mirror_entities = 0;
	tr.num_mirrors_used = 0;
}