[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 {
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);
}
Context::Context(turbine::Context &tctx) noexcept:
Context::Context(turbine::Context &tctx, InitParams const&params) noexcept:
turbineCtx(tctx),
drawer(*this) {
spriteBlocks(params.glSpriteCount, params.glBlocksPerSprite),
drawer(*this),
spriteCount(params.glSpriteCount),
blocksPerSprite(params.glBlocksPerSprite) {
}
Context::~Context() noexcept {
@ -21,7 +24,7 @@ Context::~Context() 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));
return ContextUPtr(ctx.release());
}

View File

@ -26,7 +26,9 @@ class Context {
ox::Array<Sprite, 128> spriteStates;
ox::Array<renderer::Background, 4> backgrounds;
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&&) = delete;
Context &operator=(Context const&) = delete;

View File

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

View File

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