Question

I tried to draw a 2D circle with D3D9 per vertices and DrawPrimitive but failed somehow.

The white points in the picture below representing my vertices and the cyan circle is rendered with my function.

Click here for example image

This is my ellipse function

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

I don't know what I'm doing wrong, obviously the last 2 vertices won't be drawn. Would be very glad if somebody could explain to me whats wrong!

No correct solution

OTHER TIPS

This is the correct behavior of geometry type D3DPT_TRIANGLEFAN, suppose you want to split the ellipse to 4 sides, you will need 5 vertex(plus the center of the ellipse v0) as below, so you will get 5 - 2 = 3 triangle fans, that's v0v1v2, v0v2v3, and v0v3v4, but you won't get v0v4v1, Direct3D won't do that for you.

enter image description here

if you want to get the last triangle fan v0v4v1, you need an extra vertex to store v1, something like

vextex[5] = vertex[1]

now you have 6 vertex, so you will get 6 - 2 = 4 triangle fans including v0v4v1.

you need two extra vertex, one for the center of the ellipse, one for the last vertex

int VertexSize = ( Sides * Abundance ) + 2;

Add this line below the for loop, this will add the last vertex in order to draw the last triangle fan.

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

Triangle fans in Direct3D 9

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top