Example #1
0
        //private IEnumerable<Vector2d> GenerateLensSamples(int tileSize, int sqrtSampleCount)
        //{
        //    int pixelCount = tileSize * tileSize;
        //    IEnumerator<Vector2d>[] jitteredSamplers = new IEnumerator<Vector2d>[pixelCount];
        //    Sampler sampler = new Sampler();
        //    for (int i = 0; i < pixelCount; i++)
        //    {
        //        jitteredSamplers[i] = sampler.GenerateJitteredSamples(MaxTotalSampleCount).GetEnumerator();
        //    }
        //    for (int sample = 0; sample < MaxTotalSampleCount; sample++)
        //    {
        //        for (int i = 0; i < pixelCount; i++)
        //        {
        //            jitteredSamplers[i].MoveNext();
        //            yield return jitteredSamplers[i].Current;
        //        }
        //    }
        //}

        private void GeneratePixelSamplesTexture(int textureId, int sqrtSampleCount, int sampleCount)
        {
            GL.BindTexture(TextureTarget.Texture1D, textureId);
            // size of a group of samples for a single pixel
            int bands       = 2;
            int textureSize = bands * sampleCount;

            Sampler sampler    = new Sampler();
            IntPtr  texturePtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Half)) * textureSize);

            unsafe
            {
                Half *row   = (Half *)texturePtr;
                int   index = 0;
                foreach (Vector2d sample in sampler.GenerateJitteredSamples(sqrtSampleCount))
                {
                    row[index] = (Half)(sample.X - 0.5f);
                    index++;
                    row[index] = (Half)(sample.Y - 0.5f);
                    index++;
                }
            }

            // TODO: could be an half float or unsigned byte instead of a float
            // TODO: two sample pair could be stored in one 4-channel value
            GL.TexImage1D(TextureTarget.Texture1D, 0, PixelInternalFormat.Rg16f,
                          sampleCount, 0,
                          PixelFormat.Rg, PixelType.HalfFloat, texturePtr);

            Marshal.FreeHGlobal(texturePtr);

            GL.TexParameter(TextureTarget.Texture1D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
            GL.TexParameter(TextureTarget.Texture1D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
            GL.TexParameter(TextureTarget.Texture1D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
        }
Example #2
0
        static uint GenerateHdrStarsTex(int width, int height, int starCount, float intensity, bool colorize, int seed)
        {
            uint texture = (uint)GL.GenTexture();

            GL.BindTexture(TextureTarget.Texture2D, texture);

            int bands       = 3;
            int textureSize = bands * width * height;

            IList <Star> stars = Star.GenerateStars(starCount, intensity, colorize, seed);

            IntPtr texturePtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Half)) * textureSize);

            unsafe
            {
                // zero out the texture
                Half zero = (Half)0.0;
                for (int y = 0; y < height; y++)
                {
                    Half *row   = (Half *)texturePtr + bands * y * width;
                    int   index = 0;
                    for (int x = 0; x < width; x++)
                    {
                        for (int band = 0; band < bands; band++)
                        {
                            row[index++] = zero;
                        }
                    }
                }

                // put the stars into the image
                Half *image = (Half *)texturePtr;
                foreach (var star in stars)
                {
                    int x     = (int)(star.Position.X * width);
                    int y     = (int)(star.Position.Y * height);
                    int index = bands * (y * width + x);
                    image[index]     = (Half)star.Color.X;
                    image[index + 1] = (Half)star.Color.Y;
                    image[index + 2] = (Half)star.Color.Z;
                }
            }

            GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgb16f,
                          width, height, 0, OpenTK.Graphics.OpenGL.PixelFormat.Rgb, PixelType.HalfFloat, texturePtr);
            Marshal.FreeHGlobal(texturePtr);

            //GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);

            //GL.Ext.GenerateMipmap(GenerateMipmapTarget.Texture2D);

            return(texture);
        }
Example #3
0
            public unsafe static void ToInt8(Half *x, int length, sbyte[] y)
            {
                var Threads       = Environment.ProcessorCount;
                var TaskPart      = length / Threads;
                var TaskRemainder = length % Threads;

                Parallel.For(0, Threads, (int i) =>
                {
                    var start = TaskPart * i;
                    var end   = start + TaskPart;
                    for (int j = start; j < end; j++)
                    {
                        y[j] = (sbyte)x[j];
                    }
                });
                var start_ = TaskPart * Threads;
                var end_   = start_ + TaskRemainder;

                for (int j = start_; j < end_; j++)
                {
                    y[j] = (sbyte)x[j];
                }
            }
Example #4
0
        /// <summary>
        /// Takes a NormalDepth texture and creates a normal- and a depth-bitmap
        /// </summary>
        /// <param name="normal">The normal-bitmap</param>
        /// <param name="depth">The depth-bitmap</param>
        public unsafe void UploadNormalDepthBitmapsWpf(out WriteableBitmap normal, out WriteableBitmap depth)
        {
            //Check current format
            if (m_format != GraphicsHelper.DEFAULT_TEXTURE_FORMAT_NORMAL_DEPTH)
            {
                throw new SeeingSharpGraphicsException("Invalid format for getting NormalDepth-Values (" + m_format + ")!");
            }

            //Upload the texture
            CopyTextureToStagingResource(true);

            //Read the data into the .Net data block
            SharpDX.DataBox dataBox = m_device.DeviceImmediateContextD3D11.MapSubresource(
                m_copyHelperTextureStaging, 0, D3D11.MapMode.Read, D3D11.MapFlags.None);

            //Create the output bitmaps
            normal = new WriteableBitmap(m_width, m_height, 96, 96, System.Windows.Media.PixelFormats.Bgra32, null);
            depth  = new WriteableBitmap(m_width, m_height, 96, 96, System.Windows.Media.PixelFormats.Bgra32, null);

            try
            {
                //Read the values from Texture into bitmapsa
                Half *pointr         = (Half *)dataBox.DataPointer.ToPointer();
                int   rowPitchSource = dataBox.RowPitch / 2;

                int rowSource = normal.BackBufferStride / 4;

                normal.Lock();
                depth.Lock();

                int *normalBitmapBuffer = (int *)normal.BackBuffer.ToPointer();
                int *depthBitmapBuffer  = (int *)depth.BackBuffer.ToPointer();

                for (int loopY = 0; loopY < m_height; loopY++)
                {
                    for (int loopX = 0; loopX < m_width; loopX++)
                    {
                        //Calculate the pointer
                        int position = (loopY * rowPitchSource) + (loopX * 4);

                        //Read values from texture
                        Half valueR     = pointr[position];
                        Half valueG     = pointr[position + 1];
                        Half valueB     = pointr[position + 2];
                        Half valueDepth = pointr[position + 3];

                        //Calculate the Values for the Colors
                        int colorR        = (int)Math.Abs(valueR * 255);
                        int colorG        = (int)Math.Abs(valueG * 255);
                        int colorB        = (int)Math.Abs(valueB * 255);
                        int colorDepthVal = (int)Math.Abs(valueDepth);
                        colorDepthVal = 255 - (colorDepthVal > 255 ? 255 : colorDepthVal < 0 ? 0 : colorDepthVal);
                        colorR        = colorR > 255 ? 255 : colorR < 0 ? 0 : colorR;
                        colorG        = colorG > 255 ? 255 : colorG < 0 ? 0 : colorG;
                        colorB        = colorB > 255 ? 255 : colorB < 0 ? 0 : colorB;

                        //Create Colors
                        Color colorNormal = Color.FromArgb(255, colorR, colorG, colorB);
                        Color colorDepth  = Color.FromArgb(255, colorDepthVal, colorDepthVal, colorDepthVal);

                        int normalColorData = colorNormal.A << 24;
                        normalColorData |= colorNormal.R << 16;
                        normalColorData |= colorNormal.G << 8;
                        normalColorData |= colorNormal.B << 0;

                        int depthColorData = colorDepth.A << 24;
                        depthColorData |= colorDepth.R << 16;
                        depthColorData |= colorDepth.G << 8;
                        depthColorData |= colorDepth.B << 0;

                        normalBitmapBuffer[loopY * rowSource + (loopX)] = normalColorData;
                        depthBitmapBuffer[loopY * rowSource + loopX]    = depthColorData;
                    }
                }
                normal.AddDirtyRect(new System.Windows.Int32Rect(0, 0, m_width, m_height));
                depth.AddDirtyRect(new System.Windows.Int32Rect(0, 0, m_width, m_height));
                normal.Unlock();
                normal.Freeze();
                depth.Unlock();
                depth.Freeze();
            }
            finally
            {
                m_device.DeviceImmediateContextD3D11.UnmapSubresource(m_copyHelperTextureStaging, 0);
            }
        }
Example #5
0
        private void GenerateLensSamplesTextures(int textureId, int totalSampleCount, int tileSize)
        {
            // size of a group of samples for a single pixel
            int bands       = 2;
            int textureSize = bands * totalSampleCount * tileSize * tileSize;

            //IEnumerable<Vector2d> samples = GenerateLensSamples(tileSize, (int)Math.Sqrt(MaxTotalSampleCount)).GetEnumerator();

            int sqrtTotalSampleCount = (int)Math.Sqrt(totalSampleCount);

            Vector2[, ,] samples = new Vector2[tileSize, tileSize, totalSampleCount];
            Sampler sampler = new Sampler();

            for (int y = 0; y < tileSize; y++)
            {
                for (int x = 0; x < tileSize; x++)
                {
                    IEnumerable <Vector2> pixelSamples = sampler.CreateLensSamplesFloat(sqrtTotalSampleCount, ShuffleLensSamples);
                    int z = 0;
                    foreach (Vector2 sample in pixelSamples)
                    {
                        samples[x, y, z] = sample;
                        z++;
                    }
                }
            }

            GL.BindTexture(TextureTarget.Texture3D, textureId);

            IntPtr texturePtr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Half)) * textureSize);

            unsafe
            {
                int zStride = bands * tileSize * tileSize;
                for (int y = 0; y < tileSize; y++)
                {
                    for (int x = 0; x < tileSize; x++)
                    {
                        Half *row   = (Half *)texturePtr + bands * (y * tileSize + x);
                        int   index = 0;
                        // Z dimension
                        for (int sample = 0; sample < totalSampleCount; sample++)
                        {
                            Vector2 lensPos = samples[x, y, sample];
                            row[index]     = (Half)lensPos.X;
                            row[index + 1] = (Half)lensPos.Y;
                            index         += zStride;
                        }
                    }
                }
            }

            // TODO: could be an half float or unsigned byte instead of a float
            // TODO: two sample pair could be stored in one 4-channel value
            GL.TexImage3D(TextureTarget.Texture3D, 0, PixelInternalFormat.Rg16f,
                          tileSize, tileSize, totalSampleCount, 0,
                          PixelFormat.Rg, PixelType.HalfFloat, texturePtr);

            Marshal.FreeHGlobal(texturePtr);

            GL.TexParameter(TextureTarget.Texture3D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest);
            GL.TexParameter(TextureTarget.Texture3D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest);
            GL.TexParameter(TextureTarget.Texture3D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);
            GL.TexParameter(TextureTarget.Texture3D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);
            GL.TexParameter(TextureTarget.Texture3D, TextureParameterName.TextureWrapR, (int)TextureWrapMode.Clamp);
        }
        static bool GenerateFile(string sourceRealFileName, bool generateIrradiance, int destSize, string destRealFileName, List <Vector3> outIrradianceValues, out string error)
        {
            var tempDirectory = GetTemporaryDirectory();

            string arguments;

            if (generateIrradiance)
            {
                arguments = $"--format=hdr --size={destSize} --type=cubemap --ibl-irradiance=\"{tempDirectory}\" \"{sourceRealFileName}\"";
            }
            else
            {
                arguments = $"--format=hdr --size={destSize} --type=cubemap -x \"{tempDirectory}\" \"{sourceRealFileName}\"";
            }

            var process = new Process();

            process.StartInfo.FileName  = Path.Combine(VirtualFileSystem.Directories.EngineInternal, @"Tools\Filament\cmgen.exe");
            process.StartInfo.Arguments = arguments;
            process.Start();
            process.WaitForExit();

            var exitCode = process.ExitCode;

            if (exitCode != 0)
            {
                error = $"cmgen.exe exit code = {exitCode}.";
                return(false);
            }

            var folder = Path.Combine(tempDirectory, Path.GetFileNameWithoutExtension(sourceRealFileName));

            int  size;
            bool need16bit = false;
            {
                var file  = Path.Combine(folder, generateIrradiance ? "i_nx.hdr" : "m0_nx.hdr");
                var bytes = File.ReadAllBytes(file);
                if (!ImageUtility.LoadFromBuffer(bytes, "hdr", out var data, out var size2, out _, out var format, out _, out _, out error))
                {
                    return(false);
                }
                size = size2.X;
                if (format != PixelFormat.Float32RGB)
                {
                    error = "format != PixelFormat.Float32RGB";
                    return(false);
                }

                var image2D = new ImageUtility.Image2D(format, size2, data);
                for (int y = 0; y < image2D.Size.Y; y++)
                {
                    for (int x = 0; x < image2D.Size.X; x++)
                    {
                        var v = image2D.GetPixel(new Vector2I(x, y));
                        if (v.X > 1.001f || v.Y >= 1.001f || v.Z >= 1.001f)
                        {
                            need16bit = true;
                            goto end16bit;
                        }
                    }
                }
                end16bit :;
            }

            var surfaces = new List <DDSImage.Surface>();

            for (int face = 0; face < 6; face++)
            {
                int counter     = 0;
                int currentSize = size;
                while (currentSize > 0)
                {
                    var postfixes = new string[] { "px", "nx", "py", "ny", "pz", "nz" };

                    string file;
                    if (generateIrradiance)
                    {
                        file = Path.Combine(folder, $"i_{postfixes[ face ]}.hdr");
                    }
                    else
                    {
                        file = Path.Combine(folder, $"m{counter}_{postfixes[ face ]}.hdr");
                    }

                    var bytes = File.ReadAllBytes(file);
                    if (!ImageUtility.LoadFromBuffer(bytes, "hdr", out var data, out var size2, out _, out var format, out _, out _, out error))
                    {
                        return(false);
                    }
                    if (format != PixelFormat.Float32RGB)
                    {
                        error = "format != PixelFormat.Float32RGB";
                        return(false);
                    }
                    if (size2.X != currentSize)
                    {
                        error = "size2.X != currentSize";
                        return(false);
                    }

                    if (need16bit)
                    {
                        byte[] newData = new byte[currentSize * currentSize * 4 * 2];

                        unsafe
                        {
                            fixed(byte *pData = data)
                            {
                                float *pData2 = (float *)pData;

                                fixed(byte *pNewData = newData)
                                {
                                    Half *pNewData2 = (Half *)pNewData;

                                    for (int n = 0; n < currentSize * currentSize; n++)
                                    {
                                        pNewData2[n * 4 + 0] = new Half(pData2[n * 3 + 0]);
                                        pNewData2[n * 4 + 1] = new Half(pData2[n * 3 + 1]);
                                        pNewData2[n * 4 + 2] = new Half(pData2[n * 3 + 2]);
                                        pNewData2[n * 4 + 3] = new Half(1.0f);
                                    }
                                }
                            }
                        }

                        surfaces.Add(new DDSImage.Surface(new Vector2I(currentSize, currentSize), newData));
                    }
                    else
                    {
                        byte[] newData = new byte[currentSize * currentSize * 4];

                        unsafe
                        {
                            fixed(byte *pData = data)
                            {
                                float *pData2 = (float *)pData;

                                for (int n = 0; n < currentSize * currentSize; n++)
                                {
                                    newData[n * 4 + 3] = 255;
                                    newData[n * 4 + 2] = (byte)(MathEx.Saturate(pData2[n * 3 + 0]) * 255.0);
                                    newData[n * 4 + 1] = (byte)(MathEx.Saturate(pData2[n * 3 + 1]) * 255.0);
                                    newData[n * 4 + 0] = (byte)(MathEx.Saturate(pData2[n * 3 + 2]) * 255.0);
                                }
                            }
                        }

                        surfaces.Add(new DDSImage.Surface(new Vector2I(currentSize, currentSize), newData));
                    }

                    counter++;
                    currentSize /= 2;

                    if (generateIrradiance)
                    {
                        break;
                    }
                }
            }

            var image = new DDSImage(need16bit ? DDSImage.FormatEnum.R16G16B16A16 : DDSImage.FormatEnum.X8R8G8B8, surfaces.ToArray(), true);

            if (!WriteToFile(destRealFileName, image, out error))
            {
                return(false);
            }

            if (outIrradianceValues != null)
            {
                var shFile = Path.Combine(folder, "sh.txt");
                var lines  = File.ReadAllLines(shFile);
                foreach (var line in lines)
                {
                    var index1 = line.IndexOf('(');
                    var index2 = line.IndexOf(')');
                    if (index1 != -1 && index2 != -1)
                    {
                        var str = line.Substring(index1 + 1, index2 - index1 - 1).Trim();

                        var strs = str.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                        if (strs.Length != 3)
                        {
                            error = "Unable to parse \"sh.txt\".";
                            return(false);
                        }

                        var x = double.Parse(strs[0].Trim());
                        var y = double.Parse(strs[1].Trim());
                        var z = double.Parse(strs[2].Trim());

                        outIrradianceValues.Add(new Vector3(x, y, z));
                    }
                }
            }

            DeleteDirectory(tempDirectory);

            error = "";
            return(true);
        }
Example #7
0
        public void PostRenderCommand(Vector position, float z_other, Vector bound, float rotate, Vector scale, HalfVector anchor, ByteVec4 color, bool vertical_flip, bool horizon_flip)
        {
            /*-----------------CURRENT VERSION------------------ -
             *   anchor(Hlaf)	    color(byte)         modelMatrix
             *   vec2(2)		        vec4(4)             Matrix3x2(6)
             */

            var is_xflip = Math.Sign(scale.X);
            var is_yflip = Math.Sign(scale.Y);

            //adjust scale transform which value is negative
            horizon_flip  = horizon_flip | (is_xflip < 0);
            vertical_flip = vertical_flip | (is_yflip < 0);
            float scalex = is_xflip * scale.X * bound.X;
            float scaley = is_yflip * scale.Y * bound.Y;

            //Create ModelMatrix
            float cosa = (float)Math.Cos(rotate);
            float sina = (float)Math.Sin(rotate);

            Matrix3x2 model = Matrix3x2.Zero;

            model.Row0.X = cosa * scalex;
            model.Row0.Y = -sina * scalex;
            model.Row1.X = sina * scaley;
            model.Row1.Y = cosa * scaley;

            model.Row2.X = position.X - RenderKernel.SB_WIDTH / 2f;
            model.Row2.Y = -position.Y + RenderKernel.SB_HEIGHT / 2f;

            unsafe
            {
                //Anchor write
                fixed(byte *ptr = &PostData[_currentPostBaseIndex])
                {
                    //anchor
                    int *hpv = (int *)(ptr + 0);

                    *hpv = *(int *)&anchor;

                    //color
                    int *ip = (int *)(ptr + 4);

                    *ip = *(int *)&color;

                    //flip write
                    Half *hp = (Half *)(ptr + 8);

                    hp[0] = horizon_flip ? HalfNegativeOne : HalfOne;
                    hp[1] = vertical_flip ? HalfNegativeOne : HalfOne;

                    var copyLen = 2 * 3 * sizeof(float);
                    var basePtr = (byte *)&model.Row0.X;

                    for (int i = 0; i < copyLen; i++)
                    {
                        ptr[i + 12] = *(basePtr + i);
                    }
                }
            }

            CurrentPostCount++;
            _currentPostBaseIndex += _VertexSize;
            if (CurrentPostCount >= Capacity)
            {
                FlushDraw();
            }
        }