在屏幕上绘制纹理

时间:2013-05-02 19:27:41

标签: c++ directx textures

我正在尝试学习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);
}

1 个答案:

答案 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

进一步阅读: