diff --git a/demo.py b/demo.py index 9ba1b9f..704ae9e 100644 --- a/demo.py +++ b/demo.py @@ -16,15 +16,15 @@ def __init__(self): def init_mgl(self): self.mgl = MGL() - self.journey_obj = OBJ('data/models/journey/journey.obj', self.mgl.program('data/shaders/default.vert', 'data/shaders/default.frag'), centered=True) + self.knife_obj = OBJ("data/models/knife/knife.obj", self.mgl.program("data/shaders/default.vert", "data/shaders/default.frag"), centered=True) - self.ak_obj = OBJ('data/models/ak47/ak47.obj', self.mgl.program('data/shaders/default.vert', 'data/shaders/default.frag'), centered=True) + self.m4_obj = OBJ("data/models/m4/m4.obj", self.mgl.program("data/shaders/default.vert", "data/shaders/default.frag"), centered=True) - self.shiba_obj = OBJ('data/models/shiba/shiba.obj', self.mgl.program('data/shaders/default.vert', 'data/shaders/default.frag'), centered=True) + self.watch_obj = OBJ("data/models/watch/watch.obj", self.mgl.program("data/shaders/default.vert", "data/shaders/default.frag"), centered=True) - self.test_entity = self.journey_obj.new_entity() - self.test_entity_2 = self.ak_obj.new_entity() - self.test_entity_3 = self.shiba_obj.new_entity() + self.test_entity = self.knife_obj.new_entity() + self.test_entity_2 = self.m4_obj.new_entity() + self.test_entity_3 = self.watch_obj.new_entity() self.camera = Camera(up=(0, -1, 0)) self.camera.light_pos = [0.5, 1, 1] diff --git a/mgllib/camera.py b/mgllib/camera.py index 82ed2a2..b4d61c1 100644 --- a/mgllib/camera.py +++ b/mgllib/camera.py @@ -8,6 +8,7 @@ def __init__(self, pos=[0, 0, 1], target=[0, 0, 0], up=[0, 1, 0]): self.update_matrix() self.light_pos = [0, 1, 0] + self.eye_pos = list(pos) def lookat(self, target): self.target = list(target[:3]) diff --git a/mgllib/glfwhack.py b/mgllib/glfwhack.py index d657f4e..bce763f 100644 --- a/mgllib/glfwhack.py +++ b/mgllib/glfwhack.py @@ -1,6 +1,7 @@ import ctypes import os import sys +import platform import pygame @@ -13,20 +14,28 @@ class DetectContext: def __init__(self): - ctypes.windll.opengl32.wglGetCurrentDC.restype = ctypes.c_void_p - ctypes.windll.opengl32.wglGetCurrentContext.restype = ctypes.c_void_p - self.hdc = ctypes.windll.opengl32.wglGetCurrentDC() - self.hglrc = ctypes.windll.opengl32.wglGetCurrentContext() + if platform.system() == "Windows": + ctypes.windll.opengl32.wglGetCurrentDC.restype = ctypes.c_void_p + ctypes.windll.opengl32.wglGetCurrentContext.restype = ctypes.c_void_p + self.hdc = ctypes.windll.opengl32.wglGetCurrentDC() + self.hglrc = ctypes.windll.opengl32.wglGetCurrentContext() + else: + # On Linux, pygame handles context management internally + self.hdc = None + self.hglrc = None def make_current(self): - ctypes.windll.opengl32.wglMakeCurrent.argtypes = [ctypes.c_void_p, ctypes.c_void_p] - ctypes.windll.opengl32.wglMakeCurrent(self.hdc, self.hglrc) + if platform.system() == "Windows": + ctypes.windll.opengl32.wglMakeCurrent.argtypes = [ctypes.c_void_p, ctypes.c_void_p] + ctypes.windll.opengl32.wglMakeCurrent(self.hdc, self.hglrc) + # On Linux, pygame.display.set_mode already set the current context class g: ctx = None def create_window(*args, **kwargs): - os.environ['SDL_WINDOWS_DPI_AWARENESS'] = 'permonitorv2' + if platform.system() == "Windows": + os.environ['SDL_WINDOWS_DPI_AWARENESS'] = 'permonitorv2' pygame.init() pygame.display.set_mode((1280, 720), flags=pygame.OPENGL | pygame.DOUBLEBUF, vsync=False) diff --git a/mgllib/glfwwin.py b/mgllib/glfwwin.py index 2a57907..110e298 100644 --- a/mgllib/glfwwin.py +++ b/mgllib/glfwwin.py @@ -1,6 +1,6 @@ # This implementation is specific to Windows. See PyOpenXR's hello_xr example for a linux variation. -from OpenGL import GL, WGL +from OpenGL import GL import glfw from .elements import ElementSingleton diff --git a/mgllib/xr_plugin_hack.py b/mgllib/xr_plugin_hack.py index c35c999..d0605de 100644 --- a/mgllib/xr_plugin_hack.py +++ b/mgllib/xr_plugin_hack.py @@ -19,6 +19,15 @@ from .const import FORCE_SRGB def hack_pyopenxr(window_size, window_title='VR Test'): + + def structure_type_missing_wrapper(cls, value): + + # Unknown OpenXR event type (extension event we don't support) + print(f"[WARNING] Unknown StructureType: {value}, returning UNKNOWN", flush=True) + return StructureType.UNKNOWN + + StructureType._missing_ = classmethod(structure_type_missing_wrapper) + # hack the default rendering plugin so we don't have to write a custom one def opengl_graphics_init(self, instance, system, title='glfw OpenGL window'): if not glfw.init(): @@ -99,6 +108,21 @@ def opengl_graphics_select_color_swapchain_format(runtime_formats): return sf raise RuntimeError("No runtime swapchain format supported for color swapchain") + # save begin_frame so we can wrap it + original_begin_frame = OpenGLGraphics.begin_frame + + # wrap begin_frame to suppress invalid value error for glBindFramebuffer + def opengl_graphics_begin_frame_wrapper(self, layer_view, color_texture): + try: + return original_begin_frame(self, layer_view, color_texture) + except GL.error.GLError as e: + # Suppress invalid value error for glBindFramebuffer + if e.err == 1281: + print(f"[WARNING] Suppressed expected OpenGL Error manually in begin_frame: {e}") + else: + raise e + # the cursed overrides OpenGLGraphics.__init__ = opengl_graphics_init - OpenGLGraphics.select_color_swapchain_format = opengl_graphics_select_color_swapchain_format \ No newline at end of file + OpenGLGraphics.select_color_swapchain_format = opengl_graphics_select_color_swapchain_format + OpenGLGraphics.begin_frame = opengl_graphics_begin_frame_wrapper