Я пытаюсь написать графическое приложение на C ++. В настоящее время он использует OGRE для отображения, но я бы хотел, чтобы он работал с Irrlicht или любым другим движком, даже с пользовательским механизмом рендеринга, который поддерживает мои потребности. Это довольно длинный вопрос, поэтому я буду признателен за помощь в повторной пометке / очистке (при необходимости). Начну с небольшого фона.
Приложение имеет три основных состояния:
1. Отображение растрированной сцены
2. Отображение версии трассированной трассы той же сцены
3. Показать гибридную версию сцены
Очевидно, я могу разделить свое приложение на четыре основные части:
1. Система управления состоянием для переключения между вышеуказанными режимами.
2. Система ввода, которая может принимать ввод с клавиатуры и мыши.
3. Растровый движок, используемый для отображения.
4. Система трассировки лучей.
Любое приложение, охватывающее вышеперечисленное, должно иметь возможность:
1. Создайте окно.
2. Выполните все шаги, необходимые для разрешения рендеринга в этом окне.
3. Инициализируйте систему ввода.
4. Инициализируйте менеджер состояния.
5. Начните цикл (и рендеринг!).
Я хочу иметь возможность изменять механизм рендеринга / менеджер состояний / систему ввода / систему трассировки лучей в любое время, при условии соблюдения определенных минимальных требований. Имхо, это требует отделения интерфейса от реализации. Имея это в виду, я создал интерфейсы для вышеуказанных систем.
В этот момент я заметил, что приложение также имеет общий «интерфейс». Поэтому я решил абстрагировать его в класс ApplicationBase с помощью виртуальных методов. Конкретное приложение, такое как приложение, которое использует OGRE для создания окон, рендеринга и т. Д., Будет производным от этого класса и реализует его.
Мой первый вопрос - это хорошая идея для такого дизайна?
Вот код для базового класса:
#ifndef APPLICATION_H
#define APPLICATION_H
namespace Hybrid
{
//Forward declarations
class StateManager;
class InputSystem;
//Base Class for all my apps using hybrid rendering.
class Application
{
private:
StateManager* state_manager;
InputSystem* input_system;
public:
Application()
{
try
{
//Create the state manager
initialise_state_manager();
//Create the input system
initialise_input_system();
}
catch(...) //Change this later
{
//Throw another exception
}
}
~Application()
{
delete state_manager;
delete input_system;
}
//If one of these fails, it throws an
//exception.
virtual void initialise_state_manager() = 0;
virtual void initialise_input_system() = 0;
virtual void create_window() = 0;
//Other methods.
};
#endif
Когда я использую OGRE, я полагаюсь на OGRE, чтобы создать окно. Это требует инициализации OGRE перед вызовом функции createWindow () в моем производном классе. Конечно, как и прежде, createWindow будет вызываться первым! Это оставляет меня со следующими параметрами:
1. Оставьте конструктор базового класса пустым.
2. В реализации производного класса сделайте инициализацию OGRE частью функции createWindow.
3. Добавить инициализирующую систему визуализации чисто виртуальную функцию в мой базовый класс. Это создает риск принудительной реализации в производных классах, которые не используют такой метод.
Мой второй вопрос: каковы ваши рекомендации по выбору одной из этих стратегий для инициализации OGRE?