IGNORE: Merge OVER my own codebase.
This commit is contained in:
parent
5eea65c31f
commit
06ac73d82f
25
GL/clip.c
25
GL/clip.c
|
@ -152,6 +152,15 @@ static inline void markDead(ClipVertex* vert) {
|
||||||
vert->flags = VERTEX_CMD_EOL;
|
vert->flags = VERTEX_CMD_EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define B000 0
|
||||||
|
#define B111 7
|
||||||
|
#define B100 4
|
||||||
|
#define B010 2
|
||||||
|
#define B001 1
|
||||||
|
#define B101 5
|
||||||
|
#define B011 3
|
||||||
|
#define B110 6
|
||||||
|
|
||||||
void clipTriangleStrip2(AlignedVector* vertices, uint32_t offset, uint8_t fladeShade) {
|
void clipTriangleStrip2(AlignedVector* vertices, uint32_t offset, uint8_t fladeShade) {
|
||||||
/* Room for clipping 16 triangles */
|
/* Room for clipping 16 triangles */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -195,11 +204,11 @@ void clipTriangleStrip2(AlignedVector* vertices, uint32_t offset, uint8_t fladeS
|
||||||
uint8_t visible = ((v1->w > 0) ? 4 : 0) | ((v2->w > 0) ? 2 : 0) | ((v3->w > 0) ? 1 : 0);
|
uint8_t visible = ((v1->w > 0) ? 4 : 0) | ((v2->w > 0) ? 2 : 0) | ((v3->w > 0) ? 1 : 0);
|
||||||
|
|
||||||
switch(visible) {
|
switch(visible) {
|
||||||
case 0b111:
|
case B111:
|
||||||
/* All visible? Do nothing */
|
/* All visible? Do nothing */
|
||||||
continue;
|
continue;
|
||||||
break;
|
break;
|
||||||
case 0b000:
|
case B000:
|
||||||
/*
|
/*
|
||||||
It is not possible that this is any trangle except the first
|
It is not possible that this is any trangle except the first
|
||||||
in a strip. That's because:
|
in a strip. That's because:
|
||||||
|
@ -234,12 +243,12 @@ void clipTriangleStrip2(AlignedVector* vertices, uint32_t offset, uint8_t fladeS
|
||||||
v3->flags = VERTEX_CMD;
|
v3->flags = VERTEX_CMD;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0b100:
|
case B100:
|
||||||
case 0b010:
|
case B010:
|
||||||
case 0b001:
|
case B001:
|
||||||
case 0b101:
|
case B101:
|
||||||
case 0b011:
|
case B011:
|
||||||
case 0b110:
|
case B110:
|
||||||
/* Store the triangle for clipping */
|
/* Store the triangle for clipping */
|
||||||
TO_CLIP[CLIP_COUNT].vertex[0] = *v1;
|
TO_CLIP[CLIP_COUNT].vertex[0] = *v1;
|
||||||
TO_CLIP[CLIP_COUNT].vertex[1] = *v2;
|
TO_CLIP[CLIP_COUNT].vertex[1] = *v2;
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
#define CONFIG_H
|
#define CONFIG_H
|
||||||
|
|
||||||
|
|
||||||
#define MAX_TEXTURE_COUNT 1088 //@Todo: or 1088 explain why increased. mrneo240
|
/* This figure is derived from the needs of Quake 1 */
|
||||||
|
#define MAX_TEXTURE_COUNT 1088
|
||||||
|
|
||||||
|
|
||||||
#endif // CONFIG_H
|
#endif // CONFIG_H
|
||||||
|
|
42
GL/draw.c
42
GL/draw.c
|
@ -3,6 +3,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
#include "../include/gl.h"
|
#include "../include/gl.h"
|
||||||
#include "../include/glext.h"
|
#include "../include/glext.h"
|
||||||
|
@ -449,8 +450,8 @@ static inline PolyBuildFunc _calcBuildFunc(const GLenum type) {
|
||||||
case GL_QUADS:
|
case GL_QUADS:
|
||||||
return &_buildQuad;
|
return &_buildQuad;
|
||||||
break;
|
break;
|
||||||
case GL_POLYGON:
|
|
||||||
case GL_TRIANGLE_FAN:
|
case GL_TRIANGLE_FAN:
|
||||||
|
case GL_POLYGON:
|
||||||
return &_buildTriangleFan;
|
return &_buildTriangleFan;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -459,7 +460,7 @@ static inline PolyBuildFunc _calcBuildFunc(const GLenum type) {
|
||||||
|
|
||||||
return &_buildStrip;
|
return &_buildStrip;
|
||||||
}
|
}
|
||||||
#include <assert.h>
|
|
||||||
static inline void nullFloatParseFunc(GLfloat* out, const GLubyte* in) {}
|
static inline void nullFloatParseFunc(GLfloat* out, const GLubyte* in) {}
|
||||||
|
|
||||||
static inline void genElementsCommon(
|
static inline void genElementsCommon(
|
||||||
|
@ -480,8 +481,13 @@ static inline void genElementsCommon(
|
||||||
const FloatParseFunc normalFunc = (doLighting) ? _calcNormalParseFunc() : &nullFloatParseFunc;
|
const FloatParseFunc normalFunc = (doLighting) ? _calcNormalParseFunc() : &nullFloatParseFunc;
|
||||||
|
|
||||||
const IndexParseFunc indexFunc = _calcParseIndexFunc(type);
|
const IndexParseFunc indexFunc = _calcParseIndexFunc(type);
|
||||||
|
|
||||||
assert(vertexFunc);
|
assert(vertexFunc);
|
||||||
assert(diffuseFunc);
|
assert(diffuseFunc);
|
||||||
|
assert(uvFunc);
|
||||||
|
assert(stFunc);
|
||||||
|
assert(normalFunc);
|
||||||
|
assert(indexFunc);
|
||||||
|
|
||||||
GLsizei i = 0;
|
GLsizei i = 0;
|
||||||
const GLubyte* idx = iptr;
|
const GLubyte* idx = iptr;
|
||||||
|
@ -548,7 +554,6 @@ static inline void genElementsQuads(
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void genElementsTriangleFan(
|
static inline void genElementsTriangleFan(
|
||||||
|
|
||||||
ClipVertex* output,
|
ClipVertex* output,
|
||||||
GLsizei count,
|
GLsizei count,
|
||||||
const GLubyte* iptr, GLuint istride, GLenum type,
|
const GLubyte* iptr, GLuint istride, GLenum type,
|
||||||
|
@ -625,6 +630,12 @@ static inline void genArraysCommon(
|
||||||
const FloatParseFunc stFunc = _calcSTParseFunc();
|
const FloatParseFunc stFunc = _calcSTParseFunc();
|
||||||
const FloatParseFunc normalFunc = _calcNormalParseFunc();
|
const FloatParseFunc normalFunc = _calcNormalParseFunc();
|
||||||
|
|
||||||
|
assert(vertexFunc);
|
||||||
|
assert(diffuseFunc);
|
||||||
|
assert(uvFunc);
|
||||||
|
assert(stFunc);
|
||||||
|
assert(normalFunc);
|
||||||
|
|
||||||
GLsizei i = count;
|
GLsizei i = count;
|
||||||
|
|
||||||
ClipVertex* vertex = output;
|
ClipVertex* vertex = output;
|
||||||
|
@ -745,6 +756,7 @@ static void genArraysTriangleStrip(
|
||||||
output[count - 1].flags = PVR_CMD_VERTEX_EOL;
|
output[count - 1].flags = PVR_CMD_VERTEX_EOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MAX_POLYGON_SIZE 32
|
||||||
static ClipVertex buffer[MAX_POLYGON_SIZE];
|
static ClipVertex buffer[MAX_POLYGON_SIZE];
|
||||||
|
|
||||||
static void genArraysTriangleFan(
|
static void genArraysTriangleFan(
|
||||||
|
@ -757,17 +769,14 @@ static void genArraysTriangleFan(
|
||||||
const GLubyte* nptr, GLuint nstride,
|
const GLubyte* nptr, GLuint nstride,
|
||||||
GLboolean doTexture, GLboolean doMultitexture, GLboolean doLighting) {
|
GLboolean doTexture, GLboolean doMultitexture, GLboolean doLighting) {
|
||||||
|
|
||||||
|
assert(count < MAX_POLYGON_SIZE);
|
||||||
|
|
||||||
genArraysCommon(
|
genArraysCommon(
|
||||||
output, count,
|
output, count,
|
||||||
vptr, vstride, cptr, cstride, uvptr, uvstride, stptr, ststride, nptr, nstride,
|
vptr, vstride, cptr, cstride, uvptr, uvstride, stptr, ststride, nptr, nstride,
|
||||||
doTexture, doMultitexture, doLighting
|
doTexture, doMultitexture, doLighting
|
||||||
);
|
);
|
||||||
|
|
||||||
#if TRACE_ENABLED
|
|
||||||
printf("%s(%s[%d]): count: %d\n",__func__, __FILE__,__LINE__, count);
|
|
||||||
#endif
|
|
||||||
assert(count <= MAX_POLYGON_SIZE);
|
|
||||||
|
|
||||||
if(count <= 3){
|
if(count <= 3){
|
||||||
swapVertex(&output[1], &output[2]);
|
swapVertex(&output[1], &output[2]);
|
||||||
output[2].flags = PVR_CMD_VERTEX_EOL;
|
output[2].flags = PVR_CMD_VERTEX_EOL;
|
||||||
|
@ -777,28 +786,15 @@ static void genArraysTriangleFan(
|
||||||
memcpy(buffer, output, sizeof(ClipVertex) * count);
|
memcpy(buffer, output, sizeof(ClipVertex) * count);
|
||||||
|
|
||||||
// First 3 vertices are in the right place, just end early
|
// First 3 vertices are in the right place, just end early
|
||||||
//swapVertex(&output[1], &output[2]);
|
|
||||||
output[2].flags = PVR_CMD_VERTEX_EOL;
|
output[2].flags = PVR_CMD_VERTEX_EOL;
|
||||||
|
|
||||||
GLsizei i = 3, target = 3;
|
GLsizei i = 3, target = 3;
|
||||||
ClipVertex* first = &output[0];
|
ClipVertex* first = &output[0];
|
||||||
#if TRACE_ENABLED
|
|
||||||
printf("%s(%s[%d]): Triangle!\n",__func__, __FILE__,__LINE__);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for(; i < count; ++i) {
|
for(; i < count; ++i) {
|
||||||
output[target++] = *first;
|
output[target++] = *first;
|
||||||
output[target++] = buffer[i - 1];
|
output[target++] = buffer[i - 1];
|
||||||
output[target] = buffer[i];
|
output[target] = buffer[i];
|
||||||
#if TRACE_ENABLED
|
|
||||||
printf("%s(%s[%d]): Triangle!\n",__func__, __FILE__,__LINE__);
|
|
||||||
printf("%s(%s[%d]):\tvert(%f,%f,%f)\n",__func__, __FILE__,__LINE__,
|
|
||||||
(*first).xyz[0],(*first).xyz[1],(*first).xyz[2]);
|
|
||||||
printf("%s(%s[%d]):\tvert(%f,%f,%f)\n",__func__, __FILE__,__LINE__,
|
|
||||||
(buffer[i - 1]).xyz[0],(buffer[i - 1]).xyz[1],(buffer[i - 1]).xyz[2]);
|
|
||||||
printf("%s(%s[%d]):\tvert(%f,%f,%f)\n",__func__, __FILE__,__LINE__,
|
|
||||||
(buffer[i]).xyz[0],(buffer[i]).xyz[1],(buffer[i]).xyz[2]);
|
|
||||||
#endif
|
|
||||||
output[target++].flags = PVR_CMD_VERTEX_EOL;
|
output[target++].flags = PVR_CMD_VERTEX_EOL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1085,7 +1081,6 @@ static void push(PVRHeader* header, ClipVertex* output, const GLsizei count, Pol
|
||||||
#define DEBUG_CLIPPING 0
|
#define DEBUG_CLIPPING 0
|
||||||
|
|
||||||
static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum type, const GLvoid* indices) {
|
static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum type, const GLvoid* indices) {
|
||||||
TRACE();
|
|
||||||
/* Do nothing if vertices aren't enabled */
|
/* Do nothing if vertices aren't enabled */
|
||||||
if(!(ENABLED_VERTEX_ATTRIBUTES & VERTEX_ENABLED_FLAG)) {
|
if(!(ENABLED_VERTEX_ATTRIBUTES & VERTEX_ENABLED_FLAG)) {
|
||||||
return;
|
return;
|
||||||
|
@ -1317,8 +1312,7 @@ GLuint _glGetActiveClientTexture() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void APIENTRY glClientActiveTextureARB(GLenum texture) {
|
void APIENTRY glClientActiveTextureARB(GLenum texture) {
|
||||||
//@TODO: Uncomment
|
TRACE();
|
||||||
//TRACE();
|
|
||||||
|
|
||||||
if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS) {
|
if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS) {
|
||||||
_glKosThrowError(GL_INVALID_ENUM, __func__);
|
_glKosThrowError(GL_INVALID_ENUM, __func__);
|
||||||
|
|
24
GL/flush.c
24
GL/flush.c
|
@ -55,6 +55,8 @@ static void _glInitPVR() {
|
||||||
PolyList* _glActivePolyList() {
|
PolyList* _glActivePolyList() {
|
||||||
if(_glIsBlendingEnabled()) {
|
if(_glIsBlendingEnabled()) {
|
||||||
return &TR_LIST;
|
return &TR_LIST;
|
||||||
|
} else if(_glIsAlphaTestEnabled()) {
|
||||||
|
return &PT_LIST;
|
||||||
} else {
|
} else {
|
||||||
return &OP_LIST;
|
return &OP_LIST;
|
||||||
}
|
}
|
||||||
|
@ -64,6 +66,15 @@ PolyList *_glTransparentPolyList() {
|
||||||
return &TR_LIST;
|
return &TR_LIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void APIENTRY glFlush() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void APIENTRY glFinish() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void APIENTRY glKosInit() {
|
void APIENTRY glKosInit() {
|
||||||
TRACE();
|
TRACE();
|
||||||
|
|
||||||
|
@ -94,14 +105,10 @@ void APIENTRY glKosSwapBuffers() {
|
||||||
|
|
||||||
TRACE();
|
TRACE();
|
||||||
|
|
||||||
PROFILER_PUSH(__func__);
|
profiler_push(__func__);
|
||||||
|
|
||||||
//printf("Flush:\n\tOP:%d\n\tPT:%d\n\tTR:%d\n",OP_LIST.vector.size,PT_LIST.vector.size,TR_LIST.vector.size);
|
|
||||||
//printf("Flush: glTexImage mem free:%d\n",pvr_mem_available());
|
|
||||||
|
|
||||||
pvr_wait_ready();
|
pvr_wait_ready();
|
||||||
|
|
||||||
|
|
||||||
pvr_scene_begin();
|
pvr_scene_begin();
|
||||||
QACR0 = QACRTA;
|
QACR0 = QACRTA;
|
||||||
QACR1 = QACRTA;
|
QACR1 = QACRTA;
|
||||||
|
@ -123,12 +130,11 @@ void APIENTRY glKosSwapBuffers() {
|
||||||
aligned_vector_clear(&PT_LIST.vector);
|
aligned_vector_clear(&PT_LIST.vector);
|
||||||
aligned_vector_clear(&TR_LIST.vector);
|
aligned_vector_clear(&TR_LIST.vector);
|
||||||
|
|
||||||
#ifdef PROFILER_COMPILE
|
profiler_checkpoint("scene");
|
||||||
PROFILER_CHECKPOINT("scene");
|
profiler_pop();
|
||||||
PROFILER_POP();
|
|
||||||
if(frame_count++ > 100) {
|
if(frame_count++ > 100) {
|
||||||
profiler_print_stats();
|
profiler_print_stats();
|
||||||
frame_count = 0;
|
frame_count = 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,6 +83,10 @@ void APIENTRY glColor3f(GLfloat r, GLfloat g, GLfloat b) {
|
||||||
glColor4f(r, g, b, a);
|
glColor4f(r, g, b, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void APIENTRY glColor3ub(GLubyte red, GLubyte green, GLubyte blue) {
|
||||||
|
glColor3f((float) red / 255, (float) green / 255, (float) blue / 255);
|
||||||
|
}
|
||||||
|
|
||||||
void APIENTRY glColor3fv(const GLfloat* v) {
|
void APIENTRY glColor3fv(const GLfloat* v) {
|
||||||
glColor3f(v[0], v[1], v[2]);
|
glColor3f(v[0], v[1], v[2]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
static GLfloat SCENE_AMBIENT [] = {0.2, 0.2, 0.2, 1.0};
|
static GLfloat SCENE_AMBIENT [] = {0.2, 0.2, 0.2, 1.0};
|
||||||
static GLboolean VIEWER_IN_EYE_COORDINATES = GL_TRUE;
|
static GLboolean VIEWER_IN_EYE_COORDINATES = GL_TRUE;
|
||||||
static GLenum COLOR_CONTROL = GL_SINGLE_COLOR;
|
static GLenum COLOR_CONTROL = GL_SINGLE_COLOR;
|
||||||
//static GLboolean TWO_SIDED_LIGHTING = GL_FALSE;
|
static GLboolean TWO_SIDED_LIGHTING = GL_FALSE;
|
||||||
static GLenum COLOR_MATERIAL_MODE = GL_AMBIENT_AND_DIFFUSE;
|
static GLenum COLOR_MATERIAL_MODE = GL_AMBIENT_AND_DIFFUSE;
|
||||||
|
|
||||||
static LightSource LIGHTS[MAX_LIGHTS];
|
static LightSource LIGHTS[MAX_LIGHTS];
|
||||||
|
|
10
GL/matrix.c
10
GL/matrix.c
|
@ -9,7 +9,7 @@
|
||||||
#define DEG2RAD (0.01745329251994329576923690768489)
|
#define DEG2RAD (0.01745329251994329576923690768489)
|
||||||
|
|
||||||
/* Viewport mapping */
|
/* Viewport mapping */
|
||||||
//static GLfloat gl_viewport_scale[3], gl_viewport_offset[3];
|
static GLfloat gl_viewport_scale[3], gl_viewport_offset[3];
|
||||||
|
|
||||||
/* Depth range */
|
/* Depth range */
|
||||||
static GLclampf gl_depthrange_near, gl_depthrange_far;
|
static GLclampf gl_depthrange_near, gl_depthrange_far;
|
||||||
|
@ -33,14 +33,14 @@ static const matrix_t IDENTITY = {
|
||||||
|
|
||||||
void APIENTRY glDepthRange(GLclampf n, GLclampf f);
|
void APIENTRY glDepthRange(GLclampf n, GLclampf f);
|
||||||
|
|
||||||
matrix_t* _glGetModelViewMatrix() {
|
|
||||||
return (matrix_t*)stack_top(&MATRIX_STACKS[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
matrix_t* _glGetProjectionMatrix() {
|
matrix_t* _glGetProjectionMatrix() {
|
||||||
return (matrix_t*) stack_top(&MATRIX_STACKS[1]);
|
return (matrix_t*) stack_top(&MATRIX_STACKS[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
matrix_t* _glGetModelViewMatrix() {
|
||||||
|
return (matrix_t*) stack_top(&MATRIX_STACKS[0]);
|
||||||
|
}
|
||||||
|
|
||||||
void _glInitMatrices() {
|
void _glInitMatrices() {
|
||||||
init_stack(&MATRIX_STACKS[0], sizeof(matrix_t), 32);
|
init_stack(&MATRIX_STACKS[0], sizeof(matrix_t), 32);
|
||||||
init_stack(&MATRIX_STACKS[1], sizeof(matrix_t), 32);
|
init_stack(&MATRIX_STACKS[1], sizeof(matrix_t), 32);
|
||||||
|
|
13
GL/private.h
13
GL/private.h
|
@ -16,7 +16,6 @@
|
||||||
#define NORMAL_ENABLED_FLAG (1 << 4)
|
#define NORMAL_ENABLED_FLAG (1 << 4)
|
||||||
|
|
||||||
#define MAX_TEXTURE_SIZE 1024
|
#define MAX_TEXTURE_SIZE 1024
|
||||||
#define MAX_POLYGON_SIZE 18
|
|
||||||
|
|
||||||
#define CLIP_VERTEX_INT_PADDING 6
|
#define CLIP_VERTEX_INT_PADDING 6
|
||||||
|
|
||||||
|
@ -46,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 {
|
||||||
|
@ -69,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 {
|
||||||
|
@ -142,11 +146,14 @@ 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 _glIsAlphaTestEnabled();
|
||||||
|
|
||||||
GLboolean _glIsMipmapComplete(const TextureObject* obj);
|
GLboolean _glIsMipmapComplete(const TextureObject* obj);
|
||||||
GLubyte* _glGetMipmapLocation(TextureObject* obj, GLuint level);
|
GLubyte* _glGetMipmapLocation(TextureObject* obj, GLuint level);
|
||||||
GLuint _glGetMipmapLevelCount(TextureObject* obj);
|
GLuint _glGetMipmapLevelCount(TextureObject* obj);
|
||||||
|
|
71
GL/state.c
71
GL/state.c
|
@ -30,6 +30,9 @@ static GLboolean COLOR_MATERIAL_ENABLED = GL_FALSE;
|
||||||
/* Is the shared texture palette enabled? */
|
/* Is the shared texture palette enabled? */
|
||||||
static GLboolean SHARED_PALETTE_ENABLED = GL_FALSE;
|
static GLboolean SHARED_PALETTE_ENABLED = GL_FALSE;
|
||||||
|
|
||||||
|
static GLboolean ALPHA_TEST_ENABLED = GL_FALSE;
|
||||||
|
|
||||||
|
|
||||||
GLboolean _glIsSharedTexturePaletteEnabled() {
|
GLboolean _glIsSharedTexturePaletteEnabled() {
|
||||||
return SHARED_PALETTE_ENABLED;
|
return SHARED_PALETTE_ENABLED;
|
||||||
}
|
}
|
||||||
|
@ -84,6 +87,10 @@ GLboolean _glIsBlendingEnabled() {
|
||||||
return BLEND_ENABLED;
|
return BLEND_ENABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLboolean _glIsAlphaTestEnabled() {
|
||||||
|
return ALPHA_TEST_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
static int _calcPVRBlendFactor(GLenum factor) {
|
static int _calcPVRBlendFactor(GLenum factor) {
|
||||||
switch(factor) {
|
switch(factor) {
|
||||||
case GL_ZERO:
|
case GL_ZERO:
|
||||||
|
@ -103,7 +110,7 @@ static int _calcPVRBlendFactor(GLenum factor) {
|
||||||
case GL_ONE:
|
case GL_ONE:
|
||||||
return PVR_BLEND_ONE;
|
return PVR_BLEND_ONE;
|
||||||
default:
|
default:
|
||||||
printf("Invalid blend mode: %d\n", factor);
|
fprintf(stderr, "Invalid blend mode: %d\n", factor);
|
||||||
return PVR_BLEND_ONE;
|
return PVR_BLEND_ONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,7 +134,7 @@ static void _updatePVRBlend(pvr_poly_cxt_t* context) {
|
||||||
GLboolean _glCheckValidEnum(GLint param, GLenum* values, const char* func) {
|
GLboolean _glCheckValidEnum(GLint param, GLenum* values, const char* func) {
|
||||||
GLubyte found = 0;
|
GLubyte found = 0;
|
||||||
while(*values != 0) {
|
while(*values != 0) {
|
||||||
if(*values == param) {
|
if(*values == (GLenum)param) {
|
||||||
found++;
|
found++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -135,9 +142,8 @@ GLboolean _glCheckValidEnum(GLint param, GLenum* values, const char* func) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!found) {
|
if(!found) {
|
||||||
//_glKosThrowError(GL_INVALID_ENUM, func);
|
_glKosThrowError(GL_INVALID_ENUM, func);
|
||||||
//_glKosPrintError();
|
_glKosPrintError();
|
||||||
printf("GL_INVALID_ENUM when calling %s\n",func);
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,9 +185,6 @@ void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) {
|
||||||
if(tx1->isCompressed && _glIsMipmapComplete(tx1)) {
|
if(tx1->isCompressed && _glIsMipmapComplete(tx1)) {
|
||||||
enableMipmaps = GL_TRUE;
|
enableMipmaps = GL_TRUE;
|
||||||
}
|
}
|
||||||
if(tx1->isPaletted){
|
|
||||||
enableMipmaps = GL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(enableMipmaps) {
|
if(enableMipmaps) {
|
||||||
if(tx1->minFilter == GL_LINEAR_MIPMAP_NEAREST) {
|
if(tx1->minFilter == GL_LINEAR_MIPMAP_NEAREST) {
|
||||||
|
@ -197,9 +200,6 @@ void _glUpdatePVRTextureContext(pvr_poly_cxt_t* context, GLshort textureUnit) {
|
||||||
if(tx1->minFilter == GL_LINEAR && tx1->magFilter == GL_LINEAR) {
|
if(tx1->minFilter == GL_LINEAR && tx1->magFilter == GL_LINEAR) {
|
||||||
filter = PVR_FILTER_BILINEAR;
|
filter = PVR_FILTER_BILINEAR;
|
||||||
}
|
}
|
||||||
if(tx1->isPaletted){
|
|
||||||
filter = PVR_FILTER_NONE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we don't have complete mipmaps, and yet mipmapping was enabled, we disable texturing.
|
/* If we don't have complete mipmaps, and yet mipmapping was enabled, we disable texturing.
|
||||||
|
@ -221,6 +221,16 @@ 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()) {
|
||||||
|
TexturePalette* palette = _glGetSharedPalette(tx1->shared_bank);
|
||||||
|
context->txr.format |= PVR_TXRFMT_8BPP_PAL((palette) ? 0 : palette->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;
|
||||||
|
@ -307,11 +317,11 @@ 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(); //@Todo: Actually Dont.
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case GL_ALPHA_TEST: {
|
||||||
|
ALPHA_TEST_ENABLED = GL_TRUE;
|
||||||
|
} break;
|
||||||
case GL_LIGHT0:
|
case GL_LIGHT0:
|
||||||
case GL_LIGHT1:
|
case GL_LIGHT1:
|
||||||
case GL_LIGHT2:
|
case GL_LIGHT2:
|
||||||
|
@ -361,11 +371,11 @@ 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(); //@Todo: Actually Dont.
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case GL_ALPHA_TEST: {
|
||||||
|
ALPHA_TEST_ENABLED = GL_FALSE;
|
||||||
|
} break;
|
||||||
case GL_LIGHT0:
|
case GL_LIGHT0:
|
||||||
case GL_LIGHT1:
|
case GL_LIGHT1:
|
||||||
case GL_LIGHT2:
|
case GL_LIGHT2:
|
||||||
|
@ -411,6 +421,14 @@ GLAPI void APIENTRY glClearDepth(GLfloat depth) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLAPI void APIENTRY glDrawBuffer(GLenum mode) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
GLAPI void APIENTRY glReadBuffer(GLenum mode) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
GLAPI void APIENTRY glDepthMask(GLboolean flag) {
|
GLAPI void APIENTRY glDepthMask(GLboolean flag) {
|
||||||
GL_CONTEXT.depth.write = (flag == GL_TRUE) ? PVR_DEPTHWRITE_ENABLE : PVR_DEPTHWRITE_DISABLE;
|
GL_CONTEXT.depth.write = (flag == GL_TRUE) ? PVR_DEPTHWRITE_ENABLE : PVR_DEPTHWRITE_DISABLE;
|
||||||
GL_CONTEXT.depth.comparison = _calc_pvr_depth_test();
|
GL_CONTEXT.depth.comparison = _calc_pvr_depth_test();
|
||||||
|
@ -457,8 +475,20 @@ GLAPI void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor) {
|
||||||
_updatePVRBlend(&GL_CONTEXT);
|
_updatePVRBlend(&GL_CONTEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void glAlphaFunc(GLenum func, GLclampf ref) {
|
#define PT_ALPHA_REF 0x011c
|
||||||
;
|
|
||||||
|
GLAPI void APIENTRY glAlphaFunc(GLenum func, GLclampf ref) {
|
||||||
|
GLenum validFuncs[] = {
|
||||||
|
GL_GREATER,
|
||||||
|
0
|
||||||
|
};
|
||||||
|
|
||||||
|
if(_glCheckValidEnum(func, validFuncs, __func__) != 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLubyte val = (GLubyte)(ref * 255.0f);
|
||||||
|
PVR_SET(PT_ALPHA_REF, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void glLineWidth(GLfloat width) {
|
void glLineWidth(GLfloat width) {
|
||||||
|
@ -579,6 +609,7 @@ void APIENTRY glGetFloatv(GLenum pname, GLfloat* params) {
|
||||||
switch(pname) {
|
switch(pname) {
|
||||||
case GL_PROJECTION_MATRIX:
|
case GL_PROJECTION_MATRIX:
|
||||||
memcpy(params, _glGetProjectionMatrix(), sizeof(float) * 16);
|
memcpy(params, _glGetProjectionMatrix(), sizeof(float) * 16);
|
||||||
|
break;
|
||||||
case GL_MODELVIEW_MATRIX:
|
case GL_MODELVIEW_MATRIX:
|
||||||
memcpy(params, _glGetModelViewMatrix(), sizeof(float) * 16);
|
memcpy(params, _glGetModelViewMatrix(), sizeof(float) * 16);
|
||||||
break;
|
break;
|
||||||
|
@ -643,7 +674,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";
|
||||||
|
|
390
GL/texture.c
390
GL/texture.c
|
@ -18,65 +18,107 @@ 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 GLbyte CURRENT_PALETTE = 0;
|
|
||||||
|
|
||||||
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);
|
||||||
|
memset(palette, 0x0, sizeof(TexturePalette));
|
||||||
|
|
||||||
|
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;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
last_bound_palette = src;
|
|
||||||
|
|
||||||
pvr_set_pal_format(PVR_PAL_ARGB8888);
|
pvr_set_pal_format(PVR_PAL_ARGB8888);
|
||||||
|
|
||||||
GLushort i = 0;
|
GLushort i;
|
||||||
|
GLushort offset = src->size * src->bank;
|
||||||
//printf("Palette Entries: %d\n",src->width);
|
for(i = 0; i < src->width; ++i) {
|
||||||
for(; i < src->width; ++i) {
|
|
||||||
GLubyte* entry = &src->data[i * 4];
|
GLubyte* entry = &src->data[i * 4];
|
||||||
//printf("#%02X%02X%02X\t\t %08X\n",entry[0],entry[1],entry[2], 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]));
|
||||||
pvr_set_pal_entry(i, PACK_ARGB8888(entry[3], entry[0], entry[1], entry[2]));
|
|
||||||
}
|
}
|
||||||
//printf("------END------\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLubyte _glGetActiveTexture() {
|
GLubyte _glGetActiveTexture() {
|
||||||
|
@ -159,10 +201,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,8 +222,7 @@ TextureObject* _glGetBoundTexture() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void APIENTRY glActiveTextureARB(GLenum texture) {
|
void APIENTRY glActiveTextureARB(GLenum texture) {
|
||||||
//@TODO: Uncomment
|
TRACE();
|
||||||
//TRACE();
|
|
||||||
|
|
||||||
if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS)
|
if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS)
|
||||||
_glKosThrowError(GL_INVALID_ENUM, "glActiveTextureARB");
|
_glKosThrowError(GL_INVALID_ENUM, "glActiveTextureARB");
|
||||||
|
@ -210,6 +252,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) {
|
||||||
|
@ -248,7 +293,7 @@ void APIENTRY glDeleteTextures(GLsizei n, GLuint *textures) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(txr->palette && txr->palette->data) {
|
if(txr->palette && txr->palette->data) {
|
||||||
pvr_mem_free(txr->palette->data);
|
free(txr->palette->data);
|
||||||
txr->palette->data = NULL;
|
txr->palette->data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,10 +322,8 @@ void APIENTRY glBindTexture(GLenum target, GLuint texture) {
|
||||||
TextureObject* txr = named_array_reserve(&TEXTURE_OBJECTS, texture);
|
TextureObject* txr = named_array_reserve(&TEXTURE_OBJECTS, texture);
|
||||||
_glInitializeTextureObject(txr, texture);
|
_glInitializeTextureObject(txr, texture);
|
||||||
}
|
}
|
||||||
TEXTURE_UNITS[ACTIVE_TEXTURE] = (TextureObject*) named_array_get(&TEXTURE_OBJECTS, texture);
|
|
||||||
|
|
||||||
/* Apply the texture palette if necessary */
|
TEXTURE_UNITS[ACTIVE_TEXTURE] = (TextureObject*) named_array_get(&TEXTURE_OBJECTS, texture);
|
||||||
//_glApplyColorTable(); //@Todo: Actually Dont.
|
|
||||||
} else {
|
} else {
|
||||||
TEXTURE_UNITS[ACTIVE_TEXTURE] = NULL;
|
TEXTURE_UNITS[ACTIVE_TEXTURE] = NULL;
|
||||||
}
|
}
|
||||||
|
@ -295,9 +338,9 @@ void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) {
|
||||||
|
|
||||||
GLubyte failures = 0;
|
GLubyte failures = 0;
|
||||||
|
|
||||||
/*failures += _glCheckValidEnum(target, target_values, __func__);
|
failures += _glCheckValidEnum(target, target_values, __func__);
|
||||||
failures += _glCheckValidEnum(pname, pname_values, __func__);
|
failures += _glCheckValidEnum(pname, pname_values, __func__);
|
||||||
failures += _glCheckValidEnum(param, param_values, __func__);*/
|
failures += _glCheckValidEnum(param, param_values, __func__);
|
||||||
|
|
||||||
TextureObject* active = TEXTURE_UNITS[ACTIVE_TEXTURE];
|
TextureObject* active = TEXTURE_UNITS[ACTIVE_TEXTURE];
|
||||||
|
|
||||||
|
@ -324,7 +367,7 @@ void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param) {
|
void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLint param) {
|
||||||
glTexEnvi(target, pname, param);
|
glTexEnvi(target, pname, param);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -553,7 +596,7 @@ static GLuint _determinePVRFormat(GLint internalFormat, GLenum type) {
|
||||||
case GL_COMPRESSED_ARGB_1555_VQ_MIPMAP_TWID_KOS:
|
case GL_COMPRESSED_ARGB_1555_VQ_MIPMAP_TWID_KOS:
|
||||||
return PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_TWIDDLED | PVR_TXRFMT_VQ_ENABLE;
|
return PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_TWIDDLED | PVR_TXRFMT_VQ_ENABLE;
|
||||||
case GL_COLOR_INDEX8_EXT:
|
case GL_COLOR_INDEX8_EXT:
|
||||||
return PVR_TXRFMT_PAL8BPP | PVR_TXRFMT_8BPP_PAL(CURRENT_PALETTE);
|
return PVR_TXRFMT_PAL8BPP | PVR_TXRFMT_TWIDDLED;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -568,11 +611,11 @@ static inline void _rgba8888_to_argb4444(const GLubyte* source, GLubyte* dest) {
|
||||||
|
|
||||||
static inline void _rgba8888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
|
static inline void _rgba8888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
|
||||||
/* Noop */
|
/* Noop */
|
||||||
//GLubyte* dst = (GLubyte*) dest;
|
GLubyte* dst = (GLubyte*) dest;
|
||||||
dest[0] = source[0];
|
dst[0] = source[0];
|
||||||
dest[1] = source[1];
|
dst[1] = source[1];
|
||||||
dest[2] = source[2];
|
dst[2] = source[2];
|
||||||
dest[3] = source[3];
|
dst[3] = source[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void _rgba8888_to_rgb565(const GLubyte* source, GLubyte* dest) {
|
static inline void _rgba8888_to_rgb565(const GLubyte* source, GLubyte* dest) {
|
||||||
|
@ -581,11 +624,11 @@ static inline void _rgba8888_to_rgb565(const GLubyte* source, GLubyte* dest) {
|
||||||
|
|
||||||
static inline void _rgb888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
|
static inline void _rgb888_to_rgba8888(const GLubyte* source, GLubyte* dest) {
|
||||||
/* Noop */
|
/* Noop */
|
||||||
//GLubyte* dst = (GLubyte*) dest;
|
GLubyte* dst = (GLubyte*) dest;
|
||||||
dest[0] = source[0];
|
dst[0] = source[0];
|
||||||
dest[1] = source[1];
|
dst[1] = source[1];
|
||||||
dest[2] = source[2];
|
dst[2] = source[2];
|
||||||
dest[3] = 255;
|
dst[3] = 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void _rgb888_to_rgb565(const GLubyte* source, GLubyte* dest) {
|
static inline void _rgb888_to_rgb565(const GLubyte* source, GLubyte* dest) {
|
||||||
|
@ -681,7 +724,7 @@ static TextureConversionFunc _determineConversion(GLint internalFormat, GLenum f
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("Unsupported conversion: %x -> %x, %x\n", internalFormat, format, type);
|
fprintf(stderr, "Unsupported conversion: %x -> %x, %x\n", internalFormat, format, type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -694,7 +737,6 @@ static GLboolean _isSupportedFormat(GLenum format) {
|
||||||
case GL_RGBA:
|
case GL_RGBA:
|
||||||
case GL_BGRA:
|
case GL_BGRA:
|
||||||
case GL_COLOR_INDEX:
|
case GL_COLOR_INDEX:
|
||||||
case GL_LUMINANCE:
|
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
default:
|
default:
|
||||||
return GL_FALSE;
|
return GL_FALSE;
|
||||||
|
@ -716,6 +758,20 @@ GLboolean _glIsMipmapComplete(const TextureObject* obj) {
|
||||||
return GL_TRUE;
|
return GL_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline GLuint morton_1by1(GLuint x) {
|
||||||
|
x &= 0x0000ffff; // x = ---- ---- ---- ---- fedc ba98 7654 3210
|
||||||
|
x = (x ^ (x << 8)) & 0x00ff00ff; // x = ---- ---- fedc ba98 ---- ---- 7654 3210
|
||||||
|
x = (x ^ (x << 4)) & 0x0f0f0f0f; // x = ---- fedc ---- ba98 ---- 7654 ---- 3210
|
||||||
|
x = (x ^ (x << 2)) & 0x33333333; // x = --fe --dc --ba --98 --76 --54 --32 --10
|
||||||
|
x = (x ^ (x << 1)) & 0x55555555; // x = -f-e -d-c -b-a -9-8 -7-6 -5-4 -3-2 -1-0
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline GLuint morton_index(GLuint x, GLuint y) {
|
||||||
|
return (morton_1by1(y) << 1) + morton_1by1(x);
|
||||||
|
}
|
||||||
|
|
||||||
void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
||||||
GLsizei width, GLsizei height, GLint border,
|
GLsizei width, GLsizei height, GLint border,
|
||||||
GLenum format, GLenum type, const GLvoid *data) {
|
GLenum format, GLenum type, const GLvoid *data) {
|
||||||
|
@ -723,12 +779,12 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
||||||
TRACE();
|
TRACE();
|
||||||
|
|
||||||
if(target != GL_TEXTURE_2D) {
|
if(target != GL_TEXTURE_2D) {
|
||||||
_glKosThrowError(GL_INVALID_ENUM, "glTexImage2D-tex2d");
|
_glKosThrowError(GL_INVALID_ENUM, "glTexImage2D");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(format != GL_COLOR_INDEX) {
|
if(format != GL_COLOR_INDEX) {
|
||||||
if(!_isSupportedFormat(format)) {
|
if(!_isSupportedFormat(format)) {
|
||||||
_glKosThrowError(GL_INVALID_ENUM, "glTexImage2D-invalid_format");
|
_glKosThrowError(GL_INVALID_ENUM, "glTexImage2D");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Abuse determineStride to see if type is valid */
|
/* Abuse determineStride to see if type is valid */
|
||||||
|
@ -738,43 +794,43 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
||||||
|
|
||||||
internalFormat = _cleanInternalFormat(internalFormat);
|
internalFormat = _cleanInternalFormat(internalFormat);
|
||||||
if(internalFormat == -1) {
|
if(internalFormat == -1) {
|
||||||
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D-internal_fmt");
|
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(internalFormat != GL_COLOR_INDEX8_EXT) {
|
if(internalFormat != GL_COLOR_INDEX8_EXT) {
|
||||||
_glKosThrowError(GL_INVALID_ENUM, "glTexImage2D-8EXT");
|
_glKosThrowError(GL_INVALID_ENUM, __func__);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GLint w = width;
|
GLint w = width;
|
||||||
if(w < 8 || (w & -w) != w) {
|
if(w < 8 || (w & -w) != w) {
|
||||||
/* Width is not a power of two. Must be!*/
|
/* Width is not a power of two. Must be!*/
|
||||||
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D-width");
|
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D");
|
||||||
}
|
}
|
||||||
|
|
||||||
GLint h = height;
|
GLint h = height;
|
||||||
if(h < 8 || (h & -h) != h) {
|
if(h < 8 || (h & -h) != h) {
|
||||||
/* height is not a power of two. Must be!*/
|
/* height is not a power of two. Must be!*/
|
||||||
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D-height");
|
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(level < 0) {
|
if(level < 0) {
|
||||||
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D-level");
|
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(border) {
|
if(border) {
|
||||||
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D-border");
|
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!TEXTURE_UNITS[ACTIVE_TEXTURE]) {
|
if(!TEXTURE_UNITS[ACTIVE_TEXTURE]) {
|
||||||
_glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D-active_tex");
|
_glKosThrowError(GL_INVALID_OPERATION, __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLboolean isPaletted = (internalFormat == GL_COLOR_INDEX8_EXT) ? GL_TRUE : GL_FALSE;
|
GLboolean isPaletted = (internalFormat == GL_COLOR_INDEX8_EXT) ? GL_TRUE : GL_FALSE;
|
||||||
|
|
||||||
if(isPaletted && level > 0) {
|
if(isPaletted && level > 0) {
|
||||||
/* Paletted textures can't have mipmaps */
|
/* Paletted textures can't have mipmaps */
|
||||||
_glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D-palette_level");
|
_glKosThrowError(GL_INVALID_OPERATION, __func__);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_glKosHasError()) {
|
if(_glKosHasError()) {
|
||||||
|
@ -838,52 +894,16 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
||||||
|
|
||||||
/* Let's assume we need to convert */
|
/* Let's assume we need to convert */
|
||||||
GLboolean needsConversion = GL_TRUE;
|
GLboolean needsConversion = GL_TRUE;
|
||||||
|
GLboolean needsTwiddling = GL_FALSE;
|
||||||
GLubyte* targetData = _glGetMipmapLocation(active, level);
|
|
||||||
assert(targetData);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These are the only formats where the source format passed in matches the pvr format.
|
* These are the only formats where the source format passed in matches the pvr format.
|
||||||
* Note the REV formats + GL_BGRA will reverse to ARGB which is what the PVR supports
|
* Note the REV formats + GL_BGRA will reverse to ARGB which is what the PVR supports
|
||||||
*/
|
*/
|
||||||
if(format == GL_COLOR_INDEX) {
|
if(format == GL_COLOR_INDEX) {
|
||||||
if(type == GL_UNSIGNED_BYTE_TWID_KOS){
|
|
||||||
|
|
||||||
} else {
|
|
||||||
/* Don't convert color indexes */
|
/* Don't convert color indexes */
|
||||||
/* Linear/iterative twiddling algorithm from Marcus' tatest */
|
|
||||||
#define TWIDTAB(x) ( (x&1)|((x&2)<<1)|((x&4)<<2)|((x&8)<<3)|((x&16)<<4)| \
|
|
||||||
((x&32)<<5)|((x&64)<<6)|((x&128)<<7)|((x&256)<<8)|((x&512)<<9) )
|
|
||||||
#define TWIDOUT(x, y) ( TWIDTAB((y)) | (TWIDTAB((x)) << 1) )
|
|
||||||
|
|
||||||
#define MIN(a, b) ( (a)<(b)? (a):(b) )
|
|
||||||
|
|
||||||
uint32 x, y, yout, min, mask, invert;
|
|
||||||
|
|
||||||
min = MIN(w, h);
|
|
||||||
mask = min - 1;
|
|
||||||
invert = 0;
|
|
||||||
|
|
||||||
uint8 * pixels;
|
|
||||||
uint16 * vtex;
|
|
||||||
pixels = (uint8 *) data;
|
|
||||||
vtex = (uint16*)targetData;
|
|
||||||
|
|
||||||
for(y = 0; y < h; y += 2) {
|
|
||||||
if(!invert)
|
|
||||||
yout = y;
|
|
||||||
else
|
|
||||||
yout = ((h - 1) - y);
|
|
||||||
|
|
||||||
for(x = 0; x < w; x++) {
|
|
||||||
vtex[TWIDOUT((yout & mask) / 2, x & mask) +
|
|
||||||
(x / min + yout / min)*min * min / 2] =
|
|
||||||
pixels[y * w + x] | (pixels[(y + 1) * w + x] << 8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data = NULL;
|
|
||||||
}
|
|
||||||
needsConversion = GL_FALSE;
|
needsConversion = GL_FALSE;
|
||||||
|
needsTwiddling = type == GL_UNSIGNED_BYTE;
|
||||||
} else if(format == GL_BGRA && type == GL_UNSIGNED_SHORT_4_4_4_4_REV && internalFormat == GL_RGBA) {
|
} else if(format == GL_BGRA && type == GL_UNSIGNED_SHORT_4_4_4_4_REV && internalFormat == GL_RGBA) {
|
||||||
needsConversion = GL_FALSE;
|
needsConversion = GL_FALSE;
|
||||||
} else if(format == GL_BGRA && type == GL_UNSIGNED_SHORT_1_5_5_5_REV && internalFormat == GL_RGBA) {
|
} else if(format == GL_BGRA && type == GL_UNSIGNED_SHORT_1_5_5_5_REV && internalFormat == GL_RGBA) {
|
||||||
|
@ -898,6 +918,9 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
||||||
needsConversion = GL_FALSE;
|
needsConversion = GL_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLubyte* targetData = _glGetMipmapLocation(active, level);
|
||||||
|
assert(targetData);
|
||||||
|
|
||||||
if(!data) {
|
if(!data) {
|
||||||
/* No data? Do nothing! */
|
/* No data? Do nothing! */
|
||||||
return;
|
return;
|
||||||
|
@ -906,8 +929,49 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
||||||
assert(data);
|
assert(data);
|
||||||
assert(bytes);
|
assert(bytes);
|
||||||
|
|
||||||
|
if(needsTwiddling) {
|
||||||
|
/*assert(type == GL_UNSIGNED_BYTE); // Anything else needs this loop adjusting
|
||||||
|
GLuint x, y;
|
||||||
|
for(y = 0; y < height; ++y) {
|
||||||
|
for(x = 0; x < width; ++x) {
|
||||||
|
GLuint src = (y * width) + x;
|
||||||
|
GLuint dest = morton_index(x, y);
|
||||||
|
|
||||||
|
targetData[dest] = ((GLubyte*) data)[src];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
/* Don't convert color indexes */
|
||||||
|
/* Linear/iterative twiddling algorithm from Marcus' tatest */
|
||||||
|
#define TWIDTAB(x) ( (x&1)|((x&2)<<1)|((x&4)<<2)|((x&8)<<3)|((x&16)<<4)| \
|
||||||
|
((x&32)<<5)|((x&64)<<6)|((x&128)<<7)|((x&256)<<8)|((x&512)<<9) )
|
||||||
|
#define TWIDOUT(x, y) ( TWIDTAB((y)) | (TWIDTAB((x)) << 1) )
|
||||||
|
|
||||||
|
#define MIN(a, b) ( (a)<(b)? (a):(b) )
|
||||||
|
|
||||||
|
uint32 x, y, min, mask;
|
||||||
|
|
||||||
|
min = MIN(w, h);
|
||||||
|
mask = min - 1;
|
||||||
|
|
||||||
|
uint8 * pixels;
|
||||||
|
uint16 * vtex;
|
||||||
|
pixels = (uint8 *) data;
|
||||||
|
vtex = (uint16*)targetData;
|
||||||
|
|
||||||
|
for(y = 0; y < h; y += 2) {
|
||||||
|
for(x = 0; x < w; x++) {
|
||||||
|
vtex[TWIDOUT((y & mask) / 2, x & mask) +
|
||||||
|
(x / min + y / min)*min * min / 2] =
|
||||||
|
pixels[y * w + x] | (pixels[(y + 1) * w + x] << 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
data = NULL;
|
||||||
|
} else {
|
||||||
/* No conversion? Just copy the data, and the pvr_format is correct */
|
/* No conversion? Just copy the data, and the pvr_format is correct */
|
||||||
sq_cpy(targetData, data, bytes);
|
sq_cpy(targetData, data, bytes);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
TextureConversionFunc convert = _determineConversion(
|
TextureConversionFunc convert = _determineConversion(
|
||||||
|
@ -917,7 +981,7 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
||||||
);
|
);
|
||||||
|
|
||||||
if(!convert) {
|
if(!convert) {
|
||||||
_glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D-convert");
|
_glKosThrowError(GL_INVALID_OPERATION, __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -931,7 +995,7 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
||||||
assert(stride > -1);
|
assert(stride > -1);
|
||||||
|
|
||||||
if(stride == -1) {
|
if(stride == -1) {
|
||||||
_glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D-stride");
|
_glKosThrowError(GL_INVALID_OPERATION, __func__);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -944,7 +1008,6 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
|
||||||
source += stride;
|
source += stride;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//printf("GLdc: glTexImage mem free:%d\n",pvr_mem_available());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) {
|
void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) {
|
||||||
|
@ -1012,6 +1075,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1022,7 +1090,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};
|
||||||
|
@ -1068,12 +1145,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;
|
||||||
|
@ -1082,15 +1166,32 @@ GLAPI void APIENTRY glColorTableEXT(GLenum target, GLenum internalFormat, GLsize
|
||||||
assert(palette);
|
assert(palette);
|
||||||
|
|
||||||
if(target) {
|
if(target) {
|
||||||
//pvr_mem_free(palette->data);
|
|
||||||
free(palette->data);
|
free(palette->data);
|
||||||
palette->data = NULL;
|
palette->data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
//palette->data = (GLubyte*) pvr_mem_malloc(width * 4);
|
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;
|
||||||
|
@ -1107,10 +1208,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) {
|
||||||
|
@ -1133,23 +1231,27 @@ GLAPI void APIENTRY glGetColorTableParameterfvEXT(GLenum target, GLenum pname, G
|
||||||
_glKosPrintError();
|
_glKosPrintError();
|
||||||
}
|
}
|
||||||
|
|
||||||
void APIENTRY glKosSetPalette( GLenum palette ) {
|
GLAPI void APIENTRY glTexSubImage2D(
|
||||||
switch(palette) {
|
GLenum target, GLint level, GLint xoffset, GLint yoffset,
|
||||||
case GL_EXT_PALLETE_0_8BPP:
|
GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) {
|
||||||
CURRENT_PALETTE = 0;
|
|
||||||
break;
|
|
||||||
case GL_EXT_PALLETE_1_8BPP:
|
|
||||||
CURRENT_PALETTE = 1;
|
|
||||||
break;
|
|
||||||
case GL_EXT_PALLETE_2_8BPP:
|
|
||||||
CURRENT_PALETTE = 2;
|
|
||||||
break;
|
|
||||||
case GL_EXT_PALLETE_3_8BPP:
|
|
||||||
CURRENT_PALETTE = 3;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLbyte APIENTRY glKosGetPalette() {
|
GLAPI void APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) {
|
||||||
return CURRENT_PALETTE;
|
|
||||||
|
}
|
||||||
|
|
||||||
|
GLAPI void APIENTRY glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
GLAPI void APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
GLAPI void APIENTRY glCopyTexImage1D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
GLAPI void APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
24
include/gl.h
24
include/gl.h
|
@ -112,10 +112,10 @@ __BEGIN_DECLS
|
||||||
|
|
||||||
/* Texture Environment */
|
/* Texture Environment */
|
||||||
#define GL_TEXTURE_ENV_MODE 0x2200
|
#define GL_TEXTURE_ENV_MODE 0x2200
|
||||||
#define GL_REPLACE 0x0
|
#define GL_REPLACE 0x1E01
|
||||||
#define GL_MODULATE 0x1
|
#define GL_MODULATE 0x2100
|
||||||
#define GL_DECAL 0x2
|
#define GL_DECAL 0x2101
|
||||||
#define GL_MODULATEALPHA 0x3
|
|
||||||
|
|
||||||
/* TextureMagFilter */
|
/* TextureMagFilter */
|
||||||
#define GL_NEAREST 0x2600
|
#define GL_NEAREST 0x2600
|
||||||
|
@ -393,6 +393,9 @@ __BEGIN_DECLS
|
||||||
/* Initialize the GL pipeline. GL will initialize the PVR. */
|
/* Initialize the GL pipeline. GL will initialize the PVR. */
|
||||||
GLAPI void APIENTRY glKosInit();
|
GLAPI void APIENTRY glKosInit();
|
||||||
|
|
||||||
|
GLAPI void APIENTRY glFlush();
|
||||||
|
GLAPI void APIENTRY glFinish();
|
||||||
|
|
||||||
/* Start Submission of Primitive Data */
|
/* Start Submission of Primitive Data */
|
||||||
/* Currently Supported Primitive Types:
|
/* Currently Supported Primitive Types:
|
||||||
-GL_POINTS ( does NOT work with glDrawArrays )( ZClipping NOT supported )
|
-GL_POINTS ( does NOT work with glDrawArrays )( ZClipping NOT supported )
|
||||||
|
@ -413,6 +416,7 @@ GLAPI void APIENTRY glTexCoord2fv(const GLfloat *uv);
|
||||||
GLAPI void APIENTRY glColor1ui(GLuint argb);
|
GLAPI void APIENTRY glColor1ui(GLuint argb);
|
||||||
GLAPI void APIENTRY glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a);
|
GLAPI void APIENTRY glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a);
|
||||||
GLAPI void APIENTRY glColor3f(GLfloat r, GLfloat g, GLfloat b);
|
GLAPI void APIENTRY glColor3f(GLfloat r, GLfloat g, GLfloat b);
|
||||||
|
GLAPI void APIENTRY glColor3ub(GLubyte r, GLubyte g, GLubyte b);
|
||||||
GLAPI void APIENTRY glColor3fv(const GLfloat *rgb);
|
GLAPI void APIENTRY glColor3fv(const GLfloat *rgb);
|
||||||
GLAPI void APIENTRY glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
|
GLAPI void APIENTRY glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
|
||||||
GLAPI void APIENTRY glColor4fv(const GLfloat *rgba);
|
GLAPI void APIENTRY glColor4fv(const GLfloat *rgba);
|
||||||
|
@ -462,6 +466,9 @@ GLAPI void APIENTRY glDisable(GLenum cap);
|
||||||
GLAPI void APIENTRY glClear(GLuint mode);
|
GLAPI void APIENTRY glClear(GLuint mode);
|
||||||
GLAPI void APIENTRY glClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
|
GLAPI void APIENTRY glClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a);
|
||||||
|
|
||||||
|
GLAPI void APIENTRY glReadBuffer(GLenum mode);
|
||||||
|
GLAPI void APIENTRY glDrawBuffer(GLenum mode);
|
||||||
|
|
||||||
/* Depth Testing */
|
/* Depth Testing */
|
||||||
GLAPI void APIENTRY glClearDepth(GLfloat depth);
|
GLAPI void APIENTRY glClearDepth(GLfloat depth);
|
||||||
GLAPI void APIENTRY glClearDepthf(GLfloat depth);
|
GLAPI void APIENTRY glClearDepthf(GLfloat depth);
|
||||||
|
@ -486,7 +493,7 @@ GLAPI void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor);
|
||||||
/* Texturing */
|
/* Texturing */
|
||||||
GLAPI void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param);
|
GLAPI void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param);
|
||||||
GLAPI void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param);
|
GLAPI void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param);
|
||||||
GLAPI void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param);
|
GLAPI void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLint param);
|
||||||
|
|
||||||
GLAPI GLboolean APIENTRY glIsTexture(GLuint texture);
|
GLAPI GLboolean APIENTRY glIsTexture(GLuint texture);
|
||||||
GLAPI void APIENTRY glGenTextures(GLsizei n, GLuint *textures);
|
GLAPI void APIENTRY glGenTextures(GLsizei n, GLuint *textures);
|
||||||
|
@ -524,6 +531,13 @@ GLAPI void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalForma
|
||||||
GLsizei width, GLsizei height, GLint border,
|
GLsizei width, GLsizei height, GLint border,
|
||||||
GLenum format, GLenum type, const GLvoid *data);
|
GLenum format, GLenum type, const GLvoid *data);
|
||||||
|
|
||||||
|
GLAPI void APIENTRY glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels);
|
||||||
|
GLAPI void APIENTRY glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
|
||||||
|
GLAPI void APIENTRY glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width);
|
||||||
|
GLAPI void APIENTRY glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
|
||||||
|
GLAPI void APIENTRY glCopyTexImage1D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border);
|
||||||
|
GLAPI void APIENTRY glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
|
||||||
|
|
||||||
|
|
||||||
/* GL Array API - Only GL_TRIANGLES, GL_TRIANGLE_STRIP, and GL_QUADS are supported */
|
/* GL Array API - Only GL_TRIANGLES, GL_TRIANGLE_STRIP, and GL_QUADS are supported */
|
||||||
GLAPI void APIENTRY glVertexPointer(GLint size, GLenum type,
|
GLAPI void APIENTRY glVertexPointer(GLint size, GLenum type,
|
||||||
|
|
|
@ -34,14 +34,36 @@ __BEGIN_DECLS
|
||||||
|
|
||||||
#define GL_UNSIGNED_BYTE_TWID_KOS 0xEEFB
|
#define GL_UNSIGNED_BYTE_TWID_KOS 0xEEFB
|
||||||
|
|
||||||
#define GL_EXT_PALLETE_0_8BPP 0xEFA0
|
|
||||||
#define GL_EXT_PALLETE_1_8BPP 0xEFA1
|
|
||||||
#define GL_EXT_PALLETE_2_8BPP 0xEFA2
|
|
||||||
#define GL_EXT_PALLETE_3_8BPP 0xEFA3
|
|
||||||
|
|
||||||
GLAPI void APIENTRY glKosSwapBuffers();
|
GLAPI void APIENTRY glKosSwapBuffers();
|
||||||
GLAPI void APIENTRY glKosSetPalette( GLenum palette );
|
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user