DirectX 學習三:抽取要渲染的物體

【前置條件】:
完成第二篇的內容。

【說明】
在學DirectX SDK 9.0自帶的Sample時,總是感覺手癢,因爲代碼不是面向對象的,看起來很不爽。於是就想着自己來封裝下,同時也在一步一步的學習D3D。
在前兩篇,把D3D相關的對象抽取到了Graphics類裏,今天,打算把渲染的一些數據對象抽取出來。
【具體做法】

首先,定義一個純虛類——RenderObject

#ifndef __RENDER_OBJECT_H__
#define __RENDER_OBJECT_H__

#include <d3dx9.h>

class RenderObject
{
public:
	RenderObject(){}
	virtual ~RenderObject() {}

	virtual bool Setup(LPDIRECT3DDEVICE9 pD3dDevice) = 0;
	virtual void Render(LPDIRECT3DDEVICE9 pD3dDevice) = 0;
};

#endif // end __RENDER_OBJECT_H__

然後,寫一個Box類:

Box.h

#ifndef __BOX_H__
#define __BOX_H__

#include "RenderObject.h"
#include "Common.h"

class MyBox : public RenderObject
{
public:
	MyBox();
	~MyBox();

	bool Setup(LPDIRECT3DDEVICE9 pD3dDevice);

	void Render(LPDIRECT3DDEVICE9 pD3dDevice);

private:
	// Vertex buffer
	LPDIRECT3DVERTEXBUFFER9 m_pVertexBuffer;

	// Index buffer
	LPDIRECT3DINDEXBUFFER9 m_pIndexBuffer;

};

#endif


Box.cpp

#include "Box.h"

MyBox::MyBox()
{
	m_pVertexBuffer = NULL;
	m_pIndexBuffer = NULL;
}

MyBox::~MyBox()
{
	if( m_pVertexBuffer != NULL )
        m_pVertexBuffer->Release();
    
    if( m_pIndexBuffer != NULL )
        m_pIndexBuffer->Release();
}

bool MyBox::Setup(LPDIRECT3DDEVICE9 pD3dDevice)
{
	if( FAILED( pD3dDevice->CreateVertexBuffer(8*sizeof(CUSTOM_VERTEX), 
					D3DUSAGE_WRITEONLY, 
					D3DFVF_CUSTOMVERTEX, 
					D3DPOOL_MANAGED, 
					&m_pVertexBuffer, 
					0) ) )
		return false;
	if( FAILED( pD3dDevice->CreateIndexBuffer(36*sizeof(WORD), 
					D3DUSAGE_WRITEONLY, 
					D3DFMT_INDEX16, 
					D3DPOOL_MANAGED, 
					&m_pIndexBuffer, 
					0) ) )
		return false;

	CUSTOM_VERTEX* vertices;
	if( FAILED( m_pVertexBuffer->Lock(0, 0, (void**)&vertices, 0) ) )
		return false;

	vertices[0].position = D3DXVECTOR3(-1.0f, -1.0f, -1.0f);
	vertices[1].position = D3DXVECTOR3(-1.0f,  1.0f, -1.0f);
	vertices[2].position = D3DXVECTOR3( 1.0f,  1.0f, -1.0f);
	vertices[3].position = D3DXVECTOR3( 1.0f, -1.0f, -1.0f);
	vertices[4].position = D3DXVECTOR3(-1.0f, -1.0f,  1.0f);
	vertices[5].position = D3DXVECTOR3(-1.0f,  1.0f,  1.0f);
	vertices[6].position = D3DXVECTOR3( 1.0f,  1.0f,  1.0f);
	vertices[7].position = D3DXVECTOR3( 1.0f, -1.0f,  1.0f);

	vertices[0].color = 0xffffffff;
	vertices[1].color = 0xffffffff;
	vertices[2].color = 0xffffffff;
	vertices[3].color = 0xffffffff;
	vertices[4].color = 0xffffffff;
	vertices[5].color = 0xffffffff;
	vertices[6].color = 0xffffffff;
	vertices[7].color = 0xffffffff;

	m_pVertexBuffer->Unlock();

	WORD* indices = 0;
	if( FAILED( m_pIndexBuffer->Lock(0, 0, (void**)&indices, 0) ) )
		return false;

	indices[0] = 0; indices[1] = 1; indices[2] = 2; 
	indices[3] = 0; indices[4] = 2; indices[5] = 3; 

	indices[6] = 4; indices[7] = 6; indices[8] = 5; 
	indices[9] = 4; indices[10] = 7; indices[11] = 6; 

	indices[12] = 4; indices[13] = 5; indices[14] = 1; 
	indices[15] = 4; indices[16] = 1; indices[17] = 0; 

	indices[18] = 3; indices[19] = 2; indices[20] = 6; 
	indices[21] = 3; indices[22] = 6; indices[23] = 7; 

	indices[24] = 1; indices[25] = 5; indices[26] = 6; 
	indices[27] = 1; indices[28] = 6; indices[29] = 2;

	indices[30] = 4; indices[31] = 0; indices[32] = 3; 
	indices[33] = 4; indices[34] = 3; indices[35] = 7;  

	m_pIndexBuffer->Unlock();

	return true;
}

void MyBox::Render(LPDIRECT3DDEVICE9 pD3dDevice)
{
	pD3dDevice->SetStreamSource(0,	// 管道流水線編號
		m_pVertexBuffer, 	// 頂點緩衝區指針
		0, 					// 緩衝區的數據字節偏移
		sizeof(CUSTOM_VERTEX));	// 頂點帶寬
	pD3dDevice->SetIndices(m_pIndexBuffer);
	pD3dDevice->SetFVF( D3DFVF_CUSTOMVERTEX );
<span style="white-space:pre">	</span>pD3dDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, 8, 0, 12);
}


Common.h 裏存放的自定義頂點格式:

#ifndef __COMMON_H__
#define __COMMON_H__

// #define SHOW_HOW_TO_USE_TCI

struct CUSTOM_VERTEX
{
	D3DXVECTOR3 position; 	// The 3D position for the vertex
    //D3DXVECTOR3 normal;   // The surface normal for the vertex
	D3DCOLOR color;    // The color
	
#ifndef SHOW_HOW_TO_USE_TCI
    FLOAT tu, tv;   // The texture coordinates
#endif
};

// Our custom FVF, which describes our custom vertex structure
#ifndef SHOW_HOW_TO_USE_TCI
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1)
#else
#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)
#endif

#endif // __COMMON_H__

接下來,精簡 Graphics 類的 InitTestGeometry 方法:

m_pRenderBox = new MyBox();
if( m_pRenderBox->Setup(m_pD3dDevice); )
    return true;
return false;

在 Graphics::Render 裏,在 EndScene 之前,調用:

m_pRenderBox->Render(m_pD3dDevice);
即可。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章