Пример #1
0
    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);
            }
        }
    }
Пример #2
0
    public static texture_t R_TextureAnimation(texture_t t)
    {
        if (currententity.frame != 0)
        {
            if (t.alternate_anims != null)
            {
                t = t.alternate_anims;
            }
        }

        if (t.anim_total == 0)
        {
            return(t);
        }

        int reletive = (int)(cl.time * 10) % t.anim_total;
        int count    = 0;

        while (t.anim_min > reletive || t.anim_max <= reletive)
        {
            t = t.anim_next;
            if (t == null)
            {
                Sys_Error("R_TextureAnimation: broken cycle");
            }
            if (++count > 100)
            {
                Sys_Error("R_TextureAnimation: infinite cycle");
            }
        }

        return(t);
    }
Пример #3
0
    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;
        }
    }
Пример #4
0
    public static void R_InitTextures()
    {
        // create a simple checkerboard texture for the default
        r_notexture_mip        = new texture_t();
        r_notexture_mip.pixels = new byte[16 * 16 + 8 * 8 + 4 * 4 + 2 * 2];
        r_notexture_mip.width  = r_notexture_mip.height = 16;
        int offset = 0;

        r_notexture_mip.offsets[0] = offset;
        offset += 16 * 16;
        r_notexture_mip.offsets[1] = offset;
        offset += 8 * 8;
        r_notexture_mip.offsets[2] = offset;
        offset += 4 * 4;
        r_notexture_mip.offsets[3] = offset;

        byte[] dest = r_notexture_mip.pixels;
        for (int m = 0; m < 4; m++)
        {
            offset = r_notexture_mip.offsets[m];
            for (int y = 0; y < (16 >> m); y++)
            {
                for (int x = 0; x < (16 >> m); x++)
                {
                    if ((y < (8 >> m)) ^ (x < (8 >> m)))
                    {
                        dest[offset] = 0;
                    }
                    else
                    {
                        dest[offset] = 0xff;
                    }

                    offset++;
                }
            }
        }
    }
Пример #5
0
    public static void R_DrawWaterSurfaces()
    {
        if (r_wateralpha.value == 1.0f && gl_texsort.value != 0)
        {
            return;
        }

        //
        // go back to the world matrix
        //
        GL.LoadMatrix(ref r_world_matrix);

        if (r_wateralpha.value < 1.0)
        {
            GL.Enable(EnableCap.Blend);
            GL.Color4(1, 1, 1, r_wateralpha.value);
            GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Modulate);
        }

        if (gl_texsort.value == 0)
        {
            if (waterchain == null)
            {
                return;
            }

            for (msurface_t s = waterchain; s != null; s = s.texturechain)
            {
                GL_Bind(s.texinfo.texture.gl_texturenum);
                EmitWaterPolys(s);
            }
            waterchain = null;
        }
        else
        {
            for (int i = 0; i < cl.worldmodel.numtextures; i++)
            {
                texture_t t = cl.worldmodel.textures[i];
                if (t == null)
                {
                    continue;
                }

                msurface_t s = t.texturechain;
                if (s == null)
                {
                    continue;
                }

                if ((s.flags & q_shared.SURF_DRAWTURB) == 0)
                {
                    continue;
                }

                // set modulate mode explicitly

                GL_Bind(t.gl_texturenum);

                for (; s != null; s = s.texturechain)
                {
                    EmitWaterPolys(s);
                }

                t.texturechain = null;
            }
        }

        if (r_wateralpha.value < 1.0)
        {
            GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (int)TextureEnvMode.Replace);
            GL.Color4(1f, 1, 1, 1);
            GL.Disable(EnableCap.Blend);
        }
    }
Пример #6
0
    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);
        }
    }
Пример #7
0
        /*
        =================
        Mod_LoadTextures
        =================
        */
        static void Mod_LoadTextures(bspfile.lump_t l)
        {
            int		                i, j, pixels, num, max, altmax;
            bspfile.miptex_t	    mt;
            texture_t	            tx, tx2;
            texture_t[]	            anims = new texture_t[10];
            texture_t[]	            altanims = new texture_t[10];
            bspfile.dmiptexlump_t   m;

            for(int kk = 0; kk < 10; kk++)
            {
                anims[kk] = new texture_t();
                altanims[kk] = new texture_t();
            }

            if (l.filelen == 0)
            {
                loadmodel.textures = null;
                return;
            }
            bspfile.ByteBuffer buf = new bspfile.ByteBuffer(mod_base, l.fileofs);
            m = (bspfile.dmiptexlump_t)buf;

            loadmodel.numtextures = m.nummiptex;
            loadmodel.textures = new texture_t[m.nummiptex];

            for (i=0 ; i<m.nummiptex ; i++)
            {
                loadmodel.textures[i] = new texture_t();
                if (m.dataofs[i] == -1)
                    continue;
                buf.ofs = l.fileofs + m.dataofs[i];
                mt = (bspfile.miptex_t)buf;

                if ( (mt.width & 15) != 0 || (mt.height & 15) != 0 )
                    sys_linux.Sys_Error ("Texture " + mt.name + " is not 16 aligned");
                pixels = (int)(mt.width*mt.height/64*85);
                tx = new texture_t();
                tx.pixels = new byte[pixels];
                loadmodel.textures[i] = tx;

                tx.name = mt.name;
                tx.width = mt.width;
                tx.height = mt.height;
                for (j=0 ; j<bspfile.MIPLEVELS ; j++)
                    tx.offsets[j] = mt.offsets[j]/* + sizeof_texture_t*/ - bspfile.sizeof_miptex_t;
                // the pixels immediately follow the structures
                Buffer.BlockCopy(buf.buffer, buf.ofs + bspfile.sizeof_miptex_t, tx.pixels, 0, pixels);

                if (mt.name.StartsWith("sky"))
                    render.R_InitSky(tx);
            }

            //
            // sequence the animations
            //
            for (i=0 ; i<m.nummiptex ; i++)
            {
                tx = loadmodel.textures[i];
                if (tx == null || tx.name[0] != '+')
                    continue;
             		        if (tx.anim_next != null)
                    continue;	// allready sequenced

            // find the number of frames in the animation
                //memset (anims, 0, sizeof(anims));
                //memset (altanims, 0, sizeof(altanims));

                max = tx.name[1];
                altmax = 0;
                if (max >= 'a' && max <= 'z')
                    max -= 'a' - 'A';
                if (max >= '0' && max <= '9')
                {
                    max -= '0';
                    altmax = 0;
                    anims[max] = tx;
                    max++;
                }
                else if (max >= 'A' && max <= 'J')
                {
                    altmax = max - 'A';
                    max = 0;
                    altanims[altmax] = tx;
             			        altmax++;
                }
                else
                    sys_linux.Sys_Error ("Bad animating texture " + tx.name);

                for (j=i+1 ; j<m.nummiptex ; j++)
                {
                    tx2 = loadmodel.textures[j];
                    if (tx2 == null || tx2.name[0] != '+')
                        continue;
                    if (tx2.name.Substring(2).CompareTo(tx.name.Substring(2)) != 0)
                        continue;

                    num = tx2.name[1];
                    if (num >= 'a' && num <= 'z')
                        num -= 'a' - 'A';
                    if (num >= '0' && num <= '9')
                    {
                        num -= '0';
                        anims[num] = tx2;
                        if (num+1 > max)
                            max = num + 1;
                    }
                    else if (num >= 'A' && num <= 'J')
                    {
                        num = num - 'A';
                        altanims[num] = tx2;
                        if (num+1 > altmax)
                            altmax = num+1;
                    }
                    else
                        sys_linux.Sys_Error ("Bad animating texture " + tx.name);
                }

            // link them all together
                for (j=0 ; j<max ; j++)
                {
                    tx2 = anims[j];
                    if (tx2 == null)
                        sys_linux.Sys_Error ("Missing frame " + j + " of " + tx.name);
                    tx2.anim_total = max * ANIM_CYCLE;
                    tx2.anim_min = j * ANIM_CYCLE;
                    tx2.anim_max = (j+1) * ANIM_CYCLE;
                    tx2.anim_next = anims[ (j+1)%max ];
                    if (altmax != 0)
                        tx2.alternate_anims = altanims[0];
                }
                for (j=0 ; j<altmax ; j++)
                {
                    tx2 = altanims[j];
                    if (tx2 == null)
                        sys_linux.Sys_Error ("Missing frame " + j + " of " + tx.name);
                    tx2.anim_total = altmax * ANIM_CYCLE;
                    tx2.anim_min = j * ANIM_CYCLE;
                    tx2.anim_max = (j+1) * ANIM_CYCLE;
                    tx2.anim_next = altanims[ (j+1)%altmax ];
                    if (max != 0)
                        tx2.alternate_anims = anims[0];
                }
            }
        }
Пример #8
0
    public static void R_InitSky(texture_t mt)
    {
        byte[] src    = mt.pixels;
        int    offset = mt.offsets[0];

        // make an average value for the back to avoid
        // a fringe on the top level
        const int size = 128 * 128;

        uint[]  trans  = new uint[size];
        uint[]  v8to24 = d_8to24table;
        int     r      = 0;
        int     g      = 0;
        int     b      = 0;
        Union4b rgba   = Union4b.Empty;

        for (int i = 0; i < 128; i++)
        {
            for (int j = 0; j < 128; j++)
            {
                int p = src[offset + i * 256 + j + 128];
                rgba.ui0             = v8to24[p];
                trans[(i * 128) + j] = rgba.ui0;
                r += rgba.b0;
                g += rgba.b1;
                b += rgba.b2;
            }
        }

        rgba.b0 = (byte)(r / size);
        rgba.b1 = (byte)(g / size);
        rgba.b2 = (byte)(b / size);
        rgba.b3 = 0;

        uint transpix = rgba.ui0;

        if (solidskytexture == 0)
        {
            solidskytexture = GenerateTextureNumber();
        }
        GL_Bind(solidskytexture);
        GL.TexImage2D(TextureTarget.Texture2D, 0, gl_solid_format, 128, 128, 0, PixelFormat.Rgba, PixelType.UnsignedByte, trans);
        SetTextureFilters(TextureMinFilter.Linear, TextureMagFilter.Linear);

        for (int i = 0; i < 128; i++)
        {
            for (int j = 0; j < 128; j++)
            {
                int p = src[offset + i * 256 + j];
                if (p == 0)
                {
                    trans[(i * 128) + j] = transpix;
                }
                else
                {
                    trans[(i * 128) + j] = v8to24[p];
                }
            }
        }

        if (alphaskytexture == 0)
        {
            alphaskytexture = GenerateTextureNumber();
        }
        GL_Bind(alphaskytexture);
        GL.TexImage2D(TextureTarget.Texture2D, 0, gl_alpha_format, 128, 128, 0, PixelFormat.Rgba, PixelType.UnsignedByte, trans);
        SetTextureFilters(TextureMinFilter.Linear, TextureMagFilter.Linear);
    }