i
i
i
i
i
i
i
i
13.2. System Independence with the GLUT Libraries 333
// The following code illustrates the format of the loading code
// - an external JPEG image manipulation library written in
// C is used from our C++ application
extern "C" {
extern long ReadJPG(char
*
filename, short info_only);
long x_sizeJ, y_sizeJ; // used by Library code
unsigned char
*
lpImage=NULL;
};
static unsigned char
*
LoadJpeg(char
*
filename, int
*
x, int
*
y){
unsigned char
*
screen;
long xs,ys,imagesize;
if(ReadJPG(filename,1) == 0)return NULL;
// test image is OK - if not return no pixels
xs=x_sizeJ; ys=y_sizeJ;
// if OK get width and height
imagesize=xs
*
ys
*
3
*
sizeof(unsigned char);
// allocate space for image pixel array
if((screen=(unsigned char
*
)malloc(imagesize)) == NULL)return NULL;
x_sizeJ=xs; y_sizeJ=ys;
// We need an image with (0,0) at bottom left
// JPEG uses (0,0) at top left so must read in
// opposite order.
lpImage=(screen+(ys-1)
*
xs
*
3);
if(ReadJPG(filename,0) == 0){
free(screen);
return NULL;
}
// also return image width and height
*
x=xs;
*
y = ys;
return screen;
}
Listing 13.14. (continued).
projects in Chapter 18. We shall now turn to look briefly at how OpenGL
can be used in a system independent manner.
13.2 System Independence with the
GLUT Libraries
The OpenGL Utility Toolkit [3] is a useful library of functions that removes
completely the system dependent element from OpenGL application pro-
grams. It is available in binary form or as source code for UNIX, Win-
dows and Macintosh platforms. Using it, programs can be put together very
i
i
i
i
i
i
i
i
334 13. Programming 3D Graphics in Real Time
.. // standard headers
#include <GLUT/glut.h>
.. // other headers, program variables and function prototypes
// (all standard C data types! )
void Render() { // Called by GLUT render the 3D scene
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
.. // set up view transformations
glCallList(listID);
..
glFinish();
glutSwapBuffers(); // GLUT function
}
Listing 13.15. Using the GLUT makes an application program platform-independent.
The outline program in this listing shows a version of the mesh viewer developed in
Section 13.1 w hich uses the GLUT. It was developed for the Mac OS X using the
Xcode tools.
quickly. If you are writing a program and do not need to achieve a specific
look or feel or tie into some system-dependent functionality, the GLUT is the
obvious way to use OpenGL.
The GLUT has its own programming model which is not that dissimi-
lar from the Windows approach. It uses a window of some kind to display
the contents of the frame buffer. Initialization functions create this window
and pass to the GLUT library a number of application-specific callbacks
8
to
support mouse and keyboard input. The application programmer must sup-
ply the appropriate OpenGL drawing and other commands in these callback
functions. Listing 13.15 shows the key elements of a version of our mesh
model viewer using the GLUT and running under the M acintosh OS X op-
erating system. The application would be equally at home on Windows or an
SGI UNIX system. It is a good illustration of just how platform-independent
OpenGL can be.
The example given in this section only demonstrates a few key features
of the utility library. Menu commands, mouse clicks and multiple windows
can also be used. Unless one really must have some system-specific functions
in a 3D application, it is a good idea to use the GLUT or some other multi-
platform framework so as to maintain as much host flexibility as possible.
8
A callback is a function like a window message handler that is part of the program, but
it is not called explicitly by the program itself but by another program or system or even the
operating system. It is called indirectly, or put it another way, it is called back, hence the name.
i
i
i
i
i
i
i
i
13.3. Visualizing a Virtual World Using Direct3D 335
void Reshape(int w,int h){ // called by GLUT when window changes shape
glViewport(0, 0, w, h);
}
void Init(){ // initialize openGL - called after window is created
..
glClearColor(gbRed,gbGreen,gbBlue,1.0);
..
glEnable(GL_LIGHT0);
}
void KeyHandler(unsigned char key,int x,int y){ // called by GLUT
switch(key){
case ’l’: // user pressed the ’l’ key to
// load new mesh
LoadOFXmesh(GetFileName()); // or 3DS mesh
Make3dListS(); // make the openGL display list
break;
};
}
void TimerFunc(int value){ // called by GLUT
round_angle += 5.0; up_angle += 1.0; Render(); // change view and render
glutTimerFunc(20,TimerFunc,0); // run again in 20 ms
}
int main(int argc,char
**
argv){ // main program entry point
glutInit(&argc,argv);
glutInitWindowSize(640,480); // set up window (size given)
glutInitWindowPosition(100,100); // postion on screen
glutInitDisplayMode(GLUT_RGBA|GLUT_DOUBLE|GLUT_DEPTH);
glutCreateWindow("Mesh Viewer for Mac OS X");
glutDisplayFunc(Render); // Tell GLUT the function to use
// to render the scene
glutReshapeFunc(Reshape); // Tell GLUT the function to use
// for window size change
glutKeyboardFunc(Keyhandler); // Tell GLUT the function to handle
// keyboard keys
glutTimerFunc(100,TimerFunc,0); // Tell GLUT to run this function
// in 100ms time
Init(); // initialize our OpenGL requirements
glutMainLoop(); // Wait in a loop and obey commands
// till window closed
return 0;
}
Listing 13.15. (continued).
i
i
i
i
i
i
i
i
336 13. Programming 3D Graphics in Real Time
13.3 Visualizing a Virtual Wo rld
Using Direct3D
Direct3D sets out to achieve the same result as OpenGL, but it does not have
such a long history and it is evolving at a much faster rate. For this reason,
we will not use it as our main framework for developing the visualization
examples. We will use the other components of DirectX, i.e., DirectInput
and DirectS how for all other software/hardware interfacing because it works
well and there are v ery few alternatives for Windows applications.
13.3.1 A Bit of History
DirectX [4] first appeared under the guise of the Games SDK for Windows 95
in late 1995, and it has been refined and updated many times. At first, it only
gave the ability to draw directly to the display hardware, and for the graphics
programmer that was a breath of fresh air. This is the DirectDraw compo-
nent of DirectX. It offer ed drawing speeds as fast as could be obtained if one
accessed the display adapter without using operating system mediation, say
by using assembler code. Di rectDraw was designed with 2D computer games
in mind, so it had excellent support for blits, bit-block memory transfers, in-
cluding transparent and “key color blits. Many operations are performed
asynchronously with page flipping and color fills done in the display adapter’s
hardware.
All that the DirectDraw API provides is fast access to a drawing canvas,
the equivalent of the output frame buffer. To render virtual worlds or any-
thing else in 3D, one still has to render into the frame buffer, and this is
the function of Direct3D. The first few versions of Direct3D appeared in the
1990s. Back then, hardware support for 3D functions was still very limited
and so Direct3D had two modes of operation, called retained mode and im-
mediate mode. Retained mode [2] implemented most of the 3D functionality
in library code running in the hosts own processor, not on the GPU. Immedi-
ate mode was limited to a few simple functions and only managed to provide
some very basic lighting models, for example. Its functions matched the ca-
pabilities of the hardware rather than the desires of the application programs.
Now everything has changed. Retained mode has disappeared,
9
and imme-
diate mode has evolved to map onto the powerful features provided in hard-
9
Not quite, because it uses COM architecture and so is still in there, inside the Direct3D
system. It is just not documented.
i
i
i
i
i
i
i
i
13.3. Visualizing a Virtual World Using Direct3D 337
Figure 13.7. Two examples of shader development systems. On the left, a basic shader
development program is illustrated. It presents the C-like shader code that Microsoft
calls the High Level Shader Language; NVIDIAs similar version is Cg.Ontherightis
a screen from ATI’s RenderMonkey program, which can produce fabulously exciting
shader programs.
ware. Indeed, it has driven the implementation of many hardware features.
Theimmediatemodesshader model (as it is called) which allows all sorts of
interesting lighting and mapping effects is developing fast and will probably
continue to evolve and change extensively. It is now possible to write Shader
programs for Direct3D that give the impression of chrome, wood, marble etc.
For example, Figure 13.7 illustrates two programs that can be used to write
and test shader programs. Much more elaborate shader design tools are avail-
able. NVIDIAs Cg [5] is a C like language dedicated to GPU programming.
By using it or ATI’s RenderMonkey [1] fascinating surface textures, lighting
models and other effects can be formulated for use in real time.
13.3.2 The Architecture of Direct3D
Unsurprisingly, since it runs on the same hardware, Dir ect3D’s architecture
is not too dissimilar to that of OpenGL. Vertices still play a major part; the
only differences are that in Direct3D, the term fragment is replaced with pixel
and primitives are obtained from vertices by tessellation. Figure 13.8 shows
the Direct3D rendering pipeline. In this diagram, a programmable pipeline is
illustrated. The latest version of OpenGL also has a programmable pipeline;
this will be discussed in the next chapter.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.142.237.172