丢失 OpenGL 输出

Posted

技术标签:

【中文标题】丢失 OpenGL 输出【英文标题】:Lost OpenGL output 【发布时间】:2013-03-29 21:36:44 【问题描述】:

一周前我将我的操作系统升级到最新版本,所以 GLEW、nVidia 驱动程序、g++、Qt 等也都升级了。那是我的QGLWidgets 停止显示原始 OpenGL 3.3 内容的那一天,只显示基于 2D QPainter 的内容。由于我机器上的其他 OpenGL 应用程序(包括我的 DE)没有受到影响,所以我一定在我的应用程序中编写了一些不可靠的代码,这可能是这些库的旧版本允许的 - 现在已经修改了。

我有很多高度抽象的 OpenGL 代码,有很多潜在的失败地方;经过几天尝试从中获取任何类型的输出(glGetError() 在我开始弄乱它之前没有返回错误),我决定最好的办法是编写最简单的 OpenGL 应用程序,然后慢慢构建它直到它坏了。

但我什至无法让三角形出现!

void Viewer::initializeGL()

    //  Initialise GLEW, compile/link fragment and vertex shaders, error check, etc.
    ...

    //  Create default VAO.
    glGenVertexArrays( 1, &vao_ );
    glBindVertexArray( vao_ );

    glUseProgram( shader_ );
    vVertex_ = glGetAttribLocation( shader_, "vVertex" );

    //  Create the test triangle VBO.
    glGenBuffers( 1, &vbo_ );
    glBindBuffer( GL_ARRAY_BUFFER, vbo_ );
    glEnableVertexAttribArray( vVertex_ );
    glVertexAttribPointer( vVertex_, 3, GL_FLOAT, false, 0,
                           reinterpret_cast< GLvoid* >( 0 ) );

    //  Upload the data to the GPU.
    static const float verts[9] =  0.0f, 0.0f, -0.5f,
                                    1.0f, 0.0f, -0.5f,
                                    0.5f, 1.0f, -0.5f ;
    glBufferData( GL_ARRAY_BUFFER, sizeof( verts ),
                  static_cast< const void* >( verts ), GL_STATIC_DRAW );

    glBindBuffer( GL_ARRAY_BUFFER, GL_NONE );
    glDisableVertexAttribArray( vVertex_ );
    Sy_GL::checkError();


void Viewer::paintGL()

    //  Clear the buffers.
    qglClearColor( QColor( Qt::black ) );
    glClear( GL_COLOR_BUFFER_BIT );

    glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );

    glBindBuffer( GL_ARRAY_BUFFER, vbo_ );
    glEnableVertexAttribArray( vVertex_ );
    glVertexAttribPointer( vVertex_, 3, GL_FLOAT, false, 0,
                           reinterpret_cast< GLvoid* >( 0 ) );


    glDrawArrays( GL_TRIANGLES, 0, 3 );

    glBindBuffer( GL_ARRAY_BUFFER, GL_NONE );
    glDisableVertexAttribArray( vVertex_ );

    Sy_GL::checkError();

我没有将我的 VAO 用于它的用途,因为 VAO 不能跨上下文共享,这是我的“真实”应用程序中的场景,所以我在这里复制这种情况。 Sy_GL::checkError() 只是调用glGetError() 并在出现问题时抛出异常。我的两个着色器再简单不过了:

//  Vertex shader.
#version 330
in vec3 vVertex;
void main( void )

    gl_Position = vec4( vVertex, 1.0 );


//  Fragment shader (in different file).
#version 330
out vec4 fragColour;
void main( void )

    fragColour = vec4( 1.0, 0.0, 0.0, 1.0 );

这应该在黑色背景下显示一个红色的三角形渲染,但我只得到黑色背景 - 没有控制台输出或异常。我的系统确实支持 OpenGL 3.3 及更高版本,这是我的glxinfo 输出的顶部:

name of display: :0
display: :0  screen: 0
direct rendering: Yes
server glx vendor string: NVIDIA Corporation
server glx version string: 1.4

还有我的glewinfo 输出:

GLEW version 1.9.0
Reporting capabilities of display :0, visual 0x2b
Running on a GeForce GTX 560 Ti/PCIe/SSE2 from NVIDIA Corporation
OpenGL version 4.3.0 NVIDIA 310.32 is supported

所以我的问题是:我的代码错了吗?还是我的系统受到了非常微妙的破坏?

编辑

QGLFormat 似乎在报告我只有 OpenGL v1.0 - Qt 使用什么机制来获取该值?

在我的“真实”应用程序中,我使用QGLFormat::openGLVersionFlags() &amp; QGLFormat::OpenGL_Version_3_3 执行OpenGL 版本检查,结果通过了;但使用myQGLWidget-&gt;format().majorVersion()myQGLWidget-&gt;format().minorVersion() 分别返回10

编辑 2

有趣的是,如果我在 main.cpp 中设置 v3.3 的默认 QGLFormat

QGLFormat format( QGL::DoubleBuffer |
                  QGL::DepthBuffer |
                  QGL::AlphaChannel );
format.setVersion( 3, 3 );
QGLFormat::setDefaultFormat( format );

它在第一个 my OpenGL 调用中出现段错误,特别是 glGenVertexArrays(1, &amp;vao_),但 myQGLWidget-&gt;format().majorVersion()myQGLWidget-&gt;format().minorVersion() 分别返回 33

【问题讨论】:

当你调用 QGLWidget::format()::majorVersion() 它会报告什么? @SirDigbyChickenCaesar 嗯,它说它正在报告 v1.0 - 这是错误的错误。我将更新我的问题以包含此内容。 在我看来,OpenGL 驱动程序没有正确安装。您遵循了哪个操作系统和驱动程序安装程序?对于 Windows Vista 及更高版本,您必须从 NVidia 网站下载驱动程序。 Windows 自动安装的驱动程序已失效。 @datenwolf 我正在使用专有的 310.32 nVidia 驱动程序运行 openSUSE 12.3。有报道称这些驱动程序和 3.7.10 内核存在问题,但奇怪的是只有我的 Qt 应用程序有问题。虽然我在我的应用程序中使用 v3.3 功能,而 DE 可能只是使用 OpenGL ES 2.0,因此部分驱动程序可能没问题。 @cmannett85:一些 Linux 发行版对 libGL.so 做了一些奇怪的事情。您应该确保您的程序确实找到了与 NVidia 驱动程序一起提供的 libGL.so。否则它可能会退回到 Mesa 的 libGL.so 中。恕我直言,唯一能正确解决 libGL.so 问题的发行版是 Gentoo 的 eselect 方法; Debian 的“替代品”系统也可以工作,但恕我直言,不够可靠。 【参考方案1】:

我们最近在工作中遇到了这个问题。原因是最新的 NVIDIA 驱动程序破坏了主要和次要版本查询。

编辑:我认为这可能与在设置有效的 GL 上下文之前调用这些函数有关。 结束编辑

因此,您可以尝试使用稍旧的驱动程序。但是,某些 Qt 版本和 glversion 也存在问题。看看这个链接:

http://qt-project.org/forums/viewthread/20424

【讨论】:

我正在运行 Qt v4.8,我认为您可能是对的。有一个更新版本的 nVidia 出来了,所以我先试试。 我尝试了您发布的论坛链接中的一种方法,将 QGLFormat 强制为特定的 OpenGL 版本,并将其设置为 QGLFormat::setDefaultFormat(..)。但它会在第一个 my OpenGL 调用中触发段错误。奇怪。 @cmannett85 没那么奇怪。可能只是上下文创建失败,如果不存在上下文,您的第一个调用会导致取消引用 nullptr 我升级了内核和 nVidia 驱动程序版本,问题消失了。所以谢谢你!

以上是关于丢失 OpenGL 输出的主要内容,如果未能解决你的问题,请参考以下文章

在openGL中绘制点时丢失了一些点

在批处理模式下使用 openGL 渲染器时所有文本都会丢失

使用 OpenGL 渲染时 CPU 和 GPU 之间的数据丢失

SDL2 丢失 OpenGL 上下文或未定义函数

opengl编译通过运行时报错计算机中丢失glut32.dll

OpenGL:如何设置 OpenGL 只渲染到 FBO,不输出到屏幕/窗口/控件?