当前位置: 首页 > 工具软件 > nebula-ui > 使用案例 >

Nebula2探秘14-nGuiServer的创建与使用

孟豪
2023-12-01

Nebula2探秘14-nGuiServer的创建与使用

happykevins文

关于nGui:
nGui是Nebula2本身集成的GUI系统。虽然Radon在mangalore中已经集成了对CEGUI的支持,但是nGui相比之下更加简单易用,而且紧密地与Nebula2结合,不存在CEGUI诸多的兼容性问题。另外其天生支持中文,所以在制作简单的游戏UI时可以考虑使用nGui系统。CEGUI是一个非常流行的开源的GUI系统,目前版本是0.5,虽然Bug很多而且不支持中文(网上已有很多的解决方案),但是其功能强大,并且CEGUI社区正在积极制作其相关工具,想要制作精美且复杂的UI系统的话可以考虑使用。在之后的教程中我会介绍在Nebula2中集成CEGUI的方法。

nGui的维护:
像一般的NebulaServers一样,nGui的创建过程大概分为3步:1.向Kernel添加ngui包;2.在kernel中创建nguiserver;3.调用nguiserver的初始化方法(Open)。另外在游戏循环中每帧都需要调用Trigger的方法以保证ngui正确处理用户输入,这需要有ninputserver的支持。最后在程序结束前要调用Close()方法以确保ngui正确释放资源。

nGui的初始化:
nGui的过程分为3步:1.设置nGui的skin。2.定制画刷列表。3.添加用户控件。其中前两个步骤Nebula2在startup.tcl中已经提供了默认的实现,用户也可以自由替换这些信息以实现自己期待的效果。添加用户控件可以通过两个途径来实现:1.通过kernelserver的new来创建。2.通过guiserver的newwindow来创建。其实他们本质上没有什么区别,guiserver也是通过kernelserver来创建的,只不过帮你维护了当前rootwindow的noh路径而已,nGui的所有控件都存放在noh的"/res/gui"下。

nGui的事件注册:
nGui的事件可以通过每个控件的SetXXCammond(cmd_name)来注册(XX为事件类型),传入参数cmd_name为脚本中对应的事件处理函数名,使用起来非常方便。

程序代码如下:

/* ************************************************************************** */
/* Nebula2-Tutorial14 */
/* UsingnGuiServer */
/* author:happykevins */
/* ************************************************************************** */

/// ----------------------------------------------------------------------------
/// +必要头文件

// nebula2includes
#include " kernel/nkernelserver.h "
#include
" kernel/nfileserver2.h "
#include
" script/ntclserver.h "
#include
" gfx2/nd3d9server.h "
#include
" gfx2/ncamera2.h "
#include
" gui/nguiserver.h "
#include
" tools/nmayacamcontrol.h "
#include
" scene/nsceneserver.h "

#include
" gui/nguiwindow.h "
#include
" gui/nguilabel.h "
#include
" gui/nguitextlabel.h "
#include
" gui/nguitextbutton.h "

#include
" ../NebulaUtils/nutildefs.h "
#include
" ../NebulaUtils/nkernelinfo.h "

/// -必要头文件
/// ----------------------------------------------------------------------------

/// ----------------------------------------------------------------------------
/// +链接库
#pragma comment(lib,"wsock32.lib")
#pragma comment(lib,"d_microtcl.lib")
#pragma comment(lib,"d_nkernel.lib")
#pragma comment(lib,"d_nnebula.lib")
#pragma comment(lib,"d_ntoollib.lib")
#pragma comment(lib,"d_ngui.lib")

#pragma comment(lib,"dxguid.lib")
#pragma comment(lib,"dxerr9.lib")
#pragma comment(lib,"d3d9.lib")
#pragma comment(lib,"d3dx9d.lib")
#pragma comment(lib,"dinput8.lib")

#pragma comment(lib,"d_ndinput8.lib")
#pragma comment(lib,"d_ndirect3d9.lib")
/// -链接库
/// ----------------------------------------------------------------------------

/// ----------------------------------------------------------------------------
/// +声明使用的Nebula2Package&Module
nNebulaUseModule(ntclserver);
nNebulaUseModule(nresource);
nNebulaUseModule(nresourceserver);
nNebulaUseModule(ninputserver);

nNebulaUseModule(nfont2);
nNebulaUseModule(nmesh2);
nNebulaUseModule(nmesharray);
nNebulaUseModule(nshader2);
nNebulaUseModule(ntexture2);
nNebulaUseModule(ngfxserver2);

nNebulaUseModule(nsceneserver);
nNebulaUseModule(nshadowserver2);
nNebulaUseModule(nscenenode);
nNebulaUseModule(ntransformnode);
nNebulaUseModule(nabstractcameranode);
nNebulaUseModule(nclippingcameranode);
nNebulaUseModule(nreflectioncameranode);

nNebulaUseModule(nvariableserver);
nNebulaUseModule(nconserver);

nNebulaUsePackage(ngui);
nNebulaUsePackage(ndirect3d9);
nNebulaUsePackage(ndinput8);
/// -声明使用的Nebula2Package&Module
/// ----------------------------------------------------------------------------
nCamera2cam;
nMayaCamControlccam;
nKernelInfoHelperks_info(NULL);
nTclServer
* tcl = NULL;
nKernelServer
* ks = NULL;
nD3D9Server
* gfx2 = NULL;
nInputServer
* input = NULL;
nSceneServer
* scene = NULL;
nGuiServer
* gui = NULL;

/// ----------------------------------------------------------------------------
/// +添加GUI控件
///
void SetupGUI()
{
const float borderSize = 0.02f ;
// createadummyrootwindow
// gui->SetRootWindowPointer(0);
nGuiWindow * userRootWindow = gui -> NewWindow( " nguiwindow " , true );
n_assert(userRootWindow);
rectanglenullRect(vector2(
0.0f , 0.0f ),vector2( 1.0f , 1.0f ));
userRootWindow
-> SetRect(nullRect);

// nGuiWindow*userRootWindow=gui->GetRootWindowPointer();

ks
-> PushCwd(userRootWindow);

// createlogolabel
nGuiLabel * rightLabel = (nGuiLabel * )ks -> New( " nguilabel " , " RightLogo " );
n_assert(rightLabel);
vector2rightLabelSize
= gui -> ComputeScreenSpaceBrushSize( " n2logo " );
rectanglerightRect;
rightRect.v0.
set ( 1.0f - rightLabelSize.x - borderSize, 1.0f - rightLabelSize.y - borderSize);
rightRect.v1.
set ( 1.0f - borderSize, 1.0f - borderSize);
rightLabel
-> SetRect(rightRect);
rightLabel
-> SetDefaultBrush( " n2logo " );
rightLabel
-> SetPressedBrush( " n2logo " );
rightLabel
-> SetHighlightBrush( " n2logo " );
rightLabel
-> OnShow();

// createahelptextlabel
nGuiTextLabel * textLabel = (nGuiTextLabel * )ks -> New( " nguitextlabel " , " HelpLabel " );
n_assert(textLabel);
textLabel
-> SetText( " Esc:系统菜单请不要点击"Har/Scn/Dis/Cha" 由于没有连接以上服务,会导致程序崩溃! " );
textLabel
-> SetFont( " GuiSmall " );
textLabel
-> SetAlignment(nGuiTextLabel::Left);
textLabel
-> SetColor(vector4( 1.0f , 1.0f , 1.0f , 1.0f ));
textLabel
-> SetClipping( false );
vector2textExtent
= textLabel -> GetTextExtent();
rectangletextRect(vector2(
0.0f , 0.0f ),textExtent);
textLabel
-> SetRect(textRect);
textLabel
-> OnShow();

// createacustombutton
nGuiTextButton * toggleBtn = (nGuiTextButton * )ks -> New( " nguitextbutton " , " ToggleBtn " );
n_assert(toggleBtn);
toggleBtn
-> SetText( " 系统菜单 " );
toggleBtn
-> SetCommand( " UIEvent_ToggleBtn " ); // 脚本中的函数名
toggleBtn -> SetFont( " GuiSmall " );
toggleBtn
-> SetAlignment(nGuiTextButton::Center);
toggleBtn
-> SetRect(rectangle(vector2( 0.0f + borderSize, 1 - 0.1f + borderSize),vector2( 0.15f - borderSize, 1.0f - borderSize)));
toggleBtn
-> SetDefaultBrush( " button_n " );
toggleBtn
-> SetPressedBrush( " button_p " );
toggleBtn
-> SetHighlightBrush( " button_h " );
toggleBtn
-> OnShow();

ks
-> PopCwd();

// setthenewuserrootwindow
gui -> SetRootWindowPointer(userRootWindow);

}
///
/// +添加GUI控件
/// ----------------------------------------------------------------------------

/// ----------------------------------------------------------------------------
/// +初始化环境,创建需要的Server
///
bool InitApp()
{
/// 创建KernelServer
ks = n_new(nKernelServer);

/// ----------------------------------------------------------------------------
/// +向KernelServer中添加Package&Module
nNebulaAddModule(ntclserver);
nNebulaAddModule(nresource);
nNebulaAddModule(nresourceserver);
nNebulaAddModule(ninputserver);

nNebulaAddModule(nfont2);
nNebulaAddModule(nmesh2);
nNebulaAddModule(nmesharray);
nNebulaAddModule(nshader2);
nNebulaAddModule(ntexture2);
nNebulaAddModule(ngfxserver2);

nNebulaAddModule(nsceneserver);
nNebulaAddModule(nshadowserver2);
nNebulaAddModule(nscenenode);
nNebulaAddModule(ntransformnode);
nNebulaAddModule(nabstractcameranode);
nNebulaAddModule(nclippingcameranode);
nNebulaAddModule(nreflectioncameranode);

nNebulaAddModule(nvariableserver);
nNebulaAddModule(nconserver);

ks
-> AddPackage(ndinput8);
ks
-> AddPackage(ngui);
ks
-> AddPackage(ndirect3d9);
/// +向KernelServer中添加Package&Module
/// ----------------------------------------------------------------------------

/// 获得FileServer设置shaders的路径
nFileServer2 * file = (nFileServer2 * )ks -> Lookup( " sys/servers/file2 " );
/// 设置系统路径
file -> SetAssign( " home " , " bin:../../ " );
file
-> SetAssign( " renderpath " , " home:datafiles/shaders " );
file
-> SetAssign( " shaders " , " renderpath:fixed " );
file
-> SetAssign( " scripts " , " home:datafiles/scripts " );

/// 创建tclserver
tcl = (nTclServer * )ks -> New( " ntclserver " , " /sys/servers/script " );
/// 创建ResourceServer
ks -> New( " nresourceserver " , " /sys/servers/resource " );
/// 创建variableserver
ks -> New( " nvariableserver " , " /sys/servers/variable " );
/// 创建guiserver(RenderPath依赖)
gui = (nGuiServer * )ks -> New( " nguiserver " , " /sys/servers/gui " );
/// 创建ConsoleServer(RenderPath依赖)
ks -> New( " nconserver " , " /sys/servers/console " );
/// 创建InputServer(GuiServer依赖)
input = (nInputServer * )ks -> New( " ndi8server " , " /sys/servers/input " );
/// 创建D3D9Server
gfx2 = (nD3D9Server * )ks -> New( " nd3d9server " , " /sys/servers/gfx " );
/// 创建sceneserver
scene = (nSceneServer * )ks -> New( " nsceneserver " , " /sys/servers/scene " );
/// 创建shadowserver
ks -> New( " nshadowserver2 " , " /sys/servers/shadow " );

/// 初始化显示模式
nDisplayMode2mode;
mode.SetXPos(
150 );
mode.SetYPos(
100 );
mode.SetWidth(
640 );
mode.SetHeight(
480 );

/// 将显示模式应用到d3d9server
gfx2 -> SetDisplayMode(mode);
gfx2
-> SetCamera(cam);

/// 启动sceneserver(启动d3d9server)
scene -> SetRenderPathFilename( " renderpath:dx7_renderpath.xml " );
if ( ! scene -> Open())
{
return false ;
}

/// 启动GUIServer
nStringret;
tcl
-> RunScript( " scripts:T14_GuiServer.tcl " ,ret);
gui
-> Open();

/// 启动InputServer
input -> Open();
ret.Clear();
tcl
-> RunFunction( " OnT14MapInput " ,ret);

/// 设置GUI环境
SetupGUI();

return true ;
}
///
/// +初始化环境,创建需要的Server
/// ----------------------------------------------------------------------------

/// ----------------------------------------------------------------------------
/// +初始化环境,创建需要的Server
///
bool CloseApp()
{
/// 关闭GUIServer
gui -> Close();
/// 关闭sceneserver(关闭d3d9server)
scene -> Close();

/// 销毁KernelServer
n_delete(ks);

return true ;
}
///
/// +初始化环境,创建需要的Server
/// ----------------------------------------------------------------------------

/// ----------------------------------------------------------------------------
/// +Application
int main( int argc, const char ** argv)
{
/// 初始化Application
if ( ! InitApp())
{
n_error(
" 程序初始化失败! " );
return 0 ;
}

ks_info.SetKernelServer(ks);
ks_info.LogNOH(
" / " );

/// 这里相当于游戏循环,gfx2->Trigger()将触发win32的消息泵
while (gfx2 -> Trigger() && tcl -> Trigger())
{
/// TriggerTimeServer
nTimeServer::Instance() -> Trigger();
double time = nTimeServer::Instance() -> GetTime();

/// TriggerInputServer
input -> Trigger(time);

/// 处理GUI事件,需要inputserver的支持
gui -> Trigger();

/// BeginScene(BeginFrame)
if (scene -> BeginScene(ccam.GetViewMatrix()))
{
// RenderScene
scene -> RenderScene();

// EndScene
scene -> EndScene();

// PresentScene(EndFrame)
scene -> PresentScene();
}

/// FlushEvents
input -> FlushEvents();

n_sleep(
0.00f );
}

/// 释放资源
if ( ! CloseApp())
{
n_error(
" 释放资源失败! " );
return 0 ;
}

return 0 ;
}
/// -Application
/// ----------------------------------------------------------------------------

脚本代码如下:

# -------------------------------------------------------------------------------
#T14_GuiServer.tcl
#
#ThisisextractfromthethecentralNebularuntimestartupscript
#whichisusedforNebula2TutorialGuiServer
#
#ThescriptmainlysetsupthenGuiVariablesandMapInputs
#
#(C)2003RadonLabsGmbH
#-------------------------------------------------------------------------------

#-------------------------------------------------------------------------------
#OnGuiServerOpen
#
#ThisfunctioniscalledwhentheNebula2GUIserverisopened.
#-------------------------------------------------------------------------------

procOnGuiServerOpen{}{
setcwd[psel]

# 工具提示
#initializethedefaulttooltip

setguiRoot[ / sys / servers / gui . getrootpath]
sel
$guiRoot
newnguitooltipTooltip
selTooltip
. setdefaultbrush " tooltip "
. setfont " GuiSmall "
. setcolor 0 0 0 1
. setalignment " left "
. setborder 0.005 0.005
sel
..

# 设置Gui外观相关信息
#definethesystemskin

setskin[ / sys / servers / gui . newskin system ]
sel
$skin
# settexturepathpre-andpostfix(NOTE:don'tchangepathtotextures:system!!!)
. settextureprefix " home:datafiles/textures/system/ "
. settexturepostfix " .dds "

# activeandinactivewindowmodulationcolor
. setactivewindowcolor 1.0 1.0 1.0 1.0
. setinactivewindowcolor 0.6 0.6 0.6 0.6
. setbuttontextcolor 0.0 0.0 0.0 1.0
. settitletextcolor 0.0 0.0 0.0 1.0
. setlabeltextcolor 0.0 0.0 0.0 1.0
. setentrytextcolor 0.0 0.0 0.0 1.0
. settextcolor 0.0 0.0 0.0 1.0
. setmenutextcolor 0.0 0.0 0.0 1.0

# ####################################################################
#+添加画刷
#
#definebrushes

. beginbrushes

# windowtitlebar,windowbackground,tooltipbackground
. addbrushtitlebarskin 66 152 10 20 1.0 1.0 1.0 1.0
. addbrushwindowskin 8 154 4 4 1.0 1.0 1.0 1.0
. addbrushtooltipskin 8 154 4 4 1.0 1.0 0.878 0.8
. addbrushpinkskin 8 154 4 4 1.0 0.0 1.0 1.0
. addbrushdragboxskin 8 154 4 4 1.0 0.8 0.8 0.5

# textentryfield
. addbrushtextentry_nskin 446 124 8 8 0.7 0.7 0.7 1.0
. addbrushtextentry_pskin 446 124 8 8 0.8 0.8 0.8 1.0
. addbrushtextentry_hskin 446 124 8 8 0.9 0.9 0.9 1.0
. addbrushtextcursorskin 446 124 8 8 0.4 0.4 0.4 1.0

# thewindowclosebutton
. addbrushclose_nskin 388 40 16 16 1.0 1.0 1.0 1.0
. addbrushclose_hskin 404 40 16 16 1.0 1.0 1.0 1.0
. addbrushclose_pskin 420 40 16 16 1.0 1.0 1.0 1.0

# thewindowsizebutton
 类似资料: