7

D3D11で2つの頂点の間に線を引こうとしました。D3D9とD3D11でいくつかの経験がありますが、D3D11では、ある特定のピクセルで始まり、別のピクセルで終わる線を描くのは問題のようです。

私がしたこと:

  1. テクセル/ピクセル座標系に合うように、各頂点のピクセル座標に0.5fを追加しました(D3D9座標系とD3D11座標系の違いについてMicrosoftのページを読みました)。

    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、Viewport、..を設定します。

  4. 頂点をD3D11_PRIMITIVE_TOPOLOGY_LINELISTとして描画します

問題:ラインが1ピクセル短いようです。それは与えられたピクセル座標で始まり、完璧にフィットします。線の方向は正しいように見えますが、線を終了させたいピクセルはまだ色付けされていません。線が1ピクセルから短いように見えます...

この問題を説明するチュートリアルはありますか、それとも誰かが同じ問題を抱えていますか?私が覚えているように、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 に答える