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

2
.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
[Bb]uild/*
!*/.gitkeep

16
.gitmodules vendored Normal file
View File

@@ -0,0 +1,16 @@
[submodule "gloom/vendor/glad"]
path = gloom/vendor/glad
url = https://github.com/Dav1dde/glad.git
branch = c
[submodule "gloom/vendor/glfw"]
path = gloom/vendor/glfw
url = https://github.com/glfw/glfw.git
branch = master
[submodule "gloom/vendor/glm"]
path = gloom/vendor/glm
url = https://github.com/g-truc/glm.git
branch = master
[submodule "gloom/vendor/stb"]
path = gloom/vendor/stb
url = https://github.com/nothings/stb.git
branch = master

80
CMakeLists.txt Normal file
View File

@@ -0,0 +1,80 @@
#
# Specify minimum CMake version and project name
#
cmake_minimum_required (VERSION 3.0)
project (gloom)
#
# CMake setup
#
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set (CMAKE_VERBOSE_MAKEFILE 0) # 1 should be used for debugging
set (CMAKE_SUPPRESS_REGENERATION TRUE) # Suppresses ZERO_CHECK
if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wpedantic -std=c++11")
if(NOT WIN32)
set(GLAD_LIBRARIES dl)
endif()
endif()
#
# GLFW options
#
option (GLFW_INSTALL OFF)
option (GLFW_BUILD_DOCS OFF)
option (GLFW_BUILD_EXAMPLES OFF)
option (GLFW_BUILD_TESTS OFF)
add_subdirectory (gloom/vendor/glfw)
#
# Set include paths
#
include_directories (gloom/src/
gloom/vendor/glad/include/
gloom/vendor/glfw/include/
gloom/vendor/glm/
gloom/vendor/stb/)
#
# Add files
#
file (GLOB VENDORS_SOURCES gloom/vendor/glad/src/glad.c)
file (GLOB_RECURSE PROJECT_HEADERS gloom/src/*.hpp
gloom/src/*.h)
file (GLOB_RECURSE PROJECT_SOURCES gloom/src/*.cpp
gloom/src/*.cxx
gloom/src/*.cc
gloom/src/*.c)
file (GLOB_RECURSE PROJECT_SHADERS gloom/shaders/*.comp
gloom/shaders/*.frag
gloom/shaders/*.geom
gloom/shaders/*.vert)
file (GLOB PROJECT_CONFIGS CMakeLists.txt
README.rst
.gitignore
.gitmodules)
#
# Organizing files
#
source_group ("headers" FILES ${PROJECT_HEADERS})
source_group ("shaders" FILES ${PROJECT_SHADERS})
source_group ("sources" FILES ${PROJECT_SOURCES})
source_group ("vendors" FILES ${VENDORS_SOURCES})
#
# Set executable and target link libraries
#
add_definitions (-DGLFW_INCLUDE_NONE
-DPROJECT_SOURCE_DIR=\"${PROJECT_SOURCE_DIR}\")
add_executable (${PROJECT_NAME} ${PROJECT_SOURCES} ${PROJECT_HEADERS}
${PROJECT_SHADERS} ${PROJECT_CONFIGS}
${VENDORS_SOURCES})
target_link_libraries (${PROJECT_NAME}
glfw
${GLFW_LIBRARIES}
${GLAD_LIBRARIES})
set_target_properties (${PROJECT_NAME} PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${PROJECT_NAME})

49
LICENSE Normal file
View File

@@ -0,0 +1,49 @@
The MIT License (MIT)
Copyright (c) 2015 Aleksander Rognhaugen
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
Glitter LICENSE
The MIT License (MIT)
Copyright (c) 2015 Kevin Fung
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
LearnOpenGL LICENSE
The header file camera.hpp found in the source directory is a modified
version of camera.h found in the github repository for LearnOpenGL.
https://github.com/JoeyDeVries/LearnOpenGL
From the about page at learnopengl.com:
All code samples, unless explicitly stated otherwise, are licensed under the public domain depicted by the terms of the CC0 1.0 Universal license as published by Creative Commons, either version 1.0 of the License, or (at your option) any later version.
You can find a human-readable format of the license here:
https://creativecommons.org/publicdomain/zero/1.0/
and the full license here:
https://creativecommons.org/publicdomain/zero/1.0/legalcode

140
README.rst Normal file
View File

@@ -0,0 +1,140 @@
=====
gloom
=====
A minimalistic boilerplate for OpenGL with C++ derived from `Glitter`_. Its intended use is to get smaller OpenGL projects quickly up and running for the graphics courses at `NTNU`_.
The following libraries are included with this project:
+---------+---------------------------------------+
| Library | Function |
+=========+=======================================+
| `glad`_ | OpenGL function loader |
+---------+---------------------------------------+
| `glfw`_ | Window creation and input handler |
+---------+---------------------------------------+
| `glm`_ | OpenGL mathematics |
+---------+---------------------------------------+
| `stb`_ | Various libraries, e.g. image loading |
+---------+---------------------------------------+
Additional functionality can be added by altering ``CMakeLists.txt``.
Dependencies
============
* `CMake`_ (v.3.*) is used to generate platform-specific makefiles and workspaces.
Please refer to the individual library repositories for more information about additional dependencies.
Getting started
===============
Download
--------
The project and all third-party libraries can be downloaded by cloning this repository with the ``--recursive`` flag.
.. code-block:: bash
git clone --recursive git@github.com:senbon/gloom.git
If you have already cloned the repository and missed the ``--recursive`` flag, then the following grabs all dependencies.
.. code-block:: bash
git submodule update --init
Compilation
-----------
Linux (command-line)
~~~~~~~~~~~~~~~~~~~~
With all dependencies installed, compiling the project is as easy as running CMake followed by the ``make`` command.
.. code-block:: bash
# Change into the directory where you want your makefiles
cd ./gloom/build
# Generate UNIX Makefile (point CMake to CMakeLists.txt)
cmake ..
# Execute make command
make
# Run executable
./gloom/gloom
Specific generators can also be specified with CMake if you want to create workspaces for an IDE, for example:
.. code-block::
cmake -G "CodeBlocks - Unix Makefiles"
Windows (cmake-gui)
~~~~~~~~~~~~~~~~~~~
1. Set the source code file to the root directory containing ``CMakeLists.txt``
2. Binaries can be built in the directory of your choice, e.g. ``gloom\build\``
3. Click the configure button and select which generator you would like to use
4. Click the generate button
5. If your generator is an IDE such as Visual Studio, then open up the newly created .sln file and build ``ALL_BUILD``. After this you might want to set ``gloom`` as you StartUp Project.
Examples
========
Shader class
------------
The class for loading shaders can be used as follows:
.. code-block:: cpp
#include "shader.hpp"
// ...
Gloom::Shader shader;
shader.attach("path_to_vertex_shader.vert");
shader.attach("path_to_fragment_shader.frag");
shader.link();
If all you are going to use are vertex and fragment shaders, then the piece of code above can be replaced by this:
.. code-block:: cpp
Gloom::Shader shader;
shader.makeBasicShader("path_to_vertex_shader.vert",
"path_to_fragment_shader.frag");
The shader program can be activated and deactivated as needed after you have linked the attached shaders. Below is an example from inside the rendering loop:
.. code-block:: cpp
// Activate shader program
shader.activate();
// Perform draw calls using, for example, glDrawArrays
// Deactivate shader program
shader.deactivate();
Remember to delete the shader program when exiting, e.g. ``shader.destroy();``.
.. Links
.. _Glitter: https://github.com/Polytonic/Glitter
.. _NTNU: https://www.ntnu.edu/
.. _glad: https://github.com/Dav1dde/glad
.. _glfw: https://github.com/glfw/glfw
.. _glm: https://github.com/g-truc/glm
.. _stb: https://github.com/nothings/stb
.. _CMake: https://cmake.org/

0
build/.gitkeep Normal file
View File

View File

@@ -0,0 +1,8 @@
#version 400 core
out vec4 color;
void main()
{
color = vec4(1.0f, 1.0f, 1.0f, 1.0f);
}

View File

@@ -0,0 +1,8 @@
#version 400 core
in vec3 position;
void main()
{
gl_Position = vec4(position, 1.0f);
}

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

1
gloom/vendor/glad vendored Submodule

Submodule gloom/vendor/glad added at 5bf3eda6da

1
gloom/vendor/glfw vendored Submodule

Submodule gloom/vendor/glfw added at d0649e6868

1
gloom/vendor/glm vendored Submodule

Submodule gloom/vendor/glm added at 8f0d854605

1
gloom/vendor/stb vendored Submodule

Submodule gloom/vendor/stb added at 955dfe991b