3D Modeling

Wednesday | Friday
Exploring 3D OpenGL
With an understanding of geometry, vectors, bases, and frames, we can extend the shaders and MyPanelOpenGL class to support 3D rendering as well. Over the next few weeks we will explore basic modelling, more complex VBOs, texture mapping, lighting, and perspective transforms. This will round out core OpenGL.

A recap of the process for creating an OpenGL application in QT.

  1. Create a new class, e.g., MyPanelOpenGL which inherits from QOpenGLWidget
  2. Create Data on the GPU using Vertex Buffer Object (VBOs)
  3. Compile/Link Shader programs that will run on the GPU using data from the VBO
  4. Implement the methods initializeGL(), paintGL() and resizeGL ( int width, int height ) in your MyPanelOpenGL class to draw the scene.

Setup

I have updated code on the examples repo on github. Start by checking the status of your personal examples repo using git status and committing any local changes. Refer to git status help page for instructions, particularly on files that have been modified.

Next, fetch upstream changes. If you have committed local changes, merge conflicts should be minimal

[~]$ cd ~/cs40/examples
[examples]$ git fetch upstream
[examples]$ git merge upstream/master
[examples]$ git push

Open up a terminal and navigate to sphere directory in w04-3D. You will be creating a symlink to a folder containing texture map images for this code. You need to do this step before running make in your build directory.

[~]$ cd ~/cs40/examples/w04-3D/sphere
[sphere]$ ln -s /usr/local/doc/textures data

In a second terminal, navigate to the build folder and run make -j8 to get the w04-3D folder.

[~]$ cd ~/cs40/examples/build/
[build]$ make -j8
[build]$ cd w04-3D/cube
[cube]$ ./cube
Initial Explorations
A couple of things to point out in the cube example. You can rotate the cube using the x,y,z keys. Handling key press events is done with the keyPressEvent(QKeyEvent* event); method.

vColor as attribute
GL_DEPTH_TEST, GL_DEPTH_BUFFER_BIT
shaders and rotation matrices

VBO Changes

In the cube example, we pack the vertex geometry and the vertex colors into a single VBO. See the changes to allocate, and the new write calls to the VBO in createVBO. Note there are some changes in setupVAO to describe the new layout of the VBO. The call

 m_shaderProgram->setAttributeBuffer("vColor", GL_FLOAT,
      m_numVertices*sizeof(point4),4,0);

specifies that color information from the VBO should be passed to the vColor input variable in the vertex shader and that the color information appears after the vertex information in the VBO, starting at offset m_numVertices*sizeof(point4).

Rotation in Shaders

The rotation of the cube happens in the vertex shader. angles is vec3 object containing the rotation angle (in degrees) about the $\hat{x}, \hat{y}$, and $\hat{z}$ directions. The glsl functions radians, sin and cos can do component-wise operations on vec[234] types.

Note the order of the rotation matrices. When running the demo, is the rotation axis for $\hat{x}$ always fixed with respect to the screen? What about the rotation axis for $\hat{z}$? What is going on?

Depth Buffer

In addition to the color buffer, which you see as the primary output of the fragment shader, OpenGL supports other buffers as well. One important one for 3D applications is the depth buffer.

Enable the depth buffer with

 glEnable(GL_DEPTH_TEST);
and clear the depth buffer and color buffer with
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
OpenGL computes the depth of a potential fragment and compares it to the value currently in the depth buffer. If the new fragment is in front, we keep the fragment and write this new depth to the depth buffer. Otherwise, the fragment is occluded and discarded.

You can visualize the content of the depth buffer by modifying the fragment shader

void main() 
{ 
  //fragColor = color;
  float d = 1-gl_FragCoord.z;
  fragColor = vec4(d,d,d,1);
} 

Sphere

When you first run the sphere program, you should get a wireframe outline of a square. You can rotate using the x,y, and z keys.

Examine the method updatePolyMode and see where it is called. Find out how to change the mode and toggle the various features.

Find out how to toggle the sphere

Examine GL_CULL_FACE

Texture Mapping

go to the fragment shader and uncomment the first fragColor line, while commenting out the third line. recompile and run. Woot!

Matrix Stacks