toonlenkens's picture

Need help with 2d tile-editor

Hi,

I'm creating a 2d tile-editor in Visual C# Express 2010 and I have some problems rendering the output. I'm using different jpg-images and render them based on a grid loaded from / saved to a csv-file (comma separated values). When the user clicks on the GLview it gets the position of the clicked tile based on view.width/height, tileWidth/tileHeight and mouse coordinates, then changes it's corresponding value in the grid to the selected texture.

I use the loadTexture function from the documentation-page. So far so good, it all works fine when i'm using a 16x16 grid but things are getting slow when i'm using a 128x128 grid...

The render process;

for (int i = 0; i < (gridSizeX / cellsizeX); i++){
   for (int j = 0; j < (gridSizeY / cellsizeY); j++)
   {
                    foreach (Texture t in referenceFile.refTextures)
                    {
                        if (t.getRefName() == grid.getVal(i, j))// && pGrid.getVal(i, j) != grid.getVal(i, j))
                        {
                            DrawTexture((j * (gridSizeX / cellsizeX)), (i * (gridSizeX / cellsizeX)), (gridSizeX / cellsizeX), (gridSizeX / cellsizeX), t);
                            break;
                        }
                    }
   }
renderTarget.SwapBuffers();
}

This is the drawTexture function

public void DrawTexture(int x, int y, int width, int height, Texture texture)
        {
            GL.MatrixMode(MatrixMode.Projection);
            GL.PushMatrix();
            GL.LoadIdentity();
 
            GL.Ortho(0, (width * height),(width * height), 0, -1, 1);
 
            GL.Disable(EnableCap.Lighting);
            GL.Enable(EnableCap.Texture2D);
 
            Console.WriteLine(texture.getId());
 
            GL.BindTexture(TextureTarget.Texture2D, texture.getId());
 
            GL.Begin(BeginMode.Quads);
 
            GL.TexCoord2(0, 0);
            GL.Vertex2(y, x);
 
            GL.TexCoord2(1, 0);
            GL.Vertex2(y + width, x);
 
            GL.TexCoord2(1, 1);
            GL.Vertex2(y + width, x + height);
 
            GL.TexCoord2(0, 1);
            GL.Vertex2(y, x + height);
 
            GL.End();
 
            GL.Disable(EnableCap.Texture2D);
            GL.PopMatrix();
 
            GL.MatrixMode(MatrixMode.Projection);
            GL.PopMatrix();
 
            GL.MatrixMode(MatrixMode.Modelview);
 
        }

Does anyone know how i can render more efficiently?


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
richardjmoss's picture

Before I start, bear in mind I'm no expert at this. I have a simple 2D engine which works fine, but that doesn't mean I know the best approach for this stuff either.

With that said, it looks to me like you're doing far far too much that you only need to do once.

Things like

GL.MatrixMode(MatrixMode.Projection);
GL.PushMatrix();
GL.LoadIdentity();
 
GL.Ortho(0, (width * height),(width * height), 0, -1, 1);
 
// snip
 
GL.PopMatrix();
 
GL.MatrixMode(MatrixMode.Projection);
GL.PopMatrix();
 
GL.MatrixMode(MatrixMode.Modelview);

Probably only need doing once per render frame.

GL.Disable(EnableCap.Lighting);
GL.Enable(EnableCap.Texture2D);

Probably only needs doing one at the start of a block of texture stuff. I'm not 100% clear on this though, and I can't remember offhand how I handle this in my own code.

GL.BindTexture(TextureTarget.Texture2D, texture.getId());

You should be calling this as few times as possible. If it's a simple non-overlayed 2D map, then group all your renders for each single texture together. Or write a sprite batch class that will handle texture changes when passing in data.

Hope this helps a little - I'm not at my home computer right now so I can't cross reference the calls I make, but I do know I only setup certain things once or once per frame, and I have definitely read on a few sites about making as few calls to BindTexture as possible.

Regards;
Richard Moss

AltSoftLab's picture

For this purpose just try AltSketch. You can draw like System.Drawing.Graphics