opengl - Why doesn't this viewing/projection transform work? -
opengl - Why doesn't this viewing/projection transform work? -
i'm trying understand opengl's basic matrix transformation logic better. 2d code copied textbook , modified handle 3d; "sort of works", final result visually different when matrix multiplication myself vs. using glmultmatrix.
the lines marked 'xxx' allow flipping between 'my multiplication' , 'opengl multiplication'. tried obvious things (eg. row vs. column major, order of transforms, etc.)
if can illuminate me i'm doing wrong compared opengl, i'd appreciate it.
#include <iostream> #include <math.h> #include "glut.h" #include "vector3.h" typedef glfloat matrix4x4[4][4]; matrix4x4 matcomposite; void matrix4x4setidentity(matrix4x4 matident4x4){ glint row, col; for(row = 0; row<4; row++){ for(col = 0; col<4; col++){ matident4x4[row][col] = (row == col); } } } void matrix4x4premultiply(matrix4x4 m1, matrix4x4 m2){ glint row, col; matrix4x4 mattemp; for(row=0; row<4; row++){ for(col=0; col<4; col++){ mattemp[row][col] = m1[row][0] * m2[0][col] + m1[row][1] * m2[1][col] + m1[row][2] * m2[2][col] + m1[row][3] * m2[3][col]; } } for(row=0; row<4; row++){ for(col=0; col<4; col++){ m2[row][col] = mattemp[row][col]; } } } vector3 matrixmult(glfloat x, glfloat y, glfloat z){ glfloat tempx = matcomposite[0][0] * x + matcomposite[0][1] * y + matcomposite[0][2] * z + matcomposite[0][3]; glfloat tempy = matcomposite[1][0] * x + matcomposite[1][1] * y + matcomposite[1][2] * z + matcomposite[1][3]; glfloat tempz = matcomposite[2][0] * x + matcomposite[2][1] * y + matcomposite[2][2] * z + matcomposite[2][3]; glfloat tempw = matcomposite[3][0] + matcomposite[3][1] + matcomposite[3][2] + matcomposite[3][3]; // xxx homecoming vector3(tempx/tempw, tempy/tempw, tempz/tempw); // xxx homecoming vector3 (x, y, z); } void render() { // version of viewing/projection multiplication glfloat mvmx[4][4] = {{0.948683, 0.095346, -0.301511, 0.000000}, {0.000000, 0.953463, 0.301511, 0.000000}, {0.316228, -0.286039, 0.904534, 0.000000}, {0.000004, 0.000000, -132.664993, 1.000000}}; glfloat pmx[4][4] = {{1.500000, 0.000000, 0.000000, 0.000000}, {0.000000, 1.500000, 0.000000, 0.000000}, {0.000000, 0.000000, -1.015113, -1.000000}, {0.000000, 0.000000, -3.022670, 0.000000}}; matrix4x4setidentity(matcomposite); matrix4x4premultiply(pmx, matcomposite); matrix4x4premultiply(mvmx, matcomposite); // opengl's version of viewing/projection multiplication glmatrixmode(gl_modelview); glloadidentity(); glfloat mvm[] = {0.948683, 0.095346, -0.301511, 0.000000, 0.000000, 0.953463, 0.301511, 0.000000, 0.316228, -0.286039, 0.904534, 0.000000, 0.000004, 0.000000, -132.664993, 1.000000}; glfloat pm[] = {1.500000, 0.000000, 0.000000, 0.000000, 0.000000, 1.500000, 0.000000, 0.000000, 0.000000, 0.000000, -1.015113, -1.000000, 0.000000, 0.000000, -3.022670, 0.000000}; glmultmatrixf(pm); // xxx glmultmatrixf(mvm); // xxx // draw shape glcolor3f(1, 0, 0); glbegin(gl_polygon); vector3 vpt = matrixmult(0, 0, 0); glvertex3f(vpt.x, vpt.y, vpt.z); vpt = matrixmult(0, 50, 0); glvertex3f(vpt.x, vpt.y, vpt.z); vpt = matrixmult(50, 50, 0); glvertex3f(vpt.x, vpt.y, vpt.z); vpt = matrixmult(0, 50, 0); glvertex3f(vpt.x, vpt.y, vpt.z); glend(); } void display(void) { glclear(gl_color_buffer_bit | gl_depth_buffer_bit); render(); glutswapbuffers(); } void main(int argc, char **argv){ glutinit( &argc, argv ); glutinitdisplaymode (glut_double | glut_rgb | glut_depth) ; glutinitwindowsize(500, 500); glutinitwindowposition(100, 100); int windowhandle = glutcreatewindow("testing mvm , pm matrices"); glutsetwindow(windowhandle); glutdisplayfunc(display); glutmainloop(); }
from this
mattemp[row][col]
i deduce utilize row major storage order operations. however, opengl uses column major
order. have transpose matrices before can utilize them glloadmatrix
.
also, input matrices don't match matrix order:
glfloat pmx[4][4] = {{1.500000, 0.000000, 0.000000, 0.000000}, {0.000000, 1.500000, 0.000000, 0.000000}, {0.000000, 0.000000, -1.015113, -1.000000}, {0.000000, 0.000000, -3.022670, 0.000000}};
the projection matrix should have lastly row 0,0,-1,0
, way code interprets matrices transposed that, see (0, 0, -3.02267, 0)
lastly row. need transpose first, apply matrix operations, , transpose result opengl - or alter matrix operations match of opengl , don't transpose anything.
note modern gl, can utilize matrix oder like. code set uniform matrix has transpose
parameter tell gl wich of 2 orders use.
opengl matrix
Comments
Post a Comment