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();
}