From 1356ae352c30a81ad1075a6dceb661fcc85a5acb Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Sat, 5 May 2018 20:38:55 +0100 Subject: [PATCH 01/21] Begin experimental new renderig code --- containers/aligned_vector.h | 109 ++++++++++++++++++ experimental/draw.c | 212 ++++++++++++++++++++++++++++++++++++ experimental/flush.c | 88 +++++++++++++++ experimental/private.h | 25 +++++ experimental/state.c | 175 +++++++++++++++++++++++++++++ include/glkos.h | 6 + 6 files changed, 615 insertions(+) create mode 100644 containers/aligned_vector.h create mode 100644 experimental/draw.c create mode 100644 experimental/flush.c create mode 100644 experimental/private.h create mode 100644 experimental/state.c create mode 100644 include/glkos.h diff --git a/containers/aligned_vector.h b/containers/aligned_vector.h new file mode 100644 index 0000000..a9c7fef --- /dev/null +++ b/containers/aligned_vector.h @@ -0,0 +1,109 @@ +#ifndef ALIGNED_VECTOR_H +#define ALIGNED_VECTOR_H + +#include +#include +#include +#include + +#define ALIGNED_VECTOR_INITIAL_CAPACITY 256 + +typedef struct { + unsigned int size; + unsigned int capacity; + unsigned char* data; + unsigned int element_size; +} AlignedVector; + + +inline void aligned_vector_reserve(AlignedVector* vector, unsigned int element_count); +inline void aligned_vector_resize(AlignedVector* vector, const unsigned int element_count); + +inline void aligned_vector_init(AlignedVector* vector, unsigned int element_size) { + vector->size = vector->capacity = 0; + vector->element_size = element_size; + vector->data = NULL; + + /* Reserve some initial capacity */ + aligned_vector_reserve(vector, ALIGNED_VECTOR_INITIAL_CAPACITY); +} + +inline void aligned_vector_reserve(AlignedVector* vector, unsigned int element_count) { + if(element_count <= vector->capacity) { + return; + } + + unsigned int original_byte_size = vector->size * vector->element_size; + unsigned int new_byte_size = element_count * vector->element_size; + unsigned char* original_data = vector->data; + vector->data = (unsigned char*) memalign(0x20, new_byte_size); + + if(original_data) { + memcpy(vector->data, original_data, original_byte_size); + free(original_data); + } + + vector->capacity = element_count; +} + +inline void aligned_vector_push_back(AlignedVector* vector, const void* objs, unsigned int count) { + /* Resize enough room */ + + unsigned int initial_size = vector->size; + aligned_vector_resize(vector, vector->size + count); + + unsigned char* dest = vector->data + (vector->element_size * initial_size); + + /* Copy the objects in */ + memcpy(dest, objs, vector->element_size * count); +} + +inline void aligned_vector_resize(AlignedVector* vector, const unsigned int element_count) { + /* Don't change memory when resizing downwards, just change the size */ + if(element_count <= vector->size) { + vector->size = element_count; + return; + } + + if(vector->capacity < element_count) { + /* Reserve more than we need so that a subsequent push_back doesn't trigger yet another + * resize */ + aligned_vector_reserve(vector, (int) ceil(((float)element_count) * 1.5f)); + } + + vector->size = element_count; +} + +inline void* aligned_vector_at(AlignedVector* vector, const unsigned int index) { + return &vector->data[index * vector->element_size]; +} + +inline void aligned_vector_clear(AlignedVector* vector) { + vector->size = 0; +} + +inline void aligned_vector_shrink_to_fit(AlignedVector* vector) { + if(vector->size == 0) { + free(vector->data); + vector->data = NULL; + vector->capacity = 0; + } else { + unsigned int new_byte_size = vector->size * vector->element_size; + unsigned char* original_data = vector->data; + vector->data = (unsigned char*) memalign(0x20, new_byte_size); + + if(original_data) { + memcpy(vector->data, original_data, new_byte_size); + free(original_data); + } + + vector->capacity = vector->size; + } +} + +void aligned_vector_cleanup(AlignedVector* vector) { + aligned_vector_clear(vector); + aligned_vector_shrink_to_fit(vector); +} + +#endif // ALIGNED_VECTOR_H diff --git a/experimental/draw.c b/experimental/draw.c new file mode 100644 index 0000000..c935f18 --- /dev/null +++ b/experimental/draw.c @@ -0,0 +1,212 @@ +#include "../include/gl.h" +#include "private.h" + + +typedef struct { + void* ptr; + GLenum type; + GLsizei stride; + GLint size; +} AttribPointer; + + +static AttribPointer VERTEX_POINTER; +static AttribPointer UV_POINTER; +static AttribPointer ST_POINTER; +static AttribPointer NORMAL_POINTER; +static AttribPointer DIFFUSE_POINTER; + +#define VERTEX_ENABLED_FLAG (1 << 0) +#define UV_ENABLED_FLAG (1 << 1) +#define ST_ENABLED_FLAG (1 << 2) +#define DIFFUSE_ENABLED_FLAG (1 << 3) +#define NORMAL_ENABLED_FLAG (1 << 4) + +static GLuint ENABLED_VERTEX_ATTRIBUTES = 0; +static GLubyte ACTIVE_CLIENT_TEXTURE = 0; + +void initAttributePointers() { + VERTEX_POINTER.ptr = NULL; + VERTEX_POINTER.stride = 0; + VERTEX_POINTER.type = GL_FLOAT; + VERTEX_POINTER.size = 4; +} + +static GLuint byte_size(GLenum type) { + switch(type) { + case GL_BYTE: return sizeof(GLbyte); + case GL_UNSIGNED_BYTE: return sizeof(GLubyte); + case GL_SHORT: return sizeof(GLshort); + case GL_UNSIGNED_SHORT: return sizeof(GLushort); + case GL_INT: return sizeof(GLint); + case GL_UNSIGNED_INT: return sizeof(GLuint); + case GL_DOUBLE: return sizeof(GLdouble); + default: return sizeof(GLfloat); + } +} + +static void transformVertex(const GLfloat* src) { + register float __x __asm__("fr12"); + register float __y __asm__("fr13"); + register float __z __asm__("fr14"); + + __x = src[0]; + __y = src[1]; + __z = src[2]; + + mat_trans_fv12() + + src[0] = __x; + src[1] = __y; + src[2] = __z; +} + +static void _parseFloats(GLfloat* out, const GLubyte* in, GLint size, GLenum type) { + switch(type) { + case GL_SHORT: { + GLshort* inp = (GLshort*) in; + for(GLubyte i = 0; i < size; ++i) { + out[i] = (GLfloat) inp[i]; + } + } break; + case GL_INT: { + GLint* inp = (GLint*) in; + for(GLubyte i = 0; i < size; ++i) { + out[i] = (GLfloat) inp[i]; + } + } break; + case GL_FLOAT: + case GL_DOUBLE: /* Double == Float */ + default: + for(GLubyte i = 0; i < size; ++i) out[i] = ((GLfloat*) in)[i]; + } +} + +static void _parseIndex(GLshort* out, const GLubyte* in, GLenum type) { + switch(type) { + case GL_UNSIGNED_BYTE: + *out = (GLshort) *in; + break; + case GL_UNSIGNED_SHORT: + default: + *out = *((GLshort*) in); + } +} + +static void submitVertices(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) { + if(!(ENABLED_VERTEX_ATTRIBUTES & VERTEX_ENABLED_FLAG)) { + return; + } + + _glKosMatrixApplyRender(); /* Apply the Render Matrix Stack */ + + const GLbyte 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; + + static GLfloat vparts[4]; + + GLubyte vstride = (VERTEX_POINTER.stride) ? VERTEX_POINTER.stride : VERTEX_POINTER.size * byte_size(VERTEX_POINTER.type); + 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); + } + + _parseFloats(vparts, vptr + (idx * vstride), VERTEX_POINTER.size, VERTEX_POINTER.type); + + vertex.x = vparts[0]; + vertex.y = vparts[1]; + vertex.z = vparts[2]; + + transformVertex(&vertex.x); + } +} + +GLAPI void APIENTRY glDrawElementsExp(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) { + submitVertices(mode, count, type, indices); +} + +GLAPI void APIENTRY glDrawArraysExp(GLenum mode, GLint first, GLsizei count) { + submitVertices(mode, count, type, NULL); +} + +GLAPI void APIENTRY glEnableClientStateExp(GLenum cap) { + switch(cap) { + case GL_VERTEX_ARRAY: + ENABLED_VERTEX_ATTRIBUTES |= VERTEX_ENABLED_FLAG; + break; + case GL_COLOR_ARRAY: + ENABLED_VERTEX_ATTRIBUTES |= DIFFUSE_ENABLED_FLAG; + break; + case GL_NORMAL_ARRAY: + ENABLED_VERTEX_ATTRIBUTES |= NORMAL_ENABLED_FLAG; + break; + case GL_TEXTURE_COORD_ARRAY: + (ACTIVE_CLIENT_TEXTURE) ? + (ENABLED_VERTEX_ATTRIBUTES |= ST_ENABLED_FLAG): + (ENABLED_VERTEX_ATTRIBUTES |= UV_ENABLED_FLAG); + break; + default: + _glKosThrowError(GL_INVALID_ENUM, "glEnableClientState"); + } +} + +GLAPI void APIENTRY glDisableClientStateExp(GLenum cap) { + switch(cap) { + case GL_VERTEX_ARRAY: + ENABLED_VERTEX_ATTRIBUTES &= ~VERTEX_ENABLED_FLAG; + break; + case GL_COLOR_ARRAY: + ENABLED_VERTEX_ATTRIBUTES &= ~DIFFUSE_ENABLED_FLAG; + break; + case GL_NORMAL_ARRAY: + ENABLED_VERTEX_ATTRIBUTES &= ~NORMAL_ENABLED_FLAG; + break; + case GL_TEXTURE_COORD_ARRAY: + (ACTIVE_CLIENT_TEXTURE) ? + (ENABLED_VERTEX_ATTRIBUTES &= ~ST_ENABLED_FLAG): + (ENABLED_VERTEX_ATTRIBUTES &= ~UV_ENABLED_FLAG); + break; + default: + _glKosThrowError(GL_INVALID_ENUM, "glDisableClientState"); + } +} + +GLAPI void APIENTRY glClientActiveTextureExp(GLenum texture) { + ACTIVE_CLIENT_TEXTURE = (texture == GL_TEXTURE1) ? 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; + + texpointer->ptr = pointer; + texpointer->stride = stride; + texpointer->type = type; + texpointer->size = size; +} + +GLAPI void APIENTRY glVertexPointerExp(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer) { + 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) { + 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) { + NORMAL_POINTER.ptr = pointer; + NORMAL_POINTER.stride = stride; + NORMAL_POINTER.type = type; + NORMAL_POINTER.size = 3; +} diff --git a/experimental/flush.c b/experimental/flush.c new file mode 100644 index 0000000..8af8476 --- /dev/null +++ b/experimental/flush.c @@ -0,0 +1,88 @@ + + +#include + +#include "../containers/aligned_vector.h" +#include "private.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 void pvr_list_submit(void *src, int n) { + GLuint *d = TA_SQ_ADDR; + GLuint *s = src; + + /* fill/write queues as many times necessary */ + while(n--) { + __asm__("pref @%0" : : "r"(s + 8)); /* prefetch 32 bytes for next loop */ + d[0] = *(s++); + d[1] = *(s++); + d[2] = *(s++); + d[3] = *(s++); + d[4] = *(s++); + d[5] = *(s++); + d[6] = *(s++); + d[7] = *(s++); + __asm__("pref @%0" : : "r"(d)); + d += 8; + } + + /* Wait for both store queues to complete */ + d = (GLuint *)0xe0000000; + d[0] = d[8] = 0; +} + +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 */ + 0, /* No DMA */ + 0, /* No FSAA */ + 1 /* Disable translucent auto-sorting to match traditional GL */ + }; + + pvr_init(¶ms); +} + + +AlignedVector* activePolyList() { + return &OP_LIST; +} + +/* FIXME: Rename to glKosInit when experimental is core */ +void glKosBoot() { + _initPVR(); + initAttributePointers(); + + aligned_vector_init(&OP_LIST, sizeof(PVRCommand)); + aligned_vector_init(&PT_LIST, sizeof(PVRCommand)); + aligned_vector_init(&TR_LIST, sizeof(PVRCommand)); +} + +void glKosSwapBuffers() { + pvr_wait_ready(); + + pvr_scene_begin(); + + pvr_list_begin(PVR_LIST_OP_POLY); + pvr_list_submit(OP_LIST.data, OP_LIST.size); + pvr_list_finish(); + + pvr_list_begin(PVR_LIST_PT_POLY); + pvr_list_submit(PT_LIST.data, PT_LIST.size); + pvr_list_finish(); + + pvr_list_begin(PVR_LIST_TR_POLY); + pvr_list_submit(TR_LIST.data, TR_LIST.size); + pvr_list_finish(); + pvr_scene_finish(); +} diff --git a/experimental/private.h b/experimental/private.h new file mode 100644 index 0000000..a4ea851 --- /dev/null +++ b/experimental/private.h @@ -0,0 +1,25 @@ +#ifndef PRIVATE_H +#define PRIVATE_H + +#include "../include/gl.h" + +struct AlignedVector; + +AlignedVector* activePolyList(); + +void initAttributePointers(); + +#define mat_trans_fv12() { \ + __asm__ __volatile__( \ + "fldi1 fr15\n" \ + "ftrv xmtrx, fv12\n" \ + "fldi1 fr14\n" \ + "fdiv fr15, fr14\n" \ + "fmul fr14, fr12\n" \ + "fmul fr14, fr13\n" \ + : "=f" (__x), "=f" (__y), "=f" (__z) \ + : "0" (__x), "1" (__y), "2" (__z) \ + : "fr15" ); \ + } + +#endif // PRIVATE_H diff --git a/experimental/state.c b/experimental/state.c new file mode 100644 index 0000000..daa1245 --- /dev/null +++ b/experimental/state.c @@ -0,0 +1,175 @@ +#include "../include/gl.h" + +static pvr_poly_cxt_t 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. */ +static GLenum CULL_FACE = GL_BACK; +static GLenum FRONT_FACE = GL_CCW; +static GLboolean CULLING_ENABLED = GL_FALSE; + +static int _calc_pvr_face_culling() { + if(!CULLING_ENABLED) { + return PVR_CULLING_NONE; + } else { + if(CULL_FACE == GL_BACK) { + return (FRONT_FACE == GL_CW) ? PVR_CULLING_CCW : PVR_CULLING_CW; + } else { + return (FRONT_FACE == GL_CCW) ? PVR_CULLING_CCW : PVR_CULLING_CW; + } + } +} + +static GLenum DEPTH_FUNC = GL_LESS; +static GLboolean DEPTH_TEST_ENABLED = GL_FALSE; + +static int _calc_pvr_depth_test() { + if(!DEPTH_TEST_ENABLED) { + return PVR_DEPTH_CMP_ALWAYS; + } + + switch(func) { + case GL_NEVER: + return PVR_DEPTH_CMP_NEVER; + case GL_LESS: + return PVR_DEPTH_CMP_LESS; + case GL_EQUAL: + return PVR_DEPTH_CMP_EQUAL; + case GL_LEQUAL: + return PVR_DEPTH_CMP_LEQUAL; + case GL_GREATER: + return PVR_DEPTH_CMP_GREATER; + case GL_NOTEQUAL: + return PVR_DEPTH_CMP_NOTEQUAL; + case GL_GEQUAL: + return PVR_DEPTH_CMP_GEQUAL; + break; + case GL_ALWAYS: + default: + return PVR_DEPTH_CMP_ALWAYS; + } +} + + +void initContext() { + glDepthFunc(GL_LESS); + glDepthMask(GL_TRUE); + glCullFace(GL_CCW); + + glDisable(GL_ALPHA_TEST); + glDisable(GL_CULL_FACE); + glDisable(GL_BLEND); + glDisable(GL_DEPTH_TEST); + glDisable(GL_TEXTURE_2D); +} + +GLAPI void APIENTRY glEnable(GLenum cap) { + switch(cap) { + case GL_TEXTURE_2D: + GL_CONTEXT.txr.enable = 1; + break; + case GL_CULL_FACE: { + CULLING_ENABLED = GL_TRUE; + GL_CONTEXT.gen.culling = _calc_pvr_face_culling(); + } break; + case GL_DEPTH_TEST: { + DEPTH_TEST_ENABLED = GL_TRUE; + GL_CONTEXT.depth.comparison = _calc_pvr_depth_test(); + } break; + } +} + +GLAPI void APIENTRY glDisable(GLenum cap) { + switch(cap) { + case GL_TEXTURE_2D: { + GL_CONTEXT.txr.enabled = 0; + } break; + case GL_CULL_FACE: { + CULLING_ENABLED = GL_FALSE; + GL_CONTEXT.gen.culling = _calc_pvr_face_culling(); + } break; + case GL_DEPTH_TEST: { + DEPTH_TEST_ENABLED = GL_FALSE; + GL_CONTEXT.depth.comparison = _calc_pvr_depth_test(); + } break; + } +} + +/* Clear Caps */ +GLAPI void APIENTRY glClear(GLuint mode) { + +} + +GLAPI void APIENTRY glClearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a) { + +} + +/* Depth Testing */ +GLAPI void APIENTRY glClearDepthf(GLfloat depth) { + +} + +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; +} + +GLAPI void APIENTRY glDepthFunc(GLenum func) { + DEPTH_FUNC = func; + GL_CONTEXT.depth.comparison = _calc_pvr_depth_test(); +} + +/* Hints */ +/* Currently Supported Capabilities: + GL_PERSPECTIVE_CORRECTION_HINT - This will Enable Texture Super-Sampling on the PVR */ +GLAPI void APIENTRY glHint(GLenum target, GLenum mode) { + +} + +/* Culling */ +GLAPI void APIENTRY glFrontFace(GLenum mode) { + FRONT_FACE = mode; +} + +GLAPI void APIENTRY glCullFace(GLenum mode) { + CULL_FACE = mode; +} + +/* Shading - Flat or Goraud */ +GLAPI void APIENTRY glShadeModel(GLenum mode) { + +} + +/* Blending */ +GLAPI void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor) { + +} + +/* Texturing */ +GLAPI void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) { + +} + +GLAPI void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) { + +} + +GLAPI void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param) { + +} + +GLAPI void APIENTRY glGenTextures(GLsizei n, GLuint *textures) { + +} + +GLAPI void APIENTRY glDeleteTextures(GLsizei n, GLuint *textures) { + +} + +GLAPI void APIENTRY glBindTexture(GLenum target, GLuint texture) { + +} diff --git a/include/glkos.h b/include/glkos.h new file mode 100644 index 0000000..3bffbe1 --- /dev/null +++ b/include/glkos.h @@ -0,0 +1,6 @@ +#ifndef GLKOS_H +#define GLKOS_H + +void glKosSwapBuffers(); + +#endif // GLKOS_H From 62e001c288aed4991c06f79b32e71e1be631675d Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Fri, 11 May 2018 15:39:28 +0100 Subject: [PATCH 02/21] 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 From e96d379796b386141587b83066d7f02165dc705b Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Sat, 12 May 2018 14:05:54 +0100 Subject: [PATCH 03/21] Stub out lighting functionality --- experimental/draw.c | 16 ++++ experimental/flush.c | 1 + experimental/lighting.c | 139 +++++++++++++++++++++++++++++++ experimental/private.h | 32 +++++++ experimental/state.c | 41 +++++++++ gl-light.c | 179 ---------------------------------------- include/gl.h | 10 +++ 7 files changed, 239 insertions(+), 179 deletions(-) diff --git a/experimental/draw.c b/experimental/draw.c index ec3e590..9faf048 100644 --- a/experimental/draw.c +++ b/experimental/draw.c @@ -162,6 +162,8 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ const GLubyte* indices_as_bytes = (GLubyte*) indices; + GLboolean lighting_enabled = isLightingEnabled(); + for(GLuint i = first; i < count; ++i) { pvr_vertex_t* vertex = (pvr_vertex_t*) dst; vertex->u = vertex->v = 0.0f; @@ -193,6 +195,20 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ _parseFloats(normal, nptr + (idx * nstride), NORMAL_POINTER.size, NORMAL_POINTER.type); } + if(lighting_enabled) { + GLfloat contribution[4]; + uint32 to_add; + + for(GLubyte i = 0; i < MAX_LIGHTS; ++i) { + if(isLightEnabled(i)) { + calculateLightingContribution(i, &vertex->x, normal, contribution); + to_add = PVR_PACK_COLOR(contribution[0], contribution[1], contribution[2], contribution[3]); + + /* FIXME: Add the colour to argb */ + } + } + } + ++dst; } } diff --git a/experimental/flush.c b/experimental/flush.c index 967725e..1d2d1af 100644 --- a/experimental/flush.c +++ b/experimental/flush.c @@ -66,6 +66,7 @@ void APIENTRY glKosInit() { initAttributePointers(); initContext(); + initLights(); _glKosInitMatrix(); _glKosInitTextures(); diff --git a/experimental/lighting.c b/experimental/lighting.c index e69de29..56eedb3 100644 --- a/experimental/lighting.c +++ b/experimental/lighting.c @@ -0,0 +1,139 @@ +#include "private.h" + +static GLfloat SCENE_AMBIENT [] = {0.2, 0.2, 0.2, 1.0}; +static GLboolean VIEWER_IN_EYE_COORDINATES = GL_TRUE; +static GLenum COLOR_CONTROL = GL_SINGLE_COLOR; +static GLboolean TWO_SIDED_LIGHTING = GL_FALSE; + +static LightSource LIGHTS[MAX_LIGHTS]; +static Material MATERIAL; + +void initLights() { + static GLfloat ONE [] = {1.0f, 1.0f, 1.0f, 1.0f}; + static GLfloat ZERO [] = {0.0f, 0.0f, 0.0f, 1.0f}; + static GLfloat PARTIAL [] = {0.2f, 0.2f, 0.2f, 1.0f}; + static GLfloat MOSTLY [] = {0.8f, 0.8f, 0.8f, 1.0f}; + + memcpy(MATERIAL.ambient, PARTIAL, sizeof(GLfloat) * 4); + memcpy(MATERIAL.diffuse, MOSTLY, sizeof(GLfloat) * 4); + memcpy(MATERIAL.specular, ZERO, sizeof(GLfloat) * 4); + memcpy(MATERIAL.emissive, ZERO, sizeof(GLfloat) * 4); + MATERIAL.exponent = 0.0f; + MATERIAL.ambient_color_index = 0.0f; + MATERIAL.diffuse_color_index = 1.0f; + MATERIAL.specular_color_index = 1.0f; + + for(GLubyte i = 0; i < MAX_LIGHTS; ++i) { + memcpy(LIGHTS[i].ambient, ZERO, sizeof(GLfloat) * 4); + memcpy(LIGHTS[i].diffuse, ONE, sizeof(GLfloat) * 4); + memcpy(LIGHTS[i].specular, ONE, sizeof(GLfloat) * 4); + + if(i > 0) { + memcpy(LIGHTS[i].diffuse, ZERO, sizeof(GLfloat) * 4); + memcpy(LIGHTS[i].specular, ZERO, sizeof(GLfloat) * 4); + } + + LIGHTS[i].position[0] = LIGHTS[i].position[1] = LIGHTS[i].position[3] = 0.0f; + LIGHTS[i].position[2] = 1.0f; + + LIGHTS[i].spot_direction[0] = LIGHTS[i].spot_direction[1] = 0.0f; + LIGHTS[i].spot_direction[2] = -1.0f; + + LIGHTS[i].spot_exponent = 0.0f; + LIGHTS[i].spot_cutoff = 180.0f; + + LIGHTS[i].constant_attenuation = 1.0f; + LIGHTS[i].linear_attenuation = 0.0f; + LIGHTS[i].quadratic_attenuation = 0.0f; + } +} + +void APIENTRY glLightModelf(GLenum pname, const GLfloat param) { + glLightModelfv(pname, ¶m); +} + +void APIENTRY glLightModeli(GLenum pname, const GLint param) { + glLightModeliv(pname, ¶m); +} + +void APIENTRY glLightModelfv(GLenum pname, const GLfloat *params) { + switch(pname) { + case GL_LIGHT_MODEL_AMBIENT: + memcpy(SCENE_AMBIENT, params, sizeof(GLfloat) * 4); + break; + case GL_LIGHT_MODEL_LOCAL_VIEWER: + VIEWER_IN_EYE_COORDINATES = (*params) ? GL_TRUE : GL_FALSE; + break; + case GL_LIGHT_MODEL_TWO_SIDE: + /* Not implemented */ + default: + _glKosThrowError(GL_INVALID_ENUM, __func__); + _glKosPrintError(); + } +} + +void APIENTRY glLightModeliv(GLenum pname, const GLint* params) { + switch(pname) { + case GL_LIGHT_MODEL_COLOR_CONTROL: + COLOR_CONTROL = *params; + break; + case GL_LIGHT_MODEL_LOCAL_VIEWER: + VIEWER_IN_EYE_COORDINATES = (*params) ? GL_TRUE : GL_FALSE; + break; + default: + _glKosThrowError(GL_INVALID_ENUM, __func__); + _glKosPrintError(); + } +} + +void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params) { + GLubyte idx = light & 0xF; + + if(idx >= MAX_LIGHTS) { + return; + } + + switch(pname) { + case GL_AMBIENT: + memcpy(LIGHTS[idx].ambient, params, sizeof(GLfloat) * 4); + break; + case GL_DIFFUSE: + memcpy(LIGHTS[idx].diffuse, params, sizeof(GLfloat) * 4); + break; + case GL_SPECULAR: + memcpy(LIGHTS[idx].specular, params, sizeof(GLfloat) * 4); + break; + case GL_POSITION: + memcpy(LIGHTS[idx].position, params, sizeof(GLfloat) * 4); + break; + case GL_SPOT_CUTOFF: + case GL_SPOT_DIRECTION: + case GL_SPOT_EXPONENT: + case GL_CONSTANT_ATTENUATION: + case GL_LINEAR_ATTENUATION: + case GL_QUADRATIC_ATTENUATION: + default: + _glKosThrowError(GL_INVALID_ENUM, __func__); + _glKosPrintError(); + } +} + +void APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param) { + +} + +void APIENTRY glMateriali(GLenum face, GLenum pname, const GLint param) { + +} + +void APIENTRY glMaterialf(GLenum face, GLenum pname, const GLfloat param) { + +} + +void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) { + +} + +void calculateLightingContribution(const GLint light, const GLfloat* pos, const GLfloat* normal, GLfloat* colour) { + +} diff --git a/experimental/private.h b/experimental/private.h index bf74698..fc7366d 100644 --- a/experimental/private.h +++ b/experimental/private.h @@ -41,10 +41,37 @@ typedef struct { GLvoid *data; } TextureObject; +typedef struct { + GLfloat ambient[4]; + GLfloat diffuse[4]; + GLfloat specular[4]; + GLfloat emissive[4]; + GLfloat exponent; + GLfloat ambient_color_index; + GLfloat diffuse_color_index; + GLfloat specular_color_index; +} Material; + +typedef struct { + GLfloat ambient[4]; + GLfloat diffuse[4]; + GLfloat specular[4]; + GLfloat position[4]; + GLfloat spot_direction[3]; + GLfloat spot_exponent; + GLfloat spot_cutoff; + GLfloat constant_attenuation; + GLfloat linear_attenuation; + GLfloat quadratic_attenuation; +} LightSource; + + PolyList *activePolyList(); void initAttributePointers(); void initContext(); +void initLights(); + pvr_poly_cxt_t* getPVRContext(); GLubyte _glKosInitTextures(); void updatePVRTextureContext(pvr_poly_cxt_t* context, TextureObject* tx1); @@ -53,8 +80,13 @@ TextureObject* getTexture1(); TextureObject* getBoundTexture(); GLboolean isBlendingEnabled(); +GLboolean isLightingEnabled(); +GLboolean isLightEnabled(GLubyte light); +void calculateLightingContribution(const GLint light, const GLfloat* pos, const GLfloat* normal, GLfloat* colour); + #define PVR_VERTEX_BUF_SIZE 2560 * 256 #define MAX_TEXTURE_UNITS 2 +#define MAX_LIGHTS 8 #define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) ) diff --git a/experimental/state.c b/experimental/state.c index 7f39d95..c201e8a 100644 --- a/experimental/state.c +++ b/experimental/state.c @@ -150,6 +150,16 @@ void updatePVRTextureContext(pvr_poly_cxt_t* context, TextureObject *tx1) { } } +static GLboolean LIGHTING_ENABLED = GL_FALSE; +static GLboolean LIGHT_ENABLED[MAX_LIGHTS]; + +GLboolean isLightingEnabled() { + return LIGHTING_ENABLED; +} + +GLboolean isLightEnabled(unsigned char light) { + return LIGHT_ENABLED[light & 0xF]; +} static GLfloat CLEAR_COLOUR[3]; @@ -176,6 +186,11 @@ void initContext() { glDisable(GL_BLEND); glDisable(GL_DEPTH_TEST); glDisable(GL_TEXTURE_2D); + + glDisable(GL_LIGHTING); + for(GLubyte i = 0; i < MAX_LIGHTS; ++i) { + glDisable(GL_LIGHT0 + i); + } } GLAPI void APIENTRY glEnable(GLenum cap) { @@ -198,6 +213,19 @@ GLAPI void APIENTRY glEnable(GLenum cap) { case GL_SCISSOR_TEST: { GL_CONTEXT.gen.clip_mode = PVR_USERCLIP_INSIDE; } break; + case GL_LIGHTING: { + LIGHTING_ENABLED = GL_TRUE; + } break; + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + LIGHT_ENABLED[cap & 0xF] = GL_TRUE; + break; default: break; } @@ -223,6 +251,19 @@ GLAPI void APIENTRY glDisable(GLenum cap) { case GL_SCISSOR_TEST: { GL_CONTEXT.gen.clip_mode = PVR_USERCLIP_DISABLE; } break; + case GL_LIGHTING: { + LIGHTING_ENABLED = GL_FALSE; + } break; + case GL_LIGHT0: + case GL_LIGHT1: + case GL_LIGHT2: + case GL_LIGHT3: + case GL_LIGHT4: + case GL_LIGHT5: + case GL_LIGHT6: + case GL_LIGHT7: + LIGHT_ENABLED[cap & 0xF] = GL_FALSE; + break; default: break; } diff --git a/gl-light.c b/gl-light.c index 30e565f..4a1fa55 100644 --- a/gl-light.c +++ b/gl-light.c @@ -107,18 +107,6 @@ void glNormal3fv(const GLfloat *xyz) { GL_VERTEX_NORMAL[2] = xyz[2]; } -void glLightModelfv(GLenum pname, const GLfloat *params) { - if(pname != GL_LIGHT_MODEL_AMBIENT) { - _glKosThrowError(GL_INVALID_ENUM, "glLightModelfv"); - return; - } - - GL_GLOBAL_AMBIENT[0] = params[0]; - GL_GLOBAL_AMBIENT[1] = params[1]; - GL_GLOBAL_AMBIENT[2] = params[2]; - GL_GLOBAL_AMBIENT[3] = params[3]; -} - /* Misc Lighting Functions ************************************/ static inline void glCopyRGBA(const rgba *src, rgba *dst) { *dst = *src; @@ -132,173 +120,6 @@ static inline void glCopy3f(const float *src, float *dst) { memcpy(dst, src, 0xC); } -/* GL Light Parameters ******************************************************/ - -void glLightfv(GLenum light, GLenum pname, const GLfloat *params) { - if(light < GL_LIGHT0 || light > GL_LIGHT0 + GL_KOS_MAX_LIGHTS) return; - - switch(pname) { - case GL_AMBIENT: - glCopyRGBA((rgba *)params, (rgba *)&GL_LIGHTS[light & 0xF].Ka); - break; - - case GL_DIFFUSE: - glCopyRGBA((rgba *)params, (rgba *)&GL_LIGHTS[light & 0xF].Kd); - break; - - case GL_SPECULAR: - glCopyRGBA((rgba *)params, (rgba *)&GL_LIGHTS[light & 0xF].Ks); - break; - - case GL_POSITION: - glCopy4f(params, &GL_LIGHTS[light & 0xF].Pos[0]); - break; - - case GL_SPOT_DIRECTION: - glCopy3f(params, &GL_LIGHTS[light & 0xF].Dir[0]); - break; - - case GL_SPOT_EXPONENT: - GL_LIGHTS[light & 0xF].Exponent = *params; - break; - - case GL_SPOT_CUTOFF: - if(*params >= 0.0f && *params <= 180.0f) - GL_LIGHTS[light & 0xF].CutOff = LCOS(*params); - - break; - - case GL_CONSTANT_ATTENUATION: - if(*params >= 0) - GL_LIGHTS[light & 0xF].Kc = *params; - else - GL_LIGHTS[light & 0xF].Kc = 0; - - break; - - case GL_LINEAR_ATTENUATION: - if(*params >= 0) - GL_LIGHTS[light & 0xF].Kl = *params; - else - GL_LIGHTS[light & 0xF].Kl = 0; - - break; - - case GL_QUADRATIC_ATTENUATION: - if(*params >= 0) - GL_LIGHTS[light & 0xF].Kq = *params; - else - GL_LIGHTS[light & 0xF].Kq = 0; - - break; - - case GL_AMBIENT_AND_DIFFUSE: - glCopyRGBA((rgba *)params, (rgba *)&GL_LIGHTS[light & 0xF].Ka); - glCopyRGBA((rgba *)params, (rgba *)&GL_LIGHTS[light & 0xF].Kd); - break; - } -} - -void glLightf(GLenum light, GLenum pname, GLfloat param) { - if(light < GL_LIGHT0 || light > GL_LIGHT0 + GL_KOS_MAX_LIGHTS) return; - - switch(pname) { - case GL_CONSTANT_ATTENUATION: - if(param >= 0) - GL_LIGHTS[light & 0xF].Kc = param; - else - GL_LIGHTS[light & 0xF].Kc = 0; - - break; - - case GL_LINEAR_ATTENUATION: - if(param >= 0) - GL_LIGHTS[light & 0xF].Kl = param; - else - GL_LIGHTS[light & 0xF].Kl = 0; - - break; - - case GL_QUADRATIC_ATTENUATION: - if(param >= 0) - GL_LIGHTS[light & 0xF].Kq = param; - else - GL_LIGHTS[light & 0xF].Kq = 0; - - break; - - case GL_SPOT_CUTOFF: - if(param >= 0.0f && param <= 180.0f) - GL_LIGHTS[light & 0xF].CutOff = LCOS(param); - - break; - - case GL_SPOT_EXPONENT: - GL_LIGHTS[light & 0xF].Exponent = param; - break; - } -} - -/* GL Material Parameters **************************************************/ - -void glMateriali(GLenum face, GLenum pname, const GLint param) { - //if(face!=GL_FRONT_AND_BACK) return; - - if(pname == GL_SHININESS) { - if(param < 0) - GL_MATERIAL.Shine = 0; - else if(param > 128) - GL_MATERIAL.Shine = 128; - else - GL_MATERIAL.Shine = param; - } -} - -void glMaterialf(GLenum face, GLenum pname, const GLfloat param) { - //if(face!=GL_FRONT_AND_BACK) return; - - if(pname == GL_SHININESS) { - if(param < 0) - GL_MATERIAL.Shine = 0; - else if(param > 128.0) - GL_MATERIAL.Shine = 128.0; - else - GL_MATERIAL.Shine = param; - } -} - -void glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) { - //if(face!=GL_FRONT_AND_BACK) return; - - switch(pname) { - case GL_AMBIENT: - glCopyRGBA((rgba *)params, (rgba *)&GL_MATERIAL.Ka[0]); - break; - - case GL_DIFFUSE: - glCopyRGBA((rgba *)params, (rgba *)&GL_MATERIAL.Kd[0]); - break; - - case GL_SPECULAR: - glCopyRGBA((rgba *)params, (rgba *)&GL_MATERIAL.Ks[0]); - break; - - case GL_EMISSION: - glCopyRGBA((rgba *)params, (rgba *)&GL_MATERIAL.Ke[0]); - break; - - case GL_SHININESS: - glMaterialf(GL_FRONT_AND_BACK, pname, *params); - break; - - case GL_AMBIENT_AND_DIFFUSE: - glCopyRGBA((rgba *)params, (rgba *)&GL_MATERIAL.Ka[0]); - glCopyRGBA((rgba *)params, (rgba *)&GL_MATERIAL.Kd[0]); - break; - } - -} - /* Vertex Lighting **********************************************************/ /* Fast POW Implementation - Less accurate, but much faster than math.h */ diff --git a/include/gl.h b/include/gl.h index 0d87dbe..60f5a09 100644 --- a/include/gl.h +++ b/include/gl.h @@ -235,6 +235,11 @@ __BEGIN_DECLS #define GL_LIGHT14 0x400E #define GL_LIGHT15 0x400F +/* EXT_separate_specular_color.txt */ +#define GL_LIGHT_MODEL_COLOR_CONTROL 0x81F8 +#define GL_SINGLE_COLOR 0x81F9 +#define GL_SEPARATE_SPECULAR_COLOR 0x81FA + /* Client state caps */ #define GL_VERTEX_ARRAY 0x8074 #define GL_NORMAL_ARRAY 0x8075 @@ -620,7 +625,12 @@ GLAPI void APIENTRY glFogfv(GLenum pname, const GLfloat *params); /* Set Individual Light Parameters */ GLAPI void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params); GLAPI void APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param); + +GLAPI void APIENTRY glLightModelf(GLenum pname, const GLfloat param); +GLAPI void APIENTRY glLightModeli(GLenum pname, const GLint param); GLAPI void APIENTRY glLightModelfv(GLenum pname, const GLfloat *params); +GLAPI void APIENTRY glLightModeliv(GLenum pname, const GLint *params); + /* Set Global Material Parameters */ GLAPI void APIENTRY glMateriali(GLenum face, GLenum pname, const GLint param); From 146be442f469737f170bdd44147478c1bab1fb65 Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Sat, 12 May 2018 14:39:20 +0100 Subject: [PATCH 04/21] Start reimplementing immediate mode and removing dead code --- experimental/flush.c | 1 + experimental/immediate.c | 58 +++++++++++++ experimental/private.h | 1 + experimental/state.c | 32 ++++++++ gl-api.c | 170 --------------------------------------- gl-api.h | 20 ----- gl-arrays.c | 13 --- gl-cap.c | 95 ---------------------- gl-pvr.c | 9 --- gl-texture.c | 85 -------------------- include/gl.h | 2 +- 11 files changed, 93 insertions(+), 393 deletions(-) delete mode 100644 gl-texture.c diff --git a/experimental/flush.c b/experimental/flush.c index 1d2d1af..b689156 100644 --- a/experimental/flush.c +++ b/experimental/flush.c @@ -67,6 +67,7 @@ void APIENTRY glKosInit() { initAttributePointers(); initContext(); initLights(); + initImmediateMode(); _glKosInitMatrix(); _glKosInitTextures(); diff --git a/experimental/immediate.c b/experimental/immediate.c index e69de29..e26b391 100644 --- a/experimental/immediate.c +++ b/experimental/immediate.c @@ -0,0 +1,58 @@ +#include "../include/gl.h" +#include "private.h" + +static GLboolean IMMEDIATE_MODE_ACTIVE = GL_FALSE; +static GLenum ACTIVE_POLYGON_MODE = GL_TRIANGLES; + +static AlignedVector VERTICES; +static AlignedVector COLOURS; + +void initImmediateMode() { + aligned_vector_init(&VERTICES, sizeof(GLfloat)); + aligned_vector_init(&COLOURS, sizeof(GLfloat)); +} + +void APIENTRY glBegin(GLenum mode) { + if(IMMEDIATE_MODE_ACTIVE) { + _glKosThrowError(GL_INVALID_OPERATION, __func__); + _glKosPrintError(); + return; + } + + IMMEDIATE_MODE_ACTIVE = GL_TRUE; + ACTIVE_POLYGON_MODE = mode; +} + +void APIENTRY glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) { + aligned_vector_push_back(&COLOURS, &r, 1); + aligned_vector_push_back(&COLOURS, &g, 1); + aligned_vector_push_back(&COLOURS, &b, 1); + aligned_vector_push_back(&COLOURS, &a, 1); +} + +void APIENTRY glColor3f(GLfloat r, GLfloat g, GLfloat b) { + static float a = 1.0f; + glColor4f(r, g, b, a); +} + +void APIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z) { + aligned_vector_push_back(&VERTICES, &x, 1); + aligned_vector_push_back(&VERTICES, &y, 1); + aligned_vector_push_back(&VERTICES, &z, 1); +} + +void APIENTRY glEnd() { + IMMEDIATE_MODE_ACTIVE = GL_FALSE; + + /* FIXME: Push pointers */ + + glVertexPointer(3, GL_FLOAT, 0, VERTICES.data); + glColorPointer(4, GL_FLOAT, 0, COLOURS.data); + + glDrawArrays(ACTIVE_POLYGON_MODE, 0, VERTICES.size / 3); + + aligned_vector_clear(&VERTICES); + aligned_vector_clear(&COLOURS); + + /* FIXME: Pop pointers */ +} diff --git a/experimental/private.h b/experimental/private.h index fc7366d..0c3ab27 100644 --- a/experimental/private.h +++ b/experimental/private.h @@ -71,6 +71,7 @@ PolyList *activePolyList(); void initAttributePointers(); void initContext(); void initLights(); +void initImmediateMode(); pvr_poly_cxt_t* getPVRContext(); GLubyte _glKosInitTextures(); diff --git a/experimental/state.c b/experimental/state.c index c201e8a..a6fdc09 100644 --- a/experimental/state.c +++ b/experimental/state.c @@ -395,3 +395,35 @@ void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height) { c->ey = CLAMP((maxy / 32) - 1, 0, vid_mode->height / 32); } + +GLboolean APIENTRY glIsEnabled(GLenum cap) { + switch(cap) { + case GL_DEPTH_TEST: + return DEPTH_TEST_ENABLED; + case GL_SCISSOR_TEST: + return GL_CONTEXT.gen.clip_mode == PVR_USERCLIP_INSIDE; + case GL_CULL_FACE: + return CULLING_ENABLED; + case GL_LIGHTING: + return LIGHTING_ENABLED; + case GL_BLEND: + return BLEND_ENABLED; + } + + return GL_FALSE; +} + +void APIENTRY glGetIntegerv(GLenum pname, GLint *params) { + switch(pname) { + case GL_MAX_LIGHTS: + *params = MAX_LIGHTS; + break; + case GL_TEXTURE_BINDING_2D: + *params = getBoundTexture()->index; + break; + default: + _glKosThrowError(GL_INVALID_ENUM, "glGetIntegerv"); + _glKosPrintError(); + break; + } +} diff --git a/gl-api.c b/gl-api.c index 0f82665..eac3947 100644 --- a/gl-api.c +++ b/gl-api.c @@ -248,18 +248,10 @@ void APIENTRY glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a) { GL_KOS_VERTEX_COLOR = a << 24 | r << 16 | g << 8 | b; } -void APIENTRY glColor3f(GLfloat r, GLfloat g, GLfloat b) { - GL_KOS_VERTEX_COLOR = PVR_PACK_COLOR(1.0f, r, g, b); -} - void APIENTRY glColor3fv(const GLfloat *rgb) { GL_KOS_VERTEX_COLOR = PVR_PACK_COLOR(1.0f, rgb[0], rgb[1], rgb[2]); } -void APIENTRY glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) { - GL_KOS_VERTEX_COLOR = PVR_PACK_COLOR(a, r, g, b); -} - void APIENTRY glColor4fv(const GLfloat *rgba) { GL_KOS_VERTEX_COLOR = PVR_PACK_COLOR(rgba[3], rgba[0], rgba[1], rgba[2]); } @@ -296,8 +288,6 @@ void APIENTRY glTexCoord2fv(const GLfloat *uv) { //== Vertex Position Submission Functions ==// -void APIENTRY(*glVertex3f)(GLfloat, GLfloat, GLfloat); - void APIENTRY(*glVertex3fv)(const GLfloat *); void APIENTRY glVertex2f(GLfloat x, GLfloat y) { @@ -371,92 +361,6 @@ void APIENTRY glKosVertex2fv(const GLfloat *xy) { //====================================================================================================// //== GL Begin / End ==// -void APIENTRY glBegin(GLenum mode) { - _glKosMatrixApplyRender(); - - _glKosArrayBufReset(); - - _glKosEnabledTexture2D() ? _glKosCompileHdrTx() : _glKosCompileHdr(); - - GL_KOS_VERTEX_MODE = mode; - GL_KOS_VERTEX_COUNT = 0; - - if(mode == GL_POINTS) { - glVertex3f = _glKosVertex3fp; - glVertex3fv = _glKosVertex3fpv; - } - else if(_glKosEnabledNearZClip() - && _glKosEnabledLighting()) { - glVertex3f = _glKosVertex3flc; - glVertex3fv = _glKosVertex3flcv; - } - else if(_glKosEnabledLighting()) { - glVertex3f = _glKosVertex3fl; - glVertex3fv = _glKosVertex3flv; - } - else if(_glKosEnabledNearZClip()) { - glVertex3f = _glKosVertex3fc; - glVertex3fv = _glKosVertex3fcv; - } - else { - glVertex3f = _glKosVertex3ft; - glVertex3fv = _glKosVertex3ftv; - } -} - -void APIENTRY glEnd() { - if(_glKosEnabledNearZClip()) { /* Z-Clipping Enabled */ - if(_glKosEnabledLighting()) { - _glKosVertexComputeLighting(_glKosClipBufAddress(), GL_KOS_VERTEX_COUNT); - - _glKosMatrixLoadRender(); - } - - GLuint cverts; - pvr_vertex_t *v = _glKosVertexBufPointer(); - - switch(GL_KOS_VERTEX_MODE) { - case GL_TRIANGLES: - cverts = _glKosClipTriangles(_glKosClipBufAddress(), v, GL_KOS_VERTEX_COUNT); - _glKosTransformClipBuf(v, cverts); - _glKosVertexBufAdd(cverts); - break; - - case GL_TRIANGLE_STRIP: - cverts = _glKosClipTriangleStrip(_glKosClipBufAddress(), v, GL_KOS_VERTEX_COUNT); - _glKosTransformClipBuf(v, cverts); - _glKosVertexBufAdd(cverts); - break; - - case GL_QUADS: - cverts = _glKosClipQuads(_glKosClipBufAddress(), v, GL_KOS_VERTEX_COUNT); - _glKosTransformClipBuf(v, cverts); - _glKosVertexBufAdd(cverts); - break; - } - - _glKosClipBufReset(); - } - else { /* No Z-Clipping Enabled */ - if(_glKosEnabledLighting()) - _glKosVertexComputeLighting((pvr_vertex_t *)_glKosVertexBufPointer() - GL_KOS_VERTEX_COUNT, GL_KOS_VERTEX_COUNT); - - switch(GL_KOS_VERTEX_MODE) { - case GL_TRIANGLES: - _glKosFlagsSetTriangle(); - break; - - case GL_TRIANGLE_STRIP: - _glKosFlagsSetTriangleStrip(); - break; - - case GL_QUADS: - _glKosFlagsSetQuad(); - break; - } - } -} - //====================================================================================================// //== Misc. functions ==// @@ -715,12 +619,6 @@ static inline void _glKosApplyBlendFunc() { } } -static inline void _glKosApplyTextureFunc(GL_TEXTURE_OBJECT *tex) { - GL_KOS_POLY_CXT.txr.uv_clamp = tex->uv_clamp; - GL_KOS_POLY_CXT.txr.mipmap = tex->mip_map ? 1 : 0; - GL_KOS_POLY_CXT.txr.mipmap_bias = PVR_MIPBIAS_NORMAL; -} - void _glKosCompileHdr() { pvr_poly_hdr_t *hdr = _glKosVertexBufPointer(); @@ -742,74 +640,6 @@ void _glKosCompileHdr() { _glKosVertexBufIncrement(); } - -void _glKosCompileHdrT(GL_TEXTURE_OBJECT *tex) { - pvr_poly_hdr_t *hdr = _glKosVertexBufPointer(); - - pvr_poly_cxt_txr(&GL_KOS_POLY_CXT, - _glKosList() * 2, - tex->color, - tex->width, - tex->height, - tex->data, - tex->filter); - - GL_KOS_POLY_CXT.gen.shading = GL_KOS_SHADE_FUNC; - - _glKosApplyDepthFunc(); - - _glKosApplyScissorFunc(); - - _glKosApplyFogFunc(); - - _glKosApplyCullingFunc(); - - _glKosApplyBlendFunc(); - - _glKosApplyTextureFunc(tex); - - if(_glKosEnabledBlend()) - GL_KOS_POLY_CXT.txr.env = tex->env; - - pvr_poly_compile(hdr, &GL_KOS_POLY_CXT); - - if(GL_KOS_SUPERSAMPLE) - hdr->mode2 |= GL_PVR_SAMPLE_SUPER << PVR_TA_SUPER_SAMPLE_SHIFT; - - _glKosVertexBufIncrement(); -} - -void _glKosCompileHdrMT(pvr_poly_hdr_t *dst, GL_TEXTURE_OBJECT *tex) { - pvr_poly_cxt_txr(&GL_KOS_POLY_CXT, - PVR_LIST_TR_POLY, - tex->color, - tex->width, - tex->height, - tex->data, - tex->filter); - - GL_KOS_POLY_CXT.gen.shading = GL_KOS_SHADE_FUNC; - - _glKosApplyDepthFunc(); - - _glKosApplyScissorFunc(); - - _glKosApplyFogFunc(); - - _glKosApplyCullingFunc(); - - _glKosApplyTextureFunc(tex); - - GL_KOS_POLY_CXT.blend.src = (GL_KOS_BLEND_FUNC & 0xF0) >> 4; - GL_KOS_POLY_CXT.blend.dst = (GL_KOS_BLEND_FUNC & 0x0F); - GL_KOS_POLY_CXT.txr.env = tex->env; - - pvr_poly_compile(dst, &GL_KOS_POLY_CXT); - - if(GL_KOS_SUPERSAMPLE) - dst->mode2 |= GL_PVR_SAMPLE_SUPER << PVR_TA_SUPER_SAMPLE_SHIFT; -} - //====================================================================================================// //== Internal GL KOS API State Functions ==// diff --git a/gl-api.h b/gl-api.h index f8e2751..2cf9ae9 100644 --- a/gl-api.h +++ b/gl-api.h @@ -25,18 +25,6 @@ typedef struct { GLfloat s, t, r, q; } glTexCoord4f; /* 3D Texture Coordinate */ -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; -} GL_TEXTURE_OBJECT; /* KOS Open GL Texture Object */ - typedef struct { GLuint texID; GLsizei index; @@ -95,8 +83,6 @@ unsigned char _glKosInitTextures(); void _glKosCompileHdr(); void _glKosCompileHdrTx(); void _glKosCompileHdrMTx(); -void _glKosCompileHdrT(GL_TEXTURE_OBJECT *tex); -void _glKosCompileHdrMT(pvr_poly_hdr_t *dst, GL_TEXTURE_OBJECT *tex); /* Clipping Internal Functions */ void _glKosTransformClipBuf(pvr_vertex_t *v, GLuint verts); @@ -207,14 +193,8 @@ GLuint _glKosVertexColor(); GLubyte _glKosMaxTextureUnits(); GLubyte _glKosEnabledTextureMatrix(); -GL_TEXTURE_OBJECT *_glKosBoundMultiTexObject(); -GL_TEXTURE_OBJECT *_glKosBoundTexObject(); GLuint _glKosActiveTextureBoundTexID(); -void _glKosPushMultiTexObject(GL_TEXTURE_OBJECT *tex, - pvr_vertex_t *src, - GLuint count); - static inline void _glKosVertexCopyPVR(const pvr_vertex_t *src, pvr_vertex_t *dst) { *dst = *src; } diff --git a/gl-arrays.c b/gl-arrays.c index ba33911..d875303 100644 --- a/gl-arrays.c +++ b/gl-arrays.c @@ -826,19 +826,6 @@ static GLuint _glKosArraysApplyClipping(GLfloat *uvsrc, GLuint uvstride, GLenum return count; } -static inline void _glKosArraysApplyMultiTexture(GLenum mode, GLuint count) { - if(GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_TEXTURE1) { - GL_TEXTURE_OBJECT* tex = _glKosBoundMultiTexObject(); - if(tex) { - _glKosPushMultiTexObject(tex, - (pvr_vertex_t *)_glKosVertexBufPointer(), - count); - - if(mode == GL_QUADS) - _glKosArraysSwizzleQuadsMultiTex(count); - } - } -} static inline void _glKosArraysApplyVertexFlags(GLenum mode, pvr_vertex_t *dst, GLuint count) { switch(mode) { diff --git a/gl-cap.c b/gl-cap.c index 54a2425..63996ad 100644 --- a/gl-cap.c +++ b/gl-cap.c @@ -114,101 +114,6 @@ static GLbitfield GL_KOS_ENABLE_CAP = 0; // } //} -GLboolean APIENTRY glIsEnabled(GLenum cap) { - if(cap >= GL_LIGHT0 && cap <= GL_LIGHT15) return _glKosIsLightEnabled(cap & 0xFF); - - switch(cap) { - case GL_DEPTH_TEST: - return _glKosEnabledDepthTest() ? GL_TRUE : GL_FALSE; - - case GL_SCISSOR_TEST: - return _glKosEnabledScissorTest() ? GL_TRUE : GL_FALSE; - - case GL_CULL_FACE: - return _glKosEnabledCulling() ? GL_TRUE : GL_FALSE; - - case GL_FOG: - return _glKosEnabledFog() ? GL_TRUE : GL_FALSE; - - case GL_LIGHTING: - return _glKosEnabledLighting() ? GL_TRUE : GL_FALSE; - - case GL_KOS_NEARZ_CLIPPING: - return _glKosEnabledNearZClip() ? GL_TRUE : GL_FALSE; - - case GL_TEXTURE_2D: - return _glKosEnabledTexture2D() ? GL_TRUE : GL_FALSE; - - case GL_BLEND: - return _glKosEnabledBlend() ? GL_TRUE : GL_FALSE; - - case GL_KOS_TEXTURE_MATRIX: - return _glKosEnabledTextureMatrix() ? GL_TRUE : GL_FALSE; - } - - return GL_FALSE; -} - -void APIENTRY glGetIntegerv(GLenum pname, GLint *params) { - switch(pname) { - case GL_ACTIVE_TEXTURE: - *params = 0; - break; - - case GL_BLEND: - *params = _glKosList(); - break; - - case GL_BLEND_DST: - *params = _glKosBlendSrcFunc(); - break; - - case GL_BLEND_SRC: - *params = _glKosBlendDstFunc(); - break; - - case GL_CULL_FACE: - *params = _glKosEnabledCulling(); - break; - - case GL_CULL_FACE_MODE: - *params = _glKosCullFaceMode(); - break; - - case GL_DEPTH_FUNC: - *params = _glKosDepthFunc(); - break; - - case GL_DEPTH_TEST: - *params = _glKosEnabledDepthTest(); - break; - - case GL_DEPTH_WRITEMASK: - *params = _glKosDepthMask(); - break; - - case GL_FRONT_FACE: - *params = _glKosCullFaceFront(); - break; - - case GL_SCISSOR_TEST: - *params = _glKosEnabledScissorTest(); - break; - - case GL_MAX_LIGHTS: - *params = _glKosGetMaxLights(); - break; - - case GL_TEXTURE_BINDING_2D: - *params = _glKosActiveTextureBoundTexID(); - break; - - default: - _glKosThrowError(GL_INVALID_ENUM, "glGetIntegerv"); - _glKosPrintError(); - break; - } -} void APIENTRY glGetFloatv(GLenum pname, GLfloat *params) { switch(pname) { diff --git a/gl-pvr.c b/gl-pvr.c index 7fe546c..06b7a2d 100644 --- a/gl-pvr.c +++ b/gl-pvr.c @@ -93,15 +93,6 @@ static void pvr_hdr_submit(const GLuint *src) { } #endif -void _glKosPushMultiTexObject(GL_TEXTURE_OBJECT *tex, - pvr_vertex_t *src, - GLuint count) { - _glKosCompileHdrMT(&GL_MTOBJS[GL_MTOBJECTS].hdr, tex); - - GL_MTOBJS[GL_MTOBJECTS].src = src; - GL_MTOBJS[GL_MTOBJECTS++].count = count; -} - void _glKosResetMultiTexObject() { GL_MTOBJECTS = 0; } diff --git a/gl-texture.c b/gl-texture.c deleted file mode 100644 index 937f354..0000000 --- a/gl-texture.c +++ /dev/null @@ -1,85 +0,0 @@ -/* KallistiGL for KallistiOS ##version## - - libgl/gl-texture.c - Copyright (C) 2014 Josh Pearson - Copyright (C) 2016 Joe Fenton - - Open GL Texture Submission implementation. -*/ - -#include -#include -#include - -#include "gl.h" -#include "glext.h" -#include "gl-api.h" -#include "gl-rgb.h" -#include "containers/named_array.h" - -//========================================================================================// -//== Internal KOS Open GL Texture Unit Structures / Global Variables ==// - -#define GL_KOS_MAX_TEXTURE_UNITS 2 - - -static GL_TEXTURE_OBJECT *GL_KOS_TEXTURE_UNIT[GL_KOS_MAX_TEXTURE_UNITS] = { NULL, NULL }; -static NamedArray TEXTURE_OBJECTS; - -static GLubyte GL_KOS_ACTIVE_TEXTURE = GL_TEXTURE0_ARB & 0xF; - -//========================================================================================// - - -GLuint _glKosTextureWidth(GLuint index) { - GL_TEXTURE_OBJECT *tex = (GL_TEXTURE_OBJECT*) named_array_get(&TEXTURE_OBJECTS, index); - return tex->width; -} - -GLuint _glKosTextureHeight(GLuint index) { - GL_TEXTURE_OBJECT *tex = (GL_TEXTURE_OBJECT*) named_array_get(&TEXTURE_OBJECTS, index); - return tex->height; -} - -GLvoid *_glKosTextureData(GLuint index) { - GL_TEXTURE_OBJECT *tex = (GL_TEXTURE_OBJECT*) named_array_get(&TEXTURE_OBJECTS, index); - return tex->data; -} - -void _glKosCompileHdrTx() { - return GL_KOS_TEXTURE_UNIT[GL_TEXTURE0_ARB & 0xF] ? - _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]; -} - -GLuint _glKosBoundMultiTexID() { - return GL_KOS_TEXTURE_UNIT[GL_TEXTURE1_ARB & 0xF] ? - GL_KOS_TEXTURE_UNIT[GL_TEXTURE1_ARB & 0xF]->index : 0; -} - -GLuint _glKosBoundTexID() { - return GL_KOS_TEXTURE_UNIT[GL_TEXTURE0_ARB & 0xF] ? - GL_KOS_TEXTURE_UNIT[GL_TEXTURE0_ARB & 0xF]->index : 0; -} - -GLuint _glKosActiveTextureBoundTexID() { - return (GL_KOS_ACTIVE_TEXTURE) ? _glKosBoundMultiTexID() : _glKosBoundTexID(); -} - -GLubyte _glKosMaxTextureUnits() { - return GL_KOS_MAX_TEXTURE_UNITS; -} - -//========================================================================================// -//== Public KOS Open GL API Texture Unit Functionality ==// - - - - diff --git a/include/gl.h b/include/gl.h index 60f5a09..a999be1 100644 --- a/include/gl.h +++ b/include/gl.h @@ -445,7 +445,7 @@ GLAPI void APIENTRY glKosVertex2f(GLfloat x, GLfloat y); GLAPI void APIENTRY glKosVertex2fv(const GLfloat *xy); /* Primitive 3D Position Submission */ -GLAPI void APIENTRY(*glVertex3f)(GLfloat, GLfloat, GLfloat); +GLAPI void APIENTRY glVertex3f(GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY(*glVertex3fv)(const GLfloat *); /* 2D Non-Textured Rectangle Submission */ From 4b8991e45f75b5782f8da13a6fdbe663ed0745d0 Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Sat, 12 May 2018 14:54:06 +0100 Subject: [PATCH 05/21] More immediate mode --- experimental/draw.c | 8 ++++++++ experimental/immediate.c | 44 +++++++++++++++++++++++++++++++++++++++- experimental/private.h | 1 + experimental/state.c | 1 - gl-api.c | 39 ----------------------------------- include/gl.h | 2 +- 6 files changed, 53 insertions(+), 42 deletions(-) diff --git a/experimental/draw.c b/experimental/draw.c index 9faf048..7e821b6 100644 --- a/experimental/draw.c +++ b/experimental/draw.c @@ -216,12 +216,20 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices) { TRACE(); + if(checkImmediateModeInactive(__func__)) { + return; + } + submitVertices(mode, 0, count, type, indices); } void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count) { TRACE(); + if(checkImmediateModeInactive(__func__)) { + return; + } + submitVertices(mode, first, count, GL_UNSIGNED_SHORT, NULL); } diff --git a/experimental/immediate.c b/experimental/immediate.c index e26b391..d43c579 100644 --- a/experimental/immediate.c +++ b/experimental/immediate.c @@ -6,10 +6,23 @@ static GLenum ACTIVE_POLYGON_MODE = GL_TRIANGLES; static AlignedVector VERTICES; static AlignedVector COLOURS; +static AlignedVector TEXCOORDS; void initImmediateMode() { aligned_vector_init(&VERTICES, sizeof(GLfloat)); aligned_vector_init(&COLOURS, sizeof(GLfloat)); + aligned_vector_init(&TEXCOORDS, sizeof(GLfloat)); +} + +GLubyte checkImmediateModeInactive(const char* func) { + /* Returns 1 on error */ + if(IMMEDIATE_MODE_ACTIVE) { + _glKosThrowError(GL_INVALID_OPERATION, func); + _glKosPrintError(); + return 1; + } + + return 0; } void APIENTRY glBegin(GLenum mode) { @@ -30,29 +43,58 @@ void APIENTRY glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) { aligned_vector_push_back(&COLOURS, &a, 1); } +void APIENTRY glColor4fv(const GLfloat* v) { + glColor4f(v[0], v[1], v[2], v[3]); +} + void APIENTRY glColor3f(GLfloat r, GLfloat g, GLfloat b) { static float a = 1.0f; glColor4f(r, g, b, a); } +void APIENTRY glColor3fv(const GLfloat* v) { + glColor3f(v[0], v[1], v[2]); +} + void APIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z) { aligned_vector_push_back(&VERTICES, &x, 1); aligned_vector_push_back(&VERTICES, &y, 1); aligned_vector_push_back(&VERTICES, &z, 1); } +void APIENTRY glVertex3fv(const GLfloat* v) { + glVertex3f(v[0], v[1], v[2]); +} + +void APIENTRY glVertex4fv(const GLfloat* v) { + glVertex4f(v[0], v[1], v[2], v[3]); +} + +void APIENTRY glTexCoord2f(GLfloat u, GLfloat v) { + aligned_vector_push_back(&TEXCOORDS, &u, 1); + aligned_vector_push_back(&TEXCOORDS, &v, 1); +} + +void APIENTRY glTexCoord2fv(const GLfloat* v) { + glTexCoord2f(v[0], v[1]); +} + void APIENTRY glEnd() { IMMEDIATE_MODE_ACTIVE = GL_FALSE; - /* FIXME: Push pointers */ + /* FIXME: Push pointer state */ glVertexPointer(3, GL_FLOAT, 0, VERTICES.data); glColorPointer(4, GL_FLOAT, 0, COLOURS.data); + glClientActiveTextureARB(GL_TEXTURE0); + glTexCoordPointer(2, GL_FLOAT, 0, TEXCOORDS.data); + glDrawArrays(ACTIVE_POLYGON_MODE, 0, VERTICES.size / 3); aligned_vector_clear(&VERTICES); aligned_vector_clear(&COLOURS); + aligned_vector_clear(&TEXCOORDS); /* FIXME: Pop pointers */ } diff --git a/experimental/private.h b/experimental/private.h index 0c3ab27..1ead5c5 100644 --- a/experimental/private.h +++ b/experimental/private.h @@ -72,6 +72,7 @@ void initAttributePointers(); void initContext(); void initLights(); void initImmediateMode(); +GLubyte checkImmediateModeInactive(const char* func); pvr_poly_cxt_t* getPVRContext(); GLubyte _glKosInitTextures(); diff --git a/experimental/state.c b/experimental/state.c index a6fdc09..108ce67 100644 --- a/experimental/state.c +++ b/experimental/state.c @@ -395,7 +395,6 @@ void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height) { c->ey = CLAMP((maxy / 32) - 1, 0, vid_mode->height / 32); } - GLboolean APIENTRY glIsEnabled(GLenum cap) { switch(cap) { case GL_DEPTH_TEST: diff --git a/gl-api.c b/gl-api.c index eac3947..852d42d 100644 --- a/gl-api.c +++ b/gl-api.c @@ -248,48 +248,9 @@ void APIENTRY glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a) { GL_KOS_VERTEX_COLOR = a << 24 | r << 16 | g << 8 | b; } -void APIENTRY glColor3fv(const GLfloat *rgb) { - GL_KOS_VERTEX_COLOR = PVR_PACK_COLOR(1.0f, rgb[0], rgb[1], rgb[2]); -} - -void APIENTRY glColor4fv(const GLfloat *rgba) { - GL_KOS_VERTEX_COLOR = PVR_PACK_COLOR(rgba[3], rgba[0], rgba[1], rgba[2]); -} - -//== Texture Coordinate Submission ==// - -void APIENTRY glTexCoord2f(GLfloat u, GLfloat v) { - if(_glKosEnabledTextureMatrix()) { - _glKosMatrixLoadTexture(); - - mat_trans_texture2_nomod(u, v, GL_KOS_VERTEX_UV[0], GL_KOS_VERTEX_UV[1]); - - _glKosMatrixLoadRender(); - } - else { - GL_KOS_VERTEX_UV[0] = u; - GL_KOS_VERTEX_UV[1] = v; - } -} - -void APIENTRY glTexCoord2fv(const GLfloat *uv) { - if(_glKosEnabledTextureMatrix()) { - _glKosMatrixLoadTexture(); - - mat_trans_texture2_nomod(uv[0], uv[1], GL_KOS_VERTEX_UV[0], GL_KOS_VERTEX_UV[1]); - - _glKosMatrixLoadRender(); - } - else { - GL_KOS_VERTEX_UV[0] = uv[0]; - GL_KOS_VERTEX_UV[1] = uv[1]; - } -} //== Vertex Position Submission Functions ==// -void APIENTRY(*glVertex3fv)(const GLfloat *); - void APIENTRY glVertex2f(GLfloat x, GLfloat y) { return _glKosVertex3ft(x, y, 0.0f); } diff --git a/include/gl.h b/include/gl.h index a999be1..2bbb566 100644 --- a/include/gl.h +++ b/include/gl.h @@ -446,7 +446,7 @@ GLAPI void APIENTRY glKosVertex2fv(const GLfloat *xy); /* Primitive 3D Position Submission */ GLAPI void APIENTRY glVertex3f(GLfloat, GLfloat, GLfloat); -GLAPI void APIENTRY(*glVertex3fv)(const GLfloat *); +GLAPI void APIENTRY glVertex3fv(const GLfloat *); /* 2D Non-Textured Rectangle Submission */ GLAPI GLvoid APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); From a09e05b01ad59ae9cf8c9cefc4ef4e5647395b58 Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Sat, 12 May 2018 21:01:51 +0100 Subject: [PATCH 06/21] More lighting work --- experimental/draw.c | 17 ++++++++++++++--- experimental/lighting.c | 3 ++- experimental/state.c | 7 ++++--- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/experimental/draw.c b/experimental/draw.c index 7e821b6..9b921d6 100644 --- a/experimental/draw.c +++ b/experimental/draw.c @@ -144,6 +144,7 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ // Compile pvr_poly_cxt_t cxt = *getPVRContext(); cxt.list_type = activePolyList()->list_type; + updatePVRTextureContext(&cxt, getTexture0()); pvr_poly_compile(hdr, &cxt); @@ -167,7 +168,7 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ 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->argb = 0; vertex->oargb = 0; vertex->flags = PVR_CMD_VERTEX; @@ -202,9 +203,19 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ for(GLubyte i = 0; i < MAX_LIGHTS; ++i) { if(isLightEnabled(i)) { calculateLightingContribution(i, &vertex->x, normal, contribution); - to_add = PVR_PACK_COLOR(contribution[0], contribution[1], contribution[2], contribution[3]); + to_add = PVR_PACK_COLOR(contribution[3], contribution[0], contribution[1], contribution[2]); - /* FIXME: Add the colour to argb */ + GLubyte a = ((vertex->argb & 0xFF000000) >> 24) + ((to_add & 0xFF000000) >> 24); + GLubyte r = ((vertex->argb & 0x00FF0000) >> 16) + ((to_add & 0x00FF0000) >> 16); + GLubyte g = ((vertex->argb & 0x0000FF00) >> 8) + ((to_add & 0x0000FF00) >> 8); + GLubyte b = ((vertex->argb & 0x000000FF) >> 0) + ((to_add & 0x000000FF) >> 0); + + a = (a > 255) ? 255 : a; + r = (r > 255) ? 255 : r; + g = (g > 255) ? 255 : g; + b = (b > 255) ? 255 : b; + + vertex->argb = a << 24 | r << 16 | g << 8 | b; } } } diff --git a/experimental/lighting.c b/experimental/lighting.c index 56eedb3..df8f642 100644 --- a/experimental/lighting.c +++ b/experimental/lighting.c @@ -135,5 +135,6 @@ void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) { } void calculateLightingContribution(const GLint light, const GLfloat* pos, const GLfloat* normal, GLfloat* colour) { - + colour[0] = colour[3] = 0.0f; + colour[1] = colour[2] = 0.0f; } diff --git a/experimental/state.c b/experimental/state.c index 108ce67..7782a23 100644 --- a/experimental/state.c +++ b/experimental/state.c @@ -78,7 +78,6 @@ static int _calcPVRBlendFactor(GLenum 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; @@ -86,13 +85,14 @@ static int _calcPVRBlendFactor(GLenum factor) { 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: + return PVR_BLEND_ONE; default: + fprintf(stderr, "Invalid blend mode: %d\n", factor); return PVR_BLEND_ONE; } } @@ -132,7 +132,7 @@ void updatePVRTextureContext(pvr_poly_cxt_t* context, TextureObject *tx1) { } context->txr2.enable = PVR_TEXTURE_DISABLE; - context->txr2.alpha = PVR_ALPHA_DISABLE; + context->txr2.alpha = PVR_TXRALPHA_DISABLE; if(tx1) { context->txr.enable = PVR_TEXTURE_ENABLE; @@ -145,6 +145,7 @@ void updatePVRTextureContext(pvr_poly_cxt_t* context, TextureObject *tx1) { context->txr.env = tx1->env; context->txr.uv_flip = PVR_UVFLIP_NONE; context->txr.uv_clamp = tx1->uv_clamp; + context->txr.alpha = PVR_TXRALPHA_ENABLE; } else { context->txr.enable = PVR_TEXTURE_DISABLE; } From 97f4e020ad5c90b0665c841cc6b51c33b2e5e1ea Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Sat, 12 May 2018 21:06:22 +0100 Subject: [PATCH 07/21] Rename experimental and update the Makefile --- {experimental => GL}/draw.c | 0 {experimental => GL}/flush.c | 0 {experimental => GL}/framebuffer.c | 0 {experimental => GL}/immediate.c | 0 {experimental => GL}/lighting.c | 0 {experimental => GL}/private.h | 0 {experimental => GL}/state.c | 0 {experimental => GL}/texture.c | 0 Makefile | 3 ++- 9 files changed, 2 insertions(+), 1 deletion(-) rename {experimental => GL}/draw.c (100%) rename {experimental => GL}/flush.c (100%) rename {experimental => GL}/framebuffer.c (100%) rename {experimental => GL}/immediate.c (100%) rename {experimental => GL}/lighting.c (100%) rename {experimental => GL}/private.h (100%) rename {experimental => GL}/state.c (100%) rename {experimental => GL}/texture.c (100%) diff --git a/experimental/draw.c b/GL/draw.c similarity index 100% rename from experimental/draw.c rename to GL/draw.c diff --git a/experimental/flush.c b/GL/flush.c similarity index 100% rename from experimental/flush.c rename to GL/flush.c diff --git a/experimental/framebuffer.c b/GL/framebuffer.c similarity index 100% rename from experimental/framebuffer.c rename to GL/framebuffer.c diff --git a/experimental/immediate.c b/GL/immediate.c similarity index 100% rename from experimental/immediate.c rename to GL/immediate.c diff --git a/experimental/lighting.c b/GL/lighting.c similarity index 100% rename from experimental/lighting.c rename to GL/lighting.c diff --git a/experimental/private.h b/GL/private.h similarity index 100% rename from experimental/private.h rename to GL/private.h diff --git a/experimental/state.c b/GL/state.c similarity index 100% rename from experimental/state.c rename to GL/state.c diff --git a/experimental/texture.c b/GL/texture.c similarity index 100% rename from experimental/texture.c rename to GL/texture.c diff --git a/Makefile b/Makefile index 48f8ac1..7cec35e 100644 --- a/Makefile +++ b/Makefile @@ -6,8 +6,9 @@ TARGET = libGL.a OBJS = gl-rgb.o gl-fog.o gl-sh4-light.o gl-light.o gl-clip.o gl-clip-arrays.o -OBJS += gl-arrays.o gl-pvr.o gl-matrix.o gl-api.o gl-texture.o glu-texture.o +OBJS += gl-arrays.o gl-pvr.o gl-matrix.o gl-api.o glu-texture.o OBJS += gl-framebuffer.o gl-cap.o gl-error.o +OBJS += GL/draw.o GL/flush.o GL/framebuffer.o GL/immediate.o GL/lighting.o GL/state.o GL/texture.o SUBDIRS = From c76338b16f178edd92870bdd6b1ffa369b90928a Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Sat, 12 May 2018 21:20:26 +0100 Subject: [PATCH 08/21] Add glNormalX, remove more dead code --- GL/immediate.c | 30 ++++++++++ gl-light.c | 13 ----- gl-pvr.c | 149 ------------------------------------------------- 3 files changed, 30 insertions(+), 162 deletions(-) diff --git a/GL/immediate.c b/GL/immediate.c index d43c579..8c81819 100644 --- a/GL/immediate.c +++ b/GL/immediate.c @@ -1,3 +1,12 @@ +/* + * This implements immediate mode over the top of glDrawArrays + * current problems: + * + * 1. Calling glNormal(); glVertex(); glVertex(); glVertex(); will break. + * 2. Mixing with glXPointer stuff will break badly + * 3. This is entirely untested. + */ + #include "../include/gl.h" #include "private.h" @@ -7,11 +16,14 @@ static GLenum ACTIVE_POLYGON_MODE = GL_TRIANGLES; static AlignedVector VERTICES; static AlignedVector COLOURS; static AlignedVector TEXCOORDS; +static AlignedVector NORMALS; + void initImmediateMode() { aligned_vector_init(&VERTICES, sizeof(GLfloat)); aligned_vector_init(&COLOURS, sizeof(GLfloat)); aligned_vector_init(&TEXCOORDS, sizeof(GLfloat)); + aligned_vector_init(&NORMALS, sizeof(GLfloat)); } GLubyte checkImmediateModeInactive(const char* func) { @@ -66,6 +78,12 @@ void APIENTRY glVertex3fv(const GLfloat* v) { glVertex3f(v[0], v[1], v[2]); } +void APIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) { + aligned_vector_push_back(&VERTICES, &x, 1); + aligned_vector_push_back(&VERTICES, &y, 1); + aligned_vector_push_back(&VERTICES, &z, 1); +} + void APIENTRY glVertex4fv(const GLfloat* v) { glVertex4f(v[0], v[1], v[2], v[3]); } @@ -79,6 +97,16 @@ void APIENTRY glTexCoord2fv(const GLfloat* v) { glTexCoord2f(v[0], v[1]); } +void APIENTRY glNormal3f(GLfloat x, GLfloat y, GLfloat z) { + aligned_vector_push_back(&NORMALS, &x, 1); + aligned_vector_push_back(&NORMALS, &y, 1); + aligned_vector_push_back(&NORMALS, &z, 1); +} + +void APIENTRY glNormal3fv(const GLfloat* v) { + glNormal3f(v[0], v[1], v[2]); +} + void APIENTRY glEnd() { IMMEDIATE_MODE_ACTIVE = GL_FALSE; @@ -86,6 +114,7 @@ void APIENTRY glEnd() { glVertexPointer(3, GL_FLOAT, 0, VERTICES.data); glColorPointer(4, GL_FLOAT, 0, COLOURS.data); + glNormalPointer(GL_FLOAT, 0, NORMALS.data); glClientActiveTextureARB(GL_TEXTURE0); glTexCoordPointer(2, GL_FLOAT, 0, TEXCOORDS.data); @@ -95,6 +124,7 @@ void APIENTRY glEnd() { aligned_vector_clear(&VERTICES); aligned_vector_clear(&COLOURS); aligned_vector_clear(&TEXCOORDS); + aligned_vector_clear(&NORMALS); /* FIXME: Pop pointers */ } diff --git a/gl-light.c b/gl-light.c index 4a1fa55..dc88e8d 100644 --- a/gl-light.c +++ b/gl-light.c @@ -94,19 +94,6 @@ GLubyte _glKosGetMaxLights() { return GL_KOS_MAX_LIGHTS; } -/* Vertex Normal Submission */ -void glNormal3f(GLfloat x, GLfloat y, GLfloat z) { - GL_VERTEX_NORMAL[0] = x; - GL_VERTEX_NORMAL[1] = y; - GL_VERTEX_NORMAL[2] = z; -} - -void glNormal3fv(const GLfloat *xyz) { - GL_VERTEX_NORMAL[0] = xyz[0]; - GL_VERTEX_NORMAL[1] = xyz[1]; - GL_VERTEX_NORMAL[2] = xyz[2]; -} - /* Misc Lighting Functions ************************************/ static inline void glCopyRGBA(const rgba *src, rgba *dst) { *dst = *src; diff --git a/gl-pvr.c b/gl-pvr.c index 06b7a2d..03c1cf7 100644 --- a/gl-pvr.c +++ b/gl-pvr.c @@ -47,52 +47,8 @@ static GLuint GL_LIST = GL_KOS_LIST_OP; #define GL_KOS_MAX_MULTITEXTURE_OBJECTS 512 -static GL_MULTITEX_OBJECT GL_MTOBJS[GL_KOS_MAX_MULTITEXTURE_OBJECTS]; static GLuint GL_MTOBJECTS = 0; -/* Custom version of sq_cpy from KOS for copying vertex data to the PVR */ -static void pvr_list_submit(void *src, int n) { - GLuint *d = TA_SQ_ADDR; - GLuint *s = src; - - /* fill/write queues as many times necessary */ - while(n--) { - __asm__("pref @%0" : : "r"(s + 8)); /* prefetch 32 bytes for next loop */ - d[0] = *(s++); - d[1] = *(s++); - d[2] = *(s++); - d[3] = *(s++); - d[4] = *(s++); - d[5] = *(s++); - d[6] = *(s++); - d[7] = *(s++); - __asm__("pref @%0" : : "r"(d)); - d += 8; - } - - /* Wait for both store queues to complete */ - d = (GLuint *)0xe0000000; - d[0] = d[8] = 0; -} - -#ifdef GL_KOS_USE_DMA -/* Custom version of sq_cpy from KOS for copying 32bytes of vertex data to the PVR */ -static void pvr_hdr_submit(const GLuint *src) { - GLuint *d = TA_SQ_ADDR; - - d[0] = *(src++); - d[1] = *(src++); - d[2] = *(src++); - d[3] = *(src++); - d[4] = *(src++); - d[5] = *(src++); - d[6] = *(src++); - d[7] = *(src++); - - __asm__("pref @%0" : : "r"(d)); -} -#endif - void _glKosResetMultiTexObject() { GL_MTOBJECTS = 0; } @@ -218,110 +174,5 @@ void _glKosVertexBufCopy(void *dst, void *src, GLuint count) { memcpy(dst, src, count * 0x20); } -static void glutSwapBuffer() { -#ifndef GL_KOS_USE_DMA - QACR0 = QACRTA; - QACR1 = QACRTA; -#endif - pvr_list_begin(PVR_LIST_OP_POLY); -#ifdef GL_KOS_USE_DMA - pvr_dma_transfer(_glKosVertexBufAddress(GL_KOS_LIST_OP), 0, - _glKosVertexBufCount(GL_KOS_LIST_OP) * 32, - PVR_DMA_TA, 1, NULL, 0); -#else - pvr_list_submit(_glKosVertexBufAddress(GL_KOS_LIST_OP), _glKosVertexBufCount(GL_KOS_LIST_OP)); -#endif - pvr_list_finish(); - pvr_list_begin(PVR_LIST_TR_POLY); -#ifdef GL_KOS_USE_DMA - pvr_dma_transfer(_glKosVertexBufAddress(GL_KOS_LIST_TR), 0, - _glKosVertexBufCount(GL_KOS_LIST_TR) * 32, - PVR_DMA_TA, 1, NULL, 0); -#else - pvr_list_submit(_glKosVertexBufAddress(GL_KOS_LIST_TR), _glKosVertexBufCount(GL_KOS_LIST_TR)); -#endif - /* Multi-Texture Pass - Modify U/V coords of submitted vertices */ - GLuint i, v; - glTexCoord *mt = _glKosMultiUVBufAddress(); - - for(i = 0; i < GL_MTOBJECTS; i++) { - //copy vertex uv - for(v = 0; v < GL_MTOBJS[i].count; v ++) { - GL_MTOBJS[i].src[v].u = mt->u; - GL_MTOBJS[i].src[v].v = mt->v; - ++mt; - } - - // submit vertex data to PVR -#ifdef GL_KOS_USE_DMA - pvr_hdr_submit((GLuint *)&GL_MTOBJS[i].hdr); - pvr_dma_transfer(GL_MTOBJS[i].src, 0, - GL_MTOBJS[i].count * 32, PVR_DMA_TA, 1, NULL, 0); -#else - pvr_list_submit((pvr_poly_hdr_t *)&GL_MTOBJS[i].hdr, 1); - pvr_list_submit((pvr_vertex_t *)GL_MTOBJS[i].src, GL_MTOBJS[i].count); -#endif - } - - _glKosResetMultiTexObject(); /* End Multi-Texture Pass */ - - pvr_list_finish(); - - pvr_scene_finish(); -} - -void glutSwapBuffers() { - pvr_wait_ready(); - - if(_glKosGetFBO()) { - GLsizei w = _glKosGetFBOWidth(_glKosGetFBO()); - GLsizei h = _glKosGetFBOHeight(_glKosGetFBO()); - pvr_scene_begin_txr(_glKosGetFBOData(_glKosGetFBO()), &w, &h); - } - else - pvr_scene_begin(); - - glutSwapBuffer(); - - _glKosVertexBufReset(); - - _glKosMultiUVBufReset(); - -} - -void glutCopyBufferToTexture(void *dst, GLsizei *x, GLsizei *y) { - if(_glKosGetFBO()) { - pvr_wait_ready(); - - pvr_scene_begin_txr(dst, x, y); - - glutSwapBuffer(); - } -} - -int _glKosInitPVR() { - GLubyte i; - - 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_0 }, - GL_PVR_VERTEX_BUF_SIZE, /* Vertex buffer size */ - 0, /* No DMA */ - 0, /* No FSAA */ - 1 /* Disable translucent auto-sorting to match traditional GL */ - }; - - pvr_init(¶ms); - - for(i = 0; i < 2; ++i) { - GL_VBUF[i] = memalign(0x20, COMMANDS_PER_ALLOC * sizeof(pvr_cmd_t)); - GL_VERTS_ALLOCATED[i] = COMMANDS_PER_ALLOC; - } - - GL_CBUF = malloc((GL_KOS_MAX_VERTS / 2) * sizeof(pvr_cmd_t)); - GL_UVBUF = malloc(GL_KOS_MAX_VERTS * sizeof(glTexCoord)); - - return 1; -} From ab11a02056c2c884c33e092dada4c544508037de Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Sun, 13 May 2018 09:00:38 +0100 Subject: [PATCH 09/21] Diffuse should be ignored if lighting is enabled --- GL/draw.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/GL/draw.c b/GL/draw.c index 9b921d6..e3f1de1 100644 --- a/GL/draw.c +++ b/GL/draw.c @@ -197,27 +197,23 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ } if(lighting_enabled) { - GLfloat contribution[4]; - uint32 to_add; + /* We ignore diffuse colour when lighting is enabled. If GL_COLOR_MATERIAL is enabled + * then the lighting calculation should possibly take it into account */ + GLfloat contribution [] = {0.0f, 0.0f, 0.0f, 0.0f}; + GLfloat to_add [] = {0.0f, 0.0f, 0.0f, 0.0f}; for(GLubyte i = 0; i < MAX_LIGHTS; ++i) { if(isLightEnabled(i)) { - calculateLightingContribution(i, &vertex->x, normal, contribution); - to_add = PVR_PACK_COLOR(contribution[3], contribution[0], contribution[1], contribution[2]); + calculateLightingContribution(i, &vertex->x, normal, to_add); - GLubyte a = ((vertex->argb & 0xFF000000) >> 24) + ((to_add & 0xFF000000) >> 24); - GLubyte r = ((vertex->argb & 0x00FF0000) >> 16) + ((to_add & 0x00FF0000) >> 16); - GLubyte g = ((vertex->argb & 0x0000FF00) >> 8) + ((to_add & 0x0000FF00) >> 8); - GLubyte b = ((vertex->argb & 0x000000FF) >> 0) + ((to_add & 0x000000FF) >> 0); - - a = (a > 255) ? 255 : a; - r = (r > 255) ? 255 : r; - g = (g > 255) ? 255 : g; - b = (b > 255) ? 255 : b; - - vertex->argb = a << 24 | r << 16 | g << 8 | b; + contribution[0] += to_add[0]; + contribution[1] += to_add[1]; + contribution[2] += to_add[2]; + contribution[3] += to_add[3]; } } + + vertex->argb = PVR_PACK_COLOR(contribution[3], contribution[0], contribution[1], contribution[2]); } ++dst; From 2cef0cb25e896503147b844b4dcb5e26a1d08023 Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Sun, 13 May 2018 09:34:44 +0100 Subject: [PATCH 10/21] Implement glLightf --- GL/lighting.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/GL/lighting.c b/GL/lighting.c index df8f642..1a927c0 100644 --- a/GL/lighting.c +++ b/GL/lighting.c @@ -106,12 +106,13 @@ void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params) { case GL_POSITION: memcpy(LIGHTS[idx].position, params, sizeof(GLfloat) * 4); break; + case GL_CONSTANT_ATTENUATION: + case GL_LINEAR_ATTENUATION: + case GL_QUADRATIC_ATTENUATION: case GL_SPOT_CUTOFF: case GL_SPOT_DIRECTION: case GL_SPOT_EXPONENT: - case GL_CONSTANT_ATTENUATION: - case GL_LINEAR_ATTENUATION: - case GL_QUADRATIC_ATTENUATION: + glLightf(light, pname, *params); default: _glKosThrowError(GL_INVALID_ENUM, __func__); _glKosPrintError(); @@ -119,7 +120,28 @@ void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params) { } void APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param) { + GLubyte idx = light & 0xF; + if(idx >= MAX_LIGHTS) { + return; + } + + switch(pname) { + case GL_CONSTANT_ATTENUATION: + LIGHTS[idx].constant_attenuation = param; + break; + case GL_LINEAR_ATTENUATION: + LIGHTS[idx].linear_attenuation = param; + break; + case GL_QUADRATIC_ATTENUATION: + LIGHTS[idx].quadratic_attenuation = param; + break; + case GL_SPOT_EXPONENT: + case GL_SPOT_CUTOFF: + default: + _glKosThrowError(GL_INVALID_ENUM, __func__); + _glKosPrintError(); + } } void APIENTRY glMateriali(GLenum face, GLenum pname, const GLint param) { From 41062065620358a8e81d992d6e2c55cb7af3bc2f Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Sun, 13 May 2018 19:48:55 +0100 Subject: [PATCH 11/21] Implement glMaterialfv --- GL/lighting.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/GL/lighting.c b/GL/lighting.c index 1a927c0..42d8eee 100644 --- a/GL/lighting.c +++ b/GL/lighting.c @@ -144,16 +144,55 @@ void APIENTRY glLightf(GLenum light, GLenum pname, GLfloat param) { } } -void APIENTRY glMateriali(GLenum face, GLenum pname, const GLint param) { +void APIENTRY glMaterialf(GLenum face, GLenum pname, const GLfloat param) { + if(face == GL_BACK || pname != GL_SHININESS) { + _glKosThrowError(GL_INVALID_ENUM, __func__); + _glKosPrintError(); + return; + } + MATERIAL.exponent = param; } -void APIENTRY glMaterialf(GLenum face, GLenum pname, const GLfloat param) { - +void APIENTRY glMateriali(GLenum face, GLenum pname, const GLint param) { + glMaterialf(face, pname, param); } void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) { + if(pname == GL_SHININESS) { + glMaterialf(face, pname, *params); + return; + } + if(face == GL_BACK) { + _glKosThrowError(GL_INVALID_ENUM, __func__); + _glKosPrintError(); + return; + } + + switch(pname) { + case GL_AMBIENT: + memcpy(MATERIAL.ambient, params, sizeof(GLfloat) * 4); + break; + case GL_DIFFUSE: + memcpy(MATERIAL.diffuse, params, sizeof(GLfloat) * 4); + break; + case GL_SPECULAR: + memcpy(MATERIAL.specular, params, sizeof(GLfloat) * 4); + break; + case GL_EMISSION: + memcpy(MATERIAL.specular, params, sizeof(GLfloat) * 4); + break; + case GL_AMBIENT_AND_DIFFUSE: { + glMaterialfv(face, GL_AMBIENT, params); + glMaterialfv(face, GL_DIFFUSE, params); + } break; + case GL_COLOR_INDEXES: + default: { + _glKosThrowError(GL_INVALID_ENUM, __func__); + _glKosPrintError(); + } + } } void calculateLightingContribution(const GLint light, const GLfloat* pos, const GLfloat* normal, GLfloat* colour) { From de1fb05ac13787657e4f937d00a901b596ce06d2 Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Mon, 14 May 2018 16:58:58 +0100 Subject: [PATCH 12/21] Fix bugs in immediate mode --- GL/immediate.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/GL/immediate.c b/GL/immediate.c index 8c81819..eced866 100644 --- a/GL/immediate.c +++ b/GL/immediate.c @@ -19,6 +19,11 @@ static AlignedVector TEXCOORDS; static AlignedVector NORMALS; +static GLfloat NORMAL[3] = {0.0f, 0.0f, 1.0f}; +static GLfloat COLOR[4] = {1.0f, 1.0f, 1.0f, 1.0f}; +static GLfloat TEXCOORD[2] = {0.0f, 0.0f}; + + void initImmediateMode() { aligned_vector_init(&VERTICES, sizeof(GLfloat)); aligned_vector_init(&COLOURS, sizeof(GLfloat)); @@ -49,10 +54,10 @@ void APIENTRY glBegin(GLenum mode) { } void APIENTRY glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) { - aligned_vector_push_back(&COLOURS, &r, 1); - aligned_vector_push_back(&COLOURS, &g, 1); - aligned_vector_push_back(&COLOURS, &b, 1); - aligned_vector_push_back(&COLOURS, &a, 1); + COLOR[0] = r; + COLOR[1] = g; + COLOR[2] = b; + COLOR[3] = a; } void APIENTRY glColor4fv(const GLfloat* v) { @@ -72,6 +77,12 @@ void APIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z) { aligned_vector_push_back(&VERTICES, &x, 1); aligned_vector_push_back(&VERTICES, &y, 1); aligned_vector_push_back(&VERTICES, &z, 1); + + + /* Push back the stashed colour, normal and texcoord */ + aligned_vector_push_back(&COLOURS, COLOR, 4); + aligned_vector_push_back(&TEXCOORDS, TEXCOORD, 2); + aligned_vector_push_back(&NORMALS, NORMAL, 3); } void APIENTRY glVertex3fv(const GLfloat* v) { @@ -79,9 +90,7 @@ void APIENTRY glVertex3fv(const GLfloat* v) { } void APIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) { - aligned_vector_push_back(&VERTICES, &x, 1); - aligned_vector_push_back(&VERTICES, &y, 1); - aligned_vector_push_back(&VERTICES, &z, 1); + glVertex3f(x, y, z); } void APIENTRY glVertex4fv(const GLfloat* v) { @@ -89,8 +98,8 @@ void APIENTRY glVertex4fv(const GLfloat* v) { } void APIENTRY glTexCoord2f(GLfloat u, GLfloat v) { - aligned_vector_push_back(&TEXCOORDS, &u, 1); - aligned_vector_push_back(&TEXCOORDS, &v, 1); + TEXCOORD[0] = u; + TEXCOORD[1] = v; } void APIENTRY glTexCoord2fv(const GLfloat* v) { @@ -98,9 +107,9 @@ void APIENTRY glTexCoord2fv(const GLfloat* v) { } void APIENTRY glNormal3f(GLfloat x, GLfloat y, GLfloat z) { - aligned_vector_push_back(&NORMALS, &x, 1); - aligned_vector_push_back(&NORMALS, &y, 1); - aligned_vector_push_back(&NORMALS, &z, 1); + NORMAL[0] = x; + NORMAL[1] = y; + NORMAL[2] = z; } void APIENTRY glNormal3fv(const GLfloat* v) { From 4218111ab87dceb0955c144bf6aa3ea5d9e80012 Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Mon, 14 May 2018 17:10:53 +0100 Subject: [PATCH 13/21] Make things C89 friendly --- GL/draw.c | 18 ++++++++++++------ GL/lighting.c | 3 ++- GL/state.c | 3 ++- GL/texture.c | 3 ++- Makefile | 3 ++- containers/named_array.h | 5 +++-- 6 files changed, 23 insertions(+), 12 deletions(-) diff --git a/GL/draw.c b/GL/draw.c index e3f1de1..512017e 100644 --- a/GL/draw.c +++ b/GL/draw.c @@ -90,23 +90,25 @@ static void _parseColour(uint32* out, const GLubyte* in, GLint size, GLenum type } static void _parseFloats(GLfloat* out, const GLubyte* in, GLint size, GLenum type) { + GLubyte i = 0; + switch(type) { case GL_SHORT: { GLshort* inp = (GLshort*) in; - for(GLubyte i = 0; i < size; ++i) { + for(i = 0; i < size; ++i) { out[i] = (GLfloat) inp[i]; } } break; case GL_INT: { GLint* inp = (GLint*) in; - for(GLubyte i = 0; i < size; ++i) { + for(i = 0; i < size; ++i) { out[i] = (GLfloat) inp[i]; } } break; case GL_FLOAT: case GL_DOUBLE: /* Double == Float */ default: - for(GLubyte i = 0; i < size; ++i) out[i] = ((GLfloat*) in)[i]; + for(i = 0; i < size; ++i) out[i] = ((GLfloat*) in)[i]; } } @@ -165,7 +167,8 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ GLboolean lighting_enabled = isLightingEnabled(); - for(GLuint i = first; i < count; ++i) { + GLushort i; + for(i = first; i < count; ++i) { pvr_vertex_t* vertex = (pvr_vertex_t*) dst; vertex->u = vertex->v = 0.0f; vertex->argb = 0; @@ -202,9 +205,12 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ GLfloat contribution [] = {0.0f, 0.0f, 0.0f, 0.0f}; GLfloat to_add [] = {0.0f, 0.0f, 0.0f, 0.0f}; - for(GLubyte i = 0; i < MAX_LIGHTS; ++i) { + /* FIXME!!! Transform the position to eye space */ + + GLubyte j; + for(j = 0; j < MAX_LIGHTS; ++j) { if(isLightEnabled(i)) { - calculateLightingContribution(i, &vertex->x, normal, to_add); + calculateLightingContribution(j, &vertex->x, normal, to_add); contribution[0] += to_add[0]; contribution[1] += to_add[1]; diff --git a/GL/lighting.c b/GL/lighting.c index 42d8eee..164d4f2 100644 --- a/GL/lighting.c +++ b/GL/lighting.c @@ -23,7 +23,8 @@ void initLights() { MATERIAL.diffuse_color_index = 1.0f; MATERIAL.specular_color_index = 1.0f; - for(GLubyte i = 0; i < MAX_LIGHTS; ++i) { + GLubyte i; + for(i = 0; i < MAX_LIGHTS; ++i) { memcpy(LIGHTS[i].ambient, ZERO, sizeof(GLfloat) * 4); memcpy(LIGHTS[i].diffuse, ONE, sizeof(GLfloat) * 4); memcpy(LIGHTS[i].specular, ONE, sizeof(GLfloat) * 4); diff --git a/GL/state.c b/GL/state.c index 7782a23..ed91361 100644 --- a/GL/state.c +++ b/GL/state.c @@ -189,7 +189,8 @@ void initContext() { glDisable(GL_TEXTURE_2D); glDisable(GL_LIGHTING); - for(GLubyte i = 0; i < MAX_LIGHTS; ++i) { + GLubyte i; + for(i = 0; i < MAX_LIGHTS; ++i) { glDisable(GL_LIGHT0 + i); } } diff --git a/GL/texture.c b/GL/texture.c index 4a51d3d..252170c 100644 --- a/GL/texture.c +++ b/GL/texture.c @@ -549,7 +549,8 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, } /* Perform the conversion */ - for(GLuint i = 0; i < bytes; i += 2) { + GLuint i; + for(i = 0; i < bytes; i += 2) { convert(source, dest); dest++; diff --git a/Makefile b/Makefile index 7cec35e..e2584fc 100644 --- a/Makefile +++ b/Makefile @@ -3,9 +3,10 @@ # kos-ports/libgl Makefile # Copyright (C) 2013, 2014 Josh Pearson # Copyright (C) 2014 Lawrence Sebald +# Copyright (C) 2018 Luke Benstead TARGET = libGL.a -OBJS = gl-rgb.o gl-fog.o gl-sh4-light.o gl-light.o gl-clip.o gl-clip-arrays.o +OBJS = gl-rgb.o gl-fog.o gl-sh4-light.o gl-light.o gl-clip.o gl-clip-arrays.o OBJS += gl-arrays.o gl-pvr.o gl-matrix.o gl-api.o glu-texture.o OBJS += gl-framebuffer.o gl-cap.o gl-error.o OBJS += GL/draw.o GL/flush.o GL/framebuffer.o GL/immediate.o GL/lighting.o GL/state.o GL/texture.o diff --git a/containers/named_array.h b/containers/named_array.h index 88d0774..8989cea 100644 --- a/containers/named_array.h +++ b/containers/named_array.h @@ -43,8 +43,9 @@ inline char named_array_used(NamedArray* array, unsigned int id) { } inline void* named_array_alloc(NamedArray* array, unsigned int* new_id) { - for(unsigned int i = 0; i < array->marker_count; ++i) { - for(unsigned int j = 0; j < 8; ++j) { + unsigned int i = 0, j = 0; + for(i = 0; i < array->marker_count; ++i) { + for(j = 0; j < 8; ++j) { unsigned int id = (i * 8) + j + 1; if(!named_array_used(array, id)) { array->used_markers[i] |= (unsigned char) 1 << j; From f9cdefcd815ca1caafd236fbd44827e3a69acfeb Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Wed, 16 May 2018 21:00:41 +0100 Subject: [PATCH 14/21] Replace the entire matrix stack handling to work towards fixing lighting --- GL/draw.c | 48 +++++- GL/flush.c | 2 +- GL/lighting.c | 72 +++++++- GL/matrix.c | 370 ++++++++++++++++++++++++++++++++++++++++ GL/private.h | 8 + GL/state.c | 2 +- containers/stack.h | 50 ++++++ gl-light.c | 5 - gl-matrix.c | 413 --------------------------------------------- include/gl.h | 10 +- 10 files changed, 543 insertions(+), 437 deletions(-) create mode 100644 GL/matrix.c create mode 100644 containers/stack.h delete mode 100644 gl-matrix.c diff --git a/GL/draw.c b/GL/draw.c index 512017e..02a4c10 100644 --- a/GL/draw.c +++ b/GL/draw.c @@ -123,15 +123,36 @@ static void _parseIndex(GLshort* out, const GLubyte* in, GLenum type) { } } +/* +inline void mat_trans_float3_nodiv(const GLfloat* mat, GLfloat* v) { + GLfloat x = v[0] * mat[0] + v[1] * mat[4] + v[2] * mat[8] + mat[12]; + GLfloat y = v[0] * mat[1] + v[1] * mat[5] + v[2] * mat[9] + mat[13]; + GLfloat z = v[0] * mat[2] + v[1] * mat[6] + v[2] * mat[10] + mat[14]; + + v[0] = x; + v[1] = y; + v[2] = z; +} */ + +void transformToEyeSpace(GLfloat* point) { + _matrixLoadModelView(); + mat_trans_single3_nodiv(point[0], point[1], point[2]); +} + +void transformNormalToEyeSpace(GLfloat* normal) { + _matrixLoadNormal(); + mat_trans_normal3(normal[0], normal[1], normal[2]); +} + static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum type, const GLvoid* indices) { - static float normal[3]; + static GLfloat normal[3] = {0.0f, 0.0f, -1.0f}; + static GLfloat eye_P[3]; + static GLfloat eye_N[3]; if(!(ENABLED_VERTEX_ATTRIBUTES & VERTEX_ENABLED_FLAG)) { return; } - _glKosMatrixApplyRender(); /* Apply the Render Matrix Stack */ - const GLsizei elements = (mode == GL_QUADS) ? 4 : (mode == GL_TRIANGLES) ? 3 : (mode == GL_LINES) ? 2 : count; // Make room for the element + the header @@ -185,7 +206,6 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ } _parseFloats(&vertex->x, vptr + (idx * vstride), VERTEX_POINTER.size, VERTEX_POINTER.type); - transformVertex(&vertex->x, &vertex->x, &vertex->y, &vertex->z); if(ENABLED_VERTEX_ATTRIBUTES & DIFFUSE_ENABLED_FLAG) { _parseColour(&vertex->argb, cptr + (idx * cstride), DIFFUSE_POINTER.size, DIFFUSE_POINTER.type); @@ -197,6 +217,9 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ if(ENABLED_VERTEX_ATTRIBUTES & NORMAL_ENABLED_FLAG) { _parseFloats(normal, nptr + (idx * nstride), NORMAL_POINTER.size, NORMAL_POINTER.type); + } else { + normal[0] = normal[1] = 0.0f; + normal[2] = -1.0f; } if(lighting_enabled) { @@ -205,12 +228,22 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ GLfloat contribution [] = {0.0f, 0.0f, 0.0f, 0.0f}; GLfloat to_add [] = {0.0f, 0.0f, 0.0f, 0.0f}; - /* FIXME!!! Transform the position to eye space */ + /* Transform the vertex and normal into eye-space */ + eye_P[0] = vertex->x; + eye_P[1] = vertex->y; + eye_P[2] = vertex->z; + + eye_N[0] = normal[0]; + eye_N[1] = normal[1]; + eye_N[2] = normal[2]; + + transformToEyeSpace(eye_P); + transformNormalToEyeSpace(eye_N); GLubyte j; for(j = 0; j < MAX_LIGHTS; ++j) { if(isLightEnabled(i)) { - calculateLightingContribution(j, &vertex->x, normal, to_add); + calculateLightingContribution(j, eye_P, eye_N, to_add); contribution[0] += to_add[0]; contribution[1] += to_add[1]; @@ -222,6 +255,9 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ vertex->argb = PVR_PACK_COLOR(contribution[3], contribution[0], contribution[1], contribution[2]); } + _applyRenderMatrix(); /* Apply the Render Matrix Stack */ + transformVertex(&vertex->x, &vertex->x, &vertex->y, &vertex->z); + ++dst; } } diff --git a/GL/flush.c b/GL/flush.c index b689156..d089779 100644 --- a/GL/flush.c +++ b/GL/flush.c @@ -64,12 +64,12 @@ void APIENTRY glKosInit() { _initPVR(); + initMatrices(); initAttributePointers(); initContext(); initLights(); initImmediateMode(); - _glKosInitMatrix(); _glKosInitTextures(); OP_LIST.list_type = PVR_LIST_OP_POLY; diff --git a/GL/lighting.c b/GL/lighting.c index 164d4f2..12a7686 100644 --- a/GL/lighting.c +++ b/GL/lighting.c @@ -1,3 +1,5 @@ +#include +#include #include "private.h" static GLfloat SCENE_AMBIENT [] = {0.2, 0.2, 0.2, 1.0}; @@ -107,7 +109,7 @@ void APIENTRY glLightfv(GLenum light, GLenum pname, const GLfloat *params) { case GL_POSITION: memcpy(LIGHTS[idx].position, params, sizeof(GLfloat) * 4); break; - case GL_CONSTANT_ATTENUATION: + case GL_CONSTANT_ATTENUATION: case GL_LINEAR_ATTENUATION: case GL_QUADRATIC_ATTENUATION: case GL_SPOT_CUTOFF: @@ -196,7 +198,69 @@ void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) { } } -void calculateLightingContribution(const GLint light, const GLfloat* pos, const GLfloat* normal, GLfloat* colour) { - colour[0] = colour[3] = 0.0f; - colour[1] = colour[2] = 0.0f; +inline void initVec3(struct vec3f* v, const GLfloat* src) { + memcpy(v, src, sizeof(GLfloat) * 3); +} + +/* Fast POW Implementation - Less accurate, but much faster than math.h */ +#define EXP_A 184 +#define EXP_C 16249 + +static float FEXP(float y) { + union { + float d; + struct { + short j, i; + } n; + } eco; + eco.n.i = EXP_A * (y) + (EXP_C); + eco.n.j = 0; + return eco.d; +} + +static float FLOG(float y) { + int *nTemp = (int *)&y; + y = (*nTemp) >> 16; + return (y - EXP_C) / EXP_A; +} + +static float FPOW(float b, float p) { + return FEXP(FLOG(b) * p); +} + +void calculateLightingContribution(const GLint light, const GLfloat* pos, const GLfloat* normal, GLfloat* colour) { + LightSource* l = &LIGHTS[light]; + + struct vec3f L, N, V; + + L.x = l->position[0] - pos[0]; + L.y = l->position[1] - pos[1]; + L.z = l->position[2] - pos[2]; + + N.x = normal[0]; + N.y = normal[1]; + N.z = normal[2]; + + V.x = -pos[0]; + V.y = -pos[1]; + V.z = -pos[2]; + + vec3f_normalize(L.x, L.y, L.z); + vec3f_normalize(V.x, V.y, V.z); + + GLfloat LdotN; + vec3f_dot(L.x, L.y, L.z, N.x, N.y, N.z, LdotN); + + GLfloat f = (LdotN < 0) ? 0 : 1; + + GLfloat VdotN; + vec3f_dot(V.x, V.y, V.z, N.x, N.y, N.z, VdotN); + + GLfloat VdotR = VdotN - LdotN; + GLfloat specularPower = FPOW(VdotR > 0 ? VdotR : 0, MATERIAL.exponent); + + colour[0] = l->ambient[0] * MATERIAL.ambient[0] + f * (l->diffuse[0] * MATERIAL.diffuse[0] * LdotN); // + l->specular[0] * MATERIAL.specular[0] * specularPower); + colour[1] = l->ambient[1] * MATERIAL.ambient[1] + f * (l->diffuse[1] * MATERIAL.diffuse[1] * LdotN); // + l->specular[1] * MATERIAL.specular[1] * specularPower); + colour[2] = l->ambient[2] * MATERIAL.ambient[2] + f * (l->diffuse[2] * MATERIAL.diffuse[2] * LdotN); // + l->specular[2] * MATERIAL.specular[2] * specularPower); + colour[3] = MATERIAL.diffuse[3]; } diff --git a/GL/matrix.c b/GL/matrix.c new file mode 100644 index 0000000..81f52b2 --- /dev/null +++ b/GL/matrix.c @@ -0,0 +1,370 @@ +#include + +#include "../include/gl.h" +#include "../containers/stack.h" +#include "../gl-sh4.h" + +/* Viewport mapping */ +static GLfloat gl_viewport_scale[3], gl_viewport_offset[3]; + +/* Depth range */ +static GLclampf gl_depthrange_near, gl_depthrange_far; + +/* Viewport size */ +static GLint gl_viewport_x1, gl_viewport_y1, gl_viewport_width, gl_viewport_height; + +static Stack MATRIX_STACKS[3]; // modelview, projection, texture +static matrix_t NORMAL_MATRIX __attribute__((aligned(32))); +static matrix_t SCREENVIEW_MATRIX __attribute__((aligned(32))); +static matrix_t RENDER_MATRIX __attribute__((aligned(32))); + +static GLenum MATRIX_MODE = GL_MODELVIEW; +static GLubyte MATRIX_IDX = 0; + +static const matrix_t IDENTITY = { + {1.0f, 0.0f, 0.0f, 0.0f}, + {0.0f, 1.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, 1.0f, 0.0f}, + {0.0f, 0.0f, 0.0f, 1.0f} +}; + +void APIENTRY glDepthRange(GLclampf n, GLclampf f); + +void initMatrices() { + init_stack(&MATRIX_STACKS[0], sizeof(matrix_t), 32); + init_stack(&MATRIX_STACKS[1], sizeof(matrix_t), 32); + init_stack(&MATRIX_STACKS[2], sizeof(matrix_t), 32); + + stack_push(&MATRIX_STACKS[0], IDENTITY); + stack_push(&MATRIX_STACKS[1], IDENTITY); + stack_push(&MATRIX_STACKS[2], IDENTITY); + + memcpy(NORMAL_MATRIX, IDENTITY, sizeof(matrix_t)); + memcpy(SCREENVIEW_MATRIX, IDENTITY, sizeof(matrix_t)); + + glDepthRange(0.0f, 1.0f); + glViewport(0, 0, vid_mode->width, vid_mode->height); +} + +static void recalculateNormalMatrix() { + +} + +void APIENTRY glMatrixMode(GLenum mode) { + MATRIX_MODE = mode; + MATRIX_IDX = mode & 0xF; +} + +void APIENTRY glPushMatrix() { + stack_push(MATRIX_STACKS + MATRIX_IDX, stack_top(MATRIX_STACKS + MATRIX_IDX)); +} + +void APIENTRY glPopMatrix() { + stack_pop(MATRIX_STACKS + MATRIX_IDX); + if(MATRIX_MODE == GL_MODELVIEW) { + recalculateNormalMatrix(); + } +} + +void APIENTRY glLoadIdentity() { + stack_replace(MATRIX_STACKS + MATRIX_IDX, IDENTITY); +} + +void APIENTRY glTranslatef(GLfloat x, GLfloat y, GLfloat z) { + mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX)); + mat_translate(x, y, z); + mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX)); + + if(MATRIX_MODE == GL_MODELVIEW) { + recalculateNormalMatrix(); + } +} + + +void APIENTRY glScalef(GLfloat x, GLfloat y, GLfloat z) { + mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX)); + mat_scale(x, y, z); + mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX)); + + if(MATRIX_MODE == GL_MODELVIEW) { + recalculateNormalMatrix(); + } +} + +void APIENTRY glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { + float r = DEG2RAD * -angle; + + vec3f_normalize(x, y, z); + + mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX)); + mat_rotate(r * x, r * y, r * z); + mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX)); + + if(MATRIX_MODE == GL_MODELVIEW) { + recalculateNormalMatrix(); + } +} + +/* Load an arbitrary matrix */ +void APIENTRY glLoadMatrixf(const GLfloat *m) { + stack_replace(MATRIX_STACKS + MATRIX_IDX, m); + + if(MATRIX_MODE == GL_MODELVIEW) { + recalculateNormalMatrix(); + } +} + +/* Ortho */ +void APIENTRY glOrtho(GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat znear, GLfloat zfar) { + + /* Ortho Matrix */ + static matrix_t OrthoMatrix __attribute__((aligned(32))) = { + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 1.0f } + }; + + OrthoMatrix[0][0] = 2.0f / (right - left); + OrthoMatrix[1][1] = 2.0f / (top - bottom); + OrthoMatrix[2][2] = -2.0f / (zfar - znear); + OrthoMatrix[3][0] = -(right + left) / (right - left);; + OrthoMatrix[3][1] = -(top + bottom) / (top - bottom); + OrthoMatrix[3][2] = -(zfar + znear) / (zfar - znear); + + mat_load(stack_top(MATRIX_STACKS + MATRIX_MODE)); + mat_apply(&OrthoMatrix); + mat_store(stack_top(MATRIX_STACKS + MATRIX_MODE)); +} + + +/* Set the GL frustum */ +void APIENTRY glFrustum(GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat znear, GLfloat zfar) { + + /* Frustum Matrix */ + static matrix_t FrustumMatrix __attribute__((aligned(32))) = { + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, -1.0f }, + { 0.0f, 0.0f, 0.0f, 0.0f } + }; + + FrustumMatrix[0][0] = (2.0f * znear) / (right - left); + FrustumMatrix[2][0] = (right + left) / (right - left); + FrustumMatrix[1][1] = (2.0f * znear) / (top - bottom); + FrustumMatrix[2][1] = (top + bottom) / (top - bottom); + FrustumMatrix[2][2] = zfar / (zfar - znear); + FrustumMatrix[3][2] = -(zfar * znear) / (zfar - znear); + + mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX)); + mat_apply(&FrustumMatrix); + mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX)); +} + +/* Set the Perspective */ +void gluPerspective(GLfloat angle, GLfloat aspect, + GLfloat znear, GLfloat zfar) { + GLfloat xmin, xmax, ymin, ymax; + + ymax = znear * ftan(angle * F_PI / 360.0f); + ymin = -ymax; + xmin = ymin * aspect; + xmax = ymax * aspect; + + glFrustum(xmin, xmax, ymin, ymax, znear, zfar); +} + +/* Multiply the current matrix by an arbitrary matrix */ +void glMultMatrixf(const GLfloat *m) { + static matrix_t TEMP __attribute__((aligned(32))) = { + { 1.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 1.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 1.0f } + }; + + memcpy(TEMP, m, sizeof(matrix_t)); + + mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX)); + mat_apply(&TEMP); + mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX)); + + if(MATRIX_MODE == GL_MODELVIEW) { + recalculateNormalMatrix(); + } +} + +/* Load an arbitrary transposed matrix */ +void glLoadTransposeMatrixf(const GLfloat *m) { + stack_replace(MATRIX_STACKS + MATRIX_IDX, m); + transpose(stack_top(MATRIX_STACKS + MATRIX_IDX)); + + if(MATRIX_MODE == GL_MODELVIEW) { + recalculateNormalMatrix(); + } +} + +/* Multiply the current matrix by an arbitrary transposed matrix */ +void glMultTransposeMatrixf(const GLfloat *m) { + static matrix_t ml; + + ml[0][0] = m[0]; + ml[0][1] = m[4]; + ml[0][2] = m[8]; + ml[0][3] = m[12]; + ml[1][0] = m[1]; + ml[1][1] = m[5]; + ml[1][2] = m[9]; + ml[1][3] = m[13]; + ml[2][0] = m[2]; + ml[2][1] = m[6]; + ml[2][2] = m[10]; + ml[2][3] = m[14]; + ml[3][0] = m[3]; + ml[3][1] = m[7]; + ml[3][2] = m[11]; + ml[3][3] = m[15]; + + mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX)); + mat_apply(&ml); + mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX)); +} + +/* Set the GL viewport */ +void APIENTRY glViewport(GLint x, GLint y, GLsizei width, GLsizei height) { + gl_viewport_x1 = x; + gl_viewport_y1 = y; + gl_viewport_width = width; + gl_viewport_height = height; + + /* Calculate the viewport scale and offset */ + gl_viewport_scale[0] = (GLfloat)width / 2.0f; + gl_viewport_offset[0] = gl_viewport_scale[0] + (GLfloat)x; + gl_viewport_scale[1] = (GLfloat)height / 2.0f; + gl_viewport_offset[1] = gl_viewport_scale[1] + (GLfloat)y; + gl_viewport_scale[2] = (gl_depthrange_far - gl_depthrange_near) / 2.0f; + gl_viewport_offset[2] = (gl_depthrange_near + gl_depthrange_far) / 2.0f; + + gl_viewport_offset[2] += 0.0001f; + + /* Set the Screenview Matrix based on the viewport */ + SCREENVIEW_MATRIX[0][0] = gl_viewport_scale[0]; + SCREENVIEW_MATRIX[1][1] = -gl_viewport_scale[1]; + SCREENVIEW_MATRIX[2][2] = 1; + SCREENVIEW_MATRIX[3][0] = gl_viewport_offset[0]; + SCREENVIEW_MATRIX[3][1] = vid_mode->height - gl_viewport_offset[1]; +} + +/* Set the depth range */ +void APIENTRY glDepthRange(GLclampf n, GLclampf f) { + /* clamp the values... */ + if(n < 0.0f) n = 0.0f; + else if(n > 1.0f) n = 1.0f; + + if(f < 0.0f) f = 0.0f; + else if(f > 1.0f) f = 1.0f; + + gl_depthrange_near = n; + gl_depthrange_far = f; + + /* Adjust the viewport scale and offset for Z */ + gl_viewport_scale[2] = ((f - n) / 2.0f); + gl_viewport_offset[2] = (n + f) / 2.0f; +} + +/* Vector Cross Product - Used by glhLookAtf2 */ +static inline void vec3f_cross(vector3f v1, vector3f v2, vector3f result) { + result[0] = v1[1] * v2[2] - v1[2] * v2[1]; + result[1] = v1[2] * v2[0] - v1[0] * v2[2]; + result[2] = v1[0] * v2[1] - v1[1] * v2[0]; +} + +/* glhLookAtf2 adapted from http://www.opengl.org/wiki/GluLookAt_code */ +void glhLookAtf2(vector3f eyePosition3D, + vector3f center3D, + vector3f upVector3D) { + + /* Look-At Matrix */ + static matrix4f MatrixLookAt __attribute__((aligned(32))) = { + { 1.0f, 0.0f, 0.0f, 0.0f }, + { 0.0f, 1.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, 1.0f, 0.0f }, + { 0.0f, 0.0f, 0.0f, 1.0f } + }; + + vector3f forward, side, up; + + vec3f_sub_normalize(center3D[0], center3D[1], center3D[2], + eyePosition3D[0], eyePosition3D[1], eyePosition3D[2], + forward[0], forward[1], forward[2]); + + //Side = forward x up + vec3f_cross(forward, upVector3D, side); + vec3f_normalize(side[0], side[1], side[2]); + + //Recompute up as: up = side x forward + vec3f_cross(side, forward, up); + + MatrixLookAt[0][0] = side[0]; + MatrixLookAt[1][0] = side[1]; + MatrixLookAt[2][0] = side[2]; + MatrixLookAt[3][0] = 0; + + MatrixLookAt[0][1] = up[0]; + MatrixLookAt[1][1] = up[1]; + MatrixLookAt[2][1] = up[2]; + MatrixLookAt[3][1] = 0; + + MatrixLookAt[0][2] = -forward[0]; + MatrixLookAt[1][2] = -forward[1]; + MatrixLookAt[2][2] = -forward[2]; + MatrixLookAt[3][2] = 0; + + MatrixLookAt[0][3] = + MatrixLookAt[1][3] = + MatrixLookAt[2][3] = 0; + MatrixLookAt[3][3] = 1; + + // Does not modify internal Modelview matrix + mat_load(&MatrixLookAt); + mat_translate(-eyePosition3D[0], -eyePosition3D[1], -eyePosition3D[2]); + + mat_apply(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); + mat_store(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); +} + +void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx, + GLfloat centery, GLfloat centerz, GLfloat upx, GLfloat upy, + GLfloat upz) { + vector3f eye = { eyex, eyey, eyez }; + vector3f point = { centerx, centery, centerz }; + vector3f up = { upx, upy, upz }; + glhLookAtf2(eye, point, up); +} + +void _applyRenderMatrix() { + mat_load(&SCREENVIEW_MATRIX); + mat_apply(stack_top(MATRIX_STACKS + (GL_PROJECTION & 0xF))); + mat_apply(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); + mat_store(&RENDER_MATRIX); +} + +void _matrixLoadRender() { + mat_load(&RENDER_MATRIX); +} + +void _matrixLoadTexture() { + mat_load(stack_top(MATRIX_STACKS + (GL_TEXTURE & 0xF))); +} + +void _matrixLoadModelView() { + mat_load(stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF))); +} + +void _matrixLoadNormal() { + mat_load(&NORMAL_MATRIX); +} diff --git a/GL/private.h b/GL/private.h index 1ead5c5..6f081cd 100644 --- a/GL/private.h +++ b/GL/private.h @@ -72,6 +72,14 @@ void initAttributePointers(); void initContext(); void initLights(); void initImmediateMode(); +void initMatrices(); + +void _matrixLoadNormal(); +void _matrixLoadModelView(); +void _matrixLoadTexture(); +void _matrixLoadRender(); +void _applyRenderMatrix(); + GLubyte checkImmediateModeInactive(const char* func); pvr_poly_cxt_t* getPVRContext(); diff --git a/GL/state.c b/GL/state.c index ed91361..dac06cc 100644 --- a/GL/state.c +++ b/GL/state.c @@ -164,7 +164,7 @@ GLboolean isLightEnabled(unsigned char light) { static GLfloat CLEAR_COLOUR[3]; -void initContext() { +void initContext() { memset(&GL_CONTEXT, 0, sizeof(pvr_poly_cxt_t)); GL_CONTEXT.list_type = PVR_LIST_OP_POLY; diff --git a/containers/stack.h b/containers/stack.h new file mode 100644 index 0000000..4cc15f2 --- /dev/null +++ b/containers/stack.h @@ -0,0 +1,50 @@ +#ifndef STACK_H +#define STACK_H + +#include +#include + +typedef struct { + unsigned char* data; + unsigned int capacity; + unsigned int size; + unsigned int element_size; +} Stack; + +void init_stack(Stack* stack, unsigned int element_size, unsigned int capacity) { + stack->size = 0; + stack->capacity = capacity; + stack->element_size = element_size; + stack->data = (unsigned char*) memalign(0x20, element_size * capacity); +} + +void* stack_top(Stack* stack) { + return &stack->data[(stack->size - 1) * stack->element_size]; +} + +void* stack_replace(Stack* stack, const void* element) { + memcpy(stack->data + ((stack->size - 1) * stack->element_size), element, stack->element_size); + return stack_top(stack); +} + +void* stack_push(Stack* stack, const void* element) { + if(stack->size + 1 == stack->capacity) { + return NULL; + } + + memcpy(stack->data + (stack->size * stack->element_size), element, stack->element_size); + stack->size++; + + return stack_top(stack); +} + +void stack_pop(Stack* stack) { + if(stack->size == 0) { + return; + } + + stack->size--; +} + + +#endif // STACK_H diff --git a/gl-light.c b/gl-light.c index dc88e8d..2d91278 100644 --- a/gl-light.c +++ b/gl-light.c @@ -362,8 +362,3 @@ void _glKosVertexComputeLighting(pvr_vertex_t *v, int verts) { } } -void _glKosLightTransformScreenSpace(float *xyz) { - _glKosMatrixApplyScreenSpace(); - mat_trans_single(xyz[0], xyz[1], xyz[2]); - _glKosMatrixLoadRender(); -} diff --git a/gl-matrix.c b/gl-matrix.c deleted file mode 100644 index b840d2d..0000000 --- a/gl-matrix.c +++ /dev/null @@ -1,413 +0,0 @@ -/* KallistiGL for KallistiOS ##version## - - libgl/gl-matrix.c - Copyright (C) 2013-2014 Josh Pearson - Copyright (C) 2014 Lawrence Sebald - - Some functionality adapted from the original KOS libgl: - Copyright (C) 2001 Dan Potter - - The GL matrix operations use the KOS SH4 matrix operations. - Basically, we keep two seperate matrix stacks: - 1.) Internal GL API Matrix Stack ( screenview, modelview, etc. ) ( fixed stack size ) - 2.) External Matrix Stack for client to push / pop ( size of each stack is determined by MAX_MATRICES ) -*/ - -#include - -#include "gl.h" -#include "glu.h" -#include "gl-api.h" -#include "gl-sh4.h" - -/* This Matrix contains the GL Base Stack */ -static matrix4f Matrix[GL_MATRIX_COUNT] __attribute__((aligned(32))); -static GLsizei MatrixMode = 0; - -/* This Matrix contains the GL Push/Pop Stack ( fixed size per mode, 32 matrices )*/ -static const GLsizei MAX_MATRICES = 32; -static matrix4f MatrixStack[GL_MATRIX_COUNT][32] __attribute__((aligned(32))); -static GLsizei MatrixStackPos[GL_MATRIX_COUNT]; - -/* Viewport mapping */ -static GLfloat gl_viewport_scale[3], gl_viewport_offset[3]; - -/* Depth range */ -static GLclampf gl_depthrange_near, gl_depthrange_far; - -/* Viewport size */ -static GLint gl_viewport_x1, gl_viewport_y1, gl_viewport_width, gl_viewport_height; - -/* Frustum attributes */ -typedef struct { - float left, right, bottom, top, znear, zfar; -} gl_frustum_t; - -static gl_frustum_t gl_frustum; - -/* Frustum Matrix */ -static matrix4f FrustumMatrix __attribute__((aligned(32))) = { - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, -1.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f } -}; - -/* Ortho Matrix */ -static matrix4f OrthoMatrix __attribute__((aligned(32))) = { - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 1.0f } -}; - -/* Matrix for user to submit externally, ensure 32byte allignment */ -static matrix4f ml __attribute__((aligned(32))); - -/* Look-At Matrix */ -static matrix4f MatrixLookAt __attribute__((aligned(32))) = { - { 1.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 1.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 1.0f } -}; - -/* Modelview Rotation Matrix - Applied to Vertex Normal when Lighting is Enabled */ -static matrix4f MatrixMdlRot __attribute__((aligned(32))) = { - { 1.0f, 0.0f, 0.0f, 0.0f }, - { 0.0f, 1.0f, 0.0f, 0.0f }, - { 0.0f, 0.0f, 1.0f, 0.0f }, - { 0.0f, 0.0f, 0.0f, 1.0f } -}; - -void glMatrixMode(GLenum mode) { - if(mode >= GL_SCREENVIEW && mode <= GL_IDENTITY) - MatrixMode = mode; -} - -void glPushMatrix() { - if(MatrixStackPos[MatrixMode] < MAX_MATRICES - 1) { - mat_load(Matrix + MatrixMode); - mat_store(&MatrixStack[MatrixMode][MatrixStackPos[MatrixMode]]); - ++MatrixStackPos[MatrixMode]; - } -} - -void glPopMatrix() { - if(MatrixStackPos[MatrixMode]) { - --MatrixStackPos[MatrixMode]; - mat_load(&MatrixStack[MatrixMode][MatrixStackPos[MatrixMode]]); - mat_store(Matrix + MatrixMode); - } -} - -void glLoadIdentity() { - mat_load(Matrix + GL_IDENTITY); - mat_store(Matrix + MatrixMode); - - if(MatrixMode == GL_MODELVIEW) { - mat_store(&MatrixMdlRot); - mat_store(&MatrixLookAt); - } -} - -void glTranslatef(GLfloat x, GLfloat y, GLfloat z) { - mat_load(Matrix + MatrixMode); - mat_translate(x, y, z); - mat_store(Matrix + MatrixMode); -} - -void glScalef(GLfloat x, GLfloat y, GLfloat z) { - mat_load(Matrix + MatrixMode); - mat_scale(x, y, z); - mat_store(Matrix + MatrixMode); -} - -void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { - float r = DEG2RAD * -angle; - - vec3f_normalize(x, y, z); - - mat_load(Matrix + MatrixMode); - mat_rotate(r * x, r * y, r * z); - mat_store(Matrix + MatrixMode); - - if(MatrixMode == GL_MODELVIEW) { - mat_load(&MatrixMdlRot); - mat_rotate(r * x, r * y, r * z); - mat_store(&MatrixMdlRot); - } -} - -/* Load an arbitrary matrix */ -void glLoadMatrixf(const GLfloat *m) { - memcpy(ml, m, sizeof(matrix4f)); - mat_load(&ml); - mat_store(Matrix + MatrixMode); -} - -/* Load an arbitrary transposed matrix */ -void glLoadTransposeMatrixf(const GLfloat *m) { - ml[0][0] = m[0]; - ml[0][1] = m[4]; - ml[0][2] = m[8]; - ml[0][3] = m[12]; - ml[1][0] = m[1]; - ml[1][1] = m[5]; - ml[1][2] = m[9]; - ml[1][3] = m[13]; - ml[2][0] = m[2]; - ml[2][1] = m[6]; - ml[2][2] = m[10]; - ml[2][3] = m[14]; - ml[3][0] = m[3]; - ml[3][1] = m[7]; - ml[3][2] = m[11]; - ml[3][3] = m[15]; - - mat_load(&ml); - mat_store(Matrix + MatrixMode); -} - -/* Multiply the current matrix by an arbitrary matrix */ -void glMultMatrixf(const GLfloat *m) { - memcpy(ml, m, sizeof(matrix4f)); - mat_load(Matrix + MatrixMode); - mat_apply(&ml); - mat_store(Matrix + MatrixMode); -} - -/* Multiply the current matrix by an arbitrary transposed matrix */ -void glMultTransposeMatrixf(const GLfloat *m) { - ml[0][0] = m[0]; - ml[0][1] = m[4]; - ml[0][2] = m[8]; - ml[0][3] = m[12]; - ml[1][0] = m[1]; - ml[1][1] = m[5]; - ml[1][2] = m[9]; - ml[1][3] = m[13]; - ml[2][0] = m[2]; - ml[2][1] = m[6]; - ml[2][2] = m[10]; - ml[2][3] = m[14]; - ml[3][0] = m[3]; - ml[3][1] = m[7]; - ml[3][2] = m[11]; - ml[3][3] = m[15]; - - mat_load(Matrix + MatrixMode); - mat_apply(&ml); - mat_store(Matrix + MatrixMode); -} - -/* Set the depth range */ -void glDepthRange(GLclampf n, GLclampf f) { - /* clamp the values... */ - if(n < 0.0f) n = 0.0f; - else if(n > 1.0f) n = 1.0f; - - if(f < 0.0f) f = 0.0f; - else if(f > 1.0f) f = 1.0f; - - gl_depthrange_near = n; - gl_depthrange_far = f; - - /* Adjust the viewport scale and offset for Z */ - gl_viewport_scale[2] = ((f - n) / 2.0f); - gl_viewport_offset[2] = (n + f) / 2.0f; -} - -/* Set the GL viewport */ -void glViewport(GLint x, GLint y, GLsizei width, GLsizei height) { - gl_viewport_x1 = x; - gl_viewport_y1 = y; - gl_viewport_width = width; - gl_viewport_height = height; - - /* Calculate the viewport scale and offset */ - gl_viewport_scale[0] = (GLfloat)width / 2.0f; - gl_viewport_offset[0] = gl_viewport_scale[0] + (GLfloat)x; - gl_viewport_scale[1] = (GLfloat)height / 2.0f; - gl_viewport_offset[1] = gl_viewport_scale[1] + (GLfloat)y; - gl_viewport_scale[2] = (gl_depthrange_far - gl_depthrange_near) / 2.0f; - gl_viewport_offset[2] = (gl_depthrange_near + gl_depthrange_far) / 2.0f; - - gl_viewport_offset[2] += 0.0001f; - - /* Set the Screenview Matrix based on the viewport */ - Matrix[GL_SCREENVIEW][0][0] = gl_viewport_scale[0]; - Matrix[GL_SCREENVIEW][1][1] = -gl_viewport_scale[1]; - Matrix[GL_SCREENVIEW][2][2] = 1; - Matrix[GL_SCREENVIEW][3][0] = gl_viewport_offset[0]; - Matrix[GL_SCREENVIEW][3][1] = vid_mode->height - gl_viewport_offset[1]; -} - -/* Set the GL frustum */ -void glFrustum(GLfloat left, GLfloat right, - GLfloat bottom, GLfloat top, - GLfloat znear, GLfloat zfar) { - gl_frustum.left = left; - gl_frustum.right = right; - gl_frustum.bottom = bottom; - gl_frustum.top = top; - gl_frustum.znear = znear; - gl_frustum.zfar = zfar; - - FrustumMatrix[0][0] = (2.0f * znear) / (right - left); - FrustumMatrix[2][0] = (right + left) / (right - left); - FrustumMatrix[1][1] = (2.0f * znear) / (top - bottom); - FrustumMatrix[2][1] = (top + bottom) / (top - bottom); - FrustumMatrix[2][2] = zfar / (zfar - znear); - FrustumMatrix[3][2] = -(zfar * znear) / (zfar - znear); - - mat_load(Matrix + MatrixMode); - mat_apply(&FrustumMatrix); - mat_store(Matrix + MatrixMode); -} - -/* Ortho */ -void glOrtho(GLfloat left, GLfloat right, - GLfloat bottom, GLfloat top, - GLfloat znear, GLfloat zfar) { - OrthoMatrix[0][0] = 2.0f / (right - left); - OrthoMatrix[1][1] = 2.0f / (top - bottom); - OrthoMatrix[2][2] = -2.0f / (zfar - znear); - OrthoMatrix[3][0] = -(right + left) / (right - left);; - OrthoMatrix[3][1] = -(top + bottom) / (top - bottom); - OrthoMatrix[3][2] = -(zfar + znear) / (zfar - znear); - - mat_load(Matrix + MatrixMode); - mat_apply(&OrthoMatrix); - mat_store(Matrix + MatrixMode); -} - -/* Set the Perspective */ -void gluPerspective(GLfloat angle, GLfloat aspect, - GLfloat znear, GLfloat zfar) { - GLfloat xmin, xmax, ymin, ymax; - - ymax = znear * ftan(angle * F_PI / 360.0f); - ymin = -ymax; - xmin = ymin * aspect; - xmax = ymax * aspect; - - glFrustum(xmin, xmax, ymin, ymax, znear, zfar); -} - -/* Vector Cross Product - Used by glhLookAtf2 */ -void vec3f_cross(vector3f v1, vector3f v2, vector3f result) { - result[0] = v1[1] * v2[2] - v1[2] * v2[1]; - result[1] = v1[2] * v2[0] - v1[0] * v2[2]; - result[2] = v1[0] * v2[1] - v1[1] * v2[0]; -} - -/* glhLookAtf2 adapted from http://www.opengl.org/wiki/GluLookAt_code */ -void glhLookAtf2(vector3f eyePosition3D, - vector3f center3D, - vector3f upVector3D) { - vector3f forward, side, up; - - _glKosSetEyePosition(eyePosition3D); - - vec3f_sub_normalize(center3D[0], center3D[1], center3D[2], - eyePosition3D[0], eyePosition3D[1], eyePosition3D[2], - forward[0], forward[1], forward[2]); - - //Side = forward x up - vec3f_cross(forward, upVector3D, side); - vec3f_normalize(side[0], side[1], side[2]); - - //Recompute up as: up = side x forward - vec3f_cross(side, forward, up); - - MatrixLookAt[0][0] = side[0]; - MatrixLookAt[1][0] = side[1]; - MatrixLookAt[2][0] = side[2]; - MatrixLookAt[3][0] = 0; - - MatrixLookAt[0][1] = up[0]; - MatrixLookAt[1][1] = up[1]; - MatrixLookAt[2][1] = up[2]; - MatrixLookAt[3][1] = 0; - - MatrixLookAt[0][2] = -forward[0]; - MatrixLookAt[1][2] = -forward[1]; - MatrixLookAt[2][2] = -forward[2]; - MatrixLookAt[3][2] = 0; - - MatrixLookAt[0][3] = - MatrixLookAt[1][3] = - MatrixLookAt[2][3] = 0; - MatrixLookAt[3][3] = 1; - - // Does not modify internal Modelview matrix - mat_load(&MatrixLookAt); - mat_translate(-eyePosition3D[0], -eyePosition3D[1], -eyePosition3D[2]); - - mat_apply(Matrix + GL_MODELVIEW); - mat_store(Matrix + GL_MODELVIEW); -} - -void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx, - GLfloat centery, GLfloat centerz, GLfloat upx, GLfloat upy, - GLfloat upz) { - vector3f eye = { eyex, eyey, eyez }; - vector3f point = { centerx, centery, centerz }; - vector3f up = { upx, upy, upz }; - glhLookAtf2(eye, point, up); -} - -void _glKosMatrixApplyRender() { - mat_load(Matrix + GL_SCREENVIEW); - mat_apply(Matrix + GL_PROJECTION); - mat_apply(Matrix + GL_MODELVIEW); - mat_store(Matrix + GL_RENDER); -} - -void _glKosMatrixLoadRender() { - mat_load(Matrix + GL_RENDER); -} - -void _glKosMatrixLoadTexture() { - mat_load(Matrix + GL_TEXTURE); -} - -void _glKosMatrixLoadModelView() { - mat_load(Matrix + GL_MODELVIEW); -} - -void _glKosMatrixLoadModelRot() { - mat_load(&MatrixMdlRot); -} - -void _glKosMatrixApplyScreenSpace() { - mat_load(Matrix + GL_SCREENVIEW); - mat_apply(Matrix + GL_PROJECTION); - mat_apply(&MatrixLookAt); -} - -void _glKosInitMatrix() { - mat_identity(); - mat_store(Matrix + GL_SCREENVIEW); - mat_store(Matrix + GL_PROJECTION); - mat_store(Matrix + GL_MODELVIEW); - mat_store(Matrix + GL_TEXTURE); - mat_store(Matrix + GL_IDENTITY); - mat_store(Matrix + GL_RENDER); - - int i; - - for(i = 0; i < GL_MATRIX_COUNT; i++) - MatrixStackPos[i] = 0; - - glDepthRange(0.0f, 1.0f); - glViewport(0, 0, vid_mode->width, vid_mode->height); -} - -void glKosGetMatrix(GLenum mode, GLfloat *params) { - if(mode < GL_SCREENVIEW || mode > GL_RENDER) - *params = (GLfloat)GL_INVALID_ENUM; - - memcpy(params, Matrix + mode, sizeof(GLfloat) * 16); -} diff --git a/include/gl.h b/include/gl.h index 2bbb566..38e3caa 100644 --- a/include/gl.h +++ b/include/gl.h @@ -56,13 +56,9 @@ __BEGIN_DECLS /* Matrix modes */ #define GL_MATRIX_MODE 0x0BA0 -#define GL_SCREENVIEW 0x00 -#define GL_MODELVIEW 0x01 -#define GL_PROJECTION 0x02 -#define GL_TEXTURE 0x03 -#define GL_IDENTITY 0x04 -#define GL_RENDER 0x05 -#define GL_MATRIX_COUNT 0x06 +#define GL_MODELVIEW 0x1700 +#define GL_PROJECTION 0x1701 +#define GL_TEXTURE 0x1702 #define GL_MODELVIEW_MATRIX 0x0BA6 #define GL_PROJECTION_MATRIX 0x0BA7 From 2d9c4394905c913e3f96cd1ae9a04fafa6e23b3b Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Wed, 16 May 2018 21:30:11 +0100 Subject: [PATCH 15/21] Implement normal matrix calculation --- GL/lighting.c | 6 +++--- GL/matrix.c | 41 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/GL/lighting.c b/GL/lighting.c index 12a7686..064b21c 100644 --- a/GL/lighting.c +++ b/GL/lighting.c @@ -259,8 +259,8 @@ void calculateLightingContribution(const GLint light, const GLfloat* pos, const GLfloat VdotR = VdotN - LdotN; GLfloat specularPower = FPOW(VdotR > 0 ? VdotR : 0, MATERIAL.exponent); - colour[0] = l->ambient[0] * MATERIAL.ambient[0] + f * (l->diffuse[0] * MATERIAL.diffuse[0] * LdotN); // + l->specular[0] * MATERIAL.specular[0] * specularPower); - colour[1] = l->ambient[1] * MATERIAL.ambient[1] + f * (l->diffuse[1] * MATERIAL.diffuse[1] * LdotN); // + l->specular[1] * MATERIAL.specular[1] * specularPower); - colour[2] = l->ambient[2] * MATERIAL.ambient[2] + f * (l->diffuse[2] * MATERIAL.diffuse[2] * LdotN); // + l->specular[2] * MATERIAL.specular[2] * specularPower); + colour[0] = l->ambient[0] * MATERIAL.ambient[0] + f * (l->diffuse[0] * MATERIAL.diffuse[0] * LdotN + l->specular[0] * MATERIAL.specular[0] * specularPower); + colour[1] = l->ambient[1] * MATERIAL.ambient[1] + f * (l->diffuse[1] * MATERIAL.diffuse[1] * LdotN + l->specular[1] * MATERIAL.specular[1] * specularPower); + colour[2] = l->ambient[2] * MATERIAL.ambient[2] + f * (l->diffuse[2] * MATERIAL.diffuse[2] * LdotN + l->specular[2] * MATERIAL.specular[2] * specularPower); colour[3] = MATERIAL.diffuse[3]; } diff --git a/GL/matrix.c b/GL/matrix.c index 81f52b2..e9e4703 100644 --- a/GL/matrix.c +++ b/GL/matrix.c @@ -46,8 +46,47 @@ void initMatrices() { glViewport(0, 0, vid_mode->width, vid_mode->height); } -static void recalculateNormalMatrix() { +#define swap(a, b) { \ + GLfloat x = (a); \ + a = b; \ + b = x; \ +} +static void inverse(GLfloat* m) { + GLfloat f4 = m[4]; + GLfloat f8 = m[8]; + GLfloat f1 = m[1]; + GLfloat f9 = m[9]; + GLfloat f2 = m[2]; + GLfloat f6 = m[6]; + GLfloat f12 = m[12]; + GLfloat f13 = m[13]; + GLfloat f14 = m[14]; + + m[1] = f4; + m[2] = f8; + m[4] = f1; + m[6] = f9; + m[8] = f2; + m[9] = f6; + m[12] = -(f12 * m[0] + f13 * m[4] + f14 * m[8]); + m[13] = -(f12 * m[1] + f13 * m[5] + f14 * m[9]); + m[14] = -(f12 * m[2] + f13 * m[6] + f14 * m[10]); +} + +static void transpose(GLfloat* m) { + swap(m[1], m[4]); + swap(m[2], m[8]); + swap(m[3], m[12]); + swap(m[6], m[9]); + swap(m[7], m[3]); + swap(m[11], m[14]); +} + +static void recalculateNormalMatrix() { + memcpy(NORMAL_MATRIX, stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)), sizeof(matrix_t)); + transpose((GLfloat*) NORMAL_MATRIX); + inverse((GLfloat*) NORMAL_MATRIX); } void APIENTRY glMatrixMode(GLenum mode) { From 278ba015381ec0ead630faa2c23e22e7129232ed Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Wed, 16 May 2018 21:41:12 +0100 Subject: [PATCH 16/21] Fix up the makefile --- Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e2584fc..b835cd8 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,7 @@ OBJS = gl-rgb.o gl-fog.o gl-sh4-light.o gl-light.o gl-clip.o gl-clip-arrays.o OBJS += gl-arrays.o gl-pvr.o gl-matrix.o gl-api.o glu-texture.o OBJS += gl-framebuffer.o gl-cap.o gl-error.o OBJS += GL/draw.o GL/flush.o GL/framebuffer.o GL/immediate.o GL/lighting.o GL/state.o GL/texture.o +OBJS += GL/matrix.o SUBDIRS = @@ -21,7 +22,7 @@ link: build: $(OBJS) link -defaultall: create_kos_link build subdirs linklib +defaultall: build subdirs linklib create_kos_link include $(KOS_BASE)/addons/Makefile.prefab From 9e54126de7d852e4c5f8742e8f65d8fe2e369ac8 Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Wed, 16 May 2018 21:43:56 +0100 Subject: [PATCH 17/21] Remove some old code --- Makefile | 2 +- gl-arrays.c | 1280 --------------------------------------------------- gl-arrays.h | 30 -- 3 files changed, 1 insertion(+), 1311 deletions(-) delete mode 100644 gl-arrays.c delete mode 100644 gl-arrays.h diff --git a/Makefile b/Makefile index b835cd8..4da1644 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ TARGET = libGL.a OBJS = gl-rgb.o gl-fog.o gl-sh4-light.o gl-light.o gl-clip.o gl-clip-arrays.o -OBJS += gl-arrays.o gl-pvr.o gl-matrix.o gl-api.o glu-texture.o +OBJS += gl-pvr.o gl-matrix.o gl-api.o glu-texture.o OBJS += gl-framebuffer.o gl-cap.o gl-error.o OBJS += GL/draw.o GL/flush.o GL/framebuffer.o GL/immediate.o GL/lighting.o GL/state.o GL/texture.o OBJS += GL/matrix.o diff --git a/gl-arrays.c b/gl-arrays.c deleted file mode 100644 index d875303..0000000 --- a/gl-arrays.c +++ /dev/null @@ -1,1280 +0,0 @@ -/* KallistiGL for KallistiOS ##version## - - libgl/gl-arrays.c - Copyright (C) 2013-2015 Josh Pearson - - Arrays Input Primitive Types Supported: - -GL_TRIANGLES - -GL_TRIANGLE_STRIPS - -GL_QUADS - - Here, it is not necessary to enable or disable client states; - the API is aware of what pointers have been submitted, and will - render accordingly. If you submit a normal pointer, dynamic - vertex lighting will be applied even if you submit a color - pointer, so only submit one or the other. -*/ - -#include -#include - -#include "gl.h" -#include "glext.h" -#include "gl-api.h" -#include "gl-arrays.h" -#include "gl-pvr.h" -#include "gl-rgb.h" -#include "gl-sh4.h" - -//========================================================================================// -//== Local Variables ==// - -static glVertex GL_KOS_ARRAY_BUF[GL_KOS_MAX_VERTS]; -static glVertex *GL_KOS_ARRAY_BUF_PTR; - -static GLfloat GL_KOS_ARRAY_BUFW[GL_KOS_MAX_VERTS]; -static GLfloat GL_KOS_ARRAY_DSTW[GL_KOS_MAX_VERTS]; - -static GLfloat GL_KOS_ARRAY_BUFUV[GL_KOS_MAX_VERTS]; - -static GLubyte GL_KOS_CLIENT_ACTIVE_TEXTURE = GL_TEXTURE0_ARB & 0xF; - -static GLubyte *GL_KOS_VERTEX_POINTER = NULL; -static GLubyte *GL_KOS_NORMAL_POINTER = NULL; -static GLubyte *GL_KOS_TEXCOORD0_POINTER = NULL; -static GLubyte *GL_KOS_TEXCOORD1_POINTER = NULL; -static GLubyte *GL_KOS_COLOR_POINTER = NULL; -static GLubyte *GL_KOS_INDEX_POINTER_U8 = NULL; -static GLushort *GL_KOS_INDEX_POINTER_U16 = NULL; - -static GLushort GL_KOS_VERTEX_STRIDE = 0; -static GLushort GL_KOS_NORMAL_STRIDE = 0; -static GLushort GL_KOS_TEXCOORD0_STRIDE = 0; -static GLushort GL_KOS_TEXCOORD1_STRIDE = 0; -static GLushort GL_KOS_COLOR_STRIDE = 0; - -static GLuint GL_KOS_VERTEX_PTR_MODE = 0; -static GLubyte GL_KOS_VERTEX_SIZE = 0; -static GLubyte GL_KOS_COLOR_COMPONENTS = 0; -static GLenum GL_KOS_COLOR_TYPE = 0; - -//========================================================================================// -//== Local Function Definitions ==// - -static inline void _glKosArraysTransformNormals(GLubyte *normal, GLuint count); -static inline void _glKosArraysTransformPositions(GLubyte *position, GLuint count); - -void (*_glKosArrayTexCoordFunc)(pvr_vertex_t *); -void (*_glKosArrayColorFunc)(pvr_vertex_t *); - -void (*_glKosElementTexCoordFunc)(pvr_vertex_t *, GLuint); -void (*_glKosElementColorFunc)(pvr_vertex_t *, GLuint); - -static inline GLushort _calculate_byte_size(GLenum type) { - switch(type) { - case GL_UNSIGNED_INT: return sizeof(GLuint); - case GL_INT: return sizeof(GLint); - case GL_FLOAT: return sizeof(GLfloat); - case GL_UNSIGNED_BYTE: return sizeof(GLubyte); - case GL_BYTE: return sizeof(GLbyte); - case GL_UNSIGNED_SHORT: return sizeof(GLushort); - case GL_SHORT: return sizeof(GLshort); - case GL_DOUBLE: return sizeof(GLdouble); - default: - _glKosThrowError(GL_INVALID_ENUM, "_calculate_byte_size"); - return 0; - } -} - -//========================================================================================// -//== 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"); - -// if(type != GL_FLOAT) /* Expect Floating point vertices */ -// _glKosThrowError(GL_INVALID_ENUM, "glVertexPointer"); - -// if(stride < 0) -// _glKosThrowError(GL_INVALID_VALUE, "glVertexPointer"); - -// if(_glKosHasError()) { -// _glKosPrintError(); -// return; -// } - -// GL_KOS_VERTEX_SIZE = size; - -// 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"); - -// if(stride < 0) -// _glKosThrowError(GL_INVALID_VALUE, "glNormalPointer"); - -// if(_glKosHasError()) { -// _glKosPrintError(); -// return; -// } - -// 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"); - -// if(type != GL_FLOAT) /* Expect Floating point vertices */ -// _glKosThrowError(GL_INVALID_ENUM, "glTexCoordPointer"); - -// if(stride < 0) -// _glKosThrowError(GL_INVALID_VALUE, "glTexCoordPointer"); - -// 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; -// } -//} - -///* 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; -//} -//========================================================================================// -//== Vertex Pointer Internal API ==// - -inline void _glKosArrayBufIncrement() { - ++GL_KOS_ARRAY_BUF_PTR; -} - -inline void _glKosArrayBufReset() { - GL_KOS_ARRAY_BUF_PTR = &GL_KOS_ARRAY_BUF[0]; -} - -inline glVertex *_glKosArrayBufAddr() { - return &GL_KOS_ARRAY_BUF[0]; -} - -inline glVertex *_glKosArrayBufPtr() { - return GL_KOS_ARRAY_BUF_PTR; -} - -static inline void _glKosArraysTransformNormals(GLubyte *normal, GLuint count) { - glVertex *v = &GL_KOS_ARRAY_BUF[0]; - GLubyte *src = normal; - GLfloat *N; - - _glKosMatrixLoadModelRot(); - - while(count--) { - N = (GLfloat *) src; - mat_trans_normal3_nomod(N[0], N[1], N[2], v->norm[0], v->norm[1], v->norm[2]); - src += GL_KOS_NORMAL_STRIDE; - ++v; - } -} - -static inline void _glKosArraysTransformPositions(GLubyte *position, GLuint count) { - glVertex *v = &GL_KOS_ARRAY_BUF[0]; - GLubyte *src = position; - GLfloat *P; - - _glKosMatrixLoadModelView(); - - while(count--) { - P = (GLfloat *) src; - mat_trans_single3_nodiv_nomod(P[0], P[1], P[2], v->pos[0], v->pos[1], v->pos[2]); - src += GL_KOS_VERTEX_STRIDE; - ++v; - } -} - -//========================================================================================// -//== Arrays Vertex Transform ==/ -static void _glKosArraysTransform2D(GLuint count) { - GLubyte *src = GL_KOS_VERTEX_POINTER; - GLfloat *element; - pvr_vertex_t *dst = _glKosVertexBufPointer(); - - register float __x __asm__("fr12"); - register float __y __asm__("fr13"); - register float __z __asm__("fr14"); - - while(count--) { - element = (GLfloat *) src; - __x = element[0]; - __y = element[1]; - __z = 0; - - mat_trans_fv12() - - dst->x = __x; - dst->y = __y; - dst->z = __z; - - ++dst; - - src += GL_KOS_VERTEX_STRIDE; - } -} - -static void _glKosArraysTransform(GLuint count) { - GLubyte *src = GL_KOS_VERTEX_POINTER; - GLfloat *element; - pvr_vertex_t *dst = _glKosVertexBufPointer(); - - register float __x __asm__("fr12"); - register float __y __asm__("fr13"); - register float __z __asm__("fr14"); - - while(count--) { - element = (GLfloat *) src; - __x = element[0]; - __y = element[1]; - __z = element[2]; - - mat_trans_fv12() - - dst->x = __x; - dst->y = __y; - dst->z = __z; - - ++dst; - - src += GL_KOS_VERTEX_STRIDE; - } -} - -static void _glKosArraysTransformClip(GLuint count) { - GLubyte *src = GL_KOS_VERTEX_POINTER; - GLfloat *element; - GLfloat *W = GL_KOS_ARRAY_DSTW; - pvr_vertex_t *dst = _glKosClipBufAddress(); - - register float __x __asm__("fr12"); - register float __y __asm__("fr13"); - register float __z __asm__("fr14"); - register float __w __asm__("fr15"); - - while(count--) { - element = (GLfloat *) src; - __x = element[0]; - __y = element[1]; - __z = element[2]; - - mat_trans_fv12_nodivw() - - dst->x = __x; - dst->y = __y; - dst->z = __z; - *W++ = __w; - - ++dst; - - src += GL_KOS_VERTEX_STRIDE; - } -} - -static void _glKosArraysTransformElements(GLuint count) { - GLubyte *src = GL_KOS_VERTEX_POINTER; - GLfloat *element; - GLuint i = 0; - - register float __x __asm__("fr12"); - register float __y __asm__("fr13"); - register float __z __asm__("fr14"); - - for(i = 0; i < count; i++) { - element = (GLfloat *) src; - __x = element[0]; - __y = element[1]; - __z = element[2]; - - mat_trans_fv12() - - GL_KOS_ARRAY_BUF[i].pos[0] = __x; - GL_KOS_ARRAY_BUF[i].pos[1] = __y; - GL_KOS_ARRAY_BUF[i].pos[2] = __z; - - src += GL_KOS_VERTEX_STRIDE; - } -} - -static void _glKosArraysTransformClipElements(GLuint count) { - GLubyte *src = GL_KOS_VERTEX_POINTER; - GLfloat *element; - GLuint i; - - register float __x __asm__("fr12"); - register float __y __asm__("fr13"); - register float __z __asm__("fr14"); - register float __w __asm__("fr15"); - - for(i = 0; i < count; i++) { - element = (GLfloat *) src; - __x = element[0]; - __y = element[1]; - __z = element[2]; - - mat_trans_fv12_nodivw() - - GL_KOS_ARRAY_BUF[i].pos[0] = __x; - GL_KOS_ARRAY_BUF[i].pos[1] = __y; - GL_KOS_ARRAY_BUF[i].pos[2] = __z; - GL_KOS_ARRAY_BUFW[i] = __w; - - src += GL_KOS_VERTEX_STRIDE; - } -} - -//========================================================================================// -//== Element Attribute Functions ==// - -//== Color ==// - -static inline void _glKosArrayColor0(pvr_vertex_t *dst, GLuint count) { - GLuint i; - - dst[0].argb = _glKosVertexColor(); - - for(i = 1; i < count; i++) - dst[i].argb = dst[0].argb; -} - -static inline void _glKosElementColor1uiU8(pvr_vertex_t *dst, GLuint count) { - GLuint i; - GLuint *element; - GLubyte *src = GL_KOS_COLOR_POINTER; - - for(i = 0; i < count; i++) { - element = (GLuint *) (src + (GL_KOS_INDEX_POINTER_U8[i] * GL_KOS_COLOR_STRIDE)); - dst[i].argb = *element; - } -} - -static inline void _glKosElementColor1uiU16(pvr_vertex_t *dst, GLuint count) { - GLuint i; - GLuint *element; - GLubyte *color = GL_KOS_COLOR_POINTER; - - for(i = 0; i < count; i++) { - element = (GLuint *) (color + (GL_KOS_INDEX_POINTER_U16[i] * GL_KOS_COLOR_STRIDE)); - dst[i].argb = *element; - } -} - -static inline void _glKosElementColor4ubU8(pvr_vertex_t *dst, GLuint count) { - GLuint i; - GLuint *element; - GLubyte *color = GL_KOS_COLOR_POINTER; - - for(i = 0; i < count; i++) { - element = (GLuint *) (color + (GL_KOS_INDEX_POINTER_U8[i] * GL_KOS_COLOR_STRIDE)); - dst[i].argb = RGBA32_2_ARGB32(*element); - } -} - -static inline void _glKosElementColor4ubU16(pvr_vertex_t *dst, GLuint count) { - GLuint i; - GLuint *element; - GLubyte *color = GL_KOS_COLOR_POINTER; - - for(i = 0; i < count; i++) { - element = (GLuint *) (color + (GL_KOS_INDEX_POINTER_U16[i] * GL_KOS_COLOR_STRIDE)); - dst[i].argb = RGBA32_2_ARGB32(*element); - } -} - -static inline void _glKosElementColor3fU8(pvr_vertex_t *dst, GLuint count) { - GLuint i, index; - GLrgb3f* element; - GLubyte *color = GL_KOS_COLOR_POINTER; - - for(i = 0; i < count; i++) { - index = GL_KOS_INDEX_POINTER_U8[i] * GL_KOS_COLOR_STRIDE; - element = (GLrgb3f *) (color + index); - dst[i].argb = (0xFF000000 - | ((GLubyte)((*element)[0] * 0xFF)) << 16 - | ((GLubyte)((*element)[1] * 0xFF)) << 8 - | ((GLubyte)((*element)[2] * 0xFF))); - } -} - -static inline void _glKosElementColor3fU16(pvr_vertex_t *dst, GLuint count) { - GLuint i, index; - GLrgb3f* element; - GLubyte *color = GL_KOS_COLOR_POINTER; - - for(i = 0; i < count; i++) { - index = GL_KOS_INDEX_POINTER_U16[i] * GL_KOS_COLOR_STRIDE; - element = (GLrgb3f *) (color + index); - dst[i].argb = (0xFF000000 - | ((GLubyte)((*element)[0] * 0xFF)) << 16 - | ((GLubyte)((*element)[1] * 0xFF)) << 8 - | ((GLubyte)((*element)[2] * 0xFF))); - } -} - -static inline void _glKosElementColor4fU8(pvr_vertex_t *dst, GLuint count) { - GLuint i, index; - GLrgba4f* element; - GLubyte *color = GL_KOS_COLOR_POINTER; - - for(i = 0; i < count; i++) { - index = GL_KOS_INDEX_POINTER_U8[i] * GL_KOS_COLOR_STRIDE; - element = (GLrgba4f *) (color + index); - - dst[i].argb = ( ((GLubyte) ((*element)[3] * 0xFF)) << 24 - | ((GLubyte) ((*element)[0] * 0xFF)) << 16 - | ((GLubyte) ((*element)[1] * 0xFF)) << 8 - | ((GLubyte) ((*element)[2] * 0xFF))); - } -} - -static inline void _glKosElementColor4fU16(pvr_vertex_t *dst, GLuint count) { - GLuint i, index; - GLrgba4f* element; - GLubyte* color = GL_KOS_COLOR_POINTER; - - for(i = 0; i < count; i++) { - index = GL_KOS_INDEX_POINTER_U16[i] * GL_KOS_COLOR_STRIDE; - element = (GLrgba4f *) (color + index); - dst[i].argb = ( ((GLubyte)((*element)[3] * 0xFF)) << 24 - | ((GLubyte)((*element)[0] * 0xFF)) << 16 - | ((GLubyte)((*element)[1] * 0xFF)) << 8 - | ((GLubyte)((*element)[2] * 0xFF))); - } -} - -//== Texture Coordinates ==// - - - -static inline void _glKosElementTexCoord2fU16(pvr_vertex_t *dst, GLuint count) { - GLuint i, index; - GLubyte *src = GL_KOS_TEXCOORD0_POINTER; - GLfloat *t; - - if(_glKosEnabledTextureMatrix()) { - _glKosMatrixLoadTexture(); - - for(i = 0; i < count; i++) { - index = GL_KOS_INDEX_POINTER_U16[i] * GL_KOS_TEXCOORD0_STRIDE; - t = (GLfloat *) (src + index); - mat_trans_texture2_nomod(t[0], t[1], dst[i].u, dst[i].v); - } - - _glKosMatrixLoadRender(); - } - else { - for(i = 0; i < count; i++) { - index = GL_KOS_INDEX_POINTER_U16[i] * GL_KOS_TEXCOORD0_STRIDE; - t = (GLfloat *) (src + index); - dst[i].u = t[0]; - dst[i].v = t[1]; - } - } -} - -static inline void _glKosElementTexCoord2fU8(pvr_vertex_t *dst, GLuint count) { - GLuint i, index; - GLubyte *src = GL_KOS_TEXCOORD0_POINTER; - GLfloat *t; - - if(_glKosEnabledTextureMatrix()) { - _glKosMatrixLoadTexture(); - - for(i = 0; i < count; i++) { - index = GL_KOS_INDEX_POINTER_U8[i] * GL_KOS_TEXCOORD0_STRIDE; - t = (GLfloat *) (src + index); - mat_trans_texture2_nomod(t[0], t[1], dst[i].u, dst[i].v); - } - - _glKosMatrixLoadRender(); - } - else { - for(i = 0; i < count; i++) { - index = GL_KOS_INDEX_POINTER_U8[i] * GL_KOS_TEXCOORD0_STRIDE; - t = (GLfloat *) (src + index); - dst[i].u = t[0]; - dst[i].v = t[1]; - } - } -} - -static inline void _glKosElementMultiTexCoord2fU16C(GLuint count) { - GLuint i, index; - GLubyte *src = GL_KOS_TEXCOORD1_POINTER; - GLfloat *t; - GLfloat *dst = GL_KOS_ARRAY_BUFUV; - - for(i = 0; i < count; i++) { - index = GL_KOS_INDEX_POINTER_U16[i] * GL_KOS_TEXCOORD1_STRIDE; - t = (GLfloat *) (src + index); - *dst++ = t[0]; - *dst++ = t[1]; - } -} - -static inline void _glKosElementMultiTexCoord2fU8C(GLuint count) { - GLuint i, index; - GLubyte *src = GL_KOS_TEXCOORD1_POINTER; - GLfloat *t; - GLfloat *dst = GL_KOS_ARRAY_BUFUV; - - for(i = 0; i < count; i++) { - index = GL_KOS_INDEX_POINTER_U8[i] * GL_KOS_TEXCOORD1_STRIDE; - t = (GLfloat *) (src + index); - *dst++ = t[0]; - *dst++ = t[1]; - } -} - -static inline void _glKosElementMultiTexCoord2fU16(GLuint count) { - if(_glKosEnabledNearZClip()) - return _glKosElementMultiTexCoord2fU16C(count); - - GLuint i, index; - GLubyte *src = GL_KOS_TEXCOORD1_POINTER; - GLfloat *t; - glTexCoord *dst = (glTexCoord *)_glKosMultiUVBufPointer(); - - for(i = 0; i < count; i++) { - index = GL_KOS_INDEX_POINTER_U16[i] * GL_KOS_TEXCOORD1_STRIDE; - t = (GLfloat *) (src + index); - dst[i].u = t[0]; - dst[i].v = t[1]; - } - - _glKosMultiUVBufAdd(count); -} - -static inline void _glKosElementMultiTexCoord2fU8(GLuint count) { - if(_glKosEnabledNearZClip()) - return _glKosElementMultiTexCoord2fU8C(count); - - GLuint i, index; - GLubyte *src = GL_KOS_TEXCOORD1_POINTER; - GLfloat *t; - glTexCoord *dst = (glTexCoord *)_glKosMultiUVBufPointer(); - - for(i = 0; i < count; i++) { - index = GL_KOS_INDEX_POINTER_U8[i] * GL_KOS_TEXCOORD1_STRIDE; - t = (GLfloat *) (src + index); - dst[i].u = t[0]; - dst[i].v = t[1]; - } - - _glKosMultiUVBufAdd(count); -} - -//========================================================================================// -//== Element Unpacking ==// - -static inline void _glKosArraysUnpackElementsS16(pvr_vertex_t *dst, GLuint count) { - glVertex *vert = GL_KOS_ARRAY_BUF; - GLuint i; - - for(i = 0; i < count; i++) { - dst[i].x = vert[GL_KOS_INDEX_POINTER_U16[i]].pos[0]; - dst[i].y = vert[GL_KOS_INDEX_POINTER_U16[i]].pos[1]; - dst[i].z = vert[GL_KOS_INDEX_POINTER_U16[i]].pos[2]; - } -} - -static inline void _glKosArraysUnpackElementsS8(pvr_vertex_t *dst, GLuint count) { - glVertex *vert = GL_KOS_ARRAY_BUF; - GLuint i; - - for(i = 0; i < count; i++) { - dst[i].x = vert[GL_KOS_INDEX_POINTER_U8[i]].pos[0]; - dst[i].y = vert[GL_KOS_INDEX_POINTER_U8[i]].pos[1]; - dst[i].z = vert[GL_KOS_INDEX_POINTER_U8[i]].pos[2]; - } -} - -static inline void _glKosArraysUnpackClipElementsS16(pvr_vertex_t *dst, GLuint count) { - glVertex *vert = GL_KOS_ARRAY_BUF; - GLuint i; - - for(i = 0; i < count; i++) { - dst[i].x = vert[GL_KOS_INDEX_POINTER_U16[i]].pos[0]; - dst[i].y = vert[GL_KOS_INDEX_POINTER_U16[i]].pos[1]; - dst[i].z = vert[GL_KOS_INDEX_POINTER_U16[i]].pos[2]; - GL_KOS_ARRAY_DSTW[i] = GL_KOS_ARRAY_BUFW[GL_KOS_INDEX_POINTER_U16[i]]; - } -} - -static inline void _glKosArraysUnpackClipElementsS8(pvr_vertex_t *dst, GLuint count) { - glVertex *vert = GL_KOS_ARRAY_BUF; - GLuint i; - - for(i = 0; i < count; i++) { - dst[i].x = vert[GL_KOS_INDEX_POINTER_U8[i]].pos[0]; - dst[i].y = vert[GL_KOS_INDEX_POINTER_U8[i]].pos[1]; - dst[i].z = vert[GL_KOS_INDEX_POINTER_U8[i]].pos[2]; - GL_KOS_ARRAY_DSTW[i] = GL_KOS_ARRAY_BUFW[GL_KOS_INDEX_POINTER_U8[i]]; - } -} - -//========================================================================================// -//== Misc Utils ==// - -static inline void _glKosVertexSwizzle(pvr_vertex_t *v1, pvr_vertex_t *v2) { - pvr_vertex_t tmp = *v1; - *v1 = *v2; - *v2 = * &tmp; -} - -static inline void _glKosTexCoordSwizzle(glTexCoord *uv1, glTexCoord *uv2) { - glTexCoord tmp = *uv1; - *uv1 = *uv2; - *uv2 = * &tmp; -} - - -//========================================================================================// -//== Vertex Flag Settings for the PVR2DC hardware ==// - -static inline void _glKosArrayFlagsSetQuad(pvr_vertex_t *dst, GLuint count) { - GLuint i; - - for(i = 0; i < count; i += 4) { - _glKosVertexSwizzle(&dst[i + 2], &dst[i + 3]); - dst[i + 0].flags = dst[i + 1].flags = dst[i + 2].flags = PVR_CMD_VERTEX; - dst[i + 3].flags = PVR_CMD_VERTEX_EOL; - } -} - -static inline void _glKosArrayFlagsSetTriangle(pvr_vertex_t *dst, GLuint count) { - GLuint i; - - for(i = 0; i < count; i += 3) { - dst[i + 0].flags = dst[i + 1].flags = PVR_CMD_VERTEX; - dst[i + 2].flags = PVR_CMD_VERTEX_EOL; - } -} - -static inline void _glKosArrayFlagsSetTriangleStrip(pvr_vertex_t *dst, GLuint count) { - GLuint i; - - for(i = 0; i < count - 1; i++) - dst[i].flags = PVR_CMD_VERTEX; - - dst[i].flags = PVR_CMD_VERTEX_EOL; -} - - -static inline void _glKosArraysSwizzleQuadsMultiTex(GLuint count) { - if(!_glKosEnabledNearZClip()) { - GLuint i; - glTexCoord *t = (glTexCoord *)_glKosMultiUVBufPointer() - count; - - for(i = 0; i < count; i += 4) - _glKosTexCoordSwizzle(&t[i + 2], &t[i + 3]); - } -} - -//========================================================================================// -//== OpenGL Error Code Generation ==// - -static GLuint _glKosArraysVerifyParameter(GLenum mode, GLsizei count, GLenum type, GLubyte element) { - if(mode != GL_QUADS) - if(mode != GL_TRIANGLES) - if(mode != GL_TRIANGLE_STRIP) - _glKosThrowError(GL_INVALID_ENUM, (element) ? "glDrawElements" : "glDrawArrays"); - - if(count < 0) - _glKosThrowError(GL_INVALID_VALUE, (element) ? "glDrawElements" : "glDrawArrays"); - - if(count > GL_KOS_MAX_VERTS) - _glKosThrowError(GL_OUT_OF_MEMORY, (element) ? "glDrawElements" : "glDrawArrays"); - - if(element) { - switch(type) { - case GL_UNSIGNED_BYTE: - case GL_UNSIGNED_SHORT: - break; - - default: - _glKosThrowError(GL_INVALID_ENUM, (element) ? "glDrawElements" : "glDrawArrays"); - } - } - else if(type > count) - _glKosThrowError(GL_INVALID_VALUE, (element) ? "glDrawElements" : "glDrawArrays"); - - if(_glKosHasError()) { - _glKosPrintError(); - return 0; - } - - return (GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_ARRAY) ? 1 : 0; -} - -static GLuint _glKosArraysApplyClipping(GLfloat *uvsrc, GLuint uvstride, GLenum mode, GLuint count) { - switch(mode) { - case GL_TRIANGLES: - if(GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_TEXTURE1) { - count = _glKosClipTrianglesTransformedMT((pvr_vertex_t *)_glKosClipBufAddress(), - GL_KOS_ARRAY_DSTW, - (pvr_vertex_t *)_glKosVertexBufPointer(), - uvsrc, - (glTexCoord *)_glKosMultiUVBufPointer(), - uvstride, - count); - _glKosMultiUVBufAdd(count); - } - else - count = _glKosClipTrianglesTransformed((pvr_vertex_t *)_glKosClipBufAddress(), - GL_KOS_ARRAY_DSTW, - (pvr_vertex_t *)_glKosVertexBufPointer(), - count); - - break; - - case GL_QUADS: - if(GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_TEXTURE1) { - count = _glKosClipQuadsTransformedMT((pvr_vertex_t *)_glKosClipBufAddress(), - GL_KOS_ARRAY_DSTW, - (pvr_vertex_t *)_glKosVertexBufPointer(), - uvsrc, - (glTexCoord *)_glKosMultiUVBufPointer(), - uvstride, - count); - _glKosMultiUVBufAdd(count); - } - else - count = _glKosClipQuadsTransformed((pvr_vertex_t *)_glKosClipBufAddress(), - GL_KOS_ARRAY_DSTW, - (pvr_vertex_t *)_glKosVertexBufPointer(), - count); - - break; - - case GL_TRIANGLE_STRIP: - if(GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_TEXTURE1) { - count = _glKosClipTriangleStripTransformedMT((pvr_vertex_t *)_glKosClipBufAddress(), - GL_KOS_ARRAY_DSTW, - (pvr_vertex_t *)_glKosVertexBufPointer(), - uvsrc, - (glTexCoord *)_glKosMultiUVBufPointer(), - uvstride, - count); - _glKosMultiUVBufAdd(count); - } - else - count = _glKosClipTriangleStripTransformed((pvr_vertex_t *)_glKosClipBufAddress(), - GL_KOS_ARRAY_DSTW, - (pvr_vertex_t *)_glKosVertexBufPointer(), - count); - - break; - - default: - count = 0; - break; - } - - return count; -} - - -static inline void _glKosArraysApplyVertexFlags(GLenum mode, pvr_vertex_t *dst, GLuint count) { - switch(mode) { - case GL_QUADS: - _glKosArrayFlagsSetQuad(dst, count); - break; - - case GL_TRIANGLES: - _glKosArrayFlagsSetTriangle(dst, count); - break; - - case GL_TRIANGLE_STRIP: - _glKosArrayFlagsSetTriangleStrip(dst, count); - break; - } -} - -static inline void _glKosArraysApplyLighting(pvr_vertex_t *dst, GLuint count) { - _glKosArraysTransformNormals(GL_KOS_NORMAL_POINTER, count); - _glKosArraysTransformPositions(GL_KOS_VERTEX_POINTER, count); - _glKosVertexLights(GL_KOS_ARRAY_BUF, dst, count); -} - -static inline void _glKosArraysApplyHeader() { - if((GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_TEXTURE0) && _glKosBoundTexID() > 0) - _glKosCompileHdrTx(); - else - _glKosCompileHdr(); -} - -static inline pvr_vertex_t *_glKosArraysDest() { - if(_glKosEnabledNearZClip()) - return _glKosClipBufAddress(); - - return _glKosVertexBufPointer(); -} - -static inline void _glKosArraysFlush(GLuint count) { - _glKosVertexBufAdd(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; - -// /* Compile the PVR polygon context with the currently enabled flags */ -// _glKosArraysApplyHeader(); - -// /* Destination of Output Vertex Array */ -// pvr_vertex_t *dst = _glKosArraysDest(); - -// 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; -// } - -// /* 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; - -// case GL_UNSIGNED_SHORT: -// _glKosElementColor3fU16(dst, count); -// break; -// } - -// break; - -// case 4: -// switch(type) { -// case GL_UNSIGNED_BYTE: -// _glKosElementColor4fU8(dst, count); -// break; - -// case GL_UNSIGNED_SHORT: -// _glKosElementColor4fU16(dst, count); -// 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_SHORT: -// _glKosElementColor1uiU16(dst, count); -// 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_SHORT: -// _glKosElementColor4ubU16(dst, count); -// break; -// } - -// 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; - -// 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; - -// case GL_UNSIGNED_SHORT: -// _glKosElementMultiTexCoord2fU16(count); -// break; -// } - -// _glKosMatrixApplyRender(); /* Apply the Render Matrix Stack */ - -// 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; - -// 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); - -// /* 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; -// } - -// count = _glKosArraysApplyClipping(GL_KOS_ARRAY_BUFUV, 2, mode, count); -// } - -// _glKosArraysApplyMultiTexture(mode, count); - -// _glKosArraysFlush(count); -//} - -//========================================================================================// -//== Array Attribute Functions ==// - -//== Color ==// - -static inline void _glKosArrayColor1ui(pvr_vertex_t *dst, GLuint count) { - GLuint i; - GLbyte *color = (GLbyte *)GL_KOS_COLOR_POINTER; - - for(i = 0; i < count; i++) { - dst[i].argb = *((GLuint *) color); - color += GL_KOS_COLOR_STRIDE; - } -} - -static inline void _glKosArrayColor4ub(pvr_vertex_t *dst, GLuint count) { - GLuint i; - GLuint *element; - GLubyte *color = GL_KOS_COLOR_POINTER; - - for(i = 0; i < count; i++) { - element = (GLuint *) color; - dst[i].argb = RGBA32_2_ARGB32(*element); - color += GL_KOS_COLOR_STRIDE; - } -} - -static inline void _glKosArrayColor3f(pvr_vertex_t *dst, GLuint count) { - GLuint i; - GLfloat *element; - GLubyte *color = GL_KOS_COLOR_POINTER; - - for(i = 0; i < count; i++) { - element = (GLfloat *) color; - dst[i].argb = (0xFF000000 | ((GLubyte)(element[0] * 0xFF)) << 16 - | ((GLubyte)(element[1] * 0xFF)) << 8 - | ((GLubyte)(element[2] * 0xFF))); - color += GL_KOS_COLOR_STRIDE; - } -} - -static inline void _glKosArrayColor4f(pvr_vertex_t *dst, GLuint count) { - GLuint i; - GLfloat *element; - GLubyte *color = GL_KOS_COLOR_POINTER; - - for(i = 0; i < count; i++) { - element = (GLfloat *) color; - dst[i].argb = (((GLubyte)(element[3] * 0xFF)) << 24 - | ((GLubyte)(element[0] * 0xFF)) << 16 - | ((GLubyte)(element[1] * 0xFF)) << 8 - | ((GLubyte)(element[2] * 0xFF))); - color += GL_KOS_COLOR_STRIDE; - } -} - -//== Texture Coordinates ==// - -static inline void _glKosArrayTexCoord2f(pvr_vertex_t *dst, GLuint count) { - GLuint i; - GLubyte *src = GL_KOS_TEXCOORD0_POINTER; - GLfloat *uv; - - if(_glKosEnabledTextureMatrix()) { - _glKosMatrixLoadTexture(); - - for(i = 0; i < count; i++) { - uv = (GLfloat *) src; - mat_trans_texture2_nomod(uv[0], uv[1], dst[i].u, dst[i].v); - - src += GL_KOS_TEXCOORD0_STRIDE; - } - - _glKosMatrixLoadRender(); - } - else { - for(i = 0; i < count; i++) { - uv = (GLfloat *) src; - dst[i].u = uv[0]; - dst[i].v = uv[1]; - src += GL_KOS_TEXCOORD0_STRIDE; - } - } -} - -static inline void _glKosArrayMultiTexCoord2f(GLuint count) { - if(_glKosEnabledNearZClip()) - return; - - GLuint i; - GLubyte *src = GL_KOS_TEXCOORD1_POINTER; - GLfloat *uv; - glTexCoord *dst = (glTexCoord *)_glKosMultiUVBufPointer(); - - for(i = 0; i < count; i++) { - uv = (GLfloat *) src; - dst[i].u = uv[0]; - dst[i].v = uv[1]; - src += GL_KOS_TEXCOORD1_STRIDE; - } - - _glKosMultiUVBufAdd(count); -} - -//========================================================================================// -//== Open GL Draw Arrays ==// - -static void _glKosDrawArrays2D(GLenum mode, GLint first, GLsizei count) { - pvr_vertex_t *dst = _glKosVertexBufPointer(); - - /* Check for Color Submission */ - 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; - - case 4: - _glKosArrayColor4f(dst, count); - break; - } - - break; - - case GL_UNSIGNED_INT: - if(GL_KOS_COLOR_COMPONENTS == 1) - _glKosArrayColor1ui(dst, count); - - break; - - case GL_UNSIGNED_BYTE: - if(GL_KOS_COLOR_COMPONENTS == 4) - _glKosArrayColor4ub(dst, count); - - 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)) - _glKosArrayTexCoord2f(dst, count); - - _glKosMatrixApplyRender(); /* Apply the Render Matrix Stack */ - - /* Transform Vertex Positions */ - _glKosArraysTransform2D(count); - - /* Set the vertex flags for use with the PVR */ - _glKosArraysApplyVertexFlags(mode, dst, 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); - -// /* Compile the PVR polygon context with the currently enabled flags */ -// _glKosArraysApplyHeader(); - -// if(GL_KOS_VERTEX_SIZE == 2) -// return _glKosDrawArrays2D(mode, first, count); - -// /* Destination of Output Vertex Array */ -// pvr_vertex_t *dst = _glKosArraysDest(); - -// /* 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: -// _glKosArrayColor3f(dst, count); -// break; - -// case 4: -// _glKosArrayColor4f(dst, count); -// break; -// } - -// break; - -// case GL_UNSIGNED_INT: -// if(GL_KOS_COLOR_COMPONENTS == 1) -// _glKosArrayColor1ui(dst, count); - -// break; - -// case GL_UNSIGNED_BYTE: -// if(GL_KOS_COLOR_COMPONENTS == 4) -// _glKosArrayColor4ub(dst, count); - -// break; -// } -// } -// else -// _glKosArrayColor0(dst, count); /* No colors bound, color white */ - -// /* Check if Texture Coordinates are enabled */ -// if((GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_TEXTURE0) && (_glKosEnabledTexture2D() >= 0)) -// _glKosArrayTexCoord2f(dst, count); - -// /* Check if Multi Texture Coordinates are enabled */ -// if((GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_TEXTURE1) && (_glKosEnabledTexture2D() >= 0)) -// _glKosArrayMultiTexCoord2f(count); - -// _glKosMatrixApplyRender(); /* Apply the Render Matrix Stack */ - -// if(!_glKosEnabledNearZClip()) { /* No NearZ Clipping Enabled */ -// /* Transform Vertex Positions */ -// _glKosArraysTransform(count); - -// /* 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); - -// /* 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 */ -// } - -// _glKosArraysApplyMultiTexture(mode, count); - -// _glKosArraysFlush(count); -//} - - diff --git a/gl-arrays.h b/gl-arrays.h deleted file mode 100644 index 0d57d9d..0000000 --- a/gl-arrays.h +++ /dev/null @@ -1,30 +0,0 @@ -/* KallistiGL for KallistiOS ##version## - - libgl/gl-arrays.h - Copyright (C) 2013-2014 Josh Pearson - - Arrays Input Primitive Types Supported: - -GL_TRIANGLES - -GL_TRIANGLE_STRIPS - -GL_QUADS - - Here, it is not necessary to enable or disable client states; - the API is aware of what arrays have been submitted, and will - render accordingly. If you submit a normal pointer, dynamic - vertex lighting will be applied even if you submit a color - pointer, so only submit one or the other. - -*/ - -#ifndef GL_ARRAYS_H -#define GL_ARRAYS_H - -#include "gl.h" - -#define GL_KOS_USE_ARRAY (1<<0) -#define GL_KOS_USE_TEXTURE0 (1<<1) -#define GL_KOS_USE_TEXTURE1 (1<<2) -#define GL_KOS_USE_COLOR (1<<3) -#define GL_KOS_USE_NORMAL (1<<4) - -#endif From cd71de76ee562ff5d4140145d8ab7a13d3ac0058 Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Wed, 16 May 2018 21:50:05 +0100 Subject: [PATCH 18/21] Add a readme --- README.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..f4fbb93 --- /dev/null +++ b/README.md @@ -0,0 +1,28 @@ + +# GLdc + +This is a partial implementation of OpenGL 1.2 for the SEGA Dreamcast for use +with the KallistiOS SDK. + +It began as a fork of libGL by Josh Pearson but has undergone a large refactor +which is essentially a rewrite. + +The aim is to implement as much of OpenGL 1.2 as possible, and to add additional +features via extensions. + +Things left to (re)implement: + + - Fog + - Near-Z clipping + - Spotlights and point lights + - Framebuffer extension + +Things I'd like to do: + + - Use a clean "gl.h" + - Define an extension for modifier volumes + - Support `GL_ALPHA_TEST` using punch-thru polys + - Add support for point sprites + - Optimise, add unit tests for correctness + + From 23e564269be45285e3cee991ca8b3f23fd352ccb Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Sat, 19 May 2018 09:17:24 +0100 Subject: [PATCH 19/21] Fix lighting bugs --- GL/draw.c | 78 ++++++++++++++++++++++++++++++++++++++++---------- GL/immediate.c | 8 ++++++ GL/lighting.c | 53 +++++++++++++++++++++------------- GL/matrix.c | 6 +++- GL/private.h | 15 ++++------ gl-api.c | 38 ------------------------ include/gl.h | 4 --- 7 files changed, 115 insertions(+), 87 deletions(-) diff --git a/GL/draw.c b/GL/draw.c index 02a4c10..cc9a744 100644 --- a/GL/draw.c +++ b/GL/draw.c @@ -35,6 +35,26 @@ void initAttributePointers() { VERTEX_POINTER.stride = 0; VERTEX_POINTER.type = GL_FLOAT; VERTEX_POINTER.size = 4; + + DIFFUSE_POINTER.ptr = NULL; + DIFFUSE_POINTER.stride = 0; + DIFFUSE_POINTER.type = GL_FLOAT; + DIFFUSE_POINTER.size = 4; + + UV_POINTER.ptr = NULL; + UV_POINTER.stride = 0; + UV_POINTER.type = GL_FLOAT; + UV_POINTER.size = 4; + + ST_POINTER.ptr = NULL; + ST_POINTER.stride = 0; + ST_POINTER.type = GL_FLOAT; + ST_POINTER.size = 4; + + NORMAL_POINTER.ptr = NULL; + NORMAL_POINTER.stride = 0; + NORMAL_POINTER.type = GL_FLOAT; + NORMAL_POINTER.size = 3; } static GLuint byte_size(GLenum type) { @@ -46,6 +66,7 @@ static GLuint byte_size(GLenum type) { case GL_INT: return sizeof(GLint); case GL_UNSIGNED_INT: return sizeof(GLuint); case GL_DOUBLE: return sizeof(GLdouble); + case GL_FLOAT: default: return sizeof(GLfloat); } } @@ -90,7 +111,7 @@ static void _parseColour(uint32* out, const GLubyte* in, GLint size, GLenum type } static void _parseFloats(GLfloat* out, const GLubyte* in, GLint size, GLenum type) { - GLubyte i = 0; + GLubyte i; switch(type) { case GL_SHORT: { @@ -107,8 +128,10 @@ static void _parseFloats(GLfloat* out, const GLubyte* in, GLint size, GLenum typ } break; case GL_FLOAT: case GL_DOUBLE: /* Double == Float */ - default: - for(i = 0; i < size; ++i) out[i] = ((GLfloat*) in)[i]; + default: { + const GLfloat* ptr = (const GLfloat*) in; + for(i = 0; i < size; ++i) out[i] = ptr[i]; + } } } @@ -123,27 +146,52 @@ static void _parseIndex(GLshort* out, const GLubyte* in, GLenum type) { } } -/* -inline void mat_trans_float3_nodiv(const GLfloat* mat, GLfloat* v) { - GLfloat x = v[0] * mat[0] + v[1] * mat[4] + v[2] * mat[8] + mat[12]; - GLfloat y = v[0] * mat[1] + v[1] * mat[5] + v[2] * mat[9] + mat[13]; - GLfloat z = v[0] * mat[2] + v[1] * mat[6] + v[2] * mat[10] + mat[14]; - v[0] = x; - v[1] = y; - v[2] = z; -} */ +/* There was a bug in this macro that shipped with Kos + * which has now been fixed. But just in case... + */ +#undef mat_trans_single3_nodiv +#define mat_trans_single3_nodiv(x, y, z) { \ + register float __x __asm__("fr12") = (x); \ + register float __y __asm__("fr13") = (y); \ + register float __z __asm__("fr14") = (z); \ + __asm__ __volatile__( \ + "fldi1 fr15\n" \ + "ftrv xmtrx, fv12\n" \ + : "=f" (__x), "=f" (__y), "=f" (__z) \ + : "0" (__x), "1" (__y), "2" (__z) \ + : "fr15"); \ + x = __x; y = __y; z = __z; \ +} -void transformToEyeSpace(GLfloat* point) { +#undef mat_trans_normal3 +#define mat_trans_normal3(x, y, z) { \ + register float __x __asm__("fr8") = (x); \ + register float __y __asm__("fr9") = (y); \ + register float __z __asm__("fr10") = (z); \ + __asm__ __volatile__( \ + "fldi0 fr11\n" \ + "ftrv xmtrx, fv8\n" \ + : "=f" (__x), "=f" (__y), "=f" (__z) \ + : "0" (__x), "1" (__y), "2" (__z) \ + : "fr11"); \ + x = __x; y = __y; z = __z; \ +} + + + +inline void transformToEyeSpace(GLfloat* point) { _matrixLoadModelView(); mat_trans_single3_nodiv(point[0], point[1], point[2]); } -void transformNormalToEyeSpace(GLfloat* normal) { + +inline void transformNormalToEyeSpace(GLfloat* normal) { _matrixLoadNormal(); mat_trans_normal3(normal[0], normal[1], normal[2]); } + static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum type, const GLvoid* indices) { static GLfloat normal[3] = {0.0f, 0.0f, -1.0f}; static GLfloat eye_P[3]; @@ -242,7 +290,7 @@ static void submitVertices(GLenum mode, GLsizei first, GLsizei count, GLenum typ GLubyte j; for(j = 0; j < MAX_LIGHTS; ++j) { - if(isLightEnabled(i)) { + if(isLightEnabled(j)) { calculateLightingContribution(j, eye_P, eye_N, to_add); contribution[0] += to_add[0]; diff --git a/GL/immediate.c b/GL/immediate.c index eced866..ab29025 100644 --- a/GL/immediate.c +++ b/GL/immediate.c @@ -89,6 +89,14 @@ void APIENTRY glVertex3fv(const GLfloat* v) { glVertex3f(v[0], v[1], v[2]); } +void APIENTRY glVertex2f(GLfloat x, GLfloat y) { + glVertex3f(x, y, 0.0f); +} + +void APIENTRY glVertex2fv(const GLfloat* v) { + glVertex2f(v[0], v[1]); +} + void APIENTRY glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) { glVertex3f(x, y, z); } diff --git a/GL/lighting.c b/GL/lighting.c index 064b21c..eb95b17 100644 --- a/GL/lighting.c +++ b/GL/lighting.c @@ -21,9 +21,6 @@ void initLights() { memcpy(MATERIAL.specular, ZERO, sizeof(GLfloat) * 4); memcpy(MATERIAL.emissive, ZERO, sizeof(GLfloat) * 4); MATERIAL.exponent = 0.0f; - MATERIAL.ambient_color_index = 0.0f; - MATERIAL.diffuse_color_index = 1.0f; - MATERIAL.specular_color_index = 1.0f; GLubyte i; for(i = 0; i < MAX_LIGHTS; ++i) { @@ -231,36 +228,52 @@ static float FPOW(float b, float p) { void calculateLightingContribution(const GLint light, const GLfloat* pos, const GLfloat* normal, GLfloat* colour) { LightSource* l = &LIGHTS[light]; - struct vec3f L, N, V; + struct vec3f L = { + l->position[0] - pos[0], + l->position[1] - pos[1], + l->position[2] - pos[2] + }; - L.x = l->position[0] - pos[0]; - L.y = l->position[1] - pos[1]; - L.z = l->position[2] - pos[2]; + struct vec3f N = { + normal[0], + normal[1], + normal[2] + }; - N.x = normal[0]; - N.y = normal[1]; - N.z = normal[2]; + struct vec3f V = { + pos[0], + pos[1], + pos[2] + }; - V.x = -pos[0]; - V.y = -pos[1]; - V.z = -pos[2]; + GLfloat d; + vec3f_length(V.x, V.y, V.z, d); vec3f_normalize(L.x, L.y, L.z); vec3f_normalize(V.x, V.y, V.z); - GLfloat LdotN; - vec3f_dot(L.x, L.y, L.z, N.x, N.y, N.z, LdotN); + GLfloat NdotL; + vec3f_dot(N.x, N.y, N.z, L.x, L.y, L.z, NdotL); - GLfloat f = (LdotN < 0) ? 0 : 1; + GLfloat f = (NdotL < 0) ? 0 : 1; GLfloat VdotN; vec3f_dot(V.x, V.y, V.z, N.x, N.y, N.z, VdotN); - GLfloat VdotR = VdotN - LdotN; + GLfloat VdotR = VdotN - NdotL; GLfloat specularPower = FPOW(VdotR > 0 ? VdotR : 0, MATERIAL.exponent); - colour[0] = l->ambient[0] * MATERIAL.ambient[0] + f * (l->diffuse[0] * MATERIAL.diffuse[0] * LdotN + l->specular[0] * MATERIAL.specular[0] * specularPower); - colour[1] = l->ambient[1] * MATERIAL.ambient[1] + f * (l->diffuse[1] * MATERIAL.diffuse[1] * LdotN + l->specular[1] * MATERIAL.specular[1] * specularPower); - colour[2] = l->ambient[2] * MATERIAL.ambient[2] + f * (l->diffuse[2] * MATERIAL.diffuse[2] * LdotN + l->specular[2] * MATERIAL.specular[2] * specularPower); + GLfloat att = (l->position[3] == 0) ? 1.0f : ( + l->constant_attenuation / (1.0f + l->linear_attenuation * d) * (1.0f + l->quadratic_attenuation * d * d) + ); + + colour[0] = att * l->ambient[0] * MATERIAL.ambient[0] + f * (l->diffuse[0] * MATERIAL.diffuse[0] * NdotL + l->specular[0] * MATERIAL.specular[0] * specularPower); + colour[1] = att * l->ambient[1] * MATERIAL.ambient[1] + f * (l->diffuse[1] * MATERIAL.diffuse[1] * NdotL + l->specular[1] * MATERIAL.specular[1] * specularPower); + colour[2] = att * l->ambient[2] * MATERIAL.ambient[2] + f * (l->diffuse[2] * MATERIAL.diffuse[2] * NdotL + l->specular[2] * MATERIAL.specular[2] * specularPower); colour[3] = MATERIAL.diffuse[3]; + + if(colour[0] > 1.0f) colour[0] = 1.0f; + if(colour[1] > 1.0f) colour[1] = 1.0f; + if(colour[2] > 1.0f) colour[2] = 1.0f; + if(colour[3] > 1.0f) colour[3] = 1.0f; } diff --git a/GL/matrix.c b/GL/matrix.c index e9e4703..0c36219 100644 --- a/GL/matrix.c +++ b/GL/matrix.c @@ -85,8 +85,8 @@ static void transpose(GLfloat* m) { static void recalculateNormalMatrix() { memcpy(NORMAL_MATRIX, stack_top(MATRIX_STACKS + (GL_MODELVIEW & 0xF)), sizeof(matrix_t)); - transpose((GLfloat*) NORMAL_MATRIX); inverse((GLfloat*) NORMAL_MATRIX); + transpose((GLfloat*) NORMAL_MATRIX); } void APIENTRY glMatrixMode(GLenum mode) { @@ -271,6 +271,10 @@ void glMultTransposeMatrixf(const GLfloat *m) { mat_load(stack_top(MATRIX_STACKS + MATRIX_IDX)); mat_apply(&ml); mat_store(stack_top(MATRIX_STACKS + MATRIX_IDX)); + + if(MATRIX_MODE == GL_MODELVIEW) { + recalculateNormalMatrix(); + } } /* Set the GL viewport */ diff --git a/GL/private.h b/GL/private.h index 6f081cd..b64c192 100644 --- a/GL/private.h +++ b/GL/private.h @@ -42,27 +42,24 @@ typedef struct { } TextureObject; typedef struct { + GLfloat emissive[4]; GLfloat ambient[4]; GLfloat diffuse[4]; - GLfloat specular[4]; - GLfloat emissive[4]; + GLfloat specular[4]; GLfloat exponent; - GLfloat ambient_color_index; - GLfloat diffuse_color_index; - GLfloat specular_color_index; } Material; typedef struct { - GLfloat ambient[4]; - GLfloat diffuse[4]; - GLfloat specular[4]; GLfloat position[4]; GLfloat spot_direction[3]; - GLfloat spot_exponent; GLfloat spot_cutoff; GLfloat constant_attenuation; GLfloat linear_attenuation; GLfloat quadratic_attenuation; + GLfloat spot_exponent; + GLfloat diffuse[4]; + GLfloat specular[4]; + GLfloat ambient[4]; } LightSource; diff --git a/gl-api.c b/gl-api.c index 852d42d..a62e717 100644 --- a/gl-api.c +++ b/gl-api.c @@ -251,14 +251,6 @@ void APIENTRY glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a) { //== Vertex Position Submission Functions ==// -void APIENTRY glVertex2f(GLfloat x, GLfloat y) { - return _glKosVertex3ft(x, y, 0.0f); -} - -void APIENTRY glVertex2fv(const GLfloat *xy) { - return _glKosVertex3ft(xy[0], xy[1], 0.0f); -} - void APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) { pvr_vertex_t *v = _glKosVertexBufPointer(); @@ -289,36 +281,6 @@ void APIENTRY glRectiv(const GLint *v1, const GLint *v2) { return glRectfv((const GLfloat *)v1, (const GLfloat *)v2); } -void APIENTRY glKosVertex2f(GLfloat x, GLfloat y) { - pvr_vertex_t *v = _glKosVertexBufPointer(); - - v->x = x; - v->y = y; - v->z = 10; - v->u = GL_KOS_VERTEX_UV[0]; - v->v = GL_KOS_VERTEX_UV[1]; - v->argb = GL_KOS_VERTEX_COLOR; - - _glKosVertexBufIncrement(); - - ++GL_KOS_VERTEX_COUNT; -} - -void APIENTRY glKosVertex2fv(const GLfloat *xy) { - pvr_vertex_t *v = _glKosVertexBufPointer(); - - v->x = xy[0]; - v->y = xy[1]; - v->z = 10; - v->u = GL_KOS_VERTEX_UV[0]; - v->v = GL_KOS_VERTEX_UV[1]; - v->argb = GL_KOS_VERTEX_COLOR; - - _glKosVertexBufIncrement(); - - ++GL_KOS_VERTEX_COUNT; -} - //====================================================================================================// //== GL Begin / End ==// diff --git a/include/gl.h b/include/gl.h index 38e3caa..eb9dc46 100644 --- a/include/gl.h +++ b/include/gl.h @@ -436,10 +436,6 @@ GLAPI void APIENTRY glVertex2f(GLfloat x, GLfloat y); GLAPI void APIENTRY glVertex2fv(const GLfloat *xy); #define glVertex2iv glVertex2fv -/* Non-Standard KOS Primitive 2D Submission. This will perform no tranformations on the vertices. */ -GLAPI void APIENTRY glKosVertex2f(GLfloat x, GLfloat y); -GLAPI void APIENTRY glKosVertex2fv(const GLfloat *xy); - /* Primitive 3D Position Submission */ GLAPI void APIENTRY glVertex3f(GLfloat, GLfloat, GLfloat); GLAPI void APIENTRY glVertex3fv(const GLfloat *); From 1421736733f5b13cd889bd87f31907f8cc00a2f0 Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Sat, 19 May 2018 13:43:22 +0100 Subject: [PATCH 20/21] Remove another old file --- GL/lighting.c | 1 + GL/state.c | 18 +++++ Makefile | 2 +- README.md | 11 +-- gl-cap.c | 188 -------------------------------------------------- 5 files changed, 27 insertions(+), 193 deletions(-) delete mode 100644 gl-cap.c diff --git a/GL/lighting.c b/GL/lighting.c index eb95b17..249a389 100644 --- a/GL/lighting.c +++ b/GL/lighting.c @@ -225,6 +225,7 @@ static float FPOW(float b, float p) { return FEXP(FLOG(b) * p); } +void calculateLightingContribution(const GLint light, const GLfloat* pos, const GLfloat* normal, GLfloat* colour) __attribute__((optimize("fast-math"))); void calculateLightingContribution(const GLint light, const GLfloat* pos, const GLfloat* normal, GLfloat* colour) { LightSource* l = &LIGHTS[light]; diff --git a/GL/state.c b/GL/state.c index dac06cc..044b3d8 100644 --- a/GL/state.c +++ b/GL/state.c @@ -428,3 +428,21 @@ void APIENTRY glGetIntegerv(GLenum pname, GLint *params) { break; } } + +const GLbyte *glGetString(GLenum name) { + switch(name) { + case GL_VENDOR: + return "KallistiOS / Kazade"; + + case GL_RENDERER: + return "PowerVR2 CLX2 100mHz"; + + case GL_VERSION: + return "GLdc 1.x"; + + case GL_EXTENSIONS: + return "GL_ARB_framebuffer_object, GL_ARB_multitexture, GL_ARB_texture_rg"; + } + + return "GL_KOS_ERROR: ENUM Unsupported\n"; +} diff --git a/Makefile b/Makefile index 4da1644..f2711c1 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ TARGET = libGL.a OBJS = gl-rgb.o gl-fog.o gl-sh4-light.o gl-light.o gl-clip.o gl-clip-arrays.o OBJS += gl-pvr.o gl-matrix.o gl-api.o glu-texture.o -OBJS += gl-framebuffer.o gl-cap.o gl-error.o +OBJS += gl-framebuffer.o gl-error.o OBJS += GL/draw.o GL/flush.o GL/framebuffer.o GL/immediate.o GL/lighting.o GL/state.o GL/texture.o OBJS += GL/matrix.o diff --git a/README.md b/README.md index f4fbb93..c4c7834 100644 --- a/README.md +++ b/README.md @@ -12,10 +12,13 @@ features via extensions. Things left to (re)implement: - - Fog - - Near-Z clipping - - Spotlights and point lights - - Framebuffer extension + - Fog (Trivial) + - Near-Z clipping (Tricky) + - Spotlights (Trivial) + - Framebuffer extension (Trivial) + - Multitexturing (Trivial) + - Texture Matrix (Trivial) + - Mipmapping (Trivial) Things I'd like to do: diff --git a/gl-cap.c b/gl-cap.c deleted file mode 100644 index 63996ad..0000000 --- a/gl-cap.c +++ /dev/null @@ -1,188 +0,0 @@ -/* KallistiGL for KallistiOS ##version## - - libgl/gl-cap.c - Copyright (C) 2014 Josh Pearson - - KOS Open GL Capabilty State Machine Implementation. -*/ - -#include "gl.h" -#include "gl-api.h" - -//===============================================================================// -//== Enable Bit Flags ==// - -#define GL_KOS_ENABLE_DEPTH_TEST (1<<0) -#define GL_KOS_ENABLE_SCISSOR_TEST (1<<1) -#define GL_KOS_ENABLE_CULLING (1<<2) -#define GL_KOS_ENABLE_FOG (1<<3) -#define GL_KOS_ENABLE_LIGHTING (1<<4) -#define GL_KOS_ENABLE_ZCLIPPING (1<<5) -#define GL_KOS_ENABLE_SUPERSAMPLE (1<<6) -#define GL_KOS_ENABLE_TEXTURE2D (1<<7) -#define GL_KOS_ENABLE_BLENDING (1<<8) -#define GL_KOS_ENABLE_TEXTURE_MAT (1<<9) - -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); - -// 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_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_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_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_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); - -// 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_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_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_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_KOS_TEXTURE_MATRIX: -// GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_TEXTURE_MAT; -// break; -// } -//} - - -void APIENTRY glGetFloatv(GLenum pname, GLfloat *params) { - switch(pname) { - case GL_MODELVIEW_MATRIX: - case GL_PROJECTION_MATRIX: - case GL_TEXTURE_MATRIX: - glKosGetMatrix(pname - GL_MODELVIEW_MATRIX + 1, params); - break; - - default: - _glKosThrowError(GL_INVALID_ENUM, "glGetFloatv"); - _glKosPrintError(); - break; - } -} - -const GLbyte *glGetString(GLenum name) { - switch(name) { - case GL_VENDOR: - return "KallistiOS / Kazade"; - - case GL_RENDERER: - return "PowerVR2 CLX2 100mHz"; - - case GL_VERSION: - return "KGL 1.x"; - - case GL_EXTENSIONS: - return "GL_ARB_framebuffer_object, GL_ARB_multitexture, GL_ARB_texture_rg"; - } - - return "GL_KOS_ERROR: ENUM Unsupported\n"; -} - -//===============================================================================// -//== Internal API Functions ==// - -GLubyte _glKosEnabledDepthTest() { - return GL_KOS_ENABLE_CAP & GL_KOS_ENABLE_DEPTH_TEST; -} - -GLubyte _glKosEnabledScissorTest() { - return GL_KOS_ENABLE_CAP & GL_KOS_ENABLE_SCISSOR_TEST; -} - -GLubyte _glKosEnabledCulling() { - return GL_KOS_ENABLE_CAP & GL_KOS_ENABLE_CULLING; -} - -GLubyte _glKosEnabledFog() { - return GL_KOS_ENABLE_CAP & GL_KOS_ENABLE_FOG; -} - -GLubyte _glKosEnabledLighting() { - return GL_KOS_ENABLE_CAP & GL_KOS_ENABLE_LIGHTING; -} - -GLubyte _glKosEnabledNearZClip() { - return GL_KOS_ENABLE_CAP & GL_KOS_ENABLE_ZCLIPPING; -} - -GLubyte _glKosEnabledTexture2D() { - return GL_KOS_ENABLE_CAP & GL_KOS_ENABLE_TEXTURE2D; -} - -GLubyte _glKosEnabledBlend() { - return (GL_KOS_ENABLE_CAP & GL_KOS_ENABLE_BLENDING) >> 8; -} - -GLubyte _glKosEnabledTextureMatrix() { - return (GL_KOS_ENABLE_CAP & GL_KOS_ENABLE_TEXTURE_MAT) >> 9; -} From 396ea8285626395f7986854c260570298cc786ed Mon Sep 17 00:00:00 2001 From: Luke Benstead Date: Sun, 20 May 2018 16:16:53 +0100 Subject: [PATCH 21/21] Drop all of the old libGL files --- GL/draw.c | 1 - gl-error.c => GL/error.c | 1 - GL/flush.c | 1 - GL/fog.c | 74 +++++ GL/framebuffer.c | 33 ++ GL/immediate.c | 35 +++ GL/matrix.c | 23 +- GL/private.h | 5 +- GL/state.c | 7 +- GL/texture.c | 7 +- Makefile | 7 +- gl-api.c | 663 --------------------------------------- gl-api.h | 206 ------------ gl-clip-arrays.c | 418 ------------------------ gl-clip.c | 310 ------------------ gl-clip.h | 52 --- gl-fog.c | 95 ------ gl-framebuffer.c | 181 ----------- gl-light.c | 364 --------------------- gl-light.h | 51 --- gl-pvr.c | 178 ----------- gl-pvr.h | 44 --- gl-rgb.c | 310 ------------------ gl-rgb.h | 70 ----- gl-sh4-light.S | 209 ------------ gl-sh4.h | 86 ----- glu-texture.c | 115 ------- include/gl.h | 8 - include/glkos.h | 8 + 29 files changed, 177 insertions(+), 3385 deletions(-) rename gl-error.c => GL/error.c (99%) create mode 100644 GL/fog.c delete mode 100644 gl-api.c delete mode 100644 gl-api.h delete mode 100644 gl-clip-arrays.c delete mode 100644 gl-clip.c delete mode 100644 gl-clip.h delete mode 100644 gl-fog.c delete mode 100644 gl-framebuffer.c delete mode 100644 gl-light.c delete mode 100644 gl-light.h delete mode 100644 gl-pvr.c delete mode 100644 gl-pvr.h delete mode 100644 gl-rgb.c delete mode 100644 gl-rgb.h delete mode 100644 gl-sh4-light.S delete mode 100644 gl-sh4.h delete mode 100644 glu-texture.c diff --git a/GL/draw.c b/GL/draw.c index cc9a744..4c66597 100644 --- a/GL/draw.c +++ b/GL/draw.c @@ -3,7 +3,6 @@ #include "../include/gl.h" #include "../include/glext.h" #include "private.h" -#include "../gl-api.h" typedef struct { const void* ptr; diff --git a/gl-error.c b/GL/error.c similarity index 99% rename from gl-error.c rename to GL/error.c index b62fd52..24139bb 100644 --- a/gl-error.c +++ b/GL/error.c @@ -9,7 +9,6 @@ */ #include "gl.h" -#include "gl-api.h" #include diff --git a/GL/flush.c b/GL/flush.c index d089779..e64036c 100644 --- a/GL/flush.c +++ b/GL/flush.c @@ -4,7 +4,6 @@ #include "../containers/aligned_vector.h" #include "private.h" -#include "../gl-api.h" #define TA_SQ_ADDR (unsigned int *)(void *) \ (0xe0000000 | (((unsigned long)0x10000000) & 0x03ffffe0)) diff --git a/GL/fog.c b/GL/fog.c new file mode 100644 index 0000000..ccf0662 --- /dev/null +++ b/GL/fog.c @@ -0,0 +1,74 @@ + +#include +#include "private.h" + +static GLfloat FOG_START = 0.0f; +static GLfloat FOG_END = 1.0f; +static GLfloat FOG_DENSITY = 1.0f; +static GLenum FOG_MODE = GL_EXP; +static GLfloat FOG_COLOR [] = {0.0f, 0.0f, 0.0f, 0.0f}; + +static void updatePVRFog() { + if(FOG_MODE == GL_LINEAR) { + pvr_fog_table_linear(FOG_START, FOG_END); + } else if(FOG_MODE == GL_EXP) { + pvr_fog_table_exp(FOG_DENSITY); + } else if(FOG_MODE == GL_EXP2) { + pvr_fog_table_exp2(FOG_DENSITY); + } + pvr_fog_table_color(FOG_COLOR[3], FOG_COLOR[0], FOG_COLOR[1], FOG_COLOR[2]); +} + +void APIENTRY glFogf(GLenum pname, GLfloat param) { + switch(pname) { + case GL_FOG_MODE: { + FOG_MODE = (GLenum) param; + updatePVRFog(); + } break; + case GL_FOG_DENSITY: { + FOG_DENSITY = param; + updatePVRFog(); + } break; + case GL_FOG_START: { + FOG_START = param; + updatePVRFog(); + } break; + case GL_FOG_END: { + FOG_END = param; + updatePVRFog(); + } break; + case GL_FOG_INDEX: + default: { + _glKosThrowError(GL_INVALID_ENUM, __func__); + _glKosPrintError(); + } + } +} + +void APIENTRY glFogi(GLenum pname, GLint param) { + glFogf(pname, (GLfloat) param); +} + +void APIENTRY glFogfv(GLenum pname, const GLfloat* params) { + if(pname == GL_FOG_COLOR) { + FOG_COLOR[0] = params[0]; + FOG_COLOR[1] = params[1]; + FOG_COLOR[2] = params[2]; + FOG_COLOR[3] = params[3]; + updatePVRFog(); + } else { + glFogf(pname, *params); + } +} + +void APIENTRY glFogiv(GLenum pname, const GLint* params) { + if(pname == GL_FOG_COLOR) { + FOG_COLOR[0] = ((GLfloat) params[0]) / (GLfloat) INT_MAX; + FOG_COLOR[1] = ((GLfloat) params[1]) / (GLfloat) INT_MAX; + FOG_COLOR[2] = ((GLfloat) params[2]) / (GLfloat) INT_MAX; + FOG_COLOR[3] = ((GLfloat) params[3]) / (GLfloat) INT_MAX; + updatePVRFog(); + } else { + glFogi(pname, *params); + } +} diff --git a/GL/framebuffer.c b/GL/framebuffer.c index e69de29..d699fab 100644 --- a/GL/framebuffer.c +++ b/GL/framebuffer.c @@ -0,0 +1,33 @@ +#include "private.h" + +static GLuint ACTIVE_FRAMEBUFFER = 0; +static NamedArray FRAMEBUFFERS; + + +void APIENTRY glGenFramebuffersEXT(GLsizei n, GLuint* framebuffers) { + +} + +void APIENTRY glDeleteFramebuffersEXT(GLsizei n, const GLuint* framebuffers) { + +} + +void APIENTRY glBindFramebufferEXT(GLenum target, GLuint framebuffer) { + +} + +void APIENTRY glFramebufferTexture2DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) { + +} + +void APIENTRY glGenerateMipmapEXT(GLenum target) { + +} + +GLenum APIENTRY glCheckFramebufferStatusEXT(GLenum target) { + +} + +GLboolean APIENTRY glIsFramebufferEXT(GLuint framebuffer) { + +} diff --git a/GL/immediate.c b/GL/immediate.c index ab29025..39d28bc 100644 --- a/GL/immediate.c +++ b/GL/immediate.c @@ -60,6 +60,15 @@ void APIENTRY glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) { COLOR[3] = a; } +void APIENTRY glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a) { + glColor4f( + ((GLfloat) r) / 255.0f, + ((GLfloat) g) / 255.0f, + ((GLfloat) b) / 255.0f, + ((GLfloat) a) / 255.0f + ); +} + void APIENTRY glColor4fv(const GLfloat* v) { glColor4f(v[0], v[1], v[2], v[3]); } @@ -145,3 +154,29 @@ void APIENTRY glEnd() { /* FIXME: Pop pointers */ } + +void APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) { + glBegin(GL_QUADS); + glVertex2f(x1, y1); + glVertex2f(x2, y1); + glVertex2f(x2, y2); + glVertex2f(x1, y2); + glEnd(); +} + +void APIENTRY glRectfv(const GLfloat *v1, const GLfloat *v2) { + glBegin(GL_QUADS); + glVertex2f(v1[0], v1[1]); + glVertex2f(v2[0], v1[1]); + glVertex2f(v2[0], v2[1]); + glVertex2f(v1[0], v2[1]); + glEnd(); +} + +void APIENTRY glRecti(GLint x1, GLint y1, GLint x2, GLint y2) { + return glRectf((GLfloat)x1, (GLfloat)y1, (GLfloat)x2, (GLfloat)y2); +} + +void APIENTRY glRectiv(const GLint *v1, const GLint *v2) { + return glRectfv((const GLfloat *)v1, (const GLfloat *)v2); +} diff --git a/GL/matrix.c b/GL/matrix.c index 0c36219..e200e7e 100644 --- a/GL/matrix.c +++ b/GL/matrix.c @@ -2,7 +2,8 @@ #include "../include/gl.h" #include "../containers/stack.h" -#include "../gl-sh4.h" + +#define DEG2RAD (0.01745329251994329576923690768489) /* Viewport mapping */ static GLfloat gl_viewport_scale[3], gl_viewport_offset[3]; @@ -320,26 +321,28 @@ void APIENTRY glDepthRange(GLclampf n, GLclampf f) { } /* Vector Cross Product - Used by glhLookAtf2 */ -static inline void vec3f_cross(vector3f v1, vector3f v2, vector3f result) { +static inline void vec3f_cross(const GLfloat* v1, const GLfloat* v2, GLfloat* result) { result[0] = v1[1] * v2[2] - v1[2] * v2[1]; result[1] = v1[2] * v2[0] - v1[0] * v2[2]; result[2] = v1[0] * v2[1] - v1[1] * v2[0]; } /* glhLookAtf2 adapted from http://www.opengl.org/wiki/GluLookAt_code */ -void glhLookAtf2(vector3f eyePosition3D, - vector3f center3D, - vector3f upVector3D) { +void glhLookAtf2(const GLfloat* eyePosition3D, + const GLfloat* center3D, + const GLfloat* upVector3D) { /* Look-At Matrix */ - static matrix4f MatrixLookAt __attribute__((aligned(32))) = { + static matrix_t MatrixLookAt __attribute__((aligned(32))) = { { 1.0f, 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 0.0f, 1.0f } }; - vector3f forward, side, up; + GLfloat forward[3]; + GLfloat side[3]; + GLfloat up[3]; vec3f_sub_normalize(center3D[0], center3D[1], center3D[2], eyePosition3D[0], eyePosition3D[1], eyePosition3D[2], @@ -383,9 +386,9 @@ void glhLookAtf2(vector3f eyePosition3D, void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx, GLfloat centery, GLfloat centerz, GLfloat upx, GLfloat upy, GLfloat upz) { - vector3f eye = { eyex, eyey, eyez }; - vector3f point = { centerx, centery, centerz }; - vector3f up = { upx, upy, upz }; + GLfloat eye [] = { eyex, eyey, eyez }; + GLfloat point [] = { centerx, centery, centerz }; + GLfloat up [] = { upx, upy, upz }; glhLookAtf2(eye, point, up); } diff --git a/GL/private.h b/GL/private.h index b64c192..811c40f 100644 --- a/GL/private.h +++ b/GL/private.h @@ -2,7 +2,6 @@ #define PRIVATE_H #include "../include/gl.h" -#include "../gl-api.h" #include "../containers/aligned_vector.h" #include "../containers/named_array.h" @@ -91,6 +90,10 @@ GLboolean isLightingEnabled(); GLboolean isLightEnabled(GLubyte light); void calculateLightingContribution(const GLint light, const GLfloat* pos, const GLfloat* normal, GLfloat* colour); +void _glKosThrowError(GLenum error, const char *function); +void _glKosPrintError(); +GLubyte _glKosHasError(); + #define PVR_VERTEX_BUF_SIZE 2560 * 256 #define MAX_TEXTURE_UNITS 2 #define MAX_LIGHTS 8 diff --git a/GL/state.c b/GL/state.c index 044b3d8..da3a313 100644 --- a/GL/state.c +++ b/GL/state.c @@ -6,7 +6,6 @@ #include #include "../include/gl.h" -#include "../gl-api.h" #include "private.h" static pvr_poly_cxt_t GL_CONTEXT; @@ -310,9 +309,11 @@ GLAPI void APIENTRY glDepthFunc(GLenum func) { /* Hints */ /* Currently Supported Capabilities: - GL_PERSPECTIVE_CORRECTION_HINT - This will Enable Texture Super-Sampling on the PVR */ + GL_PERSPECTIVE_CORRECTION_HINT - This will Enable on the PVR */ GLAPI void APIENTRY glHint(GLenum target, GLenum mode) { - + if(target == GL_PERSPECTIVE_CORRECTION_HINT && mode == GL_NICEST) { + // FIXME: enable supersampling + } } /* Culling */ diff --git a/GL/texture.c b/GL/texture.c index 252170c..4b6a7f3 100644 --- a/GL/texture.c +++ b/GL/texture.c @@ -454,7 +454,8 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, _glKosThrowError(GL_INVALID_VALUE, "glTexImage2D"); } - if(level < 0) { + /* FIXME: Mipmaps! */ + if(level < 0 || level > 0) { _glKosThrowError(GL_INVALID_VALUE, "glTexImage2D"); } @@ -486,9 +487,9 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, pvr_mem_free(active->data); active->data = NULL; } - } + } - GLuint bytes = level ? glKosMipMapTexSize(width, height) : (width * height * 2); + GLuint bytes = (width * height * sizeof(GLushort)); if(!active->data) { /* need texture memory */ diff --git a/Makefile b/Makefile index f2711c1..01c2c31 100644 --- a/Makefile +++ b/Makefile @@ -6,11 +6,8 @@ # Copyright (C) 2018 Luke Benstead TARGET = libGL.a -OBJS = gl-rgb.o gl-fog.o gl-sh4-light.o gl-light.o gl-clip.o gl-clip-arrays.o -OBJS += gl-pvr.o gl-matrix.o gl-api.o glu-texture.o -OBJS += gl-framebuffer.o gl-error.o -OBJS += GL/draw.o GL/flush.o GL/framebuffer.o GL/immediate.o GL/lighting.o GL/state.o GL/texture.o -OBJS += GL/matrix.o +OBJS = GL/draw.o GL/flush.o GL/framebuffer.o GL/immediate.o GL/lighting.o GL/state.o GL/texture.o +OBJS += GL/matrix.o GL/fog.o GL/error.o SUBDIRS = diff --git a/gl-api.c b/gl-api.c deleted file mode 100644 index a62e717..0000000 --- a/gl-api.c +++ /dev/null @@ -1,663 +0,0 @@ -/* KallistiGL for KallistiOS ##version## - - libgl/gl-api.c - Copyright (C) 2013-2014 Josh Pearson - Copyright (C) 2014 Lawrence Sebald - - Some functionality adapted from the original KOS libgl: - Copyright (C) 2001 Dan Potter - Copyright (C) 2002 Benoit Miller - - This API implements much but not all of the OpenGL 1.1 for KallistiOS. -*/ - -#include -#include -#include - -#include "gl.h" -#include "glu.h" -#include "gl-api.h" -#include "gl-sh4.h" -#include "gl-pvr.h" - -//====================================================================================================// -//== Local API State Macine Variables ==// - -static GLubyte GL_KOS_DEPTH_FUNC = PVR_DEPTHCMP_GEQUAL; -static GLubyte GL_KOS_DEPTH_WRITE = PVR_DEPTHWRITE_ENABLE; -static GLubyte GL_KOS_BLEND_FUNC = (PVR_BLEND_ONE << 4) | (PVR_BLEND_ZERO & 0x0F); -static GLubyte GL_KOS_SHADE_FUNC = PVR_SHADE_GOURAUD; -static GLushort GL_KOS_CULL_FUNC = PVR_CULLING_NONE; -static GLushort GL_KOS_FACE_FRONT = GL_CCW; -static GLubyte GL_KOS_SUPERSAMPLE = 0; - -static GLuint GL_KOS_VERTEX_COUNT = 0; -static GLuint GL_KOS_VERTEX_MODE = GL_TRIANGLES; -static GLuint GL_KOS_VERTEX_COLOR = 0xFFFFFFFF; -static GLfloat GL_KOS_VERTEX_UV[2] = { 0, 0 }; -//static glTexCoord4f GL_KOS_VERTEX_TEX_COORD = { 0, 0, 0, 1 }; - -static GLfloat GL_KOS_COLOR_CLEAR[3] = { 0, 0, 0 }; - -static GLfloat GL_KOS_POINT_SIZE = 0.02; - -static pvr_poly_cxt_t GL_KOS_POLY_CXT; - -static inline void _glKosFlagsSetTriangleStrip(); -static inline void _glKosFlagsSetTriangle(); -static inline void _glKosFlagsSetQuad(); -static inline void _glKosFinishRect(); - -//====================================================================================================// -//== API Initialization ==// - -//void APIENTRY glKosInit() { -// _glKosInitPVR(); - -// _glKosInitTextures(); - -// _glKosInitMatrix(); - -// _glKosInitLighting(); - -// _glKosInitFrameBuffers(); -//} - -//====================================================================================================// -//== Blending / Shading functions ==// - -//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; -// } -//} - -//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; - -// 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_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_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_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; -// } - -// 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_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_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_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_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 glClearColor(float r, float g, float b, float a) { -// if(r > 1) r = 1; - -// if(g > 1) g = 1; - -// if(b > 1) b = 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; -//} - -//== NoOp ==// -//void APIENTRY glClearDepthf(GLfloat depth) { -// ; -//} - -//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_GREATER: -// GL_KOS_DEPTH_FUNC = PVR_DEPTHCMP_LEQUAL; -// break; - -// case GL_GEQUAL: -// GL_KOS_DEPTH_FUNC = PVR_DEPTHCMP_LESS; -// break; - -// 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; -//} - -//====================================================================================================// -//== Culling functions ==// - -//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; -// } -//} - -//====================================================================================================// -//== Vertex Attributes Submission Functions ==// - -//== Vertex Color Submission ==// - -void APIENTRY glColor1ui(GLuint argb) { - GL_KOS_VERTEX_COLOR = argb; -} - -void APIENTRY glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a) { - GL_KOS_VERTEX_COLOR = a << 24 | r << 16 | g << 8 | b; -} - - -//== Vertex Position Submission Functions ==// - -void APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) { - pvr_vertex_t *v = _glKosVertexBufPointer(); - - v[0].z = v[3].z = 0; - - mat_trans_single3_nomod(x1, y1, v[0].z, v[0].x, v[0].y, v[0].z); - mat_trans_single3_nomod(x2, y2, v[3].z, v[3].x, v[3].y, v[3].z); - - _glKosFinishRect(); -} - -void APIENTRY glRectfv(const GLfloat *v1, const GLfloat *v2) { - pvr_vertex_t *v = _glKosVertexBufPointer(); - - v[0].z = v[3].z = 0; - - mat_trans_single3_nomod(v1[0], v1[1], v[0].z, v[0].x, v[0].y, v[0].z); - mat_trans_single3_nomod(v2[0], v2[1], v[3].z, v[3].x, v[3].y, v[3].z); - - _glKosFinishRect(); -} - -void APIENTRY glRecti(GLint x1, GLint y1, GLint x2, GLint y2) { - return glRectf((GLfloat)x1, (GLfloat)y1, (GLfloat)x2, (GLfloat)y2); -} - -void APIENTRY glRectiv(const GLint *v1, const GLint *v2) { - return glRectfv((const GLfloat *)v1, (const GLfloat *)v2); -} - -//====================================================================================================// -//== GL Begin / End ==// - -//====================================================================================================// -//== Misc. functions ==// - -/* Clamp X to [MIN,MAX]: */ - - -//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 ==// - -void _glKosVertex3fs(GLfloat x, GLfloat y, GLfloat z) { - pvr_vertex_t *v = _glKosVertexBufPointer(); - - mat_trans_single3_nomod(x, y, z, v->x, v->y, v->z); - - v->u = GL_KOS_VERTEX_UV[0]; - v->v = GL_KOS_VERTEX_UV[1]; - - _glKosVertexBufIncrement(); - - ++GL_KOS_VERTEX_COUNT; -} - -void _glKosVertex3fsv(const GLfloat *xyz) { - pvr_vertex_t *v = _glKosVertexBufPointer(); - - mat_trans_single3_nomod(xyz[0], xyz[1], xyz[2], v->x, v->y, v->z); - - v->u = GL_KOS_VERTEX_UV[0]; - v->v = GL_KOS_VERTEX_UV[1]; - - _glKosVertexBufIncrement(); - - ++GL_KOS_VERTEX_COUNT; -} - -void _glKosVertex3ft(GLfloat x, GLfloat y, GLfloat z) { - pvr_vertex_t *v = _glKosVertexBufPointer(); - - mat_trans_single3_nomod(x, y, z, v->x, v->y, v->z); - - v->u = GL_KOS_VERTEX_UV[0]; - v->v = GL_KOS_VERTEX_UV[1]; - v->argb = GL_KOS_VERTEX_COLOR; - - _glKosVertexBufIncrement(); - - ++GL_KOS_VERTEX_COUNT; -} - -void _glKosVertex3ftv(const GLfloat *xyz) { - pvr_vertex_t *v = _glKosVertexBufPointer(); - - mat_trans_single3_nomod(xyz[0], xyz[1], xyz[2], v->x, v->y, v->z); - - v->u = GL_KOS_VERTEX_UV[0]; - v->v = GL_KOS_VERTEX_UV[1]; - v->argb = GL_KOS_VERTEX_COLOR; - - _glKosVertexBufIncrement(); - - ++GL_KOS_VERTEX_COUNT; -} - -void _glKosVertex3fc(GLfloat x, GLfloat y, GLfloat z) { - pvr_vertex_t *v = _glKosClipBufPointer(); - - v->x = x; - v->y = y; - v->z = z; - v->u = GL_KOS_VERTEX_UV[0]; - v->v = GL_KOS_VERTEX_UV[1]; - v->argb = GL_KOS_VERTEX_COLOR; - - _glKosClipBufIncrement(); - - ++GL_KOS_VERTEX_COUNT; -} - -void _glKosVertex3fcv(const GLfloat *xyz) { - pvr_vertex_t *v = _glKosClipBufPointer(); - - v->x = xyz[0]; - v->y = xyz[1]; - v->z = xyz[2]; - v->u = GL_KOS_VERTEX_UV[0]; - v->v = GL_KOS_VERTEX_UV[1]; - v->argb = GL_KOS_VERTEX_COLOR; - - _glKosClipBufIncrement(); - - ++GL_KOS_VERTEX_COUNT; -} - -/* GL_POINTS */ -GLvoid _glKosVertex3fp(GLfloat x, GLfloat y, GLfloat z) { - pvr_vertex_t *v = _glKosVertexBufPointer(); - - mat_trans_single3_nomod(x - GL_KOS_POINT_SIZE, y + GL_KOS_POINT_SIZE, z, - v[0].x, v[0].y, v[0].z); - mat_trans_single3_nomod(x + GL_KOS_POINT_SIZE, y - GL_KOS_POINT_SIZE, z, - v[3].x, v[3].y, v[3].z); - - _glKosFinishRect(); -} - -GLvoid _glKosVertex3fpv(const GLfloat *xyz) { - pvr_vertex_t *v = _glKosVertexBufPointer(); - - mat_trans_single3_nomod(xyz[0] - GL_KOS_POINT_SIZE, xyz[1] + GL_KOS_POINT_SIZE, xyz[2], - v[0].x, v[0].y, v[0].z); - mat_trans_single3_nomod(xyz[0] + GL_KOS_POINT_SIZE, xyz[1] - GL_KOS_POINT_SIZE, xyz[2], - v[3].x, v[3].y, v[3].z); - - _glKosFinishRect(); -} - -static inline void _glKosFinishRect() { - pvr_vertex_t *v = _glKosVertexBufPointer(); - - v[0].argb = v[1].argb = v[2].argb = v[3].argb = GL_KOS_VERTEX_COLOR; - - v[0].flags = v[1].flags = v[2].flags = PVR_CMD_VERTEX; - v[3].flags = PVR_CMD_VERTEX_EOL; - - v[1].x = v[0].x; - v[1].y = v[3].y; - v[1].z = v[3].z; - - v[2].x = v[3].x; - v[2].y = v[0].y; - v[2].z = v[0].z; - - _glKosVertexBufAdd(4); - - GL_KOS_VERTEX_COUNT += 4; -} - -void _glKosTransformClipBuf(pvr_vertex_t *v, GLuint verts) { - register float __x __asm__("fr12"); - register float __y __asm__("fr13"); - register float __z __asm__("fr14"); - - while(verts--) { - __x = v->x; - __y = v->y; - __z = v->z; - - mat_trans_fv12(); - - v->x = __x; - v->y = __y; - v->z = __z; - ++v; - } -} - -static inline void _glKosVertexSwap(pvr_vertex_t *v1, pvr_vertex_t *v2) { - pvr_vertex_t tmp = *v1; - *v1 = *v2; - *v2 = * &tmp; -} - -static inline void _glKosFlagsSetQuad() { - pvr_vertex_t *v = (pvr_vertex_t *)_glKosVertexBufPointer() - GL_KOS_VERTEX_COUNT; - GLuint i; - - for(i = 0; i < GL_KOS_VERTEX_COUNT; i += 4) { - _glKosVertexSwap(v + 2, v + 3); - v->flags = (v + 1)->flags = (v + 2)->flags = PVR_CMD_VERTEX; - (v + 3)->flags = PVR_CMD_VERTEX_EOL; - v += 4; - } -} - -static inline void _glKosFlagsSetTriangle() { - pvr_vertex_t *v = (pvr_vertex_t *)_glKosVertexBufPointer() - GL_KOS_VERTEX_COUNT; - GLuint i; - - for(i = 0; i < GL_KOS_VERTEX_COUNT; i += 3) { - v->flags = (v + 1)->flags = PVR_CMD_VERTEX; - (v + 2)->flags = PVR_CMD_VERTEX_EOL; - v += 3; - } -} - -static inline void _glKosFlagsSetTriangleStrip() { - pvr_vertex_t *v = (pvr_vertex_t *)_glKosVertexBufPointer() - GL_KOS_VERTEX_COUNT; - GLuint i; - - for(i = 0; i < GL_KOS_VERTEX_COUNT - 1; i++) { - v->flags = PVR_CMD_VERTEX; - v++; - } - - v->flags = PVR_CMD_VERTEX_EOL; -} - -//====================================================================================================// -//== GL KOS PVR Header Parameter Compilation Functions ==// - -static inline void _glKosApplyDepthFunc() { - if(_glKosEnabledDepthTest()) - GL_KOS_POLY_CXT.depth.comparison = GL_KOS_DEPTH_FUNC; - else - GL_KOS_POLY_CXT.depth.comparison = PVR_DEPTHCMP_ALWAYS; - - GL_KOS_POLY_CXT.depth.write = GL_KOS_DEPTH_WRITE; -} - -static inline void _glKosApplyScissorFunc() { - if(_glKosEnabledScissorTest()) - GL_KOS_POLY_CXT.gen.clip_mode = PVR_USERCLIP_INSIDE; -} - -static inline void _glKosApplyFogFunc() { - if(_glKosEnabledFog()) - GL_KOS_POLY_CXT.gen.fog_type = PVR_FOG_TABLE; -} - -static inline void _glKosApplyCullingFunc() { - if(_glKosEnabledCulling()) { - if(GL_KOS_CULL_FUNC == GL_BACK) { - if(GL_KOS_FACE_FRONT == GL_CW) - GL_KOS_POLY_CXT.gen.culling = PVR_CULLING_CCW; - else - GL_KOS_POLY_CXT.gen.culling = PVR_CULLING_CW; - } - else if(GL_KOS_CULL_FUNC == GL_FRONT) { - if(GL_KOS_FACE_FRONT == GL_CCW) - GL_KOS_POLY_CXT.gen.culling = PVR_CULLING_CCW; - else - GL_KOS_POLY_CXT.gen.culling = PVR_CULLING_CW; - } - } - else - GL_KOS_POLY_CXT.gen.culling = PVR_CULLING_NONE; -} - -static inline void _glKosApplyBlendFunc() { - if(_glKosEnabledBlend()) { - GL_KOS_POLY_CXT.blend.src = (GL_KOS_BLEND_FUNC & 0xF0) >> 4; - GL_KOS_POLY_CXT.blend.dst = (GL_KOS_BLEND_FUNC & 0x0F); - } -} - -void _glKosCompileHdr() { - pvr_poly_hdr_t *hdr = _glKosVertexBufPointer(); - - pvr_poly_cxt_col(&GL_KOS_POLY_CXT, _glKosList() * 2); - - GL_KOS_POLY_CXT.gen.shading = GL_KOS_SHADE_FUNC; - - _glKosApplyDepthFunc(); - - _glKosApplyScissorFunc(); - - _glKosApplyFogFunc(); - - _glKosApplyCullingFunc(); - - _glKosApplyBlendFunc(); - - pvr_poly_compile(hdr, &GL_KOS_POLY_CXT); - - _glKosVertexBufIncrement(); -} -//====================================================================================================// -//== Internal GL KOS API State Functions ==// - -GLuint _glKosBlendSrcFunc() { - switch((GL_KOS_BLEND_FUNC & 0xF0) >> 4) { - case PVR_BLEND_ONE: - return GL_ONE; - - case PVR_BLEND_ZERO: - return GL_ZERO; - - case PVR_BLEND_DESTCOLOR: - return GL_DST_COLOR; - - case PVR_BLEND_SRCALPHA: - return GL_SRC_ALPHA; - - case PVR_BLEND_DESTALPHA: - return GL_DST_ALPHA; - - case PVR_BLEND_INVSRCALPHA: - return GL_ONE_MINUS_SRC_ALPHA; - - case PVR_BLEND_INVDESTALPHA: - return GL_ONE_MINUS_DST_ALPHA; - - case PVR_BLEND_INVDESTCOLOR: - return GL_ONE_MINUS_DST_COLOR; - } - - return 0; -} - -GLuint _glKosBlendDstFunc() { - switch(GL_KOS_BLEND_FUNC & 0xF) { - case PVR_BLEND_ONE: - return GL_ONE; - - case PVR_BLEND_ZERO: - return GL_ZERO; - - case PVR_BLEND_DESTCOLOR: - return GL_DST_COLOR; - - case PVR_BLEND_SRCALPHA: - return GL_SRC_ALPHA; - - case PVR_BLEND_DESTALPHA: - return GL_DST_ALPHA; - - case PVR_BLEND_INVSRCALPHA: - return GL_ONE_MINUS_SRC_ALPHA; - - case PVR_BLEND_INVDESTALPHA: - return GL_ONE_MINUS_DST_ALPHA; - - case PVR_BLEND_INVDESTCOLOR: - return GL_ONE_MINUS_DST_COLOR; - } - - return 0; -} - -GLubyte _glKosCullFaceMode() { - return GL_KOS_CULL_FUNC; -} - -GLubyte _glKosCullFaceFront() { - return GL_KOS_FACE_FRONT; -} - -GLuint _glKosDepthFunc() { - switch(GL_KOS_DEPTH_FUNC) { - case PVR_DEPTHCMP_GEQUAL: - return GL_LESS; - - case PVR_DEPTHCMP_GREATER: - return GL_LEQUAL; - - case PVR_DEPTHCMP_LEQUAL: - return GL_GREATER; - - case PVR_DEPTHCMP_LESS: - return GL_GEQUAL; - - default: - return GL_NEVER + GL_KOS_DEPTH_FUNC; - } -} - -GLubyte _glKosDepthMask() { - return (GL_KOS_DEPTH_WRITE == PVR_DEPTHWRITE_ENABLE) ? GL_TRUE : GL_FALSE; -} - -GLuint _glKosVertexColor() { - return GL_KOS_VERTEX_COLOR; -} - diff --git a/gl-api.h b/gl-api.h deleted file mode 100644 index 2cf9ae9..0000000 --- a/gl-api.h +++ /dev/null @@ -1,206 +0,0 @@ -/* KallistiGL for KallistiOS ##version## - - libgl/gl-api.h - Copyright (C) 2013-2014 Josh Pearson - - The functions defined in this header are for internal use by the API, - and not for use externally. -*/ - -#ifndef GL_API_H -#define GL_API_H - -#include "gl.h" - -typedef struct { - GLfloat pos[3]; - GLfloat norm[3]; -} glVertex; /* Simple Vertex used for Dynamic Vertex Lighting */ - -typedef struct { - GLfloat u, v; -} glTexCoord; /* Simple Texture Coordinate used for Multi-Texturing */ - -typedef struct { - GLfloat s, t, r, q; -} glTexCoord4f; /* 3D Texture Coordinate */ - -typedef struct { - GLuint texID; - GLsizei index; - GLvoid *data; - GLvoid *link; -} GL_FRAMEBUFFER_OBJECT; /* KOS Open GL Frame Buffer Object */ - -typedef struct { - pvr_poly_hdr_t hdr; - pvr_vertex_t *src; - GLuint count; -} GL_MULTITEX_OBJECT; - -typedef GLushort uint16; -typedef GLubyte uint8; - -/* Vertex Main Buffer Internal Functions */ -void _glKosVertexBufSwitchOP(); -void _glKosVertexBufSwitchTR(); -void *_glKosVertexBufAddress(unsigned char list); -void *_glKosVertexBufPointer(); -void *_glKosTRVertexBufPointer(); -void _glKosVertexBufIncrement(); -void _glKosTRVertexBufIncrement(); -void _glKosVertexBufAdd(unsigned int count); -void _glKosTRVertexBufAdd(unsigned int count); -void _glKosVertexBufDecrement(); -void _glKosVertexBufReset(); -unsigned int _glKosVertexBufCount(unsigned char list); -unsigned char _glKosList(); -void _glKosVertexBufCopy(void *src, void *dst, GLuint count); -void _glKosResetEnabledTex(); -void *_glKosMultiUVBufAddress(); -void *_glKosMultiUVBufPointer(); -void _glKosMultiUVBufIncrement(); -void _glKosMultiUVBufAdd(GLuint count); -void _glKosMultiUVBufReset(); - -/* Vertex Clip Buffer Internal Functions */ -void *_glKosClipBufAddress(); -void *_glKosClipBufPointer(); -void _glKosClipBufIncrement(); -void _glKosClipBufReset(); - -/* Vertex Array Buffer Internal Functions */ -void _glKosArrayBufIncrement(); -void _glKosArrayBufReset(); -glVertex *_glKosArrayBufAddr(); -glVertex *_glKosArrayBufPtr(); - -/* Initialize the OpenGL PVR Pipeline */ -int _glKosInitPVR(); -unsigned char _glKosInitTextures(); - -/* Compile the current Polygon Header for the PVR */ -void _glKosCompileHdr(); -void _glKosCompileHdrTx(); -void _glKosCompileHdrMTx(); - -/* Clipping Internal Functions */ -void _glKosTransformClipBuf(pvr_vertex_t *v, GLuint verts); -unsigned int _glKosClipTriangleStrip(pvr_vertex_t *vin, pvr_vertex_t *vout, unsigned int vertices); -unsigned int _glKosClipTriangles(pvr_vertex_t *vin, pvr_vertex_t *vout, unsigned int vertices); -unsigned int _glKosClipQuads(pvr_vertex_t *vin, pvr_vertex_t *vout, unsigned int vertices); - -unsigned int _glKosClipTrianglesTransformed(pvr_vertex_t *src, float *w, pvr_vertex_t *dst, GLuint count); -unsigned int _glKosClipQuadsTransformed(pvr_vertex_t *vin, float *w, pvr_vertex_t *vout, unsigned int vertices); -unsigned int _glKosClipTriangleStripTransformed(pvr_vertex_t *src, float *w, pvr_vertex_t *dst, GLuint count); - -unsigned int _glKosClipTrianglesTransformedMT(pvr_vertex_t *src, float *w, pvr_vertex_t *dst, - GLfloat *uvsrc, glTexCoord *uvdst, GLuint uv_src_stride, GLuint count); -unsigned int _glKosClipTriangleStripTransformedMT(pvr_vertex_t *src, float *w, pvr_vertex_t *dst, - GLfloat *uvsrc, glTexCoord *uvdst, GLuint uv_src_stride, GLuint count); -unsigned int _glKosClipQuadsTransformedMT(pvr_vertex_t *src, float *w, pvr_vertex_t *dst, - GLfloat *uvsrc, glTexCoord *uvdst, GLuint uv_src_stride, GLuint count); - - -/* Lighting Internal Functions */ -void _glKosInitLighting(); -void _glKosEnableLight(const GLuint light); -void _glKosDisableLight(const GLuint light); -void _glKosSetEyePosition(GLfloat *position); -void _glKosVertexComputeLighting(pvr_vertex_t *v, int verts); -void _glKosVertexLight(glVertex *P, pvr_vertex_t *v); -unsigned int _glKosVertexLightColor(glVertex *P); -void _glKosVertexLights(glVertex *P, pvr_vertex_t *v, GLuint count); - -/* Vertex Position Submission Internal Functions */ -void _glKosVertex3ft(GLfloat x, GLfloat y, GLfloat z); -void _glKosVertex3ftv(const GLfloat *xyz); -void _glKosVertex3fc(GLfloat x, GLfloat y, GLfloat z); -void _glKosVertex3fcv(const GLfloat *xyz); -void _glKosVertex3fp(GLfloat x, GLfloat y, GLfloat z); -void _glKosVertex3fpv(const GLfloat *xyz); -void _glKosVertex3fl(GLfloat x, GLfloat y, GLfloat z); -void _glKosVertex3flv(const GLfloat *xyz); -void _glKosVertex3flc(GLfloat x, GLfloat y, GLfloat z); -void _glKosVertex3flcv(const GLfloat *xyz); -void _glKosVertex3fs(GLfloat x, GLfloat y, GLfloat z); -void _glKosVertex3fsv(const GLfloat *xyz); - -/* Matrix Internal Functions */ -void _glKosInitMatrix(); -void _glKosMatrixLoadModelView(); -void _glKosMatrixLoadModelRot(); -void _glKosMatrixApplyScreenSpace(); -void _glKosMatrixApplyRender(); -void _glKosMatrixLoadRender(); -void _glKosMatrixLoadTexture(); - -/* API Enabled Capabilities Internal Functions */ -GLubyte _glKosEnabledBlend(); -GLubyte _glKosEnabledTexture2D(); -GLubyte _glKosEnabledNearZClip(); -GLubyte _glKosEnabledLighting(); -GLubyte _glKosEnabledFog(); -GLubyte _glKosEnabledCulling(); -GLubyte _glKosEnabledScissorTest(); -GLubyte _glKosEnabledDepthTest(); - -/* RGB Pixel Colorspace Internal Functions */ -uint16 __glKosAverageQuadPixelRGB565(uint16 p1, uint16 p2, uint16 p3, uint16 p4); -uint16 __glKosAverageQuadPixelARGB1555(uint16 p1, uint16 p2, uint16 p3, uint16 p4); -uint16 __glKosAverageQuadPixelARGB4444(uint16 p1, uint16 p2, uint16 p3, uint16 p4); -uint16 __glKosAverageBiPixelRGB565(uint16 p1, uint16 p2); -uint16 __glKosAverageBiPixelARGB1555(uint16 p1, uint16 p2); -uint16 __glKosAverageBiPixelARGB4444(uint16 p1, uint16 p2); - -/* Render-To-Texture Functions */ -void _glKosInitFrameBuffers(); - -/* Error Codes */ -void _glKosThrowError(GLenum error, const char *functionName); -void _glKosPrintError(); -GLubyte _glKosHasError(); - -GLuint _glKosTextureWidth(GLuint index); -GLuint _glKosTextureHeight(GLuint index); -GLvoid *_glKosTextureData(GLuint index); - -/* Frame Buffer Object Internal Functions */ -GLsizei _glKosGetFBO(); -GLuint _glKosGetFBOWidth(GLsizei fbi); -GLuint _glKosGetFBOHeight(GLsizei fbi); -GLvoid *_glKosGetFBOData(GLsizei fbi); - -/* Internal State Cap Accessors */ -GLubyte _glKosEnabledDepthTest(); -GLubyte _glKosEnabledScissorTest(); -GLubyte _glKosEnabledCulling(); -GLubyte _glKosEnabledFog(); -GLubyte _glKosEnabledLighting(); -GLubyte _glKosEnabledNearZClip(); -GLubyte _glKosEnabledTexture2D(); -GLubyte _glKosEnabledBlend(); -GLuint _glKosBlendSrcFunc(); -GLuint _glKosBlendDstFunc(); -GLubyte _glKosCullFaceMode(); -GLubyte _glKosCullFaceFront(); -GLuint _glKosDepthFunc(); -GLubyte _glKosDepthMask(); -GLubyte _glKosIsLightEnabled(GLubyte light); -GLubyte _glKosGetMaxLights(); -GLuint _glKosBoundTexID(); -GLuint _glKosVertexColor(); -GLubyte _glKosMaxTextureUnits(); -GLubyte _glKosEnabledTextureMatrix(); - -GLuint _glKosActiveTextureBoundTexID(); - -static inline void _glKosVertexCopyPVR(const pvr_vertex_t *src, pvr_vertex_t *dst) { - *dst = *src; -} - -static inline void _glKosTexCoordCopy(const glTexCoord *src, glTexCoord *dst) { - *dst = *src; -} - -#endif diff --git a/gl-clip-arrays.c b/gl-clip-arrays.c deleted file mode 100644 index 8471664..0000000 --- a/gl-clip-arrays.c +++ /dev/null @@ -1,418 +0,0 @@ -/* KallistiGL for KallistiOS ##version## - - libgl/gl-clip.c - Copyright (C) 2013-2014 Josh Pearson - - Near-Z Clipping Algorithm (C) 2013-2014 Josh PH3NOM Pearson - Input Primitive Types Supported: - -GL_TRIANGLES - -GL_TRIANGLE_STRIPS - -GL_QUADS - Outputs a mix of Triangles and Triangle Strips for use with the PVR -*/ - -#include -#include - -#include "gl.h" -#include "gl-api.h" -#include "gl-clip.h" - - -static inline void _glKosVertexClipZNear2(pvr_vertex_t *v1, pvr_vertex_t *v2, - GLfloat *w1, GLfloat *w2, - glTexCoord *uva, glTexCoord *uvb) { - GLfloat MAG = ((CLIP_NEARZ - v1->z) / (v2->z - v1->z)); - - colorui *c1 = (colorui *)&v1->argb; /* GLubyte Color Component Pointer */ - colorui *c2 = (colorui *)&v2->argb; - - v1->x += (v2->x - v1->x) * MAG; /* Clip Vertex X, Y, Z Components */ - v1->y += (v2->y - v1->y) * MAG; - v1->z += (v2->z - v1->z) * MAG; - v1->u += (v2->u - v1->u) * MAG; /* Clip Vertex Texture Coordinates */ - v1->v += (v2->v - v1->v) * MAG; - c1->a += (c2->a - c1->a) * MAG; /* Clip Vertex Color per ARGB component */ - c1->r += (c2->r - c1->r) * MAG; - c1->g += (c2->g - c1->g) * MAG; - c1->b += (c2->b - c1->b) * MAG; - - *w1 += (*w2 - *w1) * MAG; /* Clip Vertex W Component */ - - uva->u += (uvb->u - uva->u) * MAG; /* Clip Vertex Multi-Texture Coordinates */ - uva->v += (uvb->v - uva->v) * MAG; -} - -static inline void _glKosVertexClipZNear3(pvr_vertex_t *v1, pvr_vertex_t *v2, float *w1, float *w2) { - GLfloat MAG = ((CLIP_NEARZ - v1->z) / (v2->z - v1->z)); - - colorui *c1 = (colorui *)&v1->argb; - colorui *c2 = (colorui *)&v2->argb; - - v1->x += (v2->x - v1->x) * MAG; - v1->y += (v2->y - v1->y) * MAG; - v1->z += (v2->z - v1->z) * MAG; - v1->u += (v2->u - v1->u) * MAG; - v1->v += (v2->v - v1->v) * MAG; - c1->a += (c2->a - c1->a) * MAG; - c1->r += (c2->r - c1->r) * MAG; - c1->g += (c2->g - c1->g) * MAG; - c1->b += (c2->b - c1->b) * MAG; - - *w1 += (*w2 - *w1) * MAG; -} - -static inline void _glKosVertexPerspectiveDivide(pvr_vertex_t *dst, GLfloat w) { - dst->z = 1.0f / w; - dst->x *= dst->z; - dst->y *= dst->z; -} - -static inline GLubyte _glKosClipTriTransformed(pvr_vertex_t *src, GLfloat *w, pvr_vertex_t *dst) { - GLushort clip = 0; /* Clip Code for current Triangle */ - GLubyte verts_in = 0; /* # of Vertices inside clip plane for current Triangle */ - GLfloat W[4] = { w[0], w[1], w[2] }; /* W Component for Perspective Divide */ - - (src[0].z >= CLIP_NEARZ) ? clip |= FIRST : ++verts_in; - (src[1].z >= CLIP_NEARZ) ? clip |= SECOND : ++verts_in; - (src[2].z >= CLIP_NEARZ) ? clip |= THIRD : ++verts_in; - - switch(verts_in) { /* Start by examining # of vertices inside clip plane */ - case 0: /* All Vertices of Triangle are Outside of clip plne */ - return 0; - - case 3: /* All Vertices of Triangle are inside of clip plne */ - _glKosVertexCopyPVR(&src[0], &dst[0]); - _glKosVertexCopyPVR(&src[1], &dst[1]); - _glKosVertexCopyPVR(&src[2], &dst[2]); - - _glKosVertexPerspectiveDivide(&dst[0], W[0]); - _glKosVertexPerspectiveDivide(&dst[1], W[1]); - _glKosVertexPerspectiveDivide(&dst[2], W[2]); - - dst[0].flags = dst[1].flags = PVR_CMD_VERTEX; - dst[2].flags = PVR_CMD_VERTEX_EOL; - - return 3; - - case 1:/* 1 Vertex of Triangle is inside of clip plane = output 1 Triangle */ - _glKosVertexCopyPVR(&src[0], &dst[0]); - _glKosVertexCopyPVR(&src[1], &dst[1]); - _glKosVertexCopyPVR(&src[2], &dst[2]); - - switch(clip) { - case FIRST_TWO_OUT: - _glKosVertexClipZNear3(&dst[0], &dst[2], &W[0], &W[2]); - _glKosVertexClipZNear3(&dst[1], &dst[2], &W[1], &W[2]); - - break; - - case FIRST_AND_LAST_OUT: - _glKosVertexClipZNear3(&dst[0], &dst[1], &W[0], &W[1]); - _glKosVertexClipZNear3(&dst[2], &dst[1], &W[2], &W[1]); - - break; - - case LAST_TWO_OUT: - _glKosVertexClipZNear3(&dst[1], &dst[0], &W[1], &W[0]); - _glKosVertexClipZNear3(&dst[2], &dst[0], &W[2], &W[0]); - - break; - } - - _glKosVertexPerspectiveDivide(&dst[0], W[0]); - _glKosVertexPerspectiveDivide(&dst[1], W[1]); - _glKosVertexPerspectiveDivide(&dst[2], W[2]); - - dst[0].flags = dst[1].flags = PVR_CMD_VERTEX; - dst[2].flags = PVR_CMD_VERTEX_EOL; - - return 3; - - case 2:/* 2 Vertices of Triangle are inside of clip plane = output 2 Triangles */ - switch(clip) { - case FIRST: - _glKosVertexCopyPVR(&src[0], &dst[0]); - _glKosVertexCopyPVR(&src[1], &dst[1]); - _glKosVertexCopyPVR(&src[0], &dst[2]); - _glKosVertexCopyPVR(&src[2], &dst[3]); - W[3] = W[2]; - W[2] = W[0]; - - break; - - case SECOND: - _glKosVertexCopyPVR(&src[1], &dst[0]); - _glKosVertexCopyPVR(&src[2], &dst[1]); - _glKosVertexCopyPVR(&src[1], &dst[2]); - _glKosVertexCopyPVR(&src[0], &dst[3]); - W[3] = W[0]; - W[0] = W[1]; - W[1] = W[2]; - W[2] = W[0]; - - break; - - case THIRD: - _glKosVertexCopyPVR(&src[2], &dst[0]); - _glKosVertexCopyPVR(&src[0], &dst[1]); - _glKosVertexCopyPVR(&src[2], &dst[2]); - _glKosVertexCopyPVR(&src[1], &dst[3]); - W[3] = W[1]; - W[1] = W[0]; - W[0] = W[2]; - - break; - } - - _glKosVertexClipZNear3(&dst[0], &dst[1], &W[0], &W[1]); - _glKosVertexClipZNear3(&dst[2], &dst[3], &W[2], &W[3]); - - _glKosVertexPerspectiveDivide(&dst[0], W[0]); - _glKosVertexPerspectiveDivide(&dst[1], W[1]); - _glKosVertexPerspectiveDivide(&dst[2], W[2]); - _glKosVertexPerspectiveDivide(&dst[3], W[3]); - - dst[0].flags = dst[1].flags = dst[2].flags = PVR_CMD_VERTEX; - dst[3].flags = PVR_CMD_VERTEX_EOL; - - return 4; - } - - return 0; -} - -GLuint _glKosClipTrianglesTransformed(pvr_vertex_t *src, GLfloat *w, pvr_vertex_t *dst, GLuint count) { - GLuint verts_out = 0; - GLuint i; - - for(i = 0; i < count; i += 3) - verts_out += _glKosClipTriTransformed(&src[i], &w[i], &dst[verts_out]); - - return verts_out; -} - -GLuint _glKosClipTriangleStripTransformed(pvr_vertex_t *src, GLfloat *w, pvr_vertex_t *dst, GLuint count) { - GLuint verts_out = 0; - GLuint i; - - for(i = 0; i < (count - 2); i ++) - verts_out += _glKosClipTriTransformed(&src[i], &w[i], &dst[verts_out]); - - return verts_out; -} - -unsigned int _glKosClipQuadsTransformed(pvr_vertex_t *src, GLfloat *w, pvr_vertex_t *dst, GLuint count) { - GLuint i, verts_out = 0; - pvr_vertex_t qv[3]; - GLfloat W[3]; - - for(i = 0; i < count; i += 4) { /* Iterate all Quads, Rearranging into Triangle Strips */ - _glKosVertexCopyPVR(&src[i + 0], &qv[0]); - _glKosVertexCopyPVR(&src[i + 2], &qv[1]); - _glKosVertexCopyPVR(&src[i + 3], &qv[2]); - W[0] = w[0]; - W[1] = w[2]; - W[2] = w[3]; - - verts_out += _glKosClipTriTransformed(&src[i], &w[i], &dst[verts_out]); - verts_out += _glKosClipTriTransformed(qv, W, &dst[verts_out]); - } - - return verts_out; -} - -static inline GLubyte _glKosClipTriTransformedMT(pvr_vertex_t *src, float *w, pvr_vertex_t *dst, - GLfloat *uvsrc, glTexCoord *uvdst, GLuint uv_src_stride) { - GLushort clip = 0; /* Clip Code for current Triangle */ - GLubyte verts_in = 0; /* # of Vertices inside clip plane for current Triangle */ - GLfloat W[4] = { w[0], w[1], w[2] }; /* W Component for Perspective Divide */ - - (src[0].z >= CLIP_NEARZ) ? clip |= FIRST : ++verts_in; - (src[1].z >= CLIP_NEARZ) ? clip |= SECOND : ++verts_in; - (src[2].z >= CLIP_NEARZ) ? clip |= THIRD : ++verts_in; - - switch(verts_in) { /* Start by examining # of vertices inside clip plane */ - case 0: /* All Vertices of Triangle are Outside of clip plane */ - return 0; - - case 3: /* All Vertices of Triangle are Inside of clip plane */ - _glKosVertexCopyPVR(&src[0], &dst[0]); - _glKosVertexCopyPVR(&src[1], &dst[1]); - _glKosVertexCopyPVR(&src[2], &dst[2]); - - _glKosTexCoordCopy((glTexCoord *)&uvsrc[0], &uvdst[0]); - _glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride], &uvdst[1]); - _glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride + uv_src_stride], &uvdst[2]); - - _glKosVertexPerspectiveDivide(&dst[0], W[0]); - _glKosVertexPerspectiveDivide(&dst[1], W[1]); - _glKosVertexPerspectiveDivide(&dst[2], W[2]); - - dst[0].flags = dst[1].flags = PVR_CMD_VERTEX; - dst[2].flags = PVR_CMD_VERTEX_EOL; - - return 3; - - case 1:/* 1 Vertex of Triangle is Inside of clip plane = output 1 Triangle */ - _glKosVertexCopyPVR(&src[0], &dst[0]); - _glKosVertexCopyPVR(&src[1], &dst[1]); - _glKosVertexCopyPVR(&src[2], &dst[2]); - - _glKosTexCoordCopy((glTexCoord *)&uvsrc[0], &uvdst[0]); - _glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride], &uvdst[1]); - _glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride + uv_src_stride], &uvdst[2]); - - switch(clip) { - case FIRST_TWO_OUT: - _glKosVertexClipZNear2(&dst[0], &dst[2], &W[0], &W[2], &uvdst[0], &uvdst[2]); - _glKosVertexClipZNear2(&dst[1], &dst[2], &W[1], &W[2], &uvdst[1], &uvdst[2]); - - break; - - case FIRST_AND_LAST_OUT: - _glKosVertexClipZNear2(&dst[0], &dst[1], &W[0], &W[1], &uvdst[0], &uvdst[1]); - _glKosVertexClipZNear2(&dst[2], &dst[1], &W[2], &W[1], &uvdst[2], &uvdst[1]); - - break; - - case LAST_TWO_OUT: - _glKosVertexClipZNear2(&dst[1], &dst[0], &W[1], &W[0], &uvdst[1], &uvdst[0]); - _glKosVertexClipZNear2(&dst[2], &dst[0], &W[2], &W[0], &uvdst[2], &uvdst[0]); - - break; - } - - _glKosVertexPerspectiveDivide(&dst[0], W[0]); - _glKosVertexPerspectiveDivide(&dst[1], W[1]); - _glKosVertexPerspectiveDivide(&dst[2], W[2]); - - dst[0].flags = dst[1].flags = PVR_CMD_VERTEX; - dst[2].flags = PVR_CMD_VERTEX_EOL; - - return 3; - - case 2:/* 2 Vertices of Triangle are inside of clip plane = output 2 Triangles */ - switch(clip) { - case FIRST: - _glKosVertexCopyPVR(&src[0], &dst[0]); - _glKosVertexCopyPVR(&src[1], &dst[1]); - _glKosVertexCopyPVR(&src[0], &dst[2]); - _glKosVertexCopyPVR(&src[2], &dst[3]); - - _glKosTexCoordCopy((glTexCoord *)&uvsrc[0], &uvdst[0]); - _glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride], &uvdst[1]); - _glKosTexCoordCopy((glTexCoord *)&uvsrc[0], &uvdst[2]); - _glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride + uv_src_stride], &uvdst[3]); - - W[3] = W[2]; - W[2] = W[0]; - - break; - - case SECOND: - _glKosVertexCopyPVR(&src[1], &dst[0]); - _glKosVertexCopyPVR(&src[2], &dst[1]); - _glKosVertexCopyPVR(&src[1], &dst[2]); - _glKosVertexCopyPVR(&src[0], &dst[3]); - - _glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride], &uvdst[0]); - _glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride + uv_src_stride], &uvdst[1]); - _glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride], &uvdst[2]); - _glKosTexCoordCopy((glTexCoord *)&uvsrc[0], &uvdst[3]); - - W[3] = W[0]; - W[0] = W[1]; - W[1] = W[2]; - W[2] = W[0]; - - break; - - case THIRD: - _glKosVertexCopyPVR(&src[2], &dst[0]); - _glKosVertexCopyPVR(&src[0], &dst[1]); - _glKosVertexCopyPVR(&src[2], &dst[2]); - _glKosVertexCopyPVR(&src[1], &dst[3]); - - _glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride + uv_src_stride], &uvdst[0]); - _glKosTexCoordCopy((glTexCoord *)&uvsrc[0], &uvdst[1]); - _glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride + uv_src_stride], &uvdst[2]); - _glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride], &uvdst[3]); - - W[3] = W[1]; - W[1] = W[0]; - W[0] = W[2]; - - break; - } - - _glKosVertexClipZNear2(&dst[0], &dst[1], &W[0], &W[1], &uvdst[0], &uvdst[1]); - _glKosVertexClipZNear2(&dst[2], &dst[3], &W[2], &W[3], &uvdst[2], &uvdst[3]); - - _glKosVertexPerspectiveDivide(&dst[0], W[0]); - _glKosVertexPerspectiveDivide(&dst[1], W[1]); - _glKosVertexPerspectiveDivide(&dst[2], W[2]); - _glKosVertexPerspectiveDivide(&dst[3], W[3]); - - dst[0].flags = dst[1].flags = dst[2].flags = PVR_CMD_VERTEX; - dst[3].flags = PVR_CMD_VERTEX_EOL; - - return 4; - } - - return 0; -} - -GLuint _glKosClipTrianglesTransformedMT(pvr_vertex_t *src, float *w, pvr_vertex_t *dst, - GLfloat *uvsrc, glTexCoord *uvdst, GLuint uv_src_stride, - GLuint count) { - GLuint verts_out = 0; - GLuint i; - - for(i = 0; i < count; i += 3) - verts_out += _glKosClipTriTransformedMT(&src[i], &w[i], &dst[verts_out], - &uvsrc[i * uv_src_stride], &uvdst[verts_out], uv_src_stride); - - return verts_out; -} - -GLuint _glKosClipTriangleStripTransformedMT(pvr_vertex_t *src, float *w, pvr_vertex_t *dst, - GLfloat *uvsrc, glTexCoord *uvdst, GLuint uv_src_stride, GLuint count) { - GLuint verts_out = 0; - GLuint i; - - for(i = 0; i < (count - 2); i ++) - verts_out += _glKosClipTriTransformedMT(&src[i], &w[i], &dst[verts_out], - &uvsrc[i * uv_src_stride], &uvdst[verts_out], uv_src_stride); - - return verts_out; -} - -GLuint _glKosClipQuadsTransformedMT(pvr_vertex_t *src, float *w, pvr_vertex_t *dst, - GLfloat *uvsrc, glTexCoord *uvdst, GLuint uv_src_stride, GLuint count) { - GLuint i, verts_out = 0; - pvr_vertex_t qv[3]; - glTexCoord uv[3]; - GLfloat W[3]; - - for(i = 0; i < count; i += 4) { - _glKosVertexCopyPVR(&src[i + 0], &qv[0]); - _glKosVertexCopyPVR(&src[i + 2], &qv[1]); - _glKosVertexCopyPVR(&src[i + 3], &qv[2]); - - _glKosTexCoordCopy((glTexCoord *)&uvsrc[i * uv_src_stride], &uv[0]); - _glKosTexCoordCopy((glTexCoord *)&uvsrc[i * uv_src_stride + (uv_src_stride * 2)], &uv[1]); - _glKosTexCoordCopy((glTexCoord *)&uvsrc[i * uv_src_stride + (uv_src_stride * 3)], &uv[2]); - - W[0] = w[0]; - W[1] = w[2]; - W[2] = w[3]; - - verts_out += _glKosClipTriTransformedMT(&src[i], &w[i], &dst[verts_out], - &uvsrc[i * uv_src_stride], &uvdst[verts_out], uv_src_stride); - verts_out += _glKosClipTriTransformedMT(qv, W, &dst[verts_out], - (GLfloat *)uv, &uvdst[verts_out], 2); - } - - return verts_out; -} \ No newline at end of file diff --git a/gl-clip.c b/gl-clip.c deleted file mode 100644 index 31ac2a3..0000000 --- a/gl-clip.c +++ /dev/null @@ -1,310 +0,0 @@ -/* KallistiGL for KallistiOS ##version## - - libgl/gl-clip.c - Copyright (C) 2013-2014 Josh Pearson - - Near-Z Clipping Algorithm (C) 2013-2014 Josh PH3NOM Pearson - Input Primitive Types Supported: - -GL_TRIANGLES - -GL_TRIANGLE_STRIPS - -GL_QUADS - Outputs a mix of Triangles and Triangle Strips for use with the PVR -*/ - -#include -#include - -#include "gl.h" -#include "gl-api.h" -#include "gl-clip.h" - -static float3 CLIP_BUF[1024 * 32]; - -static inline void _glKosVertexClipZNear(pvr_vertex_t *v1, pvr_vertex_t *v2, float MAG) { - colorui *c1 = (colorui *)&v1->argb; - colorui *c2 = (colorui *)&v2->argb; - - v1->x += (v2->x - v1->x) * MAG; - v1->y += (v2->y - v1->y) * MAG; - v1->z += (v2->z - v1->z) * MAG; - v1->u += (v2->u - v1->u) * MAG; - v1->v += (v2->v - v1->v) * MAG; - c1->a += (c2->a - c1->a) * MAG; - c1->r += (c2->r - c1->r) * MAG; - c1->g += (c2->g - c1->g) * MAG; - c1->b += (c2->b - c1->b) * MAG; -} - -static GLuint _glKosTransformClip(pvr_vertex_t *v, GLint count) { - pvr_vertex_t *V = v; - float3 *C = CLIP_BUF; - GLuint in = 0; - - while(count--) { - mat_trans_single3_nodiv_nomod(V->x, V->y, V->z, C->x, C->y, C->z); - - if(C->z < CLIP_NEARZ) ++in; - - ++C; - ++V; - } - - return in; -} - -GLuint _glKosClipTriangleStrip(pvr_vertex_t *src, pvr_vertex_t *dst, GLuint vertices) { - GLuint i, v = 0, in = _glKosTransformClip(src, vertices); - float3 *C = CLIP_BUF; - - if(in == vertices) { - memcpy(dst, src, vertices * 0x20); - pvr_vertex_t *v = dst; - - while(--in) { - v->flags = PVR_CMD_VERTEX; - ++v; - } - - v->flags = PVR_CMD_VERTEX_EOL; - - return vertices; - } - else if(in == 0) - return 0; - - /* Iterate all Triangles of the Strip - Hence looping vertices-2 times */ - for(i = 0; i < ((vertices) - 2); i++) { - GLushort clip = 0; /* Clip Code for current Triangle */ - GLubyte verts_in = 0; /* # of Verteices inside clip plane for current Triangle */ - - C->z >= CLIP_NEARZ ? clip |= FIRST : ++verts_in; - (C + 1)->z >= CLIP_NEARZ ? clip |= SECOND : ++verts_in; - (C + 2)->z >= CLIP_NEARZ ? clip |= THIRD : ++verts_in; - - switch(verts_in) { /* Start by examining # of vertices inside clip plane */ - case 0: /* All Vertices of Triangle are outside of clip plne */ - break; - - case 3: /* All Vertices of Triangle are inside of clip plne */ - memcpy(&dst[v], &src[i], 96); - - dst[v].flags = dst[v + 1].flags = PVR_CMD_VERTEX; - dst[v + 2].flags = PVR_CMD_VERTEX_EOL; - - v += 3; - break; - - case 1:/* 1 Vertex of Triangle is inside of clip plane = output 1 Triangle */ - memcpy(&dst[v], &src[i], 96); - - switch(clip) { - case FIRST_TWO_OUT: - _glKosVertexClipZNear(&dst[v], &dst[v + 2], _glKosNearZClipMag(&CLIP_BUF[i], &CLIP_BUF[i + 2])); - _glKosVertexClipZNear(&dst[v + 1], &dst[v + 2], _glKosNearZClipMag(&CLIP_BUF[i + 1], &CLIP_BUF[i + 2])); - - break; - - case FIRST_AND_LAST_OUT: - _glKosVertexClipZNear(&dst[v], &dst[v + 1], _glKosNearZClipMag(&CLIP_BUF[i], &CLIP_BUF[i + 1])); - _glKosVertexClipZNear(&dst[v + 2], &dst[v + 1], _glKosNearZClipMag(&CLIP_BUF[i + 2], &CLIP_BUF[i + 1])); - - break; - - case LAST_TWO_OUT: - _glKosVertexClipZNear(&dst[v + 1], &dst[v], _glKosNearZClipMag(&CLIP_BUF[i + 1], &CLIP_BUF[i + 0])); - _glKosVertexClipZNear(&dst[v + 2], &dst[v], _glKosNearZClipMag(&CLIP_BUF[i + 2], &CLIP_BUF[i + 0])); - - break; - } - - dst[v].flags = dst[v + 1].flags = PVR_CMD_VERTEX; - dst[v + 2].flags = PVR_CMD_VERTEX_EOL; - v += 3; - - break; - - case 2:/* 2 Vertices of Triangle are inside of clip plane = output 2 Triangles */ - switch(clip) { - case FIRST: - _glKosVertexCopyPVR(&src[i + 0], &dst[v + 0]); - _glKosVertexCopyPVR(&src[i + 1], &dst[v + 1]); - _glKosVertexCopyPVR(&src[i + 0], &dst[v + 2]); - _glKosVertexCopyPVR(&src[i + 2], &dst[v + 3]); - _glKosVertexClipZNear(&dst[v + 0], &dst[v + 1], _glKosNearZClipMag(&CLIP_BUF[i], &CLIP_BUF[i + 1])); - _glKosVertexClipZNear(&dst[v + 2], &dst[v + 3], _glKosNearZClipMag(&CLIP_BUF[i], &CLIP_BUF[i + 2])); - break; - - case SECOND: - _glKosVertexCopyPVR(&src[i + 1], &dst[v + 0]); - _glKosVertexCopyPVR(&src[i + 0], &dst[v + 1]); - _glKosVertexCopyPVR(&src[i + 1], &dst[v + 2]); - _glKosVertexCopyPVR(&src[i + 2], &dst[v + 3]); - _glKosVertexClipZNear(&dst[v + 0], &dst[v + 1], _glKosNearZClipMag(&CLIP_BUF[i + 1], &CLIP_BUF[i + 0])); - _glKosVertexClipZNear(&dst[v + 2], &dst[v + 3], _glKosNearZClipMag(&CLIP_BUF[i + 1], &CLIP_BUF[i + 2])); - break; - - case THIRD: - _glKosVertexCopyPVR(&src[i + 2], &dst[v + 0]); - _glKosVertexCopyPVR(&src[i + 0], &dst[v + 1]); - _glKosVertexCopyPVR(&src[i + 2], &dst[v + 2]); - _glKosVertexCopyPVR(&src[i + 1], &dst[v + 3]); - _glKosVertexClipZNear(&dst[v + 0], &dst[v + 1], _glKosNearZClipMag(&CLIP_BUF[i + 2], &CLIP_BUF[i])); - _glKosVertexClipZNear(&dst[v + 2], &dst[v + 3], _glKosNearZClipMag(&CLIP_BUF[i + 2], &CLIP_BUF[i + 1])); - break; - } - - dst[v + 0].flags = dst[v + 1].flags = dst[v + 2].flags = PVR_CMD_VERTEX; - dst[v + 3].flags = PVR_CMD_VERTEX_EOL; - v += 4; - - break; - } - - C++; - } - - return v; -} - -static inline unsigned char _glKosClipTri(pvr_vertex_t *src, pvr_vertex_t *dst) { - GLushort clip = 0; /* Clip Code for current Triangle */ - GLubyte verts_in = 0; /* # of Vertices inside clip plane for current Triangle */ - float3 clip_buf[3]; /* Store the Vertices for each Triangle Translated into Clip Space */ - - /* Transform all 3 Vertices of Triangle */ - { - register float __x __asm__("fr12") = src->x; - register float __y __asm__("fr13") = src->y; - register float __z __asm__("fr14") = src->z; - - mat_trans_fv12_nodiv(); - - clip_buf[0].x = __x; - clip_buf[0].y = __y; - clip_buf[0].z = __z; - - __x = (src + 1)->x; - __y = (src + 1)->y; - __z = (src + 1)->z; - - mat_trans_fv12_nodiv(); - - clip_buf[1].x = __x; - clip_buf[1].y = __y; - clip_buf[1].z = __z; - - __x = (src + 2)->x; - __y = (src + 2)->y; - __z = (src + 2)->z; - - mat_trans_fv12_nodiv(); - - clip_buf[2].x = __x; - clip_buf[2].y = __y; - clip_buf[2].z = __z; - - /* Compute Clip Code for Triangle */ - (clip_buf[0].z >= CLIP_NEARZ) ? clip |= FIRST : ++verts_in; - (clip_buf[1].z >= CLIP_NEARZ) ? clip |= SECOND : ++verts_in; - (clip_buf[2].z >= CLIP_NEARZ) ? clip |= THIRD : ++verts_in; - } - - switch(verts_in) { /* Start by examining # of vertices inside clip plane */ - case 0: /* All Vertices of Triangle are Outside of clip plne */ - return 0; - - case 3: /* All Vertices of Triangle are inside of clip plne */ - memcpy(dst, src, 96); - - dst->flags = (dst + 1)->flags = PVR_CMD_VERTEX; - (dst + 2)->flags = PVR_CMD_VERTEX_EOL; - - return 3; - - case 1:/* 1 Vertex of Triangle is inside of clip plane = output 1 Triangle */ - memcpy(dst, src, 96); - - switch(clip) { - case FIRST_TWO_OUT: - _glKosVertexClipZNear(dst, dst + 2, _glKosNearZClipMag(&clip_buf[0], &clip_buf[2])); - _glKosVertexClipZNear(dst + 1, dst + 2, _glKosNearZClipMag(&clip_buf[1], &clip_buf[2])); - - break; - - case FIRST_AND_LAST_OUT: - _glKosVertexClipZNear(dst, dst + 1, _glKosNearZClipMag(&clip_buf[0], &clip_buf[1])); - _glKosVertexClipZNear(dst + 2, dst + 1, _glKosNearZClipMag(&clip_buf[2], &clip_buf[1])); - - break; - - case LAST_TWO_OUT: - _glKosVertexClipZNear(dst + 1, dst, _glKosNearZClipMag(&clip_buf[1], &clip_buf[0])); - _glKosVertexClipZNear(dst + 2, dst, _glKosNearZClipMag(&clip_buf[2], &clip_buf[0])); - - break; - } - - dst->flags = (dst + 1)->flags = PVR_CMD_VERTEX; - (dst + 2)->flags = PVR_CMD_VERTEX_EOL; - - return 3; - - case 2:/* 2 Vertices of Triangle are inside of clip plane = output 2 Triangles */ - switch(clip) { - case FIRST: - memcpy(dst, src, 64); - _glKosVertexCopyPVR(src, dst + 2); - _glKosVertexCopyPVR(src + 2, dst + 3); - _glKosVertexClipZNear(dst, dst + 1, _glKosNearZClipMag(&clip_buf[0], &clip_buf[1])); - _glKosVertexClipZNear(dst + 2, dst + 3, _glKosNearZClipMag(&clip_buf[0], &clip_buf[2])); - break; - - case SECOND: - _glKosVertexCopyPVR(src + 1, dst); - _glKosVertexCopyPVR(src, dst + 1); - memcpy(dst + 2, src + 1, 64); - _glKosVertexClipZNear(dst, dst + 1, _glKosNearZClipMag(&clip_buf[1], &clip_buf[0])); - _glKosVertexClipZNear(dst + 2, dst + 3, _glKosNearZClipMag(&clip_buf[1], &clip_buf[2])); - break; - - case THIRD: - _glKosVertexCopyPVR(src + 2, dst); - _glKosVertexCopyPVR(src, dst + 1); - _glKosVertexCopyPVR(src + 2, dst + 2); - _glKosVertexCopyPVR(src + 1, dst + 3); - _glKosVertexClipZNear(dst, dst + 1, _glKosNearZClipMag(&clip_buf[2], &clip_buf[0])); - _glKosVertexClipZNear(dst + 2, dst + 3, _glKosNearZClipMag(&clip_buf[2], &clip_buf[1])); - break; - } - - dst->flags = (dst + 1)->flags = (dst + 2)->flags = PVR_CMD_VERTEX; - (dst + 3)->flags = PVR_CMD_VERTEX_EOL; - - return 4; - } - - return 0; -} - -GLuint _glKosClipTriangles(pvr_vertex_t *src, pvr_vertex_t *dst, GLuint vertices) { - GLuint i, v = 0; - - for(i = 0; i < vertices; i += 3) /* Iterate all Triangles */ - v += _glKosClipTri(src + i, dst + v); - - return v; -} - -GLuint _glKosClipQuads(pvr_vertex_t *src, pvr_vertex_t *dst, GLuint vertices) { - GLuint i, v = 0; - pvr_vertex_t qv; - - for(i = 0; i < vertices; i += 4) { /* Iterate all Quads, Rearranging into Triangle Strips */ - _glKosVertexCopyPVR(src + i + 3, &qv); - _glKosVertexCopyPVR(src + i + 2, src + i + 3); - _glKosVertexCopyPVR(&qv, src + i + 2); - v += _glKosClipTriangleStrip(src + i, dst + v, 4); - } - - return v; -} diff --git a/gl-clip.h b/gl-clip.h deleted file mode 100644 index a13a384..0000000 --- a/gl-clip.h +++ /dev/null @@ -1,52 +0,0 @@ -/* KallistiGL for KallistiOS ##version## - - libgl/gl-clip.h - Copyright (C) 2013-2014 Josh Pearson - - Near-Z Clipping Algorithm (C) 2013-2014 Josh PH3NOM Pearson - Input Primitive Types Supported: - -GL_TRIANGLES - -GL_TRIANGLE_STRIPS - -GL_QUADS - Outputs a mix of Triangles and Triangle Strips for use with the PVR -*/ - -#ifndef GL_CLIP_H -#define GL_CLIP_H - -#include "gl.h" -#include "gl-sh4.h" - -#define NONE 0x0000 /* Clip Codes */ -#define FIRST 0x0001 -#define SECOND 0x0010 -#define THIRD 0x0100 -#define ALL 0x0111 -#define FIRST_TWO_OUT 0x0011 -#define FIRST_AND_LAST_OUT 0x0101 -#define LAST_TWO_OUT 0x0110 - -#define ALPHA 0xFF000000 /* Color Components using PVR's Packed 32bit int */ -#define RED 0x00FF0000 -#define GREEN 0x0000FF00 -#define BLUE 0x000000FF - -#define CLIP_NEARZ -0.20f /* Clip Threshold */ - -typedef struct { - float x, y, z; -} float3; - -typedef struct { - unsigned char b, g, r, a; -} colorui; - -static inline void _glKosVertexCopy3f(float3 *src, float3 *dst) { - *dst = *src; -} - -static inline GLfloat _glKosNearZClipMag(float3 *v1, float3 *v2) { - return ((CLIP_NEARZ - v1->z) / (v2->z - v1->z)); -} - -#endif diff --git a/gl-fog.c b/gl-fog.c deleted file mode 100644 index 71eb36b..0000000 --- a/gl-fog.c +++ /dev/null @@ -1,95 +0,0 @@ -/* KallistiGL for KallistiOS ##version## - - libgl/gl-fog.c - Copyright (C) 2013-2014 Josh Pearson - - Functionality adapted from the original KOS libgl fog code: - Copyright (C) 2002 Benoit Miller - - OpenGL Fog - Wrapper for the PowerVR fog functions in KOS. -*/ - -#include "gl.h" - -static GLuint GL_KOS_FOG_MODE = GL_EXP; /* GL_LINEAR, GL_EXP, or GL_EXP2 FOG */ -static GLfloat GL_KOS_FOG_DENSITY = 1.0f, /* Density - GL_EXP, or GL_EXP2 FOG */ - GL_KOS_FOG_START = 0.0f, /* Linear FOG */ - GL_KOS_FOG_END = 1.0f; /* Linear FOG */ - -void APIENTRY glFogi(GLenum pname, GLint param) { - switch(pname) { - case GL_FOG_MODE: - switch(param) { - case GL_LINEAR: - pvr_fog_table_linear(GL_KOS_FOG_START, GL_KOS_FOG_END); - break; - - case GL_EXP: - pvr_fog_table_exp(GL_KOS_FOG_DENSITY); - break; - - case GL_EXP2: - pvr_fog_table_exp2(GL_KOS_FOG_DENSITY); - break; - } - } -} - -void APIENTRY glFogf(GLenum pname, GLfloat param) { - switch(pname) { - case GL_FOG_START: - GL_KOS_FOG_START = param; - - if(GL_KOS_FOG_MODE == GL_LINEAR) - pvr_fog_table_linear(GL_KOS_FOG_START, GL_KOS_FOG_END); - - break; - - case GL_FOG_END: - GL_KOS_FOG_END = param; - - if(GL_KOS_FOG_MODE == GL_LINEAR) - pvr_fog_table_linear(GL_KOS_FOG_START, GL_KOS_FOG_END); - - break; - - case GL_FOG_DENSITY: - GL_KOS_FOG_DENSITY = param; - - if(GL_KOS_FOG_MODE == GL_EXP) - pvr_fog_table_exp(GL_KOS_FOG_DENSITY); - - else if(GL_KOS_FOG_MODE == GL_EXP2) - pvr_fog_table_exp2(GL_KOS_FOG_DENSITY); - - break; - } -} - -void APIENTRY glFogfv(GLenum pname, const GLfloat *params) { - switch(pname) { - case GL_FOG_MODE: - glFogi(pname, (GLint) * params); - break; - - case GL_FOG_DENSITY: - GL_KOS_FOG_DENSITY = *params; - - if(GL_KOS_FOG_MODE == GL_EXP) - pvr_fog_table_exp(GL_KOS_FOG_DENSITY); - - else if(GL_KOS_FOG_MODE == GL_EXP2) - pvr_fog_table_exp2(GL_KOS_FOG_DENSITY); - - break; - - case GL_FOG_START: - case GL_FOG_END: - glFogf(pname, *params); - break; - - case GL_FOG_COLOR: - pvr_fog_table_color(params[3], params[0], params[1], params[2]); - break; - } -} diff --git a/gl-framebuffer.c b/gl-framebuffer.c deleted file mode 100644 index cc08e0d..0000000 --- a/gl-framebuffer.c +++ /dev/null @@ -1,181 +0,0 @@ -/* KallistiGL for KallistiOS ##version## - - libgl/gl-framebuffer.c - Copyright (C) 2014 Josh Pearson - - This file implements Open GL Frame Buffer Object (FBO) functionality, with what - the DC's PVR can directly implement. - Basically, Render-To-Texture using GL_RGB565 is the only native feature of the - PVR, so if you are looking for a depth-buffer, bad news. - - This implementation uses a dynamic linked list to implement the data structures needed. -*/ - -#include "gl.h" -#include "glext.h" -#include "gl-api.h" - -#include - -//========================================================================================// -//== Internal KOS Open GL API FBO Structures / Global Variables ==// - -static GL_FRAMEBUFFER_OBJECT *FRAMEBUF_OBJ = NULL; -static GLsizei FRAMEBUF_OBJECT = 0; - -//========================================================================================// -//== Internal KOS Open GL API FBO Functionality ==// - -void _glKosInitFrameBuffers() { - FRAMEBUF_OBJ = malloc(sizeof(GL_FRAMEBUFFER_OBJECT)); - - FRAMEBUF_OBJ->index = 0; - FRAMEBUF_OBJ->texID = 0; - FRAMEBUF_OBJ->data = NULL; - FRAMEBUF_OBJ->link = NULL; -} - -static void _glKosInsertFramebufferObj(GL_FRAMEBUFFER_OBJECT *obj) { - GL_FRAMEBUFFER_OBJECT *ptr = FRAMEBUF_OBJ; - - while(ptr->link != NULL) - ptr = (GL_FRAMEBUFFER_OBJECT *)ptr->link; - - ptr->link = obj; -} - -static GLsizei _glKosGetLastFrameBufferIndex() { - GL_FRAMEBUFFER_OBJECT *ptr = FRAMEBUF_OBJ; - - while(ptr->link != NULL) - ptr = (GL_FRAMEBUFFER_OBJECT *)ptr->link; - - return ptr->index; -} - -static GL_FRAMEBUFFER_OBJECT *_glKosGetFrameBufferObj(GLuint index) { - GL_FRAMEBUFFER_OBJECT *ptr = FRAMEBUF_OBJ; - - while(ptr->index != index && ptr->link != NULL) - ptr = (GL_FRAMEBUFFER_OBJECT *)ptr->link; - - return ptr; -} - -GLsizei _glKosGetFBO() { - return FRAMEBUF_OBJECT; -} - -GLuint _glKosGetFBOWidth(GLsizei fbi) { - GL_FRAMEBUFFER_OBJECT *fbo = _glKosGetFrameBufferObj(fbi); - return _glKosTextureWidth(fbo->texID); -} - -GLuint _glKosGetFBOHeight(GLsizei fbi) { - GL_FRAMEBUFFER_OBJECT *fbo = _glKosGetFrameBufferObj(fbi); - return _glKosTextureHeight(fbo->texID); -} - -GLvoid *_glKosGetFBOData(GLsizei fbi) { - GL_FRAMEBUFFER_OBJECT *fbo = _glKosGetFrameBufferObj(fbi); - return fbo->data; -} - -//========================================================================================// -//== Public KOS Open GL API FBO Functionality ==// - -GLAPI void APIENTRY glGenFramebuffers(GLsizei n, GLuint *framebuffers) { - GLsizei index = _glKosGetLastFrameBufferIndex(); - - while(n--) { - GL_FRAMEBUFFER_OBJECT *obj = malloc(sizeof(GL_FRAMEBUFFER_OBJECT)); - obj->index = ++index; - obj->texID = 0; - obj->data = NULL; - obj->link = NULL; - - _glKosInsertFramebufferObj(obj); - - *framebuffers++ = obj->index; - } -} - -GLAPI void APIENTRY glDeleteFramebuffers(GLsizei n, GLuint *framebuffers) { - while(n--) { - GL_FRAMEBUFFER_OBJECT *ptr = FRAMEBUF_OBJ->link, * lptr = FRAMEBUF_OBJ; - - while(ptr != NULL) { - if(ptr->index == *framebuffers) { - GL_FRAMEBUFFER_OBJECT *cur_node = ptr; - lptr->link = ptr->link; - ptr = (GL_FRAMEBUFFER_OBJECT *)ptr->link; - free(cur_node); - - if(*framebuffers == FRAMEBUF_OBJECT) - FRAMEBUF_OBJECT = 0; - - break; - } - else - ptr = (GL_FRAMEBUFFER_OBJECT *)ptr->link; - } - - ++framebuffers; - } -} - -GLAPI void APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer) { - if(target != GL_FRAMEBUFFER) { - _glKosThrowError(GL_INVALID_ENUM, "glBindFramebuffer"); - _glKosPrintError(); - return; - } - - FRAMEBUF_OBJECT = framebuffer; -} - -GLAPI void APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, - GLenum textarget, GLuint texture, GLint level) { - if(target != GL_FRAMEBUFFER) - _glKosThrowError(GL_INVALID_ENUM, "glFramebufferTexture2D"); - - if(attachment != GL_COLOR_ATTACHMENT0) - _glKosThrowError(GL_INVALID_OPERATION, "glFramebufferTexture2D"); - - if(textarget != GL_TEXTURE_2D) - _glKosThrowError(GL_INVALID_OPERATION, "glFramebufferTexture2D"); - - if(level) - _glKosThrowError(GL_INVALID_ENUM, "glFramebufferTexture2D"); - - if(!FRAMEBUF_OBJECT) - _glKosThrowError(GL_INVALID_OPERATION, "glFramebufferTexture2D"); - - if(_glKosHasError()) { - _glKosPrintError(); - return; - } - - GL_FRAMEBUFFER_OBJECT *fbo = _glKosGetFrameBufferObj(FRAMEBUF_OBJECT); - - fbo->texID = texture; - fbo->data = _glKosTextureData(texture); -} - -GLAPI GLenum APIENTRY glCheckFramebufferStatus(GLenum target) { - if(target != GL_FRAMEBUFFER) { - _glKosThrowError(GL_INVALID_ENUM, "glCheckFramebufferStatus"); - _glKosPrintError(); - return 0; - } - - if(!FRAMEBUF_OBJECT) - return GL_FRAMEBUFFER_COMPLETE; - - GL_FRAMEBUFFER_OBJECT *fbo = _glKosGetFrameBufferObj(FRAMEBUF_OBJECT); - - if(!fbo->texID) - return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; - - return GL_FRAMEBUFFER_COMPLETE; -} diff --git a/gl-light.c b/gl-light.c deleted file mode 100644 index 2d91278..0000000 --- a/gl-light.c +++ /dev/null @@ -1,364 +0,0 @@ -/* KallistiGL for KallistiOS ##version## - - libgl/gl-light.c - Copyright (C) 2013-2014 Josh Pearson - - Dynamic Vertex Lighting Model: - vertexColor = emissive + ambient + ( diffuse + specular * attenuation ) - - The only difference here from real OpenGL is that only 1 ambient light - source is used, as opposed to each light containing its own abmient value. - Abmient light is set by the glKosLightAbmient..(..) functions below. - - By default, the specular lighting term is enabled. - For now, specular can be disabled by setting GL_ENABLE_SPECULAR on - gl-light.h when you build the library. -*/ - -#include -#include -#include - -#include "gl.h" -#include "gl-api.h" -#include "gl-clip.h" -#include "gl-light.h" - -#define GL_KOS_MAX_LIGHTS 16 /* Number of Light Sources that may be enabled at once */ - -static GLfloat GL_GLOBAL_AMBIENT[4] = { 0, 0, 0, 0 }; /* RGBA Global Ambient Light */ -static GLfloat GL_VERTEX_NORMAL[3] = { 0, 0, 0 }; /* Current Vertex Normal */ -static GLbitfield GL_LIGHT_ENABLED = 0; /* Client State for Enabling Lighting */ - -static glLight GL_LIGHTS[GL_KOS_MAX_LIGHTS], -GL_DEFAULT_LIGHT = { { 0.0, 0.0, 1.0, 0.0 }, /* Position */ - { 0.0, 0.0, -1.0 }, /* Spot Direction */ - -1.0f, /* Spot Cutoff */ - 1.0f, 0.0f, 0.0f, /* Attenuation Factors */ - 0.0f, /* Spot Exponent */ - { 1.0, 1.0, 1.0, 1.0 }, /* Diffuse */ - { 1.0, 1.0, 1.0, 1.0 }, /* Specular */ - { 0.0, 0.0, 0.0, 1.0 } /* Ambient */ -}; - -static glMaterial GL_MATERIAL, -GL_DEFAULT_MATERIAL = { { 0.0, 0.0, 0.0, 1.0 }, /* Emissive Color */ - { 0.2, 0.2, 0.2, 1.0 }, /* Ambient Reflectance */ - { 0.8, 0.8, 0.8, 1.0 }, /* Diffuse Reflectance */ - { 0.0, 0.0, 0.0, 1.0 }, /* Specular Reflectance */ - 0.0 /* Shininess */ -}; - -static GLfloat GL_EYE_POSITION[3] = { 0, 0, 0 }; /* Eye Position for Specular Factor */ - -void _glKosSetEyePosition(GLfloat *position) { /* Called internally by glhLookAtf() */ - GL_EYE_POSITION[0] = position[0]; - GL_EYE_POSITION[1] = position[1]; - GL_EYE_POSITION[2] = position[2]; -} - -void _glKosInitLighting() { /* Called internally by glInit() */ - unsigned char i; - - for(i = 0; i < GL_KOS_MAX_LIGHTS; i++) - memcpy(&GL_LIGHTS[i], &GL_DEFAULT_LIGHT, sizeof(glLight)); - - memcpy(&GL_MATERIAL, &GL_DEFAULT_MATERIAL, sizeof(glMaterial)); -} - -/* Enable a light - GL_LIGHT0->GL_LIGHT7 */ -void _glKosEnableLight(const GLuint light) { - if(light < GL_LIGHT0 || light > GL_LIGHT0 + GL_KOS_MAX_LIGHTS) { - _glKosThrowError(GL_INVALID_ENUM, "glEnable(GL_LIGHT)"); - return; - } - - GL_LIGHT_ENABLED |= (1 << (light & 0xF)); -} - -/* Disable a light - GL_LIGHT0->GL_LIGHT0 + GL_KOS_MAX_LIGHTS */ -void _glKosDisableLight(const GLuint light) { - if(light < GL_LIGHT0 || light > GL_LIGHT0 + GL_KOS_MAX_LIGHTS) { - _glKosThrowError(GL_INVALID_ENUM, "glDisable(GL_LIGHT)"); - return; - } - - GL_LIGHT_ENABLED &= ~(1 << (light & 0xF)); -} - -GLubyte _glKosIsLightEnabled(GLubyte light) { - return GL_LIGHT_ENABLED & (1 << light); -} - -GLubyte _glKosGetMaxLights() { - return GL_KOS_MAX_LIGHTS; -} - -/* Misc Lighting Functions ************************************/ -static inline void glCopyRGBA(const rgba *src, rgba *dst) { - *dst = *src; -} - -static inline void glCopy4f(const float *src, float *dst) { - memcpy(dst, src, 0x10); -} - -static inline void glCopy3f(const float *src, float *dst) { - memcpy(dst, src, 0xC); -} - -/* Vertex Lighting **********************************************************/ - -/* Fast POW Implementation - Less accurate, but much faster than math.h */ -#define EXP_A 184 -#define EXP_C 16249 - -float FEXP(float y) { - union { - float d; - struct { - short j, i; - } n; - } eco; - eco.n.i = EXP_A * (y) + (EXP_C); - eco.n.j = 0; - return eco.d; -} - -float FLOG(float y) { - int *nTemp = (int *)&y; - y = (*nTemp) >> 16; - return (y - EXP_C) / EXP_A; -} - -float FPOW(float b, float p) { - return FEXP(FLOG(b) * p); -} - -/* End FPOW Implementation */ - -void _glKosVertex3flv(const GLfloat *xyz) { - glVertex *v = _glKosArrayBufPtr(); - - v->pos[0] = xyz[0]; - v->pos[1] = xyz[1]; - v->pos[2] = xyz[2]; - v->norm[0] = GL_VERTEX_NORMAL[0]; - v->norm[1] = GL_VERTEX_NORMAL[1]; - v->norm[2] = GL_VERTEX_NORMAL[2]; - - _glKosArrayBufIncrement(); - - _glKosVertex3fsv(xyz); -} - -void _glKosVertex3fl(GLfloat x, GLfloat y, GLfloat z) { - glVertex *v = _glKosArrayBufPtr(); - - v->pos[0] = x; - v->pos[1] = y; - v->pos[2] = z; - v->norm[0] = GL_VERTEX_NORMAL[0]; - v->norm[1] = GL_VERTEX_NORMAL[1]; - v->norm[2] = GL_VERTEX_NORMAL[2]; - - _glKosArrayBufIncrement(); - - _glKosVertex3fs(x, y, z); -} - -void _glKosVertex3flcv(const GLfloat *xyz) { - glVertex *v = _glKosArrayBufPtr(); - - v->pos[0] = xyz[0]; - v->pos[1] = xyz[1]; - v->pos[2] = xyz[2]; - v->norm[0] = GL_VERTEX_NORMAL[0]; - v->norm[1] = GL_VERTEX_NORMAL[1]; - v->norm[2] = GL_VERTEX_NORMAL[2]; - - _glKosArrayBufIncrement(); - - _glKosVertex3fcv(xyz); -} - -void _glKosVertex3flc(GLfloat x, GLfloat y, GLfloat z) { - glVertex *v = _glKosArrayBufPtr(); - - v->pos[0] = x; - v->pos[1] = y; - v->pos[2] = z; - v->norm[0] = GL_VERTEX_NORMAL[0]; - v->norm[1] = GL_VERTEX_NORMAL[1]; - v->norm[2] = GL_VERTEX_NORMAL[2]; - - _glKosArrayBufIncrement(); - - _glKosVertex3fc(x, y, z); -} - -/**** Compute Vertex Light Color ***/ -void _glKosVertexLights(glVertex *P, pvr_vertex_t *v, GLuint count) { -#ifdef GL_ENABLE_SPECULAR - float S; -#endif - unsigned char i; - float L[4] __attribute__((aligned(8))); - float C[3] = { 0, 0, 0 }; - - colorui *color = (colorui *)&v->argb; - - /* Compute Global Ambient */ - float A[3] = { GL_MATERIAL.Ke[0] + GL_MATERIAL.Ka[0] *GL_GLOBAL_AMBIENT[0], - GL_MATERIAL.Ke[1] + GL_MATERIAL.Ka[1] *GL_GLOBAL_AMBIENT[1], - GL_MATERIAL.Ke[2] + GL_MATERIAL.Ka[2] *GL_GLOBAL_AMBIENT[2] - }; - - while(count--) { - for(i = 0; i < GL_KOS_MAX_LIGHTS; i++) - if(GL_LIGHT_ENABLED & 1 << i) - if(_glKosSpotlight(&GL_LIGHTS[i], P, L)) { /* Compute Spot / Diffuse */ - C[0] = A[0] + (GL_MATERIAL.Kd[0] * GL_LIGHTS[i].Kd[0] * L[3]); - C[1] = A[1] + (GL_MATERIAL.Kd[1] * GL_LIGHTS[i].Kd[1] * L[3]); - C[2] = A[2] + (GL_MATERIAL.Kd[2] * GL_LIGHTS[i].Kd[2] * L[3]); - -#ifdef GL_ENABLE_SPECULAR - S = _glKosSpecular(P, GL_EYE_POSITION, L); /* Compute Specular */ - - if(S > 0) { -#ifdef GL_ENABLE_FAST_POW - S = FPOW(S, GL_MATERIAL.Shine); -#else - S = pow(S, GL_MATERIAL.Shine); -#endif - C[0] += (GL_MATERIAL.Ks[0] * GL_LIGHTS[i].Ks[0] * S); - C[1] += (GL_MATERIAL.Ks[1] * GL_LIGHTS[i].Ks[1] * S); - C[2] += (GL_MATERIAL.Ks[2] * GL_LIGHTS[i].Ks[2] * S); - } - -#endif - } - - color->a = 0xFF; /* Clamp / Pack Floating Point Colors to 32bit int */ - (C[0] > 1.0f) ? (color->r = 0xFF) : (color->r = (unsigned char)(255 * C[0])); - (C[1] > 1.0f) ? (color->g = 0xFF) : (color->g = (unsigned char)(255 * C[1])); - (C[2] > 1.0f) ? (color->b = 0xFF) : (color->b = (unsigned char)(255 * C[2])); - color += 8; /* pvr_vertex_t color stride */ - ++P; - } -} - -void _glKosVertexLight(glVertex *P, pvr_vertex_t *v) { -#ifdef GL_ENABLE_SPECULAR - float S; -#endif - unsigned char i; - float L[4] __attribute__((aligned(8))); - - /* Compute Ambient */ - float C[3] = { GL_MATERIAL.Ke[0] + GL_MATERIAL.Ka[0] *GL_GLOBAL_AMBIENT[0], - GL_MATERIAL.Ke[1] + GL_MATERIAL.Ka[1] *GL_GLOBAL_AMBIENT[1], - GL_MATERIAL.Ke[2] + GL_MATERIAL.Ka[2] *GL_GLOBAL_AMBIENT[2] - }; - - for(i = 0; i < GL_KOS_MAX_LIGHTS; i++) - if(GL_LIGHT_ENABLED & 1 << i) - if(_glKosSpotlight(&GL_LIGHTS[i], P, L)) { /* Compute Spot / Diffuse */ - C[0] += (GL_MATERIAL.Kd[0] * GL_LIGHTS[i].Kd[0] * L[3]); - C[1] += (GL_MATERIAL.Kd[1] * GL_LIGHTS[i].Kd[1] * L[3]); - C[2] += (GL_MATERIAL.Kd[2] * GL_LIGHTS[i].Kd[2] * L[3]); - -#ifdef GL_ENABLE_SPECULAR - S = _glKosSpecular(P, GL_EYE_POSITION, L); /* Compute Specular */ - - if(S > 0) { -#ifdef GL_ENABLE_FAST_POW - S = FPOW(S, GL_MATERIAL.Shine); -#else - S = pow(S, GL_MATERIAL.Shine); -#endif - C[0] += (GL_MATERIAL.Ks[0] * GL_LIGHTS[i].Ks[0] * S); - C[1] += (GL_MATERIAL.Ks[1] * GL_LIGHTS[i].Ks[1] * S); - C[2] += (GL_MATERIAL.Ks[2] * GL_LIGHTS[i].Ks[2] * S); - } - -#endif - } - - colorui *col = (colorui *)&v->argb; /* Clamp / Pack floats to a 32bit int */ - col->a = 0xFF; - (C[0] > 1.0f) ? (col->r = 0xFF) : (col->r = (unsigned char)(255 * C[0])); - (C[1] > 1.0f) ? (col->g = 0xFF) : (col->g = (unsigned char)(255 * C[1])); - (C[2] > 1.0f) ? (col->b = 0xFF) : (col->b = (unsigned char)(255 * C[2])); -} - -GLuint _glKosVertexLightColor(glVertex *P) { -#ifdef GL_ENABLE_SPECULAR - float S; -#endif - GLuint color; - GLubyte i; - float L[4] __attribute__((aligned(8))); - - /* Compute Ambient */ - float C[3] = { GL_MATERIAL.Ke[0] + GL_MATERIAL.Ka[0] *GL_GLOBAL_AMBIENT[0], - GL_MATERIAL.Ke[1] + GL_MATERIAL.Ka[1] *GL_GLOBAL_AMBIENT[1], - GL_MATERIAL.Ke[2] + GL_MATERIAL.Ka[2] *GL_GLOBAL_AMBIENT[2] - }; - - for(i = 0; i < GL_KOS_MAX_LIGHTS; i++) - if(GL_LIGHT_ENABLED & 1 << i) - if(_glKosSpotlight(&GL_LIGHTS[i], P, L)) { /* Compute Spot / Diffuse */ - C[0] += (GL_MATERIAL.Kd[0] * GL_LIGHTS[i].Kd[0] * L[3]); - C[1] += (GL_MATERIAL.Kd[1] * GL_LIGHTS[i].Kd[1] * L[3]); - C[2] += (GL_MATERIAL.Kd[2] * GL_LIGHTS[i].Kd[2] * L[3]); - -#ifdef GL_ENABLE_SPECULAR - S = _glKosSpecular(P, GL_EYE_POSITION, L); /* Compute Specular */ - - if(S > 0) { -#ifdef GL_ENABLE_FAST_POW - S = FPOW(S, GL_MATERIAL.Shine); -#else - S = pow(S, GL_MATERIAL.Shine); -#endif - C[0] += (GL_MATERIAL.Ks[0] * GL_LIGHTS[i].Ks[0] * S); - C[1] += (GL_MATERIAL.Ks[1] * GL_LIGHTS[i].Ks[1] * S); - C[2] += (GL_MATERIAL.Ks[2] * GL_LIGHTS[i].Ks[2] * S); - } - -#endif - } - - colorui *col = (colorui *)&color; /* Clamp / Pack floats to a 32bit int */ - col->a = 0xFF; - (C[0] > 1.0f) ? (col->r = 0xFF) : (col->r = (unsigned char)(255 * C[0])); - (C[1] > 1.0f) ? (col->g = 0xFF) : (col->g = (unsigned char)(255 * C[1])); - (C[2] > 1.0f) ? (col->b = 0xFF) : (col->b = (unsigned char)(255 * C[2])); - - return color; -} - -/** Iterate vertices submitted and compute vertex lighting **/ - -void _glKosVertexComputeLighting(pvr_vertex_t *v, int verts) { - unsigned int i; - glVertex *s = _glKosArrayBufAddr(); - - _glKosMatrixLoadModelView(); - - for(i = 0; i < verts; i++) { - mat_trans_single3_nodiv(s->pos[0], s->pos[1], s->pos[2]); - ++s; - } - - s = _glKosArrayBufAddr(); - - _glKosMatrixLoadModelRot(); - - for(i = 0; i < verts; i++) { - mat_trans_normal3(s->norm[0], s->norm[1], s->norm[2]); - _glKosVertexLight(s++, v++); - } -} - diff --git a/gl-light.h b/gl-light.h deleted file mode 100644 index 4a69d73..0000000 --- a/gl-light.h +++ /dev/null @@ -1,51 +0,0 @@ -/* KallistiGL for KallistiOS ##version## - - libgl/gl-light.h - Copyright (C) 2013-2014 Josh Pearson - - Dynamic Vertex Lighting. - - By default, specular lighting is enabled. - For now, specular can be disabled by setting GL_ENABLE_SPECULAR - below when you build the library. - By default, specular lighting uses a fast POW implementation, at - sacrifice of accuracy. Change GL_ENABLE_FAST_POW to suit your needs. -*/ - -#ifndef GL_LIGHT_H -#define GL_LIGHT_H - -#include "gl-sh4.h" - -#define GL_ENABLE_SPECULAR 1 -#define GL_ENABLE_FAST_POW 1 - -int _glKosSpotlight(void *glLight, void *vertex6f, void *Lvectorout); -float _glKosSpecular(void *vertex6f, void *eyepos, void *Lvectorin); - -typedef struct { - float r, g, b, a; -} rgba; - -typedef struct { - float Ke[4]; /* RGBA material emissive color # 0.0, 0.0, 0.0, 1.0 */ - float Ka[4]; /* RGBA material ambient reflectance # 0.2, 0.2, 0.2, 1.0 */ - float Kd[4]; /* RGBA material diffuse reflectance # 0.8, 0.8, 0.8, 1.0 */ - float Ks[4]; /* RGBA material diffuse reflectance # 0.0, 0.0, 0.0, 1.0 */ - float Shine; /* Material Specular Shine # 0.0f */ -} glMaterial; - -typedef struct { - float Pos[4]; /* XYZW Position of Light # 0.0, 0.0, 1.0, 0.0 */ - float Dir[3]; /* Spot Light Direction # 0.0, 0.0, -1.0 */ - float CutOff; /* Spot Light CutOff #-1.0f */ - float Kc, /* Constant Attenuation # 1.0f */ - Kl, /* Linear Attenuation # 0.0f */ - Kq; /* Quadratic Attenuation # 0.0f */ - float Exponent; /* Spot Light Exponent # 0.0f */ - float Kd[4]; /* RGBA Diffuse Light Contribution # 1.0, 1.0, 1.0, 1.0 */ - float Ks[4]; /* RGBA Specular Light Contribution # 1.0, 1.0, 1.0, 1.0 */ - float Ka[4]; /* RGBA Ambient Light Contribution # 0.0, 0.0, 0.0, 1.0 */ -} glLight; - -#endif diff --git a/gl-pvr.c b/gl-pvr.c deleted file mode 100644 index 03c1cf7..0000000 --- a/gl-pvr.c +++ /dev/null @@ -1,178 +0,0 @@ -/* KallistiGL for KallistiOS ##version## - - libgl/gl-pvr.c - Copyright (C) 2013-2014 Josh Pearson - Copyright (C) 2016 Lawrence Sebald - - Vertex Buffer Routines for interfacing the Dreamcast's SH4 CPU and PowerVR GPU. - - What we are doing here is using a Vertex Buffer in main RAM to store the - submitted data, untill the user finishes the scene by either calling - glSwapBuffer() to submit the buffer to the PVR for render to the screen OR - glSwapBufferToTexture() to submit the buffer to the PVR for render to texture. - - This solution means the client can switch between transparent and opaque polygon - sumbission at any time, in no particular order, with no penalty in speed. - - The size of the Vertex Buffer can be controlled by setting some params on gl-pvr.h: - GL_PVR_VERTEX_BUF_SIZE controls size of Vertex Buffer in the PVR VRAM - GL_KOS_MAX_VERTS conrols the number of vertices per list in the Vertex Buffer in SH4 RAM -*/ - -#include -#include -#include -#include - -#include - -#include "gl.h" -#include "gl-api.h" -#include "gl-sh4.h" -#include "gl-pvr.h" - -/* Vertex Buffer Functions *************************************************************************/ - -#define COMMANDS_PER_ALLOC ((64 * 1024) / 32) /* 64k memory chunks */ - -static pvr_cmd_t *GL_VBUF[2] __attribute__((aligned(32))); /* Dynamic Vertex Buffer */ -static pvr_cmd_t *GL_CBUF; /* Dynamic Clip Buffer */ -static glTexCoord *GL_UVBUF; /* Dynamic Multi-Texture UV */ - -static GLuint GL_VERTS[2] = {0, 0}; -static GLuint GL_VERTS_ALLOCATED[2] = {0, 0}; -static GLuint GL_CVERTS = 0; -static GLuint GL_UVVERTS = 0; -static GLuint GL_LIST = GL_KOS_LIST_OP; - -#define GL_KOS_MAX_MULTITEXTURE_OBJECTS 512 - -static GLuint GL_MTOBJECTS = 0; - -void _glKosResetMultiTexObject() { - GL_MTOBJECTS = 0; -} - -void *_glKosMultiUVBufAddress() { - return &GL_UVBUF[0]; -} - -void *_glKosMultiUVBufPointer() { - return &GL_UVBUF[GL_UVVERTS]; -} - -void _glKosMultiUVBufIncrement() { - ++GL_UVVERTS; -} - -void _glKosMultiUVBufAdd(GLuint count) { - GL_UVVERTS += count; -} - -void _glKosMultiUVBufReset() { - GL_UVVERTS = 0; -} - -void *_glKosClipBufAddress() { - return &GL_CBUF[0]; -} - -void *_glKosClipBufPointer() { - return &GL_CBUF[GL_CVERTS]; -} - -void _glKosClipBufIncrement() { - ++GL_CVERTS; -} - -void _glKosClipBufAdd(GLuint count) { - GL_CVERTS += count; -} - -void _glKosClipBufReset() { - GL_CVERTS = 0; -} - -void _glKosVertexBufSwitchOP() { - GL_LIST = GL_KOS_LIST_OP; -} - -void _glKosVertexBufSwitchTR() { - GL_LIST = GL_KOS_LIST_TR; -} - -void *_glKosVertexBufAddress(GLubyte list) { - return &GL_VBUF[list][0]; -} - -void *_glKosVertexBufPointer() { - return &GL_VBUF[GL_LIST][GL_VERTS[GL_LIST]]; -} - -static void _glKosVertexBufIncrementList(GLubyte list, GLuint count) { - GL_VERTS[list] += count; - - if(GL_VERTS[list] > GL_VERTS_ALLOCATED[list]) { - /* Grow the list buffer. We can't use realloc with memalign so we have to memcpy */ - pvr_cmd_t* orig = GL_VBUF[list]; - - /* Increase the allocated counter */ - GL_VERTS_ALLOCATED[list] += COMMANDS_PER_ALLOC; - - /* Create a new memory buffer with the new size */ - GL_VBUF[list] = memalign( - 0x20, - GL_VERTS_ALLOCATED[list] * sizeof(pvr_cmd_t) - ); - - /* Copy across the original data */ - memcpy(GL_VBUF[list], orig, (GL_VERTS[list] - count) * sizeof(pvr_cmd_t)); - - /* Free previously allocated memory */ - free(orig); - } -} - -void _glKosVertexBufIncrement() { - _glKosVertexBufIncrementList(GL_LIST, 1); -} - -void *_glKosTRVertexBufPointer() { - return &GL_VBUF[GL_KOS_LIST_TR][GL_VERTS[GL_KOS_LIST_TR]]; -} - -void _glKosTRVertexBufIncrement() { - _glKosVertexBufIncrementList(GL_KOS_LIST_TR, 1); -} - -void _glKosVertexBufAdd(GLuint count) { - _glKosVertexBufIncrementList(GL_LIST, count); -} - -void _glKosTRVertexBufAdd(GLuint count) { - _glKosVertexBufIncrementList(GL_KOS_LIST_TR, count); -} - -void _glKosVertexBufDecrement() { - /* Intentionally don't free data here, we only ever grow */ - --GL_VERTS[GL_LIST]; -} - -void _glKosVertexBufReset() { - GL_VERTS[0] = GL_VERTS[1] = 0; -} - -GLuint _glKosVertexBufCount(GLubyte list) { - return GL_VERTS[list]; -} - -GLubyte _glKosList() { - return GL_LIST; -} - -void _glKosVertexBufCopy(void *dst, void *src, GLuint count) { - memcpy(dst, src, count * 0x20); -} - - - diff --git a/gl-pvr.h b/gl-pvr.h deleted file mode 100644 index cf12a7d..0000000 --- a/gl-pvr.h +++ /dev/null @@ -1,44 +0,0 @@ -/* KallistiGL for KallistiOS ##version## - - libgl/gl-pvr.h - Copyright (C) 2013-2014 Josh Pearson - - Vertex Buffer Routines for interfacing the Dreamcast's SH4 CPU and PowerVR GPU. -*/ - -#ifndef GL_PVR_H -#define GL_PVR_H - -/* GL->PVR Commands */ -typedef struct { - unsigned int cmd[8]; -} pvr_cmd_t; /* Generic 32byte 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 */ - -#define GL_KOS_LIST_OP 0 -#define GL_KOS_LIST_TR 1 - -//#define GL_KOS_USE_DMA 1 /* Use PVR DMA for vertex data transfer instead of store queues */ -//#define GL_USE_FLOAT 0 /* Use PVR's floating-point color Vertex Type (64bit) *NoOp* */ - -/* Misc SH4->PVR Commands */ -#define TA_SQ_ADDR (unsigned int *)(void *) \ - (0xe0000000 | (((unsigned long)0x10000000) & 0x03ffffe0)) - -#define QACRTA ((((unsigned int)0x10000000)>>26)<<2)&0x1c - -#define PVR_TA_TXR_FILTER_SHIFT 14 - -#define GL_PVR_FILTER_POINT 0x00 -#define GL_PVR_FILTER_BILINEAR 0x01 -#define GL_PVR_FILTER_TRILINEAR_A 0x10 -#define GL_PVR_FILTER_TRILINEAR_B 0x11 - -#define PVR_TA_SUPER_SAMPLE_SHIFT 12 - -#define GL_PVR_SAMPLE_POINT 0x0 -#define GL_PVR_SAMPLE_SUPER 0x1 - -#endif diff --git a/gl-rgb.c b/gl-rgb.c deleted file mode 100644 index e364a9d..0000000 --- a/gl-rgb.c +++ /dev/null @@ -1,310 +0,0 @@ -/* KallistiGL for KallistiOS ##version## - - libgl/gl-rgb.c - Copyright (C) 2013-2015 Josh Pearson - - A set of functions for working with ARGB pixel data, used by gluBuild2DMipmaps(...). - The pixel conversion functions are for submitting textures not supported by the PVR. -*/ - -#include "gl.h" -#include "gl-rgb.h" - -//===================================================================================================// -//== ARGB Bit Masks ==// - -static unsigned char ARGB1555_ALPHA(unsigned short c) { - return (c & ARGB1555_ALPHA_MASK) >> ARGB1555_ALPHA_SHIFT; -} - -static unsigned char ARGB1555_RED(unsigned short c) { - return (c & ARGB1555_RED_MASK) >> ARGB1555_RED_SHIFT; -} - -static unsigned char ARGB1555_GREEN(unsigned short c) { - return (c & ARGB1555_GREEN_MASK) >> ARGB1555_GREEN_SHIFT; -} - -static unsigned char ARGB1555_BLUE(unsigned short c) { - return (c & ARGB1555_BLUE_MASK) >> ARGB1555_BLUE_SHIFT; -} - -static unsigned char ARGB4444_ALPHA(unsigned short c) { - return (c & ARGB4444_ALPHA_MASK) >> ARGB4444_ALPHA_SHIFT; -} - -static unsigned char ARGB4444_RED(unsigned short c) { - return (c & ARGB4444_RED_MASK) >> ARGB4444_RED_SHIFT; -} - -static unsigned char ARGB4444_GREEN(unsigned short c) { - return (c & ARGB4444_GREEN_MASK) >> ARGB4444_GREEN_SHIFT; -} - -static unsigned char ARGB4444_BLUE(unsigned short c) { - return (c & ARGB4444_BLUE_MASK) >> ARGB4444_BLUE_SHIFT; -} - -static unsigned char RGB565_RED(unsigned short c) { - return (c & RGB565_RED_MASK) >> RGB565_RED_SHIFT; -} - -static unsigned char RGB565_GREEN(unsigned short c) { - return (c & RGB565_GREEN_MASK) >> RGB565_GREEN_SHIFT; -} - -static unsigned char RGB565_BLUE(unsigned short c) { - return c & RGB565_BLUE_MASK; -} - -//===================================================================================================// -//== Block Compression ==// - -uint16 __glKosAverageQuadPixelRGB565(uint16 p1, uint16 p2, uint16 p3, uint16 p4) { - uint8 R = (RGB565_RED(p1) + RGB565_RED(p2) + RGB565_RED(p3) + RGB565_RED(p4)) / 4; - uint8 G = (RGB565_GREEN(p1) + RGB565_GREEN(p2) + RGB565_GREEN(p3) + RGB565_GREEN(p4)) / 4; - uint8 B = (RGB565_BLUE(p1) + RGB565_BLUE(p2) + RGB565_BLUE(p3) + RGB565_BLUE(p4)) / 4; - - return R << RGB565_RED_SHIFT | G << RGB565_GREEN_SHIFT | B; -} - -uint16 __glKosAverageQuadPixelARGB1555(uint16 p1, uint16 p2, uint16 p3, uint16 p4) { - uint8 A = (ARGB1555_ALPHA(p1) + ARGB1555_ALPHA(p2) + ARGB1555_ALPHA(p3) + ARGB1555_ALPHA(p4)) / 4; - uint8 R = (ARGB1555_RED(p1) + ARGB1555_RED(p2) + ARGB1555_RED(p3) + ARGB1555_RED(p4)) / 4; - uint8 G = (ARGB1555_GREEN(p1) + ARGB1555_GREEN(p2) + ARGB1555_GREEN(p3) + ARGB1555_GREEN(p4)) / 4; - uint8 B = (ARGB1555_BLUE(p1) + ARGB1555_BLUE(p2) + ARGB1555_BLUE(p3) + ARGB1555_BLUE(p4)) / 4; - - return ((A & RGB1_MAX) << ARGB1555_ALPHA_SHIFT) | ((R & RGB5_MAX) << ARGB1555_RED_SHIFT) - | ((G & RGB5_MAX) << ARGB1555_GREEN_SHIFT) | (B & RGB5_MAX); -} - -uint16 __glKosAverageQuadPixelARGB4444(uint16 p1, uint16 p2, uint16 p3, uint16 p4) { - uint8 A = (ARGB4444_ALPHA(p1) + ARGB4444_ALPHA(p2) + ARGB4444_ALPHA(p3) + ARGB4444_ALPHA(p4)) / 4; - uint8 R = (ARGB4444_RED(p1) + ARGB4444_RED(p2) + ARGB4444_RED(p3) + ARGB4444_RED(p4)) / 4; - uint8 G = (ARGB4444_GREEN(p1) + ARGB4444_GREEN(p2) + ARGB4444_GREEN(p3) + ARGB4444_GREEN(p4)) / 4; - uint8 B = (ARGB4444_BLUE(p1) + ARGB4444_BLUE(p2) + ARGB4444_BLUE(p3) + ARGB4444_BLUE(p4)) / 4; - - return ((A & RGB4_MAX) << ARGB4444_ALPHA_SHIFT) | ((R & RGB4_MAX) << ARGB4444_RED_SHIFT) - | ((G & RGB4_MAX) << ARGB4444_GREEN_SHIFT) | (B & RGB4_MAX); -} - -uint16 __glKosAverageBiPixelRGB565(uint16 p1, uint16 p2) { - uint8 R = (RGB565_RED(p1) + RGB565_RED(p2)) / 2; - uint8 G = (RGB565_GREEN(p1) + RGB565_GREEN(p2)) / 2; - uint8 B = (RGB565_BLUE(p1) + RGB565_BLUE(p2)) / 2; - - return R << RGB565_RED_SHIFT | G << RGB565_GREEN_SHIFT | B; -} - -uint16 __glKosAverageBiPixelARGB1555(uint16 p1, uint16 p2) { - uint8 A = (ARGB1555_ALPHA(p1) + ARGB1555_ALPHA(p2)) / 2; - uint8 R = (ARGB1555_RED(p1) + ARGB1555_RED(p2)) / 2; - uint8 G = (ARGB1555_GREEN(p1) + ARGB1555_GREEN(p2)) / 2; - uint8 B = (ARGB1555_BLUE(p1) + ARGB1555_BLUE(p2)) / 2; - - return ((A & RGB1_MAX) << ARGB1555_ALPHA_SHIFT) | ((R & RGB5_MAX) << ARGB1555_RED_SHIFT) - | ((G & RGB5_MAX) << ARGB1555_GREEN_SHIFT) | (B & RGB5_MAX); -} - -uint16 __glKosAverageBiPixelARGB4444(uint16 p1, uint16 p2) { - uint8 A = (ARGB4444_ALPHA(p1) + ARGB4444_ALPHA(p2)) / 2; - uint8 R = (ARGB4444_RED(p1) + ARGB4444_RED(p2)) / 2; - uint8 G = (ARGB4444_GREEN(p1) + ARGB4444_GREEN(p2)) / 2; - uint8 B = (ARGB4444_BLUE(p1) + ARGB4444_BLUE(p2)) / 2; - - return ((A & RGB4_MAX) << ARGB4444_ALPHA_SHIFT) | ((R & RGB4_MAX) << ARGB4444_RED_SHIFT) - | ((G & RGB4_MAX) << ARGB4444_GREEN_SHIFT) | (B & RGB4_MAX); -} - -//===================================================================================================// -//== Colorspace Conversion ==// - -static uint16 _glKosConvPixelRGBAU32(uint8 r, uint8 g, uint8 b, uint8 a) { - return (uint16)((a & RGB4_MAX) << ARGB4444_ALPHA_SHIFT) | - ((r & RGB4_MAX) << ARGB4444_RED_SHIFT) | - ((g & RGB4_MAX) << ARGB4444_GREEN_SHIFT) | - ((b & RGB4_MAX)); -} - -static uint16 _glKosConvPixelRGBU24(uint8 r, uint8 g, uint8 b) { - return (uint16)((r & RGB5_MAX) << RGB565_RED_SHIFT) | - ((g & RGB6_MAX) << RGB565_GREEN_SHIFT) | - ((b & RGB5_MAX)); -} - -static void _glKosConvPixelsRGBF(int w, int h, float *src, uint16 *dst) { - int i; - - for(i = 0; i < w * h; i++) { - dst[i] = _glKosConvPixelRGBU24((uint8)(src[i * 3 + 0] * RGB5_MAX), - (uint8)(src[i * 3 + 1] * RGB6_MAX), - (uint8)(src[i * 3 + 2] * RGB5_MAX)); - } -} - -static void _glKosConvPixelsRGBAF(int w, int h, float *src, uint16 *dst) { - int i; - - for(i = 0; i < w * h; i++) { - dst[i] = _glKosConvPixelRGBAU32((uint8)(src[i * 4 + 0] * RGB4_MAX), - (uint8)(src[i * 4 + 1] * RGB4_MAX), - (uint8)(src[i * 4 + 2] * RGB4_MAX), - (uint8)(src[i * 4 + 3] * RGB4_MAX)); - } -} - -static void _glKosConvPixelsRGBU24(int w, int h, uint8 *src, uint16 *dst) { - unsigned char r, g, b; - int i; - - for(i = 0; i < w * h; i++) { - r = (src[i * 3 + 0] * RGB5_MAX) / RGB8_MAX; - g = (src[i * 3 + 1] * RGB6_MAX) / RGB8_MAX; - b = (src[i * 3 + 2] * RGB5_MAX) / RGB8_MAX; - - dst[i] = _glKosConvPixelRGBU24(r, g, b); - } -} - -static void _glKosConvPixelsRGBAU32(int w, int h, uint8 *src, uint16 *dst) { - unsigned char r, g, b, a; - int i; - - for(i = 0; i < w * h; i++) { - r = (src[i * 4 + 0] * RGB4_MAX) / RGB8_MAX; - g = (src[i * 4 + 1] * RGB4_MAX) / RGB8_MAX; - b = (src[i * 4 + 2] * RGB4_MAX) / RGB8_MAX; - a = (src[i * 4 + 3] * RGB4_MAX) / RGB8_MAX; - - dst[i] = _glKosConvPixelRGBAU32(r, g, b, a); - } -} - -static void _glKosConvPixelsRGBS24(int w, int h, int8 *src, uint16 *dst) { - unsigned char r, g, b; - int i; - - for(i = 0; i < w * h; i++) { - r = ((src[i * 3 + 0] + S8_NEG_OFT) * RGB5_MAX) / RGB8_MAX; - g = ((src[i * 3 + 1] + S8_NEG_OFT) * RGB6_MAX) / RGB8_MAX; - b = ((src[i * 3 + 2] + S8_NEG_OFT) * RGB5_MAX) / RGB8_MAX; - - dst[i] = _glKosConvPixelRGBU24(r, g, b); - } -} - -static void _glKosConvPixelsRGBAS32(int w, int h, int8 *src, uint16 *dst) { - unsigned char r, g, b, a; - int i; - - for(i = 0; i < w * h; i++) { - r = ((src[i * 4 + 0] + S8_NEG_OFT) * RGB4_MAX) / RGB8_MAX; - g = ((src[i * 4 + 1] + S8_NEG_OFT) * RGB4_MAX) / RGB8_MAX; - b = ((src[i * 4 + 2] + S8_NEG_OFT) * RGB4_MAX) / RGB8_MAX; - a = ((src[i * 4 + 3] + S8_NEG_OFT) * RGB4_MAX) / RGB8_MAX; - - dst[i] = _glKosConvPixelRGBAU32(r, g, b, a); - } -} - -static void _glKosConvPixelsRGBS48(int w, int h, int16 *src, uint16 *dst) { - unsigned char r, g, b; - int i; - - for(i = 0; i < w * h; i++) { - r = ((src[i * 3 + 0] + S16_NEG_OFT) * RGB5_MAX) / RGB16_MAX; - g = ((src[i * 3 + 1] + S16_NEG_OFT) * RGB6_MAX) / RGB16_MAX; - b = ((src[i * 3 + 2] + S16_NEG_OFT) * RGB5_MAX) / RGB16_MAX; - - dst[i] = _glKosConvPixelRGBU24(r, g, b); - } -} - -static void _glKosConvPixelsRGBAS64(int w, int h, int16 *src, uint16 *dst) { - unsigned char r, g, b, a; - int i; - - for(i = 0; i < w * h; i++) { - r = ((src[i * 4 + 0] + S16_NEG_OFT) * RGB4_MAX) / RGB16_MAX; - g = ((src[i * 4 + 1] + S16_NEG_OFT) * RGB4_MAX) / RGB16_MAX; - b = ((src[i * 4 + 2] + S16_NEG_OFT) * RGB4_MAX) / RGB16_MAX; - a = ((src[i * 4 + 3] + S16_NEG_OFT) * RGB4_MAX) / RGB16_MAX; - - dst[i] = _glKosConvPixelRGBAU32(r, g, b, a); - } -} - -static void _glKosConvPixelsRGBU48(int w, int h, uint16 *src, uint16 *dst) { - unsigned char r, g, b; - int i; - - for(i = 0; i < w * h; i++) { - r = ((src[i * 3 + 0]) * RGB5_MAX) / RGB16_MAX; - g = ((src[i * 3 + 1]) * RGB6_MAX) / RGB16_MAX; - b = ((src[i * 3 + 2]) * RGB5_MAX) / RGB16_MAX; - - dst[i] = _glKosConvPixelRGBU24(r, g, b); - } -} - -static void _glKosConvPixelsRGBAU64(int w, int h, uint16 *src, uint16 *dst) { - unsigned char r, g, b, a; - int i; - - for(i = 0; i < w * h; i++) { - r = (src[i * 4 + 0] * RGB4_MAX) / RGB16_MAX; - g = (src[i * 4 + 1] * RGB4_MAX) / RGB16_MAX; - b = (src[i * 4 + 2] * RGB4_MAX) / RGB16_MAX; - a = (src[i * 4 + 3] * RGB4_MAX) / RGB16_MAX; - - dst[i] = _glKosConvPixelRGBAU32(r, g, b, a); - } -} - -void _glKosPixelConvertRGB(int format, int w, int h, void *src, uint16 *dst) { - switch(format) { - case GL_BYTE: - _glKosConvPixelsRGBS24(w, h, (int8 *)src, dst); - break; - - case GL_UNSIGNED_BYTE: - _glKosConvPixelsRGBU24(w, h, (uint8 *)src, dst); - break; - - case GL_SHORT: - _glKosConvPixelsRGBS48(w, h, (int16 *)src, dst); - break; - - case GL_UNSIGNED_SHORT: - _glKosConvPixelsRGBU48(w, h, (uint16 *)src, dst); - break; - - case GL_FLOAT: - _glKosConvPixelsRGBF(w, h, (float *)src, dst); - break; - } -} - -void _glKosPixelConvertRGBA(int format, int w, int h, void *src, uint16 *dst) { - switch(format) { - case GL_BYTE: - _glKosConvPixelsRGBAS32(w, h, (int8 *)src, dst); - break; - - case GL_UNSIGNED_BYTE: - _glKosConvPixelsRGBAU32(w, h, (uint8 *)src, dst); - break; - - case GL_SHORT: - _glKosConvPixelsRGBAS64(w, h, (int16 *)src, dst); - break; - - case GL_UNSIGNED_SHORT: - _glKosConvPixelsRGBAU64(w, h, (uint16 *)src, dst); - break; - - case GL_FLOAT: - _glKosConvPixelsRGBAF(w, h, (float *)src, dst); - break; - } -} diff --git a/gl-rgb.h b/gl-rgb.h deleted file mode 100644 index 847078a..0000000 --- a/gl-rgb.h +++ /dev/null @@ -1,70 +0,0 @@ -/* KallistiGL for KallistiOS ##version## - - libgl/gl-rgb.h - Copyright (C) 2013-2015 Josh Pearson - - A set of functions for working with ARGB pixel data. -*/ - -#ifndef GL_RGB_H -#define GL_RGB_H - -typedef GLubyte GLrgb3ub[3]; -typedef GLubyte GLrgba4ub[3]; -typedef GLfloat GLrgb3f[3]; -typedef GLfloat GLrgba4f[4]; - -#define RGB565_RED_MASK 0xF800 -#define RGB565_GREEN_MASK 0x7E0 -#define RGB565_BLUE_MASK 0x1F - -#define RGB565_RED_SHIFT 0xB -#define RGB565_GREEN_SHIFT 0x5 -#define RGB565_BLUE_SHIFT 0x0 - -#define ARGB4444_ALPHA_MASK 0xF000 -#define ARGB4444_RED_MASK 0x0F00 -#define ARGB4444_GREEN_MASK 0x00F0 -#define ARGB4444_BLUE_MASK 0x000F - -#define ARGB4444_ALPHA_SHIFT 0xC -#define ARGB4444_RED_SHIFT 0x8 -#define ARGB4444_GREEN_SHIFT 0x4 -#define ARGB4444_BLUE_SHIFT 0x0 - -#define ARGB1555_ALPHA_MASK 0x8000 -#define ARGB1555_RED_MASK 0x7C00 -#define ARGB1555_GREEN_MASK 0x3E0 -#define ARGB1555_BLUE_MASK 0x1F - -#define ARGB1555_ALPHA_SHIFT 0xF -#define ARGB1555_RED_SHIFT 0xA -#define ARGB1555_GREEN_SHIFT 0x5 -#define ARGB1555_BLUE_SHIFT 0x0 - -#define ARGB32_ALPHA_MASK 0xFF000000 -#define ARGB32_RGB_MASK 0xFFFFFF -#define ARGB32_RED_SHIFT 0x8 - -#define RGBA32_APLHA_MASK 0xFF -#define RGBA32_RGB_MASK 0xFFFFFF00 - -#define RGB1_MAX 0x1 -#define RGB4_MAX 0xF -#define RGB5_MAX 0x1F -#define RGB6_MAX 0x3F -#define RGB8_MAX 0xFF -#define RGB16_MAX 0xFFFF - -#define RGBA32_2_ARGB32(n) (((n & ARGB32_RGB_MASK) << ARGB32_RED_SHIFT) | (n & ARGB32_ALPHA_MASK)) - -#define ARGB_PACK_RGBF(r,g,b) (0xFF000000 | ((r*0xFF) << 16) | ((g*0xFF)<<8) | (b*0xFF)) -#define ARGB_PACK_ARGBF(a,r,g,b) (((a*0xFF) << 24) | ((r*0xFF) << 16) | ((g*0xFF)<<8) | (b*0xFF)) - -#define S8_NEG_OFT 128 // Absolute Value of Minimum 8bit Signed Range // -#define S16_NEG_OFT 32768 // Absolute Value of Minimum 16bit Signed Range // - -void _glKosPixelConvertRGB(int format, int w, int h, void *src, uint16 *dst); -void _glKosPixelConvertRGBA(int format, int w, int h, void *src, uint16 *dst); - -#endif diff --git a/gl-sh4-light.S b/gl-sh4-light.S deleted file mode 100644 index 6a761a5..0000000 --- a/gl-sh4-light.S +++ /dev/null @@ -1,209 +0,0 @@ -/* KallistiGL for KallistiOS ##version## - - libgl/gl-sh4-light.S - Copyright (C) 2013-2014 Josh Pearson - - Dynamic Vertex Lighting - - This Assembly file contains 2 functions: - _glKosSpotLight - This function computes diffuse / spotlight / attenuation - _glKosSpecular - This functions computes the Specular Term -*/ - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -!float _glKosSpecular( void * vertex6f, void * eyepos, void * Lvectorin ); -.globl __glKosSpecular - -!r4 = [arg][void*] = vertex -!r5 = [arg][void*] = eyepos -!r6 = [arg][void*] = L vector - -!fr0 = return value -!fv0 = vertex position (P)(N) -!fv4 = eye position (E) -!fv8 = L vector (L) - -__glKosSpecular: - - fmov @r4+, fr0 ! load vertex x to fv0 - fmov @r4+, fr1 ! load vertex y to fv0 - fmov @r4+, fr2 ! load vertex z to fv0 - - fmov @r5+, fr4 ! load eye pos x to fv4 - fmov @r5+, fr5 ! load eye pos y to fv4 - fmov @r5+, fr6 ! load eye pos z to fv4 - - fmov @r6+, fr8 ! load L vector x to fv8 - fmov @r6+, fr9 ! load L vector y to fv8 - fmov @r6+, fr10 ! load L vector z to fv8 - - fsub fr0, fr4 ! fv4 = V = normalize ( E - P ) - fsub fr1, fr5 - fsub fr2, fr6 - fldi0 fr3 ! load 0 for P w - fldi0 fr7 ! load 0 for E w - - fipr fv4, fv4 ! Normalize V vector - fsrra fr7 - fmul fr7, fr4 - fmul fr7, fr5 - fmul fr7, fr6 - - fadd fr4, fr8 ! fv8 = H = normalize( L + V ) - fadd fr5, fr9 - fadd fr6, fr10 - fldi0 fr11 ! load 0 for H w - - fipr fv8, fv8 ! Normalize H vector - fsrra fr11 - fmul fr11, fr8 - fmul fr11, fr9 - fmul fr11, fr10 - - fmov @r4+, fr0 ! load N to fv0 - fmov @r4+, fr1 - fmov @r4+, fr2 - - fipr fv0, fv8 ! N dot H for specular term - - rts - fmov fr11, fr0 ! move N dot H to fr0 for return - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - -!int _glKosSpotlight( void * glLight, void * vertex6f, void * Lvectorout ); -.globl __glKosSpotlight - -!r0 = return value | true or false -!r1 = boolean flag -!r2 = boolean false -!r4 = [arg] = light -!r5 = [arg] = vertex -!r6 = [arg] = output - -!fv0 = vertex position -!fv4 = light position | L vector | normalize(light pos - vertex pos) | w = attenuation distance -!fv8 = light direction | N vector = Vertex Normal -!fv12 = Spot vector | normalize(vertex pos - light pos) - -__glKosSpotlight: - - mov #0, r1 ! load 0 for boolean flag - mov #0, r2 ! load 0 for boolean false - - fmov @r4+, fr4 ! load light position x to fv4 - fmov @r4+, fr5 ! load light position y to fv4 - fmov @r4+, fr6 ! load light position z to fv4 - fmov @r4+, fr7 ! load light position w to fv4 - - fmov @r4+, fr8 ! load light direction x to fv8 - fmov @r4+, fr9 ! load light direction y to fv8 - fmov @r4+, fr10 ! load light direction z to fv8 - - fmov @r5+, fr0 ! load vertex position x to fv0 - fmov @r5+, fr1 ! load vertex position y to fv0 - fmov @r5+, fr2 ! load vertex position z to fv0 - - fldi0 fr11 ! load 0 for light dir w - fcmp/gt fr11, fr7 ! light pos w component set = spot light - bf .VERTEXLIGHT0 ! light not a spot light - branch to vertex lighting - - fschg - fmov dr0, dr12 ! copy vertex x,y to fv12 - fschg - fmov fr2, fr14 ! copy vertex z to fv12 - - fsub fr4, fr12 ! fv12 = ( vertex position - light position) - fsub fr5, fr13 - fsub fr6, fr14 - fldi0 fr15 ! set fv12 w component to 0 - - fipr fv12, fv12 ! Normalize vector - fsrra fr15 - fmul fr15, fr12 - fmul fr15, fr13 - fmul fr15, fr14 - - fldi0 fr15 ! set fv12 w component to 0 - fipr fv12, fv8 ! fr11 now holds light cosDir - - fmov @r4+, fr15 ! load light cutOff to fr15 - mov #1, r1 ! load 1 for boolean flag = indicate light cutOff was read - - fcmp/gt fr15, fr11 ! cosDir > cutOff ? 0 : 1 - bt .RET0spot ! vertex outside of spotlight = return 0 - -.VERTEXLIGHT0: - - fsub fr0, fr4 ! fv4 = L vector = ( light position - vertex position) - fsub fr1, fr5 - fsub fr2, fr6 - fldi0 fr7 ! load 0 for L w - fldi0 fr11 ! load 0 for N w - - fipr fv4, fv4 ! Normalize L vector - fsrra fr7 - fmul fr7, fr4 - fmul fr7, fr5 - fmul fr7, fr6 ! fv4 = Normalized L Vector - - fmov fr7, fr3 ! copy L w to fr3 - - fldi0 fr7 ! load 0 for L w - - fcmp/gt fr7, fr3 - bf .RET0spot ! if L w < 0, return 0 now to avoid pointless computations - - fmov @r5+, fr8 ! load normal to fv8 - fmov @r5+, fr9 ! load normal to fv8 - fmov @r5+, fr10 ! load normal to fv8 - - fipr fv8, fv4 ! N dot L - - fcmp/gt fr11, fr7 ! L w < = 0 ? L w = 0 - bf .RET0spot: ! if L w < 0, return 0 now to avoid pointless computations - -.WRITEDi: - - fschg - fmov dr4, @r6 ! write L vector x to output - fschg - add #8, r6 - fmov fr6, @r6 ! write L vector z to output - add #4, r6 - - cmp/gt r2, r1 - bt .READattenf - - add #4, r4 - -.READattenf: - - fmov @r4+, fr8 ! vertex normal gets overwritten by atten factors - fmov @r4+, fr9 - fmov @r4+, fr10 - fldi1 fr11 - - fmul fr3, fr9 ! calculate attenuation - fmul fr3, fr10 - fmul fr3, fr10 - fadd fr9, fr8 - fadd fr10, fr8 - fdiv fr8, fr11 ! fr11 = A - - fmul fr7, fr11 ! D * A - - fmov fr11, @r6 ! write D*A to output - -.RET1spot: - - rts - mov #1, r0 - -.RET0spot: - - rts - mov #0, r0 - -!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! diff --git a/gl-sh4.h b/gl-sh4.h deleted file mode 100644 index 488effd..0000000 --- a/gl-sh4.h +++ /dev/null @@ -1,86 +0,0 @@ -/* KallistiGL for KallistiOS ##version## - - libgl/gl-sh4.h - Copyright (C) 2013-2014 Josh Pearson - - Macros for utilizing the Dreamcast's SH4 CPU vector / matrix math functions. -*/ - -#ifndef GL_SH4_H -#define GL_SH4_H - -typedef float vector3f[3]; /* 3 float vector */ -typedef float matrix4f[4][4]; /* 4x4 float matrix */ - -/* DEG2RAD - convert Degrees to Radians = PI / 180.0f */ -#define DEG2RAD (0.01745329251994329576923690768489) - -/* Calculate Spot Light Angle Cosine = (PI / 180.0f) * (n / 2) */ -#define LCOS(n) fcos(n*0.00872664625997164788461845384244) - -/* Internal GL API macro */ -#define mat_trans_fv12() { \ - __asm__ __volatile__( \ - "fldi1 fr15\n" \ - "ftrv xmtrx, fv12\n" \ - "fldi1 fr14\n" \ - "fdiv fr15, fr14\n" \ - "fmul fr14, fr12\n" \ - "fmul fr14, fr13\n" \ - : "=f" (__x), "=f" (__y), "=f" (__z) \ - : "0" (__x), "1" (__y), "2" (__z) \ - : "fr15" ); \ - } - -/* Internal GL API macro */ -#define mat_trans_fv12_nodiv() { \ - __asm__ __volatile__( \ - "fldi1 fr15\n" \ - "ftrv xmtrx, fv12\n" \ - : "=f" (__x), "=f" (__y), "=f" (__z) \ - : "0" (__x), "1" (__y), "2" (__z) ); \ - } - -#define mat_trans_fv12_nodivw() { \ - __asm__ __volatile__( \ - "fldi1 fr15\n" \ - "ftrv xmtrx, fv12\n" \ - : "=f" (__x), "=f" (__y), "=f" (__z), "=f" (__w) \ - : "0" (__x), "1" (__y), "2" (__z), "3" (__w) ); \ - } - -#define mat_trans_texture4(s, t, r, q) { \ - register float __s __asm__("fr4") = (s); \ - register float __t __asm__("fr5") = (t); \ - register float __r __asm__("fr6") = (r); \ - register float __q __asm__("fr7") = (q); \ - __asm__ __volatile__( \ - "ftrv xmtrx,fv4\n" \ - "fldi1 fr6\n" \ - "fdiv fr7,fr6\n" \ - "fmul fr6,fr4\n" \ - "fmul fr6,fr5\n" \ - : "=f" (__s), "=f" (__t), "=f" (__r) \ - : "0" (__s), "1" (__t), "2" (__r) \ - : "fr7" ); \ - s = __s; t = __t; r = __r; \ - } - -#define mat_trans_texture2_nomod(s, t, so, to) { \ - register float __s __asm__("fr4") = (s); \ - register float __t __asm__("fr5") = (t); \ - __asm__ __volatile__( \ - "fldi0 fr6\n" \ - "fldi1 fr7\n" \ - "ftrv xmtrx,fv4\n" \ - "fldi1 fr6\n" \ - "fdiv fr7,fr6\n" \ - "fmul fr6,fr4\n" \ - "fmul fr6,fr5\n" \ - : "=f" (__s), "=f" (__t) \ - : "0" (__s), "1" (__t) \ - : "fr7" ); \ - so = __s; to = __t; \ - } - -#endif diff --git a/glu-texture.c b/glu-texture.c deleted file mode 100644 index 6e5c00f..0000000 --- a/glu-texture.c +++ /dev/null @@ -1,115 +0,0 @@ -/* KallistiGL for KallistiOS ##version## - - libgl/glu-texture.c - Copyright (C) 2013-2014 Josh Pearson - - A set of functions for working with ARGB pixel data. -*/ - -#include "gl.h" -#include "gl-api.h" -#include "gl-rgb.h" -#include "glu.h" - -GLAPI GLuint APIENTRY glKosMipMapTexSize(GLuint width, GLuint height) { - GLuint b = 0; - - while(width >= 1 && height >= 1) { - b += width * height * 2; - - if(width >= 1) - width /= 2; - - if(height >= 1) - height /= 2; - } - - return b; -} - -static GLint gluBuild2DBiMipmaps(GLenum target, GLint internalFormat, GLsizei width, - GLsizei height, GLenum format, GLenum type, const void *data) { - if(target != GL_TEXTURE_2D) - return -1; - - if(width < 1 || height < 1) - return 0; - - uint32 i = 0; - uint16 x , y; - - uint16 *src = (uint16 *)data; - uint16 *dst = (uint16 *)data + (width * height); - - for(y = 0; y < height; y += 2) { - for(x = 0; x < width; x += 2) { - switch(type) { - case GL_UNSIGNED_SHORT_5_6_5: - dst[i++] = __glKosAverageBiPixelRGB565(*src, *(src + 1)); - break; - - case GL_UNSIGNED_SHORT_4_4_4_4: - dst[i++] = __glKosAverageBiPixelARGB4444(*src, *(src + 1)); - break; - - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - dst[i++] = __glKosAverageBiPixelARGB1555(*src, *(src + 1)); - break; - } - - src += 2; - } - - src += width; - } - - return gluBuild2DBiMipmaps(target, internalFormat, width / 2, height / 2, - format, type, (uint16 *)data + (width * height)); -} - -GLint APIENTRY gluBuild2DMipmaps(GLenum target, GLint internalFormat, GLsizei width, - GLsizei height, GLenum format, GLenum type, const void *data) { - if(target != GL_TEXTURE_2D) - return -1; - - if(type != GL_UNSIGNED_SHORT_5_6_5 && type != GL_UNSIGNED_SHORT_4_4_4_4 - && type != GL_UNSIGNED_SHORT_1_5_5_5_REV) - return -1; - - if(width < 1 || height < 1) - return 0; - - if(width == 1 || height == 1) - return gluBuild2DBiMipmaps(target, internalFormat, width, height, format, type, data); - - uint32 i = 0; - uint16 x, y; - - uint16 *src = (uint16 *)data; - uint16 *dst = (uint16 *)data + (width * height); - - for(y = 0; y < height; y += 2) { - for(x = 0; x < width; x += 2) { - switch(type) { - case GL_UNSIGNED_SHORT_5_6_5: - dst[i++] = __glKosAverageQuadPixelRGB565(*src, *(src + 1), *(src + width), *(src + width + 1)); - break; - - case GL_UNSIGNED_SHORT_4_4_4_4: - dst[i++] = __glKosAverageQuadPixelARGB4444(*src, *(src + 1), *(src + width), *(src + width + 1)); - break; - - case GL_UNSIGNED_SHORT_1_5_5_5_REV: - dst[i++] = __glKosAverageQuadPixelARGB1555(*src, *(src + 1), *(src + width), *(src + width + 1)); - break; - } - - src += 2; - } - - src += width; - } - - return gluBuild2DMipmaps(target, internalFormat, width / 2, height / 2, - format, type, (uint16 *)data + (width * height)); -} diff --git a/include/gl.h b/include/gl.h index eb9dc46..7e4701c 100644 --- a/include/gl.h +++ b/include/gl.h @@ -642,14 +642,6 @@ GLAPI const GLbyte* APIENTRY glGetString(GLenum name); GLAPI void APIENTRY glActiveTextureARB(GLenum texture); GLAPI void APIENTRY glClientActiveTextureARB(GLenum texture); -/* Frame Buffer Objects / Render-To-Texture Functions */ -GLAPI void APIENTRY glGenFramebuffers(GLsizei n, GLuint *framebuffers); -GLAPI void APIENTRY glDeleteFramebuffers(GLsizei n, GLuint *framebuffers); -GLAPI void APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer); -GLAPI void APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, - GLenum textarget, GLuint texture, GLint level); -GLAPI GLenum APIENTRY glCheckFramebufferStatus(GLenum target); - /* Error handling */ GLAPI GLenum APIENTRY glGetError(void); diff --git a/include/glkos.h b/include/glkos.h index 1743a02..7bdd2fe 100644 --- a/include/glkos.h +++ b/include/glkos.h @@ -7,6 +7,14 @@ __BEGIN_DECLS GLAPI void APIENTRY glKosSwapBuffers(); +GLAPI void APIENTRY glGenFramebuffersEXT(GLsizei n, GLuint* framebuffers); +GLAPI void APIENTRY glDeleteFramebuffersEXT(GLsizei n, const GLuint* framebuffers); +GLAPI void APIENTRY glBindFramebufferEXT(GLenum target, GLuint framebuffer); +GLAPI void APIENTRY glFramebufferTexture2DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLAPI void APIENTRY glGenerateMipmapEXT(GLenum target); +GLAPI GLenum APIENTRY glCheckFramebufferStatusEXT(GLenum target); +GLAPI GLboolean APIENTRY glIsFramebufferEXT(GLuint framebuffer); + __END_DECLS #endif // GLKOS_H