现在的位置: 首页 > 综合 > 正文

Direct3d template (camera)

2013年10月02日 ⁄ 综合 ⁄ 共 12072字 ⁄ 字号 评论关闭
#ifndef __vertexH__
#define __vertexH__

struct Vertex
{
	Vertex(){}
	Vertex(
		float x, float y, float z,
		float nx, float ny, float nz,
		float u, float v)
	{
		_x  = x;  _y  = y;  _z  = z;
		_nx = nx; _ny = ny; _nz = nz;
		_u  = u;  _v  = v;
	}
	float _x, _y, _z;
	float _nx, _ny, _nz;
	float _u, _v; // texture coordinates
};
#define FVF_VERTEX (D3DFVF_XYZ | D3DFVF_NORMAL | D3DFVF_TEX1)

#endif // __vertexH__
//=============================================================================
// Author: xujie li (C) All Rights Reserved
//=============================================================================
#pragma once
#include "stdafx.h"
#include "template.h"
//-----------------------------------------------------------------------------
// 全局变量
//-----------------------------------------------------------------------------
LPDIRECT3D9                g_pD3D       = NULL; //Direct3D对象
LPDIRECT3DDEVICE9          g_pd3dDevice = NULL; //Direct3D设备对象
LPDIRECT3DVERTEXBUFFER9    g_pVB        = NULL;    //顶点缓冲区对象
LPDIRECT3DINDEXBUFFER9     g_pIB        =NULL;     //索引缓冲区对象
LPDIRECT3DTEXTURE9         g_pTexture   = NULL;    //纹理对象
//-----------------------------------------------------------------------------
// 显示帧率
//-----------------------------------------------------------------------------
ID3DXFont* Font   = 0;
DWORD FrameCnt    = 0;
float TimeElapsed = 0;
float timeDelta   =0;
float FPS         = 0;
TCHAR TFPSString[100];
//-----------------------------------------------------------------------------
// Desc: 顶点结构
//-----------------------------------------------------------------------------

#define D3DFVF_CUSTOMVERTEX (D3DFVF_XYZ|D3DFVF_DIFFUSE)  //顶点格式

float g_fSpinX = 0.0f;
float g_fSpinY = 0.0f;
float g_fDisZ = 0.0f;
HRESULT InitGeometry()
{
	//创建纹理对象
	if( FAILED( D3DXCreateTextureFromFile( g_pd3dDevice, L"texture.jpg", &g_pTexture ) ) )
	{
		MessageBox(NULL, L"创建纹理失败", L"Texture.exe", MB_OK);
		return E_FAIL;
	}
	g_pd3dDevice->CreateVertexBuffer(
		24 * sizeof(Vertex), 
		D3DUSAGE_WRITEONLY,
		FVF_VERTEX,
		D3DPOOL_MANAGED,
		&g_pVB,
		0);

	Vertex* pVertices;
	g_pVB->Lock(0, 0, (void**)&pVertices, 0);

	// build box

	// fill in the front face vertex data
	pVertices[0] = Vertex(-1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 0.0f);
	pVertices[1] = Vertex(-1.0f,  1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 0.0f, 1.0f);
	pVertices[2] = Vertex( 1.0f,  1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 1.0f);
	pVertices[3] = Vertex( 1.0f, -1.0f, -1.0f, 0.0f, 0.0f, -1.0f, 1.0f, 0.0f);

	// fill in the back face vertex data
	pVertices[4] = Vertex(-1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
	pVertices[5] = Vertex( 1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f);
	pVertices[6] = Vertex( 1.0f,  1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f);
	pVertices[7] = Vertex(-1.0f,  1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 0.0f);

	// fill in the top face vertex data
	pVertices[8]  = Vertex(-1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f);
	pVertices[9]  = Vertex(-1.0f, 1.0f,  1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f);
	pVertices[10] = Vertex( 1.0f, 1.0f,  1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 1.0f);
	pVertices[11] = Vertex( 1.0f, 1.0f, -1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f);

	// fill in the bottom face vertex data
	pVertices[12] = Vertex(-1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f);
	pVertices[13] = Vertex( 1.0f, -1.0f, -1.0f, 0.0f, -1.0f, 0.0f, 0.0f, 1.0f);
	pVertices[14] = Vertex( 1.0f, -1.0f,  1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 1.0f);
	pVertices[15] = Vertex(-1.0f, -1.0f,  1.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f);

	// fill in the left face vertex data
	pVertices[16] = Vertex(-1.0f, -1.0f,  1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f);
	pVertices[17] = Vertex(-1.0f,  1.0f,  1.0f, -1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
	pVertices[18] = Vertex(-1.0f,  1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f);
	pVertices[19] = Vertex(-1.0f, -1.0f, -1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 0.0f);

	// fill in the right face vertex data
	pVertices[20] = Vertex( 1.0f, -1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f);
	pVertices[21] = Vertex( 1.0f,  1.0f, -1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f);
	pVertices[22] = Vertex( 1.0f,  1.0f,  1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f);
	pVertices[23] = Vertex( 1.0f, -1.0f,  1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f);

	g_pVB->Unlock();

	g_pd3dDevice->CreateIndexBuffer(
		36 * sizeof(WORD),
		D3DUSAGE_WRITEONLY,
		D3DFMT_INDEX16,
		D3DPOOL_MANAGED,
		&g_pIB,
		0);

	WORD* pIndices = 0;
	g_pIB->Lock(0, 0, (void**)&pIndices, 0);

	// fill in the front face index data
	pIndices[0] = 0; pIndices[1] = 1; pIndices[2] = 2;
	pIndices[3] = 0; pIndices[4] = 2; pIndices[5] = 3;

	// fill in the back face index data
	pIndices[6] = 4; pIndices[7]  = 5; pIndices[8]  = 6;
	pIndices[9] = 4; pIndices[10] = 6; pIndices[11] = 7;

	// fill in the top face index data
	pIndices[12] = 8; pIndices[13] =  9; pIndices[14] = 10;
	pIndices[15] = 8; pIndices[16] = 10; pIndices[17] = 11;

	// fill in the bottom face index data
	pIndices[18] = 12; pIndices[19] = 13; pIndices[20] = 14;
	pIndices[21] = 12; pIndices[22] = 14; pIndices[23] = 15;

	// fill in the left face index data
	pIndices[24] = 16; pIndices[25] = 17; pIndices[26] = 18;
	pIndices[27] = 16; pIndices[28] = 18; pIndices[29] = 19;

	// fill in the right face index data
	pIndices[30] = 20; pIndices[31] = 21; pIndices[32] = 22;
	pIndices[33] = 20; pIndices[34] = 22; pIndices[35] = 23;

	g_pIB->Unlock();
	return S_OK;
}
//-----------------------------------------------------------------------------
// Desc: 设置观察矩阵和投影矩阵
//-----------------------------------------------------------------------------
VOID SetWorldMatrix()
{
	static long curTime=0;
	static float elapsetime=0;
	elapsetime = (timeGetTime()-curTime)/1000.0f;
	curTime = timeGetTime();

	D3DXMATRIX matWorld;
	D3DXMATRIX matRotation;
	D3DXMATRIX matTranslation;
	D3DXMatrixRotationYawPitchRoll( &matRotation, D3DXToRadian(g_fSpinX), D3DXToRadian(g_fSpinY), 0.0f );
	D3DXMatrixTranslation( &matTranslation, 0.0f, 0.0f, g_fDisZ );
	matWorld = matRotation * matTranslation;
	g_pd3dDevice->SetTransform( D3DTS_WORLD, &matWorld );


}
VOID SetupViewandProjMatrices()
{
	//创建并设置观察矩阵
	D3DXVECTOR3 vEyePt( 0.0f, 0.0f, -10 );
	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.0f, 1.0f, 100.0f );
	g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &matProj );
}


void SetLight()
{

}
bool SetFont()
{
	D3DXFONT_DESC df;
	ZeroMemory(&df, sizeof(D3DXFONT_DESC));
	df.Height         = 12;    // in logical units
	df.Width          = 12;    // in logical units 
	df.Weight         = 500;   // boldness, range 0(light) - 1000(bold)
	df.Italic         = false;      
	df.CharSet        = GB2312_CHARSET;
	df.OutputPrecision   = 0;                    
	df.Quality        = 0;           
	df.PitchAndFamily = 0;           
	wcscpy(df.FaceName, L"Times New Roman"); // font style

	if(FAILED(D3DXCreateFontIndirect(g_pd3dDevice, &df, &Font)))
	{
		::MessageBox(0, L"D3DXCreateFontIndirect() - FAILED", 0, 0);
		::PostQuitMessage(0);
	}
	return true;
}
//-----------------------------------------------------------------------------
// Desc: 初始化Direct3D
//-----------------------------------------------------------------------------
HRESULT InitD3D( HWND hWnd )
{
	if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
		return E_FAIL;

	D3DDISPLAYMODE d3ddm;

	if( FAILED( g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
	{
		// TO DO: Respond to failure of GetAdapterDisplayMode
		return E_FAIL;
	}

	HRESULT hr;

	if( FAILED( hr = g_pD3D->CheckDeviceFormat( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, 
		d3ddm.Format, D3DUSAGE_DEPTHSTENCIL,
		D3DRTYPE_SURFACE, D3DFMT_D16 ) ) )
	{
		if( hr == D3DERR_NOTAVAILABLE )
			// POTENTIAL PROBLEM: We need at least a 16-bit z-buffer!
			return E_FAIL;
	}

	//
	// Do we support hardware vertex processing? if so, use it. 
	// If not, downgrade to software.
	//

	D3DCAPS9 d3dCaps;

	if( FAILED( g_pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT, 
		D3DDEVTYPE_HAL, &d3dCaps ) ) )
	{
		// TO DO: Respond to failure of GetDeviceCaps
		return E_FAIL;
	}

	DWORD dwBehaviorFlags = 0;

	if( d3dCaps.VertexProcessingCaps != 0 )
		dwBehaviorFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
	else
		dwBehaviorFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;

	//
	// Everything checks out - create a simple, windowed device.
	//

	D3DPRESENT_PARAMETERS d3dpp;
	memset(&d3dpp, 0, sizeof(d3dpp));

	d3dpp.BackBufferFormat       = d3ddm.Format;
	d3dpp.SwapEffect             = D3DSWAPEFFECT_DISCARD;
	d3dpp.Windowed               = TRUE;
	d3dpp.EnableAutoDepthStencil = TRUE;
	d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
	d3dpp.PresentationInterval   = D3DPRESENT_INTERVAL_IMMEDIATE;

	if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
		dwBehaviorFlags, &d3dpp, &g_pd3dDevice ) ) )
	{
		// TO DO: Respond to failure of CreateDevice
		return E_FAIL;
	}

	//禁用照明效果
	g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE ); 

	//设置剔出模式为不剔出任何面
	g_pd3dDevice->SetRenderState(D3DRS_CULLMODE,  D3DCULL_NONE);

	//g_pd3dDevice->SetRenderState ( D3DRS_FILLMODE, D3DFILL_WIREFRAME );
	//设置变换矩阵
	SetupViewandProjMatrices();


	SetLight();
	SetFont();
	return S_OK;
}
//-----------------------------------------------------------------------------
// Desc: 释放创建对象
//-----------------------------------------------------------------------------
VOID Cleanup()
{

	//释放纹理对象
	if( g_pTexture != NULL )
		g_pTexture->Release();

	//释放顶点缓冲区对象
	if( g_pVB != NULL )        
		g_pVB->Release();

	//释放索引缓冲区对象
	if( g_pIB != NULL )        
		g_pIB->Release();

	//释放Direct3D设备对象
	if( g_pd3dDevice != NULL) 
		g_pd3dDevice->Release();

	//释放Direct3D对象
	if( g_pD3D != NULL)
		g_pD3D->Release();
}



//-----------------------------------------------------------------------------
// Desc: 渲染图形
//-----------------------------------------------------------------------------
VOID Render(float timeDelta)
{
	FrameCnt++;

	TimeElapsed += timeDelta;

	if(TimeElapsed >= 1.0f)
	{
		char FPSString[100];
		FPS = (float)FrameCnt / TimeElapsed;
		D3DCAPS9 d3dCaps;
		g_pD3D->GetDeviceCaps( D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL, &d3dCaps );
		if( d3dCaps.VertexProcessingCaps != 0 )
			sprintf(FPSString, "D3D9 %.2ffps HAL(hw vp)", FPS);
		else
			sprintf(FPSString, "D3D9 %.2ffps REF(simulate hw vp) ", FPS);

		int nLen = strlen(FPSString) + 1;  
		FPSString[nLen] = '\0'; // mark end of string
		int nwLen = MultiByteToWideChar(CP_ACP, 0, FPSString, nLen, NULL, 0);   
		MultiByteToWideChar(CP_ACP, 0, FPSString, nLen, TFPSString, nwLen); 
		TimeElapsed = 0.0f;
		FrameCnt    = 0;
	}
	//清空后台缓冲区
	g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(45, 50, 170), 1.0f, 0 );

	
	//开始在后台缓冲区绘制图形
	if( SUCCEEDED( g_pd3dDevice->BeginScene() ) )
	{
		RECT rect = {0, 0, 600, 500};
		Font->DrawText(0,TFPSString,-1,&rect,DT_TOP | DT_LEFT, 0xffffff00);

		
		SetWorldMatrix();

		g_pd3dDevice->SetTexture( 0, g_pTexture ); //设置纹理
		g_pd3dDevice->SetStreamSource(0, g_pVB, 0, sizeof(Vertex));
		g_pd3dDevice->SetIndices(g_pIB);
		g_pd3dDevice->SetFVF(FVF_VERTEX);
		g_pd3dDevice->DrawIndexedPrimitive(D3DPT_TRIANGLELIST, 0, 0,24,0,12); 

		g_pd3dDevice->EndScene();
	}
	//将在后台缓冲区绘制的图形提交到前台缓冲区显示
	g_pd3dDevice->Present( NULL, NULL, NULL, NULL );
}

//-----------------------------------------------------------------------------
// Desc: 消息处理
//-----------------------------------------------------------------------------
LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	static POINT ptLastMousePosit;
	static POINT ptCurrentMousePosit;
	static bool bMousing;


	switch( msg )
	{
	case WM_LBUTTONDOWN:
		{
			ptLastMousePosit.x = ptCurrentMousePosit.x = LOWORD (lParam);
			ptLastMousePosit.y = ptCurrentMousePosit.y = HIWORD (lParam);
			bMousing = true;
		}
		break;

	case WM_LBUTTONUP:
		{
			bMousing = false;
		}
		break;
	
	case WM_MOUSEMOVE:
		{
			ptCurrentMousePosit.x = LOWORD (lParam);
			ptCurrentMousePosit.y = HIWORD (lParam);

			if( bMousing )
			{
				g_fSpinX -= (ptCurrentMousePosit.x - ptLastMousePosit.x);
				g_fSpinY -= (ptCurrentMousePosit.y - ptLastMousePosit.y);
			}

			ptLastMousePosit.x = ptCurrentMousePosit.x;
			ptLastMousePosit.y = ptCurrentMousePosit.y;
		}
		break;
	
	case WM_MOUSEWHEEL:
		{
			g_fDisZ +=(short)HIWORD (wParam)*0.01;
		}
		break;
	case WM_DESTROY:
		Cleanup();
		PostQuitMessage( 0 );
		return 0;
	case WM_PAINT:
		Render(timeDelta);
		ValidateRect( hWnd, NULL );
		return 0;
	}

	return DefWindowProc( hWnd, msg, wParam, lParam );
}


//-----------------------------------------------------------------------------
// Desc: 程序入口
//-----------------------------------------------------------------------------
int APIENTRY _tWinMain(HINSTANCE hInstance,
					   HINSTANCE hPrevInstance,
					   LPTSTR    lpCmdLine,
					   int       nCmdShow)
{
	WNDCLASSEX winClass;
	MSG        uMsg;

	memset(&uMsg,0,sizeof(uMsg));

	winClass.lpszClassName = L"MY_WINDOWS_CLASS";
	winClass.cbSize        = sizeof(WNDCLASSEX);
	winClass.style         = CS_HREDRAW | CS_VREDRAW;
	winClass.lpfnWndProc   = MsgProc;
	winClass.hInstance     = hInstance;
	winClass.hIcon	       = LoadIcon(hInstance, (LPCTSTR)IDI_DIRECTX_ICON);
	winClass.hIconSm	   = LoadIcon(hInstance, (LPCTSTR)IDI_DIRECTX_ICON);
	winClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
	winClass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
	winClass.lpszMenuName  = NULL;
	winClass.cbClsExtra    = 0;
	winClass.cbWndExtra    = 0;

	if( !RegisterClassEx(&winClass) )
		return E_FAIL;

	HWND hWnd = CreateWindowEx( NULL, L"MY_WINDOWS_CLASS", 
		L"Direct3D (DX9) - Initialization",
		WS_OVERLAPPEDWINDOW | WS_VISIBLE,
		0, 0, 640, 480, NULL, NULL, hInstance, NULL );

	//初始化Direct3D
	if( SUCCEEDED( InitD3D( hWnd ) ) )
	{ 
		if( SUCCEEDED(InitGeometry()))
		{
			//显示主窗口
			ShowWindow( hWnd, SW_SHOWDEFAULT );
			UpdateWindow( hWnd );

			static float lastTime = (float)timeGetTime(); 
			//进入消息循环
			MSG msg;
			ZeroMemory( &msg, sizeof(msg) );
			while( msg.message!=WM_QUIT )
			{
				if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
				{
					TranslateMessage( &msg );
					DispatchMessage( &msg );
				}
				else
				{
					float currTime  = (float)timeGetTime();
					float timeDelta = (currTime - lastTime)*0.001f;
					Render(timeDelta);  //渲染图形
					lastTime = currTime;
				}
			}
		}
	}

	UnregisterClass( L"ClassName", hInstance);
	return 0;
}

抱歉!评论已关闭.