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:
parent
7dca1abe7a
commit
47f77a3467
|
@ -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
|
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 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 */
|
/** the current polygon attribute */
|
||||||
static u32 current_polygon_attr = 0;
|
static u32 current_polygon_attr = 0;
|
||||||
|
|
||||||
|
@ -918,6 +929,8 @@ setup_vertex( float *vertex) {
|
||||||
#else
|
#else
|
||||||
glVertex3fv( vertex);
|
glVertex3fv( vertex);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
numVertex += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1050,6 +1063,48 @@ process_begin_vtxs( struct render_state *state,
|
||||||
|
|
||||||
LOG("Begin: %s\n", primitive_type_names[prim_type]);
|
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
|
#if 1
|
||||||
/* FIXME: ignoring shadow polygons for now */
|
/* FIXME: ignoring shadow polygons for now */
|
||||||
if ( ((current_polygon_attr >> 4) & 0x3) == 3) {
|
if ( ((current_polygon_attr >> 4) & 0x3) == 3) {
|
||||||
|
@ -1278,37 +1333,66 @@ process_spe_emi( struct render_state *state,
|
||||||
static void
|
static void
|
||||||
process_light_vector( struct render_state *state,
|
process_light_vector( struct render_state *state,
|
||||||
const u32 *parms) {
|
const u32 *parms) {
|
||||||
float lightDirection[4];
|
int light = parms[0] >> 30;
|
||||||
lightDirection[0] = -normalTable[parms[0]&1023];
|
lightDirection[light][0] = -normalTable[parms[0]&1023];
|
||||||
lightDirection[1] = -normalTable[(parms[0]>>10)&1023];
|
lightDirection[light][1] = -normalTable[(parms[0]>>10)&1023];
|
||||||
lightDirection[2] = -normalTable[(parms[0]>>20)&1023];
|
lightDirection[light][2] = -normalTable[(parms[0]>>20)&1023];
|
||||||
lightDirection[3] = 0.0f;
|
lightDirection[light][3] = 0.0f;
|
||||||
|
|
||||||
LOG("Light vector %f,%f,%f,%f (%08x)\n",
|
LOG("Light vector %f,%f,%f,%f (%08x)\n",
|
||||||
lightDirection[0], lightDirection[1],
|
lightDirection[light][0], lightDirection[light][1],
|
||||||
lightDirection[2], lightDirection[3],
|
lightDirection[light][2], lightDirection[light][3],
|
||||||
parms[0]);
|
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
|
static void
|
||||||
process_light_color( struct render_state *state,
|
process_light_color( struct render_state *state,
|
||||||
const u32 *parms) {
|
const u32 *parms) {
|
||||||
GLint lightColor[4] = {
|
int light = parms[0] >> 30;
|
||||||
((parms[0]) & 0x1F)<<26,
|
lightColor[light][0] = ((parms[0]) & 0x1F)<<26;
|
||||||
((parms[0]>> 5)&0x1F)<<26,
|
lightColor[light][1] = ((parms[0]>> 5)&0x1F)<<26;
|
||||||
((parms[0]>>10)&0x1F)<<26,
|
lightColor[light][2] = ((parms[0]>> 10)&0x1F)<<26;
|
||||||
0x7fffffff};
|
lightColor[light][3] = 0x7fffffff;
|
||||||
|
|
||||||
LOG("Light color %08x\n", parms[0]);
|
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);
|
* FIXME:
|
||||||
glLightiv (GL_LIGHT0 + (parms[0]>>30), GL_SPECULAR, lightColor);
|
* 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) {
|
const u32 *parms) {
|
||||||
LOG("Matrix push\n");
|
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],
|
MatrixStackPushMatrix (&mtxStack[current_matrix_mode],
|
||||||
mtxCurrent[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
|
static void
|
||||||
|
@ -1385,25 +1483,53 @@ process_mtx_pop( struct render_state *state,
|
||||||
s32 index = parms[0];
|
s32 index = parms[0];
|
||||||
LOG("Matrix pop\n");
|
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],
|
MatrixCopy ( mtxCurrent[current_matrix_mode],
|
||||||
MatrixStackPopMatrix (&mtxStack[current_matrix_mode], index));
|
MatrixStackPopMatrix (&mtxStack[current_matrix_mode], index));
|
||||||
|
|
||||||
if (current_matrix_mode == 2) {
|
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]);
|
loadMatrix( mtxCurrent[current_matrix_mode]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
process_mtx_store( struct render_state *state,
|
process_mtx_store( struct render_state *state,
|
||||||
const u32 *parms) {
|
const u32 *parms) {
|
||||||
LOG("Matrix store (%d)\n", parms[0]);
|
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],
|
MatrixStackLoadMatrix (&mtxStack[current_matrix_mode],
|
||||||
parms[0] & 31,
|
parms[0] & 31,
|
||||||
mtxCurrent[current_matrix_mode]);
|
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
|
static void
|
||||||
|
@ -1411,16 +1537,31 @@ process_mtx_restore( struct render_state *state,
|
||||||
const u32 *parms) {
|
const u32 *parms) {
|
||||||
LOG("Matrix restore\n");
|
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],
|
MatrixCopy (mtxCurrent[current_matrix_mode],
|
||||||
MatrixStackGetPos(&mtxStack[current_matrix_mode], parms[0]&31));
|
MatrixStackGetPos(&mtxStack[current_matrix_mode], parms[0]&31));
|
||||||
|
|
||||||
if (current_matrix_mode == 2) {
|
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]);
|
loadMatrix( mtxCurrent[current_matrix_mode]);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
process_mtx_load_4x4( struct render_state *state,
|
process_mtx_load_4x4( struct render_state *state,
|
||||||
|
@ -1521,8 +1662,6 @@ process_mtx_trans( struct render_state *state,
|
||||||
if (current_matrix_mode == 2)
|
if (current_matrix_mode == 2)
|
||||||
MatrixTranslate (mtxCurrent[1], trans);
|
MatrixTranslate (mtxCurrent[1], trans);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if ( current_matrix_mode == 2) {
|
if ( current_matrix_mode == 2) {
|
||||||
LOG_MATRIX( mtxCurrent[1]);
|
LOG_MATRIX( mtxCurrent[1]);
|
||||||
loadMatrix( mtxCurrent[1]);
|
loadMatrix( mtxCurrent[1]);
|
||||||
|
@ -1543,12 +1682,12 @@ process_mtx_scale( struct render_state *state,
|
||||||
scale[1] = fix2float(parms[1]);
|
scale[1] = fix2float(parms[1]);
|
||||||
scale[2] = fix2float(parms[2]);
|
scale[2] = fix2float(parms[2]);
|
||||||
|
|
||||||
MatrixScale (mtxCurrent[current_matrix_mode], scale);
|
|
||||||
|
|
||||||
if (current_matrix_mode == 2) {
|
if (current_matrix_mode == 2) {
|
||||||
|
/* scaling does not happen against the drirection matrix */
|
||||||
MatrixScale (mtxCurrent[1], scale);
|
MatrixScale (mtxCurrent[1], scale);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
MatrixScale (mtxCurrent[current_matrix_mode], scale);
|
||||||
|
|
||||||
LOG("scale %f,%f,%f\n", scale[0], scale[1], scale[2]);
|
LOG("scale %f,%f,%f\n", scale[0], scale[1], scale[2]);
|
||||||
|
|
||||||
|
@ -1741,26 +1880,12 @@ static void
|
||||||
process_control( struct render_state *state,
|
process_control( struct render_state *state,
|
||||||
const u32 *parms) {
|
const u32 *parms) {
|
||||||
LOG("Control set to %08x\n", parms[0]);
|
LOG("Control set to %08x\n", parms[0]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Save for later.
|
||||||
|
* all control is handled at a 'begin' command
|
||||||
|
*/
|
||||||
disp_3D_control = parms[0];
|
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
|
static void
|
||||||
|
@ -1776,13 +1901,23 @@ process_alpha_function( struct render_state *state,
|
||||||
static void
|
static void
|
||||||
process_clear_depth( struct render_state *state,
|
process_clear_depth( struct render_state *state,
|
||||||
const u32 *parms) {
|
const u32 *parms) {
|
||||||
u32 depth24b;
|
//u32 depth24b;
|
||||||
u32 v = parms[0] & 0x7FFFF;
|
u32 v = parms[0] & 0x7FFFF;
|
||||||
LOG("Clear depth %08x\n", parms[0]);
|
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
|
static void
|
||||||
|
@ -1791,11 +1926,22 @@ process_clear_colour( struct render_state *state,
|
||||||
u32 v = parms[0];
|
u32 v = parms[0];
|
||||||
LOG("Clear colour %08x\n", v);
|
LOG("Clear colour %08x\n", v);
|
||||||
|
|
||||||
glClearColor( ((float)(v&0x1F))/31.0f,
|
/*
|
||||||
((float)((v>>5)&0x1F))/31.0f,
|
* Save for later.
|
||||||
((float)((v>>10)&0x1F))/31.0f,
|
* handled at a 'begin' command
|
||||||
((float)((v>>16)&0x1F))/31.0f);
|
*/
|
||||||
|
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;
|
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("\n------------------------------------\n");
|
||||||
LOG("Start of render\n");
|
LOG("Start of render\n");
|
||||||
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
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++) {
|
for ( i = 0; i < state->write_index; i++) {
|
||||||
u32 cmd = state->cmds[i];
|
u32 cmd = state->cmds[i];
|
||||||
//LOG("Render cmd: %08x\n", state->cmds[i]);
|
//LOG("Render cmd: %08x\n", state->cmds[i]);
|
||||||
|
|
Loading…
Reference in New Issue