/// <summary> /// Matrix - Matrix multiplication /// </summary> /// <param name="u">A <see cref="SLMat3f"/> instance.</param> /// <param name="v">A <see cref="SLMat3f"/> instance.</param> /// <returns>A new <see cref="SLMat3f"/> instance multiplied by the matrix m</returns> /// <summary> public static SLMat3f operator*(SLMat3f m1, SLMat3f m2) { SLMat3f m = new SLMat3f(m1); m.Multiply(m2); return(m); }
/// <summary> /// Returns the transposed of the matrix /// </summary> public SLMat3f Transposed() { SLMat3f t = new SLMat3f(this); t.Transpose(); return(t); }
/// <summary> /// Post multiplies a scaling matrix defined by the vector s /// </summary> public void Scale(SLVec3f s) { SLMat3f S = new SLMat3f(); S.Scaling(s); Multiply(S); }
/// <summary> /// Post multiplies a scaling matrix defined by the vector [sx,sy,sz] /// </summary> public void Scale(float sx, float sy, float sz) { SLMat3f S = new SLMat3f(); S.Scaling(sx, sy, sz); Multiply(S); }
/// <summary> /// Post multiplies a rotation matrix defined by /// the angle degAng and the rotation axis /// </summary> public void Rotate(float degAng, SLVec3f axis) { SLMat3f R = new SLMat3f(); R.Rotation(degAng, axis); Multiply(R); }
/// <summary> /// Post multiplies a rotation matrix defined by /// the angle degAng and the rotation axis [axisx,axisy,axisz] /// </summary> public void Rotate(float degAng, float axisx, float axisy, float axisz) { SLMat3f R = new SLMat3f(); R.Rotation(degAng, axisx, axisy, axisz); Multiply(R); }
/// <summary> /// Returns the inverse transposed linear 3x3 submatrix /// that can be used as a normal matrix. /// </summary> public SLMat3f InverseTransposed() { SLMat3f it = new SLMat3f(this.Mat3()); it.Invert(); it.Transpose(); return(it); }
/// <summary> /// Returns a value indicating whether this instance is equal to /// the specified object. /// </summary> /// <param name="obj">An object to compare to this instance.</param> /// <returns>True if <paramref name="obj"/> is a <see cref="SLMat3f"/> and has the same values as this instance; otherwise, False.</returns> public override bool Equals(object obj) { if (obj is SLMat3f) { SLMat3f m = (SLMat3f)obj; return((this.m[0] == m.m[0]) && (this.m[1] == m.m[1]) && (this.m[2] == m.m[2]) && (this.m[3] == m.m[3]) && (this.m[4] == m.m[4]) && (this.m[5] == m.m[5]) && (this.m[6] == m.m[6]) && (this.m[7] == m.m[7])); } return(false); }
/// <summary> /// Post multiplies the matrix by matrix A /// </summary> public void Multiply(SLMat3f A) { // | 0 3 6 | | 0 3 6 | // M = | 1 4 7 | X | 1 4 7 | // | 2 5 8 | | 2 5 8 | Set(m[0] * A.m[0] + m[3] * A.m[1] + m[6] * A.m[2], m[0] * A.m[3] + m[3] * A.m[4] + m[6] * A.m[5], m[0] * A.m[6] + m[3] * A.m[7] + m[6] * A.m[8], m[1] * A.m[0] + m[4] * A.m[1] + m[7] * A.m[2], m[1] * A.m[3] + m[4] * A.m[4] + m[7] * A.m[5], m[1] * A.m[6] + m[4] * A.m[7] + m[7] * A.m[8], m[2] * A.m[0] + m[5] * A.m[1] + m[8] * A.m[2], m[2] * A.m[3] + m[5] * A.m[4] + m[8] * A.m[5], m[2] * A.m[6] + m[5] * A.m[7] + m[8] * A.m[8]); }
/// <summary> /// Returns the inverse of the matrix /// </summary> public SLMat3f Inverse() { // Compute determinant as early as possible using these cofactors. float d = Det(); if (Math.Abs(d) <= 0.0000000001f) { throw new DivideByZeroException("Matrix is singular. Inversion impossible."); } SLMat3f I = new SLMat3f(); I.m[0] = (m[4] * m[8] - m[7] * m[5]) / d; I.m[1] = (m[7] * m[2] - m[1] * m[8]) / d; I.m[2] = (m[1] * m[5] - m[4] * m[2]) / d; I.m[3] = (m[6] * m[5] - m[3] * m[8]) / d; I.m[4] = (m[0] * m[8] - m[6] * m[2]) / d; I.m[5] = (m[3] * m[2] - m[0] * m[5]) / d; I.m[6] = (m[3] * m[7] - m[6] * m[4]) / d; I.m[7] = (m[6] * m[1] - m[0] * m[7]) / d; I.m[8] = (m[0] * m[4] - m[3] * m[1]) / d; return(I); }
/// <summary> /// OnRenderFrame is called on every frame for rendering /// </summary> /// <param name="e">event arguments</param> protected override void OnRenderFrame(FrameEventArgs e) { base.OnRenderFrame(e); // Clear the color & depth buffer gl.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); // Start with identity every frame _viewMatrix.Identity(); // View transform: move the coordinate system away from the camera _viewMatrix.Translate(0, 0, _camZ); // View transform: rotate the coordinate system increasingly _viewMatrix.Rotate(_rotX + _deltaX, 1, 0, 0); _viewMatrix.Rotate(_rotY + _deltaY, 0, 1, 0); // Transform light position & direction into view space SLVec3f lightPosVS = _viewMatrix * _lightPos; // The light dir is not a position. We only take the rotation of the mv matrix. SLMat3f viewRot = _viewMatrix.Mat3(); SLVec3f lightDirVS = viewRot * _lightDir; // Rotate the model so that we see it _modelMatrix.Identity(); _modelMatrix.Rotate(90, -1, 0, 0); // Build the combined modelview-projection matrix SLMat4f mvp = new SLMat4f(_projectionMatrix); SLMat4f mv = new SLMat4f(_viewMatrix); mv.Multiply(_modelMatrix); mvp.Multiply(mv); // Build normal matrix SLMat3f nm = mv.InverseTransposed(); // Pass the matrix uniform variables unsafe { gl.UniformMatrix4(_mvMatrixLoc, 1, false, mv.m); gl.UniformMatrix3(_nMatrixLoc, 1, false, nm.m); gl.UniformMatrix4(_mvpMatrixLoc, 1, false, mvp.m); // Pass lighting uniforms variables gl.Uniform4(_globalAmbiLoc, 1, (float[])_globalAmbi); gl.Uniform3(_lightPosVSLoc, 1, (float[])lightPosVS); gl.Uniform3(_lightSpotDirVSLoc, 1, (float[])lightDirVS); gl.Uniform4(_lightAmbientLoc, 1, (float[])_lightAmbient); gl.Uniform4(_lightDiffuseLoc, 1, (float[])_lightDiffuse); gl.Uniform4(_lightSpecularLoc, 1, (float[])_lightSpecular); gl.Uniform4(_matAmbientLoc, 1, (float[])_matAmbient); gl.Uniform4(_matDiffuseLoc, 1, (float[])_matDiffuse); gl.Uniform4(_matSpecularLoc, 1, (float[])_matSpecular); gl.Uniform4(_matEmissiveLoc, 1, (float[])_matEmissive); } gl.Uniform1(_matShininessLoc, _matShininess); gl.Uniform1(_texture0Loc, 0); ////////////////////// // Draw with 2 VBOs // ////////////////////// // Enable all of the vertex attribute arrays gl.EnableVertexAttribArray(_pLoc); gl.EnableVertexAttribArray(_nLoc); gl.EnableVertexAttribArray(_tLoc); // Activate VBOs gl.BindBuffer(BufferTarget.ArrayBuffer, _vboV); gl.BindBuffer(BufferTarget.ElementArrayBuffer, _vboI); // Activate Texture gl.BindTexture(TextureTarget.Texture2D, _textureID); // For VBO only offset instead of data pointer int stride = 32; int offsetN = 3 * sizeof(float); int offsetT = 6 * sizeof(float); gl.VertexAttribPointer(_pLoc, 3, VertexAttribPointerType.Float, false, stride, 0); gl.VertexAttribPointer(_nLoc, 3, VertexAttribPointerType.Float, false, stride, offsetN); gl.VertexAttribPointer(_tLoc, 2, VertexAttribPointerType.Float, false, stride, offsetT); ///////////////////////////////////////////////////////////////////////////// // Draw cube model triangles by indexes gl.DrawElements(BeginMode.Triangles, _numI, DrawElementsType.UnsignedInt, 0); ///////////////////////////////////////////////////////////////////////////// // Deactivate buffers gl.BindBuffer(BufferTarget.ArrayBuffer, 0); gl.BindBuffer(BufferTarget.ElementArrayBuffer, 0); // Disable the vertex arrays gl.DisableVertexAttribArray(_pLoc); gl.DisableVertexAttribArray(_nLoc); gl.DisableVertexAttribArray(_tLoc); // Fast copy the back buffer to the front buffer. This is OS dependent. SwapBuffers(); // Check for errors glUtils.GetGLError("OnRenderFrame", true); }
/// <summary> /// Sets the matrix with the matrix A /// </summary> public void Set(SLMat3f A) { m[0] = A.m[0]; m[3] = A.m[3]; m[6] = A.m[6]; m[1] = A.m[1]; m[4] = A.m[4]; m[7] = A.m[7]; m[2] = A.m[2]; m[5] = A.m[5]; m[8] = A.m[8]; }
/// <summary> /// Copy constructor /// </summary> public SLMat3f(SLMat3f A) { Set(A); }
/// <summary> /// The forms paint routine where all drawing happens. /// </summary> private void frmHelloCube_Paint(object sender, PaintEventArgs e) { Graphics g = e.Graphics; #region graphicsSetup g.SmoothingMode = SmoothingMode.AntiAlias; e.Graphics.CompositingMode = System.Drawing.Drawing2D.CompositingMode.SourceCopy; e.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed; e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighSpeed; #endregion addFps(); zBuffer.Reset(); #region cameraMovement // start with identity every frame m_viewMatrix.Identity(); // view transform: move the coordinate system away from the camera m_viewMatrix.Translate(m_cam); // add new Rotations for camera m_viewMatrix.Rotate(m_rotAngleUp + (cursorPosition.y - preCursorPosition.y), new SLVec3f(1, 0, 0)); m_viewMatrix.Rotate(m_rotAngleSide + (cursorPosition.x - preCursorPosition.x), new SLVec3f(0, 1, 0)); #endregion using (BmpG bmpGraphics = new BmpG(ClientRectangle.Width, ClientRectangle.Height, zBuffer, light)) { #region graphicsMode bmpGraphics.phong = phongActive; bmpGraphics.wireframe = xWireframeActive; bmpGraphics.showZ = zShowActive; #endregion foreach (Mesh mesh in meshes) { // all transformed vertecies of the mesh are temporary saved in vertex2 List <SLVertex> vertex2 = new List <SLVertex>(); // Vertex Shader #region transformPipeline SLMat4f mv = new SLMat4f(m_viewMatrix); mv.Multiply(mesh.modelMatrix); SLMat3f nm = new SLMat3f(mv.InverseTransposed()); // build combined matrix out of viewport, projection & modelview matrix SLMat4f mvp = new SLMat4f(); mvp.Multiply(m_viewportMatrix); // screen mvp.Multiply(m_projectionMatrix); // projektion mvp.Multiply(mv); // kamera & view (cube) for (int n = 0; n < mesh.vertices.Length; n++) { vertex2.Add(new SLVertex(mvp.Multiply(mesh.vertices[n].position), nm.Multiply(mesh.vertices[n].normale), mesh.color, mv.Multiply(mesh.vertices[n].position))); } #endregion // Fragment Shader drawVertices(vertex2, mesh.indices, m_cam, bmpGraphics); } // Pixel output g.DrawImageUnscaled(bmpGraphics.Result(), 0, 0); } // Tell the system that the window should be repaint again this.Invalidate(); }