OpenGL 不渲染三角形

Posted

技术标签:

【中文标题】OpenGL 不渲染三角形【英文标题】:OpenGL Does Not Render Triangle 【发布时间】:2014-02-23 20:47:11 【问题描述】:

我正在关注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();

【问题讨论】:

@huseyintugrulbuyukisik 感谢您的建议,但没有区别。 @huseyintugrulbuyukisik 那么为什么该代码可以在教程中使用? 对不起,我把它误读为 c++。能给个教程链接吗? @huseyintugrulbuyukisik 这是c++ 能给个教程链接吗? 【参考方案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();

【讨论】:

感谢代码示例。我得到它来编译修复一些错别字,但我仍然得到一个黑屏。

以上是关于OpenGL 不渲染三角形的主要内容,如果未能解决你的问题,请参考以下文章

OpenGL不使用纹理渲染

初学者 openGL 项目渲染三角形的问题

OpenGL 三角形不会在 macOS 上渲染?

OpenGL:如何渲染完美的矩形渐变?

OpenGL:不能不渲染三角形

使用着色器渲染“顶点彩色”三角形时的OpenGL“黑屏”