imgui-bindings 0.0.1

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
Binary file
@@ -0,0 +1,240 @@
1
+ require 'ffi'
2
+ require 'opengl'
3
+ require 'glfw'
4
+
5
+ require_relative 'imgui'
6
+
7
+ module ImGui
8
+
9
+ @@g_Window = nil # GLFWwindow*
10
+ @@g_Time = 0.0 # double
11
+ @@g_MouseWindow = nil # GLFWwindow*
12
+ @@g_MouseJustPressed = [false, false, false, false, false]
13
+ @@g_MouseCursors = Array.new(ImGuiMouseCursor_COUNT) { 0 }
14
+
15
+ @@g_BackendPlatformName = FFI::MemoryPointer.from_string("imgui_impl_glfw")
16
+
17
+ # Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any.
18
+ @@g_PrevUserCallbackCursorEnter = nil
19
+ @@g_PrevUserCallbackMousebutton = nil
20
+ @@g_PrevUserCallbackScroll = nil
21
+ @@g_PrevUserCallbackKey = nil
22
+ @@g_PrevUserCallbackChar = nil
23
+
24
+ @@ImplGlfw_MouseButtonCallback = GLFW::create_callback(:GLFWmousebuttonfun) do |window, button, action, mods|
25
+ unless @@g_PrevUserCallbackMousebutton.null?
26
+ userfunc = Fiddle::Function.new(@@g_PrevUserCallbackMousebutton, GLFWmousebuttonfun_cb_args, GLFWmousebuttonfun_cb_retval)
27
+ userfunc.call(window, button, action, mods)
28
+ end
29
+
30
+ if action == GLFW_PRESS && button >= 0 && button < @@g_MouseJustPressed.size
31
+ @@g_MouseJustPressed[button] = true
32
+ end
33
+ end
34
+
35
+ @@ImplGlfw_ScrollCallback = GLFW::create_callback(:GLFWscrollfun) do |window, xoffset, yoffset|
36
+ unless @@g_PrevUserCallbackScroll.null?
37
+ userfunc = Fiddle::Function.new(@@g_PrevUserCallbackScroll, GLFWscrollfun_cb_args, GLFWscrollfun_cb_retval)
38
+ userfunc.call(window, xoffset, yoffset)
39
+ end
40
+
41
+ io = ImGuiIO.new(ImGui::GetIO())
42
+ io[:MouseWheelH] += xoffset.to_f
43
+ io[:MouseWheel] += yoffset.to_f
44
+ end
45
+
46
+ @@ImplGlfw_KeyCallback = GLFW::create_callback(:GLFWkeyfun) do |window, key, scancode, action, mods|
47
+ unless @@g_PrevUserCallbackKey.null?
48
+ userfunc = Fiddle::Function.new(@@g_PrevUserCallbackKey, GLFWkeyfun_cb_args, GLFWkeyfun_cb_retval)
49
+ userfunc.call(window, key, scancode, action, mods)
50
+ end
51
+
52
+ io = ImGuiIO.new(ImGui::GetIO())
53
+ io[:KeysDown][key] = true if action == GLFW_PRESS
54
+ io[:KeysDown][key] = false if action == GLFW_RELEASE
55
+
56
+ # Modifiers are not reliable across systems
57
+ io[:KeyCtrl] = io[:KeysDown][GLFW_KEY_LEFT_CONTROL] || io[:KeysDown][GLFW_KEY_RIGHT_CONTROL]
58
+ io[:KeyShift] = io[:KeysDown][GLFW_KEY_LEFT_SHIFT] || io[:KeysDown][GLFW_KEY_RIGHT_SHIFT]
59
+ io[:KeyAlt] = io[:KeysDown][GLFW_KEY_LEFT_ALT] || io[:KeysDown][GLFW_KEY_RIGHT_ALT]
60
+ io[:KeySuper] = io[:KeysDown][GLFW_KEY_LEFT_SUPER] || io[:KeysDown][GLFW_KEY_RIGHT_SUPER]
61
+ end
62
+
63
+ @@ImGui_ImplGlfw_CursorEnterCallback = GLFW::create_callback(:GLFWcursorenterfun) do |window, entered|
64
+ unless @@g_PrevUserCallbackCursorEnter.null?
65
+ userfunc = Fiddle::Function.new(@@g_PrevUserCallbackCursorEnter, GLFWcursorenterfun_cb_args, GLFWcursorenterfun_cb_retval)
66
+ userfunc.call(window, entered)
67
+ end
68
+
69
+ @@g_MouseWindow = window if entered
70
+ @@g_MouseWindow = nil if (!entered && @@g_MouseWindow == window)
71
+ end
72
+
73
+ @@ImplGlfw_CharCallback = GLFW::create_callback(:GLFWcharfun) do |window, c|
74
+ unless @@g_PrevUserCallbackChar.null?
75
+ @@g_PrevUserCallbackChar.call(window, c)
76
+ end
77
+
78
+ io = ImGuiIO.new(ImGui::GetIO())
79
+ io.AddInputCharacter(c);
80
+ end
81
+
82
+ def self.ImplGlfw_UpdateMousePosAndButtons()
83
+ # Update buttons
84
+ io = ImGuiIO.new(ImGui::GetIO())
85
+ io[:MouseDown].size.times do |i|
86
+ # If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame.
87
+ io[:MouseDown][i] = (@@g_MouseJustPressed[i] || glfwGetMouseButton(@@g_Window, i) != 0)
88
+ @@g_MouseJustPressed[i] = false
89
+ end
90
+
91
+ focused = glfwGetWindowAttrib(@@g_Window, GLFW_FOCUSED) != 0
92
+ mouse_window = (@@g_MouseWindow == @@g_Window || focused) ? @@g_Window : nil
93
+
94
+ # Update mouse position
95
+ mouse_pos_backup = io[:MousePos]
96
+ io[:MousePos][:x] = -Float::MAX
97
+ io[:MousePos][:y] = -Float::MAX
98
+ if io[:WantSetMousePos]
99
+ if focused
100
+ glfwSetCursorPos(@@g_Window, mouse_pos_backup[:x].to_f, mouse_pos_backup[:y].to_f)
101
+ end
102
+ elsif @@g_MouseWindow != nil
103
+ mouse_x = ' ' * 8
104
+ mouse_y = ' ' * 8
105
+ glfwGetCursorPos(@@g_Window, mouse_x, mouse_y)
106
+ io[:MousePos][:x] = mouse_x.unpack1('d')
107
+ io[:MousePos][:y] = mouse_y.unpack1('d')
108
+ end
109
+ end
110
+
111
+ def self.ImplGlfw_UpdateMouseCursor()
112
+ io = ImGuiIO.new(ImGui::GetIO())
113
+ return if ((io[:ConfigFlags] & ImGuiConfigFlags_NoMouseCursorChange) || glfwGetInputMode(@@g_Window, GLFW_CURSOR) == GLFW_CURSOR_DISABLED)
114
+
115
+ imgui_cursor = ImGui::GetMouseCursor()
116
+ if imgui_cursor == ImGuiMouseCursor_None || io[:MouseDrawCursor]
117
+ # Hide OS mouse cursor if imgui is drawing it or if it wants no cursor
118
+ glfwSetInputMode(@@g_Window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN)
119
+ else
120
+ # Show OS mouse cursor
121
+ # FIXME-PLATFORM: Unfocused windows seems to fail changing the mouse cursor with GLFW 3.2, but 3.3 works here.
122
+ glfwSetCursor(@@g_Window, @@g_MouseCursors[imgui_cursor] ? @@g_MouseCursors[imgui_cursor] : @@g_MouseCursors[ImGuiMouseCursor_Arrow])
123
+ glfwSetInputMode(@@g_Window, GLFW_CURSOR, GLFW_CURSOR_NORMAL)
124
+ end
125
+ end
126
+
127
+ def self.ImplGlfw_InitForOpenGL(window, install_callbacks)
128
+ return ImplGlfw_Init(window, install_callbacks, :GlfwClientApi_OpenGL)
129
+ end
130
+
131
+ def self.ImplGlfw_Shutdown()
132
+ ImGuiMouseCursor_COUNT.times do |cursor_n|
133
+ glfwDestroyCursor(@@g_MouseCursors[cursor_n])
134
+ @@g_MouseCursors[cursor_n] = nil
135
+ end
136
+ end
137
+
138
+ def self.ImplGlfw_NewFrame()
139
+ io = ImGuiIO.new(ImGui::GetIO())
140
+ unless io[:Fonts].IsBuilt()
141
+ 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()."
142
+ end
143
+
144
+ # Setup display size (every frame to accommodate for window resizing)
145
+ w = ' ' * 4
146
+ h = ' ' * 4
147
+ display_w = ' ' * 4
148
+ display_h = ' ' * 4
149
+ glfwGetWindowSize(@@g_Window, w, h)
150
+ glfwGetFramebufferSize(@@g_Window, display_w, display_h)
151
+
152
+ w = w.unpack1('L')
153
+ h = h.unpack1('L')
154
+ io[:DisplaySize][:x] = w
155
+ io[:DisplaySize][:y] = h
156
+
157
+ if w > 0 && h > 0
158
+ io[:DisplayFramebufferScale][:x] = display_w.unpack1('L') / w
159
+ io[:DisplayFramebufferScale][:y] = display_h.unpack1('L') / h
160
+ end
161
+
162
+ # Setup time step
163
+ current_time = glfwGetTime()
164
+ io[:DeltaTime] = @@g_Time > 0.0 ? (current_time - @@g_Time).to_f : (1.0/60.0)
165
+ @@g_Time = current_time
166
+
167
+ ImplGlfw_UpdateMousePosAndButtons()
168
+ ImplGlfw_UpdateMouseCursor()
169
+ # TODO update gamepads
170
+ end
171
+
172
+ # private
173
+
174
+ def self.ImplGlfw_Init(window, install_callbacks, client_api)
175
+ @@g_Window = window
176
+ @@g_Time = 0.0
177
+
178
+ io = ImGuiIO.new(ImGui::GetIO())
179
+ io[:BackendFlags] |= ImGuiBackendFlags_HasMouseCursors # We can honor GetMouseCursor() values (optional)
180
+ io[:BackendFlags] |= ImGuiBackendFlags_HasSetMousePos # We can honor io.WantSetMousePos requests (optional, rarely used)
181
+ io[:BackendPlatformName] = @@g_BackendPlatformName
182
+
183
+ # Keyboard mapping. ImGui will use those indices to peek into the io.KeysDown[] array.
184
+ io[:KeyMap][ImGuiKey_Tab] = GLFW_KEY_TAB
185
+ io[:KeyMap][ImGuiKey_LeftArrow] = GLFW_KEY_LEFT
186
+ io[:KeyMap][ImGuiKey_RightArrow] = GLFW_KEY_RIGHT
187
+ io[:KeyMap][ImGuiKey_UpArrow] = GLFW_KEY_UP
188
+ io[:KeyMap][ImGuiKey_DownArrow] = GLFW_KEY_DOWN
189
+ io[:KeyMap][ImGuiKey_PageUp] = GLFW_KEY_PAGE_UP
190
+ io[:KeyMap][ImGuiKey_PageDown] = GLFW_KEY_PAGE_DOWN
191
+ io[:KeyMap][ImGuiKey_Home] = GLFW_KEY_HOME
192
+ io[:KeyMap][ImGuiKey_End] = GLFW_KEY_END
193
+ io[:KeyMap][ImGuiKey_Insert] = GLFW_KEY_INSERT
194
+ io[:KeyMap][ImGuiKey_Delete] = GLFW_KEY_DELETE
195
+ io[:KeyMap][ImGuiKey_Backspace] = GLFW_KEY_BACKSPACE
196
+ io[:KeyMap][ImGuiKey_Space] = GLFW_KEY_SPACE
197
+ io[:KeyMap][ImGuiKey_Enter] = GLFW_KEY_ENTER
198
+ io[:KeyMap][ImGuiKey_Escape] = GLFW_KEY_ESCAPE
199
+ io[:KeyMap][ImGuiKey_KeyPadEnter] = GLFW_KEY_KP_ENTER
200
+ io[:KeyMap][ImGuiKey_A] = GLFW_KEY_A
201
+ io[:KeyMap][ImGuiKey_C] = GLFW_KEY_C
202
+ io[:KeyMap][ImGuiKey_V] = GLFW_KEY_V
203
+ io[:KeyMap][ImGuiKey_X] = GLFW_KEY_X
204
+ io[:KeyMap][ImGuiKey_Y] = GLFW_KEY_Y
205
+ io[:KeyMap][ImGuiKey_Z] = GLFW_KEY_Z
206
+
207
+ # [TODO] Support ClipboardText & IME on Windows
208
+ # io.SetClipboardTextFn = ImGui_ImplGlfw_SetClipboardText;
209
+ # io.GetClipboardTextFn = ImGui_ImplGlfw_GetClipboardText;
210
+ # io.ClipboardUserData = g_Window;
211
+ # #if defined(_WIN32)
212
+ # io.ImeWindowHandle = (void*)glfwGetWin32Window(g_Window);
213
+ # #endif
214
+
215
+ @@g_MouseCursors[ImGuiMouseCursor_Arrow] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR)
216
+ @@g_MouseCursors[ImGuiMouseCursor_TextInput] = glfwCreateStandardCursor(GLFW_IBEAM_CURSOR)
217
+ @@g_MouseCursors[ImGuiMouseCursor_ResizeAll] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR) # FIXME: GLFW doesn't have this.
218
+ @@g_MouseCursors[ImGuiMouseCursor_ResizeNS] = glfwCreateStandardCursor(GLFW_VRESIZE_CURSOR)
219
+ @@g_MouseCursors[ImGuiMouseCursor_ResizeEW] = glfwCreateStandardCursor(GLFW_HRESIZE_CURSOR)
220
+ @@g_MouseCursors[ImGuiMouseCursor_ResizeNESW] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR) # FIXME: GLFW doesn't have this.
221
+ @@g_MouseCursors[ImGuiMouseCursor_ResizeNWSE] = glfwCreateStandardCursor(GLFW_ARROW_CURSOR) # FIXME: GLFW doesn't have this.
222
+ @@g_MouseCursors[ImGuiMouseCursor_Hand] = glfwCreateStandardCursor(GLFW_HAND_CURSOR)
223
+
224
+ # Chain GLFW callbacks: our callbacks will call the user's previously installed callbacks, if any.
225
+ @@g_PrevUserCallbackMousebutton = nil
226
+ @@g_PrevUserCallbackScroll = nil
227
+ @@g_PrevUserCallbackKey = nil
228
+ @@g_PrevUserCallbackChar = nil
229
+ if install_callbacks
230
+ @@g_PrevUserCallbackCursorEnter = glfwSetCursorEnterCallback(window, @@ImGui_ImplGlfw_CursorEnterCallback)
231
+ @@g_PrevUserCallbackMousebutton = glfwSetMouseButtonCallback(window, @@ImplGlfw_MouseButtonCallback)
232
+ @@g_PrevUserCallbackScroll = glfwSetScrollCallback(window, @@ImplGlfw_ScrollCallback)
233
+ @@g_PrevUserCallbackKey = glfwSetKeyCallback(window, @@ImplGlfw_KeyCallback)
234
+ @@g_PrevUserCallbackChar = glfwSetCharCallback(window, @@ImplGlfw_CharCallback)
235
+ end
236
+
237
+ return true
238
+ end
239
+
240
+ end
@@ -0,0 +1,213 @@
1
+ require 'ffi'
2
+ require 'opengl'
3
+ include OpenGL
4
+
5
+ require_relative 'imgui'
6
+
7
+ module ImGui
8
+
9
+ @@g_FontTexture = nil
10
+ @@g_BackendRendererName = FFI::MemoryPointer.from_string("imgui_impl_opengl2")
11
+
12
+ def self.ImplOpenGL2_Init()
13
+ io = ImGuiIO.new(ImGui::GetIO())
14
+ io[:BackendRendererName] = @@g_BackendRendererName
15
+
16
+ return true
17
+ end
18
+
19
+ def self.ImplOpenGL2_Shutdown()
20
+ ImplOpenGL2_DestroyDeviceObjects()
21
+ end
22
+
23
+ def self.ImplOpenGL2_NewFrame()
24
+ ImplOpenGL2_CreateDeviceObjects() if @@g_FontTexture == nil
25
+ end
26
+
27
+ def self.ImplOpenGL2_RenderDrawData(draw_data_raw)
28
+ # Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
29
+ draw_data = ImDrawData.new(draw_data_raw)
30
+ fb_width = (draw_data[:DisplaySize][:x] * draw_data[:FramebufferScale][:x]).to_i
31
+ fb_height = (draw_data[:DisplaySize][:y] * draw_data[:FramebufferScale][:y]).to_i
32
+
33
+ return if fb_width == 0 || fb_height == 0
34
+
35
+ # Backup GL state
36
+ last_texture = ' ' * 4
37
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, last_texture)
38
+ last_polygon_mode = ' ' * 8
39
+ glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode)
40
+ last_viewport = ' ' * 16
41
+ glGetIntegerv(GL_VIEWPORT, last_viewport)
42
+ last_scissor_box = ' ' * 16
43
+ glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box)
44
+ glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_TRANSFORM_BIT)
45
+ last_shade_model = ' ' * 4
46
+ glGetIntegerv(GL_SHADE_MODEL, last_shade_model)
47
+ last_tex_env_mode = ' ' * 4
48
+ glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, last_tex_env_mode)
49
+
50
+ # Setup desired GL state
51
+ ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height)
52
+
53
+ # Will project scissor/clipping rectangles into framebuffer space
54
+ clip_off = draw_data[:DisplayPos] # (0,0) unless using multi-viewports
55
+ clip_scale = draw_data[:FramebufferScale] # (1,1) unless using retina display which are often (2,2)
56
+
57
+ # Render command lists
58
+ draw_data[:CmdListsCount].times do |n|
59
+ cmd_list = ImDrawList.new((draw_data[:CmdLists].pointer + 8 * n).read_pointer) # 8 == const ImDrawList*
60
+ vtx_buffer = ImDrawVert.new(cmd_list[:VtxBuffer][:Data]) # const ImDrawVert*
61
+ idx_buffer = cmd_list[:IdxBuffer][:Data] # const ImDrawIdx*
62
+ glVertexPointer(2, GL_FLOAT, ImDrawVert.size, Fiddle::Pointer.new((cmd_list[:VtxBuffer][:Data] + vtx_buffer.offset_of(:pos))) )
63
+ glTexCoordPointer(2, GL_FLOAT, ImDrawVert.size, Fiddle::Pointer.new((cmd_list[:VtxBuffer][:Data] + vtx_buffer.offset_of(:uv))) )
64
+ glColorPointer(4, GL_UNSIGNED_BYTE, ImDrawVert.size, Fiddle::Pointer.new((cmd_list[:VtxBuffer][:Data] + vtx_buffer.offset_of(:col))) )
65
+
66
+ cmd_list[:CmdBuffer][:Size].times do |cmd_i|
67
+ pcmd = ImDrawCmd.new(cmd_list[:CmdBuffer][:Data] + ImDrawCmd.size * cmd_i) # const ImDrawCmd*
68
+ if pcmd[:UserCallback] != nil
69
+ # [TODO] Handle user callback (Ref.: https://github.com/ffi/ffi/wiki/Callbacks )
70
+
71
+ # User callback, registered via ImDrawList::AddCallback()
72
+ # (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
73
+ # if pcmd[:UserCallback] == :ImDrawCallback_ResetRenderState
74
+ ImGui_ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height)
75
+ # else
76
+ # pcmd[:UserCallback](cmd_list, pcmd)
77
+ # end
78
+ else
79
+ # Project scissor/clipping rectangles into framebuffer space
80
+ clip_rect = ImVec4.new
81
+ clip_rect[:x] = (pcmd[:ClipRect][:x] - clip_off[:x]) * clip_scale[:x]
82
+ clip_rect[:y] = (pcmd[:ClipRect][:y] - clip_off[:y]) * clip_scale[:y]
83
+ clip_rect[:z] = (pcmd[:ClipRect][:z] - clip_off[:x]) * clip_scale[:x]
84
+ clip_rect[:w] = (pcmd[:ClipRect][:w] - clip_off[:y]) * clip_scale[:y]
85
+
86
+ if (clip_rect[:x] < fb_width && clip_rect[:y] < fb_height && clip_rect[:z] >= 0.0 && clip_rect[:w] >= 0.0)
87
+ # Apply scissor/clipping rectangle
88
+ glScissor(clip_rect[:x].to_i, (fb_height - clip_rect[:w]).to_i, (clip_rect[:z] - clip_rect[:x]).to_i, (clip_rect[:w] - clip_rect[:y]).to_i)
89
+
90
+ # Bind texture, Draw
91
+ glBindTexture(GL_TEXTURE_2D, pcmd[:TextureId].address)
92
+ glDrawElements(GL_TRIANGLES, pcmd[:ElemCount], GL_UNSIGNED_SHORT, Fiddle::Pointer.new(idx_buffer.address))
93
+ end
94
+
95
+ end
96
+ idx_buffer += pcmd[:ElemCount] * 2 # 2 == ImDrawIdx(:ushort).size
97
+ end
98
+ end
99
+
100
+ # Restore modified GL state
101
+ glDisableClientState(GL_COLOR_ARRAY)
102
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY)
103
+ glDisableClientState(GL_VERTEX_ARRAY)
104
+ glBindTexture(GL_TEXTURE_2D, last_texture.unpack1('L'))
105
+ glMatrixMode(GL_MODELVIEW)
106
+ glPopMatrix()
107
+ glMatrixMode(GL_PROJECTION)
108
+ glPopMatrix()
109
+ glPopAttrib()
110
+ last_polygon_mode = last_polygon_mode.unpack('L2')
111
+ glPolygonMode(GL_FRONT, last_polygon_mode[0])
112
+ glPolygonMode(GL_BACK, last_polygon_mode[1])
113
+ last_viewport = last_viewport.unpack('L4')
114
+ glViewport(last_viewport[0], last_viewport[1], last_viewport[2], last_viewport[3])
115
+ last_scissor_box = last_scissor_box.unpack('L4')
116
+ glScissor(last_scissor_box[0], last_scissor_box[1], last_scissor_box[2], last_scissor_box[3])
117
+ glShadeModel(last_shade_model.unpack1('L'))
118
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, last_tex_env_mode.unpack1('L'))
119
+ end
120
+
121
+ # private
122
+
123
+ def self.ImplOpenGL2_SetupRenderState(draw_data, fb_width, fb_height)
124
+ # Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, vertex/texcoord/color pointers, polygon fill.
125
+ glEnable(GL_BLEND)
126
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
127
+ # glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA) # In order to composite our output buffer we need to preserve alpha
128
+ glDisable(GL_CULL_FACE)
129
+ glDisable(GL_STENCIL_TEST)
130
+ glDisable(GL_DEPTH_TEST)
131
+ glDisable(GL_LIGHTING)
132
+ glDisable(GL_COLOR_MATERIAL)
133
+ glEnable(GL_SCISSOR_TEST)
134
+ glEnableClientState(GL_VERTEX_ARRAY)
135
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY)
136
+ glEnableClientState(GL_COLOR_ARRAY)
137
+ glDisableClientState(GL_NORMAL_ARRAY)
138
+ glEnable(GL_TEXTURE_2D)
139
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL)
140
+ glShadeModel(GL_SMOOTH)
141
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE)
142
+
143
+ # If you are using this code with non-legacy OpenGL header/contexts (which you should not, prefer using imgui_impl_opengl3.cpp!!),
144
+ # you may need to backup/reset/restore other state, e.g. for current shader using the commented lines below.
145
+ # (DO NOT MODIFY THIS FILE! Add the code in your calling function)
146
+ # GLint last_program;
147
+ # glGetIntegerv(GL_CURRENT_PROGRAM, &last_program);
148
+ # glUseProgram(0);
149
+ # ImGui_ImplOpenGL2_RenderDrawData(...);
150
+ # glUseProgram(last_program)
151
+ # There are potentially many more states you could need to clear/setup that we can't access from default headers.
152
+ # e.g. glBindBuffer(GL_ARRAY_BUFFER, 0), glDisable(GL_TEXTURE_CUBE_MAP).
153
+
154
+ # Setup viewport, orthographic projection matrix
155
+ # Our visible imgui space lies from draw_data->DisplayPos (top left) to draw_data->DisplayPos+data_data->DisplaySize (bottom right). DisplayPos is (0,0) for single viewport apps.
156
+ glViewport(0, 0, fb_width, fb_height)
157
+ glMatrixMode(GL_PROJECTION)
158
+ glPushMatrix()
159
+ glLoadIdentity()
160
+ glOrtho(draw_data[:DisplayPos][:x], draw_data[:DisplayPos][:x] + draw_data[:DisplaySize][:x], draw_data[:DisplayPos][:y] + draw_data[:DisplaySize][:y], draw_data[:DisplayPos][:y], -1.0, +1.0)
161
+ glMatrixMode(GL_MODELVIEW)
162
+ glPushMatrix()
163
+ glLoadIdentity()
164
+ end
165
+
166
+ def self.ImplOpenGL2_CreateFontsTexture()
167
+ # Build texture atlas
168
+ io = ImGuiIO.new(ImGui::GetIO())
169
+ pixels = FFI::MemoryPointer.new :pointer
170
+ width = FFI::MemoryPointer.new :int
171
+ height = FFI::MemoryPointer.new :int
172
+ io[:Fonts].GetTexDataAsRGBA32(pixels, width, height, nil) # Load as RGBA 32-bits (75% of the memory is wasted, but default font is so small) because it is more likely to be compatible with user's existing shaders. If your ImTextureId represent a higher-level concept than just a GL texture id, consider calling GetTexDataAsAlpha8() instead to save on GPU memory.
173
+
174
+ # Upload texture to graphics system
175
+ last_texture = ' ' * 4
176
+ @@g_FontTexture = ' ' * 4
177
+ glGetIntegerv(GL_TEXTURE_BINDING_2D, last_texture)
178
+ glGenTextures(1, @@g_FontTexture)
179
+ glBindTexture(GL_TEXTURE_2D, @@g_FontTexture.unpack1('L'))
180
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
181
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
182
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)
183
+ # Ruby/FFI <-> Fiddle pointer exchange
184
+ pixels_ptr = Fiddle::Pointer.new(pixels.read_pointer.address)
185
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width.read_uint, height.read_uint, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels_ptr)
186
+
187
+ # Store our identifier
188
+ io[:Fonts][:TexID] = @@g_FontTexture.unpack1('L')
189
+
190
+ # Restore state
191
+ glBindTexture(GL_TEXTURE_2D, last_texture.unpack1('L'))
192
+
193
+ return true
194
+ end
195
+
196
+ def self.ImplOpenGL2_DestroyFontsTexture()
197
+ if @@g_FontTexture != 0
198
+ glDeleteTextures(1, @@g_FontTexture)
199
+ io = ImGuiIO.new(ImGui::GetIO())
200
+ io[:Fonts][:TexID] = 0
201
+ @@g_FontTexture = 0
202
+ end
203
+ end
204
+
205
+ def self.ImplOpenGL2_CreateDeviceObjects()
206
+ return ImplOpenGL2_CreateFontsTexture()
207
+ end
208
+
209
+ def self.ImplOpenGL2_DestroyDeviceObjects()
210
+ ImplOpenGL2_DestroyFontsTexture()
211
+ end
212
+
213
+ end