【问题标题】:OpenGL-Intel 630 GPU -Ubuntu 16.04 failed to render simple triangleOpenGL-Intel 630 GPU - Ubuntu 16.04 无法渲染简单三角形
【发布时间】:2017-09-13 18:18:12
【问题描述】:

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

这是我的系统配置。 CPU - 英特尔 i5 7400(Kaby Lake 630 高清 GPU) 操作系统 - Ubuntu 16.04 64 位 台面 - 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;

}

【问题讨论】:

  • 如果你用鼠标改变窗口的大小,它会画什么,甚至只是背景颜色?
  • @Rabbid76 在 Ubuntu 中可能会发生许多奇怪的事情 :( 就像 OGL 仅在某些操作后才会启动。我以前在 Intel HD4000 上见过它。
  • 一些驱动默认启用depth_testing(违反opengl标准)。尝试明确禁用它。编辑:哦,我看到你正在运行 Mesa。你真勇敢,真是个赌徒;-)
  • @Ripi2 - 背景颜色变化是反射的,但没有三角形,如果尝试使用鼠标更改窗口大小,则会创建损坏的图像。
  • @Andreas - 在“glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);”中添加了 GL_DEPTH_BUFFER_BIT但对输出没有影响。

标签: opengl rendering ubuntu-16.04 intel mesa


【解决方案1】:

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

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

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

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

其他问题是您没有设置视口的大小(要在窗口内绘制的矩形,可能是整个窗口)。 OpenGL 使用适合窗口的默认视口。但是,如果您更改了需要再次调用glViewport 的窗口大小。结论:为您更改视口的 glfw 大小事件进行“回调”。

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

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

【讨论】:

  • 感谢@Ripi2 提供的宝贵信息。 1. GLUT lib 也出现了同样的问题。 2. 是的,我会尝试您建议的更改以将渲染代码带入循环、glViewport 并调用 glfw。 3. 同时,我尝试使用 320 es (ogles 3.2) 版本的着色器代码,它没有任何错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-08
  • 1970-01-01
  • 1970-01-01
  • 2020-04-05
  • 2017-02-04
  • 1970-01-01
相关资源
最近更新 更多