From f6be36741c4aa2eace745bb1768c33c8c3c5a606 Mon Sep 17 00:00:00 2001 From: Gary Talent Date: Sat, 29 Jan 2022 21:53:48 -0600 Subject: [PATCH] [nostalgia/core/studio] Add pixel outline to tile sheet editor --- src/nostalgia/core/color.hpp | 10 +++ src/nostalgia/core/studio/tilesheeteditor.hpp | 20 +++--- .../core/studio/tilesheetpixelgrid.cpp | 64 +++++++++++-------- .../core/studio/tilesheetpixelgrid.hpp | 48 +++++++------- 4 files changed, 81 insertions(+), 61 deletions(-) diff --git a/src/nostalgia/core/color.hpp b/src/nostalgia/core/color.hpp index 15d90f5d..6f6c6d16 100644 --- a/src/nostalgia/core/color.hpp +++ b/src/nostalgia/core/color.hpp @@ -86,6 +86,16 @@ constexpr uint8_t blue32(Color32 c) noexcept { return (c & 0x00ff0000) >> 16; } +[[nodiscard]] +constexpr Color32 color32(uint8_t r, uint8_t g, uint8_t b) noexcept { + return static_cast(r | (g << 8) | (b << 16)); +} + +[[nodiscard]] +constexpr Color32 color32(float r, float g, float b) noexcept { + return static_cast(static_cast(r * 255) | (static_cast(g * 255) << 8) | (static_cast(b * 255) << 16)); +} + [[nodiscard]] constexpr float redf(Color16 c) noexcept { diff --git a/src/nostalgia/core/studio/tilesheeteditor.hpp b/src/nostalgia/core/studio/tilesheeteditor.hpp index 73681153..13c0d9db 100644 --- a/src/nostalgia/core/studio/tilesheeteditor.hpp +++ b/src/nostalgia/core/studio/tilesheeteditor.hpp @@ -4,6 +4,8 @@ #pragma once +#include + #include #include #include @@ -20,7 +22,7 @@ enum class CommandId { ModPixel = 2, UpdateDimension = 3, InsertTile = 4, - ClipboardPaste = 4, + ClipboardPaste = 5, }; enum class TileSheetTool: int { @@ -49,20 +51,16 @@ struct PixelChunk { int size = 0; }; -template -constexpr ox::Error model(T *io, PixelChunk *c) noexcept { - io->template setTypeInfo(); - oxReturnError(io->field("pt", &c->pt)); - oxReturnError(io->field("size", &c->size)); - return OxError(0); -} +oxModelBegin(PixelChunk) + oxModelField(pt) + oxModelField(size) +oxModelEnd() struct TileSheetClipboard { static constexpr auto TypeName = "net.drinkingtea.nostalgia.core.studio.TileSheetClipboard"; static constexpr auto TypeVersion = 1; - template - friend ox::Error model(T*, TileSheetClipboard*); + oxModelFriend(TileSheetClipboard); protected: ox::Vector m_pixels; @@ -158,4 +156,4 @@ class TileSheetEditor: public studio::Editor { }; -} \ No newline at end of file +} diff --git a/src/nostalgia/core/studio/tilesheetpixelgrid.cpp b/src/nostalgia/core/studio/tilesheetpixelgrid.cpp index b87260cd..8c805608 100644 --- a/src/nostalgia/core/studio/tilesheetpixelgrid.cpp +++ b/src/nostalgia/core/studio/tilesheetpixelgrid.cpp @@ -15,24 +15,23 @@ ox::Error TileSheetGrid::buildShader() noexcept { } void TileSheetGrid::draw(bool update) noexcept { + glLineWidth(3); glUseProgram(m_shader); glBindVertexArray(m_bufferSet.vao); if (update) { glutils::sendVbo(m_bufferSet); } - glDrawElements(GL_POINTS, static_cast(m_bufferSet.elements.size()), GL_UNSIGNED_INT, nullptr); + glDrawArrays(GL_POINTS, 0, m_bufferSet.vertices.size() / VertexVboRowLength); } void TileSheetGrid::initBufferSet(const NostalgiaGraphic &img) noexcept { // vao m_bufferSet.vao = glutils::generateVertexArrayObject(); glBindVertexArray(m_bufferSet.vao); - // vbo & ebo + // vbo m_bufferSet.vbo = glutils::generateBuffer(); - m_bufferSet.ebo = glutils::generateBuffer(); setBufferObjects(img, &m_bufferSet); glutils::sendVbo(m_bufferSet); - glutils::sendEbo(m_bufferSet); // vbo layout const auto pt1Attr = static_cast(glGetAttribLocation(m_shader, "vPt1")); glEnableVertexAttribArray(pt1Attr); @@ -41,41 +40,54 @@ void TileSheetGrid::initBufferSet(const NostalgiaGraphic &img) noexcept { glEnableVertexAttribArray(pt2Attr); glVertexAttribPointer(pt2Attr, 2, GL_FLOAT, GL_FALSE, VertexVboRowLength * sizeof(float), reinterpret_cast(2 * sizeof(float))); + const auto colorAttr = static_cast(glGetAttribLocation(m_shader, "vColor")); + glEnableVertexAttribArray(colorAttr); + glVertexAttribPointer(colorAttr, 3, GL_FLOAT, GL_FALSE, VertexVboRowLength * sizeof(float), + reinterpret_cast(4 * sizeof(float))); } -void TileSheetGrid::setBufferObject(unsigned vertexRow, common::Point pt1, common::Point pt2, float *vbo, GLuint *ebo) noexcept { - const auto ps = pixelSize(); - const auto x1 = static_cast(pt1.x) * ps.x; - const auto y1 = static_cast(pt1.y) * ps.y; - const auto x2 = static_cast(pt2.x) * ps.x; - const auto y2 = static_cast(pt2.y) * ps.y; - // don't worry, these memcpys gets optimized to something much more ideal - const float vertices[VertexVboLength] = {x1, y1, x2, y2}; +void TileSheetGrid::setBufferObject(common::Point pt1, common::Point pt2, Color32 c, float *vbo, const ImVec2 &pixSize) noexcept { + const auto x1 = static_cast(pt1.x) * pixSize.x - 1.f; + const auto y1 = 1.f - static_cast(pt1.y) * pixSize.y; + const auto x2 = static_cast(pt2.x) * pixSize.x - 1.f; + const auto y2 = 1.f - static_cast(pt2.y) * pixSize.y; + // don't worry, this memcpy gets optimized to something much more ideal + const float vertices[VertexVboLength] = {x1, y1, x2, y2, redf(c), greenf(c), bluef(c)}; memcpy(vbo, vertices, sizeof(vertices)); - const GLuint elms[VertexEboLength] = {vertexRow}; - memcpy(ebo, elms, sizeof(elms)); } void TileSheetGrid::setBufferObjects(const NostalgiaGraphic &img, glutils::BufferSet *bg) noexcept { - const auto set = [bg](unsigned i, common::Point pt1, common::Point pt2) { + const auto pixSize = pixelSize(); + const auto set = [bg, pixSize](unsigned i, common::Point pt1, common::Point pt2, Color32 c) { const auto vbo = &bg->vertices[i * VertexVboLength]; - const auto ebo = &bg->elements[i * VertexEboLength]; - setBufferObject(i * VertexVboRows, pt1, pt2, vbo, ebo); + setBufferObject(pt1, pt2, c, vbo, pixSize); }; - // set buffer lengths + // set buffer length const auto width = img.columns * TileWidth; const auto height = img.rows * TileHeight; - const auto tiles = static_cast(width * height); - m_bufferSet.vertices.resize(tiles * VertexVboLength); - m_bufferSet.elements.resize(tiles * VertexEboLength); - // set buffers + const auto pixelCnt = static_cast(width * height); + const auto tileCnt = static_cast(img.columns * img.rows); + m_bufferSet.vertices.resize((tileCnt + pixelCnt) * VertexVboLength); + // set buffer auto i = 0ull; - for (auto x = 0; x < img.columns; ++x) { - set(0, {x, 0}, {x, img.rows}); + // pixel outlines + constexpr auto pixOutlineColor = color32(0.4431f, 0.4901f, 0.4941f); + for (auto x = 0; x < img.columns * TileWidth + 1; ++x) { + set(i, {x, 0}, {x, img.rows * TileHeight}, pixOutlineColor); ++i; } - for (auto y = 0; y < img.rows; ++y) { - set(0, {0, y}, {img.columns, y}); + for (auto y = 0; y < img.rows * TileHeight + 1; ++y) { + set(i, {0, y}, {img.columns * TileWidth, y}, pixOutlineColor); + ++i; + } + // tile outlines + constexpr auto tileOutlineColor = color32(0.f, 0.f, 0.f); + for (auto x = 0; x < img.columns * TileWidth + 1; x += TileWidth) { + set(i, {x, 0}, {x, img.rows * TileHeight}, tileOutlineColor); + ++i; + } + for (auto y = 0; y < img.rows * TileHeight + 1; y += TileHeight) { + set(i, {0, y}, {img.columns * TileWidth, y}, tileOutlineColor); ++i; } } diff --git a/src/nostalgia/core/studio/tilesheetpixelgrid.hpp b/src/nostalgia/core/studio/tilesheetpixelgrid.hpp index 6a523f5e..992c4894 100644 --- a/src/nostalgia/core/studio/tilesheetpixelgrid.hpp +++ b/src/nostalgia/core/studio/tilesheetpixelgrid.hpp @@ -17,45 +17,45 @@ class TileSheetGrid { private: static constexpr auto VertexVboRows = 1; - static constexpr auto VertexVboRowLength = 4; + static constexpr auto VertexVboRowLength = 7; static constexpr auto VertexVboLength = VertexVboRows * VertexVboRowLength; - static constexpr auto VertexEboLength = 1; - static constexpr auto VShad = R"( + static constexpr auto VShad = R"glsl( {} in vec2 vPt1; in vec2 vPt2; - out VS_OUT { - vec2 pt1; - vec2 pt2; - } vs_out; + in vec3 vColor; + out vec2 gPt2; + out vec3 gColor; void main() { - vs_out.pt1 = vPt1; - vs_out.pt2 = vPt2; + gColor = vColor; gl_Position = vec4(vPt1, 0.0, 1.0); - })"; + gPt2 = vPt2; + })glsl"; - static constexpr auto FShad = R"( + static constexpr auto FShad = R"glsl( {} in vec3 fColor; out vec4 outColor; void main() { - outColor = vec4(0.4431, 0.4901, 0.4941, 1.0); - })"; + outColor = vec4(fColor, 1); + //outColor = vec4(0.4431, 0.4901, 0.4941, 1.0); + })glsl"; static constexpr auto GShad = R"glsl( {} - in VS_OUT { - vec2 pt1; - vec2 pt2; - } gs_in[]; - layout(line_strip, max_vertices = 2) out; + layout(points) in; + layout(line_strip, max_vertices = 9) out; + in vec3 gColor[]; + in vec2 gPt2[]; + out vec3 fColor; void main() { - //gl_Position = vec4(gs_in[0].pt1, 0, 0); - //EmitVertex(); - //gl_Position = vec4(gs_in[0].pt2, 0, 0); - //EmitVertex(); - //EndPrimitive(); + fColor = gColor[0]; + gl_Position = gl_in[0].gl_Position; + EmitVertex(); + gl_Position = vec4(gPt2[0], 0, 1); + EmitVertex(); + EndPrimitive(); })glsl"; glutils::GLProgram m_shader; @@ -69,7 +69,7 @@ class TileSheetGrid { void initBufferSet(const NostalgiaGraphic &img) noexcept; private: - static void setBufferObject(unsigned vertexRow, common::Point pt1, common::Point pt2, float *vbo, GLuint *ebo) noexcept; + static void setBufferObject(common::Point pt1, common::Point pt2, Color32 c, float *vbo, const ImVec2 &pixSize) noexcept; void setBufferObjects(const NostalgiaGraphic &img, glutils::BufferSet *bg) noexcept;