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/2, 4.0f/3.0f, 1.0f, 1000.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, 0, 0,
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, 0L, 0L,
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, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
Render(); //渲染图形
}
}
}
}
UnregisterClass( L"ClassName", wc.hInstance );
return 0;
}
//-----------------------------------------------------------------------------
// 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/2, 4.0f/3.0f, 1.0f, 1000.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, 0, 0,
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, 0L, 0L,
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, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
Render(); //渲染图形
}
}
}
}
UnregisterClass( L"ClassName", wc.hInstance );
return 0;
}