[nostalgia/core] Fix OpenGL sprites, add priority
This commit is contained in:
parent
2b8dbb88b2
commit
59016ee894
@ -16,23 +16,26 @@ namespace nostalgia::core {
|
||||
extern ox::Array<char, 128> charMap;
|
||||
|
||||
struct Sprite {
|
||||
unsigned idx = 0;
|
||||
bool enabled = false;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
unsigned tileIdx = 0;
|
||||
unsigned spriteShape = 0;
|
||||
unsigned spriteSize = 0;
|
||||
unsigned flipX = 0;
|
||||
unsigned priority = 0;
|
||||
};
|
||||
|
||||
oxModelBegin(Sprite)
|
||||
oxModelField(idx)
|
||||
oxModelField(x)
|
||||
oxModelField(y)
|
||||
oxModelField(enabled)
|
||||
oxModelField(tileIdx)
|
||||
oxModelField(spriteShape)
|
||||
oxModelField(spriteSize)
|
||||
oxModelField(flipX)
|
||||
oxModelField(priority)
|
||||
oxModelEnd()
|
||||
|
||||
[[nodiscard]]
|
||||
@ -70,10 +73,9 @@ void clearTileLayer(Context &ctx, unsigned bgIdx) noexcept;
|
||||
|
||||
void hideSprite(Context &ctx, unsigned) noexcept;
|
||||
|
||||
void setSprite(Context &ctx, unsigned idx, int x, int y, unsigned tileIdx,
|
||||
unsigned spriteShape = 0, unsigned spriteSize = 0, unsigned flipX = 0) noexcept;
|
||||
void showSprite(Context &ctx, unsigned) noexcept;
|
||||
|
||||
void setSprite(Context &ctx, Sprite const&s) noexcept;
|
||||
void setSprite(Context &c, uint_t idx, Sprite const&s) noexcept;
|
||||
|
||||
}
|
||||
|
||||
|
@ -216,32 +216,37 @@ void clearTileLayer(Context&, unsigned bgIdx) noexcept {
|
||||
void hideSprite(Context&, unsigned idx) noexcept {
|
||||
//oxAssert(g_spriteUpdates < config::GbaSpriteBufferLen, "Sprite update buffer overflow");
|
||||
teagba::GbaSpriteAttrUpdate oa;
|
||||
oa.attr0 = 2 << 8;
|
||||
oa.attr0 = uint16_t{0b11 << 8};
|
||||
oa.idx = static_cast<uint16_t>(idx);
|
||||
teagba::addSpriteUpdate(oa);
|
||||
}
|
||||
|
||||
void setSprite(Context&,
|
||||
unsigned idx,
|
||||
int x,
|
||||
int y,
|
||||
unsigned tileIdx,
|
||||
unsigned spriteShape,
|
||||
unsigned spriteSize,
|
||||
unsigned flipX) noexcept {
|
||||
[[maybe_unused]]
|
||||
void showSprite(Context&, unsigned idx) noexcept {
|
||||
//oxAssert(g_spriteUpdates < config::GbaSpriteBufferLen, "Sprite update buffer overflow");
|
||||
teagba::GbaSpriteAttrUpdate oa;
|
||||
oa.attr0 = static_cast<uint16_t>(
|
||||
static_cast<uint16_t>(y & ox::onMask<uint8_t>(0b111'1111))
|
||||
| (static_cast<uint16_t>(1) << 10) // enable alpha
|
||||
| (static_cast<uint16_t>(spriteShape) << 14));
|
||||
oa.attr1 = static_cast<uint16_t>(
|
||||
(static_cast<uint16_t>(x) & ox::onMask<uint8_t>(8))
|
||||
| (static_cast<uint16_t>(flipX) << 12)
|
||||
| (static_cast<uint16_t>(spriteSize) << 14));
|
||||
oa.attr2 = static_cast<uint16_t>(tileIdx & ox::onMask<uint16_t>(8));
|
||||
oa.attr0 &= uint16_t{0b1111'1100'1111'1111};
|
||||
oa.idx = static_cast<uint16_t>(idx);
|
||||
teagba::addSpriteUpdate(oa);
|
||||
}
|
||||
|
||||
void setSprite(Context&, uint_t idx, Sprite const&s) noexcept {
|
||||
//oxAssert(g_spriteUpdates < config::GbaSpriteBufferLen, "Sprite update buffer overflow");
|
||||
teagba::GbaSpriteAttrUpdate const oa{
|
||||
.attr0 = static_cast<uint16_t>(
|
||||
(static_cast<uint16_t>(s.y & ox::onMask<uint8_t>(0b111'1111)))
|
||||
| (static_cast<uint16_t>(1) << 10) // enable alpha
|
||||
| (static_cast<uint16_t>(s.spriteShape) << 14)),
|
||||
.attr1 = static_cast<uint16_t>(
|
||||
(static_cast<uint16_t>(s.x) & ox::onMask<uint8_t>(8))
|
||||
| (static_cast<uint16_t>(s.flipX) << 12)
|
||||
| (static_cast<uint16_t>(s.spriteSize) << 14)),
|
||||
.attr2 = static_cast<uint16_t>(
|
||||
(static_cast<uint16_t>(s.tileIdx & ox::onMask<uint16_t>(8)))
|
||||
| (static_cast<uint16_t>(s.priority & 0b11) << 10)),
|
||||
.idx = static_cast<uint16_t>(idx),
|
||||
};
|
||||
teagba::addSpriteUpdate(oa);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -137,8 +137,4 @@ ox::Array<char, 128> charMap = {
|
||||
50, // ~
|
||||
};
|
||||
|
||||
void setSprite(Context &c, Sprite const&s) noexcept {
|
||||
setSprite(c, s.idx, s.x, s.y, s.tileIdx, s.spriteShape, s.spriteSize, s.flipX);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -27,6 +27,10 @@ class Context {
|
||||
ox::Array<renderer::Background, 4> backgrounds;
|
||||
renderer::Drawer drawer;
|
||||
explicit Context(turbine::Context &tctx) noexcept;
|
||||
Context(Context const&) = delete;
|
||||
Context(Context&&) = delete;
|
||||
Context &operator=(Context const&) = delete;
|
||||
Context &operator=(Context&&) = delete;
|
||||
~Context() noexcept;
|
||||
};
|
||||
|
||||
|
@ -29,7 +29,7 @@ void Drawer::draw(turbine::Context &tctx) noexcept {
|
||||
core::gl::draw(m_ctx, turbine::getScreenSize(tctx));
|
||||
}
|
||||
|
||||
constexpr ox::StringView bgvshadTmpl = R"glsl(
|
||||
constexpr ox::CStringView bgvshadTmpl = R"glsl(
|
||||
{}
|
||||
in vec2 vTexCoord;
|
||||
in vec2 vPosition;
|
||||
@ -41,13 +41,13 @@ constexpr ox::StringView bgvshadTmpl = R"glsl(
|
||||
float xScaleInvert = 1.0 - vXScale;
|
||||
gl_Position = vec4(
|
||||
vPosition.x * vXScale - xScaleInvert, vPosition.y,
|
||||
0.0, 1.0);
|
||||
0.5, 1.0);
|
||||
fTexCoord = vec2(
|
||||
vTexCoord.x,
|
||||
vTexCoord.y * vTileHeight + vTileIdx * vTileHeight);
|
||||
})glsl";
|
||||
|
||||
constexpr ox::StringView bgfshadTmpl = R"glsl(
|
||||
constexpr ox::CStringView bgfshadTmpl = R"glsl(
|
||||
{}
|
||||
out vec4 outColor;
|
||||
in vec2 fTexCoord;
|
||||
@ -55,17 +55,17 @@ constexpr ox::StringView bgfshadTmpl = R"glsl(
|
||||
uniform vec2 fSrcImgSz;
|
||||
uniform vec4 fPalette[256];
|
||||
void main() {
|
||||
vec2 pixelSz = vec2(1, 1) / (fSrcImgSz);
|
||||
vec2 pixelSz = vec2(1, 1) / fSrcImgSz;
|
||||
vec2 pixelCoord = floor(fTexCoord / pixelSz) * pixelSz;
|
||||
outColor = fPalette[int(texture(image, fTexCoord).rgb.r * 256)];
|
||||
//outColor = vec4(0.0, 0.7, 1.0, 1.0);
|
||||
})glsl";
|
||||
|
||||
constexpr ox::StringView spritevshadTmpl = R"glsl(
|
||||
constexpr ox::CStringView spritevshadTmpl = R"glsl(
|
||||
{}
|
||||
in float vEnabled;
|
||||
in vec3 vPosition;
|
||||
in vec2 vTexCoord;
|
||||
in vec2 vPosition;
|
||||
out vec2 fTexCoord;
|
||||
uniform float vXScale;
|
||||
uniform float vTileHeight;
|
||||
@ -73,11 +73,23 @@ constexpr ox::StringView spritevshadTmpl = R"glsl(
|
||||
float xScaleInvert = 1.0 - vXScale;
|
||||
gl_Position = vec4(
|
||||
vPosition.x * vXScale - xScaleInvert, vPosition.y,
|
||||
0.0, 1.0);
|
||||
vPosition.z, 1.0);
|
||||
fTexCoord = vTexCoord * vec2(1, vTileHeight) * vec2(vEnabled, vEnabled);
|
||||
})glsl";
|
||||
|
||||
constexpr ox::StringView spritefshadTmpl = bgfshadTmpl;
|
||||
constexpr ox::CStringView spritefshadTmpl = R"glsl(
|
||||
{}
|
||||
out vec4 outColor;
|
||||
in vec2 fTexCoord;
|
||||
uniform sampler2D image;
|
||||
uniform vec2 fSrcImgSz;
|
||||
uniform vec4 fPalette[256];
|
||||
void main() {
|
||||
vec2 pixelSz = vec2(1, 1) / fSrcImgSz;
|
||||
vec2 pixelCoord = floor(fTexCoord / pixelSz) * pixelSz;
|
||||
outColor = fPalette[int(texture(image, fTexCoord).rgb.r * 256)];
|
||||
//outColor = vec4(0.0, 0.7, 1.0, 1.0);
|
||||
})glsl";;
|
||||
|
||||
[[nodiscard]]
|
||||
static constexpr auto bgVertexRow(uint_t x, uint_t y) noexcept {
|
||||
@ -91,6 +103,7 @@ static void setSpriteBufferObject(
|
||||
float y,
|
||||
uint_t textureRow,
|
||||
uint_t flipX,
|
||||
uint_t priority,
|
||||
float *vbo,
|
||||
GLuint *ebo) noexcept {
|
||||
// don't worry, this memcpy gets optimized to something much more ideal
|
||||
@ -100,17 +113,19 @@ static void setSpriteBufferObject(
|
||||
y *= -ymod;
|
||||
x -= 1.f;
|
||||
y += 1.f - ymod;
|
||||
const auto textureRowf = static_cast<float>(textureRow);
|
||||
const float L = flipX ? 1 : 0;
|
||||
const float R = flipX ? 0 : 1;
|
||||
const ox::Array<float, SpriteVertexVboLength> vertices {
|
||||
enabled, x, y, L, textureRowf + 1, // bottom left
|
||||
enabled, x + xmod, y, R, textureRowf + 1, // bottom right
|
||||
enabled, x + xmod, y + ymod, R, textureRowf + 0, // top right
|
||||
enabled, x, y + ymod, L, textureRowf + 0, // top left
|
||||
auto const prif = static_cast<float>(priority) * 0.1f;
|
||||
auto const textureRowf = static_cast<float>(textureRow);
|
||||
float const L = flipX ? 1 : 0;
|
||||
float const R = flipX ? 0 : 1;
|
||||
ox::Array<float, SpriteVertexVboLength> const vertices {
|
||||
// vEnabled| vPosition | vTexCoord
|
||||
enabled, x, y, prif, L, textureRowf + 1, // bottom left
|
||||
enabled, x + xmod, y, prif, R, textureRowf + 1, // bottom right
|
||||
enabled, x + xmod, y + ymod, prif, R, textureRowf + 0, // top right
|
||||
enabled, x, y + ymod, prif, L, textureRowf + 0, // top left
|
||||
};
|
||||
memcpy(vbo, vertices.data(), sizeof(vertices));
|
||||
const ox::Array<GLuint, SpriteVertexEboLength> elms {
|
||||
ox::Array<GLuint, SpriteVertexEboLength> const elms {
|
||||
vi + 0, vi + 1, vi + 2,
|
||||
vi + 2, vi + 3, vi + 0,
|
||||
};
|
||||
@ -149,7 +164,7 @@ static void initSpriteBufferObjects(glutils::BufferSet &bs) noexcept {
|
||||
for (auto i = 0u; i < 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, 0, 0, 0, 0, false, vbo, ebo);
|
||||
setSpriteBufferObject(i * SpriteVertexVboRows * BlocksPerSprite, 0, 0, 0, 0, false, 0, vbo, ebo);
|
||||
}
|
||||
}
|
||||
|
||||
@ -170,7 +185,9 @@ static void initBackgroundBufferObjects(glutils::BufferSet &bg) noexcept {
|
||||
}
|
||||
}
|
||||
|
||||
static void initSpritesBufferset(GLuint shader, glutils::BufferSet &bs) noexcept {
|
||||
static void initSpritesBufferset(Context &ctx) noexcept {
|
||||
auto const shader = ctx.spriteShader.id;
|
||||
auto &bs = ctx.spriteBlocks;
|
||||
// vao
|
||||
bs.vao = glutils::generateVertexArrayObject();
|
||||
glBindVertexArray(bs.vao);
|
||||
@ -181,17 +198,20 @@ static void initSpritesBufferset(GLuint shader, glutils::BufferSet &bs) noexcept
|
||||
glutils::sendVbo(bs);
|
||||
glutils::sendEbo(bs);
|
||||
// vbo layout
|
||||
// in float vEnabled;
|
||||
auto const enabledAttr = static_cast<GLuint>(glGetAttribLocation(shader, "vEnabled"));
|
||||
glEnableVertexAttribArray(enabledAttr);
|
||||
glVertexAttribPointer(enabledAttr, 1, GL_FLOAT, GL_FALSE, SpriteVertexVboRowLength * sizeof(float), nullptr);
|
||||
// in vec3 vPosition;
|
||||
auto const posAttr = static_cast<GLuint>(glGetAttribLocation(shader, "vPosition"));
|
||||
glEnableVertexAttribArray(posAttr);
|
||||
glVertexAttribPointer(posAttr, 2, GL_FLOAT, GL_FALSE, SpriteVertexVboRowLength * sizeof(float),
|
||||
glVertexAttribPointer(posAttr, 3, GL_FLOAT, GL_FALSE, SpriteVertexVboRowLength * sizeof(float),
|
||||
std::bit_cast<void*>(uintptr_t{1 * sizeof(float)}));
|
||||
// in vec2 vTexCoord;
|
||||
auto const texCoordAttr = static_cast<GLuint>(glGetAttribLocation(shader, "vTexCoord"));
|
||||
glEnableVertexAttribArray(texCoordAttr);
|
||||
glVertexAttribPointer(texCoordAttr, 2, GL_FLOAT, GL_FALSE, SpriteVertexVboRowLength * sizeof(float),
|
||||
std::bit_cast<void*>(uintptr_t{3 * sizeof(float)}));
|
||||
std::bit_cast<void*>(uintptr_t{4 * sizeof(float)}));
|
||||
}
|
||||
|
||||
static void initBackgroundBufferset(
|
||||
@ -347,11 +367,86 @@ static void loadSpriteTexture(
|
||||
ctx.spriteBlocks.tex = createTexture(w, h, pixels);
|
||||
}
|
||||
|
||||
static void setSprite(
|
||||
Context &ctx,
|
||||
uint_t const idx,
|
||||
Sprite const&s) noexcept {
|
||||
// Tonc Table 8.4
|
||||
static constexpr ox::Array<ox::Vec<uint_t>, 12> dimensions{
|
||||
// col 0
|
||||
{1, 1}, // 0, 0
|
||||
{2, 2}, // 0, 1
|
||||
{4, 4}, // 0, 2
|
||||
{8, 8}, // 0, 3
|
||||
// col 1
|
||||
{2, 1}, // 1, 0
|
||||
{4, 1}, // 1, 1
|
||||
{4, 2}, // 1, 2
|
||||
{8, 4}, // 1, 3
|
||||
// col 2
|
||||
{1, 1}, // 2, 0
|
||||
{1, 4}, // 2, 1
|
||||
{2, 4}, // 2, 2
|
||||
{4, 8}, // 2, 3
|
||||
};
|
||||
oxAssert(idx < ctx.spriteStates.size(), "overflow");
|
||||
auto const dim = dimensions[(s.spriteShape << 2) | s.spriteSize];
|
||||
auto const uX = static_cast<int>(s.x) % 255;
|
||||
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;
|
||||
auto const vboBase = spriteVboSz * idx;
|
||||
auto const eboBase = spriteEboSz * idx;
|
||||
auto i = 0u;
|
||||
const auto set = [&](int xIt, int yIt, bool enabled) {
|
||||
auto const fX = static_cast<float>(uX + xIt * 8) / 8;
|
||||
auto const fY = static_cast<float>(uY + yIt * 8) / 8;
|
||||
auto const vboIdx = vboBase + renderer::SpriteVertexVboLength * i;
|
||||
auto const eboIdx = eboBase + renderer::SpriteVertexEboLength * i;
|
||||
oxAssert(vboIdx < ctx.spriteBlocks.vertices.size(), "vbo overflow");
|
||||
oxAssert(eboIdx < ctx.spriteBlocks.elements.size(), "ebo overflow");
|
||||
auto const vbo = &ctx.spriteBlocks.vertices[vboIdx];
|
||||
auto const ebo = &ctx.spriteBlocks.elements[eboIdx];
|
||||
renderer::setSpriteBufferObject(
|
||||
static_cast<uint_t>(vboIdx),
|
||||
enabled,
|
||||
fX,
|
||||
fY,
|
||||
s.tileIdx + i,
|
||||
s.flipX,
|
||||
s.priority,
|
||||
vbo,
|
||||
ebo);
|
||||
++i;
|
||||
};
|
||||
if (!s.flipX) {
|
||||
for (auto yIt = 0; yIt < static_cast<int>(dim.y); ++yIt) {
|
||||
for (auto xIt = 0u; xIt < dim.x; ++xIt) {
|
||||
set(static_cast<int>(xIt), static_cast<int>(yIt), s.enabled);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (auto yIt = 0u; yIt < dim.y; ++yIt) {
|
||||
for (auto xIt = dim.x - 1; xIt < ~0u; --xIt) {
|
||||
set(static_cast<int>(xIt), static_cast<int>(yIt), s.enabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
// clear remaining blocks in the sprite
|
||||
for (; i < BlocksPerSprite; ++i) {
|
||||
set(0, 0, false);
|
||||
}
|
||||
ctx.spriteBlocks.updated = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ox::Error initGfx(
|
||||
Context &ctx,
|
||||
InitParams const&initParams) noexcept {
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
const auto bgVshad = ox::sfmt(renderer::bgvshadTmpl, gl::GlslVersion);
|
||||
@ -364,7 +459,7 @@ ox::Error initGfx(
|
||||
for (auto &bg : ctx.cbbs) {
|
||||
initBackgroundBufferset(ctx.bgShader, bg);
|
||||
}
|
||||
initSpritesBufferset(ctx.spriteShader, ctx.spriteBlocks);
|
||||
renderer::initSpritesBufferset(ctx);
|
||||
if (initParams.glInstallDrawer) {
|
||||
turbine::gl::addDrawer(ctx.turbineCtx, &ctx.drawer);
|
||||
}
|
||||
@ -497,77 +592,21 @@ void clearTileLayer(Context &ctx, uint_t bgIdx) noexcept {
|
||||
}
|
||||
|
||||
void hideSprite(Context &ctx, uint_t idx) noexcept {
|
||||
auto vbo = &ctx.spriteBlocks.vertices[idx * renderer::SpriteVertexVboLength];
|
||||
auto ebo = &ctx.spriteBlocks.elements[idx * renderer::SpriteVertexEboLength];
|
||||
renderer::setSpriteBufferObject(
|
||||
idx * renderer::SpriteVertexVboRows, 0, 0, 0, 0, false, vbo, ebo);
|
||||
ctx.spriteBlocks.updated = true;
|
||||
auto &s = ctx.spriteStates[idx];
|
||||
s.enabled = false;
|
||||
renderer::setSprite(ctx, idx, s);
|
||||
}
|
||||
|
||||
void setSprite(
|
||||
Context &ctx,
|
||||
uint_t idx,
|
||||
int x,
|
||||
int y,
|
||||
uint_t tileIdx,
|
||||
uint_t spriteShape,
|
||||
uint_t spriteSize,
|
||||
uint_t flipX) noexcept {
|
||||
//oxTracef("nostalgia::core::gfx::gl", "setSprite(ctx, {}, {}, {}, {}, {}, {}, {})",
|
||||
// idx, x, y, tileIdx, spriteShape, spriteSize, flipX);
|
||||
// Tonc Table 8.4
|
||||
static constexpr ox::Array<ox::Vec<uint_t>, 12> dimensions{
|
||||
// col 0
|
||||
{1, 1}, // 0, 0
|
||||
{2, 2}, // 0, 1
|
||||
{4, 4}, // 0, 2
|
||||
{8, 8}, // 0, 3
|
||||
// col 1
|
||||
{2, 1}, // 1, 0
|
||||
{4, 1}, // 1, 1
|
||||
{4, 2}, // 1, 2
|
||||
{8, 4}, // 1, 3
|
||||
// col 2
|
||||
{1, 1}, // 2, 0
|
||||
{1, 4}, // 2, 1
|
||||
{2, 4}, // 2, 2
|
||||
{4, 8}, // 2, 3
|
||||
};
|
||||
const auto dim = dimensions[(spriteShape << 2) | spriteSize];
|
||||
const auto uX = static_cast<int>(x) % 255;
|
||||
const auto uY = static_cast<int>(y + 8) % 255 - 8;
|
||||
auto i = 0u;
|
||||
const auto set = [&](int xIt, int yIt) {
|
||||
const auto fX = static_cast<float>(uX + xIt * 8) / 8;
|
||||
const auto fY = static_cast<float>(uY + yIt * 8) / 8;
|
||||
const auto cidx = idx + i;
|
||||
auto vbo = &ctx.spriteBlocks.vertices[cidx * renderer::SpriteVertexVboLength];
|
||||
auto ebo = &ctx.spriteBlocks.elements[cidx * renderer::SpriteVertexEboLength];
|
||||
renderer::setSpriteBufferObject(
|
||||
cidx * renderer::SpriteVertexVboRows,
|
||||
1,
|
||||
fX,
|
||||
fY,
|
||||
tileIdx + i,
|
||||
flipX,
|
||||
vbo,
|
||||
ebo);
|
||||
++i;
|
||||
};
|
||||
if (!flipX) {
|
||||
for (auto yIt = 0; yIt < static_cast<int>(dim.y); ++yIt) {
|
||||
for (auto xIt = 0u; xIt < dim.x; ++xIt) {
|
||||
set(static_cast<int>(xIt), static_cast<int>(yIt));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (auto yIt = 0u; yIt < dim.y; ++yIt) {
|
||||
for (auto xIt = dim.x - 1; xIt < ~0u; --xIt) {
|
||||
set(static_cast<int>(xIt), static_cast<int>(yIt));
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx.spriteBlocks.updated = true;
|
||||
void showSprite(Context &ctx, uint_t idx) noexcept {
|
||||
auto &s = ctx.spriteStates[idx];
|
||||
s.enabled = true;
|
||||
renderer::setSprite(ctx, idx, s);
|
||||
}
|
||||
|
||||
void setSprite(Context &ctx, uint_t idx, Sprite const&sprite) noexcept {
|
||||
auto &s = ctx.spriteStates[idx];
|
||||
s = sprite;
|
||||
renderer::setSprite(ctx, idx, s);
|
||||
}
|
||||
|
||||
void setTile(
|
||||
@ -605,7 +644,8 @@ ox::Size drawSize(int scale) noexcept {
|
||||
|
||||
void draw(core::Context &ctx, ox::Size const&renderSz) noexcept {
|
||||
glViewport(0, 0, renderSz.width, renderSz.height);
|
||||
glutils::clearScreen();
|
||||
glClearColor(0, 0, 0, 1);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
renderer::drawBackgrounds(ctx, renderSz);
|
||||
if (ctx.spriteBlocks.tex) {
|
||||
renderer::drawSprites(ctx, renderSz);
|
||||
|
@ -22,10 +22,11 @@ constexpr uint64_t BgVertexVboRows = 4;
|
||||
constexpr uint64_t BgVertexVboRowLength = 5;
|
||||
constexpr uint64_t BgVertexVboLength = BgVertexVboRows * BgVertexVboRowLength;
|
||||
constexpr uint64_t BgVertexEboLength = 6;
|
||||
constexpr uint64_t SpriteVertexVboRows = 256;
|
||||
constexpr uint64_t SpriteVertexVboRowLength = 5;
|
||||
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,8 +39,8 @@ struct CBB: public glutils::BufferSet {
|
||||
struct SpriteBlockset: public glutils::BufferSet {
|
||||
bool updated = false;
|
||||
constexpr SpriteBlockset() noexcept {
|
||||
vertices.resize(SpriteCount * SpriteVertexVboLength);
|
||||
elements.resize(SpriteCount * SpriteVertexEboLength);
|
||||
vertices.resize(SpriteCount * SpriteVertexVboLength * BlocksPerSprite);
|
||||
elements.resize(SpriteCount * SpriteVertexEboLength * BlocksPerSprite);
|
||||
}
|
||||
};
|
||||
|
||||
@ -48,10 +49,6 @@ struct Background {
|
||||
unsigned cbbIdx = 0;
|
||||
};
|
||||
|
||||
struct Sprite {
|
||||
bool enabled = false;
|
||||
};
|
||||
|
||||
class Drawer: public turbine::gl::Drawer {
|
||||
private:
|
||||
Context &m_ctx;
|
||||
@ -65,4 +62,4 @@ class Drawer: public turbine::gl::Drawer {
|
||||
namespace nostalgia::core {
|
||||
ox::Error initGfx(Context &ctx, InitParams const&) noexcept;
|
||||
void shutdownGfx(Context &ctx) noexcept;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user