LegacyGlDevice class
Pipeline-state and draw-call facade of the legacy-OpenGL backend (aliased as RHI::Device).
The fixed-function GL twin of the console devices: each draw decodes the bound program's instance block(s) exactly like SwDevice::Dispatch, CPU-transforms the four sprite corners to raster pixels and submits them as triangles through glDrawArrays, under an ortho projection over the target in pixels - so nothing is ever transformed by GL and a vertex means what it says. Texture coordinates are emitted in TEXELS, like the console backends do, and a texture matrix set once per binding scales them into GL's normalized range.
Vertices come out of a per-frame arena and consecutive primitives that share their whole state are accumulated into one glDrawArrays, so a tile layer or a text run costs one draw call.
What this backend is for is the machines whose only OpenGL is a fixed-function one: MorphOS, whose TinyGL carries the texture combiners and framebuffer objects, AmigaOS 4, whose MiniGL over Warp3D has the combiners but no framebuffer objects at all, and by extension any other legacy GL. There are no shaders, so effects come from the same transpiled fixed_function tables the consoles consume (Shaders/Generated/LegacyGlGeneratedEffects.h), with the presets mapped onto GL_COMBINE programs; indexed textures have no hardware palette here, so they are baked to RGBA by LegacyGlTexture exactly as the RG8 content is on the consoles.
Because there are no shaders, the game runs the direct tier (see RhiFwd.h): the scene is rendered straight to the display at the logical resolution and the CPU lightmap is handed to the device through SetPendingSoftwareLighting() instead of a compositing shader pass.
Public types
- struct ScissorState
- struct BlendingState
- struct DepthTestState
- struct CullFaceState
Public static variables
-
static std::
int32_t MaxTextureDimension constexpr - Ceiling on the texture dimension this backend will report, whatever the driver says.
Public static functions
-
static auto GetSceneCounter() -> std::
uint32_t - Monotonic count of finished frames, used to detect "still referenced by the current frame" resources.
- static auto FindGeneratedEffect(const char* program, const char* variant) -> const FixedFunctionGeneratedEffect*
- Returns the generated fixed-function effect of a (program, variant) key, or
nullptr. - static void SetBlendingEnabled(bool enabled)
-
static void SetBlendingFactors(nCine::
BlendingFactor srcRgb, nCine:: BlendingFactor dstRgb, nCine:: BlendingFactor srcAlpha, nCine:: BlendingFactor dstAlpha) - static auto GetBlendingState() -> BlendingState
- static void SetBlendingState(const BlendingState& state)
- static void SetDepthTestEnabled(bool enabled)
- static void SetDepthMaskEnabled(bool enabled)
- static auto GetDepthTestState() -> DepthTestState
- static void SetDepthTestState(const DepthTestState& state)
- static void SetCullFaceEnabled(bool enabled)
- static auto GetCullFaceState() -> CullFaceState
- static void SetCullFaceState(const CullFaceState& state)
- static auto GetScissorState() -> ScissorState
- static void SetScissorState(const ScissorState& state)
- static void SetScissor(const Recti& rect)
- static void SetScissorTestEnabled(bool enabled)
- static auto GetViewport() -> Recti
- static void SetViewport(const Recti& rect)
-
static void InitViewport(std::
int32_t x, std:: int32_t y, std:: int32_t width, std:: int32_t height) - static auto GetClearColor() -> Colorf
- static void SetClearColor(const Colorf& color)
- static void Clear(ClearFlags flags)
-
static void DrawArrays(PrimitiveType primitive,
std::
int32_t firstVertex, std:: int32_t numVertices) -
static void DrawArraysInstanced(PrimitiveType primitive,
std::
int32_t firstVertex, std:: int32_t numVertices, std:: int32_t numInstances) -
static void DrawElements(PrimitiveType primitive,
std::
uint32_t numIndices, IndexFormat indexFormat, std:: uintptr_t indexOffset, std:: int32_t baseVertex) -
static void DrawElements(PrimitiveType primitive,
std::
uint32_t numIndices, std:: uintptr_t indexOffset, std:: int32_t baseVertex) -
static void DrawElementsInstanced(PrimitiveType primitive,
std::
uint32_t numIndices, IndexFormat indexFormat, std:: uintptr_t indexOffset, std:: int32_t numInstances, std:: int32_t baseVertex) -
static void DrawElementsInstanced(PrimitiveType primitive,
std::
uint32_t numIndices, std:: uintptr_t indexOffset, std:: int32_t numInstances, std:: int32_t baseVertex) - static auto InsertFence() -> FenceHandle
- static void DeleteFence(FenceHandle& fence)
-
static auto ClientWaitFence(FenceHandle fence,
std::
uint64_t timeoutNs) -> bool - static void SetupInitialState()
-
static auto CreateSwapchain(void* windowHandle,
std::
int32_t width, std:: int32_t height, bool vsync) -> bool - No-op (the window backend owns the presentation path).
- static void DestroySwapchain()
- No-op.
-
static void ResizeSwapchain(std::
int32_t width, std:: int32_t height) - Records the raster size of the drawable, which the screen pass renders into.
- static void PresentFrame()
- Flushes what the frame batched; the window backend swaps the buffers itself.
- static void BeginGpuTiming()
- No-op (fixed-function OpenGL has no timer queries).
- static void EndGpuTiming()
- No-op.
-
static auto GetMaxTextureDimension() -> std::
int32_t - Returns the maximum supported texture dimension (drives the tileset chunking).
- static auto SupportsNonPowerOfTwo() -> bool
- Returns
truewhen the GL samples non-power-of-two textures. -
static void ResizeScreenFramebuffer(std::
int32_t width, std:: int32_t height) - Sets the logical resolution the scene is rendered at (scaled to the drawable at submit).
- static void InitializeGl()
- Programs the once-per-context pipeline state this backend relies on.
- static void ShutdownGl()
- Flushes anything outstanding, so the exit path leaves the context idle.
- static void BindProgram(LegacyGlShaderProgram* program)
- Records the currently bound shader program.
- static auto CurrentProgram() -> LegacyGlShaderProgram*
- Returns the currently bound shader program.
-
static void BindTexture(std::
uint32_t unit, const LegacyGlTexture* texture) - Records the texture bound to a texture unit.
- static void UnbindTexture(const LegacyGlTexture* texture)
- Clears a texture from every unit it is bound to (called from ~LegacyGlTexture).
-
static auto GetBoundTexture(std::
uint32_t unit) -> const LegacyGlTexture* - Returns the texture bound to a texture unit.
-
static void BindUniformRange(std::
uint32_t index, const std:: uint8_t* data, std:: uint32_t size) - Records the host data range bound to a uniform binding point.
- static void SetRenderTarget(LegacyGlRenderTarget* renderTarget)
- Records the current draw render target (draws are redirected into it).
- static void UnbindRenderTarget(const LegacyGlRenderTarget* renderTarget)
- Clears a render target from the device if it is the current one (called from ~LegacyGlRenderTarget).
-
static void DescribeContext(std::
int32_t& majorVersion, std:: int32_t& minorVersion, const char*& vendor, const char*& renderer, const char*& apiVersion) - Reports what the GL context calls itself.
- static void InvalidateStateCache()
- Forgets the GL state the device caches, after something outside it changed a binding.
- static auto SupportsFramebufferObjects() -> bool
- Returns
truewhen framebuffer objects were found to work (probed by InitializeGl()). -
static void ClampToDrawable(std::
int32_t& width, std:: int32_t& height) - Shrinks a size to what the drawable can hold, which is what a copy-back target is limited to.
- static void RegisterPaletteTexture(LegacyGlTexture* texture)
- Registers the intercepted shared palette texture (its rows are what indexed content is baked through).
-
static void NotifyPaletteTextureChanged(LegacyGlTexture* texture,
std::
int32_t firstRow, std:: int32_t rowCount) - Invalidates the bakes built from the given palette rows after an upload.
-
static void SetPendingSoftwareLighting(const float* lightmap,
std::
int32_t lmW, std:: int32_t lmH, std:: int32_t scale, std:: int32_t vpX, std:: int32_t vpY, std:: int32_t vpW, std:: int32_t vpH, float ambR, float ambG, float ambB, bool waterActive = false, float waterLevelPx = 0.0f, float waterTime = 0.0f, float waterCamY = 0.0f) - Queues the CPU lightmap combine for the next
Combinedraw (the direct-tier lighting contract). - static void EndFrame()
- Drops any lighting entries not consumed this frame (called by the window backend at present).
Constructors, destructors, conversion operators
- LegacyGlDevice() deleted
- ~LegacyGlDevice() deleted
Function documentation
static const FixedFunctionGeneratedEffect* nCine:: RHI:: LegacyGL:: LegacyGlDevice:: FindGeneratedEffect(const char* program,
const char* variant)
Returns the generated fixed-function effect of a (program, variant) key, or nullptr.
Called once per program load from LegacyGlShaderProgram::fixed_function block in its .shader file (Lighting, Blur, the Resize* family, ...) and its draws are skipped with a one-time warning, exactly as on the other fixed-function backends.
static std:: int32_t nCine:: RHI:: LegacyGL:: LegacyGlDevice:: GetMaxTextureDimension()
Returns the maximum supported texture dimension (drives the tileset chunking).
GL_MAX_TEXTURE_SIZE as the driver reports it, capped at MaxTextureDimension. It is what ContentResolver cuts tileset atlases into chunks to fit, and it is also the size one texture page is built at, so content sized against this number is never paged.
Prebaked content that is larger anyway (Devan's fire-breathing animation is 119x1004) is NOT rejected - LegacyGlTexture splits such an image into pages internally and the draw path picks the page a primitive samples - so Texture::Initialize() only warns about it on this backend instead of asserting.
static bool nCine:: RHI:: LegacyGL:: LegacyGlDevice:: SupportsNonPowerOfTwo()
Returns true when the GL samples non-power-of-two textures.
Legacy GL is not required to: it is a GL 2.0 feature (GL_ARB_texture_non_power_of_two before that), so where it is missing every page is stored padded up to powers of two and the draw path scales texel coordinates by the padded size. Probed by InitializeGl().
static void nCine:: RHI:: LegacyGL:: LegacyGlDevice:: DescribeContext(std:: int32_t& majorVersion,
std:: int32_t& minorVersion,
const char*& vendor,
const char*& renderer,
const char*& apiVersion)
Reports what the GL context calls itself.
The three strings are the driver's own (they live as long as the context does, which outlives anything that reads them here) and the version is parsed out of GL_VERSION. Zeros and null strings are answered before the context exists.
static void nCine:: RHI:: LegacyGL:: LegacyGlDevice:: SetPendingSoftwareLighting(const float* lightmap,
std:: int32_t lmW,
std:: int32_t lmH,
std:: int32_t scale,
std:: int32_t vpX,
std:: int32_t vpY,
std:: int32_t vpW,
std:: int32_t vpH,
float ambR,
float ambG,
float ambB,
bool waterActive = false,
float waterLevelPx = 0.0f,
float waterTime = 0.0f,
float waterCamY = 0.0f)
Queues the CPU lightmap combine for the next Combine draw (the direct-tier lighting contract).
The water half of the compositor is NOT queued here: it is a fixed_function block of the CombineWithWater programs (see CombineWithWater.shader), so the water* parameters of the shared signature are ignored by this backend - only the software one still reads them.
Variable documentation
static std:: int32_t nCine:: RHI:: LegacyGL:: LegacyGlDevice:: MaxTextureDimension constexpr
Ceiling on the texture dimension this backend will report, whatever the driver says.
Not a hardware limit - it is what keeps ONE image's worth of memory bounded on the machines this backend exists for. A desktop GL answers GL_MAX_TEXTURE_SIZE with 16384, and a tileset atlas cut to fit that is a single allocation of tens of megabytes; a Radeon-era MorphOS box has no business making one. Anything larger is split into pages by LegacyGlTexture.