UPDATE The error here was a pretty simple one. I have missed a radian to degrees conversion. No need to read the whole thing if you have some other problem.

I looked at several tutorials about this and when I thought I understood I tried to implement a quaternion based camera. The problem is it doesn't work correctly, after rotating for approx. 10 degrees it jumps back to -10 degrees. I have no idea what's wrong. I'm using openTK and it already has a quaternion class. I'm a noob at opengl, I'm doing this just for fun, and don't really understand quaternions, so probably I'm doing something stupid here. Here is some code: (Actually almost all the code except the methods that load and draw a vbo (it is taken from an OpenTK sample that demonstrates vbo-s))

I load a cube into a vbo and initialize the quaternion for the camera

protected override void OnLoad(EventArgs e) {

    cameraPos = new Vector3(0, 0, 7);
    cameraRot = Quaternion.FromAxisAngle(new Vector3(0,0,-1), 0);


    vbo = LoadVBO(CubeVertices, CubeElements);

I load a perspective projection here. This is loaded at the beginning and every time I resize the window.

protected override void OnResize(EventArgs e) {

    GL.Viewport(0, 0, Width, Height);

    float aspect_ratio = Width / (float)Height;

    Matrix4 perpective = Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspect_ratio, 1, 64);
    GL.LoadMatrix(ref perpective);

Here I get the last rotation value and create a new quaternion that represents only the last rotation and multiply it with the camera quaternion. After this I transform this into axis-angle so that opengl can use it. (This is how I understood it from several online quaternion tutorials)

protected override void OnRenderFrame(FrameEventArgs e) {

    GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

    double speed = 1;
    double rx = 0, ry = 0;

    if (Keyboard[Key.A]) {
        ry = -speed * e.Time;

    if (Keyboard[Key.D]) {
        ry = +speed * e.Time;

    if (Keyboard[Key.W]) {
        rx = +speed * e.Time;

    if (Keyboard[Key.S]) {
        rx = -speed * e.Time;

    Quaternion tmpQuat = Quaternion.FromAxisAngle(new Vector3(0,1,0), (float)ry);
    cameraRot = tmpQuat * cameraRot;


    Vector3 axis;
    float angle;

    cameraRot.ToAxisAngle(out axis, out angle);
    //GL.Rotate(angle, axis);
    GL.Rotate(angle * (float)180.0/(float)Math.PI, axis);


Here are 2 images to explain better: I rotate a while and from this:


it jumps into this

enter image description here

Any help is appreciated.

Update1: I add these to a streamwriter that writes into a file:

    sw.WriteLine("camerarot: X:{0} Y:{1} Z:{2} W:{3} L:{4}", cameraRot.X, cameraRot.Y, cameraRot.Z, cameraRot.W, cameraRot.Length);
    sw.WriteLine("ry: {0}", ry);

The log is available here: http://www.pasteall.org/26133/text. At line 770 the cube jumps from right to left, when camerarot.Y changes signs. I don't know if this is normal.

Update2 Here is the complete project.

  • 2
    \$\begingroup\$ I don't understand the problem. Have you tried printing out the quaternions that you're using to render with? \$\endgroup\$ Nov 5 '11 at 18:24
  • 1
    \$\begingroup\$ Agreed, debug your rx, ry and Quaternion values. \$\endgroup\$ Nov 5 '11 at 23:09
  • \$\begingroup\$ Why don't you upload your entire project somewhere to rapidshare? Would be easier. \$\endgroup\$
    – bobobobo
    Nov 27 '11 at 0:50
  • \$\begingroup\$ OK I will upload it when I get home. \$\endgroup\$ Nov 28 '11 at 8:02

While you haven't shown the necessary code to verify my assumption here, I can almost guarantee that your problem is actually that this line:

cameraRot.ToAxisAngle(out axis, out angle);

is returning an angle value expressed in radians, while

GL.Rotate(angle, axis);

wants angle to be provided in degrees.

To fix it, you need to convert the angle value when passing it to GL.Rotate(), like this:

GL.Rotate(angle * 180.0/3.141593, axis);
  • \$\begingroup\$ Yes, that was the problem. :) Thanks a lot. I knew opengl expects degrees, I assumed that ToAxisAngle returns degrees. I just looked at the opentk code and it is radians. BTW I have provided full source code at the end. \$\endgroup\$ Dec 1 '11 at 19:14
  • \$\begingroup\$ @NickCaplinger correctly points out that in C#, there is a Math.Pi constant available, which should be used in preference to the literal 3.141593 value I used in that final calculation. \$\endgroup\$ Jun 1 '13 at 0:04

Don't. It may seem that it would be less work to have a camera that can be manipulated like other scene objects, but in the long run it is better to have a camera where you can define a position, eye direction and up vector. Especially when you start programming motion models it is really a pain to work with quaternions.

  • 1
    \$\begingroup\$ Agreed. I'm not a fan of the "if it's hard to pronounce it must be better" method of designing my applications, too =) \$\endgroup\$ Nov 30 '11 at 19:35
  • \$\begingroup\$ Quaternion is hard to pronounce? \$\endgroup\$
    – notlesh
    Nov 30 '11 at 20:55
  • 1
    \$\begingroup\$ A little humor goes a long way =D By inference I imply that the question comes from someone who has no idea WHY he wants a quaternion camera, just that it's a neat buzzword and OMG I want it sooo bad now! It's certainly not a subject to tackle when something like handling radians and degree parameters properly in the broken code above isn't dealt with properly. \$\endgroup\$ Nov 30 '11 at 21:34
  • 3
    \$\begingroup\$ This question isn't really about cameras; it's about how to represent rotations in game code, and how to convert those game representations into a form such that OpenGL can use them. It's a perfectly legitimate question, and I don't think mocking the OP's lack of domain experience is helpful in any way. It's not like the OP made a stupid mistake; OpenGL's insistence on using degrees when expressing angles is downright bizarre. Everyone makes this mistake their first time using OpenGL. So get off your high horses, people. Geez. \$\endgroup\$ Nov 30 '11 at 22:27
  • \$\begingroup\$ I just wanted to understand how a quaternion based camera works and I made this project in a day when I had nothing else to do. I have no real plans with this. \$\endgroup\$ Dec 1 '11 at 18:57

Don't know much about OpenTK internals. In my experience I did not see math library with proper implementation of quat that keeps needed precision (machine), because all of them affects e^2-e^3 errors. So the effect you see: the precision (and epsilon value) is about 10^-5, and it 'jumps' near zero. This is my guess :)


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.