Jump to content
  • Advertisement
Sign in to follow this  
AticAtac

OpenGL 3D free camera

This topic is 2146 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi folks,

 

i am using a SDK which is based on OpenGL ES and provides me a LookAt(from, to, up) function to construct a view matrix for camera.

What i want to achieve is implement a camera which can be moved freely using mouse (looking left/right and up/down) and keyboard (moving foreward/backwar and strafe left/right).

I initially set up the camera matrix with the required vectors (from, to, up) and need to maintain theses vectors while changing the camera orientation (mouse look).

Moving is easy, i can easily change camera location (from), up vector doesn't change.

What i need are code/calculations how to "maintain" the up/to vectors once camera orientation is changed.

 

any help welcome ;)

 

Share this post


Link to post
Share on other sites
Advertisement

"What i need are code/calculations how to "maintain" the up/to vectors once camera orientation is changed."

 

For a flycam, my recommendation is don't "maintain" the 'up' and 'to' vectors. Maintain heading and pitch angles and use them to construct your 'up' and 'to' vector.

 

I think this is correct, (but it's untested):

 

to = from + vector3(cosf(pitch) * sinf(heading), -sinf(pitch), cosf(pitch) * cosf(heading))

up = vector3(sinf(pitch)*sinf(heading), cosf(pitch), sinf(pitch)*cosf(heading));

Share this post


Link to post
Share on other sites

The "to" vector can be calculated by adding a small value to the camera position that will always be in front of the camera. You just transform the small vector by the camera matrix so its pointing in the correct direction then add it to the camera position, that can be your lookat position. Then you can do some cross products to calculate the correct "up" and "right" vectors.

 

Vector to(0,0,1);
to = cameraMatrix.TransformVector(to);
Vector lookat = cameraPosition + to;
Vector up(0,1,0);
Vector right = lookat.Cross(up);
up = lookat.Cross(right);

This link may also be useful to you for creating a free camera.

Edited by Nyssa

Share this post


Link to post
Share on other sites

Thx.

I picked the idea of using the 2 angles "pitch" and "roll" and reconstruct the vectors each time from these 2  and used the equations @C0lumbo gave me and it worked well.

Share this post


Link to post
Share on other sites

I've still got one problem:

using the equations and rendering a quad with an image it seems that the rotation around z-axis is not right, because the image looks like to be rotated 90° to right (around z-axis).

So instead of rendering an image with arrow on it like this

 

^

|

|

|

 

its rendered like this:

 

 

------>

 

 

 

Here is my camera (view matrix) update code:

 

 

float cos_pitch = cosf(pitch);
    float sin_pitch = sinf(pitch);
    float cos_roll = cosf(roll);
    float sin_roll = sinf(roll);

    _forward.x = cos_pitch * sin_roll;
    _forward.y = -sin_pitch;
    _forward.z = cos_pitch * cos_roll;
    _forward.Normalise();

    _up.x = sin_pitch * sin_roll;
    _up.y = cos_pitch;
    _up.z = sin_pitch * cos_roll;
    _up.Normalise();

    _right = _up ^ _forward;    
    if (_right.IsZero())
        _right.x = 1.0f;
    else
        _right.Normalise();
    _up = _forward ^ _right;    

    _view_mat.m[0][0] =  _right.x; _view_mat.m[0][1] = _right.y; _view_mat.m[0][2] =  _right.z;
    _view_mat.m[1][0] =  _up.x; _view_mat.m[1][1] =  _up.y; _view_mat.m[1][2] =  _up.z;
    _view_mat.m[2][0] =  _forward.x; _view_mat.m[2][1] =  _forward.y; _view_mat.m[2][2] = _forward.z;
 

 

 

and here is my quad rendering code:

// x,y,z : top left, verts go counter-clockwise
void RenderQuad(float x, float y, float z, float w, float h)
{
    static CIwFVec3 verts[4];
    verts[0] = CIwFVec3(x, y, z);
    verts[1] = CIwFVec3(x, y-h, z);
    verts[2] = CIwFVec3(x+w, y-h, z);
    verts[3] = CIwFVec3(x+w, y, z);
    IwGxSetVertStreamWorldSpace(s_Verts, 4);

    // texture-atlas 512x512 , image on tex-atlas at (0,0) -> (63,63)
    static CIwFVec2 uvs[4];
    uvs[0] = CIwFVec2(0.0f, 0.0f);
    uvs[1] = CIwFVec2(0.0f, 63.0f/512.0f);
    uvs[2] = CIwFVec2(63.0f/512.0f, 63.0f/512.0f);
    uvs[3] = CIwFVec2(63.0f/512.0f, 0.0f);
    IwGxSetUVStream(uvs);

    static uint16 strips[4];
    strips[0] = 0;
    strips[1] = 1;
    strips[2] = 3;
    strips[3] = 2;
    IwGxDrawPrims(IW_GX_QUAD_STRIP, strips, 4);
}

Share this post


Link to post
Share on other sites

to sum it up:

 

this is my quad in 3D-space

 

 

 

    0---3

    |      |

    |      |

   1----2

 

z=0

 

this is renderd on screen

 

 

    1---0

    |      |

    |      |

   2----3

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!