Ejemplo n.º 1
0
 private void TestUsingUnmanagedArray()
 {
     unsafe
     {
         vec3 *first = (vec3 *)array.FirstElement();
     }
 }
Ejemplo n.º 2
0
        private void btnUnsafeVSSafe_Click(object sender, EventArgs e)
        {
            int count = 1000000;
            // 测试vec3类型
            {
                var  vec3Array = new UnmanagedArray <vec3>(count);
                long 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();
                    }
                }
                long 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();
                        }
                    }
                }
                long interval2 = DateTime.Now.Ticks - startTick;

                Console.WriteLine();
                MessageBox.Show(string.Format("Ticks: safe: {0} vs unsafe: {1}", interval, interval2), "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();
        }
Ejemplo n.º 4
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();
        }
Ejemplo n.º 5
0
        // Call this only after the open gl is initialized.
        public bool ReadFile(string lpDataFile_i, int nWidth_i, int nHeight_i, int nSlices_i)
        {
            FileStream file = new FileStream(lpDataFile_i, FileMode.Open, FileAccess.Read);

            // File has only image data. The dimension of the data should be known.
            m_uImageCount  = nSlices_i;
            m_uImageWidth  = nWidth_i;
            m_uImageHeight = nHeight_i;

            // Holds the luminance buffer
            //byte[] chBuffer = new byte[m_uImageWidth * m_uImageHeight * m_uImageCount];
            //UnmanagedArray<byte> chBuffer = new UnmanagedArray<byte>(m_uImageWidth * m_uImageHeight * m_uImageCount);
            byte[] chBuffer = new byte[m_uImageWidth * m_uImageHeight * m_uImageCount];

            // Holds the RGBA buffer
            UnmanagedArray <byte> pRGBABuffer = new UnmanagedArray <byte>(m_uImageWidth * m_uImageHeight * m_uImageCount * 4);

            file.Read(chBuffer, 0, chBuffer.Length);

            // Convert the data to RGBA data.
            // Here we are simply putting the same value to R, G, B and A channels.
            // Usually for raw data, the alpha value will be constructed by a threshold value given by the user

            unsafe
            {
                byte *rgbBuffer = (byte *)pRGBABuffer.FirstElement();
                for (int nIndx = 0; nIndx < m_uImageWidth * m_uImageHeight * m_uImageCount; ++nIndx)
                {
                    byte value = chBuffer[nIndx];
                    //if (value < 20)
                    //{ value = 0; }
                    rgbBuffer[nIndx * 4]     = value;
                    rgbBuffer[nIndx * 4 + 1] = value;
                    rgbBuffer[nIndx * 4 + 2] = value;
                    rgbBuffer[nIndx * 4 + 3] = value;
                }
            }

            // If this function is getting called again for another data file.
            // Deleting and creating texture is not a good idea,
            // we can use the glTexSubImage3D for better performance for such scenario.
            // I am not using that now :-)
            if (0 != m_nTexId[0])
            {
                GL.DeleteTextures(1, m_nTexId);
            }
            GL.GenTextures(1, m_nTexId);

            GL.BindTexture(GL.GL_TEXTURE_3D, m_nTexId[0]);
            GL.TexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, (int)GL.GL_REPLACE);
            GL.TexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_WRAP_S, (int)GL.GL_CLAMP_TO_BORDER);
            GL.TexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_WRAP_T, (int)GL.GL_CLAMP_TO_BORDER);
            GL.TexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_WRAP_R, (int)GL.GL_CLAMP_TO_BORDER);
            GL.TexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_MAG_FILTER, (int)GL.GL_LINEAR);
            GL.TexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_MIN_FILTER, (int)GL.GL_LINEAR);

            //uint target, int level, int internalformat, int width, int height, int depth, int border, uint format, uint type, IntPtr pixels)

            GL.TexImage3D(GL.GL_TEXTURE_3D, 0, (int)GL.GL_RGBA, m_uImageWidth, m_uImageHeight, m_uImageCount, 0,
                          GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, pRGBABuffer.Header);
            GL.BindTexture(GL.GL_TEXTURE_3D, 0);

            return(true);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// 读取数据文件,获取3D纹理
        /// </summary>
        /// <param name="dataFiles"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="slices"></param>
        /// <returns></returns>
        public bool ReadFile(string[] dataFiles, int width, int height, int slices)
        {
            this.slices = slices;
            this.width  = width;
            this.height = height;

            float[] chBuffer = new float[width * height * slices];
            float   min = 0, max = 0;

            // 找到数据中的最大、最小值,为配色做准备
            {
                int    index = 0;
                bool   minSet = false, maxSet = false;
                char[] separator = new char[] { ' ', '\t', '\r', '\n' };
                for (int i = 0; i < dataFiles.Length; i++)
                {
                    string filename = dataFiles[i];
                    using (var sr = new StreamReader(filename))
                    {
                        while (!sr.EndOfStream)
                        {
                            var line  = sr.ReadLine();
                            var parts = line.Split(separator, StringSplitOptions.RemoveEmptyEntries);
                            foreach (var part in parts)
                            {
                                float value;
                                if (float.TryParse(part, out value))
                                {
                                    if (!minSet)
                                    {
                                        min = value; minSet = true;
                                    }
                                    if (!maxSet)
                                    {
                                        max = value; maxSet = true;
                                    }

                                    if (value < min)
                                    {
                                        min = value;
                                    }
                                    if (max < value)
                                    {
                                        max = value;
                                    }

                                    chBuffer[index++] = value;
                                }
                                else
                                {
                                    throw new Exception();
                                }
                            }
                        }
                    }
                }
            }

            // 用非托管数组存储顶点颜色,为创建3D纹理做准备
            UnmanagedArray <byte> pRGBABuffer = new UnmanagedArray <byte>(width * height * slices * 4);

            unsafe
            {
                byte *rgbBuffer = (byte *)pRGBABuffer.FirstElement();
                for (int nIndx = 0; nIndx < width * height * slices; ++nIndx)
                {
                    float    value = chBuffer[nIndx];
                    ColorBar bar   = ColorBar.GetDefault();         // 默认配色方案
                    vec3     color = bar.GetColor(min, max, value); // 有数值得到对应的颜色
                    rgbBuffer[nIndx * 4]     = (byte)(color.x * 255);
                    rgbBuffer[nIndx * 4 + 1] = (byte)(color.y * 255);
                    rgbBuffer[nIndx * 4 + 2] = (byte)(color.z * 255);
                    // 适当降低不透明度(此处用 / 10)
                    rgbBuffer[nIndx * 4 + 3] = (byte)((value - min) / (max - min) * 255.0f / 10);
                }
            }

            // 创建3D贴图,为渲染做准备
            if (0 != textureId[0])
            {
                GL.DeleteTextures(1, textureId);
            }
            GL.GenTextures(1, textureId);
            GL.BindTexture(GL.GL_TEXTURE_3D, textureId[0]);
            GL.TexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, (int)GL.GL_REPLACE);
            GL.TexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_WRAP_S, (int)GL.GL_CLAMP_TO_BORDER);
            GL.TexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_WRAP_T, (int)GL.GL_CLAMP_TO_BORDER);
            GL.TexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_WRAP_R, (int)GL.GL_CLAMP_TO_BORDER);
            GL.TexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_MAG_FILTER, (int)GL.GL_LINEAR);
            GL.TexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_MIN_FILTER, (int)GL.GL_LINEAR);
            GL.TexImage3D(GL.GL_TEXTURE_3D, 0, (int)GL.GL_RGBA, width, height, slices, 0,
                          GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, pRGBABuffer.Header);
            GL.BindTexture(GL.GL_TEXTURE_3D, 0);

            // 非托管数组要手动释放
            pRGBABuffer.Dispose();

            return(true);
        }
Ejemplo n.º 7
0
        // Call this only after the open gl is initialized.
        public bool ReadFile(string lpDataFile_i, int nWidth_i, int nHeight_i, int nSlices_i)
        {
            FileStream file = new FileStream(lpDataFile_i, FileMode.Open, FileAccess.Read);

            // File has only image data. The dimension of the data should be known.
            m_uImageCount = nSlices_i;
            m_uImageWidth = nWidth_i;
            m_uImageHeight = nHeight_i;

            // Holds the luminance buffer
            //byte[] chBuffer = new byte[m_uImageWidth * m_uImageHeight * m_uImageCount];
            //UnmanagedArray<byte> chBuffer = new UnmanagedArray<byte>(m_uImageWidth * m_uImageHeight * m_uImageCount);
            byte[] chBuffer = new byte[m_uImageWidth * m_uImageHeight * m_uImageCount];

            // Holds the RGBA buffer
            UnmanagedArray<byte> pRGBABuffer = new UnmanagedArray<byte>(m_uImageWidth * m_uImageHeight * m_uImageCount * 4);
            file.Read(chBuffer, 0, chBuffer.Length);

            // Convert the data to RGBA data.
            // Here we are simply putting the same value to R, G, B and A channels.
            // Usually for raw data, the alpha value will be constructed by a threshold value given by the user 

            unsafe
            {
                byte* rgbBuffer = (byte*)pRGBABuffer.FirstElement();
                for (int nIndx = 0; nIndx < m_uImageWidth * m_uImageHeight * m_uImageCount; ++nIndx)
                {
                    byte value = chBuffer[nIndx];
                    //if (value < 20)
                    //{ value = 0; }
                    rgbBuffer[nIndx * 4] = value;
                    rgbBuffer[nIndx * 4 + 1] = value;
                    rgbBuffer[nIndx * 4 + 2] = value;
                    rgbBuffer[nIndx * 4 + 3] = value;
                }
            }

            // If this function is getting called again for another data file.
            // Deleting and creating texture is not a good idea, 
            // we can use the glTexSubImage3D for better performance for such scenario.
            // I am not using that now :-)
            if (0 != m_nTexId[0])
            {
                GL.DeleteTextures(1, m_nTexId);
            }
            GL.GenTextures(1, m_nTexId);

            GL.BindTexture(GL.GL_TEXTURE_3D, m_nTexId[0]);
            GL.TexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, (int)GL.GL_REPLACE);
            GL.TexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_WRAP_S, (int)GL.GL_CLAMP_TO_BORDER);
            GL.TexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_WRAP_T, (int)GL.GL_CLAMP_TO_BORDER);
            GL.TexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_WRAP_R, (int)GL.GL_CLAMP_TO_BORDER);
            GL.TexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_MAG_FILTER, (int)GL.GL_LINEAR);
            GL.TexParameteri(GL.GL_TEXTURE_3D, GL.GL_TEXTURE_MIN_FILTER, (int)GL.GL_LINEAR);

            //uint target, int level, int internalformat, int width, int height, int depth, int border, uint format, uint type, IntPtr pixels)

            GL.TexImage3D(GL.GL_TEXTURE_3D, 0, (int)GL.GL_RGBA, m_uImageWidth, m_uImageHeight, m_uImageCount, 0,
                GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, pRGBABuffer.Header);
            GL.BindTexture(GL.GL_TEXTURE_3D, 0);

            return true;
        }