OpenGL без окон - PullRequest
       24

OpenGL без окон

31 голосов
/ 24 мая 2010

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

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

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

РЕДАКТИРОВАТЬ: С 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: я написал небольшую статью о opengl без окон (с примером кода) на основе принятого ответа.

Ответы [ 5 ]

21 голосов
/ 25 мая 2010

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

После того, как вы получили эту информацию, вы можете уничтожить контекст рендеринга и открыть «фиктивное» окно!

Вы должны проверить расширения 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, но в будущем их может быть больше.
  • Можно включить опцию отладки , даже если не определено, как эта опция может использоваться реальной реализацией драйвера

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

7 голосов
/ 24 мая 2010

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

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

2 голосов
/ 24 мая 2010

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

Источник

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

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

1 голос
/ 23 февраля 2018
1 голос
/ 23 июня 2015

Одна из вещей, которые я сделал - по общему признанию, немного хакерская - чтобы избежать накладных расходов на создание моего собственного окна 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 для работы с визуалами - ПОЖАЛУЙСТА, перепечатайте в этом потоке то, что вы сделали.

Удачи.

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

Когда есть желание, есть способ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...