GlimR 0.1 Ruby OpenGL Widget Kit 2006-07-14


glimr.rubyforge.org

Under development. Watch your head.

Funded as one of Ruby Central Inc.‘s Google Summer of Code 2006 projects.

code.google.com/soc/

Installation:


Requirements:

* Ruby OpenGL bindings and GLUT
* Ruby/SDL with SDL::TTF support

To install:

(sudo) ruby setup.rb

Should install and run on Windows, Linux and OS X.

How to use:


GlimR is an event-driven GUI toolkit.

You write programs by creating widgets, attaching them to a parent widget and setting event listeners to respond to user input.

GlimR can be used as either a stand-alone GUI toolkit or embedded as a part of an OpenGL application.

Currently GlimR has simple low-level widgets and you need to build dialogs and such from smaller bits.

Here’s a small GlimR program:

require ‘glimr’ include GlimR

name_form = VLayout.new(

:expand_height => true, :expand_width => true,
:align => :center, :valign => :middle)

label = Label.new(:text => “Enter your name:”) name_input = TextInput.new(:text => “”) submit = Button.new(:label => “OK”){|o,e|

name_form.attach Label.new(:text => "Hi, #{name_input.text}!")

} name_form.attach label, name_input, submit

window = GLUTWindow.new(400, 200, “My App”) window.attach name_form window.run

See tests/integration_tests/ for more sample code.

Embedding:


To embed GlimR in an OpenGL application, do this:

  1. Create a GlimR::Viewport as the root of your GlimR scene.

  2. Set the viewport’s width and height to your window’s width and height.

  3. Send user input events, window reshape events and a frame event to the viewport. See an example on how to do this in lib/glimr/renderer/glutwindow.rb.

  4. After drawing your OpenGL frame – but before swapping buffers – draw the viewport by calling viewport.render

To avoid loading GLUT, set $glimr_no_glut = true before loading GlimR.

To draw the GUI only when it has changed, render the viewport to a texture and poll viewport.changed? to figure out if anything redraw-worthy has taken place.

E.g. hypothetical frame loop:

input_events.each{|ev| viewport.multicast_event(ev) }
if reshape_event
  viewport.multicast_event(reshape_event)
  reshape_event = false
end
viewport.multicast_event(frame_event)
if viewport.changed?
  gui_texture.render_into(w,h){ viewport.render }
end

draw_frame

gui_texture.draw_on_screen

Implementation of gui_texture left as an exercise for the reader.

Code structure:


— EVENTS

+ lib/glimr/event.rb - GlimR::Event
  - Events are glorified OpenStructs
  - conforms to the DOM2 Event interface (but no subclasses)

+ lib/glimr/eventlistener.rb - GlimR::EventListener
  - EventListener mixin
  - conforms to the DOM2 EventListener interface
    (plus event multicasting)
  - if you're ever used JavaScript, you should feel comfy

— UTILITIES

+ lib/glimr/configurable.rb - Configurable
  - Configurable mixin for Hash-based initialization that works
    with inheritance

+ lib/glimr/layoutable.rb - GlimR::Layoutable
  - Layoutable mixin
  - used to make objects get layouted
  - Widgets and Layouts are Layoutable

+ lib/glimr/util.rb
  - utility classes and core class extensions
    (metaprogramming helpers mostly)

— WIDGETS

+ lib/glimr/widget.rb - GlimR::Widget
  - base GlimR widget class
  - inherits from GlimR::Model (see below)
  - is Layoutable and EventListener

+ lib/glimr/widgets.rb
  - loads widgets from widgets/

+ lib/glimr/default_theme/
  - the theme dir contains the images and fonts used by the widgets

+ lib/glimr/widgets/
  - all different widgets

  + lib/glimr/layout.rb - GlimR::Layout, GlimR::VLayout, GlimR::HLayout
    - layout classes, inherit from GlimR::Widget

  + button.rb - Button
  + checkbox.rb - CheckBox
  + radiogroup.rb - RadioGroup

  + container.rb - Container
    - viewport wrapper
  + scrollable_container.rb - ScrollableContainer
  + resizer.rb - Resizer
    - resizing knob
  + scrollbar.rb - VScrollBar, HScrollBar

  + image.rb - Image
  + stretchable_image.rb - StretchableImage

  + label.rb - Label
  + text_editor.rb - TextInput

— RENDERER

+ lib/glimr/renderer.rb
  - loads renderer core classes
  - loads standalone renderer if $glimr_no_glut is nil or false

+ lib/glimr/renderer_core.rb
  - loads renderer core classes

+ lib/glimr/renderer/
  - rendering-related classes

  + glutwindow.rb - Glimr::GLUTWindow
    - stand-alone GLUT window
    - creates GL context
    - passes input events to the viewport
    - ctrl-q quits

  + sceneobject.rb - GlimR::SceneObject
    - class that other rendering classes inherit from
    - defines child-parent relationships and state collapsing defaults

  + viewport.rb - GlimR::Viewport
    - the root of the GlimR drawing hierarchy
    - captures input events, munges them to fit its view of the world
      and passes them to the scene below
    - handles clearing screen, setting up camera, clipping to viewport,
      turning mouse_down & mouse_up into click

  + model.rb - GlimR::Model
    - convenience class for managing a transform with attached
      material, texture, shader and geometry

  + geometry.rb - GlimR::Geometry
    - drawable geometry
    - uses vertex arrays

  + transform.rb - GlimR::Transform, GlimR::AngleAxis, GlimR::Quaternion
    - does OpenGL transforms: translation, scaling, rotation
      (with angle-axis or quaternion), custom transform matrix

  + texture.rb - GlimR::Texture
    - manages OpenGL textures
    - handles loading image files to textures

Author:


Ilmari Heikkinen <[email protected]>