Example #1
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");
}
Example #2
0
File: cogl.c Project: GNOME/mutter
void
cogl_push_matrix (void)
{
  cogl_framebuffer_push_matrix (cogl_get_draw_framebuffer ());
}
Example #3
0
static CoglBool
draw_rectangle (TestState *state,
                int x,
                int y,
                TestDepthState *rect_state,
                CoglBool legacy_mode)
{
  uint8_t Cr = MASK_RED (rect_state->color);
  uint8_t Cg = MASK_GREEN (rect_state->color);
  uint8_t Cb = MASK_BLUE (rect_state->color);
  uint8_t Ca = MASK_ALPHA (rect_state->color);
  CoglPipeline *pipeline;
  CoglDepthState depth_state;

  cogl_depth_state_init (&depth_state);
  cogl_depth_state_set_test_enabled (&depth_state, rect_state->test_enable);
  cogl_depth_state_set_test_function (&depth_state, rect_state->test_function);
  cogl_depth_state_set_write_enabled (&depth_state, rect_state->write_enable);
  cogl_depth_state_set_range (&depth_state,
                              rect_state->range_near,
                              rect_state->range_far);

  pipeline = cogl_pipeline_new (test_ctx);
  if (!cogl_pipeline_set_depth_state (pipeline, &depth_state, NULL))
    {
      cogl_object_unref (pipeline);
      return FALSE;
    }

  if (!legacy_mode)
    {
      cogl_pipeline_set_color4ub (pipeline, Cr, Cg, Cb, Ca);

      cogl_framebuffer_set_depth_write_enabled (test_fb,
                                                rect_state->fb_write_enable);
      cogl_framebuffer_push_matrix (test_fb);
      cogl_framebuffer_translate (test_fb, 0, 0, rect_state->depth);
      cogl_framebuffer_draw_rectangle (test_fb,
                                       pipeline,
                                       x * QUAD_WIDTH,
                                       y * QUAD_WIDTH,
                                       x * QUAD_WIDTH + QUAD_WIDTH,
                                       y * QUAD_WIDTH + QUAD_WIDTH);
      cogl_framebuffer_pop_matrix (test_fb);
    }
  else
    {
      cogl_push_framebuffer (test_fb);
      cogl_push_matrix ();
      cogl_set_source_color4ub (Cr, Cg, Cb, Ca);
      cogl_translate (0, 0, rect_state->depth);
      cogl_rectangle (x * QUAD_WIDTH,
                      y * QUAD_WIDTH,
                      x * QUAD_WIDTH + QUAD_WIDTH,
                      y * QUAD_WIDTH + QUAD_WIDTH);
      cogl_pop_matrix ();
      cogl_pop_framebuffer ();
    }

  cogl_object_unref (pipeline);

  return TRUE;
}
Example #4
0
int
main (int argc, char **argv)
{
    CoglOnscreenTemplate *onscreen_template;
    CoglDisplay *display;
    CoglContext *ctx;
    CoglOnscreen *onscreen;
    CoglFramebuffer *fb;
    GError *error = NULL;
    CoglVertexP2C4 triangle_vertices[] = {
        {0, 0.7, 0xff, 0x00, 0x00, 0x80},
        {-0.7, -0.7, 0x00, 0xff, 0x00, 0xff},
        {0.7, -0.7, 0x00, 0x00, 0xff, 0xff}
    };
    CoglPrimitive *triangle;
    CoglTexture *tex;
    CoglOffscreen *offscreen;
    CoglFramebuffer *offscreen_fb;
    CoglPipeline *pipeline;

    onscreen_template = cogl_onscreen_template_new (NULL);
    cogl_onscreen_template_set_samples_per_pixel (onscreen_template, 4);
    display = cogl_display_new (NULL, onscreen_template);

    if (!cogl_display_setup (display, &error))
      {
        fprintf (stderr, "Platform doesn't support onscreen 4x msaa rendering: %s\n",
                 error->message);
        return 1;
      }

    ctx = cogl_context_new (display, &error);
    if (!ctx)
      {
        fprintf (stderr, "Failed to create context: %s\n", error->message);
        return 1;
      }

    onscreen = cogl_onscreen_new (ctx, 640, 480);
    fb = COGL_FRAMEBUFFER (onscreen);

    cogl_framebuffer_set_samples_per_pixel (fb, 4);

    if (!cogl_framebuffer_allocate (fb, &error))
      {
        fprintf (stderr, "Failed to allocate 4x msaa offscreen framebuffer, "
                 "disabling msaa for onscreen rendering: %s\n", error->message);
        g_error_free (error);
        cogl_framebuffer_set_samples_per_pixel (fb, 0);

        error = NULL;
        if (!cogl_framebuffer_allocate (fb, &error))
          {
            fprintf (stderr, "Failed to allocate framebuffer: %s\n", error->message);
            return 1;
          }
      }

    cogl_onscreen_show (onscreen);

    tex = cogl_texture_new_with_size (320, 480,
                                      COGL_TEXTURE_NO_SLICING,
                                      COGL_PIXEL_FORMAT_ANY);
    offscreen = cogl_offscreen_new_to_texture (tex);
    offscreen_fb = COGL_FRAMEBUFFER (offscreen);
    cogl_framebuffer_set_samples_per_pixel (offscreen_fb, 4);
    if (!cogl_framebuffer_allocate (offscreen_fb, &error))
      {
        g_error_free (error);
        error = NULL;
        fprintf (stderr, "Failed to allocate 4x msaa offscreen framebuffer, "
                 "disabling msaa for offscreen rendering");
        cogl_framebuffer_set_samples_per_pixel (offscreen_fb, 0);
      }

    triangle = cogl_primitive_new_p2c4 (ctx, COGL_VERTICES_MODE_TRIANGLES,
                                        3, triangle_vertices);
    pipeline = cogl_pipeline_new (ctx);

    for (;;) {
        CoglPollFD *poll_fds;
        int n_poll_fds;
        int64_t timeout;
        CoglPipeline *texture_pipeline;

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

        cogl_framebuffer_push_matrix (fb);
        cogl_framebuffer_scale (fb, 0.5, 1, 1);
        cogl_framebuffer_translate (fb, -1, 0, 0);
        cogl_framebuffer_draw_primitive (fb, pipeline, triangle);
        cogl_framebuffer_pop_matrix (fb);

        cogl_framebuffer_draw_primitive (fb, pipeline, triangle);
        cogl_framebuffer_resolve_samples (offscreen_fb);

        texture_pipeline = cogl_pipeline_new (ctx);
        cogl_pipeline_set_layer_texture (texture_pipeline, 0, tex);
        cogl_framebuffer_draw_rectangle (fb, texture_pipeline, 0, 1, 1, -1);
        cogl_object_unref (texture_pipeline);

        cogl_onscreen_swap_buffers (onscreen);

        cogl_poll_get_info (ctx, &poll_fds, &n_poll_fds, &timeout);
        g_poll ((GPollFD *) poll_fds, n_poll_fds, 0);
        cogl_poll_dispatch (ctx, poll_fds, n_poll_fds);
    }

    return 0;
}
Example #5
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");
}
Example #6
0
static void
rig_journal_flush (GArray *journal,
                   RigPaintContext *paint_ctx)
{
  RutPaintContext *rut_paint_ctx = &paint_ctx->_parent;
  RutCamera *camera = rut_paint_ctx->camera;
  CoglFramebuffer *fb = rut_camera_get_framebuffer (camera);
  int start, dir, end;
  int i;

  /* TODO: use an inline qsort implementation */
  g_array_sort (journal, (void *)sort_entry_cb);

  /* We draw opaque geometry front-to-back so we are more likely to be
   * able to discard later fragments earlier by depth testing.
   *
   * We draw transparent geometry back-to-front so it blends
   * correctly.
   */
  if ( paint_ctx->pass == RIG_PASS_COLOR_BLENDED)
    {
      start = 0;
      dir = 1;
      end = journal->len;
    }
  else
    {
      start = journal->len - 1;
      dir = -1;
      end = -1;
    }

  cogl_framebuffer_push_matrix (fb);

  for (i = start; i != end; i += dir)
    {
      RigJournalEntry *entry = &g_array_index (journal, RigJournalEntry, i);
      RutEntity *entity = entry->entity;
      RutComponent *geometry =
        rut_entity_get_component (entity, RUT_COMPONENT_TYPE_GEOMETRY);
      CoglPipeline *pipeline;
      CoglPrimitive *primitive;
      float normal_matrix[9];
      RutMaterial *material;

      pipeline = get_entity_pipeline (paint_ctx->engine,
                                      entity,
                                      geometry,
                                      paint_ctx->pass);

      if (paint_ctx->pass == RIG_PASS_DOF_DEPTH ||
          paint_ctx->pass == RIG_PASS_SHADOW)
        {
          /* FIXME: avoid updating these uniforms for every primitive if
           * the focal parameters haven't change! */
          set_focal_parameters (pipeline,
                                camera->focal_distance,
                                camera->depth_of_field);
        }
      else if (paint_ctx->pass == RIG_PASS_COLOR_UNBLENDED ||
               paint_ctx->pass == RIG_PASS_COLOR_BLENDED)
        {
          int location;
          RutLight *light = rut_entity_get_component (paint_ctx->engine->light,
                                                      RUT_COMPONENT_TYPE_LIGHT);
          /* FIXME: only update the lighting uniforms when the light has
           * actually moved! */
          rut_light_set_uniforms (light, pipeline);

          /* FIXME: only update the material uniforms when the material has
           * actually changed! */
          material = rut_entity_get_component (entity, RUT_COMPONENT_TYPE_MATERIAL);
          if (material)
            rut_material_flush_uniforms (material, pipeline);

          get_normal_matrix (&entry->matrix, normal_matrix);

          location = cogl_pipeline_get_uniform_location (pipeline, "normal_matrix");
          cogl_pipeline_set_uniform_matrix (pipeline,
                                            location,
                                            3, /* dimensions */
                                            1, /* count */
                                            FALSE, /* don't transpose again */
                                            normal_matrix);
        }

      if (rut_object_is (geometry, RUT_INTERFACE_ID_PRIMABLE))
        {
          primitive = rut_primable_get_primitive (geometry);
          cogl_framebuffer_set_modelview_matrix (fb, &entry->matrix);
          cogl_framebuffer_draw_primitive (fb,
                                           pipeline,
                                           primitive);
        }
      else if (rut_object_get_type (geometry) == &rut_text_type &&
               paint_ctx->pass == RIG_PASS_COLOR_BLENDED)
        {
          cogl_framebuffer_set_modelview_matrix (fb, &entry->matrix);
          rut_paintable_paint (geometry, rut_paint_ctx);
        }

      cogl_object_unref (pipeline);

      rut_refable_unref (entry->entity);
    }

  cogl_framebuffer_pop_matrix (fb);

  g_array_set_size (journal, 0);
}