RGBA textures
This commit is contained in:
@@ -144,10 +144,78 @@ void textureInit(
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
texture->ready = true;
|
||||
|
||||
#elif DOLPHIN
|
||||
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);
|
||||
|
||||
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_CLAMP, GX_CLAMP,
|
||||
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
|
||||
);
|
||||
|
||||
texture->ready = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
void textureBind(const texture_t *texture) {
|
||||
void textureBind(texture_t *texture) {
|
||||
if(TEXTURE_BOUND == texture) return;
|
||||
|
||||
if(texture == NULL) {
|
||||
@@ -158,10 +226,7 @@ void textureBind(const texture_t *texture) {
|
||||
return;
|
||||
}
|
||||
|
||||
assertTrue(
|
||||
texture->id != 0,
|
||||
"Texture ID must not be 0"
|
||||
);
|
||||
assertTrue(texture->ready, "Texture ID must be ready");
|
||||
assertTrue(
|
||||
texture->width > 0 && texture->height > 0,
|
||||
"Texture width and height must be greater than 0"
|
||||
@@ -171,15 +236,28 @@ void textureBind(const texture_t *texture) {
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, texture->id);
|
||||
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
|
||||
#elif DOLPHIN
|
||||
GX_LoadTexObj(&texture->texObj, GX_TEXMAP0);
|
||||
|
||||
#endif
|
||||
TEXTURE_BOUND = texture;
|
||||
}
|
||||
|
||||
void textureDispose(texture_t *texture) {
|
||||
assertNotNull(texture, "Texture cannot be NULL");
|
||||
assertTrue(texture->id != 0, "Texture ID must not be 0");
|
||||
assertTrue(texture->ready, "Texture ID must be ready");
|
||||
|
||||
if(TEXTURE_BOUND == texture) {
|
||||
textureBind(NULL);
|
||||
}
|
||||
|
||||
#if DISPLAY_SDL2
|
||||
glDeleteTextures(1, &texture->id);
|
||||
#elif DOLPHIN
|
||||
if(texture->rgba) {
|
||||
free(texture->rgba);
|
||||
texture->rgba = NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user