imgui-bindings 1.0.0 → 1.0.2

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.
Binary file
data/lib/imgui.x86_64.so CHANGED
Binary file
@@ -175,41 +175,46 @@ module ImGui
175
175
  clip_off = draw_data[:DisplayPos]
176
176
  clip_scale = draw_data[:FramebufferScale]
177
177
 
178
- cmd_list_data = draw_data[:CmdLists][:Data]
178
+ cmd_lists = draw_data[:CmdLists]
179
+ cmd_list_data = cmd_lists[:Data]
179
180
  pointer_stride = FFI::Pointer.size
180
181
 
181
- draw_data[:CmdListsCount].times do |n|
182
- cmd_list_ptr = (cmd_list_data + pointer_stride * n).read_pointer
183
- cmd_list = ImDrawList.new(cmd_list_ptr)
182
+ if !cmd_list_data.nil? && !cmd_list_data.null?
183
+ cmd_lists[:Size].times do |n|
184
+ cmd_list_ptr = (cmd_list_data + pointer_stride * n).read_pointer
185
+ next if cmd_list_ptr.nil? || cmd_list_ptr.null?
184
186
 
185
- vtx_size = cmd_list[:VtxBuffer][:Size] * ImDrawVert.size
186
- idx_size = cmd_list[:IdxBuffer][:Size] * 2 # ImDrawIdx is currently ushort in generated bindings.
187
+ cmd_list = ImDrawList.new(cmd_list_ptr)
187
188
 
188
- GL.BufferData(GL::ARRAY_BUFFER, vtx_size, Fiddle::Pointer.new(cmd_list[:VtxBuffer][:Data]), GL::STREAM_DRAW)
189
- GL.BufferData(GL::ELEMENT_ARRAY_BUFFER, idx_size, Fiddle::Pointer.new(cmd_list[:IdxBuffer][:Data]), GL::STREAM_DRAW)
189
+ vtx_size = cmd_list[:VtxBuffer][:Size] * ImDrawVert.size
190
+ idx_size = cmd_list[:IdxBuffer][:Size] * 2 # ImDrawIdx is currently ushort in generated bindings.
190
191
 
191
- cmd_list[:CmdBuffer][:Size].times do |cmd_i|
192
- pcmd = ImDrawCmd.new(cmd_list[:CmdBuffer][:Data] + ImDrawCmd.size * cmd_i)
193
- if pcmd[:UserCallback] != nil
194
- # Reset callback token is not exposed cleanly in current bindings, so keep old behavior.
195
- ImplDockingOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object)
196
- next
197
- end
192
+ GL.BufferData(GL::ARRAY_BUFFER, vtx_size, Fiddle::Pointer.new(cmd_list[:VtxBuffer][:Data]), GL::STREAM_DRAW)
193
+ GL.BufferData(GL::ELEMENT_ARRAY_BUFFER, idx_size, Fiddle::Pointer.new(cmd_list[:IdxBuffer][:Data]), GL::STREAM_DRAW)
198
194
 
199
- clip_min_x = (pcmd[:ClipRect][:x] - clip_off[:x]) * clip_scale[:x]
200
- clip_min_y = (pcmd[:ClipRect][:y] - clip_off[:y]) * clip_scale[:y]
201
- clip_max_x = (pcmd[:ClipRect][:z] - clip_off[:x]) * clip_scale[:x]
202
- clip_max_y = (pcmd[:ClipRect][:w] - clip_off[:y]) * clip_scale[:y]
195
+ cmd_list[:CmdBuffer][:Size].times do |cmd_i|
196
+ pcmd = ImDrawCmd.new(cmd_list[:CmdBuffer][:Data] + ImDrawCmd.size * cmd_i)
197
+ if pcmd[:UserCallback] != nil
198
+ # Reset callback token is not exposed cleanly in current bindings, so keep old behavior.
199
+ ImplDockingOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object)
200
+ next
201
+ end
203
202
 
204
- next if clip_max_x <= clip_min_x || clip_max_y <= clip_min_y
203
+ clip_min_x = (pcmd[:ClipRect][:x] - clip_off[:x]) * clip_scale[:x]
204
+ clip_min_y = (pcmd[:ClipRect][:y] - clip_off[:y]) * clip_scale[:y]
205
+ clip_max_x = (pcmd[:ClipRect][:z] - clip_off[:x]) * clip_scale[:x]
206
+ clip_max_y = (pcmd[:ClipRect][:w] - clip_off[:y]) * clip_scale[:y]
205
207
 
206
- GL.Scissor(clip_min_x.to_i, (fb_height - clip_max_y).to_i, (clip_max_x - clip_min_x).to_i, (clip_max_y - clip_min_y).to_i)
208
+ next if clip_max_x <= clip_min_x || clip_max_y <= clip_min_y
207
209
 
208
- GL.BindTexture(GL::TEXTURE_2D, pcmd.GetTexID())
209
- if @@g_DockingGL3GlVersion >= 320
210
- GL.DrawElementsBaseVertex(GL::TRIANGLES, pcmd[:ElemCount], GL::UNSIGNED_SHORT, Fiddle::Pointer.new(pcmd[:IdxOffset] * 2), pcmd[:VtxOffset])
211
- else
212
- GL.DrawElements(GL::TRIANGLES, pcmd[:ElemCount], GL::UNSIGNED_SHORT, Fiddle::Pointer.new(pcmd[:IdxOffset] * 2))
210
+ GL.Scissor(clip_min_x.to_i, (fb_height - clip_max_y).to_i, (clip_max_x - clip_min_x).to_i, (clip_max_y - clip_min_y).to_i)
211
+
212
+ GL.BindTexture(GL::TEXTURE_2D, pcmd.GetTexID())
213
+ if @@g_DockingGL3GlVersion >= 320
214
+ GL.DrawElementsBaseVertex(GL::TRIANGLES, pcmd[:ElemCount], GL::UNSIGNED_SHORT, Fiddle::Pointer.new(pcmd[:IdxOffset] * 2), pcmd[:VtxOffset])
215
+ else
216
+ GL.DrawElements(GL::TRIANGLES, pcmd[:ElemCount], GL::UNSIGNED_SHORT, Fiddle::Pointer.new(pcmd[:IdxOffset] * 2))
217
+ end
213
218
  end
214
219
  end
215
220
  end
@@ -330,6 +335,8 @@ module ImGui
330
335
 
331
336
  textures = ImVector.new(textures_ptr)
332
337
  data_ptr = textures[:Data]
338
+ return if data_ptr.nil? || data_ptr.null?
339
+
333
340
  pointer_stride = FFI::Pointer.size
334
341
 
335
342
  textures[:Size].times do |i|
@@ -18,6 +18,15 @@ module ImGui
18
18
 
19
19
  @@g_DockingSDL3BackendRendererName = FFI::MemoryPointer.from_string('imgui_impl_docking_sdlrenderer3')
20
20
  @@g_DockingSDL3BackendRendererUserData = {}
21
+ @@g_DockingSDL3RendererResetRenderStateCallback = FFI::Function.new(:void, [:pointer, :pointer]) { |_draw_list, _draw_cmd| }
22
+ @@g_DockingSDL3RendererSetSamplerLinearCallback = FFI::Function.new(:void, [:pointer, :pointer]) do |_draw_list, _draw_cmd|
23
+ backend_data = ImGui_ImplDockingSDLRenderer3_GetBackendData
24
+ backend_data[:current_scale_mode] = SDL::SCALEMODE_LINEAR if backend_data != nil
25
+ end
26
+ @@g_DockingSDL3RendererSetSamplerNearestCallback = FFI::Function.new(:void, [:pointer, :pointer]) do |_draw_list, _draw_cmd|
27
+ backend_data = ImGui_ImplDockingSDLRenderer3_GetBackendData
28
+ backend_data[:current_scale_mode] = SDL::SCALEMODE_NEAREST if backend_data != nil
29
+ end
21
30
 
22
31
  def self.ImGui_ImplDockingSDLRenderer3_GetBackendData
23
32
  return nil if ImGui::GetCurrentContext() == nil
@@ -32,7 +41,8 @@ module ImGui
32
41
  bd: ImGui_ImplDockingSDLRenderer3_Data.new,
33
42
  color_buffer: nil,
34
43
  color_buffer_capacity: 0,
35
- render_state: nil
44
+ render_state: nil,
45
+ current_scale_mode: SDL::SCALEMODE_LINEAR
36
46
  }
37
47
  backend_data[:bd][:Renderer] = renderer
38
48
 
@@ -42,6 +52,11 @@ module ImGui
42
52
  io[:BackendRendererName] = @@g_DockingSDL3BackendRendererName
43
53
  io[:BackendFlags] |= ImGuiBackendFlags_RendererHasVtxOffset
44
54
  io[:BackendFlags] |= ImGuiBackendFlags_RendererHasTextures
55
+
56
+ platform_io = ImGuiPlatformIO.new(ImGui::GetPlatformIO())
57
+ platform_io[:DrawCallback_ResetRenderState] = @@g_DockingSDL3RendererResetRenderStateCallback
58
+ platform_io[:DrawCallback_SetSamplerLinear] = @@g_DockingSDL3RendererSetSamplerLinearCallback
59
+ platform_io[:DrawCallback_SetSamplerNearest] = @@g_DockingSDL3RendererSetSamplerNearestCallback
45
60
  true
46
61
  end
47
62
 
@@ -49,7 +64,7 @@ module ImGui
49
64
  io = ImGuiIO.new(ImGui::GetIO())
50
65
  platform_io = ImGuiPlatformIO.new(ImGui::GetPlatformIO())
51
66
 
52
- ImplDockingSDL3Renderer_DestroyDeviceObjects
67
+ self.ImplDockingSDL3Renderer_DestroyDeviceObjects
53
68
 
54
69
  if ImGui::GetCurrentContext() != nil
55
70
  @@g_DockingSDL3BackendRendererUserData.delete(ImGui::GetCurrentContext().address)
@@ -62,8 +77,11 @@ module ImGui
62
77
  end
63
78
 
64
79
  def self.ImplDockingSDL3Renderer_SetupRenderState(renderer)
80
+ backend_data = ImGui_ImplDockingSDLRenderer3_GetBackendData
81
+
65
82
  SDL.SetRenderViewport(renderer, nil)
66
83
  SDL.SetRenderClipRect(renderer, nil)
84
+ backend_data[:current_scale_mode] = SDL::SCALEMODE_LINEAR if backend_data != nil
67
85
  end
68
86
 
69
87
  def self.ImplDockingSDL3Renderer_NewFrame
@@ -158,12 +176,15 @@ module ImGui
158
176
 
159
177
  if draw_data[:Textures] != nil && draw_data[:Textures].address != 0
160
178
  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
179
+ textures_data = textures[:Data]
180
+ if textures_data != nil && textures_data.address != 0
181
+ textures[:Size].times do |i|
182
+ tex_ptr = (textures_data + FFI.type_size(:pointer) * i).read_pointer
183
+ next if tex_ptr == nil || tex_ptr.address == 0
184
+
185
+ tex = ImTextureData.new(tex_ptr)
186
+ ImplDockingSDL3Renderer_UpdateTexture(tex) if tex[:Status] != ImTextureStatus_OK
187
+ end
167
188
  end
168
189
  end
169
190
 
@@ -183,51 +204,74 @@ module ImGui
183
204
 
184
205
  clip_off = draw_data[:DisplayPos]
185
206
  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
207
+ last_scale_mode = backend_data[:current_scale_mode]
208
+
209
+ cmd_lists = draw_data[:CmdLists]
210
+ cmd_lists_data = cmd_lists[:Data]
211
+ if cmd_lists_data != nil && cmd_lists_data.address != 0
212
+ cmd_lists[:Size].times do |n|
213
+ cmd_list_ptr = (cmd_lists_data + FFI.type_size(:pointer) * n).read_pointer
214
+ next if cmd_list_ptr == nil || cmd_list_ptr.address == 0
215
+
216
+ cmd_list = ImDrawList.new(cmd_list_ptr)
217
+ vtx_buffer = cmd_list[:VtxBuffer][:Data]
218
+ idx_buffer = cmd_list[:IdxBuffer][:Data]
219
+
220
+ cmd_list[:CmdBuffer][:Size].times do |cmd_i|
221
+ pcmd = ImDrawCmd.new(cmd_list[:CmdBuffer][:Data] + ImDrawCmd.size * cmd_i)
222
+ callback_ptr = pcmd[:UserCallback]
223
+ if callback_ptr != nil && callback_ptr.address != 0
224
+ callback_addr = callback_ptr.address
225
+ if callback_addr == @@g_DockingSDL3RendererResetRenderStateCallback.address
226
+ ImplDockingSDL3Renderer_SetupRenderState(renderer)
227
+ elsif callback_addr == @@g_DockingSDL3RendererSetSamplerLinearCallback.address
228
+ backend_data[:current_scale_mode] = SDL::SCALEMODE_LINEAR
229
+ elsif callback_addr == @@g_DockingSDL3RendererSetSamplerNearestCallback.address
230
+ backend_data[:current_scale_mode] = SDL::SCALEMODE_NEAREST
231
+ else
232
+ FFI::Function.new(:void, [:pointer, :pointer], callback_ptr).call(cmd_list.pointer, pcmd.pointer)
233
+ end
234
+ next
235
+ end
236
+
237
+ clip_min = ImVec2.create((pcmd[:ClipRect][:x] - clip_off[:x]) * clip_scale[:x], (pcmd[:ClipRect][:y] - clip_off[:y]) * clip_scale[:y])
238
+ clip_max = ImVec2.create((pcmd[:ClipRect][:z] - clip_off[:x]) * clip_scale[:x], (pcmd[:ClipRect][:w] - clip_off[:y]) * clip_scale[:y])
239
+ clip_min[:x] = 0.0 if clip_min[:x] < 0.0
240
+ clip_min[:y] = 0.0 if clip_min[:y] < 0.0
241
+ clip_max[:x] = fb_width.to_f if clip_max[:x] > fb_width
242
+ clip_max[:y] = fb_height.to_f if clip_max[:y] > fb_height
243
+ next if clip_max[:x] <= clip_min[:x] || clip_max[:y] <= clip_min[:y]
244
+
245
+ sdl_rect = SDL::Rect.new
246
+ sdl_rect[:x] = clip_min[:x].to_i
247
+ sdl_rect[:y] = clip_min[:y].to_i
248
+ sdl_rect[:w] = (clip_max[:x] - clip_min[:x]).to_i
249
+ sdl_rect[:h] = (clip_max[:y] - clip_min[:y]).to_i
250
+ SDL.SetRenderClipRect(renderer, sdl_rect)
251
+
252
+ vtx_base = pcmd[:VtxOffset] * ImDrawVert.size
253
+ xy = vtx_buffer + vtx_base + ImDrawVert.offset_of(:pos)
254
+ uv = vtx_buffer + vtx_base + ImDrawVert.offset_of(:uv)
255
+ color_src = vtx_buffer + vtx_base + ImDrawVert.offset_of(:col)
256
+
257
+ num_vertices = cmd_list[:VtxBuffer][:Size] - pcmd[:VtxOffset]
258
+ color_f = ImplDockingSDL3Renderer_UpdateColorBuffer(backend_data, color_src, ImDrawVert.size, num_vertices)
259
+
260
+ tex_id = pcmd.GetTexID
261
+ tex_ptr = tex_id == 0 ? nil : FFI::Pointer.new(tex_id)
262
+ if last_scale_mode != backend_data[:current_scale_mode]
263
+ SDL.FlushRenderer(renderer)
264
+ last_scale_mode = backend_data[:current_scale_mode]
265
+ end
266
+ SDL.SetTextureScaleMode(tex_ptr, backend_data[:current_scale_mode]) if tex_ptr != nil
267
+ SDL.RenderGeometryRaw(renderer,
268
+ tex_ptr,
269
+ xy, ImDrawVert.size,
270
+ color_f, SDL::FColor.size,
271
+ uv, ImDrawVert.size,
272
+ num_vertices,
273
+ idx_buffer + FFI.type_size(:ImDrawIdx) * pcmd[:IdxOffset], pcmd[:ElemCount], FFI.type_size(:ImDrawIdx))
197
274
  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
275
  end
232
276
  end
233
277
 
@@ -244,14 +288,17 @@ module ImGui
244
288
  def self.ImplDockingSDL3Renderer_DestroyDeviceObjects
245
289
  platform_io = ImGuiPlatformIO.new(ImGui::GetPlatformIO())
246
290
  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)
291
+ textures_data = textures[:Data]
292
+ if textures_data != nil && textures_data.address != 0
293
+ textures[:Size].times do |i|
294
+ tex_ptr = (textures_data + FFI.type_size(:pointer) * i).read_pointer
295
+ next if tex_ptr == nil || tex_ptr.address == 0
296
+
297
+ tex = ImTextureData.new(tex_ptr)
298
+ if tex[:RefCount] == 1
299
+ tex.SetStatus(ImTextureStatus_WantDestroy)
300
+ ImplDockingSDL3Renderer_UpdateTexture(tex)
301
+ end
255
302
  end
256
303
  end
257
304
  end
@@ -171,41 +171,46 @@ module ImGui
171
171
  clip_off = draw_data[:DisplayPos]
172
172
  clip_scale = draw_data[:FramebufferScale]
173
173
 
174
- cmd_list_data = draw_data[:CmdLists][:Data]
174
+ cmd_lists = draw_data[:CmdLists]
175
+ cmd_list_data = cmd_lists[:Data]
175
176
  pointer_stride = FFI::Pointer.size
176
177
 
177
- draw_data[:CmdListsCount].times do |n|
178
- cmd_list_ptr = (cmd_list_data + pointer_stride * n).read_pointer
179
- cmd_list = ImDrawList.new(cmd_list_ptr)
178
+ if !cmd_list_data.nil? && !cmd_list_data.null?
179
+ cmd_lists[:Size].times do |n|
180
+ cmd_list_ptr = (cmd_list_data + pointer_stride * n).read_pointer
181
+ next if cmd_list_ptr.nil? || cmd_list_ptr.null?
180
182
 
181
- vtx_size = cmd_list[:VtxBuffer][:Size] * ImDrawVert.size
182
- idx_size = cmd_list[:IdxBuffer][:Size] * 2 # ImDrawIdx is currently ushort in generated bindings.
183
+ cmd_list = ImDrawList.new(cmd_list_ptr)
183
184
 
184
- GL.BufferData(GL::ARRAY_BUFFER, vtx_size, Fiddle::Pointer.new(cmd_list[:VtxBuffer][:Data]), GL::STREAM_DRAW)
185
- GL.BufferData(GL::ELEMENT_ARRAY_BUFFER, idx_size, Fiddle::Pointer.new(cmd_list[:IdxBuffer][:Data]), GL::STREAM_DRAW)
185
+ vtx_size = cmd_list[:VtxBuffer][:Size] * ImDrawVert.size
186
+ idx_size = cmd_list[:IdxBuffer][:Size] * 2 # ImDrawIdx is currently ushort in generated bindings.
186
187
 
187
- cmd_list[:CmdBuffer][:Size].times do |cmd_i|
188
- pcmd = ImDrawCmd.new(cmd_list[:CmdBuffer][:Data] + ImDrawCmd.size * cmd_i)
189
- if pcmd[:UserCallback] != nil
190
- # Reset callback token is not exposed cleanly in current bindings, so keep old behavior.
191
- ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object)
192
- next
193
- end
188
+ GL.BufferData(GL::ARRAY_BUFFER, vtx_size, Fiddle::Pointer.new(cmd_list[:VtxBuffer][:Data]), GL::STREAM_DRAW)
189
+ GL.BufferData(GL::ELEMENT_ARRAY_BUFFER, idx_size, Fiddle::Pointer.new(cmd_list[:IdxBuffer][:Data]), GL::STREAM_DRAW)
194
190
 
195
- clip_min_x = (pcmd[:ClipRect][:x] - clip_off[:x]) * clip_scale[:x]
196
- clip_min_y = (pcmd[:ClipRect][:y] - clip_off[:y]) * clip_scale[:y]
197
- clip_max_x = (pcmd[:ClipRect][:z] - clip_off[:x]) * clip_scale[:x]
198
- clip_max_y = (pcmd[:ClipRect][:w] - clip_off[:y]) * clip_scale[:y]
191
+ cmd_list[:CmdBuffer][:Size].times do |cmd_i|
192
+ pcmd = ImDrawCmd.new(cmd_list[:CmdBuffer][:Data] + ImDrawCmd.size * cmd_i)
193
+ if pcmd[:UserCallback] != nil
194
+ # Reset callback token is not exposed cleanly in current bindings, so keep old behavior.
195
+ ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object)
196
+ next
197
+ end
199
198
 
200
- next if clip_max_x <= clip_min_x || clip_max_y <= clip_min_y
199
+ clip_min_x = (pcmd[:ClipRect][:x] - clip_off[:x]) * clip_scale[:x]
200
+ clip_min_y = (pcmd[:ClipRect][:y] - clip_off[:y]) * clip_scale[:y]
201
+ clip_max_x = (pcmd[:ClipRect][:z] - clip_off[:x]) * clip_scale[:x]
202
+ clip_max_y = (pcmd[:ClipRect][:w] - clip_off[:y]) * clip_scale[:y]
201
203
 
202
- GL.Scissor(clip_min_x.to_i, (fb_height - clip_max_y).to_i, (clip_max_x - clip_min_x).to_i, (clip_max_y - clip_min_y).to_i)
204
+ next if clip_max_x <= clip_min_x || clip_max_y <= clip_min_y
203
205
 
204
- GL.BindTexture(GL::TEXTURE_2D, pcmd.GetTexID())
205
- if @@g_GlVersion >= 320
206
- GL.DrawElementsBaseVertex(GL::TRIANGLES, pcmd[:ElemCount], GL::UNSIGNED_SHORT, Fiddle::Pointer.new(pcmd[:IdxOffset] * 2), pcmd[:VtxOffset])
207
- else
208
- GL.DrawElements(GL::TRIANGLES, pcmd[:ElemCount], GL::UNSIGNED_SHORT, Fiddle::Pointer.new(pcmd[:IdxOffset] * 2))
206
+ GL.Scissor(clip_min_x.to_i, (fb_height - clip_max_y).to_i, (clip_max_x - clip_min_x).to_i, (clip_max_y - clip_min_y).to_i)
207
+
208
+ GL.BindTexture(GL::TEXTURE_2D, pcmd.GetTexID())
209
+ if @@g_GlVersion >= 320
210
+ GL.DrawElementsBaseVertex(GL::TRIANGLES, pcmd[:ElemCount], GL::UNSIGNED_SHORT, Fiddle::Pointer.new(pcmd[:IdxOffset] * 2), pcmd[:VtxOffset])
211
+ else
212
+ GL.DrawElements(GL::TRIANGLES, pcmd[:ElemCount], GL::UNSIGNED_SHORT, Fiddle::Pointer.new(pcmd[:IdxOffset] * 2))
213
+ end
209
214
  end
210
215
  end
211
216
  end
@@ -303,6 +308,8 @@ module ImGui
303
308
 
304
309
  textures = ImVector.new(textures_ptr)
305
310
  data_ptr = textures[:Data]
311
+ return if data_ptr.nil? || data_ptr.null?
312
+
306
313
  pointer_stride = FFI::Pointer.size
307
314
 
308
315
  textures[:Size].times do |i|
@@ -94,16 +94,10 @@ module ImGui
94
94
  texture[:format] = Raylib::PIXELFORMAT_UNCOMPRESSED_R8G8B8A8
95
95
  end
96
96
 
97
- updates = tex[:Updates]
98
- updates[:Size].times do |i|
99
- r = ImTextureRect.new(updates[:Data] + ImTextureRect.size * i)
100
- rec = Raylib::Rectangle.new
101
- rec[:x] = r[:x].to_f
102
- rec[:y] = r[:y].to_f
103
- rec[:width] = r[:w].to_f
104
- rec[:height] = r[:h].to_f
105
- Raylib.UpdateTextureRec(texture, rec, tex.GetPixelsAt(r[:x], r[:y]))
106
- end
97
+ # Raylib.UpdateTextureRec has no row-pitch argument, so sub-rect updates
98
+ # sourced from a larger atlas can sample incorrect rows and corrupt glyphs.
99
+ # Uploading the full atlas keeps texture data consistent across backends.
100
+ Raylib.UpdateTexture(texture, tex.GetPixels())
107
101
  tex.SetStatus(ImTextureStatus_OK)
108
102
 
109
103
  when ImTextureStatus_WantDestroy
@@ -131,8 +125,11 @@ module ImGui
131
125
  return if draw_data[:Textures] == nil || draw_data[:Textures].address == 0
132
126
 
133
127
  textures = ImVector_ImTextureDataPtr.new(draw_data[:Textures])
128
+ textures_data = textures[:Data]
129
+ return if textures_data == nil || textures_data.address == 0
130
+
134
131
  textures[:Size].times do |i|
135
- tex_ptr = (textures[:Data] + FFI.type_size(:pointer) * i).read_pointer
132
+ tex_ptr = (textures_data + FFI.type_size(:pointer) * i).read_pointer
136
133
  next if tex_ptr == nil || tex_ptr.address == 0
137
134
 
138
135
  tex = ImTextureData.new(tex_ptr)
@@ -491,13 +488,11 @@ module ImGui
491
488
  if mode == Raylib::CAMERA_CUSTOM
492
489
  # no-op
493
490
  elsif mode == Raylib::CAMERA_ORBITAL
494
- if !wants_mouse
495
- rotation = Raylib.MatrixRotate(Raylib.GetCameraUp(camera_ptr), camera_orbital_speed)
496
- view = Raylib.Vector3Subtract(Raylib::Camera.new(camera_ptr)[:position], Raylib::Camera.new(camera_ptr)[:target])
497
- view = Raylib.Vector3Transform(view, rotation)
498
- camera_data = Raylib::Camera.new(camera_ptr)
499
- camera_data[:position] = Raylib.Vector3Add(camera_data[:target], view)
500
- end
491
+ rotation = Raylib.MatrixRotate(Raylib.GetCameraUp(camera_ptr), camera_orbital_speed)
492
+ view = Raylib.Vector3Subtract(Raylib::Camera.new(camera_ptr)[:position], Raylib::Camera.new(camera_ptr)[:target])
493
+ view = Raylib.Vector3Transform(view, rotation)
494
+ camera_data = Raylib::Camera.new(camera_ptr)
495
+ camera_data[:position] = Raylib.Vector3Add(camera_data[:target], view)
501
496
  else
502
497
  if !block_keyboard_controls
503
498
  if Raylib.IsKeyDown(Raylib::KEY_DOWN)
@@ -696,16 +691,26 @@ module ImGui
696
691
 
697
692
  clip_offset = draw_data[:DisplayPos]
698
693
  clip_scale = draw_data[:FramebufferScale]
699
- draw_data[:CmdListsCount].times do |n|
700
- cmd_list = ImDrawList.new((draw_data[:CmdLists][:Data] + FFI.type_size(:pointer) * n).read_pointer)
701
- vtx_buffer = cmd_list[:VtxBuffer][:Data] # const ImDrawVert*
702
- idx_buffer = cmd_list[:IdxBuffer][:Data] # const ImDrawIdx*
703
-
704
- cmd_list[:CmdBuffer][:Size].times do |cmd_i|
705
- pcmd = ImDrawCmd.new(cmd_list[:CmdBuffer][:Data] + ImDrawCmd.size * cmd_i) # const ImDrawCmd*
706
- if pcmd[:UserCallback] != nil
707
- # [TODO] Handle user callback (Ref.: https://github.com/ffi/ffi/wiki/Callbacks )
708
- else
694
+ cmd_lists = draw_data[:CmdLists]
695
+ cmd_lists_data = cmd_lists[:Data]
696
+
697
+ if cmd_lists_data != nil && cmd_lists_data.address != 0
698
+ cmd_lists[:Size].times do |n|
699
+ cmd_list_ptr = (cmd_lists_data + FFI.type_size(:pointer) * n).read_pointer
700
+ next if cmd_list_ptr == nil || cmd_list_ptr.address == 0
701
+
702
+ cmd_list = ImDrawList.new(cmd_list_ptr)
703
+ vtx_buffer = cmd_list[:VtxBuffer][:Data] # const ImDrawVert*
704
+ idx_buffer = cmd_list[:IdxBuffer][:Data] # const ImDrawIdx*
705
+
706
+ cmd_list[:CmdBuffer][:Size].times do |cmd_i|
707
+ pcmd = ImDrawCmd.new(cmd_list[:CmdBuffer][:Data] + ImDrawCmd.size * cmd_i) # const ImDrawCmd*
708
+ callback_ptr = pcmd[:UserCallback]
709
+ if callback_ptr != nil && callback_ptr.address != 0
710
+ # [TODO] Handle user callback (Ref.: https://github.com/ffi/ffi/wiki/Callbacks )
711
+ next
712
+ end
713
+
709
714
  rect_min_x = (pcmd[:ClipRect][:x] - clip_offset[:x]) * clip_scale[:x]
710
715
  rect_min_y = (pcmd[:ClipRect][:y] - clip_offset[:y]) * clip_scale[:y]
711
716
  rect_max_x = (pcmd[:ClipRect][:z] - clip_offset[:x]) * clip_scale[:x]
@@ -727,31 +732,31 @@ module ImGui
727
732
  vertices = vtx_buffer + ImDrawVert.size * pcmd[:VtxOffset]
728
733
  0.step(pcmd[:ElemCount] - 3, 3) do |i|
729
734
  Raylib.rlPushMatrix()
730
- Raylib.rlBegin(Raylib::RL_TRIANGLES)
731
- Raylib.rlSetTexture(pcmd.GetTexID())
732
-
733
- index = indices.get_array_of_uint16(i * FFI::type_size(:ImDrawIdx), 3)
734
-
735
- base_offset = ImDrawVert.size * index[0]
736
- xy = vertices + (base_offset + ImDrawVert.offset_of(:pos))
737
- uv = vertices + (base_offset + ImDrawVert.offset_of(:uv))
738
- color = vertices + (base_offset + ImDrawVert.offset_of(:col))
739
- set_vertex(xy.read_array_of_float(2), uv.read_array_of_float(2), color.read_array_of_uint8(4))
740
-
741
- base_offset = ImDrawVert.size * index[2]
742
- xy = vertices + (base_offset + ImDrawVert.offset_of(:pos))
743
- uv = vertices + (base_offset + ImDrawVert.offset_of(:uv))
744
- color = vertices + (base_offset + ImDrawVert.offset_of(:col))
745
- set_vertex(xy.read_array_of_float(2), uv.read_array_of_float(2), color.read_array_of_uint8(4))
746
-
747
- base_offset = ImDrawVert.size * index[1]
748
- xy = vertices + (base_offset + ImDrawVert.offset_of(:pos))
749
- uv = vertices + (base_offset + ImDrawVert.offset_of(:uv))
750
- color = vertices + (base_offset + ImDrawVert.offset_of(:col))
751
- set_vertex(xy.read_array_of_float(2), uv.read_array_of_float(2), color.read_array_of_uint8(4))
752
-
753
- Raylib.rlSetTexture(0)
754
- Raylib.rlEnd()
735
+ Raylib.rlBegin(Raylib::RL_TRIANGLES)
736
+ Raylib.rlSetTexture(pcmd.GetTexID())
737
+
738
+ index = indices.get_array_of_uint16(i * FFI::type_size(:ImDrawIdx), 3)
739
+
740
+ base_offset = ImDrawVert.size * index[0]
741
+ xy = vertices + (base_offset + ImDrawVert.offset_of(:pos))
742
+ uv = vertices + (base_offset + ImDrawVert.offset_of(:uv))
743
+ color = vertices + (base_offset + ImDrawVert.offset_of(:col))
744
+ set_vertex(xy.read_array_of_float(2), uv.read_array_of_float(2), color.read_array_of_uint8(4))
745
+
746
+ base_offset = ImDrawVert.size * index[2]
747
+ xy = vertices + (base_offset + ImDrawVert.offset_of(:pos))
748
+ uv = vertices + (base_offset + ImDrawVert.offset_of(:uv))
749
+ color = vertices + (base_offset + ImDrawVert.offset_of(:col))
750
+ set_vertex(xy.read_array_of_float(2), uv.read_array_of_float(2), color.read_array_of_uint8(4))
751
+
752
+ base_offset = ImDrawVert.size * index[1]
753
+ xy = vertices + (base_offset + ImDrawVert.offset_of(:pos))
754
+ uv = vertices + (base_offset + ImDrawVert.offset_of(:uv))
755
+ color = vertices + (base_offset + ImDrawVert.offset_of(:col))
756
+ set_vertex(xy.read_array_of_float(2), uv.read_array_of_float(2), color.read_array_of_uint8(4))
757
+
758
+ Raylib.rlSetTexture(0)
759
+ Raylib.rlEnd()
755
760
  Raylib.rlPopMatrix()
756
761
  end
757
762
  Raylib.EndScissorMode()