diff --git a/src/dawn/dawnlibs.hpp b/src/dawn/dawnlibs.hpp index d57d5b33..37a6d8b1 100644 --- a/src/dawn/dawnlibs.hpp +++ b/src/dawn/dawnlibs.hpp @@ -27,6 +27,7 @@ extern "C" { #include #include #include +#include // #include // #include // #include diff --git a/src/dawn/display/Shader.hpp b/src/dawn/display/Shader.hpp new file mode 100644 index 00000000..31b68e0a --- /dev/null +++ b/src/dawn/display/Shader.hpp @@ -0,0 +1,11 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "dawnlibs.hpp" + +namespace Dawn { + class Shader; +} \ No newline at end of file diff --git a/src/dawn/display/mesh/TriangleMesh.hpp b/src/dawn/display/mesh/TriangleMesh.hpp new file mode 100644 index 00000000..6b15c5a6 --- /dev/null +++ b/src/dawn/display/mesh/TriangleMesh.hpp @@ -0,0 +1,14 @@ +// 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" + +namespace Dawn { + class TriangleMesh { + public: + static void createTriangleMesh(std::shared_ptr mesh); + }; +} \ No newline at end of file diff --git a/src/dawn/display/mesh/_Mesh.hpp b/src/dawn/display/mesh/_Mesh.hpp new file mode 100644 index 00000000..212943a7 --- /dev/null +++ b/src/dawn/display/mesh/_Mesh.hpp @@ -0,0 +1,11 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "dawnlibs.hpp" + +namespace Dawn { + class Mesh; +} \ No newline at end of file diff --git a/src/dawn/scene/Scene.cpp b/src/dawn/scene/Scene.cpp index 5c06222a..5d0d998d 100644 --- a/src/dawn/scene/Scene.cpp +++ b/src/dawn/scene/Scene.cpp @@ -18,8 +18,8 @@ void Scene::update() { auto it = this->itemsNotInitialized.begin(); while(it != this->itemsNotInitialized.end()) { this->items[it->first] = it->second; - it++; it->second->init(); + ++it; } this->itemsNotInitialized.clear(); diff --git a/src/dawn/scene/Scene.hpp b/src/dawn/scene/Scene.hpp index 82816256..1ee5dfec 100644 --- a/src/dawn/scene/Scene.hpp +++ b/src/dawn/scene/Scene.hpp @@ -28,6 +28,17 @@ namespace Dawn { void removeSceneItem(SceneItem *item); + template + std::shared_ptr findComponent() { + auto it = this->items.begin(); + while(it != this->items.end()) { + auto component = it->second->getComponent(); + if(component != nullptr) return component; + ++it; + } + return nullptr; + } + ~Scene(); }; } \ No newline at end of file diff --git a/src/dawn/scene/SceneItem.hpp b/src/dawn/scene/SceneItem.hpp index 4ca8ca47..2df0fb2d 100644 --- a/src/dawn/scene/SceneItem.hpp +++ b/src/dawn/scene/SceneItem.hpp @@ -11,7 +11,9 @@ namespace Dawn { class Scene; - class SceneItem { + class SceneItem : + public std::enable_shared_from_this + { private: std::vector> components; @@ -25,7 +27,7 @@ namespace Dawn { template std::shared_ptr addComponent() { - auto component = std::make_unique(this); + auto component = std::make_shared(weak_from_this()); this->components.push_back(component); return component; } @@ -34,10 +36,9 @@ namespace Dawn { std::shared_ptr getComponent() { auto it = this->components.begin(); while(it != this->components.end()) { - std::shared_ptr castedAs = dynamic_cast>(*it); + auto castedAs = std::dynamic_pointer_cast(*it); if(castedAs != nullptr) return castedAs; - it++; - continue; + ++it; } return nullptr; } diff --git a/src/dawn/scene/components/CMakeLists.txt b/src/dawn/scene/components/CMakeLists.txt index df0f1622..49d05db4 100644 --- a/src/dawn/scene/components/CMakeLists.txt +++ b/src/dawn/scene/components/CMakeLists.txt @@ -7,4 +7,7 @@ target_sources(${DAWN_TARGET_NAME} PRIVATE DummyComponent.cpp -) \ No newline at end of file +) + +# Subdirs +add_subdirectory(display) \ No newline at end of file diff --git a/src/dawn/scene/components/Components.hpp b/src/dawn/scene/components/Components.hpp new file mode 100644 index 00000000..398483cb --- /dev/null +++ b/src/dawn/scene/components/Components.hpp @@ -0,0 +1,9 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "scene/components/DummyComponent.hpp" +#include "scene/components/display/Camera.hpp" +#include "scene/components/display/MeshRenderer.hpp" \ No newline at end of file diff --git a/src/dawn/scene/components/display/CMakeLists.txt b/src/dawn/scene/components/display/CMakeLists.txt new file mode 100644 index 00000000..169f9f01 --- /dev/null +++ b/src/dawn/scene/components/display/CMakeLists.txt @@ -0,0 +1,11 @@ +# Copyright (c) 2022 Dominic Masters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT + +# Sources +target_sources(${DAWN_TARGET_NAME} + PRIVATE + Camera.cpp + MeshRenderer.cpp +) \ No newline at end of file diff --git a/src/dawn/scene/components/display/Camera.cpp b/src/dawn/scene/components/display/Camera.cpp new file mode 100644 index 00000000..63f90749 --- /dev/null +++ b/src/dawn/scene/components/display/Camera.cpp @@ -0,0 +1,43 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "Camera.hpp" + +using namespace Dawn; + +Camera::Camera(std::weak_ptr item) : SceneItemComponent(item) { +} + +void Camera::updateProjection() { + switch(this->type) { + case CAMERA_TYPE_ORTHONOGRAPHIC: + this->projection = glm::ortho( + this->orthoLeft, + this->orthoRight, + this->orthoBottom, + this->orthoTop, + this->clipNear, + this->clipFar + ); + break; + + case CAMERA_TYPE_PERSPECTIVE: + this->projection = glm::perspective( + this->fov, + this->getAspect(), + this->clipNear, + this->clipFar + ); + break; + } +} + +float_t Camera::getAspect() { + return 16.0f / 9.0f; +} + +void Camera::start() { + this->updateProjection(); +} \ No newline at end of file diff --git a/src/dawn/scene/components/display/Camera.hpp b/src/dawn/scene/components/display/Camera.hpp new file mode 100644 index 00000000..4cb028f5 --- /dev/null +++ b/src/dawn/scene/components/display/Camera.hpp @@ -0,0 +1,57 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "scene/SceneItemComponent.hpp" + +namespace Dawn { + enum CameraType { + CAMERA_TYPE_ORTHONOGRAPHIC, + CAMERA_TYPE_PERSPECTIVE + }; + + class Camera : public SceneItemComponent { + public: + glm::mat4 projection; + + // Perspective + enum CameraType type = CAMERA_TYPE_PERSPECTIVE; + float_t fov = 0.785398f;// 45 degrees + + // Ortho + float_t orthoLeft = 0.0f; + float_t orthoRight = 1.0f; + float_t orthoBottom = 0.0f; + float_t orthoTop = 1.0f; + + // Shared + float_t clipNear = 0.001f; + float_t clipFar = 100.0f; + + /** + * Create a new Camera Component. + * + * @param item SceneItem that this component belongs to. + */ + Camera(std::weak_ptr item); + + /** + * Updates the projection matrix. + */ + void updateProjection(); + + /** + * Returs the aspect ratio of the camera. + * + * @return The aspect ratio of the camera. + */ + float_t getAspect(); + + /** + * Event triggered by the scene item when the item is added to the scene. + */ + void start() override; + }; +} \ No newline at end of file diff --git a/src/dawn/scene/components/display/MeshRenderer.cpp b/src/dawn/scene/components/display/MeshRenderer.cpp new file mode 100644 index 00000000..0905104f --- /dev/null +++ b/src/dawn/scene/components/display/MeshRenderer.cpp @@ -0,0 +1,18 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "MeshRenderer.hpp" + +using namespace Dawn; + +MeshRenderer::MeshRenderer(std::weak_ptr item) : + SceneItemComponent(item) +{ + +} + +void MeshRenderer::start() { + +} \ No newline at end of file diff --git a/src/dawn/scene/components/display/MeshRenderer.hpp b/src/dawn/scene/components/display/MeshRenderer.hpp new file mode 100644 index 00000000..24a879ee --- /dev/null +++ b/src/dawn/scene/components/display/MeshRenderer.hpp @@ -0,0 +1,19 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "scene/SceneItemComponent.hpp" +#include "display/mesh/Mesh.hpp" + +namespace Dawn { + class MeshRenderer : public SceneItemComponent { + public: + std::shared_ptr mesh = nullptr; + + MeshRenderer(std::weak_ptr item); + + void start() override; + }; +} \ No newline at end of file diff --git a/src/dawnopengl/display/CMakeLists.txt b/src/dawnopengl/display/CMakeLists.txt index 8e067074..9cf9350c 100644 --- a/src/dawnopengl/display/CMakeLists.txt +++ b/src/dawnopengl/display/CMakeLists.txt @@ -7,4 +7,7 @@ target_sources(${DAWN_TARGET_NAME} PRIVATE RenderManager.cpp -) \ No newline at end of file +) + +# Subdirs +add_subdirectory(mesh) \ No newline at end of file diff --git a/src/dawnopengl/display/mesh/CMakeLists.txt b/src/dawnopengl/display/mesh/CMakeLists.txt new file mode 100644 index 00000000..133c7e46 --- /dev/null +++ b/src/dawnopengl/display/mesh/CMakeLists.txt @@ -0,0 +1,11 @@ +# Copyright (c) 2022 Dominic Masters +# +# This software is released under the MIT License. +# https://opensource.org/licenses/MIT + +# Sources +target_sources(${DAWN_TARGET_NAME} + PRIVATE + Mesh.cpp + TriangleMesh.cpp +) \ No newline at end of file diff --git a/src/dawnopengl/display/mesh/Mesh.cpp b/src/dawnopengl/display/mesh/Mesh.cpp new file mode 100644 index 00000000..0ce9288e --- /dev/null +++ b/src/dawnopengl/display/mesh/Mesh.cpp @@ -0,0 +1,118 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "Mesh.hpp" + +using namespace Dawn; + +void Mesh::createBuffers( + int32_t verticeCount, + int32_t indiceCount +) { + if(verticeCount <= 0) throw "Vertice count must be greater than zero."; + if(indiceCount <= 0) throw "Indice count must be greater than zero."; + + this->disposeBuffers(); + + this->verticeCount = verticeCount; + this->indiceCount = indiceCount; + + auto sizePos = sizeof(glm::vec3) * verticeCount; + auto sizeInds = sizeof(meshindice_t) * indiceCount; + auto sizeCoords = sizeof(glm::vec2) * verticeCount; + + // Create some buffers, one for the vertex data, one for the indices + GLuint buffer[2]; + glGenBuffers(2, buffer); + this->vertexBuffer = buffer[0]; + if(this->vertexBuffer < 0) throw "Failed to create vertex buffer"; + this->indexBuffer = buffer[1]; + if(this->indexBuffer < 0) throw "Failed to create index buffer"; + + // Buffer an empty set of data then buffer each component + glBindBuffer(GL_ARRAY_BUFFER, this->vertexBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->indexBuffer); + glBufferData(GL_ARRAY_BUFFER, sizePos+sizeCoords, 0, GL_DYNAMIC_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeInds, 0, GL_DYNAMIC_DRAW); + + // Setup the attrib pointers + size_t offset = 0; + glVertexAttribPointer( + 0, sizeof(glm::vec3) / sizeof(float_t), + GL_FLOAT, GL_FALSE, + 0, (void *)offset + ); + glEnableVertexAttribArray(0); + + offset += sizePos; + glVertexAttribPointer( + 1, sizeof(glm::vec2) / sizeof(float_t), + GL_FLOAT, GL_FALSE, + 0, (void *)offset + ); + glEnableVertexAttribArray(1); +} + +void Mesh::disposeBuffers() { + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + if(this->vertexBuffer != -1) { + glDeleteBuffers(1, &this->vertexBuffer); + this->vertexBuffer = -1; + this->verticeCount = -1; + } + + if(this->indexBuffer != -1) { + glDeleteBuffers(1, &this->indexBuffer); + this->indexBuffer = -1; + this->indiceCount = -1; + } +} + +void Mesh::draw( + enum MeshDrawMode drawMode, + int32_t start, + int32_t count +) { + if( + count == 0 || + this->vertexBuffer == -1 || + this->indexBuffer == -1 + ) return; + + if(count == -1) count = this->indiceCount; + + + // Re-Bind the buffers + glBindBuffer(GL_ARRAY_BUFFER, this->vertexBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->indexBuffer); + + // Re-Calculate the attrib pointers. + size_t offset = 0; + glVertexAttribPointer( + 0, sizeof(glm::vec3) / sizeof(float_t), + GL_FLOAT, GL_FALSE, + 0, (void *)offset + ); + glEnableVertexAttribArray(0); + + offset += sizeof(glm::vec3) * this->verticeCount; + glVertexAttribPointer( + 1, sizeof(glm::vec2) / sizeof(float_t), + GL_FLOAT, GL_FALSE, + 0, (void *)offset + ); + glEnableVertexAttribArray(1); + + // Render the elements. + glDrawElements( + drawMode, count, GL_UNSIGNED_INT, (void *)(sizeof(meshindice_t) * start) + ); +} + +Mesh::~Mesh() { + this->disposeBuffers(); +} \ No newline at end of file diff --git a/src/dawnopengl/display/mesh/Mesh.hpp b/src/dawnopengl/display/mesh/Mesh.hpp new file mode 100644 index 00000000..314e15fb --- /dev/null +++ b/src/dawnopengl/display/mesh/Mesh.hpp @@ -0,0 +1,131 @@ +// 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" +#include "dawnopengl.hpp" + +/** Indice that references a specific vertice */ +typedef int32_t meshindice_t; + +namespace Dawn { + enum MeshDrawMode { + MESH_DRAW_MODE_TRIANGLES = GL_TRIANGLES + }; + + class Mesh { + private: + + protected: + /** Pointer to the vertex buffer on the GPU */ + GLuint vertexBuffer = -1; + /** Pointer to the index buffer on the GPU */ + GLuint indexBuffer = -1; + + /** How many vertices are in the mesh */ + int32_t verticeCount = -1; + /** How many indices are in the mesh */ + int32_t indiceCount = -1; + + public: + /** + * Create a new set of buffers for the mesh to use. + * + * @param verticeCount How many Vertices will this buffer support. + * @param indiceCount How many Indices will this buffer support. + */ + void createBuffers( + int32_t verticeCount, + int32_t indiceCount + ); + + /** + * Cleanup the buffers on a given mesh. This is useful if you intend to + * expand the count of vertices your mesh supports. + */ + void disposeBuffers(); + + /** + * Write vertice positions to the mesh. + * + * @tparam N Size of the array, in terms of number of elements. + * @param position Position, within the buffer, to write to. + * @param vertices Array of positions to write. + */ + template + void bufferPositions( + int32_t position, + std::array positions + ) { + glBindBuffer(GL_ARRAY_BUFFER, this->vertexBuffer); + glBufferSubData( + GL_ARRAY_BUFFER, + sizeof(glm::vec3) * position, + sizeof(positions), + (void *)positions.data() + ); + } + + /** + * Write vertice coordinates to the mesh. + * + * @tparam N Size of the array, in terms of number of elements. + * @param position Position, within the buffer, to write to. + * @param coordinates Array of coordinates to write. + */ + template + void bufferCoordinates( + int32_t position, + std::array coordinates + ) { + glBindBuffer(GL_ARRAY_BUFFER, this->vertexBuffer); + glBufferSubData( + GL_ARRAY_BUFFER, + sizeof(glm::vec2) * position, + sizeof(coordinates), + (void *)coordinates.data() + ); + } + + /** + * Write indices to the mesh. + * + * @tparam N Size of the array, in terms of number of elements. + * @param position Position, within the buffer, to write to. + * @param indices Array of indices to write. + */ + template + void bufferIndices( + int32_t position, + std::array indices + ) { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->indexBuffer); + glBufferSubData( + GL_ELEMENT_ARRAY_BUFFER, + sizeof(meshindice_t) * position, + sizeof(indices), + (void *)indices.data() + ); + } + + /** + * Draw a primitive. Primitives are drawn by their indices. + * + * @param drawMode Which drawing mode to use to draw the primitive. + * @param start Start indice (index) to draw. + * @param count Count of indices to draw. Use -1 to draw all. + */ + void draw( + enum MeshDrawMode drawMode, + int32_t start, + int32_t count + ); + + /** + * Cleanup a previously initiated mesh. + */ + ~Mesh(); + }; +} \ No newline at end of file diff --git a/src/dawnopengl/display/mesh/TriangleMesh.cpp b/src/dawnopengl/display/mesh/TriangleMesh.cpp new file mode 100644 index 00000000..e70377eb --- /dev/null +++ b/src/dawnopengl/display/mesh/TriangleMesh.cpp @@ -0,0 +1,26 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "display/mesh/Mesh.hpp" +#include "display/mesh/TriangleMesh.hpp" + +using namespace Dawn; + +void TriangleMesh::createTriangleMesh(std::shared_ptr mesh) { + mesh->createBuffers(3, 3); + mesh->bufferPositions(0, std::array{{ + glm::vec3(-1, 0, 0), + glm::vec3(0, 1, 0), + glm::vec3(1, 0, 0) + }}); + mesh->bufferCoordinates(0, std::array{{ + glm::vec2(0, 0), + glm::vec2(0, 1), + glm::vec2(1, 0) + }}); + mesh->bufferIndices(0, std::array{{ + 0, 1, 2 + }}); +} \ No newline at end of file diff --git a/src/dawnpokergame/game/DawnPokerGame.cpp b/src/dawnpokergame/game/DawnPokerGame.cpp index f2fb45ad..575e503a 100644 --- a/src/dawnpokergame/game/DawnPokerGame.cpp +++ b/src/dawnpokergame/game/DawnPokerGame.cpp @@ -16,13 +16,28 @@ DawnGame::DawnGame(std::weak_ptr host) : int32_t DawnGame::init() { this->renderManager.init(); - this->scene = std::make_unique(weak_from_this()); + this->scene = std::make_shared(weak_from_this()); + + auto cameraObject = this->scene->createSceneItem(); + auto camera = cameraObject->addComponent(); + + auto cubeObject = this->scene->createSceneItem(); + auto cubeMeshRenderer = cubeObject->addComponent(); + cubeMeshRenderer->mesh = std::make_shared(); + TriangleMesh::createTriangleMesh(cubeMeshRenderer->mesh); return DAWN_GAME_INIT_RESULT_SUCCESS; } int32_t DawnGame::update(float_t delta) { this->renderManager.update(); + if(this->scene != nullptr) this->scene->update(); + + auto meshRenderer = this->scene->findComponent(); + if(meshRenderer != nullptr) { + std::cout << "REndering" << std::endl; + meshRenderer->mesh->draw(MESH_DRAW_MODE_TRIANGLES, 0, -1); + } return DAWN_GAME_UPDATE_RESULT_SUCCESS; } diff --git a/src/dawnpokergame/game/DawnPokerGame.hpp b/src/dawnpokergame/game/DawnPokerGame.hpp index f0719e14..a0da3717 100644 --- a/src/dawnpokergame/game/DawnPokerGame.hpp +++ b/src/dawnpokergame/game/DawnPokerGame.hpp @@ -4,4 +4,6 @@ // https://opensource.org/licenses/MIT #pragma once -#include "game/DawnGame.hpp" \ No newline at end of file +#include "game/DawnGame.hpp" +#include "scene/components/Components.hpp" +#include "display/mesh/TriangleMesh.hpp" \ No newline at end of file