Пример #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="WorldViewProjection"/> class.
        /// </summary>
        /// <param name="graphics">The graphics interface to use.</param>
        public Light(GorgonGraphics graphics)
        {
            _lightData[0].Attenuation   = 6.0f;
            _lightData[0].LightColor    = GorgonColor.White;
            _lightData[0].LightPosition = Vector3.Zero;
            _lightData[0].SpecularColor = GorgonColor.White;
            _lightData[0].SpecularPower = 512.0f;

            _buffer = graphics.Buffers.CreateConstantBuffer("LightBuffer",
                                                            new GorgonConstantBufferSettings
            {
                SizeInBytes = LightData.Size * _lightData.Length,
                Usage       = BufferUsage.Default
            });

            _lightStore = new GorgonDataStream(_buffer.SizeInBytes);
            unsafe
            {
                DirectAccess.ZeroMemory(_lightStore.UnsafePointer, _buffer.SizeInBytes);
                var data = (LightData *)_lightStore.UnsafePointer;
                *   data = _lightData[0];
            }

            _buffer.Update(_lightStore);

            graphics.Shaders.PixelShader.ConstantBuffers[1] = _buffer;
        }
Пример #2
0
        /// <summary>
        /// Function to flush the cache by rendering its contents.
        /// </summary>
        public void Flush()
        {
            GorgonVertexBufferBinding binding = _renderer.Graphics.Input.VertexBuffers[0];

            // Apply the current projection/view matrix.
            if (_renderer.Camera.NeedsUpdate)
            {
                _renderer.Camera.Update();
            }

            // Only advance the cache when we've got something to copy into the buffer.
            switch (binding.VertexBuffer.Settings.Usage)
            {
            case BufferUsage.Dynamic:
                // If we're not at the beginning of the cache, then
                // do a no overwrite lock.  This will help performance.
                var flags = BufferLockFlags.Write
                            | (_currentVertex > 0 ? BufferLockFlags.NoOverwrite : BufferLockFlags.Discard);

                using (GorgonDataStream stream = binding.VertexBuffer.Lock(flags, _renderer.Graphics))
                {
                    stream.Position = _currentVertex * Gorgon2DVertex.SizeInBytes;
                    stream.WriteRange(_vertices, _currentVertex, _verticesWritten);
                    binding.VertexBuffer.Unlock();
                }
                break;

            default:
                binding.VertexBuffer.Update(_vertices,
                                            _currentVertex * Gorgon2DVertex.SizeInBytes,
                                            _renderer.Graphics);
                break;
            }

            // Draw the buffer data.
            switch (_renderer.Graphics.Input.PrimitiveType)
            {
            case PrimitiveType.PointList:
            case PrimitiveType.LineList:
                _renderer.Graphics.Output.Draw(_currentVertex, _verticesWritten);
                break;

            case PrimitiveType.TriangleList:
                if (_renderer.Graphics.Input.IndexBuffer == null)
                {
                    _renderer.Graphics.Output.Draw(_currentVertex, _verticesWritten);
                }
                else
                {
                    _renderer.Graphics.Output.DrawIndexed(_firstIndex, _vertexOffset, _indexCount);
                }
                break;
            }

            _currentVertex   = _nextVertex;
            _firstIndex     += _indexCount;
            _verticesWritten = 0;
            _indexCount      = 0;
            NeedsFlush       = false;
        }
Пример #3
0
        public void DataStreamMarshalTest()
        {
            MyStruct[] items = new MyStruct[50];

            for (int i = 0; i < items.Length; ++i)
            {
                items[i] = new MyStruct
                {
                    MyInt = i,
                    MyStr = "String #" + i + "\0"
                };
            }

            using (GorgonDataStream stream = GorgonDataStream.MarshalArrayToStream(items))
            {
                byte[] expected = Resources.DataStreamMarshalOut1;

                // Not sure how I can test the validity of the data?
                byte[] dataBlock = new byte[stream.Length];

                stream.Read(dataBlock, 0, dataBlock.Length);

                Assert.IsTrue(expected.SequenceEqual(dataBlock));
            }
        }
Пример #4
0
 /// <summary>
 /// Function to read a font from memory.
 /// </summary>
 /// <param name="name">Name of the font object.</param>
 /// <param name="fontData">Byte array containing the font data.</param>
 /// <param name="missingTextureFunction">[Optional] A function that is called if a required user defined texture has not been loaded for the font.</param>
 /// <returns>The font in the array.</returns>
 /// <remarks>
 /// The fonts will not store user defined glyph textures, in order to facilitate the loading of the textures the users must either load the texture
 /// before loading the font or specify a callback method in the <paramref name="missingTextureFunction"/> parameter.  This function will pass a name
 /// for the texture and will expect a texture to be returned.  If NULL is returned, then an exception will be raised.
 /// <para>Fonts may only be created on the immediate context.</para></remarks>
 /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="fontData"/> or the <paramref name="name"/> parameters are NULL.</exception>
 /// <exception cref="System.ArgumentException">Thrown if the name parameter is an empty string.
 /// <para>-or-</para>
 /// <para>Thrown if the font uses external textures.</para>
 /// <para>-or-</para>
 /// <para>Thrown if the fontData array is empty.</para>
 /// </exception>
 /// <exception cref="GorgonLibrary.GorgonException">Thrown if the font cannot be read.
 /// <para>-or-</para>
 /// <para>Thrown if the graphics context is deferred.</para>
 /// </exception>
 public GorgonFont FromMemory(string name, byte[] fontData, Func <string, Size, GorgonTexture2D> missingTextureFunction = null)
 {
     using (var memoryStream = new GorgonDataStream(fontData))
     {
         return(FromStream(name, memoryStream, missingTextureFunction));
     }
 }
Пример #5
0
        /// <summary>
        /// Function called when the effect is being initialized.
        /// </summary>
        /// <remarks>
        /// Use this method to set up the effect upon its creation.  For example, this method could be used to create the required shaders for the effect.
        /// </remarks>
        protected override void OnInitialize()
        {
            base.OnInitialize();

            _xOffsets   = new Vector4[13];
            _yOffsets   = new Vector4[13];
            _kernel     = new float[13];
            _blurBuffer = Graphics.ImmediateContext.Buffers.CreateConstantBuffer("Gorgon2DGaussianBlurEffect Constant Buffer",
                                                                                 new GorgonConstantBufferSettings
            {
                SizeInBytes = DirectAccess.SizeOf <Vector4>() * _xOffsets.Length
            });
            _blurStaticBuffer = Graphics.ImmediateContext.Buffers.CreateConstantBuffer("Gorgon2DGaussianBlurEffect Static Constant Buffer",
                                                                                       new GorgonConstantBufferSettings
            {
                SizeInBytes = DirectAccess.SizeOf <Vector4>() * (_kernel.Length + 1)
            });

            _blurKernelStream = new GorgonDataStream(_blurStaticBuffer.SizeInBytes);

            Passes[0].PixelShader = Graphics.ImmediateContext.Shaders.CreateShader <GorgonPixelShader>("Effect.PS.GaussBlur", "GorgonPixelShaderGaussBlur", "#GorgonInclude \"Gorgon2DShaders\"");

            UpdateKernel();

            _blurSprite = Gorgon2D.Renderables.CreateSprite("Gorgon2DGaussianBlurEffect Sprite", new GorgonSpriteSettings
            {
                Size = BlurRenderTargetsSize
            });

            _blurSprite.BlendingMode  = BlendingMode.None;
            _blurSprite.SmoothingMode = SmoothingMode.Smooth;
            _blurSprite.TextureRegion = new RectangleF(0, 0, 1, 1);
        }
Пример #6
0
        /// <summary>
        /// Function to update the buffer.
        /// </summary>
        /// <param name="stream">Stream containing the data used to update the buffer.</param>
        /// <param name="offset">Offset, in bytes, into the buffer to start writing at.</param>
        /// <param name="size">The number of bytes to write.</param>
        /// <param name="context">A graphics context to use when updating the buffer.</param>
        /// <remarks>
        /// Use the <paramref name="context" /> parameter to determine the context in which the buffer should be updated. This is necessary to use that context
        /// to update the buffer because 2 threads may not access the same resource at the same time.
        /// </remarks>
        protected override void OnUpdate(GorgonDataStream stream, int offset, int size, GorgonGraphics context)
        {
            GorgonDebug.AssertNull(stream, "stream");

#if DEBUG
            if (Settings.Usage != BufferUsage.Default)
            {
                throw new GorgonException(GorgonResult.AccessDenied, Resources.GORGFX_NOT_DEFAULT_USAGE);
            }
#endif

            context.Context.UpdateSubresource(
                new DX.DataBox
            {
                DataPointer = stream.PositionPointer,
                RowPitch    = size
            },
                D3DResource,
                0,
                new D3D11.ResourceRegion
            {
                Left   = offset,
                Right  = offset + size,
                Top    = 0,
                Bottom = 1,
                Front  = 0,
                Back   = 1
            });
        }
Пример #7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="GorgonTextureLockData"/> class.
        /// </summary>
        /// <param name="graphics">The graphics context that owns this lock.</param>
        /// <param name="texture">The texture that owns this lock.</param>
        /// <param name="cache">Lock cache that will contain this lock.</param>
        /// <param name="data">The data returned from the lock.</param>
        /// <param name="mipLevel">The mip level of the sub resource.</param>
        /// <param name="arrayIndex">Array index of the sub resource.</param>
        internal GorgonTextureLockData(GorgonGraphics graphics, GorgonTexture texture, GorgonTextureLockCache cache, DX.DataBox data, int mipLevel, int arrayIndex)
            : base(mipLevel, arrayIndex, 0)
        {
            Graphics = graphics;
            Texture  = texture;
            _cache   = cache;

            Width  = Texture.Settings.Width;
            Height = Texture.Settings.Height;
            Depth  = Texture.Settings.Depth;

            // Calculate the current size at the given mip level.
            for (int mip = 0; mip < mipLevel; ++mip)
            {
                if (Width > 1)
                {
                    Width >>= 1;
                }
                if (Height > 1)
                {
                    Height >>= 1;
                }
                if (Depth > 1)
                {
                    Depth >>= 1;
                }
            }

            PitchInformation = new GorgonFormatPitch(data.RowPitch, data.SlicePitch);
            Data             = new GorgonDataStream(data.DataPointer.ToPointer(), data.SlicePitch);
        }
Пример #8
0
        /// <summary>
        /// Function to create a index buffer.
        /// </summary>
        /// <param name="name">The name of the buffer.</param>
        /// <param name="data">Data used to initialize the buffer.</param>
        /// <param name="usage">[Optional] Usage of the buffer.</param>
        /// <param name="is32Bit">[Optional] TRUE to indicate that we're using 32 bit indices, FALSE to use 16 bit indices </param>
        /// <typeparam name="T">Type of data in the array.  Must be a value type.</typeparam>
        /// <returns>A new index buffer.</returns>
        /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="name"/> is NULL (Nothing in VB.Net).
        /// <para>-or-</para>
        /// <para>Thrown when the <paramref name="data"/> parameter is NULL.</para>
        /// </exception>
        /// <exception cref="GorgonLibrary.GorgonException">Thrown when the buffer could not be created.</exception>
        /// <exception cref="System.ArgumentException">Thrown when the <paramref name="name"/> parameter is empty.</exception>
        /// <remarks>If creating an immutable index buffer, be sure to pre-populate it via the initialData parameter.
        /// <para>This method should only be called from an immediate graphics context, if it is called from a deferred context an exception will be thrown.</para>
        /// </remarks>
        public GorgonIndexBuffer CreateIndexBuffer <T>(string name, T[] data, BufferUsage usage = BufferUsage.Default, bool is32Bit = true)
            where T : struct
        {
            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            if (data.Length == 0)
            {
                throw new ArgumentException(Resources.GORGFX_PARAMETER_MUST_NOT_BE_EMPTY, "data");
            }

            int size = data.Length * DirectAccess.SizeOf <T>();

            using (var dataStream = new GorgonDataStream(data))
            {
                return(CreateIndexBuffer(name, new GorgonIndexBufferSettings
                {
                    SizeInBytes = size,
                    IsOutput = false,
                    Usage = usage,
                    Use32BitIndices = is32Bit
                }, dataStream));
            }
        }
Пример #9
0
        /// <summary>
        /// Function to update the buffer.
        /// </summary>
        /// <param name="stream">Stream containing the data used to update the buffer.</param>
        /// <param name="offset">Offset, in bytes, into the buffer to start writing at.</param>
        /// <param name="size">The number of bytes to write.</param>
        /// <param name="deferred">[Optional] The deferred context used to update the buffer.</param>
        /// <remarks>This method can only be used with buffers that have Default usage.  Other buffer usages will thrown an exception.
        /// <para>Please note that constant buffers don't use the <paramref name="offset"/> and <paramref name="size"/> parameters.</para>
        /// <para>This method will respect the <see cref="GorgonLibrary.IO.GorgonDataStream.Position">Position</see> property of the data stream.
        /// This means that it will start reading from the stream at the current position.  To read from the beginning of the stream, set the position
        /// to 0.</para>
        /// <para>
        /// If the <paramref name="deferred"/> parameter is NULL (Nothing in VB.Net), the immediate context will be used to update the buffer.  If it is non-NULL, then it
        /// will use the specified deferred context.
        /// <para>If you are using a deferred context, it is necessary to use that context to update the buffer because 2 threads may not access the same resource at the same time.
        /// Passing a separate deferred context will alleviate that.</para>
        /// </para>
        /// </remarks>
        /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="stream"/> parameter is NULL (Nothing in VB.Net).</exception>
        /// <exception cref="GorgonLibrary.GorgonException">Thrown when the buffer usage is not set to default.</exception>
        public void Update(GorgonDataStream stream, int offset, int size, GorgonGraphics deferred = null)
        {
            if (deferred == null)
            {
                deferred = Graphics;
            }

            OnUpdate(stream, offset, size, deferred);
        }
Пример #10
0
 /// <summary>
 /// Function to update the buffer.
 /// </summary>
 /// <param name="stream">Stream containing the data used to update the buffer.</param>
 /// <param name="offset">Offset, in bytes, into the buffer to start writing at.</param>
 /// <param name="size">The number of bytes to write.</param>
 /// <param name="context">A graphics context to use when updating the buffer.</param>
 /// <remarks>
 /// Use the <paramref name="context" /> parameter to determine the context in which the buffer should be updated. This is necessary to use that context
 /// to update the buffer because 2 threads may not access the same resource at the same time.
 /// </remarks>
 protected override void OnUpdate(GorgonDataStream stream, int offset, int size, GorgonGraphics context)
 {
     context.Context.UpdateSubresource(
         new DX.DataBox
     {
         DataPointer = stream.PositionPointer,
         RowPitch    = 0,
         SlicePitch  = 0
     },
         D3DResource);
 }
Пример #11
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GorgonImageBuffer" /> class.
 /// </summary>
 /// <param name="dataStart">The data start.</param>
 /// <param name="pitchInfo">The pitch info.</param>
 /// <param name="mipLevel">Mip map level.</param>
 /// <param name="arrayIndex">Array index.</param>
 /// <param name="sliceIndex">Slice index.</param>
 /// <param name="width">The width for the buffer.</param>
 /// <param name="height">The height for the buffer.</param>
 /// <param name="depth">The depth for the buffer.</param>
 /// <param name="format">Format of the buffer.</param>
 internal unsafe GorgonImageBuffer(void *dataStart, GorgonFormatPitch pitchInfo, int mipLevel, int arrayIndex, int sliceIndex, int width, int height, int depth, BufferFormat format)
 {
     Data             = new GorgonDataStream(dataStart, pitchInfo.SlicePitch);
     PitchInformation = pitchInfo;
     MipLevel         = mipLevel;
     ArrayIndex       = arrayIndex;
     SliceIndex       = sliceIndex;
     Width            = width;
     Height           = height;
     Depth            = depth;
     Format           = format;
 }
Пример #12
0
 /// <summary>
 /// Function to create a structured buffer and initialize it with data.
 /// </summary>
 /// <param name="name">The name of the structured buffer.</param>
 /// <param name="value">Value to write to the buffer.</param>
 /// <param name="usage">Usage for the buffer.</param>
 /// <returns>A new structured buffer.</returns>
 /// <typeparam name="T">Type of data to write.  Must be a value type.</typeparam>
 /// <remarks>This method should only be called from an immediate graphics context, if it is called from a deferred context an exception will be thrown.</remarks>
 /// <exception cref="GorgonLibrary.GorgonException">Thrown when the buffer could not be created.</exception>
 public GorgonStructuredBuffer CreateStructuredBuffer <T>(string name, T value, BufferUsage usage)
     where T : struct
 {
     using (var stream = GorgonDataStream.ValueToStream(value))
     {
         return(CreateStructuredBuffer(name, new GorgonStructuredBufferSettings
         {
             Usage = usage,
             SizeInBytes = DirectAccess.SizeOf <T>(),
             StructureSize = DirectAccess.SizeOf <T>()
         }, stream));
     }
 }
Пример #13
0
        public T FromMemory <T>(string name, string entryPoint, byte[] shaderData, IList <GorgonShaderMacro> macros = null, bool isDebug = false)
#endif
            where T : GorgonShader
        {
            if (shaderData == null)
            {
                throw new ArgumentNullException("shaderData");
            }

            using (var memoryStream = new GorgonDataStream(shaderData))
            {
                return(FromStream <T>(name, entryPoint, memoryStream, shaderData.Length, macros, isDebug));
            }
        }
Пример #14
0
        /// <summary>
        /// Function used to initialize the buffer with data.
        /// </summary>
        /// <param name="data">Data to write.</param>
        /// <remarks>Passing NULL (Nothing in VB.Net) to the <paramref name="data"/> parameter should ignore the initialization and create the backing buffer as normal.</remarks>
        internal void Initialize(GorgonDataStream data)
        {
            Gorgon.Log.Print("Creating {0} Buffer '{1}'...", LoggingLevel.Verbose, BufferType, Name);

            CreateResources(data);

            // Update our statistics.
            switch (BufferType)
            {
            case BufferType.Constant:
                GorgonRenderStatistics.ConstantBufferCount++;
                GorgonRenderStatistics.ConstantBufferSize += D3DBuffer.Description.SizeInBytes;
                break;

            case BufferType.Index:
                GorgonRenderStatistics.IndexBufferCount++;
                GorgonRenderStatistics.IndexBufferSize += D3DBuffer.Description.SizeInBytes;
                break;

            case BufferType.Vertex:
                GorgonRenderStatistics.VertexBufferCount++;
                GorgonRenderStatistics.VertexBufferSize += D3DBuffer.Description.SizeInBytes;
                break;

            case BufferType.Structured:
                GorgonRenderStatistics.StructuredBufferCount++;
                GorgonRenderStatistics.StructuredBufferSize += D3DBuffer.Description.SizeInBytes;
                break;

            default:
                GorgonRenderStatistics.BufferCount++;
                GorgonRenderStatistics.BufferSize += D3DBuffer.Description.SizeInBytes;
                break;
            }

            if (IsRenderTarget)
            {
                GorgonRenderStatistics.RenderTargetCount++;
                GorgonRenderStatistics.RenderTargetSize += D3DBuffer.Description.SizeInBytes;
            }

            // Create any default shader views that are required.
            OnCreateDefaultShaderView();

            if (IsRenderTarget)
            {
                OnCreateDefaultRenderTargetView();
            }
        }
Пример #15
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Sphere" /> class.
        /// </summary>
        /// <param name="graphics">Graphics interface to use.</param>
        /// <param name="radius">Radius of the sphere</param>
        /// <param name="textureCoordinates">The texture coordinates to apply to the sphere.</param>
        /// <param name="angle">The angle of rotation, in degrees.</param>
        /// <param name="ringCount">Number of rings in the sphere.</param>
        /// <param name="segmentCount">Number of segments in the sphere.</param>
        public Sphere(GorgonGraphics graphics, float radius, RectangleF textureCoordinates, Vector3 angle, int ringCount = 8, int segmentCount = 16)
        {
            Quaternion orientation;

            // Calculate number of vertices and indices required for our sphere.
            PrimitiveType = PrimitiveType.TriangleList;
            VertexCount   = (ringCount + 1) * (segmentCount + 1);
            IndexCount    = 6 * ringCount * (segmentCount + 1);
            TriangleCount = IndexCount / 3;

            Quaternion.RotationYawPitchRoll(angle.Y.Radians(), angle.X.Radians(), angle.Z.Radians(), out orientation);
            Matrix.RotationQuaternion(ref orientation, out _orientation);

            unsafe
            {
                using (var vertexData = new GorgonDataStream(VertexCount * Vertex3D.Size))
                    using (var normalData = new GorgonDataStream(VertexCount * 2 * Vector4.SizeInBytes))
                        using (var indexData = new GorgonDataStream(IndexCount * DirectAccess.SizeOf <int>()))
                        {
                            GetVertices((Vertex3D *)vertexData.UnsafePointer, (int *)indexData.UnsafePointer, normalData.UnsafePointer, radius, textureCoordinates, ringCount, segmentCount);

                            VertexBuffer = graphics.Buffers.CreateVertexBuffer("SphereVertexBuffer",
                                                                               new GorgonBufferSettings
                            {
                                Usage       = BufferUsage.Immutable,
                                SizeInBytes = (int)vertexData.Length
                            },
                                                                               vertexData);

                            IndexBuffer = graphics.Buffers.CreateIndexBuffer("SphereIndexBuffer",
                                                                             new GorgonIndexBufferSettings
                            {
                                Usage           = BufferUsage.Immutable,
                                Use32BitIndices = true,
                                SizeInBytes     = (int)indexData.Length
                            },
                                                                             indexData);

                            Normals = graphics.Buffers.CreateVertexBuffer("NormalsBuffer",
                                                                          new GorgonBufferSettings
                            {
                                Usage       = BufferUsage.Immutable,
                                SizeInBytes = (int)normalData.Length
                            },
                                                                          normalData);
                        }
            }
        }
Пример #16
0
        /// <summary>
        /// Function to read file meta data.
        /// </summary>
        /// <param name="stream">Stream used to read the metadata.</param>
        /// <returns>
        /// The image meta data as a <see cref="GorgonLibrary.Graphics.IImageSettings">IImageSettings</see> value.
        /// </returns>
        /// <exception cref="System.IO.IOException">Thrown when the <paramref name="stream"/> is write-only or if the stream cannot perform seek operations.
        /// <para>-or-</para>
        /// <para>Thrown if the file is corrupt or can't be read by the codec.</para>
        /// </exception>
        /// <exception cref="System.IO.EndOfStreamException">Thrown when an attempt to read beyond the end of the stream is made.</exception>
        public override IImageSettings GetMetaData(Stream stream)
        {
            long position   = 0;
            int  headerSize = DirectAccess.SizeOf <TGAHeader>();

            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            if (!stream.CanRead)
            {
                throw new IOException(Resources.GORGFX_STREAM_WRITE_ONLY);
            }

            if (!stream.CanSeek)
            {
                throw new IOException(Resources.GORGFX_STREAM_NO_SEEK);
            }

            if (stream.Length - stream.Position < sizeof(uint) + DirectAccess.SizeOf <TGAHeader>())
            {
                throw new EndOfStreamException(Resources.GORGFX_STREAM_EOF);
            }

            try
            {
                position = stream.Position;

                TGAConversionFlags conversion;
                var gorgonDataStream = stream as GorgonDataStream;
                if (gorgonDataStream != null)
                {
                    return(ReadHeader(gorgonDataStream, out conversion));
                }

                using (var memoryStream = new GorgonDataStream(headerSize))
                {
                    memoryStream.ReadFromStream(stream, headerSize);
                    memoryStream.Position = 0;
                    return(ReadHeader(memoryStream, out conversion));
                }
            }
            finally
            {
                stream.Position = position;
            }
        }
Пример #17
0
        /// <summary>
        /// Function to update the buffer.
        /// </summary>
        /// <param name="stream">Stream containing the data used to update the buffer.</param>
        /// <param name="deferred">[Optional] A deferred context to use when updating the buffer.</param>
        /// <remarks>This method can only be used with buffers that have Default usage.  Other buffer usages will thrown an exception.
        /// <para>This method will respect the <see cref="GorgonLibrary.IO.GorgonDataStream.Position">Position</see> property of the data stream.
        /// This means that it will start reading from the stream at the current position.  To read from the beginning of the stream, set the position
        /// to 0.</para>
        /// <para>
        /// If the <paramref name="deferred"/> parameter is NULL (Nothing in VB.Net), the immediate context will be used to update the buffer.  If it is non-NULL, then it
        /// will use the specified deferred context to clear the render target.
        /// <para>If you are using a deferred context, it is necessary to use that context to update the buffer because 2 threads may not access the same resource at the same time.
        /// Passing a separate deferred context will alleviate that.</para>
        /// </para>
        /// </remarks>
        /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="stream"/> parameter is NULL (Nothing in VB.Net).</exception>
        /// <exception cref="GorgonLibrary.GorgonException">Thrown when the buffer usage is not set to default.</exception>
        public void Update(GorgonDataStream stream, GorgonGraphics deferred = null)
        {
            GorgonDebug.AssertNull(stream, "stream");

#if DEBUG
            if (Settings.Usage != BufferUsage.Default)
            {
                throw new GorgonException(GorgonResult.AccessDenied, Resources.GORGFX_NOT_DEFAULT_USAGE);
            }
#endif
            if (deferred == null)
            {
                deferred = Graphics;
            }

            OnUpdate(stream, 0, (int)(stream.Length - stream.Position), deferred);
        }
Пример #18
0
        /// <summary>
        /// Function to create a generic buffer.
        /// </summary>
        /// <param name="name">Name of the buffer.</param>
        /// <param name="settings">The settings for the buffer.</param>
        /// <param name="stream">[Optional] Stream used to initialize the buffer.</param>
        /// <returns>A new generic buffer object.</returns>
        /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="name"/> parameter is NULL (Nothing in VB.Net).
        /// <para>-or-</para>
        /// <para>Thrown when the <paramref name="settings"/> parameter is NULL.</para>
        /// </exception>
        /// <exception cref="System.ArgumentException">Thrown when the <paramref name="name"/> parameter is empty.</exception>
        /// <exception cref="GorgonLibrary.GorgonException">Thrown when the <see cref="GorgonLibrary.Graphics.GorgonBufferSettings.IsOutput">IsOutput</see> property is TRUE and has a usage that is not Default.
        /// <para>-or-</para>
        /// <para>Thrown when the <see cref="GorgonLibrary.Graphics.GorgonBufferSettings.SizeInBytes">SizeInBytes</see> property of the <paramref name="settings"/> parameter is less than 1.</para>
        /// <para>-or-</para>
        /// <para>Thrown when the usage is set to immutable and the <paramref name="stream"/> parameter is NULL (Nothing in VB.Net) or has no data.</para>
        /// </exception>
        /// <remarks>The generic buffer is intended to be used with the [RW]Buffer&lt;&gt; HLSL type.
        /// <para>Generic buffers are only available on video devices that are capable of SM4 or better.</para>
        /// <para>This method should only be called from an immediate graphics context, if it is called from a deferred context an exception will be thrown.</para>
        /// </remarks>
        public GorgonBuffer CreateBuffer(string name, GorgonBufferSettings settings, GorgonDataStream stream = null)
        {
            if (_graphics.IsDeferred)
            {
                throw new GorgonException(GorgonResult.CannotCreate, Resources.GORGFX_CANNOT_USE_DEFERRED_CONTEXT);
            }

            if (name == null)
            {
                throw new ArgumentNullException("name");
            }

            if (settings == null)
            {
                throw new ArgumentNullException("settings");
            }

            if (name.Length == 0)
            {
                throw new ArgumentException(Resources.GORGFX_PARAMETER_MUST_NOT_BE_EMPTY, "name");
            }

            if ((settings.Usage == BufferUsage.Immutable) && ((stream == null) || (stream.Length == 0)))
            {
                throw new GorgonException(GorgonResult.CannotCreate, Resources.GORGFX_BUFFER_IMMUTABLE_REQUIRES_DATA);
            }

            if ((settings.Usage == BufferUsage.Dynamic) && (!settings.AllowShaderViews))
            {
                throw new GorgonException(GorgonResult.CannotCreate, Resources.GORGFX_BUFFER_DYNAMIC_NEEDS_SHADER_VIEW);
            }

            // Validate our buffer settings.
            ValidateGenericBufferSettings(settings);

            var buffer = new GorgonBuffer(_graphics, name, settings);

            buffer.Initialize(stream);

            _graphics.AddTrackedObject(buffer);
            return(buffer);
        }
Пример #19
0
        /// <summary>
        /// Function to retrieve the ranges available to a specific font.
        /// </summary>
        /// <param name="font">Font to look up.</param>
        /// <param name="hDc">Device context.</param>
        /// <returns>A list of ranges.</returns>
        public static IDictionary <string, GorgonRange> GetUnicodeRanges(Font font, IntPtr hDc)
        {
            Dictionary <string, GorgonRange> result;

            if (_ranges == null)
            {
                BuildUnicodeRangeList();
            }

            uint size = GetFontUnicodeRanges(hDc, IntPtr.Zero);

            using (var stream = new GorgonDataStream((int)size))
            {
                GetFontUnicodeRanges(hDc, stream.BasePointer);

                // Skip the first 12 bytes.
                stream.Read <Int64>();
                stream.Read <Int32>();

                var itemCount = stream.Read <int>();
                result = new Dictionary <string, GorgonRange>(itemCount);

                for (int i = 0; i < itemCount; i++)
                {
                    var min   = stream.Read <ushort>();
                    var value = new GorgonRange(min, stream.Read <ushort>() + min - 1);

                    var rangeName = (from unicodeRange in _ranges
                                     where unicodeRange.Value.Contains(value.Minimum) && unicodeRange.Value.Contains(value.Maximum)
                                     select unicodeRange).SingleOrDefault();

                    if ((!string.IsNullOrEmpty(rangeName.Key)) && (!result.ContainsKey(rangeName.Key)))
                    {
                        result.Add(rangeName.Key, rangeName.Value);
                    }
                }
            }

            return(result);
        }
Пример #20
0
        /// <summary>
        /// Function to load an image from a stream.
        /// </summary>
        /// <param name="stream">Stream containing the data to load.</param>
        /// <param name="size">Size of the data to read, in bytes.</param>
        /// <returns>
        /// The image data that was in the stream.
        /// </returns>
        protected internal override GorgonImageData LoadFromStream(GorgonDataStream stream, int size)
        {
            GorgonImageData    imageData = null;
            TGAConversionFlags flags;

            if (DirectAccess.SizeOf <TGAHeader>() > size)
            {
                throw new EndOfStreamException(Resources.GORGFX_STREAM_EOF);
            }

            // Read the header information.
            IImageSettings settings = ReadHeader(stream, out flags);

            if (ArrayCount > 1)
            {
                settings.ArrayCount = ArrayCount;
            }

            try
            {
                // Create our image data structure.
                imageData = new GorgonImageData(settings);

                // Copy the data from the stream to the buffer.
                CopyImageData(stream, imageData, flags);
            }
            catch
            {
                // Clean up any memory allocated if we can't copy the image.
                if (imageData != null)
                {
                    imageData.Dispose();
                }

                throw;
            }

            return(imageData);
        }
Пример #21
0
        public void BindStructBuffer()
        {
            _framework.CreateTestScene(_sbShaders, _sbShaders, false);

            using (var buffer = _framework.Graphics.Buffers.CreateStructuredBuffer("SB", new GorgonStructuredBufferSettings
            {
                SizeInBytes = 48,
                StructureSize = 12
            }))
            {
                _bufferStream = new GorgonDataStream(48);

                _framework.Graphics.Shaders.VertexShader.Resources[0] = buffer;

                _framework.MaxTimeout = 10000;

                _framework.IdleFunc = () =>
                {
                    for (int i = 0; i < 4; i++)
                    {
                        var rnd = new Vector3(GorgonRandom.RandomSingle() * GorgonTiming.Delta,
                                              GorgonRandom.RandomSingle() * GorgonTiming.Delta,
                                              GorgonRandom.RandomSingle() * GorgonTiming.Delta);

                        _bufferStream.Write(rnd);
                    }

                    _bufferStream.Position = 0;
                    // ReSharper disable AccessToDisposedClosure
                    buffer.Update(_bufferStream);
                    // ReSharper restore AccessToDisposedClosure

                    return(false);
                };

                _framework.Run();
            }
        }
Пример #22
0
        /// <summary>
        /// Function to create a structured buffer and initialize it with data.
        /// </summary>
        /// <param name="name">The name of the structured buffer.</param>
        /// <param name="values">Values to write to the buffer.</param>
        /// <param name="usage">Usage for the buffer.</param>
        /// <returns>A new structured buffer.</returns>
        /// <typeparam name="T">Type of data to write.  Must be a value type.</typeparam>
        /// <exception cref="System.ArgumentNullException">Thrown when the <paramref name="name"/> parameter is NULL (Nothing in VB.Net).
        /// <para>-or-</para>
        /// <para>Thrown when the <paramref name="values"/> parameter is NULL (Nothing in VB.Net).</para>
        /// </exception>
        /// <exception cref="System.ArgumentException">Thrown when the <paramref name="name"/> parameter is empty.</exception>
        /// <exception cref="GorgonLibrary.GorgonException">Thrown when the buffer could not be created.</exception>
        /// <remarks>This method should only be called from an immediate graphics context, if it is called from a deferred context an exception will be thrown.</remarks>
        public GorgonStructuredBuffer CreateStructuredBuffer <T>(string name, T[] values, BufferUsage usage)
            where T : struct
        {
            if (values == null)
            {
                throw new ArgumentNullException("values");
            }

            if (values.Length == 0)
            {
                throw new ArgumentException(Resources.GORGFX_PARAMETER_MUST_NOT_BE_EMPTY, "values");
            }

            using (var stream = new GorgonDataStream(values))
            {
                return(CreateStructuredBuffer(name, new GorgonStructuredBufferSettings
                {
                    Usage = usage,
                    SizeInBytes = DirectAccess.SizeOf <T>() * values.Length,
                    StructureSize = DirectAccess.SizeOf <T>()
                }, stream));
            }
        }
Пример #23
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Plane"/> class.
        /// </summary>
        /// <param name="graphics">The graphics interface to use.</param>
        /// <param name="size">The width and height of the plane.</param>
        /// <param name="textureCoordinates">The texture coordinates to apply to the plane.</param>
        /// <param name="angle">The initial orientation, in degrees.</param>
        /// <param name="columns">The number of columns to subdivide by.</param>
        /// <param name="rows">The number of rows to subdivide by.</param>
        public Plane(GorgonGraphics graphics, Vector2 size, RectangleF textureCoordinates, Vector3 angle, int columns = 1, int rows = 1)
        {
            Quaternion orientation;

            PrimitiveType = PrimitiveType.TriangleStrip;
            VertexCount   = (columns + 1) * (rows + 1);
            IndexCount    = ((columns * rows) * 6) + (rows - 1);
            TriangleCount = (IndexCount - (rows - 1)) / 3;

            Quaternion.RotationYawPitchRoll(angle.Y.Radians(), angle.X.Radians(), angle.Z.Radians(), out orientation);
            Matrix.RotationQuaternion(ref orientation, out _orientation);

            unsafe
            {
                using (var vertexData = new GorgonDataStream(VertexCount * Vertex3D.Size))
                    using (var indexData = new GorgonDataStream(IndexCount * sizeof(int)))
                    {
                        GetVertices((Vertex3D *)vertexData.UnsafePointer, size, textureCoordinates, columns, rows);
                        GetIndices((int *)indexData.UnsafePointer, columns, rows);

                        CalculateTangents((Vertex3D *)vertexData.UnsafePointer, (int *)indexData.UnsafePointer);

                        VertexBuffer = graphics.Buffers.CreateVertexBuffer("PlaneVB", new GorgonBufferSettings
                        {
                            Usage       = BufferUsage.Immutable,
                            SizeInBytes = (int)vertexData.Length
                        }, vertexData);

                        IndexBuffer = graphics.Buffers.CreateIndexBuffer("PlaneIB", new GorgonIndexBufferSettings
                        {
                            Usage           = BufferUsage.Immutable,
                            Use32BitIndices = true,
                            SizeInBytes     = (int)indexData.Length
                        }, indexData);
                    }
            }
        }
Пример #24
0
        public void BindRawBuffer()
        {
            _framework.CreateTestScene(_rbShaders, _rbShaders, false);

            var   values = new byte[256 * 256 * 4];
            float angle  = 0.0f;

            using (var buffer = _framework.Graphics.Buffers.CreateBuffer("RB", new GorgonBufferSettings
            {
                AllowRawViews = true,
                AllowShaderViews = true,
                DefaultShaderViewFormat = BufferFormat.R32_UInt,
                SizeInBytes = values.Length
            }))
            {
                _framework.Graphics.Shaders.PixelShader.Resources[0] = buffer;

                _framework.IdleFunc = () =>
                {
                    using (var stream = new GorgonDataStream(values))
                    {
                        float rads = (angle * GorgonRandom.RandomSingle(8.0f, 32.0f) + 16.0f).Radians();
                        float x    = 128 + GorgonRandom.RandomInt32(0, 5) + (rads * rads.Cos());
                        float y    = 128 + GorgonRandom.RandomInt32(0, 5) + (rads * rads.Sin());

                        if (x > 255)
                        {
                            x = 255;
                        }

                        if (y > 255)
                        {
                            y = 255;
                        }

                        if (x < 0)
                        {
                            x = 0;
                        }

                        if (y < 0)
                        {
                            y = 0;
                        }

                        int pos = (((int)y * 1024) + ((int)x * 4));

                        for (int i = 0; i < pos - 50; i++)
                        {
                            values[i] = (byte)(values[i] * 0.95f);
                        }

                        values[pos]     = 255;
                        values[pos + 3] = values[pos + 2] = values[pos + 1] = (byte)GorgonRandom.RandomInt32(64, 128);

                        angle += GorgonRandom.RandomSingle(1, 180) * GorgonTiming.Delta;
                        if (angle > 360.0f)
                        {
                            angle = 0.0f;
                        }

                        buffer.Update(stream);

                        return(false);
                    }
                };
                _framework.MaxTimeout = 15000;
                _framework.Run();
            }
        }
Пример #25
0
        /// <summary>
        /// Function to build the Icosphere.
        /// </summary>
        /// <param name="graphics">Graphics interface to use.</param>
        /// <param name="radius">Radius of the sphere.</param>
        /// <param name="tesselation">Tessellation factor for the sphere.</param>
        /// <param name="textureCoordinates">Texture coordinate offset and scale.</param>
        private void BuildSphere(GorgonGraphics graphics, float radius, int tesselation, RectangleF textureCoordinates)
        {
            GetBaseVertices();
            List <int[]> indices = GetBaseIndices();

            for (int i = 0; i < tesselation; ++i)
            {
                var subIndices = new List <int[]>();

                foreach (int[] index in indices)
                {
                    int index0 = GetMiddlePoint(index[0], index[1]);
                    int index1 = GetMiddlePoint(index[1], index[2]);
                    int index2 = GetMiddlePoint(index[2], index[0]);

                    subIndices.Add(new []
                    {
                        index[0],
                        index0,
                        index2
                    });

                    subIndices.Add(new[]
                    {
                        index[1],
                        index1,
                        index0
                    });


                    subIndices.Add(new[]
                    {
                        index[2],
                        index2,
                        index1
                    });

                    subIndices.Add(new[]
                    {
                        index0,
                        index1,
                        index2
                    });
                }

                indices = subIndices;
                _cachedSplits.Clear();
            }

            // Perform texture coordinate calculations and vertex/normal transformations.
            const float piRecip  = 1.0f / (float)System.Math.PI;
            const float pi2Recip = 1.0f / (2.0f * (float)System.Math.PI);

            // Final list.
            var vertexList = new List <Vertex3D>();
            var indexList  = new List <int>();

            for (int i = 0; i < _vertices.Count; ++i)
            {
                Vector3 position = _vertices[i];
                Vector3 normal   = position;
                Vector2 uv       = Vector2.Zero;

                uv.X = (0.5f - position.X.ATan(position.Z) * pi2Recip) * textureCoordinates.Width + textureCoordinates.X;
                uv.Y = (0.5f - position.Y.ASin() * piRecip) * textureCoordinates.Height + textureCoordinates.Y;

                Vector3.Multiply(ref position, radius, out position);
                Vector3.TransformCoordinate(ref position, ref _orientation, out position);
                Vector3.TransformCoordinate(ref normal, ref _orientation, out normal);
                normal.Normalize();

                vertexList.Add(new Vertex3D
                {
                    Position = new Vector4(position, 1.0f),
                    Normal   = normal,
                    UV       = uv
                });
            }

            foreach (int[] index in indices)
            {
                for (int j = 0; j < 3; ++j)
                {
                    indexList.Add(index[j]);
                }
            }

            FixSeam(vertexList, indexList);

            unsafe
            {
                using (var vertexData = new GorgonDataStream(vertexList.ToArray()))
                    using (var indexData = new GorgonDataStream(indexList.ToArray()))
                    {
                        VertexCount   = vertexList.Count;
                        IndexCount    = indexList.Count;
                        TriangleCount = IndexCount / 3;

                        CalculateTangents((Vertex3D *)vertexData.UnsafePointer, (int *)indexData.UnsafePointer);

                        VertexBuffer = graphics.Buffers.CreateVertexBuffer("IcoSphereVertexBuffer",
                                                                           new GorgonBufferSettings
                        {
                            SizeInBytes = (int)vertexData.Length,
                            Usage       = BufferUsage.Immutable
                        },
                                                                           vertexData);
                        IndexBuffer = graphics.Buffers.CreateIndexBuffer("IcoSphereIndexbuffer",
                                                                         new GorgonIndexBufferSettings
                        {
                            Usage           = BufferUsage.Immutable,
                            Use32BitIndices = true,
                            SizeInBytes     = (int)indexData.Length
                        },
                                                                         indexData);
                    }
            }
        }
Пример #26
0
        /// <summary>
        /// Function to initialize the 2D renderer.
        /// </summary>
        private void Initialize()
        {
            // Add shader includes.
            if (!Graphics.Shaders.IncludeFiles.Contains("Gorgon2DShaders"))
            {
                Graphics.ImmediateContext.Shaders.IncludeFiles.Add("Gorgon2DShaders", Encoding.UTF8.GetString(Resources.BasicSprite));
            }

            // Create shader states.
            PixelShader = new Gorgon2DPixelShaderState(this);

            VertexShader = new Gorgon2DVertexShaderState(this);

            // Create layout information so we can bind our vertices to the shader.
            DefaultLayout = Graphics.ImmediateContext.Input.CreateInputLayout("Gorgon2D Input Layout", typeof(Gorgon2DVertex), VertexShader.DefaultVertexShader);

            // Create pre-defined effects objects.
            Effects = new Gorgon2DEffects(this);

            int spriteVertexBufferSize = Gorgon2DVertex.SizeInBytes * _cache.CacheSize;
            int spriteIndexBufferSize  = sizeof(int) * _cache.CacheSize * 6;

            // Set up our index buffer.
            using (var ibData = new GorgonDataStream(spriteIndexBufferSize))
            {
                unsafe
                {
                    ushort index  = 0;
                    var    buffer = (int *)ibData.UnsafePointer;
                    for (int i = 0; i < _cache.CacheSize; i++)
                    {
                        *(buffer++) = index;
                        *(buffer++) = (index + 1);
                        *(buffer++) = (index + 2);
                        *(buffer++) = (index + 1);
                        *(buffer++) = (index + 3);
                        *(buffer++) = (index + 2);

                        index += 4;
                    }
                }

                DefaultIndexBuffer = Graphics.ImmediateContext.Buffers.CreateIndexBuffer("Gorgon2D Default Index Buffer", new GorgonIndexBufferSettings
                {
                    IsOutput        = false,
                    SizeInBytes     = (int)ibData.Length,
                    Usage           = BufferUsage.Immutable,
                    Use32BitIndices = true
                }, ibData);
            }

            // Create our empty vertex buffer.
            _defaultVertexBuffer =
                new GorgonVertexBufferBinding(
                    Graphics.ImmediateContext.Buffers.CreateVertexBuffer("Gorgon 2D Default Vertex Buffer", new GorgonBufferSettings
            {
                SizeInBytes = spriteVertexBufferSize,
                Usage       = BufferUsage.Dynamic
            }), Gorgon2DVertex.SizeInBytes);

            // Set up the default render states.
            SetDefaultStates();
        }
Пример #27
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Cube"/> class.
        /// </summary>
        /// <param name="graphics">The graphics interface.</param>
        /// <param name="size">The width, height and depth of the cube.</param>
        /// <param name="textureCoordinates">The texture coordinates for the faces of the cube.</param>
        /// <param name="angle">The initial orientation of the cube, in degrees.</param>
        /// <param name="columnsPerFace">The number of columns per face.</param>
        /// <param name="rowsPerFace">The number of rows per face.</param>
        public Cube(GorgonGraphics graphics, Vector3 size, RectangleF textureCoordinates, Vector3 angle, int columnsPerFace = 1, int rowsPerFace = 1)
        {
            PrimitiveType = PrimitiveType.TriangleList;
            Quaternion orientation;
            int        faceVertexCount = (columnsPerFace + 1) * (rowsPerFace + 1);
            int        faceIndexCount  = (columnsPerFace * rowsPerFace) * 6;

            VertexCount   = faceVertexCount * 6;
            IndexCount    = faceIndexCount * 6;
            TriangleCount = IndexCount / 3;

            Quaternion.RotationYawPitchRoll(angle.Y.Radians(), angle.X.Radians(), angle.Z.Radians(), out orientation);
            Matrix.RotationQuaternion(ref orientation, out _orientation);

            unsafe
            {
                using (
                    GorgonDataStream vertexData = new GorgonDataStream(VertexCount * Vertex3D.Size),
                    indexData = new GorgonDataStream(IndexCount * sizeof(int)))
                {
                    var vertices = (Vertex3D *)vertexData.UnsafePointer;
                    // Front.
                    GetVertices(vertices, Vector3.UnitY, -Vector3.UnitZ, size, textureCoordinates, columnsPerFace, rowsPerFace);
                    // Bottom.
                    GetVertices(vertices + faceVertexCount, -Vector3.UnitZ, -Vector3.UnitY, size, textureCoordinates, columnsPerFace, rowsPerFace);
                    // Back.
                    GetVertices(vertices + (faceVertexCount * 2), Vector3.UnitY, Vector3.UnitZ, size, textureCoordinates, columnsPerFace, rowsPerFace);
                    // Top.
                    GetVertices(vertices + (faceVertexCount * 3), Vector3.UnitZ, Vector3.UnitY, size, textureCoordinates, columnsPerFace, rowsPerFace);
                    // Left.
                    GetVertices(vertices + (faceVertexCount * 4), Vector3.UnitY, -Vector3.UnitX, size, textureCoordinates, columnsPerFace, rowsPerFace);
                    // Right
                    GetVertices(vertices + (faceVertexCount * 5), Vector3.UnitY, Vector3.UnitX, size, textureCoordinates, columnsPerFace, rowsPerFace);

                    var indices = (int *)indexData.UnsafePointer;
                    GetIndices(indices, 0, columnsPerFace, rowsPerFace);
                    GetIndices(indices + faceIndexCount, faceVertexCount, columnsPerFace, rowsPerFace);
                    GetIndices(indices + (faceIndexCount * 2), faceVertexCount * 2, columnsPerFace, rowsPerFace);
                    GetIndices(indices + (faceIndexCount * 3), faceVertexCount * 3, columnsPerFace, rowsPerFace);
                    GetIndices(indices + (faceIndexCount * 4), faceVertexCount * 4, columnsPerFace, rowsPerFace);
                    GetIndices(indices + (faceIndexCount * 5), faceVertexCount * 5, columnsPerFace, rowsPerFace);

                    CalculateTangents(vertices, indices);

                    VertexBuffer = graphics.Buffers.CreateVertexBuffer("CubeVB",
                                                                       new GorgonBufferSettings
                    {
                        Usage       = BufferUsage.Immutable,
                        SizeInBytes = (int)vertexData.Length
                    },
                                                                       vertexData);


                    IndexBuffer = graphics.Buffers.CreateIndexBuffer("CubeIB",
                                                                     new GorgonIndexBufferSettings
                    {
                        Usage           = BufferUsage.Immutable,
                        Use32BitIndices = true,
                        SizeInBytes     = (int)indexData.Length
                    },
                                                                     indexData);
                }
            }
        }
Пример #28
0
        /// <summary>
        /// Function to compress the files in a given directory.
        /// </summary>
        /// <param name="output">The output data stream.</param>
        /// <param name="directory">Directory containing the files to compress.</param>
        /// <param name="rootNode">Root node for the file allocation table.</param>
        private void CompressFiles(Stream output, GorgonFileSystemDirectory directory, XElement rootNode)
        {
            // If we have sub directories, then create those entries.
            foreach (var subDir in directory.Directories)
            {
                var dirNode = CreatePathNode(subDir);

                if (_token.IsCancellationRequested)
                {
                    return;
                }

                CompressFiles(output, subDir, dirNode);

                if (_token.IsCancellationRequested)
                {
                    return;
                }

                // Attach to the root.
                rootNode.Add(dirNode);
            }

            // Compress the files.
            foreach (var fileEntry in directory.Files)
            {
                // Load the file into a buffer for compression.
                long fileStart = output.Position;
                long fileSize;
                long compressedSize = 0;


                UpdateStatus(string.Format(Resources.GORPKW_SAVING_MSG, fileEntry.FullPath.Ellipses(45, true)), 0);

                if (_token.IsCancellationRequested)
                {
                    return;
                }

                using (var sourceData = ScratchFileSystem.OpenStream(fileEntry, false))
                {
                    // Load the data into memory.
                    using (var fileData = new GorgonDataStream((int)sourceData.Length))
                    {
                        if (_token.IsCancellationRequested)
                        {
                            return;
                        }

                        sourceData.CopyTo(fileData);

                        if (_token.IsCancellationRequested)
                        {
                            return;
                        }

                        fileSize          = fileData.Length;
                        fileData.Position = 0;

                        using (var compressedData = new MemoryStream())
                        {
                            if (_token.IsCancellationRequested)
                            {
                                return;
                            }

                            CompressData(fileData, compressedData);

                            if (_token.IsCancellationRequested)
                            {
                                return;
                            }

                            compressedData.Position = 0;
                            fileData.Position       = 0;

                            // Write the compressed data out to our blob file.
                            if (compressedData.Length < fileSize)
                            {
                                if (_token.IsCancellationRequested)
                                {
                                    return;
                                }

                                compressedData.CopyTo(output);

                                if (_token.IsCancellationRequested)
                                {
                                    return;
                                }

                                compressedSize = compressedData.Length;
                            }
                            else
                            {
                                if (_token.IsCancellationRequested)
                                {
                                    return;
                                }

                                // We didn't compress anything, so just dump the file.
                                fileData.CopyTo(output);

                                if (_token.IsCancellationRequested)
                                {
                                    return;
                                }
                            }
                        }
                    }
                }

                // Add to our directory.
                rootNode.Add(CreateFileNode(fileEntry, fileStart, fileSize, compressedSize));
            }
        }
Пример #29
0
        /// <summary>
        /// Function to write the file to the specified path.
        /// </summary>
        /// <param name="path">Path to the file.</param>
        /// <param name="token">Token used to cancel the task.</param>
        protected override void WriteFile(string path, CancellationToken token)
        {
            // Don't allow other threads in here.
            lock (_syncLock)
            {
                _token = token;

                _tempPath = ScratchFileSystem.WriteLocation + Path.GetFileName(Path.GetTempFileName());

                // Calculate compression ratio.  9 is the max compression level for bzip 2.
                _compressionRatio = (int)System.Math.Round(Compression * 9.0f, 0, MidpointRounding.AwayFromZero);

                try
                {
                    // Build file system.
                    BuildFileSystem();

                    if (_token.IsCancellationRequested)
                    {
                        return;
                    }

                    // Turn off cancellation at this point.
                    CanCancel(false);

                    if (_token.IsCancellationRequested)
                    {
                        return;
                    }

                    // Write out our file.
                    using (var outputFile = File.Open(path, FileMode.Create, FileAccess.Write, FileShare.Read))
                    {
                        // Combine the file system parts into a single packed file.
                        using (var writer = new GorgonBinaryWriter(outputFile, true))
                        {
                            // Write the file header.
                            writer.Write("GORPACK1.SharpZip.BZ2");

                            // Copy FAT.
                            using (var fatData = new GorgonDataStream(Encoding.UTF8.GetBytes(_fat.ToStringWithDeclaration())))
                            {
                                using (var compressData = new MemoryStream())
                                {
                                    CompressData(fatData, compressData);
                                    compressData.Position = 0;

                                    writer.Write((int)compressData.Length);
                                    compressData.CopyTo(outputFile);
                                }
                            }
                        }

                        // Copy the file data.
                        using (var fileData = File.Open(_tempPath, FileMode.Open, FileAccess.Read, FileShare.Read))
                        {
                            fileData.CopyTo(outputFile);
                        }
                    }
                }
                finally
                {
                    // Destroy the temp data file.
                    File.Delete(_tempPath);
                }
            }
        }
Пример #30
0
        /// <summary>
        /// Function to create the resources for the buffer.
        /// </summary>
        /// <param name="data">The initial data for the buffer.</param>
        private void CreateResources(GorgonDataStream data)
        {
            var desc = new D3D.BufferDescription
            {
                BindFlags           = D3D.BindFlags.None,
                CpuAccessFlags      = D3DCPUAccessFlags,
                OptionFlags         = D3D.ResourceOptionFlags.None,
                SizeInBytes         = Settings.SizeInBytes,
                StructureByteStride = Settings.StructureSize,
                Usage = D3DUsage
            };

            // If this is a render target buffer, then ensure that we have a default resource.
            if ((IsRenderTarget) && (Settings.Usage != BufferUsage.Default))
            {
                throw new GorgonException(GorgonResult.CannotCreate, Resources.GORGFX_RENDERTARGET_NEED_DEFAULT);
            }

            // Set up the buffer.  If we're a staging buffer, then none of this stuff will
            // work because staging buffers can't be bound to the pipeline, so just skip it.
            if (Settings.Usage != BufferUsage.Staging)
            {
                switch (BufferType)
                {
                case BufferType.Constant:
                    desc.BindFlags = D3D.BindFlags.ConstantBuffer;
                    break;

                case BufferType.Index:
                    desc.BindFlags = D3D.BindFlags.IndexBuffer;
                    break;

                case BufferType.Vertex:
                    desc.BindFlags = D3D.BindFlags.VertexBuffer;
                    break;

                case BufferType.Structured:
                    if (!IsRenderTarget)
                    {
                        desc.OptionFlags = D3D.ResourceOptionFlags.BufferStructured;
                    }
                    break;
                }

                // Update binding modifiers.
                if (Settings.AllowShaderViews)
                {
                    desc.BindFlags |= D3D.BindFlags.ShaderResource;
                }

                if (Settings.AllowUnorderedAccessViews)
                {
                    desc.BindFlags |= D3D.BindFlags.UnorderedAccess;
                }

                if (!IsRenderTarget)
                {
                    if (Settings.AllowIndirectArguments)
                    {
                        desc.OptionFlags = D3D.ResourceOptionFlags.DrawIndirectArguments;
                    }
                }
                else
                {
                    desc.BindFlags |= D3D.BindFlags.RenderTarget;
                }

                if (Settings.IsOutput)
                {
                    desc.BindFlags |= D3D.BindFlags.StreamOutput;
                }

                if (Settings.AllowRawViews)
                {
                    desc.OptionFlags = D3D.ResourceOptionFlags.BufferAllowRawViews;
                }
            }

            // Create and initialize the buffer.
            if (data != null)
            {
                long position = data.Position;

                using (var dxStream = new DX.DataStream(data.BasePointer, data.Length - position, true, true))
                {
                    D3DResource = D3DBuffer = new D3D.Buffer(Graphics.D3DDevice, dxStream, desc);
                }
            }
            else
            {
                D3DResource = D3DBuffer = new D3D.Buffer(Graphics.D3DDevice, desc);
            }
        }