我正在尝试学习DirectX,我感到非常不知所措。谁能告诉我为什么这不起作用?图像不会显示在屏幕上。窗户全是黑色的。我试图按照这个教程进行操作,这是他们的代码。
#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);
}
答案 0 :(得分:2)
您有几个问题导致您的应用无法正常呈现。
你的代码很麻烦。每个功能都可以随心所欲。几乎不可能阅读它并发现错误。相反,这会产生许多功能,即执行具体任务,分离责任,这样您就可以在一次任务中集中注意力(调试,改进)。
没有错误检查。如果(1)你不知道到底发生了什么,(2)它发生了什么,你会找到bug。因此,在每次单个函数调用之后,您必须检查可能的错误。 DirectX API让它变得简单:您可以查看HRESULT
变量,从函数返回,“解码”它,并在失败时更改程序流来处理错误或只是发出警告。请参阅以下代码。
如果您不确定图片文件的确切格式,请在D3DFMT_UNKNOWN
中使用D3DXCreateTextureFromFileEx
:
D3DXCreateTextureFromFileEx (direct3DDevice, fileName, 0, 0, 0, 0, D3DFMT_UNKNOWN, D3DPOOL_MANAGED, D3DX_FILTER_NONE, D3DX_DEFAULT, colorkey, 0, 0, &d3dTexture)
切勿使用WM_PAINT
来触发渲染。现在您的应用只渲染1帧。相反,将渲染放在主循环中。
完整源代码非常长并且格式化它有点痛苦,所以我已将其上传到pastebin:link(您还必须添加到链接器输入选项{{1}来自DXSDK或来自here)
进一步阅读: