Обозначение версий OpenGL

Здравствуйте.
Если опустить долгое предисловие, то есть разные версии OpenGL. Начиная с 3.х оно стало работать быстрее, но отвалилась поддержка старых видеокарт.
По-этому, если хочется, чтобы всё работало как на старых, так и на новых видеокартах, то надо писать два одинаковых проекта. Один с использованием OpenGL ниже 3.x, другой с 3.x или выше.
Собственно, я так и сделал. Код уже давно написан. Всё работает.
Но возникла проблема с нумерацией версий. Как обозначить, какую версию использует проект - ниже 3.x или выше?

Он же в 2008 вышел. Вам точно нужны видеокарты, которым 15 лет?)

Что за проект? Обычно надо только ту часть, которая собственно использует OpenGL (рендеринг, …). Точнее скорее даже не всю часть, они ж не убрали/заменили всё, что было до 3 )

Ну… я же не Крайзис свой собираюсь написать :man_shrugging: Там особая производительность не требуется.
Скорее всего, я просто забью на поддержку старых видеокарт. Но просто я хочу, чтобы хотя-бы первые версии запускались на относительно старых компьютерах со старой ОС (пусть и с потерей FPS).

Ой…Ой-ёй-ёй :grin: Даже не спрашивайте :grin: Это такая большая мега-глупость, что пока дело не дойдёт до чего-то более-менее презентабельного, об этом даже говорить стыдно :grin:

То есть? :thinking: Ведь всё-равно же придётся вести два отдельных проекта.

Если рендеринг нормально изолирован, то просто сделать две реализации этой части с одним интерфейсом (в смысле interface в C#, или просто функции с одинаковыми параметрами) и автоматически выбирать.

Естественно, я почти ни слова не понял :laughing:
Это, типо, разные рендереры в разных dll должны быть?

Да и в одной быть или вообще без длл вроде бы ничего не мешает.
C# и .NET | Применение интерфейсов

Просто присвоить в переменную соотв. реализацию или функцию.

IRenderer renderer = supportsOpengl3 ? new Opengl3Renderer() : new Opengl2Renderer();
renderer.render();

Спокойствие :grinning: Я знаю, что такое интерфейс. Не всё так плохо :slightly_smiling_face:
Просто я не представляю, как можно засунуть в интерфейс целый рендеринг :dizzy_face: Это ведь не просто функция.
В старом и новом OpenGL объекты создаются по-разному. Вертексные буфера создаются по-разному. И рендерить их тоже можно по-разному.
Да и сам контекст OpenGL ведь тоже по-разному создаётся и настраивается.

Так не важно, хоть Вулкан или DirectX, или ASCII )

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

Ну с отрисовкой еще как-то более-менее понятно, как её в интерфейс запихать.
А вот с созданием контекста как-то не очень.
Например, для старого OpenGL я просто создаю WinAPI окно, и делаю так:

        case WM_CREATE:
            hPanelRender = CreateWindow("Static", "OpenGL renderer",
                                        WS_CHILD | WS_VISIBLE | SS_BITMAP | SS_NOTIFY, 0, 0, 0, 0,
                                        wnd, NULL, myInstance, NULL);
            SetWindowLong(hPanelRender, GWL_WNDPROC, (long)&PanRenderProc);
            dcPanelRender = GetDC(hPanelRender);

            SetDCPixelFormat(dcPanelRender);
            dcGL = wglCreateContext(dcPanelRender);
            wglMakeCurrent(dcPanelRender, dcGL);

            glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
            glColor3f(1.0f, 1.0f, 1.0f);

            break;

        case WM_DESTROY:
            wglMakeCurrent(dcPanelRender, 0);
            wglDeleteContext(dcGL);

            ReleaseDC(hPanelRender, dcPanelRender);

            PostQuitMessage(0);

            break;

А для нового использую GLFW (потому что не знаю, как сделать это на WinAPI):

    if (!glfwInit())
    {
        std::cout << "glfwInit() failed!" << std::endl;
        return 1;
    }

	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    GLFWwindow* glfwWindow = glfwCreateWindow(screenWidth, screenHeight,
                                              (char*)"camera test", nullptr, nullptr);
    if (!glfwWindow)
    {
        glfwTerminate();
        std::cout << "glfwCreateWindow() failed!" << std::endl;
        return 1;
    }
    glfwMakeContextCurrent(glfwWindow);

    glewExperimental = true;
    if (glewInit() != GLEW_OK)
    {
        glfwTerminate();
        std::cout << "glewInit() failed!" << std::endl;
        return 1;
    }

//....и тут ещё куча кода

Можно просто и для старого взять GLFW )

Да я знаю :slightly_smiling_face: Но всё-равно пока не особо понятно, как создание в интерфейс запихнуть.
По-идее, должен быть какой-то базовый интерфейс IOpenGlBase. А от него наследуем два других : IOpenGlNew и IOpenGlLegacy :thinking:
В правильном направлении мыслю?

Ну если начинать менять прямо с создания окна, то тогда нужны еще абстракции для этого, как всякие GUI фреймворки типа Qt.
И тогда проще взять Qt и его виджет для OpenGL )

Как вариант можно было бы прицепить GLFW к созданному ранее винапи окну, но GLFW вроде пока не умеет так.

https://github.com/glfw/glfw/issues/25

Начинать менять что? :thinking: Ещё толком и нет ничего, кроме двух полу-рабочих прототипов.

Это я правильно предположил?

Какие абстракции? Для событий окна и клавиатуры с мышью?

Ну если окно всегда одинаково создается, и менять только функцию отрисовки внутри него, то всё просто.
А если окно надо создавать по-разному, и потом еще и взаимодействовать с окном разными способами, то всё сложнее, тогда еще надо создавать абстракции вокруг этого (разные реализации окна, …, типа WinApiWindow, GlfwWindow наследующие/реализующие Window).
Но GLFW же сам является такой абстракцией. Поэтому

А, ну да, я так и подумал

Это всё, конечно, замечательно. Но задача еще в том, чтобы программа могла работать на Windows XP. Да, я мазохист и мне нечем заняться :man_shrugging:
А это значит, что никакие новые фреймворки не подойдут. Просто запихнуть рендереры в интерфейсы - ничего не даст. Чтобы работало на ХР, надо писать на Java. Так оно, заодно, и в линуксе нативно запустится. Нафига? Ну вот приспичило. Хочу и всё тут :man_shrugging:
Собственно, я всё уже давно написал. Работает и на Java и на старом компе с ХР и в линуксе (только код надо отрефакторить и оптимизировать, контроль версий включить).
Осталась только одна проблема. Как-то пометить одну из версий, что она использует старый OpenGL. А ту, которая использует новый, можно оставить вообще без метки.
В интернете видел, что старый OpenGL иногда называют Legacy (а новый Modern). Но не знаю, насколько корректно так делать :man_shrugging:
Получается, что версия будет выглядеть как-то так: MyDreamProject-0.5.2-alpha-legacy :thinking: