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 与我的系统不兼容。

解决方案有两个:

  1. 将 Parallels 更新到 版本 17,现在包含一个专用的第三方虚拟 GPU (virGL) 运行宁 OpenGL 3.3 代码。
  2. 更新 Ubuntu 或至少更新内核,因为 virGL 仅适用于 linux 内核版本 5.10 及更高版本。 (Ubuntu Mate 18 仅搭载内核版本 5.04。)

就是这样,按照描述进行更改,使我能够 运行 代码 与发布的完全一致 并成功地将基本三角形渲染到屏幕上。