Example #1
0
        public static IndexedMesh createIndexed <TVertex, TIndex>(IRenderDevice device, TVertex[] vertices, TIndex[] indices, string name)
            where TVertex : unmanaged
            where TIndex : unmanaged
        {
            // Find index type
            GpuValueType indexType;

            switch (Type.GetTypeCode(typeof(TIndex)))
            {
            // https://stackoverflow.com/a/4902207/126995
            case TypeCode.Int32:
            case TypeCode.UInt32:
                indexType = GpuValueType.Uint32;
                break;

            case TypeCode.Int16:
            case TypeCode.UInt16:
                indexType = GpuValueType.Uint16;
                break;

            case TypeCode.Byte:
            case TypeCode.SByte:
                indexType = GpuValueType.Uint8;
                break;

            default:
                throw new ArgumentException($"IndexedMesh.create: index type must be an integer, not { typeof( TIndex ).GetType().Name }");
            }

            // Create vertex buffer
            BufferDesc VertBuffDesc = new BufferDesc(false)
            {
                Usage     = Usage.Static,
                BindFlags = BindFlags.VertexBuffer,
            };
            string vbName = nameVb(name);
            var    vb     = device.CreateBuffer(VertBuffDesc, vertices, vbName);

            // Create index buffer
            BufferDesc IndBuffDesc = new BufferDesc(false)
            {
                Usage     = Usage.Static,
                BindFlags = BindFlags.IndexBuffer
            };
            string ibName = nameIb(name);
            var    ib     = device.CreateBuffer(IndBuffDesc, indices, ibName);

            // Wrap both into the object
            return(new IndexedMesh(vb, ib, indices.Length, indexType));
        }
Example #2
0
        /// <summary>Create buffer with initial content from a span</summary>
        public static IBuffer CreateBuffer <T>(this IRenderDevice device, BufferDesc desc, ReadOnlySpan <T> data, string name = null) where T : unmanaged
        {
            if (null == data || data.Length <= 0)
            {
                return(device.CreateBuffer(ref desc, name, IntPtr.Zero, 0));
            }

            unsafe
            {
                int cb = Marshal.SizeOf <T>() * data.Length;

                fixed(T *pointer = data)
                return(device.CreateBuffer(ref desc, name, (IntPtr)pointer, cb));
            }
        }
Example #3
0
        void createVertexBuffer(IRenderDevice device)
        {
            // Cube vertices

            //      (-1,+1,+1)________________(+1,+1,+1)
            //               /|              /|
            //              / |             / |
            //             /  |            /  |
            //            /   |           /   |
            //(-1,-1,+1) /____|__________/(+1,-1,+1)
            //           |    |__________|____|
            //           |   /(-1,+1,-1) |    /(+1,+1,-1)
            //           |  /            |   /
            //           | /             |  /
            //           |/              | /
            //           /_______________|/
            //        (-1,-1,-1)       (+1,-1,-1)
            //

            Vertex[] CubeVerts = new Vertex[]
            {
                vert(float3(-1, -1, -1), float2(0, 1)),
                vert(float3(-1, +1, -1), float2(0, 0)),
                vert(float3(+1, +1, -1), float2(1, 0)),
                vert(float3(+1, -1, -1), float2(1, 1)),

                vert(float3(-1, -1, -1), float2(0, 1)),
                vert(float3(-1, -1, +1), float2(0, 0)),
                vert(float3(+1, -1, +1), float2(1, 0)),
                vert(float3(+1, -1, -1), float2(1, 1)),

                vert(float3(+1, -1, -1), float2(0, 1)),
                vert(float3(+1, -1, +1), float2(1, 1)),
                vert(float3(+1, +1, +1), float2(1, 0)),
                vert(float3(+1, +1, -1), float2(0, 0)),

                vert(float3(+1, +1, -1), float2(0, 1)),
                vert(float3(+1, +1, +1), float2(0, 0)),
                vert(float3(-1, +1, +1), float2(1, 0)),
                vert(float3(-1, +1, -1), float2(1, 1)),

                vert(float3(-1, +1, -1), float2(1, 0)),
                vert(float3(-1, +1, +1), float2(0, 0)),
                vert(float3(-1, -1, +1), float2(0, 1)),
                vert(float3(-1, -1, -1), float2(1, 1)),

                vert(float3(-1, -1, +1), float2(1, 1)),
                vert(float3(+1, -1, +1), float2(0, 1)),
                vert(float3(+1, +1, +1), float2(0, 0)),
                vert(float3(-1, +1, +1), float2(1, 0)),
            };
            BufferDesc VertBuffDesc = new BufferDesc(false)
            {
                Usage     = Usage.Static,
                BindFlags = BindFlags.VertexBuffer,
            };

            cubeVertexBuffer = device.CreateBuffer(VertBuffDesc, CubeVerts, "Cube vertex buffer");
        }
Example #4
0
 /// <summary>Create buffer with initial content from the specified structure</summary>
 public static IBuffer CreateBuffer <T>(this IRenderDevice device, BufferDesc desc, ref T data, string name = null) where T : unmanaged
 {
     unsafe
     {
         fixed(T *pointer = &data)
         return(device.CreateBuffer(ref desc, name, (IntPtr)pointer, Marshal.SizeOf <T>()));
     }
 }
Example #5
0
        /// <summary>Create dynamic buffer for shader constants</summary>
        public static IBuffer CreateDynamicUniformBuffer(this IRenderDevice device, int cb, string name = null)
        {
            BufferDesc CBDesc = new BufferDesc(false);

            CBDesc.uiSizeInBytes  = cb;
            CBDesc.Usage          = Usage.Dynamic;
            CBDesc.BindFlags      = BindFlags.UniformBuffer;
            CBDesc.CPUAccessFlags = CpuAccessFlags.Write;
            return(device.CreateBuffer(CBDesc, name));
        }
Example #6
0
        static IBuffer createVertexBuffer(IRenderDevice device)
        {
            Vector2[] vertices = new Vector2[4]
            {
                new Vector2(1, 0),
                new Vector2(0, 0),
                new Vector2(1, 1),
                new Vector2(0, 1),
            };
            BufferDesc VertBuffDesc = new BufferDesc(false)
            {
                Usage     = Usage.Static,
                BindFlags = BindFlags.VertexBuffer,
            };

            return(device.CreateBuffer(VertBuffDesc, vertices, "Cursor vertex buffer"));
        }
Example #7
0
        /// <summary>Create immutable VB with the full-screen triangle with cropping-included texture coordinates</summary>
        public static IBuffer createVideoVertexBuffer(IRenderDevice device, CSize renderTargetSize, ref sDecodedVideoSize videoSize)
        {
            Span <sVideoVertex> data = stackalloc sVideoVertex[3];

            produceVertices(data, renderTargetSize, ref videoSize);

            BufferDesc desc = new BufferDesc(false)
            {
                uiSizeInBytes = 16 * 3,
                BindFlags     = BindFlags.VertexBuffer,
                Usage         = Usage.Static,
            };

            ReadOnlySpan <sVideoVertex> readOnly = data;

            return(device.CreateBuffer(desc, readOnly, "Video VB"));
        }
Example #8
0
        /// <summary>Create immutable buffer for shader constants.</summary>
        public static IBuffer CreateImmutableUniformBuffer <T>(this IRenderDevice device, ref T data, string name = null) where T : unmanaged
        {
            int cb = Marshal.SizeOf <T>();

            if (0 != cb % 16)
            {
                throw new ArgumentException($"Constant buffer size must be a multiple of 16 bytes, yet sizeof( { typeof( T ).FullName } ) = { cb }");
            }
            BufferDesc desc = new BufferDesc(false)
            {
                uiSizeInBytes = cb,
                BindFlags     = BindFlags.UniformBuffer,
                Usage         = Usage.Static,
            };

            return(device.CreateBuffer(desc, ref data, name));
        }
Example #9
0
        void createIndexBuffer(IRenderDevice device)
        {
            ushort[] Indices = new ushort[]
            {
                2, 0, 1, 2, 3, 0,
                4, 6, 5, 4, 7, 6,
                8, 10, 9, 8, 11, 10,
                12, 14, 13, 12, 15, 14,
                16, 18, 17, 16, 19, 18,
                20, 21, 22, 20, 22, 23
            };

            BufferDesc IndBuffDesc = new BufferDesc(false)
            {
                Usage     = Usage.Static,
                BindFlags = BindFlags.IndexBuffer
            };

            cubeIndexBuffer = device.CreateBuffer(IndBuffDesc, Indices, "Cube index buffer");
        }
Example #10
0
        void createVertexBuffer(IRenderDevice device)
        {
            // Cube vertices

            //      (-1,+1,+1)________________(+1,+1,+1)
            //               /|              /|
            //              / |             / |
            //             /  |            /  |
            //            /   |           /   |
            //(-1,-1,+1) /____|__________/(+1,-1,+1)
            //           |    |__________|____|
            //           |   /(-1,+1,-1) |    /(+1,+1,-1)
            //           |  /            |   /
            //           | /             |  /
            //           |/              | /
            //           /_______________|/
            //        (-1,-1,-1)       (+1,-1,-1)
            //

            // clang-format off
            Vertex[] CubeVerts = new Vertex[8]
            {
                vert(v3(-1, -1, -1), v4(1, 0, 0, 1)),
                vert(v3(-1, +1, -1), v4(0, 1, 0, 1)),
                vert(v3(+1, +1, -1), v4(0, 0, 1, 1)),
                vert(v3(+1, -1, -1), v4(1, 1, 1, 1)),

                vert(v3(-1, -1, +1), v4(1, 1, 0, 1)),
                vert(v3(-1, +1, +1), v4(0, 1, 1, 1)),
                vert(v3(+1, +1, +1), v4(1, 0, 1, 1)),
                vert(v3(+1, -1, +1), v4(0.2f, 0.2f, 0.2f, 1)),
            };
            BufferDesc VertBuffDesc = new BufferDesc(false)
            {
                Usage     = Usage.Static,
                BindFlags = BindFlags.VertexBuffer,
            };

            cubeVertexBuffer = device.CreateBuffer(VertBuffDesc, CubeVerts, "Cube vertex buffer");
        }
Example #11
0
        void createIndexBuffer(IRenderDevice device)
        {
            // clang-format off
            uint[] Indices = new uint[]
            {
                2, 0, 1, 2, 3, 0,
                4, 6, 5, 4, 7, 6,
                0, 7, 4, 0, 3, 7,
                1, 0, 4, 1, 4, 5,
                1, 5, 2, 5, 6, 2,
                3, 6, 7, 3, 2, 6
            };
            // clang-format on

            BufferDesc IndBuffDesc = new BufferDesc(false)
            {
                Usage     = Usage.Static,
                BindFlags = BindFlags.IndexBuffer
            };

            cubeIndexBuffer = device.CreateBuffer(IndBuffDesc, Indices, "Cube index buffer");
        }
Example #12
0
        void createPipelineState(IRenderDevice device, iStorageFolder assets)
        {
            PipelineStateDesc PSODesc = new PipelineStateDesc(false);

            PSODesc.setBufferFormats(context);

            // Primitive topology defines what kind of primitives will be rendered by this pipeline state
            PSODesc.GraphicsPipeline.PrimitiveTopology = PrimitiveTopology.TriangleList;
            // Cull back faces
            PSODesc.GraphicsPipeline.RasterizerDesc.CullMode = CullMode.Back;
            // Enable depth testing
            PSODesc.GraphicsPipeline.DepthStencilDesc.DepthEnable = true;

            iShaderFactory shaderFactory = device.GetShaderFactory();

            // We won't be using the factory object after this, `using` to release the COM interface once finished
            using (iPipelineStateFactory stateFactory = device.CreatePipelineStateFactory())
            {
                stateFactory.setName("Cube PSO");

                // Compile the two shaders
                ShaderSourceInfo sourceInfo = new ShaderSourceInfo(ShaderType.Vertex, ShaderSourceLanguage.Hlsl);
                sourceInfo.combinedTextureSamplers = true;                  // This appears to be the requirement of OpenGL backend.

                // In this tutorial, we will load shaders from resources embedded into this .NET DLL.
                var vs = shaderFactory.compileFromFile(assets, "cube.vsh", sourceInfo, "Cube VS");
                stateFactory.graphicsVertexShader(vs);

                // Create dynamic uniform buffer that will store our transformation matrix. Dynamic buffers can be frequently updated by the CPU.
                BufferDesc CBDesc = new BufferDesc(false);
                CBDesc.uiSizeInBytes  = Marshal.SizeOf <Matrix4x4>();
                CBDesc.Usage          = Usage.Dynamic;
                CBDesc.BindFlags      = BindFlags.UniformBuffer;
                CBDesc.CPUAccessFlags = CpuAccessFlags.Write;
                vsConstants           = device.CreateBuffer(CBDesc, "VS constants CB");

                // Create a pixel shader
                sourceInfo.shaderType = ShaderType.Pixel;

                var ps = shaderFactory.compileFromFile(assets, "cube.psh", sourceInfo, "Cube PS");
                stateFactory.graphicsPixelShader(ps);

                // Define vertex shader input layout

                // Attribute 0 - vertex position
                LayoutElement elt = new LayoutElement(false)
                {
                    InputIndex    = 0,
                    BufferSlot    = 0,
                    NumComponents = 3,
                    ValueType     = GpuValueType.Float32,
                    IsNormalized  = false
                };
                stateFactory.graphicsLayoutElement(elt);
                // Attribute 1 - texture coordinates
                elt.InputIndex    = 1;
                elt.NumComponents = 2;
                stateFactory.graphicsLayoutElement(elt);

                // Define variable type that will be used by default
                PSODesc.ResourceLayout.DefaultVariableType = ShaderResourceVariableType.Static;
                // Shader variables should typically be mutable, which means they are expected to change on a per-instance basis
                stateFactory.layoutVariable(ShaderType.Pixel, ShaderResourceVariableType.Mutable, "g_Texture");

                // Define static sampler for g_Texture. Static samplers should be used whenever possible.
                // The default constructor is good enough, it sets FilterType.Linear and TextureAddressMode.Clamp for all 3 coordinates.
                SamplerDesc samplerDesc = new SamplerDesc(false);
                stateFactory.layoutStaticSampler(ShaderType.Pixel, ref samplerDesc, "g_Texture");

                stateFactory.apply(ref PSODesc);
                pipelineState = device.CreatePipelineState(ref PSODesc);
            }

            // Since we did not explicitly specify the type for 'Constants' variable, default
            // type (SHADER_RESOURCE_VARIABLE_TYPE_STATIC) will be used. Static variables never
            // change and are bound directly through the pipeline state object.
            pipelineState.GetStaticVariableByName(ShaderType.Vertex, "Constants").Set(vsConstants);

            // Since we are using mutable variable, we must create a shader resource binding object
            // http://diligentgraphics.com/2016/03/23/resource-binding-model-in-diligent-engine-2-0/
            resourceBinding = pipelineState.CreateShaderResourceBinding(true);
        }
Example #13
0
 /// <summary>Create a buffer without initial data</summary>
 public static IBuffer CreateBuffer(this IRenderDevice device, BufferDesc desc, string name = null)
 {
     return(device.CreateBuffer(ref desc, name, IntPtr.Zero, 0));
 }
Example #14
0
        void createPipelineState(IRenderDevice device)
        {
            PipelineStateDesc PSODesc = new PipelineStateDesc(false);

            PSODesc.setBufferFormats(context);

            // Primitive topology defines what kind of primitives will be rendered by this pipeline state
            PSODesc.GraphicsPipeline.PrimitiveTopology = PrimitiveTopology.TriangleList;
            // Cull back faces
            PSODesc.GraphicsPipeline.RasterizerDesc.CullMode = CullMode.Back;
            // Enable depth testing
            PSODesc.GraphicsPipeline.DepthStencilDesc.DepthEnable = true;

            iShaderFactory shaderFactory = device.GetShaderFactory();

            // We won't be using the device object after this, `using` is to release the COM interface once finished
            using (iPipelineStateFactory stateFactory = device.CreatePipelineStateFactory())
            {
                stateFactory.setName("Cube PSO");

                // Compile the two shaders
                ShaderSourceInfo sourceInfo = new ShaderSourceInfo(ShaderType.Vertex, ShaderSourceLanguage.Hlsl);
                sourceInfo.combinedTextureSamplers = true;                  // This appears to be the requirement of OpenGL backend.

                // In this tutorial, we will load shaders from resources embedded into this .NET DLL.
                iStorageFolder resources = StorageFolder.embeddedResources(Assembly.GetExecutingAssembly(), "RenderSamples/02-Cube");
                var            vs        = shaderFactory.compileFromFile(resources, "cube.vsh", sourceInfo, "Cube VS");
                stateFactory.graphicsVertexShader(vs);

                // Create dynamic uniform buffer that will store our transformation matrix. Dynamic buffers can be frequently updated by the CPU.
                BufferDesc CBDesc = new BufferDesc(false);
                CBDesc.uiSizeInBytes  = Marshal.SizeOf <Matrix4x4>();
                CBDesc.Usage          = Usage.Dynamic;
                CBDesc.BindFlags      = BindFlags.UniformBuffer;
                CBDesc.CPUAccessFlags = CpuAccessFlags.Write;
                vsConstants           = device.CreateBuffer(CBDesc, "VS constants CB");

                // Create a pixel shader
                sourceInfo.shaderType = ShaderType.Pixel;

                var ps = shaderFactory.compileFromFile(resources, "cube.psh", sourceInfo, "Cube PS");
                stateFactory.graphicsPixelShader(ps);

                // Define vertex shader input layout

                // Attribute 0 - vertex position
                LayoutElement elt = new LayoutElement(false)
                {
                    InputIndex    = 0,
                    BufferSlot    = 0,
                    NumComponents = 3,
                    ValueType     = GpuValueType.Float32,
                    IsNormalized  = false
                };
                stateFactory.graphicsLayoutElement(elt);
                // Attribute 1 - vertex color
                elt.InputIndex    = 1;
                elt.NumComponents = 4;
                stateFactory.graphicsLayoutElement(elt);

                // Define variable type that will be used by default
                PSODesc.ResourceLayout.DefaultVariableType = ShaderResourceVariableType.Static;

                stateFactory.apply(ref PSODesc);
                pipelineState = device.CreatePipelineState(ref PSODesc);
            }

            // Since we did not explicitly specify the type for 'Constants' variable, default
            // type (SHADER_RESOURCE_VARIABLE_TYPE_STATIC) will be used. Static variables never
            // change and are bound directly through the pipeline state object.
            pipelineState.GetStaticVariableByName(ShaderType.Vertex, "Constants").Set(vsConstants);

            // Create a shader resource binding object and bind all static resources in it
            resourceBinding = pipelineState.CreateShaderResourceBinding(true);
        }