【问题标题】:How to "upgrade" to OpenGL 3.3 on Ubuntu 18.04.3如何在 Ubuntu 18.04.3 上“升级”到 OpenGL 3.3
【发布时间】:2020-01-22 03:31:55
【问题描述】:

我已经阅读了很多关于此的内容,但还没有解决任何问题。我正在尝试使用 OpenGL3 绘制彩色三角形,但出现以下错误:

在抛出 'std::runtime_error' what() 实例后调用终止:顶点着色器的编译错误(来自文件 ./TP1/shaders/triangle.vs.glsl):0:1(10) : 错误:不支持 GLSL 3.30。 支持的版本有:1.10、1.20、1.30、1.00 ES、3.00 ES、3.10 ES 和 3.20 ES

当我运行 glxinfo | grep -i opengl 我明白了:

OpenGL vendor string: Intel Open Source Technology Center 
OpenGL renderer string: Mesa DRI Intel(R) HD Graphics 6000 (Broadwell GT3)  
OpenGL core profile version string: 3.3 (Core Profile) Mesa 19.0.8 
OpenGL core profile shading language version string: 4.50 
OpenGL core profile context flags: (none) 
OpenGL core profile profile mask: core profile 
OpenGL version string: 3.0 Mesa 19.0.8
OpenGL shading language version string: 4.50 
OpenGL context flags: (none) 
OpenGL profile mask: compatibility profile 
OpenGL extensions: 
OpenGL ES profile version string: 
OpenGL ES 3.1 Mesa 19.0.8 
OpenGL ES profile shading language version string:
OpenGL ES GLSL ES 3.10 
OpenGL ES profile extensions:

我尝试了 export MESA_GL_VERSION_OVERRIDE=3.3,这使我能够执行代码,但我只是得到一个奇怪的三角形,而不是一个漂亮的等边多色三角形。 这是我的完整代码:

#include <glimac/SDLWindowManager.hpp>
#include <GL/glew.h>
#include <iostream>
#include <glimac/Program.hpp>
#include <glimac/FilePath.hpp>

using namespace glimac;

int main(int argc, char** argv) {

    // Initialize SDL and open a window
    SDLWindowManager windowManager(800, 600, "GLImac");

    // Initialize glew for OpenGL3+ support
    GLenum glewInitError = glewInit();
    if(GLEW_OK != glewInitError) {
        std::cerr << glewGetErrorString(glewInitError) << std::endl;
        return EXIT_FAILURE;
    }

    std::cout << "OpenGL Version : " << glGetString(GL_VERSION) << std::endl;
    std::cout << "GLEW Version : " << glewGetString(GLEW_VERSION) << std::endl;

    //load shaders and tell OpenGL to use them
    FilePath applicationPath(argv[0]);
    Program program = loadProgram(applicationPath.dirPath() + "shaders/triangle.vs.glsl",
                                    applicationPath.dirPath() + "shaders/triangle.fs.glsl");
    program.use();

    GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo); 

    //triangle data
    GLfloat vertices[] = { -0.5f, -0.5f, 1.f, 0.f, 0.f, //2 coordinates + 1 0 0 color
                         0.5f, -0.5f, 0.f, 1.f, 0.f,
                         0.0f, 0.5f, 0.f, 0.f, 1.f };

    glBufferData(GL_ARRAY_BUFFER, (15*(sizeof(float))), vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    GLuint vao;
    glGenVertexArrays(1, &vao); 
    glBindVertexArray(vao);
    const GLuint VERTEX_ATTR_POSITION = 3;
    const GLuint VERTEX_ATTR_COLOR = 8;
    glEnableVertexAttribArray(VERTEX_ATTR_POSITION);
    glEnableVertexAttribArray(VERTEX_ATTR_COLOR);

    const GLvoid* bouche;
    glVertexAttribPointer(VERTEX_ATTR_POSITION, 2, GL_FLOAT, GL_FALSE, (0*sizeof(GL_FLOAT)), bouche);
    glVertexAttribPointer(VERTEX_ATTR_COLOR, 3, GL_FLOAT, GL_FALSE, (2*sizeof(GL_FLOAT)), bouche);

    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glVertexAttribPointer(VERTEX_ATTR_POSITION, 2, GL_FLOAT, GL_FALSE, (2*sizeof(GL_FLOAT)), 0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    glBindVertexArray(0);


    // Application loop:
    bool done = false;
    while(!done) {
        // Event loop:
        SDL_Event e;
        while(windowManager.pollEvent(e)) {
            if(e.type == SDL_QUIT) {
                done = true; // Leave the loop after this iteration
            }
        }

        //clean window
        glClear(GL_COLOR_BUFFER_BIT);
        glBindVertexArray(vao);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        glBindVertexArray(0);

        // Update the display
        windowManager.swapBuffers();
    }

    //liberate allocated memory on GPU (the vbo and vao)
    glDeleteBuffers(1, &vbo);
    glDeleteVertexArrays(1, &vao);
    return EXIT_SUCCESS;
}

【问题讨论】:

    标签: c++ opengl opengl-3


    【解决方案1】:

    当您使用 glew 时,请通过 glewExperimental = GL_TRUE; 启用其他扩展。请参阅GLEW documentation,上面写着:

    GLEW 从图形驱动程序获取有关支持的扩展的信息。然而,实验性或预发布驱动程序可能不会通过标准机制报告每个可用的扩展,在这种情况下,GLEW 将报告它不受支持。为了避免这种情况,可以在调用glewInit()之前将glewExperimental全局开关设置为GL_TRUE,这样可以确保所有具有有效入口点的扩展都会被暴露。

    glewExperimental = GL_TRUE;
    GLenum glewInitError = glewInit();
    if(GLEW_OK != glewInitError) {
        std::cerr << glewGetErrorString(glewInitError) << std::endl;
        return EXIT_FAILURE;
    }
    

    当命名缓冲区对象绑定到目标 GL_ARRAY_BUFFER 时,glVertexAttribPointer 的最后一个参数将被视为该缓冲区的字节偏移量。
    glVertexAttribPointer被调用时,则顶点数组规范存储在当前绑定的顶点数组对象的状态向量中。当前绑定到目标GL_ARRAY_BUFFER 的缓冲区与属性相关联,对象的名称(值)存储在 VAO 的状态向量中。
    进一步注意,glVertexAttribPointer 的第 5 个参数 (stride) 指定连续通用顶点属性之间的字节偏移量。

    这意味着在调用glVertexAttribPointer 之前必须绑定Vertex Array ObjectVertex Buffer Object
    stride 参数必须是5*sizeof(Glfloat),因为顶点属性由 5 个GLfloat 值(x、y、r、g、b)组成。
    VERTEX_ATTR_POSITION 的偏移量为 0,VERTEX_ATTR_COLOR 的偏移量为 2*sizeof(GLfloat),因为 (r, g b) 在 (x, y) 之后。请注意,GL_FLOAT 是枚举器常量而不是数据类型,因此2*sizeof(GL_FLOAT) 不会按照您的预期执行。

    //triangle data
    GLfloat vertices[] = { -0.5f, -0.5f, 1.f, 0.f, 0.f, //2 coordinates + 1 0 0 color
                            0.5f, -0.5f, 0.f, 1.f, 0.f,
                            0.0f, 0.5f,  0.f, 0.f, 1.f };
    
    // create vertex buffer object
    GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    
    // vertex array object
     GLuint vao;
    glGenVertexArrays(1, &vao); 
    glBindVertexArray(vao);
    
    // specify the array of generic vertex attribute data
    glBindBuffer(GL_ARRAY_BUFFER, vbo); // if "vbo" is still bound then that would not be necessary
    glVertexAttribPointer(VERTEX_ATTR_POSITION, 2, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), nullptr);
    glVertexAttribPointer(VERTEX_ATTR_COLOR,    3, GL_FLOAT, GL_FALSE, 5*sizeof(GLfloat), 2*sizeof(GLfloat));
    
    glEnableVertexAttribArray(VERTEX_ATTR_POSITION);
    glEnableVertexAttribArray(VERTEX_ATTR_COLOR);
    
    // the following is not necessary, you can let them bound
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
    

    确保顶点属性索引正确:

    const GLuint VERTEX_ATTR_POSITION = 3;
    const GLuint VERTEX_ATTR_COLOR = 8;
    

    3 和 8 是可能的,但看起来很奇怪。不是这个应该是属性的资源索引,可以通过Layout qualifier设置,或者在程序链接后可以通过glGetAttribLocation获取。


    顺便说一下,等边三角形的坐标例如:

    GLfloat vertices[] = { 
         x        y      r    g    b
        -0.866f, -0.5f,  1.f, 0.f, 0.f,
         0.866f, -0.5f,  0.f, 1.f, 0.f,
         0.0f,    1.0f,  0.f, 0.f, 1.f };
    

    【讨论】:

    • @Monica 为什么会出现错误?我以为你会得到“一个奇怪的三角形,而不是一个漂亮的等边多色三角形”Running mac os x c++ program working with OpenGL 3.3 的答案可能会有所帮助。
    • 我在段落开头收到与上述相同的错误:错误:不支持 GLSL 3.30。如果我再次执行 export MESA_GL_VERSION_OVERRIDE=3.3 命令,通过您对代码的修改,我没有得到任何三角形。
    • @Monica glewExperimental = GL_TRUE; 丢失。我已经扩展了答案,请参见第一段。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-02
    相关资源
    最近更新 更多