c++ - What's wrong with my MVP matrix builder? -
i'm using own classes , mathematical functions in c++, , making dire mistake cannot see is. representing 4x4 matrix linear array, here matrix generator functions:
float& mat4x4::getref(unsigned int row, unsigned int column) { return this->data[(4 * (column)) + row]; } void mat4x4::set(unsigned int row, unsigned int column, float value) { this->getref(row, column) = value; } mat4x4 mat4x4::getrotationalxmatrix(vec3 rot, bool oglform) { /* | 1 0 0 0 | m = | 0 cos(a) -sin(a) 0 | | 0 sin(a) cos(a) 0 | | 0 0 0 1 | standard mathematical format -- opengl wants transposed. */ mat4x4 res = mat4x4::identity(); res.set(1, 1, cos(rot.getx())); res.set(2, 1, (-sin(rot.getx()))); res.set(1, 2, sin(rot.getx())); res.set(2, 2, cos(rot.getx())); return oglform ? res.transposed() : res; } mat4x4 mat4x4::getrotationalymatrix(vec3 rot, bool oglform) { /* | cos(a) 0 sin(a) 0 | m = | 0 1 0 0 | | -sin(a) 0 cos(a) 0 | | 0 0 0 1 | standard mathematical format -- opengl wants transposed. */ mat4x4 res = mat4x4::identity(); res.set(0, 0, cos(rot.gety())); res.set(2, 0, sin(rot.gety())); res.set(0, 2, -sin(rot.gety())); res.set(2, 2, cos(rot.gety())); return oglform ? res.transposed() : res; } mat4x4 mat4x4::getrotationalzmatrix(vec3 rot, bool oglform) { /* | cos(a) -sin(a) 0 0 | m = | sin(a) cos(a) 0 0 | | 0 0 1 0 | | 0 0 0 1 | standard mathematical format -- opengl wants transposed. */ mat4x4 res = mat4x4::identity(); res.set(0, 0, cos(rot.getz())); res.set(1, 0, -sin(rot.getz())); res.set(0, 1, sin(rot.getz())); res.set(1, 1, cos(rot.getz())); return oglform ? res.transposed() : res; } mat4x4 mat4x4::getrotationalmatrix(vec3 pos, bool oglform) { return getrotationalxmatrix(pos, oglform) * getrotationalymatrix(pos, oglform) * getrotationalzmatrix(pos, oglform); } mat4x4 mat4x4::gettranslationmatrix(vec3 pos, bool oglform) { mat4x4 res = mat4x4::identity(); res.set(3, 0, pos.getx()); res.set(3, 1, pos.gety()); res.set(3, 2, pos.getz()); return oglform ? res.transposed() : res; } mat4x4 mat4x4::getscalematrix(vec3 scale, bool oglform) { mat4x4 res = mat4x4::identity(); res.set(0, 0, scale.getx()); res.set(1, 1, scale.gety()); res.set(2, 2, scale.getz()); return oglform ? res.transposed() : res; } mat4x4 mat4x4::lookatogl(vec3 eye, vec3 centre, vec3 up) { vec3 zaxis = (centre - eye).normalised(); vec3 xaxis = (up.cross(zaxis)).normalised(); vec3 yaxis = zaxis.cross(xaxis); float orient[16] = {0.0f}; orient[0] = xaxis.getx(); orient[1] = yaxis.getx(); orient[2] = zaxis.getx(); orient[3] = 0.0f; orient[4] = xaxis.gety(); orient[5] = yaxis.gety(); orient[6] = zaxis.gety(); orient[7] = 0.0f; orient[8] = xaxis.getz(); orient[9] = yaxis.getz(); orient[10] = zaxis.getz(); orient[11] = 0.0f; orient[12] = 0.0f; orient[13] = 0.0f; orient[14] = 0.0f; orient[15] = 1.0f; mat4x4 orientation(orient); float trans[16] = {0.0f}; trans[0] = 1.0f; trans[1] = 0.0f; trans[2] = 0.0f; trans[3] = 0.0f; trans[4] = 0.0f; trans[5] = 1.0f; trans[6] = 0.0f; trans[7] = 0.0f; trans[8] = 0.0f; trans[9] = 0.0f; trans[10] = 1.0f; trans[11] = 0.0f; trans[12] = -eye.getx(); trans[13] = -eye.gety(); trans[14] = -eye.getz(); trans[15] = 1.0f; mat4x4 translation(trans); return (translation * orientation); } and 5 important opengl matrices:
mat4x4 mat4x4::getmodelmatrix(vec3 pos, vec3 rot, vec3 scale, bool oglform) { return mat4x4::gettranslationmatrix(pos, oglform) * mat4x4::getrotationalmatrix(rot, oglform) * mat4x4::getscalematrix(scale, oglform); } mat4x4 mat4x4::getviewmatrix(vec3 eye, vec3 centre, vec3 up, bool oglform) { return mat4x4::lookatogl(eye, centre, up); } mat4x4 mat4x4::getprojectionmatrix(float fovrad, float aspectratio, float near, float far, bool oglformat) { float tanhalffov = tan(fovrad / 2); float data[16] = {0.0f}; mat4x4 res(data); res.set(0, 0, (1/(aspectratio * tanhalffov))); res.set(1, 1, (1/tanhalffov)); res.set(2, 3, -1); float twotwo = -(far + near) / (far - near); float threetwo = -(2 * far * near) / (far - near); res.set(2, 2, twotwo); res.set(3, 2, threetwo); return res; } mat4x4 mat4x4::getmvmatrixogl(vec3 pos, vec3 rot, vec3 scale, vec3 eye, vec3 centre, vec3 up) { mat4x4 m = mat4x4::getmodelmatrix(pos, rot, scale, true); mat4x4 v = mat4x4::getviewmatrix(eye, centre, up, true); return v * m; } mat4x4 mat4x4::getmvpmatrixogl(vec3 pos, vec3 rot, vec3 scale, vec3 eye, vec3 centre, vec3 up, float fovrad, float aspectratio, float near, float far) { mat4x4 m = mat4x4::getmodelmatrix(pos, rot, scale, true); mat4x4 v = mat4x4::getviewmatrix(eye, centre, up, true); mat4x4 p = mat4x4::getprojectionmatrix(fovrad, aspectratio, near, far, true); return p * v * m; } i see several observational issues resulting matrices. when camera close model, appears normal, rotating on y-axis normal. however, camera gets further away model, model rotates around y axis in circular fashion increasing radius. also, model appears appear flatter toward apex of rotation, due nature of view matrix?
this observation using mv matrix , not projection matrix @ all. when use mvp matrix, things alot worse. model appears flat, vertices stretching long far-clip, 1000.0f. first thought had few transposing issues, know fact transposing function worked correctly. mat4x4 class natively row-major, mathematics suggests normal format. oglformat booleans transpose column major. did wrong?
Comments
Post a Comment