Updated sokol to latest git commit 1d48f3a.
This commit is contained in:
+550
-124
File diff suppressed because it is too large
Load Diff
+1083
-969
File diff suppressed because it is too large
Load Diff
+315
-142
@@ -45,8 +45,6 @@
|
||||
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_GFX_IMGUI_API_DECL - public function declaration prefix (default: extern)
|
||||
SOKOL_API_DECL - same as SOKOL_GFX_IMGUI_API_DECL
|
||||
SOKOL_API_IMPL - public function implementation prefix (default: -)
|
||||
@@ -64,7 +62,21 @@
|
||||
--- create an sg_imgui_t struct (which must be preserved between frames)
|
||||
and initialize it with:
|
||||
|
||||
sg_imgui_init(&sg_imgui);
|
||||
sg_imgui_init(&sg_imgui, &(sg_imgui_desc_t){ 0 });
|
||||
|
||||
Note that from C++ you can't inline the desc structure initialization:
|
||||
|
||||
const sg_imgui_desc_t desc = { };
|
||||
sg_imgui_init(&sg_imgui, &desc);
|
||||
|
||||
Provide optional memory allocator override functions (compatible with malloc/free) like this:
|
||||
|
||||
sg_imgui_init(&sg_imgui, &(sg_imgui_desc_t){
|
||||
.allocator = {
|
||||
.alloc = my_malloc,
|
||||
.free = my_free,
|
||||
}
|
||||
});
|
||||
|
||||
--- somewhere in the per-frame code call:
|
||||
|
||||
@@ -136,6 +148,34 @@
|
||||
Finer-grained drawing functions may be moved to the public API
|
||||
in the future as needed.
|
||||
|
||||
MEMORY ALLOCATION OVERRIDE
|
||||
==========================
|
||||
You can override the memory allocation functions at initialization time
|
||||
like this:
|
||||
|
||||
void* my_alloc(size_t size, void* user_data) {
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void my_free(void* ptr, void* user_data) {
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
...
|
||||
sg_imgui_init(&(&ctx, &(sg_imgui_desc_t){
|
||||
// ...
|
||||
.allocator = {
|
||||
.alloc = my_alloc,
|
||||
.free = my_free,
|
||||
.user_data = ...;
|
||||
}
|
||||
});
|
||||
...
|
||||
|
||||
This only affects memory allocation calls done by sokol_gfx_imgui.h
|
||||
itself though, not any allocations in OS libraries.
|
||||
|
||||
|
||||
LICENSE
|
||||
=======
|
||||
zlib/libpng license
|
||||
@@ -164,6 +204,7 @@
|
||||
#define SOKOL_GFX_IMGUI_INCLUDED (1)
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h> // size_t
|
||||
|
||||
#if !defined(SOKOL_GFX_INCLUDED)
|
||||
#error "Please include sokol_gfx.h before sokol_gfx_imgui.h"
|
||||
@@ -616,8 +657,32 @@ typedef struct sg_imgui_caps_t {
|
||||
bool open;
|
||||
} sg_imgui_caps_t;
|
||||
|
||||
/*
|
||||
sg_imgui_allocator_t
|
||||
|
||||
Used in sg_imgui_desc_t to provide custom memory-alloc and -free functions
|
||||
to sokol_gfx_imgui.h. If memory management should be overridden, both the
|
||||
alloc and free function must be provided (e.g. it's not valid to
|
||||
override one function but not the other).
|
||||
*/
|
||||
typedef struct sg_imgui_allocator_t {
|
||||
void* (*alloc)(size_t size, void* user_data);
|
||||
void (*free)(void* ptr, void* user_data);
|
||||
void* user_data;
|
||||
} sg_imgui_allocator_t;
|
||||
|
||||
/*
|
||||
sg_imgui_desc_t
|
||||
|
||||
Initialization options for sg_imgui_init().
|
||||
*/
|
||||
typedef struct sg_imgui_desc_t {
|
||||
sg_imgui_allocator_t allocator; // optional memory allocation overrides (default: malloc/free)
|
||||
} sg_imgui_desc_t;
|
||||
|
||||
typedef struct sg_imgui_t {
|
||||
uint32_t init_tag;
|
||||
sg_imgui_desc_t desc;
|
||||
sg_imgui_buffers_t buffers;
|
||||
sg_imgui_images_t images;
|
||||
sg_imgui_shaders_t shaders;
|
||||
@@ -629,7 +694,7 @@ typedef struct sg_imgui_t {
|
||||
sg_trace_hooks hooks;
|
||||
} sg_imgui_t;
|
||||
|
||||
SOKOL_GFX_IMGUI_API_DECL void sg_imgui_init(sg_imgui_t* ctx);
|
||||
SOKOL_GFX_IMGUI_API_DECL void sg_imgui_init(sg_imgui_t* ctx, const sg_imgui_desc_t* desc);
|
||||
SOKOL_GFX_IMGUI_API_DECL void sg_imgui_discard(sg_imgui_t* ctx);
|
||||
SOKOL_GFX_IMGUI_API_DECL void sg_imgui_draw(sg_imgui_t* ctx);
|
||||
|
||||
@@ -657,6 +722,11 @@ SOKOL_GFX_IMGUI_API_DECL void sg_imgui_draw_capabilities_window(sg_imgui_t* ctx)
|
||||
/*=== IMPLEMENTATION =========================================================*/
|
||||
#ifdef SOKOL_GFX_IMGUI_IMPL
|
||||
#define SOKOL_GFX_IMGUI_IMPL_INCLUDED (1)
|
||||
|
||||
#if defined(SOKOL_MALLOC) || defined(SOKOL_CALLOC) || defined(SOKOL_FREE)
|
||||
#error "SOKOL_MALLOC/CALLOC/FREE macros are no longer supported, please use sg_imgui_desc_t.allocator to override memory allocation functions"
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
#if !defined(IMGUI_VERSION)
|
||||
#error "Please include imgui.h before the sokol_imgui.h implementation"
|
||||
@@ -673,11 +743,6 @@ SOKOL_GFX_IMGUI_API_DECL void sg_imgui_draw_capabilities_window(sg_imgui_t* ctx)
|
||||
#ifndef SOKOL_UNREACHABLE
|
||||
#define SOKOL_UNREACHABLE SOKOL_ASSERT(false)
|
||||
#endif
|
||||
#ifndef SOKOL_MALLOC
|
||||
#include <stdlib.h>
|
||||
#define SOKOL_MALLOC(s) malloc(s)
|
||||
#define SOKOL_FREE(p) free(p)
|
||||
#endif
|
||||
#ifndef _SOKOL_PRIVATE
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define _SOKOL_PRIVATE __attribute__((unused)) static
|
||||
@@ -693,7 +758,8 @@ SOKOL_GFX_IMGUI_API_DECL void sg_imgui_draw_capabilities_window(sg_imgui_t* ctx)
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h> /* snprintf */
|
||||
#include <stdio.h> // snprintf
|
||||
#include <stdlib.h> // malloc, free
|
||||
|
||||
#define _SG_IMGUI_SLOT_MASK (0xFFFF)
|
||||
#define _SG_IMGUI_LIST_WIDTH (192)
|
||||
@@ -718,38 +784,38 @@ _SOKOL_PRIVATE void igSeparator() {
|
||||
_SOKOL_PRIVATE void igSameLine(float offset_from_start_x, float spacing) {
|
||||
return ImGui::SameLine(offset_from_start_x,spacing);
|
||||
}
|
||||
_SOKOL_PRIVATE void igPushIDInt(int int_id) {
|
||||
_SOKOL_PRIVATE void igPushID_Int(int int_id) {
|
||||
return ImGui::PushID(int_id);
|
||||
}
|
||||
_SOKOL_PRIVATE void igPopID() {
|
||||
return ImGui::PopID();
|
||||
}
|
||||
_SOKOL_PRIVATE bool igSelectableBool(const char* label,bool selected,ImGuiSelectableFlags flags,const ImVec2 size) {
|
||||
_SOKOL_PRIVATE bool igSelectable_Bool(const char* label,bool selected,ImGuiSelectableFlags flags,const ImVec2 size) {
|
||||
return ImGui::Selectable(label,selected,flags,size);
|
||||
}
|
||||
_SOKOL_PRIVATE bool igSmallButton(const char* label) {
|
||||
return ImGui::SmallButton(label);
|
||||
}
|
||||
_SOKOL_PRIVATE bool igBeginChildStr(const char* str_id,const ImVec2 size,bool border,ImGuiWindowFlags flags) {
|
||||
_SOKOL_PRIVATE bool igBeginChild_Str(const char* str_id,const ImVec2 size,bool border,ImGuiWindowFlags flags) {
|
||||
return ImGui::BeginChild(str_id,size,border,flags);
|
||||
}
|
||||
_SOKOL_PRIVATE void igEndChild() {
|
||||
return ImGui::EndChild();
|
||||
}
|
||||
_SOKOL_PRIVATE void igPushStyleColorU32(ImGuiCol idx, ImU32 col) {
|
||||
_SOKOL_PRIVATE void igPushStyleColor_U32(ImGuiCol idx, ImU32 col) {
|
||||
return ImGui::PushStyleColor(idx,col);
|
||||
}
|
||||
_SOKOL_PRIVATE void igPopStyleColor(int count) {
|
||||
return ImGui::PopStyleColor(count);
|
||||
}
|
||||
_SOKOL_PRIVATE bool igTreeNodeStrStr(const char* str_id,const char* fmt,...) {
|
||||
_SOKOL_PRIVATE bool igTreeNode_StrStr(const char* str_id,const char* fmt,...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
bool ret = ImGui::TreeNodeV(str_id,fmt,args);
|
||||
va_end(args);
|
||||
return ret;
|
||||
}
|
||||
_SOKOL_PRIVATE bool igTreeNodeStr(const char* label) {
|
||||
_SOKOL_PRIVATE bool igTreeNode_Str(const char* label) {
|
||||
return ImGui::TreeNode(label);
|
||||
}
|
||||
_SOKOL_PRIVATE void igTreePop() {
|
||||
@@ -785,48 +851,131 @@ _SOKOL_PRIVATE void igEnd() {
|
||||
#endif
|
||||
|
||||
/*--- UTILS ------------------------------------------------------------------*/
|
||||
_SOKOL_PRIVATE void _sg_imgui_clear(void* ptr, size_t size) {
|
||||
SOKOL_ASSERT(ptr && (size > 0));
|
||||
memset(ptr, 0, size);
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void* _sg_imgui_malloc(const sg_imgui_allocator_t* allocator, size_t size) {
|
||||
SOKOL_ASSERT(allocator && (size > 0));
|
||||
void* ptr;
|
||||
if (allocator->alloc) {
|
||||
ptr = allocator->alloc(size, allocator->user_data);
|
||||
}
|
||||
else {
|
||||
ptr = malloc(size);
|
||||
}
|
||||
SOKOL_ASSERT(ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void* _sg_imgui_malloc_clear(const sg_imgui_allocator_t* allocator, size_t size) {
|
||||
void* ptr = _sg_imgui_malloc(allocator, size);
|
||||
_sg_imgui_clear(ptr, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _sg_imgui_free(const sg_imgui_allocator_t* allocator, void* ptr) {
|
||||
SOKOL_ASSERT(allocator);
|
||||
if (allocator->free) {
|
||||
allocator->free(ptr, allocator->user_data);
|
||||
}
|
||||
else {
|
||||
free(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void* _sg_imgui_realloc(const sg_imgui_allocator_t* allocator, void* old_ptr, size_t old_size, size_t new_size) {
|
||||
SOKOL_ASSERT(allocator && (new_size > 0) && (new_size > old_size));
|
||||
void* new_ptr = _sg_imgui_malloc(allocator, new_size);
|
||||
if (old_ptr) {
|
||||
if (old_size > 0) {
|
||||
memcpy(new_ptr, old_ptr, old_size);
|
||||
}
|
||||
_sg_imgui_free(allocator, old_ptr);
|
||||
}
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE int _sg_imgui_slot_index(uint32_t id) {
|
||||
int slot_index = (int) (id & _SG_IMGUI_SLOT_MASK);
|
||||
SOKOL_ASSERT(0 != slot_index);
|
||||
return slot_index;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE int _sg_imgui_uniform_size(sg_uniform_type type, int count) {
|
||||
switch (type) {
|
||||
case SG_UNIFORMTYPE_INVALID: return 0;
|
||||
case SG_UNIFORMTYPE_FLOAT: return 4 * count;
|
||||
case SG_UNIFORMTYPE_FLOAT2: return 8 * count;
|
||||
case SG_UNIFORMTYPE_FLOAT3: return 12 * count; /* FIXME: std140??? */
|
||||
case SG_UNIFORMTYPE_FLOAT4: return 16 * count;
|
||||
case SG_UNIFORMTYPE_MAT4: return 64 * count;
|
||||
default:
|
||||
SOKOL_UNREACHABLE;
|
||||
return -1;
|
||||
}
|
||||
_SOKOL_PRIVATE uint32_t _sg_imgui_align_u32(uint32_t val, uint32_t align) {
|
||||
SOKOL_ASSERT((align > 0) && ((align & (align - 1)) == 0));
|
||||
return (val + (align - 1)) & ~(align - 1);
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void* _sg_imgui_alloc(size_t size) {
|
||||
SOKOL_ASSERT(size > 0);
|
||||
return SOKOL_MALLOC(size);
|
||||
_SOKOL_PRIVATE uint32_t _sg_imgui_std140_uniform_alignment(sg_uniform_type type, int array_count) {
|
||||
SOKOL_ASSERT(array_count > 0);
|
||||
if (array_count == 1) {
|
||||
switch (type) {
|
||||
case SG_UNIFORMTYPE_FLOAT:
|
||||
case SG_UNIFORMTYPE_INT:
|
||||
return 4;
|
||||
case SG_UNIFORMTYPE_FLOAT2:
|
||||
case SG_UNIFORMTYPE_INT2:
|
||||
return 8;
|
||||
case SG_UNIFORMTYPE_FLOAT3:
|
||||
case SG_UNIFORMTYPE_FLOAT4:
|
||||
case SG_UNIFORMTYPE_INT3:
|
||||
case SG_UNIFORMTYPE_INT4:
|
||||
return 16;
|
||||
case SG_UNIFORMTYPE_MAT4:
|
||||
return 16;
|
||||
default:
|
||||
SOKOL_UNREACHABLE;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return 16;
|
||||
}
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _sg_imgui_free(void* ptr) {
|
||||
if (ptr) {
|
||||
SOKOL_FREE(ptr);
|
||||
_SOKOL_PRIVATE uint32_t _sg_imgui_std140_uniform_size(sg_uniform_type type, int array_count) {
|
||||
SOKOL_ASSERT(array_count > 0);
|
||||
if (array_count == 1) {
|
||||
switch (type) {
|
||||
case SG_UNIFORMTYPE_FLOAT:
|
||||
case SG_UNIFORMTYPE_INT:
|
||||
return 4;
|
||||
case SG_UNIFORMTYPE_FLOAT2:
|
||||
case SG_UNIFORMTYPE_INT2:
|
||||
return 8;
|
||||
case SG_UNIFORMTYPE_FLOAT3:
|
||||
case SG_UNIFORMTYPE_INT3:
|
||||
return 12;
|
||||
case SG_UNIFORMTYPE_FLOAT4:
|
||||
case SG_UNIFORMTYPE_INT4:
|
||||
return 16;
|
||||
case SG_UNIFORMTYPE_MAT4:
|
||||
return 64;
|
||||
default:
|
||||
SOKOL_UNREACHABLE;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void* _sg_imgui_realloc(void* old_ptr, size_t old_size, size_t new_size) {
|
||||
SOKOL_ASSERT((new_size > 0) && (new_size > old_size));
|
||||
void* new_ptr = SOKOL_MALLOC(new_size);
|
||||
SOKOL_ASSERT(new_ptr);
|
||||
if (old_ptr) {
|
||||
if (old_size > 0) {
|
||||
memcpy(new_ptr, old_ptr, old_size);
|
||||
else {
|
||||
switch (type) {
|
||||
case SG_UNIFORMTYPE_FLOAT:
|
||||
case SG_UNIFORMTYPE_FLOAT2:
|
||||
case SG_UNIFORMTYPE_FLOAT3:
|
||||
case SG_UNIFORMTYPE_FLOAT4:
|
||||
case SG_UNIFORMTYPE_INT:
|
||||
case SG_UNIFORMTYPE_INT2:
|
||||
case SG_UNIFORMTYPE_INT3:
|
||||
case SG_UNIFORMTYPE_INT4:
|
||||
return 16 * (uint32_t)array_count;
|
||||
case SG_UNIFORMTYPE_MAT4:
|
||||
return 64 * (uint32_t)array_count;
|
||||
default:
|
||||
SOKOL_UNREACHABLE;
|
||||
return 0;
|
||||
}
|
||||
_sg_imgui_free(old_ptr);
|
||||
}
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _sg_imgui_strcpy(sg_imgui_str_t* dst, const char* src) {
|
||||
@@ -840,7 +989,7 @@ _SOKOL_PRIVATE void _sg_imgui_strcpy(sg_imgui_str_t* dst, const char* src) {
|
||||
dst->buf[SG_IMGUI_STRBUF_LEN-1] = 0;
|
||||
}
|
||||
else {
|
||||
memset(dst->buf, 0, SG_IMGUI_STRBUF_LEN);
|
||||
_sg_imgui_clear(dst->buf, SG_IMGUI_STRBUF_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -850,17 +999,17 @@ _SOKOL_PRIVATE sg_imgui_str_t _sg_imgui_make_str(const char* str) {
|
||||
return res;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE const char* _sg_imgui_str_dup(const char* src) {
|
||||
SOKOL_ASSERT(src);
|
||||
_SOKOL_PRIVATE const char* _sg_imgui_str_dup(const sg_imgui_allocator_t* allocator, const char* src) {
|
||||
SOKOL_ASSERT(allocator && src);
|
||||
size_t len = strlen(src) + 1;
|
||||
char* dst = (char*) _sg_imgui_alloc(len);
|
||||
char* dst = (char*) _sg_imgui_malloc(allocator, len);
|
||||
memcpy(dst, src, len);
|
||||
return (const char*) dst;
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE const void* _sg_imgui_bin_dup(const void* src, size_t num_bytes) {
|
||||
SOKOL_ASSERT(src && (num_bytes > 0));
|
||||
void* dst = _sg_imgui_alloc(num_bytes);
|
||||
_SOKOL_PRIVATE const void* _sg_imgui_bin_dup(const sg_imgui_allocator_t* allocator, const void* src, size_t num_bytes) {
|
||||
SOKOL_ASSERT(allocator && src && (num_bytes > 0));
|
||||
void* dst = _sg_imgui_malloc(allocator, num_bytes);
|
||||
memcpy(dst, src, num_bytes);
|
||||
return (const void*) dst;
|
||||
}
|
||||
@@ -966,6 +1115,7 @@ _SOKOL_PRIVATE const char* _sg_imgui_pixelformat_string(sg_pixel_format fmt) {
|
||||
case SG_PIXELFORMAT_RG16SI: return "SG_PIXELFORMAT_RG16SI";
|
||||
case SG_PIXELFORMAT_RG16F: return "SG_PIXELFORMAT_RG16F";
|
||||
case SG_PIXELFORMAT_RGBA8: return "SG_PIXELFORMAT_RGBA8";
|
||||
case SG_PIXELFORMAT_SRGB8A8: return "SG_PIXELFORMAT_SRGB8A8";
|
||||
case SG_PIXELFORMAT_RGBA8SN: return "SG_PIXELFORMAT_RGBA8SN";
|
||||
case SG_PIXELFORMAT_RGBA8UI: return "SG_PIXELFORMAT_RGBA8UI";
|
||||
case SG_PIXELFORMAT_RGBA8SI: return "SG_PIXELFORMAT_RGBA8SI";
|
||||
@@ -1004,6 +1154,7 @@ _SOKOL_PRIVATE const char* _sg_imgui_pixelformat_string(sg_pixel_format fmt) {
|
||||
case SG_PIXELFORMAT_ETC2_RGBA8: return "SG_PIXELFORMAT_ETC2_RGBA8";
|
||||
case SG_PIXELFORMAT_ETC2_RG11: return "SG_PIXELFORMAT_ETC2_RG11";
|
||||
case SG_PIXELFORMAT_ETC2_RG11SN: return "SG_PIXELFORMAT_ETC2_RG11SN";
|
||||
case SG_PIXELFORMAT_RGB9E5: return "SG_PIXELFORMAT_RGB9E5";
|
||||
default: return "???";
|
||||
}
|
||||
}
|
||||
@@ -1045,6 +1196,10 @@ _SOKOL_PRIVATE const char* _sg_imgui_uniformtype_string(sg_uniform_type t) {
|
||||
case SG_UNIFORMTYPE_FLOAT2: return "SG_UNIFORMTYPE_FLOAT2";
|
||||
case SG_UNIFORMTYPE_FLOAT3: return "SG_UNIFORMTYPE_FLOAT3";
|
||||
case SG_UNIFORMTYPE_FLOAT4: return "SG_UNIFORMTYPE_FLOAT4";
|
||||
case SG_UNIFORMTYPE_INT: return "SG_UNIFORMTYPE_INT";
|
||||
case SG_UNIFORMTYPE_INT2: return "SG_UNIFORMTYPE_INT2";
|
||||
case SG_UNIFORMTYPE_INT3: return "SG_UNIFORMTYPE_INT3";
|
||||
case SG_UNIFORMTYPE_INT4: return "SG_UNIFORMTYPE_INT4";
|
||||
case SG_UNIFORMTYPE_MAT4: return "SG_UNIFORMTYPE_MAT4";
|
||||
default: return "???";
|
||||
}
|
||||
@@ -1358,16 +1513,16 @@ _SOKOL_PRIVATE void _sg_imgui_shader_created(sg_imgui_t* ctx, sg_shader res_id,
|
||||
}
|
||||
}
|
||||
if (shd->desc.vs.source) {
|
||||
shd->desc.vs.source = _sg_imgui_str_dup(shd->desc.vs.source);
|
||||
shd->desc.vs.source = _sg_imgui_str_dup(&ctx->desc.allocator, shd->desc.vs.source);
|
||||
}
|
||||
if (shd->desc.vs.bytecode.ptr) {
|
||||
shd->desc.vs.bytecode.ptr = _sg_imgui_bin_dup(shd->desc.vs.bytecode.ptr, shd->desc.vs.bytecode.size);
|
||||
shd->desc.vs.bytecode.ptr = _sg_imgui_bin_dup(&ctx->desc.allocator, shd->desc.vs.bytecode.ptr, shd->desc.vs.bytecode.size);
|
||||
}
|
||||
if (shd->desc.fs.source) {
|
||||
shd->desc.fs.source = _sg_imgui_str_dup(shd->desc.fs.source);
|
||||
shd->desc.fs.source = _sg_imgui_str_dup(&ctx->desc.allocator, shd->desc.fs.source);
|
||||
}
|
||||
if (shd->desc.fs.bytecode.ptr) {
|
||||
shd->desc.fs.bytecode.ptr = _sg_imgui_bin_dup(shd->desc.fs.bytecode.ptr, shd->desc.fs.bytecode.size);
|
||||
shd->desc.fs.bytecode.ptr = _sg_imgui_bin_dup(&ctx->desc.allocator, shd->desc.fs.bytecode.ptr, shd->desc.fs.bytecode.size);
|
||||
}
|
||||
for (int i = 0; i < SG_MAX_VERTEX_ATTRIBUTES; i++) {
|
||||
sg_shader_attr_desc* ad = &shd->desc.attrs[i];
|
||||
@@ -1387,19 +1542,19 @@ _SOKOL_PRIVATE void _sg_imgui_shader_destroyed(sg_imgui_t* ctx, int slot_index)
|
||||
sg_imgui_shader_t* shd = &ctx->shaders.slots[slot_index];
|
||||
shd->res_id.id = SG_INVALID_ID;
|
||||
if (shd->desc.vs.source) {
|
||||
_sg_imgui_free((void*)shd->desc.vs.source);
|
||||
_sg_imgui_free(&ctx->desc.allocator, (void*)shd->desc.vs.source);
|
||||
shd->desc.vs.source = 0;
|
||||
}
|
||||
if (shd->desc.vs.bytecode.ptr) {
|
||||
_sg_imgui_free((void*)shd->desc.vs.bytecode.ptr);
|
||||
_sg_imgui_free(&ctx->desc.allocator, (void*)shd->desc.vs.bytecode.ptr);
|
||||
shd->desc.vs.bytecode.ptr = 0;
|
||||
}
|
||||
if (shd->desc.fs.source) {
|
||||
_sg_imgui_free((void*)shd->desc.fs.source);
|
||||
_sg_imgui_free(&ctx->desc.allocator, (void*)shd->desc.fs.source);
|
||||
shd->desc.fs.source = 0;
|
||||
}
|
||||
if (shd->desc.fs.bytecode.ptr) {
|
||||
_sg_imgui_free((void*)shd->desc.fs.bytecode.ptr);
|
||||
_sg_imgui_free(&ctx->desc.allocator, (void*)shd->desc.fs.bytecode.ptr);
|
||||
shd->desc.fs.bytecode.ptr = 0;
|
||||
}
|
||||
}
|
||||
@@ -1443,8 +1598,7 @@ _SOKOL_PRIVATE void _sg_imgui_capture_init(sg_imgui_t* ctx) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
sg_imgui_capture_bucket_t* bucket = &ctx->capture.bucket[i];
|
||||
bucket->ubuf_size = ubuf_initial_size;
|
||||
bucket->ubuf = (uint8_t*) _sg_imgui_alloc(bucket->ubuf_size);
|
||||
SOKOL_ASSERT(bucket->ubuf);
|
||||
bucket->ubuf = (uint8_t*) _sg_imgui_malloc(&ctx->desc.allocator, bucket->ubuf_size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1452,7 +1606,7 @@ _SOKOL_PRIVATE void _sg_imgui_capture_discard(sg_imgui_t* ctx) {
|
||||
for (int i = 0; i < 2; i++) {
|
||||
sg_imgui_capture_bucket_t* bucket = &ctx->capture.bucket[i];
|
||||
SOKOL_ASSERT(bucket->ubuf);
|
||||
_sg_imgui_free(bucket->ubuf);
|
||||
_sg_imgui_free(&ctx->desc.allocator, bucket->ubuf);
|
||||
bucket->ubuf = 0;
|
||||
}
|
||||
}
|
||||
@@ -1478,7 +1632,7 @@ _SOKOL_PRIVATE void _sg_imgui_capture_grow_ubuf(sg_imgui_t* ctx, size_t required
|
||||
size_t old_size = bucket->ubuf_size;
|
||||
size_t new_size = required_size + (required_size>>1); /* allocate a bit ahead */
|
||||
bucket->ubuf_size = new_size;
|
||||
bucket->ubuf = (uint8_t*) _sg_imgui_realloc(bucket->ubuf, old_size, new_size);
|
||||
bucket->ubuf = (uint8_t*) _sg_imgui_realloc(&ctx->desc.allocator, bucket->ubuf, old_size, new_size);
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE sg_imgui_capture_item_t* _sg_imgui_capture_next_write_item(sg_imgui_t* ctx) {
|
||||
@@ -2834,15 +2988,15 @@ _SOKOL_PRIVATE void _sg_imgui_err_bindings_invalid(void* user_data) {
|
||||
|
||||
/*--- IMGUI HELPERS ----------------------------------------------------------*/
|
||||
_SOKOL_PRIVATE bool _sg_imgui_draw_resid_list_item(uint32_t res_id, const char* label, bool selected) {
|
||||
igPushIDInt((int)res_id);
|
||||
igPushID_Int((int)res_id);
|
||||
bool res;
|
||||
if (label[0]) {
|
||||
res = igSelectableBool(label, selected, 0, IMVEC2(0,0));
|
||||
res = igSelectable_Bool(label, selected, 0, IMVEC2(0,0));
|
||||
}
|
||||
else {
|
||||
sg_imgui_str_t str;
|
||||
_sg_imgui_snprintf(&str, "0x%08X", res_id);
|
||||
res = igSelectableBool(str.buf, selected, 0, IMVEC2(0,0));
|
||||
res = igSelectable_Bool(str.buf, selected, 0, IMVEC2(0,0));
|
||||
}
|
||||
igPopID();
|
||||
return res;
|
||||
@@ -2859,7 +3013,7 @@ _SOKOL_PRIVATE bool _sg_imgui_draw_resid_link(uint32_t res_type, uint32_t res_id
|
||||
_sg_imgui_snprintf(&str_buf, "0x%08X", res_id);
|
||||
str = str_buf.buf;
|
||||
}
|
||||
igPushIDInt((int)((res_type<<24)|res_id));
|
||||
igPushID_Int((int)((res_type<<24)|res_id));
|
||||
bool res = igSmallButton(str);
|
||||
igPopID();
|
||||
return res;
|
||||
@@ -2908,7 +3062,7 @@ _SOKOL_PRIVATE void _sg_imgui_show_shader(sg_imgui_t* ctx, sg_shader shd) {
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _sg_imgui_draw_buffer_list(sg_imgui_t* ctx) {
|
||||
igBeginChildStr("buffer_list", IMVEC2(_SG_IMGUI_LIST_WIDTH,0), true, 0);
|
||||
igBeginChild_Str("buffer_list", IMVEC2(_SG_IMGUI_LIST_WIDTH,0), true, 0);
|
||||
for (int i = 0; i < ctx->buffers.num_slots; i++) {
|
||||
sg_buffer buf = ctx->buffers.slots[i].res_id;
|
||||
sg_resource_state state = sg_query_buffer_state(buf);
|
||||
@@ -2923,7 +3077,7 @@ _SOKOL_PRIVATE void _sg_imgui_draw_buffer_list(sg_imgui_t* ctx) {
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _sg_imgui_draw_image_list(sg_imgui_t* ctx) {
|
||||
igBeginChildStr("image_list", IMVEC2(_SG_IMGUI_LIST_WIDTH,0), true, 0);
|
||||
igBeginChild_Str("image_list", IMVEC2(_SG_IMGUI_LIST_WIDTH,0), true, 0);
|
||||
for (int i = 0; i < ctx->images.num_slots; i++) {
|
||||
sg_image img = ctx->images.slots[i].res_id;
|
||||
sg_resource_state state = sg_query_image_state(img);
|
||||
@@ -2938,7 +3092,7 @@ _SOKOL_PRIVATE void _sg_imgui_draw_image_list(sg_imgui_t* ctx) {
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _sg_imgui_draw_shader_list(sg_imgui_t* ctx) {
|
||||
igBeginChildStr("shader_list", IMVEC2(_SG_IMGUI_LIST_WIDTH,0), true, 0);
|
||||
igBeginChild_Str("shader_list", IMVEC2(_SG_IMGUI_LIST_WIDTH,0), true, 0);
|
||||
for (int i = 0; i < ctx->shaders.num_slots; i++) {
|
||||
sg_shader shd = ctx->shaders.slots[i].res_id;
|
||||
sg_resource_state state = sg_query_shader_state(shd);
|
||||
@@ -2953,7 +3107,7 @@ _SOKOL_PRIVATE void _sg_imgui_draw_shader_list(sg_imgui_t* ctx) {
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _sg_imgui_draw_pipeline_list(sg_imgui_t* ctx) {
|
||||
igBeginChildStr("pipeline_list", IMVEC2(_SG_IMGUI_LIST_WIDTH,0), true, 0);
|
||||
igBeginChild_Str("pipeline_list", IMVEC2(_SG_IMGUI_LIST_WIDTH,0), true, 0);
|
||||
for (int i = 1; i < ctx->pipelines.num_slots; i++) {
|
||||
sg_pipeline pip = ctx->pipelines.slots[i].res_id;
|
||||
sg_resource_state state = sg_query_pipeline_state(pip);
|
||||
@@ -2968,7 +3122,7 @@ _SOKOL_PRIVATE void _sg_imgui_draw_pipeline_list(sg_imgui_t* ctx) {
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _sg_imgui_draw_pass_list(sg_imgui_t* ctx) {
|
||||
igBeginChildStr("pass_list", IMVEC2(_SG_IMGUI_LIST_WIDTH,0), true, 0);
|
||||
igBeginChild_Str("pass_list", IMVEC2(_SG_IMGUI_LIST_WIDTH,0), true, 0);
|
||||
for (int i = 1; i < ctx->passes.num_slots; i++) {
|
||||
sg_pass pass = ctx->passes.slots[i].res_id;
|
||||
sg_resource_state state = sg_query_pass_state(pass);
|
||||
@@ -2983,19 +3137,19 @@ _SOKOL_PRIVATE void _sg_imgui_draw_pass_list(sg_imgui_t* ctx) {
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _sg_imgui_draw_capture_list(sg_imgui_t* ctx) {
|
||||
igBeginChildStr("capture_list", IMVEC2(_SG_IMGUI_LIST_WIDTH,0), true, 0);
|
||||
igBeginChild_Str("capture_list", IMVEC2(_SG_IMGUI_LIST_WIDTH,0), true, 0);
|
||||
const int num_items = _sg_imgui_capture_num_read_items(ctx);
|
||||
uint64_t group_stack = 1; /* bit set: group unfolded, cleared: folded */
|
||||
for (int i = 0; i < num_items; i++) {
|
||||
const sg_imgui_capture_item_t* item = _sg_imgui_capture_read_item_at(ctx, i);
|
||||
sg_imgui_str_t item_string = _sg_imgui_capture_item_string(ctx, i, item);
|
||||
igPushStyleColorU32(ImGuiCol_Text, item->color);
|
||||
igPushIDInt(i);
|
||||
igPushStyleColor_U32(ImGuiCol_Text, item->color);
|
||||
igPushID_Int(i);
|
||||
if (item->cmd == SG_IMGUI_CMD_PUSH_DEBUG_GROUP) {
|
||||
if (group_stack & 1) {
|
||||
group_stack <<= 1;
|
||||
const char* group_name = item->args.push_debug_group.name.buf;
|
||||
if (igTreeNodeStrStr(group_name, "Group: %s", group_name)) {
|
||||
if (igTreeNode_StrStr(group_name, "Group: %s", group_name)) {
|
||||
group_stack |= 1;
|
||||
}
|
||||
}
|
||||
@@ -3010,7 +3164,7 @@ _SOKOL_PRIVATE void _sg_imgui_draw_capture_list(sg_imgui_t* ctx) {
|
||||
group_stack >>= 1;
|
||||
}
|
||||
else if (group_stack & 1) {
|
||||
if (igSelectableBool(item_string.buf, ctx->capture.sel_item == i, 0, IMVEC2(0,0))) {
|
||||
if (igSelectable_Bool(item_string.buf, ctx->capture.sel_item == i, 0, IMVEC2(0,0))) {
|
||||
ctx->capture.sel_item = i;
|
||||
}
|
||||
if (igIsItemHovered(0)) {
|
||||
@@ -3025,7 +3179,7 @@ _SOKOL_PRIVATE void _sg_imgui_draw_capture_list(sg_imgui_t* ctx) {
|
||||
|
||||
_SOKOL_PRIVATE void _sg_imgui_draw_buffer_panel(sg_imgui_t* ctx, sg_buffer buf) {
|
||||
if (buf.id != SG_INVALID_ID) {
|
||||
igBeginChildStr("buffer", IMVEC2(0,0), false, 0);
|
||||
igBeginChild_Str("buffer", IMVEC2(0,0), false, 0);
|
||||
sg_buffer_info info = sg_query_buffer_info(buf);
|
||||
if (info.slot.state == SG_RESOURCESTATE_VALID) {
|
||||
const sg_imgui_buffer_t* buf_ui = &ctx->buffers.slots[_sg_imgui_slot_index(buf.id)];
|
||||
@@ -3060,7 +3214,7 @@ _SOKOL_PRIVATE void _sg_imgui_draw_embedded_image(sg_imgui_t* ctx, sg_image img,
|
||||
if (sg_query_image_state(img) == SG_RESOURCESTATE_VALID) {
|
||||
sg_imgui_image_t* img_ui = &ctx->images.slots[_sg_imgui_slot_index(img.id)];
|
||||
if (_sg_imgui_image_renderable(img_ui->desc.type, img_ui->desc.pixel_format)) {
|
||||
igPushIDInt((int)img.id);
|
||||
igPushID_Int((int)img.id);
|
||||
igSliderFloat("Scale", scale, 0.125f, 8.0f, "%.3f", ImGuiSliderFlags_Logarithmic);
|
||||
float w = (float)img_ui->desc.width * (*scale);
|
||||
float h = (float)img_ui->desc.height * (*scale);
|
||||
@@ -3075,7 +3229,7 @@ _SOKOL_PRIVATE void _sg_imgui_draw_embedded_image(sg_imgui_t* ctx, sg_image img,
|
||||
|
||||
_SOKOL_PRIVATE void _sg_imgui_draw_image_panel(sg_imgui_t* ctx, sg_image img) {
|
||||
if (img.id != SG_INVALID_ID) {
|
||||
igBeginChildStr("image", IMVEC2(0,0), false, 0);
|
||||
igBeginChild_Str("image", IMVEC2(0,0), false, 0);
|
||||
sg_image_info info = sg_query_image_info(img);
|
||||
if (info.slot.state == SG_RESOURCESTATE_VALID) {
|
||||
sg_imgui_image_t* img_ui = &ctx->images.slots[_sg_imgui_slot_index(img.id)];
|
||||
@@ -3139,14 +3293,14 @@ _SOKOL_PRIVATE void _sg_imgui_draw_shader_stage(const sg_shader_stage_desc* stag
|
||||
}
|
||||
}
|
||||
if (num_valid_ubs > 0) {
|
||||
if (igTreeNodeStr("Uniform Blocks")) {
|
||||
if (igTreeNode_Str("Uniform Blocks")) {
|
||||
for (int i = 0; i < num_valid_ubs; i++) {
|
||||
igText("#%d:", i);
|
||||
const sg_shader_uniform_block_desc* ub = &stage->uniform_blocks[i];
|
||||
for (int j = 0; j < SG_MAX_UB_MEMBERS; j++) {
|
||||
const sg_shader_uniform_desc* u = &ub->uniforms[j];
|
||||
if (SG_UNIFORMTYPE_INVALID != u->type) {
|
||||
if (u->array_count == 0) {
|
||||
if (u->array_count <= 1) {
|
||||
igText(" %s %s", _sg_imgui_uniformtype_string(u->type), u->name ? u->name : "");
|
||||
}
|
||||
else {
|
||||
@@ -3159,7 +3313,7 @@ _SOKOL_PRIVATE void _sg_imgui_draw_shader_stage(const sg_shader_stage_desc* stag
|
||||
}
|
||||
}
|
||||
if (num_valid_images > 0) {
|
||||
if (igTreeNodeStr("Images")) {
|
||||
if (igTreeNode_Str("Images")) {
|
||||
for (int i = 0; i < SG_MAX_SHADERSTAGE_IMAGES; i++) {
|
||||
const sg_shader_image_desc* sid = &stage->images[i];
|
||||
if (sid->image_type != _SG_IMAGETYPE_DEFAULT) {
|
||||
@@ -3182,13 +3336,13 @@ _SOKOL_PRIVATE void _sg_imgui_draw_shader_stage(const sg_shader_stage_desc* stag
|
||||
igText("D3D11 Target: %s", stage->d3d11_target);
|
||||
}
|
||||
if (stage->source) {
|
||||
if (igTreeNodeStr("Source")) {
|
||||
if (igTreeNode_Str("Source")) {
|
||||
igText("%s", stage->source);
|
||||
igTreePop();
|
||||
}
|
||||
}
|
||||
else if (stage->bytecode.ptr) {
|
||||
if (igTreeNodeStr("Byte Code")) {
|
||||
if (igTreeNode_Str("Byte Code")) {
|
||||
igText("Byte-code display currently not supported.");
|
||||
igTreePop();
|
||||
}
|
||||
@@ -3197,14 +3351,14 @@ _SOKOL_PRIVATE void _sg_imgui_draw_shader_stage(const sg_shader_stage_desc* stag
|
||||
|
||||
_SOKOL_PRIVATE void _sg_imgui_draw_shader_panel(sg_imgui_t* ctx, sg_shader shd) {
|
||||
if (shd.id != SG_INVALID_ID) {
|
||||
igBeginChildStr("shader", IMVEC2(0,0), false, ImGuiWindowFlags_HorizontalScrollbar);
|
||||
igBeginChild_Str("shader", IMVEC2(0,0), false, ImGuiWindowFlags_HorizontalScrollbar);
|
||||
sg_shader_info info = sg_query_shader_info(shd);
|
||||
if (info.slot.state == SG_RESOURCESTATE_VALID) {
|
||||
const sg_imgui_shader_t* shd_ui = &ctx->shaders.slots[_sg_imgui_slot_index(shd.id)];
|
||||
igText("Label: %s", shd_ui->label.buf[0] ? shd_ui->label.buf : "---");
|
||||
_sg_imgui_draw_resource_slot(&info.slot);
|
||||
igSeparator();
|
||||
if (igTreeNodeStr("Attrs")) {
|
||||
if (igTreeNode_Str("Attrs")) {
|
||||
for (int i = 0; i < SG_MAX_VERTEX_ATTRIBUTES; i++) {
|
||||
const sg_shader_attr_desc* a_desc = &shd_ui->desc.attrs[i];
|
||||
if (a_desc->name || a_desc->sem_index) {
|
||||
@@ -3216,11 +3370,11 @@ _SOKOL_PRIVATE void _sg_imgui_draw_shader_panel(sg_imgui_t* ctx, sg_shader shd)
|
||||
}
|
||||
igTreePop();
|
||||
}
|
||||
if (igTreeNodeStr("Vertex Shader Stage")) {
|
||||
if (igTreeNode_Str("Vertex Shader Stage")) {
|
||||
_sg_imgui_draw_shader_stage(&shd_ui->desc.vs);
|
||||
igTreePop();
|
||||
}
|
||||
if (igTreeNodeStr("Fragment Shader Stage")) {
|
||||
if (igTreeNode_Str("Fragment Shader Stage")) {
|
||||
_sg_imgui_draw_shader_stage(&shd_ui->desc.fs);
|
||||
igTreePop();
|
||||
}
|
||||
@@ -3233,7 +3387,7 @@ _SOKOL_PRIVATE void _sg_imgui_draw_shader_panel(sg_imgui_t* ctx, sg_shader shd)
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _sg_imgui_draw_vertex_layout(const sg_layout_desc* layout) {
|
||||
if (igTreeNodeStr("Buffers")) {
|
||||
if (igTreeNode_Str("Buffers")) {
|
||||
for (int i = 0; i < SG_MAX_SHADERSTAGE_BUFFERS; i++) {
|
||||
const sg_buffer_layout_desc* l_desc = &layout->buffers[i];
|
||||
if (l_desc->stride > 0) {
|
||||
@@ -3245,7 +3399,7 @@ _SOKOL_PRIVATE void _sg_imgui_draw_vertex_layout(const sg_layout_desc* layout) {
|
||||
}
|
||||
igTreePop();
|
||||
}
|
||||
if (igTreeNodeStr("Attrs")) {
|
||||
if (igTreeNode_Str("Attrs")) {
|
||||
for (int i = 0; i < SG_MAX_VERTEX_ATTRIBUTES; i++) {
|
||||
const sg_vertex_attr_desc* a_desc = &layout->attrs[i];
|
||||
if (a_desc->format != SG_VERTEXFORMAT_INVALID) {
|
||||
@@ -3271,11 +3425,11 @@ _SOKOL_PRIVATE void _sg_imgui_draw_stencil_state(const sg_stencil_state* ss) {
|
||||
igText("Read Mask: 0x%02X", ss->read_mask);
|
||||
igText("Write Mask: 0x%02X", ss->write_mask);
|
||||
igText("Ref: 0x%02X", ss->ref);
|
||||
if (igTreeNodeStr("Front")) {
|
||||
if (igTreeNode_Str("Front")) {
|
||||
_sg_imgui_draw_stencil_face_state(&ss->front);
|
||||
igTreePop();
|
||||
}
|
||||
if (igTreeNodeStr("Back")) {
|
||||
if (igTreeNode_Str("Back")) {
|
||||
_sg_imgui_draw_stencil_face_state(&ss->back);
|
||||
igTreePop();
|
||||
}
|
||||
@@ -3303,7 +3457,7 @@ _SOKOL_PRIVATE void _sg_imgui_draw_blend_state(const sg_blend_state* bs) {
|
||||
_SOKOL_PRIVATE void _sg_imgui_draw_color_state(const sg_color_state* cs) {
|
||||
igText("Pixel Format: %s", _sg_imgui_pixelformat_string(cs->pixel_format));
|
||||
igText("Write Mask: %s", _sg_imgui_colormask_string(cs->write_mask));
|
||||
if (igTreeNodeStr("Blend State:")) {
|
||||
if (igTreeNode_Str("Blend State:")) {
|
||||
_sg_imgui_draw_blend_state(&cs->blend);
|
||||
igTreePop();
|
||||
}
|
||||
@@ -3311,7 +3465,7 @@ _SOKOL_PRIVATE void _sg_imgui_draw_color_state(const sg_color_state* cs) {
|
||||
|
||||
_SOKOL_PRIVATE void _sg_imgui_draw_pipeline_panel(sg_imgui_t* ctx, sg_pipeline pip) {
|
||||
if (pip.id != SG_INVALID_ID) {
|
||||
igBeginChildStr("pipeline", IMVEC2(0,0), false, 0);
|
||||
igBeginChild_Str("pipeline", IMVEC2(0,0), false, 0);
|
||||
sg_pipeline_info info = sg_query_pipeline_info(pip);
|
||||
if (info.slot.state == SG_RESOURCESTATE_VALID) {
|
||||
const sg_imgui_pipeline_t* pip_ui = &ctx->pipelines.slots[_sg_imgui_slot_index(pip.id)];
|
||||
@@ -3322,15 +3476,15 @@ _SOKOL_PRIVATE void _sg_imgui_draw_pipeline_panel(sg_imgui_t* ctx, sg_pipeline p
|
||||
if (_sg_imgui_draw_shader_link(ctx, pip_ui->desc.shader)) {
|
||||
_sg_imgui_show_shader(ctx, pip_ui->desc.shader);
|
||||
}
|
||||
if (igTreeNodeStr("Vertex Layout")) {
|
||||
if (igTreeNode_Str("Vertex Layout")) {
|
||||
_sg_imgui_draw_vertex_layout(&pip_ui->desc.layout);
|
||||
igTreePop();
|
||||
}
|
||||
if (igTreeNodeStr("Depth State")) {
|
||||
if (igTreeNode_Str("Depth State")) {
|
||||
_sg_imgui_draw_depth_state(&pip_ui->desc.depth);
|
||||
igTreePop();
|
||||
}
|
||||
if (igTreeNodeStr("Stencil State")) {
|
||||
if (igTreeNode_Str("Stencil State")) {
|
||||
_sg_imgui_draw_stencil_state(&pip_ui->desc.stencil);
|
||||
igTreePop();
|
||||
}
|
||||
@@ -3338,7 +3492,7 @@ _SOKOL_PRIVATE void _sg_imgui_draw_pipeline_panel(sg_imgui_t* ctx, sg_pipeline p
|
||||
for (int i = 0; i < pip_ui->desc.color_count; i++) {
|
||||
sg_imgui_str_t str;
|
||||
_sg_imgui_snprintf(&str, "Color %d", i);
|
||||
if (igTreeNodeStr(str.buf)) {
|
||||
if (igTreeNode_Str(str.buf)) {
|
||||
_sg_imgui_draw_color_state(&pip_ui->desc.colors[i]);
|
||||
igTreePop();
|
||||
}
|
||||
@@ -3371,7 +3525,7 @@ _SOKOL_PRIVATE void _sg_imgui_draw_pass_attachment(sg_imgui_t* ctx, const sg_pas
|
||||
|
||||
_SOKOL_PRIVATE void _sg_imgui_draw_pass_panel(sg_imgui_t* ctx, sg_pass pass) {
|
||||
if (pass.id != SG_INVALID_ID) {
|
||||
igBeginChildStr("pass", IMVEC2(0,0), false, 0);
|
||||
igBeginChild_Str("pass", IMVEC2(0,0), false, 0);
|
||||
sg_pass_info info = sg_query_pass_info(pass);
|
||||
if (info.slot.state == SG_RESOURCESTATE_VALID) {
|
||||
sg_imgui_pass_t* pass_ui = &ctx->passes.slots[_sg_imgui_slot_index(pass.id)];
|
||||
@@ -3482,7 +3636,9 @@ _SOKOL_PRIVATE void _sg_imgui_draw_uniforms_panel(sg_imgui_t* ctx, const sg_imgu
|
||||
sg_imgui_capture_bucket_t* bucket = _sg_imgui_capture_get_read_bucket(ctx);
|
||||
SOKOL_ASSERT((args->ubuf_pos + args->data_size) <= bucket->ubuf_size);
|
||||
const float* uptrf = (const float*) (bucket->ubuf + args->ubuf_pos);
|
||||
const int32_t* uptri32 = (const int32_t*) uptrf;
|
||||
if (!draw_dump) {
|
||||
uint32_t u_off = 0;
|
||||
for (int i = 0; i < SG_MAX_UB_MEMBERS; i++) {
|
||||
const sg_shader_uniform_desc* ud = &ub_desc->uniforms[i];
|
||||
if (ud->type == SG_UNIFORMTYPE_INVALID) {
|
||||
@@ -3496,38 +3652,54 @@ _SOKOL_PRIVATE void _sg_imgui_draw_uniforms_panel(sg_imgui_t* ctx, const sg_imgu
|
||||
igText("%d: %s %s =", i, _sg_imgui_uniformtype_string(ud->type), ud->name?ud->name:"");
|
||||
}
|
||||
for (int item_index = 0; item_index < num_items; item_index++) {
|
||||
const uint32_t u_size = _sg_imgui_std140_uniform_size(ud->type, ud->array_count) / 4;
|
||||
const uint32_t u_align = _sg_imgui_std140_uniform_alignment(ud->type, ud->array_count) / 4;
|
||||
u_off = _sg_imgui_align_u32(u_off, u_align);
|
||||
switch (ud->type) {
|
||||
case SG_UNIFORMTYPE_FLOAT:
|
||||
igText(" %.3f", *uptrf);
|
||||
igText(" %.3f", uptrf[u_off]);
|
||||
break;
|
||||
case SG_UNIFORMTYPE_INT:
|
||||
igText(" %d", uptri32[u_off]);
|
||||
break;
|
||||
case SG_UNIFORMTYPE_FLOAT2:
|
||||
igText(" %.3f, %.3f", uptrf[0], uptrf[1]);
|
||||
igText(" %.3f, %.3f", uptrf[u_off], uptrf[u_off+1]);
|
||||
break;
|
||||
case SG_UNIFORMTYPE_INT2:
|
||||
igText(" %d, %d", uptri32[u_off], uptri32[u_off+1]);
|
||||
break;
|
||||
case SG_UNIFORMTYPE_FLOAT3:
|
||||
igText(" %.3f, %.3f, %.3f", uptrf[0], uptrf[1], uptrf[2]);
|
||||
igText(" %.3f, %.3f, %.3f", uptrf[u_off], uptrf[u_off+1], uptrf[u_off+2]);
|
||||
break;
|
||||
case SG_UNIFORMTYPE_INT3:
|
||||
igText(" %d, %d, %d", uptri32[u_off], uptri32[u_off+1], uptri32[u_off+2]);
|
||||
break;
|
||||
case SG_UNIFORMTYPE_FLOAT4:
|
||||
igText(" %.3f, %.3f, %.3f, %.3f", uptrf[0], uptrf[1], uptrf[2], uptrf[3]);
|
||||
igText(" %.3f, %.3f, %.3f, %.3f", uptrf[u_off], uptrf[u_off+1], uptrf[u_off+2], uptrf[u_off+3]);
|
||||
break;
|
||||
case SG_UNIFORMTYPE_INT4:
|
||||
igText(" %d, %d, %d, %d", uptri32[u_off], uptri32[u_off+1], uptri32[u_off+2], uptri32[u_off+3]);
|
||||
break;
|
||||
case SG_UNIFORMTYPE_MAT4:
|
||||
igText(" %.3f, %.3f, %.3f, %.3f\n"
|
||||
" %.3f, %.3f, %.3f, %.3f\n"
|
||||
" %.3f, %.3f, %.3f, %.3f\n"
|
||||
" %.3f, %.3f, %.3f, %.3f",
|
||||
uptrf[0], uptrf[1], uptrf[2], uptrf[3],
|
||||
uptrf[4], uptrf[5], uptrf[6], uptrf[7],
|
||||
uptrf[8], uptrf[9], uptrf[10], uptrf[11],
|
||||
uptrf[12], uptrf[13], uptrf[14], uptrf[15]);
|
||||
uptrf[u_off+0], uptrf[u_off+1], uptrf[u_off+2], uptrf[u_off+3],
|
||||
uptrf[u_off+4], uptrf[u_off+5], uptrf[u_off+6], uptrf[u_off+7],
|
||||
uptrf[u_off+8], uptrf[u_off+9], uptrf[u_off+10], uptrf[u_off+11],
|
||||
uptrf[u_off+12], uptrf[u_off+13], uptrf[u_off+14], uptrf[u_off+15]);
|
||||
break;
|
||||
default:
|
||||
igText("???");
|
||||
break;
|
||||
}
|
||||
uptrf += _sg_imgui_uniform_size(ud->type, 1) / (int)sizeof(float);
|
||||
u_off += u_size;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// FIXME: float vs int
|
||||
const size_t num_floats = ub_desc->size / sizeof(float);
|
||||
for (uint32_t i = 0; i < num_floats; i++) {
|
||||
igText("%.3f, ", uptrf[i]);
|
||||
@@ -3589,8 +3761,8 @@ _SOKOL_PRIVATE void _sg_imgui_draw_capture_panel(sg_imgui_t* ctx) {
|
||||
return;
|
||||
}
|
||||
sg_imgui_capture_item_t* item = _sg_imgui_capture_read_item_at(ctx, sel_item_index);
|
||||
igBeginChildStr("capture_item", IMVEC2(0, 0), false, 0);
|
||||
igPushStyleColorU32(ImGuiCol_Text, item->color);
|
||||
igBeginChild_Str("capture_item", IMVEC2(0, 0), false, 0);
|
||||
igPushStyleColor_U32(ImGuiCol_Text, item->color);
|
||||
igText("%s", _sg_imgui_capture_item_string(ctx, sel_item_index, item).buf);
|
||||
igPopStyleColor(1);
|
||||
igSeparator();
|
||||
@@ -3736,6 +3908,7 @@ _SOKOL_PRIVATE void _sg_imgui_draw_caps_panel(void) {
|
||||
igText(" max_image_array_layers: %d", l.max_image_array_layers);
|
||||
igText(" max_vertex_attrs: %d", l.max_vertex_attrs);
|
||||
igText(" gl_max_vertex_uniform_vectors: %d", l.gl_max_vertex_uniform_vectors);
|
||||
igText(" gl_max_combined_texture_image_units: %d", l.gl_max_combined_texture_image_units);
|
||||
igText("\nUsable Pixelformats:");
|
||||
for (int i = (int)(SG_PIXELFORMAT_NONE+1); i < (int)_SG_PIXELFORMAT_NUM; i++) {
|
||||
sg_pixel_format fmt = (sg_pixel_format)i;
|
||||
@@ -3753,16 +3926,26 @@ _SOKOL_PRIVATE void _sg_imgui_draw_caps_panel(void) {
|
||||
}
|
||||
}
|
||||
|
||||
#define _sg_imgui_def(val, def) (((val) == 0) ? (def) : (val))
|
||||
|
||||
_SOKOL_PRIVATE sg_imgui_desc_t _sg_imgui_desc_defaults(const sg_imgui_desc_t* desc) {
|
||||
SOKOL_ASSERT((desc->allocator.alloc && desc->allocator.free) || (!desc->allocator.alloc && !desc->allocator.free));
|
||||
sg_imgui_desc_t res = *desc;
|
||||
// FIXME: any additional default overrides would go here
|
||||
return res;
|
||||
}
|
||||
|
||||
/*--- PUBLIC FUNCTIONS -------------------------------------------------------*/
|
||||
SOKOL_API_IMPL void sg_imgui_init(sg_imgui_t* ctx) {
|
||||
SOKOL_ASSERT(ctx);
|
||||
memset(ctx, 0, sizeof(sg_imgui_t));
|
||||
SOKOL_API_IMPL void sg_imgui_init(sg_imgui_t* ctx, const sg_imgui_desc_t* desc) {
|
||||
SOKOL_ASSERT(ctx && desc);
|
||||
_sg_imgui_clear(ctx, sizeof(sg_imgui_t));
|
||||
ctx->init_tag = 0xABCDABCD;
|
||||
ctx->desc = _sg_imgui_desc_defaults(desc);
|
||||
_sg_imgui_capture_init(ctx);
|
||||
|
||||
/* hook into sokol_gfx functions */
|
||||
sg_trace_hooks hooks;
|
||||
memset(&hooks, 0, sizeof(hooks));
|
||||
_sg_imgui_clear(&hooks, sizeof(hooks));
|
||||
hooks.user_data = (void*) ctx;
|
||||
hooks.reset_state_cache = _sg_imgui_reset_state_cache;
|
||||
hooks.make_buffer = _sg_imgui_make_buffer;
|
||||
@@ -3827,37 +4010,27 @@ SOKOL_API_IMPL void sg_imgui_init(sg_imgui_t* ctx) {
|
||||
ctx->hooks = sg_install_trace_hooks(&hooks);
|
||||
|
||||
/* allocate resource debug-info slots */
|
||||
sg_desc desc = sg_query_desc();
|
||||
ctx->buffers.num_slots = desc.buffer_pool_size;
|
||||
ctx->images.num_slots = desc.image_pool_size;
|
||||
ctx->shaders.num_slots = desc.shader_pool_size;
|
||||
ctx->pipelines.num_slots = desc.pipeline_pool_size;
|
||||
ctx->passes.num_slots = desc.pass_pool_size;
|
||||
const sg_desc sgdesc = sg_query_desc();
|
||||
ctx->buffers.num_slots = sgdesc.buffer_pool_size;
|
||||
ctx->images.num_slots = sgdesc.image_pool_size;
|
||||
ctx->shaders.num_slots = sgdesc.shader_pool_size;
|
||||
ctx->pipelines.num_slots = sgdesc.pipeline_pool_size;
|
||||
ctx->passes.num_slots = sgdesc.pass_pool_size;
|
||||
|
||||
const size_t buffer_pool_size = (size_t)ctx->buffers.num_slots * sizeof(sg_imgui_buffer_t);
|
||||
ctx->buffers.slots = (sg_imgui_buffer_t*) _sg_imgui_alloc(buffer_pool_size);
|
||||
SOKOL_ASSERT(ctx->buffers.slots);
|
||||
memset(ctx->buffers.slots, 0, buffer_pool_size);
|
||||
ctx->buffers.slots = (sg_imgui_buffer_t*) _sg_imgui_malloc_clear(&ctx->desc.allocator, buffer_pool_size);
|
||||
|
||||
const size_t image_pool_size = (size_t)ctx->images.num_slots * sizeof(sg_imgui_image_t);
|
||||
ctx->images.slots = (sg_imgui_image_t*) _sg_imgui_alloc(image_pool_size);
|
||||
SOKOL_ASSERT(ctx->images.slots);
|
||||
memset(ctx->images.slots, 0, image_pool_size);
|
||||
ctx->images.slots = (sg_imgui_image_t*) _sg_imgui_malloc_clear(&ctx->desc.allocator, image_pool_size);
|
||||
|
||||
const size_t shader_pool_size = (size_t)ctx->shaders.num_slots * sizeof(sg_imgui_shader_t);
|
||||
ctx->shaders.slots = (sg_imgui_shader_t*) _sg_imgui_alloc(shader_pool_size);
|
||||
SOKOL_ASSERT(ctx->shaders.slots);
|
||||
memset(ctx->shaders.slots, 0, shader_pool_size);
|
||||
ctx->shaders.slots = (sg_imgui_shader_t*) _sg_imgui_malloc_clear(&ctx->desc.allocator, shader_pool_size);
|
||||
|
||||
const size_t pipeline_pool_size = (size_t)ctx->pipelines.num_slots * sizeof(sg_imgui_pipeline_t);
|
||||
ctx->pipelines.slots = (sg_imgui_pipeline_t*) _sg_imgui_alloc(pipeline_pool_size);
|
||||
SOKOL_ASSERT(ctx->pipelines.slots);
|
||||
memset(ctx->pipelines.slots, 0, pipeline_pool_size);
|
||||
ctx->pipelines.slots = (sg_imgui_pipeline_t*) _sg_imgui_malloc_clear(&ctx->desc.allocator, pipeline_pool_size);
|
||||
|
||||
const size_t pass_pool_size = (size_t)ctx->passes.num_slots * sizeof(sg_imgui_pass_t);
|
||||
ctx->passes.slots = (sg_imgui_pass_t*) _sg_imgui_alloc(pass_pool_size);
|
||||
SOKOL_ASSERT(ctx->passes.slots);
|
||||
memset(ctx->passes.slots, 0, pass_pool_size);
|
||||
ctx->passes.slots = (sg_imgui_pass_t*) _sg_imgui_malloc_clear(&ctx->desc.allocator, pass_pool_size);
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL void sg_imgui_discard(sg_imgui_t* ctx) {
|
||||
@@ -3872,7 +4045,7 @@ SOKOL_API_IMPL void sg_imgui_discard(sg_imgui_t* ctx) {
|
||||
_sg_imgui_buffer_destroyed(ctx, i);
|
||||
}
|
||||
}
|
||||
_sg_imgui_free((void*)ctx->buffers.slots);
|
||||
_sg_imgui_free(&ctx->desc.allocator, (void*)ctx->buffers.slots);
|
||||
ctx->buffers.slots = 0;
|
||||
}
|
||||
if (ctx->images.slots) {
|
||||
@@ -3881,7 +4054,7 @@ SOKOL_API_IMPL void sg_imgui_discard(sg_imgui_t* ctx) {
|
||||
_sg_imgui_image_destroyed(ctx, i);
|
||||
}
|
||||
}
|
||||
_sg_imgui_free((void*)ctx->images.slots);
|
||||
_sg_imgui_free(&ctx->desc.allocator, (void*)ctx->images.slots);
|
||||
ctx->images.slots = 0;
|
||||
}
|
||||
if (ctx->shaders.slots) {
|
||||
@@ -3890,7 +4063,7 @@ SOKOL_API_IMPL void sg_imgui_discard(sg_imgui_t* ctx) {
|
||||
_sg_imgui_shader_destroyed(ctx, i);
|
||||
}
|
||||
}
|
||||
_sg_imgui_free((void*)ctx->shaders.slots);
|
||||
_sg_imgui_free(&ctx->desc.allocator, (void*)ctx->shaders.slots);
|
||||
ctx->shaders.slots = 0;
|
||||
}
|
||||
if (ctx->pipelines.slots) {
|
||||
@@ -3899,7 +4072,7 @@ SOKOL_API_IMPL void sg_imgui_discard(sg_imgui_t* ctx) {
|
||||
_sg_imgui_pipeline_destroyed(ctx, i);
|
||||
}
|
||||
}
|
||||
_sg_imgui_free((void*)ctx->pipelines.slots);
|
||||
_sg_imgui_free(&ctx->desc.allocator, (void*)ctx->pipelines.slots);
|
||||
ctx->pipelines.slots = 0;
|
||||
}
|
||||
if (ctx->passes.slots) {
|
||||
@@ -3908,7 +4081,7 @@ SOKOL_API_IMPL void sg_imgui_discard(sg_imgui_t* ctx) {
|
||||
_sg_imgui_pass_destroyed(ctx, i);
|
||||
}
|
||||
}
|
||||
_sg_imgui_free((void*)ctx->passes.slots);
|
||||
_sg_imgui_free(&ctx->desc.allocator, (void*)ctx->passes.slots);
|
||||
ctx->passes.slots = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+1547
-1168
File diff suppressed because it is too large
Load Diff
Vendored
+451
-164
@@ -42,8 +42,6 @@
|
||||
to override defaults:
|
||||
|
||||
SOKOL_ASSERT(c) - your own assert macro (default: assert(c))
|
||||
SOKOL_MALLOC(s) - your own malloc function (default: malloc(s))
|
||||
SOKOL_FREE(p) - your own free function (default: free(p))
|
||||
SOKOL_IMGUI_API_DECL- public function declaration prefix (default: extern)
|
||||
SOKOL_API_DECL - same as SOKOL_IMGUI_API_DECL
|
||||
SOKOL_API_IMPL - public function implementation prefix (default: -)
|
||||
@@ -107,20 +105,18 @@
|
||||
|
||||
sg_pixel_format color_format
|
||||
The color pixel format of the render pass where the UI
|
||||
will be rendered. The default is SG_PIXELFORMAT_RGBA8
|
||||
will be rendered. The default (0) matches sokoL_gfx.h's
|
||||
default pass.
|
||||
|
||||
sg_pixel_format depth_format
|
||||
The depth-buffer pixel format of the render pass where
|
||||
the UI will be rendered. The default is SG_PIXELFORMAT_DEPTHSTENCIL.
|
||||
the UI will be rendered. The default (0) matches
|
||||
sokol_gfx.h's default pass depth format.
|
||||
|
||||
int sample_count
|
||||
The MSAA sample-count of the render pass where the UI
|
||||
will be rendered. The default is 1.
|
||||
|
||||
float dpi_scale
|
||||
DPI scaling factor. Set this to the result of sapp_dpi_scale().
|
||||
To render in high resolution on a Retina Mac this would
|
||||
typically be 2.0. The default value is 1.0
|
||||
will be rendered. The default (0) matches sokol_gfx.h's
|
||||
default pass sample count.
|
||||
|
||||
const char* ini_filename
|
||||
Sets this path as ImGui::GetIO().IniFilename where ImGui will store
|
||||
@@ -138,19 +134,51 @@
|
||||
font. In this case you need to initialize the font
|
||||
yourself after simgui_setup() is called.
|
||||
|
||||
bool disable_paste_override
|
||||
If set to true, sokol_imgui.h will not 'emulate' a Dear Imgui
|
||||
clipboard paste action on SAPP_EVENTTYPE_CLIPBOARD_PASTED event.
|
||||
This is mainly a hack/workaround to allow external workarounds
|
||||
for making copy/paste work on the web platform. In general,
|
||||
copy/paste support isn't properly fleshed out in sokol_imgui.h yet.
|
||||
|
||||
bool disable_set_mouse_cursor
|
||||
If true, sokol_imgui.h will not control the mouse cursor type
|
||||
by calling sapp_set_mouse_cursor().
|
||||
|
||||
bool disable_windows_resize_from_edges
|
||||
If true, windows can only be resized from the bottom right corner.
|
||||
The default is false, meaning windows can be resized from edges.
|
||||
|
||||
bool write_alpha_channel
|
||||
Set this to true if you want alpha values written to the
|
||||
framebuffer. By default this behavior is disabled to prevent
|
||||
undesired behavior on platforms like the web where the canvas is
|
||||
always alpha-blended with the background.
|
||||
|
||||
simgui_allocator_t allocator
|
||||
Used to override memory allocation functions. See further below
|
||||
for details.
|
||||
|
||||
--- At the start of a frame, call:
|
||||
|
||||
simgui_new_frame(int width, int height, double delta_time)
|
||||
simgui_new_frame(&(simgui_frame_desc_t){.width = ..., .height = ..., .delta_time = ..., .dpi_scale = ...});
|
||||
|
||||
'width' and 'height' are the dimensions of the rendering surface,
|
||||
passed to ImGui::GetIO().DisplaySize.
|
||||
|
||||
'delta_time' is the frame duration passed to ImGui::GetIO().DeltaTime.
|
||||
|
||||
For example, if you're using sokol_app.h and render to the
|
||||
default framebuffer:
|
||||
'dpi_scale' is the current DPI scale factor, if this is left zero-initialized,
|
||||
1.0f will be used instead. Typical values for dpi_scale are >= 1.0f.
|
||||
|
||||
simgui_new_frame(sapp_width(), sapp_height(), delta_time);
|
||||
For example, if you're using sokol_app.h and render to the default framebuffer:
|
||||
|
||||
simgui_new_frame(&(simgui_frame_desc_t){
|
||||
.width = sapp_width(),
|
||||
.height = sapp_height(),
|
||||
.delta_time = sapp_frame_duration(),
|
||||
.dpi_scale = sapp_dpi_scale()
|
||||
});
|
||||
|
||||
--- at the end of the frame, before the sg_end_pass() where you
|
||||
want to render the UI, call:
|
||||
@@ -169,10 +197,49 @@
|
||||
if this is true, you might want to skip keyboard input handling
|
||||
in your own event handler.
|
||||
|
||||
If you want to use the ImGui functions for checking if a key is pressed
|
||||
(e.g. ImGui::IsKeyPressed()) the following helper function to map
|
||||
an sapp_keycode to an ImGuiKey value may be useful:
|
||||
|
||||
int simgui_map_keycode(sapp_keycode c);
|
||||
|
||||
Note that simgui_map_keycode() can be called outside simgui_setup()/simgui_shutdown().
|
||||
|
||||
--- finally, on application shutdown, call
|
||||
|
||||
simgui_shutdown()
|
||||
|
||||
|
||||
MEMORY ALLOCATION OVERRIDE
|
||||
==========================
|
||||
You can override the memory allocation functions at initialization time
|
||||
like this:
|
||||
|
||||
void* my_alloc(size_t size, void* user_data) {
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
void my_free(void* ptr, void* user_data) {
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
...
|
||||
simgui_setup(&(simgui_desc_t){
|
||||
// ...
|
||||
.allocator = {
|
||||
.alloc = my_alloc,
|
||||
.free = my_free,
|
||||
.user_data = ...;
|
||||
}
|
||||
});
|
||||
...
|
||||
|
||||
If no overrides are provided, malloc and free will be used.
|
||||
|
||||
This only affects memory allocation calls done by sokol_imgui.h
|
||||
itself though, not any allocations in Dear ImGui.
|
||||
|
||||
|
||||
LICENSE
|
||||
=======
|
||||
|
||||
@@ -202,6 +269,7 @@
|
||||
#define SOKOL_IMGUI_INCLUDED (1)
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h> // size_t
|
||||
|
||||
#if !defined(SOKOL_GFX_INCLUDED)
|
||||
#error "Please include sokol_gfx.h before sokol_imgui.h"
|
||||
@@ -227,22 +295,47 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
simgui_allocator_t
|
||||
|
||||
Used in simgui_desc_t to provide custom memory-alloc and -free functions
|
||||
to sokol_imgui.h. If memory management should be overridden, both the
|
||||
alloc and free function must be provided (e.g. it's not valid to
|
||||
override one function but not the other).
|
||||
*/
|
||||
typedef struct simgui_allocator_t {
|
||||
void* (*alloc)(size_t size, void* user_data);
|
||||
void (*free)(void* ptr, void* user_data);
|
||||
void* user_data;
|
||||
} simgui_allocator_t;
|
||||
|
||||
typedef struct simgui_desc_t {
|
||||
int max_vertices;
|
||||
sg_pixel_format color_format;
|
||||
sg_pixel_format depth_format;
|
||||
int sample_count;
|
||||
float dpi_scale;
|
||||
const char* ini_filename;
|
||||
bool no_default_font;
|
||||
bool disable_hotkeys; /* don't let ImGui handle Ctrl-A,C,V,X,Y,Z */
|
||||
bool disable_paste_override; // if true, don't send Ctrl-V on EVENTTYPE_CLIPBOARD_PASTED
|
||||
bool disable_set_mouse_cursor; // if true, don't control the mouse cursor type via sapp_set_mouse_cursor()
|
||||
bool disable_windows_resize_from_edges; // if true, only resize edges from the bottom right corner
|
||||
bool write_alpha_channel; // if true, alpha values get written into the framebuffer
|
||||
simgui_allocator_t allocator; // optional memory allocation overrides (default: malloc/free)
|
||||
} simgui_desc_t;
|
||||
|
||||
typedef struct simgui_frame_desc_t {
|
||||
int width;
|
||||
int height;
|
||||
double delta_time;
|
||||
float dpi_scale;
|
||||
} simgui_frame_desc_t;
|
||||
|
||||
SOKOL_IMGUI_API_DECL void simgui_setup(const simgui_desc_t* desc);
|
||||
SOKOL_IMGUI_API_DECL void simgui_new_frame(int width, int height, double delta_time);
|
||||
SOKOL_IMGUI_API_DECL void simgui_new_frame(const simgui_frame_desc_t* desc);
|
||||
SOKOL_IMGUI_API_DECL void simgui_render(void);
|
||||
#if !defined(SOKOL_IMGUI_NO_SOKOL_APP)
|
||||
SOKOL_IMGUI_API_DECL bool simgui_handle_event(const sapp_event* ev);
|
||||
SOKOL_IMGUI_API_DECL int simgui_map_keycode(sapp_keycode keycode); // returns ImGuiKey_*
|
||||
#endif
|
||||
SOKOL_IMGUI_API_DECL void simgui_shutdown(void);
|
||||
|
||||
@@ -251,14 +344,21 @@ SOKOL_IMGUI_API_DECL void simgui_shutdown(void);
|
||||
|
||||
/* reference-based equivalents for C++ */
|
||||
inline void simgui_setup(const simgui_desc_t& desc) { return simgui_setup(&desc); }
|
||||
inline void simgui_new_frame(const simgui_frame_desc_t& desc) { return simgui_new_frame(&desc); }
|
||||
|
||||
#endif
|
||||
#endif /* SOKOL_IMGUI_INCLUDED */
|
||||
|
||||
/*-- IMPLEMENTATION ----------------------------------------------------------*/
|
||||
#define SOKOL_IMGUI_IMPL
|
||||
|
||||
#ifdef SOKOL_IMGUI_IMPL
|
||||
#define SOKOL_IMGUI_IMPL_INCLUDED (1)
|
||||
|
||||
#if defined(SOKOL_MALLOC) || defined(SOKOL_CALLOC) || defined(SOKOL_FREE)
|
||||
#error "SOKOL_MALLOC/CALLOC/FREE macros are no longer supported, please use simgui_desc_t.allocator to override memory allocation functions"
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
#if !defined(IMGUI_VERSION)
|
||||
#error "Please include imgui.h before the sokol_imgui.h implementation"
|
||||
@@ -269,8 +369,8 @@ inline void simgui_setup(const simgui_desc_t& desc) { return simgui_setup(&desc)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <stddef.h> /* offsetof */
|
||||
#include <string.h> /* memset */
|
||||
#include <string.h> // memset
|
||||
#include <stdlib.h> // malloc/free
|
||||
|
||||
#if defined(__EMSCRIPTEN__) && !defined(SOKOL_DUMMY_BACKEND)
|
||||
#include <emscripten.h>
|
||||
@@ -281,18 +381,13 @@ inline void simgui_setup(const simgui_desc_t& desc) { return simgui_setup(&desc)
|
||||
#endif
|
||||
#ifndef SOKOL_DEBUG
|
||||
#ifndef NDEBUG
|
||||
#define SOKOL_DEBUG (1)
|
||||
#define SOKOL_DEBUG
|
||||
#endif
|
||||
#endif
|
||||
#ifndef SOKOL_ASSERT
|
||||
#include <assert.h>
|
||||
#define SOKOL_ASSERT(c) assert(c)
|
||||
#endif
|
||||
#ifndef SOKOL_MALLOC
|
||||
#include <stdlib.h>
|
||||
#define SOKOL_MALLOC(s) malloc(s)
|
||||
#define SOKOL_FREE(p) free(p)
|
||||
#endif
|
||||
#ifndef _SOKOL_PRIVATE
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
#define _SOKOL_PRIVATE __attribute__((unused)) static
|
||||
@@ -301,7 +396,7 @@ inline void simgui_setup(const simgui_desc_t& desc) { return simgui_setup(&desc)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* helper macros */
|
||||
/* helper macros and constants */
|
||||
#define _simgui_def(val, def) (((val) == 0) ? (def) : (val))
|
||||
|
||||
typedef struct {
|
||||
@@ -309,26 +404,17 @@ typedef struct {
|
||||
uint8_t _pad_8[8];
|
||||
} _simgui_vs_params_t;
|
||||
|
||||
#define SIMGUI_MAX_KEY_VALUE (512) // same as ImGuis IO.KeysDown array
|
||||
|
||||
typedef struct {
|
||||
simgui_desc_t desc;
|
||||
float cur_dpi_scale;
|
||||
sg_buffer vbuf;
|
||||
sg_buffer ibuf;
|
||||
sg_image img;
|
||||
sg_shader shd;
|
||||
sg_pipeline pip;
|
||||
bool is_osx; // return true if running on OSX (or HTML5 OSX), needed for copy/paste
|
||||
|
||||
sg_range vertices;
|
||||
sg_range indices;
|
||||
|
||||
#if !defined(SOKOL_IMGUI_NO_SOKOL_APP)
|
||||
bool btn_down[SAPP_MAX_MOUSEBUTTONS];
|
||||
bool btn_up[SAPP_MAX_MOUSEBUTTONS];
|
||||
uint8_t keys_down[SIMGUI_MAX_KEY_VALUE]; // bits 0..3 or modifiers, != 0 is key-down
|
||||
uint8_t keys_up[SIMGUI_MAX_KEY_VALUE]; // same is keys_down
|
||||
#endif
|
||||
bool is_osx; // return true if running on OSX (or HTML5 OSX), needed for copy/paste
|
||||
} _simgui_state_t;
|
||||
static _simgui_state_t _simgui;
|
||||
|
||||
@@ -1605,6 +1691,33 @@ EM_JS(int, simgui_js_is_osx, (void), {
|
||||
});
|
||||
#endif
|
||||
|
||||
static void _simgui_clear(void* ptr, size_t size) {
|
||||
SOKOL_ASSERT(ptr && (size > 0));
|
||||
memset(ptr, 0, size);
|
||||
}
|
||||
|
||||
static void* _simgui_malloc(size_t size) {
|
||||
SOKOL_ASSERT(size > 0);
|
||||
void* ptr;
|
||||
if (_simgui.desc.allocator.alloc) {
|
||||
ptr = _simgui.desc.allocator.alloc(size, _simgui.desc.allocator.user_data);
|
||||
}
|
||||
else {
|
||||
ptr = malloc(size);
|
||||
}
|
||||
SOKOL_ASSERT(ptr);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static void _simgui_free(void* ptr) {
|
||||
if (_simgui.desc.allocator.free) {
|
||||
_simgui.desc.allocator.free(ptr, _simgui.desc.allocator.user_data);
|
||||
}
|
||||
else {
|
||||
free(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
static bool _simgui_is_osx(void) {
|
||||
#if defined(SOKOL_DUMMY_BACKEND)
|
||||
return false;
|
||||
@@ -1617,12 +1730,18 @@ static bool _simgui_is_osx(void) {
|
||||
#endif
|
||||
}
|
||||
|
||||
static simgui_desc_t _simgui_desc_defaults(const simgui_desc_t* desc) {
|
||||
SOKOL_ASSERT((desc->allocator.alloc && desc->allocator.free) || (!desc->allocator.alloc && !desc->allocator.free));
|
||||
simgui_desc_t res = *desc;
|
||||
res.max_vertices = _simgui_def(res.max_vertices, 65536);
|
||||
return res;
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL void simgui_setup(const simgui_desc_t* desc) {
|
||||
SOKOL_ASSERT(desc);
|
||||
memset(&_simgui, 0, sizeof(_simgui));
|
||||
_simgui.desc = *desc;
|
||||
_simgui.desc.max_vertices = _simgui_def(_simgui.desc.max_vertices, 65536);
|
||||
_simgui.desc.dpi_scale = _simgui_def(_simgui.desc.dpi_scale, 1.0f);
|
||||
_simgui_clear(&_simgui, sizeof(_simgui));
|
||||
_simgui.desc = _simgui_desc_defaults(desc);
|
||||
_simgui.cur_dpi_scale = 1.0f;
|
||||
#if !defined(SOKOL_IMGUI_NO_SOKOL_APP)
|
||||
_simgui.is_osx = _simgui_is_osx();
|
||||
#endif
|
||||
@@ -1633,11 +1752,9 @@ SOKOL_API_IMPL void simgui_setup(const simgui_desc_t* desc) {
|
||||
/* allocate an intermediate vertex- and index-buffer */
|
||||
SOKOL_ASSERT(_simgui.desc.max_vertices > 0);
|
||||
_simgui.vertices.size = (size_t)_simgui.desc.max_vertices * sizeof(ImDrawVert);
|
||||
_simgui.vertices.ptr = SOKOL_MALLOC(_simgui.vertices.size);
|
||||
SOKOL_ASSERT(_simgui.vertices.ptr);
|
||||
_simgui.vertices.ptr = _simgui_malloc(_simgui.vertices.size);
|
||||
_simgui.indices.size = (size_t)_simgui.desc.max_vertices * 3 * sizeof(ImDrawIdx);
|
||||
_simgui.indices.ptr = SOKOL_MALLOC(_simgui.indices.size);
|
||||
SOKOL_ASSERT(_simgui.indices.ptr);
|
||||
_simgui.indices.ptr = _simgui_malloc(_simgui.indices.size);
|
||||
|
||||
/* initialize Dear ImGui */
|
||||
#if defined(__cplusplus)
|
||||
@@ -1659,47 +1776,27 @@ SOKOL_API_IMPL void simgui_setup(const simgui_desc_t* desc) {
|
||||
io->ConfigMacOSXBehaviors = _simgui_is_osx();
|
||||
io->BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset;
|
||||
#if !defined(SOKOL_IMGUI_NO_SOKOL_APP)
|
||||
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;
|
||||
if (!_simgui.desc.disable_hotkeys) {
|
||||
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;
|
||||
if (!_simgui.desc.disable_set_mouse_cursor) {
|
||||
io->BackendFlags |= ImGuiBackendFlags_HasMouseCursors;
|
||||
}
|
||||
#if !defined(SOKOL_IMGUI_NO_SOKOL_APP)
|
||||
io->SetClipboardTextFn = _simgui_set_clipboard;
|
||||
io->GetClipboardTextFn = _simgui_get_clipboard;
|
||||
#endif
|
||||
#endif
|
||||
io->ConfigWindowsResizeFromEdges = !_simgui.desc.disable_windows_resize_from_edges;
|
||||
|
||||
/* create sokol-gfx resources */
|
||||
sg_push_debug_group("sokol-imgui");
|
||||
|
||||
/* NOTE: since we're in C++ mode here we can't use C99 designated init */
|
||||
sg_buffer_desc vb_desc;
|
||||
memset(&vb_desc, 0, sizeof(vb_desc));
|
||||
_simgui_clear(&vb_desc, sizeof(vb_desc));
|
||||
vb_desc.usage = SG_USAGE_STREAM;
|
||||
vb_desc.size = _simgui.vertices.size;
|
||||
vb_desc.label = "sokol-imgui-vertices";
|
||||
_simgui.vbuf = sg_make_buffer(&vb_desc);
|
||||
|
||||
sg_buffer_desc ib_desc;
|
||||
memset(&ib_desc, 0, sizeof(ib_desc));
|
||||
_simgui_clear(&ib_desc, sizeof(ib_desc));
|
||||
ib_desc.type = SG_BUFFERTYPE_INDEXBUFFER;
|
||||
ib_desc.usage = SG_USAGE_STREAM;
|
||||
ib_desc.size = _simgui.indices.size;
|
||||
@@ -1717,7 +1814,7 @@ SOKOL_API_IMPL void simgui_setup(const simgui_desc_t* desc) {
|
||||
ImFontAtlas_GetTexDataAsRGBA32(io->Fonts, &font_pixels, &font_width, &font_height, &bytes_per_pixel);
|
||||
#endif
|
||||
sg_image_desc img_desc;
|
||||
memset(&img_desc, 0, sizeof(img_desc));
|
||||
_simgui_clear(&img_desc, sizeof(img_desc));
|
||||
img_desc.width = font_width;
|
||||
img_desc.height = font_height;
|
||||
img_desc.pixel_format = SG_PIXELFORMAT_RGBA8;
|
||||
@@ -1734,7 +1831,7 @@ SOKOL_API_IMPL void simgui_setup(const simgui_desc_t* desc) {
|
||||
|
||||
/* shader object for using the embedded shader source (or bytecode) */
|
||||
sg_shader_desc shd_desc;
|
||||
memset(&shd_desc, 0, sizeof(shd_desc));
|
||||
_simgui_clear(&shd_desc, sizeof(shd_desc));
|
||||
shd_desc.attrs[0].name = "position";
|
||||
shd_desc.attrs[1].name = "texcoord0";
|
||||
shd_desc.attrs[2].name = "color0";
|
||||
@@ -1790,7 +1887,7 @@ SOKOL_API_IMPL void simgui_setup(const simgui_desc_t* desc) {
|
||||
|
||||
/* pipeline object for imgui rendering */
|
||||
sg_pipeline_desc pip_desc;
|
||||
memset(&pip_desc, 0, sizeof(pip_desc));
|
||||
_simgui_clear(&pip_desc, sizeof(pip_desc));
|
||||
pip_desc.layout.buffers[0].stride = sizeof(ImDrawVert);
|
||||
{
|
||||
sg_vertex_attr_desc* attr = &pip_desc.layout.attrs[0];
|
||||
@@ -1812,10 +1909,14 @@ SOKOL_API_IMPL void simgui_setup(const simgui_desc_t* desc) {
|
||||
pip_desc.sample_count = _simgui.desc.sample_count;
|
||||
pip_desc.depth.pixel_format = _simgui.desc.depth_format;
|
||||
pip_desc.colors[0].pixel_format = _simgui.desc.color_format;
|
||||
pip_desc.colors[0].write_mask = SG_COLORMASK_RGB;
|
||||
pip_desc.colors[0].write_mask = _simgui.desc.write_alpha_channel ? SG_COLORMASK_RGBA : SG_COLORMASK_RGB;
|
||||
pip_desc.colors[0].blend.enabled = true;
|
||||
pip_desc.colors[0].blend.src_factor_rgb = SG_BLENDFACTOR_SRC_ALPHA;
|
||||
pip_desc.colors[0].blend.dst_factor_rgb = SG_BLENDFACTOR_ONE_MINUS_SRC_ALPHA;
|
||||
if (_simgui.desc.write_alpha_channel) {
|
||||
pip_desc.colors[0].blend.src_factor_alpha = SG_BLENDFACTOR_ONE;
|
||||
pip_desc.colors[0].blend.dst_factor_alpha = SG_BLENDFACTOR_ONE;
|
||||
}
|
||||
pip_desc.label = "sokol-imgui-pipeline";
|
||||
_simgui.pip = sg_make_pipeline(&pip_desc);
|
||||
|
||||
@@ -1837,58 +1938,52 @@ SOKOL_API_IMPL void simgui_shutdown(void) {
|
||||
sg_destroy_buffer(_simgui.vbuf);
|
||||
sg_pop_debug_group();
|
||||
SOKOL_ASSERT(_simgui.vertices.ptr);
|
||||
SOKOL_FREE((void*)_simgui.vertices.ptr);
|
||||
_simgui_free((void*)_simgui.vertices.ptr);
|
||||
SOKOL_ASSERT(_simgui.indices.ptr);
|
||||
SOKOL_FREE((void*)_simgui.indices.ptr);
|
||||
_simgui_free((void*)_simgui.indices.ptr);
|
||||
}
|
||||
|
||||
#if !defined(SOKOL_IMGUI_NO_SOKOL_APP)
|
||||
_SOKOL_PRIVATE void _simgui_set_imgui_modifiers(ImGuiIO* io, uint32_t mods) {
|
||||
io->KeyAlt = (mods & SAPP_MODIFIER_ALT) != 0;
|
||||
io->KeyCtrl = (mods & SAPP_MODIFIER_CTRL) != 0;
|
||||
io->KeyShift = (mods & SAPP_MODIFIER_SHIFT) != 0;
|
||||
io->KeySuper = (mods & SAPP_MODIFIER_SUPER) != 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
SOKOL_API_IMPL void simgui_new_frame(int width, int height, double delta_time) {
|
||||
SOKOL_API_IMPL void simgui_new_frame(const simgui_frame_desc_t* desc) {
|
||||
SOKOL_ASSERT(desc);
|
||||
SOKOL_ASSERT(desc->width > 0);
|
||||
SOKOL_ASSERT(desc->height > 0);
|
||||
_simgui.cur_dpi_scale = _simgui_def(desc->dpi_scale, 1.0f);
|
||||
#if defined(__cplusplus)
|
||||
ImGuiIO* io = &ImGui::GetIO();
|
||||
#else
|
||||
ImGuiIO* io = igGetIO();
|
||||
#endif
|
||||
io->DisplaySize.x = ((float) width) / _simgui.desc.dpi_scale;
|
||||
io->DisplaySize.y = ((float) height) / _simgui.desc.dpi_scale;
|
||||
io->DeltaTime = (float) delta_time;
|
||||
io->DisplaySize.x = ((float)desc->width) / _simgui.cur_dpi_scale;
|
||||
io->DisplaySize.y = ((float)desc->height) / _simgui.cur_dpi_scale;
|
||||
io->DeltaTime = (float)desc->delta_time;
|
||||
#if !defined(SOKOL_IMGUI_NO_SOKOL_APP)
|
||||
for (int i = 0; i < SAPP_MAX_MOUSEBUTTONS; i++) {
|
||||
if (_simgui.btn_down[i]) {
|
||||
_simgui.btn_down[i] = false;
|
||||
io->MouseDown[i] = true;
|
||||
if (io->WantTextInput && !sapp_keyboard_shown()) {
|
||||
sapp_show_keyboard(true);
|
||||
}
|
||||
else if (_simgui.btn_up[i]) {
|
||||
_simgui.btn_up[i] = false;
|
||||
io->MouseDown[i] = false;
|
||||
if (!io->WantTextInput && sapp_keyboard_shown()) {
|
||||
sapp_show_keyboard(false);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < SIMGUI_MAX_KEY_VALUE; i++) {
|
||||
if (_simgui.keys_down[i]) {
|
||||
io->KeysDown[i] = true;
|
||||
_simgui_set_imgui_modifiers(io, _simgui.keys_down[i]);
|
||||
_simgui.keys_down[i] = 0;
|
||||
if (!_simgui.desc.disable_set_mouse_cursor) {
|
||||
#if defined(__cplusplus)
|
||||
ImGuiMouseCursor imgui_cursor = ImGui::GetMouseCursor();
|
||||
#else
|
||||
ImGuiMouseCursor imgui_cursor = igGetMouseCursor();
|
||||
#endif
|
||||
sapp_mouse_cursor cursor = sapp_get_mouse_cursor();
|
||||
switch (imgui_cursor) {
|
||||
case ImGuiMouseCursor_Arrow: cursor = SAPP_MOUSECURSOR_ARROW; break;
|
||||
case ImGuiMouseCursor_TextInput: cursor = SAPP_MOUSECURSOR_IBEAM; break;
|
||||
case ImGuiMouseCursor_ResizeAll: cursor = SAPP_MOUSECURSOR_RESIZE_ALL; break;
|
||||
case ImGuiMouseCursor_ResizeNS: cursor = SAPP_MOUSECURSOR_RESIZE_NS; break;
|
||||
case ImGuiMouseCursor_ResizeEW: cursor = SAPP_MOUSECURSOR_RESIZE_EW; break;
|
||||
case ImGuiMouseCursor_ResizeNESW: cursor = SAPP_MOUSECURSOR_RESIZE_NESW; break;
|
||||
case ImGuiMouseCursor_ResizeNWSE: cursor = SAPP_MOUSECURSOR_RESIZE_NWSE; break;
|
||||
case ImGuiMouseCursor_Hand: cursor = SAPP_MOUSECURSOR_POINTING_HAND; break;
|
||||
case ImGuiMouseCursor_NotAllowed: cursor = SAPP_MOUSECURSOR_NOT_ALLOWED; break;
|
||||
default: break;
|
||||
}
|
||||
sapp_set_mouse_cursor(cursor);
|
||||
}
|
||||
else if (_simgui.keys_up[i]) {
|
||||
io->KeysDown[i] = false;
|
||||
_simgui_set_imgui_modifiers(io, _simgui.keys_up[i]);
|
||||
_simgui.keys_up[i] = 0;
|
||||
}
|
||||
}
|
||||
if (io->WantTextInput && !sapp_keyboard_shown()) {
|
||||
sapp_show_keyboard(true);
|
||||
}
|
||||
if (!io->WantTextInput && sapp_keyboard_shown()) {
|
||||
sapp_show_keyboard(false);
|
||||
}
|
||||
#endif
|
||||
#if defined(__cplusplus)
|
||||
ImGui::NewFrame();
|
||||
@@ -1966,7 +2061,7 @@ SOKOL_API_IMPL void simgui_render(void) {
|
||||
}
|
||||
|
||||
/* render the ImGui command list */
|
||||
const float dpi_scale = _simgui.desc.dpi_scale;
|
||||
const float dpi_scale = _simgui.cur_dpi_scale;
|
||||
const int fb_width = (int) (io->DisplaySize.x * dpi_scale);
|
||||
const int fb_height = (int) (io->DisplaySize.y * dpi_scale);
|
||||
sg_apply_viewport(0, 0, fb_width, fb_height, true);
|
||||
@@ -1974,12 +2069,12 @@ SOKOL_API_IMPL void simgui_render(void) {
|
||||
|
||||
sg_apply_pipeline(_simgui.pip);
|
||||
_simgui_vs_params_t vs_params;
|
||||
memset((void*)&vs_params, 0, sizeof(vs_params));
|
||||
_simgui_clear((void*)&vs_params, sizeof(vs_params));
|
||||
vs_params.disp_size.x = io->DisplaySize.x;
|
||||
vs_params.disp_size.y = io->DisplaySize.y;
|
||||
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE_REF(vs_params));
|
||||
sg_bindings bind;
|
||||
memset((void*)&bind, 0, sizeof(bind));
|
||||
_simgui_clear((void*)&bind, sizeof(bind));
|
||||
bind.vertex_buffers[0] = _simgui.vbuf;
|
||||
bind.index_buffer = _simgui.ibuf;
|
||||
ImTextureID tex_id = io->Fonts->TexID;
|
||||
@@ -1993,7 +2088,6 @@ SOKOL_API_IMPL void simgui_render(void) {
|
||||
bind.index_buffer_offset = ib_offset;
|
||||
sg_apply_bindings(&bind);
|
||||
|
||||
int base_element = 0;
|
||||
#if defined(__cplusplus)
|
||||
const int num_cmds = cl->CmdBuffer.size();
|
||||
#else
|
||||
@@ -2023,13 +2117,12 @@ SOKOL_API_IMPL void simgui_render(void) {
|
||||
const int scissor_w = (int) ((pcmd->ClipRect.z - pcmd->ClipRect.x) * dpi_scale);
|
||||
const int scissor_h = (int) ((pcmd->ClipRect.w - pcmd->ClipRect.y) * dpi_scale);
|
||||
sg_apply_scissor_rect(scissor_x, scissor_y, scissor_w, scissor_h, true);
|
||||
sg_draw(base_element, (int)pcmd->ElemCount, 1);
|
||||
sg_draw((int)pcmd->IdxOffset, (int)pcmd->ElemCount, 1);
|
||||
}
|
||||
base_element += (int)pcmd->ElemCount;
|
||||
}
|
||||
#if defined(__cplusplus)
|
||||
const size_t vtx_size = cl->VtxBuffer.size() * sizeof(ImDrawVert);
|
||||
const size_t idx_size = cl->IdxBuffer.size() * sizeof(ImDrawIdx);
|
||||
const size_t vtx_size = (size_t)cl->VtxBuffer.size() * sizeof(ImDrawVert);
|
||||
const size_t idx_size = (size_t)cl->IdxBuffer.size() * sizeof(ImDrawIdx);
|
||||
#else
|
||||
const size_t vtx_size = (size_t)cl->VtxBuffer.Size * sizeof(ImDrawVert);
|
||||
const size_t idx_size = (size_t)cl->IdxBuffer.Size * sizeof(ImDrawIdx);
|
||||
@@ -2052,66 +2145,256 @@ _SOKOL_PRIVATE bool _simgui_is_ctrl(uint32_t modifiers) {
|
||||
}
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE ImGuiKey _simgui_map_keycode(sapp_keycode key) {
|
||||
switch (key) {
|
||||
case SAPP_KEYCODE_SPACE: return ImGuiKey_Space;
|
||||
case SAPP_KEYCODE_APOSTROPHE: return ImGuiKey_Apostrophe;
|
||||
case SAPP_KEYCODE_COMMA: return ImGuiKey_Comma;
|
||||
case SAPP_KEYCODE_MINUS: return ImGuiKey_Minus;
|
||||
case SAPP_KEYCODE_PERIOD: return ImGuiKey_Apostrophe;
|
||||
case SAPP_KEYCODE_SLASH: return ImGuiKey_Slash;
|
||||
case SAPP_KEYCODE_0: return ImGuiKey_0;
|
||||
case SAPP_KEYCODE_1: return ImGuiKey_1;
|
||||
case SAPP_KEYCODE_2: return ImGuiKey_2;
|
||||
case SAPP_KEYCODE_3: return ImGuiKey_3;
|
||||
case SAPP_KEYCODE_4: return ImGuiKey_4;
|
||||
case SAPP_KEYCODE_5: return ImGuiKey_5;
|
||||
case SAPP_KEYCODE_6: return ImGuiKey_6;
|
||||
case SAPP_KEYCODE_7: return ImGuiKey_7;
|
||||
case SAPP_KEYCODE_8: return ImGuiKey_8;
|
||||
case SAPP_KEYCODE_9: return ImGuiKey_9;
|
||||
case SAPP_KEYCODE_SEMICOLON: return ImGuiKey_Semicolon;
|
||||
case SAPP_KEYCODE_EQUAL: return ImGuiKey_Equal;
|
||||
case SAPP_KEYCODE_A: return ImGuiKey_A;
|
||||
case SAPP_KEYCODE_B: return ImGuiKey_B;
|
||||
case SAPP_KEYCODE_C: return ImGuiKey_C;
|
||||
case SAPP_KEYCODE_D: return ImGuiKey_D;
|
||||
case SAPP_KEYCODE_E: return ImGuiKey_E;
|
||||
case SAPP_KEYCODE_F: return ImGuiKey_F;
|
||||
case SAPP_KEYCODE_G: return ImGuiKey_G;
|
||||
case SAPP_KEYCODE_H: return ImGuiKey_H;
|
||||
case SAPP_KEYCODE_I: return ImGuiKey_I;
|
||||
case SAPP_KEYCODE_J: return ImGuiKey_J;
|
||||
case SAPP_KEYCODE_K: return ImGuiKey_K;
|
||||
case SAPP_KEYCODE_L: return ImGuiKey_L;
|
||||
case SAPP_KEYCODE_M: return ImGuiKey_M;
|
||||
case SAPP_KEYCODE_N: return ImGuiKey_N;
|
||||
case SAPP_KEYCODE_O: return ImGuiKey_O;
|
||||
case SAPP_KEYCODE_P: return ImGuiKey_P;
|
||||
case SAPP_KEYCODE_Q: return ImGuiKey_Q;
|
||||
case SAPP_KEYCODE_R: return ImGuiKey_R;
|
||||
case SAPP_KEYCODE_S: return ImGuiKey_S;
|
||||
case SAPP_KEYCODE_T: return ImGuiKey_T;
|
||||
case SAPP_KEYCODE_U: return ImGuiKey_U;
|
||||
case SAPP_KEYCODE_V: return ImGuiKey_V;
|
||||
case SAPP_KEYCODE_W: return ImGuiKey_W;
|
||||
case SAPP_KEYCODE_X: return ImGuiKey_X;
|
||||
case SAPP_KEYCODE_Y: return ImGuiKey_Y;
|
||||
case SAPP_KEYCODE_Z: return ImGuiKey_Z;
|
||||
case SAPP_KEYCODE_LEFT_BRACKET: return ImGuiKey_LeftBracket;
|
||||
case SAPP_KEYCODE_BACKSLASH: return ImGuiKey_Backslash;
|
||||
case SAPP_KEYCODE_RIGHT_BRACKET:return ImGuiKey_RightBracket;
|
||||
case SAPP_KEYCODE_GRAVE_ACCENT: return ImGuiKey_GraveAccent;
|
||||
case SAPP_KEYCODE_ESCAPE: return ImGuiKey_Escape;
|
||||
case SAPP_KEYCODE_ENTER: return ImGuiKey_Enter;
|
||||
case SAPP_KEYCODE_TAB: return ImGuiKey_Tab;
|
||||
case SAPP_KEYCODE_BACKSPACE: return ImGuiKey_Backspace;
|
||||
case SAPP_KEYCODE_INSERT: return ImGuiKey_Insert;
|
||||
case SAPP_KEYCODE_DELETE: return ImGuiKey_Delete;
|
||||
case SAPP_KEYCODE_RIGHT: return ImGuiKey_RightArrow;
|
||||
case SAPP_KEYCODE_LEFT: return ImGuiKey_LeftArrow;
|
||||
case SAPP_KEYCODE_DOWN: return ImGuiKey_DownArrow;
|
||||
case SAPP_KEYCODE_UP: return ImGuiKey_UpArrow;
|
||||
case SAPP_KEYCODE_PAGE_UP: return ImGuiKey_PageUp;
|
||||
case SAPP_KEYCODE_PAGE_DOWN: return ImGuiKey_PageDown;
|
||||
case SAPP_KEYCODE_HOME: return ImGuiKey_Home;
|
||||
case SAPP_KEYCODE_END: return ImGuiKey_End;
|
||||
case SAPP_KEYCODE_CAPS_LOCK: return ImGuiKey_CapsLock;
|
||||
case SAPP_KEYCODE_SCROLL_LOCK: return ImGuiKey_ScrollLock;
|
||||
case SAPP_KEYCODE_NUM_LOCK: return ImGuiKey_NumLock;
|
||||
case SAPP_KEYCODE_PRINT_SCREEN: return ImGuiKey_PrintScreen;
|
||||
case SAPP_KEYCODE_PAUSE: return ImGuiKey_Pause;
|
||||
case SAPP_KEYCODE_F1: return ImGuiKey_F1;
|
||||
case SAPP_KEYCODE_F2: return ImGuiKey_F2;
|
||||
case SAPP_KEYCODE_F3: return ImGuiKey_F3;
|
||||
case SAPP_KEYCODE_F4: return ImGuiKey_F4;
|
||||
case SAPP_KEYCODE_F5: return ImGuiKey_F5;
|
||||
case SAPP_KEYCODE_F6: return ImGuiKey_F6;
|
||||
case SAPP_KEYCODE_F7: return ImGuiKey_F7;
|
||||
case SAPP_KEYCODE_F8: return ImGuiKey_F8;
|
||||
case SAPP_KEYCODE_F9: return ImGuiKey_F9;
|
||||
case SAPP_KEYCODE_F10: return ImGuiKey_F10;
|
||||
case SAPP_KEYCODE_F11: return ImGuiKey_F11;
|
||||
case SAPP_KEYCODE_F12: return ImGuiKey_F12;
|
||||
case SAPP_KEYCODE_KP_0: return ImGuiKey_Keypad0;
|
||||
case SAPP_KEYCODE_KP_1: return ImGuiKey_Keypad1;
|
||||
case SAPP_KEYCODE_KP_2: return ImGuiKey_Keypad2;
|
||||
case SAPP_KEYCODE_KP_3: return ImGuiKey_Keypad3;
|
||||
case SAPP_KEYCODE_KP_4: return ImGuiKey_Keypad4;
|
||||
case SAPP_KEYCODE_KP_5: return ImGuiKey_Keypad5;
|
||||
case SAPP_KEYCODE_KP_6: return ImGuiKey_Keypad6;
|
||||
case SAPP_KEYCODE_KP_7: return ImGuiKey_Keypad7;
|
||||
case SAPP_KEYCODE_KP_8: return ImGuiKey_Keypad8;
|
||||
case SAPP_KEYCODE_KP_9: return ImGuiKey_Keypad9;
|
||||
case SAPP_KEYCODE_KP_DECIMAL: return ImGuiKey_KeypadDecimal;
|
||||
case SAPP_KEYCODE_KP_DIVIDE: return ImGuiKey_KeypadDivide;
|
||||
case SAPP_KEYCODE_KP_MULTIPLY: return ImGuiKey_KeypadMultiply;
|
||||
case SAPP_KEYCODE_KP_SUBTRACT: return ImGuiKey_KeypadSubtract;
|
||||
case SAPP_KEYCODE_KP_ADD: return ImGuiKey_KeypadAdd;
|
||||
case SAPP_KEYCODE_KP_ENTER: return ImGuiKey_KeypadEnter;
|
||||
case SAPP_KEYCODE_KP_EQUAL: return ImGuiKey_KeypadEqual;
|
||||
case SAPP_KEYCODE_LEFT_SHIFT: return ImGuiKey_LeftShift;
|
||||
case SAPP_KEYCODE_LEFT_CONTROL: return ImGuiKey_LeftCtrl;
|
||||
case SAPP_KEYCODE_LEFT_ALT: return ImGuiKey_LeftAlt;
|
||||
case SAPP_KEYCODE_LEFT_SUPER: return ImGuiKey_LeftSuper;
|
||||
case SAPP_KEYCODE_RIGHT_SHIFT: return ImGuiKey_RightShift;
|
||||
case SAPP_KEYCODE_RIGHT_CONTROL:return ImGuiKey_RightCtrl;
|
||||
case SAPP_KEYCODE_RIGHT_ALT: return ImGuiKey_RightAlt;
|
||||
case SAPP_KEYCODE_RIGHT_SUPER: return ImGuiKey_RightSuper;
|
||||
case SAPP_KEYCODE_MENU: return ImGuiKey_Menu;
|
||||
default: return ImGuiKey_None;
|
||||
}
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _simgui_add_focus_event(ImGuiIO* io, bool focus) {
|
||||
#if defined(__cplusplus)
|
||||
io->AddFocusEvent(focus);
|
||||
#else
|
||||
ImGuiIO_AddFocusEvent(io, focus);
|
||||
#endif
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _simgui_add_mouse_pos_event(ImGuiIO* io, float x, float y) {
|
||||
#if defined(__cplusplus)
|
||||
io->AddMousePosEvent(x, y);
|
||||
#else
|
||||
ImGuiIO_AddMousePosEvent(io, x, y);
|
||||
#endif
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _simgui_add_mouse_button_event(ImGuiIO* io, int mouse_button, bool down) {
|
||||
#if defined(__cplusplus)
|
||||
io->AddMouseButtonEvent(mouse_button, down);
|
||||
#else
|
||||
ImGuiIO_AddMouseButtonEvent(io, mouse_button, down);
|
||||
#endif
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _simgui_add_mouse_wheel_event(ImGuiIO* io, float wheel_x, float wheel_y) {
|
||||
#if defined(__cplusplus)
|
||||
io->AddMouseWheelEvent(wheel_x, wheel_y);
|
||||
#else
|
||||
ImGuiIO_AddMouseWheelEvent(io, wheel_x, wheel_y);
|
||||
#endif
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _simgui_add_sapp_key_event(ImGuiIO* io, sapp_keycode sapp_key, bool down) {
|
||||
const ImGuiKey imgui_key = _simgui_map_keycode(sapp_key);
|
||||
#if defined(__cplusplus)
|
||||
io->AddKeyEvent(imgui_key, down);
|
||||
io->SetKeyEventNativeData(imgui_key, (int)sapp_key, 0, -1);
|
||||
#else
|
||||
ImGuiIO_AddKeyEvent(io, imgui_key, down);
|
||||
ImGuiIO_SetKeyEventNativeData(io, imgui_key, (int)sapp_key, 0, -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _simgui_add_imgui_key_event(ImGuiIO* io, ImGuiKey imgui_key, bool down) {
|
||||
#if defined(__cplusplus)
|
||||
io->AddKeyEvent(imgui_key, down);
|
||||
#else
|
||||
ImGuiIO_AddKeyEvent(io, imgui_key, down);
|
||||
#endif
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _simgui_add_input_character(ImGuiIO* io, uint32_t c) {
|
||||
#if defined(__cplusplus)
|
||||
io->AddInputCharacter(c);
|
||||
#else
|
||||
ImGuiIO_AddInputCharacter(io, c);
|
||||
#endif
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _simgui_update_modifiers(ImGuiIO* io, uint32_t mods) {
|
||||
_simgui_add_imgui_key_event(io, ImGuiMod_Ctrl, (mods & SAPP_MODIFIER_CTRL) != 0);
|
||||
_simgui_add_imgui_key_event(io, ImGuiMod_Shift, (mods & SAPP_MODIFIER_SHIFT) != 0);
|
||||
_simgui_add_imgui_key_event(io, ImGuiMod_Alt, (mods & SAPP_MODIFIER_ALT) != 0);
|
||||
_simgui_add_imgui_key_event(io, ImGuiMod_Super, (mods & SAPP_MODIFIER_SUPER) != 0);
|
||||
}
|
||||
|
||||
// returns Ctrl or Super, depending on platform
|
||||
_SOKOL_PRIVATE ImGuiKey _simgui_copypaste_modifier(void) {
|
||||
return _simgui.is_osx ? ImGuiMod_Super : ImGuiMod_Ctrl;
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL int simgui_map_keycode(sapp_keycode keycode) {
|
||||
return (int)_simgui_map_keycode(keycode);
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL bool simgui_handle_event(const sapp_event* ev) {
|
||||
const float dpi_scale = _simgui.desc.dpi_scale;
|
||||
const float dpi_scale = _simgui.cur_dpi_scale;
|
||||
#if defined(__cplusplus)
|
||||
ImGuiIO* io = &ImGui::GetIO();
|
||||
#else
|
||||
ImGuiIO* io = igGetIO();
|
||||
#endif
|
||||
_simgui_set_imgui_modifiers(io, ev->modifiers);
|
||||
switch (ev->type) {
|
||||
case SAPP_EVENTTYPE_FOCUSED:
|
||||
_simgui_add_focus_event(io, true);
|
||||
break;
|
||||
case SAPP_EVENTTYPE_UNFOCUSED:
|
||||
_simgui_add_focus_event(io, false);
|
||||
break;
|
||||
case SAPP_EVENTTYPE_MOUSE_DOWN:
|
||||
io->MousePos.x = ev->mouse_x / dpi_scale;
|
||||
io->MousePos.y = ev->mouse_y / dpi_scale;
|
||||
if (ev->mouse_button < 3) {
|
||||
_simgui.btn_down[ev->mouse_button] = true;
|
||||
}
|
||||
_simgui_add_mouse_pos_event(io, ev->mouse_x / dpi_scale, ev->mouse_y / dpi_scale);
|
||||
_simgui_add_mouse_button_event(io, (int)ev->mouse_button, true);
|
||||
_simgui_update_modifiers(io, ev->modifiers);
|
||||
break;
|
||||
case SAPP_EVENTTYPE_MOUSE_UP:
|
||||
io->MousePos.x = ev->mouse_x / dpi_scale;
|
||||
io->MousePos.y = ev->mouse_y / dpi_scale;
|
||||
if (ev->mouse_button < 3) {
|
||||
_simgui.btn_up[ev->mouse_button] = true;
|
||||
}
|
||||
_simgui_add_mouse_pos_event(io, ev->mouse_x / dpi_scale, ev->mouse_y / dpi_scale);
|
||||
_simgui_add_mouse_button_event(io, (int)ev->mouse_button, false);
|
||||
_simgui_update_modifiers(io, ev->modifiers);
|
||||
break;
|
||||
case SAPP_EVENTTYPE_MOUSE_MOVE:
|
||||
io->MousePos.x = ev->mouse_x / dpi_scale;
|
||||
io->MousePos.y = ev->mouse_y / dpi_scale;
|
||||
_simgui_add_mouse_pos_event(io, ev->mouse_x / dpi_scale, ev->mouse_y / dpi_scale);
|
||||
break;
|
||||
case SAPP_EVENTTYPE_MOUSE_ENTER:
|
||||
case SAPP_EVENTTYPE_MOUSE_LEAVE:
|
||||
for (int i = 0; i < 3; i++) {
|
||||
_simgui.btn_down[i] = false;
|
||||
_simgui.btn_up[i] = false;
|
||||
io->MouseDown[i] = false;
|
||||
// FIXME: since the sokol_app.h emscripten backend doesn't support
|
||||
// mouse capture, mouse buttons must be released when the mouse leaves the
|
||||
// browser window, so that they don't "stick" when released outside the window.
|
||||
// A cleaner solution would be a new sokol_app.h function to query
|
||||
// "platform behaviour flags".
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
for (int i = 0; i < SAPP_MAX_MOUSEBUTTONS; i++) {
|
||||
_simgui_add_mouse_button_event(io, i, false);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case SAPP_EVENTTYPE_MOUSE_SCROLL:
|
||||
io->MouseWheelH = ev->scroll_x;
|
||||
io->MouseWheel = ev->scroll_y;
|
||||
_simgui_add_mouse_wheel_event(io, ev->scroll_x, ev->scroll_y);
|
||||
break;
|
||||
case SAPP_EVENTTYPE_TOUCHES_BEGAN:
|
||||
_simgui.btn_down[0] = true;
|
||||
io->MousePos.x = ev->touches[0].pos_x / dpi_scale;
|
||||
io->MousePos.y = ev->touches[0].pos_y / dpi_scale;
|
||||
_simgui_add_mouse_pos_event(io, ev->touches[0].pos_x / dpi_scale, ev->touches[0].pos_y / dpi_scale);
|
||||
_simgui_add_mouse_button_event(io, 0, true);
|
||||
break;
|
||||
case SAPP_EVENTTYPE_TOUCHES_MOVED:
|
||||
io->MousePos.x = ev->touches[0].pos_x / dpi_scale;
|
||||
io->MousePos.y = ev->touches[0].pos_y / dpi_scale;
|
||||
_simgui_add_mouse_pos_event(io, ev->touches[0].pos_x / dpi_scale, ev->touches[0].pos_y / dpi_scale);
|
||||
break;
|
||||
case SAPP_EVENTTYPE_TOUCHES_ENDED:
|
||||
_simgui.btn_up[0] = true;
|
||||
io->MousePos.x = ev->touches[0].pos_x / dpi_scale;
|
||||
io->MousePos.y = ev->touches[0].pos_y / dpi_scale;
|
||||
_simgui_add_mouse_pos_event(io, ev->touches[0].pos_x / dpi_scale, ev->touches[0].pos_y / dpi_scale);
|
||||
_simgui_add_mouse_button_event(io, 0, false);
|
||||
break;
|
||||
case SAPP_EVENTTYPE_TOUCHES_CANCELLED:
|
||||
_simgui.btn_up[0] = _simgui.btn_down[0] = false;
|
||||
_simgui_add_mouse_button_event(io, 0, false);
|
||||
break;
|
||||
case SAPP_EVENTTYPE_KEY_DOWN:
|
||||
_simgui_update_modifiers(io, ev->modifiers);
|
||||
/* intercept Ctrl-V, this is handled via EVENTTYPE_CLIPBOARD_PASTED */
|
||||
if (_simgui_is_ctrl(ev->modifiers) && (ev->key_code == SAPP_KEYCODE_V)) {
|
||||
break;
|
||||
if (!_simgui.desc.disable_paste_override) {
|
||||
if (_simgui_is_ctrl(ev->modifiers) && (ev->key_code == SAPP_KEYCODE_V)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* on web platform, don't forward Ctrl-X, Ctrl-V to the browser */
|
||||
if (_simgui_is_ctrl(ev->modifiers) && (ev->key_code == SAPP_KEYCODE_X)) {
|
||||
@@ -2120,9 +2403,11 @@ SOKOL_API_IMPL bool simgui_handle_event(const sapp_event* ev) {
|
||||
if (_simgui_is_ctrl(ev->modifiers) && (ev->key_code == SAPP_KEYCODE_C)) {
|
||||
sapp_consume_event();
|
||||
}
|
||||
_simgui.keys_down[ev->key_code] = 0x80 | (uint8_t)ev->modifiers;
|
||||
// it's ok to add ImGuiKey_None key events
|
||||
_simgui_add_sapp_key_event(io, ev->key_code, true);
|
||||
break;
|
||||
case SAPP_EVENTTYPE_KEY_UP:
|
||||
_simgui_update_modifiers(io, ev->modifiers);
|
||||
/* intercept Ctrl-V, this is handled via EVENTTYPE_CLIPBOARD_PASTED */
|
||||
if (_simgui_is_ctrl(ev->modifiers) && (ev->key_code == SAPP_KEYCODE_V)) {
|
||||
break;
|
||||
@@ -2134,7 +2419,8 @@ SOKOL_API_IMPL bool simgui_handle_event(const sapp_event* ev) {
|
||||
if (_simgui_is_ctrl(ev->modifiers) && (ev->key_code == SAPP_KEYCODE_C)) {
|
||||
sapp_consume_event();
|
||||
}
|
||||
_simgui.keys_up[ev->key_code] = 0x80 | (uint8_t)ev->modifiers;
|
||||
// it's ok to add ImGuiKey_None key events
|
||||
_simgui_add_sapp_key_event(io, ev->key_code, false);
|
||||
break;
|
||||
case SAPP_EVENTTYPE_CHAR:
|
||||
/* on some platforms, special keys may be reported as
|
||||
@@ -2142,27 +2428,28 @@ SOKOL_API_IMPL bool simgui_handle_event(const sapp_event* ev) {
|
||||
drop those, also don't forward characters if some
|
||||
modifiers have been pressed
|
||||
*/
|
||||
_simgui_update_modifiers(io, ev->modifiers);
|
||||
if ((ev->char_code >= 32) &&
|
||||
(ev->char_code != 127) &&
|
||||
(0 == (ev->modifiers & (SAPP_MODIFIER_ALT|SAPP_MODIFIER_CTRL|SAPP_MODIFIER_SUPER))))
|
||||
{
|
||||
#if defined(__cplusplus)
|
||||
io->AddInputCharacter((ImWchar)ev->char_code);
|
||||
#else
|
||||
ImGuiIO_AddInputCharacter(io, (ImWchar)ev->char_code);
|
||||
#endif
|
||||
_simgui_add_input_character(io, ev->char_code);
|
||||
}
|
||||
break;
|
||||
case SAPP_EVENTTYPE_CLIPBOARD_PASTED:
|
||||
/* simulate a Ctrl-V key down/up */
|
||||
_simgui.keys_down[SAPP_KEYCODE_V] = _simgui.keys_up[SAPP_KEYCODE_V] =
|
||||
(uint8_t) (0x80 | (_simgui.is_osx ? SAPP_MODIFIER_SUPER:SAPP_MODIFIER_CTRL));
|
||||
if (!_simgui.desc.disable_paste_override) {
|
||||
_simgui_add_imgui_key_event(io, _simgui_copypaste_modifier(), true);
|
||||
_simgui_add_imgui_key_event(io, ImGuiKey_V, true);
|
||||
_simgui_add_imgui_key_event(io, ImGuiKey_V, false);
|
||||
_simgui_add_imgui_key_event(io, _simgui_copypaste_modifier(), false);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return io->WantCaptureKeyboard || io->WantCaptureMouse;
|
||||
}
|
||||
#endif
|
||||
#endif // SOKOL_IMGUI_NO_SOKOL_APP
|
||||
|
||||
#endif /* SOKOL_IMPL */
|
||||
#endif // SOKOL_IMPL
|
||||
|
||||
Vendored
+48
-52
@@ -8,15 +8,6 @@
|
||||
|
||||
Project URL: https://github.com/floooh/sokol
|
||||
|
||||
Simply include this file before the sokol header implementation includes
|
||||
and after the SOKOL_IMPL macro:
|
||||
|
||||
#define SOKOL_IMPL
|
||||
#include "sokol_memtrack.h"
|
||||
#include "sokol_app.h"
|
||||
#include "sokol_gfx.h"
|
||||
...
|
||||
|
||||
Optionally provide the following defines with your own implementations:
|
||||
|
||||
SOKOL_MEMTRACK_API_DECL - public function declaration prefix (default: extern)
|
||||
@@ -28,24 +19,29 @@
|
||||
|
||||
SOKOL_DLL
|
||||
|
||||
The sokol_memtrack.h header will redirect the macros SOKOL_MALLOC,
|
||||
SOKOL_FREE and SOKOL_CALLOC to use its own function wrappers which
|
||||
keep track of number and size of allocations. The wrapper functions
|
||||
then call the CRT functions malloc(), calloc() or free().
|
||||
USAGE
|
||||
=====
|
||||
Just plug the malloc/free wrapper functions into the desc.allocator
|
||||
struct provided by most sokol header setup functions:
|
||||
|
||||
Naturally, only the memory management calls in sokol header code are tracked,
|
||||
not in underlying APIs such as D3D11 or OpenGL.
|
||||
sg_setup(&(sg_desc){
|
||||
//...
|
||||
.allocator = {
|
||||
.alloc = smemtrack_alloc,
|
||||
.free = smemtrack_free,
|
||||
}
|
||||
});
|
||||
|
||||
To get the current number and overall size of allocations, call:
|
||||
Then call smemtrack_info() to get information about current number
|
||||
of allocations and overall allocation size:
|
||||
|
||||
smemtrack_info_t alloc_info = smemtrack_info();
|
||||
const smemtrack_info_t info = smemtrack_info();
|
||||
const int num_allocs = info.num_allocs;
|
||||
const int num_bytes = info.num_bytes;
|
||||
|
||||
int num_allocations = info.num_alloc;
|
||||
int allocation_size = info.num_bytes;
|
||||
|
||||
The allocation wrapper functions are *not* thread-safe (which shouldn't
|
||||
be a problem because the sokol headers don't allocate or deallocate
|
||||
in threads).
|
||||
Note the sokol_memtrack.h can only track allocations issued by
|
||||
the sokol headers, not allocations that happen under the hood
|
||||
in system libraries.
|
||||
|
||||
LICENSE
|
||||
=======
|
||||
@@ -75,6 +71,7 @@
|
||||
*/
|
||||
#define SOKOL_MEMTRACK_INCLUDED (1)
|
||||
#include <stdint.h>
|
||||
#include <stddef.h> // size_t
|
||||
|
||||
#if defined(SOKOL_API_DECL) && !defined(SOKOL_MEMTRACK_API_DECL)
|
||||
#define SOKOL_MEMTRACK_API_DECL SOKOL_API_DECL
|
||||
@@ -99,6 +96,8 @@ typedef struct smemtrack_info_t {
|
||||
} smemtrack_info_t;
|
||||
|
||||
SOKOL_MEMTRACK_API_DECL smemtrack_info_t smemtrack_info(void);
|
||||
SOKOL_MEMTRACK_API_DECL void* smemtrack_alloc(size_t size, void* user_data);
|
||||
SOKOL_MEMTRACK_API_DECL void smemtrack_free(void* ptr, void* user_data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
@@ -108,16 +107,15 @@ SOKOL_MEMTRACK_API_DECL smemtrack_info_t smemtrack_info(void);
|
||||
/*=== IMPLEMENTATION =========================================================*/
|
||||
#ifdef SOKOL_MEMTRACK_IMPL
|
||||
#define SOKOL_MEMTRACK_IMPL_INCLUDED (1)
|
||||
#include <stdlib.h> /* malloc, free, calloc */
|
||||
#include <string.h> /* memset */
|
||||
#include <stddef.h> /* size_t */
|
||||
#include <stdlib.h> // malloc, free
|
||||
#include <string.h> // memset
|
||||
|
||||
#ifndef SOKOL_API_IMPL
|
||||
#define SOKOL_API_IMPL
|
||||
#endif
|
||||
#ifndef SOKOL_DEBUG
|
||||
#ifndef NDEBUG
|
||||
#define SOKOL_DEBUG (1)
|
||||
#define SOKOL_DEBUG
|
||||
#endif
|
||||
#endif
|
||||
#ifndef _SOKOL_PRIVATE
|
||||
@@ -128,40 +126,38 @@ SOKOL_MEMTRACK_API_DECL smemtrack_info_t smemtrack_info(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define SOKOL_MALLOC(s) _smemtrack_malloc(s)
|
||||
#define SOKOL_FREE(p) _smemtrack_free(p)
|
||||
#define SOKOL_CALLOC(n,s) _smemtrack_calloc(n,s)
|
||||
|
||||
// per-allocation header used to keep track of the allocation size
|
||||
#define _SMEMTRACK_HEADER_SIZE (16)
|
||||
|
||||
static struct {
|
||||
smemtrack_info_t state;
|
||||
} _smemtrack;
|
||||
|
||||
_SOKOL_PRIVATE void* _smemtrack_malloc(size_t size) {
|
||||
_smemtrack.state.num_allocs++;
|
||||
_smemtrack.state.num_bytes += (int) size;
|
||||
SOKOL_API_IMPL void* smemtrack_alloc(size_t size, void* user_data) {
|
||||
(void)user_data;
|
||||
uint8_t* ptr = (uint8_t*) malloc(size + _SMEMTRACK_HEADER_SIZE);
|
||||
*(size_t*)ptr = size;
|
||||
return ptr + _SMEMTRACK_HEADER_SIZE;
|
||||
if (ptr) {
|
||||
// store allocation size (for allocation size tracking)
|
||||
*(size_t*)ptr = size;
|
||||
_smemtrack.state.num_allocs++;
|
||||
_smemtrack.state.num_bytes += (int) size;
|
||||
return ptr + _SMEMTRACK_HEADER_SIZE;
|
||||
}
|
||||
else {
|
||||
// allocation failed, return null pointer
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void _smemtrack_free(void* ptr) {
|
||||
uint8_t* alloc_ptr = ((uint8_t*)ptr) - _SMEMTRACK_HEADER_SIZE;
|
||||
size_t size = *(size_t*)alloc_ptr;
|
||||
_smemtrack.state.num_allocs--;
|
||||
_smemtrack.state.num_bytes -= (int) size;
|
||||
free(alloc_ptr);
|
||||
}
|
||||
|
||||
_SOKOL_PRIVATE void* _smemtrack_calloc(size_t num, size_t size) {
|
||||
size_t mem_size = num * size;
|
||||
_smemtrack.state.num_allocs++;
|
||||
_smemtrack.state.num_bytes += (int) mem_size;
|
||||
uint8_t* ptr = (uint8_t*) malloc(mem_size + _SMEMTRACK_HEADER_SIZE);
|
||||
memset(ptr + _SMEMTRACK_HEADER_SIZE, 0, mem_size);
|
||||
*(size_t*)ptr = size;
|
||||
return ptr + _SMEMTRACK_HEADER_SIZE;
|
||||
SOKOL_API_IMPL void smemtrack_free(void* ptr, void* user_data) {
|
||||
(void)user_data;
|
||||
if (ptr) {
|
||||
uint8_t* alloc_ptr = ((uint8_t*)ptr) - _SMEMTRACK_HEADER_SIZE;
|
||||
size_t size = *(size_t*)alloc_ptr;
|
||||
_smemtrack.state.num_allocs--;
|
||||
_smemtrack.state.num_bytes -= (int) size;
|
||||
free(alloc_ptr);
|
||||
}
|
||||
}
|
||||
|
||||
SOKOL_API_IMPL smemtrack_info_t smemtrack_info(void) {
|
||||
|
||||
Vendored
+9
-2
@@ -267,7 +267,7 @@ inline void snk_setup(const snk_desc_t& desc) { return snk_setup(&desc); }
|
||||
#endif
|
||||
#ifndef SOKOL_DEBUG
|
||||
#ifndef NDEBUG
|
||||
#define SOKOL_DEBUG (1)
|
||||
#define SOKOL_DEBUG
|
||||
#endif
|
||||
#endif
|
||||
#ifndef SOKOL_ASSERT
|
||||
@@ -1941,8 +1941,15 @@ SOKOL_API_IMPL void snk_render(int width, int height) {
|
||||
int idx_offset = 0;
|
||||
nk_draw_foreach(cmd, &_snuklear.ctx, &cmds) {
|
||||
if (cmd->elem_count > 0) {
|
||||
sg_image img;
|
||||
if (cmd->texture.id != 0) {
|
||||
img = (sg_image){ .id = (uint32_t) cmd->texture.id };
|
||||
}
|
||||
else {
|
||||
img = _snuklear.img;
|
||||
}
|
||||
sg_apply_bindings(&(sg_bindings){
|
||||
.fs_images[0] = _snuklear.img,
|
||||
.fs_images[0] = img,
|
||||
.vertex_buffers[0] = _snuklear.vbuf,
|
||||
.index_buffer = _snuklear.ibuf,
|
||||
.vertex_buffer_offsets[0] = 0,
|
||||
|
||||
Vendored
+5
-6
@@ -556,7 +556,6 @@ SOKOL_SHAPE_API_DECL sshape_mat4_t sshape_mat4_transpose(const float m[16]);
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wmissing-field-initializers"
|
||||
#pragma clang diagnostic ignored "-Wmissing-braces"
|
||||
#endif
|
||||
|
||||
#ifndef SOKOL_API_IMPL
|
||||
@@ -857,7 +856,7 @@ SOKOL_API_IMPL sshape_mat4_t sshape_mat4_transpose(const float m[16]) {
|
||||
|
||||
SOKOL_API_IMPL sshape_sizes_t sshape_plane_sizes(uint32_t tiles) {
|
||||
SOKOL_ASSERT(tiles >= 1);
|
||||
sshape_sizes_t res = { 0 };
|
||||
sshape_sizes_t res = { {0} };
|
||||
res.vertices.num = _sshape_plane_num_vertices(tiles);
|
||||
res.indices.num = _sshape_plane_num_indices(tiles);
|
||||
res.vertices.size = res.vertices.num * sizeof(sshape_vertex_t);
|
||||
@@ -867,7 +866,7 @@ SOKOL_API_IMPL sshape_sizes_t sshape_plane_sizes(uint32_t tiles) {
|
||||
|
||||
SOKOL_API_IMPL sshape_sizes_t sshape_box_sizes(uint32_t tiles) {
|
||||
SOKOL_ASSERT(tiles >= 1);
|
||||
sshape_sizes_t res = { 0 };
|
||||
sshape_sizes_t res = { {0} };
|
||||
res.vertices.num = _sshape_box_num_vertices(tiles);
|
||||
res.indices.num = _sshape_box_num_indices(tiles);
|
||||
res.vertices.size = res.vertices.num * sizeof(sshape_vertex_t);
|
||||
@@ -877,7 +876,7 @@ SOKOL_API_IMPL sshape_sizes_t sshape_box_sizes(uint32_t tiles) {
|
||||
|
||||
SOKOL_API_IMPL sshape_sizes_t sshape_sphere_sizes(uint32_t slices, uint32_t stacks) {
|
||||
SOKOL_ASSERT((slices >= 3) && (stacks >= 2));
|
||||
sshape_sizes_t res = { 0 };
|
||||
sshape_sizes_t res = { {0} };
|
||||
res.vertices.num = _sshape_sphere_num_vertices(slices, stacks);
|
||||
res.indices.num = _sshape_sphere_num_indices(slices, stacks);
|
||||
res.vertices.size = res.vertices.num * sizeof(sshape_vertex_t);
|
||||
@@ -887,7 +886,7 @@ SOKOL_API_IMPL sshape_sizes_t sshape_sphere_sizes(uint32_t slices, uint32_t stac
|
||||
|
||||
SOKOL_API_IMPL sshape_sizes_t sshape_cylinder_sizes(uint32_t slices, uint32_t stacks) {
|
||||
SOKOL_ASSERT((slices >= 3) && (stacks >= 1));
|
||||
sshape_sizes_t res = { 0 };
|
||||
sshape_sizes_t res = { {0} };
|
||||
res.vertices.num = _sshape_cylinder_num_vertices(slices, stacks);
|
||||
res.indices.num = _sshape_cylinder_num_indices(slices, stacks);
|
||||
res.vertices.size = res.vertices.num * sizeof(sshape_vertex_t);
|
||||
@@ -897,7 +896,7 @@ SOKOL_API_IMPL sshape_sizes_t sshape_cylinder_sizes(uint32_t slices, uint32_t st
|
||||
|
||||
SOKOL_API_IMPL sshape_sizes_t sshape_torus_sizes(uint32_t sides, uint32_t rings) {
|
||||
SOKOL_ASSERT((sides >= 3) && (rings >= 3));
|
||||
sshape_sizes_t res = { 0 };
|
||||
sshape_sizes_t res = { {0} };
|
||||
res.vertices.num = _sshape_torus_num_vertices(sides, rings);
|
||||
res.indices.num = _sshape_torus_num_indices(sides, rings);
|
||||
res.vertices.size = res.vertices.num * sizeof(sshape_vertex_t);
|
||||
|
||||
Reference in New Issue
Block a user