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
master
Freddie Witherden 2008-07-18 22:21:54 +00:00
parent 5554dbe695
commit 36a4191818
2 changed files with 47 additions and 14 deletions

View File

@ -185,6 +185,9 @@ void widgetInit(widget *self, const char *id)
self->cr = NULL; self->cr = NULL;
widgetCairoCreate(&self->cr, CAIRO_FORMAT_ARGB32, 0, 0); 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 // Focus and mouse are false by default
self->hasFocus = false; self->hasFocus = false;
self->hasMouse = false; self->hasMouse = false;
@ -212,6 +215,9 @@ void widgetDestroyImpl(widget *self)
// Destroy the cairo context // Destroy the cairo context
cairo_destroy(self->cr); cairo_destroy(self->cr);
// Destroy the texture
glDeleteTextures(1, &self->textureId);
// If we use a mask, destroy it // If we use a mask, destroy it
if (self->maskEnabled) if (self->maskEnabled)
{ {
@ -235,6 +241,8 @@ void widgetDraw(widget *self)
// See if we need to be redrawn // See if we need to be redrawn
if (self->needsRedraw) if (self->needsRedraw)
{ {
void *bits = cairo_image_surface_get_data(cairo_get_target(self->cr));
self->needsRedraw = false; self->needsRedraw = false;
// Clear the current context // Clear the current context
@ -247,6 +255,12 @@ void widgetDraw(widget *self)
// Redaw ourself // Redaw ourself
widgetDoDraw(self); 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) // 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; int i;
// Composite ourself // Composite ourself
cairo_set_source_surface(comp, cairo_get_target(self->cr), 0, 0); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, self->textureId);
cairo_paint(comp);
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 // Now our children
for (i = 0; i < vectorSize(self->children); i++) for (i = 0; i < vectorSize(self->children); i++)
{ {
widget *child = vectorAt(self->children, i); widget *child = vectorAt(self->children, i);
cairo_matrix_t current;
// Translate such that (0,0) is the location of the widget // Translate such that (0,0) is the top-left of the widget
cairo_get_matrix(comp, &current); glTranslatef(child->offset.x, child->offset.y, 0);
cairo_translate(comp, child->offset.x, child->offset.y);
// Composite // Composite
widgetComposite(child, comp); widgetComposite(child);
// Restore the matrix // Restore the matrix
cairo_set_matrix(comp, &current); 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); 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) void widgetDoDraw(widget *self)

View File

@ -8,6 +8,9 @@
#include <cairo.h> #include <cairo.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include "vector.h" #include "vector.h"
#include "geom.h" #include "geom.h"
@ -229,7 +232,7 @@ struct _widgetVtbl
void (*resize) (widget *self, int x, int y); void (*resize) (widget *self, int x, int y);
void (*composite) (widget *self, cairo_t *comp); void (*composite) (widget *self);
void (*doDraw) (widget *self); void (*doDraw) (widget *self);
void (*doDrawMask) (widget *self); void (*doDrawMask) (widget *self);
@ -273,6 +276,11 @@ struct _widget
*/ */
cairo_t *cr; cairo_t *cr;
/*
* The id of the OpenGL texture to which self->cr is mapped
*/
GLuint textureId;
/* /*
* The widgets mouse-event mask * The widgets mouse-event mask
*/ */
@ -366,7 +374,7 @@ void widgetFocusImpl(widget *self);
void widgetBlurImpl(widget *self); void widgetBlurImpl(widget *self);
void widgetResizeImpl(widget *self, int w, int h); void widgetResizeImpl(widget *self, int w, int h);
bool widgetHandleEventImpl(widget *self, event *evt); bool widgetHandleEventImpl(widget *self, event *evt);
void widgetCompositeImpl(widget *self, cairo_t *comp); void widgetCompositeImpl(widget *self);
/* /*
* Public static methods * Public static methods
@ -396,7 +404,7 @@ void widgetDraw(widget *self);
/** /**
* TODO * TODO
*/ */
void widgetComposite(widget *self, cairo_t *comp); void widgetComposite(widget *self);
/** /**
* Enables the widgets mask. * Enables the widgets mask.