monorepo/Learning/DX9/main.cpp
2023-10-13 10:09:01 +03:00

185 lines
4.0 KiB
C++

/*
Compile with
cl /nologo main.cpp /link user32.lib d3d9.lib
OR
Add these:
#pragma comment(lib,"user32.lib")
#pragma comment(lib, "d3d9.lib")
and compile with:
cl /nologo main.cpp
*/
#include <Windows.h>
#include <d3d9.h>
// Function prototypes
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
HRESULT InitializeDirectX(HWND hWnd);
void RenderFrame();
// DirectX variables
LPDIRECT3D9 pD3D = NULL;
LPDIRECT3DDEVICE9 pd3dDevice = NULL;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
// Create the window
const char className[] = "DirectX9BlankScreen";
const int width = 800;
const int height = 600;
WNDCLASS wc = {};
wc.lpfnWndProc = WindowProc;
wc.hInstance = hInstance;
wc.lpszClassName = className;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
RegisterClass(&wc);
HWND hWnd = CreateWindowEx(
0,
className,
"DirectX 9 Blank Screen",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
width, height,
NULL,
NULL,
hInstance,
NULL
);
if (!hWnd)
{
return -1;
}
// Initialize DirectX
if (FAILED(InitializeDirectX(hWnd)))
{
return -1;
}
// Show the window
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
// Main message loop
MSG msg = {};
while (msg.message != WM_QUIT)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
RenderFrame();
}
}
// Clean up DirectX resources
if (pd3dDevice)
{
pd3dDevice->Release();
pd3dDevice = NULL;
}
if (pD3D)
{
pD3D->Release();
pD3D = NULL;
}
return static_cast<int>(msg.wParam);
}
LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
HRESULT InitializeDirectX(HWND hWnd)
{
// Create the Direct3D9 object
pD3D = Direct3DCreate9(D3D_SDK_VERSION);
if (!pD3D)
{
return E_FAIL;
}
// Setup the presentation parameters
D3DPRESENT_PARAMETERS d3dpp = {};
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
// Create the Direct3D device
if (FAILED(pD3D->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_HARDWARE_VERTEXPROCESSING,
&d3dpp,
&pd3dDevice
)))
{
return E_FAIL;
}
return S_OK;
}
void RenderFrame()
{
// Clear the back buffer
pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
// Begin the scene
pd3dDevice->BeginScene();
// Set the vertex format
pd3dDevice->SetFVF(D3DFVF_XYZ);
// Define the vertices of the triangle
struct Vertex
{
float x, y, z;
};
Vertex vertices[] =
{
{ 0.0f, 1.0f, 0.0f }, // Top
{ -1.0f, -1.0f, 0.0f }, // Bottom-left
{ 1.0f, -1.0f, 0.0f } // Bottom-right
};
// Set the color to red
pd3dDevice->SetRenderState(D3DRS_LIGHTING, FALSE); // Disable lighting
pd3dDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); // Disable backface culling
pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); // Disable alpha blending
pd3dDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); // Solid fill mode
pd3dDevice->SetRenderState(D3DRS_SHADEMODE, D3DSHADE_GOURAUD); // Gouraud shading
// Draw the triangle
pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 1, vertices, sizeof(Vertex));
// End the scene
pd3dDevice->EndScene();
// Present the back buffer to the screen
pd3dDevice->Present(NULL, NULL, NULL, NULL);
}