Work on assignment 2a

This commit is contained in:
Michael Zhang 2023-04-04 02:22:46 -05:00
parent 4e550893bb
commit e8a5758103
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B
13 changed files with 616 additions and 525 deletions

Binary file not shown.

View file

@ -0,0 +1,2 @@
---
BasedOnStyle: LLVM

View file

@ -1,81 +1,84 @@
# Set the minimum required version of cmake for this project # Set the minimum required version of cmake for this project
cmake_minimum_required (VERSION 3.1) cmake_minimum_required (VERSION 3.1)
set(CMAKE_CXX_STANDARD 17)
# Generate the `compile_commands.json` file.
set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE INTERNAL "") # 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 if(CMAKE_EXPORT_COMPILE_COMMANDS)
${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}) set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES
endif() ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
endif()
# Create a project called 'HW2a'
project(HW2a) # Create a project called 'HW2a'
project(HW2a)
# Define in the C++ code what the variable "SRC_DIR" should be equal to the current_path/src
add_definitions( -DSRC_DIR="${CMAKE_CURRENT_SOURCE_DIR}/src" ) # Define in the C++ code what the variable "SRC_DIR" should be equal to the current_path/src
add_definitions( -DSRC_DIR="${CMAKE_CURRENT_SOURCE_DIR}/src" )
# Find OpenGL, and set link library names and include paths find_package(spdlog REQUIRED)
find_package(OpenGL REQUIRED)
set(OPENGL_LIBRARIES ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY}) # Find OpenGL, and set link library names and include paths
set(OPENGL_INCLUDE_DIRS ${OPENGL_INCLUDE_DIR}) find_package(OpenGL REQUIRED)
include_directories(${OPENGL_INCLUDE_DIRS}) set(OPENGL_LIBRARIES ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY})
set(OPENGL_INCLUDE_DIRS ${OPENGL_INCLUDE_DIR})
# Also disable building some of the extra things GLFW has (examples, tests, docs) include_directories(${OPENGL_INCLUDE_DIRS})
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL " " FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL " " FORCE) # Also disable building some of the extra things GLFW has (examples, tests, docs)
set(GLFW_BUILD_DOCS OFF CACHE BOOL " " FORCE) set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL " " FORCE)
set(GLFW_BUILD_TESTS OFF CACHE BOOL " " FORCE)
# Now actually run cmake on the CMakeLists.txt file found inside of the GLFW directory set(GLFW_BUILD_DOCS OFF CACHE BOOL " " FORCE)
add_subdirectory(ext/glfw)
# Now actually run cmake on the CMakeLists.txt file found inside of the GLFW directory
# Make a list of all the source files add_subdirectory(ext/glfw)
set(
SOURCES # Make a list of all the source files
src/HW2a.cpp set(
SOURCES
ext/glad/src/glad.c src/main.cpp
) src/controls.cpp
src/util.cpp
# Make a list of all the header files (optional-- only necessary to make them appear in IDE) ext/glad/src/glad.c
set( )
INCLUDES
src/ShaderStuff.hpp # Make a list of all the header files (optional-- only necessary to make them appear in IDE)
) set(
INCLUDES
# Make a list of all of the directories to look in when doing #include "whatever.h" )
set(
INCLUDE_DIRS # Make a list of all of the directories to look in when doing #include "whatever.h"
ext/ set(
ext/glfw/include INCLUDE_DIRS
ext/glad/include ext/
) ext/glfw/include
ext/glad/include
set( )
LIBS
glfw set(
${OPENGL_LIBRARIES} LIBS
) glfw
spdlog::spdlog
# Define what we are trying to produce here (an executable), as ${OPENGL_LIBRARIES}
# well as what items are needed to create it (the header and source files) )
add_executable(${PROJECT_NAME} ${SOURCES} ${INCLUDES})
# Define what we are trying to produce here (an executable), as
# Tell cmake which directories to look in when you #include a file # well as what items are needed to create it (the header and source files)
# Equivalent to the "-I" option for g++ add_executable(${PROJECT_NAME} ${SOURCES} ${INCLUDES})
include_directories(${INCLUDE_DIRS})
# Tell cmake which directories to look in when you #include a file
# Tell cmake which libraries to link to # Equivalent to the "-I" option for g++
# Equivalent to the "-l" option for g++ include_directories(${INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} PRIVATE ${LIBS})
# Tell cmake which libraries to link to
install(TARGETS ${PROJECT_NAME} DESTINATION bin) # Equivalent to the "-l" option for g++
target_link_libraries(${PROJECT_NAME} PRIVATE ${LIBS})
# For Visual Studio only
if (MSVC) install(TARGETS ${PROJECT_NAME} DESTINATION bin)
# Do a parallel compilation of this project
target_compile_options(${PROJECT_NAME} PRIVATE "/MP") # For Visual Studio only
# Have this project be the default startup project (the one to build/run when hitting F5) if (MSVC)
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME}) # Do a parallel compilation of this project
endif() target_compile_options(${PROJECT_NAME} PRIVATE "/MP")
# Have this project be the default startup project (the one to build/run when hitting F5)
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT ${PROJECT_NAME})
endif()

View file

@ -1,4 +1,4 @@
{ stdenv, cmake, ninja, libglvnd, libGLU, xorg }: { stdenv, cmake, ninja, libglvnd, libGLU, xorg, spdlog }:
stdenv.mkDerivation { stdenv.mkDerivation {
name = "assignment-2a"; name = "assignment-2a";
@ -15,6 +15,7 @@ stdenv.mkDerivation {
xorg.libXinerama xorg.libXinerama
xorg.libXrandr xorg.libXrandr
xorg.libXrender xorg.libXrender
spdlog
]; ];
preBuild = '' preBuild = ''

View file

@ -0,0 +1,60 @@
#include "controls.h"
#include "GLFW/glfw3.h"
#include <spdlog/spdlog.h>
void key_callback(GLFWwindow *window, int key, int scancode, int action,
int mods) {
int state = glfwGetKey(window, GLFW_KEY_E);
// checks to see if the escape or q key was pressed
if ((key == GLFW_KEY_ESCAPE || key == GLFW_KEY_Q) && action == GLFW_PRESS)
glfwSetWindowShouldClose(window, GL_TRUE);
if ((mods & GLFW_MOD_CONTROL) > 0) {
if (action == GLFW_PRESS) {
ctrl_pressed = true;
spdlog::debug("Press ctrl");
} else if (action == GLFW_RELEASE) {
ctrl_pressed = false;
spdlog::debug("Release ctrl");
}
} else {
}
}
void mouse_button_callback(GLFWwindow *window, int button, int action,
int mods) {
glfwGetCursorPos(window, &mouse_x, &mouse_y);
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS) {
}
// Pressed the left mouse button, starting drag
if (ctrl_pressed && button == GLFW_MOUSE_BUTTON_LEFT &&
action == GLFW_PRESS) {
is_dragging = true;
drag_start_x = mouse_x;
drag_start_y = mouse_y;
spdlog::debug("Start drag at ({}, {})!", drag_start_x, drag_start_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
}
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
mouse_x = xpos;
mouse_y = ypos;
// (necessary to quantify the amount and direction of cursor motion)
// take the appropriate action
if (is_dragging) {
}
}

View file

@ -0,0 +1,25 @@
#ifndef PERIPHERALS_H_
#define PERIPHERALS_H_
#include "GLFW/glfw3.h"
extern GLdouble mouse_x, mouse_y;
extern GLfloat M[16];
extern bool is_dragging, ctrl_pressed;
extern GLdouble drag_start_x, drag_start_y;
// function that is called whenever a keyboard event occurs; defines how
// keyboard input will be handled
void key_callback(GLFWwindow *window, int key, int scancode, int action,
int mods);
// function that is called whenever a mouse or trackpad button press event
// occurs
void mouse_button_callback(GLFWwindow *window, int button, int action,
int mods);
// function that is called whenever a cursor motion event occurs
void cursor_pos_callback(GLFWwindow *window, double xpos, double ypos);
#endif

View file

@ -1,9 +1,9 @@
// fragment shader template // fragment shader template
#version 150 #version 150
in vec4 vcolor; in vec4 vcolor;
out vec4 color; out vec4 color;
void main()
{ void main() {
color = vcolor; // set output color to interpolated color from vshader color = vcolor; // set output color to interpolated color from vshader
} }

View file

@ -1,277 +1,248 @@
// Skeleton code for hw2a // Skeleton code for hw2a
// Based on example code from: Interactive Computer Graphics: A Top-Down // Based on example code from: Interactive Computer Graphics: A Top-Down
// Approach with Shader-Based OpenGL (6th Edition), by Ed Angel // Approach with Shader-Based OpenGL (6th Edition), by Ed Angel
#include <iostream> #include <fmt/core.h>
#include <math.h> #include <fmt/format.h>
#include <sstream> #include <iostream>
#include <stdio.h> #include <math.h>
#include <stdlib.h> #include <spdlog/spdlog.h>
#include <sstream>
#define DEBUG_ON \ #include <stdio.h>
0 // repetitive of the debug flag in the shader loading code, included here #include <stdlib.h>
// for clarity only
#define DEBUG_ON \
// This file contains the code that reads the shaders from their files and 0 // repetitive of the debug flag in the shader loading code, included here
// compiles them // for clarity only
#include "ShaderStuff.hpp"
#include "shaders.h"
//----------------------------------------------------------------------------
#include "controls.h"
// initialize some basic structure types #include "util.h"
typedef struct {
GLfloat x, y; //----------------------------------------------------------------------------
} FloatType2D;
// initialize some basic structure types
typedef struct { typedef struct {
GLfloat r, g, b; GLfloat x, y;
} ColorType3D; } FloatType2D;
GLfloat M[16]; // general transformation matrix typedef struct {
GLfloat r, g, b;
// define some assorted global variables, to make life easier } ColorType3D;
GLint m_location;
GLdouble mouse_x, mouse_y; GLfloat M[16]; // general transformation matrix
GLint window_width = 500;
GLint window_height = 500; // define some assorted global variables, to make life easier
GLdouble pi = 4.0 * atan(1.0); GLint m_location;
GLdouble mouse_x, mouse_y;
GLFWcursor *hand_cursor, *arrow_cursor; // some different cursors GLint window_width = 500;
GLint window_height = 500;
GLint NVERTICES = 9; // part of the hard-coded model GLdouble pi = 4.0 * atan(1.0);
//---------------------------------------------------------------------------- bool is_dragging = false;
// function that is called whenever an error occurs bool ctrl_pressed = false;
static void error_callback(int error, const char *description) { GLdouble drag_start_x, drag_start_y;
fputs(description, stderr); // write the error description to stderr
} double figure_x, figure_y, figure_z;
//---------------------------------------------------------------------------- GLFWcursor *hand_cursor, *arrow_cursor; // some different cursors
// function that is called whenever a keyboard event occurs; defines how
// keyboard input will be handled GLint NVERTICES = 9; // part of the hard-coded model
static void key_callback(GLFWwindow *window, int key, int scancode, int action,
int mods) { void init(void) {
if (key == GLFW_KEY_ESCAPE && ColorType3D colors[NVERTICES];
action == GLFW_PRESS) // checks to see if the escape key was pressed FloatType2D vertices[NVERTICES];
glfwSetWindowShouldClose(window, GL_TRUE); // closes the window 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
// function that is called whenever a mouse or trackpad button press event colors[0].r = 1;
// occurs colors[0].g = 1;
static void mouse_button_callback(GLFWwindow *window, int button, int action, colors[0].b = 1; // white
int mods) { colors[1].r = 1;
glfwGetCursorPos(window, &mouse_x, &mouse_y); colors[1].g = 0;
colors[1].b = 0; // red
// Check which mouse button triggered the event, e.g. GLFW_MOUSE_BUTTON_LEFT, colors[2].r = 1;
// etc. and what the button action was, e.g. GLFW_PRESS, GLFW_RELEASE, etc. colors[2].g = 0;
// (Note that ordinary trackpad click = mouse left button) colors[2].b = 0; // red
// Also check if any modifier keys were active at the time of the button colors[3].r = 1;
// press, e.g. GLFW_MOD_ALT, etc. Take the appropriate action, which could colors[3].g = 1;
// (optionally) also include changing the cursor's appearance colors[3].b = 1; // white
} colors[4].r = 0;
colors[4].g = 0;
//---------------------------------------------------------------------------- colors[4].b = 1; // blue
// function that is called whenever a cursor motion event occurs colors[5].r = 0;
static void cursor_pos_callback(GLFWwindow *window, double xpos, double ypos) { colors[5].g = 0;
colors[5].b = 1; // blue
// determine the direction of the mouse or cursor motion colors[6].r = 1;
// update the current mouse or cursor location colors[6].g = 1;
// (necessary to quantify the amount and direction of cursor motion) colors[6].b = 1; // white
// take the appropriate action colors[7].r = 0;
} colors[7].g = 1;
colors[7].b = 1; // cyan
//---------------------------------------------------------------------------- colors[8].r = 0;
colors[8].g = 1;
void init(void) { colors[8].b = 1; // cyan
ColorType3D colors[NVERTICES];
FloatType2D vertices[NVERTICES]; vertices[0].x = 0;
GLuint vao[1], buffer, program, location1, location2; vertices[0].y = 0.25; // center
vertices[1].x = 0.25;
// set up some hard-coded colors and geometry vertices[1].y = 0.5; // upper right
// this part can be customized to read in an object description from a file vertices[2].x = -0.25;
colors[0].r = 1; vertices[2].y = 0.5; // upper left
colors[0].g = 1; vertices[3].x = 0;
colors[0].b = 1; // white vertices[3].y = 0.25; // center (again)
colors[1].r = 1; vertices[4].x = 0.25;
colors[1].g = 0; vertices[4].y = -0.5; // low-lower right
colors[1].b = 0; // red vertices[5].x = 0.5;
colors[2].r = 1; vertices[5].y = -0.25; // mid-lower right
colors[2].g = 0; vertices[6].x = 0;
colors[2].b = 0; // red vertices[6].y = 0.25; // center (again)
colors[3].r = 1; vertices[7].x = -0.5;
colors[3].g = 1; vertices[7].y = -0.25; // low-lower left
colors[3].b = 1; // white vertices[8].x = -0.25;
colors[4].r = 0; vertices[8].y = -0.5; // mid-lower left
colors[4].g = 0;
colors[4].b = 1; // blue // Create and bind a vertex array object
colors[5].r = 0; glGenVertexArrays(1, vao);
colors[5].g = 0; glBindVertexArray(vao[0]);
colors[5].b = 1; // blue
colors[6].r = 1; // Create and initialize a buffer object large enough to hold both vertex
colors[6].g = 1; // position and color data
colors[6].b = 1; // white glGenBuffers(1, &buffer);
colors[7].r = 0; glBindBuffer(GL_ARRAY_BUFFER, buffer);
colors[7].g = 1; glBufferData(GL_ARRAY_BUFFER, sizeof(vertices) + sizeof(colors), vertices,
colors[7].b = 1; // cyan GL_STATIC_DRAW);
colors[8].r = 0; glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(vertices), vertices);
colors[8].g = 1; glBufferSubData(GL_ARRAY_BUFFER, sizeof(vertices), sizeof(colors), colors);
colors[8].b = 1; // cyan
// Define the names of the shader files
vertices[0].x = 0; string shader_dir = env("SHADER_DIR").value_or(SRC_DIR);
vertices[0].y = 0.25; // center string vshader = fmt::format("{}/vshader2a.glsl", shader_dir);
vertices[1].x = 0.25; string fshader = fmt::format("{}/fshader2a.glsl", shader_dir);
vertices[1].y = 0.5; // upper right spdlog::info("Shaders from: {}", shader_dir);
vertices[2].x = -0.25;
vertices[2].y = 0.5; // upper left // Load the shaders and use the resulting shader program
vertices[3].x = 0; program = InitShader(vshader.c_str(), fshader.c_str());
vertices[3].y = 0.25; // center (again)
vertices[4].x = 0.25; // Determine locations of the necessary attributes and matrices used in the
vertices[4].y = -0.5; // low-lower right // vertex shader
vertices[5].x = 0.5; location1 = glGetAttribLocation(program, "vertex_position");
vertices[5].y = -0.25; // mid-lower right glEnableVertexAttribArray(location1);
vertices[6].x = 0; glVertexAttribPointer(location1, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0));
vertices[6].y = 0.25; // center (again) location2 = glGetAttribLocation(program, "vertex_color");
vertices[7].x = -0.5; glEnableVertexAttribArray(location2);
vertices[7].y = -0.25; // low-lower left glVertexAttribPointer(location2, 3, GL_FLOAT, GL_FALSE, 0,
vertices[8].x = -0.25; BUFFER_OFFSET(sizeof(vertices)));
vertices[8].y = -0.5; // mid-lower left m_location = glGetUniformLocation(program, "M");
// Create and bind a vertex array object // Define static OpenGL state variables
glGenVertexArrays(1, vao); glClearColor(1.0, 1.0, 1.0, 1.0); // white, opaque background
glBindVertexArray(vao[0]);
// Define some GLFW cursors (in case you want to dynamically change the
// Create and initialize a buffer object large enough to hold both vertex // cursor's appearance) If you want, you can add more cursors, or even define
// position and color data // your own cursor appearance
glGenBuffers(1, &buffer); arrow_cursor = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
glBindBuffer(GL_ARRAY_BUFFER, buffer); hand_cursor = glfwCreateStandardCursor(GLFW_HAND_CURSOR);
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);
int main(int argc, char **argv) {
// Define the names of the shader files spdlog::set_level(spdlog::level::debug);
std::stringstream vshader, fshader;
vshader << SRC_DIR << "/vshader2a.glsl"; int i;
fshader << SRC_DIR << "/fshader2a.glsl"; GLFWwindow *window;
// Load the shaders and use the resulting shader program // Define the error callback function
program = InitShader(vshader.str().c_str(), fshader.str().c_str()); glfwSetErrorCallback(error_callback);
// Determine locations of the necessary attributes and matrices used in the // Initialize GLFW (performs platform-specific initialization)
// vertex shader if (!glfwInit())
location1 = glGetAttribLocation(program, "vertex_position"); exit(EXIT_FAILURE);
glEnableVertexAttribArray(location1);
glVertexAttribPointer(location1, 2, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); // Ask for OpenGL 3.2
location2 = glGetAttribLocation(program, "vertex_color"); glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glEnableVertexAttribArray(location2); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glVertexAttribPointer(location2, 3, GL_FLOAT, GL_FALSE, 0, glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
BUFFER_OFFSET(sizeof(vertices))); glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
m_location = glGetUniformLocation(program, "M");
// Use GLFW to open a window within which to display your graphics
// Define static OpenGL state variables window = glfwCreateWindow(window_width, window_height, "HW2a", NULL, NULL);
glClearColor(1.0, 1.0, 1.0, 1.0); // white, opaque background
// Verify that the window was successfully created; if not, print error
// Define some GLFW cursors (in case you want to dynamically change the // message and terminate
// cursor's appearance) If you want, you can add more cursors, or even define if (!window) {
// your own cursor appearance printf("GLFW failed to create window; terminating\n");
arrow_cursor = glfwCreateStandardCursor(GLFW_ARROW_CURSOR); glfwTerminate();
hand_cursor = glfwCreateStandardCursor(GLFW_HAND_CURSOR); exit(EXIT_FAILURE);
} }
//---------------------------------------------------------------------------- glfwMakeContextCurrent(window); // makes the newly-created context current
int main(int argc, char **argv) { // Load all OpenGL functions (needed if using Windows)
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
int i; printf("gladLoadGLLoader failed; terminating\n");
GLFWwindow *window; glfwTerminate();
exit(EXIT_FAILURE);
// Define the error callback function }
glfwSetErrorCallback(error_callback);
// tells the system to wait for the rendered frame to finish updating
// Initialize GLFW (performs platform-specific initialization) // before swapping buffers; can help to avoid tearing
if (!glfwInit()) glfwSwapInterval(1);
exit(EXIT_FAILURE);
// Define the keyboard callback function
// Ask for OpenGL 3.2 glfwSetKeyCallback(window, key_callback);
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // Define the mouse button callback function
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2); glfwSetMouseButtonCallback(window, mouse_button_callback);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Define the mouse motion callback function
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE); glfwSetCursorPosCallback(window, cursor_pos_callback);
// Use GLFW to open a window within which to display your graphics // Create the shaders and perform other one-time initializations
window = glfwCreateWindow(window_width, window_height, "HW2a", NULL, NULL); spdlog::info("Initializing...");
init();
// Verify that the window was successfully created; if not, print error
// message and terminate // event loop
if (!window) { while (!glfwWindowShouldClose(window)) {
printf("GLFW failed to create window; terminating\n");
glfwTerminate(); // fill/re-fill the window with the background color
exit(EXIT_FAILURE); glClear(GL_COLOR_BUFFER_BIT);
}
// define/re-define the modelview matrix. In this template, we define M to
glfwMakeContextCurrent(window); // makes the newly-created context current // be the identity matrix; you will need define M according to the user's
// actions.
// Load all OpenGL functions (needed if using Windows) for (i = 0; i < 16; i++) {
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) { M[i] = (i % 5 == 0);
printf("gladLoadGLLoader failed; terminating\n"); }
glfwTerminate();
exit(EXIT_FAILURE); // sanity check that your matrix contents are what you expect them to be
} spdlog::debug(
"M = [{} {} {} {}\n {} {} {} {}\n {} {} {} {}\n {} {} "
glfwSwapInterval( "{} {}]\n",
1); // tells the system to wait for the rendered frame to finish updating M[0], M[4], M[8], M[12], M[1], M[5], M[9], M[13], M[2], M[6], M[10],
// before swapping buffers; can help to avoid tearing M[14], M[3], M[7], M[11], M[15]);
// Define the keyboard callback function // send the updated model transformation matrix to the GPU
glfwSetKeyCallback(window, key_callback); glUniformMatrix4fv(m_location, 1, GL_FALSE, M);
// Define the mouse button callback function
glfwSetMouseButtonCallback(window, mouse_button_callback); // draw a triangle between the first vertex and each
// Define the mouse motion callback function // successive vertex pair in the hard-coded model
glfwSetCursorPosCallback(window, cursor_pos_callback); glDrawArrays(GL_TRIANGLES, 0, NVERTICES);
// Create the shaders and perform other one-time initializations // ensure that all OpenGL calls have executed before swapping
init(); // buffers
glFlush();
// event loop
while (!glfwWindowShouldClose(window)) { glfwSwapBuffers(window); // swap buffers
glfwWaitEvents(); // wait for a new event before re-drawing
// fill/re-fill the window with the background color
glClear(GL_COLOR_BUFFER_BIT); } // end graphics loop
// define/re-define the modelview matrix. In this template, we define M to // Clean up
// be the identity matrix; you will need define M according to the user's glfwDestroyWindow(window);
// actions. glfwTerminate(); // destroys any remaining objects, frees resources allocated
for (i = 0; i < 16; i++) { // by GLFW
M[i] = (i % 5 == 0); exit(EXIT_SUCCESS);
}
} // end main
// 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

View file

@ -1,147 +1,149 @@
#include <string> #include <spdlog/spdlog.h>
#include <string>
#include <stdio.h>
#include <stdio.h>
#include "glad/glad.h"
#include "GLFW/glfw3.h" #include "glad/glad.h"
// Basic OpenGL program #include "GLFW/glfw3.h"
// Based on example code from: Interactive Computer Graphics: A Top-Down
// Approach with Shader-Based OpenGL (6th Edition), by Ed Angel // Basic OpenGL program
// Based on example code from: Interactive Computer Graphics: A Top-Down
#ifndef SHADERSTUFF // Approach with Shader-Based OpenGL (6th Edition), by Ed Angel
#define SHADERSTUFF 1
#ifndef SHADERSTUFF
#define DEBUG_ON 0 #define SHADERSTUFF 1
#define BUFFER_OFFSET(bytes) ((GLvoid *)(bytes))
#define DEBUG_ON 0
// Create a NULL-terminated string by reading the provided file #define BUFFER_OFFSET(bytes) ((GLvoid *)(bytes))
static char *readShaderSource(const char *shaderFile) {
FILE *fp; // Create a NULL-terminated string by reading the provided file
long length, count; static char *readShaderSource(const char *shaderFile) {
char *buffer; FILE *fp;
// struct stat fileinfo; long length, count;
char *buffer;
// open the file containing the text of the shader code // struct stat fileinfo;
fp = fopen(shaderFile, "rb");
// open the file containing the text of the shader code
// check for errors in opening the file fp = fopen(shaderFile, "rb");
if (fp == NULL) {
printf("can't open shader source file %s\n", shaderFile); // check for errors in opening the file
return NULL; if (fp == NULL) {
} spdlog::info(":skull: can't open shader source file {}", 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 // determine the file size
if (DEBUG_ON) fseek(fp, 0, SEEK_END); // move position indicator to the end of the file;
fprintf(stdout, "length in bytes of shader file: %ld\n", length); length = ftell(fp); // return the value of the current position
if (DEBUG_ON)
// allocate a buffer with the indicated number of bytes, plus one fprintf(stdout, "length in bytes of shader file: %ld\n", length);
buffer = new char[length + 1];
// allocate a buffer with the indicated number of bytes, plus one
// read the appropriate number of bytes from the file buffer = new char[length + 1];
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 // read the appropriate number of bytes from the file
if (DEBUG_ON) fseek(fp, 0, SEEK_SET); // move position indicator to the start of the file
fprintf(stdout, "count of bytes successfully read: %ld\n", count); count = fread(buffer, 1, length, fp); // read all of the bytes
if (DEBUG_ON)
// append a NULL character to indicate the end of the string fprintf(stdout, "count of bytes successfully read: %ld\n", count);
buffer[count] = '\0'; // because on some systems, count != length
// append a NULL character to indicate the end of the string
// close the file buffer[count] = '\0'; // because on some systems, count != length
fclose(fp);
// close the file
// return the string fclose(fp);
return buffer;
} // 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; // Create a GLSL program object from vertex and fragment shader files
GLuint program; GLuint InitShader(const char *vShaderFileName, const char *fShaderFileName) {
GLuint vertex_shader, fragment_shader;
// check GLSL version GLuint program;
if (DEBUG_ON)
printf("GLSL version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION)); // check GLSL version
if (DEBUG_ON)
// Create shader handlers printf("GLSL version: %s\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
fragment_shader = glCreateShader(GL_FRAGMENT_SHADER); // Create shader handlers
vertex_shader = glCreateShader(GL_VERTEX_SHADER);
// Read source code from file fragment_shader = glCreateShader(GL_FRAGMENT_SHADER);
std::string vs_text = readShaderSource(vShaderFileName);
std::string fs_text = readShaderSource(fShaderFileName); // Read source code from file
std::string vs_text = readShaderSource(vShaderFileName);
// error check std::string fs_text = readShaderSource(fShaderFileName);
if (vs_text == "") {
printf("Failed to read from vertex shader file %s\n", vShaderFileName); // error check
exit(1); if (vs_text == "") {
} else if (DEBUG_ON) { printf("Failed to read from vertex shader file %s\n", vShaderFileName);
printf("read shader code:\n%s\n", vs_text.c_str()); exit(1);
} } else if (DEBUG_ON) {
if (fs_text == "") { printf("read shader code:\n%s\n", vs_text.c_str());
printf("Failed to read from fragment shader file %s\n", fShaderFileName); }
exit(1); if (fs_text == "") {
} else if (DEBUG_ON) { printf("Failed to read from fragment shader file %s\n", fShaderFileName);
printf("read shader code:\n%s\n", fs_text.c_str()); 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(); // Set shader source
glShaderSource(vertex_shader, 1, &vv, NULL); const char *vv = vs_text.c_str();
glShaderSource(fragment_shader, 1, &ff, NULL); const char *ff = fs_text.c_str();
glShaderSource(vertex_shader, 1, &vv, NULL);
// Compile shaders glShaderSource(fragment_shader, 1, &ff, NULL);
glCompileShader(vertex_shader);
glCompileShader(fragment_shader); // Compile shaders
glCompileShader(vertex_shader);
// Check for errors in compiling shaders glCompileShader(fragment_shader);
GLint compiled;
glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &compiled); // Check for errors in compiling shaders
if (!compiled) { GLint compiled;
printf("vertex_shader failed to compile\n"); glGetShaderiv(vertex_shader, GL_COMPILE_STATUS, &compiled);
if (DEBUG_ON) { if (!compiled) {
GLint logMaxSize, logLength; printf("vertex_shader failed to compile\n");
glGetShaderiv(vertex_shader, GL_INFO_LOG_LENGTH, &logMaxSize); if (DEBUG_ON) {
printf("printing error message of %d bytes\n", logMaxSize); GLint logMaxSize, logLength;
char *logMsg = new char[logMaxSize]; glGetShaderiv(vertex_shader, GL_INFO_LOG_LENGTH, &logMaxSize);
glGetShaderInfoLog(vertex_shader, logMaxSize, &logLength, logMsg); printf("printing error message of %d bytes\n", logMaxSize);
printf("%d bytes retrieved\n", logLength); char *logMsg = new char[logMaxSize];
printf("error message: %s\n", logMsg); glGetShaderInfoLog(vertex_shader, logMaxSize, &logLength, logMsg);
delete[] logMsg; printf("%d bytes retrieved\n", logLength);
} printf("error message: %s\n", logMsg);
exit(1); delete[] logMsg;
} }
glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &compiled); exit(1);
if (!compiled) { }
printf("fragment_shader failed to compile\n"); glGetShaderiv(fragment_shader, GL_COMPILE_STATUS, &compiled);
if (DEBUG_ON) { if (!compiled) {
GLint logMaxSize, logLength; printf("fragment_shader failed to compile\n");
glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &logMaxSize); if (DEBUG_ON) {
printf("printing error message of %d bytes\n", logMaxSize); GLint logMaxSize, logLength;
char *logMsg = new char[logMaxSize]; glGetShaderiv(fragment_shader, GL_INFO_LOG_LENGTH, &logMaxSize);
glGetShaderInfoLog(fragment_shader, logMaxSize, &logLength, logMsg); printf("printing error message of %d bytes\n", logMaxSize);
printf("%d bytes retrieved\n", logLength); char *logMsg = new char[logMaxSize];
printf("error message: %s\n", logMsg); glGetShaderInfoLog(fragment_shader, logMaxSize, &logLength, logMsg);
delete[] logMsg; printf("%d bytes retrieved\n", logLength);
} printf("error message: %s\n", logMsg);
exit(1); delete[] logMsg;
} }
exit(1);
// Create the program }
program = glCreateProgram();
// Create the program
// Attach shaders to program program = glCreateProgram();
glAttachShader(program, vertex_shader);
glAttachShader(program, fragment_shader); // Attach shaders to program
glAttachShader(program, vertex_shader);
// Link and set program to use glAttachShader(program, fragment_shader);
glLinkProgram(program);
glUseProgram(program); // Link and set program to use
glLinkProgram(program);
return program; glUseProgram(program);
}
return program;
#endif }
#endif

View file

@ -0,0 +1,13 @@
#include "util.h"
#include <spdlog/spdlog.h>
optional<string> env(string ident) {
char *result = getenv(ident.c_str());
if (!result)
return {};
return string(result);
}
void error_callback(int error, const char *description) {
spdlog::error("{}", description);
}

12
assignment-2a/src/util.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef UTIL_H_
#define UTIL_H_
#include <optional>
#include <string>
using namespace std;
optional<string> env(string ident);
void error_callback(int error, const char *description);
#endif

View file

@ -1,12 +1,12 @@
// vertex shader template // vertex shader template
#version 150 #version 150
in vec4 vertex_position; in vec4 vertex_position;
in vec4 vertex_color; in vec4 vertex_color;
out vec4 vcolor; out vec4 vcolor;
uniform mat4 M; uniform mat4 M;
void main() { void main() {
gl_Position = M*vertex_position; // update vertex position using M gl_Position = M * vertex_position; // update vertex position using M
vcolor = vertex_color; // pass vertex color to fragment shader vcolor = vertex_color; // pass vertex color to fragment shader
} }

View file

@ -31,12 +31,13 @@
cargo-watch cargo-watch
clang-tools clang-tools
cmake cmake
dos2unix
imagemagick imagemagick
linuxPackages_latest.perf linuxPackages_latest.perf
ninja
pandoc pandoc
poppler_utils poppler_utils
texlive.combined.scheme-full texlive.combined.scheme-full
ninja
unzip unzip
zip zip
@ -62,6 +63,7 @@
xorg.libXinerama xorg.libXinerama
xorg.libXrandr xorg.libXrandr
xorg.libXrender xorg.libXrender
spdlog
]); ]);
}; };
}); });