[nostalgia/core/studio] Add pixel outline to tile sheet editor

This commit is contained in:
2022-01-29 21:53:48 -06:00
parent 99550b60ee
commit f6be36741c
4 changed files with 81 additions and 61 deletions
@@ -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<GLsizei>(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<GLuint>(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<void*>(2 * sizeof(float)));
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*>(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<float>(pt1.x) * ps.x;
const auto y1 = static_cast<float>(pt1.y) * ps.y;
const auto x2 = static_cast<float>(pt2.x) * ps.x;
const auto y2 = static_cast<float>(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<float>(pt1.x) * pixSize.x - 1.f;
const auto y1 = 1.f - static_cast<float>(pt1.y) * pixSize.y;
const auto x2 = static_cast<float>(pt2.x) * pixSize.x - 1.f;
const auto y2 = 1.f - static_cast<float>(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<unsigned>(width * height);
m_bufferSet.vertices.resize(tiles * VertexVboLength);
m_bufferSet.elements.resize(tiles * VertexEboLength);
// set buffers
const auto pixelCnt = static_cast<unsigned>(width * height);
const auto tileCnt = static_cast<unsigned>(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;
}
}