Initial commit.

This commit is contained in:
Aleksander Rognhaugen
2016-01-29 14:28:37 +01:00
commit 82a4de6b9a
18 changed files with 764 additions and 0 deletions

171
gloom/src/camera.hpp Normal file
View File

@@ -0,0 +1,171 @@
#ifndef CAMERA_HPP
#define CAMERA_HPP
#pragma once
// System headers
#include <glad/glad.h>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
namespace Gloom
{
enum CameraDirection {
FORWARD, BACKWARD, LEFT, RIGHT
};
class Camera
{
public:
Camera(GLfloat aspect, // aspect = mWidth / mHeight
GLfloat fov = 45.0f,
GLfloat nearClip = 0.1f,
GLfloat farClip = 1000.0f,
glm::vec3 position = glm::vec3(0.0f, 0.0f, 2.0f),
glm::vec3 up = glm::vec3(0.0f, 1.0f, 0.0f),
glm::vec3 front = glm::vec3(0.0f, 0.0f, -1.0f),
GLfloat yaw = -90.0f,
GLfloat pitch = 0.0f,
GLfloat movementSpeed = 3.0f,
GLfloat mouseSensitivity = 0.15f)
{
cAspect = aspect;
cFov = fov;
cNearClip = nearClip;
cFarClip = farClip;
cPosition = position;
cWorldUp = up;
cFront = front;
cYaw = yaw;
cPitch = pitch;
cMovementSpeed = movementSpeed;
cMouseSensitivity = mouseSensitivity;
update();
}
// Public member functions
/* Getter for the model, view, projection matrices */
void getMVP(glm::mat4 &proj, glm::mat4 &view, glm::mat4 &model)
{
proj = getProjectionMatrix();
view = getViewMatrix();
model = glm::mat4(1.0f);
}
/* Getter for the projection matrix */
glm::mat4 getProjectionMatrix()
{
return glm::perspective(cFov, cAspect, cNearClip, cFarClip);
}
/* Getter for the view matrix */
glm::mat4 getViewMatrix()
{
return glm::lookAt(cPosition, cPosition + cFront, cUp);
}
/* Process keyboard inputs
`deltaTime` is the time between the current and last frame */
void processKeyboard(Gloom::CameraDirection dir,
GLfloat deltaTime)
{
// Trick to balance PC speed with movement
GLfloat velocity = cMovementSpeed * deltaTime;
// Alter position in the appropriate direction
if (dir == Gloom::FORWARD)
{
cPosition += cFront * velocity;
}
if (dir == Gloom::BACKWARD)
{
cPosition -= cFront * velocity;
}
if (dir == Gloom::LEFT)
{
cPosition -= cRight * velocity;
}
if (dir == Gloom::RIGHT)
{
cPosition += cRight * velocity;
}
}
/* Process mouse movements */
void processMouse(GLfloat xoffset, GLfloat yoffset)
{
// Smoothing
xoffset *= cMouseSensitivity;
yoffset *= cMouseSensitivity;
// Update Euler angles
cYaw += xoffset;
cPitch += yoffset;
// Constrain pitch so the screen doesn't flip
if (cPitch > 89.0f)
{
cPitch = 89.0f;
}
if (cPitch < -89.0f)
{
cPitch = -89.0f;
}
// Update cFront, cRight, and cUp using the new yaw and pitch
update();
}
private:
// Disable copying and assignment
Camera(Camera const &) = delete;
Camera & operator =(Camera const &) = delete;
// Private member function
/* Computes the cFront, cRight, and cUp vector given updated
Euler angles */
void update()
{
// Calculate cFront
glm::vec3 front;
front.x = cos(glm::radians(cYaw)) * cos(glm::radians(cPitch));
front.y = sin(glm::radians(cPitch));
front.z = sin(glm::radians(cYaw)) * cos(glm::radians(cPitch));
cFront = glm::normalize(front);
// Re-calculate cRight and cUp
cRight = glm::normalize(glm::cross(cFront, cWorldUp));
cUp = glm::normalize(glm::cross(cRight, cFront));
}
// Private member variables
// Camera variables
glm::vec3 cPosition;
glm::vec3 cFront;
glm::vec3 cUp;
glm::vec3 cRight;
glm::vec3 cWorldUp;
// Euler angles
GLfloat cYaw;
GLfloat cPitch;
// Camera settings
GLfloat cMovementSpeed;
GLfloat cMouseSensitivity;
GLfloat cFov;
GLfloat cAspect;
GLfloat cNearClip;
GLfloat cFarClip;
};
}
#endif

19
gloom/src/gloom.hpp Normal file
View File

@@ -0,0 +1,19 @@
// Preprocessor directives
#ifndef GLOOM_HPP
#define GLOOM_HPP
#pragma once
// System Headers
#include <glad/glad.h>
// Standard headers
#include <string>
// Constants
const int mWidth = 1024;
const int mHeight = 768;
const std::string mTitle = "OpenGL";
const GLint mResizable = GL_FALSE;
const int mSamples = 4;
#endif

73
gloom/src/main.cpp Normal file
View File

@@ -0,0 +1,73 @@
// Local headers
#include "gloom.hpp"
#include "program.hpp"
// System headers
#include <glad/glad.h>
#include <GLFW/glfw3.h>
// Standard headers
#include <cstdlib>
GLFWwindow* initialise()
{
// Initialise GLFW
if (!glfwInit())
{
fprintf(stderr, "Could not start GLFW\n");
exit(EXIT_FAILURE);
}
// Set core window options (adjust version numbers if needed)
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
// Set additional window options
glfwWindowHint(GLFW_RESIZABLE, mResizable);
glfwWindowHint(GLFW_SAMPLES, mSamples); // MSAA
// Create window using GLFW
GLFWwindow* mWindow = glfwCreateWindow(mWidth,
mHeight,
mTitle.c_str(),
nullptr,
nullptr);
// Ensure the window is set up correctly
if (!mWindow)
{
fprintf(stderr, "Could not open GLFW window\n");
glfwTerminate();
exit(EXIT_FAILURE);
}
// Let the window be the current OpenGL context and initialise glad
glfwMakeContextCurrent(mWindow);
gladLoadGL();
// Print various OpenGL information to stdout
printf("%s: %s\n", glGetString(GL_VENDOR), glGetString(GL_RENDERER));
printf("GLFW\t %s\n", glfwGetVersionString());
printf("OpenGL\t %s\n", glGetString(GL_VERSION));
printf("GLSL\t %s\n\n", glGetString(GL_SHADING_LANGUAGE_VERSION));
return mWindow;
}
int main(int argc, char* argb[])
{
// Initialise window using GLFW
GLFWwindow* mWindow = initialise();
// Run an OpenGL application using this window
runProgram(mWindow);
// Terminate GLFW (no need to call glfwDestroyWindow)
glfwTerminate();
return EXIT_SUCCESS;
}

42
gloom/src/program.cpp Normal file
View File

@@ -0,0 +1,42 @@
// Local headers
#include "program.hpp"
#include "gloom.hpp"
#include "shader.hpp"
void runProgram(GLFWwindow* mWindow)
{
// Set GLFW callback mechanisms
glfwSetKeyCallback(mWindow, keyboardCallback);
// Enable depth (Z) buffer (accept "closest" fragment)
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
// Set default colour after clearing the colour buffer
glClearColor(0.3f, 0.3f, 0.4f, 1.0f);
// Rendering Loop
while (!glfwWindowShouldClose(mWindow))
{
// Clear colour and depth buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Handle other events
glfwPollEvents();
// Flip buffers
glfwSwapBuffers(mWindow);
}
}
void keyboardCallback(GLFWwindow* window, int key, int scancode,
int action, int mods)
{
// Use escape key for terminating the GLFW window
if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)
{
glfwSetWindowShouldClose(window, GL_TRUE);
}
}

16
gloom/src/program.hpp Normal file
View File

@@ -0,0 +1,16 @@
#ifndef PROGRAM_HPP
#define PROGRAM_HPP
#pragma once
// System headers
#include <GLFW/glfw3.h>
// Main OpenGL program
void runProgram(GLFWwindow* mWindow);
// GLFW callback mechanisms
void keyboardCallback(GLFWwindow* window, int key, int scancode,
int action, int mods);
#endif

136
gloom/src/shader.hpp Normal file
View File

@@ -0,0 +1,136 @@
#ifndef SHADER_HPP
#define SHADER_HPP
#pragma once
// System headers
#include <glad/glad.h>
// Standard headers
#include <cassert>
#include <fstream>
#include <memory>
#include <string>
namespace Gloom
{
class Shader
{
public:
Shader() { mProgram = glCreateProgram(); }
// Public member functions
void activate() { glUseProgram(mProgram); }
void deactivate() { glUseProgram(0); }
GLuint get() { return mProgram; }
void destroy() { glDeleteProgram(mProgram); }
/* Attach a shader to the current shader program */
void attach(std::string const &filename)
{
// Load GLSL Shader from source
std::ifstream fd(filename.c_str());
auto src = std::string(std::istreambuf_iterator<char>(fd),
(std::istreambuf_iterator<char>()));
// Create shader object
const char * source = src.c_str();
auto shader = create(filename);
glShaderSource(shader, 1, &source, nullptr);
glCompileShader(shader);
// Display errors
glGetShaderiv(shader, GL_COMPILE_STATUS, &mStatus);
if (!mStatus)
{
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &mLength);
std::unique_ptr<char[]> buffer(new char[mLength]);
glGetShaderInfoLog(shader, mLength, nullptr, buffer.get());
fprintf(stderr, "%s\n%s", filename.c_str(), buffer.get());
}
assert(mStatus);
// Attach shader and free allocated memory
glAttachShader(mProgram, shader);
glDeleteShader(shader);
}
/* Links all attached shaders together into a shader program */
void link()
{
// Link all attached shaders
glLinkProgram(mProgram);
// Display errors
glGetProgramiv(mProgram, GL_LINK_STATUS, &mStatus);
if (!mStatus)
{
glGetProgramiv(mProgram, GL_INFO_LOG_LENGTH, &mLength);
std::unique_ptr<char[]> buffer(new char[mLength]);
glGetProgramInfoLog(mProgram, mLength, nullptr, buffer.get());
fprintf(stderr, "%s\n", buffer.get());
}
assert(mStatus);
}
/* Convenience function that attaches and links a vertex and a
fragment shader in a shader program */
void makeBasicShader(std::string const &vertexFilename,
std::string const &fragmentFilename)
{
attach(vertexFilename);
attach(fragmentFilename);
link();
}
/* Used for debugging shader programs (expensive to run) */
bool isValid()
{
// Validate linked shader program
glValidateProgram(mProgram);
// Display errors
glGetProgramiv(mProgram, GL_VALIDATE_STATUS, &mStatus);
if (!mStatus)
{
glGetProgramiv(mProgram, GL_INFO_LOG_LENGTH, &mLength);
std::unique_ptr<char[]> buffer(new char[mLength]);
glGetProgramInfoLog(mProgram, mLength, nullptr, buffer.get());
fprintf(stderr, "%s\n", buffer.get());
return false;
}
return true;
}
/* Helper function for creating shaders */
GLuint create(std::string const &filename)
{
// Extract file extension and create the correct shader type
auto idx = filename.rfind(".");
auto ext = filename.substr(idx + 1);
if (ext == "comp") return glCreateShader(GL_COMPUTE_SHADER);
else if (ext == "frag") return glCreateShader(GL_FRAGMENT_SHADER);
else if (ext == "geom") return glCreateShader(GL_GEOMETRY_SHADER);
else if (ext == "vert") return glCreateShader(GL_VERTEX_SHADER);
else return false;
}
private:
// Disable copying and assignment
Shader(Shader const &) = delete;
Shader & operator =(Shader const &) = delete;
// Private member variables
GLuint mProgram;
GLint mStatus;
GLint mLength;
};
}
#endif