diff options
Diffstat (limited to 'src/jake2/render/common/Light.java')
-rw-r--r-- | src/jake2/render/common/Light.java | 685 |
1 files changed, 0 insertions, 685 deletions
diff --git a/src/jake2/render/common/Light.java b/src/jake2/render/common/Light.java deleted file mode 100644 index 5781975..0000000 --- a/src/jake2/render/common/Light.java +++ /dev/null @@ -1,685 +0,0 @@ -/* -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. - -*/ - -// Created on 20.08.2006 by RST. - -// $Id: Light.java,v 1.1 2006-10-31 13:06:32 salomo Exp $ - -package jake2.render.common; - - -import java.nio.ByteBuffer; -import java.nio.IntBuffer; -import java.util.Arrays; - -import jake2.*; -import jake2.client.*; -import jake2.game.*; -import jake2.qcommon.*; -import jake2.render.*; -import jake2.server.*; -import jake2.util.Math3D; -import jake2.util.Vec3Cache; - -public abstract class Light extends Warp { - - protected float[] pointcolor = { 0, 0, 0 }; // vec3_t - - protected cplane_t lightplane; // used as shadow plane - - protected float[] lightspot = { 0, 0, 0 }; // vec3_t - - protected float[] s_blocklights = new float[34 * 34 * 3]; - - protected int r_dlightframecount; - - protected final float[] impact = { 0, 0, 0 }; - - - public static final int DLIGHT_CUTOFF = 64; - - /** - * R_AddDynamicLights - */ - protected void R_AddDynamicLights(msurface_t surf) { - int sd, td; - float fdist, frad, fminlight; - int s, t; - dlight_t dl; - float[] pfBL; - float fsacc, ftacc; - - int smax = (surf.extents[0] >> 4) + 1; - int tmax = (surf.extents[1] >> 4) + 1; - mtexinfo_t tex = surf.texinfo; - - float local0, local1; - for (int 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 (int i = 0; i < 3; i++) { - impact[i] = dl.origin[i] - surf.plane.normal[i] * fdist; - } - - local0 = Math3D.DotProduct(impact, tex.vecs[0]) + tex.vecs[0][3] - - surf.texturemins[0]; - local1 = 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) (local1 - ftacc); - if (td < 0) - td = -td; - - for (s = 0, fsacc = 0; s < smax; s++, fsacc += 16, pfBLindex += 3) { - sd = (int) (local0 - 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]; - } - } - } - } - } - - // replaces the goto jump - private Throwable gotoStore = new Throwable(); - - /** - * R_BuildLightMap - * - * Combine and scale multiple lightmaps into the floating format in - * blocklights - */ - - protected void R_BuildLightMap(msurface_t surf, IntBuffer dest, int stride) { - int r, g, b, a, max; - int i, j; - int nummaps; - float[] bl; - // lightstyle_t style; - - 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"); - - int smax = (surf.extents[0] >> 4) + 1; - int tmax = (surf.extents[1] >> 4) + 1; - int 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) { - - for (i = 0; i < size * 3; i++) - s_blocklights[i] = 255; - - // goto store; - throw gotoStore; - } - - // count the # of maps - for (nummaps = 0; nummaps < Defines.MAXLIGHTMAPS - && surf.styles[nummaps] != (byte) 255; nummaps++); - - ByteBuffer lightmap = surf.samples; - int lightmapIndex = 0; - - // add all the lightmaps - float scale0; - float scale1; - float scale2; - 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]; - - scale0 = gl_modulate.value * r_newrefdef.lightstyles[surf.styles[maps] & 0xFF].rgb[0]; - scale1 = gl_modulate.value * r_newrefdef.lightstyles[surf.styles[maps] & 0xFF].rgb[1]; - scale2 = gl_modulate.value * r_newrefdef.lightstyles[surf.styles[maps] & 0xFF].rgb[2]; - - if (scale0 == 1.0F && scale1 == 1.0F && scale2 == 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) * scale0; - bl[blp++] = (lightmap.get(lightmapIndex++) & 0xFF) * scale1; - bl[blp++] = (lightmap.get(lightmapIndex++) & 0xFF) * scale2; - } - } - // lightmap += size*3; // skip to next lightmap - } - } else { - int maps; - - 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]; - scale0 = gl_modulate.value * r_newrefdef.lightstyles[surf.styles[maps] & 0xFF].rgb[0]; - scale1 = gl_modulate.value * r_newrefdef.lightstyles[surf.styles[maps] & 0xFF].rgb[1]; - scale2 = gl_modulate.value * r_newrefdef.lightstyles[surf.styles[maps] & 0xFF].rgb[2]; - - if (scale0 == 1.0F && scale1 == 1.0F && scale2 == 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) * scale0; - bl[blp++] += (lightmap.get(lightmapIndex++) & 0xFF) * scale1; - bl[blp++] += (lightmap.get(lightmapIndex++) & 0xFF) * scale2; - } - } - // lightmap += size*3; // skip to next lightmap - } - } - - // add all the dynamic lights - if (surf.dlightframe == r_framecount) - R_AddDynamicLights(surf); - - // label store: - } catch (Throwable store) { - } - - // put into texture format - stride -= smax; - bl = s_blocklights; - int blp = 0; - - int monolightmap = gl_monolightmap.string.charAt(0); - - int destp = 0; - - if (monolightmap == '0') { - for (i = 0; i < tmax; i++, destp += stride) { - // dest.position(destp); - - 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); - } - } - } else { - for (i = 0; i < tmax; i++, destp += stride) { - // dest.position(destp); - - 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); - float af = a / 255.0f; - r *= af; - g *= af; - b *= af; - 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); - } - } - } - } - - - // stack variable - private final float[] end = { 0, 0, 0 }; - - /** - * R_LightPoint - */ - protected void R_LightPoint(float[] p, float[] color) { - assert (p.length == 3) : "vec3_t bug"; - assert (color.length == 3) : "rgb bug"; - - 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 - // - dlight_t dl; - float add; - 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); - } - - /** - * RecursiveLightPoint - * - * @param node - * @param start - * @param end - * @return - */ - protected int RecursiveLightPoint(mnode_t node, float[] start, float[] end) { - if (node.contents != -1) - return -1; // didn't hit anything - - // 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); - float[] mid = Vec3Cache.get(); - 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) { - Vec3Cache.release(); // mid - return r; // hit something - } - - if ((back < 0) == side) { - Vec3Cache.release(); // mid - return -1; // didn't hit anuthing - } - - // check for impact on this node - Math3D.VectorCopy(mid, lightspot); - lightplane = plane; - int surfIndex = node.firstsurface; - - msurface_t surf; - int s, t, ds, dt; - mtexinfo_t tex; - ByteBuffer lightmap; - int maps; - for (int 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[] rgb; - lightmapIndex += 3 * (dt * ((surf.extents[0] >> 4) + 1) + ds); - - float scale0, scale1, scale2; - for (maps = 0; maps < Defines.MAXLIGHTMAPS - && surf.styles[maps] != (byte) 255; maps++) { - rgb = r_newrefdef.lightstyles[surf.styles[maps] & 0xFF].rgb; - scale0 = gl_modulate.value * rgb[0]; - scale1 = gl_modulate.value * rgb[1]; - scale2 = gl_modulate.value * rgb[2]; - - pointcolor[0] += (lightmap.get(lightmapIndex + 0) & 0xFF) - * scale0 * (1.0f / 255); - pointcolor[1] += (lightmap.get(lightmapIndex + 1) & 0xFF) - * scale1 * (1.0f / 255); - pointcolor[2] += (lightmap.get(lightmapIndex + 2) & 0xFF) - * scale2 * (1.0f / 255); - lightmapIndex += 3 * ((surf.extents[0] >> 4) + 1) - * ((surf.extents[1] >> 4) + 1); - } - } - Vec3Cache.release(); // mid - return 1; - } - - // go down back side - r = RecursiveLightPoint(node.children[1 - sideIndex], mid, end); - Vec3Cache.release(); // mid - return r; - } - - /** - * R_MarkLights - */ - protected void R_MarkLights(dlight_t light, int bit, mnode_t node) { - if (node.contents != -1) - return; - - cplane_t splitplane = node.plane; - float 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 - msurface_t surf; - int sidebit; - for (int 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_SetCacheState - */ - protected void R_SetCacheState(msurface_t surf) { - for (int maps = 0; maps < Defines.MAXLIGHTMAPS - && surf.styles[maps] != (byte) 255; maps++) { - surf.cached_light[maps] = r_newrefdef.lightstyles[surf.styles[maps] & 0xFF].white; - } - } - - - /** - * R_PushDlights - */ - protected void R_PushDlights() { - if (gl_flashblend.value != 0) - return; - - r_dlightframecount = r_framecount + 1; // because the count hasn't - // advanced yet for this frame - dlight_t l; - for (int i = 0; i < r_newrefdef.num_dlights; i++) { - l = r_newrefdef.dlights[i]; - R_MarkLights(l, 1 << i, r_worldmodel.nodes[0]); - } - } - - - /* - * ============================================================================= - * - * DYNAMIC LIGHTS BLEND RENDERING - * - * ============================================================================= - */ - - void R_RenderDlight(dlight_t light) { - float rad = light.intensity * 0.35f; - float[] v = Vec3Cache.get(); - Math3D.VectorSubtract(light.origin, r_origin, v); - - ggl.glBegin(ggl.GL_TRIANGLE_FAN); - ggl.glColor3f(light.color[0] * 0.2f, light.color[1] * 0.2f, - light.color[2] * 0.2f); - for (int i = 0; i < 3; i++) - v[i] = light.origin[i] - vpn[i] * rad; - - ggl.glVertex3f(v[0], v[1], v[2]); - ggl.glColor3f(0, 0, 0); - float a; - for (int i = 16; i >= 0; i--) { - a = (float) (i / 16.0f * Math.PI * 2); - for (int j = 0; j < 3; j++) - v[j] = (float) (light.origin[j] + vright[j] * Math.cos(a) * rad + vup[j] - * Math.sin(a) * rad); - ggl.glVertex3f(v[0], v[1], v[2]); - } - ggl.glEnd(); - Vec3Cache.release(); - } - - - /** - * ============= R_RenderDlights ============= - */ - public void R_RenderDlights() { - if (gl_flashblend.value == 0) - return; - - r_dlightframecount = r_framecount + 1; // because the count hasn't - // advanced yet for this frame - ggl.glDepthMask(false); - ggl.glDisable(ggl.GL_TEXTURE_2D); - ggl.glShadeModel(ggl.GL_SMOOTH); - ggl.glDisable(ggl.GL_BLEND); - ggl.glBlendFunc(ggl.GL_ONE, ggl.GL_ONE); - - for (int i = 0; i < r_newrefdef.num_dlights; i++) { - R_RenderDlight(r_newrefdef.dlights[i]); - } - - ggl.glColor3f(1, 1, 1); - ggl.glDisable(ggl.GL_BLEND); - ggl.glDisable(ggl.GL_TEXTURE_2D); - ggl.glBlendFunc(ggl.GL_SRC_ALPHA, ggl.GL_ONE_MINUS_SRC_ALPHA); - ggl.glDepthMask(true); - } -} |