From: Carsten W. <ca...@us...> - 2006-11-21 00:50:49
|
Update of /cvsroot/jake2/jake2/src/jake2/render/basic In directory sc8-pr-cvs6.sourceforge.net:/tmp/cvs-serv15997/src/jake2/render/basic Added Files: Model.java Misc.java Warp.java Main.java Image.java Mesh.java Surf.java Draw.java Light.java Anorms.java Polygon.java Log Message: merge render-refactoring branch into the HEAD --- NEW FILE: Image.java --- /* * Image.java * Copyright (C) 2003 * * $Id: Image.java,v 1.2 2006/11/21 00:50:46 cawe Exp $ */ /* 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 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. [...1625 lines suppressed...] /* * =============== GL_ShutdownImages =============== */ void GL_ShutdownImages() { image_t image; for (int i = 0; i < numgltextures; i++) { image = gltextures[i]; if (image.registration_sequence == 0) continue; // free image_t slot // free it texnum.put(0, image.texnum); gl.glDeleteTextures(texnum); image.clear(); } } } --- NEW FILE: Surf.java --- /* * Surf.java * Copyright (C) 2003 * * $Id: Surf.java,v 1.2 2006/11/21 00:50:46 cawe Exp $ */ /* 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 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. [...1651 lines suppressed...] // 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); // // } } --- NEW FILE: Light.java --- /* * Light.java * Copyright (C) 2003 * * $Id: Light.java,v 1.2 2006/11/21 00:50:46 cawe Exp $ */ /* 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 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. 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.basic; import jake2.Defines; import jake2.Globals; import jake2.client.dlight_t; import jake2.client.lightstyle_t; import jake2.game.cplane_t; import jake2.qcommon.Com; import jake2.qcommon.longjmpException; import jake2.render.mnode_t; import jake2.render.msurface_t; import jake2.render.mtexinfo_t; import jake2.util.Math3D; import java.nio.ByteBuffer; import java.nio.IntBuffer; import java.util.Arrays; /** * Light * * @author cwei */ public abstract class Light extends Warp { // r_light.c int r_dlightframecount; static final int DLIGHT_CUTOFF = 64; /* * ============================================================================= * * DYNAMIC LIGHTS BLEND RENDERING * * ============================================================================= */ void R_RenderDlight(dlight_t light) { int i, j; float a; float[] v = { 0, 0, 0 }; float rad; rad = light.intensity * 0.35f; Math3D.VectorSubtract(light.origin, r_origin, v); gl.glBegin(GL_TRIANGLE_FAN); gl.glColor3f(light.color[0] * 0.2f, light.color[1] * 0.2f, light.color[2] * 0.2f); for (i = 0; i < 3; i++) v[i] = light.origin[i] - vpn[i] * rad; gl.glVertex3f(v[0], v[1], v[2]); gl.glColor3f(0, 0, 0); for (i = 16; i >= 0; i--) { a = (float) (i / 16.0f * Math.PI * 2); for (j = 0; j < 3; j++) v[j] = (float) (light.origin[j] + vright[j] * Math.cos(a) * rad + vup[j] * Math.sin(a) * rad); gl.glVertex3f(v[0], v[1], v[2]); } gl.glEnd(); } /* * ============= R_RenderDlights ============= */ void R_RenderDlights() { int i; dlight_t l; if (gl_flashblend.value == 0) return; r_dlightframecount = r_framecount + 1; // because the count hasn't // advanced yet for this frame gl.glDepthMask(false); gl.glDisable(GL_TEXTURE_2D); gl.glShadeModel(GL_SMOOTH); gl.glEnable(GL_BLEND); gl.glBlendFunc(GL_ONE, GL_ONE); for (i = 0; i < r_newrefdef.num_dlights; i++) { l = r_newrefdef.dlights[i]; R_RenderDlight(l); } gl.glColor3f(1, 1, 1); gl.glDisable(GL_BLEND); gl.glEnable(GL_TEXTURE_2D); gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); gl.glDepthMask(true); } /* * ============================================================================= * * DYNAMIC LIGHTS * * ============================================================================= */ /* * ============= R_MarkLights ============= */ void R_MarkLights(dlight_t light, int bit, mnode_t node) { cplane_t splitplane; float dist; msurface_t surf; int i; int sidebit; if (node.contents != -1) return; splitplane = node.plane; dist = Math3D.DotProduct(light.origin, splitplane.normal) - splitplane.dist; if (dist > light.intensity - DLIGHT_CUTOFF) { R_MarkLights(light, bit, node.children[0]); return; } if (dist < -light.intensity + DLIGHT_CUTOFF) { R_MarkLights(light, bit, node.children[1]); return; } // mark the polygons for (i = 0; i < node.numsurfaces; i++) { surf = r_worldmodel.surfaces[node.firstsurface + i]; /* * cwei bugfix for dlight behind the walls */ dist = Math3D.DotProduct(light.origin, surf.plane.normal) - surf.plane.dist; sidebit = (dist >= 0) ? 0 : Defines.SURF_PLANEBACK; if ((surf.flags & Defines.SURF_PLANEBACK) != sidebit) continue; /* * cwei bugfix end */ if (surf.dlightframe != r_dlightframecount) { surf.dlightbits = 0; surf.dlightframe = r_dlightframecount; } surf.dlightbits |= bit; } R_MarkLights(light, bit, node.children[0]); R_MarkLights(light, bit, node.children[1]); } /* * ============= R_PushDlights ============= */ void R_PushDlights() { int i; dlight_t l; if (gl_flashblend.value != 0) return; r_dlightframecount = r_framecount + 1; // because the count hasn't // advanced yet for this frame for (i = 0; i < r_newrefdef.num_dlights; i++) { l = r_newrefdef.dlights[i]; R_MarkLights(l, 1 << i, r_worldmodel.nodes[0]); } } /* * ============================================================================= * * LIGHT SAMPLING * * ============================================================================= */ float[] pointcolor = { 0, 0, 0 }; // vec3_t cplane_t lightplane; // used as shadow plane float[] lightspot = { 0, 0, 0 }; // vec3_t int RecursiveLightPoint(mnode_t node, float[] start, float[] end) { if (node.contents != -1) return -1; // didn't hit anything msurface_t surf; int s, t, ds, dt; int i; mtexinfo_t tex; ByteBuffer lightmap; int maps; float[] mid = { 0, 0, 0 }; // calculate mid point // FIXME: optimize for axial cplane_t plane = node.plane; float front = Math3D.DotProduct(start, plane.normal) - plane.dist; float back = Math3D.DotProduct(end, plane.normal) - plane.dist; boolean side = (front < 0); int sideIndex = (side) ? 1 : 0; if ((back < 0) == side) return RecursiveLightPoint(node.children[sideIndex], start, end); float frac = front / (front - back); mid[0] = start[0] + (end[0] - start[0]) * frac; mid[1] = start[1] + (end[1] - start[1]) * frac; mid[2] = start[2] + (end[2] - start[2]) * frac; // go down front side int r = RecursiveLightPoint(node.children[sideIndex], start, mid); if (r >= 0) return r; // hit something if ((back < 0) == side) return -1; // didn't hit anuthing // check for impact on this node Math3D.VectorCopy(mid, lightspot); lightplane = plane; int surfIndex = node.firstsurface; float[] scale = { 0, 0, 0 }; for (i = 0; i < node.numsurfaces; i++, surfIndex++) { surf = r_worldmodel.surfaces[surfIndex]; if ((surf.flags & (Defines.SURF_DRAWTURB | Defines.SURF_DRAWSKY)) != 0) continue; // no lightmaps tex = surf.texinfo; s = (int) (Math3D.DotProduct(mid, tex.vecs[0]) + tex.vecs[0][3]); t = (int) (Math3D.DotProduct(mid, tex.vecs[1]) + tex.vecs[1][3]); if (s < surf.texturemins[0] || t < surf.texturemins[1]) continue; ds = s - surf.texturemins[0]; dt = t - surf.texturemins[1]; if (ds > surf.extents[0] || dt > surf.extents[1]) continue; if (surf.samples == null) return 0; ds >>= 4; dt >>= 4; lightmap = surf.samples; int lightmapIndex = 0; Math3D.VectorCopy(Globals.vec3_origin, pointcolor); if (lightmap != null) { //float[] scale = {0, 0, 0}; float[] rgb; lightmapIndex += 3 * (dt * ((surf.extents[0] >> 4) + 1) + ds); for (maps = 0; maps < Defines.MAXLIGHTMAPS && surf.styles[maps] != (byte) 255; maps++) { rgb = r_newrefdef.lightstyles[surf.styles[maps] & 0xFF].rgb; scale[0] = gl_modulate.value * rgb[0]; scale[1] = gl_modulate.value * rgb[1]; scale[2] = gl_modulate.value * rgb[2]; pointcolor[0] += (lightmap.get(lightmapIndex + 0) & 0xFF) * scale[0] * (1.0f / 255); pointcolor[1] += (lightmap.get(lightmapIndex + 1) & 0xFF) * scale[1] * (1.0f / 255); pointcolor[2] += (lightmap.get(lightmapIndex + 2) & 0xFF) * scale[2] * (1.0f / 255); lightmapIndex += 3 * ((surf.extents[0] >> 4) + 1) * ((surf.extents[1] >> 4) + 1); } } return 1; } // go down back side return RecursiveLightPoint(node.children[1 - sideIndex], mid, end); } /* * =============== R_LightPoint =============== */ void R_LightPoint(float[] p, float[] color) { assert (p.length == 3) : "vec3_t bug"; assert (color.length == 3) : "rgb bug"; float[] end = { 0, 0, 0 }; dlight_t dl; float add; if (r_worldmodel.lightdata == null) { color[0] = color[1] = color[2] = 1.0f; return; } end[0] = p[0]; end[1] = p[1]; end[2] = p[2] - 2048; float r = RecursiveLightPoint(r_worldmodel.nodes[0], p, end); if (r == -1) { Math3D.VectorCopy(Globals.vec3_origin, color); } else { Math3D.VectorCopy(pointcolor, color); } // // add dynamic lights // for (int lnum = 0; lnum < r_newrefdef.num_dlights; lnum++) { dl = r_newrefdef.dlights[lnum]; Math3D.VectorSubtract(currententity.origin, dl.origin, end); add = dl.intensity - Math3D.VectorLength(end); add *= (1.0f / 256); if (add > 0) { Math3D.VectorMA(color, add, dl.color, color); } } Math3D.VectorScale(color, gl_modulate.value, color); } // =================================================================== float[] s_blocklights = new float[34 * 34 * 3]; /* * =============== R_AddDynamicLights =============== */ void R_AddDynamicLights(msurface_t surf) { int lnum; int sd, td; float fdist, frad, fminlight; float[] impact = { 0, 0, 0 }; float[] local = { 0, 0, 0 }; int s, t; int i; int smax, tmax; mtexinfo_t tex; dlight_t dl; float[] pfBL; float fsacc, ftacc; smax = (surf.extents[0] >> 4) + 1; tmax = (surf.extents[1] >> 4) + 1; tex = surf.texinfo; for (lnum = 0; lnum < r_newrefdef.num_dlights; lnum++) { if ((surf.dlightbits & (1 << lnum)) == 0) continue; // not lit by this light dl = r_newrefdef.dlights[lnum]; frad = dl.intensity; fdist = Math3D.DotProduct(dl.origin, surf.plane.normal) - surf.plane.dist; frad -= Math.abs(fdist); // rad is now the highest intensity on the plane fminlight = DLIGHT_CUTOFF; // FIXME: make configurable? if (frad < fminlight) continue; fminlight = frad - fminlight; for (i = 0; i < 3; i++) { impact[i] = dl.origin[i] - surf.plane.normal[i] * fdist; } local[0] = Math3D.DotProduct(impact, tex.vecs[0]) + tex.vecs[0][3] - surf.texturemins[0]; local[1] = Math3D.DotProduct(impact, tex.vecs[1]) + tex.vecs[1][3] - surf.texturemins[1]; pfBL = s_blocklights; int pfBLindex = 0; for (t = 0, ftacc = 0; t < tmax; t++, ftacc += 16) { td = (int) (local[1] - ftacc); if (td < 0) td = -td; for (s = 0, fsacc = 0; s < smax; s++, fsacc += 16, pfBLindex += 3) { sd = (int) (local[0] - fsacc); if (sd < 0) sd = -sd; if (sd > td) fdist = sd + (td >> 1); else fdist = td + (sd >> 1); if (fdist < fminlight) { pfBL[pfBLindex + 0] += (frad - fdist) * dl.color[0]; pfBL[pfBLindex + 1] += (frad - fdist) * dl.color[1]; pfBL[pfBLindex + 2] += (frad - fdist) * dl.color[2]; } } } } } /* * * R_SetCacheState */ void R_SetCacheState(msurface_t surf) { int maps; for (maps = 0; maps < Defines.MAXLIGHTMAPS && surf.styles[maps] != (byte) 255; maps++) { surf.cached_light[maps] = r_newrefdef.lightstyles[surf.styles[maps] & 0xFF].white; } } /* * =============== R_BuildLightMap * * Combine and scale multiple lightmaps into the floating format in * blocklights =============== */ void R_BuildLightMap(msurface_t surf, IntBuffer dest, int stride) { int smax, tmax; int r, g, b, a, max; int i, j, size; ByteBuffer lightmap; float[] scale = { 0, 0, 0, 0 }; int nummaps; float[] bl; lightstyle_t style; int monolightmap; if ((surf.texinfo.flags & (Defines.SURF_SKY | Defines.SURF_TRANS33 | Defines.SURF_TRANS66 | Defines.SURF_WARP)) != 0) Com.Error(Defines.ERR_DROP, "R_BuildLightMap called for non-lit surface"); smax = (surf.extents[0] >> 4) + 1; tmax = (surf.extents[1] >> 4) + 1; size = smax * tmax; if (size > ((s_blocklights.length * Defines.SIZE_OF_FLOAT) >> 4)) Com.Error(Defines.ERR_DROP, "Bad s_blocklights size"); try { // set to full bright if no light data if (surf.samples == null) { int maps; for (i = 0; i < size * 3; i++) s_blocklights[i] = 255; for (maps = 0; maps < Defines.MAXLIGHTMAPS && surf.styles[maps] != (byte) 255; maps++) { style = r_newrefdef.lightstyles[surf.styles[maps] & 0xFF]; } // goto store; throw new longjmpException(); } // count the # of maps for (nummaps = 0; nummaps < Defines.MAXLIGHTMAPS && surf.styles[nummaps] != (byte) 255; nummaps++) ; lightmap = surf.samples; int lightmapIndex = 0; // add all the lightmaps if (nummaps == 1) { int maps; for (maps = 0; maps < Defines.MAXLIGHTMAPS && surf.styles[maps] != (byte) 255; maps++) { bl = s_blocklights; int blp = 0; for (i = 0; i < 3; i++) scale[i] = gl_modulate.value * r_newrefdef.lightstyles[surf.styles[maps] & 0xFF].rgb[i]; if (scale[0] == 1.0F && scale[1] == 1.0F && scale[2] == 1.0F) { for (i = 0; i < size; i++) { bl[blp++] = lightmap.get(lightmapIndex++) & 0xFF; bl[blp++] = lightmap.get(lightmapIndex++) & 0xFF; bl[blp++] = lightmap.get(lightmapIndex++) & 0xFF; } } else { for (i = 0; i < size; i++) { bl[blp++] = (lightmap.get(lightmapIndex++) & 0xFF) * scale[0]; bl[blp++] = (lightmap.get(lightmapIndex++) & 0xFF) * scale[1]; bl[blp++] = (lightmap.get(lightmapIndex++) & 0xFF) * scale[2]; } } //lightmap += size*3; // skip to next lightmap } } else { int maps; // memset( s_blocklights, 0, sizeof( s_blocklights[0] ) * size * // 3 ); Arrays.fill(s_blocklights, 0, size * 3, 0.0f); for (maps = 0; maps < Defines.MAXLIGHTMAPS && surf.styles[maps] != (byte) 255; maps++) { bl = s_blocklights; int blp = 0; for (i = 0; i < 3; i++) scale[i] = gl_modulate.value * r_newrefdef.lightstyles[surf.styles[maps] & 0xFF].rgb[i]; if (scale[0] == 1.0F && scale[1] == 1.0F && scale[2] == 1.0F) { for (i = 0; i < size; i++) { bl[blp++] += lightmap.get(lightmapIndex++) & 0xFF; bl[blp++] += lightmap.get(lightmapIndex++) & 0xFF; bl[blp++] += lightmap.get(lightmapIndex++) & 0xFF; } } else { for (i = 0; i < size; i++) { bl[blp++] += (lightmap.get(lightmapIndex++) & 0xFF) * scale[0]; bl[blp++] += (lightmap.get(lightmapIndex++) & 0xFF) * scale[1]; bl[blp++] += (lightmap.get(lightmapIndex++) & 0xFF) * scale[2]; } } //lightmap += size*3; // skip to next lightmap } } // add all the dynamic lights if (surf.dlightframe == r_framecount) R_AddDynamicLights(surf); // label store: } catch (longjmpException store) { } // put into texture format stride -= smax; bl = s_blocklights; int blp = 0; monolightmap = gl_monolightmap.string.charAt(0); int destp = 0; if (monolightmap == '0') { for (i = 0; i < tmax; i++, destp += stride) { for (j = 0; j < smax; j++) { r = (int) bl[blp++]; g = (int) bl[blp++]; b = (int) bl[blp++]; // catch negative lights if (r < 0) r = 0; if (g < 0) g = 0; if (b < 0) b = 0; /* * * determine the brightest of the three color components */ if (r > g) max = r; else max = g; if (b > max) max = b; /* * * alpha is ONLY used for the mono lightmap case. For this * reason * we set it to the brightest of the color * components so that * things don't get too dim. */ a = max; /* * * rescale all the color components if the intensity of * the greatest * channel exceeds 1.0 */ if (max > 255) { float t = 255.0F / max; r = (int) (r * t); g = (int) (g * t); b = (int) (b * t); a = (int) (a * t); } r &= 0xFF; g &= 0xFF; b &= 0xFF; a &= 0xFF; dest.put(destp++, (a << 24) | (b << 16) | (g << 8) | (r << 0)); } } } else { for (i = 0; i < tmax; i++, destp += stride) { for (j = 0; j < smax; j++) { r = (int) bl[blp++]; g = (int) bl[blp++]; b = (int) bl[blp++]; // catch negative lights if (r < 0) r = 0; if (g < 0) g = 0; if (b < 0) b = 0; /* * * determine the brightest of the three color components */ if (r > g) max = r; else max = g; if (b > max) max = b; /* * * alpha is ONLY used for the mono lightmap case. For this * reason * we set it to the brightest of the color * components so that * things don't get too dim. */ a = max; /* * * rescale all the color components if the intensity of * the greatest * channel exceeds 1.0 */ if (max > 255) { float t = 255.0F / max; r = (int) (r * t); g = (int) (g * t); b = (int) (b * t); a = (int) (a * t); } /* * * So if we are doing alpha lightmaps we need to set the * R, G, and B * components to 0 and we need to set alpha to * 1-alpha. */ switch (monolightmap) { case 'L': case 'I': r = a; g = b = 0; break; case 'C': // try faking colored lighting a = 255 - ((r + g + b) / 3); r *= a / 255.0f; g *= a / 255.0f; b *= a / 255.0f; break; case 'A': default: r = g = b = 0; a = 255 - a; break; } r &= 0xFF; g &= 0xFF; b &= 0xFF; a &= 0xFF; dest.put(destp++, (a << 24) | (b << 16) | (g << 8) | (r << 0)); } } } } } --- NEW FILE: Mesh.java --- /* * Mesh.java * Copyright (C) 2003 * * $Id: Mesh.java,v 1.2 2006/11/21 00:50:46 cawe Exp $ */ /* 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 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. 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.basic; import jake2.Defines; import jake2.client.VID; import jake2.client.entity_t; import jake2.qcommon.qfiles; import jake2.render.image_t; import jake2.util.Lib; import jake2.util.Math3D; import java.nio.FloatBuffer; /** * Mesh * * @author cwei */ public abstract class Mesh extends Light { // g_mesh.c: triangle model functions /* * ============================================================= * * ALIAS MODELS * * ============================================================= */ static final int NUMVERTEXNORMALS = 162; float[][] r_avertexnormals = Anorms.VERTEXNORMALS; float[][] s_lerped = new float[qfiles.MAX_VERTS][4]; float[] shadevector = { 0, 0, 0 }; float[] shadelight = { 0, 0, 0 }; // precalculated dot products for quantized angles static final int SHADEDOT_QUANT = 16; float[][] r_avertexnormal_dots = Anorms.VERTEXNORMAL_DOTS; float[] shadedots = r_avertexnormal_dots[0]; void GL_LerpVerts(int nverts, int[] ov, int[] v, float[][] lerp, float[] move, float[] frontv, float[] backv) { int i; int lerpIndex = 0; int ovv, vv; //PMM -- added RF_SHELL_DOUBLE, RF_SHELL_HALF_DAM if ((currententity.flags & (Defines.RF_SHELL_RED | Defines.RF_SHELL_GREEN | Defines.RF_SHELL_BLUE | Defines.RF_SHELL_DOUBLE | Defines.RF_SHELL_HALF_DAM)) != 0) { float[] normal; for (i = 0; i < nverts; i++ /* , v++, ov++, lerp+=4 */ ) { vv = v[i]; normal = r_avertexnormals[(vv >>> 24) & 0xFF]; ovv = ov[i]; lerp[i][0] = move[0] + (ovv & 0xFF) * backv[0] + (vv & 0xFF) * frontv[0] + normal[0] * Defines.POWERSUIT_SCALE; lerp[i][1] = move[1] + ((ovv >>> 8) & 0xFF) * backv[1] + ((vv >>> 8) & 0xFF) * frontv[1] + normal[1] * Defines.POWERSUIT_SCALE; lerp[i][2] = move[2] + ((ovv >>> 16) & 0xFF) * backv[2] + ((vv >>> 16) & 0xFF) * frontv[2] + normal[2] * Defines.POWERSUIT_SCALE; } } else { for (i = 0; i < nverts; i++ /* , v++, ov++, lerp+=4 */ ) { vv = v[i]; ovv = ov[i]; lerp[i][0] = move[0] + (ovv & 0xFF) * backv[0] + (vv & 0xFF) * frontv[0]; lerp[i][1] = move[1] + ((ovv >>> 8) & 0xFF) * backv[1] + ((vv >>> 8) & 0xFF) * frontv[1]; lerp[i][2] = move[2] + ((ovv >>> 16) & 0xFF) * backv[2] + ((vv >>> 16) & 0xFF) * frontv[2]; } } } void GL_LerpVerts(int nverts, int[] ov, int[] v, float[] move, float[] frontv, float[] backv) { int lerpIndex = 0; int ovv, vv; FloatBuffer lerp = vertexArrayBuf; //PMM -- added RF_SHELL_DOUBLE, RF_SHELL_HALF_DAM if ((currententity.flags & (Defines.RF_SHELL_RED | Defines.RF_SHELL_GREEN | Defines.RF_SHELL_BLUE | Defines.RF_SHELL_DOUBLE | Defines.RF_SHELL_HALF_DAM)) != 0) { float[] normal; int j = 0; for (int i = 0; i < nverts; i++ /* , v++, ov++, lerp+=4 */ ) { vv = v[i]; normal = r_avertexnormals[(v[i] >>> 24) & 0xFF]; ovv = ov[i]; lerp.put(j, move[0] + (ovv & 0xFF) * backv[0] + (vv & 0xFF) * frontv[0] + normal[0] * Defines.POWERSUIT_SCALE); lerp.put(j + 1, move[1] + ((ovv >>> 8) & 0xFF) * backv[1] + ((vv >>> 8) & 0xFF) * frontv[1] + normal[1] * Defines.POWERSUIT_SCALE); lerp.put(j + 2, move[2] + ((ovv >>> 16) & 0xFF) * backv[2] + ((vv >>> 16) & 0xFF) * frontv[2] + normal[2] * Defines.POWERSUIT_SCALE); j += 3; } } else { int j = 0; for (int i = 0; i < nverts; i++ /* , v++, ov++, lerp+=4 */ ) { ovv = ov[i]; vv = v[i]; lerp.put(j, move[0] + (ovv & 0xFF) * backv[0] + (vv & 0xFF) * frontv[0]); lerp.put(j + 1, move[1] + ((ovv >>> 8) & 0xFF) * backv[1] + ((vv >>> 8) & 0xFF) * frontv[1]); lerp.put(j + 2, move[2] + ((ovv >>> 16) & 0xFF) * backv[2] + ((vv >>> 16) & 0xFF) * frontv[2]); j += 3; } } } FloatBuffer colorArrayBuf = Lib.newFloatBuffer(qfiles.MAX_VERTS * 4); FloatBuffer vertexArrayBuf = Lib.newFloatBuffer(qfiles.MAX_VERTS * 3); boolean isFilled = false; float[] tmpVec = { 0, 0, 0 }; /* * ============= GL_DrawAliasFrameLerp * * interpolates between two frames and origins FIXME: batch lerp all * vertexes ============= */ void GL_DrawAliasFrameLerp(qfiles.dmdl_t paliashdr, float backlerp) { float l; qfiles.daliasframe_t frame, oldframe; int[] v, ov; int[] order; int orderIndex = 0; int count; float frontlerp; float alpha; float[] move = { 0, 0, 0 }; // vec3_t float[][] vectors = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } // 3 mal // vec3_t }; float[] frontv = { 0, 0, 0 }; // vec3_t float[] backv = { 0, 0, 0 }; // vec3_t int i; int index_xyz; //float[][] lerp; frame = paliashdr.aliasFrames[currententity.frame]; v = frame.verts; oldframe = paliashdr.aliasFrames[currententity.oldframe]; ov = oldframe.verts; order = paliashdr.glCmds; if ((currententity.flags & Defines.RF_TRANSLUCENT) != 0) alpha = currententity.alpha; else alpha = 1.0f; // PMM - added double shell if ((currententity.flags & (Defines.RF_SHELL_RED | Defines.RF_SHELL_GREEN | Defines.RF_SHELL_BLUE | Defines.RF_SHELL_DOUBLE | Defines.RF_SHELL_HALF_DAM)) != 0) gl.glDisable(GL_TEXTURE_2D); frontlerp = 1.0f - backlerp; // move should be the delta back to the previous frame * backlerp Math3D.VectorSubtract(currententity.oldorigin, currententity.origin, frontv); Math3D.AngleVectors(currententity.angles, vectors[0], vectors[1], vectors[2]); move[0] = Math3D.DotProduct(frontv, vectors[0]); // forward move[1] = -Math3D.DotProduct(frontv, vectors[1]); // left move[2] = Math3D.DotProduct(frontv, vectors[2]); // up Math3D.VectorAdd(move, oldframe.translate, move); for (i = 0; i < 3; i++) { move[i] = backlerp * move[i] + frontlerp * frame.translate[i]; frontv[i] = frontlerp * frame.scale[i]; backv[i] = backlerp * oldframe.scale[i]; } if (gl_vertex_arrays.value != 0.0f) { GL_LerpVerts(paliashdr.num_xyz, ov, v, move, frontv, backv); gl.glEnableClientState(GL_VERTEX_ARRAY); gl.glVertexPointer(3, 0, vertexArrayBuf); // PMM - added double damage shell if ((currententity.flags & (Defines.RF_SHELL_RED | Defines.RF_SHELL_GREEN | Defines.RF_SHELL_BLUE | Defines.RF_SHELL_DOUBLE | Defines.RF_SHELL_HALF_DAM)) != 0) { gl.glDisableClientState(GL_COLOR_ARRAY); gl.glColor4f(shadelight[0], shadelight[1], shadelight[2], alpha); } else { gl.glEnableClientState(GL_COLOR_ARRAY); gl.glColorPointer(4, 0, colorArrayBuf); // // pre light everything // FloatBuffer color = colorArrayBuf; int j = 0; for (i = 0; i < paliashdr.num_xyz; i++) { // light normal index l = shadedots[(v[i] >>> 24) & 0xFF]; color.put(j++, l * shadelight[0]); color.put(j++, l * shadelight[1]); color.put(j++, l * shadelight[2]); color.put(j++, alpha); } } if (qglLockArraysEXT) gl.glLockArraysEXT(0, paliashdr.num_xyz); while (true) { // get the vertex count and primitive type count = order[orderIndex++]; if (count == 0) break; // done if (count < 0) { count = -count; gl.glBegin(GL_TRIANGLE_FAN); } else { gl.glBegin(GL_TRIANGLE_STRIP); } // PMM - added double damage shell if ((currententity.flags & (Defines.RF_SHELL_RED | Defines.RF_SHELL_GREEN | Defines.RF_SHELL_BLUE | Defines.RF_SHELL_DOUBLE | Defines.RF_SHELL_HALF_DAM)) != 0) { do { index_xyz = order[orderIndex + 2]; orderIndex += 3; /* * vertexArrayBuf.position(4 * index_xyz); * vertexArrayBuf.get(tmpVec); gl.glVertex3fv( tmpVec ); */ gl.glArrayElement(index_xyz); } while (--count != 0); } else { do { // texture coordinates come from the draw list gl.glTexCoord2f(Float .intBitsToFloat(order[orderIndex + 0]), Float .intBitsToFloat(order[orderIndex + 1])); index_xyz = order[orderIndex + 2]; orderIndex += 3; // normals and vertexes come from the frame list gl.glArrayElement(index_xyz); } while (--count != 0); } gl.glEnd(); } if (qglLockArraysEXT) gl.glUnlockArraysEXT(); } else { GL_LerpVerts(paliashdr.num_xyz, ov, v, s_lerped, move, frontv, backv); float[] tmp; while (true) { // get the vertex count and primitive type count = order[orderIndex++]; if (count == 0) break; // done if (count < 0) { count = -count; gl.glBegin(GL_TRIANGLE_FAN); } else { gl.glBegin(GL_TRIANGLE_STRIP); } if ((currententity.flags & (Defines.RF_SHELL_RED | Defines.RF_SHELL_GREEN | Defines.RF_SHELL_BLUE)) != 0) { do { index_xyz = order[orderIndex + 2]; orderIndex += 3; gl.glColor4f(shadelight[0], shadelight[1], shadelight[2], alpha); tmp = s_lerped[index_xyz]; gl.glVertex3f(tmp[0], tmp[1], tmp[2]); } while (--count != 0); } else { do { // texture coordinates come from the draw list // gl.glTexCoord2f (((float *)order)[0], ((float // *)order)[1]); gl.glTexCoord2f(Float .intBitsToFloat(order[orderIndex + 0]), Float .intBitsToFloat(order[orderIndex + 1])); index_xyz = order[orderIndex + 2]; orderIndex += 3; // normals and vertexes come from the frame list l = shadedots[(v[index_xyz] >>> 24) & 0xFF]; gl.glColor4f(l * shadelight[0], l * shadelight[1], l * shadelight[2], alpha); tmp = s_lerped[index_xyz]; gl.glVertex3f(tmp[0], tmp[1], tmp[2]); } while (--count != 0); } gl.glEnd(); } } // PMM - added double damage shell if ((currententity.flags & (Defines.RF_SHELL_RED | Defines.RF_SHELL_GREEN | Defines.RF_SHELL_BLUE | Defines.RF_SHELL_DOUBLE | Defines.RF_SHELL_HALF_DAM)) != 0) gl.glEnable(GL_TEXTURE_2D); } /* * ============= GL_DrawAliasShadow ============= */ void GL_DrawAliasShadow(qfiles.dmdl_t paliashdr, int posenum) { float[] point = { 0, 0, 0 }; int count; qfiles.daliasframe_t frame; float lheight = currententity.origin[2] - lightspot[2]; frame = paliashdr.aliasFrames[currententity.frame]; int[] order = paliashdr.glCmds; float height = -lheight + 1.0f; int orderIndex = 0; int index = 0; while (true) { // get the vertex count and primitive type count = order[orderIndex++]; if (count == 0) break; // done if (count < 0) { count = -count; gl.glBegin(GL_TRIANGLE_FAN); } else gl.glBegin(GL_TRIANGLE_STRIP); do { // normals and vertexes come from the frame list /* * point[0] = verts[order[2]].v[0] * frame.scale[0] + * frame.translate[0]; point[1] = verts[order[2]].v[1] * * frame.scale[1] + frame.translate[1]; point[2] = * verts[order[2]].v[2] * frame.scale[2] + frame.translate[2]; */ if (gl_vertex_arrays.value != 0.0f) { index = order[orderIndex + 2] * 3; point[0] = vertexArrayBuf.get(index); point[1] = vertexArrayBuf.get(index + 1); point[2] = vertexArrayBuf.get(index + 2); } else { Math3D.VectorCopy(s_lerped[order[orderIndex + 2]], point); } point[0] -= shadevector[0] * (point[2] + lheight); point[1] -= shadevector[1] * (point[2] + lheight); point[2] = height; gl.glVertex3f(point[0], point[1], point[2]); orderIndex += 3; } while (--count != 0); gl.glEnd(); } } /* * * R_CullAliasModel */ boolean R_CullAliasModel(float[][] bbox, entity_t e) { int i; float[] mins = { 0, 0, 0 }; float[] maxs = { 0, 0, 0 }; qfiles.dmdl_t paliashdr; float[][] vectors = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }; float[] thismins = { 0, 0, 0 }; float[] oldmins = { 0, 0, 0 }; float[] thismaxs = { 0, 0, 0 }; float[] oldmaxs = { 0, 0, 0 }; qfiles.daliasframe_t pframe, poldframe; float[] angles = { 0, 0, 0 }; paliashdr = (qfiles.dmdl_t) currentmodel.extradata; if ((e.frame >= paliashdr.num_frames) || (e.frame < 0)) { VID.Printf(Defines.PRINT_ALL, "R_CullAliasModel " + currentmodel.name + ": no such frame " + e.frame + '\n'); e.frame = 0; } if ((e.oldframe >= paliashdr.num_frames) || (e.oldframe < 0)) { VID.Printf(Defines.PRINT_ALL, "R_CullAliasModel " + currentmodel.name + ": no such oldframe " + e.oldframe + '\n'); e.oldframe = 0; } pframe = paliashdr.aliasFrames[e.frame]; poldframe = paliashdr.aliasFrames[e.oldframe]; /* * * compute axially aligned mins and maxs */ if (pframe == poldframe) { for (i = 0; i < 3; i++) { mins[i] = pframe.translate[i]; maxs[i] = mins[i] + pframe.scale[i] * 255; } } else { for (i = 0; i < 3; i++) { thismins[i] = pframe.translate[i]; thismaxs[i] = thismins[i] + pframe.scale[i] * 255; oldmins[i] = poldframe.translate[i]; oldmaxs[i] = oldmins[i] + poldframe.scale[i] * 255; if (thismins[i] < oldmins[i]) mins[i] = thismins[i]; else mins[i] = oldmins[i]; if (thismaxs[i] > oldmaxs[i]) maxs[i] = thismaxs[i]; else maxs[i] = oldmaxs[i]; } } /* * * compute a full bounding box */ for (i = 0; i < 8; i++) { float[] tmp = { 0, 0, 0 }; if ((i & 1) != 0) tmp[0] = mins[0]; else tmp[0] = maxs[0]; if ((i & 2) != 0) tmp[1] = mins[1]; else tmp[1] = maxs[1]; if ((i & 4) != 0) tmp[2] = mins[2]; else tmp[2] = maxs[2]; Math3D.VectorCopy(tmp, bbox[i]); } /* * * rotate the bounding box */ Math3D.VectorCopy(e.angles, angles); angles[YAW] = -angles[YAW]; Math3D.AngleVectors(angles, vectors[0], vectors[1], vectors[2]); for (i = 0; i < 8; i++) { float[] tmp = { 0, 0, 0 }; Math3D.VectorCopy(bbox[i], tmp); bbox[i][0] = Math3D.DotProduct(vectors[0], tmp); bbox[i][1] = -Math3D.DotProduct(vectors[1], tmp); bbox[i][2] = Math3D.DotProduct(vectors[2], tmp); Math3D.VectorAdd(e.origin, bbox[i], bbox[i]); } { int p, f; int aggregatemask = ~0; // 0xFFFFFFFF for (p = 0; p < 8; p++) { int mask = 0; for (f = 0; f < 4; f++) { float dp = Math3D.DotProduct(frustum[f].normal, bbox[p]); if ((dp - frustum[f].dist) < 0) { mask |= (1 << f); } } aggregatemask &= mask; } if (aggregatemask != 0) { return true; } return false; } } /* * ================= R_DrawAliasModel * * ================= */ void R_DrawAliasModel(entity_t e) { int i; qfiles.dmdl_t paliashdr; float an; // bounding box float[][] bbox = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 } }; image_t skin; if ((e.flags & Defines.RF_WEAPONMODEL) == 0) { if (R_CullAliasModel(bbox, e)) return; } if ((e.flags & Defines.RF_WEAPONMODEL) != 0) { if (r_lefthand.value == 2.0f) return; } paliashdr = (qfiles.dmdl_t) currentmodel.extradata; // // get lighting information // // PMM - rewrote, reordered to handle new shells & mixing // PMM - 3.20 code .. replaced with original way of doing it to keep mod // authors happy // if ((currententity.flags & (Defines.RF_SHELL_HALF_DAM | Defines.RF_SHELL_GREEN | Defines.RF_SHELL_RED | Defines.RF_SHELL_BLUE | Defines.RF_SHELL_DOUBLE)) != 0) { Math3D.VectorClear(shadelight); if ((currententity.flags & Defines.RF_SHELL_HALF_DAM) != 0) { shadelight[0] = 0.56f; shadelight[1] = 0.59f; shadelight[2] = 0.45f; } if ((currententity.flags & Defines.RF_SHELL_DOUBLE) != 0) { shadelight[0] = 0.9f; shadelight[1] = 0.7f; } if ((currententity.flags & Defines.RF_SHELL_RED) != 0) shadelight[0] = 1.0f; if ((currententity.flags & Defines.RF_SHELL_GREEN) != 0) shadelight[1] = 1.0f; if ((currententity.flags & Defines.RF_SHELL_BLUE) != 0) shadelight[2] = 1.0f; } else if ((currententity.flags & Defines.RF_FULLBRIGHT) != 0) { for (i = 0; i < 3; i++) shadelight[i] = 1.0f; } else { R_LightPoint(currententity.origin, shadelight); // player lighting hack for communication back to server // big hack! if ((currententity.flags & Defines.RF_WEAPONMODEL) != 0) { // pick the greatest component, which should be the same // as the mono value returned by software if (shadelight[0] > shadelight[1]) { if (shadelight[0] > shadelight[2]) r_lightlevel.value = 150 * shadelight[0]; else r_lightlevel.value = 150 * shadelight[2]; } else { if (shadelight[1] > shadelight[2]) r_lightlevel.value = 150 * shadelight[1]; else r_lightlevel.value = 150 * shadelight[2]; } } if (gl_monolightmap.string.charAt(0) != '0') { float s = shadelight[0]; if (s < shadelight[1]) s = shadelight[1]; if (s < shadelight[2]) s = shadelight[2]; shadelight[0] = s; shadelight[1] = s; shadelight[2] = s; } } if ((currententity.flags & Defines.RF_MINLIGHT) != 0) { for (i = 0; i < 3; i++) if (shadelight[i] > 0.1f) break; if (i == 3) { shadelight[0] = 0.1f; shadelight[1] = 0.1f; shadelight[2] = 0.1f; } } if ((currententity.flags & Defines.RF_GLOW) != 0) { // bonus items will // pulse with time float scale; float min; scale = (float) (0.1f * Math.sin(r_newrefdef.time * 7)); for (i = 0; i < 3; i++) { min = shadelight[i] * 0.8f; shadelight[i] += scale; if (shadelight[i] < min) shadelight[i] = min; } } // ================= // PGM ir goggles color override if ((r_newrefdef.rdflags & Defines.RDF_IRGOGGLES) != 0 && (currententity.flags & Defines.RF_IR_VISIBLE) != 0) { shadelight[0] = 1.0f; shadelight[1] = 0.0f; shadelight[2] = 0.0f; } // PGM // ================= shadedots = r_avertexnormal_dots[((int) (currententity.angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)]; an = (float) (currententity.angles[1] / 180 * Math.PI); shadevector[0] = (float) Math.cos(-an); shadevector[1] = (float) Math.sin(-an); shadevector[2] = 1; Math3D.VectorNormalize(shadevector); // // locate the proper data // c_alias_polys += paliashdr.num_tris; // // draw all the triangles // if ((currententity.flags & Defines.RF_DEPTHHACK) != 0) // hack the depth range to prevent view model from poking into walls gl.glDepthRange(gldepthmin, gldepthmin + 0.3 * (gldepthmax - gldepthmin)); if ((currententity.flags & Defines.RF_WEAPONMODEL) != 0 && (r_lefthand.value == 1.0f)) { gl.glMatrixMode(GL_PROJECTION); gl.glPushMatrix(); gl.glLoadIdentity(); gl.glScalef(-1, 1, 1); MYgluPerspective(r_newrefdef.fov_y, (float) r_newrefdef.width / r_newrefdef.height, 4, 4096); gl.glMatrixMode(GL_MODELVIEW); gl.glCullFace(GL_BACK); } gl.glPushMatrix(); e.angles[PITCH] = -e.angles[PITCH]; // sigh. R_RotateForEntity(e); e.angles[PITCH] = -e.angles[PITCH]; // sigh. // select skin if (currententity.skin != null) skin = currententity.skin; // custom player skin else { if (currententity.skinnum >= qfiles.MAX_MD2SKINS) skin = currentmodel.skins[0]; else { skin = currentmodel.skins[currententity.skinnum]; if (skin == null) skin = currentmodel.skins[0]; } } if (skin == null) skin = r_notexture; // fallback... GL_Bind(skin.texnum); // draw it gl.glShadeModel(GL_SMOOTH); GL_TexEnv(GL_MODULATE); if ((currententity.flags & Defines.RF_TRANSLUCENT) != 0) { gl.glEnable(GL_BLEND); } if ((currententity.frame >= paliashdr.num_frames) || (currententity.frame < 0)) { VID.Printf(Defines.PRINT_ALL, "R_DrawAliasModel " + currentmodel.name + ": no such frame " + currententity.frame + '\n'); currententity.frame = 0; currententity.oldframe = 0; } if ((currententity.oldframe >= paliashdr.num_frames) || (currententity.oldframe < 0)) { VID.Printf(Defines.PRINT_ALL, "R_DrawAliasModel " + currentmodel.name + ": no such oldframe " + currententity.oldframe + '\n'); currententity.frame = 0; currententity.oldframe = 0; } if (r_lerpmodels.value == 0.0f) currententity.backlerp = 0; GL_DrawAliasFrameLerp(paliashdr, currententity.backlerp); GL_TexEnv(GL_REPLACE); gl.glShadeModel(GL_FLAT); gl.glPopMatrix(); if ((currententity.flags & Defines.RF_WEAPONMODEL) != 0 && (r_lefthand.value == 1.0F)) { gl.glMatrixMode(GL_PROJECTION); gl.glPopMatrix(); gl.glMatrixMode(GL_MODELVIEW); gl.glCullFace(GL_FRONT); } if ((currententity.flags & Defines.RF_TRANSLUCENT) != 0) { gl.glDisable(GL_BLEND); } if ((currententity.flags & Defines.RF_DEPTHHACK) != 0) gl.glDepthRange(gldepthmin, gldepthmax); if (gl_shadows.value != 0.0f && (currententity.flags & (Defines.RF_TRANSLUCENT | Defines.RF_WEAPONMODEL)) == 0) { gl.glPushMatrix(); R_RotateForEntity(e); gl.glDisable(GL_TEXTURE_2D); gl.glEnable(GL_BLEND); gl.glColor4f(0, 0, 0, 0.5f); GL_DrawAliasShadow(paliashdr, currententity.frame); gl.glEnable(GL_TEXTURE_2D); gl.glDisable(GL_BLEND); gl.glPopMatrix(); } gl.glColor4f(1, 1, 1, 1); } } --- NEW FILE: Model.java --- /* * Model.java * Copyright (C) 2003 * * $Id: Model.java,v 1.2 2006/11/21 00:50:46 cawe Exp $ */ /* 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 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. [...1228 lines suppressed...] { mod.clear(); } /* ================ Mod_FreeAll ================ */ void Mod_FreeAll() { for (int i=0 ; i<mod_numknown ; i++) { if (mod_known[i].extradata != null) Mod_Free(mod_known[i]); } } } --- NEW FILE: Main.java --- /* * Main.java * Copyright (C) 2003 * * $Id: Main.java,v 1.2 2006/11/21 00:50:46 cawe Exp $ */ /* 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 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. [...1547 lines suppressed...] float[] v; for (i = 0; i < NUM_BEAM_SEGS; i++) { v = start_points[i]; gl.glVertex3f(v[0], v[1], v[2]); v = end_points[i]; gl.glVertex3f(v[0], v[1], v[2]); v = start_points[(i + 1) % NUM_BEAM_SEGS]; gl.glVertex3f(v[0], v[1], v[2]); v = end_points[(i + 1) % NUM_BEAM_SEGS]; gl.glVertex3f(v[0], v[1], v[2]); } gl.glEnd(); gl.glEnable(GL_TEXTURE_2D); gl.glDisable(GL_BLEND); gl.glDepthMask(true); } } --- NEW FILE: Polygon.java --- /* * Polygon.java * Copyright (C) 2003 * * $Id: Polygon.java,v 1.2 2006/11/21 00:50:46 cawe Exp $ */ /* 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 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. 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.basic; import jake2.render.glpoly_t; /** * Polygon * * @author cwei */ public final class Polygon extends glpoly_t { private final static int MAXPOLYS = 20000; private final static int MAX_BUFFER_VERTICES = 120000; private static float[] buffer = new float[MAX_BUFFER_VERTICES * STRIDE]; private static int bufferIndex = 0; private static int polyCount = 0; private static Polygon[] polyCache = new Polygon[MAXPOLYS]; static { for (int i = 0; i < polyCache.length; i++) { polyCache[i] = new Polygon(); } } public static glpoly_t create(int numverts) { Polygon poly = polyCache[polyCount++]; poly.clear(); poly.numverts = numverts; poly.pos = bufferIndex; bufferIndex += numverts; return poly; } public static void reset() { polyCount = 0; bufferIndex = 0; } private Polygon() { } private final void clear() { next = null; chain = null; numverts = 0; flags = 0; } public final float x(int index) { return buffer[offset(index)]; } public final void x(int index, float value) { buffer[offset(index)] = value; } public final float y(int index) { return buffer[offset(index) + 1]; } public final void y(int index, float value) { buffer[offset(index) + 1] = value; } public final float z(int index) { return buffer[offset(index) + 2]; } public final void z(int index, float value) { buffer[offset(index) + 2] = value; } public final float s1(int index) { return buffer[offset(index) + 3]; } public final void s1(int index, float value) { buffer[offset(index) + 3] = value; } public final float t1(int index) { return buffer[offset(index) + 4]; } public final void t1(int index, float value) { buffer[offset(index) + 4] = value; } public final float s2(int index) { return buffer[offset(index) + 5]; } public final void s2(int index, float value) { buffer[offset(index) + 5] = value; } public final float t2(int index) { return buffer[offset(index) + 6]; } public final void t2(int index, float value) { buffer[offset(index) + 6] = value; } public final void beginScrolling(float value) { // not in use } public final void endScrolling() { // not in use } private final int offset(int index) { return (index + pos) * STRIDE; } } --- NEW FILE: Warp.java --- /* * Warp.java * Copyright (C) 2003 * * $Id: Warp.java,v 1.2 2006/11/21 00:50:46 cawe Exp $ */ /* 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 ... [truncated message content] |