[nostalgia/gfx] Consolidate implementations into single files, remove unnecessary function exports
All checks were successful
Build / build (push) Successful in 1m17s
All checks were successful
Build / build (push) Successful in 1m17s
This commit is contained in:
parent
a6814030ee
commit
7b8ddc189a
@ -11,11 +11,9 @@
|
|||||||
|
|
||||||
#include "color.hpp"
|
#include "color.hpp"
|
||||||
#include "context.hpp"
|
#include "context.hpp"
|
||||||
#include "context.hpp"
|
|
||||||
#include "initparams.hpp"
|
#include "initparams.hpp"
|
||||||
#include "keelmodule.hpp"
|
#include "keelmodule.hpp"
|
||||||
#include "palette.hpp"
|
#include "palette.hpp"
|
||||||
#include "palette.hpp"
|
|
||||||
#include "ptidxconv.hpp"
|
#include "ptidxconv.hpp"
|
||||||
#include "tilesheet.hpp"
|
#include "tilesheet.hpp"
|
||||||
|
|
||||||
|
@ -4,11 +4,6 @@ add_library(
|
|||||||
tilesheet.cpp
|
tilesheet.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_subdirectory(gba)
|
|
||||||
if(NOT BUILDCORE_TARGET STREQUAL "gba")
|
|
||||||
add_subdirectory(opengl)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_include_directories(
|
target_include_directories(
|
||||||
NostalgiaGfx PUBLIC
|
NostalgiaGfx PUBLIC
|
||||||
../include
|
../include
|
||||||
@ -31,3 +26,38 @@ install(
|
|||||||
LIBRARY DESTINATION lib
|
LIBRARY DESTINATION lib
|
||||||
ARCHIVE DESTINATION lib
|
ARCHIVE DESTINATION lib
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# OpenGL
|
||||||
|
|
||||||
|
if(NOT BUILDCORE_TARGET STREQUAL "gba")
|
||||||
|
target_sources(
|
||||||
|
NostalgiaGfx PRIVATE
|
||||||
|
gfx-opengl.cpp
|
||||||
|
)
|
||||||
|
target_link_libraries(
|
||||||
|
NostalgiaGfx PUBLIC
|
||||||
|
GlUtils
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# GBA
|
||||||
|
|
||||||
|
add_library(
|
||||||
|
NostalgiaGfx-GBA OBJECT
|
||||||
|
gfx-gba.cpp
|
||||||
|
)
|
||||||
|
target_include_directories(
|
||||||
|
NostalgiaGfx-GBA PUBLIC
|
||||||
|
../include
|
||||||
|
)
|
||||||
|
target_link_libraries(
|
||||||
|
NostalgiaGfx-GBA PUBLIC
|
||||||
|
TeaGBA
|
||||||
|
Keel
|
||||||
|
Turbine
|
||||||
|
)
|
||||||
|
|
||||||
|
if(BUILDCORE_TARGET STREQUAL "gba")
|
||||||
|
set_source_files_properties(gfx-gba.cpp PROPERTIES COMPILE_FLAGS -marm)
|
||||||
|
target_link_libraries(NostalgiaGfx PUBLIC NostalgiaGfx-GBA)
|
||||||
|
endif()
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
add_library(
|
|
||||||
NostalgiaGfx-GBA OBJECT
|
|
||||||
context.cpp
|
|
||||||
gfx.cpp
|
|
||||||
panic.cpp
|
|
||||||
)
|
|
||||||
target_include_directories(
|
|
||||||
NostalgiaGfx-GBA PUBLIC
|
|
||||||
../../include
|
|
||||||
)
|
|
||||||
target_link_libraries(
|
|
||||||
NostalgiaGfx-GBA PUBLIC
|
|
||||||
TeaGBA
|
|
||||||
Keel
|
|
||||||
Turbine
|
|
||||||
)
|
|
||||||
|
|
||||||
if(BUILDCORE_TARGET STREQUAL "gba")
|
|
||||||
set_source_files_properties(gfx.cpp PROPERTIES COMPILE_FLAGS -marm)
|
|
||||||
target_link_libraries(NostalgiaGfx PUBLIC NostalgiaGfx-GBA)
|
|
||||||
endif()
|
|
@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <turbine/turbine.hpp>
|
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
|
|
||||||
namespace nostalgia::gfx {
|
|
||||||
|
|
||||||
void safeDelete(Context *ctx) noexcept {
|
|
||||||
delete ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
Context::Context(turbine::Context &tctx) noexcept: turbineCtx(tctx) {
|
|
||||||
}
|
|
||||||
|
|
||||||
ox::Error initGfx(Context &ctx, InitParams const&) noexcept;
|
|
||||||
|
|
||||||
ox::Result<ox::UPtr<Context>> init(turbine::Context &tctx, InitParams const¶ms) noexcept {
|
|
||||||
auto ctx = ox::make_unique<Context>(tctx);
|
|
||||||
OX_RETURN_ERROR(initGfx(*ctx, params));
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
keel::Context &keelCtx(Context &ctx) noexcept {
|
|
||||||
return turbine::keelCtx(ctx.turbineCtx);
|
|
||||||
}
|
|
||||||
|
|
||||||
turbine::Context &turbineCtx(Context &ctx) noexcept {
|
|
||||||
return ctx.turbineCtx;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <nostalgia/gfx/context.hpp>
|
|
||||||
|
|
||||||
namespace nostalgia::gfx {
|
|
||||||
|
|
||||||
struct BgCbbData {
|
|
||||||
unsigned bpp = 4;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Context {
|
|
||||||
|
|
||||||
public:
|
|
||||||
turbine::Context &turbineCtx;
|
|
||||||
ox::Array<BgCbbData, 4> cbbData;
|
|
||||||
|
|
||||||
explicit Context(turbine::Context &tctx) noexcept;
|
|
||||||
Context(Context &other) noexcept = delete;
|
|
||||||
Context(Context const&other) noexcept = delete;
|
|
||||||
Context(Context const&&other) noexcept = delete;
|
|
||||||
virtual ~Context() noexcept = default;
|
|
||||||
|
|
||||||
[[nodiscard]]
|
|
||||||
ox::MemFS const&rom() const noexcept {
|
|
||||||
return static_cast<ox::MemFS const&>(*turbine::rom(turbineCtx));
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <nostalgia/gfx/context.hpp>
|
|
||||||
|
|
||||||
namespace nostalgia::gfx {
|
|
||||||
ox::Error initGfx(Context &ctx, InitParams const&) noexcept;
|
|
||||||
}
|
|
@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <ox/std/def.hpp>
|
|
||||||
#include <ox/std/realstd.hpp>
|
|
||||||
|
|
||||||
#include <keel/media.hpp>
|
|
||||||
#include <turbine/turbine.hpp>
|
|
||||||
|
|
||||||
#include <teagba/addresses.hpp>
|
|
||||||
#include <teagba/bios.hpp>
|
|
||||||
|
|
||||||
#include <nostalgia/gfx/gfx.hpp>
|
|
||||||
|
|
||||||
#include "gfx.hpp"
|
|
||||||
|
|
||||||
#define HEAP_BEGIN (reinterpret_cast<char*>(MEM_EWRAM_BEGIN))
|
|
||||||
#define HEAP_SIZE ((MEM_EWRAM_END - MEM_EWRAM_BEGIN) / 2)
|
|
||||||
#define HEAP_END (reinterpret_cast<char*>(MEM_EWRAM_BEGIN + HEAP_SIZE))
|
|
||||||
|
|
||||||
namespace ox {
|
|
||||||
|
|
||||||
using namespace nostalgia::gfx;
|
|
||||||
|
|
||||||
void panic(const char *file, int line, const char *panicMsg, ox::Error const&err) noexcept {
|
|
||||||
// reset heap to make sure we have enough memory to allocate context data
|
|
||||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
|
||||||
ox::heapmgr::initHeap(HEAP_BEGIN, HEAP_END);
|
|
||||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
|
||||||
auto tctx = turbine::init(keel::loadRomFs("").unwrap(), "Nostalgia").unwrap();
|
|
||||||
auto ctx = init(*tctx).unwrap();
|
|
||||||
std::ignore = initGfx(*ctx, {});
|
|
||||||
std::ignore = initConsole(*ctx);
|
|
||||||
setBgStatus(*ctx, 0, true);
|
|
||||||
clearBg(*ctx, 0);
|
|
||||||
auto const serr = ox::sfmt<ox::IString<23>>("Error code: {}", static_cast<int64_t>(err));
|
|
||||||
consoleWrite(*ctx, 32 + 1, 1, "SADNESS...");
|
|
||||||
consoleWrite(*ctx, 32 + 1, 4, "UNEXPECTED STATE:");
|
|
||||||
consoleWrite(*ctx, 32 + 2, 6, panicMsg);
|
|
||||||
if (err) {
|
|
||||||
consoleWrite(*ctx, 32 + 2, 8, serr);
|
|
||||||
}
|
|
||||||
consoleWrite(*ctx, 32 + 1, 15, "PLEASE RESTART THE SYSTEM");
|
|
||||||
// print to terminal if in mGBA
|
|
||||||
oxErrf("\033[31;1;1mPANIC:\033[0m [{}:{}]: {}\n", file, line, panicMsg);
|
|
||||||
if (err.msg) {
|
|
||||||
oxErrf("\tError Message:\t{}\n", err.msg);
|
|
||||||
}
|
|
||||||
oxErrf("\tError Code:\t{}\n", static_cast<ErrorCode>(err));
|
|
||||||
if (err.src.file_name() != nullptr) {
|
|
||||||
oxErrf("\tError Location:\t{}:{}\n", err.src.file_name(), err.src.line());
|
|
||||||
}
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -15,15 +15,48 @@
|
|||||||
#include <nostalgia/gfx/gfx.hpp>
|
#include <nostalgia/gfx/gfx.hpp>
|
||||||
#include <nostalgia/gfx/tilesheet.hpp>
|
#include <nostalgia/gfx/tilesheet.hpp>
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
|
|
||||||
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||||
|
|
||||||
namespace nostalgia::gfx {
|
namespace nostalgia::gfx {
|
||||||
|
|
||||||
|
struct BgCbbData {
|
||||||
|
unsigned bpp = 4;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Context {
|
||||||
|
|
||||||
|
public:
|
||||||
|
turbine::Context &turbineCtx;
|
||||||
|
ox::Array<BgCbbData, 4> cbbData;
|
||||||
|
|
||||||
|
explicit Context(turbine::Context &tctx) noexcept: turbineCtx{tctx} {}
|
||||||
|
Context(Context &other) noexcept = delete;
|
||||||
|
Context(Context const&other) noexcept = delete;
|
||||||
|
Context(Context const&&other) noexcept = delete;
|
||||||
|
virtual ~Context() noexcept = default;
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
ox::MemFS const&rom() const noexcept {
|
||||||
|
return static_cast<ox::MemFS const&>(*turbine::rom(turbineCtx));
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
void safeDelete(Context *ctx) noexcept {
|
||||||
|
delete ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
keel::Context &keelCtx(Context &ctx) noexcept {
|
||||||
|
return turbine::keelCtx(ctx.turbineCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
turbine::Context &turbineCtx(Context &ctx) noexcept {
|
||||||
|
return ctx.turbineCtx;
|
||||||
|
}
|
||||||
|
|
||||||
static constexpr auto SpriteCount = 128;
|
static constexpr auto SpriteCount = 128;
|
||||||
|
|
||||||
ox::Error initGfx(Context&, InitParams const&) noexcept {
|
static ox::Error initGfx() noexcept {
|
||||||
for (auto bgCtl = ®_BG0CTL; bgCtl <= ®_BG3CTL; bgCtl += 2) {
|
for (auto bgCtl = ®_BG0CTL; bgCtl <= ®_BG3CTL; bgCtl += 2) {
|
||||||
teagba::bgSetSbb(*bgCtl, 28);
|
teagba::bgSetSbb(*bgCtl, 28);
|
||||||
}
|
}
|
||||||
@ -34,6 +67,12 @@ ox::Error initGfx(Context&, InitParams const&) noexcept {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ox::Result<ox::UPtr<Context>> init(turbine::Context &tctx, InitParams const&) noexcept {
|
||||||
|
auto ctx = ox::make_unique<Context>(tctx);
|
||||||
|
OX_RETURN_ERROR(initGfx());
|
||||||
|
return ctx;
|
||||||
|
}
|
||||||
|
|
||||||
ox::Error loadBgPalette(
|
ox::Error loadBgPalette(
|
||||||
Context&,
|
Context&,
|
||||||
size_t const palBank,
|
size_t const palBank,
|
||||||
@ -300,4 +339,43 @@ uint_t spriteCount(Context const&) noexcept {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace ox {
|
||||||
|
|
||||||
|
void panic(const char *file, int line, const char *panicMsg, ox::Error const&err) noexcept {
|
||||||
|
using namespace nostalgia::gfx;
|
||||||
|
// reset heap to make sure we have enough memory to allocate context data
|
||||||
|
OX_ALLOW_UNSAFE_BUFFERS_BEGIN
|
||||||
|
const auto heapBegin = reinterpret_cast<char*>(MEM_EWRAM_BEGIN);
|
||||||
|
const auto heapSz = (MEM_EWRAM_END - MEM_EWRAM_BEGIN) / 2;
|
||||||
|
const auto heapEnd = reinterpret_cast<char*>(MEM_EWRAM_BEGIN + heapSz);
|
||||||
|
ox::heapmgr::initHeap(heapBegin, heapEnd);
|
||||||
|
OX_ALLOW_UNSAFE_BUFFERS_END
|
||||||
|
auto tctx = turbine::init(keel::loadRomFs("").unwrap(), "Nostalgia").unwrap();
|
||||||
|
auto ctx = init(*tctx).unwrap();
|
||||||
|
std::ignore = initGfx();
|
||||||
|
std::ignore = initConsole(*ctx);
|
||||||
|
setBgStatus(*ctx, 0, true);
|
||||||
|
clearBg(*ctx, 0);
|
||||||
|
auto const serr = ox::sfmt<ox::IString<23>>("Error code: {}", static_cast<int64_t>(err));
|
||||||
|
consoleWrite(*ctx, 32 + 1, 1, "SADNESS...");
|
||||||
|
consoleWrite(*ctx, 32 + 1, 4, "UNEXPECTED STATE:");
|
||||||
|
consoleWrite(*ctx, 32 + 2, 6, panicMsg);
|
||||||
|
if (err) {
|
||||||
|
consoleWrite(*ctx, 32 + 2, 8, serr);
|
||||||
|
}
|
||||||
|
consoleWrite(*ctx, 32 + 1, 15, "PLEASE RESTART THE SYSTEM");
|
||||||
|
// print to terminal if in mGBA
|
||||||
|
oxErrf("\033[31;1;1mPANIC:\033[0m [{}:{}]: {}\n", file, line, panicMsg);
|
||||||
|
if (err.msg) {
|
||||||
|
oxErrf("\tError Message:\t{}\n", err.msg);
|
||||||
|
}
|
||||||
|
oxErrf("\tError Code:\t{}\n", static_cast<ErrorCode>(err));
|
||||||
|
if (err.src.file_name() != nullptr) {
|
||||||
|
oxErrf("\tError Location:\t{}:{}\n", err.src.file_name(), err.src.line());
|
||||||
|
}
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
OX_ALLOW_UNSAFE_BUFFERS_END
|
OX_ALLOW_UNSAFE_BUFFERS_END
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
#include <ox/std/array.hpp>
|
#include <ox/std/array.hpp>
|
||||||
#include <ox/std/fmt.hpp>
|
#include <ox/std/fmt.hpp>
|
||||||
#include <ox/std/vec.hpp>
|
|
||||||
|
|
||||||
#include <keel/media.hpp>
|
#include <keel/media.hpp>
|
||||||
|
|
||||||
@ -15,22 +14,105 @@
|
|||||||
#include <nostalgia/gfx/palette.hpp>
|
#include <nostalgia/gfx/palette.hpp>
|
||||||
#include <nostalgia/gfx/tilesheet.hpp>
|
#include <nostalgia/gfx/tilesheet.hpp>
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
#include "gfx.hpp"
|
|
||||||
|
|
||||||
namespace nostalgia::gfx {
|
namespace nostalgia::gfx {
|
||||||
|
|
||||||
|
namespace renderer {
|
||||||
|
|
||||||
|
constexpr uint64_t TileRows = 128;
|
||||||
|
constexpr uint64_t TileColumns = 128;
|
||||||
|
constexpr uint64_t TileCount = TileRows * TileColumns;
|
||||||
|
constexpr uint64_t BgVertexVboRows = 4;
|
||||||
|
constexpr uint64_t BgVertexVboRowLength = 7;
|
||||||
|
constexpr uint64_t BgVertexVboLength = BgVertexVboRows * BgVertexVboRowLength;
|
||||||
|
constexpr uint64_t BgVertexEboLength = 6;
|
||||||
|
constexpr uint64_t SpriteVertexVboRows = 4;
|
||||||
|
constexpr uint64_t SpriteVertexVboRowLength = 6;
|
||||||
|
constexpr uint64_t SpriteVertexVboLength = SpriteVertexVboRows * SpriteVertexVboRowLength;
|
||||||
|
constexpr uint64_t SpriteVertexEboLength = 6;
|
||||||
|
|
||||||
|
struct CBB: glutils::BufferSet {
|
||||||
|
bool updated = false;
|
||||||
|
ox::Array<uint32_t, 32768> pixels;
|
||||||
|
constexpr CBB() noexcept {
|
||||||
|
vertices.resize(TileCount * BgVertexVboLength);
|
||||||
|
elements.resize(TileCount * BgVertexEboLength);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SpriteBlockset: glutils::BufferSet {
|
||||||
|
bool updated = false;
|
||||||
|
constexpr SpriteBlockset(uint64_t spriteCount, uint64_t blocksPerSprite) noexcept {
|
||||||
|
vertices.resize(spriteCount * SpriteVertexVboLength * blocksPerSprite);
|
||||||
|
elements.resize(spriteCount * SpriteVertexEboLength * blocksPerSprite);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Background {
|
||||||
|
float priority = 0;
|
||||||
|
bool enabled = false;
|
||||||
|
unsigned cbbIdx = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Context {
|
||||||
|
public:
|
||||||
|
class Drawer final: public turbine::gl::Drawer {
|
||||||
|
private:
|
||||||
|
Context &m_ctx;
|
||||||
|
public:
|
||||||
|
explicit Drawer(Context &ctx) noexcept: m_ctx{ctx} {}
|
||||||
|
void draw(turbine::Context &tctx) noexcept override {
|
||||||
|
gl::draw(m_ctx, turbine::getScreenSize(tctx));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
turbine::Context &turbineCtx;
|
||||||
|
glutils::GLProgram bgShader;
|
||||||
|
glutils::GLProgram spriteShader;
|
||||||
|
ox::Array<renderer::CBB, 4> cbbs;
|
||||||
|
renderer::SpriteBlockset spriteBlocks;
|
||||||
|
ox::Array<Sprite, 128> spriteStates;
|
||||||
|
ox::Array<GLfloat, 1024> bgPalette;
|
||||||
|
ox::Array<renderer::Background, 4> backgrounds;
|
||||||
|
Drawer drawer;
|
||||||
|
uint_t spriteCount = 0;
|
||||||
|
uint_t blocksPerSprite = 0;
|
||||||
|
|
||||||
|
explicit Context(turbine::Context &tctx, InitParams const ¶ms) noexcept:
|
||||||
|
turbineCtx{tctx},
|
||||||
|
spriteBlocks{params.glSpriteCount, params.glBlocksPerSprite},
|
||||||
|
drawer{*this},
|
||||||
|
spriteCount{params.glSpriteCount},
|
||||||
|
blocksPerSprite{params.glBlocksPerSprite} {
|
||||||
|
}
|
||||||
|
Context(Context const&) = delete;
|
||||||
|
Context(Context&&) = delete;
|
||||||
|
Context &operator=(Context const&) = delete;
|
||||||
|
Context &operator=(Context&&) = delete;
|
||||||
|
~Context() noexcept {
|
||||||
|
turbine::gl::removeDrawer(turbineCtx, &drawer);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void safeDelete(Context *ctx) noexcept {
|
||||||
|
delete ctx;
|
||||||
|
}
|
||||||
|
|
||||||
|
keel::Context &keelCtx(Context &ctx) noexcept {
|
||||||
|
return turbine::keelCtx(ctx.turbineCtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
turbine::Context &turbineCtx(Context &ctx) noexcept {
|
||||||
|
return ctx.turbineCtx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
namespace renderer {
|
namespace renderer {
|
||||||
|
|
||||||
static constexpr auto Scale = 1;
|
static constexpr auto Scale = 1;
|
||||||
static constexpr auto PriorityScale = 0.01f;
|
static constexpr auto PriorityScale = 0.01f;
|
||||||
|
|
||||||
Drawer::Drawer(Context &ctx) noexcept: m_ctx(ctx) {}
|
|
||||||
|
|
||||||
void Drawer::draw(turbine::Context &tctx) noexcept {
|
|
||||||
gl::draw(m_ctx, turbine::getScreenSize(tctx));
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr ox::CStringView bgvshadTmpl = R"glsl(
|
static constexpr ox::CStringView bgvshadTmpl = R"glsl(
|
||||||
{}
|
{}
|
||||||
in vec2 vTexCoord;
|
in vec2 vTexCoord;
|
||||||
@ -241,7 +323,13 @@ static void initSpritesBufferset(Context &ctx) noexcept {
|
|||||||
// in float vEnabled;
|
// in float vEnabled;
|
||||||
auto const enabledAttr = static_cast<GLuint>(glGetAttribLocation(shader, "vEnabled"));
|
auto const enabledAttr = static_cast<GLuint>(glGetAttribLocation(shader, "vEnabled"));
|
||||||
glEnableVertexAttribArray(enabledAttr);
|
glEnableVertexAttribArray(enabledAttr);
|
||||||
glVertexAttribPointer(enabledAttr, 1, GL_FLOAT, GL_FALSE, SpriteVertexVboRowLength * sizeof(float), nullptr);
|
glVertexAttribPointer(
|
||||||
|
enabledAttr,
|
||||||
|
1,
|
||||||
|
GL_FLOAT,
|
||||||
|
GL_FALSE,
|
||||||
|
SpriteVertexVboRowLength * sizeof(float),
|
||||||
|
nullptr);
|
||||||
// in vec3 vPosition;
|
// in vec3 vPosition;
|
||||||
auto const posAttr = static_cast<GLuint>(glGetAttribLocation(shader, "vPosition"));
|
auto const posAttr = static_cast<GLuint>(glGetAttribLocation(shader, "vPosition"));
|
||||||
glEnableVertexAttribArray(posAttr);
|
glEnableVertexAttribArray(posAttr);
|
||||||
@ -250,8 +338,9 @@ static void initSpritesBufferset(Context &ctx) noexcept {
|
|||||||
// in vec2 vTexCoord;
|
// in vec2 vTexCoord;
|
||||||
auto const texCoordAttr = static_cast<GLuint>(glGetAttribLocation(shader, "vTexCoord"));
|
auto const texCoordAttr = static_cast<GLuint>(glGetAttribLocation(shader, "vTexCoord"));
|
||||||
glEnableVertexAttribArray(texCoordAttr);
|
glEnableVertexAttribArray(texCoordAttr);
|
||||||
glVertexAttribPointer(texCoordAttr, 2, GL_FLOAT, GL_FALSE, SpriteVertexVboRowLength * sizeof(float),
|
glVertexAttribPointer(
|
||||||
std::bit_cast<void*>(uintptr_t{4 * sizeof(float)}));
|
texCoordAttr, 2, GL_FLOAT, GL_FALSE, SpriteVertexVboRowLength * sizeof(float),
|
||||||
|
std::bit_cast<void*>(uintptr_t{4 * sizeof(float)}));
|
||||||
glBindVertexArray(0);
|
glBindVertexArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,7 +359,13 @@ static void initBackgroundBufferset(
|
|||||||
// vbo layout
|
// vbo layout
|
||||||
auto const posAttr = static_cast<GLuint>(glGetAttribLocation(shader, "vPosition"));
|
auto const posAttr = static_cast<GLuint>(glGetAttribLocation(shader, "vPosition"));
|
||||||
glEnableVertexAttribArray(posAttr);
|
glEnableVertexAttribArray(posAttr);
|
||||||
glVertexAttribPointer(posAttr, 3, GL_FLOAT, GL_FALSE, BgVertexVboRowLength * sizeof(float), nullptr);
|
glVertexAttribPointer(
|
||||||
|
posAttr,
|
||||||
|
3,
|
||||||
|
GL_FLOAT,
|
||||||
|
GL_FALSE,
|
||||||
|
BgVertexVboRowLength * sizeof(float),
|
||||||
|
nullptr);
|
||||||
auto const texCoordAttr = static_cast<GLuint>(glGetAttribLocation(shader, "vTexCoord"));
|
auto const texCoordAttr = static_cast<GLuint>(glGetAttribLocation(shader, "vTexCoord"));
|
||||||
glEnableVertexAttribArray(texCoordAttr);
|
glEnableVertexAttribArray(texCoordAttr);
|
||||||
glVertexAttribPointer(
|
glVertexAttribPointer(
|
||||||
@ -300,7 +395,16 @@ static glutils::GLTexture createTexture(
|
|||||||
tex.height = h;
|
tex.height = h;
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, tex.id);
|
glBindTexture(GL_TEXTURE_2D, tex.id);
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, tex.width, tex.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
glTexImage2D(
|
||||||
|
GL_TEXTURE_2D,
|
||||||
|
0,
|
||||||
|
GL_RGBA,
|
||||||
|
tex.width,
|
||||||
|
tex.height,
|
||||||
|
0,
|
||||||
|
GL_RGBA,
|
||||||
|
GL_UNSIGNED_BYTE,
|
||||||
|
pixels);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
@ -470,28 +574,23 @@ static void setSprite(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ox::Error initGfx(
|
ox::Result<ox::UPtr<Context>> init(turbine::Context &tctx, InitParams const¶ms) noexcept {
|
||||||
Context &ctx,
|
auto ctx = ox::make_unique<Context>(tctx, params);
|
||||||
InitParams const&initParams) noexcept {
|
|
||||||
const auto bgVshad = ox::sfmt(renderer::bgvshadTmpl, gl::GlslVersion);
|
const auto bgVshad = ox::sfmt(renderer::bgvshadTmpl, gl::GlslVersion);
|
||||||
const auto bgFshad = ox::sfmt(renderer::bgfshadTmpl, gl::GlslVersion);
|
const auto bgFshad = ox::sfmt(renderer::bgfshadTmpl, gl::GlslVersion);
|
||||||
const auto spriteVshad = ox::sfmt(renderer::spritevshadTmpl, gl::GlslVersion);
|
const auto spriteVshad = ox::sfmt(renderer::spritevshadTmpl, gl::GlslVersion);
|
||||||
const auto spriteFshad = ox::sfmt(renderer::spritefshadTmpl, gl::GlslVersion);
|
const auto spriteFshad = ox::sfmt(renderer::spritefshadTmpl, gl::GlslVersion);
|
||||||
OX_RETURN_ERROR(glutils::buildShaderProgram(bgVshad, bgFshad).moveTo(ctx.bgShader));
|
OX_RETURN_ERROR(glutils::buildShaderProgram(bgVshad, bgFshad).moveTo(ctx->bgShader));
|
||||||
OX_RETURN_ERROR(
|
OX_RETURN_ERROR(
|
||||||
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);
|
initBackgroundBufferset(ctx->bgShader, cbb);
|
||||||
}
|
}
|
||||||
renderer::initSpritesBufferset(ctx);
|
renderer::initSpritesBufferset(*ctx);
|
||||||
if (initParams.glInstallDrawer) {
|
if (params.glInstallDrawer) {
|
||||||
turbine::gl::addDrawer(ctx.turbineCtx, &ctx.drawer);
|
turbine::gl::addDrawer(ctx->turbineCtx, &ctx->drawer);
|
||||||
}
|
}
|
||||||
return {};
|
return ctx;
|
||||||
}
|
|
||||||
|
|
||||||
void shutdownGfx(Context &ctx) noexcept {
|
|
||||||
turbine::gl::removeDrawer(ctx.turbineCtx, &ctx.drawer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TileSheetData {
|
struct TileSheetData {
|
@ -1,9 +0,0 @@
|
|||||||
target_sources(
|
|
||||||
NostalgiaGfx PRIVATE
|
|
||||||
context.cpp
|
|
||||||
gfx.cpp
|
|
||||||
)
|
|
||||||
target_link_libraries(
|
|
||||||
NostalgiaGfx PUBLIC
|
|
||||||
GlUtils
|
|
||||||
)
|
|
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "context.hpp"
|
|
||||||
#include "gfx.hpp"
|
|
||||||
|
|
||||||
namespace nostalgia::gfx {
|
|
||||||
|
|
||||||
void safeDelete(Context *ctx) noexcept {
|
|
||||||
delete ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
Context::Context(turbine::Context &tctx, InitParams const¶ms) noexcept:
|
|
||||||
turbineCtx(tctx),
|
|
||||||
spriteBlocks(params.glSpriteCount, params.glBlocksPerSprite),
|
|
||||||
drawer(*this),
|
|
||||||
spriteCount(params.glSpriteCount),
|
|
||||||
blocksPerSprite(params.glBlocksPerSprite) {
|
|
||||||
}
|
|
||||||
|
|
||||||
Context::~Context() noexcept {
|
|
||||||
shutdownGfx(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
ox::Result<ox::UPtr<Context>> init(turbine::Context &tctx, InitParams const¶ms) noexcept {
|
|
||||||
auto ctx = ox::make_unique<Context>(tctx, params);
|
|
||||||
OX_RETURN_ERROR(initGfx(*ctx, params));
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
keel::Context &keelCtx(Context &ctx) noexcept {
|
|
||||||
return turbine::keelCtx(ctx.turbineCtx);
|
|
||||||
}
|
|
||||||
|
|
||||||
turbine::Context &turbineCtx(Context &ctx) noexcept {
|
|
||||||
return ctx.turbineCtx;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <ox/std/types.hpp>
|
|
||||||
|
|
||||||
#include <glutils/glutils.hpp>
|
|
||||||
|
|
||||||
#include <nostalgia/gfx/gfx.hpp>
|
|
||||||
#include <nostalgia/gfx/context.hpp>
|
|
||||||
|
|
||||||
#include "gfx.hpp"
|
|
||||||
|
|
||||||
namespace nostalgia::gfx {
|
|
||||||
|
|
||||||
class Context {
|
|
||||||
|
|
||||||
public:
|
|
||||||
turbine::Context &turbineCtx;
|
|
||||||
glutils::GLProgram bgShader;
|
|
||||||
glutils::GLProgram spriteShader;
|
|
||||||
ox::Array<renderer::CBB, 4> cbbs;
|
|
||||||
renderer::SpriteBlockset spriteBlocks;
|
|
||||||
ox::Array<Sprite, 128> spriteStates;
|
|
||||||
ox::Array<GLfloat, 1024> bgPalette;
|
|
||||||
ox::Array<renderer::Background, 4> backgrounds;
|
|
||||||
renderer::Drawer drawer;
|
|
||||||
uint_t spriteCount = 0;
|
|
||||||
uint_t blocksPerSprite = 0;
|
|
||||||
explicit Context(turbine::Context &tctx, InitParams const¶ms) noexcept;
|
|
||||||
Context(Context const&) = delete;
|
|
||||||
Context(Context&&) = delete;
|
|
||||||
Context &operator=(Context const&) = delete;
|
|
||||||
Context &operator=(Context&&) = delete;
|
|
||||||
~Context() noexcept;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
@ -1,65 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2016 - 2025 Gary Talent (gary@drinkingtea.net). All rights reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <ox/std/types.hpp>
|
|
||||||
|
|
||||||
#include <turbine/gfx.hpp>
|
|
||||||
|
|
||||||
#include <glutils/glutils.hpp>
|
|
||||||
|
|
||||||
#include <nostalgia/gfx/context.hpp>
|
|
||||||
|
|
||||||
namespace nostalgia::gfx::renderer {
|
|
||||||
|
|
||||||
constexpr uint64_t TileRows = 128;
|
|
||||||
constexpr uint64_t TileColumns = 128;
|
|
||||||
constexpr uint64_t TileCount = TileRows * TileColumns;
|
|
||||||
constexpr uint64_t BgVertexVboRows = 4;
|
|
||||||
constexpr uint64_t BgVertexVboRowLength = 7;
|
|
||||||
constexpr uint64_t BgVertexVboLength = BgVertexVboRows * BgVertexVboRowLength;
|
|
||||||
constexpr uint64_t BgVertexEboLength = 6;
|
|
||||||
constexpr uint64_t SpriteVertexVboRows = 4;
|
|
||||||
constexpr uint64_t SpriteVertexVboRowLength = 6;
|
|
||||||
constexpr uint64_t SpriteVertexVboLength = SpriteVertexVboRows * SpriteVertexVboRowLength;
|
|
||||||
constexpr uint64_t SpriteVertexEboLength = 6;
|
|
||||||
|
|
||||||
struct CBB: public glutils::BufferSet {
|
|
||||||
bool updated = false;
|
|
||||||
ox::Array<uint32_t, 32768> pixels;
|
|
||||||
constexpr CBB() noexcept {
|
|
||||||
vertices.resize(TileCount * BgVertexVboLength);
|
|
||||||
elements.resize(TileCount * BgVertexEboLength);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SpriteBlockset: public glutils::BufferSet {
|
|
||||||
bool updated = false;
|
|
||||||
constexpr SpriteBlockset(uint64_t spriteCount, uint64_t blocksPerSprite) noexcept {
|
|
||||||
vertices.resize(spriteCount * SpriteVertexVboLength * blocksPerSprite);
|
|
||||||
elements.resize(spriteCount * SpriteVertexEboLength * blocksPerSprite);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Background {
|
|
||||||
float priority = 0;
|
|
||||||
bool enabled = false;
|
|
||||||
unsigned cbbIdx = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Drawer: public turbine::gl::Drawer {
|
|
||||||
private:
|
|
||||||
Context &m_ctx;
|
|
||||||
public:
|
|
||||||
explicit Drawer(Context &ctx) noexcept;
|
|
||||||
void draw(turbine::Context&) noexcept final;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace nostalgia::gfx {
|
|
||||||
ox::Error initGfx(Context &ctx, InitParams const&) noexcept;
|
|
||||||
void shutdownGfx(Context &ctx) noexcept;
|
|
||||||
}
|
|
Loading…
x
Reference in New Issue
Block a user