imgui-bindings 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/ChangeLog +256 -0
- data/LICENSE.txt +21 -0
- data/README.md +90 -0
- data/lib/imgui.dll +0 -0
- data/lib/imgui.dylib +0 -0
- data/lib/imgui.rb +5414 -0
- data/lib/imgui_debug.dll +0 -0
- data/lib/imgui_debug.dylib +0 -0
- data/lib/imgui_impl_glfw.rb +240 -0
- data/lib/imgui_impl_opengl2.rb +213 -0
- data/lib/imgui_impl_opengl3.rb +513 -0
- data/lib/imgui_impl_sdl2.rb +296 -0
- data/lib/imgui_impl_sdlrenderer.rb +201 -0
- metadata +58 -0
@@ -0,0 +1,513 @@
|
|
1
|
+
require 'ffi'
|
2
|
+
require 'opengl'
|
3
|
+
include OpenGL
|
4
|
+
|
5
|
+
require_relative 'imgui'
|
6
|
+
|
7
|
+
module ImGui
|
8
|
+
|
9
|
+
@@g_GlVersion = 0 # Extracted at runtime using GL_MAJOR_VERSION, GL_MINOR_VERSION queries.
|
10
|
+
@@g_GlslVersionString = "" # Specified by user or detected based on compile time
|
11
|
+
@@g_FontTexture = nil
|
12
|
+
|
13
|
+
@@g_ShaderHandle = 0
|
14
|
+
|
15
|
+
@@g_AttribLocationTex = 0
|
16
|
+
@@g_AttribLocationProjMtx = 0
|
17
|
+
|
18
|
+
@@g_AttribLocationVtxPos = 0
|
19
|
+
@@g_AttribLocationVtxUV = 0
|
20
|
+
@@g_AttribLocationVtxColor = 0
|
21
|
+
|
22
|
+
@@g_VboHandle = 0
|
23
|
+
@@g_ElementsHandle = 0
|
24
|
+
|
25
|
+
@@g_BackendRendererName = FFI::MemoryPointer.from_string("imgui_impl_opengl3")
|
26
|
+
|
27
|
+
def self.PrintShaderCompileStatus(handle)
|
28
|
+
rvalue = ' ' * 4
|
29
|
+
glGetShaderiv(handle, GL_COMPILE_STATUS, rvalue)
|
30
|
+
rvalue = rvalue.unpack1('L')
|
31
|
+
if rvalue == GL_FALSE
|
32
|
+
$stderr.puts "Error in compiling shader"
|
33
|
+
log_length = ' ' * 4
|
34
|
+
glGetShaderiv(handle, GL_INFO_LOG_LENGTH, log_length)
|
35
|
+
log_length = log_length.unpack1('L')
|
36
|
+
if log_length > 0
|
37
|
+
buf = ' ' * log_length
|
38
|
+
glGetShaderInfoLog(handle, log_length, nil, buf)
|
39
|
+
$stderr.puts(buf)
|
40
|
+
exit()
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.PrintProgramLinkStatus(handle)
|
46
|
+
rvalue = ' ' * 4
|
47
|
+
glGetProgramiv(handle, GL_LINK_STATUS, rvalue)
|
48
|
+
rvalue = rvalue.unpack1('L')
|
49
|
+
if rvalue == GL_FALSE
|
50
|
+
$stderr.puts "Error in linking program"
|
51
|
+
log_length = ' ' * 4
|
52
|
+
glGetProgramiv(handle, GL_INFO_LOG_LENGTH, log_length)
|
53
|
+
log_length = log_length.unpack1('L')
|
54
|
+
if log_length > 0
|
55
|
+
buf = ' ' * log_length
|
56
|
+
glGetProgramInfoLog(handle, log_length, nil, buf)
|
57
|
+
$stderr.puts(buf)
|
58
|
+
exit()
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.ImplOpenGL3_Init(glsl_version = nil)
|
64
|
+
major, minor = ' ' * 4, ' ' * 4
|
65
|
+
glGetIntegerv(GL_MAJOR_VERSION, major)
|
66
|
+
glGetIntegerv(GL_MINOR_VERSION, minor)
|
67
|
+
major = major.unpack1('L')
|
68
|
+
minor = minor.unpack1('L')
|
69
|
+
@@g_GlVersion = major * 1000 + minor
|
70
|
+
|
71
|
+
io = ImGuiIO.new(ImGui::GetIO())
|
72
|
+
io[:BackendRendererName] = @@g_BackendRendererName
|
73
|
+
io[:BackendFlags] |= ImGuiBackendFlags_RendererHasVtxOffset if @@g_GlVersion >= 3200
|
74
|
+
|
75
|
+
# Ref.: Fix imgui_impl_opengl3 on MacOS
|
76
|
+
# https://github.com/ocornut/imgui/pull/3199
|
77
|
+
if OpenGL.get_platform() == :OPENGL_PLATFORM_MACOSX
|
78
|
+
glsl_version = "#version 150" if glsl_version == nil
|
79
|
+
else
|
80
|
+
glsl_version = "#version 130" if glsl_version == nil
|
81
|
+
end
|
82
|
+
|
83
|
+
@@g_GlslVersionString = glsl_version.dup
|
84
|
+
|
85
|
+
return true
|
86
|
+
end
|
87
|
+
|
88
|
+
def self.ImplOpenGL3_Shutdown()
|
89
|
+
ImplOpenGL3_DestroyDeviceObjects()
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.ImplOpenGL3_NewFrame()
|
93
|
+
ImplOpenGL3_CreateDeviceObjects() if @@g_ShaderHandle == 0
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.ImplOpenGL3_RenderDrawData(draw_data_raw)
|
97
|
+
# Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
|
98
|
+
draw_data = ImDrawData.new(draw_data_raw)
|
99
|
+
fb_width = (draw_data[:DisplaySize][:x] * draw_data[:FramebufferScale][:x]).to_i
|
100
|
+
fb_height = (draw_data[:DisplaySize][:y] * draw_data[:FramebufferScale][:y]).to_i
|
101
|
+
|
102
|
+
return if fb_width == 0 || fb_height == 0
|
103
|
+
|
104
|
+
# Backup GL state
|
105
|
+
last_active_texture = ' ' * 4; glGetIntegerv(GL_ACTIVE_TEXTURE, last_active_texture)
|
106
|
+
last_program = ' ' * 4; glGetIntegerv(GL_CURRENT_PROGRAM, last_program)
|
107
|
+
last_texture = ' ' * 4; glGetIntegerv(GL_TEXTURE_BINDING_2D, last_texture)
|
108
|
+
|
109
|
+
last_sampler = ' ' * 4; glGetIntegerv(GL_SAMPLER_BINDING, last_sampler)
|
110
|
+
last_array_buffer = ' ' * 4; glGetIntegerv(GL_ARRAY_BUFFER_BINDING, last_array_buffer)
|
111
|
+
last_vertex_array_object = ' ' * 4; glGetIntegerv(GL_VERTEX_ARRAY_BINDING, last_vertex_array_object)
|
112
|
+
|
113
|
+
last_polygon_mode = ' ' * 8; glGetIntegerv(GL_POLYGON_MODE, last_polygon_mode)
|
114
|
+
last_viewport = ' ' * 16; glGetIntegerv(GL_VIEWPORT, last_viewport)
|
115
|
+
last_scissor_box = ' ' * 16; glGetIntegerv(GL_SCISSOR_BOX, last_scissor_box)
|
116
|
+
|
117
|
+
last_blend_src_rgb = ' ' * 4; glGetIntegerv(GL_BLEND_SRC_RGB, last_blend_src_rgb)
|
118
|
+
last_blend_dst_rgb = ' ' * 4; glGetIntegerv(GL_BLEND_DST_RGB, last_blend_dst_rgb)
|
119
|
+
last_blend_src_alpha = ' ' * 4; glGetIntegerv(GL_BLEND_SRC_ALPHA, last_blend_src_alpha)
|
120
|
+
last_blend_dst_alpha = ' ' * 4; glGetIntegerv(GL_BLEND_DST_ALPHA, last_blend_dst_alpha)
|
121
|
+
last_blend_equation_rgb = ' ' * 4; glGetIntegerv(GL_BLEND_EQUATION_RGB, last_blend_equation_rgb)
|
122
|
+
last_blend_equation_alpha = ' ' * 4; glGetIntegerv(GL_BLEND_EQUATION_ALPHA, last_blend_equation_alpha)
|
123
|
+
|
124
|
+
last_enable_blend = glIsEnabled(GL_BLEND)
|
125
|
+
last_enable_cull_face = glIsEnabled(GL_CULL_FACE)
|
126
|
+
last_enable_depth_test = glIsEnabled(GL_DEPTH_TEST)
|
127
|
+
last_enable_stencil_test = glIsEnabled(GL_STENCIL_TEST)
|
128
|
+
last_enable_scissor_test = glIsEnabled(GL_SCISSOR_TEST)
|
129
|
+
|
130
|
+
# Setup desired GL state
|
131
|
+
vertex_array_object = ' ' * 4
|
132
|
+
glGenVertexArrays(1, vertex_array_object)
|
133
|
+
vertex_array_object = vertex_array_object.unpack1('L')
|
134
|
+
ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object)
|
135
|
+
|
136
|
+
# Will project scissor/clipping rectangles into framebuffer space
|
137
|
+
clip_off = draw_data[:DisplayPos] # (0,0) unless using multi-viewports
|
138
|
+
clip_scale = draw_data[:FramebufferScale] # (1,1) unless using retina display which are often (2,2)
|
139
|
+
|
140
|
+
# Render command lists
|
141
|
+
draw_data[:CmdListsCount].times do |n|
|
142
|
+
|
143
|
+
cmd_list = ImDrawList.new((draw_data[:CmdLists].pointer + 8 * n).read_pointer) # 8 == const ImDrawList*
|
144
|
+
vtx_buffer = ImDrawVert.new(cmd_list[:VtxBuffer][:Data]) # const ImDrawVert*
|
145
|
+
idx_buffer = cmd_list[:IdxBuffer][:Data] # const ImDrawIdx*
|
146
|
+
|
147
|
+
# Upload vertex/index buffers
|
148
|
+
glBufferData(GL_ARRAY_BUFFER, cmd_list[:VtxBuffer][:Size] * ImDrawVert.size, Fiddle::Pointer.new(cmd_list[:VtxBuffer][:Data]), GL_STREAM_DRAW)
|
149
|
+
# 2 == ImDrawIdx(:ushort).size
|
150
|
+
glBufferData(GL_ELEMENT_ARRAY_BUFFER, cmd_list[:IdxBuffer][:Size] * 2, Fiddle::Pointer.new(cmd_list[:IdxBuffer][:Data]), GL_STREAM_DRAW) # [TODO] Refer ImGui::ImDrawIdx
|
151
|
+
# glBufferData(GL_ELEMENT_ARRAY_BUFFER, cmd_list[:IdxBuffer][:Size] * ImDrawIdx.size, Fiddle::Pointer.new(cmd_list[:IdxBuffer][:Data]), GL_STREAM_DRAW)
|
152
|
+
|
153
|
+
cmd_list[:CmdBuffer][:Size].times do |cmd_i|
|
154
|
+
pcmd = ImDrawCmd.new(cmd_list[:CmdBuffer][:Data] + ImDrawCmd.size * cmd_i) # const ImDrawCmd*
|
155
|
+
if pcmd[:UserCallback] != nil
|
156
|
+
# [TODO] Handle user callback (Ref.: https://github.com/ffi/ffi/wiki/Callbacks )
|
157
|
+
|
158
|
+
# User callback, registered via ImDrawList::AddCallback()
|
159
|
+
# (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
|
160
|
+
# if pcmd[:UserCallback] == :ImDrawCallback_ResetRenderState
|
161
|
+
ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object)
|
162
|
+
# else
|
163
|
+
# pcmd[:UserCallback](cmd_list, pcmd)
|
164
|
+
# end
|
165
|
+
else
|
166
|
+
# Project scissor/clipping rectangles into framebuffer space
|
167
|
+
clip_rect = ImVec4.new
|
168
|
+
clip_rect[:x] = (pcmd[:ClipRect][:x] - clip_off[:x]) * clip_scale[:x]
|
169
|
+
clip_rect[:y] = (pcmd[:ClipRect][:y] - clip_off[:y]) * clip_scale[:y]
|
170
|
+
clip_rect[:z] = (pcmd[:ClipRect][:z] - clip_off[:x]) * clip_scale[:x]
|
171
|
+
clip_rect[:w] = (pcmd[:ClipRect][:w] - clip_off[:y]) * clip_scale[:y]
|
172
|
+
|
173
|
+
if (clip_rect[:x] < fb_width && clip_rect[:y] < fb_height && clip_rect[:z] >= 0.0 && clip_rect[:w] >= 0.0)
|
174
|
+
# Apply scissor/clipping rectangle
|
175
|
+
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)
|
176
|
+
|
177
|
+
# Bind texture, Draw
|
178
|
+
glBindTexture(GL_TEXTURE_2D, pcmd[:TextureId].address)
|
179
|
+
|
180
|
+
if @@g_GlVersion >= 3200
|
181
|
+
# 2 == ImDrawIdx(:ushort).size
|
182
|
+
glDrawElementsBaseVertex(GL_TRIANGLES, pcmd[:ElemCount], GL_UNSIGNED_SHORT, Fiddle::Pointer.new(pcmd[:IdxOffset] * 2), pcmd[:VtxOffset])
|
183
|
+
# glDrawElementsBaseVertex(GL_TRIANGLES, pcmd[:ElemCount], GL_UNSIGNED_SHORT, Fiddle::Pointer.new(pcmd[:IdxOffset] * ImDrawIdx.size), pcmd[:VtxOffset]) # [TODO] Refer ImGui::ImDrawIdx
|
184
|
+
else
|
185
|
+
# 2 == ImDrawIdx(:ushort).size
|
186
|
+
glDrawElements(GL_TRIANGLES, pcmd[:ElemCount], GL_UNSIGNED_SHORT, Fiddle::Pointer.new(pcmd[:IdxOffset] * 2))
|
187
|
+
# glDrawElements(GL_TRIANGLES, pcmd[:ElemCount], GL_UNSIGNED_SHORT, Fiddle::Pointer.new(pcmd[:IdxOffset] * ImDrawIdx.size)) # [TODO] Refer ImGui::ImDrawIdx
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
end
|
192
|
+
idx_buffer += pcmd[:ElemCount] * 2 # 2 == ImDrawIdx(:ushort).size
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
# Destroy the temporary VAO
|
197
|
+
glDeleteVertexArrays(1, [vertex_array_object].pack('L'))
|
198
|
+
|
199
|
+
# Restore modified GL state
|
200
|
+
glUseProgram(last_program.unpack1('L'))
|
201
|
+
glBindTexture(GL_TEXTURE_2D, last_texture.unpack1('L'))
|
202
|
+
glBindSampler(0, last_sampler.unpack1('L'))
|
203
|
+
glActiveTexture(last_active_texture.unpack1('L'))
|
204
|
+
glBindVertexArray(last_vertex_array_object.unpack1('L'))
|
205
|
+
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer.unpack1('L'))
|
206
|
+
glBlendEquationSeparate(last_blend_equation_rgb.unpack1('L'), last_blend_equation_alpha.unpack1('L'))
|
207
|
+
|
208
|
+
if last_enable_blend then glEnable(GL_BLEND) else glDisable(GL_BLEND) end
|
209
|
+
if last_enable_cull_face then glEnable(GL_CULL_FACE) else glDisable(GL_CULL_FACE) end
|
210
|
+
if last_enable_depth_test then glEnable(GL_DEPTH_TEST) else glDisable(GL_DEPTH_TEST) end
|
211
|
+
if last_enable_stencil_test then glEnable(GL_STENCIL_TEST) else glDisable(GL_STENCIL_TEST) end
|
212
|
+
if last_enable_scissor_test then glEnable(GL_SCISSOR_TEST) else glDisable(GL_SCISSOR_TEST) end
|
213
|
+
|
214
|
+
last_polygon_mode = last_polygon_mode.unpack('L2')
|
215
|
+
glPolygonMode(GL_FRONT_AND_BACK, last_polygon_mode[0])
|
216
|
+
last_viewport = last_viewport.unpack('L4')
|
217
|
+
glViewport(last_viewport[0], last_viewport[1], last_viewport[2], last_viewport[3])
|
218
|
+
last_scissor_box = last_scissor_box.unpack('L4')
|
219
|
+
glScissor(last_scissor_box[0], last_scissor_box[1], last_scissor_box[2], last_scissor_box[3])
|
220
|
+
|
221
|
+
end
|
222
|
+
|
223
|
+
# private
|
224
|
+
|
225
|
+
def self.ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object)
|
226
|
+
# Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill
|
227
|
+
glEnable(GL_BLEND)
|
228
|
+
glBlendEquation(GL_FUNC_ADD)
|
229
|
+
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA)
|
230
|
+
glDisable(GL_CULL_FACE)
|
231
|
+
glDisable(GL_DEPTH_TEST)
|
232
|
+
glDisable(GL_STENCIL_TEST)
|
233
|
+
glEnable(GL_SCISSOR_TEST)
|
234
|
+
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL) # GL_POLYGON_MODE
|
235
|
+
|
236
|
+
# Setup viewport, orthographic projection matrix
|
237
|
+
# 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.
|
238
|
+
glViewport(0, 0, fb_width, fb_height)
|
239
|
+
l = draw_data[:DisplayPos][:x]
|
240
|
+
r = draw_data[:DisplayPos][:x] + draw_data[:DisplaySize][:x]
|
241
|
+
t = draw_data[:DisplayPos][:y]
|
242
|
+
b = draw_data[:DisplayPos][:y] + draw_data[:DisplaySize][:y]
|
243
|
+
ortho_projection = [
|
244
|
+
2.0/(r-l), 0.0, 0.0, 0.0,
|
245
|
+
0.0, 2.0/(t-b), 0.0, 0.0,
|
246
|
+
0.0, 0.0, -1.0, 0.0,
|
247
|
+
(r+l)/(l-r), (t+b)/(b-t), 0.0, 1.0,
|
248
|
+
]
|
249
|
+
glUseProgram(@@g_ShaderHandle)
|
250
|
+
glUniform1i(@@g_AttribLocationTex, 0)
|
251
|
+
glUniformMatrix4fv(@@g_AttribLocationProjMtx, 1, GL_FALSE, ortho_projection.pack('F16'))
|
252
|
+
# GL_SAMPLER_BINDING
|
253
|
+
glBindSampler(0, 0) # We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise.
|
254
|
+
|
255
|
+
glBindVertexArray(vertex_array_object)
|
256
|
+
|
257
|
+
# Bind vertex/index buffers and setup attributes for ImDrawVert
|
258
|
+
glBindBuffer(GL_ARRAY_BUFFER, @@g_VboHandle)
|
259
|
+
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, @@g_ElementsHandle)
|
260
|
+
|
261
|
+
glEnableVertexAttribArray(@@g_AttribLocationVtxPos)
|
262
|
+
glEnableVertexAttribArray(@@g_AttribLocationVtxUV)
|
263
|
+
glEnableVertexAttribArray(@@g_AttribLocationVtxColor)
|
264
|
+
|
265
|
+
glVertexAttribPointer(@@g_AttribLocationVtxPos, 2, GL_FLOAT, GL_FALSE, ImDrawVert.size, ImDrawVert.offset_of(:pos))
|
266
|
+
glVertexAttribPointer(@@g_AttribLocationVtxUV, 2, GL_FLOAT, GL_FALSE, ImDrawVert.size, ImDrawVert.offset_of(:uv))
|
267
|
+
glVertexAttribPointer(@@g_AttribLocationVtxColor, 4, GL_UNSIGNED_BYTE, GL_TRUE, ImDrawVert.size, ImDrawVert.offset_of(:col))
|
268
|
+
|
269
|
+
end
|
270
|
+
|
271
|
+
def self.ImplOpenGL3_CreateFontsTexture()
|
272
|
+
# Build texture atlas
|
273
|
+
io = ImGuiIO.new(ImGui::GetIO())
|
274
|
+
pixels = FFI::MemoryPointer.new :pointer
|
275
|
+
width = FFI::MemoryPointer.new :int
|
276
|
+
height = FFI::MemoryPointer.new :int
|
277
|
+
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.
|
278
|
+
|
279
|
+
# Upload texture to graphics system
|
280
|
+
last_texture = ' ' * 4
|
281
|
+
@@g_FontTexture = ' ' * 4
|
282
|
+
glGetIntegerv(GL_TEXTURE_BINDING_2D, last_texture)
|
283
|
+
glGenTextures(1, @@g_FontTexture)
|
284
|
+
glBindTexture(GL_TEXTURE_2D, @@g_FontTexture.unpack1('L'))
|
285
|
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
|
286
|
+
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
|
287
|
+
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)
|
288
|
+
# Ruby/FFI <-> Fiddle pointer exchange
|
289
|
+
# p pixels
|
290
|
+
# p pixels.read_pointer
|
291
|
+
# p pixels.read_pointer.address.to_s(16)
|
292
|
+
pixels_ptr = Fiddle::Pointer.new(pixels.read_pointer.address)
|
293
|
+
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width.read_uint, height.read_uint, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels_ptr)
|
294
|
+
|
295
|
+
# Store our identifier
|
296
|
+
io[:Fonts][:TexID] = @@g_FontTexture.unpack1('L')
|
297
|
+
|
298
|
+
# Restore state
|
299
|
+
glBindTexture(GL_TEXTURE_2D, last_texture.unpack1('L'))
|
300
|
+
|
301
|
+
return true
|
302
|
+
end
|
303
|
+
|
304
|
+
def self.ImplOpenGL3_DestroyFontsTexture()
|
305
|
+
if @@g_FontTexture != 0
|
306
|
+
glDeleteTextures(1, @@g_FontTexture)
|
307
|
+
io = ImGuiIO.new(ImGui::GetIO())
|
308
|
+
io[:Fonts][:TexID] = 0
|
309
|
+
@@g_FontTexture = 0
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
def self.ImplOpenGL3_CreateDeviceObjects()
|
314
|
+
# Backup GL state
|
315
|
+
last_texture, last_array_buffer = ' ' * 4, ' ' * 4
|
316
|
+
glGetIntegerv(GL_TEXTURE_BINDING_2D, last_texture)
|
317
|
+
glGetIntegerv(GL_ARRAY_BUFFER_BINDING, last_array_buffer)
|
318
|
+
last_texture = last_texture.unpack1('L')
|
319
|
+
last_array_buffer = last_array_buffer.unpack1('L')
|
320
|
+
|
321
|
+
last_vertex_array = ' ' * 4
|
322
|
+
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, last_vertex_array)
|
323
|
+
last_vertex_array = last_vertex_array.unpack1('L')
|
324
|
+
|
325
|
+
glsl_version = @@g_GlslVersionString.split[1].to_i # == scanf(@@g_GlslVersionString, "#version %d")
|
326
|
+
|
327
|
+
vertex_shader_glsl_120 = <<-'SRC'
|
328
|
+
uniform mat4 ProjMtx;
|
329
|
+
attribute vec2 Position;
|
330
|
+
attribute vec2 UV;
|
331
|
+
attribute vec4 Color;
|
332
|
+
varying vec2 Frag_UV;
|
333
|
+
varying vec4 Frag_Color;
|
334
|
+
void main()
|
335
|
+
{
|
336
|
+
Frag_UV = UV;
|
337
|
+
Frag_Color = Color;
|
338
|
+
gl_Position = ProjMtx * vec4(Position.xy,0,1);
|
339
|
+
}
|
340
|
+
SRC
|
341
|
+
|
342
|
+
vertex_shader_glsl_130 = <<-'SRC'
|
343
|
+
uniform mat4 ProjMtx;
|
344
|
+
in vec2 Position;
|
345
|
+
in vec2 UV;
|
346
|
+
in vec4 Color;
|
347
|
+
out vec2 Frag_UV;
|
348
|
+
out vec4 Frag_Color;
|
349
|
+
void main()
|
350
|
+
{
|
351
|
+
Frag_UV = UV;
|
352
|
+
Frag_Color = Color;
|
353
|
+
gl_Position = ProjMtx * vec4(Position.xy,0,1);
|
354
|
+
}
|
355
|
+
SRC
|
356
|
+
|
357
|
+
vertex_shader_glsl_300_es = <<-'SRC'
|
358
|
+
precision mediump float;
|
359
|
+
layout (location = 0) in vec2 Position;
|
360
|
+
layout (location = 1) in vec2 UV;
|
361
|
+
layout (location = 2) in vec4 Color;
|
362
|
+
uniform mat4 ProjMtx;
|
363
|
+
out vec2 Frag_UV;
|
364
|
+
out vec4 Frag_Color;
|
365
|
+
void main()
|
366
|
+
{
|
367
|
+
Frag_UV = UV;
|
368
|
+
Frag_Color = Color;
|
369
|
+
gl_Position = ProjMtx * vec4(Position.xy,0,1);
|
370
|
+
}
|
371
|
+
SRC
|
372
|
+
|
373
|
+
vertex_shader_glsl_410_core = <<-'SRC'
|
374
|
+
layout (location = 0) in vec2 Position;
|
375
|
+
layout (location = 1) in vec2 UV;
|
376
|
+
layout (location = 2) in vec4 Color;
|
377
|
+
uniform mat4 ProjMtx;
|
378
|
+
out vec2 Frag_UV;
|
379
|
+
out vec4 Frag_Color;
|
380
|
+
void main()
|
381
|
+
{
|
382
|
+
Frag_UV = UV;
|
383
|
+
Frag_Color = Color;
|
384
|
+
gl_Position = ProjMtx * vec4(Position.xy,0,1);
|
385
|
+
}
|
386
|
+
SRC
|
387
|
+
|
388
|
+
fragment_shader_glsl_120 = <<-'SRC'
|
389
|
+
#ifdef GL_ES
|
390
|
+
precision mediump float;
|
391
|
+
#endif
|
392
|
+
uniform sampler2D Texture;
|
393
|
+
varying vec2 Frag_UV;
|
394
|
+
varying vec4 Frag_Color;
|
395
|
+
void main()
|
396
|
+
{
|
397
|
+
gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);
|
398
|
+
}
|
399
|
+
SRC
|
400
|
+
|
401
|
+
fragment_shader_glsl_130 = <<-'SRC'
|
402
|
+
uniform sampler2D Texture;
|
403
|
+
in vec2 Frag_UV;
|
404
|
+
in vec4 Frag_Color;
|
405
|
+
out vec4 Out_Color;
|
406
|
+
void main()
|
407
|
+
{
|
408
|
+
Out_Color = Frag_Color * texture(Texture, Frag_UV.st);
|
409
|
+
}
|
410
|
+
SRC
|
411
|
+
|
412
|
+
fragment_shader_glsl_300_es = <<-'SRC'
|
413
|
+
precision mediump float;
|
414
|
+
uniform sampler2D Texture;
|
415
|
+
in vec2 Frag_UV;
|
416
|
+
in vec4 Frag_Color;
|
417
|
+
layout (location = 0) out vec4 Out_Color;
|
418
|
+
void main()
|
419
|
+
{
|
420
|
+
Out_Color = Frag_Color * texture(Texture, Frag_UV.st);
|
421
|
+
}
|
422
|
+
SRC
|
423
|
+
|
424
|
+
fragment_shader_glsl_410_core = <<-'SRC'
|
425
|
+
in vec2 Frag_UV;
|
426
|
+
in vec4 Frag_Color;
|
427
|
+
uniform sampler2D Texture;
|
428
|
+
layout (location = 0) out vec4 Out_Color;
|
429
|
+
void main()
|
430
|
+
{
|
431
|
+
Out_Color = Frag_Color * texture(Texture, Frag_UV.st);
|
432
|
+
}
|
433
|
+
SRC
|
434
|
+
|
435
|
+
vertex_shader, fragment_shader = if glsl_version < 130
|
436
|
+
[vertex_shader_glsl_120, fragment_shader_glsl_120]
|
437
|
+
elsif glsl_version >= 410
|
438
|
+
[vertex_shader_glsl_410_core, fragment_shader_glsl_410_core]
|
439
|
+
elsif glsl_version == 300
|
440
|
+
[vertex_shader_glsl_300_es, fragment_shader_glsl_300_es]
|
441
|
+
else
|
442
|
+
[vertex_shader_glsl_130, fragment_shader_glsl_130]
|
443
|
+
end
|
444
|
+
|
445
|
+
vertex_shader.prepend(@@g_GlslVersionString + "\n")
|
446
|
+
vert_handle = glCreateShader(GL_VERTEX_SHADER)
|
447
|
+
glShaderSource(vert_handle, 1, [vertex_shader].pack('p'), nil)
|
448
|
+
glCompileShader(vert_handle)
|
449
|
+
PrintShaderCompileStatus(vert_handle)
|
450
|
+
|
451
|
+
fragment_shader.prepend(@@g_GlslVersionString + "\n")
|
452
|
+
frag_handle = glCreateShader(GL_FRAGMENT_SHADER)
|
453
|
+
glShaderSource(frag_handle, 1, [fragment_shader].pack('p'), [fragment_shader.size].pack('I'))
|
454
|
+
glCompileShader(frag_handle)
|
455
|
+
PrintShaderCompileStatus(frag_handle)
|
456
|
+
|
457
|
+
@@g_ShaderHandle = glCreateProgram()
|
458
|
+
glAttachShader(@@g_ShaderHandle, vert_handle)
|
459
|
+
glAttachShader(@@g_ShaderHandle, frag_handle)
|
460
|
+
glLinkProgram(@@g_ShaderHandle)
|
461
|
+
PrintProgramLinkStatus(@@g_ShaderHandle)
|
462
|
+
|
463
|
+
glDetachShader(@@g_ShaderHandle, vert_handle)
|
464
|
+
glDetachShader(@@g_ShaderHandle, frag_handle)
|
465
|
+
glDeleteShader(vert_handle)
|
466
|
+
glDeleteShader(frag_handle)
|
467
|
+
|
468
|
+
@@g_AttribLocationTex = glGetUniformLocation(@@g_ShaderHandle, "Texture")
|
469
|
+
@@g_AttribLocationProjMtx = glGetUniformLocation(@@g_ShaderHandle, "ProjMtx")
|
470
|
+
|
471
|
+
@@g_AttribLocationVtxPos = glGetAttribLocation(@@g_ShaderHandle, "Position")
|
472
|
+
@@g_AttribLocationVtxUV = glGetAttribLocation(@@g_ShaderHandle, "UV")
|
473
|
+
@@g_AttribLocationVtxColor = glGetAttribLocation(@@g_ShaderHandle, "Color")
|
474
|
+
|
475
|
+
# Create buffers
|
476
|
+
posBuf = ' ' * 4
|
477
|
+
glGenBuffers(1, posBuf)
|
478
|
+
glBindBuffer(GL_ARRAY_BUFFER, posBuf.unpack('L')[0])
|
479
|
+
|
480
|
+
@@g_VboHandle, @@g_ElementsHandle = ' ' * 4, ' ' * 4
|
481
|
+
glGenBuffers(1, @@g_VboHandle)
|
482
|
+
glGenBuffers(1, @@g_ElementsHandle)
|
483
|
+
@@g_VboHandle = @@g_VboHandle.unpack1('L')
|
484
|
+
@@g_ElementsHandle = @@g_ElementsHandle.unpack1('L')
|
485
|
+
|
486
|
+
ImplOpenGL3_CreateFontsTexture()
|
487
|
+
|
488
|
+
# Restore modified GL state
|
489
|
+
glBindTexture(GL_TEXTURE_2D, last_texture)
|
490
|
+
glBindBuffer(GL_ARRAY_BUFFER, last_array_buffer)
|
491
|
+
glBindVertexArray(last_vertex_array)
|
492
|
+
|
493
|
+
return true
|
494
|
+
end
|
495
|
+
|
496
|
+
def self.ImplOpenGL3_DestroyDeviceObjects()
|
497
|
+
if @@g_VboHandle != 0
|
498
|
+
glDeleteBuffers(1, [@@g_VboHandle].pack('L'))
|
499
|
+
@@g_VboHandle = 0
|
500
|
+
end
|
501
|
+
if @@g_ElementsHandle != 0
|
502
|
+
glDeleteBuffers(1, [@@g_ElementsHandle].pack('L'))
|
503
|
+
@@g_ElementsHandle = 0
|
504
|
+
end
|
505
|
+
if @@g_ShaderHandle != 0
|
506
|
+
glDeleteProgram(@@g_ShaderHandle)
|
507
|
+
@@g_ShaderHandle = 0
|
508
|
+
end
|
509
|
+
|
510
|
+
ImplOpenGL3_DestroyFontsTexture()
|
511
|
+
end
|
512
|
+
|
513
|
+
end
|