To get going, you need to clone the repository we have set up for you on Gitlab that has been pre-populated with starter code. We will be using Git for source control. For more detailed information, refer to the git tutorial. In order to get the source code, follow the directions below:
Note: If git ever asks you for a username and password when you access the repo, that's because your ssh key is not loaded into the system. From git bash (windows) or the terminal (linux), type pwd. Then navigate to that directory and there should be a .ssh file. Copy your OpenSSH public key into that folder with the name id_rsa (windows) or id_rsa.pub (linux). To generate an ssh key on Windows, use puttygen (hit generate with default settings) and export as OpenSSH under Conversions. The git server also needs to know about your public key in order to allow you access. Go to gitlab, profile settings, SSH Keys and add yours in. See the link below for information on ssh keys for linux.
$ git clone git@gitlab.cs.washington.edu:cse457-15au-impressionist/YOUR_REPO.git impressionist
$ git add --all
$ git commit -m "added a triangle brush"
$ git push origin master
$ git pull
to update your copy of the repository with their changes before you start working to avoid merge conflicts.Note: If you are having errors in the #include lines of any of your header files, copy over the fltk1.3.3 folder from C:\Program Files (x86)\ into C:\Program Files. This is an issue where the build is looking in the wrong folder.
You need to submit your binary and source code by the due date to the Catalyst Dropbox. Please submit a readme that describes any bells, whistles, and anything out of the ordinary you did for the project. This will help us out when we are grading your project. If you did your development under Linux, please note that as well.
Your turnin should be a zip file containing two folders that looks like this:
binary/ |
[program].exe - Executable file compiled in release mode Files needed by the executable - this includes textures, images, shaders, and other files README.txt - only if you did anything out of ordinary |
source/ | Everything needed to compile and run your project Please do not include the "debug/" and "release/" folders |
The grading will consist of a staff member running your project right out of the binary directory and stepping through the features. We will verify the timestamp of the executable and consult source code as needed.
Note: Be sure to compile your executable in Release Mode
Important: Please download your uploaded .zip file and test running the program from the binary directory after turning it in.
When you are done with a project, you will create a project "artifact" to show off the features of your program.
This is required. You will lose points if you do not submit at least something. We will not grade on artistic merit. However, after everyone submits their artifacts, we will create a gallery on the course website where you will vote on your favorite artifacts! The winner and runners-up will receive a small amount of extra credit. So be sure to try your best!
The main instructional lab for our course is CSE 022, in the basement of the Allen Center. As a registered student in the class, you should have access to this lab. Contact cardkey@cs if you are not able to enter the lab with your cardkey.
The computers are Windows 10 workstations. Applications are built using Visual C++, the FLTK UI toolkit, and OpenGL.
The machines in CSE 022 are primarily for the use of cse457, cse455, and cse557 students working on assignments for those courses. If you are not a graphics student, or not working on the course, you may use the machines in CSE 022, but must give up your machine if someone needs it for the course.
If for some reason, you get hung, mail support@cs. They will take care of this for you.
The lab has copies of course reference material, including textbooks OpenGL reference texts. These may not leave the lab, and please return them to the bookshelf when you are done using them.
In addition to the above rules, the Lab Community Committee has created a set of guidelines about general lab use. The main points are:
Be aware of yourself and your space. Remember that your behaviour affects others.
The labs are an academic community of which you and your fellow students are citizens.
We are each responsible for our community's working environment.
Follow the Golden Rule: Treat others as you would like to be treated.
Please read the complete Lab Usage Guidelines.
Important: We highly recommend working on a Windows machine since the project is released with a Visual Studio solution file, and we will be grading on Windows machines in the CSE022 Labs. If you do not have access to Windows OS, you can get a copy through Microsoft Imagine (DreamSpark) as a UW CSE student.
Make sure you have FLTK 1.3.3 installed on your computer. If you're running Windows and using Microsoft Visual Studio 2015, then you can download and run the FLTK Installer. Otherwise, you'll need to download and compile the FLTK source code.
Download git on your machine.
Follow the Getting Started steps above.
You may need to point Visual Studio to the correct include and library directories for the FLTK that came in your repository (since normally it points to the local one on each lab machine).
Open the .vcxproj file to load the project into Visual Studio.
Note: If you are having errors in the #include lines of any of your header files, copy over the fltk1.3.3 folder from C:\Program Files (x86)\ into C:\Program Files. This is an issue where the build is looking in the wrong folder.
Visual Studio is the Microsoft IDE for windows based development. We will use Visual Studio 2015 in the labs. You can find the community edition for free here.
Do you have the windows SDK too? If the Visual Studio install did not install the SDK, then you might run into errors of the sort gl.h ot glut.h not found. Installing the Windows SDK will help.
FLTK is a C++ graphical user interface tookit for X(Unix), OpenGL and Microsoft Windows(Nt 4.0, 95, 98).
We won't cover much about FLTK in here, since we will be using FLUID to generate the FLTK source code. But it is good to learn the basic of FLTK so that you can be more familiar with Fluid later on. For this, refer to the to see the complete FLTK Programming Manual.
These directions are intended for advanced users. The course staff supports the graphics lab development environment, but if you would like to work elsewhere these directions may help. Your mileage may vary.
1. Install FLTK files
Note: You should not have to complete Steps 2 or 3 to get the project to work. They are here to try only if Step 1 fails.
2. Configure Visual Studio (MSVC)
3. Verify that your project is linking with the correct library
FLTK is already installed on instructional Linux systems (attu and the workstations in the Allen Center labs) in /usr, and on your own Linux system, before attempting to follow these instructions you should look for prepackaged binaries for your own distribution.
1. Install Mesa
As the first step, you must install MesaGL. To install it:
> gunzip MesaLib-3_0_tar.gz
> tar -xvf MesaLib-3_0_tar
> cd Mesa-3.0
> make linux-386
.....
Several minutes later, you will have libMesaGL.a and LibMesaGLU.a in Mesa-3.0/lib and a directory called GL in Mesa-3.0/include. I usually prefer to copy all these files into ~/local/lib and ~/local/include such that I can access all the libraries without remembering tons of paths.
2. Install Fltk
Now, we try to make fltk. You can get the source from here.
> gunzip fltk-1.3.3-source.tar.gz
> tar -xvf fltk-1.3.3-source.tar
> ./configure
> make
Create a local directory in you home dir
Open makeinclude file and change the prefix variable to the your local
directory
> make install
> cp fltk-1.3.3/fluid/fluid ~/local/bin
> cp fltk-1.3.3/
You will have 'fluid' in ~/local/bin,
two directories, FL and Fl, in include
and libfltk.a in lib.
Now everyting is in ~/local, you need to change the value of the variable, $(LOCAL), in Makefile to ~/local.
Git is a modern version control system for managing the sharing and versioning of your source code. Git is a "distributed" version control system, as opposed to classical systems such as CVS and Subversion which are based on a single central repository. While distributed version control is very powerful, this tutorial will teach you to use git in a "client-server" fashion that mimics the classical version control systems that you may already be used to.
Git has many, many more advanced features than are presented in this tutorial. If you'd like to learn about them, git has a comprehensive set of man pages (man 1 git or git --help
Log on to Gitlab, add an ssh key, and then find your group's repository under the Projects tab.
Click your repository's name, and at the top of the page there should be a string you can copy of the form git@gitlab.cs.washington.edu:cse457-15sp/YOUR_REPO.git, where YOUR_REPO is your group identifier.
Copy that string, and in a shell (such as Git Bash or Git Shell), run:
$ git clone copied_string
This will create a directory named YOUR_REPO in the current directory
We recommend renaming the local copy of the repository to something more descriptive, by running:
$ git clone copied_string descriptive_name
This will create a directory named descriptive_name in the current directory
If you are prompted to enter your password that means you haven't set up your ssh keys in gitlab properly. Do that now to avoid repeated password prompts as you push and pull things from gitlab.
The commit and update process in git differs slightly from that of other version control systems that you may have used. To illustrate how it works, we'll make a minor change to one file and create a new file.
Copy the contents of pointBrush.h and paste into a new file called lineBrush.h. Replace all occurrences of 'point' with 'line'. In impressionistDoc.cpp, add lineBrush.h to the brush includes. (search for pointBrush.h if you're having trouble finding this)
Now run the git status command and observe its output:
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: impressionistDoc.cpp
Untracked files:
(use "git add <file>..." to include in what will be committed)
lineBrush.h
no changes added to commit (use "git add" and/or "git commit -a")
This output shows two things: first, you must explicitly add new ("untracked") files to the repository before they can be committed (as is true in other version control systems), and second, you must explicitly stage your changes before they will be committed (unlike subversion, which will automatically commit all of your changes if you just run svn commit). To further illustrate this, run the git commit command:
$ git commit -m "Adding the line brush header file."
This command will be a no-op: you should see the same output as from the git status command, ending in the same message: 'no changes added to commit (use "git add" and/or "git commit -a")'. To add your changes to the commit set, you must use the git add command on the changed files (whether they are new files or files already in the repository!):
$ git add impressionistDoc.cpp
$ git add lineBrush.h
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD ..." to unstage)
modified: impressionistDoc.cpp
new file: lineBrush.h
You can see that the change to the impressionistDoc.cpp file and the addition of lineBrush.h have now been staged for the commit. To commit all of the changes that you have staged, run git commit:
$ git commit -m "Adding the line brush header file."
[master 41a5c0d] Adding the line brush header file.
2 files changed, 2 insertions(+), 0 deletions(-)
create mode 100644 lineBrush.h
Details
The -m argument to git commit is used to provide a commit message; if you forget to use it, then git will open a text editor for you to enter a commit message.
To make git behave more like subversion and automatically commit all of the changes you have made to files already in the repository (automatically commit all unstaged changes), use the -a flag with git commit. You may find, however, that the process of staging / unstaging changes is one of the most useful features of git: it allows you to make lots of changes to lots of files, but only commit the changes you want while leaving other files with in-progress changes uncommitted.
If you get a message like "file.c: needs merge" when you try to commit, then you have a conflict from a previous git pull that has not been resolved. See the Updating your local repository section below for more information about resolving conflicts.
However, at this point you have committed some changes, but your commit is not yet visible to the other users of the repository. git separates the notion of committing changes from the notion of "pushing" your update to the central repository. This can be useful for an individual developer that wants to make many changes to the code in many small logical commits before pushing all of them to the central repository, but for your CSE 457 projects you will probably just want to push after every commit.
To push your commits to the central repository, simply run git push:
$ git push
Counting objects: 4, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (4/4), 312 bytes | 0 bytes/s, done.
Total 4 (delta 0), reused 0 (delta 0)
To git@gitlab.cs.washington.edu:cse457-15sp-impressionist/YOUR_REPO.git
eb27358..c3615e1 master -> master
If your push fails, it may be because you need to run a git pull to update your repository first (and potentially resolve conflicts) before pushing your new commit. See Updating your local repository below.
If you get a warning that push.default is not set, you can make that message go away by setting it to simple using the git config command given in the warning message.
If you ever run the git status command and see the output "Your branch is ahead of 'origin/master' by N commits", then this means that you have local commits that have not been pushed to the repository yet.
Remember to push your commits! If you are not used to using git, then this may be the hardest thing to get used to. Try not to forget to do this, or your group members will wonder why it seems like you're not doing any work.
To update your local copy of the repository with commits that other members of your group have made, simply use the git pull command. It will either show:
$ git pull
Already up-to-date.
or something like:
$ git pull
...
impressionistDoc.cpp | 1 +
lineBrush.h | 1 +
2 files changed, 2 insertions(+), 0 deletions(-)
create mode 100644 lineBrush.h
git will not allow you to pull updates into your repository while you have unstaged changes. Therefore, you must stage (git add) and commit all of your changes before pulling. If you have changes that you don't want to make visible to your group yet (because they cause the build to break, for instance) but you still want to update your local repository, you can just commit your changes, do not push them yet, and pull the updates. Then, when your changes are ready, you can commit again and then push to the central repository.
As with any version control system, pulling updates from the central repository may cause conflicts with changes that you have committed locally. Pay attention to the output from your pull command for instructions to resolve conflicts; generally, resolving a conflict entails opening up the conflicted file(s) in your editor, finding the conflicts (surrounded by the text markers <<<<<<<, =======, and >>>>>>>), fixing the conflicting code, staging the changes (git add) and committing and pushing again. For more information about resolving conflicts, the github user manual has a useful webpage.
Since it may be hard to visualize what is going on with Git repositories in just the terminal, there are some very high quality GUI clients available built on-top of the command-line Git. SourceTree lets you perform all the common commands with buttons and provides important visualizations of the branches and commit history. Going back to a previous commit is as simple as clicking on it and hitting checkout. GitHub Client is another one.
C++ Language Tutorial - useful for quick reference
Thinking in C++ and Thinking in Cby Bruce Eckel
OpenGL is a 2D/3D graphics library. It is based on IRIS GL, developed at Silicon Graphics for their high-end workstations. You can find more information about the OpenGL standard at www.opengl.org. This document is not a tutorial, but introduces some of the basic concepts of OpenGL that will be used in our projects, and provides pointers into the documentation.
The best book for learning OpenGL is the OpenGL Programming Guide, "The Red Book."
The Official OpenGL Documentation is great refrence material.
For tutorials on OpenGL, check out this link.
All the functions in the OpenGL library have names beginning with "gl". Defined constants have names beginning with "GL_".
It common for there to be a family of functions for performing the same operation, differing only in the number and/or types of arguments accepted by each. The names of these functions have tags at the end to indicate the type of argument. The whole family will be referred to with a star syntax. For instance, glColor*() refers to any of the 32 functions available within OpenGL for setting the current color, including:
glColor3f( GLfloat, GLfloat, GLfloat ) |
glColor4d( GLdouble, GLdouble, GLdouble, GLdouble ) |
glColor3ubv( GLubyte* ) |
There is also a library of utility functions whose names all begin with "glu". These are simply convenience functions for doing some common tasks that take a few OpenGL commands to perform.
OpenGL keeps a large amount of state. It has many modes which can be switched on and off with the glEnable and glDisable commands. You should think of each function call as manipulating this state, rather than performing a specific drawing operation. To enable high performance, implementations of OpenGL are allowed to buffer commands almost arbitrarily. When you have sent some commands to OpenGL and want to be sure that the results actually appear on screen, call glFlush to force OpenGL to complete.
The OpenGL state is kept in a data structure called a rendering context. We will typically create one rendering context for each OpenGL window. This keeps state changes for drawing in one window from interfering with drawing in the other windows. Switching to another context is done by calling wglCurrentContex.
Drawing in OpenGL consists of calling glBegin to tell OpenGL what you want to draw, then a series of calls to glVertex* to specify the geometry, then a call the glEnd to finish up. The single argument to glBegin tells it how to interpret the series of vertices you are going to throw at it. Here are some of the valid things to send to glBegin:
GL_POINTS | draws each vertex as a point |
GL_LINES | draws a segment connecting the vertices 1 and 2, a segment connecting vertices 3 and 4, 5 and 6, and so on |
GL_TRIANGLES | draws the first three vertices as a triangle, the second group of three as another triangle, and so on |
GL_POLYGON | takes the vertices as a single, simple, convex polygon |
There are several other options, see the manual for more explanation. Note that whenever you tell OpenGL to draw a polygon, it must be flat and convex. Triangles are easy, because they are always flat and convex, but with higher-order polygons you must be careful or your results will look wrong. Each polygon has a front side and a back side, which can be rendered differently if you choose. The front side is defined (by default) as the side from which the vertices appear in counterclockwise order.
The vertices you specify are coordinates in 3D space. They are transformed by the current modelview matrix, then by the current projection matrix to determine where they map to on the screen.
Note: Many OpenGL operations are not allowed between a glBegin and a glEnd, including all those listed under Matrix Stacks below. Used inappropriately an OpenGL function will likely fail silently. For basic 2D programs such as Impressionist glVertex* and glColor* will probably be the only two gl* functions used between a glBegin and a glEnd. You can use as much non-OpenGL code as you like, though.
For a more detailed and helpful explanation, visit here.
Contained in the OpenGL state are two matrices which affect how geometry appears on the screen. The projection matrix determines the position and orientation of the camera. The modelview matrix is used to transform geometry before rendering it. In our projects, the projection matrix will typically be set up by the skeleton code. You will change the modelview matrix to affect how primitives are drawn on the screen.
The state maintains a stack for each matrix, with the top matrix being the one that is in force. You can thus make temporary changes by pushing a copy, altering the matrix, using it, then throwing it away with a pop. Since a full stack is maintained, you can nest these temporary changes to (almost) arbitrary depth. The useful commands for manipulating these stacks are:
glMatrixMode | Selects which matrix stack is being manipulated, GL_PROJECTION or GL_MODELVIEW. (Actually, there is a third one for controlling texture mapping, but you can read about that in the manual.) The remaining commands all affect the currently selected matrix stack. |
glLoadIdentity | Replaces the top element of the stack with an identity matrix. |
glPushMatrix | Duplicates the top element of the matrix stack. |
glPopMatrix | Pops and discards the top element of the stack. |
glTranslate* glRotate* glScale* |
Composes the top element of the stack with a transformation. |
Frequently you will want to copy around blocks of pixels, rather than drawing individual primitives like lines and polygons. You could do this by drawing individual GL_POINT objects, but that would be horrendously slow and inefficient. Instead, there is a set of OpenGL functions for copying blocks of pixels to and from the framebuffer.
glReadPixels, glDrawPixels | read/write a block of pixels from/to the frame buffer |
glReadBuffer, glDrawBuffer | select which buffer is read/written |
glPixelStore* | specify how pixels read/written are arranged |
glRasterPos* | set the starting point for pixel write operations |
Keep in mind that we will frequently be using a double-buffered framebuffer to provide smooth animation. With double-buffering, objects are typically drawn into the "back" buffer, which is then swapped with the front buffer (with the SwapBuffers function) to provide the illusion of instantaneous redrawing. It is important to understand which buffer you are reading or writing when doing block pixel operations.
*a step by step guide to creating your final media file*
Export your animation (will create a sequence of consecutively numbered frames)
From here on out we'll be using Adobe Premiere (Pro 4.0). The help site may be useful.
Create a new project in Premiere. Select the "Custom Settings" tab (as opposed to the "Load Preset" tab). Select "General" from the list on the left and give your project a name. There are a few things you want to be sure of:
Import your sequence
Import any audio.
Make any adjustments necessary.