Lab06 completed.
This commit is contained in:
parent
d064750ed1
commit
d97e700c59
10 changed files with 716 additions and 2 deletions
|
@ -1,7 +1,8 @@
|
||||||
#version 120
|
#version 120
|
||||||
|
uniform int height;
|
||||||
varying vec3 vMyColor;
|
varying vec3 vMyColor;
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
gl_FragColor = vec4(vMyColor.r, vMyColor.g, vMyColor.b, 1.0);
|
gl_FragColor = vec4(vMyColor.r, vMyColor.g, vMyColor.b, 1.0);
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -157,7 +157,7 @@ static void init()
|
||||||
|
|
||||||
// Get uniform IDs
|
// Get uniform IDs
|
||||||
PUnifID = glGetUniformLocation(progID, "P");
|
PUnifID = glGetUniformLocation(progID, "P");
|
||||||
|
|
||||||
//
|
//
|
||||||
// Vertex buffer setup
|
// Vertex buffer setup
|
||||||
//
|
//
|
||||||
|
|
1
L06/.gitignore
vendored
Normal file
1
L06/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
||||||
|
build/
|
127
L06/CMakeLists.txt
Normal file
127
L06/CMakeLists.txt
Normal file
|
@ -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()
|
17
L06/resources/simple_frag.glsl
Normal file
17
L06/resources/simple_frag.glsl
Normal file
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
12
L06/resources/simple_vert.glsl
Normal file
12
L06/resources/simple_vert.glsl
Normal file
|
@ -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;
|
||||||
|
}
|
152
L06/src/GLSL.cpp
Normal file
152
L06/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
L06/src/GLSL.h
Normal file
40
L06/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
|
364
L06/src/main.cpp
Normal file
364
L06/src/main.cpp
Normal file
|
@ -0,0 +1,364 @@
|
||||||
|
#include <cassert>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#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 "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<float> 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<float> 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;
|
||||||
|
}
|
Reference in a new issue