0 people like it.

Triangle rendering using SlimDX

Minimal code to render some colored triangles.

  1: 
  2: 
  3: 
  4: 
  5: 
  6: 
  7: 
  8: 
  9: 
 10: 
 11: 
 12: 
 13: 
 14: 
 15: 
 16: 
 17: 
 18: 
 19: 
 20: 
 21: 
 22: 
 23: 
 24: 
 25: 
 26: 
 27: 
 28: 
 29: 
 30: 
 31: 
 32: 
 33: 
 34: 
 35: 
 36: 
 37: 
 38: 
 39: 
 40: 
 41: 
 42: 
 43: 
 44: 
 45: 
 46: 
 47: 
 48: 
 49: 
 50: 
 51: 
 52: 
 53: 
 54: 
 55: 
 56: 
 57: 
 58: 
 59: 
 60: 
 61: 
 62: 
 63: 
 64: 
 65: 
 66: 
 67: 
 68: 
 69: 
 70: 
 71: 
 72: 
 73: 
 74: 
 75: 
 76: 
 77: 
 78: 
 79: 
 80: 
 81: 
 82: 
 83: 
 84: 
 85: 
 86: 
 87: 
 88: 
 89: 
 90: 
 91: 
 92: 
 93: 
 94: 
 95: 
 96: 
 97: 
 98: 
 99: 
100: 
101: 
102: 
103: 
104: 
105: 
106: 
107: 
108: 
109: 
110: 
111: 
112: 
113: 
open SlimDX
open SlimDX.D3DCompiler
open SlimDX.Direct3D11
open SlimDX.Windows
open System.Runtime.InteropServices

type TriangleShader(device, elements, size) =
    let vertexShader, inputSignature = 
        let code = @"
            struct VShaderOutput {
	            float4 pos : SV_POSITION;
	            float4 color : COLOR;
            };

            VShaderOutput VShader(float2 pos : POSITION, float4 color : COLOR) {
                VShaderOutput output;
                output.pos = float4(pos, 1, 1);
                output.color = color;
                return output;
            }
        "
        use bytecode = ShaderBytecode.Compile(code, "VShader", "vs_5_0", ShaderFlags.Debug, EffectFlags.None)
        new VertexShader(device, bytecode), ShaderSignature.GetInputSignature(bytecode)

    let pixelShader = 
        let code = @"
            float4 PShader(float4 pos : SV_POSITION, float4 color : COLOR) : SV_Target {
	            return color;
            }
        "
        use bytecode = ShaderBytecode.Compile(code, "PShader", "ps_5_0", ShaderFlags.Debug, EffectFlags.None)
        new PixelShader(device, bytecode)

    let context = device.ImmediateContext

    member this.SetContext(device, vertexBuffer) =
        use layout  = new InputLayout(device, inputSignature, elements)

        context.InputAssembler.InputLayout <- layout
        context.InputAssembler.PrimitiveTopology <- PrimitiveTopology.TriangleList
        context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertexBuffer, size, 0))
        
        context.VertexShader.Set(vertexShader)
        context.PixelShader.Set(pixelShader)

// create random triangle positions and return them in a vertex buffer
let createTriangleVertexBuffer(device, count, size) =
    let bufferSizeInBytes = count * size * 3
    let stream = new DataStream(int64 bufferSizeInBytes, true, true)
    let rnd = System.Random()

    for i in 1 .. size * 3 do
        stream.Write(float32(rnd.NextDouble()) * 2.0f - 1.0f) // x
        stream.Write(float32(rnd.NextDouble()) * 2.0f - 1.0f) // y
        stream.Write(rnd.Next()) // color

    stream.Position <- 0L
    new Buffer(device, stream, bufferSizeInBytes, ResourceUsage.Default, BindFlags.VertexBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0)

open SlimDX.DXGI

[<EntryPoint>]
let main args =
    use form = new RenderForm("Test Window")
    let width, height = 400, 400
    let triangleCount = 20

    do  form.SetBounds(0, 0, width, height)

    let swapChainDescription = 
        SwapChainDescription(
            BufferCount       = 1,
            Usage             = (Usage.RenderTargetOutput),
            OutputHandle      = form.Handle,
            IsWindowed        = true,
            ModeDescription   = ModeDescription(0, 0, Rational(60, 1), Format.R8G8B8A8_UNorm),
            SampleDescription = SampleDescription(1, 0))
    
    let result, device, swapChain = 
        Device.CreateWithSwapChain(DriverType.Hardware, DeviceCreationFlags.Debug, [|FeatureLevel.Level_11_0|], swapChainDescription)

    use renderTarget = 
        use renderResource = Resource.FromSwapChain<Texture2D>(swapChain, 0)
        new RenderTargetView(device, renderResource)
    
    let vertexLayout = [| new InputElement("POSITION", 0, DXGI.Format.R32G32_Float, 0, 0);
                          new InputElement("COLOR", 0, DXGI.Format.R8G8B8A8_UNorm, 8, 0) |]
    let vertexSizeInBytes = 12 
    let shader = new TriangleShader(device, vertexLayout, vertexSizeInBytes)
    let vertexBuffer = createTriangleVertexBuffer(device, triangleCount, vertexSizeInBytes);

    let context = device.ImmediateContext

    // set viewport
    context.Rasterizer.SetViewports(Viewport(0.0f, 0.0f, float32 width, float32 height, 0.0f, 1.0f))
    // disable triangle culling and set fill mode to solid
    context.Rasterizer.State <- RasterizerState.FromDescription(device, RasterizerStateDescription(CullMode = CullMode.None, FillMode = FillMode.Solid))
    // set render target
    context.OutputMerger.SetTargets(renderTarget)

    // runs per frame
    MessagePump.Run(form, MainLoop(fun () ->
        // clear render buffer to black
        context.ClearRenderTargetView(renderTarget, Color4())
        // bind vertex data i.e. where the triangles should be drawn
        shader.SetContext(device, vertexBuffer)
        // draw triangles
        context.Draw(triangleCount, 0)
        // copy output buffer to screen
        swapChain.Present(0, PresentFlags.None) |> ignore
    ))

    0 // return an integer exit code
namespace System
namespace System.Runtime
namespace System.Runtime.InteropServices
Multiple items
type TriangleShader =
  new : device:obj * elements:obj [] * size:int -> TriangleShader
  member SetContext : device:'a * vertexBuffer:'b -> 'c

Full name: Script.TriangleShader

--------------------
new : device:obj * elements:obj [] * size:int -> TriangleShader
val device : obj
val elements : obj []
val size : int
val vertexShader : obj
val inputSignature : obj
val code : string
val bytecode : System.IDisposable
union case Option.None: Option<'T>
val pixelShader : obj
val context : obj
val this : TriangleShader
member TriangleShader.SetContext : device:'a * vertexBuffer:'b -> 'c

Full name: Script.TriangleShader.SetContext
val device : 'a
val vertexBuffer : 'b
val layout : System.IDisposable
Multiple items
module Set

from Microsoft.FSharp.Collections

--------------------
type Set<'T (requires comparison)> =
  interface IComparable
  interface IEnumerable
  interface IEnumerable<'T>
  interface ICollection<'T>
  new : elements:seq<'T> -> Set<'T>
  member Add : value:'T -> Set<'T>
  member Contains : value:'T -> bool
  override Equals : obj -> bool
  member IsProperSubsetOf : otherSet:Set<'T> -> bool
  member IsProperSupersetOf : otherSet:Set<'T> -> bool
  ...

Full name: Microsoft.FSharp.Collections.Set<_>

--------------------
new : elements:seq<'T> -> Set<'T>
val createTriangleVertexBuffer : device:'a * count:int * size:int -> 'b

Full name: Script.createTriangleVertexBuffer
val count : int
val bufferSizeInBytes : int
val stream : obj
Multiple items
val int64 : value:'T -> int64 (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.int64

--------------------
type int64 = System.Int64

Full name: Microsoft.FSharp.Core.int64

--------------------
type int64<'Measure> = int64

Full name: Microsoft.FSharp.Core.int64<_>
val rnd : System.Random
Multiple items
type Random =
  new : unit -> Random + 1 overload
  member Next : unit -> int + 2 overloads
  member NextBytes : buffer:byte[] -> unit
  member NextDouble : unit -> float

Full name: System.Random

--------------------
System.Random() : unit
System.Random(Seed: int) : unit
val i : int32
Multiple items
val float32 : value:'T -> float32 (requires member op_Explicit)

Full name: Microsoft.FSharp.Core.Operators.float32

--------------------
type float32 = System.Single

Full name: Microsoft.FSharp.Core.float32

--------------------
type float32<'Measure> = float32

Full name: Microsoft.FSharp.Core.float32<_>
System.Random.NextDouble() : float
System.Random.Next() : int
System.Random.Next(maxValue: int) : int
System.Random.Next(minValue: int, maxValue: int) : int
Multiple items
type EntryPointAttribute =
  inherit Attribute
  new : unit -> EntryPointAttribute

Full name: Microsoft.FSharp.Core.EntryPointAttribute

--------------------
new : unit -> EntryPointAttribute
val main : args:string [] -> int

Full name: Script.main
val args : string []
val form : System.IDisposable
val width : int
val height : int
val triangleCount : int
val swapChainDescription : obj
Multiple items
type Format<'Printer,'State,'Residue,'Result> = PrintfFormat<'Printer,'State,'Residue,'Result>

Full name: Microsoft.FSharp.Core.Format<_,_,_,_>

--------------------
type Format<'Printer,'State,'Residue,'Result,'Tuple> = PrintfFormat<'Printer,'State,'Residue,'Result,'Tuple>

Full name: Microsoft.FSharp.Core.Format<_,_,_,_,_>
val result : obj
val swapChain : obj
val renderTarget : System.IDisposable
val renderResource : System.IDisposable
val vertexLayout : obj []
val vertexSizeInBytes : int
val shader : TriangleShader
val vertexBuffer : obj
member TriangleShader.SetContext : device:'a * vertexBuffer:'b -> 'c
val ignore : value:'T -> unit

Full name: Microsoft.FSharp.Core.Operators.ignore
Raw view Test code New version

More information

Link:http://fssnip.net/gz
Posted:11 years ago
Author:gradbot
Tags: slimdx , triangle , directx , vertex , pixel , shader