i
i
i
i
i
i
i
i
13.1. Visualizing a Virtual World Using OpenGL 313
BOOL bSetupScreenFormat(HDC hDC){
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
1, // version number
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER, // double buffered
PFD_TYPE_RGBA, // RGBA type
24, // 24-bit color depth
0, 0, 0, 0, 0, 0, // color bits ignored
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accum bits ignored
32, // 32-bit z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};
int pixelformat;
if ( (pixelformat = ChoosePixelFormat(hDC, &pfd)) == 0 ) {
return FALSE;
}
if (SetPixelFormat(hDC, pixelformat, &pfd) == FALSE) {
return FALSE;
}
return TRUE;
}
Listing 13.2. A pixel format tells OpenGL whether it is to render using double buffer-
ing, 24-bit color and many other attributes.
window. Listing 13.2 describes the key function to give the window certain
attributes, such as double buffering and stereoscopic display.
13.1.3 Designing the Software
There are a vast number of ways one could write our visualization program.
Design questions might include how the user navigates through the scene,
whether it is a windowed or full screen program etc. Our desire is to try to
keep the code as focused as possible on the 3D programming issues. There-
fore, we wont include a fancy toolbar or a large collection of user dialog
boxes—you can add these if desired. We will just give our program a simple
menu and a few hot keys for frequently used commands. Neither will we
i
i
i
i
i
i
i
i
314 13. Programming 3D Graphics in Real Time
present every aspect of the program here in print. All the programs are in-
cluded on the CD; you can explore that using the book as a guide. In the text,
we will stress the structure of the program and its most important features.
The options the program will offer its user are:
Render the object in windowed or full screen mode. You may remem-
ber that to render a full screen using O penGL, you first make a win-
dow that has the same dimensions as the desktop. A child window will
be used to receive the OpenGL-rendered output, and when it is cre-
ated, the decision can be made as to whether it will be full-screen or
windowed.
Change the color of the background. This is simply done by changing
the background color during initialization.
Slowly rotate the model. A Windows timer going off every 10 ms or so
will change the angular orientation of the model.
Allow the user to rotate the model in front of her by using the mouse.
If the mesh m akes use of image maps, display them. Try to use the
map in a manner close to the way it would appear when rendered by
the CAD or animation package which originated the m esh. (The fixed-
functionality pipeline limits the way an image may be repeated; mosaic
tiling is not normally available, for example.)
Offer the best possible rendering acceleration by using display lists and
where possible polygon stripping (described in Section 13.1.5).
In the following sections, we will look at the strategy used to implement
the application by concentrating on the most important statements in the
code.
13.1.4 Setting Up
A main window, with menu bar, is created in the standard manner; that is,
in the manner described in Listings D.2 and D.3. Global variables (see List-
ing 13.3) are declared and initialized. The application-defined structures for
the vertices, polygons and image maps which describe the mesh models (see
Section 5.1) are shown in Listing 13.4. Code for the functions that parse the
file for vertex, polygon and image m ap data and build lists of these key data
in global memory buffers will not be discussed further in the text, because
i
i
i
i
i
i
i
i
13.1. Visualizing a Virtual World Using OpenGL 315
VERTEX
*
MainVp=NULL; // Pointers to RAM buffers
FACE
*
MainFp=NULL; // for the 3D geometry description
MAP
*
MapsFp=NULL; // of the mesh models
long Nvert=0,Nface=0, // Numbers of vertices and polygons
NvertGlue=0,Nmap=0; // Number of maps and vwitices with
// mapping coordinates
int listID=0; // OpenGL display list
// User commands to change the appearance of the models and rendering
BOOL Mapped=FALSE,smooth_shading=TRUE,
ffastmapping=TRUE,accelerated=TRUE,LightBackground=FALSE;
// User interactively changes these to alter their viewpoint
GLfloat ObjScale=0.5,view_scale=1.0;
GLfloat up_angle=0.0,round_angle=0.0;
GLfloat xpos_offset=0.0,ypos_offset=0.0;
Listing 13.3. The applications most significant global variables for the mesh data and
viewpoint.
typedef GLfloat vector[3]; // application defined
typedef long point[3]; // datatypes for 3D vectors
typedef GLfloat normal[3]; // of different kind
typedef struct tagVERTEX { // the Vertex data structure
point p; // 3D location
GLfloat x,y; // mapping coordinates, where appropriate
} VERTEX;
typedef struct tagFACE { // the polygon data structure
long V[3],A[3],next; // attached to vertices, faces adjacent
// Next is used by the triangle stripping
// optimzation algorithm
unsigned char color[3],matcol[3], // surface attributes
texture,map,axis;
} FACE;
typedef struct tagMAP { // the image map data structure
vector n,p,x,y; // for maps that do no use mapping
// coordinates
char filename[128], // the filenames with the images for the
frefl[128],fbump[128];// 3 types of surface for each map
... // other minor elements
} MAP;
Listing 13.4. Data structures for the 3D entities to be rendered. The functions which
read the OpenFX and 3ds Max 3DS data files convert the information into arrays of
vertices, triangular polygons and image maps in this format.
i
i
i
i
i
i
i
i
316 13. Programming 3D Graphics in Real Time
it would take up too much space. If you examine the project on the CD,
you will see that the code can handle not only OpenFX mesh m odels but
also the commercial and commonly used 3DS mesh format. This brings up
the interesting point of how different applications handle 3D data and how
compatible they are with the OpenGL model.
The OpenFX and 3DS file formats are typical of m ost 3D computer
animation application programs: they use planar polygons, with three or four
case WM_TIMER: // handle timer messages
if(IsWindow(hWndDisplay)){ // if the Display window
// is visible
round_angle += 0.5; // increment rotation
// by 1/2 degree
if(round_angle > 180.0)round_angle -= 360;
InvalidateRect(hWndDisplay, NULL, FALSE); // update the display
}
break;
.....
case WM_COMMAND: // handle
if (wParam == ID_FILE_QUIT)PostQuitMessage(0);// tell application to exit
else if(wParam == ID_CONTROL_STARTDISPLAY){ // open the display window
if(hWndDisplay == NULL){
hWndDisplay=DisplayEntry(hInstance,hWnd); // create the OpenGL window
if(IsWindow(hWndDisplay))Make3dListS(); // Make the OpenGL
// display list.
}
else{
DisplayClose(hInstance,hWndDisplay); // close the display window
hWndDisplay=NULL;
}
}
else if (wParam == ID_LOAD_MODEL){ // load a mesh model
.. // Use a file open dialog to select the model filename
int type=WhatIsFileType(filename); // MFX or 3DS file type
LoadModel(filename,type); // read the mesh data into
if(IsWindow(hWndDisplay)){ // internal RAM structures
Make3dListS(); // make teh OpenGL
// display list.
InvalidateRect(hWndDisplay, NULL, TRUE); // update the display
}
}
... // other menu commands
break;
case ... // other windows messages
Listing 13.5. Message processing of commands from the main windows menu.
i
i
i
i
i
i
i
i
13.1. Visualizing a Virtual World Using OpenGL 317
vertices at most. Many 3D CAD software packages, however, use some form
of parametric surface description, NURBS or other type of surface patch.
OpenGL provides a few NURBS rendering functions, but these are part of the
auxiliary library and are u nlikely to be implemented in the GPU hardware,
so they tend to respond very slowly.
Even within applications which concentrate on simple triangular or quadri-
lateral polygons, there can be quite a bit of difference in their data structures.
OpenFX, for example, assigns attributes on a per-polygon basis, whereas 3DS
uses a materials approach, only assigning a material identifier to each poly-
gon, and thus whole objects or groups of polygons have the same attributes.
OpenGL assumes that vertices carry the attributes of color etc., and so in the
case of rendering polygons from an OpenFX mesh, many calls to the func-
tions that change the color state variable are required. Another difference
between OpenFX and 3DS concerns mapping. Fortunately, both packages
support mapping coordinates, and this is compatible with the way OpenGL
handles image mapping.
In the basic fixed-functionality pipeline of OpenGL, the lighting and
shading models are somewhat limited when compared to the near-photorealistic
rendering capability of packages such as 3ds Max, and some compromises
may have to be accepted.
Often, hardware acceleration poses some constraints on the way in which
the data is delivered to the hardware. With OpenGL, it is much more effi-
cient to render triangle strips than individual triangles. However, often tri-
angle meshes, especially those that arise by scanning physical models, are not
recorded in any sort of order, and so it can be well worth preprocessing or
reprocessing the mesh to try to build it up from as many triangle strips as
possible.
Most 3D modeling packages use a right-handed coordinate system in
which the z-axis is vertical. OpenGLs right-handed coordinate system has
its y-axis vertical, and the default direction of view is from (0, 0, 0) looking
along the z-direction. With any mesh model, we must be careful to remem-
ber this and accommodate the scales involved, too. In our 3D application
examples, we will always scale and change the data units so that the model
is centered at (0, 0, 0), the ver tex coordinates conform to OpenGLs axes and
the largest dimension falls in the range [1, +1].
The main window’s message-handling function pr ocesses a number mes-
sages. Listing 13.5 singles out the
WM TIMER message, which is used to incre-
ment the angular rotation of the model every few milliseconds and
WM COMMAND to handle commands from the user menu.
..................Content has been hidden....................

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