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
|
// Forward-declaring some functions for later implementation
|
||||||
|
|
||||||
|
void copyMatrix(GLfloat *a, GLfloat *b);
|
||||||
|
|
||||||
/// Print the matrix
|
/// Print the matrix
|
||||||
void printMatrix(string name, GLfloat *matrix);
|
void printMatrix(string name, GLfloat *matrix);
|
||||||
|
|
||||||
|
@ -52,9 +54,11 @@ void slow4x4MatrixMultiplyIntoColumnOrder(
|
||||||
GLfloat *left, GLfloat *right, GLfloat *result
|
GLfloat *left, GLfloat *right, GLfloat *result
|
||||||
);
|
);
|
||||||
|
|
||||||
void slow4x4MatrixMultiplyAllRowOrder(
|
GLfloat *slow4x4MatrixMultiplyAllRowOrder(GLfloat *left, GLfloat *right);
|
||||||
GLfloat *left, GLfloat *right, GLfloat *result
|
|
||||||
);
|
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);
|
GLdouble pi = 4.0 * atan(1.0);
|
||||||
|
|
||||||
// Added state
|
// Added state
|
||||||
|
bool is_ctrl_held = false, is_left_mouse_pressed = false;
|
||||||
const GLdouble SCALE_DELTA = 0.05;
|
const GLdouble SCALE_DELTA = 0.05;
|
||||||
GLdouble scale_x = 1.0, scale_y = 1.0;
|
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
|
// Matrices
|
||||||
GLfloat rotation_matrix[16], translation_matrix[16], scale_matrix[16];
|
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
|
// closes the window
|
||||||
glfwSetWindowShouldClose(window, GL_TRUE);
|
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 (action == GLFW_PRESS || action == GLFW_REPEAT) {
|
||||||
if (key == GLFW_KEY_LEFT || key == GLFW_KEY_A)
|
// arrow keys control the scaling of the object
|
||||||
scale_x -= SCALE_DELTA;
|
handleScaling(key, scancode, action, mods);
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,22 +136,42 @@ static void
|
||||||
mouse_button_callback(GLFWwindow *window, int button, int action, int mods) {
|
mouse_button_callback(GLFWwindow *window, int button, int action, int mods) {
|
||||||
glfwGetCursorPos(window, &mouse_x, &mouse_y);
|
glfwGetCursorPos(window, &mouse_x, &mouse_y);
|
||||||
|
|
||||||
// Check which mouse button triggered the event, e.g. GLFW_MOUSE_BUTTON_LEFT,
|
// Check which mouse button triggered the event, e.g.
|
||||||
// etc. and what the button action was, e.g. GLFW_PRESS, GLFW_RELEASE, etc.
|
// GLFW_MOUSE_BUTTON_LEFT, etc. and what the button action was, e.g.
|
||||||
// (Note that ordinary trackpad click = mouse left button)
|
// GLFW_PRESS, GLFW_RELEASE, etc. (Note that ordinary trackpad click = mouse
|
||||||
// Also check if any modifier keys were active at the time of the button
|
// left button) Also check if any modifier keys were active at the time of
|
||||||
// press, e.g. GLFW_MOD_ALT, etc. Take the appropriate action, which could
|
// the button press, e.g. GLFW_MOD_ALT, etc. Take the appropriate action,
|
||||||
// (optionally) also include changing the cursor's appearance
|
// 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
|
// function that is called whenever a cursor motion event occurs
|
||||||
static void cursor_pos_callback(GLFWwindow *window, double xpos, double ypos) {
|
static void cursor_pos_callback(GLFWwindow *window, double xpos, double ypos) {
|
||||||
|
|
||||||
// determine the direction of the mouse or cursor motion
|
// determine the direction of the mouse or cursor motion
|
||||||
// update the current mouse or cursor location
|
// update the current mouse or cursor location
|
||||||
// (necessary to quantify the amount and direction of cursor motion)
|
// (necessary to quantify the amount and direction of cursor motion)
|
||||||
// take the appropriate action
|
// 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
|
glClearColor(1.0, 1.0, 1.0, 1.0); // white, opaque background
|
||||||
|
|
||||||
// Define some GLFW cursors (in case you want to dynamically change the
|
// 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
|
// cursor's appearance) If you want, you can add more cursors, or even
|
||||||
// your own cursor appearance
|
// define your own cursor appearance
|
||||||
arrow_cursor = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
|
arrow_cursor = glfwCreateStandardCursor(GLFW_ARROW_CURSOR);
|
||||||
hand_cursor = glfwCreateStandardCursor(GLFW_HAND_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
|
// fill/re-fill the window with the background color
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
rotation_matrix[0] = 1.0;
|
rotation_matrix[0] = cos(rotation_angle);
|
||||||
rotation_matrix[5] = 1.0;
|
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[10] = 1.0;
|
||||||
rotation_matrix[15] = 1.0;
|
rotation_matrix[15] = 1.0;
|
||||||
|
|
||||||
|
@ -300,27 +325,45 @@ int main(int argc, char **argv) {
|
||||||
scale_matrix[10] = 1.0;
|
scale_matrix[10] = 1.0;
|
||||||
scale_matrix[15] = 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
|
// 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
|
// be the identity matrix; you will need define M according to the user's
|
||||||
// actions.
|
// 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);
|
transposeMatrix(M);
|
||||||
|
|
||||||
|
free(result1);
|
||||||
|
free(result2);
|
||||||
|
|
||||||
// sanity check that your matrix contents are what you expect them to be
|
// sanity check that your matrix contents are what you expect them to be
|
||||||
if (DEBUG_ON) {
|
if (DEBUG_ON) {
|
||||||
|
/*
|
||||||
printf("--------------");
|
printf("--------------");
|
||||||
printf("scale_x = %f , scale_y = %f\n", scale_x, scale_y);
|
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("rotation_matrix", rotation_matrix);
|
||||||
printMatrix("scale_matrix", scale_matrix);
|
printMatrix("scale_matrix", scale_matrix);
|
||||||
printMatrix("M", M);
|
printMatrix("M", M);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// send the updated model transformation matrix to the GPU
|
// send the updated model transformation matrix to the GPU
|
||||||
glUniformMatrix4fv(m_location, 1, GL_FALSE, M);
|
glUniformMatrix4fv(m_location, 1, GL_FALSE, M);
|
||||||
|
|
||||||
// draw a triangle between the first vertex and each successive vertex pair
|
// draw a triangle between the first vertex and each successive vertex
|
||||||
// in the hard-coded model
|
// pair in the hard-coded model
|
||||||
glDrawArrays(GL_TRIANGLES, 0, NVERTICES);
|
glDrawArrays(GL_TRIANGLES, 0, NVERTICES);
|
||||||
|
|
||||||
// ensure that all OpenGL calls have executed before swapping buffers
|
// 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) {
|
void transposeMatrix(GLfloat *matrix) {
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
for (int j = i + 1; j < 4; ++j) {
|
for (int j = i + 1; j < 4; ++j) {
|
||||||
|
@ -369,9 +418,9 @@ void zeroInitGlfloats(GLfloat *arr, uint32_t len) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void slow4x4MatrixMultiplyAllRowOrder(
|
GLfloat *slow4x4MatrixMultiplyAllRowOrder(GLfloat *left, GLfloat *right) {
|
||||||
GLfloat *left, GLfloat *right, GLfloat *result
|
GLfloat *result = (GLfloat *)malloc(16 * sizeof(GLfloat));
|
||||||
) {
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
for (int j = 0; j < 4; ++j) {
|
for (int j = 0; j < 4; ++j) {
|
||||||
result[i * 4 + j] = 0;
|
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