【问题标题】:OpenGL 3 Rendering Problems Linux (Ubuntu Mate)OpenGL 3 渲染问题 Linux (Ubuntu Mate)
【发布时间】:2022-01-16 12:16:37
【问题描述】:

我无法让 OpenGL(使用 GLFW)将内容呈现到屏幕上。我什至无法设置清晰的颜色并在运行我的应用程序时显示它,我只是一直呈现黑屏。

我已经在我的系统上安装了必要的依赖项并设置了构建环境,以便我能够成功地编译我的应用程序(和依赖项)而不会出错。这是有问题的代码的 sn-p... 您会注意到许多渲染代码实际上已被注释掉。现在,只需显示我选择的 Clear Color 即可验证所有设置是否正确:

// 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 而言,所有渲染逻辑、着色器加载等都已被注释掉。我只是想设置一个清晰的颜色并显示它以确保我的环境配置正确。为了构建应用程序,我将 QTCreator 与自定义 CMAKE 文件一起使用。如果您认为它可能有助于确定问题,我可以发布 make 文件。

【问题讨论】:

  • glfwCreateWindow 返回的与window 关联的OpenGL 版本是什么?至少您需要使用glGetError 检查各种OpenGL 调用报告的错误。
  • 我确实有一堆 glGetError 调用在我发布的这个主类和我创建的 ShaderLoader 实用程序中运行,每个调用都始终返回 0,表示没有遇到错误。关于窗口,我在之后立即进行的检查是否不足以检测窗口创建过程中的任何和所有错误。就像我说的一切似乎都正常,没有警告或编译错误,只是我无法将任何东西真正呈现到屏幕上。
  • 您是否还有其他可能存在的问题?
  • 您没有设置 OpeGL 视口,这可能是个问题。 int width, height; glfwGetFramebufferSize(window, &amp;width, &amp;height); 并将其传递给 glViewport(0, 0, width); glScissor(0,0, with, height);
  • 您实际看到了什么?请注意,glClearColor 的值被限制在 [0, 1] 范围内,所以我希望您的清晰颜色是半透明的红色。

标签: c++ ubuntu opengl qt-creator glfw


【解决方案1】:

所以我设法解决了这个问题。我将尝试简明扼要地概述问题的根源以及我是如何得出解决方案的,希望它可能对遇到相同问题的其他人有用:

简而言之,问题的根源在于驱动程序问题,我没有提到我实际上是在 MacBook Pro 上的 Ubuntu Mate 18.0 VM(通过 Parallels 16)内运行 OpenGL(使用专用图形)这就是问题所在; 直到最近,Parallels 和 Ubuntu 都不支持更现代的 OpenGL 3.3 及更高版本。为了强制一个特定的 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,现在包括一个能够运行 OpenGL 3.3 代码的专用第三方虚拟 GPU (virGL)。
  2. 更新 Ubuntu 或至少更新内核,因为 virGL 仅适用于 5.10 及更高版本的 linux 内核。 (Ubuntu Mate 18 仅附带内核版本 5.04。)

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

【讨论】:

    猜你喜欢
    • 2013-06-06
    • 2013-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多