Esempio n. 1
0
        public void Run()
        {
            CreateAndActivateDefaultMaterial();

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

            // 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 buffer = _meshBufferManager.Create("default", mesh);

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

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

            constantBuffer.Activate(0);

            // Create our initial view and projection matrices that will represent the camera
            var view     = Matrix4x4.CreateLookAt(new Vector3(0, 1.25f, 3f), new Vector3(0, 0, 0), Vector3.UnitY);
            var proj     = CreateProjectionMatrix(_renderTarget.Window);
            var viewproj = view * proj;

            // The aspect ratio changes when the window is resized, so we need to reculate the projection matrix, or
            // our cube will look squashed
            _renderTarget.Window.SizeChanged += win => viewproj = view * CreateProjectionMatrix(win);

            // Let's define an arbitrary rotation speed for the cube
            const float rotationsPerSecond = .04f;
            const float twoPI = (float)Math.PI * 2;

            // Let the looping begin!
            _app.Run(_renderTarget, (frame, context) =>
            {
                // Each frame we need to update the cube's rotation, then push the changes to the constant buffer
                var world = Matrix4x4.CreateRotationY(_app.ElapsedSeconds * rotationsPerSecond * twoPI);
                var wvp   = Matrix4x4.Transpose(world * viewproj);
                constantBuffer.Update(wvp);

                context.Clear(Color.CornflowerBlue);
                context.SetDrawType(cubeData.DrawType);
                context.DrawIndexed(cubeData.IndexCount, cubeData.IndexBufferOffset, cubeData.VertexBufferOffset);
                context.Present();
            });
        }
Esempio n. 2
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();
            });
        }