#------------------------------------------------------------------------------ # # PyGUI - OpenGL - Win32 # #------------------------------------------------------------------------------ import win32con as wc, win32ui as ui, win32gui as gui import GUI.GDIPlus as gdi from GUI.Components import win_none from GUI.OpenGL import WGL as wgl from GUI.GGLViews import GLView as GGLView from GUI.GGLPixmaps import GLPixmap as GGLPixmap from GUI.GGLConfig import GLConfig as GGLConfig, GLConfigError from GUI.GLContexts import GLContext from GUI.GLTextures import Texture win_style = wc.WS_VISIBLE | wc.WS_CLIPCHILDREN | wc.WS_CLIPSIBLINGS win_default_size = GGLView._default_size win_default_rect = (0, 0, win_default_size[0], win_default_size[1]) #------------------------------------------------------------------------------ class GLConfig(GGLConfig): def _as_win_pixelformat(self, mode): print "GLConfig._as_win_pixelformat: mode =", mode ### pf = wgl.PIXELFORMATDESCRIPTOR() flags = wgl.PFD_SUPPORT_OPENGL if mode == 'screen' or mode == 'both': print "GLConfig: requesting screen drawing" ### flags |= wgl.PFD_DRAW_TO_WINDOW if self._double_buffer: flags |= wgl.PFD_DOUBLEBUFFER | wgl.PFD_SWAP_EXCHANGE else: flags |= wgl.PFD_DOUBLEBUFFER_DONTCARE if mode == 'pixmap' or mode == 'both': print "GLConfig: requesting pixmap drawing" ### flags |= wgl.PFD_DRAW_TO_BITMAP | wgl.PFD_SUPPORT_GDI if not self._depth_buffer: flags |= wgl.PFD_DEPTH_DONTCARE if self._stereo: flags |= wgl.PFD_STEREO else: flags |= wgl.PFD_STEREO_DONTCARE pf.dwFlags = flags & 0xffffffff pf.iPixelType = wgl.PFD_TYPE_RGBA #pf.cColorBits = 3 * self._color_size pf.cColorBits = 32 ### pf.cAlphaBits = 8 ### pf.cAlphaShift = 24 ### if self._alpha: pf.cAlphaBits = self._alpha_size pf.cAuxBuffers = self._aux_buffers if self._depth_buffer: pf.cDepthBits = self._depth_size if self._stencil_buffer: pf.cStencilBits = self._stencil_size if self._accum_buffer: pf.cAccumBits = 3 * self._accum_size pf.iLayerType = wgl.PFD_MAIN_PLANE return pf def _from_win_pixelformat(cls, pf): self = cls.__new__(cls) flags = pf.dwFlags self._double_buffer = flags & wgl.PFD_DOUBLEBUFFER != 0 self._alpha = pf.cAlphaSize > 0 self._color_size = pf.cColorBits self._alpha_size = pf.cAlphaSize self._stereo = flags & wgl.PFD_STEREO != 0 self._aux_buffers = pf.cAuxBuffers self._depth_buffer = pf.cDepthBits > 0 self._depth_size = pf.cDepthBits self._stencil_buffer = pf.cStencilBits > 0 self._stencil_size = pf.cStencilBits self._accum_size = pf.cAccumBits self._accum_buffer = self._accum_size > 0 self._multisample = False self._samples_per_pixel = 1 return self def _check_win_pixelformat(self, pf, mode): flags = pf.dwFlags if mode == 'screen' or mode == 'both': if not flags & wgl.PFD_DRAW_TO_WINDOW: raise GLConfigError("Rendering to screen not supported") if mode == 'pixmap' or mode == 'both': if not flags & wgl.PFD_DRAW_TO_BITMAP: raise GLConfigError("Rendering to pixmap not supported") if self._alpha and pf.cAlphaBits == 0: raise GLConfigError("Alpha channel not available") if self._stereo and not flags & wgl.PFD_STEREO: raise GLConfigError("Stereo buffer not available") if self._aux_buffers and pf.cAuxBuffers == 0: raise GLConfigError("Auxiliary buffers not available") if self._depth_buffer and pf.cDepthBits == 0: raise GLConfigError("Depth buffer not available") if self._stencil_buffer and pf.cStencilBits == 0: raise GLConfigError("Stencil buffer not available") if self.accum_buffer and pf.cAccumBits == 0: raise GLConfigError("Accumulation buffer not available") def _win_supported_pixelformat(self, hdc, mode): reqpf = self._as_win_pixelformat(mode) print "GLConfig._win_supported_pixelformat" ### print "Requested format:" ### win_dump_pixelformat(reqpf) ### print "GLConfig: Choosing pixel format for hdc", hdc ### ipf = wgl.ChoosePixelFormat(hdc, reqpf) print "... result =", ipf ### actpf = wgl.PIXELFORMATDESCRIPTOR() print "GLConfig: Describing pixel format", ipf, "for hdc", hdc ### wgl.DescribePixelFormat(hdc, ipf, actpf.nSize, actpf) print "Actual format:" ### win_dump_pixelformat(actpf) ### return ipf, actpf def supported(self, mode = 'both'): dc = win_none.GetDC() hdc = dc.GetSafeHdc() ipf, actpf = self._win_supported_pixelformat(hdc, mode) win_none.ReleaseDC(dc) return GLConfig._from_win_pixelformat(actpf) #------------------------------------------------------------------------------ class GLView(GGLView): def __init__(self, config = None, share_group = None, **kwds): config = GLConfig._from_args(config, kwds) win = ui.CreateWnd() win.CreateWindow(None, None, win_style, win_default_rect, win_none, 0) dc = win.GetDC() hdc = dc.GetSafeHdc() GLContext.__init__(self, share_group, config, hdc, 'screen') GGLView.__init__(self, _win = win, **kwds) self._with_context(hdc, self._init_context) win.ReleaseDC(dc) def destroy(self): GLContext.destroy(self) GGLView.destroy(self) def with_context(self, proc, flush = False): win = self._win dc = win.GetDC() hdc = dc.GetSafeHdc() try: self._with_context(hdc, proc, flush) finally: win.ReleaseDC(dc) def OnPaint(self): #print "GLView.OnPaint" ### win = self._win dc, ps = win.BeginPaint() try: hdc = dc.GetSafeHdc() self._with_context(hdc, self.render, True) finally: win.EndPaint(ps) def _resized(self, delta): self.with_context(self._update_viewport) #------------------------------------------------------------------------------ class GLPixmap(GGLPixmap): def __init__(self, width, height, config = None, share_group = None, **kwds): print "GLPixmap:", width, height, kwds ### config = GLConfig._from_args(config, kwds) image = gdi.Bitmap(width, height) self._win_image = image graphics = gdi.Graphics.from_image(image) self._win_graphics = graphics hdc = graphics.GetHDC() self._win_hdc = hdc GLContext.__init__(self, share_group, config, hdc, 'pixmap') self._with_context(hdc, self._init_context) print "GLPixmap: done" ### def __del__(self): graphics = self._win_graphics graphics.ReleaseHDC(self._win_hdc) def with_context(self, proc, flush = False): try: self._with_context(self._hdc, proc, flush) finally: graphics.ReleaseHDC(hdc) #------------------------------------------------------------------------------ #class GLPixmap(GGLPixmap): # # def __init__(self, width, height, config = None, share_group = None, **kwds): # print "GLPixmap:", width, height, kwds ### # config = GLConfig._from_args(config, kwds) # dc0 = win_none.GetDC() # dc = dc0.CreateCompatibleDC(dc0) # bm = ui.CreateBitmap() # ###bm.CreateCompatibleBitmap(dc0, width, height) # bm.CreateCompatibleBitmap(dc0, 1, 1) # win_none.ReleaseDC(dc0) # dc.SelectObject(bm) # self._win_dc = dc # self._win_bm = bm # hdc = dc.GetSafeHdc() # win_dump_bitmap(bm) ### # GLContext.__init__(self, share_group, config, hdc, 'pixmap') # self._with_context(hdc, self._init_context) # print "GLPixmap: done" ### # # def with_context(self, proc, flush = False): # hdc = self._win_dc.GetSafeHdc() # self._with_context(hdc, proc, flush) #------------------------------------------------------------------------------ def win_dump_pixelformat(pf): print "nSize =", pf.nSize print "nVersion =", pf.nVersion print "dwFlags = 0x%08x" % pf.dwFlags print "iPixelType =", pf.iPixelType print "cColorBits =", pf.cColorBits print "cRedBits =", pf.cRedBits print "cRedShift =", pf.cRedShift print "cGreenBits =", pf.cGreenBits print "cGreenShift =", pf.cGreenShift print "cBlueBits =", pf.cBlueBits print "cBlueShift =", pf.cBlueShift print "cAlphaBits =", pf.cAlphaBits print "cAlphaShift =", pf.cAlphaShift print "cAccumBits =", pf.cAccumBits print "cAccumRedBits =", pf.cAccumRedBits print "cAccumGreenBits =", pf.cAccumGreenBits print "cAccumBlueBits =", pf.cAccumBlueBits print "cDepthBits =", pf.cDepthBits print "cStencilBits =", pf.cStencilBits print "cAuxBuffers =", pf.cAuxBuffers print "iLayerType =", pf.iLayerType print "bReserved =", pf.bReserved print "dwLayerMask =", pf.dwLayerMask print "dwVisibleMask =", pf.dwVisibleMask print "dwDamageMask =", pf.dwDamageMask def win_dump_bitmap(bm): info = bm.GetInfo() print "bmType =", info['bmType'] print "bmWidth =", info['bmWidth'] print "bmHeight =", info['bmHeight'] print "bmWidthBytes =", info['bmWidthBytes'] print "bmPlanes =", info['bmPlanes'] print "bmBitsPixel =", info['bmBitsPixel']