C++ Qt 5.5,带QOpenGLWidget,岩心剖面中不可见三角形

C++ Qt 5.5,带QOpenGLWidget,岩心剖面中不可见三角形,c++,opengl,qt5.5,C++,Opengl,Qt5.5,我很难用QSurfaceFormat、QOpenGLfunctions、QOpenGLShaderProgram和opengl>=3.3等“新”的方式将hello triangle从我习惯的Qt之外的Glew和GLFW移植到Qt5.5和QOpenGlWidget中 这是我的QOpenGLWidget子类“OGLWidget”,我从中改编而来 我的代码可以编译,但我有一个黑屏。不再是三角形了 我在MacBookPro视网膜上使用Qt5.5,约塞米蒂10.10.5。英特尔虹膜处理器 你知道我应该修改

我很难用QSurfaceFormat、QOpenGLfunctions、QOpenGLShaderProgram和opengl>=3.3等“新”的方式将hello triangle从我习惯的Qt之外的Glew和GLFW移植到Qt5.5和QOpenGlWidget中

这是我的QOpenGLWidget子类“OGLWidget”,我从中改编而来

我的代码可以编译,但我有一个黑屏。不再是三角形了

我在MacBookPro视网膜上使用Qt5.5,约塞米蒂10.10.5。英特尔虹膜处理器

你知道我应该修改什么来再次向我的彩色三角形问好吗

谢谢

编辑

下面是解释注释的新版本代码,建议添加VAO。我认为VBO是必要的,但在这些最近的Qt类中没有可用的示例,我只是即兴创作。尽管如此,我的三角形仍然没有出现。我在这里进行了简化,因为我使用了直接在着色器中编码的单一颜色

OGLWidget::OGLWidget(QWidget *parent)
    :QOpenGLWidget(parent)
    , m_program(0)
{

}


OGLWidget::~OGLWidget()
{

}


static const char *vertexShaderSource =
"#version 330 core\n"
"layout (location = 0) in vec3 posAttr;\n"
"uniform mat4 matrix;\n"
"void main(){\n"
"    gl_Position = matrix * vec4(posAttr, 1.0f);\n"
"}\n";

static const char *fragmentShaderSource =
"#version 330 core\n"
"out vec4 color;\n"
"void main(){\n"
"    color = vec4(0.5f, 0.0f, 0.0f, 1.0f);\n"
"}\n";


void OGLWidget::initializeGL()
{

    initializeOpenGLFunctions();

    GLfloat vertices[] = {
        0.0f, 0.707f, 0.0f,
        -0.5f, -0.5f, 0.0f,
        0.5f, -0.5f, 0.0f
    };

    m_program = new QOpenGLShaderProgram(this);
    m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
    m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
    m_program->link();
    m_posAttr = m_program->attributeLocation("posAttr");
    m_matrixUniform = m_program->uniformLocation("matrix");

    const qreal retinaScale = devicePixelRatio();
    glViewport(0, 0, width() * retinaScale, height() * retinaScale);



    // Create Vertex Array Object
    m_vao.create();
    m_vao.bind();

    // Create Vertex Buffer (Do not release until VAO is created)
    m_vertexBuffer = QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
    m_vertexBuffer.create();
    m_vertexBuffer.bind();
    m_vertexBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
    m_vertexBuffer.allocate(sizeof(vertices));

    m_program->bind();

    m_program->setAttributeBuffer(m_posAttr, GL_FLOAT, 0, 3*sizeof(GLfloat));
    m_program->enableAttributeArray(m_posAttr);
    m_program->setAttributeArray(m_posAttr, vertices, 3);

    m_vao.release();
    m_vertexBuffer.release();
    m_program->release();

}

void OGLWidget::paintGL()
{

    glClear(GL_COLOR_BUFFER_BIT);

    m_program->bind();
    m_program->setUniformValue(m_matrixUniform, matrix);

    m_vao.bind();
    glDrawArrays(GL_TRIANGLES, 0 , 3);
    m_vao.release();

    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(0);

    m_program->release();

}

void OGLWidget::resizeGL(int w, int h)
{
    matrix.setToIdentity();
    matrix.perspective(60.0f, 4.0f/3.0f, 0.1f, 100.0f);
    matrix.translate(0, 0, -2);
}

在阅读和测试代码之后,我在这里提交了一些有用的东西。如果你认为有更好的方法(相对于Qt或openGL推荐的方法更好),请务必纠正我

(main.cpp不变)

oglwidget.h

#include <QWidget>
#include <QOpenGLWidget>
#include <QtGui/QWindow>
#include <QtGui/QOpenGLFunctions>
#include <QtGui/QOpenGLShaderProgram>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>

class QPainter;
class QOpenGLContext;
class QOpenGLPaintDevice;

class OGLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
public:
    OGLWidget(QWidget *parent = 0);
    ~OGLWidget();

protected:
    void initializeGL();
    void resizeGL(int w, int h);
    void paintGL();

private:
    bool prepareShaderProgram( const QString& vertexShaderPath,
                               const QString& fragmentShaderPath );

    QOpenGLVertexArrayObject m_vao;
    QOpenGLBuffer m_vertexBuffer;
    QOpenGLShaderProgram m_shader;
};
#包括
#包括
#包括
#包括
#包括
#包括
#包括
类油漆工;
类QOpenGLContext;
QoPENGLPAINT类器件;
OGLWidget类:公共QOpenGLWidget,受保护的QopenglFunction
{
公众:
OGLWidget(QWidget*parent=0);
~OGLWidget();
受保护的:
void initializeGL();
无效尺寸(整数w,整数h);
void paintGL();
私人:
bool prepareShaderProgram(常量QString和vertexShaderPath,
常量QString和fragmentShaderPath);
Qopengelvertexarrayobjectm_vao;
QOpenGLBuffer m_vertexBuffer;
QOpenGLShaderProgram MU着色器;
};
我没有把上面的内容放在我原来的帖子里。所以这会让事情变得更清楚。下面是一个更正的oglwidget.cpp,用于显示红色三角形

oglwidget.cpp

OGLWidget::OGLWidget(QWidget *parent)
    :QOpenGLWidget(parent)
    , m_shader(0)
    , m_vertexBuffer(QOpenGLBuffer::VertexBuffer)
{

}


OGLWidget::~OGLWidget()
{

}


void OGLWidget::initializeGL()
{

    initializeOpenGLFunctions();


    glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
    if ( !prepareShaderProgram( "/file Path To vertex shader source file", "/file Path To fragment shader source file" ) )
     return;

    GLfloat vertices[] = {
        0.0f, 0.707f, 0.0f,
        -0.5f, -0.5f, 0.0f,
        0.5f, -0.5f, 0.0f
    };
    // Setup Vertex Buffer
    m_vertexBuffer.create();
    m_vertexBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
    // Bind Vertex Buffer + check
    if ( !m_vertexBuffer.bind() )
     {
     qWarning() << "Could not bind vertex buffer to the context";
     return;
     }
    m_vertexBuffer.allocate(vertices, sizeof(vertices));

    // Bind the shader program so that we can associate variables from
    // our application to the shaders
    if ( !m_shader.bind() )
     {
     qWarning() << "Could not bind shader program to context";
     return;
     }

    // Create Vertex Array Object
    m_vao.create();
    m_vao.bind();

    m_shader.setAttributeBuffer("vertex", GL_FLOAT, 0, 3);
    m_shader.enableAttributeArray("vertex");

    m_vao.release();
    m_vertexBuffer.release();
    m_shader.release();

}

void OGLWidget::paintGL()
{


    glClear(GL_COLOR_BUFFER_BIT);

    m_shader.bind();

    m_vao.bind();
    glDrawArrays(GL_TRIANGLES, 0 , 3);
    m_vao.release();

    m_shader.release();

}

void OGLWidget::resizeGL(int w, int h)
{
//    const qreal retinaScale = devicePixelRatio();
//    glViewport(0, 0, width() * retinaScale, height() * retinaScale);
      glViewport( 0, 0, w, qMax( h, 1 ) );
}

bool OGLWidget::prepareShaderProgram(const QString &vertexShaderPath, const QString &fragmentShaderPath)
{
    // First we load and compile the vertex shader…
     bool result = m_shader.addShaderFromSourceFile( QOpenGLShader::Vertex, vertexShaderPath );
     if ( !result )
     qWarning() << m_shader.log();

    // fragment shader
     result = m_shader.addShaderFromSourceFile( QOpenGLShader::Fragment, fragmentShaderPath );
     if ( !result )
     qWarning() << m_shader.log();

    // link the shaders
     result = m_shader.link();
     if ( !result )
     qWarning() << "Could not link shader program:" << m_shader.log();

    return result;
}
OGLWidget::OGLWidget(QWidget*parent)
:QOpenGLWidget(父级)
,m_着色器(0)
,m_vertexBuffer(QOpenGLBuffer::vertexBuffer)
{
}
OGLWidget::~OGLWidget()
{
}
void OGLWidget::initializeGL()
{
初始化EnglFunctions();
glClearColor(0.0f、0.0f、0.0f、1.0f);
如果(!prepareShaderProgram(“/file Path To vertex shader source file”,“/file Path To fragment shader source file”))
返回;
GLfloat顶点[]={
0.0f,0.707f,0.0f,
-0.5f,-0.5f,0.0f,
0.5f,-0.5f,0.0f
};
//设置顶点缓冲区
m_vertexBuffer.create();
m_vertexBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
//绑定顶点缓冲区+检查
如果(!m_vertexBuffer.bind())
{

qWarning()Core profile capital-R要求您在设置attrib enable/pointer&render之前创建并绑定VAO。绑定VAO与我正在使用的QoPenglShaderProgramm类的所有绑定函数有何不同?我不能使用此类的方法来实现这一点吗?我看到Qt 5有一个for VAO,但不清楚这是否意味着int使用QOpenGLShaderProgram类进行eract。我找不到任何有效的示例。我用绑定VAO和VBO的代码编辑了我的答案。我仍然有一个黑色图像。我找到了一个有效的解决方案,这个问题可以重新打开以便发布吗?我试图使用你的代码,但没有成功。只出现了一个黑色小部件。有什么提示吗?我没有接触过这个专业版从4年以来,你使用的是什么平台/操作系统?Windows 10、MacOS X和Linux。必须支持所有平台:-/因为已经有几年了,我没有跟踪Qt和openGL中的更新,所以这可能不再像在so中一样有效。然而,这篇so文章与我上次编译它并在bo上运行它时的Github项目有关Windows 10和MacOsX是在2017年发布的,所以这篇文章比这篇文章还要新。也许你可以找到我是如何实现所有openGL上下文的,如果它仍然有效的话。
OGLWidget::OGLWidget(QWidget *parent)
    :QOpenGLWidget(parent)
    , m_program(0)
{

}


OGLWidget::~OGLWidget()
{

}


static const char *vertexShaderSource =
"#version 330 core\n"
"layout (location = 0) in vec3 posAttr;\n"
"uniform mat4 matrix;\n"
"void main(){\n"
"    gl_Position = matrix * vec4(posAttr, 1.0f);\n"
"}\n";

static const char *fragmentShaderSource =
"#version 330 core\n"
"out vec4 color;\n"
"void main(){\n"
"    color = vec4(0.5f, 0.0f, 0.0f, 1.0f);\n"
"}\n";


void OGLWidget::initializeGL()
{

    initializeOpenGLFunctions();

    GLfloat vertices[] = {
        0.0f, 0.707f, 0.0f,
        -0.5f, -0.5f, 0.0f,
        0.5f, -0.5f, 0.0f
    };

    m_program = new QOpenGLShaderProgram(this);
    m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource);
    m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource);
    m_program->link();
    m_posAttr = m_program->attributeLocation("posAttr");
    m_matrixUniform = m_program->uniformLocation("matrix");

    const qreal retinaScale = devicePixelRatio();
    glViewport(0, 0, width() * retinaScale, height() * retinaScale);



    // Create Vertex Array Object
    m_vao.create();
    m_vao.bind();

    // Create Vertex Buffer (Do not release until VAO is created)
    m_vertexBuffer = QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
    m_vertexBuffer.create();
    m_vertexBuffer.bind();
    m_vertexBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
    m_vertexBuffer.allocate(sizeof(vertices));

    m_program->bind();

    m_program->setAttributeBuffer(m_posAttr, GL_FLOAT, 0, 3*sizeof(GLfloat));
    m_program->enableAttributeArray(m_posAttr);
    m_program->setAttributeArray(m_posAttr, vertices, 3);

    m_vao.release();
    m_vertexBuffer.release();
    m_program->release();

}

void OGLWidget::paintGL()
{

    glClear(GL_COLOR_BUFFER_BIT);

    m_program->bind();
    m_program->setUniformValue(m_matrixUniform, matrix);

    m_vao.bind();
    glDrawArrays(GL_TRIANGLES, 0 , 3);
    m_vao.release();

    glDisableVertexAttribArray(1);
    glDisableVertexAttribArray(0);

    m_program->release();

}

void OGLWidget::resizeGL(int w, int h)
{
    matrix.setToIdentity();
    matrix.perspective(60.0f, 4.0f/3.0f, 0.1f, 100.0f);
    matrix.translate(0, 0, -2);
}
#include <QWidget>
#include <QOpenGLWidget>
#include <QtGui/QWindow>
#include <QtGui/QOpenGLFunctions>
#include <QtGui/QOpenGLShaderProgram>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>

class QPainter;
class QOpenGLContext;
class QOpenGLPaintDevice;

class OGLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
public:
    OGLWidget(QWidget *parent = 0);
    ~OGLWidget();

protected:
    void initializeGL();
    void resizeGL(int w, int h);
    void paintGL();

private:
    bool prepareShaderProgram( const QString& vertexShaderPath,
                               const QString& fragmentShaderPath );

    QOpenGLVertexArrayObject m_vao;
    QOpenGLBuffer m_vertexBuffer;
    QOpenGLShaderProgram m_shader;
};
OGLWidget::OGLWidget(QWidget *parent)
    :QOpenGLWidget(parent)
    , m_shader(0)
    , m_vertexBuffer(QOpenGLBuffer::VertexBuffer)
{

}


OGLWidget::~OGLWidget()
{

}


void OGLWidget::initializeGL()
{

    initializeOpenGLFunctions();


    glClearColor( 0.0f, 0.0f, 0.0f, 1.0f );
    if ( !prepareShaderProgram( "/file Path To vertex shader source file", "/file Path To fragment shader source file" ) )
     return;

    GLfloat vertices[] = {
        0.0f, 0.707f, 0.0f,
        -0.5f, -0.5f, 0.0f,
        0.5f, -0.5f, 0.0f
    };
    // Setup Vertex Buffer
    m_vertexBuffer.create();
    m_vertexBuffer.setUsagePattern(QOpenGLBuffer::StaticDraw);
    // Bind Vertex Buffer + check
    if ( !m_vertexBuffer.bind() )
     {
     qWarning() << "Could not bind vertex buffer to the context";
     return;
     }
    m_vertexBuffer.allocate(vertices, sizeof(vertices));

    // Bind the shader program so that we can associate variables from
    // our application to the shaders
    if ( !m_shader.bind() )
     {
     qWarning() << "Could not bind shader program to context";
     return;
     }

    // Create Vertex Array Object
    m_vao.create();
    m_vao.bind();

    m_shader.setAttributeBuffer("vertex", GL_FLOAT, 0, 3);
    m_shader.enableAttributeArray("vertex");

    m_vao.release();
    m_vertexBuffer.release();
    m_shader.release();

}

void OGLWidget::paintGL()
{


    glClear(GL_COLOR_BUFFER_BIT);

    m_shader.bind();

    m_vao.bind();
    glDrawArrays(GL_TRIANGLES, 0 , 3);
    m_vao.release();

    m_shader.release();

}

void OGLWidget::resizeGL(int w, int h)
{
//    const qreal retinaScale = devicePixelRatio();
//    glViewport(0, 0, width() * retinaScale, height() * retinaScale);
      glViewport( 0, 0, w, qMax( h, 1 ) );
}

bool OGLWidget::prepareShaderProgram(const QString &vertexShaderPath, const QString &fragmentShaderPath)
{
    // First we load and compile the vertex shader…
     bool result = m_shader.addShaderFromSourceFile( QOpenGLShader::Vertex, vertexShaderPath );
     if ( !result )
     qWarning() << m_shader.log();

    // fragment shader
     result = m_shader.addShaderFromSourceFile( QOpenGLShader::Fragment, fragmentShaderPath );
     if ( !result )
     qWarning() << m_shader.log();

    // link the shaders
     result = m_shader.link();
     if ( !result )
     qWarning() << "Could not link shader program:" << m_shader.log();

    return result;
}