Я не геймдевелопер - и для моих скромных запросов всегда хватало одного контекста - поэтому темы шаринга я всегда избегал. Но тут возникла задачка и я на свою голову решил, что для неё решение как раз вписывается в идеологию шаринга контекстов.
Проект на 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 ВБО - а то гугль выдает кучу ссылок на всякую болтавню в форумах - ни кода, ни примеров толковых нет - изредка куски, какие-то встречаются - и те ни о чем. Правда искал можт не долго, хз.
ПИПЕЦ ГОСПОДА!!! Я нашел где косяк!!
Я видимо когда переносил код я в GLInitialize(это в QGLWidget виртуальный метод такой) случайно закопипастил 2 строчки из рендера
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);
И из-за этого все было - я ВООБЩЕ не понимаю как это связано - что перестали биндиться буфера - это что за жесть??? Т.е. если я случайно где-то не там или раньше чем надо вызову фцию, даже которая отношения ни к чему не имеет - я получается ошибку неделями буду искать. Т.к. из-за этих 2 строк поведение стало неадекватным - glGetError - то возвращает ошибку - то нет.
glDrawRangeElements падает - причем стек постоянно разный!!!!
это опять AMDшные дрова чтоль - капец!!!
Ничего сверх-нормального, просто вы вызвавши glEnableClientState сказали серверу OpenGL, что стоит ждать от вас масив вершин, и масив цветов, а потом начали совать ему объект вершинного буфера, конечно OpenGL не понял, что от него хотят. :)
Чтобы не бить себя по лбу такими граблями, я бы рекоммендовал определиться с какой системой вы работаете: с ARB-расширениями или с OpenGL Core расширениями, использовать и то и другое конечно можно, но будьте готовы что изменения в OpenGL Core могут коснуться ARB-расширений.
Тема в архиве.