OpenGL不渲染三角形

时间:2014-02-23 20:47:12

标签: qt opengl

我正在关注this tutorial并进行一些修改并获得此代码:

#define GLSL(src) "#version 330 core\n" #src

void MainWindow::initializeGL() {

    glClearColor(0, 0, 0, 1);

    // Generate buffers

    GLfloat verticies[] = {
        +0.0f, +1.0f, +0.0f,

        -1.0f, -1.0f, +0.0f,

        +1.0f, -1.0f, +0.0f,
    };

    GLuint vertexBufferID;
    glGenBuffers(1, &vertexBufferID);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBufferID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(verticies), verticies, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void *)0);

    // Generate shaders

    const char *vertexShaderSrc = GLSL(
        layout(location = 0) in vec3 pos;

        void main() {
            gl_Position.xyz = pos;
            gl_Position.w = 1.0;
        }
    );


    GLuint vertexShaderID = createGLShader(GL_VERTEX_SHADER, vertexShaderSrc);

    const GLchar *fragmentShaderSrc = GLSL(
        out vec4 color;

        void main() {
            color = vec4(0.0, 1.0, 0.0, 1.0);
        }
    );

    GLuint fragmentShaderID = createGLShader(GL_FRAGMENT_SHADER, fragmentShaderSrc);

    GLuint programID = glCreateProgram();
    glAttachShader(programID, vertexShaderID);
    glAttachShader(programID, fragmentShaderID);
    glLinkProgram(programID);
    glUseProgram(programID);
}

void MainWindow::paintGL() {
    //glViewport(0, 0, width(), height());
    glClear(GL_COLOR_BUFFER_BIT);

    glDrawArrays(GL_TRIANGLES, 0, 3);
    //glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, 0);
}

GLuint MainWindow::createGLShader(GLenum type, const GLchar* src) {
    GLuint shaderID = glCreateShader(type);
    glShaderSource(shaderID, 1, &src, 0);
    glCompileShader(shaderID);
    GLint vertexCompileStatus;
    glGetShaderiv(shaderID, GL_COMPILE_STATUS, &vertexCompileStatus);
    if (vertexCompileStatus != GL_TRUE) {
        GLint infoLogLength;
        glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &infoLogLength);
        GLchar buffer[infoLogLength];
        glGetShaderInfoLog(shaderID, infoLogLength, 0, buffer);
        qDebug(buffer);
    }
    return shaderID;
}

这全部包含在QGLWidget中。但是,当我运行此代码时,我只是得到一个黑屏。出了什么问题?我没有收到错误消息,因此着色器正在编译。

我设置了QGLWidget

#include "mainwindow.h"
#include <QApplication>
#include <QGLFormat>

int main(int argc, char *argv[]) {
    QApplication a(argc, argv);

    QGLFormat glFormat;
    glFormat.setVersion(3, 3);
    glFormat.setProfile(QGLFormat::CoreProfile);

    MainWindow w(glFormat);
    w.show();

    return a.exec();
}

1 个答案:

答案 0 :(得分:1)

保持“纯”OpenGL代码,您需要(至少)一个顶点数组对象。配置顶点数组时,以及每次从上述数组中绘制时,都需要绑定该对象。

因此,在调用gl*VertexAttribArray之前,创建并绑定VAO。添加

GLuint m_vao;

你班上的成员。然后在initializeGL

glGenVertexArrays(1, &m_vao);
glBindVertexArray(m_vao);

// now configure the arrays:
glEnableVertexAttribArray...
glVertexAttribArray...

// now release the VAO and move on
glBindVertexArray(0);

然后在paintGL我们再次需要VAO:

glBindVertexArray(m_vao);
glDrawArrays(...);
glBindVertexArray(0);

现在你的代码带有Qt 5 OpenGL enablers(没有尝试编译它,但你可以得到这个想法)。你告诉我哪一个更易读,更不容易出错。

#define GLSL(src) "#version 330 core\n" #src

void MainWindow::initializeGL() {

    glClearColor(0, 0, 0, 1);

    // Generate buffers

    GLfloat verticies[] = {
        +0.0f, +1.0f, +0.0f,

        -1.0f, -1.0f, +0.0f,

        +1.0f, -1.0f, +0.0f,
    };

    m_vertexBuffer = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
    m_vertexBuffer->create();
    m_vertexBuffer->setusagePatter(QOpenGLBuffer::StaticDraw);
    m_vertexBuffer->bind();
    m_vertexBuffer->allocate(verticies, sizeof(verticies);
    m_vertexBuffer->release();

    // Generate shaders

    const char *vertexShaderSrc = GLSL(
        layout(location = 0) in vec3 pos;

        void main() {
            gl_Position.xyz = pos;
            gl_Position.w = 1.0;
        }
    );

    const GLchar *fragmentShaderSrc = GLSL(
        out vec4 color;

        void main() {
            color = vec4(0.0, 1.0, 0.0, 1.0);
        }
    );

    m_program = new QOpenGLShaderProgram;
    m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSrc);     
    m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSrc);
    m_program->link();
    // error checking missing from the last three calls. if they return false, check log()

    m_vao = new QOpenGLVertexArrayObject;
    m_vao->bind();
    m_program->bind();

    m_vertexBuffer->bind();
    m_program->enableAttributeArray("pos");
    m_program->setAttributeBuffer("pos", GL_FLOAT, 0, 3);
    m_vertexBuffer->release();

    m_program->release();
    m_vao->release();
}

void MainWindow::paintGL() {       
    glClear(GL_COLOR_BUFFER_BIT);

    m_vao->bind();
    m_program->bind();

    glDrawArrays(GL_TRIANGLES, 0, 3);

    m_program->release();
    m_vao->release();
}