diff --git a/Makefile b/Makefile index 56756b9..246c828 100755 --- a/Makefile +++ b/Makefile @@ -6,7 +6,9 @@ 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 glu-texture.o +OBJS += gl-arrays.o gl-matrix.o gl-api.o gl-texture.o glu-texture.o +OBJS += gl-framebuffer.o gl-cap.o gl-error.o + SUBDIRS = KOS_CFLAGS += -ffast-math -O3 -Iinclude diff --git a/gl-api.c b/gl-api.c index c1d1f52..bc417bf 100755 --- a/gl-api.c +++ b/gl-api.c @@ -1,7 +1,7 @@ /* KallistiGL for KallistiOS ##version## libgl/gl-api.c - Copyright (C) 2013-2014 Josh "PH3NOM" Pearson + Copyright (C) 2013-2014 Josh Pearson Copyright (C) 2014 Lawrence Sebald Some functionality adapted from the original KOS libgl: @@ -21,421 +21,151 @@ #include "gl-sh4.h" #include "gl-pvr.h" -/* Texture Submission Functions ************************************************************************/ -/* The texutre sumbission uses a fixed-size buffer, that defaults to 1024 textures. - That means that you must manage your texture submission by calling glDelTextures(...) - when you are done using a texture that was created by glGenTextures(...). - The size of the texture buffer can be controlled by setting GL_MAX_TEXTURES on gl-pvr.h. +//====================================================================================================// +//== Local API State Macine Variables ==// - glTexImage2D(..) is used for loading texture data to OpenGL that is located in Main RAM: - OpenGL will allocate VRAM for the texture, and copy the texture data from Main RAM to VRAM. +static GLubyte GL_KOS_DEPTH_FUNC = PVR_DEPTHCMP_GEQUAL; +static GLubyte GL_KOS_DEPTH_WRITE = PVR_DEPTHWRITE_ENABLE; +static GLubyte GL_KOS_BLEND_FUNC = (PVR_BLEND_ONE << 4) | (PVR_BLEND_ZERO & 0x0F); +static GLubyte GL_KOS_SHADE_FUNC = PVR_SHADE_GOURAUD; +static GLubyte GL_KOS_CULL_FUNC = PVR_CULLING_NONE; +static GLubyte GL_KOS_FACE_FRONT = 0; +static GLubyte GL_KOS_SUPERSAMPLE = 0; - glKosTexImage2D(...) is used for loading texture data to OpenGL that is already in VRAM: - This mode must be used for a render-to-texture if you are using glutSwapBuffersToTexture(). -*/ +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 }; -typedef struct { - GLenum target; - GLint level; - GLint border; - GLenum format; - GLenum type; - GLint filter, env; - GLuint width, height; - GLuint internalFormat; - GLvoid *data; -} glTexCxt; +static GLfloat GL_KOS_COLOR_CLEAR[3] = { 0, 0, 0 }; -static glTexCxt GL_TEX_LIST[GL_MAX_TEXTURES]; -static GLint GL_BOUND_TEX = -1, GL_LAST_BOUND_TEX = -1, - GL_BOUND_TEX1 = -1, GL_LAST_BOUND_TEX1 = -1; +static GLfloat GL_KOS_POINT_SIZE = 0.02; -static GLubyte BLEND_SRC = PVR_BLEND_ONE; -static GLubyte BLEND_DST = PVR_BLEND_ZERO; +static pvr_poly_cxt_t GL_KOS_POLY_CXT; -static GLubyte GL_SHADE_FUNC = PVR_SHADE_GOURAUD; +static inline void _glKosFlagsSetTriangleStrip(); +static inline void _glKosFlagsSetTriangle(); +static inline void _glKosFlagsSetQuad(); -static GLubyte GL_CULL_FUNC = PVR_CULLING_NONE; +//====================================================================================================// +//== API Initialization ==// -static GLubyte GL_DEPTH_CMP = PVR_DEPTHCMP_GEQUAL; -static GLubyte GL_DEPTH_ENABLE = PVR_DEPTHWRITE_ENABLE; +void APIENTRY glKosInit() { + _glKosInitPVR(); -static GLubyte GL_TEX_ENV = PVR_TXRENV_MODULATEALPHA; + _glKosInitTextures(); -static GLubyte GL_ENABLE_CLIPZ = 0; -static GLubyte GL_ENABLE_LIGHTING = 0; -static GLubyte GL_ENABLE_SCISSOR = 0; -static GLubyte GL_ENABLE_FOG = 0; -static GLubyte GL_ENABLE_CULLING = 0; -static GLubyte GL_ENABLE_DEPTH_TEST = 0; -static GLubyte GL_ENABLE_SUPERSAMP = 0; + _glKosInitMatrix(); -static GLubyte GL_FACE_FRONT = 0; -static GLubyte GL_CLAMP_ST = 0; + _glKosInitLighting(); -/* Primitive 3D Position Submission */ -void (*glVertex3f)(float, float, float); -void (*glVertex3fv)(float *); - -#define GL_CLAMP_U 0x0F -#define GL_CLAMP_V 0xF0 -#define GL_CLAMP_UV 0xFF - -#define GL_TEXTURE_0 1<<0 -#define GL_TEXTURE_1 1<<1 - -static GLuint GL_TEXTURE_ENABLED = 0; -static GLuint GL_CUR_ACTIVE_TEX = 0; - -void glActiveTexture(GLenum texture) { - if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + GL_MAX_TEXTURE_UNITS) - return; - - GL_CUR_ACTIVE_TEX = ((texture & 0xFF) - (GL_TEXTURE0 & 0xFF)); + _glKosInitFrameBuffers(); } -void glBindTexture(GLenum target, GLuint texture) { - if(target == GL_TEXTURE_2D) { - switch(GL_CUR_ACTIVE_TEX) { - case 0: - GL_BOUND_TEX = texture; - GL_LAST_BOUND_TEX = GL_BOUND_TEX; - break; +//====================================================================================================// +//== Blending / Shading functions ==// - case 1: - GL_BOUND_TEX1 = texture; - GL_LAST_BOUND_TEX1 = GL_BOUND_TEX1; - break; - } - } -} - -void glGetIntegerv(GLenum pname, GLint *params) { - switch(pname) { - case GL_ACTIVE_TEXTURE: - *params = GL_CUR_ACTIVE_TEX; - break; - - case GL_BLEND: - *params = _glKosList(); - break; - - case GL_BLEND_DST: - *params = BLEND_SRC; - break; - - case GL_BLEND_SRC: - *params = BLEND_DST; - break; - - case GL_CULL_FACE: - *params = GL_ENABLE_CULLING; - break; - - case GL_CULL_FACE_MODE: - *params = GL_CULL_FUNC; - break; - - case GL_DEPTH_FUNC: - *params = GL_DEPTH_CMP; - break; - - case GL_DEPTH_TEST: - *params = GL_ENABLE_DEPTH_TEST; - break; - - case GL_DEPTH_WRITEMASK: - *params = GL_DEPTH_ENABLE; - break; - - case GL_FRONT_FACE: - *params = GL_FACE_FRONT; - break; - - case GL_SCISSOR_TEST: - *params = GL_ENABLE_SCISSOR; - break; - - default: - *params = -1; // Indicate invalid parameter // - break; - } -} - -void glGetFloatv(GLenum pname, GLfloat *params) { - switch(pname) { - case GL_MODELVIEW_MATRIX: - case GL_PROJECTION_MATRIX: - case GL_TEXTURE_MATRIX: - glKosGetMatrix(pname - GL_MODELVIEW_MATRIX + 1, params); - break; - - default: - *params = (GLfloat)GL_INVALID_ENUM; - break; - } -} - -static void _glKosInitTextures() { - GLuint i; - - for(i = 0; i < GL_MAX_TEXTURES; i++) - GL_TEX_LIST[i].data = NULL; -} - -static GLuint _glKosNextTexture() { - GLint i; - - for(i = 0; i < GL_MAX_TEXTURES; i++) - if(GL_TEX_LIST[i].data == NULL) - return i; - - return 0; /* Invalid Texture! */ -} - -void glGenTextures(GLsizei n, GLuint *textures) { - while(n--) - *textures++ = _glKosNextTexture(); -} - -void glDelTextures(GLsizei n, GLuint *textures) { - while(n--) { - if(GL_TEX_LIST[*textures].data != NULL) { - pvr_mem_free(GL_TEX_LIST[*textures].data); - GL_TEX_LIST[*textures].data = NULL; - } - - textures++; - } -} - -void glTexImage2D(GLenum target, GLint level, GLint internalFormat, - GLsizei width, GLsizei height, GLint border, - GLenum format, GLenum type, GLvoid *data) { - if(target != GL_TEXTURE_2D) return; - - GL_TEX_LIST[GL_BOUND_TEX].target = target; - GL_TEX_LIST[GL_BOUND_TEX].level = level; - GL_TEX_LIST[GL_BOUND_TEX].border = border; - GL_TEX_LIST[GL_BOUND_TEX].format = format; - GL_TEX_LIST[GL_BOUND_TEX].type = type; - - GLuint bytes; - - if(!level) - bytes = width * height * 2; - else - bytes = glKosMipMapTexSize(width, height); - - if(format == PVR_TXRFMT_VQ_ENABLE) - bytes /= 4; - - GL_TEX_LIST[GL_BOUND_TEX].data = pvr_mem_malloc(bytes); - - GL_TEX_LIST[GL_BOUND_TEX].width = width; - GL_TEX_LIST[GL_BOUND_TEX].height = height; - GL_TEX_LIST[GL_BOUND_TEX].internalFormat = internalFormat; - - GL_TEX_LIST[GL_BOUND_TEX].filter = PVR_FILTER_NONE; - - sq_cpy(GL_TEX_LIST[GL_BOUND_TEX].data, data, bytes); -} - -void glKosTexImage2D(GLenum target, GLint level, GLint internalFormat, - GLsizei width, GLsizei height, GLint border, - GLenum format, GLenum type, GLvoid *data) { - if(target != GL_TEXTURE_2D) return; - - GL_TEX_LIST[GL_BOUND_TEX].target = target; - GL_TEX_LIST[GL_BOUND_TEX].level = level; - GL_TEX_LIST[GL_BOUND_TEX].border = border; - GL_TEX_LIST[GL_BOUND_TEX].format = format; - GL_TEX_LIST[GL_BOUND_TEX].type = type; - - GL_TEX_LIST[GL_BOUND_TEX].data = data; - - GL_TEX_LIST[GL_BOUND_TEX].width = width; - GL_TEX_LIST[GL_BOUND_TEX].height = height; - GL_TEX_LIST[GL_BOUND_TEX].internalFormat = internalFormat; - - GL_TEX_LIST[GL_BOUND_TEX].filter = PVR_FILTER_NONE; -} - -void glTexParameteri(GLenum target, GLenum pname, GLint param) { - if(target == GL_TEXTURE_2D) { - switch(pname) { - case GL_TEXTURE_MAG_FILTER: - case GL_TEXTURE_MIN_FILTER: - switch(param) { - case GL_LINEAR: - GL_TEX_LIST[GL_BOUND_TEX].filter = PVR_FILTER_BILINEAR; - break; - - case GL_NEAREST: - GL_TEX_LIST[GL_BOUND_TEX].filter = PVR_FILTER_NEAREST; - break; - - case GL_FILTER_NONE: /* Compatabile with deprecated kgl */ - GL_TEX_LIST[GL_BOUND_TEX].filter = PVR_FILTER_NONE; - break; - - case GL_FILTER_BILINEAR: /* Compatabile with deprecated kgl */ - GL_TEX_LIST[GL_BOUND_TEX].filter = PVR_FILTER_BILINEAR; - break; - - case GL_NEAREST_MIPMAP_NEAREST: - GL_TEX_LIST[GL_BOUND_TEX].level = PVR_MIPMAP_ENABLE; - break; - - default: - break; - } - - break; - - case GL_TEXTURE_WRAP_S: - switch(param) { - case GL_CLAMP: - GL_CLAMP_ST |= GL_CLAMP_U; - break; - - case GL_REPEAT: - GL_CLAMP_ST ^= GL_CLAMP_U; - break; - } - - break; - - case GL_TEXTURE_WRAP_T: - switch(param) { - case GL_CLAMP: - GL_CLAMP_ST |= GL_CLAMP_V; - break; - - case GL_REPEAT: - GL_CLAMP_ST ^= GL_CLAMP_V; - break; - } - - break; - } - } -} - -void glTexEnvi(GLenum target, GLenum pname, GLint param) { - if(target == GL_TEXTURE_ENV) - if(pname == GL_TEXTURE_ENV_MODE) - if(param >= PVR_TXRENV_REPLACE && param <= PVR_TXRENV_MODULATEALPHA) - GL_TEX_ENV = param; -} - -void glTexEnvf(GLenum target, GLenum pname, GLfloat param) { - /* GL_TEXTURE_LOD_BIAS Not Implemented */ - glTexEnvi(target, pname, param); -} - -/* Blending / Shading functions ********************************************************/ - -void glShadeModel(GLenum mode) { +void APIENTRY glShadeModel(GLenum mode) { switch(mode) { case GL_FLAT: - GL_SHADE_FUNC = PVR_SHADE_FLAT; + GL_KOS_SHADE_FUNC = PVR_SHADE_FLAT; break; case GL_SMOOTH: - GL_SHADE_FUNC = PVR_SHADE_GOURAUD; + GL_KOS_SHADE_FUNC = PVR_SHADE_GOURAUD; break; } } -void glBlendFunc(GLenum sfactor, GLenum dfactor) { +void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor) { + GL_KOS_BLEND_FUNC = 0; + switch(sfactor) { case GL_ONE: - BLEND_SRC = PVR_BLEND_ONE; + GL_KOS_BLEND_FUNC |= (PVR_BLEND_ONE & 0XF) << 4; break; case GL_ZERO: - BLEND_SRC = PVR_BLEND_ZERO; + GL_KOS_BLEND_FUNC |= (PVR_BLEND_ZERO & 0XF) << 4; break; case GL_SRC_COLOR: - BLEND_SRC = PVR_BLEND_SRCALPHA; + GL_KOS_BLEND_FUNC |= (PVR_BLEND_SRCALPHA & 0XF) << 4; break; case GL_DST_COLOR: - BLEND_SRC = PVR_BLEND_DESTCOLOR; + GL_KOS_BLEND_FUNC |= (PVR_BLEND_DESTCOLOR & 0XF) << 4; break; case GL_SRC_ALPHA: - BLEND_SRC = PVR_BLEND_SRCALPHA; + GL_KOS_BLEND_FUNC |= (PVR_BLEND_SRCALPHA << 4); break; case GL_DST_ALPHA: - BLEND_SRC = PVR_BLEND_DESTALPHA; + GL_KOS_BLEND_FUNC |= (PVR_BLEND_DESTALPHA & 0XF) << 4; break; case GL_ONE_MINUS_SRC_ALPHA: - BLEND_SRC = PVR_BLEND_INVSRCALPHA; + GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVSRCALPHA & 0XF) << 4; break; case GL_ONE_MINUS_DST_ALPHA: - BLEND_SRC = PVR_BLEND_INVDESTALPHA; + GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVDESTALPHA & 0XF) << 4; break; case GL_ONE_MINUS_DST_COLOR: - BLEND_SRC = PVR_BLEND_INVDESTCOLOR; + GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVDESTCOLOR & 0XF) << 4; break; } switch(dfactor) { case GL_ONE: - BLEND_DST = PVR_BLEND_ONE; + GL_KOS_BLEND_FUNC |= (PVR_BLEND_ONE & 0XF); break; case GL_ZERO: - BLEND_DST = PVR_BLEND_ZERO; + GL_KOS_BLEND_FUNC |= (PVR_BLEND_ZERO & 0XF); break; case GL_SRC_COLOR: - BLEND_DST = PVR_BLEND_SRCALPHA; + GL_KOS_BLEND_FUNC |= (PVR_BLEND_SRCALPHA & 0XF); break; case GL_DST_COLOR: - BLEND_DST = PVR_BLEND_DESTCOLOR; + GL_KOS_BLEND_FUNC |= (PVR_BLEND_DESTCOLOR & 0XF); break; case GL_SRC_ALPHA: - BLEND_DST = PVR_BLEND_SRCALPHA; + GL_KOS_BLEND_FUNC |= (PVR_BLEND_SRCALPHA & 0XF); break; case GL_DST_ALPHA: - BLEND_DST = PVR_BLEND_DESTALPHA; + GL_KOS_BLEND_FUNC |= (PVR_BLEND_DESTALPHA & 0XF); break; case GL_ONE_MINUS_SRC_ALPHA: - BLEND_DST = PVR_BLEND_INVSRCALPHA; + GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVSRCALPHA & 0XF); break; case GL_ONE_MINUS_DST_ALPHA: - BLEND_DST = PVR_BLEND_INVDESTALPHA; + GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVDESTALPHA & 0XF); break; case GL_ONE_MINUS_DST_COLOR: - BLEND_DST = PVR_BLEND_INVDESTCOLOR; + GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVDESTCOLOR & 0XF); break; } } -/* Depth / Clear functions */ -static GLfloat GL_DEPTH_CLEAR = 1.0f, - GL_COLOR_CLEAR[3] = { 0, 0, 0 }; +//====================================================================================================// +//== Depth / Clear functions ==// -void glClear(GLuint mode) { +void APIENTRY glClear(GLuint mode) { if(mode & GL_COLOR_BUFFER_BIT) - pvr_set_bg_color(GL_COLOR_CLEAR[0], GL_COLOR_CLEAR[1], GL_COLOR_CLEAR[2]); + pvr_set_bg_color(GL_KOS_COLOR_CLEAR[0], GL_KOS_COLOR_CLEAR[1], GL_KOS_COLOR_CLEAR[2]); } -void glClearColor(float r, float g, float b, float a) { +void APIENTRY glClearColor(float r, float g, float b, float a) { if(r > 1) r = 1; if(g > 1) g = 1; @@ -444,505 +174,177 @@ void glClearColor(float r, float g, float b, float a) { if(a > 1) a = 1; - GL_COLOR_CLEAR[0] = r * a; - GL_COLOR_CLEAR[1] = g * a; - GL_COLOR_CLEAR[2] = b * a; + GL_KOS_COLOR_CLEAR[0] = r * a; + GL_KOS_COLOR_CLEAR[1] = g * a; + GL_KOS_COLOR_CLEAR[2] = b * a; } -void glClearDepthf(GLfloat depth) { - GL_DEPTH_CLEAR = depth; +//== NoOp ==// +void APIENTRY glClearDepthf(GLfloat depth) { + ; } -void glDepthFunc(GLenum func) { +void APIENTRY glDepthFunc(GLenum func) { switch(func) { case GL_LESS: - GL_DEPTH_CMP = PVR_DEPTHCMP_GEQUAL; + GL_KOS_DEPTH_FUNC = PVR_DEPTHCMP_GEQUAL; break; case GL_LEQUAL: - GL_DEPTH_CMP = PVR_DEPTHCMP_GREATER; + GL_KOS_DEPTH_FUNC = PVR_DEPTHCMP_GREATER; break; case GL_GREATER: - GL_DEPTH_CMP = PVR_DEPTHCMP_LEQUAL; + GL_KOS_DEPTH_FUNC = PVR_DEPTHCMP_LEQUAL; break; case GL_GEQUAL: - GL_DEPTH_CMP = PVR_DEPTHCMP_LESS; + GL_KOS_DEPTH_FUNC = PVR_DEPTHCMP_LESS; break; default: - GL_DEPTH_CMP = func & 0xF; + GL_KOS_DEPTH_FUNC = (func & 0x0F); } } -void glDepthMask(GLboolean flag) { - flag ? (GL_DEPTH_ENABLE = PVR_DEPTHWRITE_ENABLE) : - (GL_DEPTH_ENABLE = PVR_DEPTHWRITE_DISABLE); +void APIENTRY glDepthMask(GLboolean flag) { + GL_KOS_DEPTH_WRITE = !flag; } -void glFrontFace(GLenum mode) { +//====================================================================================================// +//== Culling functions ==// + +void APIENTRY glFrontFace(GLenum mode) { switch(mode) { case GL_CW: case GL_CCW: - GL_FACE_FRONT = mode; + GL_KOS_FACE_FRONT = mode; break; } } -void glCullFace(GLenum mode) { +void APIENTRY glCullFace(GLenum mode) { switch(mode) { case GL_FRONT: case GL_BACK: case GL_FRONT_AND_BACK: - GL_CULL_FUNC = mode; + GL_KOS_CULL_FUNC = mode; break; } } -/* glEnable / glDisable ****************************************************************/ +//====================================================================================================// +//== Vertex Attributes Submission Functions ==// -void glEnable(GLenum cap) { - if(cap >= GL_LIGHT0 && cap <= GL_LIGHT7) return _glKosEnableLight(cap); +//== Vertex Color Submission ==// - switch(cap) { - case GL_TEXTURE_2D: - GL_TEXTURE_ENABLED |= (1 << GL_CUR_ACTIVE_TEX); - break; - - case GL_BLEND: - _glKosVertexBufSwitchTR(); - break; - - case GL_DEPTH_TEST: - GL_ENABLE_DEPTH_TEST = 1; - break; - - case GL_LIGHTING: - GL_ENABLE_LIGHTING = 1; - break; - - case GL_KOS_NEARZ_CLIPPING: - GL_ENABLE_CLIPZ = 1; - break; - - case GL_SCISSOR_TEST: - GL_ENABLE_SCISSOR = 1; - break; - - case GL_FOG: - GL_ENABLE_FOG = 1; - break; - - case GL_CULL_FACE: - GL_ENABLE_CULLING = 1; - break; - } +void APIENTRY glColor1ui(GLuint argb) { + GL_KOS_VERTEX_COLOR = argb; } -void glDisable(GLenum cap) { - if(cap >= GL_LIGHT0 && cap <= GL_LIGHT7) return _glKosDisableLight(cap); - - switch(cap) { - case GL_TEXTURE_2D: - GL_TEXTURE_ENABLED &= ~(1 << GL_CUR_ACTIVE_TEX); - break; - - case GL_BLEND: - _glKosVertexBufSwitchOP(); - break; - - case GL_DEPTH_TEST: - GL_ENABLE_DEPTH_TEST = 0; - break; - - case GL_LIGHTING: - GL_ENABLE_LIGHTING = 0; - break; - - case GL_KOS_NEARZ_CLIPPING: - GL_ENABLE_CLIPZ = 0; - break; - - case GL_SCISSOR_TEST: - GL_ENABLE_SCISSOR = 0; - break; - - case GL_FOG: - GL_ENABLE_FOG = 0; - break; - - case GL_CULL_FACE: - GL_ENABLE_CULLING = 0; - break; - } +void APIENTRY glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a) { + GL_KOS_VERTEX_COLOR = a << 24 | r << 16 | g << 8 | b; } -/* Vertex Submission Functions *************************************************************************/ -static GLuint GL_VERTICES = 0, - GL_VERTEX_MODE = GL_TRIANGLES; -static GLuint GL_VERTEX_COLOR = 0xFFFFFFFF; -//static GLuint GL_VERTEX_SPECULAR = 0xFF000000; -static GLfloat GL_VERTEX_UV[2] = {0, 0}; - -typedef struct { - GLfloat u; - GLfloat v; -} TexCoord; - -static TexCoord GL_MULTI_UV[GL_MAX_VERTS]; - -static pvr_poly_cxt_t GL_POLY_CXT; - -void glKosInit() { - _glKosInitPVR(); - - _glKosInitTextures(); - - _glKosInitMatrix(); - - _glKosInitLighting(); +void APIENTRY glColor3f(GLfloat r, GLfloat g, GLfloat b) { + GL_KOS_VERTEX_COLOR = PVR_PACK_COLOR(1.0f, r, g, b); } -void _glKosCompileHdr() { - pvr_poly_hdr_t *hdr = _glKosVertexBufPointer(); +void APIENTRY glColor3fv(GLfloat *rgb) { + GL_KOS_VERTEX_COLOR = PVR_PACK_COLOR(1.0f, rgb[0], rgb[1], rgb[2]); +} - /* Non-textured pvr poly header */ - pvr_poly_cxt_col(&GL_POLY_CXT, _glKosList() * 2); +void APIENTRY glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) { + GL_KOS_VERTEX_COLOR = PVR_PACK_COLOR(a, r, g, b); +} - GL_POLY_CXT.gen.shading = GL_SHADE_FUNC; +void APIENTRY glColor4fv(GLfloat *rgba) { + GL_KOS_VERTEX_COLOR = PVR_PACK_COLOR(rgba[3], rgba[0], rgba[1], rgba[2]); +} - if(GL_ENABLE_DEPTH_TEST) - GL_POLY_CXT.depth.comparison = GL_DEPTH_CMP; - else - GL_POLY_CXT.depth.comparison = PVR_DEPTHCMP_ALWAYS; +//== Texture Coordinate Submission ==// - GL_POLY_CXT.depth.write = GL_DEPTH_ENABLE; +void APIENTRY glTexCoord2f(GLfloat u, GLfloat v) { + GL_KOS_VERTEX_UV[0] = u; + GL_KOS_VERTEX_UV[1] = v; +} - if(GL_ENABLE_SCISSOR) - GL_POLY_CXT.gen.clip_mode = PVR_USERCLIP_INSIDE; +void APIENTRY glTexCoord2fv(GLfloat *uv) { + GL_KOS_VERTEX_UV[0] = uv[0]; + GL_KOS_VERTEX_UV[1] = uv[1]; +} - if(GL_ENABLE_FOG) - GL_POLY_CXT.gen.fog_type = PVR_FOG_TABLE; +//== Vertex Position Submission Functions ==// - if(GL_ENABLE_CULLING) { - if(GL_CULL_FUNC == GL_BACK) { - if(GL_FACE_FRONT == GL_CW) - GL_POLY_CXT.gen.culling = PVR_CULLING_CCW; - else - GL_POLY_CXT.gen.culling = PVR_CULLING_CW; - } - else if(GL_CULL_FUNC == GL_FRONT) { - if(GL_FACE_FRONT == GL_CCW) - GL_POLY_CXT.gen.culling = PVR_CULLING_CCW; - else - GL_POLY_CXT.gen.culling = PVR_CULLING_CW; - } - } - else - GL_POLY_CXT.gen.culling = PVR_CULLING_NONE; +void APIENTRY(*glVertex3f)(GLfloat, GLfloat, GLfloat); - pvr_poly_compile(hdr, &GL_POLY_CXT); +void APIENTRY(*glVertex3fv)(GLfloat *); - if(GL_ENABLE_SUPERSAMP) - hdr->mode2 |= GL_PVR_SAMPLE_SUPER << PVR_TA_SUPER_SAMPLE_SHIFT; +void APIENTRY glVertex2f(GLfloat x, GLfloat y) { + return _glKosVertex3ft(x, y, 0.0f); +} + +void APIENTRY glVertex2fv(GLfloat *xy) { + return _glKosVertex3ft(xy[0], xy[1], 0.0f); +} + +void APIENTRY glKosVertex2f(GLfloat x, GLfloat y) { + pvr_vertex_t *v = _glKosVertexBufPointer(); + + v->x = x; + v->y = y; + v->z = 10; + v->u = GL_KOS_VERTEX_UV[0]; + v->v = GL_KOS_VERTEX_UV[1]; + v->argb = GL_KOS_VERTEX_COLOR; _glKosVertexBufIncrement(); + + ++GL_KOS_VERTEX_COUNT; } -void _glKosCompileHdrTx() { - pvr_poly_hdr_t *hdr = _glKosVertexBufPointer(); +void APIENTRY glKosVertex2fv(GLfloat *xy) { + pvr_vertex_t *v = _glKosVertexBufPointer(); - pvr_poly_cxt_txr(&GL_POLY_CXT, _glKosList() * 2, - GL_TEX_LIST[GL_BOUND_TEX].format | - GL_TEX_LIST[GL_BOUND_TEX].type, - GL_TEX_LIST[GL_BOUND_TEX].width, - GL_TEX_LIST[GL_BOUND_TEX].height, - GL_TEX_LIST[GL_BOUND_TEX].data, - GL_TEX_LIST[GL_BOUND_TEX].filter); - - GL_POLY_CXT.gen.shading = GL_SHADE_FUNC; - - if(GL_ENABLE_DEPTH_TEST) - GL_POLY_CXT.depth.comparison = GL_DEPTH_CMP; - else - GL_POLY_CXT.depth.comparison = PVR_DEPTHCMP_ALWAYS; - - GL_POLY_CXT.depth.write = GL_DEPTH_ENABLE; - - if(GL_ENABLE_SCISSOR) - GL_POLY_CXT.gen.clip_mode = PVR_USERCLIP_INSIDE; - - if(GL_ENABLE_FOG) - GL_POLY_CXT.gen.fog_type = PVR_FOG_TABLE; - - if(GL_ENABLE_CULLING) { - if(GL_CULL_FUNC == GL_BACK) { - if(GL_FACE_FRONT == GL_CW) - GL_POLY_CXT.gen.culling = PVR_CULLING_CCW; - else - GL_POLY_CXT.gen.culling = PVR_CULLING_CW; - } - else if(GL_CULL_FUNC == GL_FRONT) { - if(GL_FACE_FRONT == GL_CCW) - GL_POLY_CXT.gen.culling = PVR_CULLING_CCW; - else - GL_POLY_CXT.gen.culling = PVR_CULLING_CW; - } - } - else - GL_POLY_CXT.gen.culling = PVR_CULLING_NONE; - - if(GL_CLAMP_ST == GL_CLAMP_UV) - GL_POLY_CXT.txr.uv_clamp = PVR_UVCLAMP_UV; - else if(GL_CLAMP_ST & GL_CLAMP_U) - GL_POLY_CXT.txr.uv_clamp = PVR_UVCLAMP_U; - else if(GL_CLAMP_ST & GL_CLAMP_V) - GL_POLY_CXT.txr.uv_clamp = PVR_UVCLAMP_V; - - GL_POLY_CXT.txr.mipmap = GL_TEX_LIST[GL_BOUND_TEX].level; - GL_POLY_CXT.txr.mipmap_bias = PVR_MIPBIAS_NORMAL; - - if(_glKosList()) { - GL_POLY_CXT.txr.env = GL_TEX_ENV; - GL_POLY_CXT.blend.src = BLEND_SRC; - GL_POLY_CXT.blend.dst = BLEND_DST; - } - - pvr_poly_compile(hdr, &GL_POLY_CXT); - - if(GL_ENABLE_SUPERSAMP) - hdr->mode2 |= GL_PVR_SAMPLE_SUPER << PVR_TA_SUPER_SAMPLE_SHIFT; + v->x = xy[0]; + v->y = xy[1]; + v->z = 10; + v->u = GL_KOS_VERTEX_UV[0]; + v->v = GL_KOS_VERTEX_UV[1]; + v->argb = GL_KOS_VERTEX_COLOR; _glKosVertexBufIncrement(); + + ++GL_KOS_VERTEX_COUNT; } +//====================================================================================================// +//== GL Begin / End ==// -void _glKosCompileHdrTx2() { - pvr_poly_hdr_t *hdr = _glKosTRVertexBufPointer(); +void APIENTRY glBegin(GLenum mode) { + _glKosMatrixApplyRender(); - pvr_poly_cxt_txr(&GL_POLY_CXT, 2, - GL_TEX_LIST[GL_BOUND_TEX1].format | - GL_TEX_LIST[GL_BOUND_TEX1].type, - GL_TEX_LIST[GL_BOUND_TEX1].width, - GL_TEX_LIST[GL_BOUND_TEX1].height, - GL_TEX_LIST[GL_BOUND_TEX1].data, - GL_TEX_LIST[GL_BOUND_TEX1].filter); + _glKosArrayBufReset(); - GL_POLY_CXT.gen.shading = GL_SHADE_FUNC; + _glKosEnabledTexture2D() ? _glKosCompileHdrTx() : _glKosCompileHdr(); - if(GL_ENABLE_DEPTH_TEST) - GL_POLY_CXT.depth.comparison = GL_DEPTH_CMP; - else - GL_POLY_CXT.depth.comparison = PVR_DEPTHCMP_ALWAYS; - - GL_POLY_CXT.depth.write = GL_DEPTH_ENABLE; - - if(GL_ENABLE_SCISSOR) - GL_POLY_CXT.gen.clip_mode = PVR_USERCLIP_INSIDE; - - if(GL_ENABLE_FOG) - GL_POLY_CXT.gen.fog_type = PVR_FOG_TABLE; - - if(GL_ENABLE_CULLING) { - if(GL_CULL_FUNC == GL_BACK) { - if(GL_FACE_FRONT == GL_CW) - GL_POLY_CXT.gen.culling = PVR_CULLING_CCW; - else - GL_POLY_CXT.gen.culling = PVR_CULLING_CW; - } - else if(GL_CULL_FUNC == GL_FRONT) { - if(GL_FACE_FRONT == GL_CCW) - GL_POLY_CXT.gen.culling = PVR_CULLING_CCW; - else - GL_POLY_CXT.gen.culling = PVR_CULLING_CW; - } - } - else - GL_POLY_CXT.gen.culling = PVR_CULLING_NONE; - - if(GL_CLAMP_ST == GL_CLAMP_UV) - GL_POLY_CXT.txr.uv_clamp = PVR_UVCLAMP_UV; - else if(GL_CLAMP_ST & GL_CLAMP_U) - GL_POLY_CXT.txr.uv_clamp = PVR_UVCLAMP_U; - else if(GL_CLAMP_ST & GL_CLAMP_V) - GL_POLY_CXT.txr.uv_clamp = PVR_UVCLAMP_V; - - GL_POLY_CXT.txr.mipmap = GL_TEX_LIST[GL_BOUND_TEX1].level; - GL_POLY_CXT.txr.mipmap_bias = PVR_MIPBIAS_NORMAL; - - GL_POLY_CXT.txr.env = GL_TEX_ENV; - GL_POLY_CXT.blend.src = BLEND_SRC; - GL_POLY_CXT.blend.dst = BLEND_DST; - - pvr_poly_compile(hdr, &GL_POLY_CXT); - - if(GL_ENABLE_SUPERSAMP) - hdr->mode2 |= GL_PVR_SAMPLE_SUPER << PVR_TA_SUPER_SAMPLE_SHIFT; - - _glKosTRVertexBufIncrement(); -} - -/* Vertex Color Submission */ - -void glColor1ui(GLuint argb) { - GL_VERTEX_COLOR = argb; -} - -void glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a) { - GL_VERTEX_COLOR = a << 24 | r << 16 | g << 8 | b; -} - -void glColor3f(float r, float g, float b) { - GL_VERTEX_COLOR = PVR_PACK_COLOR(1.0f, r, g, b); -} - -void glColor3fv(float *rgb) { - GL_VERTEX_COLOR = PVR_PACK_COLOR(1.0f, rgb[0], rgb[1], rgb[2]); -} - -void glColor4f(float r, float g, float b, float a) { - GL_VERTEX_COLOR = PVR_PACK_COLOR(a, r, g, b); -} - -void glColor4fv(float *rgba) { - GL_VERTEX_COLOR = PVR_PACK_COLOR(rgba[3], rgba[0], rgba[1], rgba[2]); -} - -/* Texture Coordinate Submission */ - -void glTexCoord2f(GLfloat u, GLfloat v) { - GL_VERTEX_UV[0] = u; - GL_VERTEX_UV[1] = v; -} - -void glTexCoord2fv(GLfloat *uv) { - GL_VERTEX_UV[0] = uv[0]; - GL_VERTEX_UV[1] = uv[1]; -} - -void glMultiTexCoord2f(GLenum target, GLfloat s, GLfloat t) { - switch(target) { - case GL_TEXTURE0: - GL_VERTEX_UV[0] = s; - GL_VERTEX_UV[1] = t; - break; - - case GL_TEXTURE1: - GL_MULTI_UV[GL_VERTICES].u = s; - GL_MULTI_UV[GL_VERTICES].v = t; - break; - } -} - -void glMultiTexCoord2fv(GLenum target, const GLfloat *v) { - switch(target) { - case GL_TEXTURE0: - GL_VERTEX_UV[0] = v[0]; - GL_VERTEX_UV[1] = v[1]; - break; - - case GL_TEXTURE1: - GL_MULTI_UV[GL_VERTICES].u = v[0]; - GL_MULTI_UV[GL_VERTICES].v = v[1]; - break; - } -} - -static inline void _glKosMultiTexCoord(pvr_vertex_t *v, GLuint count) { - GLuint i; - - for(i = 0; i < count; i++) { - v[i].u = GL_MULTI_UV[i].u; - v[i].v = GL_MULTI_UV[i].v; - } -} - -static inline void _glKosMultiTexCoordQuads(pvr_vertex_t *v, GLuint count) { - GLuint i; - - for(i = 0; i < count / 4; i += 4) { - v[i + 0].u = GL_MULTI_UV[i + 0].u; - v[i + 0].v = GL_MULTI_UV[i + 0].v; - v[i + 1].u = GL_MULTI_UV[i + 1].u; - v[i + 1].v = GL_MULTI_UV[i + 1].v; - v[i + 2].u = GL_MULTI_UV[i + 3].u; - v[i + 2].v = GL_MULTI_UV[i + 3].v; - v[i + 3].u = GL_MULTI_UV[i + 2].u; - v[i + 3].v = GL_MULTI_UV[i + 2].v; - } -} - -/* Vertex Submission */ - -static inline void _glKosVertexSwap(pvr_vertex_t *v1, pvr_vertex_t *v2) { - pvr_vertex_t tmp = *v1; - *v1 = *v2; - *v2 = * &tmp; -} - -static inline void _glKosFlagsSetQuad() { - pvr_vertex_t *v = (pvr_vertex_t *)_glKosVertexBufPointer() - GL_VERTICES; - GLuint i; - - for(i = 0; i < GL_VERTICES; i += 4) { - _glKosVertexSwap(v + 2, v + 3); - v->flags = (v + 1)->flags = (v + 2)->flags = PVR_CMD_VERTEX; - (v + 3)->flags = PVR_CMD_VERTEX_EOL; - v += 4; - } -} - -static inline void _glKosFlagsSetTriangle() { - pvr_vertex_t *v = (pvr_vertex_t *)_glKosVertexBufPointer() - GL_VERTICES; - GLuint i; - - for(i = 0; i < GL_VERTICES; i += 3) { - v->flags = (v + 1)->flags = PVR_CMD_VERTEX; - (v + 2)->flags = PVR_CMD_VERTEX_EOL; - v += 3; - } -} - -static inline void _glKosFlagsSetTriangleStrip() { - pvr_vertex_t *v = (pvr_vertex_t *)_glKosVertexBufPointer() - GL_VERTICES; - GLuint i; - - for(i = 0; i < GL_VERTICES - 1; i++) { - v->flags = PVR_CMD_VERTEX; - v++; - } - - v->flags = PVR_CMD_VERTEX_EOL; -} - -void glBegin(unsigned int mode) { - _glKosMatrixApplyRender(); /* Apply the Render Matrix Stack */ - - _glKosArrayBufReset(); /* Make sure arrays buffer is reset */ - - GL_VERTEX_MODE = mode; - - !GL_TEXTURE_ENABLED ? _glKosCompileHdr() : _glKosCompileHdrTx(); - - if(GL_TEXTURE_ENABLED & GL_TEXTURE_1) - _glKosCompileHdrTx2(); - - GL_VERTICES = 0; + GL_KOS_VERTEX_MODE = mode; + GL_KOS_VERTEX_COUNT = 0; if(mode == GL_POINTS) { glVertex3f = _glKosVertex3fp; glVertex3fv = _glKosVertex3fpv; } - else if(GL_ENABLE_CLIPZ && GL_ENABLE_LIGHTING) { + else if(_glKosEnabledNearZClip() + && _glKosEnabledLighting()) { glVertex3f = _glKosVertex3flc; glVertex3fv = _glKosVertex3flcv; } - else if(GL_ENABLE_LIGHTING) { + else if(_glKosEnabledLighting()) { glVertex3f = _glKosVertex3fl; glVertex3fv = _glKosVertex3flv; } - else if(GL_ENABLE_CLIPZ) { + else if(_glKosEnabledNearZClip()) { glVertex3f = _glKosVertex3fc; glVertex3fv = _glKosVertex3fcv; } @@ -952,42 +354,10 @@ void glBegin(unsigned int mode) { } } -void _glKosTransformClipBuf(pvr_vertex_t *v, GLuint verts) { - register float __x __asm__("fr12"); - register float __y __asm__("fr13"); - register float __z __asm__("fr14"); - - while(verts--) { - __x = v->x; - __y = v->y; - __z = v->z; - - mat_trans_fv12(); - - v->x = __x; - v->y = __y; - v->z = __z; - ++v; - } -} - -static inline void _glKosCopyMultiTexture(pvr_vertex_t *v, GLuint count) { - if(GL_TEXTURE_ENABLED & GL_TEXTURE_1) { - _glKosVertexBufCopy(_glKosTRVertexBufPointer(), v, count); - - if(GL_VERTEX_MODE == GL_QUADS) - _glKosMultiTexCoordQuads(_glKosTRVertexBufPointer(), count); - else - _glKosMultiTexCoord(_glKosTRVertexBufPointer(), count); - - _glKosTRVertexBufAdd(count); - } -} - -void glEnd() { - if(GL_ENABLE_CLIPZ) { /* Z-Clipping Enabled */ - if(GL_ENABLE_LIGHTING) { - _glKosVertexComputeLighting(_glKosClipBufAddress(), GL_VERTICES); +void APIENTRY glEnd() { + if(_glKosEnabledNearZClip()) { /* Z-Clipping Enabled */ + if(_glKosEnabledLighting()) { + _glKosVertexComputeLighting(_glKosClipBufAddress(), GL_KOS_VERTEX_COUNT); _glKosMatrixLoadRender(); } @@ -995,25 +365,22 @@ void glEnd() { GLuint cverts; pvr_vertex_t *v = _glKosVertexBufPointer(); - switch(GL_VERTEX_MODE) { + switch(GL_KOS_VERTEX_MODE) { case GL_TRIANGLES: - cverts = _glKosClipTriangles(_glKosClipBufAddress(), v, GL_VERTICES); + cverts = _glKosClipTriangles(_glKosClipBufAddress(), v, GL_KOS_VERTEX_COUNT); _glKosTransformClipBuf(v, cverts); - _glKosCopyMultiTexture(v, cverts); _glKosVertexBufAdd(cverts); break; case GL_TRIANGLE_STRIP: - cverts = _glKosClipTriangleStrip(_glKosClipBufAddress(), v, GL_VERTICES); + cverts = _glKosClipTriangleStrip(_glKosClipBufAddress(), v, GL_KOS_VERTEX_COUNT); _glKosTransformClipBuf(v, cverts); - _glKosCopyMultiTexture(v, cverts); _glKosVertexBufAdd(cverts); break; case GL_QUADS: - cverts = _glKosClipQuads(_glKosClipBufAddress(), v, GL_VERTICES); + cverts = _glKosClipQuads(_glKosClipBufAddress(), v, GL_KOS_VERTEX_COUNT); _glKosTransformClipBuf(v, cverts); - _glKosCopyMultiTexture(v, cverts); _glKosVertexBufAdd(cverts); break; } @@ -1021,10 +388,10 @@ void glEnd() { _glKosClipBufReset(); } else { /* No Z-Clipping Enabled */ - if(GL_ENABLE_LIGHTING) - _glKosVertexComputeLighting((pvr_vertex_t *)_glKosVertexBufPointer() - GL_VERTICES, GL_VERTICES); + if(_glKosEnabledLighting()) + _glKosVertexComputeLighting((pvr_vertex_t *)_glKosVertexBufPointer() - GL_KOS_VERTEX_COUNT, GL_KOS_VERTEX_COUNT); - switch(GL_VERTEX_MODE) { + switch(GL_KOS_VERTEX_MODE) { case GL_TRIANGLES: _glKosFlagsSetTriangle(); break; @@ -1037,183 +404,11 @@ void glEnd() { _glKosFlagsSetQuad(); break; } - - _glKosCopyMultiTexture((pvr_vertex_t *)_glKosVertexBufPointer() - GL_VERTICES, GL_VERTICES); } } -void glVertex2f(GLfloat x, GLfloat y) { - return _glKosVertex3ft(x, y, 0.0f); -} - -void glVertex2fv(GLfloat *xy) { - return _glKosVertex3ft(xy[0], xy[1], 0.0f); -} - -void glKosVertex2f(GLfloat x, GLfloat y) { - pvr_vertex_t *v = _glKosVertexBufPointer(); - - v->x = x; - v->y = y; - v->z = 10; - v->u = GL_VERTEX_UV[0]; - v->v = GL_VERTEX_UV[1]; - v->argb = GL_VERTEX_COLOR; - //v->oargb = GL_VERTEX_SPECULAR; - - _glKosVertexBufIncrement(); - - ++GL_VERTICES; -} - -void glKosVertex2fv(GLfloat *xy) { - pvr_vertex_t *v = _glKosVertexBufPointer(); - - v->x = xy[0]; - v->y = xy[1]; - v->z = 10; - v->u = GL_VERTEX_UV[0]; - v->v = GL_VERTEX_UV[1]; - v->argb = GL_VERTEX_COLOR; - //v->oargb = GL_VERTEX_SPECULAR; - - _glKosVertexBufIncrement(); - - ++GL_VERTICES; -} - -void _glKosVertex3fs(float x, float y, float z) { - pvr_vertex_t *v = _glKosVertexBufPointer(); - - mat_trans_single3_nomod(x, y, z, v->x, v->y, v->z); - - v->u = GL_VERTEX_UV[0]; - v->v = GL_VERTEX_UV[1]; - //v->oargb = GL_VERTEX_SPECULAR; - - _glKosVertexBufIncrement(); - - ++GL_VERTICES; -} - -void _glKosVertex3fsv(float *xyz) { - pvr_vertex_t *v = _glKosVertexBufPointer(); - - mat_trans_single3_nomod(xyz[0], xyz[1], xyz[2], v->x, v->y, v->z); - - v->u = GL_VERTEX_UV[0]; - v->v = GL_VERTEX_UV[1]; - //v->oargb = GL_VERTEX_SPECULAR; - - _glKosVertexBufIncrement(); - - ++GL_VERTICES; -} - -void _glKosVertex3ft(float x, float y, float z) { - pvr_vertex_t *v = _glKosVertexBufPointer(); - - mat_trans_single3_nomod(x, y, z, v->x, v->y, v->z); - - v->u = GL_VERTEX_UV[0]; - v->v = GL_VERTEX_UV[1]; - v->argb = GL_VERTEX_COLOR; - //v->oargb = GL_VERTEX_SPECULAR; - - _glKosVertexBufIncrement(); - - ++GL_VERTICES; -} - -void _glKosVertex3ftv(float *xyz) { - pvr_vertex_t *v = _glKosVertexBufPointer(); - - mat_trans_single3_nomod(xyz[0], xyz[1], xyz[2], v->x, v->y, v->z); - - v->u = GL_VERTEX_UV[0]; - v->v = GL_VERTEX_UV[1]; - v->argb = GL_VERTEX_COLOR; - //v->oargb = GL_VERTEX_SPECULAR; - - _glKosVertexBufIncrement(); - - ++GL_VERTICES; -} - -void _glKosVertex3fc(float x, float y, float z) { - pvr_vertex_t *v = _glKosClipBufPointer(); - - v->x = x; - v->y = y; - v->z = z; - v->u = GL_VERTEX_UV[0]; - v->v = GL_VERTEX_UV[1]; - v->argb = GL_VERTEX_COLOR; - //v->oargb = GL_VERTEX_SPECULAR; - - _glKosClipBufIncrement(); - - ++GL_VERTICES; -} - -void _glKosVertex3fcv(float *xyz) { - pvr_vertex_t *v = _glKosClipBufPointer(); - - v->x = xyz[0]; - v->y = xyz[1]; - v->z = xyz[2]; - v->u = GL_VERTEX_UV[0]; - v->v = GL_VERTEX_UV[1]; - v->argb = GL_VERTEX_COLOR; - //v->oargb = GL_VERTEX_SPECULAR; - - _glKosClipBufIncrement(); - - ++GL_VERTICES; -} - -/* GL_POINTS */ -static float GL_POINT_SIZE = 0.02; - -inline void _glKosVertex3fpa(float x, float y, float z) { - pvr_vertex_t *v = _glKosVertexBufPointer(); - - mat_trans_single3_nomod(x, y, z, v->x, v->y, v->z); - - v->argb = GL_VERTEX_COLOR; - //v->oargb = GL_VERTEX_SPECULAR; - v->flags = PVR_CMD_VERTEX; - - _glKosVertexBufIncrement(); -} - -inline void _glKosVertex3fpb(float x, float y, float z) { - pvr_vertex_t *v = _glKosVertexBufPointer(); - - mat_trans_single3_nomod(x, y, z, v->x, v->y, v->z); - - v->argb = GL_VERTEX_COLOR; - //v->oargb = GL_VERTEX_SPECULAR; - v->flags = PVR_CMD_VERTEX_EOL; - - _glKosVertexBufIncrement(); -} - -void _glKosVertex3fp(float x, float y, float z) { - _glKosVertex3fpa(x - GL_POINT_SIZE, y - GL_POINT_SIZE, z); - _glKosVertex3fpa(x + GL_POINT_SIZE, y - GL_POINT_SIZE, z); - _glKosVertex3fpa(x - GL_POINT_SIZE, y + GL_POINT_SIZE, z); - _glKosVertex3fpb(x + GL_POINT_SIZE, y + GL_POINT_SIZE, z); -} - -void _glKosVertex3fpv(float *xyz) { - _glKosVertex3fpa(xyz[0] - GL_POINT_SIZE, xyz[1] - GL_POINT_SIZE, xyz[2]); - _glKosVertex3fpa(xyz[0] + GL_POINT_SIZE, xyz[1] - GL_POINT_SIZE, xyz[2]); - _glKosVertex3fpa(xyz[0] - GL_POINT_SIZE, xyz[1] + GL_POINT_SIZE, xyz[2]); - _glKosVertex3fpb(xyz[0] + GL_POINT_SIZE, xyz[1] + GL_POINT_SIZE, xyz[2]); -} - -/* Misc. functions */ +//====================================================================================================// +//== Misc. functions ==// /* Clamp X to [MIN,MAX]: */ #define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) ) @@ -1231,7 +426,7 @@ void _glKosVertex3fpv(float *xyz) { hand corner of the screen to be modified and glScissor(0, 0, 0, 0) disallows modification to all 'tiles' on the screen. */ -void glScissor(GLint x, GLint y, GLsizei width, GLsizei height) { +void APIENTRY glScissor(GLint x, GLint y, GLsizei width, GLsizei height) { pvr_cmd_tclip_t *c = _glKosVertexBufPointer(); GLint miny, maxx, maxy; @@ -1254,30 +449,402 @@ void glScissor(GLint x, GLint y, GLsizei width, GLsizei height) { _glKosVertexBufIncrement(); } -void glHint(GLenum target, GLenum mode) { +void APIENTRY glHint(GLenum target, GLenum mode) { switch(target) { case GL_PERSPECTIVE_CORRECTION_HINT: if(mode == GL_NICEST) - GL_ENABLE_SUPERSAMP = 1; + GL_KOS_SUPERSAMPLE = 1; else - GL_ENABLE_SUPERSAMP = 0; + GL_KOS_SUPERSAMPLE = 0; break; } + } -GLint _glKosEnabledTexture2D() { - return GL_TEXTURE_ENABLED; +//====================================================================================================// +//== Internal API Vertex Submission functions ==// + +void _glKosVertex3fs(GLfloat x, GLfloat y, GLfloat z) { + pvr_vertex_t *v = _glKosVertexBufPointer(); + + mat_trans_single3_nomod(x, y, z, v->x, v->y, v->z); + + v->u = GL_KOS_VERTEX_UV[0]; + v->v = GL_KOS_VERTEX_UV[1]; + + _glKosVertexBufIncrement(); + + ++GL_KOS_VERTEX_COUNT; } -GLubyte _glKosEnabledNearZClip() { - return GL_ENABLE_CLIPZ; +void _glKosVertex3fsv(GLfloat *xyz) { + pvr_vertex_t *v = _glKosVertexBufPointer(); + + mat_trans_single3_nomod(xyz[0], xyz[1], xyz[2], v->x, v->y, v->z); + + v->u = GL_KOS_VERTEX_UV[0]; + v->v = GL_KOS_VERTEX_UV[1]; + + _glKosVertexBufIncrement(); + + ++GL_KOS_VERTEX_COUNT; } -GLubyte _glKosEnabledLighting() { - return GL_ENABLE_LIGHTING; +void _glKosVertex3ft(GLfloat x, GLfloat y, GLfloat z) { + pvr_vertex_t *v = _glKosVertexBufPointer(); + + mat_trans_single3_nomod(x, y, z, v->x, v->y, v->z); + + v->u = GL_KOS_VERTEX_UV[0]; + v->v = GL_KOS_VERTEX_UV[1]; + v->argb = GL_KOS_VERTEX_COLOR; + + _glKosVertexBufIncrement(); + + ++GL_KOS_VERTEX_COUNT; } -inline void _glKosResetEnabledTex() { - GL_TEXTURE_ENABLED = GL_CUR_ACTIVE_TEX = 0; +void _glKosVertex3ftv(GLfloat *xyz) { + pvr_vertex_t *v = _glKosVertexBufPointer(); + + mat_trans_single3_nomod(xyz[0], xyz[1], xyz[2], v->x, v->y, v->z); + + v->u = GL_KOS_VERTEX_UV[0]; + v->v = GL_KOS_VERTEX_UV[1]; + v->argb = GL_KOS_VERTEX_COLOR; + + _glKosVertexBufIncrement(); + + ++GL_KOS_VERTEX_COUNT; } + +void _glKosVertex3fc(GLfloat x, GLfloat y, GLfloat z) { + pvr_vertex_t *v = _glKosClipBufPointer(); + + v->x = x; + v->y = y; + v->z = z; + v->u = GL_KOS_VERTEX_UV[0]; + v->v = GL_KOS_VERTEX_UV[1]; + v->argb = GL_KOS_VERTEX_COLOR; + + _glKosClipBufIncrement(); + + ++GL_KOS_VERTEX_COUNT; +} + +void _glKosVertex3fcv(GLfloat *xyz) { + pvr_vertex_t *v = _glKosClipBufPointer(); + + v->x = xyz[0]; + v->y = xyz[1]; + v->z = xyz[2]; + v->u = GL_KOS_VERTEX_UV[0]; + v->v = GL_KOS_VERTEX_UV[1]; + v->argb = GL_KOS_VERTEX_COLOR; + + _glKosClipBufIncrement(); + + ++GL_KOS_VERTEX_COUNT; +} + +/* GL_POINTS */ + +inline void _glKosVertex3fpa(GLfloat x, GLfloat y, GLfloat z) { + pvr_vertex_t *v = _glKosVertexBufPointer(); + + mat_trans_single3_nomod(x, y, z, v->x, v->y, v->z); + + v->argb = GL_KOS_VERTEX_COLOR; + v->flags = PVR_CMD_VERTEX; + + _glKosVertexBufIncrement(); +} + +inline void _glKosVertex3fpb(GLfloat x, GLfloat y, GLfloat z) { + pvr_vertex_t *v = _glKosVertexBufPointer(); + + mat_trans_single3_nomod(x, y, z, v->x, v->y, v->z); + + v->argb = GL_KOS_VERTEX_COLOR; + v->flags = PVR_CMD_VERTEX_EOL; + + _glKosVertexBufIncrement(); +} + +void _glKosVertex3fp(GLfloat x, GLfloat y, GLfloat z) { + _glKosVertex3fpa(x - GL_KOS_POINT_SIZE, y - GL_KOS_POINT_SIZE, z); + _glKosVertex3fpa(x + GL_KOS_POINT_SIZE, y - GL_KOS_POINT_SIZE, z); + _glKosVertex3fpa(x - GL_KOS_POINT_SIZE, y + GL_KOS_POINT_SIZE, z); + _glKosVertex3fpb(x + GL_KOS_POINT_SIZE, y + GL_KOS_POINT_SIZE, z); +} + +void _glKosVertex3fpv(GLfloat *xyz) { + _glKosVertex3fpa(xyz[0] - GL_KOS_POINT_SIZE, xyz[1] - GL_KOS_POINT_SIZE, xyz[2]); + _glKosVertex3fpa(xyz[0] + GL_KOS_POINT_SIZE, xyz[1] - GL_KOS_POINT_SIZE, xyz[2]); + _glKosVertex3fpa(xyz[0] - GL_KOS_POINT_SIZE, xyz[1] + GL_KOS_POINT_SIZE, xyz[2]); + _glKosVertex3fpb(xyz[0] + GL_KOS_POINT_SIZE, xyz[1] + GL_KOS_POINT_SIZE, xyz[2]); +} + +void _glKosTransformClipBuf(pvr_vertex_t *v, GLuint verts) { + register float __x __asm__("fr12"); + register float __y __asm__("fr13"); + register float __z __asm__("fr14"); + + while(verts--) { + __x = v->x; + __y = v->y; + __z = v->z; + + mat_trans_fv12(); + + v->x = __x; + v->y = __y; + v->z = __z; + ++v; + } +} + +static inline void _glKosVertexSwap(pvr_vertex_t *v1, pvr_vertex_t *v2) { + pvr_vertex_t tmp = *v1; + *v1 = *v2; + *v2 = * &tmp; +} + +static inline void _glKosFlagsSetQuad() { + pvr_vertex_t *v = (pvr_vertex_t *)_glKosVertexBufPointer() - GL_KOS_VERTEX_COUNT; + GLuint i; + + for(i = 0; i < GL_KOS_VERTEX_COUNT; i += 4) { + _glKosVertexSwap(v + 2, v + 3); + v->flags = (v + 1)->flags = (v + 2)->flags = PVR_CMD_VERTEX; + (v + 3)->flags = PVR_CMD_VERTEX_EOL; + v += 4; + } +} + +static inline void _glKosFlagsSetTriangle() { + pvr_vertex_t *v = (pvr_vertex_t *)_glKosVertexBufPointer() - GL_KOS_VERTEX_COUNT; + GLuint i; + + for(i = 0; i < GL_KOS_VERTEX_COUNT; i += 3) { + v->flags = (v + 1)->flags = PVR_CMD_VERTEX; + (v + 2)->flags = PVR_CMD_VERTEX_EOL; + v += 3; + } +} + +static inline void _glKosFlagsSetTriangleStrip() { + pvr_vertex_t *v = (pvr_vertex_t *)_glKosVertexBufPointer() - GL_KOS_VERTEX_COUNT; + GLuint i; + + for(i = 0; i < GL_KOS_VERTEX_COUNT - 1; i++) { + v->flags = PVR_CMD_VERTEX; + v++; + } + + v->flags = PVR_CMD_VERTEX_EOL; +} + +//====================================================================================================// +//== GL KOS PVR Header Parameter Compilation Functions ==// + +static inline void _glKosApplyDepthFunc() { + if(_glKosEnabledDepthTest()) + GL_KOS_POLY_CXT.depth.comparison = GL_KOS_DEPTH_FUNC; + else + GL_KOS_POLY_CXT.depth.comparison = PVR_DEPTHCMP_ALWAYS; + + GL_KOS_POLY_CXT.depth.write = GL_KOS_DEPTH_WRITE; +} + +static inline void _glKosApplyScissorFunc() { + if(_glKosEnabledScissorTest()) + GL_KOS_POLY_CXT.gen.clip_mode = PVR_USERCLIP_INSIDE; +} + +static inline void _glKosApplyFogFunc() { + if(_glKosEnabledFog()) + GL_KOS_POLY_CXT.gen.fog_type = PVR_FOG_TABLE; +} + +static inline void _glKosApplyCullingFunc() { + if(_glKosEnabledCulling()) { + if(GL_KOS_CULL_FUNC == GL_BACK) { + if(GL_KOS_FACE_FRONT == GL_CW) + GL_KOS_POLY_CXT.gen.culling = PVR_CULLING_CCW; + else + GL_KOS_POLY_CXT.gen.culling = PVR_CULLING_CW; + } + else if(GL_KOS_CULL_FUNC == GL_FRONT) { + if(GL_KOS_FACE_FRONT == GL_CCW) + GL_KOS_POLY_CXT.gen.culling = PVR_CULLING_CCW; + else + GL_KOS_POLY_CXT.gen.culling = PVR_CULLING_CW; + } + } + else + GL_KOS_POLY_CXT.gen.culling = PVR_CULLING_NONE; +} + +static inline void _glKosApplyBlendFunc() { + if(_glKosEnabledBlend()) { + GL_KOS_POLY_CXT.blend.src = (GL_KOS_BLEND_FUNC & 0xF0) >> 4; + GL_KOS_POLY_CXT.blend.dst = (GL_KOS_BLEND_FUNC & 0x0F); + } +} + +void _glKosCompileHdr() { + pvr_poly_hdr_t *hdr = _glKosVertexBufPointer(); + + pvr_poly_cxt_col(&GL_KOS_POLY_CXT, _glKosList() * 2); + + GL_KOS_POLY_CXT.gen.shading = GL_KOS_SHADE_FUNC; + + _glKosApplyDepthFunc(); + + _glKosApplyScissorFunc(); + + _glKosApplyFogFunc(); + + _glKosApplyCullingFunc(); + + _glKosApplyBlendFunc(); + + pvr_poly_compile(hdr, &GL_KOS_POLY_CXT); + + _glKosVertexBufIncrement(); +} + +void _glKosCompileHdrT(GL_TEXTURE_OBJECT *tex) { + pvr_poly_hdr_t *hdr = _glKosVertexBufPointer(); + + pvr_poly_cxt_txr(&GL_KOS_POLY_CXT, + _glKosList() * 2, + tex->color, + tex->width, + tex->height, + tex->data, + tex->filter); + + GL_KOS_POLY_CXT.gen.shading = GL_KOS_SHADE_FUNC; + + _glKosApplyDepthFunc(); + + _glKosApplyScissorFunc(); + + _glKosApplyFogFunc(); + + _glKosApplyCullingFunc(); + + _glKosApplyBlendFunc(); + + 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; + + if(_glKosEnabledBlend()) + GL_KOS_POLY_CXT.txr.env = tex->env; + + pvr_poly_compile(hdr, &GL_KOS_POLY_CXT); + + if(GL_KOS_SUPERSAMPLE) + hdr->mode2 |= GL_PVR_SAMPLE_SUPER << PVR_TA_SUPER_SAMPLE_SHIFT; + + _glKosVertexBufIncrement(); +} + +//====================================================================================================// +//== Internal GL KOS API State Functions ==// + +GLuint _glKosBlendSrcFunc() { + switch((GL_KOS_BLEND_FUNC & 0xF0) >> 4) { + case PVR_BLEND_ONE: + return GL_ONE; + + case PVR_BLEND_ZERO: + return GL_ZERO; + + case PVR_BLEND_DESTCOLOR: + return GL_DST_COLOR; + + case PVR_BLEND_SRCALPHA: + return GL_SRC_ALPHA; + + case PVR_BLEND_DESTALPHA: + return GL_DST_ALPHA; + + case PVR_BLEND_INVSRCALPHA: + return GL_ONE_MINUS_SRC_ALPHA; + + case PVR_BLEND_INVDESTALPHA: + return GL_ONE_MINUS_DST_ALPHA; + + case PVR_BLEND_INVDESTCOLOR: + return GL_ONE_MINUS_DST_COLOR; + } + + return 0; +} + +GLuint _glKosBlendDstFunc() { + switch(GL_KOS_BLEND_FUNC & 0xF) { + case PVR_BLEND_ONE: + return GL_ONE; + + case PVR_BLEND_ZERO: + return GL_ZERO; + + case PVR_BLEND_DESTCOLOR: + return GL_DST_COLOR; + + case PVR_BLEND_SRCALPHA: + return GL_SRC_ALPHA; + + case PVR_BLEND_DESTALPHA: + return GL_DST_ALPHA; + + case PVR_BLEND_INVSRCALPHA: + return GL_ONE_MINUS_SRC_ALPHA; + + case PVR_BLEND_INVDESTALPHA: + return GL_ONE_MINUS_DST_ALPHA; + + case PVR_BLEND_INVDESTCOLOR: + return GL_ONE_MINUS_DST_COLOR; + } + + return 0; +} + +GLubyte _glKosCullFaceMode() { + return GL_KOS_CULL_FUNC; +} + +GLubyte _glKosCullFaceFront() { + return GL_KOS_FACE_FRONT; +} + +GLuint _glKosDepthFunc() { + switch(GL_KOS_DEPTH_FUNC) { + case PVR_DEPTHCMP_GEQUAL: + return GL_LESS; + + case PVR_DEPTHCMP_GREATER: + return GL_LEQUAL; + + case PVR_DEPTHCMP_LEQUAL: + return GL_GREATER; + + case PVR_DEPTHCMP_LESS: + return GL_GEQUAL; + + default: + return GL_NEVER + GL_KOS_DEPTH_FUNC; + } +} + +GLubyte _glKosDepthMask() { + return !GL_KOS_DEPTH_WRITE; +} \ No newline at end of file diff --git a/gl-api.h b/gl-api.h index 585ecd9..7848635 100755 --- a/gl-api.h +++ b/gl-api.h @@ -1,7 +1,7 @@ /* KallistiGL for KallistiOS ##version## libgl/gl-api.h - Copyright (C) 2013-2014 Josh "PH3NOM" Pearson + Copyright (C) 2013-2014 Josh Pearson The functions defined in this header are for internal use by the API, and not for use externally. @@ -15,6 +15,26 @@ typedef struct { float norm[3]; } glVertex; /* Simple Vertex used for Dynamic Vertex Lighting */ +typedef struct { + GLushort width; + GLushort height; + GLuint color; + GLubyte env; + GLubyte filter; + GLubyte mip_map; + GLubyte uv_clamp; + GLuint index; + GLvoid *data; + GLvoid *link; +} GL_TEXTURE_OBJECT; /* KOS Open GL Texture Object */ + +typedef struct { + GLuint texID; + GLsizei index; + GLvoid *data; + GLvoid *link; +} GL_FRAMEBUFFER_OBJECT; /* KOS Open GL Frame Buffer Object */ + typedef unsigned short uint16; typedef unsigned char uint8; @@ -49,11 +69,13 @@ inline glVertex *_glKosArrayBufPtr(); /* Initialize the OpenGL PVR Pipeline */ int _glKosInitPVR(); +GLubyte _glKosInitTextures(); /* Compile the current Polygon Header for the PVR */ void _glKosCompileHdr(); void _glKosCompileHdrTx(); void _glKosCompileHdrTx2(); +void _glKosCompileHdrT(GL_TEXTURE_OBJECT *tex); /* Clipping Internal Functions */ void _glKosTransformClipBuf(pvr_vertex_t *v, GLuint verts); @@ -101,9 +123,14 @@ void _glKosMatrixApplyRender(); void _glKosMatrixLoadRender(); /* API Enabled Capabilities Internal Functions */ -GLint _glKosEnabledTexture2D(); +GLubyte _glKosEnabledBlend(); +GLubyte _glKosEnabledTexture2D(); GLubyte _glKosEnabledNearZClip(); GLubyte _glKosEnabledLighting(); +GLubyte _glKosEnabledFog(); +GLubyte _glKosEnabledCulling(); +GLubyte _glKosEnabledScissorTest(); +GLubyte _glKosEnabledDepthTest(); /* RGB Pixel Colorspace Internal Functions */ uint16 __glKosAverageQuadPixelRGB565(uint16 p1, uint16 p2, uint16 p3, uint16 p4); @@ -113,4 +140,42 @@ uint16 __glKosAverageBiPixelRGB565(uint16 p1, uint16 p2); uint16 __glKosAverageBiPixelARGB1555(uint16 p1, uint16 p2); uint16 __glKosAverageBiPixelARGB4444(uint16 p1, uint16 p2); +/* Render-To-Texture Functions */ +void _glKosInitFrameBuffers(); + +/* Error Codes */ +void _glKosThrowError(GLenum error, char *functionName); +void _glKosResetError(); +void _glKosPrintError(); +GLsizei _glKosGetError(); + +GLuint _glKosTextureWidth(GLuint index); +GLuint _glKosTextureHeight(GLuint index); +GLvoid *_glKosTextureData(GLuint index); + +/* Frame Buffer Object Internal Functions */ +GLsizei _glKosGetFBO(); +GLuint _glKosGetFBOWidth(GLsizei fbi); +GLuint _glKosGetFBOHeight(GLsizei fbi); +GLvoid *_glKosGetFBOData(GLsizei fbi); + +/* Internal State Cap Accessors */ +GLubyte _glKosEnabledDepthTest(); +GLubyte _glKosEnabledScissorTest(); +GLubyte _glKosEnabledCulling(); +GLubyte _glKosEnabledFog(); +GLubyte _glKosEnabledLighting(); +GLubyte _glKosEnabledNearZClip(); +GLubyte _glKosEnabledTexture2D(); +GLubyte _glKosEnabledBlend(); +GLuint _glKosBlendSrcFunc(); +GLuint _glKosBlendDstFunc(); +GLubyte _glKosCullFaceMode(); +GLubyte _glKosCullFaceFront(); +GLuint _glKosDepthFunc(); +GLubyte _glKosDepthMask(); +GLubyte _glKosIsLightEnabled(GLubyte light); +GLubyte _glKosGetMaxLights(); +GLuint _glKosBoundTexID(); + #endif diff --git a/gl-arrays.c b/gl-arrays.c index 06f3597..315761f 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 "PH3NOM" Pearson + Copyright (C) 2013-2014 Josh Pearson Arrays Input Primitive Types Supported: -GL_TRIANGLES @@ -34,102 +34,6 @@ static GLfloat GL_ARRAY_DSTW[GL_MAX_ARRAY_VERTICES]; static glVertex *GL_ARRAY_BUF_PTR; static GLuint GL_VERTEX_PTR_MODE = 0; -//========================================================================================// -//== Multi-Texture Extensions ==// - -#define GL_TEXTURE_0 1<<0 -#define GL_TEXTURE_1 1<<1 - -static GLuint GL_ARRAY_TEXTURE_ENABLED = 0; -static GLuint GL_ARRAY_ACTIVE_TEXTURE = 0; - -GLAPI void APIENTRY glClientActiveTexture(GLenum texture) { - if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + GL_MAX_TEXTURE_UNITS) - return; - - GL_ARRAY_ACTIVE_TEXTURE = ((texture & 0xFF) - (GL_TEXTURE0 & 0xFF)); - - return glActiveTexture(texture); -} - -static inline void _glKosArrayCopyMultiTexture(GLuint count) { - if(GL_ARRAY_TEXTURE_ENABLED == 3) { - pvr_vertex_t *dst = _glKosTRVertexBufPointer(); - pvr_vertex_t *src = _glKosVertexBufPointer(); - GLuint i; - - for(i = 0; i < count; i++) { - dst[i].x = src[i].x; - dst[i].y = src[i].y; - dst[i].z = src[i].z; - dst[i].argb = src[i].argb; - dst[i].flags = src[i].flags; - - dst[i].u = GL_TEXCOORD2_POINTER[0]; - dst[i].v = GL_TEXCOORD2_POINTER[1]; - GL_TEXCOORD2_POINTER += GL_TEXCOORD2_STRIDE; - } - - _glKosTRVertexBufAdd(count); - } -} - -static inline void _glKosArrayCopyMultiTextureQuads(GLuint count) { - if(GL_ARRAY_TEXTURE_ENABLED == 3) { - pvr_vertex_t *dst = _glKosTRVertexBufPointer(); - pvr_vertex_t *src = _glKosVertexBufPointer(); - GLuint i; - - for(i = 0; i < count; i += 4) { - /* 1st Vertex */ - dst[i].x = src[i].x; - dst[i].y = src[i].y; - dst[i].z = src[i].z; - dst[i].argb = src[i].argb; - dst[i].flags = src[i].flags; - - dst[i].u = GL_TEXCOORD2_POINTER[0]; - dst[i].v = GL_TEXCOORD2_POINTER[1]; - GL_TEXCOORD2_POINTER += GL_TEXCOORD2_STRIDE; - - /* 2nd Vertex */ - dst[i + 1].x = src[i + 1].x; - dst[i + 1].y = src[i + 1].y; - dst[i + 1].z = src[i + 1].z; - dst[i + 1].argb = src[i + 1].argb; - dst[i + 1].flags = src[i + 1].flags; - - dst[i + 1].u = GL_TEXCOORD2_POINTER[0]; - dst[i + 1].v = GL_TEXCOORD2_POINTER[1]; - GL_TEXCOORD2_POINTER += GL_TEXCOORD2_STRIDE; - - /* 3rd Vertex */ - dst[i + 2].x = src[i + 2].x; - dst[i + 2].y = src[i + 2].y; - dst[i + 2].z = src[i + 2].z; - dst[i + 2].argb = src[i + 2].argb; - dst[i + 2].flags = src[i + 2].flags; - - dst[i + 3].u = GL_TEXCOORD2_POINTER[0]; - dst[i + 3].v = GL_TEXCOORD2_POINTER[1]; - GL_TEXCOORD2_POINTER += GL_TEXCOORD2_STRIDE; - - /* 4th Vertex */ - dst[i + 3].x = src[i + 3].x; - dst[i + 3].y = src[i + 3].y; - dst[i + 3].z = src[i + 3].z; - dst[i + 3].argb = src[i + 3].argb; - dst[i + 3].flags = src[i + 3].flags; - - dst[i + 2].u = GL_TEXCOORD2_POINTER[0]; - dst[i + 2].v = GL_TEXCOORD2_POINTER[1]; - GL_TEXCOORD2_POINTER += GL_TEXCOORD2_STRIDE; - } - - _glKosTRVertexBufAdd(count); - } -} - //========================================================================================// //== Local Function Definitions ==// @@ -142,9 +46,19 @@ static inline void _glKosArraysTransformPositions(GLfloat *position, GLuint coun /* Submit a Vertex Position Pointer */ GLAPI void APIENTRY glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { - if(size != 3) return; /* Expect 3D X,Y,Z vertex... could do 2d X,Y later */ + if(size != 3) /* Expect 3D X,Y,Z vertex... could do 2d X,Y later */ + _glKosThrowError(GL_INVALID_VALUE, "glVertexPointer"); - if(type != GL_FLOAT) return; /* Expect Floating point vertices */ + if(type != GL_FLOAT) /* Expect Floating point vertices */ + _glKosThrowError(GL_INVALID_ENUM, "glVertexPointer"); + + if(stride < 0) + _glKosThrowError(GL_INVALID_VALUE, "glVertexPointer"); + + if(_glKosGetError()) { + _glKosPrintError(); + return; + } (stride) ? (GL_VERTEX_STRIDE = stride / 4) : (GL_VERTEX_STRIDE = 3); @@ -155,7 +69,16 @@ GLAPI void APIENTRY glVertexPointer(GLint size, GLenum type, /* Submit a Vertex Normal Pointer */ GLAPI void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer) { - if(type != GL_FLOAT) return; /* Expect Floating point vertices */ + if(type != GL_FLOAT) /* Expect Floating point vertices */ + _glKosThrowError(GL_INVALID_ENUM, "glNormalPointer"); + + if(stride < 0) + _glKosThrowError(GL_INVALID_VALUE, "glNormalPointer"); + + if(_glKosGetError()) { + _glKosPrintError(); + return; + } (stride) ? (GL_NORMAL_STRIDE = stride / 4) : (GL_NORMAL_STRIDE = 3); @@ -167,26 +90,25 @@ GLAPI void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *p /* Submit a Texture Coordinate Pointer */ GLAPI void APIENTRY glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { - if(size != 2) return; /* Expect u and v */ + if(size != 2) /* Expect u and v */ + _glKosThrowError(GL_INVALID_VALUE, "glTexCoordPointer"); - if(type != GL_FLOAT) return; /* Expect Floating point vertices */ + if(type != GL_FLOAT) /* Expect Floating point vertices */ + _glKosThrowError(GL_INVALID_ENUM, "glTexCoordPointer"); - if(GL_ARRAY_ACTIVE_TEXTURE == 0) { - (stride) ? (GL_TEXCOORD_STRIDE = stride / 4) : (GL_TEXCOORD_STRIDE = 2); + if(stride < 0) + _glKosThrowError(GL_INVALID_VALUE, "glTexCoordPointer"); - GL_TEXCOORD_POINTER = (float *)pointer; - - GL_VERTEX_PTR_MODE |= GL_USE_TEXTURE; - - GL_ARRAY_TEXTURE_ENABLED |= GL_TEXTURE_0; + if(_glKosGetError()) { + _glKosPrintError(); + return; } - else if(GL_ARRAY_ACTIVE_TEXTURE == 1) { - (stride) ? (GL_TEXCOORD2_STRIDE = stride / 4) : (GL_TEXCOORD2_STRIDE = 2); - GL_TEXCOORD2_POINTER = (float *)pointer; + (stride) ? (GL_TEXCOORD_STRIDE = stride / 4) : (GL_TEXCOORD_STRIDE = 2); - GL_ARRAY_TEXTURE_ENABLED |= GL_TEXTURE_1; - } + GL_TEXCOORD_POINTER = (float *)pointer; + + GL_VERTEX_PTR_MODE |= GL_USE_TEXTURE; } /* Submit a Color Pointer */ @@ -212,8 +134,11 @@ GLAPI void APIENTRY glColorPointer(GLint size, GLenum type, GL_COLOR_POINTER = (GLfloat *)pointer; GL_COLOR_TYPE = type; } - else + else { + _glKosThrowError(GL_INVALID_ENUM, "glColorPointer"); + _glKosPrintError(); return; + } (stride) ? (GL_COLOR_STRIDE = stride / 4) : (GL_COLOR_STRIDE = size); @@ -541,11 +466,6 @@ static inline void _glKosVertexSwizzle(pvr_vertex_t *v1, pvr_vertex_t *v2) { static inline void _glKosArraysResetState() { GL_VERTEX_PTR_MODE = 0; - - if(GL_ARRAY_TEXTURE_ENABLED == 3) - _glKosResetEnabledTex(); - - GL_ARRAY_TEXTURE_ENABLED = GL_ARRAY_ACTIVE_TEXTURE = 0; } //========================================================================================// @@ -659,14 +579,11 @@ GLAPI void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, cons } /* Compile the PVR polygon context with the currently enabled flags */ - if((GL_VERTEX_PTR_MODE & GL_USE_TEXTURE)) + if((GL_VERTEX_PTR_MODE & GL_USE_TEXTURE) && _glKosBoundTexID() > 0) _glKosCompileHdrTx(); else _glKosCompileHdr(); - if(GL_ARRAY_TEXTURE_ENABLED == 3) /* Multi-Texture! */ - _glKosCompileHdrTx2(); - pvr_vertex_t *dst; /* Destination of Output Vertex Array */ if(_glKosEnabledNearZClip()) @@ -788,11 +705,6 @@ GLAPI void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, cons _glKosArrayFlagsSetTriangleStrip(dst, count); break; } - - if(mode == GL_QUADS) - _glKosArrayCopyMultiTextureQuads(count); - else - _glKosArrayCopyMultiTexture(count); } else { /* Transform vertices with no perspective divde, store w component */ @@ -924,14 +836,11 @@ GLAPI void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count) { GL_NORMAL_POINTER += first; /* Compile the PVR polygon context with the currently enabled flags */ - if((GL_VERTEX_PTR_MODE & GL_USE_TEXTURE)) + if((GL_VERTEX_PTR_MODE & GL_USE_TEXTURE) && _glKosBoundTexID() > 0) _glKosCompileHdrTx(); else _glKosCompileHdr(); - if(GL_ARRAY_TEXTURE_ENABLED == 3) /* Multi-Texture! */ - _glKosCompileHdrTx2(); - pvr_vertex_t *dst; /* Destination of Output Vertex Array */ if(_glKosEnabledNearZClip()) @@ -1000,11 +909,6 @@ GLAPI void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count) { _glKosArrayFlagsSetTriangleStrip(dst, count); break; } - - if(mode == GL_QUADS) - _glKosArrayCopyMultiTextureQuads(count); - else - _glKosArrayCopyMultiTexture(count); } else { /* Transform vertices with no perspective divde, store w component */ diff --git a/gl-arrays.h b/gl-arrays.h index 16e5fa2..0e6fd2b 100755 --- a/gl-arrays.h +++ b/gl-arrays.h @@ -1,7 +1,7 @@ /* KallistiGL for KallistiOS ##version## libgl/gl-arrays.h - Copyright (C) 2013-2014 Josh "PH3NOM" Pearson + Copyright (C) 2013-2014 Josh Pearson Arrays Input Primitive Types Supported: -GL_TRIANGLES @@ -44,9 +44,6 @@ static GLushort GL_NORMAL_STRIDE = 0; static GLfloat *GL_TEXCOORD_POINTER = NULL; static GLushort GL_TEXCOORD_STRIDE = 0; -static GLfloat *GL_TEXCOORD2_POINTER = NULL; -static GLushort GL_TEXCOORD2_STRIDE = 0; - static GLfloat *GL_COLOR_POINTER = NULL; static GLushort GL_COLOR_STRIDE = 0; static GLubyte GL_COLOR_COMPONENTS = 0; diff --git a/gl-cap.c b/gl-cap.c new file mode 100755 index 0000000..c307d9a --- /dev/null +++ b/gl-cap.c @@ -0,0 +1,250 @@ +/* KallistiGL for KallistiOS ##version## + + libgl/gl-cap.c + Copyright (C) 2014 Josh Pearson + + KOS Open GL Capabilty State Machine Implementation. +*/ + +#include "gl.h" +#include "gl-api.h" + +#include +#include + +//===============================================================================// +//== Enable Bit Flags ==// + +#define GL_KOS_ENABLE_DEPTH_TEST (1<<0) +#define GL_KOS_ENABLE_SCISSOR_TEST (1<<1) +#define GL_KOS_ENABLE_CULLING (1<<2) +#define GL_KOS_ENABLE_FOG (1<<3) +#define GL_KOS_ENABLE_LIGHTING (1<<4) +#define GL_KOS_ENABLE_ZCLIPPING (1<<5) +#define GL_KOS_ENABLE_SUPERSAMPLE (1<<6) +#define GL_KOS_ENABLE_TEXTURE2D (1<<7) +#define GL_KOS_ENABLE_BLENDING (1<<8) + +static GLbitfield GL_KOS_ENABLE_CAP = 0; + +//===============================================================================// +//== External API Functions ==// + +void APIENTRY glEnable(GLenum cap) { + if(cap >= GL_LIGHT0 && cap <= GL_LIGHT15) return _glKosEnableLight(cap); + + switch(cap) { + case GL_TEXTURE_2D: + GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_TEXTURE2D; + break; + + case GL_BLEND: + GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_BLENDING; + _glKosVertexBufSwitchTR(); + break; + + case GL_DEPTH_TEST: + GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_DEPTH_TEST; + break; + + case GL_LIGHTING: + GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_LIGHTING; + break; + + case GL_KOS_NEARZ_CLIPPING: + GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_ZCLIPPING; + break; + + case GL_SCISSOR_TEST: + GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_SCISSOR_TEST; + break; + + case GL_FOG: + GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_FOG; + break; + + case GL_CULL_FACE: + GL_KOS_ENABLE_CAP |= GL_KOS_ENABLE_CULLING; + break; + } +} + +void APIENTRY glDisable(GLenum cap) { + if(cap >= GL_LIGHT0 && cap <= GL_LIGHT15) return _glKosDisableLight(cap); + + switch(cap) { + case GL_TEXTURE_2D: + GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_TEXTURE2D; + break; + + case GL_BLEND: + GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_BLENDING; + _glKosVertexBufSwitchOP(); + break; + + case GL_DEPTH_TEST: + GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_DEPTH_TEST; + break; + + case GL_LIGHTING: + GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_LIGHTING; + break; + + case GL_KOS_NEARZ_CLIPPING: + GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_ZCLIPPING; + break; + + case GL_SCISSOR_TEST: + GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_SCISSOR_TEST; + break; + + case GL_FOG: + GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_FOG; + break; + + case GL_CULL_FACE: + GL_KOS_ENABLE_CAP &= ~GL_KOS_ENABLE_CULLING; + break; + } +} + +GLboolean APIENTRY glIsEnabled(GLenum cap) { + if(cap >= GL_LIGHT0 && cap <= GL_LIGHT15) return _glKosIsLightEnabled(cap & 0xFF); + + switch(cap) { + case GL_DEPTH_TEST: + return _glKosEnabledDepthTest() ? GL_TRUE : GL_FALSE; + + case GL_SCISSOR_TEST: + return _glKosEnabledScissorTest() ? GL_TRUE : GL_FALSE; + + case GL_CULL_FACE: + return _glKosEnabledFog() ? GL_TRUE : GL_FALSE; + + case GL_FOG: + return _glKosEnabledFog() ? GL_TRUE : GL_FALSE; + + case GL_LIGHTING: + return _glKosEnabledLighting() ? GL_TRUE : GL_FALSE; + + case GL_KOS_NEARZ_CLIPPING: + return _glKosEnabledNearZClip() ? GL_TRUE : GL_FALSE; + + case GL_TEXTURE_2D: + return _glKosEnabledTexture2D() ? GL_TRUE : GL_FALSE; + + case GL_BLEND: + return _glKosEnabledBlend() ? GL_TRUE : GL_FALSE; + } + + return GL_FALSE; +} + +void APIENTRY glGetIntegerv(GLenum pname, GLint *params) { + switch(pname) { + case GL_ACTIVE_TEXTURE: + *params = 0; + break; + + case GL_BLEND: + *params = _glKosList(); + break; + + case GL_BLEND_DST: + *params = _glKosBlendSrcFunc(); + break; + + case GL_BLEND_SRC: + *params = _glKosBlendDstFunc(); + break; + + case GL_CULL_FACE: + *params = _glKosEnabledCulling(); + break; + + case GL_CULL_FACE_MODE: + *params = _glKosCullFaceMode(); + break; + + case GL_DEPTH_FUNC: + *params = _glKosDepthFunc(); + break; + + case GL_DEPTH_TEST: + *params = _glKosEnabledDepthTest(); + break; + + case GL_DEPTH_WRITEMASK: + *params = _glKosDepthMask(); + break; + + case GL_FRONT_FACE: + *params = _glKosCullFaceFront(); + break; + + case GL_SCISSOR_TEST: + *params = _glKosEnabledScissorTest(); + break; + + case GL_MAX_LIGHTS: + *params = _glKosGetMaxLights(); + break; + + case GL_TEXTURE_BINDING_2D: + *params = _glKosBoundTexID(); + break; + + default: + *params = -1; // Indicate invalid parameter // + break; + } +} + +void APIENTRY glGetFloatv(GLenum pname, GLfloat *params) { + switch(pname) { + case GL_MODELVIEW_MATRIX: + case GL_PROJECTION_MATRIX: + case GL_TEXTURE_MATRIX: + glKosGetMatrix(pname - GL_MODELVIEW_MATRIX + 1, params); + break; + + default: + *params = (GLfloat)GL_INVALID_ENUM; + break; + } +} + +//===============================================================================// +//== Internal API Functions ==// + +GLubyte _glKosEnabledDepthTest() { + return GL_KOS_ENABLE_CAP & GL_KOS_ENABLE_DEPTH_TEST; +} + +GLubyte _glKosEnabledScissorTest() { + return GL_KOS_ENABLE_CAP & GL_KOS_ENABLE_SCISSOR_TEST; +} + +GLubyte _glKosEnabledCulling() { + return GL_KOS_ENABLE_CAP & GL_KOS_ENABLE_CULLING; +} + +GLubyte _glKosEnabledFog() { + return GL_KOS_ENABLE_CAP & GL_KOS_ENABLE_FOG; +} + +GLubyte _glKosEnabledLighting() { + return GL_KOS_ENABLE_CAP & GL_KOS_ENABLE_LIGHTING; +} + +GLubyte _glKosEnabledNearZClip() { + return GL_KOS_ENABLE_CAP & GL_KOS_ENABLE_ZCLIPPING; +} + +GLubyte _glKosEnabledTexture2D() { + return GL_KOS_ENABLE_CAP & GL_KOS_ENABLE_TEXTURE2D; +} + +GLubyte _glKosEnabledBlend() { + return (GL_KOS_ENABLE_CAP & GL_KOS_ENABLE_BLENDING) >> 8; +} \ No newline at end of file diff --git a/gl-clip.c b/gl-clip.c index 86943f4..6d2d500 100755 --- a/gl-clip.c +++ b/gl-clip.c @@ -1,7 +1,7 @@ /* KallistiGL for KallistiOS ##version## libgl/gl-clip.c - Copyright (C) 2013-2014 Josh "PH3NOM" Pearson + Copyright (C) 2013-2014 Josh Pearson Near-Z Clipping Algorithm (C) 2013-2014 Josh PH3NOM Pearson Input Primitive Types Supported: diff --git a/gl-clip.h b/gl-clip.h index 5db9101..d232024 100755 --- a/gl-clip.h +++ b/gl-clip.h @@ -1,7 +1,7 @@ /* KallistiGL for KallistiOS ##version## libgl/gl-clip.h - Copyright (C) 2013-2014 Josh "PH3NOM" Pearson + Copyright (C) 2013-2014 Josh Pearson Near-Z Clipping Algorithm (C) 2013-2014 Josh PH3NOM Pearson Input Primitive Types Supported: diff --git a/gl-error.c b/gl-error.c new file mode 100755 index 0000000..d047653 --- /dev/null +++ b/gl-error.c @@ -0,0 +1,72 @@ +/* KallistiGL for KallistiOS ##version## + + libgl/gl-error.c + Copyright (C) 2014 Josh Pearson + + KOS Open GL State Machine Error Code Implementation. +*/ + +#include "gl.h" +#include "gl-api.h" + +#include + +#define KOS_GL_INVALID_ENUM (1<<0) +#define KOS_GL_OUT_OF_MEMORY (1<<1) +#define KOS_GL_INVALID_OPERATION (1<<2) +#define KOS_GL_INVALID_VALUE (1<<3) + +static GLsizei KOS_GL_ERROR_CODE; + +static char KOS_GL_ERROR_FUNCTION[64] = { '\0' }; + +void _glKosThrowError(GLenum error, char *function) { + + sprintf(KOS_GL_ERROR_FUNCTION, "%s\n", function); + + switch(error) { + case GL_INVALID_ENUM: + KOS_GL_ERROR_CODE |= KOS_GL_INVALID_ENUM; + break; + + case GL_OUT_OF_MEMORY: + KOS_GL_ERROR_CODE |= KOS_GL_OUT_OF_MEMORY; + break; + + case GL_INVALID_OPERATION: + KOS_GL_ERROR_CODE |= KOS_GL_INVALID_OPERATION; + break; + + case GL_INVALID_VALUE: + KOS_GL_ERROR_CODE |= KOS_GL_INVALID_VALUE; + break; + + } +} + +GLsizei _glKosGetError() { + return KOS_GL_ERROR_CODE; +} + +void _glKosResetError() { + KOS_GL_ERROR_CODE = 0; + sprintf(KOS_GL_ERROR_FUNCTION, "\n"); +} + +void _glKosPrintError() { + printf("\nKOS GL ERROR THROWN BY FUNCTION: %s\n", KOS_GL_ERROR_FUNCTION); + + if(KOS_GL_ERROR_CODE & KOS_GL_INVALID_ENUM) + printf("KOS GL ERROR: GL_INVALID_ENUM\n"); + + if(KOS_GL_ERROR_CODE & KOS_GL_OUT_OF_MEMORY) + printf("KOS GL ERROR: GL_OUT_OF_MEMORY\n"); + + if(KOS_GL_ERROR_CODE & KOS_GL_INVALID_OPERATION) + printf("KOS GL ERROR: GL_INVALID_OPERATION\n"); + + if(KOS_GL_ERROR_CODE & KOS_GL_INVALID_VALUE) + printf("KOS GL ERROR: GL_INVALID_VALUE\n"); + + _glKosResetError(); +} \ No newline at end of file diff --git a/gl-fog.c b/gl-fog.c index d4f8564..82dcd4b 100755 --- a/gl-fog.c +++ b/gl-fog.c @@ -1,7 +1,7 @@ /* KallistiGL for KallistiOS ##version## libgl/gl-fog.c - Copyright (C) 2013-2014 Josh "PH3NOM" Pearson + Copyright (C) 2013-2014 Josh Pearson Functionality adapted from the original KOS libgl fog code: Copyright (C) 2002 Benoit Miller @@ -16,7 +16,7 @@ static GLfloat FOG_DENSITY = 1.0f, /* Density - GL_EXP, or GL_EXP2 FOG */ FOG_START = 0.0f, /* Linear FOG */ FOG_END = 1.0f; /* Linear FOG */ -void glFogi(GLenum pname, GLint param) { +void APIENTRY glFogi(GLenum pname, GLint param) { switch(pname) { case GL_FOG_MODE: switch(param) { @@ -38,7 +38,7 @@ void glFogi(GLenum pname, GLint param) { } } -void glFogf(GLenum pname, GLfloat param) { +void APIENTRY glFogf(GLenum pname, GLfloat param) { switch(pname) { case GL_FOG_START: FOG_START = param; @@ -72,7 +72,7 @@ void glFogf(GLenum pname, GLfloat param) { } } -void glFogfv(GLenum pname, const GLfloat *params) { +void APIENTRY glFogfv(GLenum pname, const GLfloat *params) { switch(pname) { case GL_FOG_MODE: return glFogi(pname, (GLint) * params); diff --git a/gl-framebuffer.c b/gl-framebuffer.c new file mode 100755 index 0000000..e4e75d7 --- /dev/null +++ b/gl-framebuffer.c @@ -0,0 +1,181 @@ +/* KallistiGL for KallistiOS ##version## + + libgl/gl-framebuffer.c + Copyright (C) 2014 Josh Pearson + + This file implements Open GL Frame Buffer Object (FBO) functionality, with what + the DC's PVR can directly implement. + Basically, Render-To-Texture using GL_RGB565 is the only native feature of the + PVR, so if you are looking for a depth-buffer, bad news. + + This implementation uses a dynamic linked list to implement the data structures needed. +*/ + +#include "gl.h" +#include "glext.h" +#include "gl-api.h" + +#include + +//========================================================================================// +//== Internal KOS Open GL API FBO Structures / Global Variables ==// + +static GL_FRAMEBUFFER_OBJECT *FRAMEBUF_OBJ = NULL; +static GLsizei FRAMEBUF_OBJECT = 0; + +//========================================================================================// +//== Internal KOS Open GL API FBO Functionality ==// + +void _glKosInitFrameBuffers() { + FRAMEBUF_OBJ = malloc(sizeof(GL_FRAMEBUFFER_OBJECT)); + + FRAMEBUF_OBJ->index = 0; + FRAMEBUF_OBJ->texID = 0; + FRAMEBUF_OBJ->data = NULL; + FRAMEBUF_OBJ->link = NULL; +} + +static void _glKosInsertFramebufferObj(GL_FRAMEBUFFER_OBJECT *obj) { + GL_FRAMEBUFFER_OBJECT *ptr = FRAMEBUF_OBJ; + + while(ptr->link != NULL) + ptr = (GL_FRAMEBUFFER_OBJECT *)ptr->link; + + ptr->link = obj; +} + +static GLsizei _glKosGetLastFrameBufferIndex() { + GL_FRAMEBUFFER_OBJECT *ptr = FRAMEBUF_OBJ; + + while(ptr->link != NULL) + ptr = (GL_FRAMEBUFFER_OBJECT *)ptr->link; + + return ptr->index; +} + +static GL_FRAMEBUFFER_OBJECT *_glKosGetFrameBufferObj(GLuint index) { + GL_FRAMEBUFFER_OBJECT *ptr = FRAMEBUF_OBJ; + + while(ptr->index != index && ptr->link != NULL) + ptr = (GL_FRAMEBUFFER_OBJECT *)ptr->link; + + return ptr; +} + +GLsizei _glKosGetFBO() { + return FRAMEBUF_OBJECT; +} + +GLuint _glKosGetFBOWidth(GLsizei fbi) { + GL_FRAMEBUFFER_OBJECT *fbo = _glKosGetFrameBufferObj(fbi); + return _glKosTextureWidth(fbo->texID); +} + +GLuint _glKosGetFBOHeight(GLsizei fbi) { + GL_FRAMEBUFFER_OBJECT *fbo = _glKosGetFrameBufferObj(fbi); + return _glKosTextureHeight(fbo->texID); +} + +GLvoid *_glKosGetFBOData(GLsizei fbi) { + GL_FRAMEBUFFER_OBJECT *fbo = _glKosGetFrameBufferObj(fbi); + return fbo->data; +} + +//========================================================================================// +//== Public KOS Open GL API FBO Functionality ==// + +GLAPI void APIENTRY glGenFramebuffers(GLsizei n, GLuint *framebuffers) { + GLsizei index = _glKosGetLastFrameBufferIndex(); + + while(n--) { + GL_FRAMEBUFFER_OBJECT *obj = malloc(sizeof(GL_FRAMEBUFFER_OBJECT)); + obj->index = ++index; + obj->texID = 0; + obj->data = NULL; + obj->link = NULL; + + _glKosInsertFramebufferObj(obj); + + *framebuffers++ = obj->index; + } +} + +GLAPI void APIENTRY glDeleteFramebuffers(GLsizei n, GLuint *framebuffers) { + while(n--) { + GL_FRAMEBUFFER_OBJECT *ptr = FRAMEBUF_OBJ->link, * lptr = FRAMEBUF_OBJ; + + while(ptr != NULL) { + if(ptr->index == *framebuffers) { + GL_FRAMEBUFFER_OBJECT *cur_node = ptr; + lptr->link = ptr->link; + ptr = (GL_FRAMEBUFFER_OBJECT *)ptr->link; + free(cur_node); + + if(*framebuffers == FRAMEBUF_OBJECT) + FRAMEBUF_OBJECT = 0; + + break; + } + else + ptr = (GL_FRAMEBUFFER_OBJECT *)ptr->link; + } + + ++framebuffers; + } +} + +GLAPI void APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer) { + if(target != GL_FRAMEBUFFER) { + _glKosThrowError(GL_INVALID_ENUM, "glBindFramebuffer"); + _glKosPrintError(); + return; + } + + FRAMEBUF_OBJECT = framebuffer; +} + +GLAPI void APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, + GLenum textarget, GLuint texture, GLint level) { + if(target != GL_FRAMEBUFFER) + _glKosThrowError(GL_INVALID_ENUM, "glFramebufferTexture2D"); + + if(attachment != GL_COLOR_ATTACHMENT0) + _glKosThrowError(GL_INVALID_OPERATION, "glFramebufferTexture2D"); + + if(textarget != GL_TEXTURE_2D) + _glKosThrowError(GL_INVALID_OPERATION, "glFramebufferTexture2D"); + + if(level) + _glKosThrowError(GL_INVALID_ENUM, "glFramebufferTexture2D"); + + if(!FRAMEBUF_OBJECT) + _glKosThrowError(GL_INVALID_OPERATION, "glFramebufferTexture2D"); + + if(_glKosGetError()) { + _glKosPrintError(); + return; + } + + GL_FRAMEBUFFER_OBJECT *fbo = _glKosGetFrameBufferObj(FRAMEBUF_OBJECT); + + fbo->texID = texture; + fbo->data = _glKosTextureData(texture); +} + +GLAPI GLenum APIENTRY glCheckFramebufferStatus(GLenum target) { + if(target != GL_FRAMEBUFFER) { + _glKosThrowError(GL_INVALID_ENUM, "glCheckFramebufferStatus"); + _glKosPrintError(); + return 0; + } + + if(!FRAMEBUF_OBJECT) + return GL_FRAMEBUFFER_COMPLETE; + + GL_FRAMEBUFFER_OBJECT *fbo = _glKosGetFrameBufferObj(FRAMEBUF_OBJECT); + + if(!fbo->texID) + return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT; + + return GL_FRAMEBUFFER_COMPLETE; +} \ No newline at end of file diff --git a/gl-light.c b/gl-light.c index d98970e..cf2887e 100755 --- a/gl-light.c +++ b/gl-light.c @@ -1,7 +1,7 @@ /* KallistiGL for KallistiOS ##version## libgl/gl-light.c - Copyright (C) 2013-2014 Josh "PH3NOM" Pearson + Copyright (C) 2013-2014 Josh Pearson Dynamic Vertex Lighting Model: vertexColor = emissive + ambient + ( diffuse + specular * attenuation ) @@ -24,11 +24,13 @@ #include "gl-clip.h" #include "gl-light.h" -static GLfloat GL_GLOBAL_AMBIENT[4] = { 0, 0, 0, 0 }; /* RGBA Global Ambient Light */ -static GLfloat GL_VERTEX_NORMAL[3] = {0, 0, 0}; /* Current Vertex Normal */ -static GLuint GL_LIGHT_ENABLED = 0; /* Client State for Enabling Lighting */ +#define GL_KOS_MAX_LIGHTS 16 /* Number of Light Sources that may be enabled at once */ -static glLight GL_LIGHTS[GL_MAX_LIGHTS], +static GLfloat GL_GLOBAL_AMBIENT[4] = { 0, 0, 0, 0 }; /* RGBA Global Ambient Light */ +static GLfloat GL_VERTEX_NORMAL[3] = { 0, 0, 0 }; /* Current Vertex Normal */ +static GLbitfield GL_LIGHT_ENABLED = 0; /* Client State for Enabling Lighting */ + +static glLight GL_LIGHTS[GL_KOS_MAX_LIGHTS], GL_DEFAULT_LIGHT = { { 0.0, 0.0, 1.0, 0.0 }, /* Position */ { 0.0, 0.0, -1.0 }, /* Spot Direction */ -1.0f, /* Spot Cutoff */ @@ -58,7 +60,7 @@ void _glKosSetEyePosition(GLfloat *position) { /* Called internally by glhLookA void _glKosInitLighting() { /* Called internally by glInit() */ unsigned char i; - for(i = 0; i < GL_MAX_LIGHTS; i++) + for(i = 0; i < GL_KOS_MAX_LIGHTS; i++) memcpy(&GL_LIGHTS[i], &GL_DEFAULT_LIGHT, sizeof(glLight)); memcpy(&GL_MATERIAL, &GL_DEFAULT_MATERIAL, sizeof(glMaterial)); @@ -78,6 +80,14 @@ void _glKosDisableLight(const GLuint light) { GL_LIGHT_ENABLED &= ~(1 << (light & 0xF)); } +GLubyte _glKosIsLightEnabled(GLubyte light) { + return GL_LIGHT_ENABLED & (1 << light); +} + +GLubyte _glKosGetMaxLights() { + return GL_KOS_MAX_LIGHTS; +} + /* Vertex Normal Submission */ void glNormal3f(float x, float y, float z) { GL_VERTEX_NORMAL[0] = x; @@ -408,7 +418,7 @@ void _glKosVertexLights(glVertex *P, pvr_vertex_t *v, GLuint count) { }; while(count--) { - for(i = 0; i < GL_MAX_LIGHTS; i++) + for(i = 0; i < GL_KOS_MAX_LIGHTS; i++) if(GL_LIGHT_ENABLED & 1 << i) if(_glKosSpotlight(&GL_LIGHTS[i], P, L)) { /* Compute Spot / Diffuse */ C[0] = A[0] + (GL_MATERIAL.Kd[0] * GL_LIGHTS[i].Kd[0] * L[3]); @@ -454,7 +464,7 @@ void _glKosVertexLight(glVertex *P, pvr_vertex_t *v) { GL_MATERIAL.Ke[2] + GL_MATERIAL.Ka[2] *GL_GLOBAL_AMBIENT[2] }; - for(i = 0; i < GL_MAX_LIGHTS; i++) + for(i = 0; i < GL_KOS_MAX_LIGHTS; i++) if(GL_LIGHT_ENABLED & 1 << i) if(_glKosSpotlight(&GL_LIGHTS[i], P, L)) { /* Compute Spot / Diffuse */ C[0] += (GL_MATERIAL.Kd[0] * GL_LIGHTS[i].Kd[0] * L[3]); @@ -499,7 +509,7 @@ GLuint _glKosVertexLightColor(glVertex *P) { GL_MATERIAL.Ke[2] + GL_MATERIAL.Ka[2] *GL_GLOBAL_AMBIENT[2] }; - for(i = 0; i < GL_MAX_LIGHTS; i++) + for(i = 0; i < GL_KOS_MAX_LIGHTS; i++) if(GL_LIGHT_ENABLED & 1 << i) if(_glKosSpotlight(&GL_LIGHTS[i], P, L)) { /* Compute Spot / Diffuse */ C[0] += (GL_MATERIAL.Kd[0] * GL_LIGHTS[i].Kd[0] * L[3]); diff --git a/gl-light.h b/gl-light.h index db7cf2c..4a69d73 100755 --- a/gl-light.h +++ b/gl-light.h @@ -1,7 +1,7 @@ /* KallistiGL for KallistiOS ##version## libgl/gl-light.h - Copyright (C) 2013-2014 Josh "PH3NOM" Pearson + Copyright (C) 2013-2014 Josh Pearson Dynamic Vertex Lighting. diff --git a/gl-matrix.c b/gl-matrix.c index a1c1550..d21d1b2 100755 --- a/gl-matrix.c +++ b/gl-matrix.c @@ -1,7 +1,7 @@ /* KallistiGL for KallistiOS ##version## libgl/gl-matrix.c - Copyright (C) 2013-2014 Josh "PH3NOM" Pearson + Copyright (C) 2013-2014 Josh Pearson Copyright (C) 2014 Lawrence Sebald Some functionality adapted from the original KOS libgl: diff --git a/gl-pvr.c b/gl-pvr.c index 9414bbf..63c1e7e 100755 --- a/gl-pvr.c +++ b/gl-pvr.c @@ -1,7 +1,7 @@ /* KallistiGL for KallistiOS ##version## libgl/gl-pvr.c - Copyright (C) 2013-2014 Josh "PH3NOM" Pearson + Copyright (C) 2013-2014 Josh Pearson Vertex Buffer Routines for interfacing the Dreamcast's SH4 CPU and PowerVR GPU. @@ -24,6 +24,7 @@ #include #include "gl.h" +#include "gl-api.h" #include "gl-sh4.h" #include "gl-pvr.h" @@ -161,17 +162,13 @@ static inline void glutSwapBuffer() { void glutSwapBuffers() { pvr_wait_ready(); - pvr_scene_begin(); - - glutSwapBuffer(); - - _glKosVertexBufReset(); -} - -void glutSwapBuffersToTexture(void *dst, GLsizei *x, GLsizei *y) { - pvr_wait_ready(); - - pvr_scene_begin_txr(dst, x, y); + if(_glKosGetFBO()) { + GLsizei w = _glKosGetFBOWidth(_glKosGetFBO()); + GLsizei h = _glKosGetFBOHeight(_glKosGetFBO()); + pvr_scene_begin_txr(_glKosGetFBOData(_glKosGetFBO()), &w, &h); + } + else + pvr_scene_begin(); glutSwapBuffer(); @@ -179,11 +176,13 @@ void glutSwapBuffersToTexture(void *dst, GLsizei *x, GLsizei *y) { } void glutCopyBufferToTexture(void *dst, GLsizei *x, GLsizei *y) { - pvr_wait_ready(); + if(_glKosGetFBO()) { + pvr_wait_ready(); - pvr_scene_begin_txr(dst, x, y); + pvr_scene_begin_txr(dst, x, y); - glutSwapBuffer(); + glutSwapBuffer(); + } } int _glKosInitPVR() { diff --git a/gl-pvr.h b/gl-pvr.h index da1fa00..809517b 100755 --- a/gl-pvr.h +++ b/gl-pvr.h @@ -1,7 +1,7 @@ /* KallistiGL for KallistiOS ##version## libgl/gl-pvr.h - Copyright (C) 2013-2014 Josh "PH3NOM" Pearson + Copyright (C) 2013-2014 Josh Pearson Vertex Buffer Routines for interfacing the Dreamcast's SH4 CPU and PowerVR GPU. */ diff --git a/gl-rgb.c b/gl-rgb.c index d2daca4..7138b6d 100755 --- a/gl-rgb.c +++ b/gl-rgb.c @@ -1,7 +1,7 @@ /* KallistiGL for KallistiOS ##version## libgl/gl-rgb.c - Copyright (C) 2013-2014 Josh "PH3NOM" Pearson + Copyright (C) 2013-2014 Josh Pearson A set of functions for working with ARGB pixel data, used by gluBuild2DMipmaps(...). */ diff --git a/gl-rgb.h b/gl-rgb.h index 3615b30..b28caf0 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 "PH3NOM" Pearson + Copyright (C) 2013-2014 Josh Pearson A set of functions for working with ARGB pixel data. */ diff --git a/gl-sh4.h b/gl-sh4.h index 1ead9bb..561aa33 100755 --- a/gl-sh4.h +++ b/gl-sh4.h @@ -1,7 +1,7 @@ /* KallistiGL for KallistiOS ##version## libgl/gl-sh4.h - Copyright (C) 2013-2014 Josh "PH3NOM" Pearson + Copyright (C) 2013-2014 Josh Pearson Macros for utilizing the Dreamcast's SH4 CPU vector / matrix math functions. */ diff --git a/gl-texture.c b/gl-texture.c new file mode 100755 index 0000000..79b6ccc --- /dev/null +++ b/gl-texture.c @@ -0,0 +1,298 @@ +/* KallistiGL for KallistiOS ##version## + + libgl/gl-texture.c + Copyright (C) 2014 Josh Pearson + + Open GL Texture Submission implementation. + This implementation uses a dynamic linked list to store the texture objects. +*/ + +#include "gl.h" +#include "gl-api.h" + +#include +#include + +//========================================================================================// +//== 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_CLAMP_U (1<<1) +#define GL_CLAMP_V (1<<0) + +//========================================================================================// + +GLubyte _glKosInitTextures() { + TEXTURE_OBJ = malloc(sizeof(GL_TEXTURE_OBJECT)); + + if(TEXTURE_OBJ == NULL) + return 0; + + TEXTURE_OBJ->index = 0; + TEXTURE_OBJ->data = NULL; + TEXTURE_OBJ->link = NULL; + + return 1; +} + +static GLsizei _glKosGetLastTextureIndex() { + GL_TEXTURE_OBJECT *ptr = TEXTURE_OBJ; + + while(ptr->link != NULL) + ptr = (GL_TEXTURE_OBJECT *)ptr->link; + + return ptr->index; +} + +static void _glKosInsertTextureObj(GL_TEXTURE_OBJECT *obj) { + GL_TEXTURE_OBJECT *ptr = TEXTURE_OBJ; + + while(ptr->link != NULL) + ptr = (GL_TEXTURE_OBJECT *)ptr->link; + + ptr->link = obj; +} + +static GL_TEXTURE_OBJECT *_glKosGetTextureObj(GLuint index) { + GL_TEXTURE_OBJECT *ptr = TEXTURE_OBJ; + + while(ptr->link != NULL && ptr->index != index) + ptr = (GL_TEXTURE_OBJECT *)ptr->link; + + return ptr; +} + +static void _glKosBindTexture(GLuint index) { + GL_TEXTURE_POINTER = _glKosGetTextureObj(index); +} + +static void _glKosUnbindTexture() { + GL_TEXTURE_POINTER = NULL; +} + +GLuint _glKosTextureWidth(GLuint index) { + GL_TEXTURE_OBJECT *tex = _glKosGetTextureObj(index); + return tex->width; +} + +GLuint _glKosTextureHeight(GLuint index) { + GL_TEXTURE_OBJECT *tex = _glKosGetTextureObj(index); + return tex->height; +} + +GLvoid *_glKosTextureData(GLuint index) { + GL_TEXTURE_OBJECT *tex = _glKosGetTextureObj(index); + return tex->data; +} + +void _glKosCompileHdrTx() { + return GL_TEXTURE_POINTER ? _glKosCompileHdrT(GL_TEXTURE_POINTER) : _glKosCompileHdr(); +} + +GLuint _glKosBoundTexID() { + return GL_TEXTURE_POINTER ? GL_TEXTURE_POINTER->index : 0; +} + +//========================================================================================// +//== Public KOS Open GL API Texture Unit Functionality ==// + +void APIENTRY glGenTextures(GLsizei n, GLuint *textures) { + GLsizei index = _glKosGetLastTextureIndex(); + + while(n--) { + GL_TEXTURE_OBJECT *txr = malloc(sizeof(GL_TEXTURE_OBJECT)); + txr->index = ++index; + txr->data = NULL; + txr->link = NULL; + + txr->width = txr->height = 0; + txr->mip_map = 0; + txr->uv_clamp = 0; + txr->env = PVR_TXRENV_MODULATEALPHA; + txr->filter = PVR_FILTER_NONE; + + _glKosInsertTextureObj(txr); + + *textures++ = txr->index; + } +} + +void APIENTRY glDeleteTextures(GLsizei n, GLuint *textures) { + while(n--) { + GL_TEXTURE_OBJECT *txr = TEXTURE_OBJ, *ltxr = NULL; + + while(txr->index != *textures && txr->link != NULL) { + ltxr = txr; + txr = txr->link; + } + + ltxr->link = txr->link; + + if(txr->index == *textures) { + if(GL_TEXTURE_POINTER) + if(GL_TEXTURE_POINTER->index == txr->index) + GL_TEXTURE_POINTER = NULL; + + if(txr->data != NULL) + pvr_mem_free(txr->data); + + free(txr); + } + + ++textures; + } +} + +void APIENTRY glBindTexture(GLenum target, GLuint texture) { + if(target != GL_TEXTURE_2D) { + _glKosThrowError(GL_INVALID_ENUM, "glBindTexture"); + _glKosPrintError(); + return; + } + + texture ? _glKosBindTexture(texture) : _glKosUnbindTexture(); +} + +void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, + GLsizei width, GLsizei height, GLint border, + GLenum format, GLenum type, GLvoid *data) { + if(target != GL_TEXTURE_2D) + _glKosThrowError(GL_INVALID_ENUM, "glTexImage2D"); + + if(format != GL_RGB) + if(format != GL_RGBA) + _glKosThrowError(GL_INVALID_ENUM, "glTexImage2D"); + + if(internalFormat != GL_RGB) + if(internalFormat != GL_RGBA) + _glKosThrowError(GL_INVALID_VALUE, "glTexImage2D"); + + if(level < 0) + _glKosThrowError(GL_INVALID_VALUE, "glTexImage2D"); + + if(border) + _glKosThrowError(GL_INVALID_VALUE, "glTexImage2D"); + + 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) + if(type != GL_UNSIGNED_SHORT_5_6_5_VQ) + if(type != GL_UNSIGNED_SHORT_5_6_5_VQ_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_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(GL_TEXTURE_POINTER == NULL) + _glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D"); + + if(_glKosGetError()) { + _glKosPrintError(); + return; + } + + GL_TEXTURE_POINTER->width = width; + GL_TEXTURE_POINTER->height = height; + GL_TEXTURE_POINTER->mip_map = level; + GL_TEXTURE_POINTER->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); + + if(data) + sq_cpy(GL_TEXTURE_POINTER->data, data, bytes); +} + +void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) { + if(target == GL_TEXTURE_2D) { + switch(pname) { + case GL_TEXTURE_MAG_FILTER: + case GL_TEXTURE_MIN_FILTER: + switch(param) { + case GL_LINEAR: + GL_TEXTURE_POINTER->filter = PVR_FILTER_BILINEAR; + break; + + case GL_NEAREST: + GL_TEXTURE_POINTER->filter = PVR_FILTER_NEAREST; + break; + + case GL_FILTER_NONE: + GL_TEXTURE_POINTER->filter = PVR_FILTER_NONE; + break; + + case GL_FILTER_BILINEAR: + GL_TEXTURE_POINTER->filter = PVR_FILTER_BILINEAR; + break; + + default: + break; + } + + break; + + case GL_TEXTURE_WRAP_S: + switch(param) { + case GL_CLAMP: + GL_TEXTURE_POINTER->uv_clamp |= GL_CLAMP_U; + break; + + case GL_REPEAT: + GL_TEXTURE_POINTER->uv_clamp &= ~GL_CLAMP_U; + break; + } + + break; + + case GL_TEXTURE_WRAP_T: + switch(param) { + case GL_CLAMP: + GL_TEXTURE_POINTER->uv_clamp |= GL_CLAMP_V; + break; + + case GL_REPEAT: + GL_TEXTURE_POINTER->uv_clamp &= ~GL_CLAMP_V; + break; + } + + break; + } + } +} + +void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) { + if(target != GL_TEXTURE_ENV) + _glKosThrowError(GL_INVALID_ENUM, "glTexEnvi"); + + if(pname != GL_TEXTURE_ENV_MODE) + _glKosThrowError(GL_INVALID_ENUM, "glTexEnvi"); + + if(_glKosGetError()) { + _glKosPrintError(); + return; + } + + if(param >= PVR_TXRENV_REPLACE && param <= PVR_TXRENV_MODULATEALPHA) + GL_TEXTURE_POINTER->env = param; +} + +void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param) { + glTexEnvi(target, pname, param); +} diff --git a/glu-texture.c b/glu-texture.c index 7b08eac..3c030c6 100755 --- a/glu-texture.c +++ b/glu-texture.c @@ -1,9 +1,9 @@ /* KallistiGL for KallistiOS ##version## libgl/glu-texture.c - Copyright (C) 2013-2014 Josh "PH3NOM" Pearson + Copyright (C) 2013-2014 Josh Pearson - A set of functions for working with ARGB pixel data, used by gluBuild2DMipmaps(...). + A set of functions for working with ARGB pixel data. */ #include "gl.h" @@ -11,7 +11,7 @@ #include "gl-rgb.h" #include "glu.h" -GLAPI GLuint APIENTRY glKosMipMapTexSize(GLuint width, GLuint height) { +GLAPI GLuint APIENTRY glKosMipMapTexSize(GLuint width, GLuint height) { GLuint b = 0; while(width >= 1 && height >= 1) { @@ -28,7 +28,7 @@ GLAPI GLuint APIENTRY glKosMipMapTexSize(GLuint width, GLuint height) { } static GLint gluBuild2DBiMipmaps(GLenum target, GLint internalFormat, GLsizei width, - GLsizei height, GLenum format, GLenum type, const void *data) { + GLsizei height, GLenum format, GLenum type, const void *data) { if(target != GL_TEXTURE_2D) return -1; @@ -68,15 +68,15 @@ static GLint gluBuild2DBiMipmaps(GLenum target, GLint internalFormat, GLsizei wi } GLint APIENTRY gluBuild2DMipmaps(GLenum target, GLint internalFormat, GLsizei width, - GLsizei height, GLenum format, GLenum type, const void *data) { + GLsizei height, GLenum format, GLenum type, const void *data) { if(target != GL_TEXTURE_2D) return -1; - - if(type != GL_UNSIGNED_SHORT_5_6_5 && type != GL_UNSIGNED_SHORT_4_4_4_4 - && type != GL_UNSIGNED_SHORT_1_5_5_5) - return -1; - if(width < 1 || height < 1) + if(type != GL_UNSIGNED_SHORT_5_6_5 && type != GL_UNSIGNED_SHORT_4_4_4_4 + && type != GL_UNSIGNED_SHORT_1_5_5_5) + return -1; + + if(width < 1 || height < 1) return 0; if(width == 1 || height == 1) diff --git a/include/gl.h b/include/gl.h index e803842..f6ae8df 100755 --- a/include/gl.h +++ b/include/gl.h @@ -86,9 +86,9 @@ __BEGIN_DECLS #define GL_DEPTH_COMPONENT 0x1902 /* Blending: Simply Need to Map GL constants to PVR constants */ -#define GL_BLEND 0x0BE2 /* capability bit */ #define GL_BLEND_DST 0x0BE0 #define GL_BLEND_SRC 0x0BE1 +#define GL_BLEND 0x0BE2 /* capability bit */ #define GL_ZERO 0x0 #define GL_ONE 0x1 @@ -133,8 +133,6 @@ __BEGIN_DECLS #define GL_LINEAR_MIPMAP_NEAREST 0x2701 #define GL_LINEAR_MIPMAP_LINEAR 0x2703 -#define GL_MAX_TEXTURE_UNITS 0x2 /* 0 = Opaque, 1 = Translucent / Blended */ - #define GL_TEXTURE_BINDING_2D 0x8069 /* TextureUnit */ @@ -218,8 +216,6 @@ __BEGIN_DECLS #define GL_FOG_HINT 0x0C54 /* Lighting constants */ -#define GL_MAX_LIGHTS 0x0008 - #define GL_LIGHTING 0x0b50 #define GL_LIGHT0 0x4000 @@ -230,6 +226,14 @@ __BEGIN_DECLS #define GL_LIGHT5 0x4005 #define GL_LIGHT6 0x4006 #define GL_LIGHT7 0x4007 +#define GL_LIGHT8 0x4008 +#define GL_LIGHT9 0x4009 +#define GL_LIGHT10 0x400A +#define GL_LIGHT11 0x400B +#define GL_LIGHT12 0x400C +#define GL_LIGHT13 0x400D +#define GL_LIGHT14 0x400E +#define GL_LIGHT15 0x400F /* LightParameter */ #define GL_AMBIENT 0x1200 @@ -285,25 +289,81 @@ __BEGIN_DECLS #define GL_STACK_UNDERFLOW 0x0504 #define GL_OUT_OF_MEMORY 0x0505 -/* KOS near Z-CLIPPING */ +/* GetPName */ +#define GL_SMOOTH_POINT_SIZE_RANGE 0x0B12 +#define GL_SMOOTH_LINE_WIDTH_RANGE 0x0B22 +#define GL_ALIASED_POINT_SIZE_RANGE 0x846D +#define GL_ALIASED_LINE_WIDTH_RANGE 0x846E +#define GL_IMPLEMENTATION_COLOR_READ_TYPE_OES 0x8B9A +#define GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES 0x8B9B +#define GL_MAX_LIGHTS 0x0D31 +#define GL_MAX_TEXTURE_SIZE 0x0D33 +#define GL_MAX_MODELVIEW_STACK_DEPTH 0x0D36 +#define GL_MAX_PROJECTION_STACK_DEPTH 0x0D38 +#define GL_MAX_TEXTURE_STACK_DEPTH 0x0D39 +#define GL_MAX_VIEWPORT_DIMS 0x0D3A +#define GL_MAX_ELEMENTS_VERTICES 0x80E8 +#define GL_MAX_ELEMENTS_INDICES 0x80E9 +#define GL_MAX_TEXTURE_UNITS 0x84E2 +#define GL_NUM_COMPRESSED_TEXTURE_FORMATS 0x86A2 +#define GL_COMPRESSED_TEXTURE_FORMATS 0x86A3 +#define GL_SUBPIXEL_BITS 0x0D50 +#define GL_RED_BITS 0x0D52 +#define GL_GREEN_BITS 0x0D53 +#define GL_BLUE_BITS 0x0D54 +#define GL_ALPHA_BITS 0x0D55 +#define GL_DEPTH_BITS 0x0D56 +#define GL_STENCIL_BITS 0x0D57 + +/* GL KOS near Z-CLIPPING */ #define GL_KOS_NEARZ_CLIPPING 0x0020 /* capability bit */ -#define GL_UNSIGNED_SHORT_5_6_5 PVR_TXRFMT_RGB565 -#define GL_UNSIGNED_SHORT_5_6_5_REV PVR_TXRFMT_RGB565 -#define GL_UNSIGNED_SHORT_1_5_5_5 PVR_TXRFMT_ARGB1555 -#define GL_UNSIGNED_SHORT_1_5_5_5_REV PVR_TXRFMT_ARGB1555 -#define GL_UNSIGNED_SHORT_4_4_4_4 PVR_TXRFMT_ARGB4444 -#define GL_UNSIGNED_SHORT_4_4_4_4_REV PVR_TXRFMT_ARGB4444 +/* 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) +#define GL_UNSIGNED_SHORT_5_5_5_1 (PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_NONTWIDDLED) +#define GL_UNSIGNED_SHORT_5_5_5_1_REV (PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_NONTWIDDLED) +#define GL_UNSIGNED_SHORT_1_5_5_5 (PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_NONTWIDDLED) +#define GL_UNSIGNED_SHORT_1_5_5_5_REV (PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_NONTWIDDLED) +#define GL_UNSIGNED_SHORT_4_4_4_4 (PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_NONTWIDDLED) +#define GL_UNSIGNED_SHORT_4_4_4_4_REV (PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_NONTWIDDLED) -#define GL_RGB565_TWID PVR_TXRFMT_RGB565 | PVR_TXRFMT_TWIDDLED -#define GL_ARGB4444_TWID PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_TWIDDLED +#define GL_UNSIGNED_SHORT_5_6_5_TWID (PVR_TXRFMT_RGB565) +#define GL_UNSIGNED_SHORT_5_6_5_REV_TWID (PVR_TXRFMT_RGB565) +#define GL_UNSIGNED_SHORT_5_5_5_1_TWID (PVR_TXRFMT_ARGB1555) +#define GL_UNSIGNED_SHORT_5_5_5_1_REV_TWID (PVR_TXRFMT_ARGB1555) +#define GL_UNSIGNED_SHORT_1_5_5_5_TWID (PVR_TXRFMT_ARGB1555) +#define GL_UNSIGNED_SHORT_1_5_5_5_REV_TWID (PVR_TXRFMT_ARGB1555) +#define GL_UNSIGNED_SHORT_4_4_4_4_TWID (PVR_TXRFMT_ARGB4444) +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_TWID (PVR_TXRFMT_ARGB4444) -#define GL_RED 0x00 -#define GL_RG 0x01 -#define GL_RGB 0x02 -#define GL_BGR 0x03 -#define GL_RGBA 0x04 -#define GL_BGRA 0x05 +#define GL_UNSIGNED_SHORT_5_6_5_VQ (PVR_TXRFMT_VQ_ENABLE | PVR_TXRFMT_RGB565 | PVR_TXRFMT_NONTWIDDLED) +#define GL_UNSIGNED_SHORT_5_6_5_REV_VQ (PVR_TXRFMT_VQ_ENABLE | PVR_TXRFMT_RGB565 | PVR_TXRFMT_NONTWIDDLED) +#define GL_UNSIGNED_SHORT_5_5_5_1_VQ (PVR_TXRFMT_VQ_ENABLE | PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_NONTWIDDLED) +#define GL_UNSIGNED_SHORT_5_5_5_1_REV_VQ (PVR_TXRFMT_VQ_ENABLE | PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_NONTWIDDLED) +#define GL_UNSIGNED_SHORT_1_5_5_5_VQ (PVR_TXRFMT_VQ_ENABLE | PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_NONTWIDDLED) +#define GL_UNSIGNED_SHORT_1_5_5_5_REV_VQ (PVR_TXRFMT_VQ_ENABLE | PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_NONTWIDDLED) +#define GL_UNSIGNED_SHORT_4_4_4_4_VQ (PVR_TXRFMT_VQ_ENABLE | PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_NONTWIDDLED) +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_VQ (PVR_TXRFMT_VQ_ENABLE | PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_NONTWIDDLED) + +#define GL_UNSIGNED_SHORT_5_6_5_VQ_TWID (PVR_TXRFMT_VQ_ENABLE | PVR_TXRFMT_RGB565) +#define GL_UNSIGNED_SHORT_5_6_5_REV_VQ_TWID (PVR_TXRFMT_VQ_ENABLE | PVR_TXRFMT_RGB565) +#define GL_UNSIGNED_SHORT_5_5_5_1_VQ_TWID (PVR_TXRFMT_VQ_ENABLE | PVR_TXRFMT_ARGB1555) +#define GL_UNSIGNED_SHORT_5_5_5_1_REV_VQ_TWID (PVR_TXRFMT_VQ_ENABLE | PVR_TXRFMT_ARGB1555) +#define GL_UNSIGNED_SHORT_1_5_5_5_VQ_TWID (PVR_TXRFMT_VQ_ENABLE | PVR_TXRFMT_ARGB1555) +#define GL_UNSIGNED_SHORT_1_5_5_5_REV_VQ_TWID (PVR_TXRFMT_VQ_ENABLE | PVR_TXRFMT_ARGB1555) +#define GL_UNSIGNED_SHORT_4_4_4_4_VQ_TWID (PVR_TXRFMT_VQ_ENABLE | PVR_TXRFMT_ARGB4444) +#define GL_UNSIGNED_SHORT_4_4_4_4_REV_VQ_TWID (PVR_TXRFMT_VQ_ENABLE | PVR_TXRFMT_ARGB4444) + +#define GL_RGB565_TWID (PVR_TXRFMT_RGB565 | PVR_TXRFMT_TWIDDLED) +#define GL_ARGB1555_TWID (PVR_TXRFMT_ARGB1555 | PVR_TXRFMT_TWIDDLED) +#define GL_ARGB4444_TWID (PVR_TXRFMT_ARGB4444 | PVR_TXRFMT_TWIDDLED) + +#define GL_ALPHA 0x1906 +#define GL_RGB 0x1907 +#define GL_RGBA 0x1908 +#define GL_LUMINANCE 0x1909 +#define GL_LUMINANCE_ALPHA 0x190A #define GLbyte char #define GLshort short @@ -318,6 +378,7 @@ __BEGIN_DECLS #define GLfixed const unsigned int #define GLclampf float #define GLubyte unsigned char +#define GLbitfield unsigned long #define GLboolean int #define GL_FALSE 0 #define GL_TRUE 1 @@ -413,7 +474,7 @@ GLAPI void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param); GLAPI void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param); GLAPI void APIENTRY glGenTextures(GLsizei n, GLuint *textures); -GLAPI void APIENTRY glDelTextures(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 */ @@ -511,8 +572,9 @@ GLAPI void APIENTRY glMaterialfv(GLenum face, GLenum pname, const GLfloat *param GLAPI GLuint APIENTRY glKosMipMapTexSize(GLuint width, GLuint height); /* glGet Functions */ -void glGetIntegerv(GLenum pname, GLint *params); -void glGetFloatv(GLenum pname, GLfloat *params); +GLAPI void APIENTRY glGetIntegerv(GLenum pname, GLint *params); +GLAPI void APIENTRY glGetFloatv(GLenum pname, GLfloat *params); +GLAPI GLboolean APIENTRY glIsEnabled(GLenum cap); /* Multi-Texture Extensions - Does not currently work with Z-Clipping Enabled */ GLAPI void APIENTRY glActiveTexture(GLenum texture); @@ -522,5 +584,13 @@ 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); +/* Frame Buffer Objects / Render-To-Texture Functions */ +GLAPI void APIENTRY glGenFramebuffers(GLsizei n, GLuint * framebuffers); +GLAPI void APIENTRY glDeleteFramebuffers(GLsizei n, GLuint * framebuffers); +GLAPI void APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer); +GLAPI void APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, + GLenum textarget, GLuint texture, GLint level); +GLAPI GLenum APIENTRY glCheckFramebufferStatus(GLenum target); + __END_DECLS #endif /* !__GL_GL_H */ diff --git a/include/glext.h b/include/glext.h new file mode 100755 index 0000000..36d9c67 --- /dev/null +++ b/include/glext.h @@ -0,0 +1,49 @@ +/* KallistiGL for KallistiOS ##version## + + libgl/glext.h + Copyright (C) 2014 Josh Pearson + Copyright (c) 2007-2013 The Khronos Group Inc. +*/ + +#ifndef __GL_GLEXT_H +#define __GL_GLEXT_H + +#include +__BEGIN_DECLS + +#include + +#define GL_COLOR_ATTACHMENT0 0x8CE0 +#define GL_COLOR_ATTACHMENT1 0x8CE1 +#define GL_COLOR_ATTACHMENT2 0x8CE2 +#define GL_COLOR_ATTACHMENT3 0x8CE3 +#define GL_COLOR_ATTACHMENT4 0x8CE4 +#define GL_COLOR_ATTACHMENT5 0x8CE5 +#define GL_COLOR_ATTACHMENT6 0x8CE6 +#define GL_COLOR_ATTACHMENT7 0x8CE7 +#define GL_COLOR_ATTACHMENT8 0x8CE8 +#define GL_COLOR_ATTACHMENT9 0x8CE9 +#define GL_COLOR_ATTACHMENT10 0x8CEA +#define GL_COLOR_ATTACHMENT11 0x8CEB +#define GL_COLOR_ATTACHMENT12 0x8CEC +#define GL_COLOR_ATTACHMENT13 0x8CED +#define GL_COLOR_ATTACHMENT14 0x8CEE +#define GL_COLOR_ATTACHMENT15 0x8CEF +#define GL_DEPTH_ATTACHMENT 0x8D00 +#define GL_STENCIL_ATTACHMENT 0x8D20 +#define GL_FRAMEBUFFER 0x8D40 +#define GL_RENDERBUFFER 0x8D41 +#define GL_RENDERBUFFER_WIDTH 0x8D42 +#define GL_RENDERBUFFER_HEIGHT 0x8D43 +#define GL_RENDERBUFFER_INTERNAL_FORMAT 0x8D44 + +#define GL_FRAMEBUFFER_COMPLETE 0x8CD5 +#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT 0x8CD6 +#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT 0x8CD7 +#define GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER 0x8CDB +#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC +#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD + +__END_DECLS + +#endif /* !__GL_GLEXT_H */ diff --git a/include/glut.h b/include/glut.h index 717a2b9..fc914ba 100755 --- a/include/glut.h +++ b/include/glut.h @@ -14,12 +14,9 @@ __BEGIN_DECLS #include -/* Flush the Submitted Primitive Data to the GPU for render to screen */ +/* Flush the Submitted Primitive Data to the GPU for render */ GLAPI void APIENTRY glutSwapBuffers(); -/* Flush the Submitted Primitive Data to the GPU for render to texture */ -GLAPI void APIENTRY glutSwapBuffersToTexture(void *dst, GLsizei *x, GLsizei *y); - /* 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 next frame rendered */ diff --git a/kos/dreamcast.cnf b/kos/dreamcast.cnf old mode 100644 new mode 100755