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
我写了一个简单的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