Search
lxdream.org :: lxdream/src/pvr2/glrender.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/pvr2/glrender.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/glrender.c Mon Feb 18 09:21:43 2008 +0000
1.2 +++ b/src/pvr2/glrender.c Thu Mar 06 08:22:00 2008 +0000
1.3 @@ -16,10 +16,33 @@
1.4 * GNU General Public License for more details.
1.5 */
1.6
1.7 +#include <assert.h>
1.8 #include "display.h"
1.9 #include "pvr2/pvr2.h"
1.10 #include "pvr2/scene.h"
1.11
1.12 +int pvr2_poly_depthmode[8] = { GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL,
1.13 + GL_GREATER, GL_NOTEQUAL, GL_GEQUAL,
1.14 + GL_ALWAYS };
1.15 +int pvr2_poly_srcblend[8] = {
1.16 + GL_ZERO, GL_ONE, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR,
1.17 + GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA,
1.18 + GL_ONE_MINUS_DST_ALPHA };
1.19 +int pvr2_poly_dstblend[8] = {
1.20 + GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR,
1.21 + GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA,
1.22 + GL_ONE_MINUS_DST_ALPHA };
1.23 +int pvr2_poly_texblend[4] = {
1.24 + GL_REPLACE,
1.25 + GL_MODULATE,
1.26 + GL_DECAL,
1.27 + GL_MODULATE
1.28 +};
1.29 +int pvr2_render_colour_format[8] = {
1.30 + COLFMT_BGRA1555, COLFMT_RGB565, COLFMT_BGRA4444, COLFMT_BGRA1555,
1.31 + COLFMT_BGR888, COLFMT_BGRA8888, COLFMT_BGRA8888, COLFMT_BGRA4444 };
1.32 +
1.33 +
1.34 /**
1.35 * Clip the tile bounds to the clipping plane.
1.36 * @return TRUE if the tile was not clipped completely.
1.37 @@ -33,13 +56,35 @@
1.38 return tile[0] < tile[1] && tile[2] < tile[3];
1.39 }
1.40
1.41 +void pvr2_scene_load_textures()
1.42 +{
1.43 + int i;
1.44 + for( i=0; i < pvr2_scene.poly_count; i++ ) {
1.45 + struct polygon_struct *poly = &pvr2_scene.poly_array[i];
1.46 + if( POLY1_TEXTURED(poly->context[0]) ) {
1.47 + poly->tex_id = texcache_get_texture( poly->context[2],
1.48 + POLY2_TEX_WIDTH(poly->context[1]),
1.49 + POLY2_TEX_HEIGHT(poly->context[1]) );
1.50 + if( poly->mod_vertex_index != -1 ) {
1.51 + poly->mod_tex_id = texcache_get_texture( poly->context[4],
1.52 + POLY2_TEX_WIDTH(poly->context[3]),
1.53 + POLY2_TEX_HEIGHT(poly->context[3]) );
1.54 + }
1.55 + } else {
1.56 + poly->tex_id = -1;
1.57 + poly->mod_tex_id = -1;
1.58 + }
1.59 + }
1.60 +}
1.61 +
1.62 +
1.63 +
1.64 /**
1.65 * Once-off call to setup the OpenGL context.
1.66 */
1.67 void pvr2_setup_gl_context()
1.68 {
1.69 texcache_gl_init(); // Allocate texture IDs
1.70 - glShadeModel(GL_SMOOTH);
1.71 glCullFace( GL_BACK );
1.72 glEnable( GL_BLEND );
1.73 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1.74 @@ -56,13 +101,111 @@
1.75 glClearStencil(0);
1.76 }
1.77
1.78 +/**
1.79 + * Setup the GL context for the supplied polygon context.
1.80 + * @param context pointer to 3 or 5 words of polygon context
1.81 + * @param modified boolean flag indicating that the modified
1.82 + * version should be used, rather than the normal version.
1.83 + */
1.84 +void render_set_context( uint32_t *context, int render_mode )
1.85 +{
1.86 + uint32_t poly1 = context[0], poly2, texture;
1.87 + if( render_mode == RENDER_FULLMOD ) {
1.88 + poly2 = context[3];
1.89 + texture = context[4];
1.90 + } else {
1.91 + poly2 = context[1];
1.92 + texture = context[2];
1.93 + }
1.94 +
1.95 + if( POLY1_DEPTH_ENABLE(poly1) ) {
1.96 + glEnable( GL_DEPTH_TEST );
1.97 + glDepthFunc( POLY1_DEPTH_MODE(poly1) );
1.98 + } else {
1.99 + glDisable( GL_DEPTH_TEST );
1.100 + }
1.101 +
1.102 + switch( POLY1_CULL_MODE(poly1) ) {
1.103 + case CULL_NONE:
1.104 + case CULL_SMALL:
1.105 + glDisable( GL_CULL_FACE );
1.106 + break;
1.107 + case CULL_CCW:
1.108 + glEnable( GL_CULL_FACE );
1.109 + glFrontFace( GL_CW );
1.110 + break;
1.111 + case CULL_CW:
1.112 + glEnable( GL_CULL_FACE );
1.113 + glFrontFace( GL_CCW );
1.114 + break;
1.115 + }
1.116 +
1.117 + if( POLY1_SPECULAR(poly1) ) {
1.118 + glEnable(GL_COLOR_SUM);
1.119 + } else {
1.120 + glDisable(GL_COLOR_SUM);
1.121 + }
1.122 +
1.123 +
1.124 + if( POLY1_TEXTURED(poly1) ) {
1.125 + int width = POLY2_TEX_WIDTH(poly2);
1.126 + int height = POLY2_TEX_HEIGHT(poly2);
1.127 + glEnable(GL_TEXTURE_2D);
1.128 + switch( POLY2_TEX_BLEND(poly2) ) {
1.129 + case 0: /* Replace */
1.130 + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
1.131 + break;
1.132 + case 2:/* Decal */
1.133 + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
1.134 + break;
1.135 + case 1: /* Modulate RGB */
1.136 + /* This is not directly supported by opengl (other than by mucking
1.137 + * with the texture format), but we get the same effect by forcing
1.138 + * the fragment alpha to 1.0 and using GL_MODULATE.
1.139 + */
1.140 + case 3: /* Modulate RGBA */
1.141 + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
1.142 + break;
1.143 + }
1.144 +
1.145 + if( POLY2_TEX_CLAMP_U(poly2) ) {
1.146 + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
1.147 + } else {
1.148 + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
1.149 + }
1.150 + if( POLY2_TEX_CLAMP_V(poly2) ) {
1.151 + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
1.152 + } else {
1.153 + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
1.154 + }
1.155 + } else {
1.156 + glDisable( GL_TEXTURE_2D );
1.157 + }
1.158 +
1.159 + glShadeModel( POLY1_SHADE_MODEL(poly1) );
1.160 +
1.161 + int srcblend = POLY2_SRC_BLEND(poly2);
1.162 + int destblend = POLY2_DEST_BLEND(poly2);
1.163 + glBlendFunc( srcblend, destblend );
1.164 +
1.165 + if( POLY2_SRC_BLEND_TARGET(poly2) || POLY2_DEST_BLEND_TARGET(poly2) ) {
1.166 + ERROR( "Accumulation buffer not supported" );
1.167 + }
1.168 +
1.169 +}
1.170 +
1.171 +
1.172 static void gl_render_poly( struct polygon_struct *poly )
1.173 {
1.174 + if( poly->tex_id != -1 ) {
1.175 + glBindTexture(GL_TEXTURE_2D, poly->tex_id);
1.176 + }
1.177 render_set_context( poly->context, RENDER_NORMAL );
1.178 glDrawArrays(GL_TRIANGLE_STRIP, poly->vertex_index, poly->vertex_count );
1.179 +
1.180 }
1.181
1.182 -static void gl_render_tilelist( pvraddr_t tile_entry )
1.183 +void gl_render_tilelist( pvraddr_t tile_entry )
1.184 {
1.185 uint32_t *tile_list = (uint32_t *)(video_base+tile_entry);
1.186 int strip_count;
1.187 @@ -76,21 +219,21 @@
1.188 case 0x0E:
1.189 tile_list = (uint32_t *)(video_base + (entry&0x007FFFFF));
1.190 break;
1.191 - case 0x08:
1.192 - case 0x09:
1.193 - case 0x0A:
1.194 - case 0x0B:
1.195 + case 0x08: case 0x09: case 0x0A: case 0x0B:
1.196 strip_count = ((entry >> 25) & 0x0F)+1;
1.197 poly = pvr2_scene.buf_to_poly_map[entry&0x000FFFFF];
1.198 while( strip_count > 0 ) {
1.199 + assert( poly != NULL );
1.200 gl_render_poly( poly );
1.201 poly = poly->next;
1.202 strip_count--;
1.203 }
1.204 break;
1.205 default:
1.206 - poly = pvr2_scene.buf_to_poly_map[entry&0x000FFFFF];
1.207 - gl_render_poly( poly );
1.208 + if( entry & 0x7E000000 ) {
1.209 + poly = pvr2_scene.buf_to_poly_map[entry&0x000FFFFF];
1.210 + gl_render_poly( poly );
1.211 + }
1.212 }
1.213 }
1.214 }
1.215 @@ -102,8 +245,17 @@
1.216 void pvr2_scene_render( render_buffer_t buffer )
1.217 {
1.218 /* Scene setup */
1.219 + struct timeval start_tv, tex_tv, end_tv;
1.220 +
1.221 + gettimeofday(&start_tv, NULL);
1.222 display_driver->set_render_target(buffer);
1.223 pvr2_check_palette_changed();
1.224 + pvr2_scene_load_textures();
1.225 +
1.226 + gettimeofday( &tex_tv, NULL );
1.227 + uint32_t ms = (tex_tv.tv_sec - start_tv.tv_sec) * 1000 +
1.228 + (tex_tv.tv_usec - start_tv.tv_usec)/1000;
1.229 + DEBUG( "Scene setup in %dms", ms );
1.230
1.231 /* Setup view projection matrix */
1.232 glMatrixMode(GL_PROJECTION);
1.233 @@ -114,7 +266,7 @@
1.234 farz*= 2.0;
1.235 }
1.236 glOrtho( 0, pvr2_scene.buffer_width, pvr2_scene.buffer_height, 0,
1.237 - -nearz, -farz );
1.238 + -nearz, -farz );
1.239
1.240 /* Clear the buffer (FIXME: May not want always want to do this) */
1.241 glDisable( GL_SCISSOR_TEST );
1.242 @@ -148,7 +300,12 @@
1.243 gl_render_tilelist(segment->opaque_ptr);
1.244 }
1.245 if( IS_TILE_PTR(segment->trans_ptr) ) {
1.246 - gl_render_tilelist(segment->trans_ptr);
1.247 + if( pvr2_scene.sort_mode == SORT_NEVER ||
1.248 + (pvr2_scene.sort_mode == SORT_TILEFLAG && (segment->control&SEGMENT_SORT_TRANS))) {
1.249 + gl_render_tilelist(segment->trans_ptr);
1.250 + } else {
1.251 + render_autosort_tile(segment->trans_ptr, RENDER_NORMAL, !pvr2_scene.full_shadow);
1.252 + }
1.253 }
1.254 if( IS_TILE_PTR(segment->punchout_ptr) ) {
1.255 gl_render_tilelist(segment->punchout_ptr);
1.256 @@ -156,4 +313,8 @@
1.257 } while( !IS_LAST_SEGMENT(segment++) );
1.258 glDisable( GL_SCISSOR_TEST );
1.259
1.260 + gettimeofday( &end_tv, NULL );
1.261 + ms = (end_tv.tv_sec - tex_tv.tv_sec) * 1000 +
1.262 + (end_tv.tv_usec - tex_tv.tv_usec)/1000;
1.263 + DEBUG( "Scene render in %dms", ms );
1.264 }
.