Как создать OpenGL DirectX «Абстракционный слой» - PullRequest
6 голосов
/ 13 сентября 2010

Я читал о создании графических «слоев абстракции», чтобы было удобно переключаться между графическими платформами. К сожалению, я не смог найти подробностей по этому вопросу. Достижима ли эта абстракция на уровне функций чем-то вроде этого?

void pushMatrix(){
  if (directx){
     // do directx function

  }else if (opengl){
     // do opengl function
  }

}

Это так работает? Есть ли способ лучше? Может кто-нибудь указать мне несколько примеров того, что делает этот или несколько примеров кода?

Ответы [ 4 ]

7 голосов
/ 13 сентября 2010

Что обычно делается для того, чтобы иметь интерфейс к «универсальному» средству визуализации:

class RendererInterface{
    virtual DrawMesh() = 0;
    virtual SwapBuffers() = 0;
    /// etc
}

с одной реализацией для каждой библиотеки:

class OpenGLRenderer : public RendererInterface{
    virtual DrawMesh(){... }
    ....
}

Но концепция та жекак ответ Александра.

4 голосов
/ 13 сентября 2010

Да, вот как это работает. Абстрагируя используемый вами графический API, вы удаляете его из того, о чем должен беспокоиться программист. Это похоже на способ, которым GDI абстрагирует записываемое устройство, например, в том, что программисту не нужно беспокоиться об этом.

В этом смысле ваша библиотека функций, аналогичная приведенной выше, будет похожа на HDC. Это интерфейс этой абстракции.

Это будет сложнее, чем простая проверка API, затем вызов соответствующей функции (ей). Два API (DirectX и OpenGL) очень разные, и абстрагирование их обоих в единый интерфейс будет непростым, особенно если вы хотите охватить большую часть функциональности.

Вам потребуется больше абстракций, чем просто создание универсальных функций. Вам нужно будет создать более сложные структуры.

Предположим, что OpenGL требует, чтобы вы вызывали функцию A, затем функцию B, чтобы что-то произошло, но DX требовал, чтобы вы вызывали func B, а затем func A. Для этого вам нужно сделать что-то подобное: 1009 *

void functionA(...) {
  if (OpenGL) {
    glFuncA();
  } else {
    //store parameters
  }
}

void functionB(...) {
  if (OpenGL) {
    glFuncB();
  } else {
    dxFuncB();
    dxFuncA( saved params );
  }
}

Это не очень хороший пример, но он демонстрирует принцип. Создание абстракции для очень больших и разных API потребует много усилий и гораздо больше усилий, чем упаковка каждой функции.

3 голосов
/ 13 сентября 2010

Это закончится грязно и неэффективно. Я бы абстрагировался через граф сцены, т.е. имел бы обобщенное высокоуровневое представление «сцены». Затем эта сцена будет отображаться экземпляром «рендерера», который может быть реализован с использованием OpenGL или Direct3D.

Я предлагаю вам взглянуть на кроссплатформенный графический движок, такой как Ogre3d.

2 голосов
/ 13 октября 2011

Я согласен с mhutch 100%.Путем реструктуризации вашего рендерера, чтобы сосредоточиться на том, ЧТО он делает, а не на том, КАК это сделать, вы сделаете намного более чистый дизайн.быстро запутает программу.

Мой совет - просмотреть ваше приложение и составить список того, ЧТО оно делает, постарайтесь не обращать большого внимания на КАК.Это может быть слишком поздно для вашего проекта, я не знаю ваш конкретный сценарий, но (ИМХО) рефакторинг его из кошмара вызова API в нечто, что абстрагирует его достаточно, улучшит ваш конечный результат.

Хотя на первый взгляд вы можете подумать, что реализация системы графического отображения сцены добавит кучу накладных расходов.В действительности, я получил значительное ускорение с помощью своего механизма рендеринга, используя граф сцены для управления изменениями состояния - избегая изменений состояния (изменение текстур, изменение шейдеров и т. Д.) И рисуя сцену в гораздо более оптимальном порядке.Такие вещи, как создание экземпляров, элегантно интегрированы в систему графического отображения сцены и могут дать вам существенное ускорение, а также очистить весь код, связанный с API, от вашего кода и отделить «что он делает» от «как он это делает» в вашей основной системе.Программная логика.

...