留一個神python代碼——混合使用wxpython和pyglet(cocos2d編輯器)

來源:互聯網
上載者:User

import wx
import pyglet
from pyglet.gl import *

import sys

if sys.platform == 'win32':
    from pyglet.window.win32 import _user32
    from pyglet.gl import wgl
elif sys.platform.startswith('linux'):
    from pyglet.image.codecs.gdkpixbuf2 import gdk
    from pyglet.gl import glx

class AbstractCanvas(pyglet.event.EventDispatcher):
    def __init__(self, context, config):
        # Create context (same as pyglet.window.Window.__init__)
        if not config:
            platform = pyglet.window.get_platform()
            display = platform.get_default_display()
            screen = display.get_screens()[0]
            for template_config in [
                pyglet.gl.Config(double_buffer=True, depth_size=24),
                pyglet.gl.Config(double_buffer=True, depth_size=16)]:
                try:
                    config = screen.get_best_config(template_config)
                    break
                except pyglet.window.NoSuchConfigException:
                    pass
            if not config:
                raise pyglet.window.NoSuchConfigException(
                    'No standard config is available.')

        if not config.is_complete():
            config = screen.get_best_config(config)

        if not context:
            context = config.create_context(pyglet.gl.current_context)

        self._display = display
        self._screen = screen
        self._config = config
        self._context = context

    def on_resize(self, width, height):
        self.switch_to()
        glViewport(0, 0, width, height)
        glMatrixMode(GL_PROJECTION)
        glLoadIdentity()
        glOrtho(0, width, 0, height, -1, 1)
        glMatrixMode(GL_MODELVIEW)

    def switch_to(self):
        self._switch_to_impl()
        self._context.set_current()
        pyglet.gl.gl_info.set_active_context()
        pyglet.gl.glu_info.set_active_context()

    def _switch_to_impl(self):
        raise NotImplementedError('abstract')

    def flip(self):
        raise NotImplementedError('abstract')
    
AbstractCanvas.register_event_type('on_draw')
AbstractCanvas.register_event_type('on_resize')

class AbstractWxCanvas(wx.Panel, AbstractCanvas):
    def __init__(self, parent, id=-1, config=None, context=None):
        wx.Window.__init__(self, parent, id, style=wx.FULL_REPAINT_ON_RESIZE)
        AbstractCanvas.__init__(self, config, context)

        #self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
        self.Bind(wx.EVT_PAINT, self._OnPaint)
        self.Bind(wx.EVT_SIZE, self._OnSize)
        self.Bind(wx.EVT_ERASE_BACKGROUND, self._OnEraseBackground)

    def _OnPaint(self, event):
        # wx handler for EVT_PAINT
        wx.PaintDC(self)
        self.dispatch_event('on_draw')
        self.flip()

    def _OnEraseBackground(self, event):
        pass

    def _OnSize(self, event):
        # wx handler for EVT_SIZE
        width, height = self.GetClientSize()
        self.dispatch_event('on_resize', width, height) 

class Win32WxCanvas(AbstractWxCanvas):
    def __init__(self, parent, id=-1, config=None, context=None):
        AbstractWxCanvas.__init__(self, parent, id, config, context)

        self._hwnd = self.GetHandle()
        self._dc = _user32.GetDC(self._hwnd)
        self._context._set_window(self)
        self._wgl_context = self._context._context
        self.switch_to()
         
    def _switch_to_impl(self):
        wgl.wglMakeCurrent(self._dc, self._wgl_context)

    def flip(self):
        wgl.wglSwapLayerBuffers(self._dc, wgl.WGL_SWAP_MAIN_PLANE)

class GTKWxCanvas(AbstractWxCanvas):
    _window = None

    def __init__(self, parent, id=-1, config=None, context=None):
        super(GTKWxCanvas, self).__init__(parent, id, config, context)

        self._glx_context = self._context._context
        self._x_display = self._config._display
        self._x_screen_id = self._screen._x_screen_id

        # GLX 1.3 doesn't work here (BadMatch error)
        self._glx_1_3 = False # self._display.info.have_version(1, 3)

    def _OnPaint(self, event):
        if not self._window:
            self._window = self.GetHandle()

            # Can also get the GDK window... (not used yet)
            gdk_window = gdk.gdk_window_lookup(self._window)

            if self._glx_1_3:
                self._glx_window = glx.glXCreateWindow(self._x_display,
                    self._config._fbconfig, self._window, None)
            self.switch_to()
        super(GTKWxCanvas, self)._OnPaint(event)

    def _switch_to_impl(self):
        if not self._window:
            return

        if self._glx_1_3:
            glx.glXMakeContextCurrent(self._x_display,
                self._glx_window, self._glx_window, self._glx_context)
        else:
            glx.glXMakeCurrent(self._x_display, self._window, self._glx_context)

    def flip(self):
        if not self._window:
            return

        if self._glx_1_3:
            glx.glXSwapBuffers(self._x_display, self._glx_window)
        else:
            glx.glXSwapBuffers(self._x_display, self._window)

if sys.platform == 'win32':
    WxCanvas = Win32WxCanvas
elif sys.platform.startswith('linux'):
    WxCanvas = GTKWxCanvas
else:
    assert False

class TestCanvas(WxCanvas):
    label = pyglet.text.Label('Hello, world', font_size=48,
                              anchor_x='center', anchor_y='center')
    batch = None;
    def CreatePics(self):
        FOO_IMAGE = pyglet.image.load('foo.png')
        self.batch = pyglet.graphics.Batch()
        self.sprite = pyglet.sprite.Sprite(FOO_IMAGE, batch=self.batch)
        self.sprite.x = 0
        self.sprite.y = 0
        #self.sprite2 = pyglet.sprite.Sprite(FOO_IMAGE, batch=self.batch)
        #self.sprite2.x = self.spritepos[0] + 100
        #self.sprite2.y = self.spritepos[1] + 200
    def on_draw(self):
        width, height = self.GetClientSize()
        
        glClear(GL_COLOR_BUFFER_BIT)
        self.label.text = 'OpenGL %s' % pyglet.gl.gl_info.get_version()
        self.label.x = width//2
        self.label.y = height//2
        self.label.draw()
        if self.batch:
            self.batch.draw()

class TestFrame(wx.Frame):
    def __init__(self, parent, title):
        wx.Frame.__init__(self, parent, -1, title, size=(640, 480))
        canvas = TestCanvas(self)
        canvas.CreatePics()

class TestApp(wx.App):
    def OnInit(self):
        frame = TestFrame(None, 'Test wxPython + pyglet')
        #self.SetTopWindow(frame)

        frame.Show(True)
        return True

if __name__ == '__main__':

    TestApp(redirect=False).MainLoop()

————————————————————————————————————————————————————————

        此代碼的價值說來話長。

        關於PyOpenGL和wxPython的結合,wxPython官方已經給出瞭解決方案:使用OpenGL控制項。但是PyOpenGL和pyglet有所區別,pyglet是cocos2d-python的基礎庫(cocos2d-python是整個cocos2d家族的鼻祖)。所以搞明白了pyglet和cocos2d的Director,應該就能把wxPython和cocos2d整合起來。已經有一些思路了,打算花點時間做出來看看。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.