c++ - 绘制带纹理的四边形看起来变形了

标签 c++ directx directx-9

我正在阅读名为 Introduction To 3D Game Programming With Directx 9.0 的书,我从书中复制并粘贴了以下示例:

struct Vertex
{
    float _x, _y, _z;
    float _nx, _ny, _nz;
    float _u, _v; // texture coordinates
    static const DWORD FVF;
};

const DWORD Vertex::FVF = D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1;

void D3DGraphics::drawBMP()
{
    pDevice->CreateVertexBuffer(6 * sizeof(Vertex), D3DUSAGE_WRITEONLY, Vertex::FVF, D3DPOOL_MANAGED, &quadVertexBuffer, 0);
    Vertex* v;
    quadVertexBuffer->Lock(0, 0, (void**)&v, 0);

    // quad built from two triangles, note texture coordinates:
    v[0] = { -1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f }; // was Vertex()
    v[1] = { -1.0f, 1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f };
    v[2] = { 1.0f, 1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f };
    v[3] = { -1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f };
    v[4] = { 1.0f, 1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f };
    v[5] = { 1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f };
    quadVertexBuffer->Unlock();

    // Load texture data.
    if (!texture)
    {
        D3DXCreateTextureFromFile(pDevice, L"C:\\Users\\Owner\\Desktop\\Result.bmp", &texture);
    }

    // Enable the texture.
    pDevice->SetTexture(0, texture);

    // Set texture filters.
    pDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    pDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    pDevice->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_POINT);

    // set projection matrix
    D3DXMATRIX proj;
    D3DXMatrixPerspectiveFovLH(&proj, D3DX_PI * 0.5f, (float)1280 / (float)720, 1.0f, 1000.0f);
    pDevice->SetTransform(D3DTS_PROJECTION, &proj);

    // don't use lighting for this sample
    pDevice->SetRenderState(D3DRS_LIGHTING, false);



    // render code
    pDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0xffffffff, 1.0f, 0);
    pDevice->BeginScene();
    pDevice->SetStreamSource(0, quadVertexBuffer, 0, sizeof(Vertex));
    pDevice->SetFVF(Vertex::FVF);
    // Draw primitives using presently enabled texture.
    pDevice->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);
    pDevice->EndScene();
    pDevice->Present(0, 0, 0, 0);
}

我只改变了一件事。书中的结构是这样初始化的:

v[0] = Vertex(-1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
v[1] = Vertex(-1.0f, 1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);
v[2] = Vertex( 1.0f, 1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);

v[3] = Vertex(-1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
v[4] = Vertex( 1.0f, 1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);
v[5] = Vertex( 1.0f, -1.0f, 1.25f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f);

但这似乎会导致编译器错误,所以我在我的代码中进行了更改。总之,Result.bmp 的尺寸是 1280x720。我正在渲染的窗口也是 1280x720。这是 Result.bmp .这是 output我正进入(状态。通常我不会问这么简单的问题,但我正在努力学习,这是一个直接来自教科书的例子(这是行不通的)。考虑到这是书中的复制和粘贴,我认为我(还)没有犯任何错误,我想知道这是否是书中的错误。如果我将 0.5f 更改为 0.4f,则尝试 D3DXMatrixPerspectiveFovLH 的第二个参数似乎让事情变得更好,但它仍然失真。

最佳答案

由于您使用的是 D3DXMatrixPerspectiveFovLH,因此您正在渲染一个带有角 (-1,-1) -> (1,1) 的方形四边形。由于 BMP 具有 16:9 aspect ratio ,结果是扭曲的纹理图像。

如果你想让图像全屏,你需要使用非透视投影如D3DXMatrixOrthoLH:

// set projection matrix
D3DXMATRIX proj;
D3DXMatrixOrthoLH(&proj, 2.0f, 2.0f, 1.0f, 1000.0f);
pDevice->SetTransform(D3DTS_PROJECTION, &proj);

在这种情况下,同一个四边形将具有使输入图像消除失真所需的 16:9 纵横比。

顺便说一句:我建议转向 DirectX 11 并使用 DirectX Tool KitSpriteBatch 而不是十年前的 Direct3D 9 API...

关于c++ - 绘制带纹理的四边形看起来变形了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30698919/

相关文章:

c++ - 为什么编译器在 vector 已满时不尝试分配连续内存(如果可能)?

c++ - Cmake include_directories()

C++如何正确复制指针的容器( vector )?

c++ - 在g++中收到的预期主表达式

video-streaming - 英特尔H264硬件MFT不支持GOP设置

c# - C++/Cx for C# 中的 Directx 包装器

multithreading - DirectX在其他线程中绘制

c++ - 将 C++ 应用程序从 Directx9 移植到 Directx10 之前的重要阅读

c++ - DirectX 9 "unresolved external symbol"问题

c++ - DirectX 11。你好三角形不渲染