[nostalgia] Start on new TileSheetEditor

This commit is contained in:
2021-12-17 20:57:56 -06:00
parent ed074d07be
commit 775008a513
122 changed files with 651 additions and 2592 deletions
@@ -0,0 +1,108 @@
/*
* Copyright 2016 - 2021 Gary Talent (gary@drinkingtea.net). All rights reserved.
*/
#include <nostalgia/core/consts.hpp>
#include "ptidxconv.hpp"
#include "tilesheetpixels.hpp"
namespace nostalgia::core {
ox::Error TileSheetPixels::buildShader() noexcept {
const auto Vshad = ox::sfmt(VShad, glutils::GlslVersion);
const auto Fshad = ox::sfmt(FShad, glutils::GlslVersion);
return glutils::buildShaderProgram(Vshad, Fshad).moveTo(&m_shader);
}
void TileSheetPixels::draw(bool update) noexcept {
glUseProgram(m_shader);
glBindVertexArray(m_bufferSet.vao);
if (update) {
glutils::sendVbo(m_bufferSet);
}
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(m_bufferSet.elements.size()), GL_UNSIGNED_INT, nullptr);
}
void TileSheetPixels::initBufferSet(const NostalgiaGraphic &img, const NostalgiaPalette &pal) noexcept {
// vao
m_bufferSet.vao = glutils::generateVertexArrayObject();
glBindVertexArray(m_bufferSet.vao);
// vbo & ebo
m_bufferSet.vbo = glutils::generateBuffer();
m_bufferSet.ebo = glutils::generateBuffer();
setBufferObjects(img, pal, &m_bufferSet);
glutils::sendVbo(m_bufferSet);
glutils::sendEbo(m_bufferSet);
// vbo layout
const auto posAttr = static_cast<GLuint>(glGetAttribLocation(m_shader, "vPosition"));
glEnableVertexAttribArray(posAttr);
glVertexAttribPointer(posAttr, 2, GL_FLOAT, GL_FALSE, VertexVboRowLength * sizeof(float), nullptr);
const auto colorAttr = static_cast<GLuint>(glGetAttribLocation(m_shader, "vColor"));
glEnableVertexAttribArray(colorAttr);
glVertexAttribPointer(colorAttr, 3, GL_FLOAT, GL_FALSE, VertexVboRowLength * sizeof(float),
reinterpret_cast<void*>(2 * sizeof(float)));
}
void TileSheetPixels::setPixelBufferObject(unsigned vertexRow, float x, float y, Color16 color, float *vbo, GLuint *ebo) noexcept {
const auto [xmod, ymod] = pixelSize();
x *= xmod;
y *= -ymod;
x -= 1.0f;
y += 1.0f - ymod;
//std::cout << x << ", " << y << ", " << (x + xmod) << ", " << (y + ymod) << '\n';
const auto r = redf(color), g = greenf(color), b = bluef(color);
// don't worry, these memcpys gets optimized to something much more ideal
const float vertices[VertexVboLength] = {
x, y, r, g, b, // bottom left
x + xmod, y, r, g, b, // bottom right
x + xmod, y + ymod, r, g, b, // top right
x, y + ymod, r, g, b, // top left
};
memcpy(vbo, vertices, sizeof(vertices));
const GLuint elms[VertexEboLength] = {
vertexRow + 0, vertexRow + 1, vertexRow + 2,
vertexRow + 2, vertexRow + 3, vertexRow + 0,
};
memcpy(ebo, elms, sizeof(elms));
}
void TileSheetPixels::setBufferObjects(const NostalgiaGraphic &img, const NostalgiaPalette &pal, glutils::BufferSet *bg) noexcept {
const auto setPixel = [bg, img, pal](std::size_t i, uint8_t p) {
const auto color = pal.colors[p];
const auto pt = idxToPt(i, img.columns);
const auto fx = static_cast<float>(pt.x);
const auto fy = static_cast<float>(pt.y);
const auto vbo = &bg->vertices[i * VertexVboLength];
const auto ebo = &bg->elements[i * VertexEboLength];
setPixelBufferObject(i * VertexVboRows, fx, fy, color, vbo, ebo);
};
// set buffer lengths
const auto width = img.columns * TileWidth;
const auto height = img.rows * TileHeight;
const auto tiles = static_cast<unsigned>(width * height);
m_bufferSet.vertices.resize(tiles * VertexVboLength);
m_bufferSet.elements.resize(tiles * VertexEboLength);
// set pixels
if (img.bpp == 4) {
for (std::size_t i = 0; i < img.pixels.size(); ++i) {
const auto colorIdx1 = img.pixels[i] & 0xF;
const auto colorIdx2 = img.pixels[i] >> 4;
setPixel(i * 2 + 0, colorIdx1);
setPixel(i * 2 + 1, colorIdx2);
}
} else {
for (std::size_t i = 0; i < img.pixels.size(); ++i) {
const auto p = img.pixels[i];
setPixel(i, p);
}
}
}
ImVec2 TileSheetPixels::pixelSize() noexcept {
const auto [sw, sh] = ImGui::GetContentRegionAvail();
constexpr float ymod = 0.35f / 10.0f;
const auto xmod = ymod * sh / sw;
return {xmod, ymod};
}
}