From 36a4191818bf6d5bc57cb59b1de0b1e14a470a07 Mon Sep 17 00:00:00 2001 From: Freddie Witherden Date: Fri, 18 Jul 2008 22:21:54 +0000 Subject: [PATCH] Switch to an OpenGL compositing mode; some clean-up still required. git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@5578 4a71c877-e1ca-e34f-864e-861f7616d084 --- lib/betawidget/widget.c | 47 +++++++++++++++++++++++++++++++---------- lib/betawidget/widget.h | 14 +++++++++--- 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/lib/betawidget/widget.c b/lib/betawidget/widget.c index f07e1cdb8..44898becc 100644 --- a/lib/betawidget/widget.c +++ b/lib/betawidget/widget.c @@ -185,6 +185,9 @@ void widgetInit(widget *self, const char *id) self->cr = NULL; widgetCairoCreate(&self->cr, CAIRO_FORMAT_ARGB32, 0, 0); + // Ask OpenGL for a texture id + glGenTextures(1, &self->textureId); + // Focus and mouse are false by default self->hasFocus = false; self->hasMouse = false; @@ -212,6 +215,9 @@ void widgetDestroyImpl(widget *self) // Destroy the cairo context cairo_destroy(self->cr); + // Destroy the texture + glDeleteTextures(1, &self->textureId); + // If we use a mask, destroy it if (self->maskEnabled) { @@ -235,6 +241,8 @@ void widgetDraw(widget *self) // See if we need to be redrawn if (self->needsRedraw) { + void *bits = cairo_image_surface_get_data(cairo_get_target(self->cr)); + self->needsRedraw = false; // Clear the current context @@ -247,6 +255,12 @@ void widgetDraw(widget *self) // Redaw ourself widgetDoDraw(self); + + // Update the texture + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self->textureId); + + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, self->size.x, + self->size.y, 0, GL_BGRA, GL_UNSIGNED_BYTE, bits); } // Draw our children (even if we did not need redrawing our children might) @@ -706,29 +720,40 @@ void widgetResizeImpl(widget *self, int w, int h) } } -void widgetCompositeImpl(widget *self, cairo_t *comp) +void widgetCompositeImpl(widget *self) { int i; // Composite ourself - cairo_set_source_surface(comp, cairo_get_target(self->cr), 0, 0); - cairo_paint(comp); + glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self->textureId); + + glBegin(GL_QUADS); + glTexCoord2f(0, 0); + glVertex2f(0, 0); + + glTexCoord2f(0, self->size.y); + glVertex2f(0, self->size.y); + + glTexCoord2f(self->size.x, self->size.y); + glVertex2f(self->size.x, self->size.y); + + glTexCoord2f(self->size.x, 0); + glVertex2f(self->size.x, 0); + glEnd(); // Now our children for (i = 0; i < vectorSize(self->children); i++) { widget *child = vectorAt(self->children, i); - cairo_matrix_t current; - // Translate such that (0,0) is the location of the widget - cairo_get_matrix(comp, ¤t); - cairo_translate(comp, child->offset.x, child->offset.y); + // Translate such that (0,0) is the top-left of the widget + glTranslatef(child->offset.x, child->offset.y, 0); // Composite - widgetComposite(child, comp); + widgetComposite(child); // Restore the matrix - cairo_set_matrix(comp, ¤t); + glTranslatef(-child->offset.x, -child->offset.y, 0); } } @@ -1038,9 +1063,9 @@ void widgetResize(widget *self, int x, int y) WIDGET_GET_VTBL(self)->resize(self, x, y); } -void widgetComposite(widget *self, cairo_t *comp) +void widgetComposite(widget *self) { - WIDGET_GET_VTBL(self)->composite(self, comp); + WIDGET_GET_VTBL(self)->composite(self); } void widgetDoDraw(widget *self) diff --git a/lib/betawidget/widget.h b/lib/betawidget/widget.h index fea2f0323..6a8ea5fbd 100644 --- a/lib/betawidget/widget.h +++ b/lib/betawidget/widget.h @@ -8,6 +8,9 @@ #include +#include +#include + #include "vector.h" #include "geom.h" @@ -229,7 +232,7 @@ struct _widgetVtbl void (*resize) (widget *self, int x, int y); - void (*composite) (widget *self, cairo_t *comp); + void (*composite) (widget *self); void (*doDraw) (widget *self); void (*doDrawMask) (widget *self); @@ -273,6 +276,11 @@ struct _widget */ cairo_t *cr; + /* + * The id of the OpenGL texture to which self->cr is mapped + */ + GLuint textureId; + /* * The widgets mouse-event mask */ @@ -366,7 +374,7 @@ void widgetFocusImpl(widget *self); void widgetBlurImpl(widget *self); void widgetResizeImpl(widget *self, int w, int h); bool widgetHandleEventImpl(widget *self, event *evt); -void widgetCompositeImpl(widget *self, cairo_t *comp); +void widgetCompositeImpl(widget *self); /* * Public static methods @@ -396,7 +404,7 @@ void widgetDraw(widget *self); /** * TODO */ -void widgetComposite(widget *self, cairo_t *comp); +void widgetComposite(widget *self); /** * Enables the widgets mask.