#include <windows.h> //include windows header for some function like MessageBox, creating the window. #include "d3dx9.h" //include a directx header #include <stdio.h> //for the sprinf_s function used by DrawString #pragma comment(lib, "d3dx9.lib") //link the library #pragma comment(lib, "d3d9.lib") //link the library #define Emsg(msg){MessageBox(NULL,msg,"Error",MB_OK|MB_ICONEXCLAMATION);} //macro for error pop-up int WINDOW_WIDTH = 1024; //window width int WINDOW_HEIGHT = 768; //window height bool windowed = true; //window mode, change to false for full screen IDirect3D9 *pD3D; //global variable that will be used by a couple of our function IDirect3DDevice9 *pDevice; //a device that will be used for most of our function created inside *pD3D LPD3DXFONT pFont; //font variable to use with our create font function and to display text after int textx = 482; //text x coord int texty = 378; //text y coord LRESULT CALLBACK wndProc(HWND hWnd,UINT uMsg,WPARAM wParam,LPARAM lParam) //callback function for our GetMessage function on the while statement inside the main function { switch(uMsg) //switch the MSG variable passed { case WM_CLOSE: //case it's a Window Close MSG PostQuitMessage(0); //Apply a Quit Message break; } return DefWindowProc(hWnd,uMsg,wParam,lParam); //pass the variable } HRESULT initialize() //funciton where all the initialization stuff go { //change the parameter (LPCSTR)"Arial" to any other font name in your font folder to test other font if(FAILED(D3DXCreateFont(pDevice, 15, 0, FW_BOLD, 1, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, (LPCSTR)"Arial", &pFont))) //create a font in our Device with the pFont variable { Emsg("Failed to create the font"); //error pop-up for debug purpose return E_FAIL; //return it failed } } void DrawString(int x, int y, DWORD color, LPD3DXFONT g_pFont, const char *fmt) //function to draw text won't go in detail in this tutorial { RECT FontPos = { x, y, x + 120, y + 16 }; char buf[1024] = {'\0'}; va_list va_alist; va_start(va_alist, fmt); vsprintf_s(buf, fmt, va_alist); va_end(va_alist); g_pFont->DrawText(NULL, buf, -1, &FontPos, DT_NOCLIP, color); } HRESULT render() //function where all Drawing/Render stuff go { if(SUCCEEDED(pDevice->BeginScene())) //Call the BeginScene function with our Device and see if it succeeded, all drawing/render code go behind BeginScene and EndScene { //first parameter is the x coord of the text we use our global variable textx, second parameter is samething but with y, last parameter is the text to draw in this case Hello World DrawString(textx, texty, D3DCOLOR_ARGB(255, 0, 255, 0), pFont, "Hello World"); //if it did draw Hello world on buffer, D3DCOLOR_ARGB(255, 0, 255, 0) is the color the first parametter is the alpha (transparent),rest is Red Blue Green the total of red blue green must be 255 maximum pDevice->EndScene(); //Call the EndScene function with our Device return S_OK; //return it succeeded } return E_FAIL; //return it failed } void CleanUp() //function to delete/release things to prevent memory leak { if(pD3D) //check if pD3D ism't released pD3D->Release(); //release it if(pDevice) //check if pDevice ism't released pDevice->Release(); //release it if(pFont) //check if pFont ism't released pFont->Release(); //release it } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd) //our main function the first function called of the program { WNDCLASSEX wc; //window class won't go in detail not related to this tutorial really wc.cbSize = sizeof(WNDCLASSEX); wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wc.lpfnWndProc = (WNDPROC)wndProc; wc.cbWndExtra = 0; wc.cbClsExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = "D3DTEST"; //class name wc.hIconSm = LoadIcon(NULL, IDI_WINLOGO); RECT rect; //window rectangle rect.top = (long)0; rect.left = (long)0; rect.right = WINDOW_WIDTH; //use our global WINDOW_WIDTH variable rect.bottom = WINDOW_HEIGHT; //use our global WINDOW_HEIGHT variable if(!RegisterClassEx(&wc)) //register the window cs { Emsg("Could not register window class"); //error pop-up for debug purpose return 1; //return error } AdjustWindowRectEx(&rect,WS_OVERLAPPEDWINDOW,false,WS_EX_APPWINDOW | WS_EX_WINDOWEDGE); //set the window width and height with the rect above //the D3DTEST must match the class name of the window class and D3D TEST is the window name HWND hWindow = CreateWindowEx(NULL,"D3DTEST","D3D TEST",WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW,0,0,rect.right-rect.left,rect.bottom-rect.top,NULL,NULL,hInstance,NULL); //create the window if(!hWindow) //if the window failed to create { DestroyWindow(hWindow); //destroy the window UnregisterClass("D3DTEST",hInstance); //unregister our window class Emsg("Failed to create the window"); //error pop-up for debug purpose return 1; //return error } ShowWindow(hWindow,SW_SHOW); //show our window UpdateWindow(hWindow); //update our window SetForegroundWindow(hWindow); //set our window on top SetFocus(hWindow); //set the focus on our window D3DPRESENT_PARAMETERS d3dpp; //the presentation parameters that will be used when we will create the device ZeroMemory(&d3dpp,sizeof(d3dpp)); //to be sure d3dpp is empty d3dpp.Windowed = windowed; //use our global windowed variable to tell if the program is windowed or not d3dpp.hDeviceWindow = hWindow; //give the window handle of the window we created above d3dpp.BackBufferCount = 1; //set it to only use 1 backbuffer d3dpp.BackBufferWidth = WINDOW_WIDTH; //set the buffer to our window width d3dpp.BackBufferHeight = WINDOW_HEIGHT; //set the buffer to out window height d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; //the backbuffer format d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; //SwapEffect pD3D = Direct3DCreate9(D3D_SDK_VERSION); //Create the presentation parameters if(FAILED(pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWindow,D3DCREATE_SOFTWARE_VERTEXPROCESSING,&d3dpp,&pDevice))) //create the device and check if it failed { Emsg("Failed to create device"); //error pop-up for debug purpose CleanUp(); //call your CleanUp() function to prevent memory leak return 1; //exit the program return 1 error } if(FAILED(initialize())) //call the initialize function and check if it failed { Emsg("Failed to initialize"); //error pop-up for debug purpose CleanUp(); //call your CleanUp() function to prevent memory leak return 1; //exit the program return 1 error } MSG msg; //declare a MSG local variable for the GetMessage of the while loop while(GetMessage(&msg,NULL,0,0)) //GetMessage reffer to the wndProc() function { pDevice->Clear(0,0,D3DCLEAR_TARGET,D3DCOLOR_XRGB(0,0,0),1.0f,0.0f); //Clear the screen with black, basically since we only draw text here it's like your background change the D3DCOLOR_XRGB(0,0,0) to change the color the 3 number additioned must make 255 maximum if(FAILED(render())) //call the function render() and verify if it worked { Emsg("Render failed"); //error pop-up for debug purpose } pDevice->Present(NULL,NULL,NULL,NULL); //display your buffer on screen TranslateMessage(&msg); //translate the msg of the GetMessage of your while loop DispatchMessage(&msg); //dispath the msg of the GetMessage of your while loop } CleanUp(); //call your CleanUp() function to prevent memory leak return 0; //return 0 no problem }