Jump to content

  • Log In with Google      Sign In   
  • Create Account

Interested in a FREE copy of HTML5 game maker Construct 2?

We'll be giving away three Personal Edition licences in next Tuesday's GDNet Direct email newsletter!

Sign up from the right-hand sidebar on our homepage and read Tuesday's newsletter for details!


We're also offering banner ads on our site from just $5! 1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


How cameras work


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
10 replies to this topic

#1 Lacoste   Members   -  Reputation: 104

Like
0Likes
Like

Posted 14 May 2013 - 04:27 AM

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



Sponsor:

#2 Lacoste   Members   -  Reputation: 104

Like
0Likes
Like

Posted 14 May 2013 - 04:41 AM

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



#3 Olof Hedman   Crossbones+   -  Reputation: 2901

Like
1Likes
Like

Posted 14 May 2013 - 06:08 AM

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


Edited by Olof Hedman, 14 May 2013 - 06:24 AM.


#4 Lacoste   Members   -  Reputation: 104

Like
0Likes
Like

Posted 14 May 2013 - 07:25 AM

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



#5 Olof Hedman   Crossbones+   -  Reputation: 2901

Like
0Likes
Like

Posted 14 May 2013 - 07:42 AM

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.



#6 Norman Barrows   Crossbones+   -  Reputation: 2204

Like
0Likes
Like

Posted 14 May 2013 - 08:06 AM

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 1988"

 

rocklandsoftware.net

 


#7 Lacoste   Members   -  Reputation: 104

Like
0Likes
Like

Posted 14 May 2013 - 08:28 AM

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

 



#8 Norman Barrows   Crossbones+   -  Reputation: 2204

Like
0Likes
Like

Posted 14 May 2013 - 06:26 PM

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 1988"

 

rocklandsoftware.net

 


#9 Kryzon   Prime Members   -  Reputation: 3226

Like
0Likes
Like

Posted 14 May 2013 - 06:32 PM

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

Edited by Kryzon, 14 May 2013 - 06:32 PM.


#10 Norman Barrows   Crossbones+   -  Reputation: 2204

Like
0Likes
Like

Posted 14 May 2013 - 06:40 PM

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 1988"

 

rocklandsoftware.net

 


#11 VladR   Members   -  Reputation: 722

Like
0Likes
Like

Posted 16 May 2013 - 02:00 PM

So, which API do you use ? OpenGL or DirectX ? Or perhaps, XNA ?

 

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

That's an advanced camera behaviour that the racing games use.

There are multiple StartPos, EndPos points, in-between which, the engine smoothly interpolates (with ease-in, ease-out speed adjustment) to construct the "feel" of the camera.

 

If I were you, I would definitely spend the time and start learning about the World/View/Projection Matrices. Specifically - try to create (not just copy/paste) a code that can create the View Matrix from the points LookFrom, LookAt and vectors Up/Right.

 

Otherwise, you won't really be able to create some advanced camera behavior - you really need to understand the rows and columns of the view matrix.


VladR    My 3rd person action RPG on GreenLight:    http://steamcommunity.com/sharedfiles/filedetails/?id=92951596

 





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS