public virtual void DrawGLPolyChain(glpoly_t p, Single soffset, Single toffset) { if (soffset == 0 && toffset == 0) { for ( ; p != null; p = p.chain) { GL.Begin(PrimitiveType.Polygon); for (var j = 0; j < p.numverts; j++) { GL.TexCoord2(p.S2(j), p.T2(j)); GL.Vertex3(p.X(j), p.Y(j), p.Z(j)); } GL.End(); } } else { for ( ; p != null; p = p.chain) { GL.Begin(PrimitiveType.Polygon); for (var j = 0; j < p.numverts; j++) { GL.TexCoord2(p.S2(j) - soffset, p.T2(j) - toffset); GL.Vertex3(p.X(j), p.Y(j), p.Z(j)); } GL.End(); } } }
public virtual void R_DrawTriangleOutlines( ) { if (gl_showtris.value == 0) { return; } GL.Disable(EnableCap.Texture2D); GL.Disable(EnableCap.DepthTest); GL.Color4(1, 1, 1, 1); for (var i = 0; i < MAX_LIGHTMAPS; i++) { msurface_t surf; for (surf = gl_lms.lightmap_surfaces[i]; surf != null; surf = surf.lightmapchain) { glpoly_t p = surf.polys; for ( ; p != null; p = p.chain) { for (var j = 2; j < p.numverts; j++) { GL.Begin(PrimitiveType.LineStrip); GL.Vertex3(p.X(0), p.Y(0), p.Z(0)); GL.Vertex3(p.X(j - 1), p.Y(j - 1), p.Z(j - 1)); GL.Vertex3(p.X(j), p.Y(j), p.Z(j)); GL.Vertex3(p.X(0), p.Y(0), p.Z(0)); GL.End(); } } } } GL.Enable(EnableCap.DepthTest); GL.Enable(EnableCap.Texture2D); }
public virtual void DrawGLPoly(glpoly_t p) { GL.Begin(PrimitiveType.Polygon); for (var i = 0; i < p.numverts; i++) { GL.TexCoord2(p.S1(i), p.T1(i)); GL.Vertex3(p.X(i), p.Y(i), p.Z(i)); } GL.End(); }
public static void DrawGLPoly(glpoly_t p) { GL.Begin(BeginMode.Polygon); for (int i = 0; i < p.numverts; i++) { float[] v = p.verts[i]; GL.TexCoord2(v[3], v[4]); GL.Vertex3(v); } GL.End(); }
public virtual void DrawGLFlowingPoly(glpoly_t p) { var scroll = -64 * ((r_newrefdef.time / 40F) - ( Int32 )(r_newrefdef.time / 40F)); if (scroll == 0F) { scroll = -64F; } p.BeginScrolling(scroll); GL.DrawArrays(PrimitiveType.Polygon, p.pos, p.numverts); p.EndScrolling(); }
public virtual void GL_BuildPolygonFromSurface(msurface_t fa) { medge_t[] pedges = currentmodel.edges; var lnumverts = fa.numedges; glpoly_t poly = Polygon.Create(lnumverts); poly.next = fa.polys; poly.flags = fa.flags; fa.polys = poly; Int32 lindex; Single[] vec; medge_t r_pedge; Single s, t; 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; 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 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); } }
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 DrawGLWaterPoly(glpoly_t p) { GL_DisableMultitexture(); float[] nv = new float[3]; GL.Begin(BeginMode.TriangleFan); for (int i = 0; i < p.numverts; i++) { float[] v = p.verts[i]; GL.TexCoord2(v[3], v[4]); nv[0] = (float)(v[0] + 8 * Math.Sin(v[1] * 0.05 + realtime) * Math.Sin(v[2] * 0.05 + realtime)); nv[1] = (float)(v[1] + 8 * Math.Sin(v[0] * 0.05 + realtime) * Math.Sin(v[2] * 0.05 + realtime)); nv[2] = v[2]; GL.Vertex3(nv); } 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(); } }
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 SubdividePolygon(int numverts, Vector3[] verts) { if (numverts > 60) { Sys_Error("numverts = {0}", numverts); } Vector3 mins, maxs; BoundPoly(numverts, verts, out mins, out maxs); float[] dist = new float[64]; for (int i = 0; i < 3; i++) { double m = (Mathlib.Comp(ref mins, i) + Mathlib.Comp(ref maxs, i)) * 0.5; m = gl_subdivide_size.value * Math.Floor(m / gl_subdivide_size.value + 0.5); if (Mathlib.Comp(ref maxs, i) - m < 8) { continue; } if (m - Mathlib.Comp(ref mins, i) < 8) { continue; } for (int j = 0; j < numverts; j++) { dist[j] = (float)(Mathlib.Comp(ref verts[j], i) - m); } Vector3[] front = new Vector3[64]; Vector3[] back = new Vector3[64]; // cut it // wrap cases dist[numverts] = dist[0]; verts[numverts] = verts[0]; // Uze: source array must be at least numverts + 1 elements long int f = 0, b = 0; for (int j = 0; j < numverts; j++) { if (dist[j] >= 0) { front[f] = verts[j]; f++; } if (dist[j] <= 0) { back[b] = verts[j]; b++; } if (dist[j] == 0 || dist[j + 1] == 0) { continue; } if ((dist[j] > 0) != (dist[j + 1] > 0)) { // clip point float frac = dist[j] / (dist[j] - dist[j + 1]); front[f] = back[b] = verts[j] + (verts[j + 1] - verts[j]) * frac; f++; b++; } } SubdividePolygon(f, front); SubdividePolygon(b, back); return; } glpoly_t poly = new glpoly_t(); poly.next = _WarpFace.polys; _WarpFace.polys = poly; poly.AllocVerts(numverts); for (int i = 0; i < numverts; i++) { Copy(ref verts[i], poly.verts[i]); float s = Vector3.Dot(verts[i], _WarpFace.texinfo.vecs[0].Xyz); float t = Vector3.Dot(verts[i], _WarpFace.texinfo.vecs[1].Xyz); poly.verts[i][3] = s; poly.verts[i][4] = t; } }
public virtual void SubdividePolygon(int numverts, float[][] verts) { int i, j, k; float[] mins = new float[] { 0, 0, 0 }; float[] maxs = new float[] { 0, 0, 0 }; float m; float[] v = new float[] { 0, 0, 0 }; float[][] front = Lib.CreateJaggedArray <float[][]>(64, 3); float[][] back = Lib.CreateJaggedArray <float[][]>(64, 3); int f, b; float[] dist = new float[64]; float frac; float s, t; float[] total = new float[] { 0, 0, 0 }; float total_s, total_t; if (numverts > 60) { Com.Error(Defines.ERR_DROP, "numverts = " + numverts); } BoundPoly(numverts, verts, mins, maxs); for (i = 0; i < 3; i++) { m = (mins[i] + maxs[i]) * 0.5F; m = SUBDIVIDE_SIZE * (float)Math.Floor(m / SUBDIVIDE_SIZE + 0.5F); if (maxs[i] - m < 8) { continue; } if (m - mins[i] < 8) { continue; } for (j = 0; j < numverts; j++) { dist[j] = verts[j][i] - m; } dist[j] = dist[0]; Math3D.VectorCopy(verts[0], verts[numverts]); f = b = 0; for (j = 0; j < numverts; j++) { v = verts[j]; if (dist[j] >= 0) { Math3D.VectorCopy(v, front[f]); f++; } if (dist[j] <= 0) { Math3D.VectorCopy(v, back[b]); b++; } if (dist[j] == 0 || dist[j + 1] == 0) { continue; } if ((dist[j] > 0) != (dist[j + 1] > 0)) { frac = dist[j] / (dist[j] - dist[j + 1]); for (k = 0; k < 3; k++) { front[f][k] = back[b][k] = v[k] + frac * (verts[j + 1][k] - v[k]); } f++; b++; } } SubdividePolygon(f, front); SubdividePolygon(b, back); return; } glpoly_t poly = Polygon.Create(numverts + 2); poly.next = warpface.polys; warpface.polys = poly; Math3D.VectorClear(total); total_s = 0; total_t = 0; for (i = 0; i < numverts; i++) { poly.X(i + 1, verts[i][0]); poly.Y(i + 1, verts[i][1]); poly.Z(i + 1, verts[i][2]); s = Math3D.DotProduct(verts[i], warpface.texinfo.vecs[0]); t = Math3D.DotProduct(verts[i], warpface.texinfo.vecs[1]); total_s += s; total_t += t; Math3D.VectorAdd(total, verts[i], total); poly.S1(i + 1, s); poly.T1(i + 1, t); } float scale = 1F / numverts; poly.X(0, total[0] * scale); poly.Y(0, total[1] * scale); poly.Z(0, total[2] * scale); poly.S1(0, total_s * scale); poly.T1(0, total_t * scale); poly.X(i + 1, poly.X(1)); poly.Y(i + 1, poly.Y(1)); poly.Z(i + 1, poly.Z(1)); poly.S1(i + 1, poly.S1(1)); poly.T1(i + 1, poly.T1(1)); poly.S2(i + 1, poly.S2(1)); poly.T2(i + 1, poly.T2(1)); }
public static void R_BlendLightmaps() { if (r_fullbright.value != 0) { return; } if (gl_texsort.value == 0) { return; } GL.DepthMask(false); // don't bother writing Z if (gl_lightmap_format == PixelFormat.Luminance) { GL.BlendFunc(BlendingFactorSrc.Zero, BlendingFactorDest.OneMinusSrcColor); } //else if (gl_lightmap_format == GL_INTENSITY) //{ // glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); // glColor4f(0, 0, 0, 1); // glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //} if (r_lightmap.value == 0) { GL.Enable(EnableCap.Blend); } for (int i = 0; i < MAX_LIGHTMAPS; i++) { glpoly_t p = lightmap_polys[i]; if (p == null) { continue; } GL_Bind(lightmap_textures + i); if (lightmap_modified[i]) { CommitLightmap(i); } for (; p != null; p = p.chain) { if ((p.flags & q_shared.SURF_UNDERWATER) != 0) { DrawGLWaterPolyLightmap(p); } else { GL.Begin(BeginMode.Polygon); for (int j = 0; j < p.numverts; j++) { float[] v = p.verts[j]; GL.TexCoord2(v[5], v[6]); GL.Vertex3(v); } GL.End(); } } } GL.Disable(EnableCap.Blend); if (gl_lightmap_format == PixelFormat.Luminance) { GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); } //else if (gl_lightmap_format == GL_INTENSITY) //{ // glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); // glColor4f(1, 1, 1, 1); //} GL.DepthMask(true); // back to normal Z buffering }
public static void BuildSurfaceDisplayList(msurface_t fa) { // reconstruct the polygon medge_t[] pedges = currentmodel.edges; int lnumverts = fa.numedges; // // draw texture // glpoly_t poly = new glpoly_t(); poly.AllocVerts(lnumverts); poly.next = fa.polys; poly.flags = fa.flags; fa.polys = poly; ushort[] r_pedge_v; Vector3 vec; for (int i = 0; i < lnumverts; i++) { int lindex = currentmodel.surfedges[fa.firstedge + i]; if (lindex > 0) { r_pedge_v = pedges[lindex].v; vec = r_pcurrentvertbase[r_pedge_v[0]].position; } else { r_pedge_v = pedges[-lindex].v; vec = r_pcurrentvertbase[r_pedge_v[1]].position; } float s = Mathlib.DotProduct(ref vec, ref fa.texinfo.vecs[0]) + fa.texinfo.vecs[0].W; s /= fa.texinfo.texture.width; float t = Mathlib.DotProduct(ref vec, ref fa.texinfo.vecs[1]) + fa.texinfo.vecs[1].W; t /= fa.texinfo.texture.height; poly.verts[i][0] = vec.X; poly.verts[i][1] = vec.Y; poly.verts[i][2] = vec.Z; poly.verts[i][3] = s; poly.verts[i][4] = t; // // lightmap texture coordinates // s = Mathlib.DotProduct(ref vec, ref fa.texinfo.vecs[0]) + fa.texinfo.vecs[0].W; s -= fa.texturemins[0]; s += fa.light_s * 16; s += 8; s /= BLOCK_WIDTH * 16; t = Mathlib.DotProduct(ref vec, ref fa.texinfo.vecs[1]) + fa.texinfo.vecs[1].W; t -= fa.texturemins[1]; t += fa.light_t * 16; t += 8; t /= BLOCK_HEIGHT * 16; poly.verts[i][5] = s; poly.verts[i][6] = t; } // // remove co-linear points - Ed // if (gl_keeptjunctions.value == 0 && (fa.flags & q_shared.SURF_UNDERWATER) == 0) { for (int i = 0; i < lnumverts; ++i) { if (IsCollinear(poly.verts[(i + lnumverts - 1) % lnumverts], poly.verts[i], poly.verts[(i + 1) % lnumverts])) { int j; for (j = i + 1; j < lnumverts; ++j) { //int k; for (int k = 0; k < q_shared.VERTEXSIZE; ++k) { poly.verts[j - 1][k] = poly.verts[j][k]; } } --lnumverts; ++nColinElim; // retry next vertex next time, which is now current vertex --i; } } } poly.numverts = lnumverts; }
public static void R_DrawSequentialPoly(msurface_t s) { // // normal lightmaped poly // if ((s.flags & (q_shared.SURF_DRAWSKY | q_shared.SURF_DRAWTURB | q_shared.SURF_UNDERWATER)) == 0) { R_RenderDynamicLightmaps(s); glpoly_t p = s.polys; texture_t t = R_TextureAnimation(s.texinfo.texture); if (gl_mtexable) { // Binds world to texture env 0 GL_SelectTexture(MTexTarget.TEXTURE0_SGIS); GL_Bind(t.gl_texturenum); GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Replace); // Binds lightmap to texenv 1 GL_EnableMultitexture(); // Same as SelectTexture (TEXTURE1) GL_Bind(lightmap_textures + s.lightmaptexturenum); int i = s.lightmaptexturenum; if (lightmap_modified[i]) { CommitLightmap(i); } GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Blend); GL.Begin(BeginMode.Polygon); for (i = 0; i < p.numverts; i++) { float[] v = p.verts[i]; GL.MultiTexCoord2(TextureUnit.Texture0, v[3], v[4]); GL.MultiTexCoord2(TextureUnit.Texture1, v[5], v[6]); GL.Vertex3(v); } GL.End(); return; } else { GL_Bind(t.gl_texturenum); GL.Begin(BeginMode.Polygon); for (int i = 0; i < p.numverts; i++) { float[] v = p.verts[i]; GL.TexCoord2(v[3], v[4]); GL.Vertex3(v); } GL.End(); GL_Bind(lightmap_textures + s.lightmaptexturenum); GL.Enable(EnableCap.Blend); GL.Begin(BeginMode.Polygon); for (int i = 0; i < p.numverts; i++) { float[] v = p.verts[i]; GL.TexCoord2(v[5], v[6]); GL.Vertex3(v); } GL.End(); GL.Disable(EnableCap.Blend); } return; } // // subdivided water surface warp // if ((s.flags & q_shared.SURF_DRAWTURB) != 0) { GL_DisableMultitexture(); GL_Bind(s.texinfo.texture.gl_texturenum); EmitWaterPolys(s); return; } // // subdivided sky warp // if ((s.flags & q_shared.SURF_DRAWSKY) != 0) { GL_DisableMultitexture(); GL_Bind(solidskytexture); speedscale = (float)realtime * 8; speedscale -= (int)speedscale & ~127; EmitSkyPolys(s); GL.Enable(EnableCap.Blend); GL_Bind(alphaskytexture); speedscale = (float)realtime * 16; speedscale -= (int)speedscale & ~127; EmitSkyPolys(s); GL.Disable(EnableCap.Blend); return; } // // underwater warped with lightmap // R_RenderDynamicLightmaps(s); if (gl_mtexable) { texture_t t = R_TextureAnimation(s.texinfo.texture); GL_SelectTexture(MTexTarget.TEXTURE0_SGIS); GL_Bind(t.gl_texturenum); GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Replace); GL_EnableMultitexture(); GL_Bind(lightmap_textures + s.lightmaptexturenum); int i = s.lightmaptexturenum; if (lightmap_modified[i]) { CommitLightmap(i); } GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Blend); GL.Begin(BeginMode.TriangleFan); glpoly_t p = s.polys; float[] nv = new float[3]; for (i = 0; i < p.numverts; i++) { float[] v = p.verts[i]; GL.MultiTexCoord2(TextureUnit.Texture0, v[3], v[4]); GL.MultiTexCoord2(TextureUnit.Texture1, v[5], v[6]); nv[0] = (float)(v[0] + 8 * Math.Sin(v[1] * 0.05 + realtime) * Math.Sin(v[2] * 0.05 + realtime)); nv[1] = (float)(v[1] + 8 * Math.Sin(v[0] * 0.05 + realtime) * Math.Sin(v[2] * 0.05 + realtime)); nv[2] = v[2]; GL.Vertex3(nv); } GL.End(); } else { glpoly_t p = s.polys; texture_t t = R_TextureAnimation(s.texinfo.texture); GL_Bind(t.gl_texturenum); DrawGLWaterPoly(p); GL_Bind(lightmap_textures + s.lightmaptexturenum); GL.Enable(EnableCap.Blend); DrawGLWaterPolyLightmap(p); GL.Disable(EnableCap.Blend); } }
public virtual void DrawGLPoly(glpoly_t p) { GL.DrawArrays(PrimitiveType.Polygon, p.pos, p.numverts); }