예제 #1
0
        void RenderableWater_WriteNextFrameEvent(Vector3 camerapos)
        {
            double           xmultiplier = scale.x / numsectors;
            double           ymultiplier = scale.y / numsectors;
            GraphicsHelperGl g           = new GraphicsHelperGl();

            g.SetMaterialColor(new double[] { 0, 0.2, 0.8, 0.6 });
            g.EnableBlendSrcAlpha();
            g.EnableModulate();
            g.DisableTexture2d(); // note to self: could add texture??? (or vertex fragment)
            g.Normal(new Vector3(0, 0, 1));
            for (int x = 0; x < numsectors; x++)
            {
                Gl.glBegin(Gl.GL_TRIANGLE_STRIP);
                for (int y = numsectors; y >= 0; y--)
                {
                    Vector3 posoffset = new Vector3(x * xmultiplier, y * ymultiplier, 0);
                    Vector3 vertexpos = pos + posoffset;
                    //Console.WriteLine(vertexpos);
                    g.Vertex(vertexpos);
                    vertexpos.x += xmultiplier;
                    //Console.WriteLine(vertexpos);
                    g.Vertex(vertexpos);
                }
                Gl.glEnd();
            }
            Gl.glDisable(Gl.GL_BLEND);
            g.SetMaterialColor(new double[] { 1, 1, 1, 1 });
        }
 public RenderableS3o( string s3opath )
 {
     g = new GraphicsHelperGl();
     unit = new S3oLoader().LoadS3o(s3opath);
     if (unit.texturename1 == "Spring unit")
     {
        unit.texturename1 = "Default.tga";
        unit.texturename2 = "Default.tga";
     }
     string texturedirectory = Path.Combine(Path.GetDirectoryName(Path.GetDirectoryName(s3opath)), "unittextures");
     LogFile.GetInstance().WriteLine( texturedirectory + "\\" + unit.texturename1 + "]");
     texture1 = GlTexture.FromFile(texturedirectory + "/" + unit.texturename1);
 }
예제 #3
0
        public RenderableS3o(string s3opath)
        {
            g    = new GraphicsHelperGl();
            unit = new S3oLoader().LoadS3o(s3opath);
            if (unit.texturename1 == "Spring unit")
            {
                unit.texturename1 = "Default.tga";
                unit.texturename2 = "Default.tga";
            }
            string texturedirectory = Path.Combine(Path.GetDirectoryName(Path.GetDirectoryName(s3opath)), "unittextures");

            LogFile.GetInstance().WriteLine(texturedirectory + "\\" + unit.texturename1 + "]");
            texture1 = GlTexture.FromFile(texturedirectory + "/" + unit.texturename1);
        }
예제 #4
0
        void RenderableAllFeatures_WriteNextFrameEvent(Vector3 camerapos)
        {
            //Console.WriteLine("raf writenextframe");
            GraphicsHelperGl g       = new GraphicsHelperGl();
            FrustrumCulling  culling = FrustrumCulling.GetInstance();

            foreach (FeatureInfo featureinfo in features)
            {
                Vector3 displaypos = new Vector3(featureinfo.x * Terrain.SquareSize, featureinfo.y * Terrain.SquareSize,
                                                 parent.Map[featureinfo.x, featureinfo.y]);
                //  Console.WriteLine("displaypos: " + displaypos );
                if (culling.IsInsideFrustum(displaypos, featureinfo.unit.Radius))
                {
                    //    Console.WriteLine("culling ok");
                    g.PushMatrix();
                    g.Translate(displaypos);
                    featureinfo.unit.Render();
                    g.PopMatrix();
                }
            }
        }
예제 #5
0
        void RenderableMinimap_WriteNextFrameEvent(Vector3 camerapos)
        {
            //Console.WriteLine( "RenderableMinimap_WriteNextFrameEvent" );
            GetDimensions();

            GraphicsHelperGl g = new GraphicsHelperGl();

            g.CheckError();
            //LogFile.GetInstance().WriteLine( windowwidth + " " + windowheight + " " + RendererSdl.GetInstance().OuterWindowWidth + " " + RendererSdl.GetInstance().OuterWindowHeight );
            g.ApplyOrtho(windowwidth, windowheight, RendererSdl.GetInstance().OuterWindowWidth, RendererSdl.GetInstance().OuterWindowHeight);
            g.CheckError();
            DrawMinimap();
            g.CheckError();
            DrawFrustrum(camerapos);
            g.CheckError();
            if (Render != null)
            {
                Render(minimapx, minimapy, minimapwidth, minimapheight);
            }
            g.CheckError();
            g.RemoveOrtho();
            g.CheckError();
        }
        // note to self: move this to subscriber?
        void DrawFrustrum(Vector3 camerapos)
        {
            FrustrumCulling frustrum = FrustrumCulling.GetInstance();
            Vector2 cameraposonmap = new Vector2(camerapos.x * minimapwidth / mapwidth / Terrain.SquareSize,
                camerapos.y * minimapheight / mapheight / Terrain.SquareSize); // ignore z
            Vector2 direction = new Vector2(frustrum.viewray.x, frustrum.viewray.y); // ignore z
            Gl.glDisable(Gl.GL_LIGHTING);
            Gl.glDisable(Gl.GL_CULL_FACE);
            GraphicsHelperGl g = new GraphicsHelperGl();
            g.DisableTexture2d();
            //g.SetColor(0, 0, 1);
            //g.SetMaterialColor(new Color(0, 0, 1));
            Gl.glColor3ub(0, 255, 0);
            Gl.glDepthFunc(Gl.GL_ALWAYS);

            Gl.glBegin(Gl.GL_LINES);
            Gl.glVertex2d(minimapx + cameraposonmap.x, minimapy + cameraposonmap.y);
            Gl.glVertex2d(minimapx + cameraposonmap.x + direction.x * viewdirectionlinelength, minimapy + cameraposonmap.y + direction.y * viewdirectionlinelength);
            Gl.glEnd();

            Gl.glEnable(Gl.GL_LIGHTING);
            Gl.glDepthFunc(Gl.GL_LEQUAL);
            Gl.glColor3ub(255, 255, 255);
        }
예제 #7
0
        // returns byte buffer in raw RGBA format, 32bits per pixel
        // opengl needs to be initialized for this to run
        // normally the renderer is initialized before anything else (in MapDesigner.cs), so this should be ok
        public byte[] CreateUnitPic(string s3ofilepath, int width, int height)
        {
            int picturewidth  = 96;
            int pictureheight = 96;

            GraphicsHelperGl g = new GraphicsHelperGl();

            Unit unit = new S3oLoader().LoadS3o(s3ofilepath);

            Gl.glViewport(0, 0, picturewidth, pictureheight);                                   // Set Our Viewport (Match Texture Size)
            //Gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);				// Set The Clear Color To Medium Blue

            Gl.glMatrixMode(Gl.GL_PROJECTION);
            Gl.glPushMatrix();
            Gl.glLoadIdentity();
            Glu.gluPerspective(60.0, (float)picturewidth / (float)pictureheight, 0.1, 1000.0);
            Gl.glMatrixMode(Gl.GL_MODELVIEW);

            /*
             * float[] ambientLight = new float[] { 1.0f, 1.0f, 1.0f, 1.0f };
             * float[] diffuseLight = new float[] { 0.6f, 0.6f, 0.6f, 1.0f };
             * float[] specularLight = new float[] { 0.2f, 0.2f, 0.2f, 1.0f };
             * float[] position = new float[] { -1.5f, 1.0f, -4.0f, 1.0f };
             *
             * Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_AMBIENT, ambientLight);
             * Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_DIFFUSE, diffuseLight);
             * Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_SPECULAR, specularLight);
             * Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, position);
             */
            Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);                // Clear The Screen And Depth Buffer

            Gl.glPushMatrix();
            Gl.glLoadIdentity();

            Gl.glRotated(-20, 0, 1, 0);
            Gl.glTranslated(-8, -8, -27);

            Gl.glRotated(-90, 1, 0, 0);

            Gl.glEnable(Gl.GL_LIGHTING);

            unit.Render();

            Gl.glPopMatrix();
            //g.Bind2DTexture(0);
            //Gl.glDeleteTextures(2, new int[] { unittexture1, unittexture2 });
            Gl.glViewport(0, 0, RendererSdl.GetInstance().OuterWindowWidth, RendererSdl.GetInstance().OuterWindowHeight);
            Gl.glMatrixMode(Gl.GL_PROJECTION);
            Gl.glPopMatrix();
            Gl.glMatrixMode(Gl.GL_MODELVIEW);
            g.CheckError();

            byte[] buffer = new byte[pictureheight * picturewidth * 4];
            IntPtr ptr    = Marshal.AllocHGlobal(picturewidth * pictureheight * 4);

            Gl.glReadPixels(0, 0, picturewidth, pictureheight, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, ptr);
            Marshal.Copy(ptr, buffer, 0, picturewidth * pictureheight * 4);
            Marshal.FreeHGlobal(ptr);

            // flip

            /* or not
             * byte[] newbuffer = new byte[pictureheight * picturewidth * 4];
             * for (int x = 0; x < picturewidth; x++)
             * {
             *  for (int y = 0; y < picturewidth; y++)
             *  {
             *      for (int i = 0; i < 4; i++)
             *      {
             *          newbuffer[( pictureheight - y - 1 ) * picturewidth * 4 + x * 4 + i] = buffer[y * picturewidth * 4 + x * 4 + i];
             *      }
             *  }
             * }
             */

            return(buffer);
        }
예제 #8
0
 public RendererPass(int maxtexels)
 {
     g = new GraphicsHelperGl();
     //texturestages = new TextureStage[maxtexels];
     this.maxtexels = maxtexels;
 }
예제 #9
0
 public RendererPass(int maxtexels)
 {
     g = new GraphicsHelperGl();
     //texturestages = new TextureStage[maxtexels];
     this.maxtexels = maxtexels;
 }
예제 #10
0
        // applies texture stage setup to gl.  texturestagenum will be 0 except for blend
        // where it will be either 0 or 1
        // texture coordinates are handled independently (?)
        // either we're using multipass or we're using multitexture.  multipass still uses 2 multitexture units, but not 4, 6, 8, ...
        public void Apply(int texturestagenum, bool UsingMultipass, int mapwidth, int mapheight)
        {
            //Console.WriteLine("Apply");
            GlTextureCombine texturecombine;
            GraphicsHelperGl g = new GraphicsHelperGl();

            switch (Operation)
            {
            case OperationType.NoTexture:
                g.DisableTexture2d();
                g.EnableModulate();
                break;

            case OperationType.Add:
                texture.Apply();
                SetTextureScale(1 / (double)Tilesize);
                texturecombine           = new GlTextureCombine();
                texturecombine.Operation = GlTextureCombine.OperationType.Add;
                texturecombine.Args[0].SetRgbaSource(GlCombineArg.Source.Previous);
                texturecombine.Args[1].SetRgbaSource(GlCombineArg.Source.Texture);
                texturecombine.Apply();
                break;

            case OperationType.Blend:
                if (UsingMultipass)
                {
                    if (texturestagenum == 0)
                    {
                        blendtexture.Apply();
                        SetTextureScale(1 / (double)mapwidth);
                        texturecombine           = new GlTextureCombine();
                        texturecombine.Operation = GlTextureCombine.OperationType.Replace;
                        texturecombine.Args[0].SetAlphaSource(GlCombineArg.Source.Texture, GlCombineArg.Operand.Alpha);
                        texturecombine.Apply();
                    }
                    else
                    {
                        texture.Apply();
                        SetTextureScale(1 / (double)Tilesize);
                        new GraphicsHelperGl().EnableModulate();
                    }
                }
                else
                {
                    if (texturestagenum == 0)
                    {
                        blendtexture.Apply();
                        SetTextureScale(1 / (double)mapwidth);
                        texturecombine           = new GlTextureCombine();
                        texturecombine.Operation = GlTextureCombine.OperationType.Replace;
                        texturecombine.Args[0].SetRgbSource(GlCombineArg.Source.Previous, GlCombineArg.Operand.Rgb);
                        texturecombine.Args[0].SetAlphaSource(GlCombineArg.Source.Texture, GlCombineArg.Operand.Alpha);
                        texturecombine.Apply();
                    }
                    else
                    {
                        texture.Apply();
                        SetTextureScale(1 / (double)Tilesize);
                        texturecombine           = new GlTextureCombine();
                        texturecombine.Operation = GlTextureCombine.OperationType.Interpolate;
                        texturecombine.Args[0].SetRgbaSource(GlCombineArg.Source.Previous);
                        texturecombine.Args[1].SetRgbaSource(GlCombineArg.Source.Texture);
                        texturecombine.Args[2].SetRgbSource(GlCombineArg.Source.Previous, GlCombineArg.Operand.Alpha);
                        texturecombine.Args[2].SetAlphaSource(GlCombineArg.Source.Previous, GlCombineArg.Operand.Alpha);
                        texturecombine.Apply();
                    }
                }
                break;

            case OperationType.Multiply:
                texture.Apply();
                SetTextureScale(1 / (double)Tilesize);
                texturecombine           = new GlTextureCombine();
                texturecombine.Operation = GlTextureCombine.OperationType.Modulate;
                texturecombine.Args[0].SetRgbaSource(GlCombineArg.Source.Previous);
                texturecombine.Args[1].SetRgbaSource(GlCombineArg.Source.Texture);
                texturecombine.Apply();
                break;

            case OperationType.Subtract:
                texture.Apply();
                SetTextureScale(1 / (double)Tilesize);
                texturecombine           = new GlTextureCombine();
                texturecombine.Operation = GlTextureCombine.OperationType.Subtract;
                texturecombine.Args[0].SetRgbaSource(GlCombineArg.Source.Previous);
                texturecombine.Args[1].SetRgbaSource(GlCombineArg.Source.Texture);
                texturecombine.Apply();
                break;

            case OperationType.Replace:
                texture.Apply();
                SetTextureScale(1 / (double)Tilesize);
                texturecombine           = new GlTextureCombine();
                texturecombine.Operation = GlTextureCombine.OperationType.Modulate;
                texturecombine.Args[0].SetRgbaSource(GlCombineArg.Source.Texture);
                texturecombine.Args[1].SetRgbaSource(GlCombineArg.Source.Fragment);
                texturecombine.Apply();
                break;
            }
        }
예제 #11
0
        // renders to 0,0,0 ; size will be (mapwidth + 1) * xscale by (mapheight + 1) * yscale
        public void Render(Vector3 camerapos)
        {
            //ExportAsSingleTexture.GetInstance().Export("");

            Gl.glPushMatrix();
            FrustrumCulling culling = FrustrumCulling.GetInstance();
            //IGraphicsHelper g = GraphicsHelperFactory.GetInstance();
            GraphicsHelperGl g = new GraphicsHelperGl();

            int iSectorsDrawn = 0;
            int iChunkDrawsSkippedNoTextureSection = 0;

            int numxchunks = width / chunksize;
            int numychunks = height / chunksize;

            double chunkboundingradius = chunksize * xscale * 1.414 / 2;

            //Console.WriteLine("chunkboundingradius: " + chunkboundingradius);

            g.SetMaterialColor(new Color(1.0, 1.0, 1.0));

            Gl.glDepthFunc(Gl.GL_LEQUAL);
            g.EnableBlendSrcAlpha();

            foreach (RendererPass rendererpass in rendererpasses)
            {
                rendererpass.Apply();
                for (int chunkx = 0; chunkx < numxchunks - 1; chunkx++)
                {
                    for (int chunky = 0; chunky < numychunks - 1; chunky++)
                    {
                        if (chunkusestexturestage[rendererpass.texturestages[0].maptexturestage][chunkx, chunky])
                        {
                            //if (iSectorsDrawn == 0)
                            //{
                            int     chunkmapposx          = chunkx * chunksize;
                            int     chunkmapposy          = chunky * chunksize;
                            int     chunkdisplayposx      = chunkmapposx * xscale;
                            int     chunkdisplayposy      = chunkmapposy * yscale;
                            Vector3 chunkmappos           = new Vector3(chunkmapposx, chunkmapposy, heightmap[chunkmapposx, chunkmapposy]);
                            Vector3 chunkdisplaypos       = new Vector3(chunkdisplayposx, chunkdisplayposy, heightmap[chunkmapposx, chunkmapposy]);
                            Vector3 chunkcentredisplaypos = chunkdisplaypos +
                                                            new Vector3(chunksize * xscale / 2, chunksize * yscale / 2, 0);
                            if (culling.IsInsideFrustum(chunkcentredisplaypos, chunkboundingradius))
                            {
                                iSectorsDrawn++;

                                // check how far away sector is
                                // if nearby we render it in detail
                                // otherwise just render a few points from it
                                double distancesquared = Vector3.DistanceSquared(chunkcentredisplaypos, camerapos);
                                //if ( distancesquared > detaildistance * detaildistance)
                                int stepsize = 16;
                                if (distancesquared < loddistances[0] * loddistances[0])
                                {
                                    stepsize = 1;
                                }
                                else if (distancesquared < loddistances[1] * loddistances[2])
                                {
                                    stepsize = 2;
                                }
                                else if (distancesquared < loddistances[3] * loddistances[3])
                                {
                                    stepsize = 4;
                                }
                                else if (distancesquared < loddistances[4] * loddistances[4])
                                {
                                    stepsize = 8;
                                }
                                else if (distancesquared < loddistances[5] * loddistances[5])
                                {
                                    stepsize = 16;
                                }

                                RenderChunk(chunkx, chunky, stepsize);
                            }
                        }
                        else
                        {
                            iChunkDrawsSkippedNoTextureSection++;
                        }
                        // System.Environment.Exit(1);
                    }
                }
                //Gl.glTranslated(0, 0, 500);
            }
            //System.Environment.Exit(0);
            //Console.WriteLine("chunk renders: " + iSectorsDrawn + " maptextureculls: " + iChunkDrawsSkippedNoTextureSection);
            for (int i = maxtexels - 1; i >= 0; i--)
            {
                g.ActiveTexture(i);
                g.SetTextureScale(1);
                g.DisableTexture2d();
            }
            Gl.glDepthFunc(Gl.GL_LESS);
            Gl.glDisable(Gl.GL_BLEND);
            g.EnableModulate();
            Gl.glPopMatrix();
        }
예제 #12
0
        // what we need to do is to render the splatted texture in ortho mode with lighting off
        // or normals off (to be tested)
        // then to export the generated bitmap
        // viewport should be set to heightmapwidth x heightmapheight
        public void Export(string filepath)
        {
            Terrain terrain       = Terrain.GetInstance();
            int     picturewidth  = terrain.MapWidth * Terrain.SquareSize;
            int     pictureheight = terrain.MapHeight * Terrain.SquareSize;

            LogFile.GetInstance().WriteLine("Export to " + filepath + " picturewidth " + picturewidth + " pictureheight: " + pictureheight);
            //int windowwidth = RendererSdl.GetInstance().WindowWidth;
            //int windowheight = RendererSdl.GetInstance().WindowHeight;
            int windowwidth  = 256;
            int windowheight = 256;

            Gl.glViewport(0, 0, windowwidth, windowheight);

            byte[] buffer = new byte[windowwidth * windowheight * 4];
            //System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap( picturewidth, pictureheight );
            //byte[] imagedata = new byte[picturewidth * pictureheight * 4];
            Image image = new Image(picturewidth, pictureheight);

            List <RendererPass> rendererpasses = new List <RendererPass>();
            bool multipass = true; // force multipass for now for simplicity
            int  maxtexels = RendererSdl.GetInstance().MaxTexelUnits;

            if (multipass)
            {
                for (int i = 0; i < terrain.texturestages.Count; i++)
                {
                    MapTextureStage maptexturestage          = terrain.texturestages[i];
                    int             numtexturestagesrequired = maptexturestage.NumTextureStagesRequired;
                    if (numtexturestagesrequired > 0) // exclude Nops
                    {
                        RendererPass rendererpass = new RendererPass(maxtexels);
                        for (int j = 0; j < maptexturestage.NumTextureStagesRequired; j++)
                        {
                            rendererpass.AddStage(new RendererTextureStage(maptexturestage, j, true, picturewidth, pictureheight));
                        }
                        rendererpasses.Add(rendererpass);
                    }
                }
            }

            GraphicsHelperGl g = new GraphicsHelperGl();

            Gl.glMatrixMode(Gl.GL_PROJECTION);
            Gl.glPushMatrix();
            Gl.glLoadIdentity();
            Gl.glOrtho(0, windowwidth, windowheight, 0, -1, 1);

            Gl.glMatrixMode(Gl.GL_MODELVIEW);
            Gl.glPushMatrix();
            Gl.glLoadIdentity();

            Gl.glDisable(Gl.GL_CULL_FACE);
            Gl.glDisable(Gl.GL_LIGHTING);

            g.EnableBlendSrcAlpha();
            Gl.glDepthFunc(Gl.GL_LEQUAL);

            for (int chunkx = 0; chunkx < Math.Ceiling((double)picturewidth / windowwidth); chunkx++)
            {
                for (int chunky = 0; chunky < Math.Ceiling((double)pictureheight / windowheight); chunky++)
                {
                    Console.WriteLine("chunkx " + chunkx + " chunky " + chunky);

                    Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);                // Clear The Screen And Depth Buffer

                    foreach (RendererPass rendererpass in rendererpasses)
                    {
                        rendererpass.Apply();

                        Gl.glBegin(Gl.GL_QUADS);

                        double ul = (chunkx * windowwidth);
                        double ur = (chunkx * windowwidth + windowwidth);
                        double vt = (chunky * windowheight);
                        double vb = (chunky * windowheight + windowheight);
                        Gl.glTexCoord2d(ul, vt);
                        Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB, ul, vt);
                        Gl.glVertex2i(0, 0);

                        Gl.glTexCoord2d(ul, vb);
                        Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB, ul, vb);
                        Gl.glVertex2i(0, windowheight);

                        Gl.glTexCoord2d(ur, vb);
                        Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB, ur, vb);
                        Gl.glVertex2i(windowwidth, windowheight);

                        Gl.glTexCoord2d(ur, vt);
                        Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB, ur, vt);
                        Gl.glVertex2i(windowwidth, 0);

                        Gl.glEnd();
                    }

                    IntPtr ptr = Marshal.AllocHGlobal(windowwidth * windowheight * 4);
                    Gl.glReadPixels(0, 0, windowwidth, windowheight, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, ptr);
                    Marshal.Copy(ptr, buffer, 0, windowwidth * windowheight * 4);
                    Marshal.FreeHGlobal(ptr);

                    for (int x = 0; x < windowwidth; x++)
                    {
                        for (int y = 0; y < windowheight; y++)
                        {
                            if ((chunky * windowheight + y < pictureheight) &&
                                (chunkx * windowwidth + x < picturewidth))
                            {
                                int pixeloffset = (windowheight - y - 1) * windowwidth * 4 + x * 4;
                                //bitmap.SetPixel(x + chunkx * windowwidth, y + chunky * windowheight, System.Drawing.Color.FromArgb(buffer[pixeloffset + 0],
                                //buffer[pixeloffset + 1], buffer[pixeloffset + 2]));
                                image.SetPixel(x + chunkx * windowwidth, y + chunky * windowheight,
                                               buffer[pixeloffset + 0],
                                               buffer[pixeloffset + 1],
                                               buffer[pixeloffset + 2],
                                               255
                                               );
                            }
                        }
                    }
                }
            }
            if (File.Exists(filepath))
            {
                File.Delete(filepath);
            }
            image.Save(filepath);
            //DevIL.DevIL.SaveBitmap( filepath, bitmap);

            Gl.glPopMatrix();
            Gl.glMatrixMode(Gl.GL_PROJECTION);
            Gl.glPopMatrix();
            Gl.glMatrixMode(Gl.GL_MODELVIEW);

            Gl.glEnable(Gl.GL_LIGHTING);

            g.ActiveTexture(1);
            g.DisableTexture2d();
            g.SetTextureScale(1);
            g.ActiveTexture(0);
            g.SetTextureScale(1);

            Gl.glEnable(Gl.GL_CULL_FACE);
            Gl.glEnable(Gl.GL_LIGHTING);
            Gl.glDisable(Gl.GL_BLEND);

            g.EnableModulate();

            Gl.glViewport(0, 0, RendererSdl.GetInstance().OuterWindowWidth, RendererSdl.GetInstance().OuterWindowHeight);
            g.CheckError();

            MainUI.GetInstance().uiwindow.InfoMessage("Exported blended terrain texture to " + filepath);
        }
예제 #13
0
        // note to self: move this to subscriber?
        void DrawMinimap()
        {
            Terrain terrain = Terrain.GetInstance();

            if (DateTime.Now.Subtract(LastMinimapUpdate).TotalMilliseconds > 1000)
            //if( true )
            {
                List <RendererPass> rendererpasses = new List <RendererPass>();
                bool multipass = true; // force multipass for now for simplicity
                int  maxtexels = RendererSdl.GetInstance().MaxTexelUnits;
                if (multipass)
                {
                    for (int i = 0; i < terrain.texturestages.Count; i++)
                    {
                        MapTextureStage maptexturestage          = terrain.texturestages[i];
                        int             numtexturestagesrequired = maptexturestage.NumTextureStagesRequired;
                        if (numtexturestagesrequired > 0) // exclude Nops
                        {
                            RendererPass rendererpass = new RendererPass(maxtexels);
                            for (int j = 0; j < maptexturestage.NumTextureStagesRequired; j++)
                            {
                                rendererpass.AddStage(new RendererTextureStage(maptexturestage, j, true, mapwidth * Terrain.SquareSize, mapheight * Terrain.SquareSize));
                            }
                            rendererpasses.Add(rendererpass);
                        }
                    }
                }

                GraphicsHelperGl g = new GraphicsHelperGl();

                //g.ApplyOrtho(windowwidth, windowheight, RendererSdl.GetInstance().OuterWindowWidth, RendererSdl.GetInstance().OuterWindowHeight);

                g.EnableBlendSrcAlpha();
                Gl.glDepthFunc(Gl.GL_LEQUAL);

                int chunkwidth  = minimapwidth / numchunks;
                int chunkheight = minimapheight / numchunks;

                float[] ambientLight  = new float[] { 0.4f, 0.4f, 0.4f, 1.0f };
                float[] diffuseLight  = new float[] { 0.6f, 0.6f, 0.6f, 1.0f };
                float[] specularLight = new float[] { 0.2f, 0.2f, 0.2f, 1.0f };
                float[] position      = new float[] { -1.0f, 0.2f, -0.4f, 1.0f };

                Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_AMBIENT, ambientLight);
                Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_DIFFUSE, diffuseLight);
                Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_SPECULAR, specularLight);
                Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, position);

                foreach (RendererPass rendererpass in rendererpasses)
                {
                    rendererpass.Apply();

                    for (int x = 0; x + chunkwidth < minimapwidth; x += chunkwidth)
                    {
                        for (int y = 0; y + chunkheight < minimapheight; y += chunkheight)
                        {
                            Gl.glBegin(Gl.GL_QUADS);

                            //double ul = 0;
                            //double ur = mapwidth * Terrain.SquareSize;
                            //double vt = 0;
                            //double vb = mapheight * Terrain.SquareSize;
                            double ul = (double)x / minimapwidth * mapwidth * Terrain.SquareSize;
                            double ur = (double)(x + chunkwidth) / minimapwidth * mapwidth * Terrain.SquareSize;
                            double vt = (double)y / minimapheight * mapheight * Terrain.SquareSize;
                            double vb = (double)(y + chunkheight) / minimapheight * mapheight * Terrain.SquareSize;

                            double xl = minimapx + x;
                            double xr = minimapx + x + minimapwidth / (double)numchunks;
                            double yt = minimapy + y;
                            double yb = minimapy + y + minimapheight / (double)numchunks;

                            Gl.glTexCoord2d(ul, vt);
                            Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB, ul, vt);
                            g.Normal(renderableheightmap.GetNormal(x * mapwidth / minimapwidth, y * mapheight / minimapheight));
                            //g.Normal(renderableheightmap.normalsperquad[, ]);
                            Gl.glVertex2d(xl, yt);

                            Gl.glTexCoord2d(ul, vb);
                            Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB, ul, vb);
                            g.Normal(renderableheightmap.GetNormal(x * mapwidth / minimapwidth, (y + chunkheight) * mapheight / minimapheight));
                            //g.Normal( renderableheightmap.normalsperquad[x * mapwidth / minimapwidth, (y + 1) * mapheight / minimapheight ] );
                            Gl.glVertex2d(xl, yb);

                            Gl.glTexCoord2d(ur, vb);
                            Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB, ur, vb);
                            g.Normal(renderableheightmap.GetNormal((x + chunkwidth) * mapwidth / minimapwidth, (y + chunkheight) * mapheight / minimapheight));
                            //g.Normal(renderableheightmap.normalsperquad[(x + 1) * mapwidth / minimapwidth, (y + 1) * mapheight / minimapheight]);
                            Gl.glVertex2d(xr, yb);

                            Gl.glTexCoord2d(ur, vt);
                            Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB, ur, vt);
                            g.Normal(renderableheightmap.GetNormal((x + chunkwidth) * mapwidth / minimapwidth, y * mapheight / minimapheight));
                            //g.Normal(renderableheightmap.normalsperquad[(x + 1) * mapwidth / minimapwidth, y * mapheight / minimapheight]);
                            Gl.glVertex2d(xr, yt);

                            Gl.glEnd();
                        }
                    }
                }

                g.ActiveTexture(0);
                Gl.glBindTexture(Gl.GL_TEXTURE_2D, minimaptexture);
                Gl.glCopyTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA8, minimapx,
                                    RendererSdl.GetInstance().InnerWindowHeight - minimapy - minimapsize,
                                    minimapsize, minimapsize, 0);
                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST);
                LastMinimapUpdate = DateTime.Now;

//                g.RemoveOrtho();

                g.ActiveTexture(1);
                g.DisableTexture2d();
                g.SetTextureScale(1);
                g.ActiveTexture(0);
                g.SetTextureScale(1);

                g.EnableModulate();

                Gl.glDisable(Gl.GL_BLEND);
            }
            else
            {
                GraphicsHelperGl g = new GraphicsHelperGl();

                //Gl.glMatrixMode(Gl.GL_PROJECTION);
                //Gl.glPushMatrix();
                //Gl.glLoadIdentity();
                //Gl.glOrtho(0, windowwidth, windowheight - RendererSdl.GetInstance().OuterWindowHeight, 0, -1, 1); // we'll just draw the minimap directly onto our display
                //Gl.glOrtho(0, windowwidth, windowheight, windowheight - RendererSdl.GetInstance().OuterWindowHeight, -1, 1); // we'll just draw the minimap directly onto our display

                //Gl.glMatrixMode(Gl.GL_MODELVIEW);
                //Gl.glPushMatrix();
                //Gl.glLoadIdentity();

                g.ActiveTexture(0);
                g.EnableTexture2d();
                Gl.glBindTexture(Gl.GL_TEXTURE_2D, minimaptexture);
                //Gl.glBindTexture(Gl.GL_TEXTURE_2D, (terrain.texturestages[0].texture as GlTexture).GlReference);
                Gl.glDisable(Gl.GL_LIGHTING);
                Gl.glBegin(Gl.GL_QUADS);

                Gl.glTexCoord2d(0, 1);
                Gl.glVertex2i(minimapx, minimapy);

                Gl.glTexCoord2d(0, 1 - minimapwidth / (double)minimapsize);
                Gl.glVertex2i(minimapx, minimapy + minimapheight);

                Gl.glTexCoord2d(minimapwidth / (double)minimapsize, 1 - minimapheight / (double)minimapsize);
                Gl.glVertex2i(minimapx + minimapwidth, minimapy + minimapheight);

                Gl.glTexCoord2d(minimapwidth / (double)minimapsize, 1);
                Gl.glVertex2i(minimapx + minimapwidth, minimapy);

                Gl.glEnd();

                Gl.glEnable(Gl.GL_LIGHTING);

                //Gl.glMatrixMode(Gl.GL_PROJECTION);
                //Gl.glPopMatrix();
                //Gl.glMatrixMode(Gl.GL_MODELVIEW);
                //Gl.glPopMatrix();
            }
        }
        // note to self: move this to subscriber?
        void DrawMinimap()
        {
            Terrain terrain = Terrain.GetInstance();

            if (DateTime.Now.Subtract(LastMinimapUpdate).TotalMilliseconds > 1000)
            //if( true )
            {
                List<RendererPass> rendererpasses = new List<RendererPass>();
                bool multipass = true; // force multipass for now for simplicity
                int maxtexels = RendererSdl.GetInstance().MaxTexelUnits;
                if (multipass)
                {
                    for (int i = 0; i < terrain.texturestages.Count; i++)
                    {
                        MapTextureStage maptexturestage = terrain.texturestages[i];
                        int numtexturestagesrequired = maptexturestage.NumTextureStagesRequired;
                        if (numtexturestagesrequired > 0) // exclude Nops
                        {
                            RendererPass rendererpass = new RendererPass(maxtexels);
                            for (int j = 0; j < maptexturestage.NumTextureStagesRequired; j++)
                            {
                                rendererpass.AddStage(new RendererTextureStage(maptexturestage, j, true, mapwidth * Terrain.SquareSize, mapheight * Terrain.SquareSize));
                            }
                            rendererpasses.Add(rendererpass);
                        }
                    }
                }

                GraphicsHelperGl g = new GraphicsHelperGl();

                //g.ApplyOrtho(windowwidth, windowheight, RendererSdl.GetInstance().OuterWindowWidth, RendererSdl.GetInstance().OuterWindowHeight);

                g.EnableBlendSrcAlpha();
                Gl.glDepthFunc(Gl.GL_LEQUAL);

                int chunkwidth = minimapwidth / numchunks;
                int chunkheight = minimapheight / numchunks;

                float[] ambientLight = new float[] { 0.4f, 0.4f, 0.4f, 1.0f };
                float[] diffuseLight = new float[] { 0.6f, 0.6f, 0.6f, 1.0f };
                float[] specularLight = new float[] { 0.2f, 0.2f, 0.2f, 1.0f };
                float[] position = new float[] { -1.0f, 0.2f, -0.4f, 1.0f };

                Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_AMBIENT, ambientLight);
                Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_DIFFUSE, diffuseLight);
                Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_SPECULAR, specularLight);
                Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, position);

                foreach (RendererPass rendererpass in rendererpasses)
                {
                    rendererpass.Apply();

                    for (int x = 0; x + chunkwidth < minimapwidth; x += chunkwidth)
                    {
                        for (int y = 0; y + chunkheight < minimapheight; y += chunkheight)
                        {
                            Gl.glBegin(Gl.GL_QUADS);

                            //double ul = 0;
                            //double ur = mapwidth * Terrain.SquareSize;
                            //double vt = 0;
                            //double vb = mapheight * Terrain.SquareSize;
                            double ul = (double)x / minimapwidth * mapwidth * Terrain.SquareSize;
                            double ur = (double)(x + chunkwidth) / minimapwidth * mapwidth * Terrain.SquareSize;
                            double vt = (double)y / minimapheight * mapheight * Terrain.SquareSize;
                            double vb = (double)(y + chunkheight) / minimapheight * mapheight * Terrain.SquareSize;

                            double xl = minimapx + x;
                            double xr = minimapx + x + minimapwidth / (double)numchunks;
                            double yt = minimapy + y;
                            double yb = minimapy + y + minimapheight / (double)numchunks;

                            Gl.glTexCoord2d(ul, vt);
                            Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB, ul, vt);
                            g.Normal(renderableheightmap.GetNormal(x * mapwidth / minimapwidth, y * mapheight / minimapheight));
                            //g.Normal(renderableheightmap.normalsperquad[, ]);
                            Gl.glVertex2d(xl, yt);

                            Gl.glTexCoord2d(ul, vb);
                            Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB, ul, vb);
                            g.Normal(renderableheightmap.GetNormal(x * mapwidth / minimapwidth, (y + chunkheight) * mapheight / minimapheight));
                            //g.Normal( renderableheightmap.normalsperquad[x * mapwidth / minimapwidth, (y + 1) * mapheight / minimapheight ] );
                            Gl.glVertex2d(xl, yb);

                            Gl.glTexCoord2d(ur, vb);
                            Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB, ur, vb);
                            g.Normal(renderableheightmap.GetNormal((x + chunkwidth) * mapwidth / minimapwidth, (y + chunkheight) * mapheight / minimapheight));
                            //g.Normal(renderableheightmap.normalsperquad[(x + 1) * mapwidth / minimapwidth, (y + 1) * mapheight / minimapheight]);
                            Gl.glVertex2d(xr, yb);

                            Gl.glTexCoord2d(ur, vt);
                            Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB, ur, vt);
                            g.Normal(renderableheightmap.GetNormal((x + chunkwidth) * mapwidth / minimapwidth, y * mapheight / minimapheight));
                            //g.Normal(renderableheightmap.normalsperquad[(x + 1) * mapwidth / minimapwidth, y * mapheight / minimapheight]);
                            Gl.glVertex2d(xr, yt);

                            Gl.glEnd();
                        }
                    }
                }

                g.ActiveTexture(0);
                Gl.glBindTexture(Gl.GL_TEXTURE_2D, minimaptexture);
                Gl.glCopyTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA8, minimapx,
                    RendererSdl.GetInstance().InnerWindowHeight - minimapy - minimapsize,
                    minimapsize, minimapsize, 0);
                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST);
                LastMinimapUpdate = DateTime.Now;

            //                g.RemoveOrtho();

                g.ActiveTexture(1);
                g.DisableTexture2d();
                g.SetTextureScale(1);
                g.ActiveTexture(0);
                g.SetTextureScale(1);

                g.EnableModulate();

                Gl.glDisable(Gl.GL_BLEND);
            }
            else
            {
                GraphicsHelperGl g = new GraphicsHelperGl();

                //Gl.glMatrixMode(Gl.GL_PROJECTION);
                //Gl.glPushMatrix();
                //Gl.glLoadIdentity();
                //Gl.glOrtho(0, windowwidth, windowheight - RendererSdl.GetInstance().OuterWindowHeight, 0, -1, 1); // we'll just draw the minimap directly onto our display
                //Gl.glOrtho(0, windowwidth, windowheight, windowheight - RendererSdl.GetInstance().OuterWindowHeight, -1, 1); // we'll just draw the minimap directly onto our display

                //Gl.glMatrixMode(Gl.GL_MODELVIEW);
                //Gl.glPushMatrix();
                //Gl.glLoadIdentity();

                g.ActiveTexture(0);
                g.EnableTexture2d();
                Gl.glBindTexture(Gl.GL_TEXTURE_2D, minimaptexture);
                //Gl.glBindTexture(Gl.GL_TEXTURE_2D, (terrain.texturestages[0].texture as GlTexture).GlReference);
                Gl.glDisable(Gl.GL_LIGHTING);
                Gl.glBegin(Gl.GL_QUADS);

                Gl.glTexCoord2d(0, 1);
                Gl.glVertex2i(minimapx, minimapy);

                Gl.glTexCoord2d(0, 1 - minimapwidth / (double)minimapsize);
                Gl.glVertex2i(minimapx, minimapy + minimapheight);

                Gl.glTexCoord2d(minimapwidth / (double)minimapsize, 1 - minimapheight / (double)minimapsize);
                Gl.glVertex2i(minimapx + minimapwidth, minimapy + minimapheight);

                Gl.glTexCoord2d(minimapwidth / (double)minimapsize, 1);
                Gl.glVertex2i(minimapx + minimapwidth, minimapy);

                Gl.glEnd();

                Gl.glEnable(Gl.GL_LIGHTING);

                //Gl.glMatrixMode(Gl.GL_PROJECTION);
                //Gl.glPopMatrix();
                //Gl.glMatrixMode(Gl.GL_MODELVIEW);
                //Gl.glPopMatrix();
            }
        }
        void RenderableMinimap_WriteNextFrameEvent(Vector3 camerapos)
        {
            //Console.WriteLine( "RenderableMinimap_WriteNextFrameEvent" );
            GetDimensions();

            GraphicsHelperGl g = new GraphicsHelperGl();
            g.CheckError();
            //LogFile.GetInstance().WriteLine( windowwidth + " " + windowheight + " " + RendererSdl.GetInstance().OuterWindowWidth + " " + RendererSdl.GetInstance().OuterWindowHeight );
            g.ApplyOrtho( windowwidth, windowheight, RendererSdl.GetInstance().OuterWindowWidth, RendererSdl.GetInstance().OuterWindowHeight );
            g.CheckError();
            DrawMinimap();
            g.CheckError();
            DrawFrustrum(camerapos);
            g.CheckError();
            if (Render != null)
            {
                Render(minimapx, minimapy, minimapwidth, minimapheight);
            }
            g.CheckError();
            g.RemoveOrtho();
            g.CheckError();
        }
 // applies texture stage setup to gl.  texturestagenum will be 0 except for blend
 // where it will be either 0 or 1
 // texture coordinates are handled independently (?)
 // either we're using multipass or we're using multitexture.  multipass still uses 2 multitexture units, but not 4, 6, 8, ...
 public void Apply(int texturestagenum, bool UsingMultipass, int mapwidth, int mapheight)
 {
     //Console.WriteLine("Apply");
     GlTextureCombine texturecombine;
     GraphicsHelperGl g = new GraphicsHelperGl();
     switch (Operation)
     {
         case OperationType.NoTexture:
             g.DisableTexture2d();
             g.EnableModulate();
             break;
         case OperationType.Add:
             texture.Apply();
             SetTextureScale(1 / (double)Tilesize);
             texturecombine = new GlTextureCombine();
             texturecombine.Operation = GlTextureCombine.OperationType.Add;
             texturecombine.Args[0].SetRgbaSource(GlCombineArg.Source.Previous);
             texturecombine.Args[1].SetRgbaSource(GlCombineArg.Source.Texture);
             texturecombine.Apply();
             break;
         case OperationType.Blend:
             if (UsingMultipass)
             {
                 if (texturestagenum == 0)
                 {
                     blendtexture.Apply();
                     SetTextureScale(1 / (double)mapwidth);
                     texturecombine = new GlTextureCombine();
                     texturecombine.Operation = GlTextureCombine.OperationType.Replace;
                     texturecombine.Args[0].SetAlphaSource(GlCombineArg.Source.Texture, GlCombineArg.Operand.Alpha);
                     texturecombine.Apply();
                 }
                 else
                 {
                     texture.Apply();
                     SetTextureScale(1 / (double)Tilesize);
                     new GraphicsHelperGl().EnableModulate();
                 }
             }
             else
             {
                 if (texturestagenum == 0)
                 {
                     blendtexture.Apply();
                     SetTextureScale(1 / (double)mapwidth);
                     texturecombine = new GlTextureCombine();
                     texturecombine.Operation = GlTextureCombine.OperationType.Replace;
                     texturecombine.Args[0].SetRgbSource(GlCombineArg.Source.Previous, GlCombineArg.Operand.Rgb);
                     texturecombine.Args[0].SetAlphaSource(GlCombineArg.Source.Texture, GlCombineArg.Operand.Alpha);
                     texturecombine.Apply();
                 }
                 else
                 {
                     texture.Apply();
                     SetTextureScale(1 / (double)Tilesize);
                     texturecombine = new GlTextureCombine();
                     texturecombine.Operation = GlTextureCombine.OperationType.Interpolate;
                     texturecombine.Args[0].SetRgbaSource(GlCombineArg.Source.Previous);
                     texturecombine.Args[1].SetRgbaSource(GlCombineArg.Source.Texture);
                     texturecombine.Args[2].SetRgbSource(GlCombineArg.Source.Previous, GlCombineArg.Operand.Alpha);
                     texturecombine.Args[2].SetAlphaSource(GlCombineArg.Source.Previous, GlCombineArg.Operand.Alpha);
                     texturecombine.Apply();
                 }
             }
             break;
         case OperationType.Multiply:
             texture.Apply();
             SetTextureScale(1 / (double)Tilesize);
             texturecombine = new GlTextureCombine();
             texturecombine.Operation = GlTextureCombine.OperationType.Modulate;
             texturecombine.Args[0].SetRgbaSource(GlCombineArg.Source.Previous);
             texturecombine.Args[1].SetRgbaSource(GlCombineArg.Source.Texture);
             texturecombine.Apply();
             break;
         case OperationType.Subtract:
             texture.Apply();
             SetTextureScale(1 / (double)Tilesize);
             texturecombine = new GlTextureCombine();
             texturecombine.Operation = GlTextureCombine.OperationType.Subtract;
             texturecombine.Args[0].SetRgbaSource(GlCombineArg.Source.Previous);
             texturecombine.Args[1].SetRgbaSource(GlCombineArg.Source.Texture);
             texturecombine.Apply();
             break;
         case OperationType.Replace:
             texture.Apply();
             SetTextureScale(1 / (double)Tilesize);
             texturecombine = new GlTextureCombine();
             texturecombine.Operation = GlTextureCombine.OperationType.Modulate;
             texturecombine.Args[0].SetRgbaSource(GlCombineArg.Source.Texture);
             texturecombine.Args[1].SetRgbaSource(GlCombineArg.Source.Fragment);
             texturecombine.Apply();
             break;
     }
 }
        // what we need to do is to render the splatted texture in ortho mode with lighting off
        // or normals off (to be tested)
        // then to export the generated bitmap
        // viewport should be set to heightmapwidth x heightmapheight
        public void Export(string filepath)
        {
            Terrain terrain = Terrain.GetInstance();
            int picturewidth = terrain.MapWidth * Terrain.SquareSize;
            int pictureheight = terrain.MapHeight * Terrain.SquareSize;
            LogFile.GetInstance().WriteLine("Export to " + filepath + " picturewidth " + picturewidth + " pictureheight: " + pictureheight);
            //int windowwidth = RendererSdl.GetInstance().WindowWidth;
            //int windowheight = RendererSdl.GetInstance().WindowHeight;
            int windowwidth = 256;
            int windowheight = 256;

            Gl.glViewport(0, 0, windowwidth, windowheight);

            byte[] buffer = new byte[windowwidth * windowheight * 4];
            //System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap( picturewidth, pictureheight );
            //byte[] imagedata = new byte[picturewidth * pictureheight * 4];
            Image image = new Image(picturewidth, pictureheight);

            List<RendererPass> rendererpasses = new List<RendererPass>();
            bool multipass = true; // force multipass for now for simplicity
            int maxtexels = RendererSdl.GetInstance().MaxTexelUnits;
            if (multipass)
            {
                for (int i = 0; i < terrain.texturestages.Count; i++)
                {
                    MapTextureStage maptexturestage = terrain.texturestages[i];
                    int numtexturestagesrequired = maptexturestage.NumTextureStagesRequired;
                    if (numtexturestagesrequired > 0) // exclude Nops
                    {
                        RendererPass rendererpass = new RendererPass(maxtexels);
                        for (int j = 0; j < maptexturestage.NumTextureStagesRequired; j++)
                        {
                            rendererpass.AddStage(new RendererTextureStage(maptexturestage, j, true, picturewidth, pictureheight));
                        }
                        rendererpasses.Add(rendererpass);
                    }
                }
            }

            GraphicsHelperGl g = new GraphicsHelperGl();

            Gl.glMatrixMode(Gl.GL_PROJECTION);
            Gl.glPushMatrix();
            Gl.glLoadIdentity();
            Gl.glOrtho(0, windowwidth, windowheight, 0, -1, 1);

            Gl.glMatrixMode(Gl.GL_MODELVIEW);
            Gl.glPushMatrix();
            Gl.glLoadIdentity();

            Gl.glDisable(Gl.GL_CULL_FACE);
            Gl.glDisable(Gl.GL_LIGHTING);

            g.EnableBlendSrcAlpha();
            Gl.glDepthFunc( Gl.GL_LEQUAL );

            for (int chunkx = 0; chunkx < Math.Ceiling((double)picturewidth / windowwidth); chunkx++)
            {
                for (int chunky = 0; chunky < Math.Ceiling((double)pictureheight / windowheight); chunky++)
                {
                    Console.WriteLine("chunkx " + chunkx + " chunky " + chunky);

                    Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);		// Clear The Screen And Depth Buffer

                    foreach (RendererPass rendererpass in rendererpasses)
                    {
                        rendererpass.Apply();

                        Gl.glBegin(Gl.GL_QUADS);

                        double ul = (chunkx * windowwidth);
                        double ur = (chunkx * windowwidth + windowwidth);
                        double vt = (chunky * windowheight);
                        double vb = (chunky * windowheight + windowheight);
                        Gl.glTexCoord2d( ul,vt );
                        Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB,ul, vt);
                        Gl.glVertex2i(0, 0);

                        Gl.glTexCoord2d( ul,vb );
                        Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB,ul, vb);
                        Gl.glVertex2i(0, windowheight);

                        Gl.glTexCoord2d( ur,vb );
                        Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB,ur, vb);
                        Gl.glVertex2i(windowwidth, windowheight);

                        Gl.glTexCoord2d( ur,vt );
                        Gl.glMultiTexCoord2dARB(Gl.GL_TEXTURE1_ARB,ur, vt);
                        Gl.glVertex2i(windowwidth, 0);

                        Gl.glEnd();
                    }

                    IntPtr ptr = Marshal.AllocHGlobal(windowwidth * windowheight * 4);
                    Gl.glReadPixels(0, 0, windowwidth, windowheight, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, ptr);
                    Marshal.Copy(ptr, buffer, 0, windowwidth * windowheight * 4);
                    Marshal.FreeHGlobal(ptr);

                    for (int x = 0; x < windowwidth; x++)
                    {
                        for (int y = 0; y < windowheight; y++)
                        {
                            if ((chunky * windowheight + y < pictureheight) &&
                                (chunkx * windowwidth + x < picturewidth))
                            {
                                int pixeloffset = (windowheight - y - 1) * windowwidth * 4 + x * 4;
                                //bitmap.SetPixel(x + chunkx * windowwidth, y + chunky * windowheight, System.Drawing.Color.FromArgb(buffer[pixeloffset + 0],
                                    //buffer[pixeloffset + 1], buffer[pixeloffset + 2]));
                                image.SetPixel(x + chunkx * windowwidth, y + chunky * windowheight,
                                    buffer[pixeloffset + 0],
                                    buffer[pixeloffset + 1],
                                    buffer[pixeloffset + 2],
                                    255
                                    );
                            }
                        }
                    }
                }
            }
            if (File.Exists(filepath))
            {
                File.Delete(filepath);
            }
            image.Save(filepath);
            //DevIL.DevIL.SaveBitmap( filepath, bitmap);

            Gl.glPopMatrix();
            Gl.glMatrixMode(Gl.GL_PROJECTION);
            Gl.glPopMatrix();
            Gl.glMatrixMode(Gl.GL_MODELVIEW);

            Gl.glEnable(Gl.GL_LIGHTING);

            g.ActiveTexture(1);
            g.DisableTexture2d();
            g.SetTextureScale(1);
            g.ActiveTexture(0);
            g.SetTextureScale(1);

            Gl.glEnable(Gl.GL_CULL_FACE);
            Gl.glEnable(Gl.GL_LIGHTING);
            Gl.glDisable(Gl.GL_BLEND);

            g.EnableModulate();

            Gl.glViewport(0, 0, RendererSdl.GetInstance().OuterWindowWidth, RendererSdl.GetInstance().OuterWindowHeight);
            g.CheckError();

            MainUI.GetInstance().uiwindow.InfoMessage("Exported blended terrain texture to " + filepath);
        }
        // returns byte buffer in raw RGBA format, 32bits per pixel
        // opengl needs to be initialized for this to run
        // normally the renderer is initialized before anything else (in MapDesigner.cs), so this should be ok
        public byte[] CreateUnitPic(string s3ofilepath, int width, int height )
        {
            int picturewidth = 96;
            int pictureheight = 96;

            GraphicsHelperGl g = new GraphicsHelperGl();

            Unit unit = new S3oLoader().LoadS3o(s3ofilepath);

            Gl.glViewport(0, 0, picturewidth, pictureheight);					// Set Our Viewport (Match Texture Size)
            //Gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);				// Set The Clear Color To Medium Blue

            Gl.glMatrixMode(Gl.GL_PROJECTION);
            Gl.glPushMatrix();
            Gl.glLoadIdentity();
            Glu.gluPerspective(60.0, (float)picturewidth / (float)pictureheight, 0.1, 1000.0);
            Gl.glMatrixMode(Gl.GL_MODELVIEW);
            /*
            float[] ambientLight = new float[] { 1.0f, 1.0f, 1.0f, 1.0f };
            float[] diffuseLight = new float[] { 0.6f, 0.6f, 0.6f, 1.0f };
            float[] specularLight = new float[] { 0.2f, 0.2f, 0.2f, 1.0f };
            float[] position = new float[] { -1.5f, 1.0f, -4.0f, 1.0f };

            Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_AMBIENT, ambientLight);
            Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_DIFFUSE, diffuseLight);
            Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_SPECULAR, specularLight);
            Gl.glLightfv(Gl.GL_LIGHT0, Gl.GL_POSITION, position);
             */
            Gl.glClear(Gl.GL_COLOR_BUFFER_BIT | Gl.GL_DEPTH_BUFFER_BIT);		// Clear The Screen And Depth Buffer

            Gl.glPushMatrix();
            Gl.glLoadIdentity();

            Gl.glRotated(-20, 0, 1, 0);
            Gl.glTranslated(-8, -8, -27);

            Gl.glRotated(-90, 1, 0, 0);

            Gl.glEnable(Gl.GL_LIGHTING);

            unit.Render();

            Gl.glPopMatrix();
            //g.Bind2DTexture(0);
            //Gl.glDeleteTextures(2, new int[] { unittexture1, unittexture2 });
            Gl.glViewport(0, 0, RendererSdl.GetInstance().OuterWindowWidth, RendererSdl.GetInstance().OuterWindowHeight);
            Gl.glMatrixMode(Gl.GL_PROJECTION);
            Gl.glPopMatrix();
            Gl.glMatrixMode(Gl.GL_MODELVIEW);
            g.CheckError();

            byte[] buffer = new byte[pictureheight * picturewidth * 4];
            IntPtr ptr = Marshal.AllocHGlobal(picturewidth * pictureheight * 4);
            Gl.glReadPixels(0, 0, picturewidth, pictureheight, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, ptr);
            Marshal.Copy(ptr, buffer, 0, picturewidth * pictureheight * 4);
            Marshal.FreeHGlobal(ptr);

            // flip
            /* or not
            byte[] newbuffer = new byte[pictureheight * picturewidth * 4];
            for (int x = 0; x < picturewidth; x++)
            {
                for (int y = 0; y < picturewidth; y++)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        newbuffer[( pictureheight - y - 1 ) * picturewidth * 4 + x * 4 + i] = buffer[y * picturewidth * 4 + x * 4 + i];
                    }
                }
            }
             */

            return buffer;
        }