【游戏开发】关于Direct X(一)

1.DirectX的定义

首先,我们必须了解DirectX的定义。

DirectX,(Direct eXtension,简称DX)是由微软公司创建的多媒体编程接口。由C++编程语言实现,遵循COM。被广泛使用于Microsoft Windows、Microsoft Xbox和Microsoft Xbox 360电子游戏开发,并且只能支持这些平台。最新版本为DirectX 11,创建在最新的Windows 7上。

Microsoft DirectX 是这样一组技术:它们旨在使基于Windows 的计算机成为运行和显示具有丰富多媒体元素(例如全色图形、视频、3D 动画和丰富音频)的应用程序的理想平台。

DirectX 包括安全和性能更新程序,以及许多涵盖所有技术的新功能。应用程序可以通过使用DirectX API 来访问这些新功能。

Direct X主要用于游戏开发,但其中部分用于开发其他类型的软件,包括游戏虚拟角色、网络软件、与游戏无关的图形软件。

Direct X通过和底层硬件打交道,从而获取软件的最大性能。

 

2.必要的工具和开发环境

要进行游戏的开发,我们必须拥有一套最新的DirectX SDK(软件开发包)。我们可以从微软的官方下载站进行下载然后安装,这里贴出地址,http://msdn.microsoft.com/zh-cn/directx/aa937788.aspx。当然我们还要拥有开发环境,我们选择Microsoft公司的Visual Studio 2010。

1>右键“项目”——“属性”——“配置属性”——“VC++目录”——编辑“包含目录”和“库目录“

eg:

C:\Program Files (x86)\Microsoft DirectX SDK (February 2010)\Include

C:\Program Files (x86)\Microsoft DirectX SDK (February 2010)\Lib\x86

 

2>”链接器“——”输入“——”附加依赖项“——编辑

输入:

dxerr.lib

dxguid.lib

d3dx9d.lib

d3dx10d.lib

d3d9.lib

winmm.lib

comctl32.lib

 

3.引擎设计概述

游戏引擎是一系列高级代码,我们可以以它为基础开发自己的游戏。现代的游戏引擎已经对使用他的人隐藏了底层实现的细节和规范。例如,可以在OpenGL和Direct3D的基础上开发渲染引擎,这样,引擎用户就不需要知道使用的是哪一个渲染引擎,尽管也用到了一些底层的东西。

游戏引擎包括:渲染引擎,物理引擎,声音引擎等。游戏引擎本身只是一个由更小的引擎组成的集合。游戏引擎或它涵盖的内容并没有一个精确的定义。

对于视频游戏而言,它的游戏引擎至少要包含渲染引擎和输入引擎,这是必须的,否则,就不能称其为交互式游戏。

游戏程序员和游戏引擎程序员完成的是两种不同的工作。游戏程序员只与开发游戏的游戏引擎打交道,而游戏引擎程序员要开发出其他人用于开发游戏的引擎。

 

4.游戏引擎中的几个关键系统

游戏引擎中的几个关键系统有:游戏渲染系统,输入系统,声音系统,物理系统,动画系统,人工智能(AI)系统等。

 

5. DirectX API函数

DirectX的API主要由DirectGraphics,DirectInput,DirectPlay,DirectMusic,DirectSound组成。每个API之间相互独立,负责完成DirectX内核中不同的功能。DirectX中每个API都可以通过硬件加速,这意味着这些API可以直接和运行软件的底层硬件对话。下面是各种API函数的概要解释。

 

DirectGraphics:

DirectGraphics为负责向屏幕渲染二维图形和三维图形的DirectX API,也就是众所周知的Direct3D。

 

DirectInput:

DirectInput是可以直接使用所有与计算机关联的输入设备的DirectX API。这些设备包括键盘,鼠标和游戏控制器设备。

 

DirectPlay:

DirectPlay是控制Direct中网络功能的Direct API。DirectPlay可以让应用程序对机器进行网络功能设置,从而可以通过和其他网络玩家交流。

 

DirectMusic:

DirectMusic是负责普通声音处理的DirectX API。

 

DirectSound:

DirectSound是负责高级声音处理的DirectX API。

 

6.动手写一个窗口

在Windows中使用Direct3D创建Win32窗口非常简单。要创建一个Win32窗口就必须拥有一个WinMain()函数(这不是废话是什么)。我们可以在MSDN中查到WinMain()的标准句法

//空的WinMain()函数

#include <Windows.h>
int WINAPI WinMain(HINSTANCE hInstance,
                    HINSTANCE hPrevInstanace,
	                PSTR szCmdLine,
                    int iCmdShow)
{
	return 0;
}

/*

WinMain函数包括4个参数:
1.程序实例的句柄(类似追踪定位的指针)
2.程序先前的实例
3.传递给程序的命令行参数指针
4.窗口的显示方式

*/

显示结果:一闪而过(正常现象)

 

//WinMain()函数内部创建窗口

#include <Windows.h>

//消息过程函数
LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
	switch (msg)
	{

    //销毁信息
	case WM_DESTROY:

        //让程序知道要退出
		PostQuitMessage(0);

		return 0;
		break;
	}

    //为所有信息提供默认处理机制
	return DefWindowProc(hWnd, msg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstanace,
	PSTR szCmdLine,int iCmdShow)
{
    //创建类型为WEDCLASSEX的窗口类对象
	WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0, 0, hInstance, NULL,
		NULL, NULL, NULL, "AppClass", NULL };

    //注册窗口类
	RegisterClassEx(&wc);

    //创建窗口
	HWND hWnd = CreateWindow("AppClass", "Window Title", WS_OVERLAPPEDWINDOW,
		100, 100, 640, 480, NULL, NULL, hInstance, NULL);
    
    //初始化D3D对象
    if(InitializeD3D(hWnd, false))
    {

    //在屏幕上显示该窗口 
	ShowWindow(hWnd, SW_SHOWDEFAULT);

    //更新窗口
	UpdateWindow(hWnd);

    //声明消息
	MSG msg;

    //清空消息缓存
	ZeroMemory(&msg, sizeof(msg));

    //消息循环直到退出
	while (msg.message != WM_QUIT)
	{

        //从消息队列中获取下一条消息
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
			{
                //获取消息,并将其转换成字符消息
				TranslateMessage(&msg);

                //将转换的消息发送给消息过程函数
				DispatchMessage(&msg);
			}
		else
			{    
                //渲染
				RenderScene();
			}
		}

	}

    //释放D3D对象
	Shutdown();
	
    //取消对窗口类的注册
	UnregisterClass(WINDOW_CLASS, wc.hInstance);

	return 0;
}
//初始化Direct3D

//InitializeD3D()函数的参数:1.窗口句柄  2.标识窗口是否全屏的标识符
bool InitializeD3D(HWND hWnd, bool fullscreen)
{
    //声明显卡信息变量
	D3DDISPLAYMODE displayMode;

    //Direct3DCreate9()函数:创建一个Direct3D接口对象,并返回该对象
	g_D3D = Direct3DCreate9(D3D_SDK_VERSION);

	if (g_D3D == NULL)return false;

    //GetAdapterDisplayMode()函数:返回当前显卡信息
	if (FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode)))
		return false;

    //D3DPRESENT_PARAMETERS:用于定义Direct3D窗口的显示信息
	D3DPRESENT_PARAMETERS d3dpp;

    //清空显示信息
	ZeroMemory(&d3dpp, sizeof(d3dpp));

    //是否全屏
	if (fullscreen)
	{
        //全屏非窗口
		d3dpp.Windowed = FALSE;

        //窗口宽度
		d3dpp.BackBufferWidth = 640;

        //窗口高度
		d3dpp.BackBufferHeight = 480;
	}
	else

        //窗口非全屏
		d3dpp.Windowed = TRUE;
    
    //处理交换结果
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;

    //管理缓存深度or模板缓存
	d3dpp.BackBufferFormat = displayMode.Format;
    
    //CreateDevice()函数:1.正在使用的显卡 2.设备类型 3.当前窗口 4.顶点运算类型 5.指定到一个                D3DPRESENT_PARAMETERS的结构体 6.返回设备的指针
	if (FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
		D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp,
		&g_D3DDevice)))return false;

	return true;
}
//在屏幕上绘制一个空白屏
void RenderScene()
{
    //清空后台缓存
	g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

    //开始渲染
	g_D3DDevice->BeginScene();

    //结束渲染
	g_D3DDevice->EndScene();

    //显示渲染结果
	g_D3DDevice->Present(NULL, NULL, NULL, NULL);
}
//释放所有Direct3D对象
void Shutdown()
{
    //释放Direct3D设备对象
	if (g_D3DDevice != NULL)g_D3DDevice->Release();

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

    //分别将两个对象指向空
	g_D3DDevice = NULL;
	g_D3D = NULL;
}
//完整代码如下:

#include <Windows.h>
#include <d3d9.h>

#pragma comment (lib,"d3d9.lib")
#pragma comment (lib,"d3dx9.lib")

#define WINDOW_CLASS "UGPDX"
#define WINDOW_NAME "Blank D3D Window"

bool InitializeD3D(HWND hWnd, bool fullscreen);
void RenderScene();
void Shutdown();

LPDIRECT3D9 g_D3D = NULL;
LPDIRECT3DDEVICE9 g_D3DDevice = NULL;

LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam){
	switch (msg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		return 0;
		break;
	case WM_KEYUP:
		if (wParam == VK_ESCAPE)
			PostQuitMessage(0);
		break;
	}
	return DefWindowProc(hWnd, msg, wParam, lParam);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstanace,
	PSTR szCmdLine, int iCmdShow)
{
	WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, MsgProc, 0, 0, hInstance, NULL,
		NULL, NULL, NULL, WINDOW_CLASS, NULL };
	RegisterClassEx(&wc);
	HWND hWnd = CreateWindow(WINDOW_CLASS, WINDOW_NAME, WS_OVERLAPPEDWINDOW,
		100, 100, 640, 480, NULL, NULL, hInstance, NULL);
	if (InitializeD3D(hWnd, false)){
		ShowWindow(hWnd, SW_SHOWDEFAULT);
		UpdateWindow(hWnd);
		MSG msg;
		ZeroMemory(&msg, sizeof(msg));
		while (msg.message != WM_QUIT)
		{
			if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
			else
			{
				RenderScene();
			}
		}

	}
	Shutdown();
	
	UnregisterClass(WINDOW_CLASS, wc.hInstance);

	return 0;

}

bool InitializeD3D(HWND hWnd, bool fullscreen)
{
	D3DDISPLAYMODE displayMode;
	g_D3D = Direct3DCreate9(D3D_SDK_VERSION);
	if (g_D3D == NULL)return false;
	if (FAILED(g_D3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &displayMode)))
		return false;
	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory(&d3dpp, sizeof(d3dpp));
	if (fullscreen)
	{
		d3dpp.Windowed = FALSE;
		d3dpp.BackBufferWidth = 640;
		d3dpp.BackBufferHeight = 480;
	}
	else
		d3dpp.Windowed = TRUE;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.BackBufferFormat = displayMode.Format;
	if (FAILED(g_D3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,
		D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp,
		&g_D3DDevice)))return false;
	return true;
}

void RenderScene()
{
	g_D3DDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
	g_D3DDevice->BeginScene();
	g_D3DDevice->EndScene();
	g_D3DDevice->Present(NULL, NULL, NULL, NULL);
}

void Shutdown()
{
	if (g_D3DDevice != NULL)g_D3DDevice->Release();
	if (g_D3D != NULL)g_D3D->Release();
	g_D3DDevice = NULL;
	g_D3D = NULL;
}

运行结果:

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值