www.pudn.com > Cube8touming.rar > My3d.cpp


// My3d.cpp: implementation of the My3d class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "1Simple.h" 
#include "My3d.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
// A structure for our custom vertex type 
struct VERTEX 
{ 
    FLOAT x, y, z, rhw; // The transformed position for the vertex 
    FLOAT tu, tv; 
}; 
 
// Fixed-Function Vertex structure 
const DWORD FVF = (D3DFVF_XYZRHW | D3DFVF_TEX1); 
 
// cube vertex  
struct CUBEVERTEX 
{ 
    D3DXVECTOR3 p; 
    D3DXVECTOR3 n; 
    FLOAT       tu, tv; 
}; 
#define FILL_CUBEVERTEX( v, vertex, normal, atu, atv )  \ 
{   v.p.x = vertex.x; v.p.y = vertex.y; v.p.z = vertex.z; \ 
    v.n.x = normal.x; v.n.y = normal.y; v.n.z = normal.z; \ 
    v.tu = atu; v.tv = atv; \ 
} 
	//定义FVF用到的数据项:坐标颜色 
	#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_TEX1) 
My3d::My3d( ) 
{ 
 
} 
 
My3d::~My3d() 
{ 
 
} 
 
My3d::My3d(HWND m_hWnd) 
{i=0; 
	this->m_hWnd=m_hWnd; 
	m_nRotateY  =0;  
} 
void My3d::InitGeometry() 
{ 
    D3DXVECTOR3 p1 = D3DXVECTOR3(-1.0f, 1.0f,-1.0f); 
    D3DXVECTOR3 p2 = D3DXVECTOR3( 1.0f, 1.0f,-1.0f); 
    D3DXVECTOR3 p3 = D3DXVECTOR3( 1.0f,-1.0f,-1.0f); 
    D3DXVECTOR3 p4 = D3DXVECTOR3(-1.0f,-1.0f,-1.0f); 
    D3DXVECTOR3 p5 = D3DXVECTOR3(-1.0f, 1.0f, 1.0f); 
    D3DXVECTOR3 p6 = D3DXVECTOR3(-1.0f,-1.0f, 1.0f); 
    D3DXVECTOR3 p7 = D3DXVECTOR3( 1.0f,-1.0f, 1.0f); 
    D3DXVECTOR3 p8 = D3DXVECTOR3( 1.0f, 1.0f, 1.0f);//8个点 
 
    // Define the normals for the cube 
    D3DXVECTOR3 n0( 0.0f, 0.0f,-1.0f ); // Front face 
    D3DXVECTOR3 n1( 0.0f, 0.0f, 1.0f ); // Back face 
    D3DXVECTOR3 n2( 0.0f, 1.0f, 0.0f ); // Bottom face 
    D3DXVECTOR3 n3( 0.0f,-1.0f, 0.0f ); // Top face 
    D3DXVECTOR3 n4( 1.0f, 0.0f, 0.0f ); // Left face 
    D3DXVECTOR3 n5(-1.0f, 0.0f, 0.0f ); // Right face//6个面 
 
	// cube vertex  
  
 CUBEVERTEX vertices[24] ; //FVF顶点数据 
 
    // Front face 
    FILL_CUBEVERTEX( vertices[0], p1, n0, 0.01f, 0.01f ); 
    FILL_CUBEVERTEX( vertices[1], p2, n0, 0.99f, 0.01f ); 
    FILL_CUBEVERTEX( vertices[2], p3, n0, 0.99f, 0.99f ); 
    FILL_CUBEVERTEX( vertices[3], p4, n0, 0.01f, 0.99f ); 
 
    // Back face 
    FILL_CUBEVERTEX( vertices[4], p5, n1, 0.99f, 0.01f ); 
    FILL_CUBEVERTEX( vertices[5], p6, n1, 0.99f, 0.99f ); 
    FILL_CUBEVERTEX( vertices[6], p7, n1, 0.01f, 0.99f ); 
    FILL_CUBEVERTEX( vertices[7], p8, n1, 0.01f, 0.01f ); 
 
    // Top face 
    FILL_CUBEVERTEX( vertices[8], p5, n2, 0.01f, 0.01f ); 
    FILL_CUBEVERTEX( vertices[9], p8, n2, 0.99f, 0.01f ); 
    FILL_CUBEVERTEX( vertices[10], p2, n2, 0.99f, 0.99f ); 
    FILL_CUBEVERTEX( vertices[11], p1, n2, 0.01f, 0.99f ); 
 
    // Bottom face 
    FILL_CUBEVERTEX( vertices[12], p6, n3, 0.01f, 0.99f ); 
    FILL_CUBEVERTEX( vertices[13], p4, n3, 0.01f, 0.01f ); 
    FILL_CUBEVERTEX( vertices[14], p3, n3, 0.99f, 0.01f ); 
    FILL_CUBEVERTEX( vertices[15], p7, n3, 0.99f, 0.99f ); 
 
    // Left face 
    FILL_CUBEVERTEX( vertices[16], p2, n4, 0.01f, 0.01f ); 
    FILL_CUBEVERTEX( vertices[17], p8, n4, 0.99f, 0.01f ); 
    FILL_CUBEVERTEX( vertices[18], p7, n4, 0.99f, 0.99f ); 
    FILL_CUBEVERTEX( vertices[19], p3, n4, 0.01f, 0.99f ); 
 
    // Right face 
    FILL_CUBEVERTEX( vertices[20], p1, n5, 0.99f, 0.01f ); 
    FILL_CUBEVERTEX( vertices[21], p4, n5, 0.99f, 0.99f ); 
    FILL_CUBEVERTEX( vertices[22], p6, n5, 0.01f, 0.99f ); 
    FILL_CUBEVERTEX( vertices[23], p5, n5, 0.01f, 0.01f ); 
 
//	WORD indices[] = { 0, 2, 1, 0, 3, 2, 0, 1, 3, 1, 2, 3 }; //索引序列 
	WORD indices[] = {  0+0, 0+1, 0+2, 0+2, 0+3, 0+0,  
		                4+0, 4+1, 4+2, 4+2, 4+3, 4+0, 
					    8+0, 8+1, 8+2, 8+2, 8+3, 8+0, 
					    12+0,12+1,12+2,12+2,12+3,12+0, 
		                16+0,16+1,16+2,16+2,16+3,16+0, 
					    20+0,20+1,20+2,20+2,20+3,20+0 
 
						// 
	}; //索引序列 
//创建顶点缓存区,并获取接口IDirect3DVertexBuffer9的指针 
	m_pDevice->CreateVertexBuffer( 
	sizeof(vertices), //缓存区尺寸 
	0, D3DFVF_CUSTOMVERTEX,D3DPOOL_MANAGED, &m_pVB, NULL ); 
	//把顶点数据填入顶点缓存区 
	void* pVertices; 
	m_pVB->Lock( 0, sizeof(vertices), (void**)&pVertices, 0 ); 
	memcpy( pVertices, vertices, sizeof(vertices) ); 
	m_pVB->Unlock(); 
	//创建索引缓存区,并获取接口LPDIRECT3DINDEXBUFFER9的指针 
	m_pDevice->CreateIndexBuffer( 
	sizeof(indices), //缓存区尺寸 
	0, D3DFMT_INDEX16, //使用16 bit的索引值 
	D3DPOOL_MANAGED, &m_pIB, NULL ); 
	//把索引值填入索引缓存区 
	void *pIndices; 
	m_pIB->Lock( 0, sizeof(indices), (void**)&pIndices, 0 ); 
	memcpy( pIndices, indices, sizeof(indices) ); 
	m_pIB->Unlock(); 
} 
 
void My3d::SetupMatrices(){ 
	float angle = m_nRotateY * D3DX_PI / 180; //把旋转角换算成弧度 
	D3DXMATRIX matWorld; 
	//计算世界变换矩阵 
	::D3DXMatrixRotationY( &matWorld, angle ); 
	//把世界变换矩阵设置到渲染环境 
	m_pDevice->SetTransform( D3DTS_WORLD, &matWorld ); 
	D3DXVECTOR3 eye( 0.0f, 3.0f,-5.0f ); //观察点 
	D3DXVECTOR3 lookat( 0.0f, 0.0f, 0.0f ); //视线目标点 
	D3DXVECTOR3 up( 0.0f, 1.0f, 0.0f ); //上方向 
	D3DXMATRIX matView; 
	//计算视角变换矩阵 
	::D3DXMatrixLookAtLH( &matView, &eye, &lookat, &up ); 
	//把视角变换矩阵设置到渲染环境 
	m_pDevice->SetTransform( D3DTS_VIEW, &matView ); 
	D3DXMATRIXA16 matProj; 
	//计算透视投影变换矩阵 
	::D3DXMatrixPerspectiveFovLH( &matProj, D3DX_PI/4, 1.0f, 1.0f, 100.0f ); 
	//把投影变换矩阵设置到渲染环境 
	m_pDevice->SetTransform( D3DTS_PROJECTION, &matProj ); 
} 
void My3d::Render() 
{	m_nRotateY += 4; //每次旋转2度 
	//用指定颜色清除后备缓存区 
	m_pDevice->Clear( 
	0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, 
	D3DCOLOR_XRGB(0,0,255), //指定使用蓝色 
	1.0f, 0); 
	//Direct3D规定在渲染前必须调用方法IDirect3DDevice9::BeginScene, 
	//结束时要调用IDirect3DDevice9::EndScene。 
 
 
 
	m_pDevice->BeginScene(); 
	ShowBack(); 
	AddWenli(); 
	SetupMatrices(); //设置变换矩阵 
	//设置自定义的FVF 
	m_pDevice->SetFVF( D3DFVF_CUSTOMVERTEX ); 
	//绑定顶点缓存区至设备数据源 
	m_pDevice->SetStreamSource( 0, m_pVB, 0, sizeof(CUBEVERTEX) ); 
 
	//绑定索引缓存区 
	m_pDevice->SetIndices( m_pIB ); 
	//从索引缓存区绘制图元,参数1为图元格式,参数4为顶点数,参数6为三角形数 
	m_pDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST,  
											0, 
											0,  
											24,  // number of vertices 
                                            0,  
											36/3); // number of primitives 
 
	//绘制图元,其中参数1为图元格式,参数3为三角形数目 
	//m_pDevice->DrawPrimitive( D3DPT_TRIANGLELIST, 0, 1 ); 
	m_pDevice->EndScene(); 
	//交换当前/后备缓存区,刷新窗口 
	m_pDevice->Present(NULL, NULL, NULL,NULL); 
} 
 
 
 
void My3d::Cleanup() 
{   m_pWallTexture->Release(); 
	m_pIB->Release(); //释放索引缓存区 
	m_pVB->Release(); 
	m_pDevice->Release(); //释放设备对象 
	m_pD3D->Release(); //释放Direct3D对象 
 
} 
 
void My3d::InitD3D() 
{ 
	//创建Direct3D对象,并获取接口IDirect3D9的指针, 
	//我们将通过该指针操作Direct3D对象。 
	m_pD3D = ::Direct3DCreate9(D3D_SDK_VERSION); 
	D3DPRESENT_PARAMETERS d3dpp; 
	::ZeroMemory(&d3dpp, sizeof(d3dpp)); 
	d3dpp.Windowed = TRUE; //创建窗口模式的Direct3D程序 
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; 
	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN; 
	d3dpp.EnableAutoDepthStencil = FALSE;// 
	d3dpp.AutoDepthStencilFormat = D3DFMT_D16; //生成16 bit的Z缓存 
	//调用方法IDirect3D9::CreateDevice创建设备对象,并获取 
	//接口IDirect3DDevice9的指针,我们将通过该指针操作设备对象 
	m_pD3D->CreateDevice( 
	D3DADAPTER_DEFAULT, //使用缺省的显卡 
	D3DDEVTYPE_HAL, //指定设备类型为HAL 
	m_hWnd, //Direct3D窗口的句柄 
	D3DCREATE_SOFTWARE_VERTEXPROCESSING,//软件顶点处理 
	&d3dpp, &m_pDevice); 
InitGeometry(); 
InitWenli(); 
InitBack(); 
} 
 
void My3d::ShowBack() 
{ 
		m_pDevice->SetTexture( 0, m_pBackgroundTexture ); 
		m_pDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE ); 
		m_pDevice->SetTextureStageState( 0, D3DTSS_COLOROP,   D3DTOP_SELECTARG1 ); 
 
		// Passing an FVF to IDirect3DDevice9::SetFVF specifies a legacy FVF with stream 0. 
	    m_pDevice->SetFVF(FVF );  
		m_pDevice->SetStreamSource( 0, m_pBack, 0, sizeof(VERTEX) ); 
	    m_pDevice->DrawPrimitive (D3DPT_TRIANGLESTRIP, 0, 2); 
 
} 
 
void My3d::AddWenli() 
{ 
			m_pDevice->SetRenderState (D3DRS_ALPHABLENDENABLE, TRUE); 
		//	m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR); 
		//	m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR); 
			m_pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR); 
			m_pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO); 
			 
			m_pDevice->SetTexture( 0, m_pWallTexture);  
} 
 
void My3d::InitWenli() 
{  
	/////////////////////////////////// 
	 D3DXCreateTextureFromFile(m_pDevice, _T("wall.bmp"),&m_pWallTexture ); 
     D3DXCreateTextureFromFile(m_pDevice, _T("lake.bmp"),&m_pBackgroundTexture ); 
} 
 
void My3d::InitBack() 
{    LPDIRECT3DSURFACE9 pBackBuffer; 
    m_pDevice->GetBackBuffer( 0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuffer ); 
	D3DSURFACE_DESC m_d3dsdBackBuffer; 
    pBackBuffer->GetDesc( &m_d3dsdBackBuffer ); 
 VERTEX Vertices[] = 
    { 
		{  0.0f, (float)m_d3dsdBackBuffer.Height, 0.5f, 1.0f, -0.5f, 1.5f, }, // x, y, z, rhw, tu, tv 
		{  0.0f, 0.0f, 0.5f, 1.0f, -0.5f, -0.5f, }, 
		{  (float)m_d3dsdBackBuffer.Width, (float)m_d3dsdBackBuffer.Height, 0.5f, 1.0f, 1.5f,1.5f, }, 
		{  (float)m_d3dsdBackBuffer.Width, 0.0f, 0.5f, 1.0f, 1.5f,-0.5f, }, 
    }; 
 
	int m_dwSizeofVertices = sizeof(Vertices); 
 
	// sixth parameter is new in DX9 
	// Create a square for rendering the background 
    if( FAILED( m_pDevice->CreateVertexBuffer( m_dwSizeofVertices, 
                                                  D3DUSAGE_WRITEONLY, FVF, 
                                                  D3DPOOL_MANAGED, &m_pBack, NULL ) ) ) 
        return ; 
 
    VERTEX* pVertices; 
	// the third parameter changed from BYTE** to VOID** in DX9 
    if( FAILED( m_pBack->Lock( 0, m_dwSizeofVertices, (VOID**)&pVertices, 0 ) ) ) 
        return ; 
    memcpy( pVertices, Vertices, m_dwSizeofVertices); 
    m_pBack->Unlock(); 
}