【问题标题】:pyOpenGL color picking on windowsWindows上的pyOpenGL颜色拾取
【发布时间】:2012-01-13 22:47:06
【问题描述】:

我有需要跨平台的 wxPython + pyOpenGL 应用程序。现在为了选择,我实现了一个颜色选择方案,基本上如下:

if len(self.pick_color_array) == 0:
    self.init_color_buffers(len(self.points))
glUseProgram(0)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glDisable(GL_BLEND) 
glDisable(GL_DITHER)
glDisable(GL_FOG) 
glDisable(GL_LIGHTING) 
glDisable(GL_TEXTURE_1D) 
glDisable(GL_TEXTURE_2D) 
glDisable(GL_TEXTURE_3D) 
glShadeModel(GL_FLAT)
glPushMatrix()           
glTranslate(self.x_translation_step,self.y_translation_step, 
                        Z_DISTANCE + z_translation)

glRotate(alpha_rotation, 0.0, 0.0, 1.0)
glRotate(beta_rotation, 0.0, 1.0, 0.0)
self.apply_connectivity_nose_correction()
for i in range(len(self.points)):
     glColor3ub(self.pick_color_array[i][0], self.pick_color_array[i][1], self.pick_color_array[i][2])
     glEnableClientState(GL_VERTEX_ARRAY) 
     glBindBuffer(GL_ARRAY_BUFFER, self.positions_buffers[i][0])
     glVertexPointer(3, GL_FLOAT, 0, None)
     glBindBuffer(GL_ARRAY_BUFFER, self.positions_buffers[i][2])

     glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, self.positions_buffers[i][2])
     glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, None) 
glPopMatrix()
viewport = glGetIntegerv(GL_VIEWPORT)
pixel = glReadPixels(self.control.mouse_x(), float(viewport[3] - float(self.control.mouse_y())), 1, 1, 
                     GL_RGB, GL_UNSIGNED_BYTE)
glUseProgram(self.shader.shader)
glEnable(GL_BLEND) 
glEnable(GL_DITHER)
glEnable(GL_FOG) 
glEnable(GL_LIGHTING) 
glEnable(GL_TEXTURE_1D) 
glEnable(GL_TEXTURE_2D) 
glEnable(GL_TEXTURE_3D) 
glShadeModel(GL_SMOOTH)    

现在是 init_color_buffers:

    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()
    self.pick_color_dict = {}
    self.pick_color_array = []
    vertices = numpy.array([
         0.0,  1000.0,  0.0,
        -1000.0, -1000.0,  1000.0,
         1000.0, -1000.0,  1000.0,
         0.0,  1000.0,  0.0,
         1000.0, -1000.0,  1000.0,
         1000.0, -1000.0, -1000.0,
         0.0,  100.0,  0.0,
         1000.0, -1000.0, -1000.0,
        -1000.0, -1000.0, -1000.0,
         0.0,  1000.0,  0.0,
        -1000.0, -1000.0, -1000.0,
        -1000.0, -1000.0,  1000.0
    ], dtype=numpy.float32)
    buffer_cube = glGenBuffers(1)
    glBindBuffer(GL_ARRAY_BUFFER, buffer_cube)
    glBufferData(GL_ARRAY_BUFFER, ADT.arrayByteCount(vertices), 
                    ADT.voidDataPointer(vertices), GL_STATIC_DRAW)
    glUseProgram(0)
    glDisable(GL_BLEND) 
    glDisable(GL_DITHER)
    glDisable(GL_FOG) 
    glDisable(GL_LIGHTING) 
    glDisable(GL_TEXTURE_1D) 
    glDisable(GL_TEXTURE_2D) 
    glDisable(GL_TEXTURE_3D) 
    glMatrixMode(GL_MODELVIEW)
    glLoadIdentity()     
    glShadeModel(GL_FLAT)   
    for i in range(nr_points):
        self.pick_color_array.append((numpy.uint8(255.0/nr_points*i), 
                                      numpy.uint8(255 - 255.0/nr_points*i), 
                                      numpy.uint8(255.0/nr_points*i)))
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glColor3ub(self.pick_color_array[i][0], self.pick_color_array[i][1], self.pick_color_array[i][2])
        glEnableClientState(GL_VERTEX_ARRAY) 
        glBindBuffer(GL_ARRAY_BUFFER, buffer_cube)
        glVertexPointer(3, GL_FLOAT, 0, None)
        glDrawArrays(GL_TRIANGLES, 0, 12) 
        pixel = glReadPixels(10, 10, 1, 1, 
                     GL_RGB, GL_UNSIGNED_BYTE)
        from binascii import hexlify
        bit_repr = bin(int(b"1" + hexlify(pixel), 16))[3:]    
        color_0 = 0
        for bit in bit_repr[:8]:
            color_0 = color_0 * 2 + numpy.uint8(bit)
        color_1 = 0
        for bit in bit_repr[8:16]:
            color_1 = color_1 * 2 + numpy.uint8(bit)
        color_2 = 0
        for bit in bit_repr[16:]:
            color_2 = color_2 * 2 + numpy.uint8(bit)              
        self.pick_color_dict[(color_0, color_1, color_2)] = i 

现在这是在 MacOS 上编写并完美运行的。但是现在当我在 Windows 上尝试它时,它根本不起作用。创建的颜色字典只是一个 {(0, 0, 0): last_index} 并且对我的任何项目的任何点击也会返回 (0, 0, 0)。现在我真的很困惑我在这里做错了什么,特别是因为在 MacOS 上一切正常。我唯一的猜测是 glReadPixels 在 Windows 上无法正常工作,或者在 Windows 上的 wxPython 以某种方式搞砸了?!

任何帮助将不胜感激。

问候, 波格丹

【问题讨论】:

    标签: opengl wxpython pyopengl


    【解决方案1】:

    您没有在 init_color_buffers 中设置任何视口,这可能是调用 glReadPixels() 返回黑色像素的原因。此外,没有设置投影矩阵。也许 Mac 和 Windows 上的调用顺序有点不同(没有完整的源代码很难说)。

    在窗口上,glViewport() 通常在 OpenGL 初始化之后在窗口第一次显示时被调用。这可能是在调用 init_color_buffers 之后。通常,该窗口应该是可见的,以便 glReadPixels() 返回一些东西。

    尝试使用延迟初始化(在调用 init_color_buffers 之前确保窗口可见)。

    此外,您可以将 glGetIntegerv() 与 GL_RED_BITS、GL_GREEN_BITS 和 GL_BLUE_BITS 一起使用,以便在无需回读的情况下计算正确的颜色(此外,您的代码没有使用它可以使用的所有颜色,它最多只能显示 256 种不同的颜色颜色,但使用 8 位 RGB 可以显示 2^24 种颜色)。

    【讨论】:

    • 感谢您的建议,我会尝试这些建议。我知道我没有使用所有颜色,但由于我最多只需要 120 种颜色,我不想再复杂化。
    • 此外,投影矩阵在 initGl 中设置一次,在使用 gluPerspective(45.0, ratio, 0.1, 800.0) 之前调用它,之后它根本不会改变。我还应该在 init_color_buffers 中再次调用它吗?
    • 那就没必要了。它也应该在 Windows 上运行,以防它在 Mac 上运行。我还注意到您的顶点数据中有一个小错误,第 6 个顶点的 y 坐标是 100,应该是 1000。但这不会影响任何事情。
    猜你喜欢
    • 2015-06-16
    • 2013-10-04
    • 1970-01-01
    • 1970-01-01
    • 2014-08-31
    • 2015-04-15
    • 2021-05-06
    • 1970-01-01
    • 2021-07-20
    相关资源
    最近更新 更多