Пример #1
0
        internal GraphicsContext(IntPtr graphics_surface_ptr, int width, int height)
        {
            var timer = Stopwatch.StartNew();

            Bgfx.SetPlatformData(new PlatformData
            {
                WindowHandle = graphics_surface_ptr
            });

            var bgfx_callback_handler = new BgfxCallbackHandler();

            var settings = new InitSettings
            {
                Backend         = RendererBackend.Default,
                ResetFlags      = ResetFlags.Vsync,
                Width           = width,
                Height          = height,
                CallbackHandler = bgfx_callback_handler
            };

            Bgfx.Init(settings);

            Console.WriteLine($" > GFX INIT : {timer.Elapsed.TotalSeconds.ToString()}");

            var caps = Bgfx.GetCaps();

            Info = new GraphicsInfo(caps.Backend, caps.MaxTextureSize);

            Console.WriteLine($"GRAPHICS BACKEND : {Info.RendererBackend.ToString()}");

            index_buffers = new IndexBuffer[16];
        }
Пример #2
0
    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);

        // check capabilities
        var caps              = Bgfx.GetCaps();
        var computeSupported  = caps.SupportedFeatures.HasFlag(DeviceFeatures.Compute);
        var indirectSupported = caps.SupportedFeatures.HasFlag(DeviceFeatures.DrawIndirect);

        if (computeSupported)
        {
            RunCompute(sample, indirectSupported);
        }
        else
        {
            RunUnsupported(sample);
        }

        // clean up
        Bgfx.Shutdown();
    }
Пример #3
0
        //!!!!
        //static void Listener_eventOccurred( string name )
        //{
        //	if( RenderSystemEvent != null )
        //	{
        //		RenderSystemEvent type;

        //		if( name == "DeviceLost" )
        //			type = NeoAxis.RenderSystemEvent.DeviceLost;
        //		else if( name == "DeviceRestored" )
        //			type = NeoAxis.RenderSystemEvent.DeviceRestored;
        //		else
        //		{
        //			Log.Fatal( "RenderSystem: Unknown render system event \"{0}\".", name );
        //			return;
        //		}

        //		RenderSystemEvent( type );
        //	}
        //}

        static void InitGPUSettingsAndCapabilities()
        {
            Capabilities = Bgfx.GetCaps();

            Log.InvisibleInfo("Renderer: Backend: " + Capabilities.Backend.ToString());
            Log.InvisibleInfo("Renderer: Adapter vendor: " + Capabilities.CurrentAdapter.Vendor.ToString());
            Log.InvisibleInfo("Renderer: Adapter device: " + Capabilities.CurrentAdapter.DeviceId.ToString());
            Log.InvisibleInfo("Renderer: Adapter description: " + Bgfx.GetGPUDescription());
            Log.InvisibleInfo("Renderer: -------------------------");
        }
Пример #4
0
        private void ImplInitialize(IntPtr graphics_surface_ptr, int width, int height)
        {
            Bgfx.SetPlatformData(new PlatformData
            {
                WindowHandle = graphics_surface_ptr
            });

            var bgfx_callback_handler = new BgfxCallbackHandler();

            var settings = new InitSettings
            {
                Backend         = RendererBackend.Default,
                ResetFlags      = ResetFlags.Vsync,
                Width           = width,
                Height          = height,
                CallbackHandler = bgfx_callback_handler
            };

            Bgfx.Init(settings);


            var caps = Bgfx.GetCaps();

            GraphicsBackend gfx_backend = GraphicsBackend.OpenGL;

            switch (caps.Backend)
            {
            case RendererBackend.OpenGL: gfx_backend = GraphicsBackend.OpenGL; break;

            case RendererBackend.Direct3D11:
            case RendererBackend.Direct3D12:
            case RendererBackend.Direct3D9:
                gfx_backend = GraphicsBackend.OpenGL; break;
            }

            Info = new GraphicsInfo(gfx_backend, caps.MaxTextureSize);
        }
Пример #5
0
    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);

        // load shaders
        var programTextureLighting = ResourceLoader.LoadProgram("vs_stencil_texture_lighting", "fs_stencil_texture_lighting");
        var programColorLighting   = ResourceLoader.LoadProgram("vs_stencil_color_lighting", "fs_stencil_color_lighting");
        var programColorTexture    = ResourceLoader.LoadProgram("vs_stencil_color_texture", "fs_stencil_color_texture");
        var programColorBlack      = ResourceLoader.LoadProgram("vs_stencil_color", "fs_stencil_color_black");
        var programTexture         = ResourceLoader.LoadProgram("vs_stencil_texture", "fs_stencil_texture");

        // load meshes
        var bunnyMesh  = ResourceLoader.LoadMesh("bunny.bin");
        var columnMesh = ResourceLoader.LoadMesh("column.bin");
        var hplaneMesh = new Mesh(MemoryBlock.FromArray(StaticMeshes.HorizontalPlane), PosNormalTexcoordVertex.Layout, StaticMeshes.PlaneIndices);
        var vplaneMesh = new Mesh(MemoryBlock.FromArray(StaticMeshes.VerticalPlane), PosNormalTexcoordVertex.Layout, StaticMeshes.PlaneIndices);

        // load textures
        var figureTex     = ResourceLoader.LoadTexture("figure-rgba.dds");
        var flareTex      = ResourceLoader.LoadTexture("flare.dds");
        var fieldstoneTex = ResourceLoader.LoadTexture("fieldstone-rgba.dds");

        // create uniforms
        var colorTextureHandle = new Uniform("u_texColor", UniformType.Sampler);
        var uniforms           = new Uniforms();

        uniforms.SubmitConstUniforms();

        // light colors
        uniforms.LightColor = new[] {
            new Vector4(1.0f, 0.7f, 0.2f, 0.0f), // yellow
            new Vector4(0.7f, 0.2f, 1.0f, 0.0f), // purple
            new Vector4(0.2f, 1.0f, 0.7f, 0.0f), // cyan
            new Vector4(1.0f, 0.4f, 0.2f, 0.0f)  // orange
        };

        // camera
        var camera = new Camera(60.0f, sample.WindowWidth, sample.WindowHeight, 0.1f, 100.0f);

        camera.Position = new Vector3(0.0f, 18.0f, -40.0f);

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

        clock.Start();

        // check caps and stats, for testing purposes
        Bgfx.GetCaps();
        Bgfx.GetStats();

        // 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/13-Stencil");
            Bgfx.DebugTextWrite(0, 2, DebugColor.White, DebugColor.Cyan, "Description: Stencil reflections.");
            Bgfx.DebugTextWrite(0, 3, DebugColor.White, DebugColor.Cyan, "Frame: {0:F3} ms", elapsed * 1000);

            // clear the background
            Bgfx.SetViewClear(BaseId, ClearTargets.Color | ClearTargets.Depth | ClearTargets.Stencil, 0x30303000);
            Bgfx.SetViewRect(BaseId, 0, 0, sample.WindowWidth, sample.WindowHeight);
            Bgfx.Touch(BaseId);

            // set view params for each pass
            var viewMtx = camera.GetViewMatrix();
            var projMtx = camera.GetProjectionMatrix();
            for (byte i = PassId0; i <= PassId4; i++)
            {
                Bgfx.SetViewRect(i, 0, 0, sample.WindowWidth, sample.WindowHeight);
                Bgfx.SetViewTransform(i, (float *)&viewMtx, (float *)&projMtx);
            }

            // first pass - draw ground plane
            var floorMtx = FloorTransform;
            hplaneMesh.Submit(PassId0, programColorBlack, &floorMtx, StateGroups[PrebuiltRenderState.StencilReflectionCraftStencil], uniforms);

            // second pass - reflected objects
            Bgfx.SetViewClear(PassId1, ClearTargets.Depth, 0);
            uniforms.AmbientPass  = true;
            uniforms.LightingPass = true;
            uniforms.Color        = new Vector4(0.70f, 0.65f, 0.60f, 0.8f);
            uniforms.LightCount   = LightCount;

            // light positions
            var lightPositions  = new Vector4[LightCount];
            var reflectedLights = new Vector4[LightCount];
            for (int i = 0; i < lightPositions.Length; i++)
            {
                var v3 = new Vector3(
                    (float)Math.Sin(time * 1.1 + i * 0.03 + i * 1.07 * Math.PI / 2) * 20.0f,
                    8.0f + (1.0f - (float)Math.Cos(time * 1.5 + i * 0.29 + 1.49f * Math.PI / 2)) * 4.0f,
                    (float)Math.Cos(time * 1.3 + i * 0.13 + i * 1.79 * Math.PI / 2) * 20.0f
                    );

                lightPositions[i]  = new Vector4(v3, 15.0f);
                reflectedLights[i] = new Vector4(Vector3.Transform(v3, ReflectionTransform), 15.0f);
            }

            uniforms.LightPosRadius = reflectedLights;
            var bunnyMtx =
                Matrix4x4.CreateScale(5) *
                Matrix4x4.CreateRotationY(time - 1.56f) *
                Matrix4x4.CreateTranslation(0.0f, 2.0f, 0.0f);
            var reflectedBunnyMtx = bunnyMtx * ReflectionTransform;
            bunnyMesh.Submit(PassId1, programColorLighting, &reflectedBunnyMtx, StateGroups[PrebuiltRenderState.StencilReflectionDrawReflected], uniforms);

            for (int i = 0; i < 4; i++)
            {
                var mtx = ColumnTransforms[i] * ReflectionTransform;
                columnMesh.Submit(PassId1, programColorLighting, &mtx, StateGroups[PrebuiltRenderState.StencilReflectionDrawReflected], uniforms);
            }

            // third pass - blend the plane and reflections
            uniforms.LightPosRadius = lightPositions;
            hplaneMesh.Submit(PassId2, programTextureLighting, &floorMtx, StateGroups[PrebuiltRenderState.StencilReflectionBlendPlane], uniforms, fieldstoneTex, colorTextureHandle);

            // fourth pass - draw the solid objects
            bunnyMesh.Submit(PassId3, programColorLighting, &bunnyMtx, StateGroups[PrebuiltRenderState.StencilReflectionDrawScene], uniforms);
            for (int i = 0; i < 4; i++)
            {
                var mtx = ColumnTransforms[i];
                columnMesh.Submit(PassId3, programColorLighting, &mtx, StateGroups[PrebuiltRenderState.StencilReflectionDrawScene], uniforms);
            }

            // fifth pass - draw the lights as objects
            for (int i = 0; i < LightCount; i++)
            {
                var c = uniforms.LightColor[i];
                uniforms.Color = new Vector4(c.X, c.Y, c.Z, 0.8f);

                var p   = lightPositions[i];
                var mtx = Matrix4x4.CreateScale(1.5f) * Matrix4x4.CreateBillboard(new Vector3(p.X, p.Y, p.Z), camera.Position, Vector3.UnitY, -Vector3.UnitZ);
                vplaneMesh.Submit(PassId4, programColorTexture, &mtx, StateGroups[PrebuiltRenderState.CustomBlendLightTexture], uniforms, flareTex, colorTextureHandle);
            }

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

        // clean up
        bunnyMesh.Dispose();
        columnMesh.Dispose();
        hplaneMesh.Dispose();
        vplaneMesh.Dispose();

        figureTex.Dispose();
        fieldstoneTex.Dispose();
        flareTex.Dispose();

        programTextureLighting.Dispose();
        programColorLighting.Dispose();
        programColorTexture.Dispose();
        programColorBlack.Dispose();
        programTexture.Dispose();

        colorTextureHandle.Dispose();
        uniforms.Dispose();

        Bgfx.Shutdown();
    }
Пример #6
0
    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();
    }
Пример #7
0
        private static void Main(string[] args)
        {
            var platform = "x64";

            if (IntPtr.Size == 4)
            {
                platform = "x86";
            }
            NativeMethods.LoadLibrary($"{platform}/SDL2.dll");
            Bgfx.InitializeLibrary();
            ushort resolutionWidth  = 800;
            ushort resolutionHeight = 600;
            var    windowhandle     = SDL.SDL_CreateWindow("hello", 10, 10, resolutionWidth, resolutionHeight,
                                                           SDL.SDL_WindowFlags.SDL_WINDOW_ALLOW_HIGHDPI);
            var wm = new SDL.SDL_SysWMinfo();

            SDL.SDL_GetWindowWMInfo(windowhandle, ref wm);
            Bgfx.SetPlatformData(wm.info.win.window);
            var init = Bgfx.Initialize(resolutionWidth, resolutionHeight, Bgfx.RendererType.DIRECT_3D11);

            ImGui.SetCurrentContext(ImGui.CreateContext());
            var IO = ImGui.GetIO();

            IO.ImeWindowHandle = wm.info.win.window;
            //IO.BackendFlags |= ImGuiBackendFlags.HasMouseCursors; // We can honor GetMouseCursor() values (optional)
            //IO.BackendFlags |= ImGuiBackendFlags.HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used)
            //IO.BackendPlatformName = new NullTerminatedString("imgui_impl_win32".ToCharArray());
            IO.KeyMap[(int)ImGuiKey.Tab]         = (int)SDL.SDL_Scancode.SDL_SCANCODE_TAB;
            IO.KeyMap[(int)ImGuiKey.LeftArrow]   = (int)SDL.SDL_Scancode.SDL_SCANCODE_LEFT;
            IO.KeyMap[(int)ImGuiKey.RightArrow]  = (int)SDL.SDL_Scancode.SDL_SCANCODE_RIGHT;
            IO.KeyMap[(int)ImGuiKey.UpArrow]     = (int)SDL.SDL_Scancode.SDL_SCANCODE_UP;
            IO.KeyMap[(int)ImGuiKey.DownArrow]   = (int)SDL.SDL_Scancode.SDL_SCANCODE_DOWN;
            IO.KeyMap[(int)ImGuiKey.PageUp]      = (int)SDL.SDL_Scancode.SDL_SCANCODE_PAGEUP;
            IO.KeyMap[(int)ImGuiKey.PageDown]    = (int)SDL.SDL_Scancode.SDL_SCANCODE_PAGEDOWN;
            IO.KeyMap[(int)ImGuiKey.Home]        = (int)SDL.SDL_Scancode.SDL_SCANCODE_HOME;
            IO.KeyMap[(int)ImGuiKey.End]         = (int)SDL.SDL_Scancode.SDL_SCANCODE_END;
            IO.KeyMap[(int)ImGuiKey.Insert]      = (int)SDL.SDL_Scancode.SDL_SCANCODE_INSERT;
            IO.KeyMap[(int)ImGuiKey.Delete]      = (int)SDL.SDL_Scancode.SDL_SCANCODE_DELETE;
            IO.KeyMap[(int)ImGuiKey.Backspace]   = (int)SDL.SDL_Scancode.SDL_SCANCODE_BACKSPACE;
            IO.KeyMap[(int)ImGuiKey.Space]       = (int)SDL.SDL_Scancode.SDL_SCANCODE_SPACE;
            IO.KeyMap[(int)ImGuiKey.Enter]       = (int)SDL.SDL_Scancode.SDL_SCANCODE_KP_ENTER;
            IO.KeyMap[(int)ImGuiKey.Escape]      = (int)SDL.SDL_Scancode.SDL_SCANCODE_ESCAPE;
            IO.KeyMap[(int)ImGuiKey.KeyPadEnter] = (int)SDL.SDL_Scancode.SDL_SCANCODE_RETURN;
            IO.KeyMap[(int)ImGuiKey.A]           = (int)SDL.SDL_Scancode.SDL_SCANCODE_A;
            IO.KeyMap[(int)ImGuiKey.C]           = (int)SDL.SDL_Scancode.SDL_SCANCODE_C;
            IO.KeyMap[(int)ImGuiKey.V]           = (int)SDL.SDL_Scancode.SDL_SCANCODE_V;
            IO.KeyMap[(int)ImGuiKey.X]           = (int)SDL.SDL_Scancode.SDL_SCANCODE_X;
            IO.KeyMap[(int)ImGuiKey.Y]           = (int)SDL.SDL_Scancode.SDL_SCANCODE_Y;
            IO.KeyMap[(int)ImGuiKey.Z]           = (int)SDL.SDL_Scancode.SDL_SCANCODE_Z;
            IO.Fonts.AddFontDefault();
            IO.Fonts.GetTexDataAsRGBA32(out IntPtr pixels, out var fwidth, out var fheight);
            IO.Fonts.SetTexID(new IntPtr(Bgfx.CreateTexture2D((ushort)fwidth, (ushort)fheight, false, 1,
                                                              (Bgfx.TextureFormat)Bgfx.TextureFormat.RGBA8,
                                                              (Bgfx.SamplerFlags.U_CLAMP | Bgfx.SamplerFlags.V_CLAMP | Bgfx.SamplerFlags.MIN_POINT |
                                                               Bgfx.SamplerFlags.MAG_POINT | Bgfx.SamplerFlags.MIP_POINT),
                                                              Bgfx.MakeRef(pixels, (uint)(4 * fwidth * fheight))).Idx));
            Bgfx.SetViewClear(0, (ushort)(Bgfx.ClearFlags.COLOR | Bgfx.ClearFlags.DEPTH), 0x6495edff, 0, 0);
            Bgfx.SetViewMode(0, Bgfx.ViewMode.SEQUENTIAL);
            Bgfx.SetViewMode(255, Bgfx.ViewMode.SEQUENTIAL);
            Bgfx.SetDebug(Bgfx.DebugFlags.NONE);
            Bgfx.Reset(resolutionWidth, resolutionHeight, Bgfx.ResetFlags.VSYNC | Bgfx.ResetFlags.MSAA_X4, init.format);
            var running  = true;
            var bgfxcaps = Bgfx.GetCaps();

            mtxOrtho(out var ortho, 0, resolutionWidth, resolutionHeight, 0, 0, 1000.0f, 0, bgfxcaps.Homogenousdepth);
            var ImguiVertexLayout = new Bgfx.VertexLayout();

            ImguiVertexLayout.Begin(Bgfx.RendererType.NOOP);
            ImguiVertexLayout.Add(Bgfx.Attrib.POSITION, Bgfx.AttribType.FLOAT, 2, false, false);
            ImguiVertexLayout.Add(Bgfx.Attrib.TEX_COORD0, Bgfx.AttribType.FLOAT, 2, false, false);
            ImguiVertexLayout.Add(Bgfx.Attrib.COLOR0, Bgfx.AttribType.UINT8, 4, true, false);
            ImguiVertexLayout.End();
            var WhitePixelTexture = Bgfx.CreateTexture2D(1, 1, false, 1, Bgfx.TextureFormat.RGBA8, Bgfx.SamplerFlags.V_CLAMP | Bgfx.SamplerFlags.U_CLAMP | Bgfx.SamplerFlags.MIN_POINT | Bgfx.SamplerFlags.MAG_POINT | Bgfx.SamplerFlags.MIP_POINT, new uint[] { 0x0000ffff });
            var TextureUniform    = Bgfx.CreateUniform("s_texture", Bgfx.UniformType.SAMPLER, 1);

            var ImGuiShader = LoadEffect("vs_imgui.bin", "fs_imgui.bin");

            while (running)
            {
                SDL.SDL_PollEvent(out var Event);
                if (Event.window.type == SDL.SDL_EventType.SDL_QUIT)
                {
                    running = false;
                }
                var mouseState = SDL.SDL_GetMouseState(out var mouseX, out var mouseY);
                IO.MouseDown[0] = (mouseState & SDL.SDL_BUTTON(SDL.SDL_BUTTON_LEFT)) != 0;
                IO.MouseDown[1] = (mouseState & SDL.SDL_BUTTON(SDL.SDL_BUTTON_RIGHT)) != 0;
                IO.MouseDown[2] = (mouseState & SDL.SDL_BUTTON(SDL.SDL_BUTTON_MIDDLE)) != 0;
                SDL.SDL_GetWindowPosition(windowhandle, out var wx, out var wy);
                SDL.SDL_GetGlobalMouseState(out mouseX, out mouseY);
                mouseX         -= wx;
                mouseY         -= wy;
                IO.MousePosPrev = IO.MousePos;
                IO.MousePos     = new Vector2(mouseX, mouseY);
                ImGui.NewFrame();
                //ImGui.SetNextWindowSize(new Vector2(200);
                if (ImGui.Begin("test"))
                {
                    if (ImGui.Button("click OS popup"))
                    {
                        SDL.SDL_ShowSimpleMessageBox(SDL.SDL_MessageBoxFlags.SDL_MESSAGEBOX_INFORMATION, "Cliked Button", "Click Message", windowhandle);
                    }

                    if (ImGui.Button("modal popup"))
                    {
                        ImGui.OpenPopup("modal popup");
                    }
                    ImGui.Text("Hello");
                    if (ImGui.BeginPopupModal("modal popup"))
                    {
                        if (ImGui.Button("clicked"))
                        {
                            ImGui.CloseCurrentPopup();
                        }
                        ImGui.EndPopup();
                    }
                }

                ImGui.End();
                ImGui.EndFrame();
                ImGui.Render();
                Bgfx.SetViewRect(0, 0, 0, resolutionWidth, resolutionHeight);
                Bgfx.SetViewRect(255, 0, 0, resolutionWidth, resolutionHeight);
                IO.DisplaySize             = new Vector2(resolutionWidth, resolutionHeight);
                IO.DisplayFramebufferScale = new Vector2(1);
                Bgfx.Touch(0);
                {
                    var    drawdata = ImGui.GetDrawData();
                    ushort viewID   = 0;
                    Bgfx.SetViewTransform(viewID, null, ortho);

                    {
                        // Render command lists
                        for (int ii = 0, num = drawdata.CmdListsCount; ii < num; ++ii)
                        {
                            var drawList    = drawdata.CmdListsRange[ii];
                            var numVertices = drawList.VtxBuffer.Size;
                            var numIndices  = drawList.IdxBuffer.Size;
                            var tib         = Bgfx.AllocateTransientIndexBuffer((uint)numIndices);
                            var tvb         = Bgfx.AllocateTransientVertexBuffer((uint)numVertices, ImguiVertexLayout);
                            tvb.CopyIntoBuffer(drawList.VtxBuffer.Data,
                                               (uint)numVertices * (uint)Unsafe.SizeOf <ImDrawVert>());
                            tib.CopyIntoBuffer(drawList.IdxBuffer.Data,
                                               (uint)numIndices * (uint)Unsafe.SizeOf <ushort>());
                            uint offset = 0;
                            for (int i = 0; i < drawList.CmdBuffer.Size; i++)
                            {
                                var cmd = drawList.CmdBuffer[i];
                                if (cmd.UserCallback != IntPtr.Zero)
                                {
                                    // cmd->UserCallback(drawList, cmd);
                                }
                                else if (cmd.ElemCount > 0)
                                {
                                    var state = Bgfx.StateFlags.WRITE_RGB
                                                | Bgfx.StateFlags.WRITE_A
                                                | Bgfx.StateFlags.MSAA
                                    ;

                                    var texHandle = new Bgfx.TextureHandle();

                                    if (cmd.TextureId.ToInt32() != 0)
                                    {
                                        texHandle.Idx = (ushort)cmd.TextureId.ToInt32();
                                    }
                                    else
                                    {
                                        texHandle.Idx = WhitePixelTexture.Idx;
                                    }

                                    state |= Bgfx.STATE_BLEND_FUNC(Bgfx.StateFlags.BLEND_SRC_ALPHA, Bgfx.StateFlags.BLEND_INV_SRC_ALPHA);
                                    ushort xx = (ushort)((cmd.ClipRect.X > 0.0f ? cmd.ClipRect.X : 0.0f));
                                    ushort yy = (ushort)((cmd.ClipRect.Y > 0.0f ? cmd.ClipRect.Y : 0.0f));
                                    ushort zz = (ushort)((cmd.ClipRect.Z > 65535.0f ? 65535.0f : cmd.ClipRect.Z) - xx);
                                    ushort ww = (ushort)((cmd.ClipRect.W > 65535.0f ? 65535.0f : cmd.ClipRect.W) - yy);
                                    Bgfx.SetScissor(xx, yy, zz, ww);
                                    Bgfx.SetState(state, 0);
                                    Bgfx.SetTexture(0, TextureUniform, texHandle);
                                    Bgfx.SetTransientVertexBuffer(0, tvb, 0, (uint)numVertices);
                                    Bgfx.SetTransientIndexBuffer(tib, offset, cmd.ElemCount);
                                    Bgfx.Submit(viewID, ImGuiShader.program, 0, false);
                                }
                                offset += cmd.ElemCount;
                            }
                        }
                    }
                }

                Bgfx.Frame(false);
            }
        }