From 4eeecced2f6639263b0ec62e6dadaf89f01b2e1f Mon Sep 17 00:00:00 2001 From: Dominic Masters Date: Sat, 19 Nov 2022 13:42:04 -0800 Subject: [PATCH] VN System improved. --- src/dawn/display/font/Font.hpp | 11 ++ src/dawn/display/font/FontMeasure.hpp | 44 +++++ src/dawn/display/font/TrueTypeFont.cpp | 5 + src/dawn/display/font/TrueTypeFont.hpp | 1 + src/dawn/scene/Scene.hpp | 22 ++- src/dawn/scene/components/Components.hpp | 20 +-- src/dawn/scene/components/display/Camera.hpp | 7 + src/dawn/scene/components/ui/UICanvas.hpp | 11 ++ src/dawn/ui/CMakeLists.txt | 25 +-- src/dawn/ui/UIComponent.cpp | 4 +- .../ui/UIEmpty.cpp} | 10 +- src/dawn/ui/UIEmpty.hpp | 15 ++ src/dawn/ui/UILabel.cpp | 2 +- src/dawn/visualnovel/CMakeLists.txt | 1 + src/dawn/visualnovel/VisualNovelManager.cpp | 68 +++++++- src/dawn/visualnovel/VisualNovelManager.hpp | 79 ++++++++- src/dawn/visualnovel/events/CMakeLists.txt | 10 ++ .../events/VisualNovelTextboxEvent.cpp | 28 ++++ .../events/VisualNovelTextboxEvent.hpp | 24 +++ .../visualnovel/ui/VisualNovelTextbox.cpp | 62 ++++++-- .../visualnovel/ui/VisualNovelTextbox.hpp | 32 +++- src/dawnopengl/display/Texture.cpp | 150 +++++++++--------- src/dawnopengl/display/Texture.hpp | 1 + src/dawnopengl/display/shader/UIShader.hpp | 2 +- src/dawnpokergame/game/DawnGame.cpp | 29 +--- src/dawnpokergame/scenes/TestScene.hpp | 40 +++++ src/dawnpokergame/ui/CMakeLists.txt | 8 +- src/dawnpokergame/ui/PokerGameTextbox.hpp | 20 ++- 28 files changed, 577 insertions(+), 154 deletions(-) rename src/{dawnpokergame/ui/PokerGameTextbox.cpp => dawn/ui/UIEmpty.cpp} (51%) create mode 100644 src/dawn/ui/UIEmpty.hpp create mode 100644 src/dawn/visualnovel/events/CMakeLists.txt create mode 100644 src/dawn/visualnovel/events/VisualNovelTextboxEvent.cpp create mode 100644 src/dawn/visualnovel/events/VisualNovelTextboxEvent.hpp create mode 100644 src/dawnpokergame/scenes/TestScene.hpp diff --git a/src/dawn/display/font/Font.hpp b/src/dawn/display/font/Font.hpp index 8c6f9729..7f0b9dbe 100644 --- a/src/dawn/display/font/Font.hpp +++ b/src/dawn/display/font/Font.hpp @@ -37,6 +37,17 @@ namespace Dawn { struct FontMeasure *info ) = 0; + /** + * Fonts need to be initialized before they can actually be used, but I + * really want to keep things kind-of non-blocking, so for the time being + * this hack works around it, fonts can decide to return false if they are + * not "ready for buffering", and the item intending to use the font is + * required to decide when it should actually request buffering. + * + * @return True if ready for buffering, otherwise false. + */ + virtual bool_t isReady() = 0; + /** * Returns the texture that is used for a given font. * diff --git a/src/dawn/display/font/FontMeasure.hpp b/src/dawn/display/font/FontMeasure.hpp index fb71043a..80a80bc4 100644 --- a/src/dawn/display/font/FontMeasure.hpp +++ b/src/dawn/display/font/FontMeasure.hpp @@ -40,12 +40,56 @@ namespace Dawn { */ void addLine(int32_t start, int32_t length); + /** + * Returns the width of this measured string. + * + * @return Width of the pre measured string. + */ float_t getWidth(); + + /** + * Returns the height of the measured string. + * + * @return Height of the pre measured string. + */ float_t getHeight(); + + /** + * Returns the count of quads on the given line. + * + * @param line Which line to get the count of quads for. + * @return Count of quads on that line. + */ int32_t getQuadsOnLine(int32_t line); + + /** + * Returns the index, of which quad is the first quad on the given line. + * + * @param line Line to get the quad index of. + * @return The quad index of that line. + */ int32_t getQuadIndexOnLine(int32_t line); + + /** + * Returns the height of the count of lines provided. + * + * @param lineCount Count of lines to get the height of. + * @return Height of the given count of lines. + */ float_t getHeightOfLineCount(int32_t lineCount); + + /** + * Returns the count of lines in this string. + * + * @return Count of lines. + */ size_t getLineCount(); + + /** + * Returns the count of quads in this string. + * + * @return Total count of quads. + */ int32_t getQuadCount(); }; } \ No newline at end of file diff --git a/src/dawn/display/font/TrueTypeFont.cpp b/src/dawn/display/font/TrueTypeFont.cpp index 96e80d7a..a56a96a3 100644 --- a/src/dawn/display/font/TrueTypeFont.cpp +++ b/src/dawn/display/font/TrueTypeFont.cpp @@ -56,6 +56,7 @@ void TrueTypeFont::buffer( assertNotNull(info); assertTrue(fontSize > 0); assertTrue(maxWidth == -1 || maxWidth > 0); + assertTrue(this->isReady()); auto stringLength = text.length(); if(stringLength == 0) { @@ -189,6 +190,10 @@ void TrueTypeFont::buffer( delete quads; } +bool_t TrueTypeFont::isReady() { + return this->texture.isReady(); +} + Texture * TrueTypeFont::getTexture() { return &this->texture; } diff --git a/src/dawn/display/font/TrueTypeFont.hpp b/src/dawn/display/font/TrueTypeFont.hpp index 6be11fc4..d300c1eb 100644 --- a/src/dawn/display/font/TrueTypeFont.hpp +++ b/src/dawn/display/font/TrueTypeFont.hpp @@ -74,6 +74,7 @@ namespace Dawn { Mesh *mesh, struct FontMeasure *info ) override; + bool_t isReady() override; Texture * getTexture() override; void draw(Mesh *mesh, int32_t startCharacter, int32_t length) override; float_t getLineHeight(float_t fontSize) override; diff --git a/src/dawn/scene/Scene.hpp b/src/dawn/scene/Scene.hpp index 1bd0e7c6..b99e615e 100644 --- a/src/dawn/scene/Scene.hpp +++ b/src/dawn/scene/Scene.hpp @@ -51,12 +51,18 @@ namespace Dawn { */ template T * findComponent() { - auto it = this->items.begin(); - while(it != this->items.end()) { + auto it = this->itemsNotInitialized.begin(); + while(it != this->itemsNotInitialized.end()) { auto component = it->second->getComponent(); if(component != nullptr) return component; ++it; } + auto it2 = this->items.begin(); + while(it2 != this->items.end()) { + auto component = it2->second->getComponent(); + if(component != nullptr) return component; + ++it2; + } return nullptr; } @@ -70,12 +76,20 @@ namespace Dawn { template std::vector findComponents() { std::vector components; - auto it = this->items.begin(); - while(it != this->items.end()) { + + auto it = this->itemsNotInitialized.begin(); + while(it != this->itemsNotInitialized.end()) { auto component = it->second->getComponent(); if(component != nullptr) components.push_back(component); ++it; } + + auto it2 = this->items.begin(); + while(it2 != this->items.end()) { + auto component = it2->second->getComponent(); + if(component != nullptr) components.push_back(component); + ++it2; + } return components; } diff --git a/src/dawn/scene/components/Components.hpp b/src/dawn/scene/components/Components.hpp index 880fdac5..0641995a 100644 --- a/src/dawn/scene/components/Components.hpp +++ b/src/dawn/scene/components/Components.hpp @@ -1,9 +1,11 @@ -// Copyright (c) 2022 Dominic Masters -// -// This software is released under the MIT License. -// https://opensource.org/licenses/MIT - -#pragma once -#include "scene/components/display/Camera.hpp" -#include "scene/components/display/MeshRenderer.hpp" -#include "scene/components/display/Material.hpp" \ No newline at end of file +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "scene/components/display/Camera.hpp" +#include "scene/components/display/MeshRenderer.hpp" +#include "scene/components/display/Material.hpp" + +#include "scene/components/ui/UICanvas.hpp" \ No newline at end of file diff --git a/src/dawn/scene/components/display/Camera.hpp b/src/dawn/scene/components/display/Camera.hpp index 447d6dc6..74985fb9 100644 --- a/src/dawn/scene/components/display/Camera.hpp +++ b/src/dawn/scene/components/display/Camera.hpp @@ -6,6 +6,7 @@ #pragma once #include "scene/SceneItemComponent.hpp" #include "display/RenderTarget.hpp" +#include "scene/Scene.hpp" namespace Dawn { enum CameraType { @@ -20,6 +21,12 @@ namespace Dawn { void onRenderTargetResize(RenderTarget *target, float_t w, float_t h); public: + static Camera * create(Scene *scene) { + auto item = scene->createSceneItem(); + auto cam = item->addComponent(); + return cam; + } + glm::mat4 projection; // Perspective diff --git a/src/dawn/scene/components/ui/UICanvas.hpp b/src/dawn/scene/components/ui/UICanvas.hpp index da3634ce..abadbb7b 100644 --- a/src/dawn/scene/components/ui/UICanvas.hpp +++ b/src/dawn/scene/components/ui/UICanvas.hpp @@ -57,6 +57,17 @@ namespace Dawn { this->children.push_back(item); return item; } + + template + T * findElement() { + auto it = this->children.begin(); + while(it != this->children.end()) { + auto castedAs = dynamic_cast(*it); + if(castedAs != nullptr) return castedAs; + ++it; + } + return nullptr; + } /** * Returns the width of the root UI Canvas size. In future I may allow diff --git a/src/dawn/ui/CMakeLists.txt b/src/dawn/ui/CMakeLists.txt index 4dde864d..247b5cad 100644 --- a/src/dawn/ui/CMakeLists.txt +++ b/src/dawn/ui/CMakeLists.txt @@ -1,13 +1,14 @@ -# 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 - UIBorder.cpp - UIComponent.cpp - UILabel.cpp - UISprite.cpp +# 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 + UIBorder.cpp + UIComponent.cpp + UILabel.cpp + UISprite.cpp + UIEmpty.cpp ) \ No newline at end of file diff --git a/src/dawn/ui/UIComponent.cpp b/src/dawn/ui/UIComponent.cpp index 4ef1583d..12ac8e26 100644 --- a/src/dawn/ui/UIComponent.cpp +++ b/src/dawn/ui/UIComponent.cpp @@ -139,10 +139,11 @@ void UIComponent::addChild(UIComponent *child) { if(child->parent != nullptr) child->parent->removeChild(child); this->children.push_back(child); child->parent = this; + this->updatePositions(); } void UIComponent::removeChild(UIComponent *child) { - assertTrue(child->parent != this); + assertTrue(child->parent == this); auto it = this->children.begin(); while(it != this->children.end()) { if(*it == child) { @@ -151,6 +152,7 @@ void UIComponent::removeChild(UIComponent *child) { } ++it; } + child->parent = nullptr; } UIComponent::~UIComponent() { diff --git a/src/dawnpokergame/ui/PokerGameTextbox.cpp b/src/dawn/ui/UIEmpty.cpp similarity index 51% rename from src/dawnpokergame/ui/PokerGameTextbox.cpp rename to src/dawn/ui/UIEmpty.cpp index 67ea5a5e..62e4924c 100644 --- a/src/dawnpokergame/ui/PokerGameTextbox.cpp +++ b/src/dawn/ui/UIEmpty.cpp @@ -3,10 +3,14 @@ // This software is released under the MIT License. // https://opensource.org/licenses/MIT -#include "PokerGameTextbox.hpp" +#include "UIEmpty.hpp" using namespace Dawn; -std::shared_ptr PokerGameTextbox::makeTextbox() { - return nullptr; +UIEmpty::UIEmpty(UICanvas *canvas) : UIComponent(canvas) { + +} + +void UIEmpty::drawSelf(UIShader *shader, glm::mat4 selfTrans) { + } \ No newline at end of file diff --git a/src/dawn/ui/UIEmpty.hpp b/src/dawn/ui/UIEmpty.hpp new file mode 100644 index 00000000..3ddda28b --- /dev/null +++ b/src/dawn/ui/UIEmpty.hpp @@ -0,0 +1,15 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "UIComponent.hpp" + +namespace Dawn { + class UIEmpty : public UIComponent { + public: + UIEmpty(UICanvas *canvas); + void drawSelf(UIShader *uiShader, glm::mat4 selfTransform) override; + }; +} \ No newline at end of file diff --git a/src/dawn/ui/UILabel.cpp b/src/dawn/ui/UILabel.cpp index 822ffcbf..fbe08f71 100644 --- a/src/dawn/ui/UILabel.cpp +++ b/src/dawn/ui/UILabel.cpp @@ -18,7 +18,7 @@ void UILabel::updatePositions() { void UILabel::updateMesh() { if(!this->needsRebuffering) return; - if(this->font == nullptr) return; + if(this->font == nullptr || !this->font->isReady()) return; if(this->text.size() == 0) return; float_t width = this->getWidth(); diff --git a/src/dawn/visualnovel/CMakeLists.txt b/src/dawn/visualnovel/CMakeLists.txt index f980f8a5..36ed345f 100644 --- a/src/dawn/visualnovel/CMakeLists.txt +++ b/src/dawn/visualnovel/CMakeLists.txt @@ -10,4 +10,5 @@ target_sources(${DAWN_TARGET_NAME} ) # Subdirs +add_subdirectory(events) add_subdirectory(ui) \ No newline at end of file diff --git a/src/dawn/visualnovel/VisualNovelManager.cpp b/src/dawn/visualnovel/VisualNovelManager.cpp index 8e2b8e12..12cfdbe8 100644 --- a/src/dawn/visualnovel/VisualNovelManager.cpp +++ b/src/dawn/visualnovel/VisualNovelManager.cpp @@ -7,6 +7,72 @@ using namespace Dawn; -VisualNovelManager::VisualNovelManager() { +VisualNovelManager::VisualNovelManager(SceneItem *item) : + SceneItemComponent(item) +{ + this->uiCanvas = nullptr; + this->textBox = nullptr; +} + +void VisualNovelManager::onStart() { + SceneItemComponent::onStart(); + + this->uiCanvas = getScene()->findComponent(); + assertNotNull(this->uiCanvas); + this->textBox = this->uiCanvas->findElement(); + assertNotNull(this->textBox); + + this->getScene()->eventSceneUnpausedUpdate.addListener(this, &VisualNovelManager::onUnpausedUpdate); +} + +void VisualNovelManager::onUnpausedUpdate() { + if(this->currentEvent == nullptr) return; + + if(!this->currentEvent->hasStarted) { + this->currentEvent->start(); + } + + if(this->currentEvent->update()) return; + auto oldCurrent = this->currentEvent; + this->currentEvent = this->currentEvent->end(); + delete oldCurrent; +} + +VisualNovelManager::~VisualNovelManager() { + if(this->currentEvent != nullptr) { + delete this->currentEvent; + } + this->getScene()->eventSceneUnpausedUpdate.removeListener(this, &VisualNovelManager::onUnpausedUpdate); +} + +// Visual Novel Event +IVisualNovelEvent::IVisualNovelEvent(VisualNovelManager *man) { + assertNotNull(man); + this->manager = man; +} + +void IVisualNovelEvent::start() { + this->onStart(); + this->hasStarted = true; +} + +bool_t IVisualNovelEvent::update() { + return this->onUpdate(); +} + +IVisualNovelEvent * IVisualNovelEvent::end() { + this->onEnd(); + + if(this->doNext != nullptr) { + auto next = this->doNext; + this->doNext = nullptr; + return next; + } +} + +IVisualNovelEvent::~IVisualNovelEvent() { + if(this->doNext != nullptr) { + delete this->doNext; + } } \ No newline at end of file diff --git a/src/dawn/visualnovel/VisualNovelManager.hpp b/src/dawn/visualnovel/VisualNovelManager.hpp index 37820e5c..9e031840 100644 --- a/src/dawn/visualnovel/VisualNovelManager.hpp +++ b/src/dawn/visualnovel/VisualNovelManager.hpp @@ -4,13 +4,84 @@ // https://opensource.org/licenses/MIT #pragma once -#include "dawnlibs.hpp" +#include "scene/SceneItemComponent.hpp" +#include "visualnovel/ui/VisualNovelTextbox.hpp" namespace Dawn { - class VisualNovelManager { - protected: + class IVisualNovelEvent; + + class VisualNovelManager : public SceneItemComponent { + private: + UICanvas *uiCanvas; + IVisualNovelEvent* currentEvent = nullptr; + + /** Event listener for unpaused scene updates. */ + void onUnpausedUpdate(); public: - VisualNovelManager(); + VisualNovelTextbox *textBox; + /** + * Constructs a visual novel manager, scene item component. + * + * @param item Item that the VN manager belongs to. + */ + VisualNovelManager(SceneItem *item); + + /** + * Sets the currently active visual novel event. This is assumed to be + * the only way to handle events (no multiples currently). + * + * @param event Event to set. + */ + template + T * setEvent(T *event) { + assertNotNull(event); + this->currentEvent = event; + return event; + } + + /** + * Override to the SceneItemComponent on start event. + * + */ + void onStart() override; + + /** + * Dispose / Cleanup the VN manager. + * + */ + ~VisualNovelManager(); + + friend class IVisualNovelEvent; + }; + + + class IVisualNovelEvent { + protected: + VisualNovelManager *manager; + IVisualNovelEvent *doNext = nullptr; + bool_t hasStarted; + + virtual void onStart() = 0; + virtual bool_t onUpdate() = 0; + virtual void onEnd() = 0; + + public: + IVisualNovelEvent(VisualNovelManager *manager); + + template + T * then(T *next) { + assertNotNull(next); + this->doNext = next; + return next; + } + + void start(); + bool_t update(); + IVisualNovelEvent * end(); + + virtual ~IVisualNovelEvent(); + + friend class VisualNovelManager; }; } \ No newline at end of file diff --git a/src/dawn/visualnovel/events/CMakeLists.txt b/src/dawn/visualnovel/events/CMakeLists.txt new file mode 100644 index 00000000..5389d80d --- /dev/null +++ b/src/dawn/visualnovel/events/CMakeLists.txt @@ -0,0 +1,10 @@ +# 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 + VisualNovelTextboxEvent.cpp +) \ No newline at end of file diff --git a/src/dawn/visualnovel/events/VisualNovelTextboxEvent.cpp b/src/dawn/visualnovel/events/VisualNovelTextboxEvent.cpp new file mode 100644 index 00000000..8d199a86 --- /dev/null +++ b/src/dawn/visualnovel/events/VisualNovelTextboxEvent.cpp @@ -0,0 +1,28 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "VisualNovelTextboxEvent.hpp" + +using namespace Dawn; + +VisualNovelTextboxEvent::VisualNovelTextboxEvent( + VisualNovelManager *manager, + std::string text +) : IVisualNovelEvent(manager) { + this->text = text; +} + +void VisualNovelTextboxEvent::onStart() { + this->manager->textBox->setText(this->text); + this->manager->textBox->show(); +} + +bool_t VisualNovelTextboxEvent::onUpdate() { + return this->manager->textBox->isVisible(); +} + +void VisualNovelTextboxEvent::onEnd() { + +} \ No newline at end of file diff --git a/src/dawn/visualnovel/events/VisualNovelTextboxEvent.hpp b/src/dawn/visualnovel/events/VisualNovelTextboxEvent.hpp new file mode 100644 index 00000000..625b1e90 --- /dev/null +++ b/src/dawn/visualnovel/events/VisualNovelTextboxEvent.hpp @@ -0,0 +1,24 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "visualnovel/VisualNovelManager.hpp" + +namespace Dawn { + class VisualNovelTextboxEvent : public IVisualNovelEvent { + protected: + std::string text; + + void onStart() override; + bool_t onUpdate() override; + void onEnd() override; + + public: + VisualNovelTextboxEvent( + VisualNovelManager *manager, + std::string text + ); + }; +} \ No newline at end of file diff --git a/src/dawn/visualnovel/ui/VisualNovelTextbox.cpp b/src/dawn/visualnovel/ui/VisualNovelTextbox.cpp index caf47257..aea30aff 100644 --- a/src/dawn/visualnovel/ui/VisualNovelTextbox.cpp +++ b/src/dawn/visualnovel/ui/VisualNovelTextbox.cpp @@ -10,14 +10,27 @@ using namespace Dawn; VisualNovelTextbox::VisualNovelTextbox(UICanvas *canvas) : UIComponent(canvas), + selfParent(canvas), border(canvas), label(canvas) { + // Self Parent + this->selfParent.setTransform( + UI_COMPONENT_ALIGN_STRETCH, UI_COMPONENT_ALIGN_STRETCH, + glm::vec4(0, 0, 0, 0), + 0.0f + ); + // Border - this->addChild(&this->border); + this->selfParent.addChild(&this->border); + this->border.setTransform( + UI_COMPONENT_ALIGN_STRETCH, UI_COMPONENT_ALIGN_STRETCH, + glm::vec4(0, 0, 0, 0), + 0.0f + ); // Label - this->addChild(&this->label); + this->selfParent.addChild(&this->label); this->label.startQuad = 0; this->label.quadCount = 0; @@ -26,18 +39,30 @@ VisualNovelTextbox::VisualNovelTextbox(UICanvas *canvas) : ); } +void VisualNovelTextbox::show() { + if(this->isVisible()) return; + this->visible = true; + this->addChild(&this->selfParent); + std::cout << "Showing" << std::endl; +} + +void VisualNovelTextbox::hide() { + if(!this->isVisible()) return; + this->visible = false; + this->removeChild(&this->selfParent); + this->eventHidden.invoke(); +} + +bool_t VisualNovelTextbox::isVisible() { + return this->visible; +} + void VisualNovelTextbox::updatePositions() { UIComponent::updatePositions(); this->lineCurrent = 0; this->timeCharacter = 0; - this->border.setTransform( - UI_COMPONENT_ALIGN_STRETCH, UI_COMPONENT_ALIGN_STRETCH, - glm::vec4(0, 0, 0, 0), - 0.0f - ); - this->label.setTransform( UI_COMPONENT_ALIGN_STRETCH, UI_COMPONENT_ALIGN_STRETCH, @@ -58,7 +83,7 @@ void VisualNovelTextbox::textboxOnSceneUpdate() { if(this->hasRevealedAllCurrentCharacters()) { if(this->hasRevealedAllCharacters()) { if(game->inputManager.isPressed(INPUT_BIND_ACCEPT)) { - this->eventClose.invoke(); + this->hide(); } } else { if(game->inputManager.isPressed(INPUT_BIND_ACCEPT)) { @@ -114,7 +139,9 @@ int32_t VisualNovelTextbox::getCountOfVisibleLines() { return this->label.measure.getLineCount(); } -void VisualNovelTextbox::drawSelf(UIShader *shader, glm::mat4 self) {} +void VisualNovelTextbox::drawSelf(UIShader *shader, glm::mat4 self) { + +} void VisualNovelTextbox::setBorder(Texture *texture, glm::vec2 dimensions) { this->border.texture = texture; @@ -133,6 +160,21 @@ void VisualNovelTextbox::setText(std::string text, float_t fontSize) { this->label.updateMesh(); } +void VisualNovelTextbox::setText(std::string text) { + this->label.setText(text); + this->label.updateMesh(); +} + +void VisualNovelTextbox::setFontSize(float_t fontSize) { + this->label.setFontSize(fontSize); + this->label.updateMesh(); +} + +void VisualNovelTextbox::setLabelPadding(glm::vec2 padding) { + this->labelPadding = padding; + this->updatePositions(); +} + bool_t VisualNovelTextbox::hasRevealedAllCurrentCharacters() { int32_t quadsTotal = 0; for( diff --git a/src/dawn/visualnovel/ui/VisualNovelTextbox.hpp b/src/dawn/visualnovel/ui/VisualNovelTextbox.hpp index a5e5d441..6ef73bb7 100644 --- a/src/dawn/visualnovel/ui/VisualNovelTextbox.hpp +++ b/src/dawn/visualnovel/ui/VisualNovelTextbox.hpp @@ -7,6 +7,7 @@ #include "ui/UISprite.hpp" #include "ui/UIBorder.hpp" #include "ui/UILabel.hpp" +#include "ui/UIEmpty.hpp" #include "util/mathutils.hpp" #define VISUAL_NOVEL_TEXTBOX_SPEED 25.0f @@ -17,9 +18,11 @@ namespace Dawn { private: int32_t lineCurrent = 0; glm::vec2 labelPadding = glm::vec2(0, 0); + UIEmpty selfParent; UIBorder border; UILabel label; float_t timeCharacter = 0.0f; + bool_t visible = false; void updatePositions() override; void drawSelf(UIShader *shader, glm::mat4 selfTransform) override; @@ -42,7 +45,8 @@ namespace Dawn { Event<> eventCurrentCharactersRevealed; Event<> eventNewPage; Event<> eventAllCharactersRevealed; - Event<> eventClose; + Event<> eventHidden; + Event<> eventVisible; /** * Constructs a VN Textbox. @@ -51,6 +55,10 @@ namespace Dawn { */ VisualNovelTextbox(UICanvas *canvas); + void show(); + void hide(); + bool_t isVisible(); + /** * Sets the font for this vn textbox. Passed to the underlying label. * @@ -74,6 +82,28 @@ namespace Dawn { */ void setText(std::string text, float_t fontSize); + /** + * Sets the string (label) for this textbox. + * + * @param text Text to set. + */ + void setText(std::string text); + + /** + * Sets the font size to use. + * + * @param fontSize Font size to use. + */ + void setFontSize(float_t fontSize); + + /** + * Sets the padding of the label. This will increase the spacing between + * the text and the border. + * + * @param padding Padding to set. + */ + void setLabelPadding(glm::vec2 padding); + /** * Returns true if all of the characters that can be made visible for the * current textbox size have finished revealing, or false if not. diff --git a/src/dawnopengl/display/Texture.cpp b/src/dawnopengl/display/Texture.cpp index a59cb3a3..c905b445 100644 --- a/src/dawnopengl/display/Texture.cpp +++ b/src/dawnopengl/display/Texture.cpp @@ -1,76 +1,76 @@ -// Copyright (c) 2022 Dominic Masters -// -// This software is released under the MIT License. -// https://opensource.org/licenses/MIT - -#include "Texture.hpp" - -using namespace Dawn; - -void Texture::bind(textureslot_t slot) { - if(this->id == -1) throw "Texture has not been initialized, cannot bind."; - glActiveTexture(GL_TEXTURE0 + slot); - glBindTexture(GL_TEXTURE_2D, this->id); -} - -int32_t Texture::getWidth() { - return this->width; -} - -int32_t Texture::getHeight() { - return this->height; -} - -void Texture::setSize(int32_t width, int32_t height) { - if(this->id != -1) glDeleteTextures(1, &this->id); - - this->width = width; - this->height = height; - - glGenTextures(1, &this->id); - if(this->id <= 0) throw "Texture generation failed!"; - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, this->id); - - // Setup our preferred texture params, later this will be configurable. - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - - // Initialize the texture to blank - glTexImage2D( - GL_TEXTURE_2D, 0, GL_RGBA, - width, height, - 0, GL_RGBA, GL_FLOAT, NULL - ); -} - -void Texture::fill(struct Color color) { - struct Color *pixels = (struct Color *)memoryAllocate( - sizeof(struct Color) * this->width * this->height - ); - - this->buffer(pixels); - - memoryFree(pixels); -} - -bool_t Texture::isReady() { - return this->id != -1; -} - -void Texture::buffer(struct Color pixels[]) { - glBindTexture(GL_TEXTURE_2D, this->id); - - glTexImage2D( - GL_TEXTURE_2D, 0, GL_RGBA, - this->width, this->height, - 0, GL_RGBA, GL_FLOAT, (void *)pixels - ); -} - -Texture::~Texture() { - if(this->id != -1) glDeleteTextures(1, &this->id); +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#include "Texture.hpp" + +using namespace Dawn; + +void Texture::bind(textureslot_t slot) { + assertTrue(this->id != -1); + glActiveTexture(GL_TEXTURE0 + slot); + glBindTexture(GL_TEXTURE_2D, this->id); +} + +int32_t Texture::getWidth() { + return this->width; +} + +int32_t Texture::getHeight() { + return this->height; +} + +void Texture::setSize(int32_t width, int32_t height) { + if(this->id != -1) glDeleteTextures(1, &this->id); + + this->width = width; + this->height = height; + + glGenTextures(1, &this->id); + if(this->id <= 0) throw "Texture generation failed!"; + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, this->id); + + // Setup our preferred texture params, later this will be configurable. + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + // Initialize the texture to blank + glTexImage2D( + GL_TEXTURE_2D, 0, GL_RGBA, + width, height, + 0, GL_RGBA, GL_FLOAT, NULL + ); +} + +void Texture::fill(struct Color color) { + struct Color *pixels = (struct Color *)memoryAllocate( + sizeof(struct Color) * this->width * this->height + ); + + this->buffer(pixels); + + memoryFree(pixels); +} + +bool_t Texture::isReady() { + return this->id != -1; +} + +void Texture::buffer(struct Color pixels[]) { + glBindTexture(GL_TEXTURE_2D, this->id); + + glTexImage2D( + GL_TEXTURE_2D, 0, GL_RGBA, + this->width, this->height, + 0, GL_RGBA, GL_FLOAT, (void *)pixels + ); +} + +Texture::~Texture() { + if(this->id != -1) glDeleteTextures(1, &this->id); } \ No newline at end of file diff --git a/src/dawnopengl/display/Texture.hpp b/src/dawnopengl/display/Texture.hpp index 4cd54194..58ef8271 100644 --- a/src/dawnopengl/display/Texture.hpp +++ b/src/dawnopengl/display/Texture.hpp @@ -5,6 +5,7 @@ #pragma once #include "dawnopengl.hpp" +#include "assert/assert.hpp" #include "display/_Texture.hpp" #include "util/memory.hpp" diff --git a/src/dawnopengl/display/shader/UIShader.hpp b/src/dawnopengl/display/shader/UIShader.hpp index 092ed523..7fc5a7cd 100644 --- a/src/dawnopengl/display/shader/UIShader.hpp +++ b/src/dawnopengl/display/shader/UIShader.hpp @@ -45,7 +45,7 @@ namespace Dawn { shaderparameter_t param, Texture *texture ) override { - if(texture == nullptr) { + if(texture == nullptr || !texture->isReady()) { this->setBoolean(this->paramHasTexture, false); } else { this->setBoolean(this->paramHasTexture, true); diff --git a/src/dawnpokergame/game/DawnGame.cpp b/src/dawnpokergame/game/DawnGame.cpp index f9052b61..bb22fe5e 100644 --- a/src/dawnpokergame/game/DawnGame.cpp +++ b/src/dawnpokergame/game/DawnGame.cpp @@ -4,9 +4,7 @@ // https://opensource.org/licenses/MIT #include "DawnGame.hpp" -#include "asset/assets/TextureAsset.hpp" -#include "asset/assets/TrueTypeAsset.hpp" -#include "visualnovel/ui/VisualNovelTextbox.hpp" +#include "scenes/TestScene.hpp" using namespace Dawn; @@ -24,30 +22,7 @@ int32_t DawnGame::init() { this->assetManager.init(); this->renderManager.init(); - this->scene = new Scene(this); - - auto cameraObject = this->scene->createSceneItem(); - auto camera = cameraObject->addComponent(); - camera->transform->lookAt(glm::vec3(50, 50, 50), glm::vec3(0, 0, 0)); - - auto canvas = UICanvas::createCanvas(this->scene); - - assetFont = this->assetManager.load("truetype_ark"); - assetTexture = this->assetManager.load("texture_test"); - while(!assetFont->loaded || !assetTexture->loaded) { - this->assetManager.update(); - } - - auto textbox = canvas->addElement(); - textbox->setBorder(&assetTexture->texture, glm::vec2(16, 16)); - textbox->setFont(&assetFont->font); - textbox->setText("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus leo odio, egestas nec imperdiet ac, placerat eget quam. Nam tellus justo, aliquam sed porta quis, ullamcorper in libero. Proin auctor eget elit nec rutrum. Vestibulum tincidunt sem vel nisi sagittis, sed imperdiet eros aliquet. Fusce a ultrices augue, at auctor lacus. Sed lobortis, ante vitae vehicula egestas, lorem turpis cursus dui, sit amet egestas mauris ligula non ipsum. Pellentesque scelerisque posuere lorem sit amet tempor. Praesent ac hendrerit mi. Nulla mollis diam vitae vestibulum aliquam. Nullam metus justo, viverra sed risus eu, tincidunt sodales lacus. Quisque efficitur accumsan posuere. Aliquam posuere volutpat diam quis lacinia. Nullam blandit nulla vestibulum mi placerat varius. Proin egestas lacus nec pellentesque iaculis. Vestibulum ex metus, congue in eleifend et, scelerisque a nulla. Pellentesque cursus lectus sed arcu efficitur tincidunt. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Nulla a felis non velit fermentum ullamcorper.", 40); - textbox->setTransform( - UI_COMPONENT_ALIGN_STRETCH, UI_COMPONENT_ALIGN_END, - glm::vec4(0, 0, 0, 0), - 0.0f - ); - textbox + this->scene = TestScene::create(this); return DAWN_GAME_INIT_RESULT_SUCCESS; } diff --git a/src/dawnpokergame/scenes/TestScene.hpp b/src/dawnpokergame/scenes/TestScene.hpp new file mode 100644 index 00000000..f83efef2 --- /dev/null +++ b/src/dawnpokergame/scenes/TestScene.hpp @@ -0,0 +1,40 @@ +// Copyright (c) 2022 Dominic Masters +// +// This software is released under the MIT License. +// https://opensource.org/licenses/MIT + +#pragma once +#include "scene/Scene.hpp" +#include "game/DawnGame.hpp" +#include "scene/components/Components.hpp" +#include "ui/PokerGameTextbox.hpp" +#include "visualnovel/VisualNovelManager.hpp" +#include "visualnovel/events/VisualNovelTextboxEvent.hpp" + +namespace Dawn { + class TestScene { + public: + static Scene * create(DawnGame *game) { + Scene *scene = new Scene(game); + + // Camera + auto camera = Camera::create(scene); + camera->transform->lookAt(glm::vec3(50, 50, 50), glm::vec3(0, 0, 0)); + + // UI + auto canvas = UICanvas::createCanvas(scene); + auto textbox = PokerGameTextbox::create(canvas); + + // VN Manager + auto item = scene->createSceneItem(); + auto vnManager = item->addComponent(); + + vnManager + ->setEvent(new VisualNovelTextboxEvent(vnManager, "Bruh event")) + ->then(new VisualNovelTextboxEvent(vnManager, "Bruh event 2")) + ; + + return scene; + } + }; +} \ No newline at end of file diff --git a/src/dawnpokergame/ui/CMakeLists.txt b/src/dawnpokergame/ui/CMakeLists.txt index 9b0eeeaa..f6c594ab 100644 --- a/src/dawnpokergame/ui/CMakeLists.txt +++ b/src/dawnpokergame/ui/CMakeLists.txt @@ -4,7 +4,7 @@ # https://opensource.org/licenses/MIT # Sources -target_sources(${DAWN_TARGET_NAME} - PRIVATE - PokerGameTextbox.cpp -) \ No newline at end of file +# target_sources(${DAWN_TARGET_NAME} +# PRIVATE +# PokerGameTextbox.cpp +# ) \ No newline at end of file diff --git a/src/dawnpokergame/ui/PokerGameTextbox.hpp b/src/dawnpokergame/ui/PokerGameTextbox.hpp index 60d4a1c4..ddf1624c 100644 --- a/src/dawnpokergame/ui/PokerGameTextbox.hpp +++ b/src/dawnpokergame/ui/PokerGameTextbox.hpp @@ -5,10 +5,28 @@ #pragma once #include "visualnovel/ui/VisualNovelTextbox.hpp" +#include "asset/assets/TextureAsset.hpp" +#include "asset/assets/TrueTypeAsset.hpp" namespace Dawn { class PokerGameTextbox { public: - static std::shared_ptr makeTextbox(); + static VisualNovelTextbox * create(UICanvas *canvas) { + auto textbox = canvas->addElement(); + + auto assetFont = canvas->getGame()->assetManager.load("truetype_ark"); + auto assetTexture = canvas->getGame()->assetManager.load("texture_test"); + + textbox->setBorder(&assetTexture->texture, glm::vec2(16, 16)); + textbox->setFont(&assetFont->font); + textbox->setFontSize(40); + textbox->setLabelPadding(glm::vec2(10, 8)); + textbox->setTransform( + UI_COMPONENT_ALIGN_STRETCH, UI_COMPONENT_ALIGN_END, + glm::vec4(0, 238, 0, 0), + 0.0f + ); + return textbox; + } }; } \ No newline at end of file