基于directx9的界面库GXUI设计与实现  
日历
<2026年6月>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011
统计
  • 随笔 - 0
  • 文章 - 1
  • 评论 - 0
  • 引用 - 0

导航

常用链接

留言簿

文章分类

文章档案

搜索

  •  

最新评论

 

/Files/biyou007/GXUI_DEMO.rar

基于
Directx9的GUI框架的设计与实现

第一章 概述

GUI框架命名为GXUI,基于directx 9.0,比较类似于微软自己的DXUT, 其目标是基于directx 9.0构建一个完整界面库(包括框架、各类控件、动画效果、脚本创建支持),但不拘泥于directx,其底层绘制实现可以替换。GXUI属于天然的DirectUI。

将目标细分为以下几点:

   1. 建立框架自己的消息循环机制,实现窗体容器管理。

   2. 在第一步的基础上实现各类控件,包括button、edit、scroll、grid、chart等。

   3. 实现动画效果及一些特殊效果。

   4. 最终支持脚本创建。

目前为止,GXUI基本完成前3项目标,并在建立的过程中不断对整体框架进行回溯修改,也许最终GXUI达不到什么实用价值,毕竟已经有很多完善的、先进的、牛人所写的库存在,作者水平有限,不能与之相提并论。但我仍希望本系列文章能起到抛砖引玉的作用,毕竟还有很多新人对从头写到尾一个全新的界面库很感兴趣,但已有的很多库已经存于非常成熟的阶段,想深入具有较大难度,而本系列文章会尽量保证浅入深出,给予读者能接受的平滑度。事实上,有很多问题作者也未能解决,希望在此过程中能与读者一起学习,并提出有效的解决方案。

作者本人对win32真正的一些复杂的底层也并不了解,因此在构建GXUI的过程中,我秉承二点基本原则:

   1. 框架内部的机制完全独立,尽量避免与win32交互,而所有必须得交互都仅限于外面的壳,该壳会调用框架。

   2. 需要什么功能,再去实现该功能,因此不会一开始考虑的全全俱到。

第二章 UIUtil.h/UIUtil.cpp 

该代码段提供了各种基础工具类,基础定义,directx初始化类等,具体如下:

class UIInitDX 

{ ……

public:

bool InitD3D( HWND hWnd,

ULONG width, ULONG height,

bool windowed=true,

D3DDEVTYPE deviceType=D3DDEVTYPE_HAL );

bool ResetD3D( ULONG width, ULONG height );

}; 

该类提供directx9的初始化,InitD3D()接口的参数widthheight表示缓存面大小,最好与窗口大小保持一致,否则会失真。ResetD3D()用于窗口大小改变时改变缓存面的大小。

以下仿函数均为基础功能类:

struct GetImagePointColor;   // 未实现

struct GetWidth;

struct GetHeight;

struct GenRect;    // NULLRECT

struct GenPoint;   // NULLPOINT

struct GenSize;

struct ComparePoint;

struct CompareRect;

struct CrossRect;

void OffsetPoint;

struct IsPointInRect;

struct IsKeyDown;

下面的类为控件布局计算类:

/* 父窗口

-------------------------

| | |

|     dy1 |

| | |

| -------- |

|-dx1- |子窗口 |-dx2- |

| |   | |

| -------- |

| | |

|     dy2 |

| | |

-------------------------

*/

struct UILayoutScale

{ ……

RECT _parentRect; // 父窗体的区域

RECT _rect; // 控件相对父窗体区域

enum zoomMode // 设置时x、y分别只能设一次 

{

NO_ZOOM = 0,

MOVE_X = 1, // bit 1 dx2不变  dx1改变  控件x方向上大小不变

MOVE_Y = 2, // bit 2 dy2不变  dy1改变  控件y方向上大小不变

SIZE_X = 4, // bit 3 dx1和dx2都不变    控件x方向上大小改变

SIZE_Y = 8, // bit 4 dy1和dy2都不变    控件y方向上大小改变

SCALE_X = 16,// bit 5 dx1,dx2按比例变

SCALE_Y = 32,// bit 6 dy1,dy2按比例变

};

int _zoomModeflag; // 缩放模式

UILayoutScale( int flag=SIZE_X|SIZE_Y ); // 设置缩放模式

void CalcScale( RECT& parentRect, RECT& rect )// 初始计算 

RECT CalcNewPosRect( LONG cx, LONG cy ); // 计算新状态

};

第三章 UI2D.h/UI2D.cpp 

该代码段基于directx9实现了各种2d图形的绘制接口,具体方法为采用RHW类型顶点绘制带颜色信息不涉及灯光材质等。 实现基础2D图元线矩形椭圆图片字体,如果这些接口用其它系统的图形接口来实现,GXUI框架将实现移植。

实现的2D这些接口具体如下:

struct UI2DPoint;

struct UI2DLine;

struct UI2DRect;

struct UI2DCircle;

struct UI2DEllipse;

struct UI2DImage; 有两种实现方式,一种直接通过文件路径载入图片,另一种方式从dll中通过ID载入图片。我们将GXUI框架所用的图片资源都封入一个GUIResource.dll,使用时从dll中载入各种图片资源。

/* 框架背景图绘制助手类:

---------------------------------

| 1 |     2     | 3|

|--------------------------------

| | | |

| 7|     9 | 8|

| | | |

|--------------------------------

| 4|  5 | 6| */

class DrawFrameHelp; 提供了框架背景图的绘制,绘制的方式主要为边框不变,中心部分大小改变,载入的方式和UI2DImage一样有两种。

class UI2DFont; 提供了字体支持。

class UI2DClipRect提供了绘制时的区域剪裁功能,并支持嵌套剪裁计算。

除了以上2D图形接口外,本代码包含另一个重要功能,即动画功能的实现,其设计包括一个动画基类以及动画管理类:

动画基类为纯虚基类,任何继承类均需要实现2个纯虚函数,DrawAnimateAuto()默认为空,因为如果是控件动画,其绘制在控件的自身绘制中就完成了,而不需要单独的动画绘制。

struct UIAnimateBase

{  ……

virtual bool IsRunAnimate() = 0; // 动画是否运行

virtual bool CalcAnimate() = 0;// 计算本帧动画 是否绘制

virtual void DrawAnimateAuto() {}// 动画绘制

};

动画管理类如下,其TimerHandle()在GXUI框架的消息循环中定时处理。

class UIAnimateManage

{ ……

bool TimerHandle();  // 计时器处理 返回值决定是否刷新

void AddAnimate( UIAnimateBase* pAnimateObj );

};

一个重要的动画实例就是插入符,其动画效果表现为当edit编辑框激活时插入符将在激活的位置自动闪烁,其实现如下。

class UICaret; 该类实现为单件类。并相应的提供了4个全局函数来进行操作。

void UIShowCaret( float z, int width, int height, D3DCOLOR  rgb );

void UIHideCaret();

void UISetCaretPos( int x, int y );

void UIDrawCaret();

第四章 UI3D.h/UI3D.cpp 

本代码段封装了部分3D相关功能、最重要的绘制功能、一些公共的动画特效,分别介绍如下。

一 部分3D相关功能

struct UICube;  提供了一个旋转的3d箱子,在绘制时会自动旋转,可用来测试GXUI框架中的UI元素实现时是否会产生无用的绘制。

struct UICamera; 设置摄像头。

 框架绘制功能

extern UIContainer gUIContainerTop;

class UIRender : public UIAnimateManage

{ ……

// 自适应窗口大小变化

bool AutoAdjustSizeChange( ULONG width, ULONG height );

// 设置投影矩阵 设置可视柱体 映射到整个缓存面

bool SetPerspective( float aspect, float angle=D3DX_PI/2.f,  float zn=1, float zf=1000 );

void Render();

};

其中Render()函数实现内容如下:

窗口最小化不进行render

清除缓存表面

绘制顶级容器内gUIContainerTop所有子窗体

绘制立方体 测试用

Swap the back and front buffers.

void UIRegisterAnimate( UIAnimateBase* pAnimateObj ); 该全局函数用于注册动画。

三 公共的动画特效

公共动画特效实现包括3种模式:

击鼓特效,选中的图片变淡放大至消失,类似击鼓时的鼓面振动。

hot特效,一个图片从淡变浓。

3 cool特效,和2相反。

template<class T>

class UIAnimateEffect : public UIAnimateBase

{ ……

enum 

{ // 动画播放帧数

HIT_DRUM_FRAME = 10,

SET_HOT_FRAME = 9,

SET_COOL_FRAME = 9

};

public:

enum 

{ // 预留前100的为自定义动画

HIT_DRUM = 100,

SET_HOT,

SET_COOL

};

void PlayAnimate( int mode, int maxFrame=0 );

};

 WinShell.h/WinShell.cpp 

本代码段实现了win32窗口的封装,具体如下:

class UIWinShell

{

protected:

virtual void AddUIElements() {}

public:

int RunMessageLoop();

void SetParam( HINSTANCE hInstance, UINT iconID, UINT   iconSmID, std::string titleStr );

bool CreateWindowShell( int width=960, int height=640 );

};

其中虚函数AddUIElements()用于继承类添加UI元素,一个完整的GUI初始化调用过程如下:

UIWinShell gUIMainFrame;

gUIMainFrame.SetParam( hInstance, IDI_WSS, IDI_WSS, "tt" );

gUIMainFrame.CreateWindowShell();

UIInitDX::GetSingleton()->InitD3D( gUIMainFrame._hWnd,   gUIMainFrame.GetWidth(), gUIMainFrame.GetHeight() );

gUIMainFrame.RunMessageLoop();

第六章 UIWinBase.h/UIWinBase.cpp 

posted on 2011-12-02 02:42 浪客倩心 阅读(5769) 评论(0)  编辑 收藏 引用 所属分类: 基于directx9的界面库GXUI设计与实现

只有注册用户登录后才能发表评论。
网站导航:   博客园   博客园最新博文   博问   管理


 
Copyright © 浪客倩心 Powered by: 博客园 模板提供:沪江博客