Ejemplo n.º 1
0
static void
assert_region_color (int x,
                     int y,
                     int width,
                     int height,
                     guint8 red,
                     guint8 green,
                     guint8 blue,
                     guint8 alpha)
{
  guint8 *data = g_malloc0 (width * height * 4);
  cogl_read_pixels (x, y, width, height,
                    COGL_READ_PIXELS_COLOR_BUFFER,
                    COGL_PIXEL_FORMAT_RGBA_8888_PRE,
                    data);
  for (y = 0; y < height; y++)
    for (x = 0; x < width; x++)
      {
        guint8 *pixel = &data[y * width * 4 + x * 4];
#if 1
        g_assert (pixel[RED] == red &&
                  pixel[GREEN] == green &&
                  pixel[BLUE] == blue &&
                  pixel[ALPHA] == alpha);
#endif
      }
  g_free (data);
}
static void
validate_result (TestState *state)
{
  GLubyte pixel[4];
  GLint y_off = 90;

  /* NB: We ignore the alpha, since we don't know if our render target is
   * RGB or RGBA */

#define RED 0
#define GREEN 1
#define BLUE 2

  /* Should see a blue pixel */
  cogl_read_pixels (10, y_off, 1, 1,
                    COGL_READ_PIXELS_COLOR_BUFFER,
                    COGL_PIXEL_FORMAT_RGBA_8888_PRE,
                    pixel);
  if (g_test_verbose ())
    g_print ("pixel 0 = %x, %x, %x\n", pixel[RED], pixel[GREEN], pixel[BLUE]);
  g_assert (pixel[RED] == 0 && pixel[GREEN] == 0 && pixel[BLUE] != 0);

#undef RED
#undef GREEN
#undef BLUE

  /* Comment this out if you want visual feedback of what this test
   * paints.
   */
  clutter_main_quit ();
}
Ejemplo n.º 3
0
void shaderAnimation(TCLControl *tcl) {
    int fbWidth = HEIGHT;
    int fbHeight = WIDTH;
    cogl_read_pixels(   0, // start x
                        0, // stary y
                        fbWidth,  // width
                        fbHeight, // height
                        COGL_READ_PIXELS_COLOR_BUFFER,
                        COGL_PIXEL_FORMAT_RGBA_8888,
                        shaderBuffer);

//    printf("Here's the data we pulled from the FB:\n");
//    int pixelLength = 4; // 4 bytes per pixel in the FB (r,g,b,a)
//    for (int i = 0; i < (fbWidth*fbHeight)*pixelLength; i++) {
//        if (i%pixelLength == 0 && i != 0) {
//            printf(", ");
//        }
//        if (i%(fbWidth*pixelLength) == 0 && i != 0) {
//            printf("\n");
//        }
//
//        printf("%i ", shaderBuffer[i]); // Print out the value of this byte in the pixel
//    }
//    printf("\nDone!\n");

    // When we pull data from the on screen display, we will need to
    // know the full size of the on screen shader display so we know where
    // to grab the pixel colors from.
    //
    // Full screen size data is located in configurations.h
    // On screen display size is defined in main.cpp

    int ledIndex = 0; // This is the pixel offset in the actual color array. uint32_t
    int fbIndex = 0;  // This is the pixel BYTE offset in the shaderBuffer
    for (int x = 0; x < WIDTH; x++) {
        for (int y = 0; y < HEIGHT; y++) {

            // Find the ADDRESS of each pixel in the pixbuf via the raw char buffer we built...
            // and bind it to a pointer to a char...
            unsigned char *pixel = &pixels[y * rowstride + x * 3];

            // And directly update that memory location with a new color
            // This AUTOMATICALLY updates the color of the pixbuf!
            // It's just hitting the memory directly!
            pixel[0] = shaderBuffer[fbIndex];//red
            pixel[1] = shaderBuffer[fbIndex+1];//green
            pixel[2] = shaderBuffer[fbIndex+2];//blue

            // Then put colors to the lights themselves:
            uint32_t thisColor = pack(shaderBuffer[fbIndex],shaderBuffer[fbIndex+1],shaderBuffer[fbIndex+2]);
            fbIndex += 4;

            tcl->pixelBuf[ledIndex] = thisColor;
            ledIndex += 1;
        }
    }

}
Ejemplo n.º 4
0
static gboolean
st_background_effect_pre_paint (ClutterEffect *effect)
{
  StBackgroundEffect *self = ST_BACKGROUND_EFFECT (effect);
  ClutterEffectClass *parent_class;
  gfloat width;
  gfloat height;
  gfloat posx;
  gfloat posy;
  guchar *data;
  guint size;
  guint rowstride;
  glong new_time;
  gdouble time_used;
  ClutterActor *stage;
  gfloat stage_width;
  gfloat stage_height;

  if (self->bg_bumpmap == NULL)
    return FALSE;

  if (!clutter_actor_meta_get_enabled (CLUTTER_ACTOR_META (effect)))
    return FALSE;

  self->actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
  if (self->actor == NULL)
    return FALSE;

  if (!clutter_feature_available (CLUTTER_FEATURE_SHADERS_GLSL))
  {
    /* if we don't have support for GLSL shaders then we
     * forcibly disable the ActorMeta
     */
    g_warning ("Unable to use the ShaderEffect: the graphics hardware "
           "or the current GL driver does not implement support "
           "for the GLSL shading language.");
    clutter_actor_meta_set_enabled (CLUTTER_ACTOR_META (effect), FALSE);
    return FALSE;
  }

  new_time = clock();
  time_used = ((double) (new_time - self->old_time)*100) / (double) CLOCKS_PER_SEC;
  self->old_time = new_time;

  posx = 0.0f;
  posy = 0.0f;

  width = 0.0f;
  height = 0.0f;

  stage_width = 0.0f;
  stage_height = 0.0f;

  clutter_actor_get_transformed_position (self->actor, &posx, &posy);
  clutter_actor_get_transformed_size (self->actor, &width, &height);
  self->opacity = clutter_actor_get_paint_opacity (self->actor);
  stage = clutter_actor_get_stage (self->actor);
  clutter_actor_get_size (stage, &stage_width, &stage_height);

  if ((posx < 0) || (posy < 0) || ((posx + width) > stage_width) || ((posy + height) > stage_height))
    return FALSE;

  if  (( posx != self->posx_old)
       || ( posy != self->posy_old)
       || ( width != self->width_old)
       || ( height != self->height_old)
       || (time_used > 50.0))

  {
    self->posx_old = posx;
    self->posy_old = posy;
    self->width_old = width;
    self->height_old = height;

    self->bg_posx_i = round(posx)+2;
    self->bg_posy_i = round(posy)+2;
    self->bg_width_i = round(width)-4;
    self->bg_height_i = round(height)-4;

    size = (self->bg_width_i) * (self->bg_height_i) * 4;

    if (((self->opacity == 0xff) || (self->bg_texture == NULL)) && (size > 400))
      {
        rowstride = (self->bg_width_i) * 4;


        data = g_malloc (size);

        cogl_read_pixels (self->bg_posx_i,
                          self->bg_posy_i,
                          self->bg_width_i,
                          self->bg_height_i,
                          COGL_READ_PIXELS_COLOR_BUFFER,
                          COGL_PIXEL_FORMAT_RGBA_8888_PRE,
                          data);

        if (data != NULL)
          {

            if (self->bg_texture != NULL)
              {
                cogl_handle_unref (self->bg_texture);
                self->bg_texture = NULL;
              }

            self->bg_texture = st_cogl_texture_new_from_data_wrapper  (self->bg_width_i,
                                                                       self->bg_height_i,
                                                                       COGL_TEXTURE_NO_SLICING,
                                                                       COGL_PIXEL_FORMAT_RGBA_8888_PRE,
                                                                       COGL_PIXEL_FORMAT_RGBA_8888_PRE,
                                                                       rowstride,
                                                                       data);

            g_free (data);

          }
      }
  }

  parent_class = CLUTTER_EFFECT_CLASS (st_background_effect_parent_class);

  if (parent_class->pre_paint (effect))
    {
      ClutterOffscreenEffect *offscreen_effect =  CLUTTER_OFFSCREEN_EFFECT (effect);
      CoglHandle fg_texture;

      fg_texture = clutter_offscreen_effect_get_texture (offscreen_effect);

      if (fg_texture != COGL_INVALID_HANDLE)
        {
          self->fg_width_i = cogl_texture_get_width (fg_texture);
          self->fg_height_i = cogl_texture_get_height (fg_texture);

          if ((self->bg_texture != NULL) && (self->opacity == 0xff))
            {


              if (self->pixel_step_uniform0 > -1)
                {
                  gfloat pixel_step[3];

                  pixel_step[0] = 1.0f / (self->bg_width_i);
                  pixel_step[1] = 1.0f / (self->bg_height_i);
                  pixel_step[2] = 0.0f;

                  cogl_pipeline_set_uniform_float (self->pipeline0,
                                                   self->pixel_step_uniform0,
                                                   3,
                                                   1,
                                                   pixel_step);
                }

              if (self->BumpTex_uniform > -1)
                {

                  cogl_pipeline_set_uniform_1i (self->pipeline0,
                                                self->BumpTex_uniform,
                                                1);
                }

              if (self->bump_step_uniform > -1)
                {
                  gfloat bump_step[2];

                  bump_step[0] = 1.0f / (self->bumptex_width_i);
                  bump_step[1] = 1.0f / (self->bumptex_height_i);

                  cogl_pipeline_set_uniform_float (self->pipeline0,
                                                   self->bump_step_uniform,
                                                   2,
                                                   1,
                                                   bump_step);
                }

              if (self->bg_sub_texture != NULL)
                {
                  cogl_handle_unref (self->bg_sub_texture);
                  self->bg_sub_texture = NULL;
                }

              self->bg_sub_texture = st_cogl_texture_new_with_size_wrapper (self->bg_width_i, self->bg_height_i,
                                                                            COGL_TEXTURE_NO_SLICING,
                                                                            COGL_PIXEL_FORMAT_RGBA_8888_PRE);

              cogl_pipeline_set_layer_texture (self->pipeline0, 0, self->bg_texture);

              if (self->pixel_step_uniform1 > -1)
                {
                  gfloat pixel_step[3];

                  pixel_step[0] = 1.0f / (self->bg_width_i);
                  pixel_step[1] = 1.0f / (self->bg_height_i);
                  pixel_step[2] = 1.0f;

                  cogl_pipeline_set_uniform_float (self->pipeline1,
                                                   self->pixel_step_uniform1,
                                                   3,
                                                   1,
                                                   pixel_step);
                }

              if (self->pixel_step_uniform2 > -1)
                {
                  gfloat pixel_step[3];

                  pixel_step[0] = 1.0f / (self->fg_width_i);
                  pixel_step[1] = 1.0f / (self->fg_height_i);
                  pixel_step[2] = 2.0f;

                  cogl_pipeline_set_uniform_float (self->pipeline3,
                                                   self->pixel_step_uniform2,
                                                   3,
                                                   1,
                                                   pixel_step);
                }

            }

          cogl_pipeline_set_layer_texture (self->pipeline2, 0, fg_texture);
          cogl_pipeline_set_layer_texture (self->pipeline3, 0, fg_texture);
          cogl_pipeline_set_layer_texture (self->pipeline4, 0, fg_texture);

        }
      return TRUE;
    }
  else
    {
      return FALSE;
    }
}
Ejemplo n.º 5
0
/* Reads back the contents of a texture by rendering it to the framebuffer
 * and reading back the resulting pixels.
 *
 * It will perform multiple renders if the texture is larger than the
 * current glViewport.
 *
 * It assumes the projection and modelview have already been setup so
 * that rendering to 0,0 with the same width and height of the viewport
 * will exactly cover the viewport.
 *
 * NB: Normally this approach isn't normally used since we can just use
 * glGetTexImage, but may be used as a fallback in some circumstances.
 */
static void
do_texture_draw_and_read (CoglHandle   handle,
                          CoglBitmap  *target_bmp,
                          GLint       *viewport)
{
  int         bpp;
  float       rx1, ry1;
  float       rx2, ry2;
  float       tx1, ty1;
  float       tx2, ty2;
  int         bw,  bh;
  CoglBitmap  *rect_bmp;
  unsigned int  tex_width, tex_height;

  bpp = _cogl_get_format_bpp (COGL_PIXEL_FORMAT_RGBA_8888);

  tex_width = cogl_texture_get_width (handle);
  tex_height = cogl_texture_get_height (handle);

  ry2 = 0;
  ty2 = 0;

  /* Walk Y axis until whole bitmap height consumed */
  for (bh = tex_height; bh > 0; bh -= viewport[3])
    {
      /* Rectangle Y coords */
      ry1 = ry2;
      ry2 += (bh < viewport[3]) ? bh : viewport[3];

      /* Normalized texture Y coords */
      ty1 = ty2;
      ty2 = (ry2 / (float) tex_height);

      rx2 = 0;
      tx2 = 0;

      /* Walk X axis until whole bitmap width consumed */
      for (bw = tex_width; bw > 0; bw-=viewport[2])
        {
          int width;
          int height;
          int rowstride;
          guint8 *data;

          /* Rectangle X coords */
          rx1 = rx2;
          rx2 += (bw < viewport[2]) ? bw : viewport[2];

          width = rx2 - rx1;
          height = ry2 - ry1;
          rowstride = width * bpp;

          /* Normalized texture X coords */
          tx1 = tx2;
          tx2 = (rx2 / (float) tex_width);

          /* Draw a portion of texture */
          cogl_rectangle_with_texture_coords (0, 0,
                                              rx2 - rx1,
                                              ry2 - ry1,
                                              tx1, ty1,
                                              tx2, ty2);

          data = g_malloc (height * rowstride);

          /* Read into a temporary bitmap */
          rect_bmp =
            _cogl_bitmap_new_from_data (data,
                                        COGL_PIXEL_FORMAT_RGBA_8888,
                                        width,
                                        height,
                                        rowstride,
                                        (CoglBitmapDestroyNotify) g_free,
                                        NULL);

          cogl_read_pixels (viewport[0], viewport[1],
                            width,
                            height,
                            COGL_READ_PIXELS_COLOR_BUFFER,
                            COGL_PIXEL_FORMAT_RGBA_8888_PRE,
                            data);

          /* Copy to target bitmap */
          _cogl_bitmap_copy_subregion (rect_bmp,
                                       target_bmp,
                                       0,0,
                                       rx1,ry1,
                                       width,
                                       height);

          /* Free temp bitmap */
          cogl_object_unref (rect_bmp);
        }
    }
}