Abstract
FOX provides extensive support for OpenGL through its
FXGLCanvas
and FXGLViewer
widgets, and FXRuby in turn provides interfaces to those classes. By
combining FXRuby with the OpenGL interface for Ruby (described below) you
can develop very powerful 3-D graphics applications. This chapter gives
you the information you'll need to get started.
OpenGL is a platform-independent API for 2D and 3D graphics. The home page is http://www.opengl.org. Because it's a fairly open standard, highly optimized OpenGL drivers are available for most operating systems (including Windows and Linux).
This extension module, developed by Yoshiyuki Kusano, provides interfaces to not only the basic OpenGL API, but also the GLU and GLUT APIs. As of this writing, the currently released version is 0.32d and is available for download from http://www2.giganet.net/~yoshi/rbogl-0.32d.tgz. Be sure to check the Ruby Application Archive for the latest version of this extension as it is still under development.
Once you've downloaded the tarball, you should extract its contents to the working directory of your choice by typing:
$ tar xzf rbogl-0.32d.tgz
After executing this command you should have a new opengl
(not rbogl-0.32b
) subdirectory. Change to this
directory and then type:
$ ruby extconf.rb
This should create a Makefile
configured
appropriately for your local Ruby installation. To now build the OpenGL
module, type:
$ make
You can safely ignore the warning(s) about
glut_KeyboardFunc
when it's compiling
glut.c
. Well, I ignore them and it hasn't hurt me yet
;) Assuming you get an otherwise clean build, install the OpenGL
extensions by typing:
$ make site-install
Please note that I'm not the maintainer of this particular Ruby extension, so I can't really accept bug fixes for it. But if you're having trouble integrating Ruby/OpenGL with FXRuby, let me know and we'll see what we can do.
An FXGLVisual
object describes the
capabilities of an FXGLCanvas
or
FXGLViewer
window. Typically, an X server supports
many different visuals with varying capabilities, but the ones with
greater capabilities require more resources than those with fewer
capbilities. To construct an FXGLVisual
object,
just call FXGLVisual.new
:
aVisual = FXGLVisual.new(theApp, VISUAL_DOUBLEBUFFER)
The first argument to FXGLVisual.new
is a
reference to the application object. The second argument is a set of
options indicating the requested capabilities for the
visual. If one or more of the requested capabilities aren't available, FOX
will try to gracefully degrade to a working GL visual; but if you're
counting on a specific capability, be sure to check the returned visual to
see if it actually supports that capability. For example, say you request
a visual with double-buffering and stereographic capabilities:
anotherVisual = FXGLVisual.new(theApp, VISUAL_DOUBLEBUFFER | VISUAL_STEREO)
Double-buffering is pretty commonplace these days, but stereo may
not be available on the system. We can check to see whether the visual we
got supports these capabilities by calling the
FXGLVisual#doubleBuffered?
and
FXGLVisual#stereo?
methods:
anotherVisual = FXGLVisual.new(theApp, VISUAL_DOUBLEBUFFER | VISUAL_STEREO) if anotherVisual.doubleBuffered? puts "It's double-buffered." else puts "It's single-buffered." end if anotherVisual.stereo? puts "It's stereo." else puts "It isn't stereo." end
Some FXGLVisual
object must be associated
with every FXGLCanvas
or
FXGLViewer
window, but you don't need to have a
separate FXGLVisual
object for each window. For
most applications, you can just construct a single
FXGLVisual
object that's shared among all the
OpenGL windows.
The FXGLCanvas
widget provides a very simple
OpenGL-capable window with minimal functionality. To construct an
FXGLCanvas
, call
FXGLCanvas.new
:
glCanvas = FXGLCanvas.new(parent, vis)
The first argument to FXGLCanvas.new
is the
parent (container) widget and the second argument is the
FXGLVisual
that should be used for this
window.
The FXGLViewer
widget provides a higher-level
OpenGL-capable window with a lot of built-in functionality. To construct
an FXGLViewer
, call
FXGLViewer.new
:
glViewer = FXGLViewer.new(parent, vis)
The first argument to FXGLViewer.new
is the
parent (container) widget and the second argument is the
FXGLVisual
that should be used for this
window.