imgui-bindings 0.1.16 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,259 @@
1
+ require 'ffi'
2
+ require 'sdl3'
3
+ require_relative 'imgui'
4
+
5
+ module ImGui
6
+
7
+ class ImGui_ImplDockingSDLRenderer3_Data < FFI::Struct
8
+ layout(
9
+ :Renderer, :pointer
10
+ )
11
+ end
12
+
13
+ class ImGui_ImplDockingSDLRenderer3_RenderState < FFI::Struct
14
+ layout(
15
+ :Renderer, :pointer
16
+ )
17
+ end
18
+
19
+ @@g_DockingSDL3BackendRendererName = FFI::MemoryPointer.from_string('imgui_impl_docking_sdlrenderer3')
20
+ @@g_DockingSDL3BackendRendererUserData = {}
21
+
22
+ def self.ImGui_ImplDockingSDLRenderer3_GetBackendData
23
+ return nil if ImGui::GetCurrentContext() == nil
24
+
25
+ @@g_DockingSDL3BackendRendererUserData[ImGui::GetCurrentContext().address]
26
+ end
27
+
28
+ def self.ImplDockingSDL3Renderer_Init(renderer)
29
+ io = ImGuiIO.new(ImGui::GetIO())
30
+
31
+ backend_data = {
32
+ bd: ImGui_ImplDockingSDLRenderer3_Data.new,
33
+ color_buffer: nil,
34
+ color_buffer_capacity: 0,
35
+ render_state: nil
36
+ }
37
+ backend_data[:bd][:Renderer] = renderer
38
+
39
+ @@g_DockingSDL3BackendRendererUserData[ImGui::GetCurrentContext().address] = backend_data
40
+
41
+ io[:BackendRendererUserData] = backend_data[:bd]
42
+ io[:BackendRendererName] = @@g_DockingSDL3BackendRendererName
43
+ io[:BackendFlags] |= ImGuiBackendFlags_RendererHasVtxOffset
44
+ io[:BackendFlags] |= ImGuiBackendFlags_RendererHasTextures
45
+ true
46
+ end
47
+
48
+ def self.ImplDockingSDL3Renderer_Shutdown
49
+ io = ImGuiIO.new(ImGui::GetIO())
50
+ platform_io = ImGuiPlatformIO.new(ImGui::GetPlatformIO())
51
+
52
+ ImplDockingSDL3Renderer_DestroyDeviceObjects
53
+
54
+ if ImGui::GetCurrentContext() != nil
55
+ @@g_DockingSDL3BackendRendererUserData.delete(ImGui::GetCurrentContext().address)
56
+ end
57
+
58
+ io[:BackendRendererName] = nil
59
+ io[:BackendRendererUserData] = nil
60
+ io[:BackendFlags] &= ~(ImGuiBackendFlags_RendererHasVtxOffset | ImGuiBackendFlags_RendererHasTextures)
61
+ platform_io.ClearRendererHandlers
62
+ end
63
+
64
+ def self.ImplDockingSDL3Renderer_SetupRenderState(renderer)
65
+ SDL.SetRenderViewport(renderer, nil)
66
+ SDL.SetRenderClipRect(renderer, nil)
67
+ end
68
+
69
+ def self.ImplDockingSDL3Renderer_NewFrame
70
+ backend_data = ImGui_ImplDockingSDLRenderer3_GetBackendData
71
+ raise 'Context or backend not initialized! Did you call ImGui::ImplDockingSDL3Renderer_Init()?' if backend_data == nil
72
+ end
73
+
74
+ def self.ImplDockingSDL3Renderer_EnsureColorBuffer(backend_data, num_vertices)
75
+ if backend_data[:color_buffer] == nil || backend_data[:color_buffer_capacity] < num_vertices
76
+ backend_data[:color_buffer] = FFI::MemoryPointer.new(SDL::FColor, num_vertices)
77
+ backend_data[:color_buffer_capacity] = num_vertices
78
+ end
79
+ backend_data[:color_buffer]
80
+ end
81
+
82
+ def self.ImplDockingSDL3Renderer_UpdateColorBuffer(backend_data, color_src, color_stride, num_vertices)
83
+ color_dst = ImplDockingSDL3Renderer_EnsureColorBuffer(backend_data, num_vertices)
84
+ num_vertices.times do |i|
85
+ packed = (color_src + i * color_stride).read_uint
86
+ color = SDL::FColor.new(color_dst + i * SDL::FColor.size)
87
+ color[:r] = ((packed >> 0) & 0xff) / 255.0
88
+ color[:g] = ((packed >> 8) & 0xff) / 255.0
89
+ color[:b] = ((packed >> 16) & 0xff) / 255.0
90
+ color[:a] = ((packed >> 24) & 0xff) / 255.0
91
+ end
92
+ color_dst
93
+ end
94
+
95
+ def self.ImplDockingSDL3Renderer_UpdateTexture(tex_raw)
96
+ backend_data = ImGui_ImplDockingSDLRenderer3_GetBackendData
97
+ return if backend_data == nil
98
+
99
+ tex = tex_raw.kind_of?(ImTextureData) ? tex_raw : ImTextureData.new(tex_raw)
100
+
101
+ case tex[:Status]
102
+ when ImTextureStatus_WantCreate
103
+ return if tex[:Format] != ImTextureFormat_RGBA32
104
+
105
+ sdl_texture = SDL.CreateTexture(backend_data[:bd][:Renderer], SDL::PIXELFORMAT_RGBA32, SDL::TEXTUREACCESS_STATIC, tex[:Width], tex[:Height])
106
+ raise 'Backend failed to create SDL texture!' if sdl_texture == nil
107
+
108
+ SDL.UpdateTexture(sdl_texture, nil, tex.GetPixels, tex.GetPitch)
109
+ SDL.SetTextureBlendMode(sdl_texture, SDL::BLENDMODE_BLEND)
110
+ SDL.SetTextureScaleMode(sdl_texture, SDL::SCALEMODE_LINEAR)
111
+ tex[:BackendUserData] = sdl_texture
112
+ tex.SetTexID(sdl_texture.address)
113
+ tex.SetStatus(ImTextureStatus_OK)
114
+
115
+ when ImTextureStatus_WantUpdates
116
+ sdl_texture = tex[:BackendUserData]
117
+ return if sdl_texture == nil || sdl_texture.address == 0
118
+
119
+ updates = tex[:Updates]
120
+ updates[:Size].times do |i|
121
+ rect = ImTextureRect.new(updates[:Data] + ImTextureRect.size * i)
122
+ sdl_rect = SDL::Rect.new
123
+ sdl_rect[:x] = rect[:x]
124
+ sdl_rect[:y] = rect[:y]
125
+ sdl_rect[:w] = rect[:w]
126
+ sdl_rect[:h] = rect[:h]
127
+ SDL.UpdateTexture(sdl_texture, sdl_rect, tex.GetPixelsAt(rect[:x], rect[:y]), tex.GetPitch)
128
+ end
129
+ tex.SetStatus(ImTextureStatus_OK)
130
+
131
+ when ImTextureStatus_WantDestroy
132
+ sdl_texture = tex[:BackendUserData]
133
+ SDL.DestroyTexture(sdl_texture) if sdl_texture != nil && sdl_texture.address != 0
134
+ tex[:BackendUserData] = nil
135
+ tex.SetTexID(0)
136
+ tex.SetStatus(ImTextureStatus_Destroyed)
137
+ end
138
+ end
139
+
140
+ def self.ImplDockingSDL3Renderer_RenderDrawData(draw_data_raw, renderer = nil)
141
+ draw_data = draw_data_raw.kind_of?(ImDrawData) ? draw_data_raw : ImDrawData.new(draw_data_raw)
142
+ backend_data = ImGui_ImplDockingSDLRenderer3_GetBackendData
143
+ return if backend_data == nil
144
+
145
+ renderer = backend_data[:bd][:Renderer] if renderer == nil
146
+ return if renderer == nil
147
+
148
+ rsx = FFI::MemoryPointer.new(:float)
149
+ rsy = FFI::MemoryPointer.new(:float)
150
+ SDL.GetRenderScale(renderer, rsx, rsy)
151
+ render_scale = ImVec2.create(0.0, 0.0)
152
+ render_scale[:x] = rsx.read_float == 1.0 ? draw_data[:FramebufferScale][:x] : 1.0
153
+ render_scale[:y] = rsy.read_float == 1.0 ? draw_data[:FramebufferScale][:y] : 1.0
154
+
155
+ fb_width = (draw_data[:DisplaySize][:x] * render_scale[:x]).to_i
156
+ fb_height = (draw_data[:DisplaySize][:y] * render_scale[:y]).to_i
157
+ return if fb_width == 0 || fb_height == 0
158
+
159
+ if draw_data[:Textures] != nil && draw_data[:Textures].address != 0
160
+ textures = ImVector_ImTextureDataPtr.new(draw_data[:Textures])
161
+ textures[:Size].times do |i|
162
+ tex_ptr = (textures[:Data] + FFI.type_size(:pointer) * i).read_pointer
163
+ next if tex_ptr == nil || tex_ptr.address == 0
164
+
165
+ tex = ImTextureData.new(tex_ptr)
166
+ ImplDockingSDL3Renderer_UpdateTexture(tex) if tex[:Status] != ImTextureStatus_OK
167
+ end
168
+ end
169
+
170
+ old_viewport_enabled = SDL.RenderViewportSet(renderer)
171
+ old_clip_enabled = SDL.RenderClipEnabled(renderer)
172
+ old_viewport = SDL::Rect.new
173
+ old_clip_rect = SDL::Rect.new
174
+ SDL.GetRenderViewport(renderer, old_viewport)
175
+ SDL.GetRenderClipRect(renderer, old_clip_rect)
176
+
177
+ ImplDockingSDL3Renderer_SetupRenderState(renderer)
178
+
179
+ platform_io = ImGuiPlatformIO.new(ImGui::GetPlatformIO())
180
+ backend_data[:render_state] = ImGui_ImplDockingSDLRenderer3_RenderState.new
181
+ backend_data[:render_state][:Renderer] = renderer
182
+ platform_io[:Renderer_RenderState] = backend_data[:render_state]
183
+
184
+ clip_off = draw_data[:DisplayPos]
185
+ clip_scale = render_scale
186
+
187
+ draw_data[:CmdListsCount].times do |n|
188
+ cmd_list = ImDrawList.new((draw_data[:CmdLists][:Data] + FFI.type_size(:pointer) * n).read_pointer)
189
+ vtx_buffer = cmd_list[:VtxBuffer][:Data]
190
+ idx_buffer = cmd_list[:IdxBuffer][:Data]
191
+
192
+ cmd_list[:CmdBuffer][:Size].times do |cmd_i|
193
+ pcmd = ImDrawCmd.new(cmd_list[:CmdBuffer][:Data] + ImDrawCmd.size * cmd_i)
194
+ if pcmd[:UserCallback] != nil && pcmd[:UserCallback].address != 0
195
+ ImplDockingSDL3Renderer_SetupRenderState(renderer)
196
+ next
197
+ end
198
+
199
+ clip_min = ImVec2.create((pcmd[:ClipRect][:x] - clip_off[:x]) * clip_scale[:x], (pcmd[:ClipRect][:y] - clip_off[:y]) * clip_scale[:y])
200
+ clip_max = ImVec2.create((pcmd[:ClipRect][:z] - clip_off[:x]) * clip_scale[:x], (pcmd[:ClipRect][:w] - clip_off[:y]) * clip_scale[:y])
201
+ clip_min[:x] = 0.0 if clip_min[:x] < 0.0
202
+ clip_min[:y] = 0.0 if clip_min[:y] < 0.0
203
+ clip_max[:x] = fb_width.to_f if clip_max[:x] > fb_width
204
+ clip_max[:y] = fb_height.to_f if clip_max[:y] > fb_height
205
+ next if clip_max[:x] <= clip_min[:x] || clip_max[:y] <= clip_min[:y]
206
+
207
+ sdl_rect = SDL::Rect.new
208
+ sdl_rect[:x] = clip_min[:x].to_i
209
+ sdl_rect[:y] = clip_min[:y].to_i
210
+ sdl_rect[:w] = (clip_max[:x] - clip_min[:x]).to_i
211
+ sdl_rect[:h] = (clip_max[:y] - clip_min[:y]).to_i
212
+ SDL.SetRenderClipRect(renderer, sdl_rect)
213
+
214
+ vtx_base = pcmd[:VtxOffset] * ImDrawVert.size
215
+ xy = vtx_buffer + vtx_base + ImDrawVert.offset_of(:pos)
216
+ uv = vtx_buffer + vtx_base + ImDrawVert.offset_of(:uv)
217
+ color_src = vtx_buffer + vtx_base + ImDrawVert.offset_of(:col)
218
+
219
+ num_vertices = cmd_list[:VtxBuffer][:Size] - pcmd[:VtxOffset]
220
+ color_f = ImplDockingSDL3Renderer_UpdateColorBuffer(backend_data, color_src, ImDrawVert.size, num_vertices)
221
+
222
+ tex_id = pcmd.GetTexID
223
+ tex_ptr = tex_id == 0 ? nil : FFI::Pointer.new(tex_id)
224
+ SDL.RenderGeometryRaw(renderer,
225
+ tex_ptr,
226
+ xy, ImDrawVert.size,
227
+ color_f, SDL::FColor.size,
228
+ uv, ImDrawVert.size,
229
+ num_vertices,
230
+ idx_buffer + FFI.type_size(:ImDrawIdx) * pcmd[:IdxOffset], pcmd[:ElemCount], FFI.type_size(:ImDrawIdx))
231
+ end
232
+ end
233
+
234
+ platform_io[:Renderer_RenderState] = nil
235
+ backend_data[:render_state] = nil
236
+
237
+ SDL.SetRenderViewport(renderer, old_viewport_enabled ? old_viewport : nil)
238
+ SDL.SetRenderClipRect(renderer, old_clip_enabled ? old_clip_rect : nil)
239
+ end
240
+
241
+ def self.ImplDockingSDL3Renderer_CreateDeviceObjects
242
+ end
243
+
244
+ def self.ImplDockingSDL3Renderer_DestroyDeviceObjects
245
+ platform_io = ImGuiPlatformIO.new(ImGui::GetPlatformIO())
246
+ textures = platform_io[:Textures]
247
+ textures[:Size].times do |i|
248
+ tex_ptr = (textures[:Data] + FFI.type_size(:pointer) * i).read_pointer
249
+ next if tex_ptr == nil || tex_ptr.address == 0
250
+
251
+ tex = ImTextureData.new(tex_ptr)
252
+ if tex[:RefCount] == 1
253
+ tex.SetStatus(ImTextureStatus_WantDestroy)
254
+ ImplDockingSDL3Renderer_UpdateTexture(tex)
255
+ end
256
+ end
257
+ end
258
+
259
+ end