newbie OpenGL questions ......

Started by
19 comments, last by graveyard filla 19 years, 11 months ago
high, im currently learning openGL to make 2d games. anyway, i have some questions and would appreciate any answers: when you draw this to the screen, say a Quad and (one of) the call looks like this glVertex3f(-1.0f,0.5f,0.0f); so when you call that function, its saying "draw this point at 1.0f to the left of the CENTER of the screen, .5 below the CENTER of the screen, and 0 into/out of the CENTER of the screen??" basically my question is, so anything you draw, is drawn at (or relative to) the center of the screen? and you change what the center is, by calling glTranslate() ??? just wanting to confirm, im reading the nehe tutorials but he doesnt really explain this (maybe i missed it?) also, 3d graphics use cartesian coordinate system? so i guess i can throw out the whole idea that the top left corner is 0,0 and Y increses by going down, eh? also, can you not translate from inside a glBegin(GL_XXXX) call? because i tried drawing 2 quads in the same bracket of glBegin(GL_QUADS) , and i translated after drawing the first quad, but when i executed the program, the second quad was on top of the first one i drew.... im thinking Translate has to be called from outside of a glBegin() bracket? or can you not draw multiple quads in a single glBegin() bracket? (nehe says otherwise, but im getting this weird thing so... also, when i made the 2 quads drawn in seperate glBegin() brackets, and translated in-between, it worked fine) thanks for any help!!
FTA, my 2D futuristic action MMORPG
Advertisement
Well technically all 3D drawing is in terms of local coordinates. When you start off the object matrix is inline with the world world coordinates. translate, rotate, etc, shift these coordinates to wherever you want on screen. Also there is no reason all your coordinates have to be with 0.0, 0.0 in the center of the screen for your world. They will just end up that way after running through the pipeline matrices which align the camera (which has its own coordinate system) with the world and the center of projection (or direction of projection if your doing parrallel).


I think your translate problem is do to when the object matrix is applied to your points. I''m not sure when OpenGL applies this, but it is likely done after glEnd inorder to allow a batching of the vertices being transformed at once.
My name is my sig.
Yes, you have to put your translations outside of the glBegin()/glEnd() calls. There is a very limited list of GL calls you may make between glBegin() and glEnd():

glVertex
glColor
glIndex
glNormal
glTexCoord
glEvalCoord
glEvalPoint
glMaterial
glEdgeFlag

(This is yoinked directly from MSDN). Obviously, these are just the root versions of the functions, add parameter number and type as appropriate.

Any other OpenGL calls will not work inside those two calls. They won''t crash or anything, but they won''t do anything useful either.

-Auron
Since you''re doing 2d graphics, use ortho mode instead of perspective. NeHe doesn''t cover this well (or at all? can''t remember).

Instead of something like this

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,(float)w/h,1,100);


do this

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(0,w,0,h);



Then instead of glVertex3f use glVertex2f. The end result is that coordinates coospond to screen space, with 0,0, being the lower left corner. Have fun!

--------------------------------------------------------
Life would be so much easier if we could just get the source code.
--------------------------------------------------------Life would be so much easier if we could just get the source code.
All right, let me give you a brief rundown of how coordinate systems in these APIs work.

Basically, they're managed by matrices. To understand exactly how this works you need to know some linear algebra, but basically, it's possible to encode a set of axes (aka a coordinate system) in a matrix. If you multiply a position vector by this matrix, the vector will be placed in the new coordinate system. It will still be in the same "place", but the origin moves, or the axes are rotated, and so the vector's location and/or orientation changes relative to the origin.

Now, as far as I remember, OpenGL has this one matrix called the WORLDVIEW matrix. This one is responsible for containing an origin and a set of axes for your world. When calling glVertex3f(), you specify the points in local coordinates . Usually, this means that the origin is at the center of whatever object you're drawing (NOT necessarily at the center of the screen! The objects are not placed anywhere on the actual screen yet). Then, while drawing, OpenGL will multiply these coordinates by the WORLDVIEW matrix to move the point to an absolute location in the world (and it'll do some other stuff with other matrices, but you don't have to worry about that).

Functions like glTranslatef() modify the WORLDVIEW matrix (or maybe whatever matrix you have active at the time, but that's usually WORLDVIEW, I think...) So, when you call glTranslatef(), you're essentially moving the origin of the world somewhere else.

Anyway, I haven't used OpenGL in a while, so please correct me wherever I'm wrong.

Here's what a typical matrix looks like as far as I can remem,er, although the arrangement of the terms may not be exactly correct:
ix iy iz 0jx jy jz 0kx ky kz 0ox oy oz 1  

Where i, j, and k are 3D basis vectors that act as the axes of your new coordinate system, and o is a position vector that represents the origin of the new coordinate system relative to the old one.

[edited by - twix on May 19, 2004 10:46:58 PM]
the OP stated things more clearly than anyone since ...

YES, glTranslate changes the current "center" of the world ... glRotate changes the "orientation" of the current "center" of the world, glScale changes the relative scale of the current world (relative to the previous state).
You can kinda think of it like the solar system:

On the bottom level, you''ve got the moon. The moon goes around the earth, the earth around the sun. However, the moon moves relative to the earth, NOT the sun.



The sun stays still, so it''s like just drawing in GL straight-up without any translation or scaling whatsoever.

// sun
draw the sun

Now we draw the earth. It''s X,Y,Z away and it''s rotated so-and-so. We push a matrix onto the stack. That means "move the universe over here so i can draw the earth now" and makes for an easy "undo" later on.

// earth
push a new stack
glRotate( so-and-so )
glTranslate( X, Y, Z );
draw earth

now we draw the moon. The moon is offset X,Y,Z and so-and-so in relation to the earth, not the sun. So we push another matrix onto the stack for the moon and do another set of offsets:

// moon
push a new stack
glRotate( so-and-so )
glTranslate( X, Y, Z );
draw moon

Now we''ve "moved the universe" over a bit for the earth and over a bit more for the moon. Sorta like if you walk across an elevator while the elevator is moving down, you are actually travelling at an angle in relation to the ground. You are combining movements. In openGL, when you push matrices, you are combining all these "movements" (translate, scale, rotate) together into one big movement (when the screen is drawn).

When we are done drawing things, we want to undo our stacks. Otherwise, everytime we draw them, they will all be off by that much more every frame. so...

pop the moon matrix from the stack
pop the earth matrix from the stack

... and now we are back to the "real" center where the sun is.

at least, that''s how i understand ;-)

The other option is just to draw everything according to an unchanging world, but that''s no fun :-) It''s also sometimes difficult to figure out if you have objects that move in relation to other objects and in general, not an organized way to do it.

Take everything i just said with a large grain of salt. I''m new to OpenGL too.
Well you don''t have to push matrices on the stack to accomplish translations, but everytime you want to go back to the world origin you''d have to load the identity matrix. :-) At first the whole matrix use thing may seem more difficult. It took my friend almost all semester to wrap her mind around the whole concept in the Computer Graphics class we took (most of the guys did well since they had already done some 3D programming using DirectX or OpenGL). When she finally got it though, she realized how much easier it is to deal with then 2D games she had to make for previous classes.

It took me a while to get used to it all too. Now it is no sweat. I can usually figure out what a set just by looking at it. If your doint 2D you might want to stick what opengl calls Ortho project (or parrallel mode). However, if you try to do anything height based and you want to show that perspective, perspective mode can be very useful. BTW, technically you can use any Coordinate system you want as long as you can translate back to OpenGL''s Cartesian system. Like I said before you can set your coordinate system to where top left of the screen is 0,0 and bottom right is whatever you want. It all involves with making custom matrices.
My name is my sig.
thanks everyone, i didnt really understand most of your replies as soon as you started talkin math, i got screwed up. i have no math skills and probably will never get them (in college now, but im in CIS so we only take up to college algabra and statistics... in HS i never made it past basic algabra)

anyway, i dont know what a matrix, vector, or any of that stuff is. but i dont think ill be needing it just yet. i figured out how to get ortho mode to work (0,0 in top left corner and my Y axis increases while going down like good old SDL).. anyway, im having a problem now i hope someoen can help with. im trying to map a texture to a quad, but im having problems. i load in the image, and when i draw the quad i map each piece of the texture with the point i specify... anyway, the result looks like this



the original image looks like this..




does anyone know what the problem is? why are my colors getting distorted like this? also, before i even tried uploading and using the texture, my colors were distorted very similarly when even specifying colors using glColor3f(r,g,b).. i noticed when i remmoved the call to glEnable( GL_TEXTURE_2D );

that this stopped the distortion. but anyway, i added the line back in, and texture mapped my quads, and now im getting this problem. also, when i maximize the window, my screen turns white and if i re-windowize it, it stays all white like this.. really weird... heres what my initialization/loading of texture code looks like:

int initGL( GLvoid ){	  /* Load in the texture */    if ( !Load_Textures( ) )		return FALSE;    /* Enable Texture Mapping ( NEW ) */	glEnable( GL_TEXTURE_2D );    /* Enable smooth shading */    glShadeModel(GL_SMOOTH);    /* Set the background black */    glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );    /* Depth buffer setup */    glClearDepth(1.0f);    /* Enables Depth Testing */    glEnable(GL_DEPTH_TEST);    /* The Type Of Depth Test To Do */    glDepthFunc(GL_LEQUAL);    /* Really Nice Perspective Calculations */    glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	return TRUE;}bool Load_Textures( ){    /* Status indicator */    int Status = FALSE;    /* Create storage space for the texture */    SDL_Surface *TextureImage[1];     /* Load The Bitmap, Check For Errors, If Bitmap's Not Found Quit */    if (( TextureImage[0] = SDL_LoadBMP( "tile1.bmp")))        {		   /* Set the status to true */		   Status = TRUE;		   /* Create The Texture */		   glGenTextures( 1, &texture[0] );			 /* Typical Texture Generation Using Data From The Bitmap */			glBindTexture( GL_TEXTURE_2D, texture[0] );					 /* Generate The Texture */			//GL_TEXTURE_2d says its a 2d texture			//0 is recommended			//3 is its using 3 colors (RGB)			//w,h of the actual image			//0 is recommended again			//			 glTexImage2D( GL_TEXTURE_2D, 0, 3, TextureImage[0]->w,TextureImage[0]->h, 0, GL_RGB,							 GL_UNSIGNED_BYTE, TextureImage[0]->pixels );	    /* Linear Filtering */	    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );	    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );        }    /* Free up any memory we may have used */    if ( TextureImage[0] )	    SDL_FreeSurface( TextureImage[0] );    return Status;}


now heres the drawing code...


void Draw_Quad(float x, float y){     glBindTexture(GL_TEXTURE_2D, texture[0]);		     glBegin(GL_QUADS);                /* Draw A Quad */         glTexCoord2f(0.0f, 1.0f);       glVertex2f(x, y + 32.0f); /* Bottom Left */	        glTexCoord2f(1.0f, 1.0f);      glVertex2f(x + 32.0f,y + 32.0f); /* Bottom Right */      glTexCoord2f(1.0f, 0.0f);       glVertex2f(x + 32.0f,y); /* Top Right */      glTexCoord2f(0.0f, 0.0f);       glVertex2f(x,y); /* Top Left */        glEnd();}


(theres a global variable called GLuint texture[1])
(so OpenGL keeps all its texture data inside an unsigned int?)

thanks for any help.. im using 2d ortho mode setting the origin to the top left corner of the screen... also using SDL for all the 'support' code obviously...

[edited by - graveyard filla on May 20, 2004 3:49:26 AM]
FTA, my 2D futuristic action MMORPG
2 things:

1) Check the part where you load the texture. One of the options is GL_RGB. That assumes pixel data is stored in R G B order, which it may not be. Your color rotation seems to indicate it''s probably GBR or some other weird thing. Just try different combos and see which one works right.

2) OpenGL is one big mutha state machine. That means that any time you change something, it stays that way until you change it again. I noticed that you do not specify the color when you are drawing the quad. That''s okay if you can guarantee that the color will be white going into the drawing phase, but otherwise, set your color to

glColor4f(1,1,1,1);

before you glBegin() all the other info. That will make sure your textures don''t get a weird color cast from some other thing you drew.

This topic is closed to new replies.

Advertisement