glClearColor返回负值?是否为溢出问题?(GLES2+EGL+PyOpenGL环境)
问题分析与解决方案
我刚看了你的问题,这其实是个数据类型不匹配导致的小坑,不是GPU或者OpenGL的bug,别担心!
为什么会读出-1?
你用了arrays.GLcharArray.asArray()来创建缓冲区,而GLcharArray对应的是有符号8位字符类型(和C语言里的signed char一致)。当glReadPixels以GL_UNSIGNED_BYTE格式输出数据时,255这个无符号字节值,放到有符号char里就会被解析成-1(因为二进制11111111作为有符号数就是-1的补码)。
你测试glClearColor(1.0,1.0,1.0,1.0)时所有通道都是-1,正好对应每个通道的无符号值都是255,转成有符号char就全是-1了,完全符合这个逻辑。
怎么解决?
把缓冲区改成无符号字节类型就行,有两种简单的方式:
方式1:用PyOpenGL的GLubyteArray
直接把GLcharArray换成GLubyteArray,它专门对应无符号8位字节:
glClearColor(0.0, 0.0, 0.0, 1.0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) eglSwapBuffers(display, surface) # 换成GLubyteArray buffer = arrays.GLubyteArray.asArray(np.empty(1000 * 2 * 4, np.ubyte)) print("\nBuffer before : ", buffer[:20]) glReadPixels(0, 0, 1000, 2, GL_RGBA, GL_UNSIGNED_BYTE, buffer) print("Buffer after: ", buffer[0:20])
方式2:直接用numpy的uint8数组传递
其实PyOpenGL可以直接接受numpy的无符号字节数组,不用绕arrays模块,代码更简洁:
glClearColor(0.0, 0.0, 0.0, 1.0) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) eglSwapBuffers(display, surface) # 直接创建uint8数组 buffer = np.empty(1000 * 2 * 4, dtype=np.uint8) print("\nBuffer before : ", buffer[:20]) glReadPixels(0, 0, 1000, 2, GL_RGBA, GL_UNSIGNED_BYTE, buffer) print("Buffer after: ", buffer[0:20])
预期输出
修改后,你应该能看到符合预期的结果:
当glClearColor(0.0,0.0,0.0,1.0)时,输出会是:
Buffer before : [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] Buffer after: [ 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255 0 0 0 255]
而glClearColor(1.0,1.0,1.0,1.0)时,输出会是全255的数组。
另外提个小细节:eglSwapBuffers之后其实是交换到前台缓冲区,如果你要读刚绘制的后台缓冲区,其实可以在eglSwapBuffers之前调用glReadPixels,这样逻辑上更准确(不过不影响最终结果)。
内容的提问来源于stack exchange,提问作者AdishRao
相关产品推荐
相关产品推荐

