Как «обновить» до OpenGL 3.3 на Ubuntu 18.04.3 - PullRequest
0 голосов
/ 21 сентября 2019

Я много читал об этом, но пока не смог ничего решить.Я пытаюсь нарисовать цветной треугольник с OpenGL3, но я получаю следующую ошибку:

terminate вызывается после бросания экземпляра '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;
}

1 Ответ

1 голос
/ 21 сентября 2019

Когда вы используете glew, включите дополнительные расширения с помощью glewExperimental = GL_TRUE;.См. Документацию GLEW , в которой говорится:

GLEW получает информацию о поддерживаемых расширениях из графического драйвера.Однако экспериментальные или предварительные версии драйверов могут не сообщать о всех доступных расширениях через стандартный механизм, и в этом случае GLEW сообщит о том, что оно не поддерживается.Чтобы обойти эту ситуацию, глобальный коммутатор glewExperimental можно включить, установив его на GL_TRUE перед вызовом glewInit(), что обеспечивает доступ ко всем расширениям с действительными точками входа.

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.
Далее отметим, что 5-й параметр ()stride ) из glVertexAttribPointer, указывает смещение байта между последовательным универсальным атрибутом вершины.

Это означает, что перед вызовом glVertexAttribPointer объект Vertex Array и объект Vertex Buffer должны быть связаны.
Шаг *Параметр 1037 * должен быть 5*sizeof(Glfloat), поскольку атрибуты вершины состоят из 5 GLfloat значений (x, y, r, g, b).
Смещение для VERTEX_ATTR_POSITION равно 0, а для VERTEX_ATTR_COLORэто 2*sizeof(GLfloat), потому что (r, gb) - после (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 возможны, но кажутся странными.Это не должны быть индексы ресурсов атрибутов, которые могут быть установлены с помощью квалификатора макета или могут быть получены с помощью 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 };
...