# OpenGL + Allegro. Moving from software drawing X Y to openGL is confusing

Having a fair bit of trouble. I'm used to Allegro and drawing sprites on a bitmap buffer at X Y coords. Now I've started a test project with OpenGL and its weird.

Basically, as far as I know, theirs many ways to draw stuff in OpenGL. At the moment, I think I'm creating a Quad? Whatever that is, and I think Ive given it a texture of a bitmap and them im drawing that:

GLuint gl_image;

glBindTexture(GL_TEXTURE_2D, gl_image);

glColor4ub(255, 255, 255, 255);

glTexCoord2f(0, 0); glVertex3f(-0.5, 0.5, 0);
glTexCoord2f(1, 0); glVertex3f(0.5, 0.5, 0);
glTexCoord2f(1, 1); glVertex3f(0.5, -0.5, 0);
glTexCoord2f(0, 1); glVertex3f(-0.5, -0.5, 0);

glEnd();


So yeah. So I got a few questions:

Is this the best way of drawing a sprite? Is it suitable?

The big question: Can anyone help / Does anyone know any tutorials on this weird coordinate thing? If it even is that. It's vastly different from XY, but I want to learn it. I was thinking maybe I could learn how this weird positioning stuff works, and then write a function to try and translate it to X and Y coords.

Thats about it. I'm still trying to figure it all out on my own but any contributions you guys can make would be greatly appreciated =D

Thanks!

• Questions asking for "help" or "tutorials" or general "best way" kinds of stuff are not what we do here. We answer practical, focused questions about a specific problem you have. – Nicol Bolas Mar 24 '12 at 4:40
• Well I just gained a fair bit of valuable information from some cool people. I don't see the problem, even if it is the rules. – Aaron Mar 24 '12 at 6:43
• FYI, if you are starting fresh with new projects, then I'd recommend using the 5.0 series of Allegro, as the 4.0 series is basically in limited support now. (5.0 has OpenGL drivers built-in.) – Matthew Mar 24 '12 at 15:51

Is this the best way of drawing a sprite? Is it suitable?

It's suitable, and it works, but it's not the best way to do it.

What gl* calls really do

What you are doing is sending commands to your video card. Just about any function you call that begins with 'gl' does so . Thraka did a fairly good job of explaining some of the commands you're using already.

The glTexCoord2f() and glVertex3f() function calls you are making interact with your video card drivers, which then send commands to the video card, which does all the real work.

The reason this isn't the best way to do it is because you are making a single function call and sending your data to the video card, for every vertex, every time you draw this quad. Imagine if you could send the data to the video card once, and then tell the video card to draw "that thing" you sent earlier, instead of telling it each time you draw what the coordinates are. This is referred to as a Vertex Buffer Object, or VBO.

Can anyone help / Does anyone know any tutorials on this weird coordinate thing?

Now it looks like you're just getting started, so I wouldn't worry too much about anything I just said. I especially wouldn't worry about using the most efficient way of rendering things. Hopefully it gives you an idea of what you're really doing, though, when you make these function calls.

To really understand the relationship between the X and Y coordinates you worked with in Allegro and the 3 dimensional coordinates (and the immense flexibility therein that OpenGL gives you), you really need a good math background.

I believe it was pre-calculus where I learned about rotations, scale, and translation, and how a 3x3 matrix could be used to represent all these things in a two-dimensional space. If I had paid more attention then, I might be a better game developer today, but that's beside the point. This is the kind of thing that's fundamental to understanding how to work with OpenGL. Of course, OpenGL is a 3-dimensional API, so things therefor get a little more complicated, but the same way of thinking extends well. However, you can get by without understanding the intricate details of transformation matrices as long as you understand some basic concepts.

Coordinate spaces

Think back to some geometry (or similar) studies you've done. You usually describe the position, shape, size, and so on of an object relative to the origin ( (0, 0) in a two dimensional space). If you say a point is at (2, 2) you are saying it is up two and right two from the origin.

What is this origin? A better question is where is it? It's completely arbitrary. You can't tell someone your house is at (x, y) and expect them to know how to get there. You could possibly give them the latitude and longitude of your house, but these are coordinates in a similarly arbitrary coordinate system. Latitude and Longitude only have any meaning because everyone agrees where the Prime Meridian and the Equator are.

Similarly, there are directions involved. In a 3D world, there is an up, a right, and a forward. This is incredibly intuitive to you because your right hand has always been your right hand, up has always been up, and forward has always been in front of you. But in an arbitrary coordinate space like we are talking about, these things have to be specified before anything makes any sense.

When you work with OpenGL, you need to think in similar terms. If you tell OpenGL to draw something at (0, 0) you're telling it to draw at the origin of the current coordinate space. This coordinate space defines where the origin is, these principal directions, and some other things like scale that may be important.

I'll try to give an example of how this could all be practically used.

Imagine you have taken your room and modeled it all in something like Google Sketchup (or any other 3D modelling program.) You've got windows, your bed, and your computer in there. Where is the origin? What is right, up, and forward? Lets say you just started modeling everything without thinking about any of this, and these things happen to correspond to the doorway to your room. That is, in your virtual world, you are at the origin and looking forward when you are standing in the doorway facing your room.

Now you've saved this whole virtual world (your room) to a file. And you've decided to model the rest of your house. You start a new virtual world (your house) and put the other rooms in there, the backyard, kitchen, etc. Now lets say you've modeled everything in your house except your room. First, lets consider where the origin of this virtual world is. We'll say you decided to call it, again, the doorway to your house. The origin is the doorway to your house, forward is the direction you are facing when you look into the house, etc.

All the items in your room are saved currently relative to the doorway to your room. But you want to pull your room that you previously modeled into your house. What needs to happen (and what the modelling program will do for you automatically) is that you define the position and rotation of your room relative to the coordinate space of your house.

Assume, now, that we have "your room" positioned in your house relative to the front door. How do you determine where, in your house, the computer is in your room? You have to transform the computer's coordinates from your rooms' coordinate system to the coordinate system of the house. Since you've defined the orientation of your room relative to your house, you can now do this.

How this relates

Imagine the computer monitor you are currently looking at is a camera, or an eye, looking into a virtual world. If you play a first-person-shooter for a bit, this isn't hard to do. The monitor, of course, isn't actually moving; it's only depicting a changing perspective into a virtual world.

From this point of view, how might you make the impression of a two dimensional space, like many games (such as Mario)? Imagine (again) that you take a board game, like Monopoly, and want to film it. The board game is essentially 2-dimensional, but the camera you are using captures an entire 3-dimensional world. If you place the board of Monopoly on a flat table, and then position your camera a couple feet above the board, facing directly downward towards it, you'd end up capturing the Monopoly world in its 2-dimensional glory.

This is exactly(1) what Allegro does for you. You give it two dimensional coordinates and it translates them into 3-dimensional coordinates that work out exactly the way you want.

Matrices

One convenient way of doing all of this is by using a matrix. As I said earlier, orientations in a 2-dimensional space can be described by a 3x3 matrix. Similarly, orientations in a 3-dimensional space can be described by a 4x4 matrix. The real convenient thing here is that to "jump" from one coordinate system to another, you just have to multiply the existing matrix by another.

If you describe the location of the computer in your room as a 3-dimensional vector, you can multiply this vector by the room's transformation matrix to find its position in the house-space. The matrix math would look something like this:

[ n, n, n, n,     [ x,
n, n, n, n,   *   y,
n, n, n, n,       z ]
n, n, n, n ]


I don't want to bog you down with the specific numbers in the matrix and their meaning, but this should give you an idea of the relationship. The 4x4 matrix on the left is our theoretical transformation matrix that describes your room's orientation, and the vector on the right (or 1x3 matrix, if you will) describes the position of your computer relative to your room.

Back to our house example, lets imagine a third coordinate space. Lets say this is the city, and that the origin is at the city hall, and that this coordinate space is facing north. Now we have 3 coordinate spaces, described by 3 matrices:

M1 - city

M2 - house

M3 - room

And we have one particular object, your computer, with a vector describing it's location relative to the room:

V1

We can do some pretty cool stuff now:

The position of your computer relative to the house is:

M3 * V1


The position of your computer relative to the city is:

M2 * M3 * V1


And if we say the city's coordinate space is relative to "world space," we can say that the position of your computer relative to "world space" is:

M1 * M2 * M3 * V1


Good luck

I'm tired of writing, and unfortunately there's still a bit more in your question that may not have been answered (specifically about texture coordinates.) Hopefully my voluminous answer has helped you understand the code you're writing though, and helped you understand some of the concepts needed to work with OpenGL.

--

(1) Allegro may not do exactly this, but this should give you the idea of the relationship between 2D and 3D in OpenGL.

• Thanks. Well, I have slowly worked out a little about coordinates (Nothing like what you just said) in the link I posted under Thraka's comment if you want to have a look =) Anyway, thanks, I'll get there eventually =P – Aaron Mar 24 '12 at 6:34
• If you really want to get good at this stuff, you just need to practice and think about it a lot. If you get to the point that you're thinking about it in your dreams, you're on your right track. – notlesh Mar 24 '12 at 6:37

I've never used OpenGL and I'm not that good at the other things I've used in the 3D world. But basically the way programming works in 3D is that you give render instructions to the graphics card. If I interpret your code it's saying

glBindTexture(GL_TEXTURE_2D, gl_image);

-- I'm going to use this texture

I'm going to draw quads to the screen. A quad is made up of 4 points and represents a flat surface, so it's going to process four points to draw a quad. So if you decalred 8 verticies(sp?) then it would make two quads.

glTexCoord2f(0, 0); glVertex3f(-0.5, 0.5, 0);

Use this texture coordinate and use this 3d world space coordinate.

A texture coordinate maps a to a location on your texture. If you think of your texture as a rectangle and the top left is the coordinate 0.0 , 0.0 and the bottom right coordinate is 1.0 , 1.0 then any number between 0.0 and 1.0 along any axis will plot a space in the texture. Where 0 and 1 are depends on how OpenGL will interpret this data. it may be that 0,0 is the bottom left and 1,1 is the top right.

Think if the center of your screen (by default) as world space 0.0 , 0.0. When you say -0.5 , 0.5 then it is probably moving a little to the left and a little up to plot that first point (vertex) depending on how OpenGL declares it's coordinate system.

Since you do this four times, you are declaring where each point is going to draw in the world and what part of the texture it will use.

I found this image online:

I think this shows you how a texture coordinate is used by a quad. t0 is the first texture coordnate you declared on the texture (0,0 i'm assuming in the picture) and that point of the texture will be rendered

If you go into quad rendering then when you define four verticies, think of it as connecting a line between all four points and then rendering the texture in it based on where you said each vertex would be on the texture.

• Thanks Thraka, that information did help. For you and any others that see this, I created this class to draw sprites at X Y locations and so far it seems to be working well, although I haven't fully tested it yet, but yeah so far so good: pastebin.com/nfnuQP87 If anyone wishes to point out any problems, or just general feedback on that, it would be great =) Thanks – Aaron Mar 24 '12 at 6:05