I'm trying to use SDL2 and Modern OpenGL to make a 2D rpg. The problem is, I have no idea how to render a tile map. I'm using the Tiled map editor to create maps. I have a vague idea of how to parse the maps using this (https://github.com/andrewrk/tmxparser) tmx parser. I try to parse the maps using said parser, but then I run into the problem of how to actually get the tile maps to appear on screen, when using a spritebatch class. How would I go about rendering these maps using modern OpenGL?
You'd draw a tile map in OpenGL the same way you'd draw a sprite that has multiple frames in a single texture; by adjusting the texture coordinates such that you only drew a portion of the texture onto the quad that represents the tile.
A rough way to do it would be to create a mesh of quads/triangles that represents your tile map; each tile's world coordinates would be equal to the tile's X,Y index in the grid * the size of the tile (make sure to use orthographic projection!);
Then, each tile's UV coordinates into the master tiles texture would be something like;
(1 / tiles across) * textureXindex
So if your texture had four tiles across (same thing in an ortho projection) and you wanted tile #2;
textureWidth = 1 / 4;
textureWidth * 2 = 0.5 (left texture U coordinate)
the above value (0.5) + textureWidth (right texture U coordinate)
Same for the Y/V coordinate. You could also calculate the tile width by dividing the total width of the tile texture in pixels by the width of a tile in pixels, which will give you the same decimal value as the 1/4 calculation above.
In order to convert a single-number tile index into an X, Y value within the tile map, divide it by the number of columns to get the Y, then mod (%) it by the number of columns to get the X.
So if your tile map is 4x4, and your index is 13;
13 / 4 = 3 13 % 4 = 1
So your tile coordinates are 1, 3.
Here is an example with a very simple tile/sprite sheet. Each tile is 32x32 and the red line marks the left and the upper corner of each tile.
You always want to use sheets like this when rendering tiles. Switching textures is much more expensive than drawing a bunch of vertices.
You can either index it either by using a 2D vector or just a number. To index it via a vector you would get the minimum position (assuming the origin is in the top left of the image) and maximum position as such (this is some kind of pseudocode):
sheetPrediv = (1 / sheetWidth, 1 / sheetHeight); minPos = (x * spriteWidth, y * spriteHeight) * sheetPrediv; maxPos = (x * spriteWidth + spriteWidth, y * spriteHeight + spriteHeight) * sheetPrediv;
sheetPrediv could be contained in some class that also contains your OpenGL texture handle, since it only needs to be calculated when the texture is loaded and can then be stored.
Another way to index the sheet is by a number. Imagine that each cell has a number; the top-left cell is 0, the top-middle cell is 1 and so on, when it gets to the last cell on the current line it keeps going on the next line.
Now you can get the minimum and maximum position of the tile (once again, assuming the origin is in the top-left) in a different way:
sheetPrediv = (1 / sheetWidth, 1 / sheetHeight); minPos = ((index % sheetColumns) * spriteWidth, floor(index / sheetColumns) * spriteHeight) * sheetPrediv; maxPos = minPos + (spriteWidth, spriteHeight) * sheetPrediv;
There are tons of other ways to get the index, doing it the way I've don it here are just two examples. If your origin is somewhere else (like in the bottom-left) you'll have to modify these formulas a bit. I'll leave that as an exercise.
So, now you have the texels for drawing. So bind the texture and send the texels to your shader. Alternatively you send the index to your shader and to do all the calculations there.
Remember to mark an answer for your question