Подтвердить что ты не робот

Без окон OpenGL

Я хотел бы иметь контекст OpenGL без окон (на GNU/Linux с Xorg и Windows). Я не собираюсь ничего делать, кроме как только функции вызова, такие как glGetString, glCompileShader и тому подобное.

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

У кого-то есть лучшая идея (для любой платформы)?

EDIT: с Xorg мне удалось создать и прикрепить контекст OpenGL к корневому окну:

#include<stdio.h>
#include<stdlib.h>
#include<X11/X.h>
#include<X11/Xlib.h>
#include<GL/gl.h>
#include<GL/glx.h>

int main(int argc, const char* argv[]){
  Display *dpy;
  Window root;
  GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
  XVisualInfo *vi;
  GLXContext glc;

  dpy = XOpenDisplay(NULL);

  if ( !dpy ) {
    printf("\n\tcannot connect to X server\n\n");
    exit(0);
  }

  root = DefaultRootWindow(dpy);
  vi = glXChooseVisual(dpy, 0, att);

  if (!vi) {
    printf("\n\tno appropriate visual found\n\n");
    exit(0);
  }

  glc = glXCreateContext(dpy, vi, NULL, GL_TRUE);
  glXMakeCurrent(dpy, root, glc);

  printf("vendor: %s\n", (const char*)glGetString(GL_VENDOR));

  return 0;
}

EDIT2: Я написал короткую статью о windowless opengl (с образцом кода) на основе принятого ответа.

4b9b3361

Ответ 1

На самом деле, необходимо создать дескриптор окна для создания "традиционного" контекста рендеринга (для этого подходят корневое окно на X11 или окно рабочего стола Windows). Он используется для получения информации о доступности и расширениях OpenGL.

Как только вы получите эту информацию, вы можете уничтожить контекст визуализации и отпустить окно "dummy"!

Вы должны проверить расширения ARB_extensions_string и ARB_create_context_profile (описанные на этой странице: ARB_create_context). Затем вы можете создать контекст визуализации, вызвав CreateContextAttribs, независимо от платформы, без связанного системного окна и требующего только контекста системного устройства:

        int[] mContextAttrib = new int[] {
            Wgl.CONTEXT_MAJOR_VERSION, REQUIRED_OGL_VERSION_MAJOR,
            Wgl.CONTEXT_MINOR_VERSION, REQUIRED_OGL_VERSION_MINOR,
            Wgl.CONTEXT_PROFILE_MASK, (int)(Wgl.CONTEXT_CORE_PROFILE_BIT),
            Wgl.CONTEXT_FLAGS, (int)(Wgl.CONTEXT_FORWARD_COMPATIBLE_BIT),
            0
        };


        if ((mRenderContext = Wgl.CreateContextAttribs(mDeviceContext, pSharedContext, mContextAttrib)) == IntPtr.Zero)
            throw new Exception("unable to create context");

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

Использование CreateContextAttribs имеет много преимуществ:

  • независимая от платформы
  • Можно запросить конкретную реализацию OpenGL
  • Возможно запросить реализацию 3.2 OpenGL
  • Возможно форсировать опцию прямой совместимости (только шейдерный рендеринг, что будет в будущем)
  • Возможно выбрать (только в прямом совместимом контексте) конкретный профиль реализации OpenGL (на самом деле существует только профиль CORE, но может быть больше в будущее.
  • Возможно включить параметр отладки, даже если не определено, как этот параметр может использоваться фактической реализацией драйвера

Однако старые аппаратные средства/драйверы не смогли реализовать это расширение, поэтому я предлагаю написать резервный код, чтобы создать обратный совместимый контекст.

Ответ 2

Пока вы не создадите окно, OpenGL не знает, какую реализацию вы используете. Например, существует очень другой драйвер (и разное аппаратное ускорение) для OpenGL в удаленном сеансе X-Windows против OpenGL в сеансе DRI X-Windows. Поддержка шейдерных языков может быть разной между этими случаями, и вывод шейдерного компилятора определенно будет зависящим от реализации, а также любые ошибки, созданные на основе исчерпания ресурсов.

Таким образом, хотя фактически создание окна может быть не на 100% необходимым, вы должны каким-то образом связать свой контекст с графическим оборудованием (или его отсутствием), и поскольку это можно сделать с помощью окна, никто не беспокоился о внедрении альтернативного метода.

Ответ 3

Вам нужно окно для размещения контекста, и вам нужен контекст, чтобы иметь возможность сделать что-либо.

Источник

Если вы не хотите отображать что-либо, сделайте окно невидимым.

Если бы был другой способ сделать это, он был бы где-то документирован и легко найден, поскольку это не необычная проблема.

Ответ 4

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

Ключом к пониманию OpenGL является следующее: все, что вам нужно для создания контекста GL с вызовом wglCreateContext, является допустимым DC.

В документации, в которой говорится, что она должна быть тем, кем вы являетесь, нет НИЧЕГО.

Чтобы проверить это, я вытащил Worlds Of Warcraft и, используя SPY ++, чтобы получить дескриптор окна, я вручную подключил этот дескриптор к вызову GetDC, который возвращает действительный контекст устройства, и оттуда я запускал остальная часть моего кода GL, как обычно.

Нет создания окна GL моего собственного.

Вот что произошло, когда я сделал это с помощью Worlds of Warcraft и Star Trek Online https://universalbri.wordpress.com/2015/06/05/experiment-results

Итак, чтобы ответить на ваш вопрос, ДА вам нужно окно, но в документации нет ничего, что говорит о том, что окно должно принадлежать вам.

Теперь имейте в виду: я не мог заставить этот метод предоставлять действительный визуальный результат с помощью окна рабочего стола, но мне удалось успешно создать DC, используя API-интерфейс getDeskTopWindow для HWND, а затем вызов GetDC. Поэтому, если есть не визуальная обработка, которую вы хотите использовать OpenGL, дайте мне знать, что вы делаете, мне интересно, и если вам нужно получить метод GetDesktopWindow, работающий с визуальными эффектами, - ПОЖАЛУЙСТА, повторите в этой теме то, что вы сделали.

Удачи.

И не позволяйте никому говорить вам, что это невозможно.

Когда там будет какой-то способ.