Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use glDeleteVertexArrays #18

Closed
cedlemo opened this issue Aug 1, 2015 · 3 comments
Closed

How to use glDeleteVertexArrays #18

cedlemo opened this issue Aug 1, 2015 · 3 comments

Comments

@cedlemo
Copy link
Contributor

cedlemo commented Aug 1, 2015

here is the example:

=begin
  gtkglarea2.rb draw a triangle using shaders on a grey background
  this script need the opengl-bindings gem from :
  https://github.com/vaiorabbit/ruby-opengl

  gem install opengl-bindings

  sources:
  http://antongerdelan.net/opengl/hellotriangle.html
  opengl-bindings/sample/RedBook/varray
  opengl-bindings/sample/GLES/gles.rb
  http://www.opengl-tutorial.org/beginners-tutorials/tutorial-2-the-first-triangle/
  https://developer.gnome.org/gtk3/stable/GtkGLArea.html
  https://www.bassi.io/articles/2015/02/17/using-opengl-with-gtk/
  http://stackoverflow.com/questions/30337845/gldrawarrays-not-working-using-gtkglarea-in-gtk3
=end

require "gtk3"
require "opengl"

unless Gtk::Version.or_later?(3, 16, 0)
  puts "This sample requires GTK+ 3.16.0 or later: #{Gtk::Version::STRING}"
  exit
end

case OpenGL.get_platform
when :OPENGL_PLATFORM_WINDOWS
  OpenGL.load_lib('opengl32.dll', 'C:/Windows/System32')
when :OPENGL_PLATFORM_MACOSX
  OpenGL.load_lib('libGL.dylib', '/System/Library/Frameworks/OpenGL.framework/Libraries')
when :OPENGL_PLATFORM_LINUX
  OpenGL.load_lib('libGL.so', '/usr/lib')
else
  raise RuntimeError, "Unsupported platform."
end

include OpenGL

window = Gtk::Window.new("OpenGL widget shaders test")

window.set_size_request(400, 400)
glarea = Gtk::GLArea.new

window.add(glarea)

vertex_shader = <<EOF
#version 400
in vec3 vp;
void main () {
  gl_Position = vec4 (vp, 1.0);
};
EOF

fragment_shader = <<EOF
#version 400
out vec4 frag_colour;
void main () {
  frag_colour = vec4 (0.5, 0.0, 0.5, 1.0);
};
EOF

def setup_shaders(vertex, fragment)

  # Load the shaders sources
  vs_handle = glCreateShader(GL_VERTEX_SHADER)
  fs_handle = glCreateShader(GL_FRAGMENT_SHADER)

  glShaderSource(vs_handle, 1, [vertex].pack("p"), [vertex.bytesize].pack("I"))

  glShaderSource(fs_handle, 1, [fragment].pack("p"), [fragment.bytesize].pack("I"))

  # Compile the vertex shader
  glCompileShader(vs_handle)
  # Check the vertex shader compilation
  vertCompiled_buf = "    "
  glGetShaderiv(vs_handle, GL_COMPILE_STATUS, vertCompiled_buf)
  vertCompiled = vertCompiled_buf.unpack("L")[0]
  if vertCompiled == 0
    infoLog = " " * 1024
    glGetShaderInfoLog(vs_handle, 1023, nil, infoLog)
    puts "Shader InfoLog:\n#{infoLog}\n"
  end

  # Compile the fragment shader
  glCompileShader(fs_handle)
  # Check the fragment shader compilation
  fragCompiled_buf = "    "
  glGetShaderiv(fs_handle, GL_COMPILE_STATUS, fragCompiled_buf)
  fragCompiled = fragCompiled_buf.unpack('L')[0]
  if fragCompiled == 0
    infoLog = " " * 1024
    glGetShaderInfoLog(fs_handle, 1023, nil, infoLog)
    puts "Shader InfoLog:\n#{infoLog}\n"
  end
  return false if (vertCompiled == 0 || fragCompiled == 0)

  # Load those 2 shaders (vertex and fragment) into a GPU shader program
  prog_handle = glCreateProgram()
  glAttachShader(prog_handle,vs_handle)
  glAttachShader(prog_handle,fs_handle)

  glLinkProgram(prog_handle)

  # Check if the program is valid
  linked_buf = "    "
  glGetProgramiv(prog_handle, GL_LINK_STATUS, linked_buf)
  linked = linked_buf.unpack("L")[0]
  if linked == 0
    infoLog = " " * 1024
    glGetProgramInfoLog(prog_handle, 1023, nil, infoLog)
    puts "Program InfoLog:\n#{infoLog}\n"
  end
  return false if linked==0

  return true, prog_handle
end

shader_program = nil
gl_vao = nil

glarea.signal_connect("realize") do |widget|
  widget.make_current
  puts "realize"
  # Define a triangle in a vertex buffer ( Vertex Buffer Object)

  points = [
    0.0, 0.5, 0.0,  #x1, y1, z1
    0.5, -0.5, 0.0, #x2, y2, z2
    -0.5, -0.5, 0.0 #x3, y3, z3
  ]
  vao_buf = "    "
  glGenVertexArrays(1, vao_buf)
  gl_vao = vao_buf.unpack("L")[0]
  glBindVertexArray(gl_vao)
  # We copy those points onto the graphics card in a unit called vertex buffer object (vbo).
  # Create an empty buffer
  vbo_buf = "    "
  glGenBuffers(1, vbo_buf)
  g_vbo = vbo_buf.unpack("L")[0]
  # Set the empty buffer as the current OpenGL's state machine by "binding"
  glBindBuffer(GL_ARRAY_BUFFER, g_vbo)
  # Copy the points in the currently bound buffer
  glBufferData(GL_ARRAY_BUFFER,
               3 * 4 * Fiddle::SIZEOF_FLOAT,
               points.pack("F*"),
               GL_STATIC_DRAW
              )

  # First attribute buffer : vertices
  glEnableVertexAttribArray(0)
  glVertexAttribPointer(0,        # No particular reason for 0
                        3,        # size
                        GL_FLOAT, # type
                        GL_FALSE, # normalized?
                        0,        # stride
                        0         # array buffer offset
                       )

  glBindVertexArray(0)
  # Load the shaders:
  ok, shader_program = setup_shaders(vertex_shader, fragment_shader)
end

glarea.signal_connect("render") do |widget, context|
  puts "render"
  glClearColor(0.3, 0.3, 0.3, 1)
  glClear(GL_COLOR_BUFFER_BIT)
  # Set the created shader program as current
  glUseProgram(shader_program)
  glBindVertexArray(gl_vao)
  glDrawArrays(GL_TRIANGLES, 0, 3)
  true
end

glarea.signal_connect("unrealize") do |widget|
  puts "unrealize"
  widget.make_current
  glDeleteVertexArrays(1, gl_vao);
  glDeleteProgram(shader_program);
end

window.signal_connect("destroy") { Gtk.main_quit }

window.show_all

Gtk.main

For the signal "unrealize" of the widget I try to clean all the allocated data (vao and shader program).

The script works well unitl I close the window which trigger the "unrealize" event and the glVertexArrays result in a segfault:

ruby gtkglarea2.rb                                                                                                                                                            [10:10:49] 
realize
render
render
unrealize
/home/cedlemo/.gem/ruby/2.2.0/gems/opengl-bindings-1.3.14/lib/opengl_command.rb:4439: [BUG] Segmentation fault at 0x00000000000001
ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]

-- Control frame information -----------------------------------------------
c:0008 p:---- s:0034 e:000033 CFUNC  :call
c:0007 p:0027 s:0029 e:000028 METHOD /home/cedlemo/.gem/ruby/2.2.0/gems/opengl-bindings-1.3.14/lib/opengl_command.rb:4439
c:0006 p:0025 s:0023 e:000022 BLOCK  gtkglarea2.rb:178 [FINISH]
c:0005 p:---- s:0020 e:000019 CFUNC  :call
c:0004 p:---- s:0018 e:000017 CFUNC  :invoke
c:0003 p:0058 s:0014 e:000013 LAMBDA /home/cedlemo/.gem/ruby/2.2.0/gems/gobject-introspection-2.2.6/lib/gobject-introspection/loader.rb:114 [FINISH]
c:0002 p:0327 s:0010 E:000430 EVAL   gtkglarea2.rb:186 [FINISH]
c:0001 p:0000 s:0002 E:000420 TOP    [FINISH]

-- Ruby level backtrace information ----------------------------------------
gtkglarea2.rb:186:in `<main>'
/home/cedlemo/.gem/ruby/2.2.0/gems/gobject-introspection-2.2.6/lib/gobject-introspection/loader.rb:114:in `block in define_singleton_method'
/home/cedlemo/.gem/ruby/2.2.0/gems/gobject-introspection-2.2.6/lib/gobject-introspection/loader.rb:114:in `invoke'
/home/cedlemo/.gem/ruby/2.2.0/gems/gobject-introspection-2.2.6/lib/gobject-introspection/loader.rb:114:in `call'
gtkglarea2.rb:178:in `block in <main>'
/home/cedlemo/.gem/ruby/2.2.0/gems/opengl-bindings-1.3.14/lib/opengl_command.rb:4439:in `glDeleteVertexArrays'
/home/cedlemo/.gem/ruby/2.2.0/gems/opengl-bindings-1.3.14/lib/opengl_command.rb:4439:in `call'

-- Machine register context ------------------------------------------------
 RIP: 0x00007f587e9de75e RBP: 0x0000000040279000 RSP: 0x00007fffaa4c9ac0
 RAX: 0x000000000476da90 RBX: 0x000000000476da90 RCX: 0x0000000000000001
 RDX: 0x0000000000000001 RDI: 0x0000000040279000 RSI: 0x00000000044e8660
  R8: 0x000000000476da90  R9: 0x0000000001c715f0 R10: 0x00007fffaa4c9a80
 R11: 0x00007f58812c4ac0 R12: 0x000000000476da90 R13: 0x0000000000000001
 R14: 0x00000000044e8660 R15: 0x0000000040279000 EFL: 0x0000000000010202

-- C level backtrace information -------------------------------------------
/usr/lib/libruby.so.2.2 [0x7f5887053915]
/usr/lib/libruby.so.2.2 [0x7f5887053b4c]
/usr/lib/libruby.so.2.2 [0x7f5886f2dd4b]
/usr/lib/libruby.so.2.2 [0x7f5886fe532e]
/usr/lib/libc.so.6 [0x7f5886b4f5b0]
/usr/lib/libnvidia-glcore.so.352.21 [0x7f587e9de75e]
/usr/lib/libnvidia-glcore.so.352.21 [0x7f587e931c6d]
/usr/lib/libffi.so.6(ffi_call_unix64+0x4c) [0x7f588471e1f0]
/usr/lib/libffi.so.6(ffi_call+0x2f8) [0x7f588471dc58]
/usr/lib/ruby/2.2.0/x86_64-linux/fiddle.so [0x7f587bf39979]
/usr/lib/libruby.so.2.2 [0x7f588703ad30]
/usr/lib/libruby.so.2.2 [0x7f588704b44d]
/usr/lib/libruby.so.2.2 [0x7f588703fcca]
/usr/lib/libruby.so.2.2 [0x7f5887044a28]
/usr/lib/libruby.so.2.2 [0x7f5887049e5f]
/usr/lib/libruby.so.2.2 [0x7f588704a020]
/usr/lib/libruby.so.2.2 [0x7f588704a108]
/usr/lib/libruby.so.2.2 [0x7f5886f38fb2]
/usr/lib/libruby.so.2.2 [0x7f58870463aa]
/usr/lib/libruby.so.2.2 [0x7f58870475f2]
/usr/lib/libruby.so.2.2(rb_apply+0xb2) [0x7f5887047a42]
/home/cedlemo/.gem/ruby/2.2.0/extensions/x86_64-linux/2.2.0/glib2-2.2.6/glib2.so(rclosure_marshal_do+0x5f) [0x7f588510b30f]
/usr/lib/libruby.so.2.2(rb_protect+0xfb) [0x7f5886f3327b]
/home/cedlemo/.gem/ruby/2.2.0/extensions/x86_64-linux/2.2.0/glib2-2.2.6/glib2.so(rbgutil_protect+0x27) [0x7f588510bf37]
/home/cedlemo/.gem/ruby/2.2.0/extensions/x86_64-linux/2.2.0/glib2-2.2.6/glib2.so(rbgutil_invoke_callback+0x44) [0x7f588510c034]
/home/cedlemo/.gem/ruby/2.2.0/extensions/x86_64-linux/2.2.0/glib2-2.2.6/glib2.so [0x7f588510b669]
/usr/lib/libgobject-2.0.so.0(g_closure_invoke+0x145) [0x7f5884eaf2f5]
/usr/lib/libgobject-2.0.so.0 [0x7f5884ec102c]
/usr/lib/libgobject-2.0.so.0(g_signal_emit_valist+0xfd8) [0x7f5884ec9688]
/usr/lib/libgobject-2.0.so.0(g_signal_emit+0x8f) [0x7f5884ec98ef]
/usr/lib/libgtk-3.so.0(gtk_widget_unrealize+0xc1) [0x7f58799e7fd1]
/usr/lib/libgtk-3.so.0 [0x7f58799f0c19]
/usr/lib/libgtk-3.so.0 [0x7f58799e7481]
/usr/lib/libgtk-3.so.0 [0x7f58799f46fe]
/usr/lib/libgobject-2.0.so.0(g_closure_invoke+0x145) [0x7f5884eaf2f5]
/usr/lib/libgobject-2.0.so.0 [0x7f5884ec0f22]
/usr/lib/libgobject-2.0.so.0(g_signal_emit_valist+0xfd8) [0x7f5884ec9688]
/usr/lib/libgobject-2.0.so.0(g_signal_emit+0x8f) [0x7f5884ec98ef]
/usr/lib/libgtk-3.so.0(gtk_widget_unrealize+0xc1) [0x7f58799e7fd1]
/usr/lib/libgtk-3.so.0 [0x7f58799e80e8]
/usr/lib/libgtk-3.so.0 [0x7f58799f7e20]
/usr/lib/libgobject-2.0.so.0(g_object_run_dispose+0x48) [0x7f5884eb5c28]
/usr/lib/libgtk-3.so.0(gtk_main_do_event+0x574) [0x7f58798a20a4]
/usr/lib/libgdk-3.so.0 [0x7f587ba4d7b2]
/usr/lib/libglib-2.0.so.0(g_main_context_dispatch+0x24d) [0x7f5884bda9fd]
/usr/lib/libglib-2.0.so.0 [0x7f5884bdace0]
/usr/lib/libglib-2.0.so.0(g_main_loop_run+0xc2) [0x7f5884bdb002]
/usr/lib/libgtk-3.so.0(gtk_main+0x85) [0x7f58798a1485]
/usr/lib/libffi.so.6(ffi_call_unix64+0x4c) [0x7f588471e1f0]
/usr/lib/libffi.so.6(ffi_call+0x2f8) [0x7f588471dc58]
/usr/lib/libgirepository-1.0.so.1(g_callable_info_invoke+0x4e9) [0x7f58842d3449]
/usr/lib/libgirepository-1.0.so.1(g_function_info_invoke+0x9a) [0x7f58842d479a]
/home/cedlemo/.gem/ruby/2.2.0/extensions/x86_64-linux/2.2.0/gobject-introspection-2.2.6/gobject_introspection.so(rb_gi_function_info_invoke_raw_call+0x2c) [0x7f5884507d0c]
/home/cedlemo/.gem/ruby/2.2.0/extensions/x86_64-linux/2.2.0/gobject-introspection-2.2.6/gobject_introspection.so(rb_gi_function_info_invoke_raw+0x9c2) [0x7f58845089e2]
/home/cedlemo/.gem/ruby/2.2.0/extensions/x86_64-linux/2.2.0/gobject-introspection-2.2.6/gobject_introspection.so [0x7f5884508e55]
/usr/lib/libruby.so.2.2 [0x7f588703ad30]
/usr/lib/libruby.so.2.2 [0x7f588704b44d]
/usr/lib/libruby.so.2.2 [0x7f588703fc1f]
/usr/lib/libruby.so.2.2 [0x7f5887044a28]
/usr/lib/libruby.so.2.2 [0x7f5887049c18]
/usr/lib/libruby.so.2.2 [0x7f588704a020]
/usr/lib/libruby.so.2.2 [0x7f588704a3f4]
/usr/lib/libruby.so.2.2 [0x7f588704b51d]
/usr/lib/libruby.so.2.2 [0x7f588703fcca]
/usr/lib/libruby.so.2.2 [0x7f5887044a28]
/usr/lib/libruby.so.2.2(rb_iseq_eval_main+0x7f) [0x7f588704618f]
/usr/lib/libruby.so.2.2 [0x7f5886f30ebf]
/usr/lib/libruby.so.2.2(ruby_exec_node+0x1d) [0x7f5886f32a2d]
/usr/lib/libruby.so.2.2(ruby_run_node+0x1e) [0x7f5886f348ae]
ruby [0x4008ab]
/usr/lib/libc.so.6(__libc_start_main+0xf0) [0x7f5886b3c790]
ruby(_start+0x29) [0x4008d9]

-- Other runtime information -----------------------------------------------

* Loaded script: gtkglarea2.rb

I don't really know how to use glDeleteVertexArrays and I haven't found any example in your sample scripts.

Regards

@vaiorabbit
Copy link
Owner

Though I haven't executed your script yet (sorry), generally speaking,
OpenGL object handles created by `glGenXXXX(nElems, ptrToArray)'

ex.)
glGenVertexArrays(1, vao_buf)
gl_vao = vao_buf.unpack("L")[0] # `[0]' == The 1st element of array.

should be deleted by passing an array of handles like:

glDeleteVertexArrays( 1, [gl_vao].pack('L') )

Line 57 of /GLExcess/texture.rb may be helpful to understand. Thank you.

@cedlemo
Copy link
Contributor Author

cedlemo commented Aug 1, 2015

I didn't understand how it should work sorry. Now it is clear Thank a lot.

You can see the final script here :
ruby-gnome/ruby-gnome#500

@cedlemo cedlemo closed this as completed Aug 1, 2015
@vaiorabbit
Copy link
Owner

Good. I've just released opengl-bindings 1.4.0.
https://rubygems.org/gems/opengl-bindings
Now you can safely commit your new sample scripts that use `load_lib'. Thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants