Updated changelog/relnotes, moved most addons into their own tree
This commit is contained in:
commit
cbe2111cd8
15
Makefile
Executable file
15
Makefile
Executable file
|
@ -0,0 +1,15 @@
|
|||
# KallistiOS ##version##
|
||||
#
|
||||
# addons/libgl Makefile
|
||||
# (c)2001 Dan Potter
|
||||
#
|
||||
# $Id: Makefile,v 1.5 2003/02/27 04:25:39 bardtx Exp $
|
||||
|
||||
TARGET = libgl.a
|
||||
OBJS = gldepth.o gldraw.o glkos.o gllight.o glmisc.o
|
||||
OBJS += gltex.o gltrans.o glvars.o glblend.o glfog.o glmodifier.o glnzclip.o
|
||||
SUBDIRS =
|
||||
|
||||
include ../Makefile.prefab
|
||||
|
||||
|
79
glblend.c
Normal file
79
glblend.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
/* KallistiGL for KOS ##version##
|
||||
|
||||
glblend.c
|
||||
(c)2002 Benoit Miller
|
||||
*/
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include "glinternal.h"
|
||||
#include "glmacros.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
CVSID("$Id: glblend.c,v 1.3 2002/04/03 03:33:38 axlen Exp $");
|
||||
|
||||
/* Blending */
|
||||
void glBlendFunc(GLenum sfactor, GLenum dfactor) {
|
||||
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
switch(sfactor) {
|
||||
case GL_ZERO:
|
||||
gl_blend_src = PVR_BLEND_ZERO;
|
||||
break;
|
||||
case GL_ONE:
|
||||
gl_blend_src = PVR_BLEND_ONE;
|
||||
break;
|
||||
case GL_DST_COLOR:
|
||||
gl_blend_src = PVR_BLEND_DESTCOLOR;
|
||||
break;
|
||||
case GL_ONE_MINUS_DST_COLOR:
|
||||
gl_blend_src = PVR_BLEND_INVDESTCOLOR;
|
||||
break;
|
||||
case GL_SRC_ALPHA:
|
||||
gl_blend_src = PVR_BLEND_SRCALPHA;
|
||||
break;
|
||||
case GL_ONE_MINUS_SRC_ALPHA:
|
||||
gl_blend_src = PVR_BLEND_INVSRCALPHA;
|
||||
break;
|
||||
case GL_DST_ALPHA:
|
||||
gl_blend_src = PVR_BLEND_DESTALPHA;
|
||||
break;
|
||||
case GL_ONE_MINUS_DST_ALPHA:
|
||||
gl_blend_src = PVR_BLEND_INVDESTALPHA;
|
||||
break;
|
||||
default:
|
||||
assert_msg(0, "Invalid source blending function.");
|
||||
}
|
||||
|
||||
switch(dfactor) {
|
||||
case GL_ZERO:
|
||||
gl_blend_dst = PVR_BLEND_ZERO;
|
||||
break;
|
||||
case GL_ONE:
|
||||
gl_blend_dst = PVR_BLEND_ONE;
|
||||
break;
|
||||
case GL_SRC_COLOR:
|
||||
gl_blend_dst = PVR_BLEND_DESTCOLOR;
|
||||
break;
|
||||
case GL_ONE_MINUS_SRC_COLOR:
|
||||
gl_blend_dst = PVR_BLEND_INVDESTCOLOR;
|
||||
break;
|
||||
case GL_SRC_ALPHA:
|
||||
gl_blend_dst = PVR_BLEND_SRCALPHA;
|
||||
break;
|
||||
case GL_ONE_MINUS_SRC_ALPHA:
|
||||
gl_blend_dst = PVR_BLEND_INVSRCALPHA;
|
||||
break;
|
||||
case GL_DST_ALPHA:
|
||||
gl_blend_dst = PVR_BLEND_DESTALPHA;
|
||||
break;
|
||||
case GL_ONE_MINUS_DST_ALPHA:
|
||||
gl_blend_dst = PVR_BLEND_INVDESTALPHA;
|
||||
break;
|
||||
default:
|
||||
assert_msg(0, "Invalid destination blending function");
|
||||
}
|
||||
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
}
|
97
glclip.h
Normal file
97
glclip.h
Normal file
|
@ -0,0 +1,97 @@
|
|||
/* KallistiGL for KOS ##version##
|
||||
|
||||
Near Z Clipper
|
||||
(c) Trilinear
|
||||
Trilinear@hotmail.com
|
||||
|
||||
$Id: glclip.h,v 1.2 2002/06/28 04:47:02 axlen Exp $
|
||||
*/
|
||||
|
||||
#ifndef __GLCLIP_H
|
||||
#define __GLCLIP_H
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include "glinternal.h"
|
||||
|
||||
#define MAXZ 0.0001f /* if z is negative, it is behind the camera */
|
||||
|
||||
inline void CopyV(gl_vertex_t *vertold, gl_vertex_t *vertnew) {
|
||||
|
||||
/* memcpy(vertnew, vertold, sizeof(gl_vertex_t)); */
|
||||
|
||||
vertnew->flags = vertold->flags;
|
||||
vertnew->x = vertold->x;
|
||||
vertnew->y = vertold->y;
|
||||
vertnew->z = vertold->z;
|
||||
vertnew->w = vertold->w;
|
||||
vertnew->u = vertold->u;
|
||||
vertnew->v = vertold->v;
|
||||
vertnew->argb = vertold->argb;
|
||||
vertnew->oargb = vertold->oargb;
|
||||
|
||||
}
|
||||
|
||||
inline void FindZ(gl_vertex_t *vertnew, gl_vertex_t *vert1, gl_vertex_t *vert2) {
|
||||
|
||||
float diffz;
|
||||
/* z is indp variable because we know it changes, thus no div 0 error */
|
||||
vertnew->z = gl_frustum.znear;
|
||||
vertnew->w = vert1->w + (gl_frustum.znear-vert1->z)*(vert1->w - vert2->w)/(vert1->z - vert2->z);
|
||||
vertnew->x = vert1->x + (gl_frustum.znear-vert1->z)*(vert1->x - vert2->x)/(vert1->z - vert2->z);
|
||||
vertnew->y = vert1->y + (gl_frustum.znear-vert1->z)*(vert1->y - vert2->y)/(vert1->z - vert2->z);
|
||||
|
||||
diffz = (vert1->z-vertnew->z)/(vert1->z-vert2->z);
|
||||
vertnew->u = (diffz)*vert2->u + (1.0f-diffz)*vert1->u;
|
||||
vertnew->v = (diffz)*vert2->v + (1.0f-diffz)*vert1->v;
|
||||
}
|
||||
|
||||
inline int ZClipTex(gl_vertex_t *vert)
|
||||
/* returns 0 for full clip, 3 for triangle output and 4 for quad output
|
||||
based on sutherland-hodgeman clip algorithm */
|
||||
{
|
||||
int i,j;
|
||||
gl_vertex_t tempvert[4];
|
||||
|
||||
if (vert[0].z < gl_frustum.znear || vert[1].z < gl_frustum.znear || vert[2].z < gl_frustum.znear) {/* one or more parts behind camera */
|
||||
j=0;
|
||||
CopyV(&vert[0],&vert[3]);/* copy first to next after last to make cyclic */
|
||||
for(i=0; i<3; i++) {
|
||||
if (vert[i].z >= gl_frustum.znear && vert[i+1].z >= gl_frustum.znear) { /* both in */
|
||||
CopyV(&vert[i],&tempvert[j]);
|
||||
j++;
|
||||
}else if (vert[i].z < gl_frustum.znear && vert[i+1].z >= gl_frustum.znear) {/* this out, next in */
|
||||
CopyV(&vert[i],&tempvert[j]);
|
||||
FindZ(&tempvert[j],&vert[i],&vert[i+1]);
|
||||
j++;
|
||||
}else if (vert[i].z >= gl_frustum.znear && vert[i+1].z < gl_frustum.znear) {/* this in, next out */
|
||||
CopyV(&vert[i],&tempvert[j]);
|
||||
CopyV(&vert[i+1],&tempvert[j+1]);
|
||||
FindZ(&tempvert[j+1],&vert[i],&vert[i+1]);
|
||||
j+=2;
|
||||
}/* both out, ignore */
|
||||
}
|
||||
|
||||
|
||||
switch (j) {
|
||||
case 3:
|
||||
CopyV(&tempvert[0],&vert[0]);
|
||||
CopyV(&tempvert[1],&vert[1]);
|
||||
CopyV(&tempvert[2],&vert[2]);
|
||||
return 3;
|
||||
case 4:
|
||||
CopyV(&tempvert[0],&vert[0]);
|
||||
CopyV(&tempvert[1],&vert[1]);
|
||||
CopyV(&tempvert[2],&vert[3]);
|
||||
CopyV(&tempvert[3],&vert[2]);
|
||||
return 4;
|
||||
}/* if j==0 we return 0 which we are about to do anyway */
|
||||
|
||||
}else{/* is all in front of camera */
|
||||
return 3;
|
||||
}
|
||||
|
||||
return 0;/* if it isn't one of the above it is an invalid poly or completely behind camera */
|
||||
}
|
||||
|
||||
#endif /* __GLCLIP_H */
|
||||
|
74
gldepth.c
Normal file
74
gldepth.c
Normal file
|
@ -0,0 +1,74 @@
|
|||
/* KallistiGL for KOS ##version##
|
||||
|
||||
gldepth.c
|
||||
(c)2001 Dan Potter
|
||||
*/
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include "glinternal.h"
|
||||
#include "glmacros.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
CVSID("$Id: gldepth.c,v 1.7 2002/04/03 03:34:22 axlen Exp $");
|
||||
|
||||
/* Depth buffer (non-functional, just stubs) */
|
||||
void glClearDepth(GLclampd depth) {
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
}
|
||||
|
||||
void glDepthFunc(GLenum func) {
|
||||
/* Note regarding the mapping of OpenGL depth stuff to the PVR2DC:
|
||||
|
||||
The depth compare modes should be "conceptually" the same except
|
||||
for two points:
|
||||
1) You have a floating point "Depth buffer" and
|
||||
2) DC uses 1/W to compare so 1 (or higher if your clipping
|
||||
is off!) = near and 0=infinity.
|
||||
Therefore > or >= is probably what you want for closer objects to be visible. - Simon Fenney
|
||||
*/
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
switch(func)
|
||||
{
|
||||
case GL_ALWAYS:
|
||||
gl_poly_cxt.depth.comparison = PVR_DEPTHCMP_ALWAYS;
|
||||
break;
|
||||
case GL_LESS:
|
||||
gl_poly_cxt.depth.comparison = PVR_DEPTHCMP_GEQUAL;
|
||||
break;
|
||||
case GL_NOTEQUAL:
|
||||
gl_poly_cxt.depth.comparison = PVR_DEPTHCMP_NOTEQUAL;
|
||||
break;
|
||||
case GL_LEQUAL:
|
||||
gl_poly_cxt.depth.comparison = PVR_DEPTHCMP_GREATER;
|
||||
break;
|
||||
case GL_GREATER:
|
||||
gl_poly_cxt.depth.comparison = PVR_DEPTHCMP_LEQUAL;
|
||||
break;
|
||||
case GL_EQUAL:
|
||||
gl_poly_cxt.depth.comparison = PVR_DEPTHCMP_EQUAL;
|
||||
break;
|
||||
case GL_GEQUAL:
|
||||
gl_poly_cxt.depth.comparison = PVR_DEPTHCMP_LESS;
|
||||
break;
|
||||
case GL_NEVER:
|
||||
gl_poly_cxt.depth.comparison = PVR_DEPTHCMP_NEVER;
|
||||
break;
|
||||
default:
|
||||
assert_msg(0, "Invalid depth comparison function.");
|
||||
}
|
||||
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
}
|
||||
|
||||
void glDepthMask(GLboolean flag) {
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
if (flag) {
|
||||
gl_poly_cxt.depth.write = PVR_DEPTHWRITE_ENABLE;
|
||||
} else {
|
||||
gl_poly_cxt.depth.write = PVR_DEPTHWRITE_DISABLE;
|
||||
}
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
}
|
595
gldraw.c
Normal file
595
gldraw.c
Normal file
|
@ -0,0 +1,595 @@
|
|||
/* KallistiGL for KOS ##version##
|
||||
|
||||
gldraw.c
|
||||
(c)2001 Dan Potter
|
||||
*/
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include "glinternal.h"
|
||||
#include "glmacros.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <dc/pvr.h>
|
||||
|
||||
CVSID("$Id: gldraw.c,v 1.23 2002/09/05 07:36:23 bardtx Exp $");
|
||||
|
||||
/* internal prototypes */
|
||||
static void send_user_clip();
|
||||
|
||||
/* Drawing functions */
|
||||
|
||||
/* This portion of the pipeline will change drastically */
|
||||
|
||||
/* Current vertex attributes (move to global?) */
|
||||
static GLuint vert_rgba = 0xffffffff;
|
||||
static GLfloat vert_u = 0.0f, vert_v = 0.0f;
|
||||
|
||||
/* Make sure the proper matrices are in the matrix registers */
|
||||
static void fix_matrices() {
|
||||
if (gl_matrix_dirty) {
|
||||
mat_identity();
|
||||
glKosMatrixApply(GL_KOS_SCREENVIEW);
|
||||
glKosMatrixApply(GL_PROJECTION);
|
||||
glKosMatrixApply(GL_MODELVIEW);
|
||||
|
||||
gl_matrix_dirty = GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Negative 1/w values annoy the pvr, so check for them */
|
||||
static inline int check_w(gl_vertex_t *vert, int n) {
|
||||
int i;
|
||||
|
||||
for(i=0; i<n; i++)
|
||||
if (vert[i].z < 0) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static short xor[2][2] ={
|
||||
{1,0}, /* FFCW, FFCCW */
|
||||
{0,1} /* BFCW, BFCCW */
|
||||
};
|
||||
/* GL_POINTS always visible! */
|
||||
static void end_points() {
|
||||
int i;
|
||||
volatile pvr_vertex_t *vert;
|
||||
pvr_dr_state_t dr_state;
|
||||
|
||||
float size1 = (xor[(gl_cull_mode == GL_BACK)][(gl_front_face == GL_CCW)]) ?
|
||||
gl_point_size : -gl_point_size;
|
||||
float size2 = ABS(size1);
|
||||
|
||||
pvr_dr_init(dr_state);
|
||||
|
||||
/* Should be one point in the buffer */
|
||||
assert_msg(gl_vbuf_top >= 1, "Need at least one point.");
|
||||
|
||||
/* create a point using a quad */
|
||||
memcpy(&gl_vbuf[1], &gl_vbuf[0], sizeof(gl_vertex_t));
|
||||
memcpy(&gl_vbuf[2], &gl_vbuf[0], sizeof(gl_vertex_t));
|
||||
memcpy(&gl_vbuf[3], &gl_vbuf[0], sizeof(gl_vertex_t));
|
||||
|
||||
gl_vbuf[3].flags = PVR_CMD_VERTEX_EOL;
|
||||
mat_transform((vector_t*)&gl_vbuf[0].x, (vector_t*)&gl_xbuf[0].x, 4, sizeof(gl_vertex_t));
|
||||
|
||||
gl_xbuf[0].x += size1;
|
||||
gl_xbuf[0].y += size2;
|
||||
gl_xbuf[1].x += size1;
|
||||
gl_xbuf[1].y -= size2;
|
||||
gl_xbuf[2].x -= size1;
|
||||
gl_xbuf[2].y += size2;
|
||||
gl_xbuf[3].x -= size1;
|
||||
gl_xbuf[3].y -= size2;
|
||||
|
||||
/* Throw it all to the TA using direct render */
|
||||
if (check_w(gl_xbuf, 4))
|
||||
for (i=0; i<4; i++) {
|
||||
vert = pvr_dr_target(dr_state);
|
||||
vert->flags = gl_vbuf[i].flags;
|
||||
vert->x = gl_xbuf[i].x;
|
||||
vert->y = gl_xbuf[i].y;
|
||||
vert->z = gl_xbuf[i].z;
|
||||
vert->u = gl_vbuf[i].u;
|
||||
vert->v = gl_vbuf[i].v;
|
||||
vert->argb = gl_vbuf[i].argb;
|
||||
vert->oargb = gl_vbuf[i].oargb;
|
||||
pvr_dr_commit(vert);
|
||||
}
|
||||
}
|
||||
|
||||
static void end_triangles() {
|
||||
int i;
|
||||
volatile pvr_vertex_t *vert;
|
||||
pvr_dr_state_t dr_state;
|
||||
|
||||
pvr_dr_init(dr_state);
|
||||
|
||||
/* Should be three points in the buffer */
|
||||
assert_msg(gl_vbuf_top == 3, "Wrong number of vertices.");
|
||||
|
||||
gl_vbuf[2].flags = PVR_CMD_VERTEX_EOL;
|
||||
/* mat_transform((vector_t*)&gl_vbuf[0].x, (vector_t*)&gl_xbuf[0].x, 3,
|
||||
sizeof(gl_vertex_t)); */
|
||||
|
||||
for (i=0; i<gl_vbuf_top; i++) {
|
||||
float x = gl_vbuf[i].x, y = gl_vbuf[i].y, z = gl_vbuf[i].z, w = 1.0f;
|
||||
mat_trans_single4(x, y, z, w);
|
||||
gl_xbuf[i].x = x;
|
||||
gl_xbuf[i].y = y;
|
||||
if (w == 1.0f)
|
||||
gl_xbuf[i].z = ((gl_viewport_scale[2] * z) + gl_viewport_offset[2]);
|
||||
else
|
||||
gl_xbuf[i].z = w;
|
||||
}
|
||||
|
||||
/* Throw it all to the TA using direct render */
|
||||
if (check_w(gl_xbuf, 3))
|
||||
for (i=0; i<3; i++) {
|
||||
vert = pvr_dr_target(dr_state);
|
||||
vert->flags = gl_vbuf[i].flags;
|
||||
vert->x = gl_xbuf[i].x;
|
||||
vert->y = gl_xbuf[i].y;
|
||||
vert->z = gl_xbuf[i].z;
|
||||
vert->u = gl_vbuf[i].u;
|
||||
vert->v = gl_vbuf[i].v;
|
||||
vert->argb = gl_vbuf[i].argb;
|
||||
vert->oargb = gl_vbuf[i].oargb;
|
||||
pvr_dr_commit(vert);
|
||||
}
|
||||
}
|
||||
|
||||
static void end_triangle_strip() {
|
||||
int i;
|
||||
volatile pvr_vertex_t *vert;
|
||||
pvr_dr_state_t dr_state;
|
||||
|
||||
pvr_dr_init(dr_state);
|
||||
|
||||
/* Should be at least 3 points in the buffer */
|
||||
assert_msg(gl_vbuf_top >= 3, "Need at least three vertices.");
|
||||
|
||||
gl_vbuf[gl_vbuf_top-1].flags = PVR_CMD_VERTEX_EOL;
|
||||
/* mat_transform((vector_t*)&gl_vbuf[0].x, (vector_t*)&gl_xbuf[0].x,
|
||||
gl_vbuf_top, sizeof(gl_vertex_t)); */
|
||||
|
||||
for (i=0; i<gl_vbuf_top; i++) {
|
||||
float x = gl_vbuf[i].x, y = gl_vbuf[i].y, z = gl_vbuf[i].z, w = 1.0f;
|
||||
mat_trans_single4(x, y, z, w);
|
||||
gl_xbuf[i].x = x;
|
||||
gl_xbuf[i].y = y;
|
||||
if (w == 1.0f)
|
||||
gl_xbuf[i].z = ((gl_viewport_scale[2] * z) + gl_viewport_offset[2]);
|
||||
else
|
||||
gl_xbuf[i].z = w;
|
||||
}
|
||||
|
||||
/* Throw it all to the TA using direct render */
|
||||
if (check_w(gl_xbuf, gl_vbuf_top))
|
||||
for (i=0; i<gl_vbuf_top; i++) {
|
||||
vert = pvr_dr_target(dr_state);
|
||||
vert->flags = gl_vbuf[i].flags;
|
||||
vert->x = gl_xbuf[i].x;
|
||||
vert->y = gl_xbuf[i].y;
|
||||
vert->z = gl_xbuf[i].z;
|
||||
vert->u = gl_vbuf[i].u;
|
||||
vert->v = gl_vbuf[i].v;
|
||||
vert->argb = gl_vbuf[i].argb;
|
||||
vert->oargb = gl_vbuf[i].oargb;
|
||||
pvr_dr_commit(vert);
|
||||
}
|
||||
}
|
||||
|
||||
static void end_quads() {
|
||||
int i, j, order[4] = {3, 0, 2, 1};
|
||||
volatile pvr_vertex_t *vert;
|
||||
pvr_dr_state_t dr_state;
|
||||
|
||||
pvr_dr_init(dr_state);
|
||||
|
||||
/* Should be four points in the buffer */
|
||||
assert_msg(gl_vbuf_top == 4, "Wrong number of vertices.");
|
||||
|
||||
gl_vbuf[order[3]].flags = PVR_CMD_VERTEX_EOL;
|
||||
/* mat_transform((vector_t*)&gl_vbuf[0].x, (vector_t*)&gl_xbuf[0].x, 4,
|
||||
sizeof(gl_vertex_t)); */
|
||||
|
||||
for (i=0; i<gl_vbuf_top; i++) {
|
||||
float x = gl_vbuf[i].x, y = gl_vbuf[i].y, z = gl_vbuf[i].z, w = 1.0f;
|
||||
mat_trans_single4(x, y, z, w);
|
||||
gl_xbuf[i].x = x;
|
||||
gl_xbuf[i].y = y;
|
||||
if (w == 1.0f)
|
||||
gl_xbuf[i].z = ((gl_viewport_scale[2] * z) + gl_viewport_offset[2]);
|
||||
else
|
||||
gl_xbuf[i].z = w;
|
||||
}
|
||||
|
||||
/* Throw it all to the TA using direct render */
|
||||
if (check_w(gl_xbuf, 4))
|
||||
for (i=0; i<4; i++) {
|
||||
j = order[i];
|
||||
vert = pvr_dr_target(dr_state);
|
||||
vert->flags = gl_vbuf[j].flags;
|
||||
vert->x = gl_xbuf[j].x;
|
||||
vert->y = gl_xbuf[j].y;
|
||||
vert->z = gl_xbuf[j].z;
|
||||
vert->u = gl_vbuf[j].u;
|
||||
vert->v = gl_vbuf[j].v;
|
||||
vert->argb = gl_vbuf[j].argb;
|
||||
vert->oargb = gl_vbuf[j].oargb;
|
||||
pvr_dr_commit(vert);
|
||||
}
|
||||
}
|
||||
|
||||
static void end_quad_strip() {
|
||||
int i;
|
||||
volatile pvr_vertex_t *vert;
|
||||
pvr_dr_state_t dr_state;
|
||||
|
||||
pvr_dr_init(dr_state);
|
||||
|
||||
/* Should be at least 4 points in the buffer */
|
||||
assert_msg(gl_vbuf_top >= 4, "Need at least four vertices.");
|
||||
|
||||
/* OpenGL specs that any dangling vertex be chopped, which
|
||||
we have to do since we're rendering as a tri-strip. */
|
||||
if(gl_vbuf_top & 0x0001)
|
||||
gl_vbuf_top--;
|
||||
|
||||
gl_vbuf[gl_vbuf_top-1].flags = PVR_CMD_VERTEX_EOL;
|
||||
|
||||
for (i=0; i<gl_vbuf_top; i++) {
|
||||
float x = gl_vbuf[i].x, y = gl_vbuf[i].y, z = gl_vbuf[i].z, w = 1.0f;
|
||||
mat_trans_single4(x, y, z, w);
|
||||
gl_xbuf[i].x = x;
|
||||
gl_xbuf[i].y = y;
|
||||
if (w == 1.0f)
|
||||
gl_xbuf[i].z = ((gl_viewport_scale[2] * z) + gl_viewport_offset[2]);
|
||||
else
|
||||
gl_xbuf[i].z = w;
|
||||
}
|
||||
|
||||
/* Throw it all to the TA using direct render */
|
||||
if (check_w(gl_xbuf, gl_vbuf_top))
|
||||
for (i=0; i<gl_vbuf_top; i++) {
|
||||
vert = pvr_dr_target(dr_state);
|
||||
vert->flags = gl_vbuf[i].flags;
|
||||
vert->x = gl_xbuf[i].x;
|
||||
vert->y = gl_xbuf[i].y;
|
||||
vert->z = gl_xbuf[i].z;
|
||||
vert->u = gl_vbuf[i].u;
|
||||
vert->v = gl_vbuf[i].v;
|
||||
vert->argb = gl_vbuf[i].argb;
|
||||
vert->oargb = gl_vbuf[i].oargb;
|
||||
pvr_dr_commit(vert);
|
||||
}
|
||||
}
|
||||
|
||||
static void end_polygon() {
|
||||
int i, j_frn, j_bck;
|
||||
volatile pvr_vertex_t *vert;
|
||||
gl_vertex_t *gl_tvbuf;
|
||||
pvr_dr_state_t dr_state;
|
||||
|
||||
pvr_dr_init(dr_state);
|
||||
|
||||
/* Should be at least 3 points in the buffer */
|
||||
assert_msg(gl_vbuf_top >= 3, "Need at least three vertices.");
|
||||
|
||||
/* Have to alter linear vertex order to staggered Triangle strip order
|
||||
performance will suffer, but it does on all cards. */
|
||||
|
||||
gl_tvbuf = malloc(sizeof(gl_vertex_t) * (gl_vbuf_top));
|
||||
assert_msg(gl_tvbuf != NULL, "Not enough memory for GL_POLYGON");
|
||||
|
||||
gl_tvbuf[0] = gl_vbuf[0];
|
||||
gl_tvbuf[1] = gl_vbuf[1];
|
||||
|
||||
i = 2; /* the first 2 vertices are in proper order. */
|
||||
j_frn = i;
|
||||
j_bck = gl_vbuf_top - 1;
|
||||
|
||||
do {
|
||||
gl_tvbuf[i++] = gl_vbuf[j_bck]; /* move data */
|
||||
if (i < gl_vbuf_top) {
|
||||
gl_tvbuf[i++] = gl_vbuf[j_frn];
|
||||
j_frn++;
|
||||
j_bck--;
|
||||
}
|
||||
} while (i < gl_vbuf_top);
|
||||
|
||||
memcpy(gl_vbuf, gl_tvbuf, sizeof(gl_vertex_t) * gl_vbuf_top);
|
||||
free(gl_tvbuf);
|
||||
|
||||
gl_vbuf[gl_vbuf_top-1].flags = PVR_CMD_VERTEX_EOL;
|
||||
|
||||
for (i=0; i<gl_vbuf_top; i++) {
|
||||
float x = gl_vbuf[i].x, y = gl_vbuf[i].y, z = gl_vbuf[i].z, w = 1.0f;
|
||||
mat_trans_single4(x, y, z, w);
|
||||
gl_xbuf[i].x = x;
|
||||
gl_xbuf[i].y = y;
|
||||
if (w == 1.0f)
|
||||
gl_xbuf[i].z = ((gl_viewport_scale[2] * z) + gl_viewport_offset[2]);
|
||||
else
|
||||
gl_xbuf[i].z = w;
|
||||
}
|
||||
|
||||
/* Throw it all to the TA using direct render */
|
||||
if (check_w(gl_xbuf, gl_vbuf_top))
|
||||
for (i=0; i<gl_vbuf_top; i++) {
|
||||
vert = pvr_dr_target(dr_state);
|
||||
vert->flags = gl_vbuf[i].flags;
|
||||
vert->x = gl_xbuf[i].x;
|
||||
vert->y = gl_xbuf[i].y;
|
||||
vert->z = gl_xbuf[i].z;
|
||||
vert->u = gl_vbuf[i].u;
|
||||
vert->v = gl_vbuf[i].v;
|
||||
vert->argb = gl_vbuf[i].argb;
|
||||
vert->oargb = gl_vbuf[i].oargb;
|
||||
pvr_dr_commit(vert);
|
||||
}
|
||||
}
|
||||
|
||||
static void check_end() {
|
||||
/* What type of primitive was it? */
|
||||
switch(gl_prim_type) {
|
||||
case GL_POINTS:
|
||||
end_points();
|
||||
gl_vbuf_top = 0;
|
||||
break;
|
||||
case GL_TRIANGLES:
|
||||
if (gl_vbuf_top == 3) {
|
||||
end_triangles();
|
||||
gl_vbuf_top = 0;
|
||||
}
|
||||
break;
|
||||
case GL_TRIANGLE_STRIP:
|
||||
break;
|
||||
case GL_QUADS:
|
||||
if (gl_vbuf_top == 4) {
|
||||
end_quads();
|
||||
gl_vbuf_top = 0;
|
||||
}
|
||||
break;
|
||||
case GL_QUAD_STRIP:
|
||||
break;
|
||||
case GL_POLYGON:
|
||||
break;
|
||||
default:
|
||||
assert_msg(0, "gl_prim_type: Unknown primitive type.");
|
||||
}
|
||||
}
|
||||
|
||||
static pvr_poly_hdr_t polyhdr;
|
||||
|
||||
void send_poly_hdr(void) {
|
||||
|
||||
if (TXR_ENABLED) {
|
||||
memcpy(&gl_poly_cxt.txr, &gl_cur_texture->txr, sizeof(gl_poly_cxt.txr));
|
||||
}
|
||||
|
||||
switch(gl_active_list) {
|
||||
case GL_LIST_OPAQUE_POLY:
|
||||
gl_poly_cxt.gen.alpha = PVR_ALPHA_DISABLE;
|
||||
gl_poly_cxt.txr.alpha = PVR_TXRALPHA_ENABLE;
|
||||
gl_poly_cxt.blend.src = PVR_BLEND_ONE;
|
||||
gl_poly_cxt.blend.dst = PVR_BLEND_ZERO;
|
||||
break;
|
||||
case GL_LIST_OPAQUE_MOD:
|
||||
break;
|
||||
case GL_LIST_TRANS_POLY:
|
||||
case GL_LIST_PUNCHTHRU:
|
||||
gl_poly_cxt.gen.alpha = PVR_ALPHA_ENABLE;
|
||||
gl_poly_cxt.txr.alpha = PVR_TXRALPHA_ENABLE;
|
||||
gl_poly_cxt.blend.src = gl_blend_src;
|
||||
gl_poly_cxt.blend.dst = gl_blend_dst;
|
||||
break;
|
||||
case GL_LIST_TRANS_MOD:
|
||||
break;
|
||||
}
|
||||
/* Set states that we couldn't before */
|
||||
if (gl_cull_face)
|
||||
{
|
||||
if (gl_cull_mode == GL_BACK)
|
||||
if (gl_front_face == GL_CW)
|
||||
gl_poly_cxt.gen.culling = PVR_CULLING_CCW;
|
||||
else
|
||||
gl_poly_cxt.gen.culling = PVR_CULLING_CW;
|
||||
else
|
||||
if (gl_front_face == GL_CCW)
|
||||
gl_poly_cxt.gen.culling = PVR_CULLING_CCW;
|
||||
else
|
||||
gl_poly_cxt.gen.culling = PVR_CULLING_CW;
|
||||
} else
|
||||
gl_poly_cxt.gen.culling = PVR_CULLING_NONE;
|
||||
|
||||
pvr_poly_compile(&polyhdr, &gl_poly_cxt);
|
||||
pvr_prim(&polyhdr, sizeof(pvr_poly_hdr_t));
|
||||
}
|
||||
|
||||
/* This can be used for KGL Direct Rendering */
|
||||
void glKosPolyHdrSend() {
|
||||
send_poly_hdr();
|
||||
}
|
||||
|
||||
void glBegin(GLenum mode) {
|
||||
/* Submit the user clip rectangle (if necessary) */
|
||||
if (gl_scissor_dirty) {
|
||||
send_user_clip();
|
||||
gl_scissor_dirty = GL_FALSE;
|
||||
}
|
||||
|
||||
/* Submit the poly buffer (if necessary) */
|
||||
if (!gl_pbuf_submitted) {
|
||||
send_poly_hdr();
|
||||
gl_pbuf_submitted = GL_TRUE;
|
||||
}
|
||||
if (ZCLIP_ENABLED || LIGHTING_ENABLED)
|
||||
fix_vfzclip_matrices();
|
||||
else
|
||||
fix_matrices();
|
||||
|
||||
gl_prim_type = mode;
|
||||
gl_vbuf_top = 0;
|
||||
}
|
||||
|
||||
void glEnd(void) {
|
||||
if (MODIFIER_ENABLED) {
|
||||
modifier_end();
|
||||
return;
|
||||
} else if (ZCLIP_ENABLED || LIGHTING_ENABLED) {
|
||||
vfzclip_end();
|
||||
return;
|
||||
}
|
||||
|
||||
/* What type of primitive was it? */
|
||||
switch(gl_prim_type) {
|
||||
case GL_POINTS:
|
||||
break;
|
||||
case GL_TRIANGLES:
|
||||
break;
|
||||
case GL_TRIANGLE_STRIP:
|
||||
end_triangle_strip();
|
||||
break;
|
||||
case GL_QUADS:
|
||||
break;
|
||||
case GL_QUAD_STRIP:
|
||||
end_quad_strip();
|
||||
break;
|
||||
case GL_POLYGON:
|
||||
end_polygon();
|
||||
break;
|
||||
default:
|
||||
assert_msg(0, "gl_prim_type: Unknown primitive type.");
|
||||
}
|
||||
gl_prim_type = 0;
|
||||
}
|
||||
|
||||
static float autouv[4][2] = {
|
||||
{0.0f, 0.0f},
|
||||
{1.0f, 0.0f},
|
||||
{1.0f, 1.0f},
|
||||
{0.0f, 1.0f}
|
||||
};
|
||||
|
||||
void glVertex3f(GLfloat x, GLfloat y, GLfloat z) {
|
||||
gl_vbuf[gl_vbuf_top].flags = PVR_CMD_VERTEX;
|
||||
|
||||
gl_vbuf[gl_vbuf_top].x = x;
|
||||
gl_vbuf[gl_vbuf_top].y = y;
|
||||
gl_vbuf[gl_vbuf_top].z = z;
|
||||
gl_vbuf[gl_vbuf_top].w = 1.0f;
|
||||
if (AUTOUV_ENABLED) {
|
||||
vert_u = autouv[gl_vbuf_top][0];
|
||||
vert_v = autouv[gl_vbuf_top][1];
|
||||
}
|
||||
gl_vbuf[gl_vbuf_top].u = vert_u;
|
||||
gl_vbuf[gl_vbuf_top].v = vert_v;
|
||||
gl_vbuf[gl_vbuf_top].argb = vert_rgba;
|
||||
gl_vbuf[gl_vbuf_top].oargb = 0xff000000;
|
||||
|
||||
gl_vbuf_top++;
|
||||
assert_msg(gl_vbuf_top < VBUF_SIZE, "Vertex buffer overflow");
|
||||
|
||||
if (MODIFIER_ENABLED)
|
||||
modifier_check_end();
|
||||
else if (ZCLIP_ENABLED || LIGHTING_ENABLED)
|
||||
vfzclip_check_end();
|
||||
else
|
||||
check_end();
|
||||
}
|
||||
|
||||
void glVertex3fv(GLfloat *v) {
|
||||
glVertex3f(*v, *(v+1), *(v+2));
|
||||
}
|
||||
|
||||
void glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz) {
|
||||
}
|
||||
|
||||
void glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) {
|
||||
vert_rgba = (alpha << 24) | (red << 16) | (green << 8) | blue;
|
||||
}
|
||||
|
||||
void glColor3f(GLfloat red, GLfloat green, GLfloat blue) {
|
||||
vert_rgba = (0xff << 24) |
|
||||
((uint32)(red * 0xff) << 16) |
|
||||
((uint32)(green * 0xff) << 8) |
|
||||
((uint32)(blue * 0xff));
|
||||
}
|
||||
|
||||
void glColor3fv(GLfloat *v) {
|
||||
glColor3f(*v, *(v+1), *(v+2));
|
||||
}
|
||||
|
||||
void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) {
|
||||
vert_rgba = ((uint32)(alpha * 0xff) << 24) |
|
||||
((uint32)(red * 0xff) << 16) |
|
||||
((uint32)(green * 0xff) << 8) |
|
||||
((uint32)(blue * 0xff));
|
||||
}
|
||||
|
||||
void glColor4fv(GLfloat *v) {
|
||||
glColor4f(*v, *(v+1), *(v+2), *(v+3));
|
||||
}
|
||||
|
||||
void glTexCoord2f(GLfloat s, GLfloat t) {
|
||||
vert_u = s;
|
||||
vert_v = t;
|
||||
}
|
||||
|
||||
void glTexCoord2fv(GLfloat *v) {
|
||||
vert_u = *v;
|
||||
vert_v = *(v+1);
|
||||
}
|
||||
|
||||
static pvr_poly_hdr_t user_clip = {
|
||||
PVR_CMD_USERCLIP, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
};
|
||||
|
||||
static void send_user_clip() {
|
||||
pvr_prim(&user_clip, sizeof(pvr_poly_hdr_t));
|
||||
}
|
||||
/* Setup the hardware user clip rectangle. It will be sent during glBegin.
|
||||
|
||||
The minimum clip rectangle is a 32x32 area which is dependent on the tile
|
||||
size use by the tile accelerator. The PVR swithes off rendering to tiles
|
||||
outside or inside the defined rectangle dependant upon the 'clipmode'
|
||||
bits
|
||||
in the polygon header.
|
||||
|
||||
Clip rectangles therefore must have a size that is some multiple of 32.
|
||||
|
||||
glScissor(0, 0, 32, 32) allows only the 'tile' in the lower left
|
||||
hand corner of the screen to be modified and glScissor(0, 0, 0, 0)
|
||||
disallows modification to all 'tiles' on the screen.
|
||||
*/
|
||||
void glScissor(GLint x, GLint y, GLsizei width, GLsizei height) {
|
||||
GLint minx, miny, maxx, maxy;
|
||||
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
assert((width >= 0) && (height >= 0));
|
||||
gl_scissor_x = x;
|
||||
gl_scissor_y = y;
|
||||
gl_scissor_width = CLAMP(width, 0, gl_screen_width);
|
||||
gl_scissor_height = CLAMP(height, 0, gl_screen_height);
|
||||
|
||||
minx = gl_scissor_x;
|
||||
/* force the origin to the lower left-hand corner of the screen */
|
||||
miny = /**/(gl_screen_height - gl_scissor_height) - /**/ gl_scissor_y;
|
||||
maxx = (gl_scissor_width + minx);
|
||||
maxy = (gl_scissor_height + miny);
|
||||
|
||||
/* load command structure while mapping screen coords to TA tiles */
|
||||
user_clip.d1 = CLAMP(minx/32, 0, gl_screen_width/32);
|
||||
user_clip.d2 = CLAMP(miny/32, 0, gl_screen_height/32);
|
||||
user_clip.d3 = CLAMP((maxx/32)-1, 0, gl_screen_width/32);
|
||||
user_clip.d4 = CLAMP((maxy/32)-1, 0, gl_screen_height/32);
|
||||
|
||||
gl_scissor_dirty = GL_TRUE;
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
}
|
||||
|
180
glfog.c
Normal file
180
glfog.c
Normal file
|
@ -0,0 +1,180 @@
|
|||
/* KallistiGL for KOS ##version##
|
||||
|
||||
glfog.c
|
||||
(c)2002 Paul Boese
|
||||
*/
|
||||
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include "glinternal.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <dc/pvr.h>
|
||||
|
||||
CVSID("$Id: glfog.c,v 1.2 2002/04/03 03:36:15 axlen Exp $");
|
||||
|
||||
#define TEST_EQ_4V(a,b) ((a)[0] == (b)[0] && \
|
||||
(a)[1] == (b)[1] && \
|
||||
(a)[2] == (b)[2] && \
|
||||
(a)[3] == (b)[3])
|
||||
|
||||
/* Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0] */
|
||||
#define INT_TO_FLOAT(I) ((2.0F * (I) + 1.0F) * (1.0F/4294967294.0F))
|
||||
|
||||
|
||||
/* prototypes */
|
||||
void Fogfv( GLenum pname, const GLfloat *params );
|
||||
void DCFogfv( GLenum pname, const GLfloat *params );
|
||||
|
||||
|
||||
/* functions */
|
||||
void glFogf(GLenum pname, GLfloat param)
|
||||
{
|
||||
glFogfv(pname, ¶m);
|
||||
}
|
||||
|
||||
|
||||
void glFogi(GLenum pname, GLint param )
|
||||
{
|
||||
GLfloat fparam = (GLfloat) param;
|
||||
glFogfv(pname, &fparam);
|
||||
}
|
||||
|
||||
|
||||
void glFogiv(GLenum pname, const GLint *params )
|
||||
{
|
||||
GLfloat p[4];
|
||||
switch (pname) {
|
||||
case GL_FOG_MODE:
|
||||
case GL_FOG_DENSITY:
|
||||
case GL_FOG_START:
|
||||
case GL_FOG_END:
|
||||
case GL_FOG_INDEX:
|
||||
p[0] = (GLfloat) *params;
|
||||
break;
|
||||
case GL_FOG_COLOR:
|
||||
p[0] = INT_TO_FLOAT( params[0] );
|
||||
p[1] = INT_TO_FLOAT( params[1] );
|
||||
p[2] = INT_TO_FLOAT( params[2] );
|
||||
p[3] = INT_TO_FLOAT( params[3] );
|
||||
break;
|
||||
default:
|
||||
/* Error will be caught later in Fogfv */
|
||||
;
|
||||
}
|
||||
glFogfv(pname, p);
|
||||
}
|
||||
|
||||
|
||||
void glFogfv( GLenum pname, const GLfloat *params )
|
||||
{
|
||||
GLenum m;
|
||||
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
switch (pname) {
|
||||
case GL_FOG_MODE:
|
||||
m = (GLenum) (GLint) *params;
|
||||
switch (m) {
|
||||
case GL_LINEAR:
|
||||
case GL_EXP:
|
||||
case GL_EXP2:
|
||||
break;
|
||||
default:
|
||||
assert_msg(0, "Unknown fog mode.");
|
||||
return;
|
||||
}
|
||||
if (gl_fog_mode == m)
|
||||
return;
|
||||
/* flush vertices here */
|
||||
gl_fog_mode = m;
|
||||
break;
|
||||
case GL_FOG_DENSITY:
|
||||
if (*params<0.0) {
|
||||
assert_msg(0, "Invalid value - fog density < zero.");
|
||||
return;
|
||||
}
|
||||
if (gl_fog_density == *params)
|
||||
return;
|
||||
/* flush vertices here */
|
||||
gl_fog_density = *params;
|
||||
break;
|
||||
case GL_FOG_START:
|
||||
if (gl_fog_start == *params)
|
||||
return;
|
||||
/* flush vertices here */
|
||||
gl_fog_start = *params;
|
||||
break;
|
||||
case GL_FOG_END:
|
||||
if (gl_fog_end == *params)
|
||||
return;
|
||||
/* flush vertices here */
|
||||
gl_fog_end = *params;
|
||||
break;
|
||||
case GL_FOG_INDEX:
|
||||
if (gl_fog_index == *params)
|
||||
return;
|
||||
/* flush vertices here */
|
||||
gl_fog_index = *params;
|
||||
break;
|
||||
case GL_FOG_COLOR:
|
||||
if (TEST_EQ_4V(gl_fog_color, params))
|
||||
return;
|
||||
/* flush vertices here */
|
||||
gl_fog_color[0] = params[0];
|
||||
gl_fog_color[1] = params[1];
|
||||
gl_fog_color[2] = params[2];
|
||||
gl_fog_color[3] = params[3];
|
||||
break;
|
||||
default:
|
||||
assert_msg(0, "Invalid parameter.");
|
||||
return;
|
||||
}
|
||||
DCFogfv( pname, params );
|
||||
}
|
||||
|
||||
/* DC specific interface for fog */
|
||||
|
||||
void fog_table_color4fv(GLfloat *v) {
|
||||
pvr_fog_table_color(*(v+3), *v, *(v+1), *(v+2));
|
||||
}
|
||||
|
||||
/* void fog_set_vertex_color4fv(GLfloat *v) {
|
||||
pvr_fog_vertex_color(*(v+3), *v, *(v+1), *(v+2));
|
||||
} */
|
||||
|
||||
void DCFogfv( GLenum pname, const GLfloat *params ) {
|
||||
|
||||
/* Just drop thru here and setup DC registers using dcutils fog.
|
||||
**
|
||||
** Future Note:
|
||||
** We should have a GL_KOS_FOG_TYPE enum that will give the user
|
||||
** a choice of GL_KOS_FOG_TABLE, GL_KOS_FOG_VERTEX, and maybe
|
||||
** GL_KOS_FOG_TABLE2
|
||||
*/
|
||||
switch (pname) {
|
||||
case GL_FOG_START:
|
||||
case GL_FOG_END:
|
||||
pvr_fog_far_depth(gl_fog_end);
|
||||
case GL_FOG_INDEX:
|
||||
case GL_FOG_DENSITY:
|
||||
case GL_FOG_COLOR:
|
||||
fog_table_color4fv(gl_fog_color);
|
||||
/* fog_set_vertex_color4fv(gl_fog_color); */
|
||||
case GL_FOG_MODE:
|
||||
switch (gl_fog_mode) {
|
||||
case GL_EXP:
|
||||
pvr_fog_table_exp(gl_fog_density);
|
||||
break;
|
||||
case GL_EXP2:
|
||||
pvr_fog_table_exp2(gl_fog_density);
|
||||
break;
|
||||
case GL_LINEAR:
|
||||
pvr_fog_table_linear(gl_fog_start, gl_fog_end);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
166
glinternal.h
Normal file
166
glinternal.h
Normal file
|
@ -0,0 +1,166 @@
|
|||
/* KallistiGL for KOS ##version##
|
||||
|
||||
glinternal.c
|
||||
(c)2001 Dan Potter
|
||||
|
||||
$Id: glinternal.h,v 1.13 2002/09/05 07:36:23 bardtx Exp $
|
||||
*/
|
||||
|
||||
#ifndef __GL_GLINTERNAL_H
|
||||
#define __GL_GLINTERNAL_H
|
||||
|
||||
/* Implementation details; not to be used externally */
|
||||
#include <GL/gl.h>
|
||||
#include <dc/pvr.h>
|
||||
#include <dc/matrix.h>
|
||||
|
||||
/* AFAIK, the PowerVR simulates a 32bit depth buffer */
|
||||
#define DEPTHBUFFER_MAX ((GLfloat)0xffffffff)
|
||||
|
||||
/* "Clear color" -- really the background plane color */
|
||||
extern GLfloat gl_clear_color[4];
|
||||
|
||||
/* Capability mask (for glEnable() and glDisable()) */
|
||||
extern GLbitfield gl_capabilities;
|
||||
|
||||
/* Enabled lists (PVR specific) */
|
||||
extern GLbitfield gl_enabled_lists;
|
||||
|
||||
/* Current primitive type (GL_TRIANGLES, etc) */
|
||||
extern GLenum gl_prim_type;
|
||||
|
||||
/* Current polygon context */
|
||||
extern pvr_poly_cxt_t gl_poly_cxt;
|
||||
|
||||
/* Poly header buffer submitted? */
|
||||
extern GLboolean gl_pbuf_submitted;
|
||||
|
||||
/* Current Blend functions */
|
||||
extern GLint gl_blend_src;
|
||||
extern GLint gl_blend_dst;
|
||||
|
||||
/* Currently selected texture header */
|
||||
extern pvr_poly_cxt_t *gl_cur_texture;
|
||||
|
||||
/* a "null" texture header for colored polys */
|
||||
extern pvr_poly_cxt_t gl_null_texture;
|
||||
|
||||
/* Depth range */
|
||||
extern GLclampf gl_depthrange_near;
|
||||
extern GLclampf gl_depthrange_far;
|
||||
|
||||
/* Screen size */
|
||||
extern GLsizei gl_screen_width;
|
||||
extern GLsizei gl_screen_height;
|
||||
|
||||
/* Viewport size */
|
||||
extern GLint gl_viewport_x1, gl_viewport_y1,
|
||||
gl_viewport_width, gl_viewport_height;
|
||||
|
||||
/* Viewport mapping */
|
||||
extern GLfloat gl_viewport_scale[3];
|
||||
extern GLfloat gl_viewport_offset[3];
|
||||
|
||||
/* Scissor clipping */
|
||||
extern GLint gl_scissor_x;
|
||||
extern GLint gl_scissor_y;
|
||||
extern GLsizei gl_scissor_width;
|
||||
extern GLsizei gl_scissor_height;
|
||||
extern GLboolean gl_scissor_dirty;
|
||||
|
||||
/* Transformation matrices; possibilities are:
|
||||
GL_MODELVIEW
|
||||
GL_PROJECTION
|
||||
GL_TEXTURE
|
||||
*/
|
||||
extern matrix_t gl_trans_mats[GL_MATRIX_COUNT] __attribute__((aligned(32)));
|
||||
extern int gl_matrix_mode;
|
||||
extern GLboolean gl_matrix_dirty;
|
||||
|
||||
/* Frustum attributes */
|
||||
typedef struct {
|
||||
float left, right, bottom, top, znear, zfar;
|
||||
} gl_frustum_t;
|
||||
|
||||
extern gl_frustum_t gl_frustum;
|
||||
|
||||
/* Some happy macros */
|
||||
#define TXR_ENABLED (gl_capabilities & GL_TEXTURE_2D)
|
||||
#define AUTOUV_ENABLED (gl_capabilities & GL_KOS_AUTO_UV)
|
||||
#define FOG_ENABLED (gl_capabilities & GL_FOG)
|
||||
#define BLEND_ENABLED (gl_capabilities & GL_BLEND)
|
||||
#define SCISSOR_ENABLED (gl_capabilities & GL_SCISSOR_TEST)
|
||||
#define USERCLIP_OUTSIDE_ENABLED (gl_capabilities & GL_KOS_USERCLIP_OUTSIDE)
|
||||
#define MODIFIER_ENABLED (gl_capabilities & GL_KOS_MODIFIER)
|
||||
#define CHEAP_SHADOW_ENABLED (gl_capabilities & GL_KOS_CHEAP_SHADOW)
|
||||
#define ZCLIP_ENABLED (gl_capabilities & GL_KOS_NEARZ_CLIPPING)
|
||||
#define LIGHTING_ENABLED (gl_capabilities & GL_LIGHT0)
|
||||
|
||||
/* Currently active list */
|
||||
extern GLbitfield gl_active_list;
|
||||
|
||||
/* Face culling enabled/disabled */
|
||||
extern GLboolean gl_cull_face;
|
||||
|
||||
/* Front face */
|
||||
extern GLenum gl_front_face;
|
||||
|
||||
/* Culling mode */
|
||||
extern GLenum gl_cull_mode;
|
||||
|
||||
/* Fog Attributes */
|
||||
extern GLfloat gl_fog_color[4];
|
||||
extern GLfloat gl_fog_density;
|
||||
extern GLfloat gl_fog_start;
|
||||
extern GLfloat gl_fog_end;
|
||||
extern GLfloat gl_fog_index; /* unused */
|
||||
extern GLenum gl_fog_mode;
|
||||
|
||||
/* Point size */
|
||||
extern GLfloat gl_point_size;
|
||||
|
||||
/* Vertex buffers
|
||||
|
||||
It is important to align the vertex buffers for use with the
|
||||
the direct render API. I found 8192 gave the best results, but 32,
|
||||
64, and 1024 also worked well. To see cache thrashing in action try
|
||||
setting the alignment to 16384 or 32768. The polys per second will
|
||||
drop by about half.
|
||||
|
||||
mat_transform seems to work best when the source and destination buffers
|
||||
are seperate. Therefore we have a pre and post transform vertex buffer
|
||||
|
||||
I'm quite aware of how wasteful this is. It's a simple matter that this
|
||||
is how you have to treat the PVR to get decent poly drawing rates.
|
||||
|
||||
What's needed is a way to collect long vertex [Strips, Fans, Polygons]
|
||||
and blast them to the store queue every 16 to 32 verts all the while
|
||||
maintaining the proper PVR_CMD_VERTEX and ...EOL requirements. One
|
||||
way might be to keep a copy of the last vertex submitted and toss
|
||||
it to the PVR in the glEnd statement. You will have to keep track of
|
||||
verts whose z values go < 0 and either clip them to the view frustum or
|
||||
cull them entirely. But you'll have to do this carefully because the PVR
|
||||
does not like degenerate triangles or strips. */
|
||||
|
||||
typedef struct {
|
||||
uint32 flags;
|
||||
float x, y, z, w;
|
||||
float u, v;
|
||||
uint32 argb, oargb;
|
||||
} gl_vertex_t;
|
||||
|
||||
#define VBUF_SIZE 128
|
||||
/* Pre-xformed vertex buffer */
|
||||
extern gl_vertex_t gl_vbuf[VBUF_SIZE] __attribute__((aligned(8192)));
|
||||
/* Post-xformed vertex buffer */
|
||||
extern gl_vertex_t gl_xbuf[VBUF_SIZE] __attribute__((aligned(8192)));
|
||||
extern int gl_vbuf_top;
|
||||
|
||||
/* some internal prototypes */
|
||||
extern void modifier_check_end();
|
||||
extern void modifier_end();
|
||||
extern void fix_vfzclip_matrices();
|
||||
extern void vfzclip_check_end();
|
||||
extern void vfzclip_end();
|
||||
#endif /* __GL_GLINTERNAL_H */
|
||||
|
212
glkos.c
Normal file
212
glkos.c
Normal file
|
@ -0,0 +1,212 @@
|
|||
/* KallistiGL for KOS ##version##
|
||||
|
||||
glkos.c
|
||||
(c)2001 Dan Potter
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <dc/video.h>
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include "glinternal.h"
|
||||
#include "glmacros.h"
|
||||
|
||||
CVSID("$Id: glkos.c,v 1.14 2002/09/05 07:36:23 bardtx Exp $");
|
||||
|
||||
/* KOS-specific APIs */
|
||||
|
||||
int glKosInit() {
|
||||
GLfloat w, h;
|
||||
static pvr_stats_t pvr_stats;
|
||||
|
||||
if (pvr_get_stats(&pvr_stats)) {
|
||||
dbglog(DBG_ERROR, "gl: glKosInit - No PVR lists enabled!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Pre-initialize all the globals */
|
||||
gl_clear_color[0] =
|
||||
gl_clear_color[1] =
|
||||
gl_clear_color[2] =
|
||||
gl_clear_color[3] = 0.0f;
|
||||
gl_capabilities = 0;
|
||||
gl_prim_type = 0;
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
|
||||
gl_enabled_lists = pvr_stats.enabled_list_mask | GL_LIST_END;
|
||||
gl_active_list = GL_LIST_NONE;
|
||||
|
||||
/* Reset all matrices */
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
glMatrixMode(GL_TEXTURE);
|
||||
glLoadIdentity();
|
||||
|
||||
/* Setup the basic polygon context */
|
||||
pvr_poly_cxt_col(&gl_poly_cxt, PVR_LIST_OP_POLY);
|
||||
/* Adjust context for GL conformance */
|
||||
gl_poly_cxt.gen.culling = PVR_CULLING_NONE;
|
||||
|
||||
/* Make a NULL Texture */
|
||||
pvr_poly_cxt_col(&gl_null_texture, PVR_LIST_OP_POLY);
|
||||
gl_cur_texture = &gl_null_texture;
|
||||
|
||||
glKosGetScreenSize(&w, &h);
|
||||
/* The screen w & h is used internally by some functions */
|
||||
gl_screen_width = (GLsizei)w; gl_screen_height = (GLsizei)h;
|
||||
|
||||
/* Initialize the viewport */
|
||||
glDepthRange(0.0f, 1.0f);
|
||||
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
|
||||
|
||||
/* Initialize the scissor test rectangle */
|
||||
glScissor(0, 0, (GLsizei)w, (GLsizei)h);
|
||||
|
||||
/* Initialize fog */
|
||||
glFogi(GL_FOG_MODE, GL_EXP);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void glKosShutdown() {
|
||||
}
|
||||
|
||||
void glKosGetScreenSize(GLfloat *w, GLfloat *h) {
|
||||
*w = vid_mode->width;
|
||||
*h = vid_mode->height;
|
||||
}
|
||||
|
||||
static void _gl_list_begin(uint32 list) {
|
||||
pvr_list_begin(list);
|
||||
gl_poly_cxt.list_type = list;
|
||||
}
|
||||
|
||||
void glKosBeginFrame() {
|
||||
uint32 tmp_list;
|
||||
|
||||
pvr_wait_ready();
|
||||
pvr_scene_begin();
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
gl_active_list = GL_LIST_FIRST;
|
||||
|
||||
/* we can't assume GL_LIST_OPAQUE_POLY is the first enabled list
|
||||
anymore! Advance to the first enabled list if opaque list is
|
||||
not first already. */
|
||||
tmp_list = gl_active_list;
|
||||
if (!(gl_active_list&gl_enabled_lists)) {
|
||||
do {
|
||||
tmp_list = gl_active_list = (gl_active_list << 1);
|
||||
tmp_list &= gl_enabled_lists;
|
||||
} while(tmp_list==0);
|
||||
}
|
||||
|
||||
switch(gl_active_list) {
|
||||
case GL_LIST_OPAQUE_POLY:
|
||||
_gl_list_begin(PVR_LIST_OP_POLY);
|
||||
break;
|
||||
case GL_LIST_OPAQUE_MOD:
|
||||
_gl_list_begin(PVR_LIST_OP_MOD);
|
||||
break;
|
||||
case GL_LIST_TRANS_POLY:
|
||||
_gl_list_begin(PVR_LIST_TR_POLY);
|
||||
break;
|
||||
case GL_LIST_TRANS_MOD:
|
||||
_gl_list_begin(PVR_LIST_TR_MOD);
|
||||
break;
|
||||
case GL_LIST_PUNCHTHRU:
|
||||
_gl_list_begin(PVR_LIST_PT_POLY);
|
||||
break;
|
||||
case GL_LIST_END:
|
||||
/* no lists were enabled!?! */
|
||||
dbglog(DBG_ERROR, "gl: no lists enabled in glKosBeginFrame!");
|
||||
/* this is probably a bailout condition! */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void glKosFinishFrame() {
|
||||
while (gl_active_list != GL_LIST_NONE)
|
||||
glKosFinishList();
|
||||
pvr_scene_finish();
|
||||
}
|
||||
|
||||
void glKosFinishList() {
|
||||
uint32 tmp_list;
|
||||
|
||||
if (gl_active_list == GL_LIST_NONE)
|
||||
return;
|
||||
|
||||
pvr_list_finish();
|
||||
|
||||
/* Advance to the next list */
|
||||
tmp_list = gl_active_list;
|
||||
do {
|
||||
tmp_list = gl_active_list = (gl_active_list << 1);
|
||||
tmp_list &= gl_enabled_lists;
|
||||
} while(tmp_list==0);
|
||||
|
||||
switch(gl_active_list) {
|
||||
case GL_LIST_OPAQUE_MOD:
|
||||
_gl_list_begin(PVR_LIST_OP_MOD);
|
||||
break;
|
||||
case GL_LIST_TRANS_POLY:
|
||||
_gl_list_begin(PVR_LIST_TR_POLY);
|
||||
break;
|
||||
case GL_LIST_TRANS_MOD:
|
||||
_gl_list_begin(PVR_LIST_TR_MOD);
|
||||
break;
|
||||
case GL_LIST_PUNCHTHRU:
|
||||
_gl_list_begin(PVR_LIST_PT_POLY);
|
||||
break;
|
||||
case GL_LIST_END:
|
||||
gl_active_list = GL_LIST_NONE;
|
||||
}
|
||||
|
||||
/* We haven't submitted the new poly headers */
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
}
|
||||
|
||||
/* This can be used for KGL Direct Rendering: applies one of the GL
|
||||
matrices to the matrix registers and lets you do whatever you
|
||||
want after that. */
|
||||
static matrix_t msv __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 }
|
||||
};
|
||||
void glKosMatrixApply(GLenum mode) {
|
||||
gl_matrix_dirty = GL_TRUE;
|
||||
if (mode < GL_KOS_SCREENVIEW) {
|
||||
mat_apply(gl_trans_mats + mode);
|
||||
} else {
|
||||
msv[0][0] = gl_viewport_scale[0];
|
||||
msv[1][1] = -gl_viewport_scale[1];
|
||||
msv[3][0] = gl_viewport_offset[0];
|
||||
msv[3][1] = gl_screen_height - gl_viewport_offset[1];
|
||||
mat_apply(&msv);
|
||||
}
|
||||
}
|
||||
|
||||
/* A matrix clear function, for completeness */
|
||||
void glKosMatrixIdent() {
|
||||
gl_matrix_dirty = GL_TRUE;
|
||||
mat_identity();
|
||||
}
|
||||
|
||||
/* Tell KGL that the poly header is dirty again (i.e., you did something
|
||||
manually that it doesn't know about) */
|
||||
void glKosPolyHdrDirty() {
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
}
|
||||
|
||||
/* Tell KGL that the matrix registers are dirty (i.e., you did something
|
||||
manually that it doesn't know about). Note that this does not include
|
||||
the above functions because those already take this step. */
|
||||
void glKosMatrixDirty() {
|
||||
gl_matrix_dirty = GL_TRUE;
|
||||
}
|
29
gllight.c
Normal file
29
gllight.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
/* KallistiGL for KOS ##version##
|
||||
|
||||
gllight.c
|
||||
(c)2001 Dan Potter
|
||||
*/
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include "glinternal.h"
|
||||
#include "glmacros.h"
|
||||
|
||||
#include "assert.h"
|
||||
|
||||
CVSID("$Id: gllight.c,v 1.5 2002/04/03 03:36:53 axlen Exp $");
|
||||
|
||||
/* Lighting */
|
||||
void glShadeModel(GLenum mode) {
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
switch(mode)
|
||||
{
|
||||
case GL_FLAT:
|
||||
gl_poly_cxt.gen.shading = PVR_SHADE_FLAT;
|
||||
break;
|
||||
case GL_SMOOTH:
|
||||
gl_poly_cxt.gen.shading = PVR_SHADE_GOURAUD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
20
glmacros.h
Normal file
20
glmacros.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
/* GL for KOS ##version##
|
||||
|
||||
glmacros.c
|
||||
(c)2001 Paul Boese
|
||||
|
||||
$Id: glmacros.h,v 1.5 2002/06/28 04:57:31 axlen Exp $
|
||||
*/
|
||||
|
||||
#ifndef __GL_GLMACROS_H
|
||||
#define __GL_GLMACROS_H
|
||||
|
||||
|
||||
#define ABS(n) ( (n)<(0.0f) ? (-n):(n) )
|
||||
#define NEG(n) ( (n)>(0.0f) ? (-n):(n) )
|
||||
#define CLAMP01(x) ( (x)<(0.0f) ? ((0.0f)) : ((x)>(1.0f) ? ((1.0f)) : (x)) )
|
||||
|
||||
/* Clamp X to [MIN,MAX]: */
|
||||
#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) )
|
||||
|
||||
#endif /* __GL_GLMACROS_H */
|
232
glmisc.c
Normal file
232
glmisc.c
Normal file
|
@ -0,0 +1,232 @@
|
|||
/* KallistiGL for KOS ##version##
|
||||
|
||||
glmisc.c
|
||||
(c)2001 Dan Potter
|
||||
*/
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include "glinternal.h"
|
||||
#include "glmacros.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
CVSID("$Id: glmisc.c,v 1.17 2002/07/08 05:28:28 axlen Exp $");
|
||||
|
||||
/* Miscellaneous APIs */
|
||||
|
||||
/* Set the background clear color */
|
||||
void glClearColor(GLclampf red,
|
||||
GLclampf green,
|
||||
GLclampf blue,
|
||||
GLclampf alpha) {
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
gl_clear_color[0] = CLAMP01(red);
|
||||
gl_clear_color[1] = CLAMP01(green);
|
||||
gl_clear_color[2] = CLAMP01(blue);
|
||||
gl_clear_color[3] = CLAMP01(alpha);
|
||||
pvr_set_bg_color(gl_clear_color[0]*gl_clear_color[3],
|
||||
gl_clear_color[1]*gl_clear_color[3],
|
||||
gl_clear_color[2]*gl_clear_color[3]);
|
||||
}
|
||||
|
||||
/* NOP: there's nothing to clear on the PVR2 */
|
||||
void glClear(GLbitfield mask) {
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
}
|
||||
|
||||
/* Set front face */
|
||||
void glFrontFace(GLenum mode) {
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
switch(mode) {
|
||||
case GL_CW:
|
||||
case GL_CCW:
|
||||
gl_front_face = mode;
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set face culling mode */
|
||||
void glCullFace(GLenum mode) {
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
switch(mode) {
|
||||
case GL_FRONT:
|
||||
case GL_BACK:
|
||||
gl_cull_mode = mode;
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Enable / disable capabilities */
|
||||
void glEnable(GLenum cap) {
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
switch(cap) {
|
||||
case GL_TEXTURE_2D:
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
gl_poly_cxt.txr.enable = PVR_TEXTURE_ENABLE;
|
||||
break;
|
||||
case GL_BLEND:
|
||||
if (gl_active_list != GL_LIST_TRANS_POLY) {
|
||||
dbglog(DBG_ERROR, "gl: invalid list to enable GL_BLEND inside");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case GL_CULL_FACE:
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
gl_cull_face = GL_TRUE;
|
||||
break;
|
||||
case GL_FOG:
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
gl_poly_cxt.gen.fog_type = PVR_FOG_TABLE;
|
||||
break;
|
||||
case GL_SCISSOR_TEST:
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
gl_poly_cxt.gen.clip_mode = PVR_USERCLIP_INSIDE;
|
||||
if (USERCLIP_OUTSIDE_ENABLED)
|
||||
gl_capabilities &= ~((GLbitfield)GL_KOS_USERCLIP_OUTSIDE);
|
||||
break;
|
||||
case GL_KOS_USERCLIP_OUTSIDE:
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
gl_poly_cxt.gen.clip_mode = PVR_USERCLIP_OUTSIDE;
|
||||
if (SCISSOR_ENABLED)
|
||||
gl_capabilities &= ~((GLbitfield)GL_SCISSOR_TEST);
|
||||
break;
|
||||
case GL_KOS_MODIFIER:
|
||||
assert_msg(0, "GL_KOS_MODIFER not implemented");
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
gl_poly_cxt.fmt.modifier = PVR_MODIFIER_ENABLE;
|
||||
break;
|
||||
case GL_KOS_CHEAP_SHADOW:
|
||||
assert_msg(0, "GL_KOS_CHEAP_SHADOW not implemented");
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
gl_poly_cxt.gen.modifier_mode = PVR_MODIFIER_CHEAP_SHADOW;
|
||||
break;
|
||||
case GL_KOS_NEARZ_CLIPPING:
|
||||
gl_matrix_dirty = GL_TRUE;
|
||||
break;
|
||||
case GL_LIGHT0:
|
||||
assert_msg(0, "GL_LIGHTi not implemented");
|
||||
break;
|
||||
}
|
||||
|
||||
gl_capabilities |= (GLbitfield)cap;
|
||||
}
|
||||
|
||||
void glDisable(GLenum cap) {
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
switch(cap) {
|
||||
case GL_TEXTURE_2D:
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
gl_poly_cxt.txr.enable = PVR_TEXTURE_DISABLE;
|
||||
break;
|
||||
case GL_BLEND:
|
||||
if (gl_active_list == GL_LIST_TRANS_POLY) {
|
||||
dbglog(DBG_ERROR, "gl: invalid list to disable GL_BLEND inside");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case GL_CULL_FACE:
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
gl_cull_face = GL_FALSE;
|
||||
break;
|
||||
case GL_FOG:
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
gl_poly_cxt.gen.fog_type = PVR_FOG_DISABLE;
|
||||
break;
|
||||
case GL_SCISSOR_TEST:
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
gl_poly_cxt.gen.clip_mode = PVR_USERCLIP_DISABLE;
|
||||
if (USERCLIP_OUTSIDE_ENABLED)
|
||||
gl_capabilities &= ~((GLbitfield)GL_KOS_USERCLIP_OUTSIDE);
|
||||
break;
|
||||
case GL_KOS_USERCLIP_OUTSIDE:
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
gl_poly_cxt.gen.clip_mode = PVR_USERCLIP_DISABLE;
|
||||
if (SCISSOR_ENABLED)
|
||||
gl_capabilities &= ~((GLbitfield)GL_SCISSOR_TEST);
|
||||
break;
|
||||
case GL_KOS_MODIFIER:
|
||||
assert_msg(0, "GL_KOS_MODIFER not implemented");
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
gl_poly_cxt.fmt.modifier = PVR_MODIFIER_DISABLE;
|
||||
break;
|
||||
case GL_KOS_CHEAP_SHADOW:
|
||||
assert_msg(0, "GL_KOS_CHEAP_SHADOW not implemented");
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
gl_poly_cxt.gen.modifier_mode = PVR_MODIFIER_NORMAL;
|
||||
break;
|
||||
case GL_KOS_NEARZ_CLIPPING:
|
||||
gl_matrix_dirty = GL_TRUE;
|
||||
break;
|
||||
case GL_LIGHT0:
|
||||
assert_msg(0, "GL_LIGHTi not implemented");
|
||||
break;
|
||||
}
|
||||
|
||||
gl_capabilities &= ~((GLbitfield)cap);
|
||||
}
|
||||
|
||||
/* We have no rendering pipeline yet, so this is a NOP */
|
||||
void glFlush() {
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
}
|
||||
|
||||
/* There aren't any useful hints to set yet, so this is a NOP */
|
||||
void glHint(GLenum target, GLenum mode) {
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
}
|
||||
|
||||
void glPointSize(GLfloat size) {
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
gl_point_size = CLAMP(size, 0.0f, 100.0f);
|
||||
}
|
||||
|
||||
/* These strings should go somewhere else */
|
||||
const GLubyte *glGetString(GLenum name) {
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
switch(name) {
|
||||
case GL_VENDOR:
|
||||
return "Cryptic Allusions";
|
||||
|
||||
case GL_RENDERER:
|
||||
return "KallistiOS";
|
||||
|
||||
case GL_VERSION:
|
||||
return "1.1";
|
||||
|
||||
case GL_EXTENSIONS:
|
||||
return "GL_ARB_transpose_matrix ";
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
/* A limited view into the guts of KGL - This will change! */
|
||||
void glGetFloatv(GLenum pname, GLfloat *params) {
|
||||
int i, j;
|
||||
matrix_t *pmat = (matrix_t*)params;
|
||||
|
||||
switch(pname) {
|
||||
case GL_MODELVIEW_MATRIX:
|
||||
for (i=0; i<4; i++)
|
||||
for (j=0; j<4; j++)
|
||||
(*pmat)[i][j] = gl_trans_mats[GL_MODELVIEW][i][j];
|
||||
break;
|
||||
case GL_PROJECTION_MATRIX:
|
||||
for (i=0; i<4; i++)
|
||||
for (j=0; j<4; j++)
|
||||
(*pmat)[i][j] = gl_trans_mats[GL_PROJECTION][i][j];
|
||||
break;
|
||||
case GL_TEXTURE_MATRIX:
|
||||
for (i=0; i<4; i++)
|
||||
for (j=0; j<4; j++)
|
||||
(*pmat)[i][j] = gl_trans_mats[GL_TEXTURE][i][j];
|
||||
break;
|
||||
default:
|
||||
assert_msg(0, "not glGet param not implemented");
|
||||
}
|
||||
}
|
214
glmodifier.c
Normal file
214
glmodifier.c
Normal file
|
@ -0,0 +1,214 @@
|
|||
/* KallistiGL for KOS ##version##
|
||||
|
||||
glmodifier.c
|
||||
(c)2002 Paul Boese
|
||||
|
||||
NOTE: This module is experimental, incomplete, and non-working
|
||||
*/
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include "glinternal.h"
|
||||
#include "glmacros.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <dc/matrix.h>
|
||||
#include <dc/pvr.h>
|
||||
|
||||
CVSID("$Id");
|
||||
|
||||
volatile pvr_modifier_vol_t *volume;
|
||||
static pvr_modifier_vol_t vol_vbuf, vol_xbuf;
|
||||
pvr_dr_state_t dr_state;
|
||||
static GLint mod_type = -1;
|
||||
|
||||
/* local buffer for textured, packed-color, affected by modifier vertex */
|
||||
pvr_vertex_tpcm_t vert_xbuf = {
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
};
|
||||
|
||||
/* Negative 1/w values annoy the pvr, so check for them */
|
||||
static inline int check_w(pvr_vertex_t *vert, int n) {
|
||||
int i;
|
||||
|
||||
for(i=0; i<n; i++)
|
||||
if (vert[i].z < 0) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Make sure the proper matrices are in the matrix registers */
|
||||
static void fix_matrices() {
|
||||
if (gl_matrix_dirty) {
|
||||
mat_identity();
|
||||
glKosMatrixApply(GL_KOS_SCREENVIEW);
|
||||
glKosMatrixApply(GL_PROJECTION);
|
||||
glKosMatrixApply(GL_MODELVIEW);
|
||||
|
||||
gl_matrix_dirty = GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static pvr_poly_hdr_t mod_hdr = {
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000
|
||||
};
|
||||
|
||||
void send_mod_hdr(void) {
|
||||
mod_hdr.cmd = PVR_CMD_MODIFIER;
|
||||
mod_hdr.mode1 = (mod_type << PVR_TA_PM1_MODIFIERINST_SHIFT) & PVR_TA_PM1_MODIFIERINST_MASK;
|
||||
|
||||
switch(gl_active_list) {
|
||||
case GL_LIST_OPAQUE_MOD:
|
||||
mod_hdr.cmd |= (PVR_LIST_OP_MOD << PVR_TA_CMD_TYPE_SHIFT) & PVR_TA_CMD_TYPE_MASK;
|
||||
break;
|
||||
case GL_LIST_TRANS_MOD:
|
||||
mod_hdr.cmd |= (PVR_LIST_TR_MOD << PVR_TA_CMD_TYPE_SHIFT) & PVR_TA_CMD_TYPE_MASK;
|
||||
break;
|
||||
default:
|
||||
assert_msg(0, "wrong list specified");
|
||||
break;
|
||||
}
|
||||
pvr_prim(&mod_hdr, sizeof(pvr_poly_hdr_t));
|
||||
}
|
||||
|
||||
void glKosModBegin(GLenum mode) {
|
||||
assert_msg(0,"not implemented");
|
||||
mod_type = mode;
|
||||
//pvr_dr_init(dr_state);
|
||||
send_mod_hdr();
|
||||
fix_matrices();
|
||||
}
|
||||
|
||||
void glKosModEnd(void) {
|
||||
assert_msg(0,"not implemented");
|
||||
mod_type = -1;
|
||||
}
|
||||
|
||||
void glKosModVolume9f(GLfloat ax, GLfloat ay, GLfloat az,
|
||||
GLfloat bx, GLfloat by, GLfloat bz,
|
||||
GLfloat cx, GLfloat cy, GLfloat cz) {
|
||||
|
||||
assert_msg(0,"not implemented");
|
||||
vol_vbuf.flags = PVR_CMD_VERTEX_EOL;
|
||||
vol_vbuf.ax = ax;
|
||||
vol_vbuf.ay = ay;
|
||||
vol_vbuf.az = az;
|
||||
vol_vbuf.bx = bx;
|
||||
vol_vbuf.by = by;
|
||||
vol_vbuf.bz = bz;
|
||||
vol_vbuf.cx = cx;
|
||||
vol_vbuf.cy = cy;
|
||||
vol_vbuf.cz = cz;
|
||||
mat_transform((vector_t*)&vol_vbuf.ax, (vector_t*)&vol_xbuf.ax, 3, sizeof(vector_t));
|
||||
|
||||
/* Can't use the alternating store queues cuz we're sending
|
||||
* 64 bytes at once with this vertex type
|
||||
*/
|
||||
vol_xbuf.flags = vol_vbuf.flags;
|
||||
vol_xbuf.d1 = vol_xbuf.d2 = vol_xbuf.d3 = 0;
|
||||
vol_xbuf.d4 = vol_xbuf.d5 = vol_xbuf.d6 = 0;
|
||||
pvr_prim(&vol_xbuf, sizeof(pvr_modifier_vol_t));
|
||||
//printf("[%2.2f, %2.2f]\n", cz, vol_xbuf.cz);
|
||||
}
|
||||
|
||||
static void end_quads() {
|
||||
int i, j, order[4] = {3, 0, 2, 1};
|
||||
|
||||
/* Should be four points in the buffer */
|
||||
assert_msg(gl_vbuf_top == 4, "Wrong number of vertices.");
|
||||
|
||||
gl_vbuf[order[3]].flags = PVR_CMD_VERTEX_EOL;
|
||||
/* mat_transform((vector_t*)&gl_vbuf[0].x, (vector_t*)&gl_xbuf[0].x, 4,
|
||||
sizeof(pvr_vertex_t)); */
|
||||
|
||||
for (i=0; i<4; i++) {
|
||||
float x = gl_vbuf[i].x, y = gl_vbuf[i].y, z = gl_vbuf[i].z, w = 1.0f;
|
||||
mat_trans_single4(x, y, z, w);
|
||||
gl_xbuf[i].x = x;
|
||||
gl_xbuf[i].y = y;
|
||||
if (w == 1.0f)
|
||||
gl_xbuf[i].z = ((gl_viewport_scale[2] * z) + gl_viewport_offset[2]);
|
||||
else
|
||||
gl_xbuf[i].z = w;
|
||||
}
|
||||
|
||||
/* Throw it all to the TA using direct render */
|
||||
if (check_w(gl_xbuf, 4))
|
||||
for (i=0; i<4; i++) {
|
||||
j = order[i];
|
||||
vert_xbuf.flags = gl_vbuf[j].flags;
|
||||
vert_xbuf.x = gl_xbuf[j].x;
|
||||
vert_xbuf.y = gl_xbuf[j].y;
|
||||
vert_xbuf.z = gl_xbuf[j].z;
|
||||
vert_xbuf.u0 = gl_vbuf[j].u;
|
||||
vert_xbuf.v0 = gl_vbuf[j].v;
|
||||
vert_xbuf.argb0 = gl_vbuf[j].argb;
|
||||
vert_xbuf.oargb0 = gl_vbuf[j].oargb;
|
||||
vert_xbuf.u1 = 0.0f;
|
||||
vert_xbuf.v1 = 0.0f;
|
||||
vert_xbuf.argb1 = 0xff00ff00;
|
||||
vert_xbuf.oargb1 = 0xffff0000;
|
||||
pvr_prim(&vert_xbuf, sizeof(pvr_vertex_tpcm_t));
|
||||
}
|
||||
}
|
||||
|
||||
void modifier_check_end() {
|
||||
/* What type of primitive was it? */
|
||||
switch(gl_prim_type) {
|
||||
case GL_POINTS:
|
||||
//end_points();
|
||||
gl_vbuf_top = 0;
|
||||
break;
|
||||
case GL_TRIANGLES:
|
||||
if (gl_vbuf_top == 3) {
|
||||
//end_triangles();
|
||||
gl_vbuf_top = 0;
|
||||
}
|
||||
break;
|
||||
case GL_TRIANGLE_STRIP:
|
||||
break;
|
||||
case GL_QUADS:
|
||||
if (gl_vbuf_top == 4) {
|
||||
end_quads();
|
||||
gl_vbuf_top = 0;
|
||||
}
|
||||
break;
|
||||
case GL_QUAD_STRIP:
|
||||
break;
|
||||
case GL_POLYGON:
|
||||
break;
|
||||
default:
|
||||
assert_msg(0, "gl_prim_type: Unknown primitive type.");
|
||||
}
|
||||
}
|
||||
|
||||
void modifier_end(void) {
|
||||
/* What type of primitive was it? */
|
||||
switch(gl_prim_type) {
|
||||
case GL_POINTS:
|
||||
break;
|
||||
case GL_TRIANGLES:
|
||||
break;
|
||||
case GL_TRIANGLE_STRIP:
|
||||
//end_triangle_strip();
|
||||
break;
|
||||
case GL_QUADS:
|
||||
break;
|
||||
case GL_QUAD_STRIP:
|
||||
//end_quad_strip();
|
||||
break;
|
||||
case GL_POLYGON:
|
||||
//end_polygon();
|
||||
break;
|
||||
default:
|
||||
assert_msg(0, "gl_prim_type: Unknown primitive type.");
|
||||
}
|
||||
gl_prim_type = 0;
|
||||
}
|
||||
|
||||
|
184
glnzclip.c
Normal file
184
glnzclip.c
Normal file
|
@ -0,0 +1,184 @@
|
|||
/* KallistiGL for KOS ##version##
|
||||
|
||||
glnzclip.c
|
||||
(c)2002 Paul Boese
|
||||
|
||||
Near Z Clipped primatives
|
||||
*/
|
||||
|
||||
/* This is experimental and subject to change - Currently only supports
|
||||
GL_TRIANGLES.
|
||||
|
||||
Note: this file was originally named glvfzclip.c. Not entirely
|
||||
correct. My Oops!
|
||||
*/
|
||||
|
||||
#include <kos.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include "glinternal.h"
|
||||
#include "glmacros.h"
|
||||
#include "glclip.h" /* Trilinear's inline near z clipper code */
|
||||
|
||||
#include <assert.h>
|
||||
#include <dc/matrix.h>
|
||||
#include <dc/pvr.h>
|
||||
|
||||
CVSID("$Id:");
|
||||
|
||||
/* Some local tranform stuff. It is generally faster to clip and
|
||||
light verts in view-space. The transform has been broken into
|
||||
two pieces to make that possibe. */
|
||||
static matrix_t mvp __attribute__((aligned(32)));
|
||||
|
||||
/* Make sure the proper matrices are in the matrix registers */
|
||||
void fix_vfzclip_matrices() {
|
||||
if (gl_matrix_dirty) {
|
||||
mat_load(gl_trans_mats + GL_PROJECTION);
|
||||
mat_apply(gl_trans_mats + GL_MODELVIEW);
|
||||
mat_store(&mvp);
|
||||
|
||||
gl_matrix_dirty = GL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32 frms = 0;
|
||||
/* translate verts from model-space to view-space */
|
||||
static void xltmodel(gl_vertex_t *invert, gl_vertex_t *outvert, int num) {
|
||||
int i;
|
||||
gl_vertex_t *ip, *op;
|
||||
|
||||
for (i=0; i<num; i++) {
|
||||
ip = &invert[i];
|
||||
op = &outvert[i];
|
||||
|
||||
/* Transform the vertex position by the MVP matrices - assume invert.w is always 1.0 */
|
||||
op->x = (mvp[0][0] * ip->x) + (mvp[1][0] * ip->y) + (mvp[2][0] * ip->z) + (mvp[3][0] * ip->w);
|
||||
op->y = (mvp[0][1] * ip->x) + (mvp[1][1] * ip->y) + (mvp[2][1] * ip->z) + (mvp[3][1] * ip->w);
|
||||
op->z = (mvp[0][2] * ip->x) + (mvp[1][2] * ip->y) + (mvp[2][2] * ip->z) + (mvp[3][2] * ip->w);
|
||||
op->w = (mvp[0][3] * ip->x) + (mvp[1][3] * ip->y) + (mvp[2][3] * ip->z) + (mvp[3][3] * ip->w);
|
||||
|
||||
/* copy other attributes */
|
||||
op->flags = ip->flags;
|
||||
op->u = ip->u;
|
||||
op->v = ip->v;
|
||||
op->argb = ip->argb;
|
||||
op->oargb = ip ->oargb;
|
||||
|
||||
if ((frms++)%20000 == 0)
|
||||
printf("z=%03.3f, w=%03.3f\n", op->z, op->w);
|
||||
}
|
||||
}
|
||||
|
||||
/* translate verts from view-space to the screen */
|
||||
static void xltview(gl_vertex_t *invert, gl_vertex_t *outvert, int num) {
|
||||
int i;
|
||||
gl_vertex_t *ip, *op;
|
||||
|
||||
for (i=0; i<num; i++) {
|
||||
ip = &invert[i];
|
||||
op = &outvert[i];
|
||||
|
||||
/* perspective divide */
|
||||
op->x = (ip->x /= ip->w);
|
||||
op->y = (ip->y /= ip->w);
|
||||
op->z = (ip->z /= ip->w);
|
||||
|
||||
/* Perform viewport mapping (note: this implicitly flips the y-axis) */
|
||||
op->x = (gl_viewport_scale[0] * op->x) + gl_viewport_offset[0];
|
||||
op->y = gl_screen_height - ((gl_viewport_scale[1] * op->y) + gl_viewport_offset[1]);
|
||||
op->z = (ip->w == 1.0) ? (gl_viewport_scale[2] * op->z) + gl_viewport_offset[2] : 1.0f / ip->w;
|
||||
}
|
||||
}
|
||||
|
||||
static void end_triangles() {
|
||||
int i, rslt;
|
||||
volatile pvr_vertex_t *vert;
|
||||
pvr_dr_state_t dr_state;
|
||||
|
||||
pvr_dr_init(dr_state);
|
||||
|
||||
/* Should be three points in the buffer */
|
||||
assert_msg(gl_vbuf_top == 3, "Wrong number of vertices.");
|
||||
|
||||
xltmodel(gl_vbuf, gl_xbuf, 3);
|
||||
rslt = ZClipTex(gl_xbuf);
|
||||
xltview(gl_xbuf, gl_xbuf, rslt);
|
||||
|
||||
/* Throw it all to the TA using direct render */
|
||||
if (rslt!=0) {
|
||||
gl_xbuf[rslt-1].flags = PVR_CMD_VERTEX_EOL;
|
||||
for (i=0; i<rslt; i++) {
|
||||
vert = pvr_dr_target(dr_state);
|
||||
vert->flags = gl_xbuf[i].flags;
|
||||
vert->x = gl_xbuf[i].x;
|
||||
vert->y = gl_xbuf[i].y;
|
||||
vert->z = gl_xbuf[i].z;
|
||||
vert->u = gl_xbuf[i].u;
|
||||
vert->v = gl_xbuf[i].v;
|
||||
vert->argb = gl_xbuf[i].argb;
|
||||
vert->oargb = gl_xbuf[i].oargb;
|
||||
pvr_dr_commit(vert);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void vfzclip_check_end() {
|
||||
/* What type of primitive was it? */
|
||||
switch(gl_prim_type) {
|
||||
case GL_POINTS:
|
||||
//end_points();
|
||||
assert_msg(0, "GL_POINTS not supported");
|
||||
gl_vbuf_top = 0;
|
||||
break;
|
||||
case GL_TRIANGLES:
|
||||
if (gl_vbuf_top == 3) {
|
||||
end_triangles();
|
||||
gl_vbuf_top = 0;
|
||||
}
|
||||
break;
|
||||
case GL_TRIANGLE_STRIP:
|
||||
assert_msg(0, "GL_TRIANGE_STRIP not supported");
|
||||
break;
|
||||
case GL_QUADS:
|
||||
assert_msg(0, "GL_QUADS not supported");
|
||||
if (gl_vbuf_top == 4) {
|
||||
//end_quads();
|
||||
gl_vbuf_top = 0;
|
||||
}
|
||||
break;
|
||||
case GL_QUAD_STRIP:
|
||||
assert_msg(0, "GL_QUAD_STRIP not supported");
|
||||
break;
|
||||
case GL_POLYGON:
|
||||
assert_msg(0, "GL_POLYGON not supported");
|
||||
break;
|
||||
default:
|
||||
assert_msg(0, "gl_prim_type: Unknown primitive type.");
|
||||
}
|
||||
}
|
||||
|
||||
void vfzclip_end(void) {
|
||||
/* What type of primitive was it? */
|
||||
switch(gl_prim_type) {
|
||||
case GL_POINTS:
|
||||
break;
|
||||
case GL_TRIANGLES:
|
||||
break;
|
||||
case GL_TRIANGLE_STRIP:
|
||||
//end_triangle_strip();
|
||||
break;
|
||||
case GL_QUADS:
|
||||
break;
|
||||
case GL_QUAD_STRIP:
|
||||
//end_quad_strip();
|
||||
break;
|
||||
case GL_POLYGON:
|
||||
//end_polygon();
|
||||
break;
|
||||
default:
|
||||
assert_msg(0, "gl_prim_type: Unknown primitive type.");
|
||||
}
|
||||
gl_prim_type = 0;
|
||||
}
|
||||
|
190
gltex.c
Normal file
190
gltex.c
Normal file
|
@ -0,0 +1,190 @@
|
|||
/* KallistiGL for KOS ##version##
|
||||
|
||||
gltex.c
|
||||
(c)2001 Dan Potter
|
||||
*/
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include "glinternal.h"
|
||||
#include "glmacros.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
|
||||
CVSID("$Id: gltex.c,v 1.11 2002/09/05 07:36:23 bardtx Exp $");
|
||||
|
||||
/* Texture handling */
|
||||
|
||||
/* Allocate "texture structures" (really poly context structs) */
|
||||
void glGenTextures(GLsizei n, GLuint *textures) {
|
||||
int i;
|
||||
pvr_poly_cxt_t *p;
|
||||
for (i=0; i<n; i++) {
|
||||
p = (pvr_poly_cxt_t*)malloc(sizeof(pvr_poly_cxt_t));
|
||||
|
||||
/* initial state for this texture object */
|
||||
p->txr.env = PVR_TXRENV_MODULATE;
|
||||
p->txr.enable = PVR_TEXTURE_ENABLE;
|
||||
p->txr.filter = PVR_FILTER_NONE;
|
||||
p->txr.alpha = PVR_TXRALPHA_DISABLE;
|
||||
p->txr.mipmap = PVR_MIPMAP_DISABLE;
|
||||
p->txr.mipmap_bias = PVR_MIPBIAS_NORMAL;
|
||||
p->txr.uv_flip = PVR_UVFLIP_NONE;
|
||||
p->txr.uv_clamp = PVR_UVCLAMP_NONE;
|
||||
p->txr.format = PVR_TXRFMT_NONE;
|
||||
p->txr.base = NULL;
|
||||
p->txr.width = -1;
|
||||
p->txr.height = -1;
|
||||
|
||||
textures[i] = (GLuint)p;
|
||||
}
|
||||
}
|
||||
|
||||
/* Delete textures from VRAM */
|
||||
void glDeleteTextures(GLsizei n, const GLuint *textures) {
|
||||
int i;
|
||||
|
||||
for (i=0; i<n; i++) {
|
||||
pvr_mem_free(((pvr_poly_cxt_t *)textures[i])->txr.base);
|
||||
free((void*)textures[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Bind a texture */
|
||||
void glBindTexture(GLenum type, GLuint texture) {
|
||||
assert(type == GL_TEXTURE_2D);
|
||||
|
||||
gl_cur_texture = (pvr_poly_cxt_t *)texture;
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
}
|
||||
|
||||
/* Load a texture from a 2D image */
|
||||
void glTexImage2D(GLenum target, GLint level,
|
||||
GLint internal_fmt,
|
||||
GLsizei width, GLsizei height,
|
||||
GLint border, GLenum format, GLenum type,
|
||||
const GLvoid *pixels) {
|
||||
pvr_ptr_t txr;
|
||||
|
||||
assert_msg(border == 0 && level == 0, "Borders and levels not supported.");
|
||||
assert_msg((internal_fmt & ~1) == (format & ~1), "Pixel conversion not supported.");
|
||||
|
||||
/* Allocate space for it */
|
||||
txr = pvr_mem_malloc(width * height * 2);
|
||||
|
||||
/* Load the texture data */
|
||||
if ((internal_fmt & 1) != (format & 1))
|
||||
pvr_txr_load_ex((GLvoid *)pixels, txr, width, height, PVR_TXRLOAD_16BPP);
|
||||
else
|
||||
pvr_txr_load((GLvoid *)pixels, txr, width * height * 2);
|
||||
|
||||
/* Store texture state in context */
|
||||
gl_cur_texture->txr.width = width;
|
||||
gl_cur_texture->txr.height = height;
|
||||
gl_cur_texture->txr.format = internal_fmt;
|
||||
gl_cur_texture->txr.base = txr;
|
||||
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
}
|
||||
|
||||
/* KOS shortcut function (if you loaded your own texture) */
|
||||
void glKosTex2D(GLint internal_fmt, GLsizei width, GLsizei height,
|
||||
pvr_ptr_t txr_address) {
|
||||
|
||||
/* Store texture state in context */
|
||||
gl_cur_texture->txr.width = width;
|
||||
gl_cur_texture->txr.height = height;
|
||||
gl_cur_texture->txr.format = internal_fmt;
|
||||
gl_cur_texture->txr.base = txr_address;
|
||||
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
}
|
||||
|
||||
/* Texture environment */
|
||||
void glTexEnvi(GLenum target, GLenum pname, GLint param) {
|
||||
assert(target == GL_TEXTURE_2D);
|
||||
assert(pname == GL_TEXTURE_ENV_MODE);
|
||||
|
||||
switch(param) {
|
||||
case GL_REPLACE:
|
||||
gl_cur_texture->txr.env = PVR_TXRENV_REPLACE;
|
||||
break;
|
||||
case GL_MODULATE:
|
||||
gl_cur_texture->txr.env = PVR_TXRENV_MODULATE;
|
||||
break;
|
||||
case GL_DECAL:
|
||||
gl_cur_texture->txr.env = PVR_TXRENV_DECAL;
|
||||
break;
|
||||
case GL_MODULATEALPHA:
|
||||
gl_cur_texture->txr.env = PVR_TXRENV_MODULATEALPHA;
|
||||
break;
|
||||
}
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
}
|
||||
|
||||
/* Texture parameter */
|
||||
void glTexParameteri(GLenum target, GLenum pname, GLint param) {
|
||||
assert(target == GL_TEXTURE_2D);
|
||||
|
||||
switch(pname) {
|
||||
case GL_TEXTURE_FILTER:
|
||||
switch(param) {
|
||||
case GL_FILTER_NONE:
|
||||
gl_cur_texture->txr.filter = PVR_FILTER_NONE;
|
||||
break;
|
||||
case GL_FILTER_BILINEAR:
|
||||
gl_cur_texture->txr.filter = PVR_FILTER_BILINEAR;
|
||||
break;
|
||||
default:
|
||||
assert_msg(0, "Unknown texture filter.");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GL_TEXTURE_WRAP_S: /* adjust state of UVCLAMP_U */
|
||||
switch(param) {
|
||||
case GL_REPEAT:
|
||||
if (gl_cur_texture->txr.uv_clamp == PVR_UVCLAMP_UV)
|
||||
gl_cur_texture->txr.uv_clamp = PVR_UVCLAMP_V;
|
||||
else if (gl_cur_texture->txr.uv_clamp == PVR_UVCLAMP_U)
|
||||
gl_cur_texture->txr.uv_clamp = PVR_UVCLAMP_NONE;
|
||||
break;
|
||||
case GL_CLAMP:
|
||||
if (gl_cur_texture->txr.uv_clamp == PVR_UVCLAMP_NONE)
|
||||
gl_cur_texture->txr.uv_clamp = PVR_UVCLAMP_U;
|
||||
else if (gl_cur_texture->txr.uv_clamp == PVR_UVCLAMP_V)
|
||||
gl_cur_texture->txr.uv_clamp = PVR_UVCLAMP_UV;
|
||||
break;
|
||||
default:
|
||||
assert_msg(0, "Unknown texture wrap mode.");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case GL_TEXTURE_WRAP_T: /* adjust state of UVCLAMP_V */
|
||||
switch(param) {
|
||||
case GL_REPEAT:
|
||||
if (gl_cur_texture->txr.uv_clamp == PVR_UVCLAMP_UV)
|
||||
gl_cur_texture->txr.uv_clamp = PVR_UVCLAMP_U;
|
||||
else if (gl_cur_texture->txr.uv_clamp == PVR_UVCLAMP_V)
|
||||
gl_cur_texture->txr.uv_clamp = PVR_UVCLAMP_NONE;
|
||||
break;
|
||||
case GL_CLAMP:
|
||||
if (gl_cur_texture->txr.uv_clamp == PVR_UVCLAMP_NONE)
|
||||
gl_cur_texture->txr.uv_clamp = PVR_UVCLAMP_V;
|
||||
else if (gl_cur_texture->txr.uv_clamp == PVR_UVCLAMP_U)
|
||||
gl_cur_texture->txr.uv_clamp = PVR_UVCLAMP_UV;
|
||||
break;
|
||||
default:
|
||||
assert_msg(0, "Unknown texture wrap mode.");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert_msg(0, "Unknown parameter name (pname).");
|
||||
break;
|
||||
|
||||
}
|
||||
gl_pbuf_submitted = GL_FALSE;
|
||||
}
|
||||
|
520
gltrans.c
Normal file
520
gltrans.c
Normal file
|
@ -0,0 +1,520 @@
|
|||
/* KallistiGL for KOS ##version##
|
||||
|
||||
gltrans.c
|
||||
(c)2001 Dan Potter
|
||||
*/
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include "glinternal.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <dc/fmath.h>
|
||||
#include <dc/matrix.h>
|
||||
|
||||
CVSID("$Id: gltrans.c,v 1.13 2002/09/05 07:36:23 bardtx Exp $");
|
||||
|
||||
/* Transformation APIs */
|
||||
|
||||
/* Modus operandi, as it were
|
||||
|
||||
The transformation API will store N matrices, representing the various
|
||||
GL matrix modes (projection, modelview, texture) and gl_matrix_mode will
|
||||
point to the currently selected on. All matrix operations will load the matrix
|
||||
from its array position, perform the math on that matrix, and store it back
|
||||
into the array.
|
||||
|
||||
When gldraw() uses the matrices, it will pull the matrices it needs and
|
||||
multiply them out in registers before applying them to vectors.
|
||||
|
||||
*/
|
||||
|
||||
#define DEG2RAD (F_PI / 180.0f)
|
||||
#define RAD2DEG (180.0f / F_PI)
|
||||
|
||||
/* Matrix stacks (move to global?) */
|
||||
#define MAT_MV_STACK_CNT 32
|
||||
#define MAT_P_STACK_CNT 2
|
||||
#define MAT_T_STACK_CNT 2
|
||||
static matrix_t gl_mat_mv_stack[MAT_MV_STACK_CNT] __attribute__((aligned(32)));
|
||||
static int gl_mat_mv_stack_top = 0;
|
||||
static matrix_t gl_mat_p_stack[MAT_P_STACK_CNT] __attribute__((aligned(32)));
|
||||
static int gl_mat_p_stack_top = 0;
|
||||
static matrix_t gl_mat_t_stack[MAT_T_STACK_CNT] __attribute__((aligned(32)));
|
||||
static int gl_mat_t_stack_top = 0;
|
||||
|
||||
/* Frustum stack */
|
||||
static gl_frustum_t gl_frustum_stack[MAT_P_STACK_CNT];
|
||||
static int gl_frustum_stack_top = 0;
|
||||
|
||||
/* Set which matrix we are working on */
|
||||
void glMatrixMode(GLenum mode) {
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
gl_matrix_mode = mode;
|
||||
gl_matrix_dirty = GL_TRUE;
|
||||
}
|
||||
|
||||
/* Load the identitiy matrix */
|
||||
void glLoadIdentity(void) {
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
mat_identity();
|
||||
mat_store(gl_trans_mats + gl_matrix_mode);
|
||||
gl_matrix_dirty = GL_TRUE;
|
||||
}
|
||||
|
||||
static matrix_t ml __attribute__((aligned(32)));
|
||||
|
||||
/* Load an arbitrary matrix */
|
||||
void glLoadMatrixf(const GLfloat *m) {
|
||||
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
memcpy(ml, m, sizeof(matrix_t));
|
||||
|
||||
mat_load(&ml);
|
||||
mat_store(gl_trans_mats + gl_matrix_mode);
|
||||
|
||||
gl_matrix_dirty = GL_TRUE;
|
||||
}
|
||||
|
||||
/* Load an arbitrary transposed matrix */
|
||||
void glLoadTransposeMatrixf(const GLfloat *m) {
|
||||
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
ml[0][0] = m[0];
|
||||
ml[0][1] = m[4];
|
||||
ml[0][2] = m[8];
|
||||
ml[0][3] = m[12];
|
||||
ml[1][0] = m[1];
|
||||
ml[1][1] = m[5];
|
||||
ml[1][2] = m[9];
|
||||
ml[1][3] = m[13];
|
||||
ml[2][0] = m[2];
|
||||
ml[2][1] = m[6];
|
||||
ml[2][2] = m[10];
|
||||
ml[2][3] = m[14];
|
||||
ml[3][0] = m[3];
|
||||
ml[3][1] = m[7];
|
||||
ml[3][2] = m[11];
|
||||
ml[3][3] = m[15];
|
||||
|
||||
mat_load(&ml);
|
||||
mat_store(gl_trans_mats + gl_matrix_mode);
|
||||
|
||||
gl_matrix_dirty = GL_TRUE;
|
||||
}
|
||||
|
||||
/* Multiply the current matrix by an arbitrary matrix */
|
||||
void glMultMatrixf(const GLfloat *m) {
|
||||
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
memcpy(ml, m, sizeof(matrix_t));
|
||||
|
||||
mat_load(gl_trans_mats + gl_matrix_mode);
|
||||
mat_apply(&ml);
|
||||
mat_store(gl_trans_mats + gl_matrix_mode);
|
||||
|
||||
gl_matrix_dirty = GL_TRUE;
|
||||
}
|
||||
|
||||
/* Multiply the current matrix by an arbitrary transposed matrix */
|
||||
void glMultTransposeMatrixf(const GLfloat *m) {
|
||||
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
ml[0][0] = m[0];
|
||||
ml[0][1] = m[4];
|
||||
ml[0][2] = m[8];
|
||||
ml[0][3] = m[12];
|
||||
ml[1][0] = m[1];
|
||||
ml[1][1] = m[5];
|
||||
ml[1][2] = m[9];
|
||||
ml[1][3] = m[13];
|
||||
ml[2][0] = m[2];
|
||||
ml[2][1] = m[6];
|
||||
ml[2][2] = m[10];
|
||||
ml[2][3] = m[14];
|
||||
ml[3][0] = m[3];
|
||||
ml[3][1] = m[7];
|
||||
ml[3][2] = m[11];
|
||||
ml[3][3] = m[15];
|
||||
|
||||
mat_load(gl_trans_mats + gl_matrix_mode);
|
||||
mat_apply(&ml);
|
||||
mat_store(gl_trans_mats + gl_matrix_mode);
|
||||
|
||||
gl_matrix_dirty = GL_TRUE;
|
||||
}
|
||||
|
||||
/* Set the depth range */
|
||||
void glDepthRange(GLclampf n, GLclampf f) {
|
||||
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
/* clamp the values... */
|
||||
if (n < 0.0f) n = 0.0f;
|
||||
if (n > 1.0f) n = 1.0f;
|
||||
if (f < 0.0f) f = 0.0f;
|
||||
if (f > 1.0f) f = 1.0f;
|
||||
|
||||
gl_depthrange_near = n;
|
||||
gl_depthrange_far = f;
|
||||
|
||||
/* Adjust the viewport scale and offset for Z */
|
||||
gl_viewport_scale[2] = ((f - n) / 2.0f);
|
||||
gl_viewport_offset[2] = (n + f) / 2.0f;
|
||||
}
|
||||
|
||||
/* Set the GL viewport */
|
||||
void glViewport(GLint x, GLint y,
|
||||
GLsizei width, GLsizei height) {
|
||||
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
gl_viewport_x1 = x;
|
||||
gl_viewport_y1 = y;
|
||||
gl_viewport_width = width;
|
||||
gl_viewport_height = height;
|
||||
|
||||
/* Calculate the viewport scale and offset */
|
||||
gl_viewport_scale[0] = (GLfloat)width / 2.0f;
|
||||
gl_viewport_offset[0] = gl_viewport_scale[0] + (GLfloat)x;
|
||||
gl_viewport_scale[1] = (GLfloat)height / 2.0f;
|
||||
gl_viewport_offset[1] = gl_viewport_scale[1] + (GLfloat)y;
|
||||
gl_viewport_scale[2] = (gl_depthrange_far - gl_depthrange_near) / 2.0f;
|
||||
gl_viewport_offset[2] = (gl_depthrange_near + gl_depthrange_far) / 2.0f;
|
||||
|
||||
/* Flip the Y-axis */
|
||||
//gl_viewport_scale[1] *= -1.0f;
|
||||
|
||||
/* FIXME: Why does the depth value need some nudging?
|
||||
* This makes polys with Z=0 work.
|
||||
*/
|
||||
gl_viewport_offset[2] += 0.0001f;
|
||||
}
|
||||
|
||||
/* Located here for now */
|
||||
void gluPerspective(GLfloat angle, GLfloat aspect,
|
||||
GLfloat znear, GLfloat zfar) {
|
||||
|
||||
GLfloat xmin, xmax, ymin, ymax;
|
||||
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
ymax = znear * ftan(angle * F_PI / 360.0f);
|
||||
ymin = -ymax;
|
||||
xmin = ymin * aspect;
|
||||
xmax = ymax * aspect;
|
||||
|
||||
glFrustum(xmin, xmax, ymin, ymax, znear, zfar);
|
||||
}
|
||||
|
||||
static matrix_t mf __attribute__((aligned(32))) = {
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, -1.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f }
|
||||
};
|
||||
|
||||
void glFrustum(GLfloat left, GLfloat right,
|
||||
GLfloat bottom, GLfloat top,
|
||||
GLfloat znear, GLfloat zfar) {
|
||||
|
||||
GLfloat x, y, a, b, c, d;
|
||||
|
||||
gl_frustum.left = left;
|
||||
gl_frustum.right = right;
|
||||
gl_frustum.bottom = bottom;
|
||||
gl_frustum.top = top;
|
||||
gl_frustum.znear = znear;
|
||||
gl_frustum.zfar = zfar;
|
||||
|
||||
assert(znear > 0.0f);
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
x = (2.0f * znear) / (right - left);
|
||||
y = (2.0f * znear) / (top - bottom);
|
||||
a = (right + left) / (right - left);
|
||||
b = (top + bottom) / (top - bottom);
|
||||
c = -(zfar + znear) / (zfar - znear);
|
||||
d = -(2.0f * zfar * znear) / (zfar - znear);
|
||||
|
||||
mf[0][0] = x;
|
||||
mf[2][0] = a;
|
||||
mf[1][1] = y;
|
||||
mf[2][1] = b;
|
||||
mf[2][2] = c;
|
||||
mf[3][2] = d;
|
||||
|
||||
mat_load(gl_trans_mats + gl_matrix_mode);
|
||||
mat_apply(&mf);
|
||||
mat_store(gl_trans_mats + gl_matrix_mode);
|
||||
|
||||
gl_matrix_dirty = GL_TRUE;
|
||||
}
|
||||
|
||||
static matrix_t mo __attribute__((aligned(32))) = {
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 1.0f }
|
||||
};
|
||||
|
||||
void glOrtho(GLfloat left, GLfloat right,
|
||||
GLfloat bottom, GLfloat top,
|
||||
GLfloat znear, GLfloat zfar) {
|
||||
|
||||
GLfloat x, y, z;
|
||||
GLfloat tx, ty, tz;
|
||||
|
||||
gl_frustum.znear = 0.001;
|
||||
gl_frustum.zfar = 100;
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
x = 2.0f / (right - left);
|
||||
y = 2.0f / (top - bottom);
|
||||
z = -2.0f / (zfar - znear);
|
||||
tx = -(right + left) / (right - left);
|
||||
ty = -(top + bottom) / (top - bottom);
|
||||
tz = -(zfar + znear) / (zfar - znear);
|
||||
|
||||
mo[0][0] = x;
|
||||
mo[1][1] = y;
|
||||
mo[2][2] = z;
|
||||
mo[3][0] = tx;
|
||||
mo[3][1] = ty;
|
||||
mo[3][2] = tz;
|
||||
|
||||
mat_load(gl_trans_mats + gl_matrix_mode);
|
||||
mat_apply(&mo);
|
||||
mat_store(gl_trans_mats + gl_matrix_mode);
|
||||
|
||||
gl_matrix_dirty = GL_TRUE;
|
||||
}
|
||||
|
||||
void glPushMatrix(void) {
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
switch (gl_matrix_mode)
|
||||
{
|
||||
case GL_MODELVIEW:
|
||||
assert_msg(gl_mat_mv_stack_top < MAT_MV_STACK_CNT, "Modelview stack overflow.");
|
||||
memcpy(gl_mat_mv_stack + gl_mat_mv_stack_top,
|
||||
gl_trans_mats + gl_matrix_mode,
|
||||
sizeof(matrix_t));
|
||||
gl_mat_mv_stack_top++;
|
||||
break;
|
||||
case GL_PROJECTION:
|
||||
assert_msg(gl_mat_p_stack_top < MAT_P_STACK_CNT, "Projection stack overflow.");
|
||||
memcpy(gl_mat_p_stack + gl_mat_p_stack_top,
|
||||
gl_trans_mats + gl_matrix_mode,
|
||||
sizeof(matrix_t));
|
||||
gl_mat_p_stack_top++;
|
||||
memcpy(gl_frustum_stack + gl_frustum_stack_top,
|
||||
&gl_frustum,
|
||||
sizeof(gl_frustum_t));
|
||||
gl_frustum_stack_top++;
|
||||
break;
|
||||
case GL_TEXTURE:
|
||||
assert_msg(gl_mat_t_stack_top < MAT_T_STACK_CNT, "Texture stack overflow.");
|
||||
memcpy(gl_mat_t_stack + gl_mat_t_stack_top,
|
||||
gl_trans_mats + gl_matrix_mode,
|
||||
sizeof(matrix_t));
|
||||
gl_mat_t_stack_top++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void glPopMatrix(void) {
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
switch(gl_matrix_mode)
|
||||
{
|
||||
case GL_MODELVIEW:
|
||||
assert_msg(gl_mat_mv_stack_top > 0, "Modelview stack underflow.");
|
||||
gl_mat_mv_stack_top--;
|
||||
memcpy(gl_trans_mats + gl_matrix_mode,
|
||||
gl_mat_mv_stack + gl_mat_mv_stack_top,
|
||||
sizeof(matrix_t));
|
||||
break;
|
||||
case GL_PROJECTION:
|
||||
assert_msg(gl_mat_p_stack_top > 0, "Projection stack underflow.");
|
||||
gl_mat_p_stack_top--;
|
||||
memcpy(gl_trans_mats + gl_matrix_mode,
|
||||
gl_mat_p_stack + gl_mat_p_stack_top,
|
||||
sizeof(matrix_t));
|
||||
gl_frustum_stack_top--;
|
||||
memcpy(&gl_frustum,
|
||||
gl_frustum_stack + gl_frustum_stack_top,
|
||||
sizeof(gl_frustum_t));
|
||||
break;
|
||||
case GL_TEXTURE:
|
||||
assert_msg(gl_mat_t_stack_top > 0, "Texture stack underflow.");
|
||||
gl_mat_t_stack_top--;
|
||||
memcpy(gl_trans_mats + gl_matrix_mode,
|
||||
gl_mat_t_stack + gl_mat_t_stack_top,
|
||||
sizeof(matrix_t));
|
||||
break;
|
||||
}
|
||||
|
||||
gl_matrix_dirty = GL_TRUE;
|
||||
}
|
||||
|
||||
static matrix_t mr __attribute__((aligned(32))) = {
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 1.0f }
|
||||
};
|
||||
|
||||
void glRotatef(GLfloat angle,
|
||||
GLfloat x, GLfloat y, GLfloat z) {
|
||||
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
GLfloat rcos = fcos(angle * DEG2RAD);
|
||||
GLfloat rsin = fsin(angle * DEG2RAD);
|
||||
GLfloat invrcos = (1.0f - rcos);
|
||||
GLfloat mag = fsqrt(x*x + y*y + z*z);
|
||||
GLfloat xx, yy, zz, xy, yz, zx;
|
||||
|
||||
if (mag < 1.0e-6) {
|
||||
/* Rotation vector is too small to be significant */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Normalize the rotation vector */
|
||||
x /= mag;
|
||||
y /= mag;
|
||||
z /= mag;
|
||||
|
||||
xx = x * x;
|
||||
yy = y * y;
|
||||
zz = z * z;
|
||||
xy = (x * y * invrcos);
|
||||
yz = (y * z * invrcos);
|
||||
zx = (z * x * invrcos);
|
||||
|
||||
/* Generate the rotation matrix */
|
||||
mr[0][0] = xx + rcos * (1.0f - xx);
|
||||
mr[2][1] = yz - x * rsin;
|
||||
mr[1][2] = yz + x * rsin;
|
||||
|
||||
mr[1][1] = yy + rcos * (1.0f - yy);
|
||||
mr[2][0] = zx + y * rsin;
|
||||
mr[0][2] = zx - y * rsin;
|
||||
|
||||
mr[2][2] = zz + rcos * (1.0f - zz);
|
||||
mr[1][0] = xy - z * rsin;
|
||||
mr[0][1] = xy + z * rsin;
|
||||
|
||||
mat_load(gl_trans_mats + gl_matrix_mode);
|
||||
mat_apply(&mr);
|
||||
mat_store(gl_trans_mats + gl_matrix_mode);
|
||||
|
||||
gl_matrix_dirty = GL_TRUE;
|
||||
}
|
||||
|
||||
static matrix_t ms __attribute__((aligned(32))) = {
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 0.0f },
|
||||
{ 0.0f, 0.0f, 0.0f, 1.0f }
|
||||
};
|
||||
|
||||
void glScalef(GLfloat x, GLfloat y, GLfloat z) {
|
||||
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
ms[0][0] = x;
|
||||
ms[1][1] = y;
|
||||
ms[2][2] = z;
|
||||
|
||||
mat_load(gl_trans_mats + gl_matrix_mode);
|
||||
mat_apply(&ms);
|
||||
mat_store(gl_trans_mats + gl_matrix_mode);
|
||||
|
||||
gl_matrix_dirty = GL_TRUE;
|
||||
}
|
||||
|
||||
static matrix_t mt __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 }
|
||||
};
|
||||
|
||||
void glTranslatef(GLfloat x, GLfloat y, GLfloat z) {
|
||||
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
mt[3][0] = x;
|
||||
mt[3][1] = y;
|
||||
mt[3][2] = z;
|
||||
|
||||
mat_load(gl_trans_mats + gl_matrix_mode);
|
||||
mat_apply(&mt);
|
||||
mat_store(gl_trans_mats + gl_matrix_mode);
|
||||
|
||||
gl_matrix_dirty = GL_TRUE;
|
||||
}
|
||||
|
||||
/* XXX - these should be in glu */
|
||||
void normalize(float v[3])
|
||||
{
|
||||
float r;
|
||||
|
||||
r = fsqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] );
|
||||
if (r == 0.0) return;
|
||||
|
||||
v[0] /= r;
|
||||
v[1] /= r;
|
||||
v[2] /= r;
|
||||
}
|
||||
|
||||
void cross(float v1[3], float v2[3], float result[3])
|
||||
{
|
||||
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];
|
||||
}
|
||||
|
||||
static matrix_t ml __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 }
|
||||
};
|
||||
|
||||
/* XXX - should move to glu */
|
||||
void gluLookAt(GLfloat eyex, GLfloat eyey, GLfloat eyez, GLfloat centerx,
|
||||
GLfloat centery, GLfloat centerz, GLfloat upx, GLfloat upy,
|
||||
GLfloat upz)
|
||||
{
|
||||
float forward[3], side[3], up[3];
|
||||
|
||||
assert_msg(!gl_prim_type, "Not allowed within glBegin/glEnd pair.");
|
||||
forward[0] = centerx - eyex;
|
||||
forward[1] = centery - eyey;
|
||||
forward[2] = centerz - eyez;
|
||||
|
||||
up[0] = upx;
|
||||
up[1] = upy;
|
||||
up[2] = upz;
|
||||
|
||||
normalize(forward);
|
||||
|
||||
/* Side = forward x up */
|
||||
cross(forward, up, side);
|
||||
normalize(side);
|
||||
|
||||
/* Recompute up as: up = side x forward */
|
||||
cross(side, forward, up);
|
||||
|
||||
ml[0][0] = side[0];
|
||||
ml[1][0] = side[1];
|
||||
ml[2][0] = side[2];
|
||||
|
||||
ml[0][1] = up[0];
|
||||
ml[1][1] = up[1];
|
||||
ml[2][1] = up[2];
|
||||
|
||||
ml[0][2] = -forward[0];
|
||||
ml[1][2] = -forward[1];
|
||||
ml[2][2] = -forward[2];
|
||||
|
||||
mat_load(gl_trans_mats + gl_matrix_mode);
|
||||
mat_apply(&ml);
|
||||
mat_store(gl_trans_mats + gl_matrix_mode);
|
||||
|
||||
glTranslatef(-eyex, -eyey, -eyez);
|
||||
}
|
103
glvars.c
Normal file
103
glvars.c
Normal file
|
@ -0,0 +1,103 @@
|
|||
/* KallistiGL for KOS ##version##
|
||||
|
||||
glvars.c
|
||||
(c)2001 Dan Potter
|
||||
*/
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#include "glinternal.h"
|
||||
|
||||
CVSID("$Id: glvars.c,v 1.11 2002/06/28 04:52:42 axlen Exp $");
|
||||
|
||||
/* Variable definitions */
|
||||
|
||||
/* Background clear color (not currently used) */
|
||||
GLfloat gl_clear_color[4];
|
||||
|
||||
/* Capabilities bitfield: toggles for glEnable() / glDisable() */
|
||||
GLbitfield gl_capabilities;
|
||||
|
||||
/* Current primitive type (or -1) */
|
||||
GLenum gl_prim_type;
|
||||
|
||||
/* Current polygon context */
|
||||
pvr_poly_cxt_t gl_poly_cxt;
|
||||
|
||||
/* Poly header buffer submitted? */
|
||||
GLboolean gl_pbuf_submitted;
|
||||
|
||||
/* Current Blend functions */
|
||||
GLint gl_blend_src = PVR_BLEND_SRCALPHA;
|
||||
GLint gl_blend_dst = PVR_BLEND_INVSRCALPHA;
|
||||
|
||||
/* Currently selected texture */
|
||||
pvr_poly_cxt_t *gl_cur_texture;
|
||||
|
||||
/* Null texture for colored polys */
|
||||
pvr_poly_cxt_t gl_null_texture;
|
||||
|
||||
/* Screen size */
|
||||
GLsizei gl_screen_width;
|
||||
GLsizei gl_screen_height;
|
||||
|
||||
/* Viewport size */
|
||||
GLint gl_viewport_x1, gl_viewport_y1,
|
||||
gl_viewport_width, gl_viewport_height;
|
||||
|
||||
/* Viewport mapping */
|
||||
GLfloat gl_viewport_scale[3];
|
||||
GLfloat gl_viewport_offset[3];
|
||||
|
||||
/* Scissor clipping */
|
||||
GLint gl_scissor_x;
|
||||
GLint gl_scissor_y;
|
||||
GLsizei gl_scissor_width;
|
||||
GLsizei gl_scissor_height;
|
||||
GLboolean gl_scissor_dirty = GL_FALSE;
|
||||
|
||||
/* Depth range */
|
||||
GLclampf gl_depthrange_near;
|
||||
GLclampf gl_depthrange_far;
|
||||
|
||||
/* Transformation matrices */
|
||||
matrix_t gl_trans_mats[GL_MATRIX_COUNT] __attribute__((aligned(32)));
|
||||
int gl_matrix_mode;
|
||||
GLboolean gl_matrix_dirty;
|
||||
|
||||
/* Frustum attributes */
|
||||
gl_frustum_t gl_frustum;
|
||||
|
||||
/* Enabled lists */
|
||||
GLbitfield gl_enabled_lists;
|
||||
|
||||
/* Currently active list */
|
||||
GLbitfield gl_active_list;
|
||||
|
||||
/* Face culling enabled/disabled */
|
||||
GLboolean gl_cull_face = GL_FALSE;
|
||||
|
||||
/* Front face */
|
||||
GLenum gl_front_face = GL_CCW;
|
||||
|
||||
/* Culling mode */
|
||||
GLenum gl_cull_mode = GL_BACK;
|
||||
|
||||
/* Fog Attributes */
|
||||
GLfloat gl_fog_color[4] = {0.5f, 0.5f, 0.5f, 1.0f}; /* r, g, b, a */
|
||||
GLfloat gl_fog_density = 1.0f; /* Density >= 0.0 - exp exp2 fog */
|
||||
GLfloat gl_fog_start = 0.0f; /* linear fog */
|
||||
GLfloat gl_fog_end = 1.0f; /* linear fog */
|
||||
GLfloat gl_fog_index = 0.0f; /* unused */
|
||||
GLenum gl_fog_mode = GL_EXP;
|
||||
|
||||
/* Point size */
|
||||
GLfloat gl_point_size = 1.0f;
|
||||
|
||||
/* Vertex buffers */
|
||||
/* Pre-xformed vertex buffer */
|
||||
gl_vertex_t gl_vbuf[VBUF_SIZE] __attribute__((aligned(8192)));
|
||||
/* Post-xformed vertex buffer */
|
||||
gl_vertex_t gl_xbuf[VBUF_SIZE] __attribute__((aligned(8192)));
|
||||
int gl_vbuf_top;
|
||||
|
0
kos/dreamcast.cnf
Normal file
0
kos/dreamcast.cnf
Normal file
Loading…
Reference in New Issue
Block a user