Starting from:

$34.99

CS4600 Assignment 3: Basics of 3D Graphics Solution


CS 4600 Computer Graphics


The goal of this assignment is to code up an interesting 3D graphical application using OpenGL. You will display with the famous Utah teapot model served as a standard reference object in 3D computer graphics. Your program will incorporates shading, animation and dolly zoom. This is an individual assignment, i.e., you have to work independently. All information needed to complete this homework is covered in the lectures and discussed at our Canvas Discussion Boards. You shouldn’t have to use any textbooks or online resources (except for Visual Studio and OpenGL documentation), but if you choose to do so, you must reference these resources in your final submission. It is strictly prohibited to reuse code or fragments of code from textbooks, online resources or other students -- in this course this is considered as academic misconduct ( https://www.cs.utah.edu/academic-misconduct / ). It is fine to use material from lectures, lecture slides and online documentation of OpenGL functions (and C++ / Visual Studio if necessary), but please add references (e.g. URL for online help) in your PDF writeup (see Submission Instructions below).

The framework code is written in C++ with the following dependencies:
● OpenGL 1.0
● C++ STL
● OpenGL Extension Wrangler Library (GLE W)
● GLFW3

The recommended IDE is Visual Studio 2017 Community Edition, which is available free of charge for educational purposes. The framework code provides precompiled dependencies for Visual Studio 2017. If you choose to use a different platform or IDE version it is your responsibility to build the dependencies and get the project to work. The provided source code, after being successfully compiled, linked, and executed, should display a static teapot with constant gray color (no shading).

The assignment consists of three parts: normal computation, view matrix computation and projection computation. All three parts should be implemented in the main.cpp file using specified subroutines. No other source code / dependencies / libraries are needed or allowed for this assignment.





Introduction
This assignment uses the very basic, yet easy to learn fixed function pipeline of OpenGL. In modern OpenGL, using the programmable pipeline gives more freedom to the programmer, but it also makes it more difficult to understand. OpenGL is a state machine. Once you set a state anywhere in the code, which runs in a thread of an OpenGL context, it remains in that state until set otherwise. The OpenGL states can be changed by calling procedures with prefix “gl”, such as glEnable, glMatrixMode, glColor3f, etc.

When the program starts and the main function is called, a new window with an OpenGL context is initialized using the GLFW library. The program continues by changing a few states of OpenGL, i.e. enabling lighting, setting background color and finally setting the projection matrix. Next, the Utah teapot mesh is loaded from a file TEAPOT.OBJ into a std::vector of floats, g_meshVertices, so that it contains the sequence of vertex coordinates (x1, y1, z1, x2, y2, z2 , ... ). Vertex indices for each triangle of the mesh are also stored sequentially in a std::vector of integers, g_meshIndices, as (a1, b1, c1, a2, b2, c2, ... ), where a1, b1, c1 are vertex indices of the first triangle and so on. Finally, a rendering loop is called. This loop sets the OpenGL ModelView matrix, renders the teapot using OpenGL immediate mode (i.e. by calling glBegin, glVertex3f, and glEnd ) and checks for I/O events until ESC key is pressed or the window is closed. But do not worry too much about the technical details. Instead, let’s code up some 3D graphics!
1 Compute Normals (33 points)
The goal of this part is to compute normal vectors for each vertex of the Utah teapot mesh in order to get basic lighting to work. OpenGL fixed function pipeline uses Blinn–Phong reflection model that describes the way a surface reflects light as a combination of an ambient, diffuse, and specular reflection (we will cover reflection models later in this course). In this task, the main thing is that this reflection model requires a normal of a surface point at each vertex in order to compute the color of reflected light. Lighting enhances the realism of the rendering significantly as shown in the figure below:

(a) Default normals (b) Color coded normal directions (c) Correct normals

Normals of each vertex are stored sequentially in a std::vector of floats, g_meshNormals, in order of the vertices, (nx1, ny1, nz1, nx2, ny2, nz2, ... ). If a vertex is shared by multiple triangles, the normal for such vertex is an average of all surface normals of all triangles sharing this vertex. All normal vectors should be normalized, i.e. length(normal) = 1. Your task is to complete the computeNormals function.
2 Make the teapot rotate (33 points)
Your second task is to make the teapot rotate about the vertical axis, as shown in this figure:

Rotating Utah teapot

In OpenGL, this can be done using a ModelView matrix, which describes the relative transformation between the model (teapot) and the camera. There are several ways to understand this, but perhaps the easiest way is to remember that the OpenGL camera is centered at [0,0,0], with x-axis (i.e. [1,0,0]) pointing to the right, y-axis ([0,1,0]) pointing up and z-axis ([0,0,1]) pointing *behind* the camera. The latter is slightly counter-intuitive, but it is like that: the camera is looking in the direction of the *negative* z-axis, i.e. [0,0,-1].

3 Dolly Zoom Effect and Orthogonal Projection (34 points)
In this part, first, you will implement an interesting effect of perspective projection called “dolly zoom”, and then experiment with orthographic projection. This task helps you better understand the concepts behind perspective and orthographic projections. In order to change the projected size of our object under perspective projection, we can either change the field of view (FOV) or move (“dolly”) the camera toward or away from the subject. The “dolly zoom” effect is achieved by adjusting the FOV while moving the camera at the same time in order to keep the size of the object approximately the same after perspective projection, as shown in the figure below:

Sample frames showing the dolly zoom effect

Considering the figure below, we can explain the math behind the dolly zoom effect. In order to achieve the effect, first we need to place the subject (blue rectangle) in a desired distance (red arrow) from the camera (the center of the camera is in the origin):


Two different states in dolly zoom

Note that moving the subject in some direction is equivalent to moving the camera in the opposite direction, so we can consider the camera is fixed at the origin. For a given FOV angle, we can compute the corresponding width of the visible part of the scene (halfWidth shown in the figure) as below:

halfWidth = distance * tan(FOV /2) (1)

Note that the “tan” function assumes that angles are in radians (not degrees). The idea is to keep the width of the visible part of the object the same while zooming. As you can see in the figure, the width in the image plane (purple vertical line) remains the same after zooming. Notice the red point on the subject is projected to the same place (green point) in the image plane in both cases.

Once we have computed the desired width (halfWidth) using the initial distance and FOV, we can change the FOV over time and update the distance like this:

distance′ = halfWidth / tan(FOV ′/2) (2)

In the equation above, distance’ is the new distance of the subject from the camera in the z direction, FOV’ is the new FOV (changed over time), and halfWidth is computed according to Equation 1.


You last job is to code up orthographic projection using OpenGL inside the function togglePerspective() where orthographic mode is activated. You can switch between perspective (key ‘P’) and orthographic (key ‘O’) projections to see the difference. In OpenGL, orthographic projection is set via function glOrtho; the key part of this task is to come up with suitable parameters (left, right, top, bottom, zNear and zFar) to pass to glOrtho. Hint: these parameters are in camera space units, zNear and zFar can be the same as in perspective projection. You need to come up with suitable numbers for the left, right, top, bottom parameters. Another hint: if your teapot image is scaled weird, think how is the image plane in camera coordinates mapped to pixels in your window. Yet another hint: left refers to the X camera axis and it should be a negative number around -1.0f, right should be a positive number around 1.0f, similarly for top and bottom which refers to the Y camera axis (obviously, zNear and zFar refers to the Z axis).
When you’re finished with Task 3, you might notice the rotation axis is not perfectly aligned with the teapot. This is because the teapot rotates about its center of mass, which also accounts for the handle and the spout. The animation would be more visually pleasing if we make the teapot rotate about the center of its body *only*. You can also make the teapot stand still when the program runs, and gradually spin it in a smooth transition, as if the teapot was rotated by physically-realistic torque (force/torque always needs time to translate into velocity, it never happens on a dime; no matter how strong your car brakes are, you have to apply them *before* the car is in contact with a wall). In order to have more control over the animation, you can write code to pause/resume the spinning of the teapot (it should start again at the same angle where it paused) or pause/resume the dolly zoom effect (it should start again at the same stage of zooming where it paused). The key callback is provided in the framework for you (you can use the key ‘S’ to toggle the spinning and the key ‘D’ to toggle the dolly zoom).

If you are curious what else we can do with normals, you can also experiment with basic OpenGL shading models (i.e. how colors of the vertices are interpolated during rasterization). The default shading model is GL_SMOOTH which is an implementation of Gouraud shading. There’s also a GL_FLAT shading model which you can set using the glShadeModel function. You can also try to change the teapot’s color. A particularly creative real-time rendering or animation of the Utah teapot will be especially appreciated!
5 Submission
When you’re finished with Tasks 1,2 and 3 (and possibly the optional Task 4), you’ll need to submit the following:

- Source code (you should only modify main.cpp so that’s all we need)
- The PDF document should also include a link (URL) to a video which you need to upload on your YouTube channel. The video will be a screen capture of your final rotating teapot. There are many free screen capture utilities that can help you with this.

Please pack the source code (main.cpp) and the PDF document to a single ZIP file named Lastname_Firstname_HW3.zip.


Late policy

More products