Search
lxdream.org :: lxdream/src/pvr2/scene.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/pvr2/scene.c
changeset 645:a7392098299c
prev639:162ee7614b60
next648:ef9aa5cba86f
author nkeynes
date Thu Mar 06 08:22:00 2008 +0000 (12 years ago)
branchlxdream-render
permissions -rw-r--r--
last change More refactor work in progress - nearly done now
file annotate diff log raw
1.1 --- a/src/pvr2/scene.c Mon Feb 18 09:21:43 2008 +0000
1.2 +++ b/src/pvr2/scene.c Thu Mar 06 08:22:00 2008 +0000
1.3 @@ -19,6 +19,7 @@
1.4
1.5 #include <assert.h>
1.6 #include <string.h>
1.7 +#include <math.h>
1.8 #include "lxdream.h"
1.9 #include "display.h"
1.10 #include "pvr2/pvr2.h"
1.11 @@ -33,6 +34,29 @@
1.12 return (bgra&0xFF00FF00) | ((bgra&0x00FF0000)>>16) | ((bgra&0x000000FF)<<16);
1.13 }
1.14
1.15 +/**
1.16 + * Convert a half-float (16-bit) FP number to a regular 32-bit float.
1.17 + * Source is 1-bit sign, 5-bit exponent, 10-bit mantissa.
1.18 + * TODO: Check the correctness of this.
1.19 + */
1.20 +static float halftofloat( uint16_t half )
1.21 +{
1.22 + union {
1.23 + float f;
1.24 + uint32_t i;
1.25 + } temp;
1.26 + /* int e = ((half & 0x7C00) >> 10) - 15 + 127;
1.27 +
1.28 + temp.i = ((half & 0x8000) << 16) | (e << 23) |
1.29 + ((half & 0x03FF) << 13); */
1.30 + temp.i = ((uint32_t)half)<<16;
1.31 + return temp.f;
1.32 +}
1.33 +
1.34 +
1.35 +
1.36 +
1.37 +
1.38 struct pvr2_scene_struct pvr2_scene;
1.39
1.40 static gboolean vbo_init = FALSE;
1.41 @@ -46,10 +70,12 @@
1.42 void pvr2_scene_init()
1.43 {
1.44 if( !vbo_init ) {
1.45 +#ifdef ENABLE_VERTEX_BUFFER
1.46 if( isGLExtensionSupported(VBO_EXT_STRING) ) {
1.47 vbo_supported = TRUE;
1.48 pvr2_scene.vbo_id = 1;
1.49 }
1.50 +#endif
1.51 pvr2_scene.vertex_array = NULL;
1.52 pvr2_scene.vertex_array_size = 0;
1.53 pvr2_scene.poly_array = g_malloc( MAX_POLY_BUFFER_SIZE );
1.54 @@ -70,16 +96,23 @@
1.55
1.56 void pvr2_scene_shutdown()
1.57 {
1.58 +#ifdef ENABLE_VERTEX_BUFFER
1.59 if( vbo_supported ) {
1.60 glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
1.61 glDeleteBuffersARB( 1, &pvr2_scene.vbo_id );
1.62 pvr2_scene.vbo_id = 0;
1.63 } else {
1.64 +#endif
1.65 g_free( pvr2_scene.vertex_array );
1.66 pvr2_scene.vertex_array = NULL;
1.67 +#ifdef ENABLE_VERTEX_BUFFER
1.68 }
1.69 +#endif
1.70 +
1.71 g_free( pvr2_scene.poly_array );
1.72 + pvr2_scene.poly_array = NULL;
1.73 g_free( pvr2_scene.buf_to_poly_map );
1.74 + pvr2_scene.buf_to_poly_map = NULL;
1.75 vbo_init = FALSE;
1.76 }
1.77
1.78 @@ -87,9 +120,9 @@
1.79 {
1.80 glGetError();
1.81 uint32_t size = pvr2_scene.vertex_count * sizeof(struct vertex_struct);
1.82 +#ifdef ENABLE_VERTEX_BUFFER
1.83 if( vbo_supported ) {
1.84 glBindBufferARB( GL_ARRAY_BUFFER_ARB, pvr2_scene.vbo_id );
1.85 - assert( glGetError() == 0 );
1.86 if( size > pvr2_scene.vertex_array_size ) {
1.87 glBufferDataARB( GL_ARRAY_BUFFER_ARB, size, NULL, GL_DYNAMIC_DRAW_ARB );
1.88 int status = glGetError();
1.89 @@ -102,21 +135,28 @@
1.90 pvr2_scene.vertex_array = glMapBufferARB( GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB );
1.91 assert(pvr2_scene.vertex_array != NULL );
1.92 } else {
1.93 +#endif
1.94 if( size > pvr2_scene.vertex_array_size ) {
1.95 pvr2_scene.vertex_array = g_realloc( pvr2_scene.vertex_array, size );
1.96 }
1.97 +#ifdef ENABLE_VERTEX_BUFFER
1.98 }
1.99 +#endif
1.100 return pvr2_scene.vertex_array;
1.101 }
1.102
1.103 gboolean vertex_buffer_unmap()
1.104 {
1.105 +#ifdef ENABLE_VERTEX_BUFFER
1.106 if( vbo_supported ) {
1.107 pvr2_scene.vertex_array = NULL;
1.108 return glUnmapBufferARB( GL_ARRAY_BUFFER_ARB );
1.109 } else {
1.110 return TRUE;
1.111 }
1.112 +#else
1.113 + return TRUE;
1.114 +#endif
1.115 }
1.116
1.117 static struct polygon_struct *scene_add_polygon( pvraddr_t poly_idx, int vertex_count,
1.118 @@ -135,6 +175,7 @@
1.119 poly->context = (uint32_t *)(video_base + MMIO_READ(PVR2,RENDER_POLYBASE) + (poly_idx<<2));
1.120 poly->vertex_count = vertex_count;
1.121 poly->vertex_index = -1;
1.122 + poly->mod_vertex_index = -1;
1.123 poly->next = NULL;
1.124 pvr2_scene.buf_to_poly_map[poly_idx] = poly;
1.125 pvr2_scene.vertex_count += (vertex_count * vert_mul);
1.126 @@ -168,6 +209,9 @@
1.127 vert->y = *data.fval++;
1.128
1.129 float z = *data.fval++;
1.130 + if( !isfinite(z) ) {
1.131 + z = 0;
1.132 + }
1.133 if( z > pvr2_scene.bounds[5] ) {
1.134 pvr2_scene.bounds[5] = z;
1.135 } else if( z < pvr2_scene.bounds[4] && z != 0 ) {
1.136 @@ -194,11 +238,15 @@
1.137 vert->rgba = bgra_to_rgba((*data.ival++) | 0xFF000000);
1.138 if( POLY1_SPECULAR(poly1) ) {
1.139 vert->offset_rgba = bgra_to_rgba((*data.ival++) | 0xFF000000);
1.140 + } else {
1.141 + vert->offset_rgba = 0;
1.142 }
1.143 } else {
1.144 vert->rgba = bgra_to_rgba(*data.ival++);
1.145 if( POLY1_SPECULAR(poly1) ) {
1.146 vert->offset_rgba = bgra_to_rgba(*data.ival++);
1.147 + } else {
1.148 + vert->offset_rgba = 0;
1.149 }
1.150 }
1.151 }
1.152 @@ -279,11 +327,11 @@
1.153 uint32_t *context = ptr;
1.154 unsigned int i;
1.155
1.156 - assert( poly != NULL );
1.157 if( poly->vertex_index == -1 ) {
1.158 ptr += (is_modified ? 5 : 3 );
1.159 poly->vertex_index = pvr2_scene.vertex_index;
1.160
1.161 + assert( poly != NULL );
1.162 assert( pvr2_scene.vertex_index + poly->vertex_count <= pvr2_scene.vertex_count );
1.163 for( i=0; i<poly->vertex_count; i++ ) {
1.164 pvr2_decode_render_vertex( &pvr2_scene.vertex_array[pvr2_scene.vertex_index++], context[0], context[1], ptr, 0 );
1.165 @@ -291,6 +339,7 @@
1.166 }
1.167 if( is_modified ) {
1.168 int mod_offset = (vertex_length - 3)>>1;
1.169 + assert( pvr2_scene.vertex_index + poly->vertex_count <= pvr2_scene.vertex_count );
1.170 ptr = &pvr2_scene.pvr2_pbuf[poly_idx] + 5;
1.171 poly->mod_vertex_index = pvr2_scene.vertex_index;
1.172 for( i=0; i<poly->vertex_count; i++ ) {
1.173 @@ -316,6 +365,7 @@
1.174 struct vertex_struct quad[4];
1.175
1.176 assert( poly != NULL );
1.177 + assert( pvr2_scene.vertex_index + poly->vertex_count <= pvr2_scene.vertex_count );
1.178 ptr += (is_modified ? 5 : 3 );
1.179 poly->vertex_index = pvr2_scene.vertex_index;
1.180 for( i=0; i<4; i++ ) {
1.181 @@ -331,6 +381,7 @@
1.182
1.183 if( is_modified ) {
1.184 int mod_offset = (vertex_length - 3)>>1;
1.185 + assert( pvr2_scene.vertex_index + poly->vertex_count <= pvr2_scene.vertex_count );
1.186 ptr = &pvr2_scene.pvr2_pbuf[poly_idx] + 5;
1.187 poly->mod_vertex_index = pvr2_scene.vertex_index;
1.188 for( i=0; i<4; i++ ) {
1.189 @@ -516,7 +567,7 @@
1.190 pvr2_scene.sort_mode = SORT_ALWAYS;
1.191 }
1.192 } else {
1.193 - pvr2_scene.sort_mode = SORT_BYFLAG;
1.194 + pvr2_scene.sort_mode = SORT_TILEFLAG;
1.195 }
1.196
1.197 // Pass 1: Extract polygon list
1.198 @@ -557,7 +608,46 @@
1.199 segment++;
1.200 }
1.201 } while( (control & SEGMENT_END) == 0 );
1.202 -
1.203 vertex_buffer_unmap();
1.204 }
1.205 }
1.206 +
1.207 +/**
1.208 + * Dump the current scene to file in a (mostly) human readable form
1.209 + */
1.210 +void pvr2_scene_dump( FILE *f )
1.211 +{
1.212 + int i,j;
1.213 +
1.214 + fprintf( f, "Polygons: %d\n", pvr2_scene.poly_count );
1.215 + for( i=0; i<pvr2_scene.poly_count; i++ ) {
1.216 + struct polygon_struct *poly = &pvr2_scene.poly_array[i];
1.217 + fprintf( f, " %08X ", ((char *)poly->context) - video_base );
1.218 + switch( poly->vertex_count ) {
1.219 + case 3: fprintf( f, "Tri " ); break;
1.220 + case 4: fprintf( f, "Quad " ); break;
1.221 + default: fprintf( f,"%d-Strip ", poly->vertex_count-2 ); break;
1.222 + }
1.223 + fprintf( f, "%08X %08X %08X ", poly->context[0], poly->context[1], poly->context[2] );
1.224 + if( poly->mod_vertex_index != -1 ) {
1.225 + fprintf( f, "%08X %08X\n", poly->context[3], poly->context[5] );
1.226 + } else {
1.227 + fprintf( f, "\n" );
1.228 + }
1.229 +
1.230 + for( j=0; j<poly->vertex_count; j++ ) {
1.231 + struct vertex_struct *v = &pvr2_scene.vertex_array[poly->vertex_index+j];
1.232 + fprintf( f, " %.5f %.5f %.5f, (%.5f,%.5f) %08X %08X\n", v->x, v->y, v->z, v->u, v->v,
1.233 + v->rgba, v->offset_rgba );
1.234 + }
1.235 + if( poly->mod_vertex_index != -1 ) {
1.236 + fprintf( f, " ---\n" );
1.237 + for( j=0; j<poly->vertex_count; j++ ) {
1.238 + struct vertex_struct *v = &pvr2_scene.vertex_array[poly->mod_vertex_index+j];
1.239 + fprintf( f, " %.5f %.5f %.5f, (%.5f,%.5f) %08X %08X\n", v->x, v->y, v->z, v->u, v->v,
1.240 + v->rgba, v->offset_rgba );
1.241 + }
1.242 + }
1.243 + }
1.244 +
1.245 +}
.