OpenGL窗口显示背景窗口中的内容而不是空白窗口

时间:2016-07-09 15:32:40

标签: c++ linux opengl graphics

我正在使用Linux并尝试学习OpenGL。我正在引用网站learnopengl.com并编制了第一个程序available here

我似乎用命令编译程序没有问题

g++ -Wall -lGLEW -lglfw -lGL -lX11 -lpthread -lXrandr -lXi ./foo.cpp

但是当我运行该程序时,它会显示后面的内容,而不是空白窗口,就像这样

enter image description here

但请注意,此窗口不透明,如果我移动窗口,背景相同。但是如果我最小化并重新打开窗口,则会新创建背景。这适用于专用和集成GPU。

我需要做些什么才能使其正常工作?

这是一些信息

System:    Host: aditya-pc Kernel: 4.4.13-1-MANJARO x86_64 (64 bit gcc: 6.1.1)
           Desktop: KDE Plasma 5.6.4 (Qt 5.6.0) Distro: Manjaro Linux
Machine:   System: HP (portable) product: HP Notebook v: Type1ProductConfigId
           Mobo: HP model: 8136 v: 31.36
           Bios: Insyde v: F.1F date: 01/18/2016
CPU:       Dual core Intel Core i5-6200U (-HT-MCP-) cache: 3072 KB
           flags: (lm nx sse sse2 sse3 sse4_1 sse4_2 ssse3 vmx) bmips: 9603
           clock speeds: max: 2800 MHz 1: 583 MHz 2: 510 MHz 3: 670 MHz 4: 683 MHz
Graphics:  Card-1: Intel Skylake Integrated Graphics bus-ID: 00:02.0
           Card-2: Advanced Micro Devices [AMD/ATI] Sun XT [Radeon HD 8670A/8670M/8690M / R5 M330]
           bus-ID: 01:00.0
           Display Server: X.Org 1.17.4 drivers: ati,radeon,intel
           Resolution: 1920x1080@60.06hz
           GLX Renderer: Mesa DRI Intel HD Graphics 520 (Skylake GT2)
           GLX Version: 3.0 Mesa 11.2.2 Direct Rendering: Yes

两张显卡的信息

Amd卡

$ DRI_PRIME=1 glxinfo|grep OpenGL
OpenGL vendor string: X.Org
OpenGL renderer string: Gallium 0.4 on AMD HAINAN (DRM 2.43.0, LLVM 3.8.0)
OpenGL core profile version string: 4.1 (Core Profile) Mesa 11.2.2
OpenGL core profile shading language version string: 4.10
OpenGL core profile context flags: (none)
OpenGL core profile profile mask: core profile
OpenGL core profile extensions:
OpenGL version string: 3.0 Mesa 11.2.2
OpenGL shading language version string: 1.30
OpenGL context flags: (none)
OpenGL extensions:
OpenGL ES profile version string: OpenGL ES 3.0 Mesa 11.2.2
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.00
OpenGL ES profile extensions:

英特尔集成

$ DRI_PRIME=0 glxinfo|grep OpenGL
OpenGL vendor string: Intel Open Source Technology Center
OpenGL renderer string: Mesa DRI Intel(R) HD Graphics 520 (Skylake GT2) 
OpenGL core profile version string: 3.3 (Core Profile) Mesa 11.2.2
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 11.2.2
OpenGL shading language version string: 1.30
OpenGL context flags: (none)
OpenGL extensions:
OpenGL ES profile version string: OpenGL ES 3.1 Mesa 11.2.2
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 3.10
OpenGL ES profile extensions:

1 个答案:

答案 0 :(得分:1)

从技术上讲,您遇到的是未定义的行为。所以这里发生了什么:你的程序要求图形系统创建一个新窗口,因为这个窗口将与OpenGL一起使用你正在使用的库(GLFW)询问图形系统不能自己清除窗口(原因是当播放动画时,图形系统在帧绘制之间清除窗口会导致闪烁,这是不必要的)。

这样就创建了一个新窗口,它需要图形内存才能做到这一点。目前,向用户呈现窗口有两种方式。一种是具有屏幕构图的离屏渲染。另一种是具有像素所有权测试的屏幕帧缓冲窗口。在你的情况下,你得到了两者中的较晚者。这意味着你的窗口基本上只是主屏幕帧缓冲区中的一个矩形,当它被创建为新的时,之前的任何内容都将保留在窗口中,直到它被所需的内容绘制出来。

当然这个"像素留下"行为是在任何地方指定的,它是最合理的实现行为的工件(在禁用Areo的Microsoft Windows上它的行为相同)。

指定的是,当窗口移动时,其内容随之移动。图形硬件,即使与1980年代后期一样古老,也有内置的特殊电路来高效地完成这项工作。但这只适用于窗口停留在屏幕帧缓冲区内的情况。如果您将窗口部分拖动到屏幕区域之外并再次向后移动,则会看到沿边缘复制的边框像素。

那么您需要做什么才能获得定义的结果?好吧,你必须实际绘制一些东西(可能就像清除它一样简单)到窗口 - 如果它是一个双缓冲的,则交换缓冲区。