OpenGL-Intel 630 GPU -Ubuntu 16.04 渲染简单三角形失败

OpenGL-Intel 630 GPU -Ubuntu 16.04 failed to render simple triangle

我写了一个简单的openGL代码来渲染三角形,编译成功但渲染三角形失败。仅创建一个 window,这样 glGetError() api 调用不会出现错误 return。相同的代码在 AMD R9 GPU 上运行良好。驱动程序安装也是正确的,因为我能够 运行 glxdemos 像 glxgears 或 glxhead 而没有任何错误。 请帮我找出这个问题的根本原因。

这是我的系统配置。 CPU - 英特尔 i5 7400(Kaby Lake 630 HD GPU) OS - Ubuntu 16.04 64 位 MESA - 3.0 v17.03

这是我渲染三角形的代码。

#include <stdio.h>
#include <stdlib.h>
#include <GL/glew.h>
#include <GLFW/glfw3.h>

int main(int agrc, char **argv)
{
    //do windowing related stuff here

    if ( !glfwInit())
    {
            printf("Error: Failed to initialize GLFW\n");
            return -1;
    }

    GLFWwindow* window = glfwCreateWindow(800, 600, "Triangle", NULL, NULL);
    if (window == NULL)
    {
            printf("Failed to create GLFW window\n");
            glfwTerminate();
            return -1;
    }
    glfwMakeContextCurrent(window);

    glewExperimental = GL_TRUE;
    if (glewInit() != GLEW_OK)
    {
            printf("Error: Failed to initialize GLEW\n");
            return -1;
    }

    //declare vertices
    GLfloat verts[] =
    {
            +0.0f, +0.5f, +0.0f,
            -0.5f, -0.5f, +0.0f,
            +0.5f, -0.5f, +0.0f,
    };

    //VBO related activity
    //declare VAO, VBO 
    GLuint VAO, VBO, EBO;

    //get unique name/ID
    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);
    //glGenBuffers(1, &EBO);

    // Bind VAO first, then bind and set VBOs and then configure vertex attributes
    //bind VAO
    glBindVertexArray(VAO);

    //bind VBO
    glBindBuffer(GL_ARRAY_BUFFER, VBO);

    //copy data to GPU
    glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

    glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glBindVertexArray(VAO);
    glDrawArrays(GL_TRIANGLES, 0, 3);

    glfwSwapBuffers(window);

    do{
            glfwPollEvents();
    }while(glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS && glfwWindowShouldClose(window) == 0);
    return 0;

}

我不知道这是否能解决您的问题,至少这里有一些建议:

您只渲染一次三角形(通过调用 glDrawArrays),就在 glew 和其他 gl 设置之后。这不好,因为一旦发生变化,您的图片就会丢失。 "something changes"的主要是window大小和位置。

Ubuntu(Xorg 或 Wayland)中的 window 管理器是异步的。这意味着您应该等到 window 可用(Xorg 的说法是 "realized")。处理这个问题的一种方法是轮询事件,因为通常 window 是实现的,然后给定大小和位置,这些动作会触发事件。

所以你的代码的第一件事是你应该将你的渲染代码移动到你调用 glfwPollEvents.

的循环中

其他问题是您没有设置视口的大小(要在 window 内绘制的矩形,可能是整个 window)。 OpenGL 使用适合 window 的默认视口。但是如果你改变 window 的大小,你需要再次调用 glViewport 。结论:为更改视口的 glfw 大小事件创建 "callback"。

你也不用着色器。好吧,也许对于您的第一个测试应用程序,您可以避免使用它们(OpenGL 具有默认着色器)。但我强烈建议现在就开始使用它们,即使是第一次使用它们也有点困难。他们是必须的。

最后,请遵循使用 OpenGL >= 3.2 的优秀教程。那里有很多。举两个例子:https://learnopengl.com/ and Learning Modern 3D Graphics Programming