Search
lxdream.org :: lxdream/src/pvr2/rendbkg.c :: diff
lxdream 0.9.1
released Jun 29
Download Now
filename src/pvr2/rendbkg.c
changeset 221:cf5c6d326162
prev219:dfd3292143f2
next223:f6c28fa9076b
author nkeynes
date Tue Sep 12 08:38:38 2006 +0000 (13 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 +0000
1.2 +++ b/src/pvr2/rendbkg.c Tue Sep 12 08:38:38 2006 +0000
1.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 handled
1.11 * completely differently.
1.12 *
1.13 + * Note: this would be really simple if GL did unclamped colour interpolation
1.14 + * but it doesn't (portably), which makes this roughly 2 orders of magnitude
1.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 modify
1.20 @@ -21,12 +25,16 @@
1.21
1.22 #include <sys/time.h>
1.23 #include "pvr2/pvr2.h"
1.24 +#include <GL/glext.h>
1.25 +#include <math.h>
1.26
1.27 -struct vertex_rgba {
1.28 - float x,y,z;
1.29 - uint32_t argb;
1.30 -};
1.31 +#define MAX_CLAMP_LINES 8
1.32 +#define MAX_VERTEXES 256
1.33 +#define MAX_REGIONS 256
1.34
1.35 +/**
1.36 + * Structure to hold an unpacked vertex
1.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.43
1.44 /**
1.45 + * Compute the line where k = target_k, (where k is normally one of
1.46 + * r,g,b,a, or z) and determines the points at which the line intersects
1.47 + * the viewport (0,0,width,height).
1.48 + *
1.49 + * @param center_x the x value for the center position
1.50 + * @param center_y the y value for the center position
1.51 + * @param center_k the k value for the center position
1.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.0
1.55 + * @param detxy
1.56 + * @param target Array to write the resultant x,y pairs to (note this
1.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 can
1.118 + * be rendered directly. Otherwise region_left and region_right refer two
1.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, while
1.178 + * "Right" means the points(s) result in a positive value in the line equation. The
1.179 + * exact meaning isn't particularly important though, as long as we're consistent
1.180 + * throughout this process
1.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, where
1.191 + * (x1,y1)-(x2,y2) defines the target segment, and
1.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_* constants
1.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 2
1.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 on
1.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 lie
1.245 + * on same side of second line segment, the line segments do
1.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, generates
1.272 + * two sets of vertexes representing the polygon on either side of the line
1.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 speaking
1.303 + * one of them must be ON the line, but this way allows for floating
1.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 speaking
1.332 + * one of them must be ON the line, but this way allows for floating
1.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 data
1.363 + * @param region current region under examination
1.364 + * @param vertex1 first vertex of the new line segment
1.365 + * @param vertex2 second vertex of the new line segment
1.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 both
1.395 + * sub trees
1.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 each
1.438 * vertex and the base 3-vertex triple used to define the background
1.439 * plane. Essentially the base vertexes are used to find the
1.440 @@ -49,69 +449,183 @@
1.441 * @param base The 3 vertexes supplied as the background definition
1.442 * @param compute An array of vertexes to compute. x and y must be
1.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.456
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.478
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 values
1.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 vertexes
1.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.599
1.600 +/**
1.601 + * Render a bkg_region.
1.602 + * @param scene the background scene data
1.603 + * @param region the region to render
1.604 + * @param vertexes the vertexes surrounding the region
1.605 + * @param num_vertexes the number of vertexes in the vertex array
1.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.647
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 }
.