From 61ff63bef082312274b03ac4f116960af2a8ad33 Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Fri, 19 Aug 2022 00:20:53 -0400 Subject: [PATCH] Start working on scene based rendering The renderer will render a scene object which has entities and "stray" models to render --- examples/dev_testing/src/main.cpp | 37 +- include/simpleengine/camera.h | 6 +- include/simpleengine/component.h | 27 + include/simpleengine/entity.h | 46 + include/simpleengine/event/event.h | 5 +- include/simpleengine/gfx/material.h | 24 + include/simpleengine/gfx/model.h | 24 +- include/simpleengine/gfx/textured_model.h | 37 - include/simpleengine/gfx/vao.h | 3 +- include/simpleengine/objects/3d/mesh.h | 57 - include/simpleengine/objects/3d/terrain.h | 104 -- include/simpleengine/optional.h | 1807 --------------------- include/simpleengine/renderable.h | 6 +- include/simpleengine/scene.h | 44 + src/camera.cpp | 6 +- src/game.cpp | 2 +- src/gfx/model.cpp | 49 +- src/gfx/textured_model.cpp | 62 - src/objects/3d/mesh.cpp | 126 -- 19 files changed, 176 insertions(+), 2296 deletions(-) create mode 100644 include/simpleengine/component.h create mode 100644 include/simpleengine/entity.h create mode 100644 include/simpleengine/gfx/material.h delete mode 100644 include/simpleengine/gfx/textured_model.h delete mode 100644 include/simpleengine/objects/3d/mesh.h delete mode 100644 include/simpleengine/objects/3d/terrain.h delete mode 100644 include/simpleengine/optional.h create mode 100644 include/simpleengine/scene.h delete mode 100644 src/gfx/textured_model.cpp delete mode 100644 src/objects/3d/mesh.cpp diff --git a/examples/dev_testing/src/main.cpp b/examples/dev_testing/src/main.cpp index af791d1..01bb019 100644 --- a/examples/dev_testing/src/main.cpp +++ b/examples/dev_testing/src/main.cpp @@ -1,22 +1,24 @@ #include "simpleengine/camera.h" #include "simpleengine/gfx/light.h" +#include "simpleengine/gfx/material.h" #include "simpleengine/gfx/model.h" #include "simpleengine/gfx/renderer.h" #include "simpleengine/gfx/texture.h" -#include "simpleengine/objects/3d/terrain.h" #include "simpleengine/vector.h" -#include -#include -#include #include #include #include #include #include #include -#include #include +#include + +#include +#include + +#include #include #include #include @@ -33,22 +35,6 @@ CMRC_DECLARE(resource_shaders); namespace se = simpleengine; -class RendererEvent : public se::Event { -public: - RendererEvent(se::gfx::Renderer renderer) : se::Event(), renderer(renderer) {} - ~RendererEvent() = default; - - se::gfx::Renderer renderer; - - virtual void update(const float& delta_time) override { - - } - - virtual void render(GLFWwindow* target) override { - this->renderer.render(nullptr); - } -}; - std::string read_resource_shader(const std::string& path) { auto fs = cmrc::resource_shaders::get_filesystem(); cmrc::file vertex_file = fs.open(path); @@ -153,14 +139,17 @@ int main(int argc, char *argv[]) { 5, 6, 12, 12, 6, 13 }; - auto cube = std::make_shared(game.get_window(), core_shader, cube_vertices, cube_indicies); + se::gfx::Material material(white_texture, 1.f, 0.f, 0.f, 0.f, 0.f); + + auto cube = std::make_shared(cube_vertices, cube_indicies, + std::optional(material)); cube->calculate_normals(); cube->translate(3.5f, 0.f, 0.f); //game.add_event(cube); - auto renderer = std::make_shared(game.get_window(), core_shader); + /* auto renderer = std::make_shared(game.get_window(), core_shader); renderer->add_model(white_texture, cube); - game.add_event(renderer); + game.add_event(renderer); */ /* auto r_event = std::make_shared(renderer); game.add_event(r_event); */ diff --git a/include/simpleengine/camera.h b/include/simpleengine/camera.h index 4dfa9f0..3a5f012 100644 --- a/include/simpleengine/camera.h +++ b/include/simpleengine/camera.h @@ -12,7 +12,7 @@ namespace simpleengine { class Camera : public simpleengine::Event { private: - //glm::vec3 camera_forward; + GLFWwindow* window; public: glm::vec3 position; glm::vec3 rotation; @@ -20,9 +20,6 @@ namespace simpleengine { glm::mat4 projection_matrix; glm::mat4 view_matrix; - //glm::vec3 camera_rotation; - /* glm::vec3 world_up = glm::vec3(0.f, 1.f, 0.f); - glm::vec3 cam_front = glm::vec3(0.f, 0.f, -1.f); */ glm::vec3 camera_front = glm::vec3(0.0f, 0.0f, -1.0f); glm::vec3 camera_up = glm::vec3(0.0f, 1.0f, 0.0f); @@ -40,6 +37,5 @@ namespace simpleengine { glm::vec3 cam_front = glm::vec3(0.f, 0.f, -1.f)); virtual void update(const float& delta_time) override; - virtual void render(GLFWwindow* target) override; }; } \ No newline at end of file diff --git a/include/simpleengine/component.h b/include/simpleengine/component.h new file mode 100644 index 0000000..68dbc7a --- /dev/null +++ b/include/simpleengine/component.h @@ -0,0 +1,27 @@ +#pragma once + +#include "gfx/model.h" +#include "event/event.h" + +#include +#include + +namespace simpleengine { + /** + * @brief A Model is a object that will be shown on the screen by a renderer. + * + */ + class Component : public simpleengine::Event { + public: + Component() = default; + + virtual void update(const float& delta_time) override { + std::cout << "Component update" << std::endl; + } + + virtual std::vector> get_renderable_models() { + std::cout << "Got renderables" << std::endl; + return {}; + } + }; +} \ No newline at end of file diff --git a/include/simpleengine/entity.h b/include/simpleengine/entity.h new file mode 100644 index 0000000..c2d7004 --- /dev/null +++ b/include/simpleengine/entity.h @@ -0,0 +1,46 @@ +#pragma once + +#include "component.h" +#include "transformable.h" + +#include +#include +#include + +namespace simpleengine { + /** + * @brief A Model is a object that will be shown on the screen by a renderer. + * + */ + class Entity : public simpleengine::Event, public simpleengine::Transformable { + public: + std::vector components; + + Entity(std::vector components = {}) : components(components) { + + } + + virtual void update(const float& delta_time) override { + std::cout << "Update entity" << std::endl; + + for (auto& component : components) { + component.update(delta_time); + } + } + + virtual std::vector> get_renderable_models() { + std::cout << "Got renderables from entity" << std::endl; + + std::vector> models; + for (auto& component : components) { + std::vector> comp_models = component.get_renderable_models(); + + // Move comp_models into models + models.insert(models.end(), std::make_move_iterator(comp_models.begin()), + std::make_move_iterator(comp_models.end())); + } + + return models; + } + }; +} \ No newline at end of file diff --git a/include/simpleengine/event/event.h b/include/simpleengine/event/event.h index ca86fcf..978332d 100644 --- a/include/simpleengine/event/event.h +++ b/include/simpleengine/event/event.h @@ -9,12 +9,9 @@ namespace simpleengine { class Event : public simpleengine::Destructable { public: - explicit Event(GLFWwindow* window = nullptr) : window(window) {} + Event() = default; virtual ~Event() = default; virtual void update(const float& delta_time) = 0; - virtual void render(GLFWwindow* target) = 0; - protected: - GLFWwindow* window; }; } \ No newline at end of file diff --git a/include/simpleengine/gfx/material.h b/include/simpleengine/gfx/material.h new file mode 100644 index 0000000..471286f --- /dev/null +++ b/include/simpleengine/gfx/material.h @@ -0,0 +1,24 @@ +#pragma once + +#include "texture.h" + +#include + +namespace simpleengine::gfx { + class Material { + public: + Texture texture; + + float ambient_scalar; + float diffuse_scalar; + float specular_scalar; + float shine; + float reflectivity; + + Material(Texture texture, float shine, float reflectivity, float specular_scalar, float ambient_scalar, float diffuse_scalar) : + texture(texture), ambient_scalar(ambient_scalar), diffuse_scalar(diffuse_scalar), specular_scalar(specular_scalar), + shine(shine), reflectivity(reflectivity) { + + } + }; +} \ No newline at end of file diff --git a/include/simpleengine/gfx/model.h b/include/simpleengine/gfx/model.h index 68097fc..c1e94b1 100644 --- a/include/simpleengine/gfx/model.h +++ b/include/simpleengine/gfx/model.h @@ -1,38 +1,34 @@ #pragma once #include "shader.h" +#include "../event/event.h" #include "vao.h" #include "vbo.h" #include "../vertex.h" #include "../renderable.h" #include "../transformable.h" +#include "material.h" +#include #include namespace simpleengine::gfx { - class Model : public simpleengine::Renderable, public simpleengine::Transformable { + /** + * @brief A Model is a object that will be shown on the screen by a renderer. + * + */ + class Model : public simpleengine::Event, public simpleengine::Transformable { public: + std::optional material; std::vector vertices; std::vector indicies; - gfx::VBO ebo; - gfx::VBO vbo; - gfx::VAO vao; - gfx::Shader shader; + Model(std::vector vertices, std::vector indicies = std::vector(), std::optional material = std::nullopt); - Model(GLFWwindow* window, gfx::Shader shader, std::vector vertices, std::vector indicies = std::vector()); - Model(GLFWwindow* window, GLuint shader_program, std::vector vertices, - std::vector indicies = std::vector()); - protected: - virtual void setup_vertices(); - public: virtual void update(const float& delta_time) override; - virtual void render(GLFWwindow* target) override; - private: glm::vec3 compute_face_normal(const glm::vec3& p1, const glm::vec3& p2, const glm::vec3& p3); - public: /** * @brief Calculate the normals of the model. * diff --git a/include/simpleengine/gfx/textured_model.h b/include/simpleengine/gfx/textured_model.h deleted file mode 100644 index 13d7fdc..0000000 --- a/include/simpleengine/gfx/textured_model.h +++ /dev/null @@ -1,37 +0,0 @@ -#pragma once - -/* #include "shader.h" -#include "vao.h" -#include "vbo.h" -#include "../vertex.h" -#include "../renderable.h" -#include "../transformable.h" */ - -#include "ssbo.h" -#include "shader.h" -#include "model.h" -#include "texture.h" - -#include - -#include - -namespace simpleengine::gfx { - class TexturedModel : public simpleengine::gfx::Model { - public: - std::vector textures; - - TexturedModel(GLFWwindow* window, gfx::Shader shader, gfx::Texture texture, std::vector vertices, - std::vector indicies = std::vector()); - TexturedModel(GLFWwindow* window, GLuint shader_program, gfx::Texture texture, std::vector vertices, - std::vector indicies = std::vector()); - - TexturedModel(GLFWwindow* window, gfx::Shader shader, std::vector textures, std::vector vertices, - std::vector indicies = std::vector()); - TexturedModel(GLFWwindow* window, GLuint shader_program, std::vector textures, std::vector vertices, - std::vector indicies = std::vector()); - - virtual void update(const float& delta_time) override; - virtual void render(GLFWwindow* target) override; - }; -} \ No newline at end of file diff --git a/include/simpleengine/gfx/vao.h b/include/simpleengine/gfx/vao.h index f66b134..d45bd9f 100644 --- a/include/simpleengine/gfx/vao.h +++ b/include/simpleengine/gfx/vao.h @@ -50,9 +50,10 @@ namespace simpleengine::gfx { void bind() const { glBindVertexArray(handle); + // TODO: Handle opengl errors EVERYWHERE GLenum err = glGetError(); if (err != GL_NO_ERROR) { - //fprintf(stderr, "Ran into opengl error: 0x%x\n", err); + fprintf(stderr, "Ran into opengl error: 0x%x\n", err); //std::cerr << "Ran into enum error: " } } diff --git a/include/simpleengine/objects/3d/mesh.h b/include/simpleengine/objects/3d/mesh.h deleted file mode 100644 index 410ecfe..0000000 --- a/include/simpleengine/objects/3d/mesh.h +++ /dev/null @@ -1,57 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "../../optional.h" -#include "../../vector.h" -#include "../../vertex.h" -#include "../../renderable.h" -#include "../../transformable.h" -#include "../../gfx/vao.h" -#include "../../gfx/vbo.h" -#include "../../gfx/shader.h" -#include "../../gfx/texture.h" -#include "../../gfx/textured_model.h" - -namespace simpleengine::objects_3d { - class Mesh : public simpleengine::gfx::TexturedModel { - private: - /** - * @brief Split a string multiple times (if possible) with a character delimiter. - * - * @param str The string to split. - * @param delim The character to split by. - * @return std::vector The tokens that were split out of str. - */ - std::vector split_string(std::string str, const char delim); - - /** - * @brief Process a vertex from tokens read from the .obj file. - * - * @param vertex_data The vertex string tokens to process the vertex from. - * @param in_textures The texture coords that are unsorted, just read from the .obj file. - * @param in_normals The normals that are unsorted, just read from the .obj file. - * @param out_indicies (out) The vector to insert the indicies that were extracted from `vertex_data` into. - * @param out_textures (out) The vector to insert the texture coords that were extracted from `vertex_data` into. - * @param out_normals (out) The vector to insert the normals that were extracted from `vertex_data` into. - */ - static void process_vertex(const std::vector& vertex_data, const std::vector& in_textures, - const std::vector& in_normals, std::vector& out_indicies, std::vector& out_textures, std::vector& out_normals); - private: - /** - * @brief This is replaced with `lit_vertices`!!!! - * - */ - using simpleengine::gfx::Model::vertices; - public: - std::vector lit_vertices; - - Mesh(GLFWwindow *window, gfx::Shader shader, gfx::Texture texture, std::string filename); - Mesh(GLFWwindow *window, gfx::Shader shader, gfx::Texture texture, std::ifstream file_stream); - - virtual void update(const float& delta_time) override; - }; -} \ No newline at end of file diff --git a/include/simpleengine/objects/3d/terrain.h b/include/simpleengine/objects/3d/terrain.h deleted file mode 100644 index 19e1721..0000000 --- a/include/simpleengine/objects/3d/terrain.h +++ /dev/null @@ -1,104 +0,0 @@ -#pragma once - -#include "../../gfx/model.h" -#include "../../gfx/texture.h" -#include "../../gfx/textured_model.h" -#include "../../renderable.h" -#include "../../vertex.h" -#include - -namespace simpleengine::objects_3d { - class Terrain : public simpleengine::gfx::TexturedModel { - private: - /** - * @brief DO NOT USE!!! Replaced with lit_vertices - * - */ - using gfx::Model::vertices; - public: - std::vector lit_vertices; - const float size; - const int vertex_count; - - float x; - float y; - - gfx::Texture texture; - - Terrain(GLFWwindow* window, gfx::Shader shader, gfx::Texture texture, int grid_x, int grid_y, float size = 800.f, int vertex_count = 128) : - simpleengine::gfx::TexturedModel(window, shader, { texture }, std::vector()), x(grid_x * size), y(grid_y * size), - texture(texture), size(size), vertex_count(vertex_count) { - - generate_terrain(); - } - - protected: - virtual void setup_vertices() override { - vao.bind(); - vbo.buffer(lit_vertices.data(), 0, sizeof(LitVertex) * lit_vertices.size()); - ebo.buffer(indicies.data(), 0, indicies.size() * sizeof(GLuint)); - - // Enable VAO attributes - vao.enable_attrib(vbo, 0, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, position)); - //vao.enable_attrib(vbo, 1, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, color)); - vao.enable_attrib(vbo, 1, 2, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, tex_coord)); - vao.enable_attrib(vbo, 2, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, normal)); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); - } - public: - void generate_terrain() { - lit_vertices.clear(); - indicies.clear(); - - // Reserve space for vertices and indicies before hand. - int count = pow(vertex_count, 2); - lit_vertices.reserve(count); - indicies.reserve(6 * pow(vertex_count - 1, 2)); - - int vertex_index = 0; - for (int i = 0; i < vertex_count; i++) { - for (int j = 0; j < vertex_count; j++) { - Vectorf pos( (float) j / ((float) vertex_count - 1) * size, 0, (float) i / ((float) vertex_count - 1) * size); - glm::vec2 tex( (float) j / (float) vertex_count - 1, (float) i / (float) vertex_count - 1); - glm::vec3 normals(0, 1, 0); - lit_vertices.emplace_back(pos, tex, normals); - - vertex_index++; - } - } - - int indicies_index = 0; - for (int i = 0; i < vertex_count; i++) { - for (int j = 0; j < vertex_count; j++) { - int top_left = (i * vertex_count) + j; - int top_right = top_left + 1; - int bottom_left = ((i + 1) * vertex_count) + j; - int bottom_right = bottom_left + 1; - - indicies.push_back(top_left); - indicies.push_back(bottom_left); - indicies.push_back(top_right); - indicies.push_back(top_right); - indicies.push_back(bottom_left); - indicies.push_back(bottom_right); - } - } - - std::cout << "========= New terrain generated =========" << std::endl; - std::cout << " Lit vertices count: " << lit_vertices.size() << std::endl; - std::cout << " Indicies count: " << indicies.size() << std::endl; - - setup_vertices(); - } - - virtual void update(const float& delta_time) override { - - } - - /* virtual void render(GLFWwindow* target) override { - - } */ - }; -} \ No newline at end of file diff --git a/include/simpleengine/optional.h b/include/simpleengine/optional.h deleted file mode 100644 index 2c9f122..0000000 --- a/include/simpleengine/optional.h +++ /dev/null @@ -1,1807 +0,0 @@ -// -// Copyright (c) 2014-2021 Martin Moene -// -// https://github.com/martinmoene/optional-lite -// -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#pragma once - -#ifndef NONSTD_OPTIONAL_LITE_HPP -#define NONSTD_OPTIONAL_LITE_HPP - -#define optional_lite_MAJOR 3 -#define optional_lite_MINOR 5 -#define optional_lite_PATCH 0 - -#define optional_lite_VERSION optional_STRINGIFY(optional_lite_MAJOR) "." optional_STRINGIFY(optional_lite_MINOR) "." optional_STRINGIFY(optional_lite_PATCH) - -#define optional_STRINGIFY( x ) optional_STRINGIFY_( x ) -#define optional_STRINGIFY_( x ) #x - -// optional-lite configuration: - -#define optional_OPTIONAL_DEFAULT 0 -#define optional_OPTIONAL_NONSTD 1 -#define optional_OPTIONAL_STD 2 - -// tweak header support: - -#ifdef __has_include -# if __has_include() -# include -# endif -#define optional_HAVE_TWEAK_HEADER 1 -#else -#define optional_HAVE_TWEAK_HEADER 0 -//# pragma message("optional.hpp: Note: Tweak header not supported.") -#endif - -// optional selection and configuration: - -#if !defined( optional_CONFIG_SELECT_OPTIONAL ) -# define optional_CONFIG_SELECT_OPTIONAL ( optional_HAVE_STD_OPTIONAL ? optional_OPTIONAL_STD : optional_OPTIONAL_NONSTD ) -#endif - -// Control presence of exception handling (try and auto discover): - -#ifndef optional_CONFIG_NO_EXCEPTIONS -# if defined(_MSC_VER) -# include // for _HAS_EXCEPTIONS -# endif -# if defined(__cpp_exceptions) || defined(__EXCEPTIONS) || (_HAS_EXCEPTIONS) -# define optional_CONFIG_NO_EXCEPTIONS 0 -# else -# define optional_CONFIG_NO_EXCEPTIONS 1 -# endif -#endif - -// C++ language version detection (C++20 is speculative): -// Note: VC14.0/1900 (VS2015) lacks too much from C++14. - -#ifndef optional_CPLUSPLUS -# if defined(_MSVC_LANG ) && !defined(__clang__) -# define optional_CPLUSPLUS (_MSC_VER == 1900 ? 201103L : _MSVC_LANG ) -# else -# define optional_CPLUSPLUS __cplusplus -# endif -#endif - -#define optional_CPP98_OR_GREATER ( optional_CPLUSPLUS >= 199711L ) -#define optional_CPP11_OR_GREATER ( optional_CPLUSPLUS >= 201103L ) -#define optional_CPP11_OR_GREATER_ ( optional_CPLUSPLUS >= 201103L ) -#define optional_CPP14_OR_GREATER ( optional_CPLUSPLUS >= 201402L ) -#define optional_CPP17_OR_GREATER ( optional_CPLUSPLUS >= 201703L ) -#define optional_CPP20_OR_GREATER ( optional_CPLUSPLUS >= 202000L ) - -// C++ language version (represent 98 as 3): - -#define optional_CPLUSPLUS_V ( optional_CPLUSPLUS / 100 - (optional_CPLUSPLUS > 200000 ? 2000 : 1994) ) - -// Use C++17 std::optional if available and requested: - -#if optional_CPP17_OR_GREATER && defined(__has_include ) -# if __has_include( ) -# define optional_HAVE_STD_OPTIONAL 1 -# else -# define optional_HAVE_STD_OPTIONAL 0 -# endif -#else -# define optional_HAVE_STD_OPTIONAL 0 -#endif - -#define optional_USES_STD_OPTIONAL ( (optional_CONFIG_SELECT_OPTIONAL == optional_OPTIONAL_STD) || ((optional_CONFIG_SELECT_OPTIONAL == optional_OPTIONAL_DEFAULT) && optional_HAVE_STD_OPTIONAL) ) - -// -// in_place: code duplicated in any-lite, expected-lite, optional-lite, value-ptr-lite, variant-lite: -// - -#ifndef nonstd_lite_HAVE_IN_PLACE_TYPES -#define nonstd_lite_HAVE_IN_PLACE_TYPES 1 - -// C++17 std::in_place in : - -#if optional_CPP17_OR_GREATER - -#include - -namespace nonstd { - -using std::in_place; -using std::in_place_type; -using std::in_place_index; -using std::in_place_t; -using std::in_place_type_t; -using std::in_place_index_t; - -#define nonstd_lite_in_place_t( T) std::in_place_t -#define nonstd_lite_in_place_type_t( T) std::in_place_type_t -#define nonstd_lite_in_place_index_t(K) std::in_place_index_t - -#define nonstd_lite_in_place( T) std::in_place_t{} -#define nonstd_lite_in_place_type( T) std::in_place_type_t{} -#define nonstd_lite_in_place_index(K) std::in_place_index_t{} - -} // namespace nonstd - -#else // optional_CPP17_OR_GREATER - -#include - -namespace nonstd { -namespace detail { - -template< class T > -struct in_place_type_tag {}; - -template< std::size_t K > -struct in_place_index_tag {}; - -} // namespace detail - -struct in_place_t {}; - -template< class T > -inline in_place_t in_place( detail::in_place_type_tag /*unused*/ = detail::in_place_type_tag() ) -{ - return in_place_t(); -} - -template< std::size_t K > -inline in_place_t in_place( detail::in_place_index_tag /*unused*/ = detail::in_place_index_tag() ) -{ - return in_place_t(); -} - -template< class T > -inline in_place_t in_place_type( detail::in_place_type_tag /*unused*/ = detail::in_place_type_tag() ) -{ - return in_place_t(); -} - -template< std::size_t K > -inline in_place_t in_place_index( detail::in_place_index_tag /*unused*/ = detail::in_place_index_tag() ) -{ - return in_place_t(); -} - -// mimic templated typedef: - -#define nonstd_lite_in_place_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag ) -#define nonstd_lite_in_place_type_t( T) nonstd::in_place_t(&)( nonstd::detail::in_place_type_tag ) -#define nonstd_lite_in_place_index_t(K) nonstd::in_place_t(&)( nonstd::detail::in_place_index_tag ) - -#define nonstd_lite_in_place( T) nonstd::in_place_type -#define nonstd_lite_in_place_type( T) nonstd::in_place_type -#define nonstd_lite_in_place_index(K) nonstd::in_place_index - -} // namespace nonstd - -#endif // optional_CPP17_OR_GREATER -#endif // nonstd_lite_HAVE_IN_PLACE_TYPES - -// -// Using std::optional: -// - -#if optional_USES_STD_OPTIONAL - -#include - -namespace nonstd { - - using std::optional; - using std::bad_optional_access; - using std::hash; - - using std::nullopt; - using std::nullopt_t; - - using std::operator==; - using std::operator!=; - using std::operator<; - using std::operator<=; - using std::operator>; - using std::operator>=; - using std::make_optional; - using std::swap; -} - -#else // optional_USES_STD_OPTIONAL - -#include -#include - -// optional-lite alignment configuration: - -#ifndef optional_CONFIG_MAX_ALIGN_HACK -# define optional_CONFIG_MAX_ALIGN_HACK 0 -#endif - -#ifndef optional_CONFIG_ALIGN_AS -// no default, used in #if defined() -#endif - -#ifndef optional_CONFIG_ALIGN_AS_FALLBACK -# define optional_CONFIG_ALIGN_AS_FALLBACK double -#endif - -// Compiler warning suppression: - -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wundef" -#elif defined(__GNUC__) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wundef" -#elif defined(_MSC_VER ) -# pragma warning( push ) -#endif - -// half-open range [lo..hi): -#define optional_BETWEEN( v, lo, hi ) ( (lo) <= (v) && (v) < (hi) ) - -// Compiler versions: -// -// MSVC++ 6.0 _MSC_VER == 1200 optional_COMPILER_MSVC_VERSION == 60 (Visual Studio 6.0) -// MSVC++ 7.0 _MSC_VER == 1300 optional_COMPILER_MSVC_VERSION == 70 (Visual Studio .NET 2002) -// MSVC++ 7.1 _MSC_VER == 1310 optional_COMPILER_MSVC_VERSION == 71 (Visual Studio .NET 2003) -// MSVC++ 8.0 _MSC_VER == 1400 optional_COMPILER_MSVC_VERSION == 80 (Visual Studio 2005) -// MSVC++ 9.0 _MSC_VER == 1500 optional_COMPILER_MSVC_VERSION == 90 (Visual Studio 2008) -// MSVC++ 10.0 _MSC_VER == 1600 optional_COMPILER_MSVC_VERSION == 100 (Visual Studio 2010) -// MSVC++ 11.0 _MSC_VER == 1700 optional_COMPILER_MSVC_VERSION == 110 (Visual Studio 2012) -// MSVC++ 12.0 _MSC_VER == 1800 optional_COMPILER_MSVC_VERSION == 120 (Visual Studio 2013) -// MSVC++ 14.0 _MSC_VER == 1900 optional_COMPILER_MSVC_VERSION == 140 (Visual Studio 2015) -// MSVC++ 14.1 _MSC_VER >= 1910 optional_COMPILER_MSVC_VERSION == 141 (Visual Studio 2017) -// MSVC++ 14.2 _MSC_VER >= 1920 optional_COMPILER_MSVC_VERSION == 142 (Visual Studio 2019) - -#if defined(_MSC_VER ) && !defined(__clang__) -# define optional_COMPILER_MSVC_VER (_MSC_VER ) -# define optional_COMPILER_MSVC_VERSION (_MSC_VER / 10 - 10 * ( 5 + (_MSC_VER < 1900 ) ) ) -#else -# define optional_COMPILER_MSVC_VER 0 -# define optional_COMPILER_MSVC_VERSION 0 -#endif - -#define optional_COMPILER_VERSION( major, minor, patch ) ( 10 * (10 * (major) + (minor) ) + (patch) ) - -#if defined(__GNUC__) && !defined(__clang__) -# define optional_COMPILER_GNUC_VERSION optional_COMPILER_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) -#else -# define optional_COMPILER_GNUC_VERSION 0 -#endif - -#if defined(__clang__) -# define optional_COMPILER_CLANG_VERSION optional_COMPILER_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__) -#else -# define optional_COMPILER_CLANG_VERSION 0 -#endif - -#if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 140 ) -# pragma warning( disable: 4345 ) // initialization behavior changed -#endif - -#if optional_BETWEEN(optional_COMPILER_MSVC_VERSION, 70, 150 ) -# pragma warning( disable: 4814 ) // in C++14 'constexpr' will not imply 'const' -#endif - -// Presence of language and library features: - -#define optional_HAVE(FEATURE) ( optional_HAVE_##FEATURE ) - -#ifdef _HAS_CPP0X -# define optional_HAS_CPP0X _HAS_CPP0X -#else -# define optional_HAS_CPP0X 0 -#endif - -// Unless defined otherwise below, consider VC14 as C++11 for optional-lite: - -#if optional_COMPILER_MSVC_VER >= 1900 -# undef optional_CPP11_OR_GREATER -# define optional_CPP11_OR_GREATER 1 -#endif - -#define optional_CPP11_90 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1500) -#define optional_CPP11_100 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1600) -#define optional_CPP11_110 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1700) -#define optional_CPP11_120 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1800) -#define optional_CPP11_140 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1900) -#define optional_CPP11_141 (optional_CPP11_OR_GREATER_ || optional_COMPILER_MSVC_VER >= 1910) - -#define optional_CPP14_000 (optional_CPP14_OR_GREATER) -#define optional_CPP17_000 (optional_CPP17_OR_GREATER) - -// clang >= 2.9, gcc >= 4.9, msvc >= vc14.0/1900 (vs15): -#define optional_CPP11_140_C290_G490 ((optional_CPP11_OR_GREATER_ && (optional_COMPILER_CLANG_VERSION >= 290 || optional_COMPILER_GNUC_VERSION >= 490)) || (optional_COMPILER_MSVC_VER >= 1900)) - -// clang >= 3.5, msvc >= vc11 (vs12): -#define optional_CPP11_110_C350 ( optional_CPP11_110 && !optional_BETWEEN( optional_COMPILER_CLANG_VERSION, 1, 350 ) ) - -// clang >= 3.5, gcc >= 5.0, msvc >= vc11 (vs12): -#define optional_CPP11_110_C350_G500 \ - ( optional_CPP11_110 && \ - !( optional_BETWEEN( optional_COMPILER_CLANG_VERSION, 1, 350 ) \ - || optional_BETWEEN( optional_COMPILER_GNUC_VERSION , 1, 500 ) ) ) - -// Presence of C++11 language features: - -#define optional_HAVE_CONSTEXPR_11 optional_CPP11_140 -#define optional_HAVE_IS_DEFAULT optional_CPP11_140 -#define optional_HAVE_NOEXCEPT optional_CPP11_140 -#define optional_HAVE_NULLPTR optional_CPP11_100 -#define optional_HAVE_REF_QUALIFIER optional_CPP11_140_C290_G490 -#define optional_HAVE_STATIC_ASSERT optional_CPP11_110 -#define optional_HAVE_INITIALIZER_LIST optional_CPP11_140 - -// Presence of C++14 language features: - -#define optional_HAVE_CONSTEXPR_14 optional_CPP14_000 - -// Presence of C++17 language features: - -#define optional_HAVE_NODISCARD optional_CPP17_000 - -// Presence of C++ library features: - -#define optional_HAVE_CONDITIONAL optional_CPP11_120 -#define optional_HAVE_REMOVE_CV optional_CPP11_120 -#define optional_HAVE_TYPE_TRAITS optional_CPP11_90 - -#define optional_HAVE_TR1_TYPE_TRAITS (!! optional_COMPILER_GNUC_VERSION ) -#define optional_HAVE_TR1_ADD_POINTER (!! optional_COMPILER_GNUC_VERSION ) - -#define optional_HAVE_IS_ASSIGNABLE optional_CPP11_110_C350 -#define optional_HAVE_IS_MOVE_CONSTRUCTIBLE optional_CPP11_110_C350 -#define optional_HAVE_IS_NOTHROW_MOVE_ASSIGNABLE optional_CPP11_110_C350 -#define optional_HAVE_IS_NOTHROW_MOVE_CONSTRUCTIBLE optional_CPP11_110_C350 -#define optional_HAVE_IS_TRIVIALLY_COPY_CONSTRUCTIBLE optional_CPP11_110_C350_G500 -#define optional_HAVE_IS_TRIVIALLY_MOVE_CONSTRUCTIBLE optional_CPP11_110_C350_G500 - -// C++ feature usage: - -#if optional_HAVE( CONSTEXPR_11 ) -# define optional_constexpr constexpr -#else -# define optional_constexpr /*constexpr*/ -#endif - -#if optional_HAVE( IS_DEFAULT ) -# define optional_is_default = default; -#else -# define optional_is_default {} -#endif - -#if optional_HAVE( CONSTEXPR_14 ) -# define optional_constexpr14 constexpr -#else -# define optional_constexpr14 /*constexpr*/ -#endif - -#if optional_HAVE( NODISCARD ) -# define optional_nodiscard [[nodiscard]] -#else -# define optional_nodiscard /*[[nodiscard]]*/ -#endif - -#if optional_HAVE( NOEXCEPT ) -# define optional_noexcept noexcept -#else -# define optional_noexcept /*noexcept*/ -#endif - -#if optional_HAVE( NULLPTR ) -# define optional_nullptr nullptr -#else -# define optional_nullptr NULL -#endif - -#if optional_HAVE( REF_QUALIFIER ) -// NOLINTNEXTLINE( bugprone-macro-parentheses ) -# define optional_ref_qual & -# define optional_refref_qual && -#else -# define optional_ref_qual /*&*/ -# define optional_refref_qual /*&&*/ -#endif - -#if optional_HAVE( STATIC_ASSERT ) -# define optional_static_assert(expr, text) static_assert(expr, text); -#else -# define optional_static_assert(expr, text) /*static_assert(expr, text);*/ -#endif - -// additional includes: - -#if optional_CONFIG_NO_EXCEPTIONS -// already included: -#else -# include -#endif - -#if optional_CPP11_OR_GREATER -# include -#endif - -#if optional_HAVE( INITIALIZER_LIST ) -# include -#endif - -#if optional_HAVE( TYPE_TRAITS ) -# include -#elif optional_HAVE( TR1_TYPE_TRAITS ) -# include -#endif - -// Method enabling - -#if optional_CPP11_OR_GREATER - -#define optional_REQUIRES_0(...) \ - template< bool B = (__VA_ARGS__), typename std::enable_if::type = 0 > - -#define optional_REQUIRES_T(...) \ - , typename std::enable_if< (__VA_ARGS__), int >::type = 0 - -#define optional_REQUIRES_R(R, ...) \ - typename std::enable_if< (__VA_ARGS__), R>::type - -#define optional_REQUIRES_A(...) \ - , typename std::enable_if< (__VA_ARGS__), void*>::type = nullptr - -#endif - -// -// optional: -// - -namespace nonstd { namespace optional_lite { - -namespace std11 { - -template< class T, T v > struct integral_constant { enum { value = v }; }; -template< bool B > struct bool_constant : integral_constant{}; - -typedef bool_constant< true > true_type; -typedef bool_constant< false > false_type; - -#if optional_CPP11_OR_GREATER - using std::move; -#else - template< typename T > T & move( T & t ) { return t; } -#endif - -#if optional_HAVE( CONDITIONAL ) - using std::conditional; -#else - template< bool B, typename T, typename F > struct conditional { typedef T type; }; - template< typename T, typename F > struct conditional { typedef F type; }; -#endif // optional_HAVE_CONDITIONAL - -#if optional_HAVE( IS_ASSIGNABLE ) - using std::is_assignable; -#else - template< class T, class U > struct is_assignable : std11::true_type{}; -#endif - -#if optional_HAVE( IS_MOVE_CONSTRUCTIBLE ) - using std::is_move_constructible; -#else - template< class T > struct is_move_constructible : std11::true_type{}; -#endif - -#if optional_HAVE( IS_NOTHROW_MOVE_ASSIGNABLE ) - using std::is_nothrow_move_assignable; -#else - template< class T > struct is_nothrow_move_assignable : std11::true_type{}; -#endif - -#if optional_HAVE( IS_NOTHROW_MOVE_CONSTRUCTIBLE ) - using std::is_nothrow_move_constructible; -#else - template< class T > struct is_nothrow_move_constructible : std11::true_type{}; -#endif - -#if optional_HAVE( IS_TRIVIALLY_COPY_CONSTRUCTIBLE ) - using std::is_trivially_copy_constructible; -#else - template< class T > struct is_trivially_copy_constructible : std11::true_type{}; -#endif - -#if optional_HAVE( IS_TRIVIALLY_MOVE_CONSTRUCTIBLE ) - using std::is_trivially_move_constructible; -#else - template< class T > struct is_trivially_move_constructible : std11::true_type{}; -#endif - -} // namespace std11 - -#if optional_CPP11_OR_GREATER - -/// type traits C++17: - -namespace std17 { - -#if optional_CPP17_OR_GREATER - -using std::is_swappable; -using std::is_nothrow_swappable; - -#elif optional_CPP11_OR_GREATER - -namespace detail { - -using std::swap; - -struct is_swappable -{ - template< typename T, typename = decltype( swap( std::declval(), std::declval() ) ) > - static std11::true_type test( int /*unused*/ ); - - template< typename > - static std11::false_type test(...); -}; - -struct is_nothrow_swappable -{ - // wrap noexcept(expr) in separate function as work-around for VC140 (VS2015): - - template< typename T > - static constexpr bool satisfies() - { - return noexcept( swap( std::declval(), std::declval() ) ); - } - - template< typename T > - static auto test( int /*unused*/ ) -> std11::integral_constant()>{} - - template< typename > - static auto test(...) -> std11::false_type; -}; - -} // namespace detail - -// is [nothow] swappable: - -template< typename T > -struct is_swappable : decltype( detail::is_swappable::test(0) ){}; - -template< typename T > -struct is_nothrow_swappable : decltype( detail::is_nothrow_swappable::test(0) ){}; - -#endif // optional_CPP17_OR_GREATER - -} // namespace std17 - -/// type traits C++20: - -namespace std20 { - -template< typename T > -struct remove_cvref -{ - typedef typename std::remove_cv< typename std::remove_reference::type >::type type; -}; - -} // namespace std20 - -#endif // optional_CPP11_OR_GREATER - -/// class optional - -template< typename T > -class optional; - -namespace detail { - -// C++11 emulation: - -struct nulltype{}; - -template< typename Head, typename Tail > -struct typelist -{ - typedef Head head; - typedef Tail tail; -}; - -#if optional_CONFIG_MAX_ALIGN_HACK - -// Max align, use most restricted type for alignment: - -#define optional_UNIQUE( name ) optional_UNIQUE2( name, __LINE__ ) -#define optional_UNIQUE2( name, line ) optional_UNIQUE3( name, line ) -#define optional_UNIQUE3( name, line ) name ## line - -#define optional_ALIGN_TYPE( type ) \ - type optional_UNIQUE( _t ); struct_t< type > optional_UNIQUE( _st ) - -template< typename T > -struct struct_t { T _; }; - -union max_align_t -{ - optional_ALIGN_TYPE( char ); - optional_ALIGN_TYPE( short int ); - optional_ALIGN_TYPE( int ); - optional_ALIGN_TYPE( long int ); - optional_ALIGN_TYPE( float ); - optional_ALIGN_TYPE( double ); - optional_ALIGN_TYPE( long double ); - optional_ALIGN_TYPE( char * ); - optional_ALIGN_TYPE( short int * ); - optional_ALIGN_TYPE( int * ); - optional_ALIGN_TYPE( long int * ); - optional_ALIGN_TYPE( float * ); - optional_ALIGN_TYPE( double * ); - optional_ALIGN_TYPE( long double * ); - optional_ALIGN_TYPE( void * ); - -#ifdef HAVE_LONG_LONG - optional_ALIGN_TYPE( long long ); -#endif - - struct Unknown; - - Unknown ( * optional_UNIQUE(_) )( Unknown ); - Unknown * Unknown::* optional_UNIQUE(_); - Unknown ( Unknown::* optional_UNIQUE(_) )( Unknown ); - - struct_t< Unknown ( * )( Unknown) > optional_UNIQUE(_); - struct_t< Unknown * Unknown::* > optional_UNIQUE(_); - struct_t< Unknown ( Unknown::* )(Unknown) > optional_UNIQUE(_); -}; - -#undef optional_UNIQUE -#undef optional_UNIQUE2 -#undef optional_UNIQUE3 - -#undef optional_ALIGN_TYPE - -#elif defined( optional_CONFIG_ALIGN_AS ) // optional_CONFIG_MAX_ALIGN_HACK - -// Use user-specified type for alignment: - -#define optional_ALIGN_AS( unused ) \ - optional_CONFIG_ALIGN_AS - -#else // optional_CONFIG_MAX_ALIGN_HACK - -// Determine POD type to use for alignment: - -#define optional_ALIGN_AS( to_align ) \ - typename type_of_size< alignment_types, alignment_of< to_align >::value >::type - -template< typename T > -struct alignment_of; - -template< typename T > -struct alignment_of_hack -{ - char c; - T t; - alignment_of_hack(); -}; - -template< size_t A, size_t S > -struct alignment_logic -{ - enum { value = A < S ? A : S }; -}; - -template< typename T > -struct alignment_of -{ - enum { value = alignment_logic< - sizeof( alignment_of_hack ) - sizeof(T), sizeof(T) >::value }; -}; - -template< typename List, size_t N > -struct type_of_size -{ - typedef typename std11::conditional< - N == sizeof( typename List::head ), - typename List::head, - typename type_of_size::type >::type type; -}; - -template< size_t N > -struct type_of_size< nulltype, N > -{ - typedef optional_CONFIG_ALIGN_AS_FALLBACK type; -}; - -template< typename T> -struct struct_t { T _; }; - -#define optional_ALIGN_TYPE( type ) \ - typelist< type , typelist< struct_t< type > - -struct Unknown; - -typedef - optional_ALIGN_TYPE( char ), - optional_ALIGN_TYPE( short ), - optional_ALIGN_TYPE( int ), - optional_ALIGN_TYPE( long ), - optional_ALIGN_TYPE( float ), - optional_ALIGN_TYPE( double ), - optional_ALIGN_TYPE( long double ), - - optional_ALIGN_TYPE( char *), - optional_ALIGN_TYPE( short * ), - optional_ALIGN_TYPE( int * ), - optional_ALIGN_TYPE( long * ), - optional_ALIGN_TYPE( float * ), - optional_ALIGN_TYPE( double * ), - optional_ALIGN_TYPE( long double * ), - - optional_ALIGN_TYPE( Unknown ( * )( Unknown ) ), - optional_ALIGN_TYPE( Unknown * Unknown::* ), - optional_ALIGN_TYPE( Unknown ( Unknown::* )( Unknown ) ), - - nulltype - > > > > > > > > > > > > > > - > > > > > > > > > > > > > > - > > > > > > - alignment_types; - -#undef optional_ALIGN_TYPE - -#endif // optional_CONFIG_MAX_ALIGN_HACK - -/// C++03 constructed union to hold value. - -template< typename T > -union storage_t -{ -//private: -// template< typename > friend class optional; - - typedef T value_type; - - storage_t() optional_is_default - - explicit storage_t( value_type const & v ) - { - construct_value( v ); - } - - void construct_value( value_type const & v ) - { - ::new( value_ptr() ) value_type( v ); - } - -#if optional_CPP11_OR_GREATER - - explicit storage_t( value_type && v ) - { - construct_value( std::move( v ) ); - } - - void construct_value( value_type && v ) - { - ::new( value_ptr() ) value_type( std::move( v ) ); - } - - template< class... Args > - storage_t( nonstd_lite_in_place_t(T), Args&&... args ) - { - emplace( std::forward(args)... ); - } - - template< class... Args > - void emplace( Args&&... args ) - { - ::new( value_ptr() ) value_type( std::forward(args)... ); - } - - template< class U, class... Args > - void emplace( std::initializer_list il, Args&&... args ) - { - ::new( value_ptr() ) value_type( il, std::forward(args)... ); - } - -#endif - - void destruct_value() - { - value_ptr()->~T(); - } - - optional_nodiscard value_type const * value_ptr() const - { - return as(); - } - - value_type * value_ptr() - { - return as(); - } - - optional_nodiscard value_type const & value() const optional_ref_qual - { - return * value_ptr(); - } - - value_type & value() optional_ref_qual - { - return * value_ptr(); - } - -#if optional_HAVE( REF_QUALIFIER ) - - optional_nodiscard value_type const && value() const optional_refref_qual - { - return std::move( value() ); - } - - value_type && value() optional_refref_qual - { - return std::move( value() ); - } - -#endif - -#if optional_CPP11_OR_GREATER - - using aligned_storage_t = typename std::aligned_storage< sizeof(value_type), alignof(value_type) >::type; - aligned_storage_t data; - -#elif optional_CONFIG_MAX_ALIGN_HACK - - typedef struct { unsigned char data[ sizeof(value_type) ]; } aligned_storage_t; - - max_align_t hack; - aligned_storage_t data; - -#else - typedef optional_ALIGN_AS(value_type) align_as_type; - - typedef struct { align_as_type data[ 1 + ( sizeof(value_type) - 1 ) / sizeof(align_as_type) ]; } aligned_storage_t; - aligned_storage_t data; - -# undef optional_ALIGN_AS - -#endif // optional_CONFIG_MAX_ALIGN_HACK - - optional_nodiscard void * ptr() optional_noexcept - { - return &data; - } - - optional_nodiscard void const * ptr() const optional_noexcept - { - return &data; - } - - template - optional_nodiscard U * as() - { - return reinterpret_cast( ptr() ); - } - - template - optional_nodiscard U const * as() const - { - return reinterpret_cast( ptr() ); - } -}; - -} // namespace detail - -/// disengaged state tag - -struct nullopt_t -{ - struct init{}; - explicit optional_constexpr nullopt_t( init /*unused*/ ) optional_noexcept {} -}; - -#if optional_HAVE( CONSTEXPR_11 ) -constexpr nullopt_t nullopt{ nullopt_t::init{} }; -#else -// extra parenthesis to prevent the most vexing parse: -const nullopt_t nullopt(( nullopt_t::init() )); -#endif - -/// optional access error - -#if ! optional_CONFIG_NO_EXCEPTIONS - -class bad_optional_access : public std::logic_error -{ -public: - explicit bad_optional_access() - : logic_error( "bad optional access" ) {} -}; - -#endif //optional_CONFIG_NO_EXCEPTIONS - -/// optional - -template< typename T> -class optional -{ - optional_static_assert(( !std::is_same::type, nullopt_t>::value ), - "T in optional must not be of type 'nullopt_t'.") - - optional_static_assert(( !std::is_same::type, in_place_t>::value ), - "T in optional must not be of type 'in_place_t'.") - - optional_static_assert(( std::is_object::value && std::is_destructible::value && !std::is_array::value ), - "T in optional must meet the Cpp17Destructible requirements.") - -private: - template< typename > friend class optional; - - typedef void (optional::*safe_bool)() const; - -public: - typedef T value_type; - - // x.x.3.1, constructors - - // 1a - default construct - optional_constexpr optional() optional_noexcept - : has_value_( false ) - , contained() - {} - - // 1b - construct explicitly empty - // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions ) - optional_constexpr optional( nullopt_t /*unused*/ ) optional_noexcept - : has_value_( false ) - , contained() - {} - - // 2 - copy-construct -#if optional_CPP11_OR_GREATER - // template< typename U = T - // optional_REQUIRES_T( - // std::is_copy_constructible::value - // || std11::is_trivially_copy_constructible::value - // ) - // > -#endif - optional_constexpr14 optional( optional const & other ) - : has_value_( other.has_value() ) - { - if ( other.has_value() ) - { - contained.construct_value( other.contained.value() ); - } - } - -#if optional_CPP11_OR_GREATER - - // 3 (C++11) - move-construct from optional - template< typename U = T - optional_REQUIRES_T( - std11::is_move_constructible::value - || std11::is_trivially_move_constructible::value - ) - > - optional_constexpr14 optional( optional && other ) - // NOLINTNEXTLINE( performance-noexcept-move-constructor ) - noexcept( std11::is_nothrow_move_constructible::value ) - : has_value_( other.has_value() ) - { - if ( other.has_value() ) - { - contained.construct_value( std::move( other.contained.value() ) ); - } - } - - // 4a (C++11) - explicit converting copy-construct from optional - template< typename U - optional_REQUIRES_T( - std::is_constructible::value - && !std::is_constructible & >::value - && !std::is_constructible && >::value - && !std::is_constructible const & >::value - && !std::is_constructible const && >::value - && !std::is_convertible< optional & , T>::value - && !std::is_convertible< optional && , T>::value - && !std::is_convertible< optional const & , T>::value - && !std::is_convertible< optional const &&, T>::value - && !std::is_convertible< U const & , T>::value /*=> explicit */ - ) - > - explicit optional( optional const & other ) - : has_value_( other.has_value() ) - { - if ( other.has_value() ) - { - contained.construct_value( T{ other.contained.value() } ); - } - } -#endif // optional_CPP11_OR_GREATER - - // 4b (C++98 and later) - non-explicit converting copy-construct from optional - template< typename U -#if optional_CPP11_OR_GREATER - optional_REQUIRES_T( - std::is_constructible::value - && !std::is_constructible & >::value - && !std::is_constructible && >::value - && !std::is_constructible const & >::value - && !std::is_constructible const && >::value - && !std::is_convertible< optional & , T>::value - && !std::is_convertible< optional && , T>::value - && !std::is_convertible< optional const & , T>::value - && !std::is_convertible< optional const &&, T>::value - && std::is_convertible< U const & , T>::value /*=> non-explicit */ - ) -#endif // optional_CPP11_OR_GREATER - > - // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions ) - /*non-explicit*/ optional( optional const & other ) - : has_value_( other.has_value() ) - { - if ( other.has_value() ) - { - contained.construct_value( other.contained.value() ); - } - } - -#if optional_CPP11_OR_GREATER - - // 5a (C++11) - explicit converting move-construct from optional - template< typename U - optional_REQUIRES_T( - std::is_constructible::value - && !std::is_constructible & >::value - && !std::is_constructible && >::value - && !std::is_constructible const & >::value - && !std::is_constructible const && >::value - && !std::is_convertible< optional & , T>::value - && !std::is_convertible< optional && , T>::value - && !std::is_convertible< optional const & , T>::value - && !std::is_convertible< optional const &&, T>::value - && !std::is_convertible< U &&, T>::value /*=> explicit */ - ) - > - explicit optional( optional && other - ) - : has_value_( other.has_value() ) - { - if ( other.has_value() ) - { - contained.construct_value( T{ std::move( other.contained.value() ) } ); - } - } - - // 5a (C++11) - non-explicit converting move-construct from optional - template< typename U - optional_REQUIRES_T( - std::is_constructible::value - && !std::is_constructible & >::value - && !std::is_constructible && >::value - && !std::is_constructible const & >::value - && !std::is_constructible const && >::value - && !std::is_convertible< optional & , T>::value - && !std::is_convertible< optional && , T>::value - && !std::is_convertible< optional const & , T>::value - && !std::is_convertible< optional const &&, T>::value - && std::is_convertible< U &&, T>::value /*=> non-explicit */ - ) - > - // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions ) - /*non-explicit*/ optional( optional && other ) - : has_value_( other.has_value() ) - { - if ( other.has_value() ) - { - contained.construct_value( std::move( other.contained.value() ) ); - } - } - - // 6 (C++11) - in-place construct - template< typename... Args - optional_REQUIRES_T( - std::is_constructible::value - ) - > - optional_constexpr explicit optional( nonstd_lite_in_place_t(T), Args&&... args ) - : has_value_( true ) - , contained( in_place, std::forward(args)... ) - {} - - // 7 (C++11) - in-place construct, initializer-list - template< typename U, typename... Args - optional_REQUIRES_T( - std::is_constructible&, Args&&...>::value - ) - > - optional_constexpr explicit optional( nonstd_lite_in_place_t(T), std::initializer_list il, Args&&... args ) - : has_value_( true ) - , contained( T( il, std::forward(args)...) ) - {} - - // 8a (C++11) - explicit move construct from value - template< typename U = T - optional_REQUIRES_T( - std::is_constructible::value - && !std::is_same::type, nonstd_lite_in_place_t(U)>::value - && !std::is_same::type, optional>::value - && !std::is_convertible::value /*=> explicit */ - ) - > - optional_constexpr explicit optional( U && value ) - : has_value_( true ) - , contained( nonstd_lite_in_place(T), std::forward( value ) ) - {} - - // 8b (C++11) - non-explicit move construct from value - template< typename U = T - optional_REQUIRES_T( - std::is_constructible::value - && !std::is_same::type, nonstd_lite_in_place_t(U)>::value - && !std::is_same::type, optional>::value - && std::is_convertible::value /*=> non-explicit */ - ) - > - // NOLINTNEXTLINE( google-explicit-constructor, hicpp-explicit-conversions ) - optional_constexpr /*non-explicit*/ optional( U && value ) - : has_value_( true ) - , contained( nonstd_lite_in_place(T), std::forward( value ) ) - {} - -#else // optional_CPP11_OR_GREATER - - // 8 (C++98) - optional( value_type const & value ) - : has_value_( true ) - , contained( value ) - {} - -#endif // optional_CPP11_OR_GREATER - - // x.x.3.2, destructor - - ~optional() - { - if ( has_value() ) - { - contained.destruct_value(); - } - } - - // x.x.3.3, assignment - - // 1 (C++98and later) - assign explicitly empty - optional & operator=( nullopt_t /*unused*/) optional_noexcept - { - reset(); - return *this; - } - - // 2 (C++98and later) - copy-assign from optional -#if optional_CPP11_OR_GREATER - // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator ) - optional_REQUIRES_R( - optional &, - true -// std::is_copy_constructible::value -// && std::is_copy_assignable::value - ) - operator=( optional const & other ) - noexcept( - std11::is_nothrow_move_assignable::value - && std11::is_nothrow_move_constructible::value - ) -#else - optional & operator=( optional const & other ) -#endif - { - if ( (has_value() == true ) && (other.has_value() == false) ) { reset(); } - else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( *other ); } - else if ( (has_value() == true ) && (other.has_value() == true ) ) { contained.value() = *other; } - return *this; - } - -#if optional_CPP11_OR_GREATER - - // 3 (C++11) - move-assign from optional - // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator ) - optional_REQUIRES_R( - optional &, - true -// std11::is_move_constructible::value -// && std::is_move_assignable::value - ) - operator=( optional && other ) noexcept - { - if ( (has_value() == true ) && (other.has_value() == false) ) { reset(); } - else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( std::move( *other ) ); } - else if ( (has_value() == true ) && (other.has_value() == true ) ) { contained.value() = std::move( *other ); } - return *this; - } - - // 4 (C++11) - move-assign from value - template< typename U = T > - // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator ) - optional_REQUIRES_R( - optional &, - std::is_constructible::value - && std11::is_assignable::value - && !std::is_same::type, nonstd_lite_in_place_t(U)>::value - && !std::is_same::type, optional>::value - && !(std::is_scalar::value && std::is_same::type>::value) - ) - operator=( U && value ) - { - if ( has_value() ) - { - contained.value() = std::forward( value ); - } - else - { - initialize( T( std::forward( value ) ) ); - } - return *this; - } - -#else // optional_CPP11_OR_GREATER - - // 4 (C++98) - copy-assign from value - template< typename U /*= T*/ > - optional & operator=( U const & value ) - { - if ( has_value() ) contained.value() = value; - else initialize( T( value ) ); - return *this; - } - -#endif // optional_CPP11_OR_GREATER - - // 5 (C++98 and later) - converting copy-assign from optional - template< typename U > -#if optional_CPP11_OR_GREATER - // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator ) - optional_REQUIRES_R( - optional&, - std::is_constructible< T , U const &>::value - && std11::is_assignable< T&, U const &>::value - && !std::is_constructible & >::value - && !std::is_constructible && >::value - && !std::is_constructible const & >::value - && !std::is_constructible const && >::value - && !std::is_convertible< optional & , T>::value - && !std::is_convertible< optional && , T>::value - && !std::is_convertible< optional const & , T>::value - && !std::is_convertible< optional const &&, T>::value - && !std11::is_assignable< T&, optional & >::value - && !std11::is_assignable< T&, optional && >::value - && !std11::is_assignable< T&, optional const & >::value - && !std11::is_assignable< T&, optional const && >::value - ) -#else - optional& -#endif // optional_CPP11_OR_GREATER - operator=( optional const & other ) - { - return *this = optional( other ); - } - -#if optional_CPP11_OR_GREATER - - // 6 (C++11) - converting move-assign from optional - template< typename U > - // NOLINTNEXTLINE( cppcoreguidelines-c-copy-assignment-signature, misc-unconventional-assign-operator ) - optional_REQUIRES_R( - optional&, - std::is_constructible< T , U>::value - && std11::is_assignable< T&, U>::value - && !std::is_constructible & >::value - && !std::is_constructible && >::value - && !std::is_constructible const & >::value - && !std::is_constructible const && >::value - && !std::is_convertible< optional & , T>::value - && !std::is_convertible< optional && , T>::value - && !std::is_convertible< optional const & , T>::value - && !std::is_convertible< optional const &&, T>::value - && !std11::is_assignable< T&, optional & >::value - && !std11::is_assignable< T&, optional && >::value - && !std11::is_assignable< T&, optional const & >::value - && !std11::is_assignable< T&, optional const && >::value - ) - operator=( optional && other ) - { - return *this = optional( std::move( other ) ); - } - - // 7 (C++11) - emplace - template< typename... Args - optional_REQUIRES_T( - std::is_constructible::value - ) - > - T& emplace( Args&&... args ) - { - *this = nullopt; - contained.emplace( std::forward(args)... ); - has_value_ = true; - return contained.value(); - } - - // 8 (C++11) - emplace, initializer-list - template< typename U, typename... Args - optional_REQUIRES_T( - std::is_constructible&, Args&&...>::value - ) - > - T& emplace( std::initializer_list il, Args&&... args ) - { - *this = nullopt; - contained.emplace( il, std::forward(args)... ); - has_value_ = true; - return contained.value(); - } - -#endif // optional_CPP11_OR_GREATER - - // x.x.3.4, swap - - void swap( optional & other ) -#if optional_CPP11_OR_GREATER - noexcept( - std11::is_nothrow_move_constructible::value - && std17::is_nothrow_swappable::value - ) -#endif - { - using std::swap; - if ( (has_value() == true ) && (other.has_value() == true ) ) { swap( **this, *other ); } - else if ( (has_value() == false) && (other.has_value() == true ) ) { initialize( std11::move(*other) ); other.reset(); } - else if ( (has_value() == true ) && (other.has_value() == false) ) { other.initialize( std11::move(**this) ); reset(); } - } - - // x.x.3.5, observers - - optional_constexpr value_type const * operator ->() const - { - return assert( has_value() ), - contained.value_ptr(); - } - - optional_constexpr14 value_type * operator ->() - { - return assert( has_value() ), - contained.value_ptr(); - } - - optional_constexpr value_type const & operator *() const optional_ref_qual - { - return assert( has_value() ), - contained.value(); - } - - optional_constexpr14 value_type & operator *() optional_ref_qual - { - return assert( has_value() ), - contained.value(); - } - -#if optional_HAVE( REF_QUALIFIER ) - - optional_constexpr value_type const && operator *() const optional_refref_qual - { - return std::move( **this ); - } - - optional_constexpr14 value_type && operator *() optional_refref_qual - { - return std::move( **this ); - } - -#endif - -#if optional_CPP11_OR_GREATER - optional_constexpr explicit operator bool() const optional_noexcept - { - return has_value(); - } -#else - optional_constexpr operator safe_bool() const optional_noexcept - { - return has_value() ? &optional::this_type_does_not_support_comparisons : 0; - } -#endif - - // NOLINTNEXTLINE( modernize-use-nodiscard ) - /*optional_nodiscard*/ optional_constexpr bool has_value() const optional_noexcept - { - return has_value_; - } - - // NOLINTNEXTLINE( modernize-use-nodiscard ) - /*optional_nodiscard*/ optional_constexpr14 value_type const & value() const optional_ref_qual - { -#if optional_CONFIG_NO_EXCEPTIONS - assert( has_value() ); -#else - if ( ! has_value() ) - { - throw bad_optional_access(); - } -#endif - return contained.value(); - } - - optional_constexpr14 value_type & value() optional_ref_qual - { -#if optional_CONFIG_NO_EXCEPTIONS - assert( has_value() ); -#else - if ( ! has_value() ) - { - throw bad_optional_access(); - } -#endif - return contained.value(); - } - -#if optional_HAVE( REF_QUALIFIER ) && ( !optional_COMPILER_GNUC_VERSION || optional_COMPILER_GNUC_VERSION >= 490 ) - - // NOLINTNEXTLINE( modernize-use-nodiscard ) - /*optional_nodiscard*/ optional_constexpr value_type const && value() const optional_refref_qual - { - return std::move( value() ); - } - - optional_constexpr14 value_type && value() optional_refref_qual - { - return std::move( value() ); - } - -#endif - -#if optional_HAVE( REF_QUALIFIER ) - - template< typename U > - optional_constexpr value_type value_or( U && v ) const optional_ref_qual - { - return has_value() ? contained.value() : static_cast(std::forward( v ) ); - } - - template< typename U > - optional_constexpr14 value_type value_or( U && v ) optional_refref_qual - { -#if optional_COMPILER_CLANG_VERSION - return has_value() ? /*std::move*/( contained.value() ) : static_cast(std::forward( v ) ); -#else - return has_value() ? std::move( contained.value() ) : static_cast(std::forward( v ) ); -#endif - } - -#else - - template< typename U > - optional_constexpr value_type value_or( U const & v ) const - { - return has_value() ? contained.value() : static_cast( v ); - } - -#endif // optional_CPP11_OR_GREATER - - // x.x.3.6, modifiers - - void reset() optional_noexcept - { - if ( has_value() ) - { - contained.destruct_value(); - } - - has_value_ = false; - } - -private: - void this_type_does_not_support_comparisons() const {} - - template< typename V > - void initialize( V const & value ) - { - assert( ! has_value() ); - contained.construct_value( value ); - has_value_ = true; - } - -#if optional_CPP11_OR_GREATER - template< typename V > - void initialize( V && value ) - { - assert( ! has_value() ); - contained.construct_value( std::move( value ) ); - has_value_ = true; - } - -#endif - -private: - bool has_value_; - detail::storage_t< value_type > contained; - -}; - -// Relational operators - -template< typename T, typename U > -inline optional_constexpr bool operator==( optional const & x, optional const & y ) -{ - return bool(x) != bool(y) ? false : !bool( x ) ? true : *x == *y; -} - -template< typename T, typename U > -inline optional_constexpr bool operator!=( optional const & x, optional const & y ) -{ - return !(x == y); -} - -template< typename T, typename U > -inline optional_constexpr bool operator<( optional const & x, optional const & y ) -{ - return (!y) ? false : (!x) ? true : *x < *y; -} - -template< typename T, typename U > -inline optional_constexpr bool operator>( optional const & x, optional const & y ) -{ - return (y < x); -} - -template< typename T, typename U > -inline optional_constexpr bool operator<=( optional const & x, optional const & y ) -{ - return !(y < x); -} - -template< typename T, typename U > -inline optional_constexpr bool operator>=( optional const & x, optional const & y ) -{ - return !(x < y); -} - -// Comparison with nullopt - -template< typename T > -inline optional_constexpr bool operator==( optional const & x, nullopt_t /*unused*/ ) optional_noexcept -{ - return (!x); -} - -template< typename T > -inline optional_constexpr bool operator==( nullopt_t /*unused*/, optional const & x ) optional_noexcept -{ - return (!x); -} - -template< typename T > -inline optional_constexpr bool operator!=( optional const & x, nullopt_t /*unused*/ ) optional_noexcept -{ - return bool(x); -} - -template< typename T > -inline optional_constexpr bool operator!=( nullopt_t /*unused*/, optional const & x ) optional_noexcept -{ - return bool(x); -} - -template< typename T > -inline optional_constexpr bool operator<( optional const & /*unused*/, nullopt_t /*unused*/ ) optional_noexcept -{ - return false; -} - -template< typename T > -inline optional_constexpr bool operator<( nullopt_t /*unused*/, optional const & x ) optional_noexcept -{ - return bool(x); -} - -template< typename T > -inline optional_constexpr bool operator<=( optional const & x, nullopt_t /*unused*/ ) optional_noexcept -{ - return (!x); -} - -template< typename T > -inline optional_constexpr bool operator<=( nullopt_t /*unused*/, optional const & /*unused*/ ) optional_noexcept -{ - return true; -} - -template< typename T > -inline optional_constexpr bool operator>( optional const & x, nullopt_t /*unused*/ ) optional_noexcept -{ - return bool(x); -} - -template< typename T > -inline optional_constexpr bool operator>( nullopt_t /*unused*/, optional const & /*unused*/ ) optional_noexcept -{ - return false; -} - -template< typename T > -inline optional_constexpr bool operator>=( optional const & /*unused*/, nullopt_t /*unused*/ ) optional_noexcept -{ - return true; -} - -template< typename T > -inline optional_constexpr bool operator>=( nullopt_t /*unused*/, optional const & x ) optional_noexcept -{ - return (!x); -} - -// Comparison with T - -template< typename T, typename U > -inline optional_constexpr bool operator==( optional const & x, U const & v ) -{ - return bool(x) ? *x == v : false; -} - -template< typename T, typename U > -inline optional_constexpr bool operator==( U const & v, optional const & x ) -{ - return bool(x) ? v == *x : false; -} - -template< typename T, typename U > -inline optional_constexpr bool operator!=( optional const & x, U const & v ) -{ - return bool(x) ? *x != v : true; -} - -template< typename T, typename U > -inline optional_constexpr bool operator!=( U const & v, optional const & x ) -{ - return bool(x) ? v != *x : true; -} - -template< typename T, typename U > -inline optional_constexpr bool operator<( optional const & x, U const & v ) -{ - return bool(x) ? *x < v : true; -} - -template< typename T, typename U > -inline optional_constexpr bool operator<( U const & v, optional const & x ) -{ - return bool(x) ? v < *x : false; -} - -template< typename T, typename U > -inline optional_constexpr bool operator<=( optional const & x, U const & v ) -{ - return bool(x) ? *x <= v : true; -} - -template< typename T, typename U > -inline optional_constexpr bool operator<=( U const & v, optional const & x ) -{ - return bool(x) ? v <= *x : false; -} - -template< typename T, typename U > -inline optional_constexpr bool operator>( optional const & x, U const & v ) -{ - return bool(x) ? *x > v : false; -} - -template< typename T, typename U > -inline optional_constexpr bool operator>( U const & v, optional const & x ) -{ - return bool(x) ? v > *x : true; -} - -template< typename T, typename U > -inline optional_constexpr bool operator>=( optional const & x, U const & v ) -{ - return bool(x) ? *x >= v : false; -} - -template< typename T, typename U > -inline optional_constexpr bool operator>=( U const & v, optional const & x ) -{ - return bool(x) ? v >= *x : true; -} - -// Specialized algorithms - -template< typename T -#if optional_CPP11_OR_GREATER - optional_REQUIRES_T( - std11::is_move_constructible::value - && std17::is_swappable::value ) -#endif -> -void swap( optional & x, optional & y ) -#if optional_CPP11_OR_GREATER - noexcept( noexcept( x.swap(y) ) ) -#endif -{ - x.swap( y ); -} - -#if optional_CPP11_OR_GREATER - -template< typename T > -optional_constexpr optional< typename std::decay::type > make_optional( T && value ) -{ - return optional< typename std::decay::type >( std::forward( value ) ); -} - -template< typename T, typename...Args > -optional_constexpr optional make_optional( Args&&... args ) -{ - return optional( nonstd_lite_in_place(T), std::forward(args)...); -} - -template< typename T, typename U, typename... Args > -optional_constexpr optional make_optional( std::initializer_list il, Args&&... args ) -{ - return optional( nonstd_lite_in_place(T), il, std::forward(args)...); -} - -#else - -template< typename T > -optional make_optional( T const & value ) -{ - return optional( value ); -} - -#endif // optional_CPP11_OR_GREATER - -} // namespace optional_lite - -using optional_lite::optional; -using optional_lite::nullopt_t; -using optional_lite::nullopt; - -#if ! optional_CONFIG_NO_EXCEPTIONS -using optional_lite::bad_optional_access; -#endif - -using optional_lite::make_optional; - -} // namespace nonstd - -#if optional_CPP11_OR_GREATER - -// specialize the std::hash algorithm: - -namespace std { - -template< class T > -struct hash< nonstd::optional > -{ -public: - std::size_t operator()( nonstd::optional const & v ) const optional_noexcept - { - return bool( v ) ? std::hash{}( *v ) : 0; - } -}; - -} //namespace std - -#endif // optional_CPP11_OR_GREATER - -#if defined(__clang__) -# pragma clang diagnostic pop -#elif defined(__GNUC__) -# pragma GCC diagnostic pop -#elif defined(_MSC_VER ) -# pragma warning( pop ) -#endif - -#endif // optional_USES_STD_OPTIONAL - -#endif // NONSTD_OPTIONAL_LITE_HPP diff --git a/include/simpleengine/renderable.h b/include/simpleengine/renderable.h index a093a58..297e81f 100644 --- a/include/simpleengine/renderable.h +++ b/include/simpleengine/renderable.h @@ -9,9 +9,11 @@ namespace simpleengine { class Renderable : public simpleengine::Event { private: - using super = simpleengine::Event; + using Super = simpleengine::Event; public: - explicit Renderable(GLFWwindow* window = nullptr) : super(window) {} + Renderable() = default; virtual ~Renderable() = default; + + virtual void render(GLFWwindow* target) = 0; }; } \ No newline at end of file diff --git a/include/simpleengine/scene.h b/include/simpleengine/scene.h new file mode 100644 index 0000000..80931a4 --- /dev/null +++ b/include/simpleengine/scene.h @@ -0,0 +1,44 @@ +#pragma once + +#include "gfx/model.h" +#include "entity.h" +#include "event/event.h" +#include "renderable.h" + +#include + +#include +#include + +namespace simpleengine { + class Scene : public simpleengine::Event { + public: + /** + * @brief A list of entities in this scene. + * + */ + std::vector> entities; + + /** + * @brief Models that don't belong to an entity. + * + */ + std::vector> stray_models; + + Scene() = default; + + void add_entity(std::shared_ptr entity) { + entities.push_back(entity); + } + + void add_stray_model(std::shared_ptr stray) { + stray_models.push_back(stray); + } + + virtual void update(const float& delta_time) override { + for (auto& entity : entities) { + entity->update(delta_time); + } + } + }; +} \ No newline at end of file diff --git a/src/camera.cpp b/src/camera.cpp index 88399a3..6ee76b7 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -5,7 +5,7 @@ namespace simpleengine { Camera::Camera(GLFWwindow* window, gfx::Shader shader, float fov, glm::vec3 position, glm::vec3 rotation, - float near_plane, float far_plane, glm::vec3 world_up, glm::vec3 cam_front) : simpleengine::Event(window), shader(shader), + float near_plane, float far_plane, glm::vec3 world_up, glm::vec3 cam_front) : window(window), shader(shader), projection_matrix(1.f), view_matrix(1.f), fov(fov), position(position), rotation(rotation), near_plane(near_plane), far_plane(far_plane) { // TODO: Update width and height on window resize. @@ -100,8 +100,4 @@ namespace simpleengine { shader.set_uniform_matrix_4f("projection_matrix", projection_matrix, false); shader.unuse(); } - - void Camera::render(GLFWwindow* target) { - - } } \ No newline at end of file diff --git a/src/game.cpp b/src/game.cpp index 29d94e0..783a7d8 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -94,7 +94,7 @@ void simpleengine::Game::render_window(const float& delta_time) { void simpleengine::Game::render_items(const float& delta_time) { for (const std::shared_ptr& event : events) { - event->render(window); + //event->render(window); } } diff --git a/src/gfx/model.cpp b/src/gfx/model.cpp index 4ceecfa..f1c56f4 100644 --- a/src/gfx/model.cpp +++ b/src/gfx/model.cpp @@ -1,60 +1,15 @@ #include "gfx/model.h" namespace simpleengine::gfx { - Model::Model(GLFWwindow* window, gfx::Shader shader, std::vector vertices, std::vector indicies) : - simpleengine::Renderable(window), shader(shader), vertices(vertices), indicies(indicies), vbo(gfx::VBO::init(GL_ARRAY_BUFFER, false)), - ebo(gfx::VBO::init(GL_ELEMENT_ARRAY_BUFFER, false)), vao(gfx::VAO::init()) { + Model::Model(std::vector vertices, std::vector indicies, std::optional material) : + material(material), vertices(vertices), indicies(indicies) { - //setup_vertices(); - } - - Model::Model(GLFWwindow* window, GLuint shader_program, std::vector vertices, std::vector indicies) : - Model(window, gfx::Shader(shader_program), vertices, indicies) { - - } - - void Model::setup_vertices() { - vao.bind(); - vbo.buffer(vertices.data(), 0, sizeof(LitVertex) * vertices.size()); - if (!indicies.empty()) { - ebo.buffer(indicies.data(), 0, indicies.size() * sizeof(GLuint)); - } - - // Enable VAO attributes - vao.enable_attrib(vbo, 0, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, position)); - vao.enable_attrib(vbo, 1, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, color)); - vao.enable_attrib(vbo, 2, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, normal)); - // Attribute 2 is used for normals - vao.enable_attrib(vbo, 3, 2, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, tex_coord)); - vao.enable_attrib(vbo, 4, 1, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, texture_id)); - - /* vao.disable_attrib(vbo, 2); - vao.disable_attrib(vbo, 4); - vao.set_attrib_value(vbo, 4, -1.f); */ - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); } void Model::update(const float& delta_time) { this->rotate_y(1.f); } - void Model::render(GLFWwindow* target) { - shader.use(); - shader.set_uniform_matrix_4f("transform_matrix", transform_matrix, false); - - // When binding to the texture, also tell the shader if the texture is set or not. - //shader.set_uniform_int("texture_is_set", (GLint) false, false); - - vao.bind(); - if (indicies.empty()) { - glDrawArrays(GL_TRIANGLES, 0, vertices.size()); - } else { - glDrawElements(GL_TRIANGLES, indicies.size(), GL_UNSIGNED_INT, 0); - } - } - glm::vec3 Model::compute_face_normal(const glm::vec3& p1, const glm::vec3& p2, const glm::vec3& p3) { // Uses p2 as a new origin for p1,p3 auto a = p3 - p2; diff --git a/src/gfx/textured_model.cpp b/src/gfx/textured_model.cpp deleted file mode 100644 index 3945a36..0000000 --- a/src/gfx/textured_model.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "gfx/textured_model.h" -#include "gfx/ssbo.h" - -namespace simpleengine::gfx { - TexturedModel::TexturedModel(GLFWwindow* window, gfx::Shader shader, gfx::Texture texture, std::vector vertices, - std::vector indicies) : simpleengine::gfx::Model(window, shader, vertices, indicies), - textures(std::vector{texture}) { - } - - TexturedModel::TexturedModel(GLFWwindow* window, GLuint shader_program, gfx::Texture texture, - std::vector vertices, std::vector indicies) : TexturedModel(window, gfx::Shader(shader_program), - std::vector{texture}, vertices, indicies) { - - } - - TexturedModel::TexturedModel(GLFWwindow* window, gfx::Shader shader, std::vector textures, std::vector vertices, - std::vector indicies) : simpleengine::gfx::Model(window, shader, vertices, indicies), - textures(textures) { - } - - TexturedModel::TexturedModel(GLFWwindow* window, GLuint shader_program, std::vector textures, - std::vector vertices, std::vector indicies) : TexturedModel(window, gfx::Shader(shader_program), - textures, vertices, indicies) { - - } - - void TexturedModel::update(const float& delta_time) { - - } - - void TexturedModel::render(GLFWwindow* target) { - shader.use(); - shader.set_uniform_matrix_4f("transform_matrix", transform_matrix, false); - - const int tex_id = 0; - - // On a batch renderer, you would set an array. - shader.set_uniform_int("u_textures", tex_id, false); - shader.set_uniform_float("u_texture_shine", 1.f, false); - shader.set_uniform_float("u_texture_reflectivity", 0.f, false); - - /* int samples[2] = { 0, 1 }; - float shine[2] = { 1.f, 1.f}; - float reflectivity[2] = { 0.f, 0.f}; - - shader.set_uniform_int_array("u_textures", 2, samples, false); - shader.set_uniform_float_array("u_texture_shine", 2, shine, false); - shader.set_uniform_float_array("u_texture_reflectivity", 2, reflectivity, false); */ - - glActiveTexture(GL_TEXTURE0 + tex_id); - glBindTextureUnit(tex_id, textures.front().get_texture_id()); - const auto& texture = textures.front(); - texture.bind(); - - vao.bind(); - if (indicies.empty()) { - glDrawArrays(GL_TRIANGLES, 0, vertices.size()); - } else { - glDrawElements(GL_TRIANGLES, indicies.size(), GL_UNSIGNED_INT, 0); - } - } -} \ No newline at end of file diff --git a/src/objects/3d/mesh.cpp b/src/objects/3d/mesh.cpp deleted file mode 100644 index f4037e0..0000000 --- a/src/objects/3d/mesh.cpp +++ /dev/null @@ -1,126 +0,0 @@ -#include "objects/3d/mesh.h" - -namespace simpleengine::objects_3d { - std::vector Mesh::split_string(std::string str, const char delim) { - std::istringstream ss(str); - - std::vector tokens; - size_t pos = 0; - std::string token; - while ((pos = str.find(delim)) != std::string::npos) { - token = str.substr(0, pos); - tokens.push_back(token); - str.erase(0, pos + 1); - } - tokens.push_back(str); - - return tokens; - } - - void Mesh::process_vertex(const std::vector& vertex_data, const std::vector& in_textures, - const std::vector& in_normals, std::vector& out_indicies, - std::vector& out_textures, std::vector& out_normals) { - - // Get the index the current vertex and put it in indicies - int currentVertexIndex = stoi(vertex_data[0]) - 1; - out_indicies.push_back(currentVertexIndex); - - // Read texture coords - glm::vec2 current_tex = in_textures.at(stoi(vertex_data[1]) - 1); - current_tex.y = 1 - current_tex.y; - out_textures.at(currentVertexIndex) = current_tex; - - // Read normals - glm::vec3 current_norm = in_normals.at(stoi(vertex_data[2]) - 1); - out_normals.at(currentVertexIndex) = current_norm; - } - - Mesh::Mesh(GLFWwindow *window, gfx::Shader shader, gfx::Texture texture, std::string filename) : - Mesh(window, shader, texture, std::ifstream(filename, std::ios::in | std::ios::binary)) { - - } - - Mesh::Mesh(GLFWwindow *window, gfx::Shader shader, gfx::Texture texture, std::ifstream file_stream) : - simpleengine::gfx::TexturedModel(window, shader, std::vector{texture}, std::vector()) { - - if (!file_stream.is_open()) { - std::cerr << "File stream that was given to ObjModel::ObjModel is not open!" << std::endl; - throw std::runtime_error("Failed to open ObjModel model file"); - } - - // The vertices, texture coords, and normals that were read from the obj file - // these are not in a particular order. - std::vector obj_vertices; - std::vector obj_textures; - std::vector obj_normals; - - // The texture coords and normals that have been sorted. - std::vector textures; - std::vector normals; - - // Read the vertices, texture coords, and normals. Break when run into indices - std::string line; - while (std::getline(file_stream, line)) { - std::vector line_tokens = split_string(line, ' '); - - if (line_tokens.front() == "v") { - //glm::vec3 vertex(stof(line_tokens[1]), stof(line_tokens[2]), stof(line_tokens[3])); - obj_vertices.emplace_back(stof(line_tokens[1]), stof(line_tokens[2]), stof(line_tokens[3])); - } else if (line_tokens.front() == "vt") { - obj_textures.emplace_back(stof(line_tokens[1]), stof(line_tokens[2])); - } else if (line_tokens.front() == "vn") { - obj_normals.emplace_back(stof(line_tokens[1]), stof(line_tokens[2]), stof(line_tokens[3])); - } else if (line_tokens.front() == "f") { - auto size = obj_vertices.size(); - textures.resize(size); - normals.resize(size); - break; - } - } - - // Process the indicies. This will sort everything for storing inside of the Vertex list. - do { - if (!line.starts_with("f")) { - continue; - } - std::vector line_tokens = split_string(line, ' '); - std::vector vertex1 = split_string(line_tokens[1], '/'); - std::vector vertex2 = split_string(line_tokens[2], '/'); - std::vector vertex3 = split_string(line_tokens[3], '/'); - - process_vertex(vertex1, obj_textures, obj_normals, indicies, textures, normals); - process_vertex(vertex2, obj_textures, obj_normals, indicies, textures, normals); - process_vertex(vertex3, obj_textures, obj_normals, indicies, textures, normals); - } while (std::getline(file_stream, line)); - - file_stream.close(); - - const int texture_id = 0; - - std::cout << "Texture ID: " << texture_id << std::endl; - - // Insert everything into lit_vertices. - for (int i = 0; i < obj_vertices.size(); i++) { - lit_vertices.emplace_back(simpleengine::Vectorf(obj_vertices.at(i)), glm::vec3(1.f), textures.at(i), normals.at(i), texture_id); - } - - // Create VAO and EBO and assign buffers - vao.bind(); - vbo.buffer(lit_vertices.data(), 0, sizeof(LitVertex) * lit_vertices.size()); - ebo.buffer(indicies.data(), 0, indicies.size() * sizeof(GLuint)); - - // Enable VAO attributes - vao.enable_attrib(vbo, 0, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, position)); - vao.enable_attrib(vbo, 1, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, color)); - vao.enable_attrib(vbo, 2, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, normal)); - vao.enable_attrib(vbo, 3, 2, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, tex_coord)); - vao.enable_attrib(vbo, 4, 1, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, texture_id)); - - glBindBuffer(GL_ARRAY_BUFFER, 0); - glBindVertexArray(0); - } - - void Mesh::update(const float& delta_time) { - this->rotate_y(0.0005f); // Slowly rotate (for debugging) - } -} \ No newline at end of file