]> icculus.org git repositories - dana/openbox.git/blob - render2/paint.c
rendering fixes for gl
[dana/openbox.git] / render2 / paint.c
1 #include "render.h"
2 #include "surface.h"
3 #include "instance.h"
4 #include "debug.h"
5 #include <assert.h>
6 #include <stdlib.h>
7 #include <GL/glx.h>
8
9 struct ExposeArea {
10     struct RrSurface *sur;
11     int x;
12     int y;
13     int w;
14     int h;
15 };
16
17 #define MERGE_AREA(a, x, y, w, h) \
18             a->w = MAX(a->x + a->w - 1, x + w - 1) - MIN(a->x, x), \
19             a->h = MAX(a->y + a->h - 1, y + h - 1) - MIN(a->y, y), \
20             a->x = MIN(a->x, x), \
21             a->y = MIN(a->y, y)
22
23
24 void RrExpose(struct RrInstance *inst, XExposeEvent *e)
25 {
26     XEvent e2;
27     struct RrSurface *sur;
28     Window win;
29
30     win = e->window;
31
32     if ((sur = RrInstaceLookupSurface(inst, win))) {
33         while (1) {
34             struct RrSurface *p = NULL;
35
36             while (XCheckTypedWindowEvent(RrDisplay(inst), Expose,
37                                           sur->win, &e2));
38
39             switch (RrSurfaceType(sur)) {
40             case RR_SURFACE_NONE:
41                 break;
42             case RR_SURFACE_PLANAR:
43                 if (RrPlanarHasAlpha(sur))
44                     p = RrSurfaceParent(sur);
45                 break;
46             case RR_SURFACE_NONPLANAR:
47                 assert(0);
48             }
49
50             if (p) sur = p;
51             else break;
52         }
53         RrPaint(sur, 0);
54     } else
55         RrDebug("Unable to find surface for window 0x%lx\n", win);
56 }
57
58 /*! Paints the surface, and all its children */
59 void RrPaint(struct RrSurface *sur, int recurse_always)
60 {
61     struct RrInstance *inst;
62     struct RrSurface *p;
63     int ok, i;
64     int surx, sury;
65     GSList *it;
66
67     inst = RrSurfaceInstance(sur);
68
69     /* can't paint a prototype! */
70     assert(inst);
71     if (!inst) return;
72
73     if (!RrSurfaceVisible(sur)) return;
74
75     ok = glXMakeCurrent(RrDisplay(inst), RrSurfaceWindow(sur),RrContext(inst));
76     assert(ok);
77
78     glViewport(0, 0, RrScreenWidth(inst), RrScreenHeight(inst));
79 /*
80     glMatrixMode(GL_PROJECTION);
81     glLoadIdentity();
82     glOrtho(RrSurfaceX(sur), RrSurfaceX(sur) + RrSurfaceWidth(sur),
83             RrSurfaceY(sur), RrSurfaceY(sur) + RrSurfaceHeight(sur),
84             0, 10);
85     glMatrixMode(GL_MODELVIEW);
86     glViewport(0, 0, RrSurfaceWidth(sur), RrSurfaceHeight(sur));
87 */
88
89     glPushMatrix();
90     glTranslatef(-RrSurfaceX(sur),
91                  -RrSurfaceY(sur), 0);
92     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
93
94     p = sur;
95     surx = sury = 0;
96     while (p) {
97         surx += RrSurfaceX(p);
98         sury += RrSurfaceY(p);
99         p = p->parent;
100     }
101
102     switch (RrSurfaceType(sur)) {
103     case RR_SURFACE_PLANAR:
104         RrPlanarPaint(sur, surx, sury);
105         break;
106     case RR_SURFACE_NONPLANAR:
107         assert(0);
108         break;
109     case RR_SURFACE_NONE:
110         break;
111     }
112
113     for (i = 0; i < sur->ntextures; ++i)
114         RrTexturePaint(sur, &sur->texture[i]);
115
116     glPopMatrix();
117
118     glXSwapBuffers(RrDisplay(inst), RrSurfaceWindow(sur));
119
120     /* recurse and paint children */
121     for (it = RrSurfaceChildren(sur); it; it = g_slist_next(it)) {
122         if (recurse_always)
123             RrPaint(it->data, 1);
124         else {
125             switch (RrSurfaceType(((struct RrSurface*)it->data))) {
126             case RR_SURFACE_NONE:
127                 break;
128             case RR_SURFACE_PLANAR:
129                 if (RrPlanarHasAlpha(it->data))
130                     RrPaint(it->data, 0);
131                 break;
132             case RR_SURFACE_NONPLANAR:
133                 assert(0);
134                 break;
135             }
136         }
137     }
138 }