Welcome to Computer Graphics. This course serves as an introduction to the area of graphics. We will learn many of the basics of modeling and rendering from a modern OpenGL approach. This course will feature lots of programming, and lots of math, but the math is not super complex. We will design many interesting projects, and you will have a chance to explore your own final project, but if you are expecting to design a full fledged 3D game, or the next CGI movie, this course will not meet your expectations. This course is designed around understanding core concepts and preparing you to explore more advanced topics in computer graphics.
An Overview of Computer Graphics
- Modeling: representing 3D objects with geometric primitives: points, lines, triangles
- Scene Creation: arranging objects in the 'world' using transformations
- Projections: setting up a viewpoint from which to visualize the world
and converting a 3D scene to 2D
- Rendering: Transforming the 3D model into a 2D image on the computer screen (pixels/fragments)
Software Tools
- OpenGL : graphics framework
- C++ : our language of choice
- CMake : for building/compiling complex software projects
- Git : for managing source code, sharing
- Qt : for designing interactive graphical applications
- CUDA : GPGPU programming
Math Concepts
- Linear Algebra
- Matrices (4x4)
- Vectors (4x1)
- Dot product
- Cross product
- Matrix/Vector product
- Affine Transformation
- Frames, Orthogonal Bases
- Trigonometry
Hardware
- GPU
- optimized for vector math
- highly parallel
- SIMD
- programmable (shaders/CUDA)
- Displays
- 3D Displays
- 3D Printing
Getting Started
We'll be using
git to submit code electronically. Follow the
instructions for setting up your Swarthmore Github Enterprise account.
Course examples
mkdir cs40
cd cs40
git clone git@github.swarthmore.edu:CS40-F16/examples-YOURUSERNAME.git examples
cd examples
git remote add upstream git@github.swarthmore.edu:CS40-F16/examples.git
git fetch upstream
Wednesday
The examples repo should have two remotes. The first, origin, refers to your personal copy on the github server. The second, upstream, refers to a read-only copy that I will update throughout the semester. Let's check the status of our remotes and get some updates
$ git remote show
origin
upstream
$ git remote show origin
X11 forwarding request failed on channel 0
* remote origin
Fetch URL: git@github.swarthmore.edu:CS40-F16/examples-adanner1.git
Push URL: git@github.swarthmore.edu:CS40-F16/examples-adanner1.git
HEAD branch: master
Remote branches:
master tracked
Local branches configured for 'git pull':
master merges with remote master
Local refs configured for 'git push':
master pushes to master (up to date)
$ git remote show upstream
X11 forwarding request failed on channel 0
* remote origin
Fetch URL: git@github.swarthmore.edu:CS40-F16/examples.git
Push URL: git@github.swarthmore.edu:CS40-F16/examples.git
HEAD branch: master
Remote branches:
master tracked
$ git branch -avv
master ddee7fe [origin/master] Last commit message
remotes/origin/HEAD -> origin/master
remotes/origin/master ddee7fe Last commit message
remotes/upstream/master 19169f2 upstream commit message
Try to get the latest changes from upstream
git fetch upstream
git merge upstream/master
git push
If you have local uncommitted changes, you may need to discard them or add them before merging.
#throw away local changes
git checkout -- ./
#add/commit local changes
git add [filenames]
git commit -m "description"
If you have a merge conflict, see the notes on
resolving merge conflicts. In this case, we can just accept the upstream changes
git checkout --theirs CMakeLists.txt
git checkout --theirs w01-intro/qtogl/CMakeLists.txt
git add CMakeLists.txt
git add w01-intro/qtogl/CMakeLists.txt
git commit -m "merged with upstream"
git push
You can use the
Git overview page to review basic git usage. If you have questions, chances are other students do too. Please post in
Piazza to start a discussion. You can post anonymously to the rest of the class (but not to the instructor).
CMake
Once you have a copy of the code, Build the examples with
CMake
[examples]$ mkdir build
[examples]$ cd build/
[build]$ cmake ../
[build]$ make -j8
[build]$ cd w01-intro
[w01-intro]$ cd simpletests
[simpletests]$ ./helloCS40
Try running the other examples in the w01-intro folder
simpletests/glmTest
opengl/chapter01 basic
qtogl/qtogl
qtImage/qtimgtest
With
CMake you
compile,
run, and
test programs in the
build directory. You
edit source files outside of the
build directory. You may want to have one terminal window open for running programs, and a separate terminal for editing.
Using Qt
OpenGL is the primary language for creating images from 3D models, but OpenGL is primarly focused on just that: image creation. Often we want more interactive applications, perhaps with buttons, menus, and key bindings. To get those features, and additionally an OpenGL context, we will be using the Qt (cute) framework to develop Graphical User Interfaces (GUIs). Keep in mind the focus of this course is on the graphics aspects, but having a basic working GUI is nice too. We won't be UX experts by the end of this course, but Qt is modern and actually used by some companies.
Let's walk through the creation of simple Qt application and demonstrate qtcreator. For more details, see the qt demo page.
Friday
QT and OpenGL
The class
QOpenGLWidget creates an OpenGL context inside QT.
OpenGL functions are called within this context. Additionally, QT has some
OpenGL wrapper classes beginning with the prefix
QOpenGL.
Creating a QT OpenGL application
- Create a new class, e.g., MyPanelOpenGL which inherits from QOpenGLWidget
- Add a widget in the UI Designer and a promote it to MyPanelOpenGL
- Implement the methods initializeGL(), paintGL() and resizeGL ( int width, int height ) in your MyPanelOpenGL class.
- Add additional methods, slots, signals, widgets as needed.
- ~/cs40/examples/w01-intro/qtogl
- MyPanelOpenGL inherits from QOpenGLWidget; provides OpenGL context in QT
- clip coordinates 2x2x2 box
- geomety -> vertex shader -> clip -> rasterize -> fragment shader -> framebuffer
- framebuffer squished into viewport
- Copying CPU data to GPU memory using Vertex Buffer Objects (VBOs)
We store the vertices of a triangle in a VBO in GPU memory. The next step is to define, create, load, and compile
shaders. The
vertex shader runs first and takes vertex data from the VBO and outputs geometry in clip coordinates. This geometry is then clipped, rasterized, and fed to the
fragment shader which runs on each fragmenet, or potential output pixel. The output of the fragment shader is written to a framebuffer and displayed in the viewport.
Once each shader is compiled, we define, create, and link a
shader program, which is the combination of a vertex shader and a fragment shader.
Finally, we are ready to draw. The main steps are:
- clear the display
- bind buffers, programs
- connect shader parameters to data
- glDraw...
- glFlush
- repeat as needed using updateGL()
Once the geometric data are copied to GPU memory, almost everything else happens on the GPU.
paintGL is just issuing commands to the GPU. The GPU itself will process those commands.
Shaders, GLSL
- keywords: in, out, uniform
- types: vec3, mat4
- variables: gl_Position;
Modifying Shaders
- Making gl_FragColor a uniform value
- modifying geometry
- uniform time variable
- QTimer
- updateGL -> Animation!