您的位置:首页 > 其它

基于ID3DXSprite的2D元素绘制

2013-02-28 15:58 211 查看
D3D中的2D元素绘制主要是通过ID3DXSprite来完成的。

我们通过调用D3DXCreateSprite来完成ID3DXSprite接口对象的创建,同时使用介于Begin与End之间的Draw方法来完成D3D中2D元素的绘制。

下面,我们对IDirect3DTexture9和ID3DXSprite进行二次封装,使其接口趋于人性化,使用起来更加便捷:
/*-------------------------------------

代码清单:Texture2D.h

来自:http://www.cnblogs.com/kenkao

-------------------------------------*/

#include "D3DInit.h"

#pragma once

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 once

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游戏开发论坛一位大侠的提点 ^ ^)




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 <stdio.h>

//---通用全局变量

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;i<numPasses;i++)

{

// 开启路径

g_pD3DEffect->GetEffect()->BeginPass(i);

for(DWORD j=0;j<g_pSimpleXMesh->GetMaterialNum();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);

}

效果图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: