我尝试用D3D11在两个顶点之间画一条线。我在D3D9和D3D11中有一些经验,但在D3D11中绘制一条线似乎是一个问题,它在一个给定像素中开始并以另一个像素结束。
我做了什么:
我在每个顶点的像素坐标上添加了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} };
生成一个正投影矩阵以适合渲染目标:
D3DXMatrixOrthoOffCenterLH(安培; MatrixOrthoProj,0.0F,(F32)uRTWidth,0.0F,(F32)uRTHeight,0.0F,1.0F); D3DXMatrixTranspose(安培; cbConstant.m_matOrthoProjection,&安培; MatrixOrthoProj);
设置RasterizerState,BlendState,Viewport,...
问题: 线似乎是一个像素到短。它从给定的像素坐标开始,非常适合它。线条的方向看起来是正确的,但我希望线条结束的像素仍然没有着色。看起来这条线只是一个像素来缩短......
是否有任何教程解释此问题或者是否有人遇到同样的问题?我记得在D3D9中并不困难。
请询问您是否需要进一步的信息。
谢谢,Stefan
编辑:找到了d3d10的光栅化规则(对于d3d11应该是相同的): http://msdn.microsoft.com/en-us/library/cc627092%28v=vs.85%29.aspx#Line_1
我希望这能帮助我理解......
答案 0 :(得分:4)
根据光栅化规则(上面问题中的链接),我可能找到了一个应该有效的解决方案:
这需要告诉光栅化器应该绘制线的最后一个像素。
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 }
};
如果您知道更好的解决方案,请告诉我。
答案 1 :(得分:1)
我不知道D3D11,但你的问题听起来很像D3D9的D3DRS_LASTPIXEL渲染状态 - 也许你需要调查D3D11的等值。
答案 2 :(得分:0)
我遇到了完全相同的问题,我感谢此讨论。
我的顶点存储在D3D11_PRIMITIVE_TOPOLOGY_LINELIST顶点缓冲区中。
感谢这篇有用的帖子,你今天让我修复了这个bug。 这真的比我在开始时想的那么棘手。
这是我的代码的几行。
// 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调用,它似乎运行良好。