Finish translation and rotation

This commit is contained in:
Michael Zhang 2023-04-08 23:01:48 -05:00
parent ce9d7942cf
commit 0b637f7ac3
Signed by: michael
GPG key ID: BDA47A31A3C8EE6B

View file

@ -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;
} }