aboutsummaryrefslogtreecommitdiffstats
path: root/src/jake2/render/fastjogl/Surf.java
diff options
context:
space:
mode:
authorRene Stoeckel <[email protected]>2004-09-22 19:22:16 +0000
committerRene Stoeckel <[email protected]>2004-09-22 19:22:16 +0000
commitc4fcffe436fbfb5b0f3b7be2e5ee103ec74932f7 (patch)
tree7c9439ab1d9f5a4fd61bd57c755069007b23e0b6 /src/jake2/render/fastjogl/Surf.java
parentbcb4ac6eefb425d5b0a90009da506361d5739e75 (diff)
major refactoring in game, server and client package
Diffstat (limited to 'src/jake2/render/fastjogl/Surf.java')
-rw-r--r--src/jake2/render/fastjogl/Surf.java2764
1 files changed, 1331 insertions, 1433 deletions
diff --git a/src/jake2/render/fastjogl/Surf.java b/src/jake2/render/fastjogl/Surf.java
index 32f1a92..e15e1d8 100644
--- a/src/jake2/render/fastjogl/Surf.java
+++ b/src/jake2/render/fastjogl/Surf.java
@@ -2,38 +2,49 @@
* Surf.java
* Copyright (C) 2003
*
- * $Id: Surf.java,v 1.4 2004-07-19 19:39:57 hzi Exp $
+ * $Id: Surf.java,v 1.5 2004-09-22 19:22:11 salomo Exp $
*/
/*
-Copyright (C) 1997-2001 Id Software, Inc.
+ Copyright (C) 1997-2001 Id Software, Inc.
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 2
+ of 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 of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-See the GNU General Public License for more details.
+ See the GNU General Public License for more details.
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
+ */
package jake2.render.fastjogl;
import jake2.Defines;
-import jake2.client.*;
+import jake2.client.dlight_t;
+import jake2.client.entity_t;
+import jake2.client.lightstyle_t;
import jake2.game.cplane_t;
import jake2.qcommon.Com;
-import jake2.render.*;
+import jake2.render.glpoly_t;
+import jake2.render.image_t;
+import jake2.render.medge_t;
+import jake2.render.mleaf_t;
+import jake2.render.mnode_t;
+import jake2.render.model_t;
+import jake2.render.msurface_t;
+import jake2.render.mtexinfo_t;
import jake2.util.Lib;
import jake2.util.Math3D;
-import java.nio.*;
+import java.nio.ByteOrder;
+import java.nio.FloatBuffer;
+import java.nio.IntBuffer;
import java.util.Arrays;
import net.java.games.jogl.GL;
@@ -41,1423 +52,1310 @@ import net.java.games.jogl.util.BufferUtils;
/**
* 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
- //byte[] lightmap_buffer = new byte[4 * BLOCK_WIDTH * BLOCK_HEIGHT];
- 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();
-
- // 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.glDrawArrays(GL.GL_POLYGON, p.pos, p.numverts);
- }
-
- // ============
- // PGM
- /*
- ================
- DrawGLFlowingPoly -- version of DrawGLPoly that handles scrolling texture
- ================
- */
- void DrawGLFlowingPoly(glpoly_t p)
- {
- int i;
- float scroll;
-
- scroll = -64 * ( (r_newrefdef.time / 40.0f) - (int)(r_newrefdef.time / 40.0f) );
- if(scroll == 0.0f)
- scroll = -64.0f;
-
- FloatBuffer texCoord = globalPolygonInterleavedBuf;
- float[][] v = p.verts;
- int index = p.pos * POLYGON_STRIDE;
- for (i=0 ; i<p.numverts ; i++) {
- texCoord.put(index, v[i][3] + scroll);
- index += POLYGON_STRIDE;
- }
- gl.glDrawArrays(GL.GL_POLYGON, p.pos, p.numverts);
- }
- // PGM
- // ============
-
- /*
- ** R_DrawTriangleOutlines
- */
- void R_DrawTriangleOutlines()
- {
- int i, j;
- glpoly_t p;
-
- 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 (i=0 ; i<MAX_LIGHTMAPS ; i++)
- {
- msurface_t surf;
-
- for ( surf = gl_lms.lightmap_surfaces[i]; surf != null; surf = surf.lightmapchain )
- {
- p = surf.polys;
- for ( ; p != null ; p=p.chain)
- {
- for (j=2 ; j<p.numverts ; j++ )
- {
- gl.glBegin (GL.GL_LINE_STRIP);
- gl.glVertex3fv (p.verts[0]);
- gl.glVertex3fv (p.verts[j-1]);
- gl.glVertex3fv (p.verts[j]);
- gl.glVertex3fv (p.verts[0]);
- gl.glEnd ();
- }
- }
- }
- }
-
- gl.glEnable (GL.GL_DEPTH_TEST);
- gl.glEnable (GL.GL_TEXTURE_2D);
- }
-
- 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.polys);
- 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;
- float intens;
-
- //
- // go back to the world matrix
- //
- gl.glLoadMatrixf(r_world_matrix);
-
- gl.glEnable (GL.GL_BLEND);
- GL_TexEnv(GL.GL_MODULATE );
-
-
- // the textures are prescaled up for a better lighting range,
- // so scale it back down
- intens = gl_state.inverse_intensity;
-
- gl.glInterleavedArrays(GL.GL_T2F_V3F, POLYGON_BYTE_STRIDE, globalPolygonInterleavedBuf);
-
- for (s=r_alpha_surfaces ; s != null ; s=s.texturechain)
- {
- GL_Bind(s.texinfo.image.texnum);
- c_brush_polys++;
- if ((s.texinfo.flags & Defines.SURF_TRANS33) != 0)
- gl.glColor4f (intens, intens, intens, 0.33f);
- else if ((s.texinfo.flags & Defines.SURF_TRANS66) != 0)
- gl.glColor4f (intens, intens, intens, 0.66f);
- else
- gl.glColor4f (intens,intens,intens,1);
- if ((s.flags & Defines.SURF_DRAWTURB) != 0)
- EmitWaterPolys(s);
- else if((s.texinfo.flags & Defines.SURF_FLOWING) != 0) // PGM 9/16/98
- DrawGLFlowingPoly(s.polys); // PGM
- else
- DrawGLPoly(s.polys);
- }
-
- GL_TexEnv( GL.GL_REPLACE );
- gl.glColor4f (1,1,1,1);
- gl.glDisable (GL.GL_BLEND);
-
- r_alpha_surfaces = null;
- }
-
- /*
- ================
- DrawTextureChains
- ================
- */
- void DrawTextureChains()
- {
- int i;
- msurface_t s;
- image_t image;
-
- c_visible_textures = 0;
-
- for (i = 0; i < numgltextures ; i++)
- {
- image = gltextures[i];
-
- if (image.registration_sequence == 0)
- continue;
- if (image.texturechain == null)
- continue;
- c_visible_textures++;
-
- for ( s = image.texturechain; s != null ; s=s.texturechain)
- {
- if ( ( s.flags & Defines.SURF_DRAWTURB) == 0 )
- R_RenderBrushPoly(s);
- }
- }
-
- GL_EnableMultitexture( false );
- for (i = 0; i < numgltextures ; i++)
- {
- image = gltextures[i];
-
- if (image.registration_sequence == 0)
- continue;
- s = image.texturechain;
- if (s == null)
- continue;
-
- for ( ; s != null ; s=s.texturechain)
- {
- if ( (s.flags & Defines.SURF_DRAWTURB) != 0 )
- R_RenderBrushPoly(s);
- }
-
- image.texturechain = null;
- }
-
- GL_TexEnv( GL.GL_REPLACE );
- }
-
- // direct buffer
- private IntBuffer temp = Lib.newIntBuffer(128 * 128, ByteOrder.LITTLE_ENDIAN);
-
- void GL_RenderLightmappedPoly( msurface_t surf )
- {
- int i, nv = surf.polys.numverts;
- int map = 0;
- int index;
- float[][] v;
- FloatBuffer texCoord = globalPolygonInterleavedBuf;
- image_t image = R_TextureAnimation( surf.texinfo );
- boolean is_dynamic = false;
- int lmtex = surf.lightmaptexturenum;
- glpoly_t p;
-
- // ersetzt goto
- boolean gotoDynamic = false;
-
- for ( map = 0; map < Defines.MAXLIGHTMAPS && (surf.styles[map] != (byte)255); map++ )
- {
- if ( r_newrefdef.lightstyles[surf.styles[map] & 0xFF].white != surf.cached_light[map] ) {
- gotoDynamic = true;
- break;
- }
- }
-
- // this is a hack from cwei
- if (map == 4) map--;
-
- // dynamic this frame or dynamic previously
- if ( gotoDynamic || ( surf.dlightframe == r_framecount ) )
- {
- // label dynamic:
- if ( gl_dynamic.value != 0 )
- {
- if ( (surf.texinfo.flags & (Defines.SURF_SKY | Defines.SURF_TRANS33 | Defines.SURF_TRANS66 | Defines.SURF_WARP )) == 0 )
- {
- is_dynamic = true;
- }
- }
- }
-
- if ( is_dynamic )
- {
- // ist raus gezogen worden int[] temp = new int[128*128];
- int smax, tmax;
-
- if ( ( (surf.styles[map] & 0xFF) >= 32 || surf.styles[map] == 0 ) && ( surf.dlightframe != r_framecount ) )
- {
- smax = (surf.extents[0]>>4)+1;
- tmax = (surf.extents[1]>>4)+1;
-
- R_BuildLightMap( surf, temp, smax);
- R_SetCacheState( surf );
-
- GL_MBind( GL_TEXTURE1, gl_state.lightmap_textures + surf.lightmaptexturenum );
-
- lmtex = surf.lightmaptexturenum;
-
- gl.glTexSubImage2D( GL.GL_TEXTURE_2D, 0,
- surf.light_s, surf.light_t,
- smax, tmax,
- GL_LIGHTMAP_FORMAT,
- GL.GL_UNSIGNED_BYTE, temp );
-
- }
- else
- {
- smax = (surf.extents[0]>>4)+1;
- tmax = (surf.extents[1]>>4)+1;
-
- R_BuildLightMap( surf, temp, smax);
-
- GL_MBind( GL_TEXTURE1, gl_state.lightmap_textures + 0 );
-
- lmtex = 0;
-
- gl.glTexSubImage2D( GL.GL_TEXTURE_2D, 0,
- surf.light_s, surf.light_t,
- smax, tmax,
- GL_LIGHTMAP_FORMAT,
- GL.GL_UNSIGNED_BYTE, temp );
-
- }
-
- c_brush_polys++;
-
- GL_MBind( GL_TEXTURE0, image.texnum );
- GL_MBind( GL_TEXTURE1, gl_state.lightmap_textures + lmtex );
-
- // ==========
- // PGM
- if ((surf.texinfo.flags & Defines.SURF_FLOWING) != 0)
- {
- float scroll;
-
- scroll = -64 * ( (r_newrefdef.time / 40.0f) - (int)(r_newrefdef.time / 40.0f) );
- if(scroll == 0.0f)
- scroll = -64.0f;
-
- for ( p = surf.polys; p != null; p = p.chain )
- {
- v = p.verts;
- index = p.pos * POLYGON_STRIDE;
- for (i=0 ; i<p.numverts ; i++) {
- texCoord.put(index, v[i][3] + scroll);
- index += POLYGON_STRIDE;
- }
- gl.glDrawArrays(GL.GL_POLYGON, p.pos, p.numverts);
- }
- }
- else
- {
- for ( p = surf.polys; p != null; p = p.chain )
- {
- gl.glDrawArrays(GL.GL_POLYGON, p.pos, p.numverts);
- }
- }
- // PGM
- // ==========
- }
- else
- {
- c_brush_polys++;
-
- GL_MBind( GL_TEXTURE0, image.texnum );
- GL_MBind( GL_TEXTURE1, gl_state.lightmap_textures + lmtex);
-
- // ==========
- // PGM
- if ((surf.texinfo.flags & Defines.SURF_FLOWING) != 0)
- {
- float scroll;
-
- scroll = -64 * ( (r_newrefdef.time / 40.0f) - (int)(r_newrefdef.time / 40.0f) );
- if(scroll == 0.0)
- scroll = -64.0f;
-
- for ( p = surf.polys; p != null; p = p.chain )
- {
- v = p.verts;
- index = p.pos * POLYGON_STRIDE;
- for (i=0 ; i<p.numverts ; i++) {
- texCoord.put(index, v[i][3] + scroll);
- index += POLYGON_STRIDE;
- }
- gl.glDrawArrays(GL.GL_POLYGON, p.pos, p.numverts);
- }
- }
- else
- {
- // PGM
- // ==========
- for ( p = surf.polys; p != null; p = p.chain )
- {
- gl.glDrawArrays(GL.GL_POLYGON, p.pos, p.numverts);
- }
-
- // ==========
- // PGM
- }
- // PGM
- // ==========
- }
- }
-
- /*
- =================
- R_DrawInlineBModel
- =================
- */
- void R_DrawInlineBModel()
- {
- int i, k;
- cplane_t pplane;
- float dot;
- msurface_t psurf;
- dlight_t lt;
-
- // calculate dynamic lighting for bmodel
- if ( gl_flashblend.value == 0 )
- {
- for (k=0 ; k<r_newrefdef.num_dlights ; k++)
- {
- lt = r_newrefdef.dlights[k];
- R_MarkLights(lt, 1<<k, currentmodel.nodes[currentmodel.firstnode]);
- }
- }
-
- // psurf = &currentmodel->surfaces[currentmodel->firstmodelsurface];
- int psurfp = currentmodel.firstmodelsurface;
- msurface_t[] surfaces;
- surfaces = currentmodel.surfaces;
- //psurf = surfaces[psurfp];
-
- if ( (currententity.flags & Defines.RF_TRANSLUCENT) != 0 )
- {
- gl.glEnable (GL.GL_BLEND);
- gl.glColor4f (1,1,1,0.25f);
- GL_TexEnv( GL.GL_MODULATE );
- }
-
- //
- // draw texture
- //
- for (i=0 ; i<currentmodel.nummodelsurfaces ; i++)
- {
- psurf = surfaces[psurfp++];
- // find which side of the node we are on
- pplane = psurf.plane;
-
- dot = Math3D.DotProduct(modelorg, pplane.normal) - pplane.dist;
-
- // draw the polygon
- if (((psurf.flags & Defines.SURF_PLANEBACK) != 0 && (dot < -BACKFACE_EPSILON)) ||
- ((psurf.flags & Defines.SURF_PLANEBACK) == 0 && (dot > BACKFACE_EPSILON)))
- {
- if ((psurf.texinfo.flags & (Defines.SURF_TRANS33 | Defines.SURF_TRANS66)) != 0 )
- { // add to the translucent chain
- psurf.texturechain = r_alpha_surfaces;
- r_alpha_surfaces = psurf;
- }
- else if ( (psurf.flags & Defines.SURF_DRAWTURB) == 0 )
- {
- GL_RenderLightmappedPoly( psurf );
- }
- else
- {
- GL_EnableMultitexture( false );
- R_RenderBrushPoly( psurf );
- GL_EnableMultitexture( true );
- }
- }
- }
-
- if ( (currententity.flags & Defines.RF_TRANSLUCENT) != 0 ) {
- gl.glDisable (GL.GL_BLEND);
- gl.glColor4f (1,1,1,1);
- GL_TexEnv( GL.GL_REPLACE );
- }
- }
-
- /*
- =================
- R_DrawBrushModel
- =================
- */
- void R_DrawBrushModel(entity_t e)
- {
- float[] mins = {0, 0, 0};
- float[] maxs = {0, 0, 0};
- int i;
- boolean rotated;
-
- if (currentmodel.nummodelsurfaces == 0)
- return;
-
- currententity = e;
- gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1;
-
- if (e.angles[0] != 0 || e.angles[1] != 0 || e.angles[2] != 0)
- {
- rotated = true;
- for (i=0 ; i<3 ; i++)
- {
- mins[i] = e.origin[i] - currentmodel.radius;
- maxs[i] = e.origin[i] + currentmodel.radius;
- }
- }
- else
- {
- rotated = false;
- Math3D.VectorAdd(e.origin, currentmodel.mins, mins);
- Math3D.VectorAdd(e.origin, currentmodel.maxs, maxs);
- }
-
- if (R_CullBox(mins, maxs)) return;
-
- gl.glColor3f (1,1,1);
-
- // memset (gl_lms.lightmap_surfaces, 0, sizeof(gl_lms.lightmap_surfaces));
-
- // TODO wird beim multitexturing nicht gebraucht
- //gl_lms.clearLightmapSurfaces();
-
- Math3D.VectorSubtract (r_newrefdef.vieworg, e.origin, modelorg);
- if (rotated)
- {
- float[] temp = {0, 0, 0};
- float[] forward = {0, 0, 0};
- float[] right = {0, 0, 0};
- float[] up = {0, 0, 0};
-
- Math3D.VectorCopy (modelorg, temp);
- Math3D.AngleVectors (e.angles, forward, right, up);
- modelorg[0] = Math3D.DotProduct (temp, forward);
- modelorg[1] = -Math3D.DotProduct (temp, right);
- modelorg[2] = Math3D.DotProduct (temp, up);
- }
-
- gl.glPushMatrix();
-
- e.angles[0] = -e.angles[0]; // stupid quake bug
- e.angles[2] = -e.angles[2]; // stupid quake bug
- R_RotateForEntity(e);
- e.angles[0] = -e.angles[0]; // stupid quake bug
- e.angles[2] = -e.angles[2]; // stupid quake bug
-
- GL_EnableMultitexture( true );
- GL_SelectTexture(GL_TEXTURE0);
- GL_TexEnv( GL.GL_REPLACE );
- gl.glInterleavedArrays(GL.GL_T2F_V3F, POLYGON_BYTE_STRIDE, globalPolygonInterleavedBuf);
- GL_SelectTexture(GL_TEXTURE1);
- GL_TexEnv( GL.GL_MODULATE );
- gl.glTexCoordPointer(2, GL.GL_FLOAT, POLYGON_BYTE_STRIDE, globalPolygonTexCoord1Buf);
- gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);
-
- R_DrawInlineBModel();
-
- gl.glClientActiveTextureARB(GL_TEXTURE1);
- gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY);
-
- GL_EnableMultitexture( false );
-
- gl.glPopMatrix();
- }
-
- /*
- =============================================================
-
- WORLD MODEL
-
- =============================================================
- */
-
- /*
- ================
- R_RecursiveWorldNode
- ================
- */
- void R_RecursiveWorldNode (mnode_t node)
- {
- int c, side, sidebit;
- cplane_t plane;
- msurface_t surf;
- msurface_t mark;
- mleaf_t pleaf;
- float dot = 0;
- image_t image;
-
- if (node.contents == Defines.CONTENTS_SOLID)
- return; // solid
-
- if (node.visframe != r_visframecount)
- return;
-
- if (R_CullBox(node.mins, node.maxs))
- return;
-
- // if a leaf node, draw stuff
- if (node.contents != -1)
- {
- pleaf = (mleaf_t)node;
-
- // check for door connected areas
- if (r_newrefdef.areabits != null)
- {
- if ( ((r_newrefdef.areabits[pleaf.area >> 3] & 0xFF) & (1 << (pleaf.area & 7)) ) == 0 )
- return; // not visible
- }
-
- int markp = 0;
-
- mark = pleaf.getMarkSurface(markp); // first marked surface
- c = pleaf.nummarksurfaces;
-
- if (c != 0)
- {
- do
- {
- mark.visframe = r_framecount;
- mark = pleaf.getMarkSurface(++markp); // next surface
- } while (--c != 0);
- }
-
- return;
- }
-
- // node is just a decision point, so go down the apropriate sides
-
- // find which side of the node we are on
- plane = node.plane;
-
- switch (plane.type)
- {
- case Defines.PLANE_X:
- dot = modelorg[0] - plane.dist;
- break;
- case Defines.PLANE_Y:
- dot = modelorg[1] - plane.dist;
- break;
- case Defines.PLANE_Z:
- dot = modelorg[2] - plane.dist;
- break;
- default:
- dot = Math3D.DotProduct(modelorg, plane.normal) - plane.dist;
- break;
- }
-
- if (dot >= 0.0f)
- {
- side = 0;
- sidebit = 0;
- }
- else
- {
- side = 1;
- sidebit = Defines.SURF_PLANEBACK;
- }
-
- // recurse down the children, front side first
- R_RecursiveWorldNode(node.children[side]);
-
- // draw stuff
- //for ( c = node.numsurfaces, surf = r_worldmodel.surfaces[node.firstsurface]; c != 0 ; c--, surf++)
- for ( c = 0; c < node.numsurfaces; c++)
- {
- surf = r_worldmodel.surfaces[node.firstsurface + c];
- if (surf.visframe != r_framecount)
- continue;
-
- if ( (surf.flags & Defines.SURF_PLANEBACK) != sidebit )
- continue; // wrong side
-
- if ((surf.texinfo.flags & Defines.SURF_SKY) != 0)
- { // just adds to visible sky bounds
- R_AddSkySurface(surf);
- }
- else if ((surf.texinfo.flags & (Defines.SURF_TRANS33 | Defines.SURF_TRANS66)) != 0)
- { // add to the translucent chain
- surf.texturechain = r_alpha_surfaces;
- r_alpha_surfaces = surf;
- }
- else
- {
- if ( ( surf.flags & Defines.SURF_DRAWTURB) == 0 )
- {
- GL_RenderLightmappedPoly( surf );
- }
- else
- {
- // the polygon is visible, so add it to the texture
- // sorted chain
- // FIXME: this is a hack for animation
- image = R_TextureAnimation(surf.texinfo);
- surf.texturechain = image.texturechain;
- image.texturechain = surf;
- }
- }
- }
-
- // recurse down the back side
- R_RecursiveWorldNode(node.children[1 - side]);
- }
-
-
- /*
- =============
- R_DrawWorld
- =============
- */
- void R_DrawWorld()
- {
- entity_t ent = new entity_t();
- // auto cycle the world frame for texture animation
- ent.frame = (int)(r_newrefdef.time*2);
- currententity = ent;
-
- if (r_drawworld.value == 0)
- return;
-
- if ( (r_newrefdef.rdflags & Defines.RDF_NOWORLDMODEL) != 0 )
- return;
-
- currentmodel = r_worldmodel;
-
- Math3D.VectorCopy(r_newrefdef.vieworg, modelorg);
-
- gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1;
-
- gl.glColor3f (1,1,1);
- // memset (gl_lms.lightmap_surfaces, 0, sizeof(gl_lms.lightmap_surfaces));
- // TODO wird bei multitexture nicht gebraucht
- //gl_lms.clearLightmapSurfaces();
-
- R_ClearSkyBox();
-
- GL_EnableMultitexture( true );
-
- GL_SelectTexture( GL_TEXTURE0);
- GL_TexEnv( GL.GL_REPLACE );
- gl.glInterleavedArrays(GL.GL_T2F_V3F, POLYGON_BYTE_STRIDE, globalPolygonInterleavedBuf);
- GL_SelectTexture( GL_TEXTURE1);
- gl.glTexCoordPointer(2, GL.GL_FLOAT, POLYGON_BYTE_STRIDE, globalPolygonTexCoord1Buf);
- gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);
-
- if ( gl_lightmap.value != 0)
- GL_TexEnv( GL.GL_REPLACE );
- else
- GL_TexEnv( GL.GL_MODULATE );
-
- R_RecursiveWorldNode(r_worldmodel.nodes[0]); // root node
-
- gl.glClientActiveTextureARB(GL_TEXTURE1);
- gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY);
-
- GL_EnableMultitexture( false );
-
- DrawTextureChains();
- R_DrawSkyBox();
- R_DrawTriangleOutlines();
- }
-
- byte[] fatvis = new byte[Defines.MAX_MAP_LEAFS / 8];
-
- /*
- ===============
- R_MarkLeaves
-
- Mark the leaves and nodes that are in the PVS for the current
- cluster
- ===============
- */
- void R_MarkLeaves()
- {
- //byte[] vis;
- //byte[] fatvis = new byte[Defines.MAX_MAP_LEAFS / 8];
-
- //Arrays.fill(fatvis, (byte)0);
-
- mnode_t node;
- int i, c;
- mleaf_t leaf;
- int cluster;
-
- if (r_oldviewcluster == r_viewcluster && r_oldviewcluster2 == r_viewcluster2 && r_novis.value == 0 && r_viewcluster != -1)
- return;
-
- // development aid to let you run around and see exactly where
- // the pvs ends
- if (gl_lockpvs.value != 0)
- return;
-
- r_visframecount++;
- r_oldviewcluster = r_viewcluster;
- r_oldviewcluster2 = r_viewcluster2;
-
- if (r_novis.value != 0 || r_viewcluster == -1 || r_worldmodel.vis == null)
- {
- // mark everything
- for (i=0 ; i<r_worldmodel.numleafs ; i++)
- r_worldmodel.leafs[i].visframe = r_visframecount;
- for (i=0 ; i<r_worldmodel.numnodes ; i++)
- r_worldmodel.nodes[i].visframe = r_visframecount;
- return;
- }
-
- byte[] vis = Mod_ClusterPVS(r_viewcluster, r_worldmodel);
- // may have to combine two clusters because of solid water boundaries
- if (r_viewcluster2 != r_viewcluster)
- {
- // memcpy (fatvis, vis, (r_worldmodel.numleafs+7)/8);
- System.arraycopy(vis, 0, fatvis, 0, (r_worldmodel.numleafs+7) / 8);
- vis = Mod_ClusterPVS(r_viewcluster2, r_worldmodel);
- c = (r_worldmodel.numleafs + 31) / 32;
- int k = 0;
- for (i=0 ; i<c ; i++) {
- fatvis[k] |= vis[k++];
- fatvis[k] |= vis[k++];
- fatvis[k] |= vis[k++];
- fatvis[k] |= vis[k++];
- }
-
- vis = fatvis;
- }
-
- for ( i=0; i < r_worldmodel.numleafs; i++)
- {
- leaf = r_worldmodel.leafs[i];
- cluster = leaf.cluster;
- if (cluster == -1)
- continue;
- if (((vis[cluster>>3] & 0xFF) & (1 << (cluster & 7))) != 0)
- {
- node = (mnode_t)leaf;
- do
- {
- if (node.visframe == r_visframecount)
- break;
- node.visframe = r_visframecount;
- node = node.parent;
- } while (node != null);
- }
- }
- }
-
-
-
- /*
- =============================================================================
-
- LIGHTMAP ALLOCATION
-
- =============================================================================
- */
-
- void LM_InitBlock()
- {
- Arrays.fill(gl_lms.allocated, 0);
- }
-
- void LM_UploadBlock( boolean dynamic )
- {
- int texture;
- int height = 0;
-
- if ( dynamic )
- {
- texture = 0;
- }
- else
- {
- texture = gl_lms.current_lightmap_texture;
- }
-
- GL_Bind( gl_state.lightmap_textures + texture );
- gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
- gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
-
- if ( dynamic )
- {
- int i;
-
- for ( i = 0; i < BLOCK_WIDTH; i++ )
- {
- if ( gl_lms.allocated[i] > height )
- height = gl_lms.allocated[i];
- }
-
- gl.glTexSubImage2D( GL.GL_TEXTURE_2D,
- 0,
- 0, 0,
- BLOCK_WIDTH, height,
- GL_LIGHTMAP_FORMAT,
- GL.GL_UNSIGNED_BYTE,
- gl_lms.lightmap_buffer );
- }
- else
- {
- gl.glTexImage2D( GL.GL_TEXTURE_2D,
- 0,
- gl_lms.internal_format,
- BLOCK_WIDTH, BLOCK_HEIGHT,
- 0,
- GL_LIGHTMAP_FORMAT,
- GL.GL_UNSIGNED_BYTE,
- gl_lms.lightmap_buffer );
- if ( ++gl_lms.current_lightmap_texture == MAX_LIGHTMAPS )
- Com.Error( Defines.ERR_DROP, "LM_UploadBlock() - MAX_LIGHTMAPS exceeded\n" );
-
-
- //debugLightmap(gl_lms.lightmap_buffer, 128, 128, 4);
-
- }
- }
-
- // returns a texture number and the position inside it
- boolean LM_AllocBlock (int w, int h, pos_t pos)
- {
- int x = pos.x;
- int y = pos.y;
- int i, j;
- int best, best2;
-
- best = BLOCK_HEIGHT;
-
- for (i=0 ; i<BLOCK_WIDTH-w ; i++)
- {
- best2 = 0;
-
- for (j=0 ; j<w ; j++)
- {
- if (gl_lms.allocated[i+j] >= best)
- break;
- if (gl_lms.allocated[i+j] > best2)
- best2 = gl_lms.allocated[i+j];
- }
- if (j == w)
- { // this is a valid spot
- pos.x = x = i;
- pos.y = y = best = best2;
- }
- }
-
- if (best + h > BLOCK_HEIGHT)
- return false;
-
- for (i=0 ; i<w ; i++)
- gl_lms.allocated[x + i] = best + h;
-
- return true;
- }
-
- /*
- ================
- GL_BuildPolygonFromSurface
- ================
- */
- void GL_BuildPolygonFromSurface(msurface_t fa)
- {
- int i, lindex, lnumverts;
- medge_t[] pedges;
- medge_t r_pedge;
- int vertpage;
- float[] vec;
- float s, t;
- glpoly_t poly;
- float[] total = {0, 0, 0};
-
- // reconstruct the polygon
- pedges = currentmodel.edges;
- lnumverts = fa.numedges;
- vertpage = 0;
-
- Math3D.VectorClear(total);
- //
- // draw texture
- //
- // poly = Hunk_Alloc (sizeof(glpoly_t) + (lnumverts-4) * VERTEXSIZE*sizeof(float));
- poly = new glpoly_t(lnumverts);
-
- poly.next = fa.polys;
- poly.flags = fa.flags;
- fa.polys = poly;
- poly.numverts = lnumverts;
-
- for (i=0 ; i<lnumverts ; i++)
- {
- lindex = currentmodel.surfedges[fa.firstedge + i];
-
- if (lindex > 0)
- {
- r_pedge = pedges[lindex];
- vec = currentmodel.vertexes[r_pedge.v[0]].position;
- }
- else
- {
- r_pedge = pedges[-lindex];
- vec = currentmodel.vertexes[r_pedge.v[1]].position;
- }
- s = Math3D.DotProduct (vec, fa.texinfo.vecs[0]) + fa.texinfo.vecs[0][3];
- s /= fa.texinfo.image.width;
-
- t = Math3D.DotProduct (vec, fa.texinfo.vecs[1]) + fa.texinfo.vecs[1][3];
- t /= fa.texinfo.image.height;
-
- Math3D.VectorAdd (total, vec, total);
- Math3D.VectorCopy (vec, poly.verts[i]);
- poly.verts[i][3] = s;
- poly.verts[i][4] = t;
-
- //
- // lightmap texture coordinates
- //
- s = Math3D.DotProduct (vec, fa.texinfo.vecs[0]) + fa.texinfo.vecs[0][3];
- s -= fa.texturemins[0];
- s += fa.light_s*16;
- s += 8;
- s /= BLOCK_WIDTH*16; //fa.texinfo.texture.width;
-
- t = Math3D.DotProduct (vec, fa.texinfo.vecs[1]) + fa.texinfo.vecs[1][3];
- t -= fa.texturemins[1];
- t += fa.light_t*16;
- t += 8;
- t /= BLOCK_HEIGHT*16; //fa.texinfo.texture.height;
-
- poly.verts[i][5] = s;
- poly.verts[i][6] = t;
- }
-
- poly.numverts = lnumverts;
-
- precompilePolygon(poly);
-
- }
-
- /*
- ========================
- GL_CreateSurfaceLightmap
- ========================
- */
- void GL_CreateSurfaceLightmap(msurface_t surf)
- {
- int smax, tmax;
- IntBuffer base;
-
- if ( (surf.flags & (Defines.SURF_DRAWSKY | Defines.SURF_DRAWTURB)) != 0)
- return;
-
- smax = (surf.extents[0]>>4)+1;
- tmax = (surf.extents[1]>>4)+1;
-
- pos_t lightPos = new pos_t(surf.light_s, surf.light_t);
-
- if ( !LM_AllocBlock( smax, tmax, lightPos ) )
- {
- LM_UploadBlock( false );
- LM_InitBlock();
- lightPos = new pos_t(surf.light_s, surf.light_t);
- if ( !LM_AllocBlock( smax, tmax, lightPos ) )
- {
- Com.Error( Defines.ERR_FATAL, "Consecutive calls to LM_AllocBlock(" + smax +"," + tmax +") failed\n");
- }
- }
-
- // kopiere die koordinaten zurueck
- surf.light_s = lightPos.x;
- surf.light_t = lightPos.y;
-
- surf.lightmaptexturenum = gl_lms.current_lightmap_texture;
-
- base = gl_lms.lightmap_buffer;
- base.position(surf.light_t * BLOCK_WIDTH + surf.light_s);
-
- R_SetCacheState( surf );
- R_BuildLightMap(surf, base.slice(), BLOCK_WIDTH);
- }
-
- lightstyle_t[] lightstyles;
- IntBuffer dummy = BufferUtils.newIntBuffer(128*128);
-
- /*
- ==================
- GL_BeginBuildingLightmaps
-
- ==================
- */
- void GL_BeginBuildingLightmaps(model_t m)
- {
- // static lightstyle_t lightstyles[MAX_LIGHTSTYLES];
- int i;
-
- // init lightstyles
- if ( lightstyles == null ) {
- lightstyles = new lightstyle_t[Defines.MAX_LIGHTSTYLES];
- for (i = 0; i < lightstyles.length; i++)
- {
- lightstyles[i] = new lightstyle_t();
- }
- }
-
- // memset( gl_lms.allocated, 0, sizeof(gl_lms.allocated) );
- Arrays.fill(gl_lms.allocated, 0);
-
- r_framecount = 1; // no dlightcache
-
- GL_EnableMultitexture( true );
- GL_SelectTexture( GL_TEXTURE1);
-
- /*
- ** setup the base lightstyles so the lightmaps won't have to be regenerated
- ** the first time they're seen
- */
- for (i=0 ; i < Defines.MAX_LIGHTSTYLES ; i++)
- {
- lightstyles[i].rgb[0] = 1;
- lightstyles[i].rgb[1] = 1;
- lightstyles[i].rgb[2] = 1;
- lightstyles[i].white = 3;
- }
- r_newrefdef.lightstyles = lightstyles;
-
- if (gl_state.lightmap_textures == 0)
- {
- gl_state.lightmap_textures = TEXNUM_LIGHTMAPS;
- }
-
- gl_lms.current_lightmap_texture = 1;
-
- /*
- ** if mono lightmaps are enabled and we want to use alpha
- ** blending (a,1-a) then we're likely running on a 3DLabs
- ** Permedia2. In a perfect world we'd use a GL_ALPHA lightmap
- ** in order to conserve space and maximize bandwidth, however
- ** this isn't a perfect world.
- **
- ** So we have to use alpha lightmaps, but stored in GL_RGBA format,
- ** which means we only get 1/16th the color resolution we should when
- ** using alpha lightmaps. If we find another board that supports
- ** only alpha lightmaps but that can at least support the GL_ALPHA
- ** format then we should change this code to use real alpha maps.
- */
-
- char format = gl_monolightmap.string.toUpperCase().charAt(0);
-
- if ( format == 'A' )
- {
- gl_lms.internal_format = gl_tex_alpha_format;
- }
- /*
- ** try to do hacked colored lighting with a blended texture
- */
- else if ( format == 'C' )
- {
- gl_lms.internal_format = gl_tex_alpha_format;
- }
- else if ( format == 'I' )
- {
- gl_lms.internal_format = GL.GL_INTENSITY8;
- }
- else if ( format == 'L' )
- {
- gl_lms.internal_format = GL.GL_LUMINANCE8;
- }
- else
- {
- gl_lms.internal_format = gl_tex_solid_format;
- }
-
- /*
- ** initialize the dynamic lightmap texture
- */
- GL_Bind( gl_state.lightmap_textures + 0 );
- gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
- gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
- gl.glTexImage2D( GL.GL_TEXTURE_2D,
- 0,
- gl_lms.internal_format,
- BLOCK_WIDTH, BLOCK_HEIGHT,
- 0,
- GL_LIGHTMAP_FORMAT,
- GL.GL_UNSIGNED_BYTE,
- dummy );
- }
-
- /*
- =======================
- GL_EndBuildingLightmaps
- =======================
- */
- void GL_EndBuildingLightmaps()
- {
- LM_UploadBlock( false );
- GL_EnableMultitexture( false );
- }
-
- /*
- * new functions for vertex array handling
- */
- static final int POLYGON_BUFFER_SIZE = 120000;
- static final int POLYGON_STRIDE = 7;
- static final int POLYGON_BYTE_STRIDE = POLYGON_STRIDE * BufferUtils.SIZEOF_FLOAT;
-
- static FloatBuffer globalPolygonInterleavedBuf = BufferUtils.newFloatBuffer(POLYGON_BUFFER_SIZE * 7);
- static FloatBuffer globalPolygonTexCoord1Buf = null;
-
- static {
- globalPolygonInterleavedBuf.position(POLYGON_STRIDE - 2);
- globalPolygonTexCoord1Buf = globalPolygonInterleavedBuf.slice();
- globalPolygonInterleavedBuf.position(0);
- };
-
- void precompilePolygon(glpoly_t p) {
-
- p.pos = globalPolygonInterleavedBuf.position() / POLYGON_STRIDE;
-
- float[] v;
- FloatBuffer buffer = globalPolygonInterleavedBuf;
-
- for (int i = 0; i < p.verts.length; i++) {
- v = p.verts[i];
- // textureCoord0
- buffer.put(v[3]);
- buffer.put(v[4]);
-
- // vertex
- buffer.put(v[0]);
- buffer.put(v[1]);
- buffer.put(v[2]);
-
- // textureCoord1
- buffer.put(v[5]);
- buffer.put(v[6]);
- }
- }
-
- public static void resetPolygonArrays() {
- globalPolygonInterleavedBuf.rewind();
- }
-
- //ImageFrame frame;
-
-// void debugLightmap(byte[] buf, int w, int h, float scale) {
-// IntBuffer pix = ByteBuffer.wrap(buf).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
-//
-// int[] pixel = new int[w * h];
-//
-// pix.get(pixel);
-//
-// BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_4BYTE_ABGR);
-// image.setRGB(0, 0, w, h, pixel, 0, w);
-// AffineTransformOp op = new AffineTransformOp(AffineTransform.getScaleInstance(scale, scale), AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
-// BufferedImage tmp = op.filter(image, null);
-//
-// if (frame == null) {
-// frame = new ImageFrame(null);
-// frame.show();
-// }
-// frame.showImage(tmp);
-//
-// }
-
-}
+ // 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
+ //byte[] lightmap_buffer = new byte[4 * BLOCK_WIDTH * BLOCK_HEIGHT];
+ 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();
+
+ // 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.glDrawArrays(GL.GL_POLYGON, p.pos, p.numverts);
+ }
+
+ // ============
+ // PGM
+ /*
+ * ================ DrawGLFlowingPoly -- version of DrawGLPoly that handles
+ * scrolling texture ================
+ */
+ void DrawGLFlowingPoly(glpoly_t p) {
+ int i;
+ float scroll;
+
+ scroll = -64
+ * ((r_newrefdef.time / 40.0f) - (int) (r_newrefdef.time / 40.0f));
+ if (scroll == 0.0f)
+ scroll = -64.0f;
+
+ FloatBuffer texCoord = globalPolygonInterleavedBuf;
+ float[][] v = p.verts;
+ int index = p.pos * POLYGON_STRIDE;
+ for (i = 0; i < p.numverts; i++) {
+ texCoord.put(index, v[i][3] + scroll);
+ index += POLYGON_STRIDE;
+ }
+ gl.glDrawArrays(GL.GL_POLYGON, p.pos, p.numverts);
+ }
+
+ // PGM
+ // ============
+
+ /*
+ * * R_DrawTriangleOutlines
+ */
+ void R_DrawTriangleOutlines() {
+ int i, j;
+ glpoly_t p;
+
+ 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 (i = 0; i < MAX_LIGHTMAPS; i++) {
+ msurface_t surf;
+
+ for (surf = gl_lms.lightmap_surfaces[i]; surf != null; surf = surf.lightmapchain) {
+ p = surf.polys;
+ for (; p != null; p = p.chain) {
+ for (j = 2; j < p.numverts; j++) {
+ gl.glBegin(GL.GL_LINE_STRIP);
+ gl.glVertex3fv(p.verts[0]);
+ gl.glVertex3fv(p.verts[j - 1]);
+ gl.glVertex3fv(p.verts[j]);
+ gl.glVertex3fv(p.verts[0]);
+ gl.glEnd();
+ }
+ }
+ }
+ }
+
+ gl.glEnable(GL.GL_DEPTH_TEST);
+ gl.glEnable(GL.GL_TEXTURE_2D);
+ }
+
+ 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.polys);
+ 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;
+ float intens;
+
+ //
+ // go back to the world matrix
+ //
+ gl.glLoadMatrixf(r_world_matrix);
+
+ gl.glEnable(GL.GL_BLEND);
+ GL_TexEnv(GL.GL_MODULATE);
+
+ // the textures are prescaled up for a better lighting range,
+ // so scale it back down
+ intens = gl_state.inverse_intensity;
+
+ gl.glInterleavedArrays(GL.GL_T2F_V3F, POLYGON_BYTE_STRIDE,
+ globalPolygonInterleavedBuf);
+
+ for (s = r_alpha_surfaces; s != null; s = s.texturechain) {
+ GL_Bind(s.texinfo.image.texnum);
+ c_brush_polys++;
+ if ((s.texinfo.flags & Defines.SURF_TRANS33) != 0)
+ gl.glColor4f(intens, intens, intens, 0.33f);
+ else if ((s.texinfo.flags & Defines.SURF_TRANS66) != 0)
+ gl.glColor4f(intens, intens, intens, 0.66f);
+ else
+ gl.glColor4f(intens, intens, intens, 1);
+ if ((s.flags & Defines.SURF_DRAWTURB) != 0)
+ EmitWaterPolys(s);
+ else if ((s.texinfo.flags & Defines.SURF_FLOWING) != 0) // PGM
+ // 9/16/98
+ DrawGLFlowingPoly(s.polys); // PGM
+ else
+ DrawGLPoly(s.polys);
+ }
+
+ GL_TexEnv(GL.GL_REPLACE);
+ gl.glColor4f(1, 1, 1, 1);
+ gl.glDisable(GL.GL_BLEND);
+
+ r_alpha_surfaces = null;
+ }
+
+ /*
+ * ================ DrawTextureChains ================
+ */
+ void DrawTextureChains() {
+ int i;
+ msurface_t s;
+ image_t image;
+
+ c_visible_textures = 0;
+
+ for (i = 0; i < numgltextures; i++) {
+ image = gltextures[i];
+
+ if (image.registration_sequence == 0)
+ continue;
+ if (image.texturechain == null)
+ continue;
+ c_visible_textures++;
+
+ for (s = image.texturechain; s != null; s = s.texturechain) {
+ if ((s.flags & Defines.SURF_DRAWTURB) == 0)
+ R_RenderBrushPoly(s);
+ }
+ }
+
+ GL_EnableMultitexture(false);
+ for (i = 0; i < numgltextures; i++) {
+ image = gltextures[i];
+
+ if (image.registration_sequence == 0)
+ continue;
+ s = image.texturechain;
+ if (s == null)
+ continue;
+
+ for (; s != null; s = s.texturechain) {
+ if ((s.flags & Defines.SURF_DRAWTURB) != 0)
+ R_RenderBrushPoly(s);
+ }
+
+ image.texturechain = null;
+ }
+
+ GL_TexEnv(GL.GL_REPLACE);
+ }
+
+ // direct buffer
+ private IntBuffer temp = Lib.newIntBuffer(128 * 128,
+ ByteOrder.LITTLE_ENDIAN);
+
+ void GL_RenderLightmappedPoly(msurface_t surf) {
+ int i, nv = surf.polys.numverts;
+ int map = 0;
+ int index;
+ float[][] v;
+ FloatBuffer texCoord = globalPolygonInterleavedBuf;
+ image_t image = R_TextureAnimation(surf.texinfo);
+ boolean is_dynamic = false;
+ int lmtex = surf.lightmaptexturenum;
+ glpoly_t p;
+
+ // ersetzt goto
+ boolean gotoDynamic = false;
+
+ for (map = 0; map < Defines.MAXLIGHTMAPS
+ && (surf.styles[map] != (byte) 255); map++) {
+ if (r_newrefdef.lightstyles[surf.styles[map] & 0xFF].white != surf.cached_light[map]) {
+ gotoDynamic = true;
+ break;
+ }
+ }
+
+ // this is a hack from cwei
+ if (map == 4)
+ map--;
+
+ // dynamic this frame or dynamic previously
+ if (gotoDynamic || (surf.dlightframe == r_framecount)) {
+ // label dynamic:
+ if (gl_dynamic.value != 0) {
+ if ((surf.texinfo.flags & (Defines.SURF_SKY
+ | Defines.SURF_TRANS33 | Defines.SURF_TRANS66 | Defines.SURF_WARP)) == 0) {
+ is_dynamic = true;
+ }
+ }
+ }
+
+ if (is_dynamic) {
+ // ist raus gezogen worden int[] temp = new int[128*128];
+ int smax, tmax;
+
+ if (((surf.styles[map] & 0xFF) >= 32 || surf.styles[map] == 0)
+ && (surf.dlightframe != r_framecount)) {
+ smax = (surf.extents[0] >> 4) + 1;
+ tmax = (surf.extents[1] >> 4) + 1;
+
+ R_BuildLightMap(surf, temp, smax);
+ R_SetCacheState(surf);
+
+ GL_MBind(GL_TEXTURE1, gl_state.lightmap_textures
+ + surf.lightmaptexturenum);
+
+ lmtex = surf.lightmaptexturenum;
+
+ gl.glTexSubImage2D(GL.GL_TEXTURE_2D, 0, surf.light_s,
+ surf.light_t, smax, tmax, GL_LIGHTMAP_FORMAT,
+ GL.GL_UNSIGNED_BYTE, temp);
+
+ } else {
+ smax = (surf.extents[0] >> 4) + 1;
+ tmax = (surf.extents[1] >> 4) + 1;
+
+ R_BuildLightMap(surf, temp, smax);
+
+ GL_MBind(GL_TEXTURE1, gl_state.lightmap_textures + 0);
+
+ lmtex = 0;
+
+ gl.glTexSubImage2D(GL.GL_TEXTURE_2D, 0, surf.light_s,
+ surf.light_t, smax, tmax, GL_LIGHTMAP_FORMAT,
+ GL.GL_UNSIGNED_BYTE, temp);
+
+ }
+
+ c_brush_polys++;
+
+ GL_MBind(GL_TEXTURE0, image.texnum);
+ GL_MBind(GL_TEXTURE1, gl_state.lightmap_textures + lmtex);
+
+ // ==========
+ // PGM
+ if ((surf.texinfo.flags & Defines.SURF_FLOWING) != 0) {
+ float scroll;
+
+ scroll = -64
+ * ((r_newrefdef.time / 40.0f) - (int) (r_newrefdef.time / 40.0f));
+ if (scroll == 0.0f)
+ scroll = -64.0f;
+
+ for (p = surf.polys; p != null; p = p.chain) {
+ v = p.verts;
+ index = p.pos * POLYGON_STRIDE;
+ for (i = 0; i < p.numverts; i++) {
+ texCoord.put(index, v[i][3] + scroll);
+ index += POLYGON_STRIDE;
+ }
+ gl.glDrawArrays(GL.GL_POLYGON, p.pos, p.numverts);
+ }
+ } else {
+ for (p = surf.polys; p != null; p = p.chain) {
+ gl.glDrawArrays(GL.GL_POLYGON, p.pos, p.numverts);
+ }
+ }
+ // PGM
+ // ==========
+ } else {
+ c_brush_polys++;
+
+ GL_MBind(GL_TEXTURE0, image.texnum);
+ GL_MBind(GL_TEXTURE1, gl_state.lightmap_textures + lmtex);
+
+ // ==========
+ // PGM
+ if ((surf.texinfo.flags & Defines.SURF_FLOWING) != 0) {
+ float scroll;
+
+ scroll = -64
+ * ((r_newrefdef.time / 40.0f) - (int) (r_newrefdef.time / 40.0f));
+ if (scroll == 0.0)
+ scroll = -64.0f;
+
+ for (p = surf.polys; p != null; p = p.chain) {
+ v = p.verts;
+ index = p.pos * POLYGON_STRIDE;
+ for (i = 0; i < p.numverts; i++) {
+ texCoord.put(index, v[i][3] + scroll);
+ index += POLYGON_STRIDE;
+ }
+ gl.glDrawArrays(GL.GL_POLYGON, p.pos, p.numverts);
+ }
+ } else {
+ // PGM
+ // ==========
+ for (p = surf.polys; p != null; p = p.chain) {
+ gl.glDrawArrays(GL.GL_POLYGON, p.pos, p.numverts);
+ }
+
+ // ==========
+ // PGM
+ }
+ // PGM
+ // ==========
+ }
+ }
+
+ /*
+ * ================= R_DrawInlineBModel =================
+ */
+ void R_DrawInlineBModel() {
+ int i, k;
+ cplane_t pplane;
+ float dot;
+ msurface_t psurf;
+ dlight_t lt;
+
+ // calculate dynamic lighting for bmodel
+ if (gl_flashblend.value == 0) {
+ for (k = 0; k < r_newrefdef.num_dlights; k++) {
+ lt = r_newrefdef.dlights[k];
+ R_MarkLights(lt, 1 << k,
+ currentmodel.nodes[currentmodel.firstnode]);
+ }
+ }
+
+ // psurf = &currentmodel->surfaces[currentmodel->firstmodelsurface];
+ int psurfp = currentmodel.firstmodelsurface;
+ msurface_t[] surfaces;
+ surfaces = currentmodel.surfaces;
+ //psurf = surfaces[psurfp];
+
+ if ((currententity.flags & Defines.RF_TRANSLUCENT) != 0) {
+ gl.glEnable(GL.GL_BLEND);
+ gl.glColor4f(1, 1, 1, 0.25f);
+ GL_TexEnv(GL.GL_MODULATE);
+ }
+
+ //
+ // draw texture
+ //
+ for (i = 0; i < currentmodel.nummodelsurfaces; i++) {
+ psurf = surfaces[psurfp++];
+ // find which side of the node we are on
+ pplane = psurf.plane;
+
+ dot = Math3D.DotProduct(modelorg, pplane.normal) - pplane.dist;
+
+ // draw the polygon
+ if (((psurf.flags & Defines.SURF_PLANEBACK) != 0 && (dot < -BACKFACE_EPSILON))
+ || ((psurf.flags & Defines.SURF_PLANEBACK) == 0 && (dot > BACKFACE_EPSILON))) {
+ if ((psurf.texinfo.flags & (Defines.SURF_TRANS33 | Defines.SURF_TRANS66)) != 0) {
+ // add to the translucent chain
+ psurf.texturechain = r_alpha_surfaces;
+ r_alpha_surfaces = psurf;
+ } else if ((psurf.flags & Defines.SURF_DRAWTURB) == 0) {
+ GL_RenderLightmappedPoly(psurf);
+ } else {
+ GL_EnableMultitexture(false);
+ R_RenderBrushPoly(psurf);
+ GL_EnableMultitexture(true);
+ }
+ }
+ }
+
+ if ((currententity.flags & Defines.RF_TRANSLUCENT) != 0) {
+ gl.glDisable(GL.GL_BLEND);
+ gl.glColor4f(1, 1, 1, 1);
+ GL_TexEnv(GL.GL_REPLACE);
+ }
+ }
+
+ /*
+ * ================= R_DrawBrushModel =================
+ */
+ void R_DrawBrushModel(entity_t e) {
+ float[] mins = { 0, 0, 0 };
+ float[] maxs = { 0, 0, 0 };
+ int i;
+ boolean rotated;
+
+ if (currentmodel.nummodelsurfaces == 0)
+ return;
+
+ currententity = e;
+ gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1;
+
+ if (e.angles[0] != 0 || e.angles[1] != 0 || e.angles[2] != 0) {
+ rotated = true;
+ for (i = 0; i < 3; i++) {
+ mins[i] = e.origin[i] - currentmodel.radius;
+ maxs[i] = e.origin[i] + currentmodel.radius;
+ }
+ } else {
+ rotated = false;
+ Math3D.VectorAdd(e.origin, currentmodel.mins, mins);
+ Math3D.VectorAdd(e.origin, currentmodel.maxs, maxs);
+ }
+
+ if (R_CullBox(mins, maxs))
+ return;
+
+ gl.glColor3f(1, 1, 1);
+
+ // memset (gl_lms.lightmap_surfaces, 0,
+ // sizeof(gl_lms.lightmap_surfaces));
+
+ // TODO wird beim multitexturing nicht gebraucht
+ //gl_lms.clearLightmapSurfaces();
+
+ Math3D.VectorSubtract(r_newrefdef.vieworg, e.origin, modelorg);
+ if (rotated) {
+ float[] temp = { 0, 0, 0 };
+ float[] forward = { 0, 0, 0 };
+ float[] right = { 0, 0, 0 };
+ float[] up = { 0, 0, 0 };
+
+ Math3D.VectorCopy(modelorg, temp);
+ Math3D.AngleVectors(e.angles, forward, right, up);
+ modelorg[0] = Math3D.DotProduct(temp, forward);
+ modelorg[1] = -Math3D.DotProduct(temp, right);
+ modelorg[2] = Math3D.DotProduct(temp, up);
+ }
+
+ gl.glPushMatrix();
+
+ e.angles[0] = -e.angles[0]; // stupid quake bug
+ e.angles[2] = -e.angles[2]; // stupid quake bug
+ R_RotateForEntity(e);
+ e.angles[0] = -e.angles[0]; // stupid quake bug
+ e.angles[2] = -e.angles[2]; // stupid quake bug
+
+ GL_EnableMultitexture(true);
+ GL_SelectTexture(GL_TEXTURE0);
+ GL_TexEnv(GL.GL_REPLACE);
+ gl.glInterleavedArrays(GL.GL_T2F_V3F, POLYGON_BYTE_STRIDE,
+ globalPolygonInterleavedBuf);
+ GL_SelectTexture(GL_TEXTURE1);
+ GL_TexEnv(GL.GL_MODULATE);
+ gl.glTexCoordPointer(2, GL.GL_FLOAT, POLYGON_BYTE_STRIDE,
+ globalPolygonTexCoord1Buf);
+ gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);
+
+ R_DrawInlineBModel();
+
+ gl.glClientActiveTextureARB(GL_TEXTURE1);
+ gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY);
+
+ GL_EnableMultitexture(false);
+
+ gl.glPopMatrix();
+ }
+
+ /*
+ * =============================================================
+ *
+ * WORLD MODEL
+ *
+ * =============================================================
+ */
+
+ /*
+ * ================ R_RecursiveWorldNode ================
+ */
+ void R_RecursiveWorldNode(mnode_t node) {
+ int c, side, sidebit;
+ cplane_t plane;
+ msurface_t surf;
+ msurface_t mark;
+ mleaf_t pleaf;
+ float dot = 0;
+ image_t image;
+
+ if (node.contents == Defines.CONTENTS_SOLID)
+ return; // solid
+
+ if (node.visframe != r_visframecount)
+ return;
+
+ if (R_CullBox(node.mins, node.maxs))
+ return;
+
+ // if a leaf node, draw stuff
+ if (node.contents != -1) {
+ pleaf = (mleaf_t) node;
+
+ // check for door connected areas
+ if (r_newrefdef.areabits != null) {
+ if (((r_newrefdef.areabits[pleaf.area >> 3] & 0xFF) & (1 << (pleaf.area & 7))) == 0)
+ return; // not visible
+ }
+
+ int markp = 0;
+
+ mark = pleaf.getMarkSurface(markp); // first marked surface
+ c = pleaf.nummarksurfaces;
+
+ if (c != 0) {
+ do {
+ mark.visframe = r_framecount;
+ mark = pleaf.getMarkSurface(++markp); // next surface
+ } while (--c != 0);
+ }
+
+ return;
+ }
+
+ // node is just a decision point, so go down the apropriate sides
+
+ // find which side of the node we are on
+ plane = node.plane;
+
+ switch (plane.type) {
+ case Defines.PLANE_X:
+ dot = modelorg[0] - plane.dist;
+ break;
+ case Defines.PLANE_Y:
+ dot = modelorg[1] - plane.dist;
+ break;
+ case Defines.PLANE_Z:
+ dot = modelorg[2] - plane.dist;
+ break;
+ default:
+ dot = Math3D.DotProduct(modelorg, plane.normal) - plane.dist;
+ break;
+ }
+
+ if (dot >= 0.0f) {
+ side = 0;
+ sidebit = 0;
+ } else {
+ side = 1;
+ sidebit = Defines.SURF_PLANEBACK;
+ }
+
+ // recurse down the children, front side first
+ R_RecursiveWorldNode(node.children[side]);
+
+ // draw stuff
+ //for ( c = node.numsurfaces, surf =
+ // r_worldmodel.surfaces[node.firstsurface]; c != 0 ; c--, surf++)
+ for (c = 0; c < node.numsurfaces; c++) {
+ surf = r_worldmodel.surfaces[node.firstsurface + c];
+ if (surf.visframe != r_framecount)
+ continue;
+
+ if ((surf.flags & Defines.SURF_PLANEBACK) != sidebit)
+ continue; // wrong side
+
+ if ((surf.texinfo.flags & Defines.SURF_SKY) != 0) { // just adds to
+ // visible sky
+ // bounds
+ R_AddSkySurface(surf);
+ } else if ((surf.texinfo.flags & (Defines.SURF_TRANS33 | Defines.SURF_TRANS66)) != 0) {
+ // add to the translucent chain
+ surf.texturechain = r_alpha_surfaces;
+ r_alpha_surfaces = surf;
+ } else {
+ if ((surf.flags & Defines.SURF_DRAWTURB) == 0) {
+ GL_RenderLightmappedPoly(surf);
+ } else {
+ // the polygon is visible, so add it to the texture
+ // sorted chain
+ // FIXME: this is a hack for animation
+ image = R_TextureAnimation(surf.texinfo);
+ surf.texturechain = image.texturechain;
+ image.texturechain = surf;
+ }
+ }
+ }
+
+ // recurse down the back side
+ R_RecursiveWorldNode(node.children[1 - side]);
+ }
+
+ /*
+ * ============= R_DrawWorld =============
+ */
+ void R_DrawWorld() {
+ entity_t ent = new entity_t();
+ // auto cycle the world frame for texture animation
+ ent.frame = (int) (r_newrefdef.time * 2);
+ currententity = ent;
+
+ if (r_drawworld.value == 0)
+ return;
+
+ if ((r_newrefdef.rdflags & Defines.RDF_NOWORLDMODEL) != 0)
+ return;
+
+ currentmodel = r_worldmodel;
+
+ Math3D.VectorCopy(r_newrefdef.vieworg, modelorg);
+
+ gl_state.currenttextures[0] = gl_state.currenttextures[1] = -1;
+
+ gl.glColor3f(1, 1, 1);
+ // memset (gl_lms.lightmap_surfaces, 0,
+ // sizeof(gl_lms.lightmap_surfaces));
+ // TODO wird bei multitexture nicht gebraucht
+ //gl_lms.clearLightmapSurfaces();
+
+ R_ClearSkyBox();
+
+ GL_EnableMultitexture(true);
+
+ GL_SelectTexture(GL_TEXTURE0);
+ GL_TexEnv(GL.GL_REPLACE);
+ gl.glInterleavedArrays(GL.GL_T2F_V3F, POLYGON_BYTE_STRIDE,
+ globalPolygonInterleavedBuf);
+ GL_SelectTexture(GL_TEXTURE1);
+ gl.glTexCoordPointer(2, GL.GL_FLOAT, POLYGON_BYTE_STRIDE,
+ globalPolygonTexCoord1Buf);
+ gl.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY);
+
+ if (gl_lightmap.value != 0)
+ GL_TexEnv(GL.GL_REPLACE);
+ else
+ GL_TexEnv(GL.GL_MODULATE);
+
+ R_RecursiveWorldNode(r_worldmodel.nodes[0]); // root node
+
+ gl.glClientActiveTextureARB(GL_TEXTURE1);
+ gl.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY);
+
+ GL_EnableMultitexture(false);
+
+ DrawTextureChains();
+ R_DrawSkyBox();
+ R_DrawTriangleOutlines();
+ }
+
+ byte[] fatvis = new byte[Defines.MAX_MAP_LEAFS / 8];
+
+ /*
+ * =============== R_MarkLeaves
+ *
+ * Mark the leaves and nodes that are in the PVS for the current cluster
+ * ===============
+ */
+ void R_MarkLeaves() {
+ //byte[] vis;
+ //byte[] fatvis = new byte[Defines.MAX_MAP_LEAFS / 8];
+
+ //Arrays.fill(fatvis, (byte)0);
+
+ mnode_t node;
+ int i, c;
+ mleaf_t leaf;
+ int cluster;
+
+ if (r_oldviewcluster == r_viewcluster
+ && r_oldviewcluster2 == r_viewcluster2 && r_novis.value == 0
+ && r_viewcluster != -1)
+ return;
+
+ // development aid to let you run around and see exactly where
+ // the pvs ends
+ if (gl_lockpvs.value != 0)
+ return;
+
+ r_visframecount++;
+ r_oldviewcluster = r_viewcluster;
+ r_oldviewcluster2 = r_viewcluster2;
+
+ if (r_novis.value != 0 || r_viewcluster == -1
+ || r_worldmodel.vis == null) {
+ // mark everything
+ for (i = 0; i < r_worldmodel.numleafs; i++)
+ r_worldmodel.leafs[i].visframe = r_visframecount;
+ for (i = 0; i < r_worldmodel.numnodes; i++)
+ r_worldmodel.nodes[i].visframe = r_visframecount;
+ return;
+ }
+
+ byte[] vis = Mod_ClusterPVS(r_viewcluster, r_worldmodel);
+ // may have to combine two clusters because of solid water boundaries
+ if (r_viewcluster2 != r_viewcluster) {
+ // memcpy (fatvis, vis, (r_worldmodel.numleafs+7)/8);
+ System
+ .arraycopy(vis, 0, fatvis, 0,
+ (r_worldmodel.numleafs + 7) / 8);
+ vis = Mod_ClusterPVS(r_viewcluster2, r_worldmodel);
+ c = (r_worldmodel.numleafs + 31) / 32;
+ int k = 0;
+ for (i = 0; i < c; i++) {
+ fatvis[k] |= vis[k++];
+ fatvis[k] |= vis[k++];
+ fatvis[k] |= vis[k++];
+ fatvis[k] |= vis[k++];
+ }
+
+ vis = fatvis;
+ }
+
+ for (i = 0; i < r_worldmodel.numleafs; i++) {
+ leaf = r_worldmodel.leafs[i];
+ cluster = leaf.cluster;
+ if (cluster == -1)
+ continue;
+ if (((vis[cluster >> 3] & 0xFF) & (1 << (cluster & 7))) != 0) {
+ node = (mnode_t) leaf;
+ do {
+ if (node.visframe == r_visframecount)
+ break;
+ node.visframe = r_visframecount;
+ node = node.parent;
+ } while (node != null);
+ }
+ }
+ }
+
+ /*
+ * =============================================================================
+ *
+ * LIGHTMAP ALLOCATION
+ *
+ * =============================================================================
+ */
+
+ void LM_InitBlock() {
+ Arrays.fill(gl_lms.allocated, 0);
+ }
+
+ void LM_UploadBlock(boolean dynamic) {
+ int texture;
+ int height = 0;
+
+ if (dynamic) {
+ texture = 0;
+ } else {
+ texture = gl_lms.current_lightmap_texture;
+ }
+
+ GL_Bind(gl_state.lightmap_textures + texture);
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER,
+ GL.GL_LINEAR);
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER,
+ GL.GL_LINEAR);
+
+ if (dynamic) {
+ int i;
+
+ for (i = 0; i < BLOCK_WIDTH; i++) {
+ if (gl_lms.allocated[i] > height)
+ height = gl_lms.allocated[i];
+ }
+
+ gl.glTexSubImage2D(GL.GL_TEXTURE_2D, 0, 0, 0, BLOCK_WIDTH, height,
+ GL_LIGHTMAP_FORMAT, GL.GL_UNSIGNED_BYTE,
+ gl_lms.lightmap_buffer);
+ } else {
+ gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, gl_lms.internal_format,
+ BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_LIGHTMAP_FORMAT,
+ GL.GL_UNSIGNED_BYTE, gl_lms.lightmap_buffer);
+ if (++gl_lms.current_lightmap_texture == MAX_LIGHTMAPS)
+ Com.Error(Defines.ERR_DROP,
+ "LM_UploadBlock() - MAX_LIGHTMAPS exceeded\n");
+
+ //debugLightmap(gl_lms.lightmap_buffer, 128, 128, 4);
+
+ }
+ }
+
+ // returns a texture number and the position inside it
+ boolean LM_AllocBlock(int w, int h, pos_t pos) {
+ int x = pos.x;
+ int y = pos.y;
+ int i, j;
+ int best, best2;
+
+ best = BLOCK_HEIGHT;
+
+ for (i = 0; i < BLOCK_WIDTH - w; i++) {
+ best2 = 0;
+
+ for (j = 0; j < w; j++) {
+ if (gl_lms.allocated[i + j] >= best)
+ break;
+ if (gl_lms.allocated[i + j] > best2)
+ best2 = gl_lms.allocated[i + j];
+ }
+ if (j == w) { // this is a valid spot
+ pos.x = x = i;
+ pos.y = y = best = best2;
+ }
+ }
+
+ if (best + h > BLOCK_HEIGHT)
+ return false;
+
+ for (i = 0; i < w; i++)
+ gl_lms.allocated[x + i] = best + h;
+
+ return true;
+ }
+
+ /*
+ * ================ GL_BuildPolygonFromSurface ================
+ */
+ void GL_BuildPolygonFromSurface(msurface_t fa) {
+ int i, lindex, lnumverts;
+ medge_t[] pedges;
+ medge_t r_pedge;
+ int vertpage;
+ float[] vec;
+ float s, t;
+ glpoly_t poly;
+ float[] total = { 0, 0, 0 };
+
+ // reconstruct the polygon
+ pedges = currentmodel.edges;
+ lnumverts = fa.numedges;
+ vertpage = 0;
+
+ Math3D.VectorClear(total);
+ //
+ // draw texture
+ //
+ // poly = Hunk_Alloc (sizeof(glpoly_t) + (lnumverts-4) *
+ // VERTEXSIZE*sizeof(float));
+ poly = new glpoly_t(lnumverts);
+
+ poly.next = fa.polys;
+ poly.flags = fa.flags;
+ fa.polys = poly;
+ poly.numverts = lnumverts;
+
+ for (i = 0; i < lnumverts; i++) {
+ lindex = currentmodel.surfedges[fa.firstedge + i];
+
+ if (lindex > 0) {
+ r_pedge = pedges[lindex];
+ vec = currentmodel.vertexes[r_pedge.v[0]].position;
+ } else {
+ r_pedge = pedges[-lindex];
+ vec = currentmodel.vertexes[r_pedge.v[1]].position;
+ }
+ s = Math3D.DotProduct(vec, fa.texinfo.vecs[0])
+ + fa.texinfo.vecs[0][3];
+ s /= fa.texinfo.image.width;
+
+ t = Math3D.DotProduct(vec, fa.texinfo.vecs[1])
+ + fa.texinfo.vecs[1][3];
+ t /= fa.texinfo.image.height;
+
+ Math3D.VectorAdd(total, vec, total);
+ Math3D.VectorCopy(vec, poly.verts[i]);
+ poly.verts[i][3] = s;
+ poly.verts[i][4] = t;
+
+ //
+ // lightmap texture coordinates
+ //
+ s = Math3D.DotProduct(vec, fa.texinfo.vecs[0])
+ + fa.texinfo.vecs[0][3];
+ s -= fa.texturemins[0];
+ s += fa.light_s * 16;
+ s += 8;
+ s /= BLOCK_WIDTH * 16; //fa.texinfo.texture.width;
+
+ t = Math3D.DotProduct(vec, fa.texinfo.vecs[1])
+ + fa.texinfo.vecs[1][3];
+ t -= fa.texturemins[1];
+ t += fa.light_t * 16;
+ t += 8;
+ t /= BLOCK_HEIGHT * 16; //fa.texinfo.texture.height;
+
+ poly.verts[i][5] = s;
+ poly.verts[i][6] = t;
+ }
+
+ poly.numverts = lnumverts;
+
+ precompilePolygon(poly);
+
+ }
+
+ /*
+ * ======================== GL_CreateSurfaceLightmap
+ * ========================
+ */
+ void GL_CreateSurfaceLightmap(msurface_t surf) {
+ int smax, tmax;
+ IntBuffer base;
+
+ if ((surf.flags & (Defines.SURF_DRAWSKY | Defines.SURF_DRAWTURB)) != 0)
+ return;
+
+ smax = (surf.extents[0] >> 4) + 1;
+ tmax = (surf.extents[1] >> 4) + 1;
+
+ pos_t lightPos = new pos_t(surf.light_s, surf.light_t);
+
+ if (!LM_AllocBlock(smax, tmax, lightPos)) {
+ LM_UploadBlock(false);
+ LM_InitBlock();
+ lightPos = new pos_t(surf.light_s, surf.light_t);
+ if (!LM_AllocBlock(smax, tmax, lightPos)) {
+ Com.Error(Defines.ERR_FATAL,
+ "Consecutive calls to LM_AllocBlock(" + smax + ","
+ + tmax + ") failed\n");
+ }
+ }
+
+ // kopiere die koordinaten zurueck
+ surf.light_s = lightPos.x;
+ surf.light_t = lightPos.y;
+
+ surf.lightmaptexturenum = gl_lms.current_lightmap_texture;
+
+ base = gl_lms.lightmap_buffer;
+ base.position(surf.light_t * BLOCK_WIDTH + surf.light_s);
+
+ R_SetCacheState(surf);
+ R_BuildLightMap(surf, base.slice(), BLOCK_WIDTH);
+ }
+
+ lightstyle_t[] lightstyles;
+
+ IntBuffer dummy = BufferUtils.newIntBuffer(128 * 128);
+
+ /*
+ * ================== GL_BeginBuildingLightmaps
+ *
+ * ==================
+ */
+ void GL_BeginBuildingLightmaps(model_t m) {
+ // static lightstyle_t lightstyles[MAX_LIGHTSTYLES];
+ int i;
+
+ // init lightstyles
+ if (lightstyles == null) {
+ lightstyles = new lightstyle_t[Defines.MAX_LIGHTSTYLES];
+ for (i = 0; i < lightstyles.length; i++) {
+ lightstyles[i] = new lightstyle_t();
+ }
+ }
+
+ // memset( gl_lms.allocated, 0, sizeof(gl_lms.allocated) );
+ Arrays.fill(gl_lms.allocated, 0);
+
+ r_framecount = 1; // no dlightcache
+
+ GL_EnableMultitexture(true);
+ GL_SelectTexture(GL_TEXTURE1);
+
+ /*
+ * * setup the base lightstyles so the lightmaps won't have to be
+ * regenerated * the first time they're seen
+ */
+ for (i = 0; i < Defines.MAX_LIGHTSTYLES; i++) {
+ lightstyles[i].rgb[0] = 1;
+ lightstyles[i].rgb[1] = 1;
+ lightstyles[i].rgb[2] = 1;
+ lightstyles[i].white = 3;
+ }
+ r_newrefdef.lightstyles = lightstyles;
+
+ if (gl_state.lightmap_textures == 0) {
+ gl_state.lightmap_textures = TEXNUM_LIGHTMAPS;
+ }
+
+ gl_lms.current_lightmap_texture = 1;
+
+ /*
+ * * if mono lightmaps are enabled and we want to use alpha * blending
+ * (a,1-a) then we're likely running on a 3DLabs * Permedia2. In a
+ * perfect world we'd use a GL_ALPHA lightmap * in order to conserve
+ * space and maximize bandwidth, however * this isn't a perfect world. * *
+ * So we have to use alpha lightmaps, but stored in GL_RGBA format, *
+ * which means we only get 1/16th the color resolution we should when *
+ * using alpha lightmaps. If we find another board that supports * only
+ * alpha lightmaps but that can at least support the GL_ALPHA * format
+ * then we should change this code to use real alpha maps.
+ */
+
+ char format = gl_monolightmap.string.toUpperCase().charAt(0);
+
+ if (format == 'A') {
+ gl_lms.internal_format = gl_tex_alpha_format;
+ }
+ /*
+ * * try to do hacked colored lighting with a blended texture
+ */
+ else if (format == 'C') {
+ gl_lms.internal_format = gl_tex_alpha_format;
+ } else if (format == 'I') {
+ gl_lms.internal_format = GL.GL_INTENSITY8;
+ } else if (format == 'L') {
+ gl_lms.internal_format = GL.GL_LUMINANCE8;
+ } else {
+ gl_lms.internal_format = gl_tex_solid_format;
+ }
+
+ /*
+ * * initialize the dynamic lightmap texture
+ */
+ GL_Bind(gl_state.lightmap_textures + 0);
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER,
+ GL.GL_LINEAR);
+ gl.glTexParameterf(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER,
+ GL.GL_LINEAR);
+ gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, gl_lms.internal_format,
+ BLOCK_WIDTH, BLOCK_HEIGHT, 0, GL_LIGHTMAP_FORMAT,
+ GL.GL_UNSIGNED_BYTE, dummy);
+ }
+
+ /*
+ * ======================= GL_EndBuildingLightmaps =======================
+ */
+ void GL_EndBuildingLightmaps() {
+ LM_UploadBlock(false);
+ GL_EnableMultitexture(false);
+ }
+
+ /*
+ * new functions for vertex array handling
+ */
+ static final int POLYGON_BUFFER_SIZE = 120000;
+
+ static final int POLYGON_STRIDE = 7;
+
+ static final int POLYGON_BYTE_STRIDE = POLYGON_STRIDE
+ * BufferUtils.SIZEOF_FLOAT;
+
+ static FloatBuffer globalPolygonInterleavedBuf = BufferUtils
+ .newFloatBuffer(POLYGON_BUFFER_SIZE * 7);
+
+ static FloatBuffer globalPolygonTexCoord1Buf = null;
+
+ static {
+ globalPolygonInterleavedBuf.position(POLYGON_STRIDE - 2);
+ globalPolygonTexCoord1Buf = globalPolygonInterleavedBuf.slice();
+ globalPolygonInterleavedBuf.position(0);
+ };
+
+ void precompilePolygon(glpoly_t p) {
+
+ p.pos = globalPolygonInterleavedBuf.position() / POLYGON_STRIDE;
+
+ float[] v;
+ FloatBuffer buffer = globalPolygonInterleavedBuf;
+
+ for (int i = 0; i < p.verts.length; i++) {
+ v = p.verts[i];
+ // textureCoord0
+ buffer.put(v[3]);
+ buffer.put(v[4]);
+
+ // vertex
+ buffer.put(v[0]);
+ buffer.put(v[1]);
+ buffer.put(v[2]);
+
+ // textureCoord1
+ buffer.put(v[5]);
+ buffer.put(v[6]);
+ }
+ }
+
+ public static void resetPolygonArrays() {
+ globalPolygonInterleavedBuf.rewind();
+ }
+
+ //ImageFrame frame;
+
+ // void debugLightmap(byte[] buf, int w, int h, float scale) {
+ // IntBuffer pix =
+ // ByteBuffer.wrap(buf).order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
+ //
+ // int[] pixel = new int[w * h];
+ //
+ // pix.get(pixel);
+ //
+ // BufferedImage image = new BufferedImage(w, h,
+ // BufferedImage.TYPE_4BYTE_ABGR);
+ // image.setRGB(0, 0, w, h, pixel, 0, w);
+ // AffineTransformOp op = new
+ // AffineTransformOp(AffineTransform.getScaleInstance(scale, scale),
+ // AffineTransformOp.TYPE_NEAREST_NEIGHBOR);
+ // BufferedImage tmp = op.filter(image, null);
+ //
+ // if (frame == null) {
+ // frame = new ImageFrame(null);
+ // frame.show();
+ // }
+ // frame.showImage(tmp);
+ //
+ // }
+
+} \ No newline at end of file