PyOpenGL中glDrawPixels函数的使用方法及体素引擎中像素颜色设置问题
解决glDrawPixels只绘制黑色像素的问题
我来帮你梳理下当前代码里的问题,以及如何让glDrawPixels画出彩色像素:
问题根源分析
- 空的像素缓冲区:你初始化的
buffer是bytearray(width * height * 3),而bytearray默认所有元素都是0。RGB值为(0,0,0)就是黑色,所以画出来自然是全黑区域。 - glDrawPixels参数顺序错误:这个函数的前两个参数是宽度和高度,但你代码里传的是
display[1](高度)和display[0](宽度),顺序搞反了,这会导致绘制的区域变形或者位置不对。 - 绘制顺序导致的覆盖:你先画下方三角形,再调用glDrawPixels(覆盖中间区域),最后画上方三角形,所以下方三角形被黑色缓冲区截断,上方的则完整显示。
修复步骤与代码示例
1. 给缓冲区填充彩色像素
要显示颜色,你需要手动修改buffer里的字节值。比如我们可以把整个缓冲区填充为红色(RGB(255,0,0)),或者随机设置一些彩色像素:
# 初始化缓冲区为红色(每个像素占3字节:R, G, B) buffer = bytearray([255, 0, 0] * (width * height)) # 或者随机生成彩色像素 buffer = bytearray(np.random.randint(0, 256, size=width*height*3, dtype=np.uint8))
2. 修正glDrawPixels的参数顺序
把宽高参数调换过来:
glDrawPixels(display[0], display[1], GL_RGB, GL_UNSIGNED_BYTE, buffer)
3. 调整绘制顺序(可选)
如果你不想让glDrawPixels覆盖三角形,可以把它的调用放在绘制三角形之前,这样三角形会画在缓冲区上方。
修改后的完整代码
import glfw from OpenGL.GL import * import numpy as np import pyrr def CreateWindow(title="Baguette game",width=800,height=600): display = (width,height) # 初始化缓冲区为红色(RGB(255,0,0)) buffer = bytearray([255, 0, 0] * (width * height)) # 或者换成随机彩色像素: # buffer = bytearray(np.random.randint(0, 256, size=width*height*3, dtype=np.uint8)) window = glfw.create_window(width,height,title, None, None) glfw.set_window_pos(window,400,200) glfw.make_context_current(window) return window, display, buffer def DrawTriangle(pointA=[-0.5, -0.5, 0.0],pointB=[0.5, -0.5,0.0], pointC=[-0.5, 0, 0.0],color=[1.0,0,0]): vertices = [pointA[0], pointA[1], pointA[2], pointB[0], pointB[1], pointB[2], pointC[0], pointC[1], pointC[2]] colors = [color[0], color[1], color[2], color[0], color[1], color[2], color[0], color[1], color[2] ] v = np.array(vertices,dtype=np.float32) c = np.array(colors, dtype=np.float32) glEnableClientState(GL_VERTEX_ARRAY) glVertexPointer(3, GL_FLOAT,0,v) glEnableClientState(GL_COLOR_ARRAY) glColorPointer(3, GL_FLOAT,0,c) glDrawArrays(GL_TRIANGLES,0,3) if __name__=="__main__": window, display, buffer = CreateWindow() z=1 while not glfw.window_should_close(window): glfw.poll_events() glClear(GL_COLOR_BUFFER_BIT) # 可选:先画缓冲区,再画三角形,避免覆盖 # glDrawPixels(display[0], display[1], GL_RGB, GL_UNSIGNED_BYTE, buffer) DrawTriangle([-0.5, -0.5, z],[0.5, -0.5,z],[-0.5, 0, z]) # 修正后的glDrawPixels调用 glDrawPixels(display[0], display[1], GL_RGB, GL_UNSIGNED_BYTE, buffer) DrawTriangle([-0.5, 0.5, z],[0.5, 0.5,z],[-0.5, 1, z]) glfw.swap_buffers(window) glfw.terminate()
额外说明
glDrawPixels是比较老旧的OpenGL函数,如果你开发体素引擎,长远来看更推荐使用纹理映射或者**帧缓冲对象(FBO)**来实现像素级绘制,性能会更好。但如果只是入门阶段,用glDrawPixels来理解像素操作是没问题的。- 每个像素的RGB值范围是0-255(对应GL_UNSIGNED_BYTE类型),所以你需要把颜色值转换成0到255的整数,而不是三角形里用的0.0-1.0的浮点数。
内容的提问来源于stack exchange,提问作者Druide
相关产品推荐
相关产品推荐

