Пример #1
0
        public float[][] verts; //[4][VERTEXSIZE];	// variable sized (xyz s1t1 s2t2)

        public void Clear()
        {
            this.next     = null;
            this.chain    = null;
            this.numverts = 0;
            this.flags    = 0;
            this.verts    = null;
        }
Пример #2
0
        public float[][] verts; //[4][VERTEXSIZE];	// variable sized (xyz s1t1 s2t2)

        public void Clear()
        {
            next     = null;
            chain    = null;
            numverts = 0;
            flags    = 0;
            verts    = null;
        }
Пример #3
0
 private static void DrawGLPoly(glpoly_t p)
 {
     GL.Begin(PrimitiveType.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();
 }
Пример #4
0
        private static void DrawGLWaterPoly(glpoly_t p)
        {
            DisableMultitexture();

            float[] nv = new float[3];
            GL.Begin(PrimitiveType.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 + host.RealTime) * Math.Sin(v[2] * 0.05 + host.RealTime));
                nv[1] = (float)(v[1] + 8 * Math.Sin(v[0] * 0.05 + host.RealTime) * Math.Sin(v[2] * 0.05 + host.RealTime));
                nv[2] = v[2];

                GL.Vertex3(nv);
            }
            GL.End();
        }
Пример #5
0
        /// <summary>
        /// EmitSkyPolys
        /// </summary>
        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] - Render.Origin.X, v[1] - Render.Origin.Y, v[2] - Render.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();
            }
        }
Пример #6
0
        /// <summary>
        /// EmitWaterPolys
        /// Does a water warp on the pre-fragmented glpoly_t chain
        /// </summary>
        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 + Host.RealTime) * TURBSCALE) & 255];
                    s *= (1.0f / 64);

                    float t = ot + _TurbSin[(int)((os * 0.125 + Host.RealTime) * TURBSCALE) & 255];
                    t *= (1.0f / 64);

                    GL.TexCoord2(s, t);
                    GL.Vertex3(v);
                }
                GL.End();
            }
        }
Пример #7
0
        private static void DrawGLWaterPolyLightmap(glpoly_t p)
        {
            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[5], v[6]);

                nv[0] = (float)(v[0] + 8 * Math.Sin(v[1] * 0.05 + Host.RealTime) * Math.Sin(v[2] * 0.05 + Host.RealTime));
                nv[1] = (float)(v[1] + 8 * Math.Sin(v[0] * 0.05 + Host.RealTime) * Math.Sin(v[2] * 0.05 + Host.RealTime));
                nv[2] = v[2];

                GL.Vertex3(nv);
            }
            GL.End();
        }
Пример #8
0
 private 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();
 }
Пример #9
0
        /// <summary>
        /// BuildSurfaceDisplayList
        /// </summary>
        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 = _CurrentVertBase[r_pedge_v[0]].position;
                }
                else
                {
                    r_pedge_v = pedges[-lindex].v;
                    vec = _CurrentVertBase[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 (_glKeepTJunctions.Value == 0 && (fa.flags & Surf.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 < Mod.VERTEXSIZE; ++k)
                                poly.verts[j - 1][k] = poly.verts[j][k];
                        }
                        --lnumverts;
                        ++_ColinElim;
                        // retry next vertex next time, which is now current vertex
                        --i;
                    }
                }
            }
            poly.numverts = lnumverts;
        }
Пример #10
0
        /// <summary>
        /// R_BlendLightmaps
        /// </summary>
        private static void BlendLightmaps()
        {
            if (_FullBright.Value != 0)
            {
                return;
            }
            if (_glTexSort.Value == 0)
            {
                return;
            }

            GL.DepthMask(false);   // don't bother writing Z

            if (Drawer.LightMapFormat == PixelFormat.Luminance)
            {
                GL.BlendFunc(BlendingFactor.Zero, BlendingFactor.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 (_LightMap.Value == 0)
            {
                GL.Enable(EnableCap.Blend);
            }

            for (int i = 0; i < MAX_LIGHTMAPS; i++)
            {
                glpoly_t p = _LightMapPolys[i];
                if (p == null)
                {
                    continue;
                }

                Drawer.Bind(_LightMapTextures + i);
                if (_LightMapModified[i])
                {
                    CommitLightmap(i);
                }

                for ( ; p != null; p = p.chain)
                {
                    if ((p.flags & Surf.SURF_UNDERWATER) != 0)
                    {
                        DrawGLWaterPolyLightmap(p);
                    }
                    else
                    {
                        GL.Begin(PrimitiveType.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 (Drawer.LightMapFormat == PixelFormat.Luminance)
            {
                GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.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
        }
Пример #11
0
        /// <summary>
        /// BuildSurfaceDisplayList
        /// </summary>
        private 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       = _CurrentVertBase[r_pedge_v[0]].position;
                }
                else
                {
                    r_pedge_v = pedges[-lindex].v;
                    vec       = _CurrentVertBase[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 (_glKeepTJunctions.Value == 0 && (fa.flags & Surf.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 < Mod.VERTEXSIZE; ++k)
                            {
                                poly.verts[j - 1][k] = poly.verts[j][k];
                            }
                        }
                        --lnumverts;
                        ++_ColinElim;
                        // retry next vertex next time, which is now current vertex
                        --i;
                    }
                }
            }
            poly.numverts = lnumverts;
        }
Пример #12
0
        /// <summary>
        /// R_DrawSequentialPoly
        /// Systems that have fast state and texture changes can
        /// just do everything as it passes with no need to sort
        /// </summary>
        private static void DrawSequentialPoly(msurface_t s)
        {
            //
            // normal lightmaped poly
            //
            if ((s.flags & (Surf.SURF_DRAWSKY | Surf.SURF_DRAWTURB | Surf.SURF_UNDERWATER)) == 0)
            {
                RenderDynamicLightmaps(s);
                glpoly_t  p = s.polys;
                texture_t t = TextureAnimation(s.texinfo.texture);
                if (vid.glMTexable)
                {
                    // Binds world to texture env 0
                    Drawer.SelectTexture(MTexTarget.TEXTURE0_SGIS);
                    Drawer.Bind(t.gl_texturenum);
                    GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Replace);

                    // Binds lightmap to texenv 1
                    EnableMultitexture(); // Same as SelectTexture (TEXTURE1)
                    Drawer.Bind(_LightMapTextures + s.lightmaptexturenum);
                    int i = s.lightmaptexturenum;
                    if (_LightMapModified[i])
                    {
                        CommitLightmap(i);
                    }

                    GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Blend);
                    GL.Begin(PrimitiveType.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
                {
                    Drawer.Bind(t.gl_texturenum);
                    GL.Begin(PrimitiveType.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();

                    Drawer.Bind(_LightMapTextures + s.lightmaptexturenum);
                    GL.Enable(EnableCap.Blend);
                    GL.Begin(PrimitiveType.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 & Surf.SURF_DRAWTURB) != 0)
            {
                DisableMultitexture();
                Drawer.Bind(s.texinfo.texture.gl_texturenum);
                EmitWaterPolys(s);
                return;
            }

            //
            // subdivided sky warp
            //
            if ((s.flags & Surf.SURF_DRAWSKY) != 0)
            {
                DisableMultitexture();
                Drawer.Bind(_SolidSkyTexture);
                _SpeedScale  = (float)host.RealTime * 8;
                _SpeedScale -= (int)_SpeedScale & ~127;

                EmitSkyPolys(s);

                GL.Enable(EnableCap.Blend);
                Drawer.Bind(_AlphaSkyTexture);
                _SpeedScale  = (float)host.RealTime * 16;
                _SpeedScale -= (int)_SpeedScale & ~127;

                EmitSkyPolys(s);

                GL.Disable(EnableCap.Blend);
                return;
            }

            //
            // underwater warped with lightmap
            //
            RenderDynamicLightmaps(s);
            if (vid.glMTexable)
            {
                texture_t t = TextureAnimation(s.texinfo.texture);
                Drawer.SelectTexture(MTexTarget.TEXTURE0_SGIS);
                Drawer.Bind(t.gl_texturenum);
                GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Replace);
                EnableMultitexture();
                Drawer.Bind(_LightMapTextures + s.lightmaptexturenum);
                int i = s.lightmaptexturenum;
                if (_LightMapModified[i])
                {
                    CommitLightmap(i);
                }

                GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Blend);
                GL.Begin(PrimitiveType.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 + host.RealTime) * Math.Sin(v[2] * 0.05 + host.RealTime));
                    nv[1] = (float)(v[1] + 8 * Math.Sin(v[0] * 0.05 + host.RealTime) * Math.Sin(v[2] * 0.05 + host.RealTime));
                    nv[2] = v[2];

                    GL.Vertex3(nv);
                }
                GL.End();
            }
            else
            {
                glpoly_t p = s.polys;

                texture_t t = TextureAnimation(s.texinfo.texture);
                Drawer.Bind(t.gl_texturenum);
                DrawGLWaterPoly(p);

                Drawer.Bind(_LightMapTextures + s.lightmaptexturenum);
                GL.Enable(EnableCap.Blend);
                DrawGLWaterPolyLightmap(p);
                GL.Disable(EnableCap.Blend);
            }
        }
Пример #13
0
 public void Clear()
 {
     this.next = null;
     this.chain = null;
     this.numverts = 0;
     this.flags = 0;
     this.verts = null;
 }
Пример #14
0
        /// <summary>
        /// SubdividePolygon
        /// </summary>
        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 = Mod.SubdivideSize * Math.Floor(m / Mod.SubdivideSize + 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++)
            {
                Common.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;
            }
        }
Пример #15
0
        /// <summary>
        /// SubdividePolygon
        /// </summary>
        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 = Mod.SubdivideSize * Math.Floor(m / Mod.SubdivideSize + 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++)
            {
                Common.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;
            }
        }