OpenGL - проблемы на определенных видеокартах - PullRequest
1 голос
/ 29 октября 2011

У меня были проблемы с рендерингом OpenGL на разных компьютерах:

Работает: Intel HD3000 / Sandy Bridge: 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();
}

1 Ответ

4 голосов
/ 29 октября 2011

В данный момент вы сначала настраиваете вершинные массивы для получения их данных из массива RAM (_lineBuffer), а затем связываете VBO и копируете в него данные _lineBuffer. В любом случае это, вероятно, не будет делать то, что вы хотите (хотя трудно сказать, что вы хотите там делать).

Всегда имейте в виду, что gl...Pointer вызывает источник своих данных из текущей привязки GL_ARRAY_BUFFER или из ОЗУ ЦП, если ни одна (0) не связана (glDrawArrays не заботится о текущей привязке) ВБО). Так что в вашем случае вызов 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, чтобы запутать ваши цвета или быть странным образом реализованным в некоторых драйверах, так как это не очень обычный путь.

...