如何获得关于OpenGL上下文的尽可能多的信息 [英] How to get as many information as possible about an OpenGL context
问题描述
我正在写一个GTK2 / 3 + OpenGL程序,我有两个版本的程序运行:
除了(a)中的渲染显着更快(b)中的渲染......我不知道为什么。 (a) (b)
下面是一些用于创建OpenGL上下文的代码部分示例:
//创建上下文以及关联的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);
//然后使用OpenGL上下文绘制:
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指令在此画出!
gdk_gl_drawable_swap_buffers(view - > gldrawable);
gdk_gl_drawable_gl_end(view - > gldrawable);
}
返回TRUE;
//创建GtkWidget
GtkWidget * drawing_area = gtk_drawing_area_new();
//需要下一行以避免背景闪烁
gtk_widget_set_double_buffered(drawing_area,FALSE);
g_signal_connect(G_OBJECT(drawing_area),实现,G_CALLBACK(on_realize),数据);
g_signal_connect(G_OBJECT(drawing_area),draw,G_CALLBACK(on_expose),data);
//创建OpenGL上下文
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,
无};
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);
}
//使用OpenGL上下文绘制
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指令在此画出!
glXSwapBuffers(GDK_WINDOW_XDISPLAY(win),GDK_WINDOW_XID(win));
}
返回TRUE;
}
试图理解为什么(a)比(b)更快,我下载了GtkGLext库的源代码,阅读它们,并发现这些命令与X11的调用完全相同。
现在我的想法是(b)中的以下行:
$ p $ gtc_widget_set_double_buffered(drawing_area,FALSE);
乱搞渲染,然后我就无法做到......
或者OpenGL上下文之间存在差异,这可能会解释我注意到的行为。如果我沿着这个方向继续前进,我需要将两个上下文与尽可能多的细节进行比较......到目前为止,我选择了似乎获取一些信息的最常见方式:
OpenGL版本:3.0 Mesa 12.0.3
OpenGL供应商:nouveau
OpenGL渲染器:NVCF上的Gallium 0.4
OpenGL渲染版本:1.30
颜色位(R,G,B,A):8,8,8,0
深度位:24
模板位数:0
最大。灯允许:8
最大。纹理尺寸:16384
最大。剪报平面:8
最大。 Modelview矩阵堆栈:32
最大。投影矩阵堆栈:32
最大。属性堆栈:16
最大。纹理堆栈:10
OpenGL扩展的总数:227
扩展列表:
编号1:GL_AMD_conservative_depth
编号2:GL_AMD_draw_buffers_blend
.. 。
但是这两种情况都会返回完全相同的信息...
感谢您到达那里......现在我的问题是:
有没有办法输出尽可能多的有关OpenGL上下文的信息,以及如何?
我欢迎任何其他关于我在做什么的建议!
S。
PS:我正在为GTK3使用GtkGLArea Widget,但正如所述这里我还没有。
一些OpenGL指令:
// OpenGL指令在此画出!
glLoadIdentity();
glPushMatrix();
// d是深度...在其他地方计算
glTranslated(0.0,0.0,-d);
//为了清晰起见,跳过旋转部分,我使用四元数
rotate_camera();
// r,g,b和a是GLFloat值
glClearColor(r,g,b,a);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
glDisable(GL_LIGHTING);
int i;
// nbds是化学键的数量
GLfloat * lineVertices;
//这是大致我做什么来绘制化学键,给你一个想法
(i = 0; i {
/ / get_bonds(i)返回一个6浮点数组
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);
[/编辑]
感谢您的建议,ApiTrace的想法令人惊叹,不仅我发现了一个很棒的工具,而且帮助我获得了一些关于我的问题的线索。
使用ApiTrace:
- 我检查了我的程序的两个版本(a)和(b)都使用完全相同的OpenGL上下文......非常详细和便捷我必须添加...因此错误不是来自上下文初始化。 我发现在(b)版本中,渲染比(a)版本更经常进行5次......对于同一帧,这意味着5次!
我想要的唯一合乎逻辑的结论是GTK +信号在版本2和3之间的差异,在我的程序的版本(a)中,我使用(b)中我使用 draw
事件(新信号用于 > GtkDrawingArea
)...显然,GTK +库在版本2和版本3之间的行为在这一点上存在一些差异......我正在寻找解决方法...我会编辑这个答案提供进一步的信息。
Hello world,
回答我自己的问题,希望帮助别人避免我犯的同样的错误。
重新绘制我正在使用的OpenGL窗口:
pre $无效更新(GtkWidget * plot)
{
gtk_widget_hide(plot);
gtw_widget_show(plot);
}
相反,我应该使用:
gtk_widget_queue_draw(plot);
所有问题都解决了![/编辑]
Hello world and thanks for taking some time to read this !
I am writing a program in GTK2/3 + OpenGL, I got two versions of the program running:
- (a) GTK+2 + GtkGlext Extention -> works great !
- (b) GTK+3 + LibX11 -> works just fine !
Everything looks fine, except that the rendering in (a) is significantly faster that the rendering in (b) ... and I got no clue why. Here are some example of the code parts used to create the OpenGL context:
(a)
// 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; }
Trying to understand why (a) was faster than (b) I downloaded the sources of the GtkGLext library, read them, and find out that the commands were exactly the same with a call to X11. Now my thoughts are either the following line in (b)
gtk_widget_set_double_buffered (drawing_area, FALSE);
Is messing with the rendering, and then there is nothing I can do ... or there is/are difference(s) between the OpenGL contexts that might explain the behavior I noticed, If I follow up in this direction I need to compare both contexts with as many detail as possible ... so far I picked what seems to be the most usual way to get some information:
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
...
But both contexts give back exactly the same information ...
Thanks for getting there already ... now my question is:
Is there a way to output as many information as possible about an OpenGL context, and how ?
I welcome any other suggestion(s) on what I am doing !
S.
PS: I am working on using the GtkGLArea Widget for GTK3, but as stated here I am not there yet.
[EDIT] Some of the OpenGL instructions:
// 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);
[/EDIT]
thanks for your suggestions, the "ApiTrace" idea was amazing, not only did I discovered a great tool, but it helped me to get some clues about my problem. Using ApiTrace:
- I checked that both versions (a) and (b) of my program were using exactly the same OpenGL contexts ... with great details and ease I must add ... and therefore that the error was not coming from the context initialization.
- I found out that in version (b) the rendering was done 5 times for more often than in version (a) ... meaning 5 times for the same frame !
The only logical conclusion I am aiming at is the difference in GTK+ signals between version 2 and 3, in version (a) of my program I use an expose-event
while in version (b) I use a draw
event (new signal for the GtkDrawingArea
) ... obviously there are some differences in the behavior of the GTK+ library between version 2 and 3 at this point ... I am working on finding a way around it ... I will edit this answer to provide further information.
[EDIT]Hello world, answering my own question, hopefully to help someone to avoid the same mistake I did. To re-draw my OpenGL window I was using:
void update (GtkWidget * plot)
{
gtk_widget_hide (plot);
gtw_widget_show (plot);
}
Instead I should have been using:
gtk_widget_queue_draw (plot);
All problems solved ![/EDIT]
这篇关于如何获得关于OpenGL上下文的尽可能多的信息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!