コード例 #1
0
ファイル: meta-window-group.c プロジェクト: collinss/muffin
/* Check if we're painting the MetaWindowGroup "untransformed". This can
 * differ from the result of actor_is_untransformed(window_group) if we're
 * inside a clone paint. The integer translation, if any, is returned.
 */
static gboolean
painting_untransformed (MetaWindowGroup *window_group,
                        int             *x_origin,
                        int             *y_origin)
{
  CoglMatrix modelview, projection, modelview_projection;
  ClutterVertex vertices[4];
  int width, height;
  float viewport[4];
  int i;

  cogl_get_modelview_matrix (&modelview);
  cogl_get_projection_matrix (&projection);

  cogl_matrix_multiply (&modelview_projection,
                        &projection,
                        &modelview);

  meta_screen_get_size (window_group->screen, &width, &height);

  vertices[0].x = 0;
  vertices[0].y = 0;
  vertices[0].z = 0;
  vertices[1].x = width;
  vertices[1].y = 0;
  vertices[1].z = 0;
  vertices[2].x = 0;
  vertices[2].y = height;
  vertices[2].z = 0;
  vertices[3].x = width;
  vertices[3].y = height;
  vertices[3].z = 0;

  cogl_get_viewport (viewport);

  for (i = 0; i < 4; i++)
    {
      float w = 1;
      cogl_matrix_transform_point (&modelview_projection, &vertices[i].x, &vertices[i].y, &vertices[i].z, &w);
      vertices[i].x = MTX_GL_SCALE_X (vertices[i].x, w,
                                      viewport[2], viewport[0]);
      vertices[i].y = MTX_GL_SCALE_Y (vertices[i].y, w,
                                      viewport[3], viewport[1]);
    }

  return meta_actor_vertices_are_untransformed (vertices, width, height, x_origin, y_origin);
}
コード例 #2
0
ファイル: cogl-clip-stack.c プロジェクト: gramozeka/GSB-NEW
/* Try to push a rectangle given in object coordinates as a rectangle in window
 * coordinates instead of object coordinates */
gboolean
try_pushing_rect_as_window_rect (float x_1,
	                         float y_1,
                                 float x_2,
                                 float y_2)
{
  CoglMatrix matrix;
  CoglMatrix matrix_p;
  float v[4];

  cogl_get_modelview_matrix (&matrix);

  /* If the modelview meets these constraints then a transformed rectangle
   * should still be a rectangle when it reaches screen coordinates.
   *
   * FIXME: we are are making certain assumptions about the projection
   * matrix a.t.m and should really be looking at the combined modelview
   * and projection matrix.
   * FIXME: we don't consider rotations that are a multiple of 90 degrees
   * which could be quite common.
   */
  if (matrix.xy != 0 || matrix.xz != 0 ||
      matrix.yx != 0 || matrix.yz != 0 ||
      matrix.zx != 0 || matrix.zy != 0)
    return FALSE;

  cogl_get_projection_matrix (&matrix_p);
  cogl_get_viewport (v);

  transform_point (&matrix, &matrix_p, v, &x_1, &y_1);
  transform_point (&matrix, &matrix_p, v, &x_2, &y_2);

  /* Consider that the modelview matrix may flip the rectangle
   * along the x or y axis... */
#define SWAP(A,B) do { float tmp = B; B = A; A = tmp; } while (0)
  if (x_1 > x_2)
    SWAP (x_1, x_2);
  if (y_1 > y_2)
    SWAP (y_1, y_2);
#undef SWAP

  cogl_clip_push_window_rectangle (COGL_UTIL_NEARBYINT (x_1),
                                   COGL_UTIL_NEARBYINT (y_1),
                                   COGL_UTIL_NEARBYINT (x_2 - x_1),
                                   COGL_UTIL_NEARBYINT (y_2 - y_1));
  return TRUE;
}
コード例 #3
0
ファイル: cogl-clip-state.c プロジェクト: nobled/clutter
void
cogl_clip_push_from_path_preserve (void)
{
  CoglFramebuffer *framebuffer;
  CoglClipState *clip_state;
  CoglMatrix modelview_matrix;

  _COGL_GET_CONTEXT (ctx, NO_RETVAL);

  framebuffer = _cogl_get_draw_buffer ();
  clip_state = _cogl_framebuffer_get_clip_state (framebuffer);

  cogl_get_modelview_matrix (&modelview_matrix);

  clip_state->stacks->data =
    _cogl_clip_stack_push_from_path (clip_state->stacks->data,
                                     ctx->current_path,
                                     &modelview_matrix);
}
コード例 #4
0
ファイル: cogl-clip-stack.c プロジェクト: gramozeka/GSB-NEW
void
cogl_clip_push_rectangle (float x_1,
                          float y_1,
                          float x_2,
                          float y_2)
{
  CoglHandle framebuffer;
  CoglClipStackState *clip_state;
  CoglClipStack *stack;
  CoglClipStackEntryRect *entry;

  _COGL_GET_CONTEXT (ctx, NO_RETVAL);

  /* We don't log clip stack changes in the journal so we must flush
   * it before making modifications */
  _cogl_journal_flush ();

  /* Try and catch window space rectangles so we can redirect to
   * cogl_clip_push_window_rect which will use scissoring. */
  if (try_pushing_rect_as_window_rect (x_1, y_1, x_2, y_2))
    return;

  framebuffer = _cogl_get_framebuffer ();
  clip_state = _cogl_framebuffer_get_clip_state (framebuffer);

  stack = clip_state->stacks->data;

  entry = g_slice_new (CoglClipStackEntryRect);

  /* Make a new entry */
  entry->type = COGL_CLIP_STACK_RECT;
  entry->x0 = x_1;
  entry->y0 = y_1;
  entry->x1 = x_2;
  entry->y1 = y_2;

  cogl_get_modelview_matrix (&entry->matrix);

  /* Store it in the stack */
  stack->stack_top = g_list_prepend (stack->stack_top, entry);

  clip_state->stack_dirty = TRUE;
}
コード例 #5
0
ファイル: test-backface-culling.c プロジェクト: collects/cogl
static void
paint (TestState *state)
{
  float stage_viewport[4];
  CoglMatrix stage_projection;
  CoglMatrix stage_modelview;

  paint_test_backface_culling (state);

  /*
   * Now repeat the test but rendered to an offscreen
   * framebuffer. Note that by default the conformance tests are
   * always run to an offscreen buffer but we might as well have this
   * check anyway in case it is being run with COGL_TEST_ONSCREEN=1
   */

  cogl_get_viewport (stage_viewport);
  cogl_get_projection_matrix (&stage_projection);
  cogl_get_modelview_matrix (&stage_modelview);

  cogl_push_framebuffer (state->offscreen);

  cogl_set_viewport (stage_viewport[0],
                     stage_viewport[1],
                     stage_viewport[2],
                     stage_viewport[3]);
  cogl_set_projection_matrix (&stage_projection);
  cogl_set_modelview_matrix (&stage_modelview);

  paint_test_backface_culling (state);

  cogl_pop_framebuffer ();

  /* Incase we want feedback of what was drawn offscreen we draw it
   * to the stage... */
  cogl_set_source_texture (state->offscreen_tex);
  cogl_rectangle (0, TEXTURE_RENDER_SIZE * 16,
                  stage_viewport[2],
                  stage_viewport[3] + TEXTURE_RENDER_SIZE * 16);

  validate_result (0);
  validate_result (16);
}
コード例 #6
0
ファイル: cogl-clip-state.c プロジェクト: nobled/clutter
void
cogl_clip_push_rectangle (float x_1,
                          float y_1,
                          float x_2,
                          float y_2)
{
  CoglFramebuffer *framebuffer;
  CoglClipState *clip_state;
  CoglMatrix modelview_matrix;

  _COGL_GET_CONTEXT (ctx, NO_RETVAL);

  framebuffer = _cogl_get_draw_buffer ();
  clip_state = _cogl_framebuffer_get_clip_state (framebuffer);

  cogl_get_modelview_matrix (&modelview_matrix);

  clip_state->stacks->data =
    _cogl_clip_stack_push_rectangle (clip_state->stacks->data,
                                     x_1, y_1, x_2, y_2,
                                     &modelview_matrix);
}
コード例 #7
0
ファイル: cogl-clip-stack.c プロジェクト: gramozeka/GSB-NEW
void
cogl_clip_push_from_path_preserve (void)
{
  CoglHandle framebuffer;
  CoglClipStackState *clip_state;
  CoglClipStack *stack;
  CoglClipStackEntryPath *entry;

  _COGL_GET_CONTEXT (ctx, NO_RETVAL);

  /* We don't log clip stack changes in the journal so we must flush
   * it before making modifications */
  _cogl_journal_flush ();

  framebuffer = _cogl_get_framebuffer ();
  clip_state = _cogl_framebuffer_get_clip_state (framebuffer);

  stack = clip_state->stacks->data;

  entry = g_malloc (sizeof (CoglClipStackEntryPath)
                    + sizeof (CoglPathNode) * (ctx->path_nodes->len - 1));

  entry->type = COGL_CLIP_STACK_PATH;
  entry->path_nodes_min = ctx->path_nodes_min;
  entry->path_nodes_max = ctx->path_nodes_max;
  entry->path_size = ctx->path_nodes->len;
  memcpy (entry->path, ctx->path_nodes->data,
          sizeof (CoglPathNode) * ctx->path_nodes->len);

  cogl_get_modelview_matrix (&entry->matrix);

  /* Store it in the stack */
  stack->stack_top = g_list_prepend (stack->stack_top, entry);

  clip_state->stack_dirty = TRUE;
}
コード例 #8
0
ファイル: meta-texture-tower.c プロジェクト: darkxst/mtest
/* This determines the appropriate level of detail to use when drawing the
 * texture, in a way that corresponds to what the GL specification does
 * when mip-mapping. This is probably fancier and slower than what we need,
 * but we do the computation only once each time we paint a window, and
 * its easier to just use the equations from the specification than to
 * come up with something simpler.
 *
 * If window is being painted at an angle from the viewer, then we have to
 * pick a point in the texture; we use the middle of the texture (which is
 * why the width/height are passed in.) This is not the normal case for
 * Meta.
 */
static int
get_paint_level (int width, int height)
{
  CoglMatrix projection, modelview, pm;
  float v[4];
  double viewport_width, viewport_height;
  double u0, v0;
  double xc, yc, wc;
  double dxdu_, dxdv_, dydu_, dydv_;
  double det_, det_sq;
  double rho_sq;
  double lambda;

  /* See
   * http://www.opengl.org/registry/doc/glspec32.core.20090803.pdf
   * Section 3.8.9, p. 1.6.2. Here we have
   *
   *  u(x,y) = x_o;
   *  v(x,y) = y_o;
   *
   * Since we are mapping 1:1 from object coordinates into pixel
   * texture coordinates, the clip coordinates are:
   *
   *  (x_c)                               (x_o)        (u)
   *  (y_c) = (M_projection)(M_modelview) (y_o) = (PM) (v)
   *  (z_c)                               (z_o)        (0)
   *  (w_c)                               (w_o)        (1)
   */

  cogl_get_projection_matrix (&projection);
  cogl_get_modelview_matrix (&modelview);

  cogl_matrix_multiply (&pm, &projection, &modelview);

  cogl_get_viewport (v);
  viewport_width = v[2];
  viewport_height = v[3];

  u0 = width / 2.;
  v0 = height / 2.;

  xc = pm.xx * u0 + pm.xy * v0 + pm.xw;
  yc = pm.yx * u0 + pm.yy * v0 + pm.yw;
  wc = pm.wx * u0 + pm.wy * v0 + pm.ww;

  /* We'll simplify the equations below for a bit of micro-optimization.
   * The commented out code is the unsimplified version.

  // Partial derivates of window coordinates:
  //
  //  x_w = 0.5 * viewport_width * x_c / w_c + viewport_center_x
  //  y_w = 0.5 * viewport_height * y_c / w_c + viewport_center_y
  //
  // with respect to u, v, using
  // d(a/b)/dx = da/dx * (1/b) - a * db/dx / (b^2)

  dxdu = 0.5 * viewport_width * (pm.xx - pm.wx * (xc/wc)) / wc;
  dxdv = 0.5 * viewport_width * (pm.xy - pm.wy * (xc/wc)) / wc;
  dydu = 0.5 * viewport_height * (pm.yx - pm.wx * (yc/wc)) / wc;
  dydv = 0.5 * viewport_height * (pm.yy - pm.wy * (yc/wc)) / wc;

  // Compute the inverse partials as the matrix inverse
  det = dxdu * dydv - dxdv * dydu;

  dudx =   dydv / det;
  dudy = - dxdv / det;
  dvdx = - dydu / det;
  dvdy =   dvdu / det;

  // Scale factor; maximum of the distance in texels for a change of 1 pixel
  // in the X direction or 1 pixel in the Y direction
  rho = MAX (sqrt (dudx * dudx + dvdx * dvdx), sqrt(dudy * dudy + dvdy * dvdy));

  // Level of detail
  lambda = log2 (rho) + LOD_BIAS;
  */

  /* dxdu * wc, etc */
  dxdu_ = 0.5 * viewport_width * (pm.xx - pm.wx * (xc/wc));
  dxdv_ = 0.5 * viewport_width * (pm.xy - pm.wy * (xc/wc));
  dydu_ = 0.5 * viewport_height * (pm.yx - pm.wx * (yc/wc));
  dydv_ = 0.5 * viewport_height * (pm.yy - pm.wy * (yc/wc));

  /* det * wc^2 */
  det_ = dxdu_ * dydv_ - dxdv_ * dydu_;
  det_sq = det_ * det_;
  if (det_sq == 0.0)
    return -1;

  /* (rho * det * wc)^2 */
  rho_sq = MAX (dydv_ * dydv_ + dydu_ * dydu_, dxdv_ * dxdv_ + dxdu_ * dxdu_);
  lambda = 0.5 * M_LOG2E * log (rho_sq * wc * wc / det_sq) + LOD_BIAS;

#if 0
  g_print ("%g %g %g\n", 0.5 * viewport_width * pm.xx / pm.ww, 0.5 * viewport_height * pm.yy / pm.ww, lambda);
#endif

  if (lambda <= 0.)
    return 0;
  else
    return (int)(0.5 + lambda);
}