绘制纹理四边形看起来扭曲

时间:2015-06-07 22:04:16

标签: 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。通常情况下,我不会问这么简单的问题,但我正在努力学习,这是教科书中的一个例子(这不起作用)。考虑到这是一个副本&从书中粘贴,我认为我还没有犯任何错误,我想知道这是否是书中的错误。使用D3DXMatrixPerspectiveFovLH的第二个参数,如果我将0.5f改为0.4f但它仍然被扭曲,似乎已经让事情变得更好了。

1 个答案:

答案 0 :(得分:1)

由于您正在使用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 Kit SpriteBatch代替十年前的Direct3D 9 API ......