Finished A2
This commit is contained in:
parent
579e3bb5df
commit
96b1e1b242
26 changed files with 3924 additions and 153 deletions
5
A2/README.txt
Normal file
5
A2/README.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
Alexander Huddleston
|
||||
|
||||
L00,L03, and L04 provided code.
|
||||
|
||||
Thank you for the extra late day. I had an unexpected midterm this week.
|
BIN
A2/shadow8t4.zip
Normal file
BIN
A2/shadow8t4.zip
Normal file
Binary file not shown.
126
A2/shadow8t4/shadow8t4/CMakeLists.txt
Normal file
126
A2/shadow8t4/shadow8t4/CMakeLists.txt
Normal file
|
@ -0,0 +1,126 @@
|
|||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
|
||||
|
||||
# Name of the project
|
||||
PROJECT(A2)
|
||||
|
||||
# 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")
|
||||
ELSE()
|
||||
FILE(GLOB_RECURSE SOURCES "src/*.cpp")
|
||||
FILE(GLOB_RECURSE HEADERS "src/*.h")
|
||||
ENDIF()
|
||||
FILE(GLOB_RECURSE GLSL "resources/*.glsl")
|
||||
|
||||
# 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()
|
5
A2/shadow8t4/shadow8t4/README.txt
Normal file
5
A2/shadow8t4/shadow8t4/README.txt
Normal file
|
@ -0,0 +1,5 @@
|
|||
Alexander Huddleston
|
||||
|
||||
L00,L03, and L04 provided code.
|
||||
|
||||
Thank you for the extra late day. I had an unexpected midterm this week.
|
29
A2/shadow8t4/shadow8t4/resources/cube.obj
Normal file
29
A2/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
|
8
A2/shadow8t4/shadow8t4/resources/frag.glsl
Normal file
8
A2/shadow8t4/shadow8t4/resources/frag.glsl
Normal file
|
@ -0,0 +1,8 @@
|
|||
#version 120
|
||||
|
||||
varying vec3 vCol;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(vCol.r, vCol.g, vCol.b, 1.0);
|
||||
}
|
13
A2/shadow8t4/shadow8t4/resources/vert.glsl
Normal file
13
A2/shadow8t4/shadow8t4/resources/vert.glsl
Normal file
|
@ -0,0 +1,13 @@
|
|||
#version 120
|
||||
|
||||
attribute vec4 aPos;
|
||||
attribute vec3 aNor;
|
||||
uniform mat4 P;
|
||||
uniform mat4 MV;
|
||||
varying vec3 vCol;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = P * MV * aPos;
|
||||
vCol = 0.5*(aNor + 1.0);
|
||||
}
|
BIN
A2/shadow8t4/shadow8t4/src/.Component.cpp.swp
Normal file
BIN
A2/shadow8t4/shadow8t4/src/.Component.cpp.swp
Normal file
Binary file not shown.
BIN
A2/shadow8t4/shadow8t4/src/.Component.h.swp
Normal file
BIN
A2/shadow8t4/shadow8t4/src/.Component.h.swp
Normal file
Binary file not shown.
BIN
A2/shadow8t4/shadow8t4/src/.main.cpp.swp
Normal file
BIN
A2/shadow8t4/shadow8t4/src/.main.cpp.swp
Normal file
Binary file not shown.
120
A2/shadow8t4/shadow8t4/src/Component.cpp
Normal file
120
A2/shadow8t4/shadow8t4/src/Component.cpp
Normal file
|
@ -0,0 +1,120 @@
|
|||
#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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
28
A2/shadow8t4/shadow8t4/src/Component.h
Normal file
28
A2/shadow8t4/shadow8t4/src/Component.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
// 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;
|
||||
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
A2/shadow8t4/shadow8t4/src/GLSL.cpp
Normal file
152
A2/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
A2/shadow8t4/shadow8t4/src/GLSL.h
Normal file
40
A2/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
|
114
A2/shadow8t4/shadow8t4/src/MatrixStack.cpp
Normal file
114
A2/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
A2/shadow8t4/shadow8t4/src/MatrixStack.h
Normal file
50
A2/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
|
126
A2/shadow8t4/shadow8t4/src/Program.cpp
Normal file
126
A2/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
A2/shadow8t4/shadow8t4/src/Program.h
Normal file
44
A2/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
|
135
A2/shadow8t4/shadow8t4/src/Shape.cpp
Normal file
135
A2/shadow8t4/shadow8t4/src/Shape.cpp
Normal file
|
@ -0,0 +1,135 @@
|
|||
#include "Shape.h"
|
||||
#include <iostream>
|
||||
|
||||
#include "GLSL.h"
|
||||
#include "Program.h"
|
||||
|
||||
#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::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);
|
||||
}
|
36
A2/shadow8t4/shadow8t4/src/Shape.h
Normal file
36
A2/shadow8t4/shadow8t4/src/Shape.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
#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 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
|
450
A2/shadow8t4/shadow8t4/src/main.cpp
Normal file
450
A2/shadow8t4/shadow8t4/src/main.cpp
Normal file
|
@ -0,0 +1,450 @@
|
|||
#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/matrix_transform.hpp>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
#include "tiny_obj_loader.h"
|
||||
|
||||
#include "GLSL.h"
|
||||
#include "MatrixStack.h"
|
||||
#include "Shape.h"
|
||||
#include "Program.h"
|
||||
#include "Component.h"
|
||||
|
||||
#define PI 3.14159
|
||||
|
||||
using namespace std;
|
||||
using namespace glm;
|
||||
|
||||
GLFWwindow *window; // Main application window
|
||||
string RESOURCE_DIR = "./"; // Where the resources are loaded from
|
||||
shared_ptr<Program> prog;
|
||||
shared_ptr<Shape> shape;
|
||||
|
||||
|
||||
GLuint progID;
|
||||
map<string,GLint> attrIDs;
|
||||
map<string,GLint> unifIDs;
|
||||
map<string,GLuint> bufIDs;
|
||||
int indCount;
|
||||
|
||||
// Root component global
|
||||
Component root;
|
||||
|
||||
// Selected component
|
||||
Component* selected = &root;
|
||||
|
||||
// This function is called when a char is input
|
||||
static void char_callback(GLFWwindow *window, unsigned int c)
|
||||
{
|
||||
char cp = (char)c;
|
||||
|
||||
if(cp == ',')
|
||||
{
|
||||
// select...
|
||||
selected->selected = false;
|
||||
selected = &selected->getPrevious(NULL);
|
||||
selected->selected = true;
|
||||
}
|
||||
else if(cp == '.')
|
||||
{
|
||||
// select...
|
||||
selected->selected = false;
|
||||
selected = &selected->getNext(NULL);
|
||||
selected->selected = true;
|
||||
}
|
||||
|
||||
if(cp == 'x')
|
||||
{
|
||||
// rotate...
|
||||
selected->r.x += 0.1;
|
||||
}
|
||||
else if(cp == 'X')
|
||||
{
|
||||
// rotate...
|
||||
selected->r.x -= 0.1;
|
||||
}
|
||||
|
||||
if(cp == 'y')
|
||||
{
|
||||
// rotate...
|
||||
selected->r.y += 0.1;
|
||||
}
|
||||
else if(cp == 'Y')
|
||||
{
|
||||
// rotate...
|
||||
selected->r.y -= 0.1;
|
||||
}
|
||||
|
||||
if(cp == 'z')
|
||||
{
|
||||
// rotate...
|
||||
selected->r.z += 0.1;
|
||||
}
|
||||
else if(cp == 'Z')
|
||||
{
|
||||
// rotate...
|
||||
selected->r.z -= 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
// 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_callback(GLFWwindow *window, int button, int action, int mods)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
// 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 setParents(Component& elem)
|
||||
{
|
||||
for (unsigned int i = 0; i < elem.children.size(); ++i)
|
||||
{
|
||||
setParents(elem.children[i]);
|
||||
elem.children[i].parent = &elem;
|
||||
}
|
||||
}
|
||||
|
||||
void createRobot(Component& body)
|
||||
{
|
||||
|
||||
body.selected = true;
|
||||
|
||||
//Make Body
|
||||
|
||||
body.s.x = 1.5;
|
||||
body.s.y = 2.0;
|
||||
body.s.z = 1.0;
|
||||
|
||||
|
||||
// Make Head
|
||||
|
||||
Component head;
|
||||
head.parent = &body;
|
||||
|
||||
head.tp.x = 0.0;
|
||||
head.tp.y = body.s.y/2;
|
||||
head.tp.z = 0.0;
|
||||
|
||||
head.t.x = 0.0;
|
||||
head.t.y = 0.5;
|
||||
head.t.z = 0.0;
|
||||
|
||||
body.children.push_back(head);
|
||||
|
||||
// Make Left Upper Arm
|
||||
|
||||
Component luarm;
|
||||
luarm.parent = &body;
|
||||
|
||||
luarm.tp.x = body.s.x/2;
|
||||
luarm.tp.y = body.s.y/4;
|
||||
luarm.tp.z = 0.0;
|
||||
|
||||
luarm.s.x = 1.0;
|
||||
luarm.s.y = 0.5;
|
||||
luarm.s.z = 0.5;
|
||||
|
||||
luarm.t.x = luarm.s.x/2;
|
||||
luarm.t.y = 0.0;
|
||||
luarm.t.z = 0.0;
|
||||
|
||||
// Make Left Lower Arm
|
||||
|
||||
Component llarm;
|
||||
llarm.parent = &luarm;
|
||||
|
||||
llarm.tp.x = luarm.s.x/2;
|
||||
llarm.tp.y = 0.0;
|
||||
llarm.tp.z = 0.0;
|
||||
|
||||
llarm.s.x = 1.5;
|
||||
llarm.s.y = 0.4;
|
||||
llarm.s.z = 0.4;
|
||||
|
||||
llarm.t.x = llarm.s.x/2;
|
||||
llarm.t.y = 0.0;
|
||||
llarm.t.z = 0.0;
|
||||
|
||||
luarm.children.push_back(llarm);
|
||||
|
||||
body.children.push_back(luarm);
|
||||
|
||||
// Make Left Upper Leg
|
||||
|
||||
Component luleg;
|
||||
luleg.parent = &body;
|
||||
|
||||
luleg.tp.x = body.s.x/4;
|
||||
luleg.tp.y = -body.s.y/2;
|
||||
luleg.tp.z = 0.0;
|
||||
|
||||
luleg.s.x = 0.5;
|
||||
luleg.s.y = 1.0;
|
||||
luleg.s.z = 0.5;
|
||||
|
||||
luleg.t.x = 0.0;
|
||||
luleg.t.y = -luleg.s.y/2;
|
||||
luleg.t.z = 0.0;
|
||||
|
||||
// Make Left Lower Leg
|
||||
|
||||
Component llleg;
|
||||
llleg.parent = &luleg;
|
||||
|
||||
llleg.tp.x = 0.0;
|
||||
llleg.tp.y = -luleg.s.y/2;
|
||||
llleg.tp.z = 0.0;
|
||||
|
||||
llleg.s.x = 0.4;
|
||||
llleg.s.y = 1.5;
|
||||
llleg.s.z = 0.4;
|
||||
|
||||
|
||||
llleg.t.x = 0.0;
|
||||
llleg.t.y = -llleg.s.y/2;
|
||||
llleg.t.z = 0.0;
|
||||
|
||||
luleg.children.push_back(llleg);
|
||||
|
||||
body.children.push_back(luleg);
|
||||
|
||||
// Make Right Upper Leg
|
||||
|
||||
Component ruleg;
|
||||
ruleg.parent = &body;
|
||||
|
||||
ruleg.tp.x = -body.s.x/4;
|
||||
ruleg.tp.y = -body.s.y/2;
|
||||
ruleg.tp.z = 0.0;
|
||||
|
||||
ruleg.s.x = 0.5;
|
||||
ruleg.s.y = 1.0;
|
||||
ruleg.s.z = 0.5;
|
||||
|
||||
ruleg.t.x = 0.0;
|
||||
ruleg.t.y = -ruleg.s.y/2;
|
||||
ruleg.t.z = 0.0;
|
||||
|
||||
// Make Right Lower Leg
|
||||
|
||||
Component rlleg;
|
||||
rlleg.parent = &ruleg;
|
||||
|
||||
rlleg.tp.x = 0.0;
|
||||
rlleg.tp.y = -ruleg.s.y/2;
|
||||
rlleg.tp.z = 0.0;
|
||||
|
||||
rlleg.s.x = 0.4;
|
||||
rlleg.s.y = 1.5;
|
||||
rlleg.s.z = 0.4;
|
||||
|
||||
|
||||
rlleg.t.x = 0.0;
|
||||
rlleg.t.y = -rlleg.s.y/2;
|
||||
rlleg.t.z = 0.0;
|
||||
|
||||
ruleg.children.push_back(rlleg);
|
||||
|
||||
body.children.push_back(ruleg);
|
||||
|
||||
// Make Right Upper Arm
|
||||
|
||||
Component ruarm;
|
||||
ruarm.parent = &body;
|
||||
|
||||
ruarm.tp.x = -body.s.x/2;
|
||||
ruarm.tp.y = body.s.y/4;
|
||||
ruarm.tp.z = 0.0;
|
||||
|
||||
ruarm.s.x = 1.0;
|
||||
ruarm.s.y = 0.5;
|
||||
ruarm.s.z = 0.5;
|
||||
|
||||
ruarm.t.x = -ruarm.s.x/2;
|
||||
ruarm.t.y = 0.0;
|
||||
ruarm.t.z = 0.0;
|
||||
|
||||
// Make Right Lower Arm
|
||||
|
||||
Component rlarm;
|
||||
rlarm.parent = &ruarm;
|
||||
|
||||
rlarm.tp.x = -ruarm.s.x/2;
|
||||
rlarm.tp.y = 0.0;
|
||||
rlarm.tp.z = 0.0;
|
||||
|
||||
rlarm.s.x = 1.5;
|
||||
rlarm.s.y = 0.4;
|
||||
rlarm.s.z = 0.4;
|
||||
|
||||
rlarm.t.x = -rlarm.s.x/2;
|
||||
rlarm.t.y = 0.0;
|
||||
rlarm.t.z = 0.0;
|
||||
|
||||
ruarm.children.push_back(rlarm);
|
||||
|
||||
body.children.push_back(ruarm);
|
||||
|
||||
setParents(body);
|
||||
}
|
||||
|
||||
static void init()
|
||||
{
|
||||
GLSL::checkVersion();
|
||||
|
||||
// Set background color.
|
||||
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
// Enable z-buffer test.
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
// Initialize mesh.
|
||||
shape = make_shared<Shape>();
|
||||
shape->loadMesh(RESOURCE_DIR + "cube.obj");
|
||||
shape->init();
|
||||
|
||||
// Initialize the GLSL program.
|
||||
prog = make_shared<Program>();
|
||||
prog->setVerbose(false); // Set this to true when debugging.
|
||||
prog->setShaderNames(RESOURCE_DIR + "vert.glsl", RESOURCE_DIR + "frag.glsl");
|
||||
prog->init();
|
||||
prog->addUniform("P");
|
||||
prog->addUniform("MV");
|
||||
prog->addAttribute("aPos");
|
||||
prog->addAttribute("aNor");
|
||||
|
||||
createRobot(root);
|
||||
selected = &root;
|
||||
|
||||
// If there were any OpenGL errors, this will print something.
|
||||
// You can intersperse this line in your code to find the exact location
|
||||
// of your OpenGL error.
|
||||
GLSL::checkError(GET_FILE_LINE);
|
||||
}
|
||||
|
||||
static void render()
|
||||
{
|
||||
// Get current frame buffer size.
|
||||
int width, height;
|
||||
glfwGetFramebufferSize(window, &width, &height);
|
||||
float aspect = width/(float)height;
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
// Clear framebuffer.
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Create matrix stacks.
|
||||
auto P = make_shared<MatrixStack>();
|
||||
auto MV = make_shared<MatrixStack>();
|
||||
// Apply projection.
|
||||
P->pushMatrix();
|
||||
P->multMatrix(glm::perspective((float)(45.0*M_PI/180.0), aspect, 0.01f, 100.0f));
|
||||
// Apply camera transform.
|
||||
MV->pushMatrix();
|
||||
MV->translate(glm::vec3(0, -0.5, -10));
|
||||
|
||||
// Draw mesh using GLSL.
|
||||
prog->bind();
|
||||
// glUniformMatrix4fv(prog->getUniform("P"), 1, GL_FALSE, &P->topMatrix()[0][0]);
|
||||
// glUniformMatrix4fv(prog->getUniform("MV"), 1, GL_FALSE, &MV->topMatrix()[0][0]);
|
||||
// shape->draw(prog);
|
||||
|
||||
root.draw(MV, P, shape, prog);
|
||||
|
||||
prog->unbind();
|
||||
|
||||
// Pop matrix stacks.
|
||||
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, "Alexander Huddleston", 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 char callback.
|
||||
glfwSetCharCallback(window, char_callback);
|
||||
// Set keyboard callback.
|
||||
glfwSetKeyCallback(window, key_callback);
|
||||
// Set the mouse call back.
|
||||
glfwSetMouseButtonCallback(window, mouse_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
A2/shadow8t4/shadow8t4/src/tiny_obj_loader.h
Normal file
1922
A2/shadow8t4/shadow8t4/src/tiny_obj_loader.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,43 +0,0 @@
|
|||
// Create Body Class
|
||||
|
||||
/*
|
||||
Class Body
|
||||
{
|
||||
Head h;
|
||||
Shoulder sl;
|
||||
Shoulder sr;
|
||||
Leg ull;
|
||||
Leg ulr;
|
||||
bool selected = true;
|
||||
|
||||
draw(MatrixStack MV);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
static void renderA(MatrixStack MV)
|
||||
{
|
||||
MV.pushMatrix();
|
||||
MV.translate(-1, 0, 0);
|
||||
MV.rotate(-(2*PI)/16, 0, 0, 1);
|
||||
MV.scale(0.5, 4, 0.5);
|
||||
glUniformMatrix4fv(unifIDs["MV"], 1, GL_FALSE, value_ptr(MV.topMatrix()));
|
||||
glDrawArrays(GL_TRIANGLES, 0, indCount);
|
||||
MV.popMatrix(); // This line undoes the transformation applied to #1
|
||||
MV.pushMatrix();
|
||||
MV.scale(2, 0.5, 0.5);
|
||||
glUniformMatrix4fv(unifIDs["MV"], 1, GL_FALSE, value_ptr(MV.topMatrix()));
|
||||
glDrawArrays(GL_TRIANGLES, 0, indCount);
|
||||
MV.popMatrix(); // This line undoes the transformation applied to #2
|
||||
MV.pushMatrix();
|
||||
MV.translate(1, 0, 0);
|
||||
MV.rotate((2*PI)/16, 0, 0, 1);
|
||||
MV.scale(0.5, 4, 0.5);
|
||||
glUniformMatrix4fv(unifIDs["MV"], 1, GL_FALSE, value_ptr(MV.topMatrix()));
|
||||
glDrawArrays(GL_TRIANGLES, 0, indCount);
|
||||
MV.popMatrix(); // This line undoes the transformation applied to #3
|
||||
}
|
||||
|
||||
|
||||
*/
|
120
A2/src/Component.cpp
Normal file
120
A2/src/Component.cpp
Normal file
|
@ -0,0 +1,120 @@
|
|||
#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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
28
A2/src/Component.h
Normal file
28
A2/src/Component.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
// 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;
|
||||
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();
|
||||
};
|
483
A2/src/main.cpp
483
A2/src/main.cpp
|
@ -21,6 +21,7 @@
|
|||
#include "MatrixStack.h"
|
||||
#include "Shape.h"
|
||||
#include "Program.h"
|
||||
#include "Component.h"
|
||||
|
||||
#define PI 3.14159
|
||||
|
||||
|
@ -38,150 +39,412 @@ map<string,GLint> attrIDs;
|
|||
map<string,GLint> unifIDs;
|
||||
map<string,GLuint> bufIDs;
|
||||
int indCount;
|
||||
|
||||
// Root component global
|
||||
Component root;
|
||||
|
||||
// Selected component
|
||||
Component* selected = &root;
|
||||
|
||||
// This function is called when a char is input
|
||||
static void char_callback(GLFWwindow *window, unsigned int c)
|
||||
{
|
||||
char cp = (char)c;
|
||||
|
||||
if(cp == ',')
|
||||
{
|
||||
// select...
|
||||
selected->selected = false;
|
||||
selected = &selected->getPrevious(NULL);
|
||||
selected->selected = true;
|
||||
}
|
||||
else if(cp == '.')
|
||||
{
|
||||
// select...
|
||||
selected->selected = false;
|
||||
selected = &selected->getNext(NULL);
|
||||
selected->selected = true;
|
||||
}
|
||||
|
||||
if(cp == 'x')
|
||||
{
|
||||
// rotate...
|
||||
selected->r.x += 0.1;
|
||||
}
|
||||
else if(cp == 'X')
|
||||
{
|
||||
// rotate...
|
||||
selected->r.x -= 0.1;
|
||||
}
|
||||
|
||||
if(cp == 'y')
|
||||
{
|
||||
// rotate...
|
||||
selected->r.y += 0.1;
|
||||
}
|
||||
else if(cp == 'Y')
|
||||
{
|
||||
// rotate...
|
||||
selected->r.y -= 0.1;
|
||||
}
|
||||
|
||||
if(cp == 'z')
|
||||
{
|
||||
// rotate...
|
||||
selected->r.z += 0.1;
|
||||
}
|
||||
else if(cp == 'Z')
|
||||
{
|
||||
// rotate...
|
||||
selected->r.z -= 0.1;
|
||||
}
|
||||
}
|
||||
|
||||
// This function is called when a GLFW error occurs
|
||||
static void error_callback(int error, const char *description)
|
||||
{
|
||||
cerr << description << endl;
|
||||
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);
|
||||
}
|
||||
if(key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) {
|
||||
glfwSetWindowShouldClose(window, GL_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
// This function is called when the mouse is clicked
|
||||
static void mouse_callback(GLFWwindow *window, int button, int action, int mods)
|
||||
{
|
||||
// Do nothing
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
// 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);
|
||||
glViewport(0, 0, width, height);
|
||||
}
|
||||
|
||||
static void setParents(Component& elem)
|
||||
{
|
||||
for (unsigned int i = 0; i < elem.children.size(); ++i)
|
||||
{
|
||||
setParents(elem.children[i]);
|
||||
elem.children[i].parent = &elem;
|
||||
}
|
||||
}
|
||||
|
||||
void createRobot(Component& body)
|
||||
{
|
||||
|
||||
body.selected = true;
|
||||
|
||||
//Make Body
|
||||
|
||||
body.s.x = 1.5;
|
||||
body.s.y = 2.0;
|
||||
body.s.z = 1.0;
|
||||
|
||||
|
||||
// Make Head
|
||||
|
||||
Component head;
|
||||
head.parent = &body;
|
||||
|
||||
head.tp.x = 0.0;
|
||||
head.tp.y = body.s.y/2;
|
||||
head.tp.z = 0.0;
|
||||
|
||||
head.t.x = 0.0;
|
||||
head.t.y = 0.5;
|
||||
head.t.z = 0.0;
|
||||
|
||||
body.children.push_back(head);
|
||||
|
||||
// Make Left Upper Arm
|
||||
|
||||
Component luarm;
|
||||
luarm.parent = &body;
|
||||
|
||||
luarm.tp.x = body.s.x/2;
|
||||
luarm.tp.y = body.s.y/4;
|
||||
luarm.tp.z = 0.0;
|
||||
|
||||
luarm.s.x = 1.0;
|
||||
luarm.s.y = 0.5;
|
||||
luarm.s.z = 0.5;
|
||||
|
||||
luarm.t.x = luarm.s.x/2;
|
||||
luarm.t.y = 0.0;
|
||||
luarm.t.z = 0.0;
|
||||
|
||||
// Make Left Lower Arm
|
||||
|
||||
Component llarm;
|
||||
llarm.parent = &luarm;
|
||||
|
||||
llarm.tp.x = luarm.s.x/2;
|
||||
llarm.tp.y = 0.0;
|
||||
llarm.tp.z = 0.0;
|
||||
|
||||
llarm.s.x = 1.5;
|
||||
llarm.s.y = 0.4;
|
||||
llarm.s.z = 0.4;
|
||||
|
||||
llarm.t.x = llarm.s.x/2;
|
||||
llarm.t.y = 0.0;
|
||||
llarm.t.z = 0.0;
|
||||
|
||||
luarm.children.push_back(llarm);
|
||||
|
||||
body.children.push_back(luarm);
|
||||
|
||||
// Make Left Upper Leg
|
||||
|
||||
Component luleg;
|
||||
luleg.parent = &body;
|
||||
|
||||
luleg.tp.x = body.s.x/4;
|
||||
luleg.tp.y = -body.s.y/2;
|
||||
luleg.tp.z = 0.0;
|
||||
|
||||
luleg.s.x = 0.5;
|
||||
luleg.s.y = 1.0;
|
||||
luleg.s.z = 0.5;
|
||||
|
||||
luleg.t.x = 0.0;
|
||||
luleg.t.y = -luleg.s.y/2;
|
||||
luleg.t.z = 0.0;
|
||||
|
||||
// Make Left Lower Leg
|
||||
|
||||
Component llleg;
|
||||
llleg.parent = &luleg;
|
||||
|
||||
llleg.tp.x = 0.0;
|
||||
llleg.tp.y = -luleg.s.y/2;
|
||||
llleg.tp.z = 0.0;
|
||||
|
||||
llleg.s.x = 0.4;
|
||||
llleg.s.y = 1.5;
|
||||
llleg.s.z = 0.4;
|
||||
|
||||
|
||||
llleg.t.x = 0.0;
|
||||
llleg.t.y = -llleg.s.y/2;
|
||||
llleg.t.z = 0.0;
|
||||
|
||||
luleg.children.push_back(llleg);
|
||||
|
||||
body.children.push_back(luleg);
|
||||
|
||||
// Make Right Upper Leg
|
||||
|
||||
Component ruleg;
|
||||
ruleg.parent = &body;
|
||||
|
||||
ruleg.tp.x = -body.s.x/4;
|
||||
ruleg.tp.y = -body.s.y/2;
|
||||
ruleg.tp.z = 0.0;
|
||||
|
||||
ruleg.s.x = 0.5;
|
||||
ruleg.s.y = 1.0;
|
||||
ruleg.s.z = 0.5;
|
||||
|
||||
ruleg.t.x = 0.0;
|
||||
ruleg.t.y = -ruleg.s.y/2;
|
||||
ruleg.t.z = 0.0;
|
||||
|
||||
// Make Right Lower Leg
|
||||
|
||||
Component rlleg;
|
||||
rlleg.parent = &ruleg;
|
||||
|
||||
rlleg.tp.x = 0.0;
|
||||
rlleg.tp.y = -ruleg.s.y/2;
|
||||
rlleg.tp.z = 0.0;
|
||||
|
||||
rlleg.s.x = 0.4;
|
||||
rlleg.s.y = 1.5;
|
||||
rlleg.s.z = 0.4;
|
||||
|
||||
|
||||
rlleg.t.x = 0.0;
|
||||
rlleg.t.y = -rlleg.s.y/2;
|
||||
rlleg.t.z = 0.0;
|
||||
|
||||
ruleg.children.push_back(rlleg);
|
||||
|
||||
body.children.push_back(ruleg);
|
||||
|
||||
// Make Right Upper Arm
|
||||
|
||||
Component ruarm;
|
||||
ruarm.parent = &body;
|
||||
|
||||
ruarm.tp.x = -body.s.x/2;
|
||||
ruarm.tp.y = body.s.y/4;
|
||||
ruarm.tp.z = 0.0;
|
||||
|
||||
ruarm.s.x = 1.0;
|
||||
ruarm.s.y = 0.5;
|
||||
ruarm.s.z = 0.5;
|
||||
|
||||
ruarm.t.x = -ruarm.s.x/2;
|
||||
ruarm.t.y = 0.0;
|
||||
ruarm.t.z = 0.0;
|
||||
|
||||
// Make Right Lower Arm
|
||||
|
||||
Component rlarm;
|
||||
rlarm.parent = &ruarm;
|
||||
|
||||
rlarm.tp.x = -ruarm.s.x/2;
|
||||
rlarm.tp.y = 0.0;
|
||||
rlarm.tp.z = 0.0;
|
||||
|
||||
rlarm.s.x = 1.5;
|
||||
rlarm.s.y = 0.4;
|
||||
rlarm.s.z = 0.4;
|
||||
|
||||
rlarm.t.x = -rlarm.s.x/2;
|
||||
rlarm.t.y = 0.0;
|
||||
rlarm.t.z = 0.0;
|
||||
|
||||
ruarm.children.push_back(rlarm);
|
||||
|
||||
body.children.push_back(ruarm);
|
||||
|
||||
setParents(body);
|
||||
}
|
||||
|
||||
static void init()
|
||||
{
|
||||
GLSL::checkVersion();
|
||||
GLSL::checkVersion();
|
||||
|
||||
// Set background color.
|
||||
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
// Enable z-buffer test.
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
// Set background color.
|
||||
glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
// Enable z-buffer test.
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
// Initialize mesh.
|
||||
shape = make_shared<Shape>();
|
||||
shape->loadMesh(RESOURCE_DIR + "teapot.obj");
|
||||
shape->init();
|
||||
|
||||
// Initialize the GLSL program.
|
||||
prog = make_shared<Program>();
|
||||
prog->setVerbose(false); // Set this to true when debugging.
|
||||
prog->setShaderNames(RESOURCE_DIR + "simple_vert.glsl", RESOURCE_DIR + "simple_frag.glsl");
|
||||
prog->init();
|
||||
prog->addUniform("P");
|
||||
prog->addUniform("MV");
|
||||
prog->addAttribute("aPos");
|
||||
prog->addAttribute("aNor");
|
||||
|
||||
// If there were any OpenGL errors, this will print something.
|
||||
// You can intersperse this line in your code to find the exact location
|
||||
// of your OpenGL error.
|
||||
GLSL::checkError(GET_FILE_LINE);
|
||||
// Initialize mesh.
|
||||
shape = make_shared<Shape>();
|
||||
shape->loadMesh(RESOURCE_DIR + "cube.obj");
|
||||
shape->init();
|
||||
|
||||
// Initialize the GLSL program.
|
||||
prog = make_shared<Program>();
|
||||
prog->setVerbose(false); // Set this to true when debugging.
|
||||
prog->setShaderNames(RESOURCE_DIR + "vert.glsl", RESOURCE_DIR + "frag.glsl");
|
||||
prog->init();
|
||||
prog->addUniform("P");
|
||||
prog->addUniform("MV");
|
||||
prog->addAttribute("aPos");
|
||||
prog->addAttribute("aNor");
|
||||
|
||||
createRobot(root);
|
||||
selected = &root;
|
||||
|
||||
// If there were any OpenGL errors, this will print something.
|
||||
// You can intersperse this line in your code to find the exact location
|
||||
// of your OpenGL error.
|
||||
GLSL::checkError(GET_FILE_LINE);
|
||||
}
|
||||
|
||||
static void render()
|
||||
{
|
||||
// Get current frame buffer size.
|
||||
int width, height;
|
||||
glfwGetFramebufferSize(window, &width, &height);
|
||||
float aspect = width/(float)height;
|
||||
glViewport(0, 0, width, height);
|
||||
// Get current frame buffer size.
|
||||
int width, height;
|
||||
glfwGetFramebufferSize(window, &width, &height);
|
||||
float aspect = width/(float)height;
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
// Clear framebuffer.
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
// Clear framebuffer.
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Create matrix stacks.
|
||||
auto P = make_shared<MatrixStack>();
|
||||
auto MV = make_shared<MatrixStack>();
|
||||
// Apply projection.
|
||||
P->pushMatrix();
|
||||
P->multMatrix(glm::perspective((float)(45.0*M_PI/180.0), aspect, 0.01f, 100.0f));
|
||||
// Apply camera transform.
|
||||
MV->pushMatrix();
|
||||
MV->translate(glm::vec3(0, -0.5, -3));
|
||||
|
||||
// Draw mesh using GLSL.
|
||||
prog->bind();
|
||||
glUniformMatrix4fv(prog->getUniform("P"), 1, GL_FALSE, &P->topMatrix()[0][0]);
|
||||
glUniformMatrix4fv(prog->getUniform("MV"), 1, GL_FALSE, &MV->topMatrix()[0][0]);
|
||||
shape->draw(prog);
|
||||
prog->unbind();
|
||||
// Create matrix stacks.
|
||||
auto P = make_shared<MatrixStack>();
|
||||
auto MV = make_shared<MatrixStack>();
|
||||
// Apply projection.
|
||||
P->pushMatrix();
|
||||
P->multMatrix(glm::perspective((float)(45.0*M_PI/180.0), aspect, 0.01f, 100.0f));
|
||||
// Apply camera transform.
|
||||
MV->pushMatrix();
|
||||
MV->translate(glm::vec3(0, -0.5, -10));
|
||||
|
||||
// Pop matrix stacks.
|
||||
MV->popMatrix();
|
||||
P->popMatrix();
|
||||
|
||||
GLSL::checkError(GET_FILE_LINE);
|
||||
// Draw mesh using GLSL.
|
||||
prog->bind();
|
||||
// glUniformMatrix4fv(prog->getUniform("P"), 1, GL_FALSE, &P->topMatrix()[0][0]);
|
||||
// glUniformMatrix4fv(prog->getUniform("MV"), 1, GL_FALSE, &MV->topMatrix()[0][0]);
|
||||
// shape->draw(prog);
|
||||
|
||||
root.draw(MV, P, shape, prog);
|
||||
|
||||
prog->unbind();
|
||||
|
||||
// Pop matrix stacks.
|
||||
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("/");
|
||||
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, "Alexander Huddleston", 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 the mouse call back.
|
||||
glfwSetMouseButtonCallback(window, mouse_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;
|
||||
// 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, "Alexander Huddleston", 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 char callback.
|
||||
glfwSetCharCallback(window, char_callback);
|
||||
// Set keyboard callback.
|
||||
glfwSetKeyCallback(window, key_callback);
|
||||
// Set the mouse call back.
|
||||
glfwSetMouseButtonCallback(window, mouse_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;
|
||||
}
|
||||
|
|
Reference in a new issue