![]() |
![]() |
![]() |
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
![]() |
![]() |
To access the contents, click the chapter and section titles.
Cutting Edge Direct 3D Programming
The InitMainSurfaces() FunctionNow, lets look at the InitMainSurfaces() function. For review, the InitMainSurfaces() function is called by the OnCreate() function after InitDisplayMode() is called. The InitMainSurfaces() function creates the primary and back surfaces along with a Z-buffer surface, as shown in Listing 10.5. Listing 10.5 The InitMainSurfaces() function. BOOL RMWin::InitMainSurfaces() { if (primsurf) { primsurf->Release(); primsurf=0; } if (zbufsurf) { zbufsurf->Release(); zbufsurf=0; } DDSURFACEDESC desc; desc.dwSize = sizeof( desc ); desc.dwFlags = DDSD_BACKBUFFERCOUNT | DDSD_CAPS; desc.dwBackBufferCount = 1; desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; ddraw->CreateSurface( &desc, &primsurf, 0 ); DDSCAPS ddscaps; ddscaps.dwCaps = DDSCAPS_BACKBUFFER; primsurf->GetAttachedSurface( &ddscaps, &backsurf ); memset( &desc, 0, sizeof(desc) ); desc.dwSize = sizeof(DDSURFACEDESC); desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_ZBUFFERBITDEPTH; desc.dwWidth = modewidth; desc.dwHeight = modeheight; desc.dwZBufferBitDepth = 16 ; desc.ddsCaps.dwCaps= DDSCAPS_ZBUFFER | DDSCAPS_SYSTEMMEMORY; ddraw->CreateSurface( &desc, &zbufsurf, 0 ); backsurf->AddAttachedSurface( zbufsurf ); return TRUE; } First the InitMainSurfaces() function releases any existing primary surface and Z-buffer: if (primsurf) { primsurf->Release(); primsurf=0; } if (zbufsurf) { zbufsurf->Release(); zbufsurf=0; } The OnCreate() function (which calls the InitMainSurfaces() function) is called only oncewhen the programs window is createdso no primary surface or Z-buffer will be present. The InitMainSurfaces() function is, however, used by other functions to change the initial display mode. Existing primary surfaces and Z-buffers will be released before new ones are created. It is not necessary to release the back surface because it gets released along with the primary surface. Next, the primary surface is created: DDSURFACEDESC desc; desc.dwSize = sizeof( desc ); desc.dwFlags = DDSD_BACKBUFFERCOUNT | DDSD_CAPS; desc.dwBackBufferCount = 1; desc.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_3DDEVICE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; ddraw->CreateSurface( &desc, &primsurf, 0 ); The surface we are interested in creating must be described with a DDSURFACEDESC structure. The structures dwSize field must contain the size of the structure. The dwFlags field is used to store flags that indicate which structure fields we will be initializing. In this case, we will be using the dwBackBufferCount and ddsCaps fields, so the DDSD_BACKBUFFERCOUNT and DDSD_CAPS flags are used. The surface capability flags (DDSCAPS_PRIMARYSURFACE, DDSCAPS_ FLIP, and DDSCAPS_COMPLEX) indicate that we are creating a primary surface that is capable of page flipping. The DDSCAPS_3DDEVICE flag indicates to DirectDraw that we will be using the new surface to create a Direct3D device. The DirectDraw CreateSurface() function performs the actual surface creation. The DDSURFACEDESC structure that we prepared is used as the first argument. The address of a pointer to the DirectDrawSurface interface is used as the second argument. The pointer (primsurf) is an RMWin data member that we will use later to perform page flipping. Notice that the DDSURFACEDESC dwBackBufferCount field is assigned to one. This means that we have already informed DirectDraw that the primary surface has one back buffer. In fact, DirectDraw created the back buffer along with the primary surface. All we have to do now is retrieve a pointer to the back buffer: DDSCAPS ddscaps; ddscaps.dwCaps = DDSCAPS_BACKBUFFER; primsurf->GetAttachedSurface( &ddscaps, &backsurf ); Later, well use the backsurf pointer to store visual output before it is moved, or flipped, to the primary surface. Next, we create a Z-buffer and attach it to the backsurf surface: memset( &desc, 0, sizeof(desc) ); desc.dwSize = sizeof(DDSURFACEDESC); desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS | DDSD_ZBUFFERBITDEPTH; desc.dwWidth = modewidth; desc.dwHeight = modeheight; desc.dwZBufferBitDepth = 16 ; desc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | DDSCAPS_SYSTEMMEMORY; ddraw->CreateSurface( &desc, &zbufsurf, 0 ); backsurf->AddAttachedSurface( zbufsurf ); We need to describe the Z-buffer surface with an instance of the DDSURFACEDESC structure. Rather than declare another copy, we can use the desc instance that was used to create the primary surface. We reset the structure with a call to the memset() function, assigning zero to all of the structures fields. The dwSize and dwFlags fields are then assigned. The flags assigned to the dwFlags field indicate that we will be supplying the surfaces width, height, capabilities, and depth of the desired Z-buffer. The appropriate fields are then assigned. The Z-buffers dimensions must be equal to the dimensions of the primary and back buffers. Because the size of the primary and back buffers is always equal to the current display mode dimensions, we can use modewidth and modeheight to assign the dwWidth and dwHeight fields. We specify a 16-bit Z-buffer by assigning the dwZBufferBitDepth field. The depth of the Z-buffer determines the accuracy of the hidden surface removal code. An 8-bit Z-buffer would provide only 256 different Z, or distance values, and that is too conservative. A 16-bit Z-buffer offers 65,536 different values, so it will work for general purpose Z-buffering. Complex scenes may require 24- or 32-bit Z-buffers. The DDSCAPS_SYSTEMMEMORY constant is used to indicate that the Z-buffer memory should be allocated from system memory rather than from video card memory. With 3D graphics, video card memory is scarce (especially with 2 megabyte video cards). Storing the Z-buffer in system memory leaves more space in video card memory for visual surfaces such as sprites and backgrounds. Storing visual data in video card memory is preferable because accelerated video cards usually copy video memory faster than system memory.
|
![]() |
Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. |