Lightningbeam/GUI/Win32/GL.py

270 lines
9.9 KiB
Python

#------------------------------------------------------------------------------
#
# PyGUI - OpenGL - Win32
#
#------------------------------------------------------------------------------
import win32con as wc, win32ui as ui, win32gui as gui
#import OpenGL.GL as gl ###
import GUI.GDIPlus as gdi
from OpenGL import WGL as wgl
from OpenGL.WGL import ChoosePixelFormat
#print "Using ctypes ChoosePixelFormat"
#from WGL import ChoosePixelFormat
from GUI.WinUtils import win_none
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.cRedBits = pf.cGreenBits = pf.cBluedBits = self._color_size
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)
self.set(**kwds)
self._with_context(hdc, self._init_context)
win.ReleaseDC(dc)
# def _init_context(self):
# print "GL_VENDOR:", gl.glGetString(gl.GL_VENDOR)
# print "GL_RENDERER:", gl.glGetString(gl.GL_RENDERER)
# print "GL_VERSION:", gl.glGetString(gl.GL_VERSION)
# print "GL_EXTENSIONS:"
# for name in gl.glGetString(gl.GL_EXTENSIONS).split():
# print " ", name
# GGLView._init_context(self)
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)
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']