Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <windows.h>
- #include <d3d9.h>
- #include <d3dx9tex.h>
- #include <dxerr.h>
- // define global constants once here, not every frame
- const DWORD D3DFVF_TLVERTEX = D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1;
- // define you types once here, not every frame
- struct TLVERTEX
- {
- float x, y, z, rhw;
- D3DCOLOR color;
- float u;
- float v;
- };
- HWND hWnd = 0;
- LPDIRECT3D9 direct3D = NULL;
- LPDIRECT3DDEVICE9 direct3DDevice = NULL;
- // You dont need to create your VB every frame (resource creation is very slow)
- // Instead do it once on app initialization.
- // Never make uninitialized variables.
- // Assign to null and change it later
- IDirect3DTexture9* texture = 0;
- IDirect3DVertexBuffer9* vertexBuffer = 0;
- // Make global variable instead using "magic strings" or "magic nunbers"
- const wchar_t* pathToMyPicture = L"DirectX.png";
- void Initialize(HINSTANCE hInstance);
- IDirect3DVertexBuffer9* CreateVertexBuffer (const D3DCOLOR& vertexColour, const RECT& rDest);
- IDirect3DTexture9 *LoadTexture(const wchar_t *fileName);
- void Run();
- void Render();
- void Cleanup();
- LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
- // Here you put things that will
- // be done only once in the beginning of your application
- void Initialize(HINSTANCE hInstance)
- {
- // -------- Here you creating the window-------------------------
- // TODO: move this code to separate function and call this function here
- // Added primitive error checking
- WNDCLASSEX wc = {sizeof(WNDCLASSEX), CS_VREDRAW|CS_HREDRAW|CS_OWNDC,
- WndProc, 0, 0, hInstance, NULL, NULL, (HBRUSH)(COLOR_WINDOW+1),
- NULL, L"DX9_TUTORIAL1_CLASS", NULL};
- if(!RegisterClassEx(&wc))
- {
- MessageBox(0, L"RegisterClassEx failed", L"Error!", MB_OK);
- }
- hWnd = CreateWindow(L"DX9_TUTORIAL1_CLASS",
- L"DirectX 9 Bare Bones Tutorial 1",
- WS_OVERLAPPEDWINDOW, 100, 100, 800, 600,
- NULL, NULL, hInstance, NULL);
- if(!hWnd)
- {
- MessageBox(0, L"RegisterClassEx failed", L"Error!", MB_OK);
- }
- ShowWindow(hWnd, SW_SHOW);
- UpdateWindow(hWnd);
- // ----------Here you creating D3D9 core interfaces --------------------
- // TODO: move this code to separate function and call this function here
- // Added primitive error checking
- direct3D = Direct3DCreate9(D3D_SDK_VERSION);
- if (!direct3D)
- {
- MessageBox(0, L"Direct3DCreate9 failed", L"Error!", MB_OK);
- }
- D3DPRESENT_PARAMETERS PresentParams;
- memset(&PresentParams, 0, sizeof(D3DPRESENT_PARAMETERS));
- PresentParams.Windowed = true;
- PresentParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
- direct3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
- D3DCREATE_SOFTWARE_VERTEXPROCESSING, &PresentParams, &direct3DDevice);
- if (!direct3DDevice)
- {
- MessageBox(0, L"CreateDevice failed", L"Error!", MB_OK);
- }
- direct3DDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
- direct3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
- direct3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
- direct3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
- direct3DDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE);
- // ------------- Here you creating your resources -------------------
- // Resources are: models, textures, shaders, etc.
- // Resource creation is very slow
- // and you dont need to re-create them every frame.
- // Instead, do it once here, on initialization.
- // TODO: move this code to separate function and call this function here
- D3DCOLOR vertexColor = D3DCOLOR_ARGB(255, 255, 255, 255);
- // No need to use dynamic allocation and pointer here
- // You can pass rect to CreateVertexBuffer function by const reference
- RECT rect = {0};
- rect.left = 10;
- rect.top = 10;
- rect.bottom = 60;
- rect.right = 60;
- vertexBuffer = CreateVertexBuffer(vertexColor, rect);
- // Your creation functions can return null if failed
- // (check their code),
- // so you must check this exceptional situation.
- // Best way is to throw exception, a
- // simple way is just create MessageBox
- if (!vertexBuffer)
- {
- MessageBox(0, L"CreateVertexBuffer failed", L"Error!", MB_OK);
- }
- // Make global variable instead using "magic strings" or "magic nunbers"
- texture = LoadTexture(pathToMyPicture);
- if (!vertexBuffer)
- {
- MessageBox(0, L"LoadTexture failed", L"Error!", MB_OK);
- }
- }
- // Here you creating your vertex buffer
- IDirect3DVertexBuffer9* CreateVertexBuffer (const D3DCOLOR& vertexColour, const RECT& rDest)
- {
- IDirect3DVertexBuffer9* vertexBuffer = 0;
- // Set vertex shader.
- direct3DDevice->SetVertexShader(NULL);
- direct3DDevice->SetFVF(D3DFVF_TLVERTEX);
- // Create vertex buffer.
- direct3DDevice->CreateVertexBuffer(sizeof(TLVERTEX) * 4, NULL,
- D3DFVF_TLVERTEX, D3DPOOL_MANAGED, &vertexBuffer, NULL);
- direct3DDevice->SetStreamSource(0, vertexBuffer, 0, sizeof(TLVERTEX));
- TLVERTEX* vertices;
- //Lock the vertex buffer
- vertexBuffer->Lock(0, 0, (void**)&vertices, NULL);
- vertices[0].color = vertexColour;
- vertices[0].x = (float) rDest.left - 0.5f;
- vertices[0].y = (float) rDest.top - 0.5f;
- vertices[0].z = 0.0f;
- vertices[0].rhw = 1.0f;
- vertices[0].u = 0.0f;
- vertices[0].v = 0.0f;
- vertices[1].color = vertexColour;
- vertices[1].x = (float) rDest.right - 0.5f;
- vertices[1].y = (float) rDest.top - 0.5f;
- vertices[1].z = 0.0f;
- vertices[1].rhw = 1.0f;
- vertices[1].u = 1.0f;
- vertices[1].v = 0.0f;
- vertices[2].color = vertexColour;
- vertices[2].x = (float) rDest.right - 0.5f;
- vertices[2].y = (float) rDest.bottom - 0.5f;
- vertices[2].z = 0.0f;
- vertices[2].rhw = 1.0f;
- vertices[2].u = 1.0f;
- vertices[2].v = 1.0f;
- vertices[3].color = vertexColour;
- vertices[3].x = (float) rDest.left - 0.5f;
- vertices[3].y = (float) rDest.bottom - 0.5f;
- vertices[3].z = 0.0f;
- vertices[3].rhw = 1.0f;
- vertices[3].u = 0.0f;
- vertices[3].v = 1.0f;
- //Unlock the vertex buffer
- vertexBuffer->Unlock();
- return vertexBuffer;
- }
- // Pass values as const if you not planning to change it in a function
- // (usually, you will want pass most input values as const)
- IDirect3DTexture9 *LoadTexture(const wchar_t *fileName)
- {
- // Never make uninitialized variables.
- // Assign to null and change it later
- IDirect3DTexture9 *d3dTexture = 0;
- D3DCOLOR colorkey = 0; //0xFFFF00FF;
- // More advancer error checking but still not perfect
- HRESULT hr = S_OK;
- // More simple variant
- //if (FAILED(D3DXCreateTextureFromFile(direct3DDevice, fileName, &d3dTexture)))
- if(FAILED(hr = D3DXCreateTextureFromFileEx (direct3DDevice, fileName, 0, 0, 0, 0,
- D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_DEFAULT, colorkey, 0, 0, &d3dTexture)))
- {
- std::wstring errorString = DXGetErrorString(hr); // Here you get error string
- std::wstring errorDesc = DXGetErrorDescription(hr); // Here you get error description
- std::wstring messageString(L"D3DXCreateTextureFromFileEx failed:\n");
- messageString += errorString;
- messageString += L"\n";
- messageString += errorDesc;
- MessageBox(0, messageString.c_str(), L"Error!", MB_OK);
- // No need to return null here, because if function failed,
- // your texture is already null (we assigned it to null)
- DebugBreak();
- }
- return d3dTexture;
- }
- // Main loop (!)
- // Heart of your papplication
- // Never use WM_PAINT to trigger directx frames
- void Run()
- {
- MSG msg = {0};
- // Until WM_QUIT message
- while(msg.message != WM_QUIT)
- {
- // If there are windows messages
- if(PeekMessage( &msg, 0, 0, 0, PM_REMOVE ))
- {
- // Process them
- TranslateMessage( &msg );
- DispatchMessage( &msg );
- }
- // If there are no messages
- else
- {
- // Render one frame
- Render();
- }
- }
- }
- // Here you put things that
- // you will do every frame
- void Render()
- {
- RECT* rect = new RECT;
- rect->left = 10;
- rect->top = 10;
- rect->bottom = 60;
- rect->right = 60;
- direct3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0),
- 1.0f, 0);
- direct3DDevice->BeginScene();
- direct3DDevice->SetTexture (0, texture);
- direct3DDevice->DrawPrimitive (D3DPT_TRIANGLEFAN, 0, 2);
- direct3DDevice->EndScene();
- direct3DDevice->Present(NULL, NULL, NULL, NULL);
- }
- // Here you put things that will
- // be done only once in the beginning of your application
- void Cleanup()
- {
- // You forget to clean up VB and texture resource
- // It was memory leak
- // Also, check if pointer is not null before dereference it
- // to prevent errors
- if (vertexBuffer)
- {
- vertexBuffer->Release();
- }
- if (texture)
- {
- texture->Release();
- }
- if (direct3DDevice)
- {
- direct3DDevice->Release();
- }
- if (direct3D)
- {
- direct3D->Release();
- }
- }
- int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShow)
- {
- // Isn't it much cleaner here? =)
- Initialize(hInstance);
- Run();
- Cleanup();
- return 0;
- }
- LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- switch (msg)
- {
- case WM_DESTROY:
- {
- PostQuitMessage(0);
- break;
- }
- default:
- {
- break;
- }
- break;
- }
- return (DefWindowProc(hWnd, msg, wParam, lParam));
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement