mirror of
https://github.com/brammie15/VoxelRenderer.git
synced 2025-12-18 18:49:20 +01:00
Initial commit.
This commit is contained in:
171
gloom/src/camera.hpp
Normal file
171
gloom/src/camera.hpp
Normal 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
19
gloom/src/gloom.hpp
Normal 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
73
gloom/src/main.cpp
Normal 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
42
gloom/src/program.cpp
Normal 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
16
gloom/src/program.hpp
Normal 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
136
gloom/src/shader.hpp
Normal 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
|
||||
Reference in New Issue
Block a user