[nostalgia/core/opengl] Allow GL implementation to customize sprite count and size

This commit is contained in:
Gary Talent 2023-12-20 23:01:56 -06:00
parent 056284c857
commit 6d2a20e8bd
5 changed files with 27 additions and 23 deletions

View File

@ -8,6 +8,8 @@ namespace nostalgia::core {
struct InitParams { struct InitParams {
bool glInstallDrawer = true; bool glInstallDrawer = true;
uint_t glSpriteCount = 128;
uint_t glBlocksPerSprite = 64;
}; };
} }

View File

@ -11,9 +11,12 @@ void ContextDeleter::operator()(Context *p) noexcept {
ox::safeDelete(p); ox::safeDelete(p);
} }
Context::Context(turbine::Context &tctx) noexcept: Context::Context(turbine::Context &tctx, InitParams const&params) noexcept:
turbineCtx(tctx), turbineCtx(tctx),
drawer(*this) { spriteBlocks(params.glSpriteCount, params.glBlocksPerSprite),
drawer(*this),
spriteCount(params.glSpriteCount),
blocksPerSprite(params.glBlocksPerSprite) {
} }
Context::~Context() noexcept { Context::~Context() noexcept {
@ -21,7 +24,7 @@ Context::~Context() noexcept {
} }
ox::Result<ContextUPtr> init(turbine::Context &tctx, InitParams const&params) noexcept { ox::Result<ContextUPtr> init(turbine::Context &tctx, InitParams const&params) noexcept {
auto ctx = ox::make_unique<Context>(tctx); auto ctx = ox::make_unique<Context>(tctx, params);
oxReturnError(initGfx(*ctx, params)); oxReturnError(initGfx(*ctx, params));
return ContextUPtr(ctx.release()); return ContextUPtr(ctx.release());
} }

View File

@ -26,7 +26,9 @@ class Context {
ox::Array<Sprite, 128> spriteStates; ox::Array<Sprite, 128> spriteStates;
ox::Array<renderer::Background, 4> backgrounds; ox::Array<renderer::Background, 4> backgrounds;
renderer::Drawer drawer; renderer::Drawer drawer;
explicit Context(turbine::Context &tctx) noexcept; uint_t spriteCount = 0;
uint_t blocksPerSprite = 0;
explicit Context(turbine::Context &tctx, InitParams const&params) noexcept;
Context(Context const&) = delete; Context(Context const&) = delete;
Context(Context&&) = delete; Context(Context&&) = delete;
Context &operator=(Context const&) = delete; Context &operator=(Context const&) = delete;

View File

@ -171,15 +171,15 @@ static void setTileBufferObject(
memcpy(ebo, elms.data(), sizeof(elms)); memcpy(ebo, elms.data(), sizeof(elms));
} }
static void initSpriteBufferObjects(glutils::BufferSet &bs) noexcept { static void initSpriteBufferObjects(Context &ctx, glutils::BufferSet &bs) noexcept {
for (auto i = 0u; i < SpriteCount; ++i) { for (auto i = 0u; i < ctx.spriteCount; ++i) {
auto vbo = &bs.vertices[i * static_cast<std::size_t>(SpriteVertexVboLength)]; auto vbo = &bs.vertices[i * static_cast<std::size_t>(SpriteVertexVboLength)];
auto ebo = &bs.elements[i * static_cast<std::size_t>(SpriteVertexEboLength)]; auto ebo = &bs.elements[i * static_cast<std::size_t>(SpriteVertexEboLength)];
setSpriteBufferObject(i * SpriteVertexVboRows * BlocksPerSprite, 0, 0, 0, 0, false, 0, vbo, ebo); setSpriteBufferObject(i * static_cast<uint_t>(SpriteVertexVboRows) * ctx.blocksPerSprite, 0, 0, 0, 0, false, 0, vbo, ebo);
} }
} }
static void initBackgroundBufferObjects(glutils::BufferSet &bs, float priority) noexcept { static void initBackgroundBufferObjects(glutils::BufferSet &bs) noexcept {
for (auto x = 0u; x < TileColumns; ++x) { for (auto x = 0u; x < TileColumns; ++x) {
for (auto y = 0u; y < TileRows; ++y) { for (auto y = 0u; y < TileRows; ++y) {
const auto i = bgVertexRow(x, y); const auto i = bgVertexRow(x, y);
@ -190,7 +190,7 @@ static void initBackgroundBufferObjects(glutils::BufferSet &bs, float priority)
static_cast<float>(x), static_cast<float>(x),
static_cast<float>(y), static_cast<float>(y),
0, 0,
priority, 0,
vbo, vbo,
ebo); ebo);
} }
@ -206,7 +206,7 @@ static void initSpritesBufferset(Context &ctx) noexcept {
// vbo & ebo // vbo & ebo
bs.vbo = glutils::generateBuffer(); bs.vbo = glutils::generateBuffer();
bs.ebo = glutils::generateBuffer(); bs.ebo = glutils::generateBuffer();
initSpriteBufferObjects(bs); initSpriteBufferObjects(ctx, bs);
glutils::sendVbo(bs); glutils::sendVbo(bs);
glutils::sendEbo(bs); glutils::sendEbo(bs);
// vbo layout // vbo layout
@ -228,15 +228,14 @@ static void initSpritesBufferset(Context &ctx) noexcept {
static void initBackgroundBufferset( static void initBackgroundBufferset(
GLuint shader, GLuint shader,
glutils::BufferSet &bs, glutils::BufferSet &bs) noexcept {
float priority) noexcept {
// vao // vao
bs.vao = glutils::generateVertexArrayObject(); bs.vao = glutils::generateVertexArrayObject();
glBindVertexArray(bs.vao); glBindVertexArray(bs.vao);
// vbo & ebo // vbo & ebo
bs.vbo = glutils::generateBuffer(); bs.vbo = glutils::generateBuffer();
bs.ebo = glutils::generateBuffer(); bs.ebo = glutils::generateBuffer();
initBackgroundBufferObjects(bs, priority); initBackgroundBufferObjects(bs);
glutils::sendVbo(bs); glutils::sendVbo(bs);
glutils::sendEbo(bs); glutils::sendEbo(bs);
// vbo layout // vbo layout
@ -412,8 +411,8 @@ static void setSprite(
auto const uY = static_cast<int>(s.y + 8) % 255 - 8; auto const uY = static_cast<int>(s.y + 8) % 255 - 8;
oxAssert(1 < ctx.spriteBlocks.vertices.size(), "vbo overflow"); oxAssert(1 < ctx.spriteBlocks.vertices.size(), "vbo overflow");
oxAssert(1 < ctx.spriteBlocks.elements.size(), "ebo overflow"); oxAssert(1 < ctx.spriteBlocks.elements.size(), "ebo overflow");
constexpr auto spriteVboSz = renderer::BlocksPerSprite * renderer::SpriteVertexVboLength; const auto spriteVboSz = ctx.blocksPerSprite * renderer::SpriteVertexVboLength;
constexpr auto spriteEboSz = renderer::BlocksPerSprite * renderer::SpriteVertexEboLength; const auto spriteEboSz = ctx.blocksPerSprite * renderer::SpriteVertexEboLength;
auto const vboBase = spriteVboSz * idx; auto const vboBase = spriteVboSz * idx;
auto const eboBase = spriteEboSz * idx; auto const eboBase = spriteEboSz * idx;
auto i = 0u; auto i = 0u;
@ -452,7 +451,7 @@ static void setSprite(
} }
} }
// clear remaining blocks in the sprite // clear remaining blocks in the sprite
for (; i < BlocksPerSprite; ++i) { for (; i < ctx.blocksPerSprite; ++i) {
set(0, 0, false); set(0, 0, false);
} }
ctx.spriteBlocks.updated = true; ctx.spriteBlocks.updated = true;
@ -471,7 +470,7 @@ ox::Error initGfx(
oxReturnError( oxReturnError(
glutils::buildShaderProgram(spriteVshad, spriteFshad).moveTo(ctx.spriteShader)); glutils::buildShaderProgram(spriteVshad, spriteFshad).moveTo(ctx.spriteShader));
for (auto &cbb : ctx.cbbs) { for (auto &cbb : ctx.cbbs) {
initBackgroundBufferset(ctx.bgShader, cbb, 0); initBackgroundBufferset(ctx.bgShader, cbb);
} }
renderer::initSpritesBufferset(ctx); renderer::initSpritesBufferset(ctx);
if (initParams.glInstallDrawer) { if (initParams.glInstallDrawer) {
@ -606,7 +605,7 @@ void setBgStatus(Context &ctx, uint_t bg, bool status) noexcept {
void clearTileLayer(Context &ctx, uint_t bgIdx) noexcept { void clearTileLayer(Context &ctx, uint_t bgIdx) noexcept {
auto &cbb = ctx.cbbs[static_cast<std::size_t>(bgIdx)]; auto &cbb = ctx.cbbs[static_cast<std::size_t>(bgIdx)];
initBackgroundBufferObjects(cbb, 0); initBackgroundBufferObjects(cbb);
cbb.updated = true; cbb.updated = true;
auto &bg = ctx.backgrounds[static_cast<std::size_t>(bgIdx)]; auto &bg = ctx.backgrounds[static_cast<std::size_t>(bgIdx)];
bg.priority = 0; bg.priority = 0;

View File

@ -17,7 +17,6 @@ namespace nostalgia::core::renderer {
constexpr uint64_t TileRows = 128; constexpr uint64_t TileRows = 128;
constexpr uint64_t TileColumns = 128; constexpr uint64_t TileColumns = 128;
constexpr uint64_t TileCount = TileRows * TileColumns; constexpr uint64_t TileCount = TileRows * TileColumns;
constexpr uint64_t SpriteCount = 128;
constexpr uint64_t BgVertexVboRows = 4; constexpr uint64_t BgVertexVboRows = 4;
constexpr uint64_t BgVertexVboRowLength = 6; constexpr uint64_t BgVertexVboRowLength = 6;
constexpr uint64_t BgVertexVboLength = BgVertexVboRows * BgVertexVboRowLength; constexpr uint64_t BgVertexVboLength = BgVertexVboRows * BgVertexVboRowLength;
@ -26,7 +25,6 @@ constexpr uint64_t SpriteVertexVboRows = 4;
constexpr uint64_t SpriteVertexVboRowLength = 6; constexpr uint64_t SpriteVertexVboRowLength = 6;
constexpr uint64_t SpriteVertexVboLength = SpriteVertexVboRows * SpriteVertexVboRowLength; constexpr uint64_t SpriteVertexVboLength = SpriteVertexVboRows * SpriteVertexVboRowLength;
constexpr uint64_t SpriteVertexEboLength = 6; constexpr uint64_t SpriteVertexEboLength = 6;
constexpr uint64_t BlocksPerSprite = 64;
struct CBB: public glutils::BufferSet { struct CBB: public glutils::BufferSet {
bool updated = false; bool updated = false;
@ -38,9 +36,9 @@ struct CBB: public glutils::BufferSet {
struct SpriteBlockset: public glutils::BufferSet { struct SpriteBlockset: public glutils::BufferSet {
bool updated = false; bool updated = false;
constexpr SpriteBlockset() noexcept { constexpr SpriteBlockset(uint64_t spriteCount, uint64_t blocksPerSprite) noexcept {
vertices.resize(SpriteCount * SpriteVertexVboLength * BlocksPerSprite); vertices.resize(spriteCount * SpriteVertexVboLength * blocksPerSprite);
elements.resize(SpriteCount * SpriteVertexEboLength * BlocksPerSprite); elements.resize(spriteCount * SpriteVertexEboLength * blocksPerSprite);
} }
}; };