Search
lxdream.org :: lxdream/src/pvr2/scene.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/pvr2/scene.c
changeset 863:a5e5310061e2
prev847:2089244671d2
next934:3acd3b3ee6d1
author nkeynes
date Sun Sep 28 01:09:51 2008 +0000 (11 years ago)
permissions -rw-r--r--
last change Initial shadow volume implementation for opaque polygons (stencil isn't quite
right, but we get some kind of shadows now)
file annotate diff log raw
1.1 --- a/src/pvr2/scene.c Sun Sep 07 04:23:49 2008 +0000
1.2 +++ b/src/pvr2/scene.c Sun Sep 28 01:09:51 2008 +0000
1.3 @@ -27,6 +27,8 @@
1.4 #include "pvr2/glutil.h"
1.5 #include "pvr2/scene.h"
1.6
1.7 +#define U8TOFLOAT(n) (((float)((n)+1))/256.0)
1.8 +
1.9 static void unpack_bgra(uint32_t bgra, float *rgba)
1.10 {
1.11 rgba[0] = ((float)(((bgra&0x00FF0000)>>16) + 1)) / 256.0;
1.12 @@ -65,10 +67,10 @@
1.13 return u.f;
1.14 }
1.15
1.16 -
1.17 struct pvr2_scene_struct pvr2_scene;
1.18
1.19 static gboolean vbo_init = FALSE;
1.20 +static float scene_shadow_intensity = 0.0;
1.21
1.22 #ifdef ENABLE_VERTEX_BUFFER
1.23 static gboolean vbo_supported = FALSE;
1.24 @@ -173,9 +175,9 @@
1.25 }
1.26
1.27 static struct polygon_struct *scene_add_polygon( pvraddr_t poly_idx, int vertex_count,
1.28 - gboolean is_modified )
1.29 + shadow_mode_t is_modified )
1.30 {
1.31 - int vert_mul = is_modified ? 2 : 1;
1.32 + int vert_mul = is_modified != SHADOW_NONE ? 2 : 1;
1.33
1.34 if( pvr2_scene.buf_to_poly_map[poly_idx] != NULL ) {
1.35 if( vertex_count > pvr2_scene.buf_to_poly_map[poly_idx]->vertex_count ) {
1.36 @@ -389,8 +391,31 @@
1.37 }
1.38 }
1.39
1.40 +static void scene_add_cheap_shadow_vertexes( struct vertex_struct *src, struct vertex_struct *dest, int count )
1.41 +{
1.42 + unsigned int i, j;
1.43 +
1.44 + for( i=0; i<count; i++ ) {
1.45 + dest->x = src->x;
1.46 + dest->y = src->y;
1.47 + dest->z = src->z;
1.48 + dest->u = src->u;
1.49 + dest->v = src->v;
1.50 + dest->rgba[0] = src->rgba[0] * scene_shadow_intensity;
1.51 + dest->rgba[1] = src->rgba[1] * scene_shadow_intensity;
1.52 + dest->rgba[2] = src->rgba[2] * scene_shadow_intensity;
1.53 + dest->rgba[3] = src->rgba[3] * scene_shadow_intensity;
1.54 + dest->offset_rgba[0] = src->offset_rgba[0] * scene_shadow_intensity;
1.55 + dest->offset_rgba[1] = src->offset_rgba[1] * scene_shadow_intensity;
1.56 + dest->offset_rgba[2] = src->offset_rgba[2] * scene_shadow_intensity;
1.57 + dest->offset_rgba[3] = src->offset_rgba[3];
1.58 + dest++;
1.59 + src++;
1.60 + }
1.61 +}
1.62 +
1.63 static void scene_add_vertexes( pvraddr_t poly_idx, int vertex_length,
1.64 - gboolean is_modified )
1.65 + shadow_mode_t is_modified )
1.66 {
1.67 struct polygon_struct *poly = pvr2_scene.buf_to_poly_map[poly_idx];
1.68 uint32_t *ptr = &pvr2_scene.pvr2_pbuf[poly_idx];
1.69 @@ -398,7 +423,7 @@
1.70 unsigned int i;
1.71
1.72 if( poly->vertex_index == -1 ) {
1.73 - ptr += (is_modified ? 5 : 3 );
1.74 + ptr += (is_modified == SHADOW_FULL ? 5 : 3 );
1.75 poly->vertex_index = pvr2_scene.vertex_index;
1.76
1.77 assert( poly != NULL );
1.78 @@ -408,20 +433,26 @@
1.79 ptr += vertex_length;
1.80 }
1.81 if( is_modified ) {
1.82 - int mod_offset = (vertex_length - 3)>>1;
1.83 assert( pvr2_scene.vertex_index + poly->vertex_count <= pvr2_scene.vertex_count );
1.84 - ptr = &pvr2_scene.pvr2_pbuf[poly_idx] + 5;
1.85 poly->mod_vertex_index = pvr2_scene.vertex_index;
1.86 - for( i=0; i<poly->vertex_count; i++ ) {
1.87 - pvr2_decode_render_vertex( &pvr2_scene.vertex_array[pvr2_scene.vertex_index++], context[0], context[3], ptr, mod_offset );
1.88 - ptr += vertex_length;
1.89 + if( is_modified == SHADOW_FULL ) {
1.90 + int mod_offset = (vertex_length - 3)>>1;
1.91 + ptr = &pvr2_scene.pvr2_pbuf[poly_idx] + 5;
1.92 + for( i=0; i<poly->vertex_count; i++ ) {
1.93 + pvr2_decode_render_vertex( &pvr2_scene.vertex_array[pvr2_scene.vertex_index++], context[0], context[3], ptr, mod_offset );
1.94 + ptr += vertex_length;
1.95 + }
1.96 + } else {
1.97 + scene_add_cheap_shadow_vertexes( &pvr2_scene.vertex_array[poly->vertex_index],
1.98 + &pvr2_scene.vertex_array[poly->mod_vertex_index], poly->vertex_count );
1.99 + pvr2_scene.vertex_index += poly->vertex_count;
1.100 }
1.101 }
1.102 }
1.103 }
1.104
1.105 static void scene_add_quad_vertexes( pvraddr_t poly_idx, int vertex_length,
1.106 - gboolean is_modified )
1.107 + shadow_mode_t is_modified )
1.108 {
1.109 struct polygon_struct *poly = pvr2_scene.buf_to_poly_map[poly_idx];
1.110 uint32_t *ptr = &pvr2_scene.pvr2_pbuf[poly_idx];
1.111 @@ -436,7 +467,7 @@
1.112
1.113 assert( poly != NULL );
1.114 assert( pvr2_scene.vertex_index + poly->vertex_count <= pvr2_scene.vertex_count );
1.115 - ptr += (is_modified ? 5 : 3 );
1.116 + ptr += (is_modified == SHADOW_FULL ? 5 : 3 );
1.117 poly->vertex_index = pvr2_scene.vertex_index;
1.118 for( i=0; i<4; i++ ) {
1.119 pvr2_decode_render_vertex( &quad[i], context[0], context[1], ptr, 0 );
1.120 @@ -450,18 +481,24 @@
1.121 pvr2_scene.vertex_index += 4;
1.122
1.123 if( is_modified ) {
1.124 - int mod_offset = (vertex_length - 3)>>1;
1.125 assert( pvr2_scene.vertex_index + poly->vertex_count <= pvr2_scene.vertex_count );
1.126 - ptr = &pvr2_scene.pvr2_pbuf[poly_idx] + 5;
1.127 poly->mod_vertex_index = pvr2_scene.vertex_index;
1.128 - for( i=0; i<4; i++ ) {
1.129 - pvr2_decode_render_vertex( &quad[4], context[0], context[3], ptr, mod_offset );
1.130 - ptr += vertex_length;
1.131 + if( is_modified == SHADOW_FULL ) {
1.132 + int mod_offset = (vertex_length - 3)>>1;
1.133 + ptr = &pvr2_scene.pvr2_pbuf[poly_idx] + 5;
1.134 + for( i=0; i<4; i++ ) {
1.135 + pvr2_decode_render_vertex( &quad[4], context[0], context[3], ptr, mod_offset );
1.136 + ptr += vertex_length;
1.137 + }
1.138 + scene_compute_vertexes( &quad[3], 1, &quad[0], !POLY1_GOURAUD_SHADED(context[0]) );
1.139 + memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index], quad, sizeof(struct vertex_struct)*2 );
1.140 + memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index+2], &quad[3], sizeof(struct vertex_struct) );
1.141 + memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index+3], &quad[2], sizeof(struct vertex_struct) );
1.142 + } else {
1.143 + scene_add_cheap_shadow_vertexes( &pvr2_scene.vertex_array[poly->vertex_index],
1.144 + &pvr2_scene.vertex_array[poly->mod_vertex_index], poly->vertex_count );
1.145 + pvr2_scene.vertex_index += poly->vertex_count;
1.146 }
1.147 - scene_compute_vertexes( &quad[3], 1, &quad[0], !POLY1_GOURAUD_SHADED(context[0]) );
1.148 - memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index], quad, sizeof(struct vertex_struct)*2 );
1.149 - memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index+2], &quad[3], sizeof(struct vertex_struct) );
1.150 - memcpy( &pvr2_scene.vertex_array[pvr2_scene.vertex_index+3], &quad[2], sizeof(struct vertex_struct) );
1.151 pvr2_scene.vertex_index += 4;
1.152 }
1.153 }
1.154 @@ -478,10 +515,10 @@
1.155 tile_list = (uint32_t *)(video_base + (entry&0x007FFFFF));
1.156 } else {
1.157 pvraddr_t polyaddr = entry&0x000FFFFF;
1.158 - int is_modified = (entry & 0x01000000) && pvr2_scene.full_shadow;
1.159 + shadow_mode_t is_modified = (entry & 0x01000000) ? pvr2_scene.shadow_mode : SHADOW_NONE;
1.160 int vertex_length = (entry >> 21) & 0x07;
1.161 int context_length = 3;
1.162 - if( is_modified ) {
1.163 + if( is_modified == SHADOW_FULL ) {
1.164 context_length = 5;
1.165 vertex_length <<= 1 ;
1.166 }
1.167 @@ -543,10 +580,10 @@
1.168 tile_list = (uint32_t *)(video_base + (entry&0x007FFFFF));
1.169 } else {
1.170 pvraddr_t polyaddr = entry&0x000FFFFF;
1.171 - int is_modified = (entry & 0x01000000) && pvr2_scene.full_shadow;
1.172 + shadow_mode_t is_modified = (entry & 0x01000000) ? pvr2_scene.shadow_mode : SHADOW_NONE;
1.173 int vertex_length = (entry >> 21) & 0x07;
1.174 int context_length = 3;
1.175 - if( is_modified ) {
1.176 + if( is_modified == SHADOW_FULL ) {
1.177 context_length = 5;
1.178 vertex_length <<=1 ;
1.179 }
1.180 @@ -592,16 +629,18 @@
1.181 uint32_t bgplane = MMIO_READ(PVR2, RENDER_BGPLANE);
1.182 int vertex_length = (bgplane >> 24) & 0x07;
1.183 int context_length = 3, i;
1.184 - int is_modified = (bgplane & 0x08000000) && pvr2_scene.full_shadow;
1.185 + shadow_mode_t is_modified = (bgplane & 0x08000000) ? pvr2_scene.shadow_mode : SHADOW_NONE;
1.186
1.187 struct polygon_struct *poly = &pvr2_scene.poly_array[pvr2_scene.poly_count++];
1.188 uint32_t *context = &pvr2_scene.pvr2_pbuf[(bgplane & 0x00FFFFFF)>>3];
1.189 poly->context = context;
1.190 poly->vertex_count = 4;
1.191 poly->vertex_index = pvr2_scene.vertex_count;
1.192 - if( is_modified ) {
1.193 + if( is_modified == SHADOW_FULL ) {
1.194 context_length = 5;
1.195 vertex_length <<= 1;
1.196 + }
1.197 + if( is_modified != SHADOW_NONE ) {
1.198 poly->mod_vertex_index = pvr2_scene.vertex_count + 4;
1.199 pvr2_scene.vertex_count += 8;
1.200 } else {
1.201 @@ -628,7 +667,7 @@
1.202 result_vertexes[2].y = result_vertexes[3].y = pvr2_scene.buffer_height;
1.203 scene_compute_vertexes( result_vertexes, 4, base_vertexes, !POLY1_GOURAUD_SHADED(context[0]) );
1.204
1.205 - if( is_modified ) {
1.206 + if( is_modified == SHADOW_FULL ) {
1.207 int mod_offset = (vertex_length - 3)>>1;
1.208 ptr = context + context_length;
1.209 for( i=0; i<3; i++ ) {
1.210 @@ -642,6 +681,10 @@
1.211 result_vertexes[1].y = result_vertexes[2].x = 0;
1.212 result_vertexes[2].y = result_vertexes[3].y = pvr2_scene.buffer_height;
1.213 scene_compute_vertexes( result_vertexes, 4, base_vertexes, !POLY1_GOURAUD_SHADED(context[0]) );
1.214 + } else if( is_modified == SHADOW_CHEAP ) {
1.215 + scene_add_cheap_shadow_vertexes( &pvr2_scene.vertex_array[poly->vertex_index],
1.216 + &pvr2_scene.vertex_array[poly->mod_vertex_index], poly->vertex_count );
1.217 + pvr2_scene.vertex_index += poly->vertex_count;
1.218 }
1.219
1.220 }
1.221 @@ -696,9 +739,11 @@
1.222
1.223 uint32_t *tilebuffer = (uint32_t *)(video_base + MMIO_READ( PVR2, RENDER_TILEBASE ));
1.224 uint32_t *segment = tilebuffer;
1.225 + uint32_t shadow = MMIO_READ(PVR2,RENDER_SHADOW);
1.226 pvr2_scene.segment_list = (struct tile_segment *)tilebuffer;
1.227 pvr2_scene.pvr2_pbuf = (uint32_t *)(video_base + MMIO_READ(PVR2,RENDER_POLYBASE));
1.228 - pvr2_scene.full_shadow = MMIO_READ( PVR2, RENDER_SHADOW ) & 0x100 ? FALSE : TRUE;
1.229 + pvr2_scene.shadow_mode = shadow & 0x100 ? SHADOW_CHEAP : SHADOW_FULL;
1.230 + scene_shadow_intensity = U8TOFLOAT(shadow&0xFF);
1.231
1.232 int max_tile_x = 0;
1.233 int max_tile_y = 0;
.