2D sprites in OpenGL using 3D coordinates

Started by
13 comments, last by GameDev.net 18 years, 4 months ago
I am trying to use 2D sprites with OpenGL. This is NOT about texture mapping quads, but rather about the best ways to position sprites using 3d coordinates. I want to use the Depth buffer for ordering the sprites.

static int zPos;

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        glLoadIdentity();                                     
	glTranslatef(0,0,-2);
        
        if(KeyPress(VK_UP))++zPos;
        else if(KeyPress(VK_DOWN))--zPos;
        
        
        glBegin(GL_QUADS);
        glColor3f(1,0,1);
          glVertex3i(0, 1,-10);
          glVertex3i(0,-1,-10);
          glVertex3i(-1,-1,-10);
          glVertex3i(-1,1,-10);
         glEnd();
        
        
        for(int i=0;i<3;i++)
        {
        glBegin(GL_QUADS);
        
        //Red
        glColor3f(1,0,0);
          glVertex3f(1, 1,zPos);
        
        //Yellow
        glColor3f(1,1,0);
          glVertex3f(1,-1,zPos);
        
        //Green
        glColor3f(0,1,0);
          glVertex3f(-1,-1,zPos);
        
        //Blue
        glColor3f(0,0,1);
          glVertex3f(-1,1,zPos);
         glEnd();
         
         glTranslatef(2,0,0.1);
        }

This is the little bit of code I've been experimenting with. I was thinking of using the zPos variable as like to represent layers, so that sprites with a deeper depth will go beneath and vice-versa. The problem, which is quite obvious is that the higher up sprites will be a bit bigger.... Any ideas on what to do? Is there a better way to do this ?
______________________________________________________________________________________________________
[AirBash.com]
Advertisement
You may switch to an equivalent orthogonal projection. Only perspective projection does a scaling dependent on the depth of occurance. (Perhaps some artifacts may occur if mixing two projection modes in one rendering pass.)

Else, of course a bottom-up ordered rendering would do the job, neglecting the need of different z values, but I assume you would not do so since it means to deny using the z buffer...

Also, you may specify a glScale per sprite to pre-undo the scaling. The scale factor is to be determined from the z value, of course, and to be applied to x and y elements only.

[Edited by - haegarr on December 3, 2005 7:20:33 AM]
Ah... I dint get anything :(

Can anybody point me to some source of a 2D game done in opengl ?

Or just even give me some pointers on how to go about doing 2D in opengl..
______________________________________________________________________________________________________
[AirBash.com]
As haegarr stated, you want to use orthographic projection mode. Basically, the viewing volume becomes a box (instead of a cut-off pyramid), so coordinates are mapped on the screen without being scaled. Check out the red book, chapter 3. Scroll down to about halfway down the page to get to the theory and some code.

Edit: of course, if you are after billboards instead of sprites, and want to mix 2d and 3d in one environment, it's a completely different story. But I think that was not your intention?
Or you could try my approach written in the forum FAQ.
----------[Development Journal]
Quote:Original post by lightbringer
As haegarr stated, you want to use orthographic projection mode. Basically, the viewing volume becomes a box (instead of a cut-off pyramid), so coordinates are mapped on the screen without being scaled. Check out the red book, chapter 3. Scroll down to about halfway down the page to get to the theory and some code.

Edit: of course, if you are after billboards instead of sprites, and want to mix 2d and 3d in one environment, it's a completely different story. But I think that was not your intention?



I am not after billboards ;)

Quote:
Orthographic Projection
With an orthographic projection, the viewing volume is a rectangular parallelepiped, or more informally, a box (see Figure 3-13 ). Unlike perspective projection, the size of the viewing volume doesn't change from one end to the other, so distance from the camera doesn't affect how large an object appears. This type of projection is used for applications such as creating architectural blueprints and computer-aided design, where it's crucial to maintain the actual sizes of objects and angles between them as they're projected.

Is that what you were pointing me to ?

But once you call glOrtho() then only the glVertex2.... commands work right?

what would be the best near, far clipping values



[
I am not trying to mix 2d and 3d. Just a plain sprite based game :)
I would really love to see some source which showed 2d in opengl
]


P.S Thanks Dwarf with Axe for this Last post about 2D in OpenGL (so please stop!)
______________________________________________________________________________________________________
[AirBash.com]
Quote:Original post by FireNet
But once you call glOrtho() then only the glVertex2.... commands work right?


Wrong, glVertex3 commands would also work, I think you can uze the Z Value as a, well, z buffer.

Quote:Original post by FireNet
what would be the best near, far clipping values


I use

glOrtho(-0.375f,width,height,-0.375f, 0.0f, 1.0f);

where width and height are the width and height of the window/screen.

Quote:Original post by FireNet
[
I am not trying to mix 2d and 3d. Just a plain sprite based game :)
I would really love to see some source which showed 2d in opengl
]


Here is my code for a 2D interface for my GUI library.
Quote:Original post by FireNet
But once you call glOrtho() then only the glVertex2.... commands work right?
No.

All glOrtho does is create an orthographic projection matrix and multiplies the matrix on the top of the current matrix mode's stack by it. It is usually used on the projection matrix after it has been set to the identity. So in the normal usage, the only thing that changes is the projection matrix; the rest of OpenGL still works exactly the same way.
As the others already stated, you still get to use the Z buffer with orthographic projection. The only thing that changes is how objects appear on the screen. If I understood your initial complaint, you didn't want them to scale with distance, and glOrtho() achieves that while keeping the "3D-ness" intact ^_^.
void OGL_2D(){  int vPort[4];   glGetIntegerv(GL_VIEWPORT, vPort);   glMatrixMode(GL_PROJECTION);   glPushMatrix();   glLoadIdentity();   glOrtho(0, vPort[2], 0, vPort[3], -100, 100);   glMatrixMode(GL_MODELVIEW);   glPushMatrix();   glLoadIdentity();}void Render(){	static float zPos = 0;	if(KeyPress(VK_ESCAPE))FlagQuit();			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	glLoadIdentity();        if(KeyPress(VK_UP))++zPos;        else if(KeyPress(VK_DOWN))--zPos;                        glBegin(GL_QUADS);        glColor3f(1,0,1);          glVertex3i(0, 1,-10);          glVertex3i(0,-1,-10);          glVertex3i(-1,-1,-10);          glVertex3i(-1,1,-10);         glEnd();                        for(int i=0;i<3;i++)        {        glBegin(GL_QUADS);                //Red        glColor3f(1,0,0);          glVertex3f(1, 1,zPos);                //Yellow        glColor3f(1,1,0);          glVertex3f(1,-1,zPos);                //Green        glColor3f(0,1,0);          glVertex3f(-1,-1,zPos);                //Blue        glColor3f(0,0,1);          glVertex3f(-1,1,zPos);         glEnd();                  glTranslatef(2,0,0.1);        }}


This is my source atm and I get nothing on the screen. The set OGL_2D() was copied from Last post about 2D in OpenGL (so please stop!).

So what am I doing wrong here?
______________________________________________________________________________________________________
[AirBash.com]

This topic is closed to new replies.

Advertisement