Drop all of the old libGL files

This commit is contained in:
Luke Benstead 2018-05-20 16:16:53 +01:00
parent 1421736733
commit 396ea82856
29 changed files with 177 additions and 3385 deletions

View File

@ -3,7 +3,6 @@
#include "../include/gl.h"
#include "../include/glext.h"
#include "private.h"
#include "../gl-api.h"
typedef struct {
const void* ptr;

View File

@ -9,7 +9,6 @@
*/
#include "gl.h"
#include "gl-api.h"
#include <stdio.h>

View File

@ -4,7 +4,6 @@
#include "../containers/aligned_vector.h"
#include "private.h"
#include "../gl-api.h"
#define TA_SQ_ADDR (unsigned int *)(void *) \
(0xe0000000 | (((unsigned long)0x10000000) & 0x03ffffe0))

74
GL/fog.c Normal file
View File

@ -0,0 +1,74 @@
#include <limits.h>
#include "private.h"
static GLfloat FOG_START = 0.0f;
static GLfloat FOG_END = 1.0f;
static GLfloat FOG_DENSITY = 1.0f;
static GLenum FOG_MODE = GL_EXP;
static GLfloat FOG_COLOR [] = {0.0f, 0.0f, 0.0f, 0.0f};
static void updatePVRFog() {
if(FOG_MODE == GL_LINEAR) {
pvr_fog_table_linear(FOG_START, FOG_END);
} else if(FOG_MODE == GL_EXP) {
pvr_fog_table_exp(FOG_DENSITY);
} else if(FOG_MODE == GL_EXP2) {
pvr_fog_table_exp2(FOG_DENSITY);
}
pvr_fog_table_color(FOG_COLOR[3], FOG_COLOR[0], FOG_COLOR[1], FOG_COLOR[2]);
}
void APIENTRY glFogf(GLenum pname, GLfloat param) {
switch(pname) {
case GL_FOG_MODE: {
FOG_MODE = (GLenum) param;
updatePVRFog();
} break;
case GL_FOG_DENSITY: {
FOG_DENSITY = param;
updatePVRFog();
} break;
case GL_FOG_START: {
FOG_START = param;
updatePVRFog();
} break;
case GL_FOG_END: {
FOG_END = param;
updatePVRFog();
} break;
case GL_FOG_INDEX:
default: {
_glKosThrowError(GL_INVALID_ENUM, __func__);
_glKosPrintError();
}
}
}
void APIENTRY glFogi(GLenum pname, GLint param) {
glFogf(pname, (GLfloat) param);
}
void APIENTRY glFogfv(GLenum pname, const GLfloat* params) {
if(pname == GL_FOG_COLOR) {
FOG_COLOR[0] = params[0];
FOG_COLOR[1] = params[1];
FOG_COLOR[2] = params[2];
FOG_COLOR[3] = params[3];
updatePVRFog();
} else {
glFogf(pname, *params);
}
}
void APIENTRY glFogiv(GLenum pname, const GLint* params) {
if(pname == GL_FOG_COLOR) {
FOG_COLOR[0] = ((GLfloat) params[0]) / (GLfloat) INT_MAX;
FOG_COLOR[1] = ((GLfloat) params[1]) / (GLfloat) INT_MAX;
FOG_COLOR[2] = ((GLfloat) params[2]) / (GLfloat) INT_MAX;
FOG_COLOR[3] = ((GLfloat) params[3]) / (GLfloat) INT_MAX;
updatePVRFog();
} else {
glFogi(pname, *params);
}
}

View File

@ -0,0 +1,33 @@
#include "private.h"
static GLuint ACTIVE_FRAMEBUFFER = 0;
static NamedArray FRAMEBUFFERS;
void APIENTRY glGenFramebuffersEXT(GLsizei n, GLuint* framebuffers) {
}
void APIENTRY glDeleteFramebuffersEXT(GLsizei n, const GLuint* framebuffers) {
}
void APIENTRY glBindFramebufferEXT(GLenum target, GLuint framebuffer) {
}
void APIENTRY glFramebufferTexture2DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level) {
}
void APIENTRY glGenerateMipmapEXT(GLenum target) {
}
GLenum APIENTRY glCheckFramebufferStatusEXT(GLenum target) {
}
GLboolean APIENTRY glIsFramebufferEXT(GLuint framebuffer) {
}

View File

@ -60,6 +60,15 @@ void APIENTRY glColor4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
COLOR[3] = a;
}
void APIENTRY glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a) {
glColor4f(
((GLfloat) r) / 255.0f,
((GLfloat) g) / 255.0f,
((GLfloat) b) / 255.0f,
((GLfloat) a) / 255.0f
);
}
void APIENTRY glColor4fv(const GLfloat* v) {
glColor4f(v[0], v[1], v[2], v[3]);
}
@ -145,3 +154,29 @@ void APIENTRY glEnd() {
/* FIXME: Pop pointers */
}
void APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) {
glBegin(GL_QUADS);
glVertex2f(x1, y1);
glVertex2f(x2, y1);
glVertex2f(x2, y2);
glVertex2f(x1, y2);
glEnd();
}
void APIENTRY glRectfv(const GLfloat *v1, const GLfloat *v2) {
glBegin(GL_QUADS);
glVertex2f(v1[0], v1[1]);
glVertex2f(v2[0], v1[1]);
glVertex2f(v2[0], v2[1]);
glVertex2f(v1[0], v2[1]);
glEnd();
}
void APIENTRY glRecti(GLint x1, GLint y1, GLint x2, GLint y2) {
return glRectf((GLfloat)x1, (GLfloat)y1, (GLfloat)x2, (GLfloat)y2);
}
void APIENTRY glRectiv(const GLint *v1, const GLint *v2) {
return glRectfv((const GLfloat *)v1, (const GLfloat *)v2);
}

View File

@ -2,7 +2,8 @@
#include "../include/gl.h"
#include "../containers/stack.h"
#include "../gl-sh4.h"
#define DEG2RAD (0.01745329251994329576923690768489)
/* Viewport mapping */
static GLfloat gl_viewport_scale[3], gl_viewport_offset[3];
@ -320,26 +321,28 @@ void APIENTRY glDepthRange(GLclampf n, GLclampf f) {
}
/* Vector Cross Product - Used by glhLookAtf2 */
static inline void vec3f_cross(vector3f v1, vector3f v2, vector3f result) {
static inline void vec3f_cross(const GLfloat* v1, const GLfloat* v2, GLfloat* result) {
result[0] = v1[1] * v2[2] - v1[2] * v2[1];
result[1] = v1[2] * v2[0] - v1[0] * v2[2];
result[2] = v1[0] * v2[1] - v1[1] * v2[0];
}
/* glhLookAtf2 adapted from http://www.opengl.org/wiki/GluLookAt_code */
void glhLookAtf2(vector3f eyePosition3D,
vector3f center3D,
vector3f upVector3D) {
void glhLookAtf2(const GLfloat* eyePosition3D,
const GLfloat* center3D,
const GLfloat* upVector3D) {
/* Look-At Matrix */
static matrix4f MatrixLookAt __attribute__((aligned(32))) = {
static matrix_t MatrixLookAt __attribute__((aligned(32))) = {
{ 1.0f, 0.0f, 0.0f, 0.0f },
{ 0.0f, 1.0f, 0.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f }
};
vector3f forward, side, up;
GLfloat forward[3];
GLfloat side[3];
GLfloat up[3];
vec3f_sub_normalize(center3D[0], center3D[1], center3D[2],
eyePosition3D[0], eyePosition3D[1], eyePosition3D[2],
@ -383,9 +386,9 @@ void glhLookAtf2(vector3f eyePosition3D,
void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx,
GLfloat centery, GLfloat centerz, GLfloat upx, GLfloat upy,
GLfloat upz) {
vector3f eye = { eyex, eyey, eyez };
vector3f point = { centerx, centery, centerz };
vector3f up = { upx, upy, upz };
GLfloat eye [] = { eyex, eyey, eyez };
GLfloat point [] = { centerx, centery, centerz };
GLfloat up [] = { upx, upy, upz };
glhLookAtf2(eye, point, up);
}

View File

@ -2,7 +2,6 @@
#define PRIVATE_H
#include "../include/gl.h"
#include "../gl-api.h"
#include "../containers/aligned_vector.h"
#include "../containers/named_array.h"
@ -91,6 +90,10 @@ GLboolean isLightingEnabled();
GLboolean isLightEnabled(GLubyte light);
void calculateLightingContribution(const GLint light, const GLfloat* pos, const GLfloat* normal, GLfloat* colour);
void _glKosThrowError(GLenum error, const char *function);
void _glKosPrintError();
GLubyte _glKosHasError();
#define PVR_VERTEX_BUF_SIZE 2560 * 256
#define MAX_TEXTURE_UNITS 2
#define MAX_LIGHTS 8

View File

@ -6,7 +6,6 @@
#include <dc/video.h>
#include "../include/gl.h"
#include "../gl-api.h"
#include "private.h"
static pvr_poly_cxt_t GL_CONTEXT;
@ -310,9 +309,11 @@ GLAPI void APIENTRY glDepthFunc(GLenum func) {
/* Hints */
/* Currently Supported Capabilities:
GL_PERSPECTIVE_CORRECTION_HINT - This will Enable Texture Super-Sampling on the PVR */
GL_PERSPECTIVE_CORRECTION_HINT - This will Enable on the PVR */
GLAPI void APIENTRY glHint(GLenum target, GLenum mode) {
if(target == GL_PERSPECTIVE_CORRECTION_HINT && mode == GL_NICEST) {
// FIXME: enable supersampling
}
}
/* Culling */

View File

@ -454,7 +454,8 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D");
}
if(level < 0) {
/* FIXME: Mipmaps! */
if(level < 0 || level > 0) {
_glKosThrowError(GL_INVALID_VALUE, "glTexImage2D");
}
@ -486,9 +487,9 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
pvr_mem_free(active->data);
active->data = NULL;
}
}
}
GLuint bytes = level ? glKosMipMapTexSize(width, height) : (width * height * 2);
GLuint bytes = (width * height * sizeof(GLushort));
if(!active->data) {
/* need texture memory */

View File

@ -6,11 +6,8 @@
# Copyright (C) 2018 Luke Benstead
TARGET = libGL.a
OBJS = gl-rgb.o gl-fog.o gl-sh4-light.o gl-light.o gl-clip.o gl-clip-arrays.o
OBJS += gl-pvr.o gl-matrix.o gl-api.o glu-texture.o
OBJS += gl-framebuffer.o gl-error.o
OBJS += GL/draw.o GL/flush.o GL/framebuffer.o GL/immediate.o GL/lighting.o GL/state.o GL/texture.o
OBJS += GL/matrix.o
OBJS = GL/draw.o GL/flush.o GL/framebuffer.o GL/immediate.o GL/lighting.o GL/state.o GL/texture.o
OBJS += GL/matrix.o GL/fog.o GL/error.o
SUBDIRS =

663
gl-api.c
View File

@ -1,663 +0,0 @@
/* KallistiGL for KallistiOS ##version##
libgl/gl-api.c
Copyright (C) 2013-2014 Josh Pearson
Copyright (C) 2014 Lawrence Sebald
Some functionality adapted from the original KOS libgl:
Copyright (C) 2001 Dan Potter
Copyright (C) 2002 Benoit Miller
This API implements much but not all of the OpenGL 1.1 for KallistiOS.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "gl.h"
#include "glu.h"
#include "gl-api.h"
#include "gl-sh4.h"
#include "gl-pvr.h"
//====================================================================================================//
//== Local API State Macine Variables ==//
static GLubyte GL_KOS_DEPTH_FUNC = PVR_DEPTHCMP_GEQUAL;
static GLubyte GL_KOS_DEPTH_WRITE = PVR_DEPTHWRITE_ENABLE;
static GLubyte GL_KOS_BLEND_FUNC = (PVR_BLEND_ONE << 4) | (PVR_BLEND_ZERO & 0x0F);
static GLubyte GL_KOS_SHADE_FUNC = PVR_SHADE_GOURAUD;
static GLushort GL_KOS_CULL_FUNC = PVR_CULLING_NONE;
static GLushort GL_KOS_FACE_FRONT = GL_CCW;
static GLubyte GL_KOS_SUPERSAMPLE = 0;
static GLuint GL_KOS_VERTEX_COUNT = 0;
static GLuint GL_KOS_VERTEX_MODE = GL_TRIANGLES;
static GLuint GL_KOS_VERTEX_COLOR = 0xFFFFFFFF;
static GLfloat GL_KOS_VERTEX_UV[2] = { 0, 0 };
//static glTexCoord4f GL_KOS_VERTEX_TEX_COORD = { 0, 0, 0, 1 };
static GLfloat GL_KOS_COLOR_CLEAR[3] = { 0, 0, 0 };
static GLfloat GL_KOS_POINT_SIZE = 0.02;
static pvr_poly_cxt_t GL_KOS_POLY_CXT;
static inline void _glKosFlagsSetTriangleStrip();
static inline void _glKosFlagsSetTriangle();
static inline void _glKosFlagsSetQuad();
static inline void _glKosFinishRect();
//====================================================================================================//
//== API Initialization ==//
//void APIENTRY glKosInit() {
// _glKosInitPVR();
// _glKosInitTextures();
// _glKosInitMatrix();
// _glKosInitLighting();
// _glKosInitFrameBuffers();
//}
//====================================================================================================//
//== Blending / Shading functions ==//
//void APIENTRY glShadeModel(GLenum mode) {
// switch(mode) {
// case GL_FLAT:
// GL_KOS_SHADE_FUNC = PVR_SHADE_FLAT;
// break;
// case GL_SMOOTH:
// GL_KOS_SHADE_FUNC = PVR_SHADE_GOURAUD;
// break;
// }
//}
//void APIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor) {
// GL_KOS_BLEND_FUNC = 0;
// switch(sfactor) {
// case GL_ONE:
// GL_KOS_BLEND_FUNC |= (PVR_BLEND_ONE & 0XF) << 4;
// break;
// case GL_ZERO:
// GL_KOS_BLEND_FUNC |= (PVR_BLEND_ZERO & 0XF) << 4;
// break;
// case GL_SRC_COLOR:
// GL_KOS_BLEND_FUNC |= (PVR_BLEND_SRCALPHA & 0XF) << 4;
// break;
// case GL_DST_COLOR:
// GL_KOS_BLEND_FUNC |= (PVR_BLEND_DESTCOLOR & 0XF) << 4;
// break;
// case GL_SRC_ALPHA:
// GL_KOS_BLEND_FUNC |= (PVR_BLEND_SRCALPHA << 4);
// break;
// case GL_DST_ALPHA:
// GL_KOS_BLEND_FUNC |= (PVR_BLEND_DESTALPHA & 0XF) << 4;
// break;
// case GL_ONE_MINUS_SRC_ALPHA:
// GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVSRCALPHA & 0XF) << 4;
// break;
// case GL_ONE_MINUS_DST_ALPHA:
// GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVDESTALPHA & 0XF) << 4;
// break;
// case GL_ONE_MINUS_DST_COLOR:
// GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVDESTCOLOR & 0XF) << 4;
// break;
// }
// switch(dfactor) {
// case GL_ONE:
// GL_KOS_BLEND_FUNC |= (PVR_BLEND_ONE & 0XF);
// break;
// case GL_ZERO:
// GL_KOS_BLEND_FUNC |= (PVR_BLEND_ZERO & 0XF);
// break;
// case GL_SRC_COLOR:
// GL_KOS_BLEND_FUNC |= (PVR_BLEND_SRCALPHA & 0XF);
// break;
// case GL_DST_COLOR:
// GL_KOS_BLEND_FUNC |= (PVR_BLEND_DESTCOLOR & 0XF);
// break;
// case GL_SRC_ALPHA:
// GL_KOS_BLEND_FUNC |= (PVR_BLEND_SRCALPHA & 0XF);
// break;
// case GL_DST_ALPHA:
// GL_KOS_BLEND_FUNC |= (PVR_BLEND_DESTALPHA & 0XF);
// break;
// case GL_ONE_MINUS_SRC_ALPHA:
// GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVSRCALPHA & 0XF);
// break;
// case GL_ONE_MINUS_DST_ALPHA:
// GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVDESTALPHA & 0XF);
// break;
// case GL_ONE_MINUS_DST_COLOR:
// GL_KOS_BLEND_FUNC |= (PVR_BLEND_INVDESTCOLOR & 0XF);
// break;
// }
//}
//====================================================================================================//
//== Depth / Clear functions ==//
//void APIENTRY glClear(GLuint mode) {
// if(mode & GL_COLOR_BUFFER_BIT)
// pvr_set_bg_color(GL_KOS_COLOR_CLEAR[0], GL_KOS_COLOR_CLEAR[1], GL_KOS_COLOR_CLEAR[2]);
//}
//void APIENTRY glClearColor(float r, float g, float b, float a) {
// if(r > 1) r = 1;
// if(g > 1) g = 1;
// if(b > 1) b = 1;
// if(a > 1) a = 1;
// GL_KOS_COLOR_CLEAR[0] = r * a;
// GL_KOS_COLOR_CLEAR[1] = g * a;
// GL_KOS_COLOR_CLEAR[2] = b * a;
//}
//== NoOp ==//
//void APIENTRY glClearDepthf(GLfloat depth) {
// ;
//}
//void APIENTRY glDepthFunc(GLenum func) {
// switch(func) {
// case GL_LESS:
// GL_KOS_DEPTH_FUNC = PVR_DEPTHCMP_GEQUAL;
// break;
// case GL_LEQUAL:
// GL_KOS_DEPTH_FUNC = PVR_DEPTHCMP_GREATER;
// break;
// case GL_GREATER:
// GL_KOS_DEPTH_FUNC = PVR_DEPTHCMP_LEQUAL;
// break;
// case GL_GEQUAL:
// GL_KOS_DEPTH_FUNC = PVR_DEPTHCMP_LESS;
// break;
// default:
// GL_KOS_DEPTH_FUNC = (func & 0x0F);
// }
//}
//void APIENTRY glDepthMask(GLboolean flag) {
// GL_KOS_DEPTH_WRITE = (flag == GL_TRUE) ? PVR_DEPTHWRITE_ENABLE : PVR_DEPTHWRITE_DISABLE;
//}
//====================================================================================================//
//== Culling functions ==//
//void APIENTRY glFrontFace(GLenum mode) {
// switch(mode) {
// case GL_CW:
// case GL_CCW:
// GL_KOS_FACE_FRONT = mode;
// break;
// }
//}
//void APIENTRY glCullFace(GLenum mode) {
// switch(mode) {
// case GL_FRONT:
// case GL_BACK:
// case GL_FRONT_AND_BACK:
// GL_KOS_CULL_FUNC = mode;
// break;
// }
//}
//====================================================================================================//
//== Vertex Attributes Submission Functions ==//
//== Vertex Color Submission ==//
void APIENTRY glColor1ui(GLuint argb) {
GL_KOS_VERTEX_COLOR = argb;
}
void APIENTRY glColor4ub(GLubyte r, GLubyte g, GLubyte b, GLubyte a) {
GL_KOS_VERTEX_COLOR = a << 24 | r << 16 | g << 8 | b;
}
//== Vertex Position Submission Functions ==//
void APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) {
pvr_vertex_t *v = _glKosVertexBufPointer();
v[0].z = v[3].z = 0;
mat_trans_single3_nomod(x1, y1, v[0].z, v[0].x, v[0].y, v[0].z);
mat_trans_single3_nomod(x2, y2, v[3].z, v[3].x, v[3].y, v[3].z);
_glKosFinishRect();
}
void APIENTRY glRectfv(const GLfloat *v1, const GLfloat *v2) {
pvr_vertex_t *v = _glKosVertexBufPointer();
v[0].z = v[3].z = 0;
mat_trans_single3_nomod(v1[0], v1[1], v[0].z, v[0].x, v[0].y, v[0].z);
mat_trans_single3_nomod(v2[0], v2[1], v[3].z, v[3].x, v[3].y, v[3].z);
_glKosFinishRect();
}
void APIENTRY glRecti(GLint x1, GLint y1, GLint x2, GLint y2) {
return glRectf((GLfloat)x1, (GLfloat)y1, (GLfloat)x2, (GLfloat)y2);
}
void APIENTRY glRectiv(const GLint *v1, const GLint *v2) {
return glRectfv((const GLfloat *)v1, (const GLfloat *)v2);
}
//====================================================================================================//
//== GL Begin / End ==//
//====================================================================================================//
//== Misc. functions ==//
/* Clamp X to [MIN,MAX]: */
//void APIENTRY glHint(GLenum target, GLenum mode) {
// switch(target) {
// case GL_PERSPECTIVE_CORRECTION_HINT:
// if(mode == GL_NICEST)
// GL_KOS_SUPERSAMPLE = 1;
// else
// GL_KOS_SUPERSAMPLE = 0;
// break;
// }
//}
//====================================================================================================//
//== Internal API Vertex Submission functions ==//
void _glKosVertex3fs(GLfloat x, GLfloat y, GLfloat z) {
pvr_vertex_t *v = _glKosVertexBufPointer();
mat_trans_single3_nomod(x, y, z, v->x, v->y, v->z);
v->u = GL_KOS_VERTEX_UV[0];
v->v = GL_KOS_VERTEX_UV[1];
_glKosVertexBufIncrement();
++GL_KOS_VERTEX_COUNT;
}
void _glKosVertex3fsv(const GLfloat *xyz) {
pvr_vertex_t *v = _glKosVertexBufPointer();
mat_trans_single3_nomod(xyz[0], xyz[1], xyz[2], v->x, v->y, v->z);
v->u = GL_KOS_VERTEX_UV[0];
v->v = GL_KOS_VERTEX_UV[1];
_glKosVertexBufIncrement();
++GL_KOS_VERTEX_COUNT;
}
void _glKosVertex3ft(GLfloat x, GLfloat y, GLfloat z) {
pvr_vertex_t *v = _glKosVertexBufPointer();
mat_trans_single3_nomod(x, y, z, v->x, v->y, v->z);
v->u = GL_KOS_VERTEX_UV[0];
v->v = GL_KOS_VERTEX_UV[1];
v->argb = GL_KOS_VERTEX_COLOR;
_glKosVertexBufIncrement();
++GL_KOS_VERTEX_COUNT;
}
void _glKosVertex3ftv(const GLfloat *xyz) {
pvr_vertex_t *v = _glKosVertexBufPointer();
mat_trans_single3_nomod(xyz[0], xyz[1], xyz[2], v->x, v->y, v->z);
v->u = GL_KOS_VERTEX_UV[0];
v->v = GL_KOS_VERTEX_UV[1];
v->argb = GL_KOS_VERTEX_COLOR;
_glKosVertexBufIncrement();
++GL_KOS_VERTEX_COUNT;
}
void _glKosVertex3fc(GLfloat x, GLfloat y, GLfloat z) {
pvr_vertex_t *v = _glKosClipBufPointer();
v->x = x;
v->y = y;
v->z = z;
v->u = GL_KOS_VERTEX_UV[0];
v->v = GL_KOS_VERTEX_UV[1];
v->argb = GL_KOS_VERTEX_COLOR;
_glKosClipBufIncrement();
++GL_KOS_VERTEX_COUNT;
}
void _glKosVertex3fcv(const GLfloat *xyz) {
pvr_vertex_t *v = _glKosClipBufPointer();
v->x = xyz[0];
v->y = xyz[1];
v->z = xyz[2];
v->u = GL_KOS_VERTEX_UV[0];
v->v = GL_KOS_VERTEX_UV[1];
v->argb = GL_KOS_VERTEX_COLOR;
_glKosClipBufIncrement();
++GL_KOS_VERTEX_COUNT;
}
/* GL_POINTS */
GLvoid _glKosVertex3fp(GLfloat x, GLfloat y, GLfloat z) {
pvr_vertex_t *v = _glKosVertexBufPointer();
mat_trans_single3_nomod(x - GL_KOS_POINT_SIZE, y + GL_KOS_POINT_SIZE, z,
v[0].x, v[0].y, v[0].z);
mat_trans_single3_nomod(x + GL_KOS_POINT_SIZE, y - GL_KOS_POINT_SIZE, z,
v[3].x, v[3].y, v[3].z);
_glKosFinishRect();
}
GLvoid _glKosVertex3fpv(const GLfloat *xyz) {
pvr_vertex_t *v = _glKosVertexBufPointer();
mat_trans_single3_nomod(xyz[0] - GL_KOS_POINT_SIZE, xyz[1] + GL_KOS_POINT_SIZE, xyz[2],
v[0].x, v[0].y, v[0].z);
mat_trans_single3_nomod(xyz[0] + GL_KOS_POINT_SIZE, xyz[1] - GL_KOS_POINT_SIZE, xyz[2],
v[3].x, v[3].y, v[3].z);
_glKosFinishRect();
}
static inline void _glKosFinishRect() {
pvr_vertex_t *v = _glKosVertexBufPointer();
v[0].argb = v[1].argb = v[2].argb = v[3].argb = GL_KOS_VERTEX_COLOR;
v[0].flags = v[1].flags = v[2].flags = PVR_CMD_VERTEX;
v[3].flags = PVR_CMD_VERTEX_EOL;
v[1].x = v[0].x;
v[1].y = v[3].y;
v[1].z = v[3].z;
v[2].x = v[3].x;
v[2].y = v[0].y;
v[2].z = v[0].z;
_glKosVertexBufAdd(4);
GL_KOS_VERTEX_COUNT += 4;
}
void _glKosTransformClipBuf(pvr_vertex_t *v, GLuint verts) {
register float __x __asm__("fr12");
register float __y __asm__("fr13");
register float __z __asm__("fr14");
while(verts--) {
__x = v->x;
__y = v->y;
__z = v->z;
mat_trans_fv12();
v->x = __x;
v->y = __y;
v->z = __z;
++v;
}
}
static inline void _glKosVertexSwap(pvr_vertex_t *v1, pvr_vertex_t *v2) {
pvr_vertex_t tmp = *v1;
*v1 = *v2;
*v2 = * &tmp;
}
static inline void _glKosFlagsSetQuad() {
pvr_vertex_t *v = (pvr_vertex_t *)_glKosVertexBufPointer() - GL_KOS_VERTEX_COUNT;
GLuint i;
for(i = 0; i < GL_KOS_VERTEX_COUNT; i += 4) {
_glKosVertexSwap(v + 2, v + 3);
v->flags = (v + 1)->flags = (v + 2)->flags = PVR_CMD_VERTEX;
(v + 3)->flags = PVR_CMD_VERTEX_EOL;
v += 4;
}
}
static inline void _glKosFlagsSetTriangle() {
pvr_vertex_t *v = (pvr_vertex_t *)_glKosVertexBufPointer() - GL_KOS_VERTEX_COUNT;
GLuint i;
for(i = 0; i < GL_KOS_VERTEX_COUNT; i += 3) {
v->flags = (v + 1)->flags = PVR_CMD_VERTEX;
(v + 2)->flags = PVR_CMD_VERTEX_EOL;
v += 3;
}
}
static inline void _glKosFlagsSetTriangleStrip() {
pvr_vertex_t *v = (pvr_vertex_t *)_glKosVertexBufPointer() - GL_KOS_VERTEX_COUNT;
GLuint i;
for(i = 0; i < GL_KOS_VERTEX_COUNT - 1; i++) {
v->flags = PVR_CMD_VERTEX;
v++;
}
v->flags = PVR_CMD_VERTEX_EOL;
}
//====================================================================================================//
//== GL KOS PVR Header Parameter Compilation Functions ==//
static inline void _glKosApplyDepthFunc() {
if(_glKosEnabledDepthTest())
GL_KOS_POLY_CXT.depth.comparison = GL_KOS_DEPTH_FUNC;
else
GL_KOS_POLY_CXT.depth.comparison = PVR_DEPTHCMP_ALWAYS;
GL_KOS_POLY_CXT.depth.write = GL_KOS_DEPTH_WRITE;
}
static inline void _glKosApplyScissorFunc() {
if(_glKosEnabledScissorTest())
GL_KOS_POLY_CXT.gen.clip_mode = PVR_USERCLIP_INSIDE;
}
static inline void _glKosApplyFogFunc() {
if(_glKosEnabledFog())
GL_KOS_POLY_CXT.gen.fog_type = PVR_FOG_TABLE;
}
static inline void _glKosApplyCullingFunc() {
if(_glKosEnabledCulling()) {
if(GL_KOS_CULL_FUNC == GL_BACK) {
if(GL_KOS_FACE_FRONT == GL_CW)
GL_KOS_POLY_CXT.gen.culling = PVR_CULLING_CCW;
else
GL_KOS_POLY_CXT.gen.culling = PVR_CULLING_CW;
}
else if(GL_KOS_CULL_FUNC == GL_FRONT) {
if(GL_KOS_FACE_FRONT == GL_CCW)
GL_KOS_POLY_CXT.gen.culling = PVR_CULLING_CCW;
else
GL_KOS_POLY_CXT.gen.culling = PVR_CULLING_CW;
}
}
else
GL_KOS_POLY_CXT.gen.culling = PVR_CULLING_NONE;
}
static inline void _glKosApplyBlendFunc() {
if(_glKosEnabledBlend()) {
GL_KOS_POLY_CXT.blend.src = (GL_KOS_BLEND_FUNC & 0xF0) >> 4;
GL_KOS_POLY_CXT.blend.dst = (GL_KOS_BLEND_FUNC & 0x0F);
}
}
void _glKosCompileHdr() {
pvr_poly_hdr_t *hdr = _glKosVertexBufPointer();
pvr_poly_cxt_col(&GL_KOS_POLY_CXT, _glKosList() * 2);
GL_KOS_POLY_CXT.gen.shading = GL_KOS_SHADE_FUNC;
_glKosApplyDepthFunc();
_glKosApplyScissorFunc();
_glKosApplyFogFunc();
_glKosApplyCullingFunc();
_glKosApplyBlendFunc();
pvr_poly_compile(hdr, &GL_KOS_POLY_CXT);
_glKosVertexBufIncrement();
}
//====================================================================================================//
//== Internal GL KOS API State Functions ==//
GLuint _glKosBlendSrcFunc() {
switch((GL_KOS_BLEND_FUNC & 0xF0) >> 4) {
case PVR_BLEND_ONE:
return GL_ONE;
case PVR_BLEND_ZERO:
return GL_ZERO;
case PVR_BLEND_DESTCOLOR:
return GL_DST_COLOR;
case PVR_BLEND_SRCALPHA:
return GL_SRC_ALPHA;
case PVR_BLEND_DESTALPHA:
return GL_DST_ALPHA;
case PVR_BLEND_INVSRCALPHA:
return GL_ONE_MINUS_SRC_ALPHA;
case PVR_BLEND_INVDESTALPHA:
return GL_ONE_MINUS_DST_ALPHA;
case PVR_BLEND_INVDESTCOLOR:
return GL_ONE_MINUS_DST_COLOR;
}
return 0;
}
GLuint _glKosBlendDstFunc() {
switch(GL_KOS_BLEND_FUNC & 0xF) {
case PVR_BLEND_ONE:
return GL_ONE;
case PVR_BLEND_ZERO:
return GL_ZERO;
case PVR_BLEND_DESTCOLOR:
return GL_DST_COLOR;
case PVR_BLEND_SRCALPHA:
return GL_SRC_ALPHA;
case PVR_BLEND_DESTALPHA:
return GL_DST_ALPHA;
case PVR_BLEND_INVSRCALPHA:
return GL_ONE_MINUS_SRC_ALPHA;
case PVR_BLEND_INVDESTALPHA:
return GL_ONE_MINUS_DST_ALPHA;
case PVR_BLEND_INVDESTCOLOR:
return GL_ONE_MINUS_DST_COLOR;
}
return 0;
}
GLubyte _glKosCullFaceMode() {
return GL_KOS_CULL_FUNC;
}
GLubyte _glKosCullFaceFront() {
return GL_KOS_FACE_FRONT;
}
GLuint _glKosDepthFunc() {
switch(GL_KOS_DEPTH_FUNC) {
case PVR_DEPTHCMP_GEQUAL:
return GL_LESS;
case PVR_DEPTHCMP_GREATER:
return GL_LEQUAL;
case PVR_DEPTHCMP_LEQUAL:
return GL_GREATER;
case PVR_DEPTHCMP_LESS:
return GL_GEQUAL;
default:
return GL_NEVER + GL_KOS_DEPTH_FUNC;
}
}
GLubyte _glKosDepthMask() {
return (GL_KOS_DEPTH_WRITE == PVR_DEPTHWRITE_ENABLE) ? GL_TRUE : GL_FALSE;
}
GLuint _glKosVertexColor() {
return GL_KOS_VERTEX_COLOR;
}

206
gl-api.h
View File

@ -1,206 +0,0 @@
/* KallistiGL for KallistiOS ##version##
libgl/gl-api.h
Copyright (C) 2013-2014 Josh Pearson
The functions defined in this header are for internal use by the API,
and not for use externally.
*/
#ifndef GL_API_H
#define GL_API_H
#include "gl.h"
typedef struct {
GLfloat pos[3];
GLfloat norm[3];
} glVertex; /* Simple Vertex used for Dynamic Vertex Lighting */
typedef struct {
GLfloat u, v;
} glTexCoord; /* Simple Texture Coordinate used for Multi-Texturing */
typedef struct {
GLfloat s, t, r, q;
} glTexCoord4f; /* 3D Texture Coordinate */
typedef struct {
GLuint texID;
GLsizei index;
GLvoid *data;
GLvoid *link;
} GL_FRAMEBUFFER_OBJECT; /* KOS Open GL Frame Buffer Object */
typedef struct {
pvr_poly_hdr_t hdr;
pvr_vertex_t *src;
GLuint count;
} GL_MULTITEX_OBJECT;
typedef GLushort uint16;
typedef GLubyte uint8;
/* Vertex Main Buffer Internal Functions */
void _glKosVertexBufSwitchOP();
void _glKosVertexBufSwitchTR();
void *_glKosVertexBufAddress(unsigned char list);
void *_glKosVertexBufPointer();
void *_glKosTRVertexBufPointer();
void _glKosVertexBufIncrement();
void _glKosTRVertexBufIncrement();
void _glKosVertexBufAdd(unsigned int count);
void _glKosTRVertexBufAdd(unsigned int count);
void _glKosVertexBufDecrement();
void _glKosVertexBufReset();
unsigned int _glKosVertexBufCount(unsigned char list);
unsigned char _glKosList();
void _glKosVertexBufCopy(void *src, void *dst, GLuint count);
void _glKosResetEnabledTex();
void *_glKosMultiUVBufAddress();
void *_glKosMultiUVBufPointer();
void _glKosMultiUVBufIncrement();
void _glKosMultiUVBufAdd(GLuint count);
void _glKosMultiUVBufReset();
/* Vertex Clip Buffer Internal Functions */
void *_glKosClipBufAddress();
void *_glKosClipBufPointer();
void _glKosClipBufIncrement();
void _glKosClipBufReset();
/* Vertex Array Buffer Internal Functions */
void _glKosArrayBufIncrement();
void _glKosArrayBufReset();
glVertex *_glKosArrayBufAddr();
glVertex *_glKosArrayBufPtr();
/* Initialize the OpenGL PVR Pipeline */
int _glKosInitPVR();
unsigned char _glKosInitTextures();
/* Compile the current Polygon Header for the PVR */
void _glKosCompileHdr();
void _glKosCompileHdrTx();
void _glKosCompileHdrMTx();
/* Clipping Internal Functions */
void _glKosTransformClipBuf(pvr_vertex_t *v, GLuint verts);
unsigned int _glKosClipTriangleStrip(pvr_vertex_t *vin, pvr_vertex_t *vout, unsigned int vertices);
unsigned int _glKosClipTriangles(pvr_vertex_t *vin, pvr_vertex_t *vout, unsigned int vertices);
unsigned int _glKosClipQuads(pvr_vertex_t *vin, pvr_vertex_t *vout, unsigned int vertices);
unsigned int _glKosClipTrianglesTransformed(pvr_vertex_t *src, float *w, pvr_vertex_t *dst, GLuint count);
unsigned int _glKosClipQuadsTransformed(pvr_vertex_t *vin, float *w, pvr_vertex_t *vout, unsigned int vertices);
unsigned int _glKosClipTriangleStripTransformed(pvr_vertex_t *src, float *w, pvr_vertex_t *dst, GLuint count);
unsigned int _glKosClipTrianglesTransformedMT(pvr_vertex_t *src, float *w, pvr_vertex_t *dst,
GLfloat *uvsrc, glTexCoord *uvdst, GLuint uv_src_stride, GLuint count);
unsigned int _glKosClipTriangleStripTransformedMT(pvr_vertex_t *src, float *w, pvr_vertex_t *dst,
GLfloat *uvsrc, glTexCoord *uvdst, GLuint uv_src_stride, GLuint count);
unsigned int _glKosClipQuadsTransformedMT(pvr_vertex_t *src, float *w, pvr_vertex_t *dst,
GLfloat *uvsrc, glTexCoord *uvdst, GLuint uv_src_stride, GLuint count);
/* Lighting Internal Functions */
void _glKosInitLighting();
void _glKosEnableLight(const GLuint light);
void _glKosDisableLight(const GLuint light);
void _glKosSetEyePosition(GLfloat *position);
void _glKosVertexComputeLighting(pvr_vertex_t *v, int verts);
void _glKosVertexLight(glVertex *P, pvr_vertex_t *v);
unsigned int _glKosVertexLightColor(glVertex *P);
void _glKosVertexLights(glVertex *P, pvr_vertex_t *v, GLuint count);
/* Vertex Position Submission Internal Functions */
void _glKosVertex3ft(GLfloat x, GLfloat y, GLfloat z);
void _glKosVertex3ftv(const GLfloat *xyz);
void _glKosVertex3fc(GLfloat x, GLfloat y, GLfloat z);
void _glKosVertex3fcv(const GLfloat *xyz);
void _glKosVertex3fp(GLfloat x, GLfloat y, GLfloat z);
void _glKosVertex3fpv(const GLfloat *xyz);
void _glKosVertex3fl(GLfloat x, GLfloat y, GLfloat z);
void _glKosVertex3flv(const GLfloat *xyz);
void _glKosVertex3flc(GLfloat x, GLfloat y, GLfloat z);
void _glKosVertex3flcv(const GLfloat *xyz);
void _glKosVertex3fs(GLfloat x, GLfloat y, GLfloat z);
void _glKosVertex3fsv(const GLfloat *xyz);
/* Matrix Internal Functions */
void _glKosInitMatrix();
void _glKosMatrixLoadModelView();
void _glKosMatrixLoadModelRot();
void _glKosMatrixApplyScreenSpace();
void _glKosMatrixApplyRender();
void _glKosMatrixLoadRender();
void _glKosMatrixLoadTexture();
/* API Enabled Capabilities Internal Functions */
GLubyte _glKosEnabledBlend();
GLubyte _glKosEnabledTexture2D();
GLubyte _glKosEnabledNearZClip();
GLubyte _glKosEnabledLighting();
GLubyte _glKosEnabledFog();
GLubyte _glKosEnabledCulling();
GLubyte _glKosEnabledScissorTest();
GLubyte _glKosEnabledDepthTest();
/* RGB Pixel Colorspace Internal Functions */
uint16 __glKosAverageQuadPixelRGB565(uint16 p1, uint16 p2, uint16 p3, uint16 p4);
uint16 __glKosAverageQuadPixelARGB1555(uint16 p1, uint16 p2, uint16 p3, uint16 p4);
uint16 __glKosAverageQuadPixelARGB4444(uint16 p1, uint16 p2, uint16 p3, uint16 p4);
uint16 __glKosAverageBiPixelRGB565(uint16 p1, uint16 p2);
uint16 __glKosAverageBiPixelARGB1555(uint16 p1, uint16 p2);
uint16 __glKosAverageBiPixelARGB4444(uint16 p1, uint16 p2);
/* Render-To-Texture Functions */
void _glKosInitFrameBuffers();
/* Error Codes */
void _glKosThrowError(GLenum error, const char *functionName);
void _glKosPrintError();
GLubyte _glKosHasError();
GLuint _glKosTextureWidth(GLuint index);
GLuint _glKosTextureHeight(GLuint index);
GLvoid *_glKosTextureData(GLuint index);
/* Frame Buffer Object Internal Functions */
GLsizei _glKosGetFBO();
GLuint _glKosGetFBOWidth(GLsizei fbi);
GLuint _glKosGetFBOHeight(GLsizei fbi);
GLvoid *_glKosGetFBOData(GLsizei fbi);
/* Internal State Cap Accessors */
GLubyte _glKosEnabledDepthTest();
GLubyte _glKosEnabledScissorTest();
GLubyte _glKosEnabledCulling();
GLubyte _glKosEnabledFog();
GLubyte _glKosEnabledLighting();
GLubyte _glKosEnabledNearZClip();
GLubyte _glKosEnabledTexture2D();
GLubyte _glKosEnabledBlend();
GLuint _glKosBlendSrcFunc();
GLuint _glKosBlendDstFunc();
GLubyte _glKosCullFaceMode();
GLubyte _glKosCullFaceFront();
GLuint _glKosDepthFunc();
GLubyte _glKosDepthMask();
GLubyte _glKosIsLightEnabled(GLubyte light);
GLubyte _glKosGetMaxLights();
GLuint _glKosBoundTexID();
GLuint _glKosVertexColor();
GLubyte _glKosMaxTextureUnits();
GLubyte _glKosEnabledTextureMatrix();
GLuint _glKosActiveTextureBoundTexID();
static inline void _glKosVertexCopyPVR(const pvr_vertex_t *src, pvr_vertex_t *dst) {
*dst = *src;
}
static inline void _glKosTexCoordCopy(const glTexCoord *src, glTexCoord *dst) {
*dst = *src;
}
#endif

View File

@ -1,418 +0,0 @@
/* KallistiGL for KallistiOS ##version##
libgl/gl-clip.c
Copyright (C) 2013-2014 Josh Pearson
Near-Z Clipping Algorithm (C) 2013-2014 Josh PH3NOM Pearson
Input Primitive Types Supported:
-GL_TRIANGLES
-GL_TRIANGLE_STRIPS
-GL_QUADS
Outputs a mix of Triangles and Triangle Strips for use with the PVR
*/
#include <stdio.h>
#include <string.h>
#include "gl.h"
#include "gl-api.h"
#include "gl-clip.h"
static inline void _glKosVertexClipZNear2(pvr_vertex_t *v1, pvr_vertex_t *v2,
GLfloat *w1, GLfloat *w2,
glTexCoord *uva, glTexCoord *uvb) {
GLfloat MAG = ((CLIP_NEARZ - v1->z) / (v2->z - v1->z));
colorui *c1 = (colorui *)&v1->argb; /* GLubyte Color Component Pointer */
colorui *c2 = (colorui *)&v2->argb;
v1->x += (v2->x - v1->x) * MAG; /* Clip Vertex X, Y, Z Components */
v1->y += (v2->y - v1->y) * MAG;
v1->z += (v2->z - v1->z) * MAG;
v1->u += (v2->u - v1->u) * MAG; /* Clip Vertex Texture Coordinates */
v1->v += (v2->v - v1->v) * MAG;
c1->a += (c2->a - c1->a) * MAG; /* Clip Vertex Color per ARGB component */
c1->r += (c2->r - c1->r) * MAG;
c1->g += (c2->g - c1->g) * MAG;
c1->b += (c2->b - c1->b) * MAG;
*w1 += (*w2 - *w1) * MAG; /* Clip Vertex W Component */
uva->u += (uvb->u - uva->u) * MAG; /* Clip Vertex Multi-Texture Coordinates */
uva->v += (uvb->v - uva->v) * MAG;
}
static inline void _glKosVertexClipZNear3(pvr_vertex_t *v1, pvr_vertex_t *v2, float *w1, float *w2) {
GLfloat MAG = ((CLIP_NEARZ - v1->z) / (v2->z - v1->z));
colorui *c1 = (colorui *)&v1->argb;
colorui *c2 = (colorui *)&v2->argb;
v1->x += (v2->x - v1->x) * MAG;
v1->y += (v2->y - v1->y) * MAG;
v1->z += (v2->z - v1->z) * MAG;
v1->u += (v2->u - v1->u) * MAG;
v1->v += (v2->v - v1->v) * MAG;
c1->a += (c2->a - c1->a) * MAG;
c1->r += (c2->r - c1->r) * MAG;
c1->g += (c2->g - c1->g) * MAG;
c1->b += (c2->b - c1->b) * MAG;
*w1 += (*w2 - *w1) * MAG;
}
static inline void _glKosVertexPerspectiveDivide(pvr_vertex_t *dst, GLfloat w) {
dst->z = 1.0f / w;
dst->x *= dst->z;
dst->y *= dst->z;
}
static inline GLubyte _glKosClipTriTransformed(pvr_vertex_t *src, GLfloat *w, pvr_vertex_t *dst) {
GLushort clip = 0; /* Clip Code for current Triangle */
GLubyte verts_in = 0; /* # of Vertices inside clip plane for current Triangle */
GLfloat W[4] = { w[0], w[1], w[2] }; /* W Component for Perspective Divide */
(src[0].z >= CLIP_NEARZ) ? clip |= FIRST : ++verts_in;
(src[1].z >= CLIP_NEARZ) ? clip |= SECOND : ++verts_in;
(src[2].z >= CLIP_NEARZ) ? clip |= THIRD : ++verts_in;
switch(verts_in) { /* Start by examining # of vertices inside clip plane */
case 0: /* All Vertices of Triangle are Outside of clip plne */
return 0;
case 3: /* All Vertices of Triangle are inside of clip plne */
_glKosVertexCopyPVR(&src[0], &dst[0]);
_glKosVertexCopyPVR(&src[1], &dst[1]);
_glKosVertexCopyPVR(&src[2], &dst[2]);
_glKosVertexPerspectiveDivide(&dst[0], W[0]);
_glKosVertexPerspectiveDivide(&dst[1], W[1]);
_glKosVertexPerspectiveDivide(&dst[2], W[2]);
dst[0].flags = dst[1].flags = PVR_CMD_VERTEX;
dst[2].flags = PVR_CMD_VERTEX_EOL;
return 3;
case 1:/* 1 Vertex of Triangle is inside of clip plane = output 1 Triangle */
_glKosVertexCopyPVR(&src[0], &dst[0]);
_glKosVertexCopyPVR(&src[1], &dst[1]);
_glKosVertexCopyPVR(&src[2], &dst[2]);
switch(clip) {
case FIRST_TWO_OUT:
_glKosVertexClipZNear3(&dst[0], &dst[2], &W[0], &W[2]);
_glKosVertexClipZNear3(&dst[1], &dst[2], &W[1], &W[2]);
break;
case FIRST_AND_LAST_OUT:
_glKosVertexClipZNear3(&dst[0], &dst[1], &W[0], &W[1]);
_glKosVertexClipZNear3(&dst[2], &dst[1], &W[2], &W[1]);
break;
case LAST_TWO_OUT:
_glKosVertexClipZNear3(&dst[1], &dst[0], &W[1], &W[0]);
_glKosVertexClipZNear3(&dst[2], &dst[0], &W[2], &W[0]);
break;
}
_glKosVertexPerspectiveDivide(&dst[0], W[0]);
_glKosVertexPerspectiveDivide(&dst[1], W[1]);
_glKosVertexPerspectiveDivide(&dst[2], W[2]);
dst[0].flags = dst[1].flags = PVR_CMD_VERTEX;
dst[2].flags = PVR_CMD_VERTEX_EOL;
return 3;
case 2:/* 2 Vertices of Triangle are inside of clip plane = output 2 Triangles */
switch(clip) {
case FIRST:
_glKosVertexCopyPVR(&src[0], &dst[0]);
_glKosVertexCopyPVR(&src[1], &dst[1]);
_glKosVertexCopyPVR(&src[0], &dst[2]);
_glKosVertexCopyPVR(&src[2], &dst[3]);
W[3] = W[2];
W[2] = W[0];
break;
case SECOND:
_glKosVertexCopyPVR(&src[1], &dst[0]);
_glKosVertexCopyPVR(&src[2], &dst[1]);
_glKosVertexCopyPVR(&src[1], &dst[2]);
_glKosVertexCopyPVR(&src[0], &dst[3]);
W[3] = W[0];
W[0] = W[1];
W[1] = W[2];
W[2] = W[0];
break;
case THIRD:
_glKosVertexCopyPVR(&src[2], &dst[0]);
_glKosVertexCopyPVR(&src[0], &dst[1]);
_glKosVertexCopyPVR(&src[2], &dst[2]);
_glKosVertexCopyPVR(&src[1], &dst[3]);
W[3] = W[1];
W[1] = W[0];
W[0] = W[2];
break;
}
_glKosVertexClipZNear3(&dst[0], &dst[1], &W[0], &W[1]);
_glKosVertexClipZNear3(&dst[2], &dst[3], &W[2], &W[3]);
_glKosVertexPerspectiveDivide(&dst[0], W[0]);
_glKosVertexPerspectiveDivide(&dst[1], W[1]);
_glKosVertexPerspectiveDivide(&dst[2], W[2]);
_glKosVertexPerspectiveDivide(&dst[3], W[3]);
dst[0].flags = dst[1].flags = dst[2].flags = PVR_CMD_VERTEX;
dst[3].flags = PVR_CMD_VERTEX_EOL;
return 4;
}
return 0;
}
GLuint _glKosClipTrianglesTransformed(pvr_vertex_t *src, GLfloat *w, pvr_vertex_t *dst, GLuint count) {
GLuint verts_out = 0;
GLuint i;
for(i = 0; i < count; i += 3)
verts_out += _glKosClipTriTransformed(&src[i], &w[i], &dst[verts_out]);
return verts_out;
}
GLuint _glKosClipTriangleStripTransformed(pvr_vertex_t *src, GLfloat *w, pvr_vertex_t *dst, GLuint count) {
GLuint verts_out = 0;
GLuint i;
for(i = 0; i < (count - 2); i ++)
verts_out += _glKosClipTriTransformed(&src[i], &w[i], &dst[verts_out]);
return verts_out;
}
unsigned int _glKosClipQuadsTransformed(pvr_vertex_t *src, GLfloat *w, pvr_vertex_t *dst, GLuint count) {
GLuint i, verts_out = 0;
pvr_vertex_t qv[3];
GLfloat W[3];
for(i = 0; i < count; i += 4) { /* Iterate all Quads, Rearranging into Triangle Strips */
_glKosVertexCopyPVR(&src[i + 0], &qv[0]);
_glKosVertexCopyPVR(&src[i + 2], &qv[1]);
_glKosVertexCopyPVR(&src[i + 3], &qv[2]);
W[0] = w[0];
W[1] = w[2];
W[2] = w[3];
verts_out += _glKosClipTriTransformed(&src[i], &w[i], &dst[verts_out]);
verts_out += _glKosClipTriTransformed(qv, W, &dst[verts_out]);
}
return verts_out;
}
static inline GLubyte _glKosClipTriTransformedMT(pvr_vertex_t *src, float *w, pvr_vertex_t *dst,
GLfloat *uvsrc, glTexCoord *uvdst, GLuint uv_src_stride) {
GLushort clip = 0; /* Clip Code for current Triangle */
GLubyte verts_in = 0; /* # of Vertices inside clip plane for current Triangle */
GLfloat W[4] = { w[0], w[1], w[2] }; /* W Component for Perspective Divide */
(src[0].z >= CLIP_NEARZ) ? clip |= FIRST : ++verts_in;
(src[1].z >= CLIP_NEARZ) ? clip |= SECOND : ++verts_in;
(src[2].z >= CLIP_NEARZ) ? clip |= THIRD : ++verts_in;
switch(verts_in) { /* Start by examining # of vertices inside clip plane */
case 0: /* All Vertices of Triangle are Outside of clip plane */
return 0;
case 3: /* All Vertices of Triangle are Inside of clip plane */
_glKosVertexCopyPVR(&src[0], &dst[0]);
_glKosVertexCopyPVR(&src[1], &dst[1]);
_glKosVertexCopyPVR(&src[2], &dst[2]);
_glKosTexCoordCopy((glTexCoord *)&uvsrc[0], &uvdst[0]);
_glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride], &uvdst[1]);
_glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride + uv_src_stride], &uvdst[2]);
_glKosVertexPerspectiveDivide(&dst[0], W[0]);
_glKosVertexPerspectiveDivide(&dst[1], W[1]);
_glKosVertexPerspectiveDivide(&dst[2], W[2]);
dst[0].flags = dst[1].flags = PVR_CMD_VERTEX;
dst[2].flags = PVR_CMD_VERTEX_EOL;
return 3;
case 1:/* 1 Vertex of Triangle is Inside of clip plane = output 1 Triangle */
_glKosVertexCopyPVR(&src[0], &dst[0]);
_glKosVertexCopyPVR(&src[1], &dst[1]);
_glKosVertexCopyPVR(&src[2], &dst[2]);
_glKosTexCoordCopy((glTexCoord *)&uvsrc[0], &uvdst[0]);
_glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride], &uvdst[1]);
_glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride + uv_src_stride], &uvdst[2]);
switch(clip) {
case FIRST_TWO_OUT:
_glKosVertexClipZNear2(&dst[0], &dst[2], &W[0], &W[2], &uvdst[0], &uvdst[2]);
_glKosVertexClipZNear2(&dst[1], &dst[2], &W[1], &W[2], &uvdst[1], &uvdst[2]);
break;
case FIRST_AND_LAST_OUT:
_glKosVertexClipZNear2(&dst[0], &dst[1], &W[0], &W[1], &uvdst[0], &uvdst[1]);
_glKosVertexClipZNear2(&dst[2], &dst[1], &W[2], &W[1], &uvdst[2], &uvdst[1]);
break;
case LAST_TWO_OUT:
_glKosVertexClipZNear2(&dst[1], &dst[0], &W[1], &W[0], &uvdst[1], &uvdst[0]);
_glKosVertexClipZNear2(&dst[2], &dst[0], &W[2], &W[0], &uvdst[2], &uvdst[0]);
break;
}
_glKosVertexPerspectiveDivide(&dst[0], W[0]);
_glKosVertexPerspectiveDivide(&dst[1], W[1]);
_glKosVertexPerspectiveDivide(&dst[2], W[2]);
dst[0].flags = dst[1].flags = PVR_CMD_VERTEX;
dst[2].flags = PVR_CMD_VERTEX_EOL;
return 3;
case 2:/* 2 Vertices of Triangle are inside of clip plane = output 2 Triangles */
switch(clip) {
case FIRST:
_glKosVertexCopyPVR(&src[0], &dst[0]);
_glKosVertexCopyPVR(&src[1], &dst[1]);
_glKosVertexCopyPVR(&src[0], &dst[2]);
_glKosVertexCopyPVR(&src[2], &dst[3]);
_glKosTexCoordCopy((glTexCoord *)&uvsrc[0], &uvdst[0]);
_glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride], &uvdst[1]);
_glKosTexCoordCopy((glTexCoord *)&uvsrc[0], &uvdst[2]);
_glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride + uv_src_stride], &uvdst[3]);
W[3] = W[2];
W[2] = W[0];
break;
case SECOND:
_glKosVertexCopyPVR(&src[1], &dst[0]);
_glKosVertexCopyPVR(&src[2], &dst[1]);
_glKosVertexCopyPVR(&src[1], &dst[2]);
_glKosVertexCopyPVR(&src[0], &dst[3]);
_glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride], &uvdst[0]);
_glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride + uv_src_stride], &uvdst[1]);
_glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride], &uvdst[2]);
_glKosTexCoordCopy((glTexCoord *)&uvsrc[0], &uvdst[3]);
W[3] = W[0];
W[0] = W[1];
W[1] = W[2];
W[2] = W[0];
break;
case THIRD:
_glKosVertexCopyPVR(&src[2], &dst[0]);
_glKosVertexCopyPVR(&src[0], &dst[1]);
_glKosVertexCopyPVR(&src[2], &dst[2]);
_glKosVertexCopyPVR(&src[1], &dst[3]);
_glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride + uv_src_stride], &uvdst[0]);
_glKosTexCoordCopy((glTexCoord *)&uvsrc[0], &uvdst[1]);
_glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride + uv_src_stride], &uvdst[2]);
_glKosTexCoordCopy((glTexCoord *)&uvsrc[uv_src_stride], &uvdst[3]);
W[3] = W[1];
W[1] = W[0];
W[0] = W[2];
break;
}
_glKosVertexClipZNear2(&dst[0], &dst[1], &W[0], &W[1], &uvdst[0], &uvdst[1]);
_glKosVertexClipZNear2(&dst[2], &dst[3], &W[2], &W[3], &uvdst[2], &uvdst[3]);
_glKosVertexPerspectiveDivide(&dst[0], W[0]);
_glKosVertexPerspectiveDivide(&dst[1], W[1]);
_glKosVertexPerspectiveDivide(&dst[2], W[2]);
_glKosVertexPerspectiveDivide(&dst[3], W[3]);
dst[0].flags = dst[1].flags = dst[2].flags = PVR_CMD_VERTEX;
dst[3].flags = PVR_CMD_VERTEX_EOL;
return 4;
}
return 0;
}
GLuint _glKosClipTrianglesTransformedMT(pvr_vertex_t *src, float *w, pvr_vertex_t *dst,
GLfloat *uvsrc, glTexCoord *uvdst, GLuint uv_src_stride,
GLuint count) {
GLuint verts_out = 0;
GLuint i;
for(i = 0; i < count; i += 3)
verts_out += _glKosClipTriTransformedMT(&src[i], &w[i], &dst[verts_out],
&uvsrc[i * uv_src_stride], &uvdst[verts_out], uv_src_stride);
return verts_out;
}
GLuint _glKosClipTriangleStripTransformedMT(pvr_vertex_t *src, float *w, pvr_vertex_t *dst,
GLfloat *uvsrc, glTexCoord *uvdst, GLuint uv_src_stride, GLuint count) {
GLuint verts_out = 0;
GLuint i;
for(i = 0; i < (count - 2); i ++)
verts_out += _glKosClipTriTransformedMT(&src[i], &w[i], &dst[verts_out],
&uvsrc[i * uv_src_stride], &uvdst[verts_out], uv_src_stride);
return verts_out;
}
GLuint _glKosClipQuadsTransformedMT(pvr_vertex_t *src, float *w, pvr_vertex_t *dst,
GLfloat *uvsrc, glTexCoord *uvdst, GLuint uv_src_stride, GLuint count) {
GLuint i, verts_out = 0;
pvr_vertex_t qv[3];
glTexCoord uv[3];
GLfloat W[3];
for(i = 0; i < count; i += 4) {
_glKosVertexCopyPVR(&src[i + 0], &qv[0]);
_glKosVertexCopyPVR(&src[i + 2], &qv[1]);
_glKosVertexCopyPVR(&src[i + 3], &qv[2]);
_glKosTexCoordCopy((glTexCoord *)&uvsrc[i * uv_src_stride], &uv[0]);
_glKosTexCoordCopy((glTexCoord *)&uvsrc[i * uv_src_stride + (uv_src_stride * 2)], &uv[1]);
_glKosTexCoordCopy((glTexCoord *)&uvsrc[i * uv_src_stride + (uv_src_stride * 3)], &uv[2]);
W[0] = w[0];
W[1] = w[2];
W[2] = w[3];
verts_out += _glKosClipTriTransformedMT(&src[i], &w[i], &dst[verts_out],
&uvsrc[i * uv_src_stride], &uvdst[verts_out], uv_src_stride);
verts_out += _glKosClipTriTransformedMT(qv, W, &dst[verts_out],
(GLfloat *)uv, &uvdst[verts_out], 2);
}
return verts_out;
}

310
gl-clip.c
View File

@ -1,310 +0,0 @@
/* KallistiGL for KallistiOS ##version##
libgl/gl-clip.c
Copyright (C) 2013-2014 Josh Pearson
Near-Z Clipping Algorithm (C) 2013-2014 Josh PH3NOM Pearson
Input Primitive Types Supported:
-GL_TRIANGLES
-GL_TRIANGLE_STRIPS
-GL_QUADS
Outputs a mix of Triangles and Triangle Strips for use with the PVR
*/
#include <stdio.h>
#include <string.h>
#include "gl.h"
#include "gl-api.h"
#include "gl-clip.h"
static float3 CLIP_BUF[1024 * 32];
static inline void _glKosVertexClipZNear(pvr_vertex_t *v1, pvr_vertex_t *v2, float MAG) {
colorui *c1 = (colorui *)&v1->argb;
colorui *c2 = (colorui *)&v2->argb;
v1->x += (v2->x - v1->x) * MAG;
v1->y += (v2->y - v1->y) * MAG;
v1->z += (v2->z - v1->z) * MAG;
v1->u += (v2->u - v1->u) * MAG;
v1->v += (v2->v - v1->v) * MAG;
c1->a += (c2->a - c1->a) * MAG;
c1->r += (c2->r - c1->r) * MAG;
c1->g += (c2->g - c1->g) * MAG;
c1->b += (c2->b - c1->b) * MAG;
}
static GLuint _glKosTransformClip(pvr_vertex_t *v, GLint count) {
pvr_vertex_t *V = v;
float3 *C = CLIP_BUF;
GLuint in = 0;
while(count--) {
mat_trans_single3_nodiv_nomod(V->x, V->y, V->z, C->x, C->y, C->z);
if(C->z < CLIP_NEARZ) ++in;
++C;
++V;
}
return in;
}
GLuint _glKosClipTriangleStrip(pvr_vertex_t *src, pvr_vertex_t *dst, GLuint vertices) {
GLuint i, v = 0, in = _glKosTransformClip(src, vertices);
float3 *C = CLIP_BUF;
if(in == vertices) {
memcpy(dst, src, vertices * 0x20);
pvr_vertex_t *v = dst;
while(--in) {
v->flags = PVR_CMD_VERTEX;
++v;
}
v->flags = PVR_CMD_VERTEX_EOL;
return vertices;
}
else if(in == 0)
return 0;
/* Iterate all Triangles of the Strip - Hence looping vertices-2 times */
for(i = 0; i < ((vertices) - 2); i++) {
GLushort clip = 0; /* Clip Code for current Triangle */
GLubyte verts_in = 0; /* # of Verteices inside clip plane for current Triangle */
C->z >= CLIP_NEARZ ? clip |= FIRST : ++verts_in;
(C + 1)->z >= CLIP_NEARZ ? clip |= SECOND : ++verts_in;
(C + 2)->z >= CLIP_NEARZ ? clip |= THIRD : ++verts_in;
switch(verts_in) { /* Start by examining # of vertices inside clip plane */
case 0: /* All Vertices of Triangle are outside of clip plne */
break;
case 3: /* All Vertices of Triangle are inside of clip plne */
memcpy(&dst[v], &src[i], 96);
dst[v].flags = dst[v + 1].flags = PVR_CMD_VERTEX;
dst[v + 2].flags = PVR_CMD_VERTEX_EOL;
v += 3;
break;
case 1:/* 1 Vertex of Triangle is inside of clip plane = output 1 Triangle */
memcpy(&dst[v], &src[i], 96);
switch(clip) {
case FIRST_TWO_OUT:
_glKosVertexClipZNear(&dst[v], &dst[v + 2], _glKosNearZClipMag(&CLIP_BUF[i], &CLIP_BUF[i + 2]));
_glKosVertexClipZNear(&dst[v + 1], &dst[v + 2], _glKosNearZClipMag(&CLIP_BUF[i + 1], &CLIP_BUF[i + 2]));
break;
case FIRST_AND_LAST_OUT:
_glKosVertexClipZNear(&dst[v], &dst[v + 1], _glKosNearZClipMag(&CLIP_BUF[i], &CLIP_BUF[i + 1]));
_glKosVertexClipZNear(&dst[v + 2], &dst[v + 1], _glKosNearZClipMag(&CLIP_BUF[i + 2], &CLIP_BUF[i + 1]));
break;
case LAST_TWO_OUT:
_glKosVertexClipZNear(&dst[v + 1], &dst[v], _glKosNearZClipMag(&CLIP_BUF[i + 1], &CLIP_BUF[i + 0]));
_glKosVertexClipZNear(&dst[v + 2], &dst[v], _glKosNearZClipMag(&CLIP_BUF[i + 2], &CLIP_BUF[i + 0]));
break;
}
dst[v].flags = dst[v + 1].flags = PVR_CMD_VERTEX;
dst[v + 2].flags = PVR_CMD_VERTEX_EOL;
v += 3;
break;
case 2:/* 2 Vertices of Triangle are inside of clip plane = output 2 Triangles */
switch(clip) {
case FIRST:
_glKosVertexCopyPVR(&src[i + 0], &dst[v + 0]);
_glKosVertexCopyPVR(&src[i + 1], &dst[v + 1]);
_glKosVertexCopyPVR(&src[i + 0], &dst[v + 2]);
_glKosVertexCopyPVR(&src[i + 2], &dst[v + 3]);
_glKosVertexClipZNear(&dst[v + 0], &dst[v + 1], _glKosNearZClipMag(&CLIP_BUF[i], &CLIP_BUF[i + 1]));
_glKosVertexClipZNear(&dst[v + 2], &dst[v + 3], _glKosNearZClipMag(&CLIP_BUF[i], &CLIP_BUF[i + 2]));
break;
case SECOND:
_glKosVertexCopyPVR(&src[i + 1], &dst[v + 0]);
_glKosVertexCopyPVR(&src[i + 0], &dst[v + 1]);
_glKosVertexCopyPVR(&src[i + 1], &dst[v + 2]);
_glKosVertexCopyPVR(&src[i + 2], &dst[v + 3]);
_glKosVertexClipZNear(&dst[v + 0], &dst[v + 1], _glKosNearZClipMag(&CLIP_BUF[i + 1], &CLIP_BUF[i + 0]));
_glKosVertexClipZNear(&dst[v + 2], &dst[v + 3], _glKosNearZClipMag(&CLIP_BUF[i + 1], &CLIP_BUF[i + 2]));
break;
case THIRD:
_glKosVertexCopyPVR(&src[i + 2], &dst[v + 0]);
_glKosVertexCopyPVR(&src[i + 0], &dst[v + 1]);
_glKosVertexCopyPVR(&src[i + 2], &dst[v + 2]);
_glKosVertexCopyPVR(&src[i + 1], &dst[v + 3]);
_glKosVertexClipZNear(&dst[v + 0], &dst[v + 1], _glKosNearZClipMag(&CLIP_BUF[i + 2], &CLIP_BUF[i]));
_glKosVertexClipZNear(&dst[v + 2], &dst[v + 3], _glKosNearZClipMag(&CLIP_BUF[i + 2], &CLIP_BUF[i + 1]));
break;
}
dst[v + 0].flags = dst[v + 1].flags = dst[v + 2].flags = PVR_CMD_VERTEX;
dst[v + 3].flags = PVR_CMD_VERTEX_EOL;
v += 4;
break;
}
C++;
}
return v;
}
static inline unsigned char _glKosClipTri(pvr_vertex_t *src, pvr_vertex_t *dst) {
GLushort clip = 0; /* Clip Code for current Triangle */
GLubyte verts_in = 0; /* # of Vertices inside clip plane for current Triangle */
float3 clip_buf[3]; /* Store the Vertices for each Triangle Translated into Clip Space */
/* Transform all 3 Vertices of Triangle */
{
register float __x __asm__("fr12") = src->x;
register float __y __asm__("fr13") = src->y;
register float __z __asm__("fr14") = src->z;
mat_trans_fv12_nodiv();
clip_buf[0].x = __x;
clip_buf[0].y = __y;
clip_buf[0].z = __z;
__x = (src + 1)->x;
__y = (src + 1)->y;
__z = (src + 1)->z;
mat_trans_fv12_nodiv();
clip_buf[1].x = __x;
clip_buf[1].y = __y;
clip_buf[1].z = __z;
__x = (src + 2)->x;
__y = (src + 2)->y;
__z = (src + 2)->z;
mat_trans_fv12_nodiv();
clip_buf[2].x = __x;
clip_buf[2].y = __y;
clip_buf[2].z = __z;
/* Compute Clip Code for Triangle */
(clip_buf[0].z >= CLIP_NEARZ) ? clip |= FIRST : ++verts_in;
(clip_buf[1].z >= CLIP_NEARZ) ? clip |= SECOND : ++verts_in;
(clip_buf[2].z >= CLIP_NEARZ) ? clip |= THIRD : ++verts_in;
}
switch(verts_in) { /* Start by examining # of vertices inside clip plane */
case 0: /* All Vertices of Triangle are Outside of clip plne */
return 0;
case 3: /* All Vertices of Triangle are inside of clip plne */
memcpy(dst, src, 96);
dst->flags = (dst + 1)->flags = PVR_CMD_VERTEX;
(dst + 2)->flags = PVR_CMD_VERTEX_EOL;
return 3;
case 1:/* 1 Vertex of Triangle is inside of clip plane = output 1 Triangle */
memcpy(dst, src, 96);
switch(clip) {
case FIRST_TWO_OUT:
_glKosVertexClipZNear(dst, dst + 2, _glKosNearZClipMag(&clip_buf[0], &clip_buf[2]));
_glKosVertexClipZNear(dst + 1, dst + 2, _glKosNearZClipMag(&clip_buf[1], &clip_buf[2]));
break;
case FIRST_AND_LAST_OUT:
_glKosVertexClipZNear(dst, dst + 1, _glKosNearZClipMag(&clip_buf[0], &clip_buf[1]));
_glKosVertexClipZNear(dst + 2, dst + 1, _glKosNearZClipMag(&clip_buf[2], &clip_buf[1]));
break;
case LAST_TWO_OUT:
_glKosVertexClipZNear(dst + 1, dst, _glKosNearZClipMag(&clip_buf[1], &clip_buf[0]));
_glKosVertexClipZNear(dst + 2, dst, _glKosNearZClipMag(&clip_buf[2], &clip_buf[0]));
break;
}
dst->flags = (dst + 1)->flags = PVR_CMD_VERTEX;
(dst + 2)->flags = PVR_CMD_VERTEX_EOL;
return 3;
case 2:/* 2 Vertices of Triangle are inside of clip plane = output 2 Triangles */
switch(clip) {
case FIRST:
memcpy(dst, src, 64);
_glKosVertexCopyPVR(src, dst + 2);
_glKosVertexCopyPVR(src + 2, dst + 3);
_glKosVertexClipZNear(dst, dst + 1, _glKosNearZClipMag(&clip_buf[0], &clip_buf[1]));
_glKosVertexClipZNear(dst + 2, dst + 3, _glKosNearZClipMag(&clip_buf[0], &clip_buf[2]));
break;
case SECOND:
_glKosVertexCopyPVR(src + 1, dst);
_glKosVertexCopyPVR(src, dst + 1);
memcpy(dst + 2, src + 1, 64);
_glKosVertexClipZNear(dst, dst + 1, _glKosNearZClipMag(&clip_buf[1], &clip_buf[0]));
_glKosVertexClipZNear(dst + 2, dst + 3, _glKosNearZClipMag(&clip_buf[1], &clip_buf[2]));
break;
case THIRD:
_glKosVertexCopyPVR(src + 2, dst);
_glKosVertexCopyPVR(src, dst + 1);
_glKosVertexCopyPVR(src + 2, dst + 2);
_glKosVertexCopyPVR(src + 1, dst + 3);
_glKosVertexClipZNear(dst, dst + 1, _glKosNearZClipMag(&clip_buf[2], &clip_buf[0]));
_glKosVertexClipZNear(dst + 2, dst + 3, _glKosNearZClipMag(&clip_buf[2], &clip_buf[1]));
break;
}
dst->flags = (dst + 1)->flags = (dst + 2)->flags = PVR_CMD_VERTEX;
(dst + 3)->flags = PVR_CMD_VERTEX_EOL;
return 4;
}
return 0;
}
GLuint _glKosClipTriangles(pvr_vertex_t *src, pvr_vertex_t *dst, GLuint vertices) {
GLuint i, v = 0;
for(i = 0; i < vertices; i += 3) /* Iterate all Triangles */
v += _glKosClipTri(src + i, dst + v);
return v;
}
GLuint _glKosClipQuads(pvr_vertex_t *src, pvr_vertex_t *dst, GLuint vertices) {
GLuint i, v = 0;
pvr_vertex_t qv;
for(i = 0; i < vertices; i += 4) { /* Iterate all Quads, Rearranging into Triangle Strips */
_glKosVertexCopyPVR(src + i + 3, &qv);
_glKosVertexCopyPVR(src + i + 2, src + i + 3);
_glKosVertexCopyPVR(&qv, src + i + 2);
v += _glKosClipTriangleStrip(src + i, dst + v, 4);
}
return v;
}

View File

@ -1,52 +0,0 @@
/* KallistiGL for KallistiOS ##version##
libgl/gl-clip.h
Copyright (C) 2013-2014 Josh Pearson
Near-Z Clipping Algorithm (C) 2013-2014 Josh PH3NOM Pearson
Input Primitive Types Supported:
-GL_TRIANGLES
-GL_TRIANGLE_STRIPS
-GL_QUADS
Outputs a mix of Triangles and Triangle Strips for use with the PVR
*/
#ifndef GL_CLIP_H
#define GL_CLIP_H
#include "gl.h"
#include "gl-sh4.h"
#define NONE 0x0000 /* Clip Codes */
#define FIRST 0x0001
#define SECOND 0x0010
#define THIRD 0x0100
#define ALL 0x0111
#define FIRST_TWO_OUT 0x0011
#define FIRST_AND_LAST_OUT 0x0101
#define LAST_TWO_OUT 0x0110
#define ALPHA 0xFF000000 /* Color Components using PVR's Packed 32bit int */
#define RED 0x00FF0000
#define GREEN 0x0000FF00
#define BLUE 0x000000FF
#define CLIP_NEARZ -0.20f /* Clip Threshold */
typedef struct {
float x, y, z;
} float3;
typedef struct {
unsigned char b, g, r, a;
} colorui;
static inline void _glKosVertexCopy3f(float3 *src, float3 *dst) {
*dst = *src;
}
static inline GLfloat _glKosNearZClipMag(float3 *v1, float3 *v2) {
return ((CLIP_NEARZ - v1->z) / (v2->z - v1->z));
}
#endif

View File

@ -1,95 +0,0 @@
/* KallistiGL for KallistiOS ##version##
libgl/gl-fog.c
Copyright (C) 2013-2014 Josh Pearson
Functionality adapted from the original KOS libgl fog code:
Copyright (C) 2002 Benoit Miller
OpenGL Fog - Wrapper for the PowerVR fog functions in KOS.
*/
#include "gl.h"
static GLuint GL_KOS_FOG_MODE = GL_EXP; /* GL_LINEAR, GL_EXP, or GL_EXP2 FOG */
static GLfloat GL_KOS_FOG_DENSITY = 1.0f, /* Density - GL_EXP, or GL_EXP2 FOG */
GL_KOS_FOG_START = 0.0f, /* Linear FOG */
GL_KOS_FOG_END = 1.0f; /* Linear FOG */
void APIENTRY glFogi(GLenum pname, GLint param) {
switch(pname) {
case GL_FOG_MODE:
switch(param) {
case GL_LINEAR:
pvr_fog_table_linear(GL_KOS_FOG_START, GL_KOS_FOG_END);
break;
case GL_EXP:
pvr_fog_table_exp(GL_KOS_FOG_DENSITY);
break;
case GL_EXP2:
pvr_fog_table_exp2(GL_KOS_FOG_DENSITY);
break;
}
}
}
void APIENTRY glFogf(GLenum pname, GLfloat param) {
switch(pname) {
case GL_FOG_START:
GL_KOS_FOG_START = param;
if(GL_KOS_FOG_MODE == GL_LINEAR)
pvr_fog_table_linear(GL_KOS_FOG_START, GL_KOS_FOG_END);
break;
case GL_FOG_END:
GL_KOS_FOG_END = param;
if(GL_KOS_FOG_MODE == GL_LINEAR)
pvr_fog_table_linear(GL_KOS_FOG_START, GL_KOS_FOG_END);
break;
case GL_FOG_DENSITY:
GL_KOS_FOG_DENSITY = param;
if(GL_KOS_FOG_MODE == GL_EXP)
pvr_fog_table_exp(GL_KOS_FOG_DENSITY);
else if(GL_KOS_FOG_MODE == GL_EXP2)
pvr_fog_table_exp2(GL_KOS_FOG_DENSITY);
break;
}
}
void APIENTRY glFogfv(GLenum pname, const GLfloat *params) {
switch(pname) {
case GL_FOG_MODE:
glFogi(pname, (GLint) * params);
break;
case GL_FOG_DENSITY:
GL_KOS_FOG_DENSITY = *params;
if(GL_KOS_FOG_MODE == GL_EXP)
pvr_fog_table_exp(GL_KOS_FOG_DENSITY);
else if(GL_KOS_FOG_MODE == GL_EXP2)
pvr_fog_table_exp2(GL_KOS_FOG_DENSITY);
break;
case GL_FOG_START:
case GL_FOG_END:
glFogf(pname, *params);
break;
case GL_FOG_COLOR:
pvr_fog_table_color(params[3], params[0], params[1], params[2]);
break;
}
}

View File

@ -1,181 +0,0 @@
/* KallistiGL for KallistiOS ##version##
libgl/gl-framebuffer.c
Copyright (C) 2014 Josh Pearson
This file implements Open GL Frame Buffer Object (FBO) functionality, with what
the DC's PVR can directly implement.
Basically, Render-To-Texture using GL_RGB565 is the only native feature of the
PVR, so if you are looking for a depth-buffer, bad news.
This implementation uses a dynamic linked list to implement the data structures needed.
*/
#include "gl.h"
#include "glext.h"
#include "gl-api.h"
#include <malloc.h>
//========================================================================================//
//== Internal KOS Open GL API FBO Structures / Global Variables ==//
static GL_FRAMEBUFFER_OBJECT *FRAMEBUF_OBJ = NULL;
static GLsizei FRAMEBUF_OBJECT = 0;
//========================================================================================//
//== Internal KOS Open GL API FBO Functionality ==//
void _glKosInitFrameBuffers() {
FRAMEBUF_OBJ = malloc(sizeof(GL_FRAMEBUFFER_OBJECT));
FRAMEBUF_OBJ->index = 0;
FRAMEBUF_OBJ->texID = 0;
FRAMEBUF_OBJ->data = NULL;
FRAMEBUF_OBJ->link = NULL;
}
static void _glKosInsertFramebufferObj(GL_FRAMEBUFFER_OBJECT *obj) {
GL_FRAMEBUFFER_OBJECT *ptr = FRAMEBUF_OBJ;
while(ptr->link != NULL)
ptr = (GL_FRAMEBUFFER_OBJECT *)ptr->link;
ptr->link = obj;
}
static GLsizei _glKosGetLastFrameBufferIndex() {
GL_FRAMEBUFFER_OBJECT *ptr = FRAMEBUF_OBJ;
while(ptr->link != NULL)
ptr = (GL_FRAMEBUFFER_OBJECT *)ptr->link;
return ptr->index;
}
static GL_FRAMEBUFFER_OBJECT *_glKosGetFrameBufferObj(GLuint index) {
GL_FRAMEBUFFER_OBJECT *ptr = FRAMEBUF_OBJ;
while(ptr->index != index && ptr->link != NULL)
ptr = (GL_FRAMEBUFFER_OBJECT *)ptr->link;
return ptr;
}
GLsizei _glKosGetFBO() {
return FRAMEBUF_OBJECT;
}
GLuint _glKosGetFBOWidth(GLsizei fbi) {
GL_FRAMEBUFFER_OBJECT *fbo = _glKosGetFrameBufferObj(fbi);
return _glKosTextureWidth(fbo->texID);
}
GLuint _glKosGetFBOHeight(GLsizei fbi) {
GL_FRAMEBUFFER_OBJECT *fbo = _glKosGetFrameBufferObj(fbi);
return _glKosTextureHeight(fbo->texID);
}
GLvoid *_glKosGetFBOData(GLsizei fbi) {
GL_FRAMEBUFFER_OBJECT *fbo = _glKosGetFrameBufferObj(fbi);
return fbo->data;
}
//========================================================================================//
//== Public KOS Open GL API FBO Functionality ==//
GLAPI void APIENTRY glGenFramebuffers(GLsizei n, GLuint *framebuffers) {
GLsizei index = _glKosGetLastFrameBufferIndex();
while(n--) {
GL_FRAMEBUFFER_OBJECT *obj = malloc(sizeof(GL_FRAMEBUFFER_OBJECT));
obj->index = ++index;
obj->texID = 0;
obj->data = NULL;
obj->link = NULL;
_glKosInsertFramebufferObj(obj);
*framebuffers++ = obj->index;
}
}
GLAPI void APIENTRY glDeleteFramebuffers(GLsizei n, GLuint *framebuffers) {
while(n--) {
GL_FRAMEBUFFER_OBJECT *ptr = FRAMEBUF_OBJ->link, * lptr = FRAMEBUF_OBJ;
while(ptr != NULL) {
if(ptr->index == *framebuffers) {
GL_FRAMEBUFFER_OBJECT *cur_node = ptr;
lptr->link = ptr->link;
ptr = (GL_FRAMEBUFFER_OBJECT *)ptr->link;
free(cur_node);
if(*framebuffers == FRAMEBUF_OBJECT)
FRAMEBUF_OBJECT = 0;
break;
}
else
ptr = (GL_FRAMEBUFFER_OBJECT *)ptr->link;
}
++framebuffers;
}
}
GLAPI void APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer) {
if(target != GL_FRAMEBUFFER) {
_glKosThrowError(GL_INVALID_ENUM, "glBindFramebuffer");
_glKosPrintError();
return;
}
FRAMEBUF_OBJECT = framebuffer;
}
GLAPI void APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level) {
if(target != GL_FRAMEBUFFER)
_glKosThrowError(GL_INVALID_ENUM, "glFramebufferTexture2D");
if(attachment != GL_COLOR_ATTACHMENT0)
_glKosThrowError(GL_INVALID_OPERATION, "glFramebufferTexture2D");
if(textarget != GL_TEXTURE_2D)
_glKosThrowError(GL_INVALID_OPERATION, "glFramebufferTexture2D");
if(level)
_glKosThrowError(GL_INVALID_ENUM, "glFramebufferTexture2D");
if(!FRAMEBUF_OBJECT)
_glKosThrowError(GL_INVALID_OPERATION, "glFramebufferTexture2D");
if(_glKosHasError()) {
_glKosPrintError();
return;
}
GL_FRAMEBUFFER_OBJECT *fbo = _glKosGetFrameBufferObj(FRAMEBUF_OBJECT);
fbo->texID = texture;
fbo->data = _glKosTextureData(texture);
}
GLAPI GLenum APIENTRY glCheckFramebufferStatus(GLenum target) {
if(target != GL_FRAMEBUFFER) {
_glKosThrowError(GL_INVALID_ENUM, "glCheckFramebufferStatus");
_glKosPrintError();
return 0;
}
if(!FRAMEBUF_OBJECT)
return GL_FRAMEBUFFER_COMPLETE;
GL_FRAMEBUFFER_OBJECT *fbo = _glKosGetFrameBufferObj(FRAMEBUF_OBJECT);
if(!fbo->texID)
return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
return GL_FRAMEBUFFER_COMPLETE;
}

View File

@ -1,364 +0,0 @@
/* KallistiGL for KallistiOS ##version##
libgl/gl-light.c
Copyright (C) 2013-2014 Josh Pearson
Dynamic Vertex Lighting Model:
vertexColor = emissive + ambient + ( diffuse + specular * attenuation )
The only difference here from real OpenGL is that only 1 ambient light
source is used, as opposed to each light containing its own abmient value.
Abmient light is set by the glKosLightAbmient..(..) functions below.
By default, the specular lighting term is enabled.
For now, specular can be disabled by setting GL_ENABLE_SPECULAR on
gl-light.h when you build the library.
*/
#include <math.h>
#include <stdio.h>
#include <string.h>
#include "gl.h"
#include "gl-api.h"
#include "gl-clip.h"
#include "gl-light.h"
#define GL_KOS_MAX_LIGHTS 16 /* Number of Light Sources that may be enabled at once */
static GLfloat GL_GLOBAL_AMBIENT[4] = { 0, 0, 0, 0 }; /* RGBA Global Ambient Light */
static GLfloat GL_VERTEX_NORMAL[3] = { 0, 0, 0 }; /* Current Vertex Normal */
static GLbitfield GL_LIGHT_ENABLED = 0; /* Client State for Enabling Lighting */
static glLight GL_LIGHTS[GL_KOS_MAX_LIGHTS],
GL_DEFAULT_LIGHT = { { 0.0, 0.0, 1.0, 0.0 }, /* Position */
{ 0.0, 0.0, -1.0 }, /* Spot Direction */
-1.0f, /* Spot Cutoff */
1.0f, 0.0f, 0.0f, /* Attenuation Factors */
0.0f, /* Spot Exponent */
{ 1.0, 1.0, 1.0, 1.0 }, /* Diffuse */
{ 1.0, 1.0, 1.0, 1.0 }, /* Specular */
{ 0.0, 0.0, 0.0, 1.0 } /* Ambient */
};
static glMaterial GL_MATERIAL,
GL_DEFAULT_MATERIAL = { { 0.0, 0.0, 0.0, 1.0 }, /* Emissive Color */
{ 0.2, 0.2, 0.2, 1.0 }, /* Ambient Reflectance */
{ 0.8, 0.8, 0.8, 1.0 }, /* Diffuse Reflectance */
{ 0.0, 0.0, 0.0, 1.0 }, /* Specular Reflectance */
0.0 /* Shininess */
};
static GLfloat GL_EYE_POSITION[3] = { 0, 0, 0 }; /* Eye Position for Specular Factor */
void _glKosSetEyePosition(GLfloat *position) { /* Called internally by glhLookAtf() */
GL_EYE_POSITION[0] = position[0];
GL_EYE_POSITION[1] = position[1];
GL_EYE_POSITION[2] = position[2];
}
void _glKosInitLighting() { /* Called internally by glInit() */
unsigned char i;
for(i = 0; i < GL_KOS_MAX_LIGHTS; i++)
memcpy(&GL_LIGHTS[i], &GL_DEFAULT_LIGHT, sizeof(glLight));
memcpy(&GL_MATERIAL, &GL_DEFAULT_MATERIAL, sizeof(glMaterial));
}
/* Enable a light - GL_LIGHT0->GL_LIGHT7 */
void _glKosEnableLight(const GLuint light) {
if(light < GL_LIGHT0 || light > GL_LIGHT0 + GL_KOS_MAX_LIGHTS) {
_glKosThrowError(GL_INVALID_ENUM, "glEnable(GL_LIGHT)");
return;
}
GL_LIGHT_ENABLED |= (1 << (light & 0xF));
}
/* Disable a light - GL_LIGHT0->GL_LIGHT0 + GL_KOS_MAX_LIGHTS */
void _glKosDisableLight(const GLuint light) {
if(light < GL_LIGHT0 || light > GL_LIGHT0 + GL_KOS_MAX_LIGHTS) {
_glKosThrowError(GL_INVALID_ENUM, "glDisable(GL_LIGHT)");
return;
}
GL_LIGHT_ENABLED &= ~(1 << (light & 0xF));
}
GLubyte _glKosIsLightEnabled(GLubyte light) {
return GL_LIGHT_ENABLED & (1 << light);
}
GLubyte _glKosGetMaxLights() {
return GL_KOS_MAX_LIGHTS;
}
/* Misc Lighting Functions ************************************/
static inline void glCopyRGBA(const rgba *src, rgba *dst) {
*dst = *src;
}
static inline void glCopy4f(const float *src, float *dst) {
memcpy(dst, src, 0x10);
}
static inline void glCopy3f(const float *src, float *dst) {
memcpy(dst, src, 0xC);
}
/* Vertex Lighting **********************************************************/
/* Fast POW Implementation - Less accurate, but much faster than math.h */
#define EXP_A 184
#define EXP_C 16249
float FEXP(float y) {
union {
float d;
struct {
short j, i;
} n;
} eco;
eco.n.i = EXP_A * (y) + (EXP_C);
eco.n.j = 0;
return eco.d;
}
float FLOG(float y) {
int *nTemp = (int *)&y;
y = (*nTemp) >> 16;
return (y - EXP_C) / EXP_A;
}
float FPOW(float b, float p) {
return FEXP(FLOG(b) * p);
}
/* End FPOW Implementation */
void _glKosVertex3flv(const GLfloat *xyz) {
glVertex *v = _glKosArrayBufPtr();
v->pos[0] = xyz[0];
v->pos[1] = xyz[1];
v->pos[2] = xyz[2];
v->norm[0] = GL_VERTEX_NORMAL[0];
v->norm[1] = GL_VERTEX_NORMAL[1];
v->norm[2] = GL_VERTEX_NORMAL[2];
_glKosArrayBufIncrement();
_glKosVertex3fsv(xyz);
}
void _glKosVertex3fl(GLfloat x, GLfloat y, GLfloat z) {
glVertex *v = _glKosArrayBufPtr();
v->pos[0] = x;
v->pos[1] = y;
v->pos[2] = z;
v->norm[0] = GL_VERTEX_NORMAL[0];
v->norm[1] = GL_VERTEX_NORMAL[1];
v->norm[2] = GL_VERTEX_NORMAL[2];
_glKosArrayBufIncrement();
_glKosVertex3fs(x, y, z);
}
void _glKosVertex3flcv(const GLfloat *xyz) {
glVertex *v = _glKosArrayBufPtr();
v->pos[0] = xyz[0];
v->pos[1] = xyz[1];
v->pos[2] = xyz[2];
v->norm[0] = GL_VERTEX_NORMAL[0];
v->norm[1] = GL_VERTEX_NORMAL[1];
v->norm[2] = GL_VERTEX_NORMAL[2];
_glKosArrayBufIncrement();
_glKosVertex3fcv(xyz);
}
void _glKosVertex3flc(GLfloat x, GLfloat y, GLfloat z) {
glVertex *v = _glKosArrayBufPtr();
v->pos[0] = x;
v->pos[1] = y;
v->pos[2] = z;
v->norm[0] = GL_VERTEX_NORMAL[0];
v->norm[1] = GL_VERTEX_NORMAL[1];
v->norm[2] = GL_VERTEX_NORMAL[2];
_glKosArrayBufIncrement();
_glKosVertex3fc(x, y, z);
}
/**** Compute Vertex Light Color ***/
void _glKosVertexLights(glVertex *P, pvr_vertex_t *v, GLuint count) {
#ifdef GL_ENABLE_SPECULAR
float S;
#endif
unsigned char i;
float L[4] __attribute__((aligned(8)));
float C[3] = { 0, 0, 0 };
colorui *color = (colorui *)&v->argb;
/* Compute Global Ambient */
float A[3] = { GL_MATERIAL.Ke[0] + GL_MATERIAL.Ka[0] *GL_GLOBAL_AMBIENT[0],
GL_MATERIAL.Ke[1] + GL_MATERIAL.Ka[1] *GL_GLOBAL_AMBIENT[1],
GL_MATERIAL.Ke[2] + GL_MATERIAL.Ka[2] *GL_GLOBAL_AMBIENT[2]
};
while(count--) {
for(i = 0; i < GL_KOS_MAX_LIGHTS; i++)
if(GL_LIGHT_ENABLED & 1 << i)
if(_glKosSpotlight(&GL_LIGHTS[i], P, L)) { /* Compute Spot / Diffuse */
C[0] = A[0] + (GL_MATERIAL.Kd[0] * GL_LIGHTS[i].Kd[0] * L[3]);
C[1] = A[1] + (GL_MATERIAL.Kd[1] * GL_LIGHTS[i].Kd[1] * L[3]);
C[2] = A[2] + (GL_MATERIAL.Kd[2] * GL_LIGHTS[i].Kd[2] * L[3]);
#ifdef GL_ENABLE_SPECULAR
S = _glKosSpecular(P, GL_EYE_POSITION, L); /* Compute Specular */
if(S > 0) {
#ifdef GL_ENABLE_FAST_POW
S = FPOW(S, GL_MATERIAL.Shine);
#else
S = pow(S, GL_MATERIAL.Shine);
#endif
C[0] += (GL_MATERIAL.Ks[0] * GL_LIGHTS[i].Ks[0] * S);
C[1] += (GL_MATERIAL.Ks[1] * GL_LIGHTS[i].Ks[1] * S);
C[2] += (GL_MATERIAL.Ks[2] * GL_LIGHTS[i].Ks[2] * S);
}
#endif
}
color->a = 0xFF; /* Clamp / Pack Floating Point Colors to 32bit int */
(C[0] > 1.0f) ? (color->r = 0xFF) : (color->r = (unsigned char)(255 * C[0]));
(C[1] > 1.0f) ? (color->g = 0xFF) : (color->g = (unsigned char)(255 * C[1]));
(C[2] > 1.0f) ? (color->b = 0xFF) : (color->b = (unsigned char)(255 * C[2]));
color += 8; /* pvr_vertex_t color stride */
++P;
}
}
void _glKosVertexLight(glVertex *P, pvr_vertex_t *v) {
#ifdef GL_ENABLE_SPECULAR
float S;
#endif
unsigned char i;
float L[4] __attribute__((aligned(8)));
/* Compute Ambient */
float C[3] = { GL_MATERIAL.Ke[0] + GL_MATERIAL.Ka[0] *GL_GLOBAL_AMBIENT[0],
GL_MATERIAL.Ke[1] + GL_MATERIAL.Ka[1] *GL_GLOBAL_AMBIENT[1],
GL_MATERIAL.Ke[2] + GL_MATERIAL.Ka[2] *GL_GLOBAL_AMBIENT[2]
};
for(i = 0; i < GL_KOS_MAX_LIGHTS; i++)
if(GL_LIGHT_ENABLED & 1 << i)
if(_glKosSpotlight(&GL_LIGHTS[i], P, L)) { /* Compute Spot / Diffuse */
C[0] += (GL_MATERIAL.Kd[0] * GL_LIGHTS[i].Kd[0] * L[3]);
C[1] += (GL_MATERIAL.Kd[1] * GL_LIGHTS[i].Kd[1] * L[3]);
C[2] += (GL_MATERIAL.Kd[2] * GL_LIGHTS[i].Kd[2] * L[3]);
#ifdef GL_ENABLE_SPECULAR
S = _glKosSpecular(P, GL_EYE_POSITION, L); /* Compute Specular */
if(S > 0) {
#ifdef GL_ENABLE_FAST_POW
S = FPOW(S, GL_MATERIAL.Shine);
#else
S = pow(S, GL_MATERIAL.Shine);
#endif
C[0] += (GL_MATERIAL.Ks[0] * GL_LIGHTS[i].Ks[0] * S);
C[1] += (GL_MATERIAL.Ks[1] * GL_LIGHTS[i].Ks[1] * S);
C[2] += (GL_MATERIAL.Ks[2] * GL_LIGHTS[i].Ks[2] * S);
}
#endif
}
colorui *col = (colorui *)&v->argb; /* Clamp / Pack floats to a 32bit int */
col->a = 0xFF;
(C[0] > 1.0f) ? (col->r = 0xFF) : (col->r = (unsigned char)(255 * C[0]));
(C[1] > 1.0f) ? (col->g = 0xFF) : (col->g = (unsigned char)(255 * C[1]));
(C[2] > 1.0f) ? (col->b = 0xFF) : (col->b = (unsigned char)(255 * C[2]));
}
GLuint _glKosVertexLightColor(glVertex *P) {
#ifdef GL_ENABLE_SPECULAR
float S;
#endif
GLuint color;
GLubyte i;
float L[4] __attribute__((aligned(8)));
/* Compute Ambient */
float C[3] = { GL_MATERIAL.Ke[0] + GL_MATERIAL.Ka[0] *GL_GLOBAL_AMBIENT[0],
GL_MATERIAL.Ke[1] + GL_MATERIAL.Ka[1] *GL_GLOBAL_AMBIENT[1],
GL_MATERIAL.Ke[2] + GL_MATERIAL.Ka[2] *GL_GLOBAL_AMBIENT[2]
};
for(i = 0; i < GL_KOS_MAX_LIGHTS; i++)
if(GL_LIGHT_ENABLED & 1 << i)
if(_glKosSpotlight(&GL_LIGHTS[i], P, L)) { /* Compute Spot / Diffuse */
C[0] += (GL_MATERIAL.Kd[0] * GL_LIGHTS[i].Kd[0] * L[3]);
C[1] += (GL_MATERIAL.Kd[1] * GL_LIGHTS[i].Kd[1] * L[3]);
C[2] += (GL_MATERIAL.Kd[2] * GL_LIGHTS[i].Kd[2] * L[3]);
#ifdef GL_ENABLE_SPECULAR
S = _glKosSpecular(P, GL_EYE_POSITION, L); /* Compute Specular */
if(S > 0) {
#ifdef GL_ENABLE_FAST_POW
S = FPOW(S, GL_MATERIAL.Shine);
#else
S = pow(S, GL_MATERIAL.Shine);
#endif
C[0] += (GL_MATERIAL.Ks[0] * GL_LIGHTS[i].Ks[0] * S);
C[1] += (GL_MATERIAL.Ks[1] * GL_LIGHTS[i].Ks[1] * S);
C[2] += (GL_MATERIAL.Ks[2] * GL_LIGHTS[i].Ks[2] * S);
}
#endif
}
colorui *col = (colorui *)&color; /* Clamp / Pack floats to a 32bit int */
col->a = 0xFF;
(C[0] > 1.0f) ? (col->r = 0xFF) : (col->r = (unsigned char)(255 * C[0]));
(C[1] > 1.0f) ? (col->g = 0xFF) : (col->g = (unsigned char)(255 * C[1]));
(C[2] > 1.0f) ? (col->b = 0xFF) : (col->b = (unsigned char)(255 * C[2]));
return color;
}
/** Iterate vertices submitted and compute vertex lighting **/
void _glKosVertexComputeLighting(pvr_vertex_t *v, int verts) {
unsigned int i;
glVertex *s = _glKosArrayBufAddr();
_glKosMatrixLoadModelView();
for(i = 0; i < verts; i++) {
mat_trans_single3_nodiv(s->pos[0], s->pos[1], s->pos[2]);
++s;
}
s = _glKosArrayBufAddr();
_glKosMatrixLoadModelRot();
for(i = 0; i < verts; i++) {
mat_trans_normal3(s->norm[0], s->norm[1], s->norm[2]);
_glKosVertexLight(s++, v++);
}
}

View File

@ -1,51 +0,0 @@
/* KallistiGL for KallistiOS ##version##
libgl/gl-light.h
Copyright (C) 2013-2014 Josh Pearson
Dynamic Vertex Lighting.
By default, specular lighting is enabled.
For now, specular can be disabled by setting GL_ENABLE_SPECULAR
below when you build the library.
By default, specular lighting uses a fast POW implementation, at
sacrifice of accuracy. Change GL_ENABLE_FAST_POW to suit your needs.
*/
#ifndef GL_LIGHT_H
#define GL_LIGHT_H
#include "gl-sh4.h"
#define GL_ENABLE_SPECULAR 1
#define GL_ENABLE_FAST_POW 1
int _glKosSpotlight(void *glLight, void *vertex6f, void *Lvectorout);
float _glKosSpecular(void *vertex6f, void *eyepos, void *Lvectorin);
typedef struct {
float r, g, b, a;
} rgba;
typedef struct {
float Ke[4]; /* RGBA material emissive color # 0.0, 0.0, 0.0, 1.0 */
float Ka[4]; /* RGBA material ambient reflectance # 0.2, 0.2, 0.2, 1.0 */
float Kd[4]; /* RGBA material diffuse reflectance # 0.8, 0.8, 0.8, 1.0 */
float Ks[4]; /* RGBA material diffuse reflectance # 0.0, 0.0, 0.0, 1.0 */
float Shine; /* Material Specular Shine # 0.0f */
} glMaterial;
typedef struct {
float Pos[4]; /* XYZW Position of Light # 0.0, 0.0, 1.0, 0.0 */
float Dir[3]; /* Spot Light Direction # 0.0, 0.0, -1.0 */
float CutOff; /* Spot Light CutOff #-1.0f */
float Kc, /* Constant Attenuation # 1.0f */
Kl, /* Linear Attenuation # 0.0f */
Kq; /* Quadratic Attenuation # 0.0f */
float Exponent; /* Spot Light Exponent # 0.0f */
float Kd[4]; /* RGBA Diffuse Light Contribution # 1.0, 1.0, 1.0, 1.0 */
float Ks[4]; /* RGBA Specular Light Contribution # 1.0, 1.0, 1.0, 1.0 */
float Ka[4]; /* RGBA Ambient Light Contribution # 0.0, 0.0, 0.0, 1.0 */
} glLight;
#endif

178
gl-pvr.c
View File

@ -1,178 +0,0 @@
/* KallistiGL for KallistiOS ##version##
libgl/gl-pvr.c
Copyright (C) 2013-2014 Josh Pearson
Copyright (C) 2016 Lawrence Sebald
Vertex Buffer Routines for interfacing the Dreamcast's SH4 CPU and PowerVR GPU.
What we are doing here is using a Vertex Buffer in main RAM to store the
submitted data, untill the user finishes the scene by either calling
glSwapBuffer() to submit the buffer to the PVR for render to the screen OR
glSwapBufferToTexture() to submit the buffer to the PVR for render to texture.
This solution means the client can switch between transparent and opaque polygon
sumbission at any time, in no particular order, with no penalty in speed.
The size of the Vertex Buffer can be controlled by setting some params on gl-pvr.h:
GL_PVR_VERTEX_BUF_SIZE controls size of Vertex Buffer in the PVR VRAM
GL_KOS_MAX_VERTS conrols the number of vertices per list in the Vertex Buffer in SH4 RAM
*/
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dc/sq.h>
#include "gl.h"
#include "gl-api.h"
#include "gl-sh4.h"
#include "gl-pvr.h"
/* Vertex Buffer Functions *************************************************************************/
#define COMMANDS_PER_ALLOC ((64 * 1024) / 32) /* 64k memory chunks */
static pvr_cmd_t *GL_VBUF[2] __attribute__((aligned(32))); /* Dynamic Vertex Buffer */
static pvr_cmd_t *GL_CBUF; /* Dynamic Clip Buffer */
static glTexCoord *GL_UVBUF; /* Dynamic Multi-Texture UV */
static GLuint GL_VERTS[2] = {0, 0};
static GLuint GL_VERTS_ALLOCATED[2] = {0, 0};
static GLuint GL_CVERTS = 0;
static GLuint GL_UVVERTS = 0;
static GLuint GL_LIST = GL_KOS_LIST_OP;
#define GL_KOS_MAX_MULTITEXTURE_OBJECTS 512
static GLuint GL_MTOBJECTS = 0;
void _glKosResetMultiTexObject() {
GL_MTOBJECTS = 0;
}
void *_glKosMultiUVBufAddress() {
return &GL_UVBUF[0];
}
void *_glKosMultiUVBufPointer() {
return &GL_UVBUF[GL_UVVERTS];
}
void _glKosMultiUVBufIncrement() {
++GL_UVVERTS;
}
void _glKosMultiUVBufAdd(GLuint count) {
GL_UVVERTS += count;
}
void _glKosMultiUVBufReset() {
GL_UVVERTS = 0;
}
void *_glKosClipBufAddress() {
return &GL_CBUF[0];
}
void *_glKosClipBufPointer() {
return &GL_CBUF[GL_CVERTS];
}
void _glKosClipBufIncrement() {
++GL_CVERTS;
}
void _glKosClipBufAdd(GLuint count) {
GL_CVERTS += count;
}
void _glKosClipBufReset() {
GL_CVERTS = 0;
}
void _glKosVertexBufSwitchOP() {
GL_LIST = GL_KOS_LIST_OP;
}
void _glKosVertexBufSwitchTR() {
GL_LIST = GL_KOS_LIST_TR;
}
void *_glKosVertexBufAddress(GLubyte list) {
return &GL_VBUF[list][0];
}
void *_glKosVertexBufPointer() {
return &GL_VBUF[GL_LIST][GL_VERTS[GL_LIST]];
}
static void _glKosVertexBufIncrementList(GLubyte list, GLuint count) {
GL_VERTS[list] += count;
if(GL_VERTS[list] > GL_VERTS_ALLOCATED[list]) {
/* Grow the list buffer. We can't use realloc with memalign so we have to memcpy */
pvr_cmd_t* orig = GL_VBUF[list];
/* Increase the allocated counter */
GL_VERTS_ALLOCATED[list] += COMMANDS_PER_ALLOC;
/* Create a new memory buffer with the new size */
GL_VBUF[list] = memalign(
0x20,
GL_VERTS_ALLOCATED[list] * sizeof(pvr_cmd_t)
);
/* Copy across the original data */
memcpy(GL_VBUF[list], orig, (GL_VERTS[list] - count) * sizeof(pvr_cmd_t));
/* Free previously allocated memory */
free(orig);
}
}
void _glKosVertexBufIncrement() {
_glKosVertexBufIncrementList(GL_LIST, 1);
}
void *_glKosTRVertexBufPointer() {
return &GL_VBUF[GL_KOS_LIST_TR][GL_VERTS[GL_KOS_LIST_TR]];
}
void _glKosTRVertexBufIncrement() {
_glKosVertexBufIncrementList(GL_KOS_LIST_TR, 1);
}
void _glKosVertexBufAdd(GLuint count) {
_glKosVertexBufIncrementList(GL_LIST, count);
}
void _glKosTRVertexBufAdd(GLuint count) {
_glKosVertexBufIncrementList(GL_KOS_LIST_TR, count);
}
void _glKosVertexBufDecrement() {
/* Intentionally don't free data here, we only ever grow */
--GL_VERTS[GL_LIST];
}
void _glKosVertexBufReset() {
GL_VERTS[0] = GL_VERTS[1] = 0;
}
GLuint _glKosVertexBufCount(GLubyte list) {
return GL_VERTS[list];
}
GLubyte _glKosList() {
return GL_LIST;
}
void _glKosVertexBufCopy(void *dst, void *src, GLuint count) {
memcpy(dst, src, count * 0x20);
}

View File

@ -1,44 +0,0 @@
/* KallistiGL for KallistiOS ##version##
libgl/gl-pvr.h
Copyright (C) 2013-2014 Josh Pearson
Vertex Buffer Routines for interfacing the Dreamcast's SH4 CPU and PowerVR GPU.
*/
#ifndef GL_PVR_H
#define GL_PVR_H
/* GL->PVR Commands */
typedef struct {
unsigned int cmd[8];
} pvr_cmd_t; /* Generic 32byte command for the pvr */
#define GL_PVR_VERTEX_BUF_SIZE 2560 * 256 /* PVR Vertex buffer size */
#define GL_KOS_MAX_VERTS 1024*64 /* SH4 Vertex Count */
#define GL_KOS_LIST_OP 0
#define GL_KOS_LIST_TR 1
//#define GL_KOS_USE_DMA 1 /* Use PVR DMA for vertex data transfer instead of store queues */
//#define GL_USE_FLOAT 0 /* Use PVR's floating-point color Vertex Type (64bit) *NoOp* */
/* Misc SH4->PVR Commands */
#define TA_SQ_ADDR (unsigned int *)(void *) \
(0xe0000000 | (((unsigned long)0x10000000) & 0x03ffffe0))
#define QACRTA ((((unsigned int)0x10000000)>>26)<<2)&0x1c
#define PVR_TA_TXR_FILTER_SHIFT 14
#define GL_PVR_FILTER_POINT 0x00
#define GL_PVR_FILTER_BILINEAR 0x01
#define GL_PVR_FILTER_TRILINEAR_A 0x10
#define GL_PVR_FILTER_TRILINEAR_B 0x11
#define PVR_TA_SUPER_SAMPLE_SHIFT 12
#define GL_PVR_SAMPLE_POINT 0x0
#define GL_PVR_SAMPLE_SUPER 0x1
#endif

310
gl-rgb.c
View File

@ -1,310 +0,0 @@
/* KallistiGL for KallistiOS ##version##
libgl/gl-rgb.c
Copyright (C) 2013-2015 Josh Pearson
A set of functions for working with ARGB pixel data, used by gluBuild2DMipmaps(...).
The pixel conversion functions are for submitting textures not supported by the PVR.
*/
#include "gl.h"
#include "gl-rgb.h"
//===================================================================================================//
//== ARGB Bit Masks ==//
static unsigned char ARGB1555_ALPHA(unsigned short c) {
return (c & ARGB1555_ALPHA_MASK) >> ARGB1555_ALPHA_SHIFT;
}
static unsigned char ARGB1555_RED(unsigned short c) {
return (c & ARGB1555_RED_MASK) >> ARGB1555_RED_SHIFT;
}
static unsigned char ARGB1555_GREEN(unsigned short c) {
return (c & ARGB1555_GREEN_MASK) >> ARGB1555_GREEN_SHIFT;
}
static unsigned char ARGB1555_BLUE(unsigned short c) {
return (c & ARGB1555_BLUE_MASK) >> ARGB1555_BLUE_SHIFT;
}
static unsigned char ARGB4444_ALPHA(unsigned short c) {
return (c & ARGB4444_ALPHA_MASK) >> ARGB4444_ALPHA_SHIFT;
}
static unsigned char ARGB4444_RED(unsigned short c) {
return (c & ARGB4444_RED_MASK) >> ARGB4444_RED_SHIFT;
}
static unsigned char ARGB4444_GREEN(unsigned short c) {
return (c & ARGB4444_GREEN_MASK) >> ARGB4444_GREEN_SHIFT;
}
static unsigned char ARGB4444_BLUE(unsigned short c) {
return (c & ARGB4444_BLUE_MASK) >> ARGB4444_BLUE_SHIFT;
}
static unsigned char RGB565_RED(unsigned short c) {
return (c & RGB565_RED_MASK) >> RGB565_RED_SHIFT;
}
static unsigned char RGB565_GREEN(unsigned short c) {
return (c & RGB565_GREEN_MASK) >> RGB565_GREEN_SHIFT;
}
static unsigned char RGB565_BLUE(unsigned short c) {
return c & RGB565_BLUE_MASK;
}
//===================================================================================================//
//== Block Compression ==//
uint16 __glKosAverageQuadPixelRGB565(uint16 p1, uint16 p2, uint16 p3, uint16 p4) {
uint8 R = (RGB565_RED(p1) + RGB565_RED(p2) + RGB565_RED(p3) + RGB565_RED(p4)) / 4;
uint8 G = (RGB565_GREEN(p1) + RGB565_GREEN(p2) + RGB565_GREEN(p3) + RGB565_GREEN(p4)) / 4;
uint8 B = (RGB565_BLUE(p1) + RGB565_BLUE(p2) + RGB565_BLUE(p3) + RGB565_BLUE(p4)) / 4;
return R << RGB565_RED_SHIFT | G << RGB565_GREEN_SHIFT | B;
}
uint16 __glKosAverageQuadPixelARGB1555(uint16 p1, uint16 p2, uint16 p3, uint16 p4) {
uint8 A = (ARGB1555_ALPHA(p1) + ARGB1555_ALPHA(p2) + ARGB1555_ALPHA(p3) + ARGB1555_ALPHA(p4)) / 4;
uint8 R = (ARGB1555_RED(p1) + ARGB1555_RED(p2) + ARGB1555_RED(p3) + ARGB1555_RED(p4)) / 4;
uint8 G = (ARGB1555_GREEN(p1) + ARGB1555_GREEN(p2) + ARGB1555_GREEN(p3) + ARGB1555_GREEN(p4)) / 4;
uint8 B = (ARGB1555_BLUE(p1) + ARGB1555_BLUE(p2) + ARGB1555_BLUE(p3) + ARGB1555_BLUE(p4)) / 4;
return ((A & RGB1_MAX) << ARGB1555_ALPHA_SHIFT) | ((R & RGB5_MAX) << ARGB1555_RED_SHIFT)
| ((G & RGB5_MAX) << ARGB1555_GREEN_SHIFT) | (B & RGB5_MAX);
}
uint16 __glKosAverageQuadPixelARGB4444(uint16 p1, uint16 p2, uint16 p3, uint16 p4) {
uint8 A = (ARGB4444_ALPHA(p1) + ARGB4444_ALPHA(p2) + ARGB4444_ALPHA(p3) + ARGB4444_ALPHA(p4)) / 4;
uint8 R = (ARGB4444_RED(p1) + ARGB4444_RED(p2) + ARGB4444_RED(p3) + ARGB4444_RED(p4)) / 4;
uint8 G = (ARGB4444_GREEN(p1) + ARGB4444_GREEN(p2) + ARGB4444_GREEN(p3) + ARGB4444_GREEN(p4)) / 4;
uint8 B = (ARGB4444_BLUE(p1) + ARGB4444_BLUE(p2) + ARGB4444_BLUE(p3) + ARGB4444_BLUE(p4)) / 4;
return ((A & RGB4_MAX) << ARGB4444_ALPHA_SHIFT) | ((R & RGB4_MAX) << ARGB4444_RED_SHIFT)
| ((G & RGB4_MAX) << ARGB4444_GREEN_SHIFT) | (B & RGB4_MAX);
}
uint16 __glKosAverageBiPixelRGB565(uint16 p1, uint16 p2) {
uint8 R = (RGB565_RED(p1) + RGB565_RED(p2)) / 2;
uint8 G = (RGB565_GREEN(p1) + RGB565_GREEN(p2)) / 2;
uint8 B = (RGB565_BLUE(p1) + RGB565_BLUE(p2)) / 2;
return R << RGB565_RED_SHIFT | G << RGB565_GREEN_SHIFT | B;
}
uint16 __glKosAverageBiPixelARGB1555(uint16 p1, uint16 p2) {
uint8 A = (ARGB1555_ALPHA(p1) + ARGB1555_ALPHA(p2)) / 2;
uint8 R = (ARGB1555_RED(p1) + ARGB1555_RED(p2)) / 2;
uint8 G = (ARGB1555_GREEN(p1) + ARGB1555_GREEN(p2)) / 2;
uint8 B = (ARGB1555_BLUE(p1) + ARGB1555_BLUE(p2)) / 2;
return ((A & RGB1_MAX) << ARGB1555_ALPHA_SHIFT) | ((R & RGB5_MAX) << ARGB1555_RED_SHIFT)
| ((G & RGB5_MAX) << ARGB1555_GREEN_SHIFT) | (B & RGB5_MAX);
}
uint16 __glKosAverageBiPixelARGB4444(uint16 p1, uint16 p2) {
uint8 A = (ARGB4444_ALPHA(p1) + ARGB4444_ALPHA(p2)) / 2;
uint8 R = (ARGB4444_RED(p1) + ARGB4444_RED(p2)) / 2;
uint8 G = (ARGB4444_GREEN(p1) + ARGB4444_GREEN(p2)) / 2;
uint8 B = (ARGB4444_BLUE(p1) + ARGB4444_BLUE(p2)) / 2;
return ((A & RGB4_MAX) << ARGB4444_ALPHA_SHIFT) | ((R & RGB4_MAX) << ARGB4444_RED_SHIFT)
| ((G & RGB4_MAX) << ARGB4444_GREEN_SHIFT) | (B & RGB4_MAX);
}
//===================================================================================================//
//== Colorspace Conversion ==//
static uint16 _glKosConvPixelRGBAU32(uint8 r, uint8 g, uint8 b, uint8 a) {
return (uint16)((a & RGB4_MAX) << ARGB4444_ALPHA_SHIFT) |
((r & RGB4_MAX) << ARGB4444_RED_SHIFT) |
((g & RGB4_MAX) << ARGB4444_GREEN_SHIFT) |
((b & RGB4_MAX));
}
static uint16 _glKosConvPixelRGBU24(uint8 r, uint8 g, uint8 b) {
return (uint16)((r & RGB5_MAX) << RGB565_RED_SHIFT) |
((g & RGB6_MAX) << RGB565_GREEN_SHIFT) |
((b & RGB5_MAX));
}
static void _glKosConvPixelsRGBF(int w, int h, float *src, uint16 *dst) {
int i;
for(i = 0; i < w * h; i++) {
dst[i] = _glKosConvPixelRGBU24((uint8)(src[i * 3 + 0] * RGB5_MAX),
(uint8)(src[i * 3 + 1] * RGB6_MAX),
(uint8)(src[i * 3 + 2] * RGB5_MAX));
}
}
static void _glKosConvPixelsRGBAF(int w, int h, float *src, uint16 *dst) {
int i;
for(i = 0; i < w * h; i++) {
dst[i] = _glKosConvPixelRGBAU32((uint8)(src[i * 4 + 0] * RGB4_MAX),
(uint8)(src[i * 4 + 1] * RGB4_MAX),
(uint8)(src[i * 4 + 2] * RGB4_MAX),
(uint8)(src[i * 4 + 3] * RGB4_MAX));
}
}
static void _glKosConvPixelsRGBU24(int w, int h, uint8 *src, uint16 *dst) {
unsigned char r, g, b;
int i;
for(i = 0; i < w * h; i++) {
r = (src[i * 3 + 0] * RGB5_MAX) / RGB8_MAX;
g = (src[i * 3 + 1] * RGB6_MAX) / RGB8_MAX;
b = (src[i * 3 + 2] * RGB5_MAX) / RGB8_MAX;
dst[i] = _glKosConvPixelRGBU24(r, g, b);
}
}
static void _glKosConvPixelsRGBAU32(int w, int h, uint8 *src, uint16 *dst) {
unsigned char r, g, b, a;
int i;
for(i = 0; i < w * h; i++) {
r = (src[i * 4 + 0] * RGB4_MAX) / RGB8_MAX;
g = (src[i * 4 + 1] * RGB4_MAX) / RGB8_MAX;
b = (src[i * 4 + 2] * RGB4_MAX) / RGB8_MAX;
a = (src[i * 4 + 3] * RGB4_MAX) / RGB8_MAX;
dst[i] = _glKosConvPixelRGBAU32(r, g, b, a);
}
}
static void _glKosConvPixelsRGBS24(int w, int h, int8 *src, uint16 *dst) {
unsigned char r, g, b;
int i;
for(i = 0; i < w * h; i++) {
r = ((src[i * 3 + 0] + S8_NEG_OFT) * RGB5_MAX) / RGB8_MAX;
g = ((src[i * 3 + 1] + S8_NEG_OFT) * RGB6_MAX) / RGB8_MAX;
b = ((src[i * 3 + 2] + S8_NEG_OFT) * RGB5_MAX) / RGB8_MAX;
dst[i] = _glKosConvPixelRGBU24(r, g, b);
}
}
static void _glKosConvPixelsRGBAS32(int w, int h, int8 *src, uint16 *dst) {
unsigned char r, g, b, a;
int i;
for(i = 0; i < w * h; i++) {
r = ((src[i * 4 + 0] + S8_NEG_OFT) * RGB4_MAX) / RGB8_MAX;
g = ((src[i * 4 + 1] + S8_NEG_OFT) * RGB4_MAX) / RGB8_MAX;
b = ((src[i * 4 + 2] + S8_NEG_OFT) * RGB4_MAX) / RGB8_MAX;
a = ((src[i * 4 + 3] + S8_NEG_OFT) * RGB4_MAX) / RGB8_MAX;
dst[i] = _glKosConvPixelRGBAU32(r, g, b, a);
}
}
static void _glKosConvPixelsRGBS48(int w, int h, int16 *src, uint16 *dst) {
unsigned char r, g, b;
int i;
for(i = 0; i < w * h; i++) {
r = ((src[i * 3 + 0] + S16_NEG_OFT) * RGB5_MAX) / RGB16_MAX;
g = ((src[i * 3 + 1] + S16_NEG_OFT) * RGB6_MAX) / RGB16_MAX;
b = ((src[i * 3 + 2] + S16_NEG_OFT) * RGB5_MAX) / RGB16_MAX;
dst[i] = _glKosConvPixelRGBU24(r, g, b);
}
}
static void _glKosConvPixelsRGBAS64(int w, int h, int16 *src, uint16 *dst) {
unsigned char r, g, b, a;
int i;
for(i = 0; i < w * h; i++) {
r = ((src[i * 4 + 0] + S16_NEG_OFT) * RGB4_MAX) / RGB16_MAX;
g = ((src[i * 4 + 1] + S16_NEG_OFT) * RGB4_MAX) / RGB16_MAX;
b = ((src[i * 4 + 2] + S16_NEG_OFT) * RGB4_MAX) / RGB16_MAX;
a = ((src[i * 4 + 3] + S16_NEG_OFT) * RGB4_MAX) / RGB16_MAX;
dst[i] = _glKosConvPixelRGBAU32(r, g, b, a);
}
}
static void _glKosConvPixelsRGBU48(int w, int h, uint16 *src, uint16 *dst) {
unsigned char r, g, b;
int i;
for(i = 0; i < w * h; i++) {
r = ((src[i * 3 + 0]) * RGB5_MAX) / RGB16_MAX;
g = ((src[i * 3 + 1]) * RGB6_MAX) / RGB16_MAX;
b = ((src[i * 3 + 2]) * RGB5_MAX) / RGB16_MAX;
dst[i] = _glKosConvPixelRGBU24(r, g, b);
}
}
static void _glKosConvPixelsRGBAU64(int w, int h, uint16 *src, uint16 *dst) {
unsigned char r, g, b, a;
int i;
for(i = 0; i < w * h; i++) {
r = (src[i * 4 + 0] * RGB4_MAX) / RGB16_MAX;
g = (src[i * 4 + 1] * RGB4_MAX) / RGB16_MAX;
b = (src[i * 4 + 2] * RGB4_MAX) / RGB16_MAX;
a = (src[i * 4 + 3] * RGB4_MAX) / RGB16_MAX;
dst[i] = _glKosConvPixelRGBAU32(r, g, b, a);
}
}
void _glKosPixelConvertRGB(int format, int w, int h, void *src, uint16 *dst) {
switch(format) {
case GL_BYTE:
_glKosConvPixelsRGBS24(w, h, (int8 *)src, dst);
break;
case GL_UNSIGNED_BYTE:
_glKosConvPixelsRGBU24(w, h, (uint8 *)src, dst);
break;
case GL_SHORT:
_glKosConvPixelsRGBS48(w, h, (int16 *)src, dst);
break;
case GL_UNSIGNED_SHORT:
_glKosConvPixelsRGBU48(w, h, (uint16 *)src, dst);
break;
case GL_FLOAT:
_glKosConvPixelsRGBF(w, h, (float *)src, dst);
break;
}
}
void _glKosPixelConvertRGBA(int format, int w, int h, void *src, uint16 *dst) {
switch(format) {
case GL_BYTE:
_glKosConvPixelsRGBAS32(w, h, (int8 *)src, dst);
break;
case GL_UNSIGNED_BYTE:
_glKosConvPixelsRGBAU32(w, h, (uint8 *)src, dst);
break;
case GL_SHORT:
_glKosConvPixelsRGBAS64(w, h, (int16 *)src, dst);
break;
case GL_UNSIGNED_SHORT:
_glKosConvPixelsRGBAU64(w, h, (uint16 *)src, dst);
break;
case GL_FLOAT:
_glKosConvPixelsRGBAF(w, h, (float *)src, dst);
break;
}
}

View File

@ -1,70 +0,0 @@
/* KallistiGL for KallistiOS ##version##
libgl/gl-rgb.h
Copyright (C) 2013-2015 Josh Pearson
A set of functions for working with ARGB pixel data.
*/
#ifndef GL_RGB_H
#define GL_RGB_H
typedef GLubyte GLrgb3ub[3];
typedef GLubyte GLrgba4ub[3];
typedef GLfloat GLrgb3f[3];
typedef GLfloat GLrgba4f[4];
#define RGB565_RED_MASK 0xF800
#define RGB565_GREEN_MASK 0x7E0
#define RGB565_BLUE_MASK 0x1F
#define RGB565_RED_SHIFT 0xB
#define RGB565_GREEN_SHIFT 0x5
#define RGB565_BLUE_SHIFT 0x0
#define ARGB4444_ALPHA_MASK 0xF000
#define ARGB4444_RED_MASK 0x0F00
#define ARGB4444_GREEN_MASK 0x00F0
#define ARGB4444_BLUE_MASK 0x000F
#define ARGB4444_ALPHA_SHIFT 0xC
#define ARGB4444_RED_SHIFT 0x8
#define ARGB4444_GREEN_SHIFT 0x4
#define ARGB4444_BLUE_SHIFT 0x0
#define ARGB1555_ALPHA_MASK 0x8000
#define ARGB1555_RED_MASK 0x7C00
#define ARGB1555_GREEN_MASK 0x3E0
#define ARGB1555_BLUE_MASK 0x1F
#define ARGB1555_ALPHA_SHIFT 0xF
#define ARGB1555_RED_SHIFT 0xA
#define ARGB1555_GREEN_SHIFT 0x5
#define ARGB1555_BLUE_SHIFT 0x0
#define ARGB32_ALPHA_MASK 0xFF000000
#define ARGB32_RGB_MASK 0xFFFFFF
#define ARGB32_RED_SHIFT 0x8
#define RGBA32_APLHA_MASK 0xFF
#define RGBA32_RGB_MASK 0xFFFFFF00
#define RGB1_MAX 0x1
#define RGB4_MAX 0xF
#define RGB5_MAX 0x1F
#define RGB6_MAX 0x3F
#define RGB8_MAX 0xFF
#define RGB16_MAX 0xFFFF
#define RGBA32_2_ARGB32(n) (((n & ARGB32_RGB_MASK) << ARGB32_RED_SHIFT) | (n & ARGB32_ALPHA_MASK))
#define ARGB_PACK_RGBF(r,g,b) (0xFF000000 | ((r*0xFF) << 16) | ((g*0xFF)<<8) | (b*0xFF))
#define ARGB_PACK_ARGBF(a,r,g,b) (((a*0xFF) << 24) | ((r*0xFF) << 16) | ((g*0xFF)<<8) | (b*0xFF))
#define S8_NEG_OFT 128 // Absolute Value of Minimum 8bit Signed Range //
#define S16_NEG_OFT 32768 // Absolute Value of Minimum 16bit Signed Range //
void _glKosPixelConvertRGB(int format, int w, int h, void *src, uint16 *dst);
void _glKosPixelConvertRGBA(int format, int w, int h, void *src, uint16 *dst);
#endif

View File

@ -1,209 +0,0 @@
/* KallistiGL for KallistiOS ##version##
libgl/gl-sh4-light.S
Copyright (C) 2013-2014 Josh Pearson
Dynamic Vertex Lighting
This Assembly file contains 2 functions:
_glKosSpotLight - This function computes diffuse / spotlight / attenuation
_glKosSpecular - This functions computes the Specular Term
*/
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!float _glKosSpecular( void * vertex6f, void * eyepos, void * Lvectorin );
.globl __glKosSpecular
!r4 = [arg][void*] = vertex
!r5 = [arg][void*] = eyepos
!r6 = [arg][void*] = L vector
!fr0 = return value
!fv0 = vertex position (P)(N)
!fv4 = eye position (E)
!fv8 = L vector (L)
__glKosSpecular:
fmov @r4+, fr0 ! load vertex x to fv0
fmov @r4+, fr1 ! load vertex y to fv0
fmov @r4+, fr2 ! load vertex z to fv0
fmov @r5+, fr4 ! load eye pos x to fv4
fmov @r5+, fr5 ! load eye pos y to fv4
fmov @r5+, fr6 ! load eye pos z to fv4
fmov @r6+, fr8 ! load L vector x to fv8
fmov @r6+, fr9 ! load L vector y to fv8
fmov @r6+, fr10 ! load L vector z to fv8
fsub fr0, fr4 ! fv4 = V = normalize ( E - P )
fsub fr1, fr5
fsub fr2, fr6
fldi0 fr3 ! load 0 for P w
fldi0 fr7 ! load 0 for E w
fipr fv4, fv4 ! Normalize V vector
fsrra fr7
fmul fr7, fr4
fmul fr7, fr5
fmul fr7, fr6
fadd fr4, fr8 ! fv8 = H = normalize( L + V )
fadd fr5, fr9
fadd fr6, fr10
fldi0 fr11 ! load 0 for H w
fipr fv8, fv8 ! Normalize H vector
fsrra fr11
fmul fr11, fr8
fmul fr11, fr9
fmul fr11, fr10
fmov @r4+, fr0 ! load N to fv0
fmov @r4+, fr1
fmov @r4+, fr2
fipr fv0, fv8 ! N dot H for specular term
rts
fmov fr11, fr0 ! move N dot H to fr0 for return
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!int _glKosSpotlight( void * glLight, void * vertex6f, void * Lvectorout );
.globl __glKosSpotlight
!r0 = return value | true or false
!r1 = boolean flag
!r2 = boolean false
!r4 = [arg] = light
!r5 = [arg] = vertex
!r6 = [arg] = output
!fv0 = vertex position
!fv4 = light position | L vector | normalize(light pos - vertex pos) | w = attenuation distance
!fv8 = light direction | N vector = Vertex Normal
!fv12 = Spot vector | normalize(vertex pos - light pos)
__glKosSpotlight:
mov #0, r1 ! load 0 for boolean flag
mov #0, r2 ! load 0 for boolean false
fmov @r4+, fr4 ! load light position x to fv4
fmov @r4+, fr5 ! load light position y to fv4
fmov @r4+, fr6 ! load light position z to fv4
fmov @r4+, fr7 ! load light position w to fv4
fmov @r4+, fr8 ! load light direction x to fv8
fmov @r4+, fr9 ! load light direction y to fv8
fmov @r4+, fr10 ! load light direction z to fv8
fmov @r5+, fr0 ! load vertex position x to fv0
fmov @r5+, fr1 ! load vertex position y to fv0
fmov @r5+, fr2 ! load vertex position z to fv0
fldi0 fr11 ! load 0 for light dir w
fcmp/gt fr11, fr7 ! light pos w component set = spot light
bf .VERTEXLIGHT0 ! light not a spot light - branch to vertex lighting
fschg
fmov dr0, dr12 ! copy vertex x,y to fv12
fschg
fmov fr2, fr14 ! copy vertex z to fv12
fsub fr4, fr12 ! fv12 = ( vertex position - light position)
fsub fr5, fr13
fsub fr6, fr14
fldi0 fr15 ! set fv12 w component to 0
fipr fv12, fv12 ! Normalize vector
fsrra fr15
fmul fr15, fr12
fmul fr15, fr13
fmul fr15, fr14
fldi0 fr15 ! set fv12 w component to 0
fipr fv12, fv8 ! fr11 now holds light cosDir
fmov @r4+, fr15 ! load light cutOff to fr15
mov #1, r1 ! load 1 for boolean flag = indicate light cutOff was read
fcmp/gt fr15, fr11 ! cosDir > cutOff ? 0 : 1
bt .RET0spot ! vertex outside of spotlight = return 0
.VERTEXLIGHT0:
fsub fr0, fr4 ! fv4 = L vector = ( light position - vertex position)
fsub fr1, fr5
fsub fr2, fr6
fldi0 fr7 ! load 0 for L w
fldi0 fr11 ! load 0 for N w
fipr fv4, fv4 ! Normalize L vector
fsrra fr7
fmul fr7, fr4
fmul fr7, fr5
fmul fr7, fr6 ! fv4 = Normalized L Vector
fmov fr7, fr3 ! copy L w to fr3
fldi0 fr7 ! load 0 for L w
fcmp/gt fr7, fr3
bf .RET0spot ! if L w < 0, return 0 now to avoid pointless computations
fmov @r5+, fr8 ! load normal to fv8
fmov @r5+, fr9 ! load normal to fv8
fmov @r5+, fr10 ! load normal to fv8
fipr fv8, fv4 ! N dot L
fcmp/gt fr11, fr7 ! L w < = 0 ? L w = 0
bf .RET0spot: ! if L w < 0, return 0 now to avoid pointless computations
.WRITEDi:
fschg
fmov dr4, @r6 ! write L vector x to output
fschg
add #8, r6
fmov fr6, @r6 ! write L vector z to output
add #4, r6
cmp/gt r2, r1
bt .READattenf
add #4, r4
.READattenf:
fmov @r4+, fr8 ! vertex normal gets overwritten by atten factors
fmov @r4+, fr9
fmov @r4+, fr10
fldi1 fr11
fmul fr3, fr9 ! calculate attenuation
fmul fr3, fr10
fmul fr3, fr10
fadd fr9, fr8
fadd fr10, fr8
fdiv fr8, fr11 ! fr11 = A
fmul fr7, fr11 ! D * A
fmov fr11, @r6 ! write D*A to output
.RET1spot:
rts
mov #1, r0
.RET0spot:
rts
mov #0, r0
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

View File

@ -1,86 +0,0 @@
/* KallistiGL for KallistiOS ##version##
libgl/gl-sh4.h
Copyright (C) 2013-2014 Josh Pearson
Macros for utilizing the Dreamcast's SH4 CPU vector / matrix math functions.
*/
#ifndef GL_SH4_H
#define GL_SH4_H
typedef float vector3f[3]; /* 3 float vector */
typedef float matrix4f[4][4]; /* 4x4 float matrix */
/* DEG2RAD - convert Degrees to Radians = PI / 180.0f */
#define DEG2RAD (0.01745329251994329576923690768489)
/* Calculate Spot Light Angle Cosine = (PI / 180.0f) * (n / 2) */
#define LCOS(n) fcos(n*0.00872664625997164788461845384244)
/* Internal GL API macro */
#define mat_trans_fv12() { \
__asm__ __volatile__( \
"fldi1 fr15\n" \
"ftrv xmtrx, fv12\n" \
"fldi1 fr14\n" \
"fdiv fr15, fr14\n" \
"fmul fr14, fr12\n" \
"fmul fr14, fr13\n" \
: "=f" (__x), "=f" (__y), "=f" (__z) \
: "0" (__x), "1" (__y), "2" (__z) \
: "fr15" ); \
}
/* Internal GL API macro */
#define mat_trans_fv12_nodiv() { \
__asm__ __volatile__( \
"fldi1 fr15\n" \
"ftrv xmtrx, fv12\n" \
: "=f" (__x), "=f" (__y), "=f" (__z) \
: "0" (__x), "1" (__y), "2" (__z) ); \
}
#define mat_trans_fv12_nodivw() { \
__asm__ __volatile__( \
"fldi1 fr15\n" \
"ftrv xmtrx, fv12\n" \
: "=f" (__x), "=f" (__y), "=f" (__z), "=f" (__w) \
: "0" (__x), "1" (__y), "2" (__z), "3" (__w) ); \
}
#define mat_trans_texture4(s, t, r, q) { \
register float __s __asm__("fr4") = (s); \
register float __t __asm__("fr5") = (t); \
register float __r __asm__("fr6") = (r); \
register float __q __asm__("fr7") = (q); \
__asm__ __volatile__( \
"ftrv xmtrx,fv4\n" \
"fldi1 fr6\n" \
"fdiv fr7,fr6\n" \
"fmul fr6,fr4\n" \
"fmul fr6,fr5\n" \
: "=f" (__s), "=f" (__t), "=f" (__r) \
: "0" (__s), "1" (__t), "2" (__r) \
: "fr7" ); \
s = __s; t = __t; r = __r; \
}
#define mat_trans_texture2_nomod(s, t, so, to) { \
register float __s __asm__("fr4") = (s); \
register float __t __asm__("fr5") = (t); \
__asm__ __volatile__( \
"fldi0 fr6\n" \
"fldi1 fr7\n" \
"ftrv xmtrx,fv4\n" \
"fldi1 fr6\n" \
"fdiv fr7,fr6\n" \
"fmul fr6,fr4\n" \
"fmul fr6,fr5\n" \
: "=f" (__s), "=f" (__t) \
: "0" (__s), "1" (__t) \
: "fr7" ); \
so = __s; to = __t; \
}
#endif

View File

@ -1,115 +0,0 @@
/* KallistiGL for KallistiOS ##version##
libgl/glu-texture.c
Copyright (C) 2013-2014 Josh Pearson
A set of functions for working with ARGB pixel data.
*/
#include "gl.h"
#include "gl-api.h"
#include "gl-rgb.h"
#include "glu.h"
GLAPI GLuint APIENTRY glKosMipMapTexSize(GLuint width, GLuint height) {
GLuint b = 0;
while(width >= 1 && height >= 1) {
b += width * height * 2;
if(width >= 1)
width /= 2;
if(height >= 1)
height /= 2;
}
return b;
}
static GLint gluBuild2DBiMipmaps(GLenum target, GLint internalFormat, GLsizei width,
GLsizei height, GLenum format, GLenum type, const void *data) {
if(target != GL_TEXTURE_2D)
return -1;
if(width < 1 || height < 1)
return 0;
uint32 i = 0;
uint16 x , y;
uint16 *src = (uint16 *)data;
uint16 *dst = (uint16 *)data + (width * height);
for(y = 0; y < height; y += 2) {
for(x = 0; x < width; x += 2) {
switch(type) {
case GL_UNSIGNED_SHORT_5_6_5:
dst[i++] = __glKosAverageBiPixelRGB565(*src, *(src + 1));
break;
case GL_UNSIGNED_SHORT_4_4_4_4:
dst[i++] = __glKosAverageBiPixelARGB4444(*src, *(src + 1));
break;
case GL_UNSIGNED_SHORT_1_5_5_5_REV:
dst[i++] = __glKosAverageBiPixelARGB1555(*src, *(src + 1));
break;
}
src += 2;
}
src += width;
}
return gluBuild2DBiMipmaps(target, internalFormat, width / 2, height / 2,
format, type, (uint16 *)data + (width * height));
}
GLint APIENTRY gluBuild2DMipmaps(GLenum target, GLint internalFormat, GLsizei width,
GLsizei height, GLenum format, GLenum type, const void *data) {
if(target != GL_TEXTURE_2D)
return -1;
if(type != GL_UNSIGNED_SHORT_5_6_5 && type != GL_UNSIGNED_SHORT_4_4_4_4
&& type != GL_UNSIGNED_SHORT_1_5_5_5_REV)
return -1;
if(width < 1 || height < 1)
return 0;
if(width == 1 || height == 1)
return gluBuild2DBiMipmaps(target, internalFormat, width, height, format, type, data);
uint32 i = 0;
uint16 x, y;
uint16 *src = (uint16 *)data;
uint16 *dst = (uint16 *)data + (width * height);
for(y = 0; y < height; y += 2) {
for(x = 0; x < width; x += 2) {
switch(type) {
case GL_UNSIGNED_SHORT_5_6_5:
dst[i++] = __glKosAverageQuadPixelRGB565(*src, *(src + 1), *(src + width), *(src + width + 1));
break;
case GL_UNSIGNED_SHORT_4_4_4_4:
dst[i++] = __glKosAverageQuadPixelARGB4444(*src, *(src + 1), *(src + width), *(src + width + 1));
break;
case GL_UNSIGNED_SHORT_1_5_5_5_REV:
dst[i++] = __glKosAverageQuadPixelARGB1555(*src, *(src + 1), *(src + width), *(src + width + 1));
break;
}
src += 2;
}
src += width;
}
return gluBuild2DMipmaps(target, internalFormat, width / 2, height / 2,
format, type, (uint16 *)data + (width * height));
}

View File

@ -642,14 +642,6 @@ GLAPI const GLbyte* APIENTRY glGetString(GLenum name);
GLAPI void APIENTRY glActiveTextureARB(GLenum texture);
GLAPI void APIENTRY glClientActiveTextureARB(GLenum texture);
/* Frame Buffer Objects / Render-To-Texture Functions */
GLAPI void APIENTRY glGenFramebuffers(GLsizei n, GLuint *framebuffers);
GLAPI void APIENTRY glDeleteFramebuffers(GLsizei n, GLuint *framebuffers);
GLAPI void APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer);
GLAPI void APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level);
GLAPI GLenum APIENTRY glCheckFramebufferStatus(GLenum target);
/* Error handling */
GLAPI GLenum APIENTRY glGetError(void);

View File

@ -7,6 +7,14 @@ __BEGIN_DECLS
GLAPI void APIENTRY glKosSwapBuffers();
GLAPI void APIENTRY glGenFramebuffersEXT(GLsizei n, GLuint* framebuffers);
GLAPI void APIENTRY glDeleteFramebuffersEXT(GLsizei n, const GLuint* framebuffers);
GLAPI void APIENTRY glBindFramebufferEXT(GLenum target, GLuint framebuffer);
GLAPI void APIENTRY glFramebufferTexture2DEXT(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
GLAPI void APIENTRY glGenerateMipmapEXT(GLenum target);
GLAPI GLenum APIENTRY glCheckFramebufferStatusEXT(GLenum target);
GLAPI GLboolean APIENTRY glIsFramebufferEXT(GLuint framebuffer);
__END_DECLS
#endif // GLKOS_H