Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WGL extensions not found when using Python 3 #7

Open
tomgoddard opened this issue Dec 21, 2017 · 4 comments
Open

WGL extensions not found when using Python 3 #7

tomgoddard opened this issue Dec 21, 2017 · 4 comments

Comments

@tomgoddard
Copy link

WGL extensions are not found when using Python 3 due to use of strings where bytes are required. Below is a traceback trying to use the WGL_EXT_swap_control extension. Changing 3 lines in OpenGL/raw/WGL/_types.py to use bytes instead of strings using the as_8_bit() function fixes the problem. I've attached a patch with these changes.

In Python 3.1 with PyOpenGL 3.1.1a:
wgl_python3.patch.gz

from OpenGL.WGL.EXT import swap_control
swap_control.wglGetSwapIntervalEXT()


TypeError Traceback (most recent call last)
in ()
----> 1 swap_control.wglGetSwapIntervalEXT()

C:\Program Files\ChimeraX\bin\lib\site-packages\OpenGL\platform\baseplatform.py in call(self, *args, **named)
399 return None
400 def call( self, *args, **named ):
--> 401 if self.load():
402 return self( *args, **named )
403 else:

C:\Program Files\ChimeraX\bin\lib\site-packages\OpenGL\platform\baseplatform.py in load(self)
388 argNames = self.argNames,
389 extension = self.extension,
--> 390 error_checker = self.error_checker,
391 )
392 except AttributeError as err:

C:\Program Files\ChimeraX\bin\lib\site-packages\OpenGL\platform\win32.py in constructFunction(self, functionName, dll, resultType, argTypes, doc, argNames, extension, deprecated, module, error_checker)
127 deprecated,
128 module,
--> 129 error_checker=error_checker,
130 )
131 except AttributeError:

C:\Program Files\ChimeraX\bin\lib\site-packages\OpenGL\platform\baseplatform.py in constructFunction(self, functionName, dll, resultType, argTypes, doc, argNames, extension, deprecated, module, force_extension, error_checker)
146 """
147 is_core = (not extension) or extension.split('_')[1] == 'VERSION'
--> 148 if (not is_core) and not self.checkExtension( extension ):
149 raise AttributeError( """Extension not available""" )
150 argTypes = [ self.finalArgType( t ) for t in argTypes ]

C:\Program Files\ChimeraX\bin\lib\site-packages\OpenGL\platform\baseplatform.py in checkExtension(self, name)
268 if current is None:
269 from OpenGL import extensions
--> 270 result = extensions.ExtensionQuerier.hasExtension( name )
271 set[name] = result
272 return result

C:\Program Files\ChimeraX\bin\lib\site-packages\OpenGL\extensions.py in hasExtension(self, specifier)
96 def hasExtension( self, specifier ):
97 for registered in self.registered:
---> 98 result = registered( specifier )
99 if result:
100 return result

C:\Program Files\ChimeraX\bin\lib\site-packages\OpenGL\extensions.py in call(self, specifier)
103 def call( self, specifier ):
104 specifier = as_8_bit(specifier).replace(as_8_bit('.'),as_8_bit('_'))
--> 105 if not specifier.startswith( self.prefix ):
106 return None
107

TypeError: startswith first arg must be bytes or a tuple of bytes, not str

@tomgoddard
Copy link
Author

Here's the patch to PyOpenGL 3.1.1a

wgl_python3.patch.gz

mcfletch added a commit that referenced this issue Feb 26, 2018
This is a bit of a belt-and-suspenders approach, but the as-8-bit should
be a near-no-op when the values are already 8-bit
@mcfletch
Copy link
Owner

This should be fixed in the latest release.

@michaelbradley91
Copy link

michaelbradley91 commented Dec 30, 2019

I see the same or a similar problem on 3.1.4 with the same example code. The WGL extension prefix appears to be a string but should be bytes. (prefix is "WGL_")

Edit: the problem seems to go deeper. The prefix is a string, as is the prefix_version check, but further more so is the call to PLATFORM.getExtensionProcedure( 'wglGetExtensionsStringARB' ) which should be passed bytes and is used when loading the extensions

Edit: after patching PLATFORM.getExtensionProcedure( 'wglGetExtensionsStringARB' ) in _WGLQuerier to use bytes as well as the above, it seems to work for this example.

In case it is helpful, an ugly monkey patch for the sake of enabling VSYNC looks like this:

from ctypes import c_char_p
from OpenGL.GLUT import PLATFORM
from OpenGL.raw.WGL._types import HDC
from OpenGL.raw.WGL._types import WGLQuerier


def pullExtensions():
    wglGetCurrentDC = PLATFORM.OpenGL.wglGetCurrentDC
    wglGetCurrentDC.restyle = HDC
    try:
        dc = wglGetCurrentDC()
        proc_address = PLATFORM.getExtensionProcedure(b'wglGetExtensionsStringARB')
        wglGetExtensionStringARB = PLATFORM.functionTypeFor(PLATFORM.WGL)(
            c_char_p,
            HDC,
        )(proc_address)
    except TypeError as err:
        return None
    except AttributeError as err:
        return []
    else:
        return wglGetExtensionStringARB(dc).split()


def monkey_patch():
    WGLQuerier.prefix = WGLQuerier.prefix.encode("utf-8")
    WGLQuerier.version_prefix = WGLQuerier.version_prefix.encode("utf-8")
    WGLQuerier.pullExtensions = pullExtensions

@mcfletch mcfletch reopened this Dec 31, 2019
mcfletch added a commit that referenced this issue Jan 2, 2020
This should have no effect whatsoever, and indeed
it doesn't seem to do anything in testing, but there's
no need to create maybe-unicode and then convert to bytes
rather than just forcing to bytes to start with.
@mcfletch
Copy link
Owner

mcfletch commented Jan 2, 2020

So far I can't replicate this. The functions seem to be correctly loaded and run on Python 3.7 with current develop. I've made trivial changes to use b-strings and thus avoid the calls to as_8_bit, but the effect of as_8_bit is to convert any unicode value to utf-8 encoding via a .encode() call (as in your monkey patch), so the code was, AFAICT already using byte-strings in all of the places you are monkey-patching.

mcfletch added a commit that referenced this issue Jan 4, 2020
* 3e9791f Bump release to 3.1.5
* d06c1ac NUMPY Register intc and uintc as handled scalar types
* 38edb04 WIN FIX GL entry points are NULL on windows initially
* 57b7706 TESTS Run accelerate tests from base tox as well
* 60aec44 BUILD Update cython source with current release
* c26398b TESTS Switch to pytest.mark for skipping numpy handler when not available
* 6ec398d TESTS Switch to assertRaises
* 581d240 TESTS Don't print glget calls, compressed image api call revert
* 8cf737d API More support for using short-string types for convenience
* 1b7c3c3 API In ctypes arrays allow for numpy style short-string type specifiers
* eb9a6b4 FIX Work around weird numpy scalar behaviour (0-dimension arrays)
* d625f8b TESTS reason cannot be passed as a keyword argument in pytest.skip
* f12403b WGL FIX Set the resstyle for getCurrentDC in the wrapper
* 143ecbc GITHUB #7 Use b-strings instead of as_8_bit
* 44a89fe GITIGNORE Ignore .pyd files for Windows develop builds
* a52215f TESTS Fix usage of glCompressedTexImage2D in test_core
* 2f401a0 EGL Allow eglGetDeviceQueryString without display, use to display drm name
* c4cd5d0 BUILD Back out adding python3.8 to the build matrix
* 447fbfa BUILD Continue trying to get sdl to compile
* bdb957b BUILD Add libsdl1.2-dev to get the sld-config utility
* dccbbb6 BUILD Revert attempts to use arm64 (pygame doesn't build) but add python 3.8
* 907ec4a BUILD Experiment with testing on arm64 (loosely related to GH #29)
* 637caf4 TESTS Remove flaky test in favour of more robust one below it
* 144ce85 EGL DEMO Further refactoring of os_egl setup
* a07c956 EGL DEMO Allow for null values in EGL debug table formatting
* 9f115ff EGL Explicitly export EGLError from the EGL namespace
* c58c9c4 EGL Move code to debug, rely on EGLError for display, debug configs
* 93d6f66 EGL DEMO PPM writing and tabular format of configs in EGL debug module
* 9640630 FIX Fix latebind __bool__ definition as __nonzero__ isn't available
* 8628ce1 EGL Allow ErrorCheckers to specify GLError sub-classes, use for EGLError
* 1f1cda4 FORMAT Black formatting for os_egl demo/test script
* 0ed754b FIX for #27 to work on machines where libOpenGL is not present
* 589d3ca EGL Make `eglGetPlatformDisplay` an alternate with `eglGetPlatformDisplayEXT`
* e04bee4 FIX Add on for the fix to #6 to make force_extension functions bool() work
* 2487c21 EGL DEMO Try to create script to query the egl device enumerations
* 41e6f57 EGL DEMO Explicitly delete the DISPLAY environment variable to force offline operation
* 4a40d2b TESTS Ignore the output of osmesa and egl tests
* 3c81386 EGL DEMO Attempt to get an offscreen (pbuffer) render wrapper working
* 8f8d3e8 FIX #27 Load libOpenGL instead of libGL for egl platform
* 4f9cb46 DOCS Add pyrender as a sample source
* d401885 FIX GH #12 Include pxd files in the source-code release
* ca2cbbe DEMO Attempt to recreate github #33 without success
* ce8c5d5 DOCS Update comment to note that we're next to the main checkout now
* f85d8ce DOCS Update tartley projects to github urls, provide first-line links on gh and bb
* e81584a DOCS Skip generation of .xhtml redirect stubs
* 5f206da DEMO provide a running version of code in bug report in #34
* bf3fe7c FIX Explicitly add nonzero methods for base latebind classes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants