Nebula2探秘15-Simple Application Framework
happykevins文
在经历了前14章的学习之后,本章将介绍一个简单的Nebula2应用程序框架nAppFrame。 nAppFrame可以说是nApplication的最简化版本,去掉了状态机和所有不必要的Packages和Servers。 nAppFrame的代码简单明了,易于使用,可以是省去每次重新创建Nebula2程序繁杂而枯燥的活动。
以下的示例代码就应用了nAppFrame,并挂载了Render2D和Render3D两个函数,Render3D什么 事情都没做,读者有兴趣的话可以扩展该例子代码,例如显示个3D模型或骨骼动画之类的东东, 当然这些内容我将在以后章节中介绍,请大家继续关注Nebula2探秘哦:)
开始贴代码,nAppFrame的代码:
/*
**************************************************************************
*/
/*
Nebula2 - Tutorial nAppFrame
*/
/*
A Simple Program Framework
*/
/*
author: happykevins
*/
/*
**************************************************************************
*/
#pragma
once
//
关闭讨厌的类型检查warning
#pragma
warning(disable: 4244 4267)
#include
"
kernel/nkernelserver.h
"
#include
"
kernel/nroot.h
"
#include
"
kernel/nautoref.h
"
#include
"
gfx2/ndisplaymode2.h
"
#include
"
gfx2/ncamera2.h
"
#include
"
tools/nmayacamcontrol.h
"
#include
"
tools/nnodelist.h
"
class
nScriptServer;
class
nGfxServer2;
class
nInputServer;
class
nConServer;
class
nResourceServer;
class
nSceneServer;
class
nVariableServer;
class
nAnimationServer;
class
nParticleServer;
class
nVideoServer;
class
nGuiServer;
class
nShadowServer2;
class
nAudioServer3;
class
nPrefServer;
class
nLocaleServer;
//
//
class nAppFrame
//
仿照napplication制作的一个Nebula2应用程序框架,对初始化和运行做了减化
//
只开启我认为必要的服务
//
class
nAppFrame :
public
nRoot
{
public
:
typedef
void
(
*
nFunc) (
void
);
nAppFrame();
~
nAppFrame();
///
初始化Nebula2引擎
bool
OpenNebula();
///
关闭Nebula2引擎
bool
CloseNebula();
///
进入Nebula2引擎的主循环
void
RunNebula();
///
用户可重载的初始化方法(在OpenNebula的最后被调用)
virtual
bool
ClientOpen() {
return
true
;}
///
用户可重载的关闭方法(在CloseNebula之前被调用)
virtual
bool
ClientClose() {
return
true
;}
///
在这里添加3D渲染代码
virtual
void
OnRender3D();
///
在这里添加2D渲染代码
virtual
void
OnRender2D();
///
在这里添加游戏逻辑代码
virtual
void
OnFrame();
///
Kernel Server
static
nKernelServer
*
ks;
///
OnFrame Function Hook
nFunc m_fpOnFrame;
///
OnRender3D Function Hook
nFunc m_fpOnRender3D;
///
OnRender2D Function Hook
nFunc m_fpOnRender2D;
///
nNode节点列表
nNodeList m_nodes;
protected
:
///
摄像机控制代码(有默认实现,用户可重载)
virtual
void
OnCameraControll();
///
Nebula2启动标志
bool
isOpen;
///
Servers
nAutoRef
<
nScriptServer
>
refScriptServer;
nAutoRef
<
nGfxServer2
>
refGfxServer;
nAutoRef
<
nInputServer
>
refInputServer;
nAutoRef
<
nConServer
>
refConServer;
nAutoRef
<
nResourceServer
>
refResourceServer;
nAutoRef
<
nSceneServer
>
refSceneServer;
nAutoRef
<
nVariableServer
>
refVariableServer;
nAutoRef
<
nGuiServer
>
refGuiServer;
nAutoRef
<
nShadowServer2
>
refShadowServer;
nAutoRef
<
nParticleServer
>
refParticleServer;
nAutoRef
<
nAnimationServer
>
refAnimationServer;
//
nAutoRef<nVideoServer> refVideoServer;
//
nAutoRef<nAudioServer3> refAudioServer;
//
nAutoRef<nPrefServer> refPrefServer;
//
nAutoRef<nLocaleServer> refLocaleServer;
///
Camera Controll
nDisplayMode2 display;
nCamera2 camera;
matrix44 view;
nMayaCamControl m_ccam;
};
///
nappframe.cpp
#include
"
nappframe.h
"
#include
"
nutildefs.h
"
#include
"
kernel/nfileserver2.h
"
#include
"
kernel/ntimeserver.h
"
#include
"
kernel/nscriptserver.h
"
#include
"
gfx2/ngfxserver2.h
"
#include
"
input/ninputserver.h
"
#include
"
misc/nconserver.h
"
#include
"
resource/nresourceserver.h
"
#include
"
scene/nsceneserver.h
"
#include
"
variable/nvariableserver.h
"
#include
"
anim2/nanimationserver.h
"
#include
"
particle/nparticleserver.h
"
#include
"
video/nvideoserver.h
"
#include
"
gui/nguiserver.h
"
#include
"
kernel/nremoteserver.h
"
#include
"
audio3/naudioserver3.h
"
#include
"
misc/nprefserver.h
"
#include
"
locale/nlocaleserver.h
"
#include
"
shadow2/nshadowserver2.h
"
nNebulaUsePackage(nnebula);
nNebulaUsePackage(ntoollib);
nNebulaUsePackage(ndirect3d9);
nNebulaUsePackage(ndinput8);
nNebulaUsePackage(ngui);
nNebulaScriptModule(nAppFrame, nappframe,
"
nroot
"
);
void
nNebulaScriptInitCmds(nappframe)(nClass
*
)
{
///
add any cmd you want.
}
nKernelServer
*
nAppFrame::ks
=
NULL;
nAppFrame::nAppFrame() :
isOpen(
false
),
refScriptServer(
"
/sys/servers/script
"
),
refGfxServer(
"
/sys/servers/gfx
"
),
refInputServer(
"
/sys/servers/input
"
),
refConServer(
"
/sys/servers/console
"
),
refResourceServer(
"
/sys/servers/resource
"
),
refSceneServer(
"
/sys/servers/scene
"
),
refVariableServer(
"
/sys/servers/variable
"
),
refGuiServer(
"
/sys/servers/gui
"
),
refShadowServer(
"
/sys/servers/shadow
"
),
refParticleServer(
"
/sys/servers/particle
"
),
refAnimationServer(
"
/sys/servers/anim
"
)
//
refVideoServer("/sys/servers/video"),
//
refAudioServer("/sys/servers/audio"),
//
refPrefServer("/sys/servers/nwin32prefserver"),
//
refLocaleServer("/sys/servers/locale"),
{
n_assert(
!
nAppFrame::ks);
nAppFrame::ks
=
n_new(nKernelServer);
m_fpOnFrame
=
NULL;
m_fpOnRender3D
=
NULL;
m_fpOnRender2D
=
NULL;
}
nAppFrame::
~
nAppFrame()
{
n_assert(nAppFrame::ks);
n_delete(nAppFrame::ks);
nAppFrame::ks
=
NULL;
}
///
Open Nebula App
bool
nAppFrame::OpenNebula()
{
///
Add Modules
ks
->
AddPackage(nnebula);
ks
->
AddPackage(ntoollib);
ks
->
AddPackage(ndirect3d9);
ks
->
AddPackage(ndinput8);
ks
->
AddPackage(ngui);
///
Create Servers
ks
->
New(
"
ntclserver
"
,
"
/sys/servers/script
"
);
ks
->
New(
"
nresourceserver
"
,
"
/sys/servers/resource
"
);
ks
->
New(
"
nvariableserver
"
,
"
/sys/servers/variable
"
);
ks
->
New(
"
ndi8server
"
,
"
/sys/servers/input
"
);
ks
->
New(
"
nguiserver
"
,
"
/sys/servers/gui
"
);
ks
->
New(
"
nconserver
"
,
"
/sys/servers/console
"
);
ks
->
New(
"
nd3d9server
"
,
"
/sys/servers/gfx
"
);
ks
->
New(
"
nsceneserver
"
,
"
/sys/servers/scene
"
);
ks
->
New(
"
nshadowserver2
"
,
"
/sys/servers/shadow
"
);
ks
->
New(
"
nparticleserver
"
,
"
/sys/servers/particle
"
);
ks
->
New(
"
nanimationserver
"
,
"
/sys/servers/anim
"
);
//
ks->New("ndshowserver", "/sys/servers/video");
//
ks->New("nprefserver", "/sys/servers/nwin32prefserver");
//
ks->New("nlocaleserver", "/sys/servers/locale");
//
ks->New("ndsoundserver3", "/sys/servers/audio");
///
SetDisplay
display.SetXPos(
150
);
display.SetYPos(
100
);
display.SetWidth(
640
);
display.SetHeight(
480
);
refGfxServer
->
SetDisplayMode(display);
refGfxServer
->
SetCamera(camera);
///////////////////////////////////////////////////////////////////////////
nString ret;
///
获得FileServer设置系统路径
nFileServer2
*
file
=
(nFileServer2
*
)ks
->
Lookup(
"
sys/servers/file2
"
);
///
设置系统路径
file
->
SetAssign(
"
home
"
,
"
bin:../../
"
);
file
->
SetAssign(
"
renderpath
"
,
"
home:datafiles/shaders
"
);
file
->
SetAssign(
"
scripts
"
,
"
home:datafiles/scripts
"
);
file
->
SetAssign(
"
particles
"
,
"
home:datafiles/particles
"
);
file
->
SetAssign(
"
gfxlib
"
,
"
home:datafiles/gfxlib
"
);
file
->
SetAssign(
"
textures
"
,
"
home:datafiles/textures
"
);
file
->
SetAssign(
"
meshes
"
,
"
home:datafiles/meshes
"
);
file
->
SetAssign(
"
anims
"
,
"
home:datafiles/anims
"
);
///
启动RemoteServer
ks
->
GetRemoteServer()
->
Open(
"
8379
"
);
///
启动sceneserver(启动d3d9server)
refSceneServer
->
SetRenderPathFilename(
"
renderpath:dx7_renderpath.xml
"
);
if
(
!
refSceneServer
->
Open() )
{
return
false
;
}
///
启动GUIServer
ret.Clear();
refScriptServer
->
RunScript(
"
scripts:ngui.tcl
"
, ret);
refGuiServer
->
Open();
///
Map Input
refInputServer
->
Open();
ret.Clear();
refScriptServer
->
RunScript(
"
scripts:ninput.tcl
"
, ret);
///
Open node list
this
->
m_nodes.SetStageScript(
"
gfxlib:stdlight.n2
"
);
this
->
m_nodes.Open();
///
Init Client Res
this
->
ClientOpen();
///
make the open mark
this
->
isOpen
=
true
;
return
true
;
}
///
Close Nebula App
bool
nAppFrame::CloseNebula()
{
///
make the close mark
this
->
isOpen
=
false
;
///
release client res
this
->
ClientClose();
///
close node list
this
->
m_nodes.Close();
///
close servers
if
(
this
->
refGuiServer.isvalid())
{
this
->
refGuiServer
->
Close();
}
if
(
this
->
refSceneServer.isvalid())
{
this
->
refSceneServer
->
Close();
}
//
if (this->refAudioServer.isvalid())
//
{
//
this->refAudioServer->Close();
//
}
//
if (this->refVideoServer.isvalid())
//
{
//
this->refVideoServer->Close();
//
}
//
if (this->refLocaleServer.isvalid())
//
{
//
if (this->refLocaleServer->IsOpen())
//
this->refLocaleServer->Close();
//
}
//
close the remote port
ks
->
GetRemoteServer()
->
Close();
this
->
refShadowServer
->
Release();
this
->
refGuiServer
->
Release();
this
->
refParticleServer
->
Release();
this
->
refVariableServer
->
Release();
this
->
refSceneServer
->
Release();
this
->
refConServer
->
Release();
this
->
refInputServer
->
Release();
this
->
refGfxServer
->
Release();
this
->
refResourceServer
->
Release();
this
->
refScriptServer
->
Release();
this
->
refAnimationServer
->
Release();
//
this->refVideoServer->Release();
//
this->refLocaleServer->Release();
//
this->refPrefServer->Release();
//
this->refAudioServer->Release();
return
true
;
}
///
Main loop
void
nAppFrame::RunNebula()
{
n_assert(
this
->
isOpen);
bool
run
=
true
;
///
Trigger GfxServer (Windows Messages) && Ping Script Quit Request
while
( run
=
refGfxServer
->
Trigger()
&&
this
->
refScriptServer
->
Trigger() )
{
///
Trigger TimeServer
nTimeServer::Instance()
->
Trigger();
double
time
=
nTimeServer::Instance()
->
GetTime();
///
Trigger InputServer
this
->
refInputServer
->
Trigger(time);
///
Trigger Logic
this
->
OnFrame();
///
Begin Scene (Begin Frame)
if
( refSceneServer
->
BeginScene(view) )
{
//
Trigger Particle Server
refParticleServer
->
Trigger();
//
Render 3D
this
->
OnRender3D();
//
Render Scene
refSceneServer
->
RenderScene();
//
End Scene
refSceneServer
->
EndScene();
//
Render 2D
this
->
OnRender2D();
//
Present Scene (End Frame)
refSceneServer
->
PresentScene();
}
///
Flush Events
this
->
refInputServer
->
FlushEvents();
}
}
///
OnRender3d
void
nAppFrame::OnRender3D()
{
for
( size_t i
=
0
; i
<
m_nodes.GetCount();
++
i )
{
this
->
refSceneServer
->
Attach(m_nodes.GetRenderContextAt(i));
}
if
( m_fpOnRender3D )
{
m_fpOnRender3D();
}
}
///
OnRender2d
void
nAppFrame::OnRender2D()
{
if
( m_fpOnRender2D )
{
m_fpOnRender2D();
}
}
///
logic trigger
void
nAppFrame::OnFrame()
{
///
update camera
this
->
OnCameraControll();
///
update node list
static
unsigned
int
nFrameID
=
0
;
this
->
m_nodes.Trigger(nTimeServer::Instance()
->
GetTime(), nFrameID
++
);
if
( m_fpOnFrame )
{
m_fpOnFrame();
}
}
///
camera controll
void
nAppFrame::OnCameraControll()
{
//
Default Camera Controller
if
(
!
this
->
refGuiServer
->
IsMouseOverGui() )
{
//
Render Debug
if
( refInputServer
->
GetButton(
"
debug
"
) )
{
if
( refSceneServer
->
GetRenderDebug() )
{
refSceneServer
->
SetRenderDebug(
false
);
}
else
{
refSceneServer
->
SetRenderDebug(
true
);
}
}
//
give inputs to camControl
this
->
m_ccam.SetResetButton(refInputServer
->
GetButton(
"
reset
"
));
this
->
m_ccam.SetLookButton(refInputServer
->
GetButton(
"
look
"
));
this
->
m_ccam.SetPanButton(refInputServer
->
GetButton(
"
pan
"
));
this
->
m_ccam.SetZoomButton(refInputServer
->
GetButton(
"
zoom
"
));
this
->
m_ccam.SetSliderLeft(refInputServer
->
GetSlider(
"
left
"
));
this
->
m_ccam.SetSliderRight(refInputServer
->
GetSlider(
"
right
"
));
this
->
m_ccam.SetSliderUp(refInputServer
->
GetSlider(
"
up
"
));
this
->
m_ccam.SetSliderDown(refInputServer
->
GetSlider(
"
down
"
));
//
update view and get the actual viewMatrix
this
->
m_ccam.Update();
this
->
view.
set
(
this
->
m_ccam.GetViewMatrix());
}
}
以下是使用实例代码:
/*
**************************************************************************
*/
/*
Nebula2 - Tutorial 15
*/
/*
Simple Application Framework
*/
/*
author: happykevins
*/
/*
**************************************************************************
*/
#include
"
kernel/nkernelserver.h
"
#include
"
gfx2/ngfxserver2.h
"
#include
"
../NebulaUtils/nappframe.h
"
#include
"
../NebulaUtils/nutildefs.h
"
void
Render3D()
{
//
Write 3D Render Code Here.
}
void
Render2D()
{
//
draw cubes
vector3 CenterPoint(
0
,
0.5f
,
0
);
float
fSize
=
0.5f
;
vector3 v[
8
];
v[
0
].
set
(CenterPoint.x
-
fSize, CenterPoint.y
-
fSize, CenterPoint.z
-
fSize);
v[
1
].
set
(CenterPoint.x
+
fSize, CenterPoint.y
-
fSize, CenterPoint.z
-
fSize);
v[
2
].
set
(CenterPoint.x
+
fSize, CenterPoint.y
+
fSize, CenterPoint.z
-
fSize);
v[
3
].
set
(CenterPoint.x
-
fSize, CenterPoint.y
+
fSize, CenterPoint.z
-
fSize);
v[
4
].
set
(CenterPoint.x
-
fSize, CenterPoint.y
-
fSize, CenterPoint.z
+
fSize);
v[
5
].
set
(CenterPoint.x
+
fSize, CenterPoint.y
-
fSize, CenterPoint.z
+
fSize);
v[
6
].
set
(CenterPoint.x
+
fSize, CenterPoint.y
+
fSize, CenterPoint.z
+
fSize);
v[
7
].
set
(CenterPoint.x
-
fSize, CenterPoint.y
+
fSize, CenterPoint.z
+
fSize);
vector3 cube[
16
]
=
{
v[
1
], v[
0
], v[
4
], v[
5
],
v[
1
], v[
2
], v[
6
], v[
5
],
v[
3
], v[
2
], v[
6
], v[
7
],
v[
3
], v[
0
], v[
4
], v[
7
]
};
vector3 CenterPoint1(
0
,
1.5f
,
0
);
float
fSize1
=
0.5f
;
vector3 v1[
8
];
v1[
0
].
set
(CenterPoint1.x
-
fSize1, CenterPoint1.y
-
fSize1, CenterPoint1.z
-
fSize1);
v1[
1
].
set
(CenterPoint1.x
+
fSize1, CenterPoint1.y
-
fSize1, CenterPoint1.z
-
fSize1);
v1[
2
].
set
(CenterPoint1.x
+
fSize1, CenterPoint1.y
+
fSize1, CenterPoint1.z
-
fSize1);
v1[
3
].
set
(CenterPoint1.x
-
fSize1, CenterPoint1.y
+
fSize1, CenterPoint1.z
-
fSize1);
v1[
4
].
set
(CenterPoint1.x
-
fSize1, CenterPoint1.y
-
fSize1, CenterPoint1.z
+
fSize1);
v1[
5
].
set
(CenterPoint1.x
+
fSize1, CenterPoint1.y
-
fSize1, CenterPoint1.z
+
fSize1);
v1[
6
].
set
(CenterPoint1.x
+
fSize1, CenterPoint1.y
+
fSize1, CenterPoint1.z
+
fSize1);
v1[
7
].
set
(CenterPoint1.x
-
fSize1, CenterPoint1.y
+
fSize1, CenterPoint1.z
+
fSize1);
vector3 cube1[
16
]
=
{
v1[
1
], v1[
0
], v1[
4
], v1[
5
],
v1[
1
], v1[
2
], v1[
6
], v1[
5
],
v1[
3
], v1[
2
], v1[
6
], v1[
7
],
v1[
3
], v1[
0
], v1[
4
], v1[
7
]
};
nGfxServer2::Instance()
->
BeginLines();
nGfxServer2::Instance()
->
DrawLines3d(cube,
8
, vector4(
1.0f
,
0
,
0
,
0.5f
) );
nGfxServer2::Instance()
->
DrawLines3d(cube
+
8
,
8
, vector4(
1.0f
,
0
,
0
,
0.5f
) );
nGfxServer2::Instance()
->
DrawLines3d(cube1,
8
, vector4(
0
,
1.0f
,
0
,
0.5f
) );
nGfxServer2::Instance()
->
DrawLines3d(cube1
+
8
,
8
, vector4(
0
,
1.0f
,
0
,
0.5f
) );
nGfxServer2::Instance()
->
EndLines();
vector3 LineH[
22
];
vector3 LineV[
22
];
float
fLen
=
5.0f
;
for
(
int
i
=
0
; i
<
11
; i
++
)
{
LineH[ i
*
2
].
set
(
0
-
fLen,
0
, i
-
fLen);
LineH[ i
*
2
+
1
].
set
(
10.0f
-
fLen,
0
, i
-
fLen);
}
for
(i
=
0
; i
<
11
; i
++
)
{
LineV[ i
*
2
].
set
(i
-
fLen,
0
,
0
-
fLen);
LineV[ i
*
2
+
1
].
set
(i
-
fLen,
0
,
10.0f
-
fLen);
}
//
draw grids
nGfxServer2::Instance()
->
BeginLines();
for
(i
=
0
; i
<
11
; i
++
)
{
nGfxServer2::Instance()
->
DrawLines3d(LineH
+
i
*
2
,
2
, vector4(
1.0f
,
0
,
1.0f
,
0.5f
) );
}
for
(i
=
0
; i
<
11
; i
++
)
{
nGfxServer2::Instance()
->
DrawLines3d(LineV
+
i
*
2
,
2
, vector4(
1.0f
,
0
,
1.0f
,
0.5f
) );
}
nGfxServer2::Instance()
->
EndLines();
}
///
----------------------------------------------------------------------------
///
+Application
int
main(
int
argc,
const
char
**
argv)
{
//
生成一个nAppFrame的实例
nAppFrame app;
//
注册渲染函数
app.m_fpOnRender2D
=
Render2D;
app.m_fpOnRender3D
=
Render3D;
//
初始化引擎
if
( app.OpenNebula() )
{
//
启动引擎主循环
app.RunNebula();
}
//
关闭引擎
app.CloseNebula();
return
0
;
}
///
-Application
///
----------------------------------------------------------------------------
-The End-
Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1499334