Nebula2探秘15-Simple Application Framework

本文介绍了一个简化的Nebula2应用程序框架nAppFrame,该框架去除了不必要的组件和服务,使开发者能够快速搭建起Nebula2的基础环境。通过示例代码展示了如何使用nAppFrame并注册自定义的渲染函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 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      refVideoServer;
    
//nAutoRef     refAudioServer;
    
//nAutoRef       refPrefServer;
    
//nAutoRef     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(00.5f0);
    
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(
01.5f0);
    
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.0f000.5f) );
    nGfxServer2::Instance()
->DrawLines3d(cube+88, vector4(1.0f000.5f) );

    nGfxServer2::Instance()
->DrawLines3d(cube1,   8, vector4(01.0f00.5f) );
    nGfxServer2::Instance()
->DrawLines3d(cube1+88, vector4(01.0f00.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, 00 - fLen);
        LineV[ i 
* 2 + 1].set(i- fLen, 010.0f- fLen);
    }

    
// draw grids
    nGfxServer2::Instance()->BeginLines();

    
for(i = 0; i < 11; i++)
    {
        nGfxServer2::Instance()
->DrawLines3d(LineH + i * 2,   2, vector4(1.0f01.0f0.5f) );
    }

    
for(i = 0; i < 11; i++)
    {
        nGfxServer2::Instance()
->DrawLines3d(LineV + i * 2,   2, vector4(1.0f01.0f0.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-


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值