[nostalgia] Add start for Scene editor in Studio

This commit is contained in:
2023-03-11 16:59:26 -06:00
parent 19d5641c6e
commit ae9272841f
37 changed files with 357 additions and 295 deletions
+74 -18
View File
@@ -18,6 +18,16 @@ namespace nostalgia::core {
void ImGui_Impl_NewFrame() noexcept;
namespace gl {
static bool mainViewEnabled = true;
void setMainViewEnabled(bool enabled) noexcept {
mainViewEnabled = enabled;
}
}
namespace renderer {
constexpr uint64_t TileRows = 128;
@@ -67,6 +77,7 @@ struct GlImplData {
SpriteBlockset spriteBlocks;
ox::Array<Sprite, 128> spriteStates;
ox::Array<Background, 4> backgrounds;
ox::Optional<geo::Size> renderSize;
};
constexpr ox::StringView bgvshadTmpl = R"(
@@ -74,9 +85,13 @@ constexpr ox::StringView bgvshadTmpl = R"(
in vec2 vTexCoord;
in vec2 vPosition;
out vec2 fTexCoord;
uniform float vXScale;
uniform float vTileHeight;
void main() {
gl_Position = vec4(vPosition, 0.0, 1.0);
float xScaleInvert = 1.0 - vXScale;
gl_Position = vec4(
vPosition.x * vXScale - xScaleInvert, vPosition.y,
0.0, 1.0);
fTexCoord = vTexCoord * vec2(1, vTileHeight);
})";
@@ -98,9 +113,13 @@ constexpr ox::StringView spritevshadTmpl = R"(
in vec2 vTexCoord;
in vec2 vPosition;
out vec2 fTexCoord;
uniform float vXScale;
uniform float vTileHeight;
void main() {
gl_Position = vec4(vPosition, 0.0, 1.0);
float xScaleInvert = 1.0 - vXScale;
gl_Position = vec4(
vPosition.x * vXScale - xScaleInvert, vPosition.y,
0.0, 1.0);
fTexCoord = vTexCoord * vec2(1, vTileHeight) * vec2(vEnabled, vEnabled);
})";
@@ -111,7 +130,7 @@ static constexpr auto bgVertexRow(unsigned x, unsigned y) noexcept {
return y * TileRows + x;
}
static void setSpriteBufferObject(Context *ctx,
static void setSpriteBufferObject(Context*,
unsigned vi,
float enabled,
float x, float y,
@@ -120,9 +139,8 @@ static void setSpriteBufferObject(Context *ctx,
float *vbo,
GLuint *ebo) noexcept {
// don't worry, this memcpy gets optimized to something much more ideal
const auto [sw, sh] = getScreenSize(ctx);
constexpr float xmod = 0.1f;
constexpr float ymod = 0.1f;
const auto xmod = ymod * static_cast<float>(sh) / static_cast<float>(sw);
x *= xmod;
y *= -ymod;
x -= 1.f;
@@ -144,7 +162,7 @@ static void setSpriteBufferObject(Context *ctx,
memcpy(ebo, elms.data(), sizeof(elms));
}
static void setTileBufferObject(Context *ctx,
static void setTileBufferObject(Context*,
unsigned vi,
float x,
float y,
@@ -152,9 +170,8 @@ static void setTileBufferObject(Context *ctx,
float *vbo,
GLuint *ebo) noexcept {
// don't worry, this memcpy gets optimized to something much more ideal
const auto [sw, sh] = getScreenSize(ctx);
constexpr float ymod = 2.0f / 20.0f;
const float xmod = ymod * static_cast<float>(sh) / static_cast<float>(sw);
constexpr float ymod = 0.1f;
constexpr float xmod = 0.1f;
x *= xmod;
y *= -ymod;
x -= 1.0f;
@@ -279,11 +296,15 @@ static void drawBackground(CBB *cbb) noexcept {
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(cbb->elements.size()), GL_UNSIGNED_INT, nullptr);
}
static void drawBackgrounds(GlImplData *id) noexcept {
static void drawBackgrounds(core::Context *ctx, GlImplData *id) noexcept {
// load background shader and its uniforms
glUseProgram(id->bgShader);
const auto uniformXScale = static_cast<GLint>(glGetUniformLocation(id->bgShader, "vXScale"));
const auto uniformTileHeight = static_cast<GLint>(glGetUniformLocation(id->bgShader, "vTileHeight"));
//glUniform3fv(uniformPalette, GlImplData::ColorCnt, id->palette.data());
const auto [wi, hi] = gl::getRenderSize(ctx);
const auto wf = static_cast<float>(wi);
const auto hf = static_cast<float>(hi);
glUniform1f(uniformXScale, hf / wf);
for (const auto &bg : id->backgrounds) {
if (bg.enabled) {
auto &cbb = id->cbbs[bg.cbbIdx];
@@ -294,10 +315,15 @@ static void drawBackgrounds(GlImplData *id) noexcept {
}
}
static void drawSprites(GlImplData *id) noexcept {
static void drawSprites(core::Context *ctx, GlImplData *id) noexcept {
glUseProgram(id->spriteShader);
auto &sb = id->spriteBlocks;
const auto uniformXScale = static_cast<GLint>(glGetUniformLocation(id->bgShader, "vXScale"));
const auto uniformTileHeight = static_cast<GLint>(glGetUniformLocation(id->spriteShader, "vTileHeight"));
const auto [wi, hi] = gl::getRenderSize(ctx);
const auto wf = static_cast<float>(wi);
const auto hf = static_cast<float>(hi);
glUniform1f(uniformXScale, hf / wf);
// update vbo
glBindVertexArray(sb.vao);
if (sb.updated) {
@@ -312,7 +338,7 @@ static void drawSprites(GlImplData *id) noexcept {
glDrawElements(GL_TRIANGLES, static_cast<GLsizei>(sb.elements.size()), GL_UNSIGNED_INT, nullptr);
}
ox::Error init(Context *ctx, void **rendererData) noexcept {
ox::Error init(Context *ctx) noexcept {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
const auto bgVshad = ox::sfmt(bgvshadTmpl, glutils::GlslVersion);
@@ -320,7 +346,7 @@ ox::Error init(Context *ctx, void **rendererData) noexcept {
const auto spriteVshad = ox::sfmt(spritevshadTmpl, glutils::GlslVersion);
const auto spriteFshad = ox::sfmt(spritefshadTmpl, glutils::GlslVersion);
const auto id = ox::make<GlImplData>();
*rendererData = id;
ctx->setRendererData(id);
oxReturnError(glutils::buildShaderProgram(bgVshad.c_str(), bgFshad.c_str()).moveTo(&id->bgShader));
oxReturnError(glutils::buildShaderProgram(spriteVshad.c_str(), spriteFshad.c_str()).moveTo(&id->spriteShader));
for (auto &bg : id->cbbs) {
@@ -328,7 +354,7 @@ ox::Error init(Context *ctx, void **rendererData) noexcept {
}
initSpritesBufferset(ctx, id->spriteShader, &id->spriteBlocks);
ImGui_ImplOpenGL3_Init(glutils::GlslVersion);
return OxError(0);
return {};
}
void shutdown(Context*, void *rendererData) noexcept {
@@ -422,9 +448,8 @@ void draw(Context *ctx) noexcept {
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT);
// render
renderer::drawBackgrounds(id);
if (id->spriteBlocks.tex) {
renderer::drawSprites(id);
if (gl::mainViewEnabled) {
gl::drawMainView(ctx);
}
for (const auto cd : ctx->drawers) {
cd->draw(ctx);
@@ -530,4 +555,35 @@ void setTile(Context *ctx, unsigned bgIdx, int column, int row, uint8_t tile) no
bg.updated = true;
}
namespace gl {
void drawMainView(core::Context *ctx) noexcept {
const auto id = ctx->rendererData<renderer::GlImplData>();
renderer::drawBackgrounds(ctx, id);
if (id->spriteBlocks.tex) {
renderer::drawSprites(ctx, id);
}
}
void setRenderSize(core::Context *ctx, int width, int height) noexcept {
const auto id = ctx->rendererData<renderer::GlImplData>();
id->renderSize.emplace(width, height);
}
void clearRenderSize(core::Context *ctx) noexcept {
auto id = ctx->rendererData<renderer::GlImplData>();
id->renderSize.reset();
}
geo::Size getRenderSize(core::Context *ctx) noexcept {
const auto id = ctx->rendererData<renderer::GlImplData>();
if (id->renderSize.has_value()) {
return id->renderSize.value();
} else {
return core::getScreenSize(ctx);
}
}
}
}