imgui-bindings 0.0.2 → 0.1.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.
@@ -1,334 +1,460 @@
1
- require 'ffi'
2
- require 'raylib'
3
- require 'opengl'
4
-
5
- require_relative 'imgui'
6
-
7
- module ImGui
8
-
9
- @@g_Time = 0.0 # UInt64
10
- @@g_BackendPlatformName = FFI::MemoryPointer.from_string("imgui_impl_raylib")
11
-
12
- # [TODO] Support ClipboardText
13
- # g_ClipboardTextData
14
- # ImplRaylib_GetClipboardText
15
- # ImplRaylib_SetClipboardText
16
-
17
- # [INTERNAL]
18
- def self.ImplRaylib_UpdateMousePosAndButtons()
19
- # Update buttons
20
- io = ImGuiIO.new(ImGui::GetIO())
21
-
22
- # Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
23
- if io[:WantSetMousePos]
24
- Raylib.SetMousePosition(io[:MousePos][:x].to_i, io[:MousePos][:y].to_i)
25
- else
26
- io[:MousePos][:x] = -Float::MAX
27
- io[:MousePos][:y] = -Float::MAX
28
- end
29
-
30
- io[:MouseDown][0] = Raylib.IsMouseButtonDown(Raylib::MOUSE_BUTTON_LEFT)
31
- io[:MouseDown][1] = Raylib.IsMouseButtonDown(Raylib::MOUSE_BUTTON_MIDDLE)
32
- io[:MouseDown][2] = Raylib.IsMouseButtonDown(Raylib::MOUSE_BUTTON_RIGHT)
33
-
34
- mouse_pos = Raylib.GetMousePosition()
35
- io[:MousePos][:x] = mouse_pos[:x]
36
- io[:MousePos][:y] = mouse_pos[:y]
37
- end
38
-
39
- # [INTERNAL]
40
- def self.ImplRaylib_UpdateMouseCursor()
41
- io = ImGuiIO.new(ImGui::GetIO())
42
- return if (io[:ConfigFlags] & ImGuiConfigFlags_NoMouseCursorChange)
43
-
44
- if io[:MouseDrawCursor] || ImGui::GetMouseCursor() == ImGuiMouseCursor_None
45
- Raylib.HideCursor() # Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
46
- else
47
- Raylib.ShowCursor() # Show OS mouse cursor
48
- end
49
- end
50
-
51
- #
52
- # [TODO] Support ImplRaylib_UpdateGamepads
53
- #
54
-
55
- def self.ImplRaylib_Shutdown()
56
- end
57
-
58
- def self.ImplRaylib_NewFrame()
59
- io = ImGuiIO.new(ImGui::GetIO())
60
-
61
- unless io[:Fonts].IsBuilt()
62
- puts "Font atlas not built! It is generally built by the renderer back-end. Missing call to renderer _NewFrame() function? e.g. ImGui_ImplOpenGL3_NewFrame()."
63
- end
64
-
65
- # Setup display size (every frame to accommodate for window resizing)
66
- io[:DisplaySize][:x] = Raylib.GetScreenWidth()
67
- io[:DisplaySize][:y] = Raylib.GetScreenHeight()
68
-
69
- # Setup time step
70
- current_time = Raylib.GetTime()
71
-
72
- io[:DeltaTime] = @@g_Time > 0 ? (current_time - @@g_Time).to_f : 1.0 / 60.0
73
- @@g_Time = current_time
74
-
75
- ImplRaylib_UpdateMousePosAndButtons()
76
- ImplRaylib_UpdateMouseCursor()
77
-
78
- wheel_y = Raylib.GetMouseWheelMove()
79
- io[:MouseWheel] += 1 if wheel_y > 0
80
- io[:MouseWheel] -= 1 if wheel_y < 0
81
- io[:MouseWheelH] = 0 # [TODO] Get wheel tilt from Raylib
82
- io[:MouseWheelH] = 0 # [TODO] Get wheel tilt from Raylib
83
-
84
- # [TODO] update gamepads
85
-
86
- # [NOTE] rlgl does not provide glBlendFuncSeparate wrapper. So we manually set states for ImGui here.
87
- # Ref.: https://github.com/vaiorabbit/ruby-imgui/blob/05e94e6bf1969d3abf12598fef831219dca90247/lib/imgui_impl_opengl3.rb#L227-L234
88
- # [TODO] Hide raw OpenGL operation
89
- GL.BlendFuncSeparate(GL::SRC_ALPHA, GL::ONE_MINUS_SRC_ALPHA, GL::ONE, GL::ONE_MINUS_SRC_ALPHA)
90
-
91
- end
92
-
93
- KEY_IDS = [
94
- # Alphanumeric keys
95
- Raylib::KEY_APOSTROPHE, # Key: '
96
- Raylib::KEY_COMMA, # Key: ,
97
- Raylib::KEY_MINUS, # Key: -
98
- Raylib::KEY_PERIOD, # Key: .
99
- Raylib::KEY_SLASH, # Key: /
100
- Raylib::KEY_ZERO, # Key: 0
101
- Raylib::KEY_ONE, # Key: 1
102
- Raylib::KEY_TWO, # Key: 2
103
- Raylib::KEY_THREE, # Key: 3
104
- Raylib::KEY_FOUR, # Key: 4
105
- Raylib::KEY_FIVE, # Key: 5
106
- Raylib::KEY_SIX, # Key: 6
107
- Raylib::KEY_SEVEN, # Key: 7
108
- Raylib::KEY_EIGHT, # Key: 8
109
- Raylib::KEY_NINE, # Key: 9
110
- Raylib::KEY_SEMICOLON, # Key: ;
111
- Raylib::KEY_EQUAL, # Key: =
112
- Raylib::KEY_A, # Key: A | a
113
- Raylib::KEY_B, # Key: B | b
114
- Raylib::KEY_C, # Key: C | c
115
- Raylib::KEY_D, # Key: D | d
116
- Raylib::KEY_E, # Key: E | e
117
- Raylib::KEY_F, # Key: F | f
118
- Raylib::KEY_G, # Key: G | g
119
- Raylib::KEY_H, # Key: H | h
120
- Raylib::KEY_I, # Key: I | i
121
- Raylib::KEY_J, # Key: J | j
122
- Raylib::KEY_K, # Key: K | k
123
- Raylib::KEY_L, # Key: L | l
124
- Raylib::KEY_M, # Key: M | m
125
- Raylib::KEY_N, # Key: N | n
126
- Raylib::KEY_O, # Key: O | o
127
- Raylib::KEY_P, # Key: P | p
128
- Raylib::KEY_Q, # Key: Q | q
129
- Raylib::KEY_R, # Key: R | r
130
- Raylib::KEY_S, # Key: S | s
131
- Raylib::KEY_T, # Key: T | t
132
- Raylib::KEY_U, # Key: U | u
133
- Raylib::KEY_V, # Key: V | v
134
- Raylib::KEY_W, # Key: W | w
135
- Raylib::KEY_X, # Key: X | x
136
- Raylib::KEY_Y, # Key: Y | y
137
- Raylib::KEY_Z, # Key: Z | z
138
- Raylib::KEY_LEFT_BRACKET, # Key: [
139
- Raylib::KEY_BACKSLASH, # Key: '\'
140
- Raylib::KEY_RIGHT_BRACKET, # Key: ]
141
- Raylib::KEY_GRAVE, # Key: `
142
- # Function keys
143
- Raylib::KEY_SPACE, # Key: Space
144
- Raylib::KEY_ESCAPE, # Key: Esc
145
- Raylib::KEY_ENTER, # Key: Enter
146
- Raylib::KEY_TAB, # Key: Tab
147
- Raylib::KEY_BACKSPACE, # Key: Backspace
148
- Raylib::KEY_INSERT, # Key: Ins
149
- Raylib::KEY_DELETE, # Key: Del
150
- Raylib::KEY_RIGHT, # Key: Cursor right
151
- Raylib::KEY_LEFT, # Key: Cursor left
152
- Raylib::KEY_DOWN, # Key: Cursor down
153
- Raylib::KEY_UP, # Key: Cursor up
154
- Raylib::KEY_PAGE_UP, # Key: Page up
155
- Raylib::KEY_PAGE_DOWN, # Key: Page down
156
- Raylib::KEY_HOME, # Key: Home
157
- Raylib::KEY_END, # Key: End
158
- Raylib::KEY_CAPS_LOCK, # Key: Caps lock
159
- Raylib::KEY_SCROLL_LOCK, # Key: Scroll down
160
- Raylib::KEY_NUM_LOCK, # Key: Num lock
161
- Raylib::KEY_PRINT_SCREEN, # Key: Print screen
162
- Raylib::KEY_PAUSE, # Key: Pause
163
- Raylib::KEY_F1, # Key: F1
164
- Raylib::KEY_F2, # Key: F2
165
- Raylib::KEY_F3, # Key: F3
166
- Raylib::KEY_F4, # Key: F4
167
- Raylib::KEY_F5, # Key: F5
168
- Raylib::KEY_F6, # Key: F6
169
- Raylib::KEY_F7, # Key: F7
170
- Raylib::KEY_F8, # Key: F8
171
- Raylib::KEY_F9, # Key: F9
172
- Raylib::KEY_F10, # Key: F10
173
- Raylib::KEY_F11, # Key: F11
174
- Raylib::KEY_F12, # Key: F12
175
- Raylib::KEY_LEFT_SHIFT, # Key: Shift left
176
- Raylib::KEY_LEFT_CONTROL, # Key: Control left
177
- Raylib::KEY_LEFT_ALT, # Key: Alt left
178
- Raylib::KEY_LEFT_SUPER, # Key: Super left
179
- Raylib::KEY_RIGHT_SHIFT, # Key: Shift right
180
- Raylib::KEY_RIGHT_CONTROL, # Key: Control right
181
- Raylib::KEY_RIGHT_ALT, # Key: Alt right
182
- Raylib::KEY_RIGHT_SUPER, # Key: Super right
183
- Raylib::KEY_KB_MENU, # Key: KB menu
184
- # Keypad keys
185
- Raylib::KEY_KP_0, # Key: Keypad 0
186
- Raylib::KEY_KP_1, # Key: Keypad 1
187
- Raylib::KEY_KP_2, # Key: Keypad 2
188
- Raylib::KEY_KP_3, # Key: Keypad 3
189
- Raylib::KEY_KP_4, # Key: Keypad 4
190
- Raylib::KEY_KP_5, # Key: Keypad 5
191
- Raylib::KEY_KP_6, # Key: Keypad 6
192
- Raylib::KEY_KP_7, # Key: Keypad 7
193
- Raylib::KEY_KP_8, # Key: Keypad 8
194
- Raylib::KEY_KP_9, # Key: Keypad 9
195
- Raylib::KEY_KP_DECIMAL, # Key: Keypad .
196
- Raylib::KEY_KP_DIVIDE, # Key: Keypad /
197
- Raylib::KEY_KP_MULTIPLY, # Key: Keypad *
198
- Raylib::KEY_KP_SUBTRACT, # Key: Keypad -
199
- Raylib::KEY_KP_ADD, # Key: Keypad +
200
- Raylib::KEY_KP_ENTER, # Key: Keypad Enter
201
- Raylib::KEY_KP_EQUAL, # Key: Keypad =
202
- ]
203
-
204
- def self.ImplRaylib_ProcessKeyboard()
205
- io = ImGuiIO.new(ImGui::GetIO())
206
-
207
- io[:KeyShift] = Raylib.IsKeyDown(Raylib::KEY_RIGHT_SHIFT) || Raylib.IsKeyDown(Raylib::KEY_LEFT_SHIFT)
208
- io[:KeyCtrl] = Raylib.IsKeyDown(Raylib::KEY_RIGHT_CONTROL) || Raylib.IsKeyDown(Raylib::KEY_LEFT_CONTROL)
209
- io[:KeyAlt] = Raylib.IsKeyDown(Raylib::KEY_RIGHT_ALT) || Raylib.IsKeyDown(Raylib::KEY_LEFT_ALT)
210
- io[:KeySuper] = Raylib.IsKeyDown(Raylib::KEY_RIGHT_SUPER) || Raylib.IsKeyDown(Raylib::KEY_LEFT_SUPER) # [TODO] io.KeySuper = false on _WIN32
211
-
212
- KEY_IDS.each { |key| io[:KeysDown][key] = Raylib.IsKeyDown(key) }
213
-
214
- keyPressed = Raylib.GetKeyPressed()
215
- io.AddInputCharacter(keyPressed) if keyPressed > 0
216
-
217
- return true
218
- end
219
-
220
- def self.ImplRaylib_Init()
221
- @@g_Time = 0
222
-
223
- io = ImGuiIO.new(ImGui::GetIO())
224
-
225
- io[:BackendPlatformUserData] = nil
226
- io[:BackendPlatformName] = @@g_BackendPlatformName
227
- io[:BackendFlags] |= ImGuiBackendFlags_HasMouseCursors # We can honor GetMouseCursor() values (optional)
228
- io[:BackendFlags] |= ImGuiBackendFlags_HasSetMousePos # We can honor io.WantSetMousePos requests (optional, rarely used)
229
-
230
- # Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array.
231
- io[:KeyMap][ImGuiKey_Tab] = Raylib::KEY_TAB
232
- io[:KeyMap][ImGuiKey_LeftArrow] = Raylib::KEY_LEFT
233
- io[:KeyMap][ImGuiKey_RightArrow] = Raylib::KEY_RIGHT
234
- io[:KeyMap][ImGuiKey_UpArrow] = Raylib::KEY_UP
235
- io[:KeyMap][ImGuiKey_DownArrow] = Raylib::KEY_DOWN
236
- io[:KeyMap][ImGuiKey_PageUp] = Raylib::KEY_PAGE_UP
237
- io[:KeyMap][ImGuiKey_PageDown] = Raylib::KEY_PAGE_DOWN
238
- io[:KeyMap][ImGuiKey_Home] = Raylib::KEY_HOME
239
- io[:KeyMap][ImGuiKey_End] = Raylib::KEY_END
240
- io[:KeyMap][ImGuiKey_Insert] = Raylib::KEY_INSERT
241
- io[:KeyMap][ImGuiKey_Delete] = Raylib::KEY_DELETE
242
- io[:KeyMap][ImGuiKey_Backspace] = Raylib::KEY_BACKSPACE
243
- io[:KeyMap][ImGuiKey_Space] = Raylib::KEY_SPACE
244
- io[:KeyMap][ImGuiKey_Enter] = Raylib::KEY_ENTER
245
- io[:KeyMap][ImGuiKey_Escape] = Raylib::KEY_ESCAPE
246
- io[:KeyMap][ImGuiKey_KeyPadEnter] = Raylib::KEY_KP_ENTER
247
- io[:KeyMap][ImGuiKey_A] = Raylib::KEY_A
248
- io[:KeyMap][ImGuiKey_C] = Raylib::KEY_C
249
- io[:KeyMap][ImGuiKey_V] = Raylib::KEY_V
250
- io[:KeyMap][ImGuiKey_X] = Raylib::KEY_X
251
- io[:KeyMap][ImGuiKey_Y] = Raylib::KEY_Y
252
- io[:KeyMap][ImGuiKey_Z] = Raylib::KEY_Z
253
-
254
- # [TODO] Support ClipboardText
255
-
256
- mouse_pos = Raylib.GetMousePosition()
257
- io[:MousePos][:x] = mouse_pos[:x]
258
- io[:MousePos][:y] = mouse_pos[:y]
259
-
260
- return true
261
- end
262
-
263
- # [INTERNAL]
264
- def self.set_vertex(xy, uv, color)
265
- Raylib.rlColor4ub(color[0], color[1], color[2], color[3])
266
- Raylib.rlTexCoord2f(uv[0], uv[1])
267
- Raylib.rlVertex2f(xy[0], xy[1])
268
- end
269
-
270
- def self.ImplRaylib_RenderDrawData(draw_data_raw)
271
- draw_data = ImDrawData.new(draw_data_raw)
272
- Raylib.rlDisableBackfaceCulling()
273
-
274
- clip_offset = draw_data[:DisplayPos]
275
- draw_data[:CmdListsCount].times do |n|
276
- cmd_list = ImDrawList.new((draw_data[:CmdLists].pointer + FFI.type_size(:pointer) * n).read_pointer)
277
- vtx_buffer = cmd_list[:VtxBuffer][:Data] # const ImDrawVert*
278
- idx_buffer = cmd_list[:IdxBuffer][:Data] # const ImDrawIdx*
279
-
280
- cmd_list[:CmdBuffer][:Size].times do |cmd_i|
281
- pcmd = ImDrawCmd.new(cmd_list[:CmdBuffer][:Data] + ImDrawCmd.size * cmd_i) # const ImDrawCmd*
282
- if pcmd[:UserCallback] != nil
283
- # [TODO] Handle user callback (Ref.: https://github.com/ffi/ffi/wiki/Callbacks )
284
- else
285
- rect_min_x = (pcmd[:ClipRect][:x] - clip_offset[:x])
286
- rect_min_y = (pcmd[:ClipRect][:y] - clip_offset[:y])
287
- rect_max_x = (pcmd[:ClipRect][:z] - clip_offset[:x])
288
- rect_max_y = (pcmd[:ClipRect][:w] - clip_offset[:y])
289
-
290
- rect_w = rect_max_x - rect_min_x
291
- rect_h = rect_max_y - rect_min_y
292
-
293
- Raylib.BeginScissorMode(rect_min_x, rect_min_y, rect_w, rect_h)
294
-
295
- # Render triangles
296
- indices = idx_buffer + FFI.type_size(:ImDrawIdx) * pcmd[:IdxOffset]
297
- vertices = vtx_buffer + ImDrawVert.size * pcmd[:VtxOffset]
298
- 0.step(pcmd[:ElemCount] - 3, 3) do |i|
299
- Raylib.rlPushMatrix()
300
- Raylib.rlBegin(Raylib::RL_TRIANGLES)
301
- Raylib.rlSetTexture(pcmd[:TextureId].read_uint32)
302
-
303
- index = indices.get_array_of_uint16(i * FFI::type_size(:ImDrawIdx), 3)
304
-
305
- base_offset = ImDrawVert.size * index[0]
306
- xy = vertices + (base_offset + ImDrawVert.offset_of(:pos))
307
- uv = vertices + (base_offset + ImDrawVert.offset_of(:uv))
308
- color = vertices + (base_offset + ImDrawVert.offset_of(:col))
309
- set_vertex(xy.read_array_of_float(2), uv.read_array_of_float(2), color.read_array_of_uint8(4))
310
-
311
- base_offset = ImDrawVert.size * index[2]
312
- xy = vertices + (base_offset + ImDrawVert.offset_of(:pos))
313
- uv = vertices + (base_offset + ImDrawVert.offset_of(:uv))
314
- color = vertices + (base_offset + ImDrawVert.offset_of(:col))
315
- set_vertex(xy.read_array_of_float(2), uv.read_array_of_float(2), color.read_array_of_uint8(4))
316
-
317
- base_offset = ImDrawVert.size * index[1]
318
- xy = vertices + (base_offset + ImDrawVert.offset_of(:pos))
319
- uv = vertices + (base_offset + ImDrawVert.offset_of(:uv))
320
- color = vertices + (base_offset + ImDrawVert.offset_of(:col))
321
- set_vertex(xy.read_array_of_float(2), uv.read_array_of_float(2), color.read_array_of_uint8(4))
322
-
323
- Raylib.rlSetTexture(0)
324
- Raylib.rlEnd()
325
- Raylib.rlPopMatrix()
326
- end
327
- Raylib.EndScissorMode()
328
- end
329
- end
330
- end
331
- Raylib.rlEnableBackfaceCulling()
332
- end
333
-
334
- end
1
+ require 'ffi'
2
+ require 'raylib'
3
+ require 'opengl'
4
+
5
+ require_relative 'imgui'
6
+
7
+ module ImGui
8
+
9
+ @@g_BackendPlatformName = FFI::MemoryPointer.from_string("imgui_impl_raylib")
10
+
11
+ # ImGui::GetCurrentContext().address => ImGui_ImplRaylib_Data
12
+ @@g_BackendData = Hash.new
13
+
14
+ # [INTERNAL]
15
+ class ImGui_ImplRaylib_Data
16
+ attr_accessor :time
17
+
18
+ def initialize
19
+ @time = 0.0
20
+ end
21
+ end
22
+
23
+ # [INTERNAL]
24
+ def self.ImGui_ImplRaylib_GetBackendData()
25
+ if ImGui::GetCurrentContext() != nil
26
+ @@g_BackendData[ImGui::GetCurrentContext().address]
27
+ else
28
+ nil
29
+ end
30
+ end
31
+
32
+ # [TODO] Support ClipboardText
33
+ # g_ClipboardTextData
34
+ # ImplRaylib_GetClipboardText
35
+ # ImplRaylib_SetClipboardText
36
+
37
+ KEY_IDS = [
38
+ # Alphanumeric keys
39
+ Raylib::KEY_APOSTROPHE, # Key: '
40
+ Raylib::KEY_COMMA, # Key: ,
41
+ Raylib::KEY_MINUS, # Key: -
42
+ Raylib::KEY_PERIOD, # Key: .
43
+ Raylib::KEY_SLASH, # Key: /
44
+ Raylib::KEY_ZERO, # Key: 0
45
+ Raylib::KEY_ONE, # Key: 1
46
+ Raylib::KEY_TWO, # Key: 2
47
+ Raylib::KEY_THREE, # Key: 3
48
+ Raylib::KEY_FOUR, # Key: 4
49
+ Raylib::KEY_FIVE, # Key: 5
50
+ Raylib::KEY_SIX, # Key: 6
51
+ Raylib::KEY_SEVEN, # Key: 7
52
+ Raylib::KEY_EIGHT, # Key: 8
53
+ Raylib::KEY_NINE, # Key: 9
54
+ Raylib::KEY_SEMICOLON, # Key: ;
55
+ Raylib::KEY_EQUAL, # Key: =
56
+ Raylib::KEY_A, # Key: A | a
57
+ Raylib::KEY_B, # Key: B | b
58
+ Raylib::KEY_C, # Key: C | c
59
+ Raylib::KEY_D, # Key: D | d
60
+ Raylib::KEY_E, # Key: E | e
61
+ Raylib::KEY_F, # Key: F | f
62
+ Raylib::KEY_G, # Key: G | g
63
+ Raylib::KEY_H, # Key: H | h
64
+ Raylib::KEY_I, # Key: I | i
65
+ Raylib::KEY_J, # Key: J | j
66
+ Raylib::KEY_K, # Key: K | k
67
+ Raylib::KEY_L, # Key: L | l
68
+ Raylib::KEY_M, # Key: M | m
69
+ Raylib::KEY_N, # Key: N | n
70
+ Raylib::KEY_O, # Key: O | o
71
+ Raylib::KEY_P, # Key: P | p
72
+ Raylib::KEY_Q, # Key: Q | q
73
+ Raylib::KEY_R, # Key: R | r
74
+ Raylib::KEY_S, # Key: S | s
75
+ Raylib::KEY_T, # Key: T | t
76
+ Raylib::KEY_U, # Key: U | u
77
+ Raylib::KEY_V, # Key: V | v
78
+ Raylib::KEY_W, # Key: W | w
79
+ Raylib::KEY_X, # Key: X | x
80
+ Raylib::KEY_Y, # Key: Y | y
81
+ Raylib::KEY_Z, # Key: Z | z
82
+ Raylib::KEY_LEFT_BRACKET, # Key: [
83
+ Raylib::KEY_BACKSLASH, # Key: '\'
84
+ Raylib::KEY_RIGHT_BRACKET, # Key: ]
85
+ Raylib::KEY_GRAVE, # Key: `
86
+ # Function keys
87
+ Raylib::KEY_SPACE, # Key: Space
88
+ Raylib::KEY_ESCAPE, # Key: Esc
89
+ Raylib::KEY_ENTER, # Key: Enter
90
+ Raylib::KEY_TAB, # Key: Tab
91
+ Raylib::KEY_BACKSPACE, # Key: Backspace
92
+ Raylib::KEY_INSERT, # Key: Ins
93
+ Raylib::KEY_DELETE, # Key: Del
94
+ Raylib::KEY_RIGHT, # Key: Cursor right
95
+ Raylib::KEY_LEFT, # Key: Cursor left
96
+ Raylib::KEY_DOWN, # Key: Cursor down
97
+ Raylib::KEY_UP, # Key: Cursor up
98
+ Raylib::KEY_PAGE_UP, # Key: Page up
99
+ Raylib::KEY_PAGE_DOWN, # Key: Page down
100
+ Raylib::KEY_HOME, # Key: Home
101
+ Raylib::KEY_END, # Key: End
102
+ Raylib::KEY_CAPS_LOCK, # Key: Caps lock
103
+ Raylib::KEY_SCROLL_LOCK, # Key: Scroll down
104
+ Raylib::KEY_NUM_LOCK, # Key: Num lock
105
+ Raylib::KEY_PRINT_SCREEN, # Key: Print screen
106
+ Raylib::KEY_PAUSE, # Key: Pause
107
+ Raylib::KEY_F1, # Key: F1
108
+ Raylib::KEY_F2, # Key: F2
109
+ Raylib::KEY_F3, # Key: F3
110
+ Raylib::KEY_F4, # Key: F4
111
+ Raylib::KEY_F5, # Key: F5
112
+ Raylib::KEY_F6, # Key: F6
113
+ Raylib::KEY_F7, # Key: F7
114
+ Raylib::KEY_F8, # Key: F8
115
+ Raylib::KEY_F9, # Key: F9
116
+ Raylib::KEY_F10, # Key: F10
117
+ Raylib::KEY_F11, # Key: F11
118
+ Raylib::KEY_F12, # Key: F12
119
+ Raylib::KEY_LEFT_SHIFT, # Key: Shift left
120
+ Raylib::KEY_LEFT_CONTROL, # Key: Control left
121
+ Raylib::KEY_LEFT_ALT, # Key: Alt left
122
+ Raylib::KEY_LEFT_SUPER, # Key: Super left
123
+ Raylib::KEY_RIGHT_SHIFT, # Key: Shift right
124
+ Raylib::KEY_RIGHT_CONTROL, # Key: Control right
125
+ Raylib::KEY_RIGHT_ALT, # Key: Alt right
126
+ Raylib::KEY_RIGHT_SUPER, # Key: Super right
127
+ Raylib::KEY_KB_MENU, # Key: KB menu
128
+ # Keypad keys
129
+ Raylib::KEY_KP_0, # Key: Keypad 0
130
+ Raylib::KEY_KP_1, # Key: Keypad 1
131
+ Raylib::KEY_KP_2, # Key: Keypad 2
132
+ Raylib::KEY_KP_3, # Key: Keypad 3
133
+ Raylib::KEY_KP_4, # Key: Keypad 4
134
+ Raylib::KEY_KP_5, # Key: Keypad 5
135
+ Raylib::KEY_KP_6, # Key: Keypad 6
136
+ Raylib::KEY_KP_7, # Key: Keypad 7
137
+ Raylib::KEY_KP_8, # Key: Keypad 8
138
+ Raylib::KEY_KP_9, # Key: Keypad 9
139
+ Raylib::KEY_KP_DECIMAL, # Key: Keypad .
140
+ Raylib::KEY_KP_DIVIDE, # Key: Keypad /
141
+ Raylib::KEY_KP_MULTIPLY, # Key: Keypad *
142
+ Raylib::KEY_KP_SUBTRACT, # Key: Keypad -
143
+ Raylib::KEY_KP_ADD, # Key: Keypad +
144
+ Raylib::KEY_KP_ENTER, # Key: Keypad Enter
145
+ Raylib::KEY_KP_EQUAL, # Key: Keypad =
146
+ ]
147
+
148
+ # [INTERNAL]
149
+ def self.ImGui_ImplRaylib_KeyToImGuiKey(key)
150
+ case key
151
+ when Raylib::KEY_TAB then ImGuiKey_Tab
152
+ when Raylib::KEY_LEFT then ImGuiKey_LeftArrow
153
+ when Raylib::KEY_RIGHT then ImGuiKey_RightArrow
154
+ when Raylib::KEY_UP then ImGuiKey_UpArrow
155
+ when Raylib::KEY_DOWN then ImGuiKey_DownArrow
156
+ when Raylib::KEY_PAGE_UP then ImGuiKey_PageUp
157
+ when Raylib::KEY_PAGE_DOWN then ImGuiKey_PageDown
158
+ when Raylib::KEY_HOME then ImGuiKey_Home
159
+ when Raylib::KEY_END then ImGuiKey_End
160
+ when Raylib::KEY_INSERT then ImGuiKey_Insert
161
+ when Raylib::KEY_DELETE then ImGuiKey_Delete
162
+ when Raylib::KEY_BACKSPACE then ImGuiKey_Backspace
163
+ when Raylib::KEY_SPACE then ImGuiKey_Space
164
+ when Raylib::KEY_ENTER then ImGuiKey_Enter
165
+ when Raylib::KEY_ESCAPE then ImGuiKey_Escape
166
+ when Raylib::KEY_APOSTROPHE then ImGuiKey_Apostrophe
167
+ when Raylib::KEY_COMMA then ImGuiKey_Comma
168
+ when Raylib::KEY_MINUS then ImGuiKey_Minus
169
+ when Raylib::KEY_PERIOD then ImGuiKey_Period
170
+ when Raylib::KEY_SLASH then ImGuiKey_Slash
171
+ when Raylib::KEY_SEMICOLON then ImGuiKey_Semicolon
172
+ when Raylib::KEY_EQUAL then ImGuiKey_Equal
173
+ when Raylib::KEY_LEFT_BRACKET then ImGuiKey_LeftBracket
174
+ when Raylib::KEY_BACKSLASH then ImGuiKey_Backslash
175
+ when Raylib::KEY_RIGHT_BRACKET then ImGuiKey_RightBracket
176
+ when Raylib::KEY_GRAVE then ImGuiKey_GraveAccent
177
+ when Raylib::KEY_CAPS_LOCK then ImGuiKey_CapsLock
178
+ when Raylib::KEY_SCROLL_LOCK then ImGuiKey_ScrollLock
179
+ when Raylib::KEY_NUM_LOCK then ImGuiKey_NumLock
180
+ when Raylib::KEY_PRINT_SCREEN then ImGuiKey_PrintScreen
181
+ when Raylib::KEY_PAUSE then ImGuiKey_Pause
182
+ when Raylib::KEY_KP_0 then ImGuiKey_Keypad0
183
+ when Raylib::KEY_KP_1 then ImGuiKey_Keypad1
184
+ when Raylib::KEY_KP_2 then ImGuiKey_Keypad2
185
+ when Raylib::KEY_KP_3 then ImGuiKey_Keypad3
186
+ when Raylib::KEY_KP_4 then ImGuiKey_Keypad4
187
+ when Raylib::KEY_KP_5 then ImGuiKey_Keypad5
188
+ when Raylib::KEY_KP_6 then ImGuiKey_Keypad6
189
+ when Raylib::KEY_KP_7 then ImGuiKey_Keypad7
190
+ when Raylib::KEY_KP_8 then ImGuiKey_Keypad8
191
+ when Raylib::KEY_KP_9 then ImGuiKey_Keypad9
192
+ when Raylib::KEY_KP_DECIMAL then ImGuiKey_KeypadDecimal
193
+ when Raylib::KEY_KP_DIVIDE then ImGuiKey_KeypadDivide
194
+ when Raylib::KEY_KP_MULTIPLY then ImGuiKey_KeypadMultiply
195
+ when Raylib::KEY_KP_SUBTRACT then ImGuiKey_KeypadSubtract
196
+ when Raylib::KEY_KP_ADD then ImGuiKey_KeypadAdd
197
+ when Raylib::KEY_KP_ENTER then ImGuiKey_KeypadEnter
198
+ when Raylib::KEY_KP_EQUAL then ImGuiKey_KeypadEqual
199
+ when Raylib::KEY_LEFT_CONTROL then ImGuiKey_LeftCtrl
200
+ when Raylib::KEY_LEFT_SHIFT then ImGuiKey_LeftShift
201
+ when Raylib::KEY_LEFT_ALT then ImGuiKey_LeftAlt
202
+ when Raylib::KEY_LEFT_SUPER then ImGuiKey_LeftSuper
203
+ when Raylib::KEY_RIGHT_CONTROL then ImGuiKey_RightCtrl
204
+ when Raylib::KEY_RIGHT_SHIFT then ImGuiKey_RightShift
205
+ when Raylib::KEY_RIGHT_ALT then ImGuiKey_RightAlt
206
+ when Raylib::KEY_RIGHT_SUPER then ImGuiKey_RightSuper
207
+ when Raylib::KEY_MENU then ImGuiKey_Menu
208
+ when Raylib::KEY_ZERO then ImGuiKey_0
209
+ when Raylib::KEY_ONE then ImGuiKey_1
210
+ when Raylib::KEY_TWO then ImGuiKey_2
211
+ when Raylib::KEY_THREE then ImGuiKey_3
212
+ when Raylib::KEY_FOUR then ImGuiKey_4
213
+ when Raylib::KEY_FIVE then ImGuiKey_5
214
+ when Raylib::KEY_SIX then ImGuiKey_6
215
+ when Raylib::KEY_SEVEN then ImGuiKey_7
216
+ when Raylib::KEY_EIGHT then ImGuiKey_8
217
+ when Raylib::KEY_NINE then ImGuiKey_9
218
+ when Raylib::KEY_A then ImGuiKey_A
219
+ when Raylib::KEY_B then ImGuiKey_B
220
+ when Raylib::KEY_C then ImGuiKey_C
221
+ when Raylib::KEY_D then ImGuiKey_D
222
+ when Raylib::KEY_E then ImGuiKey_E
223
+ when Raylib::KEY_F then ImGuiKey_F
224
+ when Raylib::KEY_G then ImGuiKey_G
225
+ when Raylib::KEY_H then ImGuiKey_H
226
+ when Raylib::KEY_I then ImGuiKey_I
227
+ when Raylib::KEY_J then ImGuiKey_J
228
+ when Raylib::KEY_K then ImGuiKey_K
229
+ when Raylib::KEY_L then ImGuiKey_L
230
+ when Raylib::KEY_M then ImGuiKey_M
231
+ when Raylib::KEY_N then ImGuiKey_N
232
+ when Raylib::KEY_O then ImGuiKey_O
233
+ when Raylib::KEY_P then ImGuiKey_P
234
+ when Raylib::KEY_Q then ImGuiKey_Q
235
+ when Raylib::KEY_R then ImGuiKey_R
236
+ when Raylib::KEY_S then ImGuiKey_S
237
+ when Raylib::KEY_T then ImGuiKey_T
238
+ when Raylib::KEY_U then ImGuiKey_U
239
+ when Raylib::KEY_V then ImGuiKey_V
240
+ when Raylib::KEY_W then ImGuiKey_W
241
+ when Raylib::KEY_X then ImGuiKey_X
242
+ when Raylib::KEY_Y then ImGuiKey_Y
243
+ when Raylib::KEY_Z then ImGuiKey_Z
244
+ when Raylib::KEY_F1 then ImGuiKey_F1
245
+ when Raylib::KEY_F2 then ImGuiKey_F2
246
+ when Raylib::KEY_F3 then ImGuiKey_F3
247
+ when Raylib::KEY_F4 then ImGuiKey_F4
248
+ when Raylib::KEY_F5 then ImGuiKey_F5
249
+ when Raylib::KEY_F6 then ImGuiKey_F6
250
+ when Raylib::KEY_F7 then ImGuiKey_F7
251
+ when Raylib::KEY_F8 then ImGuiKey_F8
252
+ when Raylib::KEY_F9 then ImGuiKey_F9
253
+ when Raylib::KEY_F10 then ImGuiKey_F10
254
+ when Raylib::KEY_F11 then ImGuiKey_F11
255
+ when Raylib::KEY_F12 then ImGuiKey_F12
256
+ else ImGuiKey_None
257
+ end
258
+ end
259
+
260
+ # [INTERNAL]
261
+ def self.ImGui_ImplRaylib_UpdateKeyModifiers()
262
+ io = ImGuiIO.new(ImGui::GetIO())
263
+ io.AddKeyEvent(ImGuiKey_ModCtrl, Raylib.IsKeyDown(Raylib::KEY_RIGHT_CONTROL) || Raylib.IsKeyDown(Raylib::KEY_LEFT_CONTROL))
264
+ io.AddKeyEvent(ImGuiKey_ModShift, Raylib.IsKeyDown(Raylib::KEY_RIGHT_SHIFT) || Raylib.IsKeyDown(Raylib::KEY_LEFT_SHIFT))
265
+ io.AddKeyEvent(ImGuiKey_ModAlt, Raylib.IsKeyDown(Raylib::KEY_RIGHT_ALT) || Raylib.IsKeyDown(Raylib::KEY_LEFT_ALT))
266
+ io.AddKeyEvent(ImGuiKey_ModSuper, Raylib.IsKeyDown(Raylib::KEY_RIGHT_SUPER) || Raylib.IsKeyDown(Raylib::KEY_LEFT_SUPER))
267
+ end
268
+
269
+ def self.ImplRaylib_ProcessKeyboard()
270
+ io = ImGuiIO.new(ImGui::GetIO())
271
+
272
+ ImGui_ImplRaylib_UpdateKeyModifiers()
273
+
274
+ KEY_IDS.each do |raylib_key|
275
+ if Raylib.IsKeyPressed(raylib_key)
276
+ key = ImGui_ImplRaylib_KeyToImGuiKey(raylib_key)
277
+ io.AddKeyEvent(key, true)
278
+ elsif Raylib.IsKeyReleased(raylib_key)
279
+ key = ImGui_ImplRaylib_KeyToImGuiKey(raylib_key)
280
+ io.AddKeyEvent(key, false)
281
+ end
282
+ end
283
+
284
+ while (charPressed = Raylib.GetCharPressed()) != 0
285
+ io.AddInputCharacter(charPressed)
286
+ end
287
+
288
+ return true
289
+ end
290
+
291
+ # [INTERNAL]
292
+ def self.ImplRaylib_UpdateMouseData()
293
+ bd = ImGui_ImplRaylib_GetBackendData()
294
+ io = ImGuiIO.new(ImGui::GetIO())
295
+
296
+ # Set OS mouse position if requested (rarely used, only when ImGuiConfigFlags_NavEnableSetMousePos is enabled by user)
297
+ if io[:WantSetMousePos]
298
+ Raylib.SetMousePosition(io[:MousePos][:x].to_i, io[:MousePos][:y].to_i)
299
+ end
300
+
301
+ wheel_move = Raylib.GetMouseWheelMove()
302
+ wheel_y = if wheel_move > 0
303
+ 1.0
304
+ elsif wheel_move < 0
305
+ -1.0
306
+ else
307
+ 0.0
308
+ end
309
+ io.AddMouseWheelEvent(0, wheel_y) # [TODO] Get wheel tilt from Raylib
310
+
311
+ [Raylib::MOUSE_BUTTON_LEFT, Raylib::MOUSE_BUTTON_RIGHT, Raylib::MOUSE_BUTTON_MIDDLE].each_with_index do |button, mouse_button|
312
+ pressed = Raylib.IsMouseButtonPressed(button)
313
+ released = Raylib.IsMouseButtonReleased(button)
314
+ if pressed || released
315
+ io.AddMouseButtonEvent(mouse_button, pressed)
316
+ end
317
+ end
318
+
319
+ mouse_pos = Raylib.GetMousePosition()
320
+ io.AddMousePosEvent(mouse_pos[:x].to_f, mouse_pos[:y].to_f)
321
+ end
322
+
323
+ # [INTERNAL]
324
+ def self.ImplRaylib_UpdateMouseCursor()
325
+ io = ImGuiIO.new(ImGui::GetIO())
326
+ return if (io[:ConfigFlags] & ImGuiConfigFlags_NoMouseCursorChange)
327
+
328
+ if io[:MouseDrawCursor] || ImGui::GetMouseCursor() == ImGuiMouseCursor_None
329
+ Raylib.HideCursor() # Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
330
+ else
331
+ Raylib.ShowCursor() # Show OS mouse cursor
332
+ end
333
+ end
334
+
335
+ #
336
+ # [TODO] Support ImplRaylib_UpdateGamepads
337
+ #
338
+
339
+ def self.ImplRaylib_Init()
340
+ # Setup backend capabilities flags
341
+ bd = ImGui_ImplRaylib_Data.new
342
+ @@g_BackendData[ImGui::GetCurrentContext().address] = bd
343
+
344
+ io = ImGuiIO.new(ImGui::GetIO())
345
+
346
+ io[:BackendPlatformUserData] = nil
347
+ io[:BackendPlatformName] = @@g_BackendPlatformName
348
+ io[:BackendFlags] |= ImGuiBackendFlags_HasMouseCursors # We can honor GetMouseCursor() values (optional)
349
+ io[:BackendFlags] |= ImGuiBackendFlags_HasSetMousePos # We can honor io.WantSetMousePos requests (optional, rarely used)
350
+
351
+ bd.time = 0.0
352
+
353
+ return true
354
+ end
355
+
356
+ def self.ImplRaylib_Shutdown()
357
+ io = ImGuiIO.new(ImGui::GetIO())
358
+ io[:BackendPlatformName] = nil
359
+ io[:BackendPlatformUserData] = nil
360
+ @@g_BackendData[ImGui::GetCurrentContext()] = nil
361
+ end
362
+
363
+ def self.ImplRaylib_NewFrame()
364
+ bd = ImGui_ImplRaylib_GetBackendData()
365
+ io = ImGuiIO.new(ImGui::GetIO())
366
+
367
+ # Setup display size (every frame to accommodate for window resizing)
368
+ io[:DisplaySize][:x] = Raylib.GetScreenWidth()
369
+ io[:DisplaySize][:y] = Raylib.GetScreenHeight()
370
+
371
+ # Setup time step
372
+ current_time = Raylib.GetTime()
373
+
374
+ io[:DeltaTime] = bd.time > 0 ? (current_time - bd.time).to_f : 1.0 / 60.0
375
+ bd.time = current_time
376
+
377
+ ImplRaylib_ProcessKeyboard()
378
+ ImplRaylib_UpdateMouseData()
379
+ ImplRaylib_UpdateMouseCursor()
380
+
381
+ # [TODO] update gamepads
382
+
383
+ # [NOTE] rlgl does not provide glBlendFuncSeparate wrapper. So we manually set states for ImGui here.
384
+ # Ref.: https://github.com/vaiorabbit/ruby-imgui/blob/05e94e6bf1969d3abf12598fef831219dca90247/lib/imgui_impl_opengl3.rb#L227-L234
385
+ # [TODO] Hide raw OpenGL operation
386
+ GL.BlendFuncSeparate(GL::SRC_ALPHA, GL::ONE_MINUS_SRC_ALPHA, GL::ONE, GL::ONE_MINUS_SRC_ALPHA)
387
+ end
388
+
389
+ # [INTERNAL]
390
+ def self.set_vertex(xy, uv, color)
391
+ Raylib.rlColor4ub(color[0], color[1], color[2], color[3])
392
+ Raylib.rlTexCoord2f(uv[0], uv[1])
393
+ Raylib.rlVertex2f(xy[0], xy[1])
394
+ end
395
+
396
+ def self.ImplRaylib_RenderDrawData(draw_data_raw)
397
+ draw_data = ImDrawData.new(draw_data_raw)
398
+ Raylib.rlDisableBackfaceCulling()
399
+
400
+ clip_offset = draw_data[:DisplayPos]
401
+ draw_data[:CmdListsCount].times do |n|
402
+ cmd_list = ImDrawList.new((draw_data[:CmdLists].pointer + FFI.type_size(:pointer) * n).read_pointer)
403
+ vtx_buffer = cmd_list[:VtxBuffer][:Data] # const ImDrawVert*
404
+ idx_buffer = cmd_list[:IdxBuffer][:Data] # const ImDrawIdx*
405
+
406
+ cmd_list[:CmdBuffer][:Size].times do |cmd_i|
407
+ pcmd = ImDrawCmd.new(cmd_list[:CmdBuffer][:Data] + ImDrawCmd.size * cmd_i) # const ImDrawCmd*
408
+ if pcmd[:UserCallback] != nil
409
+ # [TODO] Handle user callback (Ref.: https://github.com/ffi/ffi/wiki/Callbacks )
410
+ else
411
+ rect_min_x = (pcmd[:ClipRect][:x] - clip_offset[:x])
412
+ rect_min_y = (pcmd[:ClipRect][:y] - clip_offset[:y])
413
+ rect_max_x = (pcmd[:ClipRect][:z] - clip_offset[:x])
414
+ rect_max_y = (pcmd[:ClipRect][:w] - clip_offset[:y])
415
+
416
+ rect_w = rect_max_x - rect_min_x
417
+ rect_h = rect_max_y - rect_min_y
418
+
419
+ Raylib.BeginScissorMode(rect_min_x, rect_min_y, rect_w, rect_h)
420
+
421
+ # Render triangles
422
+ indices = idx_buffer + FFI.type_size(:ImDrawIdx) * pcmd[:IdxOffset]
423
+ vertices = vtx_buffer + ImDrawVert.size * pcmd[:VtxOffset]
424
+ 0.step(pcmd[:ElemCount] - 3, 3) do |i|
425
+ Raylib.rlPushMatrix()
426
+ Raylib.rlBegin(Raylib::RL_TRIANGLES)
427
+ Raylib.rlSetTexture(pcmd[:TextureId].read_uint32)
428
+
429
+ index = indices.get_array_of_uint16(i * FFI::type_size(:ImDrawIdx), 3)
430
+
431
+ base_offset = ImDrawVert.size * index[0]
432
+ xy = vertices + (base_offset + ImDrawVert.offset_of(:pos))
433
+ uv = vertices + (base_offset + ImDrawVert.offset_of(:uv))
434
+ color = vertices + (base_offset + ImDrawVert.offset_of(:col))
435
+ set_vertex(xy.read_array_of_float(2), uv.read_array_of_float(2), color.read_array_of_uint8(4))
436
+
437
+ base_offset = ImDrawVert.size * index[2]
438
+ xy = vertices + (base_offset + ImDrawVert.offset_of(:pos))
439
+ uv = vertices + (base_offset + ImDrawVert.offset_of(:uv))
440
+ color = vertices + (base_offset + ImDrawVert.offset_of(:col))
441
+ set_vertex(xy.read_array_of_float(2), uv.read_array_of_float(2), color.read_array_of_uint8(4))
442
+
443
+ base_offset = ImDrawVert.size * index[1]
444
+ xy = vertices + (base_offset + ImDrawVert.offset_of(:pos))
445
+ uv = vertices + (base_offset + ImDrawVert.offset_of(:uv))
446
+ color = vertices + (base_offset + ImDrawVert.offset_of(:col))
447
+ set_vertex(xy.read_array_of_float(2), uv.read_array_of_float(2), color.read_array_of_uint8(4))
448
+
449
+ Raylib.rlSetTexture(0)
450
+ Raylib.rlEnd()
451
+ Raylib.rlPopMatrix()
452
+ end
453
+ Raylib.EndScissorMode()
454
+ end
455
+ end
456
+ end
457
+ Raylib.rlEnableBackfaceCulling()
458
+ end
459
+
460
+ end