/* * matrix.c -- A simple example showing two ways to do matrix multiplication. * (a) OpenGL and (b) UA vision library (kjb). */ /* * In CS433/533 you can use any system like for basic matrix manipulation * including the two shown here, your own, or one of many standard ones * available on the web. The kjb library way is designed for simplified memeory * management and performance in certain circumstances. * * If you want to use the kjb library, add ~kobus/doc/man to your MANPATH, and * do a "man kjb". */ /* Include for kjb matrix stuff. Best to be first if used. Includes stuff like * stdio.h and stdlib.h (but NOT any OpenGL/GLUT stuff!). */ #include "m/m_incl.h" /* Must be first. */ #include #include #include #include /* -------------------------------------------------------------------------- */ static int demo_matrix_multiply_with_opengl(int argc, char* argv[]); static int demo_matrix_multiply_with_kjb(void); /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ int main(int argc, char *argv[]) { /* Sample code for OpenGL. */ if (demo_matrix_multiply_with_opengl(argc, argv) != 0) { return EXIT_FAILURE; } /* Sample code for kjb library. */ if (demo_matrix_multiply_with_kjb() == ERROR) { kjb_print_error(); return EXIT_FAILURE; } return EXIT_SUCCESS; } /* /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ */ /* // Example of getting OpenGL to multiply matrices for us. It seems we need to // have a window created. It is also important not to disturb the stack, so we // push, do our stuff, and then pop. */ static int demo_matrix_multiply_with_opengl(int argc, char* argv[]) { int win; int i,j; GLfloat matrix[16]; GLfloat matrix_2[16] = {2,0,1,0, /* This represents columns in sequence. */ 0,3,0,3, /* Thus the matrix is TRANSPOSE of that */ 0,0,4,0, /* suggested by the formatting. */ 1,0,0,5}; /* (Fortran legacy). */ /* Note that this is a permutation matrix that switches columns according to * the pattern in the matrix. */ GLfloat matrix_3[ 16 ] = {0,0,1,0, /* This reoresents columns in sequence. */ 0,0,0,1, /* Thus the matrix is TRANSPOSE of that */ 1,0,0,0, /* suggested by the formatting. */ 0,1,0,0}; /* (Fortran legacy). */ glutInit(&argc, argv); /* initialize GLUT system */ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); glutInitWindowSize(400,5000); /* width, height */ win = glutCreateWindow("Dummy"); /* create window */ /* From this point on the current window is win */ glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadMatrixf(matrix_2); glMultMatrixf(matrix_3); glGetFloatv(GL_MODELVIEW_MATRIX, matrix); printf("Result with OpenGL.\n\n"); for (i = 0; i < 4; i++) { for (j = 0; j <4; j++) { printf("%f ", matrix[j*4+i]); } printf("\n"); } printf("\n"); glPopMatrix(); return 0; } /* /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ */ static int demo_matrix_multiply_with_kjb() { Matrix* a_mp = NULL; /* MUST init to NULL. */ Matrix* b_mp = NULL; /* MUST init to NULL. */ Matrix* c_mp = NULL; /* MUST init to NULL. */ int result = NO_ERROR; if ( (get_zero_matrix(&a_mp, 4, 4) == ERROR) || (get_zero_matrix(&b_mp, 4, 4) == ERROR) ) { result = ERROR; } else { /* Fill in the same test values as before. */ a_mp->elements[ 0 ][ 0 ] = 2.0; a_mp->elements[ 2 ][ 0 ] = 1.0; a_mp->elements[ 1 ][ 1 ] = 3.0; a_mp->elements[ 3 ][ 1 ] = 3.0; a_mp->elements[ 2 ][ 2 ] = 4.0; a_mp->elements[ 0 ][ 3 ] = 1.0; a_mp->elements[ 3 ][ 3 ] = 5.0; /* * Note that this is a permutation matrix that switches columns * according to the pattern in the matrix. */ b_mp->elements[ 2 ][ 0 ] = 1.0; b_mp->elements[ 3 ][ 1 ] = 1.0; b_mp->elements[ 0 ][ 2 ] = 1.0; b_mp->elements[ 1 ][ 3 ] = 1.0; result = multiply_matrices(&c_mp, a_mp, b_mp); } /* * Writes don't fail often, but untested return values make me * uncomfortable. */ if (result != ERROR) { result = kjb_puts("\nResult using kjb library. The write routine writes integral doubles as integers.\n\n"); } if (result != ERROR) { result = write_matrix(c_mp, NULL); /* NULL means stdout. */ } if (result != ERROR) { result = kjb_puts("\n"); } free_matrix(a_mp); /* Free is OK, even if argument is NULL. */ free_matrix(b_mp); /* Free is OK, even if argument is NULL. */ free_matrix(c_mp); /* Free is OK, even if argument is NULL. */ return result; }