Fensterloses OpenGL

Lesezeit: 6 Minuten

Benutzer-Avatar
ext

Ich hätte gerne einen fensterlosen OpenGL-Kontext (sowohl unter GNU/Linux mit Xorg als auch unter Windows). Ich werde nichts rendern, sondern nur Funktionen wie aufrufen glGetString, glCompileShader und ähnliches.

Ich habe etwas gegoogelt, bin aber auf nichts Nützliches gekommen, außer ein verstecktes Fenster zu erstellen; das scheint mir ein Hack zu sein.

Hat jemand eine bessere Idee (für jede Plattform)?

BEARBEITEN: Mit Xorg konnte ich einen OpenGL-Kontext erstellen und an das Root-Fenster anhängen:

#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: Ich habe einen kurzen Artikel darüber geschrieben fensterlos offengl (mit Beispielcode) basierend auf der akzeptierten Antwort.

  • Verwenden Sie GetDesktopWindow für die Windows-Plattform.

    – Lukas

    25. Mai 2010 um 21:09 Uhr

Benutzer-Avatar
Lukas

Tatsächlich ist es notwendig, ein Fenster-Handle zu haben, um einen “traditionellen” Rendering-Kontext zu erstellen (das Root-Fenster auf X11 oder das Desktop-Fenster auf Windows sind dafür gut geeignet). Es wird verwendet, um OpenGL-Informationen und die Verfügbarkeit von Erweiterungen abzurufen.

Sobald Sie diese Informationen erhalten haben, können Sie den Renderkontext zerstören und das “Dummy”-Fenster freigeben!

Sie sollten die Erweiterungen testen ARB_extensions_string und ARB_create_context_profile(beschrieben auf dieser Seite: ARB_create_context). Anschließend können Sie durch Aufrufen einen Renderkontext erstellen CreateContextAttribsplattformunabhängig, ohne dass ein Systemfenster zugeordnet ist und nur der Systemgerätekontext erforderlich ist:

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

Dann könnten Sie dem erstellten Renderkontext ein Bildpufferobjekt oder ein Systemfenster zuordnen, wenn Sie rendern möchten (aber wie ich verstehe, möchten Sie nur Shader kompilieren).

Verwenden CreateContextAttribs hat viele Vorteile:

  • es ist Plattformunabhängig
  • Anfrage möglich spezifische OpenGL-Implementierung
  • Es ist möglich Fordern Sie eine > 3.2 OpenGL-Implementierung an
  • Es ist möglich Erzwinge die Aufwärtskompatibilitätsoption (nur Shader-Rendering, das ist der zukünftige Weg)
  • Es ist möglich auswählen (nur in einem aufwärtskompatiblen Kontext) ein spezifisches OpenGL-Implementierungsprofil (eigentlich gibt es nur das CORE-Profil, aber es könnte in Zukunft noch mehr geben.
  • Es ist möglich Aktivieren Sie eine Debugging-Optionauch wenn nicht definiert ist, wie diese Option von der eigentlichen Treiberimplementierung verwendet werden könnte

Ältere Hardware/Treiber konnten diese Erweiterung jedoch nicht implementieren, ich schlage sogar vor, einen Fallback-Code zu schreiben, um einen abwärtskompatiblen Kontext zu schaffen.

  • wie machst du das gleiche unter Windows?

    – Petar Iwanow

    24. Oktober 2014 um 20:32 Uhr

  • @PetarIvanov Genau mit derselben ausführbaren Datei unter Verwendung von C#. Alle OpenGL-APIs sind jedoch portabel.

    – Lukas

    5. Februar 2015 um 0:00 Uhr

Bis Sie ein Fenster erstellen, hat OpenGL keine Ahnung, welche Implementierung Sie verwenden. Beispielsweise gibt es einen ganz anderen Treiber (und eine andere Hardwarebeschleunigung) für OpenGL in einer Remote-X-Windows-Sitzung im Vergleich zu OpenGL in einer DRI-X-Windows-Sitzung. Die Unterstützung der Shader-Sprache kann in diesen Fällen unterschiedlich sein, und die Ausgabe des Shader-Compilers wird definitiv von der Implementierung abhängig sein, ebenso wie alle Fehler, die aufgrund von Ressourcenerschöpfung generiert werden.

Während das Erstellen eines Fensters möglicherweise nicht zu 100% erforderlich ist, müssen Sie Ihren Kontext irgendwie mit der Grafikhardware (oder deren Fehlen) in Verbindung bringen, und da dies mit einem Fenster möglich ist, hat sich niemand die Mühe gemacht, eine alternative Methode zu implementieren.

  • Wie wäre es, einen Kontext zu erstellen und ihn mit dem Root-Fenster zu verknüpfen?

    – Durchwahl

    24. Mai 2010 um 12:45 Uhr

  • @ext: Klingt nach einem vernünftigen Ansatz. Beachten Sie, dass für OpenGL kein zusätzlicher Code geschrieben werden musste, um diesen Fall zu handhaben. Es ist immer noch “einen neuen Kontext mit einem Fenster verknüpfen”, im Gegensatz zu “einen neuen Kontext mit dieser Grafikkarte verknüpfen und nein, ich habe kein Fenster”. . Achten Sie nur darauf, nicht tatsächlich im Root-Fenster zu rendern.

    – Ben Voigt

    24. Mai 2010 um 18:55 Uhr

Benutzer-Avatar
ChrisF

Sie brauchen ein Fenster, um den Kontext zu hosten, und Sie brauchen einen Kontext, um irgendetwas tun zu können.

Quelle

Wenn Sie nichts anzeigen möchten, machen Sie das Fenster unsichtbar.

Wenn es einen anderen Weg gäbe, dies zu tun, wäre es irgendwo dokumentiert und leicht zu finden, da es kein ungewöhnliches Problem ist.

Eines der Dinge, die ich getan habe – was zugegebenermaßen ein bisschen wie ein Hack ist – um den Aufwand für die Erstellung meines eigenen GL-Fensters zu vermeiden – ist, offene Prozessfenster zu nutzen.

Der Schlüssel zum Verständnis von OpenGL ist folgender: Alles, was Sie brauchen, um einen GL-Kontext mit dem Aufruf von wglCreateContext zu erstellen, ist ein gültiger DC.

In der Dokumentation steht NICHTS, was besagt, dass es eines sein muss, das Ihnen gehört.

Um dies zu testen, habe ich Worlds Of Warcraft aufgerufen und SPY++ genutzt, um ein Fenster-Handle zu erhalten. Ich habe dieses Handle dann manuell in einen Aufruf an GetDC gesteckt, der einen gültigen Gerätekontext zurückgibt, und von dort aus habe ich den Rest von mir ausgeführt GL-Code wie normal.

Keine eigene Erstellung von GL-Fenstern.

Folgendes ist passiert, als ich das sowohl mit Worlds of Warcraft als auch mit Star Trek Online gemacht habe https://universalbri.wordpress.com/2015/06/05/experiment-results

Um Ihre Frage zu beantworten: JA, Sie benötigen ein Fenster, aber in der Dokumentation steht nichts, was besagt, dass dieses Fenster Ihnen gehören muss.

Jetzt sei darauf hingewiesen: Ich konnte diese Methode nicht dazu bringen, eine gültige visuelle Ausgabe mit dem Desktop-Fenster bereitzustellen, aber ich konnte erfolgreich einen DC erstellen, indem ich die getDeskTopWindow-API für das HWND und dann einen Aufruf an GetDC verwendete. Also, wenn es eine nicht visuelle Verarbeitung gibt, für die Sie OpenGL verwenden möchten – lassen Sie mich wissen, was Sie tun, ich bin neugierig, und wenn Sie die GetDesktopWindow-Methode mit den visuellen Elementen zum Laufen bringen – posten Sie BITTE in diesem Thread erneut, was Sie getan haben.

Viel Glück.

Und lass dir von niemandem sagen, dass es nicht geht.

Wo ein Wille ist, ist auch ein Weg.

Mit GLFWkönnen Sie dies tun, indem Sie Einstellung einer einzigen <VISIBLE: FALSE> Fensterhinweis

1382310cookie-checkFensterloses OpenGL

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy