Lightningbeam/GUI/Win32/GL_arb.py

265 lines
10 KiB
Python

#------------------------------------------------------------------------------
#
# PyGUI - OpenGL - Win32
#
#------------------------------------------------------------------------------
import win32con as wc, win32ui as ui, win32gui as gui
import GDIPlus as gdi
import WGL
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_pixelattrs(self, mode):
print "GLConfig._as_arb_pixelattrs: mode =", mode ###
attrs = {}
attrs[wgl.WGL_SUPPORT_OPENGL_ARB] = True
if mode == 'screen' or mode == 'both':
print "GLConfig: requesting screen drawing" ###
attrs[wgl.WGL_DRAW_TO_WINDOW_ARB] = True
if self._double_buffer:
attrs[wgl.WGL_DOUBLE_BUFFER_ARB] = True
if mode == 'pixmap' or mode == 'both':
print "GLConfig: requesting pixmap drawing" ###
attrs[wgl.WGL_DRAW_TO_PBUFFER_ARB] = True
if self._stereo:
attrs[wgl.WGL_STEREO_ARB] = True
attrs[wgl.WGL_PIXEL_TYPE_ARB] = wgl.WGL_TYPE_RGBA_ARB
bits = self._color_size
attrs[wgl.WGL_RED_BITS_ARB] = bits
attrs[wgl.WGL_GREEN_BITS_ARB] = bits
attrs[wgl.WGL_BLUE_BITS_ARB] = bits
if self._alpha:
attrs[wgl.WGL_ALPHA_BITS_ARB] = self._alpha_size
attrs[wgl.WGL_AUX_BUFFERS_ARB] = self._aux_buffers
if self._depth_buffer:
attrs[wgl.WGL_DEPTH_BITS_ARB] = self._depth_size
if self._stencil_buffer:
attrs[wgl.WGL_STENCIL_BITS_ARB] = self._stencil_size
if self._accum_buffer:
bits = self._accum_size
attrs[wgl.WGL_ACCUM_RED_BITS_ARB] = bits
attrs[wgl.WGL_ACCUM_GREEN_BITS_ARB] = bits
attrs[wgl.WGL_ACCUM_BLUE_BITS_ARB] = bits
return attrs
def _from_win_pixelattrs(cls, attrs):
self = cls.__new__(cls)
self._double_buffer = attrs[wgl.WGL_DOUBLE_BUFFER_ARB]
self._color_size = attrs[wgl.WGL_COLOR_BITS_ARB] // 3
self._alpha_size = attrs[wgl.WGL_ALPHA_BITS_ARB]
self._alpha = self._alpha_size > 0
self._stereo = attrs[wgl.WGL_STEREO_ARB] #flags & wgl.PFD_STEREO != 0
self._aux_buffers = attrs[wgl.WGL_AUX_BUFFERS_ARB] > 0
self._depth_size = attrs[wgl.WGL_DEPTH_BITS_ARB]
self._depth_buffer = self._depth_size > 0
self._stencil_size = attrs[wgl.WGL_STENCIL_BITS_ARB]
self._stencil_buffer = self._stencil_bits > 0
self._accum_size = attrs[wgl.WGL_ACCUM_BITS_ARB] // 3
self._accum_buffer = self._accum_size > 0
self._multisample = False
self._samples_per_pixel = 1
return self
# def _check_win_pixelattrs(self, attrs, mode):
# if mode == 'screen' or mode == 'both':
# if not attrs[wgl.WGL_DRAW_TO_WINDOW_ARB]:
# raise GLConfigError("Rendering to screen not supported")
# if mode == 'pixmap' or mode == 'both':
# if not attrs[wgl.WGL_DRAW_TO_PBUFFER_ARB]:
# raise GLConfigError("Rendering to pixmap not supported")
# if self._alpha and attrs[wgl.WGL_ALPHA_BITS_ARB] == 0:
# raise GLConfigError("Alpha channel not available")
# if self._stereo and not attrs[wgl.WGL_STEREO_ARB]:
# raise GLConfigError("Stereo buffer not available")
# if self._aux_buffers and attrs]wgl.WGL_AUX_BUFFERS_ARB] == 0:
# raise GLConfigError("Auxiliary buffers not available")
# if self._depth_buffer and attrs[wgl.WGL_DEPTH_BITS_ARB] == 0:
# raise GLConfigError("Depth buffer not available")
# if self._stencil_buffer and attrs[wgl.WGL_STENCIL_BITS] == 0:
# raise GLConfigError("Stencil buffer not available")
# if self.accum_buffer and attrs[wgl.WGL_ACCUM_BITS] == 0:
# raise GLConfigError("Accumulation buffer not available")
_win_query_pixelattr_keys = [
wgl.WGL_SUPPORT_OPENGL_ARB,
wgl.WGL_DRAW_TO_WINDOW_ARB,
wgl.WGL_DOUBLE_BUFFER_ARB,
wgl.WGL_DRAW_TO_PBUFFER_ARB,
wgl.WGL_STEREO_ARB,
wgl.WGL_PIXEL_TYPE_ARB,
wgl.WGL_COLOR_BITS_ARB,
wgl.WGL_ALPHA_BITS_ARB,
wgl.WGL_AUX_BUFFERS_ARB,
wgl.WGL_DEPTH_BITS_ARB,
wgl.WGL_STENCIL_BITS_ARB,
wgl.WGL_ACCUM_BITS_ARB,
]
def _win_supported_pixelformat(self, hdc, mode):
req_attrs = self._as_win_pixelattrs(mode)
print "GLConfig: Choosing pixel format for hdc", hdc ###
print "Requested attributes:", req_attrs ###
req_array = WGL.attr_array(req_attrs)
print "Requested array:", req_array ###
ipfs, nf = wgl.wglChoosePixelFormatEXT(hdc, req_array, None, 1)
print "Pixel formats:", ipfs ###
print "No. of formats:", nf ###
if not ipfs:
req_attrs[wgl.WGL_DOUBLE_BUFFER_ARB] = not self._double_buffer
req_array = WGL.attr_array(req_attrs)
ipfs, nf = wglChoosePixelFormatARB(hdc, req_array, None, 1)
if not ipfs:
return None, None
print "GLConfig: Describing pixel format", ipf, "for hdc", hdc ###
keys = _win_query_pixelattr_keys
values = wglGetPixelFormatAttribivARB(hdc, ipf, 0, keys)
print "Actual values:", values ###
act_attrs = WGL.attr_dict(keys, values)
print "Actual attrs:", act_attrs ###
return ipfs[0], act_attrs
def supported(self, mode = 'both'):
dc = win_none.GetDC()
hdc = dc.GetSafeHdc()
ipf, act_attrs = self._win_supported_pixelformat(hdc, mode)
win_none.ReleaseDC(dc)
if ipf is None:
return None
return GLConfig._from_win_pixelattrs(act_attrs)
#------------------------------------------------------------------------------
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)
pyhdc = gui.CreateCompatibleDC(0)
dc = ui.CreateDCFromHandle(pyhdc)
hdc = dc.GetSafeHdc()
hbm = gui.CreateCompatibleBitmap(hdc, width, height)
bm = ui.CreateBitmapFromHandle(hbm)
dc.SelectObject(bm)
self._win_dc = dc
self._win_hbm = hbm
self._win_bm = 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