gl.h shouldn't be required when not enabling gl
[mikachu/openbox.git] / render / gradient.c
1 #ifdef USE_GL
2 #include <GL/gl.h>
3 #endif /* USE_GL */
4 #include <glib.h>
5 #include "render.h"
6 #include "gradient.h"
7 #include "../kernel/openbox.h"
8 #include "color.h"
9
10 void gradient_render(Surface *sf, int w, int h)
11 {
12     pixel32 *data = sf->data.planar.pixel_data;
13     pixel32 current;
14     unsigned int r,g,b;
15     int off, x;
16
17     switch (sf->data.planar.grad) {
18     case Background_Solid: /* already handled */
19         return;
20     case Background_Vertical:
21         gradient_vertical(sf, w, h);
22         break;
23     case Background_Horizontal:
24         gradient_horizontal(sf, w, h);
25         break;
26     case Background_Diagonal:
27         gradient_diagonal(sf, w, h);
28         break;
29     case Background_CrossDiagonal:
30         gradient_crossdiagonal(sf, w, h);
31         break;
32     case Background_Pyramid:
33         gradient_pyramid(sf, w, h);
34         break;
35     case Background_PipeCross:
36         gradient_pipecross(sf, w, h);
37         break;
38     case Background_Rectangle:
39         gradient_rectangle(sf, w, h);
40         break;
41     default:
42         g_message("unhandled gradient");
43         return;
44     }
45   
46     if (sf->data.planar.relief == Flat && sf->data.planar.border) {
47         r = sf->data.planar.border_color->r;
48         g = sf->data.planar.border_color->g;
49         b = sf->data.planar.border_color->b;
50         current = (r << default_red_offset)
51             + (g << default_green_offset)
52             + (b << default_blue_offset);
53         for (off = 0, x = 0; x < w; ++x, off++) {
54             *(data + off) = current;
55             *(data + off + ((h-1) * w)) = current;
56         }
57         for (off = 0, x = 0; x < h; ++x, off++) {
58             *(data + (off * w)) = current;
59             *(data + (off * w) + w - 1) = current;
60         }
61     }
62
63     if (sf->data.planar.relief != Flat) {
64         if (sf->data.planar.bevel == Bevel1) {
65             for (off = 1, x = 1; x < w - 1; ++x, off++)
66                 highlight(data + off,
67                           data + off + (h-1) * w,
68                           sf->data.planar.relief==Raised);
69             for (off = 0, x = 0; x < h; ++x, off++)
70                 highlight(data + off * w,
71                           data + off * w + w - 1,
72                           sf->data.planar.relief==Raised);
73         }
74
75         if (sf->data.planar.bevel == Bevel2) {
76             for (off = 2, x = 2; x < w - 2; ++x, off++)
77                 highlight(data + off + w,
78                           data + off + (h-2) * w,
79                           sf->data.planar.relief==Raised);
80             for (off = 1, x = 1; x < h-1; ++x, off++)
81                 highlight(data + off * w + 1,
82                           data + off * w + w - 2,
83                           sf->data.planar.relief==Raised);
84         }
85     }
86 }
87
88
89
90 void gradient_vertical(Surface *sf, int w, int h)
91 {
92     pixel32 *data = sf->data.planar.pixel_data;
93     pixel32 current;
94     float dr, dg, db;
95     unsigned int r,g,b;
96     int x, y;
97
98     dr = (float)(sf->data.planar.secondary->r - sf->data.planar.primary->r);
99     dr/= (float)h;
100
101     dg = (float)(sf->data.planar.secondary->g - sf->data.planar.primary->g);
102     dg/= (float)h;
103
104     db = (float)(sf->data.planar.secondary->b - sf->data.planar.primary->b);
105     db/= (float)h;
106
107     for (y = 0; y < h; ++y) {
108         r = sf->data.planar.primary->r + (int)(dr * y);
109         g = sf->data.planar.primary->g + (int)(dg * y);
110         b = sf->data.planar.primary->b + (int)(db * y);
111         current = (r << default_red_offset)
112             + (g << default_green_offset)
113             + (b << default_blue_offset);
114         for (x = 0; x < w; ++x, ++data)
115             *data = current;
116     }
117 }
118
119 void gradient_horizontal(Surface *sf, int w, int h)
120 {
121     pixel32 *data = sf->data.planar.pixel_data;
122     pixel32 current;
123     float dr, dg, db;
124     unsigned int r,g,b;
125     int x, y;
126
127     dr = (float)(sf->data.planar.secondary->r - sf->data.planar.primary->r);
128     dr/= (float)w;
129
130     dg = (float)(sf->data.planar.secondary->g - sf->data.planar.primary->g);
131     dg/= (float)w;
132
133     db = (float)(sf->data.planar.secondary->b - sf->data.planar.primary->b);
134     db/= (float)w;
135
136     for (x = 0; x < w; ++x, ++data) {
137         r = sf->data.planar.primary->r + (int)(dr * x);
138         g = sf->data.planar.primary->g + (int)(dg * x);
139         b = sf->data.planar.primary->b + (int)(db * x);
140         current = (r << default_red_offset)
141             + (g << default_green_offset)
142             + (b << default_blue_offset);
143         for (y = 0; y < h; ++y)
144             *(data + y*w) = current;
145     }
146 }
147
148 void gradient_diagonal(Surface *sf, int w, int h)
149 {
150     pixel32 *data = sf->data.planar.pixel_data;
151     pixel32 current;
152     float drx, dgx, dbx, dry, dgy, dby;
153     unsigned int r,g,b;
154     int x, y;
155
156     for (y = 0; y < h; ++y) {
157         drx = (float)(sf->data.planar.secondary->r -
158                       sf->data.planar.primary->r);
159         dry = drx/(float)h;
160         drx/= (float)w;
161
162         dgx = (float)(sf->data.planar.secondary->g -
163                       sf->data.planar.primary->g);
164         dgy = dgx/(float)h;
165         dgx/= (float)w;
166
167         dbx = (float)(sf->data.planar.secondary->b -
168                       sf->data.planar.primary->b);
169         dby = dbx/(float)h;
170         dbx/= (float)w;
171         for (x = 0; x < w; ++x, ++data) {
172             r = sf->data.planar.primary->r +
173                 ((int)(drx * x) + (int)(dry * y))/2;
174             g = sf->data.planar.primary->g +
175                 ((int)(dgx * x) + (int)(dgy * y))/2;
176             b = sf->data.planar.primary->b +
177                 ((int)(dbx * x) + (int)(dby * y))/2;
178             current = (r << default_red_offset)
179                 + (g << default_green_offset)
180                 + (b << default_blue_offset);
181             *data = current;
182         }
183     }
184 }
185
186 void gradient_crossdiagonal(Surface *sf, int w, int h)
187 {
188     pixel32 *data = sf->data.planar.pixel_data;
189     pixel32 current;
190     float drx, dgx, dbx, dry, dgy, dby;
191     unsigned int r,g,b;
192     int x, y;
193
194     for (y = 0; y < h; ++y) {
195         drx = (float)(sf->data.planar.secondary->r -
196                       sf->data.planar.primary->r);
197         dry = drx/(float)h;
198         drx/= (float)w;
199
200         dgx = (float)(sf->data.planar.secondary->g -
201                       sf->data.planar.primary->g);
202         dgy = dgx/(float)h;
203         dgx/= (float)w;
204
205         dbx = (float)(sf->data.planar.secondary->b -
206                       sf->data.planar.primary->b);
207         dby = dbx/(float)h;
208         dbx/= (float)w;
209         for (x = w; x > 0; --x, ++data) {
210             r = sf->data.planar.primary->r +
211                 ((int)(drx * (x-1)) + (int)(dry * y))/2;
212             g = sf->data.planar.primary->g +
213                 ((int)(dgx * (x-1)) + (int)(dgy * y))/2;
214             b = sf->data.planar.primary->b +
215                 ((int)(dbx * (x-1)) + (int)(dby * y))/2;
216             current = (r << default_red_offset)
217                 + (g << default_green_offset)
218                 + (b << default_blue_offset);
219             *data = current;
220         }
221     }
222 }
223
224 void highlight(pixel32 *x, pixel32 *y, gboolean raised)
225 {
226     int r, g, b;
227
228     pixel32 *up, *down;
229     if (raised) {
230         up = x;
231         down = y;
232     } else {
233         up = y;
234         down = x;
235     }
236     r = (*up >> default_red_offset) & 0xFF;
237     r += r >> 1;
238     g = (*up >> default_green_offset) & 0xFF;
239     g += g >> 1;
240     b = (*up >> default_blue_offset) & 0xFF;
241     b += b >> 1;
242     if (r > 0xFF) r = 0xFF;
243     if (g > 0xFF) g = 0xFF;
244     if (b > 0xFF) b = 0xFF;
245     *up = (r << default_red_offset) + (g << default_green_offset)
246         + (b << default_blue_offset);
247   
248     r = (*down >> default_red_offset) & 0xFF;
249     r = (r >> 1) + (r >> 2);
250     g = (*down >> default_green_offset) & 0xFF;
251     g = (g >> 1) + (g >> 2);
252     b = (*down >> default_blue_offset) & 0xFF;
253     b = (b >> 1) + (b >> 2);
254     *down = (r << default_red_offset) + (g << default_green_offset)
255         + (b << default_blue_offset);
256 }
257
258 static void create_bevel_colors(Appearance *l)
259 {
260     int r, g, b;
261
262     /* light color */
263     r = l->surface.data.planar.primary->r;
264     r += r >> 1;
265     g = l->surface.data.planar.primary->g;
266     g += g >> 1;
267     b = l->surface.data.planar.primary->b;
268     b += b >> 1;
269     if (r > 0xFF) r = 0xFF;
270     if (g > 0xFF) g = 0xFF;
271     if (b > 0xFF) b = 0xFF;
272     g_assert(!l->surface.data.planar.bevel_light);
273     l->surface.data.planar.bevel_light = color_new(r, g, b);
274     color_allocate_gc(l->surface.data.planar.bevel_light);
275
276     /* dark color */
277     r = l->surface.data.planar.primary->r;
278     r = (r >> 1) + (r >> 2);
279     g = l->surface.data.planar.primary->g;
280     g = (g >> 1) + (g >> 2);
281     b = l->surface.data.planar.primary->b;
282     b = (b >> 1) + (b >> 2);
283     g_assert(!l->surface.data.planar.bevel_dark);
284     l->surface.data.planar.bevel_dark = color_new(r, g, b);
285     color_allocate_gc(l->surface.data.planar.bevel_dark);
286 }
287
288 void gradient_solid(Appearance *l, int x, int y, int w, int h) 
289 {
290     pixel32 pix;
291     int i, a, b;
292     PlanarSurface *sp = &l->surface.data.planar;
293     int left = x, top = y, right = x + w - 1, bottom = y + h - 1;
294
295     if (sp->primary->gc == None)
296         color_allocate_gc(sp->primary);
297     pix = (sp->primary->r << default_red_offset)
298         + (sp->primary->g << default_green_offset)
299         + (sp->primary->b << default_blue_offset);
300
301     for (a = 0; a < l->area.width; a++)
302         for (b = 0; b < l->area.height; b++)
303             sp->pixel_data[a + b*l->area.width] = pix;
304
305     XFillRectangle(ob_display, l->pixmap, sp->primary->gc,
306                    x, y, w, h);
307
308     if (sp->interlaced) {
309         if (sp->secondary->gc == None)
310             color_allocate_gc(sp->secondary);
311         for (i = y; i < h; i += 2)
312             XDrawLine(ob_display, l->pixmap, sp->secondary->gc,
313                       x, i, w, i);
314     }
315
316     switch (sp->relief) {
317     case Raised:
318         if (!sp->bevel_dark)
319             create_bevel_colors(l);
320
321         switch (sp->bevel) {
322         case Bevel1:
323             XDrawLine(ob_display, l->pixmap, sp->bevel_dark->gc,
324                       left, bottom, right, bottom);
325             XDrawLine(ob_display, l->pixmap, sp->bevel_dark->gc,
326                       right, bottom, right, top);
327                 
328             XDrawLine(ob_display, l->pixmap, sp->bevel_light->gc,
329                       left, top, right, top);
330             XDrawLine(ob_display, l->pixmap, sp->bevel_light->gc,
331                       left, bottom, left, top);
332             break;
333         case Bevel2:
334             XDrawLine(ob_display, l->pixmap,
335                       sp->bevel_dark->gc,
336                       left + 1, bottom - 2, right - 2, bottom - 2);
337             XDrawLine(ob_display, l->pixmap,
338                       sp->bevel_dark->gc,
339                       right - 2, bottom - 2, right - 2, top + 1);
340
341             XDrawLine(ob_display, l->pixmap,
342                       sp->bevel_light->gc,
343                       left + 1, top + 1, right - 2, top + 1);
344             XDrawLine(ob_display, l->pixmap,
345                       sp->bevel_light->gc,
346                       left + 1, bottom - 2, left + 1, top + 1);
347             break;
348         default:
349             g_assert_not_reached(); /* unhandled BevelType */
350         }
351         break;
352     case Sunken:
353         if (!sp->bevel_dark)
354             create_bevel_colors(l);
355
356         switch (sp->bevel) {
357         case Bevel1:
358             XDrawLine(ob_display, l->pixmap, sp->bevel_light->gc,
359                       left, bottom, right, bottom);
360             XDrawLine(ob_display, l->pixmap, sp->bevel_light->gc,
361                       right, bottom, right, top);
362       
363             XDrawLine(ob_display, l->pixmap, sp->bevel_dark->gc,
364                       left, top, right, top);
365             XDrawLine(ob_display, l->pixmap, sp->bevel_dark->gc,
366                       left, bottom, left, top);
367             break;
368         case Bevel2:
369             XDrawLine(ob_display, l->pixmap, sp->bevel_light->gc,
370                       left + 1, bottom - 2, right - 2, bottom - 2);
371             XDrawLine(ob_display, l->pixmap, sp->bevel_light->gc,
372                       right - 2, bottom - 2, right - 2, top + 1);
373       
374             XDrawLine(ob_display, l->pixmap, sp->bevel_dark->gc,
375                       left + 1, top + 1, right - 2, top + 1);
376             XDrawLine(ob_display, l->pixmap, sp->bevel_dark->gc,
377                       left + 1, bottom - 2, left + 1, top + 1);
378
379             break;
380         default:
381             g_assert_not_reached(); /* unhandled BevelType */
382         }
383         break;
384     case Flat:
385         if (sp->border) {
386             if (sp->border_color->gc == None)
387                 color_allocate_gc(sp->border_color);
388             XDrawRectangle(ob_display, l->pixmap, sp->border_color->gc,
389                            left, top, right, bottom);
390         }
391         break;
392     default:  
393         g_assert_not_reached(); /* unhandled ReliefType */
394     }
395 }
396
397 void gradient_pyramid(Surface *sf, int inw, int inh)
398 {
399     pixel32 *data = sf->data.planar.pixel_data;
400     pixel32 *end = data + inw*inh - 1;
401     pixel32 current;
402     float drx, dgx, dbx, dry, dgy, dby;
403     unsigned int r,g,b;
404     int x, y, h=(inh/2) + 1, w=(inw/2) + 1;
405     for (y = 0; y < h; ++y) {
406         drx = (float)(sf->data.planar.secondary->r -
407                       sf->data.planar.primary->r);
408         dry = drx/(float)h;
409         drx/= (float)w;
410
411         dgx = (float)(sf->data.planar.secondary->g -
412                       sf->data.planar.primary->g);
413         dgy = dgx/(float)h;
414         dgx/= (float)w;
415
416         dbx = (float)(sf->data.planar.secondary->b -
417                       sf->data.planar.primary->b);
418         dby = dbx/(float)h;
419         dbx/= (float)w;
420         for (x = 0; x < w; ++x, data) {
421             r = sf->data.planar.primary->r +
422                 ((int)(drx * x) + (int)(dry * y))/2;
423             g = sf->data.planar.primary->g +
424                 ((int)(dgx * x) + (int)(dgy * y))/2;
425             b = sf->data.planar.primary->b +
426                 ((int)(dbx * x) + (int)(dby * y))/2;
427             current = (r << default_red_offset)
428                 + (g << default_green_offset)
429                 + (b << default_blue_offset);
430             *(data+x) = current;
431             *(data+inw-x) = current;
432             *(end-x) = current;
433             *(end-(inw-x)) = current;
434         }
435         data+=inw;
436         end-=inw;
437     }
438 }
439
440 void gradient_rectangle(Surface *sf, int inw, int inh)
441 {
442     pixel32 *data = sf->data.planar.pixel_data;
443     pixel32 *end = data + inw*inh - 1;
444     pixel32 current;
445     float drx, dgx, dbx, dry, dgy, dby;
446     unsigned int r,g,b;
447     int x, y, h=(inh/2) + 1, w=(inw/2) + 1;
448     int val;
449
450     for (y = 0; y < h; ++y) {
451         drx = (float)(sf->data.planar.primary->r -
452                       sf->data.planar.secondary->r);
453         dry = drx/(float)h;
454         drx/= (float)w;
455
456         dgx = (float)(sf->data.planar.primary->g -
457                       sf->data.planar.secondary->g);
458         dgy = dgx/(float)h;
459         dgx/= (float)w;
460
461         dbx = (float)(sf->data.planar.primary->b -
462                       sf->data.planar.secondary->b);
463         dby = dbx/(float)h;
464         dbx/= (float)w;
465         for (x = 0; x < w; ++x, data) {
466             if ((float)x/(float)w < (float)y/(float)h) val = (int)(drx * x);
467             else val = (int)(dry * y);
468
469             r = sf->data.planar.secondary->r + val;
470             g = sf->data.planar.secondary->g + val;
471             b = sf->data.planar.secondary->b + val;
472             current = (r << default_red_offset)
473                 + (g << default_green_offset)
474                 + (b << default_blue_offset);
475             *(data+x) = current;
476             *(data+inw-x) = current;
477             *(end-x) = current;
478             *(end-(inw-x)) = current;
479         }
480         data+=inw;
481         end-=inw;
482     }
483 }
484
485 void gradient_pipecross(Surface *sf, int inw, int inh)
486 {
487     pixel32 *data = sf->data.planar.pixel_data;
488     pixel32 *end = data + inw*inh - 1;
489     pixel32 current;
490     float drx, dgx, dbx, dry, dgy, dby;
491     unsigned int r,g,b;
492     int x, y, h=(inh/2) + 1, w=(inw/2) + 1;
493     int val;
494
495     for (y = 0; y < h; ++y) {
496         drx = (float)(sf->data.planar.secondary->r -
497                       sf->data.planar.primary->r);
498         dry = drx/(float)h;
499         drx/= (float)w;
500
501         dgx = (float)(sf->data.planar.secondary->g -
502                       sf->data.planar.primary->g);
503         dgy = dgx/(float)h;
504         dgx/= (float)w;
505
506         dbx = (float)(sf->data.planar.secondary->b -
507                       sf->data.planar.primary->b);
508         dby = dbx/(float)h;
509         dbx/= (float)w;
510         for (x = 0; x < w; ++x, data) {
511             if ((float)x/(float)w > (float)y/(float)h) val = (int)(drx * x);
512             else val = (int)(dry * y);
513
514             r = sf->data.planar.primary->r + val;
515             g = sf->data.planar.primary->g + val;
516             b = sf->data.planar.primary->b + val;
517             current = (r << default_red_offset)
518                 + (g << default_green_offset)
519                 + (b << default_blue_offset);
520             *(data+x) = current;
521             *(data+inw-x) = current;
522             *(end-x) = current;
523             *(end-(inw-x)) = current;
524         }
525         data+=inw;
526         end-=inw;
527     }
528 }
529 #ifdef USE_GL
530 void render_gl_gradient(Surface *sf, int x, int y, int w, int h)
531 {
532     float pr,pg,pb;
533     float sr, sg, sb;
534     float ar, ag, ab;
535
536     pr = (float)sf->data.planar.primary->r/255.0;
537     pg = (float)sf->data.planar.primary->g/255.0;
538     pb = (float)sf->data.planar.primary->b/255.0;
539     if (sf->data.planar.secondary) {
540         sr = (float)sf->data.planar.secondary->r/255.0;
541         sg = (float)sf->data.planar.secondary->g/255.0;
542         sb = (float)sf->data.planar.secondary->b/255.0;
543     }
544     switch (sf->data.planar.grad) {
545     case Background_Solid: /* already handled */
546         glBegin(GL_TRIANGLES);
547         glColor3f(pr, pg, pb);
548         glVertex2i(x, y);
549         glVertex2i(x+w, y);
550         glVertex2i(x+w, y+h);
551
552         glVertex2i(x+w, y+h);
553         glVertex2i(x, y+h);
554         glVertex2i(x, y);
555         glEnd();
556         return;
557     case Background_Horizontal:
558         glBegin(GL_TRIANGLES);
559         glColor3f(pr, pg, pb);
560         glVertex2i(x, y);
561         glColor3f(sr, sg, sb);
562         glVertex2i(x+w, y);
563         glVertex2i(x+w, y+h);
564
565         glVertex2i(x+w, y+h);
566         glColor3f(pr, pg, pb);
567         glVertex2i(x, y+h);
568         glVertex2i(x, y);
569         glEnd();
570         break;
571     case Background_Vertical:
572         glBegin(GL_TRIANGLES);
573         glColor3f(pr, pg, pb);
574         glVertex2i(x, y);
575         glVertex2i(x+w, y);
576         glColor3f(sr, sg, sb);
577         glVertex2i(x+w, y+h);
578
579         glVertex2i(x+w, y+h);
580         glVertex2i(x, y+h);
581         glColor3f(pr, pg, pb);
582         glVertex2i(x, y);
583         glEnd();
584         break;
585     case Background_Diagonal:
586         ar = (pr + sr) / 2.0;
587         ag = (pg + sg) / 2.0;
588         ab = (pb + sb) / 2.0;
589         glBegin(GL_TRIANGLES);
590         glColor3f(ar, ag, ab);
591         glVertex2i(x, y);
592         glColor3f(pr, pg, pb);
593         glVertex2i(x+w, y);
594         glColor3f(ar, ag, ab);
595         glVertex2i(x+w, y+h);
596
597         glColor3f(ar, ag, ab);
598         glVertex2i(x+w, y+h);
599         glColor3f(sr, sg, sb);
600         glVertex2i(x, y+h);
601         glColor3f(ar, ag, ab);
602         glVertex2i(x, y);
603         glEnd();
604         break;
605     case Background_CrossDiagonal:
606         ar = (pr + sr) / 2.0;
607         ag = (pg + sg) / 2.0;
608         ab = (pb + sb) / 2.0;
609         glBegin(GL_TRIANGLES);
610         glColor3f(pr, pg, pb);
611         glVertex2i(x, y);
612         glColor3f(ar, ag, ab);
613         glVertex2i(x+w, y);
614         glColor3f(sr, sg, sb);
615         glVertex2i(x+w, y+h);
616
617         glColor3f(sr, sg, sb);
618         glVertex2i(x+w, y+h);
619         glColor3f(ar, ag, ab);
620         glVertex2i(x, y+h);
621         glColor3f(pr, pg, pb);
622         glVertex2i(x, y);
623         glEnd();
624         break;
625     case Background_Pyramid:
626         ar = (pr + sr) / 2.0;
627         ag = (pg + sg) / 2.0;
628         ab = (pb + sb) / 2.0;
629         glBegin(GL_TRIANGLES);
630         glColor3f(pr, pg, pb);
631         glVertex2i(x, y);
632         glColor3f(sr, sg, sb);
633         glVertex2i(x+w/2, y+h/2);
634         glColor3f(ar, ag, ab);
635         glVertex2i(x, y+h/2);
636
637         glVertex2i(x, y+h/2);
638         glColor3f(sr, sg, sb);
639         glVertex2i(x+w/2, y+h/2);
640         glColor3f(pr, pg, pb);
641         glVertex2i(x, y+h);
642
643         glVertex2i(x, y+h);
644         glColor3f(sr, sg, sb);
645         glVertex2i(x+w/2, y+h/2);
646         glColor3f(ar, ag, ab);
647         glVertex2i(x+w/2, y+h);
648
649         glVertex2i(x+w/2, y+h);
650         glColor3f(sr, sg, sb);
651         glVertex2i(x+w/2, y+h/2);
652         glColor3f(pr, pg, pb);
653         glVertex2i(x+w, y+h);
654
655         glVertex2i(x+w, y+h);
656         glColor3f(sr, sg, sb);
657         glVertex2i(x+w/2, y+h/2);
658         glColor3f(ar, ag, ab);
659         glVertex2i(x+w, y+h/2);
660
661         glVertex2i(x+w, y+h/2);
662         glColor3f(sr, sg, sb);
663         glVertex2i(x+w/2, y+h/2);
664         glColor3f(pr, pg, pb);
665         glVertex2i(x+w, y);
666
667         glVertex2i(x+w, y);
668         glColor3f(sr, sg, sb);
669         glVertex2i(x+w/2, y+h/2);
670         glColor3f(ar, ag, ab);
671         glVertex2i(x+w/2, y);
672
673         glVertex2i(x+w/2, y);
674         glColor3f(sr, sg, sb);
675         glVertex2i(x+w/2, y+h/2);
676         glColor3f(pr, pg, pb);
677         glVertex2i(x, y);
678         glEnd();
679         break;
680     case Background_PipeCross:
681         glBegin(GL_TRIANGLES);
682         glColor3f(pr, pg, pb);
683         glVertex2i(x, y);
684         glColor3f(sr, sg, sb);
685         glVertex2i(x+w/2, y+h/2);
686         glVertex2i(x, y+h/2);
687
688         glVertex2i(x, y+h/2);
689         glVertex2i(x+w/2, y+h/2);
690         glColor3f(pr, pg, pb);
691         glVertex2i(x, y+h);
692
693         glVertex2i(x, y+h);
694         glColor3f(sr, sg, sb);
695         glVertex2i(x+w/2, y+h/2);
696         glVertex2i(x+w/2, y+h);
697
698         glVertex2i(x+w/2, y+h);
699         glVertex2i(x+w/2, y+h/2);
700         glColor3f(pr, pg, pb);
701         glVertex2i(x+w, y+h);
702
703         glVertex2i(x+w, y+h);
704         glColor3f(sr, sg, sb);
705         glVertex2i(x+w/2, y+h/2);
706         glVertex2i(x+w, y+h/2);
707
708         glVertex2i(x+w, y+h/2);
709         glVertex2i(x+w/2, y+h/2);
710         glColor3f(pr, pg, pb);
711         glVertex2i(x+w, y);
712
713         glVertex2i(x+w, y);
714         glColor3f(sr, sg, sb);
715         glVertex2i(x+w/2, y+h/2);
716         glVertex2i(x+w/2, y);
717
718         glVertex2i(x+w/2, y);
719         glVertex2i(x+w/2, y+h/2);
720         glColor3f(pr, pg, pb);
721         glVertex2i(x, y);
722         glEnd();
723         break;
724     case Background_Rectangle:
725         glBegin(GL_TRIANGLES);
726         glColor3f(pr, pg, pb);
727         glVertex2i(x, y);
728         glColor3f(sr, sg, sb);
729         glVertex2i(x+w/2, y+h/2);
730         glColor3f(pr, pg, pb);
731         glVertex2i(x, y+h);
732
733         glVertex2i(x, y+h);
734         glColor3f(sr, sg, sb);
735         glVertex2i(x+w/2, y+h/2);
736         glColor3f(pr, pg, pb);
737         glVertex2i(x+w, y+h);
738
739         glVertex2i(x+w, y+h);
740         glColor3f(sr, sg, sb);
741         glVertex2i(x+w/2, y+h/2);
742         glColor3f(pr, pg, pb);
743         glVertex2i(x+w, y);
744
745         glVertex2i(x+w, y);
746         glColor3f(sr, sg, sb);
747         glVertex2i(x+w/2, y+h/2);
748         glColor3f(pr, pg, pb);
749         glVertex2i(x, y);
750
751         glEnd();
752         break;
753     default:
754         g_message("unhandled gradient");
755         return;
756     }
757 }
758 #endif /* USE_GL */