Matrix4 Inverse() const { double Result[4][4]; float const* src; /* array of transpose source matrix */ double det, invDet; /* determinant */ // set src src = Transposed().Pointer(); // computing double subfactor01 = src[10] * src[15] - src[11] * src[14]; double subfactor23 = src[9] * src[15] - src[11] * src[13]; double subfactor45 = src[9] * src[14] - src[10] * src[13]; double subfactor67 = src[8] * src[15] - src[11] * src[12]; double subfactor89 = src[8] * src[14] - src[10] * src[12]; double subfactor1011 = src[8] * src[13] - src[9] * src[12]; Result[0][0] = subfactor01 * src[5] - subfactor23 * src[6] + subfactor45 * src[7]; Result[0][1] = -subfactor01 * src[4] + subfactor67 * src[6] - subfactor89 * src[7]; Result[0][2] = subfactor23 * src[4] - subfactor67 * src[5] + subfactor1011 * src[7]; Result[0][3] = -subfactor45 * src[4] + subfactor89 * src[5] - subfactor1011 * src[6]; Result[1][0] = -subfactor01 * src[1] + subfactor23 * src[2] - subfactor45 * src[3]; Result[1][1] = subfactor01 * src[0] - subfactor67 * src[2] + subfactor89 * src[3]; Result[1][2] = -subfactor23 * src[0] + subfactor67 * src[1] - subfactor1011 * src[3]; Result[1][3] = subfactor45 * src[0] - subfactor89 * src[1] + subfactor1011 * src[2]; // computing subfactor01 = src[2] * src[7] - src[3] * src[6]; subfactor23 = src[1] * src[7] - src[3] * src[5]; subfactor45 = src[1] * src[6] - src[2] * src[5]; subfactor67 = src[0] * src[7] - src[3] * src[4]; subfactor89 = src[0] * src[6] - src[2] * src[4]; subfactor1011 = src[0] * src[5] - src[1] * src[4]; Result[2][0] = subfactor01 * src[13] - subfactor23 * src[14] + subfactor45 * src[15]; Result[2][1] = -subfactor01 * src[12] + subfactor67 * src[14] - subfactor89 * src[15]; Result[2][2] = subfactor23 * src[12] - subfactor67 * src[13] + subfactor1011 * src[15]; Result[2][3] = -subfactor45 * src[12] + subfactor89 * src[13] - subfactor1011 * src[14]; Result[3][0] = - subfactor01 * src[9] + subfactor23 * src[10] - subfactor45 * src[11]; Result[3][1] = subfactor01 * src[8] - subfactor67 * src[10] + subfactor89 * src[11]; Result[3][2] = - subfactor23 * src[8] + subfactor67 * src[9] - subfactor1011 * src[11]; Result[3][3] = subfactor45 * src[8] - subfactor89 * src[9] + subfactor1011 * src[10]; // to calculate final inverse matrix det = Result[0][0] * src[0] + Result[0][1] * src[1] + Result[0][2] * src[2] + Result[0][3] * src[3]; invDet = 1.0f / det; Matrix4 inverse; float* fmat = (float*) inverse.Pointer(); for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { fmat[i * 4 + j] = float(Result[i][j] * invDet); } } return inverse; }
CubeExample(void) : cube_instr(make_cube.Instructions()) , cube_indices(make_cube.Indices()) , projection_matrix(prog) , camera_matrix(prog) { // Set the vertex shader source and compile it VertexShader vs; vs.Source( "#version 150\n" "uniform mat4 ProjectionMatrix, CameraMatrix;" "layout (std140) uniform ModelBlock {" " mat4 ModelMatrices[36];" "};" "in vec4 Position;" "out vec3 vertColor;" "void main(void)" "{" " mat4 ModelMatrix = ModelMatrices[gl_InstanceID];" " gl_Position = " " ProjectionMatrix *" " CameraMatrix *" " ModelMatrix *" " Position;" " vertColor = abs(normalize((ModelMatrix*Position).yxz));" "}" ).Compile(); // set the fragment shader source and compile it FragmentShader fs; fs.Source( "#version 150\n" "in vec3 vertColor;" "out vec4 fragColor;" "void main(void)" "{" " fragColor = vec4(vertColor, 1.0);" "}" ).Compile(); // attach the shaders to the program prog.AttachShader(vs); prog.AttachShader(fs); // link and use it prog.Link().Use(); projection_matrix.BindTo("ProjectionMatrix"); camera_matrix.BindTo("CameraMatrix"); // bind the VAO for the cube cube.Bind(); // bind the VBO for the cube vertices verts.Bind(Buffer::Target::Array); { std::vector<GLfloat> data; GLuint n_per_vertex = make_cube.Positions(data); // upload the data Buffer::Data(Buffer::Target::Array, data); // setup the vertex attribs array for the vertices (prog|"Position").Setup<GLfloat>(n_per_vertex).Enable(); } // make the matrices { // 36 x 4x4 matrices std::vector<GLfloat> matrix_data(36*16); auto p = matrix_data.begin(), e = matrix_data.end(); Angle<GLfloat> angle, astep = Angle<GLfloat>::Degrees(10); while(p != e) { GLfloat cx = Cos(angle); GLfloat sx = Sin(angle); auto matrix = Transposed(Mat4f( Vec4f( cx, 0.0, -sx, 0.0), Vec4f(0.0, 1.0, 0.0, 0.0), Vec4f( sx, 0.0, cx, 0.0), Vec4f(0.0, 0.0, 0.0, 1.0) ) * Mat4f( Vec4f(1.0, 0.0, 0.0,12.0), Vec4f(0.0, 1.0, 0.0, 0.0), Vec4f(0.0, 0.0, 1.0, 0.0), Vec4f(0.0, 0.0, 0.0, 1.0) )); p = std::copy( Data(matrix), Data(matrix)+Size(matrix), p ); angle += astep; } UniformBlock model_block(prog, "ModelBlock"); model_block.Binding(0); block_buf.Bind(Buffer::Target::Uniform); Buffer::Data( Buffer::Target::Uniform, matrix_data, BufferUsage::DynamicDraw ); block_buf.BindBaseUniform(0); } // gl.ClearColor(0.9f, 0.9f, 0.9f, 0.0f); gl.ClearDepth(1.0f); gl.Enable(Capability::DepthTest); }
/** * @glsymbols * @glfunref{LoadMatrix} */ static void LoadMatrix(const Mat4d& matrix) { OGLPLUS_GLFUNC(LoadMatrixd)(Data(Transposed(matrix))); OGLPLUS_VERIFY(OGLPLUS_ERROR_INFO(LoadMatrixd)); }
void Matrix::Transpose() { *this = Transposed(); }