[nostalgia/core/studio] Add ability to select pixels for copy/paste
This commit is contained in:
parent
3486734b50
commit
b502b8cc30
@ -109,6 +109,10 @@ struct TileSheet {
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto idx(const geo::Point &pt) const noexcept {
|
||||||
|
return ptToIdx(pt, columns);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads all pixels of this sheet or its children into the given pixel list
|
* Reads all pixels of this sheet or its children into the given pixel list
|
||||||
* @param pixels
|
* @param pixels
|
||||||
|
@ -54,15 +54,28 @@ void TileSheetEditorImGui::draw(core::Context*) noexcept {
|
|||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::BeginChild("Controls", ImVec2(m_palViewWidth - 8, paneSize.y), true);
|
ImGui::BeginChild("Controls", ImVec2(m_palViewWidth - 8, paneSize.y), true);
|
||||||
{
|
{
|
||||||
|
ImGui::BeginChild("ToolBox", ImVec2(m_palViewWidth - 24, 30), true);
|
||||||
|
{
|
||||||
|
const auto btnSz = ImVec2(40, 14);
|
||||||
|
if (ImGui::Selectable("Draw", m_tool == Tool::Draw, 0, btnSz)) {
|
||||||
|
m_tool = Tool::Draw;
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Selectable("Select", m_tool == Tool::Select, 0, btnSz)) {
|
||||||
|
m_tool = Tool::Select;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndChild();
|
||||||
|
const auto ySize = paneSize.y - 36;
|
||||||
// draw palette/color picker
|
// draw palette/color picker
|
||||||
ImGui::BeginChild("child1", ImVec2(m_palViewWidth - 24, paneSize.y / 2.07f), true);
|
ImGui::BeginChild("Palette", ImVec2(m_palViewWidth - 24, ySize / 2.07f), true);
|
||||||
{
|
{
|
||||||
drawPalettePicker();
|
drawPalettePicker();
|
||||||
}
|
}
|
||||||
ImGui::EndChild();
|
ImGui::EndChild();
|
||||||
ImGui::BeginChild("child2", ImVec2(m_palViewWidth - 24, paneSize.y / 2.07f), true);
|
ImGui::BeginChild("SubSheets", ImVec2(m_palViewWidth - 24, ySize / 2.07f), true);
|
||||||
{
|
{
|
||||||
constexpr auto btnHeight = 18;
|
static constexpr auto btnHeight = 18;
|
||||||
const auto btnSize = ImVec2(18, btnHeight);
|
const auto btnSize = ImVec2(18, btnHeight);
|
||||||
if (ImGui::Button("+", btnSize)) {
|
if (ImGui::Button("+", btnSize)) {
|
||||||
auto insertOnIdx = model()->activeSubSheetIdx();
|
auto insertOnIdx = model()->activeSubSheetIdx();
|
||||||
@ -88,7 +101,7 @@ void TileSheetEditorImGui::draw(core::Context*) noexcept {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
TileSheet::SubSheetIdx path;
|
TileSheet::SubSheetIdx path;
|
||||||
constexpr auto flags = ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody;
|
static constexpr auto flags = ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody;
|
||||||
if (ImGui::BeginTable("Subsheets", 3, flags)) {
|
if (ImGui::BeginTable("Subsheets", 3, flags)) {
|
||||||
ImGui::TableSetupColumn("Subsheet", ImGuiTableColumnFlags_NoHide);
|
ImGui::TableSetupColumn("Subsheet", ImGuiTableColumnFlags_NoHide);
|
||||||
ImGui::TableSetupColumn("Columns", ImGuiTableColumnFlags_WidthFixed, 50);
|
ImGui::TableSetupColumn("Columns", ImGuiTableColumnFlags_WidthFixed, 50);
|
||||||
@ -193,7 +206,16 @@ void TileSheetEditorImGui::drawTileSheet(const geo::Vec2 &fbSize) noexcept {
|
|||||||
const auto &winPos = ImGui::GetWindowPos();
|
const auto &winPos = ImGui::GetWindowPos();
|
||||||
clickPos.x -= winPos.x + 10;
|
clickPos.x -= winPos.x + 10;
|
||||||
clickPos.y -= winPos.y + 10;
|
clickPos.y -= winPos.y + 10;
|
||||||
m_tileSheetEditor.click(fbSize, clickPos);
|
switch (m_tool) {
|
||||||
|
case Tool::Draw:
|
||||||
|
m_tileSheetEditor.clickDraw(fbSize, clickPos);
|
||||||
|
break;
|
||||||
|
case Tool::Fill:
|
||||||
|
case Tool::None:
|
||||||
|
case Tool::Select:
|
||||||
|
m_tileSheetEditor.clickSelect(fbSize, clickPos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (io.MouseReleased[0]) {
|
if (io.MouseReleased[0]) {
|
||||||
|
@ -18,6 +18,13 @@
|
|||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::core {
|
||||||
|
|
||||||
|
enum class Tool {
|
||||||
|
None,
|
||||||
|
Draw,
|
||||||
|
Fill,
|
||||||
|
Select,
|
||||||
|
};
|
||||||
|
|
||||||
class TileSheetEditorImGui: public studio::Editor {
|
class TileSheetEditorImGui: public studio::Editor {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -43,6 +50,7 @@ class TileSheetEditorImGui: public studio::Editor {
|
|||||||
TileSheetEditorView m_tileSheetEditor;
|
TileSheetEditorView m_tileSheetEditor;
|
||||||
float m_palViewWidth = 300;
|
float m_palViewWidth = 300;
|
||||||
geo::Vec2 m_prevMouseDownPos;
|
geo::Vec2 m_prevMouseDownPos;
|
||||||
|
Tool m_tool = Tool::Draw;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TileSheetEditorImGui(Context *ctx, const ox::String &path);
|
TileSheetEditorImGui(Context *ctx, const ox::String &path);
|
||||||
|
@ -65,18 +65,48 @@ void TileSheetEditorModel::setActiveSubsheet(const TileSheet::SubSheetIdx &idx)
|
|||||||
this->activeSubsheetChanged.emit(m_activeSubsSheetIdx);
|
this->activeSubsheetChanged.emit(m_activeSubsSheetIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TileSheetEditorModel::select(const geo::Point &pt) noexcept {
|
||||||
|
if (!m_selectionOngoing) {
|
||||||
|
m_selectionPt1 = pt;
|
||||||
|
m_selectionOngoing = true;
|
||||||
|
}
|
||||||
|
if (m_selectionPt2 != pt) {
|
||||||
|
m_selectionPt2 = pt;
|
||||||
|
m_selectionBounds = {m_selectionPt1, m_selectionPt2};
|
||||||
|
m_updated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void TileSheetEditorModel::completeSelection() noexcept {
|
||||||
|
m_selectionOngoing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TileSheetEditorModel::clearSelection() noexcept {
|
||||||
|
m_updated = true;
|
||||||
|
m_selectionPt1 = {-1, -1};
|
||||||
|
m_selectionPt2 = {-1, -1};
|
||||||
|
m_selectionBounds = {m_selectionPt1, m_selectionPt2};
|
||||||
|
}
|
||||||
|
|
||||||
bool TileSheetEditorModel::updated() const noexcept {
|
bool TileSheetEditorModel::updated() const noexcept {
|
||||||
return m_updated;
|
return m_updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error TileSheetEditorModel::markUpdated(int cmdId) noexcept {
|
ox::Error TileSheetEditorModel::markUpdated(int cmdId) noexcept {
|
||||||
m_updated = true;
|
m_updated = true;
|
||||||
if (cmdId == CommandId::AddSubSheet || cmdId == CommandId::RmSubSheet) {
|
switch (static_cast<CommandId>(cmdId)) {
|
||||||
|
case CommandId::AddSubSheet:
|
||||||
|
case CommandId::RmSubSheet: {
|
||||||
// make sure the current active SubSheet is still valid
|
// make sure the current active SubSheet is still valid
|
||||||
auto idx = m_img.validateSubSheetIdx(m_activeSubsSheetIdx);
|
auto idx = m_img.validateSubSheetIdx(m_activeSubsSheetIdx);
|
||||||
if (idx != m_activeSubsSheetIdx) {
|
if (idx != m_activeSubsSheetIdx) {
|
||||||
setActiveSubsheet(idx);
|
setActiveSubsheet(idx);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CommandId::Draw:
|
||||||
|
case CommandId::UpdateSubSheet:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return OxError(0);
|
return OxError(0);
|
||||||
}
|
}
|
||||||
@ -91,6 +121,12 @@ ox::Error TileSheetEditorModel::saveFile() noexcept {
|
|||||||
return m_ctx->assetManager.setAsset(m_path, m_img).error;
|
return m_ctx->assetManager.setAsset(m_path, m_img).error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TileSheetEditorModel::pixelSelected(std::size_t idx) const noexcept {
|
||||||
|
auto s = activeSubSheet();
|
||||||
|
auto pt = idxToPt(idx, s->columns);
|
||||||
|
return m_selectionBounds.contains(pt);
|
||||||
|
}
|
||||||
|
|
||||||
void TileSheetEditorModel::getFillPixels(bool *pixels, const geo::Point &pt, int oldColor) const noexcept {
|
void TileSheetEditorModel::getFillPixels(bool *pixels, const geo::Point &pt, int oldColor) const noexcept {
|
||||||
auto &activeSubSheet = *this->activeSubSheet();
|
auto &activeSubSheet = *this->activeSubSheet();
|
||||||
const auto tileIdx = [activeSubSheet](const geo::Point &pt) noexcept {
|
const auto tileIdx = [activeSubSheet](const geo::Point &pt) noexcept {
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <ox/std/string.hpp>
|
#include <ox/std/string.hpp>
|
||||||
|
|
||||||
#include <nostalgia/core/gfx.hpp>
|
#include <nostalgia/core/gfx.hpp>
|
||||||
|
#include <nostalgia/geo/bounds.hpp>
|
||||||
#include <nostalgia/geo/point.hpp>
|
#include <nostalgia/geo/point.hpp>
|
||||||
#include <nostalgia/geo/vec.hpp>
|
#include <nostalgia/geo/vec.hpp>
|
||||||
#include <nostalgia/studio/studio.hpp>
|
#include <nostalgia/studio/studio.hpp>
|
||||||
@ -279,6 +280,11 @@ class TileSheetEditorModel: public ox::SignalHandler {
|
|||||||
bool m_updated = false;
|
bool m_updated = false;
|
||||||
Context *m_ctx = nullptr;
|
Context *m_ctx = nullptr;
|
||||||
ox::String m_path;
|
ox::String m_path;
|
||||||
|
ox::Vector<std::size_t> m_selectedPixels; // pixel idx values
|
||||||
|
bool m_selectionOngoing = false;
|
||||||
|
geo::Point m_selectionPt1 = {-1, -1};
|
||||||
|
geo::Point m_selectionPt2 = {-1, -1};
|
||||||
|
geo::Bounds m_selectionBounds;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TileSheetEditorModel(Context *ctx, const ox::String &path);
|
TileSheetEditorModel(Context *ctx, const ox::String &path);
|
||||||
@ -326,6 +332,12 @@ class TileSheetEditorModel: public ox::SignalHandler {
|
|||||||
return m_activeSubsSheetIdx;
|
return m_activeSubsSheetIdx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void select(const geo::Point &pt) noexcept;
|
||||||
|
|
||||||
|
void completeSelection() noexcept;
|
||||||
|
|
||||||
|
void clearSelection() noexcept;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
bool updated() const noexcept;
|
bool updated() const noexcept;
|
||||||
|
|
||||||
@ -337,6 +349,8 @@ class TileSheetEditorModel: public ox::SignalHandler {
|
|||||||
|
|
||||||
constexpr studio::UndoStack *undoStack() noexcept;
|
constexpr studio::UndoStack *undoStack() noexcept;
|
||||||
|
|
||||||
|
bool pixelSelected(std::size_t idx) const noexcept;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void saveItem();
|
void saveItem();
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::core {
|
||||||
|
|
||||||
TileSheetEditorView::TileSheetEditorView(Context *ctx, const ox::String &path): m_model(ctx, path) {
|
TileSheetEditorView::TileSheetEditorView(Context *ctx, const ox::String &path): m_model(ctx, path), m_pixelsDrawer(&m_model) {
|
||||||
// build shaders
|
// build shaders
|
||||||
oxThrowError(m_pixelsDrawer.buildShader());
|
oxThrowError(m_pixelsDrawer.buildShader());
|
||||||
oxThrowError(m_pixelGridDrawer.buildShader());
|
oxThrowError(m_pixelGridDrawer.buildShader());
|
||||||
@ -50,21 +50,20 @@ void TileSheetEditorView::scrollH(const geo::Vec2 &paneSz, float wheelh) noexcep
|
|||||||
m_scrollOffset.x = ox::clamp(m_scrollOffset.x, -(sheetSize.x / 2), 0.f);
|
m_scrollOffset.x = ox::clamp(m_scrollOffset.x, -(sheetSize.x / 2), 0.f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorView::click(const geo::Vec2 &paneSize, const geo::Vec2 &clickPos) noexcept {
|
void TileSheetEditorView::clickDraw(const geo::Vec2 &paneSize, const geo::Vec2 &clickPos) noexcept {
|
||||||
auto [x, y] = clickPos;
|
const auto pt = clickPoint(paneSize, clickPos);
|
||||||
const auto pixDrawSz = m_pixelsDrawer.pixelSize(paneSize);
|
|
||||||
x /= paneSize.x;
|
|
||||||
y /= paneSize.y;
|
|
||||||
x += -m_scrollOffset.x / 2;
|
|
||||||
y += m_scrollOffset.y / 2;
|
|
||||||
x /= pixDrawSz.x;
|
|
||||||
y /= pixDrawSz.y;
|
|
||||||
const auto pt = geo::Point(static_cast<int>(x * 2), static_cast<int>(y * 2));
|
|
||||||
m_model.drawCommand(pt, m_palIdx);
|
m_model.drawCommand(pt, m_palIdx);
|
||||||
|
m_model.clearSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TileSheetEditorView::clickSelect(const geo::Vec2 &paneSize, const geo::Vec2 &clickPos) noexcept {
|
||||||
|
const auto pt = clickPoint(paneSize, clickPos);
|
||||||
|
m_model.select(pt);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorView::releaseMouseButton() noexcept {
|
void TileSheetEditorView::releaseMouseButton() noexcept {
|
||||||
m_model.endDrawCommand();
|
m_model.endDrawCommand();
|
||||||
|
m_model.completeSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorView::resizeView(const geo::Vec2 &sz) noexcept {
|
void TileSheetEditorView::resizeView(const geo::Vec2 &sz) noexcept {
|
||||||
@ -82,10 +81,22 @@ void TileSheetEditorView::ackUpdate() noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetEditorView::initView() noexcept {
|
void TileSheetEditorView::initView() noexcept {
|
||||||
m_pixelsDrawer.initBufferSet(m_viewSize, img(), *m_model.activeSubSheet(), pal());
|
m_pixelsDrawer.initBufferSet(m_viewSize);
|
||||||
m_pixelGridDrawer.initBufferSet(m_viewSize, *m_model.activeSubSheet());
|
m_pixelGridDrawer.initBufferSet(m_viewSize, *m_model.activeSubSheet());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
geo::Point TileSheetEditorView::clickPoint(const geo::Vec2 &paneSize, const geo::Vec2 &clickPos) const noexcept {
|
||||||
|
auto [x, y] = clickPos;
|
||||||
|
const auto pixDrawSz = m_pixelsDrawer.pixelSize(paneSize);
|
||||||
|
x /= paneSize.x;
|
||||||
|
y /= paneSize.y;
|
||||||
|
x += -m_scrollOffset.x / 2;
|
||||||
|
y += m_scrollOffset.y / 2;
|
||||||
|
x /= pixDrawSz.x;
|
||||||
|
y /= pixDrawSz.y;
|
||||||
|
return {static_cast<int>(x * 2), static_cast<int>(y * 2)};
|
||||||
|
}
|
||||||
|
|
||||||
ox::Error TileSheetEditorView::setActiveSubsheet(const TileSheet::SubSheetIdx&) noexcept {
|
ox::Error TileSheetEditorView::setActiveSubsheet(const TileSheet::SubSheetIdx&) noexcept {
|
||||||
initView();
|
initView();
|
||||||
return OxError(0);
|
return OxError(0);
|
||||||
|
@ -55,7 +55,9 @@ class TileSheetEditorView: public ox::SignalHandler {
|
|||||||
|
|
||||||
void draw() noexcept;
|
void draw() noexcept;
|
||||||
|
|
||||||
void click(const geo::Vec2 &paneSize, const geo::Vec2 &clickPos) noexcept;
|
void clickDraw(const geo::Vec2 &paneSize, const geo::Vec2 &clickPos) noexcept;
|
||||||
|
|
||||||
|
void clickSelect(const geo::Vec2 &paneSize, const geo::Vec2 &clickPos) noexcept;
|
||||||
|
|
||||||
void releaseMouseButton() noexcept;
|
void releaseMouseButton() noexcept;
|
||||||
|
|
||||||
@ -113,6 +115,8 @@ class TileSheetEditorView: public ox::SignalHandler {
|
|||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
ox::String palettePath(const ox::String &palettePath) const;
|
ox::String palettePath(const ox::String &palettePath) const;
|
||||||
|
|
||||||
|
geo::Point clickPoint(const geo::Vec2 &paneSize, const geo::Vec2 &clickPos) const noexcept;
|
||||||
|
|
||||||
// slots
|
// slots
|
||||||
ox::Error setActiveSubsheet(const TileSheet::SubSheetIdx &idx) noexcept;
|
ox::Error setActiveSubsheet(const TileSheet::SubSheetIdx &idx) noexcept;
|
||||||
|
|
||||||
|
@ -4,10 +4,14 @@
|
|||||||
|
|
||||||
#include <nostalgia/core/consts.hpp>
|
#include <nostalgia/core/consts.hpp>
|
||||||
#include <nostalgia/core/ptidxconv.hpp>
|
#include <nostalgia/core/ptidxconv.hpp>
|
||||||
|
#include "tilesheeteditormodel.hpp"
|
||||||
#include "tilesheetpixels.hpp"
|
#include "tilesheetpixels.hpp"
|
||||||
|
|
||||||
namespace nostalgia::core {
|
namespace nostalgia::core {
|
||||||
|
|
||||||
|
TileSheetPixels::TileSheetPixels(TileSheetEditorModel *model) noexcept: m_model(model) {
|
||||||
|
}
|
||||||
|
|
||||||
void TileSheetPixels::setPixelSizeMod(float sm) noexcept {
|
void TileSheetPixels::setPixelSizeMod(float sm) noexcept {
|
||||||
m_pixelSizeMod = sm;
|
m_pixelSizeMod = sm;
|
||||||
}
|
}
|
||||||
@ -29,14 +33,14 @@ void TileSheetPixels::draw(bool update, const geo::Vec2 &scroll) noexcept {
|
|||||||
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(m_bufferSet.elements.size()), GL_UNSIGNED_INT, nullptr);
|
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(m_bufferSet.elements.size()), GL_UNSIGNED_INT, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetPixels::initBufferSet(const geo::Vec2 &paneSize, const TileSheet &img, const TileSheet::SubSheet &subSheet, const Palette &pal) noexcept {
|
void TileSheetPixels::initBufferSet(const geo::Vec2 &paneSize) noexcept {
|
||||||
// vao
|
// vao
|
||||||
m_bufferSet.vao = glutils::generateVertexArrayObject();
|
m_bufferSet.vao = glutils::generateVertexArrayObject();
|
||||||
glBindVertexArray(m_bufferSet.vao);
|
glBindVertexArray(m_bufferSet.vao);
|
||||||
// vbo & ebo
|
// vbo & ebo
|
||||||
m_bufferSet.vbo = glutils::generateBuffer();
|
m_bufferSet.vbo = glutils::generateBuffer();
|
||||||
m_bufferSet.ebo = glutils::generateBuffer();
|
m_bufferSet.ebo = glutils::generateBuffer();
|
||||||
setBufferObjects(paneSize, img, subSheet, pal);
|
setBufferObjects(paneSize);
|
||||||
glutils::sendVbo(m_bufferSet);
|
glutils::sendVbo(m_bufferSet);
|
||||||
glutils::sendEbo(m_bufferSet);
|
glutils::sendEbo(m_bufferSet);
|
||||||
// vbo layout
|
// vbo layout
|
||||||
@ -78,21 +82,29 @@ void TileSheetPixels::setPixelBufferObject(const geo::Vec2 &paneSize, unsigned v
|
|||||||
memcpy(ebo, elms, sizeof(elms));
|
memcpy(ebo, elms, sizeof(elms));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TileSheetPixels::setBufferObjects(const geo::Vec2 &paneSize, const TileSheet &img, const TileSheet::SubSheet &subSheet, const Palette &pal) noexcept {
|
void TileSheetPixels::setBufferObjects(const geo::Vec2 &paneSize) noexcept {
|
||||||
// set buffer lengths
|
// set buffer lengths
|
||||||
const auto width = subSheet.columns * TileWidth;
|
const auto subSheet = m_model->activeSubSheet();
|
||||||
const auto height = subSheet.rows * TileHeight;
|
const auto &pal = m_model->pal();
|
||||||
|
const auto width = subSheet->columns * TileWidth;
|
||||||
|
const auto height = subSheet->rows * TileHeight;
|
||||||
const auto pixels = static_cast<unsigned>(width * height);
|
const auto pixels = static_cast<unsigned>(width * height);
|
||||||
m_bufferSet.vertices.resize(pixels * VertexVboLength);
|
m_bufferSet.vertices.resize(pixels * VertexVboLength);
|
||||||
m_bufferSet.elements.resize(pixels * VertexEboLength);
|
m_bufferSet.elements.resize(pixels * VertexEboLength);
|
||||||
// set pixels
|
// set pixels
|
||||||
subSheet.walkPixels(img.bpp, [&](std::size_t i, uint8_t p) {
|
subSheet->walkPixels(m_model->img().bpp, [&](std::size_t i, uint8_t p) {
|
||||||
const auto color = pal.colors[p];
|
auto color = pal.colors[p];
|
||||||
const auto pt = idxToPt(static_cast<int>(i), subSheet.columns);
|
const auto pt = idxToPt(static_cast<int>(i), subSheet->columns);
|
||||||
const auto fx = static_cast<float>(pt.x);
|
const auto fx = static_cast<float>(pt.x);
|
||||||
const auto fy = static_cast<float>(pt.y);
|
const auto fy = static_cast<float>(pt.y);
|
||||||
const auto vbo = &m_bufferSet.vertices[i * VertexVboLength];
|
const auto vbo = &m_bufferSet.vertices[i * VertexVboLength];
|
||||||
const auto ebo = &m_bufferSet.elements[i * VertexEboLength];
|
const auto ebo = &m_bufferSet.elements[i * VertexEboLength];
|
||||||
|
if (m_model->pixelSelected(i)) {
|
||||||
|
const auto r = red16(color) / 2;
|
||||||
|
const auto g = (green16(color) + 20) / 2;
|
||||||
|
const auto b = (blue16(color) + 31) / 2;
|
||||||
|
color = color16(r, g, b);
|
||||||
|
}
|
||||||
setPixelBufferObject(paneSize, i * VertexVboRows, fx, fy, color, vbo, ebo);
|
setPixelBufferObject(paneSize, i * VertexVboRows, fx, fy, color, vbo, ebo);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -40,15 +40,18 @@ class TileSheetPixels {
|
|||||||
float m_pixelSizeMod = 1;
|
float m_pixelSizeMod = 1;
|
||||||
glutils::GLProgram m_shader;
|
glutils::GLProgram m_shader;
|
||||||
glutils::BufferSet m_bufferSet;
|
glutils::BufferSet m_bufferSet;
|
||||||
|
const class TileSheetEditorModel *m_model = nullptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
explicit TileSheetPixels(class TileSheetEditorModel *model) noexcept;
|
||||||
|
|
||||||
void setPixelSizeMod(float sm) noexcept;
|
void setPixelSizeMod(float sm) noexcept;
|
||||||
|
|
||||||
ox::Error buildShader() noexcept;
|
ox::Error buildShader() noexcept;
|
||||||
|
|
||||||
void draw(bool update, const geo::Vec2 &scroll) noexcept;
|
void draw(bool update, const geo::Vec2 &scroll) noexcept;
|
||||||
|
|
||||||
void initBufferSet(const geo::Vec2 &paneSize, const TileSheet &img, const TileSheet::SubSheet &subSheet, const Palette &pal) noexcept;
|
void initBufferSet(const geo::Vec2 &paneSize) noexcept;
|
||||||
|
|
||||||
[[nodiscard]]
|
[[nodiscard]]
|
||||||
geo::Vec2 pixelSize(const geo::Vec2 &paneSize) const noexcept;
|
geo::Vec2 pixelSize(const geo::Vec2 &paneSize) const noexcept;
|
||||||
@ -56,7 +59,7 @@ class TileSheetPixels {
|
|||||||
private:
|
private:
|
||||||
void setPixelBufferObject(const geo::Vec2 &paneS, unsigned vertexRow, float x, float y, Color16 color, float *vbo, GLuint *ebo) const noexcept;
|
void setPixelBufferObject(const geo::Vec2 &paneS, unsigned vertexRow, float x, float y, Color16 color, float *vbo, GLuint *ebo) const noexcept;
|
||||||
|
|
||||||
void setBufferObjects(const geo::Vec2 &paneS, const TileSheet &img, const TileSheet::SubSheet &subSheet, const Palette &pal) noexcept;
|
void setBufferObjects(const geo::Vec2 &paneS) noexcept;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user