Merge branch 'palette-slots' into 'master'
Palette slots Closes #28 See merge request simulant/GLdc!35
This commit is contained in:
commit
3fbb655758
10
GL/private.h
10
GL/private.h
|
@ -45,8 +45,10 @@ typedef struct {
|
||||||
/* Palette data is always stored in RAM as RGBA8888 and packed as ARGB8888
|
/* Palette data is always stored in RAM as RGBA8888 and packed as ARGB8888
|
||||||
* when uploaded to the PVR */
|
* when uploaded to the PVR */
|
||||||
GLubyte* data;
|
GLubyte* data;
|
||||||
GLushort width;
|
GLushort width; /* The user specified width */
|
||||||
|
GLushort size; /* The size of the bank (16 or 256) */
|
||||||
GLenum format;
|
GLenum format;
|
||||||
|
GLshort bank;
|
||||||
} TexturePalette;
|
} TexturePalette;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -68,6 +70,9 @@ typedef struct {
|
||||||
GLboolean isPaletted;
|
GLboolean isPaletted;
|
||||||
|
|
||||||
TexturePalette* palette;
|
TexturePalette* palette;
|
||||||
|
|
||||||
|
/* When using the shared palette, this is the bank (0-3) */
|
||||||
|
GLushort shared_bank;
|
||||||
} TextureObject;
|
} TextureObject;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -140,9 +145,10 @@ TextureObject* _glGetTexture1();
|
||||||
TextureObject* _glGetBoundTexture();
|
TextureObject* _glGetBoundTexture();
|
||||||
GLubyte _glGetActiveTexture();
|
GLubyte _glGetActiveTexture();
|
||||||
GLuint _glGetActiveClientTexture();
|
GLuint _glGetActiveClientTexture();
|
||||||
|
TexturePalette* _glGetSharedPalette(GLshort bank);
|
||||||
|
|
||||||
GLboolean _glIsSharedTexturePaletteEnabled();
|
GLboolean _glIsSharedTexturePaletteEnabled();
|
||||||
void _glApplyColorTable();
|
void _glApplyColorTable(TexturePalette *palette);
|
||||||
|
|
||||||
GLboolean _glIsBlendingEnabled();
|
GLboolean _glIsBlendingEnabled();
|
||||||
GLboolean _glIsMipmapComplete(const TextureObject* obj);
|
GLboolean _glIsMipmapComplete(const TextureObject* obj);
|
||||||
|
|
17
GL/state.c
17
GL/state.c
|
@ -214,6 +214,15 @@ void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) {
|
||||||
context->txr.height = tx1->height;
|
context->txr.height = tx1->height;
|
||||||
context->txr.base = tx1->data;
|
context->txr.base = tx1->data;
|
||||||
context->txr.format = tx1->color;
|
context->txr.format = tx1->color;
|
||||||
|
|
||||||
|
if(tx1->isPaletted) {
|
||||||
|
if(_glIsSharedTexturePaletteEnabled()) {
|
||||||
|
context->txr.format |= PVR_TXRFMT_8BPP_PAL(_glGetSharedPalette(tx1->shared_bank)->bank);
|
||||||
|
} else {
|
||||||
|
context->txr.format |= PVR_TXRFMT_8BPP_PAL((tx1->palette) ? tx1->palette->bank : 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
context->txr.env = tx1->env;
|
context->txr.env = tx1->env;
|
||||||
context->txr.uv_flip = PVR_UVFLIP_NONE;
|
context->txr.uv_flip = PVR_UVFLIP_NONE;
|
||||||
context->txr.uv_clamp = tx1->uv_clamp;
|
context->txr.uv_clamp = tx1->uv_clamp;
|
||||||
|
@ -300,9 +309,6 @@ GLAPI void APIENTRY glEnable(GLenum cap) {
|
||||||
break;
|
break;
|
||||||
case GL_SHARED_TEXTURE_PALETTE_EXT: {
|
case GL_SHARED_TEXTURE_PALETTE_EXT: {
|
||||||
SHARED_PALETTE_ENABLED = GL_TRUE;
|
SHARED_PALETTE_ENABLED = GL_TRUE;
|
||||||
|
|
||||||
/* Apply the texture palette if necessary */
|
|
||||||
_glApplyColorTable();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GL_LIGHT0:
|
case GL_LIGHT0:
|
||||||
|
@ -354,9 +360,6 @@ GLAPI void APIENTRY glDisable(GLenum cap) {
|
||||||
break;
|
break;
|
||||||
case GL_SHARED_TEXTURE_PALETTE_EXT: {
|
case GL_SHARED_TEXTURE_PALETTE_EXT: {
|
||||||
SHARED_PALETTE_ENABLED = GL_FALSE;
|
SHARED_PALETTE_ENABLED = GL_FALSE;
|
||||||
|
|
||||||
/* Restore whatever palette may exist on a bound texture */
|
|
||||||
_glApplyColorTable();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GL_LIGHT0:
|
case GL_LIGHT0:
|
||||||
|
@ -634,7 +637,7 @@ const GLbyte *glGetString(GLenum name) {
|
||||||
return "GLdc 1.x";
|
return "GLdc 1.x";
|
||||||
|
|
||||||
case GL_EXTENSIONS:
|
case GL_EXTENSIONS:
|
||||||
return "GL_ARB_framebuffer_object, GL_ARB_multitexture, GL_ARB_texture_rg, GL_EXT_paletted_texture, GL_EXT_shared_texture_palette";
|
return "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";
|
||||||
}
|
}
|
||||||
|
|
||||||
return "GL_KOS_ERROR: ENUM Unsupported\n";
|
return "GL_KOS_ERROR: ENUM Unsupported\n";
|
||||||
|
|
185
GL/texture.c
185
GL/texture.c
|
@ -18,58 +18,105 @@ static TextureObject* TEXTURE_UNITS[MAX_TEXTURE_UNITS] = {NULL, NULL};
|
||||||
static NamedArray TEXTURE_OBJECTS;
|
static NamedArray TEXTURE_OBJECTS;
|
||||||
static GLubyte ACTIVE_TEXTURE = 0;
|
static GLubyte ACTIVE_TEXTURE = 0;
|
||||||
|
|
||||||
static TexturePalette* SHARED_PALETTE = NULL;
|
static TexturePalette* SHARED_PALETTES[4] = {NULL, NULL, NULL, NULL};
|
||||||
|
|
||||||
static GLuint _determinePVRFormat(GLint internalFormat, GLenum type);
|
static GLuint _determinePVRFormat(GLint internalFormat, GLenum type);
|
||||||
|
|
||||||
#define PACK_ARGB8888(a,r,g,b) ( ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF) )
|
#define PACK_ARGB8888(a,r,g,b) ( ((a & 0xFF) << 24) | ((r & 0xFF) << 16) | ((g & 0xFF) << 8) | (b & 0xFF) )
|
||||||
|
|
||||||
static TexturePalette* last_bound_palette = NULL;
|
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
|
||||||
|
|
||||||
void _glApplyColorTable() {
|
|
||||||
|
static TexturePalette* _initTexturePalette() {
|
||||||
|
TexturePalette* palette = (TexturePalette*) malloc(sizeof(TexturePalette));
|
||||||
|
assert(palette);
|
||||||
|
|
||||||
|
palette->data = NULL;
|
||||||
|
palette->format = 0;
|
||||||
|
palette->width = 0;
|
||||||
|
palette->bank = -1;
|
||||||
|
palette->size = 0;
|
||||||
|
return palette;
|
||||||
|
}
|
||||||
|
|
||||||
|
static GLshort _glGenPaletteSlot(GLushort size) {
|
||||||
|
GLushort i, j;
|
||||||
|
|
||||||
|
assert(size == 16 || size == 256);
|
||||||
|
|
||||||
|
if(size == 16) {
|
||||||
|
for(i = 0; i < 4; ++i) {
|
||||||
|
for(j = 0; j < 16; ++j) {
|
||||||
|
if(!SUBBANKS_USED[i][j]) {
|
||||||
|
BANKS_USED[i] = GL_TRUE;
|
||||||
|
SUBBANKS_USED[i][j] = GL_TRUE;
|
||||||
|
return (i * 16) + j;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for(i = 0; i < 4; ++i) {
|
||||||
|
if(!BANKS_USED[i]) {
|
||||||
|
BANKS_USED[i] = GL_TRUE;
|
||||||
|
for(j = 0; j < 16; ++j) {
|
||||||
|
SUBBANKS_USED[i][j] = GL_TRUE;
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "GL ERROR: No palette slots remain\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _glReleasePaletteSlot(GLshort slot, GLushort size) {
|
||||||
|
GLushort i;
|
||||||
|
|
||||||
|
assert(size == 16 || size == 256);
|
||||||
|
if(size == 16) {
|
||||||
|
GLushort bank = slot / 4;
|
||||||
|
GLushort subbank = slot % 4;
|
||||||
|
|
||||||
|
SUBBANKS_USED[bank][subbank] = GL_FALSE;
|
||||||
|
for(i = 0; i < 16; ++i) {
|
||||||
|
if(SUBBANKS_USED[bank][i]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BANKS_USED[bank] = GL_FALSE;
|
||||||
|
} else {
|
||||||
|
BANKS_USED[slot] = GL_FALSE;
|
||||||
|
for(i = 0; i < 16; ++i) {
|
||||||
|
SUBBANKS_USED[slot][i] = GL_FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TexturePalette* _glGetSharedPalette(GLshort bank) {
|
||||||
|
assert(bank >= 0 && bank < 4);
|
||||||
|
return SHARED_PALETTES[bank];
|
||||||
|
}
|
||||||
|
|
||||||
|
void _glApplyColorTable(TexturePalette* src) {
|
||||||
/*
|
/*
|
||||||
* FIXME:
|
* FIXME:
|
||||||
*
|
*
|
||||||
* - Different palette formats (GL_RGB -> PVR_PAL_RGB565)
|
* - Different palette formats (GL_RGB -> PVR_PAL_RGB565)
|
||||||
*/
|
*/
|
||||||
TexturePalette* src = NULL;
|
if(!src || !src->data) {
|
||||||
|
|
||||||
if(_glIsSharedTexturePaletteEnabled()) {
|
|
||||||
src = SHARED_PALETTE;
|
|
||||||
|
|
||||||
assert(src);
|
|
||||||
|
|
||||||
/* Don't apply a palette if we haven't uploaded one yet */
|
|
||||||
if(!src->data) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
TextureObject* active = _glGetBoundTexture();
|
|
||||||
|
|
||||||
if(!active) {
|
|
||||||
return; //? Unload the palette? Make White?
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!active->palette || !active->palette->data) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
src = active->palette;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Don't reapply the palette if it was the last one we applied */
|
|
||||||
if(src == last_bound_palette) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
last_bound_palette = src;
|
|
||||||
|
|
||||||
pvr_set_pal_format(PVR_PAL_ARGB8888);
|
pvr_set_pal_format(PVR_PAL_ARGB8888);
|
||||||
|
|
||||||
GLushort i = 0;
|
GLushort i;
|
||||||
for(; i < src->width; ++i) {
|
GLushort offset = src->size * src->bank;
|
||||||
|
for(i = 0; i < src->width; ++i) {
|
||||||
GLubyte* entry = &src->data[i * 4];
|
GLubyte* entry = &src->data[i * 4];
|
||||||
pvr_set_pal_entry(i, PACK_ARGB8888(entry[3], entry[0], entry[1], entry[2]));
|
pvr_set_pal_entry(offset + i, PACK_ARGB8888(entry[3], entry[0], entry[1], entry[2]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,10 +200,11 @@ GLubyte _glInitTextures() {
|
||||||
// Reserve zero so that it is never given to anyone as an ID!
|
// Reserve zero so that it is never given to anyone as an ID!
|
||||||
named_array_reserve(&TEXTURE_OBJECTS, 0);
|
named_array_reserve(&TEXTURE_OBJECTS, 0);
|
||||||
|
|
||||||
SHARED_PALETTE = (TexturePalette*) malloc(sizeof(TexturePalette));
|
SHARED_PALETTES[0] = _initTexturePalette();
|
||||||
SHARED_PALETTE->data = NULL;
|
SHARED_PALETTES[1] = _initTexturePalette();
|
||||||
SHARED_PALETTE->format = 0;
|
SHARED_PALETTES[2] = _initTexturePalette();
|
||||||
SHARED_PALETTE->width = 0;
|
SHARED_PALETTES[3] = _initTexturePalette();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,6 +251,9 @@ static void _glInitializeTextureObject(TextureObject* txr, unsigned int id) {
|
||||||
txr->palette = NULL;
|
txr->palette = NULL;
|
||||||
txr->isCompressed = GL_FALSE;
|
txr->isCompressed = GL_FALSE;
|
||||||
txr->isPaletted = GL_FALSE;
|
txr->isPaletted = GL_FALSE;
|
||||||
|
|
||||||
|
/* Always default to the first shared bank */
|
||||||
|
txr->shared_bank = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void APIENTRY glGenTextures(GLsizei n, GLuint *textures) {
|
void APIENTRY glGenTextures(GLsizei n, GLuint *textures) {
|
||||||
|
@ -272,9 +323,6 @@ void APIENTRY glBindTexture(GLenum target, GLuint texture) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TEXTURE_UNITS[ACTIVE_TEXTURE] = (TextureObject*) named_array_get(&TEXTURE_OBJECTS, texture);
|
TEXTURE_UNITS[ACTIVE_TEXTURE] = (TextureObject*) named_array_get(&TEXTURE_OBJECTS, texture);
|
||||||
|
|
||||||
/* Apply the texture palette if necessary */
|
|
||||||
_glApplyColorTable();
|
|
||||||
} else {
|
} else {
|
||||||
TEXTURE_UNITS[ACTIVE_TEXTURE] = NULL;
|
TEXTURE_UNITS[ACTIVE_TEXTURE] = NULL;
|
||||||
}
|
}
|
||||||
|
@ -1000,6 +1048,11 @@ void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case GL_SHARED_TEXTURE_BANK_KOS:
|
||||||
|
active->shared_bank = param;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1010,7 +1063,16 @@ void APIENTRY glTexParameterf(GLenum target, GLenum pname, GLint param) {
|
||||||
}
|
}
|
||||||
|
|
||||||
GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *data) {
|
GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *data) {
|
||||||
GLenum validTargets[] = {GL_TEXTURE_2D, GL_SHARED_TEXTURE_PALETTE_EXT, 0};
|
GLenum 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
|
||||||
|
};
|
||||||
|
|
||||||
GLenum validInternalFormats[] = {GL_RGB8, GL_RGBA8, 0};
|
GLenum validInternalFormats[] = {GL_RGB8, GL_RGBA8, 0};
|
||||||
GLenum validFormats[] = {GL_RGB, GL_RGBA, 0};
|
GLenum validFormats[] = {GL_RGB, GL_RGBA, 0};
|
||||||
GLenum validTypes[] = {GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, 0};
|
GLenum validTypes[] = {GL_UNSIGNED_BYTE, GL_BYTE, GL_UNSIGNED_SHORT, GL_SHORT, 0};
|
||||||
|
@ -1056,12 +1118,19 @@ GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsize
|
||||||
|
|
||||||
TexturePalette* palette = NULL;
|
TexturePalette* palette = NULL;
|
||||||
|
|
||||||
if(target == GL_SHARED_TEXTURE_PALETTE_EXT) {
|
/* Custom extension - allow uploading to one of 4 custom palettes */
|
||||||
palette = SHARED_PALETTE;
|
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 {
|
} else {
|
||||||
TextureObject* active = _glGetBoundTexture();
|
TextureObject* active = _glGetBoundTexture();
|
||||||
if(!active->palette) {
|
if(!active->palette) {
|
||||||
active->palette = (TexturePalette*) malloc(sizeof(TexturePalette));
|
active->palette = _initTexturePalette();
|
||||||
}
|
}
|
||||||
|
|
||||||
palette = active->palette;
|
palette = active->palette;
|
||||||
|
@ -1074,9 +1143,28 @@ GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsize
|
||||||
palette->data = NULL;
|
palette->data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(palette->bank > -1) {
|
||||||
|
_glReleasePaletteSlot(palette->bank, palette->size);
|
||||||
|
palette->bank = -1;
|
||||||
|
}
|
||||||
|
|
||||||
palette->data = (GLubyte*) malloc(width * 4);
|
palette->data = (GLubyte*) malloc(width * 4);
|
||||||
palette->format = format;
|
palette->format = format;
|
||||||
palette->width = width;
|
palette->width = width;
|
||||||
|
palette->size = (width > 16) ? 256 : 16;
|
||||||
|
assert(palette->size == 16 || palette->size == 256);
|
||||||
|
|
||||||
|
palette->bank = _glGenPaletteSlot(palette->size);
|
||||||
|
|
||||||
|
if(palette->bank < 0) {
|
||||||
|
/* We ran out of slots! */
|
||||||
|
_glKosThrowError(GL_INVALID_OPERATION, __func__);
|
||||||
|
_glKosPrintError();
|
||||||
|
|
||||||
|
free(palette->data);
|
||||||
|
palette->format = palette->width = palette->size = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
GLubyte* src = (GLubyte*) data;
|
GLubyte* src = (GLubyte*) data;
|
||||||
GLubyte* dst = (GLubyte*) palette->data;
|
GLubyte* dst = (GLubyte*) palette->data;
|
||||||
|
@ -1093,10 +1181,7 @@ GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsize
|
||||||
dst += 4;
|
dst += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_glApplyColorTable(palette);
|
||||||
/* Colour table might have changed the active palette, so wipe last_bound_palette before reapplying */
|
|
||||||
last_bound_palette = NULL;
|
|
||||||
_glApplyColorTable();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLAPI void APIENTRY glColorSubTableEXT(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data) {
|
GLAPI void APIENTRY glColorSubTableEXT(GLenum target, GLsizei start, GLsizei count, GLenum format, GLenum type, const GLvoid *data) {
|
||||||
|
|
|
@ -38,6 +38,32 @@ __BEGIN_DECLS
|
||||||
GLAPI void APIENTRY glKosSwapBuffers();
|
GLAPI void APIENTRY glKosSwapBuffers();
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* CUSTOM EXTENSION multiple_shared_palette_KOS
|
||||||
|
*
|
||||||
|
* This extension allows using up to 4 different shared palettes
|
||||||
|
* with ColorTableEXT. The following constants are provided
|
||||||
|
* to use as targets for ColorTableExt:
|
||||||
|
*
|
||||||
|
* - SHARED_TEXTURE_PALETTE_0_KOS
|
||||||
|
* - SHARED_TEXTURE_PALETTE_1_KOS
|
||||||
|
* - SHARED_TEXTURE_PALETTE_2_KOS
|
||||||
|
* - SHARED_TEXTURE_PALETTE_3_KOS
|
||||||
|
*
|
||||||
|
* In this use case SHARED_TEXTURE_PALETTE_0_KOS is interchangable with SHARED_TEXTURE_PALETTE_EXT
|
||||||
|
* (both refer to the first shared palette).
|
||||||
|
*
|
||||||
|
* To select which palette a texture uses, a new pname is accepted by TexParameteri: SHARED_TEXTURE_BANK_KOS
|
||||||
|
* 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
|
||||||
|
|
||||||
|
/* Pass to glTexParameteri to set the shared bank */
|
||||||
|
#define GL_SHARED_TEXTURE_BANK_KOS 0xEF00
|
||||||
|
|
||||||
__END_DECLS
|
__END_DECLS
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,8 @@ KOS_INIT_ROMDISK(romdisk);
|
||||||
|
|
||||||
/* floats for x rotation, y rotation, z rotation */
|
/* floats for x rotation, y rotation, z rotation */
|
||||||
float xrot, yrot, zrot;
|
float xrot, yrot, zrot;
|
||||||
/* storage for one texture */
|
|
||||||
int texture[1];
|
int textures[2];
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned int height;
|
unsigned int height;
|
||||||
|
@ -131,32 +131,50 @@ int LoadPalettedPCX(const char* filename, Image* image) {
|
||||||
// Load Bitmaps And Convert To Textures
|
// Load Bitmaps And Convert To Textures
|
||||||
void LoadGLTextures() {
|
void LoadGLTextures() {
|
||||||
// Load Texture
|
// Load Texture
|
||||||
Image *image1;
|
Image image1;
|
||||||
|
|
||||||
// allocate space for texture
|
if (!LoadPalettedPCX("/rd/NeHe.pcx", &image1)) {
|
||||||
image1 = (Image *) malloc(sizeof(Image));
|
|
||||||
if (image1 == NULL) {
|
|
||||||
printf("Error allocating space for image");
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!LoadPalettedPCX("/rd/NeHe.pcx", image1)) {
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
glEnable(GL_SHARED_TEXTURE_PALETTE_EXT);
|
glEnable(GL_SHARED_TEXTURE_PALETTE_EXT);
|
||||||
glColorTableEXT(GL_SHARED_TEXTURE_PALETTE_EXT, GL_RGBA8, image1->palette_width, GL_RGB, GL_UNSIGNED_BYTE, image1->palette);
|
|
||||||
|
/* First palette */
|
||||||
|
glColorTableEXT(GL_SHARED_TEXTURE_PALETTE_EXT, GL_RGBA8, image1.palette_width, GL_RGB, GL_UNSIGNED_BYTE, image1.palette);
|
||||||
|
|
||||||
|
char* inversed_palette = (char*) malloc(sizeof(char) * image1.palette_width * 3);
|
||||||
|
GLuint i;
|
||||||
|
for(i = 0; i < image1.palette_width; i++) {
|
||||||
|
/* Swap red and green */
|
||||||
|
inversed_palette[i * 3] = image1.palette[(i * 3) + 1];
|
||||||
|
inversed_palette[(i * 3) + 1] = image1.palette[(i * 3)];
|
||||||
|
inversed_palette[(i * 3) + 2] = image1.palette[(i * 3) + 2];
|
||||||
|
}
|
||||||
|
|
||||||
|
glColorTableEXT(GL_SHARED_TEXTURE_PALETTE_1_KOS, GL_RGBA8, image1.palette_width, GL_RGB, GL_UNSIGNED_BYTE, inversed_palette);
|
||||||
|
|
||||||
// Create Texture
|
// Create Texture
|
||||||
glGenTextures(1, &texture[0]);
|
glGenTextures(2, textures);
|
||||||
glBindTexture(GL_TEXTURE_2D, texture[0]); // 2d texture (x and y size)
|
glBindTexture(GL_TEXTURE_2D, textures[0]); // 2d texture (x and y size)
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR); // scale linearly when image bigger than texture
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER, GL_LINEAR); // scale linearly when image bigger than texture
|
||||||
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR); // scale linearly when image smalled than texture
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR); // scale linearly when image smalled than texture
|
||||||
|
|
||||||
// 2d texture, level of detail 0 (normal), 3 components (red, green, blue), x size from image, y size from image,
|
// 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.
|
// border 0 (normal), rgb color data, unsigned byte data, and finally the data itself.
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, image1->width, image1->height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, image1->data);
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, image1.width, image1.height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, image1.data);
|
||||||
|
|
||||||
|
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
|
||||||
|
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER, GL_LINEAR); // scale linearly when image smalled than texture
|
||||||
|
|
||||||
|
/* Texture-specific palette! */
|
||||||
|
glColorTableEXT(GL_TEXTURE_2D, GL_RGBA8, image1.palette_width, GL_RGB, GL_UNSIGNED_BYTE, inversed_palette);
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_COLOR_INDEX8_EXT, image1.width, image1.height, 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE, image1.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* A general OpenGL initialization function. Sets all of the initial parameters. */
|
/* A general OpenGL initialization function. Sets all of the initial parameters. */
|
||||||
|
@ -193,21 +211,7 @@ void ReSizeGLScene(int Width, int Height)
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DrawPolygon() {
|
||||||
/* The main drawing function. */
|
|
||||||
void DrawGLScene()
|
|
||||||
{
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
|
|
||||||
glLoadIdentity(); // Reset The View
|
|
||||||
|
|
||||||
glTranslatef(0.0f,0.0f,-5.0f); // move 5 units into the screen.
|
|
||||||
|
|
||||||
glRotatef(xrot,1.0f,0.0f,0.0f); // Rotate On The X Axis
|
|
||||||
glRotatef(yrot,0.0f,1.0f,0.0f); // Rotate On The Y Axis
|
|
||||||
glRotatef(zrot,0.0f,0.0f,1.0f); // Rotate On The Z Axis
|
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, texture[0]); // choose the texture to use.
|
|
||||||
|
|
||||||
glBegin(GL_QUADS); // begin drawing a cube
|
glBegin(GL_QUADS); // begin drawing a cube
|
||||||
|
|
||||||
// Front Face (note that the texture's corners have to match the quad's corners)
|
// Front Face (note that the texture's corners have to match the quad's corners)
|
||||||
|
@ -247,6 +251,37 @@ void DrawGLScene()
|
||||||
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
|
glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); // Top Left Of The Texture and Quad
|
||||||
|
|
||||||
glEnd(); // done with the polygon.
|
glEnd(); // done with the polygon.
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The main drawing function. */
|
||||||
|
void DrawGLScene()
|
||||||
|
{
|
||||||
|
static GLuint switch_counter = 0;
|
||||||
|
static GLuint current_bank = 0;
|
||||||
|
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear The Screen And The Depth Buffer
|
||||||
|
glLoadIdentity(); // Reset The View
|
||||||
|
|
||||||
|
glTranslatef(-1.5f,0.0f,-5.0f); // move 5 units into the screen.
|
||||||
|
|
||||||
|
glPushMatrix();
|
||||||
|
glRotatef(xrot,1.0f,0.0f,0.0f); // Rotate On The X Axis
|
||||||
|
glRotatef(yrot,0.0f,1.0f,0.0f); // Rotate On The Y Axis
|
||||||
|
glRotatef(zrot,0.0f,0.0f,1.0f); // Rotate On The Z Axis
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textures[0]); // choose the texture to use.
|
||||||
|
|
||||||
|
if(switch_counter++ > 200) {
|
||||||
|
switch_counter = 0;
|
||||||
|
current_bank = !current_bank;
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_SHARED_TEXTURE_BANK_KOS, current_bank);
|
||||||
|
}
|
||||||
|
|
||||||
|
DrawPolygon();
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
glBindTexture(GL_TEXTURE_2D, textures[1]);
|
||||||
|
glTranslatef(3.0, 0, 0);
|
||||||
|
DrawPolygon();
|
||||||
|
|
||||||
xrot+=1.5f; // X Axis Rotation
|
xrot+=1.5f; // X Axis Rotation
|
||||||
yrot+=1.5f; // Y Axis Rotation
|
yrot+=1.5f; // Y Axis Rotation
|
||||||
|
|
Loading…
Reference in New Issue
Block a user