Search code examples
windowsgraphicsrenderingdirectx

How to change the triangle in to a square


How do I change the triangle in to a square in my d3d11 app (I don't have much experience so idk how to do it) I got the code from this http://www.directxtutorial.com/Lesson.aspx?lessonid=11-4-5 tutorial to render a green triagle but i need to make it a square.


Solution

  • Instead of drawing a single triangle, you draw TWO triangles that share two vertices. The key challenge is making sure you specify them with the correct winding order for your rendering setup.

        // Single multi-colored triangle
        static const Vertex s_vertexData[3] =
        {
            { { 0.0f,   0.5f,  0.5f, 1.0f },{ 1.0f, 0.0f, 0.0f, 1.0f } },  // Top / Red
            { { 0.5f,  -0.5f,  0.5f, 1.0f },{ 0.0f, 1.0f, 0.0f, 1.0f } },  // Right / Green
            { { -0.5f, -0.5f,  0.5f, 1.0f },{ 0.0f, 0.0f, 1.0f, 1.0f } }   // Left / Blue
        };
    
    ...
        context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
        context->Draw(3, 0);
    

    SimpleTriangle sample on GitHub

    You can draw the two triangles two different ways.

    The FIRST and most straight-forward is using an index buffer (IB) which makes it easier to support arbitrary cull settings.

        // Two triangles forming a quad with the same color at all corners
        static const Vertex s_vertexData[4] =
        {
            { { -0.5f, -0.5f, 0.5f, 1.0f }, { 0.f, 1.f } },
            { {  0.5f, -0.5f, 0.5f, 1.0f }, { 1.f, 1.f } },
            { {  0.5f,  0.5f, 0.5f, 1.0f }, { 1.f, 0.f } },
            { { -0.5f,  0.5f, 0.5f, 1.0f }, { 0.f, 0.f } },
        };
    
        static const uint16_t s_indexData[6] =
        {
            3,1,0,
            2,1,3,
        };
    
    ...
    
        context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
       context->DrawIndexed(6, 0, 0);
    

    SimpleTexture sample on GitHub

    The SECOND method is a bit trickier which is to use just 4 vertices without an index buffer by drawing them as a triangle strip. The problem here is that it constrains your winding order choices a fair bit. If you turn off backface culling, it's really simple using the same 4 vertices

       // Create rsState with D3D11_RASTERIZER_DESC.CullMode
       // set to D3D11_CULL_NONE
    
    ...
       context->RSSetState(rsState);
       context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
        context->Draw(4, 0);
    

    As you are new to DirectX, you may want to take a look at DirectX Tool Kit.

    PS: For the special case of wanting a quad that fills an entire render viewport (such as a full-screen quad), with Direct3D Hardware Feature Level 10.0 or better hardware, you can skip using a IB or VB at all and just generate the quad inside the vertex shader itself. See GitHub.