我已阅读a couple articles,其中描述了将纹理移动一半顶点位置的必要性,以便在纹素和像素之间获得正确的映射。虽然我认为我理解它背后的理论,但当我尝试实现解决方案时(向左移动半个单元),我得到的只是渲染图像两侧的黑线。
我得到的印象是我要么不调整正确的x和y参数,要么这不适用于我的特定场景。我使用direct3d 9进行线性过滤,并渲染覆盖整个屏幕的图像。我已尝试使用纹理的实际大小和-1到+1(即根据两个链接文章中的不同解决方案)。两种方法都有同样的效果。
我的问题是,这种纠正何时需要,是否有正确的方法来解决这个问题?
答案 0 :(得分: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()
之间调用此功能。您还必须正确设置纹理和采样器状态(或着色器常量)。