c++ - 在屏幕上绘制纹理

标签 c++ directx textures

我正在尝试学习 DirectX,但感觉不知所措。谁能告诉我为什么这不起作用?图像不显示在屏幕上。 window 是全黑的。我试图按照教程进行操作,这是他们拥有的代码。

#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)你不知道到底发生了什么,(2)它发生在哪里,你将永远不会发现错误。所以在每次函数调用之后,你必须检查可能的错误。 DirectX API 让这一切变得简单:您可以查看从函数返回的 HRESULT 变量,对其进行“解码”,如果失败则更改程序流程以处理错误或仅发出警告。请参阅下面的代码。

  • 如果不确定图像文件的确切格式,请在 D3DXCreateTextureFromFileEx 中使用 D3DFMT_UNKNOWN:

    D3DXCreateTextureFromFileEx(direct3DDevice、文件名、0、0、0、0、D3DFMT_UNKNOWN、D3DPOOL_MANAGED、D3DX_FILTER_NONE、D3DX_DEFAULT、colorkey、0、0、&d3dTexture)

  • 切勿使用 WM_PAINT 触发渲染。现在您的应用只渲染 1 帧。相反,将您的渲染放在主循环中。

完整源代码 很长,格式化有点麻烦,所以我把它上传到 pastebin:link (您还必须将 DXSDK 或 here 中的 dxerr.lib 添加到您的链接器输入选项)

进一步阅读:

关于c++ - 在屏幕上绘制纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16346184/

相关文章:

c++ - 运算符重载 : member function vs. 非成员函数?

directx - 再一次: triangle strips vs triangle lists

c++ - 从四元数查看矩阵

android - SurfaceTexture 大小,如何定义?

c++ - Lapack 例程 dstev 中的段错误

c++ - 如何将特定的 Boost 库编译为 DLL

c++ - 在C++/Directx中使用EXACT进行简单的2D游戏

javascript - 如何将 Sprite 纹理应用于 matter.js 主体

android - 某些手机​​上的 gl 纹理错误

c++ - FLTK 关闭窗口