Где обычно размещается рендер, и куда его следует помещать?

Я разрабатываю приложение на C++ с использованием SDL2, и заметил, что SDL_Render привязан к каждому окну. Ранее, когда у меня было только одно окно, я использовал общий класс Object с указателем на SDL_Render, который передавал текущий рендер при создании объекта. Теперь, когда я добавил возможность создания нескольких окон, столкнулся с двумя подходами:

1) Принимать rендер в конструкторе. Однако это требует передавать рендер для каждого объекта, что выглядит не очень элегантно.
   
2) Передавать рендер при вызове метода OnRender. Но в этом случае возникает проблема с созданием текстур, которые требуют рендер, а создаются они вне метода OnRender.

Есть ли другие способы решения этой проблемы? Как реализован рендер в игровых движках или системах наподобие WPF? Я ранее использовал WPF и не замечал там подобных рендеров.
  • 30 августа 2024 г. 12:14
Ответы на вопрос 2
Ваш вопрос о том, как управлять рендером в приложении на C++ с использованием SDL2, особенно в контексте многопоточности с множеством окон, вполне распространен. Важно правильно организовать управление рендером, чтобы сделать его удобным и гибким. Давайте рассмотрим несколько подходов.

### Подходы к управлению рендером:

1. **Singleton-Pattern**:
    - Вы можете реализовать паттерн Singleton для вашего рендера. Это позволит иметь один доступный экземпляр рендерера на все окна.
    - Однако будьте осторожны: этот подход может привести к проблемам в многопоточном приложении и усложнить управление состоянием.

2. **Контекст рендеринга**:
    - Создайте класс `RenderContext`, который будет хранить рендеры для каждого окна. При создании объекта вы можете передавать текущий `RenderContext`, а не сам рендер. В `RenderContext` будет метод, который возвращает рендер для конкретного окна.

3. **Хранение рендерера в каждом объекте**:
    - Возможно, вам не нужно хранить рендер в каждом объекте, но лучше всего использовать ссылку на него (например, через `std::shared_ptr`), чтобы избежать лишних копий. 
    - В современных игровых движках часто используются системы, основанные на компонентах, где объекты могут иметь доступ к рендеру через менеджер или сцену.

4. **Менеджеры ресурсов**:
    - Создайте менеджер ресурсов, который будет управлять текстурами и материалами. Этот менеджер будет связан с определённым рендером.
    - У него будет метод для создания текстур, принимающий `SDL_Renderer`, что может быть сделано через указатель или ссылку, и структурируйте обращения к текстурам так, чтобы они возвращали нужный объект.

5. **Передача через параметры**:
    - Если у вас есть методы, которые отвечают за рендеринг, вы можете передавать рендер в параметры по мере необходимости. Это добавляет чёткую ответственность за рендеринг: каждый метод знает, какой рендер использовать.

### Аналогия с WPF:

В WPF рендеринг реализован через более высокоуровневые абстракции. WPF использует "бэкенды" рендеринга и привязывает их к элементам управления с помощью мощной системы привязки данных и событий, что упрощает процесс. Вы можете заметить, что в WPF процессы создания визуальных элементов отделены от рендеринга, и они управляются системой, которая автоматически определяет, когда и что рендерить.

### Рекомендации:

- Рассмотрите возможность полного отделения логики рендеринга от логики вашего приложения.
- Используйте паттерн проектирования, который облегчает управление состоянием и упрощает отладку.
- Создайте иерархию объектов, в которой более высокоуровневые сущности (например, сцены или уровни) могут управлять своими собственными окнами и рендерами.

Исходя из вашего опыта и предпочтений, вам придется выбрать наиболее подходящий подход, который будет соответствовать архитектуре вашего приложения и вашей команде.
Как рендер реализован например в игровых движках

Используется одно окно, которое сразу фуллскрин.
Ни разу не видел игр с несколькими окнами.

1) Принимать рендер в конструкторе.
Только одна проблема надо для каждого объекта передавать этот рендер. Что не хочется и выглядит как то не очень.

Нормально выглядит. DI через конструктор.
Похожие вопросы