From: Dana Jansens Date: Sun, 16 Mar 2008 00:10:59 +0000 (-0400) Subject: render based on a variable number of vertices per window (for shaped windows in the... X-Git-Url: http://git.openbox.org/?a=commitdiff_plain;h=374d0b94854ed5e1de9f7a8f6ce4013169fc8cc0;p=dana%2Fdcompmgr.git render based on a variable number of vertices per window (for shaped windows in the future!) --- diff --git a/glxrender.c b/glxrender.c index 1dc1747..1c5ad24 100644 --- a/glxrender.c +++ b/glxrender.c @@ -20,6 +20,11 @@ static int plugin_id; +#define LEFT 0 +#define TOP 1 +#define RIGHT 2 +#define BOTTOM 3 + typedef void (*BindEXTFunc)(Display *, GLXDrawable, int, const int *); typedef void (*ReleaseEXTFunc)(Display *, GLXDrawable, int); @@ -48,6 +53,10 @@ typedef struct { typedef struct { GLuint texname; GLXPixmap glpixmap; + + GLfloat *texcoords; + GLint *vertices; + int nrects; } window_data_t; static gboolean glxrender_find_fb_config(d_screen_t *sc, data_t *d); @@ -56,10 +65,9 @@ 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, int width, - int height, int bwidth); + 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 width, int height, int bwidth); + int x, int y); static void glxrender_update_window_pixmap(d_window_t *w, data_t *d, window_data_t *wd); static void glxrender_free_window_pixmap(d_window_t *w, data_t *d, @@ -282,8 +290,11 @@ glxrender_window_show(d_window_t *w) wd = malloc(sizeof(window_data_t)); glGenTextures(1, &wd->texname); wd->glpixmap = XCB_NONE; + wd->nrects = 0; window_add_plugin_data(w, plugin_id, wd); + + glxrender_update_window_pixmap(w, d, wd); } static void @@ -316,6 +327,10 @@ glxrender_free_window_pixmap(d_window_t *w, data_t *d, window_data_t *wd) //xcb_glx_destroy_pixmap(w->sc->dpy->conn, wd->glpixmap); glXDestroyPixmap(w->sc->dpy->xlib_dpy, wd->glpixmap); wd->glpixmap = XCB_NONE; + + free(wd->texcoords); + free(wd->vertices); + wd->nrects = 0; } } @@ -378,6 +393,26 @@ 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; + + window_get_area(w, &x, &y, &width, &height, &bwidth); + + 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; + + 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; + + wd->nrects = 1; + } } static void @@ -430,6 +465,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); } static void @@ -446,6 +482,7 @@ glxrender_window_reshape(d_window_t *w) assert(wd != NULL); glxrender_free_window_pixmap(w, d, wd); + glxrender_update_window_pixmap(w, d, wd); } static void @@ -495,11 +532,12 @@ glxrender_paint(d_screen_t *sc) wd = window_find_plugin_data(w, plugin_id); glPushMatrix(); - glTranslatef(x + d->xshadowoff, y + d->yshadowoff, 0.0f); - paint_shadow(w, d, wd, 0, 0, width, height, bwidth); + glTranslatef(d->xshadowoff, d->yshadowoff, 0.0f); + paint_shadow(w, d, wd, x, y); + glTranslatef(-d->xshadowoff, -d->yshadowoff, 0.0f); - paint_window(w, d, wd, opaque, 0, 0, width, height, bwidth); + paint_window(w, d, wd, opaque, x, y); glPopMatrix(); } @@ -522,6 +560,7 @@ paint_root(d_screen_t *sc, data_t *d) glBindTexture(GL_TEXTURE_2D, d->root_texname); glBegin(GL_QUADS); + glTexCoord2f(0, 0); glVertex2i(0, 0); glTexCoord2f(1, 0); glVertex2i(sc->super->width_in_pixels, 0); @@ -529,7 +568,6 @@ paint_root(d_screen_t *sc, data_t *d) glVertex2i(sc->super->width_in_pixels, sc->super->height_in_pixels); glTexCoord2f(0, 1); glVertex2i(0, sc->super->height_in_pixels); - glTexCoord2f(0, 0); glEnd(); glBindTexture(GL_TEXTURE_2D, 0); @@ -537,13 +575,16 @@ paint_root(d_screen_t *sc, data_t *d) static void paint_window(d_window_t *w, data_t *d, window_data_t *wd, gboolean opaque, - int x, int y, int width, int height, int bwidth) + int x, int y) { uint16_t o = window_get_opacity(w); + int i; if (!wd->glpixmap) glxrender_update_window_pixmap(w, d, wd); + if (wd->nrects < 1) return; + glBindTexture(GL_TEXTURE_2D, wd->texname); if (!opaque) { @@ -554,15 +595,17 @@ paint_window(d_window_t *w, data_t *d, window_data_t *wd, gboolean opaque, } glBegin(GL_QUADS); - glTexCoord2f(0, 0); - glVertex2i(x, y); - glTexCoord2f(1, 0); - glVertex2i(x + width + bwidth, y); - glTexCoord2f(1, 1); - glVertex2i(x + width + bwidth, - y + height + bwidth); - glTexCoord2f(0, 1); - glVertex2i(x, y + height + bwidth); + 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]); + glTexCoord2f(wd->texcoords[i+RIGHT], wd->texcoords[i+TOP]); + glVertex2i(x + wd->vertices[i+RIGHT], y + wd->vertices[i+TOP]); + glTexCoord2f(wd->texcoords[i+RIGHT], wd->texcoords[i+BOTTOM]); + glVertex2i(x + wd->vertices[i+RIGHT], y + wd->vertices[i+BOTTOM]); + glTexCoord2f(wd->texcoords[i+LEFT], wd->texcoords[i+BOTTOM]); + glVertex2i(x + wd->vertices[i+LEFT], y + wd->vertices[i+BOTTOM]); + } glEnd(); glBindTexture(GL_TEXTURE_2D, 0); @@ -575,10 +618,12 @@ paint_window(d_window_t *w, data_t *d, window_data_t *wd, gboolean opaque, } static void -paint_shadow(d_window_t *w, data_t *d, window_data_t *wd, - int x, int y, int width, int height, int bwidth) +paint_shadow(d_window_t *w, data_t *d, window_data_t *wd, int x, int y) { float alpha = d->shadowalpha; + int i; + + if (wd->nrects < 1) return; alpha *= window_get_opacity(w); alpha /= 0xffff; @@ -590,28 +635,23 @@ paint_shadow(d_window_t *w, data_t *d, window_data_t *wd, /* black shadow */ glColor4f(0.0f, 0.0f, 0.0f, alpha); - if (window_is_argb(w)) { - /* shape the shadow to the window's alpha levels */ - glBindTexture(GL_TEXTURE_2D, wd->texname); - - glBegin(GL_QUADS); - glTexCoord2f(0, 0); - glVertex2i(x, y); - glTexCoord2f(1, 0); - glVertex2i(x + width + bwidth, y); - glTexCoord2f(1, 1); - glVertex2i(x + width + bwidth, - y + height + bwidth); - glTexCoord2f(0, 1); - glVertex2i(x, y + height + bwidth); - glEnd(); + /* shape the shadow to the window */ + glBindTexture(GL_TEXTURE_2D, wd->texname); - glBindTexture(GL_TEXTURE_2D, 0); + 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]); + glTexCoord2f(wd->texcoords[i+RIGHT], wd->texcoords[i+TOP]); + glVertex2i(x + wd->vertices[i+RIGHT], y + wd->vertices[i+TOP]); + glTexCoord2f(wd->texcoords[i+RIGHT], wd->texcoords[i+BOTTOM]); + glVertex2i(x + wd->vertices[i+RIGHT], y + wd->vertices[i+BOTTOM]); + glTexCoord2f(wd->texcoords[i+LEFT], wd->texcoords[i+BOTTOM]); + glVertex2i(x + wd->vertices[i+LEFT], y + wd->vertices[i+BOTTOM]); } - else - /* draw a solid rectangle */ - glRecti(x, y, - x + width + bwidth - 1, y + height + bwidth - 1); + 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);