Окно pygame opengl не обновляется при вызове диспетчера python-osc

В настоящее время я работаю над трехмерной визуализацией нескольких точек, получая данные через osc (python-osc) и отображая их с помощью pygame. Основываясь на рабочем примере куба Pygame, я добавил функции диспетчера osc для получения данных, а затем вызвал функции для обновления отображения из этих функций диспетчера. Однако дисплей не будет обновляться при вызове этих функций из отправленных событий. Дисплей все еще обновляется, когда те же функции вызываются изначально (не диспетчером). Я все еще использовал куб для тестирования, а не для отображения полученных данных.

Я новичок в Python - так что сейчас немного беспомощный, чтобы найти причину такого поведения. Я думаю, что контекст диспетчера и основной программы не совпадают или что-то в этом роде - но не знаю, как это отладить... вот код, который я использую для обновления дисплея gl:

glRotatef(1, 3, 1, 1)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
cube()
pygame.display.flip()

и вот весь код:

import pygame
from pygame.locals import *
from OpenGL.GL import *
from OpenGL.GLU import *
from pythonosc import dispatcher
from pythonosc import osc_server
import argparse

class Displ:
    def __init__ (self):
        self.verticies = (
            (1, -1, -1),
            (1, 1, -1),
            (-1, 1, -1),
            (-1, -1, -1),
            (1, -1, 1),
            (1, 1, 1),
            (-1, -1, 1),
            (-1, 1, 1)
            )
        self.edges = (
            (0,1),
            (0,3),
            (0,4),
            (2,1),
            (2,3),
            (2,7),
            (6,3),
            (6,4),
            (6,7),
            (5,1),
            (5,4),
            (5,7)
            )

    def Cube(self):
        glBegin(GL_LINES)
        for edge in self.edges:
            for vertex in edge:
                glVertex3fv(self.verticies[vertex])
        glEnd()

    def makeWindow(self):
        pygame.init()
        display = (800,600)
        screen = pygame.display.set_mode(display, OPENGL)
        gluPerspective(45, (display[0]/display[1]), 0.1, 50.0)
        glTranslatef(0.0,0.0, -5)

    def drawUpdate(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                quit()
        glRotatef(1, 3, 1, 1)
        glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
        self.Cube()
        pygame.display.flip()
        #pygame.time.wait(10)

     def printPoints (addr, x,y,z):
        print ("Point {} {}".format( str(addr), str([x,y,z])))
        displ.drawUpdate()

if __name__ == "__main__":
  parser = argparse.ArgumentParser()
  parser.add_argument("--ip",
      default="127.0.0.1", help="The ip to listen on")
  parser.add_argument("--port",
      type=int, default=9003, help="The port to listen on")
  args = parser.parse_args()

  dispatcher = dispatcher.Dispatcher()
  dispatcher.map("/buoy/p1", printPoints)
  server = osc_server.ThreadingOSCUDPServer((args.ip, args.port), dispatcher)
  print("Serving on {}".format(server.server_address))

  displ = Displ()
  displ.makeWindow()
  displ.drawUpdate() # just for testing: this gets updated
  displ.drawUpdate() # and this...
  displ.drawUpdate() # but not if drawUpdate() is called by the dispatcher.
  server.serve_forever()

1 ответ

После того, как я нашел время для изучения того, как бороться с контекстом gl, я сдался. По-видимому, внутри GLUT невозможно легко получить и установить контекст окна, но некоторые хаки существуют. Я нашел свое собственное решение в создании второго потока, который создает и обновляет функцию отображения, чтобы контекст оставался в потоке:

import threading
import time

def loop():
    displ = Displ()
    displ.makeWindow()
    displ.drawUpdate()

    while(1):
        time.sleep(0.1)
        displ.drawUpdate()

threading.Thread(target=loop).start()
Другие вопросы по тегам