Finish translation and rotation
This commit is contained in:
parent
ce9d7942cf
commit
0b637f7ac3
1 changed files with 124 additions and 38 deletions
|
@ -33,6 +33,8 @@ using namespace std;
|
|||
//----------------------------------------------------------------------------
|
||||
// Forward-declaring some functions for later implementation
|
||||
|
||||
void copyMatrix(GLfloat *a, GLfloat *b);
|
||||
|
||||
/// Print the matrix
|
||||
void printMatrix(string name, GLfloat *matrix);
|
||||
|
||||
|
@ -52,9 +54,11 @@ void slow4x4MatrixMultiplyIntoColumnOrder(
|
|||
GLfloat *left, GLfloat *right, GLfloat *result
|
||||
);
|
||||
|
||||
void slow4x4MatrixMultiplyAllRowOrder(
|
||||
GLfloat *left, GLfloat *right, GLfloat *result
|
||||
);
|
||||
GLfloat *slow4x4MatrixMultiplyAllRowOrder(GLfloat *left, GLfloat *right);
|
||||
|
||||
void handleScaling(int key, int scancode, int action, int mods);
|
||||
void handleRotate(double xpos, double ypos);
|
||||
void handleTranslate(double xpos, double ypos);
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
@ -78,9 +82,20 @@ GLint window_height = 500;
|
|||
GLdouble pi = 4.0 * atan(1.0);
|
||||
|
||||
// Added state
|
||||
bool is_ctrl_held = false, is_left_mouse_pressed = false;
|
||||
const GLdouble SCALE_DELTA = 0.05;
|
||||
GLdouble scale_x = 1.0, scale_y = 1.0;
|
||||
|
||||
double drag_start_x, drag_start_y;
|
||||
double last_mouse_x, last_mouse_y;
|
||||
double delta_mouse_x, delta_mouse_y;
|
||||
const GLdouble ROTATE_DELTA = 0.01;
|
||||
double rotation_angle = 0.0;
|
||||
|
||||
GLdouble TRANSLATE_DELTA_X = 2.0 / window_width;
|
||||
GLdouble TRANSLATE_DELTA_Y = -2.0 / window_height;
|
||||
GLdouble translate_x = 0.0, translate_y = 0.0;
|
||||
|
||||
// Matrices
|
||||
GLfloat rotation_matrix[16], translation_matrix[16], scale_matrix[16];
|
||||
|
||||
|
@ -104,25 +119,13 @@ key_callback(GLFWwindow *window, int key, int scancode, int action, int mods) {
|
|||
// closes the window
|
||||
glfwSetWindowShouldClose(window, GL_TRUE);
|
||||
|
||||
// arrow keys control the scaling of the object
|
||||
// Handle ctrl key press
|
||||
if (key == GLFW_KEY_LEFT_CONTROL)
|
||||
is_ctrl_held = action == GLFW_PRESS;
|
||||
|
||||
if (action == GLFW_PRESS || action == GLFW_REPEAT) {
|
||||
if (key == GLFW_KEY_LEFT || key == GLFW_KEY_A)
|
||||
scale_x -= SCALE_DELTA;
|
||||
|
||||
else if (key == GLFW_KEY_RIGHT || key == GLFW_KEY_D)
|
||||
scale_x += SCALE_DELTA;
|
||||
|
||||
else if (key == GLFW_KEY_UP || key == GLFW_KEY_W)
|
||||
scale_y += SCALE_DELTA;
|
||||
|
||||
else if (key == GLFW_KEY_DOWN || key == GLFW_KEY_S)
|
||||
scale_y -= SCALE_DELTA;
|
||||
|
||||
if (scale_x <= 0)
|
||||
scale_x = SCALE_DELTA;
|
||||
|
||||
if (scale_y <= 0)
|
||||
scale_y = SCALE_DELTA;
|
||||
// arrow keys control the scaling of the object
|
||||
handleScaling(key, scancode, action, mods);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -133,22 +136,42 @@ static void
|
|||
mouse_button_callback(GLFWwindow *window, int button, int action, int mods) {
|
||||
glfwGetCursorPos(window, &mouse_x, &mouse_y);
|
||||
|
||||
// Check which mouse button triggered the event, e.g. GLFW_MOUSE_BUTTON_LEFT,
|
||||
// etc. and what the button action was, e.g. GLFW_PRESS, GLFW_RELEASE, etc.
|
||||
// (Note that ordinary trackpad click = mouse left button)
|
||||
// Also check if any modifier keys were active at the time of the button
|
||||
// press, e.g. GLFW_MOD_ALT, etc. Take the appropriate action, which could
|
||||
// (optionally) also include changing the cursor's appearance
|
||||
// Check which mouse button triggered the event, e.g.
|
||||
// GLFW_MOUSE_BUTTON_LEFT, etc. and what the button action was, e.g.
|
||||
// GLFW_PRESS, GLFW_RELEASE, etc. (Note that ordinary trackpad click = mouse
|
||||
// left button) Also check if any modifier keys were active at the time of
|
||||
// the button press, e.g. GLFW_MOD_ALT, etc. Take the appropriate action,
|
||||
// which could (optionally) also include changing the cursor's appearance
|
||||
|
||||
if (button == GLFW_MOUSE_BUTTON_LEFT) {
|
||||
is_left_mouse_pressed = action == GLFW_PRESS;
|
||||
|
||||
if (action == GLFW_PRESS) {
|
||||
drag_start_x = mouse_x;
|
||||
drag_start_y = mouse_y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// function that is called whenever a cursor motion event occurs
|
||||
static void cursor_pos_callback(GLFWwindow *window, double xpos, double ypos) {
|
||||
|
||||
// determine the direction of the mouse or cursor motion
|
||||
// update the current mouse or cursor location
|
||||
// (necessary to quantify the amount and direction of cursor motion)
|
||||
// take the appropriate action
|
||||
|
||||
delta_mouse_x = xpos - last_mouse_x;
|
||||
delta_mouse_y = ypos - last_mouse_y;
|
||||
|
||||
if (is_left_mouse_pressed) {
|
||||
if (is_ctrl_held)
|
||||
handleTranslate(xpos, ypos);
|
||||
else
|
||||
handleRotate(xpos, ypos);
|
||||
}
|
||||
|
||||
glfwGetCursorPos(window, &last_mouse_x, &last_mouse_y);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -225,8 +248,8 @@ void init(void) {
|
|||
glClearColor(1.0, 1.0, 1.0, 1.0); // white, opaque background
|
||||
|
||||
// Define some GLFW cursors (in case you want to dynamically change the
|
||||
// cursor's appearance) If you want, you can add more cursors, or even define
|
||||
// your own cursor appearance
|
||||
// cursor's appearance) If you want, you can add more cursors, or even
|
||||
// define your own cursor appearance
|
||||
arrow_cursor = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
|
||||
hand_cursor = glfwCreateStandardCursor(GLFW_HAND_CURSOR);
|
||||
}
|
||||
|
@ -290,8 +313,10 @@ int main(int argc, char **argv) {
|
|||
// fill/re-fill the window with the background color
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
rotation_matrix[0] = 1.0;
|
||||
rotation_matrix[5] = 1.0;
|
||||
rotation_matrix[0] = cos(rotation_angle);
|
||||
rotation_matrix[1] = -sin(rotation_angle);
|
||||
rotation_matrix[4] = sin(rotation_angle);
|
||||
rotation_matrix[5] = cos(rotation_angle);
|
||||
rotation_matrix[10] = 1.0;
|
||||
rotation_matrix[15] = 1.0;
|
||||
|
||||
|
@ -300,27 +325,45 @@ int main(int argc, char **argv) {
|
|||
scale_matrix[10] = 1.0;
|
||||
scale_matrix[15] = 1.0;
|
||||
|
||||
translation_matrix[0] = 1.0;
|
||||
translation_matrix[5] = 1.0;
|
||||
translation_matrix[10] = 1.0;
|
||||
translation_matrix[15] = 1.0;
|
||||
translation_matrix[3] = translate_x;
|
||||
translation_matrix[7] = translate_y;
|
||||
|
||||
// define/re-define the modelview matrix. In this template, we define M to
|
||||
// be the identity matrix; you will need define M according to the user's
|
||||
// actions.
|
||||
|
||||
slow4x4MatrixMultiplyAllRowOrder(rotation_matrix, scale_matrix, M);
|
||||
GLfloat *result1 =
|
||||
slow4x4MatrixMultiplyAllRowOrder(scale_matrix, rotation_matrix);
|
||||
GLfloat *result2 =
|
||||
slow4x4MatrixMultiplyAllRowOrder(translation_matrix, result1);
|
||||
|
||||
copyMatrix(result2, M);
|
||||
transposeMatrix(M);
|
||||
|
||||
free(result1);
|
||||
free(result2);
|
||||
|
||||
// sanity check that your matrix contents are what you expect them to be
|
||||
if (DEBUG_ON) {
|
||||
/*
|
||||
printf("--------------");
|
||||
printf("scale_x = %f , scale_y = %f\n", scale_x, scale_y);
|
||||
printf("translate_x = %f , translate_y = %f\n", translate_x, translate_y);
|
||||
printMatrix("rotation_matrix", rotation_matrix);
|
||||
printMatrix("scale_matrix", scale_matrix);
|
||||
printMatrix("M", M);
|
||||
*/
|
||||
}
|
||||
|
||||
// send the updated model transformation matrix to the GPU
|
||||
glUniformMatrix4fv(m_location, 1, GL_FALSE, M);
|
||||
|
||||
// draw a triangle between the first vertex and each successive vertex pair
|
||||
// in the hard-coded model
|
||||
// draw a triangle between the first vertex and each successive vertex
|
||||
// pair in the hard-coded model
|
||||
glDrawArrays(GL_TRIANGLES, 0, NVERTICES);
|
||||
|
||||
// ensure that all OpenGL calls have executed before swapping buffers
|
||||
|
@ -353,6 +396,12 @@ void printMatrix(string name, GLfloat *matrix) {
|
|||
);
|
||||
}
|
||||
|
||||
void copyMatrix(GLfloat *a, GLfloat *b) {
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
b[i] = a[i];
|
||||
}
|
||||
}
|
||||
|
||||
void transposeMatrix(GLfloat *matrix) {
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int j = i + 1; j < 4; ++j) {
|
||||
|
@ -369,9 +418,9 @@ void zeroInitGlfloats(GLfloat *arr, uint32_t len) {
|
|||
}
|
||||
}
|
||||
|
||||
void slow4x4MatrixMultiplyAllRowOrder(
|
||||
GLfloat *left, GLfloat *right, GLfloat *result
|
||||
) {
|
||||
GLfloat *slow4x4MatrixMultiplyAllRowOrder(GLfloat *left, GLfloat *right) {
|
||||
GLfloat *result = (GLfloat *)malloc(16 * sizeof(GLfloat));
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
result[i * 4 + j] = 0;
|
||||
|
@ -382,4 +431,41 @@ void slow4x4MatrixMultiplyAllRowOrder(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void handleScaling(int key, int scancode, int action, int mods) {
|
||||
if (key == GLFW_KEY_LEFT || key == GLFW_KEY_A)
|
||||
scale_x -= SCALE_DELTA;
|
||||
|
||||
else if (key == GLFW_KEY_RIGHT || key == GLFW_KEY_D)
|
||||
scale_x += SCALE_DELTA;
|
||||
|
||||
else if (key == GLFW_KEY_UP || key == GLFW_KEY_W)
|
||||
scale_y += SCALE_DELTA;
|
||||
|
||||
else if (key == GLFW_KEY_DOWN || key == GLFW_KEY_S)
|
||||
scale_y -= SCALE_DELTA;
|
||||
|
||||
if (scale_x <= 0)
|
||||
scale_x = SCALE_DELTA;
|
||||
|
||||
if (scale_y <= 0)
|
||||
scale_y = SCALE_DELTA;
|
||||
}
|
||||
|
||||
void handleRotate(double xpos, double ypos) {
|
||||
rotation_angle -= delta_mouse_x * ROTATE_DELTA;
|
||||
}
|
||||
|
||||
void handleTranslate(double xpos, double ypos) {
|
||||
/*
|
||||
printf(
|
||||
"pos : (%f, %f) -- last_mouse : (%f, %f)\n", xpos, ypos, last_mouse_x,
|
||||
last_mouse_y
|
||||
);
|
||||
*/
|
||||
translate_x += delta_mouse_x * TRANSLATE_DELTA_X;
|
||||
translate_y += delta_mouse_y * TRANSLATE_DELTA_Y;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue