Exemplo n.º 1
0
        /// <summary>
        /// Function to create a new vertex buffer and fill it with the vertices that represent our triangle.
        /// </summary>
        private static void CreateVertexBuffer()
        {
            // Define the points that make up our triangle.
            // We'll push it back half a unit along the Z-Axis so that we can see it.
            MiniTriVertex[] vertices =
            {
                new MiniTriVertex(new DX.Vector3(0,      0.5f, 1.0f), new GorgonColor(1, 0, 0)),
                new MiniTriVertex(new DX.Vector3(0.5f,  -0.5f, 1.0f), new GorgonColor(0, 1, 0)),
                new MiniTriVertex(new DX.Vector3(-0.5f, -0.5f, 1.0f), new GorgonColor(0, 0, 1))
            };

            // Create the vertex buffer.
            //
            // This will be responsible for sending vertex data to the GPU. The buffer size is specified in bytes, so we need to ensure it has enough room to hold all
            // 3 vertices.
            _vertexBuffer = GorgonVertexBufferBinding.CreateVertexBuffer <MiniTriVertex>(_graphics,
                                                                                         new GorgonVertexBufferInfo("MiniTri Vertex Buffer")
            {
                Usage       = ResourceUsage.Default,
                SizeInBytes = MiniTriVertex.SizeInBytes * vertices.Length
            });

            // Send the vertex data into the buffer.
            _vertexBuffer.VertexBuffer.SetData(vertices);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Function to create a new vertex buffer and fill it with the vertices that represent our triangle.
        /// </summary>
        private static void CreateVertexBuffer()
        {
            // Define the points that make up our triangle.
            // We'll push it back half a unit along the Z-Axis so that we can see it.
            MiniTriVertex[] vertices =
            {
                // Note that we're assigning the texture coordinates in pixel space. The ToTexel function on the texture will convert these into
                // texel space for us.
                new MiniTriVertex(new DX.Vector3(0,      0.5f, 1.0f), _texture.ToTexel(new DX.Point(128,   3))),
                new MiniTriVertex(new DX.Vector3(0.5f,  -0.5f, 1.0f), _texture.ToTexel(new DX.Point(230, 252))),
                new MiniTriVertex(new DX.Vector3(-0.5f, -0.5f, 1.0f), _texture.ToTexel(new DX.Point(23, 252)))
            };

            // Create the vertex buffer.
            //
            // This will be responsible for sending vertex data to the GPU. The buffer size is specified in bytes, so we need to ensure it has enough room to hold all
            // 3 vertices.
            _vertexBuffer = GorgonVertexBufferBinding.CreateVertexBuffer <MiniTriVertex>(_graphics,
                                                                                         new GorgonVertexBufferInfo("MiniTri Vertex Buffer")
            {
                Usage       = ResourceUsage.Default,
                SizeInBytes = MiniTriVertex.SizeInBytes * vertices.Length
            });

            // Send the vertex data into the buffer.
            _vertexBuffer.VertexBuffer.SetData(vertices);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Cube"/> class.
        /// </summary>
        /// <param name="graphics">The graphics object used to create the buffers needed by this object.</param>
        /// <param name="inputLayout">The input layout describing how a vertex is laid out.</param>
        public Cube(GorgonGraphics graphics, GorgonInputLayout inputLayout)
        {
            CubeVertex[] vertices =
            {
                new CubeVertex(new DX.Vector3(-0.5f,  0.5f, -0.5f), new DX.Vector3(0,       0, 0)),
                new CubeVertex(new DX.Vector3(0.5f,   0.5f, -0.5f), new DX.Vector3(1.0f, 1.0f, 0)),
                new CubeVertex(new DX.Vector3(0.5f,  -0.5f, -0.5f), new DX.Vector3(0.0f, 1.0f, 0)),
                new CubeVertex(new DX.Vector3(-0.5f, -0.5f, -0.5f), new DX.Vector3(1.0f, 0.0f, 0)),

                new CubeVertex(new DX.Vector3(-0.5f,  0.5f,  0.5f), new DX.Vector3(0,       0, 0)),
                new CubeVertex(new DX.Vector3(0.5f,   0.5f,  0.5f), new DX.Vector3(1.0f, 1.0f, 0)),
                new CubeVertex(new DX.Vector3(0.5f,  -0.5f,  0.5f), new DX.Vector3(0.0f, 1.0f, 0)),
                new CubeVertex(new DX.Vector3(-0.5f, -0.5f,  0.5f), new DX.Vector3(1.0f, 0.0f, 0)),
            };

            ushort[] indices =
            {
                // Front face.
                0, 1, 2,
                2, 3, 0,
                // Back face.
                5, 4, 6,
                4, 7, 6,
                // Left face.
                4, 0, 3,
                3, 7, 4,
                // Right face.
                1, 5, 6,
                6, 2, 1,
                // Top face
                4, 5, 1,
                1, 0, 4,
                // Bottom face
                2, 6, 7,
                7, 3, 2
            };

            // Create our index buffer and vertex buffer and populate with our cube data.
            using (var indexPtr = GorgonNativeBuffer <ushort> .Pin(indices))
                using (var vertexPtr = GorgonNativeBuffer <CubeVertex> .Pin(vertices))
                {
                    IndexBuffer = new GorgonIndexBuffer(graphics,
                                                        new GorgonIndexBufferInfo("Volume Index Buffer")
                    {
                        Usage           = ResourceUsage.Immutable,
                        IndexCount      = indices.Length,
                        Use16BitIndices = true
                    },
                                                        indexPtr);

                    VertexBuffer = new GorgonVertexBufferBindings(inputLayout)
                    {
                        [0] = GorgonVertexBufferBinding.CreateVertexBuffer(graphics,
                                                                           vertices.Length,
                                                                           ResourceUsage.Immutable,
                                                                           initialData: vertexPtr,
                                                                           bufferName: "Volume Vertex Buffer")
                    };
                }
        }
Exemplo n.º 4
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;
        }
Exemplo n.º 5
0
        /// <summary>
        /// Function to return the object.
        /// </summary>
        /// <returns>The object created or updated by this builder.</returns>
        /// <exception cref="GorgonException">Thrown if the polygonal sprite has less than 3 vertices.</exception>
        /// <remarks>
        /// <para>
        /// This will return a <see cref="GorgonPolySprite"/> for use with the <see cref="Gorgon2D.DrawPolygonSprite"/> method. The object returned implements <see cref="IDisposable"/>, so it is the
        /// responsibility of the user to dispose of the object when they are done with it.
        /// </para>
        /// <para>
        /// <note type="warning">
        /// <para>
        /// A polygon sprite must have a minimum of 3 vertices.  If it does not, then this method will throw an exception.
        /// </para>
        /// </note>
        /// </para>
        /// </remarks>
        /// <seealso cref="GorgonPolySprite"/>
        /// <seealso cref="Gorgon2D"/>
        public GorgonPolySprite Build()
        {
            if (_workingSprite.RwVertices.Count < 3)
            {
                throw new GorgonException(GorgonResult.CannotCreate, Resources.GOR2D_ERR_POLY_SPRITE_NOT_ENOUGH_VERTS);
            }

            var newSprite = new GorgonPolySprite();

            CopySprite(newSprite, _workingSprite);

            newSprite.Renderable.ActualVertexCount = newSprite.RwVertices.Count;
            if ((newSprite.Renderable.Vertices == null) || (newSprite.Renderable.Vertices.Length < newSprite.RwVertices.Count))
            {
                newSprite.Renderable.Vertices = new Gorgon2DVertex[newSprite.RwVertices.Count];
            }

            for (int i = 0; i < newSprite.RwVertices.Count; ++i)
            {
                newSprite.Renderable.Vertices[i] = newSprite.RwVertices[i].Vertex;
            }

            // Enforce clockwise ordering.
            _triangulator.EnsureWindingOrder(newSprite.Renderable.Vertices, WindingOrder.CounterClockwise);

            // Split the polygon hull into triangles.
            (GorgonNativeBuffer <int> indices, DX.RectangleF bounds) = _triangulator.Triangulate(newSprite.Renderable.Vertices, WindingOrder.CounterClockwise);
            GorgonNativeBuffer <Gorgon2DVertex> vertexData = newSprite.Renderable.Vertices.ToNativeBuffer();

            try
            {
                newSprite.Renderable.IndexBuffer = new GorgonIndexBuffer(Graphics, new GorgonIndexBufferInfo
                {
                    Binding         = VertexIndexBufferBinding.None,
                    Use16BitIndices = false,
                    IndexCount      = indices.Length,
                    Usage           = ResourceUsage.Immutable
                }, indices);


                newSprite.Renderable.VertexBuffer = GorgonVertexBufferBinding.CreateVertexBuffer(Graphics, new GorgonVertexBufferInfo
                {
                    Usage       = ResourceUsage.Immutable,
                    Binding     = VertexIndexBufferBinding.None,
                    SizeInBytes = Gorgon2DVertex.SizeInBytes * newSprite.RwVertices.Count
                }, vertexData);
                newSprite.Renderable.ActualVertexCount = newSprite.RwVertices.Count;
                newSprite.Renderable.IndexCount        = indices.Length;
                newSprite.Bounds = new DX.RectangleF(newSprite.Position.X, newSprite.Position.Y, bounds.Width, bounds.Height);
            }
            finally
            {
                vertexData?.Dispose();
                indices?.Dispose();
            }

            return(newSprite);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Function to save the state information to this object.
        /// </summary>
        private void Save()
        {
            _targets               = _graphics.Output.GetRenderTargets();
            _uavs                  = _graphics.Output.GetUnorderedAccessViews();
            _indexBuffer           = _graphics.Input.IndexBuffer;
            _vertexBuffer          = _graphics.Input.VertexBuffers[0];
            _inputLayout           = _graphics.Input.Layout;
            _primitiveType         = _graphics.Input.PrimitiveType;
            _pixelShader           = _graphics.Shaders.PixelShader.Current;
            _vertexShader          = _graphics.Shaders.VertexShader.Current;
            _blendStates           = _graphics.Output.BlendingState.States;
            _blendFactor           = _graphics.Output.BlendingState.BlendFactor;
            _blendSampleMask       = _graphics.Output.BlendingState.BlendSampleMask;
            _rasterStates          = _graphics.Rasterizer.States;
            _samplerState          = _graphics.Shaders.PixelShader.TextureSamplers[0];
            _resource              = _graphics.Shaders.PixelShader.Resources[0];
            _depthStencilState     = _graphics.Output.DepthStencilState.States;
            _depthStencilReference = _graphics.Output.DepthStencilState.StencilReference;
            _rasterStates.IsScissorTestingEnabled = false;
            _depthStencil = _graphics.Output.DepthStencilView;
            _viewports    = _graphics.Rasterizer.GetViewports();
            _scissorTests = _graphics.Rasterizer.GetScissorRectangles();
            _alphaTest    = new Gorgon2DAlphaTest(Gorgon2D.IsAlphaTestEnabled, GorgonRangeF.Empty);

            _vsConstantBuffers = new Dictionary <int, GorgonConstantBuffer>();
            _psConstantBuffers = new Dictionary <int, GorgonConstantBuffer>();

            // Only store the constant buffers that we were using.
            // We need to store all the constant buffers because the effects
            // make use of multiple constant slots.  Unlike the resource views,
            // where we know that we're only using the first item (all bets are
            // off if a user decides to use another resource view slot), there's no
            // guarantee that we'll be only using 1 or 2 constant buffer slots.
            for (int i = 0; i < _graphics.Shaders.VertexShader.ConstantBuffers.Count; i++)
            {
                if (_graphics.Shaders.VertexShader.ConstantBuffers[i] != null)
                {
                    _vsConstantBuffers[i] = _graphics.Shaders.VertexShader.ConstantBuffers[i];
                }
            }

            for (int i = 0; i < _graphics.Shaders.PixelShader.ConstantBuffers.Count; i++)
            {
                if (_graphics.Shaders.PixelShader.ConstantBuffers[i] != null)
                {
                    _psConstantBuffers[i] = _graphics.Shaders.PixelShader.ConstantBuffers[i];
                }
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Plane" /> class.
        /// </summary>
        /// <param name="graphics">The graphics interface used to create the buffers for this object.</param>
        /// <param name="inputLayout">The input layout for the vertices in this mesh.</param>
        /// <param name="size">The width and height of the plane.</param>
        /// <param name="textureCoordinates">Texture coordinates.</param>
        public Plane(GorgonGraphics graphics, GorgonInputLayout inputLayout, DX.Vector2 size, DX.RectangleF textureCoordinates)
            : base(inputLayout)
        {
            Size = size;

            // Create our vertices.
            Vertices = new[]
            {
                new BoingerVertex(new DX.Vector3(-size.X, size.Y, 0.0f), textureCoordinates.Location),
                new BoingerVertex(new DX.Vector3(size.X, size.Y, 0.0f), new DX.Vector2(textureCoordinates.Right, textureCoordinates.Top)),
                new BoingerVertex(new DX.Vector3(-size.X, -size.Y, 0.0f), new DX.Vector2(textureCoordinates.Left, textureCoordinates.Bottom)),
                new BoingerVertex(new DX.Vector3(size.X, -size.Y, 0.0f), new DX.Vector2(textureCoordinates.Right, textureCoordinates.Bottom))
            };

            // Create our indices.
            Indices = new ushort[]
            {
                0,
                1,
                2,
                2,
                1,
                3
            };

            // Copy the above vertex/index data into a vertex and index buffer so we can render our plane.
            using (var vertexPtr = GorgonNativeBuffer <BoingerVertex> .Pin(Vertices))
                using (var indexPtr = GorgonNativeBuffer <ushort> .Pin(Indices))
                {
                    VertexBufferBindings[0] = GorgonVertexBufferBinding.CreateVertexBuffer(graphics,
                                                                                           new GorgonVertexBufferInfo("Plane Vertex Buffer")
                    {
                        SizeInBytes =
                            Vertices.Length * BoingerVertex.Size,
                        Usage = ResourceUsage.Immutable
                    },
                                                                                           vertexPtr);

                    IndexBuffer = new GorgonIndexBuffer(graphics,
                                                        new GorgonIndexBufferInfo("Plane Index Buffer")
                    {
                        Usage           = ResourceUsage.Immutable,
                        IndexCount      = Indices.Length,
                        Use16BitIndices = true
                    },
                                                        indexPtr);
                }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Function to create the vertex/index buffers for the renderer.
        /// </summary>
        private void CreateBuffers()
        {
            // We don't need to update the index buffer ever.  So we can set up the indices right now.
            using (var indices = new GorgonNativeBuffer <ushort>(MaxSpriteCount * 6))
            {
                int    indexOffset = 0;
                ushort index       = 0;
                for (int i = 0; i < MaxSpriteCount; ++i)
                {
                    indices[indexOffset++] = index;
                    indices[indexOffset++] = (ushort)(index + 1);
                    indices[indexOffset++] = (ushort)(index + 2);
                    indices[indexOffset++] = (ushort)(index + 1);
                    indices[indexOffset++] = (ushort)(index + 3);
                    indices[indexOffset++] = (ushort)(index + 2);

                    index += 4;
                }

                VertexBuffer = GorgonVertexBufferBinding.CreateVertexBuffer <Gorgon2DVertex>(Graphics,
                                                                                             new GorgonVertexBufferInfo
                {
                    Usage       = ResourceUsage.Dynamic,
                    Binding     = VertexIndexBufferBinding.None,
                    SizeInBytes = Gorgon2DVertex.SizeInBytes * (MaxSpriteCount * 4)
                });

                IndexBuffer = new GorgonIndexBuffer(Graphics,
                                                    new GorgonIndexBufferInfo
                {
                    Usage      = ResourceUsage.Immutable,
                    Binding    = VertexIndexBufferBinding.None,
                    IndexCount = indices.Length
                },
                                                    indices);
            }
        }
Exemplo n.º 9
0
 /// <summary>
 /// Function to retrieve a draw indexed call from the pool and,  initialize it.
 /// </summary>
 /// <param name="renderable">The renderable to evaluate.</param>
 /// <param name="batchState">The current global state for the batch.</param>
 /// <param name="indexBuffer">The index buffer to use when creating the draw call.</param>
 /// <param name="vertexBuffer">The vertex buffer binding to use when creating the draw call.</param>
 /// <param name="layout">The vertex input layout.</param>
 /// <returns>The draw call.</returns>
 public GorgonDrawIndexCall GetDrawIndexCall(BatchRenderable renderable, Gorgon2DBatchState batchState, GorgonIndexBuffer indexBuffer, GorgonVertexBufferBinding vertexBuffer, GorgonInputLayout layout)
 {
     SetCommonStates(_drawIndexBuilder, renderable, batchState, null);
     return(_drawIndexBuilder.VertexBuffer(layout, vertexBuffer)
            .IndexBuffer(indexBuffer)
            .Build(_drawIndexAllocator));
 }
Exemplo n.º 10
0
        /// <summary>
        /// Function to initialize the blitter.
        /// </summary>
        public void Initialize()
        {
            try
            {
                // We've been initialized, so leave.
                if ((_vertexShader != null) || (Interlocked.Increment(ref _initializedFlag) > 1))
                {
                    // Trap other threads until we're done initializing and then release them.
                    while ((_vertexShader == null) && (_initializedFlag > 0))
                    {
                        var wait = new SpinWait();
                        wait.SpinOnce();
                    }

                    return;
                }


                _vertexShader = GorgonShaderFactory.Compile <GorgonVertexShader>(_graphics,
                                                                                 Resources.GraphicsShaders,
                                                                                 "GorgonBltVertexShader",
                                                                                 GorgonGraphics.IsDebugEnabled);
                _pixelShader = GorgonShaderFactory.Compile <GorgonPixelShader>(_graphics,
                                                                               Resources.GraphicsShaders,
                                                                               "GorgonBltPixelShader",
                                                                               GorgonGraphics.IsDebugEnabled);

                _inputLayout = GorgonInputLayout.CreateUsingType <BltVertex>(_graphics, _vertexShader);

                _vertexBufferBindings = new GorgonVertexBufferBindings(_inputLayout)
                {
                    [0] = GorgonVertexBufferBinding.CreateVertexBuffer <BltVertex>(_graphics,
                                                                                   4,
                                                                                   ResourceUsage.Dynamic,
                                                                                   bufferName: "Gorgon Blitter Vertex Buffer")
                };

                _wvpBuffer = GorgonConstantBufferView.CreateConstantBuffer(_graphics,
                                                                           new GorgonConstantBufferInfo("Gorgon Blitter WVP Buffer")
                {
                    Usage       = ResourceUsage.Dynamic,
                    SizeInBytes = DX.Matrix.SizeInBytes
                });

                // Finish initalizing the draw call.
                _pipelineState = _pipeStateBuilder.VertexShader(_vertexShader)
                                 .BlendState(GorgonBlendState.NoBlending)
                                 .DepthStencilState(GorgonDepthStencilState.Default)
                                 .PrimitiveType(PrimitiveType.TriangleStrip)
                                 .RasterState(GorgonRasterState.Default)
                                 .PixelShader(_pixelShader)
                                 .Build();

                _drawCallBuilder.VertexBuffers(_inputLayout, _vertexBufferBindings)
                .VertexRange(0, 4)
                .SamplerState(ShaderType.Pixel, GorgonSamplerState.Default)
                .PipelineState(_pipelineState)
                .ConstantBuffer(ShaderType.Vertex, _wvpBuffer);


                _defaultTexture = Resources.White_2x2.ToTexture2D(_graphics,
                                                                  new GorgonTexture2DLoadOptions
                {
                    Name    = "Gorgon_Default_White_Texture",
                    Usage   = ResourceUsage.Immutable,
                    Binding = TextureBinding.ShaderResource
                }).GetShaderResourceView();
            }
            finally
            {
                Interlocked.Decrement(ref _initializedFlag);
            }
        }
Exemplo n.º 11
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();
        }
Exemplo n.º 12
0
        /// <summary>
        /// Function to apply any state changes.
        /// </summary>
        /// <param name="renderable">Renderable object to retrieve states from.</param>
        /// <param name="state">States that need updating.</param>
        internal void UpdateState(IRenderable renderable, StateChange state)
        {
            GorgonRenderable.DepthStencilStates  depthStencil = renderable.DepthStencil;
            GorgonRenderable.BlendState          blending     = renderable.Blending;
            GorgonRenderable.TextureSamplerState sampler      = renderable.TextureSampler;

            if ((state & StateChange.Texture) == StateChange.Texture)
            {
                _resource = _graphics.Shaders.PixelShader.Resources[0] = renderable.Texture;

                // If we have a texture change, and we have the default diffuse shader loaded, then switch to the textured shader, otherwise
                // switch to the diffuse shader.
                Gorgon2D.PixelShader.TextureSwitch(renderable.Texture);
            }

            if ((state & StateChange.BlendFactor) == StateChange.BlendFactor)
            {
                _blendFactor = blending.BlendFactor;
                _graphics.Output.BlendingState.BlendFactor = blending.BlendFactor;
            }

            if ((state & StateChange.BlendState) == StateChange.BlendState)
            {
                _blendStates.RenderTarget0.IsBlendingEnabled     = Gorgon2D.IsBlendingEnabled;
                _blendStates.RenderTarget0.AlphaOperation        = blending.AlphaOperation;
                _blendStates.RenderTarget0.BlendingOperation     = blending.BlendOperation;
                _blendStates.RenderTarget0.DestinationAlphaBlend = blending.DestinationAlphaBlend;
                _blendStates.RenderTarget0.DestinationBlend      = blending.DestinationBlend;
                _blendStates.RenderTarget0.SourceAlphaBlend      = blending.SourceAlphaBlend;
                _blendStates.RenderTarget0.SourceBlend           = blending.SourceBlend;
                _blendStates.RenderTarget0.WriteMask             = blending.WriteMask;
                _graphics.Output.BlendingState.States            = _blendStates;
            }

            if ((state & StateChange.Sampler) == StateChange.Sampler)
            {
                _samplerState.HorizontalAddressing = sampler.HorizontalWrapping;
                _samplerState.VerticalAddressing   = sampler.VerticalWrapping;
                _samplerState.BorderColor          = sampler.BorderColor;
                _samplerState.TextureFilter        = sampler.TextureFilter;
                _graphics.Shaders.PixelShader.TextureSamplers[0] = _samplerState;
            }

            if ((state & StateChange.Raster) == StateChange.Raster)
            {
                _rasterStates.IsScissorTestingEnabled = Gorgon2D.ClipRegion != null;
                _rasterStates.CullingMode             = renderable.CullingMode;
                _rasterStates.IsMultisamplingEnabled  = Gorgon2D.IsMultisamplingEnabled;
                _rasterStates.DepthBias     = depthStencil.DepthBias;
                _graphics.Rasterizer.States = _rasterStates;
            }

            if ((state & StateChange.PrimitiveType) == StateChange.PrimitiveType)
            {
                _primitiveType = _graphics.Input.PrimitiveType = renderable.PrimitiveType;
            }

            if ((state & StateChange.IndexBuffer) == StateChange.IndexBuffer)
            {
                _indexBuffer = _graphics.Input.IndexBuffer = renderable.IndexBuffer;
            }

            if ((state & StateChange.VertexBuffer) == StateChange.VertexBuffer)
            {
                _vertexBuffer = _graphics.Input.VertexBuffers[0] = renderable.VertexBufferBinding;
            }

            if ((state & StateChange.AlphaTest) == StateChange.AlphaTest)
            {
                _alphaTest = new Gorgon2DAlphaTest(Gorgon2D.IsAlphaTestEnabled, renderable.AlphaTestValues);
                Gorgon2D.PixelShader.AlphaTestValuesBuffer.Update(ref _alphaTest);
            }

            if ((state & StateChange.DepthStencilReference) == StateChange.DepthStencilReference)
            {
                _depthStencilReference = _graphics.Output.DepthStencilState.StencilReference = depthStencil.StencilReference;
            }

            if ((state & StateChange.DepthStencil) != StateChange.DepthStencil)
            {
                return;
            }

            _depthStencilState.IsDepthEnabled      = Gorgon2D.IsDepthBufferEnabled;
            _depthStencilState.IsDepthWriteEnabled = depthStencil.IsDepthWriteEnabled;
            _depthStencilState.DepthComparison     = depthStencil.DepthComparison;
            _depthStencilState.StencilReadMask     = depthStencil.StencilReadMask;
            _depthStencilState.StencilWriteMask    = depthStencil.StencilWriteMask;
            _depthStencilState.IsStencilEnabled    = Gorgon2D.IsStencilEnabled;
            _depthStencilState.StencilFrontFace.ComparisonOperator = depthStencil.FrontFace.ComparisonOperator;
            _depthStencilState.StencilFrontFace.DepthFailOperation = depthStencil.FrontFace.DepthFailOperation;
            _depthStencilState.StencilFrontFace.FailOperation      = depthStencil.FrontFace.FailOperation;
            _depthStencilState.StencilFrontFace.PassOperation      = depthStencil.FrontFace.PassOperation;
            _depthStencilState.StencilBackFace.ComparisonOperator  = depthStencil.BackFace.ComparisonOperator;
            _depthStencilState.StencilBackFace.DepthFailOperation  = depthStencil.BackFace.DepthFailOperation;
            _depthStencilState.StencilBackFace.FailOperation       = depthStencil.BackFace.FailOperation;
            _depthStencilState.StencilBackFace.PassOperation       = depthStencil.BackFace.PassOperation;
            _graphics.Output.DepthStencilState.States = _depthStencilState;
        }
Exemplo n.º 13
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Sphere" /> class.
        /// </summary>
        /// <param name="graphics">The graphics interface used to create the buffers for this object.</param>
        /// <param name="inputLayout">The input layout for the vertices in this mesh.</param>
        /// <param name="radius">Radius of the sphere</param>
        /// <param name="textureOffset">Offset of the texture.</param>
        /// <param name="textureScale">Scale of the texture.</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,
                      GorgonInputLayout inputLayout,
                      float radius,
                      DX.Vector2 textureOffset,
                      DX.Size2F textureScale,
                      int ringCount    = 8,
                      int segmentCount = 16)
            : base(inputLayout)
        {
            ushort index       = 0; // Current index.
            int    vertexIndex = 0; // Current vertex index.
            int    indexIndex  = 0; // Current index array index.

            float deltaRingAngle = ((float)System.Math.PI) / ringCount;
            float deltaSegAngle  = (((float)System.Math.PI) * 2.0f) / segmentCount;

            // Calculate number of vertices and indices required for our sphere.
            int vertexCount = (ringCount + 1) * (segmentCount + 1);
            int indexCount  = 6 * ringCount * (segmentCount + 1);

            Vertices = new BoingerVertex[vertexCount];
            Indices  = new ushort[indexCount];

            Radius = radius;

            // Build our sphere.
            for (int ring = 0; ring <= ringCount; ring++)
            {
                float angle    = deltaRingAngle * ring;
                float ringSin  = angle.Sin();
                var   position = new DX.Vector3(0, angle.Cos() * radius, 0);

                for (int segment = 0; segment <= segmentCount; segment++)
                {
                    var   textureDelta = new DX.Vector2(1.0f - (segment / (float)segmentCount), 1.0f - (ring / (float)ringCount));
                    float segmentAngle = deltaSegAngle * segment;

                    position.X = ringSin * segmentAngle.Sin() * radius;
                    position.Z = ringSin * segmentAngle.Cos() * radius;

                    // Create the vertex.
                    textureDelta.X *= textureScale.Width;
                    textureDelta.Y *= textureScale.Height;
                    textureDelta.X += textureOffset.X;
                    textureDelta.Y += textureOffset.Y;

                    Vertices[vertexIndex++] = new BoingerVertex(
                        position,
                        textureDelta
                        );

                    // Add the indices and skip the last ring.
                    if (ring == ringCount)
                    {
                        continue;
                    }

                    Indices[indexIndex++] = (ushort)(index + segmentCount + 1);
                    Indices[indexIndex++] = index;
                    Indices[indexIndex++] = (ushort)(index + segmentCount);
                    Indices[indexIndex++] = (ushort)(index + segmentCount + 1);
                    Indices[indexIndex++] = (ushort)(index + 1);
                    Indices[indexIndex++] = index;
                    index++;
                }
            }

            // Copy the above vertex/index data into a vertex and index buffer so we can render our sphere.
            using (var indexPtr = GorgonNativeBuffer <ushort> .Pin(Indices))
                using (var vertexPtr = GorgonNativeBuffer <BoingerVertex> .Pin(Vertices))
                {
                    VertexBufferBindings[0] = GorgonVertexBufferBinding.CreateVertexBuffer(graphics,
                                                                                           new GorgonVertexBufferInfo("Sphere Vertex Buffer")
                    {
                        SizeInBytes = Vertices.Length * BoingerVertex.Size,
                        Usage       = ResourceUsage.Immutable
                    },
                                                                                           vertexPtr);
                    IndexBuffer = new GorgonIndexBuffer(graphics,
                                                        new GorgonIndexBufferInfo("Sphere Index Buffer")
                    {
                        Usage      = ResourceUsage.Immutable,
                        IndexCount = Indices.Length
                    },
                                                        indexPtr);
                }
        }
Exemplo n.º 14
0
        /// <summary>
        /// Initializes a new instance of the <see cref="Cube"/> class.
        /// </summary>
        /// <param name="graphics">The graphics object used to create the buffers needed by this object.</param>
        /// <param name="inputLayout">The input layout describing how a vertex is laid out.</param>
        public Cube(GorgonGraphics graphics, GorgonInputLayout inputLayout)
        {
            GlassCubeVertex[] vertices =
            {
                // Front face.
                new GlassCubeVertex(new DX.Vector3(-0.5f,  0.5f, -0.5f), new DX.Vector2(0,       0)),
                new GlassCubeVertex(new DX.Vector3(0.5f,  -0.5f, -0.5f), new DX.Vector2(1.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(-0.5f, -0.5f, -0.5f), new DX.Vector2(0.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(0.5f,   0.5f, -0.5f), new DX.Vector2(1.0f, 0.0f)),

                // Right face.
                new GlassCubeVertex(new DX.Vector3(0.5f,   0.5f, -0.5f), new DX.Vector2(0,       0)),
                new GlassCubeVertex(new DX.Vector3(0.5f,  -0.5f,  0.5f), new DX.Vector2(1.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(0.5f,  -0.5f, -0.5f), new DX.Vector2(0.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(0.5f,   0.5f,  0.5f), new DX.Vector2(1.0f, 0.0f)),

                // Back face.
                new GlassCubeVertex(new DX.Vector3(0.5f,   0.5f,  0.5f), new DX.Vector2(0,       0)),
                new GlassCubeVertex(new DX.Vector3(-0.5f, -0.5f,  0.5f), new DX.Vector2(1.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(0.5f,  -0.5f,  0.5f), new DX.Vector2(0.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(-0.5f,  0.5f,  0.5f), new DX.Vector2(1.0f, 0.0f)),

                // Left face.
                new GlassCubeVertex(new DX.Vector3(-0.5f,  0.5f,  0.5f), new DX.Vector2(0,       0)),
                new GlassCubeVertex(new DX.Vector3(-0.5f, -0.5f, -0.5f), new DX.Vector2(1.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(-0.5f, -0.5f,  0.5f), new DX.Vector2(0.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(-0.5f,  0.5f, -0.5f), new DX.Vector2(1.0f, 0.0f)),

                // Top face.
                new GlassCubeVertex(new DX.Vector3(-0.5f,  0.5f,  0.5f), new DX.Vector2(0,       0)),
                new GlassCubeVertex(new DX.Vector3(0.5f,   0.5f, -0.5f), new DX.Vector2(1.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(-0.5f,  0.5f, -0.5f), new DX.Vector2(0.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(0.5f,   0.5f,  0.5f), new DX.Vector2(1.0f, 0.0f)),

                // Bottom face.
                new GlassCubeVertex(new DX.Vector3(-0.5f, -0.5f, -0.5f), new DX.Vector2(0,       0)),
                new GlassCubeVertex(new DX.Vector3(0.5f,  -0.5f,  0.5f), new DX.Vector2(1.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(-0.5f, -0.5f,  0.5f), new DX.Vector2(0.0f, 1.0f)),
                new GlassCubeVertex(new DX.Vector3(0.5f,  -0.5f, -0.5f), new DX.Vector2(1.0f, 0.0f))
            };

            ushort[] indices =
            {
                8,   9, 10,  8, 11,  9,
                12, 13, 14, 12, 15, 13,
                4,   5,  6,  4,  7,  5,
                16, 17, 18, 16, 19, 17,
                20, 21, 22, 20, 23, 21,
                0,   1,  2,  0,  3, 1
            };

            // Create our index buffer and vertex buffer and populate with our cube data.
            using (var indexPtr = GorgonNativeBuffer <ushort> .Pin(indices))
                using (var vertexPtr = GorgonNativeBuffer <GlassCubeVertex> .Pin(vertices))
                {
                    IndexBuffer = new GorgonIndexBuffer(graphics,
                                                        new GorgonIndexBufferInfo("GlassCube Index Buffer")
                    {
                        Usage           = ResourceUsage.Immutable,
                        IndexCount      = indices.Length,
                        Use16BitIndices = true
                    },
                                                        indexPtr);

                    VertexBuffer = new GorgonVertexBufferBindings(inputLayout)
                    {
                        [0] = GorgonVertexBufferBinding.CreateVertexBuffer(graphics,
                                                                           vertices.Length,
                                                                           ResourceUsage.Immutable,
                                                                           initialData: vertexPtr,
                                                                           bufferName: "GlassCube Vertex Buffer")
                    };
                }
        }