您的位置:首页 > 移动开发

Nebula2探秘15-Simple Application Framework

2007-12-17 10:51 141 查看
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: