⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 surf.java

📁 JAKE2用JAVA写的queck2的3D游戏开发引擎
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
/* * Surf.java * Copyright (C) 2003 * * $Id: Surf.java,v 1.6 2005/01/09 22:34:21 cawe Exp $ *//*Copyright (C) 1997-2001 Id Software, Inc.This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of the License, or (at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.*/package jake2.render.jogl;import jake2.Defines;import jake2.client.*;import jake2.game.cplane_t;import jake2.qcommon.Com;import jake2.render.*;import jake2.util.Lib;import jake2.util.Math3D;import java.nio.ByteOrder;import java.nio.IntBuffer;import java.util.Arrays;import net.java.games.jogl.GL;/** * Surf *   * @author cwei */public abstract class Surf extends Draw {	// GL_RSURF.C: surface-related refresh code	float[] modelorg = {0, 0, 0};		// relative to viewpoint	msurface_t	r_alpha_surfaces;	static final int DYNAMIC_LIGHT_WIDTH = 128;	static final int DYNAMIC_LIGHT_HEIGHT = 128;	static final int LIGHTMAP_BYTES = 4;	static final int BLOCK_WIDTH = 128;	static final int BLOCK_HEIGHT = 128;	static final int MAX_LIGHTMAPS = 128;	int c_visible_lightmaps;	int c_visible_textures;	static final int GL_LIGHTMAP_FORMAT = GL.GL_RGBA;	static class gllightmapstate_t 	{		int internal_format;		int current_lightmap_texture;		msurface_t[] lightmap_surfaces = new msurface_t[MAX_LIGHTMAPS];		int[] allocated = new int[BLOCK_WIDTH];		// the lightmap texture data needs to be kept in		// main memory so texsubimage can update properly		IntBuffer lightmap_buffer = Lib.newIntBuffer(BLOCK_WIDTH * BLOCK_HEIGHT, ByteOrder.LITTLE_ENDIAN);						public gllightmapstate_t() {			for (int i = 0; i < MAX_LIGHTMAPS; i++)				lightmap_surfaces[i] = new msurface_t();		}				public void clearLightmapSurfaces() {			for (int i = 0; i < MAX_LIGHTMAPS; i++)				// TODO lightmap_surfaces[i].clear();				lightmap_surfaces[i] = new msurface_t();		}			} 	gllightmapstate_t gl_lms = new gllightmapstate_t();////	static void		LM_InitBlock( void );//	static void		LM_UploadBlock( qboolean dynamic );//	static qboolean	LM_AllocBlock (int w, int h, int *x, int *y);////	extern void R_SetCacheState( msurface_t *surf );//	extern void R_BuildLightMap (msurface_t *surf, byte *dest, int stride);//	// Model.java	abstract byte[] Mod_ClusterPVS(int cluster, model_t model);	// Warp.java	abstract void R_DrawSkyBox();	abstract void R_AddSkySurface(msurface_t surface);	abstract void R_ClearSkyBox();	abstract void EmitWaterPolys(msurface_t fa);	// Light.java	abstract void R_MarkLights (dlight_t light, int bit, mnode_t node);	abstract void R_SetCacheState( msurface_t surf );	abstract void R_BuildLightMap(msurface_t surf, IntBuffer dest, int stride);	/*	=============================================================		BRUSH MODELS	=============================================================	*/	/*	===============	R_TextureAnimation	Returns the proper texture for a given time and base texture	===============	*/	image_t R_TextureAnimation(mtexinfo_t tex)	{		int		c;		if (tex.next == null)			return tex.image;		c = currententity.frame % tex.numframes;		while (c != 0)		{			tex = tex.next;			c--;		}		return tex.image;	}	/*	================	DrawGLPoly	================	*/	void DrawGLPoly(glpoly_t p)	{		gl.glBegin(GL.GL_POLYGON);		for (int i=0 ; i<p.numverts ; i++)		{			gl.glTexCoord2f(p.s1(i), p.t1(i));			gl.glVertex3f(p.x(i), p.y(i), p.z(i));		}		gl.glEnd();	}	//	  ============	//	  PGM	/*	================	DrawGLFlowingPoly -- version of DrawGLPoly that handles scrolling texture	================	*/	void DrawGLFlowingPoly(msurface_t fa)	{		float scroll = -64 * ( (r_newrefdef.time / 40.0f) - (int)(r_newrefdef.time / 40.0f) );		if(scroll == 0.0f)			scroll = -64.0f;		gl.glBegin (GL.GL_POLYGON);		glpoly_t p = fa.polys;		for (int i=0 ; i<p.numverts ; i++)		{			gl.glTexCoord2f(p.s1(i) + scroll, p.t1(i));			gl.glVertex3f(p.x(i), p.y(i), p.z(i));		}		gl.glEnd ();	}	//	  PGM	//	  ============	/*	** R_DrawTriangleOutlines	*/	void R_DrawTriangleOutlines()	{		if (gl_showtris.value == 0)			return;		gl.glDisable (GL.GL_TEXTURE_2D);		gl.glDisable (GL.GL_DEPTH_TEST);		gl.glColor4f (1,1,1,1);		for (int i=0 ; i<MAX_LIGHTMAPS ; i++)		{			msurface_t surf;			for ( surf = gl_lms.lightmap_surfaces[i]; surf != null; surf = surf.lightmapchain )			{				glpoly_t p = surf.polys;				for ( ; p != null ; p=p.chain)				{					for (int j=2 ; j<p.numverts ; j++ )					{						gl.glBegin (GL.GL_LINE_STRIP);						gl.glVertex3f(p.x(0), p.y(0), p.z(0));						gl.glVertex3f(p.x(j-1), p.y(j-1), p.z(j-1));						gl.glVertex3f(p.x(j), p.y(j), p.z(j));						gl.glVertex3f(p.x(0), p.y(0), p.z(0));						gl.glEnd ();					}				}			}		}		gl.glEnable (GL.GL_DEPTH_TEST);		gl.glEnable (GL.GL_TEXTURE_2D);	}	/*	** DrawGLPolyChain	*/	void DrawGLPolyChain( glpoly_t p, float soffset, float toffset )	{		if ( soffset == 0 && toffset == 0 )		{			for ( ; p != null; p = p.chain )			{				gl.glBegin(GL.GL_POLYGON);				for (int j=0 ; j<p.numverts ; j++)				{					gl.glTexCoord2f (p.s2(j), p.t2(j));					gl.glVertex3f(p.x(j), p.y(j), p.z(j));				}				gl.glEnd();			}		}		else		{			for ( ; p != null; p = p.chain )			{				gl.glBegin(GL.GL_POLYGON);				for (int j=0 ; j<p.numverts ; j++)				{					gl.glTexCoord2f (p.s2(j) - soffset, p.t2(j) - toffset);					gl.glVertex3f(p.x(j), p.y(j), p.z(j));				}				gl.glEnd();			}		}	}	/*	** R_BlendLightMaps	**	** This routine takes all the given light mapped surfaces in the world and	** blends them into the framebuffer.	*/	void R_BlendLightmaps()	{		int i;		msurface_t	surf; 		msurface_t newdrawsurf = null;		// don't bother if we're set to fullbright		if (r_fullbright.value != 0)			return;		if (r_worldmodel.lightdata == null)			return;		// don't bother writing Z		gl.glDepthMask( false );		/*		** set the appropriate blending mode unless we're only looking at the		** lightmaps.		*/		if (gl_lightmap.value == 0)		{			gl.glEnable(GL.GL_BLEND);			if ( gl_saturatelighting.value != 0)			{				gl.glBlendFunc( GL.GL_ONE, GL.GL_ONE );			}			else			{				char format = gl_monolightmap.string.toUpperCase().charAt(0);				if ( format != '0' )				{					switch ( format )					{					case 'I':						gl.glBlendFunc(GL.GL_ZERO, GL.GL_SRC_COLOR );						break;					case 'L':						gl.glBlendFunc(GL.GL_ZERO, GL.GL_SRC_COLOR );						break;					case 'A':					default:						gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA );						break;					}				}				else				{					gl.glBlendFunc(GL.GL_ZERO, GL.GL_SRC_COLOR );				}			}		}		if ( currentmodel == r_worldmodel )			c_visible_lightmaps = 0;		/*		** render static lightmaps first		*/		for ( i = 1; i < MAX_LIGHTMAPS; i++ )		{			if ( gl_lms.lightmap_surfaces[i] != null )			{				if (currentmodel == r_worldmodel)					c_visible_lightmaps++;									GL_Bind( gl_state.lightmap_textures + i);				for ( surf = gl_lms.lightmap_surfaces[i]; surf != null; surf = surf.lightmapchain )				{					if ( surf.polys != null )						DrawGLPolyChain( surf.polys, 0, 0 );				}			}		}				// TODO impl: render dynamic lightmaps		/*		** render dynamic lightmaps		*/		if ( gl_dynamic.value != 0 )		{			LM_InitBlock();			GL_Bind( gl_state.lightmap_textures+0 );			if (currentmodel == r_worldmodel)				c_visible_lightmaps++;			newdrawsurf = gl_lms.lightmap_surfaces[0];			for ( surf = gl_lms.lightmap_surfaces[0]; surf != null; surf = surf.lightmapchain )			{				int smax, tmax;				IntBuffer base;				smax = (surf.extents[0]>>4)+1;				tmax = (surf.extents[1]>>4)+1;								pos_t lightPos = new pos_t(surf.dlight_s, surf.dlight_t);				if ( LM_AllocBlock( smax, tmax, lightPos) )				{					// kopiere die koordinaten zurueck					surf.dlight_s = lightPos.x;					surf.dlight_t = lightPos.y;					base = gl_lms.lightmap_buffer;					base.position(surf.dlight_t * BLOCK_WIDTH + surf.dlight_s );					R_BuildLightMap (surf, base.slice(), BLOCK_WIDTH);				}				else				{					msurface_t drawsurf;					// upload what we have so far					LM_UploadBlock( true );					// draw all surfaces that use this lightmap					for ( drawsurf = newdrawsurf; drawsurf != surf; drawsurf = drawsurf.lightmapchain )					{						if ( drawsurf.polys != null )							DrawGLPolyChain( drawsurf.polys, 											  ( drawsurf.light_s - drawsurf.dlight_s ) * ( 1.0f / 128.0f ), 											( drawsurf.light_t - drawsurf.dlight_t ) * ( 1.0f / 128.0f ) );					}					newdrawsurf = drawsurf;					// clear the block					LM_InitBlock();					// try uploading the block now					if ( !LM_AllocBlock( smax, tmax, lightPos) )					{						Com.Error( Defines.ERR_FATAL, "Consecutive calls to LM_AllocBlock(" + smax + "," + tmax + ") failed (dynamic)\n");					}										// kopiere die koordinaten zurueck					surf.dlight_s = lightPos.x;					surf.dlight_t = lightPos.y;					base = gl_lms.lightmap_buffer;					base.position(surf.dlight_t * BLOCK_WIDTH + surf.dlight_s );					R_BuildLightMap (surf, base.slice(), BLOCK_WIDTH);				}			}			/*			** draw remainder of dynamic lightmaps that haven't been uploaded yet			*/			if ( newdrawsurf != null )				LM_UploadBlock( true );			for ( surf = newdrawsurf; surf != null; surf = surf.lightmapchain )			{				if ( surf.polys != null )					DrawGLPolyChain( surf.polys, ( surf.light_s - surf.dlight_s ) * ( 1.0f / 128.0f ), ( surf.light_t - surf.dlight_t ) * ( 1.0f / 128.0f ) );			}		}		/*		** restore state		*/		gl.glDisable(GL.GL_BLEND);		gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);		gl.glDepthMask( true );	}		private IntBuffer temp2 = Lib.newIntBuffer(34 * 34, ByteOrder.LITTLE_ENDIAN);	/*	================	R_RenderBrushPoly	================	*/	void R_RenderBrushPoly(msurface_t fa)	{		int maps;		image_t image;		boolean is_dynamic = false;		c_brush_polys++;		image = R_TextureAnimation(fa.texinfo);		if ((fa.flags & Defines.SURF_DRAWTURB) != 0)		{				GL_Bind( image.texnum );			// warp texture, no lightmaps			GL_TexEnv( GL.GL_MODULATE );			gl.glColor4f( gl_state.inverse_intensity, 						gl_state.inverse_intensity,						gl_state.inverse_intensity,						1.0F );			EmitWaterPolys (fa);			GL_TexEnv( GL.GL_REPLACE );			return;		}		else		{			GL_Bind( image.texnum );			GL_TexEnv( GL.GL_REPLACE );		}		//	  ======		//	  PGM		if((fa.texinfo.flags & Defines.SURF_FLOWING) != 0)			DrawGLFlowingPoly(fa);		else			DrawGLPoly (fa.polys);		//	  PGM		//	  ======		// ersetzt goto		boolean gotoDynamic = false;		/*		** check for lightmap modification		*/		for ( maps = 0; maps < Defines.MAXLIGHTMAPS && fa.styles[maps] != (byte)255; maps++ )		{			if ( r_newrefdef.lightstyles[fa.styles[maps] & 0xFF].white != fa.cached_light[maps] ) {				gotoDynamic = true;				break;			}		}				// this is a hack from cwei		if (maps == 4) maps--;		// dynamic this frame or dynamic previously		if ( gotoDynamic || ( fa.dlightframe == r_framecount ) )		{			//	label dynamic:			if ( gl_dynamic.value != 0 )			{				if (( fa.texinfo.flags & (Defines.SURF_SKY | Defines.SURF_TRANS33 | Defines.SURF_TRANS66 | Defines.SURF_WARP ) ) == 0)				{					is_dynamic = true;				}			}		}		if ( is_dynamic )		{			if ( ( (fa.styles[maps] & 0xFF) >= 32 || fa.styles[maps] == 0 ) && ( fa.dlightframe != r_framecount ) )			{				// ist ersetzt durch temp2:	unsigned	temp[34*34];				int smax, tmax;				smax = (fa.extents[0]>>4)+1;				tmax = (fa.extents[1]>>4)+1;				R_BuildLightMap( fa, temp2, smax);				R_SetCacheState( fa );				GL_Bind( gl_state.lightmap_textures + fa.lightmaptexturenum );				gl.glTexSubImage2D( GL.GL_TEXTURE_2D, 0,								  fa.light_s, fa.light_t, 								  smax, tmax, 								  GL_LIGHTMAP_FORMAT, 								  GL.GL_UNSIGNED_BYTE, temp2 );				fa.lightmapchain = gl_lms.lightmap_surfaces[fa.lightmaptexturenum];				gl_lms.lightmap_surfaces[fa.lightmaptexturenum] = fa;			}			else			{				fa.lightmapchain = gl_lms.lightmap_surfaces[0];				gl_lms.lightmap_surfaces[0] = fa;			}		}		else		{			fa.lightmapchain = gl_lms.lightmap_surfaces[fa.lightmaptexturenum];			gl_lms.lightmap_surfaces[fa.lightmaptexturenum] = fa;		}	}	/*	================	R_DrawAlphaSurfaces	Draw water surfaces and windows.	The BSP tree is waled front to back, so unwinding the chain	of alpha_surfaces will draw back to front, giving proper ordering.	================	*/	void R_DrawAlphaSurfaces()	{		msurface_t s;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -