diff --git a/src/files/settings_io.cpp b/src/files/settings_io.cpp index 987c33f6..3cfe3bc4 100644 --- a/src/files/settings_io.cpp +++ b/src/files/settings_io.cpp @@ -90,7 +90,7 @@ void SettingsHandler::setValue(const std::string& name, dynamic::Value value) { if (auto number = dynamic_cast(setting)) { set_numeric_value(number, value); } else if (auto integer = dynamic_cast(setting)) { - set_numeric_value(number, value); + set_numeric_value(integer, value); } else if (auto flag = dynamic_cast(setting)) { set_numeric_value(flag, value); } else { diff --git a/src/frontend/hud.cpp b/src/frontend/hud.cpp index b4c268a6..9f379df9 100644 --- a/src/frontend/hud.cpp +++ b/src/frontend/hud.cpp @@ -18,6 +18,7 @@ #include "../graphics/ui/elements/containers.h" #include "../graphics/ui/elements/controls.h" #include "../graphics/ui/elements/UINode.h" +#include "../graphics/ui/elements/Plotter.hpp" #include "../graphics/ui/GUI.h" #include "../items/Inventories.h" #include "../items/Inventory.h" @@ -60,43 +61,6 @@ extern std::shared_ptr create_debug_panel( Player* player ); -class DeltaGrapher : public gui::UINode { - std::unique_ptr points; - float multiplier; - int index = 0; - int dmwidth; - int dmheight; -public: - DeltaGrapher(uint width, uint height, float multiplier) - : gui::UINode(glm::vec2(width, height)), - multiplier(multiplier), - dmwidth(width), - dmheight(height) - { - points = std::make_unique(width); - } - - void act(float delta) override { - index = index + 1 % dmwidth; - int value = static_cast(delta * multiplier); - points[index % dmwidth] = std::min(value, dmheight); - } - - void draw(const GfxContext* pctx, Assets* assets) override { - glm::vec2 pos = calcPos(); - auto batch = pctx->getBatch2D(); - batch->texture(nullptr); - batch->lineWidth(1); - for (int i = index+1; i < index+dmwidth; i++) { - int j = i % dmwidth; - batch->line( - pos.x + i - index, pos.y + size.y - points[j], - pos.x + i - index, pos.y + size.y, 1.0f, 1.0f, 1.0f, 0.2f - ); - } - } -}; - HudElement::HudElement( hud_element_mode mode, UiDocument* document, @@ -224,9 +188,9 @@ Hud::Hud(Engine* engine, LevelFrontend* frontend, Player* player) gui->add(contentAccessPanel); gui->add(grabbedItemView); - auto dgrapher = std::make_shared(350, 250, 2000); - dgrapher->setGravity(gui::Gravity::bottom_right); - add(HudElement(hud_element_mode::permanent, nullptr, dgrapher, true)); + auto dplotter = std::make_shared(350, 250, 2000, 16); + dplotter->setGravity(gui::Gravity::bottom_right); + add(HudElement(hud_element_mode::permanent, nullptr, dplotter, true)); } Hud::~Hud() { diff --git a/src/graphics/core/Batch2D.cpp b/src/graphics/core/Batch2D.cpp index 90d4ee64..04c3ab69 100644 --- a/src/graphics/core/Batch2D.cpp +++ b/src/graphics/core/Batch2D.cpp @@ -1,6 +1,7 @@ #include "Batch2D.h" #include "Mesh.h" #include "Texture.h" +#include "gl_util.h" #include @@ -26,10 +27,19 @@ Batch2D::~Batch2D(){ delete[] buffer; } +void Batch2D::setPrimitive(DrawPrimitive primitive) { + if (primitive == this->primitive) { + return; + } + flush(); + this->primitive = primitive; +} + void Batch2D::begin(){ _texture = nullptr; blank->bind(); color = glm::vec4(1.0f); + primitive = DrawPrimitive::triangle; } void Batch2D::vertex( @@ -64,7 +74,7 @@ void Batch2D::vertex( void Batch2D::texture(Texture* new_texture){ if (_texture == new_texture) return; - flush(GL_TRIANGLES); + flush(); _texture = new_texture; if (new_texture == nullptr) blank->bind(); @@ -78,19 +88,18 @@ void Batch2D::untexture() { void Batch2D::point(float x, float y, float r, float g, float b, float a){ if (index + 6*B2D_VERTEX_SIZE >= capacity) - flush(GL_TRIANGLES); - + flush(); + setPrimitive(DrawPrimitive::point); vertex(x, y, 0, 0, r,g,b,a); - flush(GL_POINTS); } void Batch2D::line(float x1, float y1, float x2, float y2, float r, float g, float b, float a){ - if (index + 6*B2D_VERTEX_SIZE >= capacity) - flush(GL_TRIANGLES); - + if (index + 6*B2D_VERTEX_SIZE >= capacity) { + flush(); + } + setPrimitive(DrawPrimitive::line); vertex(x1, y1, 0, 0, r,g,b,a); vertex(x2, y2, 1, 1, r,g,b,a); - flush(GL_LINES); } void Batch2D::rect(float x, float y, float w, float h){ @@ -98,9 +107,10 @@ void Batch2D::rect(float x, float y, float w, float h){ const float g = color.g; const float b = color.b; const float a = color.a; - if (index + 6*B2D_VERTEX_SIZE >= capacity) - flush(GL_TRIANGLES); - + if (index + 6*B2D_VERTEX_SIZE >= capacity) { + flush(); + } + setPrimitive(DrawPrimitive::triangle); vertex(x, y, 0, 0, r,g,b,a); vertex(x, y+h, 0, 1, r,g,b,a); vertex(x+w, y+h, 1, 1, r,g,b,a); @@ -120,9 +130,10 @@ void Batch2D::rect( bool flippedY, glm::vec4 tint ) { - if (index + 6*B2D_VERTEX_SIZE >= capacity) - flush(GL_TRIANGLES); - + if (index + 6*B2D_VERTEX_SIZE >= capacity) { + flush(); + } + setPrimitive(DrawPrimitive::triangle); float centerX = w*ox; float centerY = h*oy; float acenterX = w-centerX; @@ -205,13 +216,29 @@ void Batch2D::rect( vertex(x4, y4, u4, v4, tint.r, tint.g, tint.b, tint.a); } +void Batch2D::lineRect(float x, float y, float w, float h) { + vertex(x, y, 0.0f, 0.0f, color.r, color.g, color.b, color.a); + vertex(x, y+h, 0.0f, 1.0f, color.r, color.g, color.b, color.a); + + vertex(x, y+h, 0.0f, 1.0f, color.r, color.g, color.b, color.a); + vertex(x+w, y+h, 1.0f, 1.0f, color.r, color.g, color.b, color.a); + + vertex(x+w, y+h, 1.0f, 1.0f, color.r, color.g, color.b, color.a); + vertex(x+w, y, 1.0f, 0.0f, color.r, color.g, color.b, color.a); + + vertex(x+w, y, 1.0f, 0.0f, color.r, color.g, color.b, color.a); + vertex(x, y, 0.0f, 0.0f, color.r, color.g, color.b, color.a); +} + void Batch2D::rect( float x, float y, float w, float h, float u, float v, float tx, float ty, float r, float g, float b, float a ){ - if (index + 6*B2D_VERTEX_SIZE >= capacity) - flush(GL_TRIANGLES); + if (index + 6*B2D_VERTEX_SIZE >= capacity) { + flush(); + } + setPrimitive(DrawPrimitive::triangle); vertex(x, y, u, v+ty, r,g,b,a); vertex(x+w, y+h, u+tx, v, r,g,b,a); vertex(x, y+h, u, v, r,g,b,a); @@ -229,8 +256,10 @@ void Batch2D::rect( float r3, float g3, float b3, float r4, float g4, float b4, int sh ){ - if (index + 30*B2D_VERTEX_SIZE >= capacity) - flush(GL_TRIANGLES); + if (index + 30*B2D_VERTEX_SIZE >= capacity) { + flush(); + } + setPrimitive(DrawPrimitive::triangle); glm::vec2 v0(x+h/2,y+h/2); glm::vec2 v1(x+w-sh,y); glm::vec2 v2(x+sh,y); @@ -294,18 +323,14 @@ void Batch2D::sprite(float x, float y, float w, float h, int atlasRes, int index rect(x, y, w, h, u, v, scale, scale, tint.r, tint.g, tint.b, tint.a); } -void Batch2D::flush(unsigned int gl_primitive) { +void Batch2D::flush() { if (index == 0) return; mesh->reload(buffer, index / B2D_VERTEX_SIZE); - mesh->draw(gl_primitive); + mesh->draw(gl::to_glenum(primitive)); index = 0; } -void Batch2D::flush() { - flush(GL_TRIANGLES); -} - void Batch2D::lineWidth(float width) { glLineWidth(width); } diff --git a/src/graphics/core/Batch2D.h b/src/graphics/core/Batch2D.h index 482bdb12..8eace82f 100644 --- a/src/graphics/core/Batch2D.h +++ b/src/graphics/core/Batch2D.h @@ -5,6 +5,7 @@ #include #include +#include "commons.h" #include "../../maths/UVRegion.h" class Mesh; @@ -18,6 +19,9 @@ class Batch2D { size_t index; glm::vec4 color; Texture* _texture; + DrawPrimitive primitive = DrawPrimitive::triangle; + + void setPrimitive(DrawPrimitive primitive); void vertex( float x, float y, @@ -55,6 +59,8 @@ public: float r, float g, float b, float a ); + void lineRect(float x, float y, float w, float h); + void rect( float x, float y, float w, float h, @@ -81,7 +87,6 @@ public: float r4, float g4, float b4, int sh ); - void flush(unsigned int gl_primitive); void flush(); void lineWidth(float width); diff --git a/src/graphics/core/Cubemap.cpp b/src/graphics/core/Cubemap.cpp index f6d0aba1..5dcd7a2e 100644 --- a/src/graphics/core/Cubemap.cpp +++ b/src/graphics/core/Cubemap.cpp @@ -14,7 +14,7 @@ Cubemap::Cubemap(uint width, uint height, ImageFormat imageFormat) glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameterf(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - uint format = gl::to_gl_format(imageFormat); + uint format = gl::to_glenum(imageFormat); for (uint face = 0; face < 6; face++) { glTexImage2D( GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, diff --git a/src/graphics/core/Texture.cpp b/src/graphics/core/Texture.cpp index 473c0a14..c293f6e8 100644 --- a/src/graphics/core/Texture.cpp +++ b/src/graphics/core/Texture.cpp @@ -18,7 +18,7 @@ Texture::Texture(ubyte* data, uint width, uint height, ImageFormat imageFormat) glBindTexture(GL_TEXTURE_2D, id); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - GLenum format = gl::to_gl_format(imageFormat); + GLenum format = gl::to_glenum(imageFormat); glTexImage2D( GL_TEXTURE_2D, 0, format, width, height, 0, format, GL_UNSIGNED_BYTE, (GLvoid *) data diff --git a/src/graphics/core/commons.h b/src/graphics/core/commons.h new file mode 100644 index 00000000..3a0adc37 --- /dev/null +++ b/src/graphics/core/commons.h @@ -0,0 +1,10 @@ +#ifndef GRAPHICS_CORE_COMMONS_H_ +#define GRAPHICS_CORE_COMMONS_H_ + +enum class DrawPrimitive { + point = 0, + line, + triangle, +}; + +#endif // GRAPHICS_CORE_COMMONS_H_ diff --git a/src/graphics/core/gl_util.h b/src/graphics/core/gl_util.h index 5644fa3d..5ef9ee21 100644 --- a/src/graphics/core/gl_util.h +++ b/src/graphics/core/gl_util.h @@ -1,12 +1,13 @@ #ifndef GRAPHICS_CORE_GL_UTIL_H_ #define GRAPHICS_CORE_GL_UTIL_H_ -#include - +#include "commons.h" #include "ImageData.h" +#include + namespace gl { - inline GLenum to_gl_format(ImageFormat imageFormat) { + inline GLenum to_glenum(ImageFormat imageFormat) { switch (imageFormat) { case ImageFormat::rgb888: return GL_RGB; case ImageFormat::rgba8888: return GL_RGBA; @@ -14,6 +15,15 @@ namespace gl { return 0; } } + + inline GLenum to_glenum(DrawPrimitive primitive) { + static const GLenum primitives[]{ + GL_POINTS, + GL_LINES, + GL_TRIANGLES + }; + return primitives[static_cast(primitive)]; + } } #endif // GRAPHICS_CORE_GL_UTIL_H_ diff --git a/src/graphics/ui/elements/Plotter.cpp b/src/graphics/ui/elements/Plotter.cpp new file mode 100644 index 00000000..6c20caa7 --- /dev/null +++ b/src/graphics/ui/elements/Plotter.cpp @@ -0,0 +1,52 @@ +#include "Plotter.hpp" + +#include "../../core/Batch2D.h" +#include "../../core/Font.h" +#include "../../core/GfxContext.h" +#include "../../../assets/Assets.h" +#include "../../../util/stringutil.h" + +using namespace gui; + +void Plotter::act(float delta) { + index = index + 1 % dmwidth; + int value = static_cast(delta * multiplier); + points[index % dmwidth] = std::min(value, dmheight); +} + +void Plotter::draw(const GfxContext* pctx, Assets* assets) { + glm::vec2 pos = calcPos(); + auto batch = pctx->getBatch2D(); + batch->texture(nullptr); + batch->lineWidth(1); + for (int i = index+1; i < index+dmwidth; i++) { + int j = i % dmwidth; + batch->line( + pos.x + i - index, pos.y + size.y - points[j], + pos.x + i - index, pos.y + size.y, 1.0f, 1.0f, 1.0f, 0.2f + ); + } + batch->setColor({1,1,1,0.2f}); + batch->lineRect(pos.x, pos.y, dmwidth, dmheight); + for (int y = 0; y < dmheight; y += 16) { + batch->line( + pos.x+dmwidth-4, pos.y+dmheight-y, + pos.x+dmwidth+4, pos.y+dmheight-y, + 1.0f, 1.0f, 1.0f, 0.2f + ); + } + + int current_point = static_cast(points[index % dmwidth]); + auto font = assets->getFont("normal"); + for (int y = 0; y < dmheight; y += labelsInterval) { + std::wstring string; + if (current_point/16 == y/labelsInterval) { + batch->setColor({1,1,1,0.5f}); + string = util::to_wstring(current_point / multiplier, 3); + } else { + batch->setColor({1,1,1,0.2f}); + string = util::to_wstring(y / multiplier, 3); + } + font->draw(batch, string, pos.x+dmwidth+2, pos.y+dmheight-y-labelsInterval); + } +} diff --git a/src/graphics/ui/elements/Plotter.hpp b/src/graphics/ui/elements/Plotter.hpp new file mode 100644 index 00000000..7d47ab5d --- /dev/null +++ b/src/graphics/ui/elements/Plotter.hpp @@ -0,0 +1,37 @@ +#ifndef GRAPHICS_UI_ELEMENTS_PLOTTER_HPP_ +#define GRAPHICS_UI_ELEMENTS_PLOTTER_HPP_ + +#include "UINode.h" +#include "../../../typedefs.h" + +#include +#include + +class Assets; +class GfxContext; + +namespace gui { + class Plotter : public gui::UINode { + std::unique_ptr points; + float multiplier; + int index = 0; + int dmwidth; + int dmheight; + int labelsInterval; + public: + Plotter(uint width, uint height, float multiplier, int labelsInterval) + : gui::UINode(glm::vec2(width, height)), + multiplier(multiplier), + dmwidth(width-50), + dmheight(height), + labelsInterval(labelsInterval) + { + points = std::make_unique(dmwidth); + } + + void act(float delta) override; + void draw(const GfxContext* pctx, Assets* assets) override; + }; +} + +#endif // GRAPHICS_UI_ELEMENTS_PLOTTER_HPP_ diff --git a/src/graphics/ui/elements/controls.h b/src/graphics/ui/elements/controls.h index 494566f7..1e46a786 100644 --- a/src/graphics/ui/elements/controls.h +++ b/src/graphics/ui/elements/controls.h @@ -1,6 +1,8 @@ #ifndef GRAPHICS_UI_ELEMENTS_CONTROLS_H_ #define GRAPHICS_UI_ELEMENTS_CONTROLS_H_ +// TODO: move elements to different files + #include #include #include