ПрограммированиеФорумГрафика

OpenGL context sharing (РЕШЕНО)

#0
19:08, 8 янв 2013

Я не геймдевелопер - и для моих скромных запросов всегда хватало одного контекста - поэтому темы шаринга я всегда избегал. Но тут возникла задачка и я на свою голову решил, что для неё решение как раз вписывается в идеологию шаринга контекстов.

Проект на Qt - в Qt шаринг делается вроде как просто подумал я - понаписал много чего, и когда дело дошло до логического завершения - т.е. появления картинки - шаринг почему-то не взлетел.

Вот основные куски кода:

GLView* GLController::genGLView(QWidget* parent)
{
  return new GLView(parent, this, _share.data()); //последний параметр это QGLWidget с которым шаримся какбе
}

GLView - это класс наследник от QGLWidget


Далее вызывается следующий код - в нем ошибок вроде как нет - уже все проверил glGetErrorами(потом удалил их) - да и Qt молчит(обычно он в консоль всякого г.. много пишет если, что не так)

void Scene::GLController::buildPass(QSharedPointer<Tree::TreeItemPass> const& pass, bool rebuild /*= false*/)
{
_share->makeCurrent();
.......
//тонна кода не относящегося к ogl
.......
vertexData._vertexBO = QSharedPointer<QGLBuffer>(new QGLBuffer(QGLBuffer::VertexBuffer));
if (!vertexData._vertexBO->create())
  throw std::runtime_error("can't create vertex buffer object");

vertexData._indexBO = QSharedPointer<QGLBuffer>(new QGLBuffer(QGLBuffer::IndexBuffer));
if (!vertexData._indexBO->create())
  throw std::runtime_error("can't create index buffer object");

write = true;
.......
//тонна кода не относящегося к ogl
.......
//Write into buffers
if (write)
{
  vertexData._vertexBO->bind();
  vertexData._vertexBO->allocate(offset);
  vertexData._vertexBO->write(0, modelDataPtr->vertices()->data(), sizeVertices);
.......
//еще тонна кода
.......

           vertexData._vertexBO->release();
  vertexData._indexBO->bind();
  vertexData._indexBO->allocate(modelDataPtr->indices()->data(), modelDataPtr->indices()->size() * sizeof(GLuint));
  vertexData._indexBO->release();

затем пытаемся вывести это на экран в другом контексте уже внутри GLView

void GLView::paintGL()
{
  using namespace gmath;

  makeCurrent();
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

  glMatrixMode(GL_MODELVIEW);
.......
//тонна кода вывода всяких мелочей, аля оси и пр.
.......
if (!buf._vertexBO || !buf._indexBO)
  continue;
if (!buf._vertexBO->bind())
  std::runtime_error("Error binding vertex buffer"); // сюда не попадаем!!!!
          
char* err = (char*)gluErrorString(glGetError()); // !!!!! недопустимый параметр и пипец
.......
//тонна кода, которую уже нет смысла приводить
.......
}

Уже обчитался про шаринг - все вроде нормально.

Начал внутри Qt смотреть что происходит - вроде всё нормально - никаких ошибок нет, всё валидное - всё создается

Вот так Qt создает контекст:

 
d->rc = wglCreateContextAttribsARB(hdc, shareContext && shareContext->valid
                                           ? shareContext->rc : 0, attributes);

shareContext->rc - ессесно валидный

Уже сократил кол-во контекстов до 2х - на всякий случай и чтоб удобней было отлаживать - один фиг после bind: glGetError = "недопустимый параметр"

bind внутри естественно вызывает просто glBindBuffer, ну и простенькие проверки - ну уж, параноидально, на всякий случай заменял его на чистый glBindBuffer - таже фигня


Что я упустил??

ЗЫ
Можт у кого есть нормальный компилируемый пример шаринга кстати, желательно чтоб c ВБО  - а то гугль выдает кучу ссылок на всякую болтавню в форумах - ни кода, ни примеров толковых нет - изредка куски, какие-то встречаются - и те ни о чем. Правда искал можт  не долго, хз.

#1
22:12, 8 янв 2013


ПИПЕЦ ГОСПОДА!!! Я нашел где косяк!!

Я видимо когда переносил код я в GLInitialize(это в QGLWidget виртуальный метод такой) случайно закопипастил 2 строчки из рендера

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

И из-за этого все было - я ВООБЩЕ не понимаю как это связано - что перестали биндиться буфера - это что за жесть??? Т.е. если я случайно где-то не там или раньше чем надо вызову фцию, даже которая отношения ни к чему не имеет - я получается ошибку неделями буду искать. Т.к. из-за этих 2 строк поведение стало неадекватным -  glGetError - то возвращает ошибку - то нет.
glDrawRangeElements падает - причем стек постоянно разный!!!!

это опять AMDшные дрова чтоль - капец!!!

#2
19:58, 10 янв 2013

Ничего сверх-нормального, просто вы вызвавши glEnableClientState сказали серверу OpenGL, что стоит ждать от вас масив вершин, и масив цветов, а потом начали совать ему объект вершинного буфера, конечно OpenGL не понял, что от него хотят. :)
Чтобы не бить себя по лбу такими граблями, я бы рекоммендовал определиться с какой системой вы работаете: с ARB-расширениями или с OpenGL Core расширениями, использовать и то и другое конечно можно, но будьте готовы что изменения в OpenGL Core могут коснуться ARB-расширений.

ПрограммированиеФорумГрафика

Тема в архиве.