From be529b70c1522e9c05b52874480259a30aaa4584 Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Fri, 21 Oct 2022 22:01:37 -0700 Subject: [PATCH] Basic transform stuff --- src/dawn/dawnlibs.hpp | 1 + src/dawn/display/CMakeLists.txt | 1 + src/dawn/display/RenderPipeline.cpp | 8 +- src/dawn/display/Transform.cpp | 156 +++++++++++++++++++ src/dawn/display/Transform.hpp | 69 ++++++++ src/dawn/display/mesh/CMakeLists.txt | 1 + src/dawn/display/mesh/CubeMesh.cpp | 64 ++++++++ src/dawn/display/mesh/CubeMesh.hpp | 21 +++ src/dawn/scene/Scene.cpp | 2 +- src/dawn/scene/SceneItem.cpp | 6 +- src/dawn/scene/SceneItem.hpp | 3 +- src/dawn/scene/SceneItemComponent.cpp | 5 +- src/dawn/scene/SceneItemComponent.hpp | 2 + src/dawn/scene/components/display/Camera.cpp | 8 - src/dawn/scene/components/display/Camera.hpp | 3 - src/dawnopengl/display/RenderManager.cpp | 8 + src/dawnpokergame/game/DawnPokerGame.cpp | 42 +++-- src/dawnpokergame/game/DawnPokerGame.hpp | 1 + 18 files changed, 363 insertions(+), 38 deletions(-) create mode 100644 src/dawn/display/Transform.cpp create mode 100644 src/dawn/display/Transform.hpp create mode 100644 src/dawn/display/mesh/CubeMesh.cpp create mode 100644 src/dawn/display/mesh/CubeMesh.hpp diff --git a/src/dawn/dawnlibs.hpp b/src/dawn/dawnlibs.hpp index 37a6d8b1..6b354dde 100644 --- a/src/dawn/dawnlibs.hpp +++ b/src/dawn/dawnlibs.hpp @@ -37,6 +37,7 @@ extern "C" { #include #include #include +#include #include #include #include diff --git a/src/dawn/display/CMakeLists.txt b/src/dawn/display/CMakeLists.txt index f01d2376..95caaee1 100644 --- a/src/dawn/display/CMakeLists.txt +++ b/src/dawn/display/CMakeLists.txt @@ -7,6 +7,7 @@ target_sources(${DAWN_TARGET_NAME} PRIVATE RenderPipeline.cpp + Transform.cpp ) # Subdirs diff --git a/src/dawn/display/RenderPipeline.cpp b/src/dawn/display/RenderPipeline.cpp index d50e9f37..d530b227 100644 --- a/src/dawn/display/RenderPipeline.cpp +++ b/src/dawn/display/RenderPipeline.cpp @@ -58,18 +58,18 @@ void RenderPipeline::renderSceneCamera(Scene &scene, Camera &camera) { auto it = meshes.begin(); while(it != meshes.end()) { auto mesh = *it; - auto item = mesh->item; - auto material = item.getComponent(); + auto material = mesh->item.getComponent(); // TODO: fallback material? if(material == nullptr) { + ++it; continue; } auto shader = material->getShader(); shader->bind(); - shader->setGlobalParameters(camera.projection, camera.item.transform); - shader->setMeshParameters(item.transform); + shader->setGlobalParameters(camera.projection, camera.transform.getWorldTransform()); + shader->setMeshParameters(mesh->item.transform.getWorldTransform()); material->setShaderParameters(); mesh->mesh->draw(MESH_DRAW_MODE_TRIANGLES, 0, -1); diff --git a/src/dawn/display/Transform.cpp b/src/dawn/display/Transform.cpp new file mode 100644 index 00000000..9697fdc2 --- /dev/null +++ b/src/dawn/display/Transform.cpp @@ -0,0 +1,156 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "Transform.hpp" +#include "scene/SceneItem.hpp" + +using namespace Dawn; + +Transform::Transform(SceneItem &item) : + item(item), + transformLocal(1.0f), + transformWorld(1.0f) +{ + this->updateLocalValuesFromLocalTransform(); +} + +void Transform::updateLocalValuesFromLocalTransform() { + glm::vec3 skew; + glm::vec4 perspective; + glm::decompose( + this->transformLocal, + this->localScale, + this->localRotation, + this->localPosition, + skew, perspective + ); +} + +void Transform::updateLocalTransformFromLocalValues() { + glm::mat4 translate = glm::translate(glm::mat4(1.0), this->localPosition); + glm::mat4 rotate = glm::mat4_cast(this->localRotation); + glm::mat4 scale = glm::scale(glm::mat4(1.0), this->localScale); + this->transformLocal = translate * rotate * scale; + this->updateWorldTransformFromLocalTransform(); +} + +void Transform::updateWorldTransformFromLocalTransform() { + glm::mat4 newWorld(1.0f); + auto parent = this->getParent(); + if(parent != nullptr) newWorld = parent->getWorldTransform(); + this->transformWorld = newWorld * transformLocal; +} + +void Transform::updateLocalTransformFromWorldTransform() { + glm::mat4 parentMat(1.0f); + auto parent = this->getParent(); + if(parent != nullptr) parentMat = parent->getWorldTransform(); + this->transformLocal = parentMat / this->transformWorld; + this->updateLocalValuesFromLocalTransform(); +} + +void Transform::updateChildrenTransforms() { + auto it = this->children.begin(); + while(it != this->children.end()) { + (*it)->updateWorldTransformFromLocalTransform(); + ++it; + } +} + +void Transform::lookAt(glm::vec3 pos, glm::vec3 look) { + this->lookAt(pos, look, glm::vec3(0, 1, 0)); +} + +void Transform::lookAt(glm::vec3 pos, glm::vec3 look, glm::vec3 up) { + this->setWorldTransform(glm::lookAt(pos, look, up)); +} + + +glm::vec3 Transform::getLocalPosition() { + return this->localPosition; +} + +void Transform::setLocalPosition(glm::vec3 position) { + this->localPosition = position; + this->updateLocalTransformFromLocalValues(); + this->updateChildrenTransforms(); +} + +glm::vec3 Transform::getLocalScale() { + return this->scale; +} + +void Transform::setLocalScale(glm::vec3 scale) { + this->localScale = scale; + this->updateLocalTransformFromLocalValues(); + this->updateChildrenTransforms(); +} + +glm::quat Transform::getLocalRotation() { + return this->localRotation; +} + +void Transform::setLocalRotation(glm::quat rotation) { + this->localRotation = rotation; + this->updateLocalTransformFromLocalValues(); + this->updateChildrenTransforms(); +} + + +glm::mat4 Transform::getLocalTransform() { + return this->transformLocal; +} + +void Transform::setLocalTransform(glm::mat4 transform) { + this->transformLocal = transform; + + this->updateLocalValuesFromLocalTransform(); + this->updateChildrenTransforms(); +} + +glm::mat4 Transform::getWorldTransform() { + return this->transformWorld; +} + +void Transform::setWorldTransform(glm::mat4 transform) { + this->transformWorld = transform; + this->updateLocalTransformFromWorldTransform(); + this->updateChildrenTransforms(); +} + + +void Transform::setParent(Transform *parent) { + if(parent == this) throw "Cannot self reference"; + + auto currentParent = this->getParent(); + if(currentParent == parent) return; + + if(currentParent != nullptr) { + auto it = currentParent->children.begin(); + while(it != currentParent->children.end()) { + if(*it == this) { + currentParent->children.erase(it); + break; + } + ++it; + } + } + + this->parent = parent; + if(parent != nullptr) parent->children.push_back(this); +} + +Transform * Transform::getParent() { + return this->parent; +} + +Transform::~Transform() { + this->setParent(nullptr); + auto it = this->parent->children.begin(); + while(it != this->parent->children.end()) { + (*it)->setParent(nullptr); + ++it; + } +} \ No newline at end of file diff --git a/src/dawn/display/Transform.hpp b/src/dawn/display/Transform.hpp new file mode 100644 index 00000000..916505bb --- /dev/null +++ b/src/dawn/display/Transform.hpp @@ -0,0 +1,69 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "dawnlibs.hpp" +#include "util/flag.hpp" + +namespace Dawn { + class SceneItem; + + class Transform : public std::enable_shared_from_this { + private: + // Local (real) values + glm::vec3 localPosition; + glm::vec3 localScale; + glm::quat localRotation; + + // Cached (non-real) values + glm::mat4 transformLocal; + glm::mat4 transformWorld; + + glm::vec3 position; + glm::vec3 scale; + glm::quat rotation; + + // Heirarchy + Transform *parent = nullptr; + std::vector children; + + // Hidden methods + void updateLocalValuesFromLocalTransform(); + void updateLocalTransformFromLocalValues(); + void updateWorldTransformFromLocalTransform(); + void updateLocalTransformFromWorldTransform(); + void updateChildrenTransforms(); + + public: + SceneItem &item; + + Transform(SceneItem &item); + + void lookAt(glm::vec3 position, glm::vec3 look); + void lookAt(glm::vec3 position, glm::vec3 look, glm::vec3 up); + + glm::vec3 getLocalPosition(); + void setLocalPosition(glm::vec3 position); + + glm::vec3 getLocalScale(); + void setLocalScale(glm::vec3 scale); + + glm::quat getLocalRotation(); + void setLocalRotation(glm::quat rotation); + + + glm::mat4 getLocalTransform(); + void setLocalTransform(glm::mat4 transform); + + glm::mat4 getWorldTransform(); + void setWorldTransform(glm::mat4 transform); + + + void setParent(Transform *p); + Transform * getParent(); + + ~Transform(); + }; +} \ No newline at end of file diff --git a/src/dawn/display/mesh/CMakeLists.txt b/src/dawn/display/mesh/CMakeLists.txt index c18e3879..7b31221a 100644 --- a/src/dawn/display/mesh/CMakeLists.txt +++ b/src/dawn/display/mesh/CMakeLists.txt @@ -6,6 +6,7 @@ # Sources target_sources(${DAWN_TARGET_NAME} PRIVATE + CubeMesh.cpp TriangleMesh.cpp QuadMesh.cpp ) \ No newline at end of file diff --git a/src/dawn/display/mesh/CubeMesh.cpp b/src/dawn/display/mesh/CubeMesh.cpp new file mode 100644 index 00000000..afbf84aa --- /dev/null +++ b/src/dawn/display/mesh/CubeMesh.cpp @@ -0,0 +1,64 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "CubeMesh.hpp" + +using namespace Dawn; + +void CubeMesh::buffer( + Mesh &mesh, + glm::vec3 pos, glm::vec3 size, + int32_t verticeStart, int32_t indiceStart +) { + mesh.bufferPositions(verticeStart, std::array{{ + pos, + glm::vec3(pos.x+size.x, pos.y, pos.z), + glm::vec3(pos.x, pos.y+size.y, pos.z), + glm::vec3(pos.x+size.x, pos.y+size.y, pos.z), + + glm::vec3(pos.x, pos.y, pos.z+size.z), + glm::vec3(pos.x+size.x, pos.y, pos.z+size.z), + glm::vec3(pos.x, pos.y+size.y, pos.z+size.z), + pos + size + }}); + + mesh.bufferCoordinates(verticeStart,std::array{{ + glm::vec2(0, 0), + glm::vec2(1, 0), + glm::vec2(0, 1), + glm::vec2(1, 1), + + glm::vec2(0, 0), + glm::vec2(1, 0), + glm::vec2(0, 1), + glm::vec2(1, 1) + }}); + + mesh.bufferIndices(indiceStart, std::array{{ + // Back + verticeStart, verticeStart + 1, verticeStart + 3, + verticeStart, verticeStart + 2, verticeStart + 3, + + // Right + verticeStart + 1, verticeStart + 5, verticeStart + 7, + verticeStart + 1, verticeStart + 3, verticeStart + 7, + + // Left + verticeStart + 4, verticeStart, verticeStart + 2, + verticeStart + 4, verticeStart + 6, verticeStart + 2, + + // Front + verticeStart + 5, verticeStart + 4, verticeStart + 6, + verticeStart + 5, verticeStart + 7, verticeStart + 6, + + // Top + verticeStart + 7, verticeStart + 2, verticeStart + 6, + verticeStart + 7, verticeStart + 3, verticeStart + 2, + + // Bottom + verticeStart + 1, verticeStart, verticeStart + 4, + verticeStart + 1, verticeStart + 4, verticeStart + 5 + }}); +} \ No newline at end of file diff --git a/src/dawn/display/mesh/CubeMesh.hpp b/src/dawn/display/mesh/CubeMesh.hpp new file mode 100644 index 00000000..63f7ae50 --- /dev/null +++ b/src/dawn/display/mesh/CubeMesh.hpp @@ -0,0 +1,21 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "display/mesh/Mesh.hpp" + +#define CUBE_VERTICE_COUNT 8 +#define CUBE_INDICE_COUNT 36 + +namespace Dawn { + class CubeMesh { + public: + static void buffer( + Mesh &mesh, + glm::vec3 pos, glm::vec3 size, + int32_t verticeStart, int32_t indiceStart + ); + }; +} \ No newline at end of file diff --git a/src/dawn/scene/Scene.cpp b/src/dawn/scene/Scene.cpp index 9b52ab16..ade5f528 100644 --- a/src/dawn/scene/Scene.cpp +++ b/src/dawn/scene/Scene.cpp @@ -35,5 +35,5 @@ std::shared_ptr Scene::createSceneItem() { } Scene::~Scene() { - + std::cout << "What the dick" << std::endl; } \ No newline at end of file diff --git a/src/dawn/scene/SceneItem.cpp b/src/dawn/scene/SceneItem.cpp index 4a428bca..73bf4f5d 100644 --- a/src/dawn/scene/SceneItem.cpp +++ b/src/dawn/scene/SceneItem.cpp @@ -11,10 +11,8 @@ using namespace Dawn; SceneItem::SceneItem(Scene &scene, sceneitemid_t id) : scene(scene), id(id), - transform(1.0f) + transform(*this) { - this->id = id; - this->transform = glm::translate(this->transform, glm::vec3(0, 0, 0)); } void SceneItem::init() { @@ -22,5 +20,5 @@ void SceneItem::init() { } SceneItem::~SceneItem() { - + std::cout << "Scene item disposed" << std::endl; } \ No newline at end of file diff --git a/src/dawn/scene/SceneItem.hpp b/src/dawn/scene/SceneItem.hpp index dcdc6977..264c602d 100644 --- a/src/dawn/scene/SceneItem.hpp +++ b/src/dawn/scene/SceneItem.hpp @@ -5,6 +5,7 @@ #pragma once #include "SceneItemComponent.hpp" +#include "display/Transform.hpp" namespace Dawn { typedef int32_t sceneitemid_t; @@ -18,7 +19,7 @@ namespace Dawn { public: Scene &scene; sceneitemid_t id; - glm::mat4 transform; + Transform transform; /** * Constructor for a SceneItem. Scene Items should only be called and diff --git a/src/dawn/scene/SceneItemComponent.cpp b/src/dawn/scene/SceneItemComponent.cpp index 9fc4f74b..e063ecb6 100644 --- a/src/dawn/scene/SceneItemComponent.cpp +++ b/src/dawn/scene/SceneItemComponent.cpp @@ -10,7 +10,10 @@ using namespace Dawn; -SceneItemComponent::SceneItemComponent(SceneItem &item) : item(item) { +SceneItemComponent::SceneItemComponent(SceneItem &item) : + item(item), + transform(item.transform) +{ } Scene & SceneItemComponent::getScene() { diff --git a/src/dawn/scene/SceneItemComponent.hpp b/src/dawn/scene/SceneItemComponent.hpp index 34215378..aa9dc8d0 100644 --- a/src/dawn/scene/SceneItemComponent.hpp +++ b/src/dawn/scene/SceneItemComponent.hpp @@ -5,6 +5,7 @@ #pragma once #include "dawnlibs.hpp" +#include "display/Transform.hpp" namespace Dawn { class SceneItem; @@ -14,6 +15,7 @@ namespace Dawn { class SceneItemComponent { public: SceneItem &item; + Transform &transform; /** * Constructs a new SceneItemComponent. Components are attached to diff --git a/src/dawn/scene/components/display/Camera.cpp b/src/dawn/scene/components/display/Camera.cpp index 72c6a328..737c8f56 100644 --- a/src/dawn/scene/components/display/Camera.cpp +++ b/src/dawn/scene/components/display/Camera.cpp @@ -41,14 +41,6 @@ void Camera::updateProjection() { } } -void Camera::lookAt(glm::vec3 pos, glm::vec3 look) { - this->lookAt(pos, look, glm::vec3(0, 1, 0)); -} - -void Camera::lookAt(glm::vec3 pos, glm::vec3 look, glm::vec3 up) { - this->item.transform = glm::lookAt(pos, look, up); -} - RenderTarget & Camera::getRenderTarget() { if(this->target == nullptr) { return this->getGame().renderManager.getBackBuffer(); diff --git a/src/dawn/scene/components/display/Camera.hpp b/src/dawn/scene/components/display/Camera.hpp index 2089aeeb..dbc83d4b 100644 --- a/src/dawn/scene/components/display/Camera.hpp +++ b/src/dawn/scene/components/display/Camera.hpp @@ -48,9 +48,6 @@ namespace Dawn { */ void updateProjection(); - void lookAt(glm::vec3 position, glm::vec3 look); - void lookAt(glm::vec3 position, glm::vec3 look, glm::vec3 up); - /** * Returns the intended render target for this camera to render to, will * automatically revert to the back buffer if no frame buffer is provided. diff --git a/src/dawnopengl/display/RenderManager.cpp b/src/dawnopengl/display/RenderManager.cpp index a6784b21..e371a349 100644 --- a/src/dawnopengl/display/RenderManager.cpp +++ b/src/dawnopengl/display/RenderManager.cpp @@ -21,6 +21,14 @@ RenderManager::RenderManager(DawnGame &game) : void RenderManager::init() { this->standardRenderPipeline->init(); this->simpleShader->compile(); + + // Setup the alpha blend function. + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + glEnable(GL_TEXTURE_2D); + glEnable(GL_DEPTH_TEST); + glDepthMask(GL_TRUE); + glDepthFunc(GL_LESS); } RenderTarget & RenderManager::getBackBuffer() { diff --git a/src/dawnpokergame/game/DawnPokerGame.cpp b/src/dawnpokergame/game/DawnPokerGame.cpp index ff0964f0..1750fc06 100644 --- a/src/dawnpokergame/game/DawnPokerGame.cpp +++ b/src/dawnpokergame/game/DawnPokerGame.cpp @@ -7,6 +7,22 @@ using namespace Dawn; +std::shared_ptr cubeCreate(std::shared_ptr scene) { + auto cubeObject = scene->createSceneItem(); + auto cubeMeshRenderer = cubeObject->addComponent(); + auto cubeMaterial = cubeObject->addComponent(); + cubeMeshRenderer->mesh = std::make_shared(); + cubeMeshRenderer->mesh->createBuffers(CUBE_VERTICE_COUNT, CUBE_INDICE_COUNT); + CubeMesh::buffer( + *cubeMeshRenderer->mesh, + glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(1, 1, 1), + 0, 0 + ); + return cubeObject; +} + +std::shared_ptr cubeParent; + DawnGame::DawnGame(DawnHost &host) : host(host), renderManager(*this) @@ -21,22 +37,14 @@ int32_t DawnGame::init() { auto cameraObject = this->scene->createSceneItem(); auto camera = cameraObject->addComponent(); - camera->lookAt(glm::vec3(5, 5, 5), glm::vec3(0, 0, 0)); - - auto cubeObject = this->scene->createSceneItem(); - auto cubeMeshRenderer = cubeObject->addComponent(); - auto cubeMaterial = cubeObject->addComponent(); - cubeMeshRenderer->mesh = std::make_shared(); - cubeMeshRenderer->mesh->createBuffers(QUAD_VERTICE_COUNT, QUAD_INDICE_COUNT); - QuadMesh::bufferQuadMeshWithZ( - *cubeMeshRenderer->mesh, - glm::vec2(-1, -1), glm::vec2(0, 0), - glm::vec2(1, 1), glm::vec2(1, 1), - 0, 0, 0 - ); - - auto textureAsset = this->assetManager.load("texture_test"); - cubeMaterial->textureValues[cubeMaterial->getShader()->getParameterByName("u_Text")] = std::shared_ptr(textureAsset->texture); + camera->transform.lookAt(glm::vec3(5, 5, 5), glm::vec3(0, 0, 0)); + + cubeParent = cubeCreate(this->scene); + auto cubeChild = cubeCreate(this->scene); + cubeChild->getComponent()->colorValues[cubeChild->getComponent()->getShader()->getParameterByName("u_Color")] = COLOR_MAGENTA; + cubeChild->transform.setParent(&cubeParent->transform); + cubeChild->transform.setLocalPosition(glm::vec3(1, 0, 0)); + cubeParent->transform.setLocalPosition(glm::vec3(-0.5f, 0, 0)); return DAWN_GAME_INIT_RESULT_SUCCESS; } @@ -45,6 +53,8 @@ int32_t DawnGame::update(float_t delta) { this->assetManager.update(); if(this->scene != nullptr) this->scene->update(); + + cubeParent->transform.setLocalPosition(cubeParent->transform.getLocalPosition() + glm::vec3(-delta, 0, 0)); this->renderManager.update(); diff --git a/src/dawnpokergame/game/DawnPokerGame.hpp b/src/dawnpokergame/game/DawnPokerGame.hpp index 2b65f68e..c80e9eb1 100644 --- a/src/dawnpokergame/game/DawnPokerGame.hpp +++ b/src/dawnpokergame/game/DawnPokerGame.hpp @@ -8,4 +8,5 @@ #include "scene/components/Components.hpp" #include "display/mesh/QuadMesh.hpp" #include "display/mesh/TriangleMesh.hpp" +#include "display/mesh/CubeMesh.hpp" #include "asset/assets/TextureAsset.hpp" \ No newline at end of file