shenjack
d84b490b99
Add | more formatter and some more Fix | type mis match sync pyglet Enhance | logger with Template add lib-not-dr as requirement sync pyglet sync pyglet Add | add lto=yes to nuitka_build just incase sync pyglet sync lib_not_dr Remove | external requirement lib-not-dr some logger sync lib-not-dr sync pyglet sync lib-not-dr sync lib-not-dr sync pyglet sync pyglet Fix | console thread been block Update DR rs and DR sdk sync lib not dr sync lib-not-dr sync lib-not-dr sync pyglet and lib-not-dr sync pyglet 0.1.8 sync lib not dr logger almost done? almost! sync pyglet (clicpboard support!) sync lib not dr sync lib not dr color code and sync pyglet do not show memory and progress building localy sync pyglet synclibs
256 lines
9.3 KiB
Python
256 lines
9.3 KiB
Python
from pyglet.canvas.win32 import Win32Canvas
|
|
from .base import Config, CanvasConfig, Context
|
|
|
|
from pyglet import gl
|
|
from pyglet.gl import gl_info
|
|
from pyglet.gl import wgl
|
|
from pyglet.gl import wglext_arb
|
|
from pyglet.gl import wgl_info
|
|
|
|
from pyglet.libs.win32 import _user32, _kernel32, _gdi32
|
|
from pyglet.libs.win32.constants import *
|
|
from pyglet.libs.win32.types import *
|
|
|
|
|
|
class Win32Config(Config):
|
|
def match(self, canvas):
|
|
if not isinstance(canvas, Win32Canvas):
|
|
raise RuntimeError('Canvas must be instance of Win32Canvas')
|
|
|
|
# Use ARB API if available
|
|
if gl_info.have_context() and wgl_info.have_extension('WGL_ARB_pixel_format'):
|
|
return self._get_arb_pixel_format_matching_configs(canvas)
|
|
else:
|
|
return self._get_pixel_format_descriptor_matching_configs(canvas)
|
|
|
|
def _get_pixel_format_descriptor_matching_configs(self, canvas):
|
|
"""Get matching configs using standard PIXELFORMATDESCRIPTOR
|
|
technique."""
|
|
pfd = PIXELFORMATDESCRIPTOR()
|
|
pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR)
|
|
pfd.nVersion = 1
|
|
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL
|
|
|
|
if self.double_buffer:
|
|
pfd.dwFlags |= PFD_DOUBLEBUFFER
|
|
else:
|
|
pfd.dwFlags |= PFD_DOUBLEBUFFER_DONTCARE
|
|
|
|
if self.stereo:
|
|
pfd.dwFlags |= PFD_STEREO
|
|
else:
|
|
pfd.dwFlags |= PFD_STEREO_DONTCARE
|
|
|
|
# Not supported in pyglet API
|
|
# if attributes.get('swap_copy', False):
|
|
# pfd.dwFlags |= PFD_SWAP_COPY
|
|
# if attributes.get('swap_exchange', False):
|
|
# pfd.dwFlags |= PFD_SWAP_EXCHANGE
|
|
|
|
if not self.depth_size:
|
|
pfd.dwFlags |= PFD_DEPTH_DONTCARE
|
|
|
|
pfd.iPixelType = PFD_TYPE_RGBA
|
|
pfd.cColorBits = self.buffer_size or 0
|
|
pfd.cRedBits = self.red_size or 0
|
|
pfd.cGreenBits = self.green_size or 0
|
|
pfd.cBlueBits = self.blue_size or 0
|
|
pfd.cAlphaBits = self.alpha_size or 0
|
|
pfd.cAccumRedBits = self.accum_red_size or 0
|
|
pfd.cAccumGreenBits = self.accum_green_size or 0
|
|
pfd.cAccumBlueBits = self.accum_blue_size or 0
|
|
pfd.cAccumAlphaBits = self.accum_alpha_size or 0
|
|
pfd.cDepthBits = self.depth_size or 0
|
|
pfd.cStencilBits = self.stencil_size or 0
|
|
pfd.cAuxBuffers = self.aux_buffers or 0
|
|
|
|
pf = _gdi32.ChoosePixelFormat(canvas.hdc, byref(pfd))
|
|
if pf:
|
|
return [Win32CanvasConfig(canvas, pf, self)]
|
|
else:
|
|
return []
|
|
|
|
def _get_arb_pixel_format_matching_configs(self, canvas):
|
|
"""Get configs using the WGL_ARB_pixel_format extension.
|
|
This method assumes a (dummy) GL context is already created."""
|
|
|
|
# Check for required extensions
|
|
if self.sample_buffers or self.samples:
|
|
if not gl_info.have_extension('GL_ARB_multisample'):
|
|
return []
|
|
|
|
# Construct array of attributes
|
|
attrs = []
|
|
for name, value in self.get_gl_attributes():
|
|
attr = Win32CanvasConfigARB.attribute_ids.get(name, None)
|
|
if attr and value is not None:
|
|
attrs.extend([attr, int(value)])
|
|
attrs.append(0)
|
|
attrs = (c_int * len(attrs))(*attrs)
|
|
|
|
pformats = (c_int * 16)()
|
|
nformats = c_uint(16)
|
|
wglext_arb.wglChoosePixelFormatARB(canvas.hdc, attrs, None, nformats, pformats, nformats)
|
|
|
|
formats = [Win32CanvasConfigARB(canvas, pf, self) for pf in pformats[:nformats.value]]
|
|
return formats
|
|
|
|
|
|
class Win32CanvasConfig(CanvasConfig):
|
|
def __init__(self, canvas, pf, config):
|
|
super().__init__(canvas, config)
|
|
self._pf = pf
|
|
self._pfd = PIXELFORMATDESCRIPTOR()
|
|
|
|
_gdi32.DescribePixelFormat(canvas.hdc, pf, sizeof(PIXELFORMATDESCRIPTOR), byref(self._pfd))
|
|
|
|
self.double_buffer = bool(self._pfd.dwFlags & PFD_DOUBLEBUFFER)
|
|
self.sample_buffers = 0
|
|
self.samples = 0
|
|
self.stereo = bool(self._pfd.dwFlags & PFD_STEREO)
|
|
self.buffer_size = self._pfd.cColorBits
|
|
self.red_size = self._pfd.cRedBits
|
|
self.green_size = self._pfd.cGreenBits
|
|
self.blue_size = self._pfd.cBlueBits
|
|
self.alpha_size = self._pfd.cAlphaBits
|
|
self.accum_red_size = self._pfd.cAccumRedBits
|
|
self.accum_green_size = self._pfd.cAccumGreenBits
|
|
self.accum_blue_size = self._pfd.cAccumBlueBits
|
|
self.accum_alpha_size = self._pfd.cAccumAlphaBits
|
|
self.depth_size = self._pfd.cDepthBits
|
|
self.stencil_size = self._pfd.cStencilBits
|
|
self.aux_buffers = self._pfd.cAuxBuffers
|
|
|
|
def compatible(self, canvas):
|
|
# TODO more careful checking
|
|
return isinstance(canvas, Win32Canvas)
|
|
|
|
def create_context(self, share):
|
|
return Win32Context(self, share)
|
|
|
|
def _set_pixel_format(self, canvas):
|
|
_gdi32.SetPixelFormat(canvas.hdc, self._pf, byref(self._pfd))
|
|
|
|
|
|
class Win32CanvasConfigARB(CanvasConfig):
|
|
attribute_ids = {
|
|
'double_buffer': wglext_arb.WGL_DOUBLE_BUFFER_ARB,
|
|
'stereo': wglext_arb.WGL_STEREO_ARB,
|
|
'buffer_size': wglext_arb.WGL_COLOR_BITS_ARB,
|
|
'aux_buffers': wglext_arb.WGL_AUX_BUFFERS_ARB,
|
|
'sample_buffers': wglext_arb.WGL_SAMPLE_BUFFERS_ARB,
|
|
'samples': wglext_arb.WGL_SAMPLES_ARB,
|
|
'red_size': wglext_arb.WGL_RED_BITS_ARB,
|
|
'green_size': wglext_arb.WGL_GREEN_BITS_ARB,
|
|
'blue_size': wglext_arb.WGL_BLUE_BITS_ARB,
|
|
'alpha_size': wglext_arb.WGL_ALPHA_BITS_ARB,
|
|
'depth_size': wglext_arb.WGL_DEPTH_BITS_ARB,
|
|
'stencil_size': wglext_arb.WGL_STENCIL_BITS_ARB,
|
|
'accum_red_size': wglext_arb.WGL_ACCUM_RED_BITS_ARB,
|
|
'accum_green_size': wglext_arb.WGL_ACCUM_GREEN_BITS_ARB,
|
|
'accum_blue_size': wglext_arb.WGL_ACCUM_BLUE_BITS_ARB,
|
|
'accum_alpha_size': wglext_arb.WGL_ACCUM_ALPHA_BITS_ARB,
|
|
}
|
|
|
|
def __init__(self, canvas, pf, config):
|
|
super().__init__(canvas, config)
|
|
self._pf = pf
|
|
|
|
names = list(self.attribute_ids.keys())
|
|
attrs = list(self.attribute_ids.values())
|
|
attrs = (c_int * len(attrs))(*attrs)
|
|
values = (c_int * len(attrs))()
|
|
|
|
wglext_arb.wglGetPixelFormatAttribivARB(canvas.hdc, pf, 0, len(attrs), attrs, values)
|
|
|
|
for name, value in zip(names, values):
|
|
setattr(self, name, value)
|
|
|
|
def compatible(self, canvas):
|
|
# TODO more careful checking
|
|
return isinstance(canvas, Win32Canvas)
|
|
|
|
def create_context(self, share):
|
|
if wgl_info.have_extension('WGL_ARB_create_context'):
|
|
# Graphics adapters that ONLY support up to OpenGL 3.1/3.2
|
|
# should be using the Win32ARBContext class.
|
|
return Win32ARBContext(self, share)
|
|
else:
|
|
return Win32Context(self, share)
|
|
|
|
def _set_pixel_format(self, canvas):
|
|
_gdi32.SetPixelFormat(canvas.hdc, self._pf, None)
|
|
|
|
|
|
class _BaseWin32Context(Context):
|
|
def __init__(self, config, share):
|
|
super().__init__(config, share)
|
|
self._context = None
|
|
|
|
def set_current(self):
|
|
if self._context is not None and self != gl.current_context:
|
|
wgl.wglMakeCurrent(self.canvas.hdc, self._context)
|
|
super().set_current()
|
|
|
|
def detach(self):
|
|
if self.canvas:
|
|
wgl.wglDeleteContext(self._context)
|
|
self._context = None
|
|
super().detach()
|
|
|
|
def flip(self):
|
|
_gdi32.SwapBuffers(self.canvas.hdc)
|
|
|
|
def get_vsync(self):
|
|
if wgl_info.have_extension('WGL_EXT_swap_control'):
|
|
return bool(wglext_arb.wglGetSwapIntervalEXT())
|
|
|
|
def set_vsync(self, vsync):
|
|
if wgl_info.have_extension('WGL_EXT_swap_control'):
|
|
wglext_arb.wglSwapIntervalEXT(int(vsync))
|
|
|
|
|
|
class Win32Context(_BaseWin32Context):
|
|
def attach(self, canvas):
|
|
super().attach(canvas)
|
|
|
|
if not self._context:
|
|
self.config._set_pixel_format(canvas)
|
|
self._context = wgl.wglCreateContext(canvas.hdc)
|
|
|
|
share = self.context_share
|
|
if share:
|
|
if not share.canvas:
|
|
raise RuntimeError('Share context has no canvas.')
|
|
if not wgl.wglShareLists(share._context, self._context):
|
|
raise gl.ContextException('Unable to share contexts.')
|
|
|
|
|
|
class Win32ARBContext(_BaseWin32Context):
|
|
|
|
def attach(self, canvas):
|
|
share = self.context_share
|
|
if share:
|
|
if not share.canvas:
|
|
raise RuntimeError('Share context has no canvas.')
|
|
share = share._context
|
|
|
|
attribs = []
|
|
if self.config.major_version is not None:
|
|
attribs.extend([wglext_arb.WGL_CONTEXT_MAJOR_VERSION_ARB, self.config.major_version])
|
|
if self.config.minor_version is not None:
|
|
attribs.extend([wglext_arb.WGL_CONTEXT_MINOR_VERSION_ARB, self.config.minor_version])
|
|
flags = 0
|
|
if self.config.forward_compatible:
|
|
flags |= wglext_arb.WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
|
|
if self.config.debug:
|
|
flags |= wglext_arb.WGL_CONTEXT_DEBUG_BIT_ARB
|
|
if flags:
|
|
attribs.extend([wglext_arb.WGL_CONTEXT_FLAGS_ARB, flags])
|
|
attribs.append(0)
|
|
attribs = (c_int * len(attribs))(*attribs)
|
|
|
|
self.config._set_pixel_format(canvas)
|
|
self._context = wglext_arb.wglCreateContextAttribsARB(canvas.hdc, share, attribs)
|
|
super().attach(canvas)
|