【问题标题】:Display blinking with OpenGL on Ubuntu在 Ubuntu 上使用 OpenGL 显示闪烁
【发布时间】:2018-06-11 01:12:57
【问题描述】:

我目前正在使用 GLFW3 和 GLAD 生成器使用 C++ 开发一个简单的 OpenGL 应用程序。当我运行程序时,我的整个显示器都在闪烁黑色。我该如何解决这个问题?

#include "include/glad.h"
#include <GLFW/glfw3.h>

#include <iostream>


void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow *window);

// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;

int main()
{
    // glfw: initialize and configure
    // ------------------------------
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
    GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT,           "LearnOpenGL", NULL, NULL);
if (window == NULL)
{
    std::cout << "Failed to create GLFW window" << std::endl;
    glfwTerminate();
    return -1;
}
glfwMakeContextCurrent(window);
glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

// glad: load all OpenGL function pointers
// ---------------------------------------
if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
    std::cout << "Failed to initialize GLAD" << std::endl;
    return -1;
}

// render loop
// -----------
while (!glfwWindowShouldClose(window))
{
    // input
    // -----
    processInput(window);

    // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
    // -------------------------------------------------------------------------------
    glfwSwapBuffers(window);
    glfwPollEvents();
}

// glfw: terminate, clearing all previously allocated GLFW resources.
// ------------------------------------------------------------------
glfwTerminate();
return 0;
}

// process all input: query GLFW whether relevant keys are     pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow *window)
{
    if(glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);
}

// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
    // make sure the viewport matches the new window dimensions; note that width and
    // height will be significantly larger than specified on retina displays.
    glViewport(0, 0, width, height);
}

这是我的 glxinfo | grep OpenGL

OpenGL vendor string: Intel Open Source Technology Center
OpenGL renderer string: Mesa DRI Intel(R) Sandybridge Mobile 
OpenGL core profile version string: 3.3 (Core Profile) Mesa 17.0.7
OpenGL core profile shading language version string: 3.30
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
OpenGL core profile extensions:
OpenGL version string: 3.0 Mesa 17.0.7
OpenGL shading language version string: 1.30
OpenGL context flags: (none)
OpenGL extensions:
OpenGL ES profile version string: OpenGL ES 3.0 Mesa 17.0.7
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.00
OpenGL ES profile extensions:

我认为问题与 OpenGL 设置不仅影响我的项目,而且影响整个系统的事实有关。所以我想知道,这是我的代码有问题还是我的硬件有问题 - 只有系统升级才能解决这个可怕的闪烁问题。

【问题讨论】:

  • 你没有画任何东西,所以你会看到存储在(未初始化的)后台缓冲区中的任何东西。

标签: c++ linux opengl


【解决方案1】:

您的代码缺少绘图命令。您应该在处理输入之后但在交换缓冲区之前将绘图命令添加到渲染循环中。

例如用蓝色填充背景

    ...
    while (!glfwWindowShouldClose(window))
    {
        processInput(window);

        glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }
    ...

【讨论】:

  • 哇,它现在可以工作了。但我仍然想知道,它为什么会闪烁?
  • glfwSwapBuffers() 交换 FRONT 和 BACK 缓冲区。前者用于在屏幕上显示,后者用于渲染(通过 OpenGL 命令)。如果您只清除一次,则一个缓冲区填充有“清除颜色”,另一个缓冲区处于其初始状态(在这种情况下填充为 0,使其变为黑色)。由于重复的glfwSwapBuffers(),它们交替出现,(答案告诉如何解决这个问题)。
  • 实际上,现代 GL 实现可能会使用超过 2 个缓冲区,以任何顺序,也可能随时重新分配新的缓冲区。从 GL 方面来看,在缓冲区交换操作之后,后台缓冲区的内容明确地是 undefined 的,因此当您在不绘制的情况下交换时可能会出现 everything (获得零或部分先前不过,框架是最常见的)。
  • 同意@derhass。当您不清除缓冲区时,它将绘制当前缓冲区中的内容,这很可能会产生故障/损坏的视图。
猜你喜欢
  • 2015-07-25
  • 1970-01-01
  • 1970-01-01
  • 2012-05-30
  • 1970-01-01
  • 2013-01-21
  • 2014-07-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多