void contextSwitch(QOpenGLContext *_context, ContextFunctor f) { auto *_current = QOpenGLContext::currentContext(); if (!_current || !_current->isValid()) return; if (_context != _current) { _context->makeCurrent(_current->surface()); } withCurrentContext(f); if (_context != _current) { _current->makeCurrent(_current->surface()); } }
void useShader(QOpenGLShaderProgram& _s, std::function<void(UniformHandler&)>f) { withCurrentContext([&](QOpenGLFunctions& _gl) { _s.bind(); { UniformHandler _handler(_gl, _s); f(_handler); // Destructor of handler is called here implicitly // by RAII to unbind all textures } _s.release(); }); }
void Image::update() { if (image_.width() == 0) return; if (texture_) return; withCurrentContext([&](QOpenGLFunctions& _) { texture_.reset(new QOpenGLTexture(QOpenGLTexture::TargetRectangle)); texture_->setData(image_); texture_->setMinMagFilters( QOpenGLTexture::Linear, QOpenGLTexture::Linear); texture_->allocateStorage(); }); }
void Circle::drawLine(QPointF const& _pos, float _rX, float _rY) const { withCurrentContext([&](QOpenGLFunctions& _) { glPushMatrix(); glScalef(_rX, _rY, 1.0); glTranslatef(_pos.x() / _rX, _pos.y() / _rY, 0.0); glEnableClientState(GL_VERTEX_ARRAY); _.glBindBuffer(GL_ARRAY_BUFFER, vertexVbo_.id()); glVertexPointer(2, GL_FLOAT, 0, nullptr); _.glDrawArrays(GL_LINE_LOOP, 1, numberSegments); _.glBindBuffer(GL_ARRAY_BUFFER, 0); glDisableClientState(GL_VERTEX_ARRAY); glPopMatrix(); }); }
void InputPreview::paintGL() { if (!input() || !isVisible()) return; makeCurrent(); if (!shader_) { primaryContextSwitch([&](QOpenGLFunctions& _) { visual::initShader(shader_,"textureRect"); }); } withCurrentContext([this](QOpenGLFunctions& _) { _.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); auto _rect = viewRect(); visual::viewport(this); /// Setup orthogonal projection glMatrixMode(GL_PROJECTION); { glLoadIdentity(); QMatrix4x4 _m; _m.ortho(_rect.left(), _rect.right(), _rect.top(), _rect.bottom(), -1.0, 1.0); glMultMatrixf(_m.constData()); } glMatrixMode(GL_MODELVIEW); glLoadIdentity(); shader_->bind(); _.glBindTexture(GL_TEXTURE_RECTANGLE, input_->textureId()); visual::Rectangle::draw(input_->size()); _.glBindTexture(GL_TEXTURE_RECTANGLE, 0); shader_->release(); }); paintGLDone(); }