diff --git a/cogl/cogl-framebuffer.c b/cogl/cogl-framebuffer.c index bae5c019b..43971c2c9 100644 --- a/cogl/cogl-framebuffer.c +++ b/cogl/cogl-framebuffer.c @@ -2651,6 +2651,32 @@ cogl_framebuffer_rotate (CoglFramebuffer *framebuffer, COGL_FRAMEBUFFER_STATE_MODELVIEW; } +void +cogl_framebuffer_rotate_quaternion (CoglFramebuffer *framebuffer, + const CoglQuaternion *quaternion) +{ + CoglMatrixStack *modelview_stack = + _cogl_framebuffer_get_modelview_stack (framebuffer); + _cogl_matrix_stack_rotate_quaternion (modelview_stack, quaternion); + + if (framebuffer->context->current_draw_buffer == framebuffer) + framebuffer->context->current_draw_buffer_changes |= + COGL_FRAMEBUFFER_STATE_MODELVIEW; +} + +void +cogl_framebuffer_rotate_euler (CoglFramebuffer *framebuffer, + const CoglEuler *euler) +{ + CoglMatrixStack *modelview_stack = + _cogl_framebuffer_get_modelview_stack (framebuffer); + _cogl_matrix_stack_rotate_euler (modelview_stack, euler); + + if (framebuffer->context->current_draw_buffer == framebuffer) + framebuffer->context->current_draw_buffer_changes |= + COGL_FRAMEBUFFER_STATE_MODELVIEW; +} + void cogl_framebuffer_transform (CoglFramebuffer *framebuffer, const CoglMatrix *matrix) diff --git a/cogl/cogl-framebuffer.h b/cogl/cogl-framebuffer.h index 76ce811af..44510e62a 100644 --- a/cogl/cogl-framebuffer.h +++ b/cogl/cogl-framebuffer.h @@ -43,6 +43,10 @@ #include #include #include +#ifdef COGL_ENABLE_EXPERIMENTAL_API +#include +#include +#endif G_BEGIN_DECLS @@ -347,6 +351,40 @@ cogl_framebuffer_rotate (CoglFramebuffer *framebuffer, float y, float z); +#ifdef COGL_ENABLE_EXPERIMENTAL_API + +/** + * cogl_framebuffer_rotate_quaternion: + * @framebuffer: A #CoglFramebuffer pointer + * @quaternion: A #CoglQuaternion + * + * Multiplies the current model-view matrix by one that rotates + * according to the rotation described by @quaternion. + * + * Since: 2.0 + * Stability: unstable + */ +void +cogl_framebuffer_rotate_quaternion (CoglFramebuffer *framebuffer, + const CoglQuaternion *quaternion); + +/** + * cogl_framebuffer_rotate_euler: + * @framebuffer: A #CoglFramebuffer pointer + * @euler: A #CoglEuler + * + * Multiplies the current model-view matrix by one that rotates + * according to the rotation described by @euler. + * + * Since: 2.0 + * Stability: unstable + */ +void +cogl_framebuffer_rotate_euler (CoglFramebuffer *framebuffer, + const CoglEuler *euler); + +#endif /* COGL_ENABLE_EXPERIMENTAL_API */ + /** * cogl_framebuffer_transform: * @framebuffer: A #CoglFramebuffer pointer diff --git a/cogl/cogl-matrix-stack.c b/cogl/cogl-matrix-stack.c index a8b42e7a8..14a9040dc 100644 --- a/cogl/cogl-matrix-stack.c +++ b/cogl/cogl-matrix-stack.c @@ -122,6 +122,37 @@ _cogl_matrix_stack_rotate (CoglMatrixStack *stack, entry->z = z; } +void +_cogl_matrix_stack_rotate_quaternion (CoglMatrixStack *stack, + const CoglQuaternion *quaternion) +{ + CoglMatrixEntryRotateQuaternion *entry; + + entry = _cogl_matrix_stack_push_entry (stack, + sizeof (CoglMatrixEntryRotate), + COGL_MATRIX_OP_ROTATE_QUATERNION); + + entry->values[0] = quaternion->w; + entry->values[1] = quaternion->x; + entry->values[2] = quaternion->y; + entry->values[3] = quaternion->z; +} + +void +_cogl_matrix_stack_rotate_euler (CoglMatrixStack *stack, + const CoglEuler *euler) +{ + CoglMatrixEntryRotateEuler *entry; + + entry = _cogl_matrix_stack_push_entry (stack, + sizeof (CoglMatrixEntryRotate), + COGL_MATRIX_OP_ROTATE_EULER); + + entry->heading = euler->heading; + entry->pitch = euler->pitch; + entry->roll = euler->roll; +} + void _cogl_matrix_stack_scale (CoglMatrixStack *stack, float x, @@ -272,6 +303,8 @@ _cogl_matrix_entry_unref (CoglMatrixEntry *entry) 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: break; case COGL_MATRIX_OP_MULTIPLY: @@ -411,6 +444,8 @@ initialized: 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; @@ -485,6 +520,28 @@ initialized: 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 = @@ -877,6 +934,31 @@ _cogl_matrix_entry_equal (CoglMatrixEntry *entry0, return FALSE; } break; + case COGL_MATRIX_OP_ROTATE_QUATERNION: + { + CoglMatrixEntryRotateQuaternion *rotate0 = + (CoglMatrixEntryRotateQuaternion *)entry0; + CoglMatrixEntryRotateQuaternion *rotate1 = + (CoglMatrixEntryRotateQuaternion *)entry1; + int i; + for (i = 0; i < 4; i++) + if (rotate0->values[i] != rotate1->values[i]) + return FALSE; + } + break; + case COGL_MATRIX_OP_ROTATE_EULER: + { + CoglMatrixEntryRotateEuler *rotate0 = + (CoglMatrixEntryRotateEuler *)entry0; + CoglMatrixEntryRotateEuler *rotate1 = + (CoglMatrixEntryRotateEuler *)entry1; + + if (rotate0->heading != rotate1->heading || + rotate0->pitch != rotate1->pitch || + rotate0->roll != rotate1->roll) + return FALSE; + } + break; case COGL_MATRIX_OP_SCALE: { CoglMatrixEntryScale *scale0 = (CoglMatrixEntryScale *)entry0; @@ -965,6 +1047,27 @@ _cogl_matrix_entry_print (CoglMatrixEntry *entry) rotate->z); continue; } + case COGL_MATRIX_OP_ROTATE_QUATERNION: + { + CoglMatrixEntryRotateQuaternion *rotate = + (CoglMatrixEntryRotateQuaternion *)entry; + g_print (" ROTATE QUATERNION w=%f x=%f y=%f z=%f\n", + rotate->values[0], + rotate->values[1], + rotate->values[2], + rotate->values[3]); + continue; + } + case COGL_MATRIX_OP_ROTATE_EULER: + { + CoglMatrixEntryRotateEuler *rotate = + (CoglMatrixEntryRotateEuler *)entry; + g_print (" ROTATE EULER heading=%f pitch=%f roll=%f\n", + rotate->heading, + rotate->pitch, + rotate->roll); + continue; + } case COGL_MATRIX_OP_SCALE: { CoglMatrixEntryScale *scale = (CoglMatrixEntryScale *)entry; diff --git a/cogl/cogl-matrix-stack.h b/cogl/cogl-matrix-stack.h index db957d6ca..8b942e33a 100644 --- a/cogl/cogl-matrix-stack.h +++ b/cogl/cogl-matrix-stack.h @@ -39,6 +39,8 @@ typedef enum _CoglMatrixOp COGL_MATRIX_OP_LOAD_IDENTITY, COGL_MATRIX_OP_TRANSLATE, COGL_MATRIX_OP_ROTATE, + COGL_MATRIX_OP_ROTATE_QUATERNION, + COGL_MATRIX_OP_ROTATE_EULER, COGL_MATRIX_OP_SCALE, COGL_MATRIX_OP_MULTIPLY, COGL_MATRIX_OP_LOAD, @@ -78,6 +80,26 @@ typedef struct _CoglMatrixEntryRotate } CoglMatrixEntryRotate; +typedef struct _CoglMatrixEntryRotateEuler +{ + CoglMatrixEntry _parent_data; + + /* This doesn't store an actual CoglEuler in order to avoid the + * padding */ + float heading; + float pitch; + float roll; +} CoglMatrixEntryRotateEuler; + +typedef struct _CoglMatrixEntryRotateQuaternion +{ + CoglMatrixEntry _parent_data; + + /* This doesn't store an actual CoglQuaternion in order to avoid the + * padding */ + float values[4]; +} CoglMatrixEntryRotateQuaternion; + typedef struct _CoglMatrixEntryScale { CoglMatrixEntry _parent_data; @@ -117,7 +139,9 @@ typedef union _CoglMatrixEntryFull { CoglMatrixEntry any; CoglMatrixEntryTranslate translate; - CoglMatrixEntryRotate rotae; + CoglMatrixEntryRotate rotate; + CoglMatrixEntryRotateEuler rotate_euler; + CoglMatrixEntryRotateQuaternion rotate_quaternion; CoglMatrixEntryScale scale; CoglMatrixEntryMultiply multiply; CoglMatrixEntryLoad load; @@ -170,6 +194,12 @@ _cogl_matrix_stack_rotate (CoglMatrixStack *stack, float y, float z); void +_cogl_matrix_stack_rotate_quaternion (CoglMatrixStack *stack, + const CoglQuaternion *quaternion); +void +_cogl_matrix_stack_rotate_euler (CoglMatrixStack *stack, + const CoglEuler *euler); +void _cogl_matrix_stack_multiply (CoglMatrixStack *stack, const CoglMatrix *matrix); void diff --git a/cogl/cogl-matrix.c b/cogl/cogl-matrix.c index d82ca8271..0989c080c 100644 --- a/cogl/cogl-matrix.c +++ b/cogl/cogl-matrix.c @@ -1352,6 +1352,26 @@ cogl_matrix_rotate (CoglMatrix *matrix, _COGL_MATRIX_DEBUG_PRINT (matrix); } +void +cogl_matrix_rotate_quaternion (CoglMatrix *matrix, + const CoglQuaternion *quaternion) +{ + CoglMatrix rotation_transform; + + cogl_matrix_init_from_quaternion (&rotation_transform, quaternion); + cogl_matrix_multiply (matrix, matrix, &rotation_transform); +} + +void +cogl_matrix_rotate_euler (CoglMatrix *matrix, + const CoglEuler *euler) +{ + CoglMatrix rotation_transform; + + cogl_matrix_init_from_euler (&rotation_transform, euler); + cogl_matrix_multiply (matrix, matrix, &rotation_transform); +} + /* * Apply a perspective projection matrix. * diff --git a/cogl/cogl-matrix.h b/cogl/cogl-matrix.h index 53b786571..570a23c0c 100644 --- a/cogl/cogl-matrix.h +++ b/cogl/cogl-matrix.h @@ -185,6 +185,36 @@ cogl_matrix_rotate (CoglMatrix *matrix, float y, float z); +#ifdef COGL_ENABLE_EXPERIMENTAL_API +/** + * cogl_matrix_rotate_quaternion: + * @matrix: A 4x4 transformation matrix + * @quaternion: A quaternion describing a rotation + * + * Multiplies @matrix with a rotation transformation described by the + * given #CoglQuaternion. + * + * Since: 2.0 + */ +void +cogl_matrix_rotate_quaternion (CoglMatrix *matrix, + const CoglQuaternion *quaternion); + +/** + * cogl_matrix_rotate_euler: + * @matrix: A 4x4 transformation matrix + * @euler: A euler describing a rotation + * + * Multiplies @matrix with a rotation transformation described by the + * given #CoglEuler. + * + * Since: 2.0 + */ +void +cogl_matrix_rotate_euler (CoglMatrix *matrix, + const CoglEuler *euler); +#endif + /** * cogl_matrix_translate: * @matrix: A 4x4 transformation matrix diff --git a/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt b/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt index 8ba5e9ea7..5944632db 100644 --- a/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt +++ b/doc/reference/cogl-2.0-experimental/cogl-2.0-experimental-sections.txt @@ -440,6 +440,8 @@ cogl_framebuffer_identity_matrix cogl_framebuffer_scale cogl_framebuffer_translate cogl_framebuffer_rotate +cogl_framebuffer_rotate_euler +cogl_framebuffer_rotate_quaternion cogl_framebuffer_transform cogl_framebuffer_get_modelview_matrix cogl_framebuffer_set_modelview_matrix @@ -557,6 +559,8 @@ cogl_matrix_perspective cogl_matrix_look_at cogl_matrix_multiply cogl_matrix_rotate +cogl_matrix_rotate_quaternion +cogl_matrix_rotate_euler cogl_matrix_translate cogl_matrix_scale cogl_matrix_transpose