Выбор цвета pyOpenGL на окнах - PullRequest
2 голосов
/ 13 января 2012

У меня есть приложение 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. Но теперь, когда я пробую это на окнах, это не будет работать вообще. Созданный словарь цветов - это просто {(0, 0, 0): last_index}, а также любой щелчок по любому из моих элементов также возвращает (0, 0, 0). Теперь я действительно озадачен тем, что я делаю здесь неправильно, тем более что на MacOS все работает нормально. Я могу только предположить, что либо glReadPixels как-то не работает должным образом на Windows, либо wxPython на Windows как-то испортил?!

Любая помощь будет принята с благодарностью.

С уважением, Богдан

1 Ответ

1 голос
/ 13 января 2012

Вы не настраиваете область просмотра в init_color_buffers, это может быть причиной того, что вызовы glReadPixels () возвращают черные пиксели.Кроме того, матрица проекции не устанавливается.Может быть, порядок вызовов немного отличается на Mac и в Windows (трудно сказать без полного исходного кода).

В 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 цвета).

...