C++ 在屏幕上绘制纹理

C++ 在屏幕上绘制纹理,c++,directx,textures,C++,Directx,Textures,我正在尝试学习DirectX,感觉非常不知所措。有人能告诉我为什么这不起作用吗?图像不会显示在屏幕上。窗户全黑了。我试着按照教程来做,这是他们的代码 #include <windows.h> #include <d3d9.h> #include <d3dx9tex.h> LPDIRECT3D9 direct3D = NULL; LPDIRECT3DDEVICE9 direct3DDevice = NULL; IDirect3DTexture9* textur

我正在尝试学习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);
}
#包括
#包括
#包括
LPDIRECT3D9 direct3D=NULL;
LPDIRECT3DDEVICE9 direct3DDevice=NULL;
IDirect3DTexture9*纹理;
LRESULT WINAPI WndProc(HWND HWND、UINT msg、WPARAM WPARAM、LPARAM LPARAM);
IDirect3DTexture9*加载纹理(wchar_t*文件名);
void BlitD3D(IDirect3DTexture9*纹理,RECT*rDest,
D3D颜色顶点颜色,浮动旋转);
int WINAPI WinMain(HINSTANCE HINSTANCE、HINSTANCE hPrevInstance、LPSTR lpCmdLine、int nShow)
{
味精;
WNDCLASSEX wc={sizeof(WNDCLASSEX),CS_VREDRAW | CS|HREDRAW | CS|u OWNDC,
WndProc,0,0,hInstance,NULL,NULL,(HBRUSH)(颜色窗口+1),
NULL,L“DX9\U教程1\U类”,NULL};
注册类别(&wc);
HWND hMainWnd=CreateWindow(L“DX9\u教程1\u类”,
L“DirectX 9裸体教程1”,
WS_重叠窗口,100100300300,
NULL,NULL,hInstance,NULL);
direct3D=Direct3DCreate9(D3D\U SDK\U版本);
D3DPRESENT_参数PresentParams;
memset(&PresentParams,0,sizeof(D3DPRESENT_参数));
PresentParams.Windowed=true;
PresentParams.SwapEffect=D3DSWAPEFFECT_DISCARD;
direct3D->CreateDevice(D3DADAPTER_默认值、D3DDEVTYPE_HAL、hMainWnd、,
D3D创建软件(垂直处理、显示参数和direct3DDevice);
direct3DDevice->SetRenderState(D3DRS_照明,错误);
direct3DDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,TRUE);
direct3DDevice->SetRenderState(D3DRS_SRCBLEND,D3DBLEND_SRCALPHA);
direct3DDevice->SetRenderState(D3DRS\u destlend,D3DBLEND\u INVSRCALPHA);
direct3DDevice->SetTextRestate(0,D3DTSS_ALPHAOP,D3DTOP_调制);
纹理=加载纹理(L“Ash.png”);
橱窗(hMainWnd,nShow);
更新域(hMainWnd);
while(GetMessage(&msg,NULL,0,0))
{
翻译信息(&msg);
发送消息(&msg);
}
direct3DDevice->Release();
direct3D->Release();
返回0;
}
LRESULT WINAPI WndProc(HWND HWND、UINT msg、WPARAM WPARAM、LPARAM LPARAM)
{
开关(msg)
{
案例WM_销毁:
PostQuitMessage(0);
返回0;
案例WM_油漆:
RECT*RECT=新的RECT;
rect->left=10;
rect->top=10;
矩形->底部=60;
rect->right=60;
direct3DDevice->Clear(0,NULL,D3DCLEAR\u目标,D3DCOLOR\u XRGB(0,0,0),
1.0f,0);
direct3DDevice->BeginScene();
BlitD3D(纹理,矩形,D3DCOLOR_ARGB(1,1,1,1),0);
direct3DDevice->EndScene();
direct3DDevice->Present(空,空,空,空);
验证(hWnd,NULL);
返回0;
}
返回(DefWindowProc(hWnd、msg、wParam、lParam));
}
//使用D3DX从文件加载纹理
//支持的格式:BMP、PPM、DDS、JPG、PNG、TGA、DIB
IDirect3DTexture9*加载纹理(wchar_t*文件名)
{
IDirect3D纹理9*D3D纹理;
//使用洋红色的颜色键
D3DCOLOR colorkey=0xFFFF00FF;
//从文件中加载图像
如果(失败)(D3DXCreateTextureFromFileEx(direct3DDevice,文件名,0,0,1,0,
D3DFMT_A8R8G8B8,D3DPOOL_托管,D3DX_过滤器_无,D3DX_默认,
colorkey、NULL、NULL和d3dTexture)))
{
返回NULL;
}
//返回新制作的纹理
返回d3dTexture;
}
//在后缓冲区上绘制纹理四边形
void BlitD3D(IDirect3DTexture9*纹理,RECT*rDest,
D3D颜色顶点颜色,浮动旋转)
{
常量DWORD D3DFVF_TLVERTEX=D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1;
结构TLVERTEX
{
浮动x、y、z、rhw;
D3D彩色;
浮动u;
浮动v;
};
IDirect3DVertexBuffer9*vertexBuffer;
//设置顶点着色器。
direct3DDevice->SetVertexShader(空);
direct3DDevice->SetFVF(D3DFVF_TLVERTEX);
//创建顶点缓冲区。
direct3DDevice->CreateVertexBuffer(sizeof(TLVERTEX)*4,空,
D3DFVF_TLVERTEX、D3DPOOL_MANAGED和vertexBuffer,NULL);
direct3DDevice->SetStreamSource(0,vertexBuffer,0,sizeof(TLVERTEX));
TLVERTEX*顶点;
//锁定顶点缓冲区
vertexBuffer->Lock(0,0,(void**)和顶点,NULL);
//设置顶点
//将-0.5f修改器应用于顶点坐标以匹配纹理
//和屏幕坐标。一些驱动程序可能会对此进行补偿
//自动,但在其他情况下会引入纹理对齐错误
//有关这方面的更多信息,请参阅Direct3D 9文档
顶点[0]。颜色=顶点颜色;
顶点[0]。x=(浮点)rDest->左-0.5f;
顶点[0]。y=(浮点)rDest->top-0.5f;
顶点[0]。z=0.0f;
顶点[0]。rhw=1.0f;
顶点[0]。u=0.0f;
顶点[0]。v=0.0f;
顶点[1]。颜色=顶点颜色;
顶点[1]。x=(浮点)rDest->右-0.5f;
顶点[1]。y=(浮点)rDest->top-0.5f;
顶点[1]。z=0.0f;
顶点[1]。rhw=1.0f;
顶点[1]。u=1.0f;
顶点[1]。v=0.0f;
顶点[2]。颜色=顶点颜色;
顶点[2]。x=(浮点)rDest->右-0.5f;
顶点[2]。y=(浮点)rDest->bottom-0.5f;
顶点[2]。z=0.0f;
顶点[2]。rhw=1.0f;
顶点[2]。u=1.0f;
顶点[2]。v=1.0f;
顶点[3]。颜色=顶点颜色;
顶点[3]。x=(浮点)rDest->左-0.5f;
顶点[3]。y=(浮点)rDest->bottom-0.5f;
顶点[3]。z=0.0f;
顶点[3]。rhw=1.0f;
顶点[3]。u=0.0f;
顶点[3]。v=1.0f;
//解锁顶点缓冲区
vertexBuffer->Unlock();
//设置纹理
direct3DDevice->SetTexture(0,纹理);
//画图
direct3DDevice->DrawPrimitive(D3DPT_三角帆,0,2);
}

您有几个问题妨碍了应用程序的正确渲染

  • 你的代码乱七八糟。每个函数都做它想做的事情。几乎不可能阅读它并找到一个bug。相反,这会增加功能的数量,即执行具体任务、分离责任,这样您就可以一次只关注一个任务(调试、改进)

  • 无错误检查。如果(1)你不知道到底发生了什么,(2)它发生在哪里,你就会发现这个错误。因此,在每次函数调用之后,必须检查可能的错误。DirectX API使它变得简单:您可以查看
    HRESULT
    变量,然后