Closed DeafMan1983 closed 2 years ago
Hi @DeafMan1983,
I think your issue is that PySDL2 expects bytestrings instead of regular strings in Python 3, hence why you're getting a type error. If you swap out "glGetString"
for b"glGetString"
, your code should work as intended.
That said, you may want to check out PyOpenGL if you haven't already: that's what I personally use for working with OpenGL in PySDL2 and it makes things much easier.
Hope that helps!
@a-hurst - I think you would like to pass like in C# like example from MonoGame's FuncLoader
But I would know how does it work under Python.
def gl_function(func_name, args_types, return_type):
sdlgl_param = ctypes.WINFUNCTYPE(func_name, args_types, return_type)
sdlgl = sdl2.SDL_GL_GetProcAddress(func_name)
if sdlgl == 0:
raise Exception("Error: wrong method if you check method from binding library.")
gl_func = sdlgl_param(sdlgl)
gl_func.argtypes = args_types
gl_func.restype = return_type
return gl_func
But I got error:
Traceback (most recent call last):
File "C:\Users\Jens\PycharmProjects\01_HelloWorld\01_HelloWorld.py", line 63, in <module>
sys.exit(run())
File "C:\Users\Jens\PycharmProjects\01_HelloWorld\01_HelloWorld.py", line 35, in run
GetString = gl_function("glGetString", [ctypes.c_int32], ctypes.c_char_p)
File "C:\Users\Jens\PycharmProjects\01_HelloWorld\01_HelloWorld.py", line 8, in gl_function
sdlgl_param = ctypes.WINFUNCTYPE(func_name, args_types, return_type)
File "C:\Users\Jens\scoop\apps\python\current\lib\ctypes\__init__.py", line 124, in WINFUNCTYPE
return _win_functype_cache[(restype, argtypes, flags)]
TypeError: unhashable type: 'list'
Why I don't like PyOpenGL because it has many wrong types like glVertexAttribPointer and glBufferData - I have installed with PyOpenGL but it is not append to C/C++, Java, C# or other langauges both methods from PyOpenGL have bad parameters
I want create own method with SDL_GL_GetProcAddress() Like I show you
glBufferData(GLEnum type, "POINTER or ulong", c_void_p, GLEnum usage) is correct
Example: glBufferData(GL_ARRAY_BUFFER, POINTER(vertices.nBytes * sizeof(float), c_void_p(vertices[0]), GL_STATIC_DRAW)
like in C# example: glBufferData(GL_ARRAY_BUFFER, (IntPtr)(vertices.Length * sizeof(float), vertices_ptr, GL_STATIC_ARRAY)
vertices_ptr was fixed statement.
@DeafMan1983 You're running into another type error: it looks like you're creating your WINFUNCTYPE with args_types
as a list, but the ctypes docs show that you're supposed to define the type of each argument as a separate parameter.
Changing the first line of your function to
sdlgl_param = ctypes.WINFUNCTYPE(func_name, *args_types, return_type)
(note the asterisk in front of args_types
) should fix the issue.
@a-hurst Thanks I already fixed it but why does error throw me I should type for restype?
def gl_function(func_name, args_types, return_type):
sdlgl_param = ctypes.WINFUNCTYPE(func_name, *args_types, return_type)
sdlgl = sdl2.SDL_GL_GetProcAddress(func_name)
if sdlgl == 0:
raise Exception("Error: wrong method if you check method from binding library.")
gl_func = sdlgl_param(sdlgl)
gl_func.argtypes = args_types
gl_func.restype = return_type
return gl_func
And I type function GetString
GetString = gl_function("glGetString", [ctypes.c_int32], ctypes.c_char_p)
And I give end of function in while loop or after creating gl_context of SDL2
print(b"OpenGL Version is " + GetString(GL.GL_VERSION)) # It is my initial test GL_Function with SDL_GL_GetProcAddress()
Then I got exception:
TypeError: _restype_ must be a type, a callable, or None
Where do I put casting of gl_function?
@DeafMan1983 Just tested this out myself, looks like there were a couple issues with your code: first, "glGetString"
is a regular string and not a byte string (which is what ctypes needs). Second, ctypes.CFUNCTYPE
takes return type as its first argument, then argument types, and doesn't take the function name at all. Third, maybe you didn't paste the full test code, but you need to initialize an OpenGL context with SDL2 in order to get function addresses from the library. The following code does what I think you were looking for:
import sdl2
import ctypes
from OpenGL import GL
def gl_function(func_name, args_types, return_type):
sdlgl_param = ctypes.CFUNCTYPE(return_type, *args_types)
sdlgl = sdl2.SDL_GL_GetProcAddress(func_name)
if sdlgl == 0:
raise Exception("Error: wrong method if you check method from binding library.")
gl_func = sdlgl_param(sdlgl)
return gl_func
sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO)
sdl2.SDL_GL_LoadLibrary(None)
window = sdl2.SDL_CreateWindow(
b"OpenGL", 10, 40, 32, 24, sdl2.SDL_WINDOW_OPENGL
)
ctx = sdl2.SDL_GL_CreateContext(window)
GetString = gl_function(b"glGetString", [ctypes.c_uint], ctypes.c_char_p)
print(b"OpenGL Version is " + GetString(GL.GL_VERSION))
...which gets me b'OpenGL Version is 2.1 Metal - 76.3'
on my system. Hope that helps!
I have problem with SDL_GL_GetProcAddress()
like custom function with ctypes:
But it throws error:
ctypes.ArgumentError: argument 1: <class 'TypeError'>: wrong type
How do I cast with SDL_GL_GetProcAddress() example I want create function for example:
GetString = gl_function("glGetString", [ctypes.c_int], ctypes.c_char_p)
It meansconst char* glString(GLEnum type)
GLEnum is intHow do I get successful with SDL_GL_GetProcAddress thanks I am sorry for disturbance :/
Kind regards