CS40 Lab 5: Camera motion and Perspective

Due 11:59pm Wednesday, 10 October 2018

For this lab, you'll extend lab 4 By adding a perspective projection and a camera class for easier navigation.

Getting started
Since you are extending syllabus4, you may continue to use the same git repo as last week.
Code updates
Copy over the camera.h header file and add it to your git repo. As usual, only one partner needs to do the initial copy, add, commit, and push, while the other can pull the changes
[~]$ cd ~/cs40/lab04
[lab04]$ cp ~adanner/public/cs40/lab05/* ./
Edit your lab04/CMakeLists.txt file to add camera.h to your program sources. Eventually you will also want to add camera.cpp, but since this file does not exist yet, do not add it until you start implementing your camera class.
target_sources(${PROGNAME} PRIVATE
  camera.h camera.cpp
  shaders/vshader.glsl shaders/fshader.glsl
[lab04]$ git add CMakeLists.txt camera.h README5.md
[lab04]$ git commit -m "lab 5 camera class start"
[lab04]$ git push
Basic Requirements
You will need to implement the Camera class as described. You can add additional methods/member variables, but do not remove the method declarations already in the header.

Use your camera class to specify the camera location for the vertex shader. Add a new uniform mat4 camera variable to your vertex shader. You may want to change the name view to projection as view is a bit more ambiguous in this lab. Your new shader can be as simple as follows

#version 410

uniform vec4 vColor;
uniform mat4 model;
uniform mat4 camera;
uniform mat4 projection;

in vec4 vPosition;
in vec2 vTexture;

out vec4 color;
out vec2 texCoord;

void main()
    gl_Position = projection*camera*model*vPosition;
    color = vColor;
    texCoord = vTexture;


To test the transition to the new shader variables, I recommend the following process.

  1. Change m_view in your MyPanelOpenGL class to be something like m_project. This can be a simple search/replace in the .h/.cpp file.
  2. Temporarily in PaintGL create a QMatrix4x4 object storing the identity matrix. Connect this matrix to the uniform variable camera in the vertex shader, prior to setting the model matrices for your planets.
  3. Test that your scene appears as before.

Implementing the Camera

The primary goals of implementing the camera class are to understand how to construct the lookAt matrix from scratch, and how to manipulate the camera to support panning and rotating from the camera's perspective. Use the inclass notes to implement lookAt and feel free to check your solution against QMatrix4x4::lookAt.

The Learn OpenGL Tutorial has some suggestions on how to implement camera panning and rotating methods, but you can feel free to design your own implementation.

Once you have you have your Camera implemented and compiled, you can begin testing it by adding a cs40::Camera object to your MyPanelOpenGL class. Think about a good default value for your lookAt given your solar system scene and set this viewpoint in initializeGL. Then connect your camera's lookAt matrix to the shader, by replacing the camera uniform value with a call to the matrix() method of your cs40::Camera object.

This could potentially be a very large change to the scene and everything may disappear. Note that your projection matrix (which is probably still your original ortho matrix), is now projecting eye coordinates, not world coordinates. At this point, I would strongly encourage you to modify the last two parameters of ortho to be the distances to the near and far clipping planes with $0 < n < f$. These distances are measured as distances in front of the eye. Making this change with the ortho box now will help you when you transition to a perspective projection later.

Adding interactive Camera Controls

Add keyboard, mouse, or button controls to support the following:

Document your camera controls. The method showOptions prints the keyboard controls to the screen so the user does not need to read the source to figure out how to navigate. Updating this method to reflect your changes is sufficient documentation.

Using a Perspective Projection

Given the scale of the solar system, the scene looks a bit more realistic with a perspective projection that makes further away objects appear smaller. Modify your code so that the m_project matrix uses QMatrix4x4::perspective transform instead of an ortho transform. You will likely need to experiment to find good values for these parameters.

Once you have sensible defaults in initializeGL, add keyboard, or button controls to support the following:

Additional required feature
In addition to the core requirements of implementing the camera class and adding a perspective projection, you must add some additional feature to this lab that can be of your choosing, but should deal with camera motion. The following are possible extensions to the basic requirements. For full credit, you should implement one of these extensions, or get approval for an extension not on the list.
At the start of lab, you copied over a README5.md which contains some conceptual questions and a short survey about the lab. You must answer the conceptual questions and submit your responses along with your code. Feedback on the lab is also requested, but will not effect your grade on the lab in any way.

Work incrementally. Start by separating m_view into m_project and m_camera. You can use QMatrix4x4::perspective to handle m_project. You can temporarily use QMatrix4x4::lookAt to setup a basic scene and test your shader, but ultimately you want to replace this with your Camera class and its lookAt method which you implement.

Make small changes to your camera and projection matrices. They affect everything, so it is very easy to get completely lost. That's when reset comes in handy. You may want to implement that early.

You can use any of the 'basic' QMatrix4x4 methods. Methods like translate, rotate and scale, modify an existing matrix, by multiplying it on the right. You can use perspective. You cannot use lookAt. You must implement this yourself.

External links
You should regularly commit your changes to the lab4 repo and occasionally push changes to the github remote. Note you must push to your remote to share updates with your partner. Ideally you should commit changes at the end of every session of working on the project. You will be graded on work that appears in your github repo by the project deadline.