0
votes

I was trying to create triangle drawing with user-defined coordinates using Directx 11:

void triangle(float anchorx, float anchory, float x1, float y1, float x2, float y2, XMFLOAT4 _color)
{
XMMATRIX scale;
XMMATRIX translate;
XMMATRIX world;

simplevertex framevertices[3] = { XMFLOAT3(anchorx, ui::height - anchory, 1.0f), XMFLOAT2(0.0f, 0.0f),
                                   XMFLOAT3(x1, ui::height - y1, 1.0f), XMFLOAT2(1.0f, 0.0f),
                                   XMFLOAT3(x2, ui::height - y2, 1.0f), XMFLOAT2(1.0f, 1.0f) };

world = XMMatrixIdentity();

dx11::generalcb.world = XMMatrixTranspose(world);// XMMatrixIdentity();
dx11::generalcb.fillcolor = _color;
dx11::generalcb.projection  = XMMatrixOrthographicOffCenterLH( 0.0f, ui::width, 0.0f, ui::height, 0.01f, 100.0f );

// copy the vertices into the buffer
D3D11_MAPPED_SUBRESOURCE ms;
dx11::context->Map(dx11::vertexbuffers::trianglevertexbuffer, NULL, D3D11_MAP_WRITE_DISCARD, NULL, &ms);
memcpy(ms.pData, framevertices, sizeof(simplevertex) * 3);                 
dx11::context->Unmap(dx11::vertexbuffers::trianglevertexbuffer, NULL);  

dx11::context->VSSetShader(dx11::shaders::simplevertexshader, NULL, 0);
dx11::context->IASetVertexBuffers(0, 1, &dx11::vertexbuffers::trianglevertexbuffer, &dx11::verticestride, &dx11::verticeoffset);
dx11::context->IASetInputLayout(dx11::shaders::simplevertexshaderlayout);

dx11::context->PSSetShader(dx11::shaders::panelpixelshader, NULL, 0);
dx11::context->UpdateSubresource(dx11::general_cb, 0, NULL, &dx11::generalcb, 0, 0);
dx11::context->IASetIndexBuffer(dx11::indexbuffers::triangleindexbuffer, DXGI_FORMAT_R16_UINT, 0);
dx11::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);

dx11::context->DrawIndexed(4, 0, 0);
//dx11::context->Draw(3, 0);
};

Substration on Y axis when filling pos.y data:

XMFLOAT3(anchorx, ui::height - anchory, 1.0f)
XMFLOAT3(x1, ui::height - y1, 1.0f)
XMFLOAT3(x2, ui::height - y2, 1.0f)

My orthographic projection sets coordinates zeroes to left-bottom of the screen, so I substract passed Y coordinate from height of the window to get proper position on y axis. Not sure it can affect my problem because it worked well with all the rest of primitives (rectangles, textures, filled rectangles, lines and circles).

Index order defined in index buffer:

unsigned short                  triangleindices[6] = { 0, 1, 2, 0, 2, 3 };

Im actually using this index buffer to render rectangles so its created to render 2 triangles forming a quad, didn't bother to create separate triangle index buffer

Trianglevertexbuffer contains array 4 of simplevertex:

//A VERTEX STRUCT
struct simplevertex
{  
    XMFLOAT3 pos; // pixel coordintes
    XMFLOAT2 uv; // corresponding point color coordinates in texture
};

I was not using UV data at the function above, just filled them with random data, because color data is passed via constant buffer. As you see I also memcpy only 3 first array data to the vertex buffer for a triangle requires only 3.

VERTEX SHADER:

    // SIMPLE VERTEX SHADER 

    cbuffer buffer : register(b0) // constant buffer, set up as 0 in set constant buffers command
    {
        matrix world; // world matrix
        matrix projection; // projection matrix, is orthographic for now 
        float4 bordercolor;
        float4 fillcolor;
        float blendindex;
    };

    // simple vertex shader
    float4 main(float4 input : POSITION) : SV_POSITION
    {
        float4 output = (float4)0; // setting variable fields to zero, may be skipped?
    output = mul(input, world); // multiplying vertex shader output by world matrix passed in the constant buffer
    output = mul(output, projection); // multiplying on by projection passed in the constant buffer (2d for now), resulting in final output data(.pos)
    return output;
}

PIXEL SHADER:

    // SIMPLE PIXEL SHADER RETURNING COLOR PASSED IN CONSTNT BUFFER
cbuffer buffer : register(b0) // constant buffer, set up as 0 in set constant buffers command
{
    matrix world; // world matrix
    matrix projection; // projection matrix, is orthographic for now
    float4 bordercolor;
    float4 fillcolor;
    float blendindex;
};

// pixel shader returning preset color in constant buffer
float4 main(float4 input : SV_POSITION) : SV_Target
{
    return fillcolor; // and we just return the color passed to constant buffer
}

Layout used in the function:

{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 };

There, I created next lines in the rendering cycle:

if (ui::keys[VK_F1]) tools::triangle(700, 100, 400, 300, 850, 700, colors::blue);
if (ui::keys[VK_F2]) tools::triangle(400, 300, 700, 100, 850, 700, colors::blue);
if (ui::keys[VK_F3]) tools::triangle(700, 100, 850, 700, 400, 300, colors::blue);
if (ui::keys[VK_F4]) tools::triangle(850, 700, 400, 300, 700, 100, colors::blue);
if (ui::keys[VK_F5]) tools::triangle(850, 700, 700, 100, 400, 300, colors::blue);
if (ui::keys[VK_F6]) tools::triangle(400, 300, 850, 700, 700, 100, colors::blue);

The point of this setup is to achieve any random order of coordinates forming a triangle for rendering, but this is actually the point of this question - I didn't get this triangle rendered at some coordinates variations, so I came to conclusion it goes from TOPOLOGY, as you can see I have at the moment:

dx11::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
dx11::context->DrawIndexed(4, 0, 0); 

This is the only combination that draws all the triangles but I honestly don't understand how it does happen, from what I know STRIP topology is used with context->Draw function, while LIST works with index buffer setup. Tried next:

dx11::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
dx11::context->DrawIndexed(4, 0, 0);

Triangles F1, F5, F6 were not drawn. Aight, next:

dx11::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
//dx11::context->DrawIndexed(4, 0, 0);
dx11::context->Draw(3, 0);

Same story, F1, F5 and F6 are not rendered.

I cannot understand the things are going on, you may find the code a bit primitive but I only want to know why I get working result only with the combination of STRIP topology and DrawIndexed function. I hope I provided enough information, sorry if not, Ill correct on demand. Thank you:)

1

1 Answers

0
votes

Got this. First of all in my rasterizer settings I had rasterizerState.CullMode = D3D11_CULL_FRONT, don't remember why may be I just copy-pasted some other's steady code, so I changed it to D3D11_CULL_NONE and all worked as intended.

dx11::context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
dx11::context->Draw(3, 0);

Second, I found out that facing or not-facing of a primitive depends on the drawing direction, if drawing vertices goes counter-clockwise (vertice 2 is "righter" then vertice 1 on the start) the primitive is considered as facing the view, if it goes clockwise - than we see its "back" instead.

So i decided to keep D3D11_CULL_NONE instead of adding some math logic to define the order of vertices, dont know for sure if D3D11_CULL_NONE mode cuts performance tho.