Added multi-texture support and glCompressedTexImage2D to the GL API

This commit is contained in:
Josh Pearson 2015-01-04 15:07:57 -08:00
parent 4af2c8aacc
commit 763ec99483
18 changed files with 1429 additions and 989 deletions

View File

@ -5,8 +5,8 @@
# Copyright (C) 2014 Lawrence Sebald # Copyright (C) 2014 Lawrence Sebald
TARGET = libgl.a TARGET = libgl.a
OBJS = gl-rgb.o gl-fog.o gl-sh4-light.o gl-light.o gl-clip.o gl-pvr.o OBJS = gl-rgb.o gl-fog.o gl-sh4-light.o gl-light.o gl-clip.o gl-clip-arrays.o
OBJS += gl-arrays.o gl-matrix.o gl-api.o gl-texture.o glu-texture.o OBJS += gl-arrays.o gl-pvr.o gl-matrix.o gl-api.o gl-texture.o glu-texture.o
OBJS += gl-framebuffer.o gl-cap.o gl-error.o OBJS += gl-framebuffer.o gl-cap.o gl-error.o
SUBDIRS = SUBDIRS =

View File

@ -290,7 +290,7 @@ void APIENTRY glVertex2fv(const GLfloat *xy) {
} }
void APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) { void APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) {
pvr_vertex_t * v = _glKosVertexBufPointer(); pvr_vertex_t *v = _glKosVertexBufPointer();
v[0].z = v[3].z = 0; v[0].z = v[3].z = 0;
@ -301,7 +301,7 @@ void APIENTRY glRectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) {
} }
void APIENTRY glRectfv(const GLfloat *v1, const GLfloat *v2) { void APIENTRY glRectfv(const GLfloat *v1, const GLfloat *v2) {
pvr_vertex_t * v = _glKosVertexBufPointer(); pvr_vertex_t *v = _glKosVertexBufPointer();
v[0].z = v[3].z = 0; v[0].z = v[3].z = 0;
@ -582,7 +582,7 @@ void _glKosVertex3fcv(const GLfloat *xyz) {
/* GL_POINTS */ /* GL_POINTS */
GLvoid _glKosVertex3fp(GLfloat x, GLfloat y, GLfloat z) { GLvoid _glKosVertex3fp(GLfloat x, GLfloat y, GLfloat z) {
pvr_vertex_t * v = _glKosVertexBufPointer(); pvr_vertex_t *v = _glKosVertexBufPointer();
mat_trans_single3_nomod(x - GL_KOS_POINT_SIZE, y + GL_KOS_POINT_SIZE, z, mat_trans_single3_nomod(x - GL_KOS_POINT_SIZE, y + GL_KOS_POINT_SIZE, z,
v[0].x, v[0].y, v[0].z); v[0].x, v[0].y, v[0].z);
@ -593,7 +593,7 @@ GLvoid _glKosVertex3fp(GLfloat x, GLfloat y, GLfloat z) {
} }
GLvoid _glKosVertex3fpv(const GLfloat *xyz) { GLvoid _glKosVertex3fpv(const GLfloat *xyz) {
pvr_vertex_t * v = _glKosVertexBufPointer(); pvr_vertex_t *v = _glKosVertexBufPointer();
mat_trans_single3_nomod(xyz[0] - GL_KOS_POINT_SIZE, xyz[1] + GL_KOS_POINT_SIZE, xyz[2], 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); v[0].x, v[0].y, v[0].z);
@ -604,7 +604,7 @@ GLvoid _glKosVertex3fpv(const GLfloat *xyz) {
} }
static inline void _glKosFinishRect() { static inline void _glKosFinishRect() {
pvr_vertex_t * v = _glKosVertexBufPointer(); pvr_vertex_t *v = _glKosVertexBufPointer();
v[0].argb = v[1].argb = v[2].argb = v[3].argb = GL_KOS_VERTEX_COLOR; v[0].argb = v[1].argb = v[2].argb = v[3].argb = GL_KOS_VERTEX_COLOR;
@ -619,7 +619,7 @@ static inline void _glKosFinishRect() {
v[2].y = v[0].y; v[2].y = v[0].y;
v[2].z = v[0].z; v[2].z = v[0].z;
_glKosVertexBufAdd( 4 ); _glKosVertexBufAdd(4);
GL_KOS_VERTEX_COUNT += 4; GL_KOS_VERTEX_COUNT += 4;
} }
@ -732,6 +732,12 @@ static inline void _glKosApplyBlendFunc() {
} }
} }
static inline void _glKosApplyTextureFunc(GL_TEXTURE_OBJECT *tex) {
GL_KOS_POLY_CXT.txr.uv_clamp = tex->uv_clamp;
GL_KOS_POLY_CXT.txr.mipmap = tex->mip_map ? 1 : 0;
GL_KOS_POLY_CXT.txr.mipmap_bias = PVR_MIPBIAS_NORMAL;
}
void _glKosCompileHdr() { void _glKosCompileHdr() {
pvr_poly_hdr_t *hdr = _glKosVertexBufPointer(); pvr_poly_hdr_t *hdr = _glKosVertexBufPointer();
@ -777,9 +783,7 @@ void _glKosCompileHdrT(GL_TEXTURE_OBJECT *tex) {
_glKosApplyBlendFunc(); _glKosApplyBlendFunc();
GL_KOS_POLY_CXT.txr.uv_clamp = tex->uv_clamp; _glKosApplyTextureFunc(tex);
GL_KOS_POLY_CXT.txr.mipmap = tex->mip_map ? 1 : 0;
GL_KOS_POLY_CXT.txr.mipmap_bias = PVR_MIPBIAS_NORMAL;
if(_glKosEnabledBlend()) if(_glKosEnabledBlend())
GL_KOS_POLY_CXT.txr.env = tex->env; GL_KOS_POLY_CXT.txr.env = tex->env;
@ -792,6 +796,37 @@ void _glKosCompileHdrT(GL_TEXTURE_OBJECT *tex) {
_glKosVertexBufIncrement(); _glKosVertexBufIncrement();
} }
void _glKosCompileHdrMT(pvr_poly_hdr_t *dst, GL_TEXTURE_OBJECT *tex) {
pvr_poly_cxt_txr(&GL_KOS_POLY_CXT,
PVR_LIST_TR_POLY,
tex->color,
tex->width,
tex->height,
tex->data,
tex->filter);
GL_KOS_POLY_CXT.gen.shading = GL_KOS_SHADE_FUNC;
_glKosApplyDepthFunc();
_glKosApplyScissorFunc();
_glKosApplyFogFunc();
_glKosApplyCullingFunc();
_glKosApplyTextureFunc(tex);
GL_KOS_POLY_CXT.blend.src = (GL_KOS_BLEND_FUNC & 0xF0) >> 4;
GL_KOS_POLY_CXT.blend.dst = (GL_KOS_BLEND_FUNC & 0x0F);
GL_KOS_POLY_CXT.txr.env = tex->env;
pvr_poly_compile(dst, &GL_KOS_POLY_CXT);
if(GL_KOS_SUPERSAMPLE)
dst->mode2 |= GL_PVR_SAMPLE_SUPER << PVR_TA_SUPER_SAMPLE_SHIFT;
}
//====================================================================================================// //====================================================================================================//
//== Internal GL KOS API State Functions ==// //== Internal GL KOS API State Functions ==//

View File

@ -10,11 +10,17 @@
#ifndef GL_API_H #ifndef GL_API_H
#define GL_API_H #define GL_API_H
#include "gl.h"
typedef struct { typedef struct {
float pos[3]; GLfloat pos[3];
float norm[3]; GLfloat norm[3];
} glVertex; /* Simple Vertex used for Dynamic Vertex Lighting */ } glVertex; /* Simple Vertex used for Dynamic Vertex Lighting */
typedef struct {
GLfloat u, v;
} glTexCoord; /* Simple Texture Coordinate used for Multi-Texturing */
typedef struct { typedef struct {
GLushort width; GLushort width;
GLushort height; GLushort height;
@ -35,8 +41,14 @@ typedef struct {
GLvoid *link; GLvoid *link;
} GL_FRAMEBUFFER_OBJECT; /* KOS Open GL Frame Buffer Object */ } GL_FRAMEBUFFER_OBJECT; /* KOS Open GL Frame Buffer Object */
typedef unsigned short uint16; typedef struct {
typedef unsigned char uint8; 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 */ /* Vertex Main Buffer Internal Functions */
inline void _glKosVertexBufSwitchOP(); inline void _glKosVertexBufSwitchOP();
@ -54,6 +66,11 @@ inline unsigned int _glKosVertexBufCount(unsigned char list);
unsigned char _glKosList(); unsigned char _glKosList();
inline void _glKosVertexBufCopy(void *src, void *dst, GLuint count); inline void _glKosVertexBufCopy(void *src, void *dst, GLuint count);
inline void _glKosResetEnabledTex(); inline void _glKosResetEnabledTex();
inline void *_glKosMultiUVBufAddress();
inline void *_glKosMultiUVBufPointer();
inline void _glKosMultiUVBufIncrement();
inline void _glKosMultiUVBufAdd(GLuint count);
inline void _glKosMultiUVBufReset();
/* Vertex Clip Buffer Internal Functions */ /* Vertex Clip Buffer Internal Functions */
inline void *_glKosClipBufAddress(); inline void *_glKosClipBufAddress();
@ -69,13 +86,14 @@ inline glVertex *_glKosArrayBufPtr();
/* Initialize the OpenGL PVR Pipeline */ /* Initialize the OpenGL PVR Pipeline */
int _glKosInitPVR(); int _glKosInitPVR();
GLubyte _glKosInitTextures(); unsigned char _glKosInitTextures();
/* Compile the current Polygon Header for the PVR */ /* Compile the current Polygon Header for the PVR */
void _glKosCompileHdr(); void _glKosCompileHdr();
void _glKosCompileHdrTx(); void _glKosCompileHdrTx();
void _glKosCompileHdrTx2(); void _glKosCompileHdrMTx();
void _glKosCompileHdrT(GL_TEXTURE_OBJECT *tex); void _glKosCompileHdrT(GL_TEXTURE_OBJECT *tex);
void _glKosCompileHdrMT(pvr_poly_hdr_t *dst, GL_TEXTURE_OBJECT *tex);
/* Clipping Internal Functions */ /* Clipping Internal Functions */
void _glKosTransformClipBuf(pvr_vertex_t *v, GLuint verts); void _glKosTransformClipBuf(pvr_vertex_t *v, GLuint verts);
@ -84,10 +102,17 @@ unsigned int _glKosClipTriangles(pvr_vertex_t *vin, pvr_vertex_t *vout, unsigned
unsigned int _glKosClipQuads(pvr_vertex_t *vin, pvr_vertex_t *vout, unsigned int vertices); unsigned int _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 _glKosClipTrianglesTransformed(pvr_vertex_t *src, float *w, pvr_vertex_t *dst, GLuint count);
unsigned char _glKosClipTriTransformed(pvr_vertex_t *vin, float *w, pvr_vertex_t *vout);
unsigned int _glKosClipQuadsTransformed(pvr_vertex_t *vin, float *w, pvr_vertex_t *vout, unsigned int vertices); unsigned int _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 _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 */ /* Lighting Internal Functions */
void _glKosInitLighting(); void _glKosInitLighting();
void _glKosEnableLight(const GLuint light); void _glKosEnableLight(const GLuint light);
@ -176,5 +201,20 @@ GLubyte _glKosIsLightEnabled(GLubyte light);
GLubyte _glKosGetMaxLights(); GLubyte _glKosGetMaxLights();
GLuint _glKosBoundTexID(); GLuint _glKosBoundTexID();
GLuint _glKosVertexColor(); GLuint _glKosVertexColor();
GLubyte _glKosMaxTextureUnits();
GL_TEXTURE_OBJECT *_glKosBoundMultiTexID();
inline void _glKosPushMultiTexObject(GL_TEXTURE_OBJECT *tex,
pvr_vertex_t *src,
GLuint count);
static inline void _glKosVertexCopyPVR(const pvr_vertex_t *src, pvr_vertex_t *dst) {
*dst = *src;
}
static inline void _glKosTexCoordCopy(const glTexCoord *src, glTexCoord *dst) {
*dst = *src;
}
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,6 @@
vertex lighting will be applied even if you submit a color vertex lighting will be applied even if you submit a color
pointer, so only submit one or the other. pointer, so only submit one or the other.
ToDo: glDrawElements() is not yet implemented.
*/ */
#ifndef GL_ARRAYS_H #ifndef GL_ARRAYS_H
@ -22,34 +21,10 @@
#include "gl.h" #include "gl.h"
#define GL_USE_ARRAY 0x0001 #define GL_KOS_USE_ARRAY (1<<0)
#define GL_USE_TEXTURE 0x0010 #define GL_KOS_USE_TEXTURE0 (1<<1)
#define GL_USE_COLOR 0x0100 #define GL_KOS_USE_TEXTURE1 (1<<2)
#define GL_USE_NORMAL 0x1000 #define GL_KOS_USE_COLOR (1<<3)
#define GL_USE_TEXTURE_COLOR 0x0111 #define GL_KOS_USE_NORMAL (1<<4)
#define GL_USE_TEXTURE_LIT 0x1011
void (*_glKosArrayTexCoordFunc)(pvr_vertex_t *);
void (*_glKosArrayColorFunc)(pvr_vertex_t *);
void (*_glKosElementTexCoordFunc)(pvr_vertex_t *, GLuint);
void (*_glKosElementColorFunc)(pvr_vertex_t *, GLuint);
static GLfloat *GL_VERTEX_POINTER = NULL;
static GLushort GL_VERTEX_STRIDE = 0;
static GLfloat *GL_NORMAL_POINTER = NULL;
static GLushort GL_NORMAL_STRIDE = 0;
static GLfloat *GL_TEXCOORD_POINTER = NULL;
static GLushort GL_TEXCOORD_STRIDE = 0;
static GLfloat *GL_COLOR_POINTER = NULL;
static GLushort GL_COLOR_STRIDE = 0;
static GLubyte GL_COLOR_COMPONENTS = 0;
static GLenum GL_COLOR_TYPE = 0;
static GLubyte *GL_INDEX_POINTER_U8 = NULL;
static GLushort *GL_INDEX_POINTER_U16 = NULL;
#endif #endif

418
gl-clip-arrays.c Executable file
View File

@ -0,0 +1,418 @@
/* KallistiGL for KallistiOS ##version##
libgl/gl-clip.c
Copyright (C) 2013-2014 Josh Pearson
Near-Z Clipping Algorithm (C) 2013-2014 Josh PH3NOM Pearson
Input Primitive Types Supported:
-GL_TRIANGLES
-GL_TRIANGLE_STRIPS
-GL_QUADS
Outputs a mix of Triangles and Triangle Strips for use with the PVR
*/
#include <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;
}

621
gl-clip.c
View File

@ -14,27 +14,13 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "gl.h"
#include "gl-api.h"
#include "gl-clip.h" #include "gl-clip.h"
static float3 CLIP_BUF[1024 * 32]; static float3 CLIP_BUF[1024 * 32];
static inline void glVertexCopy3f(float3 *src, float3 *dst) { static inline void _glKosVertexClipZNear(pvr_vertex_t *v1, pvr_vertex_t *v2, float MAG) {
*dst = *src;
}
static inline void glVertexCopyPVR(pvr_vertex_t *src, pvr_vertex_t *dst) {
*dst = *src;
}
static inline void _glKosVertexCopyPVR(pvr_vertex_t *src, pvr_vertex_t *dst) {
*dst = *src;
}
static inline float ZclipMag(float3 *v1, float3 *v2) {
return ((CLIP_NEARZ - v1->z) / (v2->z - v1->z));
}
static inline void glVertexClipZNear(pvr_vertex_t *v1, pvr_vertex_t *v2, float MAG) {
colorui *c1 = (colorui *)&v1->argb; colorui *c1 = (colorui *)&v1->argb;
colorui *c2 = (colorui *)&v2->argb; colorui *c2 = (colorui *)&v2->argb;
@ -49,26 +35,7 @@ static inline void glVertexClipZNear(pvr_vertex_t *v1, pvr_vertex_t *v2, float M
c1->b += (c2->b - c1->b) * MAG; c1->b += (c2->b - c1->b) * MAG;
} }
static inline void _glKosVertexClipZNear3(pvr_vertex_t *v1, pvr_vertex_t *v2, float *w1, float *w2) { static GLuint _glKosTransformClip(pvr_vertex_t *v, GLint count) {
float MAG = ((CLIP_NEARZ - v1->z) / (v2->z - v1->z));
colorui *c1 = (colorui *)&v1->argb;
colorui *c2 = (colorui *)&v2->argb;
v1->x += (v2->x - v1->x) * MAG;
v1->y += (v2->y - v1->y) * MAG;
v1->z += (v2->z - v1->z) * MAG;
v1->u += (v2->u - v1->u) * MAG;
v1->v += (v2->v - v1->v) * MAG;
c1->a += (c2->a - c1->a) * MAG;
c1->r += (c2->r - c1->r) * MAG;
c1->g += (c2->g - c1->g) * MAG;
c1->b += (c2->b - c1->b) * MAG;
*w1 += (*w2 - *w1) * MAG;
}
static GLuint glTransformClip(pvr_vertex_t *v, int count) {
pvr_vertex_t *V = v; pvr_vertex_t *V = v;
float3 *C = CLIP_BUF; float3 *C = CLIP_BUF;
GLuint in = 0; GLuint in = 0;
@ -85,13 +52,13 @@ static GLuint glTransformClip(pvr_vertex_t *v, int count) {
return in; return in;
} }
GLuint _glKosClipTriangleStrip(pvr_vertex_t *vin, pvr_vertex_t *vout, unsigned int vertices) { GLuint _glKosClipTriangleStrip(pvr_vertex_t *src, pvr_vertex_t *dst, GLuint vertices) {
GLuint i, v = 0, in = glTransformClip(vin, vertices); GLuint i, v = 0, in = _glKosTransformClip(src, vertices);
float3 *C = CLIP_BUF; float3 *C = CLIP_BUF;
if(in == vertices) { if(in == vertices) {
memcpy(vout, vin, vertices * 0x20); memcpy(dst, src, vertices * 0x20);
pvr_vertex_t *v = vout; pvr_vertex_t *v = dst;
while(--in) { while(--in) {
v->flags = PVR_CMD_VERTEX; v->flags = PVR_CMD_VERTEX;
@ -107,8 +74,8 @@ GLuint _glKosClipTriangleStrip(pvr_vertex_t *vin, pvr_vertex_t *vout, unsigned i
/* Iterate all Triangles of the Strip - Hence looping vertices-2 times */ /* Iterate all Triangles of the Strip - Hence looping vertices-2 times */
for(i = 0; i < ((vertices) - 2); i++) { for(i = 0; i < ((vertices) - 2); i++) {
unsigned short int clip = 0; /* Clip Code for current Triangle */ GLushort clip = 0; /* Clip Code for current Triangle */
unsigned char verts_in = 0; /* # of Verteices inside clip plane for current Triangle */ GLubyte verts_in = 0; /* # of Verteices inside clip plane for current Triangle */
C->z >= CLIP_NEARZ ? clip |= FIRST : ++verts_in; C->z >= CLIP_NEARZ ? clip |= FIRST : ++verts_in;
(C + 1)->z >= CLIP_NEARZ ? clip |= SECOND : ++verts_in; (C + 1)->z >= CLIP_NEARZ ? clip |= SECOND : ++verts_in;
@ -119,39 +86,39 @@ GLuint _glKosClipTriangleStrip(pvr_vertex_t *vin, pvr_vertex_t *vout, unsigned i
break; break;
case 3: /* All Vertices of Triangle are inside of clip plne */ case 3: /* All Vertices of Triangle are inside of clip plne */
memcpy(&vout[v], &vin[i], 96); memcpy(&dst[v], &src[i], 96);
vout[v].flags = vout[v + 1].flags = PVR_CMD_VERTEX; dst[v].flags = dst[v + 1].flags = PVR_CMD_VERTEX;
vout[v + 2].flags = PVR_CMD_VERTEX_EOL; dst[v + 2].flags = PVR_CMD_VERTEX_EOL;
v += 3; v += 3;
break; break;
case 1:/* 1 Vertex of Triangle is inside of clip plane = output 1 Triangle */ case 1:/* 1 Vertex of Triangle is inside of clip plane = output 1 Triangle */
memcpy(&vout[v], &vin[i], 96); memcpy(&dst[v], &src[i], 96);
switch(clip) { switch(clip) {
case FIRST_TWO_OUT: case FIRST_TWO_OUT:
glVertexClipZNear(&vout[v], &vout[v + 2], ZclipMag(&CLIP_BUF[i], &CLIP_BUF[i + 2])); _glKosVertexClipZNear(&dst[v], &dst[v + 2], _glKosNearZClipMag(&CLIP_BUF[i], &CLIP_BUF[i + 2]));
glVertexClipZNear(&vout[v + 1], &vout[v + 2], ZclipMag(&CLIP_BUF[i + 1], &CLIP_BUF[i + 2])); _glKosVertexClipZNear(&dst[v + 1], &dst[v + 2], _glKosNearZClipMag(&CLIP_BUF[i + 1], &CLIP_BUF[i + 2]));
break; break;
case FIRST_AND_LAST_OUT: case FIRST_AND_LAST_OUT:
glVertexClipZNear(&vout[v], &vout[v + 1], ZclipMag(&CLIP_BUF[i], &CLIP_BUF[i + 1])); _glKosVertexClipZNear(&dst[v], &dst[v + 1], _glKosNearZClipMag(&CLIP_BUF[i], &CLIP_BUF[i + 1]));
glVertexClipZNear(&vout[v + 2], &vout[v + 1], ZclipMag(&CLIP_BUF[i + 2], &CLIP_BUF[i + 1])); _glKosVertexClipZNear(&dst[v + 2], &dst[v + 1], _glKosNearZClipMag(&CLIP_BUF[i + 2], &CLIP_BUF[i + 1]));
break; break;
case LAST_TWO_OUT: case LAST_TWO_OUT:
glVertexClipZNear(&vout[v + 1], &vout[v], ZclipMag(&CLIP_BUF[i + 1], &CLIP_BUF[i + 0])); _glKosVertexClipZNear(&dst[v + 1], &dst[v], _glKosNearZClipMag(&CLIP_BUF[i + 1], &CLIP_BUF[i + 0]));
glVertexClipZNear(&vout[v + 2], &vout[v], ZclipMag(&CLIP_BUF[i + 2], &CLIP_BUF[i + 0])); _glKosVertexClipZNear(&dst[v + 2], &dst[v], _glKosNearZClipMag(&CLIP_BUF[i + 2], &CLIP_BUF[i + 0]));
break; break;
} }
vout[v].flags = vout[v + 1].flags = PVR_CMD_VERTEX; dst[v].flags = dst[v + 1].flags = PVR_CMD_VERTEX;
vout[v + 2].flags = PVR_CMD_VERTEX_EOL; dst[v + 2].flags = PVR_CMD_VERTEX_EOL;
v += 3; v += 3;
break; break;
@ -159,35 +126,35 @@ GLuint _glKosClipTriangleStrip(pvr_vertex_t *vin, pvr_vertex_t *vout, unsigned i
case 2:/* 2 Vertices of Triangle are inside of clip plane = output 2 Triangles */ case 2:/* 2 Vertices of Triangle are inside of clip plane = output 2 Triangles */
switch(clip) { switch(clip) {
case FIRST: case FIRST:
glVertexCopyPVR(&vin[i + 0], &vout[v + 0]); _glKosVertexCopyPVR(&src[i + 0], &dst[v + 0]);
glVertexCopyPVR(&vin[i + 1], &vout[v + 1]); _glKosVertexCopyPVR(&src[i + 1], &dst[v + 1]);
glVertexCopyPVR(&vin[i + 0], &vout[v + 2]); _glKosVertexCopyPVR(&src[i + 0], &dst[v + 2]);
glVertexCopyPVR(&vin[i + 2], &vout[v + 3]); _glKosVertexCopyPVR(&src[i + 2], &dst[v + 3]);
glVertexClipZNear(&vout[v + 0], &vout[v + 1], ZclipMag(&CLIP_BUF[i], &CLIP_BUF[i + 1])); _glKosVertexClipZNear(&dst[v + 0], &dst[v + 1], _glKosNearZClipMag(&CLIP_BUF[i], &CLIP_BUF[i + 1]));
glVertexClipZNear(&vout[v + 2], &vout[v + 3], ZclipMag(&CLIP_BUF[i], &CLIP_BUF[i + 2])); _glKosVertexClipZNear(&dst[v + 2], &dst[v + 3], _glKosNearZClipMag(&CLIP_BUF[i], &CLIP_BUF[i + 2]));
break; break;
case SECOND: case SECOND:
glVertexCopyPVR(&vin[i + 1], &vout[v + 0]); _glKosVertexCopyPVR(&src[i + 1], &dst[v + 0]);
glVertexCopyPVR(&vin[i + 0], &vout[v + 1]); _glKosVertexCopyPVR(&src[i + 0], &dst[v + 1]);
glVertexCopyPVR(&vin[i + 1], &vout[v + 2]); _glKosVertexCopyPVR(&src[i + 1], &dst[v + 2]);
glVertexCopyPVR(&vin[i + 2], &vout[v + 3]); _glKosVertexCopyPVR(&src[i + 2], &dst[v + 3]);
glVertexClipZNear(&vout[v + 0], &vout[v + 1], ZclipMag(&CLIP_BUF[i + 1], &CLIP_BUF[i + 0])); _glKosVertexClipZNear(&dst[v + 0], &dst[v + 1], _glKosNearZClipMag(&CLIP_BUF[i + 1], &CLIP_BUF[i + 0]));
glVertexClipZNear(&vout[v + 2], &vout[v + 3], ZclipMag(&CLIP_BUF[i + 1], &CLIP_BUF[i + 2])); _glKosVertexClipZNear(&dst[v + 2], &dst[v + 3], _glKosNearZClipMag(&CLIP_BUF[i + 1], &CLIP_BUF[i + 2]));
break; break;
case THIRD: case THIRD:
glVertexCopyPVR(&vin[i + 2], &vout[v + 0]); _glKosVertexCopyPVR(&src[i + 2], &dst[v + 0]);
glVertexCopyPVR(&vin[i + 0], &vout[v + 1]); _glKosVertexCopyPVR(&src[i + 0], &dst[v + 1]);
glVertexCopyPVR(&vin[i + 2], &vout[v + 2]); _glKosVertexCopyPVR(&src[i + 2], &dst[v + 2]);
glVertexCopyPVR(&vin[i + 1], &vout[v + 3]); _glKosVertexCopyPVR(&src[i + 1], &dst[v + 3]);
glVertexClipZNear(&vout[v + 0], &vout[v + 1], ZclipMag(&CLIP_BUF[i + 2], &CLIP_BUF[i])); _glKosVertexClipZNear(&dst[v + 0], &dst[v + 1], _glKosNearZClipMag(&CLIP_BUF[i + 2], &CLIP_BUF[i]));
glVertexClipZNear(&vout[v + 2], &vout[v + 3], ZclipMag(&CLIP_BUF[i + 2], &CLIP_BUF[i + 1])); _glKosVertexClipZNear(&dst[v + 2], &dst[v + 3], _glKosNearZClipMag(&CLIP_BUF[i + 2], &CLIP_BUF[i + 1]));
break; break;
} }
vout[v + 0].flags = vout[v + 1].flags = vout[v + 2].flags = PVR_CMD_VERTEX; dst[v + 0].flags = dst[v + 1].flags = dst[v + 2].flags = PVR_CMD_VERTEX;
vout[v + 3].flags = PVR_CMD_VERTEX_EOL; dst[v + 3].flags = PVR_CMD_VERTEX_EOL;
v += 4; v += 4;
break; break;
@ -199,16 +166,16 @@ GLuint _glKosClipTriangleStrip(pvr_vertex_t *vin, pvr_vertex_t *vout, unsigned i
return v; return v;
} }
static inline unsigned char _glKosClipTri(pvr_vertex_t *vin, pvr_vertex_t *vout) { static inline unsigned char _glKosClipTri(pvr_vertex_t *src, pvr_vertex_t *dst) {
unsigned short int clip = 0; /* Clip Code for current Triangle */ GLushort clip = 0; /* Clip Code for current Triangle */
unsigned char verts_in = 0; /* # of Vertices inside clip plane 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 */ float3 clip_buf[3]; /* Store the Vertices for each Triangle Translated into Clip Space */
/* Transform all 3 Vertices of Triangle */ /* Transform all 3 Vertices of Triangle */
{ {
register float __x __asm__("fr12") = vin->x; register float __x __asm__("fr12") = src->x;
register float __y __asm__("fr13") = vin->y; register float __y __asm__("fr13") = src->y;
register float __z __asm__("fr14") = vin->z; register float __z __asm__("fr14") = src->z;
mat_trans_fv12_nodiv(); mat_trans_fv12_nodiv();
@ -216,9 +183,9 @@ static inline unsigned char _glKosClipTri(pvr_vertex_t *vin, pvr_vertex_t *vout)
clip_buf[0].y = __y; clip_buf[0].y = __y;
clip_buf[0].z = __z; clip_buf[0].z = __z;
__x = (vin + 1)->x; __x = (src + 1)->x;
__y = (vin + 1)->y; __y = (src + 1)->y;
__z = (vin + 1)->z; __z = (src + 1)->z;
mat_trans_fv12_nodiv(); mat_trans_fv12_nodiv();
@ -226,9 +193,9 @@ static inline unsigned char _glKosClipTri(pvr_vertex_t *vin, pvr_vertex_t *vout)
clip_buf[1].y = __y; clip_buf[1].y = __y;
clip_buf[1].z = __z; clip_buf[1].z = __z;
__x = (vin + 2)->x; __x = (src + 2)->x;
__y = (vin + 2)->y; __y = (src + 2)->y;
__z = (vin + 2)->z; __z = (src + 2)->z;
mat_trans_fv12_nodiv(); mat_trans_fv12_nodiv();
@ -247,71 +214,71 @@ static inline unsigned char _glKosClipTri(pvr_vertex_t *vin, pvr_vertex_t *vout)
return 0; return 0;
case 3: /* All Vertices of Triangle are inside of clip plne */ case 3: /* All Vertices of Triangle are inside of clip plne */
memcpy(vout, vin, 96); memcpy(dst, src, 96);
vout->flags = (vout + 1)->flags = PVR_CMD_VERTEX; dst->flags = (dst + 1)->flags = PVR_CMD_VERTEX;
(vout + 2)->flags = PVR_CMD_VERTEX_EOL; (dst + 2)->flags = PVR_CMD_VERTEX_EOL;
return 3; return 3;
case 1:/* 1 Vertex of Triangle is inside of clip plane = output 1 Triangle */ case 1:/* 1 Vertex of Triangle is inside of clip plane = output 1 Triangle */
memcpy(vout, vin, 96); memcpy(dst, src, 96);
switch(clip) { switch(clip) {
case FIRST_TWO_OUT: case FIRST_TWO_OUT:
glVertexClipZNear(vout, vout + 2, ZclipMag(&clip_buf[0], &clip_buf[2])); _glKosVertexClipZNear(dst, dst + 2, _glKosNearZClipMag(&clip_buf[0], &clip_buf[2]));
glVertexClipZNear(vout + 1, vout + 2, ZclipMag(&clip_buf[1], &clip_buf[2])); _glKosVertexClipZNear(dst + 1, dst + 2, _glKosNearZClipMag(&clip_buf[1], &clip_buf[2]));
break; break;
case FIRST_AND_LAST_OUT: case FIRST_AND_LAST_OUT:
glVertexClipZNear(vout, vout + 1, ZclipMag(&clip_buf[0], &clip_buf[1])); _glKosVertexClipZNear(dst, dst + 1, _glKosNearZClipMag(&clip_buf[0], &clip_buf[1]));
glVertexClipZNear(vout + 2, vout + 1, ZclipMag(&clip_buf[2], &clip_buf[1])); _glKosVertexClipZNear(dst + 2, dst + 1, _glKosNearZClipMag(&clip_buf[2], &clip_buf[1]));
break; break;
case LAST_TWO_OUT: case LAST_TWO_OUT:
glVertexClipZNear(vout + 1, vout, ZclipMag(&clip_buf[1], &clip_buf[0])); _glKosVertexClipZNear(dst + 1, dst, _glKosNearZClipMag(&clip_buf[1], &clip_buf[0]));
glVertexClipZNear(vout + 2, vout, ZclipMag(&clip_buf[2], &clip_buf[0])); _glKosVertexClipZNear(dst + 2, dst, _glKosNearZClipMag(&clip_buf[2], &clip_buf[0]));
break; break;
} }
vout->flags = (vout + 1)->flags = PVR_CMD_VERTEX; dst->flags = (dst + 1)->flags = PVR_CMD_VERTEX;
(vout + 2)->flags = PVR_CMD_VERTEX_EOL; (dst + 2)->flags = PVR_CMD_VERTEX_EOL;
return 3; return 3;
case 2:/* 2 Vertices of Triangle are inside of clip plane = output 2 Triangles */ case 2:/* 2 Vertices of Triangle are inside of clip plane = output 2 Triangles */
switch(clip) { switch(clip) {
case FIRST: case FIRST:
memcpy(vout, vin, 64); memcpy(dst, src, 64);
glVertexCopyPVR(vin, vout + 2); _glKosVertexCopyPVR(src, dst + 2);
glVertexCopyPVR(vin + 2, vout + 3); _glKosVertexCopyPVR(src + 2, dst + 3);
glVertexClipZNear(vout, vout + 1, ZclipMag(&clip_buf[0], &clip_buf[1])); _glKosVertexClipZNear(dst, dst + 1, _glKosNearZClipMag(&clip_buf[0], &clip_buf[1]));
glVertexClipZNear(vout + 2, vout + 3, ZclipMag(&clip_buf[0], &clip_buf[2])); _glKosVertexClipZNear(dst + 2, dst + 3, _glKosNearZClipMag(&clip_buf[0], &clip_buf[2]));
break; break;
case SECOND: case SECOND:
glVertexCopyPVR(vin + 1, vout); _glKosVertexCopyPVR(src + 1, dst);
glVertexCopyPVR(vin, vout + 1); _glKosVertexCopyPVR(src, dst + 1);
memcpy(vout + 2, vin + 1, 64); memcpy(dst + 2, src + 1, 64);
glVertexClipZNear(vout, vout + 1, ZclipMag(&clip_buf[1], &clip_buf[0])); _glKosVertexClipZNear(dst, dst + 1, _glKosNearZClipMag(&clip_buf[1], &clip_buf[0]));
glVertexClipZNear(vout + 2, vout + 3, ZclipMag(&clip_buf[1], &clip_buf[2])); _glKosVertexClipZNear(dst + 2, dst + 3, _glKosNearZClipMag(&clip_buf[1], &clip_buf[2]));
break; break;
case THIRD: case THIRD:
glVertexCopyPVR(vin + 2, vout); _glKosVertexCopyPVR(src + 2, dst);
glVertexCopyPVR(vin, vout + 1); _glKosVertexCopyPVR(src, dst + 1);
glVertexCopyPVR(vin + 2, vout + 2); _glKosVertexCopyPVR(src + 2, dst + 2);
glVertexCopyPVR(vin + 1, vout + 3); _glKosVertexCopyPVR(src + 1, dst + 3);
glVertexClipZNear(vout, vout + 1, ZclipMag(&clip_buf[2], &clip_buf[0])); _glKosVertexClipZNear(dst, dst + 1, _glKosNearZClipMag(&clip_buf[2], &clip_buf[0]));
glVertexClipZNear(vout + 2, vout + 3, ZclipMag(&clip_buf[2], &clip_buf[1])); _glKosVertexClipZNear(dst + 2, dst + 3, _glKosNearZClipMag(&clip_buf[2], &clip_buf[1]));
break; break;
} }
vout->flags = (vout + 1)->flags = (vout + 2)->flags = PVR_CMD_VERTEX; dst->flags = (dst + 1)->flags = (dst + 2)->flags = PVR_CMD_VERTEX;
(vout + 3)->flags = PVR_CMD_VERTEX_EOL; (dst + 3)->flags = PVR_CMD_VERTEX_EOL;
return 4; return 4;
} }
@ -319,426 +286,24 @@ static inline unsigned char _glKosClipTri(pvr_vertex_t *vin, pvr_vertex_t *vout)
return 0; return 0;
} }
unsigned int _glKosClipTriangles(pvr_vertex_t *vin, pvr_vertex_t *vout, unsigned int vertices) { GLuint _glKosClipTriangles(pvr_vertex_t *src, pvr_vertex_t *dst, GLuint vertices) {
unsigned int i, v = 0; GLuint i, v = 0;
for(i = 0; i < vertices; i += 3) /* Iterate all Triangles */ for(i = 0; i < vertices; i += 3) /* Iterate all Triangles */
v += _glKosClipTri(vin + i, vout + v); v += _glKosClipTri(src + i, dst + v);
return v; return v;
} }
unsigned int _glKosClipQuads(pvr_vertex_t *vin, pvr_vertex_t *vout, unsigned int vertices) { GLuint _glKosClipQuads(pvr_vertex_t *src, pvr_vertex_t *dst, GLuint vertices) {
unsigned int i, v = 0; GLuint i, v = 0;
pvr_vertex_t qv; pvr_vertex_t qv;
for(i = 0; i < vertices; i += 4) { /* Iterate all Quads, Rearranging into Triangle Strips */ for(i = 0; i < vertices; i += 4) { /* Iterate all Quads, Rearranging into Triangle Strips */
glVertexCopyPVR(vin + i + 3, &qv); _glKosVertexCopyPVR(src + i + 3, &qv);
glVertexCopyPVR(vin + i + 2, vin + i + 3); _glKosVertexCopyPVR(src + i + 2, src + i + 3);
glVertexCopyPVR(&qv, vin + i + 2); _glKosVertexCopyPVR(&qv, src + i + 2);
v += _glKosClipTriangleStrip(vin + i, vout + v, 4); v += _glKosClipTriangleStrip(src + i, dst + v, 4);
}
return v;
}
static inline void _glKosVertexPerspectiveDivide(pvr_vertex_t *dst, float w) {
dst->z = 1.0f / w;
dst->x *= dst->z;
dst->y *= dst->z;
}
GLuint _glKosClipTrianglesTransformed(pvr_vertex_t *src, float *w, pvr_vertex_t *dst, GLuint count) {
pvr_vertex_t *vin = src;
pvr_vertex_t *vout = dst;
unsigned short int clip;
unsigned char verts_in = 0;
GLuint verts_out = 0;
GLuint i;
for(i = 0; i < count; i += 3) {
clip = 0; /* Clip Code for current Triangle */
verts_in = 0; /* # of Vertices inside clip plane for current Triangle */
float W[4] = { w[i], w[i + 1], w[i + 2] }; /* W Component for Perspective Divide */
(vin[0].z >= CLIP_NEARZ) ? clip |= FIRST : ++verts_in;
(vin[1].z >= CLIP_NEARZ) ? clip |= SECOND : ++verts_in;
(vin[2].z >= CLIP_NEARZ) ? clip |= THIRD : ++verts_in;
switch(verts_in) { /* Start by examining # of vertices inside clip plane */
case 0: /* All Vertices of Triangle are Outside of clip plne */
break;
case 3: /* All Vertices of Triangle are inside of clip plne */
_glKosVertexCopyPVR(&vin[0], &vout[0]);
_glKosVertexCopyPVR(&vin[1], &vout[1]);
_glKosVertexCopyPVR(&vin[2], &vout[2]);
_glKosVertexPerspectiveDivide(&vout[0], W[0]);
_glKosVertexPerspectiveDivide(&vout[1], W[1]);
_glKosVertexPerspectiveDivide(&vout[2], W[2]);
vout[0].flags = vout[1].flags = PVR_CMD_VERTEX;
vout[2].flags = PVR_CMD_VERTEX_EOL;
vout += 3;
verts_out += 3;
break;
case 1:/* 1 Vertex of Triangle is inside of clip plane = output 1 Triangle */
_glKosVertexCopyPVR(&vin[0], &vout[0]);
_glKosVertexCopyPVR(&vin[1], &vout[1]);
_glKosVertexCopyPVR(&vin[2], &vout[2]);
switch(clip) {
case FIRST_TWO_OUT:
_glKosVertexClipZNear3(&vout[0], &vout[2], &W[0], &W[2]);
_glKosVertexClipZNear3(&vout[1], &vout[2], &W[1], &W[2]);
break;
case FIRST_AND_LAST_OUT:
_glKosVertexClipZNear3(&vout[0], &vout[1], &W[0], &W[1]);
_glKosVertexClipZNear3(&vout[2], &vout[1], &W[2], &W[1]);
break;
case LAST_TWO_OUT:
_glKosVertexClipZNear3(&vout[1], &vout[0], &W[1], &W[0]);
_glKosVertexClipZNear3(&vout[2], &vout[0], &W[2], &W[0]);
break;
}
_glKosVertexPerspectiveDivide(&vout[0], W[0]);
_glKosVertexPerspectiveDivide(&vout[1], W[1]);
_glKosVertexPerspectiveDivide(&vout[2], W[2]);
vout[0].flags = vout[1].flags = PVR_CMD_VERTEX;
vout[2].flags = PVR_CMD_VERTEX_EOL;
vout += 3;
verts_out += 3;
break;
case 2:/* 2 Vertices of Triangle are inside of clip plane = output 2 Triangles */
switch(clip) {
case FIRST:
_glKosVertexCopyPVR(&vin[0], &vout[0]);
_glKosVertexCopyPVR(&vin[1], &vout[1]);
_glKosVertexCopyPVR(&vin[0], &vout[2]);
_glKosVertexCopyPVR(&vin[2], &vout[3]);
W[3] = W[2];
W[2] = W[0];
break;
case SECOND:
_glKosVertexCopyPVR(&vin[1], &vout[0]);
_glKosVertexCopyPVR(&vin[2], &vout[1]);
_glKosVertexCopyPVR(&vin[1], &vout[2]);
_glKosVertexCopyPVR(&vin[0], &vout[3]);
W[3] = W[0];
W[0] = W[1];
W[1] = W[2];
W[2] = W[0];
break;
case THIRD:
_glKosVertexCopyPVR(&vin[2], &vout[0]);
_glKosVertexCopyPVR(&vin[0], &vout[1]);
_glKosVertexCopyPVR(&vin[2], &vout[2]);
_glKosVertexCopyPVR(&vin[1], &vout[3]);
W[3] = W[1];
W[1] = W[0];
W[0] = W[2];
break;
}
_glKosVertexClipZNear3(&vout[0], &vout[1], &W[0], &W[1]);
_glKosVertexClipZNear3(&vout[2], &vout[3], &W[2], &W[3]);
_glKosVertexPerspectiveDivide(&vout[0], W[0]);
_glKosVertexPerspectiveDivide(&vout[1], W[1]);
_glKosVertexPerspectiveDivide(&vout[2], W[2]);
_glKosVertexPerspectiveDivide(&vout[3], W[3]);
vout[0].flags = vout[1].flags = vout[2].flags = PVR_CMD_VERTEX;
vout[3].flags = PVR_CMD_VERTEX_EOL;
vout += 4;
verts_out += 4;
break;
}
vin += 3;
}
return verts_out;
}
GLuint _glKosClipTriangleStripTransformed(pvr_vertex_t *src, float *w, pvr_vertex_t *dst, GLuint count) {
pvr_vertex_t *vin = src;
pvr_vertex_t *vout = dst;
unsigned short int clip;
unsigned char verts_in = 0;
GLuint verts_out = 0;
GLuint i;
for(i = 0; i < (count - 2); i ++) {
clip = 0; /* Clip Code for current Triangle */
verts_in = 0; /* # of Vertices inside clip plane for current Triangle */
float W[4] = { w[i], w[i + 1], w[i + 2] }; /* W Component for Perspective Divide */
(vin[0].z >= CLIP_NEARZ) ? clip |= FIRST : ++verts_in;
(vin[1].z >= CLIP_NEARZ) ? clip |= SECOND : ++verts_in;
(vin[2].z >= CLIP_NEARZ) ? clip |= THIRD : ++verts_in;
switch(verts_in) { /* Start by examining # of vertices inside clip plane */
case 0: /* All Vertices of Triangle are Outside of clip plne */
break;
case 3: /* All Vertices of Triangle are inside of clip plne */
_glKosVertexCopyPVR(&vin[0], &vout[0]);
_glKosVertexCopyPVR(&vin[1], &vout[1]);
_glKosVertexCopyPVR(&vin[2], &vout[2]);
_glKosVertexPerspectiveDivide(&vout[0], W[0]);
_glKosVertexPerspectiveDivide(&vout[1], W[1]);
_glKosVertexPerspectiveDivide(&vout[2], W[2]);
vout[0].flags = vout[1].flags = PVR_CMD_VERTEX;
vout[2].flags = PVR_CMD_VERTEX_EOL;
vout += 3;
verts_out += 3;
break;
case 1:/* 1 Vertex of Triangle is inside of clip plane = output 1 Triangle */
_glKosVertexCopyPVR(&vin[0], &vout[0]);
_glKosVertexCopyPVR(&vin[1], &vout[1]);
_glKosVertexCopyPVR(&vin[2], &vout[2]);
switch(clip) {
case FIRST_TWO_OUT:
_glKosVertexClipZNear3(&vout[0], &vout[2], &W[0], &W[2]);
_glKosVertexClipZNear3(&vout[1], &vout[2], &W[1], &W[2]);
break;
case FIRST_AND_LAST_OUT:
_glKosVertexClipZNear3(&vout[0], &vout[1], &W[0], &W[1]);
_glKosVertexClipZNear3(&vout[2], &vout[1], &W[2], &W[1]);
break;
case LAST_TWO_OUT:
_glKosVertexClipZNear3(&vout[1], &vout[0], &W[1], &W[0]);
_glKosVertexClipZNear3(&vout[2], &vout[0], &W[2], &W[0]);
break;
}
_glKosVertexPerspectiveDivide(&vout[0], W[0]);
_glKosVertexPerspectiveDivide(&vout[1], W[1]);
_glKosVertexPerspectiveDivide(&vout[2], W[2]);
vout[0].flags = vout[1].flags = PVR_CMD_VERTEX;
vout[2].flags = PVR_CMD_VERTEX_EOL;
vout += 3;
verts_out += 3;
break;
case 2:/* 2 Vertices of Triangle are inside of clip plane = output 2 Triangles */
switch(clip) {
case FIRST:
_glKosVertexCopyPVR(&vin[0], &vout[0]);
_glKosVertexCopyPVR(&vin[1], &vout[1]);
_glKosVertexCopyPVR(&vin[0], &vout[2]);
_glKosVertexCopyPVR(&vin[2], &vout[3]);
W[3] = W[2];
W[2] = W[0];
break;
case SECOND:
_glKosVertexCopyPVR(&vin[1], &vout[0]);
_glKosVertexCopyPVR(&vin[2], &vout[1]);
_glKosVertexCopyPVR(&vin[1], &vout[2]);
_glKosVertexCopyPVR(&vin[0], &vout[3]);
W[3] = W[0];
W[0] = W[1];
W[1] = W[2];
W[2] = W[0];
break;
case THIRD:
_glKosVertexCopyPVR(&vin[2], &vout[0]);
_glKosVertexCopyPVR(&vin[0], &vout[1]);
_glKosVertexCopyPVR(&vin[2], &vout[2]);
_glKosVertexCopyPVR(&vin[1], &vout[3]);
W[3] = W[1];
W[1] = W[0];
W[0] = W[2];
break;
}
_glKosVertexClipZNear3(&vout[0], &vout[1], &W[0], &W[1]);
_glKosVertexClipZNear3(&vout[2], &vout[3], &W[2], &W[3]);
_glKosVertexPerspectiveDivide(&vout[0], W[0]);
_glKosVertexPerspectiveDivide(&vout[1], W[1]);
_glKosVertexPerspectiveDivide(&vout[2], W[2]);
_glKosVertexPerspectiveDivide(&vout[3], W[3]);
vout[0].flags = vout[1].flags = vout[2].flags = PVR_CMD_VERTEX;
vout[3].flags = PVR_CMD_VERTEX_EOL;
vout += 4;
verts_out += 4;
break;
}
++vin;
}
return verts_out;
}
GLubyte _glKosClipTriTransformed(pvr_vertex_t *vin, float *w, pvr_vertex_t *vout) {
unsigned short int clip = 0; /* Clip Code for current Triangle */
unsigned char verts_in = 0; /* # of Vertices inside clip plane for current Triangle */
float W[4] = { w[0], w[1], w[2] }; /* W Component for Perspective Divide */
(vin[0].z >= CLIP_NEARZ) ? clip |= FIRST : ++verts_in;
(vin[1].z >= CLIP_NEARZ) ? clip |= SECOND : ++verts_in;
(vin[2].z >= CLIP_NEARZ) ? clip |= THIRD : ++verts_in;
switch(verts_in) { /* Start by examining # of vertices inside clip plane */
case 0: /* All Vertices of Triangle are Outside of clip plne */
return 0;
case 3: /* All Vertices of Triangle are inside of clip plne */
_glKosVertexCopyPVR(&vin[0], &vout[0]);
_glKosVertexCopyPVR(&vin[1], &vout[1]);
_glKosVertexCopyPVR(&vin[2], &vout[2]);
_glKosVertexPerspectiveDivide(&vout[0], W[0]);
_glKosVertexPerspectiveDivide(&vout[1], W[1]);
_glKosVertexPerspectiveDivide(&vout[2], W[2]);
vout[0].flags = vout[1].flags = PVR_CMD_VERTEX;
vout[2].flags = PVR_CMD_VERTEX_EOL;
return 3;
case 1:/* 1 Vertex of Triangle is inside of clip plane = output 1 Triangle */
_glKosVertexCopyPVR(&vin[0], &vout[0]);
_glKosVertexCopyPVR(&vin[1], &vout[1]);
_glKosVertexCopyPVR(&vin[2], &vout[2]);
switch(clip) {
case FIRST_TWO_OUT:
_glKosVertexClipZNear3(&vout[0], &vout[2], &W[0], &W[2]);
_glKosVertexClipZNear3(&vout[1], &vout[2], &W[1], &W[2]);
break;
case FIRST_AND_LAST_OUT:
_glKosVertexClipZNear3(&vout[0], &vout[1], &W[0], &W[1]);
_glKosVertexClipZNear3(&vout[2], &vout[1], &W[2], &W[1]);
break;
case LAST_TWO_OUT:
_glKosVertexClipZNear3(&vout[1], &vout[0], &W[1], &W[0]);
_glKosVertexClipZNear3(&vout[2], &vout[0], &W[2], &W[0]);
break;
}
_glKosVertexPerspectiveDivide(&vout[0], W[0]);
_glKosVertexPerspectiveDivide(&vout[1], W[1]);
_glKosVertexPerspectiveDivide(&vout[2], W[2]);
vout[0].flags = vout[1].flags = PVR_CMD_VERTEX;
vout[2].flags = PVR_CMD_VERTEX_EOL;
return 3;
case 2:/* 2 Vertices of Triangle are inside of clip plane = output 2 Triangles */
switch(clip) {
case FIRST:
_glKosVertexCopyPVR(&vin[0], &vout[0]);
_glKosVertexCopyPVR(&vin[1], &vout[1]);
_glKosVertexCopyPVR(&vin[0], &vout[2]);
_glKosVertexCopyPVR(&vin[2], &vout[3]);
W[3] = W[2];
W[2] = W[0];
break;
case SECOND:
_glKosVertexCopyPVR(&vin[1], &vout[0]);
_glKosVertexCopyPVR(&vin[2], &vout[1]);
_glKosVertexCopyPVR(&vin[1], &vout[2]);
_glKosVertexCopyPVR(&vin[0], &vout[3]);
W[3] = W[0];
W[0] = W[1];
W[1] = W[2];
W[2] = W[0];
break;
case THIRD:
_glKosVertexCopyPVR(&vin[2], &vout[0]);
_glKosVertexCopyPVR(&vin[0], &vout[1]);
_glKosVertexCopyPVR(&vin[2], &vout[2]);
_glKosVertexCopyPVR(&vin[1], &vout[3]);
W[3] = W[1];
W[1] = W[0];
W[0] = W[2];
break;
}
_glKosVertexClipZNear3(&vout[0], &vout[1], &W[0], &W[1]);
_glKosVertexClipZNear3(&vout[2], &vout[3], &W[2], &W[3]);
_glKosVertexPerspectiveDivide(&vout[0], W[0]);
_glKosVertexPerspectiveDivide(&vout[1], W[1]);
_glKosVertexPerspectiveDivide(&vout[2], W[2]);
_glKosVertexPerspectiveDivide(&vout[3], W[3]);
vout[0].flags = vout[1].flags = vout[2].flags = PVR_CMD_VERTEX;
vout[3].flags = PVR_CMD_VERTEX_EOL;
return 4;
}
return 0;
}
unsigned int _glKosClipQuadsTransformed(pvr_vertex_t *vin, float *w, pvr_vertex_t *vout, unsigned int vertices) {
unsigned int i, v = 0;
pvr_vertex_t qv[3];
float W[3];
for(i = 0; i < vertices; i += 4) { /* Iterate all Quads, Rearranging into Triangle Strips */
_glKosVertexCopyPVR(&vin[i + 0], &qv[0]);
_glKosVertexCopyPVR(&vin[i + 2], &qv[1]);
_glKosVertexCopyPVR(&vin[i + 3], &qv[2]);
W[0] = w[0];
W[1] = w[2];
W[2] = w[3];
v += _glKosClipTriTransformed(&vin[i], &w[i], &vout[v]);
v += _glKosClipTriTransformed(&qv[i], &W[i], &vout[v]);
} }
return v; return v;

View File

@ -31,7 +31,7 @@
#define GREEN 0x0000FF00 #define GREEN 0x0000FF00
#define BLUE 0x000000FF #define BLUE 0x000000FF
#define CLIP_NEARZ -0.5f /* Clip Threshold */ #define CLIP_NEARZ -0.20f /* Clip Threshold */
typedef struct { typedef struct {
float x, y, z; float x, y, z;
@ -41,4 +41,12 @@ typedef struct {
unsigned char b, g, r, a; unsigned char b, g, r, a;
} colorui; } 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 #endif

View File

@ -68,8 +68,7 @@ void _glKosInitLighting() { /* Called internally by glInit() */
/* Enable a light - GL_LIGHT0->GL_LIGHT7 */ /* Enable a light - GL_LIGHT0->GL_LIGHT7 */
void _glKosEnableLight(const GLuint light) { void _glKosEnableLight(const GLuint light) {
if(light < GL_LIGHT0 || light > GL_LIGHT0 + GL_KOS_MAX_LIGHTS) if(light < GL_LIGHT0 || light > GL_LIGHT0 + GL_KOS_MAX_LIGHTS) {
{
_glKosThrowError(GL_INVALID_ENUM, "glEnable(GL_LIGHT)"); _glKosThrowError(GL_INVALID_ENUM, "glEnable(GL_LIGHT)");
return; return;
} }
@ -79,8 +78,7 @@ void _glKosEnableLight(const GLuint light) {
/* Disable a light - GL_LIGHT0->GL_LIGHT7 */ /* Disable a light - GL_LIGHT0->GL_LIGHT7 */
void _glKosDisableLight(const GLuint light) { void _glKosDisableLight(const GLuint light) {
if(light < GL_LIGHT0 || light > GL_LIGHT0 + GL_KOS_MAX_LIGHTS) if(light < GL_LIGHT0 || light > GL_LIGHT0 + GL_KOS_MAX_LIGHTS) {
{
_glKosThrowError(GL_INVALID_ENUM, "glDisable(GL_LIGHT)"); _glKosThrowError(GL_INVALID_ENUM, "glDisable(GL_LIGHT)");
return; return;
} }

View File

@ -105,8 +105,7 @@ void glLoadIdentity() {
mat_load(Matrix + GL_IDENTITY); mat_load(Matrix + GL_IDENTITY);
mat_store(Matrix + MatrixMode); mat_store(Matrix + MatrixMode);
if(MatrixMode == GL_MODELVIEW) if(MatrixMode == GL_MODELVIEW) {
{
mat_store(&MatrixMdlRot); mat_store(&MatrixMdlRot);
mat_store(&MatrixLookAt); mat_store(&MatrixLookAt);
} }

119
gl-pvr.c
View File

@ -15,7 +15,7 @@
The size of the Vertex Buffer can be controlled by setting some params on gl-pvr.h: 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_PVR_VERTEX_BUF_SIZE controls size of Vertex Buffer in the PVR VRAM
GL_MAX_VERTS conrols the number of vertices per list in the Vertex Buffer in SH4 RAM GL_KOS_MAX_VERTS conrols the number of vertices per list in the Vertex Buffer in SH4 RAM
*/ */
#include <malloc.h> #include <malloc.h>
@ -30,22 +30,30 @@
/* Vertex Buffer Functions *************************************************************************/ /* Vertex Buffer Functions *************************************************************************/
#ifdef GL_USE_MALLOC #ifdef GL_KOS_USE_MALLOC
static pvr_cmd_t *GL_VBUF[2] __attribute__((aligned(32))); /* Dynamic Vertex Buffer */ static pvr_cmd_t *GL_VBUF[2] __attribute__((aligned(32))); /* Dynamic Vertex Buffer */
static pvr_cmd_t *GL_CBUF; /* Dynamic Clip Buffer */ static pvr_cmd_t *GL_CBUF; /* Dynamic Clip Buffer */
static glTexCoord *GL_UVBUF; /* Dynamic Multi-Texture UV Buffer */
#else #else
static pvr_cmd_t GL_VBUF[2][GL_MAX_VERTS] __attribute__((aligned(32))); /* Static Vertex Buffer */ static pvr_cmd_t GL_VBUF[2][GL_KOS_MAX_VERTS] __attribute__((aligned(32))); /* Static Vertex Buffer */
static pvr_cmd_t GL_CBUF[GL_MAX_VERTS / 2]; /* Static Clip Buffer */ static pvr_cmd_t GL_CBUF[GL_KOS_MAX_VERTS / 2]; /* Static Clip Buffer */
static glTexCoord GL_UVBUF[GL_KOS_MAX_VERTS / 2]; /* Static Multi-Texture UV Buffer */
#endif #endif
static unsigned int GL_VERTS[2] = {0, 0}, static GLuint GL_VERTS[2] = {0, 0},
GL_CVERTS = 0, GL_CVERTS = 0,
GL_LIST = GL_LIST_OP; GL_UVVERTS = 0,
GL_LIST = GL_KOS_LIST_OP;
#define GL_KOS_MAX_MULTITEXTURE_OBJECTS 512
static GL_MULTITEX_OBJECT GL_MTOBJS[GL_KOS_MAX_MULTITEXTURE_OBJECTS];
static GLuint GL_MTOBJECTS = 0;
/* Custom version of sq_cpy from KOS for copying vertex data to the PVR */ /* Custom version of sq_cpy from KOS for copying vertex data to the PVR */
static inline void pvr_list_submit(void *src, int n) { static inline void pvr_list_submit(void *src, int n) {
unsigned int *d = TA_SQ_ADDR; GLuint *d = TA_SQ_ADDR;
unsigned int *s = src; GLuint *s = src;
/* fill/write queues as many times necessary */ /* fill/write queues as many times necessary */
while(n--) { while(n--) {
@ -63,10 +71,43 @@ static inline void pvr_list_submit(void *src, int n) {
} }
/* Wait for both store queues to complete */ /* Wait for both store queues to complete */
d = (unsigned int *)0xe0000000; d = (GLuint *)0xe0000000;
d[0] = d[8] = 0; d[0] = d[8] = 0;
} }
inline void _glKosPushMultiTexObject(GL_TEXTURE_OBJECT *tex,
pvr_vertex_t *src,
GLuint count) {
_glKosCompileHdrMT(&GL_MTOBJS[GL_MTOBJECTS].hdr, tex);
GL_MTOBJS[GL_MTOBJECTS].src = src;
GL_MTOBJS[GL_MTOBJECTS++].count = count;
}
inline void _glKosResetMultiTexObject() {
GL_MTOBJECTS = 0;
}
inline void *_glKosMultiUVBufAddress() {
return &GL_UVBUF[0];
}
inline void *_glKosMultiUVBufPointer() {
return &GL_UVBUF[GL_UVVERTS];
}
inline void _glKosMultiUVBufIncrement() {
++GL_UVVERTS;
}
inline void _glKosMultiUVBufAdd(GLuint count) {
GL_UVVERTS += count;
}
inline void _glKosMultiUVBufReset() {
GL_UVVERTS = 0;
}
inline void *_glKosClipBufAddress() { inline void *_glKosClipBufAddress() {
return &GL_CBUF[0]; return &GL_CBUF[0];
} }
@ -79,7 +120,7 @@ inline void _glKosClipBufIncrement() {
++GL_CVERTS; ++GL_CVERTS;
} }
inline void _glKosClipBufAdd(unsigned int count) { inline void _glKosClipBufAdd(GLuint count) {
GL_CVERTS += count; GL_CVERTS += count;
} }
@ -88,14 +129,14 @@ inline void _glKosClipBufReset() {
} }
inline void _glKosVertexBufSwitchOP() { inline void _glKosVertexBufSwitchOP() {
GL_LIST = GL_LIST_OP; GL_LIST = GL_KOS_LIST_OP;
} }
inline void _glKosVertexBufSwitchTR() { inline void _glKosVertexBufSwitchTR() {
GL_LIST = GL_LIST_TR; GL_LIST = GL_KOS_LIST_TR;
} }
inline void *_glKosVertexBufAddress(unsigned char list) { inline void *_glKosVertexBufAddress(GLubyte list) {
return &GL_VBUF[list][0]; return &GL_VBUF[list][0];
} }
@ -108,19 +149,19 @@ inline void _glKosVertexBufIncrement() {
} }
inline void *_glKosTRVertexBufPointer() { inline void *_glKosTRVertexBufPointer() {
return &GL_VBUF[GL_LIST_TR][GL_VERTS[GL_LIST_TR]]; return &GL_VBUF[GL_KOS_LIST_TR][GL_VERTS[GL_KOS_LIST_TR]];
} }
inline void _glKosTRVertexBufIncrement() { inline void _glKosTRVertexBufIncrement() {
++GL_VERTS[GL_LIST_TR]; ++GL_VERTS[GL_KOS_LIST_TR];
} }
inline void _glKosVertexBufAdd(unsigned int count) { inline void _glKosVertexBufAdd(GLuint count) {
GL_VERTS[GL_LIST] += count; GL_VERTS[GL_LIST] += count;
} }
inline void _glKosTRVertexBufAdd(unsigned int count) { inline void _glKosTRVertexBufAdd(GLuint count) {
GL_VERTS[GL_LIST_TR] += count; GL_VERTS[GL_KOS_LIST_TR] += count;
} }
inline void _glKosVertexBufDecrement() { inline void _glKosVertexBufDecrement() {
@ -131,11 +172,11 @@ inline void _glKosVertexBufReset() {
GL_VERTS[0] = GL_VERTS[1] = 0; GL_VERTS[0] = GL_VERTS[1] = 0;
} }
inline unsigned int _glKosVertexBufCount(unsigned char list) { inline GLuint _glKosVertexBufCount(GLubyte list) {
return GL_VERTS[list]; return GL_VERTS[list];
} }
unsigned char _glKosList() { GLubyte _glKosList() {
return GL_LIST; return GL_LIST;
} }
@ -146,13 +187,32 @@ inline void _glKosVertexBufCopy(void *dst, void *src, GLuint count) {
static inline void glutSwapBuffer() { static inline void glutSwapBuffer() {
pvr_list_begin(PVR_LIST_OP_POLY); pvr_list_begin(PVR_LIST_OP_POLY);
pvr_list_submit(_glKosVertexBufAddress(GL_LIST_OP), _glKosVertexBufCount(GL_LIST_OP)); pvr_list_submit(_glKosVertexBufAddress(GL_KOS_LIST_OP), _glKosVertexBufCount(GL_KOS_LIST_OP));
pvr_list_finish(); pvr_list_finish();
pvr_list_begin(PVR_LIST_TR_POLY); pvr_list_begin(PVR_LIST_TR_POLY);
pvr_list_submit(_glKosVertexBufAddress(GL_LIST_TR), _glKosVertexBufCount(GL_LIST_TR)); pvr_list_submit(_glKosVertexBufAddress(GL_KOS_LIST_TR), _glKosVertexBufCount(GL_KOS_LIST_TR));
/* Multi-Texture Pass - Modify U/V coords of submitted vertices */
GLuint i, v;
glTexCoord *mt = _glKosMultiUVBufAddress();
for(i = 0; i < GL_MTOBJECTS; i++) {
//copy vertex uv
for(v = 0; v < GL_MTOBJS[i].count; v ++) {
GL_MTOBJS[i].src[v].u = mt->u;
GL_MTOBJS[i].src[v].v = mt->v;
++mt;
}
// submit vertex data to PVR
pvr_list_submit((pvr_poly_hdr_t *)&GL_MTOBJS[i].hdr, 1);
pvr_list_submit((pvr_vertex_t *)GL_MTOBJS[i].src, GL_MTOBJS[i].count);
}
_glKosResetMultiTexObject(); /* End Multi-Texture Pass */
pvr_list_finish(); pvr_list_finish();
@ -173,6 +233,9 @@ void glutSwapBuffers() {
glutSwapBuffer(); glutSwapBuffer();
_glKosVertexBufReset(); _glKosVertexBufReset();
_glKosMultiUVBufReset();
} }
void glutCopyBufferToTexture(void *dst, GLsizei *x, GLsizei *y) { void glutCopyBufferToTexture(void *dst, GLsizei *x, GLsizei *y) {
@ -200,14 +263,12 @@ int _glKosInitPVR() {
}; };
pvr_init(&params); pvr_init(&params);
#ifdef GL_USE_DMA
pvr_dma_init();
#endif
#ifdef GL_USE_MALLOC #ifdef GL_KOS_USE_MALLOC
GL_VBUF[0] = memalign(0x20, GL_MAX_VERTS * sizeof(pvr_cmd_t)); GL_VBUF[0] = memalign(0x20, GL_KOS_MAX_VERTS * sizeof(pvr_cmd_t));
GL_VBUF[1] = memalign(0x20, GL_MAX_VERTS * sizeof(pvr_cmd_t)); GL_VBUF[1] = memalign(0x20, GL_KOS_MAX_VERTS * sizeof(pvr_cmd_t));
GL_CBUF = malloc((GL_MAX_VERTS / 2) * sizeof(pvr_cmd_t)); GL_CBUF = malloc((GL_KOS_MAX_VERTS / 2) * sizeof(pvr_cmd_t));
GL_UVBUF = malloc(GL_KOS_MAX_VERTS * sizeof(glTexCoord));
#endif #endif
return 1; return 1;

View File

@ -24,14 +24,14 @@ typedef struct {
} pvr_cmd_tclip_t; /* Tile Clip command for the pvr */ } pvr_cmd_tclip_t; /* Tile Clip command for the pvr */
#define GL_PVR_VERTEX_BUF_SIZE 2560 * 256 /* PVR Vertex buffer size */ #define GL_PVR_VERTEX_BUF_SIZE 2560 * 256 /* PVR Vertex buffer size */
#define GL_MAX_VERTS 1024*64 /* SH4 Vertex Count */ #define GL_KOS_MAX_VERTS 1024*64 /* SH4 Vertex Count */
#define GL_MAX_TEXTURES 1024 /* Textures in Buffer */
#define GL_USE_MALLOC 1 /* Use Dynamic Vertex Array */ #define GL_KOS_LIST_OP 0
#define GL_KOS_LIST_TR 1
#define GL_KOS_USE_MALLOC 1 /* Use Dynamic Vertex Array */
//#define GL_USE_FLOAT 0 /* Use PVR's floating-point color Vertex Type (64bit) *NoOp* */ //#define GL_USE_FLOAT 0 /* Use PVR's floating-point color Vertex Type (64bit) *NoOp* */
//#define GL_USE_DMA 0 /* Use PVR DMA for vertex data transfer *NoOp* */ //#define GL_USE_DMA 0 /* Use PVR DMA for vertex data transfer *NoOp* */
#define GL_LIST_OP 0
#define GL_LIST_TR 1
/* Misc SH4->PVR Commands */ /* Misc SH4->PVR Commands */
#define TA_SQ_ADDR (unsigned int *)(void *) \ #define TA_SQ_ADDR (unsigned int *)(void *) \

View File

@ -8,6 +8,7 @@
*/ */
#include "gl.h" #include "gl.h"
#include "glext.h"
#include "gl-api.h" #include "gl-api.h"
#include <malloc.h> #include <malloc.h>
@ -16,11 +17,14 @@
//========================================================================================// //========================================================================================//
//== Internal KOS Open GL Texture Unit Structures / Global Variables ==// //== Internal KOS Open GL Texture Unit Structures / Global Variables ==//
static GL_TEXTURE_OBJECT *TEXTURE_OBJ = NULL; #define GL_KOS_MAX_TEXTURE_UNITS 2
static GL_TEXTURE_OBJECT *GL_TEXTURE_POINTER = NULL; #define GL_KOS_CLAMP_U (1<<1)
#define GL_KOS_CLAMP_V (1<<0)
#define GL_CLAMP_U (1<<1) static GL_TEXTURE_OBJECT *TEXTURE_OBJ = NULL;
#define GL_CLAMP_V (1<<0) static GL_TEXTURE_OBJECT *GL_KOS_TEXTURE_UNIT[GL_KOS_MAX_TEXTURE_UNITS] = { NULL, NULL };
static GLubyte GL_KOS_ACTIVE_TEXTURE = GL_TEXTURE0_ARB & 0xF;
//========================================================================================// //========================================================================================//
@ -65,11 +69,11 @@ static GL_TEXTURE_OBJECT *_glKosGetTextureObj(GLuint index) {
} }
static void _glKosBindTexture(GLuint index) { static void _glKosBindTexture(GLuint index) {
GL_TEXTURE_POINTER = _glKosGetTextureObj(index); GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE] = _glKosGetTextureObj(index);
} }
static void _glKosUnbindTexture() { static void _glKosUnbindTexture() {
GL_TEXTURE_POINTER = NULL; GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE] = NULL;
} }
GLuint _glKosTextureWidth(GLuint index) { GLuint _glKosTextureWidth(GLuint index) {
@ -88,11 +92,21 @@ GLvoid *_glKosTextureData(GLuint index) {
} }
void _glKosCompileHdrTx() { void _glKosCompileHdrTx() {
return GL_TEXTURE_POINTER ? _glKosCompileHdrT(GL_TEXTURE_POINTER) : _glKosCompileHdr(); return GL_KOS_TEXTURE_UNIT[GL_TEXTURE0_ARB & 0xF] ?
_glKosCompileHdrT(GL_KOS_TEXTURE_UNIT[GL_TEXTURE0_ARB & 0xF]) : _glKosCompileHdr();
}
GL_TEXTURE_OBJECT *_glKosBoundMultiTexID() {
return GL_KOS_TEXTURE_UNIT[GL_TEXTURE1_ARB & 0xF];
} }
GLuint _glKosBoundTexID() { GLuint _glKosBoundTexID() {
return GL_TEXTURE_POINTER ? GL_TEXTURE_POINTER->index : 0; return GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE] ?
GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->index : 0;
}
GLubyte _glKosMaxTextureUnits() {
return GL_KOS_MAX_TEXTURE_UNITS;
} }
//========================================================================================// //========================================================================================//
@ -131,9 +145,9 @@ void APIENTRY glDeleteTextures(GLsizei n, GLuint *textures) {
ltxr->link = txr->link; ltxr->link = txr->link;
if(txr->index == *textures) { if(txr->index == *textures) {
if(GL_TEXTURE_POINTER) if(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE])
if(GL_TEXTURE_POINTER->index == txr->index) if(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->index == txr->index)
GL_TEXTURE_POINTER = NULL; GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE] = NULL;
if(txr->data != NULL) if(txr->data != NULL)
pvr_mem_free(txr->data); pvr_mem_free(txr->data);
@ -155,9 +169,53 @@ void APIENTRY glBindTexture(GLenum target, GLuint texture) {
texture ? _glKosBindTexture(texture) : _glKosUnbindTexture(); texture ? _glKosBindTexture(texture) : _glKosUnbindTexture();
} }
void APIENTRY glCompressedTexImage2D(GLenum target,
GLint level,
GLenum internalformat,
GLsizei width,
GLsizei height,
GLint border,
GLsizei imageSize,
const GLvoid *data) {
if(target != GL_TEXTURE_2D)
_glKosThrowError(GL_INVALID_ENUM, "glCompressedTexImage2D");
if(level < 0)
_glKosThrowError(GL_INVALID_VALUE, "glCompressedTexImage2D");
if(border)
_glKosThrowError(GL_INVALID_VALUE, "glCompressedTexImage2D");
if(internalformat != GL_UNSIGNED_SHORT_5_6_5_VQ)
if(internalformat != GL_UNSIGNED_SHORT_5_6_5_VQ_TWID)
if(internalformat != GL_UNSIGNED_SHORT_4_4_4_4_VQ)
if(internalformat != GL_UNSIGNED_SHORT_4_4_4_4_VQ_TWID)
if(internalformat != GL_UNSIGNED_SHORT_1_5_5_5_VQ)
if(internalformat != GL_UNSIGNED_SHORT_1_5_5_5_VQ_TWID)
_glKosThrowError(GL_INVALID_OPERATION, "glCompressedTexImage2D");
if(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE] == NULL)
_glKosThrowError(GL_INVALID_OPERATION, "glCompressedTexImage2D");
if(_glKosGetError()) {
_glKosPrintError();
return;
}
GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->width = width;
GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->height = height;
GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->mip_map = level;
GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->color = internalformat;
GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->data = pvr_mem_malloc(imageSize);
if(data)
sq_cpy(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->data, data, imageSize);
}
void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
GLsizei width, GLsizei height, GLint border, GLsizei width, GLsizei height, GLint border,
GLenum format, GLenum type, GLvoid *data) { GLenum format, GLenum type, const GLvoid *data) {
if(target != GL_TEXTURE_2D) if(target != GL_TEXTURE_2D)
_glKosThrowError(GL_INVALID_ENUM, "glTexImage2D"); _glKosThrowError(GL_INVALID_ENUM, "glTexImage2D");
@ -181,22 +239,16 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
if(format == GL_RGB) if(format == GL_RGB)
if(type != GL_UNSIGNED_SHORT_5_6_5) if(type != GL_UNSIGNED_SHORT_5_6_5)
if(type != GL_UNSIGNED_SHORT_5_6_5_TWID) if(type != GL_UNSIGNED_SHORT_5_6_5_TWID)
if(type != GL_UNSIGNED_SHORT_5_6_5_VQ)
if(type != GL_UNSIGNED_SHORT_5_6_5_VQ_TWID)
_glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D"); _glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D");
if(format == GL_RGBA) if(format == GL_RGBA)
if(type != GL_UNSIGNED_SHORT_4_4_4_4) if(type != GL_UNSIGNED_SHORT_4_4_4_4)
if(type != GL_UNSIGNED_SHORT_4_4_4_4_TWID) if(type != GL_UNSIGNED_SHORT_4_4_4_4_TWID)
if(type != GL_UNSIGNED_SHORT_4_4_4_4_VQ) if(type != GL_UNSIGNED_SHORT_1_5_5_5)
if(type != GL_UNSIGNED_SHORT_4_4_4_4_VQ_TWID) if(type != GL_UNSIGNED_SHORT_1_5_5_5_TWID)
if(type != GL_UNSIGNED_SHORT_5_5_5_1)
if(type != GL_UNSIGNED_SHORT_5_5_5_1_TWID)
if(type != GL_UNSIGNED_SHORT_5_5_5_1_VQ)
if(type != GL_UNSIGNED_SHORT_5_5_5_1_VQ_TWID)
_glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D"); _glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D");
if(GL_TEXTURE_POINTER == NULL) if(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE] == NULL)
_glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D"); _glKosThrowError(GL_INVALID_OPERATION, "glTexImage2D");
if(_glKosGetError()) { if(_glKosGetError()) {
@ -204,20 +256,17 @@ void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
return; return;
} }
GL_TEXTURE_POINTER->width = width; GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->width = width;
GL_TEXTURE_POINTER->height = height; GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->height = height;
GL_TEXTURE_POINTER->mip_map = level; GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->mip_map = level;
GL_TEXTURE_POINTER->color = type; GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->color = type;
GLuint bytes = level ? glKosMipMapTexSize(width, height) : (width * height * 2); GLuint bytes = level ? glKosMipMapTexSize(width, height) : (width * height * 2);
if(format & PVR_TXRFMT_VQ_ENABLE) GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->data = pvr_mem_malloc(bytes);
GL_TEXTURE_POINTER->data = pvr_mem_malloc(bytes * 0.25);
else
GL_TEXTURE_POINTER->data = pvr_mem_malloc(bytes);
if(data) if(data)
sq_cpy(GL_TEXTURE_POINTER->data, data, bytes); sq_cpy(GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->data, data, bytes);
} }
void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) { void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) {
@ -227,19 +276,19 @@ void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) {
case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_MIN_FILTER:
switch(param) { switch(param) {
case GL_LINEAR: case GL_LINEAR:
GL_TEXTURE_POINTER->filter = PVR_FILTER_BILINEAR; GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->filter = PVR_FILTER_BILINEAR;
break; break;
case GL_NEAREST: case GL_NEAREST:
GL_TEXTURE_POINTER->filter = PVR_FILTER_NEAREST; GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->filter = PVR_FILTER_NEAREST;
break; break;
case GL_FILTER_NONE: case GL_FILTER_NONE:
GL_TEXTURE_POINTER->filter = PVR_FILTER_NONE; GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->filter = PVR_FILTER_NONE;
break; break;
case GL_FILTER_BILINEAR: case GL_FILTER_BILINEAR:
GL_TEXTURE_POINTER->filter = PVR_FILTER_BILINEAR; GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->filter = PVR_FILTER_BILINEAR;
break; break;
default: default:
@ -251,11 +300,11 @@ void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) {
case GL_TEXTURE_WRAP_S: case GL_TEXTURE_WRAP_S:
switch(param) { switch(param) {
case GL_CLAMP: case GL_CLAMP:
GL_TEXTURE_POINTER->uv_clamp |= GL_CLAMP_U; GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->uv_clamp |= GL_KOS_CLAMP_U;
break; break;
case GL_REPEAT: case GL_REPEAT:
GL_TEXTURE_POINTER->uv_clamp &= ~GL_CLAMP_U; GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->uv_clamp &= ~GL_KOS_CLAMP_U;
break; break;
} }
@ -264,11 +313,11 @@ void APIENTRY glTexParameteri(GLenum target, GLenum pname, GLint param) {
case GL_TEXTURE_WRAP_T: case GL_TEXTURE_WRAP_T:
switch(param) { switch(param) {
case GL_CLAMP: case GL_CLAMP:
GL_TEXTURE_POINTER->uv_clamp |= GL_CLAMP_V; GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->uv_clamp |= GL_KOS_CLAMP_V;
break; break;
case GL_REPEAT: case GL_REPEAT:
GL_TEXTURE_POINTER->uv_clamp &= ~GL_CLAMP_V; GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->uv_clamp &= ~GL_KOS_CLAMP_V;
break; break;
} }
@ -290,9 +339,22 @@ void APIENTRY glTexEnvi(GLenum target, GLenum pname, GLint param) {
} }
if(param >= PVR_TXRENV_REPLACE && param <= PVR_TXRENV_MODULATEALPHA) if(param >= PVR_TXRENV_REPLACE && param <= PVR_TXRENV_MODULATEALPHA)
GL_TEXTURE_POINTER->env = param; GL_KOS_TEXTURE_UNIT[GL_KOS_ACTIVE_TEXTURE]->env = param;
} }
void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param) { void APIENTRY glTexEnvf(GLenum target, GLenum pname, GLfloat param) {
glTexEnvi(target, pname, param); glTexEnvi(target, pname, param);
} }
void APIENTRY glActiveTextureARB(GLenum texture) {
if(texture < GL_TEXTURE0_ARB || texture > GL_TEXTURE0_ARB + GL_KOS_MAX_TEXTURE_UNITS)
_glKosThrowError(GL_INVALID_ENUM, "glActiveTextureARB");
if(_glKosGetError()) {
_glKosPrintError();
return;
}
GL_KOS_ACTIVE_TEXTURE = texture & 0xF;
}

View File

@ -379,7 +379,7 @@ __BEGIN_DECLS
#define GLclampf float #define GLclampf float
#define GLubyte unsigned char #define GLubyte unsigned char
#define GLbitfield unsigned long #define GLbitfield unsigned long
#define GLboolean int #define GLboolean unsigned char
#define GL_FALSE 0 #define GL_FALSE 0
#define GL_TRUE 1 #define GL_TRUE 1
@ -419,7 +419,7 @@ GLAPI void APIENTRY glNormal3fv(const GLfloat *xyz);
/* Primitive 2D Position Submission */ /* Primitive 2D Position Submission */
GLAPI void APIENTRY glVertex2f(GLfloat x, GLfloat y); GLAPI void APIENTRY glVertex2f(GLfloat x, GLfloat y);
GLAPI void APIENTRY glVertex2fv(const const GLfloat *xy); GLAPI void APIENTRY glVertex2fv(const GLfloat *xy);
/* Non-Standard KOS Primitive 2D Submission. This will perform no tranformations on the vertices. */ /* Non-Standard KOS Primitive 2D Submission. This will perform no tranformations on the vertices. */
GLAPI void APIENTRY glKosVertex2f(GLfloat x, GLfloat y); GLAPI void APIENTRY glKosVertex2f(GLfloat x, GLfloat y);
@ -491,14 +491,43 @@ GLAPI void APIENTRY glDeleteTextures(GLsizei n, GLuint *textures);
GLAPI void APIENTRY glBindTexture(GLenum target, GLuint texture); GLAPI void APIENTRY glBindTexture(GLenum target, GLuint texture);
/* Loads texture from SH4 RAM into PVR VRAM */ /* Loads texture from SH4 RAM into PVR VRAM */
/* internalformat must be one of the following constants:
GL_RGB
GL_RGBA
format must be the same as internalformat
if internal format is GL_RGB, type must be one of the following constants:
GL_UNSIGNED_SHORT_5_6_5
GL_UNSIGNED_SHORT_5_6_5_TWID
if internal format is GL_RGBA, type must be one of the following constants:
GL_UNSIGNED_SHORT_4_4_4_4
GL_UNSIGNED_SHORT_4_4_4_4_TWID
GL_UNSIGNED_SHORT_1_5_5_5
GL_UNSIGNED_SHORT_1_5_5_5_TWID
*/
GLAPI void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLAPI void APIENTRY glTexImage2D(GLenum target, GLint level, GLint internalFormat,
GLsizei width, GLsizei height, GLint border, GLsizei width, GLsizei height, GLint border,
GLenum format, GLenum type, GLvoid *data); GLenum format, GLenum type, const GLvoid *data);
/* Bind a Texture that is already in PVR VRAM */ /* Loads VQ compressed texture from SH4 RAM into PVR VRAM */
GLAPI void APIENTRY glKosTexImage2D(GLenum target, GLint level, GLint internalFormat, /* internalformat must be one of the following constants:
GLsizei width, GLsizei height, GLint border, GL_UNSIGNED_SHORT_5_6_5_VQ
GLenum format, GLenum type, GLvoid *data); GL_UNSIGNED_SHORT_5_6_5_VQ_TWID
GL_UNSIGNED_SHORT_4_4_4_4_VQ
GL_UNSIGNED_SHORT_4_4_4_4_VQ_TWID
GL_UNSIGNED_SHORT_1_5_5_5_VQ
GL_UNSIGNED_SHORT_1_5_5_5_VQ_TWID
*/
GLAPI void APIENTRY glCompressedTexImage2D(GLenum target,
GLint level,
GLenum internalformat,
GLsizei width,
GLsizei height,
GLint border,
GLsizei imageSize,
const GLvoid *data);
/* GL Array API - Only GL_TRIANGLES, GL_TRIANGLE_STRIP, and GL_QUADS are supported */ /* GL Array API - Only GL_TRIANGLES, GL_TRIANGLE_STRIP, and GL_QUADS are supported */
GLAPI void APIENTRY glVertexPointer(GLint size, GLenum type, GLAPI void APIENTRY glVertexPointer(GLint size, GLenum type,
@ -515,8 +544,6 @@ GLAPI void APIENTRY glNormalPointer(GLenum type, GLsizei stride, const GLvoid *p
GLAPI void APIENTRY glColorPointer(GLint size, GLenum type, GLAPI void APIENTRY glColorPointer(GLint size, GLenum type,
GLsizei stride, const GLvoid *pointer); GLsizei stride, const GLvoid *pointer);
GLAPI void APIENTRY glIndexPointer(GLenum type, GLsizei stride, const GLvoid *pointer);
/* Array Data Submission */ /* Array Data Submission */
GLAPI void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count); GLAPI void APIENTRY glDrawArrays(GLenum mode, GLint first, GLsizei count);
GLAPI void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); GLAPI void APIENTRY glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
@ -589,22 +616,18 @@ GLAPI void APIENTRY glGetIntegerv(GLenum pname, GLint *params);
GLAPI void APIENTRY glGetFloatv(GLenum pname, GLfloat *params); GLAPI void APIENTRY glGetFloatv(GLenum pname, GLfloat *params);
GLAPI GLboolean APIENTRY glIsEnabled(GLenum cap); GLAPI GLboolean APIENTRY glIsEnabled(GLenum cap);
/* Multi-Texture Extensions - Does not currently work with Z-Clipping Enabled /* Multi-Texture Extensions - Currently not supported in immediate mode */
GLAPI void APIENTRY glActiveTexture(GLenum texture); GLAPI void APIENTRY glActiveTextureARB(GLenum texture);
GLAPI void APIENTRY glClientActiveTextureARB(GLenum texture);
GLAPI void APIENTRY glClientActiveTexture(GLenum texture);
GLAPI void APIENTRY glMultiTexCoord2f(GLenum target, GLfloat s, GLfloat t);
GLAPI void APIENTRY glMultiTexCoord2fv(GLenum target, const GLfloat *v);
*/
/* Frame Buffer Objects / Render-To-Texture Functions */ /* Frame Buffer Objects / Render-To-Texture Functions */
GLAPI void APIENTRY glGenFramebuffers(GLsizei n, GLuint * framebuffers); GLAPI void APIENTRY glGenFramebuffers(GLsizei n, GLuint *framebuffers);
GLAPI void APIENTRY glDeleteFramebuffers(GLsizei n, GLuint * framebuffers); GLAPI void APIENTRY glDeleteFramebuffers(GLsizei n, GLuint *framebuffers);
GLAPI void APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer); GLAPI void APIENTRY glBindFramebuffer(GLenum target, GLuint framebuffer);
GLAPI void APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment, GLAPI void APIENTRY glFramebufferTexture2D(GLenum target, GLenum attachment,
GLenum textarget, GLuint texture, GLint level); GLenum textarget, GLuint texture, GLint level);
GLAPI GLenum APIENTRY glCheckFramebufferStatus(GLenum target); GLAPI GLenum APIENTRY glCheckFramebufferStatus(GLenum target);
__END_DECLS __END_DECLS
#endif /* !__GL_GL_H */ #endif /* !__GL_GL_H */

View File

@ -11,8 +11,6 @@
#include <sys/cdefs.h> #include <sys/cdefs.h>
__BEGIN_DECLS __BEGIN_DECLS
#include <GL/gl.h>
#define GL_COLOR_ATTACHMENT0 0x8CE0 #define GL_COLOR_ATTACHMENT0 0x8CE0
#define GL_COLOR_ATTACHMENT1 0x8CE1 #define GL_COLOR_ATTACHMENT1 0x8CE1
#define GL_COLOR_ATTACHMENT2 0x8CE2 #define GL_COLOR_ATTACHMENT2 0x8CE2
@ -44,6 +42,82 @@ __BEGIN_DECLS
#define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC #define GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER 0x8CDC
#define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD #define GL_FRAMEBUFFER_UNSUPPORTED 0x8CDD
#define GL_TEXTURE0_ARB 0x84C0
#define GL_TEXTURE1_ARB 0x84C1
#define GL_TEXTURE2_ARB 0x84C2
#define GL_TEXTURE3_ARB 0x84C3
#define GL_TEXTURE4_ARB 0x84C4
#define GL_TEXTURE5_ARB 0x84C5
#define GL_TEXTURE6_ARB 0x84C6
#define GL_TEXTURE7_ARB 0x84C7
#define GL_TEXTURE8_ARB 0x84C8
#define GL_TEXTURE9_ARB 0x84C9
#define GL_TEXTURE10_ARB 0x84CA
#define GL_TEXTURE11_ARB 0x84CB
#define GL_TEXTURE12_ARB 0x84CC
#define GL_TEXTURE13_ARB 0x84CD
#define GL_TEXTURE14_ARB 0x84CE
#define GL_TEXTURE15_ARB 0x84CF
#define GL_TEXTURE16_ARB 0x84D0
#define GL_TEXTURE17_ARB 0x84D1
#define GL_TEXTURE18_ARB 0x84D2
#define GL_TEXTURE19_ARB 0x84D3
#define GL_TEXTURE20_ARB 0x84D4
#define GL_TEXTURE21_ARB 0x84D5
#define GL_TEXTURE22_ARB 0x84D6
#define GL_TEXTURE23_ARB 0x84D7
#define GL_TEXTURE24_ARB 0x84D8
#define GL_TEXTURE25_ARB 0x84D9
#define GL_TEXTURE26_ARB 0x84DA
#define GL_TEXTURE27_ARB 0x84DB
#define GL_TEXTURE28_ARB 0x84DC
#define GL_TEXTURE29_ARB 0x84DD
#define GL_TEXTURE30_ARB 0x84DE
#define GL_TEXTURE31_ARB 0x84DF
#define GL_ACTIVE_TEXTURE_ARB 0x84E0
#define GL_CLIENT_ACTIVE_TEXTURE_ARB 0x84E1
#define GL_MAX_TEXTURE_UNITS_ARB 0x84E2
#define GL_TRANSPOSE_MODELVIEW_MATRIX_ARB 0x84E3
#define GL_TRANSPOSE_PROJECTION_MATRIX_ARB 0x84E4
#define GL_TRANSPOSE_TEXTURE_MATRIX_ARB 0x84E5
#define GL_TRANSPOSE_COLOR_MATRIX_ARB 0x84E6
#define GL_MULTISAMPLE_ARB 0x809D
#define GL_SAMPLE_ALPHA_TO_COVERAGE_ARB 0x809E
#define GL_SAMPLE_ALPHA_TO_ONE_ARB 0x809F
#define GL_SAMPLE_COVERAGE_ARB 0x80A0
#define GL_SAMPLE_BUFFERS_ARB 0x80A8
#define GL_SAMPLES_ARB 0x80A9
#define GL_SAMPLE_COVERAGE_VALUE_ARB 0x80AA
#define GL_SAMPLE_COVERAGE_INVERT_ARB 0x80AB
#define GL_MULTISAMPLE_BIT_ARB 0x20000000
#define GL_NORMAL_MAP_ARB 0x8511
#define GL_REFLECTION_MAP_ARB 0x8512
#define GL_TEXTURE_CUBE_MAP_ARB 0x8513
#define GL_TEXTURE_BINDING_CUBE_MAP_ARB 0x8514
#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x8515
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x8516
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x8517
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x8518
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x8519
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x851A
#define GL_PROXY_TEXTURE_CUBE_MAP_ARB 0x851B
#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB 0x851C
#define GL_COMPRESSED_ALPHA_ARB 0x84E9
#define GL_COMPRESSED_LUMINANCE_ARB 0x84EA
#define GL_COMPRESSED_LUMINANCE_ALPHA_ARB 0x84EB
#define GL_COMPRESSED_INTENSITY_ARB 0x84EC
#define GL_COMPRESSED_RGB_ARB 0x84ED
#define GL_COMPRESSED_RGBA_ARB 0x84EE
#define GL_TEXTURE_COMPRESSION_HINT_ARB 0x84EF
#define GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB 0x86A0
#define GL_TEXTURE_COMPRESSED_ARB 0x86A1
#define GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A2
#define GL_COMPRESSED_TEXTURE_FORMATS_ARB 0x86A3
__END_DECLS __END_DECLS
#endif /* !__GL_GLEXT_H */ #endif /* !__GL_GLEXT_H */