From 763ec9948364538cacef45526e1e1ce785c11f18 Mon Sep 17 00:00:00 2001 From: Josh Pearson Date: Sun, 4 Jan 2015 15:07:57 -0800 Subject: [PATCH] Added multi-texture support and glCompressedTexImage2D to the GL API --- Makefile | 4 +- gl-api.c | 91 ++++-- gl-api.h | 54 +++- gl-arrays.c | 738 +++++++++++++++++++++++++++++------------------ gl-arrays.h | 35 +-- gl-cap.c | 4 +- gl-clip-arrays.c | 418 +++++++++++++++++++++++++++ gl-clip.c | 621 ++++++--------------------------------- gl-clip.h | 10 +- gl-light.c | 8 +- gl-matrix.c | 3 +- gl-pvr.c | 121 ++++++-- gl-pvr.h | 10 +- gl-texture.c | 144 ++++++--- include/gl.h | 73 +++-- include/glext.h | 78 ++++- include/glu.h | 2 +- include/glut.h | 4 +- 18 files changed, 1429 insertions(+), 989 deletions(-) create mode 100755 gl-clip-arrays.c diff --git a/Makefile b/Makefile index 246c828..53b3f5d 100755 --- a/Makefile +++ b/Makefile @@ -5,8 +5,8 @@ # Copyright (C) 2014 Lawrence Sebald TARGET = libgl.a -OBJS = gl-rgb.o gl-fog.o gl-sh4-light.o gl-light.o gl-clip.o gl-pvr.o -OBJS += gl-arrays.o gl-matrix.o gl-api.o gl-texture.o glu-texture.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 gl-texture.o glu-texture.o OBJS += gl-framebuffer.o gl-cap.o gl-error.o SUBDIRS = diff --git a/gl-api.c b/gl-api.c index 31ddbd7..b9fae8c 100755 --- a/gl-api.c +++ b/gl-api.c @@ -290,25 +290,25 @@ void APIENTRY glVertex2fv(const GLfloat *xy) { } void APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) { - pvr_vertex_t * v = _glKosVertexBufPointer(); - + 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(); + + _glKosFinishRect(); } void APIENTRY glRectfv(const GLfloat *v1, const GLfloat *v2) { - pvr_vertex_t * v = _glKosVertexBufPointer(); - + 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(); + + _glKosFinishRect(); } void APIENTRY glRecti(GLint x1, GLint y1, GLint x2, GLint y2) { @@ -582,46 +582,46 @@ void _glKosVertex3fcv(const GLfloat *xyz) { /* GL_POINTS */ GLvoid _glKosVertex3fp(GLfloat x, GLfloat y, GLfloat z) { - pvr_vertex_t * v = _glKosVertexBufPointer(); + 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(); + + _glKosFinishRect(); } GLvoid _glKosVertex3fpv(const GLfloat *xyz) { - pvr_vertex_t * v = _glKosVertexBufPointer(); + 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(); + + _glKosFinishRect(); } static inline void _glKosFinishRect() { - pvr_vertex_t * v = _glKosVertexBufPointer(); - + 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; + v[2].z = v[0].z; + + _glKosVertexBufAdd(4); + + GL_KOS_VERTEX_COUNT += 4; } void _glKosTransformClipBuf(pvr_vertex_t *v, GLuint verts) { @@ -732,6 +732,12 @@ 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(); @@ -777,9 +783,7 @@ void _glKosCompileHdrT(GL_TEXTURE_OBJECT *tex) { _glKosApplyBlendFunc(); - 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; + _glKosApplyTextureFunc(tex); if(_glKosEnabledBlend()) GL_KOS_POLY_CXT.txr.env = tex->env; @@ -792,6 +796,37 @@ void _glKosCompileHdrT(GL_TEXTURE_OBJECT *tex) { _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 b505649..9f3082f 100755 --- a/gl-api.h +++ b/gl-api.h @@ -10,11 +10,17 @@ #ifndef GL_API_H #define GL_API_H +#include "gl.h" + typedef struct { - float pos[3]; - float norm[3]; + 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 { GLushort width; GLushort height; @@ -35,8 +41,14 @@ typedef struct { GLvoid *link; } GL_FRAMEBUFFER_OBJECT; /* KOS Open GL Frame Buffer Object */ -typedef unsigned short uint16; -typedef unsigned char uint8; +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 */ inline void _glKosVertexBufSwitchOP(); @@ -54,6 +66,11 @@ inline unsigned int _glKosVertexBufCount(unsigned char list); unsigned char _glKosList(); inline void _glKosVertexBufCopy(void *src, void *dst, GLuint count); inline void _glKosResetEnabledTex(); +inline void *_glKosMultiUVBufAddress(); +inline void *_glKosMultiUVBufPointer(); +inline void _glKosMultiUVBufIncrement(); +inline void _glKosMultiUVBufAdd(GLuint count); +inline void _glKosMultiUVBufReset(); /* Vertex Clip Buffer Internal Functions */ inline void *_glKosClipBufAddress(); @@ -69,13 +86,14 @@ inline glVertex *_glKosArrayBufPtr(); /* Initialize the OpenGL PVR Pipeline */ int _glKosInitPVR(); -GLubyte _glKosInitTextures(); +unsigned char _glKosInitTextures(); /* Compile the current Polygon Header for the PVR */ void _glKosCompileHdr(); void _glKosCompileHdrTx(); -void _glKosCompileHdrTx2(); +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); @@ -84,10 +102,17 @@ unsigned int _glKosClipTriangles(pvr_vertex_t *vin, pvr_vertex_t *vout, unsigned 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 char _glKosClipTriTransformed(pvr_vertex_t *vin, float *w, pvr_vertex_t *vout); 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); @@ -176,5 +201,20 @@ GLubyte _glKosIsLightEnabled(GLubyte light); GLubyte _glKosGetMaxLights(); GLuint _glKosBoundTexID(); GLuint _glKosVertexColor(); +GLubyte _glKosMaxTextureUnits(); + +GL_TEXTURE_OBJECT *_glKosBoundMultiTexID(); + +inline 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; +} + +static inline void _glKosTexCoordCopy(const glTexCoord *src, glTexCoord *dst) { + *dst = *src; +} #endif diff --git a/gl-arrays.c b/gl-arrays.c index 248fbde..efdc366 100755 --- a/gl-arrays.c +++ b/gl-arrays.c @@ -19,21 +19,44 @@ #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 ==// -#define GL_MAX_ARRAY_VERTICES 1024*32 /* Maximum Number of Vertices in the Array Buffer */ -static glVertex GL_ARRAY_BUF[GL_MAX_ARRAY_VERTICES]; -static GLfloat GL_ARRAY_BUFW[GL_MAX_ARRAY_VERTICES]; -static GLfloat GL_ARRAY_DSTW[GL_MAX_ARRAY_VERTICES]; -static glVertex *GL_ARRAY_BUF_PTR; -static GLuint GL_VERTEX_PTR_MODE = 0; +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 GLfloat *GL_KOS_VERTEX_POINTER = NULL; +static GLfloat *GL_KOS_NORMAL_POINTER = NULL; +static GLfloat *GL_KOS_TEXCOORD0_POINTER = NULL; +static GLfloat *GL_KOS_TEXCOORD1_POINTER = NULL; +static GLfloat *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 ==// @@ -41,6 +64,12 @@ static GLubyte GL_KOS_VERTEX_SIZE = 0; static inline void _glKosArraysTransformNormals(GLfloat *normal, GLuint count); static inline void _glKosArraysTransformPositions(GLfloat *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); + //========================================================================================// //== Open GL API Public Functions ==// @@ -61,14 +90,14 @@ GLAPI void APIENTRY glVertexPointer(GLint size, GLenum type, _glKosPrintError(); return; } - - GL_KOS_VERTEX_SIZE = size; - - (stride) ? (GL_VERTEX_STRIDE = stride / 4) : (GL_VERTEX_STRIDE = 3); - - GL_VERTEX_POINTER = (float *)pointer; - GL_VERTEX_PTR_MODE |= GL_USE_ARRAY; + GL_KOS_VERTEX_SIZE = size; + + (stride) ? (GL_KOS_VERTEX_STRIDE = stride / 4) : (GL_KOS_VERTEX_STRIDE = 3); + + GL_KOS_VERTEX_POINTER = (float *)pointer; + + GL_KOS_VERTEX_PTR_MODE |= GL_KOS_USE_ARRAY; } /* Submit a Vertex Normal Pointer */ @@ -84,11 +113,11 @@ GLAPI void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *p return; } - (stride) ? (GL_NORMAL_STRIDE = stride / 4) : (GL_NORMAL_STRIDE = 3); + (stride) ? (GL_KOS_NORMAL_STRIDE = stride / 4) : (GL_KOS_NORMAL_STRIDE = 3); - GL_NORMAL_POINTER = (float *)pointer; + GL_KOS_NORMAL_POINTER = (float *)pointer; - GL_VERTEX_PTR_MODE |= GL_USE_NORMAL; + GL_KOS_VERTEX_PTR_MODE |= GL_KOS_USE_NORMAL; } /* Submit a Texture Coordinate Pointer */ @@ -108,35 +137,44 @@ GLAPI void APIENTRY glTexCoordPointer(GLint size, GLenum type, return; } - (stride) ? (GL_TEXCOORD_STRIDE = stride / 4) : (GL_TEXCOORD_STRIDE = 2); + if(GL_KOS_CLIENT_ACTIVE_TEXTURE) { + (stride) ? (GL_KOS_TEXCOORD1_STRIDE = stride / 4) : (GL_KOS_TEXCOORD1_STRIDE = 2); - GL_TEXCOORD_POINTER = (float *)pointer; + GL_KOS_TEXCOORD1_POINTER = (float *)pointer; - GL_VERTEX_PTR_MODE |= GL_USE_TEXTURE; + GL_KOS_VERTEX_PTR_MODE |= GL_KOS_USE_TEXTURE1; + } + else { + (stride) ? (GL_KOS_TEXCOORD0_STRIDE = stride / 4) : (GL_KOS_TEXCOORD0_STRIDE = 2); + + GL_KOS_TEXCOORD0_POINTER = (float *)pointer; + + GL_KOS_VERTEX_PTR_MODE |= GL_KOS_USE_TEXTURE0; + } } /* 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_COLOR_COMPONENTS = 1; - GL_COLOR_POINTER = (GLvoid *)pointer; - GL_COLOR_TYPE = type; + GL_KOS_COLOR_COMPONENTS = 1; + GL_KOS_COLOR_POINTER = (GLvoid *)pointer; + GL_KOS_COLOR_TYPE = type; } else if((type == GL_UNSIGNED_BYTE) && (size == 4)) { - GL_COLOR_COMPONENTS = 4; - GL_COLOR_POINTER = (GLvoid *)pointer; - GL_COLOR_TYPE = type; + GL_KOS_COLOR_COMPONENTS = 4; + GL_KOS_COLOR_POINTER = (GLvoid *)pointer; + GL_KOS_COLOR_TYPE = type; } else if((type == GL_FLOAT) && (size == 3)) { - GL_COLOR_COMPONENTS = 3; - GL_COLOR_POINTER = (GLfloat *)pointer; - GL_COLOR_TYPE = type; + GL_KOS_COLOR_COMPONENTS = 3; + GL_KOS_COLOR_POINTER = (GLfloat *)pointer; + GL_KOS_COLOR_TYPE = type; } else if((type == GL_FLOAT) && (size == 4)) { - GL_COLOR_COMPONENTS = 4; - GL_COLOR_POINTER = (GLfloat *)pointer; - GL_COLOR_TYPE = type; + GL_KOS_COLOR_COMPONENTS = 4; + GL_KOS_COLOR_POINTER = (GLfloat *)pointer; + GL_KOS_COLOR_TYPE = type; } else { _glKosThrowError(GL_INVALID_ENUM, "glColorPointer"); @@ -144,31 +182,31 @@ GLAPI void APIENTRY glColorPointer(GLint size, GLenum type, return; } - (stride) ? (GL_COLOR_STRIDE = stride / 4) : (GL_COLOR_STRIDE = size); + (stride) ? (GL_KOS_COLOR_STRIDE = stride / 4) : (GL_KOS_COLOR_STRIDE = size); - GL_VERTEX_PTR_MODE |= GL_USE_COLOR; + GL_KOS_VERTEX_PTR_MODE |= GL_KOS_USE_COLOR; } //========================================================================================// //== Vertex Pointer Internal API ==// inline void _glKosArrayBufIncrement() { - ++GL_ARRAY_BUF_PTR; + ++GL_KOS_ARRAY_BUF_PTR; } inline void _glKosArrayBufReset() { - GL_ARRAY_BUF_PTR = &GL_ARRAY_BUF[0]; + GL_KOS_ARRAY_BUF_PTR = &GL_KOS_ARRAY_BUF[0]; } inline glVertex *_glKosArrayBufAddr() { - return &GL_ARRAY_BUF[0]; + return &GL_KOS_ARRAY_BUF[0]; } inline glVertex *_glKosArrayBufPtr() { - return GL_ARRAY_BUF_PTR; + return GL_KOS_ARRAY_BUF_PTR; } static inline void _glKosArraysTransformNormals(GLfloat *normal, GLuint count) { - glVertex *v = &GL_ARRAY_BUF[0]; + glVertex *v = &GL_KOS_ARRAY_BUF[0]; GLfloat *N = normal; _glKosMatrixLoadModelRot(); @@ -181,7 +219,7 @@ static inline void _glKosArraysTransformNormals(GLfloat *normal, GLuint count) { } static inline void _glKosArraysTransformPositions(GLfloat *position, GLuint count) { - glVertex *v = &GL_ARRAY_BUF[0]; + glVertex *v = &GL_KOS_ARRAY_BUF[0]; GLfloat *P = position; _glKosMatrixLoadModelView(); @@ -196,13 +234,13 @@ static inline void _glKosArraysTransformPositions(GLfloat *position, GLuint coun //========================================================================================// //== Arrays Vertex Transform ==/ static void _glKosArraysTransform2D(GLuint count) { - GLfloat *src = GL_VERTEX_POINTER; + GLfloat *src = GL_KOS_VERTEX_POINTER; pvr_vertex_t *dst = _glKosVertexBufPointer(); register float __x __asm__("fr12"); register float __y __asm__("fr13"); register float __z __asm__("fr14"); - + while(count--) { __x = src[0]; __y = src[1]; @@ -215,19 +253,19 @@ static void _glKosArraysTransform2D(GLuint count) { dst->z = __z; ++dst; - - src += GL_VERTEX_STRIDE; + + src += GL_KOS_VERTEX_STRIDE; } } static void _glKosArraysTransform(GLuint count) { - GLfloat *src = GL_VERTEX_POINTER; + GLfloat *src = GL_KOS_VERTEX_POINTER; pvr_vertex_t *dst = _glKosVertexBufPointer(); register float __x __asm__("fr12"); register float __y __asm__("fr13"); register float __z __asm__("fr14"); - + while(count--) { __x = src[0]; __y = src[1]; @@ -240,14 +278,14 @@ static void _glKosArraysTransform(GLuint count) { dst->z = __z; ++dst; - - src += GL_VERTEX_STRIDE; + + src += GL_KOS_VERTEX_STRIDE; } } static void _glKosArraysTransformClip(GLuint count) { - GLfloat *src = GL_VERTEX_POINTER; - GLfloat *W = GL_ARRAY_DSTW; + GLfloat *src = GL_KOS_VERTEX_POINTER; + GLfloat *W = GL_KOS_ARRAY_DSTW; pvr_vertex_t *dst = _glKosClipBufAddress(); register float __x __asm__("fr12"); @@ -266,23 +304,21 @@ static void _glKosArraysTransformClip(GLuint count) { dst->y = __y; dst->z = __z; *W++ = __w; - + ++dst; - - src += GL_VERTEX_STRIDE; + + src += GL_KOS_VERTEX_STRIDE; } } static void _glKosArraysTransformElements(GLuint count) { - GLfloat *src = GL_VERTEX_POINTER; + GLfloat *src = GL_KOS_VERTEX_POINTER; GLuint i = 0; register float __x __asm__("fr12"); register float __y __asm__("fr13"); register float __z __asm__("fr14"); - printf("Transform Elements()\n"); - for(i = 0; i < count; i++) { __x = src[0]; __y = src[1]; @@ -290,16 +326,16 @@ static void _glKosArraysTransformElements(GLuint count) { mat_trans_fv12() - GL_ARRAY_BUF[i].pos[0] = __x; - GL_ARRAY_BUF[i].pos[1] = __y; - GL_ARRAY_BUF[i].pos[2] = __z; + 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_VERTEX_STRIDE; + src += GL_KOS_VERTEX_STRIDE; } } static void _glKosArraysTransformClipElements(GLuint count) { - GLfloat *src = GL_VERTEX_POINTER; + GLfloat *src = GL_KOS_VERTEX_POINTER; GLuint i; register float __x __asm__("fr12"); @@ -314,12 +350,12 @@ static void _glKosArraysTransformClipElements(GLuint count) { mat_trans_fv12_nodivw() - GL_ARRAY_BUF[i].pos[0] = __x; - GL_ARRAY_BUF[i].pos[1] = __y; - GL_ARRAY_BUF[i].pos[2] = __z; - GL_ARRAY_BUFW[i] = __w; + 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_VERTEX_STRIDE; + src += GL_KOS_VERTEX_STRIDE; } } @@ -328,49 +364,51 @@ static void _glKosArraysTransformClipElements(GLuint count) { //== Color ==// -static inline void _glKosElementColor0(pvr_vertex_t *dst, GLuint count) { +static inline void _glKosArrayColor0(pvr_vertex_t *dst, GLuint count) { GLuint i; - for(i = 0; i < count; i++) - dst[i].argb = _glKosVertexColor(); + 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 *src = (GLuint *)GL_COLOR_POINTER; + GLuint *src = (GLuint *)GL_KOS_COLOR_POINTER; for(i = 0; i < count; i++) - dst[i].argb = src[GL_INDEX_POINTER_U8[i] * GL_COLOR_STRIDE]; + dst[i].argb = src[GL_KOS_INDEX_POINTER_U8[i] * GL_KOS_COLOR_STRIDE]; } static inline void _glKosElementColor1uiU16(pvr_vertex_t *dst, GLuint count) { GLuint i; - GLuint *color = (GLuint *)GL_COLOR_POINTER; + GLuint *color = (GLuint *)GL_KOS_COLOR_POINTER; for(i = 0; i < count; i++) - dst[i].argb = color[GL_INDEX_POINTER_U16[i] * GL_COLOR_STRIDE]; + dst[i].argb = color[GL_KOS_INDEX_POINTER_U16[i] * GL_KOS_COLOR_STRIDE]; } static inline void _glKosElementColor4ubU8(pvr_vertex_t *dst, GLuint count) { - GLuint i, *color = (GLuint *)GL_COLOR_POINTER; + GLuint i, *color = (GLuint *)GL_KOS_COLOR_POINTER; for(i = 0; i < count; i++) - dst[i].argb = RGBA32_2_ARGB32(color[GL_INDEX_POINTER_U8[i]] * GL_COLOR_STRIDE); + dst[i].argb = RGBA32_2_ARGB32(color[GL_KOS_INDEX_POINTER_U8[i]] * GL_KOS_COLOR_STRIDE); } static inline void _glKosElementColor4ubU16(pvr_vertex_t *dst, GLuint count) { - GLuint i, *color = (GLuint *)GL_COLOR_POINTER; + GLuint i, *color = (GLuint *)GL_KOS_COLOR_POINTER; for(i = 0; i < count; i++) - dst[i].argb = RGBA32_2_ARGB32(color[GL_INDEX_POINTER_U16[i] * GL_COLOR_STRIDE]); + dst[i].argb = RGBA32_2_ARGB32(color[GL_KOS_INDEX_POINTER_U16[i] * GL_KOS_COLOR_STRIDE]); } static inline void _glKosElementColor3fU8(pvr_vertex_t *dst, GLuint count) { GLuint i, index; - GLrgb3f *color = (GLrgb3f *)GL_COLOR_POINTER; + GLrgb3f *color = (GLrgb3f *)GL_KOS_COLOR_POINTER; for(i = 0; i < count; i++) { - index = GL_INDEX_POINTER_U8[i] * GL_COLOR_STRIDE; + index = GL_KOS_INDEX_POINTER_U8[i] * GL_KOS_COLOR_STRIDE; dst[i].argb = (0xFF000000 | ((GLubyte)color[index][0] * 0xFF) << 16 | ((GLubyte)color[index][1] * 0xFF) << 8 | ((GLubyte)color[index][2] * 0xFF)); @@ -379,10 +417,10 @@ static inline void _glKosElementColor3fU8(pvr_vertex_t *dst, GLuint count) { static inline void _glKosElementColor3fU16(pvr_vertex_t *dst, GLuint count) { GLuint i, index; - GLrgb3f *color = (GLrgb3f *)GL_COLOR_POINTER; + GLrgb3f *color = (GLrgb3f *)GL_KOS_COLOR_POINTER; for(i = 0; i < count; i++) { - index = GL_INDEX_POINTER_U16[i] * GL_COLOR_STRIDE; + index = GL_KOS_INDEX_POINTER_U16[i] * GL_KOS_COLOR_STRIDE; dst[i].argb = (0xFF000000 | ((GLubyte)color[index][0] * 0xFF) << 16 | ((GLubyte)color[index][1] * 0xFF) << 8 | ((GLubyte)color[index][2] * 0xFF)); @@ -391,10 +429,10 @@ static inline void _glKosElementColor3fU16(pvr_vertex_t *dst, GLuint count) { static inline void _glKosElementColor4fU8(pvr_vertex_t *dst, GLuint count) { GLuint i, index; - GLrgba4f *color = (GLrgba4f *)GL_COLOR_POINTER; + GLrgba4f *color = (GLrgba4f *)GL_KOS_COLOR_POINTER; for(i = 0; i < count; i++) { - index = GL_INDEX_POINTER_U8[i] * GL_COLOR_STRIDE; + index = GL_KOS_INDEX_POINTER_U8[i] * GL_KOS_COLOR_STRIDE; dst[i].argb = (((GLubyte)color[index][3] * 0xFF) << 24 | ((GLubyte)color[index][0] * 0xFF) << 16 | ((GLubyte)color[index][1] * 0xFF) << 8 @@ -404,10 +442,10 @@ static inline void _glKosElementColor4fU8(pvr_vertex_t *dst, GLuint count) { static inline void _glKosElementColor4fU16(pvr_vertex_t *dst, GLuint count) { GLuint i, index; - GLrgba4f *color = (GLrgba4f *)GL_COLOR_POINTER; + GLrgba4f *color = (GLrgba4f *)GL_KOS_COLOR_POINTER; for(i = 0; i < count; i++) { - index = GL_INDEX_POINTER_U16[i] * GL_COLOR_STRIDE; + index = GL_KOS_INDEX_POINTER_U16[i] * GL_KOS_COLOR_STRIDE; dst[i].argb = (((GLubyte)color[index][3] * 0xFF) << 24 | ((GLubyte)color[index][0] * 0xFF) << 16 | ((GLubyte)color[index][1] * 0xFF) << 8 @@ -419,10 +457,10 @@ static inline void _glKosElementColor4fU16(pvr_vertex_t *dst, GLuint count) { static inline void _glKosElementTexCoord2fU16(pvr_vertex_t *dst, GLuint count) { GLuint i, index; - GLfloat *t = GL_TEXCOORD_POINTER; + GLfloat *t = GL_KOS_TEXCOORD0_POINTER; for(i = 0; i < count; i++) { - index = GL_INDEX_POINTER_U16[i] * GL_TEXCOORD_STRIDE; + index = GL_KOS_INDEX_POINTER_U16[i] * GL_KOS_TEXCOORD0_STRIDE; dst[i].u = t[index]; dst[i].v = t[index + 1]; } @@ -430,61 +468,119 @@ static inline void _glKosElementTexCoord2fU16(pvr_vertex_t *dst, GLuint count) { static inline void _glKosElementTexCoord2fU8(pvr_vertex_t *dst, GLuint count) { GLuint i, index; - GLfloat *t = GL_TEXCOORD_POINTER; + GLfloat *t = GL_KOS_TEXCOORD0_POINTER; for(i = 0; i < count; i++) { - index = GL_INDEX_POINTER_U8[i] * GL_TEXCOORD_STRIDE; + index = GL_KOS_INDEX_POINTER_U8[i] * GL_KOS_TEXCOORD0_STRIDE; dst[i].u = t[index]; dst[i].v = t[index + 1]; } } +static inline void _glKosElementMultiTexCoord2fU16C(GLuint count) { + GLuint i, index; + GLfloat *t = GL_KOS_TEXCOORD1_POINTER; + GLfloat *dst = GL_KOS_ARRAY_BUFUV; + + for(i = 0; i < count; i++) { + index = GL_KOS_INDEX_POINTER_U16[i] * GL_KOS_TEXCOORD1_STRIDE; + *dst++ = t[index]; + *dst++ = t[index + 1]; + } +} + +static inline void _glKosElementMultiTexCoord2fU8C(GLuint count) { + GLuint i, index; + GLfloat *t = GL_KOS_TEXCOORD1_POINTER; + GLfloat *dst = GL_KOS_ARRAY_BUFUV; + + for(i = 0; i < count; i++) { + index = GL_KOS_INDEX_POINTER_U8[i] * GL_KOS_TEXCOORD1_STRIDE; + *dst++ = t[index]; + *dst++ = t[index + 1]; + } +} + +static inline void _glKosElementMultiTexCoord2fU16(GLuint count) { + if(_glKosEnabledNearZClip()) + return _glKosElementMultiTexCoord2fU16C(count); + + GLuint i, index; + GLfloat *t = GL_KOS_TEXCOORD1_POINTER; + glTexCoord *dst = (glTexCoord *)_glKosMultiUVBufPointer(); + + for(i = 0; i < count; i++) { + index = GL_KOS_INDEX_POINTER_U16[i] * GL_KOS_TEXCOORD1_STRIDE; + dst[i].u = t[index]; + dst[i].v = t[index + 1]; + } + + _glKosMultiUVBufAdd(count); +} + +static inline void _glKosElementMultiTexCoord2fU8(GLuint count) { + if(_glKosEnabledNearZClip()) + return _glKosElementMultiTexCoord2fU8C(count); + + GLuint i, index; + GLfloat *t = GL_KOS_TEXCOORD1_POINTER; + glTexCoord *dst = (glTexCoord *)_glKosMultiUVBufPointer(); + + for(i = 0; i < count; i++) { + index = GL_KOS_INDEX_POINTER_U8[i] * GL_KOS_TEXCOORD1_STRIDE; + dst[i].u = t[index]; + dst[i].v = t[index + 1]; + } + + _glKosMultiUVBufAdd(count); +} + //========================================================================================// //== Element Unpacking ==// static inline void _glKosArraysUnpackElementsS16(pvr_vertex_t *dst, GLuint count) { - glVertex *vert = GL_ARRAY_BUF; + glVertex *vert = GL_KOS_ARRAY_BUF; GLuint i; for(i = 0; i < count; i++) { - dst[i].x = vert[GL_INDEX_POINTER_U16[i]].pos[0]; - dst[i].y = vert[GL_INDEX_POINTER_U16[i]].pos[1]; - dst[i].z = vert[GL_INDEX_POINTER_U16[i]].pos[2]; + 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_ARRAY_BUF; + glVertex *vert = GL_KOS_ARRAY_BUF; GLuint i; for(i = 0; i < count; i++) { - dst[i].x = vert[GL_INDEX_POINTER_U8[i]].pos[0]; - dst[i].y = vert[GL_INDEX_POINTER_U8[i]].pos[1]; - dst[i].z = vert[GL_INDEX_POINTER_U8[i]].pos[2]; + 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_ARRAY_BUF; + glVertex *vert = GL_KOS_ARRAY_BUF; GLuint i; for(i = 0; i < count; i++) { - dst[i].x = vert[GL_INDEX_POINTER_U16[i]].pos[0]; - dst[i].y = vert[GL_INDEX_POINTER_U16[i]].pos[1]; - dst[i].z = vert[GL_INDEX_POINTER_U16[i]].pos[2]; - GL_ARRAY_DSTW[i] = GL_ARRAY_BUFW[GL_INDEX_POINTER_U16[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_ARRAY_BUF; + glVertex *vert = GL_KOS_ARRAY_BUF; GLuint i; for(i = 0; i < count; i++) { - dst[i].x = vert[GL_INDEX_POINTER_U8[i]].pos[0]; - dst[i].y = vert[GL_INDEX_POINTER_U8[i]].pos[1]; - dst[i].z = vert[GL_INDEX_POINTER_U8[i]].pos[2]; - GL_ARRAY_DSTW[i] = GL_ARRAY_BUFW[GL_INDEX_POINTER_U8[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]]; } } @@ -497,8 +593,14 @@ static inline void _glKosVertexSwizzle(pvr_vertex_t *v1, pvr_vertex_t *v2) { *v2 = * &tmp; } +static inline void _glKosTexCoordSwizzle(glTexCoord *uv1, glTexCoord *uv2) { + glTexCoord tmp = *uv1; + *uv1 = *uv2; + *uv2 = * &tmp; +} + static inline void _glKosArraysResetState() { - GL_VERTEX_PTR_MODE = 0; + GL_KOS_VERTEX_PTR_MODE = 0; } //========================================================================================// @@ -532,8 +634,19 @@ static inline void _glKosArrayFlagsSetTriangleStrip(pvr_vertex_t *dst, GLuint co 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 Genration ==// +//== OpenGL Error Code Generation ==// static GLuint _glKosArraysVerifyParameter(GLenum mode, GLsizei count, GLenum type, GLubyte element) { if(mode != GL_QUADS) @@ -544,10 +657,10 @@ static GLuint _glKosArraysVerifyParameter(GLenum mode, GLsizei count, GLenum typ if(count < 0) _glKosThrowError(GL_INVALID_VALUE, "glDrawArrays"); - if(!(GL_VERTEX_PTR_MODE & GL_USE_ARRAY)) + if(!(GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_ARRAY)) _glKosThrowError(GL_INVALID_OPERATION, "glDrawArrays"); - if(count > GL_MAX_ARRAY_VERTICES) + if(count > GL_KOS_MAX_VERTS) _glKosThrowError(GL_OUT_OF_MEMORY, "glDrawArrays"); if(element) { @@ -562,16 +675,135 @@ static GLuint _glKosArraysVerifyParameter(GLenum mode, GLsizei count, GLenum typ } else if(type > count) _glKosThrowError(GL_INVALID_VALUE, "glDrawArrays"); - - if(_glKosGetError()) - { + + if(_glKosGetError()) { _glKosPrintError(); return 0; } - + return 1; } +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 _glKosArraysApplyMultiTexture(GLenum mode, GLuint count) { + if(GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_TEXTURE1) { + _glKosPushMultiTexObject(_glKosBoundMultiTexID(), + (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) { + 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); + + _glKosArraysResetState(); +} + //========================================================================================// //== OpenGL Elemental Array Submission ==// @@ -580,39 +812,30 @@ GLAPI void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, cons 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_INDEX_POINTER_U8 = (GLubyte *)indices; + GL_KOS_INDEX_POINTER_U8 = (GLubyte *)indices; break; case GL_UNSIGNED_SHORT: - GL_INDEX_POINTER_U16 = (GLushort *)indices; + GL_KOS_INDEX_POINTER_U16 = (GLushort *)indices; break; } - /* Compile the PVR polygon context with the currently enabled flags */ - if((GL_VERTEX_PTR_MODE & GL_USE_TEXTURE) && _glKosBoundTexID() > 0) - _glKosCompileHdrTx(); - else - _glKosCompileHdr(); - - pvr_vertex_t *dst; /* Destination of Output Vertex Array */ - - if(_glKosEnabledNearZClip()) - dst = _glKosClipBufAddress(); - else - dst = _glKosVertexBufPointer(); - /* Check if Vertex Lighting is enabled. Else, check for Color Submission */ - if((GL_VERTEX_PTR_MODE & GL_USE_NORMAL) && _glKosEnabledLighting()) { - _glKosArraysTransformNormals(GL_NORMAL_POINTER, count); - _glKosArraysTransformPositions(GL_VERTEX_POINTER, count); - _glKosVertexLights(GL_ARRAY_BUF, dst, count); - } - else if(GL_VERTEX_PTR_MODE & GL_USE_COLOR) { - switch(GL_COLOR_TYPE) { + 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_COLOR_COMPONENTS) { + switch(GL_KOS_COLOR_COMPONENTS) { case 3: switch(type) { case GL_UNSIGNED_BYTE: @@ -643,7 +866,7 @@ GLAPI void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, cons break; case GL_UNSIGNED_INT: - if(GL_COLOR_COMPONENTS == 1) + if(GL_KOS_COLOR_COMPONENTS == 1) switch(type) { case GL_UNSIGNED_BYTE: _glKosElementColor1uiU8(dst, count); @@ -657,7 +880,7 @@ GLAPI void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, cons break; case GL_UNSIGNED_BYTE: - if(GL_COLOR_COMPONENTS == 4) + if(GL_KOS_COLOR_COMPONENTS == 4) switch(type) { case GL_UNSIGNED_BYTE: _glKosElementColor4ubU8(dst, count); @@ -672,10 +895,10 @@ GLAPI void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, cons } } else - _glKosElementColor0(dst, count); /* No colors bound, color white */ + _glKosArrayColor0(dst, count); /* No colors bound */ /* Check if Texture Coordinates are enabled */ - if((GL_VERTEX_PTR_MODE & GL_USE_TEXTURE) && (_glKosEnabledTexture2D() >= 0)) + if((GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_TEXTURE0) && (_glKosEnabledTexture2D() >= 0)) switch(type) { case GL_UNSIGNED_BYTE: _glKosElementTexCoord2fU8(dst, count); @@ -686,10 +909,22 @@ GLAPI void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, cons 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 divde */ + /* Transform vertices with perspective divide */ _glKosArraysTransformElements(count); /* Unpack the indexed positions into primitives for rasterization */ @@ -704,22 +939,10 @@ GLAPI void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, cons } /* Set the vertex flags for use with the PVR */ - switch(mode) { - case GL_QUADS: - _glKosArrayFlagsSetQuad(dst, count); - break; - - case GL_TRIANGLES: - _glKosArrayFlagsSetTriangle(dst, count); - break; - - case GL_TRIANGLE_STRIP: - _glKosArrayFlagsSetTriangleStrip(dst, count); - break; - } + _glKosArraysApplyVertexFlags(mode, dst, count); } else { - /* Transform vertices with no perspective divde, store w component */ + /* Transform vertices with no perspective divide, store w component */ _glKosArraysTransformClipElements(count); /* Unpack the indexed positions into primitives for rasterization */ @@ -733,29 +956,12 @@ GLAPI void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, cons break; } - /* Finally, clip the input vertex data into the output vertex buffer */ - switch(mode) { - case GL_TRIANGLES: - count = _glKosClipTrianglesTransformed(dst, GL_ARRAY_DSTW, - (pvr_vertex_t *)_glKosVertexBufPointer(), count); - break; - - case GL_QUADS: - count = _glKosClipQuadsTransformed(dst, GL_ARRAY_DSTW, - (pvr_vertex_t *)_glKosVertexBufPointer(), count); - - break; - - case GL_TRIANGLE_STRIP: - count = _glKosClipTriangleStripTransformed(dst, GL_ARRAY_DSTW, - (pvr_vertex_t *)_glKosVertexBufPointer(), count); - break; - } + count = _glKosArraysApplyClipping(GL_KOS_ARRAY_BUFUV, 2, mode, count); } - _glKosVertexBufAdd(count); + _glKosArraysApplyMultiTexture(mode, count); - _glKosArraysResetState(); + _glKosArraysFlush(count); } //========================================================================================// @@ -763,54 +969,47 @@ GLAPI void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, cons //== Color ==// -static inline void _glKosArrayColor0(pvr_vertex_t *dst, GLuint count) { - GLuint i; - - for(i = 0; i < count; i++) - dst[i].argb = _glKosVertexColor(); -} - static inline void _glKosArrayColor1ui(pvr_vertex_t *dst, GLuint count) { GLuint i; - GLuint *color = (GLuint *)GL_COLOR_POINTER; + GLuint *color = (GLuint *)GL_KOS_COLOR_POINTER; for(i = 0; i < count; i++) { dst[i].argb = *color; - color += GL_COLOR_STRIDE; + color += GL_KOS_COLOR_STRIDE; } } static inline void _glKosArrayColor4ub(pvr_vertex_t *dst, GLuint count) { - GLuint i, *color = (GLuint *)GL_COLOR_POINTER; + GLuint i, *color = (GLuint *)GL_KOS_COLOR_POINTER; for(i = 0; i < count; i++) { dst[i].argb = RGBA32_2_ARGB32(*color); - color += GL_COLOR_STRIDE; + color += GL_KOS_COLOR_STRIDE; } } static inline void _glKosArrayColor3f(pvr_vertex_t *dst, GLuint count) { GLuint i; - GLfloat *color = (GLfloat *)GL_COLOR_POINTER; + GLfloat *color = (GLfloat *)GL_KOS_COLOR_POINTER; for(i = 0; i < count; i++) { dst[i].argb = (0xFF000000 | ((GLubyte)(color[0] * 0xFF)) << 16 | ((GLubyte)(color[1] * 0xFF)) << 8 | ((GLubyte)(color[2] * 0xFF))); - color += GL_COLOR_STRIDE; + color += GL_KOS_COLOR_STRIDE; } } static inline void _glKosArrayColor4f(pvr_vertex_t *dst, GLuint count) { GLuint i; - GLfloat *color = (GLfloat *)GL_COLOR_POINTER; + GLfloat *color = (GLfloat *)GL_KOS_COLOR_POINTER; for(i = 0; i < count; i++) { dst[i].argb = (((GLubyte)(color[3] * 0xFF)) << 24 | ((GLubyte)(color[0] * 0xFF)) << 16 | ((GLubyte)(color[1] * 0xFF)) << 8 | ((GLubyte)(color[2] * 0xFF))); - color += GL_COLOR_STRIDE; + color += GL_KOS_COLOR_STRIDE; } } @@ -818,15 +1017,32 @@ static inline void _glKosArrayColor4f(pvr_vertex_t *dst, GLuint count) { static inline void _glKosArrayTexCoord2f(pvr_vertex_t *dst, GLuint count) { GLuint i; - GLfloat *uv = GL_TEXCOORD_POINTER; + GLfloat *uv = GL_KOS_TEXCOORD0_POINTER; for(i = 0; i < count; i++) { dst[i].u = uv[0]; dst[i].v = uv[1]; - uv += GL_TEXCOORD_STRIDE; + uv += GL_KOS_TEXCOORD0_STRIDE; } } +static inline void _glKosArrayMultiTexCoord2f(GLuint count) { + if(_glKosEnabledNearZClip()) + return; + + GLuint i; + GLfloat *uv = GL_KOS_TEXCOORD1_POINTER; + glTexCoord *dst = (glTexCoord *)_glKosMultiUVBufPointer(); + + for(i = 0; i < count; i++) { + dst[i].u = uv[0]; + dst[i].v = uv[1]; + uv += GL_KOS_TEXCOORD1_STRIDE; + } + + _glKosMultiUVBufAdd(count); +} + //========================================================================================// //== Open GL Draw Arrays ==// @@ -834,10 +1050,10 @@ static void _glKosDrawArrays2D(GLenum mode, GLint first, GLsizei count) { pvr_vertex_t *dst = _glKosVertexBufPointer(); /* Check for Color Submission */ - if(GL_VERTEX_PTR_MODE & GL_USE_COLOR) { - switch(GL_COLOR_TYPE) { + if(GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_COLOR) { + switch(GL_KOS_COLOR_TYPE) { case GL_FLOAT: - switch(GL_COLOR_COMPONENTS) { + switch(GL_KOS_COLOR_COMPONENTS) { case 3: _glKosArrayColor3f(dst, count); break; @@ -850,13 +1066,13 @@ static void _glKosDrawArrays2D(GLenum mode, GLint first, GLsizei count) { break; case GL_UNSIGNED_INT: - if(GL_COLOR_COMPONENTS == 1) + if(GL_KOS_COLOR_COMPONENTS == 1) _glKosArrayColor1ui(dst, count); break; case GL_UNSIGNED_BYTE: - if(GL_COLOR_COMPONENTS == 4) + if(GL_KOS_COLOR_COMPONENTS == 4) _glKosArrayColor4ub(dst, count); break; @@ -866,7 +1082,7 @@ static void _glKosDrawArrays2D(GLenum mode, GLint first, GLsizei count) { _glKosArrayColor0(dst, count); /* No colors bound */ /* Check if Texture Coordinates are enabled */ - if((GL_VERTEX_PTR_MODE & GL_USE_TEXTURE) && (_glKosEnabledTexture2D() >= 0)) + if((GL_KOS_VERTEX_PTR_MODE & GL_KOS_USE_TEXTURE0) && (_glKosEnabledTexture2D() >= 0)) _glKosArrayTexCoord2f(dst, count); _glKosMatrixApplyRender(); /* Apply the Render Matrix Stack */ @@ -875,61 +1091,38 @@ static void _glKosDrawArrays2D(GLenum mode, GLint first, GLsizei count) { _glKosArraysTransform2D(count); /* Set the vertex flags for use with the PVR */ - switch(mode) { - case GL_QUADS: - _glKosArrayFlagsSetQuad(dst, count); - break; + _glKosArraysApplyVertexFlags(mode, dst, count); - case GL_TRIANGLES: - _glKosArrayFlagsSetTriangle(dst, count); - break; - - case GL_TRIANGLE_STRIP: - _glKosArrayFlagsSetTriangleStrip(dst, count); - break; - } - - _glKosVertexBufAdd(count); - - _glKosArraysResetState(); + _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_VERTEX_POINTER += first; /* Add Pointer Offset */ - GL_TEXCOORD_POINTER += first; - GL_COLOR_POINTER += first; - GL_NORMAL_POINTER += first; - + + GL_KOS_VERTEX_POINTER += first; /* Add Pointer Offset */ + GL_KOS_TEXCOORD0_POINTER += first; + GL_KOS_COLOR_POINTER += first; + GL_KOS_NORMAL_POINTER += first; + /* Compile the PVR polygon context with the currently enabled flags */ - if((GL_VERTEX_PTR_MODE & GL_USE_TEXTURE) && _glKosBoundTexID() > 0) - _glKosCompileHdrTx(); - else - _glKosCompileHdr(); - + _glKosArraysApplyHeader(); + if(GL_KOS_VERTEX_SIZE == 2) return _glKosDrawArrays2D(mode, first, count); - pvr_vertex_t *dst; /* Destination of Output Vertex Array */ - - if(_glKosEnabledNearZClip()) - dst = _glKosClipBufAddress(); - else - dst = _glKosVertexBufPointer(); + /* Destination of Output Vertex Array */ + pvr_vertex_t *dst = _glKosArraysDest(); /* Check if Vertex Lighting is enabled. Else, check for Color Submission */ - if((GL_VERTEX_PTR_MODE & GL_USE_NORMAL) && _glKosEnabledLighting()) { - _glKosArraysTransformNormals(GL_NORMAL_POINTER, count); - _glKosArraysTransformPositions(GL_VERTEX_POINTER, count); - _glKosVertexLights(GL_ARRAY_BUF, dst, count); - } - else if(GL_VERTEX_PTR_MODE & GL_USE_COLOR) { - switch(GL_COLOR_TYPE) { + 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_COLOR_COMPONENTS) { + switch(GL_KOS_COLOR_COMPONENTS) { case 3: _glKosArrayColor3f(dst, count); break; @@ -942,13 +1135,13 @@ GLAPI void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count) { break; case GL_UNSIGNED_INT: - if(GL_COLOR_COMPONENTS == 1) + if(GL_KOS_COLOR_COMPONENTS == 1) _glKosArrayColor1ui(dst, count); break; case GL_UNSIGNED_BYTE: - if(GL_COLOR_COMPONENTS == 4) + if(GL_KOS_COLOR_COMPONENTS == 4) _glKosArrayColor4ub(dst, count); break; @@ -958,55 +1151,44 @@ GLAPI void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count) { _glKosArrayColor0(dst, count); /* No colors bound, color white */ /* Check if Texture Coordinates are enabled */ - if((GL_VERTEX_PTR_MODE & GL_USE_TEXTURE) && (_glKosEnabledTexture2D() >= 0)) + 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()) { + if(!_glKosEnabledNearZClip()) { /* No NearZ Clipping Enabled */ /* Transform Vertex Positions */ _glKosArraysTransform(count); /* Set the vertex flags for use with the PVR */ - switch(mode) { - case GL_QUADS: - _glKosArrayFlagsSetQuad(dst, count); - break; - - case GL_TRIANGLES: - _glKosArrayFlagsSetTriangle(dst, count); - break; - - case GL_TRIANGLE_STRIP: - _glKosArrayFlagsSetTriangleStrip(dst, count); - break; - } + _glKosArraysApplyVertexFlags(mode, dst, count); } - else { - /* Transform vertices with no perspective divde, store w component */ + 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 */ - switch(mode) { - case GL_TRIANGLES: - count = _glKosClipTrianglesTransformed(dst, GL_ARRAY_DSTW, - (pvr_vertex_t *)_glKosVertexBufPointer(), count); - break; - - case GL_QUADS: - count = _glKosClipQuadsTransformed(dst, GL_ARRAY_DSTW, - (pvr_vertex_t *)_glKosVertexBufPointer(), count); - - break; - - case GL_TRIANGLE_STRIP: - count = _glKosClipTriangleStripTransformed(dst, GL_ARRAY_DSTW, - (pvr_vertex_t *)_glKosVertexBufPointer(), count); - break; - } + count = _glKosArraysApplyClipping(GL_KOS_TEXCOORD1_POINTER, GL_KOS_TEXCOORD1_STRIDE, mode, count); } - _glKosVertexBufAdd(count); + _glKosArraysApplyMultiTexture(mode, count); - _glKosArraysResetState(); + _glKosArraysFlush(count); +} + +void APIENTRY glClientActiveTextureARB(GLenum texture) { + if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + _glKosMaxTextureUnits()) + _glKosThrowError(GL_INVALID_ENUM, "glClientActiveTextureARB"); + + if(_glKosGetError()) { + + _glKosPrintError(); + return; + } + + GL_KOS_CLIENT_ACTIVE_TEXTURE = texture & 0xF; } \ No newline at end of file diff --git a/gl-arrays.h b/gl-arrays.h index 0e6fd2b..0d57d9d 100755 --- a/gl-arrays.h +++ b/gl-arrays.h @@ -14,7 +14,6 @@ vertex lighting will be applied even if you submit a color pointer, so only submit one or the other. - ToDo: glDrawElements() is not yet implemented. */ #ifndef GL_ARRAYS_H @@ -22,34 +21,10 @@ #include "gl.h" -#define GL_USE_ARRAY 0x0001 -#define GL_USE_TEXTURE 0x0010 -#define GL_USE_COLOR 0x0100 -#define GL_USE_NORMAL 0x1000 -#define GL_USE_TEXTURE_COLOR 0x0111 -#define GL_USE_TEXTURE_LIT 0x1011 - -void (*_glKosArrayTexCoordFunc)(pvr_vertex_t *); -void (*_glKosArrayColorFunc)(pvr_vertex_t *); - -void (*_glKosElementTexCoordFunc)(pvr_vertex_t *, GLuint); -void (*_glKosElementColorFunc)(pvr_vertex_t *, GLuint); - -static GLfloat *GL_VERTEX_POINTER = NULL; -static GLushort GL_VERTEX_STRIDE = 0; - -static GLfloat *GL_NORMAL_POINTER = NULL; -static GLushort GL_NORMAL_STRIDE = 0; - -static GLfloat *GL_TEXCOORD_POINTER = NULL; -static GLushort GL_TEXCOORD_STRIDE = 0; - -static GLfloat *GL_COLOR_POINTER = NULL; -static GLushort GL_COLOR_STRIDE = 0; -static GLubyte GL_COLOR_COMPONENTS = 0; -static GLenum GL_COLOR_TYPE = 0; - -static GLubyte *GL_INDEX_POINTER_U8 = NULL; -static GLushort *GL_INDEX_POINTER_U16 = NULL; +#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 diff --git a/gl-cap.c b/gl-cap.c index 8c4e6f1..3857518 100755 --- a/gl-cap.c +++ b/gl-cap.c @@ -197,7 +197,7 @@ void APIENTRY glGetIntegerv(GLenum pname, GLint *params) { default: _glKosThrowError(GL_INVALID_ENUM, "glGetIntegerv"); _glKosPrintError(); - break; + break; } } @@ -212,7 +212,7 @@ void APIENTRY glGetFloatv(GLenum pname, GLfloat *params) { default: _glKosThrowError(GL_INVALID_ENUM, "glGetFloatv"); _glKosPrintError(); - break; + break; } } diff --git a/gl-clip-arrays.c b/gl-clip-arrays.c new file mode 100755 index 0000000..8471664 --- /dev/null +++ b/gl-clip-arrays.c @@ -0,0 +1,418 @@ +/* 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 index 6d2d500..31ac2a3 100755 --- a/gl-clip.c +++ b/gl-clip.c @@ -14,27 +14,13 @@ #include #include +#include "gl.h" +#include "gl-api.h" #include "gl-clip.h" static float3 CLIP_BUF[1024 * 32]; -static inline void glVertexCopy3f(float3 *src, float3 *dst) { - *dst = *src; -} - -static inline void glVertexCopyPVR(pvr_vertex_t *src, pvr_vertex_t *dst) { - *dst = *src; -} - -static inline void _glKosVertexCopyPVR(pvr_vertex_t *src, pvr_vertex_t *dst) { - *dst = *src; -} - -static inline float ZclipMag(float3 *v1, float3 *v2) { - return ((CLIP_NEARZ - v1->z) / (v2->z - v1->z)); -} - -static inline void glVertexClipZNear(pvr_vertex_t *v1, pvr_vertex_t *v2, float MAG) { +static inline void _glKosVertexClipZNear(pvr_vertex_t *v1, pvr_vertex_t *v2, float MAG) { colorui *c1 = (colorui *)&v1->argb; colorui *c2 = (colorui *)&v2->argb; @@ -49,26 +35,7 @@ static inline void glVertexClipZNear(pvr_vertex_t *v1, pvr_vertex_t *v2, float M c1->b += (c2->b - c1->b) * MAG; } -static inline void _glKosVertexClipZNear3(pvr_vertex_t *v1, pvr_vertex_t *v2, float *w1, float *w2) { - float 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 GLuint glTransformClip(pvr_vertex_t *v, int count) { +static GLuint _glKosTransformClip(pvr_vertex_t *v, GLint count) { pvr_vertex_t *V = v; float3 *C = CLIP_BUF; GLuint in = 0; @@ -85,13 +52,13 @@ static GLuint glTransformClip(pvr_vertex_t *v, int count) { return in; } -GLuint _glKosClipTriangleStrip(pvr_vertex_t *vin, pvr_vertex_t *vout, unsigned int vertices) { - GLuint i, v = 0, in = glTransformClip(vin, vertices); +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(vout, vin, vertices * 0x20); - pvr_vertex_t *v = vout; + memcpy(dst, src, vertices * 0x20); + pvr_vertex_t *v = dst; while(--in) { v->flags = PVR_CMD_VERTEX; @@ -107,8 +74,8 @@ GLuint _glKosClipTriangleStrip(pvr_vertex_t *vin, pvr_vertex_t *vout, unsigned i /* Iterate all Triangles of the Strip - Hence looping vertices-2 times */ for(i = 0; i < ((vertices) - 2); i++) { - unsigned short int clip = 0; /* Clip Code for current Triangle */ - unsigned char verts_in = 0; /* # of Verteices inside clip plane for current Triangle */ + 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; @@ -119,39 +86,39 @@ GLuint _glKosClipTriangleStrip(pvr_vertex_t *vin, pvr_vertex_t *vout, unsigned i break; case 3: /* All Vertices of Triangle are inside of clip plne */ - memcpy(&vout[v], &vin[i], 96); + memcpy(&dst[v], &src[i], 96); - vout[v].flags = vout[v + 1].flags = PVR_CMD_VERTEX; - vout[v + 2].flags = PVR_CMD_VERTEX_EOL; + 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(&vout[v], &vin[i], 96); + memcpy(&dst[v], &src[i], 96); switch(clip) { case FIRST_TWO_OUT: - glVertexClipZNear(&vout[v], &vout[v + 2], ZclipMag(&CLIP_BUF[i], &CLIP_BUF[i + 2])); - glVertexClipZNear(&vout[v + 1], &vout[v + 2], ZclipMag(&CLIP_BUF[i + 1], &CLIP_BUF[i + 2])); + _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: - glVertexClipZNear(&vout[v], &vout[v + 1], ZclipMag(&CLIP_BUF[i], &CLIP_BUF[i + 1])); - glVertexClipZNear(&vout[v + 2], &vout[v + 1], ZclipMag(&CLIP_BUF[i + 2], &CLIP_BUF[i + 1])); + _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: - glVertexClipZNear(&vout[v + 1], &vout[v], ZclipMag(&CLIP_BUF[i + 1], &CLIP_BUF[i + 0])); - glVertexClipZNear(&vout[v + 2], &vout[v], ZclipMag(&CLIP_BUF[i + 2], &CLIP_BUF[i + 0])); + _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; } - vout[v].flags = vout[v + 1].flags = PVR_CMD_VERTEX; - vout[v + 2].flags = PVR_CMD_VERTEX_EOL; + dst[v].flags = dst[v + 1].flags = PVR_CMD_VERTEX; + dst[v + 2].flags = PVR_CMD_VERTEX_EOL; v += 3; break; @@ -159,35 +126,35 @@ GLuint _glKosClipTriangleStrip(pvr_vertex_t *vin, pvr_vertex_t *vout, unsigned i case 2:/* 2 Vertices of Triangle are inside of clip plane = output 2 Triangles */ switch(clip) { case FIRST: - glVertexCopyPVR(&vin[i + 0], &vout[v + 0]); - glVertexCopyPVR(&vin[i + 1], &vout[v + 1]); - glVertexCopyPVR(&vin[i + 0], &vout[v + 2]); - glVertexCopyPVR(&vin[i + 2], &vout[v + 3]); - glVertexClipZNear(&vout[v + 0], &vout[v + 1], ZclipMag(&CLIP_BUF[i], &CLIP_BUF[i + 1])); - glVertexClipZNear(&vout[v + 2], &vout[v + 3], ZclipMag(&CLIP_BUF[i], &CLIP_BUF[i + 2])); + _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: - glVertexCopyPVR(&vin[i + 1], &vout[v + 0]); - glVertexCopyPVR(&vin[i + 0], &vout[v + 1]); - glVertexCopyPVR(&vin[i + 1], &vout[v + 2]); - glVertexCopyPVR(&vin[i + 2], &vout[v + 3]); - glVertexClipZNear(&vout[v + 0], &vout[v + 1], ZclipMag(&CLIP_BUF[i + 1], &CLIP_BUF[i + 0])); - glVertexClipZNear(&vout[v + 2], &vout[v + 3], ZclipMag(&CLIP_BUF[i + 1], &CLIP_BUF[i + 2])); + _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: - glVertexCopyPVR(&vin[i + 2], &vout[v + 0]); - glVertexCopyPVR(&vin[i + 0], &vout[v + 1]); - glVertexCopyPVR(&vin[i + 2], &vout[v + 2]); - glVertexCopyPVR(&vin[i + 1], &vout[v + 3]); - glVertexClipZNear(&vout[v + 0], &vout[v + 1], ZclipMag(&CLIP_BUF[i + 2], &CLIP_BUF[i])); - glVertexClipZNear(&vout[v + 2], &vout[v + 3], ZclipMag(&CLIP_BUF[i + 2], &CLIP_BUF[i + 1])); + _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; } - vout[v + 0].flags = vout[v + 1].flags = vout[v + 2].flags = PVR_CMD_VERTEX; - vout[v + 3].flags = PVR_CMD_VERTEX_EOL; + 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; @@ -199,16 +166,16 @@ GLuint _glKosClipTriangleStrip(pvr_vertex_t *vin, pvr_vertex_t *vout, unsigned i return v; } -static inline unsigned char _glKosClipTri(pvr_vertex_t *vin, pvr_vertex_t *vout) { - unsigned short int clip = 0; /* Clip Code for current Triangle */ - unsigned char verts_in = 0; /* # of Vertices inside clip plane for current Triangle */ +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") = vin->x; - register float __y __asm__("fr13") = vin->y; - register float __z __asm__("fr14") = vin->z; + 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(); @@ -216,9 +183,9 @@ static inline unsigned char _glKosClipTri(pvr_vertex_t *vin, pvr_vertex_t *vout) clip_buf[0].y = __y; clip_buf[0].z = __z; - __x = (vin + 1)->x; - __y = (vin + 1)->y; - __z = (vin + 1)->z; + __x = (src + 1)->x; + __y = (src + 1)->y; + __z = (src + 1)->z; mat_trans_fv12_nodiv(); @@ -226,9 +193,9 @@ static inline unsigned char _glKosClipTri(pvr_vertex_t *vin, pvr_vertex_t *vout) clip_buf[1].y = __y; clip_buf[1].z = __z; - __x = (vin + 2)->x; - __y = (vin + 2)->y; - __z = (vin + 2)->z; + __x = (src + 2)->x; + __y = (src + 2)->y; + __z = (src + 2)->z; mat_trans_fv12_nodiv(); @@ -247,71 +214,71 @@ static inline unsigned char _glKosClipTri(pvr_vertex_t *vin, pvr_vertex_t *vout) return 0; case 3: /* All Vertices of Triangle are inside of clip plne */ - memcpy(vout, vin, 96); + memcpy(dst, src, 96); - vout->flags = (vout + 1)->flags = PVR_CMD_VERTEX; - (vout + 2)->flags = PVR_CMD_VERTEX_EOL; + 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(vout, vin, 96); + memcpy(dst, src, 96); switch(clip) { case FIRST_TWO_OUT: - glVertexClipZNear(vout, vout + 2, ZclipMag(&clip_buf[0], &clip_buf[2])); - glVertexClipZNear(vout + 1, vout + 2, ZclipMag(&clip_buf[1], &clip_buf[2])); + _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: - glVertexClipZNear(vout, vout + 1, ZclipMag(&clip_buf[0], &clip_buf[1])); - glVertexClipZNear(vout + 2, vout + 1, ZclipMag(&clip_buf[2], &clip_buf[1])); + _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: - glVertexClipZNear(vout + 1, vout, ZclipMag(&clip_buf[1], &clip_buf[0])); - glVertexClipZNear(vout + 2, vout, ZclipMag(&clip_buf[2], &clip_buf[0])); + _glKosVertexClipZNear(dst + 1, dst, _glKosNearZClipMag(&clip_buf[1], &clip_buf[0])); + _glKosVertexClipZNear(dst + 2, dst, _glKosNearZClipMag(&clip_buf[2], &clip_buf[0])); break; } - vout->flags = (vout + 1)->flags = PVR_CMD_VERTEX; - (vout + 2)->flags = PVR_CMD_VERTEX_EOL; + 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(vout, vin, 64); - glVertexCopyPVR(vin, vout + 2); - glVertexCopyPVR(vin + 2, vout + 3); - glVertexClipZNear(vout, vout + 1, ZclipMag(&clip_buf[0], &clip_buf[1])); - glVertexClipZNear(vout + 2, vout + 3, ZclipMag(&clip_buf[0], &clip_buf[2])); + 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: - glVertexCopyPVR(vin + 1, vout); - glVertexCopyPVR(vin, vout + 1); - memcpy(vout + 2, vin + 1, 64); - glVertexClipZNear(vout, vout + 1, ZclipMag(&clip_buf[1], &clip_buf[0])); - glVertexClipZNear(vout + 2, vout + 3, ZclipMag(&clip_buf[1], &clip_buf[2])); + _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: - glVertexCopyPVR(vin + 2, vout); - glVertexCopyPVR(vin, vout + 1); - glVertexCopyPVR(vin + 2, vout + 2); - glVertexCopyPVR(vin + 1, vout + 3); - glVertexClipZNear(vout, vout + 1, ZclipMag(&clip_buf[2], &clip_buf[0])); - glVertexClipZNear(vout + 2, vout + 3, ZclipMag(&clip_buf[2], &clip_buf[1])); + _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; } - vout->flags = (vout + 1)->flags = (vout + 2)->flags = PVR_CMD_VERTEX; - (vout + 3)->flags = PVR_CMD_VERTEX_EOL; + dst->flags = (dst + 1)->flags = (dst + 2)->flags = PVR_CMD_VERTEX; + (dst + 3)->flags = PVR_CMD_VERTEX_EOL; return 4; } @@ -319,426 +286,24 @@ static inline unsigned char _glKosClipTri(pvr_vertex_t *vin, pvr_vertex_t *vout) return 0; } -unsigned int _glKosClipTriangles(pvr_vertex_t *vin, pvr_vertex_t *vout, unsigned int vertices) { - unsigned int i, v = 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(vin + i, vout + v); + v += _glKosClipTri(src + i, dst + v); return v; } -unsigned int _glKosClipQuads(pvr_vertex_t *vin, pvr_vertex_t *vout, unsigned int vertices) { - unsigned int i, v = 0; +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 */ - glVertexCopyPVR(vin + i + 3, &qv); - glVertexCopyPVR(vin + i + 2, vin + i + 3); - glVertexCopyPVR(&qv, vin + i + 2); - v += _glKosClipTriangleStrip(vin + i, vout + v, 4); - } - - return v; -} - -static inline void _glKosVertexPerspectiveDivide(pvr_vertex_t *dst, float w) { - dst->z = 1.0f / w; - dst->x *= dst->z; - dst->y *= dst->z; -} - -GLuint _glKosClipTrianglesTransformed(pvr_vertex_t *src, float *w, pvr_vertex_t *dst, GLuint count) { - pvr_vertex_t *vin = src; - pvr_vertex_t *vout = dst; - unsigned short int clip; - unsigned char verts_in = 0; - GLuint verts_out = 0; - GLuint i; - - for(i = 0; i < count; i += 3) { - clip = 0; /* Clip Code for current Triangle */ - verts_in = 0; /* # of Vertices inside clip plane for current Triangle */ - float W[4] = { w[i], w[i + 1], w[i + 2] }; /* W Component for Perspective Divide */ - - (vin[0].z >= CLIP_NEARZ) ? clip |= FIRST : ++verts_in; - (vin[1].z >= CLIP_NEARZ) ? clip |= SECOND : ++verts_in; - (vin[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 */ - _glKosVertexCopyPVR(&vin[0], &vout[0]); - _glKosVertexCopyPVR(&vin[1], &vout[1]); - _glKosVertexCopyPVR(&vin[2], &vout[2]); - - _glKosVertexPerspectiveDivide(&vout[0], W[0]); - _glKosVertexPerspectiveDivide(&vout[1], W[1]); - _glKosVertexPerspectiveDivide(&vout[2], W[2]); - - vout[0].flags = vout[1].flags = PVR_CMD_VERTEX; - vout[2].flags = PVR_CMD_VERTEX_EOL; - - vout += 3; - verts_out += 3; - break; - - case 1:/* 1 Vertex of Triangle is inside of clip plane = output 1 Triangle */ - _glKosVertexCopyPVR(&vin[0], &vout[0]); - _glKosVertexCopyPVR(&vin[1], &vout[1]); - _glKosVertexCopyPVR(&vin[2], &vout[2]); - - switch(clip) { - case FIRST_TWO_OUT: - _glKosVertexClipZNear3(&vout[0], &vout[2], &W[0], &W[2]); - _glKosVertexClipZNear3(&vout[1], &vout[2], &W[1], &W[2]); - - break; - - case FIRST_AND_LAST_OUT: - _glKosVertexClipZNear3(&vout[0], &vout[1], &W[0], &W[1]); - _glKosVertexClipZNear3(&vout[2], &vout[1], &W[2], &W[1]); - - break; - - case LAST_TWO_OUT: - _glKosVertexClipZNear3(&vout[1], &vout[0], &W[1], &W[0]); - _glKosVertexClipZNear3(&vout[2], &vout[0], &W[2], &W[0]); - - break; - } - - _glKosVertexPerspectiveDivide(&vout[0], W[0]); - _glKosVertexPerspectiveDivide(&vout[1], W[1]); - _glKosVertexPerspectiveDivide(&vout[2], W[2]); - - vout[0].flags = vout[1].flags = PVR_CMD_VERTEX; - vout[2].flags = PVR_CMD_VERTEX_EOL; - - vout += 3; - verts_out += 3; - break; - - case 2:/* 2 Vertices of Triangle are inside of clip plane = output 2 Triangles */ - switch(clip) { - case FIRST: - _glKosVertexCopyPVR(&vin[0], &vout[0]); - _glKosVertexCopyPVR(&vin[1], &vout[1]); - _glKosVertexCopyPVR(&vin[0], &vout[2]); - _glKosVertexCopyPVR(&vin[2], &vout[3]); - W[3] = W[2]; - W[2] = W[0]; - - break; - - case SECOND: - _glKosVertexCopyPVR(&vin[1], &vout[0]); - _glKosVertexCopyPVR(&vin[2], &vout[1]); - _glKosVertexCopyPVR(&vin[1], &vout[2]); - _glKosVertexCopyPVR(&vin[0], &vout[3]); - W[3] = W[0]; - W[0] = W[1]; - W[1] = W[2]; - W[2] = W[0]; - - break; - - case THIRD: - _glKosVertexCopyPVR(&vin[2], &vout[0]); - _glKosVertexCopyPVR(&vin[0], &vout[1]); - _glKosVertexCopyPVR(&vin[2], &vout[2]); - _glKosVertexCopyPVR(&vin[1], &vout[3]); - W[3] = W[1]; - W[1] = W[0]; - W[0] = W[2]; - - break; - } - - _glKosVertexClipZNear3(&vout[0], &vout[1], &W[0], &W[1]); - _glKosVertexClipZNear3(&vout[2], &vout[3], &W[2], &W[3]); - - _glKosVertexPerspectiveDivide(&vout[0], W[0]); - _glKosVertexPerspectiveDivide(&vout[1], W[1]); - _glKosVertexPerspectiveDivide(&vout[2], W[2]); - _glKosVertexPerspectiveDivide(&vout[3], W[3]); - - vout[0].flags = vout[1].flags = vout[2].flags = PVR_CMD_VERTEX; - vout[3].flags = PVR_CMD_VERTEX_EOL; - - vout += 4; - verts_out += 4; - break; - } - - vin += 3; - } - - return verts_out; -} - -GLuint _glKosClipTriangleStripTransformed(pvr_vertex_t *src, float *w, pvr_vertex_t *dst, GLuint count) { - pvr_vertex_t *vin = src; - pvr_vertex_t *vout = dst; - unsigned short int clip; - unsigned char verts_in = 0; - GLuint verts_out = 0; - GLuint i; - - for(i = 0; i < (count - 2); i ++) { - clip = 0; /* Clip Code for current Triangle */ - verts_in = 0; /* # of Vertices inside clip plane for current Triangle */ - float W[4] = { w[i], w[i + 1], w[i + 2] }; /* W Component for Perspective Divide */ - - (vin[0].z >= CLIP_NEARZ) ? clip |= FIRST : ++verts_in; - (vin[1].z >= CLIP_NEARZ) ? clip |= SECOND : ++verts_in; - (vin[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 */ - _glKosVertexCopyPVR(&vin[0], &vout[0]); - _glKosVertexCopyPVR(&vin[1], &vout[1]); - _glKosVertexCopyPVR(&vin[2], &vout[2]); - - _glKosVertexPerspectiveDivide(&vout[0], W[0]); - _glKosVertexPerspectiveDivide(&vout[1], W[1]); - _glKosVertexPerspectiveDivide(&vout[2], W[2]); - - vout[0].flags = vout[1].flags = PVR_CMD_VERTEX; - vout[2].flags = PVR_CMD_VERTEX_EOL; - - vout += 3; - verts_out += 3; - break; - - case 1:/* 1 Vertex of Triangle is inside of clip plane = output 1 Triangle */ - _glKosVertexCopyPVR(&vin[0], &vout[0]); - _glKosVertexCopyPVR(&vin[1], &vout[1]); - _glKosVertexCopyPVR(&vin[2], &vout[2]); - - switch(clip) { - case FIRST_TWO_OUT: - _glKosVertexClipZNear3(&vout[0], &vout[2], &W[0], &W[2]); - _glKosVertexClipZNear3(&vout[1], &vout[2], &W[1], &W[2]); - - break; - - case FIRST_AND_LAST_OUT: - _glKosVertexClipZNear3(&vout[0], &vout[1], &W[0], &W[1]); - _glKosVertexClipZNear3(&vout[2], &vout[1], &W[2], &W[1]); - - break; - - case LAST_TWO_OUT: - _glKosVertexClipZNear3(&vout[1], &vout[0], &W[1], &W[0]); - _glKosVertexClipZNear3(&vout[2], &vout[0], &W[2], &W[0]); - - break; - } - - _glKosVertexPerspectiveDivide(&vout[0], W[0]); - _glKosVertexPerspectiveDivide(&vout[1], W[1]); - _glKosVertexPerspectiveDivide(&vout[2], W[2]); - - vout[0].flags = vout[1].flags = PVR_CMD_VERTEX; - vout[2].flags = PVR_CMD_VERTEX_EOL; - - vout += 3; - verts_out += 3; - break; - - case 2:/* 2 Vertices of Triangle are inside of clip plane = output 2 Triangles */ - switch(clip) { - case FIRST: - _glKosVertexCopyPVR(&vin[0], &vout[0]); - _glKosVertexCopyPVR(&vin[1], &vout[1]); - _glKosVertexCopyPVR(&vin[0], &vout[2]); - _glKosVertexCopyPVR(&vin[2], &vout[3]); - W[3] = W[2]; - W[2] = W[0]; - - break; - - case SECOND: - _glKosVertexCopyPVR(&vin[1], &vout[0]); - _glKosVertexCopyPVR(&vin[2], &vout[1]); - _glKosVertexCopyPVR(&vin[1], &vout[2]); - _glKosVertexCopyPVR(&vin[0], &vout[3]); - W[3] = W[0]; - W[0] = W[1]; - W[1] = W[2]; - W[2] = W[0]; - - break; - - case THIRD: - _glKosVertexCopyPVR(&vin[2], &vout[0]); - _glKosVertexCopyPVR(&vin[0], &vout[1]); - _glKosVertexCopyPVR(&vin[2], &vout[2]); - _glKosVertexCopyPVR(&vin[1], &vout[3]); - W[3] = W[1]; - W[1] = W[0]; - W[0] = W[2]; - - break; - } - - _glKosVertexClipZNear3(&vout[0], &vout[1], &W[0], &W[1]); - _glKosVertexClipZNear3(&vout[2], &vout[3], &W[2], &W[3]); - - _glKosVertexPerspectiveDivide(&vout[0], W[0]); - _glKosVertexPerspectiveDivide(&vout[1], W[1]); - _glKosVertexPerspectiveDivide(&vout[2], W[2]); - _glKosVertexPerspectiveDivide(&vout[3], W[3]); - - vout[0].flags = vout[1].flags = vout[2].flags = PVR_CMD_VERTEX; - vout[3].flags = PVR_CMD_VERTEX_EOL; - - vout += 4; - verts_out += 4; - break; - } - - ++vin; - } - - return verts_out; -} - -GLubyte _glKosClipTriTransformed(pvr_vertex_t *vin, float *w, pvr_vertex_t *vout) { - unsigned short int clip = 0; /* Clip Code for current Triangle */ - unsigned char verts_in = 0; /* # of Vertices inside clip plane for current Triangle */ - float W[4] = { w[0], w[1], w[2] }; /* W Component for Perspective Divide */ - - (vin[0].z >= CLIP_NEARZ) ? clip |= FIRST : ++verts_in; - (vin[1].z >= CLIP_NEARZ) ? clip |= SECOND : ++verts_in; - (vin[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(&vin[0], &vout[0]); - _glKosVertexCopyPVR(&vin[1], &vout[1]); - _glKosVertexCopyPVR(&vin[2], &vout[2]); - - _glKosVertexPerspectiveDivide(&vout[0], W[0]); - _glKosVertexPerspectiveDivide(&vout[1], W[1]); - _glKosVertexPerspectiveDivide(&vout[2], W[2]); - - vout[0].flags = vout[1].flags = PVR_CMD_VERTEX; - vout[2].flags = PVR_CMD_VERTEX_EOL; - - return 3; - - case 1:/* 1 Vertex of Triangle is inside of clip plane = output 1 Triangle */ - _glKosVertexCopyPVR(&vin[0], &vout[0]); - _glKosVertexCopyPVR(&vin[1], &vout[1]); - _glKosVertexCopyPVR(&vin[2], &vout[2]); - - switch(clip) { - case FIRST_TWO_OUT: - _glKosVertexClipZNear3(&vout[0], &vout[2], &W[0], &W[2]); - _glKosVertexClipZNear3(&vout[1], &vout[2], &W[1], &W[2]); - - break; - - case FIRST_AND_LAST_OUT: - _glKosVertexClipZNear3(&vout[0], &vout[1], &W[0], &W[1]); - _glKosVertexClipZNear3(&vout[2], &vout[1], &W[2], &W[1]); - - break; - - case LAST_TWO_OUT: - _glKosVertexClipZNear3(&vout[1], &vout[0], &W[1], &W[0]); - _glKosVertexClipZNear3(&vout[2], &vout[0], &W[2], &W[0]); - - break; - } - - _glKosVertexPerspectiveDivide(&vout[0], W[0]); - _glKosVertexPerspectiveDivide(&vout[1], W[1]); - _glKosVertexPerspectiveDivide(&vout[2], W[2]); - - vout[0].flags = vout[1].flags = PVR_CMD_VERTEX; - vout[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(&vin[0], &vout[0]); - _glKosVertexCopyPVR(&vin[1], &vout[1]); - _glKosVertexCopyPVR(&vin[0], &vout[2]); - _glKosVertexCopyPVR(&vin[2], &vout[3]); - W[3] = W[2]; - W[2] = W[0]; - - break; - - case SECOND: - _glKosVertexCopyPVR(&vin[1], &vout[0]); - _glKosVertexCopyPVR(&vin[2], &vout[1]); - _glKosVertexCopyPVR(&vin[1], &vout[2]); - _glKosVertexCopyPVR(&vin[0], &vout[3]); - W[3] = W[0]; - W[0] = W[1]; - W[1] = W[2]; - W[2] = W[0]; - - break; - - case THIRD: - _glKosVertexCopyPVR(&vin[2], &vout[0]); - _glKosVertexCopyPVR(&vin[0], &vout[1]); - _glKosVertexCopyPVR(&vin[2], &vout[2]); - _glKosVertexCopyPVR(&vin[1], &vout[3]); - W[3] = W[1]; - W[1] = W[0]; - W[0] = W[2]; - - break; - } - - _glKosVertexClipZNear3(&vout[0], &vout[1], &W[0], &W[1]); - _glKosVertexClipZNear3(&vout[2], &vout[3], &W[2], &W[3]); - - _glKosVertexPerspectiveDivide(&vout[0], W[0]); - _glKosVertexPerspectiveDivide(&vout[1], W[1]); - _glKosVertexPerspectiveDivide(&vout[2], W[2]); - _glKosVertexPerspectiveDivide(&vout[3], W[3]); - - vout[0].flags = vout[1].flags = vout[2].flags = PVR_CMD_VERTEX; - vout[3].flags = PVR_CMD_VERTEX_EOL; - - return 4; - } - - return 0; -} - -unsigned int _glKosClipQuadsTransformed(pvr_vertex_t *vin, float *w, pvr_vertex_t *vout, unsigned int vertices) { - unsigned int i, v = 0; - pvr_vertex_t qv[3]; - float W[3]; - - for(i = 0; i < vertices; i += 4) { /* Iterate all Quads, Rearranging into Triangle Strips */ - _glKosVertexCopyPVR(&vin[i + 0], &qv[0]); - _glKosVertexCopyPVR(&vin[i + 2], &qv[1]); - _glKosVertexCopyPVR(&vin[i + 3], &qv[2]); - W[0] = w[0]; - W[1] = w[2]; - W[2] = w[3]; - - v += _glKosClipTriTransformed(&vin[i], &w[i], &vout[v]); - v += _glKosClipTriTransformed(&qv[i], &W[i], &vout[v]); + _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 index d232024..a13a384 100755 --- a/gl-clip.h +++ b/gl-clip.h @@ -31,7 +31,7 @@ #define GREEN 0x0000FF00 #define BLUE 0x000000FF -#define CLIP_NEARZ -0.5f /* Clip Threshold */ +#define CLIP_NEARZ -0.20f /* Clip Threshold */ typedef struct { float x, y, z; @@ -41,4 +41,12 @@ 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-light.c b/gl-light.c index f1f66ef..78f7fbc 100755 --- a/gl-light.c +++ b/gl-light.c @@ -68,19 +68,17 @@ void _glKosInitLighting() { /* Called internally by glInit() */ /* Enable a light - GL_LIGHT0->GL_LIGHT7 */ void _glKosEnableLight(const GLuint light) { - if(light < GL_LIGHT0 || light > GL_LIGHT0 + GL_KOS_MAX_LIGHTS) - { + 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_LIGHT7 */ void _glKosDisableLight(const GLuint light) { - if(light < GL_LIGHT0 || light > GL_LIGHT0 + GL_KOS_MAX_LIGHTS) - { + if(light < GL_LIGHT0 || light > GL_LIGHT0 + GL_KOS_MAX_LIGHTS) { _glKosThrowError(GL_INVALID_ENUM, "glDisable(GL_LIGHT)"); return; } diff --git a/gl-matrix.c b/gl-matrix.c index 1ee931f..6863771 100755 --- a/gl-matrix.c +++ b/gl-matrix.c @@ -105,8 +105,7 @@ void glLoadIdentity() { mat_load(Matrix + GL_IDENTITY); mat_store(Matrix + MatrixMode); - if(MatrixMode == GL_MODELVIEW) - { + if(MatrixMode == GL_MODELVIEW) { mat_store(&MatrixMdlRot); mat_store(&MatrixLookAt); } diff --git a/gl-pvr.c b/gl-pvr.c index 63c1e7e..5d7e4a1 100755 --- a/gl-pvr.c +++ b/gl-pvr.c @@ -15,7 +15,7 @@ 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_MAX_VERTS conrols the number of vertices per list in the Vertex Buffer in SH4 RAM + GL_KOS_MAX_VERTS conrols the number of vertices per list in the Vertex Buffer in SH4 RAM */ #include @@ -30,22 +30,30 @@ /* Vertex Buffer Functions *************************************************************************/ -#ifdef GL_USE_MALLOC +#ifdef GL_KOS_USE_MALLOC 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 Buffer */ #else -static pvr_cmd_t GL_VBUF[2][GL_MAX_VERTS] __attribute__((aligned(32))); /* Static Vertex Buffer */ -static pvr_cmd_t GL_CBUF[GL_MAX_VERTS / 2]; /* Static Clip Buffer */ +static pvr_cmd_t GL_VBUF[2][GL_KOS_MAX_VERTS] __attribute__((aligned(32))); /* Static Vertex Buffer */ +static pvr_cmd_t GL_CBUF[GL_KOS_MAX_VERTS / 2]; /* Static Clip Buffer */ +static glTexCoord GL_UVBUF[GL_KOS_MAX_VERTS / 2]; /* Static Multi-Texture UV Buffer */ #endif -static unsigned int GL_VERTS[2] = {0, 0}, - GL_CVERTS = 0, - GL_LIST = GL_LIST_OP; +static GLuint GL_VERTS[2] = {0, 0}, + GL_CVERTS = 0, + GL_UVVERTS = 0, + 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 inline void pvr_list_submit(void *src, int n) { - unsigned int *d = TA_SQ_ADDR; - unsigned int *s = src; + GLuint *d = TA_SQ_ADDR; + GLuint *s = src; /* fill/write queues as many times necessary */ while(n--) { @@ -63,10 +71,43 @@ static inline void pvr_list_submit(void *src, int n) { } /* Wait for both store queues to complete */ - d = (unsigned int *)0xe0000000; + d = (GLuint *)0xe0000000; d[0] = d[8] = 0; } +inline 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; +} + +inline void _glKosResetMultiTexObject() { + GL_MTOBJECTS = 0; +} + +inline void *_glKosMultiUVBufAddress() { + return &GL_UVBUF[0]; +} + +inline void *_glKosMultiUVBufPointer() { + return &GL_UVBUF[GL_UVVERTS]; +} + +inline void _glKosMultiUVBufIncrement() { + ++GL_UVVERTS; +} + +inline void _glKosMultiUVBufAdd(GLuint count) { + GL_UVVERTS += count; +} + +inline void _glKosMultiUVBufReset() { + GL_UVVERTS = 0; +} + inline void *_glKosClipBufAddress() { return &GL_CBUF[0]; } @@ -79,7 +120,7 @@ inline void _glKosClipBufIncrement() { ++GL_CVERTS; } -inline void _glKosClipBufAdd(unsigned int count) { +inline void _glKosClipBufAdd(GLuint count) { GL_CVERTS += count; } @@ -88,14 +129,14 @@ inline void _glKosClipBufReset() { } inline void _glKosVertexBufSwitchOP() { - GL_LIST = GL_LIST_OP; + GL_LIST = GL_KOS_LIST_OP; } inline void _glKosVertexBufSwitchTR() { - GL_LIST = GL_LIST_TR; + GL_LIST = GL_KOS_LIST_TR; } -inline void *_glKosVertexBufAddress(unsigned char list) { +inline void *_glKosVertexBufAddress(GLubyte list) { return &GL_VBUF[list][0]; } @@ -108,19 +149,19 @@ inline void _glKosVertexBufIncrement() { } inline void *_glKosTRVertexBufPointer() { - return &GL_VBUF[GL_LIST_TR][GL_VERTS[GL_LIST_TR]]; + return &GL_VBUF[GL_KOS_LIST_TR][GL_VERTS[GL_KOS_LIST_TR]]; } inline void _glKosTRVertexBufIncrement() { - ++GL_VERTS[GL_LIST_TR]; + ++GL_VERTS[GL_KOS_LIST_TR]; } -inline void _glKosVertexBufAdd(unsigned int count) { +inline void _glKosVertexBufAdd(GLuint count) { GL_VERTS[GL_LIST] += count; } -inline void _glKosTRVertexBufAdd(unsigned int count) { - GL_VERTS[GL_LIST_TR] += count; +inline void _glKosTRVertexBufAdd(GLuint count) { + GL_VERTS[GL_KOS_LIST_TR] += count; } inline void _glKosVertexBufDecrement() { @@ -131,11 +172,11 @@ inline void _glKosVertexBufReset() { GL_VERTS[0] = GL_VERTS[1] = 0; } -inline unsigned int _glKosVertexBufCount(unsigned char list) { +inline GLuint _glKosVertexBufCount(GLubyte list) { return GL_VERTS[list]; } -unsigned char _glKosList() { +GLubyte _glKosList() { return GL_LIST; } @@ -146,13 +187,32 @@ inline void _glKosVertexBufCopy(void *dst, void *src, GLuint count) { static inline void glutSwapBuffer() { pvr_list_begin(PVR_LIST_OP_POLY); - pvr_list_submit(_glKosVertexBufAddress(GL_LIST_OP), _glKosVertexBufCount(GL_LIST_OP)); + pvr_list_submit(_glKosVertexBufAddress(GL_KOS_LIST_OP), _glKosVertexBufCount(GL_KOS_LIST_OP)); pvr_list_finish(); pvr_list_begin(PVR_LIST_TR_POLY); - pvr_list_submit(_glKosVertexBufAddress(GL_LIST_TR), _glKosVertexBufCount(GL_LIST_TR)); + pvr_list_submit(_glKosVertexBufAddress(GL_KOS_LIST_TR), _glKosVertexBufCount(GL_KOS_LIST_TR)); + + /* 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 + 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); + } + + _glKosResetMultiTexObject(); /* End Multi-Texture Pass */ pvr_list_finish(); @@ -173,6 +233,9 @@ void glutSwapBuffers() { glutSwapBuffer(); _glKosVertexBufReset(); + + _glKosMultiUVBufReset(); + } void glutCopyBufferToTexture(void *dst, GLsizei *x, GLsizei *y) { @@ -200,14 +263,12 @@ int _glKosInitPVR() { }; pvr_init(¶ms); -#ifdef GL_USE_DMA - pvr_dma_init(); -#endif -#ifdef GL_USE_MALLOC - GL_VBUF[0] = memalign(0x20, GL_MAX_VERTS * sizeof(pvr_cmd_t)); - GL_VBUF[1] = memalign(0x20, GL_MAX_VERTS * sizeof(pvr_cmd_t)); - GL_CBUF = malloc((GL_MAX_VERTS / 2) * sizeof(pvr_cmd_t)); +#ifdef GL_KOS_USE_MALLOC + GL_VBUF[0] = memalign(0x20, GL_KOS_MAX_VERTS * sizeof(pvr_cmd_t)); + GL_VBUF[1] = memalign(0x20, GL_KOS_MAX_VERTS * sizeof(pvr_cmd_t)); + GL_CBUF = malloc((GL_KOS_MAX_VERTS / 2) * sizeof(pvr_cmd_t)); + GL_UVBUF = malloc(GL_KOS_MAX_VERTS * sizeof(glTexCoord)); #endif return 1; diff --git a/gl-pvr.h b/gl-pvr.h index 809517b..03128cd 100755 --- a/gl-pvr.h +++ b/gl-pvr.h @@ -24,14 +24,14 @@ typedef struct { } pvr_cmd_tclip_t; /* Tile Clip command for the pvr */ #define GL_PVR_VERTEX_BUF_SIZE 2560 * 256 /* PVR Vertex buffer size */ -#define GL_MAX_VERTS 1024*64 /* SH4 Vertex Count */ -#define GL_MAX_TEXTURES 1024 /* Textures in Buffer */ +#define GL_KOS_MAX_VERTS 1024*64 /* SH4 Vertex Count */ -#define GL_USE_MALLOC 1 /* Use Dynamic Vertex Array */ +#define GL_KOS_LIST_OP 0 +#define GL_KOS_LIST_TR 1 + +#define GL_KOS_USE_MALLOC 1 /* Use Dynamic Vertex Array */ //#define GL_USE_FLOAT 0 /* Use PVR's floating-point color Vertex Type (64bit) *NoOp* */ //#define GL_USE_DMA 0 /* Use PVR DMA for vertex data transfer *NoOp* */ -#define GL_LIST_OP 0 -#define GL_LIST_TR 1 /* Misc SH4->PVR Commands */ #define TA_SQ_ADDR (unsigned int *)(void *) \ diff --git a/gl-texture.c b/gl-texture.c index 79b6ccc..93e44e7 100755 --- a/gl-texture.c +++ b/gl-texture.c @@ -8,6 +8,7 @@ */ #include "gl.h" +#include "glext.h" #include "gl-api.h" #include @@ -16,11 +17,14 @@ //========================================================================================// //== Internal KOS Open GL Texture Unit Structures / Global Variables ==// -static GL_TEXTURE_OBJECT *TEXTURE_OBJ = NULL; -static GL_TEXTURE_OBJECT *GL_TEXTURE_POINTER = NULL; +#define GL_KOS_MAX_TEXTURE_UNITS 2 +#define GL_KOS_CLAMP_U (1<<1) +#define GL_KOS_CLAMP_V (1<<0) -#define GL_CLAMP_U (1<<1) -#define GL_CLAMP_V (1<<0) +static GL_TEXTURE_OBJECT *TEXTURE_OBJ = NULL; +static GL_TEXTURE_OBJECT *GL_KOS_TEXTURE_UNIT[GL_KOS_MAX_TEXTURE_UNITS] = { NULL, NULL }; + +static GLubyte GL_KOS_ACTIVE_TEXTURE = GL_TEXTURE0_ARB & 0xF; //========================================================================================// @@ -65,11 +69,11 @@ static GL_TEXTURE_OBJECT *_glKosGetTextureObj(GLuint index) { } static void _glKosBindTexture(GLuint index) { - GL_TEXTURE_POINTER = _glKosGetTextureObj(index); + GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE] = _glKosGetTextureObj(index); } static void _glKosUnbindTexture() { - GL_TEXTURE_POINTER = NULL; + GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE] = NULL; } GLuint _glKosTextureWidth(GLuint index) { @@ -88,11 +92,21 @@ GLvoid *_glKosTextureData(GLuint index) { } void _glKosCompileHdrTx() { - return GL_TEXTURE_POINTER ? _glKosCompileHdrT(GL_TEXTURE_POINTER) : _glKosCompileHdr(); + return GL_KOS_TEXTURE_UNIT[GL_TEXTURE0_ARB & 0xF] ? + _glKosCompileHdrT(GL_KOS_TEXTURE_UNIT[GL_TEXTURE0_ARB & 0xF]) : _glKosCompileHdr(); +} + +GL_TEXTURE_OBJECT *_glKosBoundMultiTexID() { + return GL_KOS_TEXTURE_UNIT[GL_TEXTURE1_ARB & 0xF]; } GLuint _glKosBoundTexID() { - return GL_TEXTURE_POINTER ? GL_TEXTURE_POINTER->index : 0; + return GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE] ? + GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->index : 0; +} + +GLubyte _glKosMaxTextureUnits() { + return GL_KOS_MAX_TEXTURE_UNITS; } //========================================================================================// @@ -131,9 +145,9 @@ void APIENTRY glDeleteTextures(GLsizei n, GLuint *textures) { ltxr->link = txr->link; if(txr->index == *textures) { - if(GL_TEXTURE_POINTER) - if(GL_TEXTURE_POINTER->index == txr->index) - GL_TEXTURE_POINTER = NULL; + if(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]) + if(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->index == txr->index) + GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE] = NULL; if(txr->data != NULL) pvr_mem_free(txr->data); @@ -155,9 +169,53 @@ void APIENTRY glBindTexture(GLenum target, GLuint texture) { 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) + if(internalformat != GL_UNSIGNED_SHORT_5_6_5_VQ_TWID) + if(internalformat != GL_UNSIGNED_SHORT_4_4_4_4_VQ) + if(internalformat != GL_UNSIGNED_SHORT_4_4_4_4_VQ_TWID) + if(internalformat != GL_UNSIGNED_SHORT_1_5_5_5_VQ) + if(internalformat != GL_UNSIGNED_SHORT_1_5_5_5_VQ_TWID) + _glKosThrowError(GL_INVALID_OPERATION, "glCompressedTexImage2D"); + + if(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE] == NULL) + _glKosThrowError(GL_INVALID_OPERATION, "glCompressedTexImage2D"); + + if(_glKosGetError()) { + _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 = internalformat; + + 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); +} + void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, - GLenum format, GLenum type, GLvoid *data) { + GLenum format, GLenum type, const GLvoid *data) { if(target != GL_TEXTURE_2D) _glKosThrowError(GL_INVALID_ENUM, "glTexImage2D"); @@ -181,22 +239,16 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, if(format == GL_RGB) if(type != GL_UNSIGNED_SHORT_5_6_5) if(type != GL_UNSIGNED_SHORT_5_6_5_TWID) - if(type != GL_UNSIGNED_SHORT_5_6_5_VQ) - if(type != GL_UNSIGNED_SHORT_5_6_5_VQ_TWID) - _glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D"); + _glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D"); if(format == GL_RGBA) if(type != GL_UNSIGNED_SHORT_4_4_4_4) if(type != GL_UNSIGNED_SHORT_4_4_4_4_TWID) - if(type != GL_UNSIGNED_SHORT_4_4_4_4_VQ) - if(type != GL_UNSIGNED_SHORT_4_4_4_4_VQ_TWID) - if(type != GL_UNSIGNED_SHORT_5_5_5_1) - if(type != GL_UNSIGNED_SHORT_5_5_5_1_TWID) - if(type != GL_UNSIGNED_SHORT_5_5_5_1_VQ) - if(type != GL_UNSIGNED_SHORT_5_5_5_1_VQ_TWID) - _glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D"); + if(type != GL_UNSIGNED_SHORT_1_5_5_5) + if(type != GL_UNSIGNED_SHORT_1_5_5_5_TWID) + _glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D"); - if(GL_TEXTURE_POINTER == NULL) + if(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE] == NULL) _glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D"); if(_glKosGetError()) { @@ -204,20 +256,17 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, return; } - GL_TEXTURE_POINTER->width = width; - GL_TEXTURE_POINTER->height = height; - GL_TEXTURE_POINTER->mip_map = level; - GL_TEXTURE_POINTER->color = type; + 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 = type; GLuint bytes = level ? glKosMipMapTexSize(width, height) : (width * height * 2); - if(format & PVR_TXRFMT_VQ_ENABLE) - GL_TEXTURE_POINTER->data = pvr_mem_malloc(bytes * 0.25); - else - GL_TEXTURE_POINTER->data = pvr_mem_malloc(bytes); + GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->data = pvr_mem_malloc(bytes); if(data) - sq_cpy(GL_TEXTURE_POINTER->data, data, bytes); + sq_cpy(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->data, data, bytes); } void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) { @@ -227,19 +276,19 @@ void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) { case GL_TEXTURE_MIN_FILTER: switch(param) { case GL_LINEAR: - GL_TEXTURE_POINTER->filter = PVR_FILTER_BILINEAR; + GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->filter = PVR_FILTER_BILINEAR; break; case GL_NEAREST: - GL_TEXTURE_POINTER->filter = PVR_FILTER_NEAREST; + GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->filter = PVR_FILTER_NEAREST; break; case GL_FILTER_NONE: - GL_TEXTURE_POINTER->filter = PVR_FILTER_NONE; + GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->filter = PVR_FILTER_NONE; break; case GL_FILTER_BILINEAR: - GL_TEXTURE_POINTER->filter = PVR_FILTER_BILINEAR; + GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->filter = PVR_FILTER_BILINEAR; break; default: @@ -251,11 +300,11 @@ void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) { case GL_TEXTURE_WRAP_S: switch(param) { case GL_CLAMP: - GL_TEXTURE_POINTER->uv_clamp |= GL_CLAMP_U; + GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->uv_clamp |= GL_KOS_CLAMP_U; break; case GL_REPEAT: - GL_TEXTURE_POINTER->uv_clamp &= ~GL_CLAMP_U; + GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->uv_clamp &= ~GL_KOS_CLAMP_U; break; } @@ -264,11 +313,11 @@ void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) { case GL_TEXTURE_WRAP_T: switch(param) { case GL_CLAMP: - GL_TEXTURE_POINTER->uv_clamp |= GL_CLAMP_V; + GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->uv_clamp |= GL_KOS_CLAMP_V; break; case GL_REPEAT: - GL_TEXTURE_POINTER->uv_clamp &= ~GL_CLAMP_V; + GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->uv_clamp &= ~GL_KOS_CLAMP_V; break; } @@ -290,9 +339,22 @@ void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) { } if(param >= PVR_TXRENV_REPLACE && param <= PVR_TXRENV_MODULATEALPHA) - GL_TEXTURE_POINTER->env = param; + 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(_glKosGetError()) { + + _glKosPrintError(); + return; + } + + GL_KOS_ACTIVE_TEXTURE = texture & 0xF; +} \ No newline at end of file diff --git a/include/gl.h b/include/gl.h index dea7734..65b2931 100755 --- a/include/gl.h +++ b/include/gl.h @@ -379,9 +379,9 @@ __BEGIN_DECLS #define GLclampf float #define GLubyte unsigned char #define GLbitfield unsigned long -#define GLboolean int -#define GL_FALSE 0 -#define GL_TRUE 1 +#define GLboolean unsigned char +#define GL_FALSE 0 +#define GL_TRUE 1 #define GLAPI extern #define APIENTRY @@ -419,7 +419,7 @@ GLAPI void APIENTRY glNormal3fv(const GLfloat *xyz); /* Primitive 2D Position Submission */ GLAPI void APIENTRY glVertex2f(GLfloat x, GLfloat y); -GLAPI void APIENTRY glVertex2fv(const const GLfloat *xy); +GLAPI void APIENTRY glVertex2fv(const GLfloat *xy); /* Non-Standard KOS Primitive 2D Submission. This will perform no tranformations on the vertices. */ GLAPI void APIENTRY glKosVertex2f(GLfloat x, GLfloat y); @@ -491,14 +491,43 @@ GLAPI void APIENTRY glDeleteTextures(GLsizei n, GLuint *textures); GLAPI void APIENTRY glBindTexture(GLenum target, GLuint texture); /* Loads texture from SH4 RAM into PVR VRAM */ +/* internalformat must be one of the following constants: + GL_RGB + GL_RGBA + + format must be the same as internalformat + + if internal format is GL_RGB, type must be one of the following constants: + GL_UNSIGNED_SHORT_5_6_5 + GL_UNSIGNED_SHORT_5_6_5_TWID + + if internal format is GL_RGBA, type must be one of the following constants: + GL_UNSIGNED_SHORT_4_4_4_4 + GL_UNSIGNED_SHORT_4_4_4_4_TWID + GL_UNSIGNED_SHORT_1_5_5_5 + GL_UNSIGNED_SHORT_1_5_5_5_TWID + */ GLAPI void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, - GLenum format, GLenum type, GLvoid *data); + GLenum format, GLenum type, const GLvoid *data); -/* Bind a Texture that is already in PVR VRAM */ -GLAPI void APIENTRY glKosTexImage2D(GLenum target, GLint level, GLint internalFormat, - GLsizei width, GLsizei height, GLint border, - GLenum format, GLenum type, GLvoid *data); +/* Loads VQ compressed texture from SH4 RAM into PVR VRAM */ +/* internalformat must be one of the following constants: + GL_UNSIGNED_SHORT_5_6_5_VQ + GL_UNSIGNED_SHORT_5_6_5_VQ_TWID + GL_UNSIGNED_SHORT_4_4_4_4_VQ + GL_UNSIGNED_SHORT_4_4_4_4_VQ_TWID + GL_UNSIGNED_SHORT_1_5_5_5_VQ + GL_UNSIGNED_SHORT_1_5_5_5_VQ_TWID + */ +GLAPI void APIENTRY glCompressedTexImage2D(GLenum target, + GLint level, + GLenum internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLsizei imageSize, + const GLvoid *data); /* GL Array API - Only GL_TRIANGLES, GL_TRIANGLE_STRIP, and GL_QUADS are supported */ GLAPI void APIENTRY glVertexPointer(GLint size, GLenum type, @@ -515,8 +544,6 @@ GLAPI void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *p GLAPI void APIENTRY glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer); -GLAPI void APIENTRY glIndexPointer(GLenum type, GLsizei stride, const GLvoid *pointer); - /* Array Data Submission */ GLAPI void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count); GLAPI void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); @@ -587,24 +614,20 @@ GLAPI GLuint APIENTRY glKosMipMapTexSize(GLuint width, GLuint height); /* glGet Functions */ GLAPI void APIENTRY glGetIntegerv(GLenum pname, GLint *params); GLAPI void APIENTRY glGetFloatv(GLenum pname, GLfloat *params); -GLAPI GLboolean APIENTRY glIsEnabled(GLenum cap); +GLAPI GLboolean APIENTRY glIsEnabled(GLenum cap); -/* Multi-Texture Extensions - Does not currently work with Z-Clipping Enabled -GLAPI void APIENTRY glActiveTexture(GLenum texture); - -GLAPI void APIENTRY glClientActiveTexture(GLenum texture); - -GLAPI void APIENTRY glMultiTexCoord2f(GLenum target, GLfloat s, GLfloat t); -GLAPI void APIENTRY glMultiTexCoord2fv(GLenum target, const GLfloat *v); -*/ +/* Multi-Texture Extensions - Currently not supported in immediate mode */ +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 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); + GLenum textarget, GLuint texture, GLint level); +GLAPI GLenum APIENTRY glCheckFramebufferStatus(GLenum target); __END_DECLS + #endif /* !__GL_GL_H */ diff --git a/include/glext.h b/include/glext.h index 36d9c67..e005224 100755 --- a/include/glext.h +++ b/include/glext.h @@ -11,8 +11,6 @@ #include __BEGIN_DECLS -#include - #define GL_COLOR_ATTACHMENT0 0x8CE0 #define GL_COLOR_ATTACHMENT1 0x8CE1 #define GL_COLOR_ATTACHMENT2 0x8CE2 @@ -44,6 +42,82 @@ __BEGIN_DECLS #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC #define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD +#define GL_TEXTURE0_ARB 0x84C0 +#define GL_TEXTURE1_ARB 0x84C1 +#define GL_TEXTURE2_ARB 0x84C2 +#define GL_TEXTURE3_ARB 0x84C3 +#define GL_TEXTURE4_ARB 0x84C4 +#define GL_TEXTURE5_ARB 0x84C5 +#define GL_TEXTURE6_ARB 0x84C6 +#define GL_TEXTURE7_ARB 0x84C7 +#define GL_TEXTURE8_ARB 0x84C8 +#define GL_TEXTURE9_ARB 0x84C9 +#define GL_TEXTURE10_ARB 0x84CA +#define GL_TEXTURE11_ARB 0x84CB +#define GL_TEXTURE12_ARB 0x84CC +#define GL_TEXTURE13_ARB 0x84CD +#define GL_TEXTURE14_ARB 0x84CE +#define GL_TEXTURE15_ARB 0x84CF +#define GL_TEXTURE16_ARB 0x84D0 +#define GL_TEXTURE17_ARB 0x84D1 +#define GL_TEXTURE18_ARB 0x84D2 +#define GL_TEXTURE19_ARB 0x84D3 +#define GL_TEXTURE20_ARB 0x84D4 +#define GL_TEXTURE21_ARB 0x84D5 +#define GL_TEXTURE22_ARB 0x84D6 +#define GL_TEXTURE23_ARB 0x84D7 +#define GL_TEXTURE24_ARB 0x84D8 +#define GL_TEXTURE25_ARB 0x84D9 +#define GL_TEXTURE26_ARB 0x84DA +#define GL_TEXTURE27_ARB 0x84DB +#define GL_TEXTURE28_ARB 0x84DC +#define GL_TEXTURE29_ARB 0x84DD +#define GL_TEXTURE30_ARB 0x84DE +#define GL_TEXTURE31_ARB 0x84DF +#define GL_ACTIVE_TEXTURE_ARB 0x84E0 +#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1 +#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2 + +#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3 +#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4 +#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5 +#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6 + +#define GL_MULTISAMPLE_ARB 0x809D +#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E +#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F +#define GL_SAMPLE_COVERAGE_ARB 0x80A0 +#define GL_SAMPLE_BUFFERS_ARB 0x80A8 +#define GL_SAMPLES_ARB 0x80A9 +#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA +#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB +#define GL_MULTISAMPLE_BIT_ARB 0x20000000 + +#define GL_NORMAL_MAP_ARB 0x8511 +#define GL_REFLECTION_MAP_ARB 0x8512 +#define GL_TEXTURE_CUBE_MAP_ARB 0x8513 +#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518 +#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519 +#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A +#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B +#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C + +#define GL_COMPRESSED_ALPHA_ARB 0x84E9 +#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA +#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB +#define GL_COMPRESSED_INTENSITY_ARB 0x84EC +#define GL_COMPRESSED_RGB_ARB 0x84ED +#define GL_COMPRESSED_RGBA_ARB 0x84EE +#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF +#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0 +#define GL_TEXTURE_COMPRESSED_ARB 0x86A1 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3 + __END_DECLS #endif /* !__GL_GLEXT_H */ diff --git a/include/glu.h b/include/glu.h index b4d9818..29ba7f4 100755 --- a/include/glu.h +++ b/include/glu.h @@ -34,7 +34,7 @@ GLAPI void APIENTRY gluPerspective(GLdouble fovy, GLdouble aspect, GLAPI void APIENTRY gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx, GLfloat centery, GLfloat centerz, GLfloat upx, GLfloat upy, GLfloat upz); - + /* glhLookAtf2 = gluLookAt operating on 3 float vectors. */ GLAPI void APIENTRY glhLookAtf2(GLfloat *eyePosition3D, GLfloat *center3D, diff --git a/include/glut.h b/include/glut.h index fc914ba..406f867 100755 --- a/include/glut.h +++ b/include/glut.h @@ -3,7 +3,7 @@ libgl/glut.h Copyright (C) 2014 Josh Pearson Copyright (C) 2014 Lawrence Sebald - + */ #ifndef __GL_GLUT_H @@ -18,7 +18,7 @@ __BEGIN_DECLS GLAPI void APIENTRY glutSwapBuffers(); /* Copy the Submitted Primitive Data to the GPU for render to texture */ -/* This will leave the Vertex Data in the Main Buffer to be Flushed on the +/* This will leave the Vertex Data in the Main Buffer to be Flushed on the next frame rendered */ GLAPI void APIENTRY glutCopyBufferToTexture(void *dst, GLsizei *x, GLsizei *y);