imgui-bindings 0.1.10-x64-mingw

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.
@@ -0,0 +1,509 @@
1
+ require 'ffi'
2
+ require 'opengl'
3
+
4
+ require_relative 'imgui'
5
+
6
+ module ImGui
7
+
8
+ @@g_GlVersion = 0 # Extracted at runtime using GL::MAJOR_VERSION, GL::MINOR_VERSION queries.
9
+ @@g_GlslVersionString = "" # Specified by user or detected based on compile time
10
+ @@g_FontTexture = nil
11
+
12
+ @@g_ShaderHandle = 0
13
+
14
+ @@g_AttribLocationTex = 0
15
+ @@g_AttribLocationProjMtx = 0
16
+
17
+ @@g_AttribLocationVtxPos = 0
18
+ @@g_AttribLocationVtxUV = 0
19
+ @@g_AttribLocationVtxColor = 0
20
+
21
+ @@g_VboHandle = 0
22
+ @@g_ElementsHandle = 0
23
+
24
+ @@g_BackendRendererName = FFI::MemoryPointer.from_string("imgui_impl_opengl3")
25
+
26
+ def self.PrintShaderCompileStatus(handle)
27
+ rvalue = ' ' * 4
28
+ GL.GetShaderiv(handle, GL::COMPILE_STATUS, rvalue)
29
+ rvalue = rvalue.unpack1('L')
30
+ if rvalue == GL::FALSE
31
+ $stderr.puts "Error in compiling shader"
32
+ log_length = ' ' * 4
33
+ GL.GetShaderiv(handle, GL::INFO_LOG_LENGTH, log_length)
34
+ log_length = log_length.unpack1('L')
35
+ if log_length > 0
36
+ buf = ' ' * log_length
37
+ GL.GetShaderInfoLog(handle, log_length, nil, buf)
38
+ $stderr.puts(buf)
39
+ exit()
40
+ end
41
+ end
42
+ end
43
+
44
+ def self.PrintProgramLinkStatus(handle)
45
+ rvalue = ' ' * 4
46
+ GL.GetProgramiv(handle, GL::LINK_STATUS, rvalue)
47
+ rvalue = rvalue.unpack1('L')
48
+ if rvalue == GL::FALSE
49
+ $stderr.puts "Error in linking program"
50
+ log_length = ' ' * 4
51
+ GL.GetProgramiv(handle, GL::INFO_LOG_LENGTH, log_length)
52
+ log_length = log_length.unpack1('L')
53
+ if log_length > 0
54
+ buf = ' ' * log_length
55
+ GL.GetProgramInfoLog(handle, log_length, nil, buf)
56
+ $stderr.puts(buf)
57
+ exit()
58
+ end
59
+ end
60
+ end
61
+
62
+ def self.ImplOpenGL3_Init(glsl_version = nil)
63
+ major, minor = ' ' * 4, ' ' * 4
64
+ GL.GetIntegerv(GL::MAJOR_VERSION, major)
65
+ GL.GetIntegerv(GL::MINOR_VERSION, minor)
66
+ major = major.unpack1('L')
67
+ minor = minor.unpack1('L')
68
+ @@g_GlVersion = major * 1000 + minor
69
+
70
+ io = ImGuiIO.new(ImGui::GetIO())
71
+ io[:BackendRendererName] = @@g_BackendRendererName
72
+ io[:BackendFlags] |= ImGuiBackendFlags_RendererHasVtxOffset if @@g_GlVersion >= 3200
73
+
74
+ # Ref.: Fix imgui_impl_opengl3 on MacOS
75
+ # https://github.com/ocornut/imgui/pull/3199
76
+ if GL.get_platform() == :OPENGL_PLATFORM_MACOSX
77
+ glsl_version = "#version 150" if glsl_version == nil
78
+ else
79
+ glsl_version = "#version 130" if glsl_version == nil
80
+ end
81
+
82
+ @@g_GlslVersionString = glsl_version.dup
83
+
84
+ return true
85
+ end
86
+
87
+ def self.ImplOpenGL3_Shutdown()
88
+ ImplOpenGL3_DestroyDeviceObjects()
89
+ end
90
+
91
+ def self.ImplOpenGL3_NewFrame()
92
+ ImplOpenGL3_CreateDeviceObjects() if @@g_ShaderHandle == 0
93
+ end
94
+
95
+ def self.ImplOpenGL3_RenderDrawData(draw_data_raw)
96
+ # Avoid rendering when minimized, scale coordinates for retina displays (screen coordinates != framebuffer coordinates)
97
+ draw_data = ImDrawData.new(draw_data_raw)
98
+ fb_width = (draw_data[:DisplaySize][:x] * draw_data[:FramebufferScale][:x]).to_i
99
+ fb_height = (draw_data[:DisplaySize][:y] * draw_data[:FramebufferScale][:y]).to_i
100
+
101
+ return if fb_width == 0 || fb_height == 0
102
+
103
+ # Backup GL state
104
+ last_active_texture = ' ' * 4; GL.GetIntegerv(GL::ACTIVE_TEXTURE, last_active_texture)
105
+ last_program = ' ' * 4; GL.GetIntegerv(GL::CURRENT_PROGRAM, last_program)
106
+ last_texture = ' ' * 4; GL.GetIntegerv(GL::TEXTURE_BINDING_2D, last_texture)
107
+
108
+ last_sampler = ' ' * 4; GL.GetIntegerv(GL::SAMPLER_BINDING, last_sampler)
109
+ last_array_buffer = ' ' * 4; GL.GetIntegerv(GL::ARRAY_BUFFER_BINDING, last_array_buffer)
110
+ last_vertex_array_object = ' ' * 4; GL.GetIntegerv(GL::VERTEX_ARRAY_BINDING, last_vertex_array_object)
111
+
112
+ last_polygon_mode = ' ' * 8; GL.GetIntegerv(GL::POLYGON_MODE, last_polygon_mode)
113
+ last_viewport = ' ' * 16; GL.GetIntegerv(GL::VIEWPORT, last_viewport)
114
+ last_scissor_box = ' ' * 16; GL.GetIntegerv(GL::SCISSOR_BOX, last_scissor_box)
115
+
116
+ last_blend_src_rgb = ' ' * 4; GL.GetIntegerv(GL::BLEND_SRC_RGB, last_blend_src_rgb)
117
+ last_blend_dst_rgb = ' ' * 4; GL.GetIntegerv(GL::BLEND_DST_RGB, last_blend_dst_rgb)
118
+ last_blend_src_alpha = ' ' * 4; GL.GetIntegerv(GL::BLEND_SRC_ALPHA, last_blend_src_alpha)
119
+ last_blend_dst_alpha = ' ' * 4; GL.GetIntegerv(GL::BLEND_DST_ALPHA, last_blend_dst_alpha)
120
+ last_blend_equation_rgb = ' ' * 4; GL.GetIntegerv(GL::BLEND_EQUATION_RGB, last_blend_equation_rgb)
121
+ last_blend_equation_alpha = ' ' * 4; GL.GetIntegerv(GL::BLEND_EQUATION_ALPHA, last_blend_equation_alpha)
122
+
123
+ last_enable_blend = GL.IsEnabled(GL::BLEND)
124
+ last_enable_cull_face = GL.IsEnabled(GL::CULL_FACE)
125
+ last_enable_depth_test = GL.IsEnabled(GL::DEPTH_TEST)
126
+ last_enable_stencil_test = GL.IsEnabled(GL::STENCIL_TEST)
127
+ last_enable_scissor_test = GL.IsEnabled(GL::SCISSOR_TEST)
128
+
129
+ # Setup desired GL state
130
+ vertex_array_object = ' ' * 4
131
+ GL.GenVertexArrays(1, vertex_array_object)
132
+ vertex_array_object = vertex_array_object.unpack1('L')
133
+ ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object)
134
+
135
+ # Will project scissor/clipping rectangles into framebuffer space
136
+ clip_off = draw_data[:DisplayPos] # (0,0) unless using multi-viewports
137
+ clip_scale = draw_data[:FramebufferScale] # (1,1) unless using retina display which are often (2,2)
138
+
139
+ # Render command lists
140
+ draw_data[:CmdListsCount].times do |n|
141
+
142
+ cmd_list = ImDrawList.new((draw_data[:CmdLists][:Data] + 8 * n).read_pointer) # 8 == const ImDrawList*
143
+ # vtx_buffer = ImDrawVert.new(cmd_list[:VtxBuffer][:Data]) # const ImDrawVert*
144
+ # idx_buffer = cmd_list[:IdxBuffer][:Data] # const ImDrawIdx*
145
+
146
+ # Upload vertex/index buffers
147
+ GL.BufferData(GL::ARRAY_BUFFER, cmd_list[:VtxBuffer][:Size] * ImDrawVert.size, Fiddle::Pointer.new(cmd_list[:VtxBuffer][:Data]), GL::STREAM_DRAW)
148
+ # 2 == ImDrawIdx(:ushort).size
149
+ GL.BufferData(GL::ELEMENT_ARRAY_BUFFER, cmd_list[:IdxBuffer][:Size] * 2, Fiddle::Pointer.new(cmd_list[:IdxBuffer][:Data]), GL::STREAM_DRAW) # [TODO] Refer ImGui::ImDrawIdx
150
+
151
+ cmd_list[:CmdBuffer][:Size].times do |cmd_i|
152
+ pcmd = ImDrawCmd.new(cmd_list[:CmdBuffer][:Data] + ImDrawCmd.size * cmd_i) # const ImDrawCmd*
153
+ if pcmd[:UserCallback] != nil
154
+ # [TODO] Handle user callback (Ref.: https://github.com/ffi/ffi/wiki/Callbacks )
155
+
156
+ # User callback, registered via ImDrawList::AddCallback()
157
+ # (ImDrawCallback_ResetRenderState is a special callback value used by the user to request the renderer to reset render state.)
158
+ # if pcmd[:UserCallback] == :ImDrawCallback_ResetRenderState
159
+ ImGui_ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object)
160
+ # else
161
+ # pcmd[:UserCallback](cmd_list, pcmd)
162
+ # end
163
+ else
164
+ # Project scissor/clipping rectangles into framebuffer space
165
+ clip_rect = ImVec4.new
166
+ clip_rect[:x] = (pcmd[:ClipRect][:x] - clip_off[:x]) * clip_scale[:x]
167
+ clip_rect[:y] = (pcmd[:ClipRect][:y] - clip_off[:y]) * clip_scale[:y]
168
+ clip_rect[:z] = (pcmd[:ClipRect][:z] - clip_off[:x]) * clip_scale[:x]
169
+ clip_rect[:w] = (pcmd[:ClipRect][:w] - clip_off[:y]) * clip_scale[:y]
170
+
171
+ if (clip_rect[:x] < fb_width && clip_rect[:y] < fb_height && clip_rect[:z] >= 0.0 && clip_rect[:w] >= 0.0)
172
+ # Apply scissor/clipping rectangle
173
+ GL.Scissor(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)
174
+
175
+ # Bind texture, Draw
176
+ GL.BindTexture(GL::TEXTURE_2D, pcmd[:TextureId].address)
177
+
178
+ if @@g_GlVersion >= 3200
179
+ # 2 == ImDrawIdx(:ushort).size
180
+ GL.DrawElementsBaseVertex(GL::TRIANGLES, pcmd[:ElemCount], GL::UNSIGNED_SHORT, Fiddle::Pointer.new(pcmd[:IdxOffset] * 2), pcmd[:VtxOffset])
181
+ else
182
+ # 2 == ImDrawIdx(:ushort).size
183
+ GL.DrawElements(GL::TRIANGLES, pcmd[:ElemCount], GL::UNSIGNED_SHORT, Fiddle::Pointer.new(pcmd[:IdxOffset] * 2))
184
+ end
185
+ end
186
+
187
+ end
188
+ # idx_buffer += pcmd[:ElemCount] * 2 # 2 == ImDrawIdx(:ushort).size
189
+ end
190
+ end
191
+
192
+ # Destroy the temporary VAO
193
+ GL.DeleteVertexArrays(1, [vertex_array_object].pack('L'))
194
+
195
+ # Restore modified GL state
196
+ GL.UseProgram(last_program.unpack1('L'))
197
+ GL.BindTexture(GL::TEXTURE_2D, last_texture.unpack1('L'))
198
+ GL.BindSampler(0, last_sampler.unpack1('L'))
199
+ GL.ActiveTexture(last_active_texture.unpack1('L'))
200
+ GL.BindVertexArray(last_vertex_array_object.unpack1('L'))
201
+ GL.BindBuffer(GL::ARRAY_BUFFER, last_array_buffer.unpack1('L'))
202
+ GL.BlendEquationSeparate(last_blend_equation_rgb.unpack1('L'), last_blend_equation_alpha.unpack1('L'))
203
+
204
+ if last_enable_blend then GL.Enable(GL::BLEND) else GL.Disable(GL::BLEND) end
205
+ if last_enable_cull_face then GL.Enable(GL::CULL_FACE) else GL.Disable(GL::CULL_FACE) end
206
+ if last_enable_depth_test then GL.Enable(GL::DEPTH_TEST) else GL.Disable(GL::DEPTH_TEST) end
207
+ if last_enable_stencil_test then GL.Enable(GL::STENCIL_TEST) else GL.Disable(GL::STENCIL_TEST) end
208
+ if last_enable_scissor_test then GL.Enable(GL::SCISSOR_TEST) else GL.Disable(GL::SCISSOR_TEST) end
209
+
210
+ last_polygon_mode = last_polygon_mode.unpack('L2')
211
+ GL.PolygonMode(GL::FRONT_AND_BACK, last_polygon_mode[0])
212
+ last_viewport = last_viewport.unpack('L4')
213
+ GL.Viewport(last_viewport[0], last_viewport[1], last_viewport[2], last_viewport[3])
214
+ last_scissor_box = last_scissor_box.unpack('L4')
215
+ GL.Scissor(last_scissor_box[0], last_scissor_box[1], last_scissor_box[2], last_scissor_box[3])
216
+
217
+ end
218
+
219
+ # private
220
+
221
+ def self.ImplOpenGL3_SetupRenderState(draw_data, fb_width, fb_height, vertex_array_object)
222
+ # Setup render state: alpha-blending enabled, no face culling, no depth testing, scissor enabled, polygon fill
223
+ GL.Enable(GL::BLEND)
224
+ GL.BlendEquation(GL::FUNC_ADD)
225
+ GL.BlendFuncSeparate(GL::SRC_ALPHA, GL::ONE_MINUS_SRC_ALPHA, GL::ONE, GL::ONE_MINUS_SRC_ALPHA)
226
+ GL.Disable(GL::CULL_FACE)
227
+ GL.Disable(GL::DEPTH_TEST)
228
+ GL.Disable(GL::STENCIL_TEST)
229
+ GL.Enable(GL::SCISSOR_TEST)
230
+ GL.PolygonMode(GL::FRONT_AND_BACK, GL::FILL) # GL::POLYGON_MODE
231
+
232
+ # Setup viewport, orthographic projection matrix
233
+ # 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.
234
+ GL.Viewport(0, 0, fb_width, fb_height)
235
+ l = draw_data[:DisplayPos][:x]
236
+ r = draw_data[:DisplayPos][:x] + draw_data[:DisplaySize][:x]
237
+ t = draw_data[:DisplayPos][:y]
238
+ b = draw_data[:DisplayPos][:y] + draw_data[:DisplaySize][:y]
239
+ ortho_projection = [
240
+ 2.0/(r-l), 0.0, 0.0, 0.0,
241
+ 0.0, 2.0/(t-b), 0.0, 0.0,
242
+ 0.0, 0.0, -1.0, 0.0,
243
+ (r+l)/(l-r), (t+b)/(b-t), 0.0, 1.0,
244
+ ]
245
+ GL.UseProgram(@@g_ShaderHandle)
246
+ GL.Uniform1i(@@g_AttribLocationTex, 0)
247
+ GL.UniformMatrix4fv(@@g_AttribLocationProjMtx, 1, GL::FALSE, ortho_projection.pack('F16'))
248
+ # GL::SAMPLER_BINDING
249
+ GL.BindSampler(0, 0) # We use combined texture/sampler state. Applications using GL 3.3 may set that otherwise.
250
+
251
+ GL.BindVertexArray(vertex_array_object)
252
+
253
+ # Bind vertex/index buffers and setup attributes for ImDrawVert
254
+ GL.BindBuffer(GL::ARRAY_BUFFER, @@g_VboHandle)
255
+ GL.BindBuffer(GL::ELEMENT_ARRAY_BUFFER, @@g_ElementsHandle)
256
+
257
+ GL.EnableVertexAttribArray(@@g_AttribLocationVtxPos)
258
+ GL.EnableVertexAttribArray(@@g_AttribLocationVtxUV)
259
+ GL.EnableVertexAttribArray(@@g_AttribLocationVtxColor)
260
+
261
+ GL.VertexAttribPointer(@@g_AttribLocationVtxPos, 2, GL::FLOAT, GL::FALSE, ImDrawVert.size, ImDrawVert.offset_of(:pos))
262
+ GL.VertexAttribPointer(@@g_AttribLocationVtxUV, 2, GL::FLOAT, GL::FALSE, ImDrawVert.size, ImDrawVert.offset_of(:uv))
263
+ GL.VertexAttribPointer(@@g_AttribLocationVtxColor, 4, GL::UNSIGNED_BYTE, GL::TRUE, ImDrawVert.size, ImDrawVert.offset_of(:col))
264
+
265
+ end
266
+
267
+ def self.ImplOpenGL3_CreateFontsTexture()
268
+ # Build texture atlas
269
+ io = ImGuiIO.new(ImGui::GetIO())
270
+ pixels = FFI::MemoryPointer.new :pointer
271
+ width = FFI::MemoryPointer.new :int
272
+ height = FFI::MemoryPointer.new :int
273
+ 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.
274
+
275
+ # Upload texture to graphics system
276
+ last_texture = ' ' * 4
277
+ @@g_FontTexture = ' ' * 4
278
+ GL.GetIntegerv(GL::TEXTURE_BINDING_2D, last_texture)
279
+ GL.GenTextures(1, @@g_FontTexture)
280
+ GL.BindTexture(GL::TEXTURE_2D, @@g_FontTexture.unpack1('L'))
281
+ GL.TexParameteri(GL::TEXTURE_2D, GL::TEXTURE_MIN_FILTER, GL::LINEAR)
282
+ GL.TexParameteri(GL::TEXTURE_2D, GL::TEXTURE_MAG_FILTER, GL::LINEAR)
283
+ GL.PixelStorei(GL::UNPACK_ROW_LENGTH, 0)
284
+ # Ruby/FFI <-> Fiddle pointer exchange
285
+ # p pixels
286
+ # p pixels.read_pointer
287
+ # p pixels.read_pointer.address.to_s(16)
288
+ pixels_ptr = Fiddle::Pointer.new(pixels.read_pointer.address)
289
+ GL.TexImage2D(GL::TEXTURE_2D, 0, GL::RGBA, width.read_uint, height.read_uint, 0, GL::RGBA, GL::UNSIGNED_BYTE, pixels_ptr)
290
+
291
+ # Store our identifier
292
+ io[:Fonts][:TexID] = @@g_FontTexture.unpack1('L')
293
+
294
+ # Restore state
295
+ GL.BindTexture(GL::TEXTURE_2D, last_texture.unpack1('L'))
296
+
297
+ return true
298
+ end
299
+
300
+ def self.ImplOpenGL3_DestroyFontsTexture()
301
+ if @@g_FontTexture != 0
302
+ GL.DeleteTextures(1, @@g_FontTexture)
303
+ io = ImGuiIO.new(ImGui::GetIO())
304
+ io[:Fonts][:TexID] = 0
305
+ @@g_FontTexture = 0
306
+ end
307
+ end
308
+
309
+ def self.ImplOpenGL3_CreateDeviceObjects()
310
+ # Backup GL state
311
+ last_texture, last_array_buffer = ' ' * 4, ' ' * 4
312
+ GL.GetIntegerv(GL::TEXTURE_BINDING_2D, last_texture)
313
+ GL.GetIntegerv(GL::ARRAY_BUFFER_BINDING, last_array_buffer)
314
+ last_texture = last_texture.unpack1('L')
315
+ last_array_buffer = last_array_buffer.unpack1('L')
316
+
317
+ last_vertex_array = ' ' * 4
318
+ GL.GetIntegerv(GL::VERTEX_ARRAY_BINDING, last_vertex_array)
319
+ last_vertex_array = last_vertex_array.unpack1('L')
320
+
321
+ glsl_version = @@g_GlslVersionString.split[1].to_i # == scanf(@@g_GlslVersionString, "#version %d")
322
+
323
+ vertex_shader_glsl_120 = <<-'SRC'
324
+ uniform mat4 ProjMtx;
325
+ attribute vec2 Position;
326
+ attribute vec2 UV;
327
+ attribute vec4 Color;
328
+ varying vec2 Frag_UV;
329
+ varying vec4 Frag_Color;
330
+ void main()
331
+ {
332
+ Frag_UV = UV;
333
+ Frag_Color = Color;
334
+ gl_Position = ProjMtx * vec4(Position.xy,0,1);
335
+ }
336
+ SRC
337
+
338
+ vertex_shader_glsl_130 = <<-'SRC'
339
+ uniform mat4 ProjMtx;
340
+ in vec2 Position;
341
+ in vec2 UV;
342
+ in vec4 Color;
343
+ out vec2 Frag_UV;
344
+ out vec4 Frag_Color;
345
+ void main()
346
+ {
347
+ Frag_UV = UV;
348
+ Frag_Color = Color;
349
+ gl_Position = ProjMtx * vec4(Position.xy,0,1);
350
+ }
351
+ SRC
352
+
353
+ vertex_shader_glsl_300_es = <<-'SRC'
354
+ precision mediump float;
355
+ layout (location = 0) in vec2 Position;
356
+ layout (location = 1) in vec2 UV;
357
+ layout (location = 2) in vec4 Color;
358
+ uniform mat4 ProjMtx;
359
+ out vec2 Frag_UV;
360
+ out vec4 Frag_Color;
361
+ void main()
362
+ {
363
+ Frag_UV = UV;
364
+ Frag_Color = Color;
365
+ gl_Position = ProjMtx * vec4(Position.xy,0,1);
366
+ }
367
+ SRC
368
+
369
+ vertex_shader_glsl_410_core = <<-'SRC'
370
+ layout (location = 0) in vec2 Position;
371
+ layout (location = 1) in vec2 UV;
372
+ layout (location = 2) in vec4 Color;
373
+ uniform mat4 ProjMtx;
374
+ out vec2 Frag_UV;
375
+ out vec4 Frag_Color;
376
+ void main()
377
+ {
378
+ Frag_UV = UV;
379
+ Frag_Color = Color;
380
+ gl_Position = ProjMtx * vec4(Position.xy,0,1);
381
+ }
382
+ SRC
383
+
384
+ fragment_shader_glsl_120 = <<-'SRC'
385
+ #ifdef GL::ES
386
+ precision mediump float;
387
+ #endif
388
+ uniform sampler2D Texture;
389
+ varying vec2 Frag_UV;
390
+ varying vec4 Frag_Color;
391
+ void main()
392
+ {
393
+ gl_FragColor = Frag_Color * texture2D(Texture, Frag_UV.st);
394
+ }
395
+ SRC
396
+
397
+ fragment_shader_glsl_130 = <<-'SRC'
398
+ uniform sampler2D Texture;
399
+ in vec2 Frag_UV;
400
+ in vec4 Frag_Color;
401
+ out vec4 Out_Color;
402
+ void main()
403
+ {
404
+ Out_Color = Frag_Color * texture(Texture, Frag_UV.st);
405
+ }
406
+ SRC
407
+
408
+ fragment_shader_glsl_300_es = <<-'SRC'
409
+ precision mediump float;
410
+ uniform sampler2D Texture;
411
+ in vec2 Frag_UV;
412
+ in vec4 Frag_Color;
413
+ layout (location = 0) out vec4 Out_Color;
414
+ void main()
415
+ {
416
+ Out_Color = Frag_Color * texture(Texture, Frag_UV.st);
417
+ }
418
+ SRC
419
+
420
+ fragment_shader_glsl_410_core = <<-'SRC'
421
+ in vec2 Frag_UV;
422
+ in vec4 Frag_Color;
423
+ uniform sampler2D Texture;
424
+ layout (location = 0) out vec4 Out_Color;
425
+ void main()
426
+ {
427
+ Out_Color = Frag_Color * texture(Texture, Frag_UV.st);
428
+ }
429
+ SRC
430
+
431
+ vertex_shader, fragment_shader = if glsl_version < 130
432
+ [vertex_shader_glsl_120, fragment_shader_glsl_120]
433
+ elsif glsl_version >= 410
434
+ [vertex_shader_glsl_410_core, fragment_shader_glsl_410_core]
435
+ elsif glsl_version == 300
436
+ [vertex_shader_glsl_300_es, fragment_shader_glsl_300_es]
437
+ else
438
+ [vertex_shader_glsl_130, fragment_shader_glsl_130]
439
+ end
440
+
441
+ vertex_shader.prepend(@@g_GlslVersionString + "\n")
442
+ vert_handle = GL.CreateShader(GL::VERTEX_SHADER)
443
+ GL.ShaderSource(vert_handle, 1, [vertex_shader].pack('p'), nil)
444
+ GL.CompileShader(vert_handle)
445
+ PrintShaderCompileStatus(vert_handle)
446
+
447
+ fragment_shader.prepend(@@g_GlslVersionString + "\n")
448
+ frag_handle = GL.CreateShader(GL::FRAGMENT_SHADER)
449
+ GL.ShaderSource(frag_handle, 1, [fragment_shader].pack('p'), [fragment_shader.size].pack('I'))
450
+ GL.CompileShader(frag_handle)
451
+ PrintShaderCompileStatus(frag_handle)
452
+
453
+ @@g_ShaderHandle = GL.CreateProgram()
454
+ GL.AttachShader(@@g_ShaderHandle, vert_handle)
455
+ GL.AttachShader(@@g_ShaderHandle, frag_handle)
456
+ GL.LinkProgram(@@g_ShaderHandle)
457
+ PrintProgramLinkStatus(@@g_ShaderHandle)
458
+
459
+ GL.DetachShader(@@g_ShaderHandle, vert_handle)
460
+ GL.DetachShader(@@g_ShaderHandle, frag_handle)
461
+ GL.DeleteShader(vert_handle)
462
+ GL.DeleteShader(frag_handle)
463
+
464
+ @@g_AttribLocationTex = GL.GetUniformLocation(@@g_ShaderHandle, "Texture")
465
+ @@g_AttribLocationProjMtx = GL.GetUniformLocation(@@g_ShaderHandle, "ProjMtx")
466
+
467
+ @@g_AttribLocationVtxPos = GL.GetAttribLocation(@@g_ShaderHandle, "Position")
468
+ @@g_AttribLocationVtxUV = GL.GetAttribLocation(@@g_ShaderHandle, "UV")
469
+ @@g_AttribLocationVtxColor = GL.GetAttribLocation(@@g_ShaderHandle, "Color")
470
+
471
+ # Create buffers
472
+ posBuf = ' ' * 4
473
+ GL.GenBuffers(1, posBuf)
474
+ GL.BindBuffer(GL::ARRAY_BUFFER, posBuf.unpack('L')[0])
475
+
476
+ @@g_VboHandle, @@g_ElementsHandle = ' ' * 4, ' ' * 4
477
+ GL.GenBuffers(1, @@g_VboHandle)
478
+ GL.GenBuffers(1, @@g_ElementsHandle)
479
+ @@g_VboHandle = @@g_VboHandle.unpack1('L')
480
+ @@g_ElementsHandle = @@g_ElementsHandle.unpack1('L')
481
+
482
+ ImplOpenGL3_CreateFontsTexture()
483
+
484
+ # Restore modified GL state
485
+ GL.BindTexture(GL::TEXTURE_2D, last_texture)
486
+ GL.BindBuffer(GL::ARRAY_BUFFER, last_array_buffer)
487
+ GL.BindVertexArray(last_vertex_array)
488
+
489
+ return true
490
+ end
491
+
492
+ def self.ImplOpenGL3_DestroyDeviceObjects()
493
+ if @@g_VboHandle != 0
494
+ GL.DeleteBuffers(1, [@@g_VboHandle].pack('L'))
495
+ @@g_VboHandle = 0
496
+ end
497
+ if @@g_ElementsHandle != 0
498
+ GL.DeleteBuffers(1, [@@g_ElementsHandle].pack('L'))
499
+ @@g_ElementsHandle = 0
500
+ end
501
+ if @@g_ShaderHandle != 0
502
+ GL.DeleteProgram(@@g_ShaderHandle)
503
+ @@g_ShaderHandle = 0
504
+ end
505
+
506
+ ImplOpenGL3_DestroyFontsTexture()
507
+ end
508
+
509
+ end