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 (17 years ago) |
permissions | -rw-r--r-- |
last change | Bug #0010 Move polygon macros to pvr2.h Implement background rendering more fully |
view | annotate | diff | log | raw |
1 /**
2 * $Id: rendbkg.c,v 1.2 2006-09-12 08:38:38 nkeynes Exp $
3 *
4 * PVR2 background renderer.
5 *
6 * Yes, it uses the same basic data structure. Yes, it needs to be handled
7 * completely differently.
8 *
9 * Note: this would be really simple if GL did unclamped colour interpolation
10 * but it doesn't (portably), which makes this roughly 2 orders of magnitude
11 * more complicated than it otherwise would be.
12 *
13 * Copyright (c) 2005 Nathan Keynes.
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 */
26 #include <sys/time.h>
27 #include "pvr2/pvr2.h"
28 #include <GL/glext.h>
29 #include <math.h>
31 #define MAX_CLAMP_LINES 8
32 #define MAX_VERTEXES 256
33 #define MAX_REGIONS 256
35 /**
36 * Structure to hold an unpacked vertex
37 */
38 struct vertex_all {
39 float x,y,z;
40 float u,v;
41 float rgba[4]; /* Note - RGBA order, as preferred by GL */
42 float spec_rgba[4];
43 };
45 #define FARGB_A(x) (((float)(((x)>>24)+1))/256.0)
46 #define FARGB_R(x) (((float)((((x)>>16)&0xFF)+1))/256.0)
47 #define FARGB_G(x) (((float)((((x)>>8)&0xFF)+1))/256.0)
48 #define FARGB_B(x) (((float)(((x)&0xFF)+1))/256.0)
50 /**
51 * Compute the line where k = target_k, (where k is normally one of
52 * r,g,b,a, or z) and determines the points at which the line intersects
53 * the viewport (0,0,width,height).
54 *
55 * @param center_x the x value for the center position
56 * @param center_y the y value for the center position
57 * @param center_k the k value for the center position
58 * @param width Width of the viewport (ie 640)
59 * @param height Height of the viewport (ie 480)
60 * @param target_k determine the line where k = this value, ie 1.0
61 * @param detxy
62 * @param target Array to write the resultant x,y pairs to (note this
63 * function only sets x and y values).
64 * @return number of vertexes written to the target.
65 */
66 static int compute_colour_line( float center_x, float center_y, float center_k,
67 int width, int height, float target_k,
68 float detxy, float detxk, float detyk,
69 struct vertex_all *target ) {
70 int num_points = 0;
71 float tmpk = (target_k - center_k) * detxy;
72 float x0 = -1;
73 float x1 = -1;
75 if( detyk != 0 ) {
76 x0 = (tmpk - ((0-center_y)*detxk))/detyk + center_x; /* x where y=0 */
77 if( x0 >= 0.0 && x0 <= width ) {
78 target[num_points].x = x0;
79 target[num_points].y = 0.0;
80 num_points++;
81 }
83 x1 = (tmpk - ((height-center_y)*detxk))/detyk + center_x; /* x where y=height */
84 if( x1 >= 0.0 && x1 <= width ) {
85 target[num_points].x = x1;
86 target[num_points].y = height;
87 num_points++;
88 }
89 }
91 if( detxk != 0 ) {
92 if( x0 != 0.0 && x1 != 0.0 ) { /* If x0 == 0 or x1 == 0, then we already have this one */
93 float y0 = (tmpk - ((0-center_x)*detyk))/detxk + center_y; /* y where x=0 */
94 if( y0 >= 0.0 && y0 <= height ) {
95 target[num_points].x = 0.0;
96 target[num_points].y = y0;
97 num_points++;
98 }
99 }
101 if( x0 != width && x1 != width ) {
102 float y1 = (tmpk - ((width-center_x)*detyk))/detxk + center_y; /* y where x=width */
103 if( y1 >= 0.0 && y1 <= height ) {
104 target[num_points].x = width;
105 target[num_points].y = y1;
106 num_points++;
107 }
108 }
109 }
111 if( num_points == 0 || num_points == 2 ) {
112 /* 0 = no points - line doesn't pass through the viewport */
113 /* 2 = normal case - got 2 endpoints */
114 return num_points;
115 } else {
116 ERROR( "compute_colour_line got bad number of points: %d", num_points );
117 return 0;
118 }
119 }
121 /**
122 * A region describes a portion of the screen, possibly subdivided by a line.
123 * if region_left and region_right are -1, this is a terminal region that can
124 * be rendered directly. Otherwise region_left and region_right refer two
125 * sub-regions that are separated by the line segment vertex1-vertex2.
126 */
127 struct bkg_region {
128 /* Vertexes marking the line segment that splits this region */
129 int vertex1;
130 int vertex2;
131 /* Index of the left sub-region */
132 int region_left;
133 /* Index of the right sub-region */
134 int region_right;
135 };
137 /**
138 * Convenience structure to bundle together the vertex and region data.
139 */
140 struct bkg_scene {
141 int num_vertexes;
142 int num_regions;
143 struct vertex_all vertexes[MAX_VERTEXES];
144 struct bkg_region regions[MAX_REGIONS];
145 };
147 void parse_vertexes( uint32_t *polygon, int num_vertexes, struct vertex_all *result )
148 {
149 uint32_t *vertexes = polygon + 3;
150 int i,m = 0;
151 for( i=0; i<num_vertexes; i++ ) {
152 float *vertexf = (float *)vertexes;
153 result[i].x = vertexf[0];
154 result[i].y = vertexf[1];
155 result[i].z = vertexf[2];
156 uint32_t argb;
157 if( POLY1_TEXTURED(*polygon) ) {
158 if( POLY1_UV16(*polygon) ) {
159 result[i].u = halftofloat(vertexes[m+3]>>16);
160 result[i].v = halftofloat(vertexes[m+3]);
161 argb = vertexes[m+4];
162 vertexes += 5;
163 } else {
164 result[i].u = vertexf[m+3];
165 result[i].v = vertexf[m+4];
166 argb = vertexes[m+5];
167 vertexes += 6;
168 }
169 } else {
170 argb = vertexes[m+3];
171 vertexes += 4;
172 }
173 result[i].rgba[0] = FARGB_R(argb);
174 result[i].rgba[1] = FARGB_G(argb);
175 result[i].rgba[2] = FARGB_B(argb);
176 result[i].rgba[3] = FARGB_A(argb);
177 }
179 }
181 /**
182 * Constants returned by compute_line_intersection. Note that for these purposes,
183 * "Left" means the point(s) result in a negative value in the line equation, while
184 * "Right" means the points(s) result in a positive value in the line equation. The
185 * exact meaning isn't particularly important though, as long as we're consistent
186 * throughout this process
187 */
188 #define LINE_COLLINEAR 0 /* The line segments are part of the same line */
189 #define LINE_SIDE_LEFT 1 /* The second line is entirely to the "left" of the first line */
190 #define LINE_SIDE_RIGHT 2 /* The second line is entirely to the "right" of the first line */
191 #define LINE_INTERSECT_FROM_LEFT 3 /* The lines intersect, and (x3,y3) is to the "left" of the first line */
192 #define LINE_INTERSECT_FROM_RIGHT 4 /* The lines intersect, and (x3,y3) is to the "right" of the first line */
193 #define LINE_SKEW 5 /* The line segments neither intersect nor do any of the above apply (should never happen here) */
195 /**
196 * Compute the intersection of two line segments, where
197 * (x1,y1)-(x2,y2) defines the target segment, and
198 * (x3,y3)-(x4,y4) defines the line intersecting it.
199 *
200 * Based off work by Mukesh Prasad (http://www.acm.org/pubs/tog/GraphicsGems/index.html)
201 *
202 * @return one of the above LINE_* constants
203 */
204 static int compute_line_intersection( float x1, float y1, /* First line segment */
205 float x2, float y2,
206 float x3, float y3, /* Second line segment */
207 float x4, float y4,
208 float *x, float *y ) /* Output value: */
209 {
210 float a1, a2, b1, b2, c1, c2; /* Coefficients of line eqns. */
211 float r1, r2, r3, r4; /* test values */
212 float denom; /* Intermediate values */
214 /* Compute a1, b1, c1, where line joining points 1 and 2
215 * is "a1 x + b1 y + c1 = 0".
216 */
218 a1 = y2 - y1;
219 b1 = x1 - x2;
220 c1 = x2 * y1 - x1 * y2;
222 /* Compute r3 and r4. */
224 r3 = a1 * x3 + b1 * y3 + c1;
225 r4 = a1 * x4 + b1 * y4 + c1;
227 /* Check signs of r3 and r4. If both point 3 and point 4 lie on
228 * same side of line 1, the line segments do not intersect.
229 */
231 if( r3 == 0 && r4 == 0 ) {
232 return LINE_COLLINEAR;
233 } else if( r3 <= 0 && r4 <= 0 ) {
234 return LINE_SIDE_LEFT;
235 } else if( r3 >= 0 && r4 >= 0 ) {
236 return LINE_SIDE_RIGHT;
237 }
239 /* Compute a2, b2, c2 */
241 a2 = y4 - y3;
242 b2 = x3 - x4;
243 c2 = x4 * y3 - x3 * y4;
245 /* Compute r1 and r2 */
247 r1 = a2 * x1 + b2 * y1 + c2;
248 r2 = a2 * x2 + b2 * y2 + c2;
250 /* Check signs of r1 and r2. If both point 1 and point 2 lie
251 * on same side of second line segment, the line segments do
252 * not intersect.
253 */
255 if ( r1 != 0 && r2 != 0 &&
256 signbit(r1) == signbit(r2) ) {
257 return LINE_SKEW; /* Should never happen */
258 }
260 /* Cmpute intersection point.
261 */
262 denom = a1 * b2 - a2 * b1;
263 if ( denom == 0 )
264 return LINE_COLLINEAR; /* Should never get to this point either */
266 *x = (b1 * c2 - b2 * c1) / denom;
267 *y = (a2 * c1 - a1 * c2) / denom;
269 if( r3 <= 0 && r4 >= 0 ) {
270 return LINE_INTERSECT_FROM_LEFT;
271 } else {
272 return LINE_INTERSECT_FROM_RIGHT;
273 }
274 }
276 /**
277 * Given a set of vertexes and a line segment to use to split them, generates
278 * two sets of vertexes representing the polygon on either side of the line
279 * segment. This method preserves the winding direction of the input vertexes.
280 */
281 static void compute_subregions( struct bkg_scene *scene,
282 int splitv1, int splitv2,
283 int *vertex_in, int num_vertex_in,
284 int *left_vertex_out, int *num_left_vertex_out,
285 int *right_vertex_out, int *num_right_vertex_out )
286 {
287 float x1 = scene->vertexes[splitv1].x;
288 float y1 = scene->vertexes[splitv1].y;
289 float x2 = scene->vertexes[splitv2].x;
290 float y2 = scene->vertexes[splitv2].y;
292 float a1 = y2 - y1;
293 float b1 = x1 - x2;
294 float c1 = x2 * y1 - x1 * y2;
295 int i;
297 *num_left_vertex_out = 0;
298 *num_right_vertex_out = 0;
299 int last = 0;
300 for( i=0; i<num_vertex_in; i++ ) {
301 struct vertex_all *vertex = &scene->vertexes[vertex_in[i]];
302 float r = a1 * vertex->x + b1 * vertex->y + c1;
303 if( r <= 0 ) {
304 if( last == 1 ) {
305 /* cross-point. add the split vertexes */
306 int v1 = vertex_in[i-1];
307 int v2 = vertex_in[i];
308 /* Determine which point is closer to the line. Strictly speaking
309 * one of them must be ON the line, but this way allows for floating
310 * point inaccuracies.
311 */
312 float a2 = scene->vertexes[v2].y - scene->vertexes[v1].y;
313 float b2 = scene->vertexes[v1].x - scene->vertexes[v2].x;
314 float c2 = scene->vertexes[v2].x * scene->vertexes[v1].y -
315 scene->vertexes[v1].x * scene->vertexes[v2].y;
316 float r1 = a2 * x1 + b2 * y1 + c2;
317 float r2 = a2 * x2 + b2 * y2 + c2;
318 if( fabsf(r1) > fabs(r2) ) {
319 int tmp = splitv1;
320 splitv1 = splitv2;
321 splitv2 = tmp;
322 }
323 right_vertex_out[(*num_right_vertex_out)++] = splitv1;
324 right_vertex_out[(*num_right_vertex_out)++] = splitv2;
325 left_vertex_out[(*num_left_vertex_out)++] = splitv2;
326 left_vertex_out[(*num_left_vertex_out)++] = splitv1;
327 last = 2;
328 } else if( last != 2 ) {
329 last = -1;
330 }
331 left_vertex_out[(*num_left_vertex_out)++] = vertex_in[i];
332 } else {
333 if( last == -1 ) {
334 /* cross-point. add the split vertexes */
335 int v1 = vertex_in[i-1];
336 int v2 = vertex_in[i];
337 /* Determine which point is closer to the line. Strictly speaking
338 * one of them must be ON the line, but this way allows for floating
339 * point inaccuracies.
340 */
341 float a2 = scene->vertexes[v2].y - scene->vertexes[v1].y;
342 float b2 = scene->vertexes[v1].x - scene->vertexes[v2].x;
343 float c2 = scene->vertexes[v2].x * scene->vertexes[v1].y -
344 scene->vertexes[v1].x * scene->vertexes[v2].y;
345 float r1 = a2 * x1 + b2 * y1 + c2;
346 float r2 = a2 * x2 + b2 * y2 + c2;
347 if( fabsf(r1) > fabs(r2) ) {
348 int tmp = splitv1;
349 splitv1 = splitv2;
350 splitv2 = tmp;
351 }
352 left_vertex_out[(*num_left_vertex_out)++] = splitv1;
353 left_vertex_out[(*num_left_vertex_out)++] = splitv2;
354 right_vertex_out[(*num_right_vertex_out)++] = splitv2;
355 right_vertex_out[(*num_right_vertex_out)++] = splitv1;
356 last = 2;
357 } else if( last != 2 ) {
358 last = 1;
359 }
360 right_vertex_out[(*num_right_vertex_out)++] = vertex_in[i];
361 }
362 }
363 }
365 /**
366 * Subdivide the region tree by splitting it along a given line.
367 *
368 * @param scene current bkg scene data
369 * @param region current region under examination
370 * @param vertex1 first vertex of the new line segment
371 * @param vertex2 second vertex of the new line segment
372 */
373 static void bkg_region_subdivide( struct bkg_scene *scene, int region, int vertex1, int vertex2 ) {
374 struct bkg_region *this_region = &scene->regions[region];
376 if( scene->regions[region].region_left == -1 || scene->regions[region].region_right == -1 ) {
377 /* Reached the end of the tree. Setup new left+right regions */
378 int i = scene->num_regions;
379 scene->regions[i].region_left = scene->regions[i].region_right = -1;
380 scene->regions[i+1].region_left = scene->regions[i+1].region_right = -1;
381 this_region->region_left = i;
382 this_region->region_right = i+1;
383 this_region->vertex1 = vertex1;
384 this_region->vertex2 = vertex2;
385 scene->num_regions += 2;
386 } else {
387 float x,y;
388 int thisv1 = this_region->vertex1;
389 int thisv2 = this_region->vertex2;
390 int vertex3;
391 int status =
392 compute_line_intersection( scene->vertexes[thisv1].x, scene->vertexes[thisv1].y,
393 scene->vertexes[thisv2].x, scene->vertexes[thisv2].y,
394 scene->vertexes[vertex1].x, scene->vertexes[vertex1].y,
395 scene->vertexes[vertex2].x, scene->vertexes[vertex2].y,
396 &x, &y );
397 switch( status ) {
398 case LINE_INTERSECT_FROM_LEFT:
399 /* if new line segment intersects our current line segment,
400 * subdivide the segment (add a new vertex) and recurse on both
401 * sub trees
402 */
403 /* Compute split-point vertex */
404 vertex3 = scene->num_vertexes++;
405 scene->vertexes[vertex3].x = x;
406 scene->vertexes[vertex3].y = y;
407 /* Recurse */
408 bkg_region_subdivide( scene, scene->regions[region].region_left, vertex1,vertex3 );
409 bkg_region_subdivide( scene, scene->regions[region].region_right, vertex3, vertex2 );
410 break;
411 case LINE_INTERSECT_FROM_RIGHT:
412 /* Same except line runs in the opposite direction */
413 vertex3 = scene->num_vertexes++;
414 scene->vertexes[vertex3].x = x;
415 scene->vertexes[vertex3].y = y;
416 /* Recurse */
417 bkg_region_subdivide( scene, scene->regions[region].region_left, vertex2,vertex3 );
418 bkg_region_subdivide( scene, scene->regions[region].region_right, vertex3, vertex1 );
419 break;
420 case LINE_COLLINEAR:
421 case LINE_SKEW:
422 /* Collinear - ignore */
423 break;
424 case LINE_SIDE_LEFT:
425 /* else if line segment passes through the left sub-region alone,
426 * left-recurse only.
427 */
428 bkg_region_subdivide( scene, scene->regions[region].region_left, vertex1, vertex2 );
429 break;
430 case LINE_SIDE_RIGHT:
431 /* Otherwise line segment passes through the right sub-region alone,
432 * so right-recurse.
433 */
434 bkg_region_subdivide( scene, scene->regions[region].region_right, vertex1, vertex2 );
435 break;
436 }
437 }
438 }
442 /**
443 * Compute the values for an array of vertexes, given x,y for each
444 * vertex and the base 3-vertex triple used to define the background
445 * plane. Essentially the base vertexes are used to find the
446 * plane equation for each of z,a,r,g,b,etc, which is then solved for
447 * each of the required compute vertexes (normally the corner points).
448 *
449 * @param base The 3 vertexes supplied as the background definition
450 * @param compute An array of vertexes to compute. x and y must be
451 * preset, other values are computed.
452 */
453 static void bkg_compute_scene( struct vertex_all *base, int width, int height,
454 struct bkg_scene *scene )
455 {
456 struct vertex_all center;
457 struct vertex_all diff0, diff1;
458 int i,k;
460 center.x = base[1].x;
461 center.y = base[1].y;
462 center.z = base[1].z;
463 diff0.x = base[0].x - base[1].x;
464 diff0.y = base[0].y - base[1].y;
465 diff0.z = base[0].z - base[1].z;
466 diff1.x = base[2].x - base[1].x;
467 diff1.y = base[2].y - base[1].y;
468 diff1.z = base[2].z - base[1].z;
470 float detxy = ((diff1.y) * (diff0.x)) - ((diff0.y) * (diff1.x));
472 /* Corner points first */
473 scene->vertexes[0].x = 0.0;
474 scene->vertexes[0].y = 0.0;
475 scene->vertexes[1].x = width;
476 scene->vertexes[1].y = 0.0;
477 scene->vertexes[2].x = width;
478 scene->vertexes[2].y = height;
479 scene->vertexes[3].x = 0.0;
480 scene->vertexes[3].y = height;
481 scene->regions[0].region_left = -1;
482 scene->regions[0].region_right = -1;
483 scene->num_vertexes = 4;
484 scene->num_regions = 1;
486 if( detxy == 0 ) {
487 /* The points lie on a single line - no plane for you. Use the values
488 * from the 3rd point for the whole screen.
489 */
490 for( i=0; i<4; i++ ) {
491 scene->vertexes[i].rgba[0] = base[2].rgba[0];
492 scene->vertexes[i].rgba[1] = base[2].rgba[1];
493 scene->vertexes[i].rgba[2] = base[2].rgba[2];
494 scene->vertexes[i].rgba[3] = base[2].rgba[3];
495 scene->vertexes[i].u = base[2].u;
496 scene->vertexes[i].v = base[2].v;
497 }
498 } else {
499 /* Compute the colour values at each corner */
500 center.rgba[0] = base[1].rgba[0];
501 center.rgba[1] = base[1].rgba[1];
502 center.rgba[2] = base[1].rgba[2];
503 center.rgba[3] = base[1].rgba[3];
504 diff0.rgba[0] = base[0].rgba[0] - center.rgba[0];
505 diff0.rgba[1] = base[0].rgba[1] - center.rgba[1];
506 diff0.rgba[2] = base[0].rgba[2] - center.rgba[2];
507 diff0.rgba[3] = base[0].rgba[3] - center.rgba[3];
508 diff0.u = base[0].u - center.u;
509 diff0.v = base[0].v - center.v;
510 diff1.rgba[0] = base[2].rgba[0] - center.rgba[0];
511 diff1.rgba[1] = base[2].rgba[1] - center.rgba[1];
512 diff1.rgba[2] = base[2].rgba[2] - center.rgba[2];
513 diff1.rgba[3] = base[2].rgba[3] - center.rgba[3];
514 diff1.u = base[2].u - center.u;
515 diff1.v = base[2].v - center.v;
516 for( i=0; i<4; i++ ) {
517 float t = ((scene->vertexes[i].x - center.x) * diff1.y -
518 (scene->vertexes[i].y - center.y) * diff1.x) / detxy;
519 float s = ((scene->vertexes[i].y - center.y) * diff0.x -
520 (scene->vertexes[i].x - center.x) * diff0.y) / detxy;
521 scene->vertexes[i].z = center.z + (t*diff0.z) + (s*diff1.z);
522 scene->vertexes[i].rgba[0] = center.rgba[0] + (t*diff0.rgba[0]) + (s*diff1.rgba[0]);
523 scene->vertexes[i].rgba[1] = center.rgba[1] + (t*diff0.rgba[1]) + (s*diff1.rgba[1]);
524 scene->vertexes[i].rgba[2] = center.rgba[2] + (t*diff0.rgba[2]) + (s*diff1.rgba[2]);
525 scene->vertexes[i].rgba[3] = center.rgba[3] + (t*diff0.rgba[3]) + (s*diff1.rgba[3]);
526 scene->vertexes[i].u = center.u + (t*diff0.u) + (s*diff1.u);
527 scene->vertexes[i].v = center.v + (t*diff0.v) + (s*diff1.v);
528 }
530 /* Check for values > 1.0 | < 0.0 */
531 for( k=0; k<4; k++ ) {
532 float detyk = ((diff1.y) * (diff0.rgba[k])) - ((diff0.y)*(diff1.rgba[k]));
533 float detxk = ((diff0.x) * (diff1.rgba[k])) - ((diff1.x)*(diff0.rgba[k]));
534 if( scene->vertexes[0].rgba[k] > 1.0 || scene->vertexes[1].rgba[k] > 1.0 ||
535 scene->vertexes[2].rgba[k] > 1.0 || scene->vertexes[3].rgba[k] > 1.0 ) {
536 int v1 = scene->num_vertexes;
537 scene->num_vertexes += compute_colour_line(center.x, center.y, center.rgba[k],
538 width, height, 1.0,
539 detxy, detxk, detyk,
540 scene->vertexes+scene->num_vertexes );
541 if( scene->num_vertexes != v1 ) {
542 bkg_region_subdivide( scene, 0, v1, v1+1 );
543 }
544 }
546 if( scene->vertexes[0].rgba[k] < 0.0 || scene->vertexes[1].rgba[k] < 0.0 ||
547 scene->vertexes[2].rgba[k] < 0.0 || scene->vertexes[3].rgba[k] < 0.0 ) {
548 int v1 = scene->num_vertexes;
549 scene->num_vertexes += compute_colour_line(center.x, center.y, center.rgba[k],
550 width, height, 0.0,
551 detxy, detxk, detyk,
552 scene->vertexes+scene->num_vertexes );
553 if( scene->num_vertexes != v1 ) {
554 bkg_region_subdivide( scene, 0, v1, v1+1 );
555 }
557 }
558 }
560 /* Finally compute the colour values for all vertexes
561 * (excluding the 4 we did upfront) */
562 for( i=4; i<scene->num_vertexes; i++ ) {
563 float t = ((scene->vertexes[i].x - center.x) * diff1.y -
564 (scene->vertexes[i].y - center.y) * diff1.x) / detxy;
565 float s = ((scene->vertexes[i].y - center.y) * diff0.x -
566 (scene->vertexes[i].x - center.x) * diff0.y) / detxy;
567 scene->vertexes[i].z = center.z + (t*diff0.z) + (s*diff1.z);
568 scene->vertexes[i].rgba[0] = center.rgba[0] + (t*diff0.rgba[0]) + (s*diff1.rgba[0]);
569 scene->vertexes[i].rgba[1] = center.rgba[1] + (t*diff0.rgba[1]) + (s*diff1.rgba[1]);
570 scene->vertexes[i].rgba[2] = center.rgba[2] + (t*diff0.rgba[2]) + (s*diff1.rgba[2]);
571 scene->vertexes[i].rgba[3] = center.rgba[3] + (t*diff0.rgba[3]) + (s*diff1.rgba[3]);
572 scene->vertexes[i].u = center.u + (t*diff0.u) + (s*diff1.u);
573 scene->vertexes[i].v = center.v + (t*diff0.v) + (s*diff1.v);
574 }
575 }
576 }
578 /**
579 * Render a bkg_region.
580 * @param scene the background scene data
581 * @param region the region to render
582 * @param vertexes the vertexes surrounding the region
583 * @param num_vertexes the number of vertexes in the vertex array
584 */
585 void bkg_render_region( struct bkg_scene *scene, int region, int *vertexes, int num_vertexes,
586 uint32_t poly1 )
587 {
588 if( scene->regions[region].region_left == -1 && scene->regions[region].region_right == -1 ) {
589 /* Leaf node - render the points as given */
590 int i,k;
591 glBegin(GL_POLYGON);
592 for( i=0; i<num_vertexes; i++ ) {
593 k = vertexes[i];
594 glColor4fv(scene->vertexes[k].rgba);
595 if( POLY1_TEXTURED(poly1) ) {
596 glTexCoord2f(scene->vertexes[k].u, scene->vertexes[k].v);
597 }
598 glVertex3f(scene->vertexes[k].x, scene->vertexes[k].y, scene->vertexes[k].z);
599 }
600 glEnd();
601 } else {
602 /* split the region into left and right regions */
603 int left_vertexes[num_vertexes+1];
604 int right_vertexes[num_vertexes+1];
605 int num_left = 0;
606 int num_right = 0;
607 struct bkg_region *reg = &scene->regions[region];
608 compute_subregions( scene, reg->vertex1, reg->vertex2, vertexes, num_vertexes,
609 left_vertexes, &num_left, right_vertexes, &num_right );
610 bkg_render_region( scene, reg->region_left, left_vertexes, num_left, poly1 );
611 bkg_render_region( scene, reg->region_right, right_vertexes, num_right, poly1 );
612 }
614 }
617 void render_backplane( uint32_t *polygon, uint32_t width, uint32_t height, uint32_t mode ) {
618 struct vertex_all vertex[3];
619 int screen_vertexes[4] = {0,1,2,3};
620 struct bkg_scene scene;
621 int i,j,k, num_vertexes;
623 parse_vertexes(polygon, 3, vertex);
624 render_set_context(polygon, 0);
625 glDisable(GL_CULL_FACE);
626 glDisable(GL_DEPTH_TEST);
627 glBlendFunc(GL_ONE, GL_ZERO); /* For now, just disable alpha blending on the bkg */
628 fwrite_dump32( polygon, 48, stderr );
629 bkg_compute_scene(vertex, width, height, &scene);
630 bkg_render_region(&scene, 0, screen_vertexes, 4, *polygon);
631 }
.