Finished A4
This commit is contained in:
parent
97066ef640
commit
d7c568f3e2
106 changed files with 58242 additions and 0 deletions
1
A4/.gitignore
vendored
Normal file
1
A4/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
build/
|
127
A4/CMakeLists.txt
Normal file
127
A4/CMakeLists.txt
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||||
|
|
||||||
|
# Name of the project
|
||||||
|
PROJECT(A4)
|
||||||
|
|
||||||
|
# FOR LAB MACHINES ONLY!
|
||||||
|
# DO NOT EDIT
|
||||||
|
SET(DEF_DIR_GLM "C:\\c++\\glm")
|
||||||
|
SET(DEF_DIR_GLFW "C:\\c++\\glfw-3.2.1")
|
||||||
|
SET(DEF_DIR_GLEW "C:\\c++\\glew-2.0.0")
|
||||||
|
|
||||||
|
# Is this the solution?
|
||||||
|
# Override with `cmake -DSOL=ON ..`
|
||||||
|
OPTION(SOL "Solution" OFF)
|
||||||
|
|
||||||
|
# Use glob to get the list of all source files.
|
||||||
|
# We don't really need to include header and resource files to build, but it's
|
||||||
|
# nice to have them also show up in IDEs.
|
||||||
|
IF(${SOL})
|
||||||
|
FILE(GLOB_RECURSE SOURCES "src0/*.cpp")
|
||||||
|
FILE(GLOB_RECURSE HEADERS "src0/*.h")
|
||||||
|
FILE(GLOB_RECURSE GLSL "resources0/*.glsl")
|
||||||
|
ELSE()
|
||||||
|
FILE(GLOB_RECURSE SOURCES "src/*.cpp")
|
||||||
|
FILE(GLOB_RECURSE HEADERS "src/*.h")
|
||||||
|
FILE(GLOB_RECURSE GLSL "resources/*.glsl")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# Set the executable.
|
||||||
|
ADD_EXECUTABLE(${CMAKE_PROJECT_NAME} ${SOURCES} ${HEADERS} ${GLSL})
|
||||||
|
|
||||||
|
# Get the GLM environment variable. Since GLM is a header-only library, we
|
||||||
|
# just need to add it to the include directory.
|
||||||
|
SET(GLM_INCLUDE_DIR "$ENV{GLM_INCLUDE_DIR}")
|
||||||
|
IF(NOT GLM_INCLUDE_DIR)
|
||||||
|
# The environment variable was not set
|
||||||
|
SET(ERR_MSG "Please point the environment variable GLM_INCLUDE_DIR to the root directory of your GLM installation.")
|
||||||
|
IF(WIN32)
|
||||||
|
# On Windows, try the default location
|
||||||
|
MESSAGE(STATUS "Looking for GLM in ${DEF_DIR_GLM}")
|
||||||
|
IF(IS_DIRECTORY ${DEF_DIR_GLM})
|
||||||
|
MESSAGE(STATUS "Found!")
|
||||||
|
SET(GLM_INCLUDE_DIR ${DEF_DIR_GLM})
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
INCLUDE_DIRECTORIES(${GLM_INCLUDE_DIR})
|
||||||
|
|
||||||
|
# Get the GLFW environment variable. There should be a CMakeLists.txt in the
|
||||||
|
# specified directory.
|
||||||
|
SET(GLFW_DIR "$ENV{GLFW_DIR}")
|
||||||
|
IF(NOT GLFW_DIR)
|
||||||
|
# The environment variable was not set
|
||||||
|
SET(ERR_MSG "Please point the environment variable GLFW_DIR to the root directory of your GLFW installation.")
|
||||||
|
IF(WIN32)
|
||||||
|
# On Windows, try the default location
|
||||||
|
MESSAGE(STATUS "Looking for GLFW in ${DEF_DIR_GLFW}")
|
||||||
|
IF(IS_DIRECTORY ${DEF_DIR_GLFW})
|
||||||
|
MESSAGE(STATUS "Found!")
|
||||||
|
SET(GLFW_DIR ${DEF_DIR_GLFW})
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
OPTION(GLFW_BUILD_EXAMPLES "GLFW_BUILD_EXAMPLES" OFF)
|
||||||
|
OPTION(GLFW_BUILD_TESTS "GLFW_BUILD_TESTS" OFF)
|
||||||
|
OPTION(GLFW_BUILD_DOCS "GLFW_BUILD_DOCS" OFF)
|
||||||
|
IF(CMAKE_BUILD_TYPE MATCHES Release)
|
||||||
|
ADD_SUBDIRECTORY(${GLFW_DIR} ${GLFW_DIR}/release)
|
||||||
|
ELSE()
|
||||||
|
ADD_SUBDIRECTORY(${GLFW_DIR} ${GLFW_DIR}/debug)
|
||||||
|
ENDIF()
|
||||||
|
INCLUDE_DIRECTORIES(${GLFW_DIR}/include)
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} glfw ${GLFW_LIBRARIES})
|
||||||
|
|
||||||
|
# Get the GLEW environment variable.
|
||||||
|
SET(GLEW_DIR "$ENV{GLEW_DIR}")
|
||||||
|
IF(NOT GLEW_DIR)
|
||||||
|
# The environment variable was not set
|
||||||
|
SET(ERR_MSG "Please point the environment variable GLEW_DIR to the root directory of your GLEW installation.")
|
||||||
|
IF(WIN32)
|
||||||
|
# On Windows, try the default location
|
||||||
|
MESSAGE(STATUS "Looking for GLEW in ${DEF_DIR_GLEW}")
|
||||||
|
IF(IS_DIRECTORY ${DEF_DIR_GLEW})
|
||||||
|
MESSAGE(STATUS "Found!")
|
||||||
|
SET(GLEW_DIR ${DEF_DIR_GLEW})
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
INCLUDE_DIRECTORIES(${GLEW_DIR}/include)
|
||||||
|
IF(WIN32)
|
||||||
|
# With prebuilt binaries
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} ${GLEW_DIR}/lib/Release/Win32/glew32s.lib)
|
||||||
|
ELSE()
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} ${GLEW_DIR}/lib/libGLEW.a)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# OS specific options and libraries
|
||||||
|
IF(WIN32)
|
||||||
|
# c++11 is enabled by default.
|
||||||
|
# -Wall produces way too many warnings.
|
||||||
|
# -pedantic is not supported.
|
||||||
|
# Disable warning 4996.
|
||||||
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4996")
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} opengl32.lib)
|
||||||
|
ELSE()
|
||||||
|
# Enable all pedantic warnings.
|
||||||
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -pedantic")
|
||||||
|
IF(APPLE)
|
||||||
|
# Add required frameworks for GLFW.
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} "-framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo")
|
||||||
|
ELSE()
|
||||||
|
#Link the Linux OpenGL library
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} "GL")
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
7
A4/README.txt
Normal file
7
A4/README.txt
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
Alexander Huddleston
|
||||||
|
|
||||||
|
I downloaded the code from the lab pages and worked from there.
|
||||||
|
|
||||||
|
I added a large flat cube as a "ground" but didn't texture it because I was tired of looking at a white abyss and thought this would make it look a little bit better.
|
||||||
|
|
||||||
|
I didn't notice you implemented a "toggle key" functionality in the main and instead coded if statements in the char callback to do what I wanted. The functionality remains the same, but I thought it was worth noting.
|
17
A4/resources/.frag.glsl
Normal file
17
A4/resources/.frag.glsl
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
uniform vec3 lightPos;
|
||||||
|
uniform vec3 ka;
|
||||||
|
uniform vec3 kd;
|
||||||
|
uniform vec3 ks;
|
||||||
|
uniform float s;
|
||||||
|
|
||||||
|
varying vec3 n; // passed from the vertex shader
|
||||||
|
varying vec3 p; // passed from the vertex shader
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
n = normalize(normal);
|
||||||
|
vec3 color = 0.5 * (n + 1.0);
|
||||||
|
gl_FragColor = vec4(color.r, color.g, color.b, 1.0);
|
||||||
|
}
|
17
A4/resources/.vert.glsl
Normal file
17
A4/resources/.vert.glsl
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
uniform mat4 P;
|
||||||
|
uniform mat4 MV;
|
||||||
|
|
||||||
|
attribute vec4 aPos; // in object space
|
||||||
|
attribute vec3 aNor; // in object space
|
||||||
|
|
||||||
|
varying vec3 p; // passed to fragment shader
|
||||||
|
varying vec3 n; // passed to fragment shader
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
ugl_Position = P * MV * aPos;
|
||||||
|
p = MV * aPos;
|
||||||
|
n = MV * aNor;
|
||||||
|
}
|
9977
A4/resources/bunny.obj
Normal file
9977
A4/resources/bunny.obj
Normal file
File diff suppressed because it is too large
Load diff
29
A4/resources/cube.obj
Normal file
29
A4/resources/cube.obj
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
# Blender v2.71 (sub 0) OBJ File: ''
|
||||||
|
# www.blender.org
|
||||||
|
v 0.500000 0.500000 -0.500000
|
||||||
|
v 0.500000 -0.500000 -0.500000
|
||||||
|
v -0.500000 -0.500000 -0.500000
|
||||||
|
v -0.500000 0.500000 -0.500000
|
||||||
|
v 0.500000 0.500000 0.500000
|
||||||
|
v 0.500000 -0.500000 0.500000
|
||||||
|
v -0.500000 -0.500000 0.500000
|
||||||
|
v -0.500000 0.500000 0.500000
|
||||||
|
vn 0.000000 0.000000 -1.000000
|
||||||
|
vn 0.000000 0.000000 1.000000
|
||||||
|
vn 1.000000 -0.000000 -0.000000
|
||||||
|
vn -0.000000 -1.000000 -0.000000
|
||||||
|
vn -1.000000 0.000000 -0.000000
|
||||||
|
vn 0.000000 1.000000 0.000000
|
||||||
|
s off
|
||||||
|
f 2//1 3//1 4//1
|
||||||
|
f 8//2 7//2 6//2
|
||||||
|
f 1//3 5//3 6//3
|
||||||
|
f 2//4 6//4 7//4
|
||||||
|
f 7//5 8//5 4//5
|
||||||
|
f 1//6 4//6 8//6
|
||||||
|
f 1//1 2//1 4//1
|
||||||
|
f 5//2 8//2 6//2
|
||||||
|
f 2//3 1//3 6//3
|
||||||
|
f 3//4 2//4 7//4
|
||||||
|
f 3//5 7//5 4//5
|
||||||
|
f 5//6 1//6 8//6
|
37
A4/resources/frag.glsl
Normal file
37
A4/resources/frag.glsl
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
uniform mat4 MVL;
|
||||||
|
uniform vec3 lightPos1;
|
||||||
|
uniform vec3 lightPos2;
|
||||||
|
uniform vec3 ka;
|
||||||
|
uniform vec3 kd;
|
||||||
|
uniform vec3 ks;
|
||||||
|
uniform float s;
|
||||||
|
uniform float i1;
|
||||||
|
uniform float i2;
|
||||||
|
|
||||||
|
varying vec3 color; // passed from the vertex shader
|
||||||
|
varying vec4 p;
|
||||||
|
varying vec4 n;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 normal = normalize(n);
|
||||||
|
vec3 norm = vec3(normal.x, normal.y, normal.z);
|
||||||
|
|
||||||
|
vec4 npos = normalize(p);
|
||||||
|
vec3 pos = vec3(npos.x, npos.y, npos.z);
|
||||||
|
|
||||||
|
vec3 lightnorm = vec3(MVL[3].x, MVL[3].y, MVL[3].z);
|
||||||
|
|
||||||
|
vec3 light = lightnorm - vec3(p.x, p.y, p.z);
|
||||||
|
vec3 lnorm = normalize(vec3(light.x,light.y,light.z));
|
||||||
|
float temp = dot(lnorm, norm);
|
||||||
|
vec3 cd = kd*max(0, temp);
|
||||||
|
|
||||||
|
vec3 h = normalize(lnorm - pos);
|
||||||
|
vec3 cs = ks*pow(max(0, dot(h, norm)), s);
|
||||||
|
|
||||||
|
vec4 c = vec4(ka.r + cd.r + cs.r, ka.g + cd.g + cs.g, ka.b + cd.b + cs.b, 1.0);
|
||||||
|
gl_FragColor = c;
|
||||||
|
}
|
20
A4/resources/sil.glsl
Normal file
20
A4/resources/sil.glsl
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
varying vec4 p;
|
||||||
|
varying vec4 n;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 normal = normalize(n);
|
||||||
|
vec3 norm = vec3(normal.x, normal.y, normal.z);
|
||||||
|
|
||||||
|
vec4 npos = normalize(p);
|
||||||
|
vec3 pos = vec3(npos.x, npos.y, npos.z);
|
||||||
|
|
||||||
|
float product = dot(norm, pos);
|
||||||
|
|
||||||
|
if(product <= 0.3 && product >= -0.3)
|
||||||
|
gl_FragColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
else
|
||||||
|
gl_FragColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
}
|
204
A4/resources/sphere.obj
Normal file
204
A4/resources/sphere.obj
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
####
|
||||||
|
#
|
||||||
|
# OBJ File Generated by LightWave3D
|
||||||
|
# LightWave3D OBJ Export v2.2
|
||||||
|
#
|
||||||
|
####
|
||||||
|
#
|
||||||
|
# Vertices: 62
|
||||||
|
# Points: 0
|
||||||
|
# Lines: 0
|
||||||
|
# Faces: 120
|
||||||
|
# Materials: 1
|
||||||
|
#
|
||||||
|
####
|
||||||
|
|
||||||
|
# Vertex list
|
||||||
|
|
||||||
|
v 0 -0.5 -0
|
||||||
|
v 0.25 -0.433013 -0
|
||||||
|
v 0.216506 -0.433013 -0.125
|
||||||
|
v 0.125 -0.433013 -0.216506
|
||||||
|
v 0 -0.433013 -0.25
|
||||||
|
v -0.125 -0.433013 -0.216506
|
||||||
|
v -0.216506 -0.433013 -0.125
|
||||||
|
v -0.25 -0.433013 -0
|
||||||
|
v -0.216506 -0.433013 0.125
|
||||||
|
v -0.125 -0.433013 0.216506
|
||||||
|
v 0 -0.433013 0.25
|
||||||
|
v 0.125 -0.433013 0.216506
|
||||||
|
v 0.216506 -0.433013 0.125
|
||||||
|
v 0.433013 -0.25 -0
|
||||||
|
v 0.375 -0.25 -0.216506
|
||||||
|
v 0.216506 -0.25 -0.375
|
||||||
|
v 0 -0.25 -0.433013
|
||||||
|
v -0.216506 -0.25 -0.375
|
||||||
|
v -0.375 -0.25 -0.216506
|
||||||
|
v -0.433013 -0.25 -0
|
||||||
|
v -0.375 -0.25 0.216506
|
||||||
|
v -0.216506 -0.25 0.375
|
||||||
|
v 0 -0.25 0.433013
|
||||||
|
v 0.216506 -0.25 0.375
|
||||||
|
v 0.375 -0.25 0.216506
|
||||||
|
v 0.5 2.55171e-12 -0
|
||||||
|
v 0.433013 2.55171e-12 -0.25
|
||||||
|
v 0.25 2.55171e-12 -0.433013
|
||||||
|
v 0 2.55171e-12 -0.5
|
||||||
|
v -0.25 2.55171e-12 -0.433013
|
||||||
|
v -0.433013 2.55171e-12 -0.25
|
||||||
|
v -0.5 2.55171e-12 -0
|
||||||
|
v -0.433013 2.55171e-12 0.25
|
||||||
|
v -0.25 2.55171e-12 0.433013
|
||||||
|
v 0 2.55171e-12 0.5
|
||||||
|
v 0.25 2.55171e-12 0.433013
|
||||||
|
v 0.433013 2.55171e-12 0.25
|
||||||
|
v 0.433013 0.25 -0
|
||||||
|
v 0.375 0.25 -0.216506
|
||||||
|
v 0.216506 0.25 -0.375
|
||||||
|
v 0 0.25 -0.433013
|
||||||
|
v -0.216506 0.25 -0.375
|
||||||
|
v -0.375 0.25 -0.216506
|
||||||
|
v -0.433013 0.25 -0
|
||||||
|
v -0.375 0.25 0.216506
|
||||||
|
v -0.216506 0.25 0.375
|
||||||
|
v 0 0.25 0.433013
|
||||||
|
v 0.216506 0.25 0.375
|
||||||
|
v 0.375 0.25 0.216506
|
||||||
|
v 0.25 0.433013 -0
|
||||||
|
v 0.216506 0.433013 -0.125
|
||||||
|
v 0.125 0.433013 -0.216506
|
||||||
|
v 0 0.433013 -0.25
|
||||||
|
v -0.125 0.433013 -0.216506
|
||||||
|
v -0.216506 0.433013 -0.125
|
||||||
|
v -0.25 0.433013 -0
|
||||||
|
v -0.216506 0.433013 0.125
|
||||||
|
v -0.125 0.433013 0.216506
|
||||||
|
v 0 0.433013 0.25
|
||||||
|
v 0.125 0.433013 0.216506
|
||||||
|
v 0.216506 0.433013 0.125
|
||||||
|
v 5.10341e-12 0.5 -0
|
||||||
|
|
||||||
|
# Face list
|
||||||
|
|
||||||
|
f 3 2 1
|
||||||
|
f 4 3 1
|
||||||
|
f 5 4 1
|
||||||
|
f 6 5 1
|
||||||
|
f 7 6 1
|
||||||
|
f 8 7 1
|
||||||
|
f 9 8 1
|
||||||
|
f 10 9 1
|
||||||
|
f 11 10 1
|
||||||
|
f 12 11 1
|
||||||
|
f 13 12 1
|
||||||
|
f 2 13 1
|
||||||
|
f 3 14 2
|
||||||
|
f 15 14 3
|
||||||
|
f 4 15 3
|
||||||
|
f 16 15 4
|
||||||
|
f 17 16 4
|
||||||
|
f 5 17 4
|
||||||
|
f 17 5 6
|
||||||
|
f 18 17 6
|
||||||
|
f 18 6 7
|
||||||
|
f 19 18 7
|
||||||
|
f 20 7 8
|
||||||
|
f 20 19 7
|
||||||
|
f 20 8 9
|
||||||
|
f 21 20 9
|
||||||
|
f 21 9 10
|
||||||
|
f 22 21 10
|
||||||
|
f 23 10 11
|
||||||
|
f 23 22 10
|
||||||
|
f 12 23 11
|
||||||
|
f 24 23 12
|
||||||
|
f 13 24 12
|
||||||
|
f 25 24 13
|
||||||
|
f 14 25 13
|
||||||
|
f 2 14 13
|
||||||
|
f 15 26 14
|
||||||
|
f 27 26 15
|
||||||
|
f 28 27 15
|
||||||
|
f 16 28 15
|
||||||
|
f 29 28 16
|
||||||
|
f 17 29 16
|
||||||
|
f 29 17 18
|
||||||
|
f 30 29 18
|
||||||
|
f 31 18 19
|
||||||
|
f 31 30 18
|
||||||
|
f 32 19 20
|
||||||
|
f 32 31 19
|
||||||
|
f 32 20 21
|
||||||
|
f 33 32 21
|
||||||
|
f 34 21 22
|
||||||
|
f 34 33 21
|
||||||
|
f 35 22 23
|
||||||
|
f 35 34 22
|
||||||
|
f 24 35 23
|
||||||
|
f 36 35 24
|
||||||
|
f 37 36 24
|
||||||
|
f 25 37 24
|
||||||
|
f 26 37 25
|
||||||
|
f 14 26 25
|
||||||
|
f 39 38 26
|
||||||
|
f 27 39 26
|
||||||
|
f 28 39 27
|
||||||
|
f 40 39 28
|
||||||
|
f 29 40 28
|
||||||
|
f 41 40 29
|
||||||
|
f 42 29 30
|
||||||
|
f 42 41 29
|
||||||
|
f 43 30 31
|
||||||
|
f 43 42 30
|
||||||
|
f 43 31 32
|
||||||
|
f 44 43 32
|
||||||
|
f 45 32 33
|
||||||
|
f 45 44 32
|
||||||
|
f 45 33 34
|
||||||
|
f 46 45 34
|
||||||
|
f 46 34 35
|
||||||
|
f 47 46 35
|
||||||
|
f 48 47 35
|
||||||
|
f 36 48 35
|
||||||
|
f 49 48 36
|
||||||
|
f 37 49 36
|
||||||
|
f 26 49 37
|
||||||
|
f 38 49 26
|
||||||
|
f 39 50 38
|
||||||
|
f 51 50 39
|
||||||
|
f 40 51 39
|
||||||
|
f 52 51 40
|
||||||
|
f 53 52 40
|
||||||
|
f 41 53 40
|
||||||
|
f 53 41 42
|
||||||
|
f 54 53 42
|
||||||
|
f 55 42 43
|
||||||
|
f 55 54 42
|
||||||
|
f 56 43 44
|
||||||
|
f 56 55 43
|
||||||
|
f 56 44 45
|
||||||
|
f 57 56 45
|
||||||
|
f 58 45 46
|
||||||
|
f 58 57 45
|
||||||
|
f 58 46 47
|
||||||
|
f 59 58 47
|
||||||
|
f 60 59 47
|
||||||
|
f 48 60 47
|
||||||
|
f 49 60 48
|
||||||
|
f 61 60 49
|
||||||
|
f 50 61 49
|
||||||
|
f 38 50 49
|
||||||
|
f 51 62 50
|
||||||
|
f 52 62 51
|
||||||
|
f 53 62 52
|
||||||
|
f 62 53 54
|
||||||
|
f 62 54 55
|
||||||
|
f 62 55 56
|
||||||
|
f 62 56 57
|
||||||
|
f 62 57 58
|
||||||
|
f 62 58 59
|
||||||
|
f 60 62 59
|
||||||
|
f 61 62 60
|
||||||
|
f 50 62 61
|
||||||
|
|
||||||
|
# End of file
|
5049
A4/resources/teapot.obj
Normal file
5049
A4/resources/teapot.obj
Normal file
File diff suppressed because it is too large
Load diff
24
A4/resources/vert.glsl
Normal file
24
A4/resources/vert.glsl
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
uniform mat4 P;
|
||||||
|
uniform mat4 MV;
|
||||||
|
uniform mat4 MVL;
|
||||||
|
uniform vec3 lightPos1;
|
||||||
|
uniform vec3 lightPos2;
|
||||||
|
uniform float i1;
|
||||||
|
uniform float i2;
|
||||||
|
|
||||||
|
attribute vec4 aPos; // in object space
|
||||||
|
attribute vec3 aNor; // in object space
|
||||||
|
|
||||||
|
varying vec3 color; // Pass to fragment shader
|
||||||
|
varying vec4 p;
|
||||||
|
varying vec4 n;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = P * MV * aPos;
|
||||||
|
p = MV * aPos;
|
||||||
|
n = MV * vec4(aNor, 0.0);
|
||||||
|
color = vec3(0.5, 0.5, 0.5);
|
||||||
|
}
|
BIN
A4/shadow8t4.zip
Normal file
BIN
A4/shadow8t4.zip
Normal file
Binary file not shown.
127
A4/shadow8t4/shadow8t4/CMakeLists.txt
Normal file
127
A4/shadow8t4/shadow8t4/CMakeLists.txt
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||||
|
|
||||||
|
# Name of the project
|
||||||
|
PROJECT(A4)
|
||||||
|
|
||||||
|
# FOR LAB MACHINES ONLY!
|
||||||
|
# DO NOT EDIT
|
||||||
|
SET(DEF_DIR_GLM "C:\\c++\\glm")
|
||||||
|
SET(DEF_DIR_GLFW "C:\\c++\\glfw-3.2.1")
|
||||||
|
SET(DEF_DIR_GLEW "C:\\c++\\glew-2.0.0")
|
||||||
|
|
||||||
|
# Is this the solution?
|
||||||
|
# Override with `cmake -DSOL=ON ..`
|
||||||
|
OPTION(SOL "Solution" OFF)
|
||||||
|
|
||||||
|
# Use glob to get the list of all source files.
|
||||||
|
# We don't really need to include header and resource files to build, but it's
|
||||||
|
# nice to have them also show up in IDEs.
|
||||||
|
IF(${SOL})
|
||||||
|
FILE(GLOB_RECURSE SOURCES "src0/*.cpp")
|
||||||
|
FILE(GLOB_RECURSE HEADERS "src0/*.h")
|
||||||
|
FILE(GLOB_RECURSE GLSL "resources0/*.glsl")
|
||||||
|
ELSE()
|
||||||
|
FILE(GLOB_RECURSE SOURCES "src/*.cpp")
|
||||||
|
FILE(GLOB_RECURSE HEADERS "src/*.h")
|
||||||
|
FILE(GLOB_RECURSE GLSL "resources/*.glsl")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# Set the executable.
|
||||||
|
ADD_EXECUTABLE(${CMAKE_PROJECT_NAME} ${SOURCES} ${HEADERS} ${GLSL})
|
||||||
|
|
||||||
|
# Get the GLM environment variable. Since GLM is a header-only library, we
|
||||||
|
# just need to add it to the include directory.
|
||||||
|
SET(GLM_INCLUDE_DIR "$ENV{GLM_INCLUDE_DIR}")
|
||||||
|
IF(NOT GLM_INCLUDE_DIR)
|
||||||
|
# The environment variable was not set
|
||||||
|
SET(ERR_MSG "Please point the environment variable GLM_INCLUDE_DIR to the root directory of your GLM installation.")
|
||||||
|
IF(WIN32)
|
||||||
|
# On Windows, try the default location
|
||||||
|
MESSAGE(STATUS "Looking for GLM in ${DEF_DIR_GLM}")
|
||||||
|
IF(IS_DIRECTORY ${DEF_DIR_GLM})
|
||||||
|
MESSAGE(STATUS "Found!")
|
||||||
|
SET(GLM_INCLUDE_DIR ${DEF_DIR_GLM})
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
INCLUDE_DIRECTORIES(${GLM_INCLUDE_DIR})
|
||||||
|
|
||||||
|
# Get the GLFW environment variable. There should be a CMakeLists.txt in the
|
||||||
|
# specified directory.
|
||||||
|
SET(GLFW_DIR "$ENV{GLFW_DIR}")
|
||||||
|
IF(NOT GLFW_DIR)
|
||||||
|
# The environment variable was not set
|
||||||
|
SET(ERR_MSG "Please point the environment variable GLFW_DIR to the root directory of your GLFW installation.")
|
||||||
|
IF(WIN32)
|
||||||
|
# On Windows, try the default location
|
||||||
|
MESSAGE(STATUS "Looking for GLFW in ${DEF_DIR_GLFW}")
|
||||||
|
IF(IS_DIRECTORY ${DEF_DIR_GLFW})
|
||||||
|
MESSAGE(STATUS "Found!")
|
||||||
|
SET(GLFW_DIR ${DEF_DIR_GLFW})
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
OPTION(GLFW_BUILD_EXAMPLES "GLFW_BUILD_EXAMPLES" OFF)
|
||||||
|
OPTION(GLFW_BUILD_TESTS "GLFW_BUILD_TESTS" OFF)
|
||||||
|
OPTION(GLFW_BUILD_DOCS "GLFW_BUILD_DOCS" OFF)
|
||||||
|
IF(CMAKE_BUILD_TYPE MATCHES Release)
|
||||||
|
ADD_SUBDIRECTORY(${GLFW_DIR} ${GLFW_DIR}/release)
|
||||||
|
ELSE()
|
||||||
|
ADD_SUBDIRECTORY(${GLFW_DIR} ${GLFW_DIR}/debug)
|
||||||
|
ENDIF()
|
||||||
|
INCLUDE_DIRECTORIES(${GLFW_DIR}/include)
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} glfw ${GLFW_LIBRARIES})
|
||||||
|
|
||||||
|
# Get the GLEW environment variable.
|
||||||
|
SET(GLEW_DIR "$ENV{GLEW_DIR}")
|
||||||
|
IF(NOT GLEW_DIR)
|
||||||
|
# The environment variable was not set
|
||||||
|
SET(ERR_MSG "Please point the environment variable GLEW_DIR to the root directory of your GLEW installation.")
|
||||||
|
IF(WIN32)
|
||||||
|
# On Windows, try the default location
|
||||||
|
MESSAGE(STATUS "Looking for GLEW in ${DEF_DIR_GLEW}")
|
||||||
|
IF(IS_DIRECTORY ${DEF_DIR_GLEW})
|
||||||
|
MESSAGE(STATUS "Found!")
|
||||||
|
SET(GLEW_DIR ${DEF_DIR_GLEW})
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
INCLUDE_DIRECTORIES(${GLEW_DIR}/include)
|
||||||
|
IF(WIN32)
|
||||||
|
# With prebuilt binaries
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} ${GLEW_DIR}/lib/Release/Win32/glew32s.lib)
|
||||||
|
ELSE()
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} ${GLEW_DIR}/lib/libGLEW.a)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# OS specific options and libraries
|
||||||
|
IF(WIN32)
|
||||||
|
# c++11 is enabled by default.
|
||||||
|
# -Wall produces way too many warnings.
|
||||||
|
# -pedantic is not supported.
|
||||||
|
# Disable warning 4996.
|
||||||
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4996")
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} opengl32.lib)
|
||||||
|
ELSE()
|
||||||
|
# Enable all pedantic warnings.
|
||||||
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -pedantic")
|
||||||
|
IF(APPLE)
|
||||||
|
# Add required frameworks for GLFW.
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} "-framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo")
|
||||||
|
ELSE()
|
||||||
|
#Link the Linux OpenGL library
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} "GL")
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
7
A4/shadow8t4/shadow8t4/README.txt
Normal file
7
A4/shadow8t4/shadow8t4/README.txt
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
Alexander Huddleston
|
||||||
|
|
||||||
|
I downloaded the code from the lab pages and worked from there.
|
||||||
|
|
||||||
|
I added a large flat cube as a "ground" but didn't texture it because I was tired of looking at a white abyss and thought this would make it look a little bit better.
|
||||||
|
|
||||||
|
I didn't notice you implemented a "toggle key" functionality in the main and instead coded if statements in the char callback to do what I wanted. The functionality remains the same, but I thought it was worth noting.
|
17
A4/shadow8t4/shadow8t4/resources/.frag.glsl
Normal file
17
A4/shadow8t4/shadow8t4/resources/.frag.glsl
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
uniform vec3 lightPos;
|
||||||
|
uniform vec3 ka;
|
||||||
|
uniform vec3 kd;
|
||||||
|
uniform vec3 ks;
|
||||||
|
uniform float s;
|
||||||
|
|
||||||
|
varying vec3 n; // passed from the vertex shader
|
||||||
|
varying vec3 p; // passed from the vertex shader
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
n = normalize(normal);
|
||||||
|
vec3 color = 0.5 * (n + 1.0);
|
||||||
|
gl_FragColor = vec4(color.r, color.g, color.b, 1.0);
|
||||||
|
}
|
17
A4/shadow8t4/shadow8t4/resources/.vert.glsl
Normal file
17
A4/shadow8t4/shadow8t4/resources/.vert.glsl
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
uniform mat4 P;
|
||||||
|
uniform mat4 MV;
|
||||||
|
|
||||||
|
attribute vec4 aPos; // in object space
|
||||||
|
attribute vec3 aNor; // in object space
|
||||||
|
|
||||||
|
varying vec3 p; // passed to fragment shader
|
||||||
|
varying vec3 n; // passed to fragment shader
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
ugl_Position = P * MV * aPos;
|
||||||
|
p = MV * aPos;
|
||||||
|
n = MV * aNor;
|
||||||
|
}
|
9977
A4/shadow8t4/shadow8t4/resources/bunny.obj
Normal file
9977
A4/shadow8t4/shadow8t4/resources/bunny.obj
Normal file
File diff suppressed because it is too large
Load diff
29
A4/shadow8t4/shadow8t4/resources/cube.obj
Normal file
29
A4/shadow8t4/shadow8t4/resources/cube.obj
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
# Blender v2.71 (sub 0) OBJ File: ''
|
||||||
|
# www.blender.org
|
||||||
|
v 0.500000 0.500000 -0.500000
|
||||||
|
v 0.500000 -0.500000 -0.500000
|
||||||
|
v -0.500000 -0.500000 -0.500000
|
||||||
|
v -0.500000 0.500000 -0.500000
|
||||||
|
v 0.500000 0.500000 0.500000
|
||||||
|
v 0.500000 -0.500000 0.500000
|
||||||
|
v -0.500000 -0.500000 0.500000
|
||||||
|
v -0.500000 0.500000 0.500000
|
||||||
|
vn 0.000000 0.000000 -1.000000
|
||||||
|
vn 0.000000 0.000000 1.000000
|
||||||
|
vn 1.000000 -0.000000 -0.000000
|
||||||
|
vn -0.000000 -1.000000 -0.000000
|
||||||
|
vn -1.000000 0.000000 -0.000000
|
||||||
|
vn 0.000000 1.000000 0.000000
|
||||||
|
s off
|
||||||
|
f 2//1 3//1 4//1
|
||||||
|
f 8//2 7//2 6//2
|
||||||
|
f 1//3 5//3 6//3
|
||||||
|
f 2//4 6//4 7//4
|
||||||
|
f 7//5 8//5 4//5
|
||||||
|
f 1//6 4//6 8//6
|
||||||
|
f 1//1 2//1 4//1
|
||||||
|
f 5//2 8//2 6//2
|
||||||
|
f 2//3 1//3 6//3
|
||||||
|
f 3//4 2//4 7//4
|
||||||
|
f 3//5 7//5 4//5
|
||||||
|
f 5//6 1//6 8//6
|
37
A4/shadow8t4/shadow8t4/resources/frag.glsl
Normal file
37
A4/shadow8t4/shadow8t4/resources/frag.glsl
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
uniform mat4 MVL;
|
||||||
|
uniform vec3 lightPos1;
|
||||||
|
uniform vec3 lightPos2;
|
||||||
|
uniform vec3 ka;
|
||||||
|
uniform vec3 kd;
|
||||||
|
uniform vec3 ks;
|
||||||
|
uniform float s;
|
||||||
|
uniform float i1;
|
||||||
|
uniform float i2;
|
||||||
|
|
||||||
|
varying vec3 color; // passed from the vertex shader
|
||||||
|
varying vec4 p;
|
||||||
|
varying vec4 n;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 normal = normalize(n);
|
||||||
|
vec3 norm = vec3(normal.x, normal.y, normal.z);
|
||||||
|
|
||||||
|
vec4 npos = normalize(p);
|
||||||
|
vec3 pos = vec3(npos.x, npos.y, npos.z);
|
||||||
|
|
||||||
|
vec3 lightnorm = vec3(MVL[3].x, MVL[3].y, MVL[3].z);
|
||||||
|
|
||||||
|
vec3 light = lightnorm - vec3(p.x, p.y, p.z);
|
||||||
|
vec3 lnorm = normalize(vec3(light.x,light.y,light.z));
|
||||||
|
float temp = dot(lnorm, norm);
|
||||||
|
vec3 cd = kd*max(0, temp);
|
||||||
|
|
||||||
|
vec3 h = normalize(lnorm - pos);
|
||||||
|
vec3 cs = ks*pow(max(0, dot(h, norm)), s);
|
||||||
|
|
||||||
|
vec4 c = vec4(ka.r + cd.r + cs.r, ka.g + cd.g + cs.g, ka.b + cd.b + cs.b, 1.0);
|
||||||
|
gl_FragColor = c;
|
||||||
|
}
|
20
A4/shadow8t4/shadow8t4/resources/sil.glsl
Normal file
20
A4/shadow8t4/shadow8t4/resources/sil.glsl
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
varying vec4 p;
|
||||||
|
varying vec4 n;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 normal = normalize(n);
|
||||||
|
vec3 norm = vec3(normal.x, normal.y, normal.z);
|
||||||
|
|
||||||
|
vec4 npos = normalize(p);
|
||||||
|
vec3 pos = vec3(npos.x, npos.y, npos.z);
|
||||||
|
|
||||||
|
float product = dot(norm, pos);
|
||||||
|
|
||||||
|
if(product <= 0.3 && product >= -0.3)
|
||||||
|
gl_FragColor = vec4(0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
else
|
||||||
|
gl_FragColor = vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
}
|
204
A4/shadow8t4/shadow8t4/resources/sphere.obj
Normal file
204
A4/shadow8t4/shadow8t4/resources/sphere.obj
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
####
|
||||||
|
#
|
||||||
|
# OBJ File Generated by LightWave3D
|
||||||
|
# LightWave3D OBJ Export v2.2
|
||||||
|
#
|
||||||
|
####
|
||||||
|
#
|
||||||
|
# Vertices: 62
|
||||||
|
# Points: 0
|
||||||
|
# Lines: 0
|
||||||
|
# Faces: 120
|
||||||
|
# Materials: 1
|
||||||
|
#
|
||||||
|
####
|
||||||
|
|
||||||
|
# Vertex list
|
||||||
|
|
||||||
|
v 0 -0.5 -0
|
||||||
|
v 0.25 -0.433013 -0
|
||||||
|
v 0.216506 -0.433013 -0.125
|
||||||
|
v 0.125 -0.433013 -0.216506
|
||||||
|
v 0 -0.433013 -0.25
|
||||||
|
v -0.125 -0.433013 -0.216506
|
||||||
|
v -0.216506 -0.433013 -0.125
|
||||||
|
v -0.25 -0.433013 -0
|
||||||
|
v -0.216506 -0.433013 0.125
|
||||||
|
v -0.125 -0.433013 0.216506
|
||||||
|
v 0 -0.433013 0.25
|
||||||
|
v 0.125 -0.433013 0.216506
|
||||||
|
v 0.216506 -0.433013 0.125
|
||||||
|
v 0.433013 -0.25 -0
|
||||||
|
v 0.375 -0.25 -0.216506
|
||||||
|
v 0.216506 -0.25 -0.375
|
||||||
|
v 0 -0.25 -0.433013
|
||||||
|
v -0.216506 -0.25 -0.375
|
||||||
|
v -0.375 -0.25 -0.216506
|
||||||
|
v -0.433013 -0.25 -0
|
||||||
|
v -0.375 -0.25 0.216506
|
||||||
|
v -0.216506 -0.25 0.375
|
||||||
|
v 0 -0.25 0.433013
|
||||||
|
v 0.216506 -0.25 0.375
|
||||||
|
v 0.375 -0.25 0.216506
|
||||||
|
v 0.5 2.55171e-12 -0
|
||||||
|
v 0.433013 2.55171e-12 -0.25
|
||||||
|
v 0.25 2.55171e-12 -0.433013
|
||||||
|
v 0 2.55171e-12 -0.5
|
||||||
|
v -0.25 2.55171e-12 -0.433013
|
||||||
|
v -0.433013 2.55171e-12 -0.25
|
||||||
|
v -0.5 2.55171e-12 -0
|
||||||
|
v -0.433013 2.55171e-12 0.25
|
||||||
|
v -0.25 2.55171e-12 0.433013
|
||||||
|
v 0 2.55171e-12 0.5
|
||||||
|
v 0.25 2.55171e-12 0.433013
|
||||||
|
v 0.433013 2.55171e-12 0.25
|
||||||
|
v 0.433013 0.25 -0
|
||||||
|
v 0.375 0.25 -0.216506
|
||||||
|
v 0.216506 0.25 -0.375
|
||||||
|
v 0 0.25 -0.433013
|
||||||
|
v -0.216506 0.25 -0.375
|
||||||
|
v -0.375 0.25 -0.216506
|
||||||
|
v -0.433013 0.25 -0
|
||||||
|
v -0.375 0.25 0.216506
|
||||||
|
v -0.216506 0.25 0.375
|
||||||
|
v 0 0.25 0.433013
|
||||||
|
v 0.216506 0.25 0.375
|
||||||
|
v 0.375 0.25 0.216506
|
||||||
|
v 0.25 0.433013 -0
|
||||||
|
v 0.216506 0.433013 -0.125
|
||||||
|
v 0.125 0.433013 -0.216506
|
||||||
|
v 0 0.433013 -0.25
|
||||||
|
v -0.125 0.433013 -0.216506
|
||||||
|
v -0.216506 0.433013 -0.125
|
||||||
|
v -0.25 0.433013 -0
|
||||||
|
v -0.216506 0.433013 0.125
|
||||||
|
v -0.125 0.433013 0.216506
|
||||||
|
v 0 0.433013 0.25
|
||||||
|
v 0.125 0.433013 0.216506
|
||||||
|
v 0.216506 0.433013 0.125
|
||||||
|
v 5.10341e-12 0.5 -0
|
||||||
|
|
||||||
|
# Face list
|
||||||
|
|
||||||
|
f 3 2 1
|
||||||
|
f 4 3 1
|
||||||
|
f 5 4 1
|
||||||
|
f 6 5 1
|
||||||
|
f 7 6 1
|
||||||
|
f 8 7 1
|
||||||
|
f 9 8 1
|
||||||
|
f 10 9 1
|
||||||
|
f 11 10 1
|
||||||
|
f 12 11 1
|
||||||
|
f 13 12 1
|
||||||
|
f 2 13 1
|
||||||
|
f 3 14 2
|
||||||
|
f 15 14 3
|
||||||
|
f 4 15 3
|
||||||
|
f 16 15 4
|
||||||
|
f 17 16 4
|
||||||
|
f 5 17 4
|
||||||
|
f 17 5 6
|
||||||
|
f 18 17 6
|
||||||
|
f 18 6 7
|
||||||
|
f 19 18 7
|
||||||
|
f 20 7 8
|
||||||
|
f 20 19 7
|
||||||
|
f 20 8 9
|
||||||
|
f 21 20 9
|
||||||
|
f 21 9 10
|
||||||
|
f 22 21 10
|
||||||
|
f 23 10 11
|
||||||
|
f 23 22 10
|
||||||
|
f 12 23 11
|
||||||
|
f 24 23 12
|
||||||
|
f 13 24 12
|
||||||
|
f 25 24 13
|
||||||
|
f 14 25 13
|
||||||
|
f 2 14 13
|
||||||
|
f 15 26 14
|
||||||
|
f 27 26 15
|
||||||
|
f 28 27 15
|
||||||
|
f 16 28 15
|
||||||
|
f 29 28 16
|
||||||
|
f 17 29 16
|
||||||
|
f 29 17 18
|
||||||
|
f 30 29 18
|
||||||
|
f 31 18 19
|
||||||
|
f 31 30 18
|
||||||
|
f 32 19 20
|
||||||
|
f 32 31 19
|
||||||
|
f 32 20 21
|
||||||
|
f 33 32 21
|
||||||
|
f 34 21 22
|
||||||
|
f 34 33 21
|
||||||
|
f 35 22 23
|
||||||
|
f 35 34 22
|
||||||
|
f 24 35 23
|
||||||
|
f 36 35 24
|
||||||
|
f 37 36 24
|
||||||
|
f 25 37 24
|
||||||
|
f 26 37 25
|
||||||
|
f 14 26 25
|
||||||
|
f 39 38 26
|
||||||
|
f 27 39 26
|
||||||
|
f 28 39 27
|
||||||
|
f 40 39 28
|
||||||
|
f 29 40 28
|
||||||
|
f 41 40 29
|
||||||
|
f 42 29 30
|
||||||
|
f 42 41 29
|
||||||
|
f 43 30 31
|
||||||
|
f 43 42 30
|
||||||
|
f 43 31 32
|
||||||
|
f 44 43 32
|
||||||
|
f 45 32 33
|
||||||
|
f 45 44 32
|
||||||
|
f 45 33 34
|
||||||
|
f 46 45 34
|
||||||
|
f 46 34 35
|
||||||
|
f 47 46 35
|
||||||
|
f 48 47 35
|
||||||
|
f 36 48 35
|
||||||
|
f 49 48 36
|
||||||
|
f 37 49 36
|
||||||
|
f 26 49 37
|
||||||
|
f 38 49 26
|
||||||
|
f 39 50 38
|
||||||
|
f 51 50 39
|
||||||
|
f 40 51 39
|
||||||
|
f 52 51 40
|
||||||
|
f 53 52 40
|
||||||
|
f 41 53 40
|
||||||
|
f 53 41 42
|
||||||
|
f 54 53 42
|
||||||
|
f 55 42 43
|
||||||
|
f 55 54 42
|
||||||
|
f 56 43 44
|
||||||
|
f 56 55 43
|
||||||
|
f 56 44 45
|
||||||
|
f 57 56 45
|
||||||
|
f 58 45 46
|
||||||
|
f 58 57 45
|
||||||
|
f 58 46 47
|
||||||
|
f 59 58 47
|
||||||
|
f 60 59 47
|
||||||
|
f 48 60 47
|
||||||
|
f 49 60 48
|
||||||
|
f 61 60 49
|
||||||
|
f 50 61 49
|
||||||
|
f 38 50 49
|
||||||
|
f 51 62 50
|
||||||
|
f 52 62 51
|
||||||
|
f 53 62 52
|
||||||
|
f 62 53 54
|
||||||
|
f 62 54 55
|
||||||
|
f 62 55 56
|
||||||
|
f 62 56 57
|
||||||
|
f 62 57 58
|
||||||
|
f 62 58 59
|
||||||
|
f 60 62 59
|
||||||
|
f 61 62 60
|
||||||
|
f 50 62 61
|
||||||
|
|
||||||
|
# End of file
|
5049
A4/shadow8t4/shadow8t4/resources/teapot.obj
Normal file
5049
A4/shadow8t4/shadow8t4/resources/teapot.obj
Normal file
File diff suppressed because it is too large
Load diff
24
A4/shadow8t4/shadow8t4/resources/vert.glsl
Normal file
24
A4/shadow8t4/shadow8t4/resources/vert.glsl
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
uniform mat4 P;
|
||||||
|
uniform mat4 MV;
|
||||||
|
uniform mat4 MVL;
|
||||||
|
uniform vec3 lightPos1;
|
||||||
|
uniform vec3 lightPos2;
|
||||||
|
uniform float i1;
|
||||||
|
uniform float i2;
|
||||||
|
|
||||||
|
attribute vec4 aPos; // in object space
|
||||||
|
attribute vec3 aNor; // in object space
|
||||||
|
|
||||||
|
varying vec3 color; // Pass to fragment shader
|
||||||
|
varying vec4 p;
|
||||||
|
varying vec4 n;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = P * MV * aPos;
|
||||||
|
p = MV * aPos;
|
||||||
|
n = MV * vec4(aNor, 0.0);
|
||||||
|
color = vec3(0.5, 0.5, 0.5);
|
||||||
|
}
|
68
A4/shadow8t4/shadow8t4/src/Camera.cpp
Normal file
68
A4/shadow8t4/shadow8t4/src/Camera.cpp
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
#include "Camera.h"
|
||||||
|
#include "MatrixStack.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
|
Camera::Camera() :
|
||||||
|
aspect(1.0f),
|
||||||
|
fovy(45.0f),
|
||||||
|
znear(0.1f),
|
||||||
|
zfar(1000.0f),
|
||||||
|
rotations(0.0, 0.0),
|
||||||
|
translations(0.0f, 0.0f, -5.0f),
|
||||||
|
rfactor(0.01f),
|
||||||
|
tfactor(0.001f),
|
||||||
|
sfactor(0.005f)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Camera::~Camera()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::mouseClicked(float x, float y, bool shift, bool ctrl, bool alt)
|
||||||
|
{
|
||||||
|
mousePrev.x = x;
|
||||||
|
mousePrev.y = y;
|
||||||
|
if(shift) {
|
||||||
|
state = Camera::TRANSLATE;
|
||||||
|
} else if(ctrl) {
|
||||||
|
state = Camera::SCALE;
|
||||||
|
} else {
|
||||||
|
state = Camera::ROTATE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::mouseMoved(float x, float y)
|
||||||
|
{
|
||||||
|
glm::vec2 mouseCurr(x, y);
|
||||||
|
glm::vec2 dv = mouseCurr - mousePrev;
|
||||||
|
switch(state) {
|
||||||
|
case Camera::ROTATE:
|
||||||
|
rotations += rfactor * dv;
|
||||||
|
break;
|
||||||
|
case Camera::TRANSLATE:
|
||||||
|
translations.x -= translations.z * tfactor * dv.x;
|
||||||
|
translations.y += translations.z * tfactor * dv.y;
|
||||||
|
break;
|
||||||
|
case Camera::SCALE:
|
||||||
|
translations.z *= (1.0f - sfactor * dv.y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mousePrev = mouseCurr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::applyProjectionMatrix(std::shared_ptr<MatrixStack> P) const
|
||||||
|
{
|
||||||
|
// Modify provided MatrixStack
|
||||||
|
P->multMatrix(glm::perspective(fovy, aspect, znear, zfar));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::applyViewMatrix(std::shared_ptr<MatrixStack> MV) const
|
||||||
|
{
|
||||||
|
MV->translate(translations);
|
||||||
|
MV->rotate(rotations.y, glm::vec3(1.0f, 0.0f, 0.0f));
|
||||||
|
MV->rotate(rotations.x, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
|
}
|
||||||
|
*/
|
49
A4/shadow8t4/shadow8t4/src/Camera.h
Normal file
49
A4/shadow8t4/shadow8t4/src/Camera.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
#pragma once
|
||||||
|
#ifndef __Camera__
|
||||||
|
#define __Camera__
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#define GLM_FORCE_RADIANS
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
class MatrixStack;
|
||||||
|
|
||||||
|
class Camera
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
ROTATE = 0,
|
||||||
|
TRANSLATE,
|
||||||
|
SCALE
|
||||||
|
};
|
||||||
|
|
||||||
|
Camera();
|
||||||
|
virtual ~Camera();
|
||||||
|
void setInitDistance(float z) { translations.z = -std::abs(z); }
|
||||||
|
void setAspect(float a) { aspect = a; };
|
||||||
|
void setRotationFactor(float f) { rfactor = f; };
|
||||||
|
void setTranslationFactor(float f) { tfactor = f; };
|
||||||
|
void setScaleFactor(float f) { sfactor = f; };
|
||||||
|
void mouseClicked(float x, float y, bool shift, bool ctrl, bool alt);
|
||||||
|
void mouseMoved(float x, float y);
|
||||||
|
void applyProjectionMatrix(std::shared_ptr<MatrixStack> P) const;
|
||||||
|
void applyViewMatrix(std::shared_ptr<MatrixStack> MV) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
float aspect;
|
||||||
|
float fovy;
|
||||||
|
float znear;
|
||||||
|
float zfar;
|
||||||
|
glm::vec2 rotations;
|
||||||
|
glm::vec3 translations;
|
||||||
|
glm::vec2 mousePrev;
|
||||||
|
int state;
|
||||||
|
float rfactor;
|
||||||
|
float tfactor;
|
||||||
|
float sfactor;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
*/
|
122
A4/shadow8t4/shadow8t4/src/Component.cpp
Normal file
122
A4/shadow8t4/shadow8t4/src/Component.cpp
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include "Component.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
Component::Component()
|
||||||
|
{
|
||||||
|
parent = NULL;
|
||||||
|
selected = false;
|
||||||
|
t = vec3(0,0,0);
|
||||||
|
tp = vec3(0,0,0);
|
||||||
|
r = vec3(0,0,0);
|
||||||
|
s = vec3(1.0,1.0,1.0);
|
||||||
|
children.resize(0);
|
||||||
|
sid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Component::Component(const Component& c)
|
||||||
|
{
|
||||||
|
parent = c.parent;
|
||||||
|
children = c.children;
|
||||||
|
selected = c.selected;
|
||||||
|
t = vec3(c.t.x, c.t.y, c.t.z);
|
||||||
|
tp = vec3(c.tp.x, c.tp.y, c.tp.z);
|
||||||
|
r = vec3(c.r.x, c.r.y, c.r.z);
|
||||||
|
s = vec3(c.s.x, c.s.y, c.s.z);
|
||||||
|
sid = c.sid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Component::draw(shared_ptr<MatrixStack> MV, shared_ptr<MatrixStack> P, shared_ptr<Shape> S, shared_ptr<Program> Prog)
|
||||||
|
{
|
||||||
|
MV->pushMatrix();
|
||||||
|
MV->translate(tp.x, tp.y, tp.z);
|
||||||
|
MV->rotate(r.x, 1, 0, 0);
|
||||||
|
MV->rotate(r.y, 0, 1, 0);
|
||||||
|
MV->rotate(r.z, 0, 0, 1);
|
||||||
|
MV->translate(t.x, t.y, t.z);
|
||||||
|
for(unsigned int i = 0; i < children.size(); i++)
|
||||||
|
{
|
||||||
|
children[i].draw(MV, P, S, Prog);
|
||||||
|
}
|
||||||
|
if(selected)
|
||||||
|
{
|
||||||
|
MV->scale(1.1,1.1,1.1);
|
||||||
|
}
|
||||||
|
MV->scale(s.x,s.y,s.z);
|
||||||
|
glUniformMatrix4fv(Prog->getUniform("P"), 1, GL_FALSE, &P->topMatrix()[0][0]);
|
||||||
|
glUniformMatrix4fv(Prog->getUniform("MV"), 1, GL_FALSE, &MV->topMatrix()[0][0]);
|
||||||
|
S->draw(Prog);
|
||||||
|
MV->popMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
Component& Component::getLastChild()
|
||||||
|
{
|
||||||
|
if(this->children.empty())
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
return this->children[this->children.size() - 1].getLastChild();
|
||||||
|
}
|
||||||
|
|
||||||
|
Component& Component::getPrevious(Component *addr)
|
||||||
|
{
|
||||||
|
if(children.empty())
|
||||||
|
{
|
||||||
|
if(parent != NULL)
|
||||||
|
{
|
||||||
|
return parent->getPrevious(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < this->children.size(); i++)
|
||||||
|
{
|
||||||
|
//return *this;
|
||||||
|
if(&children[i] == addr)
|
||||||
|
{
|
||||||
|
if(i > 0)
|
||||||
|
{
|
||||||
|
return children[i-1].getLastChild();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parent == NULL) {
|
||||||
|
return this->getLastChild();
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent->getPrevious(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Component& Component::getNext(Component *addr)
|
||||||
|
{
|
||||||
|
if(addr == NULL)
|
||||||
|
{
|
||||||
|
if(!children.empty())
|
||||||
|
{
|
||||||
|
return children[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < this->children.size(); i++)
|
||||||
|
{
|
||||||
|
//return *this;
|
||||||
|
if(&children[i] == addr)
|
||||||
|
{
|
||||||
|
if(i+1 < children.size())
|
||||||
|
{
|
||||||
|
return children[i+1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parent == NULL) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent->getNext(this);
|
||||||
|
}
|
30
A4/shadow8t4/shadow8t4/src/Component.h
Normal file
30
A4/shadow8t4/shadow8t4/src/Component.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// Create Body Class
|
||||||
|
#include <vector>
|
||||||
|
#include "MatrixStack.h"
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <memory>
|
||||||
|
#include "Shape.h"
|
||||||
|
#include "Program.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace glm;
|
||||||
|
|
||||||
|
class Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Component *parent;
|
||||||
|
vector<Component> children;
|
||||||
|
bool selected;
|
||||||
|
vec3 t;
|
||||||
|
vec3 tp;
|
||||||
|
vec3 r;
|
||||||
|
vec3 s;
|
||||||
|
int sid; // used for storing which shape to render
|
||||||
|
|
||||||
|
Component();
|
||||||
|
Component(const Component& c);
|
||||||
|
void draw(shared_ptr<MatrixStack> MV, shared_ptr<MatrixStack> P, shared_ptr<Shape> S, shared_ptr<Program> Prog);
|
||||||
|
Component& getNext(Component *addr);
|
||||||
|
Component& getPrevious(Component *addr);
|
||||||
|
Component& getLastChild();
|
||||||
|
};
|
152
A4/shadow8t4/shadow8t4/src/GLSL.cpp
Normal file
152
A4/shadow8t4/shadow8t4/src/GLSL.cpp
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
//
|
||||||
|
// Many useful helper functions for GLSL shaders - gleaned from various sources including orange book
|
||||||
|
// Created by zwood on 2/21/10.
|
||||||
|
// Modified by sueda 10/15/15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "GLSL.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace GLSL {
|
||||||
|
|
||||||
|
const char * errorString(GLenum err)
|
||||||
|
{
|
||||||
|
switch(err) {
|
||||||
|
case GL_NO_ERROR:
|
||||||
|
return "No error";
|
||||||
|
case GL_INVALID_ENUM:
|
||||||
|
return "Invalid enum";
|
||||||
|
case GL_INVALID_VALUE:
|
||||||
|
return "Invalid value";
|
||||||
|
case GL_INVALID_OPERATION:
|
||||||
|
return "Invalid operation";
|
||||||
|
case GL_STACK_OVERFLOW:
|
||||||
|
return "Stack overflow";
|
||||||
|
case GL_STACK_UNDERFLOW:
|
||||||
|
return "Stack underflow";
|
||||||
|
case GL_OUT_OF_MEMORY:
|
||||||
|
return "Out of memory";
|
||||||
|
default:
|
||||||
|
return "No error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkVersion()
|
||||||
|
{
|
||||||
|
int major, minor;
|
||||||
|
major = minor = 0;
|
||||||
|
const char *verstr = (const char *)glGetString(GL_VERSION);
|
||||||
|
|
||||||
|
if((verstr == NULL) || (sscanf(verstr, "%d.%d", &major, &minor) != 2)) {
|
||||||
|
printf("Invalid GL_VERSION format %d.%d\n", major, minor);
|
||||||
|
}
|
||||||
|
if(major < 2) {
|
||||||
|
printf("This shader example will not work due to the installed Opengl version, which is %d.%d.\n", major, minor);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkError(const char *str)
|
||||||
|
{
|
||||||
|
GLenum glErr = glGetError();
|
||||||
|
if(glErr != GL_NO_ERROR) {
|
||||||
|
if(str) {
|
||||||
|
printf("%s: ", str);
|
||||||
|
}
|
||||||
|
printf("GL_ERROR = %s.\n", errorString(glErr));
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void printShaderInfoLog(GLuint shader)
|
||||||
|
{
|
||||||
|
GLint infologLength = 0;
|
||||||
|
GLint charsWritten = 0;
|
||||||
|
GLchar *infoLog = 0;
|
||||||
|
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infologLength);
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
|
||||||
|
if(infologLength > 0) {
|
||||||
|
infoLog = (GLchar *)malloc(infologLength);
|
||||||
|
if(infoLog == NULL) {
|
||||||
|
puts("ERROR: Could not allocate InfoLog buffer");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
glGetShaderInfoLog(shader, infologLength, &charsWritten, infoLog);
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
printf("Shader InfoLog:\n%s\n\n", infoLog);
|
||||||
|
free(infoLog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void printProgramInfoLog(GLuint program)
|
||||||
|
{
|
||||||
|
GLint infologLength = 0;
|
||||||
|
GLint charsWritten = 0;
|
||||||
|
GLchar *infoLog = 0;
|
||||||
|
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infologLength);
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
|
||||||
|
if(infologLength > 0) {
|
||||||
|
infoLog = (GLchar *)malloc(infologLength);
|
||||||
|
if(infoLog == NULL) {
|
||||||
|
puts("ERROR: Could not allocate InfoLog buffer");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
glGetProgramInfoLog(program, infologLength, &charsWritten, infoLog);
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
printf("Program InfoLog:\n%s\n\n", infoLog);
|
||||||
|
free(infoLog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *textFileRead(const char *fn)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char *content = NULL;
|
||||||
|
int count = 0;
|
||||||
|
if(fn != NULL) {
|
||||||
|
fp = fopen(fn,"rt");
|
||||||
|
if(fp != NULL) {
|
||||||
|
fseek(fp, 0, SEEK_END);
|
||||||
|
count = (int)ftell(fp);
|
||||||
|
rewind(fp);
|
||||||
|
if(count > 0) {
|
||||||
|
content = (char *)malloc(sizeof(char) * (count+1));
|
||||||
|
count = (int)fread(content,sizeof(char),count,fp);
|
||||||
|
content[count] = '\0';
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
} else {
|
||||||
|
printf("error loading %s\n", fn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
int textFileWrite(const char *fn, const char *s)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
int status = 0;
|
||||||
|
if(fn != NULL) {
|
||||||
|
fp = fopen(fn,"w");
|
||||||
|
if(fp != NULL) {
|
||||||
|
if(fwrite(s,sizeof(char),strlen(s),fp) == strlen(s)) {
|
||||||
|
status = 1;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
40
A4/shadow8t4/shadow8t4/src/GLSL.h
Normal file
40
A4/shadow8t4/shadow8t4/src/GLSL.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
//
|
||||||
|
// Many useful helper functions for GLSL shaders - gleaned from various sources including orange book
|
||||||
|
// Created by zwood on 2/21/10.
|
||||||
|
// Modified by sueda 10/15/15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef __GLSL__
|
||||||
|
#define __GLSL__
|
||||||
|
|
||||||
|
#define GLEW_STATIC
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// For printing out the current file and line number //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::string NumberToString(T x)
|
||||||
|
{
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << x;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GET_FILE_LINE (std::string(__FILE__) + ":" + NumberToString(__LINE__)).c_str()
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace GLSL {
|
||||||
|
|
||||||
|
void checkVersion();
|
||||||
|
void checkError(const char *str = 0);
|
||||||
|
void printProgramInfoLog(GLuint program);
|
||||||
|
void printShaderInfoLog(GLuint shader);
|
||||||
|
int textFileWrite(const char *filename, const char *s);
|
||||||
|
char *textFileRead(const char *filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
39
A4/shadow8t4/shadow8t4/src/Light.cpp
Normal file
39
A4/shadow8t4/shadow8t4/src/Light.cpp
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#include "Light.h"
|
||||||
|
|
||||||
|
Light::Light()
|
||||||
|
{
|
||||||
|
pos = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
|
intensity = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Light::Light(const Light &l)
|
||||||
|
{
|
||||||
|
pos = l.pos;
|
||||||
|
intensity = l.intensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
Light::Light(glm::vec3 p, float i)
|
||||||
|
{
|
||||||
|
pos = p;
|
||||||
|
intensity = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Light::setPos(glm::vec3 p)
|
||||||
|
{
|
||||||
|
this->pos = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Light::setIntensity(float i)
|
||||||
|
{
|
||||||
|
this->intensity = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 Light::getPos()
|
||||||
|
{
|
||||||
|
return this->pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Light::getIntensity()
|
||||||
|
{
|
||||||
|
return this->intensity;
|
||||||
|
}
|
27
A4/shadow8t4/shadow8t4/src/Light.h
Normal file
27
A4/shadow8t4/shadow8t4/src/Light.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
#include "GLSL.h"
|
||||||
|
#include "MyCamera.h"
|
||||||
|
#include "Shape.h"
|
||||||
|
#include "MatrixStack.h"
|
||||||
|
|
||||||
|
class Light
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
glm::vec3 pos;
|
||||||
|
float intensity;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Light();
|
||||||
|
Light(const Light &l);
|
||||||
|
Light(glm::vec3 p, float i);
|
||||||
|
void setPos(glm::vec3 p);
|
||||||
|
void setIntensity(float i);
|
||||||
|
glm::vec3 getPos();
|
||||||
|
float getIntensity();
|
||||||
|
};
|
39
A4/shadow8t4/shadow8t4/src/Material.cpp
Normal file
39
A4/shadow8t4/shadow8t4/src/Material.cpp
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#include "Material.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
Material::Material()
|
||||||
|
{
|
||||||
|
this->ca = glm::vec3(0.3f,0.3f,0.3f);
|
||||||
|
this->cd = glm::vec3(0.3f,0.3f,0.3f);
|
||||||
|
this->cs = glm::vec3(1.0f,1.0f,1.0f);
|
||||||
|
this->shine = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Material::setMaterial(glm::vec3 a, glm::vec3 d, glm::vec3 s, float sh)
|
||||||
|
{
|
||||||
|
this->ca = a;
|
||||||
|
this->cd = d;
|
||||||
|
this->cs = s;
|
||||||
|
this->shine = sh;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 Material::getAmbient()
|
||||||
|
{
|
||||||
|
return this->ca;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 Material::getDiffuse()
|
||||||
|
{
|
||||||
|
return this->cd;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 Material::getSpecular()
|
||||||
|
{
|
||||||
|
return this->cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Material::getShiny()
|
||||||
|
{
|
||||||
|
return this->shine;
|
||||||
|
}
|
41
A4/shadow8t4/shadow8t4/src/Material.h
Normal file
41
A4/shadow8t4/shadow8t4/src/Material.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
#include "GLSL.h"
|
||||||
|
#include "MyCamera.h"
|
||||||
|
#include "Shape.h"
|
||||||
|
#include "MatrixStack.h"
|
||||||
|
|
||||||
|
class Material
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
glm::vec3 ca;
|
||||||
|
glm::vec3 cd;
|
||||||
|
glm::vec3 cs;
|
||||||
|
float shine;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Material();
|
||||||
|
Material(const Material &m)
|
||||||
|
{
|
||||||
|
ca = m.ca;
|
||||||
|
cd = m.cd;
|
||||||
|
cs = m.cs;
|
||||||
|
}
|
||||||
|
Material(glm::vec3 a, glm::vec3 d, glm::vec3 s, float sh)
|
||||||
|
{
|
||||||
|
ca = a;
|
||||||
|
cd = d;
|
||||||
|
cs = s;
|
||||||
|
shine = sh;
|
||||||
|
}
|
||||||
|
void setMaterial(glm::vec3 a, glm::vec3 d, glm::vec3 s, float sh);
|
||||||
|
glm::vec3 getAmbient();
|
||||||
|
glm::vec3 getDiffuse();
|
||||||
|
glm::vec3 getSpecular();
|
||||||
|
float getShiny();
|
||||||
|
};
|
114
A4/shadow8t4/shadow8t4/src/MatrixStack.cpp
Normal file
114
A4/shadow8t4/shadow8t4/src/MatrixStack.cpp
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
#include "MatrixStack.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <cassert>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#define GLM_FORCE_RADIANS
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtx/transform.hpp>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
MatrixStack::MatrixStack()
|
||||||
|
{
|
||||||
|
mstack = make_shared< stack<glm::mat4> >();
|
||||||
|
mstack->push(glm::mat4(1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
MatrixStack::~MatrixStack()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::pushMatrix()
|
||||||
|
{
|
||||||
|
const glm::mat4 &top = mstack->top();
|
||||||
|
mstack->push(top);
|
||||||
|
assert(mstack->size() < 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::popMatrix()
|
||||||
|
{
|
||||||
|
assert(!mstack->empty());
|
||||||
|
mstack->pop();
|
||||||
|
// There should always be one matrix left.
|
||||||
|
assert(!mstack->empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::loadIdentity()
|
||||||
|
{
|
||||||
|
glm::mat4 &top = mstack->top();
|
||||||
|
top = glm::mat4(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::translate(const glm::vec3 &t)
|
||||||
|
{
|
||||||
|
glm::mat4 &top = mstack->top();
|
||||||
|
top *= glm::translate(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::translate(float x, float y, float z)
|
||||||
|
{
|
||||||
|
translate(glm::vec3(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::scale(const glm::vec3 &s)
|
||||||
|
{
|
||||||
|
glm::mat4 &top = mstack->top();
|
||||||
|
top *= glm::scale(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::scale(float x, float y, float z)
|
||||||
|
{
|
||||||
|
scale(glm::vec3(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::scale(float s)
|
||||||
|
{
|
||||||
|
scale(glm::vec3(s, s, s));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::rotate(float angle, const glm::vec3 &axis)
|
||||||
|
{
|
||||||
|
glm::mat4 &top = mstack->top();
|
||||||
|
top *= glm::rotate(angle, axis);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::rotate(float angle, float x, float y, float z)
|
||||||
|
{
|
||||||
|
rotate(angle, glm::vec3(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::multMatrix(const glm::mat4 &matrix)
|
||||||
|
{
|
||||||
|
glm::mat4 &top = mstack->top();
|
||||||
|
top *= matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
const glm::mat4 &MatrixStack::topMatrix() const
|
||||||
|
{
|
||||||
|
return mstack->top();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::print(const glm::mat4 &mat, const char *name)
|
||||||
|
{
|
||||||
|
if(name) {
|
||||||
|
printf("%s = [\n", name);
|
||||||
|
}
|
||||||
|
for(int i = 0; i < 4; ++i) {
|
||||||
|
for(int j = 0; j < 4; ++j) {
|
||||||
|
// mat[j] returns the jth column
|
||||||
|
printf("%- 5.2f ", mat[j][i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
if(name) {
|
||||||
|
printf("];");
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::print(const char *name) const
|
||||||
|
{
|
||||||
|
print(mstack->top(), name);
|
||||||
|
}
|
50
A4/shadow8t4/shadow8t4/src/MatrixStack.h
Normal file
50
A4/shadow8t4/shadow8t4/src/MatrixStack.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef _MatrixStack_H_
|
||||||
|
#define _MatrixStack_H_
|
||||||
|
|
||||||
|
#include <stack>
|
||||||
|
#include <memory>
|
||||||
|
#include <glm/fwd.hpp>
|
||||||
|
|
||||||
|
class MatrixStack
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MatrixStack();
|
||||||
|
virtual ~MatrixStack();
|
||||||
|
|
||||||
|
// glPushMatrix(): Copies the current matrix and adds it to the top of the stack
|
||||||
|
void pushMatrix();
|
||||||
|
// glPopMatrix(): Removes the top of the stack and sets the current matrix to be the matrix that is now on top
|
||||||
|
void popMatrix();
|
||||||
|
|
||||||
|
// glLoadIdentity(): Sets the top matrix to be the identity
|
||||||
|
void loadIdentity();
|
||||||
|
// glMultMatrix(): Right multiplies the top matrix
|
||||||
|
void multMatrix(const glm::mat4 &matrix);
|
||||||
|
|
||||||
|
// glTranslate(): Right multiplies the top matrix by a translation matrix
|
||||||
|
void translate(const glm::vec3 &trans);
|
||||||
|
void translate(float x, float y, float z);
|
||||||
|
// glScale(): Right multiplies the top matrix by a scaling matrix
|
||||||
|
void scale(const glm::vec3 &scale);
|
||||||
|
void scale(float x, float y, float z);
|
||||||
|
// glScale(): Right multiplies the top matrix by a scaling matrix
|
||||||
|
void scale(float size);
|
||||||
|
// glRotate(): Right multiplies the top matrix by a rotation matrix (angle in radians)
|
||||||
|
void rotate(float angle, const glm::vec3 &axis);
|
||||||
|
void rotate(float angle, float x, float y, float z);
|
||||||
|
|
||||||
|
// glGet(GL_MODELVIEW_MATRIX): Gets the top matrix
|
||||||
|
const glm::mat4 &topMatrix() const;
|
||||||
|
|
||||||
|
// Prints out the specified matrix
|
||||||
|
static void print(const glm::mat4 &mat, const char *name = 0);
|
||||||
|
// Prints out the top matrix
|
||||||
|
void print(const char *name = 0) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr< std::stack<glm::mat4> > mstack;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
88
A4/shadow8t4/shadow8t4/src/MyCamera.cpp
Normal file
88
A4/shadow8t4/shadow8t4/src/MyCamera.cpp
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
#include "MyCamera.h"
|
||||||
|
#include "MatrixStack.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
|
Camera::Camera() :
|
||||||
|
aspect(1.0f),
|
||||||
|
fovy(45.0f),
|
||||||
|
znear(0.1f),
|
||||||
|
zfar(1000.0f),
|
||||||
|
rotations(0.0, 0.0),
|
||||||
|
translations(0.0f, 0.0f, -5.0f),
|
||||||
|
rfactor(0.01f),
|
||||||
|
tfactor(0.001f),
|
||||||
|
sfactor(0.005f),
|
||||||
|
pos(0.0f, 0.0f, 1.0f),
|
||||||
|
pitch(0.0f),
|
||||||
|
yaw(0.0f)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Camera::~Camera()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::mouseClicked(float x, float y, bool shift, bool ctrl, bool alt)
|
||||||
|
{
|
||||||
|
mousePrev.x = x;
|
||||||
|
mousePrev.y = y;
|
||||||
|
if(shift) {
|
||||||
|
state = Camera::TRANSLATE;
|
||||||
|
} else if(ctrl) {
|
||||||
|
state = Camera::SCALE;
|
||||||
|
} else {
|
||||||
|
state = Camera::ROTATE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::mouseMoved(float x, float y)
|
||||||
|
{
|
||||||
|
glm::vec2 mouseCurr(x, y);
|
||||||
|
glm::vec2 dv = mouseCurr - mousePrev;
|
||||||
|
switch(state) {
|
||||||
|
case Camera::ROTATE:
|
||||||
|
rotations += rfactor * dv;
|
||||||
|
if(rotations.y > 0.6)
|
||||||
|
{
|
||||||
|
rotations.y = 0.6;
|
||||||
|
}
|
||||||
|
else if(rotations.y < -0.6)
|
||||||
|
{
|
||||||
|
rotations.y = -0.6;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Camera::TRANSLATE:
|
||||||
|
translations.x -= translations.z * tfactor * dv.x;
|
||||||
|
translations.y += translations.z * tfactor * dv.y;
|
||||||
|
break;
|
||||||
|
case Camera::SCALE:
|
||||||
|
translations.z *= (1.0f - sfactor * dv.y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mousePrev = mouseCurr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::applyProjectionMatrix(std::shared_ptr<MatrixStack> P) const
|
||||||
|
{
|
||||||
|
// Modify provided MatrixStack
|
||||||
|
P->multMatrix(glm::perspective(fovy, aspect, znear, zfar));
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 Camera::getPos()
|
||||||
|
{
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::transpose(glm::vec3 t)
|
||||||
|
{
|
||||||
|
glm::vec3 target(sin(rotations.x), 0, cos(rotations.x));
|
||||||
|
pos -= (cross(glm::vec3(0, 1, 0), target))*t.x;
|
||||||
|
pos -= target*t.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::applyViewMatrix(std::shared_ptr<MatrixStack> MV) const
|
||||||
|
{
|
||||||
|
glm::vec3 target(sin(rotations.x), sin(rotations.y), cos(rotations.x));
|
||||||
|
MV->multMatrix(glm::lookAt(pos, pos + target, glm::vec3(0,1,0)));
|
||||||
|
}
|
54
A4/shadow8t4/shadow8t4/src/MyCamera.h
Normal file
54
A4/shadow8t4/shadow8t4/src/MyCamera.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef __MyCamera__
|
||||||
|
#define __MyCamera__
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#define GLM_FORCE_RADIANS
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
class MatrixStack;
|
||||||
|
|
||||||
|
class Camera
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
ROTATE = 0,
|
||||||
|
TRANSLATE,
|
||||||
|
SCALE
|
||||||
|
};
|
||||||
|
|
||||||
|
Camera();
|
||||||
|
virtual ~Camera();
|
||||||
|
void setInitDistance(float z) { translations.z = -std::abs(z); }
|
||||||
|
void setAspect(float a) { aspect = a; };
|
||||||
|
void setRotationFactor(float f) { rfactor = f; };
|
||||||
|
void setTranslationFactor(float f) { tfactor = f; };
|
||||||
|
void setScaleFactor(float f) { sfactor = f; };
|
||||||
|
void mouseClicked(float x, float y, bool shift, bool ctrl, bool alt);
|
||||||
|
void mouseMoved(float x, float y);
|
||||||
|
void applyProjectionMatrix(std::shared_ptr<MatrixStack> P) const;
|
||||||
|
void applyViewMatrix(std::shared_ptr<MatrixStack> MV) const;
|
||||||
|
glm::vec3 getPos();
|
||||||
|
void transpose(glm::vec3 t);
|
||||||
|
|
||||||
|
private:
|
||||||
|
float aspect;
|
||||||
|
float fovy;
|
||||||
|
float znear;
|
||||||
|
float zfar;
|
||||||
|
glm::vec2 rotations;
|
||||||
|
glm::vec3 translations;
|
||||||
|
glm::vec2 mousePrev;
|
||||||
|
int state;
|
||||||
|
float rfactor;
|
||||||
|
float tfactor;
|
||||||
|
float sfactor;
|
||||||
|
|
||||||
|
// TODO: Implement these
|
||||||
|
glm::vec3 pos;
|
||||||
|
float pitch; // Preliminarily making these floats
|
||||||
|
float yaw; // to hold angles.
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
126
A4/shadow8t4/shadow8t4/src/Program.cpp
Normal file
126
A4/shadow8t4/shadow8t4/src/Program.cpp
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
#include "Program.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include "GLSL.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
Program::Program() :
|
||||||
|
vShaderName(""),
|
||||||
|
fShaderName(""),
|
||||||
|
pid(0),
|
||||||
|
verbose(true)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Program::~Program()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Program::setShaderNames(const string &v, const string &f)
|
||||||
|
{
|
||||||
|
vShaderName = v;
|
||||||
|
fShaderName = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Program::init()
|
||||||
|
{
|
||||||
|
GLint rc;
|
||||||
|
|
||||||
|
// Create shader handles
|
||||||
|
GLuint VS = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
GLuint FS = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
|
||||||
|
// Read shader sources
|
||||||
|
const char *vshader = GLSL::textFileRead(vShaderName.c_str());
|
||||||
|
const char *fshader = GLSL::textFileRead(fShaderName.c_str());
|
||||||
|
glShaderSource(VS, 1, &vshader, NULL);
|
||||||
|
glShaderSource(FS, 1, &fshader, NULL);
|
||||||
|
|
||||||
|
// Compile vertex shader
|
||||||
|
glCompileShader(VS);
|
||||||
|
glGetShaderiv(VS, GL_COMPILE_STATUS, &rc);
|
||||||
|
if(!rc) {
|
||||||
|
if(isVerbose()) {
|
||||||
|
GLSL::printShaderInfoLog(VS);
|
||||||
|
cout << "Error compiling vertex shader " << vShaderName << endl;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compile fragment shader
|
||||||
|
glCompileShader(FS);
|
||||||
|
glGetShaderiv(FS, GL_COMPILE_STATUS, &rc);
|
||||||
|
if(!rc) {
|
||||||
|
if(isVerbose()) {
|
||||||
|
GLSL::printShaderInfoLog(FS);
|
||||||
|
cout << "Error compiling fragment shader " << fShaderName << endl;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the program and link
|
||||||
|
pid = glCreateProgram();
|
||||||
|
glAttachShader(pid, VS);
|
||||||
|
glAttachShader(pid, FS);
|
||||||
|
glLinkProgram(pid);
|
||||||
|
glGetProgramiv(pid, GL_LINK_STATUS, &rc);
|
||||||
|
if(!rc) {
|
||||||
|
if(isVerbose()) {
|
||||||
|
GLSL::printProgramInfoLog(pid);
|
||||||
|
cout << "Error linking shaders " << vShaderName << " and " << fShaderName << endl;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLSL::checkError(GET_FILE_LINE);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Program::bind()
|
||||||
|
{
|
||||||
|
glUseProgram(pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Program::unbind()
|
||||||
|
{
|
||||||
|
glUseProgram(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Program::addAttribute(const string &name)
|
||||||
|
{
|
||||||
|
attributes[name] = glGetAttribLocation(pid, name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Program::addUniform(const string &name)
|
||||||
|
{
|
||||||
|
uniforms[name] = glGetUniformLocation(pid, name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint Program::getAttribute(const string &name) const
|
||||||
|
{
|
||||||
|
map<string,GLint>::const_iterator attribute = attributes.find(name.c_str());
|
||||||
|
if(attribute == attributes.end()) {
|
||||||
|
if(isVerbose()) {
|
||||||
|
cout << name << " is not an attribute variable" << endl;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return attribute->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint Program::getUniform(const string &name) const
|
||||||
|
{
|
||||||
|
map<string,GLint>::const_iterator uniform = uniforms.find(name.c_str());
|
||||||
|
if(uniform == uniforms.end()) {
|
||||||
|
if(isVerbose()) {
|
||||||
|
cout << name << " is not a uniform variable" << endl;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return uniform->second;
|
||||||
|
}
|
44
A4/shadow8t4/shadow8t4/src/Program.h
Normal file
44
A4/shadow8t4/shadow8t4/src/Program.h
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef __Program__
|
||||||
|
#define __Program__
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#define GLEW_STATIC
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An OpenGL Program (vertex and fragment shaders)
|
||||||
|
*/
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Program();
|
||||||
|
virtual ~Program();
|
||||||
|
|
||||||
|
void setVerbose(bool v) { verbose = v; }
|
||||||
|
bool isVerbose() const { return verbose; }
|
||||||
|
|
||||||
|
void setShaderNames(const std::string &v, const std::string &f);
|
||||||
|
virtual bool init();
|
||||||
|
virtual void bind();
|
||||||
|
virtual void unbind();
|
||||||
|
|
||||||
|
void addAttribute(const std::string &name);
|
||||||
|
void addUniform(const std::string &name);
|
||||||
|
GLint getAttribute(const std::string &name) const;
|
||||||
|
GLint getUniform(const std::string &name) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string vShaderName;
|
||||||
|
std::string fShaderName;
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLuint pid;
|
||||||
|
std::map<std::string,GLint> attributes;
|
||||||
|
std::map<std::string,GLint> uniforms;
|
||||||
|
bool verbose;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
165
A4/shadow8t4/shadow8t4/src/Shape.cpp
Normal file
165
A4/shadow8t4/shadow8t4/src/Shape.cpp
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
#include "Shape.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "GLSL.h"
|
||||||
|
#include "Program.h"
|
||||||
|
|
||||||
|
#define GLM_FORCE_RADIANS
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
#define TINYOBJLOADER_IMPLEMENTATION
|
||||||
|
#include "tiny_obj_loader.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
Shape::Shape() :
|
||||||
|
posBufID(0),
|
||||||
|
norBufID(0),
|
||||||
|
texBufID(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Shape::~Shape()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shape::loadMesh(const string &meshName)
|
||||||
|
{
|
||||||
|
// Load geometry
|
||||||
|
tinyobj::attrib_t attrib;
|
||||||
|
std::vector<tinyobj::shape_t> shapes;
|
||||||
|
std::vector<tinyobj::material_t> materials;
|
||||||
|
string errStr;
|
||||||
|
bool rc = tinyobj::LoadObj(&attrib, &shapes, &materials, &errStr, meshName.c_str());
|
||||||
|
if(!rc) {
|
||||||
|
cerr << errStr << endl;
|
||||||
|
} else {
|
||||||
|
// Some OBJ files have different indices for vertex positions, normals,
|
||||||
|
// and texture coordinates. For example, a cube corner vertex may have
|
||||||
|
// three different normals. Here, we are going to duplicate all such
|
||||||
|
// vertices.
|
||||||
|
// Loop over shapes
|
||||||
|
for(size_t s = 0; s < shapes.size(); s++) {
|
||||||
|
// Loop over faces (polygons)
|
||||||
|
size_t index_offset = 0;
|
||||||
|
for(size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++) {
|
||||||
|
size_t fv = shapes[s].mesh.num_face_vertices[f];
|
||||||
|
// Loop over vertices in the face.
|
||||||
|
for(size_t v = 0; v < fv; v++) {
|
||||||
|
// access to vertex
|
||||||
|
tinyobj::index_t idx = shapes[s].mesh.indices[index_offset + v];
|
||||||
|
posBuf.push_back(attrib.vertices[3*idx.vertex_index+0]);
|
||||||
|
posBuf.push_back(attrib.vertices[3*idx.vertex_index+1]);
|
||||||
|
posBuf.push_back(attrib.vertices[3*idx.vertex_index+2]);
|
||||||
|
if(!attrib.normals.empty()) {
|
||||||
|
norBuf.push_back(attrib.normals[3*idx.normal_index+0]);
|
||||||
|
norBuf.push_back(attrib.normals[3*idx.normal_index+1]);
|
||||||
|
norBuf.push_back(attrib.normals[3*idx.normal_index+2]);
|
||||||
|
}
|
||||||
|
if(!attrib.texcoords.empty()) {
|
||||||
|
texBuf.push_back(attrib.texcoords[2*idx.texcoord_index+0]);
|
||||||
|
texBuf.push_back(attrib.texcoords[2*idx.texcoord_index+1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index_offset += fv;
|
||||||
|
// per-face material (IGNORE)
|
||||||
|
shapes[s].mesh.material_ids[f];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shape::fitToUnitBox()
|
||||||
|
{
|
||||||
|
// Scale the vertex positions so that they fit within [-1, +1] in all three dimensions.
|
||||||
|
glm::vec3 vmin(posBuf[0], posBuf[1], posBuf[2]);
|
||||||
|
glm::vec3 vmax(posBuf[0], posBuf[1], posBuf[2]);
|
||||||
|
for(int i = 0; i < (int)posBuf.size(); i += 3) {
|
||||||
|
glm::vec3 v(posBuf[i], posBuf[i+1], posBuf[i+2]);
|
||||||
|
vmin.x = min(vmin.x, v.x);
|
||||||
|
vmin.y = min(vmin.y, v.y);
|
||||||
|
vmin.z = min(vmin.z, v.z);
|
||||||
|
vmax.x = max(vmax.x, v.x);
|
||||||
|
vmax.y = max(vmax.y, v.y);
|
||||||
|
vmax.z = max(vmax.z, v.z);
|
||||||
|
}
|
||||||
|
glm::vec3 center = 0.5f*(vmin + vmax);
|
||||||
|
glm::vec3 diff = vmax - vmin;
|
||||||
|
float diffmax = diff.x;
|
||||||
|
diffmax = max(diffmax, diff.y);
|
||||||
|
diffmax = max(diffmax, diff.z);
|
||||||
|
float scale = 1.0f / diffmax;
|
||||||
|
for(int i = 0; i < (int)posBuf.size(); i += 3) {
|
||||||
|
posBuf[i ] = (posBuf[i ] - center.x) * scale;
|
||||||
|
posBuf[i+1] = (posBuf[i+1] - center.y) * scale;
|
||||||
|
posBuf[i+2] = (posBuf[i+2] - center.z) * scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shape::init()
|
||||||
|
{
|
||||||
|
// Send the position array to the GPU
|
||||||
|
glGenBuffers(1, &posBufID);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, posBufID);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, posBuf.size()*sizeof(float), &posBuf[0], GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
// Send the normal array to the GPU
|
||||||
|
if(!norBuf.empty()) {
|
||||||
|
glGenBuffers(1, &norBufID);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, norBufID);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, norBuf.size()*sizeof(float), &norBuf[0], GL_STATIC_DRAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the texture array to the GPU
|
||||||
|
if(!texBuf.empty()) {
|
||||||
|
glGenBuffers(1, &texBufID);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, texBufID);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, texBuf.size()*sizeof(float), &texBuf[0], GL_STATIC_DRAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unbind the arrays
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
GLSL::checkError(GET_FILE_LINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shape::draw(const shared_ptr<Program> prog) const
|
||||||
|
{
|
||||||
|
// Bind position buffer
|
||||||
|
int h_pos = prog->getAttribute("aPos");
|
||||||
|
glEnableVertexAttribArray(h_pos);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, posBufID);
|
||||||
|
glVertexAttribPointer(h_pos, 3, GL_FLOAT, GL_FALSE, 0, (const void *)0);
|
||||||
|
|
||||||
|
// Bind normal buffer
|
||||||
|
int h_nor = prog->getAttribute("aNor");
|
||||||
|
if(h_nor != -1 && norBufID != 0) {
|
||||||
|
glEnableVertexAttribArray(h_nor);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, norBufID);
|
||||||
|
glVertexAttribPointer(h_nor, 3, GL_FLOAT, GL_FALSE, 0, (const void *)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind texcoords buffer
|
||||||
|
int h_tex = prog->getAttribute("aTex");
|
||||||
|
if(h_tex != -1 && texBufID != 0) {
|
||||||
|
glEnableVertexAttribArray(h_tex);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, texBufID);
|
||||||
|
glVertexAttribPointer(h_tex, 2, GL_FLOAT, GL_FALSE, 0, (const void *)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
int count = posBuf.size()/3; // number of indices to be rendered
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, count);
|
||||||
|
|
||||||
|
// Disable and unbind
|
||||||
|
if(h_tex != -1) {
|
||||||
|
glDisableVertexAttribArray(h_tex);
|
||||||
|
}
|
||||||
|
if(h_nor != -1) {
|
||||||
|
glDisableVertexAttribArray(h_nor);
|
||||||
|
}
|
||||||
|
glDisableVertexAttribArray(h_pos);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
GLSL::checkError(GET_FILE_LINE);
|
||||||
|
}
|
37
A4/shadow8t4/shadow8t4/src/Shape.h
Normal file
37
A4/shadow8t4/shadow8t4/src/Shape.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef _SHAPE_H_
|
||||||
|
#define _SHAPE_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class Program;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A shape defined by a list of triangles
|
||||||
|
* - posBuf should be of length 3*ntris
|
||||||
|
* - norBuf should be of length 3*ntris (if normals are available)
|
||||||
|
* - texBuf should be of length 2*ntris (if texture coords are available)
|
||||||
|
* posBufID, norBufID, and texBufID are OpenGL buffer identifiers.
|
||||||
|
*/
|
||||||
|
class Shape
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Shape();
|
||||||
|
virtual ~Shape();
|
||||||
|
void loadMesh(const std::string &meshName);
|
||||||
|
void fitToUnitBox();
|
||||||
|
void init();
|
||||||
|
void draw(const std::shared_ptr<Program> prog) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<float> posBuf;
|
||||||
|
std::vector<float> norBuf;
|
||||||
|
std::vector<float> texBuf;
|
||||||
|
unsigned posBufID;
|
||||||
|
unsigned norBufID;
|
||||||
|
unsigned texBufID;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
462
A4/shadow8t4/shadow8t4/src/main.cpp
Normal file
462
A4/shadow8t4/shadow8t4/src/main.cpp
Normal file
|
@ -0,0 +1,462 @@
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
#define _USE_MATH_DEFINES
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#define GLEW_STATIC
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#define GLM_FORCE_RADIANS
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
#include "MyCamera.h"
|
||||||
|
#include "GLSL.h"
|
||||||
|
#include "MatrixStack.h"
|
||||||
|
#include "Program.h"
|
||||||
|
#include "Shape.h"
|
||||||
|
#include "Material.h"
|
||||||
|
#include "Light.h"
|
||||||
|
#include "Component.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
GLFWwindow *window; // Main application window
|
||||||
|
string RESOURCE_DIR = "./"; // Where the resources are loaded from
|
||||||
|
|
||||||
|
shared_ptr<Camera> camera;
|
||||||
|
shared_ptr<Program> prog;
|
||||||
|
shared_ptr<Program> sprog;
|
||||||
|
shared_ptr<Shape> shape;
|
||||||
|
shared_ptr<Shape> sphere;
|
||||||
|
shared_ptr<Shape> cube;
|
||||||
|
shared_ptr<Shape> teapot;
|
||||||
|
|
||||||
|
bool keyToggles[256] = {false}; // only for English keyboards!
|
||||||
|
|
||||||
|
vector<Material> materials;
|
||||||
|
Light l[2];
|
||||||
|
int ind = 0;
|
||||||
|
int lind = 0;
|
||||||
|
int sind = 0;
|
||||||
|
|
||||||
|
unsigned int pid0;
|
||||||
|
unsigned int pid1;
|
||||||
|
|
||||||
|
//Variables affecting the assortment of shapes.
|
||||||
|
unsigned int n = 10;
|
||||||
|
float s = 1.0;
|
||||||
|
float tx = 1.0;
|
||||||
|
float ty = 1.0;
|
||||||
|
float tz = 1.0;
|
||||||
|
vector<Component> shapes;
|
||||||
|
|
||||||
|
// This function is called when a GLFW error occurs
|
||||||
|
static void error_callback(int error, const char *description)
|
||||||
|
{
|
||||||
|
cerr << description << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is called when a key is pressed
|
||||||
|
static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods)
|
||||||
|
{
|
||||||
|
if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
|
||||||
|
glfwSetWindowShouldClose(window, GL_TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is called when the mouse is clicked
|
||||||
|
static void mouse_button_callback(GLFWwindow *window, int button, int action, int mods)
|
||||||
|
{
|
||||||
|
// Get the current mouse position.
|
||||||
|
double xmouse, ymouse;
|
||||||
|
glfwGetCursorPos(window, &xmouse, &ymouse);
|
||||||
|
// Get current window size.
|
||||||
|
int width, height;
|
||||||
|
glfwGetWindowSize(window, &width, &height);
|
||||||
|
if(action == GLFW_PRESS) {
|
||||||
|
bool shift = (mods & GLFW_MOD_SHIFT) != 0;
|
||||||
|
bool ctrl = (mods & GLFW_MOD_CONTROL) != 0;
|
||||||
|
bool alt = (mods & GLFW_MOD_ALT) != 0;
|
||||||
|
camera->mouseClicked((float)xmouse, (float)ymouse, shift, ctrl, alt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is called when the mouse moves
|
||||||
|
static void cursor_position_callback(GLFWwindow* window, double xmouse, double ymouse)
|
||||||
|
{
|
||||||
|
int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT);
|
||||||
|
if(state == GLFW_PRESS) {
|
||||||
|
camera->mouseMoved((float)xmouse, (float)ymouse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void char_callback(GLFWwindow *window, unsigned int key)
|
||||||
|
{
|
||||||
|
keyToggles[key] = !keyToggles[key];
|
||||||
|
char cp = (char)key;
|
||||||
|
|
||||||
|
if(cp == 'W' || cp == 'w')
|
||||||
|
{
|
||||||
|
vec3 temp(0.0f, 0.0f, -0.1f);
|
||||||
|
camera->transpose(temp);
|
||||||
|
}
|
||||||
|
if(cp == 'A' || cp == 'a')
|
||||||
|
{
|
||||||
|
vec3 temp(-0.1f, 0.0f, 0.0f);
|
||||||
|
camera->transpose(temp);
|
||||||
|
}
|
||||||
|
if(cp == 'S' || cp == 's')
|
||||||
|
{
|
||||||
|
vec3 temp(0.0f, 0.0f, 0.1f);
|
||||||
|
camera->transpose(temp);
|
||||||
|
}
|
||||||
|
if(cp == 'D' || cp == 'd')
|
||||||
|
{
|
||||||
|
vec3 temp(0.1f, 0.0f, 0.0f);
|
||||||
|
camera->transpose(temp);
|
||||||
|
}
|
||||||
|
if(cp == 'X')
|
||||||
|
{
|
||||||
|
glm::vec3 temp = l[lind].getPos();
|
||||||
|
l[lind].setPos(glm::vec3(temp.x + 0.1f, temp.y, temp.z));
|
||||||
|
}
|
||||||
|
if(cp == 'x')
|
||||||
|
{
|
||||||
|
glm::vec3 temp = l[lind].getPos();
|
||||||
|
l[lind].setPos(glm::vec3(temp.x - 0.1f, temp.y, temp.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cp == 'Y')
|
||||||
|
{
|
||||||
|
glm::vec3 temp = l[lind].getPos();
|
||||||
|
l[lind].setPos(glm::vec3(temp.x, temp.y + 0.1f, temp.z));
|
||||||
|
}
|
||||||
|
if(cp == 'y')
|
||||||
|
{
|
||||||
|
glm::vec3 temp = l[lind].getPos();
|
||||||
|
l[lind].setPos(glm::vec3(temp.x, temp.y - 0.1f, temp.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cp == 'Z')
|
||||||
|
{
|
||||||
|
glm::vec3 temp = l[lind].getPos();
|
||||||
|
l[lind].setPos(glm::vec3(temp.x, temp.y, temp.z + 0.1f));
|
||||||
|
}
|
||||||
|
if(cp == 'z')
|
||||||
|
{
|
||||||
|
glm::vec3 temp = l[lind].getPos();
|
||||||
|
l[lind].setPos(glm::vec3(temp.x, temp.y, temp.z - 0.1f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the window is resized, capture the new size and reset the viewport
|
||||||
|
static void resize_callback(GLFWwindow *window, int width, int height)
|
||||||
|
{
|
||||||
|
glViewport(0, 0, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void createComponents()
|
||||||
|
{
|
||||||
|
for(unsigned int i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
Component temp;
|
||||||
|
|
||||||
|
temp.s.x = s;
|
||||||
|
temp.s.y = s;
|
||||||
|
temp.s.z = s;
|
||||||
|
|
||||||
|
temp.tp.x = 0;
|
||||||
|
temp.tp.y = 0;
|
||||||
|
temp.tp.z = -tz*((float)i);
|
||||||
|
|
||||||
|
temp.t.x = 1.0/2.0;
|
||||||
|
temp.t.y = 0;
|
||||||
|
temp.t.z = -1.0/2.0;
|
||||||
|
|
||||||
|
temp.sid = rand()%3;
|
||||||
|
|
||||||
|
shapes.push_back(temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void createMaterials()
|
||||||
|
{
|
||||||
|
Material m1;
|
||||||
|
|
||||||
|
materials.push_back(m1);
|
||||||
|
materials.push_back(m1);
|
||||||
|
materials.push_back(m1);
|
||||||
|
materials.push_back(m1);
|
||||||
|
materials.push_back(m1);
|
||||||
|
materials.push_back(m1);
|
||||||
|
materials.push_back(m1);
|
||||||
|
materials.push_back(m1);
|
||||||
|
materials.push_back(m1);
|
||||||
|
materials.push_back(m1);
|
||||||
|
materials.push_back(m1);
|
||||||
|
|
||||||
|
materials[0].setMaterial(glm::vec3(0.0f, 0.0f, 0.4f), glm::vec3(0.2f, 0.1f, 0.7f), glm::vec3(0.5f, 0.5f, 0.5f), 200.0f);
|
||||||
|
materials[1].setMaterial(glm::vec3(0.3f, 0.3f, 0.4f), glm::vec3(0.2f, 0.2f, 0.3f), glm::vec3(0.1f, 0.1f, 0.1f), 10.0f);
|
||||||
|
materials[2].setMaterial(glm::vec3(0.2f, 0.2f, 0.2f), glm::vec3(0.8f, 0.7f, 0.7f), glm::vec3(1.0f, 0.9f, 0.8f), 200.0f);
|
||||||
|
materials[3].setMaterial(glm::vec3(0.2f, 0.8f, 0.2f), glm::vec3(0.1f, 0.7f, 0.2f), glm::vec3(0.2f, 0.2f, 0.2f), 100.0f);
|
||||||
|
materials[4].setMaterial(glm::vec3(0.8f, 0.2f, 0.2f), glm::vec3(0.7f, 0.1f, 0.1f), glm::vec3(0.3f, 0.3f, 0.3f), 100.0f);
|
||||||
|
materials[5].setMaterial(glm::vec3(0.7f, 0.7f, 0.1f), glm::vec3(0.6f, 0.5f, 0.2f), glm::vec3(0.1f, 0.1f, 0.1f), 50.0f);
|
||||||
|
materials[6].setMaterial(glm::vec3(0.5f, 0.1f, 0.1f), glm::vec3(0.7f, 0.1f, 0.1f), glm::vec3(0.2f, 0.2f, 0.2f), 50.0f);
|
||||||
|
materials[7].setMaterial(glm::vec3(0.2f, 0.8f, 0.8f), glm::vec3(0.1f, 0.7f, 0.6f), glm::vec3(0.5f, 0.5f, 0.5f), 120.0f);
|
||||||
|
materials[8].setMaterial(glm::vec3(0.3f, 0.6f, 0.3f), glm::vec3(0.3f, 0.6f, 0.3f), glm::vec3(0.7f, 0.7f, 0.7f), 20.0f);
|
||||||
|
materials[9].setMaterial(glm::vec3(0.8f, 0.2f, 0.7f), glm::vec3(0.7f, 0.2f, 0.8f), glm::vec3(0.5f, 0.5f, 0.5f), 200.0f);
|
||||||
|
materials[10].setMaterial(glm::vec3(0.2f, 0.5f, 0.2f), glm::vec3(0.2f, 0.5f, 0.2f), glm::vec3(0.5f, 0.5f, 0.5f), 10.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void makeGround()
|
||||||
|
{
|
||||||
|
Component temp;
|
||||||
|
|
||||||
|
temp.tp.x = 0.0f;
|
||||||
|
temp.tp.y = -1.0f;
|
||||||
|
temp.tp.z = 0.0f;
|
||||||
|
|
||||||
|
temp.s.x = 100.0f;
|
||||||
|
temp.s.y = 0.0f;
|
||||||
|
temp.s.z = 100.0f;
|
||||||
|
|
||||||
|
temp.t.x = 0.0f;
|
||||||
|
temp.t.y = 0.0f;
|
||||||
|
temp.t.z = 0.0f;
|
||||||
|
|
||||||
|
temp.sid = 2;
|
||||||
|
|
||||||
|
shapes.push_back(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is called once to initialize the scene and OpenGL
|
||||||
|
static void init()
|
||||||
|
{
|
||||||
|
// Initialize time.
|
||||||
|
glfwSetTime(0.0);
|
||||||
|
|
||||||
|
// Set background color.
|
||||||
|
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
// Enable z-buffer test.
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
sprog = make_shared<Program>();
|
||||||
|
sprog->setShaderNames(RESOURCE_DIR + "vert.glsl", RESOURCE_DIR + "sil.glsl");
|
||||||
|
sprog->setVerbose(false);
|
||||||
|
sprog->init();
|
||||||
|
sprog->addAttribute("aPos");
|
||||||
|
sprog->addAttribute("aNor");
|
||||||
|
sprog->addUniform("MV");
|
||||||
|
sprog->addUniform("P");
|
||||||
|
|
||||||
|
prog = make_shared<Program>();
|
||||||
|
prog->setShaderNames(RESOURCE_DIR + "vert.glsl", RESOURCE_DIR + "frag.glsl");
|
||||||
|
prog->setVerbose(false);
|
||||||
|
prog->init();
|
||||||
|
prog->addAttribute("aPos");
|
||||||
|
prog->addAttribute("aNor");
|
||||||
|
prog->addUniform("MV");
|
||||||
|
prog->addUniform("P");
|
||||||
|
prog->addUniform("MVL");
|
||||||
|
prog->addUniform("lightPos1");
|
||||||
|
prog->addUniform("lightPos2");
|
||||||
|
prog->addUniform("ka");
|
||||||
|
prog->addUniform("kd");
|
||||||
|
prog->addUniform("ks");
|
||||||
|
prog->addUniform("s");
|
||||||
|
prog->addUniform("i1");
|
||||||
|
prog->addUniform("i2");
|
||||||
|
|
||||||
|
camera = make_shared<Camera>();
|
||||||
|
camera->setInitDistance(2.0f);
|
||||||
|
|
||||||
|
shape = make_shared<Shape>();
|
||||||
|
shape->loadMesh(RESOURCE_DIR + "bunny.obj");
|
||||||
|
shape->fitToUnitBox();
|
||||||
|
shape->init();
|
||||||
|
|
||||||
|
sphere = make_shared<Shape>();
|
||||||
|
sphere->loadMesh(RESOURCE_DIR + "sphere.obj");
|
||||||
|
sphere->fitToUnitBox();
|
||||||
|
sphere->init();
|
||||||
|
|
||||||
|
cube = make_shared<Shape>();
|
||||||
|
cube->loadMesh(RESOURCE_DIR + "cube.obj");
|
||||||
|
cube->fitToUnitBox();
|
||||||
|
cube->init();
|
||||||
|
|
||||||
|
teapot = make_shared<Shape>();
|
||||||
|
teapot->loadMesh(RESOURCE_DIR + "teapot.obj");
|
||||||
|
teapot->fitToUnitBox();
|
||||||
|
teapot->init();
|
||||||
|
|
||||||
|
createMaterials();
|
||||||
|
|
||||||
|
Light l1(glm::vec3(1.0f, 1.0f, 1.0f), 0.8f);
|
||||||
|
Light l2(glm::vec3(-1.0f, 1.0f, 1.0f), 0.2f);
|
||||||
|
l[0] = l1;
|
||||||
|
l[1] = l2;
|
||||||
|
|
||||||
|
// separate function to create shapes.
|
||||||
|
createComponents();
|
||||||
|
|
||||||
|
makeGround();
|
||||||
|
|
||||||
|
GLSL::checkError(GET_FILE_LINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is called every frame to draw the scene.
|
||||||
|
static void render()
|
||||||
|
{
|
||||||
|
// Clear framebuffer.
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
if(keyToggles[(unsigned)'c']) {
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
}
|
||||||
|
// Get current frame buffer size.
|
||||||
|
int width, height;
|
||||||
|
glfwGetFramebufferSize(window, &width, &height);
|
||||||
|
camera->setAspect((float)width/(float)height);
|
||||||
|
|
||||||
|
// Matrix stacks
|
||||||
|
auto P = make_shared<MatrixStack>();
|
||||||
|
auto MV = make_shared<MatrixStack>();
|
||||||
|
|
||||||
|
// Apply camera transforms
|
||||||
|
P->pushMatrix();
|
||||||
|
camera->applyProjectionMatrix(P);
|
||||||
|
MV->pushMatrix();
|
||||||
|
camera->applyViewMatrix(MV);
|
||||||
|
|
||||||
|
prog->bind();
|
||||||
|
|
||||||
|
mat4 templ;
|
||||||
|
templ[0] = vec4(1.0, 0, 0, 0);
|
||||||
|
templ[1] = vec4(0, 1.0, 0, 0);
|
||||||
|
templ[2] = vec4(0, 0, 1.0, 0);
|
||||||
|
templ[3] = vec4(l[0].getPos().x, l[0].getPos().y, l[0].getPos().z, 1.0);
|
||||||
|
templ = MV->topMatrix()*templ;
|
||||||
|
glUniformMatrix4fv(prog->getUniform("MVL"), 1, GL_FALSE, glm::value_ptr(templ));
|
||||||
|
|
||||||
|
Component light;
|
||||||
|
|
||||||
|
light.t.x = l[0].getPos().x;
|
||||||
|
light.t.y = l[0].getPos().y;
|
||||||
|
light.t.z = l[0].getPos().z;
|
||||||
|
|
||||||
|
glUniform3f(prog->getUniform("lightPos1"), l[0].getPos().x, l[0].getPos().y, l[0].getPos().z);
|
||||||
|
glUniform3f(prog->getUniform("ka"), 0.95, 1.0, 0.35);
|
||||||
|
glUniform3f(prog->getUniform("kd"), 1.0, 1.0, 1.0);
|
||||||
|
glUniform3f(prog->getUniform("ks"), 1.0, 1.0, 1.0);
|
||||||
|
glUniform1f(prog->getUniform("s"), 1.0);
|
||||||
|
|
||||||
|
light.draw(MV, P, sphere, prog);
|
||||||
|
prog->unbind();
|
||||||
|
|
||||||
|
glm::vec3 ambient = materials.at(0).getAmbient();
|
||||||
|
glm::vec3 diffuse = materials.at(0).getDiffuse();
|
||||||
|
glm::vec3 specular = materials.at(0).getSpecular();
|
||||||
|
float shine = materials.at(0).getShiny();
|
||||||
|
for(unsigned int i = 0; i < n + 1; i++)
|
||||||
|
{
|
||||||
|
prog->bind();
|
||||||
|
ambient = materials.at(i).getAmbient();
|
||||||
|
diffuse = materials.at(i).getDiffuse();
|
||||||
|
specular = materials.at(i).getSpecular();
|
||||||
|
shine = materials.at(i).getShiny();
|
||||||
|
|
||||||
|
glUniform3f(prog->getUniform("ka"), ambient.r, ambient.g, ambient.b);
|
||||||
|
glUniform3f(prog->getUniform("kd"), diffuse.r, diffuse.g, diffuse.b);
|
||||||
|
glUniform3f(prog->getUniform("ks"), specular.r, specular.g, specular.b);
|
||||||
|
glUniform1f(prog->getUniform("s"), shine);
|
||||||
|
glUniform1f(prog->getUniform("i1"), l[0].getIntensity());
|
||||||
|
glUniform1f(prog->getUniform("i2"), l[1].getIntensity());
|
||||||
|
|
||||||
|
switch(shapes.at(i).sid)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
shapes.at(i).draw(MV, P, shape, prog);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
shapes.at(i).draw(MV, P, teapot, prog);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
shapes.at(i).draw(MV, P, cube, prog);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
shapes.at(i).draw(MV, P, shape, prog);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
prog->unbind();
|
||||||
|
}
|
||||||
|
MV->popMatrix();
|
||||||
|
P->popMatrix();
|
||||||
|
|
||||||
|
GLSL::checkError(GET_FILE_LINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if(argc < 2) {
|
||||||
|
cout << "Please specify the resource directory." << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
RESOURCE_DIR = argv[1] + string("/");
|
||||||
|
|
||||||
|
// Set error callback.
|
||||||
|
glfwSetErrorCallback(error_callback);
|
||||||
|
// Initialize the library.
|
||||||
|
if(!glfwInit()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// Create a windowed mode window and its OpenGL context.
|
||||||
|
window = glfwCreateWindow(640, 480, "Alex Huddleston Assignment 4", NULL, NULL);
|
||||||
|
if(!window) {
|
||||||
|
glfwTerminate();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// Make the window's context current.
|
||||||
|
glfwMakeContextCurrent(window);
|
||||||
|
// Initialize GLEW.
|
||||||
|
glewExperimental = true;
|
||||||
|
if(glewInit() != GLEW_OK) {
|
||||||
|
cerr << "Failed to initialize GLEW" << endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
glGetError(); // A bug in glewInit() causes an error that we can safely ignore.
|
||||||
|
cout << "OpenGL version: " << glGetString(GL_VERSION) << endl;
|
||||||
|
cout << "GLSL version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << endl;
|
||||||
|
GLSL::checkVersion();
|
||||||
|
// Set vsync.
|
||||||
|
glfwSwapInterval(1);
|
||||||
|
// Set keyboard callback.
|
||||||
|
glfwSetKeyCallback(window, key_callback);
|
||||||
|
// Set char callback.
|
||||||
|
glfwSetCharCallback(window, char_callback);
|
||||||
|
// Set cursor position callback.
|
||||||
|
glfwSetCursorPosCallback(window, cursor_position_callback);
|
||||||
|
// Set mouse button callback.
|
||||||
|
glfwSetMouseButtonCallback(window, mouse_button_callback);
|
||||||
|
// Set the window resize call back.
|
||||||
|
glfwSetFramebufferSizeCallback(window, resize_callback);
|
||||||
|
// Initialize scene.
|
||||||
|
init();
|
||||||
|
// Loop until the user closes the window.
|
||||||
|
while(!glfwWindowShouldClose(window)) {
|
||||||
|
// Render scene.
|
||||||
|
render();
|
||||||
|
// Swap front and back buffers.
|
||||||
|
glfwSwapBuffers(window);
|
||||||
|
// Poll for and process events.
|
||||||
|
glfwPollEvents();
|
||||||
|
}
|
||||||
|
// Quit program.
|
||||||
|
glfwDestroyWindow(window);
|
||||||
|
glfwTerminate();
|
||||||
|
return 0;
|
||||||
|
}
|
1922
A4/shadow8t4/shadow8t4/src/tiny_obj_loader.h
Normal file
1922
A4/shadow8t4/shadow8t4/src/tiny_obj_loader.h
Normal file
File diff suppressed because it is too large
Load diff
68
A4/src/Camera.cpp
Normal file
68
A4/src/Camera.cpp
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
#include "Camera.h"
|
||||||
|
#include "MatrixStack.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
|
Camera::Camera() :
|
||||||
|
aspect(1.0f),
|
||||||
|
fovy(45.0f),
|
||||||
|
znear(0.1f),
|
||||||
|
zfar(1000.0f),
|
||||||
|
rotations(0.0, 0.0),
|
||||||
|
translations(0.0f, 0.0f, -5.0f),
|
||||||
|
rfactor(0.01f),
|
||||||
|
tfactor(0.001f),
|
||||||
|
sfactor(0.005f)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Camera::~Camera()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::mouseClicked(float x, float y, bool shift, bool ctrl, bool alt)
|
||||||
|
{
|
||||||
|
mousePrev.x = x;
|
||||||
|
mousePrev.y = y;
|
||||||
|
if(shift) {
|
||||||
|
state = Camera::TRANSLATE;
|
||||||
|
} else if(ctrl) {
|
||||||
|
state = Camera::SCALE;
|
||||||
|
} else {
|
||||||
|
state = Camera::ROTATE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::mouseMoved(float x, float y)
|
||||||
|
{
|
||||||
|
glm::vec2 mouseCurr(x, y);
|
||||||
|
glm::vec2 dv = mouseCurr - mousePrev;
|
||||||
|
switch(state) {
|
||||||
|
case Camera::ROTATE:
|
||||||
|
rotations += rfactor * dv;
|
||||||
|
break;
|
||||||
|
case Camera::TRANSLATE:
|
||||||
|
translations.x -= translations.z * tfactor * dv.x;
|
||||||
|
translations.y += translations.z * tfactor * dv.y;
|
||||||
|
break;
|
||||||
|
case Camera::SCALE:
|
||||||
|
translations.z *= (1.0f - sfactor * dv.y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mousePrev = mouseCurr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::applyProjectionMatrix(std::shared_ptr<MatrixStack> P) const
|
||||||
|
{
|
||||||
|
// Modify provided MatrixStack
|
||||||
|
P->multMatrix(glm::perspective(fovy, aspect, znear, zfar));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::applyViewMatrix(std::shared_ptr<MatrixStack> MV) const
|
||||||
|
{
|
||||||
|
MV->translate(translations);
|
||||||
|
MV->rotate(rotations.y, glm::vec3(1.0f, 0.0f, 0.0f));
|
||||||
|
MV->rotate(rotations.x, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
|
}
|
||||||
|
*/
|
49
A4/src/Camera.h
Normal file
49
A4/src/Camera.h
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
#pragma once
|
||||||
|
#ifndef __Camera__
|
||||||
|
#define __Camera__
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#define GLM_FORCE_RADIANS
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
class MatrixStack;
|
||||||
|
|
||||||
|
class Camera
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
ROTATE = 0,
|
||||||
|
TRANSLATE,
|
||||||
|
SCALE
|
||||||
|
};
|
||||||
|
|
||||||
|
Camera();
|
||||||
|
virtual ~Camera();
|
||||||
|
void setInitDistance(float z) { translations.z = -std::abs(z); }
|
||||||
|
void setAspect(float a) { aspect = a; };
|
||||||
|
void setRotationFactor(float f) { rfactor = f; };
|
||||||
|
void setTranslationFactor(float f) { tfactor = f; };
|
||||||
|
void setScaleFactor(float f) { sfactor = f; };
|
||||||
|
void mouseClicked(float x, float y, bool shift, bool ctrl, bool alt);
|
||||||
|
void mouseMoved(float x, float y);
|
||||||
|
void applyProjectionMatrix(std::shared_ptr<MatrixStack> P) const;
|
||||||
|
void applyViewMatrix(std::shared_ptr<MatrixStack> MV) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
float aspect;
|
||||||
|
float fovy;
|
||||||
|
float znear;
|
||||||
|
float zfar;
|
||||||
|
glm::vec2 rotations;
|
||||||
|
glm::vec3 translations;
|
||||||
|
glm::vec2 mousePrev;
|
||||||
|
int state;
|
||||||
|
float rfactor;
|
||||||
|
float tfactor;
|
||||||
|
float sfactor;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
*/
|
122
A4/src/Component.cpp
Normal file
122
A4/src/Component.cpp
Normal file
|
@ -0,0 +1,122 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include "Component.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
Component::Component()
|
||||||
|
{
|
||||||
|
parent = NULL;
|
||||||
|
selected = false;
|
||||||
|
t = vec3(0,0,0);
|
||||||
|
tp = vec3(0,0,0);
|
||||||
|
r = vec3(0,0,0);
|
||||||
|
s = vec3(1.0,1.0,1.0);
|
||||||
|
children.resize(0);
|
||||||
|
sid = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Component::Component(const Component& c)
|
||||||
|
{
|
||||||
|
parent = c.parent;
|
||||||
|
children = c.children;
|
||||||
|
selected = c.selected;
|
||||||
|
t = vec3(c.t.x, c.t.y, c.t.z);
|
||||||
|
tp = vec3(c.tp.x, c.tp.y, c.tp.z);
|
||||||
|
r = vec3(c.r.x, c.r.y, c.r.z);
|
||||||
|
s = vec3(c.s.x, c.s.y, c.s.z);
|
||||||
|
sid = c.sid;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Component::draw(shared_ptr<MatrixStack> MV, shared_ptr<MatrixStack> P, shared_ptr<Shape> S, shared_ptr<Program> Prog)
|
||||||
|
{
|
||||||
|
MV->pushMatrix();
|
||||||
|
MV->translate(tp.x, tp.y, tp.z);
|
||||||
|
MV->rotate(r.x, 1, 0, 0);
|
||||||
|
MV->rotate(r.y, 0, 1, 0);
|
||||||
|
MV->rotate(r.z, 0, 0, 1);
|
||||||
|
MV->translate(t.x, t.y, t.z);
|
||||||
|
for(unsigned int i = 0; i < children.size(); i++)
|
||||||
|
{
|
||||||
|
children[i].draw(MV, P, S, Prog);
|
||||||
|
}
|
||||||
|
if(selected)
|
||||||
|
{
|
||||||
|
MV->scale(1.1,1.1,1.1);
|
||||||
|
}
|
||||||
|
MV->scale(s.x,s.y,s.z);
|
||||||
|
glUniformMatrix4fv(Prog->getUniform("P"), 1, GL_FALSE, &P->topMatrix()[0][0]);
|
||||||
|
glUniformMatrix4fv(Prog->getUniform("MV"), 1, GL_FALSE, &MV->topMatrix()[0][0]);
|
||||||
|
S->draw(Prog);
|
||||||
|
MV->popMatrix();
|
||||||
|
}
|
||||||
|
|
||||||
|
Component& Component::getLastChild()
|
||||||
|
{
|
||||||
|
if(this->children.empty())
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
return this->children[this->children.size() - 1].getLastChild();
|
||||||
|
}
|
||||||
|
|
||||||
|
Component& Component::getPrevious(Component *addr)
|
||||||
|
{
|
||||||
|
if(children.empty())
|
||||||
|
{
|
||||||
|
if(parent != NULL)
|
||||||
|
{
|
||||||
|
return parent->getPrevious(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < this->children.size(); i++)
|
||||||
|
{
|
||||||
|
//return *this;
|
||||||
|
if(&children[i] == addr)
|
||||||
|
{
|
||||||
|
if(i > 0)
|
||||||
|
{
|
||||||
|
return children[i-1].getLastChild();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parent == NULL) {
|
||||||
|
return this->getLastChild();
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent->getPrevious(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
Component& Component::getNext(Component *addr)
|
||||||
|
{
|
||||||
|
if(addr == NULL)
|
||||||
|
{
|
||||||
|
if(!children.empty())
|
||||||
|
{
|
||||||
|
return children[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(unsigned int i = 0; i < this->children.size(); i++)
|
||||||
|
{
|
||||||
|
//return *this;
|
||||||
|
if(&children[i] == addr)
|
||||||
|
{
|
||||||
|
if(i+1 < children.size())
|
||||||
|
{
|
||||||
|
return children[i+1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parent == NULL) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent->getNext(this);
|
||||||
|
}
|
30
A4/src/Component.h
Normal file
30
A4/src/Component.h
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// Create Body Class
|
||||||
|
#include <vector>
|
||||||
|
#include "MatrixStack.h"
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <memory>
|
||||||
|
#include "Shape.h"
|
||||||
|
#include "Program.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace glm;
|
||||||
|
|
||||||
|
class Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Component *parent;
|
||||||
|
vector<Component> children;
|
||||||
|
bool selected;
|
||||||
|
vec3 t;
|
||||||
|
vec3 tp;
|
||||||
|
vec3 r;
|
||||||
|
vec3 s;
|
||||||
|
int sid; // used for storing which shape to render
|
||||||
|
|
||||||
|
Component();
|
||||||
|
Component(const Component& c);
|
||||||
|
void draw(shared_ptr<MatrixStack> MV, shared_ptr<MatrixStack> P, shared_ptr<Shape> S, shared_ptr<Program> Prog);
|
||||||
|
Component& getNext(Component *addr);
|
||||||
|
Component& getPrevious(Component *addr);
|
||||||
|
Component& getLastChild();
|
||||||
|
};
|
152
A4/src/GLSL.cpp
Normal file
152
A4/src/GLSL.cpp
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
//
|
||||||
|
// Many useful helper functions for GLSL shaders - gleaned from various sources including orange book
|
||||||
|
// Created by zwood on 2/21/10.
|
||||||
|
// Modified by sueda 10/15/15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "GLSL.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace GLSL {
|
||||||
|
|
||||||
|
const char * errorString(GLenum err)
|
||||||
|
{
|
||||||
|
switch(err) {
|
||||||
|
case GL_NO_ERROR:
|
||||||
|
return "No error";
|
||||||
|
case GL_INVALID_ENUM:
|
||||||
|
return "Invalid enum";
|
||||||
|
case GL_INVALID_VALUE:
|
||||||
|
return "Invalid value";
|
||||||
|
case GL_INVALID_OPERATION:
|
||||||
|
return "Invalid operation";
|
||||||
|
case GL_STACK_OVERFLOW:
|
||||||
|
return "Stack overflow";
|
||||||
|
case GL_STACK_UNDERFLOW:
|
||||||
|
return "Stack underflow";
|
||||||
|
case GL_OUT_OF_MEMORY:
|
||||||
|
return "Out of memory";
|
||||||
|
default:
|
||||||
|
return "No error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkVersion()
|
||||||
|
{
|
||||||
|
int major, minor;
|
||||||
|
major = minor = 0;
|
||||||
|
const char *verstr = (const char *)glGetString(GL_VERSION);
|
||||||
|
|
||||||
|
if((verstr == NULL) || (sscanf(verstr, "%d.%d", &major, &minor) != 2)) {
|
||||||
|
printf("Invalid GL_VERSION format %d.%d\n", major, minor);
|
||||||
|
}
|
||||||
|
if(major < 2) {
|
||||||
|
printf("This shader example will not work due to the installed Opengl version, which is %d.%d.\n", major, minor);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkError(const char *str)
|
||||||
|
{
|
||||||
|
GLenum glErr = glGetError();
|
||||||
|
if(glErr != GL_NO_ERROR) {
|
||||||
|
if(str) {
|
||||||
|
printf("%s: ", str);
|
||||||
|
}
|
||||||
|
printf("GL_ERROR = %s.\n", errorString(glErr));
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void printShaderInfoLog(GLuint shader)
|
||||||
|
{
|
||||||
|
GLint infologLength = 0;
|
||||||
|
GLint charsWritten = 0;
|
||||||
|
GLchar *infoLog = 0;
|
||||||
|
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infologLength);
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
|
||||||
|
if(infologLength > 0) {
|
||||||
|
infoLog = (GLchar *)malloc(infologLength);
|
||||||
|
if(infoLog == NULL) {
|
||||||
|
puts("ERROR: Could not allocate InfoLog buffer");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
glGetShaderInfoLog(shader, infologLength, &charsWritten, infoLog);
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
printf("Shader InfoLog:\n%s\n\n", infoLog);
|
||||||
|
free(infoLog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void printProgramInfoLog(GLuint program)
|
||||||
|
{
|
||||||
|
GLint infologLength = 0;
|
||||||
|
GLint charsWritten = 0;
|
||||||
|
GLchar *infoLog = 0;
|
||||||
|
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infologLength);
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
|
||||||
|
if(infologLength > 0) {
|
||||||
|
infoLog = (GLchar *)malloc(infologLength);
|
||||||
|
if(infoLog == NULL) {
|
||||||
|
puts("ERROR: Could not allocate InfoLog buffer");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
glGetProgramInfoLog(program, infologLength, &charsWritten, infoLog);
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
printf("Program InfoLog:\n%s\n\n", infoLog);
|
||||||
|
free(infoLog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *textFileRead(const char *fn)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char *content = NULL;
|
||||||
|
int count = 0;
|
||||||
|
if(fn != NULL) {
|
||||||
|
fp = fopen(fn,"rt");
|
||||||
|
if(fp != NULL) {
|
||||||
|
fseek(fp, 0, SEEK_END);
|
||||||
|
count = (int)ftell(fp);
|
||||||
|
rewind(fp);
|
||||||
|
if(count > 0) {
|
||||||
|
content = (char *)malloc(sizeof(char) * (count+1));
|
||||||
|
count = (int)fread(content,sizeof(char),count,fp);
|
||||||
|
content[count] = '\0';
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
} else {
|
||||||
|
printf("error loading %s\n", fn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
int textFileWrite(const char *fn, const char *s)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
int status = 0;
|
||||||
|
if(fn != NULL) {
|
||||||
|
fp = fopen(fn,"w");
|
||||||
|
if(fp != NULL) {
|
||||||
|
if(fwrite(s,sizeof(char),strlen(s),fp) == strlen(s)) {
|
||||||
|
status = 1;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
40
A4/src/GLSL.h
Normal file
40
A4/src/GLSL.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
//
|
||||||
|
// Many useful helper functions for GLSL shaders - gleaned from various sources including orange book
|
||||||
|
// Created by zwood on 2/21/10.
|
||||||
|
// Modified by sueda 10/15/15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef __GLSL__
|
||||||
|
#define __GLSL__
|
||||||
|
|
||||||
|
#define GLEW_STATIC
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// For printing out the current file and line number //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::string NumberToString(T x)
|
||||||
|
{
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << x;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GET_FILE_LINE (std::string(__FILE__) + ":" + NumberToString(__LINE__)).c_str()
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace GLSL {
|
||||||
|
|
||||||
|
void checkVersion();
|
||||||
|
void checkError(const char *str = 0);
|
||||||
|
void printProgramInfoLog(GLuint program);
|
||||||
|
void printShaderInfoLog(GLuint shader);
|
||||||
|
int textFileWrite(const char *filename, const char *s);
|
||||||
|
char *textFileRead(const char *filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
39
A4/src/Light.cpp
Normal file
39
A4/src/Light.cpp
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#include "Light.h"
|
||||||
|
|
||||||
|
Light::Light()
|
||||||
|
{
|
||||||
|
pos = glm::vec3(0.0f, 0.0f, 0.0f);
|
||||||
|
intensity = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Light::Light(const Light &l)
|
||||||
|
{
|
||||||
|
pos = l.pos;
|
||||||
|
intensity = l.intensity;
|
||||||
|
}
|
||||||
|
|
||||||
|
Light::Light(glm::vec3 p, float i)
|
||||||
|
{
|
||||||
|
pos = p;
|
||||||
|
intensity = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Light::setPos(glm::vec3 p)
|
||||||
|
{
|
||||||
|
this->pos = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Light::setIntensity(float i)
|
||||||
|
{
|
||||||
|
this->intensity = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 Light::getPos()
|
||||||
|
{
|
||||||
|
return this->pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Light::getIntensity()
|
||||||
|
{
|
||||||
|
return this->intensity;
|
||||||
|
}
|
27
A4/src/Light.h
Normal file
27
A4/src/Light.h
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
#include "GLSL.h"
|
||||||
|
#include "MyCamera.h"
|
||||||
|
#include "Shape.h"
|
||||||
|
#include "MatrixStack.h"
|
||||||
|
|
||||||
|
class Light
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
glm::vec3 pos;
|
||||||
|
float intensity;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Light();
|
||||||
|
Light(const Light &l);
|
||||||
|
Light(glm::vec3 p, float i);
|
||||||
|
void setPos(glm::vec3 p);
|
||||||
|
void setIntensity(float i);
|
||||||
|
glm::vec3 getPos();
|
||||||
|
float getIntensity();
|
||||||
|
};
|
39
A4/src/Material.cpp
Normal file
39
A4/src/Material.cpp
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#include "Material.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
Material::Material()
|
||||||
|
{
|
||||||
|
this->ca = glm::vec3(0.3f,0.3f,0.3f);
|
||||||
|
this->cd = glm::vec3(0.3f,0.3f,0.3f);
|
||||||
|
this->cs = glm::vec3(1.0f,1.0f,1.0f);
|
||||||
|
this->shine = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Material::setMaterial(glm::vec3 a, glm::vec3 d, glm::vec3 s, float sh)
|
||||||
|
{
|
||||||
|
this->ca = a;
|
||||||
|
this->cd = d;
|
||||||
|
this->cs = s;
|
||||||
|
this->shine = sh;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 Material::getAmbient()
|
||||||
|
{
|
||||||
|
return this->ca;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 Material::getDiffuse()
|
||||||
|
{
|
||||||
|
return this->cd;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 Material::getSpecular()
|
||||||
|
{
|
||||||
|
return this->cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
float Material::getShiny()
|
||||||
|
{
|
||||||
|
return this->shine;
|
||||||
|
}
|
41
A4/src/Material.h
Normal file
41
A4/src/Material.h
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
#include "GLSL.h"
|
||||||
|
#include "MyCamera.h"
|
||||||
|
#include "Shape.h"
|
||||||
|
#include "MatrixStack.h"
|
||||||
|
|
||||||
|
class Material
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
glm::vec3 ca;
|
||||||
|
glm::vec3 cd;
|
||||||
|
glm::vec3 cs;
|
||||||
|
float shine;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Material();
|
||||||
|
Material(const Material &m)
|
||||||
|
{
|
||||||
|
ca = m.ca;
|
||||||
|
cd = m.cd;
|
||||||
|
cs = m.cs;
|
||||||
|
}
|
||||||
|
Material(glm::vec3 a, glm::vec3 d, glm::vec3 s, float sh)
|
||||||
|
{
|
||||||
|
ca = a;
|
||||||
|
cd = d;
|
||||||
|
cs = s;
|
||||||
|
shine = sh;
|
||||||
|
}
|
||||||
|
void setMaterial(glm::vec3 a, glm::vec3 d, glm::vec3 s, float sh);
|
||||||
|
glm::vec3 getAmbient();
|
||||||
|
glm::vec3 getDiffuse();
|
||||||
|
glm::vec3 getSpecular();
|
||||||
|
float getShiny();
|
||||||
|
};
|
114
A4/src/MatrixStack.cpp
Normal file
114
A4/src/MatrixStack.cpp
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
#include "MatrixStack.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <cassert>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#define GLM_FORCE_RADIANS
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtx/transform.hpp>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
MatrixStack::MatrixStack()
|
||||||
|
{
|
||||||
|
mstack = make_shared< stack<glm::mat4> >();
|
||||||
|
mstack->push(glm::mat4(1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
MatrixStack::~MatrixStack()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::pushMatrix()
|
||||||
|
{
|
||||||
|
const glm::mat4 &top = mstack->top();
|
||||||
|
mstack->push(top);
|
||||||
|
assert(mstack->size() < 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::popMatrix()
|
||||||
|
{
|
||||||
|
assert(!mstack->empty());
|
||||||
|
mstack->pop();
|
||||||
|
// There should always be one matrix left.
|
||||||
|
assert(!mstack->empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::loadIdentity()
|
||||||
|
{
|
||||||
|
glm::mat4 &top = mstack->top();
|
||||||
|
top = glm::mat4(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::translate(const glm::vec3 &t)
|
||||||
|
{
|
||||||
|
glm::mat4 &top = mstack->top();
|
||||||
|
top *= glm::translate(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::translate(float x, float y, float z)
|
||||||
|
{
|
||||||
|
translate(glm::vec3(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::scale(const glm::vec3 &s)
|
||||||
|
{
|
||||||
|
glm::mat4 &top = mstack->top();
|
||||||
|
top *= glm::scale(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::scale(float x, float y, float z)
|
||||||
|
{
|
||||||
|
scale(glm::vec3(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::scale(float s)
|
||||||
|
{
|
||||||
|
scale(glm::vec3(s, s, s));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::rotate(float angle, const glm::vec3 &axis)
|
||||||
|
{
|
||||||
|
glm::mat4 &top = mstack->top();
|
||||||
|
top *= glm::rotate(angle, axis);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::rotate(float angle, float x, float y, float z)
|
||||||
|
{
|
||||||
|
rotate(angle, glm::vec3(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::multMatrix(const glm::mat4 &matrix)
|
||||||
|
{
|
||||||
|
glm::mat4 &top = mstack->top();
|
||||||
|
top *= matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
const glm::mat4 &MatrixStack::topMatrix() const
|
||||||
|
{
|
||||||
|
return mstack->top();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::print(const glm::mat4 &mat, const char *name)
|
||||||
|
{
|
||||||
|
if(name) {
|
||||||
|
printf("%s = [\n", name);
|
||||||
|
}
|
||||||
|
for(int i = 0; i < 4; ++i) {
|
||||||
|
for(int j = 0; j < 4; ++j) {
|
||||||
|
// mat[j] returns the jth column
|
||||||
|
printf("%- 5.2f ", mat[j][i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
if(name) {
|
||||||
|
printf("];");
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::print(const char *name) const
|
||||||
|
{
|
||||||
|
print(mstack->top(), name);
|
||||||
|
}
|
50
A4/src/MatrixStack.h
Normal file
50
A4/src/MatrixStack.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef _MatrixStack_H_
|
||||||
|
#define _MatrixStack_H_
|
||||||
|
|
||||||
|
#include <stack>
|
||||||
|
#include <memory>
|
||||||
|
#include <glm/fwd.hpp>
|
||||||
|
|
||||||
|
class MatrixStack
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MatrixStack();
|
||||||
|
virtual ~MatrixStack();
|
||||||
|
|
||||||
|
// glPushMatrix(): Copies the current matrix and adds it to the top of the stack
|
||||||
|
void pushMatrix();
|
||||||
|
// glPopMatrix(): Removes the top of the stack and sets the current matrix to be the matrix that is now on top
|
||||||
|
void popMatrix();
|
||||||
|
|
||||||
|
// glLoadIdentity(): Sets the top matrix to be the identity
|
||||||
|
void loadIdentity();
|
||||||
|
// glMultMatrix(): Right multiplies the top matrix
|
||||||
|
void multMatrix(const glm::mat4 &matrix);
|
||||||
|
|
||||||
|
// glTranslate(): Right multiplies the top matrix by a translation matrix
|
||||||
|
void translate(const glm::vec3 &trans);
|
||||||
|
void translate(float x, float y, float z);
|
||||||
|
// glScale(): Right multiplies the top matrix by a scaling matrix
|
||||||
|
void scale(const glm::vec3 &scale);
|
||||||
|
void scale(float x, float y, float z);
|
||||||
|
// glScale(): Right multiplies the top matrix by a scaling matrix
|
||||||
|
void scale(float size);
|
||||||
|
// glRotate(): Right multiplies the top matrix by a rotation matrix (angle in radians)
|
||||||
|
void rotate(float angle, const glm::vec3 &axis);
|
||||||
|
void rotate(float angle, float x, float y, float z);
|
||||||
|
|
||||||
|
// glGet(GL_MODELVIEW_MATRIX): Gets the top matrix
|
||||||
|
const glm::mat4 &topMatrix() const;
|
||||||
|
|
||||||
|
// Prints out the specified matrix
|
||||||
|
static void print(const glm::mat4 &mat, const char *name = 0);
|
||||||
|
// Prints out the top matrix
|
||||||
|
void print(const char *name = 0) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr< std::stack<glm::mat4> > mstack;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
88
A4/src/MyCamera.cpp
Normal file
88
A4/src/MyCamera.cpp
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
#include "MyCamera.h"
|
||||||
|
#include "MatrixStack.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
|
Camera::Camera() :
|
||||||
|
aspect(1.0f),
|
||||||
|
fovy(45.0f),
|
||||||
|
znear(0.1f),
|
||||||
|
zfar(1000.0f),
|
||||||
|
rotations(0.0, 0.0),
|
||||||
|
translations(0.0f, 0.0f, -5.0f),
|
||||||
|
rfactor(0.01f),
|
||||||
|
tfactor(0.001f),
|
||||||
|
sfactor(0.005f),
|
||||||
|
pos(0.0f, 0.0f, 1.0f),
|
||||||
|
pitch(0.0f),
|
||||||
|
yaw(0.0f)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Camera::~Camera()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::mouseClicked(float x, float y, bool shift, bool ctrl, bool alt)
|
||||||
|
{
|
||||||
|
mousePrev.x = x;
|
||||||
|
mousePrev.y = y;
|
||||||
|
if(shift) {
|
||||||
|
state = Camera::TRANSLATE;
|
||||||
|
} else if(ctrl) {
|
||||||
|
state = Camera::SCALE;
|
||||||
|
} else {
|
||||||
|
state = Camera::ROTATE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::mouseMoved(float x, float y)
|
||||||
|
{
|
||||||
|
glm::vec2 mouseCurr(x, y);
|
||||||
|
glm::vec2 dv = mouseCurr - mousePrev;
|
||||||
|
switch(state) {
|
||||||
|
case Camera::ROTATE:
|
||||||
|
rotations += rfactor * dv;
|
||||||
|
if(rotations.y > 0.6)
|
||||||
|
{
|
||||||
|
rotations.y = 0.6;
|
||||||
|
}
|
||||||
|
else if(rotations.y < -0.6)
|
||||||
|
{
|
||||||
|
rotations.y = -0.6;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case Camera::TRANSLATE:
|
||||||
|
translations.x -= translations.z * tfactor * dv.x;
|
||||||
|
translations.y += translations.z * tfactor * dv.y;
|
||||||
|
break;
|
||||||
|
case Camera::SCALE:
|
||||||
|
translations.z *= (1.0f - sfactor * dv.y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mousePrev = mouseCurr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::applyProjectionMatrix(std::shared_ptr<MatrixStack> P) const
|
||||||
|
{
|
||||||
|
// Modify provided MatrixStack
|
||||||
|
P->multMatrix(glm::perspective(fovy, aspect, znear, zfar));
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 Camera::getPos()
|
||||||
|
{
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::transpose(glm::vec3 t)
|
||||||
|
{
|
||||||
|
glm::vec3 target(sin(rotations.x), 0, cos(rotations.x));
|
||||||
|
pos -= (cross(glm::vec3(0, 1, 0), target))*t.x;
|
||||||
|
pos -= target*t.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::applyViewMatrix(std::shared_ptr<MatrixStack> MV) const
|
||||||
|
{
|
||||||
|
glm::vec3 target(sin(rotations.x), sin(rotations.y), cos(rotations.x));
|
||||||
|
MV->multMatrix(glm::lookAt(pos, pos + target, glm::vec3(0,1,0)));
|
||||||
|
}
|
54
A4/src/MyCamera.h
Normal file
54
A4/src/MyCamera.h
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef __MyCamera__
|
||||||
|
#define __MyCamera__
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#define GLM_FORCE_RADIANS
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
class MatrixStack;
|
||||||
|
|
||||||
|
class Camera
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
ROTATE = 0,
|
||||||
|
TRANSLATE,
|
||||||
|
SCALE
|
||||||
|
};
|
||||||
|
|
||||||
|
Camera();
|
||||||
|
virtual ~Camera();
|
||||||
|
void setInitDistance(float z) { translations.z = -std::abs(z); }
|
||||||
|
void setAspect(float a) { aspect = a; };
|
||||||
|
void setRotationFactor(float f) { rfactor = f; };
|
||||||
|
void setTranslationFactor(float f) { tfactor = f; };
|
||||||
|
void setScaleFactor(float f) { sfactor = f; };
|
||||||
|
void mouseClicked(float x, float y, bool shift, bool ctrl, bool alt);
|
||||||
|
void mouseMoved(float x, float y);
|
||||||
|
void applyProjectionMatrix(std::shared_ptr<MatrixStack> P) const;
|
||||||
|
void applyViewMatrix(std::shared_ptr<MatrixStack> MV) const;
|
||||||
|
glm::vec3 getPos();
|
||||||
|
void transpose(glm::vec3 t);
|
||||||
|
|
||||||
|
private:
|
||||||
|
float aspect;
|
||||||
|
float fovy;
|
||||||
|
float znear;
|
||||||
|
float zfar;
|
||||||
|
glm::vec2 rotations;
|
||||||
|
glm::vec3 translations;
|
||||||
|
glm::vec2 mousePrev;
|
||||||
|
int state;
|
||||||
|
float rfactor;
|
||||||
|
float tfactor;
|
||||||
|
float sfactor;
|
||||||
|
|
||||||
|
// TODO: Implement these
|
||||||
|
glm::vec3 pos;
|
||||||
|
float pitch; // Preliminarily making these floats
|
||||||
|
float yaw; // to hold angles.
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
126
A4/src/Program.cpp
Normal file
126
A4/src/Program.cpp
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
#include "Program.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include "GLSL.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
Program::Program() :
|
||||||
|
vShaderName(""),
|
||||||
|
fShaderName(""),
|
||||||
|
pid(0),
|
||||||
|
verbose(true)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Program::~Program()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Program::setShaderNames(const string &v, const string &f)
|
||||||
|
{
|
||||||
|
vShaderName = v;
|
||||||
|
fShaderName = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Program::init()
|
||||||
|
{
|
||||||
|
GLint rc;
|
||||||
|
|
||||||
|
// Create shader handles
|
||||||
|
GLuint VS = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
GLuint FS = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
|
||||||
|
// Read shader sources
|
||||||
|
const char *vshader = GLSL::textFileRead(vShaderName.c_str());
|
||||||
|
const char *fshader = GLSL::textFileRead(fShaderName.c_str());
|
||||||
|
glShaderSource(VS, 1, &vshader, NULL);
|
||||||
|
glShaderSource(FS, 1, &fshader, NULL);
|
||||||
|
|
||||||
|
// Compile vertex shader
|
||||||
|
glCompileShader(VS);
|
||||||
|
glGetShaderiv(VS, GL_COMPILE_STATUS, &rc);
|
||||||
|
if(!rc) {
|
||||||
|
if(isVerbose()) {
|
||||||
|
GLSL::printShaderInfoLog(VS);
|
||||||
|
cout << "Error compiling vertex shader " << vShaderName << endl;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compile fragment shader
|
||||||
|
glCompileShader(FS);
|
||||||
|
glGetShaderiv(FS, GL_COMPILE_STATUS, &rc);
|
||||||
|
if(!rc) {
|
||||||
|
if(isVerbose()) {
|
||||||
|
GLSL::printShaderInfoLog(FS);
|
||||||
|
cout << "Error compiling fragment shader " << fShaderName << endl;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the program and link
|
||||||
|
pid = glCreateProgram();
|
||||||
|
glAttachShader(pid, VS);
|
||||||
|
glAttachShader(pid, FS);
|
||||||
|
glLinkProgram(pid);
|
||||||
|
glGetProgramiv(pid, GL_LINK_STATUS, &rc);
|
||||||
|
if(!rc) {
|
||||||
|
if(isVerbose()) {
|
||||||
|
GLSL::printProgramInfoLog(pid);
|
||||||
|
cout << "Error linking shaders " << vShaderName << " and " << fShaderName << endl;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLSL::checkError(GET_FILE_LINE);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Program::bind()
|
||||||
|
{
|
||||||
|
glUseProgram(pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Program::unbind()
|
||||||
|
{
|
||||||
|
glUseProgram(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Program::addAttribute(const string &name)
|
||||||
|
{
|
||||||
|
attributes[name] = glGetAttribLocation(pid, name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Program::addUniform(const string &name)
|
||||||
|
{
|
||||||
|
uniforms[name] = glGetUniformLocation(pid, name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint Program::getAttribute(const string &name) const
|
||||||
|
{
|
||||||
|
map<string,GLint>::const_iterator attribute = attributes.find(name.c_str());
|
||||||
|
if(attribute == attributes.end()) {
|
||||||
|
if(isVerbose()) {
|
||||||
|
cout << name << " is not an attribute variable" << endl;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return attribute->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint Program::getUniform(const string &name) const
|
||||||
|
{
|
||||||
|
map<string,GLint>::const_iterator uniform = uniforms.find(name.c_str());
|
||||||
|
if(uniform == uniforms.end()) {
|
||||||
|
if(isVerbose()) {
|
||||||
|
cout << name << " is not a uniform variable" << endl;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return uniform->second;
|
||||||
|
}
|
44
A4/src/Program.h
Normal file
44
A4/src/Program.h
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef __Program__
|
||||||
|
#define __Program__
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#define GLEW_STATIC
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An OpenGL Program (vertex and fragment shaders)
|
||||||
|
*/
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Program();
|
||||||
|
virtual ~Program();
|
||||||
|
|
||||||
|
void setVerbose(bool v) { verbose = v; }
|
||||||
|
bool isVerbose() const { return verbose; }
|
||||||
|
|
||||||
|
void setShaderNames(const std::string &v, const std::string &f);
|
||||||
|
virtual bool init();
|
||||||
|
virtual void bind();
|
||||||
|
virtual void unbind();
|
||||||
|
|
||||||
|
void addAttribute(const std::string &name);
|
||||||
|
void addUniform(const std::string &name);
|
||||||
|
GLint getAttribute(const std::string &name) const;
|
||||||
|
GLint getUniform(const std::string &name) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string vShaderName;
|
||||||
|
std::string fShaderName;
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLuint pid;
|
||||||
|
std::map<std::string,GLint> attributes;
|
||||||
|
std::map<std::string,GLint> uniforms;
|
||||||
|
bool verbose;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
165
A4/src/Shape.cpp
Normal file
165
A4/src/Shape.cpp
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
#include "Shape.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "GLSL.h"
|
||||||
|
#include "Program.h"
|
||||||
|
|
||||||
|
#define GLM_FORCE_RADIANS
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
#define TINYOBJLOADER_IMPLEMENTATION
|
||||||
|
#include "tiny_obj_loader.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
Shape::Shape() :
|
||||||
|
posBufID(0),
|
||||||
|
norBufID(0),
|
||||||
|
texBufID(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Shape::~Shape()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shape::loadMesh(const string &meshName)
|
||||||
|
{
|
||||||
|
// Load geometry
|
||||||
|
tinyobj::attrib_t attrib;
|
||||||
|
std::vector<tinyobj::shape_t> shapes;
|
||||||
|
std::vector<tinyobj::material_t> materials;
|
||||||
|
string errStr;
|
||||||
|
bool rc = tinyobj::LoadObj(&attrib, &shapes, &materials, &errStr, meshName.c_str());
|
||||||
|
if(!rc) {
|
||||||
|
cerr << errStr << endl;
|
||||||
|
} else {
|
||||||
|
// Some OBJ files have different indices for vertex positions, normals,
|
||||||
|
// and texture coordinates. For example, a cube corner vertex may have
|
||||||
|
// three different normals. Here, we are going to duplicate all such
|
||||||
|
// vertices.
|
||||||
|
// Loop over shapes
|
||||||
|
for(size_t s = 0; s < shapes.size(); s++) {
|
||||||
|
// Loop over faces (polygons)
|
||||||
|
size_t index_offset = 0;
|
||||||
|
for(size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++) {
|
||||||
|
size_t fv = shapes[s].mesh.num_face_vertices[f];
|
||||||
|
// Loop over vertices in the face.
|
||||||
|
for(size_t v = 0; v < fv; v++) {
|
||||||
|
// access to vertex
|
||||||
|
tinyobj::index_t idx = shapes[s].mesh.indices[index_offset + v];
|
||||||
|
posBuf.push_back(attrib.vertices[3*idx.vertex_index+0]);
|
||||||
|
posBuf.push_back(attrib.vertices[3*idx.vertex_index+1]);
|
||||||
|
posBuf.push_back(attrib.vertices[3*idx.vertex_index+2]);
|
||||||
|
if(!attrib.normals.empty()) {
|
||||||
|
norBuf.push_back(attrib.normals[3*idx.normal_index+0]);
|
||||||
|
norBuf.push_back(attrib.normals[3*idx.normal_index+1]);
|
||||||
|
norBuf.push_back(attrib.normals[3*idx.normal_index+2]);
|
||||||
|
}
|
||||||
|
if(!attrib.texcoords.empty()) {
|
||||||
|
texBuf.push_back(attrib.texcoords[2*idx.texcoord_index+0]);
|
||||||
|
texBuf.push_back(attrib.texcoords[2*idx.texcoord_index+1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index_offset += fv;
|
||||||
|
// per-face material (IGNORE)
|
||||||
|
shapes[s].mesh.material_ids[f];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shape::fitToUnitBox()
|
||||||
|
{
|
||||||
|
// Scale the vertex positions so that they fit within [-1, +1] in all three dimensions.
|
||||||
|
glm::vec3 vmin(posBuf[0], posBuf[1], posBuf[2]);
|
||||||
|
glm::vec3 vmax(posBuf[0], posBuf[1], posBuf[2]);
|
||||||
|
for(int i = 0; i < (int)posBuf.size(); i += 3) {
|
||||||
|
glm::vec3 v(posBuf[i], posBuf[i+1], posBuf[i+2]);
|
||||||
|
vmin.x = min(vmin.x, v.x);
|
||||||
|
vmin.y = min(vmin.y, v.y);
|
||||||
|
vmin.z = min(vmin.z, v.z);
|
||||||
|
vmax.x = max(vmax.x, v.x);
|
||||||
|
vmax.y = max(vmax.y, v.y);
|
||||||
|
vmax.z = max(vmax.z, v.z);
|
||||||
|
}
|
||||||
|
glm::vec3 center = 0.5f*(vmin + vmax);
|
||||||
|
glm::vec3 diff = vmax - vmin;
|
||||||
|
float diffmax = diff.x;
|
||||||
|
diffmax = max(diffmax, diff.y);
|
||||||
|
diffmax = max(diffmax, diff.z);
|
||||||
|
float scale = 1.0f / diffmax;
|
||||||
|
for(int i = 0; i < (int)posBuf.size(); i += 3) {
|
||||||
|
posBuf[i ] = (posBuf[i ] - center.x) * scale;
|
||||||
|
posBuf[i+1] = (posBuf[i+1] - center.y) * scale;
|
||||||
|
posBuf[i+2] = (posBuf[i+2] - center.z) * scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shape::init()
|
||||||
|
{
|
||||||
|
// Send the position array to the GPU
|
||||||
|
glGenBuffers(1, &posBufID);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, posBufID);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, posBuf.size()*sizeof(float), &posBuf[0], GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
// Send the normal array to the GPU
|
||||||
|
if(!norBuf.empty()) {
|
||||||
|
glGenBuffers(1, &norBufID);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, norBufID);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, norBuf.size()*sizeof(float), &norBuf[0], GL_STATIC_DRAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the texture array to the GPU
|
||||||
|
if(!texBuf.empty()) {
|
||||||
|
glGenBuffers(1, &texBufID);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, texBufID);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, texBuf.size()*sizeof(float), &texBuf[0], GL_STATIC_DRAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unbind the arrays
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
GLSL::checkError(GET_FILE_LINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shape::draw(const shared_ptr<Program> prog) const
|
||||||
|
{
|
||||||
|
// Bind position buffer
|
||||||
|
int h_pos = prog->getAttribute("aPos");
|
||||||
|
glEnableVertexAttribArray(h_pos);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, posBufID);
|
||||||
|
glVertexAttribPointer(h_pos, 3, GL_FLOAT, GL_FALSE, 0, (const void *)0);
|
||||||
|
|
||||||
|
// Bind normal buffer
|
||||||
|
int h_nor = prog->getAttribute("aNor");
|
||||||
|
if(h_nor != -1 && norBufID != 0) {
|
||||||
|
glEnableVertexAttribArray(h_nor);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, norBufID);
|
||||||
|
glVertexAttribPointer(h_nor, 3, GL_FLOAT, GL_FALSE, 0, (const void *)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind texcoords buffer
|
||||||
|
int h_tex = prog->getAttribute("aTex");
|
||||||
|
if(h_tex != -1 && texBufID != 0) {
|
||||||
|
glEnableVertexAttribArray(h_tex);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, texBufID);
|
||||||
|
glVertexAttribPointer(h_tex, 2, GL_FLOAT, GL_FALSE, 0, (const void *)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
int count = posBuf.size()/3; // number of indices to be rendered
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, count);
|
||||||
|
|
||||||
|
// Disable and unbind
|
||||||
|
if(h_tex != -1) {
|
||||||
|
glDisableVertexAttribArray(h_tex);
|
||||||
|
}
|
||||||
|
if(h_nor != -1) {
|
||||||
|
glDisableVertexAttribArray(h_nor);
|
||||||
|
}
|
||||||
|
glDisableVertexAttribArray(h_pos);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
GLSL::checkError(GET_FILE_LINE);
|
||||||
|
}
|
37
A4/src/Shape.h
Normal file
37
A4/src/Shape.h
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef _SHAPE_H_
|
||||||
|
#define _SHAPE_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class Program;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A shape defined by a list of triangles
|
||||||
|
* - posBuf should be of length 3*ntris
|
||||||
|
* - norBuf should be of length 3*ntris (if normals are available)
|
||||||
|
* - texBuf should be of length 2*ntris (if texture coords are available)
|
||||||
|
* posBufID, norBufID, and texBufID are OpenGL buffer identifiers.
|
||||||
|
*/
|
||||||
|
class Shape
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Shape();
|
||||||
|
virtual ~Shape();
|
||||||
|
void loadMesh(const std::string &meshName);
|
||||||
|
void fitToUnitBox();
|
||||||
|
void init();
|
||||||
|
void draw(const std::shared_ptr<Program> prog) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<float> posBuf;
|
||||||
|
std::vector<float> norBuf;
|
||||||
|
std::vector<float> texBuf;
|
||||||
|
unsigned posBufID;
|
||||||
|
unsigned norBufID;
|
||||||
|
unsigned texBufID;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
462
A4/src/main.cpp
Normal file
462
A4/src/main.cpp
Normal file
|
@ -0,0 +1,462 @@
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
#define _USE_MATH_DEFINES
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#define GLEW_STATIC
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#define GLM_FORCE_RADIANS
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
#include "MyCamera.h"
|
||||||
|
#include "GLSL.h"
|
||||||
|
#include "MatrixStack.h"
|
||||||
|
#include "Program.h"
|
||||||
|
#include "Shape.h"
|
||||||
|
#include "Material.h"
|
||||||
|
#include "Light.h"
|
||||||
|
#include "Component.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
GLFWwindow *window; // Main application window
|
||||||
|
string RESOURCE_DIR = "./"; // Where the resources are loaded from
|
||||||
|
|
||||||
|
shared_ptr<Camera> camera;
|
||||||
|
shared_ptr<Program> prog;
|
||||||
|
shared_ptr<Program> sprog;
|
||||||
|
shared_ptr<Shape> shape;
|
||||||
|
shared_ptr<Shape> sphere;
|
||||||
|
shared_ptr<Shape> cube;
|
||||||
|
shared_ptr<Shape> teapot;
|
||||||
|
|
||||||
|
bool keyToggles[256] = {false}; // only for English keyboards!
|
||||||
|
|
||||||
|
vector<Material> materials;
|
||||||
|
Light l[2];
|
||||||
|
int ind = 0;
|
||||||
|
int lind = 0;
|
||||||
|
int sind = 0;
|
||||||
|
|
||||||
|
unsigned int pid0;
|
||||||
|
unsigned int pid1;
|
||||||
|
|
||||||
|
//Variables affecting the assortment of shapes.
|
||||||
|
unsigned int n = 10;
|
||||||
|
float s = 1.0;
|
||||||
|
float tx = 1.0;
|
||||||
|
float ty = 1.0;
|
||||||
|
float tz = 1.0;
|
||||||
|
vector<Component> shapes;
|
||||||
|
|
||||||
|
// This function is called when a GLFW error occurs
|
||||||
|
static void error_callback(int error, const char *description)
|
||||||
|
{
|
||||||
|
cerr << description << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is called when a key is pressed
|
||||||
|
static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods)
|
||||||
|
{
|
||||||
|
if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
|
||||||
|
glfwSetWindowShouldClose(window, GL_TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is called when the mouse is clicked
|
||||||
|
static void mouse_button_callback(GLFWwindow *window, int button, int action, int mods)
|
||||||
|
{
|
||||||
|
// Get the current mouse position.
|
||||||
|
double xmouse, ymouse;
|
||||||
|
glfwGetCursorPos(window, &xmouse, &ymouse);
|
||||||
|
// Get current window size.
|
||||||
|
int width, height;
|
||||||
|
glfwGetWindowSize(window, &width, &height);
|
||||||
|
if(action == GLFW_PRESS) {
|
||||||
|
bool shift = (mods & GLFW_MOD_SHIFT) != 0;
|
||||||
|
bool ctrl = (mods & GLFW_MOD_CONTROL) != 0;
|
||||||
|
bool alt = (mods & GLFW_MOD_ALT) != 0;
|
||||||
|
camera->mouseClicked((float)xmouse, (float)ymouse, shift, ctrl, alt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is called when the mouse moves
|
||||||
|
static void cursor_position_callback(GLFWwindow* window, double xmouse, double ymouse)
|
||||||
|
{
|
||||||
|
int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT);
|
||||||
|
if(state == GLFW_PRESS) {
|
||||||
|
camera->mouseMoved((float)xmouse, (float)ymouse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void char_callback(GLFWwindow *window, unsigned int key)
|
||||||
|
{
|
||||||
|
keyToggles[key] = !keyToggles[key];
|
||||||
|
char cp = (char)key;
|
||||||
|
|
||||||
|
if(cp == 'W' || cp == 'w')
|
||||||
|
{
|
||||||
|
vec3 temp(0.0f, 0.0f, -0.1f);
|
||||||
|
camera->transpose(temp);
|
||||||
|
}
|
||||||
|
if(cp == 'A' || cp == 'a')
|
||||||
|
{
|
||||||
|
vec3 temp(-0.1f, 0.0f, 0.0f);
|
||||||
|
camera->transpose(temp);
|
||||||
|
}
|
||||||
|
if(cp == 'S' || cp == 's')
|
||||||
|
{
|
||||||
|
vec3 temp(0.0f, 0.0f, 0.1f);
|
||||||
|
camera->transpose(temp);
|
||||||
|
}
|
||||||
|
if(cp == 'D' || cp == 'd')
|
||||||
|
{
|
||||||
|
vec3 temp(0.1f, 0.0f, 0.0f);
|
||||||
|
camera->transpose(temp);
|
||||||
|
}
|
||||||
|
if(cp == 'X')
|
||||||
|
{
|
||||||
|
glm::vec3 temp = l[lind].getPos();
|
||||||
|
l[lind].setPos(glm::vec3(temp.x + 0.1f, temp.y, temp.z));
|
||||||
|
}
|
||||||
|
if(cp == 'x')
|
||||||
|
{
|
||||||
|
glm::vec3 temp = l[lind].getPos();
|
||||||
|
l[lind].setPos(glm::vec3(temp.x - 0.1f, temp.y, temp.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cp == 'Y')
|
||||||
|
{
|
||||||
|
glm::vec3 temp = l[lind].getPos();
|
||||||
|
l[lind].setPos(glm::vec3(temp.x, temp.y + 0.1f, temp.z));
|
||||||
|
}
|
||||||
|
if(cp == 'y')
|
||||||
|
{
|
||||||
|
glm::vec3 temp = l[lind].getPos();
|
||||||
|
l[lind].setPos(glm::vec3(temp.x, temp.y - 0.1f, temp.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
if(cp == 'Z')
|
||||||
|
{
|
||||||
|
glm::vec3 temp = l[lind].getPos();
|
||||||
|
l[lind].setPos(glm::vec3(temp.x, temp.y, temp.z + 0.1f));
|
||||||
|
}
|
||||||
|
if(cp == 'z')
|
||||||
|
{
|
||||||
|
glm::vec3 temp = l[lind].getPos();
|
||||||
|
l[lind].setPos(glm::vec3(temp.x, temp.y, temp.z - 0.1f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the window is resized, capture the new size and reset the viewport
|
||||||
|
static void resize_callback(GLFWwindow *window, int width, int height)
|
||||||
|
{
|
||||||
|
glViewport(0, 0, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void createComponents()
|
||||||
|
{
|
||||||
|
for(unsigned int i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
Component temp;
|
||||||
|
|
||||||
|
temp.s.x = s;
|
||||||
|
temp.s.y = s;
|
||||||
|
temp.s.z = s;
|
||||||
|
|
||||||
|
temp.tp.x = 0;
|
||||||
|
temp.tp.y = 0;
|
||||||
|
temp.tp.z = -tz*((float)i);
|
||||||
|
|
||||||
|
temp.t.x = 1.0/2.0;
|
||||||
|
temp.t.y = 0;
|
||||||
|
temp.t.z = -1.0/2.0;
|
||||||
|
|
||||||
|
temp.sid = rand()%3;
|
||||||
|
|
||||||
|
shapes.push_back(temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void createMaterials()
|
||||||
|
{
|
||||||
|
Material m1;
|
||||||
|
|
||||||
|
materials.push_back(m1);
|
||||||
|
materials.push_back(m1);
|
||||||
|
materials.push_back(m1);
|
||||||
|
materials.push_back(m1);
|
||||||
|
materials.push_back(m1);
|
||||||
|
materials.push_back(m1);
|
||||||
|
materials.push_back(m1);
|
||||||
|
materials.push_back(m1);
|
||||||
|
materials.push_back(m1);
|
||||||
|
materials.push_back(m1);
|
||||||
|
materials.push_back(m1);
|
||||||
|
|
||||||
|
materials[0].setMaterial(glm::vec3(0.0f, 0.0f, 0.4f), glm::vec3(0.2f, 0.1f, 0.7f), glm::vec3(0.5f, 0.5f, 0.5f), 200.0f);
|
||||||
|
materials[1].setMaterial(glm::vec3(0.3f, 0.3f, 0.4f), glm::vec3(0.2f, 0.2f, 0.3f), glm::vec3(0.1f, 0.1f, 0.1f), 10.0f);
|
||||||
|
materials[2].setMaterial(glm::vec3(0.2f, 0.2f, 0.2f), glm::vec3(0.8f, 0.7f, 0.7f), glm::vec3(1.0f, 0.9f, 0.8f), 200.0f);
|
||||||
|
materials[3].setMaterial(glm::vec3(0.2f, 0.8f, 0.2f), glm::vec3(0.1f, 0.7f, 0.2f), glm::vec3(0.2f, 0.2f, 0.2f), 100.0f);
|
||||||
|
materials[4].setMaterial(glm::vec3(0.8f, 0.2f, 0.2f), glm::vec3(0.7f, 0.1f, 0.1f), glm::vec3(0.3f, 0.3f, 0.3f), 100.0f);
|
||||||
|
materials[5].setMaterial(glm::vec3(0.7f, 0.7f, 0.1f), glm::vec3(0.6f, 0.5f, 0.2f), glm::vec3(0.1f, 0.1f, 0.1f), 50.0f);
|
||||||
|
materials[6].setMaterial(glm::vec3(0.5f, 0.1f, 0.1f), glm::vec3(0.7f, 0.1f, 0.1f), glm::vec3(0.2f, 0.2f, 0.2f), 50.0f);
|
||||||
|
materials[7].setMaterial(glm::vec3(0.2f, 0.8f, 0.8f), glm::vec3(0.1f, 0.7f, 0.6f), glm::vec3(0.5f, 0.5f, 0.5f), 120.0f);
|
||||||
|
materials[8].setMaterial(glm::vec3(0.3f, 0.6f, 0.3f), glm::vec3(0.3f, 0.6f, 0.3f), glm::vec3(0.7f, 0.7f, 0.7f), 20.0f);
|
||||||
|
materials[9].setMaterial(glm::vec3(0.8f, 0.2f, 0.7f), glm::vec3(0.7f, 0.2f, 0.8f), glm::vec3(0.5f, 0.5f, 0.5f), 200.0f);
|
||||||
|
materials[10].setMaterial(glm::vec3(0.2f, 0.5f, 0.2f), glm::vec3(0.2f, 0.5f, 0.2f), glm::vec3(0.5f, 0.5f, 0.5f), 10.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void makeGround()
|
||||||
|
{
|
||||||
|
Component temp;
|
||||||
|
|
||||||
|
temp.tp.x = 0.0f;
|
||||||
|
temp.tp.y = -1.0f;
|
||||||
|
temp.tp.z = 0.0f;
|
||||||
|
|
||||||
|
temp.s.x = 100.0f;
|
||||||
|
temp.s.y = 0.0f;
|
||||||
|
temp.s.z = 100.0f;
|
||||||
|
|
||||||
|
temp.t.x = 0.0f;
|
||||||
|
temp.t.y = 0.0f;
|
||||||
|
temp.t.z = 0.0f;
|
||||||
|
|
||||||
|
temp.sid = 2;
|
||||||
|
|
||||||
|
shapes.push_back(temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is called once to initialize the scene and OpenGL
|
||||||
|
static void init()
|
||||||
|
{
|
||||||
|
// Initialize time.
|
||||||
|
glfwSetTime(0.0);
|
||||||
|
|
||||||
|
// Set background color.
|
||||||
|
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||||
|
// Enable z-buffer test.
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
sprog = make_shared<Program>();
|
||||||
|
sprog->setShaderNames(RESOURCE_DIR + "vert.glsl", RESOURCE_DIR + "sil.glsl");
|
||||||
|
sprog->setVerbose(false);
|
||||||
|
sprog->init();
|
||||||
|
sprog->addAttribute("aPos");
|
||||||
|
sprog->addAttribute("aNor");
|
||||||
|
sprog->addUniform("MV");
|
||||||
|
sprog->addUniform("P");
|
||||||
|
|
||||||
|
prog = make_shared<Program>();
|
||||||
|
prog->setShaderNames(RESOURCE_DIR + "vert.glsl", RESOURCE_DIR + "frag.glsl");
|
||||||
|
prog->setVerbose(false);
|
||||||
|
prog->init();
|
||||||
|
prog->addAttribute("aPos");
|
||||||
|
prog->addAttribute("aNor");
|
||||||
|
prog->addUniform("MV");
|
||||||
|
prog->addUniform("P");
|
||||||
|
prog->addUniform("MVL");
|
||||||
|
prog->addUniform("lightPos1");
|
||||||
|
prog->addUniform("lightPos2");
|
||||||
|
prog->addUniform("ka");
|
||||||
|
prog->addUniform("kd");
|
||||||
|
prog->addUniform("ks");
|
||||||
|
prog->addUniform("s");
|
||||||
|
prog->addUniform("i1");
|
||||||
|
prog->addUniform("i2");
|
||||||
|
|
||||||
|
camera = make_shared<Camera>();
|
||||||
|
camera->setInitDistance(2.0f);
|
||||||
|
|
||||||
|
shape = make_shared<Shape>();
|
||||||
|
shape->loadMesh(RESOURCE_DIR + "bunny.obj");
|
||||||
|
shape->fitToUnitBox();
|
||||||
|
shape->init();
|
||||||
|
|
||||||
|
sphere = make_shared<Shape>();
|
||||||
|
sphere->loadMesh(RESOURCE_DIR + "sphere.obj");
|
||||||
|
sphere->fitToUnitBox();
|
||||||
|
sphere->init();
|
||||||
|
|
||||||
|
cube = make_shared<Shape>();
|
||||||
|
cube->loadMesh(RESOURCE_DIR + "cube.obj");
|
||||||
|
cube->fitToUnitBox();
|
||||||
|
cube->init();
|
||||||
|
|
||||||
|
teapot = make_shared<Shape>();
|
||||||
|
teapot->loadMesh(RESOURCE_DIR + "teapot.obj");
|
||||||
|
teapot->fitToUnitBox();
|
||||||
|
teapot->init();
|
||||||
|
|
||||||
|
createMaterials();
|
||||||
|
|
||||||
|
Light l1(glm::vec3(1.0f, 1.0f, 1.0f), 0.8f);
|
||||||
|
Light l2(glm::vec3(-1.0f, 1.0f, 1.0f), 0.2f);
|
||||||
|
l[0] = l1;
|
||||||
|
l[1] = l2;
|
||||||
|
|
||||||
|
// separate function to create shapes.
|
||||||
|
createComponents();
|
||||||
|
|
||||||
|
makeGround();
|
||||||
|
|
||||||
|
GLSL::checkError(GET_FILE_LINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is called every frame to draw the scene.
|
||||||
|
static void render()
|
||||||
|
{
|
||||||
|
// Clear framebuffer.
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
if(keyToggles[(unsigned)'c']) {
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
}
|
||||||
|
// Get current frame buffer size.
|
||||||
|
int width, height;
|
||||||
|
glfwGetFramebufferSize(window, &width, &height);
|
||||||
|
camera->setAspect((float)width/(float)height);
|
||||||
|
|
||||||
|
// Matrix stacks
|
||||||
|
auto P = make_shared<MatrixStack>();
|
||||||
|
auto MV = make_shared<MatrixStack>();
|
||||||
|
|
||||||
|
// Apply camera transforms
|
||||||
|
P->pushMatrix();
|
||||||
|
camera->applyProjectionMatrix(P);
|
||||||
|
MV->pushMatrix();
|
||||||
|
camera->applyViewMatrix(MV);
|
||||||
|
|
||||||
|
prog->bind();
|
||||||
|
|
||||||
|
mat4 templ;
|
||||||
|
templ[0] = vec4(1.0, 0, 0, 0);
|
||||||
|
templ[1] = vec4(0, 1.0, 0, 0);
|
||||||
|
templ[2] = vec4(0, 0, 1.0, 0);
|
||||||
|
templ[3] = vec4(l[0].getPos().x, l[0].getPos().y, l[0].getPos().z, 1.0);
|
||||||
|
templ = MV->topMatrix()*templ;
|
||||||
|
glUniformMatrix4fv(prog->getUniform("MVL"), 1, GL_FALSE, glm::value_ptr(templ));
|
||||||
|
|
||||||
|
Component light;
|
||||||
|
|
||||||
|
light.t.x = l[0].getPos().x;
|
||||||
|
light.t.y = l[0].getPos().y;
|
||||||
|
light.t.z = l[0].getPos().z;
|
||||||
|
|
||||||
|
glUniform3f(prog->getUniform("lightPos1"), l[0].getPos().x, l[0].getPos().y, l[0].getPos().z);
|
||||||
|
glUniform3f(prog->getUniform("ka"), 0.95, 1.0, 0.35);
|
||||||
|
glUniform3f(prog->getUniform("kd"), 1.0, 1.0, 1.0);
|
||||||
|
glUniform3f(prog->getUniform("ks"), 1.0, 1.0, 1.0);
|
||||||
|
glUniform1f(prog->getUniform("s"), 1.0);
|
||||||
|
|
||||||
|
light.draw(MV, P, sphere, prog);
|
||||||
|
prog->unbind();
|
||||||
|
|
||||||
|
glm::vec3 ambient = materials.at(0).getAmbient();
|
||||||
|
glm::vec3 diffuse = materials.at(0).getDiffuse();
|
||||||
|
glm::vec3 specular = materials.at(0).getSpecular();
|
||||||
|
float shine = materials.at(0).getShiny();
|
||||||
|
for(unsigned int i = 0; i < n + 1; i++)
|
||||||
|
{
|
||||||
|
prog->bind();
|
||||||
|
ambient = materials.at(i).getAmbient();
|
||||||
|
diffuse = materials.at(i).getDiffuse();
|
||||||
|
specular = materials.at(i).getSpecular();
|
||||||
|
shine = materials.at(i).getShiny();
|
||||||
|
|
||||||
|
glUniform3f(prog->getUniform("ka"), ambient.r, ambient.g, ambient.b);
|
||||||
|
glUniform3f(prog->getUniform("kd"), diffuse.r, diffuse.g, diffuse.b);
|
||||||
|
glUniform3f(prog->getUniform("ks"), specular.r, specular.g, specular.b);
|
||||||
|
glUniform1f(prog->getUniform("s"), shine);
|
||||||
|
glUniform1f(prog->getUniform("i1"), l[0].getIntensity());
|
||||||
|
glUniform1f(prog->getUniform("i2"), l[1].getIntensity());
|
||||||
|
|
||||||
|
switch(shapes.at(i).sid)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
shapes.at(i).draw(MV, P, shape, prog);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
shapes.at(i).draw(MV, P, teapot, prog);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
shapes.at(i).draw(MV, P, cube, prog);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
shapes.at(i).draw(MV, P, shape, prog);
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
prog->unbind();
|
||||||
|
}
|
||||||
|
MV->popMatrix();
|
||||||
|
P->popMatrix();
|
||||||
|
|
||||||
|
GLSL::checkError(GET_FILE_LINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if(argc < 2) {
|
||||||
|
cout << "Please specify the resource directory." << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
RESOURCE_DIR = argv[1] + string("/");
|
||||||
|
|
||||||
|
// Set error callback.
|
||||||
|
glfwSetErrorCallback(error_callback);
|
||||||
|
// Initialize the library.
|
||||||
|
if(!glfwInit()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// Create a windowed mode window and its OpenGL context.
|
||||||
|
window = glfwCreateWindow(640, 480, "Alex Huddleston Assignment 4", NULL, NULL);
|
||||||
|
if(!window) {
|
||||||
|
glfwTerminate();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// Make the window's context current.
|
||||||
|
glfwMakeContextCurrent(window);
|
||||||
|
// Initialize GLEW.
|
||||||
|
glewExperimental = true;
|
||||||
|
if(glewInit() != GLEW_OK) {
|
||||||
|
cerr << "Failed to initialize GLEW" << endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
glGetError(); // A bug in glewInit() causes an error that we can safely ignore.
|
||||||
|
cout << "OpenGL version: " << glGetString(GL_VERSION) << endl;
|
||||||
|
cout << "GLSL version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << endl;
|
||||||
|
GLSL::checkVersion();
|
||||||
|
// Set vsync.
|
||||||
|
glfwSwapInterval(1);
|
||||||
|
// Set keyboard callback.
|
||||||
|
glfwSetKeyCallback(window, key_callback);
|
||||||
|
// Set char callback.
|
||||||
|
glfwSetCharCallback(window, char_callback);
|
||||||
|
// Set cursor position callback.
|
||||||
|
glfwSetCursorPosCallback(window, cursor_position_callback);
|
||||||
|
// Set mouse button callback.
|
||||||
|
glfwSetMouseButtonCallback(window, mouse_button_callback);
|
||||||
|
// Set the window resize call back.
|
||||||
|
glfwSetFramebufferSizeCallback(window, resize_callback);
|
||||||
|
// Initialize scene.
|
||||||
|
init();
|
||||||
|
// Loop until the user closes the window.
|
||||||
|
while(!glfwWindowShouldClose(window)) {
|
||||||
|
// Render scene.
|
||||||
|
render();
|
||||||
|
// Swap front and back buffers.
|
||||||
|
glfwSwapBuffers(window);
|
||||||
|
// Poll for and process events.
|
||||||
|
glfwPollEvents();
|
||||||
|
}
|
||||||
|
// Quit program.
|
||||||
|
glfwDestroyWindow(window);
|
||||||
|
glfwTerminate();
|
||||||
|
return 0;
|
||||||
|
}
|
1922
A4/src/tiny_obj_loader.h
Normal file
1922
A4/src/tiny_obj_loader.h
Normal file
File diff suppressed because it is too large
Load diff
BIN
L09.zip
Normal file
BIN
L09.zip
Normal file
Binary file not shown.
127
L09/CMakeLists.txt
Normal file
127
L09/CMakeLists.txt
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||||
|
|
||||||
|
# Name of the project
|
||||||
|
PROJECT(L09)
|
||||||
|
|
||||||
|
# FOR LAB MACHINES ONLY!
|
||||||
|
# DO NOT EDIT
|
||||||
|
SET(DEF_DIR_GLM "C:\\c++\\glm")
|
||||||
|
SET(DEF_DIR_GLFW "C:\\c++\\glfw-3.2.1")
|
||||||
|
SET(DEF_DIR_GLEW "C:\\c++\\glew-2.0.0")
|
||||||
|
|
||||||
|
# Is this the solution?
|
||||||
|
# Override with `cmake -DSOL=ON ..`
|
||||||
|
OPTION(SOL "Solution" OFF)
|
||||||
|
|
||||||
|
# Use glob to get the list of all source files.
|
||||||
|
# We don't really need to include header and resource files to build, but it's
|
||||||
|
# nice to have them also show up in IDEs.
|
||||||
|
IF(${SOL})
|
||||||
|
FILE(GLOB_RECURSE SOURCES "src0/*.cpp")
|
||||||
|
FILE(GLOB_RECURSE HEADERS "src0/*.h")
|
||||||
|
FILE(GLOB_RECURSE GLSL "resources0/*.glsl")
|
||||||
|
ELSE()
|
||||||
|
FILE(GLOB_RECURSE SOURCES "src/*.cpp")
|
||||||
|
FILE(GLOB_RECURSE HEADERS "src/*.h")
|
||||||
|
FILE(GLOB_RECURSE GLSL "resources/*.glsl")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# Set the executable.
|
||||||
|
ADD_EXECUTABLE(${CMAKE_PROJECT_NAME} ${SOURCES} ${HEADERS} ${GLSL})
|
||||||
|
|
||||||
|
# Get the GLM environment variable. Since GLM is a header-only library, we
|
||||||
|
# just need to add it to the include directory.
|
||||||
|
SET(GLM_INCLUDE_DIR "$ENV{GLM_INCLUDE_DIR}")
|
||||||
|
IF(NOT GLM_INCLUDE_DIR)
|
||||||
|
# The environment variable was not set
|
||||||
|
SET(ERR_MSG "Please point the environment variable GLM_INCLUDE_DIR to the root directory of your GLM installation.")
|
||||||
|
IF(WIN32)
|
||||||
|
# On Windows, try the default location
|
||||||
|
MESSAGE(STATUS "Looking for GLM in ${DEF_DIR_GLM}")
|
||||||
|
IF(IS_DIRECTORY ${DEF_DIR_GLM})
|
||||||
|
MESSAGE(STATUS "Found!")
|
||||||
|
SET(GLM_INCLUDE_DIR ${DEF_DIR_GLM})
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
INCLUDE_DIRECTORIES(${GLM_INCLUDE_DIR})
|
||||||
|
|
||||||
|
# Get the GLFW environment variable. There should be a CMakeLists.txt in the
|
||||||
|
# specified directory.
|
||||||
|
SET(GLFW_DIR "$ENV{GLFW_DIR}")
|
||||||
|
IF(NOT GLFW_DIR)
|
||||||
|
# The environment variable was not set
|
||||||
|
SET(ERR_MSG "Please point the environment variable GLFW_DIR to the root directory of your GLFW installation.")
|
||||||
|
IF(WIN32)
|
||||||
|
# On Windows, try the default location
|
||||||
|
MESSAGE(STATUS "Looking for GLFW in ${DEF_DIR_GLFW}")
|
||||||
|
IF(IS_DIRECTORY ${DEF_DIR_GLFW})
|
||||||
|
MESSAGE(STATUS "Found!")
|
||||||
|
SET(GLFW_DIR ${DEF_DIR_GLFW})
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
OPTION(GLFW_BUILD_EXAMPLES "GLFW_BUILD_EXAMPLES" OFF)
|
||||||
|
OPTION(GLFW_BUILD_TESTS "GLFW_BUILD_TESTS" OFF)
|
||||||
|
OPTION(GLFW_BUILD_DOCS "GLFW_BUILD_DOCS" OFF)
|
||||||
|
IF(CMAKE_BUILD_TYPE MATCHES Release)
|
||||||
|
ADD_SUBDIRECTORY(${GLFW_DIR} ${GLFW_DIR}/release)
|
||||||
|
ELSE()
|
||||||
|
ADD_SUBDIRECTORY(${GLFW_DIR} ${GLFW_DIR}/debug)
|
||||||
|
ENDIF()
|
||||||
|
INCLUDE_DIRECTORIES(${GLFW_DIR}/include)
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} glfw ${GLFW_LIBRARIES})
|
||||||
|
|
||||||
|
# Get the GLEW environment variable.
|
||||||
|
SET(GLEW_DIR "$ENV{GLEW_DIR}")
|
||||||
|
IF(NOT GLEW_DIR)
|
||||||
|
# The environment variable was not set
|
||||||
|
SET(ERR_MSG "Please point the environment variable GLEW_DIR to the root directory of your GLEW installation.")
|
||||||
|
IF(WIN32)
|
||||||
|
# On Windows, try the default location
|
||||||
|
MESSAGE(STATUS "Looking for GLEW in ${DEF_DIR_GLEW}")
|
||||||
|
IF(IS_DIRECTORY ${DEF_DIR_GLEW})
|
||||||
|
MESSAGE(STATUS "Found!")
|
||||||
|
SET(GLEW_DIR ${DEF_DIR_GLEW})
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
INCLUDE_DIRECTORIES(${GLEW_DIR}/include)
|
||||||
|
IF(WIN32)
|
||||||
|
# With prebuilt binaries
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} ${GLEW_DIR}/lib/Release/Win32/glew32s.lib)
|
||||||
|
ELSE()
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} ${GLEW_DIR}/lib/libGLEW.a)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# OS specific options and libraries
|
||||||
|
IF(WIN32)
|
||||||
|
# c++11 is enabled by default.
|
||||||
|
# -Wall produces way too many warnings.
|
||||||
|
# -pedantic is not supported.
|
||||||
|
# Disable warning 4996.
|
||||||
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4996")
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} opengl32.lib)
|
||||||
|
ELSE()
|
||||||
|
# Enable all pedantic warnings.
|
||||||
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -pedantic")
|
||||||
|
IF(APPLE)
|
||||||
|
# Add required frameworks for GLFW.
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} "-framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo")
|
||||||
|
ELSE()
|
||||||
|
#Link the Linux OpenGL library
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} "GL")
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
14
L09/resources/frag.glsl
Normal file
14
L09/resources/frag.glsl
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
uniform sampler2D texture0;
|
||||||
|
uniform sampler2D texture1;
|
||||||
|
|
||||||
|
varying vec2 vTex0;
|
||||||
|
varying vec2 vTex1;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec4 color0 = texture2D(texture0, vTex0);
|
||||||
|
//vec4 color1 = texture2D(texture1, vTex1);
|
||||||
|
gl_FragColor = color0;
|
||||||
|
}
|
BIN
L09/resources/reveille.jpg
Normal file
BIN
L09/resources/reveille.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 83 KiB |
BIN
L09/resources/tamu.jpg
Normal file
BIN
L09/resources/tamu.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 65 KiB |
18
L09/resources/vert.glsl
Normal file
18
L09/resources/vert.glsl
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
uniform mat4 P;
|
||||||
|
uniform mat4 MV;
|
||||||
|
uniform mat3 T1;
|
||||||
|
|
||||||
|
attribute vec4 aPos;
|
||||||
|
attribute vec2 aTex;
|
||||||
|
|
||||||
|
varying vec2 vTex0;
|
||||||
|
varying vec2 vTex1;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = P * MV * aPos;
|
||||||
|
vTex0 = aTex;
|
||||||
|
vTex1 = aTex;
|
||||||
|
}
|
68
L09/src/Camera.cpp
Normal file
68
L09/src/Camera.cpp
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
#include "Camera.h"
|
||||||
|
#include "MatrixStack.h"
|
||||||
|
#include <iostream>
|
||||||
|
#define _USE_MATH_DEFINES
|
||||||
|
#include <cmath>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
|
Camera::Camera() :
|
||||||
|
aspect(1.0f),
|
||||||
|
fovy((float)(45.0*M_PI/180.0)),
|
||||||
|
znear(0.1f),
|
||||||
|
zfar(1000.0f),
|
||||||
|
rotations(0.0, 0.0),
|
||||||
|
translations(0.0f, 0.0f, -5.0f),
|
||||||
|
rfactor(0.01f),
|
||||||
|
tfactor(0.001f),
|
||||||
|
sfactor(0.005f)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Camera::~Camera()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::mouseClicked(float x, float y, bool shift, bool ctrl, bool alt)
|
||||||
|
{
|
||||||
|
mousePrev.x = x;
|
||||||
|
mousePrev.y = y;
|
||||||
|
if(shift) {
|
||||||
|
state = Camera::TRANSLATE;
|
||||||
|
} else if(ctrl) {
|
||||||
|
state = Camera::SCALE;
|
||||||
|
} else {
|
||||||
|
state = Camera::ROTATE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::mouseMoved(float x, float y)
|
||||||
|
{
|
||||||
|
glm::vec2 mouseCurr(x, y);
|
||||||
|
glm::vec2 dv = mouseCurr - mousePrev;
|
||||||
|
switch(state) {
|
||||||
|
case Camera::ROTATE:
|
||||||
|
rotations += rfactor * dv;
|
||||||
|
break;
|
||||||
|
case Camera::TRANSLATE:
|
||||||
|
translations.x -= translations.z * tfactor * dv.x;
|
||||||
|
translations.y += translations.z * tfactor * dv.y;
|
||||||
|
break;
|
||||||
|
case Camera::SCALE:
|
||||||
|
translations.z *= (1.0f - sfactor * dv.y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mousePrev = mouseCurr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::applyProjectionMatrix(std::shared_ptr<MatrixStack> P) const
|
||||||
|
{
|
||||||
|
// Modify provided MatrixStack
|
||||||
|
P->multMatrix(glm::perspective(fovy, aspect, znear, zfar));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::applyViewMatrix(std::shared_ptr<MatrixStack> MV) const
|
||||||
|
{
|
||||||
|
MV->translate(translations);
|
||||||
|
MV->rotate(rotations.y, glm::vec3(1.0f, 0.0f, 0.0f));
|
||||||
|
MV->rotate(rotations.x, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
|
}
|
47
L09/src/Camera.h
Normal file
47
L09/src/Camera.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef __Camera__
|
||||||
|
#define __Camera__
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#define GLM_FORCE_RADIANS
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
class MatrixStack;
|
||||||
|
|
||||||
|
class Camera
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
ROTATE = 0,
|
||||||
|
TRANSLATE,
|
||||||
|
SCALE
|
||||||
|
};
|
||||||
|
|
||||||
|
Camera();
|
||||||
|
virtual ~Camera();
|
||||||
|
void setInitDistance(float z) { translations.z = -std::abs(z); }
|
||||||
|
void setAspect(float a) { aspect = a; };
|
||||||
|
void setRotationFactor(float f) { rfactor = f; };
|
||||||
|
void setTranslationFactor(float f) { tfactor = f; };
|
||||||
|
void setScaleFactor(float f) { sfactor = f; };
|
||||||
|
void mouseClicked(float x, float y, bool shift, bool ctrl, bool alt);
|
||||||
|
void mouseMoved(float x, float y);
|
||||||
|
void applyProjectionMatrix(std::shared_ptr<MatrixStack> P) const;
|
||||||
|
void applyViewMatrix(std::shared_ptr<MatrixStack> MV) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
float aspect;
|
||||||
|
float fovy;
|
||||||
|
float znear;
|
||||||
|
float zfar;
|
||||||
|
glm::vec2 rotations;
|
||||||
|
glm::vec3 translations;
|
||||||
|
glm::vec2 mousePrev;
|
||||||
|
int state;
|
||||||
|
float rfactor;
|
||||||
|
float tfactor;
|
||||||
|
float sfactor;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
152
L09/src/GLSL.cpp
Normal file
152
L09/src/GLSL.cpp
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
//
|
||||||
|
// Many useful helper functions for GLSL shaders - gleaned from various sources including orange book
|
||||||
|
// Created by zwood on 2/21/10.
|
||||||
|
// Modified by sueda 10/15/15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "GLSL.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace GLSL {
|
||||||
|
|
||||||
|
const char * errorString(GLenum err)
|
||||||
|
{
|
||||||
|
switch(err) {
|
||||||
|
case GL_NO_ERROR:
|
||||||
|
return "No error";
|
||||||
|
case GL_INVALID_ENUM:
|
||||||
|
return "Invalid enum";
|
||||||
|
case GL_INVALID_VALUE:
|
||||||
|
return "Invalid value";
|
||||||
|
case GL_INVALID_OPERATION:
|
||||||
|
return "Invalid operation";
|
||||||
|
case GL_STACK_OVERFLOW:
|
||||||
|
return "Stack overflow";
|
||||||
|
case GL_STACK_UNDERFLOW:
|
||||||
|
return "Stack underflow";
|
||||||
|
case GL_OUT_OF_MEMORY:
|
||||||
|
return "Out of memory";
|
||||||
|
default:
|
||||||
|
return "No error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkVersion()
|
||||||
|
{
|
||||||
|
int major, minor;
|
||||||
|
major = minor = 0;
|
||||||
|
const char *verstr = (const char *)glGetString(GL_VERSION);
|
||||||
|
|
||||||
|
if((verstr == NULL) || (sscanf(verstr, "%d.%d", &major, &minor) != 2)) {
|
||||||
|
printf("Invalid GL_VERSION format %d.%d\n", major, minor);
|
||||||
|
}
|
||||||
|
if(major < 2) {
|
||||||
|
printf("This shader example will not work due to the installed Opengl version, which is %d.%d.\n", major, minor);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkError(const char *str)
|
||||||
|
{
|
||||||
|
GLenum glErr = glGetError();
|
||||||
|
if(glErr != GL_NO_ERROR) {
|
||||||
|
if(str) {
|
||||||
|
printf("%s: ", str);
|
||||||
|
}
|
||||||
|
printf("GL_ERROR = %s.\n", errorString(glErr));
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void printShaderInfoLog(GLuint shader)
|
||||||
|
{
|
||||||
|
GLint infologLength = 0;
|
||||||
|
GLint charsWritten = 0;
|
||||||
|
GLchar *infoLog = 0;
|
||||||
|
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infologLength);
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
|
||||||
|
if(infologLength > 0) {
|
||||||
|
infoLog = (GLchar *)malloc(infologLength);
|
||||||
|
if(infoLog == NULL) {
|
||||||
|
puts("ERROR: Could not allocate InfoLog buffer");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
glGetShaderInfoLog(shader, infologLength, &charsWritten, infoLog);
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
printf("Shader InfoLog:\n%s\n\n", infoLog);
|
||||||
|
free(infoLog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void printProgramInfoLog(GLuint program)
|
||||||
|
{
|
||||||
|
GLint infologLength = 0;
|
||||||
|
GLint charsWritten = 0;
|
||||||
|
GLchar *infoLog = 0;
|
||||||
|
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infologLength);
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
|
||||||
|
if(infologLength > 0) {
|
||||||
|
infoLog = (GLchar *)malloc(infologLength);
|
||||||
|
if(infoLog == NULL) {
|
||||||
|
puts("ERROR: Could not allocate InfoLog buffer");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
glGetProgramInfoLog(program, infologLength, &charsWritten, infoLog);
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
printf("Program InfoLog:\n%s\n\n", infoLog);
|
||||||
|
free(infoLog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *textFileRead(const char *fn)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char *content = NULL;
|
||||||
|
int count = 0;
|
||||||
|
if(fn != NULL) {
|
||||||
|
fp = fopen(fn,"rt");
|
||||||
|
if(fp != NULL) {
|
||||||
|
fseek(fp, 0, SEEK_END);
|
||||||
|
count = (int)ftell(fp);
|
||||||
|
rewind(fp);
|
||||||
|
if(count > 0) {
|
||||||
|
content = (char *)malloc(sizeof(char) * (count+1));
|
||||||
|
count = (int)fread(content,sizeof(char),count,fp);
|
||||||
|
content[count] = '\0';
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
} else {
|
||||||
|
printf("error loading %s\n", fn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
int textFileWrite(const char *fn, const char *s)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
int status = 0;
|
||||||
|
if(fn != NULL) {
|
||||||
|
fp = fopen(fn,"w");
|
||||||
|
if(fp != NULL) {
|
||||||
|
if(fwrite(s,sizeof(char),strlen(s),fp) == strlen(s)) {
|
||||||
|
status = 1;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
40
L09/src/GLSL.h
Normal file
40
L09/src/GLSL.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
//
|
||||||
|
// Many useful helper functions for GLSL shaders - gleaned from various sources including orange book
|
||||||
|
// Created by zwood on 2/21/10.
|
||||||
|
// Modified by sueda 10/15/15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef __GLSL__
|
||||||
|
#define __GLSL__
|
||||||
|
|
||||||
|
#define GLEW_STATIC
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// For printing out the current file and line number //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::string NumberToString(T x)
|
||||||
|
{
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << x;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GET_FILE_LINE (std::string(__FILE__) + ":" + NumberToString(__LINE__)).c_str()
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace GLSL {
|
||||||
|
|
||||||
|
void checkVersion();
|
||||||
|
void checkError(const char *str = 0);
|
||||||
|
void printProgramInfoLog(GLuint program);
|
||||||
|
void printShaderInfoLog(GLuint shader);
|
||||||
|
int textFileWrite(const char *filename, const char *s);
|
||||||
|
char *textFileRead(const char *filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
114
L09/src/MatrixStack.cpp
Normal file
114
L09/src/MatrixStack.cpp
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
#include "MatrixStack.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <cassert>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#define GLM_FORCE_RADIANS
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtx/transform.hpp>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
MatrixStack::MatrixStack()
|
||||||
|
{
|
||||||
|
mstack = make_shared< stack<glm::mat4> >();
|
||||||
|
mstack->push(glm::mat4(1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
MatrixStack::~MatrixStack()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::pushMatrix()
|
||||||
|
{
|
||||||
|
const glm::mat4 &top = mstack->top();
|
||||||
|
mstack->push(top);
|
||||||
|
assert(mstack->size() < 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::popMatrix()
|
||||||
|
{
|
||||||
|
assert(!mstack->empty());
|
||||||
|
mstack->pop();
|
||||||
|
// There should always be one matrix left.
|
||||||
|
assert(!mstack->empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::loadIdentity()
|
||||||
|
{
|
||||||
|
glm::mat4 &top = mstack->top();
|
||||||
|
top = glm::mat4(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::translate(const glm::vec3 &t)
|
||||||
|
{
|
||||||
|
glm::mat4 &top = mstack->top();
|
||||||
|
top *= glm::translate(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::translate(float x, float y, float z)
|
||||||
|
{
|
||||||
|
translate(glm::vec3(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::scale(const glm::vec3 &s)
|
||||||
|
{
|
||||||
|
glm::mat4 &top = mstack->top();
|
||||||
|
top *= glm::scale(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::scale(float x, float y, float z)
|
||||||
|
{
|
||||||
|
scale(glm::vec3(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::scale(float s)
|
||||||
|
{
|
||||||
|
scale(glm::vec3(s, s, s));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::rotate(float angle, const glm::vec3 &axis)
|
||||||
|
{
|
||||||
|
glm::mat4 &top = mstack->top();
|
||||||
|
top *= glm::rotate(angle, axis);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::rotate(float angle, float x, float y, float z)
|
||||||
|
{
|
||||||
|
rotate(angle, glm::vec3(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::multMatrix(const glm::mat4 &matrix)
|
||||||
|
{
|
||||||
|
glm::mat4 &top = mstack->top();
|
||||||
|
top *= matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
const glm::mat4 &MatrixStack::topMatrix() const
|
||||||
|
{
|
||||||
|
return mstack->top();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::print(const glm::mat4 &mat, const char *name)
|
||||||
|
{
|
||||||
|
if(name) {
|
||||||
|
printf("%s = [\n", name);
|
||||||
|
}
|
||||||
|
for(int i = 0; i < 4; ++i) {
|
||||||
|
for(int j = 0; j < 4; ++j) {
|
||||||
|
// mat[j] returns the jth column
|
||||||
|
printf("%- 5.2f ", mat[j][i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
if(name) {
|
||||||
|
printf("];");
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::print(const char *name) const
|
||||||
|
{
|
||||||
|
print(mstack->top(), name);
|
||||||
|
}
|
50
L09/src/MatrixStack.h
Normal file
50
L09/src/MatrixStack.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef _MatrixStack_H_
|
||||||
|
#define _MatrixStack_H_
|
||||||
|
|
||||||
|
#include <stack>
|
||||||
|
#include <memory>
|
||||||
|
#include <glm/fwd.hpp>
|
||||||
|
|
||||||
|
class MatrixStack
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MatrixStack();
|
||||||
|
virtual ~MatrixStack();
|
||||||
|
|
||||||
|
// glPushMatrix(): Copies the current matrix and adds it to the top of the stack
|
||||||
|
void pushMatrix();
|
||||||
|
// glPopMatrix(): Removes the top of the stack and sets the current matrix to be the matrix that is now on top
|
||||||
|
void popMatrix();
|
||||||
|
|
||||||
|
// glLoadIdentity(): Sets the top matrix to be the identity
|
||||||
|
void loadIdentity();
|
||||||
|
// glMultMatrix(): Right multiplies the top matrix
|
||||||
|
void multMatrix(const glm::mat4 &matrix);
|
||||||
|
|
||||||
|
// glTranslate(): Right multiplies the top matrix by a translation matrix
|
||||||
|
void translate(const glm::vec3 &trans);
|
||||||
|
void translate(float x, float y, float z);
|
||||||
|
// glScale(): Right multiplies the top matrix by a scaling matrix
|
||||||
|
void scale(const glm::vec3 &scale);
|
||||||
|
void scale(float x, float y, float z);
|
||||||
|
// glScale(): Right multiplies the top matrix by a scaling matrix
|
||||||
|
void scale(float size);
|
||||||
|
// glRotate(): Right multiplies the top matrix by a rotation matrix (angle in radians)
|
||||||
|
void rotate(float angle, const glm::vec3 &axis);
|
||||||
|
void rotate(float angle, float x, float y, float z);
|
||||||
|
|
||||||
|
// glGet(GL_MODELVIEW_MATRIX): Gets the top matrix
|
||||||
|
const glm::mat4 &topMatrix() const;
|
||||||
|
|
||||||
|
// Prints out the specified matrix
|
||||||
|
static void print(const glm::mat4 &mat, const char *name = 0);
|
||||||
|
// Prints out the top matrix
|
||||||
|
void print(const char *name = 0) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr< std::stack<glm::mat4> > mstack;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
126
L09/src/Program.cpp
Normal file
126
L09/src/Program.cpp
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
#include "Program.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include "GLSL.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
Program::Program() :
|
||||||
|
vShaderName(""),
|
||||||
|
fShaderName(""),
|
||||||
|
pid(0),
|
||||||
|
verbose(true)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Program::~Program()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Program::setShaderNames(const string &v, const string &f)
|
||||||
|
{
|
||||||
|
vShaderName = v;
|
||||||
|
fShaderName = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Program::init()
|
||||||
|
{
|
||||||
|
GLint rc;
|
||||||
|
|
||||||
|
// Create shader handles
|
||||||
|
GLuint VS = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
GLuint FS = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
|
||||||
|
// Read shader sources
|
||||||
|
const char *vshader = GLSL::textFileRead(vShaderName.c_str());
|
||||||
|
const char *fshader = GLSL::textFileRead(fShaderName.c_str());
|
||||||
|
glShaderSource(VS, 1, &vshader, NULL);
|
||||||
|
glShaderSource(FS, 1, &fshader, NULL);
|
||||||
|
|
||||||
|
// Compile vertex shader
|
||||||
|
glCompileShader(VS);
|
||||||
|
glGetShaderiv(VS, GL_COMPILE_STATUS, &rc);
|
||||||
|
if(!rc) {
|
||||||
|
if(isVerbose()) {
|
||||||
|
GLSL::printShaderInfoLog(VS);
|
||||||
|
cout << "Error compiling vertex shader " << vShaderName << endl;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compile fragment shader
|
||||||
|
glCompileShader(FS);
|
||||||
|
glGetShaderiv(FS, GL_COMPILE_STATUS, &rc);
|
||||||
|
if(!rc) {
|
||||||
|
if(isVerbose()) {
|
||||||
|
GLSL::printShaderInfoLog(FS);
|
||||||
|
cout << "Error compiling fragment shader " << fShaderName << endl;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the program and link
|
||||||
|
pid = glCreateProgram();
|
||||||
|
glAttachShader(pid, VS);
|
||||||
|
glAttachShader(pid, FS);
|
||||||
|
glLinkProgram(pid);
|
||||||
|
glGetProgramiv(pid, GL_LINK_STATUS, &rc);
|
||||||
|
if(!rc) {
|
||||||
|
if(isVerbose()) {
|
||||||
|
GLSL::printProgramInfoLog(pid);
|
||||||
|
cout << "Error linking shaders " << vShaderName << " and " << fShaderName << endl;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLSL::checkError(GET_FILE_LINE);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Program::bind()
|
||||||
|
{
|
||||||
|
glUseProgram(pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Program::unbind()
|
||||||
|
{
|
||||||
|
glUseProgram(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Program::addAttribute(const string &name)
|
||||||
|
{
|
||||||
|
attributes[name] = glGetAttribLocation(pid, name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Program::addUniform(const string &name)
|
||||||
|
{
|
||||||
|
uniforms[name] = glGetUniformLocation(pid, name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint Program::getAttribute(const string &name) const
|
||||||
|
{
|
||||||
|
map<string,GLint>::const_iterator attribute = attributes.find(name.c_str());
|
||||||
|
if(attribute == attributes.end()) {
|
||||||
|
if(isVerbose()) {
|
||||||
|
cout << name << " is not an attribute variable" << endl;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return attribute->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint Program::getUniform(const string &name) const
|
||||||
|
{
|
||||||
|
map<string,GLint>::const_iterator uniform = uniforms.find(name.c_str());
|
||||||
|
if(uniform == uniforms.end()) {
|
||||||
|
if(isVerbose()) {
|
||||||
|
cout << name << " is not a uniform variable" << endl;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return uniform->second;
|
||||||
|
}
|
44
L09/src/Program.h
Normal file
44
L09/src/Program.h
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef __Program__
|
||||||
|
#define __Program__
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#define GLEW_STATIC
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An OpenGL Program (vertex and fragment shaders)
|
||||||
|
*/
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Program();
|
||||||
|
virtual ~Program();
|
||||||
|
|
||||||
|
void setVerbose(bool v) { verbose = v; }
|
||||||
|
bool isVerbose() const { return verbose; }
|
||||||
|
|
||||||
|
void setShaderNames(const std::string &v, const std::string &f);
|
||||||
|
virtual bool init();
|
||||||
|
virtual void bind();
|
||||||
|
virtual void unbind();
|
||||||
|
|
||||||
|
void addAttribute(const std::string &name);
|
||||||
|
void addUniform(const std::string &name);
|
||||||
|
GLint getAttribute(const std::string &name) const;
|
||||||
|
GLint getUniform(const std::string &name) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string vShaderName;
|
||||||
|
std::string fShaderName;
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLuint pid;
|
||||||
|
std::map<std::string,GLint> attributes;
|
||||||
|
std::map<std::string,GLint> uniforms;
|
||||||
|
bool verbose;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
80
L09/src/Texture.cpp
Normal file
80
L09/src/Texture.cpp
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
#include "Texture.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <iostream>
|
||||||
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
|
#include "stb_image.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
Texture::Texture() :
|
||||||
|
filename(""),
|
||||||
|
tid(0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Texture::~Texture()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture::init()
|
||||||
|
{
|
||||||
|
// Load texture
|
||||||
|
int w, h, ncomps;
|
||||||
|
stbi_set_flip_vertically_on_load(true);
|
||||||
|
unsigned char *data = stbi_load(filename.c_str(), &w, &h, &ncomps, 0);
|
||||||
|
if(!data) {
|
||||||
|
cerr << filename << " not found" << endl;
|
||||||
|
}
|
||||||
|
if(ncomps != 3) {
|
||||||
|
cerr << filename << " must have 3 components (RGB)" << endl;
|
||||||
|
}
|
||||||
|
if((w & (w - 1)) != 0 || (h & (h - 1)) != 0) {
|
||||||
|
cerr << filename << " must be a power of 2" << endl;
|
||||||
|
}
|
||||||
|
width = w;
|
||||||
|
height = h;
|
||||||
|
|
||||||
|
// Generate a texture buffer object
|
||||||
|
glGenTextures(1, &tid);
|
||||||
|
// Bind the current texture to be the newly generated texture object
|
||||||
|
glBindTexture(GL_TEXTURE_2D, tid);
|
||||||
|
// Load the actual texture data
|
||||||
|
// Base level is 0, number of channels is 3, and border is 0.
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, ncomps, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
||||||
|
// Generate image pyramid
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
// Set texture wrap modes for the S and T directions
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
// Set filtering mode for magnification and minimification
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
|
// Unbind
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
// Free image, since the data is now on the GPU
|
||||||
|
stbi_image_free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture::setWrapModes(GLint wrapS, GLint wrapT)
|
||||||
|
{
|
||||||
|
// Must be called after init()
|
||||||
|
glBindTexture(GL_TEXTURE_2D, tid);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS);
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture::bind(GLint handle)
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE0 + unit);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, tid);
|
||||||
|
glUniform1i(handle, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Texture::unbind()
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE0 + unit);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
}
|
32
L09/src/Texture.h
Normal file
32
L09/src/Texture.h
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef __Texture__
|
||||||
|
#define __Texture__
|
||||||
|
|
||||||
|
#define GLEW_STATIC
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class Texture
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Texture();
|
||||||
|
virtual ~Texture();
|
||||||
|
void setFilename(const std::string &f) { filename = f; }
|
||||||
|
void init();
|
||||||
|
void setUnit(GLint u) { unit = u; }
|
||||||
|
GLint getUnit() const { return unit; }
|
||||||
|
void bind(GLint handle);
|
||||||
|
void unbind();
|
||||||
|
void setWrapModes(GLint wrapS, GLint wrapT); // Must be called after init()
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string filename;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
GLuint tid;
|
||||||
|
GLint unit;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
312
L09/src/main.cpp
Normal file
312
L09/src/main.cpp
Normal file
|
@ -0,0 +1,312 @@
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
#define _USE_MATH_DEFINES
|
||||||
|
#include <cmath>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
#define GLEW_STATIC
|
||||||
|
#include <GL/glew.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#define GLM_FORCE_RADIANS
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
|
||||||
|
#include "Camera.h"
|
||||||
|
#include "GLSL.h"
|
||||||
|
#include "MatrixStack.h"
|
||||||
|
#include "Program.h"
|
||||||
|
#include "Texture.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
GLFWwindow *window; // Main application window
|
||||||
|
string RESOURCE_DIR = "./"; // Where the resources are loaded from
|
||||||
|
|
||||||
|
shared_ptr<Camera> camera;
|
||||||
|
shared_ptr<Program> prog;
|
||||||
|
shared_ptr<Texture> texture0;
|
||||||
|
shared_ptr<Texture> texture1;
|
||||||
|
|
||||||
|
vector<float> posBuf;
|
||||||
|
vector<float> texBuf;
|
||||||
|
vector<unsigned int> indBuf;
|
||||||
|
map<string,GLuint> bufIDs;
|
||||||
|
int indCount;
|
||||||
|
|
||||||
|
glm::mat3 T1;
|
||||||
|
|
||||||
|
bool keyToggles[256] = {false}; // only for English keyboards!
|
||||||
|
|
||||||
|
// This function is called when a GLFW error occurs
|
||||||
|
static void error_callback(int error, const char *description)
|
||||||
|
{
|
||||||
|
cerr << description << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is called when a key is pressed
|
||||||
|
static void key_callback(GLFWwindow *window, int key, int scancode, int action, int mods)
|
||||||
|
{
|
||||||
|
if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
|
||||||
|
glfwSetWindowShouldClose(window, GL_TRUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is called when the mouse is clicked
|
||||||
|
static void mouse_button_callback(GLFWwindow *window, int button, int action, int mods)
|
||||||
|
{
|
||||||
|
// Get the current mouse position.
|
||||||
|
double xmouse, ymouse;
|
||||||
|
glfwGetCursorPos(window, &xmouse, &ymouse);
|
||||||
|
// Get current window size.
|
||||||
|
int width, height;
|
||||||
|
glfwGetWindowSize(window, &width, &height);
|
||||||
|
if(action == GLFW_PRESS) {
|
||||||
|
bool shift = (mods & GLFW_MOD_SHIFT) != 0;
|
||||||
|
bool ctrl = (mods & GLFW_MOD_CONTROL) != 0;
|
||||||
|
bool alt = (mods & GLFW_MOD_ALT) != 0;
|
||||||
|
camera->mouseClicked((float)xmouse, (float)ymouse, shift, ctrl, alt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is called when the mouse moves
|
||||||
|
static void cursor_position_callback(GLFWwindow* window, double xmouse, double ymouse)
|
||||||
|
{
|
||||||
|
int state = glfwGetMouseButton(window, GLFW_MOUSE_BUTTON_LEFT);
|
||||||
|
if(state == GLFW_PRESS) {
|
||||||
|
camera->mouseMoved((float)xmouse, (float)ymouse);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void char_callback(GLFWwindow *window, unsigned int key)
|
||||||
|
{
|
||||||
|
keyToggles[key] = !keyToggles[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the window is resized, capture the new size and reset the viewport
|
||||||
|
static void resize_callback(GLFWwindow *window, int width, int height)
|
||||||
|
{
|
||||||
|
glViewport(0, 0, width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is called once to initialize the scene and OpenGL
|
||||||
|
static void init()
|
||||||
|
{
|
||||||
|
// Initialize time.
|
||||||
|
glfwSetTime(0.0);
|
||||||
|
|
||||||
|
// Set background color.
|
||||||
|
glClearColor(0.1f, 0.2f, 0.4f, 1.0f);
|
||||||
|
// Enable z-buffer test.
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
prog = make_shared<Program>();
|
||||||
|
prog->setShaderNames(RESOURCE_DIR + "vert.glsl", RESOURCE_DIR + "frag.glsl");
|
||||||
|
prog->setVerbose(true);
|
||||||
|
prog->init();
|
||||||
|
prog->addAttribute("aPos");
|
||||||
|
prog->addAttribute("aTex");
|
||||||
|
prog->addUniform("MV");
|
||||||
|
prog->addUniform("P");
|
||||||
|
prog->addUniform("T1");
|
||||||
|
prog->addUniform("texture0");
|
||||||
|
prog->addUniform("texture1");
|
||||||
|
prog->setVerbose(false);
|
||||||
|
|
||||||
|
camera = make_shared<Camera>();
|
||||||
|
camera->setInitDistance(3.0f);
|
||||||
|
|
||||||
|
texture0 = make_shared<Texture>();
|
||||||
|
texture0->setFilename(RESOURCE_DIR + "tamu.jpg");
|
||||||
|
texture0->init();
|
||||||
|
texture0->setUnit(0);
|
||||||
|
texture0->setWrapModes(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
|
texture1 = make_shared<Texture>();
|
||||||
|
texture1->setFilename(RESOURCE_DIR + "reveille.jpg");
|
||||||
|
texture1->init();
|
||||||
|
texture1->setUnit(1);
|
||||||
|
texture1->setWrapModes(GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
|
//
|
||||||
|
// Texture matrix
|
||||||
|
//
|
||||||
|
T1[0][0] = 1.0f;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Initialize geometry
|
||||||
|
//
|
||||||
|
// We need to fill in the position buffer, normal buffer, the texcoord
|
||||||
|
// buffer, and the index buffer.
|
||||||
|
// 0
|
||||||
|
posBuf.push_back(-1.0f);
|
||||||
|
posBuf.push_back(-1.0f);
|
||||||
|
posBuf.push_back(0.0f);
|
||||||
|
texBuf.push_back(0.0f);
|
||||||
|
texBuf.push_back(0.0f);
|
||||||
|
// 1
|
||||||
|
posBuf.push_back(1.0f);
|
||||||
|
posBuf.push_back(-1.0f);
|
||||||
|
posBuf.push_back(0.0f);
|
||||||
|
texBuf.push_back(0.0f);
|
||||||
|
texBuf.push_back(0.0f);
|
||||||
|
// 2
|
||||||
|
posBuf.push_back(-1.0f);
|
||||||
|
posBuf.push_back(1.0f);
|
||||||
|
posBuf.push_back(0.0f);
|
||||||
|
texBuf.push_back(0.0f);
|
||||||
|
texBuf.push_back(0.0f);
|
||||||
|
// 3
|
||||||
|
posBuf.push_back(1.0f);
|
||||||
|
posBuf.push_back(1.0f);
|
||||||
|
posBuf.push_back(0.0f);
|
||||||
|
texBuf.push_back(0.0f);
|
||||||
|
texBuf.push_back(0.0f);
|
||||||
|
// Index
|
||||||
|
indBuf.push_back(0);
|
||||||
|
indBuf.push_back(1);
|
||||||
|
indBuf.push_back(2);
|
||||||
|
indBuf.push_back(3);
|
||||||
|
indBuf.push_back(2);
|
||||||
|
indBuf.push_back(1);
|
||||||
|
indCount = (int)indBuf.size();
|
||||||
|
|
||||||
|
// Generate 3 buffer IDs and put them in the bufIDs map.
|
||||||
|
GLuint tmp[3];
|
||||||
|
glGenBuffers(3, tmp);
|
||||||
|
bufIDs["bPos"] = tmp[0];
|
||||||
|
bufIDs["bTex"] = tmp[1];
|
||||||
|
bufIDs["bInd"] = tmp[2];
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, bufIDs["bPos"]);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, posBuf.size()*sizeof(float), &posBuf[0], GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, bufIDs["bTex"]);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, texBuf.size()*sizeof(float), &texBuf[0], GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufIDs["bInd"]);
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indBuf.size()*sizeof(unsigned int), &indBuf[0], GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
GLSL::checkError(GET_FILE_LINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This function is called every frame to draw the scene.
|
||||||
|
static void render()
|
||||||
|
{
|
||||||
|
// Clear framebuffer.
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
if(keyToggles[(unsigned)'c']) {
|
||||||
|
glEnable(GL_CULL_FACE);
|
||||||
|
} else {
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
}
|
||||||
|
if(keyToggles[(unsigned)'l']) {
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||||
|
} else {
|
||||||
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get current frame buffer size.
|
||||||
|
int width, height;
|
||||||
|
glfwGetFramebufferSize(window, &width, &height);
|
||||||
|
camera->setAspect((float)width/(float)height);
|
||||||
|
|
||||||
|
// Matrix stacks
|
||||||
|
auto P = make_shared<MatrixStack>();
|
||||||
|
auto MV = make_shared<MatrixStack>();
|
||||||
|
|
||||||
|
// Apply camera transforms
|
||||||
|
P->pushMatrix();
|
||||||
|
camera->applyProjectionMatrix(P);
|
||||||
|
MV->pushMatrix();
|
||||||
|
camera->applyViewMatrix(MV);
|
||||||
|
|
||||||
|
prog->bind();
|
||||||
|
texture0->bind(prog->getUniform("texture0"));
|
||||||
|
texture1->bind(prog->getUniform("texture1"));
|
||||||
|
glUniformMatrix4fv(prog->getUniform("P"), 1, GL_FALSE, glm::value_ptr(P->topMatrix()));
|
||||||
|
glUniformMatrix4fv(prog->getUniform("MV"), 1, GL_FALSE, glm::value_ptr(MV->topMatrix()));
|
||||||
|
glUniformMatrix3fv(prog->getUniform("T1"), 1, GL_FALSE, glm::value_ptr(T1));
|
||||||
|
glEnableVertexAttribArray(prog->getAttribute("aPos"));
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, bufIDs["bPos"]);
|
||||||
|
glVertexAttribPointer(prog->getAttribute("aPos"), 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
|
||||||
|
glEnableVertexAttribArray(prog->getAttribute("aTex"));
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, bufIDs["bTex"]);
|
||||||
|
glVertexAttribPointer(prog->getAttribute("aTex"), 2, GL_FLOAT, GL_FALSE, 0, (void *)0);
|
||||||
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bufIDs["bInd"]);
|
||||||
|
glDrawElements(GL_TRIANGLES, indCount, GL_UNSIGNED_INT, (void *)0);
|
||||||
|
texture1->unbind();
|
||||||
|
texture0->unbind();
|
||||||
|
prog->unbind();
|
||||||
|
|
||||||
|
MV->popMatrix();
|
||||||
|
P->popMatrix();
|
||||||
|
|
||||||
|
GLSL::checkError(GET_FILE_LINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
if(argc < 2) {
|
||||||
|
cout << "Please specify the resource directory." << endl;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
RESOURCE_DIR = argv[1] + string("/");
|
||||||
|
|
||||||
|
// Set error callback.
|
||||||
|
glfwSetErrorCallback(error_callback);
|
||||||
|
// Initialize the library.
|
||||||
|
if(!glfwInit()) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// Create a windowed mode window and its OpenGL context.
|
||||||
|
window = glfwCreateWindow(640, 480, "YOUR NAME", NULL, NULL);
|
||||||
|
if(!window) {
|
||||||
|
glfwTerminate();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
// Make the window's context current.
|
||||||
|
glfwMakeContextCurrent(window);
|
||||||
|
// Initialize GLEW.
|
||||||
|
glewExperimental = true;
|
||||||
|
if(glewInit() != GLEW_OK) {
|
||||||
|
cerr << "Failed to initialize GLEW" << endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
glGetError(); // A bug in glewInit() causes an error that we can safely ignore.
|
||||||
|
cout << "OpenGL version: " << glGetString(GL_VERSION) << endl;
|
||||||
|
cout << "GLSL version: " << glGetString(GL_SHADING_LANGUAGE_VERSION) << endl;
|
||||||
|
GLSL::checkVersion();
|
||||||
|
// Set vsync.
|
||||||
|
glfwSwapInterval(1);
|
||||||
|
// Set keyboard callback.
|
||||||
|
glfwSetKeyCallback(window, key_callback);
|
||||||
|
// Set char callback.
|
||||||
|
glfwSetCharCallback(window, char_callback);
|
||||||
|
// Set cursor position callback.
|
||||||
|
glfwSetCursorPosCallback(window, cursor_position_callback);
|
||||||
|
// Set mouse button callback.
|
||||||
|
glfwSetMouseButtonCallback(window, mouse_button_callback);
|
||||||
|
// Set the window resize call back.
|
||||||
|
glfwSetFramebufferSizeCallback(window, resize_callback);
|
||||||
|
// Initialize scene.
|
||||||
|
init();
|
||||||
|
// Loop until the user closes the window.
|
||||||
|
while(!glfwWindowShouldClose(window)) {
|
||||||
|
// Render scene.
|
||||||
|
render();
|
||||||
|
// Swap front and back buffers.
|
||||||
|
glfwSwapBuffers(window);
|
||||||
|
// Poll for and process events.
|
||||||
|
glfwPollEvents();
|
||||||
|
}
|
||||||
|
// Quit program.
|
||||||
|
glfwDestroyWindow(window);
|
||||||
|
glfwTerminate();
|
||||||
|
return 0;
|
||||||
|
}
|
6755
L09/src/stb_image.h
Normal file
6755
L09/src/stb_image.h
Normal file
File diff suppressed because it is too large
Load diff
BIN
L10.zip
Normal file
BIN
L10.zip
Normal file
Binary file not shown.
127
L10/CMakeLists.txt
Normal file
127
L10/CMakeLists.txt
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||||
|
|
||||||
|
# Name of the project
|
||||||
|
PROJECT(L10)
|
||||||
|
|
||||||
|
# FOR LAB MACHINES ONLY!
|
||||||
|
# DO NOT EDIT
|
||||||
|
SET(DEF_DIR_GLM "C:\\c++\\glm")
|
||||||
|
SET(DEF_DIR_GLFW "C:\\c++\\glfw-3.2.1")
|
||||||
|
SET(DEF_DIR_GLEW "C:\\c++\\glew-2.0.0")
|
||||||
|
|
||||||
|
# Is this the solution?
|
||||||
|
# Override with `cmake -DSOL=ON ..`
|
||||||
|
OPTION(SOL "Solution" OFF)
|
||||||
|
|
||||||
|
# Use glob to get the list of all source files.
|
||||||
|
# We don't really need to include header and resource files to build, but it's
|
||||||
|
# nice to have them also show up in IDEs.
|
||||||
|
IF(${SOL})
|
||||||
|
FILE(GLOB_RECURSE SOURCES "src0/*.cpp")
|
||||||
|
FILE(GLOB_RECURSE HEADERS "src0/*.h")
|
||||||
|
FILE(GLOB_RECURSE GLSL "resources0/*.glsl")
|
||||||
|
ELSE()
|
||||||
|
FILE(GLOB_RECURSE SOURCES "src/*.cpp")
|
||||||
|
FILE(GLOB_RECURSE HEADERS "src/*.h")
|
||||||
|
FILE(GLOB_RECURSE GLSL "resources/*.glsl")
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# Set the executable.
|
||||||
|
ADD_EXECUTABLE(${CMAKE_PROJECT_NAME} ${SOURCES} ${HEADERS} ${GLSL})
|
||||||
|
|
||||||
|
# Get the GLM environment variable. Since GLM is a header-only library, we
|
||||||
|
# just need to add it to the include directory.
|
||||||
|
SET(GLM_INCLUDE_DIR "$ENV{GLM_INCLUDE_DIR}")
|
||||||
|
IF(NOT GLM_INCLUDE_DIR)
|
||||||
|
# The environment variable was not set
|
||||||
|
SET(ERR_MSG "Please point the environment variable GLM_INCLUDE_DIR to the root directory of your GLM installation.")
|
||||||
|
IF(WIN32)
|
||||||
|
# On Windows, try the default location
|
||||||
|
MESSAGE(STATUS "Looking for GLM in ${DEF_DIR_GLM}")
|
||||||
|
IF(IS_DIRECTORY ${DEF_DIR_GLM})
|
||||||
|
MESSAGE(STATUS "Found!")
|
||||||
|
SET(GLM_INCLUDE_DIR ${DEF_DIR_GLM})
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
INCLUDE_DIRECTORIES(${GLM_INCLUDE_DIR})
|
||||||
|
|
||||||
|
# Get the GLFW environment variable. There should be a CMakeLists.txt in the
|
||||||
|
# specified directory.
|
||||||
|
SET(GLFW_DIR "$ENV{GLFW_DIR}")
|
||||||
|
IF(NOT GLFW_DIR)
|
||||||
|
# The environment variable was not set
|
||||||
|
SET(ERR_MSG "Please point the environment variable GLFW_DIR to the root directory of your GLFW installation.")
|
||||||
|
IF(WIN32)
|
||||||
|
# On Windows, try the default location
|
||||||
|
MESSAGE(STATUS "Looking for GLFW in ${DEF_DIR_GLFW}")
|
||||||
|
IF(IS_DIRECTORY ${DEF_DIR_GLFW})
|
||||||
|
MESSAGE(STATUS "Found!")
|
||||||
|
SET(GLFW_DIR ${DEF_DIR_GLFW})
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
OPTION(GLFW_BUILD_EXAMPLES "GLFW_BUILD_EXAMPLES" OFF)
|
||||||
|
OPTION(GLFW_BUILD_TESTS "GLFW_BUILD_TESTS" OFF)
|
||||||
|
OPTION(GLFW_BUILD_DOCS "GLFW_BUILD_DOCS" OFF)
|
||||||
|
IF(CMAKE_BUILD_TYPE MATCHES Release)
|
||||||
|
ADD_SUBDIRECTORY(${GLFW_DIR} ${GLFW_DIR}/release)
|
||||||
|
ELSE()
|
||||||
|
ADD_SUBDIRECTORY(${GLFW_DIR} ${GLFW_DIR}/debug)
|
||||||
|
ENDIF()
|
||||||
|
INCLUDE_DIRECTORIES(${GLFW_DIR}/include)
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} glfw ${GLFW_LIBRARIES})
|
||||||
|
|
||||||
|
# Get the GLEW environment variable.
|
||||||
|
SET(GLEW_DIR "$ENV{GLEW_DIR}")
|
||||||
|
IF(NOT GLEW_DIR)
|
||||||
|
# The environment variable was not set
|
||||||
|
SET(ERR_MSG "Please point the environment variable GLEW_DIR to the root directory of your GLEW installation.")
|
||||||
|
IF(WIN32)
|
||||||
|
# On Windows, try the default location
|
||||||
|
MESSAGE(STATUS "Looking for GLEW in ${DEF_DIR_GLEW}")
|
||||||
|
IF(IS_DIRECTORY ${DEF_DIR_GLEW})
|
||||||
|
MESSAGE(STATUS "Found!")
|
||||||
|
SET(GLEW_DIR ${DEF_DIR_GLEW})
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ELSE()
|
||||||
|
MESSAGE(FATAL_ERROR ${ERR_MSG})
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
||||||
|
INCLUDE_DIRECTORIES(${GLEW_DIR}/include)
|
||||||
|
IF(WIN32)
|
||||||
|
# With prebuilt binaries
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} ${GLEW_DIR}/lib/Release/Win32/glew32s.lib)
|
||||||
|
ELSE()
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} ${GLEW_DIR}/lib/libGLEW.a)
|
||||||
|
ENDIF()
|
||||||
|
|
||||||
|
# OS specific options and libraries
|
||||||
|
IF(WIN32)
|
||||||
|
# c++11 is enabled by default.
|
||||||
|
# -Wall produces way too many warnings.
|
||||||
|
# -pedantic is not supported.
|
||||||
|
# Disable warning 4996.
|
||||||
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4996")
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} opengl32.lib)
|
||||||
|
ELSE()
|
||||||
|
# Enable all pedantic warnings.
|
||||||
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -pedantic")
|
||||||
|
IF(APPLE)
|
||||||
|
# Add required frameworks for GLFW.
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} "-framework OpenGL -framework Cocoa -framework IOKit -framework CoreVideo")
|
||||||
|
ELSE()
|
||||||
|
#Link the Linux OpenGL library
|
||||||
|
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME} "GL")
|
||||||
|
ENDIF()
|
||||||
|
ENDIF()
|
BIN
L10/resources/earthClouds.jpg
Normal file
BIN
L10/resources/earthClouds.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 359 KiB |
BIN
L10/resources/earthKd.jpg
Normal file
BIN
L10/resources/earthKd.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 375 KiB |
BIN
L10/resources/earthKs.jpg
Normal file
BIN
L10/resources/earthKs.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 216 KiB |
14
L10/resources/frag.glsl
Normal file
14
L10/resources/frag.glsl
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
uniform sampler2D texture0;
|
||||||
|
uniform sampler2D texture1;
|
||||||
|
uniform sampler2D texture2;
|
||||||
|
uniform vec3 lightPosCam;
|
||||||
|
|
||||||
|
varying vec2 vTex0;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
vec3 kd = texture2D(texture0, vTex0).rgb;
|
||||||
|
gl_FragColor = vec4(kd, 1.0);
|
||||||
|
}
|
1834
L10/resources/sphere.obj
Normal file
1834
L10/resources/sphere.obj
Normal file
File diff suppressed because it is too large
Load diff
11
L10/resources/square.obj
Normal file
11
L10/resources/square.obj
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
v -0.500000 -0.500000 0.000000
|
||||||
|
v 0.500000 -0.500000 0.000000
|
||||||
|
v -0.500000 0.500000 0.000000
|
||||||
|
v 0.500000 0.500000 0.000000
|
||||||
|
vn 0.000000 0.000000 1.000000
|
||||||
|
vt 0 0
|
||||||
|
vt 1 0
|
||||||
|
vt 0 1
|
||||||
|
vt 1 1
|
||||||
|
f 2/2/1 4/4/1 3/3/1
|
||||||
|
f 1/1/1 2/2/1 3/3/1
|
17
L10/resources/vert.glsl
Normal file
17
L10/resources/vert.glsl
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
#version 120
|
||||||
|
|
||||||
|
uniform mat4 P;
|
||||||
|
uniform mat4 MV;
|
||||||
|
uniform mat3 T;
|
||||||
|
|
||||||
|
attribute vec4 aPos;
|
||||||
|
attribute vec3 aNor;
|
||||||
|
attribute vec2 aTex;
|
||||||
|
|
||||||
|
varying vec2 vTex0;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
gl_Position = P * MV * aPos;
|
||||||
|
vTex0 = aTex;
|
||||||
|
}
|
68
L10/src/Camera.cpp
Normal file
68
L10/src/Camera.cpp
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
#include "Camera.h"
|
||||||
|
#include "MatrixStack.h"
|
||||||
|
#include <iostream>
|
||||||
|
#define _USE_MATH_DEFINES
|
||||||
|
#include <cmath>
|
||||||
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
|
Camera::Camera() :
|
||||||
|
aspect(1.0f),
|
||||||
|
fovy((float)(45.0*M_PI/180.0)),
|
||||||
|
znear(0.1f),
|
||||||
|
zfar(1000.0f),
|
||||||
|
rotations(0.0, 0.0),
|
||||||
|
translations(0.0f, 0.0f, -5.0f),
|
||||||
|
rfactor(0.01f),
|
||||||
|
tfactor(0.001f),
|
||||||
|
sfactor(0.005f)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Camera::~Camera()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::mouseClicked(float x, float y, bool shift, bool ctrl, bool alt)
|
||||||
|
{
|
||||||
|
mousePrev.x = x;
|
||||||
|
mousePrev.y = y;
|
||||||
|
if(shift) {
|
||||||
|
state = Camera::TRANSLATE;
|
||||||
|
} else if(ctrl) {
|
||||||
|
state = Camera::SCALE;
|
||||||
|
} else {
|
||||||
|
state = Camera::ROTATE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::mouseMoved(float x, float y)
|
||||||
|
{
|
||||||
|
glm::vec2 mouseCurr(x, y);
|
||||||
|
glm::vec2 dv = mouseCurr - mousePrev;
|
||||||
|
switch(state) {
|
||||||
|
case Camera::ROTATE:
|
||||||
|
rotations += rfactor * dv;
|
||||||
|
break;
|
||||||
|
case Camera::TRANSLATE:
|
||||||
|
translations.x -= translations.z * tfactor * dv.x;
|
||||||
|
translations.y += translations.z * tfactor * dv.y;
|
||||||
|
break;
|
||||||
|
case Camera::SCALE:
|
||||||
|
translations.z *= (1.0f - sfactor * dv.y);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mousePrev = mouseCurr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::applyProjectionMatrix(std::shared_ptr<MatrixStack> P) const
|
||||||
|
{
|
||||||
|
// Modify provided MatrixStack
|
||||||
|
P->multMatrix(glm::perspective(fovy, aspect, znear, zfar));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Camera::applyViewMatrix(std::shared_ptr<MatrixStack> MV) const
|
||||||
|
{
|
||||||
|
MV->translate(translations);
|
||||||
|
MV->rotate(rotations.y, glm::vec3(1.0f, 0.0f, 0.0f));
|
||||||
|
MV->rotate(rotations.x, glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
|
}
|
47
L10/src/Camera.h
Normal file
47
L10/src/Camera.h
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef __Camera__
|
||||||
|
#define __Camera__
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#define GLM_FORCE_RADIANS
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
class MatrixStack;
|
||||||
|
|
||||||
|
class Camera
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum {
|
||||||
|
ROTATE = 0,
|
||||||
|
TRANSLATE,
|
||||||
|
SCALE
|
||||||
|
};
|
||||||
|
|
||||||
|
Camera();
|
||||||
|
virtual ~Camera();
|
||||||
|
void setInitDistance(float z) { translations.z = -std::abs(z); }
|
||||||
|
void setAspect(float a) { aspect = a; };
|
||||||
|
void setRotationFactor(float f) { rfactor = f; };
|
||||||
|
void setTranslationFactor(float f) { tfactor = f; };
|
||||||
|
void setScaleFactor(float f) { sfactor = f; };
|
||||||
|
void mouseClicked(float x, float y, bool shift, bool ctrl, bool alt);
|
||||||
|
void mouseMoved(float x, float y);
|
||||||
|
void applyProjectionMatrix(std::shared_ptr<MatrixStack> P) const;
|
||||||
|
void applyViewMatrix(std::shared_ptr<MatrixStack> MV) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
float aspect;
|
||||||
|
float fovy;
|
||||||
|
float znear;
|
||||||
|
float zfar;
|
||||||
|
glm::vec2 rotations;
|
||||||
|
glm::vec3 translations;
|
||||||
|
glm::vec2 mousePrev;
|
||||||
|
int state;
|
||||||
|
float rfactor;
|
||||||
|
float tfactor;
|
||||||
|
float sfactor;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
152
L10/src/GLSL.cpp
Normal file
152
L10/src/GLSL.cpp
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
//
|
||||||
|
// Many useful helper functions for GLSL shaders - gleaned from various sources including orange book
|
||||||
|
// Created by zwood on 2/21/10.
|
||||||
|
// Modified by sueda 10/15/15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "GLSL.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
namespace GLSL {
|
||||||
|
|
||||||
|
const char * errorString(GLenum err)
|
||||||
|
{
|
||||||
|
switch(err) {
|
||||||
|
case GL_NO_ERROR:
|
||||||
|
return "No error";
|
||||||
|
case GL_INVALID_ENUM:
|
||||||
|
return "Invalid enum";
|
||||||
|
case GL_INVALID_VALUE:
|
||||||
|
return "Invalid value";
|
||||||
|
case GL_INVALID_OPERATION:
|
||||||
|
return "Invalid operation";
|
||||||
|
case GL_STACK_OVERFLOW:
|
||||||
|
return "Stack overflow";
|
||||||
|
case GL_STACK_UNDERFLOW:
|
||||||
|
return "Stack underflow";
|
||||||
|
case GL_OUT_OF_MEMORY:
|
||||||
|
return "Out of memory";
|
||||||
|
default:
|
||||||
|
return "No error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkVersion()
|
||||||
|
{
|
||||||
|
int major, minor;
|
||||||
|
major = minor = 0;
|
||||||
|
const char *verstr = (const char *)glGetString(GL_VERSION);
|
||||||
|
|
||||||
|
if((verstr == NULL) || (sscanf(verstr, "%d.%d", &major, &minor) != 2)) {
|
||||||
|
printf("Invalid GL_VERSION format %d.%d\n", major, minor);
|
||||||
|
}
|
||||||
|
if(major < 2) {
|
||||||
|
printf("This shader example will not work due to the installed Opengl version, which is %d.%d.\n", major, minor);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkError(const char *str)
|
||||||
|
{
|
||||||
|
GLenum glErr = glGetError();
|
||||||
|
if(glErr != GL_NO_ERROR) {
|
||||||
|
if(str) {
|
||||||
|
printf("%s: ", str);
|
||||||
|
}
|
||||||
|
printf("GL_ERROR = %s.\n", errorString(glErr));
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void printShaderInfoLog(GLuint shader)
|
||||||
|
{
|
||||||
|
GLint infologLength = 0;
|
||||||
|
GLint charsWritten = 0;
|
||||||
|
GLchar *infoLog = 0;
|
||||||
|
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infologLength);
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
|
||||||
|
if(infologLength > 0) {
|
||||||
|
infoLog = (GLchar *)malloc(infologLength);
|
||||||
|
if(infoLog == NULL) {
|
||||||
|
puts("ERROR: Could not allocate InfoLog buffer");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
glGetShaderInfoLog(shader, infologLength, &charsWritten, infoLog);
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
printf("Shader InfoLog:\n%s\n\n", infoLog);
|
||||||
|
free(infoLog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void printProgramInfoLog(GLuint program)
|
||||||
|
{
|
||||||
|
GLint infologLength = 0;
|
||||||
|
GLint charsWritten = 0;
|
||||||
|
GLchar *infoLog = 0;
|
||||||
|
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infologLength);
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
|
||||||
|
if(infologLength > 0) {
|
||||||
|
infoLog = (GLchar *)malloc(infologLength);
|
||||||
|
if(infoLog == NULL) {
|
||||||
|
puts("ERROR: Could not allocate InfoLog buffer");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
glGetProgramInfoLog(program, infologLength, &charsWritten, infoLog);
|
||||||
|
checkError(GET_FILE_LINE);
|
||||||
|
printf("Program InfoLog:\n%s\n\n", infoLog);
|
||||||
|
free(infoLog);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
char *textFileRead(const char *fn)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char *content = NULL;
|
||||||
|
int count = 0;
|
||||||
|
if(fn != NULL) {
|
||||||
|
fp = fopen(fn,"rt");
|
||||||
|
if(fp != NULL) {
|
||||||
|
fseek(fp, 0, SEEK_END);
|
||||||
|
count = (int)ftell(fp);
|
||||||
|
rewind(fp);
|
||||||
|
if(count > 0) {
|
||||||
|
content = (char *)malloc(sizeof(char) * (count+1));
|
||||||
|
count = (int)fread(content,sizeof(char),count,fp);
|
||||||
|
content[count] = '\0';
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
} else {
|
||||||
|
printf("error loading %s\n", fn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
int textFileWrite(const char *fn, const char *s)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
int status = 0;
|
||||||
|
if(fn != NULL) {
|
||||||
|
fp = fopen(fn,"w");
|
||||||
|
if(fp != NULL) {
|
||||||
|
if(fwrite(s,sizeof(char),strlen(s),fp) == strlen(s)) {
|
||||||
|
status = 1;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
40
L10/src/GLSL.h
Normal file
40
L10/src/GLSL.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
//
|
||||||
|
// Many useful helper functions for GLSL shaders - gleaned from various sources including orange book
|
||||||
|
// Created by zwood on 2/21/10.
|
||||||
|
// Modified by sueda 10/15/15.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef __GLSL__
|
||||||
|
#define __GLSL__
|
||||||
|
|
||||||
|
#define GLEW_STATIC
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
// For printing out the current file and line number //
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
std::string NumberToString(T x)
|
||||||
|
{
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << x;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GET_FILE_LINE (std::string(__FILE__) + ":" + NumberToString(__LINE__)).c_str()
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
namespace GLSL {
|
||||||
|
|
||||||
|
void checkVersion();
|
||||||
|
void checkError(const char *str = 0);
|
||||||
|
void printProgramInfoLog(GLuint program);
|
||||||
|
void printShaderInfoLog(GLuint shader);
|
||||||
|
int textFileWrite(const char *filename, const char *s);
|
||||||
|
char *textFileRead(const char *filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
114
L10/src/MatrixStack.cpp
Normal file
114
L10/src/MatrixStack.cpp
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
#include "MatrixStack.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <cassert>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#define GLM_FORCE_RADIANS
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtx/transform.hpp>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
MatrixStack::MatrixStack()
|
||||||
|
{
|
||||||
|
mstack = make_shared< stack<glm::mat4> >();
|
||||||
|
mstack->push(glm::mat4(1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
MatrixStack::~MatrixStack()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::pushMatrix()
|
||||||
|
{
|
||||||
|
const glm::mat4 &top = mstack->top();
|
||||||
|
mstack->push(top);
|
||||||
|
assert(mstack->size() < 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::popMatrix()
|
||||||
|
{
|
||||||
|
assert(!mstack->empty());
|
||||||
|
mstack->pop();
|
||||||
|
// There should always be one matrix left.
|
||||||
|
assert(!mstack->empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::loadIdentity()
|
||||||
|
{
|
||||||
|
glm::mat4 &top = mstack->top();
|
||||||
|
top = glm::mat4(1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::translate(const glm::vec3 &t)
|
||||||
|
{
|
||||||
|
glm::mat4 &top = mstack->top();
|
||||||
|
top *= glm::translate(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::translate(float x, float y, float z)
|
||||||
|
{
|
||||||
|
translate(glm::vec3(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::scale(const glm::vec3 &s)
|
||||||
|
{
|
||||||
|
glm::mat4 &top = mstack->top();
|
||||||
|
top *= glm::scale(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::scale(float x, float y, float z)
|
||||||
|
{
|
||||||
|
scale(glm::vec3(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::scale(float s)
|
||||||
|
{
|
||||||
|
scale(glm::vec3(s, s, s));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::rotate(float angle, const glm::vec3 &axis)
|
||||||
|
{
|
||||||
|
glm::mat4 &top = mstack->top();
|
||||||
|
top *= glm::rotate(angle, axis);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::rotate(float angle, float x, float y, float z)
|
||||||
|
{
|
||||||
|
rotate(angle, glm::vec3(x, y, z));
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::multMatrix(const glm::mat4 &matrix)
|
||||||
|
{
|
||||||
|
glm::mat4 &top = mstack->top();
|
||||||
|
top *= matrix;
|
||||||
|
}
|
||||||
|
|
||||||
|
const glm::mat4 &MatrixStack::topMatrix() const
|
||||||
|
{
|
||||||
|
return mstack->top();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::print(const glm::mat4 &mat, const char *name)
|
||||||
|
{
|
||||||
|
if(name) {
|
||||||
|
printf("%s = [\n", name);
|
||||||
|
}
|
||||||
|
for(int i = 0; i < 4; ++i) {
|
||||||
|
for(int j = 0; j < 4; ++j) {
|
||||||
|
// mat[j] returns the jth column
|
||||||
|
printf("%- 5.2f ", mat[j][i]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
if(name) {
|
||||||
|
printf("];");
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void MatrixStack::print(const char *name) const
|
||||||
|
{
|
||||||
|
print(mstack->top(), name);
|
||||||
|
}
|
50
L10/src/MatrixStack.h
Normal file
50
L10/src/MatrixStack.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef _MatrixStack_H_
|
||||||
|
#define _MatrixStack_H_
|
||||||
|
|
||||||
|
#include <stack>
|
||||||
|
#include <memory>
|
||||||
|
#include <glm/fwd.hpp>
|
||||||
|
|
||||||
|
class MatrixStack
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MatrixStack();
|
||||||
|
virtual ~MatrixStack();
|
||||||
|
|
||||||
|
// glPushMatrix(): Copies the current matrix and adds it to the top of the stack
|
||||||
|
void pushMatrix();
|
||||||
|
// glPopMatrix(): Removes the top of the stack and sets the current matrix to be the matrix that is now on top
|
||||||
|
void popMatrix();
|
||||||
|
|
||||||
|
// glLoadIdentity(): Sets the top matrix to be the identity
|
||||||
|
void loadIdentity();
|
||||||
|
// glMultMatrix(): Right multiplies the top matrix
|
||||||
|
void multMatrix(const glm::mat4 &matrix);
|
||||||
|
|
||||||
|
// glTranslate(): Right multiplies the top matrix by a translation matrix
|
||||||
|
void translate(const glm::vec3 &trans);
|
||||||
|
void translate(float x, float y, float z);
|
||||||
|
// glScale(): Right multiplies the top matrix by a scaling matrix
|
||||||
|
void scale(const glm::vec3 &scale);
|
||||||
|
void scale(float x, float y, float z);
|
||||||
|
// glScale(): Right multiplies the top matrix by a scaling matrix
|
||||||
|
void scale(float size);
|
||||||
|
// glRotate(): Right multiplies the top matrix by a rotation matrix (angle in radians)
|
||||||
|
void rotate(float angle, const glm::vec3 &axis);
|
||||||
|
void rotate(float angle, float x, float y, float z);
|
||||||
|
|
||||||
|
// glGet(GL_MODELVIEW_MATRIX): Gets the top matrix
|
||||||
|
const glm::mat4 &topMatrix() const;
|
||||||
|
|
||||||
|
// Prints out the specified matrix
|
||||||
|
static void print(const glm::mat4 &mat, const char *name = 0);
|
||||||
|
// Prints out the top matrix
|
||||||
|
void print(const char *name = 0) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::shared_ptr< std::stack<glm::mat4> > mstack;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
126
L10/src/Program.cpp
Normal file
126
L10/src/Program.cpp
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
#include "Program.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#include "GLSL.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
Program::Program() :
|
||||||
|
vShaderName(""),
|
||||||
|
fShaderName(""),
|
||||||
|
pid(0),
|
||||||
|
verbose(true)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Program::~Program()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Program::setShaderNames(const string &v, const string &f)
|
||||||
|
{
|
||||||
|
vShaderName = v;
|
||||||
|
fShaderName = f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Program::init()
|
||||||
|
{
|
||||||
|
GLint rc;
|
||||||
|
|
||||||
|
// Create shader handles
|
||||||
|
GLuint VS = glCreateShader(GL_VERTEX_SHADER);
|
||||||
|
GLuint FS = glCreateShader(GL_FRAGMENT_SHADER);
|
||||||
|
|
||||||
|
// Read shader sources
|
||||||
|
const char *vshader = GLSL::textFileRead(vShaderName.c_str());
|
||||||
|
const char *fshader = GLSL::textFileRead(fShaderName.c_str());
|
||||||
|
glShaderSource(VS, 1, &vshader, NULL);
|
||||||
|
glShaderSource(FS, 1, &fshader, NULL);
|
||||||
|
|
||||||
|
// Compile vertex shader
|
||||||
|
glCompileShader(VS);
|
||||||
|
glGetShaderiv(VS, GL_COMPILE_STATUS, &rc);
|
||||||
|
if(!rc) {
|
||||||
|
if(isVerbose()) {
|
||||||
|
GLSL::printShaderInfoLog(VS);
|
||||||
|
cout << "Error compiling vertex shader " << vShaderName << endl;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compile fragment shader
|
||||||
|
glCompileShader(FS);
|
||||||
|
glGetShaderiv(FS, GL_COMPILE_STATUS, &rc);
|
||||||
|
if(!rc) {
|
||||||
|
if(isVerbose()) {
|
||||||
|
GLSL::printShaderInfoLog(FS);
|
||||||
|
cout << "Error compiling fragment shader " << fShaderName << endl;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the program and link
|
||||||
|
pid = glCreateProgram();
|
||||||
|
glAttachShader(pid, VS);
|
||||||
|
glAttachShader(pid, FS);
|
||||||
|
glLinkProgram(pid);
|
||||||
|
glGetProgramiv(pid, GL_LINK_STATUS, &rc);
|
||||||
|
if(!rc) {
|
||||||
|
if(isVerbose()) {
|
||||||
|
GLSL::printProgramInfoLog(pid);
|
||||||
|
cout << "Error linking shaders " << vShaderName << " and " << fShaderName << endl;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLSL::checkError(GET_FILE_LINE);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Program::bind()
|
||||||
|
{
|
||||||
|
glUseProgram(pid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Program::unbind()
|
||||||
|
{
|
||||||
|
glUseProgram(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Program::addAttribute(const string &name)
|
||||||
|
{
|
||||||
|
attributes[name] = glGetAttribLocation(pid, name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Program::addUniform(const string &name)
|
||||||
|
{
|
||||||
|
uniforms[name] = glGetUniformLocation(pid, name.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint Program::getAttribute(const string &name) const
|
||||||
|
{
|
||||||
|
map<string,GLint>::const_iterator attribute = attributes.find(name.c_str());
|
||||||
|
if(attribute == attributes.end()) {
|
||||||
|
if(isVerbose()) {
|
||||||
|
cout << name << " is not an attribute variable" << endl;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return attribute->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint Program::getUniform(const string &name) const
|
||||||
|
{
|
||||||
|
map<string,GLint>::const_iterator uniform = uniforms.find(name.c_str());
|
||||||
|
if(uniform == uniforms.end()) {
|
||||||
|
if(isVerbose()) {
|
||||||
|
cout << name << " is not a uniform variable" << endl;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return uniform->second;
|
||||||
|
}
|
44
L10/src/Program.h
Normal file
44
L10/src/Program.h
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
#pragma once
|
||||||
|
#ifndef __Program__
|
||||||
|
#define __Program__
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#define GLEW_STATIC
|
||||||
|
#include <GL/glew.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An OpenGL Program (vertex and fragment shaders)
|
||||||
|
*/
|
||||||
|
class Program
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Program();
|
||||||
|
virtual ~Program();
|
||||||
|
|
||||||
|
void setVerbose(bool v) { verbose = v; }
|
||||||
|
bool isVerbose() const { return verbose; }
|
||||||
|
|
||||||
|
void setShaderNames(const std::string &v, const std::string &f);
|
||||||
|
virtual bool init();
|
||||||
|
virtual void bind();
|
||||||
|
virtual void unbind();
|
||||||
|
|
||||||
|
void addAttribute(const std::string &name);
|
||||||
|
void addUniform(const std::string &name);
|
||||||
|
GLint getAttribute(const std::string &name) const;
|
||||||
|
GLint getUniform(const std::string &name) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::string vShaderName;
|
||||||
|
std::string fShaderName;
|
||||||
|
|
||||||
|
private:
|
||||||
|
GLuint pid;
|
||||||
|
std::map<std::string,GLint> attributes;
|
||||||
|
std::map<std::string,GLint> uniforms;
|
||||||
|
bool verbose;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
165
L10/src/Shape.cpp
Normal file
165
L10/src/Shape.cpp
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
#include "Shape.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "GLSL.h"
|
||||||
|
#include "Program.h"
|
||||||
|
|
||||||
|
#define GLM_FORCE_RADIANS
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
|
||||||
|
#define TINYOBJLOADER_IMPLEMENTATION
|
||||||
|
#include "tiny_obj_loader.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
Shape::Shape() :
|
||||||
|
posBufID(0),
|
||||||
|
norBufID(0),
|
||||||
|
texBufID(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
Shape::~Shape()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shape::loadMesh(const string &meshName)
|
||||||
|
{
|
||||||
|
// Load geometry
|
||||||
|
tinyobj::attrib_t attrib;
|
||||||
|
std::vector<tinyobj::shape_t> shapes;
|
||||||
|
std::vector<tinyobj::material_t> materials;
|
||||||
|
string errStr;
|
||||||
|
bool rc = tinyobj::LoadObj(&attrib, &shapes, &materials, &errStr, meshName.c_str());
|
||||||
|
if(!rc) {
|
||||||
|
cerr << errStr << endl;
|
||||||
|
} else {
|
||||||
|
// Some OBJ files have different indices for vertex positions, normals,
|
||||||
|
// and texture coordinates. For example, a cube corner vertex may have
|
||||||
|
// three different normals. Here, we are going to duplicate all such
|
||||||
|
// vertices.
|
||||||
|
// Loop over shapes
|
||||||
|
for(size_t s = 0; s < shapes.size(); s++) {
|
||||||
|
// Loop over faces (polygons)
|
||||||
|
size_t index_offset = 0;
|
||||||
|
for(size_t f = 0; f < shapes[s].mesh.num_face_vertices.size(); f++) {
|
||||||
|
size_t fv = shapes[s].mesh.num_face_vertices[f];
|
||||||
|
// Loop over vertices in the face.
|
||||||
|
for(size_t v = 0; v < fv; v++) {
|
||||||
|
// access to vertex
|
||||||
|
tinyobj::index_t idx = shapes[s].mesh.indices[index_offset + v];
|
||||||
|
posBuf.push_back(attrib.vertices[3*idx.vertex_index+0]);
|
||||||
|
posBuf.push_back(attrib.vertices[3*idx.vertex_index+1]);
|
||||||
|
posBuf.push_back(attrib.vertices[3*idx.vertex_index+2]);
|
||||||
|
if(!attrib.normals.empty()) {
|
||||||
|
norBuf.push_back(attrib.normals[3*idx.normal_index+0]);
|
||||||
|
norBuf.push_back(attrib.normals[3*idx.normal_index+1]);
|
||||||
|
norBuf.push_back(attrib.normals[3*idx.normal_index+2]);
|
||||||
|
}
|
||||||
|
if(!attrib.texcoords.empty()) {
|
||||||
|
texBuf.push_back(attrib.texcoords[2*idx.texcoord_index+0]);
|
||||||
|
texBuf.push_back(attrib.texcoords[2*idx.texcoord_index+1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
index_offset += fv;
|
||||||
|
// per-face material (IGNORE)
|
||||||
|
shapes[s].mesh.material_ids[f];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shape::fitToUnitBox()
|
||||||
|
{
|
||||||
|
// Scale the vertex positions so that they fit within [-1, +1] in all three dimensions.
|
||||||
|
glm::vec3 vmin(posBuf[0], posBuf[1], posBuf[2]);
|
||||||
|
glm::vec3 vmax(posBuf[0], posBuf[1], posBuf[2]);
|
||||||
|
for(int i = 0; i < (int)posBuf.size(); i += 3) {
|
||||||
|
glm::vec3 v(posBuf[i], posBuf[i+1], posBuf[i+2]);
|
||||||
|
vmin.x = min(vmin.x, v.x);
|
||||||
|
vmin.y = min(vmin.y, v.y);
|
||||||
|
vmin.z = min(vmin.z, v.z);
|
||||||
|
vmax.x = max(vmax.x, v.x);
|
||||||
|
vmax.y = max(vmax.y, v.y);
|
||||||
|
vmax.z = max(vmax.z, v.z);
|
||||||
|
}
|
||||||
|
glm::vec3 center = 0.5f*(vmin + vmax);
|
||||||
|
glm::vec3 diff = vmax - vmin;
|
||||||
|
float diffmax = diff.x;
|
||||||
|
diffmax = max(diffmax, diff.y);
|
||||||
|
diffmax = max(diffmax, diff.z);
|
||||||
|
float scale = 1.0f / diffmax;
|
||||||
|
for(int i = 0; i < (int)posBuf.size(); i += 3) {
|
||||||
|
posBuf[i ] = (posBuf[i ] - center.x) * scale;
|
||||||
|
posBuf[i+1] = (posBuf[i+1] - center.y) * scale;
|
||||||
|
posBuf[i+2] = (posBuf[i+2] - center.z) * scale;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shape::init()
|
||||||
|
{
|
||||||
|
// Send the position array to the GPU
|
||||||
|
glGenBuffers(1, &posBufID);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, posBufID);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, posBuf.size()*sizeof(float), &posBuf[0], GL_STATIC_DRAW);
|
||||||
|
|
||||||
|
// Send the normal array to the GPU
|
||||||
|
if(!norBuf.empty()) {
|
||||||
|
glGenBuffers(1, &norBufID);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, norBufID);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, norBuf.size()*sizeof(float), &norBuf[0], GL_STATIC_DRAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send the texture array to the GPU
|
||||||
|
if(!texBuf.empty()) {
|
||||||
|
glGenBuffers(1, &texBufID);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, texBufID);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, texBuf.size()*sizeof(float), &texBuf[0], GL_STATIC_DRAW);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unbind the arrays
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
GLSL::checkError(GET_FILE_LINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shape::draw(const shared_ptr<Program> prog) const
|
||||||
|
{
|
||||||
|
// Bind position buffer
|
||||||
|
int h_pos = prog->getAttribute("aPos");
|
||||||
|
glEnableVertexAttribArray(h_pos);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, posBufID);
|
||||||
|
glVertexAttribPointer(h_pos, 3, GL_FLOAT, GL_FALSE, 0, (const void *)0);
|
||||||
|
|
||||||
|
// Bind normal buffer
|
||||||
|
int h_nor = prog->getAttribute("aNor");
|
||||||
|
if(h_nor != -1 && norBufID != 0) {
|
||||||
|
glEnableVertexAttribArray(h_nor);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, norBufID);
|
||||||
|
glVertexAttribPointer(h_nor, 3, GL_FLOAT, GL_FALSE, 0, (const void *)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind texcoords buffer
|
||||||
|
int h_tex = prog->getAttribute("aTex");
|
||||||
|
if(h_tex != -1 && texBufID != 0) {
|
||||||
|
glEnableVertexAttribArray(h_tex);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, texBufID);
|
||||||
|
glVertexAttribPointer(h_tex, 2, GL_FLOAT, GL_FALSE, 0, (const void *)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw
|
||||||
|
int count = posBuf.size()/3; // number of indices to be rendered
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, count);
|
||||||
|
|
||||||
|
// Disable and unbind
|
||||||
|
if(h_tex != -1) {
|
||||||
|
glDisableVertexAttribArray(h_tex);
|
||||||
|
}
|
||||||
|
if(h_nor != -1) {
|
||||||
|
glDisableVertexAttribArray(h_nor);
|
||||||
|
}
|
||||||
|
glDisableVertexAttribArray(h_pos);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
|
GLSL::checkError(GET_FILE_LINE);
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue