Exemple #1
0
        private int CreateAndActivateInstanceBuffer()
        {
            // We want to draw the same mesh multiple times, with slightly different data for each instance, so
            // we'll define an array of four transformation matrices that will be provide the data for each of
            // four instances we'll draw.
            var scaled = (Matrix4x4.Identity * 0.5f);

            scaled.M44 = 1.0f;
            const float dist      = .4f;
            var         instances = new[]
            {
                scaled *Matrix4x4.CreateTranslation(-dist, dist, 0),
                scaled *Matrix4x4.CreateTranslation(dist, dist, 0),
                scaled *Matrix4x4.CreateTranslation(-dist, -dist, 0),
                scaled *Matrix4x4.CreateTranslation(dist, -dist, 0)
            };

            // We also need a buffer to store the transformation matrices for each quad instance
            var instanceBuffer = _instanceBufferManager.Create("quad");

            // Now we'll write our instance data to the instance buffer that we created earlier
            using (var writer = instanceBuffer.BeginWrite(instances.Length))
                writer.Write(instances);

            // Instance buffers must be activated starting at slot #1
            instanceBuffer.Activate(1);

            return(instances.Length);
        }
Exemple #2
0
        protected override void InitializeInternal()
        {
            _vertexBuffer = _vertexBufferManager.Create(Id);
            _indexBuffer  = _indexBufferManager.Create(Id);

            var vertexCount = Meshes.Select(m => m.Vertices.Length).Sum();
            var indexCount  = Meshes.Select(m => m.Indices.Length).Sum();

            using (var vertexWriter = _vertexBuffer.BeginWrite(vertexCount))
                using (var indexWriter = _indexBuffer.BeginWrite(indexCount))
                {
                    int vbOffset = 0, ibOffset = 0;
                    foreach (var mesh in Meshes)
                    {
                        _locations.Add(mesh.Id, new MeshLocation(mesh.Indices.Length, vbOffset, ibOffset, mesh.DrawType));
                        for (var i = 0; i < mesh.Vertices.Length; i++)
                        {
                            vertexWriter.Write(ref mesh.Vertices[i]);
                        }
                        foreach (var index in mesh.Indices)
                        {
                            indexWriter.Write(index);
                        }
                        vbOffset += mesh.Vertices.Length;
                        ibOffset += mesh.Indices.Length;
                    }
                }
        }
Exemple #3
0
        private void Run()
        {
            // Choose sampler settings that will prevent our texture from blurring when it is scaled up.
            _graphics.TextureSamplerManager
            .Create("crisp", new TextureSamplerSettings(TextureWrapping.Clamp, TextureWrapping.Clamp, TextureWrapping.Clamp, TextureFiltering.MinMagMipPoint))
            .Activate(0);

            // Create a texture that we can write to, making sure the dimensions are a power of 2
            _texture = _graphics.TextureResourceManager.Create2DDynamic("foo", 8, 8, PixelFormat.R32G32B32A32_Float);
            _texture.Activate(0);

            // Prepare our default material with which we will render our dynamic texture. We then set the material
            // active, which sets the active shaders in GPU memory, ready for drawing with.
            var material = _graphics.MaterialManager.Create("simple");

            material.VertexShaderSpec = new VertexShaderSpec(Resources.VertexShader, Vertex.ShaderInputLayout);
            material.PixelShaderSpec  = new PixelShaderSpec(Resources.PixelShader);
            material.Textures.Add("foo");
            material.Activate();

            // We'll use Grasshopper's procedural tools to quickly build a set of vertices for our quad
            var vertices = QuadBuilder.New
                           .XY()
                           .Colors(Color.Red, Color.Green, Color.Blue, Color.Yellow)
                           .Select(v => new Vertex(v.Position, v.Color, v.TextureCoordinate))
                           .ToArray();

            // Create a vertex buffer. We don't need to dispose of it ourselves; it'll automatically get cleaned
            // up when the vertex manager that created it is disposed of.
            var vertexBuffer = _vertexBufferManager.Create("quad");

            // Six vertices will be written here; 3 per triangle
            using (var writer = vertexBuffer.BeginWrite(vertices.Length))
                writer.Write(vertices);

            // Normal vertex buffers should be activated in slot 0; we only use other slots when doing more
            // advanced things with shaders.
            vertexBuffer.Activate(0);

            // Now that our material and vertex buffers are activated and ready to go, let's initiate our main
            // loop and draw our quad!
            _app.Run(_renderTarget, (frame, context) =>
            {
                UpdateTexture(frame);

                context.Clear(Color.CornflowerBlue);
                context.SetDrawType(DrawType.Triangles);
                context.Draw(vertices.Length, 0);
                context.Present();
            });
        }
Exemple #4
0
        private int CreateAndActivateVertexBuffer()
        {
            // We'll use Grasshopper's procedural tools to quickly build a set of vertices for our quad
            var vertices = QuadBuilder.New
                           .XY()
                           .Colors(Color.Red, Color.Green, Color.Blue, Color.Yellow)
                           .Select(v => new Vertex(v.Position, v.Color))
                           .ToArray();

            // Create a vertex buffer. We don't need to dispose of it ourselves; it'll automatically get cleaned
            // up when the vertex manager that created it is disposed of.
            var vertexBuffer = _vertexBufferManager.Create("quad");

            // Six vertices will be written here; 3 per triangle
            using (var writer = vertexBuffer.BeginWrite(vertices.Length))
                writer.Write(vertices);

            // Base vertex buffers must always be activated in slot #0
            vertexBuffer.Activate(0);

            return(vertices.Length);
        }
Exemple #5
0
        private void Run()
        {
            // Prepare our default material which will simply render out using the vertex colour. We then set the
            // material active, which sets the active shaders in GPU memory, ready for drawing with.
            var material = _graphics.MaterialManager.Create("simple");

            material.VertexShaderSpec = new VertexShaderSpec(Resources.VertexShader, Vertex.ShaderInputLayout);
            material.PixelShaderSpec  = new PixelShaderSpec(Resources.PixelShader);
            material.Activate();

            // We'll use Grasshopper's procedural tools to quickly build a set of vertices for our quad
            var vertices = QuadBuilder.New
                           .XY()
                           .Colors(Color.Red, Color.Green, Color.Blue, Color.Yellow)
                           .Select(v => new Vertex(v.Position, v.Color))
                           .ToArray();

            // Create a vertex buffer. We don't need to dispose of it ourselves; it'll automatically get cleaned
            // up when the vertex manager that created it is disposed of.
            var vertexBuffer = _vertexBufferManager.Create("quad");

            // Six vertices will be written here; 3 per triangle
            using (var writer = vertexBuffer.BeginWrite(vertices.Length))
                writer.Write(vertices);

            // Normal vertex buffers should be activated in slot 0; we only use other slots when doing more
            // advanced things with shaders.
            vertexBuffer.Activate(0);

            // Now that our material and vertex buffers are activated and ready to go, let's initiate our main
            // loop and draw our quad!
            _app.Run(_renderTarget, (frame, context) =>
            {
                context.Clear(Color.CornflowerBlue);
                context.SetDrawType(DrawType.Triangles);
                context.Draw(vertices.Length, 0);
                context.Present();
            });
        }
Exemple #6
0
        public void Run()
        {
            ConfigureInput();
            CreateAndActivateDefaultMaterial();

            // Use Grasshopper's procedural tools to create a cube mesh
            var mesh = CubeBuilder.New
                       .Size(0.25f)
                       .ToMesh("cube", v => new Vertex(v.Position, v.Color, v.TextureCoordinate));

            // A mesh buffer manager allows us to pack multiple meshes into a vertex buffer and accompanying index
            // buffer, and keep track of the offset locations of each mesh in each buffer. In our case we're only
            // storing one mesh.
            var meshBuffer = _meshBufferManager.Create("default", mesh);

            meshBuffer.Activate();
            var cubeData = meshBuffer["cube"];

            // Create a set of cube instance data with different sizes and rotation values for each cube instance
            var       rand          = new Random();
            const int instanceCount = 100000;
            var       instances     = Enumerable.Range(0, instanceCount)
                                      .Select(i =>
            {
                // rotation on each axis
                var rotX = rand.Next(200) - 100.0f;
                var rotY = rand.Next(200) - 100.0f;
                var rotZ = rand.Next(200) - 100.0f;
                // rotation speed
                var rotS = (rand.Next(200)) / 5000.0f;
                // cube offset from the origin
                var posX = (rand.Next(20000) - 10000) / 100.0f;
                var posY = (rand.Next(20000) - 10000) / 100.0f;
                var posZ = (rand.Next(20000) - 10000) / 100.0f;
                // cube size variation
                var scale = (rand.Next(8) == 0 ? (rand.Next(1500) + 100.0f) : rand.Next(200) + 50.0f) / 100.0f;

                return(new CubeInstance
                {
                    Position = new Vector4(posX, posY, posZ, 0),
                    Rotation = new Vector4(rotX, rotY, rotZ, rotS),
                    Scale = new Vector4(scale, scale, scale, 1),
                    Texture = rand.Next(5)
                });
            });

            // Create an instance buffer and write the instance data to it, then active the buffer in slot 1, so
            // that its values will be included for each vertex in the vertex shader
            var instanceBuffer = _instanceBufferManager.Create("default");

            using (var writer = instanceBuffer.BeginWrite(instanceCount))
                writer.Write(instances.ToArray());
            instanceBuffer.Activate(1);

            // Create our initial view matrix that will represent the camera
            var view = Matrix4x4.CreateLookAt(new Vector3(0, 1.25f, -75f), new Vector3(0, 0, 0), Vector3.UnitY);

            // Create and activate our constant buffer which will hold the world-view-projection data and time
            // signature for use by the vertex shader
            var constantBuffer = _constantBufferManager.Create("cube");

            constantBuffer.Activate(0);

            // Define the data that will go into the constant buffer
            var sceneData = new SceneData {
                View = Matrix4x4.Transpose(view)
            };

            constantBuffer.Update(ref sceneData);

            // Let the looping begin!
            _app.Run(_renderTarget, (frame, context) =>
            {
                MoveCamera();

                sceneData.Projection     = Matrix4x4.Transpose(_camera.ProjectionMatrix);
                sceneData.View           = Matrix4x4.Transpose(_camera.ViewMatrix);
                sceneData.SecondsElapsed = _app.ElapsedSeconds;
                constantBuffer.Update(ref sceneData);

                context.Clear(Color.CornflowerBlue);
                context.SetDrawType(cubeData.DrawType);
                context.DrawIndexedInstanced(cubeData.IndexCount, instanceCount, cubeData.IndexBufferOffset, cubeData.VertexBufferOffset, 0);
                context.Present();
            });
        }