From d97e700c59d0f87d731442a8999860e125939a58 Mon Sep 17 00:00:00 2001 From: Alex Date: Tue, 28 Feb 2017 10:55:40 -0600 Subject: [PATCH] Lab06 completed. --- L05/resources/simple_frag.glsl | 3 +- L05/src/.main.cpp.swp | Bin 28672 -> 0 bytes L05/src/main.cpp | 2 +- L06/.gitignore | 1 + L06/CMakeLists.txt | 127 ++++++++++++ L06/resources/simple_frag.glsl | 17 ++ L06/resources/simple_vert.glsl | 12 ++ L06/src/GLSL.cpp | 152 ++++++++++++++ L06/src/GLSL.h | 40 ++++ L06/src/main.cpp | 364 +++++++++++++++++++++++++++++++++ 10 files changed, 716 insertions(+), 2 deletions(-) delete mode 100644 L05/src/.main.cpp.swp create mode 100644 L06/.gitignore create mode 100644 L06/CMakeLists.txt create mode 100644 L06/resources/simple_frag.glsl create mode 100644 L06/resources/simple_vert.glsl create mode 100644 L06/src/GLSL.cpp create mode 100644 L06/src/GLSL.h create mode 100644 L06/src/main.cpp diff --git a/L05/resources/simple_frag.glsl b/L05/resources/simple_frag.glsl index 84cf1e6..d4af67d 100644 --- a/L05/resources/simple_frag.glsl +++ b/L05/resources/simple_frag.glsl @@ -1,7 +1,8 @@ #version 120 +uniform int height; varying vec3 vMyColor; void main() { - gl_FragColor = vec4(vMyColor.r, vMyColor.g, vMyColor.b, 1.0); + gl_FragColor = vec4(vMyColor.r, vMyColor.g, vMyColor.b, 1.0); } diff --git a/L05/src/.main.cpp.swp b/L05/src/.main.cpp.swp deleted file mode 100644 index 0d88884bdca6ca23047709352031a43f0e165e1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28672 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 diff --git a/L05/src/main.cpp b/L05/src/main.cpp index 03d71ce..c0d3a06 100644 --- a/L05/src/main.cpp +++ b/L05/src/main.cpp @@ -157,7 +157,7 @@ static void init() // Get uniform IDs PUnifID = glGetUniformLocation(progID, "P"); - + // // Vertex buffer setup // diff --git a/L06/.gitignore b/L06/.gitignore new file mode 100644 index 0000000..567609b --- /dev/null +++ b/L06/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/L06/CMakeLists.txt b/L06/CMakeLists.txt new file mode 100644 index 0000000..b6c14c9 --- /dev/null +++ b/L06/CMakeLists.txt @@ -0,0 +1,127 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) + +# Name of the project +PROJECT(L06) + +# 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() diff --git a/L06/resources/simple_frag.glsl b/L06/resources/simple_frag.glsl new file mode 100644 index 0000000..ccbebb7 --- /dev/null +++ b/L06/resources/simple_frag.glsl @@ -0,0 +1,17 @@ +#version 120 +uniform vec2 middle; +varying vec3 vMyColor; + + +void main() +{ + if(distance(vec2(middle, vec2(gl_FragCoord.x, gl_FragCoord.y)) < 20) + { + discard; + } + else + { + float light = ((distance(middle, vec2(gl_FragCoord.x, gl_FragCoord.y))- 20.0)/200.0); + gl_FragColor = vec4(light+vMyColor.r, light+vMyColor.g, light+vMyColor.b, 1.0); + } +} diff --git a/L06/resources/simple_vert.glsl b/L06/resources/simple_vert.glsl new file mode 100644 index 0000000..895db85 --- /dev/null +++ b/L06/resources/simple_vert.glsl @@ -0,0 +1,12 @@ +#version 120 + +uniform mat4 P; +attribute vec3 vertPos; +attribute vec3 vertCol; +varying vec3 vMyColor; + +void main() +{ + gl_Position = P * vec4(vertPos, 1.0); + vMyColor = 1.0 * vertCol; +} diff --git a/L06/src/GLSL.cpp b/L06/src/GLSL.cpp new file mode 100644 index 0000000..2969872 --- /dev/null +++ b/L06/src/GLSL.cpp @@ -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 +#include +#include +#include + +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); +} + +} diff --git a/L06/src/GLSL.h b/L06/src/GLSL.h new file mode 100644 index 0000000..f945fdd --- /dev/null +++ b/L06/src/GLSL.h @@ -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 + +/////////////////////////////////////////////////////////////////////////////// +// For printing out the current file and line number // +/////////////////////////////////////////////////////////////////////////////// +#include + +template +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 diff --git a/L06/src/main.cpp b/L06/src/main.cpp new file mode 100644 index 0000000..43a182e --- /dev/null +++ b/L06/src/main.cpp @@ -0,0 +1,364 @@ +#include +#include +#include + +#define GLEW_STATIC +#include +#include + +#define GLM_FORCE_RADIANS +#include +#include + +#include "GLSL.h" + +using namespace std; +using namespace glm; + +GLFWwindow *window; // Main application window +string RESOURCE_DIR = "./"; // Where the resources are loaded from + +GLuint progID; +GLint PUnifID; +GLint vertPosAttrID; +GLint vertColAttrID; +GLuint posBufID; +GLuint colBufID; +GLint middleID; + +float worldSize = 1.2f; + +// 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) +{ + double posX, posY; + float newPt[2]; + if(action == GLFW_PRESS) { + // Get window size + int width, height; + glfwGetWindowSize(window, &width, &height); + // Get cursor position + glfwGetCursorPos(window, &posX, &posY); + posY = height - posY; // flip the Y-axis + cout << "Pos X " << posX << " Pos Y " << posY << endl; + // Compute where the cursor is in world coords + float aspect = width/(float)height; + float xMinWorld, xMaxWorld, yMinWorld, yMaxWorld; + if(width > height) { + xMinWorld = -worldSize*aspect; + xMaxWorld = worldSize*aspect; + yMinWorld = -worldSize; + yMaxWorld = worldSize; + } else { + xMinWorld = -worldSize; + xMaxWorld = worldSize; + yMinWorld = -worldSize/aspect; + yMaxWorld = worldSize/aspect; + } + // At this point: + // - The lower left corner of the world is (xMinWorld, xMaxWorld) + // - The top right corner of the world is (yMinWorld, yMaxWorld) + // - The lower left corner of the window is (0, 0) + // - The top right corner of the window is (width, height) + // + // THIS IS BROKEN - YOU GET TO FIX IT - yay! + newPt[0] = ((xMaxWorld - xMinWorld)/width)*posX + xMinWorld; + newPt[1] = ((yMaxWorld - yMinWorld)/height)*posY + yMinWorld; + cout << "converted: " << newPt[0] << " " << newPt[1] << endl; + // Update the vertex array with newPt + glBindBuffer(GL_ARRAY_BUFFER, posBufID); + glBufferSubData(GL_ARRAY_BUFFER, 6*sizeof(float), 2*sizeof(float), newPt); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } +} + +// 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() +{ + // + // General setup + // + + // Set background color. + glClearColor(0.1f, 0.2f, 0.4f, 1.0f); + // Enable z-buffer test. + glEnable(GL_DEPTH_TEST); + + // + // GLSL program setup + // + + // Create shader handles + GLuint vShaderID = glCreateShader(GL_VERTEX_SHADER); + GLuint fShaderID = glCreateShader(GL_FRAGMENT_SHADER); + + // Read shader sources + string vShaderName = RESOURCE_DIR + "simple_vert.glsl"; + string fShaderName = RESOURCE_DIR + "simple_frag.glsl"; + const char *vShaderText = GLSL::textFileRead(vShaderName.c_str()); + const char *fShaderText = GLSL::textFileRead(fShaderName.c_str()); + glShaderSource(vShaderID, 1, &vShaderText, NULL); + glShaderSource(fShaderID, 1, &fShaderText, NULL); + + // Compile vertex shader + int rc; + glCompileShader(vShaderID); + glGetShaderiv(vShaderID, GL_COMPILE_STATUS, &rc); + if(!rc) { + GLSL::printShaderInfoLog(vShaderID); + cout << "Error compiling vertex shader " << vShaderName << endl; + return; + } + + // Compile fragment shader + glCompileShader(fShaderID); + glGetShaderiv(fShaderID, GL_COMPILE_STATUS, &rc); + if(!rc) { + GLSL::printShaderInfoLog(fShaderID); + cout << "Error compiling fragment shader " << fShaderName << endl; + return; + } + + // Create the program and link + progID = glCreateProgram(); + glAttachShader(progID, vShaderID); + glAttachShader(progID, fShaderID); + glLinkProgram(progID); + glGetProgramiv(progID, GL_LINK_STATUS, &rc); + if(!rc) { + GLSL::printProgramInfoLog(progID); + cout << "Error linking shaders " << vShaderName << " and " << fShaderName << endl; + return; + } + + // Get vertex attribute IDs + vertPosAttrID = glGetAttribLocation(progID, "vertPos"); + // Get vertex attribute IDs + vertColAttrID = glGetAttribLocation(progID, "vertCol"); + + // Get uniform IDs + PUnifID = glGetUniformLocation(progID, "P"); + + middleID = glGetUniformLocation(progID, "middle"); + + // + // Vertex buffer setup + // + + // Vertex position data + vector posBuf; + posBuf.push_back(-1.0f); // x + posBuf.push_back(-1.0f); // y + posBuf.push_back( 0.0f); // z + posBuf.push_back( 1.0f); // x + posBuf.push_back(-1.0f); // y + posBuf.push_back( 0.0f); // z + posBuf.push_back( 0.0f); // x + posBuf.push_back( 1.0f); // y + posBuf.push_back( 0.0f); // z + + // Vertex position data + posBuf.push_back(-1.1f); // x + posBuf.push_back(-1.0f); // y + posBuf.push_back( 0.0f); // z + posBuf.push_back(-0.1f); // x + posBuf.push_back( 1.0f); // y + posBuf.push_back( 0.0f); // z + posBuf.push_back(-1.1f); // x + posBuf.push_back( 1.0f); // y + posBuf.push_back( 0.0f); // z + + // Vertex position data + posBuf.push_back( 1.1f); // x + posBuf.push_back(-1.0f); // y + posBuf.push_back( 0.0f); // z + posBuf.push_back( 0.1f); // x + posBuf.push_back( 1.0f); // y + posBuf.push_back( 0.0f); // z + posBuf.push_back( 1.1f); // x + posBuf.push_back( 1.0f); // y + posBuf.push_back( 0.0f); // z + + // Color data + vector colBuf; + colBuf.push_back( 0.0f); // r + colBuf.push_back( 1.0f); // g + colBuf.push_back( 0.0f); // b + colBuf.push_back( 1.0f); // r + colBuf.push_back( 1.0f); // g + colBuf.push_back( 0.0f); // b + colBuf.push_back( 0.0f); // r + colBuf.push_back( 0.0f); // g + colBuf.push_back( 1.0f); // b + + // Color data + colBuf.push_back( 1.0f); // r + colBuf.push_back( 0.0f); // g + colBuf.push_back( 0.0f); // b + colBuf.push_back( 0.0f); // r + colBuf.push_back( 0.0f); // g + colBuf.push_back( 1.0f); // b + colBuf.push_back( 0.0f); // r + colBuf.push_back( 0.0f); // g + colBuf.push_back( 1.0f); // b + + // Color data + colBuf.push_back( 1.0f); // r + colBuf.push_back( 0.0f); // g + colBuf.push_back( 0.0f); // b + colBuf.push_back( 0.0f); // r + colBuf.push_back( 0.0f); // g + colBuf.push_back( 1.0f); // b + colBuf.push_back( 0.0f); // r + colBuf.push_back( 0.0f); // g + colBuf.push_back( 1.0f); // b + + // Generate a buffer object + glGenBuffers(1, &posBufID); + // Bind the buffer object to make it the currently active buffer + glBindBuffer(GL_ARRAY_BUFFER, posBufID); + // Send the buffer data + glBufferData(GL_ARRAY_BUFFER, posBuf.size()*sizeof(float), &posBuf[0], GL_DYNAMIC_DRAW); + // Unbind the buffer object + glBindBuffer(GL_ARRAY_BUFFER, 0); + // Generate a buffer object + glGenBuffers(1, &colBufID); + // Bind the buffer object to make it the currently active buffer + glBindBuffer(GL_ARRAY_BUFFER, colBufID); + // Send the buffer data + glBufferData(GL_ARRAY_BUFFER, colBuf.size()*sizeof(float), &colBuf[0], GL_DYNAMIC_DRAW); + // Unbind the buffer object + glBindBuffer(GL_ARRAY_BUFFER, 0); +} + +// This function is called every frame to draw the scene. +static void render() +{ + // Clear framebuffer. + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Get current frame buffer size. + int width, height; + glfwGetFramebufferSize(window, &width, &height); + float aspect = width/(float)height; + + // Set up projection matrix (camera intrinsics) + mat4 P; + if(width > height) { + P = ortho(-worldSize*aspect, worldSize*aspect, -worldSize, worldSize, -1.0f, 1.0f); + } else { + P = ortho(-worldSize, worldSize, -worldSize/aspect, worldSize/aspect, -1.0f, 1.0f); + } + + float middle[2]; + middle[0] = 100*cos(glfwGetTime()) + (width/2.0); + middle[1] = 100*sin(glfwGetTime()) + (height/2.0); + + std::cout << middle[0] << middle[1] << std::endl; + + // Tell OpenGL which GLSL program to use + glUseProgram(progID); + // Pass in the current projection matrix + glUniform2fv(middleID, 1, middle); + // Pass in the current projection matrix + glUniformMatrix4fv(PUnifID, 1, GL_FALSE, &P[0][0]); + // Enable the attribute + glEnableVertexAttribArray(vertPosAttrID); + // Bind the position buffer object to make it the currently active buffer + glBindBuffer(GL_ARRAY_BUFFER, posBufID); + // Set the pointer -- the data is already on the GPU + glVertexAttribPointer(vertPosAttrID, 3, GL_FLOAT, GL_FALSE, 0, (void *)0); + // Enable the attribute + glEnableVertexAttribArray(vertColAttrID); + // Bind the position buffer object to make it the currently active buffer + glBindBuffer(GL_ARRAY_BUFFER, colBufID); + // Set the pointer -- the data is already on the GPU + glVertexAttribPointer(vertColAttrID, 3, GL_FLOAT, GL_FALSE, 0, (void *)0); + // Actually draw here + glDrawArrays(GL_TRIANGLES, 0, 9); + // Unbind the buffer object + glBindBuffer(GL_ARRAY_BUFFER, 0); + // Disable the attribute + glDisableVertexAttribArray(vertPosAttrID); + // Disable the attribute + glDisableVertexAttribArray(vertColAttrID); + // Unbind our GLSL program + glUseProgram(0); +} + +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", 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; +}