D3D9圈原始bug

时间:2014-02-04 20:37:14

标签: directx primitive ellipse direct3d9

我试图用每个顶点和DrawPrimitive绘制一个带有D3D9的2D圆,但不知何故失败了。

下图中代表我的顶点和青色圆圈的白点用我的函数渲染。

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个顶点不会被绘制出来。 如果有人可以向我解释什么是错的,我会很高兴的!

1 个答案:

答案 0 :(得分: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;

在for循环下方添加此行,这将添加最后一个顶点以绘制最后一个三角形扇形。

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

Triangle fans in Direct3D 9