如何获取尽可能多的有关 OpenGL 上下文的信息

2023-12-07

世界你好,感谢您花时间阅读本文!

我正在用 GTK2/3 + OpenGL 编写一个程序,我运行了该程序的两个版本:

  • (a) GTK+2 + GtkGlext 扩展 -> 效果很好!
  • (b) GTK+3 + LibX11 -> 工作得很好!

一切看起来都很好,除了 (a) 中的渲染速度明显快于 (b) 中的渲染速度……我不知道为什么。 以下是用于创建 OpenGL 上下文的代码部分的一些示例:

  • (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;
    }
    

为了理解为什么(a)比(b)更快,我下载了 GtkGLext 库的源代码,阅读它们,发现命令与调用 X11 完全相同。 现在我的想法是(b)中的以下行

gtk_widget_set_double_buffered (drawing_area, FALSE);

搞乱了渲染,然后我就无能为力了...... 或者 OpenGL 上下文之间存在差异,这可能可以解释我注意到的行为,如果我朝这个方向跟进,我需要尽可能多地比较两个上下文......到目前为止,我选择了似乎是获取一些信息的最常用方法:

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
 ...

但两种上下文都返回完全相同的信息......

感谢您已经到达那里......现在我的问题是:

有没有办法输出尽可能多的有关 OpenGL 上下文的信息,以及如何输出?

我欢迎对我正在做的事情提出任何其他建议!

S.

PS:我正在研究使用 GTK3 的 GtkGLArea 小部件,但如上所述here我还没到那儿。

[编辑] 一些 OpenGL 指令:

// 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]


感谢您的建议,“ApiTrace”的想法非常棒,我不仅发现了一个很棒的工具,而且还帮助我获得了有关我的问题的一些线索。 使用 ApiTrace:

  1. 我检查了我的程序的两个版本(a)和(b)都使用完全相同的OpenGL上下文...我必须添加大量细节和易用性...因此错误不是来自上下文初始化。
  2. 我发现版本 (b) 中的渲染次数比版本 (a) 中的渲染次数多了 5 次……这意味着同一帧渲染了 5 次!

我想要的唯一合乎逻辑的结论是版本 2 和版本 3 之间 GTK+ 信号的差异,在我的程序的版本 (a) 中,我使用expose-event在版本(b)中我使用draw事件(新信号GtkDrawingArea)...显然,此时版本 2 和 3 之间 GTK+ 库的行为存在一些差异...我正在努力寻找解决方法...我将编辑此答案以提供更多信息。

[编辑]世界你好, 回答我自己的问题,希望能帮助别人避免我犯的同样的错误。 为了重新绘制我的 OpenGL 窗口,我使用了:

void update (GtkWidget * plot)
{
  gtk_widget_hide (plot);
  gtw_widget_show (plot);
}

相反,我应该使用:

gtk_widget_queue_draw (plot);

所有问题都解决了![/编辑]

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何获取尽可能多的有关 OpenGL 上下文的信息 的相关文章

  • WPF DataGrid 多选

    我读过几篇关于这个主题的文章 但很多都是来自 VS 或框架的早期版本 我想做的是从 dataGrid 中选择多行并将这些行返回到绑定的可观察集合中 我尝试创建一个属性 类型 并将其添加到可观察集合中 它适用于单个记录 但代码永远不会触发多个
  • 在模板类中声明模板友元类时出现编译器错误

    我一直在尝试实现我自己的链表类以用于教学目的 我在迭代器声明中指定了 List 类作为友元 但它似乎无法编译 这些是我使用过的 3 个类的接口 Node h define null Node
  • C# 异步等待澄清?

    我读了here http blog stephencleary com 2012 02 async and await html that 等待检查等待的看看它是否有already完全的 如果 可等待已经完成 那么该方法将继续 运行 同步
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • 如何从本机 C(++) DLL 调用 .NET (C#) 代码?

    我有一个 C app exe 和一个 C my dll my dll NET 项目链接到本机 C DLL mynat dll 外部 C DLL 接口 并且从 C 调用 C DLL 可以正常工作 通过使用 DllImport mynat dl
  • 如何连接重叠的圆圈?

    我想在视觉上连接两个重叠的圆圈 以便 becomes 我已经有部分圆的方法 但现在我需要知道每个圆的重叠角度有多大 但我不知道该怎么做 有人有主意吗 Phi ArcTan Sqrt 4 R 2 d 2 d HTH Edit 对于两个不同的半
  • 如何在 C++ 中标记字符串?

    Java有一个方便的分割方法 String str The quick brown fox String results str split 在 C 中是否有一种简单的方法可以做到这一点 The 增强分词器 http www boost o
  • 如何使从 C# 调用的 C(P/invoke)代码“线程安全”

    我有一些简单的 C 代码 它使用单个全局变量 显然这不是线程安全的 所以当我使用 P invoke 从 C 中的多个线程调用它时 事情就搞砸了 如何为每个线程单独导入此函数 或使其线程安全 我尝试声明变量 declspec thread 但
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • 人脸 API DetectAsync 错误

    我想创建一个简单的程序来使用 Microsoft Azure Face API 和 Visual Studio 2015 检测人脸 遵循 https social technet microsoft com wiki contents ar
  • 如何定义一个可结构化绑定的对象的概念?

    我想定义一个concept可以检测类型是否T can be 结构化绑定 or not template
  • 为什么 C# 2.0 之后没有 ISO 或 ECMA 标准化?

    我已经开始学习 C 并正在寻找标准规范 但发现大于 2 0 的 C 版本并未由 ISO 或 ECMA 标准化 或者是我从 Wikipedia 收集到的 这有什么原因吗 因为编写 审查 验证 发布 处理反馈 修订 重新发布等复杂的规范文档需要
  • C# xml序列化必填字段

    我需要将一些字段标记为需要写入 XML 文件 但没有成功 我有一个包含约 30 个属性的配置类 这就是为什么我不能像这样封装所有属性 public string SomeProp get return someProp set if som
  • LINQ:使用 INNER JOIN、Group 和 SUM

    我正在尝试使用 LINQ 执行以下 SQL 最接近的是执行交叉联接和总和计算 我知道必须有更好的方法来编写它 所以我向堆栈团队寻求帮助 SELECT T1 Column1 T1 Column2 SUM T3 Column1 AS Amoun
  • 复制目录下所有文件

    如何将一个目录中的所有内容复制到另一个目录而不循环遍历每个文件 你不能 两者都不Directory http msdn microsoft com en us library system io directory aspx nor Dir
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • C 函数 time() 如何处理秒的小数部分?

    The time 函数将返回自 1970 年以来的秒数 我想知道它如何对返回的秒数进行舍入 例如 对于100 4s 它会返回100还是101 有明确的定义吗 ISO C标准没有说太多 它只说time 回报 该实现对当前日历时间的最佳近似 结
  • 相当于Linux中的导入库

    在 Windows C 中 当您想要链接 DLL 时 您必须提供导入库 但是在 GNU 构建系统中 当您想要链接 so 文件 相当于 dll 时 您就不需要链接 为什么是这样 是否有等效的 Windows 导入库 注意 我不会谈论在 Win
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • 现代编译器是否优化乘以 1 和 -1

    如果我写 template

随机推荐

  • 为什么“git rebase -p”不保留冲突解决方案?

    Has the man page陈述关于git rebase preserve 合并冲突解决方案或对合并提交的手动修改不会保留 这有什么好的理由吗 这与存在的理由是一样的command git rerere Reuse recorded r
  • 为什么 JavaScript 中数组允许字符串作为索引? [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 我们已经知道 数组和对象之间的区别之一是 如果你想提供特定的键 唯一的选择是一个对象 如果你不关心键 它就是一个数组 阅读更多here 此外 根据MDN 的文档 Arrays 不
  • 附加到画布内对象的事件

    我只有在画布上绘制矩形的画布代码 var x document getElementById canvas var ctx x getContext 2d ctx rect 20 20 150 100 ctx stroke 是否可以在所述矩
  • 如何通过分页从我的mysql数据库表中每页仅显示5条记录?

    我要显示通过分页每页五个记录 mysql php html css 直到显示所有记录 导航到页面必须是这样的 页码 1 2 3 4 5 6 7 7 8 最后 这是我的代码 用于查看 emp master 表中的所有记录 我是 PHP 新手
  • 使用ajax调用php函数

    我试图在单击 HTML 按钮时调用 php 函数 我做了一些搜索 发现直接执行此操作是不可能的 我应该使用 ajax 所以这是我到目前为止的尝试 但不起作用 这是我的 test php 该函数也在这个页面中
  • 如何在 Spring MVC 控制器中处理不同的日期格式?

    是否可以在 Spring MVC 控制器中处理不同的日期格式 我知道设置这样的东西 InitBinder protected void initBinder WebDataBinder binder SimpleDateFormat dat
  • Python 文件重命名

    我的目录中有一些文件 文件 IL txt文件 IL csv文件 NY txt文件 NY csv 我将不得不重命名它们 以便它们获得序列号 例如 文件 IL txt 001文件 IL csv 001文件 NY txt 002file NY c
  • SharePoint 中的 VBA MKDIR 失败

    这是我的问题 我正在尝试在 SharePoint 共享文档库中创建一个文件夹 但它仅在我使用 使用 Windows 资源管理器打开 菜单项输入凭据后才有效 如果我告诉我的用户他们需要先这样做 他们将不会理解 所以 我的问题是 A 有没有办法
  • 安装人员绑定

    我有一些安装程序 例如 JDK 阿帕奇雄猫 MySQL MySQL GUI 等 我想将所有这些安装程序捆绑在一起成一个 exe文件 以便单个 exe 将一一遍历所有安装程序 结果将 希望 使用户尽可能轻松地安装许多软件包 MySQL 安装程
  • WebView 上的 NullPointerException (WebView.requestFocus())

    我有一个问题 在我的 Android 应用程序中 有一个 Activity 包含WebView This WebView包含播放的 Flash 内容 当我从该应用程序切换到主屏幕时 Flash 内容在后台流畅运行 当我切换到主屏幕然后关闭屏
  • file_exists 不适用于本地主机 URL

    我有这段 PHP 代码 if file exists POST current folder do something But file exists总是返回 false 传递给该函数的值是 echo POST current folder
  • 数据框中列表的 Pandas 平均值

    我有一个 pandas DataFrame 其中包含包含列表的列 我正在尝试获取本专栏中列表的含义 这是我的 DataFrame 的示例 Loc Background 0 115227854 0 000120481927711 1 1152
  • mysql C++ 中的连接崩溃

    目前 我已经实现了一个写入 mysql 数据库的程序 我也使用 Xcode 和 c 我已正确导入所有库 但在这一行收到 BAD EXCESS 错误消息 con driver gt connect tcp 127 0 0 1 3306 roo
  • 用Java解析JSON数据

    我想解析此页面中的一些数据 http www bbc co uk radio1 programmes schedules england 2013 03 1 json 我想要解析的数据是标题 但我不确定如何提取数据 这是我到目前为止所做的
  • Apache Spark 中的数据集

    Dataset
  • 如何隐藏 Firefox 窗口(Selenium WebDriver)?

    当我同时执行多个测试时 我不想让 Firefox 浏览器窗口保持可见 我可以使用以下命令将其最小化selenium minimizeWindow 但我不想这样做 有什么办法可以隐藏 Firefox 窗口吗 我正在使用 FireFox Web
  • 删除日期字符串中的前导零

    我有一个如下所示的日期字符串 2011 02 03 我想删除字符串的日期和月份部分中的前导零 我该怎么做呢 2011 02 03 replace 0 g gt 2011 2 3 Update 根据 Lucky的问题 您可以考虑其他可能有前导
  • 将单元素数组传递给 SendInput 是一个错误吗?

    给出以下代码 void foo INPUT input input type INPUT MOUSE input mi dwFlags MOUSEEVENTF LEFTDOWN SendInput 1 input sizeof input
  • Jquery - 单击文档上任意位置时隐藏

    我有一个 div 只要您在其外部单击 它就会隐藏 但我在使 div 内的某些链接正常工作 而不是隐藏 div 时遇到了一些麻烦 document click function fav hide theDiv click function e
  • 如何获取尽可能多的有关 OpenGL 上下文的信息

    世界你好 感谢您花时间阅读本文 我正在用 GTK2 3 OpenGL 编写一个程序 我运行了该程序的两个版本 a GTK 2 GtkGlext 扩展 gt 效果很好 b GTK 3 LibX11 gt 工作得很好 一切看起来都很好 除了 a