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(); }); }
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(); }); }