Search
lxdream.org :: lxdream :: r1232:e5b12e2fe6ba
lxdream 0.9.1
released Jun 29
Download Now
changeset1232:e5b12e2fe6ba
parent1231:d63c808ddcd3
child1233:06923d1020de
authornkeynes
dateThu Feb 23 22:20:15 2012 +1000 (7 years ago)
Remove most of the remaining fixed-functionality in the shader rendering
path.
Rearrange the renderer to do each list for the full scene in turn, rather
than doing each tile completely
src/pvr2/glrender.c
src/pvr2/shaders.glsl
1.1 --- a/src/pvr2/glrender.c Thu Feb 23 20:16:37 2012 +1000
1.2 +++ b/src/pvr2/glrender.c Thu Feb 23 22:20:15 2012 +1000
1.3 @@ -33,7 +33,7 @@
1.4 static CGLContextObj CGL_MACRO_CONTEXT;
1.5 #endif
1.6
1.7 -#define IS_EMPTY_TILE_LIST(p) ((*((uint32_t *)(pvr2_main_ram+(p))) >> 28) == 0x0F)
1.8 +#define IS_NONEMPTY_TILE_LIST(p) (IS_TILE_PTR(p) && ((*((uint32_t *)(pvr2_main_ram+(p))) >> 28) != 0x0F))
1.9
1.10 int pvr2_poly_depthmode[8] = { GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL,
1.11 GL_GREATER, GL_NOTEQUAL, GL_GEQUAL,
1.12 @@ -62,7 +62,7 @@
1.13 * Clip the tile bounds to the clipping plane.
1.14 * @return TRUE if the tile was not clipped completely.
1.15 */
1.16 -static gboolean clip_tile_bounds( uint32_t *tile, float *clip )
1.17 +static gboolean clip_tile_bounds( uint32_t *tile, uint32_t *clip )
1.18 {
1.19 if( tile[0] < clip[0] ) tile[0] = clip[0];
1.20 if( tile[1] > clip[1] ) tile[1] = clip[1];
1.21 @@ -73,11 +73,11 @@
1.22
1.23 static void drawrect2d( uint32_t tile_bounds[], float z )
1.24 {
1.25 - glBegin( GL_QUADS );
1.26 + glBegin( GL_TRIANGLE_STRIP );
1.27 glVertex3f( tile_bounds[0], tile_bounds[2], z );
1.28 glVertex3f( tile_bounds[1], tile_bounds[2], z );
1.29 + glVertex3f( tile_bounds[0], tile_bounds[3], z );
1.30 glVertex3f( tile_bounds[1], tile_bounds[3], z );
1.31 - glVertex3f( tile_bounds[0], tile_bounds[3], z );
1.32 glEnd();
1.33 }
1.34
1.35 @@ -112,7 +112,6 @@
1.36 */
1.37 void pvr2_setup_gl_context()
1.38 {
1.39 -
1.40 if( glsl_is_supported() && isGLMultitextureSupported() ) {
1.41 if( !glsl_load_shaders( ) ) {
1.42 WARN( "Unable to load GL shaders" );
1.43 @@ -128,9 +127,6 @@
1.44 glDisable( GL_CULL_FACE );
1.45 glEnable( GL_BLEND );
1.46 glEnable( GL_DEPTH_TEST );
1.47 - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1.48 - glMatrixMode(GL_MODELVIEW);
1.49 - glLoadIdentity();
1.50
1.51 #ifdef HAVE_OPENGL_CLAMP_COLOR
1.52 if( isGLExtensionSupported("GL_ARB_color_buffer_float") ) {
1.53 @@ -139,27 +135,14 @@
1.54 }
1.55 #endif
1.56
1.57 - glEnableClientState( GL_COLOR_ARRAY );
1.58 - glEnableClientState( GL_VERTEX_ARRAY );
1.59 - glEnableClientState( GL_TEXTURE_COORD_ARRAY );
1.60 - glEnableClientState( GL_SECONDARY_COLOR_ARRAY );
1.61 - glEnableClientState( GL_FOG_COORDINATE_ARRAY_EXT );
1.62 + glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
1.63
1.64 - glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
1.65 +#ifdef HAVE_OPENGL_CLEAR_DEPTHF
1.66 + glClearDepthf(0);
1.67 +#else
1.68 glClearDepth(0);
1.69 +#endif
1.70 glClearStencil(0);
1.71 -
1.72 - glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
1.73 - glFogi(GL_FOG_MODE, GL_LINEAR);
1.74 - glFogf(GL_FOG_START, 0.0);
1.75 - glFogf(GL_FOG_END, 1.0);
1.76 -
1.77 - if( have_shaders ) {
1.78 - glsl_use_pvr2_shader();
1.79 - glsl_set_pvr2_shader_primary_texture(0);
1.80 - glsl_set_pvr2_shader_palette_texture(1);
1.81 - glsl_clear_shader();
1.82 - }
1.83 }
1.84
1.85 /**
1.86 @@ -182,24 +165,26 @@
1.87 {
1.88 glShadeModel( POLY1_SHADE_MODEL(poly1) );
1.89
1.90 +#ifdef HAVE_OPENGL_FIXEDFUNC
1.91 if( !have_shaders ) {
1.92 if( POLY1_TEXTURED(poly1) ) {
1.93 if( POLY2_TEX_BLEND(poly2) == 2 )
1.94 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
1.95 else
1.96 glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
1.97 +
1.98 + }
1.99
1.100 - }
1.101 - }
1.102 -
1.103 - switch( POLY2_FOG_MODE(poly2) ) {
1.104 - case PVR2_POLY_FOG_LOOKUP:
1.105 - glFogfv( GL_FOG_COLOR, pvr2_scene.fog_lut_colour );
1.106 - break;
1.107 - case PVR2_POLY_FOG_VERTEX:
1.108 - glFogfv( GL_FOG_COLOR, pvr2_scene.fog_vert_colour );
1.109 - break;
1.110 + switch( POLY2_FOG_MODE(poly2) ) {
1.111 + case PVR2_POLY_FOG_LOOKUP:
1.112 + glFogfv( GL_FOG_COLOR, pvr2_scene.fog_lut_colour );
1.113 + break;
1.114 + case PVR2_POLY_FOG_VERTEX:
1.115 + glFogfv( GL_FOG_COLOR, pvr2_scene.fog_vert_colour );
1.116 + break;
1.117 + }
1.118 }
1.119 +#endif
1.120
1.121 int srcblend = POLY2_SRC_BLEND(poly2);
1.122 int destblend = POLY2_DEST_BLEND(poly2);
1.123 @@ -387,17 +372,6 @@
1.124 {
1.125 tileentryiter list;
1.126
1.127 - if( !IS_TILE_PTR(tile_entry) )
1.128 - return;
1.129 -
1.130 - glEnable( GL_STENCIL_TEST );
1.131 - glEnable( GL_DEPTH_TEST );
1.132 - glStencilFunc( GL_ALWAYS, 0, 1 );
1.133 - glStencilOp( GL_KEEP,GL_INVERT, GL_KEEP );
1.134 - glStencilMask( 0x01 );
1.135 - glDepthFunc( GL_LEQUAL );
1.136 - glDepthMask( GL_FALSE );
1.137 -
1.138 FOREACH_TILEENTRY(list, tile_entry ) {
1.139 struct polygon_struct *poly = pvr2_scene.buf_to_poly_map[TILEENTRYITER_POLYADDR(list)];
1.140 if( poly != NULL ) {
1.141 @@ -407,9 +381,123 @@
1.142 } while( list.strip_count-- > 0 );
1.143 }
1.144 }
1.145 - glDepthMask( GL_TRUE );
1.146 - glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
1.147 - glDisable( GL_STENCIL_TEST );
1.148 +}
1.149 +
1.150 +/**
1.151 + * Define an orthographic projection matrix
1.152 + * Note: row-major order
1.153 + */
1.154 +static void setOrtho( GLfloat *matrix, GLfloat width, GLfloat height, GLfloat znear, GLfloat zfar )
1.155 +{
1.156 + matrix[0] = 2/width;
1.157 + matrix[1] = 0;
1.158 + matrix[2] = 0;
1.159 + matrix[3] = 0;
1.160 +
1.161 + matrix[4] = 0;
1.162 + matrix[5] = -2/height;
1.163 + matrix[6] = 0;
1.164 + matrix[7] = 0;
1.165 +
1.166 + matrix[8] = 0;
1.167 + matrix[9] = 0;
1.168 + matrix[10]= -2/(zfar-znear);
1.169 + matrix[11]= 0;
1.170 +
1.171 + matrix[12]= -1;
1.172 + matrix[13]= 1;
1.173 + matrix[14]= -(zfar+znear)/(zfar-znear);
1.174 + matrix[15]= 1;
1.175 +}
1.176 +
1.177 +#ifdef HAVE_OPENGL_FIXEDFUNC
1.178 +void pvr2_scene_setup_fixed( GLfloat *viewMatrix )
1.179 +{
1.180 + glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
1.181 +
1.182 + glMatrixMode(GL_MODELVIEW);
1.183 + glLoadIdentity();
1.184 + glMatrixMode(GL_PROJECTION);
1.185 + glLoadIdentity();
1.186 + glLoadMatrixf(viewMatrix);
1.187 +
1.188 + glEnable( GL_FOG );
1.189 + glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT);
1.190 + glFogi(GL_FOG_MODE, GL_LINEAR);
1.191 + glFogf(GL_FOG_START, 0.0);
1.192 + glFogf(GL_FOG_END, 1.0);
1.193 +
1.194 + glEnable( GL_ALPHA_TEST );
1.195 + glAlphaFunc( GL_GEQUAL, 0 );
1.196 +
1.197 + glEnable( GL_COLOR_SUM );
1.198 +
1.199 + glEnableClientState( GL_VERTEX_ARRAY );
1.200 + glEnableClientState( GL_COLOR_ARRAY );
1.201 + glEnableClientState( GL_TEXTURE_COORD_ARRAY );
1.202 + glEnableClientState( GL_SECONDARY_COLOR_ARRAY );
1.203 + glEnableClientState( GL_FOG_COORDINATE_ARRAY_EXT );
1.204 +
1.205 + /* Vertex array pointers */
1.206 + glVertexPointer(3, GL_FLOAT, sizeof(struct vertex_struct), &pvr2_scene.vertex_array[0].x);
1.207 + glColorPointer(4, GL_FLOAT, sizeof(struct vertex_struct), &pvr2_scene.vertex_array[0].rgba[0]);
1.208 + glTexCoordPointer(4, GL_FLOAT, sizeof(struct vertex_struct), &pvr2_scene.vertex_array[0].u);
1.209 + glSecondaryColorPointerEXT(3, GL_FLOAT, sizeof(struct vertex_struct), pvr2_scene.vertex_array[0].offset_rgba );
1.210 + glFogCoordPointerEXT(GL_FLOAT, sizeof(struct vertex_struct), &pvr2_scene.vertex_array[0].offset_rgba[3] );
1.211 +}
1.212 +
1.213 +void pvr2_scene_set_alpha_fixed( float alphaRef )
1.214 +{
1.215 + glAlphaFunc( GL_GEQUAL, alphaRef );
1.216 +}
1.217 +
1.218 +void pvr2_scene_cleanup_fixed()
1.219 +{
1.220 + glDisable( GL_COLOR_SUM );
1.221 + glDisable( GL_FOG );
1.222 + glDisable( GL_ALPHA_TEST );
1.223 +
1.224 + glDisableClientState( GL_VERTEX_ARRAY );
1.225 + glDisableClientState( GL_COLOR_ARRAY );
1.226 + glDisableClientState( GL_TEXTURE_COORD_ARRAY );
1.227 + glDisableClientState( GL_SECONDARY_COLOR_ARRAY );
1.228 + glDisableClientState( GL_FOG_COORDINATE_ARRAY_EXT );
1.229 +}
1.230 +#else
1.231 +void pvr2_scene_setup_fixed( GLfloat *viewMatrix, float alphaRef )
1.232 +{
1.233 +}
1.234 +void pvr2_scene_set_alpha_fixed( float alphaRef )
1.235 +{
1.236 +}
1.237 +void pvr2_scene_cleanup_fixed()
1.238 +{
1.239 +}
1.240 +#endif
1.241 +
1.242 +void pvr2_scene_setup_shader( GLfloat *viewMatrix )
1.243 +{
1.244 + glsl_use_pvr2_shader();
1.245 + glsl_set_pvr2_shader_view_matrix(viewMatrix);
1.246 + glsl_set_pvr2_shader_fog_colour1(pvr2_scene.fog_vert_colour);
1.247 + glsl_set_pvr2_shader_fog_colour2(pvr2_scene.fog_lut_colour);
1.248 + glsl_set_pvr2_shader_in_vertex_vec3_pointer(&pvr2_scene.vertex_array[0].x, sizeof(struct vertex_struct));
1.249 + glsl_set_pvr2_shader_in_colour_pointer(&pvr2_scene.vertex_array[0].rgba[0], sizeof(struct vertex_struct));
1.250 + glsl_set_pvr2_shader_in_colour2_pointer(&pvr2_scene.vertex_array[0].offset_rgba[0], sizeof(struct vertex_struct));
1.251 + glsl_set_pvr2_shader_in_texcoord_pointer(&pvr2_scene.vertex_array[0].u, sizeof(struct vertex_struct));
1.252 + glsl_set_pvr2_shader_alpha_ref(0.0);
1.253 + glsl_set_pvr2_shader_primary_texture(0);
1.254 + glsl_set_pvr2_shader_palette_texture(1);
1.255 +}
1.256 +
1.257 +void pvr2_scene_cleanup_shader( )
1.258 +{
1.259 + glsl_clear_shader();
1.260 +}
1.261 +
1.262 +void pvr2_scene_set_alpha_shader( float alphaRef )
1.263 +{
1.264 + glsl_set_pvr2_shader_alpha_ref(alphaRef);
1.265 }
1.266
1.267 /**
1.268 @@ -419,6 +507,10 @@
1.269 {
1.270 /* Scene setup */
1.271 struct timeval start_tv, tex_tv, end_tv;
1.272 + int i;
1.273 + GLfloat viewMatrix[16];
1.274 + uint32_t clip_bounds[4];
1.275 +
1.276
1.277 gettimeofday(&start_tv, NULL);
1.278 display_driver->set_render_target(buffer);
1.279 @@ -429,20 +521,28 @@
1.280 gettimeofday( &tex_tv, NULL );
1.281 uint32_t ms = (tex_tv.tv_sec - start_tv.tv_sec) * 1000 +
1.282 (tex_tv.tv_usec - start_tv.tv_usec)/1000;
1.283 - DEBUG( "Scene setup in %dms", ms );
1.284 + DEBUG( "Texture load in %dms", ms );
1.285
1.286 - /* Setup view projection matrix */
1.287 - glMatrixMode(GL_PROJECTION);
1.288 - glLoadIdentity();
1.289 + float alphaRef = ((float)(MMIO_READ(PVR2, RENDER_ALPHA_REF)&0xFF)+1)/256.0;
1.290 float nearz = pvr2_scene.bounds[4];
1.291 float farz = pvr2_scene.bounds[5];
1.292 if( nearz == farz ) {
1.293 farz*= 4.0;
1.294 }
1.295 - glOrtho( 0, pvr2_scene.buffer_width, pvr2_scene.buffer_height, 0,
1.296 - -farz, -nearz );
1.297 - float alphaRef = ((float)(MMIO_READ(PVR2, RENDER_ALPHA_REF)&0xFF)+1)/256.0;
1.298 - glAlphaFunc( GL_GEQUAL, alphaRef );
1.299 +
1.300 + /* Generate integer clip boundaries */
1.301 + for( i=0; i<4; i++ ) {
1.302 + clip_bounds[i] = (uint32_t)pvr2_scene.bounds[i];
1.303 + }
1.304 +
1.305 + setOrtho(viewMatrix, pvr2_scene.buffer_width, pvr2_scene.buffer_height, -farz, -nearz);
1.306 +
1.307 + if( have_shaders ) {
1.308 + pvr2_scene_setup_shader(viewMatrix);
1.309 + } else {
1.310 + pvr2_scene_setup_fixed(viewMatrix);
1.311 + }
1.312 +
1.313
1.314 /* Clear the buffer (FIXME: May not want always want to do this) */
1.315 glDisable( GL_SCISSOR_TEST );
1.316 @@ -450,58 +550,85 @@
1.317 glStencilMask( 0x03 );
1.318 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
1.319
1.320 - /* Setup vertex array pointers */
1.321 - glVertexPointer(3, GL_FLOAT, sizeof(struct vertex_struct), &pvr2_scene.vertex_array[0].x);
1.322 - glColorPointer(4, GL_FLOAT, sizeof(struct vertex_struct), &pvr2_scene.vertex_array[0].rgba[0]);
1.323 - glTexCoordPointer(4, GL_FLOAT, sizeof(struct vertex_struct), &pvr2_scene.vertex_array[0].u);
1.324 - glSecondaryColorPointerEXT(3, GL_FLOAT, sizeof(struct vertex_struct), pvr2_scene.vertex_array[0].offset_rgba );
1.325 - glFogCoordPointerEXT(GL_FLOAT, sizeof(struct vertex_struct), &pvr2_scene.vertex_array[0].offset_rgba[3] );
1.326 - /* Turn on the shaders (if available) */
1.327 - glsl_use_pvr2_shader();
1.328 -
1.329 /* Render the background */
1.330 gl_render_bkgnd( pvr2_scene.bkgnd_poly );
1.331
1.332 glEnable( GL_SCISSOR_TEST );
1.333 - glEnable( GL_COLOR_SUM );
1.334 - glEnable( GL_FOG );
1.335 glEnable( GL_TEXTURE_2D );
1.336
1.337 - /* Process the segment list */
1.338 - struct tile_segment *segment = pvr2_scene.segment_list;
1.339 - do {
1.340 - int tilex = SEGMENT_X(segment->control);
1.341 - int tiley = SEGMENT_Y(segment->control);
1.342 + struct tile_segment *segment;
1.343
1.344 - uint32_t tile_bounds[4] = { tilex << 5, (tilex+1)<<5, tiley<<5, (tiley+1)<<5 };
1.345 - if( !clip_tile_bounds(tile_bounds, pvr2_scene.bounds) ) {
1.346 - continue; // fully clipped, skip tile
1.347 +#define FOREACH_SEGMENT(segment) \
1.348 + segment = pvr2_scene.segment_list; \
1.349 + do { \
1.350 + int tilex = SEGMENT_X(segment->control); \
1.351 + int tiley = SEGMENT_Y(segment->control); \
1.352 + \
1.353 + uint32_t tile_bounds[4] = { tilex << 5, (tilex+1)<<5, tiley<<5, (tiley+1)<<5 }; \
1.354 + if( !clip_tile_bounds(tile_bounds, clip_bounds) ) { \
1.355 + continue; \
1.356 }
1.357 +#define END_FOREACH_SEGMENT() \
1.358 + } while( !IS_LAST_SEGMENT(segment++) );
1.359 +#define CLIP_TO_SEGMENT() \
1.360 + glScissor( tile_bounds[0], pvr2_scene.buffer_height-tile_bounds[3], tile_bounds[1]-tile_bounds[0], tile_bounds[3] - tile_bounds[2] )
1.361
1.362 - /* Clip to the visible part of the tile */
1.363 - glScissor( tile_bounds[0], pvr2_scene.buffer_height-tile_bounds[3],
1.364 - tile_bounds[1]-tile_bounds[0], tile_bounds[3] - tile_bounds[2] );
1.365 - if( display_driver->capabilities.stencil_bits >= 2 &&
1.366 - IS_TILE_PTR(segment->opaquemod_ptr) &&
1.367 - !IS_EMPTY_TILE_LIST(segment->opaquemod_ptr) ) {
1.368 - /* Don't do this unless there's actually some shadow polygons */
1.369 + /* Build up the opaque stencil map */
1.370 + if( display_driver->capabilities.stencil_bits >= 2 ) {
1.371 + glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
1.372 + FOREACH_SEGMENT(segment)
1.373 + if( IS_NONEMPTY_TILE_LIST(segment->opaquemod_ptr) ) {
1.374 + CLIP_TO_SEGMENT();
1.375 + gl_render_tilelist_depthonly(segment->opaque_ptr);
1.376 + }
1.377 + END_FOREACH_SEGMENT()
1.378
1.379 - /* Use colormask instead of drawbuffer for simplicity */
1.380 - glColorMask( GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE );
1.381 - gl_render_tilelist_depthonly(segment->opaque_ptr);
1.382 - gl_render_modifier_tilelist(segment->opaquemod_ptr, tile_bounds);
1.383 - glClear( GL_DEPTH_BUFFER_BIT );
1.384 - glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
1.385 - }
1.386 + glEnable( GL_STENCIL_TEST );
1.387 + glStencilFunc( GL_ALWAYS, 0, 1 );
1.388 + glStencilOp( GL_KEEP,GL_INVERT, GL_KEEP );
1.389 + glStencilMask( 0x01 );
1.390 + glDepthFunc( GL_LEQUAL );
1.391 + glDepthMask( GL_FALSE );
1.392 + glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
1.393 + FOREACH_SEGMENT(segment)
1.394 + if( IS_NONEMPTY_TILE_LIST(segment->opaquemod_ptr) ) {
1.395 + CLIP_TO_SEGMENT();
1.396 + gl_render_modifier_tilelist(segment->opaquemod_ptr, tile_bounds);
1.397 + }
1.398 + END_FOREACH_SEGMENT()
1.399 + glDepthMask( GL_TRUE );
1.400 + glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
1.401 + glDisable( GL_SCISSOR_TEST );
1.402 + glClear( GL_DEPTH_BUFFER_BIT );
1.403 + glEnable( GL_SCISSOR_TEST );
1.404 + glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE );
1.405 + }
1.406 +
1.407 + /* Render the opaque polygons */
1.408 + FOREACH_SEGMENT(segment)
1.409 + CLIP_TO_SEGMENT();
1.410 gl_render_tilelist(segment->opaque_ptr,TRUE);
1.411 - if( IS_TILE_PTR(segment->punchout_ptr) ) {
1.412 - glEnable(GL_ALPHA_TEST );
1.413 - glDepthFunc(GL_GEQUAL);
1.414 - gl_render_tilelist(segment->punchout_ptr, FALSE );
1.415 - glDisable(GL_ALPHA_TEST );
1.416 - }
1.417 + END_FOREACH_SEGMENT()
1.418
1.419 - if( IS_TILE_PTR(segment->trans_ptr) ) {
1.420 + /* Render the punch-out polygons */
1.421 + if( have_shaders )
1.422 + pvr2_scene_set_alpha_shader(alphaRef);
1.423 + else
1.424 + pvr2_scene_set_alpha_fixed(alphaRef);
1.425 + glDepthFunc(GL_GEQUAL);
1.426 + FOREACH_SEGMENT(segment)
1.427 + CLIP_TO_SEGMENT();
1.428 + gl_render_tilelist(segment->punchout_ptr, FALSE );
1.429 + END_FOREACH_SEGMENT()
1.430 + if( have_shaders )
1.431 + pvr2_scene_set_alpha_shader(0.0);
1.432 + else
1.433 + pvr2_scene_set_alpha_fixed(0.0);
1.434 +
1.435 + /* Render the translucent polygons */
1.436 + FOREACH_SEGMENT(segment)
1.437 + if( IS_NONEMPTY_TILE_LIST(segment->trans_ptr) ) {
1.438 + CLIP_TO_SEGMENT();
1.439 if( pvr2_scene.sort_mode == SORT_NEVER ||
1.440 (pvr2_scene.sort_mode == SORT_TILEFLAG && (segment->control&SEGMENT_SORT_TRANS))) {
1.441 gl_render_tilelist(segment->trans_ptr, TRUE);
1.442 @@ -509,11 +636,15 @@
1.443 render_autosort_tile(segment->trans_ptr, RENDER_NORMAL );
1.444 }
1.445 }
1.446 - } while( !IS_LAST_SEGMENT(segment++) );
1.447 + END_FOREACH_SEGMENT()
1.448 +
1.449 glDisable( GL_SCISSOR_TEST );
1.450 - glDisable( GL_COLOR_SUM );
1.451 - glDisable( GL_FOG );
1.452 - glsl_clear_shader();
1.453 +
1.454 + if( have_shaders ) {
1.455 + pvr2_scene_cleanup_shader();
1.456 + } else {
1.457 + pvr2_scene_cleanup_fixed();
1.458 + }
1.459
1.460 pvr2_scene_finished();
1.461
2.1 --- a/src/pvr2/shaders.glsl Thu Feb 23 20:16:37 2012 +1000
2.2 +++ b/src/pvr2/shaders.glsl Thu Feb 23 22:20:15 2012 +1000
2.3 @@ -66,44 +66,67 @@
2.4
2.5
2.6 #vertex DEFAULT_VERTEX_SHADER
2.7 +uniform mat4 view_matrix;
2.8 +attribute vec4 in_vertex;
2.9 +attribute vec4 in_colour;
2.10 +attribute vec4 in_colour2; /* rgb = colour, a = fog */
2.11 +attribute vec4 in_texcoord; /* uv = coord, z = palette, w = mode */
2.12 +
2.13 +varying vec4 frag_colour;
2.14 +varying vec4 frag_colour2;
2.15 +varying vec4 frag_texcoord;
2.16 void main()
2.17 {
2.18 - vec4 tmp = ftransform();
2.19 - float w = gl_Vertex.z;
2.20 + vec4 tmp = view_matrix * in_vertex;
2.21 + float w = in_vertex.z;
2.22 gl_Position = tmp * w;
2.23 - gl_FrontColor = gl_Color;
2.24 - gl_FrontSecondaryColor = gl_SecondaryColor;
2.25 - gl_TexCoord[0] = gl_MultiTexCoord0;
2.26 - gl_FogFragCoord = gl_FogCoord;
2.27 + frag_colour = in_colour;
2.28 + frag_colour2 = in_colour2;
2.29 + frag_texcoord = in_texcoord;
2.30 }
2.31
2.32 #fragment DEFAULT_FRAGMENT_SHADER
2.33
2.34 +uniform float alpha_ref;
2.35 uniform sampler2D primary_texture;
2.36 uniform sampler2D palette_texture;
2.37 +uniform vec3 fog_colour1;
2.38 +uniform vec3 fog_colour2;
2.39 +varying vec4 frag_colour;
2.40 +varying vec4 frag_colour2;
2.41 +varying vec4 frag_texcoord;
2.42
2.43 void main()
2.44 {
2.45 - vec4 tex = texture2D( primary_texture, gl_TexCoord[0].xy );
2.46 - if( gl_TexCoord[0].z >= 0.0 ) {
2.47 - tex = texture2D( palette_texture, vec2(gl_TexCoord[0].z + (tex.a*0.249023),0.5) );
2.48 + vec4 tex = texture2D( primary_texture, frag_texcoord.xy );
2.49 + if( frag_texcoord.z >= 0.0 ) {
2.50 + tex = texture2D( palette_texture, vec2(frag_texcoord.z + (tex.a*0.249023), 0.5) );
2.51 }
2.52 /* HACK: unfortunately we have to maintain compatibility with GLSL 1.20,
2.53 * which only supports varying float. So since we're propagating texcoord
2.54 * anyway, overload the last component to indicate texture mode.
2.55 */
2.56 - if( gl_TexCoord[0].w == 0.0 ) {
2.57 - gl_FragColor.rgb = mix( gl_Color.rgb * tex.rgb + gl_SecondaryColor.rgb, gl_Fog.color.rgb, gl_FogFragCoord );
2.58 - gl_FragColor.a = gl_Color.a * tex.a;
2.59 - } else if( gl_TexCoord[0].w >= 1.5 ) {
2.60 - gl_FragColor.rgb = mix( gl_Color.rgb, gl_Fog.color.rgb, gl_FogFragCoord );
2.61 - gl_FragColor.a = gl_Color.a;
2.62 + vec3 main_colour;
2.63 + if( frag_texcoord.w == 0.0 ) {
2.64 + main_colour = frag_colour.rgb * tex.rgb + frag_colour2.rgb;
2.65 + gl_FragColor.a = frag_colour.a * tex.a;
2.66 + } else if( frag_texcoord.w >= 1.5 ) {
2.67 + main_colour = frag_colour.rgb;
2.68 + gl_FragColor.a = frag_colour.a;
2.69 } else {
2.70 - gl_FragColor.rgb = mix( mix(gl_Color.rgb,tex.rgb,tex.a) + gl_SecondaryColor.rgb, gl_Fog.color.rgb, gl_FogFragCoord);
2.71 - gl_FragColor.a = gl_Color.a;
2.72 + main_colour = mix(frag_colour.rgb,tex.rgb,tex.a) + frag_colour2.rgb;
2.73 + gl_FragColor.a = frag_colour.a;
2.74 }
2.75 - gl_FragDepth = gl_FragCoord.z;
2.76 + if( gl_FragColor.a < alpha_ref ) {
2.77 + discard;
2.78 + } else {
2.79 + if( frag_colour2.a >= 0.0 ) {
2.80 + gl_FragColor.rgb = mix( main_colour, fog_colour1, frag_colour2.a );
2.81 + } else {
2.82 + gl_FragColor.rgb = mix( main_colour, fog_colour2, -frag_colour2.a );
2.83 + }
2.84 + gl_FragDepth = gl_FragCoord.z;
2.85 + }
2.86 }
2.87
2.88 #program pvr2_shader = DEFAULT_VERTEX_SHADER DEFAULT_FRAGMENT_SHADER
2.89 -
.