Thursday, November 29, 2012

Project 3


Objective: Use the OpenGL library along with the GLSL language to create a implementation of Tangent space normal mapping and Spotlight Projective Texture Mapping.

Initial Thoughts:  Implement the spotlight first, then work back to get the tangent space mapping working correctly.

Files: 

image.h && image.c && 
obj.h && obj.c &&
plane.h && plane.c && 
math3d.h && math3d.c
view.c && view.h
viewglut.c && viewglut.h
gl.h                        : All of the files mentioned before here are credit to Robert Kooima, each one can be considered a crucial part of the project. For more information please see http://csc.lsu.edu/~kooima/util3d/index.html


main.cpp : Main file where all the implementation of the glut functions as well as main logic is located. The program is started without the need to command line arguments.

shaderloader.h && shaderloader.cpp : This file was used in the last program but has been modified significantly in order to fully handle the shader files from compile to linking. This also has the ability to load textures from simply passing the file name. It then will generate the textures and bind them.

thirteenBoxFragmentShader2.glsl && thirteenBoxVertexShader.glsl: These are the shader files that have been implemented for the tangent space normal mapping.

Process: Now that we have explained all the files, let us explore more into depth of what is happening in the guts of the program.

As always, we start out in main with our initialization of all glut methods as well as initializing all others.

As with the last program, this program has a menu bound to the right click. (Note that the projective texture mapping spotlight is not working. After much work, I called my losses and moved on to the tangent space normal mapping of the thirteen box) 

The thirteen box mapping is done as was explained to us in the description of the project. I load the textures and calculate all the bump mapping in the shaders using the "tangent" vertex attribute that is bound to the glBindAttribLocationARB(program, 6, "tangent");  which is done all before linking of the program.

The main purpose of the vertex shader in this situation is calculating the eye vector and the light vector with the tangent being taken into account.

It then comes down to the fragment shader to receive the sampler2D textures that have been bound inside the C++ code. We bind the locations then access them in the fragment shader through the uniform sampler2D api. The fragment shader then has the job of calculating the bump and all the fragment colors.

Once this is all done we must make sure to clean up after so that the texture is not projected onto any other models or anything else in the scene.

This is simply done in the format :

get uniform location;
bind program; //This is done through our shaderloader, which holds our program at all times.
use uniform api to tell shader where the textures are located;
set the active texture;
bind a texture to that active location;
render object;
unbind program; //Also done with shaderloader

The above "pseudocode" is done within our glutDrawFunc().

Unfortunately, the spotlight projection is something that I could not get accomplished. If I had to take a guess I would say that I am not taking the right approach with loading the matrices, I know that we are trying to use a sampler2Dproj and instead of using just .xy we use .xyzw.

Screenshots: 



This is one of the mess up with the models, the textures show up as black and dont load, havent quite gotten to the bottom of this.






keys:

All bindings follow the viewglut.c except for panning the light.

Pan Light: ALT+CLICK

Sunday, October 28, 2012

Project 2

Objective: Create an openGL implentation that will load GLSL shader files as well as wavefront(.obj) files and apply them appropriately.

As with the first project, C++ will be used mostly with much more C this time around.

Thoughts: It seems as if we could come up with a solution that will load the files that we want from a menu that we can create through openGL, rather than load them from the command line which would create a hassle when it comes time to switch out models or shader files. 

Like with the first project, all the code can be found on my public Github repository located at:  

https://github.com/popasquat89/ME4573.git

The files contained within the project include:

image.h && image.c && 
obj.h && obj.c &&
plane.h && plane.c && 
gl.h                              : All of the files mentioned before here are credit to Robert Kooima, each one can be considered a crucial part of the project. For more information please see http://csc.lsu.edu/~kooima/util3d/index.html

shaderloader.h && shaderloader.cpp: The shader loader was built to load in the different shader files, whether those be vertex or fragment. 

main.cpp - Main file of the program, implementing all glutMethods which are declared as prototypes at the top. Also accomplishes much more which will be explained more in detail below.

brick_fragment.glsl && brick_vertex.glsl: These two shader files are combined to create a brick look on all loaded objects.

colors_animation_fragment.glsl: This fragment will create a speaker that will hop and bounce around, very cool effect.

flatten_fragment.glsl && flatten_vertex.glsl: This will simply flatten out the model while having a color changing effect depending on where the user is viewing from.

wave_fragment.glsl && wave_vertex.glsl: This will create a wave effect on all models that are being rendered.


Process: Now that we have explained what each file is used for, let us now go more in depth and explain the process behind all of these files and how they are linked together.


Like any other program, we start out in main, where we will initialize all of our glut methods that will do the work we assign to their method.

By default, the program will start off with the jet being loaded and the plane being rendered. If one should want to change what model is being loaded, or if they would like to stop displaying all models, they would right click and use the "Swap Models" option which will give them any option they should desire.



The way that I have accomplished this is through case statements in the display function. Should a user want to choose a model a scenario is assigned to the scenario variable with 4 different flavors.

The plane is same concept but since it is manipulated on its own, a simple bool sufficed in order to tell the function to render the plane or not.

Shader Process:

When the user decides that he or she should want to apply a shader program the models, it is just as simple as the previous step. The user should right click and choose which program they would like to run.




The way that this is accomplished is through the proper use of case statements through the openGL menu that one can build. Once a user clicks on the shader program, it is sent to a case statement which will load the proper files needed for the program through the use of the createProgram() method. 

The createProgram() method is responsible for all of the following:

  • Creating an instance of ShaderLoader and loading the file in.
  • Compiling the Shader files
  • Calling checkCompilationStatus() to check for errors on the compile.
  • Linking the Shader files to the program;
  • Returning the program.
One all of this has been done, it is as simple as calling glUseProgram() and retrieving all the Uniform Variables from the Shader Program.

Once the program is being used, a couple of the Shader Programs have it to where we can adjust certain values that belong to them. We will explore this greater in detail soon enough.

Should the user want to stop displaying the Shader Programs, I have built in the option to reset everything to its default state. This can be done by Right Clicking, then selecting the "Reset" option.





As I change gears into explaining the Shader Programs more in depth, I would like to first explain a key method in this program which has been set up as a timer for a couple of the Shader's.

In the idle function, you may notice that I have used the <time.h> in order to update my timeFactor variable which plays a key part in the functions that rely on time. The code is very obvious for the timer, but what you may also notice is the part where I have used if statements in order to see which shader is being run and update that time variable specifically. This is very important, as multiple shaders use this variable, without it, they would not be moving ever.

Lets now look into each shader specifically, excluding the ones that were included in class. (Brick and Wave)

The colors_animation_fragment is a boombox that will jump around from time to time updating with the timeFactor variable and the mouse function. The basics of this fragment are not basic at all, it was downloaded off of a heroku GLSL sandbox and is quite complex. I will try to explain as best as possible. 

The first thing that has to happen is the drawing of the figure itself which is done with float vectors as well as using functions like pi which is defined at the top. Once we are drawn, it comes down to the time as well as beat function which is controlled by time. 

toon_fragment && toon_vertex: This is another downloaded that is pretty simple. The vertex file will calculate the normal that is declared as a global variable for both the fragment and vertex, then transform the position. Then the fragment file has the job of coming up with the colors and the intensity of those colors. 

flatten_fragment && flatten_vertex: These are two that will combine to flatten the objects that are currently loaded and make them look wavy. The vertex does the manipulation of the object by multiplying the Z coordinate of the gl_vertex by a special sine function. The fragment will give the flattened object a different look when the user changes the camera around.


ScreenShots: 









Keys:

"w" : Move forward
"s" : Move backwards
"a" : Move left
"d" : Move right
" " : Move up
"c": Move down

CONTROL+MOUSE: Move Spotlight
SHIFT+MOUSE: ZOOM 

/* Only for when Brick Shader is active */
"h": Change brick color - add
"u": Change brick color - subtract


/* Only for the Shader's relying on time */
"i" : Increase time added to timer
"k" : Decrease time added to timer
"j" : Increase time frequency
"l" : Decrease time frequency










Wednesday, September 26, 2012

Project 1


Objective: Create an OpenGL implementation that loads a file and renders it while also providing the ability for the user to Zoom, Pan, and view the object from all angles.

Syntax will be all in C++ with little mixes of C here and there.

Thoughts: It seems as though current OpenGL is mostly in C which doesn't have the structured classes that c++ provides, with this being said I will attempt to outsource as much as I can to the c++ classes.

All code will be uploaded to a public git repository at https://github.com/popasquat89/ME4573.git

The files contained within the project include:

LoadedObject.h && LoadedObject.cpp - This is our object that will be loaded, containing the vertice and elements within its private members. (Also contains mutators and accessors as well as render function for the object)

FileLoader.h && FileLoader.cpp - This is our file loader that will take in argv and a pointer to a LoadedObject. The file loads the file by creating dynamic vertice and elements then passing them to the LoadedObject.

Plane.cpp && Plane.h - A ported version of the plane.h and plane.c found on UTIL3D.

GLObjects.h - Contains the structs for the vertice and elements as well as a vertice for a plane backdrop.

keys.h - Simple header file containing definitions for different keys.

main.cpp - The main file for the program, containing all glut methods used for the main loop.

Process:

The layout of the program is pretty straightforward when compared to the examples showed in class, some of the code presented is based off the code presented to the class. Most of the glut functions were taken directly then modified slightly, with that being said I will lay out the structure of the program.

The program starts in the main with regular initializations with one slight difference. When the FileLoader object is initialized it automatically loads the file that was sent as a param via argv[].

The program then proceeds to call the startup method which will enable all of our GL enums that we plan on using such as lighting and depth test. It is important to note that whatever we plan on rendering in the display function needs to be created here. Since we are rendering one object as well as a plane we will create them here.

Once back from startup, main sets all of our glut functions such as keyboard, mouse, etc.

We then proceed to call the glutMainLoop() which is the heart of the program in essence, this will call all of our functions that we have registered as callbacks. It is important to note, the logic check for glewInit (if(glewInit() == GLEW_OK)) is not used because glew is a natural implementation in the Mac OS X system whereas it's a extension in Windows and Linux.

glutKeyboardFunc - This function will have a case statement that will switch on our keys that are defined in keys.h. This function will change the variables rotation_ and call the glutPostRedisplay() so that the display function will be called.

glutDisplayFunc - This will be in charge of all the rendering and transforming, anytime one of the variables that a call in this function contains changes it is standard to call glutPostRedisplay() to update the information.

glutMotionFunc - Anytime there is motion in the program this is the callback function that handles, in our case this is the function that handles when the click button is either a single or double click. Should it be a single click there will be rotation and translation, double click the zoom will be adjusted. This function gets its variables from the params as well as the mouse function.

glutMouseFunc - Anytime there is interaction from the mouse this callback will receive the button and state as well as where the event happened.

glutIdleFunc - For when the process lays idle this callback will keep the program processing tasks even when the program is not receiving events.


ScreenShots:

Standard Teapot Diffuse && Specular Enabled:


Standard Teapot Diffuse On Specular off:



Standard 747 w/ Logging - Diffuse on Specular Off:


Standard 747 from different angle Specular && Diffuse enabled:






Last image shows the error checking that is in place should the file path be incorrect.



Interaction:

Keys :

w - Rotate +x
a - Rotate +y
s - Rotate -x
d - Rotate -y
e - Rotate +z
c - Rotate -z

Left Click + Drag - Will Rotate and Zoom (Pan Effect)
Right Click + Drag - Zoom