Ejemplo n.º 1
0
void
test_primitive_and_journal (void)
{
  CoglPrimitive *primitives[2];
  CoglPipeline *pipeline;

  setup_orthographic_modelview ();
  create_primitives (primitives);
  pipeline = create_pipeline ();

  /* Set a clip to clip all three rectangles to just the bottom half.
   * The journal flushes its own clip state so this verifies that the
   * clip state is correctly restored for the second primitive. */
  cogl_framebuffer_push_rectangle_clip (test_fb,
                                        0, 50, 300, 100);

  cogl_primitive_draw (primitives[0], test_fb, pipeline);

  /* Draw a rectangle using the journal in-between the two primitives.
   * This should test that the journal gets flushed correctly and that
   * the modelview matrix is restored. Half of the rectangle should be
   * overriden by the second primitive */
  cogl_framebuffer_draw_rectangle (test_fb,
                                   pipeline,
                                   100, 0, /* x1/y1 */
                                   300, 100 /* x2/y2 */);

  cogl_primitive_draw (primitives[1], test_fb, pipeline);

  /* Check the three rectangles */
  test_utils_check_region (test_fb,
                           1, 51,
                           98, 48,
                           0xff0000ff);
  test_utils_check_region (test_fb,
                           101, 51,
                           98, 48,
                           0x00ff00ff);
  test_utils_check_region (test_fb,
                           201, 51,
                           98, 48,
                           0x0000ffff);

  /* Check that the top half of all of the rectangles was clipped */
  test_utils_check_region (test_fb,
                           1, 1,
                           298, 48,
                           0x000000ff);

  cogl_framebuffer_pop_clip (test_fb);

  if (cogl_test_verbose ())
    g_print ("OK\n");
}
Ejemplo n.º 2
0
void
_cogl_pango_display_list_render (CoglFramebuffer *fb,
                                 CoglPangoDisplayList *dl,
                                 const CoglColor *color)
{
  GSList *l;

  for (l = dl->nodes; l; l = l->next)
    {
      CoglPangoDisplayListNode *node = l->data;
      CoglColor draw_color;

      if (node->pipeline == NULL)
        {
          if (node->type == COGL_PANGO_DISPLAY_LIST_TEXTURE)
            node->pipeline =
              _cogl_pango_pipeline_cache_get (dl->pipeline_cache,
                                              node->d.texture.texture);
          else
            node->pipeline =
              _cogl_pango_pipeline_cache_get (dl->pipeline_cache,
                                              NULL);
        }

      if (node->color_override)
        /* Use the override color but preserve the alpha from the
           draw color */
        cogl_color_init_from_4ub (&draw_color,
                                  cogl_color_get_red_byte (&node->color),
                                  cogl_color_get_green_byte (&node->color),
                                  cogl_color_get_blue_byte (&node->color),
                                  cogl_color_get_alpha_byte (color));
      else
        draw_color = *color;
      cogl_color_premultiply (&draw_color);

      cogl_pipeline_set_color (node->pipeline, &draw_color);

      switch (node->type)
        {
        case COGL_PANGO_DISPLAY_LIST_TEXTURE:
          _cogl_framebuffer_draw_display_list_texture (fb, node->pipeline, node);
          break;

        case COGL_PANGO_DISPLAY_LIST_RECTANGLE:
          cogl_framebuffer_draw_rectangle (fb,
                                           node->pipeline,
                                           node->d.rectangle.x_1,
                                           node->d.rectangle.y_1,
                                           node->d.rectangle.x_2,
                                           node->d.rectangle.y_2);
          break;

        case COGL_PANGO_DISPLAY_LIST_TRAPEZOID:
          cogl_primitive_draw (node->d.trapezoid.primitive,
                               fb, node->pipeline);
          break;
        }
    }
}
Ejemplo n.º 3
0
static gboolean
paint_cb (void *user_data)
{
    Data *data = user_data;
    CoglError *error = NULL;
    const CoglGLES2Vtable *gles2 = data->gles2_vtable;

    /* Draw scene with GLES2 */
    if (!cogl_push_gles2_context (data->ctx,
                                  data->gles2_ctx,
                                  data->fb,
                                  data->fb,
                                  &error))
    {
        g_error ("Failed to push gles2 context: %s\n", error->message);
    }

    /* Clear offscreen framebuffer with a random color */
    gles2->glClearColor (g_random_double (),
                         g_random_double (),
                         g_random_double (),
                         1.0f);
    gles2->glClear (GL_COLOR_BUFFER_BIT);

    cogl_pop_gles2_context (data->ctx);

    /* Draw scene with Cogl */
    cogl_primitive_draw (data->triangle, data->fb, data->pipeline);

    cogl_onscreen_swap_buffers (COGL_ONSCREEN (data->fb));

    return FALSE; /* remove the callback */
}
Ejemplo n.º 4
0
static test_draw_frame_and_swap (TestData *data)
{
  if (data->context)
    {
      cogl_primitive_draw (data->triangle);
      cogl_framebuffer_swap_buffers (data->fb);
    }
}
Ejemplo n.º 5
0
static void
paint (void)
{
  CoglPipeline *pipeline = cogl_pipeline_new (test_ctx);
  int width = cogl_framebuffer_get_width (test_fb);
  int half_width = width / 2;
  int height = cogl_framebuffer_get_height (test_fb);
  CoglVertexP2 tri0_vertices[] = {
        { 0, 0 },
        { 0, height },
        { half_width, height },
  };
  CoglVertexP2C4 tri1_vertices[] = {
        { half_width, 0, 0x80, 0x80, 0x80, 0x80 },
        { half_width, height, 0x80, 0x80, 0x80, 0x80 },
        { width, height, 0x80, 0x80, 0x80, 0x80 },
  };
  CoglPrimitive *tri0;
  CoglPrimitive *tri1;

  cogl_framebuffer_clear4f (test_fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 0);

  tri0 = cogl_primitive_new_p2 (test_ctx, COGL_VERTICES_MODE_TRIANGLES,
                                3, tri0_vertices);
  tri1 = cogl_primitive_new_p2c4 (test_ctx, COGL_VERTICES_MODE_TRIANGLES,
                                  3, tri1_vertices);

  /* Check that cogl correctly handles the case where we draw
   * different primitives same pipeline and switch from using the
   * opaque color associated with the pipeline and using a colour
   * attribute with an alpha component which implies blending is
   * required.
   *
   * If Cogl gets this wrong then then in all likelyhood the second
   * primitive will be drawn with blending still disabled.
   */

  cogl_primitive_draw (tri0, test_fb, pipeline);
  cogl_primitive_draw (tri1, test_fb, pipeline);

  test_utils_check_pixel_and_alpha (test_fb,
                                    half_width + 5,
                                    height - 5,
                                    0x80808080);
}
Ejemplo n.º 6
0
static void
test_float_verts (TestState *state, int offset_x, int offset_y)
{
  CoglAttribute *attributes[2];
  CoglAttributeBuffer *buffer;
  CoglPrimitive *primitive;

  static const FloatVert float_verts[] =
    {
      { 0, 10, /**/ 1, 0, 0, 1 },
      { 10, 10, /**/ 1, 0, 0, 1 },
      { 5, 0, /**/ 1, 0, 0, 1 },

      { 10, 10, /**/ 0, 1, 0, 1 },
      { 20, 10, /**/ 0, 1, 0, 1 },
      { 15, 0, /**/ 0, 1, 0, 1 }
    };

  buffer = cogl_attribute_buffer_new (test_ctx,
                                      sizeof (float_verts), float_verts);
  attributes[0] = cogl_attribute_new (buffer,
                                      "cogl_position_in",
                                      sizeof (FloatVert),
                                      G_STRUCT_OFFSET (FloatVert, x),
                                      2, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_SHORT);
  attributes[1] = cogl_attribute_new (buffer,
                                      "color",
                                      sizeof (FloatVert),
                                      G_STRUCT_OFFSET (FloatVert, r),
                                      4, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_FLOAT);

  cogl_framebuffer_push_matrix (test_fb);
  cogl_framebuffer_translate (test_fb, offset_x, offset_y, 0.0f);

  primitive = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLES,
                                                  6, /* n_vertices */
                                                  attributes,
                                                  2); /* n_attributes */
  cogl_primitive_draw (primitive, test_fb, state->pipeline);
  cogl_object_unref (primitive);

  cogl_framebuffer_pop_matrix (test_fb);

  cogl_object_unref (attributes[1]);
  cogl_object_unref (attributes[0]);
  cogl_object_unref (buffer);

  test_utils_check_pixel (test_fb, offset_x + 5, offset_y + 5, 0xff0000ff);
  test_utils_check_pixel (test_fb, offset_x + 15, offset_y + 5, 0x00ff00ff);
}
Ejemplo n.º 7
0
static void
paint (Data *data)
{
  CoglFramebuffer *fb = data->fb;
  float rotation;

  cogl_framebuffer_clear4f (fb,
                            COGL_BUFFER_BIT_COLOR|COGL_BUFFER_BIT_DEPTH,
                            0, 0, 0, 1);

  cogl_framebuffer_push_matrix (fb);

  cogl_framebuffer_translate (fb,
                              data->framebuffer_width / 2,
                              data->framebuffer_height / 2,
                              0);

  cogl_framebuffer_scale (fb, 75, 75, 75);

  /* Update the rotation based on the time the application has been
     running so that we get a linear animation regardless of the frame
     rate */
  rotation = g_timer_elapsed (data->timer, NULL) * 60.0f;

  /* Rotate the cube separately around each axis.
   *
   * Note: Cogl matrix manipulation follows the same rules as for
   * OpenGL. We use column-major matrices and - if you consider the
   * transformations happening to the model - then they are combined
   * in reverse order which is why the rotation is done last, since
   * we want it to be a rotation around the origin, before it is
   * scaled and translated.
   */
  cogl_framebuffer_rotate (fb, rotation, 0, 0, 1);
  cogl_framebuffer_rotate (fb, rotation, 0, 1, 0);
  cogl_framebuffer_rotate (fb, rotation, 1, 0, 0);

  cogl_primitive_draw (data->prim, fb, data->crate_pipeline);

  cogl_framebuffer_pop_matrix (fb);

  /* And finally render our Pango layouts... */

  cogl_pango_show_layout (fb,
                          data->hello_label,
                          (data->framebuffer_width / 2) -
                          (data->hello_label_width / 2),
                          (data->framebuffer_height / 2) -
                          (data->hello_label_height / 2),
                          &white);
}
Ejemplo n.º 8
0
void
cogl_path_stroke (CoglPath *path,
                  CoglFramebuffer *framebuffer,
                  CoglPipeline *pipeline)
{
  CoglPathData *data;
  CoglPipeline *copy = NULL;
  unsigned int path_start;
  int path_num = 0;
  CoglPathNode *node;

  _COGL_RETURN_IF_FAIL (cogl_is_path (path));
  _COGL_RETURN_IF_FAIL (cogl_is_framebuffer (framebuffer));
  _COGL_RETURN_IF_FAIL (cogl_is_pipeline (pipeline));

  data = path->data;

  if (data->path_nodes->len == 0)
    return;

  if (cogl_pipeline_get_n_layers (pipeline) != 0)
    {
      copy = cogl_pipeline_copy (pipeline);
      _cogl_pipeline_prune_to_n_layers (copy, 0);
      pipeline = copy;
    }

  _cogl_path_build_stroke_attribute_buffer (path);

  for (path_start = 0;
       path_start < data->path_nodes->len;
       path_start += node->path_size)
    {
      CoglPrimitive *primitive;

      node = &g_array_index (data->path_nodes, CoglPathNode, path_start);

      primitive =
        cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_LINE_STRIP,
                                            node->path_size,
                                            &data->stroke_attributes[path_num],
                                            1);
      cogl_primitive_draw (primitive, framebuffer, pipeline);
      cogl_object_unref (primitive);

      path_num++;
    }

  if (copy)
    cogl_object_unref (copy);
}
Ejemplo n.º 9
0
static void
redraw (Data *data)
{
  CoglFramebuffer *fb = data->fb;

  cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);

  cogl_framebuffer_push_matrix (fb);
  cogl_framebuffer_translate (fb, data->center_x, -data->center_y, 0.0f);

  cogl_primitive_draw (data->triangle, fb, data->pipeline);
  cogl_framebuffer_pop_matrix (fb);

  cogl_onscreen_swap_buffers (COGL_ONSCREEN (fb));
}
Ejemplo n.º 10
0
Archivo: cogland.c Proyecto: 3v1n0/cogl
static CoglBool
paint_cb (void *user_data)
{
  CoglandCompositor *compositor = user_data;
  GList *l;

  for (l = compositor->outputs; l; l = l->next)
    {
      CoglandOutput *output = l->data;
      CoglFramebuffer *fb = output->onscreen;
      GList *l2;

      cogl_framebuffer_clear4f (fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);

      cogl_primitive_draw (compositor->triangle,
                           fb, compositor->triangle_pipeline);

      for (l2 = compositor->surfaces; l2; l2 = l2->next)
        {
          CoglandSurface *surface = l2->data;

          if (surface->texture)
            {
              CoglTexture2D *texture = surface->texture;
              CoglPipeline *pipeline =
                cogl_pipeline_new (compositor->cogl_context);
              cogl_pipeline_set_layer_texture (pipeline, 0, texture);
              cogl_framebuffer_draw_rectangle (fb, pipeline, -1, 1, 1, -1);
              cogl_object_unref (pipeline);
            }
        }
      cogl_onscreen_swap_buffers (COGL_ONSCREEN (fb));
    }

  while (!wl_list_empty (&compositor->frame_callbacks))
    {
      CoglandFrameCallback *callback =
        wl_container_of (compositor->frame_callbacks.next, callback, link);

      wl_callback_send_done (callback->resource, get_time ());
      wl_resource_destroy (callback->resource);
    }

  compositor->redraw_idle = 0;

  return G_SOURCE_REMOVE;
}
Ejemplo n.º 11
0
static gboolean
paint_cb (void *user_data)
{
  CoglandCompositor *compositor = user_data;
  GList *l;

  for (l = compositor->outputs; l; l = l->next)
    {
      CoglandOutput *output = l->data;
      CoglFramebuffer *fb = COGL_FRAMEBUFFER (output->onscreen);
      GList *l2;

      cogl_push_framebuffer (fb);

#if 0
      cogl_framebuffer_clear (fb, COGL_BUFFER_BIT_COLOR);
#else
      cogl_clear (&black, COGL_BUFFER_BIT_COLOR);
#endif
      cogl_primitive_draw (compositor->triangle);

      for (l2 = compositor->surfaces; l2; l2 = l2->next)
        {
          CoglandSurface *surface = l2->data;

          if (surface->buffer)
            {
              CoglTexture2D *texture = surface->buffer->texture;
              cogl_set_source_texture (texture);
              cogl_rectangle (-1, 1, 1, -1);
            }
          wl_display_post_frame (compositor->wayland_display,
                                 &surface->wayland_surface, get_time ());
        }
      cogl_framebuffer_swap_buffers (fb);


      cogl_pop_framebuffer ();

    }

  return TRUE;
}
Ejemplo n.º 12
0
/**
 * mash_data_render:
 * @self: A #MashData instance
 *
 * Renders the data contained in the model to the Clutter
 * scene. The current Cogl source material will be used to affect the
 * appearance of the model. This function is not usually called
 * directly but instead the #MashData instance is added to a
 * #MashModel and this function will be automatically called by
 * the paint method of the model.
 */
void
mash_data_render (MashData *self, CoglPipeline* pl){
    MashDataPrivate *priv;
    g_return_if_fail (MASH_IS_DATA (self));
    priv = self->priv;

    if (priv->loaded_data.prim != NULL){
        CoglFramebuffer     *fb  = /*(CoglFramebuffer*)*/ cogl_get_draw_framebuffer();
        cogl_primitive_draw(priv->loaded_data.prim, fb, pl);
    }
    else if(priv->loaded_data.vertices_vbo != NULL && priv->loaded_data.indices != NULL){
        cogl_vertex_buffer_draw_elements (priv->loaded_data.vertices_vbo,
                                    COGL_VERTICES_MODE_TRIANGLES,
                                    priv->loaded_data.indices,
                                    priv->loaded_data.min_index,
                                    priv->loaded_data.max_index,
                                    0, priv->loaded_data.n_triangles * 3);
    }
}
Ejemplo n.º 13
0
static void
do_test (CoglBool check_orientation)
{
  int fb_width = cogl_framebuffer_get_width (test_fb);
  int fb_height = cogl_framebuffer_get_height (test_fb);
  CoglPrimitive *prim;
  CoglError *error = NULL;
  CoglTexture2D *tex_2d;
  CoglPipeline *pipeline, *solid_pipeline;
  CoglBool res;
  int tex_height;

  cogl_framebuffer_orthographic (test_fb,
                                 0, 0, /* x_1, y_1 */
                                 fb_width, /* x_2 */
                                 fb_height /* y_2 */,
                                 -1, 100 /* near/far */);

  cogl_framebuffer_clear4f (test_fb,
                            COGL_BUFFER_BIT_COLOR,
                            1.0f, 1.0f, 1.0f, 1.0f);

  /* If we're not checking the orientation of the point sprite then
   * we'll set the height of the texture to 1 so that the vertical
   * orientation does not matter */
  if (check_orientation)
    tex_height = 2;
  else
    tex_height = 1;

  tex_2d = cogl_texture_2d_new_from_data (test_ctx,
                                          2, tex_height, /* width/height */
                                          COGL_PIXEL_FORMAT_RGB_888,
                                          COGL_PIXEL_FORMAT_ANY,
                                          6, /* row stride */
                                          tex_data,
                                          &error);
  g_assert (tex_2d != NULL);
  g_assert (error == NULL);

  pipeline = cogl_pipeline_new (test_ctx);
  cogl_pipeline_set_layer_texture (pipeline, 0, COGL_TEXTURE (tex_2d));

  res = cogl_pipeline_set_layer_point_sprite_coords_enabled (pipeline,
                                                             /* layer_index */
                                                             0,
                                                             /* enable */
                                                             TRUE,
                                                             &error);
  g_assert (res == TRUE);
  g_assert (error == NULL);

  cogl_pipeline_set_layer_filters (pipeline,
                                   0, /* layer_index */
                                   COGL_PIPELINE_FILTER_NEAREST,
                                   COGL_PIPELINE_FILTER_NEAREST);
  cogl_pipeline_set_point_size (pipeline, POINT_SIZE);

  prim = cogl_primitive_new_p2t2 (test_ctx,
                                  COGL_VERTICES_MODE_POINTS,
                                  1, /* n_vertices */
                                  &point);

  cogl_primitive_draw (prim, test_fb, pipeline);

  /* Render the primitive again without point sprites to make sure
     disabling it works */
  solid_pipeline = cogl_pipeline_copy (pipeline);
  cogl_pipeline_set_layer_point_sprite_coords_enabled (solid_pipeline,
                                                       /* layer_index */
                                                       0,
                                                       /* enable */
                                                       FALSE,
                                                       &error);
  cogl_framebuffer_push_matrix (test_fb);
  cogl_framebuffer_translate (test_fb,
                              POINT_SIZE * 2, /* x */
                              0.0f, /* y */
                              0.0f /* z */);
  cogl_primitive_draw (prim, test_fb, solid_pipeline);
  cogl_framebuffer_pop_matrix (test_fb);

  cogl_object_unref (prim);
  cogl_object_unref (solid_pipeline);
  cogl_object_unref (pipeline);
  cogl_object_unref (tex_2d);

  test_utils_check_pixel (test_fb,
                          POINT_SIZE - POINT_SIZE / 4,
                          POINT_SIZE - POINT_SIZE / 4,
                          0x0000ffff);
  test_utils_check_pixel (test_fb,
                          POINT_SIZE + POINT_SIZE / 4,
                          POINT_SIZE - POINT_SIZE / 4,
                          0x00ff00ff);
  test_utils_check_pixel (test_fb,
                          POINT_SIZE - POINT_SIZE / 4,
                          POINT_SIZE + POINT_SIZE / 4,
                          check_orientation ?
                          0x00ffffff :
                          0x0000ffff);
  test_utils_check_pixel (test_fb,
                          POINT_SIZE + POINT_SIZE / 4,
                          POINT_SIZE + POINT_SIZE / 4,
                          check_orientation ?
                          0xff0000ff :
                          0x00ff00ff);

  /* When rendering without the point sprites all of the texture
     coordinates should be 0,0 so it should get the top-left texel
     which is blue */
  test_utils_check_region (test_fb,
                           POINT_SIZE * 3 - POINT_SIZE / 2 + 1,
                           POINT_SIZE - POINT_SIZE / 2 + 1,
                           POINT_SIZE - 2, POINT_SIZE - 2,
                           0x0000ffff);

  if (cogl_test_verbose ())
    g_print ("OK\n");
}
Ejemplo n.º 14
0
// This is the main rendering function that you have to implement and provide to ImGui (via setting up 'RenderDrawListsFn' in the ImGuiIO structure)
// If text or lines are blurry when integrating ImGui in your engine:
// - in your Render function, try translating your projection matrix by (0.5f,0.5f) or (0.375f,0.375f)
void ImGui_ImplGtk3Cogl_RenderDrawData(ImDrawData* draw_data)
{
    // Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
    ImGuiIO& io = ImGui::GetIO();
    int fb_width = (int)(io.DisplaySize.x * io.DisplayFramebufferScale.x);
    int fb_height = (int)(io.DisplaySize.y * io.DisplayFramebufferScale.y);
    if (fb_width == 0 || fb_height == 0)
        return;
    draw_data->ScaleClipRects(io.DisplayFramebufferScale);

    cogl_framebuffer_orthographic(g_Framebuffer, 0, 0,
                                  io.DisplaySize.x, io.DisplaySize.y,
                                  -1, 1);

    CoglContext *context = cogl_framebuffer_get_context(g_Framebuffer);
    for (int n = 0; n < draw_data->CmdListsCount; n++)
    {
        const ImDrawList* cmd_list = draw_data->CmdLists[n];
        int idx_buffer_offset = 0;

        CoglAttributeBuffer *vertices =
            cogl_attribute_buffer_new(context,
                                      cmd_list->VtxBuffer.Size * sizeof(ImDrawVert),
                                      cmd_list->VtxBuffer.Data);

#define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT))
        CoglAttribute *attrs[3] = {
            cogl_attribute_new(vertices, "cogl_position_in",
                               sizeof(ImDrawVert), OFFSETOF(ImDrawVert, pos),
                               2, COGL_ATTRIBUTE_TYPE_FLOAT),
            cogl_attribute_new(vertices, "cogl_tex_coord0_in",
                               sizeof(ImDrawVert), OFFSETOF(ImDrawVert, uv),
                               2, COGL_ATTRIBUTE_TYPE_FLOAT),
            cogl_attribute_new(vertices, "cogl_color_in",
                               sizeof(ImDrawVert), OFFSETOF(ImDrawVert, col),
                               4, COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE)
        };
#undef OFFSETOF

        CoglPrimitive *primitive =
            cogl_primitive_new_with_attributes(COGL_VERTICES_MODE_TRIANGLES,
                                               cmd_list->VtxBuffer.Size,
                                               attrs, 3);

        CoglIndices *indices = cogl_indices_new(context,
                                                sizeof(ImDrawIdx) == 2 ?
                                                COGL_INDICES_TYPE_UNSIGNED_SHORT :
                                                COGL_INDICES_TYPE_UNSIGNED_INT,
                                                cmd_list->IdxBuffer.Data,
                                                cmd_list->IdxBuffer.Size);

        for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++)
        {
            const ImDrawCmd* pcmd = &cmd_list->CmdBuffer[cmd_i];

            cogl_indices_set_offset(indices, sizeof(ImDrawIdx) * idx_buffer_offset);
            cogl_primitive_set_indices(primitive, indices, pcmd->ElemCount);

            if (pcmd->UserCallback)
            {
                pcmd->UserCallback(cmd_list, pcmd);
            }
            else
            {
                bool has_texture = pcmd->TextureId != NULL;
                CoglPipeline *pipeline =
                    has_texture ?
                    (cogl_is_pipeline(pcmd->TextureId) ?
                     (CoglPipeline *) pcmd->TextureId : g_ImagePipeline) :
                    g_ColorPipeline;

                if (has_texture && pipeline == g_ImagePipeline) {
                    cogl_pipeline_set_layer_texture(g_ImagePipeline, 0,
                                                    COGL_TEXTURE(pcmd->TextureId));
                }

                cogl_framebuffer_push_scissor_clip(g_Framebuffer,
                                                   pcmd->ClipRect.x,
                                                   pcmd->ClipRect.y,
                                                   pcmd->ClipRect.z - pcmd->ClipRect.x,
                                                   pcmd->ClipRect.w - pcmd->ClipRect.y);
                cogl_primitive_draw(primitive, g_Framebuffer, pipeline);
                cogl_framebuffer_pop_clip(g_Framebuffer);
            }
            idx_buffer_offset += pcmd->ElemCount;
        }

        for (int i = 0; i < 3; i++)
            cogl_object_unref(attrs[i]);
        cogl_object_unref(primitive);
        cogl_object_unref(vertices);
        cogl_object_unref(indices);
    }
}
Ejemplo n.º 15
0
void
test_map_buffer_range (void)
{
  CoglTexture2D *tex;
  CoglPipeline *pipeline;
  int fb_width, fb_height;
  CoglAttributeBuffer *buffer;
  CoglVertexP2T2 *data;
  CoglAttribute *pos_attribute;
  CoglAttribute *tex_coord_attribute;
  CoglPrimitive *primitive;

  tex = cogl_texture_2d_new_from_data (test_ctx,
                                       2, 2, /* width/height */
                                       COGL_PIXEL_FORMAT_RGBA_8888_PRE,
                                       COGL_PIXEL_FORMAT_ANY,
                                       2 * 4, /* rowstride */
                                       tex_data,
                                       NULL /* error */);

  pipeline = cogl_pipeline_new (test_ctx);

  cogl_pipeline_set_layer_texture (pipeline, 0, COGL_TEXTURE (tex));
  cogl_pipeline_set_layer_filters (pipeline,
                                   0, /* layer */
                                   COGL_PIPELINE_FILTER_NEAREST,
                                   COGL_PIPELINE_FILTER_NEAREST);
  cogl_pipeline_set_layer_wrap_mode (pipeline,
                                     0, /* layer */
                                     COGL_PIPELINE_WRAP_MODE_CLAMP_TO_EDGE);

  fb_width = cogl_framebuffer_get_width (test_fb);
  fb_height = cogl_framebuffer_get_height (test_fb);

  buffer = cogl_attribute_buffer_new (test_ctx,
                                      sizeof (vertex_data),
                                      vertex_data);

  /* Replace the texture coordinates of the third vertex with the
   * coordinates for a green texel */
  data = cogl_buffer_map_range (COGL_BUFFER (buffer),
                                sizeof (vertex_data[0]) * 2,
                                sizeof (vertex_data[0]),
                                COGL_BUFFER_ACCESS_WRITE,
                                COGL_BUFFER_MAP_HINT_DISCARD_RANGE,
                                NULL); /* don't catch errors */
  g_assert (data != NULL);

  data->x = vertex_data[2].x;
  data->y = vertex_data[2].y;
  data->s = 1.0f;
  data->t = 0.0f;

  cogl_buffer_unmap (COGL_BUFFER (buffer));

  pos_attribute =
    cogl_attribute_new (buffer,
                        "cogl_position_in",
                        sizeof (vertex_data[0]),
                        offsetof (CoglVertexP2T2, x),
                        2, /* n_components */
                        COGL_ATTRIBUTE_TYPE_FLOAT);
  tex_coord_attribute =
    cogl_attribute_new (buffer,
                        "cogl_tex_coord_in",
                        sizeof (vertex_data[0]),
                        offsetof (CoglVertexP2T2, s),
                        2, /* n_components */
                        COGL_ATTRIBUTE_TYPE_FLOAT);

  cogl_framebuffer_clear4f (test_fb,
                            COGL_BUFFER_BIT_COLOR,
                            0, 0, 0, 1);

  primitive =
    cogl_primitive_new (COGL_VERTICES_MODE_TRIANGLE_STRIP,
                        4, /* n_vertices */
                        pos_attribute,
                        tex_coord_attribute,
                        NULL);
  cogl_primitive_draw (primitive, test_fb, pipeline);
  cogl_object_unref (primitive);

  /* Top left pixel should be the one that is replaced to be green */
  test_utils_check_pixel (test_fb, 1, 1, 0x00ff00ff);
  /* The other three corners should be left as red */
  test_utils_check_pixel (test_fb, fb_width - 2, 1, 0xff0000ff);
  test_utils_check_pixel (test_fb, 1, fb_height - 2, 0xff0000ff);
  test_utils_check_pixel (test_fb, fb_width - 2, fb_height - 2, 0xff0000ff);

  cogl_object_unref (buffer);
  cogl_object_unref (pos_attribute);
  cogl_object_unref (tex_coord_attribute);

  cogl_object_unref (pipeline);
  cogl_object_unref (tex);

  if (cogl_test_verbose ())
    g_print ("OK\n");
}
Ejemplo n.º 16
0
static void
do_test (CoglBool check_orientation,
         CoglBool use_glsl)
{
  int fb_width = cogl_framebuffer_get_width (test_fb);
  int fb_height = cogl_framebuffer_get_height (test_fb);
  CoglPrimitive *prim;
  CoglError *error = NULL;
  CoglTexture2D *tex_2d;
  CoglPipeline *pipeline, *solid_pipeline;
  int tex_height;

  cogl_framebuffer_orthographic (test_fb,
                                 0, 0, /* x_1, y_1 */
                                 fb_width, /* x_2 */
                                 fb_height /* y_2 */,
                                 -1, 100 /* near/far */);

  cogl_framebuffer_clear4f (test_fb,
                            COGL_BUFFER_BIT_COLOR,
                            1.0f, 1.0f, 1.0f, 1.0f);

  /* If we're not checking the orientation of the point sprite then
   * we'll set the height of the texture to 1 so that the vertical
   * orientation does not matter */
  if (check_orientation)
    tex_height = 2;
  else
    tex_height = 1;

  tex_2d = cogl_texture_2d_new_from_data (test_ctx,
                                          2, tex_height, /* width/height */
                                          COGL_PIXEL_FORMAT_RGB_888,
                                          COGL_PIXEL_FORMAT_ANY,
                                          6, /* row stride */
                                          tex_data,
                                          &error);
  g_assert (tex_2d != NULL);
  g_assert (error == NULL);

  pipeline = cogl_pipeline_new (test_ctx);
  cogl_pipeline_set_layer_texture (pipeline, 0, tex_2d);

  cogl_pipeline_set_layer_filters (pipeline,
                                   0, /* layer_index */
                                   COGL_PIPELINE_FILTER_NEAREST,
                                   COGL_PIPELINE_FILTER_NEAREST);
  cogl_pipeline_set_point_size (pipeline, POINT_SIZE);

  /* If we're using GLSL then we don't need to enable point sprite
   * coords and we can just directly reference cogl_point_coord in the
   * snippet */
  if (use_glsl)
    {
      CoglSnippet *snippet =
        cogl_snippet_new (COGL_SNIPPET_HOOK_TEXTURE_LOOKUP,
                          NULL, /* declarations */
                          NULL /* post */);
      static const char source[] =
        "  cogl_texel = texture2D (cogl_sampler, cogl_point_coord);\n";

      cogl_snippet_set_replace (snippet, source);

      /* Keep a reference to the original pipeline because there is no
       * way to remove a snippet in order to recreate the solid
       * pipeline */
      solid_pipeline = cogl_pipeline_copy (pipeline);

      cogl_pipeline_add_layer_snippet (pipeline, 0, snippet);

      cogl_object_unref (snippet);
    }
  else
    {
      CoglBool res =
        cogl_pipeline_set_layer_point_sprite_coords_enabled (pipeline,
                                                             /* layer_index */
                                                             0,
                                                             /* enable */
                                                             TRUE,
                                                             &error);
      g_assert (res == TRUE);
      g_assert (error == NULL);

      solid_pipeline = cogl_pipeline_copy (pipeline);

      res =
        cogl_pipeline_set_layer_point_sprite_coords_enabled (solid_pipeline,
                                                             /* layer_index */
                                                             0,
                                                             /* enable */
                                                             FALSE,
                                                             &error);

      g_assert (res == TRUE);
      g_assert (error == NULL);
    }

  prim = cogl_primitive_new_p2t2 (test_ctx,
                                  COGL_VERTICES_MODE_POINTS,
                                  1, /* n_vertices */
                                  &point);

  cogl_primitive_draw (prim, test_fb, pipeline);

  /* Render the primitive again without point sprites to make sure
     disabling it works */

  cogl_framebuffer_push_matrix (test_fb);
  cogl_framebuffer_translate (test_fb,
                              POINT_SIZE * 2, /* x */
                              0.0f, /* y */
                              0.0f /* z */);
  cogl_primitive_draw (prim, test_fb, solid_pipeline);
  cogl_framebuffer_pop_matrix (test_fb);

  cogl_object_unref (prim);
  cogl_object_unref (solid_pipeline);
  cogl_object_unref (pipeline);
  cogl_object_unref (tex_2d);

  test_utils_check_pixel (test_fb,
                          POINT_SIZE - POINT_SIZE / 4,
                          POINT_SIZE - POINT_SIZE / 4,
                          0x0000ffff);
  test_utils_check_pixel (test_fb,
                          POINT_SIZE + POINT_SIZE / 4,
                          POINT_SIZE - POINT_SIZE / 4,
                          0x00ff00ff);
  test_utils_check_pixel (test_fb,
                          POINT_SIZE - POINT_SIZE / 4,
                          POINT_SIZE + POINT_SIZE / 4,
                          check_orientation ?
                          0x00ffffff :
                          0x0000ffff);
  test_utils_check_pixel (test_fb,
                          POINT_SIZE + POINT_SIZE / 4,
                          POINT_SIZE + POINT_SIZE / 4,
                          check_orientation ?
                          0xff0000ff :
                          0x00ff00ff);

  /* When rendering without the point sprites all of the texture
     coordinates should be 0,0 so it should get the top-left texel
     which is blue */
  test_utils_check_region (test_fb,
                           POINT_SIZE * 3 - POINT_SIZE / 2 + 1,
                           POINT_SIZE - POINT_SIZE / 2 + 1,
                           POINT_SIZE - 2, POINT_SIZE - 2,
                           0x0000ffff);

  if (cogl_test_verbose ())
    g_print ("OK\n");
}
Ejemplo n.º 17
0
static void
emit_vertex_buffer_geometry (CoglFramebuffer *fb,
                             CoglPipeline *pipeline,
                             CoglPangoDisplayListNode *node)
{
  CoglContext *ctx = fb->context;

  /* It's expensive to go through the Cogl journal for large runs
   * of text in part because the journal transforms the quads in software
   * to avoid changing the modelview matrix. So for larger runs of text
   * we load the vertices into a VBO, and this has the added advantage
   * that if the text doesn't change from frame to frame the VBO can
   * be re-used avoiding the repeated cost of validating the data and
   * mapping it into the GPU... */

  if (node->d.texture.primitive == NULL)
    {
      CoglAttributeBuffer *buffer;
      CoglVertexP2T2 *verts, *v;
      int n_verts;
      CoglBool allocated = FALSE;
      CoglAttribute *attributes[2];
      CoglPrimitive *prim;
      int i;
      CoglError *ignore_error = NULL;

      n_verts = node->d.texture.rectangles->len * 4;

      buffer
        = cogl_attribute_buffer_new_with_size (ctx,
                                               n_verts *
                                               sizeof (CoglVertexP2T2));

      if ((verts = cogl_buffer_map (COGL_BUFFER (buffer),
                                    COGL_BUFFER_ACCESS_WRITE,
                                    COGL_BUFFER_MAP_HINT_DISCARD,
                                    &ignore_error)) == NULL)
        {
          cogl_error_free (ignore_error);
          verts = g_new (CoglVertexP2T2, n_verts);
          allocated = TRUE;
        }

      v = verts;

      /* Copy the rectangles into the buffer and expand into four
         vertices instead of just two */
      for (i = 0; i < node->d.texture.rectangles->len; i++)
        {
          const CoglPangoDisplayListRectangle *rectangle
            = &g_array_index (node->d.texture.rectangles,
                              CoglPangoDisplayListRectangle, i);

          v->x = rectangle->x_1;
          v->y = rectangle->y_1;
          v->s = rectangle->s_1;
          v->t = rectangle->t_1;
          v++;
          v->x = rectangle->x_1;
          v->y = rectangle->y_2;
          v->s = rectangle->s_1;
          v->t = rectangle->t_2;
          v++;
          v->x = rectangle->x_2;
          v->y = rectangle->y_2;
          v->s = rectangle->s_2;
          v->t = rectangle->t_2;
          v++;
          v->x = rectangle->x_2;
          v->y = rectangle->y_1;
          v->s = rectangle->s_2;
          v->t = rectangle->t_1;
          v++;
        }

      if (allocated)
        {
          cogl_buffer_set_data (COGL_BUFFER (buffer),
                                0, /* offset */
                                verts,
                                sizeof (CoglVertexP2T2) * n_verts,
                                NULL);
          g_free (verts);
        }
      else
        cogl_buffer_unmap (COGL_BUFFER (buffer));

      attributes[0] = cogl_attribute_new (buffer,
                                          "cogl_position_in",
                                          sizeof (CoglVertexP2T2),
                                          G_STRUCT_OFFSET (CoglVertexP2T2, x),
                                          2, /* n_components */
                                          COGL_ATTRIBUTE_TYPE_FLOAT);
      attributes[1] = cogl_attribute_new (buffer,
                                          "cogl_tex_coord0_in",
                                          sizeof (CoglVertexP2T2),
                                          G_STRUCT_OFFSET (CoglVertexP2T2, s),
                                          2, /* n_components */
                                          COGL_ATTRIBUTE_TYPE_FLOAT);

      prim = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLES,
                                                 n_verts,
                                                 attributes,
                                                 2 /* n_attributes */);

#ifdef CLUTTER_COGL_HAS_GL
      if (_cogl_has_private_feature (ctx, COGL_PRIVATE_FEATURE_QUADS))
        cogl_primitive_set_mode (prim, GL_QUADS);
      else
#endif
        {
          /* GLES doesn't support GL_QUADS so instead we use a VBO
             with indexed vertices to generate GL_TRIANGLES from the
             quads */

          CoglIndices *indices =
            cogl_get_rectangle_indices (ctx, node->d.texture.rectangles->len);

          cogl_primitive_set_indices (prim, indices,
                                      node->d.texture.rectangles->len * 6);
        }

      node->d.texture.primitive = prim;

      cogl_object_unref (buffer);
      cogl_object_unref (attributes[0]);
      cogl_object_unref (attributes[1]);
    }

  cogl_primitive_draw (node->d.texture.primitive,
                       fb,
                       pipeline);
}
Ejemplo n.º 18
0
static void
test_byte_verts (TestState *state, int offset_x, int offset_y)
{
  CoglAttribute *attributes[2];
  CoglAttributeBuffer *buffer, *unnorm_buffer;
  CoglPrimitive *primitive;

  static const ByteVert norm_verts[] =
    {
      { 0, 10, /**/ 255, 0, 0, 255 },
      { 10, 10, /**/ 255, 0, 0, 255 },
      { 5, 0, /**/ 255, 0, 0, 255 },

      { 10, 10, /**/ 0, 255, 0, 255 },
      { 20, 10, /**/ 0, 255, 0, 255 },
      { 15, 0, /**/ 0, 255, 0, 255 }
    };

  static const ByteVert unnorm_verts[] =
    {
      { 0, 0, /**/ 0, 0, 1, 1 },
      { 0, 0, /**/ 0, 0, 1, 1 },
      { 0, 0, /**/ 0, 0, 1, 1 },
    };

  buffer = cogl_attribute_buffer_new (test_ctx,
                                      sizeof (norm_verts), norm_verts);
  attributes[0] = cogl_attribute_new (buffer,
                                      "cogl_position_in",
                                      sizeof (ByteVert),
                                      G_STRUCT_OFFSET (ByteVert, x),
                                      2, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_SHORT);
  attributes[1] = cogl_attribute_new (buffer,
                                      "color",
                                      sizeof (ByteVert),
                                      G_STRUCT_OFFSET (ByteVert, r),
                                      4, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_UNSIGNED_BYTE);
  cogl_attribute_set_normalized (attributes[1], TRUE);

  cogl_framebuffer_push_matrix (test_fb);
  cogl_framebuffer_translate (test_fb, offset_x, offset_y, 0.0f);

  primitive = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLES,
                                                  6, /* n_vertices */
                                                  attributes,
                                                  2); /* n_attributes */
  cogl_primitive_draw (primitive, test_fb, state->pipeline);
  cogl_object_unref (primitive);

  cogl_object_unref (attributes[1]);

  /* Test again with unnormalized attributes */
  unnorm_buffer = cogl_attribute_buffer_new (test_ctx,
                                             sizeof (unnorm_verts),
                                             unnorm_verts);
  attributes[1] = cogl_attribute_new (unnorm_buffer,
                                      "color",
                                      sizeof (ByteVert),
                                      G_STRUCT_OFFSET (ByteVert, r),
                                      4, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_BYTE);

  cogl_framebuffer_translate (test_fb, 20, 0, 0);

  primitive = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLES,
                                                  3, /* n_vertices */
                                                  attributes,
                                                  2); /* n_attributes */
  cogl_primitive_draw (primitive, test_fb, state->pipeline);
  cogl_object_unref (primitive);

  cogl_framebuffer_pop_matrix (test_fb);

  cogl_object_unref (attributes[0]);
  cogl_object_unref (attributes[1]);
  cogl_object_unref (buffer);
  cogl_object_unref (unnorm_buffer);

  test_utils_check_pixel (test_fb, offset_x + 5, offset_y + 5, 0xff0000ff);
  test_utils_check_pixel (test_fb, offset_x + 15, offset_y + 5, 0x00ff00ff);
  test_utils_check_pixel (test_fb, offset_x + 25, offset_y + 5, 0x0000ffff);
}
Ejemplo n.º 19
0
static void
test_short_verts (TestState *state, int offset_x, int offset_y)
{
  CoglAttribute *attributes[2];
  CoglAttributeBuffer *buffer;
  CoglPipeline *pipeline, *pipeline2;
  CoglSnippet *snippet;
  CoglPrimitive *primitive;

  static const ShortVert short_verts[] =
    {
      { -10, -10, /**/ 0xffff, 0, 0, 0xffff },
      { -1, -10,  /**/ 0xffff, 0, 0, 0xffff },
      { -5, -1, /**/ 0xffff, 0, 0, 0xffff }
    };


  pipeline = cogl_pipeline_copy (state->pipeline);

  cogl_pipeline_set_color4ub (pipeline, 255, 0, 0, 255);

  buffer = cogl_attribute_buffer_new (test_ctx,
                                      sizeof (short_verts), short_verts);
  attributes[0] = cogl_attribute_new (buffer,
                                      "cogl_position_in",
                                      sizeof (ShortVert),
                                      G_STRUCT_OFFSET (ShortVert, x),
                                      2, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_SHORT);
  attributes[1] = cogl_attribute_new (buffer,
                                      "color",
                                      sizeof (ShortVert),
                                      G_STRUCT_OFFSET (ShortVert, r),
                                      4, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_UNSIGNED_SHORT);
  cogl_attribute_set_normalized (attributes[1], TRUE);

  cogl_framebuffer_push_matrix (test_fb);
  cogl_framebuffer_translate (test_fb,
                              offset_x + 10.0f,
                              offset_y + 10.0f,
                              0.0f);

  primitive = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLES,
                                                  3, /* n_vertices */
                                                  attributes,
                                                  2); /* n_attributes */
  cogl_primitive_draw (primitive, test_fb, pipeline);
  cogl_object_unref (primitive);

  cogl_framebuffer_pop_matrix (test_fb);

  cogl_object_unref (attributes[0]);

  /* Test again treating the attribute as unsigned */
  attributes[0] = cogl_attribute_new (buffer,
                                      "cogl_position_in",
                                      sizeof (ShortVert),
                                      G_STRUCT_OFFSET (ShortVert, x),
                                      2, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_UNSIGNED_SHORT);

  /* XXX: this is a hack to force the pipeline to use the glsl backend
   * because we know it's not possible to test short vertex position
   * components with the legacy GL backend since which might otherwise
   * be used internally... */
  pipeline2 = cogl_pipeline_new (test_ctx);
  snippet = cogl_snippet_new (COGL_SNIPPET_HOOK_VERTEX,
                              "attribute vec4 color;",
                              "cogl_color_out = vec4 (0.0, 1.0, 0.0, 1.0);");
  cogl_pipeline_add_snippet (pipeline2, snippet);

  cogl_framebuffer_push_matrix (test_fb);
  cogl_framebuffer_translate (test_fb,
                              offset_x + 10.0f - 65525.0f,
                              offset_y - 65525,
                              0.0f);

  primitive = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLES,
                                                  3, /* n_vertices */
                                                  attributes,
                                                  1); /* n_attributes */
  cogl_primitive_draw (primitive, test_fb, pipeline2);
  cogl_object_unref (primitive);

  cogl_framebuffer_pop_matrix (test_fb);

  cogl_object_unref (attributes[0]);

  cogl_object_unref (pipeline2);
  cogl_object_unref (pipeline);
  cogl_object_unref (buffer);

  test_utils_check_pixel (test_fb, offset_x + 5, offset_y + 5, 0xff0000ff);
  test_utils_check_pixel (test_fb, offset_x + 15, offset_y + 5, 0x00ff00ff);
}
Ejemplo n.º 20
0
static void
paint (Data *data)
{
  int i;
  float diff_time;

  /* Update all of the firework's positions */
  for (i = 0; i < N_FIREWORKS; i++)
    {
      Firework *firework = data->fireworks + i;

      if ((fabsf (firework->x - firework->start_x) > 2.0f) ||
          firework->y < -1.0f)
        {
          firework->size = g_random_double_range (0.001f, 0.1f);
          firework->start_x = 1.0f + firework->size;
          firework->start_y = -1.0f;
          firework->initial_x_velocity = g_random_double_range (-0.1f, -2.0f);
          firework->initial_y_velocity = g_random_double_range (0.1f, 4.0f);
          g_timer_reset (firework->timer);

          /* Pick a random color out of six */
          if (g_random_boolean ())
            {
              memset (&firework->color, 0, sizeof (Color));
              ((uint8_t *) &firework->color)[g_random_int_range (0, 3)] = 255;
            }
          else
            {
              memset (&firework->color, 255, sizeof (Color));
              ((uint8_t *) &firework->color)[g_random_int_range (0, 3)] = 0;
            }
          firework->color.alpha = 255;

          /* Fire some of the fireworks from the other side */
          if (g_random_boolean ())
            {
              firework->start_x = -firework->start_x;
              firework->initial_x_velocity = -firework->initial_x_velocity;
            }
        }

      diff_time = g_timer_elapsed (firework->timer, NULL);

      firework->x = (firework->start_x +
                     firework->initial_x_velocity * diff_time);

      firework->y = ((firework->initial_y_velocity * diff_time +
                      0.5f * GRAVITY * diff_time * diff_time) +
                     firework->start_y);
    }

  diff_time = g_timer_elapsed (data->last_spark_time, NULL);
  if (diff_time < 0.0f || diff_time >= TIME_PER_SPARK)
    {
      /* Add a new spark for each firework, overwriting the oldest ones */
      for (i = 0; i < N_FIREWORKS; i++)
        {
          Spark *spark = data->sparks + data->next_spark_num;
          Firework *firework = data->fireworks + i;

          spark->x = (firework->x +
                      g_random_double_range (-firework->size / 2.0f,
                                             firework->size / 2.0f));
          spark->y = (firework->y +
                      g_random_double_range (-firework->size / 2.0f,
                                             firework->size / 2.0f));
          spark->base_color = firework->color;

          data->next_spark_num = (data->next_spark_num + 1) & (N_SPARKS - 1);
        }

      /* Update the colour of each spark */
      for (i = 0; i < N_SPARKS; i++)
        {
          float color_value;

          /* First spark is the oldest */
          Spark *spark = data->sparks + ((data->next_spark_num + i)
                                         & (N_SPARKS - 1));

          color_value = i / (N_SPARKS - 1.0f);
          spark->color.red = spark->base_color.red * color_value;
          spark->color.green = spark->base_color.green * color_value;
          spark->color.blue = spark->base_color.blue * color_value;
          spark->color.alpha = 255.0f * color_value;
        }

      g_timer_reset (data->last_spark_time);
    }

  cogl_buffer_set_data (data->attribute_buffer,
                        0, /* offset */
                        data->sparks,
                        sizeof (data->sparks),
                        NULL /* error */);

  cogl_framebuffer_clear4f (data->fb, COGL_BUFFER_BIT_COLOR, 0, 0, 0, 1);

  cogl_primitive_draw (data->primitive,
                       data->fb,
                       data->pipeline);

  cogl_onscreen_swap_buffers (data->fb);
}
Ejemplo n.º 21
0
static void
draw_frame (TestState *state)
{
  CoglTexture *tex = create_texture_3d (test_ctx);
  CoglPipeline *pipeline = cogl_pipeline_new (test_ctx);
  typedef struct { float x, y, s, t, r; } Vert;
  CoglPrimitive *primitive;
  CoglAttributeBuffer *attribute_buffer;
  CoglAttribute *attributes[2];
  Vert *verts, *v;
  int i;

  cogl_pipeline_set_layer_texture (pipeline, 0, tex);
  cogl_object_unref (tex);
  cogl_pipeline_set_layer_filters (pipeline, 0,
                                   COGL_PIPELINE_FILTER_NEAREST,
                                   COGL_PIPELINE_FILTER_NEAREST);

  /* Render the texture repeated horizontally twice using a regular
     cogl rectangle. This should end up with the r texture coordinates
     as zero */
  cogl_framebuffer_draw_textured_rectangle (test_fb, pipeline,
                                            0.0f, 0.0f, TEX_WIDTH * 2, TEX_HEIGHT,
                                            0.0f, 0.0f, 2.0f, 1.0f);

  /* Render all of the images in the texture using coordinates from a
     CoglPrimitive */
  v = verts = g_new (Vert, 4 * TEX_DEPTH);
  for (i = 0; i < TEX_DEPTH; i++)
    {
      float r = (i + 0.5f) / TEX_DEPTH;

      v->x = i * TEX_WIDTH;
      v->y = TEX_HEIGHT;
      v->s = 0;
      v->t = 0;
      v->r = r;
      v++;

      v->x = i * TEX_WIDTH;
      v->y = TEX_HEIGHT * 2;
      v->s = 0;
      v->t = 1;
      v->r = r;
      v++;

      v->x = i * TEX_WIDTH + TEX_WIDTH;
      v->y = TEX_HEIGHT * 2;
      v->s = 1;
      v->t = 1;
      v->r = r;
      v++;

      v->x = i * TEX_WIDTH + TEX_WIDTH;
      v->y = TEX_HEIGHT;
      v->s = 1;
      v->t = 0;
      v->r = r;
      v++;
    }

  attribute_buffer = cogl_attribute_buffer_new (test_ctx,
                                                4 * TEX_DEPTH * sizeof (Vert),
                                                verts);
  attributes[0] = cogl_attribute_new (attribute_buffer,
                                      "cogl_position_in",
                                      sizeof (Vert),
                                      G_STRUCT_OFFSET (Vert, x),
                                      2, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_FLOAT);
  attributes[1] = cogl_attribute_new (attribute_buffer,
                                      "cogl_tex_coord_in",
                                      sizeof (Vert),
                                      G_STRUCT_OFFSET (Vert, s),
                                      3, /* n_components */
                                      COGL_ATTRIBUTE_TYPE_FLOAT);
  primitive = cogl_primitive_new_with_attributes (COGL_VERTICES_MODE_TRIANGLES,
                                                  6 * TEX_DEPTH,
                                                  attributes,
                                                  2 /* n_attributes */);

  cogl_primitive_set_indices (primitive,
                              cogl_get_rectangle_indices (test_ctx,
                                                          TEX_DEPTH),
                              6 * TEX_DEPTH);

  cogl_primitive_draw (primitive, test_fb, pipeline);

  g_free (verts);

  cogl_object_unref (primitive);
  cogl_object_unref (attributes[0]);
  cogl_object_unref (attributes[1]);
  cogl_object_unref (attribute_buffer);
  cogl_object_unref (pipeline);
}