Making your game fullscreen is easy, but requires changing a few details of the program, as well as adding a couple lines of code.
In this lesson we will cover two things. First, we will go over how to globalize your screen resolution and why you would do this. Second, we'll cover the mechanics of making a window go into fullscreen mode.
Throughout your DirectX experience and in game programming you will come across many functions and structs that demand to know your screen size. This can become a hassle when you decide to change the resolution later, and especially when you decide to change it during run-time. For right now, we will cover a simple method to standardize your screen size across your program.
First, we must add two directives to the top of our program. These represent the screen width and the screen height.
// define the screen resolution
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
The next step is to go through your program to where you indicate the width and height of your window. Up to this point in the tutorial, you only have one, although we will come across another in a minute. Do this to the code (changes in bold):
hWnd = CreateWindowEx(NULL,
L"WindowClass",
L"Our Direct3D Program",
WS_OVERLAPPEDWINDOW,
300, 300,
SCREEN_WIDTH, SCREEN_HEIGHT, // set window to new resolution
NULL,
NULL,
hInstance,
NULL);
In a later lesson we will cover how to maintain screen size throughout your game after changing it during runtime.
There are specific resolutions that are available on most PCs, the most common of which can be seen in this table.
Some Common Screen Resolutions
Resolution | Pixels | Widescreen |
---|
800 x 600 | 480,000 | No |
1024 x 768 | 786,432 | No |
1152 x 864 | 995,328 | No |
1280 x 1024 | 1,310,720 | No |
1600 x 1200 | 1,920,000 | No |
1440 x 900 | 1,296,000 | Yes |
1680 x 1050 | 1,764,000 | Yes |
1920 x 1080 | 2,073,600 | Yes |
1920 x 1200 | 2,304,000 | Yes |
When changing to full screen you are doing several things. First, your are telling Windows not to apply any of the standard Windows borders to your window. Second, you are telling Windows to have your window overlap all other things on the screen, including the start menu. Third, you are telling DirectX to change the resolution of the monitor to your set preference. Finally, although less importantly, you are telling Windows to leave the window background color up to you.
The first two of these are handled by changing some CreateWindowEx() parameters. The changes we need to make are shown here.
hWnd = CreateWindowEx(NULL,
L"WindowClass",
L"Our Direct3D Program",
WS_EX_TOPMOST | WS_POPUP, // fullscreen values
0, 0, // the starting x and y positions should be 0
SCREEN_WIDTH, SCREEN_HEIGHT,
NULL,
NULL,
hInstance,
NULL);
Here we set the starting x and y positions to 0. We also changed the previous parameter to "WS_EX_TOPMOST | WS_POPUP". The WS_EX_TOPMOST is self-explanatory, and makes the window overlap everything else. The WS_POPUP is less self-explanatory, but what it does is tell Windows to remove all borders of any kind, including the rounded-edge top that you see in Windows XP.
There is also a member of the WINDOWCLASSEX struct that we need to take out. This leaves the background color untouched, which means it won't be visible as window for a second or two before the game starts (important to making your game look professional).
// wc.hbrBackground = (HBRUSH)COLOR_WINDOW;
Next, we have to tell DirectX about our new screen resolution. We do this by making a few changes to the d3dpp struct we built in the last lesson. Let's look at what they are before we see what they do.
D3DPRESENT_PARAMETERS d3dpp; // create a struct to hold various device information
ZeroMemory(&d3dpp, sizeof(d3dpp)); // clear out the struct for use
d3dpp.Windowed = FALSE; // program fullscreen, not windowed
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // discard old frames
d3dpp.hDeviceWindow = hWnd; // set the window to be used by Direct3D
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; // set the back buffer format to 32-bit
d3dpp.BackBufferWidth = SCREEN_WIDTH; // set the width of the buffer
d3dpp.BackBufferHeight = SCREEN_HEIGHT; // set the height of the buffer
Let's examine these new back buffer related variables.
This member is used to tell Direct3D what kind of pixels should be displayed. There are six types that can be used here, but two of them are older types (16-bit) and not generally used anymore. There are several 32-bit types that we can use. We'll use the D3DFMT_X8R8G8B8. See the table for a description along with some other values than can be used here (definitely not all of them).
A Couple Common Back Buffer Formats
Value | Description |
---|
D3DFMT_A8R8G8B8 | This is a 32-Bit pixel format, with 256 levels (8 bits) of red, green, blue and alpha (semi-transparency). |
D3DFMT_X8R8G8B8 | This is similar to A8R8G8B8, with the one difference being that it does not support alpha, even though there are 8 bits to represent this. |
These two members indicate the width and height of the back buffer. Painfully simple.
So, there isn't much to change. Let's take a look at the whole picture and see what is different and what is the same.
[
Main.cpp]
// include the basic windows header files and the Direct3D header file
#include <windows.h>
#include <windowsx.h>
#include <d3d9.h>
// define the screen resolution
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
// include the Direct3D Library file
#pragma comment (lib, "d3d9.lib")
// global declarations
LPDIRECT3D9 d3d; // the pointer to our Direct3D interface
LPDIRECT3DDEVICE9 d3ddev; // the pointer to the device class
// function prototypes
void initD3D(HWND hWnd); // sets up and initializes Direct3D
void render_frame(void); // renders a single frame
void cleanD3D(void); // closes Direct3D and releases memory
// the WindowProc function prototype
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
// the entry point for any Windows program
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
HWND hWnd;
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
// wc.hbrBackground = (HBRUSH)COLOR_WINDOW; // not needed any more
wc.lpszClassName = L"WindowClass";
RegisterClassEx(&wc);
hWnd = CreateWindowEx(NULL,
L"WindowClass",
L"Our Direct3D Program",
WS_EX_TOPMOST | WS_POPUP, // fullscreen values
0, 0, // the starting x and y positions should be 0
SCREEN_WIDTH, SCREEN_HEIGHT, // set the window to 640 x 480
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hWnd, nCmdShow);
// set up and initialize Direct3D
initD3D(hWnd);
// enter the main loop:
MSG msg;
while(TRUE)
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(msg.message == WM_QUIT)
break;
render_frame();
}
// clean up DirectX and COM
cleanD3D();
return msg.wParam;
}
// this is the main message handler for the program
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message)
{
case WM_DESTROY:
{
PostQuitMessage(0);
return 0;
} break;
}
return DefWindowProc (hWnd, message, wParam, lParam);
}
// this function initializes and prepares Direct3D for use
void initD3D(HWND hWnd)
{
d3d = Direct3DCreate9(D3D_SDK_VERSION); // create the Direct3D interface
D3DPRESENT_PARAMETERS d3dpp; // create a struct to hold various device information
ZeroMemory(&d3dpp, sizeof(d3dpp)); // clear out the struct for use
d3dpp.Windowed = FALSE; // program fullscreen, not windowed
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; // discard old frames
d3dpp.hDeviceWindow = hWnd; // set the window to be used by Direct3D
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; // set the back buffer format to 32-bit
d3dpp.BackBufferWidth = SCREEN_WIDTH; // set the width of the buffer
d3dpp.BackBufferHeight = SCREEN_HEIGHT; // set the height of the buffer
// create a device class using this information and the info from the d3dpp stuct
d3d->CreateDevice(D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING,
&d3dpp,
&d3ddev);
}
// this is the function used to render a single frame
void render_frame(void)
{
// clear the window to a deep blue
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 40, 100), 1.0f, 0);
d3ddev->BeginScene(); // begins the 3D scene
// do 3D rendering on the back buffer here
d3ddev->EndScene(); // ends the 3D scene
d3ddev->Present(NULL, NULL, NULL, NULL); // displays the created frame on the screen
}
// this is the function that cleans up Direct3D and COM
void cleanD3D(void)
{
d3ddev->Release(); // close and release the 3D device
d3d->Release(); // close and release Direct3D
}
There isn't really a point in me showing a screenshot of this program's result, because it would just be a blue rectangle. Your program should look like that: a blue rectangle with a mouse pointer in the middle.
Great! We now have a simple platform on which to build games.
Before you go on, I recommend doing the following exercise to gain familiarity with the code in this program:
Change the resolution of the program until you are familiar with the various resolutions selectable.
When you're ready to go on, let's hit the next lesson!
Next Lesson: An Overview of the Third Dimension
GO! GO! GO!
© 2006-2024 DirectXTutorial.com. All Rights Reserved.
Expand