Render DirectX within a window (plus my introduction)
Hello everyone... I'm oyasuna.dev, but you may call me Oliver or Ollie if you would like to. I am 16, and currently the leader of the programming branch for an upcoming FPS game which is scheduled to be released in around 3 to 4 years. The name has not been set yet, but my signature will give updates to our progress.
Anyway to the point of this thread... I just wanted to release what I think is the most easy and efficient way to Render Direct3D within a windows application. This is made for fullscreen only, but if you have enough knowledge of C++ and Direct3D you should be able to whip something up. Basically I will be guiding anyone who needs help through the steps to initiate DirectX in a window application.
--------------------
If you have not already downloaded the latest version of DirectX SDK then do so. Learn how to include the files into your Microsoft Visual C++ project. Remember that the ability to include files under Tools->Options was deprecated in Microsoft Visual C++ 2008 and was taken out in 2010. In 2010 you will have to either include the header and library files in the project settings or use the User Property Sheet.
In this tutorial I will be using Direct3D 9, because Direct3D 9 was the last version to support XP. Although I have recently upgraded to Windows 7, I still love Direct3D 9, but time to time use some things from 10 and 11.
Now onto the tutorial!
--------------------
Since we are going to make this as simple as possible we will put everything into one cpp file. You may re-organize later.
Includes:
Globals:
We want these to be accessed from anywhere and have the same value
Prototypes:
The point of prototypes to define the function almost like a global so we don't have to create a function before another function that calls the first
WinMain:
WindowProc:
Initiate Direct3D:
Release Direct3D:
Render Direct3D:
Anyway to the point of this thread... I just wanted to release what I think is the most easy and efficient way to Render Direct3D within a windows application. This is made for fullscreen only, but if you have enough knowledge of C++ and Direct3D you should be able to whip something up. Basically I will be guiding anyone who needs help through the steps to initiate DirectX in a window application.
--------------------
If you have not already downloaded the latest version of DirectX SDK then do so. Learn how to include the files into your Microsoft Visual C++ project. Remember that the ability to include files under Tools->Options was deprecated in Microsoft Visual C++ 2008 and was taken out in 2010. In 2010 you will have to either include the header and library files in the project settings or use the User Property Sheet.
In this tutorial I will be using Direct3D 9, because Direct3D 9 was the last version to support XP. Although I have recently upgraded to Windows 7, I still love Direct3D 9, but time to time use some things from 10 and 11.
Now onto the tutorial!
--------------------
Since we are going to make this as simple as possible we will put everything into one cpp file. You may re-organize later.
Includes:
Code:
#include <windows.h> #include <d3d9.h> #include <d3dx9.h> #pragma comment (lib, "d3d9.lib") #pragma comment (lib, "d3dx9.lib")
We want these to be accessed from anywhere and have the same value
Code:
HWND g_hWnd = NULL; //Window Handle LPDIRECT3D9 g_pD3D = NULL; LPDIRECT3DDEVICE9 g_pDevice = NULL; //D3D Device int xRes = GetSystemMetrics(SM_CXSCREEN); //Screen Resolution Width int yRes = GetSystemMetrics(SM_CYSCREEN); //Screen Resolution Height
The point of prototypes to define the function almost like a global so we don't have to create a function before another function that calls the first
Code:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow); LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); void init(void); void shutDown(void); void render(void);
Code:
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX winClass; //Window Class Name
MSG uMsg; //Message Handler
memset(&uMsg, 0, sizeof(uMsg));
winClass.lpszClassName = TEXT("MY_WINDOWS_CLASS");
winClass.cbSize = sizeof(WNDCLASSEX);
winClass.style = CS_HREDRAW | CS_VREDRAW;
winClass.lpfnWndProc = WindowProc;
winClass.hInstance = hInstance;
winClass.hIcon = NULL;
winClass.hIconSm = NULL;
winClass.hCursor = LoadCursor(NULL, IDC_ARROW);
winClass.hbrBackground = NULL;
winClass.lpszMenuName = NULL;
winClass.cbClsExtra = 0;
winClass.cbWndExtra = 0;
if(RegisterClassEx(&winClass) == 0)
{
return E_FAIL;
}
g_hWnd = CreateWindowEx(NULL, TEXT("MY_WINDOWS_CLASS"), TEXT("Direct3D (DX9) - Full Screen"), WS_POPUP | WS_SYSMENU | WS_VISIBLE, 0, 0, xRes, yRes, NULL, NULL, hInstance, NULL);
if(g_hWnd == NULL)
{
return E_FAIL;
}
ShowWindow(g_hWnd, nCmdShow);
UpdateWindow(g_hWnd);
init();
while(uMsg.message != WM_QUIT)
{
if(PeekMessage(&uMsg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&uMsg);
DispatchMessage(&uMsg);
}
else
{
render();
}
}
shutDown();
UnregisterClass(TEXT("MY_WINDOWS_CLASS"), winClass.hInstance);
return uMsg.wParam;
}
Code:
LRESULT CALLBACK WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_KEYDOWN:
{
switch(wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
break;
case VK_F1:
//Show info
break;
}
}
break;
case WM_CLOSE:
{
PostQuitMessage(0);
}
break;
case WM_DESTROY:
{
PostQuitMessage(0);
}
break;
default:
{
return DefWindowProc(hWnd, msg, wParam, lParam);
}
break;
}
return 0;
}
Code:
void init(void)
{
g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
if(g_pD3D == NULL)
{
return;
}
int nMode = 0;
D3DDISPLAYMODE d3ddm;
bool bDesiredAdapterModeFound = false;
int nMaxAdapterModes = g_pD3D->GetAdapterModeCount(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8);
for(nMode = 0; nMode < nMaxAdapterModes; ++nMode)
{
if(FAILED(g_pD3D->EnumAdapterModes(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, nMode, &d3ddm)))
{
return;
}
//Does this adapter mode support a mode of xRes x yRes?
if(d3ddm.Width != xRes || d3ddm.Height != yRes)
{
continue;
}
//Does this adapter mode support a 32-bit RGB pixel format?
if(d3ddm.Format != D3DFMT_X8R8G8B8)
{
continue;
}
//Does this adapter mode support a refresh rate of 85 MHz? - Change this to your maximum refresh rate
if(d3ddm.RefreshRate != 85)
{
continue;
}
//We found a match!
bDesiredAdapterModeFound = true;
break;
}
if(bDesiredAdapterModeFound == false)
{
return;
}
//Can we get a 32-bit back buffer?
if(FAILED(g_pD3D->CheckDeviceType(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, FALSE)))
{
return;
}
//Can we get a z-buffer that's at least 16 bits?
if(FAILED(g_pD3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, D3DFMT_X8R8G8B8, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, D3DFMT_D16)))
{
return;
}
D3DCAPS9 d3dCaps;
if(FAILED(g_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, &d3dCaps)))
{
return;
}
DWORD flags = 0;
if(d3dCaps.VertexProcessingCaps != 0)
{
flags = D3DCREATE_HARDWARE_VERTEXPROCESSING;
} else {
flags = D3DCREATE_SOFTWARE_VERTEXPROCESSING;
}
D3DPRESENT_PARAMETERS d3dpp;
memset(&d3dpp, 0, sizeof(d3dpp));
d3dpp.Windowed = false;
d3dpp.EnableAutoDepthStencil = true;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferWidth = xRes;
d3dpp.BackBufferHeight = yRes;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
if(FAILED(g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd, flags, &d3dpp, &g_pDevice)))
{
return;
}
}
Code:
void shutDown(void)
{
if(g_pDevice != NULL)
{
g_pDevice->Release();
}
if(g_pD3D != NULL)
{
g_pD3D->Release();
}
}
Code:
void render(void)
{
g_pDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
g_pDevice->BeginScene();
//PUT ALL OF YOUR CRAP HERE!
g_pDevice->EndScene();
g_pDevice->Present(NULL, NULL, NULL, NULL);
}

