Domanda

I am attempting to draw primitives in orthographic view using DirectX (on WP8), to make things easier I am trying to use DirectXTK.

However, for some reason I am unable to figure out on my own, only Line strip/list topology works while any triangle based have no (visual) effect.

Scene is orthographic and PrimitiveBatch is feed with BasicEffect, code is based on sample and tested on physical WP8 device.

projection = XMMatrixOrthographicOffCenterLH(-1, 1, -1, 1, 0, 1);
...
VertexPositionColor A, B, C, D; 
A.position.x = -0.5;
A.position.y = -0.5;
A.position.z = 0;B.position.x = 0.5;
B.position.x = 0.5;
B.position.y = -0.5;
B.position.z = 0;
C.position.x = 0.5;
C.position.y = 0.5;
C.position.z = 0;
D.position.x = -0.5;
D.position.y = 0.5;
D.position.z = 0;
//and so on, centered rectangle with width/height of half of screen
...    
// only DrawLine produces effect
m_batch->DrawLine(A, B);
m_batch->DrawQuad(A, B, C, D);
m_batch->DrawTriangle(A, B, C);

// even more direct approach produces no effect (for line topology it works fine)
m_batch->Draw(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST, mappedVertices, n);

All I need is a lot of 2D primitives (lines/rectangles with thickness and/or fill) and text (spritefont?) which currently is executed on .NET (XAML) frontend (with awesome speed of writing text via textblock...) which I want to get rid off but first clash with DirectX is killing me (Last time I bothered with such low level graphic stuff was on Commodore 64 and it appears that things have changed...)

Maybe there is another library that will better suit my needs of performance and native code but won't require learning new wicked technology?

È stato utile?

Soluzione

After some learning I am able to answer my own question.

As Zdd and Roger mentioned in comments, issue was caused by back-side culling, or rather incorrect order of vertices making triangles viable for culling. Back-Side Culling is testing triangle for visibility in quite simple way: vertices of triangle must be positioned clockwise around center of figure in order for it to be deemed visible.

There are two possible solutions.

  • Change Culling mode to accept incorrect order of vertices, but it results in reduced performance.
  • Change order of vertices to appropriate one, which require preparations before drawing

To check if vertices are in clockwise order it is enough to do a bit of math, and if result is False simply flip around A and C. Result depends on Z axis direction.

bool TestTriangle(VertexPositionColor A, VertexPositionColor B, VertexPositionColor C)
{
    float crossz = (B.position.x - A.position.x) * (C.position.y - B.position.y) - (B.position.y - A.position.y) * (C.position.x - B.position.x);
    // for Left Hand z axis
    return !(crossz > 0.0f);
    // for Right Hand z axis
    return (crossz > 0.0f);
}

For axis-aligned rectangles vertices can be created in correct order from start

void DrawRect(int x, int y, int h, int w, XMFLOAT4 brush)
{
    VertexPositionColor A, B, C, D;
    // set color
    D.color = C.color = B.color = A.color = brush;
    //Z index manipulation can be used to position figure above/below other drawings
    D.position.z = C.position.z = B.position.z = A.position.z = 0;
    // clockwise aligned vertices
    A.position.x = x; B.position.x = x + w;
    D.position.x = x; C.position.x = x + w;
    // DirectX Y axis starts from bottom left corner (as in cartesian coordinates system and in opposite to WinApi Top/Left coord system)
    A.position.y = y + h; B.position.y = y + h;
    D.position.y = y;     C.position.y = y;
    //m_batch is PrimitveBatch from Directx Toolkit
    m_batch->DrawQuad(A, B, C, D);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top