<html>
<body>
<div id="body" style="background-color:#ffffff;" >
<table cellspacing="0" cellpadding="0" border="0" rules="cols">
<tr class="head" style="border-bottom-width:1px;border-bottom-style:solid;" ><td class="headtd" style="padding:0;padding-top:.2em;" colspan="4">Commit in <b><tt>lxdream/src/pvr2</tt></b></td></tr>
<tr><td><tt><a href="#file1">glrender.c</a></tt></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+38</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-39</td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">1e074a98317c -> f3da7d810d5c</td></tr>
<tr class="alt" style=";" ><td><tt><a href="#file2">rendsort.c</a></tt></td><td id="addedalt" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ccf7cc;" align="right">+22</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-19</td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">1e074a98317c -> f3da7d810d5c</td></tr>
<tr><td><tt><a href="#file3">scene.c</a></tt></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+88</td><td></td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">1e074a98317c -> f3da7d810d5c</td></tr>
<tr class="alt" style=";" ><td><tt><a href="#file4">scene.h</a></tt></td><td id="addedalt" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ccf7cc;" align="right">+4</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-2</td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">1e074a98317c -> f3da7d810d5c</td></tr>
<tr><td></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+152</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-60</td><td></td></tr>
</table>
<small id="info" style="color: #888888;" >4 modified files</small><br />
<div class="tasklist" style="padding:4px;border:1px dashed #000000;margin-top:1em;" ><ul>
<li><a href="#task1">FIXME: This could end up including a triangle that was</a></li>
</ul></div>
<pre class="comment" style="white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;padding:4px;border:1px dashed #000000;background-color:#ffffdd;" >
Perform backface culling in scene preparation rather than leaving it to the
GL - this is a huge performance win, at least on the 9400M - changing cull
state appears to be very expensive, whereas the CPU needed to do the same
job is only just barely measurable.
</pre>
<hr /><a name="file1" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream/src/pvr2</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>glrender.c</b></big> <small id="info" style="color: #888888;" >1e074a98317c -> f3da7d810d5c</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/pvr2/glrender.c
+++ lxdream/src/pvr2/glrender.c
@@ -101,7 +101,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
texcache_gl_init(); // Allocate texture IDs
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- glCullFace( GL_BACK );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ glDisable( GL_CULL_FACE );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > glEnable( GL_BLEND );
glEnable( GL_DEPTH_TEST );
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -131,24 +131,6 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > glFogf(GL_FOG_END, 1.0);
}
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static void render_set_cull( uint32_t poly1 )
-{
- switch( POLY1_CULL_MODE(poly1) ) {
- case CULL_NONE:
- case CULL_SMALL:
- glDisable( GL_CULL_FACE );
- break;
- case CULL_CCW:
- glEnable( GL_CULL_FACE );
- glFrontFace( GL_CW );
- break;
- case CULL_CW:
- glEnable( GL_CULL_FACE );
- glFrontFace( GL_CCW );
- break;
- }
-}
-
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > /**
* Setup the basic context that's shared between normal and modified modes -
* depth, culling
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -162,7 +144,6 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
glDepthMask( POLY1_DEPTH_WRITE(poly1) ? GL_TRUE : GL_FALSE );
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- render_set_cull( poly1 );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
/**
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -223,22 +204,40 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > render_set_tsp_context(context[0],context[1],context[2]);
}
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static inline void gl_draw_vertexes( struct polygon_struct *poly )
+{
+ do {
+ glDrawArrays(GL_TRIANGLE_STRIP, poly->vertex_index, poly->vertex_count);
+ poly = poly->sub_next;
+ } while( poly != NULL );
+}
+
+static inline void gl_draw_mod_vertexes( struct polygon_struct *poly )
+{
+ do {
+ glDrawArrays(GL_TRIANGLE_STRIP, poly->mod_vertex_index, poly->vertex_count);
+ poly = poly->sub_next;
+ } while( poly != NULL );
+}
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
static void gl_render_poly( struct polygon_struct *poly, GLint depth_mode )
{
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ if( poly->vertex_count == 0 )
+ return; /* Culled */
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > if( poly->tex_id != -1 ) {
glBindTexture(GL_TEXTURE_2D, poly->tex_id);
}
if( poly->mod_vertex_index == -1 ) {
glDisable( GL_STENCIL_TEST );
render_set_context( poly->context, depth_mode );
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- glDrawArrays(GL_TRIANGLE_STRIP, poly->vertex_index, poly->vertex_count );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ gl_draw_vertexes(poly);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > } else {
glEnable( GL_STENCIL_TEST );
render_set_base_context( poly->context[0], depth_mode );
render_set_tsp_context( poly->context[0], poly->context[1], poly->context[2] );
glStencilFunc(GL_EQUAL, 0, 2);
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- glDrawArrays(GL_TRIANGLE_STRIP, poly->vertex_index, poly->vertex_count );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ gl_draw_vertexes(poly);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
if( pvr2_scene.shadow_mode == SHADOW_FULL ) {
if( poly->mod_tex_id != -1 ) {
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -247,7 +246,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > render_set_tsp_context( poly->context[0], poly->context[3], poly->context[4] );
}
glStencilFunc(GL_EQUAL, 2, 2);
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- glDrawArrays(GL_TRIANGLE_STRIP, poly->mod_vertex_index, poly->vertex_count );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ gl_draw_mod_vertexes(poly);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
}
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -258,10 +257,8 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
render_set_context( poly->context, 0 );
glDisable( GL_DEPTH_TEST );
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- glDisable( GL_CULL_FACE );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > glBlendFunc( GL_ONE, GL_ZERO );
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- glDrawArrays(GL_TRIANGLE_STRIP, poly->vertex_index, poly->vertex_count );
- glEnable( GL_CULL_FACE );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ gl_draw_vertexes(poly);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > glEnable( GL_DEPTH_TEST );
}
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -327,8 +324,10 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > strip_count = ((entry >> 25) & 0x0F)+1;
poly = pvr2_scene.buf_to_poly_map[entry&0x000FFFFF];
while( strip_count > 0 ) {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- render_set_base_context(poly->context[0],0);
- glDrawArrays(GL_TRIANGLE_STRIP, poly->vertex_index, poly->vertex_count );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ if( poly->vertex_count != 0 ) {
+ render_set_base_context(poly->context[0],0);
+ gl_draw_vertexes(poly);
+ }
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > poly = poly->next;
strip_count--;
}
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -336,8 +335,10 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > default:
if( entry & 0x7E000000 ) {
poly = pvr2_scene.buf_to_poly_map[entry&0x000FFFFF];
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- render_set_base_context(poly->context[0],0);
- glDrawArrays(GL_TRIANGLE_STRIP, poly->vertex_index, poly->vertex_count );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ if( poly->vertex_count != 0 ) {
+ render_set_base_context(poly->context[0],0);
+ gl_draw_vertexes(poly);
+ }
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
}
}
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -368,8 +369,12 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > * now :)
*/
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- render_set_cull(poly->context[0]);
- glDrawArrays(GL_TRIANGLE_STRIP, poly->vertex_index, poly->vertex_count );
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ if( poly->vertex_count == 0 )
+ return; /* Culled */
+
+ gl_draw_vertexes(poly);
+
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
int poly_type = POLY1_VOLUME_MODE(poly->context[0]);
if( poly_type == PVR2_VOLUME_REGION0 ) {
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -381,7 +386,6 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > glStencilMask( 0x03 );
glStencilFunc(GL_EQUAL, 0x02, 0x03);
glStencilOp(GL_ZERO, GL_KEEP, GL_KEEP);
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- glDisable( GL_CULL_FACE );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > glDisable( GL_DEPTH_TEST );
drawrect2d( tile_bounds, pvr2_scene.bounds[4] );
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -399,7 +403,6 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > */
glStencilMask( 0x02 );
glStencilOp( GL_INVERT, GL_INVERT, GL_INVERT );
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- glDisable( GL_CULL_FACE );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > glDisable( GL_DEPTH_TEST );
drawrect2d( tile_bounds, pvr2_scene.bounds[4] );
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -427,7 +430,6 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > return;
glDisable( GL_TEXTURE_2D );
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- glDisable( GL_CULL_FACE );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > glEnable( GL_STENCIL_TEST );
glEnable( GL_DEPTH_TEST );
glDepthFunc( GL_LEQUAL );
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -552,10 +554,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > gl_render_tilelist(segment->punchout_ptr, GL_GEQUAL );
glDisable(GL_ALPHA_TEST );
}
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- glDisable( GL_STENCIL_TEST );
- glStencilMask(0x03);
- glClear( GL_STENCIL_BUFFER_BIT );
-
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > if( IS_TILE_PTR(segment->trans_ptr) ) {
if( pvr2_scene.sort_mode == SORT_NEVER ||
(pvr2_scene.sort_mode == SORT_TILEFLAG && (segment->control&SEGMENT_SORT_TRANS))) {
</pre></div>
<hr /><a name="file2" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream/src/pvr2</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>rendsort.c</b></big> <small id="info" style="color: #888888;" >1e074a98317c -> f3da7d810d5c</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/pvr2/rendsort.c
+++ lxdream/src/pvr2/rendsort.c
@@ -38,7 +38,8 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
/**
* Count the number of triangles in the list starting at the given
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- * pvr memory address.
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ * pvr memory address. This is an upper bound as it includes
+ * triangles that have been culled out.
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > */
static int sort_count_triangles( pvraddr_t tile_entry ) {
uint32_t *tile_list = (uint32_t *)(pvr2_main_ram+tile_entry);
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -54,11 +55,11 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > } else if( entry >> 29 == 0x05 ) { /* Quad array */
count += ((((entry >> 25) & 0x0F)+1)<<1);
} else { /* Polygon */
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- int i;
- for( i=0; i<6; i++ ) {
- if( entry & (0x40000000>>i) ) {
- count++;
- }
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ struct polygon_struct *poly = pvr2_scene.buf_to_poly_map[entry&0x000FFFFF];
+ while( poly != NULL ) {
+ if( poly->vertex_count != 0 )
+ count += poly->vertex_count-2;
+ poly = poly->sub_next;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
}
}
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -94,6 +95,8 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > vertexes[0].z*triangle->mz;
}
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > /**
* Extract a triangle list from the tile (basically indexes into the polygon list, plus
* computing maxz while we go through it
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -118,7 +121,8 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > poly = pvr2_scene.buf_to_poly_map[entry&0x000FFFFF];
while( strip_count > 0 ) {
assert( poly != NULL );
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- for( i=0; i<poly->vertex_count-2; i++ ) {
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ for( i=0; i+2<poly->vertex_count; i++ ) {
+ /* Note: tris + quads can't have sub-polys */
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > sort_add_triangle( &triangles[count], poly, i );
count++;
}
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -129,11 +133,17 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > default:
if( entry & 0x7E000000 ) {
poly = pvr2_scene.buf_to_poly_map[entry&0x000FFFFF];
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- for( i=0; i<6; i++ ) {
- if( entry & (0x40000000>>i) ) {
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" ><a name="task1" />+ /* <span class="task" style="background-color:#ffff00;" >FIXME</span>: This could end up including a triangle that was
+ * excluded from the tile, if it is part of a strip that
+ * still has some other triangles in the tile.
+ * (This couldn't happen with TA output though).
+ */
+ while( poly != NULL ) {
+ for( i=0; i+2<poly->vertex_count; i++ ) {
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > sort_add_triangle( &triangles[count], poly, i );
count++;
}
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ poly = poly->sub_next;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
}
}
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -151,13 +161,6 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
render_set_context( poly->context, GL_GEQUAL );
glDepthMask(GL_FALSE);
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- /* Fix cull direction */
- if( triangles[i]->triangle_num & 1 ) {
- glCullFace(GL_FRONT);
- } else {
- glCullFace(GL_BACK);
- }
-
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > glDrawArrays(GL_TRIANGLE_STRIP, poly->vertex_index + triangles[i]->triangle_num, 3 );
}
}
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -263,9 +266,9 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > triangle_order[i] = &triangles[i];
}
int extracted_triangles = sort_extract_triangles(tile_entry, triangles);
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- assert( extracted_triangles == num_triangles );
- sort_triangles( triangle_order, num_triangles, triangle_order );
- sort_render_triangles(triangle_order, num_triangles);
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ assert( extracted_triangles <= num_triangles );
+ sort_triangles( triangle_order, extracted_triangles, triangle_order );
+ sort_render_triangles(triangle_order, extracted_triangles);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > glCullFace(GL_BACK);
assert( triangles[num_triangles].poly == (void *)SENTINEL );
}
</pre></div>
<hr /><a name="file3" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream/src/pvr2</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>scene.c</b></big> <small id="info" style="color: #888888;" >1e074a98317c -> f3da7d810d5c</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/pvr2/scene.c
+++ lxdream/src/pvr2/scene.c
@@ -192,6 +192,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > poly->vertex_index = -1;
poly->mod_vertex_index = -1;
poly->next = NULL;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ poly->sub_next = NULL;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > pvr2_scene.buf_to_poly_map[poly_idx] = poly;
pvr2_scene.vertex_count += (vertex_count * vert_mul);
return poly;
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -199,6 +200,33 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
/**
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ * Given a starting polygon, break it at the specified triangle so that the
+ * preceding triangles are retained, and the remainder are contained in a
+ * new sub-polygon. Does not preserve winding.
+ */
+static struct polygon_struct *scene_split_subpolygon( struct polygon_struct *parent, int split_offset )
+{
+ assert( split_offset > 0 && split_offset < (parent->vertex_count-2) );
+ assert( pvr2_scene.poly_count < MAX_POLYGONS );
+ struct polygon_struct *poly = &pvr2_scene.poly_array[pvr2_scene.poly_count++];
+ poly->vertex_count = parent->vertex_count - split_offset;
+ poly->vertex_index = parent->vertex_index + split_offset;
+ if( parent->mod_vertex_index == -1 ) {
+ poly->mod_vertex_index = -1;
+ } else {
+ poly->mod_vertex_index = parent->mod_vertex_index + split_offset;
+ }
+ poly->context = parent->context;
+ poly->next = NULL;
+ poly->sub_next = parent->sub_next;
+
+ parent->sub_next = poly;
+ parent->vertex_count = split_offset + 2;
+
+ return poly;
+}
+
+/**
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > * Decode a single PVR2 renderable vertex (opaque/trans/punch-out, but not shadow
* volume)
* @param vert Pointer to output vertex structure
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -395,6 +423,64 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
}
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+/**
+ * Manually cull back-facing polygons where we can - this actually saves
+ * us a lot of time vs passing everything to GL to do it.
+ */
+static void scene_backface_cull()
+{
+ unsigned poly_idx;
+ unsigned poly_count = pvr2_scene.poly_count; /* Note: we don't want to process any sub-polygons created here */
+ for( poly_idx = 0; poly_idx<poly_count; poly_idx++ ) {
+ uint32_t poly1 = pvr2_scene.poly_array[poly_idx].context[0];
+ if( POLY1_CULL_ENABLE(poly1) ) {
+ struct polygon_struct *poly = &pvr2_scene.poly_array[poly_idx];
+ unsigned vert_idx = poly->vertex_index;
+ unsigned tri_count = poly->vertex_count-2;
+ struct vertex_struct *vert = &pvr2_scene.vertex_array[vert_idx];
+ unsigned i;
+ gboolean ccw = (POLY1_CULL_MODE(poly1) == CULL_CCW);
+ int first_visible = -1, last_visible = -1;
+ for( i=0; i<tri_count; i++ ) {
+ float ux = vert[i+1].x - vert[i].x;
+ float uy = vert[i+1].y - vert[i].y;
+ float vx = vert[i+2].x - vert[i].x;
+ float vy = vert[i+2].y - vert[i].y;
+ float nz = (ux*vy) - (uy*vx);
+ if( ccw ? nz > 0 : nz < 0 ) {
+ /* Surface is visible */
+ if( first_visible == -1 ) {
+ first_visible = i;
+ /* Elide the initial hidden triangles (note we don't
+ * need to care about winding anymore here) */
+ poly->vertex_index += i;
+ poly->vertex_count -= i;
+ if( poly->mod_vertex_index != -1 )
+ poly->mod_vertex_index += i;
+ } else if( last_visible != i-1 ) {
+ /* And... here we have to split the polygon. Allocate a new
+ * sub-polygon to hold the vertex references */
+ struct polygon_struct *sub = scene_split_subpolygon(poly, (i-first_visible));
+ poly->vertex_count -= (i-first_visible-1) - last_visible;
+ first_visible = i;
+ poly = sub;
+ }
+ last_visible = i;
+ } /* Else culled */
+ /* Invert ccw flag for triangle strip processing */
+ ccw = !ccw;
+ }
+ if( last_visible == -1 ) {
+ /* No visible surfaces, so we can mark the whole polygon as being vertex-less */
+ poly->vertex_count = 0;
+ } else if( last_visible != tri_count-1 ) {
+ /* Remove final hidden tris */
+ poly->vertex_count -= (tri_count - 1 - last_visible);
+ }
+ }
+ }
+}
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > static void scene_add_cheap_shadow_vertexes( struct vertex_struct *src, struct vertex_struct *dest, int count )
{
unsigned int i, j;
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -655,6 +741,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > context_length += (bgplane & 0x07) * vertex_length;
poly->next = NULL;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ poly->sub_next = NULL;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > pvr2_scene.bkgnd_poly = poly;
struct vertex_struct base_vertexes[3];
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -804,6 +891,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
scene_extract_background();
scene_compute_lut_fog();
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ scene_backface_cull();
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
vertex_buffer_unmap();
}
</pre></div>
<hr /><a name="file4" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream/src/pvr2</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>scene.h</b></big> <small id="info" style="color: #888888;" >1e074a98317c -> f3da7d810d5c</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/pvr2/scene.h
+++ lxdream/src/pvr2/scene.h
@@ -49,6 +49,7 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > uint32_t mod_tex_id;
int32_t mod_vertex_index; // index of first modified vertex in vertex buffer
struct polygon_struct *next; // chain for tri/quad arrays
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ struct polygon_struct *sub_next; // chain for internal sub-polygons
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > };
void pvr2_scene_init(void);
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -74,10 +75,11 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >
/**
* Maximum polygons - smallest is 1 polygon in 48 bytes, giving
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >- * 87381, plus 1 for the background
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+ * 87381, plus 1 for the background. Allow the same amount again
+ * for split polygons (worst case)
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > *
*/
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-#define MAX_POLYGONS <span id="removedchars" style="background-color:#ff9999;font-weight:bolder;" >87382</span>
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+#define MAX_POLYGONS <span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >(87382*2)</span>
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > #define MAX_POLY_BUFFER_SIZE (MAX_POLYGONS*sizeof(struct polygon_struct))
#define BUF_POLY_MAP_SIZE (4 MB)
</pre></div>
<center><small>Chaos Theory</small></center>
</div></body></html>