2010-05-24 11 views
30

Me gustaría tener un contexto OpenGL sin ventanas (en GNU/linux con Xorg y Windows). No voy a procesar nada, solo llamaré a funciones como glGetString, glCompileShader y similares.WindowGL OpenGL

He hecho algunas goggles pero no he encontrado nada útil, excepto crear una ventana oculta; que me parece un truco.

¿Alguien tiene una mejor idea (para cualquier plataforma)?

EDIT: Con Xorg que fue capaz de crear y adjuntar un contexto OpenGL a la raíz-ventana:

#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: He escrito un breve artículo sobre windowless opengl (con código de ejemplo) en base a la respuesta aceptada

+1

Uso GetDesktopWindow para la plataforma Windows. – Luca

Respuesta

21

En realidad, es necesario tener un identificador de ventana para crear un contexto de representación "tradicional" (la ventana raíz en X11 o la ventana del escritorio en Windows son buenas para esto). Se usa para obtener información de OpenGL y disponibilidad de extensiones.

¡Una vez que obtuviste esa información, puedes destruir el contexto del renderizado y liberar la ventana "ficticia"!

Debe probar para las extensiones ARB_extensions_string y ARB_create_context_profile, (descrito en estas página: ARB_create_context). A continuación, puede crear un contexto rendir llamando CreateContextAttribs, de una manera independiente de la plataforma, sin tener una ventana del sistema asociado y que sólo requiere el contexto de dispositivo del sistema:

 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"); 

Entonces, se podría asociar un marco el objeto del búfer o una ventana del sistema al contexto del renderizado creado, si desea renderizar (pero, según tengo entendido, solo desea compilar shaders).

Usando CreateContextAttribs tiene muchas ventajas:

  • Es independiente de la plataforma
  • Es posible solicitar OpenGL específico de aplicación
  • Es posible solicitud de aplicación a> 3,2 OpenGL
  • Es posible a efecto la opción de compatibilidad con versiones posteriores (shader única representación, que es la forma futura)
  • Es posible seleccione (en un contexto compatible sólo hacia adelante) un perfil de aplicación OpenGL específica (en realidad sólo existe el perfil básico , pero podría haber más en el futuro.
  • Es posible habilitar una opción de depuración, incluso si no se define cómo esta opción podría ser utilizado por la implementación real del conductor

Sin embargo, el hardware antiguo/conductores no podían implementos esta extensión, de hecho sugiero escribir un código alternativo para crear un contexto compatible hacia atrás.

+0

Esto parece lo que estoy buscando, lo probaré. – ext

+0

¿cómo haces lo mismo en Windows? –

+0

@PetarIvanov Exactamente con el mismo ejecutable, usando C#. Sin embargo, toda la API de OpenGL es portátil. – Luca

2

Necesita una ventana para alojar el contexto y necesita un contexto para poder hacer cualquier cosa.

Source

Si no desea mostrar algo que la haga la ventana invisible.

Si hay otra forma de hacerlo, se documentará en alguna parte y se encontrará fácilmente, ya que no es un problema poco común.

7

Hasta que crea una ventana, OpenGL no tiene idea de qué implementación utiliza. Por ejemplo, hay un controlador muy diferente (y una aceleración de hardware diferente) para OpenGL en una sesión remota de X-Windows frente a OpenGL en una sesión de DRI X-Windows. El soporte del lenguaje Shader puede ser diferente entre estos casos, y el resultado del compilador shader dependerá definitivamente de la implementación, así como también de los errores generados en función del agotamiento de los recursos. Así que aunque crear una ventana puede no ser 100% necesario, debe asociar su contexto con el hardware gráfico (o la falta) de alguna manera, y como esto puede hacerse con una ventana, nadie se molestó en implementar un método alternativo .

+0

¿Qué tal crear un contexto y asociarlo con la ventana raíz? – ext

+0

@ext: suena como un enfoque razonable. Tenga en cuenta que no fue necesario escribir ningún código adicional para que OpenGL maneje ese caso, todavía es "asociar un nuevo contexto con alguna ventana", en oposición a "asociar un nuevo contexto con esta tarjeta gráfica y no, no tengo una ventana" . Solo tenga cuidado de no renderizar en la ventana raíz. –

1

Una de las cosas que he hecho, que sin duda es un truco, para evitar la sobrecarga de crear mi propia ventana GL, es aprovechar las ventanas abiertas del proceso.

La clave para comprender OpenGL es esta: todo lo que necesita para crear un contexto GL con la llamada a wglCreateContext es un DC válido.

No hay NADA en la documentación que indique que tiene que ser de su propiedad.

Para probar esto, apareció Worlds Of Warcraft, y aprovechando SPY ++ para obtener un identificador de ventana, luego conecté manualmente ese identificador en una llamada a GetDC, que devuelve un Contexto de dispositivo válido, y desde allí, ejecuté el resto de mi código GL como normal.

Sin creación de ventanas GL propias.

Aquí es lo que pasó cuando hice esto con ambos mundos de Warcraft y Star Trek Online https://universalbri.wordpress.com/2015/06/05/experiment-results

Así que para responder a su pregunta, sí usted no necesita una ventana, pero no hay nada en la documentación que establece que la ventana necesita ser propiedad de usted

Ahora tenga en cuenta: No pude obtener este método para proporcionar resultados visuales válidos usando la ventana del escritorio, pero pude crear con éxito un DC utilizando la API getDeskTopWindow para el HWND y luego una llamada a GetDC. Entonces, si hay un procesamiento no visual para el que desea usar OpenGL, déjeme saber lo que está haciendo, tengo curiosidad, y si UD. Obtiene el método GetDesktopWindow trabajando con las imágenes, POR FAVOR vuelva a publicar en este hilo lo que hizo.

Buena suerte.

Y no permita que nadie le diga que no se puede hacer.

Cuando hay voluntad, hay una manera.