Dark Bit Factory & Gravity
PROGRAMMING => General coding questions => Topic started by: Pixel_Outlaw on April 09, 2009
-
I've looked for the answer to this question online and have come up short. I need a camera that follows around my player. The "world" is much bigger than the screen so it cannot be drawn at once. I know I need to use a translation. However, every time I draw an object in the world I first reset the projection using glloadidentity(). So my final "camera" translation becomes meaningless... I know I'm handling drawing wrong I think...
I'm just trying to make the camera follow the player, this is a simple 2d top-down project.
-
First of all you have to set up some useful projection first; either perspective (http://www.opengl.org/sdk/docs/man/xhtml/glFrustum.xml) or parallel (http://www.opengl.org/sdk/docs/man/xhtml/glOrtho.xml):
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// perspective:
glFrustum( -1.0, 1.0, 1.0, -1.0, 0.1, 10.0 );
// parallel:
glOrtho( -1.0, 1.0, 1.0, -1.0, 0.1, 10.0 );
(although you're just doing 2D, perspective projection has the benefit of free scaling by simply altering the z-component)
In both cases 0,0 is the center of the screen, positive x-values go right, negative y-values go up (crt-orientation).
Z ranges from -0.1..-10.0 and at z=-1, x & y range from -1..+1 (so your coordinates are independent from screen resolutions).
Now the first thing you put into your modelview is the camera-position (x,y):
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(x,y,0);
When modifying the modelview, make sure to use push/pop to restore the initial camera-setting properly:
glPushMatrix();
// ...
glTranslatef(x,y,z);
// ...
glPopMatrix();
Another option is to put your camera-transformation into the projection, so you can mess up the modelview freely.
This will introduce some problems later, though.
-
Thanks for the tips.
I have some lingering problems however.
My projection is set up funny compared to yours...
glPolygonMode(GL_FRONT, GL_LINE)
glMatrixMode GL_PROJECTION
glLoadIdentity
gluOrtho2D(0.0, 800.0, 600.0, 0.0)
glMatrixMode GL_MODELVIEW
glLoadIdentity
Now that you mention using the perspective projection to scale this fixes a problem I could make a simple world map by scaling out. The code is just to initialize the OpenGL.
The basic game loops looks like this
glPolygonMode(GL_FRONT, GL_LINE)
glMatrixMode GL_PROJECTION
glLoadIdentity
gluOrtho2D(0.0, 800.0, 600.0, 0.0)
glMatrixMode GL_MODELVIEW
glLoadIdentity
while 1
'clear screen
glClear GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
glLoadIdentity()
' Every object shape in the game is then drawn starting with 1 glloadidentity(), 2 gltranslatef(), 3 draw()
' I have the models stored as shapes so I must first move to the location and then place them, they have no passable coordinates
'update the camera x and y here
flip buffer
wend
I'm trying to understand but I'm not sure where to put what in my loop. I DO want to set up the projection properly and have a movable camera. So maybe you can see where I'm failing here. I don't know what to ask...
-
My projection is set up funny compared to yours...
glMatrixMode GL_PROJECTION
glLoadIdentity
gluOrtho2D(0.0, 800.0, 600.0, 0.0)
Well, that's not so different, you're just thinking in pixel-coordinates.
Actually it makes things a bit easier as long as your screen is 800x600 (but gets somewhat dirty when it is not).
Just keep in mind that your z-coordinates need to be between -1..+1 (implied by gluOrtho2D, you can specify the z-clipping manually by using glOrtho).
As far as I understood, each object has a translation and you want to apply a global camera translation on all objects.
So you most likely want to do something like this:
// initially set up the camera transformation:
glMatrixMode GL_MODELVIEW
glLoadIdentity
glTranslatef cameraX, cameraY, 0.0
// when drawing an object, save the current transformation (inlcuding the camera-translation)
glPushMatrix
// apply the object's transformation (so the modelview contains both, camera & object transformation):
glTranslatef objectX, objectY, 0.0
glRoatef objectRot, 0,0,1
// draw the object
glBegin ... glEnd
// restore the previous transformation (camera-transformation only)
glPopMatrix
-
Thanks as usual hellfire!
I'll try it tomorrow after work and get back to you ASAP. :)