FaytesEnd's picture

Anyone know any good tutorials on cameras in opengl...

Hello all,
so I'm reading the super bible fourth edition...
I get to the end of chapter four with the 'Sphere World' example, but I'm having a tough time figuring out if i have the GL.Frustum setup right and camera basics.

Anyone know any good tutorials for learning the camera? (should I normalize vectors? use certain default values?)
While in perspective mode, the edges of the screen look warped, like the object, a torus in this case, bends near the edges....

Here are some code snippets in-case I'm doing something silly and obviously wrong.

Setting up viewport and perspective/ortho

protected override void OnClientSizeChanged(EventArgs e)
    {
      base.OnClientSizeChanged(e);
      if (_glLoaded)
      {
        // Viewport to window dimensions, so it covers the whole window
        if (glControl1.Dock == DockStyle.Fill)
          GL.Viewport(0, 0, this.ClientSize.Width, this.ClientSize.Height);
        else
          GL.Viewport(0, 0, glControl1.Width, glControl1.Height);
 
        // open gl takes whole window
        if(glControl1.Dock == DockStyle.Fill)
          Setup2DGraphics(ClientSize.Width, ClientSize.Height);
        else // open gl is not whole window
          Setup2DGraphics(glControl1.Width, glControl1.Height);
 
        UIHelper.GLControlWidth = glControl1.Width;
        UIHelper.GLControlHeight = glControl1.Height;
      }
    }
 
    private void Setup2DGraphics(double width, double height)
    {
      //double nRange = 100.0;
      double halfWidth = width / 2;
      double halfHeight = height / 2;
 
      // reset coordinate system
      GL.MatrixMode(MatrixMode.Projection);
      GL.LoadIdentity();
 
      // from game book
      // Establish clipping volume (left, right, bottom, top, near, far)
      //GL.Ortho(-halfWidth, halfWidth, -halfHeight, halfHeight, -200, 200);
      if (UIHelper.Ortho)
        GL.Ortho(-halfWidth, halfWidth, -halfHeight, halfHeight, UIHelper.ZNearOrthographic, UIHelper.ZFar);
      else if (UIHelper.Perspective)
        SetPerspectiveMode(UIHelper.PerspectiveViewAngle, width / height, UIHelper.ZNearPerspective, UIHelper.ZFar);
        //SetPerspectiveMode((float)Math.PI / 4, width / height, UIHelper.ZNearPerspective, UIHelper.ZFar);
      else
        throw new Exception("Invalid view state.");
 
        // from super bible
        // Establish clipping volume (left, right, bottom, top, near, far)
        //if (width <= height)
        //  GL.Ortho(-nRange, nRange, -nRange * height / width, nRange * height / width, -nRange, nRange);
        //else
        //  GL.Ortho(-nRange * width / height, nRange * width / height, -nRange, nRange, -nRange, nRange);
 
      GL.MatrixMode(MatrixMode.Modelview);
      GL.LoadIdentity();
    }
 
// from tutorial found online
protected static void SetPerspectiveMode(double fov, double aspect, double near, double far)
    {
      double fovRadians = fov * (Math.PI / 180); // convert to radians
      double y = Math.Tan(fovRadians / 2.0) * near;
      double x = y * aspect;
      GL.Frustum(-x, x, -y, y, near, far);
    }

Drawing classes (uses and update/render system)

public void Update(double elapsedTime)
    {
      // update input
      _mouse.Update(elapsedTime);
      _keyboard.Process();
      //System.Diagnostics.Trace.WriteLine("mouse position : " + _mouse.Position.X + " " + _mouse.Position.Y);
 
      // looking at
      mouseDelta = new Point(_mouse.Position.X - lastMousePosition.X, _mouse.Position.Y - lastMousePosition.Y);
      lookAt.X += mouseDelta.X;
      lookAt.Y += mouseDelta.Y;
      lastMousePosition = _mouse.Position;
      //System.Diagnostics.Trace.WriteLine("mouse delta -> " + mouseDelta.X + " " + mouseDelta.Y);
 
      // position
      if (_keyboard.IsKeyPressed(Keys.D) || _keyboard.IsKeyHeld(Keys.D))
        cameraPosistion.X += 10;
 
      if (_keyboard.IsKeyPressed(Keys.A) || _keyboard.IsKeyHeld(Keys.A))
        cameraPosistion.X -= 10;
 
      if (_keyboard.IsKeyPressed(Keys.W) || _keyboard.IsKeyHeld(Keys.W))
        cameraPosistion.Z += 10;
 
      if (_keyboard.IsKeyPressed(Keys.S) || _keyboard.IsKeyHeld(Keys.S))
        cameraPosistion.Z -= 10;
 
      // lock to screen? move mouse back
      if (false) // TODO FIX!
      {
        centerCursorPosition = new System.Drawing.Point(_form.Location.X + (int)UIHelper.ViewCenterPoint.X, _form.Location.Y + (int)UIHelper.ViewCenterPoint.Y);
        System.Windows.Forms.Cursor.Position = centerCursorPosition;
        lastMousePosition = new Point(centerCursorPosition.X, centerCursorPosition.Y);
      }
    }
 
    public void Render()
    {
      GL.ClearColor(Color.SkyBlue);
      GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
 
      //System.Diagnostics.Trace.WriteLine("look at -> " + lookAt.X + " " + lookAt.Y );
      camera = Matrix4d.LookAt(cameraPosistion, // eye - keyboard control?
                               lookAt, // target - mouse control?
                               new Vector3d(0,1,0)); // up
      GL.PushMatrix();
      {
        GL.LoadMatrix(ref camera);
        drawAxis.Draw(true);
 
        GL.Color3(Color.Red);
        GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
        GL.PushMatrix();
        {
          if (UIHelper.Perspective)
          {
            // push the coordinate system back
            GL.Translate(0, 0, -300);
          }
          new Torus().Draw(10.0f, 5.0f, 20, 20);
        }
        GL.PopMatrix();
 
      }
      GL.PopMatrix();
    }
  }

Some default values... (from the static UIHelper class)

      VSync = true;
      Ortho = true;
      PerspectiveViewAngle = 90.0; // Standard in most games
      ZNearOrthographic = -1500;
      ZNearPerspective = 1;
      ZFar = 1500;  // perspective and orthographic

Any thoughts? This is still all new to me... I wish school taught me more of this.....

Inline Images
Odd stretching in perspective mode near screen edge