Exemple #1
1
        private static Texture DecodeMultiframe(ImagingFactory imagingFactory, WicFlags flags, TextureDescription description, BitmapDecoder decoder)
        {
            var texture = new Texture(description);
              Guid dstFormat = ToWic(description.Format, false);

              for (int index = 0; index < description.ArraySize; ++index)
              {
            var image = texture.Images[index];
            using (var frame = decoder.GetFrame(index))
            {
              var pfGuid = frame.PixelFormat;
              var size = frame.Size;

              if (size.Width == description.Width && size.Height == description.Height)
              {
            // This frame does not need resized
            if (pfGuid == dstFormat)
            {
              frame.CopyPixels(image.Data, image.RowPitch);
            }
            else
            {
              using (var converter = new FormatConverter(imagingFactory))
              {
                converter.Initialize(frame, dstFormat, GetWicDither(flags), null, 0, BitmapPaletteType.Custom);
                converter.CopyPixels(image.Data, image.RowPitch);
              }
            }
              }
              else
              {
            // This frame needs resizing
            using (var scaler = new BitmapScaler(imagingFactory))
            {
              scaler.Initialize(frame, description.Width, description.Height, GetWicInterp(flags));

              Guid pfScaler = scaler.PixelFormat;
              if (pfScaler == dstFormat)
              {
                scaler.CopyPixels(image.Data, image.RowPitch);
              }
              else
              {
                // The WIC bitmap scaler is free to return a different pixel format than the source image, so here we
                // convert it to our desired format
                using (var converter = new FormatConverter(imagingFactory))
                {
                  converter.Initialize(scaler, dstFormat, GetWicDither(flags), null, 0, BitmapPaletteType.Custom);
                  converter.CopyPixels(image.Data, image.RowPitch);
                }
              }
            }
              }
            }
              }

              return texture;
        }
Exemple #2
0
        /// <summary>
        /// Initializes a new <see cref="Texture"/> from the specified <see cref="TextureDescription"/>.
        /// </summary>
        /// <param name="description">The <see cref="TextureDescription"/> to initialize from.</param>
        protected Texture(TextureDescription description)
        {
            Contract.Requires<ArgumentNullException>(description != null);
            Contract.Requires<ArgumentException>(Enum.IsDefined(typeof(TextureTarget), description.Target));

            this.Description = description;

            this.VerifyAccess();
            using (this.Bind(0))
            {
                // Set anisotropic filtering level and min and mag filter
                int linearMipmapLinear = Texture.linearMipmapLinear;
                int linear = Texture.linear;
                GL.TexParameterI(this.Target, TextureParameterName.TextureMinFilter, ref linearMipmapLinear);
                GL.TexParameterI(this.Target, TextureParameterName.TextureMagFilter, ref linear);

                if (VideoSettings.Default.AnisotropicFiltering && SupportsExtension("GL_EXT_texture_filter_anisotropic"))
                {
                    // User might want higher aniso level than the h/w supports.
                    float requestedAnisoLevel = VideoSettings.Default.AnisotropicLevel;
                    float maxSupportedAnisoLevel = GL.GetFloat((GetPName)OpenTK.Graphics.OpenGL.ExtTextureFilterAnisotropic.MaxTextureMaxAnisotropyExt);

                    GL.TexParameter(this.Target, anisoParameterName, Math.Min(requestedAnisoLevel, maxSupportedAnisoLevel));
                }

                GL.GenerateMipmap((GenerateMipmapTarget)this.Target);
            }
        }
Exemple #3
0
        public async Task<object> ReadAsync(ContentReadParameters parameters)
        {
            using (Bitmap bmp = new Bitmap(parameters.AssetStream))
            {
                BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, GDIPixelFormat.Format32bppArgb);
                try
                {
                    return await this.Dispatcher.Invoke((Func<CancellationToken, object>)(ct =>
                    {
                        ct.ThrowIfCancellationRequested();

                        TextureDescription desc = new TextureDescription(
                            data.Width, data.Height,
                            TextureDescription.GetMaxTextureLevels(data.Width, data.Height),
                            2,
                            (TextureTarget2d)(parameters.Parameter ?? TextureTarget2d.Texture2D),
                            PixelInternalFormat.Rgba
                        );
                        if (parameters.AssetType == typeof(Texture2D))
                        {
                            return Texture2D.Create(desc, data.Scan0, GLPixelFormat.Bgra, PixelType.UnsignedByte, data.Width, data.Height, 0, 0, 0);
                        }
                        else if (parameters.AssetType == typeof(Texture1DArray))
                        {
                            return Texture1DArray.Create(desc, data.Scan0, GLPixelFormat.Bgra, PixelType.UnsignedByte, data.Width, data.Height, 0, 0, 0);
                        }
                        else
                        {
                            throw new InvalidOperationException(
                                string.Format(
                                    "{0} can only load {1} and {2}, not {3}!",
                                    typeof(TextureReader).Name,
                                    typeof(Texture1DArray).Name,
                                    typeof(Texture2D).Name,
                                    parameters.AssetType.Name
                                )
                            );
                        }
                    }), DispatcherPriority.Normal, parameters.CancellationToken).ConfigureAwait(false);
                }
                finally
                {
                    bmp.UnlockBits(data);
                }
            }
        }
 private static TextureDescription New1D(int width, PixelFormat format, TextureFlags flags, int mipCount, int arraySize, GraphicsResourceUsage usage)
 {
     usage = (flags & TextureFlags.UnorderedAccess) != 0 ? GraphicsResourceUsage.Default : usage;
     var desc = new TextureDescription()
     {
         Dimension = TextureDimension.Texture1D,
         Width = width,
         Height = 1,
         Depth = 1,
         ArraySize = arraySize,
         Flags = flags,
         Format = format,
         MipLevels = Texture.CalculateMipMapCount(mipCount, width),
         Usage = Texture.GetUsageWithFlags(usage, flags),
     };
     return desc;
 }
        private static TextureDescription New3D(int width, int height, int depth, PixelFormat format, TextureFlags flags, int mipCount, GraphicsResourceUsage usage)
        {
            var desc = new TextureDescription()
            {
                Width = width,
                Height = height,
                Depth = depth,
                Flags = flags,
                Format = format,
                MipLevels = Texture.CalculateMipMapCount(mipCount, width, height, depth),
                Usage = Texture.GetUsageWithFlags(usage, flags),
                ArraySize = 1,
                Dimension = TextureDimension.Texture3D,
                MultiSampleLevel = MSAALevel.None
            };

            return desc;
        } 
        private static TextureDescription New2D(int width, int height, PixelFormat format, TextureFlags textureFlags, int mipCount, int arraySize, GraphicsResourceUsage usage)
        {
            if ((textureFlags & TextureFlags.UnorderedAccess) != 0)
                usage = GraphicsResourceUsage.Default;

            var desc = new TextureDescription()
            {
                Dimension = TextureDimension.Texture2D,
                Width = width,
                Height = height,
                Depth = 1,
                ArraySize = arraySize,
                MultiSampleLevel = MSAALevel.None,
                Flags = textureFlags,
                Format = format,
                MipLevels = Texture.CalculateMipMapCount(mipCount, width, height),
                Usage = Texture.GetUsageWithFlags(usage, textureFlags),
            };
            return desc;
        }
            protected override void DrawCore(RenderContext context, RenderDrawContext drawContext)
            {
                if (!IsIncrustEnabled)
                {
                    return;
                }

                using (context.PushRenderViewAndRestore(RenderView))
                    using (drawContext.PushTagAndRestore(CameraComponentRendererExtensions.Current, Camera))
                    {
                        var oldViewport = drawContext.CommandList.Viewport;

                        // Allocate a RT for the incrust
                        GeneratedIncrust = drawContext.GraphicsContext.Allocator.GetTemporaryTexture2D(TextureDescription.New2D((int)Viewport.Width, (int)Viewport.Height, 1, drawContext.CommandList.RenderTarget.Format, TextureFlags.ShaderResource | TextureFlags.RenderTarget));
                        var depthBuffer = drawContext.CommandList.DepthStencilBuffer != null?drawContext.GraphicsContext.Allocator.GetTemporaryTexture2D(TextureDescription.New2D((int)Viewport.Width, (int)Viewport.Height, 1, drawContext.CommandList.DepthStencilBuffer.Format, TextureFlags.DepthStencil)) : null;

                        // Push and set render target
                        using (drawContext.PushRenderTargetsAndRestore())
                        {
                            drawContext.CommandList.SetRenderTarget(depthBuffer, GeneratedIncrust);

                            drawContext.CommandList.SetViewport(Viewport);
                            Content.Draw(drawContext);

                            drawContext.CommandList.SetViewport(oldViewport);
                        }

                        // Note: GeneratedIncrust is released by RenderIncrustCompositorPart
                        if (depthBuffer != null)
                        {
                            drawContext.GraphicsContext.Allocator.ReleaseReference(depthBuffer);
                        }
                    }
            }
 protected override Texture CreateTextureCore(ref TextureDescription description)
 {
     return(new D3D11Texture(_device, ref description));
 }
Exemple #9
0
        private void StreamingTask(int residency)
        {
            if (cancellationToken.IsCancellationRequested)
            {
                return;
            }

            // Cache data
            var mipsChange = residency - CurrentResidency;
            var mipsCount  = residency;

            Debug.Assert(mipsChange != 0, $"mipsChange[{mipsChange}] != 0");

            if (residency == 0)
            {
                // Release
                Manager.RegisterMemoryUsage(-texture.SizeInBytes);
                texture.ReleaseData();
                residentMips = 0;
                return;
            }

            try
            {
                Storage.LockChunks();

                // Setup texture description
                TextureDescription newDesc     = description;
                var newHighestResidentMipIndex = TotalMipLevels - mipsCount;
                newDesc.MipLevels = mipsCount;
                var topMip = mipInfos[description.MipLevels - newDesc.MipLevels];
                newDesc.Width  = topMip.Width;
                newDesc.Height = topMip.Height;

                // Load chunks
                var mipsData = new IntPtr[mipsCount];
                for (var mipIndex = 0; mipIndex < mipsCount; mipIndex++)
                {
                    var totalMipIndex = newHighestResidentMipIndex + mipIndex;
                    var chunk         = Storage.GetChunk(totalMipIndex);
                    if (chunk == null)
                    {
                        throw new ContentStreamingException("Data chunk is missing.", Storage);
                    }

                    if (chunk.Size != mipInfos[totalMipIndex].TotalSize)
                    {
                        throw new ContentStreamingException("Data chunk has invalid size.", Storage);
                    }

                    var data = chunk.GetData(fileProvider);
                    if (!chunk.IsLoaded)
                    {
                        throw new ContentStreamingException("Data chunk is not loaded.", Storage);
                    }

                    if (cancellationToken.IsCancellationRequested)
                    {
                        return;
                    }

                    mipsData[mipIndex] = data;
                }

                // Get data boxes
                var dataBoxIndex = 0;
                var dataBoxes    = new DataBox[newDesc.MipLevels * newDesc.ArraySize];
                for (var arrayIndex = 0; arrayIndex < newDesc.ArraySize; arrayIndex++)
                {
                    for (var mipIndex = 0; mipIndex < mipsCount; mipIndex++)
                    {
                        var totalMipIndex = newHighestResidentMipIndex + mipIndex;
                        var info          = mipInfos[totalMipIndex];

                        dataBoxes[dataBoxIndex].DataPointer = mipsData[mipIndex] + info.SlicePitch * arrayIndex;
                        dataBoxes[dataBoxIndex].RowPitch    = info.RowPitch;
                        dataBoxes[dataBoxIndex].SlicePitch  = info.SlicePitch;
                        dataBoxIndex++;
                    }
                }

                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                // Create texture (use staging object and swap it on sync)
                textureToSync = Texture.New(texture.GraphicsDevice, newDesc, new TextureViewDescription(), dataBoxes);
                textureToSync.FullQualitySize = texture.FullQualitySize;

                residentMips = newDesc.MipLevels;
            }
            finally
            {
                Storage.UnlockChunks();
            }
        }
Exemple #10
0
 /// <summary>
 /// Creates a new <see cref="Texture"/>.
 /// </summary>
 /// <param name="description">The desired properties of the created object.</param>
 /// <returns>A new <see cref="Texture"/>.</returns>
 public Texture CreateTexture(TextureDescription description) => CreateTexture(ref description);
Exemple #11
0
        private static Texture CopyImage(BinaryReader reader, TextureDescription description, ComputePitchFlags cpFlags, ConversionFlags convFlags, uint[] pal8)
        {
            if (reader == null)
            throw new ArgumentNullException("reader");

              if ((convFlags & ConversionFlags.Expand) != 0)
              {
            if ((convFlags & ConversionFlags.Format888) != 0)
              cpFlags |= ComputePitchFlags.Bpp24;
            else if ((convFlags & (ConversionFlags.Format565 | ConversionFlags.Format5551 | ConversionFlags.Format4444 | ConversionFlags.Format8332 | ConversionFlags.FormatA8P8 | ConversionFlags.FormatL16 | ConversionFlags.FormatA8L8)) != 0)
              cpFlags |= ComputePitchFlags.Bpp16;
            else if ((convFlags & (ConversionFlags.Format44 | ConversionFlags.Format332 | ConversionFlags.Pal8 | ConversionFlags.FormatL8)) != 0)
              cpFlags |= ComputePitchFlags.Bpp8;
              }

              var texture = new Texture(description);
              description = texture.Description;  // MipLevel may have been set.

              ScanlineFlags tflags = (convFlags & ConversionFlags.NoAlpha) != 0 ? ScanlineFlags.SetAlpha : 0;
              if ((convFlags & ConversionFlags.Swizzle) != 0)
            tflags |= ScanlineFlags.Legacy;

              switch (description.Dimension)
              {
            case TextureDimension.Texture1D:
            case TextureDimension.Texture2D:
            case TextureDimension.TextureCube:
              {
            int index = 0;
            for (int item = 0; item < description.ArraySize; ++item)
            {
              int width = description.Width;
              int height = description.Height;

              for (int level = 0; level < description.MipLevels; ++level, ++index)
              {
                int sRowPitch, sSlicePitch;
                TextureHelper.ComputePitch(description.Format, width, height, out sRowPitch, out sSlicePitch, cpFlags);

                var image = texture.Images[index];
                if (TextureHelper.IsBCn(description.Format) || TextureHelper.IsPlanar(description.Format))
                {
                  reader.Read(image.Data, 0, image.Data.Length);
                }
                else
                {
                  using (var stream = new MemoryStream(image.Data))
                  using (var writer = new BinaryWriter(stream))
                  {
                    for (int h = 0; h < height; ++h)
                    {
                      if ((convFlags & ConversionFlags.Expand) != 0)
                      {
                        if ((convFlags & (ConversionFlags.Format565 | ConversionFlags.Format5551 | ConversionFlags.Format4444)) != 0)
                        {
                          if (!TextureHelper.ExpandScanline(reader, sRowPitch, (convFlags & ConversionFlags.Format565) != 0 ? DataFormat.B5G6R5_UNORM : DataFormat.B5G5R5A1_UNORM, writer, image.RowPitch, DataFormat.R8G8B8A8_UNORM, tflags))
                            throw new InvalidDataException("Unable to expand format.");
                        }
                        else
                        {
                          LegacyFormat lformat = FindLegacyFormat(convFlags);
                          if (!LegacyExpandScanline(reader, sRowPitch, lformat, writer, image.RowPitch, description.Format, pal8, tflags))
                            throw new InvalidDataException("Unable to expand legacy format.");
                        }
                      }
                      else if ((convFlags & ConversionFlags.Swizzle) != 0)
                      {
                        TextureHelper.SwizzleScanline(reader, sRowPitch, writer, image.RowPitch, description.Format, tflags);
                      }
                      else
                      {
                        TextureHelper.CopyScanline(reader, sRowPitch, writer, image.RowPitch, description.Format, tflags);
                      }
                    }
                  }
                }

                if (width > 1)
                  width >>= 1;

                if (height > 1)
                  height >>= 1;
              }
            }
              }
              break;

            case TextureDimension.Texture3D:
              {
            int index = 0;

            int width = description.Width;
            int height = description.Height;
            int depth = description.Depth;

            for (int level = 0; level < description.MipLevels; ++level)
            {
              int sRowPitch, sSlicePitch;
              TextureHelper.ComputePitch(description.Format, width, height, out sRowPitch, out sSlicePitch, cpFlags);

              for (int slice = 0; slice < depth; ++slice, ++index)
              {
                // We use the same memory organization that Direct3D 11 needs for D3D11_SUBRESOURCE_DATA
                // with all slices of a given miplevel being continuous in memory
                var image = texture.Images[index];

                if (TextureHelper.IsBCn(description.Format))
                {
                  reader.Read(image.Data, 0, image.Data.Length);
                }
                else if (TextureHelper.IsPlanar(description.Format))
                {
                  // Direct3D does not support any planar formats for Texture3D
                  throw new NotSupportedException("Planar texture formats are not support for volume textures.");
                }
                else
                {
                  using (var stream = new MemoryStream(image.Data))
                  using (var writer = new BinaryWriter(stream))
                  {
                    for (int h = 0; h < height; ++h)
                    {
                      if ((convFlags & ConversionFlags.Expand) != 0)
                      {
                        if ((convFlags & (ConversionFlags.Format565 | ConversionFlags.Format5551 | ConversionFlags.Format4444)) != 0)
                        {
                          if (!TextureHelper.ExpandScanline(reader, sRowPitch, (convFlags & ConversionFlags.Format565) != 0 ? DataFormat.B5G6R5_UNORM : DataFormat.B5G5R5A1_UNORM, writer, image.RowPitch, DataFormat.R8G8B8A8_UNORM, tflags))
                            throw new InvalidDataException("Unable to expand format.");
                        }
                        else
                        {
                          LegacyFormat lformat = FindLegacyFormat(convFlags);
                          if (!LegacyExpandScanline(reader, sRowPitch, lformat, writer, image.RowPitch, description.Format, pal8, tflags))
                            throw new InvalidDataException("Unable to expand legacy format.");
                        }
                      }
                      else if ((convFlags & ConversionFlags.Swizzle) != 0)
                      {
                        TextureHelper.SwizzleScanline(reader, sRowPitch, writer, image.RowPitch, description.Format, tflags);
                      }
                      else
                      {
                        TextureHelper.CopyScanline(reader, sRowPitch, writer, image.RowPitch, description.Format, tflags);
                      }
                    }
                  }
                }
              }

              if (width > 1)
                width >>= 1;

              if (height > 1)
                height >>= 1;

              if (depth > 1)
                depth >>= 1;
            }
              }
              break;

            default:
              throw new NotSupportedException("The specified texture dimension is not supported.");
              }

              return texture;
        }
Exemple #12
0
        private static void EncodeDDSHeader(BinaryWriter writer, TextureDescription description, DdsFlags flags)
        {
            if (!TextureHelper.IsValidDds(description.Format))
            throw new ArgumentException("Invalid texture format.", "description");

              if (TextureHelper.IsPalettized(description.Format))
            throw new NotSupportedException("Palettized texture formats are not supported.");

              if (description.ArraySize > 1)
              {
            if (description.ArraySize != 6 || description.Dimension != TextureDimension.Texture2D || description.Dimension != TextureDimension.TextureCube)
            {
              // Texture1D arrays, Texture2D arrays, and TextureCube arrays must be stored using 'DX10' extended header
              flags |= DdsFlags.ForceDX10Ext;
            }
              }

              if ((flags & DdsFlags.ForceDX10ExtMisc2) != 0)
            flags |= DdsFlags.ForceDX10Ext;

              PixelFormat ddpf = default(PixelFormat);
              if ((flags & DdsFlags.ForceDX10Ext) == 0)
              {
            switch (description.Format)
            {
              case DataFormat.R8G8B8A8_UNORM:
            ddpf = PixelFormat.A8B8G8R8;
            break;
              case DataFormat.R16G16_UNORM:
            ddpf = PixelFormat.G16R16;
            break;
              case DataFormat.R8G8_UNORM:
            ddpf = PixelFormat.A8L8;
            break;
              case DataFormat.R16_UNORM:
            ddpf = PixelFormat.L16;
            break;
              case DataFormat.R8_UNORM:
            ddpf = PixelFormat.L8;
            break;
              case DataFormat.A8_UNORM:
            ddpf = PixelFormat.A8;
            break;
              case DataFormat.R8G8_B8G8_UNORM:
            ddpf = PixelFormat.R8G8_B8G8;
            break;
              case DataFormat.G8R8_G8B8_UNORM:
            ddpf = PixelFormat.G8R8_G8B8;
            break;
              case DataFormat.BC1_UNORM:
            ddpf = PixelFormat.DXT1;
            break;
              case DataFormat.BC2_UNORM:
            ddpf = /* (description.AlphaMode == AlphaMode.Premultiplied) ? PixelFormat.DXT2 : */ PixelFormat.DXT3;
            break;
              case DataFormat.BC3_UNORM:
            ddpf = /* (description.AlphaMode == AlphaMode.Premultiplied) ? PixelFormat.DXT2 : */ PixelFormat.DXT5;
            break;
              case DataFormat.BC4_UNORM:
            ddpf = PixelFormat.BC4_UNorm;
            break;
              case DataFormat.BC4_SNORM:
            ddpf = PixelFormat.BC4_SNorm;
            break;
              case DataFormat.BC5_UNORM:
            ddpf = PixelFormat.BC5_UNorm;
            break;
              case DataFormat.BC5_SNORM:
            ddpf = PixelFormat.BC5_SNorm;
            break;
              case DataFormat.B5G6R5_UNORM:
            ddpf = PixelFormat.R5G6B5;
            break;
              case DataFormat.B5G5R5A1_UNORM:
            ddpf = PixelFormat.A1R5G5B5;
            break;
              case DataFormat.R8G8_SNORM:
            ddpf = PixelFormat.V8U8;
            break;
              case DataFormat.R8G8B8A8_SNORM:
            ddpf = PixelFormat.Q8W8V8U8;
            break;
              case DataFormat.R16G16_SNORM:
            ddpf = PixelFormat.V16U16;
            break;
              case DataFormat.B8G8R8A8_UNORM:
            ddpf = PixelFormat.A8R8G8B8;
            break; // DXGI 1.1
              case DataFormat.B8G8R8X8_UNORM:
            ddpf = PixelFormat.X8R8G8B8;
            break; // DXGI 1.1
              //#if DIRECTX11_1
              case DataFormat.B4G4R4A4_UNORM:
            ddpf = PixelFormat.A4R4G4B4;
            break;
              case DataFormat.YUY2:
            ddpf = PixelFormat.YUY2;
            break;
              //#endif
              // Legacy D3DX formats using D3DFMT enum value as FourCC
              case DataFormat.R32G32B32A32_FLOAT:
            ddpf.Size = Marshal.SizeOf(typeof(PixelFormat));
            ddpf.Flags = PixelFormatFlags.FourCC;
            ddpf.FourCC = 116; // D3DFMT_A32B32G32R32F
            break;
              case DataFormat.R16G16B16A16_FLOAT:
            ddpf.Size = Marshal.SizeOf(typeof(PixelFormat));
            ddpf.Flags = PixelFormatFlags.FourCC;
            ddpf.FourCC = 113; // D3DFMT_A16B16G16R16F
            break;
              case DataFormat.R16G16B16A16_UNORM:
            ddpf.Size = Marshal.SizeOf(typeof(PixelFormat));
            ddpf.Flags = PixelFormatFlags.FourCC;
            ddpf.FourCC = 36; // D3DFMT_A16B16G16R16
            break;
              case DataFormat.R16G16B16A16_SNORM:
            ddpf.Size = Marshal.SizeOf(typeof(PixelFormat));
            ddpf.Flags = PixelFormatFlags.FourCC;
            ddpf.FourCC = 110; // D3DFMT_Q16W16V16U16
            break;
              case DataFormat.R32G32_FLOAT:
            ddpf.Size = Marshal.SizeOf(typeof(PixelFormat));
            ddpf.Flags = PixelFormatFlags.FourCC;
            ddpf.FourCC = 115; // D3DFMT_G32R32F
            break;
              case DataFormat.R16G16_FLOAT:
            ddpf.Size = Marshal.SizeOf(typeof(PixelFormat));
            ddpf.Flags = PixelFormatFlags.FourCC;
            ddpf.FourCC = 112; // D3DFMT_G16R16F
            break;
              case DataFormat.R32_FLOAT:
            ddpf.Size = Marshal.SizeOf(typeof(PixelFormat));
            ddpf.Flags = PixelFormatFlags.FourCC;
            ddpf.FourCC = 114; // D3DFMT_R32F
            break;
              case DataFormat.R16_FLOAT:
            ddpf.Size = Marshal.SizeOf(typeof(PixelFormat));
            ddpf.Flags = PixelFormatFlags.FourCC;
            ddpf.FourCC = 111; // D3DFMT_R16F
            break;
            }
              }

              writer.Write(MagicHeader);

              var header = new Header();
              header.Size = Marshal.SizeOf(typeof(Header));
              header.Flags = HeaderFlags.Texture;
              header.SurfaceFlags = SurfaceFlags.Texture;

              if (description.MipLevels > 0)
              {
            header.Flags |= HeaderFlags.Mipmap;
            header.MipMapCount = description.MipLevels;

            if (header.MipMapCount > 1)
              header.SurfaceFlags |= SurfaceFlags.Mipmap;
              }

              switch (description.Dimension)
              {
            case TextureDimension.Texture1D:
              header.Height = description.Height;
              header.Width = header.Depth = 1;
              break;

            case TextureDimension.Texture2D:
            case TextureDimension.TextureCube:
              header.Height = description.Height;
              header.Width = description.Width;
              header.Depth = 1;

              if (description.Dimension == TextureDimension.TextureCube)
              {
            header.SurfaceFlags |= SurfaceFlags.Cubemap;
            header.CubemapFlags |= CubemapFlags.AllFaces;
              }
              break;

            case TextureDimension.Texture3D:
              header.Flags |= HeaderFlags.Volume;
              header.CubemapFlags |= CubemapFlags.Volume;
              header.Height = description.Height;
              header.Width = description.Width;
              header.Depth = description.Depth;
              break;

            default:
              throw new NotSupportedException("The specified texture dimension is not supported.");
              }

              int rowPitch, slicePitch;
              TextureHelper.ComputePitch(description.Format, description.Width, description.Height, out rowPitch, out slicePitch);

              if (TextureHelper.IsBCn(description.Format))
              {
            header.Flags |= HeaderFlags.LinearSize;
            header.PitchOrLinearSize = slicePitch;
              }
              else
              {
            header.Flags |= HeaderFlags.Pitch;
            header.PitchOrLinearSize = rowPitch;
              }

              if (ddpf.Size != 0)
              {
            header.PixelFormat = ddpf;
            writer.BaseStream.WriteStruct(header);
              }
              else
              {
            header.PixelFormat = PixelFormat.DX10;

            var ext = new HeaderDXT10();
            ext.DXGIFormat = description.Format;
            switch (description.Dimension)
            {
              case TextureDimension.Texture1D:
            ext.ResourceDimension = ResourceDimension.Texture1D;
            break;
              case TextureDimension.Texture2D:
              case TextureDimension.TextureCube:
            ext.ResourceDimension = ResourceDimension.Texture2D;
            break;
              case TextureDimension.Texture3D:
            ext.ResourceDimension = ResourceDimension.Texture3D;
            break;
            }

            if (description.Dimension == TextureDimension.TextureCube)
            {
              ext.MiscFlags |= ResourceOptionFlags.TextureCube;
              ext.ArraySize = description.ArraySize / 6;
            }
            else
            {
              ext.ArraySize = description.ArraySize;
            }

            if ((flags & DdsFlags.ForceDX10ExtMisc2) != 0)
            {
              // This was formerly 'reserved'. D3DX10 and D3DX11 will fail if this value is anything other than 0.
              //ext.MiscFlags2 = description.MiscFlags2;
              throw new NotImplementedException("DdsFlags.ForceDX10ExtMisc2 is not implemented.");
            }

            writer.BaseStream.WriteStruct(header);
            writer.BaseStream.WriteStruct(ext);
              }
        }
Exemple #13
0
 /// <summary>
 /// Gets a render target with the specified description, scoped for the duration of the <see cref="DrawEffect.DrawCore"/>.
 /// </summary>
 /// <returns>A new instance of texture.</returns>
 protected Texture NewScopedRenderTarget2D(TextureDescription description)
 {
     // TODO: Check if we should introduce an enum for the kind of scope (per DrawCore, per Frame...etc.)
     CheckIsInDrawCore();
     return(PushScopedResource(Context.Allocator.GetTemporaryTexture2D(description)));
 }
Exemple #14
0
        private static ImageCollection CreateImageCollection(TextureDescription description, bool skipMipLevel0 = false)
        {
            int numberOfImages, pixelSize;
              DetermineImages(description, out numberOfImages, out pixelSize);
              var images = new ImageCollection(numberOfImages);

              int index = 0;
              switch (description.Dimension)
              {
            case TextureDimension.Texture1D:
            case TextureDimension.Texture2D:
            case TextureDimension.TextureCube:
              Debug.Assert(description.ArraySize != 0);
              Debug.Assert(description.MipLevels > 0);

              for (int item = 0; item < description.ArraySize; item++)
              {
            int w = description.Width;
            int h = description.Height;

            for (int level = 0; level < description.MipLevels; level++)
            {
              if (!skipMipLevel0 || level != 0)
                images[index] = new Image(w, h, description.Format);

              index++;

              if (h > 1)
                h >>= 1;

              if (w > 1)
                w >>= 1;
            }
              }
              break;

            case TextureDimension.Texture3D:
              {
            Debug.Assert(description.MipLevels > 0);
            Debug.Assert(description.Depth > 0);

            int w = description.Width;
            int h = description.Height;
            int d = description.Depth;

            for (int level = 0; level < description.MipLevels; level++)
            {
              for (int slice = 0; slice < d; slice++)
              {
                // We use the same memory organization that Direct3D 11 needs for D3D11_SUBRESOURCE_DATA
                // with all slices of a given mip level being continuous in memory.
                if (!skipMipLevel0 || level != 0)
                  images[index] = new Image(w, h, description.Format);

                index++;
              }

              if (h > 1)
                h >>= 1;

              if (w > 1)
                w >>= 1;

              if (d > 1)
                d >>= 1;
            }
              }
              break;

            default:
              Debug.Fail("Unexpected texture dimension");
              break;
              }

              return images;
        }
Exemple #15
0
        public D3D11Texture(Device device, ref TextureDescription description)
        {
            Width       = description.Width;
            Height      = description.Height;
            Depth       = description.Depth;
            MipLevels   = description.MipLevels;
            ArrayLayers = description.ArrayLayers;
            Format      = description.Format;
            Usage       = description.Usage;
            SampleCount = description.SampleCount;

            DxgiFormat = D3D11Formats.ToDxgiFormat(
                description.Format,
                (description.Usage & TextureUsage.DepthStencil) == TextureUsage.DepthStencil);

            CpuAccessFlags cpuFlags      = CpuAccessFlags.None;
            ResourceUsage  resourceUsage = ResourceUsage.Default;
            BindFlags      bindFlags     = BindFlags.None;

            if ((description.Usage & TextureUsage.RenderTarget) == TextureUsage.RenderTarget)
            {
                bindFlags |= BindFlags.RenderTarget;
            }
            if ((description.Usage & TextureUsage.DepthStencil) == TextureUsage.DepthStencil)
            {
                bindFlags |= BindFlags.DepthStencil;
            }
            if ((description.Usage & TextureUsage.Sampled) == TextureUsage.Sampled)
            {
                bindFlags |= BindFlags.ShaderResource;
            }
            if ((description.Usage & TextureUsage.Storage) == TextureUsage.Storage)
            {
                bindFlags |= BindFlags.UnorderedAccess;
            }
            if ((description.Usage & TextureUsage.Staging) == TextureUsage.Staging)
            {
                cpuFlags      = CpuAccessFlags.Read | CpuAccessFlags.Write;
                resourceUsage = ResourceUsage.Staging;
            }

            ResourceOptionFlags optionFlags = ResourceOptionFlags.None;
            int arraySize = (int)description.ArrayLayers;

            if ((description.Usage & TextureUsage.Cubemap) == TextureUsage.Cubemap)
            {
                optionFlags = ResourceOptionFlags.TextureCube;
                arraySize  *= 6;
            }

            Texture2DDescription deviceDescription = new Texture2DDescription()
            {
                Width             = (int)description.Width,
                Height            = (int)description.Height,
                MipLevels         = (int)description.MipLevels,
                ArraySize         = arraySize,
                Format            = DxgiFormat,
                BindFlags         = bindFlags,
                CpuAccessFlags    = cpuFlags,
                Usage             = resourceUsage,
                SampleDescription = new SharpDX.DXGI.SampleDescription((int)FormatHelpers.GetSampleCountUInt32(SampleCount), 0),
                OptionFlags       = optionFlags,
            };

            DeviceTexture = new Texture2D(device, deviceDescription);
        }
 /// <summary>
 /// Gets a <see cref="Texture" /> output for the specified description.
 /// </summary>
 /// <param name="allocator">The allocator.</param>
 /// <param name="description">The description.</param>
 /// <returns>A new instance of <see cref="Texture" /> class.</returns>
 public static Texture GetTemporaryTexture2D(this GraphicsResourceAllocator allocator, TextureDescription description)
 {
     return allocator.GetTemporaryTexture(description);
 }
Exemple #17
0
        /// <summary>
        /// Decodes the TGA file header.
        /// </summary>
        /// <param name="stream">The stream.</param>
        /// <param name="offset">The offset in the stream at which the data starts.</param>
        /// <param name="convFlags">The conversion flags.</param>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="stream"/> is <see langword="null"/>.
        /// </exception>
        /// <exception cref="InvalidDataException">
        /// Invalid data.
        /// </exception>
        /// <exception cref="NotSupportedException">
        /// The specified format is not supported.
        /// </exception>
        private static TextureDescription DecodeTGAHeader(Stream stream, out int offset, out ConversionFlags convFlags)
        {
            if (stream == null)
            throw new ArgumentNullException("stream");

              TextureDescription description = new TextureDescription
              {
            Dimension = TextureDimension.Texture2D,
            Format = DataFormat.R8G8B8A8_UNORM,
              };

              offset = 0;
              convFlags = ConversionFlags.None;

              long size = stream.Length - stream.Position;
              int sizeOfTGAHeader = Marshal.SizeOf(typeof(Header));
              if (size < sizeOfTGAHeader)
            throw new InvalidDataException("The TGA file is corrupt.");

              var header = stream.ReadStruct<Header>();
              if (header.ColorMapType != 0 || header.ColorMapLength != 0)
            throw new NotSupportedException("TGA files with color maps are not supported.");

              if ((header.Descriptor & (DescriptorFlags.Interleaved2Way | DescriptorFlags.Interleaved4Way)) != 0)
            throw new NotSupportedException("TGA files with interleaved images are not supported.");

              if (header.Width == 0 || header.Height == 0)
            throw new NotSupportedException("The TGA file is corrupt. Width and height are invalid.");

              switch (header.ImageType)
              {
            case ImageType.TrueColor:
            case ImageType.TrueColorRLE:
              switch (header.BitsPerPixel)
              {
            case 16:
              description.Format = DataFormat.B5G5R5A1_UNORM;
              break;
            case 24:
              description.Format = DataFormat.R8G8B8A8_UNORM;
              convFlags |= ConversionFlags.Expand;
              // We could use DXGI_FORMAT_B8G8R8X8_UNORM, but we prefer DXGI 1.0 formats
              break;
            case 32:
              description.Format = DataFormat.R8G8B8A8_UNORM;
              // We could use DXGI.Format.B8G8R8A8_UNORM, but we prefer DXGI 1.0 formats
              break;
              }

              if (header.ImageType == ImageType.TrueColorRLE)
            convFlags |= ConversionFlags.RLE;
              break;

            case ImageType.BlackAndWhite:
            case ImageType.BlackAndWhiteRLE:
              switch (header.BitsPerPixel)
              {
            case 8:
              description.Format = DataFormat.R8_UNORM;
              break;
            default:
              throw new NotSupportedException("The black-and-white format used by the TGA file is not supported. Only 8-bit black-and-white images are supported.");
              }

              if (header.ImageType == ImageType.BlackAndWhiteRLE)
            convFlags |= ConversionFlags.RLE;
              break;

            case ImageType.NoImage:
            case ImageType.ColorMapped:
            case ImageType.ColorMappedRLE:
              throw new NotSupportedException("The image format used by the TGA file is not supported.");
            default:
              throw new InvalidDataException("Unknown image format used by the TGA file.");
              }

              description.Width = header.Width;
              description.Height = header.Height;
              description.Depth = 1;
              description.MipLevels = 1;
              description.ArraySize = 1;

              if ((header.Descriptor & DescriptorFlags.InvertX) != 0)
            convFlags |= ConversionFlags.InvertX;

              if ((header.Descriptor & DescriptorFlags.InvertY) != 0)
            convFlags |= ConversionFlags.InvertY;

              offset = sizeOfTGAHeader;
              if (header.IDLength != 0)
            offset += header.IDLength;
              return description;
        }
 internal TextureCube(GraphicsDevice device, TextureDescription description2D) : base(device, description2D, null)
 {
 }
 internal TextureCube(GraphicsDevice device, TextureDescription description2D, params DataBox[] dataBoxes) : base(device, description2D, dataBoxes)
 {
 }
Exemple #20
0
 protected internal Texture1D(GraphicsDevice device, TextureDescription description1D, DataBox[] dataBox = null)
     : base(device, description1D)
 {
 }
Exemple #21
0
        private static TextureDescription DecodeMetadata(ImagingFactory imagingFactory, WicFlags flags, BitmapDecoder decoder, BitmapFrameDecode frame, out Guid pixelFormat)
        {
            var size = frame.Size;

              var description = new TextureDescription
              {
            Dimension = TextureDimension.Texture2D,
            Width = size.Width,
            Height = size.Height,
            Depth = 1,
            MipLevels = 1,
            ArraySize = (flags & WicFlags.AllFrames) != 0 ? decoder.FrameCount : 1,
            Format = DetermineFormat(imagingFactory, frame.PixelFormat, flags, out pixelFormat)
              };

              if (description.Format == DataFormat.Unknown)
            throw new NotSupportedException("The pixel format is not supported.");

              if ((flags & WicFlags.IgnoreSrgb) == 0)
              {
            // Handle sRGB.
            #pragma warning disable 168
            try
            {
              Guid containerFormat = decoder.ContainerFormat;
              var metareader = frame.MetadataQueryReader;
              if (metareader != null)
              {
            // Check for sRGB color space metadata.
            bool sRgb = false;

            if (containerFormat == ContainerFormatGuids.Png)
            {
              // Check for sRGB chunk.
              if (metareader.GetMetadataByName("/sRGB/RenderingIntent") != null)
                sRgb = true;
            }
            else if (containerFormat == ContainerFormatGuids.Jpeg)
            {
              if (Equals(metareader.GetMetadataByName("/app1/ifd/exif/{ushort=40961}"), 1))
                sRgb = true;
            }
            else if (containerFormat == ContainerFormatGuids.Tiff)
            {
              if (Equals(metareader.GetMetadataByName("/ifd/exif/{ushort=40961}"), 1))
                sRgb = true;
            }
            else
            {
              if (Equals(metareader.GetMetadataByName("System.Image.ColorSpace"), 1))
                sRgb = true;
            }

            if (sRgb)
              description.Format = TextureHelper.MakeSRgb(description.Format);
              }
            }
            // ReSharper disable once EmptyGeneralCatchClause
            catch (Exception exception)
            {
              // Some formats just don't support metadata (BMP, ICO, etc.).
            }
              }
            #pragma warning restore 168

              return description;
        }
Exemple #22
0
        private void DrawInternal(RenderDrawContext context, RenderView renderView, RenderViewStage renderViewStage, int startIndex, int endIndex)
        {
            base.Draw(context, renderView, renderViewStage, startIndex, endIndex);

            var uiProcessor = SceneInstance.GetCurrent(context.RenderContext).GetProcessor <UIRenderProcessor>();

            if (uiProcessor == null)
            {
                return;
            }


            // build the list of the UI elements to render
            uiElementStates.Clear();
            for (var index = startIndex; index < endIndex; index++)
            {
                var renderNodeReference = renderViewStage.SortedRenderNodes[index].RenderNode;
                var renderNode          = GetRenderNode(renderNodeReference);
                var renderElement       = (RenderUIElement)renderNode.RenderObject;

                uiElementStates.Add(new UIElementState(renderElement));
            }

            // evaluate the current draw time (game instance is null for thumbnails)
            var drawTime = game != null ? game.DrawTime : new GameTime();

            // update the rendering context
            renderingContext.GraphicsContext = context.GraphicsContext;
            renderingContext.Time            = drawTime;
            renderingContext.RenderTarget    = context.CommandList.RenderTargets[0]; // TODO: avoid hardcoded index 0

            // Prepare content required for Picking and MouseOver events
            PickingPrepare();

            // allocate temporary graphics resources if needed
            Texture scopedDepthBuffer = null;

            foreach (var uiElement in uiElementStates)
            {
                if (uiElement.RenderObject.IsFullScreen)
                {
                    var renderTarget = renderingContext.RenderTarget;
                    var description  = TextureDescription.New2D(renderTarget.Width, renderTarget.Height, PixelFormat.D24_UNorm_S8_UInt, TextureFlags.DepthStencil);
                    scopedDepthBuffer = context.RenderContext.Allocator.GetTemporaryTexture(description);
                    break;
                }
            }

            // see UIElementUnderMouseCursor property
            UIElement elementUnderMouseCursor = null;


            // update view parameters and perform UI picking
            foreach (var uiElementState in uiElementStates)
            {
                var renderObject = uiElementState.RenderObject;
                var rootElement  = renderObject.Page?.RootElement;
                if (rootElement == null)
                {
                    continue;
                }

                UIElement loopedElementUnderMouseCursor = null;

                // calculate the size of the virtual resolution depending on target size (UI canvas)
                var virtualResolution = renderObject.Resolution;

                if (renderObject.IsFullScreen)
                {
                    //var targetSize = viewportSize;
                    var targetSize = new Vector2(renderingContext.RenderTarget.Width, renderingContext.RenderTarget.Height);

                    // update the virtual resolution of the renderer
                    if (renderObject.ResolutionStretch == ResolutionStretch.FixedWidthAdaptableHeight)
                    {
                        virtualResolution.Y = virtualResolution.X * targetSize.Y / targetSize.X;
                    }
                    if (renderObject.ResolutionStretch == ResolutionStretch.FixedHeightAdaptableWidth)
                    {
                        virtualResolution.X = virtualResolution.Y * targetSize.X / targetSize.Y;
                    }

                    uiElementState.Update(renderObject, virtualResolution);
                }
                else
                {
                    var cameraComponent = context.RenderContext.Tags.Get(CameraComponentRendererExtensions.Current);
                    if (cameraComponent != null)
                    {
                        uiElementState.Update(renderObject, cameraComponent);
                    }
                }


                // Check if the current UI component is being picked based on the current ViewParameters (used to draw this element)
                using (Profiler.Begin(UIProfilerKeys.TouchEventsUpdate))
                {
                    PickingUpdate(uiElementState.RenderObject, context.CommandList.Viewport, ref uiElementState.WorldViewProjectionMatrix, drawTime, ref loopedElementUnderMouseCursor);

                    // only update result element, when this one has a value
                    if (loopedElementUnderMouseCursor != null)
                    {
                        elementUnderMouseCursor = loopedElementUnderMouseCursor;
                    }
                }
            }
            UIElementUnderMouseCursor = elementUnderMouseCursor;

            // render the UI elements of all the entities
            foreach (var uiElementState in uiElementStates)
            {
                var renderObject = uiElementState.RenderObject;
                var rootElement  = renderObject.Page?.RootElement;
                if (rootElement == null)
                {
                    continue;
                }

                var updatableRootElement = (IUIElementUpdate)rootElement;
                var virtualResolution    = renderObject.Resolution;

                // update the rendering context values specific to this element
                renderingContext.Resolution           = virtualResolution;
                renderingContext.ViewProjectionMatrix = uiElementState.WorldViewProjectionMatrix;
                renderingContext.DepthStencilBuffer   = renderObject.IsFullScreen ? scopedDepthBuffer : context.CommandList.DepthStencilBuffer;
                renderingContext.ShouldSnapText       = renderObject.SnapText && renderObject.IsBillboard && (renderObject.IsFixedSize || renderObject.IsFullScreen);

                // calculate an estimate of the UI real size by projecting the element virtual resolution on the screen
                var virtualOrigin            = uiElementState.WorldViewProjectionMatrix.Row4;
                var virtualWidth             = new Vector4(virtualResolution.X / 2, 0, 0, 1);
                var virtualHeight            = new Vector4(0, virtualResolution.Y / 2, 0, 1);
                var transformedVirtualWidth  = Vector4.Zero;
                var transformedVirtualHeight = Vector4.Zero;
                for (var i = 0; i < 4; i++)
                {
                    transformedVirtualWidth[i]  = virtualWidth[0] * uiElementState.WorldViewProjectionMatrix[0 + i] + uiElementState.WorldViewProjectionMatrix[12 + i];
                    transformedVirtualHeight[i] = virtualHeight[1] * uiElementState.WorldViewProjectionMatrix[4 + i] + uiElementState.WorldViewProjectionMatrix[12 + i];
                }

                var viewportSize           = context.CommandList.Viewport.Size;
                var projectedOrigin        = virtualOrigin.XY() / virtualOrigin.W;
                var projectedVirtualWidth  = viewportSize * (transformedVirtualWidth.XY() / transformedVirtualWidth.W - projectedOrigin);
                var projectedVirtualHeight = viewportSize * (transformedVirtualHeight.XY() / transformedVirtualHeight.W - projectedOrigin);

                // Set default services
                rootElement.UIElementServices = new UIElementServices {
                    Services = RenderSystem.Services
                };

                // set default resource dictionary

                // update layouting context.
                layoutingContext.VirtualResolution          = virtualResolution;
                layoutingContext.RealResolution             = viewportSize;
                layoutingContext.RealVirtualResolutionRatio = new Vector2(projectedVirtualWidth.Length() / virtualResolution.X, projectedVirtualHeight.Length() / virtualResolution.Y);
                rootElement.LayoutingContext = layoutingContext;

                // perform the time-based updates of the UI element
                updatableRootElement.Update(drawTime);

                // update the UI element disposition
                rootElement.Measure(virtualResolution);
                rootElement.Arrange(virtualResolution, false);

                // update the UI element hierarchical properties
                var rootMatrix = Matrix.Translation(-virtualResolution / 2); // UI world is translated by a half resolution compared to its quad, which is centered around the origin
                updatableRootElement.UpdateWorldMatrix(ref rootMatrix, rootMatrix != uiElementState.RenderObject.LastRootMatrix);
                updatableRootElement.UpdateElementState(0);
                uiElementState.RenderObject.LastRootMatrix = rootMatrix;

                // clear and set the Depth buffer as required
                if (renderObject.IsFullScreen)
                {
                    context.CommandList.Clear(renderingContext.DepthStencilBuffer, DepthStencilClearOptions.DepthBuffer | DepthStencilClearOptions.Stencil);
                }
                context.CommandList.SetRenderTarget(renderingContext.DepthStencilBuffer, renderingContext.RenderTarget);

                // start the image draw session
                renderingContext.StencilTestReferenceValue = 0;
                batch.Begin(context.GraphicsContext, ref uiElementState.WorldViewProjectionMatrix, BlendStates.AlphaBlend, uiSystem.KeepStencilValueState, renderingContext.StencilTestReferenceValue);

                // Render the UI elements in the final render target
                RecursiveDrawWithClipping(context, rootElement, ref uiElementState.WorldViewProjectionMatrix);

                // end the image draw session
                batch.End();
            }

            PickingClear();

            // revert the depth stencil buffer to the default value
            context.CommandList.SetRenderTargets(context.CommandList.DepthStencilBuffer, context.CommandList.RenderTargetCount, context.CommandList.RenderTargets);

            // Release scroped texture
            if (scopedDepthBuffer != null)
            {
                context.RenderContext.Allocator.ReleaseReference(scopedDepthBuffer);
            }
        }
        protected override Texture CreateTextureCore(ulong nativeTexture, ref TextureDescription description)
        {
            ID3D11Texture2D existingTexture = new ID3D11Texture2D((IntPtr)nativeTexture);

            return(new D3D11Texture(existingTexture, description.Type, description.Format));
        }
Exemple #24
0
 //--------------------------------------------------------------
 /// <summary>
 /// Initializes a new instance of the <see cref="Texture"/> class.
 /// </summary>
 /// <param name="description">The description.</param>
 /// <exception cref="ArgumentException">
 /// The <paramref name="description"/> is invalid.
 /// </exception>
 public Texture(TextureDescription description)
 {
     ValidateTexture(description);
       Description = description;
       Images = CreateImageCollection(description);
 }
Exemple #25
0
        internal VkTexture(VkGraphicsDevice gd, ref TextureDescription description)
        {
            _gd         = gd;
            _width      = description.Width;
            _height     = description.Height;
            _depth      = description.Depth;
            MipLevels   = description.MipLevels;
            ArrayLayers = description.ArrayLayers;
            bool isCubemap = ((description.Usage) & TextureUsage.Cubemap) == TextureUsage.Cubemap;

            _actualImageArrayLayers = isCubemap
                ? 6 * ArrayLayers
                : ArrayLayers;
            _format       = description.Format;
            Usage         = description.Usage;
            Type          = description.Type;
            SampleCount   = description.SampleCount;
            VkSampleCount = VkFormats.VdToVkSampleCount(SampleCount);
            VkFormat      = VkFormats.VdToVkPixelFormat(Format, (description.Usage & TextureUsage.DepthStencil) == TextureUsage.DepthStencil);

            bool isStaging = (Usage & TextureUsage.Staging) == TextureUsage.Staging;

            if (!isStaging)
            {
                VkImageCreateInfo imageCI = VkImageCreateInfo.New();
                imageCI.mipLevels     = MipLevels;
                imageCI.arrayLayers   = _actualImageArrayLayers;
                imageCI.imageType     = VkFormats.VdToVkTextureType(Type);
                imageCI.extent.width  = Width;
                imageCI.extent.height = Height;
                imageCI.extent.depth  = Depth;
                imageCI.initialLayout = VkImageLayout.Preinitialized;
                imageCI.usage         = VkFormats.VdToVkTextureUsage(Usage);
                imageCI.tiling        = isStaging ? VkImageTiling.Linear : VkImageTiling.Optimal;
                imageCI.format        = VkFormat;
                imageCI.flags         = VkImageCreateFlags.MutableFormat;

                imageCI.samples = VkSampleCount;
                if (isCubemap)
                {
                    imageCI.flags |= VkImageCreateFlags.CubeCompatible;
                }

                uint     subresourceCount = MipLevels * _actualImageArrayLayers * Depth;
                VkResult result           = vkCreateImage(gd.Device, ref imageCI, null, out _optimalImage);
                CheckResult(result);

                VkMemoryRequirements memoryRequirements;
                bool prefersDedicatedAllocation;
                if (_gd.GetImageMemoryRequirements2 != null)
                {
                    VkImageMemoryRequirementsInfo2KHR memReqsInfo2 = VkImageMemoryRequirementsInfo2KHR.New();
                    memReqsInfo2.image = _optimalImage;
                    VkMemoryRequirements2KHR         memReqs2      = VkMemoryRequirements2KHR.New();
                    VkMemoryDedicatedRequirementsKHR dedicatedReqs = VkMemoryDedicatedRequirementsKHR.New();
                    memReqs2.pNext = &dedicatedReqs;
                    _gd.GetImageMemoryRequirements2(_gd.Device, &memReqsInfo2, &memReqs2);
                    memoryRequirements         = memReqs2.memoryRequirements;
                    prefersDedicatedAllocation = dedicatedReqs.prefersDedicatedAllocation || dedicatedReqs.requiresDedicatedAllocation;
                }
                else
                {
                    vkGetImageMemoryRequirements(gd.Device, _optimalImage, out memoryRequirements);
                    prefersDedicatedAllocation = false;
                }

                VkMemoryBlock memoryToken = gd.MemoryManager.Allocate(
                    gd.PhysicalDeviceMemProperties,
                    memoryRequirements.memoryTypeBits,
                    VkMemoryPropertyFlags.DeviceLocal,
                    false,
                    memoryRequirements.size,
                    memoryRequirements.alignment,
                    prefersDedicatedAllocation,
                    _optimalImage,
                    Vulkan.VkBuffer.Null);
                _memoryBlock = memoryToken;
                result       = vkBindImageMemory(gd.Device, _optimalImage, _memoryBlock.DeviceMemory, _memoryBlock.Offset);
                CheckResult(result);

                _imageLayouts = new VkImageLayout[subresourceCount];
                for (int i = 0; i < _imageLayouts.Length; i++)
                {
                    _imageLayouts[i] = VkImageLayout.Preinitialized;
                }
            }
            else // isStaging
            {
                uint depthPitch = FormatHelpers.GetDepthPitch(
                    FormatHelpers.GetRowPitch(Width, Format),
                    Height,
                    Format);
                uint stagingSize = depthPitch * Depth;
                for (uint level = 1; level < MipLevels; level++)
                {
                    Util.GetMipDimensions(this, level, out uint mipWidth, out uint mipHeight, out uint mipDepth);

                    depthPitch = FormatHelpers.GetDepthPitch(
                        FormatHelpers.GetRowPitch(mipWidth, Format),
                        mipHeight,
                        Format);

                    stagingSize += depthPitch * mipDepth;
                }
                stagingSize *= ArrayLayers;

                VkBufferCreateInfo bufferCI = VkBufferCreateInfo.New();
                bufferCI.usage = VkBufferUsageFlags.TransferSrc | VkBufferUsageFlags.TransferDst;
                bufferCI.size  = stagingSize;
                VkResult result = vkCreateBuffer(_gd.Device, ref bufferCI, null, out _stagingBuffer);
                CheckResult(result);

                VkMemoryRequirements bufferMemReqs;
                bool prefersDedicatedAllocation;
                if (_gd.GetBufferMemoryRequirements2 != null)
                {
                    VkBufferMemoryRequirementsInfo2KHR memReqInfo2 = VkBufferMemoryRequirementsInfo2KHR.New();
                    memReqInfo2.buffer = _stagingBuffer;
                    VkMemoryRequirements2KHR         memReqs2      = VkMemoryRequirements2KHR.New();
                    VkMemoryDedicatedRequirementsKHR dedicatedReqs = VkMemoryDedicatedRequirementsKHR.New();
                    memReqs2.pNext = &dedicatedReqs;
                    _gd.GetBufferMemoryRequirements2(_gd.Device, &memReqInfo2, &memReqs2);
                    bufferMemReqs = memReqs2.memoryRequirements;
                    prefersDedicatedAllocation = dedicatedReqs.prefersDedicatedAllocation || dedicatedReqs.requiresDedicatedAllocation;
                }
                else
                {
                    vkGetBufferMemoryRequirements(gd.Device, _stagingBuffer, out bufferMemReqs);
                    prefersDedicatedAllocation = false;
                }

                _memoryBlock = _gd.MemoryManager.Allocate(
                    _gd.PhysicalDeviceMemProperties,
                    bufferMemReqs.memoryTypeBits,
                    VkMemoryPropertyFlags.HostVisible | VkMemoryPropertyFlags.HostCoherent,
                    true,
                    bufferMemReqs.size,
                    bufferMemReqs.alignment,
                    prefersDedicatedAllocation,
                    VkImage.Null,
                    _stagingBuffer);

                result = vkBindBufferMemory(_gd.Device, _stagingBuffer, _memoryBlock.DeviceMemory, _memoryBlock.Offset);
                CheckResult(result);
            }

            ClearIfRenderTarget();
            TransitionIfSampled();
            RefCount = new ResourceRefCount(RefCountedDispose);
        }
Exemple #26
0
        public static unsafe Texture LoadTexture(
            GraphicsDevice gd,
            ResourceFactory factory,
            Stream assetStream,
            PixelFormat format)
        {
            KtxFile ktxTex2D = Load(assetStream, false);

            uint width  = ktxTex2D.Header.PixelWidth;
            uint height = ktxTex2D.Header.PixelHeight;

            if (height == 0)
            {
                height = width;
            }

            uint arrayLayers = Math.Max(1, ktxTex2D.Header.NumberOfArrayElements);
            uint mipLevels   = Math.Max(1, ktxTex2D.Header.NumberOfMipmapLevels);

            Texture ret = factory.CreateTexture(TextureDescription.Texture2D(
                                                    width, height, mipLevels, arrayLayers,
                                                    format, TextureUsage.Sampled));

            Texture stagingTex = factory.CreateTexture(TextureDescription.Texture2D(
                                                           width, height, mipLevels, arrayLayers,
                                                           format, TextureUsage.Staging));

            // Copy texture data into staging buffer
            for (uint level = 0; level < mipLevels; level++)
            {
                KtxMipmapLevel mipmap = ktxTex2D.Mipmaps[level];
                for (uint layer = 0; layer < arrayLayers; layer++)
                {
                    KtxArrayElement ktxLayer = mipmap.ArrayElements[layer];
                    Debug.Assert(ktxLayer.Faces.Length == 1);
                    byte[] pixelData = ktxLayer.Faces[0].Data;
                    fixed(byte *pixelDataPtr = &pixelData[0])
                    {
                        gd.UpdateTexture(stagingTex, (IntPtr)pixelDataPtr, (uint)pixelData.Length,
                                         0, 0, 0, mipmap.Width, mipmap.Height, 1, level, layer);
                    }
                }
            }

            CommandList copyCL = factory.CreateCommandList();

            copyCL.Begin();
            for (uint level = 0; level < mipLevels; level++)
            {
                KtxMipmapLevel mipLevel = ktxTex2D.Mipmaps[level];
                for (uint layer = 0; layer < arrayLayers; layer++)
                {
                    copyCL.CopyTexture(
                        stagingTex, 0, 0, 0, level, layer,
                        ret, 0, 0, 0, level, layer,
                        mipLevel.Width, mipLevel.Height, mipLevel.Depth,
                        1);
                }
            }
            copyCL.End();
            gd.SubmitCommands(copyCL);

            gd.DisposeWhenIdle(copyCL);
            gd.DisposeWhenIdle(stagingTex);

            return(ret);
        }
Exemple #27
0
        private static TextureDescription DecodeDDSHeader(BinaryReader reader, DdsFlags flags, out ConversionFlags convFlags)
        {
            Debug.Assert(Marshal.SizeOf(typeof(Header)) == 124, "DDS Header size mismatch");
              Debug.Assert(Marshal.SizeOf(typeof(HeaderDXT10)) == 20, "DDS DX10 Extended Header size mismatch");

              var description = new TextureDescription();
              convFlags = ConversionFlags.None;

              long size = reader.BaseStream.Length - reader.BaseStream.Position;
              int sizeOfTGAHeader = Marshal.SizeOf(typeof(Header));
              if (size < sizeOfTGAHeader)
            throw new InvalidDataException("The DDS file is corrupt.");

              // DDS files always start with the same magic number ("DDS ").
              if (reader.ReadUInt32() != MagicHeader)
            throw new InvalidDataException("The file does not appear to be a DDS file.");

              var header = reader.BaseStream.ReadStruct<Header>();

              // Verify header to validate DDS file
              if (header.Size != Marshal.SizeOf(typeof(Header))
              || header.PixelFormat.Size != Marshal.SizeOf(typeof(PixelFormat)))
            throw new InvalidDataException("Incorrect sizes in DDS file.");

              description.MipLevels = header.MipMapCount;
              if (description.MipLevels == 0)
            description.MipLevels = 1;

              // Check for DX10 extension
              if ((header.PixelFormat.Flags & PixelFormatFlags.FourCC) != 0
              && (new FourCC('D', 'X', '1', '0') == header.PixelFormat.FourCC))
              {
            // Buffer must be big enough for both headers and magic value
            if (reader.BaseStream.Length < (Marshal.SizeOf(typeof(Header)) + Marshal.SizeOf(typeof(HeaderDXT10)) + sizeof(uint)))
              throw new InvalidDataException("The DDS files is truncated.");

            var headerDX10 = reader.BaseStream.ReadStruct<HeaderDXT10>();
            convFlags |= ConversionFlags.DX10;

            description.ArraySize = headerDX10.ArraySize;
            if (description.ArraySize == 0)
              throw new InvalidDataException("Invalid array size specified in DDS file.");

            description.Format = headerDX10.DXGIFormat;
            if (!TextureHelper.IsValidDds(description.Format) || TextureHelper.IsPalettized(description.Format))
              throw new InvalidDataException("Invalid format specified in DDS file.");

            switch (headerDX10.ResourceDimension)
            {
              case ResourceDimension.Texture1D:

            // D3DX writes 1D textures with a fixed Height of 1
            if ((header.Flags & HeaderFlags.Height) != 0 && header.Height != 1)
              throw new InvalidDataException("Invalid height for 1D texture specified in DDS file.");

            description.Dimension = TextureDimension.Texture1D;
            description.Width = header.Width;
            description.Height = 1;
            description.Depth = 1;
            break;

              case ResourceDimension.Texture2D:
            if ((headerDX10.MiscFlags & ResourceOptionFlags.TextureCube) != 0)
            {
              description.Dimension = TextureDimension.TextureCube;
              description.ArraySize *= 6;
            }
            else
            {
              description.Dimension = TextureDimension.Texture2D;
            }

            description.Width = header.Width;
            description.Height = header.Height;
            description.Depth = 1;
            break;

              case ResourceDimension.Texture3D:
            if ((header.Flags & HeaderFlags.Volume) == 0)
              throw new InvalidDataException("Volume flag for 3D texture is missing in DDS file.");

            if (description.ArraySize > 1)
              throw new InvalidDataException("Invalid array size for 3D texture specified in DDS file.");

            description.Dimension = TextureDimension.Texture3D;
            description.Width = header.Width;
            description.Height = header.Height;
            description.Depth = header.Depth;
            break;

              default:
            throw new InvalidDataException(string.Format(CultureInfo.InvariantCulture, "Invalid texture dimension specified in DDS file."));
            }
              }
              else
              {
            description.ArraySize = 1;

            if ((header.Flags & HeaderFlags.Volume) != 0)
            {
              description.Dimension = TextureDimension.Texture3D;
              description.Width = header.Width;
              description.Height = header.Height;
              description.Depth = header.Depth;
            }
            else
            {
              if ((header.CubemapFlags & CubemapFlags.CubeMap) != 0)
              {
            // We require all six faces to be defined
            if ((header.CubemapFlags & CubemapFlags.AllFaces) != CubemapFlags.AllFaces)
              throw new InvalidDataException("Cube map faces missing in DDS file. All six faces required.");

            description.Dimension = TextureDimension.TextureCube;
            description.ArraySize = 6;
              }
              else
              {
            description.Dimension = TextureDimension.Texture2D;
              }

              description.Width = header.Width;
              description.Height = header.Height;
              description.Depth = 1;

              // Note there's no way for a legacy Direct3D 9 DDS to express a '1D' texture
            }

            description.Format = GetDXGIFormat(ref header.PixelFormat, flags, out convFlags);

            if (description.Format == DataFormat.Unknown)
              throw new NotSupportedException("The texture format used in the DDS file is not supported.");

            // Premultiplied formats are considered deprecated.
            //if ((convFlags & ConversionFlags.PremultipliedAlpha) != 0)
            //  Description.AlphaMode = AlphaMode.Premultiplied;

            // Special flag for handling LUMINANCE legacy formats
            if ((flags & DdsFlags.ExpandLuminance) != 0)
            {
              switch (description.Format)
              {
            case DataFormat.R8_UNORM:
              description.Format = DataFormat.R8G8B8A8_UNORM;
              convFlags |= ConversionFlags.FormatL8 | ConversionFlags.Expand;
              break;

            case DataFormat.R8G8_UNORM:
              description.Format = DataFormat.R8G8B8A8_UNORM;
              convFlags |= ConversionFlags.FormatA8L8 | ConversionFlags.Expand;
              break;

            case DataFormat.R16_UNORM:
              description.Format = DataFormat.R16G16B16A16_UNORM;
              convFlags |= ConversionFlags.FormatL16 | ConversionFlags.Expand;
              break;
              }
            }
              }

              // Special flag for handling BGR DXGI 1.1 formats
              if ((flags & DdsFlags.ForceRgb) != 0)
              {
            switch (description.Format)
            {
              case DataFormat.B8G8R8A8_UNORM:
            description.Format = DataFormat.R8G8B8A8_UNORM;
            convFlags |= ConversionFlags.Swizzle;
            break;

              case DataFormat.B8G8R8X8_UNORM:
            description.Format = DataFormat.R8G8B8A8_UNORM;
            convFlags |= ConversionFlags.Swizzle | ConversionFlags.NoAlpha;
            break;

              case DataFormat.B8G8R8A8_TYPELESS:
            description.Format = DataFormat.R8G8B8A8_TYPELESS;
            convFlags |= ConversionFlags.Swizzle;
            break;

              case DataFormat.B8G8R8A8_UNORM_SRGB:
            description.Format = DataFormat.R8G8B8A8_UNORM_SRGB;
            convFlags |= ConversionFlags.Swizzle;
            break;

              case DataFormat.B8G8R8X8_TYPELESS:
            description.Format = DataFormat.R8G8B8A8_TYPELESS;
            convFlags |= ConversionFlags.Swizzle | ConversionFlags.NoAlpha;
            break;

              case DataFormat.B8G8R8X8_UNORM_SRGB:
            description.Format = DataFormat.R8G8B8A8_UNORM_SRGB;
            convFlags |= ConversionFlags.Swizzle | ConversionFlags.NoAlpha;
            break;
            }
              }

              // Special flag for handling 16bpp formats
              if ((flags & DdsFlags.No16Bpp) != 0)
              {
            switch (description.Format)
            {
              case DataFormat.B5G6R5_UNORM:
              case DataFormat.B5G5R5A1_UNORM:
              case DataFormat.B4G4R4A4_UNORM:
            description.Format = DataFormat.R8G8B8A8_UNORM;
            convFlags |= ConversionFlags.Expand;
            if (description.Format == DataFormat.B5G6R5_UNORM)
              convFlags |= ConversionFlags.NoAlpha;
            break;
            }
              }
              return description;
        }
Exemple #28
0
        public unsafe void Copy_Compressed_Array(bool separateLayerCopies)
        {
            PixelFormat format = PixelFormat.BC3_UNorm;

            if (!GD.GetPixelFormatSupport(format, TextureType.Texture2D, TextureUsage.Sampled))
            {
                return;
            }

            TextureDescription texDesc = TextureDescription.Texture2D(
                16, 16,
                1, 4,
                format,
                TextureUsage.Sampled);

            Texture copySrc = RF.CreateTexture(texDesc);

            texDesc.Usage = TextureUsage.Staging;
            Texture copyDst = RF.CreateTexture(texDesc);

            for (uint layer = 0; layer < copySrc.ArrayLayers; layer++)
            {
                int    byteCount = 16 * 16;
                byte[] data      = Enumerable.Range(0, byteCount).Select(i => (byte)(i + layer)).ToArray();
                GD.UpdateTexture(
                    copySrc,
                    data,
                    0, 0, 0,
                    16, 16, 1,
                    0, layer);
            }

            CommandList copyCL = RF.CreateCommandList();

            copyCL.Begin();
            if (separateLayerCopies)
            {
                for (uint layer = 0; layer < copySrc.ArrayLayers; layer++)
                {
                    copyCL.CopyTexture(copySrc, 0, 0, 0, 0, layer, copyDst, 0, 0, 0, 0, layer, 16, 16, 1, 1);
                }
            }
            else
            {
                copyCL.CopyTexture(copySrc, 0, 0, 0, 0, 0, copyDst, 0, 0, 0, 0, 0, 16, 16, 1, copySrc.ArrayLayers);
            }
            copyCL.End();
            Fence fence = RF.CreateFence(false);

            GD.SubmitCommands(copyCL, fence);
            GD.WaitForFence(fence);

            for (uint layer = 0; layer < copyDst.ArrayLayers; layer++)
            {
                MappedResource map     = GD.Map(copyDst, MapMode.Read, layer);
                byte *         basePtr = (byte *)map.Data;

                int  index   = 0;
                uint rowSize = 64;
                uint numRows = 4;
                for (uint row = 0; row < numRows; row++)
                {
                    byte *rowBase = basePtr + (row * map.RowPitch);
                    for (uint x = 0; x < rowSize; x++)
                    {
                        Assert.Equal((byte)(index + layer), rowBase[x]);
                        index += 1;
                    }
                }

                GD.Unmap(copyDst, layer);
            }
        }
Exemple #29
0
        private static Texture DecodeSingleframe(ImagingFactory imagingFactory, WicFlags flags, TextureDescription description, Guid convertGuid, BitmapFrameDecode frame)
        {
            var texture = new Texture(description);
              var image = texture.Images[0];

              if (convertGuid == Guid.Empty)
              {
            frame.CopyPixels(image.Data, image.RowPitch);
              }
              else
              {
            using (var converter = new FormatConverter(imagingFactory))
            {
              converter.Initialize(frame, convertGuid, GetWicDither(flags), null, 0, BitmapPaletteType.Custom);
              converter.CopyPixels(image.Data, image.RowPitch);
            }
              }

              return texture;
        }
Exemple #30
0
        public override void Draw(RenderDrawContext context, RenderView renderView, RenderViewStage renderViewStage, int startIndex, int endIndex)
        {
            base.Draw(context, renderView, renderViewStage, startIndex, endIndex);

            var currentRenderFrame = context.RenderContext.Tags.Get(RenderFrame.Current);

            var uiProcessor = renderView.SceneInstance.GetProcessor <UIRenderProcessor>();

            if (uiProcessor == null)
            {
                return;
            }

            //foreach (var uiRoot in uiProcessor.UIRoots)
            //{
            //    // Perform culling on group and accept
            //    if (!renderView.SceneCameraRenderer.CullingMask.Contains(uiRoot.UIComponent.Entity.Group))
            //        continue;

            //    // skips empty UI elements
            //    if (uiRoot.UIComponent.RootElement == null)
            //        continue;

            //    // Project the position
            //    // TODO: This code is duplicated from SpriteComponent -> unify it at higher level?
            //    var worldPosition = new Vector4(uiRoot.TransformComponent.WorldMatrix.TranslationVector, 1.0f);

            //    float projectedZ;
            //    if (uiRoot.UIComponent.IsFullScreen)
            //    {
            //        projectedZ = -uiRoot.TransformComponent.WorldMatrix.M43;
            //    }
            //    else
            //    {
            //        Vector4 projectedPosition;
            //        var cameraComponent = renderView.Camera;
            //        if (cameraComponent == null)
            //            continue;

            //        Vector4.Transform(ref worldPosition, ref cameraComponent.ViewProjectionMatrix, out projectedPosition);
            //        projectedZ = projectedPosition.Z / projectedPosition.W;
            //    }

            //    transparentList.Add(new RenderItem(this, uiRoot, projectedZ));
            //}

            // build the list of the UI elements to render
            uiElementStates.Clear();
            for (var index = startIndex; index < endIndex; index++)
            {
                var renderNodeReference = renderViewStage.SortedRenderNodes[index].RenderNode;
                var renderNode          = GetRenderNode(renderNodeReference);
                var renderElement       = (RenderUIElement)renderNode.RenderObject;

                uiElementStates.Add(renderElement);
            }

            // evaluate the current draw time (game instance is null for thumbnails)
            var drawTime = game != null ? game.DrawTime : new GameTime();

            // update the rendering context
            renderingContext.GraphicsContext = context.GraphicsContext;
            renderingContext.Time            = drawTime;
            renderingContext.RenderTarget    = currentRenderFrame.RenderTargets[0]; // TODO: avoid hardcoded index 0

            // cache the ratio between viewport and target.
            var viewportSize = context.CommandList.Viewport.Size;

            viewportTargetRatio = new Vector2(viewportSize.X / renderingContext.RenderTarget.Width, viewportSize.Y / renderingContext.RenderTarget.Height);

            // compact all the pointer events that happened since last frame to avoid performing useless hit tests.
            CompactPointerEvents();

            // allocate temporary graphics resources if needed
            Texture scopedDepthBuffer = null;

            foreach (var uiElement in uiElementStates)
            {
                if (uiElement.UIComponent.IsFullScreen)
                {
                    var renderTarget = renderingContext.RenderTarget;
                    var description  = TextureDescription.New2D(renderTarget.Width, renderTarget.Height, PixelFormat.D24_UNorm_S8_UInt, TextureFlags.DepthStencil);
                    scopedDepthBuffer = context.RenderContext.Allocator.GetTemporaryTexture(description);
                    break;
                }
            }

            // render the UI elements of all the entities
            foreach (var uiElementState in uiElementStates)
            {
                var uiComponent = uiElementState.UIComponent;
                var rootElement = uiComponent.RootElement;
                if (rootElement == null)
                {
                    continue;
                }

                var updatableRootElement = (IUIElementUpdate)rootElement;

                // calculate the size of the virtual resolution depending on target size (UI canvas)
                var virtualResolution = uiComponent.VirtualResolution;
                var targetSize        = new Vector2(renderingContext.RenderTarget.Width, renderingContext.RenderTarget.Height);
                if (uiComponent.IsFullScreen)
                {
                    // update the virtual resolution of the renderer
                    if (uiComponent.VirtualResolutionMode == VirtualResolutionMode.FixedWidthAdaptableHeight)
                    {
                        virtualResolution.Y = virtualResolution.X * targetSize.Y / targetSize.X;
                    }
                    if (uiComponent.VirtualResolutionMode == VirtualResolutionMode.FixedHeightAdaptableWidth)
                    {
                        virtualResolution.X = virtualResolution.Y * targetSize.X / targetSize.Y;
                    }
                }

                // Update the view parameters
                if (uiComponent.IsFullScreen)
                {
                    viewParameters.Update(uiComponent.Entity, virtualResolution);
                }
                else
                {
                    var cameraComponent = context.RenderContext.Tags.Get(CameraComponentRendererExtensions.Current);
                    viewParameters.Update(uiComponent.Entity, cameraComponent);
                }

                // Analyze the input and trigger the UI element touch and key events
                // Note: this is done before measuring/arranging/drawing the element in order to avoid one frame latency on clicks.
                //       But by doing so the world matrices taken for hit test are the ones calculated during last frame.
                using (Profiler.Begin(UIProfilerKeys.TouchEventsUpdate))
                {
                    foreach (var uiState in uiElementStates)
                    {
                        if (uiState.UIComponent.RootElement == null)
                        {
                            continue;
                        }

                        UpdateMouseOver(uiState);
                        UpdateTouchEvents(uiState, drawTime);
                    }
                }

                // update the rendering context values specific to this element
                renderingContext.Resolution           = virtualResolution;
                renderingContext.ViewMatrix           = viewParameters.ViewMatrix;
                renderingContext.ProjectionMatrix     = viewParameters.ProjectionMatrix;
                renderingContext.ViewProjectionMatrix = viewParameters.ViewProjectionMatrix;
                renderingContext.DepthStencilBuffer   = uiComponent.IsFullScreen ? scopedDepthBuffer : currentRenderFrame.DepthStencil;
                renderingContext.ShouldSnapText       = uiComponent.SnapText;

                // calculate an estimate of the UI real size by projecting the element virtual resolution on the screen
                var virtualOrigin            = viewParameters.ViewProjectionMatrix.Row4;
                var virtualWidth             = new Vector4(virtualResolution.X / 2, 0, 0, 1);
                var virtualHeight            = new Vector4(0, virtualResolution.Y / 2, 0, 1);
                var transformedVirtualWidth  = Vector4.Zero;
                var transformedVirtualHeight = Vector4.Zero;
                for (int i = 0; i < 4; i++)
                {
                    transformedVirtualWidth[i]  = virtualWidth[0] * viewParameters.ViewProjectionMatrix[0 + i] + viewParameters.ViewProjectionMatrix[12 + i];
                    transformedVirtualHeight[i] = virtualHeight[1] * viewParameters.ViewProjectionMatrix[4 + i] + viewParameters.ViewProjectionMatrix[12 + i];
                }
                var projectedOrigin        = virtualOrigin.XY() / virtualOrigin.W;
                var projectedVirtualWidth  = viewportSize * (transformedVirtualWidth.XY() / transformedVirtualWidth.W - projectedOrigin);
                var projectedVirtualHeight = viewportSize * (transformedVirtualHeight.XY() / transformedVirtualHeight.W - projectedOrigin);

                // set default resource dictionary
                rootElement.ResourceDictionary = uiSystem.DefaultResourceDictionary;

                // update layouting context.
                layoutingContext.VirtualResolution          = virtualResolution;
                layoutingContext.RealResolution             = viewportSize;
                layoutingContext.RealVirtualResolutionRatio = new Vector2(projectedVirtualWidth.Length() / virtualResolution.X, projectedVirtualHeight.Length() / virtualResolution.Y);
                rootElement.LayoutingContext = layoutingContext;

                // perform the time-based updates of the UI element
                updatableRootElement.Update(drawTime);

                // update the UI element disposition
                rootElement.Measure(virtualResolution);
                rootElement.Arrange(virtualResolution, false);

                // update the UI element hierarchical properties
                var rootMatrix = Matrix.Translation(-virtualResolution / 2); // UI world is rotated of 180degrees along Ox
                updatableRootElement.UpdateWorldMatrix(ref rootMatrix, rootMatrix != uiElementState.LastRootMatrix);
                updatableRootElement.UpdateElementState(0);
                uiElementState.LastRootMatrix = rootMatrix;

                // clear and set the Depth buffer as required
                if (uiComponent.IsFullScreen)
                {
                    context.CommandList.Clear(renderingContext.DepthStencilBuffer, DepthStencilClearOptions.DepthBuffer | DepthStencilClearOptions.Stencil);
                }
                context.CommandList.SetRenderTargetAndViewport(renderingContext.DepthStencilBuffer, renderingContext.RenderTarget);

                // start the image draw session
                renderingContext.StencilTestReferenceValue = 0;
                batch.Begin(context.GraphicsContext, ref viewParameters.ViewProjectionMatrix, BlendStates.AlphaBlend, uiSystem.KeepStencilValueState, renderingContext.StencilTestReferenceValue);

                // Render the UI elements in the final render target
                ReccursiveDrawWithClipping(context, rootElement);

                // end the image draw session
                batch.End();
            }

            // clear the list of compacted pointer events of time frame
            ClearPointerEvents();

            // revert the depth stencil buffer to the default value
            context.CommandList.SetRenderTargetsAndViewport(currentRenderFrame.DepthStencil, currentRenderFrame.RenderTargets);

            // Release scroped texture
            if (scopedDepthBuffer != null)
            {
                context.RenderContext.Allocator.ReleaseReference(scopedDepthBuffer);
            }
        }
Exemple #31
0
 protected internal Texture1D(GraphicsDevice device, TextureDescription description1D, DataBox[] dataBox = null)
     : base(device, description1D)
 {
 }
Exemple #32
0
        private unsafe Texture CreateTexture(TextKey key)
        {
            var size       = key.Size;
            var actualFont = key.Font;

            var image = _textImagePool.Acquire(new ImageKey
            {
                Width  = (int)Math.Ceiling(size.Width),
                Height = (int)Math.Ceiling(size.Height)
            });

            // Clear image to transparent.
            // TODO: Don't need to do this for a newly created image.
            fixed(void *pin = &image.DangerousGetPinnableReferenceToPixelBuffer())
            {
                Unsafe.InitBlock(pin, 0, (uint)(image.Width * image.Height * 4));
            }

            image.Mutate(x =>
            {
                var location = new SixLabors.Primitives.PointF(0, size.Height / 2.0f);

                // TODO: Vertical centering is not working properly.
                location.Y *= 0.8f;

                var color = key.Color;

                x.DrawText(
                    key.Text,
                    actualFont,
                    new Bgra32(
                        (byte)(color.R * 255.0f),
                        (byte)(color.G * 255.0f),
                        (byte)(color.B * 255.0f),
                        (byte)(color.A * 255.0f)),
                    location,
                    new TextGraphicsOptions
                {
                    WrapTextWidth       = size.Width,
                    HorizontalAlignment = key.Alignment == TextAlignment.Center
                            ? HorizontalAlignment.Center
                            : HorizontalAlignment.Left,
                    VerticalAlignment = VerticalAlignment.Center
                });
            });

            Texture texture;

            // Draw image to texture.
            fixed(void *pin = &image.DangerousGetPinnableReferenceToPixelBuffer())
            {
                texture = _graphicsDevice.ResourceFactory.CreateTexture(
                    TextureDescription.Texture2D(
                        (uint)image.Width,
                        (uint)image.Height,
                        1,
                        1,
                        PixelFormat.B8_G8_R8_A8_UNorm,
                        TextureUsage.Sampled));

                _graphicsDevice.UpdateTexture(
                    texture,
                    new IntPtr(pin),
                    (uint)(image.Width * image.Height * 4),
                    0, 0, 0,
                    texture.Width,
                    texture.Height,
                    1,
                    0,
                    0);
            }

            _textImagePool.ReleaseAll();

            return(texture);
        }
Exemple #33
0
 public abstract Texture CreateTexture(ref TextureDescription description);
Exemple #34
0
 // TODO: private protected
 /// <summary>
 /// </summary>
 /// <param name="description"></param>
 /// <returns></returns>
 protected abstract Texture CreateTextureCore(ref TextureDescription description);
Exemple #35
0
        protected override void DrawCore(RenderContext context, RenderDrawContext drawContext)
        {
            var viewport = drawContext.CommandList.Viewport;

            using (drawContext.PushRenderTargetsAndRestore())
            {
                // Render Shadow maps
                shadowMapRenderer?.Draw(drawContext);

                if (VRSettings.Enabled && VRSettings.VRDevice != null)
                {
                    var isFullViewport = (int)viewport.X == 0 && (int)viewport.Y == 0 &&
                                         (int)viewport.Width == drawContext.CommandList.RenderTarget.ViewWidth &&
                                         (int)viewport.Height == drawContext.CommandList.RenderTarget.ViewHeight;
                    if (!isFullViewport)
                    {
                        return;
                    }

                    var hasPostEffects = PostEffects != null; // When we have post effect we need to bind a different framebuffer for each view to be sure effects impinge on the other view.

                    Texture vrFullSurface;
                    using (drawContext.PushRenderTargetsAndRestore())
                    {
                        var currentRenderTarget     = drawContext.CommandList.RenderTarget;
                        var vrFullFrameSize         = VRSettings.VRDevice.ActualRenderFrameSize;
                        var desiredRenderTargetSize = !hasPostEffects ? vrFullFrameSize : new Size2(vrFullFrameSize.Width / 2, vrFullFrameSize.Height);
                        if (hasPostEffects || desiredRenderTargetSize.Width != currentRenderTarget.Width || desiredRenderTargetSize.Height != currentRenderTarget.Height)
                        {
                            drawContext.CommandList.SetRenderTargets(null, null); // force to create and bind a new render target
                        }
                        PrepareRenderTargets(drawContext, desiredRenderTargetSize);

                        //prepare the final VR target
                        vrFullSurface = ViewOutputTarget;
                        if (hasPostEffects)
                        {
                            var frameSize = VRSettings.VRDevice.ActualRenderFrameSize;
                            var renderTargetDescription = TextureDescription.New2D(frameSize.Width, frameSize.Height, 1, PixelFormat.R8G8B8A8_UNorm_SRgb, TextureFlags.ShaderResource | TextureFlags.RenderTarget);
                            vrFullSurface = PushScopedResource(drawContext.GraphicsContext.Allocator.GetTemporaryTexture2D(renderTargetDescription));
                        }

                        //draw per eye
                        using (context.SaveViewportAndRestore())
                            using (drawContext.PushRenderTargetsAndRestore())
                            {
                                ViewCount = 2;
                                bool isWindowsMixedReality = false;

                                for (var i = 0; i < 2; i++)
                                {
#if XENKO_GRAPHICS_API_DIRECT3D11 && XENKO_PLATFORM_UWP
                                    if (drawContext.GraphicsDevice.Presenter is WindowsMixedRealityGraphicsPresenter graphicsPresenter)
                                    {
                                        isWindowsMixedReality = true;

                                        MSAALevel = MultisampleCount.None;
                                        currentRenderTargets.Clear();

                                        if (i == 0)
                                        {
                                            currentRenderTargets.Add(graphicsPresenter.LeftEyeBuffer);
                                        }
                                        else
                                        {
                                            currentRenderTargets.Add(graphicsPresenter.RightEyeBuffer);
                                        }
                                    }
#endif

                                    drawContext.CommandList.SetRenderTargets(currentDepthStencil, currentRenderTargets.Count, currentRenderTargets.Items);

                                    if (!hasPostEffects && !isWindowsMixedReality) // need to change the viewport between each eye
                                    {
                                        var frameSize = VRSettings.VRDevice.ActualRenderFrameSize;
                                        drawContext.CommandList.SetViewport(new Viewport(i * frameSize.Width / 2, 0, frameSize.Width / 2, frameSize.Height));
                                    }
                                    else if (i == 0) // the viewport is the same for both eyes so we set it only once
                                    {
                                        drawContext.CommandList.SetViewport(new Viewport(0.0f, 0.0f, VRSettings.VRDevice.ActualRenderFrameSize.Width / 2.0f, VRSettings.VRDevice.ActualRenderFrameSize.Height));
                                    }

                                    using (context.PushRenderViewAndRestore(VRSettings.RenderViews[i]))
                                    {
                                        // Clear render target and depth stencil
                                        if (hasPostEffects || i == 0) // need to clear for each eye in the case we have two different render targets
                                        {
                                            Clear?.Draw(drawContext);
                                        }

                                        ViewIndex = i;

                                        DrawView(context, drawContext, i, 2);

                                        if (hasPostEffects) // copy the rendered view into the vr full view framebuffer
                                        {
                                            drawContext.CommandList.CopyRegion(ViewOutputTarget, 0, null, vrFullSurface, 0, VRSettings.VRDevice.ActualRenderFrameSize.Width / 2 * i);
                                        }
                                    }
                                }

                                if (VRSettings.VRDevice.SupportsOverlays)
                                {
                                    foreach (var overlay in VRSettings.Overlays)
                                    {
                                        if (overlay != null && overlay.Texture != null)
                                        {
                                            overlay.Overlay.UpdateSurface(drawContext.CommandList, overlay.Texture);
                                        }
                                    }
                                }

                                VRSettings.VRDevice.Commit(drawContext.CommandList, vrFullSurface);
                            }
                    }

                    //draw mirror to backbuffer (if size is matching and full viewport)
                    if (VRSettings.CopyMirror)
                    {
                        CopyOrScaleTexture(drawContext, VRSettings.VRDevice.MirrorTexture, drawContext.CommandList.RenderTarget);
                    }
                    else if (hasPostEffects)
                    {
                        CopyOrScaleTexture(drawContext, vrFullSurface, drawContext.CommandList.RenderTarget);
                    }
                }
                else
                {
                    PrepareRenderTargets(drawContext, new Size2((int)viewport.Width, (int)viewport.Height));

                    ViewCount = 1;
                    ViewIndex = 0;

                    //var sssMaterialIndexRenderTarget = GenerateSSSMaterialIndexRenderTarget(context, viewport);

                    using (drawContext.PushRenderTargetsAndRestore())
                    {
                        drawContext.CommandList.SetRenderTargets(currentDepthStencil, currentRenderTargets.Count, currentRenderTargets.Items);

                        // Clear render target and depth stencil
                        Clear?.Draw(drawContext);

                        DrawView(context, drawContext, 0, 1);
                    }
                }
            }

            // Clear intermediate results
            currentRenderTargets.Clear();
            currentRenderTargetsNonMSAA.Clear();
            currentDepthStencil        = null;
            currentDepthStencilNonMSAA = null;
        }
Exemple #36
0
        public StandardGraphicsResources(GraphicsDevice graphicsDevice)
        {
            _graphicsDevice = graphicsDevice;

            var linearClampSamplerDescription = SamplerDescription.Linear;

            linearClampSamplerDescription.AddressModeU = SamplerAddressMode.Clamp;
            linearClampSamplerDescription.AddressModeV = SamplerAddressMode.Clamp;
            linearClampSamplerDescription.AddressModeW = SamplerAddressMode.Clamp;
            LinearClampSampler = AddDisposable(
                graphicsDevice.ResourceFactory.CreateSampler(ref linearClampSamplerDescription));

            var pointClampSamplerDescription = SamplerDescription.Point;

            pointClampSamplerDescription.AddressModeU = SamplerAddressMode.Clamp;
            pointClampSamplerDescription.AddressModeV = SamplerAddressMode.Clamp;
            pointClampSamplerDescription.AddressModeW = SamplerAddressMode.Clamp;
            PointClampSampler = AddDisposable(
                graphicsDevice.ResourceFactory.CreateSampler(ref pointClampSamplerDescription));

            NullTexture      = AddDisposable(graphicsDevice.ResourceFactory.CreateTexture(TextureDescription.Texture2D(1, 1, 1, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Sampled)));
            NullTexture.Name = "Null Texture";

            SolidWhiteTexture = AddDisposable(graphicsDevice.CreateStaticTexture2D(
                                                  1, 1, 1,
                                                  new TextureMipMapData(
                                                      new byte[] { 255, 255, 255, 255 },
                                                      4, 4, 1, 1),
                                                  PixelFormat.R8_G8_B8_A8_UNorm));
            SolidWhiteTexture.Name = "Solid White Texture";

            PlaceholderTexture = AddDisposable(graphicsDevice.CreateStaticTexture2D(
                                                   1, 1, 1,
                                                   new TextureMipMapData(
                                                       new byte[] { 255, 105, 180, 255 },
                                                       4, 4, 1, 1),
                                                   PixelFormat.R8_G8_B8_A8_UNorm));
            PlaceholderTexture.Name = "Placeholder Texture";

            _nullStructuredBuffers = new Dictionary <uint, DeviceBuffer>();
        }
Exemple #37
0
        public void Parse(byte[] byteCode, ShaderStage stage)
        {
            ConstantBufferMappings.Clear();
            TextureMappings.Clear();
            UAVMappings.Clear();
            SamplerMappings.Clear();
            using (var reflection = new ShaderReflection(byteCode))
            {
                FeatureLevel = reflection.MinFeatureLevel;
                for (int i = 0; i < reflection.Description.BoundResources; ++i)
                {
                    var res = reflection.GetResourceBindingDescription(i);
                    switch (res.Type)
                    {
                    case ShaderInputType.ConstantBuffer:
                        var cb     = reflection.GetConstantBuffer(res.Name);
                        var cbDesc = new ConstantBufferDescription(res.Name, cb.Description.Size)
                        {
                            Stage = stage
                        };
                        ConstantBufferMappings.Add(res.Name, cbDesc.CreateMapping(res.BindPoint));
                        break;

                    case ShaderInputType.Texture:
                        var tDescT = new TextureDescription(res.Name, stage, TextureType.Texture);
                        TextureMappings.Add(res.Name, tDescT.CreateMapping(res.BindPoint));
                        break;

                    case ShaderInputType.Structured:
                        var tDescStr = new TextureDescription(res.Name, stage, TextureType.Structured);
                        TextureMappings.Add(res.Name, tDescStr.CreateMapping(res.BindPoint));
                        break;

                    case ShaderInputType.TextureBuffer:
                        var tDescTB = new TextureDescription(res.Name, stage, TextureType.TextureBuffer);
                        TextureMappings.Add(res.Name, tDescTB.CreateMapping(res.BindPoint));
                        break;

                    case ShaderInputType.UnorderedAccessViewAppendStructured:
                        var uDescAppend = new UAVDescription(res.Name, stage, UnorderedAccessViewType.AppendStructured);
                        UAVMappings.Add(res.Name, uDescAppend.CreateMapping(res.BindPoint));
                        break;

                    case ShaderInputType.UnorderedAccessViewConsumeStructured:
                        var uDescConsume = new UAVDescription(res.Name, stage, UnorderedAccessViewType.ConsumeStructured);
                        UAVMappings.Add(res.Name, uDescConsume.CreateMapping(res.BindPoint));
                        break;

                    case ShaderInputType.UnorderedAccessViewRWByteAddress:
                        var uDescByte = new UAVDescription(res.Name, stage, UnorderedAccessViewType.RWByteAddress);
                        UAVMappings.Add(res.Name, uDescByte.CreateMapping(res.BindPoint));
                        break;

                    case ShaderInputType.UnorderedAccessViewRWStructuredWithCounter:
                        var uDescStr = new UAVDescription(res.Name, stage, UnorderedAccessViewType.RWStructuredWithCounter);
                        UAVMappings.Add(res.Name, uDescStr.CreateMapping(res.BindPoint));
                        break;

                    case ShaderInputType.UnorderedAccessViewRWTyped:
                        var uDescTyped = new UAVDescription(res.Name, stage, UnorderedAccessViewType.RWTyped);
                        UAVMappings.Add(res.Name, uDescTyped.CreateMapping(res.BindPoint));
                        break;

                    case ShaderInputType.Sampler:
                        SamplerMappings.Add(res.Name, new SamplerMapping(res.BindPoint, res.Name, stage));
                        break;
                    }
                }
            }
        }
        private void Initialize()
        {
            var factory = graphicsDevice.ResourceFactory;

            aspectWidth  = 2f / graphicsDevice.SwapchainFramebuffer.Width;
            aspectHeight = 2f / graphicsDevice.SwapchainFramebuffer.Height;

            glyphVertexBuffer = factory.CreateBuffer(new BufferDescription(VertexPosition3Coord2.SizeInBytes, BufferUsage.VertexBuffer));
            quadVertexBuffer  = factory.CreateBuffer(new BufferDescription(VertexPosition2.SizeInBytes * 4, BufferUsage.VertexBuffer));
            quadVertices      = new VertexPosition2[]
            {
                new VertexPosition2(new Vector2(-1, 1)),
                new VertexPosition2(new Vector2(-1, -1)),
                new VertexPosition2(new Vector2(1, 1)),
                new VertexPosition2(new Vector2(1, -1)),
            };
            graphicsDevice.UpdateBuffer(quadVertexBuffer, 0, quadVertices);

            textVertexPropertiesBuffer   = factory.CreateBuffer(new BufferDescription((uint)Unsafe.SizeOf <TextVertexProperties>(), BufferUsage.UniformBuffer | BufferUsage.Dynamic));
            textFragmentPropertiesBuffer = factory.CreateBuffer(new BufferDescription((uint)Unsafe.SizeOf <TextFragmentProperties>(), BufferUsage.UniformBuffer | BufferUsage.Dynamic));
            textVertexProperties         = new TextVertexProperties
            {
                Transform = new Matrix4x4(),
                Rectangle = new Vector4(0, 0, 1, 1)
            };
            textFragmentProperties = new TextFragmentProperties
            {
                ThicknessAndMode = 0, // TODO support other modes
                GlyphColor       = new Color(0, 0.5f, 1, 1)
            };
            graphicsDevice.UpdateBuffer(textVertexPropertiesBuffer, 0, textVertexProperties);
            graphicsDevice.UpdateBuffer(textFragmentPropertiesBuffer, 0, textFragmentProperties);

            var colorFormat = PixelFormat.B8_G8_R8_A8_UNorm;

            glyphTexture            = factory.CreateTexture(TextureDescription.Texture2D(graphicsDevice.SwapchainFramebuffer.Width, graphicsDevice.SwapchainFramebuffer.Height, 1, 1, colorFormat, TextureUsage.RenderTarget | TextureUsage.Sampled));
            glyphTextureView        = factory.CreateTextureView(glyphTexture);
            glyphTextureFramebuffer = factory.CreateFramebuffer(new FramebufferDescription(null, glyphTexture));
            // HACK workaround issue with texture view caching for shader resources
            dummyTexture     = factory.CreateTexture(TextureDescription.Texture2D(1, 1, 1, 1, colorFormat, TextureUsage.Sampled));
            dummyTextureView = factory.CreateTextureView(dummyTexture);

            var shaderOptions = GetCompileOptions();

            CompileShaders(factory, shaderOptions);

            var textPropertiesLayout = factory.CreateResourceLayout(
                new ResourceLayoutDescription(
                    new ResourceLayoutElementDescription("TextVertexPropertiesBuffer", ResourceKind.UniformBuffer, ShaderStages.Vertex),
                    new ResourceLayoutElementDescription("TextFragmentPropertiesBuffer", ResourceKind.UniformBuffer, ShaderStages.Fragment)));

            textTextureLayout = factory.CreateResourceLayout(
                new ResourceLayoutDescription(
                    new ResourceLayoutElementDescription("GlyphTexture", ResourceKind.TextureReadOnly, ShaderStages.Fragment),
                    new ResourceLayoutElementDescription("GlyphTextureSampler", ResourceKind.Sampler, ShaderStages.Fragment)));

            textPropertiesSet = factory.CreateResourceSet(new ResourceSetDescription(
                                                              textPropertiesLayout,
                                                              textVertexPropertiesBuffer,
                                                              textFragmentPropertiesBuffer));

            textTextureSet = factory.CreateResourceSet(new ResourceSetDescription(
                                                           textTextureLayout,
                                                           glyphTextureView,
                                                           graphicsDevice.LinearSampler));
            // HACK workaround issue with texture view caching for shader resources
            dummyTextureSet = factory.CreateResourceSet(new ResourceSetDescription(
                                                            textTextureLayout,
                                                            dummyTextureView,
                                                            graphicsDevice.LinearSampler));

            var additiveBlendState = new BlendStateDescription(RgbaFloat.White,
                                                               new BlendAttachmentDescription(
                                                                   blendEnabled: true,
                                                                   sourceColorFactor: BlendFactor.One,
                                                                   destinationColorFactor: BlendFactor.One,
                                                                   colorFunction: BlendFunction.Add,
                                                                   sourceAlphaFactor: BlendFactor.One,
                                                                   destinationAlphaFactor: BlendFactor.One,
                                                                   alphaFunction: BlendFunction.Add));

            var pipelineDescription = new GraphicsPipelineDescription(
                blendState: new BlendStateDescription(RgbaFloat.White,
                                                      new BlendAttachmentDescription(
                                                          blendEnabled: true,
                                                          sourceColorFactor: BlendFactor.Zero,
                                                          destinationColorFactor: BlendFactor.SourceColor,
                                                          colorFunction: BlendFunction.Add,
                                                          sourceAlphaFactor: BlendFactor.Zero,
                                                          destinationAlphaFactor: BlendFactor.SourceAlpha,
                                                          alphaFunction: BlendFunction.Add)),
                depthStencilStateDescription: new DepthStencilStateDescription(
                    depthTestEnabled: true,
                    depthWriteEnabled: true,
                    comparisonKind: ComparisonKind.LessEqual),
                rasterizerState: new RasterizerStateDescription(
                    cullMode: FaceCullMode.Back,
                    fillMode: PolygonFillMode.Solid,
                    frontFace: FrontFace.Clockwise,
                    depthClipEnabled: true,
                    scissorTestEnabled: false),
                primitiveTopology: PrimitiveTopology.TriangleStrip,
                shaderSet: new ShaderSetDescription(
                    vertexLayouts: new[]
            {
                new VertexLayoutDescription(
                    new VertexElementDescription("Position", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2))
            },
                    shaders: textShaders,
                    specializations: shaderOptions.Specializations),
                resourceLayouts: new ResourceLayout[] { textPropertiesLayout, textTextureLayout },
                outputs: graphicsDevice.SwapchainFramebuffer.OutputDescription
                );

            outputPipeline = factory.CreateGraphicsPipeline(pipelineDescription);

            pipelineDescription.BlendState = additiveBlendState;
            outputColorPipeline            = factory.CreateGraphicsPipeline(pipelineDescription);

            pipelineDescription.Outputs           = new OutputDescription(null, new OutputAttachmentDescription(colorFormat));
            pipelineDescription.BlendState        = additiveBlendState;
            pipelineDescription.ResourceLayouts   = new ResourceLayout[] { textPropertiesLayout };
            pipelineDescription.PrimitiveTopology = PrimitiveTopology.TriangleList;
            pipelineDescription.RasterizerState   = new RasterizerStateDescription(
                cullMode: FaceCullMode.None,
                fillMode: PolygonFillMode.Solid,
                frontFace: FrontFace.Clockwise,
                depthClipEnabled: true,
                scissorTestEnabled: false);
            pipelineDescription.ShaderSet = new ShaderSetDescription(
                vertexLayouts: new[]
            {
                new VertexLayoutDescription(
                    new VertexElementDescription("Position", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float3),
                    new VertexElementDescription("Coord", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2))
            },
                shaders: glyphShaders,
                specializations: shaderOptions.Specializations);
            glyphPipeline = factory.CreateGraphicsPipeline(pipelineDescription);
        }
Exemple #39
0
        public void Points_WithUShortColor()
        {
            Texture target = RF.CreateTexture(TextureDescription.Texture2D(
                                                  50, 50, 1, 1, PixelFormat.R32_G32_B32_A32_Float, TextureUsage.RenderTarget));
            Texture staging = RF.CreateTexture(TextureDescription.Texture2D(
                                                   50, 50, 1, 1, PixelFormat.R32_G32_B32_A32_Float, TextureUsage.Staging));

            Framebuffer framebuffer = RF.CreateFramebuffer(new FramebufferDescription(null, target));

            DeviceBuffer infoBuffer  = RF.CreateBuffer(new BufferDescription(16, BufferUsage.UniformBuffer));
            DeviceBuffer orthoBuffer = RF.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer));
            Matrix4x4    orthoMatrix = Matrix4x4.CreateOrthographicOffCenter(
                0,
                framebuffer.Width,
                framebuffer.Height,
                0,
                -1,
                1);

            GD.UpdateBuffer(orthoBuffer, 0, ref orthoMatrix);

            ShaderSetDescription shaderSet = new ShaderSetDescription(
                new VertexLayoutDescription[]
            {
                new VertexLayoutDescription(
                    new VertexElementDescription("Position", VertexElementSemantic.Position, VertexElementFormat.Float2),
                    new VertexElementDescription("Color_UInt", VertexElementSemantic.Color, VertexElementFormat.UShort4))
            },
                new Shader[]
            {
                TestShaders.Load(RF, "U16VertexAttribs", ShaderStages.Vertex, "VS"),
                TestShaders.Load(RF, "U16VertexAttribs", ShaderStages.Fragment, "FS")
            });

            ResourceLayout layout = RF.CreateResourceLayout(new ResourceLayoutDescription(
                                                                new ResourceLayoutElementDescription("InfoBuffer", ResourceKind.UniformBuffer, ShaderStages.Vertex),
                                                                new ResourceLayoutElementDescription("Ortho", ResourceKind.UniformBuffer, ShaderStages.Vertex)));

            ResourceSet set = RF.CreateResourceSet(new ResourceSetDescription(layout, infoBuffer, orthoBuffer));

            GraphicsPipelineDescription gpd = new GraphicsPipelineDescription(
                BlendStateDescription.SingleOverrideBlend,
                DepthStencilStateDescription.Disabled,
                RasterizerStateDescription.Default,
                PrimitiveTopology.PointList,
                shaderSet,
                layout,
                framebuffer.OutputDescription);

            Pipeline pipeline = RF.CreateGraphicsPipeline(ref gpd);

            uint colorNormalizationFactor = 2500;

            VertexCPU_UShort[] vertices = new VertexCPU_UShort[]
            {
                new VertexCPU_UShort
                {
                    Position = new Vector2(0.5f, 0.5f),
                    R        = (ushort)(0.25f * colorNormalizationFactor),
                    G        = (ushort)(0.5f * colorNormalizationFactor),
                    B        = (ushort)(0.75f * colorNormalizationFactor),
                },
                new VertexCPU_UShort
                {
                    Position = new Vector2(10.5f, 12.5f),
                    R        = (ushort)(0.25f * colorNormalizationFactor),
                    G        = (ushort)(0.5f * colorNormalizationFactor),
                    B        = (ushort)(0.75f * colorNormalizationFactor),
                },
                new VertexCPU_UShort
                {
                    Position = new Vector2(25.5f, 35.5f),
                    R        = (ushort)(0.75f * colorNormalizationFactor),
                    G        = (ushort)(0.5f * colorNormalizationFactor),
                    B        = (ushort)(0.25f * colorNormalizationFactor),
                },
                new VertexCPU_UShort
                {
                    Position = new Vector2(49.5f, 49.5f),
                    R        = (ushort)(0.15f * colorNormalizationFactor),
                    G        = (ushort)(0.2f * colorNormalizationFactor),
                    B        = (ushort)(0.35f * colorNormalizationFactor),
                },
            };

            DeviceBuffer vb = RF.CreateBuffer(
                new BufferDescription((uint)(Unsafe.SizeOf <UIntVertexAttribs.Vertex>() * vertices.Length), BufferUsage.VertexBuffer));

            GD.UpdateBuffer(vb, 0, vertices);
            GD.UpdateBuffer(infoBuffer, 0, new UIntVertexAttribs.Info {
                ColorNormalizationFactor = colorNormalizationFactor
            });

            CommandList cl = RF.CreateCommandList();

            cl.Begin();
            cl.SetFramebuffer(framebuffer);
            cl.SetFullViewports();
            cl.SetFullScissorRects();
            cl.ClearColorTarget(0, RgbaFloat.Black);
            cl.SetPipeline(pipeline);
            cl.SetVertexBuffer(0, vb);
            cl.SetGraphicsResourceSet(0, set);
            cl.Draw((uint)vertices.Length);
            cl.SetFramebuffer(GD.SwapchainFramebuffer);
            cl.ClearColorTarget(0, RgbaFloat.Red);
            cl.CopyTexture(target, staging);
            cl.End();
            GD.SubmitCommands(cl);
            GD.WaitForIdle();

            MappedResourceView <RgbaFloat> readView = GD.Map <RgbaFloat>(staging, MapMode.Read);

            foreach (VertexCPU_UShort vertex in vertices)
            {
                uint x = (uint)vertex.Position.X;
                uint y = (uint)vertex.Position.Y;
                if (GD.BackendType == GraphicsBackend.OpenGL)
                {
                    y = framebuffer.Height - y - 1;
                }

                RgbaFloat expectedColor = new RgbaFloat(
                    vertex.R / (float)colorNormalizationFactor,
                    vertex.G / (float)colorNormalizationFactor,
                    vertex.B / (float)colorNormalizationFactor,
                    1);
                Assert.Equal(expectedColor, readView[x, y], RgbaFloatFuzzyComparer.Instance);
            }
            GD.Unmap(staging);
        }
Exemple #40
0
        public ContentManager(
            Game game,
            FileSystem fileSystem,
            GraphicsDevice graphicsDevice,
            SageGame sageGame,
            WndCallbackResolver wndCallbackResolver)
        {
            using (GameTrace.TraceDurationEvent("ContentManager()"))
            {
                _game       = game;
                _fileSystem = fileSystem;

                GraphicsDevice = graphicsDevice;

                SageGame = sageGame;

                Language = LanguageUtility.ReadCurrentLanguage(game.Definition, fileSystem.RootDirectory);

                IniDataContext = new IniDataContext(fileSystem, sageGame);

                DataContext = new DataContext();

                SubsystemLoader = Content.SubsystemLoader.Create(game.Definition, _fileSystem, IniDataContext);

                switch (sageGame)
                {
                // Only load these INI files for a subset of games, because we can't parse them for others yet.
                case SageGame.CncGenerals:
                case SageGame.CncGeneralsZeroHour:
                case SageGame.Bfme:
                case SageGame.Bfme2:
                case SageGame.Bfme2Rotwk:
                    SubsystemLoader.Load(Subsystem.Core);

                    // TODO: Move this somewhere else.
                    // Subsystem.Core should load mouse and water config, but that isn't the case with at least BFME2.
                    IniDataContext.LoadIniFile(@"Data\INI\Mouse.ini");
                    IniDataContext.LoadIniFile(@"Data\INI\Water.ini");
                    IniDataContext.LoadIniFile(@"Data\INI\AudioSettings.ini");

                    break;

                default:
                    break;
                }

                // TODO: Defer subsystem loading until necessary
                switch (sageGame)
                {
                // Only load these INI files for a subset of games, because we can't parse them for others yet.
                case SageGame.CncGenerals:
                case SageGame.CncGeneralsZeroHour:
                case SageGame.Bfme:
                case SageGame.Bfme2:
                case SageGame.Bfme2Rotwk:
                    SubsystemLoader.Load(Subsystem.Players);
                    SubsystemLoader.Load(Subsystem.ParticleSystems);
                    SubsystemLoader.Load(Subsystem.ObjectCreation);
                    SubsystemLoader.Load(Subsystem.Multiplayer);
                    SubsystemLoader.Load(Subsystem.LinearCampaign);
                    break;

                default:
                    break;
                }

                _contentLoaders = new Dictionary <Type, ContentLoader>
                {
                    { typeof(Model), AddDisposable(new ModelLoader()) },
                    { typeof(Scene3D), AddDisposable(new MapLoader()) },
                    { typeof(Texture), AddDisposable(new TextureLoader(graphicsDevice)) },
                    { typeof(Window), AddDisposable(new WindowLoader(this, wndCallbackResolver, Language)) },
                    { typeof(AptWindow), AddDisposable(new AptLoader()) },
                };

                _cachedObjects = new Dictionary <string, object>();

                TranslationManager = Translation.TranslationManager.Instance;
                Translation.TranslationManager.LoadGameStrings(fileSystem, Language, sageGame);

                _cachedFonts = new Dictionary <FontKey, Font>();

                var linearClampSamplerDescription = SamplerDescription.Linear;
                linearClampSamplerDescription.AddressModeU = SamplerAddressMode.Clamp;
                linearClampSamplerDescription.AddressModeV = SamplerAddressMode.Clamp;
                linearClampSamplerDescription.AddressModeW = SamplerAddressMode.Clamp;
                LinearClampSampler = AddDisposable(
                    graphicsDevice.ResourceFactory.CreateSampler(ref linearClampSamplerDescription));

                var pointClampSamplerDescription = SamplerDescription.Point;
                pointClampSamplerDescription.AddressModeU = SamplerAddressMode.Clamp;
                pointClampSamplerDescription.AddressModeV = SamplerAddressMode.Clamp;
                pointClampSamplerDescription.AddressModeW = SamplerAddressMode.Clamp;
                PointClampSampler = AddDisposable(
                    graphicsDevice.ResourceFactory.CreateSampler(ref pointClampSamplerDescription));

                NullTexture = AddDisposable(graphicsDevice.ResourceFactory.CreateTexture(TextureDescription.Texture2D(1, 1, 1, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.Sampled)));

                _cachedNullStructuredBuffers = new Dictionary <uint, DeviceBuffer>();

                SolidWhiteTexture = AddDisposable(graphicsDevice.CreateStaticTexture2D(
                                                      1, 1, 1,
                                                      new TextureMipMapData(
                                                          new byte[] { 255, 255, 255, 255 },
                                                          4, 4, 1, 1),
                                                      PixelFormat.R8_G8_B8_A8_UNorm));

                ShaderResources = AddDisposable(new ShaderResourceManager(graphicsDevice, SolidWhiteTexture));

                WndImageLoader = AddDisposable(new WndImageLoader(this, new MappedImageLoader(this)));

                _fallbackFonts = new FontCollection();
                var assembly   = Assembly.GetExecutingAssembly();
                var fontStream = assembly.GetManifestResourceStream($"OpenSage.Content.Fonts.{_fallbackEmbeddedFont}-Regular.ttf");
                _fallbackFonts.Install(fontStream);
                fontStream = assembly.GetManifestResourceStream($"OpenSage.Content.Fonts.{_fallbackEmbeddedFont}-Bold.ttf");
                _fallbackFonts.Install(fontStream);
            }
        }
Exemple #41
0
 protected override Texture CreateTextureCore(ref TextureDescription description)
 {
     return(new MTLTexture(ref description, _gd));
 }
Exemple #42
0
        protected override void CreateResources(ResourceFactory factory)
        {
            _vertexLayout = new VertexLayoutDescription(
                new VertexElementDescription("Position", VertexElementSemantic.Position, VertexElementFormat.Float3),
                new VertexElementDescription("UV", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2),
                new VertexElementDescription("Color", VertexElementSemantic.Color, VertexElementFormat.Float3),
                new VertexElementDescription("Normal", VertexElementSemantic.Normal, VertexElementFormat.Float3));

            using (Stream planeModelStream = OpenEmbeddedAssetStream("plane2.dae"))
            {
                _planeModel = new Model(
                    GraphicsDevice,
                    factory,
                    planeModelStream,
                    "dae",
                    _vertexLayout,
                    new Model.ModelCreateInfo(new Vector3(0.5f, 0.5f, 0.5f), Vector2.One, Vector3.Zero));
            }

            using (Stream dragonModelStream = OpenEmbeddedAssetStream("chinesedragon.dae"))
            {
                _dragonModel = new Model(
                    GraphicsDevice,
                    factory,
                    dragonModelStream,
                    "dae",
                    _vertexLayout,
                    new Model.ModelCreateInfo(new Vector3(0.3f, -0.3f, 0.3f), Vector2.One, Vector3.Zero));
            }

            using (Stream colorMapStream = OpenEmbeddedAssetStream("darkmetal_bc3_unorm.ktx"))
            {
                _colorMap = KtxFile.LoadTexture(
                    GraphicsDevice,
                    factory,
                    colorMapStream,
                    PixelFormat.BC3_UNorm);
            }
            _colorView = factory.CreateTextureView(_colorMap);

            _offscreenColor = factory.CreateTexture(TextureDescription.Texture2D(
                                                        OffscreenWidth, OffscreenHeight, 1, 1,
                                                        PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.RenderTarget | TextureUsage.Sampled));
            _offscreenView = factory.CreateTextureView(_offscreenColor);
            Texture offscreenDepth = factory.CreateTexture(TextureDescription.Texture2D(
                                                               OffscreenWidth, OffscreenHeight, 1, 1, PixelFormat.R16_UNorm, TextureUsage.DepthStencil));

            _offscreenFB = factory.CreateFramebuffer(new FramebufferDescription(offscreenDepth, _offscreenColor));

            ShaderSetDescription phongShaders = new ShaderSetDescription(
                new[] { _vertexLayout },
                new[]
            {
                LoadShader(factory, "Phong", ShaderStages.Vertex, "VS"),
                LoadShader(factory, "Phong", ShaderStages.Fragment, "FS")
            });

            ResourceLayout phongLayout = factory.CreateResourceLayout(new ResourceLayoutDescription(
                                                                          new ResourceLayoutElementDescription("UBO", ResourceKind.UniformBuffer, ShaderStages.Vertex)));

            GraphicsPipelineDescription pd = new GraphicsPipelineDescription(
                BlendStateDescription.SingleOverrideBlend,
                DepthStencilStateDescription.DepthOnlyLessEqual,
                new RasterizerStateDescription(FaceCullMode.Front, PolygonFillMode.Solid, FrontFace.Clockwise, true, false),
                PrimitiveTopology.TriangleList,
                phongShaders,
                phongLayout,
                _offscreenFB.OutputDescription);

            _offscreenPipeline = factory.CreateGraphicsPipeline(pd);

            pd.Outputs         = GraphicsDevice.SwapchainFramebuffer.OutputDescription;
            pd.RasterizerState = RasterizerStateDescription.Default;
            _dragonPipeline    = factory.CreateGraphicsPipeline(pd);

            ResourceLayout mirrorLayout = factory.CreateResourceLayout(new ResourceLayoutDescription(
                                                                           new ResourceLayoutElementDescription("UBO", ResourceKind.UniformBuffer, ShaderStages.Vertex),
                                                                           new ResourceLayoutElementDescription("ReflectionMap", ResourceKind.TextureReadOnly, ShaderStages.Fragment),
                                                                           new ResourceLayoutElementDescription("ReflectionMapSampler", ResourceKind.Sampler, ShaderStages.Fragment),
                                                                           new ResourceLayoutElementDescription("ColorMap", ResourceKind.TextureReadOnly, ShaderStages.Fragment),
                                                                           new ResourceLayoutElementDescription("ColorMapSampler", ResourceKind.Sampler, ShaderStages.Fragment)));

            ShaderSetDescription mirrorShaders = new ShaderSetDescription(
                new[] { _vertexLayout },
                new[]
            {
                LoadShader(factory, "Mirror", ShaderStages.Vertex, "VS"),
                LoadShader(factory, "Mirror", ShaderStages.Fragment, "FS")
            });

            GraphicsPipelineDescription mirrorPD = new GraphicsPipelineDescription(
                BlendStateDescription.SingleOverrideBlend,
                DepthStencilStateDescription.DepthOnlyLessEqual,
                new RasterizerStateDescription(FaceCullMode.None, PolygonFillMode.Solid, FrontFace.Clockwise, true, false),
                PrimitiveTopology.TriangleList,
                mirrorShaders,
                mirrorLayout,
                GraphicsDevice.SwapchainFramebuffer.OutputDescription);

            _mirrorPipeline = factory.CreateGraphicsPipeline(ref mirrorPD);

            _uniformBuffers_vsShared    = factory.CreateBuffer(new BufferDescription(208, BufferUsage.UniformBuffer | BufferUsage.Dynamic));
            _uniformBuffers_vsMirror    = factory.CreateBuffer(new BufferDescription(208, BufferUsage.UniformBuffer | BufferUsage.Dynamic));
            _uniformBuffers_vsOffScreen = factory.CreateBuffer(new BufferDescription(208, BufferUsage.UniformBuffer | BufferUsage.Dynamic));

            _offscreenResourceSet = factory.CreateResourceSet(new ResourceSetDescription(phongLayout, _uniformBuffers_vsOffScreen));
            _dragonResourceSet    = factory.CreateResourceSet(new ResourceSetDescription(phongLayout, _uniformBuffers_vsShared));
            _mirrorResourceSet    = factory.CreateResourceSet(new ResourceSetDescription(mirrorLayout,
                                                                                         _uniformBuffers_vsMirror,
                                                                                         _offscreenView,
                                                                                         GraphicsDevice.LinearSampler,
                                                                                         _colorView,
                                                                                         GraphicsDevice.Aniso4xSampler));

            _cl = factory.CreateCommandList();
        }
Exemple #43
0
        public GpuSurface CreateGpuSurface(bool isFrameworkInternal,
                                           uint width,
                                           uint height,
                                           PixelFormat pixelFormat,
                                           bool hasDepthBuffer,
                                           SamplerType samplerType,
                                           uint numberMipLevels,
                                           bool isGpuToCpuStagingTexture)
        {
            if (width == 0 || height == 0)
            {
                throw new Yak2DException("Internal Framework Exception: GpuSurfaceFactory, texture size must be non 0");
            }

            if (numberMipLevels == 0)
            {
                numberMipLevels = 1;
            }

            var texture = _components.Factory.CreateTexture(TextureDescription.Texture2D(
                                                                width,
                                                                height,
                                                                numberMipLevels,
                                                                1,
                                                                pixelFormat,
                                                                isGpuToCpuStagingTexture ? TextureUsage.Staging : TextureUsage.RenderTarget | TextureUsage.Sampled,
                                                                TextureSampleCountConverter.ConvertYakToVeldrid(_components.SwapChainFramebufferSampleCount)
                                                                ));

            var view = isGpuToCpuStagingTexture ? null : _components.Factory.CreateTextureView(texture);

            var depthStencil = hasDepthBuffer ?
                               _components.Factory.CreateTexture(TextureDescription.Texture2D(
                                                                     width, height, 1, 1, PixelFormat.R16_UNorm, TextureUsage.DepthStencil
                                                                     )) : null;

            var buffer = isGpuToCpuStagingTexture ? null : _components.Factory.CreateFramebuffer(new FramebufferDescription(hasDepthBuffer ? depthStencil : null, texture));

            Sampler wrap   = null;
            Sampler mirror = null;

            switch (samplerType)
            {
            case SamplerType.Anisotropic:
                wrap   = _anisotropicSamplerWrap;
                mirror = _anisotropicSamplerMirror;
                break;

            case SamplerType.Linear:
                wrap   = _linearSamplerWrap;
                mirror = _linearSamplerMirror;
                break;

            case SamplerType.Point:
                wrap   = _pointSamplerWrap;
                mirror = _pointSamplerMirror;
                break;

            case SamplerType.PointMagLinearMin:
                wrap   = _pointMagLinearMinSamplerWrap;
                mirror = _pointMagLinearMinSamplerMirror;
                break;
            }

            var resourceSet_wrap = isGpuToCpuStagingTexture ? null : _components.Factory.CreateResourceSet(new ResourceSetDescription(
                                                                                                               _cachedTextureResourceLayout,
                                                                                                               view,
                                                                                                               wrap
                                                                                                               ));

            var resourceSet_mirror = isGpuToCpuStagingTexture ? null : _components.Factory.CreateResourceSet(new ResourceSetDescription(
                                                                                                                 _cachedTextureResourceLayout,
                                                                                                                 view,
                                                                                                                 mirror
                                                                                                                 ));

            return(new GpuSurface
            {
                Type = isFrameworkInternal ? GpuSurfaceType.RenderTarget | GpuSurfaceType.Internal : GpuSurfaceType.RenderTarget | GpuSurfaceType.User,
                Texture = texture,
                TextureView = view,
                Framebuffer = buffer,
                ResourceSet_TexWrap = resourceSet_wrap,
                ResourceSet_TexMirror = resourceSet_mirror
            });
        }
 private void CreateDepthTexture()
 {
     if (_depthFormat.HasValue)
     {
         _depthAttachment?.Target.Dispose();
         VkTexture depthTexture = (VkTexture)_gd.ResourceFactory.CreateTexture(TextureDescription.Texture2D(
                                                                                   Math.Max(1, _scExtent.width),
                                                                                   Math.Max(1, _scExtent.height),
                                                                                   1,
                                                                                   1,
                                                                                   _depthFormat.Value,
                                                                                   TextureUsage.DepthStencil));
         _depthAttachment = new FramebufferAttachment(depthTexture, 0);
     }
 }
 protected override Texture CreateTextureCore(ulong nativeTexture, ref TextureDescription description)
 => Track(_factory.CreateTexture(nativeTexture, description));
 protected override Texture CreateTextureCore(ref TextureDescription description)
 => Track(_factory.CreateTexture(description));
        public virtual void CreateDeviceObjects(GraphicsDevice gd, CommandList cl, GraphicsSystem sc)
        {
            ResourceFactory factory = gd.ResourceFactory;

            ProjectionMatrixBuffer          = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic));
            ViewMatrixBuffer                = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic));
            LightViewProjectionBuffer0      = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic));
            LightViewProjectionBuffer0.Name = "LightViewProjectionBuffer0";
            LightViewProjectionBuffer1      = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic));
            LightViewProjectionBuffer1.Name = "LightViewProjectionBuffer1";
            LightViewProjectionBuffer2      = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic));
            LightViewProjectionBuffer2.Name = "LightViewProjectionBuffer2";
            DepthLimitsBuffer               = factory.CreateBuffer(new BufferDescription((uint)Unsafe.SizeOf <DepthCascadeLimits>(), BufferUsage.UniformBuffer | BufferUsage.Dynamic));
            LightInfoBuffer  = factory.CreateBuffer(new BufferDescription((uint)Unsafe.SizeOf <DirectionalLightInfo>(), BufferUsage.UniformBuffer | BufferUsage.Dynamic));
            CameraInfoBuffer = factory.CreateBuffer(new BufferDescription((uint)Unsafe.SizeOf <CameraInfo>(), BufferUsage.UniformBuffer | BufferUsage.Dynamic));
            if (Camera != null)
            {
                UpdateCameraBuffers(cl);
            }

            PointLightsBuffer = factory.CreateBuffer(new BufferDescription((uint)Unsafe.SizeOf <PointLightsInfo.Blittable>(), BufferUsage.UniformBuffer));

            PointLightsInfo pli = new PointLightsInfo();

            pli.NumActiveLights = 4;
            pli.PointLights     = new PointLightInfo[4]
            {
                new PointLightInfo {
                    Color = new Vector3(1f, 1f, 1f), Position = new Vector3(-50, 5, 0), Range = 75f
                },
                new PointLightInfo {
                    Color = new Vector3(1f, .75f, .9f), Position = new Vector3(0, 5, 0), Range = 100f
                },
                new PointLightInfo {
                    Color = new Vector3(1f, 1f, 0.6f), Position = new Vector3(50, 5, 0), Range = 40f
                },
                new PointLightInfo {
                    Color = new Vector3(0.75f, 0.75f, 1f), Position = new Vector3(25, 5, 45), Range = 150f
                },
            };

            cl.UpdateBuffer(PointLightsBuffer, 0, pli.GetBlittable());

            TextureSamplerResourceLayout = factory.CreateResourceLayout(new ResourceLayoutDescription(
                                                                            new ResourceLayoutElementDescription("SourceTexture", ResourceKind.TextureReadOnly, ShaderStages.Fragment),
                                                                            new ResourceLayoutElementDescription("SourceSampler", ResourceKind.Sampler, ShaderStages.Fragment)));

            uint ReflectionMapSize = 2048;

            ReflectionColorTexture   = factory.CreateTexture(TextureDescription.Texture2D(ReflectionMapSize, ReflectionMapSize, 12, 1, PixelFormat.R8_G8_B8_A8_UNorm, TextureUsage.RenderTarget | TextureUsage.Sampled | TextureUsage.GenerateMipmaps));
            ReflectionDepthTexture   = factory.CreateTexture(TextureDescription.Texture2D(ReflectionMapSize, ReflectionMapSize, 1, 1, PixelFormat.R32_Float, TextureUsage.DepthStencil));
            ReflectionColorView      = factory.CreateTextureView(ReflectionColorTexture);
            ReflectionFramebuffer    = factory.CreateFramebuffer(new FramebufferDescription(ReflectionDepthTexture, ReflectionColorTexture));
            ReflectionViewProjBuffer = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic));

            MirrorClipPlaneBuffer = factory.CreateBuffer(new BufferDescription(32, BufferUsage.UniformBuffer));
            gd.UpdateBuffer(MirrorClipPlaneBuffer, 0, new ClipPlaneInfo(MirrorMesh.Plane, true));
            NoClipPlaneBuffer = factory.CreateBuffer(new BufferDescription(32, BufferUsage.UniformBuffer));
            gd.UpdateBuffer(NoClipPlaneBuffer, 0, new ClipPlaneInfo());

            RecreateWindowSizedResources(gd, cl);

            ShadowMaps.CreateDeviceResources(gd);
        }
Exemple #48
0
        /// <summary>
        /// Determines the number of image array entries and pixel size.
        /// </summary>
        /// <param name="description">The texture description.</param>
        /// <param name="nImages">The number of entries in the image array.</param>
        /// <param name="pixelSize">The total pixel size.</param>
        private static void DetermineImages(TextureDescription description, out int nImages, out int pixelSize)
        {
            Debug.Assert(description.Width > 0 && description.Height > 0 && description.Depth > 0);
              Debug.Assert(description.ArraySize > 0);
              Debug.Assert(description.MipLevels > 0);

              pixelSize = 0;
              nImages = 0;

              switch (description.Dimension)
              {
            case TextureDimension.Texture1D:
            case TextureDimension.Texture2D:
            case TextureDimension.TextureCube:
              for (int item = 0; item < description.ArraySize; item++)
              {
            int w = description.Width;
            int h = description.Height;

            for (int level = 0; level < description.MipLevels; level++)
            {
              int rowPitch, slicePitch;
              TextureHelper.ComputePitch(description.Format, w, h, out rowPitch, out slicePitch, ComputePitchFlags.None);
              pixelSize += slicePitch;
              nImages++;

              if (h > 1)
                h >>= 1;

              if (w > 1)
                w >>= 1;
            }
              }
              break;

            case TextureDimension.Texture3D:
              {
            int w = description.Width;
            int h = description.Height;
            int d = description.Depth;

            for (int level = 0; level < description.MipLevels; level++)
            {
              int rowPitch, slicePitch;
              TextureHelper.ComputePitch(description.Format, w, h, out rowPitch, out slicePitch, ComputePitchFlags.None);

              for (int slice = 0; slice < d; slice++)
              {
                pixelSize += slicePitch;
                nImages++;
              }

              if (h > 1)
                h >>= 1;

              if (w > 1)
                w >>= 1;

              if (d > 1)
                d >>= 1;
            }
              }
              break;

            default:
              Debug.Fail("Unexpected texture dimension");
              break;
              }
        }
        public void RecreateWindowSizedResources(GraphicsDevice gd, CommandList cl)
        {
            MainSceneColorTexture?.Dispose();
            MainSceneDepthTexture?.Dispose();
            MainSceneResolvedColorTexture?.Dispose();
            MainSceneResolvedColorView?.Dispose();
            MainSceneViewResourceSet?.Dispose();
            MainSceneFramebuffer?.Dispose();
            DuplicatorTarget0?.Dispose();
            DuplicatorTarget1?.Dispose();
            DuplicatorTargetView0?.Dispose();
            DuplicatorTargetView1?.Dispose();
            DuplicatorTargetSet0?.Dispose();
            DuplicatorTargetSet1?.Dispose();
            DuplicatorFramebuffer?.Dispose();

            ResourceFactory factory = gd.ResourceFactory;

            TextureSampleCount mainSceneSampleCountCapped = (TextureSampleCount)Math.Min(
                (int)gd.GetSampleCountLimit(PixelFormat.R8_G8_B8_A8_UNorm, false),
                (int)MainSceneSampleCount);

            TextureDescription mainColorDesc = TextureDescription.Texture2D(
                gd.SwapchainFramebuffer.Width,
                gd.SwapchainFramebuffer.Height,
                1,
                1,
                PixelFormat.R8_G8_B8_A8_UNorm,
                TextureUsage.RenderTarget | TextureUsage.Sampled,
                mainSceneSampleCountCapped);

            MainSceneColorTexture = factory.CreateTexture(ref mainColorDesc);
            if (mainSceneSampleCountCapped != TextureSampleCount.Count1)
            {
                mainColorDesc.SampleCount     = TextureSampleCount.Count1;
                MainSceneResolvedColorTexture = factory.CreateTexture(ref mainColorDesc);
            }
            else
            {
                MainSceneResolvedColorTexture = MainSceneColorTexture;
            }
            MainSceneResolvedColorView = factory.CreateTextureView(MainSceneResolvedColorTexture);
            MainSceneDepthTexture      = factory.CreateTexture(TextureDescription.Texture2D(
                                                                   gd.SwapchainFramebuffer.Width,
                                                                   gd.SwapchainFramebuffer.Height,
                                                                   1,
                                                                   1,
                                                                   PixelFormat.R32_Float,
                                                                   TextureUsage.DepthStencil,
                                                                   mainSceneSampleCountCapped));
            MainSceneFramebuffer     = factory.CreateFramebuffer(new FramebufferDescription(MainSceneDepthTexture, MainSceneColorTexture));
            MainSceneViewResourceSet = factory.CreateResourceSet(new ResourceSetDescription(TextureSamplerResourceLayout, MainSceneResolvedColorView, gd.PointSampler));

            TextureDescription colorTargetDesc = TextureDescription.Texture2D(
                gd.SwapchainFramebuffer.Width,
                gd.SwapchainFramebuffer.Height,
                1,
                1,
                PixelFormat.R8_G8_B8_A8_UNorm,
                TextureUsage.RenderTarget | TextureUsage.Sampled);

            DuplicatorTarget0     = factory.CreateTexture(ref colorTargetDesc);
            DuplicatorTargetView0 = factory.CreateTextureView(DuplicatorTarget0);
            DuplicatorTarget1     = factory.CreateTexture(ref colorTargetDesc);
            DuplicatorTargetView1 = factory.CreateTextureView(DuplicatorTarget1);
            DuplicatorTargetSet0  = factory.CreateResourceSet(new ResourceSetDescription(TextureSamplerResourceLayout, DuplicatorTargetView0, gd.PointSampler));
            DuplicatorTargetSet1  = factory.CreateResourceSet(new ResourceSetDescription(TextureSamplerResourceLayout, DuplicatorTargetView1, gd.PointSampler));

            FramebufferDescription fbDesc = new FramebufferDescription(null, DuplicatorTarget0, DuplicatorTarget1);

            DuplicatorFramebuffer = factory.CreateFramebuffer(ref fbDesc);
        }
Exemple #50
0
        /// <summary>
        /// Validates the texture.
        /// </summary>
        /// <param name="description">The texture description.</param>
        /// <exception cref="ArgumentException">
        /// The <paramref name="description"/> is invalid.
        /// </exception>
        /// <exception cref="NotSupportedException">
        /// The specified format is not supported.
        /// </exception>
        private static void ValidateTexture(TextureDescription description)
        {
            if (!TextureHelper.IsValid(description.Format))
            throw new ArgumentException("The specified texture format is not supported.", "description");

              if (TextureHelper.IsPalettized(description.Format))
            throw new ArgumentException("Palettized texture formats are not supported.", "description");

              switch (description.Dimension)
              {
            case TextureDimension.Texture1D:
              if (description.Width <= 0 || description.Height != 1 || description.Depth != 1 || description.ArraySize <= 0)
            throw new ArgumentException("Invalid texture description.", "description");

              //if (TextureHelper.IsVideo(description.Format))
              //  throw new NotSupportedException("Video formats are not supported.");

              if (!TextureHelper.ValidateMipLevels(description.Width, 1, description.MipLevels))
            throw new ArgumentException("Invalid number of mipmap levels.", "description");
              break;

            case TextureDimension.Texture2D:
            case TextureDimension.TextureCube:
              if (description.Width <= 0 || description.Height <= 0 || description.Depth != 1 || description.ArraySize <= 0)
            throw new ArgumentException("Invalid texture description.", "description");

              if (description.Dimension == TextureDimension.TextureCube)
              {
            if ((description.ArraySize % 6) != 0)
              throw new ArgumentException("All six faces need to be specified for cube maps.", "description");

            //if (TextureHelper.IsVideo(description.Format))
            //  throw new NotSupportedException("Video formats are not supported.");
              }

              if (!TextureHelper.ValidateMipLevels(description.Width, description.Height, description.MipLevels))
            throw new ArgumentException("Invalid number of mipmaps levels.", "description");
              break;

            case TextureDimension.Texture3D:
              if (description.Width <= 0 || description.Height <= 0 || description.Depth <= 0 || description.ArraySize != 1)
            throw new ArgumentException("Invalid texture description.", "description");

              //if (TextureHelper.IsVideo(description.Format) || TextureHelper.IsPlanar(description.Format)
              //    || TextureHelper.IsDepthStencil(description.Format))
              //  throw new NotSupportedException("The specified texture format is not supported.");

              if (!TextureHelper.ValidateMipLevels(description.Width, description.Height, description.Depth, description.MipLevels))
            throw new ArgumentException("Invalid number of mipmaps levels.", "description");
              break;

            default:
              throw new NotSupportedException("The specified texture dimension is not supported.");
              }
        }
        //--------------------------------------------------------------
        /// <summary>
        /// Converts an XNA <see cref="TextureContent"/> to a DigitalRune <see cref="Texture"/>.
        /// </summary>
        /// <param name="textureContent">The <see cref="TextureContent"/>.</param>
        /// <returns>The <see cref="Texture"/>.</returns>
        public static Texture ToTexture(TextureContent textureContent)
        {
            SurfaceFormat surfaceFormat;
              var bitmapContent0 = textureContent.Faces[0][0];
              if (!bitmapContent0.TryGetFormat(out surfaceFormat))
            throw new InvalidContentException("Invalid surface format.", textureContent.Identity);

              var texture2DContent = textureContent as Texture2DContent;
              if (texture2DContent != null)
              {
            var description = new TextureDescription
            {
              Dimension = TextureDimension.Texture2D,
              Width = bitmapContent0.Width,
              Height = bitmapContent0.Height,
              Depth = 1,
              MipLevels = texture2DContent.Mipmaps.Count,
              ArraySize = 1,
              Format = surfaceFormat.ToDataFormat()
            };

            var texture = new Texture(description);
            for (int mipIndex = 0; mipIndex < description.MipLevels; mipIndex++)
            {
              var bitmapContent = texture2DContent.Mipmaps[mipIndex];
              var image = texture.Images[texture.GetImageIndex(mipIndex, 0, 0)];
              Buffer.BlockCopy(bitmapContent.GetPixelData(), 0, image.Data, 0, image.Data.Length);
            }

            return texture;
              }

              var textureCubeContent = textureContent as TextureCubeContent;
              if (textureCubeContent != null)
              {
            var description = new TextureDescription
            {
              Dimension = TextureDimension.TextureCube,
              Width = bitmapContent0.Width,
              Height = bitmapContent0.Height,
              Depth = 1,
              MipLevels = textureCubeContent.Faces[0].Count,
              ArraySize = 6,
              Format = surfaceFormat.ToDataFormat()
            };

            var texture = new Texture(description);
            for (int faceIndex = 0; faceIndex < 6; faceIndex++)
            {
              for (int mipIndex = 0; mipIndex < description.MipLevels; mipIndex++)
              {
            var bitmapContent = textureCubeContent.Faces[faceIndex][mipIndex];
            var image = texture.Images[texture.GetImageIndex(mipIndex, faceIndex, 0)];
            Buffer.BlockCopy(bitmapContent.GetPixelData(), 0, image.Data, 0, image.Data.Length);
              }
            }

            return texture;
              }

              var texture3DContent = textureContent as Texture3DContent;
              if (texture3DContent != null)
              {
            var description = new TextureDescription
            {
              Dimension = TextureDimension.Texture3D,
              Width = bitmapContent0.Width,
              Height = bitmapContent0.Height,
              Depth = texture3DContent.Faces.Count,
              MipLevels = texture3DContent.Faces[0].Count,
              ArraySize = 1,
              Format = surfaceFormat.ToDataFormat()
            };

            var texture = new Texture(description);
            for (int zIndex = 0; zIndex < description.Depth; zIndex++)
            {
              for (int mipIndex = 0; mipIndex < description.MipLevels; mipIndex++)
              {
            var bitmapContent = texture3DContent.Faces[zIndex][mipIndex];
            var image = texture.Images[texture.GetImageIndex(mipIndex, 0, zIndex)];
            Buffer.BlockCopy(bitmapContent.GetPixelData(), 0, image.Data, 0, image.Data.Length);
              }
            }

            return texture;
              }

              throw new InvalidOperationException("Invalid texture dimension.");
        }