get the build process working
This commit is contained in:
parent
66ccaecd8f
commit
4e550893bb
5 changed files with 356 additions and 296 deletions
1
assignment-2a/.gitignore
vendored
1
assignment-2a/.gitignore
vendored
|
@ -1,2 +1,3 @@
|
|||
/build
|
||||
/result*
|
||||
.cache
|
||||
|
|
|
@ -1,6 +1,14 @@
|
|||
# Set the minimum required version of cmake for this project
|
||||
cmake_minimum_required (VERSION 3.1)
|
||||
|
||||
# Generate the `compile_commands.json` file.
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE INTERNAL "")
|
||||
|
||||
if(CMAKE_EXPORT_COMPILE_COMMANDS)
|
||||
set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES
|
||||
${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
|
||||
endif()
|
||||
|
||||
# Create a project called 'HW2a'
|
||||
project(HW2a)
|
||||
|
||||
|
|
1
assignment-2a/compile_commands.json
Symbolic link
1
assignment-2a/compile_commands.json
Symbolic link
|
@ -0,0 +1 @@
|
|||
build/compile_commands.json
|
|
@ -1,29 +1,30 @@
|
|||
// Skeleton code for hw2a
|
||||
// Based on example code from: Interactive Computer Graphics: A Top-Down Approach with Shader-Based OpenGL (6th Edition), by Ed Angel
|
||||
// Based on example code from: Interactive Computer Graphics: A Top-Down
|
||||
// Approach with Shader-Based OpenGL (6th Edition), by Ed Angel
|
||||
|
||||
|
||||
#include "glad/glad.h"
|
||||
#include "GLFW/glfw3.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <iostream>
|
||||
#include <math.h>
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define DEBUG_ON 0 // repetitive of the debug flag in the shader loading code, included here for clarity only
|
||||
#define DEBUG_ON \
|
||||
0 // repetitive of the debug flag in the shader loading code, included here
|
||||
// for clarity only
|
||||
|
||||
// This file contains the code that reads the shaders from their files and compiles them
|
||||
// This file contains the code that reads the shaders from their files and
|
||||
// compiles them
|
||||
#include "ShaderStuff.hpp"
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
// initialize some basic structure types
|
||||
typedef struct {
|
||||
GLfloat x, y;
|
||||
GLfloat x, y;
|
||||
} FloatType2D;
|
||||
|
||||
typedef struct {
|
||||
GLfloat r, g, b;
|
||||
GLfloat r, g, b;
|
||||
} ColorType3D;
|
||||
|
||||
GLfloat M[16]; // general transformation matrix
|
||||
|
@ -33,201 +34,244 @@ GLint m_location;
|
|||
GLdouble mouse_x, mouse_y;
|
||||
GLint window_width = 500;
|
||||
GLint window_height = 500;
|
||||
GLdouble pi = 4.0*atan(1.0);
|
||||
GLdouble pi = 4.0 * atan(1.0);
|
||||
|
||||
GLFWcursor *hand_cursor, *arrow_cursor; // some different cursors
|
||||
|
||||
GLint NVERTICES = 9; // part of the hard-coded model
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// function that is called whenever an error occurs
|
||||
static void
|
||||
error_callback(int error, const char* description){
|
||||
fputs(description, stderr); // write the error description to stderr
|
||||
static void error_callback(int error, const char *description) {
|
||||
fputs(description, stderr); // write the error description to stderr
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// function that is called whenever a keyboard event occurs; defines how keyboard input will be handled
|
||||
static void
|
||||
key_callback(GLFWwindow* window, int key, int scancode, int action, int mods) {
|
||||
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS) // checks to see if the escape key was pressed
|
||||
glfwSetWindowShouldClose(window, GL_TRUE); // closes the window
|
||||
// function that is called whenever a keyboard event occurs; defines how
|
||||
// keyboard input will be handled
|
||||
static void key_callback(GLFWwindow *window, int key, int scancode, int action,
|
||||
int mods) {
|
||||
if (key == GLFW_KEY_ESCAPE &&
|
||||
action == GLFW_PRESS) // checks to see if the escape key was pressed
|
||||
glfwSetWindowShouldClose(window, GL_TRUE); // closes the window
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// function that is called whenever a mouse or trackpad button press event occurs
|
||||
static void
|
||||
mouse_button_callback(GLFWwindow* window, int button, int action, int mods) {
|
||||
glfwGetCursorPos(window, &mouse_x, &mouse_y);
|
||||
|
||||
// Check which mouse button triggered the event, e.g. GLFW_MOUSE_BUTTON_LEFT, etc.
|
||||
// and what the button action was, e.g. GLFW_PRESS, GLFW_RELEASE, etc.
|
||||
// (Note that ordinary trackpad click = mouse left button)
|
||||
// Also check if any modifier keys were active at the time of the button press, e.g. GLFW_MOD_ALT, etc.
|
||||
// Take the appropriate action, which could (optionally) also include changing the cursor's appearance
|
||||
// function that is called whenever a mouse or trackpad button press event
|
||||
// occurs
|
||||
static void mouse_button_callback(GLFWwindow *window, int button, int action,
|
||||
int mods) {
|
||||
glfwGetCursorPos(window, &mouse_x, &mouse_y);
|
||||
|
||||
// Check which mouse button triggered the event, e.g. GLFW_MOUSE_BUTTON_LEFT,
|
||||
// etc. and what the button action was, e.g. GLFW_PRESS, GLFW_RELEASE, etc.
|
||||
// (Note that ordinary trackpad click = mouse left button)
|
||||
// Also check if any modifier keys were active at the time of the button
|
||||
// press, e.g. GLFW_MOD_ALT, etc. Take the appropriate action, which could
|
||||
// (optionally) also include changing the cursor's appearance
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// function that is called whenever a cursor motion event occurs
|
||||
static void
|
||||
cursor_pos_callback(GLFWwindow* window, double xpos, double ypos) {
|
||||
|
||||
// determine the direction of the mouse or cursor motion
|
||||
// update the current mouse or cursor location
|
||||
// (necessary to quantify the amount and direction of cursor motion)
|
||||
// take the appropriate action
|
||||
|
||||
static void cursor_pos_callback(GLFWwindow *window, double xpos, double ypos) {
|
||||
|
||||
// determine the direction of the mouse or cursor motion
|
||||
// update the current mouse or cursor location
|
||||
// (necessary to quantify the amount and direction of cursor motion)
|
||||
// take the appropriate action
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
void init( void )
|
||||
{
|
||||
ColorType3D colors[NVERTICES];
|
||||
FloatType2D vertices[NVERTICES];
|
||||
GLuint vao[1], buffer, program, location1, location2;
|
||||
|
||||
// set up some hard-coded colors and geometry
|
||||
// this part can be customized to read in an object description from a file
|
||||
colors[0].r = 1; colors[0].g = 1; colors[0].b = 1; // white
|
||||
colors[1].r = 1; colors[1].g = 0; colors[1].b = 0; // red
|
||||
colors[2].r = 1; colors[2].g = 0; colors[2].b = 0; // red
|
||||
colors[3].r = 1; colors[3].g = 1; colors[3].b = 1; // white
|
||||
colors[4].r = 0; colors[4].g = 0; colors[4].b = 1; // blue
|
||||
colors[5].r = 0; colors[5].g = 0; colors[5].b = 1; // blue
|
||||
colors[6].r = 1; colors[6].g = 1; colors[6].b = 1; // white
|
||||
colors[7].r = 0; colors[7].g = 1; colors[7].b = 1; // cyan
|
||||
colors[8].r = 0; colors[8].g = 1; colors[8].b = 1; // cyan
|
||||
|
||||
vertices[0].x = 0; vertices[0].y = 0.25; // center
|
||||
vertices[1].x = 0.25; vertices[1].y = 0.5; // upper right
|
||||
vertices[2].x = -0.25; vertices[2].y = 0.5; // upper left
|
||||
vertices[3].x = 0; vertices[3].y = 0.25; // center (again)
|
||||
vertices[4].x = 0.25; vertices[4].y = -0.5; // low-lower right
|
||||
vertices[5].x = 0.5; vertices[5].y = -0.25; // mid-lower right
|
||||
vertices[6].x = 0; vertices[6].y = 0.25; // center (again)
|
||||
vertices[7].x = -0.5; vertices[7].y = -0.25; // low-lower left
|
||||
vertices[8].x = -0.25; vertices[8].y = -0.5; // mid-lower left
|
||||
|
||||
// Create and bind a vertex array object
|
||||
glGenVertexArrays( 1, vao );
|
||||
glBindVertexArray( vao[0] );
|
||||
void init(void) {
|
||||
ColorType3D colors[NVERTICES];
|
||||
FloatType2D vertices[NVERTICES];
|
||||
GLuint vao[1], buffer, program, location1, location2;
|
||||
|
||||
// Create and initialize a buffer object large enough to hold both vertex position and color data
|
||||
glGenBuffers( 1, &buffer );
|
||||
glBindBuffer( GL_ARRAY_BUFFER, buffer );
|
||||
glBufferData( GL_ARRAY_BUFFER, sizeof(vertices)+sizeof(colors), vertices, GL_STATIC_DRAW );
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertices), sizeof(colors), colors);
|
||||
|
||||
// Define the names of the shader files
|
||||
std::stringstream vshader, fshader;
|
||||
vshader << SRC_DIR << "/vshader2a.glsl";
|
||||
fshader << SRC_DIR << "/fshader2a.glsl";
|
||||
|
||||
// Load the shaders and use the resulting shader program
|
||||
program = InitShader( vshader.str().c_str(), fshader.str().c_str() );
|
||||
|
||||
// Determine locations of the necessary attributes and matrices used in the vertex shader
|
||||
location1 = glGetAttribLocation( program, "vertex_position" );
|
||||
glEnableVertexAttribArray( location1 );
|
||||
glVertexAttribPointer( location1, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0) );
|
||||
location2 = glGetAttribLocation( program, "vertex_color" );
|
||||
glEnableVertexAttribArray( location2 );
|
||||
glVertexAttribPointer( location2, 3, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(sizeof(vertices)) );
|
||||
m_location = glGetUniformLocation( program, "M");
|
||||
|
||||
// Define static OpenGL state variables
|
||||
glClearColor( 1.0, 1.0, 1.0, 1.0 ); // white, opaque background
|
||||
|
||||
// Define some GLFW cursors (in case you want to dynamically change the cursor's appearance)
|
||||
// If you want, you can add more cursors, or even define your own cursor appearance
|
||||
arrow_cursor = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
|
||||
hand_cursor = glfwCreateStandardCursor(GLFW_HAND_CURSOR);
|
||||
|
||||
// set up some hard-coded colors and geometry
|
||||
// this part can be customized to read in an object description from a file
|
||||
colors[0].r = 1;
|
||||
colors[0].g = 1;
|
||||
colors[0].b = 1; // white
|
||||
colors[1].r = 1;
|
||||
colors[1].g = 0;
|
||||
colors[1].b = 0; // red
|
||||
colors[2].r = 1;
|
||||
colors[2].g = 0;
|
||||
colors[2].b = 0; // red
|
||||
colors[3].r = 1;
|
||||
colors[3].g = 1;
|
||||
colors[3].b = 1; // white
|
||||
colors[4].r = 0;
|
||||
colors[4].g = 0;
|
||||
colors[4].b = 1; // blue
|
||||
colors[5].r = 0;
|
||||
colors[5].g = 0;
|
||||
colors[5].b = 1; // blue
|
||||
colors[6].r = 1;
|
||||
colors[6].g = 1;
|
||||
colors[6].b = 1; // white
|
||||
colors[7].r = 0;
|
||||
colors[7].g = 1;
|
||||
colors[7].b = 1; // cyan
|
||||
colors[8].r = 0;
|
||||
colors[8].g = 1;
|
||||
colors[8].b = 1; // cyan
|
||||
|
||||
vertices[0].x = 0;
|
||||
vertices[0].y = 0.25; // center
|
||||
vertices[1].x = 0.25;
|
||||
vertices[1].y = 0.5; // upper right
|
||||
vertices[2].x = -0.25;
|
||||
vertices[2].y = 0.5; // upper left
|
||||
vertices[3].x = 0;
|
||||
vertices[3].y = 0.25; // center (again)
|
||||
vertices[4].x = 0.25;
|
||||
vertices[4].y = -0.5; // low-lower right
|
||||
vertices[5].x = 0.5;
|
||||
vertices[5].y = -0.25; // mid-lower right
|
||||
vertices[6].x = 0;
|
||||
vertices[6].y = 0.25; // center (again)
|
||||
vertices[7].x = -0.5;
|
||||
vertices[7].y = -0.25; // low-lower left
|
||||
vertices[8].x = -0.25;
|
||||
vertices[8].y = -0.5; // mid-lower left
|
||||
|
||||
// Create and bind a vertex array object
|
||||
glGenVertexArrays(1, vao);
|
||||
glBindVertexArray(vao[0]);
|
||||
|
||||
// Create and initialize a buffer object large enough to hold both vertex
|
||||
// position and color data
|
||||
glGenBuffers(1, &buffer);
|
||||
glBindBuffer(GL_ARRAY_BUFFER, buffer);
|
||||
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices) + sizeof(colors), vertices,
|
||||
GL_STATIC_DRAW);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
|
||||
glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertices), sizeof(colors), colors);
|
||||
|
||||
// Define the names of the shader files
|
||||
std::stringstream vshader, fshader;
|
||||
vshader << SRC_DIR << "/vshader2a.glsl";
|
||||
fshader << SRC_DIR << "/fshader2a.glsl";
|
||||
|
||||
// Load the shaders and use the resulting shader program
|
||||
program = InitShader(vshader.str().c_str(), fshader.str().c_str());
|
||||
|
||||
// Determine locations of the necessary attributes and matrices used in the
|
||||
// vertex shader
|
||||
location1 = glGetAttribLocation(program, "vertex_position");
|
||||
glEnableVertexAttribArray(location1);
|
||||
glVertexAttribPointer(location1, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
|
||||
location2 = glGetAttribLocation(program, "vertex_color");
|
||||
glEnableVertexAttribArray(location2);
|
||||
glVertexAttribPointer(location2, 3, GL_FLOAT, GL_FALSE, 0,
|
||||
BUFFER_OFFSET(sizeof(vertices)));
|
||||
m_location = glGetUniformLocation(program, "M");
|
||||
|
||||
// Define static OpenGL state variables
|
||||
glClearColor(1.0, 1.0, 1.0, 1.0); // white, opaque background
|
||||
|
||||
// Define some GLFW cursors (in case you want to dynamically change the
|
||||
// cursor's appearance) If you want, you can add more cursors, or even define
|
||||
// your own cursor appearance
|
||||
arrow_cursor = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
|
||||
hand_cursor = glfwCreateStandardCursor(GLFW_HAND_CURSOR);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
int main(int argc, char **argv) {
|
||||
|
||||
int i;
|
||||
GLFWwindow* window;
|
||||
int i;
|
||||
GLFWwindow *window;
|
||||
|
||||
// Define the error callback function
|
||||
glfwSetErrorCallback(error_callback);
|
||||
|
||||
// Initialize GLFW (performs platform-specific initialization)
|
||||
if (!glfwInit()) exit(EXIT_FAILURE);
|
||||
|
||||
// Ask for OpenGL 3.2
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||
// Define the error callback function
|
||||
glfwSetErrorCallback(error_callback);
|
||||
|
||||
// Use GLFW to open a window within which to display your graphics
|
||||
window = glfwCreateWindow(window_width, window_height, "HW2a", NULL, NULL);
|
||||
|
||||
// Verify that the window was successfully created; if not, print error message and terminate
|
||||
if (!window)
|
||||
{
|
||||
printf("GLFW failed to create window; terminating\n");
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(window); // makes the newly-created context current
|
||||
|
||||
// Load all OpenGL functions (needed if using Windows)
|
||||
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
|
||||
printf("gladLoadGLLoader failed; terminating\n");
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
glfwSwapInterval(1); // tells the system to wait for the rendered frame to finish updating before swapping buffers; can help to avoid tearing
|
||||
// Initialize GLFW (performs platform-specific initialization)
|
||||
if (!glfwInit())
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
// Define the keyboard callback function
|
||||
glfwSetKeyCallback(window, key_callback);
|
||||
// Define the mouse button callback function
|
||||
glfwSetMouseButtonCallback(window, mouse_button_callback);
|
||||
// Define the mouse motion callback function
|
||||
glfwSetCursorPosCallback(window, cursor_pos_callback);
|
||||
// Ask for OpenGL 3.2
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
|
||||
|
||||
// Create the shaders and perform other one-time initializations
|
||||
init();
|
||||
// Use GLFW to open a window within which to display your graphics
|
||||
window = glfwCreateWindow(window_width, window_height, "HW2a", NULL, NULL);
|
||||
|
||||
// event loop
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
// Verify that the window was successfully created; if not, print error
|
||||
// message and terminate
|
||||
if (!window) {
|
||||
printf("GLFW failed to create window; terminating\n");
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
// fill/re-fill the window with the background color
|
||||
glClear( GL_COLOR_BUFFER_BIT );
|
||||
|
||||
// define/re-define the modelview matrix. In this template, we define M to be the identity matrix; you will need define M according to the user's actions.
|
||||
for (i=0; i<16; i++) {
|
||||
M[i] = (i%5==0);
|
||||
}
|
||||
|
||||
// sanity check that your matrix contents are what you expect them to be
|
||||
if (DEBUG_ON) printf("M = [%f %f %f %f\n %f %f %f %f\n %f %f %f %f\n %f %f %f %f]\n",M[0],M[4],M[8],M[12], M[1],M[5],M[9],M[13], M[2],M[6],M[10],M[14], M[3],M[7],M[11],M[15]);
|
||||
|
||||
glUniformMatrix4fv( m_location, 1, GL_FALSE, M ); // send the updated model transformation matrix to the GPU
|
||||
glDrawArrays( GL_TRIANGLES, 0, NVERTICES ); // draw a triangle between the first vertex and each successive vertex pair in the hard-coded model
|
||||
glFlush(); // ensure that all OpenGL calls have executed before swapping buffers
|
||||
glfwMakeContextCurrent(window); // makes the newly-created context current
|
||||
|
||||
glfwSwapBuffers(window); // swap buffers
|
||||
glfwWaitEvents(); // wait for a new event before re-drawing
|
||||
// Load all OpenGL functions (needed if using Windows)
|
||||
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
|
||||
printf("gladLoadGLLoader failed; terminating\n");
|
||||
glfwTerminate();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
} // end graphics loop
|
||||
glfwSwapInterval(
|
||||
1); // tells the system to wait for the rendered frame to finish updating
|
||||
// before swapping buffers; can help to avoid tearing
|
||||
|
||||
// Clean up
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate(); // destroys any remaining objects, frees resources allocated by GLFW
|
||||
exit(EXIT_SUCCESS);
|
||||
// Define the keyboard callback function
|
||||
glfwSetKeyCallback(window, key_callback);
|
||||
// Define the mouse button callback function
|
||||
glfwSetMouseButtonCallback(window, mouse_button_callback);
|
||||
// Define the mouse motion callback function
|
||||
glfwSetCursorPosCallback(window, cursor_pos_callback);
|
||||
|
||||
// Create the shaders and perform other one-time initializations
|
||||
init();
|
||||
|
||||
// event loop
|
||||
while (!glfwWindowShouldClose(window)) {
|
||||
|
||||
// fill/re-fill the window with the background color
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// define/re-define the modelview matrix. In this template, we define M to
|
||||
// be the identity matrix; you will need define M according to the user's
|
||||
// actions.
|
||||
for (i = 0; i < 16; i++) {
|
||||
M[i] = (i % 5 == 0);
|
||||
}
|
||||
|
||||
// sanity check that your matrix contents are what you expect them to be
|
||||
if (DEBUG_ON)
|
||||
printf("M = [%f %f %f %f\n %f %f %f %f\n %f %f %f %f\n %f %f "
|
||||
"%f %f]\n",
|
||||
M[0], M[4], M[8], M[12], M[1], M[5], M[9], M[13], M[2], M[6],
|
||||
M[10], M[14], M[3], M[7], M[11], M[15]);
|
||||
|
||||
glUniformMatrix4fv(
|
||||
m_location, 1, GL_FALSE,
|
||||
M); // send the updated model transformation matrix to the GPU
|
||||
glDrawArrays(
|
||||
GL_TRIANGLES, 0,
|
||||
NVERTICES); // draw a triangle between the first vertex and each
|
||||
// successive vertex pair in the hard-coded model
|
||||
glFlush(); // ensure that all OpenGL calls have executed before swapping
|
||||
// buffers
|
||||
|
||||
glfwSwapBuffers(window); // swap buffers
|
||||
glfwWaitEvents(); // wait for a new event before re-drawing
|
||||
|
||||
} // end graphics loop
|
||||
|
||||
// Clean up
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate(); // destroys any remaining objects, frees resources allocated
|
||||
// by GLFW
|
||||
exit(EXIT_SUCCESS);
|
||||
|
||||
} // end main
|
||||
|
||||
|
||||
|
|
|
@ -1,141 +1,147 @@
|
|||
#include <string>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "glad/glad.h"
|
||||
#include "GLFW/glfw3.h"
|
||||
|
||||
// Basic OpenGL program
|
||||
// Based on example code from: Interactive Computer Graphics: A Top-Down Approach with Shader-Based OpenGL (6th Edition), by Ed Angel
|
||||
// Based on example code from: Interactive Computer Graphics: A Top-Down
|
||||
// Approach with Shader-Based OpenGL (6th Edition), by Ed Angel
|
||||
|
||||
#ifndef SHADERSTUFF
|
||||
#define SHADERSTUFF 1
|
||||
|
||||
#define DEBUG_ON 0
|
||||
#define BUFFER_OFFSET(bytes) ((GLvoid*) (bytes))
|
||||
#define BUFFER_OFFSET(bytes) ((GLvoid *)(bytes))
|
||||
|
||||
// Create a NULL-terminated string by reading the provided file
|
||||
static char*
|
||||
readShaderSource(const char* shaderFile)
|
||||
{
|
||||
FILE *fp;
|
||||
long length, count;
|
||||
char *buffer;
|
||||
// struct stat fileinfo;
|
||||
|
||||
// open the file containing the text of the shader code
|
||||
fp = fopen(shaderFile, "rb");
|
||||
|
||||
// check for errors in opening the file
|
||||
if ( fp == NULL ) {
|
||||
printf("can't open shader source file %s\n", shaderFile);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// determine the file size
|
||||
fseek(fp, 0, SEEK_END); // move position indicator to the end of the file;
|
||||
length = ftell(fp); // return the value of the current position
|
||||
if (DEBUG_ON) fprintf(stdout, "length in bytes of shader file: %ld\n", length);
|
||||
|
||||
// allocate a buffer with the indicated number of bytes, plus one
|
||||
buffer = new char[length + 1];
|
||||
|
||||
// read the appropriate number of bytes from the file
|
||||
fseek(fp, 0, SEEK_SET); // move position indicator to the start of the file
|
||||
count = fread(buffer, 1, length, fp); // read all of the bytes
|
||||
if (DEBUG_ON) fprintf(stdout, "count of bytes successfully read: %ld\n", count);
|
||||
static char *readShaderSource(const char *shaderFile) {
|
||||
FILE *fp;
|
||||
long length, count;
|
||||
char *buffer;
|
||||
// struct stat fileinfo;
|
||||
|
||||
// append a NULL character to indicate the end of the string
|
||||
buffer[count] = '\0'; //because on some systems, count != length
|
||||
|
||||
// close the file
|
||||
fclose(fp);
|
||||
|
||||
// return the string
|
||||
return buffer;
|
||||
// open the file containing the text of the shader code
|
||||
fp = fopen(shaderFile, "rb");
|
||||
|
||||
// check for errors in opening the file
|
||||
if (fp == NULL) {
|
||||
printf("can't open shader source file %s\n", shaderFile);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// determine the file size
|
||||
fseek(fp, 0, SEEK_END); // move position indicator to the end of the file;
|
||||
length = ftell(fp); // return the value of the current position
|
||||
if (DEBUG_ON)
|
||||
fprintf(stdout, "length in bytes of shader file: %ld\n", length);
|
||||
|
||||
// allocate a buffer with the indicated number of bytes, plus one
|
||||
buffer = new char[length + 1];
|
||||
|
||||
// read the appropriate number of bytes from the file
|
||||
fseek(fp, 0, SEEK_SET); // move position indicator to the start of the file
|
||||
count = fread(buffer, 1, length, fp); // read all of the bytes
|
||||
if (DEBUG_ON)
|
||||
fprintf(stdout, "count of bytes successfully read: %ld\n", count);
|
||||
|
||||
// append a NULL character to indicate the end of the string
|
||||
buffer[count] = '\0'; // because on some systems, count != length
|
||||
|
||||
// close the file
|
||||
fclose(fp);
|
||||
|
||||
// return the string
|
||||
return buffer;
|
||||
}
|
||||
|
||||
// Create a GLSL program object from vertex and fragment shader files
|
||||
GLuint
|
||||
InitShader(const char* vShaderFileName, const char* fShaderFileName)
|
||||
{
|
||||
GLuint vertex_shader, fragment_shader;
|
||||
GLuint program;
|
||||
|
||||
// check GLSL version
|
||||
if (DEBUG_ON) printf("GLSL version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
|
||||
// Create shader handlers
|
||||
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
|
||||
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
// Read source code from file
|
||||
std::string vs_text = readShaderSource(vShaderFileName);
|
||||
std::string fs_text = readShaderSource(fShaderFileName);
|
||||
|
||||
// error check
|
||||
if ( vs_text == "" ) {
|
||||
printf("Failed to read from vertex shader file %s\n", vShaderFileName);
|
||||
exit( 1 );
|
||||
} else if (DEBUG_ON) {
|
||||
printf("read shader code:\n%s\n", vs_text.c_str());
|
||||
}
|
||||
if ( fs_text == "" ) {
|
||||
printf("Failed to read from fragment shader file %s\n", fShaderFileName);
|
||||
exit( 1 );
|
||||
} else if (DEBUG_ON) {
|
||||
printf("read shader code:\n%s\n", fs_text.c_str());
|
||||
}
|
||||
|
||||
// Set shader source
|
||||
const char *vv = vs_text.c_str();
|
||||
const char *ff = fs_text.c_str();
|
||||
glShaderSource(vertex_shader, 1, &vv, NULL);
|
||||
glShaderSource(fragment_shader, 1, &ff, NULL);
|
||||
|
||||
// Compile shaders
|
||||
glCompileShader(vertex_shader);
|
||||
glCompileShader(fragment_shader);
|
||||
|
||||
// Check for errors in compiling shaders
|
||||
GLint compiled;
|
||||
glGetShaderiv( vertex_shader, GL_COMPILE_STATUS, &compiled );
|
||||
if ( !compiled ) {
|
||||
printf("vertex_shader failed to compile\n");
|
||||
if (DEBUG_ON) {
|
||||
GLint logMaxSize, logLength;
|
||||
glGetShaderiv( vertex_shader, GL_INFO_LOG_LENGTH, &logMaxSize );
|
||||
printf("printing error message of %d bytes\n", logMaxSize);
|
||||
char* logMsg = new char[logMaxSize];
|
||||
glGetShaderInfoLog( vertex_shader, logMaxSize, &logLength, logMsg );
|
||||
printf("%d bytes retrieved\n", logLength);
|
||||
printf("error message: %s\n", logMsg);
|
||||
delete[] logMsg;
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
glGetShaderiv( fragment_shader, GL_COMPILE_STATUS, &compiled );
|
||||
if ( !compiled ) {
|
||||
printf("fragment_shader failed to compile\n");
|
||||
if (DEBUG_ON) {
|
||||
GLint logMaxSize, logLength;
|
||||
glGetShaderiv( fragment_shader, GL_INFO_LOG_LENGTH, &logMaxSize );
|
||||
printf("printing error message of %d bytes\n", logMaxSize);
|
||||
char* logMsg = new char[logMaxSize];
|
||||
glGetShaderInfoLog( fragment_shader, logMaxSize, &logLength, logMsg );
|
||||
printf("%d bytes retrieved\n", logLength);
|
||||
printf("error message: %s\n", logMsg);
|
||||
delete[] logMsg;
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Create the program
|
||||
program = glCreateProgram();
|
||||
|
||||
// Attach shaders to program
|
||||
glAttachShader(program, vertex_shader);
|
||||
glAttachShader(program, fragment_shader);
|
||||
|
||||
// Link and set program to use
|
||||
glLinkProgram(program);
|
||||
glUseProgram(program);
|
||||
|
||||
return program;
|
||||
GLuint InitShader(const char *vShaderFileName, const char *fShaderFileName) {
|
||||
GLuint vertex_shader, fragment_shader;
|
||||
GLuint program;
|
||||
|
||||
// check GLSL version
|
||||
if (DEBUG_ON)
|
||||
printf("GLSL version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
|
||||
|
||||
// Create shader handlers
|
||||
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
|
||||
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
// Read source code from file
|
||||
std::string vs_text = readShaderSource(vShaderFileName);
|
||||
std::string fs_text = readShaderSource(fShaderFileName);
|
||||
|
||||
// error check
|
||||
if (vs_text == "") {
|
||||
printf("Failed to read from vertex shader file %s\n", vShaderFileName);
|
||||
exit(1);
|
||||
} else if (DEBUG_ON) {
|
||||
printf("read shader code:\n%s\n", vs_text.c_str());
|
||||
}
|
||||
if (fs_text == "") {
|
||||
printf("Failed to read from fragment shader file %s\n", fShaderFileName);
|
||||
exit(1);
|
||||
} else if (DEBUG_ON) {
|
||||
printf("read shader code:\n%s\n", fs_text.c_str());
|
||||
}
|
||||
|
||||
// Set shader source
|
||||
const char *vv = vs_text.c_str();
|
||||
const char *ff = fs_text.c_str();
|
||||
glShaderSource(vertex_shader, 1, &vv, NULL);
|
||||
glShaderSource(fragment_shader, 1, &ff, NULL);
|
||||
|
||||
// Compile shaders
|
||||
glCompileShader(vertex_shader);
|
||||
glCompileShader(fragment_shader);
|
||||
|
||||
// Check for errors in compiling shaders
|
||||
GLint compiled;
|
||||
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &compiled);
|
||||
if (!compiled) {
|
||||
printf("vertex_shader failed to compile\n");
|
||||
if (DEBUG_ON) {
|
||||
GLint logMaxSize, logLength;
|
||||
glGetShaderiv(vertex_shader, GL_INFO_LOG_LENGTH, &logMaxSize);
|
||||
printf("printing error message of %d bytes\n", logMaxSize);
|
||||
char *logMsg = new char[logMaxSize];
|
||||
glGetShaderInfoLog(vertex_shader, logMaxSize, &logLength, logMsg);
|
||||
printf("%d bytes retrieved\n", logLength);
|
||||
printf("error message: %s\n", logMsg);
|
||||
delete[] logMsg;
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &compiled);
|
||||
if (!compiled) {
|
||||
printf("fragment_shader failed to compile\n");
|
||||
if (DEBUG_ON) {
|
||||
GLint logMaxSize, logLength;
|
||||
glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &logMaxSize);
|
||||
printf("printing error message of %d bytes\n", logMaxSize);
|
||||
char *logMsg = new char[logMaxSize];
|
||||
glGetShaderInfoLog(fragment_shader, logMaxSize, &logLength, logMsg);
|
||||
printf("%d bytes retrieved\n", logLength);
|
||||
printf("error message: %s\n", logMsg);
|
||||
delete[] logMsg;
|
||||
}
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Create the program
|
||||
program = glCreateProgram();
|
||||
|
||||
// Attach shaders to program
|
||||
glAttachShader(program, vertex_shader);
|
||||
glAttachShader(program, fragment_shader);
|
||||
|
||||
// Link and set program to use
|
||||
glLinkProgram(program);
|
||||
glUseProgram(program);
|
||||
|
||||
return program;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue