Hi Robert,
Thanks for the reply. Your suggestion helped me diagnose the problem. The
clutter functions are working fine. As far as I can tell, the problem is
with my data source.
I wrote a test program (attached) like you suggested and that cleared things
up.
Thanks a lot,
Uday
On Fri, Feb 5, 2010 at 3:50 AM, Robert Bragg <[email protected]> wrote:
> Hi Uday,
>
> Excerpts from Uday Verma's message of Fri Feb 05 06:15:40 +0000 2010:
>
> >I am trying to upload RGB24 data onto a ClutterTexture
> >using clutter_texture_set_area_from_rgb_data function. I am getting this
> >data from a top-down source device. When I upload this data, things work
> >great but the color and the image are inverted. I think this is expected
> >since the data layout for OGL textures is a little different.
> ClutterTexture and the underlying CoglTexture both consider (0,0) to be
> the top left and (1,1) the bottom right of your texture. When uploading
> data from a pointer, the pointer should reference the first, top-left
> texel.
>
> From what you are saying it *sounds* like a bug in Clutter. I think it
> would help a lot if you are able to write a small test demonstrating
> exactly what you are trying (just runtime generating dummy source device
> data via malloc + a couple of for(;;) loops)
>
> If you could then attach the test to a bug on bugzilla:
> http://bugzilla.o-hand.com/enter_bug.cgi?product=Clutter
> I think that would really help us understand where the problem lies.
>
> kind regards,
> - Robert
> --
> Robert Bragg, Intel Open Source Technology Center
>
/* test-texture.c
Test texture fill functions */
#include <clutter/clutter.h>
#include <string.h>
static ClutterActor *texture_full, *texture_slices;
static guchar *image_buf; /* 512x768 buffer, left to right: black to red, top to bottom: black to green */
static int min (int x, int y) {
return x < y ? x : y;
}
static ClutterActor *
create_empty_texture (int width,
int height)
{
ClutterActor *ret = NULL;
GError *error = NULL;
guchar *buf = NULL;
gint row_stride;
gboolean fill_result;
row_stride = ((width * 3) + 3) & ~3;
buf = (guchar *) g_slice_alloc0 (row_stride * height);
g_assert (buf);
ret = clutter_texture_new ();
fill_result =
clutter_texture_set_from_rgb_data (CLUTTER_TEXTURE (ret),
buf,
FALSE,
width, height,
row_stride,
3,
CLUTTER_TEXTURE_NONE,
&error);
g_assert (fill_result);
g_slice_free1 (row_stride * height, buf);
return ret;
}
static void
create_image_buf (int width, int height) {
gint row_stride = ((width * 3) + 3) & ~3;
gint y, x;
guchar *ptr, *pix;
image_buf = (guchar *) g_slice_alloc0 (row_stride * height);
g_assert (image_buf);
for (y = 0 ; y < height ; y ++) {
ptr = image_buf + row_stride * y;
for (x = 0 ; x < width ; x ++) {
*ptr ++ = (x * 255) / width;
*ptr ++ = (y * 255) / height;
*ptr ++ = 0;
}
}
}
static void
fill_single (ClutterTexture *tex)
{
gboolean fill_status;
fill_status =
clutter_texture_set_from_rgb_data (tex,
image_buf,
FALSE,
512,
768,
((512 * 3) + 3) & ~3,
3,
CLUTTER_TEXTURE_NONE,
NULL);
g_assert (fill_status);
}
static void
fill_slices (ClutterTexture *tex, gint swidth, gint sheight) {
const int bs = 64;
gint y, x;
gint bsbytes = bs * bs * 3;
guchar *dest = g_slice_alloc (bsbytes);
guchar *sptr, *dptr;
gint src_row_stride = ((swidth * 3) + 3) & ~3;
gint dest_row_stride = bs * 3;
g_assert (dest);
for (y = 0 ; y < sheight ; y += bs) {
for (x = 0 ; x < swidth ; x += bs) {
gint w = min (bs, swidth - x);
gint h = min (bs, sheight - x);
gint hi;
gboolean fill_status;
sptr = image_buf + (src_row_stride * y) + x * 3;
dptr = dest;
for (hi = 0 ; hi < h ; hi ++) {
memcpy (dptr, sptr, bs * 3);
dptr += dest_row_stride;
sptr += src_row_stride;
}
/* now write this buffer to our texture */
fill_status =
clutter_texture_set_area_from_rgb_data (tex,
dest,
FALSE,
x, y,
w, h,
dest_row_stride,
3,
CLUTTER_TEXTURE_NONE,
NULL);
g_assert (fill_status);
}
}
g_slice_free1 (bsbytes, dest);
}
int main (int argc, char **argv) {
ClutterActor *stage;
clutter_init (&argc, &argv);
stage = clutter_stage_get_default ();
clutter_actor_set_size (stage, 1024, 768);
texture_full = create_empty_texture (512, 768);
texture_slices = create_empty_texture (512, 768);
clutter_container_add (CLUTTER_CONTAINER (stage),
texture_full,
texture_slices, NULL);
clutter_actor_set_position (texture_full, 0, 0);
clutter_actor_set_position (texture_slices, 512, 0);
clutter_actor_set_size (texture_full, 512, 768);
clutter_actor_set_size (texture_slices, 512, 768);
/* 512x768 buffer, left to right: black to red, top to bottom: black to green */
create_image_buf (512, 768);
fill_single (CLUTTER_TEXTURE (texture_full));
fill_slices (CLUTTER_TEXTURE (texture_slices), 512, 768);
clutter_actor_show_all (stage);
clutter_main ();
return 0;
}