You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyOpenGL中glDrawPixels函数的使用方法及体素引擎中像素颜色设置问题

解决glDrawPixels只绘制黑色像素的问题

我来帮你梳理下当前代码里的问题,以及如何让glDrawPixels画出彩色像素:

问题根源分析

  1. 空的像素缓冲区:你初始化的buffer是bytearray(width * height * 3),而bytearray默认所有元素都是0。RGB值为(0,0,0)就是黑色,所以画出来自然是全黑区域。
  2. glDrawPixels参数顺序错误:这个函数的前两个参数是宽度和高度,但你代码里传的是display[1](高度)和display[0](宽度),顺序搞反了,这会导致绘制的区域变形或者位置不对。
  3. 绘制顺序导致的覆盖:你先画下方三角形,再调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 09:02:40