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.4 * GNU General Public License for more details.
1.9 #include "pvr2/pvr2.h"
1.10 #include "pvr2/scene.h"
1.12 +int pvr2_poly_depthmode[8] = { GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL,
1.13 + GL_GREATER, GL_NOTEQUAL, GL_GEQUAL,
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.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.35 * Clip the tile bounds to the clipping plane.
1.36 * @return TRUE if the tile was not clipped completely.
1.38 return tile[0] < tile[1] && tile[2] < tile[3];
1.41 +void pvr2_scene_load_textures()
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.56 + poly->tex_id = -1;
1.57 + poly->mod_tex_id = -1;
1.65 * Once-off call to setup the OpenGL context.
1.67 void pvr2_setup_gl_context()
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.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.84 +void render_set_context( uint32_t *context, int render_mode )
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.91 + poly2 = context[1];
1.92 + texture = context[2];
1.95 + if( POLY1_DEPTH_ENABLE(poly1) ) {
1.96 + glEnable( GL_DEPTH_TEST );
1.97 + glDepthFunc( POLY1_DEPTH_MODE(poly1) );
1.99 + glDisable( GL_DEPTH_TEST );
1.102 + switch( POLY1_CULL_MODE(poly1) ) {
1.105 + glDisable( GL_CULL_FACE );
1.108 + glEnable( GL_CULL_FACE );
1.109 + glFrontFace( GL_CW );
1.112 + glEnable( GL_CULL_FACE );
1.113 + glFrontFace( GL_CCW );
1.117 + if( POLY1_SPECULAR(poly1) ) {
1.118 + glEnable(GL_COLOR_SUM);
1.120 + glDisable(GL_COLOR_SUM);
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.132 + case 2:/* Decal */
1.133 + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
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.140 + case 3: /* Modulate RGBA */
1.141 + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
1.145 + if( POLY2_TEX_CLAMP_U(poly2) ) {
1.146 + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
1.148 + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
1.150 + if( POLY2_TEX_CLAMP_V(poly2) ) {
1.151 + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
1.153 + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
1.156 + glDisable( GL_TEXTURE_2D );
1.159 + glShadeModel( POLY1_SHADE_MODEL(poly1) );
1.161 + int srcblend = POLY2_SRC_BLEND(poly2);
1.162 + int destblend = POLY2_DEST_BLEND(poly2);
1.163 + glBlendFunc( srcblend, destblend );
1.165 + if( POLY2_SRC_BLEND_TARGET(poly2) || POLY2_DEST_BLEND_TARGET(poly2) ) {
1.166 + ERROR( "Accumulation buffer not supported" );
1.172 static void gl_render_poly( struct polygon_struct *poly )
1.174 + if( poly->tex_id != -1 ) {
1.175 + glBindTexture(GL_TEXTURE_2D, poly->tex_id);
1.177 render_set_context( poly->context, RENDER_NORMAL );
1.178 glDrawArrays(GL_TRIANGLE_STRIP, poly->vertex_index, poly->vertex_count );
1.182 -static void gl_render_tilelist( pvraddr_t tile_entry )
1.183 +void gl_render_tilelist( pvraddr_t tile_entry )
1.185 uint32_t *tile_list = (uint32_t *)(video_base+tile_entry);
1.187 @@ -76,21 +219,21 @@
1.189 tile_list = (uint32_t *)(video_base + (entry&0x007FFFFF));
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.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.215 @@ -102,8 +245,17 @@
1.216 void pvr2_scene_render( render_buffer_t buffer )
1.219 + struct timeval start_tv, tex_tv, end_tv;
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.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.231 /* Setup view projection matrix */
1.232 glMatrixMode(GL_PROJECTION);
1.233 @@ -114,7 +266,7 @@
1.236 glOrtho( 0, pvr2_scene.buffer_width, pvr2_scene.buffer_height, 0,
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.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.251 + render_autosort_tile(segment->trans_ptr, RENDER_NORMAL, !pvr2_scene.full_shadow);
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.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 );