コード例 #1
0
 public void SetInstanceDataBuffer(GpuVertexBuffer buffer, int startVertex /*= 0*/, int count /*= -1*/)
 {
     if (buffer.Flags.HasFlag(GpuBufferFlags.Dynamic) || buffer.Flags.HasFlag(GpuBufferFlags.ComputeWrite))
     {
         Bgfx.SetInstanceDataBuffer((DynamicVertexBuffer)buffer.GetNativeObject(), startVertex, count);
     }
     else
     {
         Bgfx.SetInstanceDataBuffer((VertexBuffer)buffer.GetNativeObject(), startVertex, count);
     }
 }
コード例 #2
0
    static unsafe void RunCompute(Sample sample, bool indirectSupported)
    {
        // build vertex layouts
        var quadLayout = new VertexLayout();

        quadLayout.Begin()
        .Add(VertexAttributeUsage.Position, 2, VertexAttributeType.Float)
        .End();

        var computeLayout = new VertexLayout();

        computeLayout.Begin()
        .Add(VertexAttributeUsage.TexCoord0, 4, VertexAttributeType.Float)
        .End();

        // static quad data
        var vb = new VertexBuffer(MemoryBlock.FromArray(QuadVertices), quadLayout);
        var ib = new IndexBuffer(MemoryBlock.FromArray(QuadIndices));

        // create compute buffers
        var currPositionBuffer0 = new DynamicVertexBuffer(1 << 15, computeLayout, BufferFlags.ComputeReadWrite);
        var currPositionBuffer1 = new DynamicVertexBuffer(1 << 15, computeLayout, BufferFlags.ComputeReadWrite);
        var prevPositionBuffer0 = new DynamicVertexBuffer(1 << 15, computeLayout, BufferFlags.ComputeReadWrite);
        var prevPositionBuffer1 = new DynamicVertexBuffer(1 << 15, computeLayout, BufferFlags.ComputeReadWrite);

        // load shaders
        var particleProgram        = ResourceLoader.LoadProgram("vs_particle", "fs_particle");
        var initInstancesProgram   = ResourceLoader.LoadProgram("cs_init_instances");
        var updateInstancesProgram = ResourceLoader.LoadProgram("cs_update_instances");

        // indirect rendering support
        var  indirectProgram = SharpBgfx.Program.Invalid;
        var  indirectBuffer  = IndirectBuffer.Invalid;
        bool useIndirect     = false;

        if (indirectSupported)
        {
            indirectProgram = ResourceLoader.LoadProgram("cs_indirect");
            indirectBuffer  = new IndirectBuffer(2);
            useIndirect     = true;
        }

        // setup params uniforms
        var paramData = new ParamsData {
            TimeStep          = 0.0157f,
            DispatchSize      = 32,
            Gravity           = 0.109f,
            Damping           = 0.25f,
            ParticleIntensity = 0.64f,
            ParticleSize      = 0.279f,
            BaseSeed          = 57,
            ParticlePower     = 3.5f,
            InitialSpeed      = 3.2f,
            InitialShape      = 1,
            MaxAccel          = 100.0f
        };

        // have the compute shader run initialization
        var u_params = new Uniform("u_params", UniformType.Vector4, 3);

        Bgfx.SetUniform(u_params, &paramData, 3);
        Bgfx.SetComputeBuffer(0, prevPositionBuffer0, ComputeBufferAccess.Write);
        Bgfx.SetComputeBuffer(1, currPositionBuffer0, ComputeBufferAccess.Write);
        Bgfx.Dispatch(0, initInstancesProgram, MaxParticleCount / ThreadGroupUpdateSize);

        // start the frame clock
        var clock = new Clock();

        clock.Start();

        // main loop
        while (sample.ProcessEvents(ResetFlags.Vsync))
        {
            // tick the clock
            var elapsed = clock.Frame();
            var time    = clock.TotalTime();

            // write some debug text
            Bgfx.DebugTextClear();
            Bgfx.DebugTextWrite(0, 1, DebugColor.White, DebugColor.Blue, "SharpBgfx/Samples/24-NBody");
            Bgfx.DebugTextWrite(0, 2, DebugColor.White, DebugColor.Cyan, "Description: N-body simulation with compute shaders using buffers.");
            Bgfx.DebugTextWrite(0, 3, DebugColor.White, DebugColor.Cyan, "Frame: {0:F3} ms", elapsed * 1000);

            // fill the indirect buffer if we're using it
            if (useIndirect)
            {
                Bgfx.SetUniform(u_params, &paramData, 3);
                Bgfx.SetComputeBuffer(0, indirectBuffer, ComputeBufferAccess.Write);
                Bgfx.Dispatch(0, indirectProgram);
            }

            // update particle positions
            Bgfx.SetComputeBuffer(0, prevPositionBuffer0, ComputeBufferAccess.Read);
            Bgfx.SetComputeBuffer(1, currPositionBuffer0, ComputeBufferAccess.Read);
            Bgfx.SetComputeBuffer(2, prevPositionBuffer1, ComputeBufferAccess.Write);
            Bgfx.SetComputeBuffer(3, currPositionBuffer1, ComputeBufferAccess.Write);
            Bgfx.SetUniform(u_params, &paramData, 3);
            if (useIndirect)
            {
                Bgfx.Dispatch(0, updateInstancesProgram, indirectBuffer, 1);
            }
            else
            {
                Bgfx.Dispatch(0, updateInstancesProgram, paramData.DispatchSize);
            }

            // ping-pong the buffers for next frame
            Swap(ref currPositionBuffer0, ref currPositionBuffer1);
            Swap(ref prevPositionBuffer0, ref prevPositionBuffer1);

            // view transforms for particle rendering
            var viewMatrix = Matrix4x4.CreateLookAt(new Vector3(0.0f, 0.0f, -45.0f), -Vector3.UnitZ, Vector3.UnitY);
            var projMatrix = Matrix4x4.CreatePerspectiveFieldOfView((float)Math.PI / 4, (float)sample.WindowWidth / sample.WindowHeight, 0.1f, 10000.0f);
            Bgfx.SetViewTransform(0, &viewMatrix.M11, &projMatrix.M11);
            Bgfx.SetViewRect(0, 0, 0, sample.WindowWidth, sample.WindowHeight);

            // draw the particles
            Bgfx.SetVertexBuffer(vb);
            Bgfx.SetIndexBuffer(ib);
            Bgfx.SetInstanceDataBuffer(currPositionBuffer0, 0, paramData.DispatchSize * ThreadGroupUpdateSize);
            Bgfx.SetRenderState(RenderState.ColorWrite | RenderState.BlendAdd | RenderState.DepthTestAlways);
            if (useIndirect)
            {
                Bgfx.Submit(0, particleProgram, indirectBuffer);
            }
            else
            {
                Bgfx.Submit(0, particleProgram);
            }

            // done with frame
            Bgfx.Frame();
        }

        // cleanup
        if (indirectSupported)
        {
            indirectProgram.Dispose();
            indirectBuffer.Dispose();
        }

        u_params.Dispose();
        currPositionBuffer0.Dispose();
        currPositionBuffer1.Dispose();
        prevPositionBuffer0.Dispose();
        prevPositionBuffer1.Dispose();
        updateInstancesProgram.Dispose();
        initInstancesProgram.Dispose();
        particleProgram.Dispose();
        ib.Dispose();
        vb.Dispose();
    }
コード例 #3
0
ファイル: Program.cs プロジェクト: sweep3r/SharpBgfx
    static unsafe void RenderThread(Sample sample)
    {
        // initialize the renderer
        Bgfx.Init();
        Bgfx.Reset(sample.WindowWidth, sample.WindowHeight, ResetFlags.Vsync);

        // enable debug text
        Bgfx.SetDebugFeatures(DebugFeatures.DisplayText);

        // set view 0 clear state
        Bgfx.SetViewClear(0, ClearTargets.Color | ClearTargets.Depth, 0x303030ff);

        // create vertex and index buffers
        var vbh = Cube.CreateVertexBuffer();
        var ibh = Cube.CreateIndexBuffer();

        // load shaders
        var program = ResourceLoader.LoadProgram("vs_instancing", "fs_instancing");

        // start the frame clock
        var clock = new Clock();

        clock.Start();

        // getting caps
        var caps = Bgfx.GetCaps();

        // main loop
        while (sample.ProcessEvents(ResetFlags.Vsync))
        {
            // set view 0 viewport
            Bgfx.SetViewRect(0, 0, 0, sample.WindowWidth, sample.WindowHeight);

            // view transforms
            var viewMatrix = Matrix4x4.CreateLookAt(new Vector3(0.0f, 0.0f, -35.0f), Vector3.Zero, Vector3.UnitY);
            var projMatrix = Matrix4x4.CreatePerspectiveFieldOfView((float)Math.PI / 3, (float)sample.WindowWidth / sample.WindowHeight, 0.1f, 100.0f);
            Bgfx.SetViewTransform(0, &viewMatrix.M11, &projMatrix.M11);

            // make sure view 0 is cleared if no other draw calls are submitted
            Bgfx.Touch(0);

            // tick the clock
            var elapsed = clock.Frame();
            var time    = clock.TotalTime();

            // write some debug text
            Bgfx.DebugTextClear();
            Bgfx.DebugTextWrite(0, 1, DebugColor.White, DebugColor.Blue, "SharpBgfx/Samples/05-Instancing");
            Bgfx.DebugTextWrite(0, 2, DebugColor.White, DebugColor.Cyan, "Description: Geometry instancing.");
            Bgfx.DebugTextWrite(0, 3, DebugColor.White, DebugColor.Cyan, "Frame: {0:F3} ms", elapsed * 1000);

            // check caps
            if ((caps.SupportedFeatures & DeviceFeatures.Instancing) != DeviceFeatures.Instancing)
            {
                // instancing not supported
                Bgfx.DebugTextWrite(0, 3, DebugColor.White, DebugColor.Red, "Instancing not supported!");
            }
            else
            {
                const int instanceStride = 80;
                const int instanceCount  = 121;

                var idb = new InstanceDataBuffer(instanceCount, instanceStride);

                // fill in InstanceDataBuffer
                byte *dataPtr = (byte *)idb.Data.ToPointer();
                // TODO: extract idb->data->num
                for (int y = 0; y < 11; y++)
                {
                    for (int x = 0; x < 11; x++)
                    {
                        float *matrix     = (float *)dataPtr;
                        var    realMatrix = Matrix4x4.CreateFromYawPitchRoll(time + x * 0.21f, time + y * 0.37f, 0f);
                        realMatrix.M41 = -15.0f + x * 3.0f;
                        realMatrix.M42 = -15.0f + y * 3.0f;
                        realMatrix.M43 = 0.0f;
                        // TODO: use proper copy function, not a bycicle
                        float *realMatrixPtr = &realMatrix.M11;
                        for (int i = 0; i < 16; i++)
                        {
                            matrix[i] = realMatrixPtr[i];
                        }

                        float *color = (float *)(dataPtr + 64);
                        color[0] = (float)Math.Sin(time + x / 11.0f) * 0.5f + 0.5f;
                        color[1] = (float)Math.Cos(time + y / 11.0f) * 0.5f + 0.5f;
                        color[2] = (float)Math.Sin(time * 3.0f) * 0.5f + 0.5f;
                        color[3] = 1.0f;

                        dataPtr += instanceStride;
                    }
                }

                // set pipeline states
                Bgfx.SetVertexBuffer(0, vbh);
                Bgfx.SetIndexBuffer(ibh);
                Bgfx.SetInstanceDataBuffer(ref idb);
                Bgfx.SetRenderState(RenderState.Default);

                // submit primitives
                Bgfx.Submit(0, program);
            }

            // advance to the next frame. Rendering thread will be kicked to
            // process submitted rendering primitives.
            Bgfx.Frame();
        }

        // clean up
        ibh.Dispose();
        vbh.Dispose();
        program.Dispose();
        Bgfx.Shutdown();
    }