Best method for a top down, side scrolling camera.

Started by
4 comments, last by Goran Milovanovic 11 years, 5 months ago
Ive seen examples using gluLookAt(), glOrtho(), gluOrtho2d(), etc. One example I saw said all you need is to just use glTranslate(). So what is presently the best, easiest method to achieve this effect?

Thanks in advance.
Advertisement
Every time you render a frame, you have to specify your projection matrix and place your camera position, and the direction you are looking in. There is nothing special or different about a top down, side scrolling camera. Just put your camera where you need it, and then tell it what direction to point in.

Create a camera class, and use it to keep track of the camera's position, lookat vector, Field of View, and anything else you might want, like velocity.

http://nehe.gamedev.net/article/camera_class_tutorial/18010/
I understand the camera class. My question is what OpenGL commands to use.

My question is what OpenGL commands to use.


You need to encode the desired translation in the model-view matrix. In older versions of OpenGL, this could be done with glTranslate. In modern OpenGL, you would typically manage your own matrices, and send the raw data to the shader program, using glUniformMatrix.

+---------------------------------------------------------------------+

| Game Dev video tutorials -> http://www.youtube.com/goranmilovano | +---------------------------------------------------------------------+
Alright, then I need to figure out what I'm doing wrong. I have the following:


void RenderScene()
{
std::sort (RenderList.begin(), RenderList.end(), SortRenderList);
glMatrixMode(GL_MODELVIEW);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0f, 1.0f, 1.0f);
glLoadIdentity();
glTranslatef(MyCamera->GetPosX(), MyCamera->GetPosY(), MyCamera->GetPosZ());
uintptr_t LastKey = (uintptr_t)-1;
uintptr_t LastMeshKey = (uintptr_t)-1;
uintptr_t LastTexKey = (uintptr_t)-1;
uintptr_t LastMatKey = (uintptr_t)-1;
for (RenderListIT = RenderList.begin(); RenderListIT != RenderList.end(); RenderListIT++)
{
glPushMatrix();
glLoadIdentity();
glTranslatef((*RenderListIT)->Position->x, (*RenderListIT)->Position->y, (*RenderListIT)->Position->z);

glScalef ((*RenderListIT)->Scale->x, (*RenderListIT)->Scale->y, (*RenderListIT)->Scale->z);
glRotatef ((*RenderListIT)->Rotation->x, 1.0f, 0.0f, 0.0f);
glRotatef ((*RenderListIT)->Rotation->y, 0.0f, 1.0f, 0.0f);
glRotatef ((*RenderListIT)->Rotation->z, 0.0f, 0.0f, 1.0f);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
glEnable(GL_LIGHTING);
if ((*RenderListIT)->Key != LastKey)
{
LastKey = (*RenderListIT)->Key;
DrawCalls++;
if ((*RenderListIT)->RenderMesh->Materials->Key != LastMatKey)
{
LastMatKey = (*RenderListIT)->RenderMesh->Materials->Key;
if ((*RenderListIT)->RenderMesh->HasMaterials == true)
{
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, (*RenderListIT)->RenderMesh->Materials->Diffuse );
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, (*RenderListIT)->RenderMesh->Materials->Specular );
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (*RenderListIT)->RenderMesh->Materials->Ambient );
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, (*RenderListIT)->RenderMesh->Materials->Emission );
}
}
if ((*RenderListIT)->RenderMesh->Key != LastMeshKey)
{
LastMeshKey = (*RenderListIT)->RenderMesh->Key;
if (VBO_Support)
{
glVertexPointer( 3, GL_FLOAT, sizeof(MyVertex), (GLvoid*) (*RenderListIT)->RenderMesh->VBO_Offset );
glNormalPointer( GL_FLOAT, sizeof(MyVertex), (GLvoid*)((*RenderListIT)->RenderMesh->VBO_Offset+sizeof(float)*3) );
glTexCoordPointer( 2, GL_FLOAT, sizeof(MyVertex), (GLvoid*)((*RenderListIT)->RenderMesh->VBO_Offset+sizeof(float)*6) );
glColorPointer( 3, GL_FLOAT, sizeof(MyVertex), (GLvoid*)((*RenderListIT)->RenderMesh->VBO_Offset+sizeof(float)*8) );
}
else
{
glVertexPointer( 3, GL_FLOAT, sizeof(MyVertex), &(*RenderListIT)->RenderMesh->VertexData->x );
glNormalPointer( GL_FLOAT, sizeof(MyVertex), &(*RenderListIT)->RenderMesh->VertexData->nx );
glTexCoordPointer( 2, GL_FLOAT, sizeof(MyVertex), &(*RenderListIT)->RenderMesh->VertexData->u );
glColorPointer( 3, GL_FLOAT, sizeof(MyVertex), &(*RenderListIT)->RenderMesh->VertexData->a );
}
}
if ((*RenderListIT)->RenderMesh->Active->Key != LastTexKey)
{
LastTexKey = (*RenderListIT)->RenderMesh->Active->Key;
if ((*RenderListIT)->RenderMesh->HasTexture == true)
{
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, (*RenderListIT)->RenderMesh->Active->TextureHandle);
}
else
{
glDisable(GL_TEXTURE_2D);
}
}
}
glDrawArrays(GL_TRIANGLES, 0, (*RenderListIT)->RenderMesh->NumVerticies);
glPopMatrix();
}
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
glDisable(GL_LIGHTING);
}


And it's not moving the screen.

HELP!
I would say that the effects of the initial glTranslate call (made for the camera) are being eliminated by by the glLoadIdentity calls in the render loop.

The push/pop matrix calls should be used to preserve the view transform, which can then be further modified to include world-space transformations for the object in question.

You should do additional research on matrices.

PS:

It's often a good idea to start with a very simple example, rather than a piece of your own complex system, especially when you're just learning the basics. So, for this question, it would be better for everyone if you were simply trying to move a single quad, rather than process some pipeline of your own design.

Also, if you're interested, you can look at a demo that I wrote for someone else, where translation and zoom are demonstrated in a fairly simple OpenGL program: Link

+---------------------------------------------------------------------+

| Game Dev video tutorials -> http://www.youtube.com/goranmilovano | +---------------------------------------------------------------------+

This topic is closed to new replies.

Advertisement