From aafbe087547c69590df61be14bc36e46d186a008 Mon Sep 17 00:00:00 2001 From: Joseph Walton-Rivers <joseph@walton-rivers.uk> Date: Mon, 18 Apr 2022 14:45:56 +0100 Subject: [PATCH] start work on porting model rendering over to the new API --- fggl/gfx/ogl4/models.cpp | 104 ++++++++++++++++++++++++++++ include/fggl/ecs3/prototype/world.h | 8 +-- include/fggl/gfx/ogl/types.hpp | 1 - include/fggl/gfx/ogl4/canvas.hpp | 4 +- include/fggl/gfx/ogl4/models.hpp | 17 ++++- 5 files changed, 126 insertions(+), 8 deletions(-) create mode 100644 fggl/gfx/ogl4/models.cpp diff --git a/fggl/gfx/ogl4/models.cpp b/fggl/gfx/ogl4/models.cpp new file mode 100644 index 0000000..b752d30 --- /dev/null +++ b/fggl/gfx/ogl4/models.cpp @@ -0,0 +1,104 @@ +/* + * ${license.title} + * Copyright (C) 2022 ${license.owner} + * ${license.mailto} + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +// +// Created by webpigeon on 18/04/22. +// + +#include "fggl/gfx/ogl4/models.hpp" +#include "fggl/gfx/camera.hpp" +#include <spdlog/spdlog.h> + +namespace fggl::gfx::ogl4 { + + void StaticModelRenderer::resolveModels(ecs3::World &world) { + // FIXME: this needs something reactive or performance will suck. + auto renderables = world.findMatching<StaticModel>(); + + for (auto& renderable : renderables){ + auto currModel = world.get<StaticModel>( renderable ); + if ( currModel != nullptr ){ + continue; + } + + // no active model, we need to resolve/load one. + } + } + + void StaticModelRenderer::renderModelsForward(const ecs3::World &world) { + + // fetch cameras we will need to render with + auto cameras = world.findMatching<gfx::Camera>(); + + // if there are no cameras, we can't do anything... + if ( cameras.size() == 0) { + spdlog::warn("asked to render static models, but there were no cameras"); + return; + } + + float deltaTime = 0.0f; + + // perform a rendering pass for each camera (will usually only be one...) + for ( auto& cameraEnt : cameras ){ + + //TODO should be cliping this to only visible objects + + // enable required OpenGL state + glEnable( GL_CULL_FACE ); + glCullFace( GL_BACK ); + + // enable depth testing + glEnable( GL_DEPTH_TEST ); + + // set-up camera matrices + auto* const camTransform = world.get<math::Transform>(cameraEnt); + auto* const camComp = world.get<gfx::Camera>(cameraEnt); + + math::mat4 projectionMatrix = glm::perspective(camComp->fov, camComp->aspectRatio, camComp->nearPlane, camComp->farPlane); + math::mat4 viewMatrix = glm::lookAt( camTransform->origin(), camComp->target, camTransform->up() ); + + // TODO lighting needs to not be this... + math::vec3 lightPos{1.0f, 1.0f, 1.0f}; + math::mat4 modelMatrix(1.0f); + + auto renderables = world.findMatching<StaticModel>(); + for ( const auto& entity : renderables ){ + auto* transform = world.get<math::Transform>(entity); + StaticModel* model = world.get<StaticModel>(entity); + + // grouping by shader would mean we only need to send the model matrix... + // TODO clean shader API + auto shader = model->pipeline; + shader->use(); + shader->setUniformMtx(shader->uniform("model"), &modelMatrix, 1); + shader->setUniformMtx(shader->uniform("view"), &viewMatrix, 1); + shader->setUniformMtx(shader->uniform("projection"), &projectionMatrix, 1); + + auto vao = model->vao; + + // TODO support primitive restart/fans/etc... + auto elements = model->elements.get(); + vao->drawElements( *elements, model->drawType, model->elementCount); + } + + } + } + +} diff --git a/include/fggl/ecs3/prototype/world.h b/include/fggl/ecs3/prototype/world.h index 97e2d10..26dba7a 100644 --- a/include/fggl/ecs3/prototype/world.h +++ b/include/fggl/ecs3/prototype/world.h @@ -54,7 +54,7 @@ namespace fggl::ecs3::prototype { } template<typename C> - C *get() { + C *get() const { void *ptr = m_components.at(Component<C>::typeID()); return (C *) ptr; } @@ -71,7 +71,7 @@ namespace fggl::ecs3::prototype { return comps; } - bool hasComponents(std::vector<component_type_t> &Cs) { + bool hasComponents(std::vector<component_type_t> &Cs) const { for (auto c : Cs) { if (m_components.find(c) == m_components.end()) { return false; @@ -145,7 +145,7 @@ namespace fggl::ecs3::prototype { } template<typename... Cs> - std::vector<entity_t> findMatching() { + std::vector<entity_t> findMatching() const { // construct the key std::vector<ecs::component_type_t> key; (key.push_back(Component<Cs>::typeID()), ...); @@ -200,7 +200,7 @@ namespace fggl::ecs3::prototype { } template<typename C> - C *get(entity_t entity_id) { + C *get(entity_t entity_id) const { try { auto &entity = m_entities.at(entity_id); try { diff --git a/include/fggl/gfx/ogl/types.hpp b/include/fggl/gfx/ogl/types.hpp index 45d8cf6..5bc8897 100644 --- a/include/fggl/gfx/ogl/types.hpp +++ b/include/fggl/gfx/ogl/types.hpp @@ -60,7 +60,6 @@ namespace fggl::gfx::ogl { void use(); Location uniform(const std::string_view& name) const; - Location uniform(const std::string& name) const; // primatives void setUniformF(Location name, GLfloat value); diff --git a/include/fggl/gfx/ogl4/canvas.hpp b/include/fggl/gfx/ogl4/canvas.hpp index 8ace79c..6908867 100644 --- a/include/fggl/gfx/ogl4/canvas.hpp +++ b/include/fggl/gfx/ogl4/canvas.hpp @@ -17,8 +17,8 @@ namespace fggl::gfx::ogl4 { private: ogl::VertexArray m_vao; - ogl::Buffer<ogl::BufType::ARRAY> m_vertexList; - ogl::Buffer<ogl::BufType::ELEMENT_ARRAY> m_indexList; + ogl::ArrayBuffer m_vertexList; + ogl::ElementBuffer m_indexList; }; } // namespace fggl::gfx::ogl4 diff --git a/include/fggl/gfx/ogl4/models.hpp b/include/fggl/gfx/ogl4/models.hpp index baabd39..8ae6fa1 100644 --- a/include/fggl/gfx/ogl4/models.hpp +++ b/include/fggl/gfx/ogl4/models.hpp @@ -9,10 +9,23 @@ #include <unordered_map> #include "fggl/gfx/ogl/backend.hpp" +#include "fggl/gfx/ogl/types.hpp" #include "fggl/ecs3/ecs.hpp" namespace fggl::gfx::ogl4 { + struct StaticModel { + constexpr static const char name[] = "StaticModel"; + + std::shared_ptr<ogl::Shader> pipeline; + std::shared_ptr<ogl::VertexArray> vao; + + // element data + std::shared_ptr<ogl::ElementBuffer> elements; + ogl::Primative drawType; + std::size_t elementCount; + }; + class StaticModelRenderer { public: StaticModelRenderer() = default; @@ -40,7 +53,9 @@ namespace fggl::gfx::ogl4 { */ void renderModelsForward(const ecs3::World& world); - std::unordered_map<std::string, std::shared_ptr<gfx::Shader>> m_shaders; + ogl::VertexArray m_vao; + ogl::ArrayBuffer m_vertexList; + ogl::ElementBuffer m_indexList; }; } -- GitLab