cbe1e8321b
Some of the tests are making direct GL calls. Eventually we want Clutter not to link directly against any GL library so that it can leave Cogl to load it dynamically. As a step towards getting this to work this patch changes the tests to resolve the symbols using cogl_get_proc_address instead of linking directly.
243 lines
6.7 KiB
C
243 lines
6.7 KiB
C
#include <glib.h>
|
|
#include <gmodule.h>
|
|
#include <stdlib.h>
|
|
#include <clutter/clutter.h>
|
|
#include <cogl/cogl.h>
|
|
|
|
/* Coglbox declaration
|
|
*--------------------------------------------------*/
|
|
|
|
G_BEGIN_DECLS
|
|
|
|
#define TEST_TYPE_COGLBOX test_coglbox_get_type()
|
|
|
|
#define TEST_COGLBOX(obj) \
|
|
(G_TYPE_CHECK_INSTANCE_CAST ((obj), \
|
|
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
|
|
|
#define TEST_COGLBOX_CLASS(klass) \
|
|
(G_TYPE_CHECK_CLASS_CAST ((klass), \
|
|
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
|
|
|
#define TEST_IS_COGLBOX(obj) \
|
|
(G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
|
|
TEST_TYPE_COGLBOX))
|
|
|
|
#define TEST_IS_COGLBOX_CLASS(klass) \
|
|
(G_TYPE_CHECK_CLASS_TYPE ((klass), \
|
|
TEST_TYPE_COGLBOX))
|
|
|
|
#define TEST_COGLBOX_GET_CLASS(obj) \
|
|
(G_TYPE_INSTANCE_GET_CLASS ((obj), \
|
|
TEST_TYPE_COGLBOX, TestCoglboxClass))
|
|
|
|
typedef struct _TestCoglbox TestCoglbox;
|
|
typedef struct _TestCoglboxClass TestCoglboxClass;
|
|
typedef struct _TestCoglboxPrivate TestCoglboxPrivate;
|
|
|
|
struct _TestCoglbox
|
|
{
|
|
ClutterActor parent;
|
|
|
|
/*< private >*/
|
|
TestCoglboxPrivate *priv;
|
|
};
|
|
|
|
struct _TestCoglboxClass
|
|
{
|
|
ClutterActorClass parent_class;
|
|
|
|
/* padding for future expansion */
|
|
void (*_test_coglbox1) (void);
|
|
void (*_test_coglbox2) (void);
|
|
void (*_test_coglbox3) (void);
|
|
void (*_test_coglbox4) (void);
|
|
};
|
|
|
|
static GType test_coglbox_get_type (void) G_GNUC_CONST;
|
|
|
|
G_END_DECLS
|
|
|
|
/* Coglbox private declaration
|
|
*--------------------------------------------------*/
|
|
|
|
G_DEFINE_TYPE (TestCoglbox, test_coglbox, CLUTTER_TYPE_ACTOR);
|
|
|
|
#define TEST_COGLBOX_GET_PRIVATE(obj) \
|
|
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), TEST_TYPE_COGLBOX, TestCoglboxPrivate))
|
|
|
|
struct _TestCoglboxPrivate
|
|
{
|
|
GLuint gl_handle;
|
|
CoglHandle cogl_handle;
|
|
|
|
void
|
|
(* glGetIntegerv) (GLenum pname, GLint *params);
|
|
void
|
|
(* glPixelStorei) (GLenum pname, GLint param);
|
|
void
|
|
(* glTexParameteri) (GLenum target, GLenum pname, GLint param);
|
|
void
|
|
(* glTexImage2D) (GLenum target, GLint level,
|
|
GLint internalFormat,
|
|
GLsizei width, GLsizei height,
|
|
GLint border, GLenum format, GLenum type,
|
|
const GLvoid *pixels);
|
|
void
|
|
(* glGenTextures) (GLsizei n, GLuint *textures);
|
|
void
|
|
(* glDeleteTextures) (GLsizei n, const GLuint *textures);
|
|
void
|
|
(* glBindTexture) (GLenum target, GLuint texture);
|
|
};
|
|
|
|
/* Coglbox implementation
|
|
*--------------------------------------------------*/
|
|
|
|
static void
|
|
test_coglbox_paint(ClutterActor *self)
|
|
{
|
|
TestCoglboxPrivate *priv = TEST_COGLBOX_GET_PRIVATE (self);
|
|
gfloat texcoords[4] = { 0.3f, 0.3f, 0.7f, 0.7f };
|
|
|
|
priv = TEST_COGLBOX_GET_PRIVATE (self);
|
|
|
|
cogl_set_source_color4ub (0x66, 0x66, 0xdd, 0xff);
|
|
cogl_rectangle (0,0,400,400);
|
|
|
|
cogl_push_matrix ();
|
|
|
|
cogl_translate (100,100,0);
|
|
cogl_set_source_texture (priv->cogl_handle);
|
|
cogl_rectangle_with_texture_coords (0, 0, 200, 200,
|
|
texcoords[0], texcoords[1],
|
|
texcoords[2], texcoords[3]);
|
|
|
|
cogl_pop_matrix();
|
|
}
|
|
|
|
static void
|
|
test_coglbox_finalize (GObject *object)
|
|
{
|
|
G_OBJECT_CLASS (test_coglbox_parent_class)->finalize (object);
|
|
}
|
|
|
|
static void
|
|
test_coglbox_dispose (GObject *object)
|
|
{
|
|
TestCoglboxPrivate *priv;
|
|
|
|
priv = TEST_COGLBOX_GET_PRIVATE (object);
|
|
|
|
cogl_handle_unref (priv->cogl_handle);
|
|
priv->glDeleteTextures (1, &priv->gl_handle);
|
|
|
|
G_OBJECT_CLASS (test_coglbox_parent_class)->dispose (object);
|
|
}
|
|
|
|
static void
|
|
test_coglbox_init (TestCoglbox *self)
|
|
{
|
|
TestCoglboxPrivate *priv;
|
|
guchar data[12];
|
|
GLint prev_unpack_alignment;
|
|
GLint prev_2d_texture_binding;
|
|
|
|
self->priv = priv = TEST_COGLBOX_GET_PRIVATE(self);
|
|
|
|
/* Prepare a 2x2 pixels texture */
|
|
|
|
data[0] = 255; data[1] = 0; data[2] = 0;
|
|
data[3] = 0; data[4] = 255; data[5] = 0;
|
|
data[6] = 0; data[7] = 0; data[8] = 255;
|
|
data[9] = 0; data[10] = 0; data[11] = 0;
|
|
|
|
priv->glGetIntegerv = (void *) cogl_get_proc_address ("glGetIntegerv");
|
|
priv->glPixelStorei = (void *) cogl_get_proc_address ("glPixelStorei");
|
|
priv->glTexParameteri = (void *) cogl_get_proc_address ("glTexParameteri");
|
|
priv->glTexImage2D = (void *) cogl_get_proc_address ("glTexImage2D");
|
|
priv->glGenTextures = (void *) cogl_get_proc_address ("glGenTextures");
|
|
priv->glDeleteTextures = (void *) cogl_get_proc_address ("glDeleteTextures");
|
|
priv->glBindTexture = (void *) cogl_get_proc_address ("glBindTexture");
|
|
|
|
/* We are about to use OpenGL directly to create a TEXTURE_2D
|
|
* texture so we need to save the state that we modify so we can
|
|
* restore it afterwards and be sure not to interfere with any state
|
|
* caching that Cogl may do internally.
|
|
*/
|
|
priv->glGetIntegerv (GL_UNPACK_ALIGNMENT, &prev_unpack_alignment);
|
|
priv->glGetIntegerv (GL_TEXTURE_BINDING_2D, &prev_2d_texture_binding);
|
|
|
|
priv->glGenTextures (1, &priv->gl_handle);
|
|
priv->glBindTexture (GL_TEXTURE_2D, priv->gl_handle);
|
|
|
|
priv->glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
|
|
priv->glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB,
|
|
2, 2, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
|
|
|
|
/* Now restore the original GL state as Cogl had left it */
|
|
priv->glPixelStorei (GL_UNPACK_ALIGNMENT, prev_unpack_alignment);
|
|
priv->glBindTexture (GL_TEXTURE_2D, prev_2d_texture_binding);
|
|
|
|
priv->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
|
priv->glTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
|
|
|
/* Create texture from foreign */
|
|
|
|
priv->cogl_handle =
|
|
cogl_texture_new_from_foreign (priv->gl_handle,
|
|
GL_TEXTURE_2D,
|
|
2, 2, 0, 0,
|
|
COGL_PIXEL_FORMAT_RGB_888);
|
|
|
|
if (priv->cogl_handle == COGL_INVALID_HANDLE)
|
|
{
|
|
printf ("Failed creating texture from foreign!\n");
|
|
return;
|
|
}
|
|
}
|
|
|
|
static void
|
|
test_coglbox_class_init (TestCoglboxClass *klass)
|
|
{
|
|
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
|
|
ClutterActorClass *actor_class = CLUTTER_ACTOR_CLASS (klass);
|
|
|
|
gobject_class->finalize = test_coglbox_finalize;
|
|
gobject_class->dispose = test_coglbox_dispose;
|
|
actor_class->paint = test_coglbox_paint;
|
|
|
|
g_type_class_add_private (gobject_class, sizeof (TestCoglboxPrivate));
|
|
}
|
|
|
|
static ClutterActor*
|
|
test_coglbox_new (void)
|
|
{
|
|
return g_object_new (TEST_TYPE_COGLBOX, NULL);
|
|
}
|
|
|
|
G_MODULE_EXPORT int
|
|
test_cogl_tex_foreign_main (int argc, char *argv[])
|
|
{
|
|
ClutterActor *stage;
|
|
ClutterActor *coglbox;
|
|
|
|
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
|
|
return 1;
|
|
|
|
/* Stage */
|
|
stage = clutter_stage_get_default ();
|
|
clutter_actor_set_size (stage, 400, 400);
|
|
clutter_stage_set_title (CLUTTER_STAGE (stage), "Cogl Test");
|
|
|
|
/* Cogl Box */
|
|
coglbox = test_coglbox_new ();
|
|
clutter_container_add_actor (CLUTTER_CONTAINER (stage), coglbox);
|
|
|
|
clutter_actor_show_all (stage);
|
|
|
|
clutter_main ();
|
|
|
|
return 0;
|
|
}
|