diff options
| author | Andre Weissflog <floooh@gmail.com> | 2019-03-15 17:34:40 +0100 |
|---|---|---|
| committer | Andre Weissflog <floooh@gmail.com> | 2019-03-15 17:34:40 +0100 |
| commit | 072b8d2158a0c73e6fd9456a983bb8bacd9a1e43 (patch) | |
| tree | 34683bedfe03aa64609bd3e418a589452e993fff | |
| parent | 97fc8ccc9d1a0b25e46f11bd2c3884c5aa4be53c (diff) | |
move sokol_gfx_imgui.h to util/, update docs
| -rw-r--r-- | README.md | 18 | ||||
| -rw-r--r-- | fips.yml | 2 | ||||
| -rw-r--r-- | imgui/README.md | 538 | ||||
| -rw-r--r-- | util/README.md | 14 | ||||
| -rw-r--r-- | util/sokol_gfx_imgui.h (renamed from imgui/sokol_gfx_imgui.h) | 75 |
5 files changed, 83 insertions, 564 deletions
@@ -3,6 +3,8 @@ **Sokol (Сокол)**: Russian for Falcon, a smaller and more nimble bird of prey than the Eagle (Орёл, Oryol) +[See what's new](#updates) + Minimalistic header-only cross-platform libs in C: - **sokol\_gfx.h**: 3D-API wrapper (GL + Metal + D3D11) @@ -407,6 +409,22 @@ Mainly some "missing features" for desktop apps: # Updates +- **15-Mar-2019**: various Dear ImGui related changes: + - there's a new utility header sokol_imgui.h with a simple drop-in + renderer for Dear ImGui on top of sokol_gfx.h and sokol_app.h + (sokol_app.h is optional, and only used for input handling) + - the sokol_gfx_imgui.h debug inspection header no longer + depends on internal data structures and functions of sokol_gfx.h, as such + it is now a normal *utility header* and has been moved to the *utils* + directory + - the implementation macro for sokol_gfx_imgui.h has been changed + from SOKOL_IMPL to SOKOL_GFX_IMGUI_IMPL (so when you suddenly get + unresoled linker errors, that's the reason) + - all headers now have two preprocessor defines for the declaration + and implementation (for instance in sokol_gfx.h: SOKOL_GFX_INCLUDED + and SOKOL_GFX_IMPL_INCLUDED) these are checked in the utility-headers + to provide useful error message when dependent headers are missing + - **05-Mar-2019**: sokol_gfx.h now has a 'trace hook' API, and I have started implementing optional debug-inspection-UI headers on top of Dear ImGui: - sokol_gfx.h has a new function *sg_install_trace_hooks()*, this allows @@ -1,2 +1,2 @@ exports: - header-dirs: [ ".", "imgui", "util" ] + header-dirs: [ ".", "util" ] diff --git a/imgui/README.md b/imgui/README.md deleted file mode 100644 index 28548dc0..00000000 --- a/imgui/README.md +++ /dev/null @@ -1,538 +0,0 @@ -# Sokol Debug Inspection UIs - -This directory contains optional 'extension headers' which implement debug -inspection UIs for various Sokol headers implemented with [Dear -ImGui](https://github.com/ocornut/imgui). - -## Integration Howto - -These are the steps to add the debug inspection UIs to your own project. - -### 1. Compile the implementation as C++ (or Objective-C++) - -Dear ImGui is a C++ library, and offers a C++ API. This means the implementation -of the debug inspection headers is also written in C++, and -must be compiled in C++ or Objective-C++ mode. - -### 2. Compile the Sokol headers with trace-hooks enabled - -The debug inspection headers may need to *hook into* the Sokol APIs via -callback functions. These API callbacks are called **trace hooks** and must -be enabled by defining ```SOKOL_TRACE_HOOKS``` before including the -implementation. - -### 3. Include "imgui.h" before the implementation - -The debug inspection headers don't include ```imgui.h``` themselves, -instead the ImGui header must be included before the implementation. - -### 3. Include the debug UI implementations after the Sokol implementations - -The debug inspection headers need access to private data and functions of -their associated Sokol header. This means the implementation of the -debug inspection headers must be included **after** the implementation -of the their associated Sokol headers. I'd recomment putting all the -Sokol headers of a project into a single implementation file, together -with all *extension headers*. - -```cpp -// sokol-ui.cc -// -// Sokol header implementations and their debug inspection headers, -// compiled as C++ code and with trace-hooks enabled. On macOS/iOS -// this would need to be an Objective-C++ file instead (.mm extension). -// -#define SOKOL_IMPL -#define SOKOL_TRACE_HOOKS -#include "sokol_app.h" -#include "sokol_gfx.h" -#include "sokol_time.h" -#include "imgui.h" -#include "sokol_app_imgui.h" -#include "sokol_gfx_imgui.h" -``` - -### 4. Provide your own ImGui renderer - -You need to provide your own ImGui initialization and rendering -code. If you are using sokol_gfx.h together with sokol_app.h, you -can just copy the code from the sokol-samples: - -```cpp -#pragma once -/* - Implements a Dear ImGui renderer on top of sokol_gfx.h for - the debug-visualization UIs. -*/ -#include "sokol_app.h" -#include "sokol_gfx.h" - -#if defined(__cplusplus) -extern "C" { -#endif -void imgui_init(int sample_count); -void imgui_newframe(void); -void imgui_draw(void); -void imgui_event(const sapp_event* event); -#if defined(__cplusplus) -} // extern "C" -#endif - -//------------------------------------------------------------------------------ -#if defined(UI_IMPL) -#include "imgui.h" - -typedef struct { - ImVec2 disp_size; -} vs_params_t; - -static bool btn_down[SAPP_MAX_MOUSEBUTTONS]; -static bool btn_up[SAPP_MAX_MOUSEBUTTONS]; -static const int MaxVertices = (1<<17); -static const int MaxIndices = MaxVertices * 3; -static sg_pipeline imgui_pip; -static sg_bindings imgui_bind; - -extern const char* vs_src_imgui; -extern const char* fs_src_imgui; - -void imgui_init(int sample_count) { - ImGui::CreateContext(); - ImGui::StyleColorsDark(); - auto& style = ImGui::GetStyle(); - style.WindowRounding = 0.0f; - style.WindowBorderSize = 1.0f; - style.Alpha = 1.0f; - auto& io = ImGui::GetIO(); - io.Fonts->AddFontDefault(); - io.IniFilename = nullptr; - io.KeyMap[ImGuiKey_Tab] = SAPP_KEYCODE_TAB; - io.KeyMap[ImGuiKey_LeftArrow] = SAPP_KEYCODE_LEFT; - io.KeyMap[ImGuiKey_RightArrow] = SAPP_KEYCODE_RIGHT; - io.KeyMap[ImGuiKey_UpArrow] = SAPP_KEYCODE_UP; - io.KeyMap[ImGuiKey_DownArrow] = SAPP_KEYCODE_DOWN; - io.KeyMap[ImGuiKey_PageUp] = SAPP_KEYCODE_PAGE_UP; - io.KeyMap[ImGuiKey_PageDown] = SAPP_KEYCODE_PAGE_DOWN; - io.KeyMap[ImGuiKey_Home] = SAPP_KEYCODE_HOME; - io.KeyMap[ImGuiKey_End] = SAPP_KEYCODE_END; - io.KeyMap[ImGuiKey_Delete] = SAPP_KEYCODE_DELETE; - io.KeyMap[ImGuiKey_Backspace] = SAPP_KEYCODE_BACKSPACE; - io.KeyMap[ImGuiKey_Space] = SAPP_KEYCODE_SPACE; - io.KeyMap[ImGuiKey_Enter] = SAPP_KEYCODE_ENTER; - io.KeyMap[ImGuiKey_Escape] = SAPP_KEYCODE_ESCAPE; - io.KeyMap[ImGuiKey_A] = SAPP_KEYCODE_A; - io.KeyMap[ImGuiKey_C] = SAPP_KEYCODE_C; - io.KeyMap[ImGuiKey_V] = SAPP_KEYCODE_V; - io.KeyMap[ImGuiKey_X] = SAPP_KEYCODE_X; - io.KeyMap[ImGuiKey_Y] = SAPP_KEYCODE_Y; - io.KeyMap[ImGuiKey_Z] = SAPP_KEYCODE_Z; - - sg_push_debug_group("imgui init"); - - // dynamic vertex- and index-buffers for imgui-generated geometry - sg_buffer_desc vbuf_desc = { }; - vbuf_desc.usage = SG_USAGE_STREAM; - vbuf_desc.size = MaxVertices * sizeof(ImDrawVert); - vbuf_desc.label = "imgui-vertices"; - imgui_bind.vertex_buffers[0] = sg_make_buffer(&vbuf_desc); - - sg_buffer_desc ibuf_desc = { }; - ibuf_desc.type = SG_BUFFERTYPE_INDEXBUFFER; - ibuf_desc.usage = SG_USAGE_STREAM; - ibuf_desc.size = MaxIndices * sizeof(ImDrawIdx); - ibuf_desc.label = "imgui-indices"; - imgui_bind.index_buffer = sg_make_buffer(&ibuf_desc); - - // font texture for imgui's default font - unsigned char* font_pixels; - int font_width, font_height; - io.Fonts->GetTexDataAsRGBA32(&font_pixels, &font_width, &font_height); - sg_image_desc img_desc = { }; - img_desc.width = font_width; - img_desc.height = font_height; - img_desc.pixel_format = SG_PIXELFORMAT_RGBA8; - img_desc.wrap_u = SG_WRAP_CLAMP_TO_EDGE; - img_desc.wrap_v = SG_WRAP_CLAMP_TO_EDGE; - img_desc.min_filter = SG_FILTER_LINEAR; - img_desc.mag_filter = SG_FILTER_LINEAR; - img_desc.content.subimage[0][0].ptr = font_pixels; - img_desc.content.subimage[0][0].size = font_width * font_height * 4; - img_desc.label = "imgui-font"; - io.Fonts->TexID = (ImTextureID)(uintptr_t) sg_make_image(&img_desc).id; - - // shader object for imgui rendering - sg_shader_desc shd_desc = { }; - auto& ub = shd_desc.vs.uniform_blocks[0]; - ub.size = sizeof(vs_params_t); - ub.uniforms[0].name = "disp_size"; - ub.uniforms[0].type = SG_UNIFORMTYPE_FLOAT2; - shd_desc.fs.images[0].name = "tex"; - shd_desc.fs.images[0].type = SG_IMAGETYPE_2D; - shd_desc.vs.source = vs_src_imgui; - shd_desc.fs.source = fs_src_imgui; - shd_desc.label = "imgui-shader"; - sg_shader shd = sg_make_shader(&shd_desc); - - // pipeline object for imgui rendering - sg_pipeline_desc pip_desc = { }; - pip_desc.layout.buffers[0].stride = sizeof(ImDrawVert); - auto& attrs = pip_desc.layout.attrs; - attrs[0].name="position"; attrs[0].sem_name="POSITION"; attrs[0].offset=offsetof(ImDrawVert, pos); attrs[0].format=SG_VERTEXFORMAT_FLOAT2; - attrs[1].name="texcoord0"; attrs[1].sem_name="TEXCOORD"; attrs[1].offset=offsetof(ImDrawVert, uv); attrs[1].format=SG_VERTEXFORMAT_FLOAT2; - attrs[2].name="color0"; attrs[2].sem_name="COLOR"; attrs[2].offset=offsetof(ImDrawVert, col); attrs[2].format=SG_VERTEXFORMAT_UBYTE4N; - pip_desc.shader = shd; - pip_desc.index_type = SG_INDEXTYPE_UINT16; - pip_desc.blend.enabled = true; - pip_desc.blend.src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA; - pip_desc.blend.dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA; - pip_desc.blend.color_write_mask = SG_COLORMASK_RGB; - pip_desc.rasterizer.sample_count = sample_count; - pip_desc.label = "imgui-pipeline"; - imgui_pip = sg_make_pipeline(&pip_desc); - - sg_pop_debug_group(); -} - -void imgui_newframe(void) { - const int cur_width = sapp_width(); - const int cur_height = sapp_height(); - ImGuiIO& io = ImGui::GetIO(); - io.DisplaySize = ImVec2(float(cur_width), float(cur_height)); - io.DeltaTime = 1.0f / 60.0f; - for (int i = 0; i < SAPP_MAX_MOUSEBUTTONS; i++) { - if (btn_down[i]) { - btn_down[i] = false; - io.MouseDown[i] = true; - } - else if (btn_up[i]) { - btn_up[i] = false; - io.MouseDown[i] = false; - } - } - ImGui::NewFrame(); -} - -void imgui_draw(void) { - ImGui::Render(); - ImDrawData* draw_data = ImGui::GetDrawData(); - if (nullptr == draw_data) { - return; - } - if (draw_data->CmdListsCount == 0) { - return; - } - - // render the command list - sg_push_debug_group("imgui"); - sg_apply_pipeline(imgui_pip); - vs_params_t vs_params; - vs_params.disp_size.x = ImGui::GetIO().DisplaySize.x; - vs_params.disp_size.y = ImGui::GetIO().DisplaySize.y; - sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, &vs_params, sizeof(vs_params)); - for (int cl_index = 0; cl_index < draw_data->CmdListsCount; cl_index++) { - const ImDrawList* cl = draw_data->CmdLists[cl_index]; - - // append vertices and indices to buffers, record start offsets in draw state - const int vtx_size = cl->VtxBuffer.size() * sizeof(ImDrawVert); - const int idx_size = cl->IdxBuffer.size() * sizeof(ImDrawIdx); - const int vb_offset = sg_append_buffer(imgui_bind.vertex_buffers[0], &cl->VtxBuffer.front(), vtx_size); - const int ib_offset = sg_append_buffer(imgui_bind.index_buffer, &cl->IdxBuffer.front(), idx_size); - /* don't render anything if the buffer is in overflow state (this is also - checked internally in sokol_gfx, draw calls that attempt from - overflowed buffers will be silently dropped) - */ - if (sg_query_buffer_overflow(imgui_bind.vertex_buffers[0]) || - sg_query_buffer_overflow(imgui_bind.index_buffer)) - { - break; - } - - ImTextureID tex_id = ImGui::GetIO().Fonts->TexID; - imgui_bind.vertex_buffer_offsets[0] = vb_offset; - imgui_bind.index_buffer_offset = ib_offset; - imgui_bind.fs_images[0].id = (uint32_t)(uintptr_t)tex_id; - - sg_apply_bindings(&imgui_bind); - int base_element = 0; - for (const ImDrawCmd& pcmd : cl->CmdBuffer) { - if (pcmd.UserCallback) { - pcmd.UserCallback(cl, &pcmd); - } - else { - if (tex_id != pcmd.TextureId) { - tex_id = pcmd.TextureId; - imgui_bind.fs_images[0].id = (uint32_t)(uintptr_t)tex_id; - sg_apply_bindings(&imgui_bind); - } - const int scissor_x = (int) (pcmd.ClipRect.x); - const int scissor_y = (int) (pcmd.ClipRect.y); - const int scissor_w = (int) (pcmd.ClipRect.z - pcmd.ClipRect.x); - const int scissor_h = (int) (pcmd.ClipRect.w - pcmd.ClipRect.y); - sg_apply_scissor_rect(scissor_x, scissor_y, scissor_w, scissor_h, true); - sg_draw(base_element, pcmd.ElemCount, 1); - } - base_element += pcmd.ElemCount; - } - } - sg_pop_debug_group(); -} - -void imgui_event(const sapp_event* event) { - auto& io = ImGui::GetIO(); - io.KeyAlt = (event->modifiers & SAPP_MODIFIER_ALT) != 0; - io.KeyCtrl = (event->modifiers & SAPP_MODIFIER_CTRL) != 0; - io.KeyShift = (event->modifiers & SAPP_MODIFIER_SHIFT) != 0; - io.KeySuper = (event->modifiers & SAPP_MODIFIER_SUPER) != 0; - switch (event->type) { - case SAPP_EVENTTYPE_MOUSE_DOWN: - io.MousePos.x = event->mouse_x; - io.MousePos.y = event->mouse_y; - btn_down[event->mouse_button] = true; - break; - case SAPP_EVENTTYPE_MOUSE_UP: - io.MousePos.x = event->mouse_x; - io.MousePos.y = event->mouse_y; - btn_up[event->mouse_button] = true; - break; - case SAPP_EVENTTYPE_MOUSE_MOVE: - io.MousePos.x = event->mouse_x; - io.MousePos.y = event->mouse_y; - break; - case SAPP_EVENTTYPE_MOUSE_ENTER: - case SAPP_EVENTTYPE_MOUSE_LEAVE: - for (int i = 0; i < 3; i++) { - btn_down[i] = false; - btn_up[i] = false; - io.MouseDown[i] = false; - } - break; - case SAPP_EVENTTYPE_MOUSE_SCROLL: - io.MouseWheelH = event->scroll_x; - io.MouseWheel = event->scroll_y; - break; - case SAPP_EVENTTYPE_TOUCHES_BEGAN: - btn_down[0] = true; - io.MousePos.x = event->touches[0].pos_x; - io.MousePos.y = event->touches[0].pos_y; - break; - case SAPP_EVENTTYPE_TOUCHES_MOVED: - io.MousePos.x = event->touches[0].pos_x; - io.MousePos.y = event->touches[0].pos_y; - break; - case SAPP_EVENTTYPE_TOUCHES_ENDED: - btn_up[0] = true; - io.MousePos.x = event->touches[0].pos_x; - io.MousePos.y = event->touches[0].pos_y; - break; - case SAPP_EVENTTYPE_TOUCHES_CANCELLED: - btn_up[0] = btn_down[0] = false; - break; - case SAPP_EVENTTYPE_KEY_DOWN: - io.KeysDown[event->key_code] = true; - break; - case SAPP_EVENTTYPE_KEY_UP: - io.KeysDown[event->key_code] = false; - break; - case SAPP_EVENTTYPE_CHAR: - io.AddInputCharacter((ImWchar)event->char_code); - break; - default: - break; - } -} - -#if defined(SOKOL_GLCORE33) -const char* vs_src_imgui = - "#version 330\n" - "uniform vec2 disp_size;\n" - "in vec2 position;\n" - "in vec2 texcoord0;\n" - "in vec4 color0;\n" - "out vec2 uv;\n" - "out vec4 color;\n" - "void main() {\n" - " gl_Position = vec4(((position/disp_size)-0.5)*vec2(2.0,-2.0), 0.5, 1.0);\n" - " uv = texcoord0;\n" - " color = color0;\n" - "}\n"; -const char* fs_src_imgui = - "#version 330\n" - "uniform sampler2D tex;\n" - "in vec2 uv;\n" - "in vec4 color;\n" - "out vec4 frag_color;\n" - "void main() {\n" - " frag_color = texture(tex, uv) * color;\n" - "}\n"; -#elif defined(SOKOL_GLES2) || defined(SOKOL_GLES3) -const char* vs_src_imgui = - "uniform vec2 disp_size;\n" - "attribute vec2 position;\n" - "attribute vec2 texcoord0;\n" - "attribute vec4 color0;\n" - "varying vec2 uv;\n" - "varying vec4 color;\n" - "void main() {\n" - " gl_Position = vec4(((position/disp_size)-0.5)*vec2(2.0,-2.0), 0.5, 1.0);\n" - " uv = texcoord0;\n" - " color = color0;\n" - "}\n"; -const char* fs_src_imgui = - "precision mediump float;\n" - "uniform sampler2D tex;\n" - "varying vec2 uv;\n" - "varying vec4 color;\n" - "void main() {\n" - " gl_FragColor = texture2D(tex, uv) * color;\n" - "}\n"; -#elif defined(SOKOL_METAL) -const char* vs_src_imgui = - "#include <metal_stdlib>\n" - "using namespace metal;\n" - "struct params_t {\n" - " float2 disp_size;\n" - "};\n" - "struct vs_in {\n" - " float2 pos [[attribute(0)]];\n" - " float2 uv [[attribute(1)]];\n" - " float4 color [[attribute(2)]];\n" - "};\n" - "struct vs_out {\n" - " float4 pos [[position]];\n" - " float2 uv;\n" - " float4 color;\n" - "};\n" - "vertex vs_out _main(vs_in in [[stage_in]], constant params_t& params [[buffer(0)]]) {\n" - " vs_out out;\n" - " out.pos = float4(((in.pos / params.disp_size)-0.5)*float2(2.0,-2.0), 0.5, 1.0);\n" - " out.uv = in.uv;\n" - " out.color = in.color;\n" - " return out;\n" - "}\n"; -const char* fs_src_imgui = - "#include <metal_stdlib>\n" - "using namespace metal;\n" - "struct fs_in {\n" - " float2 uv;\n" - " float4 color;\n" - "};\n" - "fragment float4 _main(fs_in in [[stage_in]], texture2d<float> tex [[texture(0)]], sampler smp [[sampler(0)]]) {\n" - " return tex.sample(smp, in.uv) * in.color;\n" - "}\n"; -#elif defined(SOKOL_D3D11) -const char* vs_src_imgui = - "cbuffer params {\n" - " float2 disp_size;\n" - "};\n" - "struct vs_in {\n" - " float2 pos: POSITION;\n" - " float2 uv: TEXCOORD0;\n" - " float4 color: COLOR0;\n" - "};\n" - "struct vs_out {\n" - " float2 uv: TEXCOORD0;\n" - " float4 color: COLOR0;\n" - " float4 pos: SV_Position;\n" - "};\n" - "vs_out main(vs_in inp) {\n" - " vs_out outp;\n" - " outp.pos = float4(((inp.pos/disp_size)-0.5)*float2(2.0,-2.0), 0.5, 1.0);\n" - " outp.uv = inp.uv;\n" - " outp.color = inp.color;\n" - " return outp;\n" - "}\n"; -const char* fs_src_imgui = - "Texture2D<float4> tex: register(t0);\n" - "sampler smp: register(s0);\n" - "float4 main(float2 uv: TEXCOORD0, float4 color: COLOR0): SV_Target0 {\n" - " return tex.Sample(smp, uv) * color;\n" - "}\n"; -#else -#error "No sokol-gfx backend selected" -#endif - -#endif /* UI_IMPL */ -``` - -### 5. Add UI init- and rendering-calls to your code - -All debug inspection headers follow the same API pattern (here shown -with ```sokol_gfx_imgui.h``` as an example): - -- a struct to store all state -- an init-function to initialize this struct to a good state -- a one-in-all draw-function which is called per frame -- ...and a discard function called at shutdown - -```cpp -static sg_imgui_t sg_imgui; - -void init(void) { - ... - /* initialize the sokol-gfx debug inspection UI */ - sg_imgui_init(&sg_imgui) - ... -} - -void draw_frame(void) { - ... - /* draw the debug inspection UI via Dear ImGui calls */ - sg_imgui_draw(&sg_imgui); - ... -} - -void shutdown(void) { - ... - sg_imgui_discard(&sg_imgui); - ... -} -``` - -When running this code, nothing will be rendered because all debug inspection -windows are in closed state. Opening and closing the windows is done -directly by toggling public bool members of the state struct. - -For instance in with sokol_gfx_imgui.h: - -```cpp -/* open all sokol_gfx_imgui.h windows */ -sg_imgui.buffers.open = true -sg_imgui.images.open = true; -sg_imgui.shaders.open = true; -sg_imgui.pipelines.open = true; -sg_imgui.passes.open = true; -sg_imgui.capture.open = true; -``` - -Exposing the open state as booleans has been done to make it easier to -toggle the window visibility with other ImGui functions. For instance -you could build a menu like this: - -```cpp -if (ImGui::BeginMainMenuBar()) { - if (ImGui::BeginMenu("sokol-gfx")) { - ImGui::MenuItem("Buffers", 0, &sg_imgui.buffers.open); - ImGui::MenuItem("Images", 0, &sg_imgui.images.open); - ImGui::MenuItem("Shaders", 0, &sg_imgui.shaders.open); - ImGui::MenuItem("Pipelines", 0, &sg_imgui.pipelines.open); - ImGui::MenuItem("Passes", 0, &sg_imgui.passes.open); - ImGui::MenuItem("Calls", 0, &sg_imgui.capture.open); - ImGui::EndMenu(); - } - ImGui::EndMainMenuBar(); -} -``` - -The debug inspection headers also offer more granular drawing functions -for more flexible integration into your own UI, for example the following -```sokol_gfx_imgui.h``` functions only draw the window content, so you -can integrate the UIs into your own windows: - -```cpp -void sg_imgui_draw_buffers_content(sg_imgui_t* ctx); -void sg_imgui_draw_images_content(sg_imgui_t* ctx); -void sg_imgui_draw_shaders_content(sg_imgui_t* ctx); -void sg_imgui_draw_pipelines_content(sg_imgui_t* ctx); -void sg_imgui_draw_passes_content(sg_imgui_t* ctx); -void sg_imgui_draw_capture_content(sg_imgui_t* ctx); -``` diff --git a/util/README.md b/util/README.md index 482a3896..b4fa97db 100644 --- a/util/README.md +++ b/util/README.md @@ -1,7 +1,15 @@ # Sokol Utility Headers These are optional utility headers on top of the Sokol headers. Unlike the -'core headers' they are not standalone, and usually do not contain -platform specific code. +'core headers' they are not standalone but depend on other Sokol headers +and sometimes also external libraries. -FIXME: overview of the headers, and general usage instructions. +### What's in here: + +- **sokol_imgui.h**: implements a renderer for [Dear ImGui](https://github.com/ocornut/imgui) on top of sokol_gfx.h and sokol_app.h (the latter being optional if you do your own input-forwarding to ImGui) +- **sokol_gfx_imgui.h**: a debug-inspection UI for sokol_gfx.h, this hooks into the sokol-gfx API and lets you inspect resource objects and captured API calls +- **sokol_gl.h**: (WIP) an OpenGL 1.x style immediate-mode rendering API +in top of sokol-gfx +- **sokol_dbgtxt.h**: (planned) an as simple-as-possible debug-text renderer on top of sokol-gl + +See the embedded header-documentation for build- and usage-details. diff --git a/imgui/sokol_gfx_imgui.h b/util/sokol_gfx_imgui.h index 5eeac737..13eb9155 100644 --- a/imgui/sokol_gfx_imgui.h +++ b/util/sokol_gfx_imgui.h @@ -2,29 +2,44 @@ /* sokol_gfx_imgui.h -- debug-inspection UI for sokol_gfx.h using Dear ImGui - This is an extension header for sokol_gfx.h, this means sokol_gfx_imgui.h - must be included *after* sokol_gfx.h both for the implementation - and declaration. + Do this: + #define SOKOL_GFX_IMGUI_IMPL + before you include this file in *one* C++ file to create the + implementation. - You also need to include imgui.h before including the implementation - of sokol_gfx_imgui.h. + NOTE that the implementation must be compiled as C++ or Objective-C++ + because it calls into the ImGui C++ API. The sokol_gfx_imgui.h API + itself is plain C though. - The implementation must be compiled as C++ or Objective-C++, the - declaration can be included in plain C sources. + Include the following file(s) before including sokol_gfx_imgui.h: - The sokol_gfx_imgui.h header recognizes the same preprocessor defines - that have been set for the actual Sokol headers (for instance - SOKOL_IMPL, SOKOL_MALLOC, SOKOL_LOG, etc...). + sokol_gfx.h - STEP BY STEP: - ============= - --- include the sokol_gfx_imgui.h header after the actual Sokol header - implementations and the imgui.h header (and make sure this code - is compiled as C++ or Objective-C++) + Additionally, include the following files(s) beforing including + the implementation of sokol_gfx_imgui.h: + + imgui.h + + The sokol_gfx.h implementation must be compiled with debug trace hooks + enabled by defining: - --- add a Dear ImGui renderer to your application, and the basic - per-frame code to render an ImGui UI. + SOKOL_TRACE_HOOKS + ...before including the sokol_gfx.h implementation. + + Before including the sokol_gfx_imgui.h implementation, optionally + override the following macros: + + SOKOL_ASSERT(c) -- your own assert macro, default: assert(c) + SOKOL_UNREACHABLE -- your own macro to annotate unreachable code, + default: SOKOL_ASSERT(false) + SOKOL_MALLOC(s) -- your own memory allocation function, default: malloc(s) + SOKOL_FREE(p) -- your own memory free function, default: free(p) + SOKOL_API_DECL - public function declaration prefix (default: extern) + SOKOL_API_IMPL - public function implementation prefix (default: -) + + STEP BY STEP: + ============= --- create an sg_imgui_t struct (which must be preserved between frames) and initialize it with: @@ -62,13 +77,15 @@ ImGui::EndMainMenuBar(); } - --- finally before application shutdown, call: + --- before application shutdown, call: sg_imgui_discard(&sg_imgui); ...this is not strictly necessary because the application exits anyway, but not doing this may trigger memory leak detection tools. + --- finally, your application needs an ImGui renderer, you can either + provide your own, or drop in the sokol_imgui.h utility header ALTERNATIVE DRAWING FUNCTIONS: ============================== @@ -98,8 +115,8 @@ Finer-grained drawing functions may be moved to the public API in the future as needed. - - + LICENSE + ======= zlib/libpng license Copyright (c) 2018 Andre Weissflog @@ -130,6 +147,10 @@ #error "Please include sokol_gfx.h before sokol_gfx_imgui.h" #endif +#ifndef SOKOL_API_DECL +#define SOKOL_API_DECL extern +#endif + #if defined(__cplusplus) extern "C" { #endif @@ -541,7 +562,7 @@ SOKOL_API_DECL void sg_imgui_draw_capture_window(sg_imgui_t* ctx); #endif /*=== IMPLEMENTATION =========================================================*/ -#if defined SOKOL_IMPL +#if defined SOKOL_GFX_IMGUI_IMPL #if !defined(IMGUI_VERSION) #error "Please include imgui.h before the sokol_gfx_imgui.h implementation" #endif @@ -557,6 +578,16 @@ SOKOL_API_DECL void sg_imgui_draw_capture_window(sg_imgui_t* ctx); #define SOKOL_MALLOC(s) malloc(s) #define SOKOL_FREE(p) free(p) #endif +#ifndef _SOKOL_PRIVATE + #if defined(__GNUC__) + #define _SOKOL_PRIVATE __attribute__((unused)) static + #else + #define _SOKOL_PRIVATE static + #endif +#endif +#ifndef SOKOL_API_IMPL +#define SOKOL_API_IMPL +#endif #include <string.h> #include <stdio.h> /* snprintf */ @@ -3421,4 +3452,4 @@ SOKOL_API_IMPL void sg_imgui_draw_capture_content(sg_imgui_t* ctx) { _sg_imgui_draw_capture_panel(ctx); } -#endif /* SOKOL_IMPL */ +#endif /* SOKOL_GFX_IMGUI_IMPL */ |