Move the get_actor_at_pos() inside ClutterStage, as it is pure
GL and not GLX. Removed the get_actor_at_pos() and flush() vfuncs from ClutterStageClass: clutter_stage_flush() becomes the private _clutter_stage_sync_viewport() function, which should only be used internally.
This commit is contained in:
parent
65d1a65b49
commit
fa93634d14
@ -137,6 +137,8 @@ void _clutter_synthetise_stage_state (ClutterBackend *backend,
|
||||
ClutterStageState set_flags,
|
||||
ClutterStageState unset_flags);
|
||||
|
||||
void _clutter_stage_sync_viewport (ClutterStage *stage);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* _HAVE_CLUTTER_PRIVATE_H */
|
||||
|
@ -44,6 +44,8 @@
|
||||
#include "clutter-debug.h"
|
||||
#include "clutter-version.h" /* For flavour */
|
||||
|
||||
#include <GL/gl.h>
|
||||
|
||||
#include <gdk-pixbuf-xlib/gdk-pixbuf-xlib.h>
|
||||
|
||||
G_DEFINE_ABSTRACT_TYPE (ClutterStage, clutter_stage, CLUTTER_TYPE_GROUP);
|
||||
@ -581,23 +583,6 @@ clutter_stage_hide_cursor (ClutterStage *stage)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_stage_flush:
|
||||
* @stage: a #ClutterStage
|
||||
*
|
||||
* Flushes the stage. This function is only useful for stage
|
||||
* implementations inside backends or for actors; you should never
|
||||
* need to call this function directly.
|
||||
*/
|
||||
void
|
||||
clutter_stage_flush (ClutterStage *stage)
|
||||
{
|
||||
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
||||
|
||||
if (CLUTTER_STAGE_GET_CLASS (stage)->flush)
|
||||
CLUTTER_STAGE_GET_CLASS (stage)->flush (stage);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_stage_snapshot
|
||||
* @stage: A #ClutterStage
|
||||
@ -637,17 +622,148 @@ clutter_stage_snapshot (ClutterStage *stage,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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;
|
||||
|
||||
frustum (xmin, xmax, ymin, ymax, zNear, zFar);
|
||||
}
|
||||
|
||||
void
|
||||
_clutter_stage_sync_viewport (ClutterStage *stage)
|
||||
{
|
||||
ClutterActor *actor;
|
||||
gint width, height;
|
||||
|
||||
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
||||
|
||||
actor = CLUTTER_ACTOR (stage);
|
||||
|
||||
width = clutter_actor_get_width (actor);
|
||||
height = clutter_actor_get_height (actor);
|
||||
|
||||
glViewport (0, 0, width, height);
|
||||
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glLoadIdentity ();
|
||||
|
||||
perspective (60.0f, 1.0f, 0.1f, 100.0f);
|
||||
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glLoadIdentity ();
|
||||
|
||||
/* Then for 2D like transform */
|
||||
|
||||
/* camera distance from screen, 0.5 * tan (FOV) */
|
||||
#define DEFAULT_Z_CAMERA 0.866025404f
|
||||
|
||||
glTranslatef (-0.5f, -0.5f, -DEFAULT_Z_CAMERA);
|
||||
glScalef ( 1.0f / width,
|
||||
-1.0f / height,
|
||||
1.0f / width);
|
||||
glTranslatef (0.0f, -1.0 * height, 0.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* clutter_stage_get_actor_at_pos:
|
||||
* @stage:
|
||||
* @x:
|
||||
* @y:
|
||||
*
|
||||
* FIXME
|
||||
*
|
||||
* Return value: the actor at the specified coordinates, if any
|
||||
*/
|
||||
ClutterActor *
|
||||
clutter_stage_get_actor_at_pos (ClutterStage *stage,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
ClutterActor *found = NULL;
|
||||
GLuint buff[64] = { 0 };
|
||||
GLint hits;
|
||||
GLint view[4];
|
||||
|
||||
g_return_val_if_fail (CLUTTER_IS_STAGE (stage), NULL);
|
||||
|
||||
glSelectBuffer (sizeof (buff), buff);
|
||||
glGetIntegerv (GL_VIEWPORT, view);
|
||||
glRenderMode (GL_SELECT);
|
||||
|
||||
if (CLUTTER_STAGE_GET_CLASS (stage)->get_actor_at_pos)
|
||||
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);
|
||||
|
||||
perspective (60.0f, 1.0f, 0.1f, 100.0f);
|
||||
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
|
||||
clutter_actor_paint (CLUTTER_ACTOR (stage));
|
||||
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glPopMatrix ();
|
||||
|
||||
hits = glRenderMode (GL_RENDER);
|
||||
|
||||
if (hits != 0)
|
||||
{
|
||||
return CLUTTER_STAGE_GET_CLASS (stage)->get_actor_at_pos (stage, x, y);
|
||||
#if 0
|
||||
gint i
|
||||
for (i = 0; i < hits; i++)
|
||||
g_print ("Hit at %i\n", buff[i * 4 + 3]);
|
||||
#endif
|
||||
|
||||
found = clutter_group_find_child_by_id (CLUTTER_GROUP (stage),
|
||||
buff[(hits-1) * 4 + 3]);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
_clutter_stage_sync_viewport (stage);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
@ -84,9 +84,6 @@ struct _ClutterStageClass
|
||||
gboolean visible);
|
||||
void (* set_offscreen) (ClutterStage *stage,
|
||||
gboolean offscreen);
|
||||
ClutterActor *(* get_actor_at_pos) (ClutterStage *stage,
|
||||
gint x,
|
||||
gint y);
|
||||
void (* draw_to_pixbuf) (ClutterStage *stage,
|
||||
GdkPixbuf *dest,
|
||||
gint x,
|
||||
|
@ -45,75 +45,6 @@
|
||||
|
||||
G_DEFINE_TYPE (ClutterStageGlx, clutter_stage_glx, CLUTTER_TYPE_STAGE);
|
||||
|
||||
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
|
||||
|
||||
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;
|
||||
|
||||
frustum (xmin, xmax, ymin, ymax, zNear, zFar);
|
||||
}
|
||||
|
||||
static void
|
||||
sync_viewport (ClutterStageGlx *stage_glx)
|
||||
{
|
||||
glViewport (0, 0, stage_glx->xwin_width, stage_glx->xwin_height);
|
||||
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glLoadIdentity ();
|
||||
|
||||
perspective (60.0f, 1.0f, 0.1f, 100.0f);
|
||||
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
glLoadIdentity ();
|
||||
|
||||
/* Then for 2D like transform */
|
||||
|
||||
/* camera distance from screen, 0.5 * tan (FOV) */
|
||||
#define DEFAULT_Z_CAMERA 0.866025404f
|
||||
|
||||
glTranslatef (-0.5f, -0.5f, -DEFAULT_Z_CAMERA);
|
||||
glScalef ( 1.0f / stage_glx->xwin_width,
|
||||
-1.0f / stage_glx->xwin_height,
|
||||
1.0f / stage_glx->xwin_width);
|
||||
glTranslatef (0.0f, -1.0 * stage_glx->xwin_height, 0.0f);
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_glx_show (ClutterActor *actor)
|
||||
{
|
||||
@ -349,7 +280,7 @@ clutter_stage_glx_realize (ClutterActor *actor)
|
||||
glXIsDirect (stage_glx->xdpy, stage_glx->gl_context) ? "yes"
|
||||
: "no");
|
||||
|
||||
sync_viewport (stage_glx);
|
||||
_clutter_stage_sync_viewport (CLUTTER_STAGE (stage_glx));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -449,7 +380,7 @@ clutter_stage_glx_request_coords (ClutterActor *self,
|
||||
clutter_actor_realize (self);
|
||||
}
|
||||
|
||||
sync_viewport (stage_glx);
|
||||
_clutter_stage_sync_viewport (CLUTTER_STAGE (stage_glx));
|
||||
}
|
||||
|
||||
if (stage_glx->xwin != None) /* Do we want to bother ? */
|
||||
@ -493,7 +424,7 @@ clutter_stage_glx_set_fullscreen (ClutterStage *stage,
|
||||
XDeleteProperty (stage_glx->xdpy, stage_glx->xwin, atom_WM_STATE);
|
||||
}
|
||||
|
||||
sync_viewport (stage_glx);
|
||||
_clutter_stage_sync_viewport (stage);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -537,7 +468,7 @@ clutter_stage_glx_set_cursor_visible (ClutterStage *stage,
|
||||
#endif /* HAVE_XFIXES */
|
||||
}
|
||||
|
||||
sync_viewport (stage_glx);
|
||||
_clutter_stage_sync_viewport (stage);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -547,61 +478,6 @@ clutter_stage_glx_set_offscreen (ClutterStage *stage,
|
||||
|
||||
}
|
||||
|
||||
static ClutterActor *
|
||||
clutter_stage_glx_get_actor_at_pos (ClutterStage *stage,
|
||||
gint x,
|
||||
gint y)
|
||||
{
|
||||
ClutterActor *found = NULL;
|
||||
GLuint buff[64] = { 0 };
|
||||
GLint hits;
|
||||
GLint view[4];
|
||||
|
||||
glSelectBuffer (sizeof (buff), 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);
|
||||
|
||||
perspective (60.0f, 1.0f, 0.1f, 100.0f);
|
||||
|
||||
glMatrixMode (GL_MODELVIEW);
|
||||
|
||||
clutter_actor_paint (CLUTTER_ACTOR (stage));
|
||||
|
||||
glMatrixMode (GL_PROJECTION);
|
||||
glPopMatrix ();
|
||||
|
||||
hits = glRenderMode(GL_RENDER);
|
||||
|
||||
if (hits != 0)
|
||||
{
|
||||
#if 0
|
||||
gint i
|
||||
for (i = 0; i < hits; i++)
|
||||
g_print ("Hit at %i\n", buff[i * 4 + 3]);
|
||||
#endif
|
||||
|
||||
found = clutter_group_find_child_by_id (CLUTTER_GROUP (stage),
|
||||
buff[(hits-1) * 4 + 3]);
|
||||
}
|
||||
|
||||
clutter_stage_flush (stage);
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
static void
|
||||
snapshot_pixbuf_free (guchar *pixels,
|
||||
gpointer data)
|
||||
@ -671,12 +547,6 @@ clutter_stage_glx_draw_to_pixbuf (ClutterStage *stage,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_glx_flush (ClutterStage *stage)
|
||||
{
|
||||
sync_viewport (CLUTTER_STAGE_GLX (stage));
|
||||
}
|
||||
|
||||
static void
|
||||
clutter_stage_glx_dispose (GObject *gobject)
|
||||
{
|
||||
@ -708,9 +578,7 @@ clutter_stage_glx_class_init (ClutterStageGlxClass *klass)
|
||||
stage_class->set_fullscreen = clutter_stage_glx_set_fullscreen;
|
||||
stage_class->set_cursor_visible = clutter_stage_glx_set_cursor_visible;
|
||||
stage_class->set_offscreen = clutter_stage_glx_set_offscreen;
|
||||
stage_class->get_actor_at_pos = clutter_stage_glx_get_actor_at_pos;
|
||||
stage_class->draw_to_pixbuf = clutter_stage_glx_draw_to_pixbuf;
|
||||
stage_class->flush = clutter_stage_glx_flush;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -131,7 +131,6 @@ Macro evaluating to the height of the #ClutterStage
|
||||
@set_fullscreen:
|
||||
@set_cursor_visible:
|
||||
@set_offscreen:
|
||||
@get_actor_at_pos:
|
||||
@draw_to_pixbuf:
|
||||
@flush:
|
||||
@event:
|
||||
|
Loading…
Reference in New Issue
Block a user