Мой виджет qtopengl не отображается? - PullRequest
0 голосов
/ 24 июня 2018

main.cpp

#include "QtGuiApplication4.h"
#include <QtWidgets/QApplication>
#include "megui.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    megui test;
    test.show();

    return a.exec();
}

qtguiapplication4.h

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_QtGuiApplication4.h"

class QtGuiApplication4 : public QMainWindow
{
    Q_OBJECT

public:
    QtGuiApplication4(QWidget *parent = Q_NULLPTR);

private:
    Ui::QtGuiApplication4Class ui;
};

qtguiapplication4.cpp

#include "QtGuiApplication4.h"

QtGuiApplication4::QtGuiApplication4(QWidget *parent)
    : QMainWindow(parent)
{
    ui.setupUi(this);
}

megui.h

#pragma once
#include "QOpenGLWidget"
#include "QOpenGLBuffer"
#include "QOpenGLFunctions"
#include "QOpenGLShaderProgram"
#include <iostream>
class megui:public QOpenGLWidget, protected QOpenGLFunctions
{
public:
    QOpenGLFunctions glfunctions;
    QOpenGLShaderProgram program;

    void initializeGL();
    void paintGL();

    megui();
    ~megui();
};

megui.cpp

#include "megui.h"

void megui::initializeGL()
{
    makeCurrent();
    float vertexpositions[] = {
        0.5f,0.5f,
        0.0f,-0.5f,
        0.5f,-0.5f
    };
    QOpenGLBuffer buffer1(QOpenGLBuffer::VertexBuffer);
    buffer1.create();
    buffer1.setUsagePattern(QOpenGLBuffer::StaticDraw);
    buffer1.allocate(vertexpositions, sizeof(vertexpositions));
    buffer1.bind();
    glfunctions.initializeOpenGLFunctions();
    glfunctions.glEnableVertexAttribArray(0);
    glfunctions.glVertexAttribPointer(0, 3, GL_FLOAT, false, 0, 0);

    program.addShaderFromSourceFile(QOpenGLShader::Vertex, "C:/open gl testimg/opengl testing/opengl testing/vertex.glsl");
    program.addShaderFromSourceFile(QOpenGLShader::Fragment, "C:/open gl testimg/opengl testing/opengl testing/fragmentshader.glsl");
    program.link();
}

void megui::paintGL()
{
    makeCurrent();

    glfunctions.initializeOpenGLFunctions();

    program.bind();
    glfunctions.glDrawArrays(GL_TRIANGLES, 0, 3);   
}

megui::megui()
{
}

megui::~megui()
{
}

fragmentshader

#version 430

out vec4 inalcolors;

void main() {

    inalcolors =vec4( 1.0f, 0.0f, 0.0f,1.0) ;
}

vertexshader

#version 430 

layout(location = 0) in vec4 positions;

void main() {

    gl_Position =positions; 
}

Экран виджета не отображается, но когда я удаляю вызов glDrawArrays , он появляется. Я подозреваю, что в коде opengl есть какая-то проблема, которая вызывает это. Я следовал руководству по YouTube на всем его и мой код такой же, ожидайте, что я использую класс-оболочку qt opengl, а не библиотеку glew. В чем причина?

1 Ответ

0 голосов
/ 24 июня 2018

QOpenGLBuffer buffer1 является локальной переменной в методе megui::initializeGL(). Объекты Qt OpenGL используют технологию Resource Acquisition Is Initialization (RAII) . Это означает, что в конце функция buffer1 разрушена, а буфер исчез и недействителен.

Далее объект QOpenGLBuffer должен быть связан (bind()) до того, как может быть выделен (allocate()). См. Документацию QOpenGLBuffer::allocate.

Кстати, ваши координаты вершин состоят из 2-х компонентов (x, y), а не из 3.

Создать QOpenGLBuffer член в классе megui

class megui:public QOpenGLWidget, protected QOpenGLFunctions
{
public:
    QOpenGLFunctions glfunctions;
    QOpenGLShaderProgram program;

    QOpenGLBuffer buffer1;

    .....
}

megui::megui()
    : buffer1(QOpenGLBuffer::VertexBuffer)
{}

Привязать буфер перед его выделением:

void megui::initializeGL()
{
    .....

    buffer1.create();
    buffer1.setUsagePattern(QOpenGLBuffer::StaticDraw);

    buffer1.bind(); // <-------- bind before allocate
    buffer1.allocate(vertexpositions, sizeof(vertexpositions));


    float vertexpositions[] = {
        0.5f,0.5f,
        0.0f,-0.5f,
        0.5f,-0.5f
    };

    glfunctions.glEnableVertexAttribArray(0);

    glfunctions.glVertexAttribPointer(
        0, 2,       // <-------- 2 instead of 3
        GL_FLOAT, false, 0, 0);

    buffer1.release();

    .....
}
...