• No se han encontrado resultados

Entrevista a la directora

Capítulo 4. Análisis de resultados

4.2 Entrevista a la directora

GAME_HEIGHT+(GAME_HEIGHT-clientRect.bottom),// Bottom TRUE); // Repaint

// the window

}

// Show the window

ShowWindow(hwnd, nCmdShow);

// Send a WM_PAINT message to the window procedure UpdateWindow(hwnd);

return true;

}

Listing 3.26. New winmain.cpp with support for fullscreen graphics added.

3.10 Debug vs. Retail DLLs

In order for this program to build successfully, we need to add d3dx9.lib to the project.

There is a retail version and a debug version of this library. Add the debug version as follows:

• Right click the project in the “Solution Explorer” window and select “Properties.”

• Set the configuration to “Debug.”

• Expand “Linker” in the left tab of the “Properties” page.

• Select “Input” in the left pane.

• Click “%(AdditionalDependencies)” in the right pane.

• Open the drop down menu and select “<Edit...>”.

• Enter “d3dx9d.lib.”

• Set the configuration to “Release” and repeat the above procedure, but this time enter “d3dx9.lib.” The debug version of the library has an extra “d” at the end of the name. The debug library provides more detailed messages and performs extra code validation.

The DirectX SDK has the option of installing debug or retail versions of the D3D9 runtime. If the debug runtime is installed, we can switch between retail and debug versions from the DirectX control panel. The DirectX control panel is under Start/All Programs/

Microsoft DirectX SDK (June 2010)/DirectX Utilities/DirectX Control Panel. The Direct3D tab is where we select the version of the runtime.

3.11 Determining Device Capabilities

As mentioned previously in this chapter, it is possible for DirectX functions to fail if we specify parameters that are incompatible with the system hardware. This is normally only a concern with fullscreen applications and in most cases windowed applications can skip

66 3. Introduction to DirectX

these steps. There are several DirectX functions we may use to get information about the hardware. The first step is to select the device. We will limit our coverage to display adapters, but the same techniques could be applied to any device type.

A display adapter is a physical device in the computer. It may be a peripheral card plugged into a system bus or integrated into the motherboard. A single graph-ics card may contain multiple adapters, as in the case of dual-headed displays. Deter-mining the number of display adapters installed in a system is done with the function IDirect3D9::GetAdapterCount();. If the game is not going to support multiple monitor displays, skip this step and pass D3DADAPTER_DEFAULT as the parameter to those DirectX functions that require the adapter number. GetAdapterCount() returns the number of display adapters as an unsigned integer.

Each adapter supports multiple display modes. The function IDirect3D9::Get AdapterModeCount returns the number of display modes available for the specified adapter:

UINT GetAdapterModeCount(

UINT Adapter, D3DFORMAT Format );

The parameters are:

Adapter. The number of the display adapter. Use D3DADAPTER_DEFAULT to spec-ify the primary adapter.

Format. The format of the surface type we want our game to use, as defined in D3DFORMAT.

And here are the format choices from D3DFORMAT, which are compatible with GetAdapter ModeCount and EnumAdapterModes:

D3DFMT_A1R5G5B5. A 16-bit pixel format with 5 bits for each color.

D3DFMT_R5G6B5. A 16-bit pixel format with 5 bits for red, 6 bits for green, and 5 bits for blue.

D3DFMT_A8R8G8B8. A 32-bit ARGB pixel format with 8 bits for alpha and 8 bits for each color.

D3DFMT_X8R8G8B8. A 32-bit RGB pixel format with 8 bits for each color.

D3DFMT_A2B10G10R10. A 32-bit pixel format using 10 bits for each color and 2 bits for alpha.

Once we have the number of display modes available for the desired format, we can use IDirect3D9::EnumAdapterModes to get details about each mode and determine if

67 3.11. Determining Device Capabilities

hardware acceleration is available:

HRESULT EnumAdapterModes(

UINT Adapter, D3DFORMAT Format, UINT Mode,

D3DDISPLAYMODE *pMode );

The parameters are:

Adapter. The number of the display adapter. Use D3DADAPTER_DEFAULT to spec-ify the primary adapter.

Format. The format of the surface we want our game to use from D3DFORMAT, as listed above.

Mode. Display mode number between 0 and the value returned by GetAdapter ModeCount – 1.

*pMode: Pointer to a D3DDISPLAYMODE structure that is filled in by the function with details about the mode.

The HRESULT return value contains the following:

• If the adapter supports the display mode, D3D_OK is returned.

• If the Adapter parameter exceeds the number of display adapters in the system, D3DERR_INVALIDCALL is returned.

• If either surface format is not supported or if hardware acceleration is not available for the specified formats, D3DERR_NOTAVAILABLE is returned.

The D3DDISPLAYMODE structure is defined as

typedef struct D3DDISPLAYMODE { UINT Width;

UINT Height;

UINT RefreshRate;

D3DFORMAT Format;

} D3DDISPLAYMODE, *LPD3DDISPLAYMODE;

The members are:

Width. Screen width in pixels.

Height. Screen height in pixels.

RefreshRate. Refresh rate in hertz (cycles per second). A value of 0 indicates the adapter default.

Format. Member of D3DFORMAT, as described above.

68 3. Introduction to DirectX

Let’s add a new function to graphics.cpp to check the compatibility of an adapter (see Listing 3.27).

//========================================================================

// Checks the adapter to see if it is compatible with the BackBuffer // height, width, and refresh rate specified in d3dpp. Fills in the pMode // structure with the format of the compatible mode, if found.

// Pre: d3dpp is initialized.

// Post: Returns true if compatible mode found and pMode structure is // filled.

// Returns false if no compatible mode found.

//========================================================================

bool Graphics::isAdapterCompatible()

{ UINT modes = direct3d->GetAdapterModeCount(D3DADAPTER_DEFAULT, d3dpp.BackBufferFormat);

for(int i=0; i<modes-1; i++) {

result = direct3d->EnumAdapterModes( D3DADAPTER_DEFAULT, d3dpp.BackBufferFormat, i, &pMode);

if( pMode.Height == d3dpp.BackBufferHeight &&

pMode.Width == d3dpp.BackBufferWidth &&

pMode.RefreshRate >= d3dpp.FullScreen_RefreshRateInHz) return true;

}

return false;

}

Listing 3.27. A function to check adapter compatibility.

We will call this function from our initialize function after the call to initD3Dpp(). If the game is set to run in fullscreen, we get the RefreshRate returned by isAdapterCompatible() and we set the d3dpp.FullScreen_RefreshRateInHz parameter with it. See Listing 3.28.

The last device capability we will test for is the ability to perform vertex processing in hardware. To determine if the device supports hardware vertex processing, we will use the IDirect3D9::GetDeviceCaps method:

HRESULT GetDeviceCaps(

UINT Adapter,

D3DDEVTYPE DeviceType, D3DCAPS9 *pCaps );

The parameters are:

Adapter. Number of the display adapter. Use D3DADAPTER_DEFAULT to specify the primary adapter.

DeviceType. Member of D3DDEVTYPE.

69 3.11. Determining Device Capabilities

*pCaps. Pointer to a D3DCAPS9 structure that is filled in by this function with the device capabilities.

We will add this function to our initialize function in graphics.cpp. If the device supports hardware vertex processing, we will use it. The new initialize function can be seen in Listing 3.28.

//========================================================================

// Initialize DirectX graphics // Throws GameError on error

//========================================================================

void Graphics::initialize(HWND hw, int w, int h, bool full) { hwnd = hw;

width = w;

height = h;

fullscreen = full;

// Initialize Direct3D

direct3d = Direct3DCreate9(D3D_SDK_VERSION);

if (direct3d == NULL)

throw(GameError(gameErrorNS::FATAL_ERROR, "Error initializing Direct3D")); // Determine if graphics card supports harware texturing and lighting // and vertex shaders result = direct3d->CreateDevice(

D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd,

behavior, &d3dpp,

70 3. Introduction to DirectX &device3d);

if (FAILED(result))

throw(GameError(gameErrorNS::FATAL_ERROR,

"Error creating Direct3D device"));

}

Listing 3.28. The new Graphics::initialize function.

Chapter Review

In this chapter, we introduced DirectX. We learned how to write a complete DirectX ap-plication that filled the window with a color. We created a Graphics class to hold all of our DirectX graphics code. We also learned how to determine the capabilities of a DirectX device. Here are the main points:

• The first step is using DirectX is to create a DirectX object using Direct3DCreate9.

• The second step is to create a device with the CreateDevice function.

• The Clear function can fill the window with a color.

• “Page flipping” is drawing to an offscreen buffer then making the offscreen buffer the visible buffer. The Present function does the page flipping.

• The Release method is used to free memory and resources reserved by DirectX functions.

• The Graphics class is our wrapper class for the DirectX graphics code.

• The Graphics::initialize function initializes DirectX graphics.

• The Graphics::showBackbuffer function does the page flip.

• We created and configured a DirectX project in Visual Studio.

• We learned how to create a fullscreen DirectX application.

• We wrote the Graphics::isAdapterCompatible function to see if the display adapter is compatible with our desired height, width, and refresh rate.

Review Questions

1. Which DirectX header file (.h) is required by the example code in this chapter?

2. Which DirectX library file (.lib) is required by the example code in this chapter?

3. Which DirectX function is used to initialize Direct3D?

71 Examples

4. What parameter value is assigned to the Adapter parameter of the CreateDevice function to use the primary display adapter?

5. What is rasterization?

6. What is a vertex?

7. What is the SUCCEEDED macro used for?

8. What parameter values would be used in D3DCOLOR_XRGB(?,?,?) to create the bright blue color?

9. Why do we use page flipping to display graphics?

10. What is a memory leak?

11. Each of our classes we create is contained in two files. Which file type contains the variables?

12. Which function in our Graphics class displays the back buffer?

Exercises

1. Modify this chapter’s “DirectX Window” example program so the window color is dark blue (RGB value (0, 0, 128)) and the window is a different size. (Not all win-dow sizes are valid. Try different size combinations until a working size is found.) 2. Modify this chapter’s “DirectX Fullscreen” example program. Change the program

to make it run in a window instead of in fullscreen mode so it will be easier to de-bug. Modify it so that pressing the space bar will exit the program.

3. Modify this chapter’s “DirectX Window” example program so a new random window color will be displayed each time the space bar is pressed. Hints: Add a backColor variable of type COLOR_ARGB to the Graphics class. Modify the showBackbuffer function in the Graphics class to use the backColor variable when clearing the screen. Add the following function to the graphics.h file:

// Set color used to clear screen

void setBackColor(COLOR_ARGB c) {backColor = c;}

Examples

All examples are available for download from www.programming2dgames.com. The fol-lowing is a list of what is available and what the examples show.

• DirectX Window. Creates a DirectX window application.

– Contains a Visual Studio project configured for DirectX.

– Demonstrates how to use the Graphics class to create a DirectX window.

72 3. Introduction to DirectX

• DirectX Fullscreen. Creates a fullscreen DirectX application.

– Demonstrates how to use the Graphics class to create a fullscreen DirectX application.

• DirectX Device Capabilities. Displays a dialog box if the graphics device does not support the specified resolution and/or format.

– Demonstrates how to use the Graphics::isAdapterCompatible function.