I want to interact with the prompt (do some calculations, give my
application more things to draw, etc.) while visualizing my plot. In
other words I'm trying to reproduce sympy's "plotting" library
functionality which uses a separate thread for pyglet. I would use
their library but it is based on pyglet 1.0 and I have no idea on how
to migrate their ManagedWindow and PlotWindow classes to pyglet 1.1...
I'm sure you could tell me what's wrong with it though in a blink of
an eye ;), so here it is (thanks for the quick reply btw):

#!/usr/bin/env python

import Camera
import Controller

from time import clock
from threading import Thread, Lock

from pyglet.window import Window
from pyglet.clock import Clock
from pyglet.gl import *

gl_lock = Lock()

class ManagedWindow(Window):

    '''a pyglet window with an event loop which executes automatically
in a
    separate thread. behavior is added by creating a subclass which
overrides
    setup, update, and/or draw.'''

    def __init__(self, **win_args):

        '''ManagedWindow class initialization

        notes:
        ------
        - it is best not to override this function in the child class,
unless
          you need to take additional arguments
        - do any OpenGL initialization calls in setup()'''

        #-- default values
        self.fps_limit = 30 #-- deprecated
        self.default_win_args = dict(width=600, height=500,
vsync=False, resizable=True)
        self.win_args = dict(self.default_win_args, **win_args)

        self.Thread = Thread(target=self.__event_loop__)
        self.Thread.start()


    def __event_loop__(self, **win_args):

        '''the event loop thread function.

        notes:
        ------
        do not override or call directly (it is called by __init__)'''

        #-- initialize window
        gl_lock.acquire()
        try:
            try:
                super(ManagedWindow, self).__init__(**self.win_args)
                self.switch_to()
                self.setup()
            except Exception, e:
                print "Window initialization failed: %s" % (str(e))

        finally:
            gl_lock.release()

        #-- window event loop

        clock = Clock()
        clock.set_fps_limit(self.fps_limit)

        while not self.has_exit:
            dt = clock.tick()
            gl_lock.acquire()
            try:
                try:
                    self.switch_to()
                    self.dispatch_events()
                    self.clear()
                    self.update(dt)
                    self.draw()
                    self.flip()
                except Exception, e:
                    print "Uncaught exception in event loop: %s" %
str(e)
                    self.has_exit = True

            finally:
                gl_lock.release()

        super(ManagedWindow, self).close()

    def setup(self):

        '''setup window

        notes:
        ------
        called once before the event loop begins
        override this method in a child class
        this is the best place to put things like OpenGL
initialization calls'''

        pass


    def close(self):

        '''close window'''

        self.close()


    def update(self, dt):

        ''' update window

        notes:
        ------
        called before draw during each iteration of the event loop
        dt is the elapsed time in seconds since the last update
        OpenGL rendering calls are best put in draw() rather than
here'''

        pass


    def draw(self):

        '''called after update during each iteration of the event loop
        put OpenGL rendering calls here'''

        pass



class PlotWindow(ManagedWindow):

    '''
    PlotWindow - inherited from managed window
    '''

    def __init__(self, plot, **kwargs):

        '''PlotWindow class initialization

        keyword arguments:
        ------------------
        antialiasing = True (True or False)
        ortho = False (True or False)
        invert_mouse_zoom = False (True or False)
        linewidth = SCALAR'''

        self.plot = plot
        self.camera = None
        self.antialiasing = kwargs.pop('antialiasing', True)
        self.ortho = kwargs.pop('ortho', False)
        self.invert_mouse_zoom = kwargs.pop('invert_mouse_zoom',
False)
        self.linewidth = kwargs.pop('linewidth', 1.5)
        self.pointsize = kwargs.pop('pointsize', 4.5)
        self.title = kwargs.setdefault('caption', "Figure")
        self.last_caption_update = 0
        self.caption_update_interval = 0.2
        self.drawing_first_object = True

        super(PlotWindow, self).__init__(**kwargs)

    def setup(self):

        '''setup window'''

        #-- instantiate camera
        self.camera = Camera.PlotCamera(self, ortho=self.ortho)

        #-- instantiate controller
        self.controller = Controller.PlotController(self,
invert_mouse_zoom=self.invert_mouse_zoom)
        self.push_handlers(self.controller)

        #-- OpenGL initialization
        glClearColor(1.0, 1.0, 1.0, 0.0)
        #glClearColor(0.95, 0.95, 0.95, 0.0)
        glClearDepth(1.0)

        glDepthFunc(GL_LESS)
        glEnable(GL_DEPTH_TEST)

        glEnable(GL_LINE_SMOOTH)
        glShadeModel(GL_SMOOTH)
        glLineWidth(self.linewidth)

        glEnable(GL_POINT_SMOOTH)
        glPointSize(self.pointsize)

        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

        if self.antialiasing:
            glHint(GL_LINE_SMOOTH_HINT, GL_NICEST)
            glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST)
            #glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE)
            #glHint(GL_POLYGON_SMOOTH_HINT, GL_DONT_CARE)

        self.camera.setup_projection()


    def on_resize(self, w, h):

        '''resize window - pyglet on_resize'''

        super(PlotWindow, self).on_resize(w, h)
        if self.camera is not None:
            self.camera.setup_projection()


    def update(self, dt):

        '''update window'''

        #-- update window controller
        self.controller.update(dt)


    def draw(self):

        '''draw in window'''

        #-- render lock
        self.plot._render_lock.acquire()

        self.camera.apply_transformation()

        calc_verts_pos = 0
        calc_verts_len = 0
        calc_cverts_pos = 0
        calc_cverts_len = 0

        should_update_caption = (clock()-self.last_caption_update >
self.caption_update_interval)

        #-- set first object flag
        if len(self.plot._gobjects.values()) == 0:
            self.drawing_first_object = True

        for r in self.plot._gobjects.itervalues():

            if self.drawing_first_object:

                #-- set camera rotation
                self.camera.set_rot_preset(r.default_rot_preset)

                #-- reset first object flag
                self.drawing_first_object = False

            #-- plot graphic objects
            glPushMatrix()
            r._draw()
            glPopMatrix()

            #-- update caption, might as well do this while we are
iterating
            #-- and have the lock rather than locking and iterating
twice per
            #-- frame
            if should_update_caption:
                try:
                    if r.calculating_verts:
                        calc_verts_pos += r.calculating_verts_pos
                        calc_verts_len += r.calculating_verts_len

                    if r.calculating_cverts:
                        calc_cverts_pos += r.calculating_cverts_pos
                        calc_cverts_len += r.calculating_cverts_len

                except:
                    pass

        #-- plot objects
        for r in self.plot._pobjects:
            glPushMatrix()
            r._draw()
            glPopMatrix()

        #-- update caption
        if should_update_caption:
            self.update_caption(calc_verts_pos, calc_verts_len,
calc_cverts_pos, calc_cverts_len)
            self.last_caption_update = clock()

        #-- save screenshot
        if self.plot._screenshot:
            self.plot._screenshot._execute_saving()

        #-- release render lock
        self.plot._render_lock.release()


    def update_caption(self, calc_verts_pos, calc_verts_len,
calc_cverts_pos, calc_cverts_len):

        '''update window caption'''

        caption = self.title
        if calc_verts_len or calc_cverts_len:
            caption += " (calculating"
            if calc_verts_len > 0:
                p = (calc_verts_pos/calc_verts_len)*100
                caption += " vertices %i%%" % (p)

            if calc_cverts_len > 0:
                p = (calc_cverts_pos/calc_cverts_len)*100
                caption += " colors %i%%" % (p)

            caption += ")"

        if self.caption != caption:
            self.set_caption(caption)


if __name__ == '__main__':
    ManagedWindow()

On Mar 6, 10:57 pm, Richard Jones <[email protected]> wrote:
> On Mon, Mar 7, 2011 at 2:44 PM, hugo <[email protected]> wrote:
> > I want to create an interactive OpenGL application with pyglet and I
> > was wondering what is the best way to do so.
>
> You'll have to be more specific about what you mean by "an interactive
> OpenGL application". Please read the events bits of the programming
> guide and see if they are enough interaction for you.
>
> http://pyglet.org/doc/programming_guide/
>
>     Richard

-- 
You received this message because you are subscribed to the Google Groups 
"pyglet-users" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/pyglet-users?hl=en.

Reply via email to