Question

J'ai essayé de tracer une ligne entre deux sommets avec D3D11. J'ai quelques expériences dans D3D9 et D3D11, mais cela semble être un problème dans D3D11 pour tracer une ligne, qui commence dans un pixel donné et se termine par un autre.

Ce que j'ai fait:

  1. J'ai ajouté 0,5F aux coordonnées de pixels de chaque sommet pour s'adapter au système de coordonnées Texel- / Pixel (j'ai lu les pages Microsoft aux différences entre les systèmes de coordonnées D3D9 et D3D11):

    F32 renoff = 0,5f; ColoredVertex newVertices [2] = {{d3dxvector3 (fstartx + renoff, fstarty + renoff, 0), veccolorrgb}, {d3dxvector3 (fendx + foff, fendy + foff, 0), veccolorrgb}};

  2. Généré une matrice de projection Ortho pour s'adapter à la cible de rendu:

    D3dxMatrixorthOoffCenterlh (& matrixorthoproj, 0,0f, (f32) urtwidth, 0,0f, (f32) urtheight, 0,0f, 1,0f); D3dxMatrixTransspose (& cbConstant.m_matorThoprojection, & matrixorthoproj);

  3. Définissez Rasterizerstate, BlendState, la fenêtre, ...

  4. Dessinez des sommets sous le nom de D3D11_PRIMIENTAL_TOPOLOGY_LINELIST

Problème: la ligne semble être un pixel à court. Il commence dans la coordonnée de pixels donnée et lui convient parfaitement. La direction de la ligne semble correcte, mais le pixel où je veux que la ligne se termine n'est toujours pas colorée. Il semble que la ligne ne soit qu'un pixel à court ...

Le tutoriel explique-t-il ce problème ou est-ce que quelqu'un a le même problème? Comme je me souviens, ce n'était pas aussi difficile dans D3D9.

Veuillez vous demander si vous avez besoin d'informations supplémentaires.

Merci, Stefan

EDIT: Found les règles de rasterisation pour D3D10 (devrait être la même pour D3D11):http://msdn.microsoft.com/en-us/library/cc627092%28v=vs.85%29.aspx#line_1

J'espère que cela m'aidera à comprendre ...

Était-ce utile?

La solution

Selon les règles de rasterisation (lien dans la question ci-dessus), j'ai pu trouver une solution qui devrait fonctionner:

  1. Triez les sommets startx <endx et starty <endy
  2. Ajouter (0,5 / 0,5) au sommet de départ (comme je l'ai fait avant) pour déplacer le sommet au centre du pixel
  3. Ajouter (1.0 / 1.0) au sommet de la fin pour déplacer le sommet dans le coin inférieur droit

Cela est nécessaire pour indiquer au rasterizer que le dernier pixel de la ligne doit être tracé.

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 }
};

Si vous connaissez une meilleure solution, faites-le moi savoir.

Autres conseils

Je ne connais pas D3d11, mais votre problème ressemble beaucoup à l'état de rendu D3DRS_lastPixel de D3D9 - peut-être qu'il y a un égal pour D3D11 que vous devez examiner.

J'ai rencontré exactement le même problème, et je remercie cette discussion.

Mes sommets sont stockés dans un tampon de sommet D3D11_PRIMITIF_TOPOLOGY_LINELIST.

Merci pour ce message utile, vous m'avez fait corriger ce bug aujourd'hui. C'était vraiment plus délicat que je ne le pensais au début.

Ici quelques lignes de mon code.

// 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;
}

J'ai testé plusieurs appels Drawline2D, et cela semble bien fonctionner.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top