How cameras work

Started by
9 comments, last by VladR 10 years, 11 months ago

Hi,

I'm new to 3d graphics programming. First i learned some 3d math from books, then i created a few 3d objects (cube, cone) and rotated them around axisses. Now i have 2 questions

1) help me to create simple 3d camera that i can place it everywhere i want and rotate

2) please explain me in 3d games is camera moving while person makes move, for example in Temple Run

any kind of answer would be appreciated thank you

Advertisement

also please take a look a the CSR Racing

">

any thoughts about how camera is working in this game? is camera fixed or is moving with the vehicle how to determine

For all 3d graphics, the "camera" is just a useful abstraction for how to construct the view and projection transform matrix.

If it "moves" or not, is up to you as a programmer to decide, depending on how you want to look at it.

It's equally valid to see it as the camera moves around, as it is to see it as the world is rotated and moved around the camera.

The math will be the same.

I'd recommend you chose whatever you feel is intuitive, that usually results in better structured code.

A very common way is to construct the view matrix from an eye-position, a lookat-point, and an up-vector.

The "camera" would just be these values stored somewhere (maybe in a class called Camera)

Here is the code for gluLookAt, which implement this: http://www.opengl.org/wiki/GluLookAt_code

For all 3d graphics, the "camera" is just a useful abstraction for how to construct the view and projection transform matrix.

If it "moves" or not, is up to you as a programmer to decide, depending on how you want to look at it.

It's equally valid to see it as the camera moves around, as it is to see it as the world is rotated and moved around the camera.

The math will be the same.

I'd recommend you chose whatever you feel is intuitive, that usually results in better structured code.

A very common way is to construct the view matrix from an eye-position, a lookat-point, and an up-vector.

The "camera" would just be these values stored somewhere (maybe in a class called Camera)

Here is the code for gluLookAt, which implement this: http://www.opengl.org/wiki/GluLookAt_code

Thank you very much for your answer, will take a look.

In the camera class example you've shared, there are no near pane/far pane am i understand right? So, how much space you will see if there are no edges

Ah, no, gluLookat only constructs the view matrix. that is, how to rotate and move your world/camera to show the right part on the screen.

near and far plane is used to construct the projection matrix

Here is code for gluPerspective, which set up a projection matrix from field of view, near and far and aspect ratio: http://www.opengl.org/wiki/GluPerspective_code

these are just examples on how to create the matrices, a complete camera class should probably have them both (and might be responsible for multiplying them together)

Projection matrix do not change when you move, so you only have to recalculate view matrix.

here's the setup i use:
you have a camera position cam_x,cam_y,cam_z. you have a camera rotation cam_xr,cam_yr,cam_zr.
these are used to create your view matrix.
an object you want to draw has a position x,y,z. and orientation xr,yr,zr.
these are used to create your world matrix.
you use near and far plane, and FOV and aspect ratio, or screen width and height, to set your projection matrix.
until you get into fancy stuff, you can just set the projection matrix once at program start and forget about it.
to draw,
1. clear the screen
2. set light(s) - until you get into fancy stuff, again here you can set it once at program start and forget it.
3. set the camera - set the camera's location and orientation to the player's location and orientation (or whatever you want). then compute and set your view matrix. the view matrix "moves" the "camera" to the origin and aims it down the z axis (in a left handed coordinate system). this makes the following projection math easier. the view matix is the reverse (inverse?) of moving the camera out into the world. IE instead of rotating then translating, you untranslate, then unrotate. so you translate by -cam_x,-cam_y,-cam_z. then you rotate by -cam_yr, then by -cam_xr (assuming 2 degrees of rotational freedom, like a 1st person shooter game). this is you view matrix. it moves the camera to the origin and aims it down the z axis. any other object you apply this matrix to will also untranslate and rotate, placing it where it would be if you moved everything so the camera was at the origin looking down the z axis. this is what was meant in the post above about rotating the world around the camera. you see, projection math is easier when the camera is at the origin. looking down z. so to get this, you "pick up" the world by the camera and move the entire thing and spin it around so the camera is at the origin and looking down z. this is the function of the view matrix. it translates world objects from their "world space" location, to their "camera space" location. world space is where they are in the world. camera space is where they are once you move the camera to the origin looking down z, and move everything else along with it.
4. set world transform for object 1. draw object 1.
5. repeat setting world transforms and drawing objects.
6. display the scene.
setting the camera to the location of the player's eyes gives you first person view. if you move the camera back, then rotate and translate, you get a 3rd person shooter chasecam:
the camera's "world tranform" would be move -20 z, rotate cam_xr, rotate cam_yr, translate cam_x,cam_y,cam_z. so the view matrix would be the opposite order: translate -cam_x,-cam_y,-cam_z, rotate -cam_yr, rotate -cam_xr, move +20 z.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

Thank you very much will check your answer and ask for any questions, maybe will share some piece of code ..

Must tell that i have no interaction with via email or other spammers, ad-senders, etc please explain why my second post was marked as an addvertisment? smile.pnghuh.png

maybe will share some piece of code ..
DX9 fixed function c/c++ : other flavors will be similar....
void Zclearscreen(int r,int g,int b)
{
Zd3d_device_ptr->Clear(0,NULL,D3DCLEAR_TARGET,D3DCOLOR_XRGB(r,g,b),1.0f,0);
}
// set parameters for a light
void Zsetlite(DWORD liteID,float x,float y,float z,float brightness)
{
D3DLIGHT9 light;
ZeroMemory(&light, sizeof(light));
light.Type=D3DLIGHT_DIRECTIONAL;
light.Diffuse=D3DXCOLOR(brightness,brightness,brightness,1.0f);
light.Ambient=D3DXCOLOR(0.0f, 0.0f, 0.0f, 1.0f);
light.Specular=D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
light.Direction.x=x;
light.Direction.y=y;
light.Direction.z=z;
Zd3d_device_ptr->SetLight(liteID, &light);
}
// turn a light on/off
void Zlite(DWORD liteID,int onoff)
{
if (onoff==1) Zd3d_device_ptr->LightEnable(liteID,TRUE);
else Zd3d_device_ptr->LightEnable(liteID,FALSE);
}
// set camera position and orientation
void Zsetcam(float x,float y,float z,float rx,float ry,float rz)
{
D3DXMATRIX m;
// save cam location for when we sort meshes for drawing based on range to cam
Zcamx=x;
Zcamy=y;
Zcamz=z;
Zcamxr=rx;
Zcamyr=ry;
Zcamzr=rz;
D3DXMatrixTranslation(&ZmView,-x,-y,-z);
D3DXMatrixRotationZ(&m,-rz);
D3DXMatrixMultiply(&ZmView,&ZmView,&m);
D3DXMatrixRotationY(&m,-ry);
D3DXMatrixMultiply(&ZmView,&ZmView,&m);
D3DXMatrixRotationX(&m,-rx);
D3DXMatrixMultiply(&ZmView,&ZmView,&m);
Zd3d_device_ptr->SetTransform(D3DTS_VIEW,&ZmView);
// std transform order: scale, xrot, yrot, zrot, translate.
// inv transform order: untranslate, -zrot, -yrot, -xrot, unscale.
}
// set camera position and orientation using rot matrix
void Zsetcam2(float x,float y,float z,D3DXMATRIX *m)
{
D3DXMATRIX m2;
// save cam location for when we sort meshes for drawing based on range to cam
Zcamx=x;
Zcamy=y;
Zcamz=z;
m2=*m; // preform inverse transform on a copy of m so we dont change the plane's rot matrix.
D3DXMatrixTranslation(&ZmView,-x,-y,-z);
//D3DXMatrixInverse(&m2,NULL,&m2);
//D3DXMatrixTranspose(&m2,&m2);
D3DXMatrixMultiply(&ZmView,&ZmView,&m2);
Zd3d_device_ptr->SetTransform(D3DTS_VIEW,&ZmView);
// std transform order: scale, xrot, yrot, zrot, translate.
// inv transform order: untranslate, -zrot, -yrot, -xrot, unscale.
}
for drawing, i get a little fancy. i have a struct called a Zdrawinfo. it has all the info to draw a mesh or model: position, orientation, cull, alphatest, clamp, materialID, meshID, textureID, modelID, animationID, etc. i fill in the fields in a Zdrawinfo, then either send it off to a list for later drawing (ordered on texture), or call Zdrawimmediate(), which sets the approprite states (via a state manager to eliminate unnecessary state changes) and calls DrawIndexedPrimitive().

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

Must tell that i have no interaction with via email or other spammers, ad-senders, etc please explain why my second post was marked as an addvertisment?

It wasn't marked as advertisement. The forum generates an "in-between" post to show advertisment. It's unrelated to yours smile.png

i set the projection matrix when i start the graphics engine with these 2 lines of code:

// create projection matrix... 45 deg vert FOV * 1600/900 aspect ratio = 80 deg horiz FOV
D3DXMatrixPerspectiveFovLH(&Zprojection_matrix,
D3DXToRadian(45), // the VERTICAL field of view (normally 45)
(float)width/(float)height, // aspect ratio
nearplane,
(float)farplane);
Zd3d_device_ptr->SetTransform(D3DTS_PROJECTION, &Zprojection_matrix); // set the projection
later, i use the following routine to set the near and far planes to draw far stuff (clouds) or near stuff (everything else):
void Zset_clip_planes(float nearplane,int farplane)
{
D3DXMatrixPerspectiveFovLH(&Zprojection_matrix,D3DXToRadian(45),(float)Zscreen_width/(float)Zscreen_height,nearplane,(float)farplane);
Zd3d_device_ptr->SetTransform(D3DTS_PROJECTION,&Zprojection_matrix);
Znearplane=nearplane;
Zfarplane=farplane;
}

the only other place i play with the projection is when modeling intoxication. the global variable "fov" is set to 45 (degrees) + some amount based on the player character's intoxication level. aspectratio is #defined as 1.777777777f. then the following routine is called:

void setfov()
{
D3DXMATRIX m;
D3DXMatrixPerspectiveFovLH(&m,
D3DXToRadian(fov), // the VERTICAL field of view
aspectratio, // aspect ratio
1.0f, // the near view-plane
200.0f); // the far view-plane
Zd3d_device_ptr->SetTransform(D3DTS_PROJECTION, &m); // set the projection
}

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

This topic is closed to new replies.

Advertisement