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.
[Table 2.1 - 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 |
|
[Close Table] |
[See Full Table] |
|
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).
[
Table 2.2 - Some 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. |
|
D3DFMT_A2R10G10B10 |
This is a 32-Bit pixel format, with only two bits of alpha, but 10 bits (1024 levels)
of each red, green and blue. |
|
D3DFMT_A16B16G16R16 |
64-BIT COLOR! If you have the capability to run 64-bit color, I'd recommend
playing around with this to see how it works.
This value has 16 bits for each component (65536 levels compared to the current
measly 256!) |
|
[Close Table] |
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.
[
Show Code]
// 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!
Liked the Lesson? Hated the lesson? Give your feedback.
© 2006-2010 DirectXTutorial.com. All Rights Reserved.