D3D描绘四边形的四种方法之DrawPrimitive、DrawIndexedPrimitive、DrawPrimitiveUP、DrawIndexedPrimitiveUP
2010-07-20 21:00
309 查看
创建描绘四边形的四种方法:(程序片段,只是简要介绍不同之处,不对之处,恳请指正)
第一种:最常用的一种:
使用D3D坐标(D3DFVF_XYZ ),通过设置矩阵,使用VB, 4个点。调用DrawPrimitive();
使用6个顶点时也可以,在render时需要使用
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 );
LPDIRECT3D9 g_pD3D = NULL;// Used to create the D3DDevice
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; // Our rendering device
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; // Buffer to hold Vertices'
LPDIRECT3DINDEXBUFFER9 g_pIB = NULL;
VOID* pVertices;
struct CUSTOMVERTEX
{
FLOAT x, y, z;
DWORD color;
};
CUSTOMVERTEX Vertices[] =
{
{ -1.0f, -1.0f, 1.f, 0xffff0000, },//左下
{ -1.0f, 1.0f, 1.f, 0xff00ff00, },//左上
{ 1.0f, -1.0f, 1.f, 0xff00ff00, },//右下
{ 1.0f, 1.0f, 1.f, 0xff00ff00, },//右上
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE)
HRESULT InitVB()
{
HRESULT hr = E_FAIL;
do
{
hr = g_pd3dDevice->CreateVetexBuffer( 4 * sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL)
;
If(E_FAIL == hr)
{ Break; }
hr = g_pVB->Lock( 0, sizeof( Vertices ), ( void** )&pVertices, 0 )
If(E_FAIL == hr)
{ Break; }
memcpy( pVertices, Vertices, sizeof( Vertices ) );
g_pVB->Unlock();
// create index buffer
#if 0
int fIB[] = {0,1,2,2,1,3,};
if (FAILED(g_pd3dDevice->CreateIndexBuffer( sizeof(fIB), D3DUSAGE_DYNAMIC, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &g_pIB, NULL)))
{ return E_FAIL; }
void *pIndexs;
if (FAILED(g_pIB->Lock(0, sizeof(fIB),&pIndexs,D3DLOCK_DISCARD)))
{ return E_FAIL; }
memcpy(pIndexs, fIB, sizeof(fIB)); g_pIB->Unlock();
#endif
}while(false)
return hr;
}
//set world view project matrix.
VOID SetupMatrices()
{ D3DXMATRIXA16 matWorld;
// Set up the rotation matrix to generate 1 full rotation (2*PI radians)
// every 1000 ms. To avoid the loss of precision inherent in very high
// floating point numbers, the system time is modulated by the rotation
// period before conversion to a radian angle.
UINT iTime = timeGetTime() % 1000;
FLOAT fAngle = iTime * ( 2.0f * D3DX_PI ) / 1000.0f;
D3DXMatrixRotationX( &matWorld, fAngle );
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
D3DXVECTOR3 vEyePt( 0.0f, 0.0f, -5.0f );
D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
D3DXMATRIXA16 matView;
D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
D3DXMATRIXA16 matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 1.778f, 1.0f, 100.0f );
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj ); }
//render
VOID Render()
{
//USE VB,don't use IB.
//use D3DFVF_XYZ FVF,it’s should call SetupMatrices() SetupMatrices();
g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ));
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
#if 0 // use VB and IB.
SetupMatrices();
g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ));
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
g_pd3dDevice->SetIndices(g_pIB);
g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0,4,0,2 );
#endif
}
第二种:使用顶点缓冲区和索引缓冲区,且使用DrawIndexedPrimitive()。
第三种:使用屏幕坐标,D3DFVF_XYZRHW,而不使用D3DFVF_XYZ。这个时候不需要使用顶点缓冲区和索引缓冲区。
在render的时候,不需要设置world、view、project矩阵。调用DrawPrimitiveUP()。
struct CUSTOMVERTEX_RHW
{
FLOAT x, y, z, rhw; // The transformed position for the vertex
DWORD color; // The vertex color }; // Initialize three Vertices for rendering a triangle
CUSTOMVERTEX_RHW Verticesrhw[] =
{
{ 50.0f, 150.0f, 0.5f, 1.0f, 0xff00ffff, },
{ 50.0f, 50.0f, 0.5f, 1.0f, 0xffff0000, },
{ 150.0f, 150.0f, 0.5f, 1.0f, 0xff00ffff, },
{ 150.0f, 50.0f, 0.5f, 1.0f, 0xff00ff00, },
};
Void render()
{
//SetupMatrices();
//g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ));
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX_RHW);
//g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
//g_pd3dDevice->SetIndices(g_pIB);
//g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0,4,0,2 );
g_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP, 2, (void*)Verticesrhw, sizeof(CUSTOMVERTEX_RHW)); }
第四种:使用屏幕坐标,D3DFVF_XYZRHW,而不使用D3DFVF_XYZ。这个时候不需要使用顶点缓冲区和索引缓冲区。
在render的时候,不需要设置world、view、project矩阵。调用DrawIndexedPrimitiveUP()。
与第三种方法相比,只是多了一个顶点索引设置。
int fIB[] = {0,1,2,2,1,3,};
Void render()
{
//SetupMatrices();
//g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ));
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX_RHW);
//g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
//g_pd3dDevice->SetIndices(g_pIB);
//g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0,4,0,2 );
g_pd3dDevice->DrawIndexedPrimitiveUP( D3DPT_TRIANGLELIST, 0, 4, 2, (void*)fIB, D3DFMT_INDEX32, (void*)Verticesrhw, sizeof(CUSTOMVERTEX_RHW));
}
第一种:最常用的一种:
使用D3D坐标(D3DFVF_XYZ ),通过设置矩阵,使用VB, 4个点。调用DrawPrimitive();
使用6个顶点时也可以,在render时需要使用
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 2 );
LPDIRECT3D9 g_pD3D = NULL;// Used to create the D3DDevice
LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; // Our rendering device
LPDIRECT3DVERTEXBUFFER9 g_pVB = NULL; // Buffer to hold Vertices'
LPDIRECT3DINDEXBUFFER9 g_pIB = NULL;
VOID* pVertices;
struct CUSTOMVERTEX
{
FLOAT x, y, z;
DWORD color;
};
CUSTOMVERTEX Vertices[] =
{
{ -1.0f, -1.0f, 1.f, 0xffff0000, },//左下
{ -1.0f, 1.0f, 1.f, 0xff00ff00, },//左上
{ 1.0f, -1.0f, 1.f, 0xff00ff00, },//右下
{ 1.0f, 1.0f, 1.f, 0xff00ff00, },//右上
};
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ | D3DFVF_DIFFUSE)
HRESULT InitVB()
{
HRESULT hr = E_FAIL;
do
{
hr = g_pd3dDevice->CreateVetexBuffer( 4 * sizeof(CUSTOMVERTEX), 0, D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT, &g_pVB, NULL)
;
If(E_FAIL == hr)
{ Break; }
hr = g_pVB->Lock( 0, sizeof( Vertices ), ( void** )&pVertices, 0 )
If(E_FAIL == hr)
{ Break; }
memcpy( pVertices, Vertices, sizeof( Vertices ) );
g_pVB->Unlock();
// create index buffer
#if 0
int fIB[] = {0,1,2,2,1,3,};
if (FAILED(g_pd3dDevice->CreateIndexBuffer( sizeof(fIB), D3DUSAGE_DYNAMIC, D3DFMT_INDEX32, D3DPOOL_DEFAULT, &g_pIB, NULL)))
{ return E_FAIL; }
void *pIndexs;
if (FAILED(g_pIB->Lock(0, sizeof(fIB),&pIndexs,D3DLOCK_DISCARD)))
{ return E_FAIL; }
memcpy(pIndexs, fIB, sizeof(fIB)); g_pIB->Unlock();
#endif
}while(false)
return hr;
}
//set world view project matrix.
VOID SetupMatrices()
{ D3DXMATRIXA16 matWorld;
// Set up the rotation matrix to generate 1 full rotation (2*PI radians)
// every 1000 ms. To avoid the loss of precision inherent in very high
// floating point numbers, the system time is modulated by the rotation
// period before conversion to a radian angle.
UINT iTime = timeGetTime() % 1000;
FLOAT fAngle = iTime * ( 2.0f * D3DX_PI ) / 1000.0f;
D3DXMatrixRotationX( &matWorld, fAngle );
g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );
D3DXVECTOR3 vEyePt( 0.0f, 0.0f, -5.0f );
D3DXVECTOR3 vLookatPt( 0.0f, 0.0f, 0.0f );
D3DXVECTOR3 vUpVec( 0.0f, 1.0f, 0.0f );
D3DXMATRIXA16 matView;
D3DXMatrixLookAtLH( &matView, &vEyePt, &vLookatPt, &vUpVec );
g_pd3dDevice->SetTransform( D3DTS_VIEW, &matView );
D3DXMATRIXA16 matProj;
D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI / 4, 1.778f, 1.0f, 100.0f );
g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj ); }
//render
VOID Render()
{
//USE VB,don't use IB.
//use D3DFVF_XYZ FVF,it’s should call SetupMatrices() SetupMatrices();
g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ));
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
#if 0 // use VB and IB.
SetupMatrices();
g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ));
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
g_pd3dDevice->SetIndices(g_pIB);
g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0,4,0,2 );
#endif
}
第二种:使用顶点缓冲区和索引缓冲区,且使用DrawIndexedPrimitive()。
第三种:使用屏幕坐标,D3DFVF_XYZRHW,而不使用D3DFVF_XYZ。这个时候不需要使用顶点缓冲区和索引缓冲区。
在render的时候,不需要设置world、view、project矩阵。调用DrawPrimitiveUP()。
struct CUSTOMVERTEX_RHW
{
FLOAT x, y, z, rhw; // The transformed position for the vertex
DWORD color; // The vertex color }; // Initialize three Vertices for rendering a triangle
CUSTOMVERTEX_RHW Verticesrhw[] =
{
{ 50.0f, 150.0f, 0.5f, 1.0f, 0xff00ffff, },
{ 50.0f, 50.0f, 0.5f, 1.0f, 0xffff0000, },
{ 150.0f, 150.0f, 0.5f, 1.0f, 0xff00ffff, },
{ 150.0f, 50.0f, 0.5f, 1.0f, 0xff00ff00, },
};
Void render()
{
//SetupMatrices();
//g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ));
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX_RHW);
//g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
//g_pd3dDevice->SetIndices(g_pIB);
//g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0,4,0,2 );
g_pd3dDevice->DrawPrimitiveUP( D3DPT_TRIANGLESTRIP, 2, (void*)Verticesrhw, sizeof(CUSTOMVERTEX_RHW)); }
第四种:使用屏幕坐标,D3DFVF_XYZRHW,而不使用D3DFVF_XYZ。这个时候不需要使用顶点缓冲区和索引缓冲区。
在render的时候,不需要设置world、view、project矩阵。调用DrawIndexedPrimitiveUP()。
与第三种方法相比,只是多了一个顶点索引设置。
int fIB[] = {0,1,2,2,1,3,};
Void render()
{
//SetupMatrices();
//g_pd3dDevice->SetStreamSource( 0, g_pVB, 0, sizeof( CUSTOMVERTEX ));
g_pd3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX_RHW);
//g_pd3dDevice->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );
//g_pd3dDevice->SetIndices(g_pIB);
//g_pd3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0,4,0,2 );
g_pd3dDevice->DrawIndexedPrimitiveUP( D3DPT_TRIANGLELIST, 0, 4, 2, (void*)fIB, D3DFMT_INDEX32, (void*)Verticesrhw, sizeof(CUSTOMVERTEX_RHW));
}
相关文章推荐
- 关于DrawIndexedPrimitiveUP这个函数
- DrawPrimitiveUP And DrawIndexedPrimitiveUP
- 硬件兼容性的陷阱,DrawIndexedPrimitiveUP的用法
- DrawIndexedPrimitiveUP这个函数
- 硬件兼容性的陷阱,DrawIndexedPrimitiveUP的用法
- DrawPrimitiveUP And DrawIndexedPrimitiveUP
- 硬件兼容性的陷阱,DrawIndexedPrimitiveUP的用法
- DrawPrimitiveUP And DrawIndexedPrimitiveUP
- 硬件兼容性的陷阱,DrawIndexedPrimitiveUP的用法
- 硬件兼容性的陷阱,DrawIndexedPrimitiveUP的用法
- 硬件兼容性的陷阱,DrawIndexedPrimitiveUP的用法
- DrawIndexedPrimitive()函数
- DrawPrimitiveUP 与 DrawPrimitive
- DrawIndexedPrimitive()
- DrawIndexedPrimitive()函数
- DrawPrimitiveUP 与 DrawPrimitive
- DrawIndexedPrimitive函数的详细解释
- DrawIndexedPrimitive和D3DXIntersect。搭配使用的问题。
- 为DrawPrimitiveUP(DrawUserPrimitive)洗冤
- 为DrawPrimitiveUP(DrawUserPrimitive)洗冤