RyanPridgeon: M_D_K got the problems I ran into 100% accurate. PictureBoxes are slow when they get big, and redrawing them isn't fast, either.
dandymcgee wrote:If you guys have never made any sort of editor before I would definitely recommend you start off with SDL or OpenGL, just drawing the tiles in a window. It's much less complicated and doing it on some sort of form.
Actually, with the GLControl, drawing the map is exactly the same as drawing the map outside of a form, in a normal OpenGL window. With that out of the way,
MadPumpkin wrote:a bit of code and an explaination of where it goes would be VERY useful on this
I don't want to teach you OpenGL basics here, so here's some summary followed by the only code that you won't find on NeHe:
I got OpenTK, and made a "public partial class Viewport : GLControl", which I then placed on my form.
For initialization, look @ NeHe's tutorial on Orthographic projection, or read the documentation on glOrtho (OpenTK: GL.Ortho)
My initialization uses GL.MatrixMode, GL.LoadIdentity, GL.Ortho and GL.Viewport (I'm pretty sure I just copied this bunch out of the tutorial on opentk.com).
Drawing the map is just iterating through my list of tiles and drawing the correct one from the tile sheet. The tile that the map has can be used as a direct index into the tilesheet's list of rectangles, when the tilesheet is loaded left to right top to bottom.
To draw, it's just the calls you can find in the tutorials on texture mapping with a tile sheet. Mine enables Texture2D, AlphaTest, uses Greater for the alpha function, and sets color to (1.0, 1.0, 1.0, 1.0) using GL.Color4(). My GL.Translate takes into account the values of my scroll bars.
The only thing that really differs from standard OpenGL techniques is the tile sheet loading, so here's that, with some parts edited out.
Code: Select all
public TileSheet(string imageLocation)
{
/* do some parameter validation... */
/* set some defaults... */
/* save the image location... */
Bitmap sheet = new Bitmap(imageLocation); //TCR: Load the sheet's image so we can load it into opengl
/* save sheet width and height... */
TilesHigh = SheetHeight / TileHeight; //FIXME: Default value only; needs to load from file
TilesWide = SheetWidth / TileWidth; //FIXME: Default value only; needs to load from file
/* Class "Tile" is pretty much just Rectangle with some extra class members that I found useful during map editing.
So this is just a glorified list of Rectangles. */
Tiles = new List<Tile>(TilesHigh * TilesWide);
this.ID = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, this.ID);
/* Copied this next bit from OpenTK forums. It probably does what you think it does. */
BitmapData data = sheet.LockBits(new Rectangle(0, 0, sheet.Width, sheet.Height),
ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0, OpenTK.Graphics.PixelFormat.Bgra,
PixelType.UnsignedByte, data.Scan0);
// GL.TexEnv(TextureEnvTarget.TextureEnv, TextureEnvParameter.TextureEnvMode, (float)TextureEnvMode.Replace);
GL.Finish(); /* Finish guarantees that the file is not being held by OpenGL, otherwise we get occasional exceptions during the next call */
sheet.UnlockBits(data); /* Copied this from OpenTK forums ... */
sheet.Dispose(); /* Get rid of our Bitmap, it's a memory hog */
sheet = null; /* Ensure no references so the garbage collector doesn't get confused */
data = null; /* Same for its data */
/* Do some standard NeHe stuff */
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter,
(int)TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter,
(int)TextureMagFilter.Linear);
/* Increment tile cut-out coordinates by the size of a tile, where "1.0" is the size of the sheet. */
float uInc = (float)TileWidth / (float)SheetWidth;
float vInc = (float)TileHeight / (float)SheetHeight;
float u1, v1, u2, v2;
for (int y = 0; y < TilesHigh; ++y)
{
for (int x = 0; x < TilesWide; ++x)
{
u1 = uInc * x;
v1 = vInc * y;
u2 = uInc * x + uInc;
v2 = vInc * y + vInc;
Tile t = new Tile(u1, v1, u2, v2);
Tiles.Add(t);
}
}
MadPumpkin: Let me know if you need more. I don't really want to teach you C# basics, either. :) You'll find it's a lot like C++ combined with Visual Basic.