Moved a bunch of code around
This commit is contained in:
@@ -8,12 +8,12 @@ add_subdirectory(dusk)
|
||||
if(DUSK_TARGET_SYSTEM STREQUAL "linux")
|
||||
add_subdirectory(dusklinux)
|
||||
add_subdirectory(dusksdl2)
|
||||
add_subdirectory(duskopengl)
|
||||
add_subdirectory(duskgl)
|
||||
|
||||
elseif(DUSK_TARGET_SYSTEM STREQUAL "psp")
|
||||
add_subdirectory(duskpsp)
|
||||
add_subdirectory(dusksdl2)
|
||||
add_subdirectory(duskopengl)
|
||||
add_subdirectory(duskgl)
|
||||
|
||||
elseif(DUSK_TARGET_SYSTEM STREQUAL "gamecube" OR DUSK_TARGET_SYSTEM STREQUAL "wii")
|
||||
add_subdirectory(duskdolphin)
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||
PUBLIC
|
||||
display.c
|
||||
framebuffer.c
|
||||
screen.c
|
||||
spritebatch.c
|
||||
text.c
|
||||
)
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
#include "camera.h"
|
||||
#include "display/display.h"
|
||||
#include "assert/assert.h"
|
||||
#include "display/framebuffer.h"
|
||||
#include "display/screen.h"
|
||||
#include "display/framebuffer/framebuffer.h"
|
||||
#include "display/screen/screen.h"
|
||||
|
||||
void cameraInit(camera_t *camera) {
|
||||
cameraInitPerspective(camera);
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
|
||||
#include "display/display.h"
|
||||
#include "engine/engine.h"
|
||||
#include "display/framebuffer.h"
|
||||
#include "display/framebuffer/framebuffer.h"
|
||||
#include "scene/scene.h"
|
||||
#include "display/spritebatch.h"
|
||||
#include "display/spritebatch/spritebatch.h"
|
||||
#include "display/mesh/quad.h"
|
||||
#include "display/screen.h"
|
||||
#include "display/screen/screen.h"
|
||||
#include "ui/ui.h"
|
||||
#include "debug/debug.h"
|
||||
#include "display/text.h"
|
||||
@@ -25,10 +25,8 @@ display_t DISPLAY = { 0 };
|
||||
errorret_t displayInit(void) {
|
||||
memoryZero(&DISPLAY, sizeof(DISPLAY));
|
||||
|
||||
#if DISPLAY_SDL2
|
||||
displaySDL2Init();
|
||||
#elif DOLPHIN
|
||||
displayDolphinInit();
|
||||
#ifdef displayPlatformInit
|
||||
errorChain(displayPlatformInit());
|
||||
#endif
|
||||
|
||||
quadInit();
|
||||
@@ -42,8 +40,8 @@ errorret_t displayInit(void) {
|
||||
}
|
||||
|
||||
errorret_t displayUpdate(void) {
|
||||
#if DISPLAY_SDL2
|
||||
displaySDL2Update();
|
||||
#ifdef displayPlatformUpdate
|
||||
errorChain(displayPlatformUpdate());
|
||||
#endif
|
||||
|
||||
// Reset state
|
||||
@@ -60,19 +58,16 @@ errorret_t displayUpdate(void) {
|
||||
errorChain(sceneRender());
|
||||
|
||||
// Render UI
|
||||
// uiRender();
|
||||
uiRender();
|
||||
|
||||
// Finish up
|
||||
screenUnbind();
|
||||
screenRender();
|
||||
|
||||
#if DISPLAY_SDL2
|
||||
displaySDL2Swap();
|
||||
#elif DOLPHIN
|
||||
displayDolphinSwap();
|
||||
// Swap and return.
|
||||
#ifdef displayPlatformSwap
|
||||
errorChain(displayPlatformSwap());
|
||||
#endif
|
||||
|
||||
// For now, we just return an OK error.
|
||||
errorOk();
|
||||
}
|
||||
|
||||
@@ -80,9 +75,9 @@ errorret_t displayDispose(void) {
|
||||
spriteBatchDispose();
|
||||
screenDispose();
|
||||
textDispose();
|
||||
|
||||
#if DISPLAY_SDL2
|
||||
displaySDL2Dispose();
|
||||
|
||||
#ifdef displayPlatformDispose
|
||||
displayPlatformDispose();
|
||||
#endif
|
||||
|
||||
// For now, we just return an OK error.
|
||||
|
||||
@@ -6,12 +6,35 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "displaydefs.h"
|
||||
#include "error/error.h"
|
||||
#include "display/camera/camera.h"
|
||||
#include "display/framebuffer.h"
|
||||
#include "display/displayplatform.h"
|
||||
#include "display/camera/camera.h"
|
||||
|
||||
// Expecting some definitions to be provided
|
||||
#ifndef DUSK_DISPLAY_SIZE_DYNAMIC
|
||||
#ifndef DUSK_DISPLAY_WIDTH
|
||||
#error "DUSK_DISPLAY_WIDTH must be defined."
|
||||
#endif
|
||||
#ifndef DUSK_DISPLAY_HEIGHT
|
||||
#error "DUSK_DISPLAY_HEIGHT must be defined"
|
||||
#endif
|
||||
#define DISPLAY_WINDOW_WIDTH_DEFAULT DUSK_DISPLAY_WIDTH
|
||||
#define DISPLAY_WINDOW_HEIGHT_DEFAULT DUSK_DISPLAY_HEIGHT
|
||||
#else
|
||||
#ifndef DUSK_DISPLAY_WIDTH_DEFAULT
|
||||
#error "DUSK_DISPLAY_WIDTH_DEFAULT must be defined."
|
||||
#endif
|
||||
#ifndef DUSK_DISPLAY_HEIGHT_DEFAULT
|
||||
#error "DUSK_DISPLAY_HEIGHT_DEFAULT must be defined."
|
||||
#endif
|
||||
#ifdef DUSK_DISPLAY_WIDTH
|
||||
#error "DUSK_DISPLAY_WIDTH should not be defined."
|
||||
#endif
|
||||
#ifdef DUSK_DISPLAY_HEIGHT
|
||||
#error "DUSK_DISPLAY_HEIGHT should not be defined."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Main Display Struct, platform-speicifc
|
||||
typedef displayplatform_t display_t;
|
||||
|
||||
extern display_t DISPLAY;
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "dusk.h"
|
||||
|
||||
#if DISPLAY_SDL2
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
|
||||
#ifndef DISPLAY_SIZE_DYNAMIC
|
||||
#define DISPLAY_SIZE_DYNAMIC 1
|
||||
#endif
|
||||
#elif DOLPHIN
|
||||
// Dolphin.
|
||||
#define DISPLAY_FIFO_SIZE (256*1024)
|
||||
#else
|
||||
#error "Need to specify display backend."
|
||||
#endif
|
||||
|
||||
#if DISPLAY_SIZE_DYNAMIC == 0
|
||||
#ifndef DISPLAY_WIDTH
|
||||
#error "DISPLAY_WIDTH must be defined when DISPLAY_SIZE_DYNAMIC is 0."
|
||||
#endif
|
||||
#ifndef DISPLAY_HEIGHT
|
||||
#error "DISPLAY_HEIGHT must be defined when DISPLAY_SIZE_DYNAMIC is 0."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef DISPLAY_WINDOW_WIDTH_DEFAULT
|
||||
#error "DISPLAY_WINDOW_WIDTH_DEFAULT must be defined."
|
||||
#endif
|
||||
#ifndef DISPLAY_WINDOW_HEIGHT_DEFAULT
|
||||
#define DISPLAY_WINDOW_HEIGHT_DEFAULT DISPLAY_HEIGHT
|
||||
#endif
|
||||
@@ -1,192 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "framebuffer.h"
|
||||
#include "display/display.h"
|
||||
#include "assert/assert.h"
|
||||
#include "util/memory.h"
|
||||
|
||||
framebuffer_t FRAMEBUFFER_BACKBUFFER = {0};
|
||||
const framebuffer_t *FRAMEBUFFER_BOUND = &FRAMEBUFFER_BACKBUFFER;
|
||||
|
||||
void frameBufferInitBackbuffer() {
|
||||
memoryZero(&FRAMEBUFFER_BACKBUFFER, sizeof(framebuffer_t));
|
||||
|
||||
FRAMEBUFFER_BACKBUFFER.id = -1;
|
||||
FRAMEBUFFER_BOUND = &FRAMEBUFFER_BACKBUFFER;
|
||||
}
|
||||
|
||||
#if DISPLAY_SIZE_DYNAMIC == 1
|
||||
void frameBufferInit(
|
||||
framebuffer_t *framebuffer,
|
||||
const uint32_t width,
|
||||
const uint32_t height
|
||||
) {
|
||||
#if DISPLAY_SDL2 == 1
|
||||
assertNotNull(framebuffer, "Framebuffer cannot be NULL");
|
||||
assertTrue(width > 0 && height > 0, "W/H must be greater than 0");
|
||||
|
||||
memoryZero(framebuffer, sizeof(framebuffer_t));
|
||||
textureInit(&framebuffer->texture, width, height, TEXTURE_FORMAT_RGBA,(texturedata_t){
|
||||
.rgbaColors = NULL
|
||||
});
|
||||
|
||||
glGenFramebuffersEXT(1, &framebuffer->id);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer->id);
|
||||
|
||||
glFramebufferTexture2DEXT(
|
||||
GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
|
||||
GL_TEXTURE_2D, framebuffer->texture.id, 0
|
||||
);
|
||||
|
||||
if(
|
||||
glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) !=
|
||||
GL_FRAMEBUFFER_COMPLETE_EXT
|
||||
) {
|
||||
assertUnreachable("Framebuffer is not complete");
|
||||
}
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t frameBufferGetWidth(const framebuffer_t *framebuffer) {
|
||||
#if DISPLAY_SDL2
|
||||
if(framebuffer == &FRAMEBUFFER_BACKBUFFER) {
|
||||
#if DISPLAY_SIZE_DYNAMIC == 0
|
||||
return DISPLAY_WIDTH;
|
||||
#else
|
||||
int32_t windowWidth, windowHeight;
|
||||
SDL_GetWindowSize(DISPLAY.window, &windowWidth, &windowHeight);
|
||||
return windowWidth;
|
||||
#endif
|
||||
}
|
||||
|
||||
return framebuffer->texture.width;
|
||||
|
||||
#elif DOLPHIN
|
||||
return DISPLAY.screenMode->fbWidth;
|
||||
|
||||
#else
|
||||
#error "Unsupported DISPLAY_TYPE."
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t frameBufferGetHeight(const framebuffer_t *framebuffer) {
|
||||
#if DISPLAY_SDL2
|
||||
if(framebuffer == &FRAMEBUFFER_BACKBUFFER) {
|
||||
#if DISPLAY_SIZE_DYNAMIC == 0
|
||||
return DISPLAY_HEIGHT;
|
||||
#else
|
||||
int32_t windowWidth, windowHeight;
|
||||
SDL_GetWindowSize(DISPLAY.window, &windowWidth, &windowHeight);
|
||||
return windowHeight;
|
||||
#endif
|
||||
}
|
||||
|
||||
return framebuffer->texture.height;
|
||||
|
||||
#elif DOLPHIN
|
||||
return DISPLAY.screenMode->efbHeight;
|
||||
|
||||
#else
|
||||
#error "Unsupported DISPLAY_TYPE."
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void frameBufferBind(const framebuffer_t *framebuffer) {
|
||||
if(framebuffer == NULL) {
|
||||
frameBufferBind(&FRAMEBUFFER_BACKBUFFER);
|
||||
FRAMEBUFFER_BOUND = &FRAMEBUFFER_BACKBUFFER;
|
||||
return;
|
||||
}
|
||||
|
||||
// Bind the framebuffer for rendering
|
||||
#if DISPLAY_SDL2
|
||||
if(framebuffer == &FRAMEBUFFER_BACKBUFFER) {
|
||||
#if PSP
|
||||
|
||||
#else
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
#endif
|
||||
} else {
|
||||
#if PSP
|
||||
assertUnreachable("Framebuffers not supported on PSP");
|
||||
#else
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer->id);
|
||||
#endif
|
||||
}
|
||||
|
||||
glViewport(
|
||||
0, 0,
|
||||
frameBufferGetWidth(framebuffer), frameBufferGetHeight(framebuffer)
|
||||
);
|
||||
|
||||
#elif DOLPHIN
|
||||
GX_InvVtxCache();
|
||||
GX_InvalidateTexAll();
|
||||
GX_SetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE);
|
||||
|
||||
GX_SetViewport(
|
||||
0, 0,
|
||||
frameBufferGetWidth(framebuffer),
|
||||
frameBufferGetHeight(framebuffer),
|
||||
0, 1
|
||||
);
|
||||
|
||||
#endif
|
||||
|
||||
FRAMEBUFFER_BOUND = framebuffer;
|
||||
}
|
||||
|
||||
void frameBufferClear(uint8_t flags, color_t color) {
|
||||
#if DISPLAY_SDL2
|
||||
GLbitfield glFlags = 0;
|
||||
|
||||
if(flags & FRAMEBUFFER_CLEAR_COLOR) {
|
||||
glFlags |= GL_COLOR_BUFFER_BIT;
|
||||
glClearColor(
|
||||
color.r / 255.0f,
|
||||
color.g / 255.0f,
|
||||
color.b / 255.0f,
|
||||
color.a / 255.0f
|
||||
);
|
||||
}
|
||||
|
||||
if(flags & FRAMEBUFFER_CLEAR_DEPTH) {
|
||||
glFlags |= GL_DEPTH_BUFFER_BIT;
|
||||
}
|
||||
|
||||
glClear(glFlags);
|
||||
#elif DOLPHIN
|
||||
GX_SetCopyClear(
|
||||
(GXColor){ color.r, color.g, color.b, color.a },
|
||||
GX_MAX_Z24
|
||||
);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void frameBufferDispose(framebuffer_t *framebuffer) {
|
||||
assertNotNull(framebuffer, "Framebuffer cannot be NULL");
|
||||
|
||||
#if DISPLAY_SDL2
|
||||
if(framebuffer == &FRAMEBUFFER_BACKBUFFER) {
|
||||
assertUnreachable("Cannot dispose of backbuffer");
|
||||
}
|
||||
|
||||
#if DISPLAY_SIZE_DYNAMIC == 0
|
||||
assertUnreachable("Dynamic size framebuffers not supported");
|
||||
#else
|
||||
textureDispose(&framebuffer->texture);
|
||||
glDeleteFramebuffersEXT(1, &framebuffer->id);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
64
src/dusk/display/framebuffer/framebuffer.c
Normal file
64
src/dusk/display/framebuffer/framebuffer.c
Normal file
@@ -0,0 +1,64 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "framebuffer.h"
|
||||
#include "display/display.h"
|
||||
#include "assert/assert.h"
|
||||
#include "util/memory.h"
|
||||
|
||||
framebuffer_t FRAMEBUFFER_BACKBUFFER = {0};
|
||||
const framebuffer_t *FRAMEBUFFER_BOUND = &FRAMEBUFFER_BACKBUFFER;
|
||||
|
||||
errorret_t frameBufferInitBackbuffer() {
|
||||
memoryZero(&FRAMEBUFFER_BACKBUFFER, sizeof(framebuffer_t));
|
||||
errorChain(frameBufferPlatformInitBackbuffer());
|
||||
FRAMEBUFFER_BOUND = &FRAMEBUFFER_BACKBUFFER;
|
||||
}
|
||||
|
||||
void frameBufferBind(framebuffer_t *framebuffer) {
|
||||
if(framebuffer == NULL) {
|
||||
frameBufferBind(&FRAMEBUFFER_BACKBUFFER);
|
||||
FRAMEBUFFER_BOUND = &FRAMEBUFFER_BACKBUFFER;
|
||||
return;
|
||||
}
|
||||
|
||||
errorChain(frameBufferPlatformBind(framebuffer));
|
||||
FRAMEBUFFER_BOUND = framebuffer;
|
||||
errorOk();
|
||||
}
|
||||
|
||||
void frameBufferDispose(framebuffer_t *framebuffer) {
|
||||
assertNotNull(framebuffer, "Framebuffer cannot be NULL");
|
||||
|
||||
#if DISPLAY_SDL2
|
||||
if(framebuffer == &FRAMEBUFFER_BACKBUFFER) {
|
||||
assertUnreachable("Cannot dispose of backbuffer");
|
||||
}
|
||||
|
||||
#if DISPLAY_SIZE_DYNAMIC == 0
|
||||
assertUnreachable("Dynamic size framebuffers not supported");
|
||||
#else
|
||||
textureDispose(&framebuffer->texture);
|
||||
glDeleteFramebuffersEXT(1, &framebuffer->id);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DUSK_DISPLAY_SIZE_DYNAMIC
|
||||
errorret_t frameBufferInit(
|
||||
framebuffer_t *fb,
|
||||
const uint32_t width,
|
||||
const uint32_t height
|
||||
) {
|
||||
assertNotNull(fb, "Framebuffer cannot be NULL");
|
||||
assertTrue(width > 0 && height > 0, "W/H must be greater than 0");
|
||||
|
||||
memoryZero(fb, sizeof(framebuffer_t));
|
||||
errorChain(frameBufferPlatformInit(fb, width, height));
|
||||
errorOk();
|
||||
}
|
||||
#endif
|
||||
@@ -6,46 +6,32 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "error/error.h"
|
||||
#include "display/framebuffer/framebufferplatform.h"
|
||||
#include "display/texture/texture.h"
|
||||
|
||||
// Expected defs.
|
||||
#ifndef frameBufferPlatformInitBackBuffer
|
||||
#error "frameBufferPlatformInitBackBuffer not defined for this platform"
|
||||
#endif
|
||||
#ifndef frameBufferPlatformBind
|
||||
#error "frameBufferPlatformBind not defined for this platform"
|
||||
#endif
|
||||
|
||||
#define FRAMEBUFFER_CLEAR_COLOR (1 << 0)
|
||||
#define FRAMEBUFFER_CLEAR_DEPTH (1 << 1)
|
||||
|
||||
typedef struct {
|
||||
#if DISPLAY_SDL2 == 1
|
||||
// OpenGL Framebuffer Object ID
|
||||
GLuint id;
|
||||
texture_t texture;
|
||||
#elif DOLPHIN
|
||||
// --- IGNORE ---
|
||||
uint8_t id;
|
||||
#else
|
||||
#error "Framebuffers not implemented on this platform."
|
||||
#endif
|
||||
} framebuffer_t;
|
||||
typedef framebufferplatform_t framebuffer_t;
|
||||
|
||||
extern framebuffer_t FRAMEBUFFER_BACKBUFFER;
|
||||
extern const framebuffer_t *FRAMEBUFFER_BOUND;
|
||||
|
||||
/**
|
||||
* Initializes the backbuffer framebuffer.
|
||||
*/
|
||||
void frameBufferInitBackbuffer(void);
|
||||
|
||||
/**
|
||||
* Initializes a framebuffer.
|
||||
*
|
||||
* @param framebuffer The framebuffer to initialize.
|
||||
* @param width The width of the framebuffer.
|
||||
* @param height The height of the framebuffer.
|
||||
* @return Error for initialization of the backbuffer.
|
||||
*/
|
||||
#if DISPLAY_SIZE_DYNAMIC == 1
|
||||
void frameBufferInit(
|
||||
framebuffer_t *framebuffer,
|
||||
const uint32_t width,
|
||||
const uint32_t height
|
||||
);
|
||||
#endif
|
||||
errorret_t frameBufferInitBackBuffer(void);
|
||||
|
||||
/**
|
||||
* Gets the width of the framebuffer.
|
||||
@@ -53,7 +39,7 @@ void frameBufferInitBackbuffer(void);
|
||||
* @param framebuffer The framebuffer to get the width of.
|
||||
* @return The width of the framebuffer, or 0 if the framebuffer is NULL.
|
||||
*/
|
||||
int32_t frameBufferGetWidth(const framebuffer_t *framebuffer);
|
||||
uint32_t frameBufferGetWidth(const framebuffer_t *framebuffer);
|
||||
|
||||
/**
|
||||
* Gets the height of the framebuffer.
|
||||
@@ -61,7 +47,7 @@ int32_t frameBufferGetWidth(const framebuffer_t *framebuffer);
|
||||
* @param framebuffer The framebuffer to get the height of.
|
||||
* @return The height of the framebuffer, or 0 if the framebuffer is NULL.
|
||||
*/
|
||||
int32_t frameBufferGetHeight(const framebuffer_t *framebuffer);
|
||||
uint32_t frameBufferGetHeight(const framebuffer_t *framebuffer);
|
||||
|
||||
/**
|
||||
* Binds the framebuffer for rendering, or the backbuffer if the framebuffer
|
||||
@@ -80,30 +66,29 @@ void frameBufferBind(const framebuffer_t *framebuffer);
|
||||
void frameBufferClear(uint8_t flags, color_t color);
|
||||
|
||||
/**
|
||||
* Disposes of the framebuffer using EXT methods.
|
||||
* Disposes of the framebuffer. Will also be used for request disposing of the
|
||||
* backbuffer.
|
||||
*
|
||||
* @param framebuffer The framebuffer to dispose of.
|
||||
*/
|
||||
void frameBufferDispose(framebuffer_t *framebuffer);
|
||||
|
||||
// #if RENDER_USE_FRAMEBUFFER
|
||||
// typedef struct {
|
||||
// GLuint id;
|
||||
// texture_t texture;
|
||||
// } framebuffer_t;
|
||||
#ifdef DUSK_DISPLAY_SIZE_DYNAMIC
|
||||
#ifndef frameBufferPlatformInit
|
||||
#error "frameBufferPlatformInit not defined for this platform"
|
||||
#endif
|
||||
|
||||
// /**
|
||||
// * Initializes a framebuffer using EXT methods.
|
||||
// *
|
||||
// * @param framebuffer The framebuffer to initialize.
|
||||
// * @param width The width of the framebuffer.
|
||||
// * @param height The height of the framebuffer.
|
||||
// * @return An error code indicating success or failure.
|
||||
// */
|
||||
// void frameBufferInit(
|
||||
// framebuffer_t *framebuffer,
|
||||
// const uint32_t width,
|
||||
// const uint32_t height
|
||||
// );
|
||||
|
||||
// #endif
|
||||
/**
|
||||
* Initializes a framebuffer.
|
||||
*
|
||||
* @param framebuffer The framebuffer to initialize.
|
||||
* @param width The width of the framebuffer.
|
||||
* @param height The height of the framebuffer.
|
||||
* @return Error for initialization of the framebuffer.
|
||||
*/
|
||||
errorret_t frameBufferInit(
|
||||
framebuffer_t *framebuffer,
|
||||
const uint32_t width,
|
||||
const uint32_t height
|
||||
);
|
||||
#endif
|
||||
@@ -11,9 +11,9 @@
|
||||
#include "util/math.h"
|
||||
#include "display/display.h"
|
||||
|
||||
const texture_t *TEXTURE_BOUND = NULL;
|
||||
texture_t *TEXTURE_BOUND = NULL;
|
||||
|
||||
void textureInit(
|
||||
errorret_t textureInit(
|
||||
texture_t *texture,
|
||||
const int32_t width,
|
||||
const int32_t height,
|
||||
@@ -22,401 +22,29 @@ void textureInit(
|
||||
) {
|
||||
assertNotNull(texture, "Texture cannot be NULL");
|
||||
assertTrue(width > 0 && height > 0, "width/height must be greater than 0");
|
||||
|
||||
memoryZero(texture, sizeof(texture_t));
|
||||
texture->width = width;
|
||||
texture->height = height;
|
||||
texture->format = format;
|
||||
|
||||
assertTrue(width == mathNextPowTwo(width), "Width must be a power of 2.");
|
||||
assertTrue(height == mathNextPowTwo(height), "Height must be a power of 2.");
|
||||
|
||||
#if DISPLAY_SDL2
|
||||
glGenTextures(1, &texture->id);
|
||||
glBindTexture(GL_TEXTURE_2D, texture->id);
|
||||
|
||||
switch(format) {
|
||||
case TEXTURE_FORMAT_RGBA:
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D, 0, format, width, height, 0,
|
||||
format, GL_UNSIGNED_BYTE, (void*)data.rgbaColors
|
||||
);
|
||||
break;
|
||||
|
||||
case TEXTURE_FORMAT_PALETTE:
|
||||
assertNotNull(data.paletteData, "Palette texture data cannot be NULL");
|
||||
|
||||
if(DISPLAY.usingShaderedPalettes) {
|
||||
// Palette textures not supported, convert to GL_RED style texture
|
||||
// so shader can perform the lookup.
|
||||
uint8_t formatted[width * height];
|
||||
for(int32_t i = 0; i < width * height; i++) {
|
||||
uint8_t index = data.paletteData[i];
|
||||
formatted[i] = index * 128;
|
||||
}
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D, 0, GL_R8, width, height, 0,
|
||||
GL_RED, GL_UNSIGNED_BYTE, (void*)formatted
|
||||
);
|
||||
|
||||
} else {
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0, GL_COLOR_INDEX8_EXT,
|
||||
width, height,
|
||||
0, GL_COLOR_INDEX8_EXT,
|
||||
GL_UNSIGNED_BYTE, (void*)data.paletteData
|
||||
);
|
||||
// glColorTableEXT(
|
||||
// GL_TEXTURE_2D, GL_RGBA, data.palette.palette->colorCount, GL_RGBA,
|
||||
// GL_UNSIGNED_BYTE, (const void*)data.palette.palette->colors
|
||||
// );
|
||||
}
|
||||
|
||||
GLenum err = glGetError();
|
||||
if(err != GL_NO_ERROR) {
|
||||
printf("GL Error uploading palette texture: %d\n", err);
|
||||
assertUnreachable("GL error uploading palette texture");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unknown texture format");
|
||||
break;
|
||||
}
|
||||
|
||||
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_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
texture->ready = true;
|
||||
|
||||
#elif DOLPHIN
|
||||
|
||||
switch(format) {
|
||||
case TEXTURE_FORMAT_RGBA:
|
||||
assertTrue(
|
||||
(width % 4) == 0 && (height % 4) == 0,
|
||||
"RGB5A3 requires w/h multiple of 4 (or pad)"
|
||||
);
|
||||
|
||||
// Convert to RGB5A3 format
|
||||
size_t rgbaSize = width * height * sizeof(u16);
|
||||
texture->rgba = (u16*)memalign(32, rgbaSize);
|
||||
assertNotNull(texture->rgba, "Failed to allocate texture RGBA data");
|
||||
|
||||
for(uint32_t y = 0; y < height; ++y) {
|
||||
for(uint32_t x = 0; x < width; ++x) {
|
||||
const int src = y * width + x;
|
||||
|
||||
const int tileX = x >> 2;
|
||||
const int tileY = y >> 2;
|
||||
const int tilesPerRow = width >> 2;
|
||||
const int tileIndex = tileY * tilesPerRow + tileX;
|
||||
const int tileBaseWords = tileIndex * 16;
|
||||
const int inTile = ((y & 3) << 2) + (x & 3);
|
||||
const int dest = tileBaseWords + inTile;
|
||||
|
||||
color4b_t col = data.rgba.colors[src];
|
||||
|
||||
u16 outCol;
|
||||
if(col.a < 255) {
|
||||
// 0AAA RRRR GGGG BBBB
|
||||
outCol = (
|
||||
(0u << 15) |
|
||||
((u16)(col.a >> 5) << 12) |
|
||||
((u16)(col.r >> 4) << 8) |
|
||||
((u16)(col.g >> 4) << 4) |
|
||||
((u16)(col.b >> 4) << 0)
|
||||
);
|
||||
} else {
|
||||
// 1RRRR RRGG GGGB BBBB
|
||||
outCol = (
|
||||
(1u << 15) |
|
||||
((u16)(col.r >> 3) << 10) |
|
||||
((u16)(col.g >> 3) << 5) |
|
||||
((u16)(col.b >> 3) << 0)
|
||||
);
|
||||
}
|
||||
texture->rgba[dest] = outCol;
|
||||
}
|
||||
}
|
||||
|
||||
DCFlushRange(texture->rgba, rgbaSize);
|
||||
GX_InitTexObj(
|
||||
&texture->texObj,
|
||||
texture->rgba,
|
||||
width, height,
|
||||
GX_TF_RGB5A3,
|
||||
GX_REPEAT, GX_REPEAT,
|
||||
GX_FALSE
|
||||
);
|
||||
|
||||
DCFlushRange(texture->rgba, rgbaSize);
|
||||
GX_InvalidateTexAll();
|
||||
|
||||
GX_InitTexObjLOD(
|
||||
&texture->texObj,
|
||||
GX_NEAR, GX_NEAR,
|
||||
0.0f, 0.0f, 0.0f,
|
||||
GX_FALSE,
|
||||
GX_FALSE,
|
||||
GX_ANISO_1
|
||||
);
|
||||
break;
|
||||
|
||||
case TEXTURE_FORMAT_ALPHA: {
|
||||
assertTrue(
|
||||
(width % 4) == 0 && (height % 4) == 0,
|
||||
"GX_TF_I8 requires w/h multiple of 4 (or pad)"
|
||||
);
|
||||
|
||||
// 1 byte per pixel (I8), GX expects 4x4 tiled layout
|
||||
const size_t alphaSize = (size_t)width * (size_t)height;
|
||||
|
||||
texture->alpha = (u8*)memalign(32, alphaSize);
|
||||
assertNotNull(texture->alpha, "Failed to allocate alpha texture data");
|
||||
|
||||
const u32 tilesPerRow = ((u32)width) >> 3; // /8
|
||||
|
||||
for (u32 y = 0; y < (u32)height; ++y) {
|
||||
const u32 tileY = y >> 2; // /4
|
||||
const u32 inTileY = (y & 3) << 3; // (y%4)*8
|
||||
|
||||
for (u32 x = 0; x < (u32)width; ++x) {
|
||||
const u32 srcI = y * (u32)width + x;
|
||||
const u8 srcA = data.alpha.data[srcI]; // linear input
|
||||
|
||||
const u32 tileX = x >> 3; // /8
|
||||
const u32 tileIndex = tileY * tilesPerRow + tileX;
|
||||
|
||||
const u32 tileBase = tileIndex * 32; // 8*4*1 = 32 bytes per tile
|
||||
const u32 inTile = inTileY + (x & 7); // (y%4)*8 + (x%8)
|
||||
|
||||
texture->alpha[tileBase + inTile] = 0xFF - srcA;// Fixes inverted alpha.
|
||||
}
|
||||
}
|
||||
|
||||
// Flush CPU cache so GX sees the swizzled I8 texture data
|
||||
DCFlushRange(texture->alpha, alphaSize);
|
||||
|
||||
// Initialize GX texture object with swizzled data
|
||||
GX_InitTexObj(
|
||||
&texture->texObj,
|
||||
texture->alpha,
|
||||
width, height,
|
||||
GX_TF_I8,
|
||||
GX_REPEAT, GX_REPEAT,
|
||||
GX_FALSE
|
||||
);
|
||||
|
||||
GX_InitTexObjLOD(
|
||||
&texture->texObj,
|
||||
GX_NEAR, GX_NEAR,
|
||||
0.0f, 0.0f, 0.0f,
|
||||
GX_FALSE,
|
||||
GX_FALSE,
|
||||
GX_ANISO_1
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
||||
case TEXTURE_FORMAT_PALETTE: {
|
||||
// Not supported, convert to RGBA using lookup
|
||||
color_t* formatted = memoryAllocate(width * height * sizeof(color_t));
|
||||
for(int32_t i = 0; i < width * height; i++) {
|
||||
uint8_t index = data.palette.data[i];
|
||||
assertTrue(
|
||||
index < data.palette.palette->colorCount,
|
||||
"Palette index out of range"
|
||||
);
|
||||
formatted[i] = data.palette.palette->colors[index];
|
||||
}
|
||||
|
||||
textureInit(
|
||||
texture, width, height, TEXTURE_FORMAT_RGBA,
|
||||
(texturedata_t){
|
||||
.rgba = { .colors = formatted }
|
||||
}
|
||||
);
|
||||
memoryFree(formatted);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
assertUnreachable("Unsupported texture format for Dolphin");
|
||||
break;
|
||||
}
|
||||
|
||||
texture->ready = true;
|
||||
#endif
|
||||
errorChain(textureInitPlatform(texture, width, height, format, data));
|
||||
errorOk();
|
||||
}
|
||||
|
||||
void textureBind(texture_t *texture) {
|
||||
if(TEXTURE_BOUND == texture) return;
|
||||
|
||||
if(texture == NULL) {
|
||||
#if DISPLAY_SDL2
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
#elif DOLPHIN
|
||||
GX_SetNumChans(0);
|
||||
#endif
|
||||
TEXTURE_BOUND = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
assertTrue(texture->ready, "Texture ID must be ready");
|
||||
assertTrue(
|
||||
texture->width > 0 && texture->height > 0,
|
||||
"Texture width and height must be greater than 0"
|
||||
);
|
||||
|
||||
#if DISPLAY_SDL2
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, texture->id);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
#elif DOLPHIN
|
||||
GX_SetNumChans(1);
|
||||
GX_LoadTexObj(&texture->texObj, GX_TEXMAP0);
|
||||
#endif
|
||||
TEXTURE_BOUND = texture;
|
||||
errorret_t textureBind(texture_t *texture) {
|
||||
errorChain(textureBindPlatform(texture));
|
||||
errorOk();
|
||||
}
|
||||
|
||||
void textureDispose(texture_t *texture) {
|
||||
errorret_t textureDispose(texture_t *texture) {
|
||||
assertNotNull(texture, "Texture cannot be NULL");
|
||||
assertTrue(texture->ready, "Texture ID must be ready");
|
||||
|
||||
if(TEXTURE_BOUND == texture) {
|
||||
textureBind(NULL);
|
||||
}
|
||||
|
||||
#if DISPLAY_SDL2
|
||||
glDeleteTextures(1, &texture->id);
|
||||
#elif DOLPHIN
|
||||
switch(texture->format) {
|
||||
case TEXTURE_FORMAT_RGBA:
|
||||
free(texture->rgba);
|
||||
break;
|
||||
|
||||
case TEXTURE_FORMAT_ALPHA:
|
||||
free(texture->alpha);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
memoryZero(texture, sizeof(texture_t));
|
||||
#endif
|
||||
}
|
||||
|
||||
#if DOLPHIN
|
||||
void textureDolphinUploadTEV() {
|
||||
if(TEXTURE_BOUND == NULL) {
|
||||
GX_SetNumTexGens(0);
|
||||
GX_SetNumTevStages(1);
|
||||
GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
|
||||
return;
|
||||
}
|
||||
|
||||
// Add channel for vertex color
|
||||
GX_SetNumChans(1);
|
||||
GX_SetChanCtrl(
|
||||
GX_COLOR0A0,// Store in color channel 0
|
||||
GX_DISABLE,// Lighting disabled
|
||||
GX_SRC_REG,// Ambient color?
|
||||
GX_SRC_VTX,// Material color?
|
||||
GX_LIGHTNULL,// Light Mask
|
||||
GX_DF_NONE,// Diffuse function
|
||||
GX_AF_NONE// Attenuation function
|
||||
);
|
||||
|
||||
// One set of UVs
|
||||
GX_SetNumTexGens(1);
|
||||
GX_SetTexCoordGen(
|
||||
GX_TEXCOORD0,
|
||||
GX_TG_MTX2x4,
|
||||
GX_TG_TEX0,
|
||||
GX_IDENTITY
|
||||
);
|
||||
|
||||
// Basically the shader setup
|
||||
switch(TEXTURE_BOUND->format) {
|
||||
case TEXTURE_FORMAT_RGBA:
|
||||
// One TEV stage: vertex color * texture color
|
||||
GX_SetNumTevStages(1);
|
||||
GX_SetTevOp(GX_TEVSTAGE0, GX_MODULATE);
|
||||
GX_SetTevOrder(
|
||||
GX_TEVSTAGE0,
|
||||
GX_TEXCOORD0,
|
||||
GX_TEXMAP0,
|
||||
GX_COLOR0A0
|
||||
);
|
||||
GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR);
|
||||
GX_SetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0);
|
||||
break;
|
||||
|
||||
case TEXTURE_FORMAT_ALPHA:
|
||||
// One TEV stage: vertex color * texture color
|
||||
GX_SetNumTevStages(1);
|
||||
GX_SetTevOrder(
|
||||
GX_TEVSTAGE0,
|
||||
GX_TEXCOORD0,
|
||||
GX_TEXMAP0,
|
||||
GX_COLOR0A0
|
||||
);
|
||||
|
||||
// Color = vertex color
|
||||
GX_SetTevColorIn(
|
||||
GX_TEVSTAGE0,
|
||||
GX_CC_RASC,
|
||||
GX_CC_ZERO,
|
||||
GX_CC_ZERO,
|
||||
GX_CC_ZERO
|
||||
);
|
||||
GX_SetTevColorOp(
|
||||
GX_TEVSTAGE0,
|
||||
GX_TEV_ADD,
|
||||
GX_TB_ZERO,
|
||||
GX_CS_SCALE_1,
|
||||
GX_TRUE,
|
||||
GX_TEVPREV
|
||||
);
|
||||
|
||||
// Alpha = vertex alpha * I8 intensity
|
||||
GX_SetTevAlphaIn(
|
||||
GX_TEVSTAGE0,
|
||||
GX_CA_RASA,
|
||||
GX_CA_ZERO,
|
||||
GX_CA_TEXA,
|
||||
GX_CA_ZERO
|
||||
);
|
||||
GX_SetTevAlphaOp(
|
||||
GX_TEVSTAGE0,
|
||||
GX_TEV_ADD,
|
||||
GX_TB_ZERO,
|
||||
GX_CS_SCALE_1,
|
||||
GX_TRUE,
|
||||
GX_TEVPREV
|
||||
);
|
||||
|
||||
GX_SetBlendMode(
|
||||
GX_BM_BLEND,
|
||||
GX_BL_SRCALPHA,
|
||||
GX_BL_INVSRCALPHA,
|
||||
GX_LO_CLEAR
|
||||
);
|
||||
|
||||
GX_SetColorUpdate(GX_TRUE);
|
||||
GX_SetAlphaUpdate(GX_TRUE);
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unknown texture format in meshDraw");
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
errorChain(textureDisposePlatform(texture));
|
||||
errorOk();
|
||||
}
|
||||
@@ -6,44 +6,30 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "error/error.h"
|
||||
#include "display/color.h"
|
||||
#include "display/displaydefs.h"
|
||||
#include "display/texture/palette.h"
|
||||
#include "display/texture/textureplatform.h"
|
||||
|
||||
typedef enum {
|
||||
#if DISPLAY_SDL2
|
||||
TEXTURE_FORMAT_RGBA = GL_RGBA,
|
||||
TEXTURE_FORMAT_PALETTE = GL_COLOR_INDEX8_EXT,
|
||||
#elif DOLPHIN
|
||||
// TEXTURE_FORMAT_RGBA = GX_TF_RGBA8,
|
||||
// TEXTURE_FORMAT_ALPHA = GX_TF_A8,
|
||||
TEXTURE_FORMAT_PALETTE = GX_TF_CI8,
|
||||
#endif
|
||||
} textureformat_t;
|
||||
#ifndef textureInitPlatform
|
||||
#error "textureInitPlatform should not be defined."
|
||||
#endif
|
||||
#ifndef textureBindPlatform
|
||||
#error "textureBindPlatform should not be defined."
|
||||
#endif
|
||||
#ifndef textureDisposePlatform
|
||||
#error "textureDisposePlatform should not be defined."
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
#if DISPLAY_SDL2
|
||||
GLuint id;
|
||||
#elif DOLPHIN
|
||||
GXTexObj texObj;
|
||||
union {
|
||||
u16 *rgba;
|
||||
u8 *alpha;
|
||||
};
|
||||
#endif
|
||||
|
||||
textureformat_t format;
|
||||
bool_t ready;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
} texture_t;
|
||||
typedef textureformatplatform_t textureformat_t;
|
||||
typedef textureplatform_t texture_t;
|
||||
|
||||
typedef union {
|
||||
typedef union texturedata_u {
|
||||
uint8_t *paletteData;
|
||||
color_t *rgbaColors;
|
||||
} texturedata_t;
|
||||
|
||||
extern const texture_t *TEXTURE_BOUND;
|
||||
extern texture_t *TEXTURE_BOUND;
|
||||
|
||||
/**
|
||||
* Initializes a texture.
|
||||
@@ -54,7 +40,7 @@ extern const texture_t *TEXTURE_BOUND;
|
||||
* @param format The format of the texture (e.g., GL_RGBA, GL_ALPHA).
|
||||
* @param data The data for the texture, the format changes per format.
|
||||
*/
|
||||
void textureInit(
|
||||
errorret_t textureInit(
|
||||
texture_t *texture,
|
||||
const int32_t width,
|
||||
const int32_t height,
|
||||
@@ -67,18 +53,11 @@ void textureInit(
|
||||
*
|
||||
* @param texture The texture to bind.
|
||||
*/
|
||||
void textureBind(texture_t *texture);
|
||||
errorret_t textureBind(texture_t *texture);
|
||||
|
||||
/**
|
||||
* Disposes a texture.
|
||||
*
|
||||
* @param texture The texture to dispose.
|
||||
*/
|
||||
void textureDispose(texture_t *texture);
|
||||
|
||||
#if DOLPHIN
|
||||
/**
|
||||
* Uploads the TEV settings for the currently bound texture.
|
||||
*/
|
||||
void textureDolphinUploadTEV();
|
||||
#endif
|
||||
errorret_t textureDispose(texture_t *texture);
|
||||
@@ -9,4 +9,6 @@ target_include_directories(${DUSK_LIBRARY_TARGET_NAME}
|
||||
${CMAKE_CURRENT_LIST_DIR}
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
# Subdirs
|
||||
add_subdirectory(display)
|
||||
add_subdirectory(error)
|
||||
14
src/duskgl/display/CMakeLists.txt
Normal file
14
src/duskgl/display/CMakeLists.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
# Copyright (c) 2026 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||
PUBLIC
|
||||
displaygl.c
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(framebuffer)
|
||||
add_subdirectory(texture)
|
||||
31
src/duskgl/display/displaygl.c
Normal file
31
src/duskgl/display/displaygl.c
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "displaygl.h"
|
||||
|
||||
errorret_t displayOpenGLInit(void) {
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_LIGHTING);// PSP defaults this on?
|
||||
glShadeModel(GL_SMOOTH); // Fixes color on PSP?
|
||||
errorChain(errorGLCheck());
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDepthFunc(GL_LEQUAL);
|
||||
glClearDepth(1.0f);
|
||||
errorChain(errorGLCheck());
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
|
||||
errorChain(errorGLCheck());
|
||||
|
||||
glEnableClientState(GL_COLOR_ARRAY);// To confirm: every frame on PSP?
|
||||
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
glEnableClientState(GL_VERTEX_ARRAY);
|
||||
errorChain(errorGLCheck());
|
||||
}
|
||||
14
src/duskgl/display/displaygl.h
Normal file
14
src/duskgl/display/displaygl.h
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "error/errorgl.h"
|
||||
|
||||
/**
|
||||
* Initializes the OpenGL specific contexts for rendering.
|
||||
*/
|
||||
errorret_t displayOpenGLInit(void);
|
||||
9
src/duskgl/display/framebuffer/CMakeLists.txt
Normal file
9
src/duskgl/display/framebuffer/CMakeLists.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
# Copyright (c) 2026 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||
PUBLIC
|
||||
)
|
||||
133
src/duskgl/display/framebuffer/framebuffergl.c
Normal file
133
src/duskgl/display/framebuffer/framebuffergl.c
Normal file
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "display/display.h"
|
||||
#include "display/framebuffer/framebuffer.h"
|
||||
#include "assert/assert.h"
|
||||
|
||||
errorret_t frameBufferGLInitBackBuffer(void) {
|
||||
errorOk();
|
||||
}
|
||||
|
||||
uint32_t frameBufferGetWidth(const framebuffer_t *framebuffer) {
|
||||
if(framebuffer == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(framebuffer == &FRAMEBUFFER_BACKBUFFER) {
|
||||
#ifdef DUSK_DISPLAY_SIZE_DYNAMIC
|
||||
int32_t windowWidth, windowHeight;
|
||||
SDL_GetWindowSize(DISPLAY.window, &windowWidth, &windowHeight);
|
||||
return windowWidth;
|
||||
#else
|
||||
return DUSK_DISPLAY_WIDTH;
|
||||
#endif
|
||||
}
|
||||
|
||||
return framebuffer->texture.width;
|
||||
}
|
||||
|
||||
uint32_t frameBufferGLGetHeight(const framebuffer_t *framebuffer) {
|
||||
if(framebuffer == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(framebuffer == &FRAMEBUFFER_BACKBUFFER) {
|
||||
#ifdef DUSK_DISPLAY_SIZE_DYNAMIC
|
||||
int32_t windowWidth, windowHeight;
|
||||
SDL_GetWindowSize(DISPLAY.window, &windowWidth, &windowHeight);
|
||||
return windowHeight;
|
||||
#else
|
||||
return DUSK_DISPLAY_HEIGHT;
|
||||
#endif
|
||||
}
|
||||
|
||||
return framebuffer->texture.height;
|
||||
}
|
||||
|
||||
errorret_t frameBufferGLBind(framebuffer_t *framebuffer) {
|
||||
assertNotNull(framebuffer, "Framebuffer cannot be NULL");
|
||||
|
||||
#ifdef DUSK_DISPLAY_SIZE_DYNAMIC
|
||||
if(framebuffer == &FRAMEBUFFER_BACKBUFFER) {
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
} else {
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, framebuffer->id);
|
||||
}
|
||||
|
||||
glViewport(
|
||||
0, 0,
|
||||
frameBufferGetWidth(framebuffer), frameBufferGetHeight(framebuffer)
|
||||
);
|
||||
#else
|
||||
glViewport(
|
||||
0, 0,
|
||||
DUSK_DISPLAY_WIDTH, DUSK_DISPLAY_HEIGHT
|
||||
);
|
||||
#endif
|
||||
|
||||
errorChain(errorGLCheck());
|
||||
errorOk();
|
||||
}
|
||||
|
||||
void frameBufferClear(const uint8_t flags, const color_t color) {
|
||||
GLbitfield glFlags = 0;
|
||||
|
||||
if(flags & FRAMEBUFFER_CLEAR_COLOR) {
|
||||
glFlags |= GL_COLOR_BUFFER_BIT;
|
||||
glClearColor(
|
||||
color.r / 255.0f,
|
||||
color.g / 255.0f,
|
||||
color.b / 255.0f,
|
||||
color.a / 255.0f
|
||||
);
|
||||
}
|
||||
|
||||
if(flags & FRAMEBUFFER_CLEAR_DEPTH) {
|
||||
glFlags |= GL_DEPTH_BUFFER_BIT;
|
||||
}
|
||||
|
||||
glClear(glFlags);
|
||||
}
|
||||
|
||||
#ifdef DUSK_DISPLAY_SIZE_DYNAMIC
|
||||
errorret_t frameBufferGLInit(
|
||||
framebuffer_t *fb,
|
||||
const uint32_t width,
|
||||
const uint32_t height
|
||||
) {
|
||||
assertNotNull(fb, "Framebuffer cannot be NULL");
|
||||
assertTrue(width > 0 && height > 0, "W/H must be greater than 0");
|
||||
|
||||
memoryZero(fb, sizeof(framebuffer_t));
|
||||
textureInit(&fb->texture, width, height, TEXTURE_FORMAT_RGBA,(texturedata_t){
|
||||
.rgbaColors = NULL
|
||||
});
|
||||
errorChain(errorGLCheck());
|
||||
|
||||
glGenFramebuffersEXT(1, &fb->id);
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb->id);
|
||||
errorChain(errorGLCheck());
|
||||
|
||||
glFramebufferTexture2DEXT(
|
||||
GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
|
||||
GL_TEXTURE_2D, fb->texture.id, 0
|
||||
);
|
||||
errorChain(errorGLCheck());
|
||||
|
||||
if(
|
||||
glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) !=
|
||||
GL_FRAMEBUFFER_COMPLETE_EXT
|
||||
) {
|
||||
assertUnreachable("Framebuffer is not complete");
|
||||
}
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
errorChain(errorGLCheck());
|
||||
errorOk();
|
||||
}
|
||||
#endif
|
||||
36
src/duskgl/display/framebuffer/framebuffergl.h
Normal file
36
src/duskgl/display/framebuffer/framebuffergl.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "display/texture/texture.h"
|
||||
#include "error/errorgl.h"
|
||||
|
||||
typedef struct {
|
||||
GLuint id;
|
||||
texture_t texture;
|
||||
} framebuffergl_t;
|
||||
|
||||
/**
|
||||
* Initializes the backbuffer framebuffer. (OpenGL implementation).
|
||||
*/
|
||||
errorret_t frameBufferGLInitBackBuffer(void);
|
||||
|
||||
#ifdef DUSK_DISPLAY_SIZE_DYNAMIC
|
||||
/**
|
||||
* Initializes an OpenGL style framebuffer.
|
||||
*
|
||||
* @param fb The framebuffer to initialize.
|
||||
* @param width The width of the framebuffer.
|
||||
* @param height The height of the framebuffer.
|
||||
* @return Either error or not.
|
||||
*/
|
||||
errorret_t frameBufferGLInit(
|
||||
framebuffergl_t *fb,
|
||||
const uint32_t width,
|
||||
const uint32_t height
|
||||
);
|
||||
#endif
|
||||
14
src/duskgl/display/framebuffer/framebufferplatform.h
Normal file
14
src/duskgl/display/framebuffer/framebufferplatform.h
Normal file
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "display/framebuffer/framebuffergl.h"
|
||||
typedef framebuffergl_t framebufferplatform_t;
|
||||
|
||||
#define frameBufferPlatformInitBackBuffer frameBufferGLInitBackBuffer
|
||||
#define frameBufferPlatformInit frameBufferGLInit
|
||||
#define frameBufferPlatformBind frameBufferGLBind
|
||||
10
src/duskgl/display/texture/CMakeLists.txt
Normal file
10
src/duskgl/display/texture/CMakeLists.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
# Copyright (c) 2026 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||
PUBLIC
|
||||
texturegl.c
|
||||
)
|
||||
86
src/duskgl/display/texture/texturegl.c
Normal file
86
src/duskgl/display/texture/texturegl.c
Normal file
@@ -0,0 +1,86 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "display/texture/texture.h"
|
||||
#include "assert/assert.h"
|
||||
#include "error/errorgl.h"
|
||||
|
||||
errorret_t textureInitGL(
|
||||
texturegl_t *texture,
|
||||
const int32_t width,
|
||||
const int32_t height,
|
||||
const textureformatgl_t format,
|
||||
const texturedata_t data
|
||||
) {
|
||||
glGenTextures(1, &texture->id);
|
||||
glBindTexture(GL_TEXTURE_2D, texture->id);
|
||||
errorChain(errorGLCheck());
|
||||
|
||||
switch(format) {
|
||||
case TEXTURE_FORMAT_RGBA:
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D, 0, format, width, height, 0,
|
||||
format, GL_UNSIGNED_BYTE, (void*)data.rgbaColors
|
||||
);
|
||||
break;
|
||||
|
||||
case TEXTURE_FORMAT_PALETTE:
|
||||
assertNotNull(data.paletteData, "Palette texture data cannot be NULL");
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0, GL_COLOR_INDEX8_EXT,
|
||||
width, height,
|
||||
0, GL_COLOR_INDEX8_EXT,
|
||||
GL_UNSIGNED_BYTE, (void*)data.paletteData
|
||||
);
|
||||
errorChain(errorGLCheck());
|
||||
|
||||
glColorTableEXT(
|
||||
GL_TEXTURE_2D, GL_RGBA, data.palette.palette->colorCount, GL_RGBA,
|
||||
GL_UNSIGNED_BYTE, (const void*)data.palette.palette->colors
|
||||
);
|
||||
break;
|
||||
|
||||
default:
|
||||
assertUnreachable("Unknown texture format");
|
||||
break;
|
||||
}
|
||||
errorChain(errorGLCheck());
|
||||
|
||||
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_WRAP_S, GL_REPEAT);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
|
||||
errorChain(errorGLCheck());
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
errorChain(errorGLCheck());
|
||||
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t textureBindGL(texturegl_t *texture) {
|
||||
if(texture == NULL) {
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
errorChain(errorGLCheck());
|
||||
errorOk();
|
||||
}
|
||||
|
||||
assertTrue(texture->id != 0, "Texture ID must be valid");
|
||||
glBindTexture(GL_TEXTURE_2D, texture->id);
|
||||
errorChain(errorGLCheck());
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t textureDisposeGL(texturegl_t *texture) {
|
||||
assertNotNull(texture, "Texture cannot be NULL");
|
||||
assertTrue(texture->id != 0, "Texture ID must be valid");
|
||||
|
||||
glDeleteTextures(1, &texture->id);
|
||||
errorChain(errorGLCheck());
|
||||
errorOk();
|
||||
}
|
||||
57
src/duskgl/display/texture/texturegl.h
Normal file
57
src/duskgl/display/texture/texturegl.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "dusk.h"
|
||||
|
||||
typedef union texturedata_u texturedata_t;
|
||||
|
||||
typedef enum {
|
||||
TEXTURE_FORMAT_RGBA = GL_RGBA,
|
||||
TEXTURE_FORMAT_PALETTE = GL_COLOR_INDEX8_EXT,
|
||||
} textureformatgl_t;
|
||||
|
||||
typedef struct {
|
||||
GLuint id;
|
||||
textureformatgl_t format;
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
} texturegl_t;
|
||||
|
||||
/**
|
||||
* Initializes a texture.
|
||||
*
|
||||
* @param texture The texture to initialize.
|
||||
* @param width The width of the texture.
|
||||
* @param height The height of the texture.
|
||||
* @param format The format of the texture (e.g., GL_RGBA, GL_ALPHA).
|
||||
* @param data The data for the texture, the format changes per format.
|
||||
* @return An error if the texture failed to initialize, otherwise success.
|
||||
*/
|
||||
errorret_t textureInitGL(
|
||||
texturegl_t *texture,
|
||||
const int32_t width,
|
||||
const int32_t height,
|
||||
const textureformatgl_t format,
|
||||
const texturedata_t data
|
||||
);
|
||||
|
||||
/**
|
||||
* Binds a texture for rendering. Providing NULL will unbind any texture.
|
||||
*
|
||||
* @param texture The texture to bind.
|
||||
* @return An error if the texture failed to bind, otherwise success.
|
||||
*/
|
||||
errorret_t textureBindGL(texturegl_t *texture);
|
||||
|
||||
/**
|
||||
* Disposes a texture.
|
||||
*
|
||||
* @param texture The texture to dispose.
|
||||
* @return An error if the texture failed to dispose, otherwise success.
|
||||
*/
|
||||
errorret_t textureDisposeGL(texturegl_t *texture);
|
||||
16
src/duskgl/display/texture/textureplatform.h
Normal file
16
src/duskgl/display/texture/textureplatform.h
Normal file
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "display/texture/texturegl.h"
|
||||
|
||||
typedef textureformatgl_t textureformatplatform_t;
|
||||
typedef texturegl_t textureplatform_t;
|
||||
|
||||
#define textureInitPlatform textureInitGL
|
||||
#define textureBindPlatform textureBindGL
|
||||
#define textureDisposePlatform textureDisposeGL
|
||||
@@ -6,4 +6,6 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "display/displaysdl2.h"
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
10
src/duskgl/error/CMakeLists.txt
Normal file
10
src/duskgl/error/CMakeLists.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
# Copyright (c) 2026 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||
PUBLIC
|
||||
errorgl.c
|
||||
)
|
||||
17
src/duskgl/error/errorgl.c
Normal file
17
src/duskgl/error/errorgl.c
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "errorgl.h"
|
||||
|
||||
errorret_t errorGLCheck(void) {
|
||||
GLenum err = glGetError();
|
||||
if(err != GL_NO_ERROR) {
|
||||
errorThrow("GL Error: %d", err);
|
||||
}
|
||||
|
||||
errorOk();
|
||||
}
|
||||
16
src/duskgl/error/errorgl.h
Normal file
16
src/duskgl/error/errorgl.h
Normal file
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "error/error.h"
|
||||
|
||||
/**
|
||||
* Gets the GL error (if any) and throws it as a dusk style error.
|
||||
*
|
||||
* @return Error code, if GL error present.
|
||||
*/
|
||||
errorret_t errorGLCheck(void);
|
||||
16
src/dusklinux/display/displayplatform.h
Normal file
16
src/dusklinux/display/displayplatform.h
Normal file
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "display/displaysdl2.h"
|
||||
|
||||
typedef displaysdl2_t displayplatform_t;
|
||||
|
||||
#define displayPlatformInit displaySDL2Init
|
||||
#define displayPlatformUpdate displaySDL2Update
|
||||
#define displayPlatformSwap displaySDL2Swap
|
||||
#define displayPlatformDispose displaySDL2Dispose
|
||||
@@ -1,8 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
@@ -9,4 +9,5 @@ target_include_directories(${DUSK_LIBRARY_TARGET_NAME}
|
||||
${CMAKE_CURRENT_LIST_DIR}
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
# Subdirs
|
||||
add_subdirectory(display)
|
||||
12
src/dusksdl2/display/CMakeLists.txt
Normal file
12
src/dusksdl2/display/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
# Copyright (c) 2026 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||
PUBLIC
|
||||
displaysdl2.c
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
111
src/dusksdl2/display/displaysdl2.c
Normal file
111
src/dusksdl2/display/displaysdl2.c
Normal file
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* Copyright (c) 2026 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "display/display.h"
|
||||
#include "engine/engine.h"
|
||||
#include "display/displaygl.h"
|
||||
|
||||
erroret_t displaySDL2Init(void) {
|
||||
uint32_t flags = SDL_INIT_VIDEO;
|
||||
#if INPUT_GAMEPAD == 1
|
||||
flags |= SDL_INIT_GAMECONTROLLER | SDL_INIT_JOYSTICK;
|
||||
#endif
|
||||
if(SDL_Init(flags) != 0) {
|
||||
errorThrow("SDL Failed to Initialize: %s", SDL_GetError());
|
||||
}
|
||||
|
||||
// Set OpenGL attributes (Needs to be done now or later?)
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
|
||||
// Create window with OpenGL flag.
|
||||
DISPLAY.window = SDL_CreateWindow(
|
||||
"Dusk",
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
SDL_WINDOWPOS_UNDEFINED,
|
||||
DUSK_WINDOW_WIDTH_DEFAULT,
|
||||
DUSK_WINDOW_HEIGHT_DEFAULT,
|
||||
SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI |
|
||||
SDL_WINDOW_OPENGL
|
||||
);
|
||||
if(!DISPLAY.window) {
|
||||
errorThrow("SDL_CreateWindow failed: %s", SDL_GetError());
|
||||
}
|
||||
|
||||
// Create OpenGL context
|
||||
DISPLAY.glContext = SDL_GL_CreateContext(DISPLAY.window);
|
||||
if(!DISPLAY.glContext) {
|
||||
errorThrow("SDL_GL_CreateContext failed: %s", SDL_GetError());
|
||||
}
|
||||
errorChain(errorGLCheck());
|
||||
|
||||
SDL_GL_SetSwapInterval(1);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
errorChain(errorGLCheck());
|
||||
|
||||
errorChain(displayOpenGLInit());
|
||||
|
||||
|
||||
// #if DUSK_PSP
|
||||
// errorChain(displayPSPInit());
|
||||
// #endif
|
||||
|
||||
errorChain(errorGLCheck());
|
||||
}
|
||||
|
||||
errorret_t displaySDL2Update(void) {
|
||||
SDL_Event event;
|
||||
while(SDL_PollEvent(&event)) {
|
||||
switch(event.type) {
|
||||
case SDL_QUIT: {
|
||||
ENGINE.running = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_WINDOWEVENT: {
|
||||
switch(event.window.event) {
|
||||
case SDL_WINDOWEVENT_CLOSE: {
|
||||
ENGINE.running = false;
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDL_GL_MakeCurrent(DISPLAY.window, DISPLAY.glContext);
|
||||
errorOk();
|
||||
}
|
||||
|
||||
errorret_t displaySDL2Swap(void) {
|
||||
SDL_GL_SwapWindow(DISPLAY.window);
|
||||
|
||||
GLenum err;
|
||||
while((err = glGetError()) != GL_NO_ERROR) {
|
||||
debugPrint("GL Error: %d\n", err);
|
||||
}
|
||||
errorOk();
|
||||
}
|
||||
|
||||
void displaySDL2Dispose(void) {
|
||||
if(DISPLAY.glContext) {
|
||||
SDL_GL_DeleteContext(DISPLAY.glContext);
|
||||
DISPLAY.glContext = NULL;
|
||||
}
|
||||
if(DISPLAY.window) {
|
||||
SDL_DestroyWindow(DISPLAY.window);
|
||||
DISPLAY.window = NULL;
|
||||
}
|
||||
SDL_Quit();
|
||||
}
|
||||
@@ -6,10 +6,30 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "dusk.h"
|
||||
#include "error/error.h"
|
||||
|
||||
typedef struct {
|
||||
SDL_Window *window;
|
||||
SDL_GLContext glContext;
|
||||
bool_t usingShaderedPalettes;
|
||||
} displayplatform_t;
|
||||
} displaysdl2_t;
|
||||
|
||||
/**
|
||||
* Initializes the SDL2 display system.
|
||||
*/
|
||||
errorret_t displaySDL2Init(void);
|
||||
|
||||
/**
|
||||
* Handles SDL2 Updating (pre-render context initialization)
|
||||
*/
|
||||
errorret_t displaySDL2Update(void);
|
||||
|
||||
/**
|
||||
* Handles SDL2 Display Swapping (to switch from frontbuffer to backbuffer).
|
||||
*/
|
||||
errorret_t displaySDL2Swap(void);
|
||||
|
||||
/**
|
||||
* Disposes/Cleans up the SDL2 Render system.
|
||||
*/
|
||||
void displaySDL2Dispose(void);
|
||||
@@ -6,4 +6,5 @@
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include "duskopengl.h"
|
||||
#include <SDL2/SDL.h>
|
||||
#include "duskgl.h"
|
||||
Reference in New Issue
Block a user