diff --git a/.gitmodules b/.gitmodules index 2cf019a..2c250a5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "vendor/glfw"] path = vendor/glfw url = git@github.com:glfw/glfw.git +[submodule "vendor/glm"] + path = vendor/glm + url = git@github.com:g-truc/glm.git diff --git a/CMakeLists.txt b/CMakeLists.txt index a709afe..7be59e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ cmake_minimum_required (VERSION 3.8) project ("Visualizer") -find_package(glfw3) +find_package(GLFW3) if(NOT GLFW3_FOUND) message(STATUS "Could not find GLFW binaries on system, building from source instead") add_subdirectory("vendor/glfw") @@ -14,5 +14,13 @@ if(NOT GLFW3_FOUND) set(GLFW3_LIBRARIES glfw) endif() +find_package(GLM) +if(NOT GLM_FOUND) + message(STATUS "Could not find GLM on system, including from source instead") + add_subdirectory("vendor/glm") + + set(GLM_INCLUDE_DIRS glm::glm_static) +endif() + # Include sub-projects. add_subdirectory ("src") diff --git a/src/Application.cpp b/src/Application.cpp index 2d91376..a74fe6b 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -67,7 +67,7 @@ void Application::Launch() { glfwPollEvents(); - glClearColor(0.1f, 0.0f, 0.1f, 1.0f); + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glfwSwapBuffers(window); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 767d25a..fd2f1e4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,6 @@ add_executable(visualizer "main.cpp" "Application.cpp" -) + "VertexArrayObject.cpp") target_sources(visualizer PUBLIC ${CMAKE_SOURCE_DIR}/vendor/glad/src/glad.c @@ -8,6 +8,7 @@ target_sources(visualizer PUBLIC target_include_directories(visualizer PUBLIC ${GLFW3_INCLUDE_DIRS} + ${GLM_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/vendor/glad/include ) diff --git a/src/VertexArrayObject.cpp b/src/VertexArrayObject.cpp new file mode 100644 index 0000000..61b1847 --- /dev/null +++ b/src/VertexArrayObject.cpp @@ -0,0 +1,53 @@ +#include "VertexArrayObject.hpp" + +#include +#include + +AbstractVertexArrayObject::~AbstractVertexArrayObject() +{ + glDeleteBuffers(1, &ebo); + glDeleteBuffers(1, &vbo); + glDeleteVertexArrays(1, &vao); +} + +AbstractVertexArrayObject::AbstractVertexArrayObject(const VertexArray& vertices, const IndexArray& indices, const Layout& layout, Usage usage) : + vao(0), vbo(0), ebo(0) +{ + glGenVertexArrays(1, &vao); + glBindVertexArray(vao); + + // Determing native OpenGL GLenum depending on specified usage + GLenum bufferUsage; + switch (usage) + { + case Usage::Static: bufferUsage = GL_STATIC_DRAW; break; + case Usage::Dynamic: bufferUsage = GL_DYNAMIC_DRAW; break; + case Usage::Stream: bufferUsage = GL_STREAM_DRAW; break; + + default: // Forgot to add a usage case to this switch + assert("Unknown buffer usage" == ""); + break; + } + + // Create VBO + glGenBuffers(1, &vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + + glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(float), (const void*)(vertices.data()), bufferUsage); + + // Create EBO + glGenBuffers(1, &ebo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); + + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(unsigned int), (const void*)(indices.data()), bufferUsage); + + // Set up pipeline layout + unsigned int index = 0; + for (const VertexAttribute& attribute : layout) + { + glVertexAttribPointer(index, attribute.size, attribute.type, attribute.normalized, attribute.stride, attribute.pointer); + glEnableVertexAttribArray(index); + + index++; + } +} diff --git a/src/VertexArrayObject.hpp b/src/VertexArrayObject.hpp new file mode 100644 index 0000000..7cd5b02 --- /dev/null +++ b/src/VertexArrayObject.hpp @@ -0,0 +1,57 @@ +#pragma once + +#include +#include + +// struct representing an OpenGL attribute pointer +struct VertexAttribute +{ + int size; + unsigned int type; + bool normalized; + unsigned int stride; + const void* pointer; +}; + +// Useful abbreviations +typedef std::vector VertexArray; +typedef std::vector IndexArray; +typedef std::vector Layout; + +// OpenGL Buffer usages (I turned them into an enum so it's easier to know what options exist) +enum class Usage +{ + Static, Stream, Dynamic +}; + +// VAO structure that sets up the buffers and deletes them at the end of the lifecycle +class AbstractVertexArrayObject +{ + friend class VAOFactory; + +public: + AbstractVertexArrayObject() = delete; + ~AbstractVertexArrayObject(); + +private: + AbstractVertexArrayObject(const VertexArray& vertices, const IndexArray& indices, const Layout& layout, Usage usage); + +private: + unsigned int vao, vbo, ebo; +}; + +// You cannot actually create this VAO, you are forced to use a shared pointer +// so the buffers dont get accidentally deleted while another obejct is potentially still using it. +// I find this to be very important since VAOs are supposed to be shared between copies of objects +// if they have the same model. +typedef std::shared_ptr VertexArrayObject; + +// Factory for creating said shared pointers. +class VAOFactory +{ +public: + static VertexArrayObject Produce(const VertexArray& vertices, const IndexArray& indices, const Layout& layout, Usage usage = Usage::Static) + { + return std::make_shared(vertices, indices, layout, usage); + } +}; \ No newline at end of file diff --git a/vendor/glm b/vendor/glm new file mode 160000 index 0000000..6ad79aa --- /dev/null +++ b/vendor/glm @@ -0,0 +1 @@ +Subproject commit 6ad79aae3eb5bf809c30bf1168171e9e55857e45