2012-01-13 2 views
2

크로스 플랫폼이어야하는 wxPython + pyOpenGL 애플리케이션이 있습니다. init_color_buffers 지금Windows에서 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)  

:

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 

지금이 작성되었으며 맥 OS에 완벽하게 작동 이제 선택을 위해 나는 다음과 기본적으로 같은 방식을 따기 색상을 구현했습니다. 하지만 지금은 창문에 그것을 시도하면 전혀 작동하지 않습니다. 생성 된 색상 사전은 {(0, 0, 0) : last_index} 뿐이며 모든 항목에 대한 모든 클릭 또한 (0, 0, 0)을 반환합니다. 이제 저는 여기서 제가 잘못하고있는 일에 정말로 혼란 스럽습니다. 특히 MacOS에서는 모든 것이 잘 작동합니다. 내 유일한 추측은 glReadPixels 어떻게 든 Windows에서 제대로 작동하지 않습니다 또는 wxPython 어떻게 든 그것을 엉망이 될 것이라고?!

도움을 주시면 감사하겠습니다. 이유를 glReadPixels에 대한 호출을() 될 수있다

감사합니다, 보그

답변

1

당신은 init_color_buffers에있는 뷰포트를 설정하지 않는 블랙 픽셀을 반환합니다. 또한 투영 행렬이 설정되지 않습니다. 어쩌면 호출 순서는 Mac과 Windows에서 약간 다릅니다 (완전한 소스 코드가 없어도 어렵습니다).

윈도우에서 glViewport()는 일반적으로 OpenGL이 초기화 된 후 윈도우가 처음 표시되는 지점에서 호출됩니다. 이는 init_color_buffers가 호출 된 시점 이후 일 것입니다. 일반적으로 glReadPixels()이 무언가를 반환하려면 창을 볼 수 있어야합니다.

지연 초기화를 사용해보십시오 (init_color_buffers를 호출하기 전에 창이 표시되는지 확인하십시오).

또한 GL_RED_BITS, GL_GREEN_BITS 및 GL_BLUE_BITS와 함께 glGetIntegerv()를 사용하면 다시 읽을 필요없이 올바른 색상을 계산할 수 있습니다 (또한 코드가 가능한 모든 색상을 사용하지 않고 최대 256 개까지만 표시 할 수 있음). 별개의 색상이지만 8 비트 RGB에서는 2^24 색상을 표시 할 수 있습니다).

+0

조언을 주셔서 감사합니다. 제안을 시도해 보겠습니다. 나는 모든 색상을 사용하지는 않는다는 것을 압니다. 그러나 나는 단지 120 색을 필요로하기 때문에 더 이상 복잡하게 만들고 싶지 않았습니다. – Bogdan

+0

또한 투영 행렬은 gluPerspective (45.0, ratio, 0.1, 800.0)로 시작하기 전에 initGl에서 한 번 설정되고 이후에는 전혀 변경되지 않습니다. init_color_buffers에서 다시 호출해야합니까? – Bogdan

+0

그런데 꼭 필요한 것은 아닙니다. Mac에서 작동하는 경우 Windows에서도 작동합니다. 나는 또한 정점 데이터에서 작은 에러를 발견했다. 6 번째 정점의 y 좌표는 100이어야한다.하지만 그것은 아무 것도 영향을 미치지 않아야한다. –