How to use OpenGLSurface to draw 2D tiles?

Hi, I am considering using Xojo as the language for a 2D game engine. However all the tutorials I’ve looked at for 2D sprite rendering are complex, and often involve manipulations such as rotations, movement, etc. It would really help me get started if someone can give me a simple snippet of code on how to draw a 32 by 32 pixel tile on to a position on the GLSurface from an image of a tileset (png, jpeg, etc).


Hi Anton,

I’ve recently built a component better known as X3Canvas. It operates very similar to how you would use the Xojo native canvas, except that all rendering is done via OpenGL.

Have a look at the “tiles” example in the following folder:

The code is public domain, so you can use it in commercial and non-commercial apps without requiring any permission.

I need to point out the X3Graphics renders 2D content with an engine designed for 3D graphics, so you will be able to add support for 3D models to your game engine, should you wish to do so.

Enjoy, and please let me know if you have any questions, or if there are any features that you would like to see added to the X3Core framework.

One final note, X3Canvas is actually just an OpenGLSurface with some code added to do all the heavy lifting of initializing OpenGL.

…even if you don’t want to use X3Canvas, and write your own component… there should be enough code to get you started in the example project.

Wow thank you very much. I will definitely let you know if I need anymore help!

Update: There is a known issue with these examples on Mac. I’m working on a solution and will have the issue fixed ASAP.

Update 2: The examples have been fixed and should now run on Mac as well.

They do :slight_smile:

Ok. I have used your code to implement a simple 2D engine. Reading and writing maps to text files, etc. That is all ok. However now I am wondering if the X3Canvas supports transparent masks.

For example, I want to draw a ground tile and then draw a shrub tile on top of that. The background of the shrub tile is white, however I want that white background to be a transparent mask such that the white will be replaced with the non-overlapping parts of the previous or (lower level) tile (the grass tile). Any help would be really appreciated. Thank you!

X3Canvas absolutely supports transparency.

You have two options:

  1. PNG files (recommended option)
    Simply create a PNG of the shrub with the background transparent. Then use the DrawTexture with a texture that was created from that PNG. X3Canvas will automatically handle the transparent areas.

  2. Shrub and mask files seperate
    If your shrub and B&W mask files are seperate, do the following:

ShrubPic = ...load shrub picture ShrubPic.Mask = ...load mask picture ShrubTexture = X3Texture(ShrubPic) DrawTexture ShrubTexture , x, y

I makes sense to me however, to simply store your shrub as a PNG file that already has the transparent layer.

Just make sure to draw the shrub texture AFTER you drew the grass tiles.

Please let me know if you need any help.

Ok, I’ve decided to go with PNG. I am wondering about using tilesets instead of individual tiles as that is much more efficient. Do you know a way I can get a 32 by 32 tile at the 64, 64 position on a tileset and draw it on the X3Canvas?

dim tile as new picture(32, 32)
tile.DrawPicture(tileset, 0,0,32,32, 64,64,32,32)
tileTexture = X3Texture(tile)
DrawTexture tileTexture, x, y

You can also load the whole tileset as a single texture, and then adjust the UV-coordinates of indivdual polygons manually to point to different tiles on the tileset.

But Tim’s approach is actually much easier to achieve exactly the same result.

Thanks Tim, but the code doesn’t seem to run. It says there is no ‘DrawPicture’ in tile. Any ideas?

Ok I got it to work using

Ok, I have a question. How does one retrieve the current positions of the X3Canvas. For example, say I have moved the camera to the right of the canvas by 512 pixels up and 256 pixels down. How do I get those positional figures from the X3Canvas?

It will require some calculations to transpose between the 3D space and 2D pixel space. The camera is actually moving in 3D space and generating a 2D projection of objects in 3D. The 3D space is not measured in pixels though.

What exactly do you want to achieve, e.g. Why do you need the pixel values?

PS. I can add some methods for you to do these calculations easily, e.g. Calculate pixels from camera position. Let me know if such a method will help you.

Thank you very much! I used Tim’s method to render the canvas, but that takes up a lot of memory and also causes the program to be laggy. Unless you can possibly suggest a method to load a large, say 200 by 200 tile map without using up 200+mb of ram and the presence of unresponsiveness, I would have to progressively load the map. ie, initially, pixels from 256 (x) to 256 (y) are rendered. If the player moves from the x pixel 256 to 512, i will then render the horizontal parts of the map from tile at pixel 256 to 512.