/// <summary>
        /// Serializes an array of static <see cref="StreamOutputElement"/>s.
        /// </summary>
        /// <param name="valueArray">An array of <see cref="StreamOutputElement"/>s to serialize</param>
        /// <param name="serializeFlags">Type of serialization, see <see cref="SerializeFlags"/>.</param>
        /// <remarks>
        /// Note that depending on the serialization <see cref="Mode"/>, this method reads or writes the value.
        /// </remarks>
        public void Serialize(ref StreamOutputElement[] valueArray, SerializeFlags serializeFlags = SerializeFlags.Normal)
        {
            int storeObjectRef;
            if (SerializeIsNull(ref valueArray, out storeObjectRef, serializeFlags))
                return;

            if (Mode == SerializerMode.Write)
            {
                // Store ObjectRef
                if (storeObjectRef >= 0) StoreObjectRef(valueArray, storeObjectRef);

                WriteArrayLength(valueArray.Length);
                for (int i = 0; i < valueArray.Length; i++)
                    Serialize(ref valueArray[i], serializeFlags);
            }
            else
            {
                var count = ReadArrayLength();
                valueArray = new StreamOutputElement[count];

                // Store ObjectRef
                if (storeObjectRef >= 0) StoreObjectRef(valueArray, storeObjectRef);

                for (int index = 0; index < count; index++)
                    Serialize(ref valueArray[index], serializeFlags);
            }
        }
        private void CreateShaders()
        {
            foreach (var shaderBytecode in effectBytecode.Stages)
            {
                var bytecodeRaw = shaderBytecode.Data;
                var reflection = effectBytecode.Reflection;

                // TODO CACHE Shaders with a bytecode hash
                switch (shaderBytecode.Stage)
                {
                    case ShaderStage.Vertex:
                        vertexShader = new VertexShader(GraphicsDevice.NativeDevice, bytecodeRaw);
                        // Note: input signature can be reused when reseting device since it only stores non-GPU data,
                        // so just keep it if it has already been created before.
                        if (inputSignature == null)
                            inputSignature = EffectInputSignature.GetOrCreateLayout(new EffectInputSignature(shaderBytecode.Id, bytecodeRaw));
                        break;
                    case ShaderStage.Domain:
                        domainShader = new DomainShader(GraphicsDevice.NativeDevice, bytecodeRaw);
                        break;
                    case ShaderStage.Hull:
                        hullShader = new HullShader(GraphicsDevice.NativeDevice, bytecodeRaw);
                        break;
                    case ShaderStage.Geometry:
                        if (reflection.ShaderStreamOutputDeclarations != null && reflection.ShaderStreamOutputDeclarations.Count > 0)
                        {
                            // Calculate the strides
                            var soStrides = new List<int>();
                            foreach (var streamOutputElement in reflection.ShaderStreamOutputDeclarations)
                            {
                                for (int i = soStrides.Count; i < (streamOutputElement.Stream + 1); i++)
                                {
                                    soStrides.Add(0);
                                }

                                soStrides[streamOutputElement.Stream] += streamOutputElement.ComponentCount * sizeof(float);
                            }
                            var soElements = new StreamOutputElement[0]; // TODO CREATE StreamOutputElement from bytecode.Reflection.ShaderStreamOutputDeclarations
                            geometryShader = new GeometryShader(GraphicsDevice.NativeDevice, bytecodeRaw, soElements, soStrides.ToArray(), reflection.StreamOutputRasterizedStream);
                        }
                        else
                        {
                            geometryShader = new GeometryShader(GraphicsDevice.NativeDevice, bytecodeRaw);
                        }
                        break;
                    case ShaderStage.Pixel:
                        pixelShader = new PixelShader(GraphicsDevice.NativeDevice, bytecodeRaw);
                        break;
                    case ShaderStage.Compute:
                        computeShader = new ComputeShader(GraphicsDevice.NativeDevice, bytecodeRaw);
                        break;
                }
            }
        }
Exemple #3
0
 /// <summary>
 ///   Initializes a new instance of the <see cref = "T:SharpDX.Direct3D11.GeometryShader" /> class.
 /// </summary>
 /// <param name = "device">The device used to create the shader.</param>
 /// <param name = "shaderBytecode">The compiled shader bytecode.</param>
 /// <param name = "elements">An array of <see cref = "T:SharpDX.Direct3D11.StreamOutputElement" /> instances describing the layout of the output buffers.</param>
 /// <param name = "bufferedStrides">An array of buffer strides; each stride is the size of an element for that buffer.</param>
 /// <param name = "rasterizedStream">The index number of the stream to be sent to the rasterizer stage. Set to NoRasterizedStream if no stream is to be rasterized.</param>
 /// <param name = "linkage">A dynamic class linkage interface.</param>
 public GeometryShader(Device device, byte[] shaderBytecode, StreamOutputElement[] elements,
                       int[] bufferedStrides, int rasterizedStream, ClassLinkage linkage = null)
     : base(IntPtr.Zero)
 {
     unsafe
     {
         fixed (void* pBuffer = shaderBytecode)
             device.CreateGeometryShaderWithStreamOutput((IntPtr)pBuffer, shaderBytecode.Length, elements, elements.Length,
                                                         bufferedStrides, bufferedStrides.Length, rasterizedStream,
                                                         linkage, this);
     }
 }
        /// <summary>
        /// Serializes a static <see cref="StreamOutputElement"/>.
        /// </summary>
        /// <param name="value">The <see cref="StreamOutputElement"/> to serialize</param>
        /// <param name="serializeFlags">Type of serialization, see <see cref="SerializeFlags"/>.</param>
        /// <remarks>
        /// Note that depending on the serialization <see cref="Mode"/>, this method reads or writes the value.
        /// </remarks>
        public void Serialize(ref StreamOutputElement value, SerializeFlags serializeFlags = SerializeFlags.Normal)
        {
            int storeObjectRef;
            if (SerializeIsNull(ref value, out storeObjectRef, serializeFlags))
                return;

            if (Mode == SerializerMode.Read)
                value = new StreamOutputElement();

            // Store ObjectRef
            if (storeObjectRef >= 0) StoreObjectRef(value, storeObjectRef);

            Serialize(ref value.Stream);
            Serialize(ref value.SemanticName);
            Serialize(ref value.SemanticIndex);
            Serialize(ref value.StartComponent);
            Serialize(ref value.ComponentCount);
            Serialize(ref value.OutputSlot);
        }
        internal unsafe MyFoliageGeneratingPass()
        {
            var soElements = new StreamOutputElement[2];
            soElements[0].Stream = 0;
            soElements[0].SemanticName = "TEXCOORD";
            soElements[0].SemanticIndex = 0;
            soElements[0].ComponentCount = 3;
            soElements[0].OutputSlot = 0;
            soElements[1].Stream = 0;
            soElements[1].SemanticName = "TEXCOORD";
            soElements[1].SemanticIndex = 1;
            soElements[1].ComponentCount = 1;
            soElements[1].OutputSlot = 0;

            var soStrides = new int[] { sizeof(Vector3) + sizeof(uint) };

            if(m_geometryShader == GeometryShaderId.NULL)
                m_geometryShader = MyShaders.CreateGs("passes/foliage_streaming/geometry_stage.hlsl", null, new MyShaderStreamOutputInfo { Elements = soElements, Strides = soStrides, RasterizerStreams = GeometryShader.StreamOutputNoRasterizedStream });

            SetImmediate(true);
        }
        internal unsafe MyFoliageGeneratingPass()
        {
            var soElements = new StreamOutputElement[2];
            soElements[0].Stream = 0;
            soElements[0].SemanticName = "TEXCOORD";
            soElements[0].SemanticIndex = 0;
            soElements[0].ComponentCount = 3;
            soElements[0].OutputSlot = 0;
            soElements[1].Stream = 0;
            soElements[1].SemanticName = "TEXCOORD";
            soElements[1].SemanticIndex = 1;
            soElements[1].ComponentCount = 1;
            soElements[1].OutputSlot = 0;

            var soStrides = new int[] { sizeof(Vector3) + sizeof(uint) };

            if(m_geometryShader == GeometryShaderId.NULL)
            {
                string stageFile = Path.Combine(MyMaterialShaders.PassesFolder, MyMaterialShaders.FOLIAGE_STREAMING_PASS, "GeometryStage.hlsl");
                m_geometryShader = MyShaders.CreateGs(stageFile, null, new MyShaderStreamOutputInfo { Elements = soElements, Strides = soStrides, RasterizerStreams = GeometryShader.StreamOutputNoRasterizedStream });
            }

            SetImmediate(true);
        }
Exemple #7
0
        internal DeviceChild GetOrCompileShader(EffectShaderType shaderType, int index, int soRasterizedStream, StreamOutputElement[] soElements, out string profileError)
        {
            DeviceChild shader = null;
            profileError = null;
            lock (sync)
            {
                shader = compiledShadersGroup[(int)shaderType][index];
                if (shader == null)
                {
                    if (RegisteredShaders[index].Level > graphicsDevice.Features.Level)
                    {
                        profileError = string.Format("{0}", RegisteredShaders[index].Level);
                        return null;
                    }

                    var bytecodeRaw = RegisteredShaders[index].Bytecode;
                    switch (shaderType)
                    {
                        case EffectShaderType.Vertex:
                            shader = new VertexShader(graphicsDevice, bytecodeRaw);
                            break;
                        case EffectShaderType.Domain:
                            shader = new DomainShader(graphicsDevice, bytecodeRaw);
                            break;
                        case EffectShaderType.Hull:
                            shader = new HullShader(graphicsDevice, bytecodeRaw);
                            break;
                        case EffectShaderType.Geometry:
                            if (soElements != null)
                            {
                                // Calculate the strides
                                var soStrides = new List<int>();
                                foreach (var streamOutputElement in soElements)
                                {
                                    for (int i = soStrides.Count; i < (streamOutputElement.Stream+1); i++)
                                    {
                                        soStrides.Add(0);
                                    }

                                    soStrides[streamOutputElement.Stream] += streamOutputElement.ComponentCount * sizeof(float);
                                }
                                shader = new GeometryShader(graphicsDevice, bytecodeRaw, soElements, soStrides.ToArray(), soRasterizedStream);
                            }
                            else
                            {
                                shader = new GeometryShader(graphicsDevice, bytecodeRaw);
                            }
                            break;
                        case EffectShaderType.Pixel:
                            shader = new PixelShader(graphicsDevice, bytecodeRaw);
                            break;
                        case EffectShaderType.Compute:
                            shader = new ComputeShader(graphicsDevice, bytecodeRaw);
                            break;
                    }
                    compiledShadersGroup[(int)shaderType][index] = ToDispose(shader);
                }
            }
            return shader;
        }
Exemple #8
0
        static void Main()
        {
            if (!SharpDevice.IsDirectX11Supported())
            {
                System.Windows.Forms.MessageBox.Show("DirectX11 Not Supported");
                return;
            }

            //Init textured cube
            int[] indices = new int[]
            {
                0,1,2,0,2,3,
                4,6,5,4,7,6,
                8,9,10,8,10,11,
                12,14,13,12,15,14,
                16,18,17,16,19,18,
                20,21,22,20,22,23
            };

            TexturedVertex[] vertices = new[]
            {
                ////TOP
                new TexturedVertex(new Vector3(-5,5,5),new Vector2(1,1)),
                new TexturedVertex(new Vector3(5,5,5),new Vector2(0,1)),
                new TexturedVertex(new Vector3(5,5,-5),new Vector2(0,0)),
                new TexturedVertex(new Vector3(-5,5,-5),new Vector2(1,0)),
                //BOTTOM
                new TexturedVertex(new Vector3(-5,-5,5),new Vector2(1,1)),
                new TexturedVertex(new Vector3(5,-5,5),new Vector2(0,1)),
                new TexturedVertex(new Vector3(5,-5,-5),new Vector2(0,0)),
                new TexturedVertex(new Vector3(-5,-5,-5),new Vector2(1,0)),
                //LEFT
                new TexturedVertex(new Vector3(-5,-5,5),new Vector2(0,1)),
                new TexturedVertex(new Vector3(-5,5,5),new Vector2(0,0)),
                new TexturedVertex(new Vector3(-5,5,-5),new Vector2(1,0)),
                new TexturedVertex(new Vector3(-5,-5,-5),new Vector2(1,1)),
                //RIGHT
                new TexturedVertex(new Vector3(5,-5,5),new Vector2(1,1)),
                new TexturedVertex(new Vector3(5,5,5),new Vector2(1,0)),
                new TexturedVertex(new Vector3(5,5,-5),new Vector2(0,0)),
                new TexturedVertex(new Vector3(5,-5,-5),new Vector2(0,1)),
                //FRONT
                new TexturedVertex(new Vector3(-5,5,5),new Vector2(1,0)),
                new TexturedVertex(new Vector3(5,5,5),new Vector2(0,0)),
                new TexturedVertex(new Vector3(5,-5,5),new Vector2(0,1)),
                new TexturedVertex(new Vector3(-5,-5,5),new Vector2(1,1)),
                //BACK
                new TexturedVertex(new Vector3(-5,5,-5),new Vector2(0,0)),
                new TexturedVertex(new Vector3(5,5,-5),new Vector2(1,0)),
                new TexturedVertex(new Vector3(5,-5,-5),new Vector2(1,1)),
                new TexturedVertex(new Vector3(-5,-5,-5),new Vector2(0,1))
            };

            //render form
            RenderForm form = new RenderForm();
            form.Text = "Tutorial 14: Output Stream";
            SharpFPS fpsCounter = new SharpFPS();

            using (SharpDevice device = new SharpDevice(form))
            {

                //Init font
                SharpBatch font = new SharpBatch(device, "textfont.dds");

                //Init Mesh
                SharpMesh mesh = SharpMesh.Create<TexturedVertex>(device, vertices, indices);

                //Init shader from file
                SharpShader shader = new SharpShader(device, "../../HLSL.txt",
                    new SharpShaderDescription() { VertexShaderFunction = "VS", PixelShaderFunction = "PS" },
                    new InputElement[] {
                        new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
                        new InputElement("TEXCOORD", 0, Format.R32G32_Float, 12, 0)
                    });

                //output stream element declaration
                StreamOutputElement[] soDeclaration = new StreamOutputElement[]
                {
                    new StreamOutputElement(){SemanticName="POSITION",ComponentCount=3},
                    new StreamOutputElement(){SemanticName="TEXCOORD",ComponentCount=2}
                };
                const int streamOutputVertexSize = 20; //bytes (3 floats for position, 2 floats for texcoord)

                //output shader
                SharpShader shaderOutput = new SharpShader(device, "../../HLSL.txt",
                    new SharpShaderDescription() { VertexShaderFunction = "VS_O", GeometryShaderFunction = "GS_O", GeometrySO = soDeclaration },
                    new InputElement[] {
                        new InputElement("POSITION", 0, Format.R32G32B32_Float, 0, 0),
                        new InputElement("TEXCOORD", 0, Format.R32G32_Float, 12, 0)
                    });

                //declare 2 output buffer to switch between them
                //one will contain the source and the other will be the target of the rendeinrg
                SharpOutputBuffer outputBufferA = new SharpOutputBuffer(device, 100000);
                SharpOutputBuffer outputBufferB = new SharpOutputBuffer(device, 100000);

                //Create constant buffer
                Buffer11 buffer = shader.CreateBuffer<Matrix>();

                //Create texture from file
                ShaderResourceView texture = ShaderResourceView.FromFile(device.Device, "../../texture.bmp");

                fpsCounter.Reset();

                //for updating
                bool update = true;
                Vector3 nextPosition = new Vector3();

                form.KeyUp += (sender, e) =>
                {
                    switch (e.KeyCode)
                    {
                        case Keys.Up:
                            update = true;
                            nextPosition += new Vector3(0, 10, 0);
                            break;
                        case Keys.Down:
                            update = true;
                            nextPosition += new Vector3(0, -10, 0);
                            break;
                        case Keys.A:
                            update = true;
                            nextPosition += new Vector3(-10, 0, 0);
                            break;
                        case Keys.D:
                            update = true;
                            nextPosition += new Vector3(10, 0, 0);
                            break;
                        case Keys.W:
                            update = true;
                            nextPosition += new Vector3(0, 0, 10);
                            break;
                        case Keys.S:
                            update = true;
                            nextPosition += new Vector3(0, 0, -10);
                            break;
                    }
                };

                //main loop
                RenderLoop.Run(form, () =>
                {
                    //Resizing
                    if (device.MustResize)
                    {
                        device.Resize();
                        font.Resize();
                    }

                    //apply states
                    device.UpdateAllStates();

                    //clear color
                    device.Clear(Color.CornflowerBlue);

                    //apply constant buffer to shader
                    device.DeviceContext.VertexShader.SetConstantBuffer(0, buffer);

                    //set texture
                    device.DeviceContext.PixelShader.SetShaderResource(0, texture);

                    //update output buffer only when needed
                    if (update)
                    {
                        //switch buffer
                        var t = outputBufferA;
                        outputBufferA = outputBufferB;
                        outputBufferB = t;

                        //apply shader
                        shaderOutput.Apply();

                        //start drawing on output buffer
                        outputBufferA.Begin();

                        //draw the other output buffer as source
                        device.UpdateData<Matrix>(buffer, Matrix.Identity);
                        outputBufferB.Draw(streamOutputVertexSize);

                        //draw the mesh to add it to buffer
                        device.UpdateData<Matrix>(buffer, Matrix.Translation(nextPosition));
                        //draw mesh
                        mesh.Draw();

                        //end rendering on buffer
                        outputBufferA.End();

                        //stop updating
                        update = false;
                    }

                    //set transformation matrix
                    float ratio = (float)form.ClientRectangle.Width / (float)form.ClientRectangle.Height;
                    Matrix projection = Matrix.PerspectiveFovLH(3.14F / 3.0F, ratio, 1, 1000);
                    Matrix view = Matrix.LookAtLH(new Vector3(0, 50, -100), new Vector3(), Vector3.UnitY);
                    Matrix world = Matrix.Identity;
                    Matrix WVP = world * view * projection;
                    device.UpdateData<Matrix>(buffer, WVP);

                    //stream
                    shader.Apply();

                    //draw all buffer every frame
                    outputBufferA.Draw(streamOutputVertexSize);

                    //begin drawing text
                    font.Begin();

                    //draw string
                    fpsCounter.Update();
                    font.DrawString("FPS: " + fpsCounter.FPS, 0, 0, Color.White);
                    font.DrawString("Press WASD, Up, Down to move cube", 0, 30, Color.White);

                    //flush text to view
                    font.End();
                    //present
                    device.Present();
                });

                //release resource
                font.Dispose();
                mesh.Dispose();
                buffer.Dispose();
                texture.Dispose();
            }
        }
        internal static unsafe void Init()
        {
            var soElements = new StreamOutputElement[2];
            soElements[0].Stream = 0;
            soElements[0].SemanticName = "TEXCOORD";
            soElements[0].SemanticIndex = 0;
            soElements[0].ComponentCount = 3;
            soElements[0].OutputSlot = 0;
            soElements[1].Stream = 0;
            soElements[1].SemanticName = "TEXCOORD";
            soElements[1].SemanticIndex = 1;
            soElements[1].ComponentCount = 1;
            soElements[1].OutputSlot = 0;

            var soStrides = new int[] { sizeof(Vector3) + sizeof(uint) };

            m_gs = MyShaders.CreateGs("passes/foliage_streaming/geometry_stage.hlsl", "gs", "", new MyShaderStreamOutputInfo { Elements = soElements, Strides = soStrides, RasterizerStreams = GeometryShader.StreamOutputNoRasterizedStream });

            m_instance.SetImmediate(true);
        }