Example #1
0
        /// <summary>
        /// 把连续16个float值按照列优先的顺序转换为mat4
        /// </summary>
        /// <param name="values"></param>
        /// <param name="startIndex"></param>
        /// <returns></returns>
        public static mat4 ToMat4(this float[] values, int startIndex = 0)
        {
            mat4 result;
            result = new mat4(
                values.ToVec4(startIndex + 0), values.ToVec4(startIndex + 4), values.ToVec4(startIndex + 8), values.ToVec4(startIndex + 12));

            return result;
        }
Example #2
0
        void element_BeforeRendering(object sender, Objects.RenderEventArgs e)
        {
            rotation += 3.0f;
            modelMatrix = glm.rotate(rotation, new vec3(0, 1, 0));
            viewMatrix = this.camera.GetViewMat4();
            projectionMatrix = this.camera.GetProjectionMat4();

            mat4 mvp = projectionMatrix * viewMatrix * modelMatrix;

            IMVP element = sender as IMVP;

            element.SetShaderProgram(mvp);
        }
Example #3
0
        void glCanvas1_OpenGLDraw(object sender, PaintEventArgs e)
        {
            rotation += 3.0f;
            modelMatrix = glm.rotate(rotation, new vec3(0, 1, 0));
            viewMatrix = this.camera.GetViewMat4();
            projectionMatrix = this.camera.GetProjectionMat4();
            mat4 mvp = projectionMatrix * viewMatrix * modelMatrix;

            element.mvp = mvp;

            //GL.ClearColor(0x87 / 255.0f, 0xce / 255.0f, 0xeb / 255.0f, 0xff / 255.0f);
            GL.Clear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

            var arg = new RenderEventArgs(RenderModes.Render, this.camera);
            element.Render(arg);
        }
Example #4
0
        private void glCanvas1_OpenGLDraw(object sender, PaintEventArgs e)
        {
            rotation += 3.0f;
            mat4 modelMatrix = glm.rotate(rotation, new vec3(0, 1, 0));
            const float distance = 0.7f;
            viewMatrix = glm.lookAt(new vec3(-distance, distance, -distance), new vec3(0, 0, 0), new vec3(0, -1, 0));
            int[] viewport = new int[4];
            GL.GetInteger(GetTarget.Viewport, viewport);
            projectionMatrix = glm.perspective(60.0f, (float)viewport[2] / (float)viewport[3], 0.01f, 100.0f);
            mat4 mvp = projectionMatrix * viewMatrix * modelMatrix;

            pyramidElement.mvp = mvp;

            GL.Clear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);

            var arg = new RenderEventArgs(RenderModes.Render, null);
            pyramidElement.Render(arg);
        }
Example #5
0
        /// <summary>
        /// Creates a matrix for a symmetric perspective-view frustum with far plane at infinite.
        /// </summary>
        /// <param name="fovy">The fovy.</param>
        /// <param name="aspect">The aspect.</param>
        /// <param name="zNear">The z near.</param>
        /// <returns></returns>
        public static mat4 infinitePerspective(float fovy, float aspect, float zNear)
        {

            float range = tan(fovy / (2f)) * zNear;

            float left = -range * aspect;
            float right = range * aspect;
            float bottom = -range;
            float top = range;

            var result = new mat4(0);
            result[0, 0] = ((2f) * zNear) / (right - left);
            result[1, 1] = ((2f) * zNear) / (top - bottom);
            result[2, 2] = -(1f);
            result[2, 3] = -(1f);
            result[3, 2] = -(2f) * zNear;
            return result;
        }
Example #6
0
        void pyramidElement_BeforeRendering(object sender, Objects.RenderEventArgs e)
        {
            rotation += 3.0f;
            mat4 modelMatrix = glm.rotate(rotation, new vec3(0, 1, 0));

            const float distance = 0.7f;
            viewMatrix = glm.lookAt(new vec3(-distance, distance, -distance), new vec3(0, 0, 0), new vec3(0, -1, 0));

            int[] viewport = new int[4];
            GL.GetInteger(GetTarget.Viewport, viewport);
            projectionMatrix = glm.perspective(60.0f, (float)viewport[2] / (float)viewport[3], 0.01f, 100.0f);

            mat4 mvp = projectionMatrix * viewMatrix * modelMatrix;

            IMVP element = sender as IMVP;

            element.SetShaderProgram(mvp);
        }
Example #7
0
        /// <summary>
        /// Build a look at view matrix.
        /// </summary>
        /// <param name="eye">The eye.</param>
        /// <param name="center">The center.</param>
        /// <param name="up">Up.</param>
        /// <returns></returns>
        public static mat4 lookAt(vec3 eye, vec3 center, vec3 up)
        {
            vec3 f = (center - eye); f.Normalize();
            vec3 s = f.cross(up); s.Normalize();
            vec3 u = s.cross(f);

            mat4 Result = new mat4(1);
            Result[0, 0] = s.x;
            Result[1, 0] = s.y;
            Result[2, 0] = s.z;
            Result[0, 1] = u.x;
            Result[1, 1] = u.y;
            Result[2, 1] = u.z;
            Result[0, 2] = -f.x;
            Result[1, 2] = -f.y;
            Result[2, 2] = -f.z;
            Result[3, 0] = -s.dot(eye);// dot(s, eye);
            Result[3, 1] = -u.dot(eye);// dot(u, eye);
            Result[3, 2] = f.dot(eye);// dot(f, eye);
            return Result;
        }
Example #8
0
        /// <summary>
        /// Builds a perspective projection matrix based on a field of view.
        /// </summary>
        /// <param name="fov">The fov (in radians).</param>
        /// <param name="width">The width.</param>
        /// <param name="height">The height.</param>
        /// <param name="zNear">The z near.</param>
        /// <param name="zFar">The z far.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentOutOfRangeException"></exception>
        public static mat4 perspectiveFov(float fov, float width, float height, float zNear, float zFar)
        {
            if (width <= 0 || height <= 0 || fov <= 0)
            {
                throw new ArgumentOutOfRangeException();
            }

            var rad = fov;

            var h = glm.cos((0.5f) * rad) / glm.sin((0.5f) * rad);
            var w = h * height / width;

            var result = new mat4(0);

            result[0, 0] = w;
            result[1, 1] = h;
            result[2, 2] = -(zFar + zNear) / (zFar - zNear);
            result[2, 3] = -(1f);
            result[3, 2] = -((2f) * zFar * zNear) / (zFar - zNear);
            return(result);
        }
Example #9
0
        /// <summary>
        /// Define a picking region.
        /// </summary>
        /// <param name="center">The center.</param>
        /// <param name="delta">The delta.</param>
        /// <param name="viewport">The viewport.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentOutOfRangeException"></exception>
        public static mat4 pickMatrix(vec2 center, vec2 delta, vec4 viewport)
        {
            if (delta.x <= 0 || delta.y <= 0)
            {
                throw new ArgumentOutOfRangeException();
            }
            var Result = new mat4(1.0f);

            if (!(delta.x > (0f) && delta.y > (0f)))
            {
                return(Result); // Error
            }
            vec3 Temp = new vec3(
                ((viewport[2]) - (2f) * (center.x - (viewport[0]))) / delta.x,
                ((viewport[3]) - (2f) * (center.y - (viewport[1]))) / delta.y,
                (0f));

            // Translate and scale the picked region to the entire window
            Result = translate(Result, Temp);
            return(scale(Result, new vec3((viewport[2]) / delta.x, (viewport[3]) / delta.y, (1))));
        }
Example #10
0
        /// <summary>
        /// Build a look at view matrix.
        /// </summary>
        /// <param name="eye">The eye.</param>
        /// <param name="center">The center.</param>
        /// <param name="up">Up.</param>
        /// <returns></returns>
        public static mat4 lookAt(vec3 eye, vec3 center, vec3 up)
        {
            vec3 forward    = (center - eye).normalize();
            vec3 right      = forward.cross(up).normalize();
            vec3 standardUp = right.cross(forward);

            mat4 Result = new mat4(1);

            Result[0, 0] = right.x;
            Result[1, 0] = right.y;
            Result[2, 0] = right.z;
            Result[0, 1] = standardUp.x;
            Result[1, 1] = standardUp.y;
            Result[2, 1] = standardUp.z;
            Result[0, 2] = -forward.x;
            Result[1, 2] = -forward.y;
            Result[2, 2] = -forward.z;
            Result[3, 0] = -right.dot(eye);      // dot(s, eye);
            Result[3, 1] = -standardUp.dot(eye); // dot(u, eye);
            Result[3, 2] = forward.dot(eye);     // dot(f, eye);
            return(Result);
        }
Example #11
0
        /// <summary>
        /// Build a look at view matrix.
        /// </summary>
        /// <param name="eye">The eye.</param>
        /// <param name="center">The center.</param>
        /// <param name="up">Up.</param>
        /// <returns></returns>
        public static mat4 lookAt(vec3 eye, vec3 center, vec3 up)
        {
            vec3 f = (center - eye); f.Normalize();
            vec3 s = f.cross(up); s.Normalize();
            vec3 u = s.cross(f);

            mat4 Result = new mat4(1);

            Result[0, 0] = s.x;
            Result[1, 0] = s.y;
            Result[2, 0] = s.z;
            Result[0, 1] = u.x;
            Result[1, 1] = u.y;
            Result[2, 1] = u.z;
            Result[0, 2] = -f.x;
            Result[1, 2] = -f.y;
            Result[2, 2] = -f.z;
            Result[3, 0] = -s.dot(eye); // dot(s, eye);
            Result[3, 1] = -u.dot(eye); // dot(u, eye);
            Result[3, 2] = f.dot(eye);  // dot(f, eye);
            return(Result);
        }
Example #12
0
        /// <summary>
        /// Map the specified object coordinates (obj.x, obj.y, obj.z) into window coordinates.
        /// </summary>
        /// <param name="obj">The object.</param>
        /// <param name="model">The model.</param>
        /// <param name="proj">The proj.</param>
        /// <param name="viewport">The viewport.</param>
        /// <returns></returns>
        public static vec3 project(vec3 obj, mat4 model, mat4 proj, vec4 viewport)
        {
            vec4 tmp = new vec4(obj, (1f));
            tmp = model * tmp;
            tmp = proj * tmp;

            tmp /= tmp.w;
            tmp = tmp * 0.5f + new vec4(0.5f, 0.5f, 0.5f, 0.5f);
            tmp[0] = tmp[0] * viewport[2] + viewport[0];
            tmp[1] = tmp[1] * viewport[3] + viewport[1];

            return new vec3(tmp.x, tmp.y, tmp.z);
        }
 void IMVP.SetShaderProgram(mat4 mvp)
 {
     IMVP element = this.element as IMVP;
     element.SetShaderProgram(mvp);
 }
Example #14
0
        /// <summary>
        /// Multiplies the <paramref name="lhs"/> matrix by the <paramref name="rhs"/> matrix.
        /// </summary>
        /// <param name="lhs">The LHS matrix.</param>
        /// <param name="rhs">The RHS matrix.</param>
        /// <returns>The product of <paramref name="lhs"/> and <paramref name="rhs"/>.</returns>
        public static mat4 operator *(mat4 lhs, mat4 rhs)
        {
            mat4 result = new mat4(
                new vec4(
                    lhs[0][0] * rhs[0][0] + lhs[1][0] * rhs[0][1] + lhs[2][0] * rhs[0][2] + lhs[3][0] * rhs[0][3],
                    lhs[0][1] * rhs[0][0] + lhs[1][1] * rhs[0][1] + lhs[2][1] * rhs[0][2] + lhs[3][1] * rhs[0][3],
                    lhs[0][2] * rhs[0][0] + lhs[1][2] * rhs[0][1] + lhs[2][2] * rhs[0][2] + lhs[3][2] * rhs[0][3],
                    lhs[0][3] * rhs[0][0] + lhs[1][3] * rhs[0][1] + lhs[2][3] * rhs[0][2] + lhs[3][3] * rhs[0][3]
                    ),
                new vec4(
                    lhs[0][0] * rhs[1][0] + lhs[1][0] * rhs[1][1] + lhs[2][0] * rhs[1][2] + lhs[3][0] * rhs[1][3],
                    lhs[0][1] * rhs[1][0] + lhs[1][1] * rhs[1][1] + lhs[2][1] * rhs[1][2] + lhs[3][1] * rhs[1][3],
                    lhs[0][2] * rhs[1][0] + lhs[1][2] * rhs[1][1] + lhs[2][2] * rhs[1][2] + lhs[3][2] * rhs[1][3],
                    lhs[0][3] * rhs[1][0] + lhs[1][3] * rhs[1][1] + lhs[2][3] * rhs[1][2] + lhs[3][3] * rhs[1][3]
                    ),
                new vec4(
                    lhs[0][0] * rhs[2][0] + lhs[1][0] * rhs[2][1] + lhs[2][0] * rhs[2][2] + lhs[3][0] * rhs[2][3],
                    lhs[0][1] * rhs[2][0] + lhs[1][1] * rhs[2][1] + lhs[2][1] * rhs[2][2] + lhs[3][1] * rhs[2][3],
                    lhs[0][2] * rhs[2][0] + lhs[1][2] * rhs[2][1] + lhs[2][2] * rhs[2][2] + lhs[3][2] * rhs[2][3],
                    lhs[0][3] * rhs[2][0] + lhs[1][3] * rhs[2][1] + lhs[2][3] * rhs[2][2] + lhs[3][3] * rhs[2][3]
                    ),
                new vec4(
                    lhs[0][0] * rhs[3][0] + lhs[1][0] * rhs[3][1] + lhs[2][0] * rhs[3][2] + lhs[3][0] * rhs[3][3],
                    lhs[0][1] * rhs[3][0] + lhs[1][1] * rhs[3][1] + lhs[2][1] * rhs[3][2] + lhs[3][1] * rhs[3][3],
                    lhs[0][2] * rhs[3][0] + lhs[1][2] * rhs[3][1] + lhs[2][2] * rhs[3][2] + lhs[3][2] * rhs[3][3],
                    lhs[0][3] * rhs[3][0] + lhs[1][3] * rhs[3][1] + lhs[2][3] * rhs[3][2] + lhs[3][3] * rhs[3][3]
                    )
                    );

            return result;
        }
Example #15
0
        /// <summary>
        /// Define a picking region.
        /// </summary>
        /// <param name="center">The center.</param>
        /// <param name="delta">The delta.</param>
        /// <param name="viewport">The viewport.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentOutOfRangeException"></exception>
        public static mat4 pickMatrix(vec2 center, vec2 delta, vec4 viewport)
        {
            if (delta.x <= 0 || delta.y <= 0)
                throw new ArgumentOutOfRangeException();
            var Result = new mat4(1.0f);

            if (!(delta.x > (0f) && delta.y > (0f)))
                return Result; // Error

            vec3 Temp = new vec3(
                ((viewport[2]) - (2f) * (center.x - (viewport[0]))) / delta.x,
                ((viewport[3]) - (2f) * (center.y - (viewport[1]))) / delta.y,
                (0f));

            // Translate and scale the picked region to the entire window
            Result = translate(Result, Temp);
            return scale(Result, new vec3((viewport[2]) / delta.x, (viewport[3]) / delta.y, (1)));
        }
        void IMVP.SetShaderProgram(mat4 mvp)
        {
            ShaderProgram shaderProgram = this.currentShaderProgram;

            shaderProgram.Bind();
            if (shaderProgram == this.pickingShaderProgram)
            {
                shaderProgram.SetUniform("pickingBaseID", ((IColorCodedPicking)this).PickingBaseID);
                shaderProgram.SetUniformMatrix4(strMVP, mvp.to_array());
            }
            else
            {
                shaderProgram.SetUniformMatrix4(strMVP, mvp.to_array());
            }
        }
Example #17
0
 /// <summary>
 /// Applies a translation transformation to matrix <paramref name="m"/> by vector <paramref name="v"/>.
 /// </summary>
 /// <param name="m">The matrix to transform.</param>
 /// <param name="v">The vector to translate by.</param>
 /// <returns><paramref name="m"/> translated by <paramref name="v"/>.</returns>
 public static mat4 translate(mat4 m, vec3 v)
 {
     mat4 result = m;
     result[3] = m[0] * v[0] + m[1] * v[1] + m[2] * v[2] + m[3];
     return result;
 }
Example #18
0
        /// <summary>
        /// Builds a rotation 4 * 4 matrix created from an axis vector and an angle.
        /// </summary>
        /// <param name="m">The m.</param>
        /// <param name="angle">The angle.</param>
        /// <param name="v">The v.</param>
        /// <returns></returns>
        public static mat4 rotate(mat4 m, float angle, vec3 v)
        {
            float c = cos(angle);
            float s = sin(angle);

            vec3 axis = v; axis.Normalize();// normalize(v);
            vec3 temp = (1.0f - c) * axis;

            mat4 rotate = mat4.identity();
            rotate[0, 0] = c + temp[0] * axis[0];
            rotate[0, 1] = 0 + temp[0] * axis[1] + s * axis[2];
            rotate[0, 2] = 0 + temp[0] * axis[2] - s * axis[1];

            rotate[1, 0] = 0 + temp[1] * axis[0] - s * axis[2];
            rotate[1, 1] = c + temp[1] * axis[1];
            rotate[1, 2] = 0 + temp[1] * axis[2] + s * axis[0];

            rotate[2, 0] = 0 + temp[2] * axis[0] + s * axis[1];
            rotate[2, 1] = 0 + temp[2] * axis[1] - s * axis[0];
            rotate[2, 2] = c + temp[2] * axis[2];

            mat4 result = mat4.identity();
            result[0] = m[0] * rotate[0][0] + m[1] * rotate[0][1] + m[2] * rotate[0][2];
            result[1] = m[0] * rotate[1][0] + m[1] * rotate[1][1] + m[2] * rotate[1][2];
            result[2] = m[0] * rotate[2][0] + m[1] * rotate[2][1] + m[2] * rotate[2][2];
            result[3] = m[3];
            return result;
        }
Example #19
0
        /// <summary>
        /// Map the specified window coordinates (win.x, win.y, win.z) into object coordinates.
        /// </summary>
        /// <param name="win">The win.</param>
        /// <param name="model">The model.</param>
        /// <param name="proj">The proj.</param>
        /// <param name="viewport">The viewport.</param>
        /// <returns></returns>
        public static vec3 unProject(vec3 win, mat4 model, mat4 proj, vec4 viewport)
        {
            mat4 Inverse = glm.inverse(proj * model);

            vec4 tmp = new vec4(win, (1f));
            tmp.x = (tmp.x - (viewport[0])) / (viewport[2]);
            tmp.y = (tmp.y - (viewport[1])) / (viewport[3]);
            tmp = tmp * (2f) - new vec4(1, 1, 1, 1);

            vec4 obj = Inverse * tmp;
            obj /= obj.w;

            return new vec3(obj);
        }
Example #20
0
        /// <summary>
        /// Creates a matrix for a symmetric perspective-view frustum with far plane 
        /// at infinite for graphics hardware that doesn't support depth clamping.
        /// </summary>
        /// <param name="fovy">The fovy.</param>
        /// <param name="aspect">The aspect.</param>
        /// <param name="zNear">The z near.</param>
        /// <returns></returns>
        public static mat4 tweakedInfinitePerspective(float fovy, float aspect, float zNear)
        {
            float range = tan(fovy / (2)) * zNear;
            float left = -range * aspect;
            float right = range * aspect;
            float bottom = -range;
            float top = range;

            mat4 Result = new mat4((0f));
            Result[0, 0] = ((2) * zNear) / (right - left);
            Result[1, 1] = ((2) * zNear) / (top - bottom);
            Result[2, 2] = (0.0001f) - (1f);
            Result[2, 3] = (-1);
            Result[3, 2] = -((0.0001f) - (2)) * zNear;
            return Result;
        }
        public static void TypicalScene()
        {
            const int count = 1000000;

            long startTick = 0;
            long interval, interval2;

            // 测试float类型
            {
                var floatArray = new UnmanagedArray<float>(count);
                startTick = DateTime.Now.Ticks;
                for (int i = 0; i < count; i++)
                {
                    floatArray[i] = i;
                }
                for (int i = 0; i < count; i++)
                {
                    var item = floatArray[i];
                    if (item != i)
                    { throw new Exception(); }
                }
                interval = DateTime.Now.Ticks - startTick;

                unsafe
                {
                    startTick = DateTime.Now.Ticks;
                    float* header = (float*)floatArray.FirstElement();
                    float* last = (float*)floatArray.LastElement();
                    float* tailAddress = (float*)floatArray.TailAddress();
                    int value = 0;
                    for (float* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++)
                    {
                        *ptr = value++;
                    }
                    int i = 0;
                    for (float* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++, i++)
                    {
                        var item = *ptr;
                        if (item != i)
                        { throw new Exception(); }
                    }
                    interval2 = DateTime.Now.Ticks - startTick;
                }
                Console.WriteLine("Ticks: safe: {0} vs unsafe: {1}", interval, interval2);
            }

            // 测试decimal类型
            {
                var decimalArray = new UnmanagedArray<decimal>(count);
                startTick = DateTime.Now.Ticks;
                for (int i = 0; i < count; i++)
                {
                    decimalArray[i] = i;
                }
                for (int i = 0; i < count; i++)
                {
                    var item = decimalArray[i];
                    if (item != i)
                    { throw new Exception(); }
                }
                interval = DateTime.Now.Ticks - startTick;

                unsafe
                {
                    startTick = DateTime.Now.Ticks;
                    decimal* header = (decimal*)decimalArray.FirstElement();
                    decimal* last = (decimal*)decimalArray.LastElement();
                    decimal* tailAddress = (decimal*)decimalArray.TailAddress();
                    int value = 0;
                    for (decimal* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++)
                    {
                        *ptr = value++;
                    }
                    int i = 0;
                    for (decimal* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++, i++)
                    {
                        var item = *ptr;
                        if (item != i)
                        { throw new Exception(); }
                    }
                    interval2 = DateTime.Now.Ticks - startTick;
                }
                Console.WriteLine("Ticks: safe: {0} vs unsafe: {1}", interval, interval2);
            }

            // 测试int类型
            {
                var intArray = new UnmanagedArray<int>(count);
                startTick = DateTime.Now.Ticks;
                for (int i = 0; i < count; i++)
                {
                    intArray[i] = i;
                }
                for (int i = 0; i < count; i++)
                {
                    var item = intArray[i];
                    if (item != i)
                    { throw new Exception(); }
                }
                interval = DateTime.Now.Ticks - startTick;

                unsafe
                {
                    startTick = DateTime.Now.Ticks;
                    int* header = (int*)intArray.FirstElement();
                    int* last = (int*)intArray.LastElement();
                    int* tailAddress = (int*)intArray.TailAddress();
                    int value = 0;
                    for (int* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++)
                    {
                        *ptr = value++;
                    }
                    int i = 0;
                    for (int* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++, i++)
                    {
                        var item = *ptr;
                        if (item != i)
                        { throw new Exception(); }
                    }
                    interval2 = DateTime.Now.Ticks - startTick;
                }
                Console.WriteLine("Ticks: safe: {0} vs unsafe: {1}", interval, interval2);
            }

            // 测试bool类型
            {
                var boolArray = new UnmanagedArray<bool>(count);
                startTick = DateTime.Now.Ticks;
                for (int i = 0; i < count; i++)
                {
                    boolArray[i] = i % 2 == 0;
                }
                for (int i = 0; i < count; i++)
                {
                    var item = boolArray[i];
                    if (item != (i % 2 == 0))
                    { throw new Exception(); }
                }
                interval = DateTime.Now.Ticks - startTick;

                unsafe
                {
                    startTick = DateTime.Now.Ticks;
                    bool* header = (bool*)boolArray.FirstElement();
                    bool* last = (bool*)boolArray.LastElement();
                    bool* tailAddress = (bool*)boolArray.TailAddress();
                    int value = 0;
                    for (bool* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++)
                    {
                        *ptr = (value % 2 == 0);
                        value++;
                    }
                    int i = 0;
                    for (bool* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++, i++)
                    {
                        var item = *ptr;
                        if (item != (i % 2 == 0))
                        { throw new Exception(); }
                    }
                    interval2 = DateTime.Now.Ticks - startTick;
                }
                Console.WriteLine("Ticks: safe: {0} vs unsafe: {1}", interval, interval2);
            }

            // 测试vec3类型
            {
                var vec3Array = new UnmanagedArray<vec3>(count);
                startTick = DateTime.Now.Ticks;
                for (int i = 0; i < count; i++)
                {
                    vec3Array[i] = new vec3(i * 3 + 0, i * 3 + 1, i * 3 + 2);
                }
                for (int i = 0; i < count; i++)
                {
                    var item = vec3Array[i];
                    var old = new vec3(i * 3 + 0, i * 3 + 1, i * 3 + 2);
                    if (item.x != old.x || item.y != old.y || item.z != old.z)
                    { throw new Exception(); }
                }
                interval = DateTime.Now.Ticks - startTick;

                unsafe
                {
                    startTick = DateTime.Now.Ticks;
                    vec3* header = (vec3*)vec3Array.FirstElement();
                    vec3* last = (vec3*)vec3Array.LastElement();
                    vec3* tailAddress = (vec3*)vec3Array.TailAddress();
                    int i = 0;
                    for (vec3* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++)
                    {
                        *ptr = new vec3(i * 3 + 0, i * 3 + 1, i * 3 + 2);
                        i++;
                    }
                    i = 0;
                    for (vec3* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++, i++)
                    {
                        var item = *ptr;
                        var old = new vec3(i * 3 + 0, i * 3 + 1, i * 3 + 2);
                        if (item.x != old.x || item.y != old.y || item.z != old.z)
                        { throw new Exception(); }
                    }
                    interval2 = DateTime.Now.Ticks - startTick;
                }
                Console.WriteLine("Ticks: safe: {0} vs unsafe: {1}", interval, interval2);

            }

            // 测试mat4类型
            {
                var vec3Array = new UnmanagedArray<mat4>(count);
                startTick = DateTime.Now.Ticks;
                for (int i = 0; i < count; i++)
                {
                    vec3Array[i] = new mat4(new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3));
                }
                for (int i = 0; i < count; i++)
                {
                    var item = vec3Array[i];
                    var old = new mat4(new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3));
                    for (int col = 0; col < 4; col++)
                    {
                        for (int row = 0; row < 4; row++)
                        {
                            if (item[col][row] != old[col][row])
                            { throw new Exception(); }
                        }
                    }
                }
                interval = DateTime.Now.Ticks - startTick;

                unsafe
                {
                    startTick = DateTime.Now.Ticks;
                    mat4* header = (mat4*)vec3Array.FirstElement();
                    mat4* last = (mat4*)vec3Array.LastElement();
                    mat4* tailAddress = (mat4*)vec3Array.TailAddress();
                    int i = 0;
                    for (mat4* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++)
                    {
                        *ptr = new mat4(new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3));
                        i++;
                    }
                    i = 0;
                    for (mat4* ptr = header; ptr <= last/*or: ptr < tailAddress*/; ptr++, i++)
                    {
                        var item = *ptr;
                        var old = new mat4(new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3), new vec4(i, i + 1, i + 2, i + 3));
                        for (int col = 0; col < 4; col++)
                        {
                            for (int row = 0; row < 4; row++)
                            {
                                if (item[col][row] != old[col][row])
                                { throw new Exception(); }
                            }
                        }
                    }
                    interval2 = DateTime.Now.Ticks - startTick;
                }
                Console.WriteLine("Ticks: safe: {0} vs unsafe: {1}", interval, interval2);

            }

            // 立即释放所有非托管数组占用的内存,任何之前创建的UnmanagedBase数组都不再可用了。
            UnmanagedArray<int>.FreeAll();
        }
Example #22
0
 /// <summary>
 /// Applies a scale transformation to matrix <paramref name="m"/> by vector <paramref name="v"/>.
 /// </summary>
 /// <param name="m">The matrix to transform.</param>
 /// <param name="v">The vector to scale by.</param>
 /// <returns><paramref name="m"/> scaled by <paramref name="v"/>.</returns>
 public static mat4 scale(mat4 m, vec3 v)
 {
     mat4 result = m;
     result[0] = m[0] * v[0];
     result[1] = m[1] * v[1];
     result[2] = m[2] * v[2];
     result[3] = m[3];
     return result;
 }
Example #23
0
        protected override void DoRender(RenderEventArgs e)
        {
            mat4 projectionMatrix, viewMatrix, modelMatrix;
            {
                IUILayout element = this as IUILayout;
                element.GetMatrix(out projectionMatrix, out viewMatrix, out modelMatrix, e.Camera);
            }

            this.mvp = projectionMatrix * viewMatrix * modelMatrix;
            this.shaderProgram.Bind();
            this.shaderProgram.SetUniformMatrix4(strMVP, mvp.to_array());

            GL.BindVertexArray(vao[0]);

            GL.DrawArrays(this.axisPrimitiveMode, 0, this.axisVertexCount);

            GL.BindVertexArray(0);
            this.shaderProgram.Unbind();
        }
Example #24
0
        void IMVP.SetShaderProgram(mat4 mvp)
        {
            this.tex.Bind();

            IMVPHelper.SetMVP(this, mvp);
        }
        void IMVP.SetShaderProgram(mat4 mvp)
        {
            GL.Enable(GL.GL_VERTEX_PROGRAM_POINT_SIZE);
            GL.Enable(GL.GL_POINT_SPRITE_ARB);
            //GL.TexEnv(GL.GL_POINT_SPRITE_ARB, GL.GL_COORD_REPLACE_ARB, GL.GL_TRUE);//TODO: test TexEnvi()
            GL.TexEnvf(GL.GL_POINT_SPRITE_ARB, GL.GL_COORD_REPLACE_ARB, GL.GL_TRUE);
            GL.Enable(GL.GL_POINT_SMOOTH);
            GL.Hint(GL.GL_POINT_SMOOTH_HINT, GL.GL_NICEST);
            GL.Enable(GL.GL_BLEND);
            GL.BlendEquation(GL.GL_FUNC_ADD_EXT);
            GL.BlendFuncSeparate(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA, GL.GL_ONE, GL.GL_ONE);

            GL.BindTexture(GL.GL_TEXTURE_2D, this.texture[0]);

            IMVPHelper.SetMVP(this, mvp);

            //int[] poinSizes = new int[2];
            //GL.GetInteger(GetTarget.PointSizeRange, poinSizes);
            //if (this.textureWidth > poinSizes[1])
            //{
            //    GL.PointParameter(GL.GL_POINT_SIZE_MAX_ARB, this.textureWidth);
            //    GL.GetInteger(GetTarget.PointSizeRange, poinSizes);
            //    Console.WriteLine("asf");
            //}
            shaderProgram.SetUniform(PointSpriteStringElement.strpointSize, this.textureWidth + 0.0f);
            shaderProgram.SetUniform(PointSpriteStringElement.strtex, this.texture[0]);
            shaderProgram.SetUniform(PointSpriteStringElement.strtextColor, this.textColor.x, this.textColor.y, this.textColor.z);
        }
Example #26
0
        /// <summary>
        /// 获取此UI元素的投影矩阵、视图矩阵和模型矩阵
        /// </summary>
        /// <param name="uiElement"></param>
        /// <param name="projectionMatrix"></param>
        /// <param name="viewMatrix"></param>
        /// <param name="modelMatrix"></param>
        /// <param name="camera">如果为null,会以glm.lookAt(new vec3(0, 0, 1), new vec3(0, 0, 0), new vec3(0, 1, 0))计算默认值。</param>
        /// <param name="maxDepth">UI元素的外接球半径的倍数。</param>
        public static void GetMatrix(this IUILayout uiElement,
            out mat4 projectionMatrix, out mat4 viewMatrix, out mat4 modelMatrix,
            IViewCamera camera = null, float maxDepth = 2.0f)
        {
            IUILayoutArgs args = uiElement.GetArgs();
            float max = (float)Math.Max(args.UIWidth, args.UIHeight);

            {
                //projectionMatrix = glm.ortho((float)args.left, (float)args.right, (float)args.bottom, (float)args.top,
                // TODO: / 2后与legacy opengl的UI元素显示就完全一致了。为什么???
                projectionMatrix = glm.ortho((float)args.left / 2, (float)args.right / 2, (float)args.bottom / 2, (float)args.top / 2,
                    uiElement.Param.zNear, uiElement.Param.zFar);
                // 下面注释掉的代码是用来测试legacy OpenGL的matrix与GLM库计算的matrix是否相同用的。已经证明了两者完全相同,此处仅作留念+以防万一。
                //{
                //    float[] matrix = new float[16];

                //    GL.MatrixMode(GL.GL_PROJECTION);
                //    GL.PushMatrix();
                //    GL.GetFloat(GetTarget.ProjectionMatrix, matrix);

                //    GL.LoadIdentity();
                //    GL.GetFloat(GetTarget.ProjectionMatrix, matrix);

                //    GL.Ortho(args.left / 2, args.right / 2, args.bottom / 2, args.top / 2, uiElement.Param.zNear, uiElement.Param.zFar);
                //    GL.GetFloat(GetTarget.ProjectionMatrix, matrix);// this equals projectionMatrix

                //    GL.PopMatrix();
                //}
                // 把UI元素移到ortho长方体的最靠近camera的地方,这样就可以把UI元素放到OpenGL最前方。
                projectionMatrix = glm.translate(projectionMatrix, new vec3(0, 0, uiElement.Param.zFar - max / 2 * maxDepth));
            }
            {
                // UI元素不在三维场景中,所以其Camera可以是null。
                if (camera == null)
                {
                    //viewMatrix = glm.lookAt(new vec3(0, 0, 1), new vec3(0, 0, 0), new vec3(0, 1, 0));
                    viewMatrix = glm.lookAt(
                        Camera.defaultPosition, 
                        Camera.defaultTarget, 
                        Camera.defaultUpVector);
                }
                else
                {
                    vec3 position = camera.Position - camera.Target;
                    position.Normalize();
                    viewMatrix = glm.lookAt(position, new vec3(0, 0, 0), camera.UpVector);
                }
                // 下面注释掉的代码是用来测试legacy OpenGL的matrix与GLM库计算的matrix是否相同用的。已经证明了两者完全相同,此处仅作留念+以防万一。
                //{
                //    float[] matrix = new float[16];

                //    GL.MatrixMode(GL.GL_MODELVIEW);
                //    GL.PushMatrix();
                //    GL.GetFloat(GetTarget.ModelviewMatix, matrix);

                //    GL.LoadIdentity();
                //    GL.GetFloat(GetTarget.ModelviewMatix, matrix);

                //    if(camera==null)
                //    {
                //        GL.gluLookAt(0, 0, 1, 0, 0, 0, 0, 1, 0);
                //    }
                //    else
                //    {
                //        vec3 position = camera.Position - camera.Target;
                //        position.Normalize();
                //        GL.gluLookAt(position.x, position.y, position.z, 0, 0, 0, camera.UpVector.x, camera.UpVector.y, camera.UpVector.z);
                //    }
                //    GL.GetFloat(GetTarget.ModelviewMatix, matrix);// this equals viewMatrix

                //    GL.PopMatrix();
                //}
            }
            {
                modelMatrix = glm.scale(mat4.identity(), new vec3(args.UIWidth / 2, args.UIHeight / 2, max / 2));
                // 下面注释掉的代码是用来测试legacy OpenGL的matrix与GLM库计算的matrix是否相同用的。已经证明了两者完全相同,此处仅作留念+以防万一。
                //{
                //    float[] matrix = new float[16];

                //    GL.MatrixMode(GL.GL_MODELVIEW);
                //    GL.PushMatrix();
                //    GL.GetFloat(GetTarget.ModelviewMatix, matrix);

                //    GL.LoadIdentity();
                //    GL.GetFloat(GetTarget.ModelviewMatix, matrix);

                //    GL.Scale(args.UIWidth / 2, args.UIHeight / 2, max / 2);
                //    GL.GetFloat(GetTarget.ModelviewMatix, matrix);// this equals modelMatrix

                //    GL.PopMatrix();
                //}
            }
        }
        void IMVP.SetShaderProgram(mat4 mvp)
        {
            //this.tex.Bind();
            GL.CullFace(GL.GL_FRONT_AND_BACK);
            GL.PolygonMode(PolygonModeFaces.FrontAndBack, PolygonModes.Filled);

            GL.Enable(GL.GL_ALPHA_TEST);
            GL.AlphaFunc(GL.GL_GREATER, alphaThreshold);

            bool blend = this.blend;
            if (blend)
            {
                GL.Enable(GL.GL_BLEND);
                GL.BlendFunc(sFactor, dFactor);
            }

            uint textureID = this.textureProcessor.GetTexture3D();
            GL.BindTexture(GL.GL_TEXTURE_3D, textureID);

            this.shaderProgram.Bind();
            this.shaderProgram.SetUniform("tex", textureID);

            IMVPHelper.SetMVP(this, mvp);
        }
Example #28
0
        /// <summary>
        /// 如果此矩阵是glm.perspective()的结果,那么返回glm.perspective()的各个参数值。
        /// </summary>
        /// <param name="matrix"></param>
        /// <param name="fovy"></param>
        /// <param name="aspectRatio"></param>
        /// <param name="zNear"></param>
        /// <param name="zFar"></param>
        /// <returns></returns>
        public static bool TryParse(this mat4 matrix,
                                    out float fovy, out float aspectRatio, out float zNear, out float zFar)
        {
            /*
             * var result = mat4.identity();
             * float tangent = (float)Math.Tan(fovy / 2.0f);
             * float height = zNear * tangent;
             * float width = height * aspect;
             * float l = -width, r = width, b = -height, t = height, n = zNear, f = zFar;
             * result[0, 0] = 2 * n / (r - l);// = 2 * zNear / (2 * zNear * tangent * aspect)
             * result[1, 1] = 2 * n / (t - b);// = 2 * zNear / (2 * zNear * tangent)
             * result[2, 0] = (r + l) / (r - l);// = 0
             * result[2, 1] = (t + b) / (t - b);// = 0
             * result[2, 2] = -(f + n) / (f - n);
             * result[2, 3] = -1;
             * result[3, 2] = -(2 * f * n) / (f - n);
             * result[3, 3] = 0;
             */
            float tanHalfFovy = 1.0f / matrix[1, 1];

            fovy = 2 * (float)(Math.Atan(tanHalfFovy));
            if (fovy < 0)
            {
                fovy = -fovy;
            }
            //aspectRatio = 1.0f / matrix[0, 0] / tanHalfFovy;
            aspectRatio = matrix[1, 1] / matrix[0, 0];
            if (matrix[2, 2] == 1.0f)
            {
                zFar  = 0.0f;
                zNear = 0.0f;
            }
            else if (matrix[2, 2] == -1.0f)
            {
                zNear = 0.0f;
                zFar  = float.PositiveInfinity;
            }
            else
            {
                zNear = matrix[3, 2] / (matrix[2, 2] - 1);
                zFar  = matrix[3, 2] / (matrix[2, 2] + 1);
            }

            if (matrix[0, 0] == 0.0f || matrix[1, 1] == 0.0f || matrix[2, 2] == 0.0f)
            {
                return(false);
            }

            if (matrix[1, 0] != 0.0f || matrix[3, 0] != 0.0f ||
                matrix[0, 1] != 0.0f || matrix[3, 1] != 0.0f ||
                matrix[0, 2] != 0.0f || matrix[1, 2] != 0.0f ||
                matrix[0, 3] != 0.0f || matrix[1, 3] != 0.0f || matrix[3, 3] != 0.0f)
            {
                return(false);
            }

            if (matrix[2, 3] != -1.0f)
            {
                return(false);
            }

            return(true);
        }
Example #29
0
 void IMVP.SetShaderProgram(mat4 mvp)
 {
     IMVPHelper.SetMVP(this, mvp);
 }
Example #30
0
        /// <summary>
        /// Builds a perspective projection matrix based on a field of view.
        /// </summary>
        /// <param name="fov">The fov (in radians).</param>
        /// <param name="width">The width.</param>
        /// <param name="height">The height.</param>
        /// <param name="zNear">The z near.</param>
        /// <param name="zFar">The z far.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentOutOfRangeException"></exception>
        public static mat4 perspectiveFov(float fov, float width, float height, float zNear, float zFar)
        {
            if (width <= 0 || height <= 0 || fov <= 0)
                throw new ArgumentOutOfRangeException();

            var rad = fov;

            var h = glm.cos((0.5f) * rad) / glm.sin((0.5f) * rad);
            var w = h * height / width;

            var result = new mat4(0);
            result[0, 0] = w;
            result[1, 1] = h;
            result[2, 2] = -(zFar + zNear) / (zFar - zNear);
            result[2, 3] = -(1f);
            result[3, 2] = -((2f) * zFar * zNear) / (zFar - zNear);
            return result;
        }