Get mesh renderer functional

This commit is contained in:
Bailey Harrison 2022-12-22 11:27:16 +00:00
parent c493ba559b
commit 2a7a9e54b2
8 changed files with 131 additions and 16 deletions

View File

@ -49,6 +49,7 @@ set(INCLUDE_FILES
"include/scene.hpp"
"include/ecs/ecs_system.hpp"
"include/ecs/transform.hpp"
"include/ecs/mesh_renderer.hpp"
"include/util/files.hpp"

View File

@ -24,8 +24,6 @@ namespace engine {
std::map<uint32_t, T> m_components{};
virtual void onUpdate(float ts) = 0;
};
}

View File

@ -4,14 +4,19 @@
#include "resources/material.hpp"
#include "resources/shader.hpp"
#include "resources/texture.hpp"
#include "resources/mesh.hpp"
#include "log.hpp"
#include "scene.hpp"
#include "application.hpp"
#include "window.hpp"
#include "gfx_device.hpp"
#include <glm/mat4x4.hpp>
#include <glm/gtc/quaternion.hpp>
#include <set>
namespace engine::ecs {
@ -26,13 +31,32 @@ namespace engine::ecs {
RendererSystem(Scene* scene)
: EcsSystem<MeshRendererComponent>(scene)
{
updateProjectionMatrix();
}
void onUpdate(float ts) override
void drawMeshes(const std::map<uint32_t, glm::mat4>& worldTransforms)
{
glm::mat4 cameraTransform{1.0f};
// cameraTransform = glm::mat4_cast(m_cameraRot);
// reinterpret_cast<glm::vec3&>(cameraTransform[3]) = m_cameraPos;
glm::mat4 viewMatrix = glm::inverse(cameraTransform);
if (m_scene->app()->window()->getWindowResized()) {
updateProjectionMatrix();
}
std::set<resources::Shader*> uniqueShaders{};
for (const auto& [id, data] : m_components) {
DEBUG("rendering entity {}\tts={}", id, ts);
uniqueShaders.insert(data.material->getShader());
}
for (resources::Shader* shader : uniqueShaders) {
DEBUG("TEST {}", (void*)shader);
m_scene->app()->gfx()->updateUniformBuffer(shader->getPipeline(), &m_projMatrix, sizeof(m_projMatrix), 0);
}
for (const auto& [id, data] : m_components) {
DEBUG("drawing entity {}", id);
DEBUG("material shader addr: {}", (void*)data.material->getShader());
assert(data.material != nullptr);
@ -42,7 +66,7 @@ namespace engine::ecs {
glm::mat4 model;
glm::mat4 view;
} pushConsts{};
pushConsts.model = glm::mat4{1.0f};
pushConsts.model = worldTransforms.at(id);
pushConsts.view = glm::mat4{1.0f};
m_scene->app()->gfx()->draw(
@ -50,9 +74,30 @@ namespace engine::ecs {
data.mesh->getVB(),
data.mesh->getIB(),
data.mesh->getCount(),
&pushConsts, sizeof(pushConsts), nullptr);
&pushConsts, sizeof(pushConsts),
data.material->m_texture->getHandle());
}
}
glm::vec3 m_cameraPos;
glm::quat m_cameraRot;
glm::mat4 m_projMatrix;
private:
void updateProjectionMatrix()
{
constexpr float NEAR = 0.1f;
constexpr float FAR = 1000.0f;
float fovRad = glm::radians(75.0f);
uint32_t viewportWidth, viewportHeight;
m_scene->app()->gfx()->getViewportSize(&viewportWidth, &viewportHeight);
float aspect = (float)viewportWidth / (float)viewportHeight;
float fovY = fovRad / aspect;
m_projMatrix = glm::perspectiveZO(fovY, aspect, NEAR, FAR);
}
};

50
include/ecs/transform.hpp Normal file
View File

@ -0,0 +1,50 @@
#pragma once
#include "ecs_system.hpp"
#include <glm/vec3.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/mat4x4.hpp>
namespace engine::ecs {
struct TransformComponent {
uint32_t parent;
glm::vec3 scale;
glm::vec3 position;
glm::quat rotation;
};
class TransformSystem : public EcsSystem<TransformComponent> {
public:
TransformSystem(Scene* scene)
: EcsSystem<TransformComponent>(scene)
{
}
std::unique_ptr<std::map<uint32_t, glm::mat4>> getMatrices()
{
auto transforms = std::make_unique<std::map<uint32_t, glm::mat4>>();
for (const auto& [id, data] : m_components) {
glm::mat4 transform;
// rotation
transform = glm::mat4_cast(data.rotation);
// position
reinterpret_cast<glm::vec3&>(transform[3]) = data.position;
// scale (effectively applied first)
transform = glm::scale(transform, data.scale);
if (data.parent != 0) {
transform = transforms->at(data.parent) * transform;
}
transforms->emplace(id, transform);
}
return transforms;
}
};
}

View File

@ -5,6 +5,7 @@
namespace engine::resources {
class Shader;
class Texture;
class Material {
@ -14,7 +15,9 @@ namespace engine::resources {
Material(const Material&) = delete;
Material& operator=(const Material&) = delete;
Shader* getShader() { return m_shader.get(); }
auto getShader() { return m_shader.get(); }
std::shared_ptr<Texture> m_texture;
private:
const std::shared_ptr<Shader> m_shader;

View File

@ -9,6 +9,7 @@ namespace engine {
class Application;
namespace ecs {
class TransformSystem;
class RendererSystem;
}
@ -27,6 +28,7 @@ namespace engine {
return m_nextEntityID++;
}
std::unique_ptr<ecs::TransformSystem> m_transformSystem;
std::unique_ptr<ecs::RendererSystem> m_renderSystem;
Application* app() { return m_app; }

View File

@ -1,5 +1,6 @@
#include "scene.hpp"
#include "ecs/transform.hpp"
#include "ecs/mesh_renderer.hpp"
namespace engine {
@ -8,13 +9,16 @@ namespace engine {
: m_app(app)
{
m_renderSystem = std::make_unique<ecs::RendererSystem>(this);
m_transformSystem = std::make_unique<ecs::TransformSystem>(this);
}
Scene::~Scene() {}
void Scene::update(float ts)
{
m_renderSystem->onUpdate(ts);
auto transforms = m_transformSystem->getMatrices();
m_renderSystem->drawMeshes(*transforms);
}
}

View File

@ -8,6 +8,7 @@
#include "resources/shader.hpp"
#include "resources/texture.hpp"
#include "resources/mesh.hpp"
#include "ecs/transform.hpp"
#include "ecs/mesh_renderer.hpp"
void playGame()
@ -19,6 +20,9 @@ void playGame()
auto myScene = app.sceneManager()->createScene();
myScene->m_renderSystem->m_cameraPos = { 0.0f, 2.0f, 0.0f };
myScene->m_renderSystem->m_cameraRot = glm::angleAxis(0.0f, glm::vec3{ 0.0f, 0.0f, -1.0f });
{
auto entity1 = myScene->createEntity();
engine::gfx::VertexFormat vertFormat{};
@ -28,20 +32,19 @@ void playGame()
vertFormat.attributeDescriptions.emplace_back(2, engine::gfx::VertexAttribFormat::VEC2, sizeof(float) * 6);
auto myShader = std::make_unique<engine::resources::Shader>(
app.gfx(),
app.getResourcePath("engine/shaders/basic.vert").c_str(),
app.getResourcePath("engine/shaders/basic.frag").c_str(),
app.getResourcePath("engine/shaders/texture.vert").c_str(),
app.getResourcePath("engine/shaders/texture.frag").c_str(),
vertFormat,
false,
false
);
glm::mat4 uniformBuffer{1.0f};
app.gfx()->updateUniformBuffer(myShader->getPipeline(), &uniformBuffer, sizeof(glm::mat4), 0);
auto myMaterial = std::make_unique<engine::resources::Material>(std::move(myShader));
std::vector<engine::Vertex> triVertices{
{ { 0.5f, 0.5f, 0.5f }, { 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f } },
{ { -0.5f, -0.5f, 0.5f }, { 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f } },
{ { 0.5f, -0.5f, 0.5f }, { 0.0f, 0.0f, 1.0f }, { 1.0f, 1.0f } },
{ { 0.5f, 0.5f, 0.0f }, { 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f } },
{ { -0.5f, -0.5f, 0.0f }, { 0.0f, 0.0f, 1.0f }, { 0.0f, 1.0f } },
{ { 0.5f, -0.5f, 0.0f }, { 0.0f, 0.0f, 1.0f }, { 1.0f, 1.0f } },
};
myMaterial->m_texture = std::make_unique<engine::resources::Texture>(app.gfx(), app.getResourcePath("textures/grass.jpg"));
auto myMesh = std::make_unique<engine::resources::Mesh>(app.gfx(), triVertices);
myScene->m_renderSystem->m_components.emplace(
entity1,
@ -50,6 +53,15 @@ void playGame()
std::move(myMesh),
}
);
myScene->m_transformSystem->m_components.emplace(
entity1,
engine::ecs::TransformComponent{
.parent = 0,
.scale = {1.0f, 1.0f, 1.0f},
.position = {0.0f, 0.0f, -10.0f},
.rotation = glm::angleAxis(glm::radians(24.0f), glm::vec3{ 0.0f, 1.0f, 0.0f })
}
);
}
app.gameLoop();