Closed cedlemo closed 9 years ago
Good news!
After another tests I am able to display the triangle. Here is the script:
=begin
gtkglarea2.rb draw a white triangle on a default black background
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 'glfw'
require 'opengl'
require 'glu'
case OpenGL.get_platform
when :OPENGL_PLATFORM_WINDOWS
OpenGL.load_lib('opengl32.dll', 'C:/Windows/System32')
GLU.load_lib('GLU32.dll', 'C:/Windows/System32')
GLFW.load_lib('glfw3.dll', '..')
when :OPENGL_PLATFORM_MACOSX
OpenGL.load_lib('libGL.dylib', '/System/Library/Frameworks/OpenGL.framework/Libraries')
GLU.load_lib('libGLU.dylib', '/System/Library/Frameworks/OpenGL.framework/Libraries')
GLFW.load_lib('libglfw.dylib', '..')
when :OPENGL_PLATFORM_LINUX
OpenGL.load_lib('libGL.so', '/usr/lib')
GLU.load_lib('libGLU.so', '/usr/lib')
GLFW.load_lib('libglfw.so', '/usr/lib')
else
raise RuntimeError, "Unsupported platform."
end
include GLFW
include OpenGL
include GLU
window = Gtk::Window.new("OpenGL widget 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
# Set the created shader program as current
#glUseProgram(prog_handle)
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)
glUseProgram(shader_program)
glBindVertexArray(gl_vao)
glDrawArrays(GL_TRIANGLES, 0, 3)
glFlush
false
end
glarea.signal_connect("unrealize") do |widget|
puts "unrealize"
glDisableVertexAttribArray(0)
true
end
window.signal_connect("destroy") { Gtk.main_quit }
window.show_all
Gtk.main
I will try to clean this and trully understand the differences (I found the solution here: http://stackoverflow.com/questions/30337845/gldrawarrays-not-working-using-gtkglarea-in-gtk3)
If you have any advices on this let me know .
Hi,
I think you can remove all GLFW and GLU initialization lines because this sample doesn't use any features of them.
require "gtk3"
require 'opengl'
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
#
# ...
#
Anyway, congratulations. I'm going to release opengl-bindings 1.4.0 that contains `load_lib' API. Thank you.
I think you can remove all GLFW and GLU initialization lines
Yes you are right.
You can find the first working script here : https://github.com/ruby-gnome2/ruby-gnome2/pull/499
Hi @vaiorabbit,
I am trying to find out how to use your bindings with the gtk3 bindings from ruby-gnome2. Unfortunately, I am not an expert in OpenGl so I have written those 2 little scripts :
This one which should display a white triangle on a black background:
And this one that use shaders
I haven't any issue except that the triangle is not drawing in the two scripts (the background is in grey like I set it with
glClearColor
. Maybe you could find an error in the opengl code that I use.Thank