【DirectX 2D游戏编程基础】DirectX精灵的创建

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/shangdi712/article/details/47763273

       首先,说明一下,我的博客里的代码均为完整代码,只要环境搭建没有问题,复制代码即可运行

       工程文件下载地址:http://download.csdn.net/detail/shangdi712/9052015   使用工程代码时切记配置DirectX 环境

       怎么讲呢,突然发现,如果真的只是讲一讲,然后将完整代码贴出来,虽然有注释,但是对于初学者来说,或者是对于日后自己复习,都会产生一些困扰,所以,这次我打算先讲一讲这里面几个函数的用法,我前几篇博客也会做适当修改,以帮助大家和自己日后更好理解(原谅我是博客新手),前面Window窗口讲完了,我就直接写关于D3D的内容了,对于字符集,消息机制并没有写,这样,我之后在这篇博客之后加上这两部分,然后也会对于前面的博客做些修改,但是,如果你不理解Win32,其实只要把我Win32那篇博客里的代码复制下,在里面修改,加入D3D需要的代码即可

       好的,我们这次的任务是创建精灵,创建精灵主要分为以下几步:

      1.声明一个精灵指针 :精灵创建跟创建D3D窗口一样,也需要一个指针,用于创建精灵

LPD3DXSPRITE g_pSprite = nullptr;

      2.创建精灵,这里会用到D3D的一个内置函数D3DXCreateSprite,他需要两个参数,第一个是D3D的设备指针(见前一篇博客),第二个是精灵指针

D3DXCreateSprite(g_pDevice, &g_pSprite);
      3.加载纹理,加载纹理的时候我们需要一个纹理指针和和一个用来存储图片信息的变量如下:
LPDIRECT3DTEXTURE9 g_pTexture = nullptr;	
D3DXIMAGE_INFO imageInfo;

之后我们开始调用D3D内置的加载纹理的函数,加载纹理的函数有两个,分别如下:

        D3DXCreateTextureFromFile(
		g_pDevice,			//设备指针
		TEXT("Resources\\Textures\\carrot.png"),	//路径及文件名
		&g_pTexture			//返回的读取到的纹理的指针
		);
	D3DXCreateTextureFromFileEx(
		g_pDevice,	//设备指针
		TEXT("Resources\\Textures\\carrot.png"),//路径及文件名
		D3DX_FROM_FILE,	//图片的宽来自于文件本身
		D3DX_FROM_FILE,	//图片的高来自于文件本身
		0,				//多级渐进纹理的等级
		0,				//图片的作用
		D3DFMT_UNKNOWN,	//未知纹理格式
		D3DPOOL_MANAGED,	//受系统管理的存储空间
		D3DX_FILTER_LINEAR,	//线性纹理过滤
		D3DX_FILTER_LINEAR,	//多级渐进纹理过滤,采用线性过滤方式
		D3DCOLOR_XRGB(255,255,255),//关键色透明
		&imageInfo,		//图片详细信息存储在这个结构体中
		nullptr,		//调色板信息
		&g_pTexture		//返回的纹理指针
		);

第一个函数比较简单,第二个比较复杂,多数情况下我们都使用这个比较复杂的,因为第一个功能确实有限,仅仅就是单纯的加载图片而已,完全不能满足我们的要求

        4.绘制图片

//告诉系统,在3D的窗口中绘制2D的内容
	g_pSprite->Begin(D3DXSPRITE_ALPHABLEND);//参数告知系统,需要alpha混合的支持

	RECT srcRect;
	SetRect(&srcRect, 100, 0, 200, 85);

	//Sprite的绘制函数
	g_pSprite->Draw(
		g_pTexture,				//绘制哪张图片			
		/*&srcRect*/nullptr,	//绘制图片的哪个部分
		&D3DXVECTOR3(100,85,0),	//图片的锚点
		&D3DXVECTOR3(0,0,0),	//绘制在客户区的哪个位置
		D3DCOLOR_XRGB(255,255,255)//绘制混合色
		);
	
	g_pSprite->End();	//告诉系统,在3D的窗口中绘制2D的工作结束


           首先,我要解释下RECT 这个数据类型,这个数据类型定义的变量的作用就是,定义图片的一块矩形区域,并且由setRect这个函数赋值,这个函数有参数,第一个参数的意思是要将这些参数赋给哪个矩形区域,后四个参数的作用是,赋给矩形区域的坐标,这个坐标怎么看呢

         我们先把这四个数分成两组,前两个为左上角的点的坐标,后两个为右下角的点的坐标,一这两个点位对角线组成的矩形就是该矩形区域。我们将这个矩形区域赋给Draw函数的第二个参数,如果第二个参数给的是nullptr,则代表将这个图片全部绘制,否则的话,就只显示赋予的矩形区域范围内的部分。

         5.

        Safe_Release(g_pTexture);
	Safe_Release(g_pSprite);
	Safe_Release(g_pDevice);
	Safe_Release(g_pD3D);

Safe_Relese()是我们定义在Utility.h里的一个函数模板,用来安全释放


    


        好了,以上就是创建精灵及绘图的基本步骤,但是,道理什么事精灵呢,精灵可以看成一个存放图片的容器,精灵里可以放一张图片,也可以是多张,随你便,但是,图片必须要放到精灵里才能做操作,所有对图片的操作其实都是对精灵的操作

        接下来,按照国际惯例,我将贴出完整代码

       注意:请复制代码运行时,将D3DXCreateTextureFromFileEx这个函数的第二个参数TEXT(" ")内部的内容改为你要导入的图片的路径,最好是相对路径


Utility.h

#ifndef WIN32_PLATFORM_
#define WIN32_PLATFORM_
#include <Windows.h>
#include <mmsystem.h>
#pragma comment(lib,"Winmm.lib")
#endif


#ifndef D3D_USEFUL_
#define D3D_USEFUL_
#include <d3d9.h>
#pragma comment(lib,"d3d9.lib")

#include <d3dx9.h>
#pragma comment(lib,"d3dx9.lib")
#endif


#ifndef SAFE_DELETE_T_
#define SAFE_DELETE_T_
template<typename T>inline void Safe_Delete(T* & p)
{
	if (p){ delete p; p = nullptr; }
}

//数据类型是系统类型,系统函数分配内存
template<typename T>inline void Safe_Release(T* & p)
{
	if (p){  p->Release(); p = nullptr; }
}
#endif



WinMain.cpp

#include "Utility.h"

HWND g_hWnd = 0;
HINSTANCE g_hInstance = 0;

LRESULT CALLBACK WndProc(HWND hWnd ,UINT uMsg,
						 WPARAM wParam,LPARAM lParam);

LPDIRECT3D9 g_pD3D = nullptr;
LPDIRECT3DDEVICE9 g_pDevice = nullptr;

//纹理指针,用来存储加载到的纹理图片信息
LPDIRECT3DTEXTURE9 g_pTexture = nullptr;	
D3DXIMAGE_INFO imageInfo;

/*
	Sprite精灵的使用:
	1、声明精灵指针
	2、创建精灵
	3、加载纹理
	4、绘制图片
	5、销毁资源
*/

//	1、声明精灵指针
LPD3DXSPRITE g_pSprite = nullptr;


VOID initGame()
{
	//	2、创建精灵
	D3DXCreateSprite(g_pDevice, &g_pSprite);

	//	3、加载纹理
	//D3DXCreateTextureFromFile(
	//	g_pDevice,			//设备指针
	//	TEXT("Resources\\Textures\\carrot.png"),	//路径及文件名
	//	&g_pTexture			//返回的读取到的纹理的指针
	//	);
	ZeroMemory(&imageInfo, sizeof(imageInfo));
	D3DXCreateTextureFromFileEx(
		g_pDevice,	//设备指针
		TEXT("Resources\\Textures\\carrot.png"),//路径及文件名
		D3DX_FROM_FILE,	//图片的宽来自于文件本身
		D3DX_FROM_FILE,	//图片的高来自于文件本身
		0,				//多级渐进纹理的等级
		0,				//图片的作用
		D3DFMT_UNKNOWN,	//未知纹理格式
		D3DPOOL_MANAGED,	//受系统管理的存储空间
		D3DX_FILTER_LINEAR,	//线性纹理过滤
		D3DX_FILTER_LINEAR,	//多级渐进纹理过滤,采用线性过滤方式
		D3DCOLOR_XRGB(255,255,255),//关键色透明
		&imageInfo,		//图片详细信息存储在这个结构体中
		nullptr,		//调色板信息
		&g_pTexture		//返回的纹理指针
		);
}

VOID onInit()
{
	g_pD3D = Direct3DCreate9(D3D_SDK_VERSION);
	D3DDISPLAYMODE d3ddm;
	ZeroMemory(&d3ddm, sizeof(D3DDISPLAYMODE));
	g_pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm);

	D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory(&d3dpp, sizeof(d3dpp));
	d3dpp.BackBufferCount = 1;
	d3dpp.Windowed = true;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
		g_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &g_pDevice);

	initGame();
}
VOID onLogic(float fElapsedTime)
{

}
VOID onRender(float fElapsedTime)
{
	g_pDevice->Clear(0, nullptr, D3DCLEAR_TARGET,
		D3DCOLOR_XRGB(123, 123, 234), 1.0f, 0);
	g_pDevice->BeginScene();

	//告诉系统,在3D的窗口中绘制2D的内容
	g_pSprite->Begin(D3DXSPRITE_ALPHABLEND);//参数告知系统,需要alpha混合的支持

	static RECT srcRect;
	SetRect(&srcRect, 100, 0, 200, 85);

	//static D3DXMATRIX matWorld;
	//D3DXMatrixIdentity(&matWorld);
	//static float fAngle = 0.0f;
	//fAngle += fElapsedTime;

	//D3DXMatrixTransformation2D(
	//	&matWorld,
	//	nullptr,
	//	0.0f,
	//	&D3DXVECTOR2(0.5f, 0.5f),
	//	&D3DXVECTOR2(0, 0),
	//	fAngle,
	//	&D3DXVECTOR2(200, 200)
	//	);
	//g_pDevice->SetTransform(D3DTS_WORLD, &matWorld);
	//Sprite的绘制函数
	g_pSprite->Draw(
		g_pTexture,				//绘制哪张图片			
		/*&srcRect*/nullptr,	//绘制图片的哪个部分
		&D3DXVECTOR3(100,85,0),	//图片的锚点
		&D3DXVECTOR3(0,0,0),	//绘制在客户区的哪个位置
		D3DCOLOR_XRGB(255,255,255)//绘制混合色
		);
	
	g_pSprite->End();	//告诉系统,在3D的窗口中绘制2D的工作结束


	g_pDevice->EndScene();
	g_pDevice->Present(nullptr, nullptr, 0, nullptr);
}

VOID onDestroy()
{
	Safe_Release(g_pTexture);
	Safe_Release(g_pSprite);
	Safe_Release(g_pDevice);
	Safe_Release(g_pD3D);
}

INT WINAPI WinMain( __in HINSTANCE hInstance, 
				   __in_opt HINSTANCE hPrevInstance,
				   __in_opt LPSTR lpCmdLine, 
				   __in int nShowCmd )
{
	WNDCLASS wc;
	ZeroMemory(&wc,sizeof(wc));
	wc.cbClsExtra = NULL;
	wc.cbWndExtra = NULL;
	wc.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
	wc.hCursor = LoadCursor(0,IDC_ARROW);
	wc.hIcon = LoadIcon(0,IDI_APPLICATION);
	wc.hInstance = hInstance;
	wc.lpfnWndProc = WndProc;
	wc.lpszClassName = TEXT("Alibaba");
	wc.lpszMenuName = NULL;
	wc.style = CS_HREDRAW | CS_VREDRAW;

	RegisterClass(&wc);

	g_hWnd = CreateWindow(wc.lpszClassName,
		TEXT("D3D_FirstApp"),WS_OVERLAPPEDWINDOW,
		50,20,800,600,NULL,NULL,hInstance,NULL);

	if(g_hWnd)
	{
		g_hInstance = hInstance;
		onInit();
		ShowWindow(g_hWnd,SW_SHOWNORMAL);
		UpdateWindow(g_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
		{
			static DWORD dwTime = timeGetTime();
			DWORD dwCurrentTime = timeGetTime();
			DWORD dwElapsedTime = dwCurrentTime - dwTime;
			float fElapsedTime = dwElapsedTime * 0.001f;
			onLogic(fElapsedTime);
			onRender(fElapsedTime);
			if (dwElapsedTime < 1000 / 60)
				Sleep(1000 / 60 - dwElapsedTime);
			dwTime = dwCurrentTime;
		}
	}
	onDestroy();
	UnregisterClass(wc.lpszClassName, hInstance);
	return 0;
}

LRESULT CALLBACK WndProc(HWND hWnd ,UINT uMsg,
						 WPARAM wParam,LPARAM lParam)
{
	switch(uMsg)
	{
	case WM_KEYDOWN:
		if(wParam == VK_ESCAPE)
			DestroyWindow(hWnd);
		break;
	case WM_CLOSE:
		DestroyWindow(hWnd);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	}
	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}




猜你喜欢

转载自blog.csdn.net/shangdi712/article/details/47763273