【问题标题】:D3D9 circle primitive bugD3D9 圆形原始错误
【发布时间】:2015-05-26 06:50:19
【问题描述】:

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

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

这是我的椭圆函数

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

【问题讨论】:

    标签: directx primitive ellipse direct3d9


    【解决方案1】:

    这是几何类型 D3DPT_TRIANGLEFAN 的正确行为,假设你想将椭圆分成 4 条边,你需要 5 个顶点(加上椭圆的中心 v0),如下所示,所以你会得到 5 - 2 = 3三角扇,即 v0v1v2、v0v2v3 和 v0v3v4,但你不会得到 v0v4v1,Direct3D 不会为你做。

    如果你想得到最后一个三角扇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

    【讨论】:

      猜你喜欢
      • 2011-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-14
      • 1970-01-01
      • 2018-12-14
      • 1970-01-01
      相关资源
      最近更新 更多