2014-02-04 7 views
0

Я попытался нарисовать 2D-круг с D3D9 на вершины и DrawPrimitive, но так или иначе не получился.Ошибка примитивного круга D3D9

Белые точки на изображении ниже, представляющие мои вершины и цианский круг, отображаются с моей функцией.

Click here for example image

Это моя Эллипс функция

RETURN CRender::Ellipse(SPos Position, SSize Size, int Sides, int LineWidth, CColor* BgColor, CColor* LineColor, float Abundance) 
{ 
    // check if parameters valid 
    if(!BgColor || !LineColor) return R_FAILED; // check pointers 
    if(Abundance > 1 || Abundance < 0) (Abundance > 1) ? Abundance = 1 : Abundance = 0; // max. & min. abundance 

    // instance needed vars 
    int VertexSize = (Sides * Abundance); // how much vertices to draw ? 
    int abSize = VertexSize * sizeof(CUSTOMVERTEX); // absolute size in byte 
    double PosOffset = 0; // used in function below 
    LPDIRECT3DVERTEXBUFFER9 VertexBuffer = NULL; // instance vertex buffer 
    CUSTOMVERTEX* Vertex = new CUSTOMVERTEX[ VertexSize ]; // instance vertices 
    D3DXVECTOR2* Line = new D3DXVECTOR2[ VertexSize ]; // instance outline 
    VOID* pData = NULL; // pipe data 

    // calc vertices 
    Vertex[ 0 ] = FillVertex(Position.X, Position.Y, /*Position.Z*/ 0, 1, BgColor->ToDWORD()); 
    for(int i = 1; i <= VertexSize; i++, PosOffset += (2*PI)/Sides) 
    { 
     // corrections 
     while(PosOffset > 2*PI) PosOffset -= 2*PI; 
     // instance vertex 
     Vertex[ i ] = FillVertex( (cos(PosOffset) * Size.Width) + Position.X, 
            (sin(PosOffset) * Size.Height) + Position.Y, 
            /*(tan(PosOffset) * Size.Depth) + Position.Z*/ 0, // fix 2D position 
            1, BgColor->ToDWORD()); 
    } 

    // instance buffer 
    Device->CreateVertexBuffer(abSize, D3DUSAGE_WRITEONLY, CUSTOMFVF, D3DPOOL_MANAGED, &VertexBuffer, NULL); 

    // prepare buffer 
    VertexBuffer->Lock(NULL, abSize, (void**)&pData, NULL); 
    memcpy(pData, Vertex, abSize); 
    VertexBuffer->Unlock(); 

    // prepare primitive 
    Device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); 
    Device->SetRenderState(D3DRS_ALPHABLENDENABLE, true); 
    Device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA); 
    Device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA); 

    // draw primitive 
    Device->SetStreamSource(0, VertexBuffer, NULL, sizeof(CUSTOMVERTEX)); 
    Device->DrawPrimitive(D3DPT_TRIANGLEFAN, 0, VertexSize - 2); 

    return R_OK; 
} 

Я не знаю, что я делаю неправильно, очевидно, последние 2 вершины не будут сделаны. Был бы очень рад, если бы кто-нибудь мог объяснить мне, что случилось!

ответ

0

Это правильное поведение типа геометрии D3DPT_TRIANGLEFAN, предположим, что вы хотите разделить эллипс на 4 стороны, вам понадобится 5 вершин (плюс центр эллипса v0), как показано ниже, так что вы получите 5 - 2 = 3 вентилятора треугольника, это v0v1v2, v0v2v3 и v0v3v4, но вы не получите v0v4v1, Direct3D не сделает этого для вас.

enter image description here

, если вы хотите, чтобы получить последний треугольник v0v4v1 вентилятора, вам требуется дополнительная вершина для хранения v1, что-то вроде

vextex[5] = vertex[1] 

теперь у вас есть 6 вершин, так что вы получите 6 - 2 = 4 треугольных вентилятора, включая v0v4v1.

вам понадобится две дополнительных вершины, один для центра эллипса, одна для последней вершины

int VertexSize = (Sides * Abundance) + 2; 

Добавьте эту строку ниже для цикла, это добавит последнюю вершину, чтобы привлечь последние треугольный вентилятор.

Vertex[VertexSize -1] = Vertex[1]; 

Triangle fans in Direct3D 9

Смежные вопросы