【DirectX 2D游戏编程基础】directx 精灵绘图的应用,锚点与变换

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

        首先,工程文件链接http://download.csdn.net/detail/shangdi712/9051999 使用工程文件时候,切记配置directx环境

         其实,这个博客只介绍一个函数,就是D3DXMatrixTransformation2D,矩阵变换函数,在使用这个函数之前,我们需要先定义一个矩阵变量

D3DXMATRIX g_matWorld;

这是D3D里面定义的矩阵,用于实现图片的平移,旋转,缩放变换,而图像的锚点是什么呢,我们暂且把它认为成逻辑上的中心点,默认是在图片左上角,旋转的时候以它为中心,显示的时候,将这个点认为是图片坐标系的原点,也就是说,如果我们不设置位置的话,这个图片永远都把锚点放到最左上角,超出 的部分显示,好了,现在让我们看一下这个函数

D3DXMatrixTransformation2D(
		&g_matWorld,	//返回的矩阵
		nullptr,		//缩放的中心
		0.0f,			//影响缩放的因素
		&D3DXVECTOR2(1.0f, 1.0f),	//在X、Y方向的缩放量
		&D3DXVECTOR2(0.0f, 0.0f),	//旋转中心
		fAngle,			//旋转弧度
		&g_playerPos//平移量
		);


要使这个函数生效,我们需要调用这个函数

g_pSprite->SetTransform(&g_matWorld);

最后,我们一定要记得恢复渲染状态

D3DXMatrixIdentity(&g_matWorld);

    但是,图片的变换,跟矩阵有什么关系呢,好的

假设我们有这样一个单位矩阵,再假设我们的图片坐标为写X 和Y,我们将x 和 y竖着写,最底下给0,然后和矩阵相乘会发生什么

对,没错,这个关系恒成立,假设最底下一行变成2,2,1  会怎么样,那相乘之后就会变成  2+x  2+y 1,大家可以亲自动笔算一下,所以,接下来告诉大家结论

我们在此处画两条线,右下角负责图片平移,左下角负责图片的等比例缩放,左上角负责x轴方向和y轴方向缩放,左上角负责旋转

好了,现在我们照例,贴出完整代码


//Utility.h
#ifndef WINDOWS_USEFUL_TOOLS_
#define WINDOWS_USEFUL_TOOLS_
#include <Windows.h>
#include <MMSystem.h>
#pragma comment(lib,"Winmm.lib")
#endif

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

#ifndef SAFE_CLEANUP_
#define SAFE_CLEANUP_

//内联函数模板,参数为 T* 类型的引用
template<typename T>inline void Safe_Delete( T* & p )
{
	if(p){ delete p ; p = NULL;}
}

template<typename T>inline void Safe_Release( T* & p )
{
	if(p){ p->Release() ; p = NULL;}
}

#endif


#ifndef STL_TOOLS_
#define STL_TOOLS_
#include <vector>
using namespace std;
#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;

LPD3DXSPRITE g_pSprite = nullptr;
LPDIRECT3DTEXTURE9 g_pTexture = nullptr;
D3DXIMAGE_INFO g_ImageInfo;
	

//矩阵:用来控制图片的平移、旋转、缩放变换
D3DXMATRIX g_matWorld;		//世界坐标系下的矩阵(4x4)


LPDIRECT3DTEXTURE9 g_pCarrot = nullptr;


VOID onInitGame()
{
	D3DXCreateSprite(g_pDevice, &g_pSprite);

	ZeroMemory(&g_ImageInfo, sizeof(g_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(254,253,255),&g_ImageInfo,nullptr,&g_pTexture);

	D3DXCreateTextureFromFile(g_pDevice,
		TEXT("Resources\\Textures\\carrot.png"), &g_pCarrot);

	INT iTileWidth = g_ImageInfo.Width / 3;	 //单元格的宽(Tile:单元格)
	INT iTileHeight = g_ImageInfo.Height / 3;	 //单元格的高(Tile:单元格)

	//将矩阵置为单位矩阵
	D3DXMatrixIdentity(&g_matWorld);

}

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

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

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

	//获得一个具有变换信息的矩阵
	static float fAngle = 0.0f;
	fAngle += fElapsedTime*10;

	D3DXMatrixTransformation2D(
		&g_matWorld,	//返回的矩阵
		nullptr,		//缩放的中心
		0.0f,			//影响缩放的因素
		&D3DXVECTOR2(1.0f, 1.0f),	//在X、Y方向的缩放量
		&D3DXVECTOR2(0.0f, 0.0f),	//旋转中心
		fAngle,			//旋转弧度
		&g_playerPos//平移量
		);

	g_pSprite->SetTransform(&g_matWorld);
	g_pSprite->Draw(
		g_pTexture,
		nullptr,
		&D3DXVECTOR3(g_ImageInfo.Width / 2.0f, g_ImageInfo.Height / 2.0f, 0.0f),  //锚点
		&D3DXVECTOR3(0.0f,0.0f,0.0f),
		0xFFFFFFFF
		);

	//----恢复渲染状态----    ****************************
	D3DXMatrixIdentity(&g_matWorld);
	g_pSprite->setTransform(&g_matWorld);
	g_pSprite->End();
	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_MOUSEMOVE:
		g_playerPos.x = LOWORD(lParam);
		g_playerPos.y = HIWORD(lParam);
		break;
	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/47963509