Enable VSync (Fix bug 5296)
[dana/dcompmgr.git] / glxrender.c
index 1c5ad24..5b2d902 100644 (file)
@@ -10,6 +10,9 @@
 #include <assert.h>
 #include <stdlib.h>
 
+#include <X11/Xmd.h>
+#include <GL/glxproto.h>
+
 #include <GL/gl.h>
 #include <GL/glx.h>
 #include <GL/glxtokens.h>
@@ -27,6 +30,7 @@ static int plugin_id;
 
 typedef void (*BindEXTFunc)(Display *, GLXDrawable, int, const int *);
 typedef void (*ReleaseEXTFunc)(Display *, GLXDrawable, int);
+typedef int (*SwapIntervalSGIFunc)(int);
 
 typedef struct {
     void (*screen_paint)(d_screen_t *sc);
@@ -57,6 +61,14 @@ typedef struct {
     GLfloat *texcoords;
     GLint *vertices;
     int nrects;
+
+    xcb_xfixes_fetch_region_cookie_t ck_region;
+    int waiting_region;
+    int x_region;
+    int y_region;
+    int w_region;
+    int h_region;
+    int bw_region;
 } window_data_t;
 
 static gboolean glxrender_find_fb_config(d_screen_t *sc, data_t *d);
@@ -65,13 +77,16 @@ static void glxrender_paint(d_screen_t *sc);
 static void glxrender_root_pixmap_change(d_screen_t *sc);
 static void paint_root(d_screen_t *sc, data_t *d);
 static void paint_window(d_window_t *window, data_t *d, window_data_t *wd,
-                         gboolean opaque, int x, int y);
-static void paint_shadow(d_window_t *w, data_t *d, window_data_t *wd,
-                         int x, int y);
+                         int x, int y, GLfloat z);
+static void paint_shadow(data_t *d, window_data_t *wd, int x, int y,
+                         GLfloat z);
 static void glxrender_update_window_pixmap(d_window_t *w, data_t *d,
                                            window_data_t *wd);
+static void glxrender_fetch_window_region(d_window_t *w, window_data_t *wd);
+static void glxrender_update_window_region(d_window_t *w, window_data_t *wd);
 static void glxrender_free_window_pixmap(d_window_t *w, data_t *d,
                                          window_data_t *wd);
+static void glxrender_free_window_region(window_data_t *wd);
 static void glxrender_free_root_pixmap(d_screen_t *sc, data_t *d);
 static void glxrender_update_root_pixmap(d_screen_t *sc, data_t *d);
 
@@ -120,15 +135,14 @@ glxrender_init(d_screen_t *sc, int id)
         exit(1);
     }
 
-    d->context = glXCreateContext(sc->dpy->xlib_dpy, vi, NULL, GL_TRUE);
-    glXMakeCurrent(sc->dpy->xlib_dpy, sc->overlay, d->context);
-
-
     if (!(glxrender_find_fb_config(sc, d))) {
         printf("unable to find FB configs\n");
         exit(1);
     }
 
+    d->context = glXCreateContext(sc->dpy->xlib_dpy, vi, NULL, GL_TRUE);
+    glXMakeCurrent(sc->dpy->xlib_dpy, sc->overlay, d->context);
+
     glViewport(0, 0, sc->super->width_in_pixels, sc->super->height_in_pixels);
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
@@ -137,13 +151,17 @@ glxrender_init(d_screen_t *sc, int id)
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
     glEnable(GL_TEXTURE_2D);
+    glEnable(GL_DEPTH_TEST);
+    //glEnable(GL_SCISSOR_TEST); ?? what is this, glxcompmgr enables it
+    //glEnable(GL_STENCIL_TEST); ?? what is this, glxcompmgr enables it
 
     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
     glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
     glDisable(GL_BLEND);
 
     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
-    glClear(GL_COLOR_BUFFER_BIT);
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
     glXSwapBuffers(sc->dpy->xlib_dpy, sc->overlay);
 
     d->bind_func = (BindEXTFunc)
@@ -151,6 +169,11 @@ glxrender_init(d_screen_t *sc, int id)
     d->release_func = (ReleaseEXTFunc)
         glXGetProcAddress((const guchar*)"glXReleaseTexImageEXT");
 
+    SwapIntervalSGIFunc swap_interval_func = (SwapIntervalSGIFunc)
+        glXGetProcAddress((const guchar*)"glXSwapIntervalSGI");
+    if(swap_interval_func)
+        swap_interval_func(1);
+
     glGenTextures(1, &d->root_texname);
     d->root_glpixmap = XCB_NONE;
 }
@@ -188,7 +211,7 @@ glxrender_find_fb_config(d_screen_t *sc, data_t *d)
         stencil = 32767;
         depth = 32767;
 
-        printf("looking for depth %d\n", i);
+        //printf("looking for depth %d\n", i);
 
         tvis.depth = i;
         visinfo = XGetVisualInfo(sc->dpy->xlib_dpy, VisualDepthMask,
@@ -245,8 +268,11 @@ void
 glxrender_free(d_screen_t *sc)
 {
     data_t *d = screen_find_plugin_data(sc, plugin_id);
-    glxrender_free_root_pixmap(sc, d);
-    free(d);
+    if (d) {
+        glxrender_free_root_pixmap(sc, d);
+        glXDestroyContext(sc->dpy->xlib_dpy, d->context);
+        free(d);
+    }
     screen_remove_plugin_data(sc, plugin_id);
 }
 
@@ -268,6 +294,7 @@ void
 glxrender_window_free_data(d_window_t *w, data_t *d, window_data_t *wd)
 {
     glxrender_free_window_pixmap(w, d, wd);
+    glxrender_free_window_region(wd);
     glDeleteTextures(1, &wd->texname);
     free(wd);
 }
@@ -284,17 +311,22 @@ glxrender_window_show(d_window_t *w)
     d->window_show(w);
 
     wd = window_find_plugin_data(w, plugin_id);
-    if (wd)
+    if (wd) {
         glxrender_window_free_data(w, d, wd);
-   
+        window_remove_plugin_data(w, plugin_id);
+    }
+
     wd = malloc(sizeof(window_data_t));
     glGenTextures(1, &wd->texname);
     wd->glpixmap = XCB_NONE;
+    wd->texcoords = NULL;
+    wd->vertices = NULL;
     wd->nrects = 0;
+    wd->waiting_region = FALSE;
 
     window_add_plugin_data(w, plugin_id, wd);
 
-    glxrender_update_window_pixmap(w, d, wd);
+    glxrender_fetch_window_region(w, wd);
 }
 
 static void
@@ -324,12 +356,20 @@ glxrender_free_window_pixmap(d_window_t *w, data_t *d, window_data_t *wd)
                         wd->glpixmap, GLX_FRONT_LEFT_EXT);
         glBindTexture(GL_TEXTURE_2D, 0);
 
-        //xcb_glx_destroy_pixmap(w->sc->dpy->conn, wd->glpixmap);
         glXDestroyPixmap(w->sc->dpy->xlib_dpy, wd->glpixmap);
         wd->glpixmap = XCB_NONE;
 
+    }
+}
+
+static void
+glxrender_free_window_region(window_data_t *wd)
+{
+    if (wd->nrects) {
         free(wd->texcoords);
         free(wd->vertices);
+        wd->texcoords = NULL;
+        wd->vertices = NULL;
         wd->nrects = 0;
     }
 }
@@ -344,7 +384,6 @@ glxrender_free_root_pixmap(d_screen_t *sc, data_t *d)
                         d->root_glpixmap, GLX_FRONT_LEFT_EXT);
         glBindTexture(GL_TEXTURE_2D, 0);
 
-        //xcb_glx_destroy_pixmap(w->sc->dpy->conn, wd->glpixmap);
         glXDestroyPixmap(sc->dpy->xlib_dpy, d->root_glpixmap);
         d->root_glpixmap = XCB_NONE;
     }
@@ -380,11 +419,55 @@ glxrender_update_window_pixmap(d_window_t *w, data_t *d, window_data_t *wd)
     wd->glpixmap = glXCreatePixmap(w->sc->dpy->xlib_dpy,
                                    d->fbconfig[depth],
                                    px, attrs);
-
+#if 0
+    wd->glpixmap = xcb_generate_id(w->sc->dpy->conn);
+    int v;
+    glXGetFBConfigAttrib(w->sc->dpy->xlib_dpy, d->fbconfig[depth],
+                         GLX_FBCONFIG_ID, &v);
+    xcb_void_cookie_t ck =
+        xcb_glx_create_pixmap_checked(w->sc->dpy->conn, w->sc->num,
+                                      v,
+                                      px, wd->glpixmap,
+                                      2,
+                                      attrs);
+    xcb_generic_error_t *err = xcb_request_check(w->sc->dpy->conn, ck);
+    if (err) {
+        display_error(w->sc->dpy, err);
+        free(err);
+        wd->glpixmap = XCB_NONE;
+        return;
+    }
+#endif
 
     glBindTexture(GL_TEXTURE_2D, wd->texname);
     d->bind_func(w->sc->dpy->xlib_dpy,
                  wd->glpixmap, GLX_FRONT_LEFT_EXT, NULL);
+#if 0
+    {
+        /*
+          BindTexImageEXT
+          1           CARD8                   opcode (X assigned)
+          1           16                      GLX opcode (glXVendorPrivate)
+          2           6+n                     request length
+          4           1330                    vendor specific opcode
+          4           CARD32                  context tag
+          4           GLX_DRAWABLE            drawable
+          4           INT32                   buffer
+          4           CARD32                  num_attributes
+          4*n         LISTofATTRIBUTE_PAIR    attribute, value pairs.
+        */
+        unsigned int len = 12;
+        uint32_t data[] = {
+            wd->glpixmap,
+            GLX_FRONT_LEFT_EXT,
+            0,
+        };
+        xcb_glx_vendor_private(w->sc->dpy->conn,
+                               X_GLXvop_BindTexImageEXT,
+                               1,
+                               len, (uint8_t*)data);
+    }
+#endif
 
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
@@ -393,26 +476,72 @@ glxrender_update_window_pixmap(d_window_t *w, data_t *d, window_data_t *wd)
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 
     glBindTexture(GL_TEXTURE_2D, 0);
+}
 
-    {
-        int x, y, width, height, bwidth;
+static void
+glxrender_fetch_window_region(d_window_t *w, window_data_t *wd)
+{
+    window_get_area(w, &wd->x_region, &wd->y_region,
+                    &wd->w_region, &wd->h_region, &wd->bw_region);
+
+    wd->ck_region =
+        xcb_xfixes_fetch_region_unchecked(w->sc->dpy->conn,
+                                          window_get_region(w));
+    wd->waiting_region = TRUE;
+    xcb_flush(w->sc->dpy->conn);
+}
+
+static void
+glxrender_update_window_region(d_window_t *w, window_data_t *wd)
+{
+    xcb_xfixes_fetch_region_reply_t *rep;
+    xcb_rectangle_t area, *rects;
+    int nrects, i, j;
 
-        window_get_area(w, &x, &y, &width, &height, &bwidth);
+    if (!wd->waiting_region) return;
 
-        wd->texcoords = (GLfloat*)malloc(sizeof(GLfloat) * 4);
-        wd->texcoords[LEFT] = 0.0f;
-        wd->texcoords[TOP] = 0.0f;
-        wd->texcoords[RIGHT] = 1.0f;
-        wd->texcoords[BOTTOM] = 1.0f;
+    area.x = wd->x_region;
+    area.y = wd->y_region;
+    area.width = wd->w_region + wd->bw_region * 2;
+    area.height = wd->h_region + wd->bw_region * 2;
 
-        wd->vertices = (GLint*)malloc(sizeof(GLint) * 4);
-        wd->vertices[LEFT] = 0;
-        wd->vertices[TOP] = 0;
-        wd->vertices[RIGHT] = width + bwidth;
-        wd->vertices[BOTTOM] = height + bwidth;
+    rep = xcb_xfixes_fetch_region_reply(w->sc->dpy->conn, wd->ck_region, NULL);
+    if (!rep) {
+        rects = &area;
+        nrects = 1;
+    }
+    else {
+        rects = xcb_xfixes_fetch_region_rectangles(rep);
+        nrects = xcb_xfixes_fetch_region_rectangles_length(rep);
+    }
 
-        wd->nrects = 1;
+    wd->texcoords = (GLfloat*)realloc(wd->texcoords,
+                                      sizeof(GLfloat) * (nrects * 4));
+    wd->vertices = (GLint*)realloc(wd->vertices, sizeof(GLint) * (nrects * 4));
+    wd->nrects = nrects;
+
+    for (i = j = 0; i < nrects * 4; ++j, i += 4) {
+        wd->texcoords[i+LEFT] =
+            (GLfloat)(rects[j].x - area.x) / (GLfloat)area.width;
+        wd->texcoords[i+TOP] =
+            (GLfloat)(rects[j].y - area.y) / (GLfloat)area.height;
+        wd->texcoords[i+RIGHT] =
+            (GLfloat)(rects[j].x - area.x + rects[j].width) /
+            (GLfloat)area.width;
+        wd->texcoords[i+BOTTOM] =
+            (GLfloat)(rects[j].y - area.y + rects[j].height) /
+            (GLfloat)area.height;
+
+        wd->vertices[i+LEFT] = rects[j].x - area.x;
+        wd->vertices[i+TOP] = rects[j].y - area.y;
+        wd->vertices[i+RIGHT] = rects[j].x - area.x + rects[j].width;
+        wd->vertices[i+BOTTOM] = rects[j].y - area.y + rects[j].height;
     }
+
+    if (rep)
+        free(rep);
+
+    wd->waiting_region = FALSE;
 }
 
 static void
@@ -465,7 +594,7 @@ glxrender_window_resize(d_window_t *w)
 
     assert(wd != NULL);
     glxrender_free_window_pixmap(w, d, wd);
-    glxrender_update_window_pixmap(w, d, wd);
+    glxrender_fetch_window_region(w, wd);
 }
 
 static void
@@ -481,8 +610,8 @@ glxrender_window_reshape(d_window_t *w)
     d->window_reshape(w);
 
     assert(wd != NULL);
-    glxrender_free_window_pixmap(w, d, wd);
-    glxrender_update_window_pixmap(w, d, wd);
+    //glxrender_free_window_pixmap(w, d, wd);
+    glxrender_fetch_window_region(w, wd);
 }
 
 static void
@@ -502,11 +631,55 @@ glxrender_paint(d_screen_t *sc)
 {
     data_t *d = screen_find_plugin_data(sc, plugin_id);
     d_list_it_t *it;
+    GLfloat z;
 
     //printf("painting\n");
 
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+    /* add 0.1f to keep everything above the root */
+    z = list_length(sc->stacking) * 0.1f + 0.1f;
+    for (it = list_top(sc->stacking); it; it = it->next) {
+        d_window_t *w = it->data;
+
+        if (!window_is_input_only(w) &&
+            (window_is_mapped(w) || window_is_zombie(w)))
+        {
+            int x, y, width, height, bwidth;
+            gboolean opaque;
+            window_data_t *wd;
+
+            window_get_area(w, &x, &y, &width, &height, &bwidth);
+
+            if (!(x < sc->super->width_in_pixels &&
+                  y < sc->super->height_in_pixels &&
+                  (x + width > 0 || x + width + d->xshadowoff > 0) &&
+                  (y + height > 0 || y + height + d->yshadowoff > 0)))
+            {
+                continue;
+            }
+
+            opaque = !window_is_argb(w) && window_get_opacity(w) == 0xffff;
+
+            if (opaque) {
+                wd = window_find_plugin_data(w, plugin_id);
+
+                //glPushMatrix();
+
+                paint_window(w, d, wd, x, y, z - 0.05f);
+
+                //glPopMatrix();
+            }
+
+            z -= 0.1f;
+        }
+    }
+
     paint_root(sc, d);
 
+    glEnable(GL_BLEND);
+    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
     for (it = list_bottom(sc->stacking); it; it = it->prev) {
         d_window_t *w = it->data;
 
@@ -516,6 +689,8 @@ glxrender_paint(d_screen_t *sc)
             int x, y, width, height, bwidth;
             gboolean opaque;
             window_data_t *wd;
+            uint16_t opac;
+            GLfloat alpha;
 
             window_get_area(w, &x, &y, &width, &height, &bwidth);
 
@@ -527,25 +702,37 @@ glxrender_paint(d_screen_t *sc)
                 continue;
             }
 
-            opaque = !window_is_argb(w) && window_get_opacity(w) == 0xffff;
+            opac = window_get_opacity(w);
+            opaque = !window_is_argb(w) && opac == 0xffff;
 
             wd = window_find_plugin_data(w, plugin_id);
 
-            glPushMatrix();
-
-            glTranslatef(d->xshadowoff, d->yshadowoff, 0.0f);
-            paint_shadow(w, d, wd, x, y);
+            /* black shadow */
+            alpha = d->shadowalpha;
+            alpha *= opac;
+            alpha /= 0xffff;
+            if (alpha >= 0.01) {
+                glColor4f(0.0f, 0.0f, 0.0f, alpha);
+                paint_shadow(d, wd, x, y, z);
+            }
 
-            glTranslatef(-d->xshadowoff, -d->yshadowoff, 0.0f);
-            paint_window(w, d, wd, opaque, x, y);
+            if (!opaque) {
+                glColor4us(opac, opac, opac, opac);
+                paint_window(w, d, wd, x, y, z + 0.05f);
+            }
 
-            glPopMatrix();
+            z += 0.1f;
         }
     }
 
-    //xcb_glx_swap_buffers(sc->dpy->conn, d->context_tag, sc->overlay);
+    glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
+    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+    glDisable(GL_BLEND);
+
     glXSwapBuffers(sc->dpy->xlib_dpy, sc->overlay);
 
+    glFinish();
+
     /* call the function we replaced in the chain */
     d->screen_paint(sc);
 }
@@ -556,104 +743,77 @@ paint_root(d_screen_t *sc, data_t *d)
     if (!d->root_glpixmap)
         glxrender_update_root_pixmap(sc, d);
 
-    glClear(GL_COLOR_BUFFER_BIT);
-
     glBindTexture(GL_TEXTURE_2D, d->root_texname);
     glBegin(GL_QUADS);
     glTexCoord2f(0, 0);
-    glVertex2i(0, 0);
+    glVertex3i(0, 0, 0);
     glTexCoord2f(1, 0);
-    glVertex2i(sc->super->width_in_pixels, 0);
+    glVertex3i(sc->super->width_in_pixels, 0, 0);
     glTexCoord2f(1, 1);
-    glVertex2i(sc->super->width_in_pixels, sc->super->height_in_pixels);
+    glVertex3i(sc->super->width_in_pixels, sc->super->height_in_pixels, 0);
     glTexCoord2f(0, 1);
-    glVertex2i(0, sc->super->height_in_pixels);
+    glVertex3i(0, sc->super->height_in_pixels, 0);
     glEnd();
 
     glBindTexture(GL_TEXTURE_2D, 0);
 }
 
 static void
-paint_window(d_window_t *w, data_t *d, window_data_t *wd, gboolean opaque,
-             int x, int y)
+paint_window(d_window_t *w, data_t *d, window_data_t *wd, int x, int y,
+             GLfloat z)
 {
-    uint16_t o = window_get_opacity(w);
     int i;
 
     if (!wd->glpixmap)
         glxrender_update_window_pixmap(w, d, wd);
+    if (wd->waiting_region)
+        glxrender_update_window_region(w, wd);
 
     if (wd->nrects < 1) return;
 
     glBindTexture(GL_TEXTURE_2D, wd->texname);
 
-    if (!opaque) {
-        glEnable(GL_BLEND);
-
-        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-        glColor4us(o, o, o, o);
-    }
-
     glBegin(GL_QUADS);
     for (i = 0; i < wd->nrects * 4; i += 4) {
-        // XXX use glVertex3i
         glTexCoord2f(wd->texcoords[i+LEFT], wd->texcoords[i+TOP]);
-        glVertex2i(x + wd->vertices[i+LEFT], y + wd->vertices[i+TOP]);
+        glVertex3f(x+wd->vertices[i+LEFT], y+wd->vertices[i+TOP], z);
         glTexCoord2f(wd->texcoords[i+RIGHT], wd->texcoords[i+TOP]);
-        glVertex2i(x + wd->vertices[i+RIGHT], y + wd->vertices[i+TOP]);
+        glVertex3f(x+wd->vertices[i+RIGHT], y+wd->vertices[i+TOP], z);
         glTexCoord2f(wd->texcoords[i+RIGHT], wd->texcoords[i+BOTTOM]);
-        glVertex2i(x + wd->vertices[i+RIGHT], y + wd->vertices[i+BOTTOM]);
+        glVertex3f(x+wd->vertices[i+RIGHT], y+wd->vertices[i+BOTTOM], z);
         glTexCoord2f(wd->texcoords[i+LEFT], wd->texcoords[i+BOTTOM]);
-        glVertex2i(x + wd->vertices[i+LEFT], y + wd->vertices[i+BOTTOM]);
+        glVertex3f(x+wd->vertices[i+LEFT], y+wd->vertices[i+BOTTOM], z);
     }
     glEnd();
 
     glBindTexture(GL_TEXTURE_2D, 0);
-
-    if (!opaque) {
-        glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
-        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-        glDisable(GL_BLEND);
-    }
 }
 
 static void
-paint_shadow(d_window_t *w, data_t *d, window_data_t *wd, int x, int y)
+paint_shadow(data_t *d, window_data_t *wd, int x, int y, GLfloat z)
 {
-    float alpha = d->shadowalpha;
     int i;
 
     if (wd->nrects < 1) return;
 
-    alpha *= window_get_opacity(w);
-    alpha /= 0xffff;
-
-    if (alpha < 0.01) return;
-
-    glEnable(GL_BLEND);
-    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-    /* black shadow */
-    glColor4f(0.0f, 0.0f, 0.0f, alpha);
-
     /* shape the shadow to the window */
     glBindTexture(GL_TEXTURE_2D, wd->texname);
 
+    x += d->xshadowoff;
+    y += d->yshadowoff;
+
     glBegin(GL_QUADS);
     for (i = 0; i < wd->nrects * 4; i += 4) {
         glTexCoord2f(wd->texcoords[i+LEFT], wd->texcoords[i+TOP]);
-        glVertex2i(x + wd->vertices[i+LEFT], y + wd->vertices[i+TOP]);
+        glVertex3f(x+wd->vertices[i+LEFT], y+wd->vertices[i+TOP], z);
         glTexCoord2f(wd->texcoords[i+RIGHT], wd->texcoords[i+TOP]);
-        glVertex2i(x + wd->vertices[i+RIGHT], y + wd->vertices[i+TOP]);
+        glVertex3f(x+wd->vertices[i+RIGHT], y+wd->vertices[i+TOP], z);
         glTexCoord2f(wd->texcoords[i+RIGHT], wd->texcoords[i+BOTTOM]);
-        glVertex2i(x + wd->vertices[i+RIGHT], y + wd->vertices[i+BOTTOM]);
+        glVertex3f(x+wd->vertices[i+RIGHT], y+wd->vertices[i+BOTTOM], z);
         glTexCoord2f(wd->texcoords[i+LEFT], wd->texcoords[i+BOTTOM]);
-        glVertex2i(x + wd->vertices[i+LEFT], y + wd->vertices[i+BOTTOM]);
+        glVertex3f(x+wd->vertices[i+LEFT], y+wd->vertices[i+BOTTOM], z);
     }
     glEnd();
 
     glBindTexture(GL_TEXTURE_2D, 0);
-
-    glColor4f(0.0f, 0.0f, 0.0f, 0.0f);
-    glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
-    glDisable(GL_BLEND);
 }