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