PDA

View Full Version : OpenGL Camera Tutorial???



jdarling
21-07-2010, 07:56 PM
Ok, this is going to sound stupid, but I'm looking for a SIMPLE to understand tutorial that utilizes vectors to create a camera in OpenGL. I've searched around with Google and the best I've found (so far) is the one in the NeHe articles. Problem is, it only explains rotation on Y and movement forward and back.

What I'd love to learn is something along the following:
1) Placement of the camera within the world
2) Follow an object given a viewing sphere
3) Smooth transformation from one object to another
4) Free movement of camera over "landscape"

From what I can figure out thus far, I need to have a Vector for the Camera position and a Vector for the Camera orientation (rotation?). Then its "a simple matter of moving/rotating these vectors", only I can't figure out the simple matter :)

Does anyone have a truly for dummies version of Camera's for OpenGL?

- Jeremy

PS: Yes, I'm back on my quest for 3D. Prolly should stick with what I know, 2D, but I can't help but want to play in that 3rd dimension :)

Traveler
21-07-2010, 09:05 PM
This (http://www.sulaco.co.za/opengl_project_Basic_3D_engine.htm) one perhaps?

chronozphere
21-07-2010, 11:22 PM
Getting stuff on your screen using OpenGL happens through transformations. These will determine how every object is positioned on your screen (in other words: how your camera is positioned with respect to that object).

First, some theory. Transformations exist in three flavours:

World transformations:

These will "place" your objects in the world. Typically, you set the world transformation for a specific object before you render it. All the vertices will be transformed so that the object is translated/rotated/scaled as you like.

View transformations:

The view transform determines how your camera is placed in the world, or how the world is placed in your camera. ;) After everything has been transformed to world space, geometry is transformed to view space. This is the most important bit, when you want to dive into camera control and such. In view space, the X and Y axis are aligned to your screen and Z is perpendicular to it.

Projection transformation:

Right now, all objects with size X have the same size on screen, no matter how far they are from the camera. This is where the projection matrix is for. You can set up a perspective projection matrix using a function like gluPerspective() if I recall correctly. This will make distant objects smaller. If you dont want distant objects to be smaller (e.g for an Isometric-ish view) you can use an Orthogonal projection matrix ( glOrtho() ).

After all these transformations, you can simply throw away the Z component and you will have X, Y screen space coordinates, like in 2D games. :)

In openGL, the world and the view transformations are combined and they are called "modelview" transform. The projection is kept separate.

Some practical information now:

To set up a camera:

glMatrixMode(GL_MODELVIEW); //switch to modelview matrix mode
glLoadIdentity(); //Load identity matrix (this matrix does nothing)

//Now you will add a new transformation on top of the identity matrix we loaded earlier.
//This is a typical camera transformation. You set the position of the camere, the location
//where you are looking at and an upvector.
//The upvector is neccesary to explain what up is. I could ask you to look at your keyboard, //but you can still do so, if you were turned upside down.
gluLookAt(CameraPosition, CameraLookAt, CameraUp);

//Some more calls here, to build the world transform on top of the view transform

//Render your object here


Hope this helps a bit. I think there are plenty of tutorials that will get you started with this. :)

User137
22-07-2010, 06:58 AM
There is no real camera in OpenGL. Even glRotate, glTranslate are all matrix multiplications. If you end up using too many these calls you may speed up program alot if you have own camera-matrix variable. Position/rotate it when needed and apply it to OpenGL with glMultMatrix.

But for sure first is best to practise with those default functions.

Edit: Also, this own matrix is the only way to make a camera to a space simulator or anything requiring free rotation.

What more should i add to this, is that you don't need separate vectors or angles stored anywhere anymore. 1 single matrix contains rotation and position as 4 vectors in itself.

This is how opengl.org described it:

As far as OpenGL is concerned, there is no camera. More specifically, the camera is always located at the eye space coordinate (0., 0., 0.). To give the appearance of moving the camera, your OpenGL application must move the scene with the inverse of the camera transformation.

jdarling
22-07-2010, 01:03 PM
Thanks for the links and basics so far... Let me see if I have this somewhat correct:
1) Translate/rotate my view (Camera) before I do anything else. This is one mistake I've been making as I thought I was setting up the "world" and then moving through it.
2) Stop trying to consider world and view as different, I never change the world moves around me LOL
3) I need to call glMatrixMode(GL_MODELVIEW) some place in my code.
4) glLoadIdentity() seems to reset the view (or is it world) matrix back to 0 so, for "world" translations call it before you move something. For relative movement (IE: Based on the position of something else) don't call it?
5) ... I'm still lost :(, then again 3D has evaded me for many MANY years now.

If I wanted to have a basic "object" it would seem that it would have a placement vector and a rotation vector, but reading User137's post that would be wrong?

There has to be a for dummies out there I haven't read yet LOL :D

- Jeremy

jdarling
22-07-2010, 04:35 PM
Ok, I think I'm starting to understand the 4x4 Matrix and its relation ship to a basic 3D vector.

If I define a vector as: v={X,Y,Z}
Then that exact same Vector described (using the Matrix Identity) as a 4x4 Matrix would be:

M={
X, 0, 0, 0
0, Y, 0, 0
0, 0, Z, 0
0, 0, 0, 1
}

As there has been no rotation, translation, or scale applied. If I apply translation, rotation, and/or scale I can still retrieve the basic position (in world space) by using the Identity matrix and multiplying it by the result matrix. Thus a faster way to convert it from a Matrix to a BASIC world position would be to extract out those 3 parts.

Now, I have to setup a base matrix for translation, rotation, and scale then use that * the current matrix to perform translations, rotation, and scaling within 3D space. According to one article I found (http://www.gamedev.net/reference/articles/article415.asp) those matrix should be:

Matrix for a 3D translation of (tx, ty, tz)
1 0 0 0
0 1 0 0
0 0 1 0
tx ty tz 1

Matrix for a 3D scaling of (sx, sy, sz)
sz 0 0 0
0 sy 0 0
0 0 sx 0
0 0 0 1

Matrix for a 3D rotation around the x axis of q
0 0 0 0
0 cos(q) sin(q) 0
0 -sin(q) cos(q) 0
0 0 0 1

Matrix for a 3D rotation around the y axis of q
cos(q) 0 -sin(q) 0
0 1 0 0
sin(q) 0 cos(q) 0
0 0 0 1

Matrix for a 3D rotation around the z axis of q
cos(q) sin(q) 0 0
-sin(q) cos(q) 0 0
0 0 1 0
0 0 0 1


So, I need to setup a basic set of routines or objects to handle all of this LOL.

Now, I'm also guessing that the Matrices above are for local space, and that I would basically need 1 Matrix per "object" (where object is a collection of "local" Vertices)?

- Jeremy

User137
22-07-2010, 05:27 PM
Like i said, you would be best off to start with vectors, angles using glTranslate and glRotate :) You can accomplish everything basic in understandable way with this.

angle:=angle+1; // Lets have a rolling angle variable
glLoadidentity; // Always reset at start of frame
glTranslatef(-1,0,-4); // Move "camera" 1 left and 4 backwards
glRotate(angle,0,1,0); // Rotate around Y-axis
// Draw...

// Now what happens is object is drawn in front of camera a little to right and is rotating around its center point.


If I define a vector as: v={X,Y,Z}
Then that exact same Vector described (using the Matrix Identity) as a 4x4 Matrix would be:

M={
X, 0, 0, 0
0, Y, 0, 0
0, 0, Z, 0
0, 0, 0, 1
}
This code actually should make a scale matrix. There is alot of ready code relating to matrices already made by many others. You can for example study/copy some source of GLScene or Next3D.

glRotate creates a rotation matrix and multiplies it with modelview_matrix.
glTranslate creates a translation matrix and multiplies it with modelview_matrix.
glScale etc...
glPushMatrix adds current modelview_matrix in a stack
glPopMatrix recalls previous modelview_matrix from a stack and deletes it

Projection matrix is set only when window is created or resized. Or if you change ortho (2D mode) in the middle of run to for example render a HUD, user interface or pixel perfect text.

chronozphere
22-07-2010, 05:54 PM
Thanks for the links and basics so far... Let me see if I have this somewhat correct:
1) Translate/rotate my view (Camera) before I do anything else. This is one mistake I've been making as I thought I was setting up the "world" and then moving through it.
2) Stop trying to consider world and view as different, I never change the world moves around me LOL
3) I need to call glMatrixMode(GL_MODELVIEW) some place in my code.
4) glLoadIdentity() seems to reset the view (or is it world) matrix back to 0 so, for "world" translations call it before you move something. For relative movement (IE: Based on the position of something else) don't call it?
5) ... I'm still lost :(, then again 3D has evaded me for many MANY years now.

If I wanted to have a basic "object" it would seem that it would have a placement vector and a rotation vector, but reading User137's post that would be wrong?

There has to be a for dummies out there I haven't read yet LOL :D

- Jeremy


1. Yes, In OpenGL you have to set up the camera before you can render your geometry. This is because the view transformation and the world (model) transformation are combined. You cannot independantly change one of them.

When you call OpenGL matrix functions, you are manipulating the one of the openGl matrices (this depends on the mode you are in. change it using glMatrixMode() ). Most functions will add new transformations on top of the ones you allready built. Let's say if you do:


glScale( ... )
glRotate( ... )
glTranslate( ... )


and you want to change the scale again, you cannot. You must either call glLoadIdentity() and rebuild everything from ground up or use a the transform stack:


glScale( ... )
glPushMatrix(); //We push the current Modelview matrix to the stack to save it

//So some additional transforms
glRotate( ... )
glTranslate( ... )

//Render some stuff

glPopMatrix(); //We pop the matrix that we pushed from the stack to restore its transformation


2. Well, you need to view these things as separate because they actually are. It's just that opengl doesn't separate them, so if you are thinking in terms of OpenGL programming, these are indeed combined. Direct3D seperates the view from the world transform, and I think that's a better way.

3. Yeah, every time you want to modify the MODELVIEW matrix, you have to call this routine. Unless you are sure that OpenGL is allready in MODELVIEW mode. This takes some getting used to.

4. Yes, glLoadIdentity() is used to reset your transform. Be carefull with this, because if you do this, you will also reset your camera transform (because MODELVIEW was view+model combined). You probably want to use the stack to save the transforms.

5. The hardest part of this is properly understanding matrices and vectors. It took me a lot of time to squeeze them in, but it was worth it. I suggest you start looking at simple demo's and start decomposing them. If you understand how they are build, you're on the right track.

Hope this helps. ;)

jdarling
22-07-2010, 06:22 PM
I've been able to get my head around Vectors fairly well. In fact to the point that I can build a basic wire mesh 3D render. I'm just stuck with the whole Matrix thing...

A few things that have me are:
1) Converting (properly) from a Vector to a Matrix (or, would this simply be creating a new 0 matrix and translating it to v?)
2) Converting from a Matrix to a Vector
3) What the f@*% is q???? I'm used to radians and angles, where did q come from? I'm guessing this isn't the q from StarTrek

Now, on subject 2, I've read several contradicting articles (at least they read that way to me). Some saying sample (0, 0), (1, 1) and (2, 2) some saying sample (3, 0), (3, 1) and (3, 2) (as x, y, z respectively in both cases). Each with working examples :( I'm a bit more inclined to believe the 3, 0 version.

- Jeremy

User137
22-07-2010, 07:03 PM
A few things that have me are:
1) Converting (properly) from a Vector to a Matrix (or, would this simply be creating a new 0 matrix and translating it to v?)
2) Converting from a Matrix to a Vector
3) What the f@*% is q???? I'm used to radians and angles, where did q come from? I'm guessing this isn't the q from StarTrek
1) Your question does not make any sense. What are you trying to achieve?
Translation matrix looks like (This is matrix that glTranslate uses):

1 0 0 x
0 1 0 y
0 0 1 z
0 0 0 1

2) Again question don't make sense. Matrix contains 4 vectors: Left,Up,Front,Position
If i mark them as L,U,F,P and each have x,y,z component:

Lx Ux Fx Px
Ly Uy Fy Py
Lz Uz Fz Pz
0 0 0 1

3) Need link to algorithm using such. People use different symbols and terms. As a game programmer you don't really need to know deep insight on how all the functions work, only the big picture on how the matrixes can be used.

jdarling
22-07-2010, 07:26 PM
I gave the link in a previous post:

Now, I have to setup a base matrix for translation, rotation, and scale then use that * the current matrix to perform translations, rotation, and scaling within 3D space. According to one article I found (http://www.gamedev.net/reference/articles/article415.asp) those matrix should be:

Just in case, the link is: http://www.gamedev.net/reference/articles/article415.asp

Looks like your using row based instead of column based matrices since your x, y, z are running vertical (if I'm reading properly through the plethora of articles).

Looking specifically at his rotation matrices he refers to q, and so do many many others (just as an example, hit just about any of the articles on GameDev about Matrix Math and Rotations http://www.gamedev.net/reference/list.asp?categoryid=259). So, my basic question is, what is q?

- Jeremy

User137
22-07-2010, 09:35 PM
In the article, q means angle. It means basically similar calculation than what glRotate uses. Article just defines matrices around set X, Y or Z axis instead of any vector.
The sections answer to question "I have axis Y and i want to turn q degrees around it, what is the rotation matrix?"

I just wrote in form that came to mind first. It is different thing how different libraries define their matrix array. However with OpenGL everyone is using the same system.

chronozphere
23-07-2010, 03:50 PM
The key to all the 3d goodness lies in the understanding of matrices and vectors. Vectors aren't that hard, and I think you understand those pretty well. The matrices on the other hand are quite tough.

First you should exactly understand what a matrix does. It defines the relationship between two coordinate spaces and can be used to transform vectors from coordinate space A to coordinate space B. Read some more articles about matrices until you can visualize this.

If you really want to dive into this, I suggest you buy "3d math primer for graphics and game development". I have a hard copy here, and its definitely a good read. It covers all vector and matrix math you will need.