7

我试图用 D3D11 在两个顶点之间画一条线。我在 D3D9 和 D3D11 方面有一些经验,但在 D3D11 中画一条线似乎是一个问题,它从一个给定的像素开始,到另一个像素结束。

我做了什么:

  1. 我在每个顶点的像素坐标上添加了 0.5f 以适应纹素/像素坐标系(我阅读了 Microsoft 页面以了解 D3D9 和 D3D11 坐标系之间的差异):

    f32 fOff = 0.5f;ColoredVertex newVertices[2] = { { D3DXVECTOR3(fStartX + fOff, fStartY + fOff,0), vecColorRGB }, { D3DXVECTOR3(fEndX + fOff, fEndY + fOff,0), vecColorRGB } };

  2. 生成一个正交投影矩阵以适应渲染目标:

    D3DXMatrixOrthoOffCenterLH(&MatrixOrthoProj,0.0f,(f32)uRTWidth,0.0f,(f32)uRTHeight,0.0f,1.0f); D3DXMatrixTranspose(&cbConstant.m_matOrthoProjection,&MatrixOrthoProj);

  3. 设置 RasterizerState、BlendState、视口、...

  4. 将顶点绘制为 D3D11_PRIMITIVE_TOPOLOGY_LINELIST

问题:线条似乎短了一个像素。它从给定的像素坐标开始,非常适合它。线条的方向看起来是正确的,但是我希望线条结束的像素仍然没有着色。看起来这条线只有一个像素短......

任何教程解释了这个问题还是有人有同样的问题?我记得在 D3D9 中这并不难。

请询问您是否需要更多信息。

谢谢,斯特凡

编辑:找到 d3d10 的光栅化规则(d3d11 应该相同):http: //msdn.microsoft.com/en-us/library/cc627092%28v=vs.85%29.aspx#Line_1

我希望这能帮助我理解......

4

3 回答 3

4

根据光栅化规则(上述问题中的链接),我可能已经找到了一个可行的解决方案:

  1. 对顶点 StartX < EndX 和 StartY < EndY 进行排序
  2. 将 (0.5/0.5) 添加到起始顶点(就像我之前所做的那样)以将顶点移动到像素的中心
  3. 将(1.0/1.0)添加到结束顶点以将顶点移动到右下角

这需要告诉光栅化器应该绘制线的最后一个像素。

f32 fXStartOff = 0.5f;
f32 fYStartOff = 0.5f;
f32 fXEndOff = 1.0f;
f32 fYEndOff = 1.0f;

ColoredVertex newVertices[2] = 
{
    { D3DXVECTOR3((f32)fStartX + fXStartOff, (f32)fStartY + fYStartOff,0), vecColorRGB },
    { D3DXVECTOR3((f32)fEndX + fXEndOff , (f32)fEndY + fYEndOff,0), vecColorRGB }
};

如果您知道更好的解决方案,请告诉我。

于 2011-05-06T10:42:55.930 回答
1

我不知道 D3D11,但您的问题听起来很像 D3D9 中的 D3DRS_LASTPIXEL 渲染状态 - 也许您需要研究 D3D11 的等价物。

于 2011-05-05T21:24:14.247 回答
0

我遇到了完全相同的问题,感谢这个讨论,我解决了。

我的顶点存储在 D3D11_PRIMITIVE_TOPOLOGY_LINELIST 顶点缓冲区中。

感谢这篇有用的帖子,你今天让我修复了这个错误。这真的比我一开始想的要棘手。

这是我的几行代码。

// projection matrix code
float width = 1024.0f;
float height = 768.0f;
DirectX::XMMATRIX offsetedProj = DirectX::XMMatrixOrthographicRH(width, height, 0.0f, 10.0f);
DirectX::XMMATRIX proj = DirectX::XMMatrixMultiply(DirectX::XMMatrixTranslation(- width / 2, height / 2, 0), offsetedProj);

// view matrix code
// screen top left pixel is 0,0 and bottom right is 1023,767
DirectX::XMMATRIX viewMirrored = DirectX::XMMatrixLookAtRH(eye, at, up);
DirectX::XMMATRIX mirrorYZ = DirectX::XMMatrixScaling(1.0f, -1.0f, -1.0f);
DirectX::XMMATRIX view = DirectX::XMMatrixMultiply(mirrorYZ, viewMirrored);

// draw line code in my visual debug tool.
void TVisualDebug::DrawLine2D(int2 const& parStart,
                              int2 const& parEnd,
                              TColor parColorStart,
                              TColor parColorEnd,
                              float parDepth)

{
    FLine2DsDirty = true;

    // D3D11_PRIMITIVE_TOPOLOGY_LINELIST
    float2 const startFloat(parStart.x() + 0.5f, parStart.y() + 0.5f);
    float2 const endFloat(parEnd.x() + 0.5f, parEnd.y() + 0.5f);
    float2 const diff = endFloat - startFloat;
    // return normalized difference or float2(1.0f, 1.0f) if distance between the points is null. Then multiplies the result by something a little bigger than 0.5f, 0.5f is not enough.
    float2 const diffNormalized =  diff.normalized_replace_if_null(float2(1.0f, 1.0f)) * 0.501f;

    size_t const currentIndex = FLine2Ds.size();
    FLine2Ds.resize(currentIndex + 2);
    render::vertex::TVertexColor* baseAddress = FLine2Ds.data() + currentIndex;
    render::vertex::TVertexColor& v0 = baseAddress[0];
    render::vertex::TVertexColor& v1 = baseAddress[1];
    v0.FPosition = float3(startFloat.x(), startFloat.y(), parDepth);
    v0.FColor = parColorStart;
    v1.FPosition = float3(endFloat.x() + diffNormalized.x(), endFloat.y() + diffNormalized.y(), parDepth);
    v1.FColor = parColorEnd;
}

我测试了几个 DrawLine2D 调用,它似乎运行良好。

于 2015-09-25T21:56:41.243 回答