From 62e001c288aed4991c06f79b32e71e1be631675d Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Fri, 11 May 2018 15:39:28 +0100 Subject: [PATCH] Reimplement or refactor Texturing, State, and Drawing Things working: - glDrawArrays / glDrawElements et al. - Texturing - Blending Things missing: - Lighting - Multitexturing - Near Z-clipping - Framebuffer extension - Immediate mode --- containers/aligned_vector.h | 10 +- experimental/draw.c | 179 ++++++++--- experimental/flush.c | 58 ++-- experimental/framebuffer.c | 0 experimental/immediate.c | 0 experimental/lighting.c | 0 experimental/private.h | 53 ++- experimental/state.c | 241 ++++++++++++-- experimental/texture.c | 620 ++++++++++++++++++++++++++++++++++++ gl-api.c | 343 +++++++++----------- gl-api.h | 3 +- gl-arrays.c | 608 ++++++++++++++++------------------- gl-cap.c | 132 ++++---- gl-error.c | 2 +- gl-pvr.h | 9 - gl-texture.c | 542 +------------------------------ include/gl.h | 2 +- include/glkos.h | 8 +- 18 files changed, 1565 insertions(+), 1245 deletions(-) create mode 100644 experimental/framebuffer.c create mode 100644 experimental/immediate.c create mode 100644 experimental/lighting.c create mode 100644 experimental/texture.c diff --git a/containers/aligned_vector.h b/containers/aligned_vector.h index a9c7fef..31e4710 100644 --- a/containers/aligned_vector.h +++ b/containers/aligned_vector.h @@ -6,7 +6,7 @@ #include #include -#define ALIGNED_VECTOR_INITIAL_CAPACITY 256 +#define ALIGNED_VECTOR_INITIAL_CAPACITY 256u typedef struct { unsigned int size; @@ -78,6 +78,12 @@ inline void* aligned_vector_at(AlignedVector* vector, const unsigned int index) return &vector->data[index * vector->element_size]; } +inline void* aligned_vector_extend(AlignedVector* vector, const unsigned int additional_count) { + const unsigned int current = vector->size; + aligned_vector_resize(vector, vector->size + additional_count); + return aligned_vector_at(vector, current); +} + inline void aligned_vector_clear(AlignedVector* vector) { vector->size = 0; } @@ -101,7 +107,7 @@ inline void aligned_vector_shrink_to_fit(AlignedVector* vector) { } } -void aligned_vector_cleanup(AlignedVector* vector) { +inline void aligned_vector_cleanup(AlignedVector* vector) { aligned_vector_clear(vector); aligned_vector_shrink_to_fit(vector); } diff --git a/experimental/draw.c b/experimental/draw.c index c935f18..ec3e590 100644 --- a/experimental/draw.c +++ b/experimental/draw.c @@ -1,9 +1,12 @@ -#include "../include/gl.h" -#include "private.h" +#include +#include "../include/gl.h" +#include "../include/glext.h" +#include "private.h" +#include "../gl-api.h" typedef struct { - void* ptr; + const void* ptr; GLenum type; GLsizei stride; GLint size; @@ -26,6 +29,8 @@ static GLuint ENABLED_VERTEX_ATTRIBUTES = 0; static GLubyte ACTIVE_CLIENT_TEXTURE = 0; void initAttributePointers() { + TRACE(); + VERTEX_POINTER.ptr = NULL; VERTEX_POINTER.stride = 0; VERTEX_POINTER.type = GL_FLOAT; @@ -45,7 +50,7 @@ static GLuint byte_size(GLenum type) { } } -static void transformVertex(const GLfloat* src) { +static void transformVertex(GLfloat* src, float* x, float* y, float* z) { register float __x __asm__("fr12"); register float __y __asm__("fr13"); register float __z __asm__("fr14"); @@ -56,9 +61,32 @@ static void transformVertex(const GLfloat* src) { mat_trans_fv12() - src[0] = __x; - src[1] = __y; - src[2] = __z; + *x = __x; + *y = __y; + *z = __z; +} + +static void _parseColour(uint32* out, const GLubyte* in, GLint size, GLenum type) { + switch(type) { + case GL_BYTE: { + case GL_UNSIGNED_BYTE: + *out = in[3] << 24 | in[0] << 16 | in[1] << 8 | in[0]; + } break; + case GL_SHORT: + case GL_UNSIGNED_SHORT: + /* FIXME!!!! */ + break; + case GL_INT: + case GL_UNSIGNED_INT: + /* FIXME!!!! */ + break; + case GL_FLOAT: + case GL_DOUBLE: + default: { + const GLfloat* src = (GLfloat*) in; + *out = PVR_PACK_COLOR(src[3], src[0], src[1], src[2]); + } break; + } } static void _parseFloats(GLfloat* out, const GLubyte* in, GLint size, GLenum type) { @@ -93,49 +121,97 @@ static void _parseIndex(GLshort* out, const GLubyte* in, GLenum type) { } } -static void submitVertices(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) { +static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum type, const GLvoid* indices) { + static float normal[3]; + if(!(ENABLED_VERTEX_ATTRIBUTES & VERTEX_ENABLED_FLAG)) { return; } - _glKosMatrixApplyRender(); /* Apply the Render Matrix Stack */ + _glKosMatrixApplyRender(); /* Apply the Render Matrix Stack */ - const GLbyte elements = (mode == GL_QUADS) ? 4 : (mode == GL_TRIANGLES) ? 3 : (mode == GL_LINES) ? 2 : count; + const GLsizei elements = (mode == GL_QUADS) ? 4 : (mode == GL_TRIANGLES) ? 3 : (mode == GL_LINES) ? 2 : count; - pvr_vertex_t vertex; - vertex.u = vertex.v = 0.0f; - vertex.argb = 0xFFFFFFFF; + // Make room for the element + the header + PVRCommand* dst = (PVRCommand*) aligned_vector_extend(&activePolyList()->vector, count + 1); - static GLfloat vparts[4]; + // Store a pointer to the header + pvr_poly_hdr_t* hdr = (pvr_poly_hdr_t*) dst; + + // Point dest at the first new vertex to populate + dst++; + + // Compile + pvr_poly_cxt_t cxt = *getPVRContext(); + cxt.list_type = activePolyList()->list_type; + updatePVRTextureContext(&cxt, getTexture0()); + + pvr_poly_compile(hdr, &cxt); GLubyte vstride = (VERTEX_POINTER.stride) ? VERTEX_POINTER.stride : VERTEX_POINTER.size * byte_size(VERTEX_POINTER.type); - GLubyte* vptr = VERTEX_POINTER.ptr; + const GLubyte* vptr = VERTEX_POINTER.ptr; - for(GLuint i = 0; i < count; ++i) { - GLshort idx = i; - if(indices) { - _parseIndex(&idx, indices[byte_size(type) * i], type); + GLubyte cstride = (DIFFUSE_POINTER.stride) ? DIFFUSE_POINTER.stride : DIFFUSE_POINTER.size * byte_size(DIFFUSE_POINTER.type); + const GLubyte* cptr = DIFFUSE_POINTER.ptr; + + GLubyte uvstride = (UV_POINTER.stride) ? UV_POINTER.stride : UV_POINTER.size * byte_size(UV_POINTER.type); + const GLubyte* uvptr = UV_POINTER.ptr; + + GLubyte nstride = (NORMAL_POINTER.stride) ? NORMAL_POINTER.stride : NORMAL_POINTER.size * byte_size(NORMAL_POINTER.type); + const GLubyte* nptr = NORMAL_POINTER.ptr; + + const GLubyte* indices_as_bytes = (GLubyte*) indices; + + for(GLuint i = first; i < count; ++i) { + pvr_vertex_t* vertex = (pvr_vertex_t*) dst; + vertex->u = vertex->v = 0.0f; + vertex->argb = PVR_PACK_COLOR(0.0f, 0.0f, 0.0f, 0.0f); + vertex->oargb = 0; + vertex->flags = PVR_CMD_VERTEX; + + if(((i + 1) % elements) == 0) { + vertex->flags = PVR_CMD_VERTEX_EOL; } - _parseFloats(vparts, vptr + (idx * vstride), VERTEX_POINTER.size, VERTEX_POINTER.type); + GLshort idx = i; + if(indices) { + _parseIndex(&idx, &indices_as_bytes[byte_size(type) * i], type); + } - vertex.x = vparts[0]; - vertex.y = vparts[1]; - vertex.z = vparts[2]; + _parseFloats(&vertex->x, vptr + (idx * vstride), VERTEX_POINTER.size, VERTEX_POINTER.type); + transformVertex(&vertex->x, &vertex->x, &vertex->y, &vertex->z); - transformVertex(&vertex.x); + if(ENABLED_VERTEX_ATTRIBUTES & DIFFUSE_ENABLED_FLAG) { + _parseColour(&vertex->argb, cptr + (idx * cstride), DIFFUSE_POINTER.size, DIFFUSE_POINTER.type); + } + + if(ENABLED_VERTEX_ATTRIBUTES & UV_ENABLED_FLAG) { + _parseFloats(&vertex->u, uvptr + (idx * uvstride), UV_POINTER.size, UV_POINTER.type); + } + + if(ENABLED_VERTEX_ATTRIBUTES & NORMAL_ENABLED_FLAG) { + _parseFloats(normal, nptr + (idx * nstride), NORMAL_POINTER.size, NORMAL_POINTER.type); + } + + ++dst; } } -GLAPI void APIENTRY glDrawElementsExp(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) { - submitVertices(mode, count, type, indices); +void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) { + TRACE(); + + submitVertices(mode, 0, count, type, indices); } -GLAPI void APIENTRY glDrawArraysExp(GLenum mode, GLint first, GLsizei count) { - submitVertices(mode, count, type, NULL); +void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count) { + TRACE(); + + submitVertices(mode, first, count, GL_UNSIGNED_SHORT, NULL); } -GLAPI void APIENTRY glEnableClientStateExp(GLenum cap) { +void APIENTRY glEnableClientState(GLenum cap) { + TRACE(); + switch(cap) { case GL_VERTEX_ARRAY: ENABLED_VERTEX_ATTRIBUTES |= VERTEX_ENABLED_FLAG; @@ -156,7 +232,9 @@ GLAPI void APIENTRY glEnableClientStateExp(GLenum cap) { } } -GLAPI void APIENTRY glDisableClientStateExp(GLenum cap) { +void APIENTRY glDisableClientState(GLenum cap) { + TRACE(); + switch(cap) { case GL_VERTEX_ARRAY: ENABLED_VERTEX_ATTRIBUTES &= ~VERTEX_ENABLED_FLAG; @@ -177,34 +255,53 @@ GLAPI void APIENTRY glDisableClientStateExp(GLenum cap) { } } -GLAPI void APIENTRY glClientActiveTextureExp(GLenum texture) { - ACTIVE_CLIENT_TEXTURE = (texture == GL_TEXTURE1) ? 1 : 0; +void APIENTRY glClientActiveTextureARB(GLenum texture) { + TRACE(); + + if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS) { + _glKosThrowError(GL_INVALID_ENUM, "glClientActiveTextureARB"); + } + + if(_glKosHasError()) { + _glKosPrintError(); + return; + } + + ACTIVE_CLIENT_TEXTURE = (texture == GL_TEXTURE1_ARB) ? 1 : 0; } -GLAPI void APIENTRY glTexcoordPointerExp(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) { - AttribPointer* texpointer = (ACTIVE_CLIENT_TEXTURE == 0) ? &UV_POINTER : &ST_POINTER; +void APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) { + TRACE(); - texpointer->ptr = pointer; - texpointer->stride = stride; - texpointer->type = type; - texpointer->size = size; + AttribPointer* tointer = (ACTIVE_CLIENT_TEXTURE == 0) ? &UV_POINTER : &ST_POINTER; + + tointer->ptr = pointer; + tointer->stride = stride; + tointer->type = type; + tointer->size = size; } -GLAPI void APIENTRY glVertexPointerExp(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) { +void APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) { + TRACE(); + VERTEX_POINTER.ptr = pointer; VERTEX_POINTER.stride = stride; VERTEX_POINTER.type = type; VERTEX_POINTER.size = size; } -GLAPI void APIENTRY glColorPointerExp(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) { +void APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) { + TRACE(); + DIFFUSE_POINTER.ptr = pointer; DIFFUSE_POINTER.stride = stride; DIFFUSE_POINTER.type = type; DIFFUSE_POINTER.size = size; } -GLAPI void APIENTRY glNormalPointerExp(GLenum type, GLsizei stride, const GLvoid * pointer) { +void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid * pointer) { + TRACE(); + NORMAL_POINTER.ptr = pointer; NORMAL_POINTER.stride = stride; NORMAL_POINTER.type = type; diff --git a/experimental/flush.c b/experimental/flush.c index 8af8476..967725e 100644 --- a/experimental/flush.c +++ b/experimental/flush.c @@ -4,17 +4,14 @@ #include "../containers/aligned_vector.h" #include "private.h" +#include "../gl-api.h" #define TA_SQ_ADDR (unsigned int *)(void *) \ (0xe0000000 | (((unsigned long)0x10000000) & 0x03ffffe0)) -static AlignedVector OP_LIST; -static AlignedVector PT_LIST; -static AlignedVector TR_LIST; - -typedef struct { - unsigned int cmd[8]; -} PVRCommand; +static PolyList OP_LIST; +static PolyList PT_LIST; +static PolyList TR_LIST; static void pvr_list_submit(void *src, int n) { GLuint *d = TA_SQ_ADDR; @@ -44,7 +41,7 @@ static void _initPVR() { pvr_init_params_t params = { /* Enable opaque and translucent polygons with size 32 and 32 */ { PVR_BINSIZE_32, PVR_BINSIZE_0, PVR_BINSIZE_32, PVR_BINSIZE_0, PVR_BINSIZE_32 }, - GL_PVR_VERTEX_BUF_SIZE, /* Vertex buffer size */ + PVR_VERTEX_BUF_SIZE, /* Vertex buffer size */ 0, /* No DMA */ 0, /* No FSAA */ 1 /* Disable translucent auto-sorting to match traditional GL */ @@ -54,35 +51,54 @@ static void _initPVR() { } -AlignedVector* activePolyList() { - return &OP_LIST; +PolyList* activePolyList() { + if(isBlendingEnabled()) { + return &TR_LIST; + } else { + return &OP_LIST; + } } -/* FIXME: Rename to glKosInit when experimental is core */ -void glKosBoot() { +void APIENTRY glKosInit() { + TRACE(); + _initPVR(); - initAttributePointers(); - aligned_vector_init(&OP_LIST, sizeof(PVRCommand)); - aligned_vector_init(&PT_LIST, sizeof(PVRCommand)); - aligned_vector_init(&TR_LIST, sizeof(PVRCommand)); + initAttributePointers(); + initContext(); + + _glKosInitMatrix(); + _glKosInitTextures(); + + OP_LIST.list_type = PVR_LIST_OP_POLY; + PT_LIST.list_type = PVR_LIST_PT_POLY; + TR_LIST.list_type = PVR_LIST_TR_POLY; + + aligned_vector_init(&OP_LIST.vector, sizeof(PVRCommand)); + aligned_vector_init(&PT_LIST.vector, sizeof(PVRCommand)); + aligned_vector_init(&TR_LIST.vector, sizeof(PVRCommand)); } -void glKosSwapBuffers() { +void APIENTRY glKosSwapBuffers() { + TRACE(); + pvr_wait_ready(); pvr_scene_begin(); - pvr_list_begin(PVR_LIST_OP_POLY); - pvr_list_submit(OP_LIST.data, OP_LIST.size); + pvr_list_submit(OP_LIST.vector.data, OP_LIST.vector.size); pvr_list_finish(); pvr_list_begin(PVR_LIST_PT_POLY); - pvr_list_submit(PT_LIST.data, PT_LIST.size); + pvr_list_submit(PT_LIST.vector.data, PT_LIST.vector.size); pvr_list_finish(); pvr_list_begin(PVR_LIST_TR_POLY); - pvr_list_submit(TR_LIST.data, TR_LIST.size); + pvr_list_submit(TR_LIST.vector.data, TR_LIST.vector.size); pvr_list_finish(); pvr_scene_finish(); + + aligned_vector_clear(&OP_LIST.vector); + aligned_vector_clear(&PT_LIST.vector); + aligned_vector_clear(&TR_LIST.vector); } diff --git a/experimental/framebuffer.c b/experimental/framebuffer.c new file mode 100644 index 0000000..e69de29 diff --git a/experimental/immediate.c b/experimental/immediate.c new file mode 100644 index 0000000..e69de29 diff --git a/experimental/lighting.c b/experimental/lighting.c new file mode 100644 index 0000000..e69de29 diff --git a/experimental/private.h b/experimental/private.h index a4ea851..bf74698 100644 --- a/experimental/private.h +++ b/experimental/private.h @@ -2,12 +2,61 @@ #define PRIVATE_H #include "../include/gl.h" +#include "../gl-api.h" +#include "../containers/aligned_vector.h" +#include "../containers/named_array.h" -struct AlignedVector; -AlignedVector* activePolyList(); +#define TRACE_ENABLED 0 +#define TRACE() if(TRACE_ENABLED) {fprintf(stderr, "%s\n", __func__);} + + +typedef struct { + unsigned int cmd[8]; +} PVRCommand; + +typedef struct { + unsigned int flags; /* Constant PVR_CMD_USERCLIP */ + unsigned int d1, d2, d3; /* Ignored for this type */ + unsigned int sx, /* Start x */ + sy, /* Start y */ + ex, /* End x */ + ey; /* End y */ +} PVRTileClipCommand; /* Tile Clip command for the pvr */ + +typedef struct { + unsigned int list_type; + AlignedVector vector; +} PolyList; + +typedef struct { + GLushort width; + GLushort height; + GLuint color; /* This is the PVR texture format */ + GLubyte env; + GLubyte filter; + GLubyte mip_map; + GLubyte uv_clamp; + GLuint index; + GLvoid *data; +} TextureObject; + +PolyList *activePolyList(); void initAttributePointers(); +void initContext(); +pvr_poly_cxt_t* getPVRContext(); +GLubyte _glKosInitTextures(); +void updatePVRTextureContext(pvr_poly_cxt_t* context, TextureObject* tx1); +TextureObject* getTexture0(); +TextureObject* getTexture1(); +TextureObject* getBoundTexture(); +GLboolean isBlendingEnabled(); + +#define PVR_VERTEX_BUF_SIZE 2560 * 256 +#define MAX_TEXTURE_UNITS 2 + +#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) ) #define mat_trans_fv12() { \ __asm__ __volatile__( \ diff --git a/experimental/state.c b/experimental/state.c index daa1245..7f39d95 100644 --- a/experimental/state.c +++ b/experimental/state.c @@ -1,7 +1,21 @@ +#include +#include + +#include +#include +#include + #include "../include/gl.h" +#include "../gl-api.h" +#include "private.h" static pvr_poly_cxt_t GL_CONTEXT; +pvr_poly_cxt_t* getPVRContext() { + return &GL_CONTEXT; +} + + /* We can't just use the GL_CONTEXT for this state as the two * GL states are combined, so we store them separately and then * calculate the appropriate PVR state from them. */ @@ -26,36 +40,136 @@ static GLboolean DEPTH_TEST_ENABLED = GL_FALSE; static int _calc_pvr_depth_test() { if(!DEPTH_TEST_ENABLED) { - return PVR_DEPTH_CMP_ALWAYS; + return PVR_DEPTHCMP_ALWAYS; } - switch(func) { + switch(DEPTH_FUNC) { case GL_NEVER: - return PVR_DEPTH_CMP_NEVER; + return PVR_DEPTHCMP_NEVER; case GL_LESS: - return PVR_DEPTH_CMP_LESS; + return PVR_DEPTHCMP_GEQUAL; case GL_EQUAL: - return PVR_DEPTH_CMP_EQUAL; + return PVR_DEPTHCMP_EQUAL; case GL_LEQUAL: - return PVR_DEPTH_CMP_LEQUAL; + return PVR_DEPTHCMP_GREATER; case GL_GREATER: - return PVR_DEPTH_CMP_GREATER; + return PVR_DEPTHCMP_LEQUAL; case GL_NOTEQUAL: - return PVR_DEPTH_CMP_NOTEQUAL; + return PVR_DEPTHCMP_NOTEQUAL; case GL_GEQUAL: - return PVR_DEPTH_CMP_GEQUAL; + return PVR_DEPTHCMP_LESS; break; case GL_ALWAYS: default: - return PVR_DEPTH_CMP_ALWAYS; + return PVR_DEPTHCMP_ALWAYS; + } +} + +static GLenum BLEND_SFACTOR = GL_ONE; +static GLenum BLEND_DFACTOR = GL_ZERO; +static GLboolean BLEND_ENABLED = GL_FALSE; + +GLboolean isBlendingEnabled() { + return BLEND_ENABLED; +} + +static int _calcPVRBlendFactor(GLenum factor) { + switch(factor) { + case GL_ZERO: + return PVR_BLEND_ZERO; + case GL_SRC_ALPHA: + case GL_SRC_COLOR: + return PVR_BLEND_SRCALPHA; + case GL_DST_COLOR: + return PVR_BLEND_DESTCOLOR; + case GL_DST_ALPHA: + return PVR_BLEND_DESTALPHA; + case GL_ONE_MINUS_DST_COLOR: + return PVR_BLEND_INVDESTCOLOR; + case GL_ONE_MINUS_SRC_COLOR: + case GL_ONE_MINUS_SRC_ALPHA: + return PVR_BLEND_INVSRCALPHA; + case GL_ONE_MINUS_DST_ALPHA: + return PVR_BLEND_INVDESTALPHA; + case GL_ONE: + default: + return PVR_BLEND_ONE; + } +} + +static void _updatePVRBlend(pvr_poly_cxt_t* context) { + if(BLEND_ENABLED) { + context->gen.alpha = PVR_ALPHA_ENABLE; + context->blend.src = _calcPVRBlendFactor(BLEND_SFACTOR); + context->blend.dst = _calcPVRBlendFactor(BLEND_DFACTOR); + context->blend.src_enable = PVR_BLEND_ENABLE; + context->blend.dst_enable = PVR_BLEND_ENABLE; + + context->blend.src2 = PVR_BLEND_ONE; + context->blend.dst2 = PVR_BLEND_ZERO; + context->blend.src_enable2 = PVR_BLEND_DISABLE; + context->blend.dst_enable2 = PVR_BLEND_DISABLE; + } else { + context->gen.alpha = PVR_ALPHA_DISABLE; + context->blend.src = PVR_BLEND_ONE; + context->blend.dst = PVR_BLEND_ZERO; + context->blend.src_enable = PVR_BLEND_DISABLE; + context->blend.dst_enable = PVR_BLEND_DISABLE; + + context->blend.src2 = PVR_BLEND_ONE; + context->blend.dst2 = PVR_BLEND_ZERO; + context->blend.src_enable2 = PVR_BLEND_DISABLE; + context->blend.dst_enable2 = PVR_BLEND_DISABLE; + } +} + +static GLboolean TEXTURES_ENABLED = GL_FALSE; + +void updatePVRTextureContext(pvr_poly_cxt_t* context, TextureObject *tx1) { + if(!TEXTURES_ENABLED) { + context->txr2.enable = context->txr.enable = PVR_TEXTURE_DISABLE; + return; + } + + context->txr2.enable = PVR_TEXTURE_DISABLE; + context->txr2.alpha = PVR_ALPHA_DISABLE; + + if(tx1) { + context->txr.enable = PVR_TEXTURE_ENABLE; + context->txr.filter = tx1->filter; + context->txr.mipmap_bias = PVR_MIPBIAS_NORMAL; + context->txr.width = tx1->width; + context->txr.height = tx1->height; + context->txr.base = tx1->data; + context->txr.format = tx1->color; + context->txr.env = tx1->env; + context->txr.uv_flip = PVR_UVFLIP_NONE; + context->txr.uv_clamp = tx1->uv_clamp; + } else { + context->txr.enable = PVR_TEXTURE_DISABLE; } } -void initContext() { +static GLfloat CLEAR_COLOUR[3]; + +void initContext() { + memset(&GL_CONTEXT, 0, sizeof(pvr_poly_cxt_t)); + + GL_CONTEXT.list_type = PVR_LIST_OP_POLY; + GL_CONTEXT.fmt.color = PVR_CLRFMT_ARGBPACKED; + GL_CONTEXT.fmt.uv = PVR_UVFMT_32BIT; + GL_CONTEXT.gen.fog_type = PVR_FOG_DISABLE; + GL_CONTEXT.gen.color_clamp = PVR_CLRCLAMP_DISABLE; + GL_CONTEXT.gen.fog_type = PVR_FOG_DISABLE; + GL_CONTEXT.gen.color_clamp = PVR_CLRCLAMP_DISABLE; + glDepthFunc(GL_LESS); glDepthMask(GL_TRUE); - glCullFace(GL_CCW); + glFrontFace(GL_CCW); + glCullFace(GL_BACK); + glShadeModel(GL_SMOOTH); + glClearColor(0, 0, 0, 0); glDisable(GL_ALPHA_TEST); glDisable(GL_CULL_FACE); @@ -67,7 +181,7 @@ void initContext() { GLAPI void APIENTRY glEnable(GLenum cap) { switch(cap) { case GL_TEXTURE_2D: - GL_CONTEXT.txr.enable = 1; + TEXTURES_ENABLED = GL_TRUE; break; case GL_CULL_FACE: { CULLING_ENABLED = GL_TRUE; @@ -77,13 +191,22 @@ GLAPI void APIENTRY glEnable(GLenum cap) { DEPTH_TEST_ENABLED = GL_TRUE; GL_CONTEXT.depth.comparison = _calc_pvr_depth_test(); } break; + case GL_BLEND: { + BLEND_ENABLED = GL_TRUE; + _updatePVRBlend(&GL_CONTEXT); + } break; + case GL_SCISSOR_TEST: { + GL_CONTEXT.gen.clip_mode = PVR_USERCLIP_INSIDE; + } break; + default: + break; } } GLAPI void APIENTRY glDisable(GLenum cap) { switch(cap) { case GL_TEXTURE_2D: { - GL_CONTEXT.txr.enabled = 0; + TEXTURES_ENABLED = GL_FALSE; } break; case GL_CULL_FACE: { CULLING_ENABLED = GL_FALSE; @@ -93,16 +216,34 @@ GLAPI void APIENTRY glDisable(GLenum cap) { DEPTH_TEST_ENABLED = GL_FALSE; GL_CONTEXT.depth.comparison = _calc_pvr_depth_test(); } break; + case GL_BLEND: + BLEND_ENABLED = GL_FALSE; + _updatePVRBlend(&GL_CONTEXT); + break; + case GL_SCISSOR_TEST: { + GL_CONTEXT.gen.clip_mode = PVR_USERCLIP_DISABLE; + } break; + default: + break; } } /* Clear Caps */ GLAPI void APIENTRY glClear(GLuint mode) { - + if(mode & GL_COLOR_BUFFER_BIT) { + pvr_set_bg_color(CLEAR_COLOUR[0], CLEAR_COLOUR[1], CLEAR_COLOUR[2]); + } } GLAPI void APIENTRY glClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) { + if(r > 1) r = 1; + if(g > 1) g = 1; + if(b > 1) b = 1; + if(a > 1) a = 1; + CLEAR_COLOUR[0] = r * a; + CLEAR_COLOUR[1] = g * a; + CLEAR_COLOUR[2] = b * a; } /* Depth Testing */ @@ -116,6 +257,7 @@ GLAPI void APIENTRY glClearDepth(GLfloat depth) { GLAPI void APIENTRY glDepthMask(GLboolean flag) { GL_CONTEXT.depth.write = (flag == GL_TRUE) ? PVR_DEPTHWRITE_ENABLE : PVR_DEPTHWRITE_DISABLE; + GL_CONTEXT.depth.comparison = _calc_pvr_depth_test(); } GLAPI void APIENTRY glDepthFunc(GLenum func) { @@ -133,43 +275,82 @@ GLAPI void APIENTRY glHint(GLenum target, GLenum mode) { /* Culling */ GLAPI void APIENTRY glFrontFace(GLenum mode) { FRONT_FACE = mode; + GL_CONTEXT.gen.culling = _calc_pvr_face_culling(); } GLAPI void APIENTRY glCullFace(GLenum mode) { CULL_FACE = mode; + GL_CONTEXT.gen.culling = _calc_pvr_face_culling(); } /* Shading - Flat or Goraud */ GLAPI void APIENTRY glShadeModel(GLenum mode) { - + GL_CONTEXT.gen.shading = (mode == GL_SMOOTH) ? PVR_SHADE_GOURAUD : PVR_SHADE_FLAT; } /* Blending */ GLAPI void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor) { - + BLEND_SFACTOR = sfactor; + BLEND_DFACTOR = dfactor; + _updatePVRBlend(&GL_CONTEXT); } -/* Texturing */ -GLAPI void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) { - +void glAlphaFunc(GLenum func, GLclampf ref) { + ; } -GLAPI void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) { - +void glLineWidth(GLfloat width) { + ; } -GLAPI void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param) { - +void glPolygonOffset(GLfloat factor, GLfloat units) { + ; } -GLAPI void APIENTRY glGenTextures(GLsizei n, GLuint *textures) { - +void glGetTexParameteriv(GLenum target, GLenum pname, GLint *params) { + ; } -GLAPI void APIENTRY glDeleteTextures(GLsizei n, GLuint *textures) { - +void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { + ; } -GLAPI void APIENTRY glBindTexture(GLenum target, GLuint texture) { - +void glPixelStorei(GLenum pname, GLint param) { + ; } + +/* Setup the hardware user clip rectangle. + + The minimum clip rectangle is a 32x32 area which is dependent on the tile + size use by the tile accelerator. The PVR swithes off rendering to tiles + outside or inside the defined rectangle dependant upon the 'clipmode' + bits in the polygon header. + + Clip rectangles therefore must have a size that is some multiple of 32. + + glScissor(0, 0, 32, 32) allows only the 'tile' in the lower left + hand corner of the screen to be modified and glScissor(0, 0, 0, 0) + disallows modification to all 'tiles' on the screen. +*/ +void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height) { + /*!!! FIXME: Shouldn't this be added to *all* lists? */ + PVRTileClipCommand *c = aligned_vector_extend(&activePolyList()->vector, 1); + + GLint miny, maxx, maxy; + GLsizei gl_scissor_width = CLAMP(width, 0, vid_mode->width); + GLsizei gl_scissor_height = CLAMP(height, 0, vid_mode->height); + + /* force the origin to the lower left-hand corner of the screen */ + miny = (vid_mode->height - gl_scissor_height) - y; + maxx = (gl_scissor_width + x); + maxy = (gl_scissor_height + miny); + + /* load command structure while mapping screen coords to TA tiles */ + c->flags = PVR_CMD_USERCLIP; + c->d1 = c->d2 = c->d3 = 0; + c->sx = CLAMP(x / 32, 0, vid_mode->width / 32); + c->sy = CLAMP(miny / 32, 0, vid_mode->height / 32); + c->ex = CLAMP((maxx / 32) - 1, 0, vid_mode->width / 32); + c->ey = CLAMP((maxy / 32) - 1, 0, vid_mode->height / 32); +} + diff --git a/experimental/texture.c b/experimental/texture.c new file mode 100644 index 0000000..4a51d3d --- /dev/null +++ b/experimental/texture.c @@ -0,0 +1,620 @@ +#include "private.h" +#include "../include/glext.h" +#include + +#define CLAMP_U (1<<1) +#define CLAMP_V (1<<0) + +static TextureObject* TEXTURE_UNITS[MAX_TEXTURE_UNITS] = {NULL, NULL}; +static NamedArray TEXTURE_OBJECTS; +static GLubyte ACTIVE_TEXTURE = 0; + +static GLuint _determinePVRFormat(GLint internalFormat, GLenum type); + +GLubyte _glKosInitTextures() { + named_array_init(&TEXTURE_OBJECTS, sizeof(TextureObject), 256); + return 1; +} + +TextureObject* getTexture0() { + return TEXTURE_UNITS[0]; +} + +TextureObject* getTexture1() { + return TEXTURE_UNITS[1]; +} + +TextureObject* getBoundTexture() { + return TEXTURE_UNITS[ACTIVE_TEXTURE]; +} + +GLubyte check_valid_enum(GLint param, GLenum* values, const char* func) { + GLubyte found = 0; + while(*values != 0) { + if(*values == param) { + found++; + break; + } + values++; + } + + if(!found) { + _glKosThrowError(GL_INVALID_ENUM, func); + _glKosPrintError(); + return 1; + } + + return 0; +} + + +void APIENTRY glActiveTextureARB(GLenum texture) { + TRACE(); + + if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + MAX_TEXTURE_UNITS) + _glKosThrowError(GL_INVALID_ENUM, "glActiveTextureARB"); + + if(_glKosHasError()) { + _glKosPrintError(); + return; + } + + ACTIVE_TEXTURE = texture & 0xF; +} + +void APIENTRY glGenTextures(GLsizei n, GLuint *textures) { + TRACE(); + + while(n--) { + GLuint id = 0; + TextureObject* txr = (TextureObject*) named_array_alloc(&TEXTURE_OBJECTS, &id); + txr->index = id; + txr->width = txr->height = 0; + txr->mip_map = 0; + txr->uv_clamp = 0; + txr->env = PVR_TXRENV_MODULATEALPHA; + txr->filter = PVR_FILTER_NONE; + txr->data = NULL; + + *textures = id; + + textures++; + } +} + +void APIENTRY glDeleteTextures(GLsizei n, GLuint *textures) { + TRACE(); + + while(n--) { + TextureObject* txr = (TextureObject*) named_array_get(&TEXTURE_OBJECTS, *textures); + + if(txr == TEXTURE_UNITS[ACTIVE_TEXTURE]) { + TEXTURE_UNITS[ACTIVE_TEXTURE] = NULL; + } + + if(txr->data) { + pvr_mem_free(txr->data); + } + + named_array_release(&TEXTURE_OBJECTS, *textures++); + } +} + +void APIENTRY glBindTexture(GLenum target, GLuint texture) { + TRACE(); + + GLenum target_values [] = {GL_TEXTURE_2D, 0}; + + if(check_valid_enum(target, target_values, __func__) != 0) { + return; + } + + if(texture) { + TEXTURE_UNITS[ACTIVE_TEXTURE] = (TextureObject*) named_array_get(&TEXTURE_OBJECTS, texture); + } else { + TEXTURE_UNITS[ACTIVE_TEXTURE] = NULL; + } +} + +void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) { + TRACE(); + + GLenum target_values [] = {GL_TEXTURE_ENV, 0}; + GLenum pname_values [] = {GL_TEXTURE_ENV_MODE, 0}; + GLenum param_values [] = {GL_MODULATE, GL_DECAL, GL_REPLACE, 0}; + + GLubyte failures = 0; + + failures += check_valid_enum(target, target_values, __func__); + failures += check_valid_enum(pname, pname_values, __func__); + failures += check_valid_enum(param, param_values, __func__); + + TextureObject* active = TEXTURE_UNITS[ACTIVE_TEXTURE]; + + if(!active) { + return; + } + + if(failures) { + return; + } + + switch(param) { + case GL_MODULATE: + active->env = PVR_TXRENV_MODULATEALPHA; + break; + case GL_DECAL: + active->env = PVR_TXRENV_DECAL; + break; + case GL_REPLACE: + active->env = PVR_TXRENV_REPLACE; + break; + default: + break; + } +} + +void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param) { + glTexEnvi(target, pname, param); +} + +void APIENTRY glCompressedTexImage2D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const GLvoid *data) { + TRACE(); + + if(target != GL_TEXTURE_2D) + _glKosThrowError(GL_INVALID_ENUM, "glCompressedTexImage2D"); + + if(level < 0) + _glKosThrowError(GL_INVALID_VALUE, "glCompressedTexImage2D"); + + if(border) + _glKosThrowError(GL_INVALID_VALUE, "glCompressedTexImage2D"); + + if(internalformat != GL_UNSIGNED_SHORT_5_6_5_VQ_KOS) + if(internalformat != GL_UNSIGNED_SHORT_5_6_5_VQ_TWID_KOS) + if(internalformat != GL_UNSIGNED_SHORT_4_4_4_4_VQ_KOS) + if(internalformat != GL_UNSIGNED_SHORT_4_4_4_4_REV_VQ_TWID_KOS) + if(internalformat != GL_UNSIGNED_SHORT_1_5_5_5_REV_VQ_KOS) + if(internalformat != GL_UNSIGNED_SHORT_1_5_5_5_REV_VQ_TWID_KOS) + _glKosThrowError(GL_INVALID_OPERATION, "glCompressedTexImage2D"); + + if(TEXTURE_UNITS[ACTIVE_TEXTURE] == NULL) + _glKosThrowError(GL_INVALID_OPERATION, "glCompressedTexImage2D"); + + if(_glKosHasError()) { + _glKosPrintError(); + return; + } + + TextureObject* active = TEXTURE_UNITS[ACTIVE_TEXTURE]; + + active->width = width; + active->height = height; + active->mip_map = level; + active->color = _determinePVRFormat( + internalformat, + internalformat /* Doesn't matter (see determinePVRFormat) */ + ); + + /* Odds are slim new data is same size as old, so free always */ + if(active->data) + pvr_mem_free(active->data); + + active->data = pvr_mem_malloc(imageSize); + + if(data) + sq_cpy(active->data, data, imageSize); +} + +static GLint _cleanInternalFormat(GLint internalFormat) { + switch (internalFormat) { + case GL_ALPHA: +/* case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16:*/ + return GL_ALPHA; + case 1: + case GL_LUMINANCE: +/* case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16:*/ + return GL_LUMINANCE; + case 2: + case GL_LUMINANCE_ALPHA: +/* case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: */ + return GL_LUMINANCE_ALPHA; +/* case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + return GL_INTENSITY; */ + case 3: + return GL_RGB; + case GL_RGB: +/* case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: */ + return GL_RGB; + case 4: + return GL_RGBA; + case GL_RGBA: +/* case GL_RGBA2: + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: */ + return GL_RGBA; + + /* Support ARB_texture_rg */ + case GL_RED: +/* case GL_R8: + case GL_R16: + case GL_RED: + case GL_COMPRESSED_RED: */ + return GL_RED; +/* case GL_RG: + case GL_RG8: + case GL_RG16: + case GL_COMPRESSED_RG: + return GL_RG;*/ + default: + return -1; + } +} + +static GLuint _determinePVRFormat(GLint internalFormat, GLenum type) { + /* Given a cleaned internalFormat, return the Dreamcast format + * that can hold it + */ + switch(internalFormat) { + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + /* OK so if we have something that requires alpha, we return 4444 unless + * the type was already 1555 (1-bit alpha) in which case we return that + */ + return (type == GL_UNSIGNED_SHORT_1_5_5_5_REV) ? + PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_NONTWIDDLED : + PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_NONTWIDDLED; + case GL_RED: + case GL_RGB: + /* No alpha? Return RGB565 which is the best we can do without using palettes */ + return PVR_TXRFMT_RGB565 | PVR_TXRFMT_NONTWIDDLED; + /* Compressed and twiddled versions */ + case GL_UNSIGNED_SHORT_5_6_5_TWID_KOS: + return PVR_TXRFMT_RGB565 | PVR_TXRFMT_TWIDDLED; + case GL_UNSIGNED_SHORT_5_6_5_VQ_KOS: + return PVR_TXRFMT_RGB565 | PVR_TXRFMT_NONTWIDDLED | PVR_TXRFMT_VQ_ENABLE; + case GL_UNSIGNED_SHORT_5_6_5_VQ_TWID_KOS: + return PVR_TXRFMT_RGB565 | PVR_TXRFMT_TWIDDLED | PVR_TXRFMT_VQ_ENABLE; + case GL_UNSIGNED_SHORT_4_4_4_4_REV_TWID_KOS: + return PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_TWIDDLED; + case GL_UNSIGNED_SHORT_4_4_4_4_REV_VQ_TWID_KOS: + return PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_TWIDDLED | PVR_TXRFMT_VQ_ENABLE; + case GL_UNSIGNED_SHORT_4_4_4_4_VQ_KOS: + return PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_NONTWIDDLED | PVR_TXRFMT_VQ_ENABLE; + case GL_UNSIGNED_SHORT_1_5_5_5_REV_TWID_KOS: + return PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_TWIDDLED; + case GL_UNSIGNED_SHORT_1_5_5_5_REV_VQ_KOS: + return PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_NONTWIDDLED | PVR_TXRFMT_VQ_ENABLE; + case GL_UNSIGNED_SHORT_1_5_5_5_REV_VQ_TWID_KOS: + return PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_TWIDDLED | PVR_TXRFMT_VQ_ENABLE; + default: + return 0; + } +} + + +typedef void (*TextureConversionFunc)(const GLubyte*, GLushort*); + +static void _rgba8888_to_argb4444(const GLubyte* source, GLushort* dest) { + *dest = (source[3] & 0xF0) << 8 | (source[0] & 0xF0) << 4 | (source[1] & 0xF0) | (source[2] & 0xF0) >> 4; +} + +static void _rgb888_to_rgb565(const GLubyte* source, GLushort* dest) { + *dest = ((source[0] & 0b11111000) << 8) | ((source[1] & 0b11111100) << 3) | (source[2] >> 3); +} + +static void _rgba8888_to_a000(const GLubyte* source, GLushort* dest) { + *dest = ((source[3] & 0b11111000) << 8); +} + +static void _r8_to_rgb565(const GLubyte* source, GLushort* dest) { + *dest = (source[0] & 0b11111000) << 8; +} + +static void _rgba4444_to_argb4444(const GLubyte* source, GLushort* dest) { + GLushort* src = (GLushort*) source; + *dest = ((*src & 0x000F) << 12) | *src >> 4; +} + +static TextureConversionFunc _determineConversion(GLint internalFormat, GLenum format, GLenum type) { + switch(internalFormat) { + case GL_ALPHA: { + if(type == GL_UNSIGNED_BYTE && format == GL_RGBA) { + return _rgba8888_to_a000; + } else if(type == GL_BYTE && format == GL_RGBA) { + return _rgba8888_to_a000; + } + } break; + case GL_RGB: { + if(type == GL_UNSIGNED_BYTE && format == GL_RGB) { + return _rgb888_to_rgb565; + } else if(type == GL_BYTE && format == GL_RGB) { + return _rgb888_to_rgb565; + } else if(type == GL_UNSIGNED_BYTE && format == GL_RED) { + return _r8_to_rgb565; + } + } break; + case GL_RGBA: { + if(type == GL_UNSIGNED_BYTE && format == GL_RGBA) { + return _rgba8888_to_argb4444; + } else if (type == GL_BYTE && format == GL_RGBA) { + return _rgba8888_to_argb4444; + } else if(type == GL_UNSIGNED_SHORT_4_4_4_4 && format == GL_RGBA) { + return _rgba4444_to_argb4444; + } + } break; + default: + fprintf(stderr, "Unsupported conversion: %d -> %d, %d", internalFormat, format, type); + break; + } + return 0; +} + +static GLint _determineStride(GLenum format, GLenum type) { + switch(type) { + case GL_BYTE: + case GL_UNSIGNED_BYTE: + return (format == GL_RED) ? 1 : (format == GL_RGB) ? 3 : 4; + case GL_UNSIGNED_SHORT: + return (format == GL_RED) ? 2 : (format == GL_RGB) ? 6 : 8; + case GL_UNSIGNED_SHORT_5_6_5_REV: + case GL_UNSIGNED_SHORT_5_6_5_TWID_KOS: + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV_TWID_KOS: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV_TWID_KOS: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + return 2; + } + + return -1; +} + +static GLboolean _isSupportedFormat(GLenum format) { + switch(format) { + case GL_RED: + case GL_RGB: + case GL_RGBA: + case GL_BGRA: + return GL_TRUE; + default: + return GL_FALSE; + } +} + + +void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, + GLsizei width, GLsizei height, GLint border, + GLenum format, GLenum type, const GLvoid *data) { + + TRACE(); + + if(target != GL_TEXTURE_2D) { + _glKosThrowError(GL_INVALID_ENUM, "glTexImage2D"); + } + + if(!_isSupportedFormat(format)) { + _glKosThrowError(GL_INVALID_ENUM, "glTexImage2D"); + } + + /* Abuse determineStride to see if type is valid */ + if(_determineStride(GL_RGBA, type) == -1) { + _glKosThrowError(GL_INVALID_ENUM, "glTexImage2D"); + } + + internalFormat = _cleanInternalFormat(internalFormat); + if(internalFormat == -1) { + _glKosThrowError(GL_INVALID_VALUE, "glTexImage2D"); + } + + GLint w = width; + if(w == 0 || (w & -w) != w) { + /* Width is not a power of two. Must be!*/ + _glKosThrowError(GL_INVALID_VALUE, "glTexImage2D"); + } + + GLint h = height; + if(h == 0 || (h & -h) != h) { + /* height is not a power of two. Must be!*/ + _glKosThrowError(GL_INVALID_VALUE, "glTexImage2D"); + } + + if(level < 0) { + _glKosThrowError(GL_INVALID_VALUE, "glTexImage2D"); + } + + if(border) { + _glKosThrowError(GL_INVALID_VALUE, "glTexImage2D"); + } + + if(!TEXTURE_UNITS[ACTIVE_TEXTURE]) { + _glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D"); + } + + if(_glKosHasError()) { + _glKosPrintError(); + return; + } + + /* Calculate the format that we need to convert the data to */ + GLuint pvr_format = _determinePVRFormat(internalFormat, type); + + TextureObject* active = TEXTURE_UNITS[ACTIVE_TEXTURE]; + + if(active->data) { + /* pre-existing texture - check if changed */ + if(active->width != width || + active->height != height || + active->mip_map != level || + active->color != pvr_format) { + /* changed - free old texture memory */ + pvr_mem_free(active->data); + active->data = NULL; + } + } + + GLuint bytes = level ? glKosMipMapTexSize(width, height) : (width * height * 2); + + if(!active->data) { + /* need texture memory */ + active->width = width; + active->height = height; + active->mip_map = level; + active->color = pvr_format; + active->data = pvr_mem_malloc(bytes); + } + + /* Let's assume we need to convert */ + GLboolean needsConversion = GL_TRUE; + + /* + * 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 + */ + if(format == GL_BGRA && type == GL_UNSIGNED_SHORT_4_4_4_4_REV && internalFormat == GL_RGBA) { + needsConversion = GL_FALSE; + } else if(format == GL_BGRA && type == GL_UNSIGNED_SHORT_1_5_5_5_REV && internalFormat == GL_RGBA) { + needsConversion = GL_FALSE; + } else if(format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 && internalFormat == GL_RGB) { + needsConversion = GL_FALSE; + } else if(format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5_TWID_KOS && internalFormat == GL_RGB) { + needsConversion = GL_FALSE; + } else if(format == GL_BGRA && type == GL_UNSIGNED_SHORT_1_5_5_5_REV_TWID_KOS && internalFormat == GL_RGBA) { + needsConversion = GL_FALSE; + } else if(format == GL_BGRA && type == GL_UNSIGNED_SHORT_4_4_4_4_REV_TWID_KOS && internalFormat == GL_RGBA) { + needsConversion = GL_FALSE; + } + + if(!data) { + /* No data? Do nothing! */ + return; + } else if(!needsConversion) { + /* No conversion? Just copy the data, and the pvr_format is correct */ + sq_cpy(active->data, data, bytes); + return; + } else { + TextureConversionFunc convert = _determineConversion( + internalFormat, + format, + type + ); + + if(!convert) { + _glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D"); + return; + } + + GLushort* dest = active->data; + const GLubyte* source = data; + GLint stride = _determineStride(format, type); + + if(stride == -1) { + _glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D"); + return; + } + + /* Perform the conversion */ + for(GLuint i = 0; i < bytes; i += 2) { + convert(source, dest); + + dest++; + source += stride; + } + } +} + +void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) { + TRACE(); + + TextureObject* active = getBoundTexture(); + + if(target == GL_TEXTURE_2D) { + switch(pname) { + case GL_TEXTURE_MAG_FILTER: + case GL_TEXTURE_MIN_FILTER: + switch(param) { + case GL_LINEAR: + active->filter = PVR_FILTER_BILINEAR; + break; + + case GL_NEAREST: + active->filter = PVR_FILTER_NEAREST; + break; + + case GL_FILTER_NONE: + active->filter = PVR_FILTER_NONE; + break; + + case GL_FILTER_BILINEAR: + active->filter = PVR_FILTER_BILINEAR; + break; + + default: + break; + } + + break; + + case GL_TEXTURE_WRAP_S: + switch(param) { + case GL_CLAMP: + active->uv_clamp |= CLAMP_U; + break; + + case GL_REPEAT: + active->uv_clamp &= ~CLAMP_U; + break; + } + + break; + + case GL_TEXTURE_WRAP_T: + switch(param) { + case GL_CLAMP: + active->uv_clamp |= CLAMP_V; + break; + + case GL_REPEAT: + active->uv_clamp &= ~CLAMP_V; + break; + } + + break; + } + } +} diff --git a/gl-api.c b/gl-api.c index db3ade4..0f82665 100644 --- a/gl-api.c +++ b/gl-api.c @@ -52,188 +52,188 @@ static inline void _glKosFinishRect(); //====================================================================================================// //== API Initialization ==// -void APIENTRY glKosInit() { - _glKosInitPVR(); +//void APIENTRY glKosInit() { +// _glKosInitPVR(); - _glKosInitTextures(); +// _glKosInitTextures(); - _glKosInitMatrix(); +// _glKosInitMatrix(); - _glKosInitLighting(); +// _glKosInitLighting(); - _glKosInitFrameBuffers(); -} +// _glKosInitFrameBuffers(); +//} //====================================================================================================// //== Blending / Shading functions ==// -void APIENTRY glShadeModel(GLenum mode) { - switch(mode) { - case GL_FLAT: - GL_KOS_SHADE_FUNC = PVR_SHADE_FLAT; - break; +//void APIENTRY glShadeModel(GLenum mode) { +// switch(mode) { +// case GL_FLAT: +// GL_KOS_SHADE_FUNC = PVR_SHADE_FLAT; +// break; - case GL_SMOOTH: - GL_KOS_SHADE_FUNC = PVR_SHADE_GOURAUD; - break; - } -} +// case GL_SMOOTH: +// GL_KOS_SHADE_FUNC = PVR_SHADE_GOURAUD; +// break; +// } +//} -void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor) { - GL_KOS_BLEND_FUNC = 0; +//void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor) { +// GL_KOS_BLEND_FUNC = 0; - switch(sfactor) { - case GL_ONE: - GL_KOS_BLEND_FUNC |= (PVR_BLEND_ONE & 0XF) << 4; - break; +// switch(sfactor) { +// case GL_ONE: +// GL_KOS_BLEND_FUNC |= (PVR_BLEND_ONE & 0XF) << 4; +// break; - case GL_ZERO: - GL_KOS_BLEND_FUNC |= (PVR_BLEND_ZERO & 0XF) << 4; - break; +// case GL_ZERO: +// GL_KOS_BLEND_FUNC |= (PVR_BLEND_ZERO & 0XF) << 4; +// break; - case GL_SRC_COLOR: - GL_KOS_BLEND_FUNC |= (PVR_BLEND_SRCALPHA & 0XF) << 4; - break; +// case GL_SRC_COLOR: +// GL_KOS_BLEND_FUNC |= (PVR_BLEND_SRCALPHA & 0XF) << 4; +// break; - case GL_DST_COLOR: - GL_KOS_BLEND_FUNC |= (PVR_BLEND_DESTCOLOR & 0XF) << 4; - break; +// case GL_DST_COLOR: +// GL_KOS_BLEND_FUNC |= (PVR_BLEND_DESTCOLOR & 0XF) << 4; +// break; - case GL_SRC_ALPHA: - GL_KOS_BLEND_FUNC |= (PVR_BLEND_SRCALPHA << 4); - break; +// case GL_SRC_ALPHA: +// GL_KOS_BLEND_FUNC |= (PVR_BLEND_SRCALPHA << 4); +// break; - case GL_DST_ALPHA: - GL_KOS_BLEND_FUNC |= (PVR_BLEND_DESTALPHA & 0XF) << 4; - break; +// case GL_DST_ALPHA: +// GL_KOS_BLEND_FUNC |= (PVR_BLEND_DESTALPHA & 0XF) << 4; +// break; - case GL_ONE_MINUS_SRC_ALPHA: - GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVSRCALPHA & 0XF) << 4; - break; +// case GL_ONE_MINUS_SRC_ALPHA: +// GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVSRCALPHA & 0XF) << 4; +// break; - case GL_ONE_MINUS_DST_ALPHA: - GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVDESTALPHA & 0XF) << 4; - break; +// case GL_ONE_MINUS_DST_ALPHA: +// GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVDESTALPHA & 0XF) << 4; +// break; - case GL_ONE_MINUS_DST_COLOR: - GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVDESTCOLOR & 0XF) << 4; - break; - } +// case GL_ONE_MINUS_DST_COLOR: +// GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVDESTCOLOR & 0XF) << 4; +// break; +// } - switch(dfactor) { - case GL_ONE: - GL_KOS_BLEND_FUNC |= (PVR_BLEND_ONE & 0XF); - break; +// switch(dfactor) { +// case GL_ONE: +// GL_KOS_BLEND_FUNC |= (PVR_BLEND_ONE & 0XF); +// break; - case GL_ZERO: - GL_KOS_BLEND_FUNC |= (PVR_BLEND_ZERO & 0XF); - break; +// case GL_ZERO: +// GL_KOS_BLEND_FUNC |= (PVR_BLEND_ZERO & 0XF); +// break; - case GL_SRC_COLOR: - GL_KOS_BLEND_FUNC |= (PVR_BLEND_SRCALPHA & 0XF); - break; +// case GL_SRC_COLOR: +// GL_KOS_BLEND_FUNC |= (PVR_BLEND_SRCALPHA & 0XF); +// break; - case GL_DST_COLOR: - GL_KOS_BLEND_FUNC |= (PVR_BLEND_DESTCOLOR & 0XF); - break; +// case GL_DST_COLOR: +// GL_KOS_BLEND_FUNC |= (PVR_BLEND_DESTCOLOR & 0XF); +// break; - case GL_SRC_ALPHA: - GL_KOS_BLEND_FUNC |= (PVR_BLEND_SRCALPHA & 0XF); - break; +// case GL_SRC_ALPHA: +// GL_KOS_BLEND_FUNC |= (PVR_BLEND_SRCALPHA & 0XF); +// break; - case GL_DST_ALPHA: - GL_KOS_BLEND_FUNC |= (PVR_BLEND_DESTALPHA & 0XF); - break; +// case GL_DST_ALPHA: +// GL_KOS_BLEND_FUNC |= (PVR_BLEND_DESTALPHA & 0XF); +// break; - case GL_ONE_MINUS_SRC_ALPHA: - GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVSRCALPHA & 0XF); - break; +// case GL_ONE_MINUS_SRC_ALPHA: +// GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVSRCALPHA & 0XF); +// break; - case GL_ONE_MINUS_DST_ALPHA: - GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVDESTALPHA & 0XF); - break; +// case GL_ONE_MINUS_DST_ALPHA: +// GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVDESTALPHA & 0XF); +// break; - case GL_ONE_MINUS_DST_COLOR: - GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVDESTCOLOR & 0XF); - break; - } -} +// case GL_ONE_MINUS_DST_COLOR: +// GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVDESTCOLOR & 0XF); +// break; +// } +//} //====================================================================================================// //== Depth / Clear functions ==// -void APIENTRY glClear(GLuint mode) { - if(mode & GL_COLOR_BUFFER_BIT) - pvr_set_bg_color(GL_KOS_COLOR_CLEAR[0], GL_KOS_COLOR_CLEAR[1], GL_KOS_COLOR_CLEAR[2]); -} +//void APIENTRY glClear(GLuint mode) { +// if(mode & GL_COLOR_BUFFER_BIT) +// pvr_set_bg_color(GL_KOS_COLOR_CLEAR[0], GL_KOS_COLOR_CLEAR[1], GL_KOS_COLOR_CLEAR[2]); +//} -void APIENTRY glClearColor(float r, float g, float b, float a) { - if(r > 1) r = 1; +//void APIENTRY glClearColor(float r, float g, float b, float a) { +// if(r > 1) r = 1; - if(g > 1) g = 1; +// if(g > 1) g = 1; - if(b > 1) b = 1; +// if(b > 1) b = 1; - if(a > 1) a = 1; +// if(a > 1) a = 1; - GL_KOS_COLOR_CLEAR[0] = r * a; - GL_KOS_COLOR_CLEAR[1] = g * a; - GL_KOS_COLOR_CLEAR[2] = b * a; -} +// GL_KOS_COLOR_CLEAR[0] = r * a; +// GL_KOS_COLOR_CLEAR[1] = g * a; +// GL_KOS_COLOR_CLEAR[2] = b * a; +//} //== NoOp ==// -void APIENTRY glClearDepthf(GLfloat depth) { - ; -} +//void APIENTRY glClearDepthf(GLfloat depth) { +// ; +//} -void APIENTRY glDepthFunc(GLenum func) { - switch(func) { - case GL_LESS: - GL_KOS_DEPTH_FUNC = PVR_DEPTHCMP_GEQUAL; - break; +//void APIENTRY glDepthFunc(GLenum func) { +// switch(func) { +// case GL_LESS: +// GL_KOS_DEPTH_FUNC = PVR_DEPTHCMP_GEQUAL; +// break; - case GL_LEQUAL: - GL_KOS_DEPTH_FUNC = PVR_DEPTHCMP_GREATER; - break; +// case GL_LEQUAL: +// GL_KOS_DEPTH_FUNC = PVR_DEPTHCMP_GREATER; +// break; - case GL_GREATER: - GL_KOS_DEPTH_FUNC = PVR_DEPTHCMP_LEQUAL; - break; +// case GL_GREATER: +// GL_KOS_DEPTH_FUNC = PVR_DEPTHCMP_LEQUAL; +// break; - case GL_GEQUAL: - GL_KOS_DEPTH_FUNC = PVR_DEPTHCMP_LESS; - break; +// case GL_GEQUAL: +// GL_KOS_DEPTH_FUNC = PVR_DEPTHCMP_LESS; +// break; - default: - GL_KOS_DEPTH_FUNC = (func & 0x0F); - } -} +// default: +// GL_KOS_DEPTH_FUNC = (func & 0x0F); +// } +//} -void APIENTRY glDepthMask(GLboolean flag) { - GL_KOS_DEPTH_WRITE = (flag == GL_TRUE) ? PVR_DEPTHWRITE_ENABLE : PVR_DEPTHWRITE_DISABLE; -} +//void APIENTRY glDepthMask(GLboolean flag) { +// GL_KOS_DEPTH_WRITE = (flag == GL_TRUE) ? PVR_DEPTHWRITE_ENABLE : PVR_DEPTHWRITE_DISABLE; +//} //====================================================================================================// //== Culling functions ==// -void APIENTRY glFrontFace(GLenum mode) { - switch(mode) { - case GL_CW: - case GL_CCW: - GL_KOS_FACE_FRONT = mode; - break; - } -} +//void APIENTRY glFrontFace(GLenum mode) { +// switch(mode) { +// case GL_CW: +// case GL_CCW: +// GL_KOS_FACE_FRONT = mode; +// break; +// } +//} -void APIENTRY glCullFace(GLenum mode) { - switch(mode) { - case GL_FRONT: - case GL_BACK: - case GL_FRONT_AND_BACK: - GL_KOS_CULL_FUNC = mode; - break; - } -} +//void APIENTRY glCullFace(GLenum mode) { +// switch(mode) { +// case GL_FRONT: +// case GL_BACK: +// case GL_FRONT_AND_BACK: +// GL_KOS_CULL_FUNC = mode; +// break; +// } +//} //====================================================================================================// //== Vertex Attributes Submission Functions ==// @@ -461,56 +461,20 @@ void APIENTRY glEnd() { //== Misc. functions ==// /* Clamp X to [MIN,MAX]: */ -#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) ) -/* Setup the hardware user clip rectangle. - The minimum clip rectangle is a 32x32 area which is dependent on the tile - size use by the tile accelerator. The PVR swithes off rendering to tiles - outside or inside the defined rectangle dependant upon the 'clipmode' - bits in the polygon header. +//void APIENTRY glHint(GLenum target, GLenum mode) { +// switch(target) { +// case GL_PERSPECTIVE_CORRECTION_HINT: +// if(mode == GL_NICEST) +// GL_KOS_SUPERSAMPLE = 1; +// else +// GL_KOS_SUPERSAMPLE = 0; - Clip rectangles therefore must have a size that is some multiple of 32. +// break; +// } - glScissor(0, 0, 32, 32) allows only the 'tile' in the lower left - hand corner of the screen to be modified and glScissor(0, 0, 0, 0) - disallows modification to all 'tiles' on the screen. -*/ -void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height) { - pvr_cmd_tclip_t *c = _glKosVertexBufPointer(); - - GLint miny, maxx, maxy; - GLsizei gl_scissor_width = CLAMP(width, 0, vid_mode->width); - GLsizei gl_scissor_height = CLAMP(height, 0, vid_mode->height); - - /* force the origin to the lower left-hand corner of the screen */ - miny = (vid_mode->height - gl_scissor_height) - y; - maxx = (gl_scissor_width + x); - maxy = (gl_scissor_height + miny); - - /* load command structure while mapping screen coords to TA tiles */ - c->flags = PVR_CMD_USERCLIP; - c->d1 = c->d2 = c->d3 = 0; - c->sx = CLAMP(x / 32, 0, vid_mode->width / 32); - c->sy = CLAMP(miny / 32, 0, vid_mode->height / 32); - c->ex = CLAMP((maxx / 32) - 1, 0, vid_mode->width / 32); - c->ey = CLAMP((maxy / 32) - 1, 0, vid_mode->height / 32); - - _glKosVertexBufIncrement(); -} - -void APIENTRY glHint(GLenum target, GLenum mode) { - switch(target) { - case GL_PERSPECTIVE_CORRECTION_HINT: - if(mode == GL_NICEST) - GL_KOS_SUPERSAMPLE = 1; - else - GL_KOS_SUPERSAMPLE = 0; - - break; - } - -} +//} //====================================================================================================// //== Internal API Vertex Submission functions ==// @@ -944,26 +908,3 @@ GLuint _glKosVertexColor() { return GL_KOS_VERTEX_COLOR; } -void glAlphaFunc(GLenum func, GLclampf ref) { - ; -} - -void glLineWidth(GLfloat width) { - ; -} - -void glPolygonOffset(GLfloat factor, GLfloat units) { - ; -} - -void glGetTexParameteriv(GLenum target, GLenum pname, GLint *params) { - ; -} - -void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { - ; -} - -void glPixelStorei(GLenum pname, GLint param) { - ; -} diff --git a/gl-api.h b/gl-api.h index 421c02b..f8e2751 100644 --- a/gl-api.h +++ b/gl-api.h @@ -171,7 +171,7 @@ uint16 __glKosAverageBiPixelARGB4444(uint16 p1, uint16 p2); void _glKosInitFrameBuffers(); /* Error Codes */ -void _glKosThrowError(GLenum error, char *functionName); +void _glKosThrowError(GLenum error, const char *functionName); void _glKosPrintError(); GLubyte _glKosHasError(); @@ -208,6 +208,7 @@ GLubyte _glKosMaxTextureUnits(); GLubyte _glKosEnabledTextureMatrix(); GL_TEXTURE_OBJECT *_glKosBoundMultiTexObject(); +GL_TEXTURE_OBJECT *_glKosBoundTexObject(); GLuint _glKosActiveTextureBoundTexID(); void _glKosPushMultiTexObject(GL_TEXTURE_OBJECT *tex, diff --git a/gl-arrays.c b/gl-arrays.c index 8e144ba..ba33911 100644 --- a/gl-arrays.c +++ b/gl-arrays.c @@ -90,104 +90,104 @@ static inline GLushort _calculate_byte_size(GLenum type) { //== Open GL API Public Functions ==// /* Submit a Vertex Position Pointer */ -GLAPI void APIENTRY glVertexPointer(GLint size, GLenum type, - GLsizei stride, const GLvoid *pointer) { - if(size != 2) /* Expect 2D X,Y or 3D X,Y,Z vertex... */ - if(size != 3) - _glKosThrowError(GL_INVALID_VALUE, "glVertexPointer"); +//GLAPI void APIENTRY glVertexPointer(GLint size, GLenum type, +// GLsizei stride, const GLvoid *pointer) { +// if(size != 2) /* Expect 2D X,Y or 3D X,Y,Z vertex... */ +// if(size != 3) +// _glKosThrowError(GL_INVALID_VALUE, "glVertexPointer"); - if(type != GL_FLOAT) /* Expect Floating point vertices */ - _glKosThrowError(GL_INVALID_ENUM, "glVertexPointer"); +// if(type != GL_FLOAT) /* Expect Floating point vertices */ +// _glKosThrowError(GL_INVALID_ENUM, "glVertexPointer"); - if(stride < 0) - _glKosThrowError(GL_INVALID_VALUE, "glVertexPointer"); +// if(stride < 0) +// _glKosThrowError(GL_INVALID_VALUE, "glVertexPointer"); - if(_glKosHasError()) { - _glKosPrintError(); - return; - } +// if(_glKosHasError()) { +// _glKosPrintError(); +// return; +// } - GL_KOS_VERTEX_SIZE = size; +// GL_KOS_VERTEX_SIZE = size; - GL_KOS_VERTEX_STRIDE = (stride) ? stride : _calculate_byte_size(type) * size; - GL_KOS_VERTEX_POINTER = (GLubyte *)pointer; -} +// GL_KOS_VERTEX_STRIDE = (stride) ? stride : _calculate_byte_size(type) * size; +// GL_KOS_VERTEX_POINTER = (GLubyte *)pointer; +//} -/* Submit a Vertex Normal Pointer */ -GLAPI void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer) { - if(type != GL_FLOAT) /* Expect Floating point vertices */ - _glKosThrowError(GL_INVALID_ENUM, "glNormalPointer"); +///* Submit a Vertex Normal Pointer */ +//GLAPI void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer) { +// if(type != GL_FLOAT) /* Expect Floating point vertices */ +// _glKosThrowError(GL_INVALID_ENUM, "glNormalPointer"); - if(stride < 0) - _glKosThrowError(GL_INVALID_VALUE, "glNormalPointer"); +// if(stride < 0) +// _glKosThrowError(GL_INVALID_VALUE, "glNormalPointer"); - if(_glKosHasError()) { - _glKosPrintError(); - return; - } +// if(_glKosHasError()) { +// _glKosPrintError(); +// return; +// } - GL_KOS_NORMAL_STRIDE = (stride) ? stride : _calculate_byte_size(type) * 3; - GL_KOS_NORMAL_POINTER = (GLubyte *)pointer; -} +// GL_KOS_NORMAL_STRIDE = (stride) ? stride : _calculate_byte_size(type) * 3; +// GL_KOS_NORMAL_POINTER = (GLubyte *)pointer; +//} -/* Submit a Texture Coordinate Pointer */ -GLAPI void APIENTRY glTexCoordPointer(GLint size, GLenum type, - GLsizei stride, const GLvoid *pointer) { - if(size != 2) /* Expect u and v */ - _glKosThrowError(GL_INVALID_VALUE, "glTexCoordPointer"); +///* Submit a Texture Coordinate Pointer */ +//GLAPI void APIENTRY glTexCoordPointer(GLint size, GLenum type, +// GLsizei stride, const GLvoid *pointer) { +// if(size != 2) /* Expect u and v */ +// _glKosThrowError(GL_INVALID_VALUE, "glTexCoordPointer"); - if(type != GL_FLOAT) /* Expect Floating point vertices */ - _glKosThrowError(GL_INVALID_ENUM, "glTexCoordPointer"); +// if(type != GL_FLOAT) /* Expect Floating point vertices */ +// _glKosThrowError(GL_INVALID_ENUM, "glTexCoordPointer"); - if(stride < 0) - _glKosThrowError(GL_INVALID_VALUE, "glTexCoordPointer"); +// if(stride < 0) +// _glKosThrowError(GL_INVALID_VALUE, "glTexCoordPointer"); - if(_glKosHasError()) { - _glKosPrintError(); - return; - } +// if(_glKosHasError()) { +// _glKosPrintError(); +// return; +// } - if(GL_KOS_CLIENT_ACTIVE_TEXTURE) { - GL_KOS_TEXCOORD1_STRIDE = (stride) ? stride : _calculate_byte_size(type) * size; - GL_KOS_TEXCOORD1_POINTER = (GLubyte *)pointer; - } - else { - GL_KOS_TEXCOORD0_STRIDE = (stride) ? stride : _calculate_byte_size(type) * size; - GL_KOS_TEXCOORD0_POINTER = (GLubyte *)pointer; - } -} +// if(GL_KOS_CLIENT_ACTIVE_TEXTURE) { +// GL_KOS_TEXCOORD1_STRIDE = (stride) ? stride : _calculate_byte_size(type) * size; +// GL_KOS_TEXCOORD1_POINTER = (GLubyte *)pointer; +// } +// else { +// GL_KOS_TEXCOORD0_STRIDE = (stride) ? stride : _calculate_byte_size(type) * size; +// GL_KOS_TEXCOORD0_POINTER = (GLubyte *)pointer; +// } +//} -/* Submit a Color Pointer */ -GLAPI void APIENTRY glColorPointer(GLint size, GLenum type, - GLsizei stride, const GLvoid *pointer) { - if((type == GL_UNSIGNED_INT) && (size == 1)) { - GL_KOS_COLOR_COMPONENTS = size; - GL_KOS_COLOR_POINTER = (GLubyte *)pointer; - GL_KOS_COLOR_TYPE = type; - } - else if((type == GL_UNSIGNED_BYTE) && (size == 4)) { - GL_KOS_COLOR_COMPONENTS = size; - GL_KOS_COLOR_POINTER = (GLubyte *)pointer; - GL_KOS_COLOR_TYPE = type; - } - else if((type == GL_FLOAT) && (size == 3)) { - GL_KOS_COLOR_COMPONENTS = size; - GL_KOS_COLOR_POINTER = (GLubyte *)pointer; - GL_KOS_COLOR_TYPE = type; - } - else if((type == GL_FLOAT) && (size == 4)) { - GL_KOS_COLOR_COMPONENTS = size; - GL_KOS_COLOR_POINTER = (GLubyte *)pointer; - GL_KOS_COLOR_TYPE = type; - } - else { - _glKosThrowError(GL_INVALID_ENUM, "glColorPointer"); - _glKosPrintError(); - return; - } +///* Submit a Color Pointer */ +//GLAPI void APIENTRY glColorPointer(GLint size, GLenum type, +// GLsizei stride, const GLvoid *pointer) { +// if((type == GL_UNSIGNED_INT) && (size == 1)) { +// GL_KOS_COLOR_COMPONENTS = size; +// GL_KOS_COLOR_POINTER = (GLubyte *)pointer; +// GL_KOS_COLOR_TYPE = type; +// } +// else if((type == GL_UNSIGNED_BYTE) && (size == 4)) { +// GL_KOS_COLOR_COMPONENTS = size; +// GL_KOS_COLOR_POINTER = (GLubyte *)pointer; +// GL_KOS_COLOR_TYPE = type; +// } +// else if((type == GL_FLOAT) && (size == 3)) { +// GL_KOS_COLOR_COMPONENTS = size; +// GL_KOS_COLOR_POINTER = (GLubyte *)pointer; +// GL_KOS_COLOR_TYPE = type; +// } +// else if((type == GL_FLOAT) && (size == 4)) { +// GL_KOS_COLOR_COMPONENTS = size; +// GL_KOS_COLOR_POINTER = (GLubyte *)pointer; +// GL_KOS_COLOR_TYPE = type; +// } +// else { +// _glKosThrowError(GL_INVALID_ENUM, "glColorPointer"); +// _glKosPrintError(); +// return; +// } - GL_KOS_COLOR_STRIDE = (stride) ? stride : _calculate_byte_size(type) * size; -} +// GL_KOS_COLOR_STRIDE = (stride) ? stride : _calculate_byte_size(type) * size; +//} //========================================================================================// //== Vertex Pointer Internal API ==// @@ -883,162 +883,162 @@ static inline void _glKosArraysFlush(GLuint count) { //========================================================================================// //== OpenGL Elemental Array Submission ==// -GLAPI void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) { - /* Before we process the vertex data, ensure all parameters are valid */ - if(!_glKosArraysVerifyParameter(mode, count, type, 1)) - return; +//GLAPI void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) { +// /* Before we process the vertex data, ensure all parameters are valid */ +// if(!_glKosArraysVerifyParameter(mode, count, type, 1)) +// return; - /* Compile the PVR polygon context with the currently enabled flags */ - _glKosArraysApplyHeader(); +// /* Compile the PVR polygon context with the currently enabled flags */ +// _glKosArraysApplyHeader(); - /* Destination of Output Vertex Array */ - pvr_vertex_t *dst = _glKosArraysDest(); +// /* Destination of Output Vertex Array */ +// pvr_vertex_t *dst = _glKosArraysDest(); - switch(type) { - case GL_UNSIGNED_BYTE: - GL_KOS_INDEX_POINTER_U8 = (GLubyte *)indices; - break; +// switch(type) { +// case GL_UNSIGNED_BYTE: +// GL_KOS_INDEX_POINTER_U8 = (GLubyte *)indices; +// break; - case GL_UNSIGNED_SHORT: - GL_KOS_INDEX_POINTER_U16 = (GLushort *)indices; - break; - } +// case GL_UNSIGNED_SHORT: +// GL_KOS_INDEX_POINTER_U16 = (GLushort *)indices; +// break; +// } - /* Check if Vertex Lighting is enabled. Else, check for Color Submission */ - if((GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_NORMAL) && _glKosEnabledLighting()) - _glKosArraysApplyLighting(dst, count); +// /* Check if Vertex Lighting is enabled. Else, check for Color Submission */ +// if((GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_NORMAL) && _glKosEnabledLighting()) +// _glKosArraysApplyLighting(dst, count); - else if(GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_COLOR) { - switch(GL_KOS_COLOR_TYPE) { - case GL_FLOAT: - switch(GL_KOS_COLOR_COMPONENTS) { - case 3: - switch(type) { - case GL_UNSIGNED_BYTE: - _glKosElementColor3fU8(dst, count); - break; +// else if(GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_COLOR) { +// switch(GL_KOS_COLOR_TYPE) { +// case GL_FLOAT: +// switch(GL_KOS_COLOR_COMPONENTS) { +// case 3: +// switch(type) { +// case GL_UNSIGNED_BYTE: +// _glKosElementColor3fU8(dst, count); +// break; - case GL_UNSIGNED_SHORT: - _glKosElementColor3fU16(dst, count); - break; - } +// case GL_UNSIGNED_SHORT: +// _glKosElementColor3fU16(dst, count); +// break; +// } - break; +// break; - case 4: - switch(type) { - case GL_UNSIGNED_BYTE: - _glKosElementColor4fU8(dst, count); - break; +// case 4: +// switch(type) { +// case GL_UNSIGNED_BYTE: +// _glKosElementColor4fU8(dst, count); +// break; - case GL_UNSIGNED_SHORT: - _glKosElementColor4fU16(dst, count); - break; - } +// case GL_UNSIGNED_SHORT: +// _glKosElementColor4fU16(dst, count); +// break; +// } - break; - } +// break; +// } - break; +// break; - case GL_UNSIGNED_INT: - if(GL_KOS_COLOR_COMPONENTS == 1) - switch(type) { - case GL_UNSIGNED_BYTE: - _glKosElementColor1uiU8(dst, count); - break; +// case GL_UNSIGNED_INT: +// if(GL_KOS_COLOR_COMPONENTS == 1) +// switch(type) { +// case GL_UNSIGNED_BYTE: +// _glKosElementColor1uiU8(dst, count); +// break; - case GL_UNSIGNED_SHORT: - _glKosElementColor1uiU16(dst, count); - break; - } +// case GL_UNSIGNED_SHORT: +// _glKosElementColor1uiU16(dst, count); +// break; +// } - break; +// break; - case GL_UNSIGNED_BYTE: - if(GL_KOS_COLOR_COMPONENTS == 4) - switch(type) { - case GL_UNSIGNED_BYTE: - _glKosElementColor4ubU8(dst, count); - break; +// case GL_UNSIGNED_BYTE: +// if(GL_KOS_COLOR_COMPONENTS == 4) +// switch(type) { +// case GL_UNSIGNED_BYTE: +// _glKosElementColor4ubU8(dst, count); +// break; - case GL_UNSIGNED_SHORT: - _glKosElementColor4ubU16(dst, count); - break; - } +// case GL_UNSIGNED_SHORT: +// _glKosElementColor4ubU16(dst, count); +// break; +// } - break; - } - } - else - _glKosArrayColor0(dst, count); /* No colors bound */ +// break; +// } +// } +// else +// _glKosArrayColor0(dst, count); /* No colors bound */ - /* Check if Texture Coordinates are enabled */ - if((GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_TEXTURE0) && (_glKosEnabledTexture2D() >= 0)) - switch(type) { - case GL_UNSIGNED_BYTE: - _glKosElementTexCoord2fU8(dst, count); - break; +// /* Check if Texture Coordinates are enabled */ +// if((GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_TEXTURE0) && (_glKosEnabledTexture2D() >= 0)) +// switch(type) { +// case GL_UNSIGNED_BYTE: +// _glKosElementTexCoord2fU8(dst, count); +// break; - case GL_UNSIGNED_SHORT: - _glKosElementTexCoord2fU16(dst, count); - break; - } +// case GL_UNSIGNED_SHORT: +// _glKosElementTexCoord2fU16(dst, count); +// break; +// } - /* Check if Multi Texture Coordinates are enabled */ - if((GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_TEXTURE1) && (_glKosEnabledTexture2D() >= 0)) - switch(type) { - case GL_UNSIGNED_BYTE: - _glKosElementMultiTexCoord2fU8(count); - break; +// /* Check if Multi Texture Coordinates are enabled */ +// if((GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_TEXTURE1) && (_glKosEnabledTexture2D() >= 0)) +// switch(type) { +// case GL_UNSIGNED_BYTE: +// _glKosElementMultiTexCoord2fU8(count); +// break; - case GL_UNSIGNED_SHORT: - _glKosElementMultiTexCoord2fU16(count); - break; - } +// case GL_UNSIGNED_SHORT: +// _glKosElementMultiTexCoord2fU16(count); +// break; +// } - _glKosMatrixApplyRender(); /* Apply the Render Matrix Stack */ +// _glKosMatrixApplyRender(); /* Apply the Render Matrix Stack */ - if(!(_glKosEnabledNearZClip())) {/* Transform the element vertices */ - /* Transform vertices with perspective divide */ - _glKosArraysTransformElements(count); +// if(!(_glKosEnabledNearZClip())) {/* Transform the element vertices */ +// /* Transform vertices with perspective divide */ +// _glKosArraysTransformElements(count); - /* Unpack the indexed positions into primitives for rasterization */ - switch(type) { - case GL_UNSIGNED_BYTE: - _glKosArraysUnpackElementsS8(dst, count); - break; +// /* Unpack the indexed positions into primitives for rasterization */ +// switch(type) { +// case GL_UNSIGNED_BYTE: +// _glKosArraysUnpackElementsS8(dst, count); +// break; - case GL_UNSIGNED_SHORT: - _glKosArraysUnpackElementsS16(dst, count); - break; - } +// case GL_UNSIGNED_SHORT: +// _glKosArraysUnpackElementsS16(dst, count); +// break; +// } - /* Set the vertex flags for use with the PVR */ - _glKosArraysApplyVertexFlags(mode, dst, count); - } - else { - /* Transform vertices with no perspective divide, store w component */ - _glKosArraysTransformClipElements(count); +// /* Set the vertex flags for use with the PVR */ +// _glKosArraysApplyVertexFlags(mode, dst, count); +// } +// else { +// /* Transform vertices with no perspective divide, store w component */ +// _glKosArraysTransformClipElements(count); - /* Unpack the indexed positions into primitives for rasterization */ - switch(type) { - case GL_UNSIGNED_BYTE: - _glKosArraysUnpackClipElementsS8(dst, count); - break; +// /* Unpack the indexed positions into primitives for rasterization */ +// switch(type) { +// case GL_UNSIGNED_BYTE: +// _glKosArraysUnpackClipElementsS8(dst, count); +// break; - case GL_UNSIGNED_SHORT: - _glKosArraysUnpackClipElementsS16(dst, count); - break; - } +// case GL_UNSIGNED_SHORT: +// _glKosArraysUnpackClipElementsS16(dst, count); +// break; +// } - count = _glKosArraysApplyClipping(GL_KOS_ARRAY_BUFUV, 2, mode, count); - } +// count = _glKosArraysApplyClipping(GL_KOS_ARRAY_BUFUV, 2, mode, count); +// } - _glKosArraysApplyMultiTexture(mode, count); +// _glKosArraysApplyMultiTexture(mode, count); - _glKosArraysFlush(count); -} +// _glKosArraysFlush(count); +//} //========================================================================================// //== Array Attribute Functions ==// @@ -1197,151 +1197,97 @@ static void _glKosDrawArrays2D(GLenum mode, GLint first, GLsizei count) { _glKosArraysFlush(count); } -GLAPI void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count) { - /* Before we process the vertex data, ensure all parameters are valid */ - if(!_glKosArraysVerifyParameter(mode, count, first, 0)) - return; - GL_KOS_VERTEX_POINTER += (first * GL_KOS_VERTEX_STRIDE); /* Add Pointer Offset */ - GL_KOS_TEXCOORD0_POINTER += (first * GL_KOS_TEXCOORD0_STRIDE); - GL_KOS_TEXCOORD1_POINTER += (first * GL_KOS_TEXCOORD1_STRIDE); - GL_KOS_COLOR_POINTER += (first * GL_KOS_COLOR_STRIDE); - GL_KOS_NORMAL_POINTER += (first * GL_KOS_NORMAL_STRIDE); +//GLAPI void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count) { +// /* Before we process the vertex data, ensure all parameters are valid */ +// if(!_glKosArraysVerifyParameter(mode, count, first, 0)) +// return; - /* Compile the PVR polygon context with the currently enabled flags */ - _glKosArraysApplyHeader(); +// GL_KOS_VERTEX_POINTER += (first * GL_KOS_VERTEX_STRIDE); /* Add Pointer Offset */ +// GL_KOS_TEXCOORD0_POINTER += (first * GL_KOS_TEXCOORD0_STRIDE); +// GL_KOS_TEXCOORD1_POINTER += (first * GL_KOS_TEXCOORD1_STRIDE); +// GL_KOS_COLOR_POINTER += (first * GL_KOS_COLOR_STRIDE); +// GL_KOS_NORMAL_POINTER += (first * GL_KOS_NORMAL_STRIDE); - if(GL_KOS_VERTEX_SIZE == 2) - return _glKosDrawArrays2D(mode, first, count); +// /* Compile the PVR polygon context with the currently enabled flags */ +// _glKosArraysApplyHeader(); - /* Destination of Output Vertex Array */ - pvr_vertex_t *dst = _glKosArraysDest(); +// if(GL_KOS_VERTEX_SIZE == 2) +// return _glKosDrawArrays2D(mode, first, count); - /* Check if Vertex Lighting is enabled. Else, check for Color Submission */ - if((GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_NORMAL) && _glKosEnabledLighting()) - _glKosArraysApplyLighting(dst, count); +// /* Destination of Output Vertex Array */ +// pvr_vertex_t *dst = _glKosArraysDest(); - else if(GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_COLOR) { - switch(GL_KOS_COLOR_TYPE) { - case GL_FLOAT: - switch(GL_KOS_COLOR_COMPONENTS) { - case 3: - _glKosArrayColor3f(dst, count); - break; +// /* Check if Vertex Lighting is enabled. Else, check for Color Submission */ +// if((GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_NORMAL) && _glKosEnabledLighting()) +// _glKosArraysApplyLighting(dst, count); - case 4: - _glKosArrayColor4f(dst, count); - break; - } +// else if(GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_COLOR) { +// switch(GL_KOS_COLOR_TYPE) { +// case GL_FLOAT: +// switch(GL_KOS_COLOR_COMPONENTS) { +// case 3: +// _glKosArrayColor3f(dst, count); +// break; - break; +// case 4: +// _glKosArrayColor4f(dst, count); +// break; +// } - case GL_UNSIGNED_INT: - if(GL_KOS_COLOR_COMPONENTS == 1) - _glKosArrayColor1ui(dst, count); +// break; - break; +// case GL_UNSIGNED_INT: +// if(GL_KOS_COLOR_COMPONENTS == 1) +// _glKosArrayColor1ui(dst, count); - case GL_UNSIGNED_BYTE: - if(GL_KOS_COLOR_COMPONENTS == 4) - _glKosArrayColor4ub(dst, count); +// break; - break; - } - } - else - _glKosArrayColor0(dst, count); /* No colors bound, color white */ +// case GL_UNSIGNED_BYTE: +// if(GL_KOS_COLOR_COMPONENTS == 4) +// _glKosArrayColor4ub(dst, count); - /* Check if Texture Coordinates are enabled */ - if((GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_TEXTURE0) && (_glKosEnabledTexture2D() >= 0)) - _glKosArrayTexCoord2f(dst, count); +// break; +// } +// } +// else +// _glKosArrayColor0(dst, count); /* No colors bound, color white */ - /* Check if Multi Texture Coordinates are enabled */ - if((GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_TEXTURE1) && (_glKosEnabledTexture2D() >= 0)) - _glKosArrayMultiTexCoord2f(count); +// /* Check if Texture Coordinates are enabled */ +// if((GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_TEXTURE0) && (_glKosEnabledTexture2D() >= 0)) +// _glKosArrayTexCoord2f(dst, count); - _glKosMatrixApplyRender(); /* Apply the Render Matrix Stack */ +// /* Check if Multi Texture Coordinates are enabled */ +// if((GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_TEXTURE1) && (_glKosEnabledTexture2D() >= 0)) +// _glKosArrayMultiTexCoord2f(count); - if(!_glKosEnabledNearZClip()) { /* No NearZ Clipping Enabled */ - /* Transform Vertex Positions */ - _glKosArraysTransform(count); +// _glKosMatrixApplyRender(); /* Apply the Render Matrix Stack */ - /* Set the vertex flags for use with the PVR */ - _glKosArraysApplyVertexFlags(mode, dst, count); - } - else { /* NearZ Clipping is Enabled */ - /* Transform vertices with no perspective divide, store w component */ - _glKosArraysTransformClip(count); +// if(!_glKosEnabledNearZClip()) { /* No NearZ Clipping Enabled */ +// /* Transform Vertex Positions */ +// _glKosArraysTransform(count); - /* Finally, clip the input vertex data into the output vertex buffer */ - count = _glKosArraysApplyClipping( - (GLfloat *) GL_KOS_TEXCOORD1_POINTER, - GL_KOS_TEXCOORD1_STRIDE / 4, - mode, count - ); - /* FIXME: The above function should really accept a GLbyte* and the stride directly - but that affects a lot of other code, so dividing the stride by float size - hopefully results in the same thing for now */ - } +// /* Set the vertex flags for use with the PVR */ +// _glKosArraysApplyVertexFlags(mode, dst, count); +// } +// else { /* NearZ Clipping is Enabled */ +// /* Transform vertices with no perspective divide, store w component */ +// _glKosArraysTransformClip(count); - _glKosArraysApplyMultiTexture(mode, count); +// /* Finally, clip the input vertex data into the output vertex buffer */ +// count = _glKosArraysApplyClipping( +// (GLfloat *) GL_KOS_TEXCOORD1_POINTER, +// GL_KOS_TEXCOORD1_STRIDE / 4, +// mode, count +// ); +// /* FIXME: The above function should really accept a GLbyte* and the stride directly +// but that affects a lot of other code, so dividing the stride by float size +// hopefully results in the same thing for now */ +// } - _glKosArraysFlush(count); -} +// _glKosArraysApplyMultiTexture(mode, count); -void APIENTRY glClientActiveTextureARB(GLenum texture) { - if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + _glKosMaxTextureUnits()) - _glKosThrowError(GL_INVALID_ENUM, "glClientActiveTextureARB"); +// _glKosArraysFlush(count); +//} - if(_glKosHasError()) { - - _glKosPrintError(); - return; - } - - GL_KOS_CLIENT_ACTIVE_TEXTURE = texture & 0xF; -} - -void APIENTRY glEnableClientState(GLenum cap) { - switch(cap) { - case GL_VERTEX_ARRAY: - GL_KOS_VERTEX_PTR_MODE |= GL_KOS_USE_ARRAY; - break; - case GL_COLOR_ARRAY: - GL_KOS_VERTEX_PTR_MODE |= GL_KOS_USE_COLOR; - break; - case GL_NORMAL_ARRAY: - GL_KOS_VERTEX_PTR_MODE |= GL_KOS_USE_NORMAL; - break; - case GL_TEXTURE_COORD_ARRAY: - (GL_KOS_CLIENT_ACTIVE_TEXTURE) ? - (GL_KOS_VERTEX_PTR_MODE |= GL_KOS_USE_TEXTURE1): - (GL_KOS_VERTEX_PTR_MODE |= GL_KOS_USE_TEXTURE0); - break; - default: - _glKosThrowError(GL_INVALID_ENUM, "glEnableClientState"); - } - -} - -void APIENTRY glDisableClientState(GLenum cap) { - switch(cap) { - case GL_VERTEX_ARRAY: - GL_KOS_VERTEX_PTR_MODE &= ~GL_KOS_USE_ARRAY; - break; - case GL_COLOR_ARRAY: - GL_KOS_VERTEX_PTR_MODE &= ~GL_KOS_USE_COLOR; - break; - case GL_NORMAL_ARRAY: - GL_KOS_VERTEX_PTR_MODE &= ~GL_KOS_USE_NORMAL; - break; - case GL_TEXTURE_COORD_ARRAY: - (GL_KOS_CLIENT_ACTIVE_TEXTURE) ? - (GL_KOS_VERTEX_PTR_MODE &= ~GL_KOS_USE_TEXTURE1): - (GL_KOS_VERTEX_PTR_MODE &= ~GL_KOS_USE_TEXTURE0); - break; - default: - _glKosThrowError(GL_INVALID_ENUM, "glDisableClientState"); - } -} diff --git a/gl-cap.c b/gl-cap.c index d7bb017..54a2425 100644 --- a/gl-cap.c +++ b/gl-cap.c @@ -28,91 +28,91 @@ static GLbitfield GL_KOS_ENABLE_CAP = 0; //===============================================================================// //== External API Functions ==// -void APIENTRY glEnable(GLenum cap) { - if(cap >= GL_LIGHT0 && cap <= GL_LIGHT15) return _glKosEnableLight(cap); +//void APIENTRY glEnable(GLenum cap) { +// if(cap >= GL_LIGHT0 && cap <= GL_LIGHT15) return _glKosEnableLight(cap); - switch(cap) { - case GL_TEXTURE_2D: - GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_TEXTURE2D; - break; +// switch(cap) { +// case GL_TEXTURE_2D: +// GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_TEXTURE2D; +// break; - case GL_BLEND: - GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_BLENDING; - _glKosVertexBufSwitchTR(); - break; +// case GL_BLEND: +// GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_BLENDING; +// _glKosVertexBufSwitchTR(); +// break; - case GL_DEPTH_TEST: - GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_DEPTH_TEST; - break; +// case GL_DEPTH_TEST: +// GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_DEPTH_TEST; +// break; - case GL_LIGHTING: - GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_LIGHTING; - break; +// case GL_LIGHTING: +// GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_LIGHTING; +// break; - case GL_KOS_NEARZ_CLIPPING: - GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_ZCLIPPING; - break; +// case GL_KOS_NEARZ_CLIPPING: +// GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_ZCLIPPING; +// break; - case GL_SCISSOR_TEST: - GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_SCISSOR_TEST; - break; +// case GL_SCISSOR_TEST: +// GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_SCISSOR_TEST; +// break; - case GL_FOG: - GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_FOG; - break; +// case GL_FOG: +// GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_FOG; +// break; - case GL_CULL_FACE: - GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_CULLING; - break; +// case GL_CULL_FACE: +// GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_CULLING; +// break; - case GL_KOS_TEXTURE_MATRIX: - GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_TEXTURE_MAT; - break; - } -} +// case GL_KOS_TEXTURE_MATRIX: +// GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_TEXTURE_MAT; +// break; +// } +//} -void APIENTRY glDisable(GLenum cap) { - if(cap >= GL_LIGHT0 && cap <= GL_LIGHT15) return _glKosDisableLight(cap); +//void APIENTRY glDisable(GLenum cap) { +// if(cap >= GL_LIGHT0 && cap <= GL_LIGHT15) return _glKosDisableLight(cap); - switch(cap) { - case GL_TEXTURE_2D: - GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_TEXTURE2D; - break; +// switch(cap) { +// case GL_TEXTURE_2D: +// GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_TEXTURE2D; +// break; - case GL_BLEND: - GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_BLENDING; - _glKosVertexBufSwitchOP(); - break; +// case GL_BLEND: +// GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_BLENDING; +// _glKosVertexBufSwitchOP(); +// break; - case GL_DEPTH_TEST: - GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_DEPTH_TEST; - break; +// case GL_DEPTH_TEST: +// GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_DEPTH_TEST; +// break; - case GL_LIGHTING: - GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_LIGHTING; - break; +// case GL_LIGHTING: +// GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_LIGHTING; +// break; - case GL_KOS_NEARZ_CLIPPING: - GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_ZCLIPPING; - break; +// case GL_KOS_NEARZ_CLIPPING: +// GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_ZCLIPPING; +// break; - case GL_SCISSOR_TEST: - GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_SCISSOR_TEST; - break; +// case GL_SCISSOR_TEST: +// GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_SCISSOR_TEST; +// break; - case GL_FOG: - GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_FOG; - break; +// case GL_FOG: +// GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_FOG; +// break; - case GL_CULL_FACE: - GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_CULLING; - break; +// case GL_CULL_FACE: +// GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_CULLING; +// break; - case GL_KOS_TEXTURE_MATRIX: - GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_TEXTURE_MAT; - break; - } -} +// case GL_KOS_TEXTURE_MATRIX: +// GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_TEXTURE_MAT; +// break; +// } +//} GLboolean APIENTRY glIsEnabled(GLenum cap) { if(cap >= GL_LIGHT0 && cap <= GL_LIGHT15) return _glKosIsLightEnabled(cap & 0xFF); diff --git a/gl-error.c b/gl-error.c index aad8e05..b62fd52 100644 --- a/gl-error.c +++ b/gl-error.c @@ -25,7 +25,7 @@ static char error_function[64] = { '\0' }; Nothing in the spec requires recording multiple error flags, although it is allowed by the spec. We take the easy way out for now. */ -void _glKosThrowError(GLenum error, char *function) { +void _glKosThrowError(GLenum error, const char *function) { if(last_error == GL_NO_ERROR) { last_error = error; sprintf(error_function, "%s\n", function); diff --git a/gl-pvr.h b/gl-pvr.h index 2d2b340..cf12a7d 100644 --- a/gl-pvr.h +++ b/gl-pvr.h @@ -14,15 +14,6 @@ typedef struct { unsigned int cmd[8]; } pvr_cmd_t; /* Generic 32byte command for the pvr */ -typedef struct { - unsigned int flags; /* Constant PVR_CMD_USERCLIP */ - unsigned int d1, d2, d3; /* Ignored for this type */ - unsigned int sx, /* Start x */ - sy, /* Start y */ - ex, /* End x */ - ey; /* End y */ -} pvr_cmd_tclip_t; /* Tile Clip command for the pvr */ - #define GL_PVR_VERTEX_BUF_SIZE 2560 * 256 /* PVR Vertex buffer size */ #define GL_KOS_MAX_VERTS 1024*64 /* SH4 Vertex Count */ diff --git a/gl-texture.c b/gl-texture.c index 29ebe5b..937f354 100644 --- a/gl-texture.c +++ b/gl-texture.c @@ -21,8 +21,6 @@ //== Internal KOS Open GL Texture Unit Structures / Global Variables ==// #define GL_KOS_MAX_TEXTURE_UNITS 2 -#define GL_KOS_CLAMP_U (1<<1) -#define GL_KOS_CLAMP_V (1<<0) static GL_TEXTURE_OBJECT *GL_KOS_TEXTURE_UNIT[GL_KOS_MAX_TEXTURE_UNITS] = { NULL, NULL }; @@ -32,20 +30,6 @@ static GLubyte GL_KOS_ACTIVE_TEXTURE = GL_TEXTURE0_ARB & 0xF; //========================================================================================// -static GLuint _determinePVRFormat(GLint internalFormat, GLenum type); - -GLubyte _glKosInitTextures() { - named_array_init(&TEXTURE_OBJECTS, sizeof(GL_TEXTURE_OBJECT), 256); - return 1; -} - -static void _glKosBindTexture(GLuint index) { - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE] = (GL_TEXTURE_OBJECT*) named_array_get(&TEXTURE_OBJECTS, index); -} - -static void _glKosUnbindTexture() { - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE] = NULL; -} GLuint _glKosTextureWidth(GLuint index) { GL_TEXTURE_OBJECT *tex = (GL_TEXTURE_OBJECT*) named_array_get(&TEXTURE_OBJECTS, index); @@ -67,6 +51,10 @@ void _glKosCompileHdrTx() { _glKosCompileHdrT(GL_KOS_TEXTURE_UNIT[GL_TEXTURE0_ARB & 0xF]) : _glKosCompileHdr(); } +GL_TEXTURE_OBJECT *_glKosBoundTexObject() { + return GL_KOS_TEXTURE_UNIT[GL_TEXTURE0_ARB & 0xF]; +} + GL_TEXTURE_OBJECT *_glKosBoundMultiTexObject() { return GL_KOS_TEXTURE_UNIT[GL_TEXTURE1_ARB & 0xF]; } @@ -92,528 +80,6 @@ GLubyte _glKosMaxTextureUnits() { //========================================================================================// //== Public KOS Open GL API Texture Unit Functionality ==// -void APIENTRY glGenTextures(GLsizei n, GLuint *textures) { - while(n--) { - GLuint id = 0; - GL_TEXTURE_OBJECT* txr = (GL_TEXTURE_OBJECT*) named_array_alloc(&TEXTURE_OBJECTS, &id); - txr->index = id; - txr->width = txr->height = 0; - txr->mip_map = 0; - txr->uv_clamp = 0; - txr->env = PVR_TXRENV_MODULATEALPHA; - txr->filter = PVR_FILTER_NONE; - txr->data = NULL; - *textures = id; - textures++; - } -} -void APIENTRY glDeleteTextures(GLsizei n, GLuint *textures) { - while(n--) { - GL_TEXTURE_OBJECT* txr = (GL_TEXTURE_OBJECT*) named_array_get(&TEXTURE_OBJECTS, *textures); - - if(txr == GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]) { - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE] = NULL; - } - - if(txr->data) { - pvr_mem_free(txr->data); - } - - named_array_release(&TEXTURE_OBJECTS, *textures++); - } -} - -void APIENTRY glBindTexture(GLenum target, GLuint texture) { - if(target != GL_TEXTURE_2D) { - _glKosThrowError(GL_INVALID_ENUM, "glBindTexture"); - _glKosPrintError(); - return; - } - - texture ? _glKosBindTexture(texture) : _glKosUnbindTexture(); -} - -void APIENTRY glCompressedTexImage2D(GLenum target, - GLint level, - GLenum internalformat, - GLsizei width, - GLsizei height, - GLint border, - GLsizei imageSize, - const GLvoid *data) { - if(target != GL_TEXTURE_2D) - _glKosThrowError(GL_INVALID_ENUM, "glCompressedTexImage2D"); - - if(level < 0) - _glKosThrowError(GL_INVALID_VALUE, "glCompressedTexImage2D"); - - if(border) - _glKosThrowError(GL_INVALID_VALUE, "glCompressedTexImage2D"); - - if(internalformat != GL_UNSIGNED_SHORT_5_6_5_VQ_KOS) - if(internalformat != GL_UNSIGNED_SHORT_5_6_5_VQ_TWID_KOS) - if(internalformat != GL_UNSIGNED_SHORT_4_4_4_4_VQ_KOS) - if(internalformat != GL_UNSIGNED_SHORT_4_4_4_4_REV_VQ_TWID_KOS) - if(internalformat != GL_UNSIGNED_SHORT_1_5_5_5_REV_VQ_KOS) - if(internalformat != GL_UNSIGNED_SHORT_1_5_5_5_REV_VQ_TWID_KOS) - _glKosThrowError(GL_INVALID_OPERATION, "glCompressedTexImage2D"); - - if(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE] == NULL) - _glKosThrowError(GL_INVALID_OPERATION, "glCompressedTexImage2D"); - - if(_glKosHasError()) { - _glKosPrintError(); - return; - } - - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->width = width; - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->height = height; - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->mip_map = level; - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->color = _determinePVRFormat( - internalformat, - internalformat /* Doesn't matter (see determinePVRFormat) */ - ); - - /* Odds are slim new data is same size as old, so free always */ - if(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->data) - pvr_mem_free(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->data); - - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->data = pvr_mem_malloc(imageSize); - - if(data) - sq_cpy(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->data, data, imageSize); -} - -static GLint _cleanInternalFormat(GLint internalFormat) { - switch (internalFormat) { - case GL_ALPHA: -/* case GL_ALPHA4: - case GL_ALPHA8: - case GL_ALPHA12: - case GL_ALPHA16:*/ - return GL_ALPHA; - case 1: - case GL_LUMINANCE: -/* case GL_LUMINANCE4: - case GL_LUMINANCE8: - case GL_LUMINANCE12: - case GL_LUMINANCE16:*/ - return GL_LUMINANCE; - case 2: - case GL_LUMINANCE_ALPHA: -/* case GL_LUMINANCE4_ALPHA4: - case GL_LUMINANCE6_ALPHA2: - case GL_LUMINANCE8_ALPHA8: - case GL_LUMINANCE12_ALPHA4: - case GL_LUMINANCE12_ALPHA12: - case GL_LUMINANCE16_ALPHA16: */ - return GL_LUMINANCE_ALPHA; -/* case GL_INTENSITY: - case GL_INTENSITY4: - case GL_INTENSITY8: - case GL_INTENSITY12: - case GL_INTENSITY16: - return GL_INTENSITY; */ - case 3: - return GL_RGB; - case GL_RGB: -/* case GL_R3_G3_B2: - case GL_RGB4: - case GL_RGB5: - case GL_RGB8: - case GL_RGB10: - case GL_RGB12: - case GL_RGB16: */ - return GL_RGB; - case 4: - return GL_RGBA; - case GL_RGBA: -/* case GL_RGBA2: - case GL_RGBA4: - case GL_RGB5_A1: - case GL_RGBA8: - case GL_RGB10_A2: - case GL_RGBA12: - case GL_RGBA16: */ - return GL_RGBA; - - /* Support ARB_texture_rg */ - case GL_RED: -/* case GL_R8: - case GL_R16: - case GL_RED: - case GL_COMPRESSED_RED: */ - return GL_RED; -/* case GL_RG: - case GL_RG8: - case GL_RG16: - case GL_COMPRESSED_RG: - return GL_RG;*/ - default: - return -1; - } -} - -static GLuint _determinePVRFormat(GLint internalFormat, GLenum type) { - /* Given a cleaned internalFormat, return the Dreamcast format - * that can hold it - */ - switch(internalFormat) { - case GL_ALPHA: - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - case GL_RGBA: - /* OK so if we have something that requires alpha, we return 4444 unless - * the type was already 1555 (1-bit alpha) in which case we return that - */ - return (type == GL_UNSIGNED_SHORT_1_5_5_5_REV) ? - PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_NONTWIDDLED : - PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_NONTWIDDLED; - case GL_RED: - case GL_RGB: - /* No alpha? Return RGB565 which is the best we can do without using palettes */ - return PVR_TXRFMT_RGB565 | PVR_TXRFMT_NONTWIDDLED; - /* Compressed and twiddled versions */ - case GL_UNSIGNED_SHORT_5_6_5_TWID_KOS: - return PVR_TXRFMT_RGB565 | PVR_TXRFMT_TWIDDLED; - case GL_UNSIGNED_SHORT_5_6_5_VQ_KOS: - return PVR_TXRFMT_RGB565 | PVR_TXRFMT_NONTWIDDLED | PVR_TXRFMT_VQ_ENABLE; - case GL_UNSIGNED_SHORT_5_6_5_VQ_TWID_KOS: - return PVR_TXRFMT_RGB565 | PVR_TXRFMT_TWIDDLED | PVR_TXRFMT_VQ_ENABLE; - case GL_UNSIGNED_SHORT_4_4_4_4_REV_TWID_KOS: - return PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_TWIDDLED; - case GL_UNSIGNED_SHORT_4_4_4_4_REV_VQ_TWID_KOS: - return PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_TWIDDLED | PVR_TXRFMT_VQ_ENABLE; - case GL_UNSIGNED_SHORT_4_4_4_4_VQ_KOS: - return PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_NONTWIDDLED | PVR_TXRFMT_VQ_ENABLE; - case GL_UNSIGNED_SHORT_1_5_5_5_REV_TWID_KOS: - return PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_TWIDDLED; - case GL_UNSIGNED_SHORT_1_5_5_5_REV_VQ_KOS: - return PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_NONTWIDDLED | PVR_TXRFMT_VQ_ENABLE; - case GL_UNSIGNED_SHORT_1_5_5_5_REV_VQ_TWID_KOS: - return PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_TWIDDLED | PVR_TXRFMT_VQ_ENABLE; - default: - return 0; - } -} - - -typedef void (*TextureConversionFunc)(const GLubyte*, GLushort*); - -static void _rgba8888_to_argb4444(const GLubyte* source, GLushort* dest) { - *dest = (source[3] & 0xF0) << 8 | (source[0] & 0xF0) << 4 | (source[1] & 0xF0) | (source[2] & 0xF0) >> 4; -} - -static void _rgb888_to_rgb565(const GLubyte* source, GLushort* dest) { - *dest = ((source[0] & 0b11111000) << 8) | ((source[1] & 0b11111100) << 3) | (source[2] >> 3); -} - -static void _rgba8888_to_a000(const GLubyte* source, GLushort* dest) { - *dest = ((source[3] & 0b11111000) << 8); -} - -static void _r8_to_rgb565(const GLubyte* source, GLushort* dest) { - *dest = (source[0] & 0b11111000) << 8; -} - -static void _rgba4444_to_argb4444(const GLubyte* source, GLushort* dest) { - GLushort* src = (GLushort*) source; - *dest = ((*src & 0x000F) << 12) | *src >> 4; -} - -static TextureConversionFunc _determineConversion(GLint internalFormat, GLenum format, GLenum type) { - switch(internalFormat) { - case GL_ALPHA: { - if(type == GL_UNSIGNED_BYTE && format == GL_RGBA) { - return _rgba8888_to_a000; - } else if(type == GL_BYTE && format == GL_RGBA) { - return _rgba8888_to_a000; - } - } break; - case GL_RGB: { - if(type == GL_UNSIGNED_BYTE && format == GL_RGB) { - return _rgb888_to_rgb565; - } else if(type == GL_BYTE && format == GL_RGB) { - return _rgb888_to_rgb565; - } else if(type == GL_UNSIGNED_BYTE && format == GL_RED) { - return _r8_to_rgb565; - } - } break; - case GL_RGBA: { - if(type == GL_UNSIGNED_BYTE && format == GL_RGBA) { - return _rgba8888_to_argb4444; - } else if (type == GL_BYTE && format == GL_RGBA) { - return _rgba8888_to_argb4444; - } else if(type == GL_UNSIGNED_SHORT_4_4_4_4 && format == GL_RGBA) { - return _rgba4444_to_argb4444; - } - } break; - default: - break; - } - return 0; -} - -static GLint _determineStride(GLenum format, GLenum type) { - switch(type) { - case GL_BYTE: - case GL_UNSIGNED_BYTE: - return (format == GL_RED) ? 1 : (format == GL_RGB) ? 3 : 4; - case GL_UNSIGNED_SHORT: - return (format == GL_RED) ? 2 : (format == GL_RGB) ? 6 : 8; - case GL_UNSIGNED_SHORT_5_6_5_REV: - case GL_UNSIGNED_SHORT_5_6_5_TWID_KOS: - case GL_UNSIGNED_SHORT_5_5_5_1: - case GL_UNSIGNED_SHORT_1_5_5_5_REV_TWID_KOS: - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - case GL_UNSIGNED_SHORT_4_4_4_4: - case GL_UNSIGNED_SHORT_4_4_4_4_REV_TWID_KOS: - case GL_UNSIGNED_SHORT_4_4_4_4_REV: - return 2; - } - - return -1; -} - -static GLboolean _isSupportedFormat(GLenum format) { - switch(format) { - case GL_RED: - case GL_RGB: - case GL_RGBA: - case GL_BGRA: - return GL_TRUE; - default: - return GL_FALSE; - } -} - - -void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, - GLsizei width, GLsizei height, GLint border, - GLenum format, GLenum type, const GLvoid *data) { - - if(target != GL_TEXTURE_2D) { - _glKosThrowError(GL_INVALID_ENUM, "glTexImage2D"); - } - - if(!_isSupportedFormat(format)) { - _glKosThrowError(GL_INVALID_ENUM, "glTexImage2D"); - } - - /* Abuse determineStride to see if type is valid */ - if(_determineStride(GL_RGBA, type) == -1) { - _glKosThrowError(GL_INVALID_ENUM, "glTexImage2D"); - } - - internalFormat = _cleanInternalFormat(internalFormat); - if(internalFormat == -1) { - _glKosThrowError(GL_INVALID_VALUE, "glTexImage2D"); - } - - GLint w = width; - if(w == 0 || (w & -w) != w) { - /* Width is not a power of two. Must be!*/ - _glKosThrowError(GL_INVALID_VALUE, "glTexImage2D"); - } - - GLint h = height; - if(h == 0 || (h & -h) != h) { - /* height is not a power of two. Must be!*/ - _glKosThrowError(GL_INVALID_VALUE, "glTexImage2D"); - } - - if(level < 0) { - _glKosThrowError(GL_INVALID_VALUE, "glTexImage2D"); - } - - if(border) { - _glKosThrowError(GL_INVALID_VALUE, "glTexImage2D"); - } - - if(!GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]) { - _glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D"); - } - - if(_glKosHasError()) { - _glKosPrintError(); - return; - } - - /* Calculate the format that we need to convert the data to */ - GLuint pvr_format = _determinePVRFormat(internalFormat, type); - - if(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->data) { - /* pre-existing texture - check if changed */ - if(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->width != width || - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->height != height || - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->mip_map != level || - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->color != pvr_format) { - /* changed - free old texture memory */ - pvr_mem_free(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->data); - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->data = NULL; - } - } - - GLuint bytes = level ? glKosMipMapTexSize(width, height) : (width * height * 2); - - if(!GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->data) { - /* need texture memory */ - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->width = width; - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->height = height; - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->mip_map = level; - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->color = pvr_format; - - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->data = pvr_mem_malloc(bytes); - } - - /* Let's assume we need to convert */ - GLboolean needsConversion = GL_TRUE; - - /* - * 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 - */ - if(format == GL_BGRA && type == GL_UNSIGNED_SHORT_4_4_4_4_REV && internalFormat == GL_RGBA) { - needsConversion = GL_FALSE; - } else if(format == GL_BGRA && type == GL_UNSIGNED_SHORT_1_5_5_5_REV && internalFormat == GL_RGBA) { - needsConversion = GL_FALSE; - } else if(format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5 && internalFormat == GL_RGB) { - needsConversion = GL_FALSE; - } else if(format == GL_RGB && type == GL_UNSIGNED_SHORT_5_6_5_TWID_KOS && internalFormat == GL_RGB) { - needsConversion = GL_FALSE; - } else if(format == GL_BGRA && type == GL_UNSIGNED_SHORT_1_5_5_5_REV_TWID_KOS && internalFormat == GL_RGBA) { - needsConversion = GL_FALSE; - } else if(format == GL_BGRA && type == GL_UNSIGNED_SHORT_4_4_4_4_REV_TWID_KOS && internalFormat == GL_RGBA) { - needsConversion = GL_FALSE; - } - - if(!data) { - /* No data? Do nothing! */ - return; - } else if(!needsConversion) { - /* No conversion? Just copy the data, and the pvr_format is correct */ - sq_cpy(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->data, data, bytes); - return; - } else { - TextureConversionFunc convert = _determineConversion( - internalFormat, - format, - type - ); - - if(!convert) { - _glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D"); - return; - } - - GLushort* dest = GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->data; - const GLubyte* source = data; - GLint stride = _determineStride(format, type); - - if(stride == -1) { - _glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D"); - return; - } - - /* Perform the conversion */ - for(GLuint i = 0; i < bytes; i += 2) { - convert(source, dest); - - dest++; - source += stride; - } - } -} - -void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) { - if(target == GL_TEXTURE_2D) { - switch(pname) { - case GL_TEXTURE_MAG_FILTER: - case GL_TEXTURE_MIN_FILTER: - switch(param) { - case GL_LINEAR: - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->filter = PVR_FILTER_BILINEAR; - break; - - case GL_NEAREST: - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->filter = PVR_FILTER_NEAREST; - break; - - case GL_FILTER_NONE: - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->filter = PVR_FILTER_NONE; - break; - - case GL_FILTER_BILINEAR: - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->filter = PVR_FILTER_BILINEAR; - break; - - default: - break; - } - - break; - - case GL_TEXTURE_WRAP_S: - switch(param) { - case GL_CLAMP: - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->uv_clamp |= GL_KOS_CLAMP_U; - break; - - case GL_REPEAT: - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->uv_clamp &= ~GL_KOS_CLAMP_U; - break; - } - - break; - - case GL_TEXTURE_WRAP_T: - switch(param) { - case GL_CLAMP: - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->uv_clamp |= GL_KOS_CLAMP_V; - break; - - case GL_REPEAT: - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->uv_clamp &= ~GL_KOS_CLAMP_V; - break; - } - - break; - } - } -} - -void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) { - if(target != GL_TEXTURE_ENV) - _glKosThrowError(GL_INVALID_ENUM, "glTexEnvi"); - - if(pname != GL_TEXTURE_ENV_MODE) - _glKosThrowError(GL_INVALID_ENUM, "glTexEnvi"); - - if(_glKosHasError()) { - _glKosPrintError(); - return; - } - - if(param >= PVR_TXRENV_REPLACE && param <= PVR_TXRENV_MODULATEALPHA) - GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->env = param; -} - -void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param) { - glTexEnvi(target, pname, param); -} - -void APIENTRY glActiveTextureARB(GLenum texture) { - if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + GL_KOS_MAX_TEXTURE_UNITS) - _glKosThrowError(GL_INVALID_ENUM, "glActiveTextureARB"); - - if(_glKosHasError()) { - - _glKosPrintError(); - return; - } - - GL_KOS_ACTIVE_TEXTURE = texture & 0xF; -} diff --git a/include/gl.h b/include/gl.h index 6c8d7f8..0d87dbe 100644 --- a/include/gl.h +++ b/include/gl.h @@ -473,8 +473,8 @@ GLAPI void APIENTRY glClear(GLuint mode); GLAPI void APIENTRY glClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a); /* Depth Testing */ +GLAPI void APIENTRY glClearDepth(GLfloat depth); GLAPI void APIENTRY glClearDepthf(GLfloat depth); -#define glClearDepth glClearDepthf GLAPI void APIENTRY glDepthMask(GLboolean flag); GLAPI void APIENTRY glDepthFunc(GLenum func); diff --git a/include/glkos.h b/include/glkos.h index 3bffbe1..1743a02 100644 --- a/include/glkos.h +++ b/include/glkos.h @@ -1,6 +1,12 @@ #ifndef GLKOS_H #define GLKOS_H -void glKosSwapBuffers(); +#include "gl.h" + +__BEGIN_DECLS + +GLAPI void APIENTRY glKosSwapBuffers(); + +__END_DECLS #endif // GLKOS_H