imgui-bindings 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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