Merge branch 'paletted-textures' into 'master'
4BPP paletted textures and OES_compressed_paletted_texture support See merge request simulant/GLdc!98
This commit is contained in:
commit
3d1f447af9
|
@ -1333,7 +1333,7 @@ GLuint _glGetActiveClientTexture() {
|
|||
void APIENTRY glClientActiveTextureARB(GLenum texture) {
|
||||
TRACE();
|
||||
|
||||
if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS) {
|
||||
if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_GLDC_TEXTURE_UNITS) {
|
||||
_glKosThrowError(GL_INVALID_ENUM, __func__);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ void APIENTRY glKosInitConfig(GLdcConfig* config) {
|
|||
config->initial_pt_capacity = 512 * 3;
|
||||
config->initial_tr_capacity = 1024 * 3;
|
||||
config->initial_immediate_capacity = 1024 * 3;
|
||||
config->internal_palette_format = GL_RGBA4;
|
||||
config->internal_palette_format = GL_RGBA8;
|
||||
}
|
||||
|
||||
void APIENTRY glKosInitEx(GLdcConfig* config) {
|
||||
|
|
|
@ -175,7 +175,7 @@ void APIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z) {
|
|||
|
||||
vert->x = x;
|
||||
vert->y = y;
|
||||
vert->z = z;
|
||||
vert->z = z;
|
||||
vert->u = UV_COORD[0];
|
||||
vert->v = UV_COORD[1];
|
||||
vert->s = ST_COORD[0];
|
||||
|
|
|
@ -27,7 +27,7 @@ static GLenum COLOR_MATERIAL_MODE = GL_AMBIENT_AND_DIFFUSE;
|
|||
|
||||
static GLenum COLOR_MATERIAL_MASK = AMBIENT_MASK | DIFFUSE_MASK;
|
||||
|
||||
static LightSource LIGHTS[MAX_LIGHTS];
|
||||
static LightSource LIGHTS[MAX_GLDC_LIGHTS];
|
||||
static GLuint ENABLED_LIGHT_COUNT = 0;
|
||||
static Material MATERIAL;
|
||||
|
||||
|
@ -37,7 +37,7 @@ static void recalcEnabledLights() {
|
|||
GLubyte i;
|
||||
|
||||
ENABLED_LIGHT_COUNT = 0;
|
||||
for(i = 0; i < MAX_LIGHTS; ++i) {
|
||||
for(i = 0; i < MAX_GLDC_LIGHTS; ++i) {
|
||||
if(LIGHTS[i].isEnabled) {
|
||||
ENABLED_LIGHT_COUNT++;
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ void _glInitLights() {
|
|||
MATERIAL.exponent = 0.0f;
|
||||
|
||||
GLubyte i;
|
||||
for(i = 0; i < MAX_LIGHTS; ++i) {
|
||||
for(i = 0; i < MAX_GLDC_LIGHTS; ++i) {
|
||||
memcpy(LIGHTS[i].ambient, ZERO, sizeof(GLfloat) * 4);
|
||||
memcpy(LIGHTS[i].diffuse, ONE, sizeof(GLfloat) * 4);
|
||||
memcpy(LIGHTS[i].specular, ONE, sizeof(GLfloat) * 4);
|
||||
|
@ -97,7 +97,7 @@ GL_FORCE_INLINE void _glPrecalcLightingValues(GLuint mask) {
|
|||
GLshort i;
|
||||
|
||||
if(mask & AMBIENT_MASK) {
|
||||
for(i = 0; i < MAX_LIGHTS; ++i) {
|
||||
for(i = 0; i < MAX_GLDC_LIGHTS; ++i) {
|
||||
LIGHTS[i].ambientMaterial[0] = LIGHTS[i].ambient[0] * MATERIAL.ambient[0];
|
||||
LIGHTS[i].ambientMaterial[1] = LIGHTS[i].ambient[1] * MATERIAL.ambient[1];
|
||||
LIGHTS[i].ambientMaterial[2] = LIGHTS[i].ambient[2] * MATERIAL.ambient[2];
|
||||
|
@ -106,7 +106,7 @@ GL_FORCE_INLINE void _glPrecalcLightingValues(GLuint mask) {
|
|||
}
|
||||
|
||||
if(mask & DIFFUSE_MASK) {
|
||||
for(i = 0; i < MAX_LIGHTS; ++i) {
|
||||
for(i = 0; i < MAX_GLDC_LIGHTS; ++i) {
|
||||
LIGHTS[i].diffuseMaterial[0] = LIGHTS[i].diffuse[0] * MATERIAL.diffuse[0];
|
||||
LIGHTS[i].diffuseMaterial[1] = LIGHTS[i].diffuse[1] * MATERIAL.diffuse[1];
|
||||
LIGHTS[i].diffuseMaterial[2] = LIGHTS[i].diffuse[2] * MATERIAL.diffuse[2];
|
||||
|
@ -115,7 +115,7 @@ GL_FORCE_INLINE void _glPrecalcLightingValues(GLuint mask) {
|
|||
}
|
||||
|
||||
if(mask & SPECULAR_MASK) {
|
||||
for(i = 0; i < MAX_LIGHTS; ++i) {
|
||||
for(i = 0; i < MAX_GLDC_LIGHTS; ++i) {
|
||||
LIGHTS[i].specularMaterial[0] = LIGHTS[i].specular[0] * MATERIAL.specular[0];
|
||||
LIGHTS[i].specularMaterial[1] = LIGHTS[i].specular[1] * MATERIAL.specular[1];
|
||||
LIGHTS[i].specularMaterial[2] = LIGHTS[i].specular[2] * MATERIAL.specular[2];
|
||||
|
@ -173,7 +173,7 @@ void APIENTRY glLightModeliv(GLenum pname, const GLint* params) {
|
|||
void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params) {
|
||||
GLubyte idx = light & 0xF;
|
||||
|
||||
if(idx >= MAX_LIGHTS) {
|
||||
if(idx >= MAX_GLDC_LIGHTS) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -227,7 +227,7 @@ void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params) {
|
|||
void APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param) {
|
||||
GLubyte idx = light & 0xF;
|
||||
|
||||
if(idx >= MAX_LIGHTS) {
|
||||
if(idx >= MAX_GLDC_LIGHTS) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -495,7 +495,7 @@ void _glPerformLighting(Vertex* vertices, EyeSpaceData* es, const uint32_t count
|
|||
const float Ny = data->n[1];
|
||||
const float Nz = data->n[2];
|
||||
|
||||
for(i = 0; i < MAX_LIGHTS; ++i) {
|
||||
for(i = 0; i < MAX_GLDC_LIGHTS; ++i) {
|
||||
if(!LIGHTS[i].isEnabled) {
|
||||
continue;
|
||||
}
|
||||
|
|
14
GL/matrix.c
14
GL/matrix.c
|
@ -288,11 +288,19 @@ void APIENTRY glFrustum(GLfloat left, GLfloat right,
|
|||
|
||||
/* Multiply the current matrix by an arbitrary matrix */
|
||||
void glMultMatrixf(const GLfloat *m) {
|
||||
Matrix4x4 TEMP;
|
||||
MEMCPY4(TEMP, m, sizeof(Matrix4x4));
|
||||
Matrix4x4 TEMP __attribute__((aligned(32)));
|
||||
const Matrix4x4 *pMatrix;
|
||||
|
||||
if (((GLint)m)&0xf){ /* Unaligned matrix */
|
||||
pMatrix = &TEMP;
|
||||
MEMCPY4(TEMP, m, sizeof(Matrix4x4));
|
||||
}
|
||||
else{
|
||||
pMatrix = (const Matrix4x4*) m;
|
||||
}
|
||||
|
||||
UploadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX));
|
||||
MultiplyMatrix4x4((const Matrix4x4*) &TEMP);
|
||||
MultiplyMatrix4x4(pMatrix);
|
||||
DownloadMatrix4x4(stack_top(MATRIX_STACKS + MATRIX_IDX));
|
||||
|
||||
if(MATRIX_MODE == GL_MODELVIEW) {
|
||||
|
|
|
@ -14,6 +14,11 @@
|
|||
#include "../containers/aligned_vector.h"
|
||||
#include "../containers/named_array.h"
|
||||
|
||||
#define MAX_GLDC_4BPP_PALETTE_SLOTS 16
|
||||
#define MAX_GLDC_PALETTE_SLOTS 4
|
||||
#define MAX_GLDC_SHARED_PALETTES (MAX_GLDC_PALETTE_SLOTS*MAX_GLDC_4BPP_PALETTE_SLOTS)
|
||||
|
||||
|
||||
extern void* memcpy4 (void *dest, const void *src, size_t count);
|
||||
|
||||
#define GL_NO_INSTRUMENT inline __attribute__((no_instrument_function))
|
||||
|
@ -508,8 +513,8 @@ GLuint _glFreeContiguousTextureMemory();
|
|||
|
||||
void _glApplyScissor(bool force);
|
||||
|
||||
#define MAX_TEXTURE_UNITS 2
|
||||
#define MAX_LIGHTS 8
|
||||
#define MAX_GLDC_TEXTURE_UNITS 2
|
||||
#define MAX_GLDC_LIGHTS 8
|
||||
|
||||
/* This is from KOS pvr_buffers.c */
|
||||
#define PVR_MIN_Z 0.0001f
|
||||
|
|
23
GL/state.c
23
GL/state.c
|
@ -236,9 +236,20 @@ void _glUpdatePVRTextureContext(PolyContext *context, GLshort textureUnit) {
|
|||
if(tx1->isPaletted) {
|
||||
if(_glIsSharedTexturePaletteEnabled()) {
|
||||
TexturePalette* palette = _glGetSharedPalette(tx1->shared_bank);
|
||||
context->txr.format |= GPUPaletteSelect8BPP(palette->bank);
|
||||
} else {
|
||||
context->txr.format |= GPUPaletteSelect8BPP((tx1->palette) ? tx1->palette->bank : 0);
|
||||
if (palette->size != 16){
|
||||
context->txr.format |= GPUPaletteSelect8BPP(palette->bank);
|
||||
}
|
||||
else{
|
||||
context->txr.format |= GPUPaletteSelect4BPP(palette->bank);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (tx1->palette->size != 16){
|
||||
context->txr.format |= GPUPaletteSelect8BPP((tx1->palette) ? tx1->palette->bank : 0);
|
||||
}
|
||||
else{
|
||||
context->txr.format |= GPUPaletteSelect4BPP((tx1->palette) ? tx1->palette->bank : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -291,7 +302,7 @@ void _glInitContext() {
|
|||
glDisable(GL_LIGHTING);
|
||||
|
||||
GLubyte i;
|
||||
for(i = 0; i < MAX_LIGHTS; ++i) {
|
||||
for(i = 0; i < MAX_GLDC_LIGHTS; ++i) {
|
||||
glDisable(GL_LIGHT0 + i);
|
||||
}
|
||||
}
|
||||
|
@ -739,7 +750,7 @@ void APIENTRY glGetFloatv(GLenum pname, GLfloat* params) {
|
|||
void APIENTRY glGetIntegerv(GLenum pname, GLint *params) {
|
||||
switch(pname) {
|
||||
case GL_MAX_LIGHTS:
|
||||
*params = MAX_LIGHTS;
|
||||
*params = MAX_GLDC_LIGHTS;
|
||||
break;
|
||||
case GL_TEXTURE_BINDING_2D:
|
||||
*params = (_glGetBoundTexture()) ? _glGetBoundTexture()->index : 0;
|
||||
|
@ -799,7 +810,7 @@ const GLubyte *glGetString(GLenum name) {
|
|||
return (const GLubyte*) "1.2 (partial) - GLdc 1.1";
|
||||
|
||||
case GL_EXTENSIONS:
|
||||
return (const GLubyte*) "GL_ARB_framebuffer_object, GL_ARB_multitexture, GL_ARB_texture_rg, GL_EXT_paletted_texture, GL_EXT_shared_texture_palette, GL_KOS_multiple_shared_palette, GL_ARB_vertex_array_bgra, GL_ARB_vertex_type_2_10_10_10_rev, GL_KOS_texture_memory_management, GL_ATI_meminfo";
|
||||
return (const GLubyte*)"GL_ARB_framebuffer_object, GL_ARB_multitexture, GL_ARB_texture_rg, GL_OES_compressed_paletted_texture, GL_EXT_paletted_texture, GL_EXT_shared_texture_palette, GL_KOS_multiple_shared_palette, GL_ARB_vertex_array_bgra, GL_ARB_vertex_type_2_10_10_10_rev, GL_KOS_texture_memory_management, GL_ATI_meminfo";
|
||||
}
|
||||
|
||||
return (const GLubyte*) "GL_KOS_ERROR: ENUM Unsupported\n";
|
||||
|
|
423
GL/texture.c
423
GL/texture.c
|
@ -18,17 +18,18 @@
|
|||
#define CLAMP_U (1<<1)
|
||||
#define CLAMP_V (1<<0)
|
||||
|
||||
static TextureObject* TEXTURE_UNITS[MAX_TEXTURE_UNITS] = {NULL, NULL};
|
||||
static TextureObject* TEXTURE_UNITS[MAX_GLDC_TEXTURE_UNITS] = {NULL, NULL};
|
||||
static NamedArray TEXTURE_OBJECTS;
|
||||
GLubyte ACTIVE_TEXTURE = 0;
|
||||
|
||||
static TexturePalette* SHARED_PALETTES[4] = {NULL, NULL, NULL, NULL};
|
||||
static TexturePalette* SHARED_PALETTES[MAX_GLDC_SHARED_PALETTES];
|
||||
|
||||
static GLuint _determinePVRFormat(GLint internalFormat, GLenum type);
|
||||
|
||||
static GLboolean BANKS_USED[4]; // Each time a 256 colour bank is used, this is set to true
|
||||
static GLboolean SUBBANKS_USED[4][16]; // 4 counts of the used 16 colour banks within the 256 ones
|
||||
static GLenum INTERNAL_PALETTE_FORMAT = GL_RGBA4;
|
||||
static GLboolean BANKS_USED[MAX_GLDC_PALETTE_SLOTS]; // Each time a 256 colour bank is used, this is set to true
|
||||
static GLboolean SUBBANKS_USED[MAX_GLDC_PALETTE_SLOTS][MAX_GLDC_4BPP_PALETTE_SLOTS]; // 4 counts of the used 16 colour banks within the 256 ones
|
||||
|
||||
static GLenum INTERNAL_PALETTE_FORMAT = GL_RGBA8;
|
||||
|
||||
static void* YALLOC_BASE = NULL;
|
||||
static size_t YALLOC_SIZE = 0;
|
||||
|
@ -63,20 +64,21 @@ static GLshort _glGenPaletteSlot(GLushort size) {
|
|||
assert(size == 16 || size == 256);
|
||||
|
||||
if(size == 16) {
|
||||
for(i = 0; i < 4; ++i) {
|
||||
for(j = 0; j < 16; ++j) {
|
||||
for(i = 0; i < MAX_GLDC_PALETTE_SLOTS; ++i) {
|
||||
for(j = 0; j < MAX_GLDC_4BPP_PALETTE_SLOTS; ++j) {
|
||||
if(!SUBBANKS_USED[i][j]) {
|
||||
BANKS_USED[i] = GL_TRUE;
|
||||
SUBBANKS_USED[i][j] = GL_TRUE;
|
||||
return (i * 16) + j;
|
||||
return (i * MAX_GLDC_4BPP_PALETTE_SLOTS) + j;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(i = 0; i < 4; ++i) {
|
||||
}
|
||||
else {
|
||||
for(i = 0; i < MAX_GLDC_PALETTE_SLOTS; ++i) {
|
||||
if(!BANKS_USED[i]) {
|
||||
BANKS_USED[i] = GL_TRUE;
|
||||
for(j = 0; j < 16; ++j) {
|
||||
for(j = 0; j < MAX_GLDC_4BPP_PALETTE_SLOTS; ++j) {
|
||||
SUBBANKS_USED[i][j] = GL_TRUE;
|
||||
}
|
||||
return i;
|
||||
|
@ -88,25 +90,54 @@ static GLshort _glGenPaletteSlot(GLushort size) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void _glReleasePaletteSlot(GLshort slot, GLushort size) {
|
||||
GLushort i;
|
||||
GLushort _glFreePaletteSlots(GLushort size)
|
||||
{
|
||||
GLushort i, j , slots = 0;
|
||||
|
||||
assert(size == 16 || size == 256);
|
||||
|
||||
if(size == 16) {
|
||||
GLushort bank = slot / 4;
|
||||
GLushort subbank = slot % 4;
|
||||
for(i = 0; i < MAX_GLDC_PALETTE_SLOTS; ++i) {
|
||||
for(j = 0; j < MAX_GLDC_4BPP_PALETTE_SLOTS; ++j) {
|
||||
if(!SUBBANKS_USED[i][j]) {
|
||||
slots++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for(i = 0; i < MAX_GLDC_PALETTE_SLOTS; ++i) {
|
||||
if(!BANKS_USED[i]) {
|
||||
slots++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return slots;
|
||||
}
|
||||
|
||||
static void _glReleasePaletteSlot(GLshort slot, GLushort size)
|
||||
{
|
||||
GLushort i, j;
|
||||
|
||||
assert(size == 16 || size == 256);
|
||||
|
||||
|
||||
if (size == 16) {
|
||||
GLushort bank = slot / MAX_GLDC_PALETTE_SLOTS;
|
||||
GLushort subbank = slot % MAX_GLDC_PALETTE_SLOTS;
|
||||
|
||||
SUBBANKS_USED[bank][subbank] = GL_FALSE;
|
||||
for(i = 0; i < 16; ++i) {
|
||||
if(SUBBANKS_USED[bank][i]) {
|
||||
|
||||
for (i = 0; i < MAX_GLDC_4BPP_PALETTE_SLOTS; ++i) {
|
||||
if (SUBBANKS_USED[bank][i]) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
BANKS_USED[bank] = GL_FALSE;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
BANKS_USED[slot] = GL_FALSE;
|
||||
for(i = 0; i < 16; ++i) {
|
||||
for (i = 0; i < MAX_GLDC_4BPP_PALETTE_SLOTS; ++i) {
|
||||
SUBBANKS_USED[slot][i] = GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -139,6 +170,30 @@ static void GPUTextureTwiddle8PPP(void* src, void* dst, uint32_t w, uint32_t h)
|
|||
}
|
||||
}
|
||||
|
||||
static void GPUTextureTwiddle4PPP(void* src, void* dst, uint32_t w, uint32_t h) {
|
||||
uint32_t x, y, yout, min, mask;
|
||||
|
||||
min = MIN(w, h);
|
||||
mask = min - 1;
|
||||
|
||||
uint8_t* pixels;
|
||||
uint16_t* vtex;
|
||||
pixels = (uint8_t*) src;
|
||||
vtex = (uint16_t*) dst;
|
||||
|
||||
for(y = 0; y < h; y += 2) {
|
||||
yout = y;
|
||||
for (x = 0; x < w; x += 2) {
|
||||
vtex[TWIDOUT((x & mask) / 2, (yout & mask) / 2) +
|
||||
(x / min + yout / min) * min * min / 4] =
|
||||
vtex[TWIDOUT((x & mask) / 2, (yout & mask) / 2) +
|
||||
(x / min + yout / min) * min * min / 4] =
|
||||
((pixels[(x + y * w) >> 1] & 15) << 8) | ((pixels[(x + (y + 1) * w) >> 1] & 15) << 12) |
|
||||
((pixels[(x + y * w) >> 1] >> 4) << 0) | ((pixels[(x + (y + 1) * w) >> 1] >> 4) << 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void GPUTextureTwiddle16BPP(void * src, void* dst, uint32_t w, uint32_t h) {
|
||||
uint32_t x, y, yout, min, mask;
|
||||
|
||||
|
@ -161,39 +216,55 @@ static void GPUTextureTwiddle16BPP(void * src, void* dst, uint32_t w, uint32_t h
|
|||
}
|
||||
|
||||
TexturePalette* _glGetSharedPalette(GLshort bank) {
|
||||
assert(bank >= 0 && bank < 4);
|
||||
assert(bank >= 0 && bank < MAX_GLDC_SHARED_PALETTES);
|
||||
return SHARED_PALETTES[bank];
|
||||
}
|
||||
|
||||
void _glSetInternalPaletteFormat(GLenum val) {
|
||||
INTERNAL_PALETTE_FORMAT = val;
|
||||
|
||||
if(INTERNAL_PALETTE_FORMAT == GL_RGBA4) {
|
||||
GPUSetPaletteFormat(GPU_PAL_ARGB4444);
|
||||
} else {
|
||||
assert(INTERNAL_PALETTE_FORMAT == GL_RGBA8);
|
||||
GPUSetPaletteFormat(GPU_PAL_ARGB8888);
|
||||
switch(INTERNAL_PALETTE_FORMAT){
|
||||
case GL_RGBA8:
|
||||
GPUSetPaletteFormat(GPU_PAL_ARGB8888);
|
||||
break;
|
||||
case GL_RGBA4:
|
||||
GPUSetPaletteFormat(GPU_PAL_ARGB4444);
|
||||
break;
|
||||
case GL_RGB5_A1:
|
||||
GPUSetPaletteFormat(GPU_PAL_ARGB1555);
|
||||
break;
|
||||
case GL_RGB565_KOS:
|
||||
GPUSetPaletteFormat(GPU_PAL_RGB565);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void _glApplyColorTable(TexturePalette* src) {
|
||||
/*
|
||||
* FIXME:
|
||||
*
|
||||
* - Different palette formats (GL_RGB -> PVR_PAL_RGB565)
|
||||
*/
|
||||
if(!src || !src->data) {
|
||||
return;
|
||||
}
|
||||
|
||||
GLushort i;
|
||||
GLushort offset = src->size * src->bank;
|
||||
|
||||
for(i = 0; i < src->width; ++i) {
|
||||
GLubyte* entry = &src->data[i * 4];
|
||||
if(INTERNAL_PALETTE_FORMAT == GL_RGBA8) {
|
||||
GPUSetPaletteEntry(offset + i, PACK_ARGB8888(entry[3], entry[0], entry[1], entry[2]));
|
||||
} else {
|
||||
GPUSetPaletteEntry(offset + i, PACK_ARGB4444(entry[3], entry[0], entry[1], entry[2]));
|
||||
|
||||
switch(INTERNAL_PALETTE_FORMAT)
|
||||
{
|
||||
case GL_RGBA8:
|
||||
GPUSetPaletteEntry(offset + i, PACK_ARGB8888(entry[3], entry[0], entry[1], entry[2]));
|
||||
break;
|
||||
case GL_RGBA4:
|
||||
GPUSetPaletteEntry(offset + i, PACK_ARGB4444(entry[3], entry[0], entry[1], entry[2]));
|
||||
break;
|
||||
case GL_RGB5_A1:
|
||||
GPUSetPaletteEntry(offset + i, PACK_ARGB1555(entry[3], entry[0], entry[1], entry[2]));
|
||||
break;
|
||||
case GL_RGB565_KOS:
|
||||
GPUSetPaletteEntry(offset + i, PACK_RGB565(entry[0], entry[1], entry[2]));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -364,19 +435,38 @@ static GLuint _glGetMipmapDataSize(TextureObject* obj) {
|
|||
return imageSize + offset;
|
||||
}
|
||||
|
||||
|
||||
void _glResetSharedPalettes()
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
for (i=0; i < MAX_GLDC_SHARED_PALETTES;i++){
|
||||
|
||||
MEMSET4(SHARED_PALETTES[i], 0x0, sizeof(TexturePalette));
|
||||
SHARED_PALETTES[i]->bank = -1;
|
||||
}
|
||||
|
||||
memset((void*) BANKS_USED, 0x0, sizeof(BANKS_USED));
|
||||
memset((void*) SUBBANKS_USED, 0x0, sizeof(SUBBANKS_USED));
|
||||
|
||||
}
|
||||
GLubyte _glInitTextures() {
|
||||
|
||||
uint32_t i;
|
||||
|
||||
named_array_init(&TEXTURE_OBJECTS, sizeof(TextureObject), MAX_TEXTURE_COUNT);
|
||||
|
||||
// Reserve zero so that it is never given to anyone as an ID!
|
||||
named_array_reserve(&TEXTURE_OBJECTS, 0);
|
||||
|
||||
SHARED_PALETTES[0] = _initTexturePalette();
|
||||
SHARED_PALETTES[1] = _initTexturePalette();
|
||||
SHARED_PALETTES[2] = _initTexturePalette();
|
||||
SHARED_PALETTES[3] = _initTexturePalette();
|
||||
for (i=0; i < MAX_GLDC_SHARED_PALETTES;i++){
|
||||
SHARED_PALETTES[i] = _initTexturePalette();
|
||||
}
|
||||
|
||||
memset((void*) BANKS_USED, 0x0, sizeof(BANKS_USED));
|
||||
memset((void*) SUBBANKS_USED, 0x0, sizeof(SUBBANKS_USED));
|
||||
_glResetSharedPalettes();
|
||||
|
||||
//memset((void*) BANKS_USED, 0x0, sizeof(BANKS_USED));
|
||||
//memset((void*) SUBBANKS_USED, 0x0, sizeof(SUBBANKS_USED));
|
||||
|
||||
size_t vram_free = GPUMemoryAvailable();
|
||||
YALLOC_SIZE = vram_free - PVR_MEM_BUFFER_SIZE; /* Take all but 64kb VRAM */
|
||||
|
@ -406,7 +496,7 @@ TextureObject* _glGetBoundTexture() {
|
|||
void APIENTRY glActiveTextureARB(GLenum texture) {
|
||||
TRACE();
|
||||
|
||||
if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS) {
|
||||
if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_GLDC_TEXTURE_UNITS) {
|
||||
_glKosThrowError(GL_INVALID_ENUM, "glActiveTextureARB");
|
||||
return;
|
||||
}
|
||||
|
@ -476,6 +566,11 @@ void APIENTRY glDeleteTextures(GLsizei n, GLuint *textures) {
|
|||
}
|
||||
|
||||
if(txr->palette && txr->palette->data) {
|
||||
|
||||
if (txr->palette->bank > -1) {
|
||||
_glReleasePaletteSlot(txr->palette->bank, txr->palette->size);
|
||||
txr->palette->bank = -1;
|
||||
}
|
||||
free(txr->palette->data);
|
||||
txr->palette->data = NULL;
|
||||
}
|
||||
|
@ -616,6 +711,8 @@ void APIENTRY glCompressedTexImage2DARB(GLenum target,
|
|||
}
|
||||
|
||||
GLboolean mipmapped = GL_FALSE;
|
||||
//GLboolean paletted = GL_FALSE;
|
||||
GLbyte *ptr = (GLbyte*)data;
|
||||
|
||||
switch(internalFormat) {
|
||||
case GL_COMPRESSED_ARGB_1555_VQ_KOS:
|
||||
|
@ -633,6 +730,50 @@ void APIENTRY glCompressedTexImage2DARB(GLenum target,
|
|||
case GL_COMPRESSED_RGB_565_VQ_MIPMAP_TWID_KOS:
|
||||
mipmapped = GL_TRUE;
|
||||
break;
|
||||
case GL_PALETTE4_RGB8_OES:
|
||||
glColorTableEXT(GL_TEXTURE_2D, GL_RGBA8, 16, internalFormat, GL_UNSIGNED_BYTE, data);
|
||||
ptr += 16*3;
|
||||
glTexImage2D(GL_TEXTURE_2D, level, GL_COLOR_INDEX4_EXT, width, height, border, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, ptr);
|
||||
return;
|
||||
|
||||
case GL_PALETTE4_RGBA8_OES:
|
||||
glColorTableEXT(GL_TEXTURE_2D, GL_RGBA8, 16, internalFormat, GL_UNSIGNED_BYTE, data);
|
||||
ptr += 16*4;
|
||||
glTexImage2D(GL_TEXTURE_2D, level, GL_COLOR_INDEX4_EXT, width, height, border, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, ptr);
|
||||
return;
|
||||
|
||||
case GL_PALETTE4_R5_G6_B5_OES:
|
||||
case GL_PALETTE4_RGBA4_OES:
|
||||
case GL_PALETTE4_RGB5_A1_OES:
|
||||
glColorTableEXT(GL_TEXTURE_2D, GL_RGBA8, 16, internalFormat, GL_UNSIGNED_BYTE, data);
|
||||
ptr += 16*2;
|
||||
glTexImage2D(GL_TEXTURE_2D, level, GL_COLOR_INDEX4_EXT, width, height, border, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, ptr);
|
||||
return;
|
||||
|
||||
case GL_PALETTE8_RGB8_OES:
|
||||
glColorTableEXT(GL_TEXTURE_2D, GL_RGBA8, 256, internalFormat, GL_UNSIGNED_BYTE, data);
|
||||
ptr += 256*3;
|
||||
glTexImage2D(GL_TEXTURE_2D, level, GL_COLOR_INDEX8_EXT, width, height, border, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, ptr);
|
||||
return;
|
||||
|
||||
|
||||
case GL_PALETTE8_RGBA8_OES:
|
||||
//
|
||||
glColorTableEXT(GL_TEXTURE_2D, GL_RGBA8, 256, internalFormat, GL_UNSIGNED_BYTE, data);
|
||||
ptr += 256*4;
|
||||
glTexImage2D(GL_TEXTURE_2D, level, GL_COLOR_INDEX8_EXT, width, height, border, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, ptr);
|
||||
return;
|
||||
|
||||
|
||||
case GL_PALETTE8_RGBA4_OES:
|
||||
case GL_PALETTE8_RGB5_A1_OES:
|
||||
case GL_PALETTE8_R5_G6_B5_OES:
|
||||
|
||||
glColorTableEXT(GL_TEXTURE_2D, GL_RGBA8, 256, internalFormat, GL_UNSIGNED_BYTE, data);
|
||||
ptr += 256*2;
|
||||
glTexImage2D(GL_TEXTURE_2D, level, GL_COLOR_INDEX8_EXT, width, height, border, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, ptr);
|
||||
return;
|
||||
|
||||
default: {
|
||||
_glKosThrowError(GL_INVALID_OPERATION, __func__);
|
||||
return;
|
||||
|
@ -824,9 +965,21 @@ static GLint _cleanInternalFormat(GLint internalFormat) {
|
|||
typedef void (*TextureConversionFunc)(const GLubyte*, GLubyte*);
|
||||
|
||||
GL_FORCE_INLINE void _rgba8888_to_argb4444(const GLubyte* source, GLubyte* dest) {
|
||||
*((GLushort*) dest) = (source[3] & 0xF0) << 8 | (source[0] & 0xF0) << 4 | (source[1] & 0xF0) | (source[2] & 0xF0) >> 4;
|
||||
|
||||
*((GLushort*) dest) = (source[1] & 0xF0) << 8 | (source[2] & 0xF0) << 4 | (source[0] & 0xF0) | (source[3] & 0xF0) >> 4;
|
||||
}
|
||||
|
||||
GL_FORCE_INLINE void _rgba8888_to_rgba4444(const GLubyte* source, GLubyte* dest) {
|
||||
|
||||
*((GLushort*) dest) = (source[3] & 0xF0) << 8 | (source[2] & 0xF0) << 4 | (source[1] & 0xF0) | (source[0] & 0xF0) >> 4;
|
||||
}
|
||||
|
||||
GL_FORCE_INLINE void _rgb888_to_argb4444(const GLubyte* source, GLubyte* dest) {
|
||||
|
||||
*((GLushort*) dest) = 0xF << 8 | (source[0] & 0xF0) << 4 | (source[1] & 0xF0) | (source[2] & 0xF0) >> 4;
|
||||
}
|
||||
|
||||
|
||||
GL_FORCE_INLINE void _rgba8888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
|
||||
/* Noop */
|
||||
GLubyte* dst = (GLubyte*) dest;
|
||||
|
@ -836,7 +989,15 @@ GL_FORCE_INLINE void _rgba8888_to_rgba8888(const GLubyte* source, GLubyte* dest)
|
|||
dst[3] = source[3];
|
||||
}
|
||||
|
||||
GL_FORCE_INLINE void _rgba4444_to_rgba4444(const GLubyte* source, GLubyte* dest) {
|
||||
/* Noop */
|
||||
GLubyte* dst = (GLubyte*) dest;
|
||||
dst[0] = source[0];
|
||||
dst[1] = source[1];
|
||||
}
|
||||
|
||||
GL_FORCE_INLINE void _rgba8888_to_rgb565(const GLubyte* source, GLubyte* dest) {
|
||||
|
||||
*((GLushort*) dest) = ((source[0] & 0b11111000) << 8) | ((source[1] & 0b11111100) << 3) | (source[2] >> 3);
|
||||
}
|
||||
|
||||
|
@ -849,10 +1010,23 @@ GL_FORCE_INLINE void _rgb888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
|
|||
dst[3] = 255;
|
||||
}
|
||||
|
||||
GL_FORCE_INLINE void _rgb888_to_rgba4444(const GLubyte* source, GLubyte* dest) {
|
||||
*((GLushort*) dest) = 0xF << 8 | (source[2] & 0xF0) << 4 | (source[1] & 0xF0) | (source[0] & 0xF0) >> 4;
|
||||
}
|
||||
|
||||
GL_FORCE_INLINE void _rgb888_to_rgb565(const GLubyte* source, GLubyte* dest) {
|
||||
*((GLushort*) dest) = ((source[0] & 0b11111000) << 8) | ((source[1] & 0b11111100) << 3) | (source[2] >> 3);
|
||||
}
|
||||
|
||||
GL_FORCE_INLINE void _rgb565_to_rgb8888(const GLubyte* source, GLubyte* dest) {
|
||||
GLushort src = *((GLushort*) source);
|
||||
|
||||
dest[3] = (src & 0x1f) << 3;
|
||||
dest[2] = ((src >> 5) & 0x3f) <<2;
|
||||
dest[1] = ((src >> 11) & 0x1f) <<3;
|
||||
dest[0] = 0xff;
|
||||
}
|
||||
|
||||
GL_FORCE_INLINE void _rgba8888_to_a000(const GLubyte* source, GLubyte* dest) {
|
||||
*((GLushort*) dest) = ((source[3] & 0b11111000) << 8);
|
||||
}
|
||||
|
@ -870,10 +1044,20 @@ GL_FORCE_INLINE void _rgba4444_to_rgba8888(const GLubyte* source, GLubyte* dest)
|
|||
GLushort src = *((GLushort*) source);
|
||||
GLubyte* dst = (GLubyte*) dest;
|
||||
|
||||
dst[0] = ((src & 0xF000) >> 12) * 2;
|
||||
dst[1] = ((src & 0x0F00) >> 8) * 2;
|
||||
dst[2] = ((src & 0x00F0) >> 4) * 2;
|
||||
dst[3] = ((src & 0x000F)) * 2;
|
||||
dst[0] = (src & 0xf) << 4;
|
||||
dst[1] = ((src >> 4) & 0xf) << 4;
|
||||
dst[2] = ((src >> 8) & 0xf) << 4;
|
||||
dst[3] = (src >> 12) << 4;
|
||||
}
|
||||
|
||||
GL_FORCE_INLINE void _rgba5551_to_rgba8888(const GLubyte* source, GLubyte* dest) {
|
||||
GLushort src = *((GLushort*) source);
|
||||
GLubyte* dst = (GLubyte*) dest;
|
||||
|
||||
dst[0] = (src & 0x1f) << 3;
|
||||
dst[1] = ((src >> 5) & 0x1f) << 3;
|
||||
dst[2] = ((src >> 5) & 0x1f) << 3;
|
||||
dst[3] = (src >> 15) << 7;
|
||||
}
|
||||
|
||||
GL_FORCE_INLINE void _i8_to_i8(const GLubyte* source, GLubyte* dest) {
|
||||
|
@ -882,8 +1066,10 @@ GL_FORCE_INLINE void _i8_to_i8(const GLubyte* source, GLubyte* dest) {
|
|||
*dst = *source;
|
||||
}
|
||||
|
||||
static inline void _alpha8_to_argb4444(const GLubyte* source, GLubyte* dest) {
|
||||
*((GLushort*) dest) = (*source & 0xF0) << 8 | (0xFF & 0xF0) << 4 | (0xFF & 0xF0) | (0xFF & 0xF0) >> 4;
|
||||
static inline void _a8_to_argb4444(const GLubyte* source, GLubyte* dest) {
|
||||
GLushort color = *source & 0xf0;
|
||||
color |= (color >> 4);
|
||||
*((GLushort*) dest) = (color << 8) | color;
|
||||
}
|
||||
|
||||
static TextureConversionFunc _determineConversion(GLint internalFormat, GLenum format, GLenum type) {
|
||||
|
@ -891,7 +1077,8 @@ static TextureConversionFunc _determineConversion(GLint internalFormat, GLenum f
|
|||
case GL_ALPHA: {
|
||||
if(format == GL_ALPHA) {
|
||||
/* Dreamcast doesn't really support GL_ALPHA internally, so store as argb with each rgb value as white */
|
||||
return _alpha8_to_argb4444;
|
||||
/* Applying alpha values to all channels seems a better option*/
|
||||
return _a8_to_argb4444;
|
||||
} else if(type == GL_UNSIGNED_BYTE && format == GL_RGBA) {
|
||||
return _rgba8888_to_a000;
|
||||
} else if(type == GL_BYTE && format == GL_RGBA) {
|
||||
|
@ -924,19 +1111,43 @@ static TextureConversionFunc _determineConversion(GLint internalFormat, GLenum f
|
|||
return _rgba4444_to_argb4444;
|
||||
}
|
||||
} break;
|
||||
case GL_RGBA8: {
|
||||
case GL_RGBA8:
|
||||
case GL_RGBA4:
|
||||
case GL_RGB5_A1:
|
||||
case GL_RGB565_KOS:
|
||||
|
||||
if(type == GL_UNSIGNED_BYTE && format == GL_RGBA) {
|
||||
return _rgba8888_to_rgba8888;
|
||||
} else if (type == GL_BYTE && format == GL_RGBA) {
|
||||
}
|
||||
else
|
||||
if (type == GL_BYTE && format == GL_RGBA) {
|
||||
return _rgba8888_to_rgba8888;
|
||||
} else if(type == GL_UNSIGNED_BYTE && format == GL_RGB) {
|
||||
}
|
||||
else
|
||||
if(type == GL_UNSIGNED_BYTE && format == GL_RGB) {
|
||||
return _rgb888_to_rgba8888;
|
||||
} else if (type == GL_BYTE && format == GL_RGB) {
|
||||
}
|
||||
else
|
||||
if (type == GL_BYTE && format == GL_RGB) {
|
||||
return _rgb888_to_rgba8888;
|
||||
} else if(type == GL_UNSIGNED_SHORT_4_4_4_4 && format == GL_RGBA) {
|
||||
}
|
||||
else
|
||||
if(type == GL_UNSIGNED_SHORT_4_4_4_4 && format == GL_RGBA) {
|
||||
return _rgba4444_to_rgba8888;
|
||||
}
|
||||
} break;
|
||||
else
|
||||
if(type == GL_UNSIGNED_BYTE && format == GL_RGBA4) {
|
||||
return _rgba4444_to_rgba8888;
|
||||
}
|
||||
else
|
||||
if(type == GL_UNSIGNED_BYTE && format == GL_RGB5_A1) {
|
||||
return _rgba5551_to_rgba8888;
|
||||
}
|
||||
else
|
||||
if(type == GL_UNSIGNED_BYTE && format == GL_RGB565_KOS) {
|
||||
return _rgb565_to_rgb8888;
|
||||
}
|
||||
break;
|
||||
case GL_COLOR_INDEX8_EXT:
|
||||
if(format == GL_COLOR_INDEX) {
|
||||
switch(type) {
|
||||
|
@ -1050,6 +1261,12 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
|||
return;
|
||||
}
|
||||
|
||||
if (width > 1024 || height > 1024){
|
||||
INFO_MSG("Invalid texture size");
|
||||
_glKosThrowError(GL_INVALID_VALUE, __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
if(format != GL_COLOR_INDEX) {
|
||||
if(!_isSupportedFormat(format)) {
|
||||
INFO_MSG("Unsupported format");
|
||||
|
@ -1071,7 +1288,7 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
|||
return;
|
||||
}
|
||||
} else {
|
||||
if(internalFormat != GL_COLOR_INDEX8_EXT) {
|
||||
if(internalFormat != GL_COLOR_INDEX8_EXT && internalFormat != GL_COLOR_INDEX4_EXT) {
|
||||
INFO_MSG("");
|
||||
_glKosThrowError(GL_INVALID_ENUM, __func__);
|
||||
return;
|
||||
|
@ -1129,7 +1346,7 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
|||
return;
|
||||
}
|
||||
|
||||
GLboolean isPaletted = (internalFormat == GL_COLOR_INDEX8_EXT) ? GL_TRUE : GL_FALSE;
|
||||
GLboolean isPaletted = (internalFormat == GL_COLOR_INDEX8_EXT || internalFormat == GL_COLOR_INDEX4_EXT) ? GL_TRUE : GL_FALSE;
|
||||
|
||||
/* Calculate the format that we need to convert the data to */
|
||||
GLuint pvr_format = _determinePVRFormat(internalFormat, type);
|
||||
|
@ -1161,6 +1378,11 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
|||
GLint destStride = isPaletted ? 1 : 2;
|
||||
GLuint bytes = (width * height * destStride);
|
||||
|
||||
//special case 4bpp
|
||||
if(internalFormat == GL_COLOR_INDEX4_EXT){
|
||||
bytes >>= 1;
|
||||
}
|
||||
|
||||
if(!active->data) {
|
||||
assert(active);
|
||||
assert(width);
|
||||
|
@ -1302,8 +1524,14 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
|||
|
||||
if(internalFormat == GL_COLOR_INDEX8_EXT) {
|
||||
GPUTextureTwiddle8PPP((void*) pixels, targetData, width, height);
|
||||
} else {
|
||||
GPUTextureTwiddle16BPP((void*) pixels, targetData, width, height);
|
||||
}
|
||||
else{
|
||||
if(internalFormat == GL_COLOR_INDEX4_EXT) {
|
||||
GPUTextureTwiddle4PPP((void*) pixels, targetData, width, height);
|
||||
}
|
||||
else {
|
||||
GPUTextureTwiddle16BPP((void*) pixels, targetData, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
/* We make sure we remove nontwiddled and add twiddled. We could always
|
||||
|
@ -1403,18 +1631,21 @@ void APIENTRY glTexParameterf(GLenum target, GLenum pname, GLfloat param) {
|
|||
}
|
||||
|
||||
GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *data) {
|
||||
|
||||
GLint validTargets[] = {
|
||||
GL_TEXTURE_2D,
|
||||
GL_SHARED_TEXTURE_PALETTE_EXT,
|
||||
GL_SHARED_TEXTURE_PALETTE_0_KOS,
|
||||
GL_SHARED_TEXTURE_PALETTE_1_KOS,
|
||||
GL_SHARED_TEXTURE_PALETTE_2_KOS,
|
||||
GL_SHARED_TEXTURE_PALETTE_3_KOS,
|
||||
0
|
||||
};
|
||||
GL_SHARED_TEXTURE_PALETTE_0_KOS,GL_SHARED_TEXTURE_PALETTE_1_KOS,GL_SHARED_TEXTURE_PALETTE_2_KOS,GL_SHARED_TEXTURE_PALETTE_3_KOS,GL_SHARED_TEXTURE_PALETTE_4_KOS,GL_SHARED_TEXTURE_PALETTE_5_KOS,GL_SHARED_TEXTURE_PALETTE_6_KOS,GL_SHARED_TEXTURE_PALETTE_7_KOS,GL_SHARED_TEXTURE_PALETTE_8_KOS,GL_SHARED_TEXTURE_PALETTE_9_KOS,
|
||||
GL_SHARED_TEXTURE_PALETTE_10_KOS,GL_SHARED_TEXTURE_PALETTE_11_KOS,GL_SHARED_TEXTURE_PALETTE_12_KOS,GL_SHARED_TEXTURE_PALETTE_13_KOS,GL_SHARED_TEXTURE_PALETTE_14_KOS,GL_SHARED_TEXTURE_PALETTE_15_KOS,GL_SHARED_TEXTURE_PALETTE_16_KOS,GL_SHARED_TEXTURE_PALETTE_17_KOS,GL_SHARED_TEXTURE_PALETTE_18_KOS,GL_SHARED_TEXTURE_PALETTE_19_KOS,
|
||||
GL_SHARED_TEXTURE_PALETTE_20_KOS,GL_SHARED_TEXTURE_PALETTE_21_KOS,GL_SHARED_TEXTURE_PALETTE_22_KOS,GL_SHARED_TEXTURE_PALETTE_23_KOS,GL_SHARED_TEXTURE_PALETTE_24_KOS,GL_SHARED_TEXTURE_PALETTE_25_KOS,GL_SHARED_TEXTURE_PALETTE_26_KOS,GL_SHARED_TEXTURE_PALETTE_27_KOS,GL_SHARED_TEXTURE_PALETTE_28_KOS,GL_SHARED_TEXTURE_PALETTE_29_KOS,
|
||||
GL_SHARED_TEXTURE_PALETTE_30_KOS,GL_SHARED_TEXTURE_PALETTE_31_KOS,GL_SHARED_TEXTURE_PALETTE_32_KOS,GL_SHARED_TEXTURE_PALETTE_33_KOS,GL_SHARED_TEXTURE_PALETTE_34_KOS,GL_SHARED_TEXTURE_PALETTE_35_KOS,GL_SHARED_TEXTURE_PALETTE_36_KOS,GL_SHARED_TEXTURE_PALETTE_37_KOS,GL_SHARED_TEXTURE_PALETTE_38_KOS,GL_SHARED_TEXTURE_PALETTE_39_KOS,
|
||||
GL_SHARED_TEXTURE_PALETTE_40_KOS,GL_SHARED_TEXTURE_PALETTE_41_KOS,GL_SHARED_TEXTURE_PALETTE_42_KOS,GL_SHARED_TEXTURE_PALETTE_43_KOS,GL_SHARED_TEXTURE_PALETTE_44_KOS,GL_SHARED_TEXTURE_PALETTE_45_KOS,GL_SHARED_TEXTURE_PALETTE_46_KOS,GL_SHARED_TEXTURE_PALETTE_47_KOS,GL_SHARED_TEXTURE_PALETTE_48_KOS,GL_SHARED_TEXTURE_PALETTE_49_KOS,
|
||||
GL_SHARED_TEXTURE_PALETTE_50_KOS,GL_SHARED_TEXTURE_PALETTE_51_KOS,GL_SHARED_TEXTURE_PALETTE_52_KOS,GL_SHARED_TEXTURE_PALETTE_53_KOS,GL_SHARED_TEXTURE_PALETTE_54_KOS,GL_SHARED_TEXTURE_PALETTE_55_KOS,GL_SHARED_TEXTURE_PALETTE_56_KOS,GL_SHARED_TEXTURE_PALETTE_57_KOS,GL_SHARED_TEXTURE_PALETTE_58_KOS,GL_SHARED_TEXTURE_PALETTE_59_KOS,
|
||||
GL_SHARED_TEXTURE_PALETTE_60_KOS,GL_SHARED_TEXTURE_PALETTE_61_KOS,GL_SHARED_TEXTURE_PALETTE_62_KOS,GL_SHARED_TEXTURE_PALETTE_63_KOS,
|
||||
0};
|
||||
|
||||
GLint validInternalFormats[] = {GL_RGB8, GL_RGBA8, 0};
|
||||
GLint validFormats[] = {GL_RGB, GL_RGBA, 0};
|
||||
GLint validInternalFormats[] = {GL_RGB8, GL_RGBA8, GL_RGBA4, 0};
|
||||
GLint validFormats[] = {GL_RGB, GL_RGBA,GL_RGB5_A1, GL_RGB5_A1, GL_RGB565_KOS, GL_RGBA4, 0};
|
||||
GLint validTypes[] = {GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, 0};
|
||||
|
||||
if(_glCheckValidEnum(target, validTargets, __func__) != 0) {
|
||||
|
@ -1425,6 +1656,33 @@ GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsize
|
|||
return;
|
||||
}
|
||||
|
||||
switch(format){
|
||||
case GL_PALETTE4_RGBA8_OES:
|
||||
case GL_PALETTE8_RGBA8_OES:
|
||||
format = GL_RGBA;
|
||||
break;
|
||||
case GL_PALETTE4_RGB8_OES:
|
||||
case GL_PALETTE8_RGB8_OES:
|
||||
format = GL_RGB;
|
||||
break;
|
||||
case GL_PALETTE4_R5_G6_B5_OES:
|
||||
case GL_PALETTE8_R5_G6_B5_OES:
|
||||
case GL_UNSIGNED_SHORT_5_6_5:
|
||||
format = GL_RGB565_KOS;
|
||||
break;
|
||||
case GL_PALETTE4_RGB5_A1_OES:
|
||||
case GL_PALETTE8_RGB5_A1_OES:
|
||||
case GL_UNSIGNED_SHORT_5_5_5_1:
|
||||
format = GL_RGB5_A1;
|
||||
break;
|
||||
case GL_PALETTE4_RGBA4_OES:
|
||||
case GL_PALETTE8_RGBA4_OES:
|
||||
case GL_UNSIGNED_SHORT_4_4_4_4:
|
||||
format = GL_RGBA4;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if(_glCheckValidEnum(format, validFormats, __func__) != 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -1444,7 +1702,7 @@ GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsize
|
|||
assert(sourceStride > -1);
|
||||
|
||||
TextureConversionFunc convert = _determineConversion(
|
||||
GL_RGBA8, /* We always store palettes in this format */
|
||||
INTERNAL_PALETTE_FORMAT,
|
||||
format,
|
||||
type
|
||||
);
|
||||
|
@ -1456,21 +1714,25 @@ GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsize
|
|||
|
||||
TexturePalette* palette = NULL;
|
||||
|
||||
GLboolean sharedPaletteUsed = GL_FALSE;
|
||||
|
||||
/* Custom extension - allow uploading to one of 4 custom palettes */
|
||||
if(target == GL_SHARED_TEXTURE_PALETTE_EXT || target == GL_SHARED_TEXTURE_PALETTE_0_KOS) {
|
||||
palette = SHARED_PALETTES[0];
|
||||
} else if(target == GL_SHARED_TEXTURE_PALETTE_1_KOS) {
|
||||
palette = SHARED_PALETTES[1];
|
||||
} else if(target == GL_SHARED_TEXTURE_PALETTE_2_KOS) {
|
||||
palette = SHARED_PALETTES[2];
|
||||
} else if(target == GL_SHARED_TEXTURE_PALETTE_3_KOS) {
|
||||
palette = SHARED_PALETTES[3];
|
||||
} else {
|
||||
sharedPaletteUsed = GL_TRUE;
|
||||
}
|
||||
|
||||
for (GLbyte i = 1; i < MAX_GLDC_SHARED_PALETTES; ++i) {
|
||||
if (target == GL_SHARED_TEXTURE_PALETTE_0_KOS + i) {
|
||||
palette = SHARED_PALETTES[i];
|
||||
sharedPaletteUsed = GL_TRUE;
|
||||
}
|
||||
}
|
||||
if (sharedPaletteUsed == GL_FALSE){
|
||||
TextureObject* active = _glGetBoundTexture();
|
||||
if(!active->palette) {
|
||||
active->palette = _initTexturePalette();
|
||||
}
|
||||
|
||||
palette = active->palette;
|
||||
}
|
||||
|
||||
|
@ -1623,6 +1885,9 @@ GLAPI void APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height
|
|||
_GL_UNUSED(pixels);
|
||||
assert(0 && "Not Implemented");
|
||||
}
|
||||
GLuint _glMaxTextureMemory() {
|
||||
return YALLOC_SIZE;
|
||||
}
|
||||
|
||||
GLuint _glFreeTextureMemory() {
|
||||
return yalloc_count_free(YALLOC_BASE);
|
||||
|
|
|
@ -161,6 +161,22 @@ GLAPI void APIENTRY glGetColorTableEXT(GLenum target, GLenum format, GLenum type
|
|||
GLAPI void APIENTRY glGetColorTableParameterivEXT(GLenum target, GLenum pname, GLint *params);
|
||||
GLAPI void APIENTRY glGetColorTableParameterfvEXT(GLenum target, GLenum pname, GLfloat *params);
|
||||
|
||||
/* ext OES_compressed_paletted_texture */
|
||||
|
||||
/* PixelInternalFormat */
|
||||
//Ozzy: used MesaGL definitions please adjust if it causes probs.
|
||||
#define GL_PALETTE4_RGB8_OES 0x8B90
|
||||
#define GL_PALETTE4_RGBA8_OES 0x8B91
|
||||
#define GL_PALETTE4_R5_G6_B5_OES 0x8B92
|
||||
#define GL_PALETTE4_RGBA4_OES 0x8B93
|
||||
#define GL_PALETTE4_RGB5_A1_OES 0x8B94
|
||||
#define GL_PALETTE8_RGB8_OES 0x8B95
|
||||
#define GL_PALETTE8_RGBA8_OES 0x8B96
|
||||
#define GL_PALETTE8_R5_G6_B5_OES 0x8B97
|
||||
#define GL_PALETTE8_RGBA4_OES 0x8B98
|
||||
#define GL_PALETTE8_RGB5_A1_OES 0x8B99
|
||||
|
||||
|
||||
/* Loads VQ compressed texture from SH4 RAM into PVR VRAM */
|
||||
/* internalformat must be one of the following constants:
|
||||
GL_UNSIGNED_SHORT_5_6_5_VQ
|
||||
|
|
|
@ -88,6 +88,7 @@ GLAPI void APIENTRY glKosInitConfig(GLdcConfig* config);
|
|||
GLAPI void APIENTRY glKosInitEx(GLdcConfig* config);
|
||||
GLAPI void APIENTRY glKosSwapBuffers();
|
||||
|
||||
|
||||
/*
|
||||
* CUSTOM EXTENSION multiple_shared_palette_KOS
|
||||
*
|
||||
|
@ -107,20 +108,90 @@ GLAPI void APIENTRY glKosSwapBuffers();
|
|||
* by default textures use shared palette 0.
|
||||
*/
|
||||
|
||||
|
||||
#define GL_SHARED_TEXTURE_PALETTE_0_KOS 0xEEFC
|
||||
#define GL_SHARED_TEXTURE_PALETTE_1_KOS 0xEEFD
|
||||
#define GL_SHARED_TEXTURE_PALETTE_2_KOS 0xEEFE
|
||||
#define GL_SHARED_TEXTURE_PALETTE_3_KOS 0xEEFF
|
||||
#define GL_SHARED_TEXTURE_PALETTE_4_KOS 0xEF00
|
||||
#define GL_SHARED_TEXTURE_PALETTE_5_KOS 0xEF01
|
||||
#define GL_SHARED_TEXTURE_PALETTE_6_KOS 0xEF02
|
||||
#define GL_SHARED_TEXTURE_PALETTE_7_KOS 0xEF03
|
||||
#define GL_SHARED_TEXTURE_PALETTE_8_KOS 0xEF04
|
||||
#define GL_SHARED_TEXTURE_PALETTE_9_KOS 0xEF05
|
||||
|
||||
#define GL_SHARED_TEXTURE_PALETTE_10_KOS 0xEF06
|
||||
#define GL_SHARED_TEXTURE_PALETTE_11_KOS 0xEF07
|
||||
#define GL_SHARED_TEXTURE_PALETTE_12_KOS 0xEF08
|
||||
#define GL_SHARED_TEXTURE_PALETTE_13_KOS 0xEF09
|
||||
#define GL_SHARED_TEXTURE_PALETTE_14_KOS 0xEF0A
|
||||
#define GL_SHARED_TEXTURE_PALETTE_15_KOS 0xEF0B
|
||||
#define GL_SHARED_TEXTURE_PALETTE_16_KOS 0xEF0C
|
||||
#define GL_SHARED_TEXTURE_PALETTE_17_KOS 0xEF0D
|
||||
#define GL_SHARED_TEXTURE_PALETTE_18_KOS 0xEF0E
|
||||
#define GL_SHARED_TEXTURE_PALETTE_19_KOS 0xEF0F
|
||||
|
||||
#define GL_SHARED_TEXTURE_PALETTE_20_KOS 0xEF10
|
||||
#define GL_SHARED_TEXTURE_PALETTE_21_KOS 0xEF11
|
||||
#define GL_SHARED_TEXTURE_PALETTE_22_KOS 0xEF12
|
||||
#define GL_SHARED_TEXTURE_PALETTE_23_KOS 0xEF13
|
||||
#define GL_SHARED_TEXTURE_PALETTE_24_KOS 0xEF14
|
||||
#define GL_SHARED_TEXTURE_PALETTE_25_KOS 0xEF15
|
||||
#define GL_SHARED_TEXTURE_PALETTE_26_KOS 0xEF16
|
||||
#define GL_SHARED_TEXTURE_PALETTE_27_KOS 0xEF17
|
||||
#define GL_SHARED_TEXTURE_PALETTE_28_KOS 0xEF18
|
||||
#define GL_SHARED_TEXTURE_PALETTE_29_KOS 0xEF19
|
||||
|
||||
#define GL_SHARED_TEXTURE_PALETTE_30_KOS 0xEF1A
|
||||
#define GL_SHARED_TEXTURE_PALETTE_31_KOS 0xEF1B
|
||||
#define GL_SHARED_TEXTURE_PALETTE_32_KOS 0xEF1C
|
||||
#define GL_SHARED_TEXTURE_PALETTE_33_KOS 0xEF1D
|
||||
#define GL_SHARED_TEXTURE_PALETTE_34_KOS 0xEF1E
|
||||
#define GL_SHARED_TEXTURE_PALETTE_35_KOS 0xEF1F
|
||||
#define GL_SHARED_TEXTURE_PALETTE_36_KOS 0xEF20
|
||||
#define GL_SHARED_TEXTURE_PALETTE_37_KOS 0xEF21
|
||||
#define GL_SHARED_TEXTURE_PALETTE_38_KOS 0xEF22
|
||||
#define GL_SHARED_TEXTURE_PALETTE_39_KOS 0xEF23
|
||||
|
||||
#define GL_SHARED_TEXTURE_PALETTE_40_KOS 0xEF24
|
||||
#define GL_SHARED_TEXTURE_PALETTE_41_KOS 0xEF25
|
||||
#define GL_SHARED_TEXTURE_PALETTE_42_KOS 0xEF26
|
||||
#define GL_SHARED_TEXTURE_PALETTE_43_KOS 0xEF27
|
||||
#define GL_SHARED_TEXTURE_PALETTE_44_KOS 0xEF28
|
||||
#define GL_SHARED_TEXTURE_PALETTE_45_KOS 0xEF29
|
||||
#define GL_SHARED_TEXTURE_PALETTE_46_KOS 0xEF2A
|
||||
#define GL_SHARED_TEXTURE_PALETTE_47_KOS 0xEF2B
|
||||
#define GL_SHARED_TEXTURE_PALETTE_48_KOS 0xEF2C
|
||||
#define GL_SHARED_TEXTURE_PALETTE_49_KOS 0xEF2D
|
||||
|
||||
#define GL_SHARED_TEXTURE_PALETTE_50_KOS 0xEF2E
|
||||
#define GL_SHARED_TEXTURE_PALETTE_51_KOS 0xEF2F
|
||||
#define GL_SHARED_TEXTURE_PALETTE_52_KOS 0xEF30
|
||||
#define GL_SHARED_TEXTURE_PALETTE_53_KOS 0xEF31
|
||||
#define GL_SHARED_TEXTURE_PALETTE_54_KOS 0xEF32
|
||||
#define GL_SHARED_TEXTURE_PALETTE_55_KOS 0xEF33
|
||||
#define GL_SHARED_TEXTURE_PALETTE_56_KOS 0xEF34
|
||||
#define GL_SHARED_TEXTURE_PALETTE_57_KOS 0xEF35
|
||||
#define GL_SHARED_TEXTURE_PALETTE_58_KOS 0xEF36
|
||||
#define GL_SHARED_TEXTURE_PALETTE_59_KOS 0xEF37
|
||||
|
||||
#define GL_SHARED_TEXTURE_PALETTE_60_KOS 0xEF38
|
||||
#define GL_SHARED_TEXTURE_PALETTE_61_KOS 0xEF39
|
||||
#define GL_SHARED_TEXTURE_PALETTE_62_KOS 0xEF3A
|
||||
#define GL_SHARED_TEXTURE_PALETTE_63_KOS 0xEF3B
|
||||
|
||||
/* Pass to glTexParameteri to set the shared bank */
|
||||
#define GL_SHARED_TEXTURE_BANK_KOS 0xEF00
|
||||
#define GL_SHARED_TEXTURE_BANK_KOS 0xEF3C
|
||||
|
||||
/* Memory allocation extension (GL_KOS_texture_memory_management) */
|
||||
GLAPI GLvoid APIENTRY glDefragmentTextureMemory_KOS(void);
|
||||
|
||||
#define GL_FREE_TEXTURE_MEMORY_KOS 0xEF01
|
||||
#define GL_USED_TEXTURE_MEMORY_KOS 0xEF02
|
||||
#define GL_FREE_CONTIGUOUS_TEXTURE_MEMORY_KOS 0xEF03
|
||||
#define GL_FREE_TEXTURE_MEMORY_KOS 0xEF3D
|
||||
#define GL_USED_TEXTURE_MEMORY_KOS 0xEF3E
|
||||
#define GL_FREE_CONTIGUOUS_TEXTURE_MEMORY_KOS 0xEF3F
|
||||
|
||||
//for palette internal format (glfcConfig)
|
||||
#define GL_RGB565_KOS 0xEF40
|
||||
|
||||
__END_DECLS
|
||||
|
||||
|
|
|
@ -24,19 +24,24 @@
|
|||
#define IMG_ALPHA_PATH "../samples/paletted_pcx/romdisk/NeHe-Alpha.pcx"
|
||||
#endif
|
||||
|
||||
/* using 4bpp textures from BMP files instead of 8bpp from PCX files */
|
||||
#define USE_16C_PALETTE
|
||||
|
||||
/* floats for x rotation, y rotation, z rotation */
|
||||
float xrot, yrot, zrot;
|
||||
|
||||
int textures[3];
|
||||
|
||||
typedef struct {
|
||||
unsigned int height;
|
||||
unsigned int width;
|
||||
unsigned int palette_width;
|
||||
uint32_t height;
|
||||
uint32_t width;
|
||||
uint32_t palette_width;
|
||||
char* palette;
|
||||
char* data;
|
||||
} Image;
|
||||
|
||||
#ifndef USE_16C_PALETTE
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
|
||||
|
@ -140,11 +145,234 @@ int LoadPalettedPCX(const char* filename, Image* image) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define BMP_BI_RGB 0L
|
||||
#define BMP_BI_UNCOMPRESSED 0L
|
||||
#define BMP_BI_RLE8 1L
|
||||
#define BMP_BI_RLE4 2L
|
||||
#define BMP_BI_BITFIELDS 3L
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
|
||||
typedef struct BITMAP_FILE_HEADER
|
||||
{
|
||||
uint16_t Type;
|
||||
uint32_t Size;
|
||||
uint16_t Reserved1;
|
||||
uint16_t Reserved2;
|
||||
uint32_t OffBits;
|
||||
} BITMAP_FILE_HEADER;
|
||||
|
||||
typedef struct BITMAP_INFO_HEADER
|
||||
{
|
||||
uint32_t Size;
|
||||
int32_t Width;
|
||||
int32_t Height;
|
||||
uint16_t Planes;
|
||||
uint16_t BitCount;
|
||||
uint32_t Compression;
|
||||
uint32_t SizeImage;
|
||||
int32_t XPelsPerMeter;
|
||||
int32_t YPelsPerMeter;
|
||||
uint32_t ClrUsed;
|
||||
uint32_t ClrImportant;
|
||||
} BITMAP_INFO_HEADER;
|
||||
|
||||
typedef struct RGB_QUAD
|
||||
{
|
||||
uint8_t Blue;
|
||||
uint8_t Green;
|
||||
uint8_t Red;
|
||||
uint8_t Reserved;
|
||||
} RGB_QUAD;
|
||||
|
||||
typedef struct BITMAP_INFO
|
||||
{
|
||||
BITMAP_INFO_HEADER Header;
|
||||
RGB_QUAD Colors[1];
|
||||
} BITMAP_INFO;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
/* some global variables used to load a 4bpp BMP file */
|
||||
static BITMAP_FILE_HEADER BmpFileHeader;
|
||||
static BITMAP_INFO_HEADER BmpInfoHeader;
|
||||
static RGB_QUAD BmpRgbQuad[256];
|
||||
static uint8_t BmpPal[256 * 3];
|
||||
|
||||
int BMP_Infos(FILE *pFile, uint32_t *width, uint32_t *height)
|
||||
{
|
||||
if (!pFile)
|
||||
return 0;
|
||||
|
||||
if (fread(&BmpFileHeader.Type, 1, 2, pFile) != 2)
|
||||
return 0;
|
||||
if (fread(&BmpFileHeader.Size, 1, 4, pFile) != 4)
|
||||
return 0;
|
||||
if (fread(&BmpFileHeader.Reserved1, 1, 2, pFile) != 2)
|
||||
return 0;
|
||||
if (fread(&BmpFileHeader.Reserved2, 1, 2, pFile) != 2)
|
||||
return 0;
|
||||
if (fread(&BmpFileHeader.OffBits, 1, 4, pFile) != 4)
|
||||
return 0;
|
||||
if (fread(&BmpInfoHeader.Size, 1, 4, pFile) != 4)
|
||||
return 0;
|
||||
if (fread(&BmpInfoHeader.Width, 1, 4, pFile) != 4)
|
||||
return 0;
|
||||
if (fread(&BmpInfoHeader.Height, 1, 4, pFile) != 4)
|
||||
return 0;
|
||||
if (fread(&BmpInfoHeader.Planes, 1, 2, pFile) != 2)
|
||||
return 0;
|
||||
if (fread(&BmpInfoHeader.BitCount, 1, 2, pFile) != 2)
|
||||
return 0;
|
||||
if (fread(&BmpInfoHeader.Compression, 1, 4, pFile) != 4)
|
||||
return 0;
|
||||
if (fread(&BmpInfoHeader.SizeImage, 1, 4, pFile) != 4)
|
||||
return 0;
|
||||
if (fread(&BmpInfoHeader.XPelsPerMeter, 1, 4, pFile) != 4)
|
||||
return 0;
|
||||
if (fread(&BmpInfoHeader.YPelsPerMeter, 1, 4, pFile) != 4)
|
||||
return 0;
|
||||
if (fread(&BmpInfoHeader.ClrUsed, 1, 4, pFile) != 4)
|
||||
return 0;
|
||||
if (fread(&BmpInfoHeader.ClrImportant, 1, 4, pFile) != 4)
|
||||
return 0;
|
||||
|
||||
*width = (uint32_t)BmpInfoHeader.Width;
|
||||
*height = (uint32_t)BmpInfoHeader.Height;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int BMP_GetPalette(FILE *pFile)
|
||||
{
|
||||
int32_t i,bitCount;
|
||||
|
||||
if (BmpInfoHeader.BitCount == 4) {
|
||||
|
||||
if (!BmpInfoHeader.ClrImportant) {
|
||||
BmpInfoHeader.ClrImportant = 16;
|
||||
}
|
||||
bitCount = BmpInfoHeader.ClrImportant * sizeof(RGB_QUAD);
|
||||
|
||||
if (fread(BmpRgbQuad, 1, bitCount, pFile) != bitCount){
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < BmpInfoHeader.ClrImportant; i++) {
|
||||
|
||||
BmpPal[i * 3] = (uint8_t)BmpRgbQuad[i].Red;
|
||||
BmpPal[i * 3 + 1] = (uint8_t)BmpRgbQuad[i].Green;
|
||||
BmpPal[i * 3 + 2] = (uint8_t)BmpRgbQuad[i].Blue;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* maybe not the best BMP loader... */
|
||||
int BMP_Depack(FILE *pFile,char *pZone)
|
||||
{
|
||||
char PadRead[4];
|
||||
int32_t i, j, Offset, PadSize, pix, c;
|
||||
|
||||
if (BmpInfoHeader.Compression != BMP_BI_RGB)
|
||||
return 0;
|
||||
|
||||
PadSize = (BmpInfoHeader.Width & 3);
|
||||
|
||||
PadSize = (4 - (BmpInfoHeader.Width & 3)) & 3;
|
||||
|
||||
for (i = BmpInfoHeader.Height - 1; (i > -1); i--) {
|
||||
Offset = i * BmpInfoHeader.Width / 2;
|
||||
|
||||
if (PadSize < 4) {
|
||||
for (j = 0; (j < BmpInfoHeader.Width / 2); j++) {
|
||||
if (!fread(&c, 1, 1, pFile)) {
|
||||
return 0;
|
||||
}
|
||||
pZone[Offset + j] = c;
|
||||
}
|
||||
}
|
||||
|
||||
if (PadSize) {
|
||||
if (fread(PadRead, PadSize, 1, pFile) != PadSize) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (i != -1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int LoadPalettedBMP(const char* filename, Image* image)
|
||||
{
|
||||
FILE *fp;
|
||||
uint32_t bytes;
|
||||
|
||||
if (filename == NULL || image == NULL) {
|
||||
printf("Invalid NULL argument\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
fp = fopen(filename, "rb");
|
||||
if (fp == NULL) {
|
||||
printf("Unable to open file\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!BMP_Infos(fp, &image->width, &image->height)) {
|
||||
printf("Error reading BMP:%s header\n",filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!BMP_GetPalette(fp)) {
|
||||
printf("Only 16c BMP are supported for this sample");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* store palette information */
|
||||
image->palette = BmpPal;
|
||||
image->palette_width = 16;
|
||||
|
||||
|
||||
bytes = sizeof(char) * image->width * image->height;
|
||||
/* 4bpp is half byte size*/
|
||||
bytes >>= 1;
|
||||
|
||||
image->data = (char*)malloc(bytes);
|
||||
if (image->data == NULL) {
|
||||
printf("Error allocating image data");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!BMP_Depack(fp, image->data)) {
|
||||
printf("Error depacking BMP:%s",filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// Load Bitmaps And Convert To Textures
|
||||
void LoadGLTextures() {
|
||||
// Load Texture
|
||||
Image image1, image2;
|
||||
|
||||
#ifndef USE_16C_PALETTE
|
||||
if(!LoadPalettedPCX(IMG_PATH, &image1)) {
|
||||
exit(1);
|
||||
}
|
||||
|
@ -152,6 +380,15 @@ void LoadGLTextures() {
|
|||
if(!LoadPalettedPCX(IMG_ALPHA_PATH, &image2)) {
|
||||
exit(1);
|
||||
}
|
||||
#else
|
||||
if (!LoadPalettedBMP("/rd/NeHe.bmp", &image1)) {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (!LoadPalettedBMP("/rd/NeHe-Alpha.bmp", &image2)) {
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
glEnable(GL_SHARED_TEXTURE_PALETTE_EXT);
|
||||
|
||||
|
@ -178,7 +415,11 @@ void LoadGLTextures() {
|
|||
|
||||
// 2d texture, level of detail 0 (normal), 3 components (red, green, blue), x size from image, y size from image,
|
||||
// border 0 (normal), rgb color data, unsigned byte data, and finally the data itself.
|
||||
#ifndef USE_16C_PALETTE
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, image1.width, image1.height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, image1.data);
|
||||
#else
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX4_EXT, image1.width, image1.height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, image1.data);
|
||||
#endif
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, textures[1]); // 2d texture (x and y size)
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR); // scale linearly when image bigger than texture
|
||||
|
@ -189,7 +430,11 @@ void LoadGLTextures() {
|
|||
|
||||
// 2d texture, level of detail 0 (normal), 3 components (red, green, blue), x size from image, y size from image,
|
||||
// border 0 (normal), rgb color data, unsigned byte data, and finally the data itself.
|
||||
#ifndef USE_16C_PALETTE
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, image1.width, image1.height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, image1.data);
|
||||
#else
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX4_EXT, image1.width, image1.height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, image1.data);
|
||||
#endif
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, textures[2]);
|
||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
|
@ -204,8 +449,11 @@ void LoadGLTextures() {
|
|||
}
|
||||
|
||||
glColorTableEXT(GL_TEXTURE_2D, GL_RGBA8, image2.palette_width, GL_RGBA, GL_UNSIGNED_BYTE, new_palette);
|
||||
|
||||
#ifndef USE_16C_PALETTE
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, image2.width, image2.height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, image2.data);
|
||||
#else
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX4_EXT, image2.width, image2.height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, image2.data);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* A general OpenGL initialization function. Sets all of the initial parameters. */
|
||||
|
|
BIN
samples/paletted_pcx/romdisk/NeHe-Alpha.bmp
Normal file
BIN
samples/paletted_pcx/romdisk/NeHe-Alpha.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
Binary file not shown.
Before Width: | Height: | Size: 192 KiB After Width: | Height: | Size: 64 KiB |
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user