我的qtopengl小部件没有显示?

时间:2018-06-24 07:45:23

标签: c++ qt opengl qt5

main.cpp

#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.h

#include "QtGuiApplication4.h"

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

qtguiapplication4.cpp

#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.h

#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()
{
}

megui.cpp

#version 430

out vec4 inalcolors;

void main() {

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

fragmentshader

#version 430 

layout(location = 0) in vec4 positions;

void main() {

    gl_Position =positions; 
}

vertexshader

<activity
    android:name="com.example.android.GizmosActivity"
    android:label="@string/title_gizmos" >
    <intent-filter android:label="@string/filter_view_http_gizmos">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <!-- Accepts URIs that begin with "http://www.example.com/gizmos” -->
            <data android:scheme="http"
                  android:host="www.example.com"
                  android:pathPrefix="/gizmos" />
            <!-- note that the leading "/" is required for pathPrefix-->
        </intent-filter> 
</activity>

窗口小部件屏幕没有显示,但是当我删除 glDrawArrays 调用时它出现了。我怀疑opengl代码中存在一些问题导致了此问题。他和我的代码相同,期望我使用qt opengl wrapper类而不是glew库。这是什么原因?

1 个答案:

答案 0 :(得分:0)

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();

    .....
}