Reputation: 1017
I am attempting to learn DirectX, and am feeling quite overwhelmed. Can anyone tell me why this is not working? The image does not display to the screen. The window is just all black. I was trying to follow along a tutorial for this, and this is the code they had.
#include <windows.h>
#include <d3d9.h>
#include <d3dx9tex.h>
LPDIRECT3D9 direct3D = NULL;
LPDIRECT3DDEVICE9 direct3DDevice = NULL;
IDirect3DTexture9* texture;
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
IDirect3DTexture9 *LoadTexture(wchar_t *fileName);
void BlitD3D (IDirect3DTexture9 *texture, RECT *rDest,
D3DCOLOR vertexColour, float rotate);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShow)
{
MSG msg;
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};
RegisterClassEx(&wc);
HWND hMainWnd = CreateWindow(L"DX9_TUTORIAL1_CLASS",
L"DirectX 9 Bare Bones Tutorial 1",
WS_OVERLAPPEDWINDOW, 100, 100, 300, 300,
NULL, NULL, hInstance, NULL);
direct3D = Direct3DCreate9(D3D_SDK_VERSION);
D3DPRESENT_PARAMETERS PresentParams;
memset(&PresentParams, 0, sizeof(D3DPRESENT_PARAMETERS));
PresentParams.Windowed = true;
PresentParams.SwapEffect = D3DSWAPEFFECT_DISCARD;
direct3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hMainWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING, &PresentParams, &direct3DDevice);
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);
texture = LoadTexture(L"Ash.png");
ShowWindow(hMainWnd, nShow);
UpdateWindow(hMainWnd);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
direct3DDevice->Release();
direct3D->Release();
return 0;
}
LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg)
{
case WM_DESTROY:
PostQuitMessage(0);
return 0;
case WM_PAINT:
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();
BlitD3D(texture, rect, D3DCOLOR_ARGB(1, 1, 1,1), 0);
direct3DDevice->EndScene();
direct3DDevice->Present(NULL, NULL, NULL, NULL);
ValidateRect(hWnd, NULL);
return 0;
}
return (DefWindowProc(hWnd, msg, wParam, lParam));
}
//Load texture from file with D3DX
//Supported formats: BMP, PPM, DDS, JPG, PNG, TGA, DIB
IDirect3DTexture9 *LoadTexture(wchar_t *fileName)
{
IDirect3DTexture9 *d3dTexture;
//Use a magenta colourkey
D3DCOLOR colorkey = 0xFFFF00FF;
// Load image from file
if (FAILED(D3DXCreateTextureFromFileEx (direct3DDevice, fileName, 0, 0, 1, 0,
D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_DEFAULT,
colorkey, NULL, NULL, &d3dTexture)))
{
return NULL;
}
//Return the newly made texture
return d3dTexture;
}
//Draw a textured quad on the back-buffer
void BlitD3D (IDirect3DTexture9 *texture, RECT *rDest,
D3DCOLOR vertexColour, float rotate)
{
const DWORD D3DFVF_TLVERTEX = D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1;
struct TLVERTEX
{
float x, y, z, rhw;
D3DCOLOR color;
float u;
float v;
};
IDirect3DVertexBuffer9* vertexBuffer;
// 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);
//Setup vertices
//A -0.5f modifier is applied to vertex coordinates to match texture
//and screen coords. Some drivers may compensate for this
//automatically, but on others texture alignment errors are introduced
//More information on this can be found in the Direct3D 9 documentation
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();
//Set texture
direct3DDevice->SetTexture (0, texture);
//Draw image
direct3DDevice->DrawPrimitive (D3DPT_TRIANGLEFAN, 0, 2);
}
Upvotes: 2
Views: 8970
Reputation: 13005
You have several issues that prevent your app from proper rendering.
Your code is a hairy mess. Every function do whatever it wants. Nearly impossible to read it and find a bugs. Instead this make number of functions, that doing concrete tasks, separating responsibilities, so you can focus (debug, improve) at one task a time.
No error checking. You will naver find bug if (1) you dont know what exactly happened, (2) where it happened. So after every single function call, you must check possible errors. DirectX API makes it easy: you can look at HRESULT
variable, returned from function, "decode" it, and in case of fail change program flow to handle error or just make a warning. See code below.
Use D3DFMT_UNKNOWN
in D3DXCreateTextureFromFileEx
if you not sure what exactly format you image file has:
D3DXCreateTextureFromFileEx (direct3DDevice, fileName, 0, 0, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_DEFAULT, colorkey, 0, 0, &d3dTexture)
Never use WM_PAINT
to trigger you rendering. Now your app rendering only 1 frame. Instead, put your rendering in main loop.
Full source is very long and formatting it a little pain, so I've uploaded it to pastebin: link (you must also add to your linker input options dxerr.lib
from DXSDK or from here )
Further reading:
D3DXCreateTextureFromFileEx
HRESULT
, Common HRESULT ValuesUpvotes: 1