D3D 部分功能测试结论

  写了个测试程序,方便个人在使用中查询,不当之处请指出(以下结论均为三角形数为20000,一个批次中完成渲染)

1 在三角形数量不超过20000时,DrawIndexedPrimitive和DrawIndexedPrimitiveUP效率没有明显差别,
  前提是创建buffer时没有使用D3DUSAGE_DYNAMIC,否则DrawIndexedPrimitive的性能不如DrawIndexedPrimitiveUP
2 创建buffer时,如果D3DUSAGE使用的是0,DrawIndexedPrimitive的性能不如DrawIndexedPrimitiveUP,
  而且0和D3DUSAGE_WRITEONLY在三角形数量为20000时,性能差别比较大(差不多有100帧的差距)
3 尽量不要使用DrawPrimitive和DrawPrimitiveUP,尤其是DrawPrimitiveUP,效率比起前面两个函数,差很多
4 使用DrawIndexedPrimitive和DrawIndexedPrimitiveUP两个函数测试D3DPOOL_DEFAULT,D3DPOOL_MANAGED,
  D3DPOOL_SYSTEMMEM。发现D3DPOOL_DEFAULT,D3DPOOL_MANAGED的效率差不多,D3DPOOL_DEFAULT表现稍好。
  当使用D3DPOOL_SYSTEMMEM时,效率相对前面两个参数,DrawIndexedPrimitive有明显下降。
  而DrawIndexedPrimitiveUP的速度稍有下降,而且DrawIndexedPrimitiveUP比DrawIndexedPrimitive要快

以下是测试程序:


代码
#include <d3dx9.h>


//-----------------------------------------------------------------------------
// Desc: 全局变量
//-----------------------------------------------------------------------------
LPDIRECT3D9             g_pD3D       = NULL;    //Direct3D对象
LPDIRECT3DDEVICE9       g_pd3dDevice = NULL;    //Direct3D设备对象
LPDIRECT3DVERTEXBUFFER9 g_pVB_Index  = NULL;    //顶点缓冲区对象
LPDIRECT3DINDEXBUFFER9  g_pIB_Index  = NULL;
LPDIRECT3DVERTEXBUFFER9 g_pVB        
= NULL;    //顶点缓冲区对象
LPDIRECT3DINDEXBUFFER9  g_pIB        = NULL;
//-----------------------------------------------------------------------------
// Desc: 顶点结构
//-----------------------------------------------------------------------------
struct CUSTOMVERTEX
{
    FLOAT x, y, z;    
//顶点位置  
    DWORD diffuse;

//public:
//    CUSTOMVERTEX():diffuse(0xffffffff){}
};
#define D3DFVF_CUSTOMVERTEX   (D3DFVF_XYZ|D3DFVF_DIFFUSE)


const int g_edgeVertexCnts = 101;  //每边顶点数目
CUSTOMVERTEX *g_pVertex_Index;     //顶点
int *g_pIndexes_Index;             //索引

CUSTOMVERTEX 
*g_pVertex;           //顶点
//-----------------------------------------------------------------------------
// Desc: 渲染类型
//-----------------------------------------------------------------------------
enum Draw_Prim_Type
{
    DPT_INDEX 
= 0,//drawindexedprimitive
    DPT_INDEX_UP, //drawindexedprimitiveup
    DPT_PRIM,     //drawprimitive
    DPT_PRIM_UP,  //drawprimitiveup
};
Draw_Prim_Type g_kDrawType 
= DPT_INDEX;

//-----------------------------------------------------------------------------
// Desc: 设置变换矩阵
//-----------------------------------------------------------------------------
VOID SetupMatrices()
{
    D3DXMATRIX matWorld;
    D3DXMatrixIdentity(
&matWorld);
    g_pd3dDevice
->SetTransform(D3DTS_WORLD,&matWorld);

    D3DXMATRIX matView;
    D3DXVECTOR3 vecEyeat(
0,100,-100);
    D3DXVECTOR3 vecLookat(
0,0,10);
    D3DXVECTOR3 vecUp(
0,1,0);
    D3DXMatrixLookAtLH(
&matView, &vecEyeat, &vecLookat, &vecUp);
    g_pd3dDevice
->SetTransform(D3DTS_VIEW, &matView);

    D3DXMATRIX matProj;
    D3DXMatrixPerspectiveFovLH(
&matProj, D3DX_PI/24.0f/3.0f1.0f1000.0f);
    g_pd3dDevice
->SetTransform(D3DTS_PROJECTION, &matProj);
}


//-----------------------------------------------------------------------------
// Desc: 初始化Direct3D
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
    
//创建d3d对象
    g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);

    
//初始化设置参数
    D3DPRESENT_PARAMETERS parm;
    ZeroMemory(
&parm, sizeof(D3DPRESENT_PARAMETERS));
    parm.BackBufferWidth 
= 800;
    parm.BackBufferHeight 
= 600;
    parm.BackBufferCount 
= 2;
    parm.BackBufferFormat 
= D3DFMT_UNKNOWN;
    parm.MultiSampleType 
= D3DMULTISAMPLE_NONE;
    parm.SwapEffect 
= D3DSWAPEFFECT_DISCARD;
    parm.Windowed 
= true;
    parm.hDeviceWindow 
= hWnd;
    parm.EnableAutoDepthStencil 
= false;
    parm.PresentationInterval 
= D3DPRESENT_INTERVAL_IMMEDIATE;

    
//创建设备
    HRESULT hr = g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,hWnd,
        D3DCREATE_HARDWARE_VERTEXPROCESSING, 
&parm, &g_pd3dDevice);
    
if (FAILED(hr))
    {
        
return S_FALSE;
    }

    
//禁用light
    g_pd3dDevice->SetRenderState(D3DRS_LIGHTING, false);
    g_pd3dDevice
->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);

    SetupMatrices();

    
return S_OK;
}


//-----------------------------------------------------------------------------
// Desc: 创建场景图形
//-----------------------------------------------------------------------------
HRESULT InitGriphics()
{
    
//--------------vertex buffer for index
    const float fGridLenth = 0.10f;
    g_pVertex_Index 
= new CUSTOMVERTEX[g_edgeVertexCnts * g_edgeVertexCnts];

    
for (int j = 0; j < g_edgeVertexCnts; j+=1)
    {
        
for (int i = 0; i < g_edgeVertexCnts; i+=1)
        {
            g_pVertex_Index[j 
* g_edgeVertexCnts + i].x = fGridLenth * i;
            g_pVertex_Index[j 
* g_edgeVertexCnts + i].y = 0;
            g_pVertex_Index[j 
* g_edgeVertexCnts + i].z = 0.5f*fGridLenth*(g_edgeVertexCnts-1- fGridLenth * j;
        }
    }

    HRESULT hr 
= g_pd3dDevice->CreateVertexBuffer(
        g_edgeVertexCnts 
* g_edgeVertexCnts*sizeof(CUSTOMVERTEX),
        D3DUSAGE_WRITEONLY,
//非常影响新能
        D3DFVF_CUSTOMVERTEX,
        D3DPOOL_DEFAULT,
        
&g_pVB_Index,
        NULL);
    
if (FAILED(hr))
    {
        
return S_FALSE;
    }

    
//写入数据
    void *pData;
    g_pVB_Index
->Lock(0, g_edgeVertexCnts * g_edgeVertexCnts*sizeof(CUSTOMVERTEX), (void**)&pData, D3DLOCK_DISCARD);
    memcpy(pData, g_pVertex_Index, g_edgeVertexCnts 
* g_edgeVertexCnts*sizeof(CUSTOMVERTEX));
    g_pVB_Index
->Unlock();


    
//--------------index buffer for index
    int iIndexCount = (g_edgeVertexCnts-1* (g_edgeVertexCnts-1* 6;
    g_pIndexes_Index 
= new int[iIndexCount];

    
for(int j=0;j<g_edgeVertexCnts-1;j+=1)
    {
        
for(int i=0;i<g_edgeVertexCnts-1;i+=1)
        {
            g_pIndexes_Index[j
*(g_edgeVertexCnts-1)*6+i*6+0=(int)(j*g_edgeVertexCnts+i);
            g_pIndexes_Index[j
*(g_edgeVertexCnts-1)*6+i*6+1=(int)(j*g_edgeVertexCnts+i+g_edgeVertexCnts+1);
            g_pIndexes_Index[j
*(g_edgeVertexCnts-1)*6+i*6+2=(int)(j*g_edgeVertexCnts+i+g_edgeVertexCnts);
            g_pIndexes_Index[j
*(g_edgeVertexCnts-1)*6+i*6+3=(int)(j*g_edgeVertexCnts+i);
            g_pIndexes_Index[j
*(g_edgeVertexCnts-1)*6+i*6+4=(int)(j*g_edgeVertexCnts+i+1);
            g_pIndexes_Index[j
*(g_edgeVertexCnts-1)*6+i*6+5=(int)(j*g_edgeVertexCnts+i+g_edgeVertexCnts+1);
        }
    }

    g_pd3dDevice
->CreateIndexBuffer(iIndexCount*sizeof(int), 
        D3DUSAGE_WRITEONLY,
        D3DFMT_INDEX32,
        D3DPOOL_DEFAULT,
        
&g_pIB_Index,
        NULL);
    
void *pp;
    
if(FAILED(g_pIB_Index->Lock(0, iIndexCount*sizeof(int), (void**)&pp, 0)))
    {
        
//add code
        return S_FALSE;
    }
    memcpy(pp, g_pIndexes_Index, iIndexCount
*sizeof(int));
    g_pIB_Index
->Unlock();

    
//--------------vertex buffer
    int prim_list_vertex_cnts = (g_edgeVertexCnts-1)*(g_edgeVertexCnts-1)*6;
    g_pVertex 
= new CUSTOMVERTEX[prim_list_vertex_cnts];

    
for (int j = 0; j < g_edgeVertexCnts-1; j+=1)
    {
        
for (int i = 0; i < g_edgeVertexCnts-1; i+=1)
        {
            g_pVertex[j
*(g_edgeVertexCnts-1)*6+i*6+0].x = i*fGridLenth;
            g_pVertex[j
*(g_edgeVertexCnts-1)*6+i*6+0].y = 0;
            g_pVertex[j
*(g_edgeVertexCnts-1)*6+i*6+0].z = 0.5f*fGridLenth*(g_edgeVertexCnts-1)-j*fGridLenth;
            g_pVertex[j
*(g_edgeVertexCnts-1)*6+i*6+1].x = (i+1)*fGridLenth;
            g_pVertex[j
*(g_edgeVertexCnts-1)*6+i*6+1].y = 0;
            g_pVertex[j
*(g_edgeVertexCnts-1)*6+i*6+1].z = 0.5f*fGridLenth*(g_edgeVertexCnts-1)-j*fGridLenth;
            g_pVertex[j
*(g_edgeVertexCnts-1)*6+i*6+2].x = (i+1)*fGridLenth;
            g_pVertex[j
*(g_edgeVertexCnts-1)*6+i*6+2].y = 0;
            g_pVertex[j
*(g_edgeVertexCnts-1)*6+i*6+2].z = 0.5f*fGridLenth*(g_edgeVertexCnts-1)-(j+1)*fGridLenth;
            g_pVertex[j
*(g_edgeVertexCnts-1)*6+i*6+3].x = i*fGridLenth;
            g_pVertex[j
*(g_edgeVertexCnts-1)*6+i*6+3].y = 0;
            g_pVertex[j
*(g_edgeVertexCnts-1)*6+i*6+3].z = 0.5f*fGridLenth*(g_edgeVertexCnts-1)-j*fGridLenth;
            g_pVertex[j
*(g_edgeVertexCnts-1)*6+i*6+4].x = (i+1)*fGridLenth;
            g_pVertex[j
*(g_edgeVertexCnts-1)*6+i*6+4].y = 0;
            g_pVertex[j
*(g_edgeVertexCnts-1)*6+i*6+4].z = 0.5f*fGridLenth*(g_edgeVertexCnts-1)-(j+1)*fGridLenth;
            g_pVertex[j
*(g_edgeVertexCnts-1)*6+i*6+5].x = i*fGridLenth;
            g_pVertex[j
*(g_edgeVertexCnts-1)*6+i*6+5].y = 0;
            g_pVertex[j
*(g_edgeVertexCnts-1)*6+i*6+5].z = 0.5f*fGridLenth*(g_edgeVertexCnts-1)-(j+1)*fGridLenth;
        }
    }

    
if( FAILED( g_pd3dDevice->CreateVertexBuffer( 
        prim_list_vertex_cnts
*sizeof(CUSTOMVERTEX),
        D3DUSAGE_WRITEONLY, 
        D3DFVF_CUSTOMVERTEX,
        D3DPOOL_DEFAULT, 
        
&g_pVB,
        NULL ) ) )
    {
        
return E_FAIL;
    }

    VOID
* pVertices;
    
if( FAILED( g_pVB->Lock( 0, prim_list_vertex_cnts*sizeof(CUSTOMVERTEX), (void**)&pVertices, 0 ) ) )
        
return E_FAIL;
    memcpy( pVertices, g_pVertex, prim_list_vertex_cnts
*sizeof(CUSTOMVERTEX) );
    g_pVB
->Unlock();

    
return S_OK;
}


//-----------------------------------------------------------------------------
// Desc: 释放创建的对象
//-----------------------------------------------------------------------------
VOID Cleanup()
{
    
//释放顶点缓冲区对象
    if( g_pVB_Index != NULL )        
        g_pVB_Index
->Release();

    
//释放Direct3D设备对象
    if( g_pd3dDevice != NULL ) 
        g_pd3dDevice
->Release();

    
//释放Direct3D对象
    if( g_pD3D != NULL )       
        g_pD3D
->Release();
}


//-----------------------------------------------------------------------------
// Desc: 渲染图形 
//-----------------------------------------------------------------------------
VOID Render()
{
    g_pd3dDevice
->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255),1,0);

    g_pd3dDevice
->BeginScene();

    g_pd3dDevice
->SetFVF(D3DFVF_CUSTOMVERTEX);

    
switch(g_kDrawType)
    {
    
case  DPT_INDEX:
        g_pd3dDevice
->SetStreamSource(0,g_pVB_Index,0,sizeof(CUSTOMVERTEX));
        g_pd3dDevice
->SetIndices(g_pIB_Index);

        g_pd3dDevice
->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 00
            g_edgeVertexCnts
*g_edgeVertexCnts, 0 ,
            (g_edgeVertexCnts
-1)*(g_edgeVertexCnts-1* 2);
        
break;

    
case  DPT_INDEX_UP:
        g_pd3dDevice
->SetStreamSource(0,g_pVB_Index,0,sizeof(CUSTOMVERTEX));
        g_pd3dDevice
->SetIndices(g_pIB_Index);

        g_pd3dDevice
->DrawIndexedPrimitiveUP(D3DPT_TRIANGLELIST, 0, g_edgeVertexCnts*g_edgeVertexCnts, 
            (g_edgeVertexCnts
-1)*(g_edgeVertexCnts-1* 2, g_pIndexes_Index,
            D3DFMT_INDEX32, g_pVertex_Index, 
sizeof(CUSTOMVERTEX));
        
break;

    
case  DPT_PRIM:
        g_pd3dDevice
->SetStreamSource(0,g_pVB,0,sizeof(CUSTOMVERTEX));

        g_pd3dDevice
->DrawPrimitive(D3DPT_TRIANGLELIST, 0, (g_edgeVertexCnts-1)*(g_edgeVertexCnts-1* 2);
        
break;

    
case  DPT_PRIM_UP:
        g_pd3dDevice
->SetStreamSource(0,g_pVB,0,sizeof(CUSTOMVERTEX));

        g_pd3dDevice
->DrawPrimitiveUP(D3DPT_TRIANGLELIST, (g_edgeVertexCnts-1)*(g_edgeVertexCnts-1* 2,
            g_pVertex, 
sizeof(CUSTOMVERTEX));
        
break;
    }

    g_pd3dDevice
->EndScene();

    g_pd3dDevice
->Present(NULL,NULL,NULL,NULL);
}


//-----------------------------------------------------------------------------
// Desc: 消息处理
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
    
switch( msg )
    {
    
case WM_DESTROY:
        Cleanup();
        PostQuitMessage( 
0 );

    
case WM_KEYDOWN:
        {
            
switch((WORD)wParam)
            {
            
case 'W':
                g_pd3dDevice
->SetRenderState(D3DRS_FILLMODE, D3DFILL_WIREFRAME);
                
break;
            
case 'S':
                g_pd3dDevice
->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
                
break;

            
case '1':
                g_kDrawType 
= DPT_INDEX;
                
break;

            
case '2':
                g_kDrawType 
= DPT_INDEX_UP;
                
break;

            
case '3':
                g_kDrawType 
= DPT_PRIM;
                
break;

            
case '4':
                g_kDrawType 
= DPT_PRIM_UP;
                
break;

            
case 'Q':
                exit(
0);
                
break;
            }
        }

        
return 0;
    }

    
return DefWindowProc( hWnd, msg, wParam, lParam );
}



//-----------------------------------------------------------------------------
// Desc: 入口函数
//-----------------------------------------------------------------------------
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{

    
//注册窗口类
    WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0L0L,
                      GetModuleHandle(NULL), NULL, NULL, NULL, NULL,
                       L
"ClassName", NULL };
    RegisterClassEx( 
&wc );

    RECT rc;
    rc.left 
= 0;
    rc.top 
= 0;
    rc.right 
= 800;
    rc.bottom 
= 600;
    AdjustWindowRect(
&rc,  WS_VISIBLE | WS_CLIPCHILDREN | WS_OVERLAPPEDWINDOW, false);
    
//创建窗口
    HWND hWnd = CreateWindow(  L"ClassName", L"纹理影射基础",
                              WS_OVERLAPPEDWINDOW, 
                              
200
                              
100
                              rc.right
-rc.left, 
                              rc.bottom
-rc.top,
                              GetDesktopWindow(), NULL, wc.hInstance, NULL );

    
//初始化Direct3D
    if( SUCCEEDED( InitD3D( hWnd ) ) )
    {
        
//创建场景图形
        if( SUCCEEDED( InitGriphics() ) )
        {
            
//显示窗口
            ShowWindow( hWnd, SW_SHOWDEFAULT );
            UpdateWindow( hWnd );

            
//进入消息循环
            MSG msg;
            ZeroMemory( 
&msg, sizeof(msg) );
            
while( msg.message!=WM_QUIT )
            {
                
if( PeekMessage( &msg, NULL, 0U0U, PM_REMOVE ) )
                {
                    TranslateMessage( 
&msg );
                    DispatchMessage( 
&msg );
                }
                
else
                {
                    Render();  
//渲染图形
                }
            }
        }
    }

    UnregisterClass(  L
"ClassName", wc.hInstance );
    
return 0;
}
原文地址:https://www.cnblogs.com/lancidie/p/1848847.html