diff --git a/README.md b/README.md
index 6bc9831..5dfdb06 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,27 @@
--------------------------------------------------------------------------------
+-------------------------------------------------------------------------------
CIS565: Project 5: Advanced GLSL
-------------------------------------------------------------------------------
Fall 2012
--------------------------------------------------------------------------------
+--------------------------------------------------------------
+My Notes:
+
+Blog can be found at http://glslvsfs.blogspot.com/
+
+
+Part 1:
+Implemented all the basic stuff and added a revolving moon to as the extra feature. The rim doesn't look too bright because I just intentionally reduced it. Created a hack for the moon, but it works :)
+
+Part 2:
+Implemented regular grid, poisson sphere and poisson sphere in the world.
+I was finding differences in values between world coordinates and projected screen coordinates. So another hack for it to work ;). The change in camera angle changes AO a lot in the world view, it maybe due to the way I have implemented it.
+
+Part 3:
+Implemented pulsing on the Stanford Dragon.
+Implemented skinning. Not working very great as I had expected, but a basic version. The screenshot shows an extreme version of skinning (which no one will ever do). It has 3 joints and the image just rotates it in 3 different directions.
+
+
+
+-----------------
Due Monday 11/19/2012
-------------------------------------------------------------------------------
diff --git a/part1/Globe/Globe.sdf b/part1/Globe/Globe.sdf
new file mode 100644
index 0000000..b73a2e9
Binary files /dev/null and b/part1/Globe/Globe.sdf differ
diff --git a/part1/Globe/Globe/Globe.cpp b/part1/Globe/Globe/Globe.cpp
index 244cbd0..79b6fcb 100644
--- a/part1/Globe/Globe/Globe.cpp
+++ b/part1/Globe/Globe/Globe.cpp
@@ -35,12 +35,14 @@ static GLuint cloud_tex;
static GLuint cloudtrans_tex;
static GLuint earthspec_tex;
static GLuint disp_tex;
+static GLuint moon_tex;
static const int LONGITUDE_DIVISIONS = 75;
static const int LATITUDE_DIVISIONS = 75;
static const int NUM_LONGITUDE_PTS = LONGITUDE_DIVISIONS + 1;
static const int NUM_LATITUDE_PTS = LATITUDE_DIVISIONS + 1;
static const float RADIUS = 1;
+static const float RADIUS_MOON = 0.21;
//r theta phi
vec3 computeSpherical(vec2 uv, float radius) {
@@ -69,47 +71,86 @@ vec3 computeNormal(vec3 spherical) {
return computePosition(new_spherical);
}
-void appendPoint(mesh_t * mesh, vec2 uv, float radius) {
+void appendPoint(mesh_t * mesh, vec2 uv, float radius, vec3 offset) {
vec3 spherical = computeSpherical(uv, radius);
vec3 position = computePosition(spherical);
vec3 normal = computeNormal(spherical);
- mesh->vertices.push_back(position);
+ mesh->vertices.push_back(position+offset);
mesh->uvs.push_back(uv);
mesh->normals.push_back(normal);
}
//Trig Time
void initSphere() {
+
mesh_t sphere;
- //Check assumptions
- assert(LATITUDE_DIVISIONS >= 2);
- assert(LONGITUDE_DIVISIONS >= 3);
- //drop starting row. Notice num_pts = num_dvisions + 1
- for (int i = 0; i < NUM_LONGITUDE_PTS; i ++) {
- vec2 uv(i / (float)(NUM_LONGITUDE_PTS - 1),0);
- appendPoint(&sphere, uv, RADIUS);
+ {
+ vec3 offset = vec3(0,0,0);
+ //Check assumptions
+ assert(LATITUDE_DIVISIONS >= 2);
+ assert(LONGITUDE_DIVISIONS >= 3);
+ //drop starting row. Notice num_pts = num_dvisions + 1
+ for (int i = 0; i < NUM_LONGITUDE_PTS; i ++) {
+ vec2 uv(i / (float)(NUM_LONGITUDE_PTS - 1),0);
+ appendPoint(&sphere, uv, RADIUS, offset);
+ }
+
+ for (int j = 0; j < LATITUDE_DIVISIONS; j++) {
+ float v = (j + 1)/((float)NUM_LATITUDE_PTS-1);
+ //Set up first point
+ vec2 first_uv(0.0f,v);
+ appendPoint(&sphere, first_uv,RADIUS, offset);
+ //Iterate over divisions
+ for (int i = 0; i < LONGITUDE_DIVISIONS; i++) {
+ //Setup new point
+ vec2 new_uv((i+1)/((float)NUM_LONGITUDE_PTS - 1),v);
+ appendPoint(&sphere,new_uv, RADIUS, offset);
+ unsigned short length = (unsigned short)sphere.vertices.size();
+ unsigned short upper_right = length - 1;
+ unsigned short lower_right = upper_right - NUM_LONGITUDE_PTS;
+ unsigned short lower_left = lower_right - 1;
+ unsigned short upper_left = lower_left + NUM_LONGITUDE_PTS;
+ unsigned short added [] = {upper_left, lower_right, upper_right,
+ upper_left, lower_left, lower_right};
+ for (int i = 0; i < 6; ++i) { sphere.indices.push_back(added[i]); }
+ }
+ }
}
+
+ //mesh_t sphere1;
+ {
+ vec3 offset = vec3(0,1.35,-0.2);
+ //Check assumptions
+ assert(LATITUDE_DIVISIONS >= 2);
+ assert(LONGITUDE_DIVISIONS >= 3);
+ //drop starting row. Notice num_pts = num_dvisions + 1
+ for (int i = 0; i < NUM_LONGITUDE_PTS; i ++) {
+ vec2 uv(i / (float)(NUM_LONGITUDE_PTS - 1),0);
+ appendPoint(&sphere, uv, RADIUS_MOON, offset);
+ }
- for (int j = 0; j < LATITUDE_DIVISIONS; j++) {
- float v = (j + 1)/((float)NUM_LATITUDE_PTS-1);
- //Set up first point
- vec2 first_uv(0.0f,v);
- appendPoint(&sphere, first_uv,RADIUS);
- //Iterate over divisions
- for (int i = 0; i < LONGITUDE_DIVISIONS; i++) {
- //Setup new point
- vec2 new_uv((i+1)/((float)NUM_LONGITUDE_PTS - 1),v);
- appendPoint(&sphere,new_uv, RADIUS);
- unsigned short length = (unsigned short)sphere.vertices.size();
- unsigned short upper_right = length - 1;
- unsigned short lower_right = upper_right - NUM_LONGITUDE_PTS;
- unsigned short lower_left = lower_right - 1;
- unsigned short upper_left = lower_left + NUM_LONGITUDE_PTS;
- unsigned short added [] = {upper_left, lower_right, upper_right,
- upper_left, lower_left, lower_right};
- for (int i = 0; i < 6; ++i) { sphere.indices.push_back(added[i]); }
+ for (int j = 0; j < LATITUDE_DIVISIONS; j++) {
+ float v = (j + 1)/((float)NUM_LATITUDE_PTS-1);
+ //Set up first point
+ vec2 first_uv(0.0f,v);
+ appendPoint(&sphere, first_uv,RADIUS_MOON, offset);
+ //Iterate over divisions
+ for (int i = 0; i < LONGITUDE_DIVISIONS; i++) {
+ //Setup new point
+ vec2 new_uv((i+1)/((float)NUM_LONGITUDE_PTS - 1),v);
+ appendPoint(&sphere,new_uv, RADIUS_MOON, offset);
+ unsigned short length = (unsigned short)sphere.vertices.size();
+ unsigned short upper_right = length - 1;
+ unsigned short lower_right = upper_right - NUM_LONGITUDE_PTS;
+ unsigned short lower_left = lower_right - 1;
+ unsigned short upper_left = lower_left + NUM_LONGITUDE_PTS;
+ unsigned short added [] = {upper_left, lower_right, upper_right,
+ upper_left, lower_left, lower_right};
+ for (int i = 0; i < 6; ++i) { sphere.indices.push_back(added[i]); }
+ }
}
}
+
device_sphere = uploadMesh(sphere);
}
@@ -232,7 +273,7 @@ void rotate(float dx, float dy) {
void initView() {
- dist = 4.0f;
+ dist = 6.0f;
rx = -140.0f;
ry = 0.0f;
}
@@ -251,7 +292,7 @@ float time = 0.0;
void display(void)
{
- time += 0.0001f;
+ time += 0.2*PI/180.0;
// clear the screen
glClearColor(0.0f,0.0f,0.0f,1.0f);
@@ -274,6 +315,8 @@ void display(void)
glUniformMatrix4fv(glGetUniformLocation(current_prog,"u_Persp"),1,GL_FALSE,&persp[0][0]);
glUniformMatrix4fv(glGetUniformLocation(current_prog,"u_InvTrans") ,1,GL_FALSE,&inverse_transposed[0][0]);
glUniform1f(glGetUniformLocation(current_prog,"u_time"), time);
+ vec3 worldLightDir = normalize(worlddirlight);
+ glUniform3fv(glGetUniformLocation(current_prog,"u_WorldSpaceDirLight"),1, &worldLightDir[0]);
glDrawElements(GL_TRIANGLES, current_mesh.num_indices, GL_UNSIGNED_SHORT,0);
@@ -294,7 +337,9 @@ void initGlobeShader() {
cloud_tex = (unsigned int)SOIL_load_OGL_texture("earthcloudmap.jpg",0,0,0);
cloudtrans_tex = (unsigned int)SOIL_load_OGL_texture("earthcloudmaptrans.jpg",0,0,0);
earthspec_tex = (unsigned int) SOIL_load_OGL_texture("earthspec1k.jpg",0,0,0);
-disp_tex = (unsigned int) SOIL_load_OGL_texture("earthbump1k.jpg",0,0,0);
+ disp_tex = (unsigned int) SOIL_load_OGL_texture("earthbump1k.jpg",0,0,0);
+ moon_tex = (unsigned int)SOIL_load_OGL_texture("moonmap4k.jpg",0,0,0);
+
glBindTexture(GL_TEXTURE_2D, cloudtrans_tex);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glBindTexture(GL_TEXTURE_2D, 0);
@@ -325,6 +370,9 @@ void setGlobeShader() {
glActiveTexture(GL_TEXTURE5);
glBindTexture(GL_TEXTURE_2D, disp_tex);
glUniform1i(glGetUniformLocation(current_prog, "u_Bump"),5);
+ glActiveTexture(GL_TEXTURE6);
+ glBindTexture(GL_TEXTURE_2D, moon_tex);
+ glUniform1i(glGetUniformLocation(current_prog, "u_Moon"),6);
}
diff --git a/part1/Globe/Globe/Globe.h b/part1/Globe/Globe/Globe.h
index cb2235e..275ab5c 100644
--- a/part1/Globe/Globe/Globe.h
+++ b/part1/Globe/Globe/Globe.h
@@ -49,7 +49,7 @@ void setGlobeShader();
glm::vec3 computeSpherical(glm::vec2 uv, float radius);
glm::vec3 computePosition(glm::vec3 spherical) ;
glm::vec3 computeNormal(glm::vec3 spherical);
-void appendPoint(mesh_t * mesh, glm::vec2 uv, float radius);
+void appendPoint(mesh_t * mesh, glm::vec2 uv, float radius, glm::vec3 offset);
void initSphere();
device_mesh_t uploadMesh(const mesh_t & mesh);
diff --git a/part1/Globe/Globe/fs.glsl b/part1/Globe/Globe/fs.glsl
index a4a5000..d361b67 100644
--- a/part1/Globe/Globe/fs.glsl
+++ b/part1/Globe/Globe/fs.glsl
@@ -1,6 +1,10 @@
//View-Space directional light
//A unit vector
uniform vec3 u_CameraSpaceDirLight;
+uniform vec3 u_WorldSpaceDirLight;
+uniform mat4 u_Model;
+uniform mat4 u_View;
+uniform mat4 u_Persp;
//Diffuse texture map for the day
uniform sampler2D u_DayDiffuse;
@@ -16,6 +20,8 @@ uniform sampler2D u_CloudTrans;
uniform sampler2D u_EarthSpec;
//Bump map
uniform sampler2D u_Bump;
+//Moon map
+uniform sampler2D u_Moon;
uniform float u_time;
uniform mat4 u_InvTrans;
@@ -24,6 +30,7 @@ varying vec3 v_Normal; // surface normal in camera coordinates
varying vec2 v_Texcoord;
varying vec3 v_Position; // position in camera coordinates
varying vec3 v_positionMC; // position in model coordinates
+varying vec3 v_positionWorld; // position in model coordinates
mat3 eastNorthUpToEyeCoordinates(vec3 positionMC, vec3 normalEC);
@@ -32,18 +39,73 @@ void main(void)
vec3 normal = normalize(v_Normal); // surface normal - normalized after rasterization
vec3 eyeToPosition = normalize(v_Position); // normalized eye-to-position vector in camera coordinates
- float diffuse = max(dot(u_CameraSpaceDirLight, normal), 0.0);
+ float dotProd = dot(u_CameraSpaceDirLight, normal);
+
+ vec4 center = texture2D(u_Bump, v_Texcoord);
+ vec4 right = texture2D(u_Bump, vec2(v_Texcoord.x+1.0/1000.0, v_Texcoord.y));
+ vec4 top = texture2D(u_Bump, vec2(v_Texcoord.x, v_Texcoord.y+1.0/500.0));
+ vec3 newNormal = normalize(vec3(center.x - right.x, center.y - top.y, 0.2));
+ mat3 matrix = eastNorthUpToEyeCoordinates(v_positionMC, normal);
+ newNormal = matrix*newNormal;
+ newNormal = normalize(newNormal);
- vec3 toReflectedLight = reflect(-u_CameraSpaceDirLight, normal);
+ float newdotProd = dot(u_CameraSpaceDirLight, newNormal);
+ float diffuse = max(newdotProd, 0.0);
+
+ vec3 toReflectedLight = reflect(-u_CameraSpaceDirLight, newNormal);
float specular = max(dot(toReflectedLight, -eyeToPosition), 0.0);
specular = pow(specular, 20.0);
- float gammaCorrect = 1/1.8; //gamma correct by 1/1.8
+ float gammaCorrect = 1.0/1.8; //gamma correct by 1/1.8
vec4 dayColor = texture2D(u_DayDiffuse, v_Texcoord);
- vec4 nightColor = pow(texture2D(u_Night, v_Texcoord),gammaCorrect); //apply gamma correction to nighttime texture
+ vec4 ocean = texture2D(u_EarthSpec, v_Texcoord);
+
+ vec4 cloudColor = texture2D(u_Cloud, vec2(v_Texcoord.s+0.02*u_time, v_Texcoord.t));
+ vec4 cloudTransp = texture2D(u_CloudTrans, vec2(v_Texcoord.s+0.02*u_time, v_Texcoord.t));
+
+ vec4 finalDayColor = mix(cloudColor, ((0.6 * diffuse) + (0.4 * specular)*ocean) * dayColor, cloudTransp);
+ vec4 nightColor = mix(0.0, pow(texture2D(u_Night, v_Texcoord),gammaCorrect), cloudTransp); //apply gamma correction to nighttime texture
+
+ // Rim lighting
+ float rimFactor = dot(v_Normal, v_Position)+0.6;
+ float rim = 0.6;
+ vec4 newColor = mix(nightColor, finalDayColor, clamp(2.0*(dotProd+0.25),0.0,1.0));
+
+ vec4 shadowColor = vec4(1);
+ bool inShadow = false;
+ //if (v_positionMC.y < 1.1)
+ //{
+ // // Shadow
+ // // Imagine that the clouds are at a height of say 0.2 above the ground
+ //
+ // float cloudDistFromGround = 0.01;
+ // vec3 cloudHitPoint = v_Position + u_WorldSpaceDirLight * cloudDistFromGround;
+
+ // // Transform this point to screen
+ // vec4 cloudScreen = u_Persp * (u_View* (u_Model * vec4(cloudHitPoint, 1.0)));
+ // vec2 cloudScreenPoint = cloudScreen.xy/cloudScreen.w;
+ // cloudScreenPoint = cloudScreenPoint*0.5 + 0.5;
+
+ // vec4 cloudShadow = texture2D(u_Cloud, cloudScreenPoint);
+ // vec4 cloudShadowTransp = texture2D(u_CloudTrans, cloudScreenPoint);
+
+ // if (cloudShadowTransp.x <0.8 || cloudShadowTransp.y <0.8)
+ // {
+ // inShadow = true;
+ // shadowColor = vec4(1.0-cloudShadowTransp);
+ // }
+ //}
- gl_FragColor = ((0.6 * diffuse) + (0.4 * specular)) * dayColor;
+
+ // Mixing color and rim factor to get the final color of the fragment
+ if (v_positionMC.y > 1.1)
+ gl_FragColor = texture2D(u_Moon, v_Texcoord);
+ else
+ {
+ vec4 finalColor = mix(newColor, vec4(rim/4.0, rim/2.0, rim/2.0, 1.0), clamp(2.0*(rimFactor+0.25),0.0,1.0));
+ gl_FragColor = mix(vec4(0.0,0.0,0.0,finalColor.w), finalColor, shadowColor);
+ }
}
mat3 eastNorthUpToEyeCoordinates(vec3 positionMC, vec3 normalEC)
diff --git a/part1/Globe/Globe/moonmap4k.jpg b/part1/Globe/Globe/moonmap4k.jpg
new file mode 100644
index 0000000..3625930
Binary files /dev/null and b/part1/Globe/Globe/moonmap4k.jpg differ
diff --git a/part1/Globe/Globe/vs.glsl b/part1/Globe/Globe/vs.glsl
index e1eb94d..48fbac0 100644
--- a/part1/Globe/Globe/vs.glsl
+++ b/part1/Globe/Globe/vs.glsl
@@ -2,6 +2,7 @@ uniform mat4 u_Model;
uniform mat4 u_View;
uniform mat4 u_Persp;
uniform mat4 u_InvTrans;
+uniform float u_time;
attribute vec3 Position;
attribute vec3 Normal;
@@ -11,14 +12,24 @@ varying vec3 v_Normal;
varying vec2 v_Texcoord;
varying vec3 v_Position;
varying vec3 v_positionMC;
+varying vec3 v_positionWorld;
void main(void)
{
+ vec3 pos = Position;
+
+ if (Position.y > 1.1)
+ {
+ pos.x -= 1.7*sin(u_time);
+ pos.z += 1.7*cos(u_time);
+ //Position.z += cos(u_time);
+ }
v_Normal = (u_InvTrans*vec4(Normal,0.0)).xyz;
v_Texcoord = Texcoord;
- vec4 world = u_Model * vec4(Position, 1.0);
+ vec4 world = u_Model * vec4(pos, 1.0);
vec4 camera = u_View * world;
v_Position = camera.xyz;
- v_positionMC = Position;
+ v_positionMC = pos;
+ v_positionWorld = world.xyz;
gl_Position = u_Persp * camera;
}
diff --git a/part2/565GLFrame/565GLFrame.sdf b/part2/565GLFrame/565GLFrame.sdf
new file mode 100644
index 0000000..62f8b4a
Binary files /dev/null and b/part2/565GLFrame/565GLFrame.sdf differ
diff --git a/part2/565GLFrame/565GLFrame/565GLFrame.vcxproj b/part2/565GLFrame/565GLFrame/565GLFrame.vcxproj
index fb709ae..e32a163 100644
--- a/part2/565GLFrame/565GLFrame/565GLFrame.vcxproj
+++ b/part2/565GLFrame/565GLFrame/565GLFrame.vcxproj
@@ -108,6 +108,8 @@
+
+
diff --git a/part2/565GLFrame/565GLFrame/565GLFrame.vcxproj.filters b/part2/565GLFrame/565GLFrame/565GLFrame.vcxproj.filters
index f0e54d9..5e0c8af 100644
--- a/part2/565GLFrame/565GLFrame/565GLFrame.vcxproj.filters
+++ b/part2/565GLFrame/565GLFrame/565GLFrame.vcxproj.filters
@@ -39,6 +39,12 @@
Resources
+
+ Source Files
+
+
+ Source Files
+
diff --git a/part2/565GLFrame/565GLFrame/565GLFrame.vcxproj.tease.nvuser b/part2/565GLFrame/565GLFrame/565GLFrame.vcxproj.tease.nvuser
new file mode 100644
index 0000000..6a94f56
--- /dev/null
+++ b/part2/565GLFrame/565GLFrame/565GLFrame.vcxproj.tease.nvuser
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/part2/565GLFrame/565GLFrame/565GLFrame.vcxproj.user b/part2/565GLFrame/565GLFrame/565GLFrame.vcxproj.user
index e0a41f0..4c685f0 100644
--- a/part2/565GLFrame/565GLFrame/565GLFrame.vcxproj.user
+++ b/part2/565GLFrame/565GLFrame/565GLFrame.vcxproj.user
@@ -4,4 +4,8 @@
mesh=../sponza.obj
WindowsLocalDebugger
+
+ mesh=../sponza.obj
+ WindowsLocalDebugger
+
\ No newline at end of file
diff --git a/part2/565GLFrame/565GLFrame/blur.frag b/part2/565GLFrame/565GLFrame/blur.frag
new file mode 100644
index 0000000..bd92ebd
--- /dev/null
+++ b/part2/565GLFrame/565GLFrame/blur.frag
@@ -0,0 +1,12 @@
+#version 330
+
+uniform sampler2D u_SSAOtex;
+
+in vec2 fs_Texcoord;
+
+out vec4 out_Color;
+
+void main(void)
+{
+ out_Color = vec4(texture(u_SSAOtex,fs_Texcoord).xyz, 1.0);
+}
diff --git a/part2/565GLFrame/565GLFrame/blur.vert b/part2/565GLFrame/565GLFrame/blur.vert
new file mode 100644
index 0000000..9d66621
--- /dev/null
+++ b/part2/565GLFrame/565GLFrame/blur.vert
@@ -0,0 +1,11 @@
+#version 330
+
+in vec3 Position;
+in vec2 Texcoord;
+
+out vec2 fs_Texcoord;
+
+void main() {
+ fs_Texcoord = Texcoord;
+ gl_Position = vec4(Position,1.0f);
+}
\ No newline at end of file
diff --git a/part2/565GLFrame/565GLFrame/main.cpp b/part2/565GLFrame/565GLFrame/main.cpp
index 3fc40a1..2af0b21 100644
--- a/part2/565GLFrame/565GLFrame/main.cpp
+++ b/part2/565GLFrame/565GLFrame/main.cpp
@@ -78,15 +78,19 @@ void initMesh() {
for(int i=f; i face = objmesh->getFaces()->operator[](i);
- vector facenormal = objmesh->getFaceNormals()->operator[](i);
+ //vector facenormal = objmesh->getFaceNormals()->operator[](i);
mesh.vertices.push_back(glm::vec3(objmesh->getPoints()->operator[](face[0])));
mesh.vertices.push_back(glm::vec3(objmesh->getPoints()->operator[](face[1])));
mesh.vertices.push_back(glm::vec3(objmesh->getPoints()->operator[](face[2])));
- mesh.normals.push_back(glm::vec3(objmesh->getNormals()->operator[](facenormal[0])));
+ /*mesh.normals.push_back(glm::vec3(objmesh->getNormals()->operator[](facenormal[0])));
mesh.normals.push_back(glm::vec3(objmesh->getNormals()->operator[](facenormal[1])));
- mesh.normals.push_back(glm::vec3(objmesh->getNormals()->operator[](facenormal[2])));
+ mesh.normals.push_back(glm::vec3(objmesh->getNormals()->operator[](facenormal[2])));*/
+
+ mesh.normals.push_back(glm::vec3(objmesh->getSmoothNormals()->operator[](face[0])));
+ mesh.normals.push_back(glm::vec3(objmesh->getSmoothNormals()->operator[](face[1])));
+ mesh.normals.push_back(glm::vec3(objmesh->getSmoothNormals()->operator[](face[2])));
mesh.indices.push_back(points);
mesh.indices.push_back(points+1);
@@ -142,6 +146,7 @@ GLuint normalTexture = 0;
GLuint positionTexture = 0;
GLuint FBO = 0;
+GLuint ssaoTexture = 0;
GLuint pass_prog;
void initPass() {
@@ -168,6 +173,18 @@ void initSSAO() {
Utility::attachAndLinkProgram(ssao_prog, shaders);
}
+GLuint blur_prog;
+void initBlur() {
+ Utility::shaders_t shaders = Utility::loadShaders("blur.vert", "blur.frag");
+
+ blur_prog = glCreateProgram();
+
+ glBindAttribLocation(blur_prog, 0, "Position");
+ glBindAttribLocation(blur_prog, 1, "Texcoord");
+
+ Utility::attachAndLinkProgram(blur_prog, shaders);
+}
+
void freeFBO() {
glDeleteTextures(1,&depthTexture);
glDeleteTextures(1,&normalTexture);
@@ -352,6 +369,10 @@ Camera::adjust(float dx, // look left right
pos += mag;
}
+ if (abs(ty) > 0) {
+ z += ty;
+ }
+
if (abs(tz) > 0) {
vec3 dir = glm::gtx::rotate_vector::rotate(start_dir,rx,up);
vec2 dir2(dir.x,dir.y);
@@ -581,6 +602,7 @@ void motion(int x, int y)
void keyboard(unsigned char key, int x, int y) {
float tx = 0;
float tz = 0;
+ float ty = 0;
switch(key) {
case('w'):
tz = 0.1;
@@ -594,6 +616,12 @@ void keyboard(unsigned char key, int x, int y) {
case('a'):
tx = 0.1;
break;
+ case('q'):
+ ty = +0.1;
+ break;
+ case('z'):
+ ty = -0.1;
+ break;
case('1'):
occlusion_type = OCCLUSION_NONE;
break;
@@ -623,8 +651,8 @@ void keyboard(unsigned char key, int x, int y) {
break;
}
- if (abs(tx) > 0 || abs(tz) > 0 ) {
- cam.adjust(0,0,0,tx,0,tz);
+ if (abs(tx) > 0 || abs(tz) > 0 || abs(ty) > 0) {
+ cam.adjust(0,0,0,tx,ty,tz);
}
}
@@ -646,6 +674,10 @@ int main (int argc, char* argv[])
//renderScene = new scene(data);
objmesh = new obj();
objLoader* loader = new objLoader(data, objmesh);
+ glm::vec3 meshPos = glm::vec3(0,0,0);
+ glm::vec3 meshRot = glm::vec3(0,0,0);
+ glm::vec3 meshScale = glm::vec3(1,1,1);
+ objmesh->setTransforms(meshPos, meshRot, meshScale);
objmesh->buildVBOs();
delete loader;
loadedScene = true;
@@ -676,6 +708,7 @@ int main (int argc, char* argv[])
cout << "OpenGL version " << glGetString(GL_VERSION) << " supported" << endl;
initNoise();
+ initBlur();
initSSAO();
initPass();
initFBO(width,height);
diff --git a/part2/565GLFrame/565GLFrame/obj.cpp b/part2/565GLFrame/565GLFrame/obj.cpp
index 2749610..fadf5f2 100644
--- a/part2/565GLFrame/565GLFrame/obj.cpp
+++ b/part2/565GLFrame/565GLFrame/obj.cpp
@@ -4,6 +4,7 @@
#include "obj.h"
#include
#include
+#include "glm/gtc/matrix_transform.hpp"
#define EPSILON std::numeric_limits::epsilon()
@@ -41,18 +42,31 @@ void obj::buildVBOs(){
vector NBOvec;
vector IBOvec;
int index = 0;
- bool genNormals = true;
+
+ glm::mat4 transform = getTransform();
+ for (int i=0; i face = faces[k];
+ glm::mat4 transform = getTransform();
glm::vec4 p0 = points[face[0]];
-
for(int i=2; i facenormal = facenormals[k];
- NBOvec.push_back(normals[facenormal[0]][0]); NBOvec.push_back(normals[facenormal[0]][1]); NBOvec.push_back(normals[facenormal[0]][2]); //NBOvec.push_back(0.0f);
- NBOvec.push_back(normals[facenormal[i-1]][0]); NBOvec.push_back(normals[facenormal[i-1]][1]); NBOvec.push_back(normals[facenormal[i-1]][2]); //NBOvec.push_back(0.0f);
- NBOvec.push_back(normals[facenormal[i]][0]); NBOvec.push_back(normals[facenormal[i]][1]); NBOvec.push_back(normals[facenormal[i]][2]); //NBOvec.push_back(0.0f);
+ glm::vec4 n0 = normals[facenormal[0]];
+ //n0 = glm::normalize(transform*n0);
+ glm::vec4 n1 = normals[facenormal[i-1]];
+ //n1 = glm::normalize(transform*n1);
+ glm::vec4 n2 = normals[facenormal[i]];
+ //n2 = glm::normalize(transform*n2);
+
+ smoothNormals[face[0]] += n0;//normals[facenormal[0]];
+ smoothNormals[face[i-1]] += n1;//normals[facenormal[i-1]];
+ smoothNormals[face[i]] += n2;//normals[facenormal[i]];
+
+ /*NBOvec.push_back(n0[0]); NBOvec.push_back(n0[1]); NBOvec.push_back(n0[2]); //NBOvec.push_back(0.0f);
+ NBOvec.push_back(n1[0]); NBOvec.push_back(n1[1]); NBOvec.push_back(n1[2]); //NBOvec.push_back(0.0f);
+ NBOvec.push_back(n2[0]); NBOvec.push_back(n2[1]); NBOvec.push_back(n2[2]); //NBOvec.push_back(0.0f);*/
}else{
glm::vec3 a = glm::vec3(p1[0], p1[1], p1[2]) - glm::vec3(p0[0], p0[1], p0[2]);
glm::vec3 b = glm::vec3(p2[0], p2[1], p2[2]) - glm::vec3(p0[0], p0[1], p0[2]);
glm::vec3 n = glm::normalize(glm::cross(a,b));
- NBOvec.push_back(n[0]); NBOvec.push_back(n[1]); NBOvec.push_back(n[2]); //NBOvec.push_back(0.0f);
- NBOvec.push_back(n[0]); NBOvec.push_back(n[1]); NBOvec.push_back(n[2]); //NBOvec.push_back(0.0f);
- NBOvec.push_back(n[0]); NBOvec.push_back(n[1]); NBOvec.push_back(n[2]); //NBOvec.push_back(0.0f);
+ smoothNormals[face[0]] += glm::vec4(n,0);//normals[facenormal[0]];
+ smoothNormals[face[i-1]] += glm::vec4(n,0);//normals[facenormal[i-1]];
+ smoothNormals[face[i]] += glm::vec4(n,0);//normals[facenormal[i]];
+ //NBOvec.push_back(n[0]); NBOvec.push_back(n[1]); NBOvec.push_back(n[2]); //NBOvec.push_back(0.0f);
+ //NBOvec.push_back(n[0]); NBOvec.push_back(n[1]); NBOvec.push_back(n[2]); //NBOvec.push_back(0.0f);
+ //NBOvec.push_back(n[0]); NBOvec.push_back(n[1]); NBOvec.push_back(n[2]); //NBOvec.push_back(0.0f);
}
IBOvec.push_back(index+0); IBOvec.push_back(index+1); IBOvec.push_back(index+2);
@@ -81,6 +109,30 @@ void obj::buildVBOs(){
}
}
}
+
+ for (int i = 0; i face = faces[k];
+ for(int i=2; i facenormal = facenormals[k];
+ glm::vec4 n0 = smoothNormals[face[0]];
+ glm::vec4 n1 = smoothNormals[face[i-1]];
+ glm::vec4 n2 = smoothNormals[face[i]];
+
+ NBOvec.push_back(n0[0]); NBOvec.push_back(n0[1]); NBOvec.push_back(n0[2]); //NBOvec.push_back(0.0f);
+ NBOvec.push_back(n1[0]); NBOvec.push_back(n1[1]); NBOvec.push_back(n1[2]); //NBOvec.push_back(0.0f);
+ NBOvec.push_back(n2[0]); NBOvec.push_back(n2[1]); NBOvec.push_back(n2[2]); //NBOvec.push_back(0.0f);
+ //}
+ }
+ }
+ }
vbo = new float[VBOvec.size()];
nbo = new float[NBOvec.size()];
@@ -285,6 +337,10 @@ vector* obj::getNormals(){
return &normals;
}
+vector* obj::getSmoothNormals(){
+ return &smoothNormals;
+}
+
vector* obj::getTextureCoords(){
return &texturecoords;
}
@@ -329,3 +385,20 @@ int obj::getCBOsize(){
return cbosize;
}
+glm::mat4 obj::getTransform()
+{
+ glm::mat4 translationMat = glm::translate(glm::mat4(), pos);
+ glm::mat4 rotationMat = glm::rotate(glm::mat4(), rot.x, glm::vec3(1,0,0));
+ rotationMat = rotationMat*glm::rotate(glm::mat4(), rot.y, glm::vec3(0,1,0));
+ rotationMat = rotationMat*glm::rotate(glm::mat4(), rot.z, glm::vec3(0,0,1));
+ glm::mat4 scaleMat = glm::scale(glm::mat4(), scale);
+ return translationMat*rotationMat*scaleMat;
+ //return scaleMat*rotationMat*translationMat;
+}
+
+void obj::setTransforms(glm::vec3 v_pos, glm::vec3 v_rot, glm::vec3 v_scale)
+{
+ pos = v_pos;
+ rot = v_rot;
+ scale = v_scale;
+}
\ No newline at end of file
diff --git a/part2/565GLFrame/565GLFrame/obj.h b/part2/565GLFrame/565GLFrame/obj.h
index 84939ba..51edd76 100644
--- a/part2/565GLFrame/565GLFrame/obj.h
+++ b/part2/565GLFrame/565GLFrame/obj.h
@@ -18,6 +18,7 @@ class obj{
vector > facetextures;
vector faceboxes; //bounding boxes for each face are stored in vbo-format!
vector normals;
+ vector smoothNormals;
vector texturecoords;
int vbosize;
int nbosize;
@@ -32,6 +33,10 @@ class obj{
glm::vec3 defaultColor;
float xmax; float xmin; float ymax; float ymin; float zmax; float zmin;
bool maxminSet;
+
+ glm::vec3 pos;
+ glm::vec3 rot;
+ glm::vec3 scale;
public:
obj();
~obj();
@@ -70,8 +75,12 @@ class obj{
vector >* getFaceNormals();
vector >* getFaceTextures();
vector* getNormals();
+ vector* getSmoothNormals();
vector* getTextureCoords();
vector* getFaceBoxes();
+
+ glm::mat4 getTransform();
+ void setTransforms(glm::vec3 v_pos, glm::vec3 v_rot, glm::vec3 v_scale);
};
#endif
\ No newline at end of file
diff --git a/part2/565GLFrame/565GLFrame/ssao.frag b/part2/565GLFrame/565GLFrame/ssao.frag
index 54e5967..03c5f68 100644
--- a/part2/565GLFrame/565GLFrame/ssao.frag
+++ b/part2/565GLFrame/565GLFrame/ssao.frag
@@ -8,13 +8,13 @@
#define OCCLUSION_POISSON_SS_SAMPLES 2
#define OCCLUSION_WORLD_SPACE_SAMPLES 3
-
#define DISPLAY_DEPTH 0
#define DISPLAY_NORMAL 1
#define DISPLAY_POSITION 2
#define DISPLAY_OCCLUSION 3
#define DISPLAY_TOTAL 4
+#define PI 3.14
/////////////////////////////////////
// Uniforms, Attributes, and Outputs
@@ -96,14 +96,42 @@ float gatherOcclusion( vec3 pt_normal,
vec3 pt_position,
vec3 occluder_normal,
vec3 occluder_position) {
- return -1.0f;///IMPLEMENT THIS
+
+ //if (occluder_position.z >= pt_position.z)
+ //return 0.0;
+
+ float depthDiff = (pt_position.z - occluder_position.z);
+ //if (depthDiff < 0.001)
+ //return 0.0;
+
+ float normDiff = (1.0-dot(occluder_normal, pt_normal));
+ return step(0.001, depthDiff)*normDiff*(1.0-smoothstep(0.001, 0.08, depthDiff));
+ //return abs(depthDiff);
+
+ //return -1.0f;///IMPLEMENT THIS
}
const float REGULAR_SAMPLE_STEP = 0.012f;
float occlusionWithRegularSamples(vec2 texcoord,
vec3 position,
vec3 normal) {
- return -1.0f; //IMPLEMENT THIS
+
+ float occlusion = 0.0;
+ normal = normalize(normal);
+ for (float x = -1.5*REGULAR_SAMPLE_STEP; x<= 1.5*REGULAR_SAMPLE_STEP; x+= REGULAR_SAMPLE_STEP)
+ {
+ for (float y = -1.5*REGULAR_SAMPLE_STEP; y<= 1.5*REGULAR_SAMPLE_STEP; y+= REGULAR_SAMPLE_STEP)
+ {
+ vec2 occluderTexcoord = vec2(texcoord.x+x, texcoord.y+y);
+ vec3 occluderPosition = samplePos(occluderTexcoord);
+ vec3 occluderNormal = sampleNrm(occluderTexcoord);
+ occluderNormal = normalize(occluderNormal);
+ occlusion += gatherOcclusion(normal, position, occluderNormal, occluderPosition);
+ }
+ }
+
+ return occlusion * (1.0/16.0);
+ //return -1.0f; //IMPLEMENT THIS
}
@@ -132,7 +160,26 @@ const float SS_RADIUS = 0.02f;
float occlusionWithPoissonSSSamples(vec2 texcoord,
vec3 position,
vec3 normal) {
- return -1.0f; //IMPLEMENT THIS
+
+ float occlusion = 0.0;
+ normal = normalize(normal);
+ float randVal = getRandomScalar(texcoord)*2.0*PI;
+ float cosVal = cos(randVal);
+ float sinVal = sin(randVal);
+
+ for(int i=0; i
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav
+
+
+ {6f59ee02-fbfd-456b-aaac-7b7db5e1b49a}
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ GLSL
+
+
+ GLSL
+
+
+ GLSL
+
+
+ GLSL
+
+
+ Resources
+
+
+ Resources
+
+
+ Resources
+
+
+
\ No newline at end of file
diff --git a/part3/565GLFrame/565GLFrame/565GLFrame.vcproj b/part3/565GLFrame/565GLFrame/565GLFrame.vcproj
new file mode 100644
index 0000000..d996679
--- /dev/null
+++ b/part3/565GLFrame/565GLFrame/565GLFrame.vcproj
@@ -0,0 +1,232 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/part3/565GLFrame/565GLFrame/565GLFrame.vcxproj b/part3/565GLFrame/565GLFrame/565GLFrame.vcxproj
new file mode 100644
index 0000000..3767492
--- /dev/null
+++ b/part3/565GLFrame/565GLFrame/565GLFrame.vcxproj
@@ -0,0 +1,137 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+
+ {BE7096A9-AE60-4A3E-95B1-ACBFF084E9C3}
+ 565GLFrame
+ Win32Proj
+ 565GLFrame
+
+
+
+ Application
+ Unicode
+ true
+
+
+ Application
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+ <_ProjectFileVersion>10.0.30319.1
+ $(SolutionDir)$(Configuration)\
+ $(Configuration)\
+ true
+ $(SolutionDir)$(Configuration)\
+ $(Configuration)\
+ false
+ AllRules.ruleset
+
+
+ AllRules.ruleset
+
+
+
+
+
+ Disabled
+ ..\..\shared32\glm;..\..\shared32\freeglut\include;..\..\shared32\glew\include;..\Shader_Loading;..\SOIL;%(AdditionalIncludeDirectories)
+ WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ true
+ EnableFastChecks
+ MultiThreadedDebugDLL
+
+
+ Level3
+ EditAndContinue
+
+
+ freeglut.lib;glew32.lib;%(AdditionalDependencies)
+ ..\..\shared32\glew\lib;..\..\shared32\freeglut\lib;%(AdditionalLibraryDirectories)
+ true
+ Console
+ MachineX86
+
+
+
+
+ MaxSpeed
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ MultiThreadedDLL
+ true
+
+
+ Level3
+ ProgramDatabase
+ ..\..\shared32\glm;..\..\shared32\freeglut\include;..\..\shared32\glew\include;..\Shader_Loading;..\SOIL;%(AdditionalIncludeDirectories)
+
+
+ true
+ Console
+ true
+ true
+ MachineX86
+ ..\..\shared32\glew\lib;..\..\shared32\freeglut\lib;%(AdditionalLibraryDirectories)
+ freeglut.lib;glew32.lib;%(AdditionalDependencies)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {25544c77-3b78-405f-a15d-1231d05969f3}
+ false
+
+
+
+
+
+
\ No newline at end of file
diff --git a/part3/565GLFrame/565GLFrame/565GLFrame.vcxproj.filters b/part3/565GLFrame/565GLFrame/565GLFrame.vcxproj.filters
new file mode 100644
index 0000000..a34e059
--- /dev/null
+++ b/part3/565GLFrame/565GLFrame/565GLFrame.vcxproj.filters
@@ -0,0 +1,92 @@
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Resources
+
+
+ Resources
+
+
+ Resources
+
+
+ Resources
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
+
+ {653f4210-8695-4246-a7cb-772dcf907199}
+
+
+ {36fa45bc-e486-4c3e-8f5d-faa25587c2ae}
+
+
+ {591122f9-cdec-49e4-bbf0-693802d53f4e}
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/part3/565GLFrame/565GLFrame/565GLFrame.vcxproj.tease.nvuser b/part3/565GLFrame/565GLFrame/565GLFrame.vcxproj.tease.nvuser
new file mode 100644
index 0000000..6a94f56
--- /dev/null
+++ b/part3/565GLFrame/565GLFrame/565GLFrame.vcxproj.tease.nvuser
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/part3/565GLFrame/565GLFrame/565GLFrame.vcxproj.user b/part3/565GLFrame/565GLFrame/565GLFrame.vcxproj.user
new file mode 100644
index 0000000..2a82383
--- /dev/null
+++ b/part3/565GLFrame/565GLFrame/565GLFrame.vcxproj.user
@@ -0,0 +1,11 @@
+
+
+
+ mesh=../cow.obj
+ WindowsLocalDebugger
+
+
+ mesh=../cow.obj
+ WindowsLocalDebugger
+
+
\ No newline at end of file
diff --git a/part3/565GLFrame/565GLFrame/Utility.cpp b/part3/565GLFrame/565GLFrame/Utility.cpp
new file mode 100644
index 0000000..1a33e70
--- /dev/null
+++ b/part3/565GLFrame/565GLFrame/Utility.cpp
@@ -0,0 +1,142 @@
+#include "Utility.h"
+
+#include
+#include
+#include
+#include
+
+using namespace std;
+
+namespace Utility {
+
+ char* loadFile(char *fname, GLint &fSize)
+ {
+ ifstream::pos_type size;
+ char * memblock;
+ std::string text;
+
+ // file read based on example in cplusplus.com tutorial
+ ifstream file (fname, ios::in|ios::binary|ios::ate);
+ if (file.is_open())
+ {
+ size = file.tellg();
+ fSize = (GLuint) size;
+ memblock = new char [size];
+ file.seekg (0, ios::beg);
+ file.read (memblock, size);
+ file.close();
+ cout << "file " << fname << " loaded" << endl;
+ text.assign(memblock);
+ }
+ else
+ {
+ cout << "Unable to open file " << fname << endl;
+ exit(1);
+ }
+ return memblock;
+ }
+
+ // printShaderInfoLog
+ // From OpenGL Shading Language 3rd Edition, p215-216
+ // Display (hopefully) useful error messages if shader fails to compile
+ void printShaderInfoLog(GLint shader)
+ {
+ int infoLogLen = 0;
+ int charsWritten = 0;
+ GLchar *infoLog;
+
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLen);
+
+ // should additionally check for OpenGL errors here
+
+ if (infoLogLen > 0)
+ {
+ infoLog = new GLchar[infoLogLen];
+ // error check for fail to allocate memory omitted
+ glGetShaderInfoLog(shader,infoLogLen, &charsWritten, infoLog);
+ cout << "InfoLog:" << endl << infoLog << endl;
+ delete [] infoLog;
+ }
+
+ // should additionally check for OpenGL errors here
+ }
+
+ void printLinkInfoLog(GLint prog)
+ {
+ int infoLogLen = 0;
+ int charsWritten = 0;
+ GLchar *infoLog;
+
+ glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &infoLogLen);
+
+ // should additionally check for OpenGL errors here
+
+ if (infoLogLen > 0)
+ {
+ infoLog = new GLchar[infoLogLen];
+ // error check for fail to allocate memory omitted
+ glGetProgramInfoLog(prog,infoLogLen, &charsWritten, infoLog);
+ cout << "InfoLog:" << endl << infoLog << endl;
+ delete [] infoLog;
+ }
+ }
+
+ shaders_t loadShaders(char * vert_path, char * frag_path) {
+ GLuint f, v;
+
+ char *vs,*fs;
+
+ v = glCreateShader(GL_VERTEX_SHADER);
+ f = glCreateShader(GL_FRAGMENT_SHADER);
+
+ // load shaders & get length of each
+ GLint vlen;
+ GLint flen;
+ vs = loadFile(vert_path,vlen);
+ fs = loadFile(frag_path,flen);
+
+ const char * vv = vs;
+ const char * ff = fs;
+
+ glShaderSource(v, 1, &vv,&vlen);
+ glShaderSource(f, 1, &ff,&flen);
+
+ GLint compiled;
+
+ glCompileShader(v);
+ glGetShaderiv(v, GL_COMPILE_STATUS, &compiled);
+ if (!compiled)
+ {
+ cout << "Vertex shader not compiled." << endl;
+ printShaderInfoLog(v);
+ }
+
+ glCompileShader(f);
+ glGetShaderiv(f, GL_COMPILE_STATUS, &compiled);
+ if (!compiled)
+ {
+ cout << "Fragment shader not compiled." << endl;
+ printShaderInfoLog(f);
+ }
+ shaders_t out; out.vertex = v; out.fragment = f;
+
+ delete [] vs; // dont forget to free allocated memory
+ delete [] fs; // we allocated this in the loadFile function...
+
+ return out;
+ }
+
+ void attachAndLinkProgram( GLuint program, shaders_t shaders) {
+ glAttachShader(program, shaders.vertex);
+ glAttachShader(program, shaders.fragment);
+
+ glLinkProgram(program);
+ GLint linked;
+ glGetProgramiv(program,GL_LINK_STATUS, &linked);
+ if (!linked)
+ {
+ cout << "Program did not link." << endl;
+ printLinkInfoLog(program);
+ }
+ }
+}
\ No newline at end of file
diff --git a/part3/565GLFrame/565GLFrame/Utility.h b/part3/565GLFrame/565GLFrame/Utility.h
new file mode 100644
index 0000000..20ba844
--- /dev/null
+++ b/part3/565GLFrame/565GLFrame/Utility.h
@@ -0,0 +1,29 @@
+#ifndef UTILITY_H_
+#define UTILITY_H_
+
+#include
+
+namespace Utility {
+
+ typedef struct {
+ GLuint vertex;
+ GLuint fragment;
+ } shaders_t;
+
+
+
+shaders_t loadShaders(char * vert_path, char * frag_path);
+
+void attachAndLinkProgram( GLuint program, shaders_t shaders);
+
+char* loadFile(char *fname, GLint &fSize);
+
+// printShaderInfoLog
+// From OpenGL Shading Language 3rd Edition, p215-216
+// Display (hopefully) useful error messages if shader fails to compile
+void printShaderInfoLog(GLint shader);
+
+void printLinkInfoLog(GLint prog) ;
+}
+
+#endif
\ No newline at end of file
diff --git a/part3/565GLFrame/565GLFrame/blur.frag b/part3/565GLFrame/565GLFrame/blur.frag
new file mode 100644
index 0000000..bd92ebd
--- /dev/null
+++ b/part3/565GLFrame/565GLFrame/blur.frag
@@ -0,0 +1,12 @@
+#version 330
+
+uniform sampler2D u_SSAOtex;
+
+in vec2 fs_Texcoord;
+
+out vec4 out_Color;
+
+void main(void)
+{
+ out_Color = vec4(texture(u_SSAOtex,fs_Texcoord).xyz, 1.0);
+}
diff --git a/part3/565GLFrame/565GLFrame/blur.vert b/part3/565GLFrame/565GLFrame/blur.vert
new file mode 100644
index 0000000..9d66621
--- /dev/null
+++ b/part3/565GLFrame/565GLFrame/blur.vert
@@ -0,0 +1,11 @@
+#version 330
+
+in vec3 Position;
+in vec2 Texcoord;
+
+out vec2 fs_Texcoord;
+
+void main() {
+ fs_Texcoord = Texcoord;
+ gl_Position = vec4(Position,1.0f);
+}
\ No newline at end of file
diff --git a/part3/565GLFrame/565GLFrame/city.txt b/part3/565GLFrame/565GLFrame/city.txt
new file mode 100644
index 0000000..c88b423
--- /dev/null
+++ b/part3/565GLFrame/565GLFrame/city.txt
@@ -0,0 +1,83 @@
+** Begin
+
+** Others
+center: 0 40 0 extents: 38 32 2
+center: 0 -40 0 extents: 38 32 2
+center: -46 0 0 extents: 38 32 2
+center: -46 40 0 extents: 20 20 20
+center: -46 -40 0 extents: 20 20 20
+
+** Pavilion
+center: 0 0 0 extents: 38 32 2
+center: 0 0 2.0 extents: 1 1 1
+center: 0 0 1.25 extents: 2 2 0.5
+center: 7 3 2 extents: 2 2 2
+center: 7 -3 2 extents: 2 2 2
+
+** Top Building
+center: -1 9 1 extents: 8 8 2
+center: -1 9 1 extents: 6 6 3
+center: -1 9 1 extents: 5 5 4
+center: -1 9 1 extents: 4 4 5
+center: -1 9 1 extents: 3 3 6
+center: -1 9 1 extents: 2 2 16
+center: -1 9 1 extents: 1 1 17
+
+
+** Bottom Building
+center: -1 -9 1 extents: 8 8 2
+center: -1 -9 4 extents: 4 4 4
+center: -1 -9 7 extents: 6 6 2
+
+** Main Building
+center: -12 0 1 extents: 8 8 2
+** Base Corners
+center: -14 2 3 extents: 2 2 2
+center: -14 -2 3 extents: 2 2 2
+center: -10 2 3 extents: 2 2 2
+center: -10 -2 3 extents: 2 2 2
+** Large Block
+center: -12 0 5 extents: 4 4 4
+** Tucked In
+center: -12 2 7 extents: 2 2 2
+center: -12 -2 7 extents: 2 2 2
+center: -14 0 7 extents: 2 2 2
+center: -10 0 7 extents: 2 2 2
+** Stack one
+center: -13 -1 9 extents: 2 2 2
+center: -11 1 9 extents: 2 2 2
+** Stack one
+center: -13 1 11 extents: 2 2 2
+center: -11 -1 11 extents: 2 2 2
+** Top
+center: -12 0 12.5 extents: 2 2 1
+center: -12 0 13.5 extents: 1 1 1
+
+** Bottom Left
+center: -12 -9 1 extents: 8 8 2
+** Right base
+center: -9.5 -10.5 2.5 extents: 3 5 1
+center: -10 -10 6 extents: 2 4 6
+center: -8.75 -9 6 extents: 0.5 1 5
+center: -8.75 -11 6 extents: 0.5 1 5
+** Left Base
+center: -14.5 -10.5 2.5 extents: 3 5 1
+center: -14 -10 6 extents: 2 4 6
+** Top
+center: -12 -9.5 10 extents: 4 5 2
+** Flourish
+center: -12 -6.5 10 extents: 4 1 1
+
+** Top Left
+center: -12 9 1 extents: 8 8 2
+** left tower
+center: -12 11.5 4.5 extents: 6 3 5
+center: -12 11 10 extents: 6 2 6
+** right tower
+center: -12.5 7 10.5 extents: 5 2 9
+center: -12.5 5 11.5 extents: 2 2 5
+center: -13.5 7 4 extents: 3 2 4
+** bridges
+center: -13.5 9 5 extents: 1 2 2
+center: -10.5 9 7 extents: 1 2 2
+center: -13.5 9 9 extents: 1 2 2
\ No newline at end of file
diff --git a/part3/565GLFrame/565GLFrame/freeglut.dll b/part3/565GLFrame/565GLFrame/freeglut.dll
new file mode 100644
index 0000000..4ec8893
Binary files /dev/null and b/part3/565GLFrame/565GLFrame/freeglut.dll differ
diff --git a/part3/565GLFrame/565GLFrame/glew32.dll b/part3/565GLFrame/565GLFrame/glew32.dll
new file mode 100644
index 0000000..999a59b
Binary files /dev/null and b/part3/565GLFrame/565GLFrame/glew32.dll differ
diff --git a/part3/565GLFrame/565GLFrame/main.cpp b/part3/565GLFrame/565GLFrame/main.cpp
new file mode 100644
index 0000000..9466374
--- /dev/null
+++ b/part3/565GLFrame/565GLFrame/main.cpp
@@ -0,0 +1,982 @@
+#include "main.h"
+
+#include "Utility.h"
+#include "objloader.h"
+
+#include
+#include "SOIL.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+using namespace std;
+using namespace glm;
+
+const float PI = 3.14159f;
+
+int width, height;
+
+enum DisplayVertex displayVertex_type = DISPLAY_V_NORMAL;
+vec4 boneMatrix[9];
+
+vector draw_meshes;
+
+device_mesh_t uploadMesh(const mesh_t & mesh) {
+ device_mesh_t out;
+ //Allocate vertex array
+ //Vertex arrays encapsulate a set of generic vertex attributes and the buffers they are bound too
+ //Different vertex array per mesh.
+ glGenVertexArrays(1, &(out.vertex_array));
+ glBindVertexArray(out.vertex_array);
+
+ //Allocate vbos for data
+ glGenBuffers(1,&(out.vbo_vertices));
+ glGenBuffers(1,&(out.vbo_normals));
+ glGenBuffers(1,&(out.vbo_indices));
+
+ //Upload vertex data
+ glBindBuffer(GL_ARRAY_BUFFER, out.vbo_vertices);
+ glBufferData(GL_ARRAY_BUFFER, mesh.vertices.size()*sizeof(vec3), &mesh.vertices[0], GL_STATIC_DRAW);
+ glVertexAttribPointer(mesh_attributes::POSITION, 3, GL_FLOAT, GL_FALSE,0,0);
+ glEnableVertexAttribArray(mesh_attributes::POSITION);
+
+ //VBO for normal data
+ glBindBuffer(GL_ARRAY_BUFFER, out.vbo_normals);
+ glBufferData(GL_ARRAY_BUFFER, mesh.normals.size()*sizeof(vec3), &mesh.normals[0], GL_STATIC_DRAW);
+ glVertexAttribPointer(mesh_attributes::NORMAL, 3, GL_FLOAT, GL_FALSE,0,0);
+ glEnableVertexAttribArray(mesh_attributes::NORMAL);
+
+ //VBO for bone weights Index
+ glBindBuffer(GL_ARRAY_BUFFER, out.vbo_boneIndex);
+ glBufferData(GL_ARRAY_BUFFER, mesh.boneWeightIndex.size()*sizeof(vec2), &mesh.boneWeightIndex[0], GL_STATIC_DRAW);
+ glVertexAttribPointer(mesh_attributes::BONEINDEX, 2, GL_FLOAT, GL_FALSE,0,0);
+ glEnableVertexAttribArray(mesh_attributes::BONEINDEX);
+
+ //VBO for bone weights
+ glBindBuffer(GL_ARRAY_BUFFER, out.vbo_boneWeights);
+ glBufferData(GL_ARRAY_BUFFER, mesh.boneWeights.size()*sizeof(vec2), &mesh.boneWeights[0], GL_STATIC_DRAW);
+ glVertexAttribPointer(mesh_attributes::BONEWEIGHT, 2, GL_FLOAT, GL_FALSE,0,0);
+ glEnableVertexAttribArray(mesh_attributes::BONEWEIGHT);
+
+ //indices
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, out.vbo_indices);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh.indices.size()*sizeof(GLushort), &mesh.indices[0], GL_STATIC_DRAW);
+ out.num_indices = mesh.indices.size();
+ //Unplug Vertex Array
+ glBindVertexArray(0);
+ return out;
+}
+
+
+int num_boxes = 3;
+const int DUMP_SIZE = 1024;
+
+void initMesh() {
+ int totalsize = objmesh->getFaces()->size();
+ int f = 0;
+
+ /*vector bonePos;
+ bonePos.push_back(vec3(-1.0, 0.5, 0));
+ boneMatrix[0] = vec4(cos(5*PI/180.0),-sin(5*PI/180.0),0,0);
+ boneMatrix[1] = vec4(sin(5*PI/180.0),cos(5*PI/180.0),0,0);
+ boneMatrix[2] = vec4(0,0,1,0);
+
+ bonePos.push_back(vec3(-0.25, 0.5, 0));
+ boneMatrix[3] = vec4(cos(10*PI/180.0),-sin(10*PI/180.0),0,0);
+ boneMatrix[4] = vec4(sin(10*PI/180.0),cos(10*PI/180.0),0,0);
+ boneMatrix[5] = vec4(0,0,1,0);
+
+ bonePos.push_back(vec3(0, 0.5, 0));
+ boneMatrix[9] = vec4(1,0,0,0);
+ boneMatrix[10] = vec4(0,1,0,0);
+ boneMatrix[11] = vec4(0,0,1,0);
+
+ bonePos.push_back(vec3(0.25, 0.5, 0));
+ boneMatrix[6] = vec4(1,0,0,0);
+ boneMatrix[7] = vec4(0,1,0,0);
+ boneMatrix[8] = vec4(0,0,1,0);
+
+ bonePos.push_back(vec3(1.0, 0.5, 0));
+ boneMatrix[12] = vec4(1,0,0,0);
+ boneMatrix[13] = vec4(0,1,0,0);
+ boneMatrix[14] = vec4(0,0,1,0);*/
+
+ vector bonePos;
+ bonePos.push_back(vec3(0, -0.25, 0));
+ boneMatrix[0] = vec4(1,0,0,0);
+ boneMatrix[1] = vec4(0,cos(5*PI/180.0),-sin(5*PI/180.0),0);
+ boneMatrix[2] = vec4(0,sin(5*PI/180.0),cos(5*PI/180.0),0);
+
+ bonePos.push_back(vec3(0, 0, 0));
+ boneMatrix[3] = vec4(cos(10*PI/180.0),-sin(10*PI/180.0),0,0);
+ boneMatrix[4] = vec4(sin(10*PI/180.0),cos(10*PI/180.0),0,0);
+ boneMatrix[5] = vec4(0,0,1,0);
+
+ bonePos.push_back(vec3(0, 0.25, 0));
+ boneMatrix[6] = vec4(1,0,0,0);
+ boneMatrix[7] = vec4(0,1,0,0);
+ boneMatrix[8] = vec4(0,0,1,0);
+
+
+ while(f face = objmesh->getFaces()->operator[](i);
+ //vector facenormal = objmesh->getFaceNormals()->operator[](i);
+
+ mesh.vertices.push_back(glm::vec3(objmesh->getPoints()->operator[](face[0])));
+ mesh.vertices.push_back(glm::vec3(objmesh->getPoints()->operator[](face[1])));
+ mesh.vertices.push_back(glm::vec3(objmesh->getPoints()->operator[](face[2])));
+
+ mesh.boneWeights.push_back(glm::vec2(0,0));
+ mesh.boneWeights.push_back(glm::vec2(0,0));
+ mesh.boneWeights.push_back(glm::vec2(0,0));
+
+ mesh.boneWeightIndex.push_back(glm::vec2(-1,-1));
+ mesh.boneWeightIndex.push_back(glm::vec2(-1,-1));
+ mesh.boneWeightIndex.push_back(glm::vec2(-1,-1));
+
+ int vertSize = mesh.vertices.size();
+ float minValue = 100.0;
+ float secondMin = minValue;
+ int weightIndex = 0;
+ for (int vertIndex = vertSize-1; vertIndex >= vertSize - 3; --vertIndex)
+ {
+ for (int boneIndex = 0; boneIndex < bonePos.size(); ++boneIndex)
+ {
+ if (mesh.vertices[vertIndex].y == bonePos[boneIndex].y)
+ {
+ mesh.boneWeightIndex[vertIndex].x = boneIndex;
+ mesh.boneWeights[vertIndex].x = 1.0;
+ break;
+ }
+ else if (mesh.vertices[vertIndex].y < bonePos[boneIndex].y)
+ {
+ if (boneIndex == 0)
+ {
+ mesh.boneWeightIndex[vertIndex].x = boneIndex;
+ mesh.boneWeights[vertIndex].x = 1.0;
+ //mesh.vertices[vertIndex] = vec3(0);
+ break;
+ }
+ else
+ {
+ mesh.boneWeights[vertIndex].x = abs(bonePos[boneIndex].y - mesh.vertices[vertIndex].y);
+ mesh.boneWeights[vertIndex].y = abs(bonePos[boneIndex-1].y - mesh.vertices[vertIndex].y);
+ float tot = mesh.boneWeights[vertIndex].x + mesh.boneWeights[vertIndex].y;
+
+ // Bring the values to between 0 and 1
+ mesh.boneWeights[vertIndex].x /= tot;
+ mesh.boneWeights[vertIndex].y /= tot;
+
+ mesh.boneWeightIndex[vertIndex].x = boneIndex;
+ mesh.boneWeightIndex[vertIndex].y = boneIndex-1;
+ break;
+ }
+ }
+ else if((boneIndex == bonePos.size() - 1) && mesh.vertices[vertIndex].y > bonePos[boneIndex].y)
+ {
+ mesh.boneWeightIndex[vertIndex].x = boneIndex;
+ mesh.boneWeights[vertIndex].x = 1.0;
+ //mesh.vertices[vertIndex] = vec3(0);
+ break;
+ }
+ }
+ }
+
+ /*mesh.normals.push_back(glm::vec3(objmesh->getNormals()->operator[](facenormal[0])));
+ mesh.normals.push_back(glm::vec3(objmesh->getNormals()->operator[](facenormal[1])));
+ mesh.normals.push_back(glm::vec3(objmesh->getNormals()->operator[](facenormal[2])));*/
+
+ mesh.normals.push_back(glm::vec3(objmesh->getSmoothNormals()->operator[](face[0])));
+ mesh.normals.push_back(glm::vec3(objmesh->getSmoothNormals()->operator[](face[1])));
+ mesh.normals.push_back(glm::vec3(objmesh->getSmoothNormals()->operator[](face[2])));
+
+ mesh.indices.push_back(points);
+ mesh.indices.push_back(points+1);
+ mesh.indices.push_back(points+2);
+ points = points + 3;
+ }
+ draw_meshes.push_back(uploadMesh(mesh));
+
+ // Temp - To find Max
+ // TODO - Please Remove
+ vec3 max = mesh.vertices[0];
+ vec3 min = max;
+ for (unsigned int i = 0; i mesh.vertices[i].x) min.x = mesh.vertices[i].x;
+ if (min.y > mesh.vertices[i].y) min.y = mesh.vertices[i].y;
+ if (min.z > mesh.vertices[i].z) min.z = mesh.vertices[i].z;
+ }
+
+ std::cout<<"Max: " << max.x << ", " << max.y << ", " << max.z << std::endl;
+ std::cout<<"Min: " << min.x << ", " << min.y << ", " << min.z << std::endl;
+
+ f=f+process;
+ }
+}
+
+
+device_mesh2_t device_quad;
+void initQuad() {
+ vertex2_t verts [] = { {vec3(-1,1,0),vec2(0,1)},
+ {vec3(-1,-1,0),vec2(0,0)},
+ {vec3(1,-1,0),vec2(1,0)},
+ {vec3(1,1,0),vec2(1,1)}};
+
+ unsigned short indices[] = { 0,1,2,0,2,3};
+
+ //Allocate vertex array
+ //Vertex arrays encapsulate a set of generic vertex attributes and the buffers they are bound too
+ //Different vertex array per mesh.
+ glGenVertexArrays(1, &(device_quad.vertex_array));
+ glBindVertexArray(device_quad.vertex_array);
+
+
+ //Allocate vbos for data
+ glGenBuffers(1,&(device_quad.vbo_data));
+ glGenBuffers(1,&(device_quad.vbo_indices));
+
+ //Upload vertex data
+ glBindBuffer(GL_ARRAY_BUFFER, device_quad.vbo_data);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
+ //Use of strided data, Array of Structures instead of Structures of Arrays
+ glVertexAttribPointer(quad_attributes::POSITION, 3, GL_FLOAT, GL_FALSE,sizeof(vertex2_t),0);
+ glVertexAttribPointer(quad_attributes::TEXCOORD, 2, GL_FLOAT, GL_FALSE,sizeof(vertex2_t),(void*)sizeof(vec3));
+ glEnableVertexAttribArray(quad_attributes::POSITION);
+ glEnableVertexAttribArray(quad_attributes::TEXCOORD);
+
+ //indices
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, device_quad.vbo_indices);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6*sizeof(GLushort), indices, GL_STATIC_DRAW);
+ device_quad.num_indices = 6;
+ //Unplug Vertex Array
+ glBindVertexArray(0);
+}
+
+
+GLuint depthTexture = 0;
+GLuint normalTexture = 0;
+GLuint positionTexture = 0;
+GLuint FBO = 0;
+
+GLuint ssaoTexture = 0;
+
+GLuint pass_prog;
+void initPass() {
+ Utility::shaders_t shaders = Utility::loadShaders("pass.vert", "pass.frag");
+
+ pass_prog = glCreateProgram();
+
+ glBindAttribLocation(pass_prog,mesh_attributes::POSITION, "Position");
+ glBindAttribLocation(pass_prog,mesh_attributes::NORMAL, "Normal");
+
+ Utility::attachAndLinkProgram(pass_prog,shaders);
+
+}
+
+GLuint pulse_prog;
+void initPulse() {
+ Utility::shaders_t shaders = Utility::loadShaders("pulse.vert", "pulse.frag");
+
+ pulse_prog = glCreateProgram();
+
+ glBindAttribLocation(pulse_prog,mesh_attributes::POSITION, "Position");
+ glBindAttribLocation(pulse_prog,mesh_attributes::NORMAL, "Normal");
+
+ Utility::attachAndLinkProgram(pulse_prog,shaders);
+
+}
+
+GLuint skin_prog;
+void initSkining() {
+ Utility::shaders_t shaders = Utility::loadShaders("skining.vert", "skining.frag");
+
+ skin_prog = glCreateProgram();
+
+ glBindAttribLocation(skin_prog, mesh_attributes::POSITION, "Position");
+ glBindAttribLocation(skin_prog, mesh_attributes::NORMAL, "Normal");
+ glBindAttribLocation(skin_prog, mesh_attributes::BONEWEIGHT, "BoneWeight");
+ glBindAttribLocation(skin_prog, mesh_attributes::BONEINDEX, "BoneIndex");
+
+ Utility::attachAndLinkProgram(skin_prog,shaders);
+
+}
+
+GLuint morph_prog;
+void initMorph() {
+ Utility::shaders_t shaders = Utility::loadShaders("morph.vert", "morph.frag");
+
+ morph_prog = glCreateProgram();
+
+ glBindAttribLocation(morph_prog,mesh_attributes::POSITION, "Position");
+ glBindAttribLocation(morph_prog,mesh_attributes::NORMAL, "Normal");
+
+ Utility::attachAndLinkProgram(morph_prog,shaders);
+
+}
+
+GLuint ssao_prog;
+void initSSAO() {
+ Utility::shaders_t shaders = Utility::loadShaders("ssao.vert", "ssao.frag");
+
+ ssao_prog = glCreateProgram();
+
+ glBindAttribLocation(ssao_prog, quad_attributes::POSITION, "Position");
+ glBindAttribLocation(ssao_prog, quad_attributes::TEXCOORD, "Texcoord");
+
+ Utility::attachAndLinkProgram(ssao_prog, shaders);
+}
+
+GLuint blur_prog;
+void initBlur() {
+ Utility::shaders_t shaders = Utility::loadShaders("blur.vert", "blur.frag");
+
+ blur_prog = glCreateProgram();
+
+ glBindAttribLocation(blur_prog, 0, "Position");
+ glBindAttribLocation(blur_prog, 1, "Texcoord");
+
+ Utility::attachAndLinkProgram(blur_prog, shaders);
+}
+
+void freeFBO() {
+ glDeleteTextures(1,&depthTexture);
+ glDeleteTextures(1,&normalTexture);
+ glDeleteTextures(1,&positionTexture);
+ glDeleteFramebuffers(1,&FBO);
+}
+
+void checkFramebufferStatus(GLenum framebufferStatus) {
+ switch (framebufferStatus) {
+ case GL_FRAMEBUFFER_COMPLETE_EXT: break;
+ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
+ printf("Attachment Point Unconnected");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
+ printf("Missing Attachment");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
+ printf("Dimensions do not match");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
+ printf("Formats");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
+ printf("Draw Buffer");
+ break;
+ case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
+ printf("Read Buffer");
+ break;
+ case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
+ printf("Unsupported Framebuffer Configuration");
+ break;
+ default:
+ printf("Unkown Framebuffer Object Failure");
+ break;
+ }
+}
+
+
+GLuint random_normal_tex;
+GLuint random_scalar_tex;
+void initNoise() {
+ random_normal_tex = (unsigned int)SOIL_load_OGL_texture("random_normal.png",0,0,0);
+ glBindTexture(GL_TEXTURE_2D, random_normal_tex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glBindTexture(GL_TEXTURE_2D, 0);
+
+ random_scalar_tex = (unsigned int)SOIL_load_OGL_texture("random.png",0,0,0);
+ glBindTexture(GL_TEXTURE_2D, random_scalar_tex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glBindTexture(GL_TEXTURE_2D, 0);
+}
+
+void initFBO(int w, int h) {
+ GLenum FBOstatus;
+
+ glActiveTexture(GL_TEXTURE0);
+
+ glGenTextures(1, &depthTexture);
+ glGenTextures(1, &normalTexture);
+ glGenTextures(1, &positionTexture);
+ glBindTexture(GL_TEXTURE_2D, depthTexture);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+ glTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_INTENSITY);
+
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, w, h, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
+
+ glBindTexture(GL_TEXTURE_2D, normalTexture);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB32F , w, h, 0, GL_RGBA, GL_FLOAT,0);
+
+ glBindTexture(GL_TEXTURE_2D, positionTexture);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
+
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB32F , w, h, 0, GL_RGBA, GL_FLOAT,0);
+
+ // creatwwe a framebuffer object
+ glGenFramebuffers(1, &FBO);
+ glBindFramebuffer(GL_FRAMEBUFFER, FBO);
+
+ // Instruct openGL that we won't bind a color texture with the currently binded FBO
+ glReadBuffer(GL_NONE);
+
+ GLuint curr_prog = pass_prog;
+ switch(displayVertex_type)
+ {
+ case DISPLAY_V_PULSE:
+ curr_prog = pulse_prog;
+ break;
+ case DISPLAY_V_SKINING:
+ curr_prog = skin_prog;
+ break;
+ case DISPLAY_V_MORPH:
+ curr_prog = morph_prog;
+ break;
+ }
+ GLint normal_loc = glGetFragDataLocation(curr_prog,"out_Normal");
+ GLint position_loc = glGetFragDataLocation(curr_prog,"out_Position");
+ GLenum draws [2];
+ draws[normal_loc] = GL_COLOR_ATTACHMENT0;
+ draws[position_loc] = GL_COLOR_ATTACHMENT1;
+ glDrawBuffers(2, draws);
+
+ // attach the texture to FBO depth attachment point
+ int test = GL_COLOR_ATTACHMENT0;
+ glBindTexture(GL_TEXTURE_2D, depthTexture);
+ glFramebufferTexture(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTexture, 0);
+ glBindTexture(GL_TEXTURE_2D, normalTexture);
+ glFramebufferTexture(GL_FRAMEBUFFER, draws[normal_loc], normalTexture, 0);
+ glBindTexture(GL_TEXTURE_2D, positionTexture);
+ glFramebufferTexture(GL_FRAMEBUFFER, draws[position_loc], positionTexture, 0);
+
+ // check FBO status
+ FBOstatus = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+ if(FBOstatus != GL_FRAMEBUFFER_COMPLETE) {
+ printf("GL_FRAMEBUFFER_COMPLETE failed, CANNOT use FBO\n");
+ checkFramebufferStatus(FBOstatus);
+ }
+
+
+ // switch back to window-system-provided framebuffer
+ glClear(GL_DEPTH_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+}
+
+void bindFBO() {
+ glDisable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D,0); //Bad mojo to unbind the framebuffer using the texture
+ glBindFramebuffer(GL_FRAMEBUFFER, FBO);
+ glClear(GL_DEPTH_BUFFER_BIT);
+ //glColorMask(false,false,false,false);
+ glEnable(GL_DEPTH_TEST);
+}
+
+void setTextures() {
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D,0);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
+
+ //glColorMask(true,true,true,true);
+ glDisable(GL_DEPTH_TEST);
+ glClear(GL_COLOR_BUFFER_BIT);
+}
+
+
+// Dragon
+//Camera cam(vec3(27,0,-3),
+// normalize(vec3(-1,0,0)),
+// normalize(vec3(0,0,1)));
+
+Camera cam(vec3(20,4,4),
+ normalize(vec3(-1,0,0)),
+ normalize(vec3(0,0,1)));
+
+void
+Camera::adjust(float dx, // look left right
+ float dy, //look up down
+ float dz,
+ float tx, //strafe left right
+ float ty,
+ float tz)//go forward) //strafe up down
+{
+
+ if (abs(dx) > 0) {
+ rx += dx;
+ rx = fmod(rx,360.0f);
+ }
+
+ if (abs(dy) > 0) {
+ ry += dy;
+ ry = clamp(ry,-70.0f, 70.0f);
+ }
+
+ if (abs(tx) > 0) {
+ vec3 dir = glm::gtx::rotate_vector::rotate(start_dir,rx + 90,up);
+ vec2 dir2(dir.x,dir.y);
+ vec2 mag = dir2 * tx;
+ pos += mag;
+ }
+
+ if (abs(ty) > 0) {
+ z += ty;
+ }
+
+ if (abs(tz) > 0) {
+ vec3 dir = glm::gtx::rotate_vector::rotate(start_dir,rx,up);
+ vec2 dir2(dir.x,dir.y);
+ vec2 mag = dir2 * tz;
+ pos += mag;
+ }
+}
+
+mat4x4 Camera::get_view() {
+ vec3 inclin = glm::gtx::rotate_vector::rotate(start_dir,ry,start_left);
+ vec3 spun = glm::gtx::rotate_vector::rotate(inclin,rx,up);
+ vec3 cent(pos, z);
+ return lookAt(cent, cent + spun, up);
+}
+
+mat4x4 get_mesh_world() {
+ vec3 tilt(1.0f,0.0f,0.0f);
+ mat4 translate_mat = glm::translate(glm::vec3(0.0f,.8f,0.0f));
+ mat4 tilt_mat = glm::rotate(mat4(), 0.0f, tilt);
+ mat4 scale_mat = glm::scale(glm::vec3(8,8,8));
+ /*mat4 translate_mat = glm::translate(glm::vec3(0.0f,.5f,0.0f));
+ mat4 tilt_mat = glm::rotate(mat4(), 90.0f, tilt);
+ mat4 scale_mat = glm::scale(glm::vec3(1,1,1));*/
+ return scale_mat*tilt_mat * translate_mat;
+}
+
+
+float FARP;
+float NEARP;
+float timeVal;
+void draw_mesh_common(GLuint& currProg, float timeValue) {
+ FARP = 100.0f;
+ NEARP = 1.0f;
+
+ glUseProgram(currProg);
+
+
+ mat4 model = get_mesh_world();
+ mat4 view = cam.get_view();
+ mat4 persp = perspective(45.0f,(float)width/(float)height,NEARP,FARP);
+ mat4 inverse_transposed = transpose(inverse(view*model));
+
+ glUniform1f(glGetUniformLocation(currProg, "u_Far"), FARP);
+ glUniformMatrix4fv(glGetUniformLocation(currProg,"u_Model"),1,GL_FALSE,&model[0][0]);
+ glUniformMatrix4fv(glGetUniformLocation(currProg,"u_View"),1,GL_FALSE,&view[0][0]);
+ glUniformMatrix4fv(glGetUniformLocation(currProg,"u_Persp"),1,GL_FALSE,&persp[0][0]);
+ glUniformMatrix4fv(glGetUniformLocation(currProg,"u_InvTrans") ,1,GL_FALSE,&inverse_transposed[0][0]);
+ glUniform1f(glGetUniformLocation(currProg, "u_Time"), timeValue);
+ glUniform4fv(glGetUniformLocation(currProg,"u_BoneMatrix"),9, &boneMatrix[0][0]);
+
+ for(int i=0; i 0.001/* && timeVal < 600*/)
+ timeVal += 0.5;
+ else
+ timeVal = 0;
+
+ draw_mesh_common(pulse_prog, timeVal);
+}
+
+void draw_skining() {
+ draw_mesh_common(skin_prog, 0);
+}
+
+void draw_morph() {
+ draw_mesh_common(skin_prog, 0);
+}
+
+enum Display display_type = DISPLAY_TOTAL;
+enum Occlusion occlusion_type = OCCLUSION_NONE;
+void draw_quad() {
+ glUseProgram(ssao_prog);
+
+ glBindVertexArray(device_quad.vertex_array);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, device_quad.vbo_indices);
+
+ glEnable(GL_TEXTURE_2D);
+
+ mat4 persp = perspective(45.0f,1.0f,NEARP,FARP);
+ vec4 test(-2,0,10,1);
+ vec4 testp = persp * test;
+ vec4 testh = testp / testp.w;
+ vec2 coords = vec2(testh.x, testh.y) / 2.0f + 0.5f;
+ glUniform1i(glGetUniformLocation(ssao_prog, "u_ScreenHeight"), height);
+ glUniform1i(glGetUniformLocation(ssao_prog, "u_ScreenWidth"), width);
+ glUniform1f(glGetUniformLocation(ssao_prog, "u_Far"), FARP);
+ glUniform1f(glGetUniformLocation(ssao_prog, "u_Near"), NEARP);
+ glUniform1i(glGetUniformLocation(ssao_prog, "u_OcclusionType"), occlusion_type);
+ glUniform1i(glGetUniformLocation(ssao_prog, "u_DisplayType"), display_type);
+ glUniformMatrix4fv(glGetUniformLocation(ssao_prog, "u_Persp"),1, GL_FALSE, &persp[0][0] );
+
+ glActiveTexture(GL_TEXTURE0);
+ glBindTexture(GL_TEXTURE_2D, depthTexture);
+ glUniform1i(glGetUniformLocation(ssao_prog, "u_Depthtex"),0);
+ glActiveTexture(GL_TEXTURE1);
+ glBindTexture(GL_TEXTURE_2D, normalTexture);
+ glUniform1i(glGetUniformLocation(ssao_prog, "u_Normaltex"),1);
+ glActiveTexture(GL_TEXTURE2);
+ glBindTexture(GL_TEXTURE_2D, positionTexture);
+ glUniform1i(glGetUniformLocation(ssao_prog, "u_Positiontex"),2);
+ glActiveTexture(GL_TEXTURE3);
+ glBindTexture(GL_TEXTURE_2D, random_normal_tex);
+ glUniform1i(glGetUniformLocation(ssao_prog, "u_RandomNormaltex"),3);
+ glActiveTexture(GL_TEXTURE4);
+ glBindTexture(GL_TEXTURE_2D, random_scalar_tex);
+ glUniform1i(glGetUniformLocation(ssao_prog, "u_RandomScalartex"),4);
+
+ glDrawElements(GL_TRIANGLES, device_quad.num_indices, GL_UNSIGNED_SHORT,0);
+
+ glBindVertexArray(0);
+}
+
+void updateDisplayText(char * disp) {
+ switch(display_type) {
+ case(DISPLAY_DEPTH):
+ sprintf(disp, "Displaying Depth");
+ break;
+ case(DISPLAY_NORMAL):
+ sprintf(disp, "Displaying Normal");
+ break;
+ case(DISPLAY_POSITION):
+ sprintf(disp, "Displaying Position");
+ break;
+ case(DISPLAY_OCCLUSION):
+ sprintf(disp, "Displaying Occlusion");
+ break;
+ case(DISPLAY_TOTAL):
+ sprintf(disp, "Displaying Diffuse+Occlusion");
+ break;
+ }
+}
+
+void updateOcclusionText(char * disp) {
+ switch(occlusion_type) {
+ case(OCCLUSION_NONE):
+ sprintf(disp, "with No Occlusion");
+ break;
+ case(OCCLUSION_REGULAR_SAMPLES):
+ sprintf(disp, "with Regular Grid Occlusion");
+ break;
+ case(OCCLUSION_POISSON_SS_SAMPLES):
+ sprintf(disp, "with Poisson Disk SS Occlusion");
+ break;
+ case(OCCLUSION_WORLD_SPACE_SAMPLES):
+ sprintf(disp, "with World Space Occlusion");
+ break;
+ }
+}
+
+
+
+int frame = 0;
+int currenttime = 0;
+int timebase = 0;
+char title[1024];
+char disp[1024];
+char occl[1024];
+void updateTitle() {
+ updateDisplayText(disp);
+ updateOcclusionText(occl);
+//calculate the frames per second
+ frame++;
+
+ //get the current time
+ currenttime = glutGet(GLUT_ELAPSED_TIME);
+
+ //check if a second has passed
+ if (currenttime - timebase > 1000)
+ {
+
+ sprintf(title, "CIS565 OpenGL Frame | %s %s FPS: %4.2f", disp, occl,frame*1000.0/(currenttime-timebase));
+ //sprintf(title, "CIS565 OpenGL Frame | %4.2f FPS", frame*1000.0/(currenttime-timebase));
+ glutSetWindowTitle(title);
+ timebase = currenttime;
+ frame = 0;
+ }
+}
+
+void display(void)
+{
+ // clear the screen
+ bindFBO();
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ switch (displayVertex_type)
+ {
+ case DISPLAY_V_PULSE:
+ draw_pulsing();
+ break;
+ case DISPLAY_V_SKINING:
+ draw_skining();
+ break;
+ case DISPLAY_V_MORPH:
+ draw_morph();
+ break;
+ default:
+ draw_mesh();
+ }
+
+ setTextures();
+ draw_quad();
+
+ updateTitle();
+
+ glutPostRedisplay();
+ glutSwapBuffers();
+}
+
+
+
+void reshape(int w, int h)
+{
+ width = w;
+ height = h;
+ glBindFramebuffer(GL_FRAMEBUFFER,0);
+ glViewport(0,0,(GLsizei)w,(GLsizei)h);
+ if (FBO != 0 || depthTexture != 0 || normalTexture != 0 ) {
+ freeFBO();
+ }
+ initFBO(w,h);
+}
+
+
+int mouse_buttons = 0;
+int mouse_old_x = 0;
+int mouse_old_y = 0;
+void mouse(int button, int state, int x, int y)
+{
+ if (state == GLUT_DOWN) {
+ mouse_buttons |= 1<