This page has been translated automatically.
Видеоуроки
Interface
Essentials
Advanced
Подсказки и советы
Основы
Программирование на C#
Рендеринг
Принципы работы
Свойства (properties)
Компонентная Система
Рендер
Физика
Редактор UnigineEditor
Обзор интерфейса
Работа с ассетами
Настройки и предпочтения
Работа с проектами
Настройка параметров ноды
Setting Up Materials
Настройка свойств
Освещение
Landscape Tool
Sandworm
Использование инструментов редактора для конкретных задач
Extending Editor Functionality
Встроенные объекты
Ноды (Nodes)
Объекты (Objects)
Эффекты
Декали
Источники света
Geodetics
World Nodes
Звуковые объекты
Объекты поиска пути
Players
Программирование
Основы
Настройка среды разработки
Примеры использования
C#
UnigineScript
Унифицированный язык шейдеров UUSL
Плагины
File Formats
Rebuilding the Engine Tools
GUI
Двойная точность координат
API
Containers
Common Functionality
Controls-Related Classes
Engine-Related Classes
Filesystem Functionality
GUI-Related Classes
Math Functionality
Node-Related Classes
Objects-Related Classes
Networking Functionality
Pathfinding-Related Classes
Physics-Related Classes
Plugins-Related Classes
IG Plugin
CIGIConnector Plugin
Rendering-Related Classes
Работа с контентом
Оптимизация контента
Материалы
Material Nodes Library
Miscellaneous
Input
Math
Matrix
Textures
Art Samples
Tutorials
Внимание! Эта версия документация УСТАРЕЛА, поскольку относится к более ранней версии SDK! Пожалуйста, переключитесь на самую актуальную документацию для последней версии SDK.
Внимание! Эта версия документации описывает устаревшую версию SDK, которая больше не поддерживается! Пожалуйста, обновитесь до последней версии SDK.

CustomApp Class

Warning
The functionality described in this article is not available in the Community SDK edition.
You should upgrade to Engineering / Sim SDK edition to use it.

Each Unigine-based application has a part, which is called a main loop and does most of the job required for window updating and drawing. The required code can be embedded directly into the main loop of the application as described here. Or it can be handled by the Unigine::CustomApp class.

For example, the need to use the Unigine::CustomApp class can arise when you want to integrate the Unigine engine into a custom application window.

Notice
App* plugins (AppProjection, AppSurround, AppWall, AppPanorama, and others) cannot be used in a Qt-based application.

To correctly use the Unigine::CustomApp class, you should perform the following:

  1. Include the UnigineCustomApp.h header file into the source code.
  2. Create a custom class and inherit it from the Unigine::CustomApp class.
  3. Override all of the virtual functions specified in the include/UnigineCustomApp.h file.
  4. Create the application window and initialize the graphics in your source code.

Notice
There are several examples of custom applications that can be found in the source/samples/App/ subfolder of the Unigine installation folder.

Unigine Controls the Main Loop#

In this case, the engine cycles through the main loop by itself.

Inside the custom class inherited from the Unigine::CustomApp class, you should implement virtual functions doUpdate(), doRender(), and doSwap() that must call the update(), render(), swap() functions respectively. These functions request the engine to update, render a world and swap render buffers.

Furthermore, the custom logic, which is implemented in the doUpdate(), doRender(), and doSwap() functions, will be performed on the corresponding stages of the main loop.

Source code (C++)
#include <UnigineEngine.h>
#include <UnigineCustomApp.h>

#include "AppSystemLogic.h"
#include "AppWorldLogic.h"
#include "AppEditorLogic.h"

using namespace Unigine;

class AppUser : public CustomApp
{
public:	
	// main loop
	virtual void doUpdate();
	virtual void doRender();
	virtual void doSwap();
	
	// list of other class methods and variables
	// list of overridden methods of the CustomApp class
	// ...
	
};

void AppUser::doUpdate()
{
	// some code that will be executed on the engine update 
	update();
	// some more code
}
void AppUser::doRender()
{
	// some code that will be executed on the engine render() function call 
	render();
	// some more code
}
void AppUser::doSwap()
{
	// some code that will be executed on the engine swap() function call
	swap();
	// some more code
}

/*
 */
#ifdef _WIN32
	int wmain(int argc,wchar_t *argv[]) 
	{
#else
	int main(int argc,char *argv[])
	{
#endif
	
	AppSystemLogic system_logic;
	AppWorldLogic world_logic;
	AppEditorLogic editor_logic;
	
	AppUser app;
	Unigine::EnginePtr engine(app,argc,argv);
	
	engine->main(&system_logic,&world_logic,&editor_logic);
	
	return 0;
}
Notice
The AppUser::setVideoMode() implementation should unconditionally call either initGL(), initD3D11() or initNULL() in order to correctly initialize the window.

Application Controls the Main Loop#

In this case, the application decides when update, rendering and swapping should be done.

Therefore, implementations of doUpdate(), doRender(), doSwap() functions can be left empty to ignore engine requests. The update(), render(), and swap() functions are called directly when necessary (e.g. when some message from the operating system is received).

Notice
This approach is used in the examples of the engine integration into the Qt application (see the source/app/main_qt folder).

In the example below, the AppUser::main() function manages the main loop: it handles events and call the update(), render() and swap() functions when some specific event occurs.

Source code (C++)
#include <UnigineEngine.h>
#include <UnigineCustomApp.h>

#include "AppSystemLogic.h"
#include "AppWorldLogic.h"
#include "AppEditorLogic.h"

using namespace Unigine;

class AppUser : public CustomApp
{
public:
	// main loop
	virtual void doUpdate();
	virtual void doRender();
	virtual void doSwap();
	
	void main();
	void paintEvent();
	// list of other class methods and variables
	// list of overridden methods of the CustomApp class
	// ...
	
};

// empty implementations
void AppUser::doUpdate() { }
void AppUser::doRender() { }
void AppUser::doSwap() { }

// application is smart enough to handle drawing by itself
void AppUser::main()
{

	// handle events that come from the operating system
	// ...
	// call the engine update(), render() and swap() functions when necessary
	if(some_event_occured)
	{
		paintEvent();
	}

}

// the paintEvent() function should be called in AppUser::main()
void AppUser::paintEvent()
{
	update();
	render();
	swap();
}

int main(int argc,char **argv)
{
	AppSystemLogic system_logic;
	AppWorldLogic world_logic;
	AppEditorLogic editor_logic;
	
	// declare the graphics application
	AppUser app;
	// initialize the engine to be used with the external graphics application (AppUser)
	Unigine::EnginePtr engine(app,argc,argv);
	
	// add system, world and editor logic instances to engine runtime
	engine->addSystemLogic(&system_logic);
	engine->addWorldLogic(&world_logic);
	engine->addEditorLogic(&editor_logic);
	
	// run the function that manages the main loop
	app.main();
	
	// shutdown the engine
	Engine::shutdown();
}
Notice
The AppUser::setVideoMode() implementation should unconditionally call either initGL(), initD3D11() or initNULL() in order to correctly initialize the window.
Last update: 13.12.2021
Build: ()