Direct3D轮回:基于ID3DXSprite的2D元素绘制

D3D中的2D元素绘制主要是通过ID3DXSprite来完成的。
我们通过调用D3DXCreateSprite来完成ID3DXSprite接口对象的创建,同时使用介于Begin与End之间的Draw方法来完成D3D中2D元素的绘制。
下面,我们对IDirect3DTexture9和ID3DXSprite进行二次封装,使其接口趋于人性化,使用起来更加便捷:
/*------------------------------------- 代码清单:Texture2D.h 来自:http://www.cnblogs.com/kenkao -------------------------------------*/ #include "D3DInit.h" #pragma _disibledevent=> class CTexture2D { public: CTexture2D(void); ~CTexture2D(void); public: void LoadTexture( //纹理加载 char* szFxFileName, //文件路径 UINT SizeX = D3DX_DEFAULT_NONPOW2, //X默认非2次幂尺寸 UINT SizeY = D3DX_DEFAULT_NONPOW2 //Y默认非2次幂尺寸 ); void Release() {ReleaseCOM(m_pTexture);} //释放纹理 public: UINT GetWidth() {return m_Width;} //获得纹理宽 UINT GetHight() {return m_Height;} //获得纹理高 RECT GetRect() {return m_SurRect;} //获得纹理尺寸 IDirect3DTexture9* GetTexture() {return m_pTexture;} //获得纹理指针 D3DXIMAGE_INFO GetTextureInfo() {return m_TextureInfo;} //获得纹理信息 private: IDirect3DTexture9* m_pTexture; //纹理指针 D3DXIMAGE_INFO m_TextureInfo; //纹理信息 RECT m_SurRect; //纹理尺寸 UINT m_Width; //纹理宽 UINT m_Height; //纹理高 };
/*------------------------------------- 代码清单:Texture2D.cpp 来自:http://www.cnblogs.com/kenkao -------------------------------------*/ #include "StdAfx.h" #include "Texture2D.h" #include "D3DGame.h" extern IDirect3DDevice9* g_pD3DDevice; CTexture2D::CTexture2D(void):m_pTexture(NULL) { } CTexture2D::~CTexture2D(void) { } void CTexture2D::LoadTexture(char* szFxFileName, UINT SizeX, UINT SizeY) { D3DXCreateTextureFromFileEx( g_pD3DDevice, szFxFileName, SizeX, SizeY, D3DX_FROM_FILE, D3DPOOL_DEFAULT, D3DFMT_FROM_FILE, D3DPOOL_MANAGED, D3DX_DEFAULT, D3DX_DEFAULT, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f), &m_TextureInfo, NULL, &m_pTexture); if(SizeX==(UINT)-2) m_Width = m_TextureInfo.Width; else m_Width = SizeX; if(SizeY==(UINT)-2) m_Height = m_TextureInfo.Height; else m_Height = SizeY; m_SurRect.top = 0; m_SurRect.left = 0; m_SurRect.right = m_Width; m_SurRect.bottom = m_Height; }
我们依然通过调用D3DXCreateTextureFromFileEx函数从特定的Img文件产生纹理,只不过这次通过传入特定的参数使其产生专门用于2D绘制的纹理。
大家可以看到LoadTexture中的SizeX,SizeY我给定了默认值D3DX_DEFAULT_NONPOW2,意在使所获得的纹理默认支持非二次幂尺寸;而两个值如果默认为0的话,纹理尺寸会被自动拉伸到最相近的二次幂值,这不是我们所期待的结果。
加载完毕的纹理必要信息,会被存放到一个D3DXIMAGE_INFO类型的结构体中,其定义可以参看SDK,很好理解~
/*------------------------------------- 代码清单:D3DSprite.h 来自:http://www.cnblogs.com/kenkao -------------------------------------*/ #include "Texture2D.h" #pragma _disibledevent=> class CD3DSprite { public: CD3DSprite(IDirect3DDevice9* pDevice); ~CD3DSprite(void); public: void Begin(DWORD Flags); // 开启Sprite绘制 void End(); // 结束Sprite绘制 void Draw( // 绘制Sprite CTexture2D* pTexture, // 2D纹理 const POINT& Position, // 位置 D3DCOLOR Color // 色相 ); void Draw( CTexture2D* pTexture, const POINT& Position, const RECT& SurRect, // 指定绘制纹理区域 D3DCOLOR Color ); void Draw( CTexture2D* pTexture, const POINT& Pos, const D3DXMATRIX& TransMatrix, // 变换矩阵 const RECT& SurRect, D3DCOLOR Color ); void Draw( CTexture2D* pTexture, const POINT& Pos, const POINT& Size, // 绘制尺寸 const RECT& SurRect, D3DCOLOR Color ); void Draw( CTexture2D* pTexture, const RECT& DesRect, // 指定绘制目标区域 const RECT& SurRect, D3DCOLOR Color ); void Draw( CTexture2D* pTexture, const RECT& DesRect, D3DCOLOR Color ); void Release(){ReleaseCOM(m_pSprite)}; // 释放Sprite public: ID3DXSprite* GetSprite(){return m_pSprite;} // 获得Sprite指针 private: ID3DXSprite* m_pSprite; // Sprite指针 D3DXMATRIX m_orgMatrix; // 原始矩阵 };
/*------------------------------------- 代码清单:D3DSprite.cpp 来自:http://www.cnblogs.com/kenkao -------------------------------------*/ #include "StdAfx.h" #include "D3DSprite.h" CD3DSprite::CD3DSprite(IDirect3DDevice9* pDevice) { D3DXCreateSprite(pDevice, &m_pSprite); D3DXMatrixTranslation(&m_orgMatrix,1.0f,1.0f,0.0f); } CD3DSprite::~CD3DSprite(void) { } void CD3DSprite::Begin(DWORD Flags) { m_pSprite->Begin(Flags); } void CD3DSprite::End() { m_pSprite->End(); } void CD3DSprite::Draw(CTexture2D* pTexture, const POINT& Pos, D3DCOLOR Color) { Draw(pTexture,Pos,pTexture->GetRect(),Color); } void CD3DSprite::Draw(CTexture2D* pTexture, const POINT& Pos, const RECT& SurRect, D3DCOLOR Color) { m_pSprite->Draw(pTexture->GetTexture(),&SurRect,&D3DXVECTOR3(0.0f,0.0f,0.0f),&D3DXVECTOR3(Pos.x,Pos.y,0.0f),Color); } void CD3DSprite::Draw(CTexture2D* pTexture, const POINT& Pos, const D3DXMATRIX& TransMatrix, const RECT& SurRect, D3DCOLOR Color) { // 设置缩放矩阵 m_pSprite->SetTransform(&TransMatrix); Draw(pTexture,Pos,SurRect,Color); // 还原缩放矩阵 m_pSprite->SetTransform(&m_orgMatrix); } void CD3DSprite::Draw(CTexture2D* pTexture, const POINT& Pos, const POINT& Size, const RECT& SurRect, D3DCOLOR Color) { D3DXMATRIX TransMatrix; FLOAT ScalX, ScalY; ScalX = (FLOAT)Size.x/(FLOAT)(SurRect.right-SurRect.left); ScalY = (FLOAT)Size.y/(FLOAT)(SurRect.bottom-SurRect.top); D3DXMatrixScaling(&TransMatrix,ScalX,ScalY,0.0f); Draw(pTexture,Pos,TransMatrix,SurRect,Color); } void CD3DSprite::Draw(CTexture2D* pTexture, const RECT& DesRect, const RECT& SurRect, D3DCOLOR Color) { POINT Pos; Pos.x = DesRect.left; Pos.y = DesRect.top; POINT Size; Size.x = DesRect.right - DesRect.left; Size.y = DesRect.bottom - DesRect.top; Draw(pTexture, Pos, Size, SurRect, Color); } void CD3DSprite::Draw(CTexture2D* pTexture, const RECT& DesRect, D3DCOLOR Color) { Draw(pTexture,DesRect,pTexture->GetRect(),Color); }
我们的CD3DSprite在原有ID3DXSprite基础上所做的主要工作是提供了大量的重载Draw函数,以更加人性化的参数设计提供更加便捷的函数调用。
这里值得一提的是
m_pSprite->SetTransform(&TransMatrix);
方法的调用。所传入参数就目前测试来看,只可以是缩放矩阵,平移与旋转矩阵被认定是非法的。ID3DXSprite接口对象就是通过这种方式来完成2D图像的缩放工作的。(感谢CSDN游戏开发论坛一位大侠的提点 ^ ^)
Direct3D轮回:基于ID3DXSprite的2D元素绘制Direct3D轮回:基于ID3DXSprite的2D元素绘制D3DGame.cpp /*------------------------------------- 代码清单:D3DGame.cpp 来自:http://www.cnblogs.com/kenkao -------------------------------------*/ #include "StdAfx.h" #include "D3DGame.h" #include "D3DCamera.h" #include "D3DEffect.h" #include "CoordCross.h" #include "SimpleXMesh.h" #include "Texture2D.h" #include "D3DSprite.h" #include //---通用全局变量 HINSTANCE g_hInst; HWND g_hWnd; D3DXMATRIX g_matProjection; //---D3D全局变量 IDirect3D9 *g_pD3D = NULL; IDirect3DDevice9 *g_pD3DDevice = NULL; CMouseInput *g_pMouseInput = NULL; CKeyboardInput *g_pKeyboardInput = NULL; CD3DCamera *g_pD3DCamera = NULL; CCoordCross *g_pCoordCross = NULL; CSimpleXMesh *g_pSimpleXMesh = NULL; CD3DEffect *g_pD3DEffect = NULL; CD3DSprite *g_pD3DSprite = NULL; CTexture2D *g_pTexture2D = NULL; //---HLSL全局变量句柄 D3DXHANDLE g_CurrentTechHandle = NULL; D3DXHANDLE g_matWorldViewProj = NULL; D3DXHANDLE g_matWorld = NULL; D3DXHANDLE g_vecEye = NULL; D3DXHANDLE g_vecLightDir = NULL; D3DXHANDLE g_vDiffuseColor = NULL; D3DXHANDLE g_vSpecularColor = NULL; D3DXHANDLE g_vAmbient = NULL; // HLSL特效参数设置 void GetParameters(); void SetParameters(); void Initialize(HINSTANCE hInst, HWND hWnd) { g_hInst = hInst; g_hWnd = hWnd; InitD3D(&g_pD3D, &g_pD3DDevice, g_matProjection, hWnd); g_pMouseInput = new CMouseInput; g_pMouseInput->Initialize(hInst,hWnd); g_pKeyboardInput = new CKeyboardInput; g_pKeyboardInput->Initialize(hInst,hWnd); g_pD3DCamera = new CD3DCamera; } void LoadContent() { g_pCoordCross = new CCoordCross; // 设置摄影机位置 g_pD3DCamera->SetCameraPos(D3DXVECTOR3(0.5f,0.5f,-5.0f)); g_pSimpleXMesh = new CSimpleXMesh; // 加载X网格 g_pSimpleXMesh->LoadXMesh("teapot.X"); g_pD3DEffect = new CD3DEffect; char ErrMsg[60]; // 加载fx特效 if(!g_pD3DEffect->LoadEffect("Light.fx",ErrMsg)) ::MessageBox(g_hWnd,ErrMsg,0,0); // 获得句柄 GetParameters(); g_pD3DSprite = new CD3DSprite(g_pD3DDevice); g_pTexture2D = new CTexture2D; // 加载纹理 g_pTexture2D->LoadTexture("img.jpg"); } void Update() { g_pMouseInput->GetState(); g_pKeyboardInput->GetState(); g_pD3DCamera->Update(); } void Draw() { // 参数设定 SetParameters(); g_pD3DDevice->SetTransform(D3DTS_VIEW,&g_pD3DCamera->GetViewMatrix()); POINT pos; pos.x=0; pos.y=0; g_pD3DDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_RGBA(100,149,237,255), 1.0f, 0); if(SUCCEEDED(g_pD3DDevice->BeginScene())) { g_pCoordCross->Draw(); // Sprite绘制开始 g_pD3DSprite->Begin(D3DXSPRITE_ALPHABLEND); // Sprite绘制 g_pD3DSprite->Draw(g_pTexture2D,pos,g_pTexture2D->GetRect(),D3DXCOLOR_WHITE); // Sprite绘制结束 g_pD3DSprite->End(); UINT numPasses; // 开启特效 g_pD3DEffect->BeginEffect(numPasses); for(UINT i=0;iGetEffect()->BeginPass(i); for(DWORD j=0;jGetMaterialNum();j++) { g_pSimpleXMesh->DrawXMeshSubset(j); } // 路径结束 g_pD3DEffect->GetEffect()->EndPass(); } // 特效结束 g_pD3DEffect->EndEffect(); g_pD3DDevice->EndScene(); } g_pD3DDevice->Present(NULL, NULL, NULL, NULL); } void UnloadContent() { ReleaseCOM(g_pTexture2D); ReleaseCOM(g_pD3DSprite); ReleaseCOM(g_pD3DEffect); ReleaseCOM(g_pSimpleXMesh); ReleaseCOM(g_pCoordCross); } void Dispose() { ReleaseCOM(g_pD3DCamera); ReleaseCOM(g_pKeyboardInput); ReleaseCOM(g_pMouseInput); ReleaseCOM(g_pD3DDevice); ReleaseCOM(g_pD3D); } void GetParameters() { // 获得HLSL中各个全局变量句柄 g_CurrentTechHandle = g_pD3DEffect -> GetEffect() -> GetTechniqueByName("SpecularLight"); g_matWorldViewProj = g_pD3DEffect -> GetEffect() -> GetParameterByName(0, "matWorldViewProj"); g_matWorld = g_pD3DEffect -> GetEffect() -> GetParameterByName(0, "matWorld"); g_vecEye = g_pD3DEffect -> GetEffect() -> GetParameterByName(0, "vecEye"); g_vecLightDir = g_pD3DEffect -> GetEffect() -> GetParameterByName(0, "vecLightDir"); g_vDiffuseColor = g_pD3DEffect -> GetEffect() -> GetParameterByName(0, "vDiffuseColor"); g_vSpecularColor = g_pD3DEffect -> GetEffect() -> GetParameterByName(0, "vSpecularColor"); g_vAmbient = g_pD3DEffect -> GetEffect() -> GetParameterByName(0, "vAmbient"); } void SetParameters() { // 设定当前技术 g_pD3DEffect -> GetEffect() -> SetTechnique(g_CurrentTechHandle); // 设定HLSL中的各个参数 D3DXMATRIX worldMatrix; D3DXMatrixTranslation(&worldMatrix,0.0f,0.0f,0.0f); g_pD3DEffect -> GetEffect() -> SetMatrix(g_matWorldViewProj,&(worldMatrix*g_pD3DCamera->GetViewMatrix()*g_matProjection)); g_pD3DEffect -> GetEffect() -> SetMatrix(g_matWorld,&worldMatrix); D3DXVECTOR3 cameraPos = g_pD3DCamera->GetCameraPos(); D3DXVECTOR4 vecEye = D3DXVECTOR4(cameraPos.x,cameraPos.y,cameraPos.z,0.0f); g_pD3DEffect -> GetEffect() -> SetVector(g_vecEye,&vecEye); D3DXVECTOR4 vLightDirection = D3DXVECTOR4(0.0f, 0.0f, -1.0f, 1.0f); g_pD3DEffect -> GetEffect() -> SetVector(g_vecLightDir,&vLightDirection); D3DXVECTOR4 vColorDiffuse = D3DXVECTOR4(0.8f, 0.0f, 0.0f, 1.0f); D3DXVECTOR4 vColorSpecular = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f); D3DXVECTOR4 vColorAmbient = D3DXVECTOR4(0.1f, 0.1f, 0.1f, 1.0f); g_pD3DEffect -> GetEffect() -> SetVector(g_vDiffuseColor,&vColorDiffuse); g_pD3DEffect -> GetEffect() -> SetVector(g_vSpecularColor,&vColorSpecular); g_pD3DEffect -> GetEffect() -> SetVector(g_vAmbient,&vColorAmbient); }
效果图:
Direct3D轮回:基于ID3DXSprite的2D元素绘制
Tags: 

延伸阅读

最新评论

发表评论