[jasper/world/studio] Simplify CollisionMapView with MapTileHighlighter
All checks were successful
Build / build (push) Successful in 3m15s

This commit is contained in:
Gary Talent 2024-05-26 00:00:44 -05:00
parent 6e32d36c78
commit aa43dc9575
2 changed files with 8 additions and 110 deletions

View File

@ -11,56 +11,19 @@ CollisionMap mapIdx(auto x, auto y) noexcept {
+ static_cast<CollisionMap>(x); + static_cast<CollisionMap>(x);
} }
const glutils::ProgramSource CollisionView::s_programSrc = {
.shaderParams = {
{
.len = 2,
.name = ox::String("vPosition"),
},
{
.len = 1,
.name = ox::String("vSelection"),
},
},
.vertShader = ox::sfmt(R"(
{}
in vec2 vPosition;
in float vSelection;
out float fSelection;
void main() {
gl_Position = vec4(vPosition, 0.0, 1.0);
fSelection = vSelection;
})", ncore::gl::GlslVersion),
.fragShader = ox::sfmt(R"(
{}
in float fSelection;
out vec4 outColor;
void main() {
outColor = vec4(0.0, 0.7, 1.0, 0.4) * fSelection;
})", ncore::gl::GlslVersion),
};
CollisionView::CollisionView(studio::StudioContext &sctx): CollisionView::CollisionView(studio::StudioContext &sctx):
m_nctx(ncore::init(sctx.tctx, { m_nctx(ncore::init(sctx.tctx, {
.glInstallDrawer = false, .glInstallDrawer = false,
.glSpriteCount = 0, .glSpriteCount = 0,
}).unwrapThrow()), }).unwrapThrow()),
m_frameBuffer(glutils::generateFrameBuffer(240 * s_scale, 160 * s_scale)) { m_frameBuffer(glutils::generateFrameBuffer(240 * s_scale, 160 * s_scale)) {
m_bufferSet.vao = glutils::generateVertexArrayObject();
m_bufferSet.vbo = glutils::generateBuffer();
m_bufferSet.ebo = glutils::generateBuffer();
glBindVertexArray(m_bufferSet.vao);
sendVbo(m_bufferSet);
sendEbo(m_bufferSet);
m_shader = glutils::buildShaderProgram(s_programSrc).unwrapThrow();
glBindVertexArray(0);
} }
ox::Error CollisionView::setup( ox::Error CollisionView::setup(
ox::FileAddress const&tsAddr, ox::FileAddress const&tsAddr,
ox::FileAddress const&palAddr, ox::FileAddress const&palAddr,
int const w, int const w,
int h, int const h,
uint_t tile, uint_t tile,
CollisionMap colMap) noexcept { CollisionMap colMap) noexcept {
m_subsheetTilesWidth = w; m_subsheetTilesWidth = w;
@ -69,6 +32,7 @@ ox::Error CollisionView::setup(
ncore::setBgStatus(*m_nctx, 0, true); ncore::setBgStatus(*m_nctx, 0, true);
oxReturnError(ncore::loadBgTileSheet(*m_nctx, 0, tsAddr)); oxReturnError(ncore::loadBgTileSheet(*m_nctx, 0, tsAddr));
oxReturnError(ncore::loadBgPalette(*m_nctx, 0, palAddr)); oxReturnError(ncore::loadBgPalette(*m_nctx, 0, palAddr));
oxReturnError(m_highlighter.setup({w / 2, h / 2}));
buildGlBuffers(colMap); buildGlBuffers(colMap);
return {}; return {};
} }
@ -76,17 +40,7 @@ ox::Error CollisionView::setup(
void CollisionView::draw() noexcept { void CollisionView::draw() noexcept {
glutils::FrameBufferBind const frameBufferBind(m_frameBuffer); glutils::FrameBufferBind const frameBufferBind(m_frameBuffer);
ncore::gl::draw(*m_nctx, s_scale); ncore::gl::draw(*m_nctx, s_scale);
glEnable(GL_BLEND); m_highlighter.draw();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glUseProgram(m_shader);
glBindVertexArray(m_bufferSet.vao);
sendVbo(m_bufferSet);
sendEbo(m_bufferSet);
auto const elmCnt = static_cast<GLsizei>(m_bufferSet.elements.size());
glDrawElements(GL_TRIANGLES, elmCnt, GL_UNSIGNED_INT, nullptr);
glBindVertexArray(0);
glUseProgram(0);
glDisable(GL_BLEND);
} }
int CollisionView::scale() const noexcept { int CollisionView::scale() const noexcept {
@ -97,34 +51,6 @@ glutils::FrameBuffer const&CollisionView::framebuffer() const noexcept {
return m_frameBuffer; return m_frameBuffer;
} }
void CollisionView::setPixelBufferObject(
unsigned vertexRow,
float x, float y,
bool const selected,
float *vbo,
GLuint *ebo) const noexcept {
auto constexpr xmod = static_cast<float>(ncore::TileWidth) / 240.f * 4;
auto constexpr ymod = static_cast<float>(ncore::TileHeight) / 160.f * 4;
x *= xmod;
y *= -ymod;
x -= 1.0f;
y += 1.0f - ymod;
auto const selection = 1.f * static_cast<float>(selected);
// don't worry, these memcpys gets optimized to something much more ideal
std::array const vertices{
x, y, selection, // bottom left
x + xmod, y, selection, // bottom right
x + xmod, y + ymod, selection, // top right
x, y + ymod, selection, // top left
};
memcpy(vbo, vertices.data(), sizeof(vertices));
ox::Array<GLuint, 6> const elms{
vertexRow + 0, vertexRow + 1, vertexRow + 2,
vertexRow + 2, vertexRow + 3, vertexRow + 0,
};
memcpy(ebo, elms.data(), sizeof(elms));
}
bool CollisionView::click(ox::Vec2 const&pos, CollisionMap &colMap) noexcept { bool CollisionView::click(ox::Vec2 const&pos, CollisionMap &colMap) noexcept {
auto const inMap = colMap; auto const inMap = colMap;
auto const x = static_cast<uint64_t>(pos.x * static_cast<float>(m_subsheetTilesWidth)) / 2; auto const x = static_cast<uint64_t>(pos.x * static_cast<float>(m_subsheetTilesWidth)) / 2;
@ -138,36 +64,15 @@ bool CollisionView::click(ox::Vec2 const&pos, CollisionMap &colMap) noexcept {
} }
void CollisionView::buildGlBuffers(CollisionMap colMap) noexcept { void CollisionView::buildGlBuffers(CollisionMap colMap) noexcept {
auto const vboLength = static_cast<size_t>(s_programSrc.rowLen) * 4;
auto constexpr eboLength = 6;
auto const tileCnt =
static_cast<size_t>(m_subsheetTilesWidth) * static_cast<size_t>(m_subsheetTilesHeight);
m_bufferSet.vertices.resize(tileCnt * vboLength);
m_bufferSet.elements.resize(tileCnt * eboLength);
size_t i = 0;
auto tile = m_sheetTileStart; auto tile = m_sheetTileStart;
for (auto y = 0; y < m_subsheetTilesHeight; ++y) { for (auto y = 0; y < m_subsheetTilesHeight; ++y) {
for (auto x = 0; x < m_subsheetTilesWidth; ++x) { for (auto x = 0; x < m_subsheetTilesWidth; ++x) {
ncore::setBgTile(*m_nctx, 0, x, y, tile); ncore::setBgTile(*m_nctx, 0, x, y, tile);
auto const vbo = &m_bufferSet.vertices[i * vboLength]; auto const collidable = (colMap >> mapIdx(x, y)) & 1;
auto const ebo = &m_bufferSet.elements[i * eboLength]; std::ignore = m_highlighter.setTileHighlight({x, y}, collidable);
setPixelBufferObject(
static_cast<uint_t>(i * 4),
static_cast<float>(x),
static_cast<float>(y),
(colMap >> mapIdx(x, y)) & 1,
vbo,
ebo);
++i;
++tile; ++tile;
} }
} }
glUseProgram(m_shader);
glBindVertexArray(m_bufferSet.vao);
sendVbo(m_bufferSet);
sendEbo(m_bufferSet);
glBindVertexArray(0);
glUseProgram(0);
} }
} }

View File

@ -11,21 +11,21 @@
#include <jasper/world/worldobject.hpp> #include <jasper/world/worldobject.hpp>
#include "../maptilehighlighter.hpp"
namespace jasper::world { namespace jasper::world {
namespace ncore = nostalgia::core; namespace ncore = nostalgia::core;
class CollisionView { class CollisionView {
private: private:
static const glutils::ProgramSource s_programSrc;
static constexpr int s_scale = 5; static constexpr int s_scale = 5;
ncore::ContextUPtr m_nctx; ncore::ContextUPtr m_nctx;
glutils::FrameBuffer m_frameBuffer; glutils::FrameBuffer m_frameBuffer;
glutils::GLProgram m_shader;
glutils::BufferSet m_bufferSet;
uint_t m_sheetTileStart{}; uint_t m_sheetTileStart{};
int m_subsheetTilesWidth{}; int m_subsheetTilesWidth{};
int m_subsheetTilesHeight{}; int m_subsheetTilesHeight{};
MapTileHighlighter m_highlighter;
public: public:
CollisionView(studio::StudioContext &sctx); CollisionView(studio::StudioContext &sctx);
@ -46,13 +46,6 @@ class CollisionView {
[[nodiscard]] [[nodiscard]]
glutils::FrameBuffer const&framebuffer() const noexcept; glutils::FrameBuffer const&framebuffer() const noexcept;
void setPixelBufferObject(
unsigned vertexRow,
float x, float y,
bool selected,
float *vbo,
GLuint *ebo) const noexcept;
/** /**
* @return true if colMap changes * @return true if colMap changes
*/ */