Search
lxdream.org :: lxdream :: r319:5392aed6a982
lxdream 0.9.1
released Jun 29
Download Now
changeset319:5392aed6a982
parent318:363935d31859
child320:660b15095115
authornkeynes
dateWed Jan 24 08:11:14 2007 +0000 (17 years ago)
Add support for quads (auto-calculated 4th vertex)
src/pvr2/pvr2.h
src/pvr2/rendcore.c
src/pvr2/rendsort.c
1.1 --- a/src/pvr2/pvr2.h Tue Jan 23 12:03:57 2007 +0000
1.2 +++ b/src/pvr2/pvr2.h Wed Jan 24 08:11:14 2007 +0000
1.3 @@ -1,5 +1,5 @@
1.4 /**
1.5 - * $Id: pvr2.h,v 1.25 2007-01-23 11:19:32 nkeynes Exp $
1.6 + * $Id: pvr2.h,v 1.26 2007-01-24 08:11:14 nkeynes Exp $
1.7 *
1.8 * PVR2 (video chip) functions and macros.
1.9 *
1.10 @@ -208,7 +208,6 @@
1.11 gboolean pvr2_render_buffer_invalidate( sh4addr_t addr );
1.12
1.13
1.14 -
1.15 /**************************** Tile Accelerator ***************************/
1.16 /**
1.17 * Process the data in the supplied buffer as an array of TA command lists.
1.18 @@ -266,6 +265,24 @@
1.19 void pvr2_render_tilebuffer( int width, int height, int clipx1, int clipy1,
1.20 int clipx2, int clipy2 );
1.21
1.22 +
1.23 +/**
1.24 + * Structure to hold a complete unpacked vertex (excluding modifier
1.25 + * volume parameters - generate separate vertexes in that case).
1.26 + */
1.27 +struct vertex_unpacked {
1.28 + float x,y,z;
1.29 + float u,v; /* Texture coordinates */
1.30 + float rgba[4]; /* Fragment colour (RGBA order) */
1.31 + float offset_rgba[4]; /* Offset color (RGBA order) */
1.32 +};
1.33 +
1.34 +void render_unpacked_vertex_array( uint32_t poly1, struct vertex_unpacked *vertexes[],
1.35 + int num_vertexes );
1.36 +
1.37 +void render_vertex_array( uint32_t poly1, uint32_t *vertexes[], int num_vertexes,
1.38 + int vertex_size, int render_mode );
1.39 +
1.40 /****************************** Texture Cache ****************************/
1.41
1.42 /**
1.43 @@ -309,6 +326,7 @@
1.44 #define POLY1_CULL_MODE(poly1) (((poly1)>>27)&0x03)
1.45 #define POLY1_TEXTURED(poly1) (((poly1)&0x02000000))
1.46 #define POLY1_SPECULAR(poly1) (((poly1)&0x01000000))
1.47 +#define POLY1_GOURAUD_SHADED(poly1) ((poly1)&0x00800000)
1.48 #define POLY1_SHADE_MODEL(poly1) (((poly1)&0x00800000) ? GL_SMOOTH : GL_FLAT)
1.49 #define POLY1_UV16(poly1) (((poly1)&0x00400000))
1.50 #define POLY1_SINGLE_TILE(poly1) (((poly1)&0x00200000))
2.1 --- a/src/pvr2/rendcore.c Tue Jan 23 12:03:57 2007 +0000
2.2 +++ b/src/pvr2/rendcore.c Wed Jan 24 08:11:14 2007 +0000
2.3 @@ -1,5 +1,5 @@
2.4 /**
2.5 - * $Id: rendcore.c,v 1.11 2007-01-23 12:03:57 nkeynes Exp $
2.6 + * $Id: rendcore.c,v 1.12 2007-01-24 08:11:14 nkeynes Exp $
2.7 *
2.8 * PVR2 renderer core.
2.9 *
2.10 @@ -158,8 +158,151 @@
2.11
2.12 }
2.13
2.14 -void render_vertexes( uint32_t poly1, uint32_t *vertexes, int num_vertexes, int vertex_size,
2.15 - int render_mode )
2.16 +#define FARGB_A(x) (((float)(((x)>>24)+1))/256.0)
2.17 +#define FARGB_R(x) (((float)((((x)>>16)&0xFF)+1))/256.0)
2.18 +#define FARGB_G(x) (((float)((((x)>>8)&0xFF)+1))/256.0)
2.19 +#define FARGB_B(x) (((float)(((x)&0xFF)+1))/256.0)
2.20 +
2.21 +void render_unpack_vertexes( struct vertex_unpacked *out, uint32_t poly1,
2.22 + uint32_t *vertexes, int num_vertexes,
2.23 + int vertex_size, int render_mode )
2.24 +{
2.25 + int m = 0, i;
2.26 + if( render_mode == RENDER_FULLMOD ) {
2.27 + m = (vertex_size - 3)/2;
2.28 + }
2.29 +
2.30 + for( i=0; i<num_vertexes; i++ ) {
2.31 + float *vertexf = (float *)vertexes;
2.32 + int k = m + 3;
2.33 + out[i].x = vertexf[0];
2.34 + out[i].y = vertexf[1];
2.35 + out[i].z = vertexf[2];
2.36 + if( POLY1_TEXTURED(poly1) ) {
2.37 + if( POLY1_UV16(poly1) ) {
2.38 + out[i].u = halftofloat(vertexes[k]>>16);
2.39 + out[i].v = halftofloat(vertexes[k]);
2.40 + k++;
2.41 + } else {
2.42 + out[i].u = vertexf[k];
2.43 + out[i].v = vertexf[k+1];
2.44 + k+=2;
2.45 + }
2.46 + } else {
2.47 + out[i].u = 0;
2.48 + out[i].v = 0;
2.49 + }
2.50 + uint32_t argb = vertexes[k++];
2.51 + out[i].rgba[0] = FARGB_R(argb);
2.52 + out[i].rgba[1] = FARGB_G(argb);
2.53 + out[i].rgba[2] = FARGB_B(argb);
2.54 + out[i].rgba[3] = FARGB_A(argb);
2.55 + if( POLY1_SPECULAR(poly1) ) {
2.56 + uint32_t offset = vertexes[k++];
2.57 + out[i].offset_rgba[0] = FARGB_R(argb);
2.58 + out[i].offset_rgba[1] = FARGB_G(argb);
2.59 + out[i].offset_rgba[2] = FARGB_B(argb);
2.60 + out[i].offset_rgba[3] = FARGB_A(argb);
2.61 + }
2.62 + vertexes += vertex_size;
2.63 + }
2.64 +}
2.65 +
2.66 +/**
2.67 + * Unpack the vertexes for a quad, calculating the values for the last
2.68 + * vertex.
2.69 + * FIXME: Integrate this with rendbkg somehow
2.70 + */
2.71 +void render_unpack_quad( struct vertex_unpacked *unpacked, uint32_t poly1,
2.72 + uint32_t *vertexes, int vertex_size,
2.73 + int render_mode )
2.74 +{
2.75 + int i;
2.76 + struct vertex_unpacked diff0, diff1;
2.77 +
2.78 + render_unpack_vertexes( unpacked, poly1, vertexes, 3, vertex_size, render_mode );
2.79 +
2.80 + diff0.x = unpacked[0].x - unpacked[1].x;
2.81 + diff0.y = unpacked[0].y - unpacked[1].y;
2.82 + diff1.x = unpacked[2].x - unpacked[1].x;
2.83 + diff1.y = unpacked[2].y - unpacked[1].y;
2.84 +
2.85 + float detxy = ((diff1.y) * (diff0.x)) - ((diff0.y) * (diff1.x));
2.86 + float *vertexf = (float *)(vertexes+(vertex_size*3));
2.87 + if( detxy == 0 ) {
2.88 + memcpy( &unpacked[3], &unpacked[2], sizeof(struct vertex_unpacked) );
2.89 + unpacked[3].x = vertexf[0];
2.90 + unpacked[3].y = vertexf[1];
2.91 + return;
2.92 + }
2.93 +
2.94 + unpacked[3].x = vertexf[0];
2.95 + unpacked[3].y = vertexf[1];
2.96 + float t = ((unpacked[3].x - unpacked[1].x) * diff1.y -
2.97 + (unpacked[3].y - unpacked[1].y) * diff1.x) / detxy;
2.98 + float s = ((unpacked[3].y - unpacked[1].y) * diff0.x -
2.99 + (unpacked[3].x - unpacked[1].x) * diff0.y) / detxy;
2.100 + diff0.z = unpacked[0].z - unpacked[1].z;
2.101 + diff1.z = unpacked[2].z - unpacked[1].z;
2.102 + unpacked[3].z = unpacked[1].z + (t*diff0.z) + (s*diff1.z);
2.103 +
2.104 + diff0.u = unpacked[0].u - unpacked[1].u;
2.105 + diff0.v = unpacked[0].v - unpacked[1].v;
2.106 + diff1.u = unpacked[2].u - unpacked[1].u;
2.107 + diff1.v = unpacked[2].v - unpacked[1].v;
2.108 + unpacked[3].u = unpacked[1].u + (t*diff0.u) + (s*diff1.u);
2.109 + unpacked[3].v = unpacked[1].v + (t*diff0.v) + (s*diff1.v);
2.110 +
2.111 + if( !POLY1_GOURAUD_SHADED(poly1) ) {
2.112 + memcpy( unpacked[3].rgba, unpacked[2].rgba, sizeof(unpacked[2].rgba) );
2.113 + memcpy( unpacked[3].offset_rgba, unpacked[2].offset_rgba, sizeof(unpacked[2].offset_rgba) );
2.114 + } else {
2.115 + for( i=0; i<4; i++ ) {
2.116 + float d0 = unpacked[0].rgba[i] - unpacked[1].rgba[i];
2.117 + float d1 = unpacked[2].rgba[i] - unpacked[1].rgba[i];
2.118 + unpacked[3].rgba[i] = unpacked[1].rgba[i] + (t*d0) + (s*d1);
2.119 + d0 = unpacked[0].offset_rgba[i] - unpacked[1].offset_rgba[i];
2.120 + d1 = unpacked[2].offset_rgba[i] - unpacked[1].offset_rgba[i];
2.121 + unpacked[3].offset_rgba[i] = unpacked[1].offset_rgba[i] + (t*d0) + (s*d1);
2.122 + }
2.123 + }
2.124 +}
2.125 +
2.126 +void render_unpacked_vertex_array( uint32_t poly1, struct vertex_unpacked *vertexes[],
2.127 + int num_vertexes ) {
2.128 + int i;
2.129 +
2.130 + glBegin( GL_TRIANGLE_STRIP );
2.131 +
2.132 + for( i=0; i<num_vertexes; i++ ) {
2.133 + if( POLY1_TEXTURED(poly1) ) {
2.134 + glTexCoord2f( vertexes[i]->u, vertexes[i]->v );
2.135 + }
2.136 +
2.137 + glColor4f( vertexes[i]->rgba[0], vertexes[i]->rgba[1], vertexes[i]->rgba[2],
2.138 + (pvr2_force_fragment_alpha ? 1.0 : vertexes[i]->rgba[3]) );
2.139 +
2.140 + if( POLY1_SPECULAR(poly1) ) {
2.141 + glSecondaryColor3fEXT( vertexes[i]->offset_rgba[0],
2.142 + vertexes[i]->offset_rgba[1],
2.143 + vertexes[i]->offset_rgba[2] );
2.144 + }
2.145 + glVertex3f( vertexes[i]->x, vertexes[i]->y, vertexes[i]->z );
2.146 + }
2.147 +
2.148 + glEnd();
2.149 +}
2.150 +
2.151 +void render_quad_vertexes( uint32_t poly1, uint32_t *vertexes, int vertex_size, int render_mode )
2.152 +{
2.153 + struct vertex_unpacked unpacked[4];
2.154 + struct vertex_unpacked *pt[4] = {&unpacked[0], &unpacked[1], &unpacked[3], &unpacked[2]};
2.155 + render_unpack_quad( unpacked, poly1, vertexes, vertex_size, render_mode );
2.156 + render_unpacked_vertex_array( poly1, pt, 4 );
2.157 +}
2.158 +
2.159 +void render_vertex_array( uint32_t poly1, uint32_t *vert_array[], int num_vertexes, int vertex_size,
2.160 + int render_mode )
2.161 {
2.162 int i, m=0;
2.163
2.164 @@ -170,7 +313,8 @@
2.165 glBegin( GL_TRIANGLE_STRIP );
2.166
2.167 for( i=0; i<num_vertexes; i++ ) {
2.168 - float *vertexf = (float *)vertexes;
2.169 + uint32_t *vertexes = vert_array[i];
2.170 + float *vertexf = (float *)vert_array[i];
2.171 uint32_t argb;
2.172 int k = m + 3;
2.173 if( POLY1_TEXTURED(poly1) ) {
2.174 @@ -205,6 +349,18 @@
2.175 glEnd();
2.176 }
2.177
2.178 +void render_vertexes( uint32_t poly1, uint32_t *vertexes, int num_vertexes, int vertex_size,
2.179 + int render_mode )
2.180 +{
2.181 + uint32_t *vert_array[num_vertexes];
2.182 + int i;
2.183 + for( i=0; i<num_vertexes; i++ ) {
2.184 + vert_array[i] = vertexes;
2.185 + vertexes += vertex_size;
2.186 + }
2.187 + render_vertex_array( poly1, vert_array, num_vertexes, vertex_size, render_mode );
2.188 +}
2.189 +
2.190 /**
2.191 * Render a simple (not auto-sorted) tile
2.192 */
2.193 @@ -241,13 +397,13 @@
2.194 }
2.195 } else if( (entry & 0xE0000000) == 0xA0000000 ) {
2.196 /* Sprite(s) */
2.197 - int strip_count = (entry >> 25) & 0x0F;
2.198 + int strip_count = ((entry >> 25) & 0x0F)+1;
2.199 int polygon_length = 4 * vertex_length + context_length;
2.200 int i;
2.201 for( i=0; i<strip_count; i++ ) {
2.202 render_set_context( polygon, render_mode );
2.203 - render_vertexes( *polygon, polygon+context_length, 4, vertex_length,
2.204 - render_mode );
2.205 + render_quad_vertexes( *polygon, polygon+context_length, vertex_length,
2.206 + render_mode );
2.207 polygon += polygon_length;
2.208 }
2.209 } else {
3.1 --- a/src/pvr2/rendsort.c Tue Jan 23 12:03:57 2007 +0000
3.2 +++ b/src/pvr2/rendsort.c Wed Jan 24 08:11:14 2007 +0000
3.3 @@ -1,5 +1,5 @@
3.4 /**
3.5 - * $Id: rendsort.c,v 1.3 2007-01-23 12:03:57 nkeynes Exp $
3.6 + * $Id: rendsort.c,v 1.4 2007-01-24 08:11:14 nkeynes Exp $
3.7 *
3.8 * PVR2 renderer routines for depth sorted polygons
3.9 *
3.10 @@ -25,14 +25,9 @@
3.11 #define MIN3( a,b,c ) ((a) < (b) ? ( (a) < (c) ? (a) : (c) ) : ((b) < (c) ? (b) : (c)) )
3.12 #define MAX3( a,b,c ) ((a) > (b) ? ( (a) > (c) ? (a) : (c) ) : ((b) > (c) ? (b) : (c)) )
3.13
3.14 -struct pvr_vertex {
3.15 - float x,y,z;
3.16 - uint32_t detail[1];
3.17 -};
3.18 -
3.19 struct render_triangle {
3.20 uint32_t *polygon;
3.21 - int vertex_length;
3.22 + int vertex_length; /* Number of 32-bit words in vertex, or 0 for an unpacked vertex */
3.23 float minx,miny,minz;
3.24 float maxx,maxy,maxz;
3.25 float *vertexes[3];
3.26 @@ -83,7 +78,8 @@
3.27 }
3.28
3.29 void render_extract_triangles( pvraddr_t tile_entry, gboolean cheap_modifier_mode,
3.30 - struct render_triangle *triangles, int num_triangles )
3.31 + struct render_triangle *triangles, int num_triangles,
3.32 + struct vertex_unpacked *vertex_space, int render_mode )
3.33 {
3.34 uint32_t poly_bank = MMIO_READ(PVR2,RENDER_POLYBASE);
3.35 uint32_t *tile_list = (uint32_t *)(video_base+tile_entry);
3.36 @@ -123,27 +119,28 @@
3.37 count++;
3.38 }
3.39 } else if( (entry & 0xE0000000) == 0xA0000000 ) {
3.40 - /* Sprite(s) */
3.41 + /* Quad(s) */
3.42 int strip_count = ((entry >> 25) & 0x0F)+1;
3.43 int polygon_length = 4 * vertex_length + context_length;
3.44 +
3.45 int i;
3.46 for( i=0; i<strip_count; i++ ) {
3.47 - float *vertex = (float *)(polygon+context_length);
3.48 + render_unpack_quad( vertex_space, *polygon, (polygon+context_length),
3.49 + vertex_length, render_mode );
3.50 triangles[count].polygon = polygon;
3.51 - triangles[count].vertex_length = vertex_length;
3.52 - triangles[count].vertexes[0] = vertex;
3.53 - vertex+=vertex_length;
3.54 - triangles[count].vertexes[1] = vertex;
3.55 - vertex+=vertex_length;
3.56 - triangles[count].vertexes[2] = vertex;
3.57 + triangles[count].vertex_length = 0;
3.58 + triangles[count].vertexes[0] = (float *)vertex_space;
3.59 + triangles[count].vertexes[1] = (float *)(vertex_space + 1);
3.60 + triangles[count].vertexes[2] = (float *)(vertex_space + 3);
3.61 count++;
3.62 /* Preserve face direction */
3.63 triangles[count].polygon = polygon;
3.64 - triangles[count].vertex_length = vertex_length;
3.65 - triangles[count].vertexes[0] = vertex;
3.66 - triangles[count].vertexes[1] = vertex - vertex_length;
3.67 - triangles[count].vertexes[2] = vertex + vertex_length;
3.68 + triangles[count].vertex_length = 0;
3.69 + triangles[count].vertexes[0] = (float *)(vertex_space + 1);
3.70 + triangles[count].vertexes[1] = (float *)(vertex_space + 2);
3.71 + triangles[count].vertexes[2] = (float *)(vertex_space + 3);
3.72 count++;
3.73 + vertex_space += 4;
3.74 polygon += polygon_length;
3.75 }
3.76 } else {
3.77 @@ -181,44 +178,12 @@
3.78 int i,j, k, m = 0;
3.79 for( i=0; i<num_triangles; i++ ) {
3.80 render_set_context( triangles[i].polygon, render_mode );
3.81 - if( render_mode == RENDER_FULLMOD ) {
3.82 - m = (triangles[i].vertex_length - 3)/2;
3.83 + if( triangles[i].vertex_length == 0 ) {
3.84 + render_unpacked_vertex_array( *triangles[i].polygon, (struct vertex_unpacked **)triangles[i].vertexes, 3 );
3.85 + } else {
3.86 + render_vertex_array( *triangles[i].polygon, (uint32_t **)triangles[i].vertexes, 3,
3.87 + triangles[i].vertex_length, render_mode );
3.88 }
3.89 -
3.90 - glBegin( GL_TRIANGLE_STRIP );
3.91 -
3.92 - for( j=0; j<3; j++ ) {
3.93 - uint32_t *vertexes = (uint32_t *)triangles[i].vertexes[j];
3.94 - float *vertexf = (float *)vertexes;
3.95 - uint32_t argb;
3.96 - k = m + 3;
3.97 - if( POLY1_TEXTURED(*triangles[i].polygon) ) {
3.98 - if( POLY1_UV16(*triangles[i].polygon) ) {
3.99 - glTexCoord2f( halftofloat(vertexes[k]>>16),
3.100 - halftofloat(vertexes[k]) );
3.101 - k++;
3.102 - } else {
3.103 - glTexCoord2f( vertexf[k], vertexf[k+1] );
3.104 - k+=2;
3.105 - }
3.106 - }
3.107 - argb = vertexes[k++];
3.108 - if( pvr2_force_fragment_alpha ) {
3.109 - glColor4ub( (GLubyte)(argb >> 16), (GLubyte)(argb >> 8),
3.110 - (GLubyte)argb, 0xFF );
3.111 - } else {
3.112 - glColor4ub( (GLubyte)(argb >> 16), (GLubyte)(argb >> 8),
3.113 - (GLubyte)argb, (GLubyte)(argb >> 24) );
3.114 - }
3.115 -
3.116 - if( POLY1_SPECULAR(*triangles[i].polygon) ) {
3.117 - uint32_t spec = vertexes[k];
3.118 - glSecondaryColor3ubEXT( (GLubyte)(spec >> 16), (GLubyte)(spec >> 8),
3.119 - (GLubyte)spec );
3.120 - }
3.121 - glVertex3f( vertexf[0], vertexf[1], vertexf[2] );
3.122 - }
3.123 - glEnd();
3.124 }
3.125
3.126
3.127 @@ -251,8 +216,11 @@
3.128 render_tile( tile_entry, render_mode, cheap_modifier_mode );
3.129 } else { /* Ooh boy here we go... */
3.130 struct render_triangle triangles[num_triangles+1];
3.131 + struct vertex_unpacked vertex_space[num_triangles << 1];
3.132 + // Reserve space for num_triangles / 2 * 4 vertexes (maximum possible number of
3.133 + // quad vertices)
3.134 triangles[num_triangles].polygon = (void *)SENTINEL;
3.135 - render_extract_triangles(tile_entry, cheap_modifier_mode, triangles, num_triangles);
3.136 + render_extract_triangles(tile_entry, cheap_modifier_mode, triangles, num_triangles, vertex_space, render_mode);
3.137 compute_triangle_boxes(triangles, num_triangles);
3.138 sort_triangles( triangles, num_triangles );
3.139 render_triangles(triangles, num_triangles, render_mode);
.