OpenGL 3 渲染问题 Linux (Ubuntu Mate)
OpenGL 3 Rendering Problems Linux (Ubuntu Mate)
我无法让 OpenGL(使用 GLFW)将内容呈现到屏幕上。当我 运行 我的应用程序时,我什至无法设置清晰的颜色并显示它,我只是一直看到黑屏。
我已经在我的系统上安装了必要的依赖项并设置了构建环境,这样我就可以成功地编译我的应用程序(和依赖项)而不会出错。这是有问题的代码片段...您会注意到很多渲染代码实际上已被注释掉。现在,只要显示我选择的清晰颜色即可验证所有设置是否正确:
// Include standard headers
#include <stdio.h>
#include <stdlib.h>
//Include GLEW. Always include it before gl.h and glfw3.h, since it's a bit magic.
#include <GL/glew.h>
// Include GLFW
#include <GLFW/glfw3.h>
// Include GLM
#include <glm/glm.hpp>
#include <GL/glu.h>
#include<common/shader.h>
#include <iostream>
using namespace glm;
int main()
{
// Initialise GLFW
glewExperimental = true; // Needed for core profile
if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW\n" );
return -1;
}
// Open a window and create its OpenGL context
GLFWwindow* window; // (In the accompanying source code, this variable is global for simplicity)
window = glfwCreateWindow( 1024, 768, "Tutorial 02", NULL, NULL);
if( window == NULL ){
fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window); // Initialize GLEW
//glewExperimental=true; // Needed in core profile
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
return -1;
}
//INIT VERTEX ARRAY OBJECT (VAO)...
//create Vertex Array Object (VAO)
GLuint VertexArrayID;
//Generate 1 buffer, put the resulting identifier in our Vertex array identifier.
glGenVertexArrays(1, &VertexArrayID);
//Bind the Vertex Array Object (VAO) associated with the specified identifier.
glBindVertexArray(VertexArrayID);
// Create an array of 3 vectors which represents 3 vertices
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
};
//INIT VERTEX BUFFER OBJECT (VBO)...
// This will identify our vertex buffer
GLuint VertexBufferId;
// Generate 1 buffer, put the resulting identifier in VertexBufferId
glGenBuffers(1, &VertexBufferId);
//Bind the Vertex Buffer Object (VBO) associated with the specified identifier.
glBindBuffer(GL_ARRAY_BUFFER, VertexBufferId);
// Give our vertices to OpenGL.
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
//Compile our Vertex and Fragment shaders into a shader program.
/**
GLuint programId = LoadShaders("../tutorial2-drawing-triangles/SimpleVertexShader.glsl","../tutorial2-drawing-triangles/SimpleFragmentShader.glsl");
if(programId == -1){
printf("An error occured whilst attempting to load one or more shaders. Exiting....");
exit(-1);
}
//glUseProgram(programId); //use our shader program
*/
// Ensure we can capture the escape key being pressed below
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
do{
// Clear the screen. It's not mentioned before Tutorial 02, but it can cause flickering, so it's there nonetheless.
glClearColor(8.0f, 0.0f, 0.0f, 0.3f);
//glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// DRAW OUR TRIANGE...
/**
glBindBuffer(GL_ARRAY_BUFFER, VertexBufferId);
glEnableVertexAttribArray(0); // 1st attribute buffer : vertices
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// plot the triangle !
glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle
glDisableVertexAttribArray(0); //clean up attribute array
*/
// Swap buffers
glfwSwapBuffers(window);
//poll for and process events.
glfwPollEvents();
} // Check if the ESC key was pressed or the window was closed
while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0 );
}
同样,就 OpenGL 而言,所有渲染逻辑、着色器加载等都已被注释掉,我只是想设置一个清晰的颜色并显示它以确保我的环境已配置正确。为了构建应用程序,我使用带有自定义 CMAKE 文件的 QTCreator。如果您认为它可能有助于确定问题,我可以 post make 文件。
所以我设法解决了这个问题。我将尝试简要概述问题的根源以及我是如何得出解决方案的,希望它对遇到相同问题的其他人有用:
简而言之,问题的根源是驱动程序问题,我忘了说我实际上是在 Ubuntu 中 运行ning OpenGL ] MacBook Pro(带有专用显卡)上的 Mate 18.0 VM(通过 Parallels 16) 问题就在这里; 直到最近,Parallels 和 Ubuntu 都不支持更现代的 OpenGL 3.3 及更高版本。我通过在发布的代码中添加以下行来发现这一点,以便 force 特定的 OpenGL 版本:
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
执行此操作后,应用程序立即开始崩溃,并且 glGetError()
报告我需要降级到较早版本的 OpenGL,因为 3.3 与我的系统不兼容。
解决方案有两个:
- 将 Parallels 更新到 版本 17,现在包含一个专用的第三方虚拟 GPU (virGL) 运行宁 OpenGL 3.3 代码。
- 更新 Ubuntu 或至少更新内核,因为 virGL 仅适用于 linux 内核版本 5.10 及更高版本。 (Ubuntu Mate 18 仅搭载内核版本 5.04。)
就是这样,按照描述进行更改,使我能够 运行 代码 与发布的完全一致 并成功地将基本三角形渲染到屏幕上。
我无法让 OpenGL(使用 GLFW)将内容呈现到屏幕上。当我 运行 我的应用程序时,我什至无法设置清晰的颜色并显示它,我只是一直看到黑屏。
我已经在我的系统上安装了必要的依赖项并设置了构建环境,这样我就可以成功地编译我的应用程序(和依赖项)而不会出错。这是有问题的代码片段...您会注意到很多渲染代码实际上已被注释掉。现在,只要显示我选择的清晰颜色即可验证所有设置是否正确:
// Include standard headers
#include <stdio.h>
#include <stdlib.h>
//Include GLEW. Always include it before gl.h and glfw3.h, since it's a bit magic.
#include <GL/glew.h>
// Include GLFW
#include <GLFW/glfw3.h>
// Include GLM
#include <glm/glm.hpp>
#include <GL/glu.h>
#include<common/shader.h>
#include <iostream>
using namespace glm;
int main()
{
// Initialise GLFW
glewExperimental = true; // Needed for core profile
if( !glfwInit() )
{
fprintf( stderr, "Failed to initialize GLFW\n" );
return -1;
}
// Open a window and create its OpenGL context
GLFWwindow* window; // (In the accompanying source code, this variable is global for simplicity)
window = glfwCreateWindow( 1024, 768, "Tutorial 02", NULL, NULL);
if( window == NULL ){
fprintf( stderr, "Failed to open GLFW window. If you have an Intel GPU, they are not 3.3 compatible. Try the 2.1 version of the tutorials.\n" );
glfwTerminate();
return -1;
}
glfwMakeContextCurrent(window); // Initialize GLEW
//glewExperimental=true; // Needed in core profile
if (glewInit() != GLEW_OK) {
fprintf(stderr, "Failed to initialize GLEW\n");
return -1;
}
//INIT VERTEX ARRAY OBJECT (VAO)...
//create Vertex Array Object (VAO)
GLuint VertexArrayID;
//Generate 1 buffer, put the resulting identifier in our Vertex array identifier.
glGenVertexArrays(1, &VertexArrayID);
//Bind the Vertex Array Object (VAO) associated with the specified identifier.
glBindVertexArray(VertexArrayID);
// Create an array of 3 vectors which represents 3 vertices
static const GLfloat g_vertex_buffer_data[] = {
-1.0f, -1.0f, 0.0f,
1.0f, -1.0f, 0.0f,
0.0f, 1.0f, 0.0f,
};
//INIT VERTEX BUFFER OBJECT (VBO)...
// This will identify our vertex buffer
GLuint VertexBufferId;
// Generate 1 buffer, put the resulting identifier in VertexBufferId
glGenBuffers(1, &VertexBufferId);
//Bind the Vertex Buffer Object (VBO) associated with the specified identifier.
glBindBuffer(GL_ARRAY_BUFFER, VertexBufferId);
// Give our vertices to OpenGL.
glBufferData(GL_ARRAY_BUFFER, sizeof(g_vertex_buffer_data), g_vertex_buffer_data, GL_STATIC_DRAW);
//Compile our Vertex and Fragment shaders into a shader program.
/**
GLuint programId = LoadShaders("../tutorial2-drawing-triangles/SimpleVertexShader.glsl","../tutorial2-drawing-triangles/SimpleFragmentShader.glsl");
if(programId == -1){
printf("An error occured whilst attempting to load one or more shaders. Exiting....");
exit(-1);
}
//glUseProgram(programId); //use our shader program
*/
// Ensure we can capture the escape key being pressed below
glfwSetInputMode(window, GLFW_STICKY_KEYS, GL_TRUE);
do{
// Clear the screen. It's not mentioned before Tutorial 02, but it can cause flickering, so it's there nonetheless.
glClearColor(8.0f, 0.0f, 0.0f, 0.3f);
//glClearColor(1.0f, 1.0f, 0.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
// DRAW OUR TRIANGE...
/**
glBindBuffer(GL_ARRAY_BUFFER, VertexBufferId);
glEnableVertexAttribArray(0); // 1st attribute buffer : vertices
glVertexAttribPointer(
0, // attribute 0. No particular reason for 0, but must match the layout in the shader.
3, // size
GL_FLOAT, // type
GL_FALSE, // normalized?
0, // stride
(void*)0 // array buffer offset
);
// plot the triangle !
glDrawArrays(GL_TRIANGLES, 0, 3); // Starting from vertex 0; 3 vertices total -> 1 triangle
glDisableVertexAttribArray(0); //clean up attribute array
*/
// Swap buffers
glfwSwapBuffers(window);
//poll for and process events.
glfwPollEvents();
} // Check if the ESC key was pressed or the window was closed
while( glfwGetKey(window, GLFW_KEY_ESCAPE ) != GLFW_PRESS &&
glfwWindowShouldClose(window) == 0 );
}
同样,就 OpenGL 而言,所有渲染逻辑、着色器加载等都已被注释掉,我只是想设置一个清晰的颜色并显示它以确保我的环境已配置正确。为了构建应用程序,我使用带有自定义 CMAKE 文件的 QTCreator。如果您认为它可能有助于确定问题,我可以 post make 文件。
所以我设法解决了这个问题。我将尝试简要概述问题的根源以及我是如何得出解决方案的,希望它对遇到相同问题的其他人有用:
简而言之,问题的根源是驱动程序问题,我忘了说我实际上是在 Ubuntu 中 运行ning OpenGL ] MacBook Pro(带有专用显卡)上的 Mate 18.0 VM(通过 Parallels 16) 问题就在这里; 直到最近,Parallels 和 Ubuntu 都不支持更现代的 OpenGL 3.3 及更高版本。我通过在发布的代码中添加以下行来发现这一点,以便 force 特定的 OpenGL 版本:
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
执行此操作后,应用程序立即开始崩溃,并且 glGetError()
报告我需要降级到较早版本的 OpenGL,因为 3.3 与我的系统不兼容。
解决方案有两个:
- 将 Parallels 更新到 版本 17,现在包含一个专用的第三方虚拟 GPU (virGL) 运行宁 OpenGL 3.3 代码。
- 更新 Ubuntu 或至少更新内核,因为 virGL 仅适用于 linux 内核版本 5.10 及更高版本。 (Ubuntu Mate 18 仅搭载内核版本 5.04。)
就是这样,按照描述进行更改,使我能够 运行 代码 与发布的完全一致 并成功地将基本三角形渲染到屏幕上。