Нарисуйте содержимое QGLWdiget в FBO

у меня есть QGraphicsScene + QGraphicsView установка, которая использует QGLWidget нарисовать содержимое.

Я также сделал несколько фрагментных шейдеров, чтобы добавить карту смещения и эффект цветения к сцене. Если я сделаю QPainter объект с QFramebufferObject в качестве устройства и вызвать функцию рендеринга графической сцены на QPainter Объект, сцена передается в FBO, и я могу затем использовать его для создания композиции. Это, однако, имеет тот недостаток, что он использует рендеринг программного обеспечения и потребляет много ресурсов.

К сожалению, когда я пытаюсь установить FBO в качестве текущей цели рендера и оставляю QGLWidget чтобы нарисовать на FBO, FBO выходит пустым (и под пустым я имею в виду цвет glClearColor вызов)

Так что мой вопрос в основном, есть ли способ получить содержимое QGLWidget на FBO, или есть какой-либо другой способ реализации шейдеров постобработки в QGLWidget

Вот соответствующие части моего текущего кода

void MyWindow::SwitchRenderContext(RenderType type)
{
m_renderType = type;
m_renderArea->SetRenderType(type);
switch(type)
{
case RenderType_Software:
m_view.setViewport(NULL);
layout()->removeWidget(&m_view);
layout()->addWidget(m_renderArea);
m_view.m_renderWidget = NULL;
break;
case RenderType_OpenGL:
m_view.setViewport(m_renderArea);
m_view.setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
layout()->addWidget(m_renderArea);
m_view.m_renderWidget = m_renderArea;
break;
}
}

void MyGlWidget::initializeGL()
{
m_initialized = true;
if(m_dispFbo == NULL)
m_dispFbo = new QGLFramebufferObject(width(), height());
if(m_bufFbo == NULL)
m_bufFbo = new QGLFramebufferObject(width(), height());
if(m_fbo == NULL)
m_fbo = new QGLFramebufferObject(width(), height());

static const float vertex[] = {
-1.0f,  1.0f, 0.0f, 1.0f,
1.0f,  1.0f, 0.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 1.0f,
1.0f, 1.0f, 0.0f, 1.0f,
1.0f, -1.0f, 0.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 1.0f,
};

//initialize vbo
if(!m_vbo.isCreated())
{
m_vboEnabled = m_vbo.create();
if(m_vboEnabled)
{
m_vbo.setUsagePattern(QOpenGLBuffer::StaticDraw);
m_vbo.bind();
m_vbo.allocate(vertex, sizeof(vertex) );
m_vbo.release();
}
glEnable(GL_TEXTURE_2D);
}
glViewport(0, 0, width(), height());
m_shadersEnabled = initializeShaders();
}

void MyGlWidget::SetRenderType(RenderType type)
{
m_renderType = type;
}

void MyGlWidget::DoHardwarePaint()
{
m_fbo->release();
QPainter dispPainter(m_dispFbo);
m_dispScene->RenderScene(&dispPainter);
dispPainter.end();

DrawShaders();

m_fbo->bind();
}

void MyGlWidget::DoSoftwarePaint()
{
if(!m_shadersEnabled || !m_vboEnabled)
{
QPainter painter(this);
m_scene->render(&painter);
return;
}

QPainter dispPainter(m_dispFbo);
m_dispScene->RenderScene(&dispPainter);
dispPainter.end();

QPainter painter(m_fbo);
m_scene->render(&painter);
painter.end();

DrawShaders();
update();

}

void MyGlWidget::DrawShaders()
{
m_vbo.bind();
m_bufFbo->bind();
glDisable(GL_DEPTH_TEST);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_fbo->texture());
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, m_dispFbo->texture());

m_displaceShader.bind();
m_displaceShader.enableAttributeArray("in_verts");
m_displaceShader.setAttributeBuffer( "in_verts", GL_FLOAT, 0, 4);
m_displaceShader.setUniformValue("inCol", 0);
m_displaceShader.setUniformValue("inDisplace", 1);
glDrawArrays(GL_TRIANGLES, 0, m_vbo.size());

m_bufFbo->release();

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_bufFbo->texture());

m_bloomShader.bind();
m_bloomShader.enableAttributeArray("in_verts");
m_bloomShader.setAttributeBuffer( "in_verts", GL_FLOAT, 0, 4);
m_bloomShader.setUniformValue("inCol", 0);
m_bloomShader.setUniformValueArray("offsets", offsets, 8, 2);
glDrawArrays(GL_TRIANGLES, 0, m_vbo.size());

m_bloomShader.disableAttributeArray("in_verts");
m_bloomShader.release();

m_vbo.release();
glEnable(GL_DEPTH_TEST);
}

void MyGlWidget::paintGL()
{
if(!m_vboEnabled && m_renderType == RenderType_OpenGL)
return;

if(m_renderType == RenderType_Software)
{
DoSoftwarePaint();
return;
}

DoHardwarePaint();
}

1

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]