2007-05-28 Matthew Allum <mallum@openedhand.com>

* clutter/clutter-backend.c:
        * clutter/clutter-backend.h:
        * clutter/glx/clutter-stage-glx.c:
        * clutter/glx/clutter-backend-glx.c:
        Fix up rendering pipeline removing clutter_backend_XXX_stage_paint
        and adding clutter_backend_XXX_redraw instead. Duplicates less
        code in backends, avoids clutter_actor_paint() getting called
        before stage is set up (viewport wise) and unbreaks things like
        picking.

        * clutter/clutter-actor.c:
        * clutter/clutter-actor.h:
        * clutter/clutter-main.c:
        * clutter/clutter-private.h:
        * clutter/clutter-stage.c: (clutter_stage_get_actor_at_pos):
        Redo picking functionality a different way (via color indexing)
        as to provide more flexibility, possibly speed and more likely
        work with GL/ES (doesn't currently however - not sure why).

        * clutter/clutter-group.c:
        Add groups own 'pick' method.

        * clutter/cogl/cogl.h:
        * clutter/cogl/gl/cogl.c:
        * clutter/cogl/gles/cogl.c:
        Move clipping funtionality into cogl.

        * clutter/cogl/gles/cogl-defines.h:
        Hack around missing BGR format in GL/ES.

        * clutter/egl/clutter-backend-egl.c:
        * clutter/egl/clutter-backend-egl.h:
        * clutter/egl/clutter-stage-egl.c:
        * clutter/sdl/clutter-backend-sdl.c:
        * clutter/sdl/clutter-backend-sdl.h:
        * clutter/sdl/clutter-event-sdl.c:
        * clutter/sdl/clutter-stage-sdl.c:
        Update backends to newer API.
        Add basic mouse event translation to SDL.
This commit is contained in:
Matthew Allum 2007-05-28 18:49:34 +00:00
parent a64b6b7ee7
commit a2bd6de736
22 changed files with 498 additions and 374 deletions

View File

@ -1,3 +1,45 @@
2007-05-28 Matthew Allum <mallum@openedhand.com>
* clutter/clutter-backend.c:
* clutter/clutter-backend.h:
* clutter/glx/clutter-stage-glx.c:
* clutter/glx/clutter-backend-glx.c:
Fix up rendering pipeline removing clutter_backend_XXX_stage_paint
and adding clutter_backend_XXX_redraw instead. Duplicates less
code in backends, avoids clutter_actor_paint() getting called
before stage is set up (viewport wise) and unbreaks things like
picking.
* clutter/clutter-actor.c:
* clutter/clutter-actor.h:
* clutter/clutter-main.c:
* clutter/clutter-private.h:
* clutter/clutter-stage.c: (clutter_stage_get_actor_at_pos):
Redo picking functionality a different way (via color indexing)
as to provide more flexibility, possibly speed and more likely
work with GL/ES (doesn't currently however - not sure why).
* clutter/clutter-group.c:
Add groups own 'pick' method.
* clutter/cogl/cogl.h:
* clutter/cogl/gl/cogl.c:
* clutter/cogl/gles/cogl.c:
Move clipping funtionality into cogl.
* clutter/cogl/gles/cogl-defines.h:
Hack around missing BGR format in GL/ES.
* clutter/egl/clutter-backend-egl.c:
* clutter/egl/clutter-backend-egl.h:
* clutter/egl/clutter-stage-egl.c:
* clutter/sdl/clutter-backend-sdl.c:
* clutter/sdl/clutter-backend-sdl.h:
* clutter/sdl/clutter-event-sdl.c:
* clutter/sdl/clutter-stage-sdl.c:
Update backends to newer API.
Add basic mouse event translation to SDL.
2007-05-25 Matthew Allum <mallum@openedhand.com>
* clutter/clutter-color.c: (clutter_color_parse):

View File

@ -265,6 +265,40 @@ clutter_actor_unrealize (ClutterActor *self)
(klass->unrealize) (self);
}
/**
* clutter_actor_pick:
* @self: A #ClutterActor
* @color: A #ClutterColor
*
* Renders a silhouette of the actor in supplied color.
*
* This function should not never be called directly by applications.
**/
void
clutter_actor_pick (ClutterActor *self,
const ClutterColor *color)
{
ClutterActorClass *klass;
klass = CLUTTER_ACTOR_GET_CLASS (self);
if (G_UNLIKELY(klass->pick))
{
/* Its pretty unlikely anything other than a container actor
* would need to supply its own pick method.
*/
(klass->pick) (self, color);
}
else
{
cogl_color (color);
cogl_rectangle (0,
0,
clutter_actor_get_width(self),
clutter_actor_get_height(self));
}
}
/**
* clutter_actor_paint:
* @self: A #ClutterActor
@ -279,6 +313,7 @@ clutter_actor_paint (ClutterActor *self)
{
ClutterActorPrivate *priv;
ClutterActorClass *klass;
ClutterMainContext *context;
g_return_if_fail (CLUTTER_IS_ACTOR (self));
priv = self->priv;
@ -295,14 +330,11 @@ clutter_actor_paint (ClutterActor *self)
}
}
klass = CLUTTER_ACTOR_GET_CLASS (self);
context = clutter_context_get_default ();
klass = CLUTTER_ACTOR_GET_CLASS (self);
cogl_push_matrix();
#if HAVE_COGL_GL
glLoadName (clutter_actor_get_id (self));
#endif
if (clutter_actor_get_parent (self) != NULL)
{
cogl_translate (CLUTTER_UNITS_TO_INT (priv->coords.x1),
@ -340,39 +372,35 @@ clutter_actor_paint (ClutterActor *self)
cogl_scale (priv->scale_x, priv->scale_y);
}
#if HAVE_COGL_GL
if (priv->has_clip)
cogl_clip_set (&(priv->clip));
if (G_UNLIKELY(context->pick_mode == TRUE))
{
ClutterGeometry *clip = &(priv->clip);
ClutterColor col;
guint32 id;
/* FIXME: ES ... */
glEnable (GL_STENCIL_TEST);
id = clutter_actor_get_id (self);
glClearStencil (0.0f);
glClear (GL_STENCIL_BUFFER_BIT);
/* Encode the actor id into a color */
col.red = (id >> 16) & 0xff;
col.green = (id >> 8) & 0xff;
col.blue = id & 0xff;
col.alpha = 0xff;
glStencilFunc (GL_NEVER, 0x1, 0x1);
glStencilOp (GL_INCR, GL_INCR, GL_INCR);
glColor3f (1.0f, 1.0f, 1.0f);
glRecti (clip->x,
clip->y,
clip->x + clip->width,
clip->y + clip->height);
glStencilFunc (GL_EQUAL, 0x1, 0x1);
glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
/* Actor will then paint silhouette of itself in supplied color.
* See clutter_stage_get_actor_at_pos() for where picking is enabled.
*/
clutter_actor_pick (self, &col);
}
else
{
if (G_LIKELY(klass->paint))
(klass->paint) (self);
}
#endif
if (klass->paint)
(klass->paint) (self);
#if CLUTTER_COGL_GL
if (priv->has_clip)
glDisable (GL_STENCIL_TEST);
#endif
cogl_clip_unset();
if (priv->scale_x != CFX_ONE || priv->scale_y != CFX_ONE)
cogl_scale (CFX_ONE, CFX_ONE);

View File

@ -31,6 +31,7 @@
#include <glib-object.h>
#include <clutter/clutter-fixed.h>
#include <clutter/clutter-units.h>
#include <clutter/clutter-color.h>
G_BEGIN_DECLS
@ -139,10 +140,8 @@ struct _ClutterActorClass
void (* parent_set) (ClutterActor *actor,
ClutterActor *old_parent);
void (* destroy) (ClutterActor *actor);
/* to go ? */
void (* queue_redraw) (ClutterActor *actor);
void (* destroy) (ClutterActor *actor);
void (* pick) (ClutterActor *actor, const ClutterColor *color);
/* padding for future expansion */
void (*_clutter_actor_1) (void);
@ -161,6 +160,8 @@ void clutter_actor_hide_all (ClutterActor *sel
void clutter_actor_realize (ClutterActor *self);
void clutter_actor_unrealize (ClutterActor *self);
void clutter_actor_paint (ClutterActor *self);
void clutter_actor_pick (ClutterActor *actor,
const ClutterColor *color);
void clutter_actor_queue_redraw (ClutterActor *self);
void clutter_actor_destroy (ClutterActor *self);
void clutter_actor_request_coords (ClutterActor *self,

View File

@ -143,6 +143,16 @@ _clutter_backend_init_stage (ClutterBackend *backend,
return TRUE;
}
void
_clutter_backend_redraw (ClutterBackend *backend)
{
ClutterBackendClass *klass;
klass = CLUTTER_BACKEND_GET_CLASS (backend);
if (G_LIKELY(klass->redraw))
klass->redraw (backend);
}
ClutterFeatureFlags
_clutter_backend_get_features (ClutterBackend *backend)
{

View File

@ -68,6 +68,7 @@ struct _ClutterBackendClass
void (* add_options) (ClutterBackend *backend,
GOptionGroup *group);
ClutterFeatureFlags (* get_features) (ClutterBackend *backend);
void (* redraw) (ClutterBackend *backend);
};
GType clutter_backend_get_type (void) G_GNUC_CONST;

View File

@ -46,6 +46,8 @@
#include "clutter-marshal.h"
#include "clutter-enum-types.h"
#include "cogl.h"
enum
{
ADD,
@ -66,6 +68,7 @@ struct _ClutterGroupPrivate
GList *children;
};
static void
clutter_group_paint (ClutterActor *actor)
{
@ -93,6 +96,19 @@ clutter_group_paint (ClutterActor *actor)
CLUTTER_NOTE (PAINT, "ClutterGroup paint leave");
}
static void
clutter_group_pick (ClutterActor *actor,
const ClutterColor *color)
{
/* Just forward to the paint call which in turn will trigger
* the child actors also getting 'picked'. To make ourselves
* 'sensitive' to clicks we could also paint a bounding rect
* but this is not currently done.
*/
clutter_group_paint (actor);
}
static void
clutter_group_request_coords (ClutterActor *self,
ClutterActorBox *box)
@ -224,6 +240,7 @@ clutter_group_class_init (ClutterGroupClass *klass)
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
actor_class->paint = clutter_group_paint;
actor_class->pick = clutter_group_pick;
actor_class->show_all = clutter_group_real_show_all;
actor_class->hide_all = clutter_group_real_hide_all;
actor_class->request_coords = clutter_group_request_coords;

View File

@ -46,6 +46,8 @@
#include "clutter-debug.h"
#include "clutter-version.h" /* For flavour define */
#include "cogl.h"
static ClutterMainContext *ClutterCntx = NULL;
static gboolean clutter_is_initialized = FALSE;
@ -94,10 +96,61 @@ void
clutter_redraw (void)
{
ClutterMainContext *ctx;
ClutterColor stage_color;
ClutterActor *stage;
static GTimer *timer = NULL;
static guint timer_n_frames = 0;
ctx = clutter_context_get_default ();
if (ctx->backend)
clutter_actor_paint (_clutter_backend_get_stage (ctx->backend));
ctx = clutter_context_get_default ();
stage = _clutter_backend_get_stage (ctx->backend);
CLUTTER_NOTE (PAINT, " Redraw enter");
/* Setup FPS count */
if (clutter_get_show_fps ())
{
if (!timer)
timer = g_timer_new ();
}
/* The below cant go in stage paint as base actor_paint will get
* called before the below (and break picking etc)
*/
if (CLUTTER_PRIVATE_FLAGS (stage) & CLUTTER_ACTOR_SYNC_MATRICES)
{
cogl_setup_viewport (clutter_actor_get_width (stage),
clutter_actor_get_height (stage),
171, /* 60 degrees */
CFX_ONE,
CLUTTER_FLOAT_TO_FIXED (0.1),
CLUTTER_FLOAT_TO_FIXED (100.0));
}
/* Setup the initial paint */
clutter_stage_get_color (CLUTTER_STAGE(stage), &stage_color);
cogl_paint_init (&stage_color);
/* Call through ti the actual backend to do the painting down from
* the stage. It will likely need to swap buffers, vblank sync etc
* which will be windowing system dependant.
*/
_clutter_backend_redraw (ctx->backend);
/* Complete FPS info */
if (clutter_get_show_fps ())
{
timer_n_frames++;
if (g_timer_elapsed (timer, NULL) >= 1.0)
{
g_print ("*** FPS: %i ***\n", timer_n_frames);
timer_n_frames = 0;
g_timer_start (timer);
}
}
CLUTTER_NOTE (PAINT, " Redraw leave");
}
/**
@ -271,7 +324,7 @@ clutter_get_debug_enabled (void)
ClutterMainContext*
clutter_context_get_default (void)
{
if (!ClutterCntx)
if (G_UNLIKELY(!ClutterCntx))
{
ClutterMainContext *ctx;

View File

@ -56,6 +56,7 @@ struct _ClutterMainContext
guint main_loop_level;
GSList *main_loops;
guint is_initialized : 1;
guint pick_mode :1;
};
#define CLUTTER_CONTEXT() (clutter_context_get_default ())
@ -98,6 +99,8 @@ GType _clutter_backend_impl_get_type (void);
ClutterActor *_clutter_backend_get_stage (ClutterBackend *backend);
void _clutter_backend_redraw (ClutterBackend *backend);
void _clutter_backend_add_options (ClutterBackend *backend,
GOptionGroup *group);
gboolean _clutter_backend_pre_parse (ClutterBackend *backend,

View File

@ -94,12 +94,9 @@ enum
static guint stage_signals[LAST_SIGNAL] = { 0, };
static void
clutter_stage_paint (ClutterActor *actor)
clutter_stage_paint (ClutterActor *self)
{
/* chain up */
CLUTTER_NOTE (PAINT, "Chaining up to parent class paint");
CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->paint (actor);
CLUTTER_ACTOR_CLASS (clutter_stage_parent_class)->paint (self);
}
static void
@ -766,68 +763,41 @@ clutter_stage_get_actor_at_pos (ClutterStage *stage,
gint x,
gint y)
{
#if HAVE_COGL_GL
ClutterMainContext *context;
guchar pixel[3];
GLint viewport[4];
ClutterColor white = { 0xff, 0xff, 0xff, 0xff };
guint32 id;
/* FIXME: Add a clutter feature flag for this or figure out
* for gles.
context = clutter_context_get_default ();
cogl_paint_init (&white);
cogl_enable (0);
/* Render the entire scence in pick mode - just single colored silhouette's
* are drawn offscreen (as we never swap buffers)
*/
ClutterActor *found = NULL;
GLuint buff[512] = { 0 };
GLint hits;
GLint view[4];
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
glSelectBuffer (512, buff);
glGetIntegerv (GL_VIEWPORT, view);
glRenderMode (GL_SELECT);
glInitNames ();
glPushName (0);
glMatrixMode (GL_PROJECTION);
glPushMatrix ();
glLoadIdentity ();
/* This is gluPickMatrix(x, y, 1.0, 1.0, view); */
glTranslatef ((view[2] - 2 * (x - view[0])),
(view[3] - 2 * (y - view[1])), 0);
glScalef (view[2], -view[3], 1.0);
cogl_perspective (171, /* 60 degrees */
CFX_ONE,
CLUTTER_FLOAT_TO_FIXED (0.1),
CLUTTER_FLOAT_TO_FIXED (100.0));
glMatrixMode (GL_MODELVIEW);
context->pick_mode = TRUE;
clutter_actor_paint (CLUTTER_ACTOR (stage));
context->pick_mode = FALSE;
glMatrixMode (GL_PROJECTION);
glPopMatrix ();
/* Calls should work under both GL and GLES
*
* FIXME: of course we need to handle the case where the frame buffer isn't
* 24bpp, i.e 16bpp which could be the case with GLES.
*/
glGetIntegerv(GL_VIEWPORT, viewport);
glReadPixels(x, viewport[3] - y, 1, 1, GL_RGB, GL_UNSIGNED_BYTE, pixel);
hits = glRenderMode (GL_RENDER);
/* printf("x: %i , y: %i %x:%x:%x\n", x, y, pixel[0], pixel[1], pixel[2]); */
if (hits != 0)
{
#if 1
gint i;
for (i = 0; i < hits; i++)
g_print ("Hit at %i\n", buff[(hits-1) * 4 + 3]);
#endif
found = clutter_group_find_child_by_id (CLUTTER_GROUP (stage),
buff[(hits-1) * 4 + 3]);
}
if (pixel[0] == 0xff && pixel[1] == 0xff && pixel[2] == 0xff)
return CLUTTER_ACTOR(stage);
CLUTTER_SET_PRIVATE_FLAGS(stage, CLUTTER_ACTOR_SYNC_MATRICES);
/* Decode color back into an ID */
id = pixel[2] | pixel[1] << 8 | pixel[0] << 16;
return found;
#else
/* GL/ES cannot do this yet.. */
return NULL;
#endif
return clutter_group_find_child_by_id (CLUTTER_GROUP (stage), id);
}
/**

View File

@ -77,7 +77,7 @@ cogl_setup_viewport (guint width,
ClutterFixed z_far);
void
cogl_paint_init (ClutterColor *color);
cogl_paint_init (const ClutterColor *color);
void
cogl_push_matrix (void);
@ -101,7 +101,13 @@ void
cogl_rotate (gint angle, gint x, gint y, gint z);
void
cogl_color (ClutterColor *color);
cogl_color (const ClutterColor *color);
void
cogl_clip_set (const ClutterGeometry *clip);
void
cogl_clip_unset (void);
void
cogl_enable (gulong flags);

View File

@ -139,7 +139,7 @@ cogl_check_extension (const gchar *name, const gchar *ext)
}
void
cogl_paint_init (ClutterColor *color)
cogl_paint_init (const ClutterColor *color)
{
GE( glClearColor (((float) color->red / 0xff * 1.0),
((float) color->green / 0xff * 1.0),
@ -266,11 +266,39 @@ cogl_enable (gulong flags)
}
void
cogl_color (ClutterColor *color)
cogl_color (const ClutterColor *color)
{
glColor4ub (color->red, color->green, color->blue, color->alpha);
}
void
cogl_clip_set (const ClutterGeometry *clip)
{
GE( glEnable (GL_STENCIL_TEST) );
GE( glClearStencil (0.0f) );
GE( glClear (GL_STENCIL_BUFFER_BIT) );
GE( glStencilFunc (GL_NEVER, 0x1, 0x1) );
GE( glStencilOp (GL_INCR, GL_INCR, GL_INCR) );
GE( glColor3f (1.0f, 1.0f, 1.0f) );
GE( glRecti (clip->x,
clip->y,
clip->x + clip->width,
clip->y + clip->height) );
GE( glStencilFunc (GL_EQUAL, 0x1, 0x1) );
; GE( glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) );
}
void
cogl_clip_unset (void)
{
GE( glDisable (GL_STENCIL_TEST) );
}
gboolean
cogl_texture_can_size (COGLenum pixel_format,
COGLenum pixel_type,
@ -423,7 +451,6 @@ cogl_trapezoid (gint y1,
GE( glEnd () );
}
void
cogl_alpha_func (COGLenum func,
ClutterFixed ref)
@ -431,61 +458,6 @@ cogl_alpha_func (COGLenum func,
GE( glAlphaFunc (func, CLUTTER_FIXED_TO_FLOAT(ref)) );
}
#if 0
/*
* Original floating point implementaiton of the perspective function,
* retained for reference purposes
*/
static inline void
frustum (GLfloat left,
GLfloat right,
GLfloat bottom,
GLfloat top,
GLfloat nearval,
GLfloat farval)
{
GLfloat x, y, a, b, c, d;
GLfloat m[16];
x = (2.0 * nearval) / (right - left);
y = (2.0 * nearval) / (top - bottom);
a = (right + left) / (right - left);
b = (top + bottom) / (top - bottom);
c = -(farval + nearval) / ( farval - nearval);
d = -(2.0 * farval * nearval) / (farval - nearval);
#define M(row,col) m[col*4+row]
M(0,0) = x; M(0,1) = 0.0F; M(0,2) = a; M(0,3) = 0.0F;
M(1,0) = 0.0F; M(1,1) = y; M(1,2) = b; M(1,3) = 0.0F;
M(2,0) = 0.0F; M(2,1) = 0.0F; M(2,2) = c; M(2,3) = d;
M(3,0) = 0.0F; M(3,1) = 0.0F; M(3,2) = -1.0F; M(3,3) = 0.0F;
#undef M
GE( glMultMatrixf (m) );
}
static inline void
perspective (GLfloat fovy,
GLfloat aspect,
GLfloat zNear,
GLfloat zFar)
{
GLfloat xmin, xmax, ymin, ymax;
ymax = zNear * tan (fovy * M_PI / 360.0);
ymin = -ymax;
xmin = ymin * aspect;
xmax = ymax * aspect;
printf ("%f, %f, %f, %f\n", xmin, xmax, ymin, ymax);
frustum (xmin, xmax, ymin, ymax, zNear, zFar);
}
#endif
/*
* Fixed point implementation of the perspective function
*/
void
cogl_perspective (ClutterAngle fovy,
ClutterFixed aspect,
@ -495,11 +467,7 @@ cogl_perspective (ClutterAngle fovy,
ClutterFixed xmax, ymax;
ClutterFixed x, y, c, d;
#ifdef HAVE_COGL_GL
GLfloat m[16];
#else
GLfixed m[16];
#endif
memset (&m[0], 0, sizeof (m));
@ -521,7 +489,6 @@ cogl_perspective (ClutterAngle fovy,
d = CFX_DIV (-(clutter_qmulx (2*zFar, zNear)), (zFar - zNear));
#define M(row,col) m[col*4+row]
#ifdef HAVE_COGL_GL
M(0,0) = CLUTTER_FIXED_TO_FLOAT (x);
M(1,1) = CLUTTER_FIXED_TO_FLOAT (y);
M(2,2) = CLUTTER_FIXED_TO_FLOAT (c);
@ -529,15 +496,6 @@ cogl_perspective (ClutterAngle fovy,
M(3,2) = -1.0F;
GE( glMultMatrixf (m) );
#else
M(0,0) = x;
M(1,1) = y;
M(2,2) = c;
M(2,3) = d;
M(3,2) = 1 + ~CFX_ONE;
GE( glMultMatrixx (m) );
#endif
#undef M
}
@ -568,7 +526,7 @@ cogl_setup_viewport (guint width,
GE( glTranslatef (-0.5f, -0.5f, -z_camera) );
GE( glScalef ( 1.0f / width,
-1.0f / height,
-1.0f / height,
1.0f / width) );
GE( glTranslatef (0.0f, -1.0 * height, 0.0f) );
}

View File

@ -444,6 +444,13 @@ typedef GLint COGLint;
#define CGL_TEXTURE_2D GL_TEXTURE_2D
#define CGL_ARGB GL_ARGB
/* FIXME: There is no BGR support in GLES - so with below BGR textures are
* borked. Will likely need a feature flag and some coversion..
*/
#define CGL_BGR GL_RGB
#define CGL_BGRA GL_RGBA
#define CGL_TEXTURE_RECTANGLE_ARB 0 /* Its unlikely we support this */
G_END_DECLS

View File

@ -100,7 +100,7 @@ cogl_check_extension (const gchar *name, const gchar *ext)
}
void
cogl_paint_init (ClutterColor *color)
cogl_paint_init (const ClutterColor *color)
{
#if COGL_DEBUG
fprintf(stderr, "\n ============== Paint Start ================ \n");
@ -234,7 +234,7 @@ cogl_enable (gulong flags)
}
void
cogl_color (ClutterColor *color)
cogl_color (const ClutterColor *color)
{
GE( glColor4x ((color->red << 16) / 0xff,
(color->green << 16) / 0xff,
@ -242,19 +242,45 @@ cogl_color (ClutterColor *color)
(color->alpha << 16) / 0xff) );
}
void
cogl_clip_set (const ClutterGeometry *clip)
{
GE( glEnable (GL_STENCIL_TEST) );
GE( glClearStencil (0) );
GE( glClear (GL_STENCIL_BUFFER_BIT) );
GE( glStencilFunc (GL_NEVER, 0x1, 0x1) );
GE( glStencilOp (GL_INCR, GL_INCR, GL_INCR) );
GE( glColor4x (CFX_ONE, CFX_ONE, CFX_ONE, CFX_ONE ) );
cogl_rectangle (clip->x, clip->y, clip->width, clip->height);
GE( glStencilFunc (GL_EQUAL, 0x1, 0x1) );
GE( glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP) );
}
void
cogl_clip_unset (void)
{
GE( glDisable (GL_STENCIL_TEST) );
}
gboolean
cogl_texture_can_size (COGLenum pixel_format,
COGLenum pixel_type,
int width,
int height)
{
GLint new_width = 0;
/* FIXME */
return TRUE;
#if 0
GLint new_width = 0;
GE( glTexImage2D (GL_PROXY_TEXTURE_2D, 0, GL_RGBA,
width, height, 0 /* border */,
pixel_format, pixel_type, NULL) );
@ -433,8 +459,6 @@ cogl_alpha_func (COGLenum func,
GE( glAlphaFunc (func, CLUTTER_FIXED_TO_FLOAT(ref)) );
}
/*
* Fixed point implementation of the perspective function
*/
@ -507,8 +531,15 @@ cogl_setup_viewport (guint w,
/* camera distance from screen, 0.5 * tan (FOV) */
#define DEFAULT_Z_CAMERA 0.866025404f
z_camera = clutter_tani (fovy) << 1;
GE( glTranslatex (-1 << 15, -1 << 15, -z_camera );
/*
printf("%i vs %i\n",
CLUTTER_FLOAT_TO_FIXED(DEFAULT_Z_CAMERA),
clutter_tani (fovy) << 1);
*/
GE( glTranslatex (-1 << 15, -1 << 15, /*-z_camera*/
-CLUTTER_FLOAT_TO_FIXED(DEFAULT_Z_CAMERA)));
GE( glScalex ( CFX_ONE / width,
-CFX_ONE / height,

View File

@ -166,6 +166,30 @@ static const GOptionEntry entries[] =
{ NULL }
};
static void
clutter_backend_egl_redraw (ClutterBackend *backend)
{
ClutterBackendEgl *backend_egl = CLUTTER_BACKEND_EGL (backend);
ClutterStageEgl *stage_egl;
stage_egl = CLUTTER_STAGE_EGL(backend_egl->stage);
clutter_actor_paint (CLUTTER_ACTOR(stage_egl));
/* Why this paint is done in backend as likely GL windowing system
* specific calls, like swapping buffers.
*/
if (stage_egl->xwin)
{
/* clutter_feature_wait_for_vblank (); */
eglSwapBuffers ((EGLDisplay)stage_egl->xdpy, stage_egl->egl_surface);
}
else
{
eglWaitGL ();
CLUTTER_GLERR ();
}
}
static void
clutter_backend_egl_add_options (ClutterBackend *backend,
@ -237,7 +261,6 @@ clutter_backend_egl_constructor (GType gtype,
return g_object_ref (backend_singleton);
}
static void
clutter_backend_egl_class_init (ClutterBackendEglClass *klass)
{
@ -248,12 +271,13 @@ clutter_backend_egl_class_init (ClutterBackendEglClass *klass)
gobject_class->dispose = clutter_backend_egl_dispose;
gobject_class->finalize = clutter_backend_egl_finalize;
backend_class->pre_parse = clutter_backend_egl_pre_parse;
backend_class->post_parse = clutter_backend_egl_post_parse;
backend_class->init_stage = clutter_backend_egl_init_stage;
backend_class->pre_parse = clutter_backend_egl_pre_parse;
backend_class->post_parse = clutter_backend_egl_post_parse;
backend_class->init_stage = clutter_backend_egl_init_stage;
backend_class->init_events = clutter_backend_egl_init_events;
backend_class->get_stage = clutter_backend_egl_get_stage;
backend_class->get_stage = clutter_backend_egl_get_stage;
backend_class->add_options = clutter_backend_egl_add_options;
backend_class->redraw = clutter_backend_egl_redraw;
}
static void

View File

@ -72,6 +72,9 @@ struct _ClutterBackendEglClass
GType clutter_backend_egl_get_type (void) G_GNUC_CONST;
void _clutter_events_init (ClutterBackend *backend);
void _clutter_events_uninit (ClutterBackend *backend);
G_END_DECLS
#endif /* __CLUTTER_BACKEND_EGL_H__ */

View File

@ -182,60 +182,7 @@ clutter_stage_egl_realize (ClutterActor *actor)
/* FIXME */
}
_clutter_stage_sync_viewport (CLUTTER_STAGE (stage_egl));
}
static void
clutter_stage_egl_paint (ClutterActor *self)
{
ClutterStageEgl *stage_egl = CLUTTER_STAGE_EGL (self);
ClutterStage *stage = CLUTTER_STAGE (self);
ClutterColor stage_color;
static GTimer *timer = NULL;
static guint timer_n_frames = 0;
CLUTTER_NOTE (PAINT, " Redraw enter");
if (clutter_get_show_fps ())
{
if (!timer)
timer = g_timer_new ();
}
clutter_stage_get_color (stage, &stage_color);
cogl_paint_init (&stage_color);
/* Basically call up to ClutterGroup paint here */
CLUTTER_ACTOR_CLASS (clutter_stage_egl_parent_class)->paint (self);
/* Why this paint is done in backend as likely GL windowing system
* specific calls, like swapping buffers.
*/
if (stage_egl->xwin)
{
/* clutter_feature_wait_for_vblank (); */
eglSwapBuffers ((EGLDisplay)stage_egl->xdpy, stage_egl->egl_surface);
}
else
{
eglWaitGL ();
CLUTTER_GLERR ();
}
if (clutter_get_show_fps ())
{
timer_n_frames++;
if (g_timer_elapsed (timer, NULL) >= 1.0)
{
g_print ("*** FPS: %i ***\n", timer_n_frames);
timer_n_frames = 0;
g_timer_start (timer);
}
}
CLUTTER_NOTE (PAINT, " Redraw leave");
CLUTTER_SET_PRIVATE_FLAGS(actor, CLUTTER_ACTOR_SYNC_MATRICES);
}
static void
@ -272,7 +219,7 @@ clutter_stage_egl_request_coords (ClutterActor *self,
stage_egl->xwin_width,
stage_egl->xwin_height);
_clutter_stage_sync_viewport (CLUTTER_STAGE (stage_egl));
CLUTTER_SET_PRIVATE_FLAGS(self, CLUTTER_ACTOR_SYNC_MATRICES);
}
if (stage_egl->xwin != None) /* Do we want to bother ? */
@ -316,7 +263,7 @@ clutter_stage_egl_set_fullscreen (ClutterStage *stage,
XDeleteProperty (stage_egl->xdpy, stage_egl->xwin, atom_WM_STATE);
}
_clutter_stage_sync_viewport (stage);
CLUTTER_SET_PRIVATE_FLAGS(stage, CLUTTER_ACTOR_SYNC_MATRICES);
}
static void
@ -359,8 +306,6 @@ clutter_stage_egl_set_cursor_visible (ClutterStage *stage,
XDefineCursor (stage_egl->xdpy, stage_egl->xwin, curs);
#endif /* HAVE_XFIXES */
}
_clutter_stage_sync_viewport (stage);
}
static void
@ -371,13 +316,6 @@ clutter_stage_egl_set_offscreen (ClutterStage *stage,
G_OBJECT_TYPE_NAME (stage));
}
static void
snapshot_pixbuf_free (guchar *pixels,
gpointer data)
{
g_free (pixels);
}
static void
clutter_stage_egl_draw_to_pixbuf (ClutterStage *stage,
GdkPixbuf *dest,
@ -414,7 +352,6 @@ clutter_stage_egl_class_init (ClutterStageEglClass *klass)
actor_class->hide = clutter_stage_egl_hide;
actor_class->realize = clutter_stage_egl_realize;
actor_class->unrealize = clutter_stage_egl_unrealize;
actor_class->paint = clutter_stage_egl_paint;
actor_class->request_coords = clutter_stage_egl_request_coords;
actor_class->allocate_coords = clutter_stage_egl_allocate_coords;

View File

@ -468,6 +468,33 @@ clutter_backend_glx_get_features (ClutterBackend *backend)
return flags;
}
static void
clutter_backend_glx_redraw (ClutterBackend *backend)
{
ClutterBackendGlx *backend_glx = CLUTTER_BACKEND_GLX (backend);
ClutterStageGlx *stage_glx;
stage_glx = CLUTTER_STAGE_GLX(backend_glx->stage);
clutter_actor_paint (CLUTTER_ACTOR(stage_glx));
/* Why this paint is done in backend as likely GL windowing system
* specific calls, like swapping buffers.
*/
if (stage_glx->xwin)
{
clutter_backend_glx_wait_for_vblank (stage_glx->backend);
glXSwapBuffers (stage_glx->xdpy, stage_glx->xwin);
}
else
{
/* offscreen */
glXWaitGL ();
CLUTTER_GLERR ();
}
}
static void
clutter_backend_glx_class_init (ClutterBackendGlxClass *klass)
{
@ -478,13 +505,14 @@ clutter_backend_glx_class_init (ClutterBackendGlxClass *klass)
gobject_class->dispose = clutter_backend_glx_dispose;
gobject_class->finalize = clutter_backend_glx_finalize;
backend_class->pre_parse = clutter_backend_glx_pre_parse;
backend_class->post_parse = clutter_backend_glx_post_parse;
backend_class->init_stage = clutter_backend_glx_init_stage;
backend_class->init_events = clutter_backend_glx_init_events;
backend_class->get_stage = clutter_backend_glx_get_stage;
backend_class->add_options = clutter_backend_glx_add_options;
backend_class->pre_parse = clutter_backend_glx_pre_parse;
backend_class->post_parse = clutter_backend_glx_post_parse;
backend_class->init_stage = clutter_backend_glx_init_stage;
backend_class->init_events = clutter_backend_glx_init_events;
backend_class->get_stage = clutter_backend_glx_get_stage;
backend_class->add_options = clutter_backend_glx_add_options;
backend_class->get_features = clutter_backend_glx_get_features;
backend_class->redraw = clutter_backend_glx_redraw;
}
static void

View File

@ -305,72 +305,6 @@ clutter_stage_glx_realize (ClutterActor *actor)
return;
}
static void
clutter_stage_glx_paint (ClutterActor *self)
{
ClutterStageGlx *stage_glx = CLUTTER_STAGE_GLX (self);
ClutterStage *stage = CLUTTER_STAGE (self);
ClutterColor stage_color;
static GTimer *timer = NULL;
static guint timer_n_frames = 0;
CLUTTER_NOTE (PAINT, " Redraw enter");
/* Setup FPS count */
if (clutter_get_show_fps ())
{
if (!timer)
timer = g_timer_new ();
}
/* Reset view matrices if needed. */
if (CLUTTER_PRIVATE_FLAGS (self) & CLUTTER_ACTOR_SYNC_MATRICES)
{
cogl_setup_viewport (clutter_actor_get_width (self),
clutter_actor_get_height (self),
171, /* 60 degrees */
CFX_ONE,
CLUTTER_FLOAT_TO_FIXED (0.1),
CLUTTER_FLOAT_TO_FIXED (100.0));
}
/* Setup the initial paint */
clutter_stage_get_color (stage, &stage_color);
cogl_paint_init (&stage_color);
/* chain up to reach ClutterGroup->paint here and actually paint all */
CLUTTER_ACTOR_CLASS (clutter_stage_glx_parent_class)->paint (self);
/* Why this paint is done in backend as likely GL windowing system
* specific calls, like swapping buffers.
*/
if (stage_glx->xwin)
{
clutter_backend_glx_wait_for_vblank (stage_glx->backend);
glXSwapBuffers (stage_glx->xdpy, stage_glx->xwin);
}
else
{
glXWaitGL ();
CLUTTER_GLERR ();
}
/* Complete FPS info */
if (clutter_get_show_fps ())
{
timer_n_frames++;
if (g_timer_elapsed (timer, NULL) >= 1.0)
{
g_print ("*** FPS: %i ***\n", timer_n_frames);
timer_n_frames = 0;
g_timer_start (timer);
}
}
CLUTTER_NOTE (PAINT, " Redraw leave");
}
static void
clutter_stage_glx_allocate_coords (ClutterActor *self,
ClutterActorBox *box)
@ -600,7 +534,6 @@ clutter_stage_glx_class_init (ClutterStageGlxClass *klass)
actor_class->hide = clutter_stage_glx_hide;
actor_class->realize = clutter_stage_glx_realize;
actor_class->unrealize = clutter_stage_glx_unrealize;
actor_class->paint = clutter_stage_glx_paint;
actor_class->request_coords = clutter_stage_glx_request_coords;
actor_class->allocate_coords = clutter_stage_glx_allocate_coords;

View File

@ -113,6 +113,19 @@ clutter_backend_sdl_get_stage (ClutterBackend *backend)
return backend_sdl->stage;
}
static void
clutter_backend_sdl_redraw (ClutterBackend *backend)
{
ClutterBackendSDL *backend_sdl = CLUTTER_BACKEND_SDL (backend);
ClutterStageSDL *stage_sdl;
stage_sdl = CLUTTER_STAGE_SDL(backend_sdl->stage);
clutter_actor_paint (CLUTTER_ACTOR(stage_sdl));
SDL_GL_SwapBuffers();
}
static void
clutter_backend_sdl_finalize (GObject *gobject)
{
@ -181,6 +194,7 @@ clutter_backend_sdl_class_init (ClutterBackendSDLClass *klass)
backend_class->init_events = clutter_backend_sdl_init_events;
backend_class->get_stage = clutter_backend_sdl_get_stage;
backend_class->add_options = clutter_backend_sdl_add_options;
backend_class->redraw = clutter_backend_sdl_redraw;
}
static void

View File

@ -58,6 +58,9 @@ struct _ClutterBackendSDLClass
GType clutter_backend_sdl_get_type (void) G_GNUC_CONST;
void _clutter_events_init (ClutterBackend *backend);
void _clutter_events_uninit (ClutterBackend *backend);
G_END_DECLS
#endif /* __CLUTTER_BACKEND_SDL_H__ */

View File

@ -123,6 +123,91 @@ clutter_event_check (GSource *source)
return SDL_PeepEvents(&events, 1, SDL_PEEKEVENT, SDL_ALLEVENTS);
}
static gboolean
event_translate (ClutterBackend *backend,
ClutterEvent *event,
SDL_Event *sdl_event)
{
/* FIXME: Complete */
gboolean res;
res = TRUE;
switch (sdl_event->type)
{
case SDL_MOUSEBUTTONDOWN:
switch (sdl_event->button.button)
{
case 4: /* up */
case 5: /* down */
case 6: /* left */
case 7: /* right */
event->scroll.type = event->type = CLUTTER_SCROLL;
if (sdl_event->button.button == 4)
event->scroll.direction = CLUTTER_SCROLL_UP;
else if (sdl_event->button.button == 5)
event->scroll.direction = CLUTTER_SCROLL_DOWN;
else if (sdl_event->button.button == 6)
event->scroll.direction = CLUTTER_SCROLL_LEFT;
else
event->scroll.direction = CLUTTER_SCROLL_RIGHT;
event->scroll.time = 0;
event->scroll.x = sdl_event->button.x;
event->scroll.y = sdl_event->button.y;
event->scroll.modifier_state = sdl_event->button.state;
break;
default:
event->button.type = event->type = CLUTTER_BUTTON_PRESS;
event->button.time = 0;
event->button.x = sdl_event->button.x;
event->button.y = sdl_event->button.y;
event->button.modifier_state = sdl_event->button.state;
event->button.button = sdl_event->button.button;
_clutter_event_button_generate (backend, event);
break;
}
break;
case SDL_MOUSEBUTTONUP:
/* scroll events don't have a corresponding release */
if (sdl_event->button.button == 4 ||
sdl_event->button.button == 5 ||
sdl_event->button.button == 6 ||
sdl_event->button.button == 7)
{
res = FALSE;
break;
}
event->button.type = event->type = CLUTTER_BUTTON_RELEASE;
event->button.time = 0;
event->button.x = sdl_event->button.x;
event->button.y = sdl_event->button.y;
event->button.modifier_state = sdl_event->button.state;
event->button.button = sdl_event->button.button;
break;
case SDL_MOUSEMOTION:
event->motion.type = event->type = CLUTTER_MOTION;
event->motion.time = 0;
event->motion.x = sdl_event->motion.x;
event->motion.y = sdl_event->motion.y;
event->motion.modifier_state = sdl_event->motion.state;;
break;
default:
res = FALSE;
break;
}
return res;
}
static gboolean
clutter_event_dispatch (GSource *source,
GSourceFunc callback,
@ -130,6 +215,10 @@ clutter_event_dispatch (GSource *source,
{
SDL_Event sdl_event;
ClutterEvent *event = NULL;
ClutterBackend *backend = ((ClutterEventSource *) source)->backend;
ClutterMainContext *clutter_context;
clutter_context = clutter_context_get_default ();
while (SDL_PollEvent(&sdl_event))
{
@ -141,11 +230,22 @@ clutter_event_dispatch (GSource *source,
SDL_Quit();
exit(0);
}
else
{
event = clutter_event_new (CLUTTER_NOTHING);
if (event_translate (backend, event, &sdl_event))
{
/* push directly here to avoid copy of queue_put */
g_queue_push_head (clutter_context->events_queue, event);
}
else
{
clutter_event_free (event);
}
}
}
return TRUE;
event = clutter_event_get ();
if (event)

View File

@ -77,51 +77,7 @@ clutter_stage_sdl_realize (ClutterActor *actor)
return;
}
_clutter_stage_sync_viewport (CLUTTER_STAGE (stage_sdl));
}
static void
clutter_stage_sdl_paint (ClutterActor *self)
{
ClutterStage *stage = CLUTTER_STAGE (self);
ClutterColor stage_color;
static GTimer *timer = NULL;
static guint timer_n_frames = 0;
CLUTTER_NOTE (PAINT, " Redraw enter");
if (clutter_get_show_fps ())
{
if (!timer)
timer = g_timer_new ();
}
clutter_stage_get_color (stage, &stage_color);
cogl_paint_init (&stage_color);
/* Basically call up to ClutterGroup paint here */
CLUTTER_ACTOR_CLASS (clutter_stage_sdl_parent_class)->paint (self);
/* Why this paint is done in backend as likely GL windowing system
* specific calls, like swapping buffers.
*/
SDL_GL_SwapBuffers();
if (clutter_get_show_fps ())
{
timer_n_frames++;
if (g_timer_elapsed (timer, NULL) >= 1.0)
{
g_print ("*** FPS: %i ***\n", timer_n_frames);
timer_n_frames = 0;
g_timer_start (timer);
}
}
CLUTTER_NOTE (PAINT, " Redraw leave");
CLUTTER_SET_PRIVATE_FLAGS(actor, CLUTTER_ACTOR_SYNC_MATRICES);
}
static void
@ -163,7 +119,7 @@ clutter_stage_sdl_request_coords (ClutterActor *self,
stage_sdl->win_width = new_width;
stage_sdl->win_height = new_height;
_clutter_stage_sync_viewport (CLUTTER_STAGE (stage_sdl));
CLUTTER_SET_PRIVATE_FLAGS(self, CLUTTER_ACTOR_SYNC_MATRICES);
}
}
@ -231,7 +187,6 @@ clutter_stage_sdl_class_init (ClutterStageSDLClass *klass)
actor_class->hide = clutter_stage_sdl_hide;
actor_class->realize = clutter_stage_sdl_realize;
actor_class->unrealize = clutter_stage_sdl_unrealize;
actor_class->paint = clutter_stage_sdl_paint;
actor_class->request_coords = clutter_stage_sdl_request_coords;
actor_class->allocate_coords = clutter_stage_sdl_allocate_coords;