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;

}

 

你可能感兴趣的:(DXUT中增加自定义按钮控件)