class Roglew::RenderHandle

Public Class Methods

current() click to toggle source
# File lib/roglew/render_handle.rb, line 6
def current
  stack.empty? ? nil : peek.first
end
new(display, screen, window, version = nil) click to toggle source
# File lib/roglew/platform/linux/render_handle.rb, line 3
def initialize(display, screen, window, version = nil)
  @display, @screen, @window = display, screen, window
  @loaded_extensions = Set.new

  extension_list(:glx).each { |ext| load_extension(ext) }

  attrList = FFI::MemoryPointer.new(:int, 11)
  attrList.write_array_of_int([
    GLX::RGBA,       GLX::DOUBLEBUFFER,
    GLX::RED_SIZE,   4,
    GLX::GREEN_SIZE, 4,
    GLX::BLUE_SIZE,  4,
    GLX::DEPTH_SIZE, 16
  ])
  @visual = GLX.ChooseVisual(@display, screen, attrList)
  @context = GLX.CreateContext(@display, @visual, nil, true)

  old_context = nil

  bind do
    #check version
    max_version = glGetString(GL::VERSION).split('.', 2).map!(&:to_i)

    #if max OpelGL version is less than requested, give error
    raise ArgumentError, "unsupported version #{version.join('.')}" if version && (max_version <=> version < 0)

    @version = version || max_version
    extension_list(:core).each { |ext| load_extension(ext) }
    old_context, @context = @context, upgrade_context if @version[0] > 2
    extension_list(:gl, :platform).each { |ext| load_extension(ext) }
  end

  GLX.delete_context(display, old_context) if old_context

  self.class.finalize(self, @display, @context)
end

Private Class Methods

def_function(name, func) click to toggle source
# File lib/roglew/render_handle.rb, line 11
def def_function(name, func)
  define_method(name) { |*args| func.(*args) }
end
finalize(*args) click to toggle source
# File lib/roglew/render_handle.rb, line 15
def finalize(*args)
  proc do
    #puts 'releasing a render context'
    GL.platform_module.delete_context(*args)
  end
end
peek() click to toggle source
# File lib/roglew/render_handle.rb, line 22
def peek
  stack.last
end
push(rh, rc) click to toggle source
# File lib/roglew/render_handle.rb, line 26
def push(rh, rc)
  stack.push([rh, rc])
end
register_extensions(extensions) click to toggle source
# File lib/roglew/render_handle.rb, line 34
def register_extensions(extensions)
  extensions = Hash[extensions.map { |k, v| [k.to_sym, v] }]
  @registered_extensions.merge!(extensions)
  nil
end
stack() click to toggle source
# File lib/roglew/render_handle.rb, line 30
def stack
  @stack ||= []
end
unregister_extensions(*extensions) click to toggle source
# File lib/roglew/render_handle.rb, line 40
def unregister_extensions(*extensions)
  extensions.map! { |e| e.to_sym }.each { |e| @registered_extensions.delete(e) }
  nil
end

Public Instance Methods

attribs() click to toggle source

platform specific implementations:

#initialize
#get_proc_address
#make_current
#remove_current
#swap_buffers
# File lib/roglew/render_handle.rb, line 53
def attribs
  @attribs.dup
end
bind() { |ctx| ... } click to toggle source
# File lib/roglew/render_handle.rb, line 57
def bind
  if current?
    ctx = RenderContext.current
  else
    stack = self.class.send(:stack)
    i = stack.rindex { |rh, _| rh == self }
    ctx = i ? stack[i].last : create_context
    make_current
  end
  self.class.send(:push, self, ctx)

  return ctx unless block_given?
  result = yield ctx
  ctx.finished
  result
end
current?() click to toggle source
# File lib/roglew/render_handle.rb, line 80
def current?
  self.class.current == self
end
extension_list(*types) click to toggle source
# File lib/roglew/render_handle.rb, line 74
def extension_list(*types)
  list = types.flat_map { |type| send("extension_list_#{type}") }
  list.uniq!
  list
end
load_extension(ext) click to toggle source
# File lib/roglew/render_handle.rb, line 84
def load_extension(ext)
  LOGGER.debug "load_extension: #{ext}"
  ext = ext.to_sym
  @loaded_extensions << ext

  unless Object.const_defined?(ext)
    reg = self.class.instance_variable_get(:@registered_extensions)
    filename = reg[ext] || File.expand_path("extensions/#{ext}.rb", __dir__)
    require filename if File.exists?(filename)
  end

  return unless Object.const_defined?(ext)
  mod = Object.const_get(ext)
  if mod.const_defined?(:RenderHandle)
    modrh = mod.const_get(:RenderHandle)
    singleton_class.send(:include, modrh)

    bind do |rc|
      modrh.functions.each do |options, list|
        list.each do |name, parameters, ret_type|
          function = if options.include?(:ffi)
                       if name =~ /^(glX|wgl)/
                         GL.platform_module.attach_function(name[3..-1], name, parameters, ret_type)
                       else
                         GL.attach_function(name[2..-1], name, parameters, ret_type)
                       end
                     else
                       rc.get_function(name, parameters, ret_type)
                     end
          define_singleton_method(name) { |*a| function.(*a) } if function
        end if !options.include?(:compatibility) || ((@version <=> [3, 0]) <= 0)
      end if modrh.respond_to?(:functions)
    end
  end

  nil
end
loaded_extensions() click to toggle source
# File lib/roglew/render_handle.rb, line 122
def loaded_extensions
  @loaded_extensions.dup
end
supports?(extension) click to toggle source
# File lib/roglew/render_handle.rb, line 126
def supports?(extension)
  !!@loaded_extensions[extension]
end
version() click to toggle source
# File lib/roglew/render_handle.rb, line 130
def version
  @version.dup
end

Private Instance Methods

create_context() click to toggle source
# File lib/roglew/render_handle.rb, line 135
def create_context
  RenderContext.new(self)
end
extension_list_core() click to toggle source
# File lib/roglew/render_handle.rb, line 139
def extension_list_core
  dirs = Dir["#{File.expand_path('../extensions', __FILE__)}/GL_VERSION_*.rb"]
  dirs.map! { |f| File.basename(f, '.rb') }
  dirs.select! { |f| (f.gsub('GL_VERSION_', '').split('_', 2).map!(&:to_i) <=> @version) <= 0 }
  dirs
end
extension_list_gl() click to toggle source
# File lib/roglew/render_handle.rb, line 146
def extension_list_gl
  if @version[0] < 3
    glGetString(GL::EXTENSIONS).split
  else
    RenderContext.current.num_extensions.times.map { |i| glGetStringi(GL::EXTENSIONS, i) }
  end.map!(&:to_sym)
end