Я хотел бы иметь контекст OpenGL без окон (и на GNU/linux с Xorg и на Windows). Я не собираюсь представлять что-либо, но только вызывать функции как glGetString
, glCompileShader
и подобный.
Я сделал некоторых таращение глаза, но не придумал что-либо полезное, кроме создания скрытого окна; который походит на взлом мне.
У кого-либо есть лучшая идея (для какой-либо платформы)?
Править: С Xorg я смог создать и присоединить контекст OpenGL к корневому окну:
#include
#include
#include
#include
#include
#include
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 без окон (с примером кода) на основе принятого ответа.
Вообще-то, для создания "традиционного" контекста рендеринга необходимо иметь хэндл окна (для этого хорошо подходит корневое окно в 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 понятия не имеет, какую реализацию вы используете. Например, для OpenGL в удаленной сессии X-Windows и OpenGL в сессии DRI X-Windows существует совершенно разный драйвер (и разное аппаратное ускорение). Поддержка языка шейдеров может быть разной в этих случаях, а вывод компилятора шейдеров определенно будет зависеть от реализации, как и любые ошибки, возникающие на основе исчерпания ресурсов.
Таким образом, хотя создание окна, возможно, не является на 100% необходимым, вам нужно как-то связать ваш контекст с графическим оборудованием (или его отсутствием), и поскольку это можно сделать с помощью окна, никто не потрудился реализовать альтернативный метод.