0

我已经阅读几篇文章,这些文章描述了将纹理移动一半顶点位置的必要性,以便获得纹素和像素之间的正确映射。虽然我认为我理解它背后的理论,但当我尝试实施解决方案时(向左移动半个单位),我得到的只是渲染图像两侧的黑线。

我得到的印象是我要么没有调整正确的 x 和 y 参数,要么这不适用于我的特定场景。我使用带有线性过滤的 direct3d 9 并渲染覆盖整个屏幕的图像。我已经尝试过纹理的实际大小和 -1 到 +1 (即根据两个链接文章中的不同解决方案)。两种方法都产生相同的效果。

我的问题是,何时需要进行此更正,是否有正确的方法可以做到这一点,而我却错过了?

4

1 回答 1

1

根据 DirectX 文档,仅在“使用预转换顶点渲染 2D 输出时”才需要偏移半个像素。预先转换的顶点是那些在调用中D3DFVF_XYZRHW指定了标志的顶点。IDirect3DDevice9::SetFVF为了正确绘制转换后的顶点,您必须将其位置设置为(posx - 0.5, posy - 0.5, 0, 1)顶点(posx, posy)的屏幕空间坐标(以像素为单位)。

这是渲染全屏纹理四边形的代码:

struct TRANSFORMED_VERTEX
{
    D3DXVECTOR4 pos;
    D3DXVECTOR2 tex;
    static const DWORD FVF;
};
const DWORD TRANSFORMED_VERTEX::FVF = D3DFVF_XYZRHW | D3DFVF_TEX1;



void RenderFullScreenQuad()
{
    D3DSURFACE_DESC desc;
    LPDIRECT3DSURFACE9 pSurf;

    g_pd3dDevice->GetRenderTarget(0, &pSurf);
    pSurf->GetDesc(&desc);
    pSurf->Release();

    float width = (float)desc.Width - 0.5f;
    float height = (float)desc.Height - 0.5f;

    TRANSFORMED_VERTEX v[4];
    v[0].pos = D3DXVECTOR4(-0.5f, -0.5f, 0.0f, 1.0f);
    v[1].pos = D3DXVECTOR4(width, -0.5f, 0.0f, 1.0f);
    v[2].pos = D3DXVECTOR4(-0.5f, height, 0.0f, 1.0f);
    v[3].pos = D3DXVECTOR4(width, height, 0.0f, 1.0f);

    v[0].tex = D3DXVECTOR2(0.0f, 0.0f);
    v[1].tex = D3DXVECTOR2(1.0f, 0.0f);
    v[2].tex = D3DXVECTOR2(0.0f, 1.0f);
    v[3].tex = D3DXVECTOR2(1.0f, 1.0f);

    g_pd3dDevice->SetFVF(TRANSFORMED_VERTEX::FVF);
    g_pd3dDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, v, sizeof(TRANSFORMED_VERTEX));
}

当然,你需要在BeginScene()和之间调用这个函数EndScene()。您还必须正确设置纹理和采样器状态(或着色器常量)。

于 2012-05-15T13:50:44.720 回答