1

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

作品:Intel HD3000 / Sandy 桥接器:ATI 6950 ATI 6970m ATI 5670m Quadro FX 2000

不工作:Nvidia 移动 9600 gt Quadro 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();
}
4

1 回答 1

4

目前,您首先将顶点数组设置为从 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 而不是从 VBO 获取数据(我对此表示怀疑),那么缓冲区函数调用无论如何都是不必要的,您可以省略它们。

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

于 2011-10-29T14:58:15.320 回答