一周前我将我的操作系统升级到最新版本,所以 GLEW、nVidia 驱动程序、g++、Qt 等也都升级了。那是我QGLWidget
停止显示原始 OpenGL 3.3 内容的那一天,只显示基于 2DQPainter
的内容。由于我机器上的其他 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 使用什么机制来获取该值?
在我的“真实”应用程序中,我使用 执行 OpenGL 版本检查QGLFormat::openGLVersionFlags() & QGLFormat::OpenGL_Version_3_3
,并且通过了;但分别使用myQGLWidget->format().majorVersion()
和myQGLWidget->format().minorVersion()
返回1
和0
。
编辑 2
有趣的是,如果我QGLFormat
在 main.cpp 中设置 v3.3 的默认值:
QGLFormat format( QGL::DoubleBuffer |
QGL::DepthBuffer |
QGL::AlphaChannel );
format.setVersion( 3, 3 );
QGLFormat::setDefaultFormat( format );
It segfaults on the first of my OpenGL calls, specifically glGenVertexArrays(1, &vao_)
, but myQGLWidget->format().majorVersion()
and myQGLWidget->format().minorVersion()
return 3
and 3
respectively.