# HG changeset patch # User nkeynes # Date 1169553837 0 # Node ID 363935d31859dd298ea112e275b6d3ecabcaa612 # Parent 7c90a7dc139b4817c28f874defe84272d26393b3 Add initial offset color support Honor the "enable fragment alpha" bit --- a/src/pvr2/rendcore.c Tue Jan 23 11:21:21 2007 +0000 +++ b/src/pvr2/rendcore.c Tue Jan 23 12:03:57 2007 +0000 @@ -1,5 +1,5 @@ /** - * $Id: rendcore.c,v 1.10 2007-01-21 11:28:43 nkeynes Exp $ + * $Id: rendcore.c,v 1.11 2007-01-23 12:03:57 nkeynes Exp $ * * PVR2 renderer core. * @@ -52,6 +52,8 @@ extern char *video_base; +gboolean pvr2_force_fragment_alpha; + struct tile_segment { uint32_t control; pvraddr_t opaque_ptr; @@ -120,6 +122,12 @@ break; } + if( POLY1_SPECULAR(poly1) ) { + glEnable(GL_COLOR_SUM); + } else { + glDisable(GL_COLOR_SUM); + } + if( POLY1_TEXTURED(poly1) ) { int width = POLY2_TEX_WIDTH(poly2); int height = POLY2_TEX_HEIGHT(poly2); @@ -145,6 +153,9 @@ int srcblend = POLY2_SRC_BLEND(poly2); int destblend = POLY2_DEST_BLEND(poly2); glBlendFunc( srcblend, destblend ); + + pvr2_force_fragment_alpha = POLY2_ALPHA_ENABLE(poly2) ? FALSE : TRUE; + } void render_vertexes( uint32_t poly1, uint32_t *vertexes, int num_vertexes, int vertex_size, @@ -161,21 +172,32 @@ for( i=0; i>16), - halftofloat(vertexes[m+3]) ); - argb = vertexes[m+4]; + glTexCoord2f( halftofloat(vertexes[k]>>16), + halftofloat(vertexes[k]) ); + k++; } else { - glTexCoord2f( vertexf[m+3], vertexf[m+4] ); - argb = vertexes[m+5]; + glTexCoord2f( vertexf[k], vertexf[k+1] ); + k+=2; } - } else { - argb = vertexes[m+3]; } - glColor4ub( (GLubyte)(argb >> 16), (GLubyte)(argb >> 8), - (GLubyte)argb, (GLubyte)(argb >> 24) ); + argb = vertexes[k++]; + if( pvr2_force_fragment_alpha ) { + glColor4ub( (GLubyte)(argb >> 16), (GLubyte)(argb >> 8), + (GLubyte)argb, 0xFF ); + } else { + glColor4ub( (GLubyte)(argb >> 16), (GLubyte)(argb >> 8), + (GLubyte)argb, (GLubyte)(argb >> 24) ); + } + + if( POLY1_SPECULAR(poly1) ) { + uint32_t spec = vertexes[k++]; + glSecondaryColor3ubEXT( (GLubyte)(spec >> 16), (GLubyte)(spec >> 8), + (GLubyte)spec ); + } glVertex3f( vertexf[0], vertexf[1], vertexf[2] ); vertexes += vertex_size; } --- a/src/pvr2/rendsort.c Tue Jan 23 11:21:21 2007 +0000 +++ b/src/pvr2/rendsort.c Tue Jan 23 12:03:57 2007 +0000 @@ -1,5 +1,5 @@ /** - * $Id: rendsort.c,v 1.2 2007-01-12 10:15:06 nkeynes Exp $ + * $Id: rendsort.c,v 1.3 2007-01-23 12:03:57 nkeynes Exp $ * * PVR2 renderer routines for depth sorted polygons * @@ -20,6 +20,7 @@ #include "asic.h" extern char *video_base; +extern gboolean pvr2_force_fragment_alpha; #define MIN3( a,b,c ) ((a) < (b) ? ( (a) < (c) ? (a) : (c) ) : ((b) < (c) ? (b) : (c)) ) #define MAX3( a,b,c ) ((a) > (b) ? ( (a) > (c) ? (a) : (c) ) : ((b) > (c) ? (b) : (c)) ) @@ -37,6 +38,8 @@ float *vertexes[3]; }; +#define SENTINEL 0xDEADBEEF + /** * Count the number of triangles in the list starting at the given * pvr memory address. @@ -80,7 +83,7 @@ } void render_extract_triangles( pvraddr_t tile_entry, gboolean cheap_modifier_mode, - struct render_triangle *triangles ) + struct render_triangle *triangles, int num_triangles ) { uint32_t poly_bank = MMIO_READ(PVR2,RENDER_POLYBASE); uint32_t *tile_list = (uint32_t *)(video_base+tile_entry); @@ -167,12 +170,15 @@ } } } + if( count != num_triangles ) { + ERROR( "Extracted triangles do not match expected count!" ); + } } void render_triangles( struct render_triangle *triangles, int num_triangles, int render_mode ) { - int i,j, m = 0; + int i,j, k, m = 0; for( i=0; i>16), - halftofloat(vertexes[m+3]) ); - argb = vertexes[m+4]; + glTexCoord2f( halftofloat(vertexes[k]>>16), + halftofloat(vertexes[k]) ); + k++; } else { - glTexCoord2f( vertexf[m+3], vertexf[m+4] ); - argb = vertexes[m+5]; + glTexCoord2f( vertexf[k], vertexf[k+1] ); + k+=2; } + } + argb = vertexes[k++]; + if( pvr2_force_fragment_alpha ) { + glColor4ub( (GLubyte)(argb >> 16), (GLubyte)(argb >> 8), + (GLubyte)argb, 0xFF ); } else { - argb = vertexes[m+3]; + glColor4ub( (GLubyte)(argb >> 16), (GLubyte)(argb >> 8), + (GLubyte)argb, (GLubyte)(argb >> 24) ); } - - glColor4ub( (GLubyte)(argb >> 16), (GLubyte)(argb >> 8), - (GLubyte)argb, (GLubyte)(argb >> 24) ); + + if( POLY1_SPECULAR(*triangles[i].polygon) ) { + uint32_t spec = vertexes[k]; + glSecondaryColor3ubEXT( (GLubyte)(spec >> 16), (GLubyte)(spec >> 8), + (GLubyte)spec ); + } glVertex3f( vertexf[0], vertexf[1], vertexf[2] ); } glEnd(); @@ -234,10 +250,14 @@ } else if( num_triangles == 1 ) { /* Triangle can hardly overlap with itself */ render_tile( tile_entry, render_mode, cheap_modifier_mode ); } else { /* Ooh boy here we go... */ - struct render_triangle triangles[num_triangles]; - render_extract_triangles(tile_entry, cheap_modifier_mode, triangles); + struct render_triangle triangles[num_triangles+1]; + triangles[num_triangles].polygon = (void *)SENTINEL; + render_extract_triangles(tile_entry, cheap_modifier_mode, triangles, num_triangles); compute_triangle_boxes(triangles, num_triangles); sort_triangles( triangles, num_triangles ); render_triangles(triangles, num_triangles, render_mode); + if( triangles[num_triangles].polygon != (void *)SENTINEL ) { + fprintf( stderr, "Triangle overflow in render_autosort_tile!" ); + } } }