Handle implicit end of a primitive. Avoid doing things that cannot be done inside a glBegin glEnd pair. Pop and push seperate Model and Direction matrix but using same stack pointers.

This commit is contained in:
masscat 2007-05-07 21:25:32 +00:00
parent 7dca1abe7a
commit 47f77a3467
1 changed files with 228 additions and 60 deletions

View File

@ -1,4 +1,4 @@
/* $Id: opengl_collector_3Demu.c,v 1.12 2007-05-06 18:18:26 masscat Exp $
/* $Id: opengl_collector_3Demu.c,v 1.13 2007-05-07 21:25:32 masscat Exp $
*/
/*
Copyright (C) 2006-2007 Ben Jaques, shash
@ -192,6 +192,17 @@ static float cur_vertex[3] = {0.0f, 0.0f, 0.0f};
static u32 alpha_function = 0;
static float lightDirection[4][4];
static int light_direction_valid = 0;
static GLint lightColor[4][4];
static int light_colour_valid = 0;
static u32 current_depth24b = 0;
static int depth24b_valid = 0;
static u32 current_clear_colour = 0;
static int clear_colour_valid = 0;
/** the current polygon attribute */
static u32 current_polygon_attr = 0;
@ -918,6 +929,8 @@ setup_vertex( float *vertex) {
#else
glVertex3fv( vertex);
#endif
numVertex += 1;
}
@ -1050,6 +1063,48 @@ process_begin_vtxs( struct render_state *state,
LOG("Begin: %s\n", primitive_type_names[prim_type]);
if ( inside_primitive) {
LOG( "implicit primitive end\n");
glEnd();
}
if ( depth24b_valid) {
glClearDepth( current_depth24b / ((float)(1<<24)));
depth24b_valid = 0;
}
if ( clear_colour_valid) {
glClearColor( ((float)( current_clear_colour & 0x1F))/31.0f,
((float)(( current_clear_colour >> 5)&0x1F))/31.0f,
((float)(( current_clear_colour >> 10)&0x1F))/31.0f,
((float)(( current_clear_colour >> 16)&0x1F))/31.0f);
clear_colour_valid = 0;
}
if ( light_colour_valid) {
int light;
for ( light = 0; light < 4; light++) {
if ( light_colour_valid & (1 << light)) {
glLightiv (GL_LIGHT0 + light, GL_AMBIENT, lightColor[light]);
glLightiv (GL_LIGHT0 + light, GL_DIFFUSE, lightColor[light]);
glLightiv (GL_LIGHT0 + light, GL_SPECULAR, lightColor[light]);
}
}
light_colour_valid = 0;
}
if ( light_direction_valid) {
int light;
for ( light = 0; light < 4; light++) {
if ( light_direction_valid & (1 << light)) {
glLightfv(GL_LIGHT0 + light, GL_POSITION, lightDirection[light]);
}
}
light_direction_valid = 0;
}
#if 1
/* FIXME: ignoring shadow polygons for now */
if ( ((current_polygon_attr >> 4) & 0x3) == 3) {
@ -1278,37 +1333,66 @@ process_spe_emi( struct render_state *state,
static void
process_light_vector( struct render_state *state,
const u32 *parms) {
float lightDirection[4];
lightDirection[0] = -normalTable[parms[0]&1023];
lightDirection[1] = -normalTable[(parms[0]>>10)&1023];
lightDirection[2] = -normalTable[(parms[0]>>20)&1023];
lightDirection[3] = 0.0f;
int light = parms[0] >> 30;
lightDirection[light][0] = -normalTable[parms[0]&1023];
lightDirection[light][1] = -normalTable[(parms[0]>>10)&1023];
lightDirection[light][2] = -normalTable[(parms[0]>>20)&1023];
lightDirection[light][3] = 0.0f;
LOG("Light vector %f,%f,%f,%f (%08x)\n",
lightDirection[0], lightDirection[1],
lightDirection[2], lightDirection[3],
lightDirection[light][0], lightDirection[light][1],
lightDirection[light][2], lightDirection[light][3],
parms[0]);
MatrixMultVec3x3( mtxCurrent[2], lightDirection);
MatrixMultVec3x3( mtxCurrent[2], lightDirection[light]);
glLightfv(GL_LIGHT0 + (parms[0]>>30), GL_POSITION, lightDirection);
/*
* FIXME:
* Delay until the next normal command.
* Can this change inside a primative?
*/
if ( inside_primitive) {
//LOG_ALWAYS( "Light vector change whilst inside primative\n");
/*
* Save until the 'begin' command
*/
light_direction_valid |= 1 << light;
}
else {
glLightfv(GL_LIGHT0 + light, GL_POSITION, lightDirection[light]);
light_direction_valid &= ~(1 << light);
}
}
static void
process_light_color( struct render_state *state,
const u32 *parms) {
GLint lightColor[4] = {
((parms[0]) & 0x1F)<<26,
((parms[0]>> 5)&0x1F)<<26,
((parms[0]>>10)&0x1F)<<26,
0x7fffffff};
int light = parms[0] >> 30;
lightColor[light][0] = ((parms[0]) & 0x1F)<<26;
lightColor[light][1] = ((parms[0]>> 5)&0x1F)<<26;
lightColor[light][2] = ((parms[0]>> 10)&0x1F)<<26;
lightColor[light][3] = 0x7fffffff;
LOG("Light color %08x\n", parms[0]);
glLightiv (GL_LIGHT0 + (parms[0]>>30), GL_AMBIENT, lightColor);
glLightiv (GL_LIGHT0 + (parms[0]>>30), GL_DIFFUSE, lightColor);
glLightiv (GL_LIGHT0 + (parms[0]>>30), GL_SPECULAR, lightColor);
/*
* FIXME:
* Delay until the next normal command.
* Can this change inside a primative?
*/
if ( inside_primitive) {
//LOG_ALWAYS( "Light colour change whilst inside primative\n");
/*
* Save until the 'begin' command
*/
light_colour_valid |= 1 << light;
}
else {
glLightiv (GL_LIGHT0 + light, GL_AMBIENT, lightColor[light]);
glLightiv (GL_LIGHT0 + light, GL_DIFFUSE, lightColor[light]);
glLightiv (GL_LIGHT0 + light, GL_SPECULAR, lightColor[light]);
light_colour_valid &= ~(1 << light);
}
}
@ -1375,8 +1459,22 @@ process_mtx_push( struct render_state *state,
const u32 *parms) {
LOG("Matrix push\n");
if ( current_matrix_mode == 2) {
/* copy the stack position and size from the Model matrix stack
* as they are shared and may have been updated whilst Model
* Matrix mode was selected. */
mtxStack[2].position = mtxStack[1].position;
mtxStack[2].size = mtxStack[1].size;
}
MatrixStackPushMatrix (&mtxStack[current_matrix_mode],
mtxCurrent[current_matrix_mode]);
if ( current_matrix_mode == 2) {
/* push the model matrix as well */
MatrixStackPushMatrix ( &mtxStack[1],
mtxCurrent[1]);
}
}
static void
@ -1385,25 +1483,53 @@ process_mtx_pop( struct render_state *state,
s32 index = parms[0];
LOG("Matrix pop\n");
if ( current_matrix_mode == 2) {
/* copy the stack position and size from the Model matrix stack
* as they are shared and may have been updated whilst Model
* Matrix mode was selected. */
mtxStack[2].position = mtxStack[1].position;
mtxStack[2].size = mtxStack[1].size;
}
MatrixCopy ( mtxCurrent[current_matrix_mode],
MatrixStackPopMatrix (&mtxStack[current_matrix_mode], index));
if (current_matrix_mode == 2) {
MatrixCopy (mtxCurrent[1], mtxCurrent[2]);
MatrixCopy ( mtxCurrent[1],
MatrixStackPopMatrix( &mtxStack[1], index));
}
if ( current_matrix_mode < 3)
if ( current_matrix_mode < 3) {
if ( current_matrix_mode == 2)
loadMatrix( mtxCurrent[1]);
else
loadMatrix( mtxCurrent[current_matrix_mode]);
}
}
static void
process_mtx_store( struct render_state *state,
const u32 *parms) {
LOG("Matrix store (%d)\n", parms[0]);
if ( current_matrix_mode == 2) {
/* copy the stack position and size from the Model matrix stack
* as they are shared and may have been updated whilst Model
* Matrix mode was selected. */
mtxStack[2].position = mtxStack[1].position;
mtxStack[2].size = mtxStack[1].size;
}
MatrixStackLoadMatrix (&mtxStack[current_matrix_mode],
parms[0] & 31,
mtxCurrent[current_matrix_mode]);
if ( current_matrix_mode == 2) {
/* store the model matrix as well */
MatrixStackLoadMatrix (&mtxStack[1],
parms[0] & 31,
mtxCurrent[1]);
}
}
static void
@ -1411,16 +1537,31 @@ process_mtx_restore( struct render_state *state,
const u32 *parms) {
LOG("Matrix restore\n");
if ( current_matrix_mode == 2) {
/* copy the stack position and size from the Model matrix stack
* as they are shared and may have been updated whilst Model
* Matrix mode was selected. */
mtxStack[2].position = mtxStack[1].position;
mtxStack[2].size = mtxStack[1].size;
}
MatrixCopy (mtxCurrent[current_matrix_mode],
MatrixStackGetPos(&mtxStack[current_matrix_mode], parms[0]&31));
if (current_matrix_mode == 2) {
MatrixCopy (mtxCurrent[1], mtxCurrent[2]);
MatrixCopy (mtxCurrent[1],
MatrixStackGetPos(&mtxStack[1], parms[0]&31));
}
if ( current_matrix_mode < 3)
if ( current_matrix_mode < 3) {
if ( current_matrix_mode == 2) {
loadMatrix( mtxCurrent[1]);
}
else {
loadMatrix( mtxCurrent[current_matrix_mode]);
}
}
}
static void
process_mtx_load_4x4( struct render_state *state,
@ -1521,8 +1662,6 @@ process_mtx_trans( struct render_state *state,
if (current_matrix_mode == 2)
MatrixTranslate (mtxCurrent[1], trans);
if ( current_matrix_mode == 2) {
LOG_MATRIX( mtxCurrent[1]);
loadMatrix( mtxCurrent[1]);
@ -1543,12 +1682,12 @@ process_mtx_scale( struct render_state *state,
scale[1] = fix2float(parms[1]);
scale[2] = fix2float(parms[2]);
MatrixScale (mtxCurrent[current_matrix_mode], scale);
if (current_matrix_mode == 2) {
/* scaling does not happen against the drirection matrix */
MatrixScale (mtxCurrent[1], scale);
}
else
MatrixScale (mtxCurrent[current_matrix_mode], scale);
LOG("scale %f,%f,%f\n", scale[0], scale[1], scale[2]);
@ -1741,26 +1880,12 @@ static void
process_control( struct render_state *state,
const u32 *parms) {
LOG("Control set to %08x\n", parms[0]);
/*
* Save for later.
* all control is handled at a 'begin' command
*/
disp_3D_control = parms[0];
if( disp_3D_control & 1)
{
glEnable (GL_TEXTURE_2D);
}
else
{
glDisable (GL_TEXTURE_2D);
}
if( disp_3D_control & (1<<2))
{
glEnable(GL_ALPHA_TEST);
}
else
{
glDisable(GL_ALPHA_TEST);
}
}
static void
@ -1776,13 +1901,23 @@ process_alpha_function( struct render_state *state,
static void
process_clear_depth( struct render_state *state,
const u32 *parms) {
u32 depth24b;
//u32 depth24b;
u32 v = parms[0] & 0x7FFFF;
LOG("Clear depth %08x\n", parms[0]);
depth24b = (v * 0x200)+((v+1)/0x8000);
/*
* Save for later.
* handled at a 'begin' command
*/
current_depth24b = (v * 0x200)+((v+1)/0x8000);
glClearDepth(depth24b / ((float)(1<<24)));
if ( inside_primitive) {
depth24b_valid = 1;
}
else {
depth24b_valid = 0;
glClearDepth( current_depth24b / ((float)(1<<24)));
}
}
static void
@ -1791,11 +1926,22 @@ process_clear_colour( struct render_state *state,
u32 v = parms[0];
LOG("Clear colour %08x\n", v);
glClearColor( ((float)(v&0x1F))/31.0f,
((float)((v>>5)&0x1F))/31.0f,
((float)((v>>10)&0x1F))/31.0f,
((float)((v>>16)&0x1F))/31.0f);
/*
* Save for later.
* handled at a 'begin' command
*/
current_clear_colour = v;
if ( inside_primitive) {
clear_colour_valid = 1;
}
else {
glClearColor( ((float)( current_clear_colour & 0x1F))/31.0f,
((float)(( current_clear_colour >> 5)&0x1F))/31.0f,
((float)(( current_clear_colour >> 10)&0x1F))/31.0f,
((float)(( current_clear_colour >> 16)&0x1F))/31.0f);
clear_colour_valid = 0;
}
}
@ -1815,10 +1961,32 @@ draw_3D_area( void) {
return;
}
#ifndef READ_PIXELS_IMMEDIATELY
/*
* If there is a render which has not had its pixels read yet
* then read them now.
*/
if ( new_render_available) {
new_render_available = 0;
#ifdef USE_BGR_ORDER
glReadPixels(0,0,256,192,GL_BGRA,GL_UNSIGNED_BYTE,GPU_screen3D);
#else
glReadPixels(0,0,256,192,GL_RGBA,GL_UNSIGNED_BYTE,GPU_screen3D);
#endif
}
#endif
LOG("\n------------------------------------\n");
LOG("Start of render\n");
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/*if ( state->write_index > 10000) {
LOG_ALWAYS( "3d write index %d\n", state->write_index);
}*/
for ( i = 0; i < state->write_index; i++) {
u32 cmd = state->cmds[i];
//LOG("Render cmd: %08x\n", state->cmds[i]);