filename | src/pvr2/rendbkg.c |
changeset | 221:cf5c6d326162 |
prev | 219:dfd3292143f2 |
next | 223:f6c28fa9076b |
author | nkeynes |
date | Tue Sep 12 08:38:38 2006 +0000 (15 years ago) |
permissions | -rw-r--r-- |
last change | Bug #0010 Move polygon macros to pvr2.h Implement background rendering more fully |
file | annotate | diff | log | raw |
1.1 --- a/src/pvr2/rendbkg.c Tue Aug 29 08:12:13 2006 +00001.2 +++ b/src/pvr2/rendbkg.c Tue Sep 12 08:38:38 2006 +00001.3 @@ -1,11 +1,15 @@1.4 /**1.5 - * $Id: rendbkg.c,v 1.1 2006-08-29 08:12:13 nkeynes Exp $1.6 + * $Id: rendbkg.c,v 1.2 2006-09-12 08:38:38 nkeynes Exp $1.7 *1.8 * PVR2 background renderer.1.9 *1.10 * Yes, it uses the same basic data structure. Yes, it needs to be handled1.11 * completely differently.1.12 *1.13 + * Note: this would be really simple if GL did unclamped colour interpolation1.14 + * but it doesn't (portably), which makes this roughly 2 orders of magnitude1.15 + * more complicated than it otherwise would be.1.16 + *1.17 * Copyright (c) 2005 Nathan Keynes.1.18 *1.19 * This program is free software; you can redistribute it and/or modify1.20 @@ -21,12 +25,16 @@1.22 #include <sys/time.h>1.23 #include "pvr2/pvr2.h"1.24 +#include <GL/glext.h>1.25 +#include <math.h>1.27 -struct vertex_rgba {1.28 - float x,y,z;1.29 - uint32_t argb;1.30 -};1.31 +#define MAX_CLAMP_LINES 81.32 +#define MAX_VERTEXES 2561.33 +#define MAX_REGIONS 2561.35 +/**1.36 + * Structure to hold an unpacked vertex1.37 + */1.38 struct vertex_all {1.39 float x,y,z;1.40 float u,v;1.41 @@ -40,6 +48,398 @@1.42 #define FARGB_B(x) (((float)(((x)&0xFF)+1))/256.0)1.44 /**1.45 + * Compute the line where k = target_k, (where k is normally one of1.46 + * r,g,b,a, or z) and determines the points at which the line intersects1.47 + * the viewport (0,0,width,height).1.48 + *1.49 + * @param center_x the x value for the center position1.50 + * @param center_y the y value for the center position1.51 + * @param center_k the k value for the center position1.52 + * @param width Width of the viewport (ie 640)1.53 + * @param height Height of the viewport (ie 480)1.54 + * @param target_k determine the line where k = this value, ie 1.01.55 + * @param detxy1.56 + * @param target Array to write the resultant x,y pairs to (note this1.57 + * function only sets x and y values).1.58 + * @return number of vertexes written to the target.1.59 + */1.60 +static int compute_colour_line( float center_x, float center_y, float center_k,1.61 + int width, int height, float target_k,1.62 + float detxy, float detxk, float detyk,1.63 + struct vertex_all *target ) {1.64 + int num_points = 0;1.65 + float tmpk = (target_k - center_k) * detxy;1.66 + float x0 = -1;1.67 + float x1 = -1;1.68 +1.69 + if( detyk != 0 ) {1.70 + x0 = (tmpk - ((0-center_y)*detxk))/detyk + center_x; /* x where y=0 */1.71 + if( x0 >= 0.0 && x0 <= width ) {1.72 + target[num_points].x = x0;1.73 + target[num_points].y = 0.0;1.74 + num_points++;1.75 + }1.76 +1.77 + x1 = (tmpk - ((height-center_y)*detxk))/detyk + center_x; /* x where y=height */1.78 + if( x1 >= 0.0 && x1 <= width ) {1.79 + target[num_points].x = x1;1.80 + target[num_points].y = height;1.81 + num_points++;1.82 + }1.83 + }1.84 +1.85 + if( detxk != 0 ) {1.86 + if( x0 != 0.0 && x1 != 0.0 ) { /* If x0 == 0 or x1 == 0, then we already have this one */1.87 + float y0 = (tmpk - ((0-center_x)*detyk))/detxk + center_y; /* y where x=0 */1.88 + if( y0 >= 0.0 && y0 <= height ) {1.89 + target[num_points].x = 0.0;1.90 + target[num_points].y = y0;1.91 + num_points++;1.92 + }1.93 + }1.94 +1.95 + if( x0 != width && x1 != width ) {1.96 + float y1 = (tmpk - ((width-center_x)*detyk))/detxk + center_y; /* y where x=width */1.97 + if( y1 >= 0.0 && y1 <= height ) {1.98 + target[num_points].x = width;1.99 + target[num_points].y = y1;1.100 + num_points++;1.101 + }1.102 + }1.103 + }1.104 +1.105 + if( num_points == 0 || num_points == 2 ) {1.106 + /* 0 = no points - line doesn't pass through the viewport */1.107 + /* 2 = normal case - got 2 endpoints */1.108 + return num_points;1.109 + } else {1.110 + ERROR( "compute_colour_line got bad number of points: %d", num_points );1.111 + return 0;1.112 + }1.113 +}1.114 +1.115 +/**1.116 + * A region describes a portion of the screen, possibly subdivided by a line.1.117 + * if region_left and region_right are -1, this is a terminal region that can1.118 + * be rendered directly. Otherwise region_left and region_right refer two1.119 + * sub-regions that are separated by the line segment vertex1-vertex2.1.120 + */1.121 +struct bkg_region {1.122 + /* Vertexes marking the line segment that splits this region */1.123 + int vertex1;1.124 + int vertex2;1.125 + /* Index of the left sub-region */1.126 + int region_left;1.127 + /* Index of the right sub-region */1.128 + int region_right;1.129 +};1.130 +1.131 +/**1.132 + * Convenience structure to bundle together the vertex and region data.1.133 + */1.134 +struct bkg_scene {1.135 + int num_vertexes;1.136 + int num_regions;1.137 + struct vertex_all vertexes[MAX_VERTEXES];1.138 + struct bkg_region regions[MAX_REGIONS];1.139 +};1.140 +1.141 +void parse_vertexes( uint32_t *polygon, int num_vertexes, struct vertex_all *result )1.142 +{1.143 + uint32_t *vertexes = polygon + 3;1.144 + int i,m = 0;1.145 + for( i=0; i<num_vertexes; i++ ) {1.146 + float *vertexf = (float *)vertexes;1.147 + result[i].x = vertexf[0];1.148 + result[i].y = vertexf[1];1.149 + result[i].z = vertexf[2];1.150 + uint32_t argb;1.151 + if( POLY1_TEXTURED(*polygon) ) {1.152 + if( POLY1_UV16(*polygon) ) {1.153 + result[i].u = halftofloat(vertexes[m+3]>>16);1.154 + result[i].v = halftofloat(vertexes[m+3]);1.155 + argb = vertexes[m+4];1.156 + vertexes += 5;1.157 + } else {1.158 + result[i].u = vertexf[m+3];1.159 + result[i].v = vertexf[m+4];1.160 + argb = vertexes[m+5];1.161 + vertexes += 6;1.162 + }1.163 + } else {1.164 + argb = vertexes[m+3];1.165 + vertexes += 4;1.166 + }1.167 + result[i].rgba[0] = FARGB_R(argb);1.168 + result[i].rgba[1] = FARGB_G(argb);1.169 + result[i].rgba[2] = FARGB_B(argb);1.170 + result[i].rgba[3] = FARGB_A(argb);1.171 + }1.172 +1.173 +}1.174 +1.175 +/**1.176 + * Constants returned by compute_line_intersection. Note that for these purposes,1.177 + * "Left" means the point(s) result in a negative value in the line equation, while1.178 + * "Right" means the points(s) result in a positive value in the line equation. The1.179 + * exact meaning isn't particularly important though, as long as we're consistent1.180 + * throughout this process1.181 + */1.182 +#define LINE_COLLINEAR 0 /* The line segments are part of the same line */1.183 +#define LINE_SIDE_LEFT 1 /* The second line is entirely to the "left" of the first line */1.184 +#define LINE_SIDE_RIGHT 2 /* The second line is entirely to the "right" of the first line */1.185 +#define LINE_INTERSECT_FROM_LEFT 3 /* The lines intersect, and (x3,y3) is to the "left" of the first line */1.186 +#define LINE_INTERSECT_FROM_RIGHT 4 /* The lines intersect, and (x3,y3) is to the "right" of the first line */1.187 +#define LINE_SKEW 5 /* The line segments neither intersect nor do any of the above apply (should never happen here) */1.188 +1.189 +/**1.190 + * Compute the intersection of two line segments, where1.191 + * (x1,y1)-(x2,y2) defines the target segment, and1.192 + * (x3,y3)-(x4,y4) defines the line intersecting it.1.193 + *1.194 + * Based off work by Mukesh Prasad (http://www.acm.org/pubs/tog/GraphicsGems/index.html)1.195 + *1.196 + * @return one of the above LINE_* constants1.197 + */1.198 +static int compute_line_intersection( float x1, float y1, /* First line segment */1.199 + float x2, float y2,1.200 + float x3, float y3, /* Second line segment */1.201 + float x4, float y4,1.202 + float *x, float *y ) /* Output value: */1.203 +{1.204 + float a1, a2, b1, b2, c1, c2; /* Coefficients of line eqns. */1.205 + float r1, r2, r3, r4; /* test values */1.206 + float denom; /* Intermediate values */1.207 +1.208 + /* Compute a1, b1, c1, where line joining points 1 and 21.209 + * is "a1 x + b1 y + c1 = 0".1.210 + */1.211 +1.212 + a1 = y2 - y1;1.213 + b1 = x1 - x2;1.214 + c1 = x2 * y1 - x1 * y2;1.215 +1.216 + /* Compute r3 and r4. */1.217 +1.218 + r3 = a1 * x3 + b1 * y3 + c1;1.219 + r4 = a1 * x4 + b1 * y4 + c1;1.220 +1.221 + /* Check signs of r3 and r4. If both point 3 and point 4 lie on1.222 + * same side of line 1, the line segments do not intersect.1.223 + */1.224 +1.225 + if( r3 == 0 && r4 == 0 ) {1.226 + return LINE_COLLINEAR;1.227 + } else if( r3 <= 0 && r4 <= 0 ) {1.228 + return LINE_SIDE_LEFT;1.229 + } else if( r3 >= 0 && r4 >= 0 ) {1.230 + return LINE_SIDE_RIGHT;1.231 + }1.232 +1.233 + /* Compute a2, b2, c2 */1.234 +1.235 + a2 = y4 - y3;1.236 + b2 = x3 - x4;1.237 + c2 = x4 * y3 - x3 * y4;1.238 +1.239 + /* Compute r1 and r2 */1.240 +1.241 + r1 = a2 * x1 + b2 * y1 + c2;1.242 + r2 = a2 * x2 + b2 * y2 + c2;1.243 +1.244 + /* Check signs of r1 and r2. If both point 1 and point 2 lie1.245 + * on same side of second line segment, the line segments do1.246 + * not intersect.1.247 + */1.248 +1.249 + if ( r1 != 0 && r2 != 0 &&1.250 + signbit(r1) == signbit(r2) ) {1.251 + return LINE_SKEW; /* Should never happen */1.252 + }1.253 +1.254 + /* Cmpute intersection point.1.255 + */1.256 + denom = a1 * b2 - a2 * b1;1.257 + if ( denom == 0 )1.258 + return LINE_COLLINEAR; /* Should never get to this point either */1.259 +1.260 + *x = (b1 * c2 - b2 * c1) / denom;1.261 + *y = (a2 * c1 - a1 * c2) / denom;1.262 +1.263 + if( r3 <= 0 && r4 >= 0 ) {1.264 + return LINE_INTERSECT_FROM_LEFT;1.265 + } else {1.266 + return LINE_INTERSECT_FROM_RIGHT;1.267 + }1.268 +}1.269 +1.270 +/**1.271 + * Given a set of vertexes and a line segment to use to split them, generates1.272 + * two sets of vertexes representing the polygon on either side of the line1.273 + * segment. This method preserves the winding direction of the input vertexes.1.274 + */1.275 +static void compute_subregions( struct bkg_scene *scene,1.276 + int splitv1, int splitv2,1.277 + int *vertex_in, int num_vertex_in,1.278 + int *left_vertex_out, int *num_left_vertex_out,1.279 + int *right_vertex_out, int *num_right_vertex_out )1.280 +{1.281 + float x1 = scene->vertexes[splitv1].x;1.282 + float y1 = scene->vertexes[splitv1].y;1.283 + float x2 = scene->vertexes[splitv2].x;1.284 + float y2 = scene->vertexes[splitv2].y;1.285 +1.286 + float a1 = y2 - y1;1.287 + float b1 = x1 - x2;1.288 + float c1 = x2 * y1 - x1 * y2;1.289 + int i;1.290 +1.291 + *num_left_vertex_out = 0;1.292 + *num_right_vertex_out = 0;1.293 + int last = 0;1.294 + for( i=0; i<num_vertex_in; i++ ) {1.295 + struct vertex_all *vertex = &scene->vertexes[vertex_in[i]];1.296 + float r = a1 * vertex->x + b1 * vertex->y + c1;1.297 + if( r <= 0 ) {1.298 + if( last == 1 ) {1.299 + /* cross-point. add the split vertexes */1.300 + int v1 = vertex_in[i-1];1.301 + int v2 = vertex_in[i];1.302 + /* Determine which point is closer to the line. Strictly speaking1.303 + * one of them must be ON the line, but this way allows for floating1.304 + * point inaccuracies.1.305 + */1.306 + float a2 = scene->vertexes[v2].y - scene->vertexes[v1].y;1.307 + float b2 = scene->vertexes[v1].x - scene->vertexes[v2].x;1.308 + float c2 = scene->vertexes[v2].x * scene->vertexes[v1].y -1.309 + scene->vertexes[v1].x * scene->vertexes[v2].y;1.310 + float r1 = a2 * x1 + b2 * y1 + c2;1.311 + float r2 = a2 * x2 + b2 * y2 + c2;1.312 + if( fabsf(r1) > fabs(r2) ) {1.313 + int tmp = splitv1;1.314 + splitv1 = splitv2;1.315 + splitv2 = tmp;1.316 + }1.317 + right_vertex_out[(*num_right_vertex_out)++] = splitv1;1.318 + right_vertex_out[(*num_right_vertex_out)++] = splitv2;1.319 + left_vertex_out[(*num_left_vertex_out)++] = splitv2;1.320 + left_vertex_out[(*num_left_vertex_out)++] = splitv1;1.321 + last = 2;1.322 + } else if( last != 2 ) {1.323 + last = -1;1.324 + }1.325 + left_vertex_out[(*num_left_vertex_out)++] = vertex_in[i];1.326 + } else {1.327 + if( last == -1 ) {1.328 + /* cross-point. add the split vertexes */1.329 + int v1 = vertex_in[i-1];1.330 + int v2 = vertex_in[i];1.331 + /* Determine which point is closer to the line. Strictly speaking1.332 + * one of them must be ON the line, but this way allows for floating1.333 + * point inaccuracies.1.334 + */1.335 + float a2 = scene->vertexes[v2].y - scene->vertexes[v1].y;1.336 + float b2 = scene->vertexes[v1].x - scene->vertexes[v2].x;1.337 + float c2 = scene->vertexes[v2].x * scene->vertexes[v1].y -1.338 + scene->vertexes[v1].x * scene->vertexes[v2].y;1.339 + float r1 = a2 * x1 + b2 * y1 + c2;1.340 + float r2 = a2 * x2 + b2 * y2 + c2;1.341 + if( fabsf(r1) > fabs(r2) ) {1.342 + int tmp = splitv1;1.343 + splitv1 = splitv2;1.344 + splitv2 = tmp;1.345 + }1.346 + left_vertex_out[(*num_left_vertex_out)++] = splitv1;1.347 + left_vertex_out[(*num_left_vertex_out)++] = splitv2;1.348 + right_vertex_out[(*num_right_vertex_out)++] = splitv2;1.349 + right_vertex_out[(*num_right_vertex_out)++] = splitv1;1.350 + last = 2;1.351 + } else if( last != 2 ) {1.352 + last = 1;1.353 + }1.354 + right_vertex_out[(*num_right_vertex_out)++] = vertex_in[i];1.355 + }1.356 + }1.357 +}1.358 +1.359 +/**1.360 + * Subdivide the region tree by splitting it along a given line.1.361 + *1.362 + * @param scene current bkg scene data1.363 + * @param region current region under examination1.364 + * @param vertex1 first vertex of the new line segment1.365 + * @param vertex2 second vertex of the new line segment1.366 + */1.367 +static void bkg_region_subdivide( struct bkg_scene *scene, int region, int vertex1, int vertex2 ) {1.368 + struct bkg_region *this_region = &scene->regions[region];1.369 +1.370 + if( scene->regions[region].region_left == -1 || scene->regions[region].region_right == -1 ) {1.371 + /* Reached the end of the tree. Setup new left+right regions */1.372 + int i = scene->num_regions;1.373 + scene->regions[i].region_left = scene->regions[i].region_right = -1;1.374 + scene->regions[i+1].region_left = scene->regions[i+1].region_right = -1;1.375 + this_region->region_left = i;1.376 + this_region->region_right = i+1;1.377 + this_region->vertex1 = vertex1;1.378 + this_region->vertex2 = vertex2;1.379 + scene->num_regions += 2;1.380 + } else {1.381 + float x,y;1.382 + int thisv1 = this_region->vertex1;1.383 + int thisv2 = this_region->vertex2;1.384 + int vertex3;1.385 + int status =1.386 + compute_line_intersection( scene->vertexes[thisv1].x, scene->vertexes[thisv1].y,1.387 + scene->vertexes[thisv2].x, scene->vertexes[thisv2].y,1.388 + scene->vertexes[vertex1].x, scene->vertexes[vertex1].y,1.389 + scene->vertexes[vertex2].x, scene->vertexes[vertex2].y,1.390 + &x, &y );1.391 + switch( status ) {1.392 + case LINE_INTERSECT_FROM_LEFT:1.393 + /* if new line segment intersects our current line segment,1.394 + * subdivide the segment (add a new vertex) and recurse on both1.395 + * sub trees1.396 + */1.397 + /* Compute split-point vertex */1.398 + vertex3 = scene->num_vertexes++;1.399 + scene->vertexes[vertex3].x = x;1.400 + scene->vertexes[vertex3].y = y;1.401 + /* Recurse */1.402 + bkg_region_subdivide( scene, scene->regions[region].region_left, vertex1,vertex3 );1.403 + bkg_region_subdivide( scene, scene->regions[region].region_right, vertex3, vertex2 );1.404 + break;1.405 + case LINE_INTERSECT_FROM_RIGHT:1.406 + /* Same except line runs in the opposite direction */1.407 + vertex3 = scene->num_vertexes++;1.408 + scene->vertexes[vertex3].x = x;1.409 + scene->vertexes[vertex3].y = y;1.410 + /* Recurse */1.411 + bkg_region_subdivide( scene, scene->regions[region].region_left, vertex2,vertex3 );1.412 + bkg_region_subdivide( scene, scene->regions[region].region_right, vertex3, vertex1 );1.413 + break;1.414 + case LINE_COLLINEAR:1.415 + case LINE_SKEW:1.416 + /* Collinear - ignore */1.417 + break;1.418 + case LINE_SIDE_LEFT:1.419 + /* else if line segment passes through the left sub-region alone,1.420 + * left-recurse only.1.421 + */1.422 + bkg_region_subdivide( scene, scene->regions[region].region_left, vertex1, vertex2 );1.423 + break;1.424 + case LINE_SIDE_RIGHT:1.425 + /* Otherwise line segment passes through the right sub-region alone,1.426 + * so right-recurse.1.427 + */1.428 + bkg_region_subdivide( scene, scene->regions[region].region_right, vertex1, vertex2 );1.429 + break;1.430 + }1.431 + }1.432 +}1.433 +1.434 +1.435 +1.436 +/**1.437 * Compute the values for an array of vertexes, given x,y for each1.438 * vertex and the base 3-vertex triple used to define the background1.439 * plane. Essentially the base vertexes are used to find the1.440 @@ -49,69 +449,183 @@1.441 * @param base The 3 vertexes supplied as the background definition1.442 * @param compute An array of vertexes to compute. x and y must be1.443 * preset, other values are computed.1.444 - * @param num_compute number of vertexes in the compute array.1.445 */1.446 -void compute_vertexes( struct vertex_rgba *base,1.447 - struct vertex_all *compute,1.448 - int num_compute )1.449 +static void bkg_compute_scene( struct vertex_all *base, int width, int height,1.450 + struct bkg_scene *scene )1.451 {1.452 struct vertex_all center;1.453 struct vertex_all diff0, diff1;1.454 - int i;1.455 + int i,k;1.457 center.x = base[1].x;1.458 center.y = base[1].y;1.459 center.z = base[1].z;1.460 - center.rgba[0] = FARGB_R(base[1].argb);1.461 - center.rgba[1] = FARGB_G(base[1].argb);1.462 - center.rgba[2] = FARGB_B(base[1].argb);1.463 - center.rgba[3] = FARGB_A(base[1].argb);1.464 diff0.x = base[0].x - base[1].x;1.465 diff0.y = base[0].y - base[1].y;1.466 diff0.z = base[0].z - base[1].z;1.467 diff1.x = base[2].x - base[1].x;1.468 diff1.y = base[2].y - base[1].y;1.469 diff1.z = base[2].z - base[1].z;1.470 - diff0.rgba[0] = FARGB_R(base[0].argb) - center.rgba[0];1.471 - diff0.rgba[1] = FARGB_G(base[0].argb) - center.rgba[1];1.472 - diff0.rgba[2] = FARGB_B(base[0].argb) - center.rgba[2];1.473 - diff0.rgba[3] = FARGB_A(base[0].argb) - center.rgba[3];1.474 - diff1.rgba[0] = FARGB_R(base[2].argb) - center.rgba[0];1.475 - diff1.rgba[1] = FARGB_G(base[2].argb) - center.rgba[1];1.476 - diff1.rgba[2] = FARGB_B(base[2].argb) - center.rgba[2];1.477 - diff1.rgba[3] = FARGB_A(base[2].argb) - center.rgba[3];1.479 - float divisor = ((diff1.y) * (diff0.x)) - ((diff0.y) * (diff1.x));1.480 - if( divisor == 0 ) {1.481 - /* The points lie on a single line - no plane for you. *shrugs* */1.482 + float detxy = ((diff1.y) * (diff0.x)) - ((diff0.y) * (diff1.x));1.483 +1.484 + /* Corner points first */1.485 + scene->vertexes[0].x = 0.0;1.486 + scene->vertexes[0].y = 0.0;1.487 + scene->vertexes[1].x = width;1.488 + scene->vertexes[1].y = 0.0;1.489 + scene->vertexes[2].x = width;1.490 + scene->vertexes[2].y = height;1.491 + scene->vertexes[3].x = 0.0;1.492 + scene->vertexes[3].y = height;1.493 + scene->regions[0].region_left = -1;1.494 + scene->regions[0].region_right = -1;1.495 + scene->num_vertexes = 4;1.496 + scene->num_regions = 1;1.497 +1.498 + if( detxy == 0 ) {1.499 + /* The points lie on a single line - no plane for you. Use the values1.500 + * from the 3rd point for the whole screen.1.501 + */1.502 + for( i=0; i<4; i++ ) {1.503 + scene->vertexes[i].rgba[0] = base[2].rgba[0];1.504 + scene->vertexes[i].rgba[1] = base[2].rgba[1];1.505 + scene->vertexes[i].rgba[2] = base[2].rgba[2];1.506 + scene->vertexes[i].rgba[3] = base[2].rgba[3];1.507 + scene->vertexes[i].u = base[2].u;1.508 + scene->vertexes[i].v = base[2].v;1.509 + }1.510 } else {1.511 - for( i=0; i<num_compute; i++ ) {1.512 - float t = ((compute[i].x - center.x) * diff1.y -1.513 - (compute[i].y - center.y) * diff1.x) / divisor;1.514 - float s = ((compute[i].y - center.y) * diff0.x -1.515 - (compute[i].x - center.x) * diff0.y) / divisor;1.516 - compute[i].z = center.z + (t*diff0.z) + (s*diff1.z);1.517 - compute[i].rgba[0] = center.rgba[0] + (t*diff0.rgba[0]) + (s*diff1.rgba[0]);1.518 - compute[i].rgba[1] = center.rgba[1] + (t*diff0.rgba[1]) + (s*diff1.rgba[1]);1.519 - compute[i].rgba[2] = center.rgba[2] + (t*diff0.rgba[2]) + (s*diff1.rgba[2]);1.520 - compute[i].rgba[3] = center.rgba[3] + (t*diff0.rgba[3]) + (s*diff1.rgba[3]);1.521 + /* Compute the colour values at each corner */1.522 + center.rgba[0] = base[1].rgba[0];1.523 + center.rgba[1] = base[1].rgba[1];1.524 + center.rgba[2] = base[1].rgba[2];1.525 + center.rgba[3] = base[1].rgba[3];1.526 + diff0.rgba[0] = base[0].rgba[0] - center.rgba[0];1.527 + diff0.rgba[1] = base[0].rgba[1] - center.rgba[1];1.528 + diff0.rgba[2] = base[0].rgba[2] - center.rgba[2];1.529 + diff0.rgba[3] = base[0].rgba[3] - center.rgba[3];1.530 + diff0.u = base[0].u - center.u;1.531 + diff0.v = base[0].v - center.v;1.532 + diff1.rgba[0] = base[2].rgba[0] - center.rgba[0];1.533 + diff1.rgba[1] = base[2].rgba[1] - center.rgba[1];1.534 + diff1.rgba[2] = base[2].rgba[2] - center.rgba[2];1.535 + diff1.rgba[3] = base[2].rgba[3] - center.rgba[3];1.536 + diff1.u = base[2].u - center.u;1.537 + diff1.v = base[2].v - center.v;1.538 + for( i=0; i<4; i++ ) {1.539 + float t = ((scene->vertexes[i].x - center.x) * diff1.y -1.540 + (scene->vertexes[i].y - center.y) * diff1.x) / detxy;1.541 + float s = ((scene->vertexes[i].y - center.y) * diff0.x -1.542 + (scene->vertexes[i].x - center.x) * diff0.y) / detxy;1.543 + scene->vertexes[i].z = center.z + (t*diff0.z) + (s*diff1.z);1.544 + scene->vertexes[i].rgba[0] = center.rgba[0] + (t*diff0.rgba[0]) + (s*diff1.rgba[0]);1.545 + scene->vertexes[i].rgba[1] = center.rgba[1] + (t*diff0.rgba[1]) + (s*diff1.rgba[1]);1.546 + scene->vertexes[i].rgba[2] = center.rgba[2] + (t*diff0.rgba[2]) + (s*diff1.rgba[2]);1.547 + scene->vertexes[i].rgba[3] = center.rgba[3] + (t*diff0.rgba[3]) + (s*diff1.rgba[3]);1.548 + scene->vertexes[i].u = center.u + (t*diff0.u) + (s*diff1.u);1.549 + scene->vertexes[i].v = center.v + (t*diff0.v) + (s*diff1.v);1.550 + }1.551 +1.552 + /* Check for values > 1.0 | < 0.0 */1.553 + for( k=0; k<4; k++ ) {1.554 + float detyk = ((diff1.y) * (diff0.rgba[k])) - ((diff0.y)*(diff1.rgba[k]));1.555 + float detxk = ((diff0.x) * (diff1.rgba[k])) - ((diff1.x)*(diff0.rgba[k]));1.556 + if( scene->vertexes[0].rgba[k] > 1.0 || scene->vertexes[1].rgba[k] > 1.0 ||1.557 + scene->vertexes[2].rgba[k] > 1.0 || scene->vertexes[3].rgba[k] > 1.0 ) {1.558 + int v1 = scene->num_vertexes;1.559 + scene->num_vertexes += compute_colour_line(center.x, center.y, center.rgba[k],1.560 + width, height, 1.0,1.561 + detxy, detxk, detyk,1.562 + scene->vertexes+scene->num_vertexes );1.563 + if( scene->num_vertexes != v1 ) {1.564 + bkg_region_subdivide( scene, 0, v1, v1+1 );1.565 + }1.566 + }1.567 +1.568 + if( scene->vertexes[0].rgba[k] < 0.0 || scene->vertexes[1].rgba[k] < 0.0 ||1.569 + scene->vertexes[2].rgba[k] < 0.0 || scene->vertexes[3].rgba[k] < 0.0 ) {1.570 + int v1 = scene->num_vertexes;1.571 + scene->num_vertexes += compute_colour_line(center.x, center.y, center.rgba[k],1.572 + width, height, 0.0,1.573 + detxy, detxk, detyk,1.574 + scene->vertexes+scene->num_vertexes );1.575 + if( scene->num_vertexes != v1 ) {1.576 + bkg_region_subdivide( scene, 0, v1, v1+1 );1.577 + }1.578 +1.579 + }1.580 + }1.581 +1.582 + /* Finally compute the colour values for all vertexes1.583 + * (excluding the 4 we did upfront) */1.584 + for( i=4; i<scene->num_vertexes; i++ ) {1.585 + float t = ((scene->vertexes[i].x - center.x) * diff1.y -1.586 + (scene->vertexes[i].y - center.y) * diff1.x) / detxy;1.587 + float s = ((scene->vertexes[i].y - center.y) * diff0.x -1.588 + (scene->vertexes[i].x - center.x) * diff0.y) / detxy;1.589 + scene->vertexes[i].z = center.z + (t*diff0.z) + (s*diff1.z);1.590 + scene->vertexes[i].rgba[0] = center.rgba[0] + (t*diff0.rgba[0]) + (s*diff1.rgba[0]);1.591 + scene->vertexes[i].rgba[1] = center.rgba[1] + (t*diff0.rgba[1]) + (s*diff1.rgba[1]);1.592 + scene->vertexes[i].rgba[2] = center.rgba[2] + (t*diff0.rgba[2]) + (s*diff1.rgba[2]);1.593 + scene->vertexes[i].rgba[3] = center.rgba[3] + (t*diff0.rgba[3]) + (s*diff1.rgba[3]);1.594 + scene->vertexes[i].u = center.u + (t*diff0.u) + (s*diff1.u);1.595 + scene->vertexes[i].v = center.v + (t*diff0.v) + (s*diff1.v);1.596 }1.597 }1.598 }1.600 +/**1.601 + * Render a bkg_region.1.602 + * @param scene the background scene data1.603 + * @param region the region to render1.604 + * @param vertexes the vertexes surrounding the region1.605 + * @param num_vertexes the number of vertexes in the vertex array1.606 + */1.607 +void bkg_render_region( struct bkg_scene *scene, int region, int *vertexes, int num_vertexes,1.608 + uint32_t poly1 )1.609 +{1.610 + if( scene->regions[region].region_left == -1 && scene->regions[region].region_right == -1 ) {1.611 + /* Leaf node - render the points as given */1.612 + int i,k;1.613 + glBegin(GL_POLYGON);1.614 + for( i=0; i<num_vertexes; i++ ) {1.615 + k = vertexes[i];1.616 + glColor4fv(scene->vertexes[k].rgba);1.617 + if( POLY1_TEXTURED(poly1) ) {1.618 + glTexCoord2f(scene->vertexes[k].u, scene->vertexes[k].v);1.619 + }1.620 + glVertex3f(scene->vertexes[k].x, scene->vertexes[k].y, scene->vertexes[k].z);1.621 + }1.622 + glEnd();1.623 + } else {1.624 + /* split the region into left and right regions */1.625 + int left_vertexes[num_vertexes+1];1.626 + int right_vertexes[num_vertexes+1];1.627 + int num_left = 0;1.628 + int num_right = 0;1.629 + struct bkg_region *reg = &scene->regions[region];1.630 + compute_subregions( scene, reg->vertex1, reg->vertex2, vertexes, num_vertexes,1.631 + left_vertexes, &num_left, right_vertexes, &num_right );1.632 + bkg_render_region( scene, reg->region_left, left_vertexes, num_left, poly1 );1.633 + bkg_render_region( scene, reg->region_right, right_vertexes, num_right, poly1 );1.634 + }1.635 +1.636 +}1.637 +1.638 +1.639 void render_backplane( uint32_t *polygon, uint32_t width, uint32_t height, uint32_t mode ) {1.640 - struct vertex_rgba *vertex = (struct vertex_rgba *)(polygon + 3);1.641 - struct vertex_all compute[4] = { {0.0,0.0}, {width,0.0}, {width, height}, {0.0,height} };1.642 - int i;1.643 + struct vertex_all vertex[3];1.644 + int screen_vertexes[4] = {0,1,2,3};1.645 + struct bkg_scene scene;1.646 + int i,j,k, num_vertexes;1.648 + parse_vertexes(polygon, 3, vertex);1.649 render_set_context(polygon, 0);1.650 - compute_vertexes( vertex, compute, 4 );1.651 - glBegin(GL_QUADS);1.652 - for( i=0; i<4; i++ ) {1.653 - glColor4fv(compute[i].rgba);1.654 - glVertex3f(compute[i].x, compute[i].y, compute[i].z);1.655 - fprintf( stderr, "BG %d,%d: %f %f %f\n", (int)compute[i].x, (int)compute[i].y,1.656 - compute[i].rgba[0], compute[i].rgba[1], compute[i].rgba[2] );1.657 - }1.658 - glEnd();1.659 + glDisable(GL_CULL_FACE);1.660 + glDisable(GL_DEPTH_TEST);1.661 + glBlendFunc(GL_ONE, GL_ZERO); /* For now, just disable alpha blending on the bkg */1.662 + fwrite_dump32( polygon, 48, stderr );1.663 + bkg_compute_scene(vertex, width, height, &scene);1.664 + bkg_render_region(&scene, 0, screen_vertexes, 4, *polygon);1.665 }
.