185 lines
4.5 KiB
C
185 lines
4.5 KiB
C
/* 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;
|
|
}
|
|
|