DXUT中增加自定义按钮控件

DXUT中增加自定义按钮控件

作者:kagula

日期:2009-3-27

环境:[1]Microsoft DirectX SDK (November 2008)

[2]WindowsSDK_6.0.6001.18000.367

[3] Visual Studio 2005 with C

读者对象:

[1]能够看懂DirectX SDK包中 Custom UI 这个例子程序,并能根据这个例子熟练使用DXUT中提供的控件。

[2]熟悉C++语言

关键字:

DirectX DXUT Button

内容简介:

在同一个资源管理器中,如何包含多种自定义风格按钮控件。

正文:

我们知道所有的Dialog由资源管理器(CDXUTDialogResourceManager类的实例)管理,所有的Dialog需要从资料管理器里注册(Init),所有的控件要在Dialog里添加(例如AddButton方法)

这里我们通过重载CDXUTDialog,建立CDXUTDialog。因为我们需要通过它来载入纹理资源。纹理可以是JPG格式,也可以是DDS格式。

为了正确Render我们的按钮控件。我们对CDXUTButton也进行了重载,建立了CDXUTButton2

下面以一个例子来说明如何使用CDXUTDialog2CDXUTButton2

第一步:参考本文的附件,在你的工程中建立DXUTGUI2.HDXUTGUI2.CPP文件。

第二步:引入下面的头文件

#include "DXUT.h"

#include "DXUTgui2.h"

第三步:

建立CDXUTDialog实例,取名为m_SampleUI是因为它的作用同Custom UI这个例子中的相同变量。

CDXUTDialog2 m_SampleUI; // dialog for sample specific controls

第四步:

利用资源管理器初始化m_SampleUI中要使用到的纹理资源

std::vector<LPCWSTR> vectorFN;

//压入,按钮纹理,这里为平方像素大小,DXUT会为你自动拉伸,

//这个值,你可以配合CDXUTGUI2.cpp中的源代码,进行修改。

vectorFN.push_back(L"button.jpg");

//压入,按钮纹理。下面的dds格式纹理,带AlphaChannel

//可以帮助你Render圆角按钮。

vectorFN.push_back(L"button2.dds");

m_SampleUI.Init( &m_DialogResourceManager ,vectorFN); //初始化

m_SampleUI.SetCallback( ::OnGUIEvent ); //设置GUI事件回调函数

// Font

m_SampleUI.SetFont( 1, L"Comic Sans MS", 24, FW_NORMAL );

m_SampleUI.SetFont( 2, L"Courier New", 16, FW_NORMAL );

第五步:添加按钮

// Buttons; Remark:这里的x,y,width,height暂时可以随便指定一个

int nI=100;

// 这里,省去部份代码

m_SampleUI.AddButton( IDC_PTTJSXZ, L"B1", 30, nI, 80, 35, L'4' );

nI+=50;

m_SampleUI.AddButton2( IDC_GJLSSY, L"B2", 30, nI, 80, 35, L'5' ,false,NULL,1);

m_SampleUI.AddButton2( IDC_GXLQSY, L"B3", 30, nI, 80, 35, L'6' ,false,NULL,2);

其中B1按钮,这是DXUT缺省的按钮控件Render样子。

B2按钮,是采用button.jpg纹理的按钮控件。注意它的最后一个参数为1。表示它将使用第一个压入栈的纹理文件。

B3按钮,是采用button2.dds纹理的按钮控件,dds文件带Alpha Channel可以生成任意形状的按钮控件。注意它的最后一个参数为2。表示它将使用第二个压入栈的纹理文件。

第六步:使用按钮

这里开始,使用方式同Custom UI这个例子的m_SampleUI对象变量,这里不再重复。

如何生成Jpg图像文件格式的纹理,个人认为属于常识问题,这里不展开,下面介绍如何生成dds格式的纹理。

制作DDS格式的纹理

你需要使用DirectX Texture Tool 安装完成DirectX SDK后,你可以从系统的[开始]菜单里面找到。

你需要准备二张图片,第一张图片是要显示的纹理,第二张图片,是黑白两色的图像可以有过渡,黑色代表透明色,白色代表第一张图片可以显示的区域。

具体如下:

第一步:打开DirectX Texture Tool工具软件,新建纹理(New Texture) 在我们这个例子中,设定了32平方,纹理格式为Unsigned 32-bit: A8R8G8B8

第二步:在菜单里,选中[Open Onto This Surface],打开你已经准备好的第一张图片。

第三步:在菜单里,选中(Open Onto Alpha Channel Of This Surface),打开你已经准备好的第二张图片。你可以看到由于Alpha Channel的缘故,第一张图片中的部份区域变的不可见。如果你有兴趣,可以试着用一下菜单里的[Change Background Color]选项。

第四步:保存即可。

附件:

DXUTGUI2.H

#pragma once

#ifndef DXUT_GUI2_H

#define DXUT_GUI2_H

#include "DXUTgui.h"

#include <vector>

// Minimum scroll bar thumb size

#define SCROLLBAR_MINTHUMBSIZE 8

// Delay and repeat period when clicking on the scroll bar arrows

#define SCROLLBAR_ARROWCLICK_DELAY 0.33

#define SCROLLBAR_ARROWCLICK_REPEAT 0.05

#define DXUT_NEAR_BUTTON_DEPTH 0.6f

#define DXUT_FAR_BUTTON_DEPTH 0.8f

#define DXUT_MAX_GUI_SPRITES 500

/*

这个集合的目的是,增强原DXUTButton控件的可视化效果方面的功能。

*/

//-----------------------------------------------------------------------------

// Button control

//-----------------------------------------------------------------------------

class CDXUTButton2 : public CDXUTButton

{

public:

CDXUTButton2(CDXUTDialog* pDialog):CDXUTButton( pDialog )

{

m_nStyle = 0;

}

virtual void Render( float fElapsedTime );

public:

int m_nStyle; //Get(0+m_nStyle<<1),Get(1+m_nStyle<<1);

};

//-----------------------------------------------------------------------------

// All controls must be assigned to a dialog, which handles

// input and rendering for the controls.

//-----------------------------------------------------------------------------

class CDXUTDialog2: public CDXUTDialog

{

public:

/*

功能:在这里分配,控件将要用到的D设备相关资源

*/

void Init( CDXUTDialogResourceManager* pManager, std::vector<LPCWSTR> pVector);

void Init( CDXUTDialogResourceManager* pManager )

{

CDXUTDialog::Init(pManager);

}

/*

功能:添加,自定义按钮

备注:最后一个参数,指明将要使用到的Element的编号,必须大于,而且该编号的Element已经在Init

分配。

警告:如果pVector.size()>nStyle,可能会出现不可预测后果!

*/

HRESULT AddButton2( int ID, LPCWSTR strText, int x, int y, int width, int height, UINT nHotkey=0,

bool bIsDefault=false, CDXUTButton** ppCreated=NULL, int nStyle=0 );

};

#endif

DXUTGUI2.CPP

#include "dxut.h"

#include "dxutgui2.h"

void CDXUTButton2::Render( float fElapsedTime )

{

int nOffsetX = 0;

int nOffsetY = 0;

DXUT_CONTROL_STATE iState = DXUT_STATE_NORMAL;

if( m_bVisible == false )

{

iState = DXUT_STATE_HIDDEN;

}

else if( m_bEnabled == false )

{

iState = DXUT_STATE_DISABLED;

}

else if( m_bPressed )

{

iState = DXUT_STATE_PRESSED;

nOffsetX = 1;

nOffsetY = 2;

}

else if( m_bMouseOver )

{

iState = DXUT_STATE_MOUSEOVER;

nOffsetX = -1;

nOffsetY = -2;

}

else if( m_bHasFocus )

{

iState = DXUT_STATE_FOCUS;

}

// Background fill layer

//TODO: remove magic numbers

CDXUTElement* pElement = m_Elements.GetAt( 0 + m_nStyle*2 );

float fBlendRate = ( iState == DXUT_STATE_PRESSED ) ? 0.0f : 0.8f;

RECT rcWindow = m_rcBoundingBox;

OffsetRect( &rcWindow, nOffsetX, nOffsetY );

// Blend current color

pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );

pElement->FontColor.Blend( iState, fElapsedTime, fBlendRate );

m_pDialog->DrawSprite( pElement, &rcWindow, DXUT_FAR_BUTTON_DEPTH );

m_pDialog->DrawText( m_strText, pElement, &rcWindow );

// Main button

pElement = m_Elements.GetAt( 1 + m_nStyle*2 );

// Blend current color

pElement->TextureColor.Blend( iState, fElapsedTime, fBlendRate );

pElement->FontColor.Blend( iState, fElapsedTime, fBlendRate );

m_pDialog->DrawSprite( pElement, &rcWindow, DXUT_NEAR_BUTTON_DEPTH );

m_pDialog->DrawText( m_strText, pElement, &rcWindow );

}

//--------------------------------------------------------------------------------------

void CDXUTDialog2::Init( CDXUTDialogResourceManager* pManager, std::vector<LPCWSTR> pVector)

{

CDXUTDialog::Init(pManager);

for(int i=0;i<pVector.size();i++)

{

OutputDebugString(L"CDXUTDialog2::Init() ... Button控件装载纹理,From[");

SetTexture( 1+i, pVector[i] );

OutputDebugString(pVector[i]);

OutputDebugString(L"]/n");

}

RECT rcTexture;

CDXUTElement Element;

for(int i=0;i<pVector.size();i++)

{

//-------------------------------------

// CDXUTButton - Button

//-------------------------------------

SetRect( &rcTexture, 0, 0, 32, 32 ); //位图中指定的区域,作为按钮纹理

Element.SetTexture( 1+i, &rcTexture ); //绕过第一个,因为第一个是default材质

Element.SetFont( 0 );

Element.TextureColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 150, 255, 255, 255 ); //按钮控件缺省颜色(ARGB) A为时,为最大透明度

Element.TextureColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB( 150, 255, 255, 255 ); //按钮控件点中颜色(ARGB)

Element.FontColor.States[ DXUT_STATE_MOUSEOVER ] = D3DCOLOR_ARGB( 255, 0, 0, 0 ); //鼠标悬浮在按钮控件上时,字体颜色

Element.FontColor.States[ DXUT_STATE_NORMAL ] = D3DCOLOR_ARGB( 255, 0, 0, 0 ); //缺省字体颜色

// Assign the Element

SetDefaultElement( DXUT_CONTROL_BUTTON, 2+i*2, &Element );

//-------------------------------------

// CDXUTButton - Fill layer

//-------------------------------------

SetRect( &rcTexture, 0, 0, 32, 32 );

Element.SetTexture(1+i, &rcTexture, D3DCOLOR_ARGB( 0, 255, 255, 255 ) ); //绕过第一个,因为第一个是default材质

Element.TextureColor.States[ DXUT_STATE_MOUSEOVER ] = D3DCOLOR_ARGB( 160, 255, 255, 255 );

Element.TextureColor.States[ DXUT_STATE_PRESSED ] = D3DCOLOR_ARGB( 60, 0, 0, 0 );

Element.TextureColor.States[ DXUT_STATE_FOCUS ] = D3DCOLOR_ARGB( 30, 255, 255, 255 );

// Assign the Element

SetDefaultElement( DXUT_CONTROL_BUTTON, 3+i*2, &Element );

}

}

HRESULT CDXUTDialog2::AddButton2( int ID, LPCWSTR strText, int x, int y, int width, int height, UINT nHotkey,

bool bIsDefault, CDXUTButton** ppCreated, int nStyle )

{

HRESULT hr = S_OK;

CDXUTButton2* pButton = new CDXUTButton2( this );

if( ppCreated != NULL )

*ppCreated = pButton;

if( pButton == NULL )

return E_OUTOFMEMORY;

hr = AddControl( pButton );

if( FAILED( hr ) )

return hr;

// Set the ID and list index

pButton->SetID( ID );

pButton->SetText( strText );

pButton->SetLocation( x, y );

pButton->SetSize( width, height );

pButton->SetHotkey( nHotkey );

pButton->m_bIsDefault = bIsDefault;

pButton->m_nStyle = nStyle;

return S_OK;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值