zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Dns信息收集
    Top命令--性能
    一些php常用函数积累
    样本组成了整体,特例装裱了样本
    Android OKHttp 可能你从来没用过的拦截器 【实用推荐】
    一篇文章搞懂android存储目录结构
    [ES6 系列] 你真的了解ES6吗(一)
    撸了一个简易的工具库: jeasy
    SQL基础语句(详解版)
    状态管理之 Flux、Redux、Vuex、MobX(概念篇)
  • 原文地址:https://www.cnblogs.com/lancidie/p/1848847.html
Copyright © 2011-2022 走看看