将控制从Pygame移交给SDL2导致CALayer异常

时间:2014-10-16 18:56:22

标签: python pygame sdl sdl-2

上下文

我从事认知科学工作,所以这个问题的背景很难传达。长话短说,我们现有的图书馆在很大程度上取决于PyGame;我们需要将SDL2用于特定的实验任务。

我们的库在设计实验时扩展了基类Exp;它在PyGame中有一个简单且经过良好测试的预备序列,然后将控制传递给实验者以完成一组构成实验的抽象方法。

目标:在切换时,杀死PyGame并切换到SDL2。

问题:以下脚本( SDL2脚本)在Exp环境之外使用时可以正常工作。但是当它改变了一点但是(实施实施)时,会发生两件事:

  1. 我们使用SDL2加载的图像不会明显绘制(认为SDL2窗口有效)
  2. 引发异常:CALayer position contains NaN: [nan nan]
  3. 当前可疑 Pygame和SDL2正在争夺命名空间到两个地方,从该计划发布时的终端输出中可以看出:

    objc[34300]: Class SDLTranslatorResponder is implemented in both /Library/Frameworks/SDL.framework/Versions/A/SDL and /Library/Frameworks/SDL2.framework/SDL2. One of the two will be used. Which one is undefined.
    objc[34300]: Class SDLApplication is implemented in both /Library/Frameworks/SDL2.framework/SDL2 and /Library/Python/2.7/site-packages/pygame/sdlmain_osx.so. One of the two will be used. Which one is undefined.
    

    下面是工作外部脚本以及在Exp上下文中实现它的小修改。最后,完整的错误输出位于底部。

    对此问题的任何建议都会非常感激!!!

    SDL2脚本

    import sdl2 
    import sdl2.ext 
    import numpy 
    from PIL import Image 
    import time 
    import OpenGL.GL as gl
    from scipy import misc
    import os
    
    stimDisplayRes = (1366,768) #pixel resolution of the stimDisplay    
    imgs = []
    img_path = "path/to/jpgs"
    # this loop just grabs our images; works fine in both scripts
    for x in range(1, 450):
        x = str(int(x * 2.5)).zfill(8)
        path = os.path.join(img_path, "{0}.jpg".format(x))
        imgs.append(numpy.array(Image.open(path)))
    
    
    sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO)
    stimDisplay = sdl2.ext.Window("Experiment", size=stimDisplayRes,position=(0,0),flags=sdl2.SDL_WINDOW_OPENGL|sdl2.SDL_WINDOW_SHOWN| sdl2.SDL_WINDOW_FULLSCREEN_DESKTOP |sdl2.SDL_RENDERER_ACCELERATED | sdl2.SDL_RENDERER_PRESENTVSYNC)
    glContext = sdl2.SDL_GL_CreateContext(stimDisplay.window)
    gl.glMatrixMode(gl.GL_PROJECTION)
    gl.glLoadIdentity()
    gl.glOrtho(0, stimDisplayRes[0],stimDisplayRes[1], 0, 0, 1)
    gl.glMatrixMode(gl.GL_MODELVIEW)
    gl.glDisable(gl.GL_DEPTH_TEST)
    
    sdl2.SDL_PumpEvents() # to show the windows
    
    time.sleep(1)
    
    def blitNumpy(numpyArray,xLoc,yLoc,xCentered=True,yCentered=True):
        gl.glEnable(gl.GL_BLEND)
        gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA)
        ID = gl.glGenTextures(1)
        gl.glBindTexture(gl.GL_TEXTURE_2D, ID)
        gl.glTexEnvi(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, gl.GL_REPLACE);
        gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_S, gl.GL_CLAMP)
        gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_WRAP_T, gl.GL_CLAMP)
        gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MAG_FILTER, gl.GL_LINEAR)
        gl.glTexParameterf(gl.GL_TEXTURE_2D, gl.GL_TEXTURE_MIN_FILTER, gl.GL_LINEAR)
        if len(numpyArray.shape)==3: #no alpha channel
            gl.glTexImage2D( gl.GL_TEXTURE_2D , 0 , gl.GL_RGBA , numpyArray.shape[1] , numpyArray.shape[0] , 0 , gl.GL_RGB , gl.GL_UNSIGNED_BYTE , numpyArray )
        elif len(numpyArray.shape)==4: #alpha channel
            gl.glTexImage2D( gl.GL_TEXTURE_2D , 0 , gl.GL_RGBA , numpyArray.shape[1] , numpyArray.shape[0] , 0 , gl.GL_RGBA , gl.GL_UNSIGNED_BYTE , numpyArray )
        gl.glEnable(gl.GL_TEXTURE_2D)
        gl.glBindTexture(gl.GL_TEXTURE_2D, ID)
        gl.glBegin(gl.GL_QUADS)
        x1 = xLoc + 1.5 - 0.5
        x2 = xLoc + numpyArray.shape[1] - 0.0 + 0.5
        y1 = yLoc + 1.0 - 0.5
        y2 = yLoc + numpyArray.shape[0] - 0.5 + 0.5
        if xCentered:
            x1 = x1 - numpyArray.shape[1]/2.0
            x2 = x2 - numpyArray.shape[1]/2.0
        if yCentered:
            y1 = y1 - numpyArray.shape[0]/2.0
            y2 = y2 - numpyArray.shape[0]/2.0
        gl.glTexCoord2f( 0 , 0 )
        gl.glVertex2f( x1 , y1 )
        gl.glTexCoord2f( 1 , 0 )
        gl.glVertex2f( x2 , y1 )
        gl.glTexCoord2f( 1 , 1)
        gl.glVertex2f( x2 , y2 )
        gl.glTexCoord2f( 0 , 1 )
        gl.glVertex2f( x1, y2 )
        gl.glEnd()
        gl.glBindTexture(gl.GL_TEXTURE_2D, 0)
        gl.glDeleteTextures([ID])
        del ID
        gl.glDisable(gl.GL_TEXTURE_2D)
        return None
    
    # this is a little loop we're using to get our "frame rate" right; if this is made to work, I'm good from here
    i = 0
    j = 0
    start = time.time()
    while time.time()-start<10:
        time.sleep(.01) #pretend to do 5ms of other work per frame
        gl.glClearColor(0,0,0,1)
        gl.glClear(gl.GL_COLOR_BUFFER_BIT)
        blitNumpy(imgs[i],0,0,xCentered=False,yCentered=False)
        sdl2.SDL_GL_SwapWindow(stimDisplay.window)
        i+= 1
        if i == len(imgs):
            i=0
        j += 1
    
    print j/(time.time()-start) # we just happen to need this metric
    

    实验实施

    我没有重新发布整个脚本;除了在这里添加的内容之外,我几乎没有改变:

    class Experiment(ExpLib.Exp):
        first_run = True  # 
        # bunch of methods that don't interact with either PyGame or SDL2—science stuff
    
        def trial(self, trial_factors, trial_num):
            if self.first_run:
                pygame.quit()
                self.first_run = False
    
            time.sleep(0.1)  # maybe unnecessary; just giving PyGame a chance to be fully shut down
    
            # this next call wraps the script above; the only difference is that 
            # blitNumpy becomes self.blitNumpy, and our FPS loop
            self.sdl_trial()  
    
            # the experiment's code will go here if I can get this to fly
    

    控制台输出

      

    2014-10-16 15:15:18.366 Python [34300:d07]未被捕获的例外是   提出2014-10-16 15:15:18.366 Python [34300:d07] CALayer的位置   含有NaN:[nan nan] 2014-10-16 15:15:18.366 Python [34300:d07](0   CoreFoundation 0x00007fff8fba325c    exceptionPreprocess + 172 1 libobjc.A.dylib 0x00007fff86dc3e75 objc_exception_throw + 43 2 CoreFoundation
      0x00007fff8fba310c + [NSException raise:format:] + 204 3 QuartzCore   0x00007fff84cc425e _ZN2CA5Layer12set_positionERKNS_4Vec2IdEEb + 158 4   QuartzCore 0x00007fff84cc41b7 - [CALayer   setPosition:] + 44 5 QuartzCore
      0x00007fff84cc5e97 - [CALayer setFrame:] + 858 6 AppKit
      0x00007fff8e5e837e - [_ NSFullScreenTransitionOverlayWindow   positionLayers] + 1790 7 AppKit
      0x00007fff8e5e8e61 - [_ NSFullScreenTransitionOverlayWindow   startEnterFullScreenAnimationWithDuration:completionHandler:] + 55 8   AppKit 0x00007fff8e5ead76    - [_ NSFullScreenTransition _startFullScreenTransitionForCGWindow:targetFrame:duration:completionHandler:]   + 193 9 AppKit 0x00007fff8e5ecca6 __89 - [_ NSFullScreenTransition _performEnterFullScreenModeAnimating:activation:customWindows:] _ block_invoke361   + 1430 10 libxpc.dylib 0x00007fff84eafca2 _xpc_connection_reply_callout + 47 11 libxpc.dylib 0x00007fff84eafc2e _xpc_connection_call_reply + 36 12   libdispatch.dylib 0x00007fff869ab2ad   _dispatch_client_callout + 8 13 libdispatch.dylib 0x00007fff869b2f03 _dispatch_main_queue_callback_4CF + 333 14   CoreFoundation 0x00007fff8fb0a679   __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE
    + 9 15 CoreFoundation 0x00007fff8fac5954 CFRunLoopRun   + 1636 16 CoreFoundation 0x00007fff8fac50b5 CFRunLoopRunSpecific + 309 17 HIToolbox
      0x00007fff85ab9a0d RunCurrentEventLoopInMode + 226 18 HIToolbox
      0x00007fff85ab97b7 ReceiveNextEventCommon + 479 19 HIToolbox
      0x00007fff85ab95bc _BlockUntilNextEventMatchingListInModeWithFilter +   65 20 AppKit 0x00007fff8dd293de   _DPSNextEvent + 1434 21 AppKit 0x00007fff8dd28a2b - [NSApplication   nextEventMatchingMask:untilDate:inMode:dequeue:] + 122 22 SDL
      0x000000011023243c SDL_SoftStretch + 7888 23 SDL
      0x0000000110211efd SDL_PumpEvents + 38 24 SDL
      0x00000001102120dd SDL_EventState + 200 25 SDL
      0x00000001102303f6 SDL_JoystickEventState + 82 26 joystick.so
      0x000000011040313d joy_autoinit + 42 27 Python
      0x000000010ff18f72 PyObject_Call + 101 28 Python
      0x000000010ff9501f PyEval_CallObjectWithKeywords + 93 29 base.so
      0x0000000110207c47 init + 279 30 Python
      0x000000010ff921ef PyEval_EvalFrameEx + 12338 31 Python
      0x000000010ff8f093 PyEval_EvalCodeEx + 1641 32 Python
      0x000000010ff36796 PyFunction_SetClosure + 809 33 Python
      0x000000010ff18f72 PyObject_Call + 101 34 Python
      0x000000010ff239a7 PyMethod_New + 1200 35 Python
      0x000000010ff18f72 PyObject_Call + 101 36 Python
      0x000000010ff92df5 PyEval_EvalFrameEx + 15416 37 Python
      0x000000010ff8f093 PyEval_EvalCodeEx + 1641 38 Python
      0x000000010ff36796 PyFunction_SetClosure + 809 39 Python
      0x000000010ff18f72 PyObject_Call + 101 40 Python
      0x000000010ff239a7 PyMethod_New + 1200 41 Python
      0x000000010ff18f72 PyObject_Call + 101 42 Python
      0x000000010ff5e6ce _PyObject_SlotCompare + 5565 43 Python
      0x000000010ff5a184 _PyType_Lookup + 1343 44 Python
      0x000000010ff18f72 PyObject_Call + 101 45 Python
      0x000000010ff92df5 PyEval_EvalFrameEx + 15416 46 Python
      0x000000010ff8f093 PyEval_EvalCodeEx + 1641 47 Python
      0x000000010ff958c8 _PyEval_SliceIndex + 929 48 Python
      0x000000010ff924d4 PyEval_EvalFrameEx + 13079 49 Python
      0x000000010ff8f093 PyEval_EvalCodeEx + 1641 50 Python
      0x000000010ff36796 PyFunction_SetClosure + 809 51 Python
      0x000000010ff18f72 PyObject_Call + 101 52 Python
      0x000000010ff93395 PyEval_EvalFrameEx + 16856 53 Python
      0x000000010ff8f093 PyEval_EvalCodeEx + 1641 54 Python
      0x000000010ff958c8 _PyEval_SliceIndex + 929 55 Python
      0x000000010ff924d4 PyEval_EvalFrameEx + 13079 56 Python
      0x000000010ff8f093 PyEval_EvalCodeEx + 1641 57 Python
      0x000000010ff36796 PyFunction_SetClosure + 809 58 Python
      0x000000010ff18f72 PyObject_Call + 101 59 Python
      0x000000010ff93395 PyEval_EvalFrameEx + 16856 60 Python
      0x000000010ff8f093 PyEval_EvalCodeEx + 1641 61 Python
      0x000000010ff958c8 _PyEval_SliceIndex + 929 62 Python
      0x000000010ff924d4 PyEval_EvalFrameEx + 13079 63 Python
      0x000000010ff8f093 PyEval_EvalCodeEx + 1641 64 Python
      0x000000010ff8ea24 PyEval_EvalCode + 54 65 Python
      0x000000010ffadc2c PyParser_ASTFromFile + 306 66 Python
      0x000000010ffadcd3 PyRun_FileExFlags + 137 67 Python
      0x000000010ffad821 PyRun_SimpleFileExFlags + 718 68 Python
      0x000000010ffbe363 Py_Main + 2995 69 libdyld.dylib
      0x00007fff89e375fd start + 1 70 ???   0x0000000000000002 0x0 + 2)2014-10-16 15:15:18.367 Python [34300:d07]   ***由于未捕获的异常终止应用程序&#39; CALayerInvalidGeometry&#39;,原因:&#39; CALayer位置包含NaN:[nan   南]&#39;   ***第一次抛出调用堆栈:(0 CoreFoundation 0x00007fff8fba325c __exceptionPreprocess + 172 1 libobjc.A.dylib
      0x00007fff86dc3e75 objc_exception_throw + 43 2 CoreFoundation
      0x00007fff8fba310c + [NSException raise:format:] + 204 3 QuartzCore   0x00007fff84cc425e _ZN2CA5Layer12set_positionERKNS_4Vec2IdEEb + 158 4   QuartzCore 0x00007fff84cc41b7 - [CALayer   setPosition:] + 44 5 QuartzCore
      0x00007fff84cc5e97 - [CALayer setFrame:] + 858 6 AppKit
      0x00007fff8e5e837e - [_ NSFullScreenTransitionOverlayWindow   positionLayers] + 1790 7 AppKit
      0x00007fff8e5e8e61 - [_ NSFullScreenTransitionOverlayWindow   startEnterFullScreenAnimationWithDuration:completionHandler:] + 55 8   AppKit 0x00007fff8e5ead76    - [_ NSFullScreenTransition _startFullScreenTransitionForCGWindow:targetFrame:duration:completionHandler:]   + 193 9 AppKit 0x00007fff8e5ecca6 __89 - [_ NSFullScreenTransition _performEnterFullScreenModeAnimating:activation:customWindows:] _ block_invoke361   + 1430 10 libxpc.dylib 0x00007fff84eafca2 _xpc_connection_reply_callout + 47 11 libxpc.dylib 0x00007fff84eafc2e _xpc_connection_call_reply + 36 12   libdispatch.dylib 0x00007fff869ab2ad   _dispatch_client_callout + 8 13 libdispatch.dylib 0x00007fff869b2f03 _dispatch_main_queue_callback_4CF + 333 14   CoreFoundation 0x00007fff8fb0a679   __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE
    + 9 15 CoreFoundation 0x00007fff8fac5954 __CFRunLoopRun   + 1636 16 CoreFoundation 0x00007fff8fac50b5 CFRunLoopRunSpecific + 309 17 HIToolbox
      0x00007fff85ab9a0d RunCurrentEventLoopInMode + 226 18 HIToolbox
      0x00007fff85ab97b7 ReceiveNextEventCommon + 479 19 HIToolbox
      0x00007fff85ab95bc _BlockUntilNextEventMatchingListInModeWithFilter +   65 20 AppKit 0x00007fff8dd293de   _DPSNextEvent + 1434 21 AppKit 0x00007fff8dd28a2b - [NSApplication   nextEventMatchingMask:untilDate:inMode:dequeue:] + 122 22 SDL
      0x000000011023243c SDL_SoftStretch + 7888 23 SDL
      0x0000000110211efd SDL_PumpEvents + 38 24 SDL
      0x00000001102120dd SDL_EventState + 200 25 SDL
      0x00000001102303f6 SDL_JoystickEventState + 82 26 joystick.so
      0x000000011040313d joy_autoinit + 42 27 Python
      0x000000010ff18f72 PyObject_Call + 101 28 Python
      0x000000010ff9501f PyEval_CallObjectWithKeywords + 93 29 base.so
      0x0000000110207c47 init + 279 30 Python
      0x000000010ff921ef PyEval_EvalFrameEx + 12338 31 Python
      0x000000010ff8f093 PyEval_EvalCodeEx + 1641 32 Python
      0x000000010ff36796 PyFunction_SetClosure + 809 33 Python
      0x000000010ff18f72 PyObject_Call + 101 34 Python
      0x000000010ff239a7 PyMethod_New + 1200 35 Python
      0x000000010ff18f72 PyObject_Call + 101 36 Python
      0x000000010ff92df5 PyEval_EvalFrameEx + 15416 37 Python
      0x000000010ff8f093 PyEval_EvalCodeEx + 1641 38 Python
      0x000000010ff36796 PyFunction_SetClosure + 809 39 Python
      0x000000010ff18f72 PyObject_Call + 101 40 Python
      0x000000010ff239a7 PyMethod_New + 1200 41 Python
      0x000000010ff18f72 PyObject_Call + 101 42 Python
      0x000000010ff5e6ce _PyObject_SlotCompare + 5565 43 Python
      0x000000010ff5a184 _PyType_Lookup + 1343 44 Python
      0x000000010ff18f72 PyObject_Call + 101 45 Python
      0x000000010ff92df5 PyEval_EvalFrameEx + 15416 46 Python
      0x000000010ff8f093 PyEval_EvalCodeEx + 1641 47 Python
      0x000000010ff958c8 _PyEval_SliceIndex + 929 48 Python
      0x000000010ff924d4 PyEval_EvalFrameEx + 13079 49 Python
      0x000000010ff8f093 PyEval_EvalCodeEx + 1641 50 Python
      0x000000010ff36796 PyFunction_SetClosure + 809 51 Python
      0x000000010ff18f72 PyObject_Call + 101 52 Python
      0x000000010ff93395 PyEval_EvalFrameEx + 16856 53 Python
      0x000000010ff8f093 PyEval_EvalCodeEx + 1641 54 Python
      0x000000010ff958c8 _PyEval_SliceIndex + 929 55 Python
      0x000000010ff924d4 PyEval_EvalFrameEx + 13079 56 Python
      0x000000010ff8f093 PyEval_EvalCodeEx + 1641 57 Python
      0x000000010ff36796 PyFunction_SetClosure + 809 58 Python
      0x000000010ff18f72 PyObject_Call + 101 59 Python
      0x000000010ff93395 PyEval_EvalFrameEx + 16856 60 Python
      0x000000010ff8f093 PyEval_EvalCodeEx + 1641 61 Python
      0x000000010ff958c8 _PyEval_SliceIndex + 929 62 Python
      0x000000010ff924d4 PyEval_EvalFrameEx + 13079 63 Python
      0x000000010ff8f093 PyEval_EvalCodeEx + 1641 64 Python
      0x000000010ff8ea24 PyEval_EvalCode + 54 65 Python
      0x000000010ffadc2c PyParser_ASTFromFile + 306 66 Python
      0x000000010ffadcd3 PyRun_FileExFlags + 137 67 Python
      0x000000010ffad821 PyRun_SimpleFileExFlags + 718 68 Python
      0x000000010ffbe363 Py_Main + 2995 69 libdyld.dylib
      0x00007fff89e375fd start + 1 70 ???   0x0000000000000002 0x0 + 2)libc ++ abi.dylib:终止于   NSException类型的未捕获异常

         

    流程已完成退出代码13

1 个答案:

答案 0 :(得分:0)

在咨询了一些内部书呆子后,他们确认Brad Allred's对我的问题发表评论,解决方案是:同时使用PyGame和SDL2基本上总是需要比用SDL2替换PyGame更多的工作。不要这样做。

离开我的问题,以防它被证明有所帮助。