예제 #1
0
static void
paint_matrix_pipeline (CoglPipeline *pipeline)
{
  CoglMatrix matrices[4];
  float matrix_floats[16 * 4];
  int uniform_location;
  int i;

  for (i = 0; i < 4; i++)
    cogl_matrix_init_identity (matrices + i);

  /* Use the first matrix to make the color red */
  cogl_matrix_translate (matrices + 0, 1.0f, 0.0f, 0.0f);

  /* Rotate the vertex so that it ends up green */
  cogl_matrix_rotate (matrices + 1, 90.0f, 0.0f, 0.0f, 1.0f);

  /* Scale the vertex so it ends up halved */
  cogl_matrix_scale (matrices + 2, 0.5f, 0.5f, 0.5f);

  /* Add a blue component in the final matrix. The final matrix is
     uploaded as transposed so we need to transpose first to cancel
     that out */
  cogl_matrix_translate (matrices + 3, 0.0f, 0.0f, 1.0f);
  cogl_matrix_transpose (matrices + 3);

  for (i = 0; i < 4; i++)
    memcpy (matrix_floats + i * 16,
            cogl_matrix_get_array (matrices + i),
            sizeof (float) * 16);

  /* Set the first three matrices as transposed */
  uniform_location =
    cogl_pipeline_get_uniform_location (pipeline, "matrix_array");
  cogl_pipeline_set_uniform_matrix (pipeline,
                                    uniform_location,
                                    4, /* dimensions */
                                    3, /* count */
                                    FALSE, /* not transposed */
                                    matrix_floats);

  /* Set the last matrix as untransposed */
  uniform_location =
    cogl_pipeline_get_uniform_location (pipeline, "matrix_array[3]");
  cogl_pipeline_set_uniform_matrix (pipeline,
                                    uniform_location,
                                    4, /* dimensions */
                                    1, /* count */
                                    TRUE, /* transposed */
                                    matrix_floats + 16 * 3);

  paint_pipeline (pipeline, 12);
}
예제 #2
0
static gboolean
clutter_pan_action_real_pan (ClutterPanAction *self,
                             ClutterActor     *actor,
                             gboolean          is_interpolated)
{
  ClutterPanActionPrivate *priv = self->priv;
  gfloat dx, dy;
  ClutterMatrix transform;

  clutter_pan_action_get_motion_delta (self, 0, &dx, &dy);

  switch (priv->pan_axis)
    {
    case CLUTTER_PAN_AXIS_NONE:
      break;

    case CLUTTER_PAN_X_AXIS:
      dy = 0.0f;
      break;

    case CLUTTER_PAN_Y_AXIS:
      dx = 0.0f;
      break;
    }

  clutter_actor_get_child_transform (actor, &transform);
  cogl_matrix_translate (&transform, dx, dy, 0.0f);
  clutter_actor_set_child_transform (actor, &transform);
  return TRUE;
}
예제 #3
0
파일: mx-fade-effect.c 프로젝트: 3v1n0/mx
static void
mx_fade_effect_post_paint (ClutterEffect *effect)
{
  MxFadeEffectPrivate *priv = MX_FADE_EFFECT (effect)->priv;

  if (!priv->freeze_update)
    CLUTTER_EFFECT_CLASS (mx_fade_effect_parent_class)->post_paint (effect);
  else
    {
      CoglMatrix modelview;
      ClutterActor *actor, *stage;

      actor = clutter_actor_meta_get_actor (CLUTTER_ACTOR_META (effect));
      stage = clutter_actor_get_stage (actor);

      /* Set up the draw matrix so we draw the offscreen texture at the
       * absolute coordinates of the actor-box. We need to do this to
       * avoid transforming by the actor matrix twice, as when it's drawn
       * into the offscreen surface, it'll already be transformed.
       */
      cogl_push_matrix ();

      cogl_matrix_init_identity (&modelview);
      CLUTTER_ACTOR_CLASS (G_OBJECT_GET_CLASS (stage))->
        apply_transform (stage, &modelview);
      cogl_matrix_translate (&modelview, priv->x_offset, priv->y_offset, 0.f);
      cogl_set_modelview_matrix (&modelview);

      clutter_offscreen_effect_paint_target (CLUTTER_OFFSCREEN_EFFECT (effect));

      cogl_pop_matrix ();
    }
}
예제 #4
0
파일: cogl-matrix.c 프로젝트: rib/clutter
void
cogl_matrix_view_2d_in_frustum (CoglMatrix *matrix,
                                float left,
                                float right,
                                float bottom,
                                float top,
                                float z_near,
                                float z_2d,
                                float width_2d,
                                float height_2d)
{
  float left_2d_plane = left / z_near * z_2d;
  float right_2d_plane = right / z_near * z_2d;
  float bottom_2d_plane = bottom / z_near * z_2d;
  float top_2d_plane = top / z_near * z_2d;

  float width_2d_start = right_2d_plane - left_2d_plane;
  float height_2d_start = top_2d_plane - bottom_2d_plane;

  /* Factors to scale from framebuffer geometry to frustum
   * cross-section geometry. */
  float width_scale = width_2d_start / width_2d;
  float height_scale = height_2d_start / height_2d;

  cogl_matrix_translate (matrix,
                         left_2d_plane, top_2d_plane, -z_2d);

  cogl_matrix_scale (matrix, width_scale, -height_scale, width_scale);
}
예제 #5
0
void
rut_transform_translate (RutTransform *transform,
                         float x,
                         float y,
                         float z)
{
    cogl_matrix_translate (&transform->matrix, x, y, z);
}
예제 #6
0
void
_cogl_matrix_stack_translate (CoglMatrixStack *stack,
                              float            x,
                              float            y,
                              float            z)
{
  CoglMatrixState *state;

  state = _cogl_matrix_stack_top_mutable (stack, TRUE);
  cogl_matrix_translate (&state->matrix, x, y, z);
  state->is_identity = FALSE;
  stack->age++;
}
예제 #7
0
static void
mex_column_apply_transform (ClutterActor *actor,
                            CoglMatrix   *matrix)
{
  MexColumnPrivate *priv = MEX_COLUMN (actor)->priv;

  CLUTTER_ACTOR_CLASS (mex_column_parent_class)->
    apply_transform (actor, matrix);

  if (priv->adjustment)
    cogl_matrix_translate (matrix, 0,
                           -priv->adjustment_value, 0);
}
예제 #8
0
void
mai_node_draw_recursive (MaiNode *self)
{
  CoglMatrix initial_mtx;
  cogl_matrix_init_identity (&initial_mtx);
  cogl_set_modelview_matrix (&initial_mtx);

  cogl_set_source_color4ub ('\x1', '\x1', '\xFF', 255);
  cogl_set_source_texture (g_testtex);
  cogl_ortho (0, 64, 0, 64, -1, 1);

  cogl_matrix_translate (&initial_mtx, 20.0f, 20.0f, 0.0f);
  cogl_matrix_scale (&initial_mtx, 5.0f, 5.0f, 1.0f);
  cogl_matrix_rotate(&initial_mtx, -90.0f, 1.0f, 0.0f, 0.0f);

  _mai_node_draw_recursive (self, &initial_mtx);

  cogl_flush ();
}
예제 #9
0
static void
mx_deform_bow_tie_texture_vflip (ClutterTexture *texture)
{
  CoglHandle material;

  material = clutter_texture_get_cogl_material (texture);

  if (material)
    {
      CoglMatrix matrix;
      cogl_matrix_init_identity (&matrix);

      /* Vflip */
      cogl_matrix_scale (&matrix, 1.f, -1.f, 1.f);
      cogl_matrix_translate (&matrix, 0.f, 1.f, 0.f);

      cogl_material_set_layer_matrix (material, 0, &matrix);
    }
}
예제 #10
0
/* Update view depending on scrollbar values */
static void _xfdashboard_viewpad_update_view_viewport(XfdashboardViewpad *self)
{
	XfdashboardViewpadPrivate	*priv;
	ClutterMatrix				transform;
	gfloat						x, y, w, h;

	g_return_if_fail(XFDASHBOARD_IS_VIEWPAD(self));

	priv=self->priv;

	/* Check for active view */
	if(priv->activeView==NULL)
	{
		g_warning(_("Cannot update viewport of view because no one is active"));
		return;
	}

	/* Get offset from scrollbars and view size from clipping */
	if(clutter_actor_has_clip(CLUTTER_ACTOR(priv->activeView)))
	{
		clutter_actor_get_clip(CLUTTER_ACTOR(priv->activeView), &x, &y, &w, &h);
	}
		else
		{
 			x=y=0.0f;
			clutter_actor_get_size(CLUTTER_ACTOR(priv->activeView), &w, &h);
		}

	/* To avoid blur convert float to ints (virtually) */
	x=ceil(x);
	y=ceil(y);
	w=ceil(w);
	h=ceil(h);

	/* Set transformation (offset) */
	cogl_matrix_init_identity(&transform);
	cogl_matrix_translate(&transform, -x, -y, 0.0f);
	clutter_actor_set_transform(CLUTTER_ACTOR(priv->activeView), &transform);

	/* Set new clipping */
	clutter_actor_set_clip(CLUTTER_ACTOR(priv->activeView), x, y, w, h);
}
static void
mx_viewport_apply_transform (ClutterActor *actor,
                             CoglMatrix   *matrix)
{
  MxViewportPrivate *priv = MX_VIEWPORT (actor)->priv;
  gdouble x, y;

  CLUTTER_ACTOR_CLASS (mx_viewport_parent_class)->apply_transform (actor, matrix);

  if (priv->hadjustment)
    x = mx_adjustment_get_value (priv->hadjustment);
  else
    x = 0;

  if (priv->vadjustment)
    y = mx_adjustment_get_value (priv->vadjustment);
  else
    y = 0;

  cogl_matrix_translate (matrix, (int) -x, (int) -y, 0);
}
예제 #12
0
static void
st_box_layout_apply_transform (ClutterActor *a,
                               CoglMatrix   *m)
{
  StBoxLayoutPrivate *priv = ST_BOX_LAYOUT (a)->priv;
  gdouble x, y;

  CLUTTER_ACTOR_CLASS (st_box_layout_parent_class)->apply_transform (a, m);

  if (priv->hadjustment)
    x = st_adjustment_get_value (priv->hadjustment);
  else
    x = 0;

  if (priv->vadjustment)
    y = st_adjustment_get_value (priv->vadjustment);
  else
    y = 0;

  cogl_matrix_translate (m, (int) -x, (int) -y, 0);
}
예제 #13
0
G_MODULE_EXPORT int
test_cogl_multitexture_main (int argc, char *argv[])
{
  GError            *error = NULL;
  ClutterActor	    *stage;
  ClutterColor       stage_color = { 0x61, 0x56, 0x56, 0xff };
  TestMultiLayerMaterialState *state = g_new0 (TestMultiLayerMaterialState, 1);
  gfloat             stage_w, stage_h;
  gchar            **files;
  gfloat             tex_coords[] =
    {
    /* tx1  ty1  tx2  ty2 */
         0,   0,   1,   1,
         0,   0,   1,   1,
         0,   0,   1,   1
    };

  if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
    return 1;

  stage = clutter_stage_new ();
  clutter_actor_get_size (stage, &stage_w, &stage_h);

  clutter_stage_set_title (CLUTTER_STAGE (stage), "Cogl: Multi-texturing");
  clutter_stage_set_color (CLUTTER_STAGE (stage), &stage_color);

  g_signal_connect (stage, "destroy", G_CALLBACK (clutter_main_quit), NULL);

  /* We create a non-descript actor that we know doesn't have a
   * default paint handler, so that we can easily control
   * painting in a paint signal handler, without having to
   * sub-class anything etc. */
  state->group = clutter_group_new ();
  clutter_actor_set_position (state->group, stage_w / 2, stage_h / 2);
  g_signal_connect (state->group, "paint",
		    G_CALLBACK(material_rectangle_paint), state);

  files = g_new (gchar*, 4);
  files[0] = g_build_filename (TESTS_DATADIR, "redhand_alpha.png", NULL);
  files[1] = g_build_filename (TESTS_DATADIR, "redhand.png", NULL);
  files[2] = g_build_filename (TESTS_DATADIR, "light0.png", NULL);
  files[3] = NULL;

  state->alpha_tex =
    cogl_texture_new_from_file (files[0],
                                COGL_TEXTURE_NO_SLICING,
				COGL_PIXEL_FORMAT_ANY,
				&error);
  if (!state->alpha_tex)
    g_critical ("Failed to load redhand_alpha.png: %s", error->message);

  state->redhand_tex =
    cogl_texture_new_from_file (files[1],
                                COGL_TEXTURE_NO_SLICING,
				COGL_PIXEL_FORMAT_ANY,
				&error);
  if (!state->redhand_tex)
    g_critical ("Failed to load redhand.png: %s", error->message);

  state->light_tex0 =
    cogl_texture_new_from_file (files[2],
                                COGL_TEXTURE_NO_SLICING,
				COGL_PIXEL_FORMAT_ANY,
				&error);
  if (!state->light_tex0)
    g_critical ("Failed to load light0.png: %s", error->message);

  state->light_tex1 =
    cogl_texture_new_from_file (files[2],
                                COGL_TEXTURE_NO_SLICING,
				COGL_PIXEL_FORMAT_ANY,
				&error);
  if (!state->light_tex1)
    g_critical ("Failed to load light0.png: %s", error->message);

  g_strfreev (files);

  state->material0 = cogl_material_new ();
  cogl_material_set_layer (state->material0, 0, state->alpha_tex);
  cogl_material_set_layer (state->material0, 1, state->redhand_tex);
  cogl_material_set_layer (state->material0, 2, state->light_tex0);

  state->material1 = cogl_material_new ();
  cogl_material_set_layer (state->material1, 0, state->alpha_tex);
  cogl_material_set_layer (state->material1, 1, state->redhand_tex);
  cogl_material_set_layer (state->material1, 2, state->light_tex1);

  state->tex_coords = tex_coords;

  cogl_matrix_init_identity (&state->tex_matrix0);
  cogl_matrix_init_identity (&state->tex_matrix1);
  cogl_matrix_init_identity (&state->rot_matrix0);
  cogl_matrix_init_identity (&state->rot_matrix1);

  cogl_matrix_translate (&state->rot_matrix0, 0.5, 0.5, 0);
  cogl_matrix_rotate (&state->rot_matrix0, 10.0, 0, 0, 1.0);
  cogl_matrix_translate (&state->rot_matrix0, -0.5, -0.5, 0);

  cogl_matrix_translate (&state->rot_matrix1, 0.5, 0.5, 0);
  cogl_matrix_rotate (&state->rot_matrix1, -10.0, 0, 0, 1.0);
  cogl_matrix_translate (&state->rot_matrix1, -0.5, -0.5, 0);

  clutter_actor_set_anchor_point (state->group, 86, 125);
  clutter_container_add_actor (CLUTTER_CONTAINER(stage),
			       state->group);

  state->timeline = clutter_timeline_new (2812);

  g_signal_connect (state->timeline, "new-frame", G_CALLBACK (frame_cb), state);

  clutter_actor_animate_with_timeline (state->group,
                                       CLUTTER_LINEAR,
                                       state->timeline,
                                       "rotation-angle-y", 30.0,
                                       "signal-after::completed",
                                       animation_completed_cb, state,
                                       NULL);

  /* start the timeline and thus the animations */
  clutter_timeline_start (state->timeline);

  clutter_actor_show_all (stage);

  clutter_main();

  cogl_handle_unref (state->material1);
  cogl_handle_unref (state->material0);
  cogl_handle_unref (state->alpha_tex);
  cogl_handle_unref (state->redhand_tex);
  cogl_handle_unref (state->light_tex0);
  cogl_handle_unref (state->light_tex1);
  g_free (state);

  return 0;
}
예제 #14
0
static RutShapeModel *
shape_model_new (RutContext *ctx,
                 CoglBool shaped,
                 float tex_width,
                 float tex_height)
{
  RutShapeModel *shape_model = g_slice_new (RutShapeModel);
  RutBuffer *buffer = rut_buffer_new (sizeof (CoglVertexP3) * 6);
  RutMesh *pick_mesh = rut_mesh_new_from_buffer_p3 (COGL_VERTICES_MODE_TRIANGLES,
                                                    6,
                                                    buffer);
  CoglVertexP3 *pick_vertices = (CoglVertexP3 *)buffer->data;
  CoglMatrix matrix;
  float tex_aspect;
  float size_x;
  float size_y;
  float half_size_x;
  float half_size_y;
  float geom_size_x;
  float geom_size_y;
  float half_geom_size_x;
  float half_geom_size_y;

  rut_object_init (&shape_model->_parent, &rut_shape_model_type);

  shape_model->ref_count = 1;

  if (shaped)
    {
      /* In this case we are using a shape mask texture which is has a
       * square size and is padded with transparent pixels to provide
       * antialiasing. The shape mask is half the size of the texture
       * itself so we make the geometry twice as large to compensate.
       */
      size_x = MIN (tex_width, tex_height);
      size_y = size_x;
      geom_size_x = size_x * 2.0;
      geom_size_y = geom_size_x;
    }
  else
    {
      size_x = tex_width;
      size_y = tex_height;
      geom_size_x = tex_width;
      geom_size_y = tex_height;
    }

  half_size_x = size_x / 2.0;
  half_size_y = size_y / 2.0;
  half_geom_size_x = geom_size_x / 2.0;
  half_geom_size_y = geom_size_y / 2.0;

    {
      int n_vertices;
      int i;

      VertexP2T2T2 vertices[] =
        {
          { -half_geom_size_x, -half_geom_size_y, 0, 0, 0, 0 },
          { -half_geom_size_x,  half_geom_size_y, 0, 1, 0, 1 },
          {  half_geom_size_x,  half_geom_size_y, 1, 1, 1, 1 },

          { -half_geom_size_x, -half_geom_size_y, 0, 0, 0, 0 },
          {  half_geom_size_x,  half_geom_size_y, 1, 1, 1, 1 },
          {  half_geom_size_x, -half_geom_size_y, 1, 0, 1, 0 },
        };

      cogl_matrix_init_identity (&matrix);
      tex_aspect = (float)tex_width / (float)tex_height;

      if (shaped)
        {
          float s_scale, t_scale;
          float s0, t0;

          /* NB: The circle mask texture has a centered circle that is
           * half the width of the texture itself. We want the primary
           * texture to be mapped to this center circle. */

          s_scale = 2;
          t_scale = 2;

          if (tex_aspect < 1) /* taller than it is wide */
            t_scale *= tex_aspect;
          else /* wider than it is tall */
            {
              float inverse_aspect = 1.0f / tex_aspect;
              s_scale *= inverse_aspect;
            }

          s0 = 0.5 - (s_scale / 2.0);
          t0 = 0.5 - (t_scale / 2.0);

          cogl_matrix_translate (&matrix, s0, t0, 0);
          cogl_matrix_scale (&matrix, s_scale, t_scale, 1);
        }

      n_vertices = sizeof (vertices) / sizeof (VertexP2T2T2);
      for (i = 0; i < n_vertices; i++)
        {
          float z = 0, w = 1;

          cogl_matrix_transform_point (&matrix,
                                       &vertices[i].s1,
                                       &vertices[i].t1,
                                       &z,
                                       &w);
#ifdef MESA_CONST_ATTRIB_BUG_WORKAROUND
          vertices[i].Nx = 0;
          vertices[i].Ny = 0;
          vertices[i].Nz = 1;

          vertices[i].Tx = 1;
          vertices[i].Ty = 0;
          vertices[i].Tz = 0;
#endif
        }

      shape_model->primitive =
        primitive_new_p2t2t2 (ctx->cogl_context,
                              COGL_VERTICES_MODE_TRIANGLES,
                              n_vertices,
                              vertices);
    }

  shape_model->shape_texture = cogl_object_ref (ctx->circle_texture);

  pick_vertices[0].x = -half_size_x;
  pick_vertices[0].y = -half_size_y;
  pick_vertices[1].x = -half_size_x;
  pick_vertices[1].y = half_size_y;
  pick_vertices[2].x = half_size_x;
  pick_vertices[2].y = half_size_y;
  pick_vertices[3] = pick_vertices[0];
  pick_vertices[4] = pick_vertices[2];
  pick_vertices[5].x = half_size_x;
  pick_vertices[5].y = -half_size_y;

  shape_model->pick_mesh = pick_mesh;


  return shape_model;
}
예제 #15
0
/* In addition to writing the stack matrix into the give @matrix
 * argument this function *may* sometimes also return a pointer
 * to a matrix too so if we are querying the inverse matrix we
 * should query from the return matrix so that the result can
 * be cached within the stack. */
CoglMatrix *
cogl_matrix_entry_get (CoglMatrixEntry *entry,
                        CoglMatrix *matrix)
{
  int depth;
  CoglMatrixEntry *current;
  CoglMatrixEntry **children;
  int i;

  for (depth = 0, current = entry;
       current;
       current = current->parent, depth++)
    {
      switch (current->op)
        {
        case COGL_MATRIX_OP_LOAD_IDENTITY:
          cogl_matrix_init_identity (matrix);
          goto initialized;
        case COGL_MATRIX_OP_LOAD:
          {
            CoglMatrixEntryLoad *load = (CoglMatrixEntryLoad *)current;
            *matrix = *load->matrix;
            goto initialized;
          }
        case COGL_MATRIX_OP_SAVE:
          {
            CoglMatrixEntrySave *save = (CoglMatrixEntrySave *)current;
            if (!save->cache_valid)
              {
                CoglMagazine *matrices_magazine =
                  cogl_matrix_stack_matrices_magazine;
                save->cache = _cogl_magazine_chunk_alloc (matrices_magazine);
                cogl_matrix_entry_get (current->parent, save->cache);
                save->cache_valid = TRUE;
              }
            *matrix = *save->cache;
            goto initialized;
          }
        default:
          continue;
        }
    }

initialized:

  if (depth == 0)
    {
      switch (entry->op)
        {
        case COGL_MATRIX_OP_LOAD_IDENTITY:
        case COGL_MATRIX_OP_TRANSLATE:
        case COGL_MATRIX_OP_ROTATE:
        case COGL_MATRIX_OP_ROTATE_QUATERNION:
        case COGL_MATRIX_OP_ROTATE_EULER:
        case COGL_MATRIX_OP_SCALE:
        case COGL_MATRIX_OP_MULTIPLY:
          return NULL;

        case COGL_MATRIX_OP_LOAD:
          {
            CoglMatrixEntryLoad *load = (CoglMatrixEntryLoad *)entry;
            return load->matrix;
          }
        case COGL_MATRIX_OP_SAVE:
          {
            CoglMatrixEntrySave *save = (CoglMatrixEntrySave *)entry;
            return save->cache;
          }
        }
      g_warn_if_reached ();
      return NULL;
    }

#ifdef COGL_ENABLE_DEBUG
  if (!current)
    {
      g_warning ("Inconsistent matrix stack");
      return NULL;
    }

  entry->composite_gets++;
#endif

  children = g_alloca (sizeof (CoglMatrixEntry) * depth);

  /* We need walk the list of entries from the init/load/save entry
   * back towards the leaf node but the nodes don't link to their
   * children so we need to re-walk them here to add to a separate
   * array. */
  for (i = depth - 1, current = entry;
       i >= 0 && current;
       i--, current = current->parent)
    {
      children[i] = current;
    }

#ifdef COGL_ENABLE_DEBUG
  if (COGL_DEBUG_ENABLED (COGL_DEBUG_PERFORMANCE) &&
      entry->composite_gets >= 2)
    {
      COGL_NOTE (PERFORMANCE,
                 "Re-composing a matrix stack entry multiple times");
    }
#endif

  for (i = 0; i < depth; i++)
    {
      switch (children[i]->op)
        {
        case COGL_MATRIX_OP_TRANSLATE:
          {
            CoglMatrixEntryTranslate *translate =
              (CoglMatrixEntryTranslate *)children[i];
            cogl_matrix_translate (matrix,
                                   translate->x,
                                   translate->y,
                                   translate->z);
            continue;
          }
        case COGL_MATRIX_OP_ROTATE:
          {
            CoglMatrixEntryRotate *rotate=
              (CoglMatrixEntryRotate *)children[i];
            cogl_matrix_rotate (matrix,
                                rotate->angle,
                                rotate->x,
                                rotate->y,
                                rotate->z);
            continue;
          }
        case COGL_MATRIX_OP_ROTATE_EULER:
          {
            CoglMatrixEntryRotateEuler *rotate =
              (CoglMatrixEntryRotateEuler *)children[i];
            CoglEuler euler;
            cogl_euler_init (&euler,
                             rotate->heading,
                             rotate->pitch,
                             rotate->roll);
            cogl_matrix_rotate_euler (matrix,
                                      &euler);
            continue;
          }
        case COGL_MATRIX_OP_ROTATE_QUATERNION:
          {
            CoglMatrixEntryRotateQuaternion *rotate =
              (CoglMatrixEntryRotateQuaternion *)children[i];
            CoglQuaternion quaternion;
            cogl_quaternion_init_from_array (&quaternion, rotate->values);
            cogl_matrix_rotate_quaternion (matrix, &quaternion);
            continue;
          }
        case COGL_MATRIX_OP_SCALE:
          {
            CoglMatrixEntryScale *scale =
              (CoglMatrixEntryScale *)children[i];
            cogl_matrix_scale (matrix,
                               scale->x,
                               scale->y,
                               scale->z);
            continue;
          }
        case COGL_MATRIX_OP_MULTIPLY:
          {
            CoglMatrixEntryMultiply *multiply =
              (CoglMatrixEntryMultiply *)children[i];
            cogl_matrix_multiply (matrix, matrix, multiply->matrix);
            continue;
          }

        case COGL_MATRIX_OP_LOAD_IDENTITY:
        case COGL_MATRIX_OP_LOAD:
        case COGL_MATRIX_OP_SAVE:
          g_warn_if_reached ();
          continue;
        }
    }

  return NULL;
}
예제 #16
0
static RutDiamondSlice *
diamond_slice_new (RutContext *ctx,
                   float size,
                   int tex_width,
                   int tex_height)
{
  RutDiamondSlice *diamond_slice = g_slice_new (RutDiamondSlice);
  float width = size;
  float height = size;
#define DIAMOND_SLICE_CORNER_RADIUS 20
  CoglMatrix matrix;
  float tex_aspect;

  rut_object_init (&diamond_slice->_parent, &rut_diamond_slice_type);

  diamond_slice->ref_count = 1;

  diamond_slice->size = size;

    {
      /* x0,y0,x1,y1 and s0,t0,s1,t1 define the postion and texture
       * coordinates for the center rectangle... */
      float x0 = DIAMOND_SLICE_CORNER_RADIUS;
      float y0 = DIAMOND_SLICE_CORNER_RADIUS;
      float x1 = width - DIAMOND_SLICE_CORNER_RADIUS;
      float y1 = height - DIAMOND_SLICE_CORNER_RADIUS;

      /* The center region of the nine-slice can simply map to the
       * degenerate center of the circle */
      float s0 = 0.5;
      float t0 = 0.5;
      float s1 = 0.5;
      float t1 = 0.5;

      int n_vertices;
      int i;

      /*
       * 0,0      x0,0      x1,0      width,0
       * 0,0      s0,0      s1,0      1,0
       * 0        1         2         3
       *
       * 0,y0     x0,y0     x1,y0     width,y0
       * 0,t0     s0,t0     s1,t0     1,t0
       * 4        5         6         7
       *
       * 0,y1     x0,y1     x1,y1     width,y1
       * 0,t1     s0,t1     s1,t1     1,t1
       * 8        9         10        11
       *
       * 0,height x0,height x1,height width,height
       * 0,1      s0,1      s1,1      1,1
       * 12       13        14        15
       */

      VertexP2T2T2 vertices[] =
        {
          { 0,  0, 0, 0, 0, 0 },
          { x0, 0, s0, 0, x0, 0},
          { x1, 0, s1, 0, x1, 0},
          { width, 0, 1, 0, width, 0},

          { 0, y0, 0, t0, 0, y0},
          { x0, y0, s0, t0, x0, y0},
          { x1, y0, s1, t0, x1, y0},
          { width, y0, 1, t0, width, y0},

          { 0, y1, 0, t1, 0, y1},
          { x0, y1, s0, t1, x0, y1},
          { x1, y1, s1, t1, x1, y1},
          { width, y1, 1, t1, width, y1},

          { 0, height, 0, 1, 0, height},
          { x0, height, s0, 1, x0, height},
          { x1, height, s1, 1, x1, height},
          { width, height, 1, 1, width, height},
        };

      cogl_matrix_init_identity (&diamond_slice->rotate_matrix);
      cogl_matrix_rotate (&diamond_slice->rotate_matrix, 45, 0, 0, 1);
      cogl_matrix_translate (&diamond_slice->rotate_matrix, - width / 2.0, - height / 2.0, 0);

      n_vertices = sizeof (vertices) / sizeof (VertexP2T2T2);
      for (i = 0; i < n_vertices; i++)
        {
          float z = 0, w = 1;

          cogl_matrix_transform_point (&diamond_slice->rotate_matrix,
                                       &vertices[i].x,
                                       &vertices[i].y,
                                       &z,
                                       &w);

#ifdef MESA_CONST_ATTRIB_BUG_WORKAROUND
          vertices[i].Nx = 0;
          vertices[i].Ny = 0;
          vertices[i].Nz = 1;

          vertices[i].Tx = 1;
          vertices[i].Ty = 0;
          vertices[i].Tz = 0;
#endif
        }

      cogl_matrix_init_identity (&matrix);

      {
        float s_scale = 1.0, t_scale = 1.0;
        float s0, t0;
        float diagonal_size_scale = 1.0 / (sinf (G_PI_4) * 2.0);

        tex_aspect = (float)tex_width / (float)tex_height;

        if (tex_aspect < 1) /* taller than it is wide */
          t_scale *= tex_aspect;
        else /* wider than it is tall */
          {
            float inverse_aspect = 1.0f / tex_aspect;
            s_scale *= inverse_aspect;
          }

        s_scale *= diagonal_size_scale;
        t_scale *= diagonal_size_scale;

        s0 = 0.5 - (s_scale / 2.0);
        t0 = 0.5 - (t_scale / 2.0);

        cogl_matrix_translate (&matrix, s0, t0, 0);
        cogl_matrix_scale (&matrix, s_scale / width, t_scale / height, 1);

        cogl_matrix_translate (&matrix, width / 2.0, height / 2.0, 1);
        cogl_matrix_rotate (&matrix, 45, 0, 0, 1);
        cogl_matrix_translate (&matrix, -width / 2.0, -height / 2.0, 1);
      }

      n_vertices = sizeof (vertices) / sizeof (VertexP2T2T2);
      for (i = 0; i < n_vertices; i++)
        {
          float z = 0, w = 1;

          cogl_matrix_transform_point (&matrix,
                                       &vertices[i].s1,
                                       &vertices[i].t1,
                                       &z,
                                       &w);
        }


      diamond_slice->primitive =
        primitive_new_p2t2t2 (ctx->cogl_context,
                              COGL_VERTICES_MODE_TRIANGLES,
                              n_vertices,
                              vertices);

      /* The vertices uploaded only map to the key intersection points of the
       * 9-slice grid which isn't a topology that GPUs can handle directly so
       * this specifies an array of indices that allow the GPU to interpret the
       * vertices as a list of triangles... */
      cogl_primitive_set_indices (diamond_slice->primitive,
                                  ctx->nine_slice_indices,
                                  sizeof (_rut_nine_slice_indices_data) /
                                  sizeof (_rut_nine_slice_indices_data[0]));
    }

  return diamond_slice;
}
예제 #17
0
static gboolean
clutter_matrix_progress (const GValue *a,
                         const GValue *b,
                         gdouble       progress,
                         GValue       *retval)
{
  const ClutterMatrix *matrix1 = g_value_get_boxed (a);
  const ClutterMatrix *matrix2 = g_value_get_boxed (b);
  ClutterVertex scale1 = CLUTTER_VERTEX_INIT (1.f, 1.f, 1.f);
  float shear1[3] = { 0.f, 0.f, 0.f };
  ClutterVertex rotate1 = CLUTTER_VERTEX_INIT_ZERO;
  ClutterVertex translate1 = CLUTTER_VERTEX_INIT_ZERO;
  ClutterVertex4 perspective1 = { 0.f, 0.f, 0.f, 0.f };
  ClutterVertex scale2 = CLUTTER_VERTEX_INIT (1.f, 1.f, 1.f);
  float shear2[3] = { 0.f, 0.f, 0.f };
  ClutterVertex rotate2 = CLUTTER_VERTEX_INIT_ZERO;
  ClutterVertex translate2 = CLUTTER_VERTEX_INIT_ZERO;
  ClutterVertex4 perspective2 = { 0.f, 0.f, 0.f, 0.f };
  ClutterVertex scale_res = CLUTTER_VERTEX_INIT (1.f, 1.f, 1.f);
  float shear_res = 0.f;
  ClutterVertex rotate_res = CLUTTER_VERTEX_INIT_ZERO;
  ClutterVertex translate_res = CLUTTER_VERTEX_INIT_ZERO;
  ClutterVertex4 perspective_res = { 0.f, 0.f, 0.f, 0.f };
  ClutterMatrix res;

  clutter_matrix_init_identity (&res);

  _clutter_util_matrix_decompose (matrix1,
                                  &scale1, shear1, &rotate1, &translate1,
                                  &perspective1);
  _clutter_util_matrix_decompose (matrix2,
                                  &scale2, shear2, &rotate2, &translate2,
                                  &perspective2);

  /* perspective */
  _clutter_util_vertex4_interpolate (&perspective1, &perspective2, progress, &perspective_res);
  res.wx = perspective_res.x;
  res.wy = perspective_res.y;
  res.wz = perspective_res.z;
  res.ww = perspective_res.w;

  /* translation */
  clutter_vertex_interpolate (&translate1, &translate2, progress, &translate_res);
  cogl_matrix_translate (&res, translate_res.x, translate_res.y, translate_res.z);

  /* rotation */
  clutter_vertex_interpolate (&rotate1, &rotate2, progress, &rotate_res);
  cogl_matrix_rotate (&res, rotate_res.x, 1.0f, 0.0f, 0.0f);
  cogl_matrix_rotate (&res, rotate_res.y, 0.0f, 1.0f, 0.0f);
  cogl_matrix_rotate (&res, rotate_res.z, 0.0f, 0.0f, 1.0f);

  /* skew */
  shear_res = shear1[2] + (shear2[2] - shear1[2]) * progress; /* YZ */
  if (shear_res != 0.f)
    _clutter_util_matrix_skew_yz (&res, shear_res);

  shear_res = shear1[1] + (shear2[1] - shear1[1]) * progress; /* XZ */
  if (shear_res != 0.f)
    _clutter_util_matrix_skew_xz (&res, shear_res);

  shear_res = shear1[0] + (shear2[0] - shear1[0]) * progress; /* XY */
  if (shear_res != 0.f)
    _clutter_util_matrix_skew_xy (&res, shear_res);

  /* scale */
  clutter_vertex_interpolate (&scale1, &scale2, progress, &scale_res);
  cogl_matrix_scale (&res, scale_res.x, scale_res.y, scale_res.z);

  g_value_set_boxed (retval, &res);

  return TRUE;
}