matrix: adds 2d view transform conveniences

This adds two new experimental functions to cogl-matrix.c:
cogl_matrix_view_2d_in_perspective and cogl_matrix_view_2d_in_frustum
which can be used to setup a view transform that maps a 2D coordinate
system (0,0) top left and (width,height) bottom right to the current
viewport.

Toolkits such as Clutter that want to mix 2D and 3D drawing can use
these APIs to position a 2D coordinate system at an arbitrary depth
inside a 3D perspective projected viewing frustum.
This commit is contained in:
Robert Bragg 2011-02-08 15:21:41 +00:00
parent 1431b77747
commit ca30ac7835
2 changed files with 137 additions and 0 deletions

View File

@ -304,6 +304,63 @@ cogl_matrix_ortho (CoglMatrix *matrix,
_COGL_MATRIX_DEBUG_PRINT (matrix); _COGL_MATRIX_DEBUG_PRINT (matrix);
} }
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);
}
/* Assuming a symmetric perspective matrix is being used for your
* projective transform this convenience function lets you compose a
* view transform such that geometry on the z=0 plane will map to
* screen coordinates with a top left origin of (0,0) and with the
* given width and height.
*/
void
cogl_matrix_view_2d_in_perspective (CoglMatrix *matrix,
float fov_y,
float aspect,
float z_near,
float z_2d,
float width_2d,
float height_2d)
{
float top = z_near * tan (fov_y * G_PI / 360.0);
cogl_matrix_view_2d_in_frustum (matrix,
-top * aspect,
top * aspect,
-top,
top,
z_near,
z_2d,
width_2d,
height_2d);
}
void void
cogl_matrix_init_from_array (CoglMatrix *matrix, const float *array) cogl_matrix_init_from_array (CoglMatrix *matrix, const float *array)
{ {

View File

@ -258,6 +258,86 @@ cogl_matrix_ortho (CoglMatrix *matrix,
float z_near, float z_near,
float z_far); float z_far);
#ifdef COGL_ENABLE_EXPERIMENTAL_API
#define cogl_matrix_view_2d_in_frustum cogl_matrix_view_2d_in_frustum_EXP
#define cogl_matrix_view_2d_in_perspective \
cogl_matrix_view_2d_in_perspective_EXP
/**
* cogl_matrix_view_2d_in_frustum:
* @matrix: A 4x4 transformation matrix
* @left: coord of left vertical clipping plane
* @right: coord of right vertical clipping plane
* @bottom: coord of bottom horizontal clipping plane
* @top: coord of top horizontal clipping plane
* @z_near: The distance to the near clip plane. Never pass 0 and always pass
* a positive number.
* @z_2d: The distance to the 2D plane. (Should always be positive and
* be between @z_near and the z_far value that was passed to
* cogl_matrix_frustum())
* @width_2d: The width of the 2D coordinate system
* @height_2d: The height of the 2D coordinate system
*
* Multiplies @matrix by a view transform that maps the 2D coordinates
* (0,0) top left and (@width_2d,@height_2d) bottom right the full viewport
* size. Geometry at a depth of 0 will now lie on this 2D plane.
*
* Note: this doesn't multiply the matrix by any projection matrix,
* but it assumes you have a perspective projection as defined by
* passing the corresponding arguments to cogl_matrix_frustum().
* Toolkits such as Clutter that mix 2D and 3D drawing can use this to
* create a 2D coordinate system within a 3D perspective projected
* view frustum.
*/
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);
/**
* cogl_matrix_view_2d_in_perspective:
* @fov_y: A field of view angle for the Y axis
* @aspect: The ratio of width to height determining the field of view angle
* for the x axis.
* @z_near: The distance to the near clip plane. Never pass 0 and always pass
* a positive number.
* @z_2d: The distance to the 2D plane. (Should always be positive and
* be between @z_near and the z_far value that was passed to
* cogl_matrix_frustum())
* @width_2d: The width of the 2D coordinate system
* @height_2d: The height of the 2D coordinate system
*
* Multiplies @matrix by a view transform that maps the 2D coordinates
* (0,0) top left and (@width_2d,@height_2d) bottom right the full viewport
* size. Geometry at a depth of 0 will now lie on this 2D plane.
*
* Note: this doesn't multiply the matrix by any projection matrix,
* but it assumes you have a perspective projection as defined by
* passing the corresponding arguments to cogl_matrix_perspective().
*
* Toolkits such as Clutter that mix 2D and 3D drawing can use this to
* create a 2D coordinate system within a 3D perspective projected
* view frustum.
*/
void
cogl_matrix_view_2d_in_perspective (CoglMatrix *matrix,
float fov_y,
float aspect,
float z_near,
float z_2d,
float width_2d,
float height_2d);
#endif
/** /**
* cogl_matrix_init_from_array: * cogl_matrix_init_from_array:
* @matrix: A 4x4 transformation matrix * @matrix: A 4x4 transformation matrix