Tải bản đầy đủ - 0 (trang)
Chapter 7. The AGL API for OpenGL Configuration

Chapter 7. The AGL API for OpenGL Configuration

Tải bản đầy đủ - 0trang

a porting strategy from windowing interfaces of other platforms such as GLX

or WGL is relatively simple.

To make the Cocoa versus AGL decision even more complex, the Carbon event

model, in the humble opinion of the authors, is more complicated than the event

model used by Cocoa.

One of the most redeeming aspects of AGL is its clear and apparent similarity

to CGL. It has the simplicity of CGL with the additional logic and entry points

required to build windowed applications.



Software Layering

The composited desktop of Mac OS X arguably provides the best user experience of any OS available. The underpinnings of such an amazing user experience are necessarily more complex than conventional windowing systems. This

complexity manifests itself to some extent in the software layering of AGL and

its related APIs (see Figure 7-1).

As we’ve said, AGL is built on top of CGL. Because of the compositing interaction of Quartz window server and drawables used as a destination for rendering in AGL applications, AGL also has dependencies on the Core Graphics API.

Add the obvious interaction with OpenGL, and you have all the pieces with

which AGL interacts.

The AGL API lives in either your particular SDK framework path or /System/

Library/Frameworks. As with other APIs, linking against AGL requires

specification of this framework path. Similarly, compiling using headers from

the AGL framework requires specification of the framework. Table 7-1 indicates

the relevant locations for building and linking with the AGL framework.

AGL is an interface for Carbon applications. It is incompatible with Cocoa applications. Because AGL is built on top of CGL, you may make CGL calls from

an AGL application so long as you respect the distinct data structures and types

for the two APIs.



NSGL



AGL

CGL

OpenGLCoreGraphics



Figure 7-1 AGL Software Dependencies



90



Chapter 7: The AGL API for OpenGL Configuration



Table 7-1 Locations of AGL Headers and Frameworks

Framework path

Build flag

Header



/System/Library/Frameworks/AGL.framework

-framework AGL

#include



With the fundamentals of AGL now described, and the locations in which to

fully explore the framework identified, let’s move directly into pixel format and

context configuration.



Pixel Format and Context

As we’ve discussed in earlier chapters of this book, the layer of “glue” between

your OpenGL code and the window system of your application performs two

key tasks: pixel format selection and OpenGL context creation. The name for

that layer, in this chapter at least, is AGL.

The pixel formats describe attributes, per pixel, of your OpenGL rendering

destination, and the context binds that pixel format to your window-system

drawable. To review, a drawable is an object such as a window, pixel buffer,

framebuffer object, or other graphics target used in OpenGL rendering. In

this chapter we’ll examine the APIs for basic pixel format selection and creation. We’ll explain all the enumerants used to specify the pixel format and

the functions necessary to configure them and create contexts using those pixel

formats.

The overview of how to use AGL to create the relevant glue code for rendering

should be familiar. In fact, this process, aside from the specifics of what function

calls to use, remains the same as that for CGL. Specifically, you perform four

simple steps:

1. Describe, create, and find a matching pixel format (AGLPixelFormat,

aglChoosePixelFormat).

2. Create an OpenGL context (AGLContext, aglCreateContext), using

the pixel format created in step 1.

3. Bind that context to a drawable (AGLDrawable, aglSetDrawable).

4. Initialize OpenGL, handle events, and render!

Here, we’ll look at the relevant application code to create and use a windowed AGL application and a full-screen AGL application as examples of

the creation and use of pixel formats and contexts. In the Cocoa chapter

(Chapter 8), we’ll spend time walking through how to configure and create an

XCode project for that set of examples. For now, however, we’ll leave it to you

to create an XCode project on your own to insert these samples—Carbon event



Pixel Format and Context



91



management and plumbing are well beyond our scope. But without further ado,

let’s begin the construction of our application.



Full-Screen Application

We will begin by creating a full-screen AGL application, so we must create

a new XCode project and configure it to depend on the key libraries necessary for OpenGL and AGL on the Mac—that is, the AGL.framework and

OpenGL.framework frameworks. Once it is configured, we can create a main

c program. You’ll next want to add code to include the OpenGL and AGL headers, as in Example 7-1.

Example 7-1 Headers for OpenGL and AGL

#include

#include



We’ll also configure a pair of standard methods we’ll use in a variety of examples to initialize our OpenGL state, once we’ve got a context, and to draw in our

main loop. With one minor exception, these methods look like other initialization and draw methods you’ve seen other places. Example 7-2 shows these two

routines, and their resultant bodies.

Example 7-2 AGL OpenGL Initialization and Draw Functions

void initGLstate()

{

glMatrixMode( GL_PROJECTION );

glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);

glClearColor( 0.0, 0.5, 0.8, 1.0 );

}

void draw(void)

{

glClear( GL_COLOR_BUFFER_BIT );

glMatrixMode( GL_MODELVIEW );

glLoadIdentity();

glRotatef( 5.0, 0.0, 0.0, 1.0 );

glColor4d( 0.0, 1.0, 0.0, 1.0 );

glRectd( 0.1, 0.1, 0.9, 0.9 );

aglSwapBuffers(context);

}



The difference between this code and code you’ve seen before, and will see

again later, is the method used to swap the implicitly double-buffered pixel

format we’re using. The call aglSwapBuffers() takes one argument, the

AGL context to be swapped, which for our purposes is declared in a globally

accessible variable outside this routine. We also have an externally declared



92



Chapter 7: The AGL API for OpenGL Configuration



pixel format that we use elsewhere, too. That’s all there is to our initialization

and draw methods; they’re pretty much boilerplate OpenGL.

Let’s now look at the entirety of our example application main method and see

how a pixel format is declared, described, and initialized.

Example 7-3 AGL Full-Screen Application main Method

int main(int argc, char **argv)

{

// create pixelformat

AGLPixelFormat pixelFormat;

GLint attribs[] =

{

AGL_DOUBLEBUFFER,

AGL_ACCELERATED,

AGL_NO_RECOVERY,

AGL_RGBA,

AGL_NONE

};

pixelFormat = aglChoosePixelFormat( NULL, 0, attribs );

// create context & bind to full-screen

context = aglCreateContext( pixelFormat, NULL );

aglDestroyPixelFormat( pixelFormat );

aglSetCurrentContext( context );

aglSetFullScreen( context, 0, 0, 0, 0 );

// main loop

initGLstate();

draw();

sleep( 3 );

// cleanup

aglSetCurrentContext( NULL );

aglDestroyContext( context );

return 0;

}



In Example 7-3, we build code in a few main sections. The first of these methods creates and fills out an AGLPixelFormat structure. In it, we specify the

desired attributes of our OpenGL render target—in this case, that we would like

an RGBA, double-buffered, hardware-accelerated drawable. Each pixel format

specification must end with the AGL NONE token or you’ll encounter unexpected

pixel format selections at best, and crashes at worst.

Next, we issue the command to actually find a pixel format matching our criteria using aglChoosePixelFormat. The last argument is our attribute list,

and the first two arguments are a handle to a list of graphics devices and the

number of devices, respectively. Specifying NULL as the list indicates that all

devices should be searched for matching visuals. In this example, that’s what

we’ll do, and see what we get back. The aglChoosePixelFormat call will



Pixel Format and Context



93



return an opaque handle that describes one or many pixel formats supported by

the devices-and-attribute combination in the call. If this were production code,

you’d want to ensure that the returned pixel format results were valid and, if

they were not, check for other pixel formats that would better meet your needs.

If a variety of pixel formats met the criteria you specified, you will want to call

aglNextPixelFormat to cycle through the pixel formats in the return value,

and then examine each of those options using aglDescribePixelFormat to

see which characteristics each has, and if any of them are particularly wellsuited to your needs.

One final note on pixel format specification and selection: A variety of AGL

functions can generate verbose errors (much like OpenGL does through its

glGetError mechanism). You should look at Apple’s reference documentation to see which calls can generate these errors and to learn when to query

them using aglGetError.

So what are all the tokens that you can specify in conjunction with aglChoose

PixelFormat? There are quite a few, and the Apple documentation describes

them reasonably well. We include our own descriptions of a useful selection

of these tokens in Table 7-2. Among the things that can be specified are stereo

or monoscopic rendering capabilities (also known as quad-buffering), stencil

planes, depth- and color-buffer sizes, floating-point pixels, anti-aliasing, and

even exact specification of the renderer and pixel format by ID. There’s quite

a lot of capability, and there are close analogs to any of the pixel format tokens

exposed in Cocoa as well. Read the table, experiment some, decide which best

fit your needs, and then customize your baseline code with your pixel format

requirements.

The second major component of the code in Example 7-3 creates and sets

the context for our rendering. We simply call aglCreateContext and clean

up our pixel format using aglDestroyPixelFormat, since our context is

bound to that pixel format. We then make the new context current by using

aglSetCurrentContext and bind our context to a full-screen drawable by

using aglSetFullScreen. As before, robust production code should check

for failure at any step in this process, and subsequently use aglGetError to

provide detailed error information for user feedback.

The final component of the code in Example 7-3 is a main loop, one in which

you’d handle events. For purposes of our example (that is, raw simplicity), our

event loop simply contains calls to initialize the OpenGL machine, draw our

scene, and display the results for a few seconds. Because this is a full-screen

application managed by Carbon, you’d need to create a Carbon event handler

to capture mouse and keyboard events. We’ll provide demo code on this book’s

website (www.macopenglbook.com) to show how this works and a preview in

the next section here showing a windowed visual selection and event-handling

loop.



94



Chapter 7: The AGL API for OpenGL Configuration



Table 7-2 Pixel Format Specifiers for Use with aglChoosePixelFormat

Token



Description



AGL ALL RENDERERS



Choose from all available renderers. This can

include non-OpenGL-compliant renderers.

Usually better to specify.

Type: Boolean

n/a

Default: n/a

Policy: n/a

Number of bits per color buffer. If AGL RGBA

is specified, this value is the sum of all

components. If a color index pixel format is

specified, the buffer size is the size of the

color indices.

Type: Unsigned integer

n/a

Default: n/a

Policy: Greater than or equal to value.

Level in plane stacking. Used to specify

overlay or underlay planes.

Type: Integer

n/a

Default: n/a

Policy: Exact.

Choose an RGBA format.

Type: Boolean

GL TRUE

Default: GL FALSE

Policy: If GL TRUE, search only RGBA pixel

formats; else search only color index pixel

formats.

Select double-buffered pixel formats.

Type: Boolean

GL TRUE

Default: GL FALSE

Policy: If GL TRUE, search only among

double-buffered pixel formats; else search

only single-buffered pixel formats.

Select stereo pixel formats.

Type: Boolean

GL TRUE

Default: GL FALSE

Policy: If GL TRUE, search only among stereo

pixel formats; else search only monoscopic

pixel formats.

(Continued)



AGL BUFFER SIZE



AGL LEVEL



AGL RGBA



AGL DOUBLEBUFFER



AGL STEREO



Pixel Format and Context



95



Table 7-2 Pixel Format Specifiers for Use with aglChoosePixelFormat

(Continued)

Token



Description



AGL AUX BUFFERS



Number of aux buffers.

Type: Unsigned integer

0 specifies no aux buffers.

Default: n/a

Policy: Greater than or equal to value.

Number of red component bits.

Type: Unsigned integer

0 if AGL RGBA is GL FALSE.

Default: n/a

Policy: Closest.

Number of green component bits.

Type: Unsigned integer

0 if AGL RGBA is GL FALSE.

Default: n/a

Policy: Closest.

Number of blue component bits.

Type: Unsigned integer

0 if AGL RGBA is GL FALSE.

Default: n/a

Policy: Closest.

Number of alpha component bits.

Type: Unsigned integer

0 if AGL RGBA is GL FALSE.

Default: n/a

Policy: Closest.

Number of depth bits.

Type: Unsigned integer

n/a

Default: n/a

Policy: Closest.

Number of stencil bits.

Type: Unsigned integer

n/a

Default: n/a

Policy: Greater than or equal to value.

Number of red accum bits.

Type: Unsigned integer

n/a

Default: n/a

Policy: Closest.



AGL RED SIZE



AGL GREEN SIZE



AGL BLUE SIZE



AGL ALPHA SIZE



AGL DEPTH SIZE



AGL STENCIL SIZE



AGL ACCUM RED SIZE



96



Chapter 7: The AGL API for OpenGL Configuration



Token



Description



AGL ACCUM GREEN SIZE



Number of green accum bits.

Type: Unsigned integer

n/a

Default: n/a

Policy: Closest.

Number of blue accum bits.

Type: Unsigned integer

n/a

Default: n/a

Policy: Closest.

Number of alpha accum bits.

Type: Unsigned integer

Value

Default: Default

Policy: AGL CLOSEST POLICY

Framebuffer bits per pixel, including unused

bits, ignoring alpha buffer bits.

Type: Unsigned integer

n/a

Default: n/a

Policy: n/a

Never choose smaller buffers than the type

and size requested.

Type: Boolean

n/a

Default: GL FALSE

Policy: n/a

Choose largest buffers of type and size

requested. Alters default policy for color,

depth, and accumulation buffers.

Type: Token

n/a

Default: n/a

Policy: n/a

Find the pixel format most closely matching

the specified size. Alters default policy and

size for color buffers.

Type: Unsigned integer

n/a

Default: n/a

Policy: Closest match.

(Continued)



AGL ACCUM BLUE SIZE



AGL ACCUM ALPHA SIZE



AGL PIXEL SIZE



AGL MINIMUM POLICY



AGL MAXIMUM POLICY



AGL CLOSEST POLICY



Pixel Format and Context



97



Table 7-2 Pixel Format Specifiers for Use with aglChoosePixelFormat

(Continued)

Token



Description



AGL OFFSCREEN



Choose an off-screen renderer.

Type: Token

n/a

Default: n/a

Policy: Closest match.

Choose a full-screen renderer.

Type: Token

n/a

Default: n/a

Policy: n/a

Number of multisample buffers.

Type: Unsigned integer

n/a

Default: n/a

Policy: n/a

Number of samples per multisample buffer.

Type: Unsigned integer

n/a

Default: n/a

Policy: n/a

Specify number of depth or stencil buffers

for the aux buffer.

Type: Unsigned integer

n/a

Default: n/a

Policy: n/a

Select pixel buffers with color buffers that

store floating-point pixels.

Type: n/a

n/a

Default: n/a

Policy: n/a

Select pixel formats with multisample

buffers.

Type: n/a

n/a

Default: n/a

Policy: Hint: prefer.

Select pixel formats with supersample

buffers.

Type: n/a

n/a

Default: n/a

Policy: Hint: prefer.



AGL FULLSCREEN



AGL SAMPLE BUFFERS ARB



AGL SAMPLES ARB



AGL AUX DEPTH STENCIL



AGL COLOR FLOAT



AGL MULTISAMPLE



AGL SUPERSAMPLE



98



Chapter 7: The AGL API for OpenGL Configuration



Token



Description



AGL SAMPLE ALPHA



Request alpha filtering

Type: n/a

n/a

Default: n/a

Policy: n/a

Choose renderer by a specific ID.

Type: Unsigned integer

One of AGL RENDERER * ID tokens

Default: n/a

Policy: Exact.

Choose a single renderer for all screens.

Type: Boolean

GL TRUE

Default: n/a

Policy: n/a

Disable all failure recovery systems. The

OpenGL driver layer will fall back to other

renderers if a drawable or surface cannot be

attached, typically due to insufficient

graphics memory resources. AGL would, in

this failure case, usually switch to another

renderer; however, specifying GL TRUE to

this option will prevent a failover to a

software renderer from occurring in this

instance.

Type: Boolean

GL TRUE: Disable failure modes.

GL FALSE: Fail to alternate renderers.

Default: n/a

Policy: Exact.

Choose a hardware-accelerated renderer.

Note that in a multiscreen system

configuration, it’s possible that you may not

get windows that span, because a spanning

window usually causes OpenGL to choose

the software renderer.

Type: Boolean

GL TRUE: Specify that only hardware

renderers are searched.

Default: GL FALSE

Policy: Exact.

(Continued)



AGL RENDERER ID



AGL SINGLE RENDERER



AGL NO RECOVERY



AGL ACCELERATED



Pixel Format and Context



99



Table 7-2 Pixel Format Specifiers for Use with aglChoosePixelFormat

(Continued)

Token



Description



AGL ROBUST



Choose a renderer that doesn’t have a

hardware failure mode due to lack of

graphics resources.

Type: Boolean

GL TRUE: Search renderers with no

hardware failure modes as described.

Default: GL FALSE

Policy: Exact.

Specify that only renderers with a back

buffer that accommodates the full size of the

drawable/surface object should be searched.

Ensure that the back buffer is copy-swapped

to the front buffer, meaning that the contents

are usable after a “swap buffers” command.

Type: Boolean

GL TRUE: Consider only renderers with this

capability.

Default: n/a

Policy: Exact.

Can be used to render to a window.

Type: n/a

n/a

Default: n/a

Policy: n/a

A single window can span multiple screens.

Type: n/a

n/a

Default: n/a

Policy: n/a

Specify a virtual screen number on which to

search for pixel formats.

Type: Integer

n/a

Default: n/a

Policy: Exact.

Choose a renderer that can be used to render

to a pbuffer.

Type: Boolean

GL TRUE: Choose a pbuffer pixel format.

Default: n/a

Policy: Exact.



AGL BACKING STORE



AGL WINDOW



AGL MULTISCREEN



AGL VIRTUAL SCREEN



AGL PBUFFER



100



Chapter 7: The AGL API for OpenGL Configuration



Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Chapter 7. The AGL API for OpenGL Configuration

Tải bản đầy đủ ngay(0 tr)

×