my openGL API need threads!!! But how to ,ake it work???

Discussion in 'Python' started by Laurent, Feb 2, 2006.

  1. Laurent

    Laurent Guest

    Hi,

    here is the context:

    I'm coding a openGL API I will need for a project for my school.
    This API is quite simple:

    an ooglScene describe all needed to make an openGL, and inherits from a
    list. So an ooglScene is fundamentaly a list of ooglObjects (which is
    organised as a Composite Pattern).

    ooglScene.run() do everthing needed to initialise GL and GLUT, and then
    launch the GLUT Main Loop.
    (the display function I wrote juste call the display method of each
    ooglObject in the ooglScene)

    Here is the problem!

    Once the GLUT Main Loop is launched, I cannot add other ooglObjects to
    my ooglScene, neither modify any existing ooglObject in my scene!

    exemple that works but is sequential:
    ------------------------------------------------------
    Scene = ooglScene()
    Scene.append(ooglObject())
    Scene.run()

    What I want to do:
    ---------------------------
    Scene = ooglScene()
    Scene.run()
    Scene.append(ooglObject())



    I don't know the threqding system, I've take a look on that but I don't
    know how to make what I need: the ooglScene.run() method must create a
    separate thread to launch the glutMainLoop!

    Actually I see only one solution: create two threads out of the
    ooglScene and launch run() in one, and the rest of my program in the
    other:

    Thread1.start() --> launch the ooglScene.run()
    Thread2.start() --> launch the rest of my program...

    THIS IS NOT ENOUGH TRANSPARENT IN MY POINT OF VIEW!!
     
    Laurent, Feb 2, 2006
    #1
    1. Advertisements

  2. Laurent

    Laurent Guest

    Here are my codes:
    it doesn't use threading...!

    # ------------------------------------------------------------
    # test_pyoogl.py
    # ------------------------------------------------------------

    #!/usr/bin/env python

    from pyoogl import *
    import unittest

    class test(unittest.TestCase):
    def testWindow(self):
    global Scene

    print 'Test 1:'
    print '-------'
    print 'This test simply verify if a GL window can be created.'
    print

    Scene = ooglScene()
    Scene.run()

    print 'Test 2:'
    print '-------'
    print 'Verify if a Point can ben drawed, and then if the
    ooglBaseObject inheritance scheme is in order.'
    print

    Scene.append(ooglPoint())

    if __name__ == '__main__':
    Scene = None
    unittest.main()

    # ------------------------------------------------------------
    # pyoogl.py
    # ------------------------------------------------------------

    #!/usr/bin/env python

    from OpenGL.GL import *
    from OpenGL.GLU import *
    from OpenGL.GLUT import *
    import math
    import sys
    import threading

    #-------------------------------------------------------------------------------
    class ooglBaseObject(object):
    def __init__(self):
    pass

    #-------------------------------------------------------------------------------
    class ooglObject(ooglBaseObject, list):
    """
    An ooglObject represent a object in a OpenGL scene.
    This is based on a Composite Pattern: an ooglObject is a list of
    ooglObjects, and an ooglObject can ben specialised in ooglPoint,
    ooglPolygon, ...
    """

    def __init__(self):
    ooglBaseObject.__init__(self)
    list.__init__(self)

    def ooglDraw(self):
    for obj in self:
    obj.ooglDraw()

    #-------------------------------------------------------------------------------
    class ooglPoint(ooglBaseObject):
    """
    An ooglPoint is the simpliest stuff you can creat into your scene.
    It inherits directly from ooglObject.
    """
    def __init__(self, **kwargs):
    ooglBaseObject.__init__(self)

    if 'x' in kwargs:
    self.__x = kargs['x']
    else:
    self.__x = 0

    if 'y' in kwargs:
    self.__y = kargs['y']
    else:
    self.__y = 0

    if 'z' in kwargs:
    self.__z = kargs['z']
    else:
    self.__z = 0

    def ooglSend(self):
    glVertex3f(self.__x, self.__y, self.__z)

    def ooglDraw(self):
    glBegin(GL_POINTS)
    self.ooglSend()
    glEnd()
    glFlush()

    #-------------------------------------------------------------------------------
    class ooglScene(list):
    """
    An ooglScene describe all that is needed to represent a OpenGL scene.
    Fundamentaly, this is a list of ooglObjects.
    """

    def __init__(self):
    list.__init__(self)

    # GLUT variables:
    self.__argv = sys.argv
    self.__DisplayMode = GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE
    self.__WindowPosition = {'x': 200, 'y': 200}
    self.__WindowSize = {'height': 250, 'width': 250}
    self.__WindowName = 'Untitled'
    self.__ClearColor = {'red': 0, 'green': 0, 'blue': 0, 'alpha': 0}

    # GL variables:
    self.__PointSize = 2
    self.__Enable = GL_DEPTH_TEST

    # Callback functions:
    self.__DisplayFunc = self.display
    self.__KeyboardFunc = self.keyboard

    # Display variables:
    self.__Clear = GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT
    self.__DefaultColor = {'red': 1, 'green': 1, 'blue': 1}

    def run(self):
    """
    Make the GL, GLUT initialisations & launch the GLUT main loop.
    """
    # GLUT initialisation + window creation:
    glutInit(self.__argv)
    glutInitDisplayMode(self.__DisplayMode)
    glutInitWindowPosition(self.__WindowPosition['x'],
    self.__WindowPosition['y'])
    glutInitWindowSize(self.__WindowSize['height'],
    self.__WindowSize['width'])
    glutCreateWindow(self.__WindowName)

    # GL initialisation:
    glClearColor(self.__ClearColor['red'], self.__ClearColor['green'],
    self.__ClearColor['blue'], self.__ClearColor['alpha'])
    glPointSize(self.__PointSize)
    glEnable(self.__Enable)

    # setting callback functions:
    glutDisplayFunc(self.__DisplayFunc)
    glutKeyboardFunc(self.__KeyboardFunc)

    # GLUT main loop:
    glutMainLoop()
    sys.exit(0)

    def display(self):
    """
    The default for glutDisplayFunc.
    """
    glClear(self.__Clear)

    glColor3f(self.__DefaultColor['red'], self.__DefaultColor['green'],
    self.__DefaultColor['blue'])
    for obj in self:
    obj.ooglDraw()

    glFlush()
    glutSwapBuffers()

    def keyboard(self, key, x, y):
    """
    The default for glutKeyboardFunc.
    """
    if key == 'q':
    sys.exit(1)
     
    Laurent, Feb 2, 2006
    #2
    1. Advertisements

  3. Do that in the registered event-functions. For example, keyboard(). After
    all, the user must somehow trigger the need for inserting objects or
    otherwise manipulating the scene. And that she does with either mouse or
    keyboard. I bet there is a mouse-callback, too.

    Diez
     
    Diez B. Roggisch, Feb 2, 2006
    #3
  4. Laurent

    Laurent Guest

    That is exactly what I do not want!!

    this is not transparent, I'm sure it is possible to make what I want:
    Scene = ooglScene()
    Scene.run()
    scene.append(ooglPoint())
     
    Laurent, Feb 2, 2006
    #4
  5. Well, if you know so well what you want, why don't you know how to do it?

    Besides: just using threads might help - but as well your whole application
    might crash, as inserting scene parts concurrently might f... up internal
    structures.

    But if you really want threads (albeit not knowing much about them...) here
    you go:


    import threading

    Scene = ooglScene()
    threading.Thread(target=Scene.run)
    scene.append(ooglPoint())


    Diez
     
    Diez B. Roggisch, Feb 2, 2006
    #5
  6. Laurent

    Laurent Guest

    This is not a fantasm...

    Why this can not work??

    in a thread a loop (the glut main loop) called by Scene.run()
    and in a second something else, e.g. function A

    A want to add an object in the Scene, the it call
    Scene.append(anObject)
    and in his next step, the glutmainloop will see that there is a new
    object in the list...

    If we cannot do something like that, wheere is the parrallelism? What
    are the advantages of threads??!!

    My code is quiet simple, plz take a look. I tried to launch the
    glutMainLoop in a separate thread:

    threading.Thread(glutMainLoop).start()

    but the execution never reach the print 'Test 2' --> the loop freeze
    the program, or the program wait for start() to end...

    How this can not stop at this point?
     
    Laurent, Feb 2, 2006
    #6
  7. Laurent

    Laurent Guest

    threading.Thread(target = Scene.run).start() WORKS !!!

    great thx ;)

    now this should be better if the thread can ben declared inside the
    class!
     
    Laurent, Feb 2, 2006
    #7
  8. Laurent

    Laurent Guest

    Youpiiiiiiiiiiiiiiiiiiiiiiiiiiiie!

    That work as I want!!!!

    Thx everybody ;)

    The problem was that I launched the glut main loop into a thread, and
    then it was separated from his initialisations functions


    I put it into another method and launch that method into a thread...!

    That work!
     
    Laurent, Feb 2, 2006
    #8
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.