Tải bản đầy đủ - 0trang
Appendix A. X11 APIs for OpenGL Configuration
• 256MB RAM
• 200MB of available hard disk space
• A built-in display or a display connected to an Apple-supplied video card
When the installation is complete, X11 is launched using the /Applications/
Utilities/X11.app application. In the Application menu, you’ll ﬁnd the familiar “xterm” application. Xterm will set up the X11 execution environment
for you and makes it easy to launch your X11 applications. If you need more
information on conﬁguring your X11 environment, see Apple’s comprehensive
guide on its website .
Like most X11 distributions, the X11 install comes with the Athena and Xt widget sets. If your application uses another widget set (most commercial applications do), you’ll have to do a bit more installation work to conﬁgure your Mac.
One of these widget sets, Motif, is quite popular in the commercial X software
world. Motif is a layer above raw X11 that provides a variety of higher-level,
object-oriented (though not C++) rendering widgets. Many large-scale applications use Motif in the Unix world, and a compatible version of Motif for Mac
OS X, called OpenMotif, can be downloaded from the OpenMotif website .
This version of OpenMotif requires a complete compile process, however, so
you may prefer to use a precompiled version. IST makes a variety of packaged versions of OpenMotif for many platforms, including an installer .dmg
for OS X. Despite this not being an ofﬁcial Open Group version of OpenMotif,
installing from the disk image is considerably easier than building Motif from
scratch. IST’s version of this packaged OpenMotif can be downloaded from the
company’s website .
Building X11 Applications on OS X
Once the software is installed, building your X11 applications on OS X is similar
to building them on any other Unix platform. By deﬁnition, this means that your
X11 application builds will look different from standard native OS X application
builds. Speciﬁcally, you will be linking against libraries in /usr/lib rather
than specifying frameworks.
Following is a sample makeﬁle from our x11 simple example for an
OpenMotif/OpenGL application on OS X (Tiger):
# Object files
CXXOBJS = main.o oglMotif.o
$(CXXOBJS): %.o: %.c++
Appendix A: X11 APIs for OpenGL Conﬁguration
g++ -g -Wall -I/usr/OpenMotif/include \
-I/usr/X11R6/include -c $< -o $@
g++ -g -o $@ $(CXXOBJS) -L/usr/X11R6/lib \
-L/usr/OpenMotif/lib -lGL -lGLw -lXm -lXt -lX11
rm -f *.o oglMotif
Note the -I and -L options of the compile and link lines, respectively. They refer
to the default installation directories for both X11 and OpenMotif. Also note the
lack of any -framework options. You cannot mix and match references to the
Mac OS X OpenGL libraries for an X11 application.
As far as the build process goes, X11 on OS X is quite straightforward. It probably will not require many changes for the Mac when bringing applications from
other platforms running Unix.
X11 Color Models
X11 shows its age (or seniority, if you prefer) with the prevalence of color index
rendering. Two X11 color models use color index (or color mapped) rendering:
PseudoColor and DirectColor. PseudoColor is the more common of these two
and represents each pixel in the framebuffer as an index into a single colormap.
DirectColor, by contrast, has a separate color map for red, green, and blue. As
you would expect, each pixel in the framebuffer contains an index for each of
the three color maps.
If you wish to run an application that uses the PseudoColor model, you can
launch X11 in 256-color mode. To do so, select the output tab from the X11.app
preferences pane, and select “256 colors” from the Colors drop-down menu. You
must restart X11.app for this change to take effect.
The TrueColor color model stores a maximum of four color component intensity
values in the framebuffer—one each for red, green, blue, and alpha. Modern
graphics applications typically use this color model.
By default, X11.app is conﬁgured to take the color setting from the display. The
display setting is typically millions for 24-bit color. This setting is appropriate
for TrueColor X11 applications.
X11 Color Models
This page intentionally left blank
API Acronym for application programming interface. An API is a set of functions, classes, and tokens used to deﬁne a particular set of software tools.
OpenGL is an API for graphics.
ARB See OpenGL Architecture Review Board.
Context sharing Reusing resources from one OpenGL context in another
Deferred validation The caching or postponement of data or state changes in
OpenGL until these changes are required at drawing time.
Direct memory access A hardware-to-hardware fetching of data. In the context of graphics, it usually entails the GPU fetching data from a region of
specially mapped or reserved host system memory.
Display capture To take over a particular display as part of a full-screen application.
Fragment A collection of all framebuffer state information for a single pixel.
A fragment may have some or all of color, alpha, depth, stencil, and other related data. The data associated with a fragment is deﬁned when the drawable
or surface for the framebuffer containing this fragment is constructed.
Framebuffer A destination buffer to which the results of OpenGL rendering
Frame rate quantization A description of the artifact observed when analyzing the performance of double-buffered OpenGL windows, where the frame
rate moves between discrete states deﬁned by integer divisors of the monitor refresh rate. For example, a 60Hz monitor refresh may cause a doublebuffered application to run at 60Hz, 30Hz, or 20Hz.
GLSL Acronym for OpenGL Shading Language.
GLX The OpenGL and X-Windows interface layer. The GLX speciﬁcation
describes how OpenGL contexts and drawables interact with X-Windows
widgets and windows.
Immediate mode rendering Rendering with objects passed from the host to
the GPU on a per-frame basis. Compared to retained mode rendering, immediate mode rendering implies more function-calling overhead in each rendering frame in addition to more bus bandwidth used with each frame.
OpenGL Architecture Review Board The standards body that deﬁnes which
features, functionality, and APIs appear in core OpenGL versions, extensions,
and associated speciﬁcations.
OpenGL Shading Language The high-level shading language employed by
Red Book The familiar name for the OpenGL programming guide.
Retained mode rendering Rendering with objects already cached on the
GPU. Typically glBind . . . Object calls invoke retained mode rendering.
Display lists are another form of this style of rendering.
Throughput The data transfer rate that an application achieves for a particular form of data over some data path. In graphics, throughput typically refers
to the rate at which data can be transferred from main memory to the graphics processor.
vbl-sync Vertical blanking synchronized is a conﬁguration option of graphics
applications that ties the redrawing of the framebuffer to the refresh rate of
the display device.
Virtualized desktop A single, continuous desktop that may span multiple,
potentially heterogeneous graphics devices. Dragging windows among the
displays attached to these graphics devices is seamless and continuous.
Appendix B: Glossary
The Cocoa API for
Mac OS X 10.5
Cocoa, also known as AppKit, is the Objective-C API for writing modern Mac
OS X applications. Cocoa provides a high-level, object-oriented set of classes
and interfaces for the OpenGL subsystem and for user–interface interaction.
Cocoa is the modern successor to the NextStep API from NeXT Computer; the
company’s initials explain the “NS” preﬁx on all of the class deﬁnitions and data
types. Cocoa provides a more object-oriented API than any other option on the
Mac, which is useful for building UIs, handling events, and functioning as an
interface to OpenGL.
We presume you’re reading this appendix with a fundamental understanding of
the Objective-C language and basic Cocoa, so we won’t spend any time reviewing core Cocoa concepts like the Objective-C language, views, actions, outlets,
Interface Builder, and so on. We also assume you’ve already read one of the
many good books on these key background elements of Cocoa. If not, we’ve got
a reference or two for you in Appendix D. In the following sections, we’ll explore two ways of creating a Cocoa-based application: one that relies heavily on
Interface Builder and one that requires more code but yields a bit more ﬂexibility and capability. We’ll also tackle some advanced OpenGL topics concerning
off-screen rendering, context sharing, and more.
This appendix is a repeat of the earlier chapter focused on Cocoa and OpenGL
but with a focus on Leopard. Though all the basic concepts from that chapter
still apply, Leopard does it a bit differently. Because of that, rather than trying
to integrate the two, we’ve broken them into two tracks. If you’re on Tiger or
earlier, read Chapter 8, but if you’re using Leopard, check out this appendix.
Figure C-1 AppKit API and Framework in Overall OpenGL Infrastructure on
The AppKit OpenGL API is part of the overall Apple OpenGL infrastructure.
It constitutes a layer above CGL but also has the ability to reach down into
both CGL and lower layers. Figure C-1 shows where the AppKit (also known as
Cocoa or NSGL) API and framework reside relative to other API layers.
The AppKit framework is typically found at /System/Library/Frameworks
but may also be in a path speciﬁc to your SDK installation. As with other
APIs, linking against AppKit requires speciﬁcation of this framework path
In this section, we will create an XCode project showing how to create a custom view to handle OpenGL rendering using a Cocoa UI element. This project
will be a foundation project that we will return to when we create other examples with increased functionality throughout this appendix. We’ll begin with the
overall project setup and creation—so launch XCode, and we’ll get started.
Create a new XCode project of type Cocoa Application. This action will create your project, set it to link properly against the Cocoa frameworks, and create
a sample main program from which we’ll begin. If you do not feel like walking
through the steps or would like to see the ﬁnished product ﬁrst, check out the
sample code from our website (www.macopenglbook.com).
Open the Resources folder, and double-click on the MainMenu.nib icon. This
will open the NIB ﬁle for this project in Interface Builder. Now switch to Interface Builder.
Table C-1 AppKit Cocoa Headers, Frameworks, and Overview
Appendix C: The Cocoa API for OpenGL Conﬁguration in Leopard
Figure C-2 Window and NIB Ready to be Edited in Leopard Interface Builder.
In the MainMenu.nib window, double-click on the Window icon, and you’ll
see the window that will be your application window open. Position and scale
it as you like, and you should end up with something like Figure C-2 when
Next bring up the Library and Inspector tools, both available in the Tools
menu. Navigate to the Inspector icon in the Library window and drag the
custom view out and into our window. Position and scale the view within the
window to suite your tastes. Finally, in the Inspector window, name your
class something sensible, like MyOpenGLView. Your results should look similar
to Figure C-3.
So what did we just do? We told Interface Builder that we wanted to create a
CustomView, arrange it in the window, and name it. We’re trying to get a custom
OpenGL view, speciﬁcally the NSOpenGLView class. It provides the integration
between OpenGL and Cocoa. By subclassing it, we become able to customize
many aspects of its behavior, including pixel format selection and context sharing. But we’re getting ahead of ourselves. First we’ve got to get MyOpenGLView
into a form where we can write some code.
We’ll now use Interface Builder to instantiate a default object when the NIB ﬁle
is loaded, bind it to our CustomView and create some sample code.
First, let’s create an instance of our class. Return to the Library window and
ﬁnd the blue cube icon. This stands for an arbitrary object to be instantiated on
Figure C-3 Selection, Layout, and Specialization of a CustomView in Interface
our behalf. Drag that out and into the MainMenu window. Select the blue cube,
and look in the Inspector window. Type in the Class entry the name of our
custom view, MyOpenGLView. This creates a custom object, of our custom view
type in the NIB, and will recreate that when the NIB gets instantiated at runtime.
You should see something like Figure C-4.
Now let’s create the actual headers and code. In Interface Builder go to the
File menu and choose Write Class Files. This will prompt you to create ﬁles for
both the header and the source for this view. Accept the defaults, placed within
your project directory. Finally, drag those ﬁles into your XCode project and
we’re set to start coding. The ﬁnal step in this setup operation is to change the
CustomView to derive from NSOpenGLView, the base Cocoa View class for rendering OpenGL content. To do so, open the code you’ve just generated within
XCode, and change the MyOpenGLView.h header so your project and code look
like Figure C-5.
We could have handled all of this setup, conﬁguration, and routing
programmatically—but this book isn’t about Cocoa plumbing, so we’ll stay
at this level for now. In a later section, we’ll explore Cocoa conﬁguration of a
Appendix C: The Cocoa API for OpenGL Conﬁguration in Leopard
Figure C-4 Create and Bind an Instance of our CustomView
Figure C-5 Custom View Derivation and Project Files in XCode 3.0
generic NSView, which allows us a bit more ﬂexibility. For now, switch back to
XCode and we’ll dig into the code.
In XCode, open the ﬁle MyOpenGLView.m. We’ll now begin adding methods to
handle key elements of the OpenGL render cycle. We start by adding a method
to select pixel formats. This code performs pixel format selection in three steps:
1. A structure is created containing a list of pixel format conﬁguration
2. That structure is passed to an NSOpenGLPixelFormat constructor to create
a new pixel format object.
3. That pixel format object is passed on to the base NSOpenGLView method for
ﬁnishing the initialization of this view.
Either add the code yourself to your project or grab it from the sample code
provided in Example C-1. Compile and run the code, and you should have a
Example C-1 Conﬁguration of an OpenGL View in initWithFrame
- (id) initWithFrame: (NSRect) frame
time = 0;
angle = 0;
GLuint attributes =
// choose among pixelformats capable of rendering to windows
// require hardware-accelerated pixelformat
// require double-buffered pixelformat
// require 24 bits for color-channels
// require an 8-bit alpha channel
// require a 24-bit depth buffer
// select a pixelformat which meets or exceeds these requirements
Appendix C: The Cocoa API for OpenGL Conﬁguration in Leopard