Wie Sie so viele Informationen wie möglich über einen OpenGL-Kontext erhalten

Hallo Welt und danke, dass du dir die Zeit genommen hast, das zu lesen!

Ich schreibe ein Programm in GTK2 / 3 + OpenGL, ich habe zwei Versionen des Programms ausgeführt:

(a) GTK + 2 + GtkGlext Extention -> funktioniert super! (b) GTK + 3 + LibX11 -> funktioniert einwandfrei!

Alles sieht gut aus, außer dass das Rendern in (a) deutlich schneller ist als das Rendern in (b) ... und ich habe keine Ahnung warum. Hier sind einige Beispiele für die Codeteile, die zum Erstellen des OpenGL-Kontexts verwendet werden:

(ein

// To create the context, and the associated GtkWidget 

GdkGLConfig * glconfig = gdk_gl_config_new_by_mode (GDK_GL_MODE_RGBA | GDK_GL_MODE_DEPTH | GDK_GL_MODE_DOUBLE);
GtkWidget * drawing_area = gtk_drawing_area_new ();
gtk_widget_set_gl_capability (drawing_area, glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE);
g_signal_connect (G_OBJECT (drawing_area), "expose-event", G_CALLBACK (on_expose), data);

// And later on to draw using the OpenGL context: 

gboolean on_expose (GtkWidget * widg, GdkEvent * event, gpointer data)
{
  GdkGLContext * glcontext  = gtk_widget_get_gl_context (widg);
  GdkGLDrawable * gldrawable = gtk_widget_get_gl_drawable (widg);
  if (gdk_gl_drawable_gl_begin (gldrawable, glcontext))
  {
    // OpenGL instructions to draw here !
    gdk_gl_drawable_swap_buffers (view -> gldrawable);
    gdk_gl_drawable_gl_end (view -> gldrawable);
  }
  return TRUE;
}

(b)

// To create the GtkWidget 

 GtkWidget * drawing_area = gtk_drawing_area_new ();
 // Next line is required to avoid background flickering
 gtk_widget_set_double_buffered (drawing_area, FALSE);
 g_signal_connect (G_OBJECT (drawing_area), "realize", G_CALLBACK(on_realize), data);
 g_signal_connect (G_OBJECT (drawing_area), "draw", G_CALLBACK(on_expose), data);

// To create the OpenGL context

GLXContext glcontext;

G_MODULE_EXPORT void on_realize (GtkWidget * widg, gpointer data)
{
  GdkWindow * xwin = gtk_widget_get_window (widg);
  GLint attr_list[] = {GLX_DOUBLEBUFFER,
                       GLX_RGBA,
                       GLX_DEPTH_SIZE, 16,
                       GLX_RED_SIZE,   8,
                       GLX_GREEN_SIZE, 8,
                       GLX_BLUE_SIZE,  8,
                       None};
   XVisualInfo * visualinfo = glXChooseVisual (GDK_WINDOW_XDISPLAY (xwin), gdk_screen_get_number (gdk_window_get_screen (xwin)), attr_list);
   glcontext = glXCreateContext (GDK_WINDOW_XDISPLAY (xwin), visualinfo, NULL, TRUE);
   xfree (visualinfo);
}

// To Draw using the OpenGL context

G_MODULE_EXPORT gboolean on_expose (GtkWidget * widg, cairo_t * cr, gpointer data)
{
  GdkWindow * win = gtk_widget_get_window (widg);
  if (glXMakeCurrent (GDK_WINDOW_XDISPLAY (xwin), GDK_WINDOW_XID (xwin), glcontext))
  {
     // OpenGL instructions to draw here !
     glXSwapBuffers (GDK_WINDOW_XDISPLAY (win), GDK_WINDOW_XID (win));
   }
   return TRUE;
}

Versuche zu verstehen, warum (a) schneller war als (b) Ich habe die Quellen der GtkGLext-Bibliothek heruntergeladen, sie gelesen und festgestellt, dass die Befehle bei einem Aufruf von X11 genau gleich waren. Jetzt sind meine Gedanken entweder die folgende Zeile in (b)

gtk_widget_set_double_buffered (drawing_area, FALSE);

Mischt sich mit dem Rendering herum, und dann kann ich nichts tun ... oder es gibt / gibt Unterschiede zwischen den OpenGL-Kontexten, die möglicherweise das von mir festgestellte Verhalten erklären. Wenn ich in diese Richtung folge, muss ich vergleichen beide Zusammenhänge so detailliert wie möglich ... bis jetzt habe ich die gängigste Methode ausgewählt, um an Informationen zu gelangen:

OpenGL Version                  : 3.0 Mesa 12.0.3
OpenGL Vendor                   : nouveau
OpenGL Renderer                 : Gallium 0.4 on NVCF
OpenGL Shading Version          : 1.30

Color Bits (R,G,B,A)            : 8, 8, 8, 0
Depth Bits                      : 24
Stencil Bits                    : 0
Max. Lights Allowed             : 8
Max. Texture Size               : 16384
Max. Clipping Planes            : 8
Max. Modelview Matrix Stacks    : 32
Max. Projection Matrix Stacks   : 32
Max. Attribute Stacks           : 16
Max. Texture Stacks             : 10

Total number of OpenGL Extensions   : 227
Extensions list:
     N°1    :   GL_AMD_conservative_depth
     N°2    :   GL_AMD_draw_buffers_blend
 ...

Aber beide Kontexte geben genau die gleichen Informationen zurück ...

Danke, dass du schon da bist ... jetzt ist meine Frage:

Gibt es eine Möglichkeit, so viele Informationen wie möglich über einen OpenGL-Kontext auszugeben, und wie?

Ich freue mich über jeden weiteren Vorschlag!

S.

PS: Ich arbeite an der Verwendung des GtkGLArea-Widgets für GTK3, aber wie angegebenHie Ich bin noch nicht da.

[EDIT] Einige der OpenGL-Anweisungen:

// OpenGL instructions to draw here !

glLoadIdentity (); 
glPushMatrix ();
// d is the depth ... calculated somewhere else
glTranslated (0.0, 0.0, -d); 
// Skipping the rotation part for clarity, I am using a quaternion
rotate_camera (); 
// r, g, b and a are GLFloat values
glClearColor (r,g,b,a); 
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); 
glDisable (GL_LIGHTING);
int i;
// nbds is the number of chemical bonds 
GLfloat * lineVertices;
// This is "roughly" what I do to draw chemical bonds, to give you an idea
for (i=0; i<nbds;i++)
{
   // get_bonds (i) gives backs a 6 float array
   lineVertices = get_bonds(i);
   glPushMatrix(); 
   glLineWidth (1.0); 
   glEnableClientState (GL_VERTEX_ARRAY); 
   glVertexPointer (3, GL_FLOAT, 0, lineVertices); 
   glDrawArrays (GL_LINES, 0, 2); 
   glDisableClientState (GL_VERTEX_ARRAY); 
   glPopMatrix();
}
glEnable (GL_LIGHTING);

[/BEARBEITEN

Antworten auf die Frage(2)

Ihre Antwort auf die Frage