Ejemplo n.º 1
0
        private void DoRender(object sender, PaintEventArgs e)
        {
            // Compute the MVP (Model View Projection matrix)
            {
                GL.BindBuffer(BufferTarget.UniformBuffer, BufferName[1]);//BufferName[TRANSFORM]
                var mvpPointer = GL.MapBufferRange(GL.GL_UNIFORM_BUFFER, 0, 64, (uint)(GL.GL_MAP_WRITE_BIT | GL.GL_MAP_INVALIDATE_BUFFER_BIT));

                var  tmp        = new UnmanagedArray <mat4>(1);
                mat4 projection = this.camera.GetProjectionMat4();
                mat4 view       = this.camera.GetViewMat4();
                //tmp[0] = projection * view;
                //tmp.CopyTo(Pointer);
                unsafe
                {
                    mat4 *array = (mat4 *)mvpPointer.ToPointer();
                    array[0] = projection * view;
                }

                GL.UnmapBuffer(GL.GL_UNIFORM_BUFFER);

                tmp.Dispose();
            }

            // Clear color buffer
            //GL.ClearBufferfv(GL_COLOR, 0, &GL.m.vec4(0.0f, 0.0f, 0.0f, 1.0f)[0]);
            GL.ClearBuffer(GL.GL_COLOR, 0, new float[] { 0.0f, 0.0f, 0.0f, 1.0f });

            // First draw, capture the attributes
            // Disable rasterisation, vertices processing only!
            GL.Enable(GL.GL_RASTERIZER_DISCARD);

            transformProgram.Bind();

            GL.BindVertexArray(transformArray[0]);
            //GL.BindBufferBase(GL.GL_UNIFORM_BUFFER, semantic.uniform.TRANSFORM0, BufferName[buffer.TRANSFORM]);
            GL.BindBufferBase(GL.GL_UNIFORM_BUFFER, 1, BufferName[1]);

            GL.BindTransformFeedback(GL.GL_TRANSFORM_FEEDBACK, feedbackObj[0]);
            GL.BeginTransformFeedback(GL.GL_TRIANGLES);
            GL.DrawArraysInstanced(GL.GL_TRIANGLES, 0, 6, 1);//VertexCount: 6
            GL.EndTransformFeedback();
            GL.BindTransformFeedback(GL.GL_TRANSFORM_FEEDBACK, 0);

            GL.Disable(GL.GL_RASTERIZER_DISCARD);

            // Second draw, reuse the captured attributes
            feedbackProgram.Bind();

            GL.BindVertexArray(feedbackArray[0]);
            GL.DrawTransformFeedback(GL.GL_TRIANGLES, feedbackObj[0]);
        }
Ejemplo n.º 2
0
        protected override void DoRender(RenderEventArgs e)
        {
            float t = (float)(TimerHelper.GetTickCount() & 0x3FFF) / factor;
            int   n;


            //// Setup
            //glEnable(GL_CULL_FACE);
            //glEnable(GL_DEPTH_TEST);
            //glDepthFunc(GL_LEQUAL);

            // Bind the weight VBO and change its data
            GL.BindBuffer(BufferTarget.ArrayBuffer, model_matrix_buffer[0]);

            // Set model matrices for each instance
            IntPtr pointer = GL.MapBuffer(BufferTarget.ArrayBuffer, MapBufferAccess.WriteOnly);

            unsafe
            {
                mat4 *matrices = (mat4 *)pointer.ToPointer();
                for (n = 0; n < INSTANCE_COUNT; n++)
                {
                    float a = 50.0f * (float)(n) / 4.0f;
                    float b = 50.0f * (float)(n) / 5.0f;
                    float c = 50.0f * (float)(n) / 6.0f;

                    matrices[n] =
                        glm.rotate(a + t * 1.0f, new vec3(1, 0, 0))
                        * glm.rotate(b + t * 1.0f, new vec3(0, 1, 0))
                        * glm.rotate(c + t * 1.0f, new vec3(0, 0, 1))
                        * glm.translate(mat4.identity(), new vec3(10.0f + a, 40.0f + b, 50.0f + c));
                }
            }

            GL.UnmapBuffer(BufferTarget.ArrayBuffer);

            // Activate instancing program
            GL.UseProgram(render_prog);

            // Set up the view and projection matrices
            //mat4 view_matrix(translate(0.0f, 0.0f, -1500.0f) * rotate(t * 360.0f * 2.0f, 0.0f, 1.0f, 0.0f));
            //mat4 projection_matrix(frustum(-1.0f, 1.0f, -aspect, aspect, 1.0f, 5000.0f));
            mat4 view_matrix       = e.Camera.GetViewMat4();
            mat4 projection_matrix = e.Camera.GetProjectionMat4();

            GL.UniformMatrix4(view_matrix_loc, 1, false, view_matrix.to_array());
            GL.UniformMatrix4(projection_matrix_loc, 1, false, projection_matrix.to_array());

            // Render INSTANCE_COUNT objects
            vboObject.Render(0, INSTANCE_COUNT);
        }
Ejemplo n.º 3
0
        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();
        }