📄 light.java
字号:
/* * Light.java * Copyright (C) 2003 * * $Id: Light.java,v 1.4 2005/05/07 17:21:42 cawe Exp $ *//*Copyright (C) 1997-2001 Id Software, Inc.This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of the License, or (at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the GNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*/package jake2.render.lwjgl;import jake2.Defines;import jake2.Globals;import jake2.client.dlight_t;import jake2.game.cplane_t;import jake2.qcommon.Com;import jake2.render.*;import jake2.util.Math3D;import jake2.util.Vec3Cache;import java.nio.ByteBuffer;import java.nio.IntBuffer;import java.util.Arrays;import org.lwjgl.opengl.GL11;/** * 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 ============================================================================= */ // stack variable private final float[] v = {0, 0, 0}; /** * R_RenderDlight */ void R_RenderDlight(dlight_t light) { float rad = light.intensity * 0.35f; Math3D.VectorSubtract (light.origin, r_origin, v); gl.glBegin (GL11.GL_TRIANGLE_FAN); gl.glColor3f (light.color[0]*0.2f, light.color[1]*0.2f, light.color[2]*0.2f); int i; 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); int j; float a; 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() { 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(GL11.GL_TEXTURE_2D); gl.glShadeModel (GL11.GL_SMOOTH); gl.glEnable (GL11.GL_BLEND); gl.glBlendFunc (GL11.GL_ONE, GL11.GL_ONE); for (int i=0 ; i<r_newrefdef.num_dlights ; i++) { R_RenderDlight(r_newrefdef.dlights[i]); } gl.glColor3f (1,1,1); gl.glDisable(GL11.GL_BLEND); gl.glEnable(GL11.GL_TEXTURE_2D); gl.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA); gl.glDepthMask(true); } /* ============================================================================= DYNAMIC LIGHTS ============================================================================= */ /** * R_MarkLights */ 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_PushDlights */ 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] ); } } /* ============================================================================= LIGHT SAMPLING ============================================================================= */ float[] pointcolor = {0, 0, 0}; // vec3_t cplane_t lightplane; // used as shadow plane float[] lightspot = {0, 0, 0}; // vec3_t /** * RecursiveLightPoint * @param node * @param start * @param end * @return */ 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; } // stack variable private final float[] end = {0, 0, 0}; /** * R_LightPoint */ 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); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -