Дочерний класс QOpenGLWidget с общим контекстом - PullRequest
0 голосов
/ 22 января 2019

У меня есть QOpenGLWidget класс:

#ifndef GLWIDGET_H
#define GLWIDGET_H

#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLFramebufferObject>
#include <QOpenGLShaderProgram>
#include <QOpenGLBuffer>
#include <QOpenGLFunctions_4_3_Compatibility>
...

QT_FORWARD_DECLARE_CLASS(QOpenGLShaderProgram)


class GLWidget : public QOpenGLWidget, protected 
QOpenGLFunctions_4_3_Compatibility
{
    Q_OBJECT

public:
    GLWidget(QWidget *parent = 0);
    ~GLWidget();
...

Внутри initializeGL() У меня есть вызовы для инициализации шейдеров и буферов и т. Д.:

void GLWidget::initializeGL()
{

    connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &GLWidget::cleanup);

    initializeOpenGLFunctions();

    QSurfaceFormat format;
    format.setMajorVersion( 4 );
    format.setMinorVersion( 3 );
    format.setProfile( QSurfaceFormat::CompatibilityProfile );
    context()->setFormat(format);
    //glClearColor(0.8f, 0.9f, 1.0f, m_transparent ? 0 : 1);
    glClearColor(0.0, 0.0, 0.0, 1.0);
    glEnable(GL_CULL_FACE);
    glCullFace(GL_BACK);
    glEnable(GL_DEPTH_TEST);

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glBlendEquation(GL_FUNC_ADD);


    //LOAD OBJECTS
    makeCurrent();
    loadObjects();


    //SHADER INIT (SIMPLE)

    simple_shader = new QOpenGLShaderProgram;
    simple_shader->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/shaders/simple.vert");
    simple_shader->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/shaders/simple.frag");
    simple_shader->bindAttributeLocation("vertex", 0);
    simple_shader->link();
    simple_shader->bind();
    simple_proj_matrix_loc = simple_shader->uniformLocation("projMatrix");
    simple_mv_matrix_loc = simple_shader->uniformLocation("mvMatrix");
    simple_tex_loc = simple_shader->uniformLocation("texture");
    simple_shader->release();



    //BUFFER INIT (SIMPLE)

    simple_vao.create();
    simple_vao.bind();
    simple_vbo.create();
    simple_vbo.setUsagePattern(QOpenGLBuffer::StaticDraw);
    simple_vbo.bind();
    simple_vbo.allocate(VertexPosUvData.constData(),  VertexPosUvData.count() * sizeof(VertexPosUv));
    glEnableVertexAttribArray(0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(VertexPosUv), (void*)0);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(VertexPosUv), (void*)12);
    simple_vbo.release();
    simple_vao.release();

    //--------------------------

Мой вопрос:

Поскольку этот класс становится все более сложным с большим количеством шейдеров и буферов, мне нужно все организовать в какую-то лучшую форму. Каков наилучший способ реализовать некоторый класс менеджера шейдеров / буферов, чтобы функциональность была такой же, как сейчас, но в другом файле. Проблема состоит в использовании функций opengl и совместного использования контекста.

Внутри ::initializeGL() Я хочу что-то вроде:

shader_manager.init_simple_shader();
shader_manager.init_simple_buffer();

Внутри шейдерного менеджера что-то вроде этого:

void ShaderManager::init_simple_shader()
{
    simple_vao.create();
    simple_vao.bind();
    simple_vbo.create();
    simple_vbo.setUsagePattern(QOpenGLBuffer::StaticDraw);
    simple_vbo.bind();

... и т. Д. С функциями opengl, которые работают точно так же, как в родительском классе.

...