public virtual void GL_CreateSurfaceLightmap(msurface_t surf) { if ((surf.flags & (Defines.SURF_DRAWSKY | Defines.SURF_DRAWTURB)) != 0) { return; } var smax = (surf.extents[0] >> 4) + 1; var 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"); } } surf.light_s = lightPos.x; surf.light_t = lightPos.y; surf.lightmaptexturenum = gl_lms.current_lightmap_texture; Int32Buffer base_renamed = gl_lms.lightmap_buffer; base_renamed.Position = surf.light_t * BLOCK_WIDTH + surf.light_s; R_SetCacheState(surf); R_BuildLightMap(surf, base_renamed.Slice(), BLOCK_WIDTH); }
public virtual void Mod_LoadMarksurfaces(lump_t l) { Int32 i, j, count; msurface_t[] out_renamed; if ((l.filelen % Defines.SIZE_OF_SHORT) != 0) { Com.Error(Defines.ERR_DROP, "MOD_LoadBmodel: funny lump size in " + loadmodel.name); } count = l.filelen / Defines.SIZE_OF_SHORT; out_renamed = new msurface_t[count]; loadmodel.marksurfaces = out_renamed; loadmodel.nummarksurfaces = count; ByteBuffer bb = ByteBuffer.Wrap(mod_base, l.fileofs, l.filelen); bb.Order = ByteOrder.LittleEndian; for (i = 0; i < count; i++) { j = bb.GetInt16(); if (j < 0 || j >= loadmodel.numsurfaces) { Com.Error(Defines.ERR_DROP, "Mod_ParseMarksurfaces: bad surface number"); } out_renamed[i] = loadmodel.surfaces[j]; } }
public virtual void ClearLightmapSurfaces( ) { for (var i = 0; i < MAX_LIGHTMAPS; i++) { lightmap_surfaces[i] = new msurface_t(); } }
public static void GL_SubdivideSurface(msurface_t fa) { _WarpFace = fa; // // convert edges back to a normal polygon // int numverts = 0; Vector3[] verts = new Vector3[fa.numedges + 1]; for (int i = 0; i < fa.numedges; i++) { int lindex = loadmodel.surfedges[fa.firstedge + i]; if (lindex > 0) { verts[numverts] = loadmodel.vertexes[loadmodel.edges[lindex].v[0]].position; } else { verts[numverts] = loadmodel.vertexes[loadmodel.edges[-lindex].v[1]].position; } numverts++; } SubdividePolygon(numverts, verts); }
public gllightmapstate_t( ) { for (var i = 0; i < MAX_LIGHTMAPS; i++) { lightmap_surfaces[i] = new msurface_t(); } }
private static void R_DrawSkyChain(msurface_t s) { GL_DisableMultitexture(); // used when gl_texsort is on GL_Bind(solidskytexture); speedscale = (float)realtime * 8; speedscale -= (int)speedscale & ~127; for (msurface_t fa = s; fa != null; fa = fa.texturechain) { EmitSkyPolys(fa); } GL.Enable(EnableCap.Blend); GL_Bind(alphaskytexture); speedscale = (float)realtime * 16; speedscale -= (int)speedscale & ~127; for (msurface_t fa = s; fa != null; fa = fa.texturechain) { EmitSkyPolys(fa); } GL.Disable(EnableCap.Blend); }
public static void R_RenderBrushPoly(msurface_t fa) { c_brush_polys++; if ((fa.flags & q_shared.SURF_DRAWSKY) != 0) { // warp texture, no lightmaps EmitBothSkyLayers(fa); return; } texture_t t = R_TextureAnimation(fa.texinfo.texture); GL_Bind(t.gl_texturenum); if ((fa.flags & q_shared.SURF_DRAWTURB) != 0) { // warp texture, no lightmaps EmitWaterPolys(fa); return; } if ((fa.flags & q_shared.SURF_UNDERWATER) != 0) { DrawGLWaterPoly(fa.polys); } else { DrawGLPoly(fa.polys); } // add the poly to the proper lightmap chain fa.polys.chain = lightmap_polys[fa.lightmaptexturenum]; lightmap_polys[fa.lightmaptexturenum] = fa.polys; // check for lightmap modification bool modified = false; for (int maps = 0; maps < q_shared.MAXLIGHTMAPS && fa.styles[maps] != 255; maps++) { if (d_lightstylevalue[fa.styles[maps]] != fa.cached_light[maps]) { modified = true; break; } } if (modified || fa.dlightframe == r_framecount || // dynamic this frame fa.cached_dlight) // dynamic previously { if (r_dynamic.value != 0) { lightmap_modified[fa.lightmaptexturenum] = true; UpdateRect(fa, ref lightmap_rectchange[fa.lightmaptexturenum]); int offset = fa.lightmaptexturenum * lightmap_bytes * BLOCK_WIDTH * BLOCK_HEIGHT; offset += fa.light_t * BLOCK_WIDTH * lightmap_bytes + fa.light_s * lightmap_bytes; R_BuildLightMap(fa, new ByteArraySegment(lightmaps, offset), BLOCK_WIDTH * lightmap_bytes); } } }
public override void R_SetCacheState(msurface_t surf) { for (var maps = 0; maps < Defines.MAXLIGHTMAPS && surf.styles[maps] != ( Byte )255; maps++) { surf.cached_light[maps] = r_newrefdef.lightstyles[surf.styles[maps] & 0xFF].white; } }
protected void GL_SubdivideSurface(msurface_t fa) { var verts = this.tmpVerts; float[] vec; this.warpface = fa; // // convert edges back to a normal polygon // var numverts = 0; for (var i = 0; i < fa.numedges; i++) { var lindex = this.loadmodel.surfedges[fa.firstedge + i]; if (lindex > 0) { vec = this.loadmodel.vertexes[this.loadmodel.edges[lindex].v[0]].position; } else { vec = this.loadmodel.vertexes[this.loadmodel.edges[-lindex].v[1]].position; } Math3D.VectorCopy(vec, verts[numverts]); numverts++; } this.SubdividePolygon(numverts, verts); }
public static void UpdateRect(msurface_t fa, ref glRect_t theRect) { if (fa.light_t < theRect.t) { if (theRect.h != 0) { theRect.h += (byte)(theRect.t - fa.light_t); } theRect.t = (byte)fa.light_t; } if (fa.light_s < theRect.l) { if (theRect.w != 0) { theRect.w += (byte)(theRect.l - fa.light_s); } theRect.l = (byte)fa.light_s; } int smax = (fa.extents[0] >> 4) + 1; int tmax = (fa.extents[1] >> 4) + 1; if ((theRect.w + theRect.l) < (fa.light_s + smax)) { theRect.w = (byte)((fa.light_s - theRect.l) + smax); } if ((theRect.h + theRect.t) < (fa.light_t + tmax)) { theRect.h = (byte)((fa.light_t - theRect.t) + tmax); } }
public virtual void R_DrawInlineBModel( ) { if (gl_flashblend.value == 0) { dlight_t lt; for (var k = 0; k < r_newrefdef.num_dlights; k++) { lt = r_newrefdef.dlights[k]; R_MarkLights(lt, 1 << k, currentmodel.nodes[currentmodel.firstnode]); } } var psurfp = currentmodel.firstmodelsurface; msurface_t[] surfaces = currentmodel.surfaces; if ((currententity.flags & Defines.RF_TRANSLUCENT) != 0) { GL.Enable(EnableCap.Blend); GL.Color4(1, 1, 1, 0.25F); GL_TexEnv(( Int32 )All.Modulate); } msurface_t psurf; cplane_t pplane; Single dot; for (var i = 0; i < currentmodel.nummodelsurfaces; i++) { psurf = surfaces[psurfp++]; pplane = psurf.plane; dot = Math3D.DotProduct(modelorg, pplane.normal) - pplane.dist; 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) { 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.Disable(EnableCap.Blend); GL.Color4(1, 1, 1, 1); GL_TexEnv(( Int32 )All.Replace); } }
/* * * R_SetCacheState */ protected void R_SetCacheState(msurface_t surf) { int maps; for (maps = 0; maps < Defines.MAXLIGHTMAPS && surf.styles[maps] != (byte)255; maps++) { surf.cached_light[maps] = this.r_newrefdef.lightstyles[surf.styles[maps] & 0xFF].white; } }
public static void R_MirrorChain(msurface_t s) { if (mirror) { return; } mirror = true; mirror_plane = s.plane; }
public virtual void GL_BuildPolygonFromSurface(msurface_t fa) { Int32 lindex, lnumverts; medge_t[] pedges; medge_t r_pedge; Single[] vec; Single s, t; glpoly_t poly; Single[] total = new Single[] { 0, 0, 0 }; pedges = currentmodel.edges; lnumverts = fa.numedges; Math3D.VectorClear(total); poly = Polygon.Create(lnumverts); poly.next = fa.polys; poly.flags = fa.flags; fa.polys = poly; for (var 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); poly.X(i, vec[0]); poly.Y(i, vec[1]); poly.Z(i, vec[2]); poly.S1(i, s); poly.T1(i, t); 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; 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; poly.S2(i, s); poly.T2(i, t); } }
public static void DrawTextureChains() { if (gl_texsort.value == 0) { GL_DisableMultitexture(); if (skychain != null) { R_DrawSkyChain(skychain); skychain = null; } return; } model_t world = cl.worldmodel; for (int i = 0; i < world.numtextures; i++) { texture_t t = world.textures[i]; if (t == null) { continue; } msurface_t s = t.texturechain; if (s == null) { continue; } if (i == skytexturenum) { R_DrawSkyChain(s); } else if (i == mirrortexturenum && r_mirroralpha.value != 1.0f) { R_MirrorChain(s); continue; } else { if ((s.flags & q_shared.SURF_DRAWTURB) != 0 && r_wateralpha.value != 1.0f) { continue; // draw translucent water later } for (; s != null; s = s.texturechain) { R_RenderBrushPoly(s); } } t.texturechain = null; } }
public override void R_AddSkySurface(msurface_t fa) { for (glpoly_t p = fa.polys; p != null; p = p.next) { for (int i = 0; i < p.numverts; i++) { verts[i][0] = p.X(i) - r_origin[0]; verts[i][1] = p.Y(i) - r_origin[1]; verts[i][2] = p.Z(i) - r_origin[2]; } ClipSkyPolygon(p.numverts, verts, 0); } }
/* * R_AddSkySurface */ protected void R_AddSkySurface(msurface_t fa) { // calculate vertex values for sky box for (var p = fa.polys; p != null; p = p.next) { for (var i = 0; i < p.numverts; i++) { this.verts[i][0] = p.x(i) - this.r_origin[0]; this.verts[i][1] = p.y(i) - this.r_origin[1]; this.verts[i][2] = p.z(i) - this.r_origin[2]; } this.ClipSkyPolygon(p.numverts, this.verts, 0); } }
public static void GL_CreateSurfaceLightmap(msurface_t surf) { if ((surf.flags & (q_shared.SURF_DRAWSKY | q_shared.SURF_DRAWTURB)) != 0) { return; } int smax = (surf.extents[0] >> 4) + 1; int tmax = (surf.extents[1] >> 4) + 1; surf.lightmaptexturenum = AllocBlock(smax, tmax, ref surf.light_s, ref surf.light_t); int offset = surf.lightmaptexturenum * lightmap_bytes * BLOCK_WIDTH * BLOCK_HEIGHT; offset += (surf.light_t * BLOCK_WIDTH + surf.light_s) * lightmap_bytes; R_BuildLightMap(surf, new ByteArraySegment(lightmaps, offset), BLOCK_WIDTH * lightmap_bytes); }
public void clear() { // don't clear the id // wichtig !!! this.name = ""; this.type = 0; this.width = this.height = 0; this.upload_width = this.upload_height = 0; this.registration_sequence = 0; // 0 = free this.texturechain = null; this.texnum = 0; // gl texture binding this.sl = this.tl = this.sh = this.th = 0; this.scrap = false; this.has_alpha = false; this.paletted = false; }
public virtual void CalcSurfaceExtents(msurface_t s) { Single[] mins = new Single[] { 0, 0 }; Single[] maxs = new Single[] { 0, 0 }; Single val; Int32 j, e; mvertex_t v; Int32[] bmins = new[] { 0, 0 }; Int32[] bmaxs = new[] { 0, 0 }; mins[0] = mins[1] = 999999; maxs[0] = maxs[1] = -99999; mtexinfo_t tex = s.texinfo; for (var i = 0; i < s.numedges; i++) { e = loadmodel.surfedges[s.firstedge + i]; if (e >= 0) { v = loadmodel.vertexes[loadmodel.edges[e].v[0]]; } else { v = loadmodel.vertexes[loadmodel.edges[-e].v[1]]; } for (j = 0; j < 2; j++) { val = v.position[0] * tex.vecs[j][0] + v.position[1] * tex.vecs[j][1] + v.position[2] * tex.vecs[j][2] + tex.vecs[j][3]; if (val < mins[j]) { mins[j] = val; } if (val > maxs[j]) { maxs[j] = val; } } } for (var i = 0; i < 2; i++) { bmins[i] = ( Int32 )Math.Floor(mins[i] / 16); bmaxs[i] = ( Int32 )Math.Ceiling(maxs[i] / 16); s.texturemins[i] = ( Int16 )(bmins[i] * 16); s.extents[i] = ( Int16 )((bmaxs[i] - bmins[i]) * 16); } }
public override void R_DrawAlphaSurfaces( ) { msurface_t s; Single intens; r_world_matrix.Clear(); GL.LoadMatrix(r_world_matrix.Array); GL.Enable(EnableCap.Blend); GL_TexEnv(( Int32 )All.Modulate); intens = gl_state.inverse_intensity; 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.Color4(intens, intens, intens, 0.33F); } else if ((s.texinfo.flags & Defines.SURF_TRANS66) != 0) { GL.Color4(intens, intens, intens, 0.66F); } else { GL.Color4(intens, intens, intens, 1); } if ((s.flags & Defines.SURF_DRAWTURB) != 0) { EmitWaterPolys(s); } else if ((s.texinfo.flags & Defines.SURF_FLOWING) != 0) { DrawGLFlowingPoly(s); } else { DrawGLPoly(s.polys); } } GL_TexEnv(( Int32 )All.Replace); GL.Color4(1, 1, 1, 1); GL.Disable(EnableCap.Blend); r_alpha_surfaces = null; }
/* * ============= EmitWaterPolys * * Does a water warp on the pre-fragmented glpoly_t chain ============= */ protected void EmitWaterPolys(msurface_t fa) { glpoly_t p, bp; int i; float s = 0; float t = 0; float os, ot; float scroll; var rdt = this.r_newrefdef.time; if ((fa.texinfo.flags & Defines.SURF_FLOWING) != 0) { scroll = -64 * (this.r_newrefdef.time * 0.5f - (int)(this.r_newrefdef.time * 0.5f)); } else { scroll = 0; } for (bp = fa.polys; bp != null; bp = bp.next) { p = bp; this.gl.glBegin(OpenGL.GL_TRIANGLE_FAN); for (i = 0; i < p.numverts; i++) { os = p.s1(i); ot = p.t1(i); s = os + OpenGLRenderApi.SIN[(int)((ot * 0.125f + this.r_newrefdef.time) * OpenGLRenderApi.TURBSCALE) & 255]; s += scroll; s *= 1.0f / 64; t = ot + OpenGLRenderApi.SIN[(int)((os * 0.125f + rdt) * OpenGLRenderApi.TURBSCALE) & 255]; t *= 1.0f / 64; this.gl.glTexCoord2f(s, t); this.gl.glVertex3f(p.x(i), p.y(i), p.z(i)); } this.gl.glEnd(); } }
private static void EmitBothSkyLayers(msurface_t fa) { GL_DisableMultitexture(); GL_Bind(solidskytexture); speedscale = (float)realtime * 8; speedscale -= (int)speedscale & ~127; EmitSkyPolys(fa); GL.Enable(EnableCap.Blend); GL_Bind(alphaskytexture); speedscale = (float)realtime * 16; speedscale -= (int)speedscale & ~127; EmitSkyPolys(fa); GL.Disable(EnableCap.Blend); }
public virtual void DrawGLFlowingPoly(msurface_t fa) { var scroll = -64 * ((r_newrefdef.time / 40F) - ( Int32 )(r_newrefdef.time / 40F)); if (scroll == 0F) { scroll = -64F; } GL.Begin(PrimitiveType.Polygon); glpoly_t p = fa.polys; for (var i = 0; i < p.numverts; i++) { GL.TexCoord2(p.S1(i) + scroll, p.T1(i)); GL.Vertex3(p.X(i), p.Y(i), p.Z(i)); } GL.End(); }
public static void R_RenderDynamicLightmaps(msurface_t fa) { c_brush_polys++; if ((fa.flags & (q_shared.SURF_DRAWSKY | q_shared.SURF_DRAWTURB)) != 0) { return; } fa.polys.chain = lightmap_polys[fa.lightmaptexturenum]; lightmap_polys[fa.lightmaptexturenum] = fa.polys; // check for lightmap modification bool flag = false; for (int maps = 0; maps < q_shared.MAXLIGHTMAPS && fa.styles[maps] != 255; maps++) { if (d_lightstylevalue[fa.styles[maps]] != fa.cached_light[maps]) { flag = true; break; } } if (flag || fa.dlightframe == r_framecount || // dynamic this frame fa.cached_dlight) // dynamic previously { if (r_dynamic.value != 0) { lightmap_modified[fa.lightmaptexturenum] = true; UpdateRect(fa, ref lightmap_rectchange[fa.lightmaptexturenum]); int offset = fa.lightmaptexturenum * lightmap_bytes * BLOCK_WIDTH * BLOCK_HEIGHT + fa.light_t * BLOCK_WIDTH * lightmap_bytes + fa.light_s * lightmap_bytes; R_BuildLightMap(fa, new ByteArraySegment(lightmaps, offset), BLOCK_WIDTH * lightmap_bytes); } } }
public override void EmitWaterPolys(msurface_t fa) { glpoly_t p, bp; int i; float s = 0; float t = 0; float os, ot; float scroll; float rdt = r_newrefdef.time; if ((fa.texinfo.flags & Defines.SURF_FLOWING) != 0) { scroll = -64 * ((r_newrefdef.time * 0.5F) - (int)(r_newrefdef.time * 0.5F)); } else { scroll = 0; } for (bp = fa.polys; bp != null; bp = bp.next) { p = bp; GL.Begin(PrimitiveType.TriangleFan); for (i = 0; i < p.numverts; i++) { os = p.S1(i); ot = p.T1(i); s = os + Warp.SIN[(int)((ot * 0.125F + r_newrefdef.time) * TURBSCALE) & 255]; s += scroll; s *= (1F / 64); t = ot + Warp.SIN[(int)((os * 0.125F + rdt) * TURBSCALE) & 255]; t *= (1F / 64); GL.TexCoord2(s, t); GL.Vertex3(p.X(i), p.Y(i), p.Z(i)); } GL.End(); } }
static void EmitWaterPolys(msurface_t fa) { for (glpoly_t p = fa.polys; p != null; p = p.next) { GL.Begin(BeginMode.Polygon); for (int i = 0; i < p.numverts; i++) { float[] v = p.verts[i]; float os = v[3]; float ot = v[4]; float s = os + turbsin[(int)((ot * 0.125 + realtime) * q_shared.TURBSCALE) & 255]; s *= (1.0f / 64); float t = ot + turbsin[(int)((os * 0.125 + realtime) * q_shared.TURBSCALE) & 255]; t *= (1.0f / 64); GL.TexCoord2(s, t); GL.Vertex3(v); } GL.End(); } }
static void EmitSkyPolys(msurface_t fa) { for (glpoly_t p = fa.polys; p != null; p = p.next) { GL.Begin(BeginMode.Polygon); for (int i = 0; i < p.numverts; i++) { float[] v = p.verts[i]; Vector3 dir = new Vector3(v[0] - r_origin.X, v[1] - r_origin.Y, v[2] - r_origin.Z); dir.Z *= 3; // flatten the sphere dir.Normalize(); dir *= 6 * 63; float s = (speedscale + dir.X) / 128.0f; float t = (speedscale + dir.Y) / 128.0f; GL.TexCoord2(s, t); GL.Vertex3(v); } GL.End(); } }
public static void R_MarkLights(dlight_t light, int bit, mnodebase_t node) { if (node.contents < 0) { return; } mnode_t n = (mnode_t)node; mplane_t splitplane = n.plane; float dist = Vector3.Dot(light.origin, splitplane.normal) - splitplane.dist; if (dist > light.radius) { R_MarkLights(light, bit, n.children[0]); return; } if (dist < -light.radius) { R_MarkLights(light, bit, n.children[1]); return; } // mark the polygons for (int i = 0; i < n.numsurfaces; i++) { msurface_t surf = cl.worldmodel.surfaces[n.firstsurface + i]; if (surf.dlightframe != r_dlightframecount) { surf.dlightbits = 0; surf.dlightframe = r_dlightframecount; } surf.dlightbits |= bit; } R_MarkLights(light, bit, n.children[0]); R_MarkLights(light, bit, n.children[1]); }
public override void GL_SubdivideSurface(msurface_t fa) { float[][] verts = tmpVerts; float[] vec; warpface = fa; int numverts = 0; for (int i = 0; i < fa.numedges; i++) { int lindex = loadmodel.surfedges[fa.firstedge + i]; if (lindex > 0) { vec = loadmodel.vertexes[loadmodel.edges[lindex].v[0]].position; } else { vec = loadmodel.vertexes[loadmodel.edges[-lindex].v[1]].position; } Math3D.VectorCopy(vec, verts[numverts]); numverts++; } SubdividePolygon(numverts, verts); }
/* ================= Mod_LoadMarksurfaces ================= */ static void Mod_LoadMarksurfaces(bspfile.lump_t l) { int i, j, count; short[] @in; msurface_t[] @out; if ((l.filelen % sizeof(short)) != 0) sys_linux.Sys_Error ("MOD_LoadBmodel: funny lump size in " + loadmodel.name); count = l.filelen / sizeof(short); @in = new short[count]; @out = new msurface_t[count]; int ofs = l.fileofs; for (int kk = 0; kk < count; kk++) { @in[kk] = BitConverter.ToInt16(mod_base, ofs); ofs += sizeof(short); } loadmodel.marksurfaces = @out; loadmodel.nummarksurfaces = count; for ( i=0 ; i<count ; i++) { j = @in[i]; if (j >= loadmodel.numsurfaces) sys_linux.Sys_Error ("Mod_ParseMarksurfaces: bad surface number"); @out[i] = loadmodel.surfaces[j]; } }
/* ================ CalcSurfaceExtents Fills in s.texturemins[] and s.extents[] ================ */ static void CalcSurfaceExtents(msurface_t s) { double[] mins = new double[2], maxs = new double[2]; double val; int i,j, e; mvertex_t v; mtexinfo_t tex; int[] bmins = new int[2], bmaxs = new int[2]; mins[0] = mins[1] = 999999; maxs[0] = maxs[1] = -99999; tex = s.texinfo; for (i=0 ; i<s.numedges ; i++) { e = loadmodel.surfedges[s.firstedge+i]; if (e >= 0) v = loadmodel.vertexes[loadmodel.edges[e].v[0]]; else v = loadmodel.vertexes[loadmodel.edges[-e].v[1]]; for (j=0 ; j<2 ; j++) { val = v.position[0] * tex.vecs[j][0] + v.position[1] * tex.vecs[j][1] + v.position[2] * tex.vecs[j][2] + tex.vecs[j][3]; if (val < mins[j]) mins[j] = val; if (val > maxs[j]) maxs[j] = val; } } for (i=0 ; i<2 ; i++) { bmins[i] = (int)Math.Floor(mins[i]/16); bmaxs[i] = (int)Math.Ceiling(maxs[i]/16); s.texturemins[i] = (short)(bmins[i] * 16); s.extents[i] = (short)((bmaxs[i] - bmins[i]) * 16); /*if ( (tex.flags & bspfile.TEX_SPECIAL) == 0 && s.extents[i] > 256) sys_linux.Sys_Error ("Bad surface extents");*/ } }
/* ================= Mod_LoadFaces ================= */ static void Mod_LoadFaces(bspfile.lump_t l) { bspfile.dface_t[] @in; msurface_t[] @out; int i, count, surfnum; int planenum, side; if ((l.filelen % bspfile.sizeof_dface_t) != 0) sys_linux.Sys_Error ("MOD_LoadBmodel: funny lump size in " + loadmodel.name); count = l.filelen / bspfile.sizeof_dface_t; bspfile.ByteBuffer buf = new bspfile.ByteBuffer(mod_base, l.fileofs); @in = new bspfile.dface_t[count]; @out = new msurface_t[count]; for (int kk = 0; kk < count; kk++) { @in[kk] = (bspfile.dface_t)buf; buf.ofs += bspfile.sizeof_dface_t; @out[kk] = new msurface_t(); } loadmodel.surfaces = @out; loadmodel.numsurfaces = count; int color = colors[(icolor++) % 8]; for ( surfnum=0 ; surfnum<count ; surfnum++) { @out[surfnum].firstedge = @in[surfnum].firstedge; @out[surfnum].numedges = @in[surfnum].numedges; @out[surfnum].flags = 0; planenum = @in[surfnum].planenum; side = @in[surfnum].side; if (side != 0) @out[surfnum].flags |= SURF_PLANEBACK; @out[surfnum].plane = loadmodel.planes[planenum]; @out[surfnum].color = color; color += 0x40; @out[surfnum].texinfo = loadmodel.texinfo[@in[surfnum].texinfo]; CalcSurfaceExtents (@out[surfnum]); // lighting info for (i=0 ; i<bspfile.MAXLIGHTMAPS ; i++) @out[surfnum].styles[i] = @in[surfnum].styles[i]; i = @in[surfnum].lightofs; if (i == -1) @out[surfnum].samples = null; else @out[surfnum].samples = new bspfile.ByteBuffer(loadmodel.lightdata, i); // set the drawing flags flag if (@out[surfnum].texinfo.texture.name.StartsWith("sky")) // sky { @out[surfnum].flags |= (SURF_DRAWSKY | SURF_DRAWTILED); continue; } if (@out[surfnum].texinfo.texture.name.StartsWith("*")) // turbulent { @out[surfnum].flags |= (SURF_DRAWTURB | SURF_DRAWTILED); for (i=0 ; i<2 ; i++) { @out[surfnum].extents[i] = 16384; @out[surfnum].texturemins[i] = -8192; } continue; } } }