OpenGL -某些显卡上的问题

OpenGL - problems on certain graphics cards

本文关键字:问题 显卡 OpenGL      更新时间:2023-10-16

我一直在遇到不同计算机上的OpenGL渲染问题:

工作原理:Intel HD3000/Sandy bridge:ATI 6950ATI 6970ATI 5670Quadro FX 2000

不工作:英伟达移动9600gtQuadro FX 1800

当代码行"renderLines()"被调用时,屏幕上没有显示"不工作"的显卡。没有"renderLines()",在我测试过的所有显卡上,一切都像预期的那样工作。

"renderSprites()"与renderLines()非常相似,唯一的区别是它是渲染四边形到屏幕而不是线条。

void GraphicsEngineOGL3::update()
{
    this->renderSprites();
    this->renderLines(); // this is the offending line of code
    SDL_GL_SwapBuffers();
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    checkError();
}
void GraphicsEngineOGL3::renderLines()
{
    if(lineBuffer_.empty()) // note: lineBuffer is a std::Vector<Vertex>
        return;
    glEnableClientState(GL_VERTEX_ARRAY);           // DEPRECATED in OGL 3.1
    glEnableClientState(GL_COLOR_ARRAY);
    // Note: glVertexPointer is deprecated, change to glVertexAttribPointer
    glVertexPointer(3, GL_FLOAT, sizeof(Vertex), &(lineBuffer_[0].x));  // DEPRECATED in OGL 3.1
    glColorPointer(4, GL_BYTE, sizeof(Vertex), &(lineBuffer_[0].r));
    glBindBuffer( GL_ARRAY_BUFFER, VBOs_[activeVBO_]);
    glBufferData( GL_ARRAY_BUFFER, lineBuffer_.size() * sizeof(Vertex), &(lineBuffer_[0]), GL_STREAM_DRAW);
    glDrawArrays( GL_LINES, 0, lineBuffer_.size()); // where 4 is the number of vertices in the quad
    glBindBuffer( GL_ARRAY_BUFFER, 0); // Binding the buffer object with 0 switchs off VBO operation. 
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
    lineBuffer_.clear();
    checkError();
}

此时,您首先将顶点数组设置为从RAM数组(_lineBuffer)获取数据,然后绑定VBO并将_lineBuffer的数据复制到其中。无论如何,这可能不会达到你想要的效果(尽管很难说你想在这里做什么)。

始终记住,gl...Pointer调用从当前绑定的GL_ARRAY_BUFFER获取数据,如果没有(0)被绑定,则从CPU RAM获取数据(glDrawArrays不关心当前绑定的VBO)。因此,在您的示例中,glBindBuffer调用根本不起作用,您的数组从CPU数组_lineBuffer而不是从VBO获取数据。如果你想让它们使用VBO,你必须在gl...Pointer调用之前绑定缓冲区,但在这种情况下,确保地址实际上只是一个字节偏移到缓冲区,而不是一个真正的RAM地址:

glBindBuffer( GL_ARRAY_BUFFER, VBOs_[activeVBO_]);
glBufferData( GL_ARRAY_BUFFER, lineBuffer_.size() * sizeof(Vertex), &(lineBuffer_[0]), GL_STREAM_DRAW);
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), (const char*)0+offsetof(Vertex,x));  //use the current VBO
glColorPointer(4, GL_UNSIGNED_BYTE, sizeof(Vertex), (const char*)0+offsetof(Vertex,r));
glBindBuffer( GL_ARRAY_BUFFER, 0);    //can already be unbound
glDrawArrays( GL_LINES, 0, lineBuffer_.size());

注意,我使用GL_UNSIGNED_BYTE作为颜色数据,这对于颜色来说比符号类型更自然。使用GL_BYTE,它甚至可能是,你的颜色被转换为[-1,1]而不是[0,1],然后被箝位(而不是线性转换)为[0,1]。

但是如果你真的希望数组从_lineBuffer而不是从VBO(我怀疑)中获取数据,那么缓冲区函数调用是不必要的,你可以忽略它们。

请注意,你的代码,虽然非常奇怪,肯定是错误的,但仍然应该工作。所以我不知道这是不是问题本身的问题,但这确实是个问题。但最多,我会怀疑使用GL_BYTE而不是GL_UNSIGNED_BYTE来混淆你的颜色或在某些驱动程序中奇怪地实现,因为它不是一个非常常见的路径。