Palettized image test.

This commit is contained in:
2025-09-02 18:57:28 -05:00
parent 71080682cc
commit 8de12da1ec
14 changed files with 394 additions and 39 deletions

View File

@@ -11,8 +11,10 @@
#include "display/framebuffer/framebuffer.h"
#include "display/scene/scenemanager.h"
#include "display/mesh/quad.h"
#include "asset/assetmanager.h"
camera_t SCENE_OVERWORLD_CAMERA;
asset_t *testAsset;
void sceneOverworldInit(void) {
cameraInit(&SCENE_OVERWORLD_CAMERA);
@@ -20,6 +22,10 @@ void sceneOverworldInit(void) {
scene_t *scene = &SCENE_MANAGER_SCENES[SCENE_TYPE_OVERWORLD];
scene->flags |= SCENE_FLAG_ACTIVE | SCENE_FLAG_VISIBLE;
assetManagerGetAsset("entities.dpi", &testAsset);
ref_t lock = assetLock(testAsset);
assetLoad(testAsset);
}
void sceneOverworldUpdate(void) {
@@ -35,7 +41,7 @@ void sceneOverworldRender(void) {
// Draw overlay layer.
spriteBatchPush(
NULL,
&testAsset->paletteImage.texture,
0.0f, 0.0f, 12.0f, 12.0f,
0xFF, 0x00, 0x00, 0xFF,
0.0f, 0.0f, 1.0f, 1.0f

View File

@@ -9,6 +9,7 @@
#include "assert/assert.h"
#include "util/memory.h"
#include "util/math.h"
#include "display/palette/palettelist.h"
const texture_t *TEXTURE_BOUND = NULL;
@@ -17,7 +18,7 @@ void textureInit(
const int32_t width,
const int32_t height,
const textureformat_t format,
const void *data
const texturedata_t data
) {
assertNotNull(texture, "Texture cannot be NULL");
assertTrue(width > 0 && height > 0, "width/height must be greater than 0");
@@ -40,15 +41,96 @@ void textureInit(
#if DISPLAY_SDL2
glGenTextures(1, &texture->id);
glBindTexture(GL_TEXTURE_2D, texture->id);
glTexImage2D(
GL_TEXTURE_2D, 0, format, width, height, 0,
format, GL_UNSIGNED_BYTE, data
);
switch(format) {
case TEXTURE_FORMAT_RGBA:
assertNotNull(data.rgba.colors, "RGBA texture data cannot be NULL");
glTexImage2D(
GL_TEXTURE_2D, 0, format, width, height, 0,
format, GL_UNSIGNED_BYTE, (void*)data.rgba.colors
);
break;
case TEXTURE_FORMAT_ALPHA:
assertNotNull(data.alpha.data, "Alpha texture data cannot be NULL");
glTexImage2D(
GL_TEXTURE_2D, 0, format, width, height, 0,
format, GL_UNSIGNED_BYTE, (void*)data.alpha.data
);
break;
case TEXTURE_FORMAT_PALETTE:
assertNotNull(data.palette.data, "Palette texture data cannot be NULL");
assertTrue(
data.palette.palette < PALETTE_LIST_COUNT,
"Palette index out of range"
);
const palette_t *pal = PALETTE_LIST[data.palette.palette];
assertNotNull(pal, "Palette cannot be NULL");
GLenum err = glGetError();
if (err != GL_NO_ERROR) {
assertUnreachable("GL Error before setting color table");
}
// Do we support paletted textures?
bool_t havePalTex = false;
GLint mask = 0;
glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &mask);
if(mask & GL_CONTEXT_CORE_PROFILE_BIT) {
GLint n=0; glGetIntegerv(GL_NUM_EXTENSIONS, &n);
for (GLint i=0; i<n; ++i) {
const char* e = (const char*)glGetStringi(GL_EXTENSIONS, i);
if (e && strcmp(e, "GL_EXT_paletted_texture")==0) { havePalTex = true; break; }
}
} else {
const char* ext = (const char*)glGetString(GL_EXTENSIONS);
havePalTex = ext && strstr(ext, "GL_EXT_paletted_texture");
}
if(!havePalTex) {
// Not supported, convert to RGBA using lookup
color_t formatted[width * height];
for(int32_t i = 0; i < width * height; i++) {
uint8_t index = data.palette.data[i];
assertTrue(
index < pal->colorCount,
"Palette index out of range"
);
formatted[i] = pal->colors[index];
}
glTexImage2D(
GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, (void*)formatted
);
} else {
// Supported.
glColorTableEXT(
GL_TEXTURE_2D, GL_RGBA, pal->colorCount, GL_RGBA,
GL_UNSIGNED_BYTE, (const void*)pal->colors
);
glTexImage2D(
GL_TEXTURE_2D,
0, GL_COLOR_INDEX8_EXT,
width, height,
0, GL_COLOR_INDEX8_EXT,
GL_UNSIGNED_BYTE, (void*)data.palette.data
);
}
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_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glBindTexture(GL_TEXTURE_2D, 0);
#endif

View File

@@ -13,6 +13,7 @@ typedef enum {
#if DISPLAY_SDL2
TEXTURE_FORMAT_RGBA = GL_RGBA,
TEXTURE_FORMAT_ALPHA = GL_ALPHA,
TEXTURE_FORMAT_PALETTE = GL_COLOR_INDEX8_EXT,
#endif
} textureformat_t;
@@ -25,6 +26,21 @@ typedef struct {
int32_t height;
} texture_t;
typedef union {
struct {
color_t *colors;
} rgba;
struct {
uint8_t palette;
uint8_t *data;
} palette;
struct {
uint8_t *data;
} alpha;
} texturedata_t;
extern const texture_t *TEXTURE_BOUND;
/**
@@ -34,14 +50,14 @@ extern const texture_t *TEXTURE_BOUND;
* @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 pixel data for the texture.
* @param data The data for the texture, the format changes per format.
*/
void textureInit(
texture_t *texture,
const int32_t width,
const int32_t height,
const textureformat_t format,
const void *data
const texturedata_t data
);
/**