python - How to initialize OpenGL with glXChooseFBConfig and ctypes module? -
i want make simple opengl animation on tkinter window. dont want include needless dependencies i'm writing scratch ctypes. far have this:
#!/usr/bin/env python3 import tkinter import ctypes ctypes import cdll glx_pixmap_bit = 0x00000002 glx_window_bit = 0x00000001 glx_pbuffer_bit = 0x00000004 glx_rgba_bit = 0x00000001 glx_color_index_bit = 0x00000002 glx_pbuffer_clobber_mask = 0x08000000 glx_front_left_buffer_bit = 0x00000001 glx_front_right_buffer_bit = 0x00000002 glx_back_left_buffer_bit = 0x00000004 glx_back_right_buffer_bit = 0x00000008 glx_aux_buffers_bit = 0x00000010 glx_depth_buffer_bit = 0x00000020 glx_stencil_buffer_bit = 0x00000040 glx_accum_buffer_bit = 0x00000080 glx_config_caveat = 0x20 glx_x_visual_type = 0x22 glx_transparent_type = 0x23 glx_transparent_index_value = 0x24 glx_transparent_red_value = 0x25 glx_transparent_green_value = 0x26 glx_transparent_blue_value = 0x27 glx_transparent_alpha_value = 0x28 glx_dont_care = 0xffffffff glx_none = 0x8000 glx_slow_config = 0x8001 glx_true_color = 0x8002 glx_direct_color = 0x8003 glx_pseudo_color = 0x8004 glx_static_color = 0x8005 glx_gray_scale = 0x8006 glx_static_gray = 0x8007 glx_transparent_rgb = 0x8008 glx_transparent_index = 0x8009 glx_visual_id = 0x800b glx_screen = 0x800c glx_non_conformant_config = 0x800d glx_drawable_type = 0x8010 glx_render_type = 0x8011 glx_x_renderable = 0x8012 glx_fbconfig_id = 0x8013 glx_rgba_type = 0x8014 glx_color_index_type = 0x8015 glx_max_pbuffer_width = 0x8016 glx_max_pbuffer_height = 0x8017 glx_max_pbuffer_pixels = 0x8018 glx_preserved_contents = 0x801b glx_largest_pbuffer = 0x801c glx_width = 0x801d glx_height = 0x801e glx_event_mask = 0x801f glx_damaged = 0x8020 glx_saved = 0x8021 glx_window = 0x8022 glx_pbuffer = 0x8023 glx_pbuffer_height = 0x8040 glx_pbuffer_width = 0x8041 glx_accum_alpha_size = 17 glx_accum_blue_size = 16 glx_accum_green_size = 15 glx_accum_red_size = 14 glx_alpha_size = 11 glx_aux_buffers = 7 glx_bad_attribute = 2 glx_bad_context = 5 glx_bad_enum = 7 glx_bad_screen = 1 glx_bad_value = 6 glx_bad_visual = 4 glx_blue_size = 10 glx_buffer_size = 2 glx_bufferswapcomplete = 1 glx_depth_size = 12 glx_doublebuffer = 5 glx_green_size = 9 glx_level = 3 glx_no_extension = 3 glx_pbufferclobber = 0 glx_red_size = 8 glx_rgba = 4 glx_stencil_size = 13 glx_stereo = 6 glx_use_gl = 1 class openglview(tkinter.frame): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._x_window_id = self.winfo_id() self._init_gl() def _init_gl(self): self._xlib = cdll.loadlibrary('libx11.so') self._gl = cdll.loadlibrary('libgl.so') self._glx = cdll.loadlibrary('libglu.so') self._x_display = self._xlib.xopendisplay() elements = [ glx_x_renderable, 1, glx_drawable_type, glx_window_bit, glx_render_type, glx_rgba_bit, glx_x_visual_type, glx_true_color, glx_doublebuffer, 1, glx_red_size, 8, glx_green_size, 8, glx_blue_size, 8, glx_alpha_size, 8, glx_depth_size, 24, glx_stencil_size, 8, 0 ] elements = (ctypes.c_int * len(elements))(*elements) gl_configs = self._glx.glxchoosefbconfig(self._x_display, 0, ctypes.byref(elements), ctypes.sizeof(elements)) context = self._glx.glxcreatenewcontext(self._x_display, gl_configs[0], self._glx.glx_rgba_type, none, true) self._glx.glxmakecontextcurrent(self._x_display, self._x_window_id, self._x_window_id, context) tk = tkinter.tk() v = openglview(tk) v.pack(fill=tkinter.both, expand=true) tk.mainloop()
why piece of code generates error?
libgl error: no matching fbconfigs or visuals found libgl error: failed load driver: swrast segmentation fault (core dumped)
i don't have linux distribution @ hand right test it, mcve?
from ctypes import c_char_p, c_void_p, cdll ctypes import c_bool, c_char_p, c_double, c_float, c_int, c_uint, c_ulong, c_void_p, pointer tkinter import tk, yes, both _xlib = cdll.loadlibrary('libx11.so') _gl = cdll.loadlibrary('libgl.so') # data types linux platform xid = c_ulong glxdrawable = xid # data types opengl glbitfield = c_uint glubyte = c_char_p glclampf = c_float glclampd = c_double gldouble = c_double glenum = c_uint glfloat = c_float glint = c_int gl_blend = 0x0be2 gl_color_buffer_bit = 0x00004000 gl_depth_buffer_bit = 0x00000100 gl_depth_test = 0x0b71 gl_modelview = 0x1700 gl_one_minus_src_alpha = 0x0303 gl_projection = 0x1701 gl_quads = 0x0007 gl_renderer = 0x1f01 gl_src_alpha = 0x0302 gl_vendor = 0x1f00 gl_version = 0x1f02 gl_true = 1 # constants linux platform pglint = glint * 11 glx_rgba = 4 glx_red_size = 8 glx_green_size = 9 glx_blue_size = 10 glx_depth_size = 12 glx_doublebuffer = 5 # opengl function definitions glbegin = _gl.glbegin glbegin.restype = none glbegin.argtypes = [glenum] glclear = _gl.glclear glclear.restype = none glclear.argtypes = [glbitfield] glblendfunc = _gl.glblendfunc glblendfunc.restype = none glblendfunc.argtypes = [glenum, glenum] glclearcolor = _gl.glclearcolor glclearcolor.restype = none glclearcolor.argtypes = [glclampf, glclampf, glclampf, glclampf] glcleardepth = _gl.glcleardepth glcleardepth.restype = none glcleardepth.argtypes = [glclampd] glcolor3f = _gl.glcolor3f glcolor3f.restype = none glcolor3f.argtypes = [glfloat, glfloat, glfloat] glenable = _gl.glenable glenable.restype = none glenable.argtypes = [glenum] glend = _gl.glend glend.restype = none glend.argtypes = none glflush = _gl.glflush glflush.restype = none glflush.argtypes = none glgetstring = _gl.glgetstring glgetstring.restype = glubyte glgetstring.argtypes = [glenum] glloadidentity = _gl.glloadidentity glloadidentity.restype = none glloadidentity.argtypes = none glmatrixmode = _gl.glmatrixmode glmatrixmode.restype = none glmatrixmode.argtypes = none glortho = _gl.glortho glortho.restype = none glortho.argtypes = [gldouble, gldouble, gldouble, gldouble, gldouble, gldouble] glrotatef = _gl.glrotatef glrotatef.restype = none glrotatef.argtypes = [glfloat, glfloat, glfloat, glfloat] glvertex3f = _gl.glvertex3f glvertex3f.restype = none glvertex3f.argtypes = [glfloat, glfloat, glfloat] glviewport = _gl.glviewport glviewport.restype = none glviewport.argtypes = [glint, glint, glint, glint] glxchoosevisual = _gl.glxchoosevisual glxchoosevisual.argtypes = [c_void_p, c_int, pointer(c_int)] glxchoosevisual.restype = c_void_p glxcreatecontext = _gl.glxcreatecontext glxcreatecontext.argtypes = [c_void_p, c_void_p, c_void_p, c_bool] glxcreatecontext.restype = c_void_p glxmakecurrent = _gl.glxmakecurrent glxmakecurrent.argtypes = [c_void_p, glxdrawable, c_void_p] glxmakecurrent.restype = c_bool glxswapbuffers = _gl.glxswapbuffers glxswapbuffers.argtypes = [c_void_p, glxdrawable] glxswapbuffers.resttype = none x11_none = 0 x_open_display = _xlib.xopendisplay x_open_display.argtypes = [c_char_p] x_open_display.restype = c_void_p class tkoglwin(frame): def __init__(self, parent, *args, **kwargs): frame.__init__(self, parent, *args, **kwargs) self.parent = parent self.parent.title(kwargs.get('app_title', 'opengl test')) self.bind('<configure>', self.on_resize) self.parent.after(100, self._cfg_tkogl) def _cfg_tkogl(self): att = pglint( glx_rgba, glx_doublebuffer, glx_red_size, 4, glx_green_size, 4, glx_blue_size, 4, glx_depth_size, 16, x11_none ) self.dpy = x_open_display(none) vi = glxchoosevisual(self.dpy, 0, att) glc = glxcreatecontext(self.dpy, vi, none, gl_true) glxmakecurrent(self.dpy, self.winfo_id(), glc) self.set_ortho_view() self.parent.after(10, self._render_loop) def on_resize(self, event, arg=none): raise notimplementederror def _render_loop(self): self.render_scene() glxswapbuffers(self.dpy, self.winfo_id()) self.parent.after(5, self._render_loop) def render_scene(self): raise notimplementederror def set_ortho_view(self): raise notimplementederror class appogl(tkoglwin): rot = 0 def on_resize(self, event, arg=none): if event: w = event.width h = event.height else: if arg: w = arg['w'] h = arg['h'] else: raise exception dx = w / h glviewport(0, 0, w, h) glmatrixmode(gl_projection) glloadidentity() glortho(-2 * dx, 2 * dx, -2, 2, -2, 2) def set_ortho_view(self): glenable(gl_blend) glenable(gl_depth_test) glblendfunc(gl_src_alpha, gl_one_minus_src_alpha) glclearcolor(0, 0, 0, 0) glcleardepth(1) glmatrixmode(gl_projection) self.on_resize(none, arg={ 'w': self.winfo_width(), 'h': self.winfo_height() }) print('%s - %s - %s' % ( glgetstring(gl_vendor), glgetstring(gl_version), glgetstring(gl_renderer) )) def render_scene(self): self.rot += .5 glclear(gl_color_buffer_bit | gl_depth_buffer_bit) glmatrixmode(gl_modelview) glloadidentity() glrotatef(self.rot, 1, 1, 0.5) # draw simple cube. glbegin(gl_quads) glcolor3f(0, 1, 0) glvertex3f(1, 1, -1) glvertex3f(-1, 1, -1) glvertex3f(-1, 1, 1) glvertex3f(1, 1, 1) glcolor3f(1, 0.5, 0) glvertex3f(1, -1, 1) glvertex3f(-1, -1, 1) glvertex3f(-1, -1, -1) glvertex3f(1, -1, -1) glcolor3f(1, 0, 0) glvertex3f(1, 1, 1) glvertex3f(-1, 1, 1) glvertex3f(-1, -1, 1) glvertex3f(1, -1, 1) glcolor3f(1, 1, 0) glvertex3f(1, -1, -1) glvertex3f(-1, -1, -1) glvertex3f(-1, 1, -1) glvertex3f(1, 1, -1) glcolor3f(0, 0, 1) glvertex3f(-1, 1, 1) glvertex3f(-1, 1, -1) glvertex3f(-1, -1, -1) glvertex3f(-1, -1, 1) glcolor3f(1, 0, 1) glvertex3f(1, 1, -1) glvertex3f(1, 1, 1) glvertex3f(1, -1, 1) glvertex3f(1, -1, -1) glend() glflush() if __name__ == '__main__': root = tk() app = appogl(root, width=320, height=200) app.pack(fill=both, expand=yes) app.mainloop()
Comments
Post a Comment