diff --git a/Makefile b/Makefile index 53b3f5d..e3ceec2 100755 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ # Copyright (C) 2013, 2014 Josh Pearson # Copyright (C) 2014 Lawrence Sebald -TARGET = libgl.a +TARGET = libGL.a OBJS = gl-rgb.o gl-fog.o gl-sh4-light.o gl-light.o gl-clip.o gl-clip-arrays.o OBJS += gl-arrays.o gl-pvr.o gl-matrix.o gl-api.o gl-texture.o glu-texture.o OBJS += gl-framebuffer.o gl-cap.o gl-error.o diff --git a/gl-api.c b/gl-api.c index b9fae8c..dedfa6b 100755 --- a/gl-api.c +++ b/gl-api.c @@ -36,6 +36,7 @@ static GLuint GL_KOS_VERTEX_COUNT = 0; static GLuint GL_KOS_VERTEX_MODE = GL_TRIANGLES; static GLuint GL_KOS_VERTEX_COLOR = 0xFFFFFFFF; static GLfloat GL_KOS_VERTEX_UV[2] = { 0, 0 }; +//static glTexCoord4f GL_KOS_VERTEX_TEX_COORD = { 0, 0, 0, 1 }; static GLfloat GL_KOS_COLOR_CLEAR[3] = { 0, 0, 0 }; @@ -266,13 +267,33 @@ void APIENTRY glColor4fv(const GLfloat *rgba) { //== Texture Coordinate Submission ==// void APIENTRY glTexCoord2f(GLfloat u, GLfloat v) { - GL_KOS_VERTEX_UV[0] = u; - GL_KOS_VERTEX_UV[1] = v; + if(_glKosEnabledTextureMatrix()) + { + _glKosMatrixLoadTexture(); + + mat_trans_texture2_nomod(u, v, GL_KOS_VERTEX_UV[0], GL_KOS_VERTEX_UV[1]); + + _glKosMatrixLoadRender(); + } + else { + GL_KOS_VERTEX_UV[0] = u; + GL_KOS_VERTEX_UV[1] = v; + } } void APIENTRY glTexCoord2fv(const GLfloat *uv) { - GL_KOS_VERTEX_UV[0] = uv[0]; - GL_KOS_VERTEX_UV[1] = uv[1]; + if(_glKosEnabledTextureMatrix()) + { + _glKosMatrixLoadTexture(); + + mat_trans_texture2_nomod(uv[0], uv[1], GL_KOS_VERTEX_UV[0], GL_KOS_VERTEX_UV[1]); + + _glKosMatrixLoadRender(); + } + else { + GL_KOS_VERTEX_UV[0] = uv[0]; + GL_KOS_VERTEX_UV[1] = uv[1]; + } } //== Vertex Position Submission Functions ==// @@ -923,4 +944,34 @@ GLubyte _glKosDepthMask() { GLuint _glKosVertexColor() { return GL_KOS_VERTEX_COLOR; -} \ No newline at end of file +} + +void glAlphaFunc(GLenum func, GLclampf ref) +{ + ; +} + +void glLineWidth(GLfloat width) +{ + ; +} + +void glPolygonOffset(GLfloat factor, GLfloat units) +{ + ; +} + +void glGetTexParameteriv(GLenum target, GLenum pname, GLint * params) +{ + ; +} + +void glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) +{ + ; +} + +void glPixelStorei(GLenum pname, GLint param) +{ + ; +} diff --git a/gl-api.h b/gl-api.h index 9f3082f..fa3c15f 100755 --- a/gl-api.h +++ b/gl-api.h @@ -21,6 +21,10 @@ typedef struct { GLfloat u, v; } glTexCoord; /* Simple Texture Coordinate used for Multi-Texturing */ +typedef struct { + GLfloat s, t, r, q; +} glTexCoord4f; /* 3D Texture Coordinate */ + typedef struct { GLushort width; GLushort height; @@ -144,6 +148,7 @@ void _glKosMatrixLoadModelRot(); void _glKosMatrixApplyScreenSpace(); void _glKosMatrixApplyRender(); void _glKosMatrixLoadRender(); +void _glKosMatrixLoadTexture(); /* API Enabled Capabilities Internal Functions */ GLubyte _glKosEnabledBlend(); @@ -202,6 +207,7 @@ GLubyte _glKosGetMaxLights(); GLuint _glKosBoundTexID(); GLuint _glKosVertexColor(); GLubyte _glKosMaxTextureUnits(); +GLubyte _glKosEnabledTextureMatrix(); GL_TEXTURE_OBJECT *_glKosBoundMultiTexID(); diff --git a/gl-arrays.c b/gl-arrays.c index efdc366..3deee29 100755 --- a/gl-arrays.c +++ b/gl-arrays.c @@ -1,7 +1,7 @@ /* KallistiGL for KallistiOS ##version## libgl/gl-arrays.c - Copyright (C) 2013-2014 Josh Pearson + Copyright (C) 2013-2015 Josh Pearson Arrays Input Primitive Types Supported: -GL_TRIANGLES @@ -455,14 +455,31 @@ static inline void _glKosElementColor4fU16(pvr_vertex_t *dst, GLuint count) { //== Texture Coordinates ==// + + static inline void _glKosElementTexCoord2fU16(pvr_vertex_t *dst, GLuint count) { GLuint i, index; GLfloat *t = GL_KOS_TEXCOORD0_POINTER; - for(i = 0; i < count; i++) { - index = GL_KOS_INDEX_POINTER_U16[i] * GL_KOS_TEXCOORD0_STRIDE; - dst[i].u = t[index]; - dst[i].v = t[index + 1]; + if(_glKosEnabledTextureMatrix()) + { + _glKosMatrixLoadTexture(); + + for(i = 0; i < count; i++) + { + index = GL_KOS_INDEX_POINTER_U16[i] * GL_KOS_TEXCOORD0_STRIDE; + + mat_trans_texture2_nomod(t[index], t[index + 1], dst[i].u, dst[i].v); + } + + _glKosMatrixLoadRender(); + } + else { + for(i = 0; i < count; i++) { + index = GL_KOS_INDEX_POINTER_U16[i] * GL_KOS_TEXCOORD0_STRIDE; + dst[i].u = t[index]; + dst[i].v = t[index + 1]; + } } } @@ -470,10 +487,25 @@ static inline void _glKosElementTexCoord2fU8(pvr_vertex_t *dst, GLuint count) { GLuint i, index; GLfloat *t = GL_KOS_TEXCOORD0_POINTER; - for(i = 0; i < count; i++) { - index = GL_KOS_INDEX_POINTER_U8[i] * GL_KOS_TEXCOORD0_STRIDE; - dst[i].u = t[index]; - dst[i].v = t[index + 1]; + if(_glKosEnabledTextureMatrix()) + { + _glKosMatrixLoadTexture(); + + for(i = 0; i < count; i++) + { + index = GL_KOS_INDEX_POINTER_U8[i] * GL_KOS_TEXCOORD0_STRIDE; + + mat_trans_texture2_nomod(t[index], t[index + 1], dst[i].u, dst[i].v); + } + + _glKosMatrixLoadRender(); + } + else { + for(i = 0; i < count; i++) { + index = GL_KOS_INDEX_POINTER_U8[i] * GL_KOS_TEXCOORD0_STRIDE; + dst[i].u = t[index]; + dst[i].v = t[index + 1]; + } } } @@ -610,7 +642,7 @@ static inline void _glKosArrayFlagsSetQuad(pvr_vertex_t *dst, GLuint count) { GLuint i; for(i = 0; i < count; i += 4) { - _glKosVertexSwizzle(&dst[2], &dst[3]); + _glKosVertexSwizzle(&dst[i + 2], &dst[i + 3]); dst[i + 0].flags = dst[i + 1].flags = dst[i + 2].flags = PVR_CMD_VERTEX; dst[i + 3].flags = PVR_CMD_VERTEX_EOL; } @@ -1018,11 +1050,27 @@ 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_KOS_TEXCOORD0_POINTER; - - for(i = 0; i < count; i++) { - dst[i].u = uv[0]; - dst[i].v = uv[1]; - uv += GL_KOS_TEXCOORD0_STRIDE; + + if(_glKosEnabledTextureMatrix()) + { + _glKosMatrixLoadTexture(); + + for(i = 0; i < count; i++) + { + mat_trans_texture2_nomod(uv[0], uv[1], dst[i].u, dst[i].v); + + uv += GL_KOS_TEXCOORD0_STRIDE; + } + + _glKosMatrixLoadRender(); + } + else + { + for(i = 0; i < count; i++) { + dst[i].u = uv[0]; + dst[i].v = uv[1]; + uv += GL_KOS_TEXCOORD0_STRIDE; + } } } @@ -1191,4 +1239,4 @@ void APIENTRY glClientActiveTextureARB(GLenum texture) { } GL_KOS_CLIENT_ACTIVE_TEXTURE = texture & 0xF; -} \ No newline at end of file +} diff --git a/gl-cap.c b/gl-cap.c index 3857518..10e2617 100755 --- a/gl-cap.c +++ b/gl-cap.c @@ -24,6 +24,7 @@ #define GL_KOS_ENABLE_SUPERSAMPLE (1<<6) #define GL_KOS_ENABLE_TEXTURE2D (1<<7) #define GL_KOS_ENABLE_BLENDING (1<<8) +#define GL_KOS_ENABLE_TEXTURE_MAT (1<<9) static GLbitfield GL_KOS_ENABLE_CAP = 0; @@ -66,6 +67,10 @@ void APIENTRY glEnable(GLenum cap) { case GL_CULL_FACE: GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_CULLING; break; + + case GL_KOS_TEXTURE_MATRIX: + GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_TEXTURE_MAT; + break; } } @@ -105,6 +110,10 @@ void APIENTRY glDisable(GLenum cap) { case GL_CULL_FACE: GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_CULLING; break; + + case GL_KOS_TEXTURE_MATRIX: + GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_TEXTURE_MAT; + break; } } @@ -135,6 +144,9 @@ GLboolean APIENTRY glIsEnabled(GLenum cap) { case GL_BLEND: return _glKosEnabledBlend() ? GL_TRUE : GL_FALSE; + + case GL_KOS_TEXTURE_MATRIX: + return _glKosEnabledTextureMatrix() ? GL_TRUE : GL_FALSE; } return GL_FALSE; @@ -216,6 +228,26 @@ void APIENTRY glGetFloatv(GLenum pname, GLfloat *params) { } } +const GLbyte* glGetString(GLenum name) +{ + switch(name) + { + case GL_VENDOR: + return "KallistiOS"; + + case GL_RENDERER: + return "PowerVR2 CLX2 100mHz"; + + case GL_VERSION: + return "KGL 1.x"; + + case GL_EXTENSIONS: + return "GL_ARB_framebuffer_object, GL_ARB_multitexture"; + } + + return "GL_KOS_ERROR: ENUM Unsupported\n"; +} + //===============================================================================// //== Internal API Functions ==// @@ -249,4 +281,8 @@ GLubyte _glKosEnabledTexture2D() { GLubyte _glKosEnabledBlend() { return (GL_KOS_ENABLE_CAP & GL_KOS_ENABLE_BLENDING) >> 8; -} \ No newline at end of file +} + +GLubyte _glKosEnabledTextureMatrix() { + return (GL_KOS_ENABLE_CAP & GL_KOS_ENABLE_TEXTURE_MAT) >> 9; +} diff --git a/gl-matrix.c b/gl-matrix.c index 6863771..1e9484a 100755 --- a/gl-matrix.c +++ b/gl-matrix.c @@ -123,8 +123,11 @@ void glScalef(GLfloat x, GLfloat y, GLfloat z) { mat_store(Matrix + MatrixMode); } -void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { - float r = DEG2RAD * angle; +void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { + float r = DEG2RAD * -angle; + + vec3f_normalize(x, y, z); + mat_load(Matrix + MatrixMode); mat_rotate(r * x, r * y, r * z); mat_store(Matrix + MatrixMode); @@ -366,6 +369,10 @@ void _glKosMatrixLoadRender() { mat_load(Matrix + GL_RENDER); } +void _glKosMatrixLoadTexture() { + mat_load(Matrix + GL_TEXTURE); +} + void _glKosMatrixLoadModelView() { mat_load(Matrix + GL_MODELVIEW); } diff --git a/gl-pvr.c b/gl-pvr.c index 5d7e4a1..0ecfbe2 100755 --- a/gl-pvr.c +++ b/gl-pvr.c @@ -75,6 +75,22 @@ static inline void pvr_list_submit(void *src, int n) { d[0] = d[8] = 0; } +/* Custom version of sq_cpy from KOS for copying 32bytes of vertex data to the PVR */ +static inline void pvr_hdr_submit(const GLuint *src) { + GLuint *d = TA_SQ_ADDR; + + d[0] = *(src++); + d[1] = *(src++); + d[2] = *(src++); + d[3] = *(src++); + d[4] = *(src++); + d[5] = *(src++); + d[6] = *(src++); + d[7] = *(src++); + + asm("pref @%0" : : "r"(d)); +} + inline void _glKosPushMultiTexObject(GL_TEXTURE_OBJECT *tex, pvr_vertex_t *src, GLuint count) { @@ -186,15 +202,23 @@ inline void _glKosVertexBufCopy(void *dst, void *src, GLuint count) { static inline void glutSwapBuffer() { pvr_list_begin(PVR_LIST_OP_POLY); - +#ifdef GL_KOS_USE_DMA + pvr_dma_transfer(_glKosVertexBufAddress(GL_KOS_LIST_OP), 0, + _glKosVertexBufCount(GL_KOS_LIST_OP) * 32, + PVR_DMA_TA, 1, NULL, 0); +#else pvr_list_submit(_glKosVertexBufAddress(GL_KOS_LIST_OP), _glKosVertexBufCount(GL_KOS_LIST_OP)); - +#endif pvr_list_finish(); pvr_list_begin(PVR_LIST_TR_POLY); - +#ifdef GL_KOS_USE_DMA + pvr_dma_transfer(_glKosVertexBufAddress(GL_KOS_LIST_TR), 0, + _glKosVertexBufCount(GL_KOS_LIST_TR) * 32, + PVR_DMA_TA, 1, NULL, 0); +#else pvr_list_submit(_glKosVertexBufAddress(GL_KOS_LIST_TR), _glKosVertexBufCount(GL_KOS_LIST_TR)); - +#endif /* Multi-Texture Pass - Modify U/V coords of submitted vertices */ GLuint i, v; glTexCoord *mt = _glKosMultiUVBufAddress(); @@ -208,8 +232,14 @@ static inline void glutSwapBuffer() { } // submit vertex data to PVR +#ifdef GL_KOS_USE_DMA + pvr_hdr_submit((GLuint *)&GL_MTOBJS[i].hdr); + pvr_dma_transfer(GL_MTOBJS[i].src, 0, + GL_MTOBJS[i].count * 32, PVR_DMA_TA, 1, NULL, 0); +#else pvr_list_submit((pvr_poly_hdr_t *)&GL_MTOBJS[i].hdr, 1); pvr_list_submit((pvr_vertex_t *)GL_MTOBJS[i].src, GL_MTOBJS[i].count); +#endif } _glKosResetMultiTexObject(); /* End Multi-Texture Pass */ diff --git a/gl-pvr.h b/gl-pvr.h index 03128cd..5348d04 100755 --- a/gl-pvr.h +++ b/gl-pvr.h @@ -30,8 +30,8 @@ typedef struct { #define GL_KOS_LIST_TR 1 #define GL_KOS_USE_MALLOC 1 /* Use Dynamic Vertex Array */ +//#define GL_KOS_USE_DMA 1 /* Use PVR DMA for vertex data transfer instead of store queues */ //#define GL_USE_FLOAT 0 /* Use PVR's floating-point color Vertex Type (64bit) *NoOp* */ -//#define GL_USE_DMA 0 /* Use PVR DMA for vertex data transfer *NoOp* */ /* Misc SH4->PVR Commands */ #define TA_SQ_ADDR (unsigned int *)(void *) \ diff --git a/gl-rgb.c b/gl-rgb.c index 7138b6d..7c8f391 100755 --- a/gl-rgb.c +++ b/gl-rgb.c @@ -1,9 +1,10 @@ /* KallistiGL for KallistiOS ##version## libgl/gl-rgb.c - Copyright (C) 2013-2014 Josh Pearson + Copyright (C) 2013-2015 Josh Pearson A set of functions for working with ARGB pixel data, used by gluBuild2DMipmaps(...). + The pixel conversion functions are for submitting textures not supported by the PVR. */ #include "gl.h" @@ -114,3 +115,220 @@ uint16 __glKosAverageBiPixelARGB4444(uint16 p1, uint16 p2) { return ((A & RGB4_MAX) << ARGB4444_ALPHA_SHIFT) | ((R & RGB4_MAX) << ARGB4444_RED_SHIFT) | ((G & RGB4_MAX) << ARGB4444_GREEN_SHIFT) | (B & RGB4_MAX); } + +//===================================================================================================// +//== Colorspace Conversion ==// + +static uint16 _glConvPixelRGBAU32(uint8 r, uint8 g, uint8 b, uint8 a) +{ + return (uint16)((a & RGB4_MAX) << ARGB4444_ALPHA_SHIFT) | + ((r & RGB4_MAX) << ARGB4444_RED_SHIFT) | + ((g & RGB4_MAX) << ARGB4444_GREEN_SHIFT) | + ((b & RGB4_MAX)); +} + +static uint16 _glConvPixelRGBU24(uint8 r, uint8 g, uint8 b) +{ + return (uint16)((r & RGB5_MAX) << RGB565_RED_SHIFT) | + ((g & RGB6_MAX) << RGB565_GREEN_SHIFT) | + ((b & RGB5_MAX)); +} + +static void _glConvPixelsRGBF(int w, int h, float * src, uint16 * dst) +{ + int i; + for(i = 0; i < w * h; i++) + { + dst[i] = _glConvPixelRGBU24((uint8)(src[i * 3 + 0] * RGB5_MAX), + (uint8)(src[i * 3 + 1] * RGB6_MAX), + (uint8)(src[i * 3 + 2] * RGB5_MAX)); + } +} + +static void _glConvPixelsRGBAF(int w, int h, float * src, uint16 * dst) +{ + int i; + for(i = 0; i < w * h; i++) + { + dst[i] = _glConvPixelRGBAU32((uint8)(src[i * 4 + 0] * RGB4_MAX), + (uint8)(src[i * 4 + 1] * RGB4_MAX), + (uint8)(src[i * 4 + 2] * RGB4_MAX), + (uint8)(src[i * 4 + 3] * RGB4_MAX)); + } +} + +static void _glConvPixelsRGBU24(int w, int h, uint8 * src, uint16 * dst) +{ + unsigned char r, g, b; + int i; + + for(i = 0; i < w * h; i++) + { + r = (src[i * 3 + 0] * RGB5_MAX) / RGB8_MAX; + g = (src[i * 3 + 1] * RGB6_MAX) / RGB8_MAX; + b = (src[i * 3 + 2] * RGB5_MAX) / RGB8_MAX; + + dst[i] = _glConvPixelRGBU24(r, g, b); + } +} + +static void _glConvPixelsRGBAU32(int w, int h, uint8 * src, uint16 * dst) +{ + unsigned char r, g, b, a; + int i; + + for(i = 0; i < w * h; i++) + { + r = (src[i * 4 + 0] * RGB4_MAX) / RGB8_MAX; + g = (src[i * 4 + 1] * RGB4_MAX) / RGB8_MAX; + b = (src[i * 4 + 2] * RGB4_MAX) / RGB8_MAX; + a = (src[i * 4 + 3] * RGB4_MAX) / RGB8_MAX; + + dst[i] = _glConvPixelRGBAU32(r, g, b, a); + } +} + +static void _glConvPixelsRGBS24(int w, int h, int8 * src, uint16 * dst) +{ + unsigned char r, g, b; + int i; + + for(i = 0; i < w * h; i++) + { + r = ((src[i * 3 + 0] + S8_NEG_OFT) * RGB5_MAX) / RGB8_MAX; + g = ((src[i * 3 + 1] + S8_NEG_OFT) * RGB6_MAX) / RGB8_MAX; + b = ((src[i * 3 + 2] + S8_NEG_OFT) * RGB5_MAX) / RGB8_MAX; + + dst[i] = _glConvPixelRGBU24(r, g, b); + } +} + +static void _glConvPixelsRGBAS32(int w, int h, int8 * src, uint16 * dst) +{ + unsigned char r, g, b, a; + int i; + + for(i = 0; i < w * h; i++) + { + r = ((src[i * 4 + 0] + S8_NEG_OFT) * RGB4_MAX) / RGB8_MAX; + g = ((src[i * 4 + 1] + S8_NEG_OFT) * RGB4_MAX) / RGB8_MAX; + b = ((src[i * 4 + 2] + S8_NEG_OFT) * RGB4_MAX) / RGB8_MAX; + a = ((src[i * 4 + 3] + S8_NEG_OFT) * RGB4_MAX) / RGB8_MAX; + + dst[i] = _glConvPixelRGBAU32(r, g, b, a); + } +} + +static void _glConvPixelsRGBS48(int w, int h, int16 * src, uint16 * dst) +{ + unsigned char r, g, b; + int i; + + for(i = 0; i < w * h; i++) + { + r = ((src[i * 3 + 0] + S16_NEG_OFT) * RGB5_MAX) / RGB16_MAX; + g = ((src[i * 3 + 1] + S16_NEG_OFT) * RGB6_MAX) / RGB16_MAX; + b = ((src[i * 3 + 2] + S16_NEG_OFT) * RGB5_MAX) / RGB16_MAX; + + dst[i] = _glConvPixelRGBU24(r, g, b); + } +} + +static void _glConvPixelsRGBAS64(int w, int h, int16 * src, uint16 * dst) +{ + unsigned char r, g, b, a; + int i; + + for(i = 0; i < w * h; i++) + { + r = ((src[i * 4 + 0] + S16_NEG_OFT) * RGB4_MAX) / RGB16_MAX; + g = ((src[i * 4 + 1] + S16_NEG_OFT) * RGB4_MAX) / RGB16_MAX; + b = ((src[i * 4 + 2] + S16_NEG_OFT) * RGB4_MAX) / RGB16_MAX; + a = ((src[i * 4 + 3] + S16_NEG_OFT) * RGB4_MAX) / RGB16_MAX; + + dst[i] = _glConvPixelRGBAU32(r, g, b, a); + } +} + +static void _glConvPixelsRGBU48(int w, int h, uint16 * src, uint16 * dst) +{ + unsigned char r, g, b; + int i; + + for(i = 0; i < w * h; i++) + { + r = ((src[i * 3 + 0]) * RGB5_MAX) / RGB16_MAX; + g = ((src[i * 3 + 1]) * RGB6_MAX) / RGB16_MAX; + b = ((src[i * 3 + 2]) * RGB5_MAX) / RGB16_MAX; + + dst[i] = _glConvPixelRGBU24(r, g, b); + } +} + +static void _glConvPixelsRGBAU64(int w, int h, uint16 * src, uint16 * dst) +{ + unsigned char r, g, b, a; + int i; + + for(i = 0; i < w * h; i++) + { + r = (src[i * 4 + 0] * RGB4_MAX) / RGB16_MAX; + g = (src[i * 4 + 1] * RGB4_MAX) / RGB16_MAX; + b = (src[i * 4 + 2] * RGB4_MAX) / RGB16_MAX; + a = (src[i * 4 + 3] * RGB4_MAX) / RGB16_MAX; + + dst[i] = _glConvPixelRGBAU32(r, g, b, a); + } +} + +void _glPixelConvertRGB(int format, int w, int h, void * src, uint16 * dst) +{ + switch(format) + { + case GL_BYTE: + _glConvPixelsRGBS24(w, h, (int8 *)src, dst); + break; + + case GL_UNSIGNED_BYTE: + _glConvPixelsRGBU24(w, h, (uint8 *)src, dst); + break; + + case GL_SHORT: + _glConvPixelsRGBS48(w, h, (int16 *)src, dst); + break; + + case GL_UNSIGNED_SHORT: + _glConvPixelsRGBU48(w, h, (uint16 *)src, dst); + break; + + case GL_FLOAT: + _glConvPixelsRGBF(w, h, (float *)src, dst); + break; + } +} + +void _glPixelConvertRGBA(int format, int w, int h, void * src, uint16 * dst) +{ + switch(format) + { + case GL_BYTE: + _glConvPixelsRGBAS32(w, h, (int8 *)src, dst); + break; + + case GL_UNSIGNED_BYTE: + _glConvPixelsRGBAU32(w, h, (uint8 *)src, dst); + break; + + case GL_SHORT: + _glConvPixelsRGBAS64(w, h, (int16 *)src, dst); + break; + + case GL_UNSIGNED_SHORT: + _glConvPixelsRGBAU64(w, h, (uint16 *)src, dst); + break; + + case GL_FLOAT: + _glConvPixelsRGBAF(w, h, (float *)src, dst); + break; + } +} diff --git a/gl-rgb.h b/gl-rgb.h index b28caf0..9a4cb73 100755 --- a/gl-rgb.h +++ b/gl-rgb.h @@ -1,7 +1,7 @@ /* KallistiGL for KallistiOS ##version## libgl/gl-rgb.h - Copyright (C) 2013-2014 Josh Pearson + Copyright (C) 2013-2015 Josh Pearson A set of functions for working with ARGB pixel data. */ @@ -54,10 +54,17 @@ typedef GLfloat GLrgba4f[4]; #define RGB5_MAX 0x1F #define RGB6_MAX 0x3F #define RGB8_MAX 0xFF +#define RGB16_MAX 0xFFFF #define RGBA32_2_ARGB32(n) (((n & ARGB32_RGB_MASK) << ARGB32_RED_SHIFT) | (n & ARGB32_ALPHA_MASK)) #define ARGB_PACK_RGBF(r,g,b) (0xFF000000 | ((r*0xFF) << 16) | ((g*0xFF)<<8) | (b*0xFF)) #define ARGB_PACK_ARGBF(a,r,g,b) (((a*0xFF) << 24) | ((r*0xFF) << 16) | ((g*0xFF)<<8) | (b*0xFF)) +#define S8_NEG_OFT 128 // Absolute Value of Minimum 8bit Signed Range // +#define S16_NEG_OFT 32768 // Absolute Value of Minimum bit Signed Range // + +void _glPixelConvertRGB(int format, int w, int h, void * src, uint16 * dst); +void _glPixelConvertRGBA(int format, int w, int h, void * src, uint16 * dst); + #endif diff --git a/gl-sh4.h b/gl-sh4.h index 561aa33..488effd 100755 --- a/gl-sh4.h +++ b/gl-sh4.h @@ -49,4 +49,38 @@ typedef float matrix4f[4][4]; /* 4x4 float matrix */ : "0" (__x), "1" (__y), "2" (__z), "3" (__w) ); \ } +#define mat_trans_texture4(s, t, r, q) { \ + register float __s __asm__("fr4") = (s); \ + register float __t __asm__("fr5") = (t); \ + register float __r __asm__("fr6") = (r); \ + register float __q __asm__("fr7") = (q); \ + __asm__ __volatile__( \ + "ftrv xmtrx,fv4\n" \ + "fldi1 fr6\n" \ + "fdiv fr7,fr6\n" \ + "fmul fr6,fr4\n" \ + "fmul fr6,fr5\n" \ + : "=f" (__s), "=f" (__t), "=f" (__r) \ + : "0" (__s), "1" (__t), "2" (__r) \ + : "fr7" ); \ + s = __s; t = __t; r = __r; \ + } + +#define mat_trans_texture2_nomod(s, t, so, to) { \ + register float __s __asm__("fr4") = (s); \ + register float __t __asm__("fr5") = (t); \ + __asm__ __volatile__( \ + "fldi0 fr6\n" \ + "fldi1 fr7\n" \ + "ftrv xmtrx,fv4\n" \ + "fldi1 fr6\n" \ + "fdiv fr7,fr6\n" \ + "fmul fr6,fr4\n" \ + "fmul fr6,fr5\n" \ + : "=f" (__s), "=f" (__t) \ + : "0" (__s), "1" (__t) \ + : "fr7" ); \ + so = __s; to = __t; \ + } + #endif diff --git a/gl-texture.c b/gl-texture.c index 93e44e7..325843d 100755 --- a/gl-texture.c +++ b/gl-texture.c @@ -10,6 +10,7 @@ #include "gl.h" #include "glext.h" #include "gl-api.h" +#include "gl-rgb.h" #include #include @@ -236,18 +237,6 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, if(format != internalFormat) _glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D"); - if(format == GL_RGB) - if(type != GL_UNSIGNED_SHORT_5_6_5) - if(type != GL_UNSIGNED_SHORT_5_6_5_TWID) - _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_1_5_5_5) - if(type != GL_UNSIGNED_SHORT_1_5_5_5_TWID) - _glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D"); - if(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE] == NULL) _glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D"); @@ -266,7 +255,60 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->data = pvr_mem_malloc(bytes); if(data) - sq_cpy(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->data, data, bytes); + { + switch(type) + { + case GL_BYTE: /* Texture Formats that need conversion for PVR */ + case GL_UNSIGNED_BYTE: + case GL_SHORT: + case GL_UNSIGNED_SHORT: + case GL_FLOAT: + { + uint16 tex[width * height]; + + switch(internalFormat) + { + case GL_RGB: + + _glPixelConvertRGB(type, width, height, (void *)data, tex); + + GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->color = (PVR_TXRFMT_RGB565 | PVR_TXRFMT_NONTWIDDLED); + + sq_cpy(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->data, tex, bytes); + + break; + + case GL_RGBA: + + _glPixelConvertRGBA(type, width, height, (void *)data, tex); + + GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->color = (PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_NONTWIDDLED); + + sq_cpy(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->data, tex, bytes); + + break; + } + } + break; + + case GL_UNSIGNED_SHORT_5_6_5: /* Texture Formats that do not need conversion */ + case GL_UNSIGNED_SHORT_5_6_5_TWID: + case GL_UNSIGNED_SHORT_1_5_5_5: + case GL_UNSIGNED_SHORT_1_5_5_5_TWID: + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_TWID: + + sq_cpy(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->data, data, bytes); + + break; + + default: /* Unsupported Texture Format */ + + _glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D"); + + break; + } + } } void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) { @@ -357,4 +399,4 @@ void APIENTRY glActiveTextureARB(GLenum texture) { } GL_KOS_ACTIVE_TEXTURE = texture & 0xF; -} \ No newline at end of file +} diff --git a/include/gl.h b/include/gl.h index 65b2931..c57476e 100755 --- a/include/gl.h +++ b/include/gl.h @@ -315,9 +315,18 @@ __BEGIN_DECLS #define GL_DEPTH_BITS 0x0D56 #define GL_STENCIL_BITS 0x0D57 +/* StringName */ +#define GL_VENDOR 0x1F00 +#define GL_RENDERER 0x1F01 +#define GL_VERSION 0x1F02 +#define GL_EXTENSIONS 0x1F03 + /* GL KOS near Z-CLIPPING */ #define GL_KOS_NEARZ_CLIPPING 0x0020 /* capability bit */ +/* GL KOS Texture Matrix Enable Bit */ +#define GL_KOS_TEXTURE_MATRIX 0x002F + /* GL KOS Texture Color Modes */ #define GL_UNSIGNED_SHORT_5_6_5 (PVR_TXRFMT_RGB565 | PVR_TXRFMT_NONTWIDDLED) #define GL_UNSIGNED_SHORT_5_6_5_REV (PVR_TXRFMT_RGB565 | PVR_TXRFMT_NONTWIDDLED) @@ -383,6 +392,12 @@ __BEGIN_DECLS #define GL_FALSE 0 #define GL_TRUE 1 +/* Stubs for portability */ +#define GL_ALPHA_TEST 0 +#define GL_STENCIL_TEST 0 +#define GL_CLAMP_TO_EDGE 0 +#define GL_UNPACK_ALIGNMENT 0 + #define GLAPI extern #define APIENTRY @@ -415,11 +430,15 @@ GLAPI void APIENTRY glColor4fv(const GLfloat *rgba); /* Primitive Normal Submission */ GLAPI void APIENTRY glNormal3f(GLfloat x, GLfloat y, GLfloat z); +#define glNormal3i glNormal3f GLAPI void APIENTRY glNormal3fv(const GLfloat *xyz); +#define glNormal3iv glNormal3fv /* Primitive 2D Position Submission */ GLAPI void APIENTRY glVertex2f(GLfloat x, GLfloat y); +#define glVertex2i glVertex2f GLAPI void APIENTRY glVertex2fv(const GLfloat *xy); +#define glVertex2iv glVertex2fv /* Non-Standard KOS Primitive 2D Submission. This will perform no tranformations on the vertices. */ GLAPI void APIENTRY glKosVertex2f(GLfloat x, GLfloat y); @@ -432,13 +451,10 @@ GLAPI void APIENTRY(*glVertex3fv)(const GLfloat *); /* 2D Non-Textured Rectangle Submission */ GLAPI GLvoid APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); #define glRectd glRectf - GLAPI GLvoid APIENTRY glRectfv(const GLfloat *v1, const GLfloat *v2); #define glRectdv glRectfv - GLAPI GLvoid APIENTRY glRecti(GLint x1, GLint y1, GLint x2, GLint y2); #define glRects glRecti - GLAPI GLvoid APIENTRY glRectiv(const GLint *v1, const GLint *v2); #define glRectsv glRectiv @@ -452,6 +468,7 @@ GLAPI GLvoid APIENTRY glRectiv(const GLint *v1, const GLint *v2); GL_FOG GL_CULL_FACE GL_KOS_NEARZ_CLIPPING + GL_KOS_TEXTURE_MATRIX */ GLAPI void APIENTRY glEnable(GLenum cap); GLAPI void APIENTRY glDisable(GLenum cap); @@ -490,7 +507,7 @@ GLAPI void APIENTRY glGenTextures(GLsizei n, GLuint *textures); GLAPI void APIENTRY glDeleteTextures(GLsizei n, GLuint *textures); GLAPI void APIENTRY glBindTexture(GLenum target, GLuint texture); -/* Loads texture from SH4 RAM into PVR VRAM */ +/* Loads texture from SH4 RAM into PVR VRAM applying color conversion if needed */ /* internalformat must be one of the following constants: GL_RGB GL_RGBA @@ -498,10 +515,20 @@ GLAPI void APIENTRY glBindTexture(GLenum target, GLuint texture); format must be the same as internalformat if internal format is GL_RGB, type must be one of the following constants: + GL_BYTE + GL_UNSIGNED_BYTE + GL_SHORT + GL_UNSIGNED_SHORT + GL_FLOAT 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_BYTE + GL_UNSIGNED_BYTE + GL_SHORT + GL_UNSIGNED_SHORT + GL_FLOAT GL_UNSIGNED_SHORT_4_4_4_4 GL_UNSIGNED_SHORT_4_4_4_4_TWID GL_UNSIGNED_SHORT_1_5_5_5 @@ -585,6 +612,9 @@ GLAPI void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height); GLAPI void APIENTRY glKosGetMatrix(GLenum mode, GLfloat *params); +GLAPI void APIENTRY glFrustum(GLfloat left, GLfloat right, + GLfloat bottom, GLfloat top, + GLfloat znear, GLfloat zfar); /* Fog Functions - client must enable GL_FOG for this to take effect */ GLAPI void APIENTRY glFogi(GLenum pname, GLint param); @@ -615,6 +645,7 @@ GLAPI GLuint APIENTRY glKosMipMapTexSize(GLuint width, GLuint height); GLAPI void APIENTRY glGetIntegerv(GLenum pname, GLint *params); GLAPI void APIENTRY glGetFloatv(GLenum pname, GLfloat *params); GLAPI GLboolean APIENTRY glIsEnabled(GLenum cap); +GLAPI const GLbyte* APIENTRY glGetString(GLenum name); /* Multi-Texture Extensions - Currently not supported in immediate mode */ GLAPI void APIENTRY glActiveTextureARB(GLenum texture); @@ -628,6 +659,14 @@ GLAPI void APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); GLAPI GLenum APIENTRY glCheckFramebufferStatus(GLenum target); +/* Non Operational Stubs for portability */ +GLAPI void APIENTRY glAlphaFunc(GLenum func, GLclampf ref); +GLAPI void APIENTRY glLineWidth(GLfloat width); +GLAPI void APIENTRY glPolygonOffset(GLfloat factor, GLfloat units); +GLAPI void APIENTRY glGetTexParameteriv(GLenum target, GLenum pname, GLint * params); +GLAPI void APIENTRY glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); +GLAPI void APIENTRY glPixelStorei(GLenum pname, GLint param); + __END_DECLS #endif /* !__GL_GL_H */