revision 221:cf5c6d326162
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 221:cf5c6d326162 |
parent | 220:f72f8a7dff88 |
child | 222:541d9d899aba |
author | nkeynes |
date | Tue Sep 12 08:38:38 2006 +0000 (16 years ago) |
Bug #0010
Move polygon macros to pvr2.h
Implement background rendering more fully
Move polygon macros to pvr2.h
Implement background rendering more fully
![]() | src/pvr2/pvr2.h | view | annotate | diff | log | |
![]() | src/pvr2/rendbkg.c | view | annotate | diff | log | |
![]() | src/pvr2/rendcore.c | view | annotate | diff | log | |
![]() | src/pvr2/render.c | view | annotate | diff | log |
1.1 --- a/src/pvr2/pvr2.h Tue Sep 12 08:36:09 2006 +00001.2 +++ b/src/pvr2/pvr2.h Tue Sep 12 08:38:38 2006 +00001.3 @@ -1,5 +1,5 @@1.4 /**1.5 - * $Id: pvr2.h,v 1.16 2006-08-29 08:12:13 nkeynes Exp $1.6 + * $Id: pvr2.h,v 1.17 2006-09-12 08:38:38 nkeynes Exp $1.7 *1.8 * PVR2 (video chip) functions and macros.1.9 *1.10 @@ -202,3 +202,31 @@1.11 */1.12 GLuint texcache_get_texture( uint32_t texture_addr, int width, int height,1.13 int mode );1.14 +1.15 +/************************* Rendering support macros **************************/1.16 +#define POLY1_DEPTH_MODE(poly1) ( pvr2_poly_depthmode[(poly1)>>29] )1.17 +#define POLY1_DEPTH_ENABLE(poly1) (((poly1)&0x04000000) == 0 )1.18 +#define POLY1_CULL_MODE(poly1) (((poly1)>>27)&0x03)1.19 +#define POLY1_TEXTURED(poly1) (((poly1)&0x02000000))1.20 +#define POLY1_SPECULAR(poly1) (((poly1)&0x01000000))1.21 +#define POLY1_SHADE_MODEL(poly1) (((poly1)&0x00800000) ? GL_SMOOTH : GL_FLAT)1.22 +#define POLY1_UV16(poly1) (((poly1)&0x00400000))1.23 +#define POLY1_SINGLE_TILE(poly1) (((poly1)&0x00200000))1.24 +1.25 +#define POLY2_SRC_BLEND(poly2) ( pvr2_poly_srcblend[(poly2) >> 29] )1.26 +#define POLY2_DEST_BLEND(poly2) ( pvr2_poly_dstblend[((poly2)>>26)&0x07] )1.27 +#define POLY2_SRC_BLEND_ENABLE(poly2) ((poly2)&0x02000000)1.28 +#define POLY2_DEST_BLEND_ENABLE(poly2) ((poly2)&0x01000000)1.29 +#define POLY2_COLOUR_CLAMP_ENABLE(poly2) ((poly2)&0x00200000)1.30 +#define POLY2_ALPHA_ENABLE(poly2) ((poly2)&0x001000000)1.31 +#define POLY2_TEX_ALPHA_ENABLE(poly2) (((poly2)&0x00080000) == 0 )1.32 +#define POLY2_TEX_WIDTH(poly2) ( 1<< ((((poly2) >> 3) & 0x07 ) + 3) )1.33 +#define POLY2_TEX_HEIGHT(poly2) ( 1<< (((poly2) & 0x07 ) + 3) )1.34 +#define POLY2_TEX_BLEND(poly2) ( pvr2_poly_texblend[((poly2) >> 6)&0x03] )1.35 +extern int pvr2_poly_depthmode[8];1.36 +extern int pvr2_poly_srcblend[8];1.37 +extern int pvr2_poly_dstblend[8];1.38 +extern int pvr2_poly_texblend[4];1.39 +extern int pvr2_render_colour_format[8];1.40 +1.41 +float halftofloat(uint16_t half);
2.1 --- a/src/pvr2/rendbkg.c Tue Sep 12 08:36:09 2006 +00002.2 +++ b/src/pvr2/rendbkg.c Tue Sep 12 08:38:38 2006 +00002.3 @@ -1,11 +1,15 @@2.4 /**2.5 - * $Id: rendbkg.c,v 1.1 2006-08-29 08:12:13 nkeynes Exp $2.6 + * $Id: rendbkg.c,v 1.2 2006-09-12 08:38:38 nkeynes Exp $2.7 *2.8 * PVR2 background renderer.2.9 *2.10 * Yes, it uses the same basic data structure. Yes, it needs to be handled2.11 * completely differently.2.12 *2.13 + * Note: this would be really simple if GL did unclamped colour interpolation2.14 + * but it doesn't (portably), which makes this roughly 2 orders of magnitude2.15 + * more complicated than it otherwise would be.2.16 + *2.17 * Copyright (c) 2005 Nathan Keynes.2.18 *2.19 * This program is free software; you can redistribute it and/or modify2.20 @@ -21,12 +25,16 @@2.22 #include <sys/time.h>2.23 #include "pvr2/pvr2.h"2.24 +#include <GL/glext.h>2.25 +#include <math.h>2.27 -struct vertex_rgba {2.28 - float x,y,z;2.29 - uint32_t argb;2.30 -};2.31 +#define MAX_CLAMP_LINES 82.32 +#define MAX_VERTEXES 2562.33 +#define MAX_REGIONS 2562.35 +/**2.36 + * Structure to hold an unpacked vertex2.37 + */2.38 struct vertex_all {2.39 float x,y,z;2.40 float u,v;2.41 @@ -40,6 +48,398 @@2.42 #define FARGB_B(x) (((float)(((x)&0xFF)+1))/256.0)2.44 /**2.45 + * Compute the line where k = target_k, (where k is normally one of2.46 + * r,g,b,a, or z) and determines the points at which the line intersects2.47 + * the viewport (0,0,width,height).2.48 + *2.49 + * @param center_x the x value for the center position2.50 + * @param center_y the y value for the center position2.51 + * @param center_k the k value for the center position2.52 + * @param width Width of the viewport (ie 640)2.53 + * @param height Height of the viewport (ie 480)2.54 + * @param target_k determine the line where k = this value, ie 1.02.55 + * @param detxy2.56 + * @param target Array to write the resultant x,y pairs to (note this2.57 + * function only sets x and y values).2.58 + * @return number of vertexes written to the target.2.59 + */2.60 +static int compute_colour_line( float center_x, float center_y, float center_k,2.61 + int width, int height, float target_k,2.62 + float detxy, float detxk, float detyk,2.63 + struct vertex_all *target ) {2.64 + int num_points = 0;2.65 + float tmpk = (target_k - center_k) * detxy;2.66 + float x0 = -1;2.67 + float x1 = -1;2.68 +2.69 + if( detyk != 0 ) {2.70 + x0 = (tmpk - ((0-center_y)*detxk))/detyk + center_x; /* x where y=0 */2.71 + if( x0 >= 0.0 && x0 <= width ) {2.72 + target[num_points].x = x0;2.73 + target[num_points].y = 0.0;2.74 + num_points++;2.75 + }2.76 +2.77 + x1 = (tmpk - ((height-center_y)*detxk))/detyk + center_x; /* x where y=height */2.78 + if( x1 >= 0.0 && x1 <= width ) {2.79 + target[num_points].x = x1;2.80 + target[num_points].y = height;2.81 + num_points++;2.82 + }2.83 + }2.84 +2.85 + if( detxk != 0 ) {2.86 + if( x0 != 0.0 && x1 != 0.0 ) { /* If x0 == 0 or x1 == 0, then we already have this one */2.87 + float y0 = (tmpk - ((0-center_x)*detyk))/detxk + center_y; /* y where x=0 */2.88 + if( y0 >= 0.0 && y0 <= height ) {2.89 + target[num_points].x = 0.0;2.90 + target[num_points].y = y0;2.91 + num_points++;2.92 + }2.93 + }2.94 +2.95 + if( x0 != width && x1 != width ) {2.96 + float y1 = (tmpk - ((width-center_x)*detyk))/detxk + center_y; /* y where x=width */2.97 + if( y1 >= 0.0 && y1 <= height ) {2.98 + target[num_points].x = width;2.99 + target[num_points].y = y1;2.100 + num_points++;2.101 + }2.102 + }2.103 + }2.104 +2.105 + if( num_points == 0 || num_points == 2 ) {2.106 + /* 0 = no points - line doesn't pass through the viewport */2.107 + /* 2 = normal case - got 2 endpoints */2.108 + return num_points;2.109 + } else {2.110 + ERROR( "compute_colour_line got bad number of points: %d", num_points );2.111 + return 0;2.112 + }2.113 +}2.114 +2.115 +/**2.116 + * A region describes a portion of the screen, possibly subdivided by a line.2.117 + * if region_left and region_right are -1, this is a terminal region that can2.118 + * be rendered directly. Otherwise region_left and region_right refer two2.119 + * sub-regions that are separated by the line segment vertex1-vertex2.2.120 + */2.121 +struct bkg_region {2.122 + /* Vertexes marking the line segment that splits this region */2.123 + int vertex1;2.124 + int vertex2;2.125 + /* Index of the left sub-region */2.126 + int region_left;2.127 + /* Index of the right sub-region */2.128 + int region_right;2.129 +};2.130 +2.131 +/**2.132 + * Convenience structure to bundle together the vertex and region data.2.133 + */2.134 +struct bkg_scene {2.135 + int num_vertexes;2.136 + int num_regions;2.137 + struct vertex_all vertexes[MAX_VERTEXES];2.138 + struct bkg_region regions[MAX_REGIONS];2.139 +};2.140 +2.141 +void parse_vertexes( uint32_t *polygon, int num_vertexes, struct vertex_all *result )2.142 +{2.143 + uint32_t *vertexes = polygon + 3;2.144 + int i,m = 0;2.145 + for( i=0; i<num_vertexes; i++ ) {2.146 + float *vertexf = (float *)vertexes;2.147 + result[i].x = vertexf[0];2.148 + result[i].y = vertexf[1];2.149 + result[i].z = vertexf[2];2.150 + uint32_t argb;2.151 + if( POLY1_TEXTURED(*polygon) ) {2.152 + if( POLY1_UV16(*polygon) ) {2.153 + result[i].u = halftofloat(vertexes[m+3]>>16);2.154 + result[i].v = halftofloat(vertexes[m+3]);2.155 + argb = vertexes[m+4];2.156 + vertexes += 5;2.157 + } else {2.158 + result[i].u = vertexf[m+3];2.159 + result[i].v = vertexf[m+4];2.160 + argb = vertexes[m+5];2.161 + vertexes += 6;2.162 + }2.163 + } else {2.164 + argb = vertexes[m+3];2.165 + vertexes += 4;2.166 + }2.167 + result[i].rgba[0] = FARGB_R(argb);2.168 + result[i].rgba[1] = FARGB_G(argb);2.169 + result[i].rgba[2] = FARGB_B(argb);2.170 + result[i].rgba[3] = FARGB_A(argb);2.171 + }2.172 +2.173 +}2.174 +2.175 +/**2.176 + * Constants returned by compute_line_intersection. Note that for these purposes,2.177 + * "Left" means the point(s) result in a negative value in the line equation, while2.178 + * "Right" means the points(s) result in a positive value in the line equation. The2.179 + * exact meaning isn't particularly important though, as long as we're consistent2.180 + * throughout this process2.181 + */2.182 +#define LINE_COLLINEAR 0 /* The line segments are part of the same line */2.183 +#define LINE_SIDE_LEFT 1 /* The second line is entirely to the "left" of the first line */2.184 +#define LINE_SIDE_RIGHT 2 /* The second line is entirely to the "right" of the first line */2.185 +#define LINE_INTERSECT_FROM_LEFT 3 /* The lines intersect, and (x3,y3) is to the "left" of the first line */2.186 +#define LINE_INTERSECT_FROM_RIGHT 4 /* The lines intersect, and (x3,y3) is to the "right" of the first line */2.187 +#define LINE_SKEW 5 /* The line segments neither intersect nor do any of the above apply (should never happen here) */2.188 +2.189 +/**2.190 + * Compute the intersection of two line segments, where2.191 + * (x1,y1)-(x2,y2) defines the target segment, and2.192 + * (x3,y3)-(x4,y4) defines the line intersecting it.2.193 + *2.194 + * Based off work by Mukesh Prasad (http://www.acm.org/pubs/tog/GraphicsGems/index.html)2.195 + *2.196 + * @return one of the above LINE_* constants2.197 + */2.198 +static int compute_line_intersection( float x1, float y1, /* First line segment */2.199 + float x2, float y2,2.200 + float x3, float y3, /* Second line segment */2.201 + float x4, float y4,2.202 + float *x, float *y ) /* Output value: */2.203 +{2.204 + float a1, a2, b1, b2, c1, c2; /* Coefficients of line eqns. */2.205 + float r1, r2, r3, r4; /* test values */2.206 + float denom; /* Intermediate values */2.207 +2.208 + /* Compute a1, b1, c1, where line joining points 1 and 22.209 + * is "a1 x + b1 y + c1 = 0".2.210 + */2.211 +2.212 + a1 = y2 - y1;2.213 + b1 = x1 - x2;2.214 + c1 = x2 * y1 - x1 * y2;2.215 +2.216 + /* Compute r3 and r4. */2.217 +2.218 + r3 = a1 * x3 + b1 * y3 + c1;2.219 + r4 = a1 * x4 + b1 * y4 + c1;2.220 +2.221 + /* Check signs of r3 and r4. If both point 3 and point 4 lie on2.222 + * same side of line 1, the line segments do not intersect.2.223 + */2.224 +2.225 + if( r3 == 0 && r4 == 0 ) {2.226 + return LINE_COLLINEAR;2.227 + } else if( r3 <= 0 && r4 <= 0 ) {2.228 + return LINE_SIDE_LEFT;2.229 + } else if( r3 >= 0 && r4 >= 0 ) {2.230 + return LINE_SIDE_RIGHT;2.231 + }2.232 +2.233 + /* Compute a2, b2, c2 */2.234 +2.235 + a2 = y4 - y3;2.236 + b2 = x3 - x4;2.237 + c2 = x4 * y3 - x3 * y4;2.238 +2.239 + /* Compute r1 and r2 */2.240 +2.241 + r1 = a2 * x1 + b2 * y1 + c2;2.242 + r2 = a2 * x2 + b2 * y2 + c2;2.243 +2.244 + /* Check signs of r1 and r2. If both point 1 and point 2 lie2.245 + * on same side of second line segment, the line segments do2.246 + * not intersect.2.247 + */2.248 +2.249 + if ( r1 != 0 && r2 != 0 &&2.250 + signbit(r1) == signbit(r2) ) {2.251 + return LINE_SKEW; /* Should never happen */2.252 + }2.253 +2.254 + /* Cmpute intersection point.2.255 + */2.256 + denom = a1 * b2 - a2 * b1;2.257 + if ( denom == 0 )2.258 + return LINE_COLLINEAR; /* Should never get to this point either */2.259 +2.260 + *x = (b1 * c2 - b2 * c1) / denom;2.261 + *y = (a2 * c1 - a1 * c2) / denom;2.262 +2.263 + if( r3 <= 0 && r4 >= 0 ) {2.264 + return LINE_INTERSECT_FROM_LEFT;2.265 + } else {2.266 + return LINE_INTERSECT_FROM_RIGHT;2.267 + }2.268 +}2.269 +2.270 +/**2.271 + * Given a set of vertexes and a line segment to use to split them, generates2.272 + * two sets of vertexes representing the polygon on either side of the line2.273 + * segment. This method preserves the winding direction of the input vertexes.2.274 + */2.275 +static void compute_subregions( struct bkg_scene *scene,2.276 + int splitv1, int splitv2,2.277 + int *vertex_in, int num_vertex_in,2.278 + int *left_vertex_out, int *num_left_vertex_out,2.279 + int *right_vertex_out, int *num_right_vertex_out )2.280 +{2.281 + float x1 = scene->vertexes[splitv1].x;2.282 + float y1 = scene->vertexes[splitv1].y;2.283 + float x2 = scene->vertexes[splitv2].x;2.284 + float y2 = scene->vertexes[splitv2].y;2.285 +2.286 + float a1 = y2 - y1;2.287 + float b1 = x1 - x2;2.288 + float c1 = x2 * y1 - x1 * y2;2.289 + int i;2.290 +2.291 + *num_left_vertex_out = 0;2.292 + *num_right_vertex_out = 0;2.293 + int last = 0;2.294 + for( i=0; i<num_vertex_in; i++ ) {2.295 + struct vertex_all *vertex = &scene->vertexes[vertex_in[i]];2.296 + float r = a1 * vertex->x + b1 * vertex->y + c1;2.297 + if( r <= 0 ) {2.298 + if( last == 1 ) {2.299 + /* cross-point. add the split vertexes */2.300 + int v1 = vertex_in[i-1];2.301 + int v2 = vertex_in[i];2.302 + /* Determine which point is closer to the line. Strictly speaking2.303 + * one of them must be ON the line, but this way allows for floating2.304 + * point inaccuracies.2.305 + */2.306 + float a2 = scene->vertexes[v2].y - scene->vertexes[v1].y;2.307 + float b2 = scene->vertexes[v1].x - scene->vertexes[v2].x;2.308 + float c2 = scene->vertexes[v2].x * scene->vertexes[v1].y -2.309 + scene->vertexes[v1].x * scene->vertexes[v2].y;2.310 + float r1 = a2 * x1 + b2 * y1 + c2;2.311 + float r2 = a2 * x2 + b2 * y2 + c2;2.312 + if( fabsf(r1) > fabs(r2) ) {2.313 + int tmp = splitv1;2.314 + splitv1 = splitv2;2.315 + splitv2 = tmp;2.316 + }2.317 + right_vertex_out[(*num_right_vertex_out)++] = splitv1;2.318 + right_vertex_out[(*num_right_vertex_out)++] = splitv2;2.319 + left_vertex_out[(*num_left_vertex_out)++] = splitv2;2.320 + left_vertex_out[(*num_left_vertex_out)++] = splitv1;2.321 + last = 2;2.322 + } else if( last != 2 ) {2.323 + last = -1;2.324 + }2.325 + left_vertex_out[(*num_left_vertex_out)++] = vertex_in[i];2.326 + } else {2.327 + if( last == -1 ) {2.328 + /* cross-point. add the split vertexes */2.329 + int v1 = vertex_in[i-1];2.330 + int v2 = vertex_in[i];2.331 + /* Determine which point is closer to the line. Strictly speaking2.332 + * one of them must be ON the line, but this way allows for floating2.333 + * point inaccuracies.2.334 + */2.335 + float a2 = scene->vertexes[v2].y - scene->vertexes[v1].y;2.336 + float b2 = scene->vertexes[v1].x - scene->vertexes[v2].x;2.337 + float c2 = scene->vertexes[v2].x * scene->vertexes[v1].y -2.338 + scene->vertexes[v1].x * scene->vertexes[v2].y;2.339 + float r1 = a2 * x1 + b2 * y1 + c2;2.340 + float r2 = a2 * x2 + b2 * y2 + c2;2.341 + if( fabsf(r1) > fabs(r2) ) {2.342 + int tmp = splitv1;2.343 + splitv1 = splitv2;2.344 + splitv2 = tmp;2.345 + }2.346 + left_vertex_out[(*num_left_vertex_out)++] = splitv1;2.347 + left_vertex_out[(*num_left_vertex_out)++] = splitv2;2.348 + right_vertex_out[(*num_right_vertex_out)++] = splitv2;2.349 + right_vertex_out[(*num_right_vertex_out)++] = splitv1;2.350 + last = 2;2.351 + } else if( last != 2 ) {2.352 + last = 1;2.353 + }2.354 + right_vertex_out[(*num_right_vertex_out)++] = vertex_in[i];2.355 + }2.356 + }2.357 +}2.358 +2.359 +/**2.360 + * Subdivide the region tree by splitting it along a given line.2.361 + *2.362 + * @param scene current bkg scene data2.363 + * @param region current region under examination2.364 + * @param vertex1 first vertex of the new line segment2.365 + * @param vertex2 second vertex of the new line segment2.366 + */2.367 +static void bkg_region_subdivide( struct bkg_scene *scene, int region, int vertex1, int vertex2 ) {2.368 + struct bkg_region *this_region = &scene->regions[region];2.369 +2.370 + if( scene->regions[region].region_left == -1 || scene->regions[region].region_right == -1 ) {2.371 + /* Reached the end of the tree. Setup new left+right regions */2.372 + int i = scene->num_regions;2.373 + scene->regions[i].region_left = scene->regions[i].region_right = -1;2.374 + scene->regions[i+1].region_left = scene->regions[i+1].region_right = -1;2.375 + this_region->region_left = i;2.376 + this_region->region_right = i+1;2.377 + this_region->vertex1 = vertex1;2.378 + this_region->vertex2 = vertex2;2.379 + scene->num_regions += 2;2.380 + } else {2.381 + float x,y;2.382 + int thisv1 = this_region->vertex1;2.383 + int thisv2 = this_region->vertex2;2.384 + int vertex3;2.385 + int status =2.386 + compute_line_intersection( scene->vertexes[thisv1].x, scene->vertexes[thisv1].y,2.387 + scene->vertexes[thisv2].x, scene->vertexes[thisv2].y,2.388 + scene->vertexes[vertex1].x, scene->vertexes[vertex1].y,2.389 + scene->vertexes[vertex2].x, scene->vertexes[vertex2].y,2.390 + &x, &y );2.391 + switch( status ) {2.392 + case LINE_INTERSECT_FROM_LEFT:2.393 + /* if new line segment intersects our current line segment,2.394 + * subdivide the segment (add a new vertex) and recurse on both2.395 + * sub trees2.396 + */2.397 + /* Compute split-point vertex */2.398 + vertex3 = scene->num_vertexes++;2.399 + scene->vertexes[vertex3].x = x;2.400 + scene->vertexes[vertex3].y = y;2.401 + /* Recurse */2.402 + bkg_region_subdivide( scene, scene->regions[region].region_left, vertex1,vertex3 );2.403 + bkg_region_subdivide( scene, scene->regions[region].region_right, vertex3, vertex2 );2.404 + break;2.405 + case LINE_INTERSECT_FROM_RIGHT:2.406 + /* Same except line runs in the opposite direction */2.407 + vertex3 = scene->num_vertexes++;2.408 + scene->vertexes[vertex3].x = x;2.409 + scene->vertexes[vertex3].y = y;2.410 + /* Recurse */2.411 + bkg_region_subdivide( scene, scene->regions[region].region_left, vertex2,vertex3 );2.412 + bkg_region_subdivide( scene, scene->regions[region].region_right, vertex3, vertex1 );2.413 + break;2.414 + case LINE_COLLINEAR:2.415 + case LINE_SKEW:2.416 + /* Collinear - ignore */2.417 + break;2.418 + case LINE_SIDE_LEFT:2.419 + /* else if line segment passes through the left sub-region alone,2.420 + * left-recurse only.2.421 + */2.422 + bkg_region_subdivide( scene, scene->regions[region].region_left, vertex1, vertex2 );2.423 + break;2.424 + case LINE_SIDE_RIGHT:2.425 + /* Otherwise line segment passes through the right sub-region alone,2.426 + * so right-recurse.2.427 + */2.428 + bkg_region_subdivide( scene, scene->regions[region].region_right, vertex1, vertex2 );2.429 + break;2.430 + }2.431 + }2.432 +}2.433 +2.434 +2.435 +2.436 +/**2.437 * Compute the values for an array of vertexes, given x,y for each2.438 * vertex and the base 3-vertex triple used to define the background2.439 * plane. Essentially the base vertexes are used to find the2.440 @@ -49,69 +449,183 @@2.441 * @param base The 3 vertexes supplied as the background definition2.442 * @param compute An array of vertexes to compute. x and y must be2.443 * preset, other values are computed.2.444 - * @param num_compute number of vertexes in the compute array.2.445 */2.446 -void compute_vertexes( struct vertex_rgba *base,2.447 - struct vertex_all *compute,2.448 - int num_compute )2.449 +static void bkg_compute_scene( struct vertex_all *base, int width, int height,2.450 + struct bkg_scene *scene )2.451 {2.452 struct vertex_all center;2.453 struct vertex_all diff0, diff1;2.454 - int i;2.455 + int i,k;2.457 center.x = base[1].x;2.458 center.y = base[1].y;2.459 center.z = base[1].z;2.460 - center.rgba[0] = FARGB_R(base[1].argb);2.461 - center.rgba[1] = FARGB_G(base[1].argb);2.462 - center.rgba[2] = FARGB_B(base[1].argb);2.463 - center.rgba[3] = FARGB_A(base[1].argb);2.464 diff0.x = base[0].x - base[1].x;2.465 diff0.y = base[0].y - base[1].y;2.466 diff0.z = base[0].z - base[1].z;2.467 diff1.x = base[2].x - base[1].x;2.468 diff1.y = base[2].y - base[1].y;2.469 diff1.z = base[2].z - base[1].z;2.470 - diff0.rgba[0] = FARGB_R(base[0].argb) - center.rgba[0];2.471 - diff0.rgba[1] = FARGB_G(base[0].argb) - center.rgba[1];2.472 - diff0.rgba[2] = FARGB_B(base[0].argb) - center.rgba[2];2.473 - diff0.rgba[3] = FARGB_A(base[0].argb) - center.rgba[3];2.474 - diff1.rgba[0] = FARGB_R(base[2].argb) - center.rgba[0];2.475 - diff1.rgba[1] = FARGB_G(base[2].argb) - center.rgba[1];2.476 - diff1.rgba[2] = FARGB_B(base[2].argb) - center.rgba[2];2.477 - diff1.rgba[3] = FARGB_A(base[2].argb) - center.rgba[3];2.479 - float divisor = ((diff1.y) * (diff0.x)) - ((diff0.y) * (diff1.x));2.480 - if( divisor == 0 ) {2.481 - /* The points lie on a single line - no plane for you. *shrugs* */2.482 + float detxy = ((diff1.y) * (diff0.x)) - ((diff0.y) * (diff1.x));2.483 +2.484 + /* Corner points first */2.485 + scene->vertexes[0].x = 0.0;2.486 + scene->vertexes[0].y = 0.0;2.487 + scene->vertexes[1].x = width;2.488 + scene->vertexes[1].y = 0.0;2.489 + scene->vertexes[2].x = width;2.490 + scene->vertexes[2].y = height;2.491 + scene->vertexes[3].x = 0.0;2.492 + scene->vertexes[3].y = height;2.493 + scene->regions[0].region_left = -1;2.494 + scene->regions[0].region_right = -1;2.495 + scene->num_vertexes = 4;2.496 + scene->num_regions = 1;2.497 +2.498 + if( detxy == 0 ) {2.499 + /* The points lie on a single line - no plane for you. Use the values2.500 + * from the 3rd point for the whole screen.2.501 + */2.502 + for( i=0; i<4; i++ ) {2.503 + scene->vertexes[i].rgba[0] = base[2].rgba[0];2.504 + scene->vertexes[i].rgba[1] = base[2].rgba[1];2.505 + scene->vertexes[i].rgba[2] = base[2].rgba[2];2.506 + scene->vertexes[i].rgba[3] = base[2].rgba[3];2.507 + scene->vertexes[i].u = base[2].u;2.508 + scene->vertexes[i].v = base[2].v;2.509 + }2.510 } else {2.511 - for( i=0; i<num_compute; i++ ) {2.512 - float t = ((compute[i].x - center.x) * diff1.y -2.513 - (compute[i].y - center.y) * diff1.x) / divisor;2.514 - float s = ((compute[i].y - center.y) * diff0.x -2.515 - (compute[i].x - center.x) * diff0.y) / divisor;2.516 - compute[i].z = center.z + (t*diff0.z) + (s*diff1.z);2.517 - compute[i].rgba[0] = center.rgba[0] + (t*diff0.rgba[0]) + (s*diff1.rgba[0]);2.518 - compute[i].rgba[1] = center.rgba[1] + (t*diff0.rgba[1]) + (s*diff1.rgba[1]);2.519 - compute[i].rgba[2] = center.rgba[2] + (t*diff0.rgba[2]) + (s*diff1.rgba[2]);2.520 - compute[i].rgba[3] = center.rgba[3] + (t*diff0.rgba[3]) + (s*diff1.rgba[3]);2.521 + /* Compute the colour values at each corner */2.522 + center.rgba[0] = base[1].rgba[0];2.523 + center.rgba[1] = base[1].rgba[1];2.524 + center.rgba[2] = base[1].rgba[2];2.525 + center.rgba[3] = base[1].rgba[3];2.526 + diff0.rgba[0] = base[0].rgba[0] - center.rgba[0];2.527 + diff0.rgba[1] = base[0].rgba[1] - center.rgba[1];2.528 + diff0.rgba[2] = base[0].rgba[2] - center.rgba[2];2.529 + diff0.rgba[3] = base[0].rgba[3] - center.rgba[3];2.530 + diff0.u = base[0].u - center.u;2.531 + diff0.v = base[0].v - center.v;2.532 + diff1.rgba[0] = base[2].rgba[0] - center.rgba[0];2.533 + diff1.rgba[1] = base[2].rgba[1] - center.rgba[1];2.534 + diff1.rgba[2] = base[2].rgba[2] - center.rgba[2];2.535 + diff1.rgba[3] = base[2].rgba[3] - center.rgba[3];2.536 + diff1.u = base[2].u - center.u;2.537 + diff1.v = base[2].v - center.v;2.538 + for( i=0; i<4; i++ ) {2.539 + float t = ((scene->vertexes[i].x - center.x) * diff1.y -2.540 + (scene->vertexes[i].y - center.y) * diff1.x) / detxy;2.541 + float s = ((scene->vertexes[i].y - center.y) * diff0.x -2.542 + (scene->vertexes[i].x - center.x) * diff0.y) / detxy;2.543 + scene->vertexes[i].z = center.z + (t*diff0.z) + (s*diff1.z);2.544 + scene->vertexes[i].rgba[0] = center.rgba[0] + (t*diff0.rgba[0]) + (s*diff1.rgba[0]);2.545 + scene->vertexes[i].rgba[1] = center.rgba[1] + (t*diff0.rgba[1]) + (s*diff1.rgba[1]);2.546 + scene->vertexes[i].rgba[2] = center.rgba[2] + (t*diff0.rgba[2]) + (s*diff1.rgba[2]);2.547 + scene->vertexes[i].rgba[3] = center.rgba[3] + (t*diff0.rgba[3]) + (s*diff1.rgba[3]);2.548 + scene->vertexes[i].u = center.u + (t*diff0.u) + (s*diff1.u);2.549 + scene->vertexes[i].v = center.v + (t*diff0.v) + (s*diff1.v);2.550 + }2.551 +2.552 + /* Check for values > 1.0 | < 0.0 */2.553 + for( k=0; k<4; k++ ) {2.554 + float detyk = ((diff1.y) * (diff0.rgba[k])) - ((diff0.y)*(diff1.rgba[k]));2.555 + float detxk = ((diff0.x) * (diff1.rgba[k])) - ((diff1.x)*(diff0.rgba[k]));2.556 + if( scene->vertexes[0].rgba[k] > 1.0 || scene->vertexes[1].rgba[k] > 1.0 ||2.557 + scene->vertexes[2].rgba[k] > 1.0 || scene->vertexes[3].rgba[k] > 1.0 ) {2.558 + int v1 = scene->num_vertexes;2.559 + scene->num_vertexes += compute_colour_line(center.x, center.y, center.rgba[k],2.560 + width, height, 1.0,2.561 + detxy, detxk, detyk,2.562 + scene->vertexes+scene->num_vertexes );2.563 + if( scene->num_vertexes != v1 ) {2.564 + bkg_region_subdivide( scene, 0, v1, v1+1 );2.565 + }2.566 + }2.567 +2.568 + if( scene->vertexes[0].rgba[k] < 0.0 || scene->vertexes[1].rgba[k] < 0.0 ||2.569 + scene->vertexes[2].rgba[k] < 0.0 || scene->vertexes[3].rgba[k] < 0.0 ) {2.570 + int v1 = scene->num_vertexes;2.571 + scene->num_vertexes += compute_colour_line(center.x, center.y, center.rgba[k],2.572 + width, height, 0.0,2.573 + detxy, detxk, detyk,2.574 + scene->vertexes+scene->num_vertexes );2.575 + if( scene->num_vertexes != v1 ) {2.576 + bkg_region_subdivide( scene, 0, v1, v1+1 );2.577 + }2.578 +2.579 + }2.580 + }2.581 +2.582 + /* Finally compute the colour values for all vertexes2.583 + * (excluding the 4 we did upfront) */2.584 + for( i=4; i<scene->num_vertexes; i++ ) {2.585 + float t = ((scene->vertexes[i].x - center.x) * diff1.y -2.586 + (scene->vertexes[i].y - center.y) * diff1.x) / detxy;2.587 + float s = ((scene->vertexes[i].y - center.y) * diff0.x -2.588 + (scene->vertexes[i].x - center.x) * diff0.y) / detxy;2.589 + scene->vertexes[i].z = center.z + (t*diff0.z) + (s*diff1.z);2.590 + scene->vertexes[i].rgba[0] = center.rgba[0] + (t*diff0.rgba[0]) + (s*diff1.rgba[0]);2.591 + scene->vertexes[i].rgba[1] = center.rgba[1] + (t*diff0.rgba[1]) + (s*diff1.rgba[1]);2.592 + scene->vertexes[i].rgba[2] = center.rgba[2] + (t*diff0.rgba[2]) + (s*diff1.rgba[2]);2.593 + scene->vertexes[i].rgba[3] = center.rgba[3] + (t*diff0.rgba[3]) + (s*diff1.rgba[3]);2.594 + scene->vertexes[i].u = center.u + (t*diff0.u) + (s*diff1.u);2.595 + scene->vertexes[i].v = center.v + (t*diff0.v) + (s*diff1.v);2.596 }2.597 }2.598 }2.600 +/**2.601 + * Render a bkg_region.2.602 + * @param scene the background scene data2.603 + * @param region the region to render2.604 + * @param vertexes the vertexes surrounding the region2.605 + * @param num_vertexes the number of vertexes in the vertex array2.606 + */2.607 +void bkg_render_region( struct bkg_scene *scene, int region, int *vertexes, int num_vertexes,2.608 + uint32_t poly1 )2.609 +{2.610 + if( scene->regions[region].region_left == -1 && scene->regions[region].region_right == -1 ) {2.611 + /* Leaf node - render the points as given */2.612 + int i,k;2.613 + glBegin(GL_POLYGON);2.614 + for( i=0; i<num_vertexes; i++ ) {2.615 + k = vertexes[i];2.616 + glColor4fv(scene->vertexes[k].rgba);2.617 + if( POLY1_TEXTURED(poly1) ) {2.618 + glTexCoord2f(scene->vertexes[k].u, scene->vertexes[k].v);2.619 + }2.620 + glVertex3f(scene->vertexes[k].x, scene->vertexes[k].y, scene->vertexes[k].z);2.621 + }2.622 + glEnd();2.623 + } else {2.624 + /* split the region into left and right regions */2.625 + int left_vertexes[num_vertexes+1];2.626 + int right_vertexes[num_vertexes+1];2.627 + int num_left = 0;2.628 + int num_right = 0;2.629 + struct bkg_region *reg = &scene->regions[region];2.630 + compute_subregions( scene, reg->vertex1, reg->vertex2, vertexes, num_vertexes,2.631 + left_vertexes, &num_left, right_vertexes, &num_right );2.632 + bkg_render_region( scene, reg->region_left, left_vertexes, num_left, poly1 );2.633 + bkg_render_region( scene, reg->region_right, right_vertexes, num_right, poly1 );2.634 + }2.635 +2.636 +}2.637 +2.638 +2.639 void render_backplane( uint32_t *polygon, uint32_t width, uint32_t height, uint32_t mode ) {2.640 - struct vertex_rgba *vertex = (struct vertex_rgba *)(polygon + 3);2.641 - struct vertex_all compute[4] = { {0.0,0.0}, {width,0.0}, {width, height}, {0.0,height} };2.642 - int i;2.643 + struct vertex_all vertex[3];2.644 + int screen_vertexes[4] = {0,1,2,3};2.645 + struct bkg_scene scene;2.646 + int i,j,k, num_vertexes;2.648 + parse_vertexes(polygon, 3, vertex);2.649 render_set_context(polygon, 0);2.650 - compute_vertexes( vertex, compute, 4 );2.651 - glBegin(GL_QUADS);2.652 - for( i=0; i<4; i++ ) {2.653 - glColor4fv(compute[i].rgba);2.654 - glVertex3f(compute[i].x, compute[i].y, compute[i].z);2.655 - fprintf( stderr, "BG %d,%d: %f %f %f\n", (int)compute[i].x, (int)compute[i].y,2.656 - compute[i].rgba[0], compute[i].rgba[1], compute[i].rgba[2] );2.657 - }2.658 - glEnd();2.659 + glDisable(GL_CULL_FACE);2.660 + glDisable(GL_DEPTH_TEST);2.661 + glBlendFunc(GL_ONE, GL_ZERO); /* For now, just disable alpha blending on the bkg */2.662 + fwrite_dump32( polygon, 48, stderr );2.663 + bkg_compute_scene(vertex, width, height, &scene);2.664 + bkg_render_region(&scene, 0, screen_vertexes, 4, *polygon);2.665 }
3.1 --- a/src/pvr2/rendcore.c Tue Sep 12 08:36:09 2006 +00003.2 +++ b/src/pvr2/rendcore.c Tue Sep 12 08:38:38 2006 +00003.3 @@ -1,5 +1,5 @@3.4 /**3.5 - * $Id: rendcore.c,v 1.3 2006-08-18 12:43:24 nkeynes Exp $3.6 + * $Id: rendcore.c,v 1.4 2006-09-12 08:38:38 nkeynes Exp $3.7 *3.8 * PVR2 renderer core.3.9 *3.10 @@ -19,41 +19,23 @@3.11 #include "pvr2/pvr2.h"3.12 #include "asic.h"3.14 -static int pvr2_poly_depthmode[8] = { GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL,3.15 +int pvr2_poly_depthmode[8] = { GL_NEVER, GL_LESS, GL_EQUAL, GL_LEQUAL,3.16 GL_GREATER, GL_NOTEQUAL, GL_GEQUAL,3.17 GL_ALWAYS };3.18 -static int pvr2_poly_srcblend[8] = {3.19 +int pvr2_poly_srcblend[8] = {3.20 GL_ZERO, GL_ONE, GL_DST_COLOR, GL_ONE_MINUS_DST_COLOR,3.21 GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA,3.22 GL_ONE_MINUS_DST_ALPHA };3.23 -static int pvr2_poly_dstblend[8] = {3.24 +int pvr2_poly_dstblend[8] = {3.25 GL_ZERO, GL_ONE, GL_SRC_COLOR, GL_ONE_MINUS_SRC_COLOR,3.26 GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_DST_ALPHA,3.27 GL_ONE_MINUS_DST_ALPHA };3.28 -static int pvr2_poly_texblend[4] = {3.29 +int pvr2_poly_texblend[4] = {3.30 GL_REPLACE, GL_BLEND, GL_DECAL, GL_MODULATE };3.31 -static int pvr2_render_colour_format[8] = {3.32 +int pvr2_render_colour_format[8] = {3.33 COLFMT_ARGB1555, COLFMT_RGB565, COLFMT_ARGB4444, COLFMT_ARGB1555,3.34 COLFMT_RGB888, COLFMT_ARGB8888, COLFMT_ARGB8888, COLFMT_ARGB4444 };3.35 -#define POLY1_DEPTH_MODE(poly1) ( pvr2_poly_depthmode[(poly1)>>29] )3.36 -#define POLY1_DEPTH_ENABLE(poly1) (((poly1)&0x04000000) == 0 )3.37 -#define POLY1_CULL_MODE(poly1) (((poly1)>>27)&0x03)3.38 -#define POLY1_TEXTURED(poly1) (((poly1)&0x02000000))3.39 -#define POLY1_SPECULAR(poly1) (((poly1)&0x01000000))3.40 -#define POLY1_SHADE_MODEL(poly1) (((poly1)&0x00800000) ? GL_SMOOTH : GL_FLAT)3.41 -#define POLY1_UV16(poly1) (((poly1)&0x00400000))3.42 -#define POLY1_SINGLE_TILE(poly1) (((poly1)&0x00200000))3.44 -#define POLY2_SRC_BLEND(poly2) ( pvr2_poly_srcblend[(poly2) >> 29] )3.45 -#define POLY2_DEST_BLEND(poly2) ( pvr2_poly_dstblend[((poly2)>>26)&0x07] )3.46 -#define POLY2_SRC_BLEND_ENABLE(poly2) ((poly2)&0x02000000)3.47 -#define POLY2_DEST_BLEND_ENABLE(poly2) ((poly2)&0x01000000)3.48 -#define POLY2_COLOUR_CLAMP_ENABLE(poly2) ((poly2)&0x00200000)3.49 -#define POLY2_ALPHA_ENABLE(poly2) ((poly2)&0x001000000)3.50 -#define POLY2_TEX_ALPHA_ENABLE(poly2) (((poly2)&0x00080000) == 0 )3.51 -#define POLY2_TEX_WIDTH(poly2) ( 1<< ((((poly2) >> 3) & 0x07 ) + 3) )3.52 -#define POLY2_TEX_HEIGHT(poly2) ( 1<< (((poly2) & 0x07 ) + 3) )3.53 -#define POLY2_TEX_BLEND(poly2) ( pvr2_poly_texblend[((poly2) >> 6)&0x03] )3.55 #define RENDER_ZONLY 03.56 #define RENDER_NORMAL 1 /* Render non-modified polygons */3.57 @@ -153,7 +135,9 @@3.59 glShadeModel( POLY1_SHADE_MODEL(poly1) );3.61 - glBlendFunc( POLY2_SRC_BLEND(poly2), POLY2_DEST_BLEND(poly2) );3.62 + int srcblend = POLY2_SRC_BLEND(poly2);3.63 + int destblend = POLY2_DEST_BLEND(poly2);3.64 + glBlendFunc( srcblend, destblend );3.65 if( POLY2_TEX_ALPHA_ENABLE(poly2) ) {3.66 glEnable(GL_BLEND);3.67 } else {3.68 @@ -297,6 +281,7 @@3.69 fprintf( stderr, "Start render at %d.%d\n", tv_start.tv_sec, tv_start.tv_usec );3.70 glEnable( GL_SCISSOR_TEST );3.71 while( (segment->control & SEGMENT_END) == 0 ) {3.72 + // fwrite_dump32v( (uint32_t *)segment, sizeof(struct tile_segment), 6, stderr );3.73 int tilex = SEGMENT_X(segment->control);3.74 int tiley = SEGMENT_Y(segment->control);
4.1 --- a/src/pvr2/render.c Tue Sep 12 08:36:09 2006 +00004.2 +++ b/src/pvr2/render.c Tue Sep 12 08:38:38 2006 +00004.3 @@ -1,5 +1,5 @@4.4 /**4.5 - * $Id: render.c,v 1.13 2006-08-29 08:12:13 nkeynes Exp $4.6 + * $Id: render.c,v 1.14 2006-09-12 08:38:38 nkeynes Exp $4.7 *4.8 * PVR2 Renderer support. This part is primarily4.9 *4.10 @@ -19,11 +19,6 @@4.11 #include "pvr2/pvr2.h"4.12 #include "asic.h"4.14 -static int pvr2_render_colour_format[8] = {4.15 - COLFMT_ARGB1555, COLFMT_RGB565, COLFMT_ARGB4444, COLFMT_ARGB1555,4.16 - COLFMT_RGB888, COLFMT_ARGB8888, COLFMT_ARGB8888, COLFMT_ARGB4444 };4.17 -4.18 -4.19 /**4.20 * Describes a rendering buffer that's actually held in GL, for when we need4.21 * to fetch the bits back to vram.
.