前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >实现一个同步的RenderApplication

实现一个同步的RenderApplication

作者头像
逍遥剑客
发布2019-02-20 12:53:08
3770
发布2019-02-20 12:53:08
举报

Nebula3 Sep2008 SDK之后渲染改成异步的了, 对于想直接操作内部API接口的我来说, 没法直接下手了

因为RenderApplication的图形接口也变成了异步-_-

没办法, 参照Feb2008 SDK写了一个SyncRenderApplication.

有一个问题待解决: InputServer要用到Display, 而Display用的是异步的Graphics, 汗

反正暂时不需要进行操作, 先这样凑合着用吧:

代码语言:javascript
复制
#pragma once
//------------------------------------------------------------------------------
/** 
    @class App::SyncRenderApplication
    
    Render application class with single threaded rendering.
    
    (C) 2009 xoyojank
*/
#include "app/application.h"
#include "core/coreserver.h"
#include "debug/debuginterface.h"
#include "io/ioserver.h"
#include "interface/iointerface.h"
#include "input/inputserver.h"
#include "timing/timer.h"
#include "coregraphics/renderdevice.h"
#include "coregraphics/displaydevice.h"
#include "coregraphics/transformdevice.h"
#include "coregraphics/shaderserver.h"
#include "coregraphics/shaperenderer.h"
#include "coregraphics/vertexlayoutserver.h"
#include "resources/sharedresourceserver.h"
#include "resources/resourcemanager.h"
#include "models/modelserver.h"
#include "internalgraphics/internalgraphicsserver.h"
#include "lighting/lightserver.h"
#include "lighting/shadowserver.h"
#include "frame/frameserver.h"
#include "addons/nebula2/nebula2wrapper.h"
#include "http/httpinterface.h"

#include "coregraphics/textrenderer.h"

//------------------------------------------------------------------------------
namespace App
{
class SyncRenderApplication : public Application
{
public:
    /// constructor
    SyncRenderApplication();
    /// destructor
    virtual ~SyncRenderApplication();
    /// open the application
    virtual bool Open();
    /// close the application
    virtual void Close();
    /// run the application
    virtual void Run();

private:
    /// update the current time values
    void UpdateTime();

protected:
    /// set quit requested flag
    void SetQuitRequested(bool b);
    /// return true if quit requested
    bool IsQuitRequested() const;
    /// called to configure display
    virtual void OnConfigureDisplay();
    /// process input (called before rendering)
    virtual void OnProcessInput();
    /// update world 
    virtual void OnUpdateFrame();
	/// render current frame
	virtual void OnRenderFrame();
    /// get current absolute time
    Timing::Time GetTime() const;
    /// get current frame time
    Timing::Time GetFrameTime() const;

    Ptr<Core::CoreServer> coreServer;
	Ptr<Debug::DebugInterface> debugInterface;
    Ptr<IO::IoServer> ioServer;
    Ptr<Interface::IOInterface> ioInterface;
	Ptr<CoreGraphics::RenderDevice> renderDevice;
	Ptr<CoreGraphics::DisplayDevice> displayDevice;
	Ptr<CoreGraphics::TransformDevice> transformDevice;
	Ptr<CoreGraphics::ShaderServer> shaderServer;
	Ptr<CoreGraphics::ShapeRenderer> shapeRenderer;
	Ptr<CoreGraphics::VertexLayoutServer> vertexLayoutServer;
	Ptr<CoreGraphics::TextRenderer> textRenderer;
	Ptr<Resources::SharedResourceServer> sharedResourceServer;
	Ptr<Resources::ResourceManager> resourceManager;
	Ptr<Models::ModelServer> modelServer;
	Ptr<InternalGraphics::InternalGraphicsServer> graphicsServer;
	Ptr<Lighting::LightServer> lightServer;
	Ptr<Lighting::ShadowServer> shadowServer;
	Ptr<Frame::FrameServer> frameServer;
	Ptr<Anim::AnimationServer> animationServer;
    Ptr<Input::InputServer> inputServer;
	Ptr<Http::HttpInterface> httpInterface;
    Timing::Timer timer;
    Timing::Time time;
    Timing::Time frameTime;
    bool quitRequested;
};

//------------------------------------------------------------------------------
/**
*/
inline void
SyncRenderApplication::SetQuitRequested(bool b)
{
    this->quitRequested = b;
}

//------------------------------------------------------------------------------
/**
*/
inline bool
SyncRenderApplication::IsQuitRequested() const
{
    return this->quitRequested;
}

//------------------------------------------------------------------------------
/**
*/
inline Timing::Time
SyncRenderApplication::GetTime() const
{
    return this->time;
}

//------------------------------------------------------------------------------
/**
*/
inline Timing::Time
SyncRenderApplication::GetFrameTime() const
{
    return this->frameTime;
}

} // namespace App
//------------------------------------------------------------------------------
代码语言:javascript
复制
//------------------------------------------------------------------------------
//  syncrenderapplication.cc
//  (C) 2009 xoyojank
//------------------------------------------------------------------------------
#include "stdneb.h"
#include "apprender/syncrenderapplication.h"
#include "io/filestream.h"
#include "resources/simpleresourcemapper.h"
#include "coregraphics/streamtextureloader.h"
#include "coregraphics/streammeshloader.h"
#include "coregraphics/shaperenderer.h"
#include "resources/managedtexture.h"
#include "resources/managedmesh.h"
#include "coreanimation/streamanimationloader.h"
#include "internalgraphics/stagebuilder.h"
#include "internalgraphics/internalstage.h"
#include "internalgraphics/internalview.h"
#include "lighting/internalspotlightentity.h"
#include "apprender/platformconfig.h"
#include "debugrender/debugshaperenderer.h"
#include "models/nodes/statenodeinstance.h"

namespace App
{
using namespace Core;
using namespace IO;
using namespace Interface;
using namespace CoreGraphics;
using namespace InternalGraphics;
using namespace Resources;
using namespace Models;
using namespace Input;
using namespace Timing;
using namespace CoreAnimation;
using namespace Lighting;
using namespace Frame;
using namespace Anim;
using namespace Debug;

//------------------------------------------------------------------------------
/**
*/
SyncRenderApplication::SyncRenderApplication() :
    time(0.0),
    frameTime(0.0),
    quitRequested(false)
{
    // empty
}

//------------------------------------------------------------------------------
/**
*/
SyncRenderApplication::~SyncRenderApplication()
{
    n_assert(!this->IsOpen());
}

//------------------------------------------------------------------------------
/**
*/
bool
SyncRenderApplication::Open()
{
    n_assert(!this->IsOpen());
    if (Application::Open())
    {
        // setup core subsystem
        this->coreServer = CoreServer::Create();
        this->coreServer->SetCompanyName(this->companyName);
        this->coreServer->SetAppName(this->appName);
        this->coreServer->Open();

        // setup io subsystem
        // FIXME: REDUNDANT!!! 
        this->ioServer = IoServer::Create();
        this->ioServer->RegisterStandardUriSchemes();
        this->ioServer->SetupStandardAssigns();
        this->ioServer->MountStandardZipArchives();

        this->ioInterface = IOInterface::Create();
        this->ioInterface->Open();

		// setup http subsystem
		this->httpInterface = Http::HttpInterface::Create();
		this->httpInterface->Open();

		// setup debug subsystem
		this->debugInterface = DebugInterface::Create();
		this->debugInterface->Open();

        // setup graphics subsystem
		this->renderDevice = RenderDevice::Create();
		this->displayDevice = DisplayDevice::Create();
		this->transformDevice = TransformDevice::Create();
		this->shaderServer = ShaderServer::Create();
		this->shapeRenderer = ShapeRenderer::Create();
		this->textRenderer = TextRenderer::Create();
		this->vertexLayoutServer = VertexLayoutServer::Create();
		this->sharedResourceServer = SharedResourceServer::Create();
		this->resourceManager = ResourceManager::Create();
		this->modelServer = ModelServer::Create();
		this->graphicsServer = InternalGraphicsServer::Create();
		this->lightServer = LightServer::Create();
		this->shadowServer = ShadowServer::Create();
		this->frameServer = FrameServer::Create();
		this->animationServer = AnimationServer::Create();
        this->OnConfigureDisplay();
		if (!this->displayDevice->Open())
		{
			n_error("SyncRenderApplication: failed to open display device!");
		}
		if (!this->renderDevice->Open())
		{
			n_error("SyncRenderApplication: failed to open render device!");
		}
		this->vertexLayoutServer->Open();
		this->shaderServer->Open();
		this->transformDevice->Open();
		this->shapeRenderer->Open();
		this->sharedResourceServer->Open();
		this->resourceManager->Open();
		this->frameServer->Open();
		this->textRenderer->Open();

		// setup resource mapper for textures
		// FIXME: should be configurable!
		Ptr<SimpleResourceMapper> texMapper = SimpleResourceMapper::Create();
		texMapper->SetPlaceholderResourceId(ResourceId(PLACEHOLDER_TEXTURENAME));
		texMapper->SetResourceClass(Texture::RTTI);
		texMapper->SetResourceLoaderClass(StreamTextureLoader::RTTI);
		texMapper->SetManagedResourceClass(ManagedTexture::RTTI);
		this->resourceManager->AttachMapper(texMapper.upcast<ResourceMapper>());

		// setup resource mapper for meshes
		// FIXME: should be configurable!
		Ptr<SimpleResourceMapper> meshMapper = SimpleResourceMapper::Create();
		meshMapper->SetPlaceholderResourceId(ResourceId(PLACEHOLDER_MESHNAME));
		meshMapper->SetResourceClass(Mesh::RTTI);
		meshMapper->SetResourceLoaderClass(StreamMeshLoader::RTTI);
		meshMapper->SetManagedResourceClass(ManagedMesh::RTTI);
		this->resourceManager->AttachMapper(meshMapper.upcast<ResourceMapper>());

		// setup resource mapper for animations
		// FIXME: should be configurable!
		//Ptr<SimpleResourceMapper> animMapper = SimpleResourceMapper::Create();
		//animMapper->SetPlaceholderResourceId(ResourceId("ani:examples/eagle.nax2"));
		//animMapper->SetResourceClass(MemoryAnimation::RTTI);
		//animMapper->SetResourceLoaderClass(StreamAnimationLoader::RTTI);
		//animMapper->SetManagedResourceClass(ManagedAnimation::RTTI);
		//this->resourceManager->AttachMapper(animMapper.upcast<ResourceMapper>());

		this->modelServer->Open();
		this->graphicsServer->Open();
		this->lightServer->Open();
		this->shadowServer->Open();

        // setup input subsystem
        //this->inputServer = InputServer::Create();
        //this->inputServer->Open();

        // setup frame timer
        this->timer.Start();
        this->time = 0.0;
        this->frameTime = 0.01;

        return true;
    }
    return false;
}

//------------------------------------------------------------------------------
/**
*/
void
SyncRenderApplication::OnConfigureDisplay()
{
    // display adapter
    Adapter::Code adapter = Adapter::Primary;
    if (this->args.HasArg("-adapter"))
    {
        adapter = Adapter::FromString(this->args.GetString("-adapter"));
        if (this->displayDevice->AdapterExists(adapter))
        {
            this->displayDevice->SetAdapter(adapter);
        }
    }

    // display mode
    DisplayMode displayMode;
    if (this->args.HasArg("-x"))
    {
        displayMode.SetXPos(this->args.GetInt("-x"));
    }
    if (this->args.HasArg("-y"))
    {
        displayMode.SetYPos(this->args.GetInt("-y"));
    }
    if (this->args.HasArg("-w"))
    {
        displayMode.SetWidth(this->args.GetInt("-w"));
    }
    if (this->args.HasArg("-h"))
    {
        displayMode.SetHeight(this->args.GetInt("-h"));
    }
    this->displayDevice->SetDisplayMode(displayMode);
    this->displayDevice->SetFullscreen(this->args.GetBool("-fullscreen"));
    this->displayDevice->SetAlwaysOnTop(this->args.GetBool("-alwaysontop"));
    this->displayDevice->SetVerticalSyncEnabled(this->args.GetBool("-vsync"));
    if (this->args.HasArg("-aa"))
    {
        this->displayDevice->SetAntiAliasQuality(AntiAliasQuality::FromString(this->args.GetString("-aa")));
    }
    #if __XBOX360__
        this->displayDevice->SetAntiAliasQuality(AntiAliasQuality::Medium);
    #endif
}

//------------------------------------------------------------------------------
/**
*/
void
SyncRenderApplication::Close()
{
    n_assert(this->IsOpen());

    this->timer.Stop();

    //this->inputServer->Close();
    //this->inputServer = 0;

	this->frameServer = 0;
	this->shadowServer = 0;
	this->lightServer = 0;
	this->graphicsServer = 0;
	this->modelServer = 0;
	this->resourceManager = 0;
	this->sharedResourceServer = 0;
	this->vertexLayoutServer = 0;
	this->shapeRenderer = 0;
	this->shaderServer = 0;
	this->transformDevice = 0;
	this->displayDevice = 0;
	this->renderDevice = 0;
	this->animationServer = 0;
	this->textRenderer = 0;

	this->debugInterface->Close();
	this->debugInterface = 0;

	this->httpInterface->Close();
	this->httpInterface = 0;

    this->ioInterface->Close();
    this->ioInterface = 0;
    this->ioServer = 0;

    this->coreServer->Close();
    this->coreServer = 0;

    Application::Close();
}

//------------------------------------------------------------------------------
/**
*/
void
SyncRenderApplication::Run()
{
    n_assert(this->isOpen);
    //while (!(this->inputServer->IsQuitRequested() || this->IsQuitRequested()))
    //{
    //    // process input
    //    this->inputServer->BeginFrame();
    //    this->inputServer->OnFrame();
	while(true)
	{
        this->OnProcessInput();

        // update time
        this->UpdateTime();

        // run "game logic"
        this->OnUpdateFrame();

		// render frame
		this->OnRenderFrame();

        //this->inputServer->EndFrame();

        if (!this->displayDevice->IsFullscreen())
        {
            Core::SysFunc::Sleep(0.0);
        }
    }
}

//------------------------------------------------------------------------------
/**
*/
void
SyncRenderApplication::OnProcessInput()
{
    // empty, override this method in a subclass
}

//------------------------------------------------------------------------------
/**
*/
void
SyncRenderApplication::OnUpdateFrame()
{
    // empty, override this method in a subclass
}

//------------------------------------------------------------------------------
/**
*/
void
SyncRenderApplication::UpdateTime()
{
    Time curTime = this->timer.GetTime();
    this->frameTime = curTime - this->time;
    this->time = curTime;
}

//------------------------------------------------------------------------------
void
SyncRenderApplication::OnRenderFrame()
{
	// empty, override this method in a subclass
}
	
} // namespace App

测试程序, 仍然还是一条线:

代码语言:javascript
复制
#include "stdneb.h"    
#include "apprender/syncrenderapplication.h"    
#include "coregraphics/memoryvertexbufferloader.h"    
#include "resources/resourceloader.h"    
#include "timing/time.h"    

using namespace App;   
using namespace Util;   
using namespace Math;   
using namespace CoreGraphics;   
using namespace Resources;   

ImplementNebulaApplication()   

class LineRenderApp : public SyncRenderApplication   
{   
	Ptr<VertexBuffer> vertexBuffer;   
	Ptr<ShaderInstance> shaderInstance;   

public:   
	bool Open()   
	{   
		if (SyncRenderApplication::Open())   
		{   
			// vertex    
			Array<VertexComponent> vertexComponents;   
			vertexComponents.Append(VertexComponent(VertexComponent::Position, 0, VertexComponent::Float3));   
			float vertex[2][3] = { {-1.0f, -1.0f, 0.0f}, {1.0f, 1.0f, 0.0f} };   
			vertexBuffer = VertexBuffer::Create();   
			Ptr<MemoryVertexBufferLoader> vbLoader = MemoryVertexBufferLoader::Create();   
			vbLoader->Setup(vertexComponents, 2, vertex, 2 * 3 * sizeof(float));   
			vertexBuffer->SetLoader(vbLoader.upcast<ResourceLoader>());   
			vertexBuffer->SetAsyncEnabled(false);   
			vertexBuffer->Load();   
			vertexBuffer->SetLoader(NULL);   
			// shader    
			this->shaderInstance = this->shaderServer->CreateShaderInstance(ResourceId("shd:shape"));   
			Ptr<ShaderVariable> color = this->shaderInstance->GetVariableBySemantic(ShaderVariable::Semantic("MatDiffuse"));   
			color->SetVector(float4(1.0f, 1.0f, 1.0f, 1.0f));   
			Ptr<ShaderVariable> mvp = this->shaderInstance->GetVariableBySemantic(ShaderVariable::Semantic("ModelViewProjection"));   
			mvp->SetMatrix(matrix44::identity());   
		}   
		return true;   
	}   

	void OnRenderFrame()   
	{   
		this->displayDevice->ProcessWindowMessages();   
		this->renderDevice->BeginFrame();   
		this->renderDevice->BeginPass(this->renderDevice->GetDefaultRenderTarget(), this->shaderInstance);   
		PrimitiveGroup primGroup;   
		primGroup.SetBaseVertex(0);   
		primGroup.SetNumVertices(2);   
		primGroup.SetPrimitiveTopology(PrimitiveTopology::LineList);   

		this->renderDevice->SetVertexBuffer(this->vertexBuffer);   
		this->renderDevice->SetPrimitiveGroup(primGroup);   
		this->renderDevice->Draw();   
		this->renderDevice->EndPass();   
		this->renderDevice->EndFrame();   
		this->renderDevice->Present();   
	}   
};   

void  
NebulaMain(const CmdLineArgs& args)   
{   
	LineRenderApp app;   
	app.SetAppName("Test Renderer");   
	app.SetCmdLineArgs(args);   
	if (app.Open())   
	{   
		app.Run();   
		app.Close();   
	}   
	app.Exit();   
}  
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2009年02月26日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档