Giter VIP home page Giter VIP logo

moderngl-window's Introduction

preview

ModernGL

ModernGL is a Python wrapper over OpenGL Core. ModernGL simplifies the creation of graphics applications like scientific simulations, games or user interfaces. Usually, acquiring in-depth knowledge of OpenGL requires a steep learning curve. In contrast, ModernGL is easy to learn and use. ModernGL is capable of rendering with high performance and quality, with less code written.

pip install moderngl

Extras

glcontext - Headless Context Creation

pip install moderngl[headless]

moderngl-window - Window Creation and Resource Loading

pip install moderngl-window

Features

  • GPU accelerated high quality graphics
  • Rendering modern OpenGL scenes with less headache
  • Simpler and faster than PyOpenGL
  • Can render without a window
  • 100% Pythonic

Sample usage

>>> import moderngl
>>> ctx = moderngl.get_context()
>>> buf = ctx.buffer(b"Hello World!")  # allocated on the GPU
>>> buf.read()
b'Hello World!'

For complete examples please visit the Examples.

Easy to use with Pillow

>>> img = Image.open("texture.jpg").convert("RGB")
>>> ctx.texture(img.size, 3, img.tobytes())
<Texture: 1>

Easy to use with Numpy

>>> ctx.buffer(np.array([0.0, 0.0, 1.0, 1.0], dtype="f4"))
<Buffer: 1>

Compared to PyOpenGL

With PyOpenGL, using the original OpenGL API, you have to write three lines to achieve a simple task like binding a VBO:

vbo1 = GL.glGenBuffers(1)
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo1)
GL.glBufferData(GL.GL_ARRAY_BUFFER, b"Hello World!", GL.GL_STATIC_DRAW)

vbo2 = GL.glGenBuffers(1)
GL.glBindBuffer(GL.GL_ARRAY_BUFFER, vbo2)
GL.glBufferData(GL.GL_ARRAY_BUFFER, None, GL.GL_DYNAMIC_DRAW)

With ModernGL you need just one simple line per VBO to achieve the same results:

vbo1 = ctx.buffer(b"Hello World!")
vbo2 = ctx.buffer(reserve=1024, dynamic=True)

Development

git clone [email protected]:moderngl/moderngl.git
cd moderngl
python -m pip install -e .

Notes

ModernGL may be faster than other libraries providing direct OpenGL access. ModernGL is implemented in C++ and a single render call involving multiple OpenGL functions count as a single Python function call.

ModernGL require OpenGL 3.3. Compute Shaders require OpenGL 4.3. Some functionality relies on specific extensions.

ModernGL can be used anywhere where OpenGL is supported. ModernGL is also working in a headless environment.

ModernGL is responsible for calling the OpenGL API and providing a Pythonic user-friendly API instead. It is possible to integrate moderngl into any window libraries that support OpenGL. Consider moderngl-window which implements many of them, plus it also helps with resource loading.

ModernGL does not implement the full OpenGL feature set or extensions. You can interact with the ModernGL objects from OpenGL.

Citation

If you need to cite this repository in academic research:

@Online{Dombi2020,
  author = {Szabolcs Dombi},
  title = {ModernGL, high performance python bindings for OpenGL 3.3+},
  date = {2020-05-01},
  publisher = {GitHub},
  journal = {GitHub repository},
  howpublished = {\url{https://github.com/moderngl/moderngl}},
  commit = {<insert hash if needed>}
}

The commit hash can be found in the Releases.

Community

moderngl-window's People

Contributors

aforren1 avatar alicja-januszkiewicz avatar dalyag avatar davideruzza avatar dbs4261 avatar dominoplayer84 avatar einarf avatar encukou avatar enigmacurry avatar erikstrand avatar frosenek avatar huguesdevimeux avatar joehalliwell avatar julee avatar leterax avatar loreno-heer avatar minujeong avatar n3onuser avatar nbelakovski avatar okaluza avatar rafale25 avatar sheepman4267 avatar szabolcsdombi avatar tpwrules avatar tremeschin avatar xreaper95 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

moderngl-window's Issues

Programs: Modify source line to give better error feedback

From GLSL Spec

#line must have, after macro substitution, one of the following two forms:

#line line
#line line source-string-number

where line and source-string-number are constant integer expressions. After processing this directive (including its new-line), the implementation will behave as if the following line has line number line and starts with source string number source-string-number. Subsequent source strings will be numbered sequentially, until another #line directive overrides that numbering.

If during macro expansion a preprocessor directive is encountered, the results are undefined. The compiler may or may not report an error in such cases

Support loadig TextureCube

We should support loading texture cubes:

  • From 6 independent textures representing the cube map
  • From Single texture cube maps

4 x 3 single cubemap texture.

|       | top    |       |       |
| left  | front  | right | back  |
|       | bottom |       |       |

Trying to open pathlib.Path in Single Program Loader gives error in Python 3.5

When running the loading_obj_files.py example in Python 3.5 I get the following error:

moderngl/examples$ python loading_obj_files.py
...
scene = Scene(self.meta.resolved_path)
  File "../env/lib/python3.5/site-packages/moderngl_window/scene/scene.py", line 46, in __init__
    ProgramDescription(path='scene_default/bbox.glsl'),
  File "../env/lib/python3.5/site-packages/moderngl_window/resources/programs.py", line 22, in load
    return super().load(meta)
  File "../env/lib/python3.5/site-packages/moderngl_window/resources/base.py", line 47, in load
    return meta.loader_cls(meta).load()
  File "../env/lib/python3.5/site-packages/moderngl_window/loaders/program/single.py", line 21, in load
    with open(self.meta.resolved_path, 'r') as fd:
TypeError: invalid file: PosixPath('../env/lib/python3.5/site-packages/moderngl_window/scene/programs/scene_default/bbox.glsl')

Changing line 21 from

 with open(self.meta.resolved_path, 'r') as fd:

to

 with open(str(self.meta.resolved_path), 'r') as fd:

makes the example work.

Tkinter?

I have some (rough) code at https://github.com/jonwright/pyopengltk which makes an OpenGL context for tkinter. You can summarise it as creating empty Tk.frame, and then using the window information (winfo_id/winfo_screen) for some ctypes calls.

Would you be interested to try to get a Tk backend working here?

Event: Support on_mouse_drag

We should support this event for all window types.

Method description from pyglet:

The mouse was moved with one or more mouse buttons pressed. This event will continue to be fired even if the mouse leaves the window, so long as the drag buttons are continuously held down.

We need to explore how this event is handled in all window libraries and if the on_mouse_motion function is also triggered during mouse drag. We could simplify this by checking mouse button states during mouse motion and simply send the event to a generic mouse drag method.

Make PyPI release

We should make an initial PyPI release asap.

Remaining:

  • Do not hack in debug logging
  • Add log level property in WindowConfig
  • SceneLoaders should use the configurable AttributeNames

Improve vsync support

I noticed that when trying to set vsync to false in the following example, vsync is still enabled.

class Window(mglw.WindowConfig):
    gl_version = (3, 3)
    title = 'Test'
    vsync = False

Passing --vsync false via the command line successfully disables vsync for the same context using the default of pyglet.
I also tried both methods with --window glfw and it ignored both and kept vsync enabled.

Do not generate mipmaps by default

Texture loader should not generate mipmaps by default. It should rely on the mipmap parameter and the user should also be able to specify start/end levels.

Scene loading improvements

Currently the Scene instance returned by scene loaders are fairly generic. It contains both the scene structure and is responsible for rendering. This is a problem when handling scenes from different formats, but at least does a decent job at rendering any scene using generic shaders.

Improvements

  • The Scene class should ideally ONLY contain the scene tree with nodes, meshes, materials.
  • Keep the old rendering code intact in the Scene class to not break compatibility.
  • Should support different material classes with with a common base class. Each material should have the same common minimum set of properties that still allows for basic rendering regardless of material class. This way we for example expand material support for wavefront and PBR materials for GLTF2.
  • Move to separate SceneRenderer classes. Have a basic scene renderer what will render any scene and expand to specific ones for wavefront and PBR rendeing for GLTF2. These could take a scene as input and generate a list of scopes ready for rendering. Stick to UBOs and drop as many single uniform setters as possible.
  • Better support for bounding box data.
  • Ensure to provide a decent interface for users to extend and/or implement renderer.

Helper module for basic geometry

I suggest a very simple geometry module were users can generate the most basic meshes (as VAOs) like cubes, plane, sphere. For a lot of people this is probably one of the most frustrating aspects of playing around with rendering if they don't have capabilities of loading scenes.

I do have a very ugly module for this in demosys-py I could strip down and improve.

Helper module for loading basic resources

I think a good addition to this package would be a ressources module with basic functions for loading textures and programs. This should probably have optional dependencies in the package (mainly Pillow for now).

Maybe something like (On the top of my head right now)

load_program
load_texture_1d
load_texture_2d
load_texture_3d
load_texture_cube
load_texture_cube_map

Support basic text/glyph rendering

It would be nice to support basic text rendering. I already have a very simple version in demosys-py that could be ported over and possibly improved: https://github.com/Contraz/demosys-py/tree/master/demosys/effects/text

Right now it's just using a texture generated with freetype-py loaded as a TextureArray.

This part is pretty interesting:

From PyPI, recommended: pip install freetype-py. This will install the library with a bundled FreeType binary, so you’re ready to go on Windows, macOS and Linux (all with 32 and 64 bit x86 architecture support).

This means we could provide cross platform support for generating text on the fly in moderngl_window. Still it should probably be an optional dependency.

https://github.com/rougier/freetype-py

Call native gl functions via PyOpenGL has no context

Backend: glfw
Context OpenGL version: 450 core
Operation system: Windows 10
Python interpreter: Python 3.8.0 [MSC v.1916 64 bit (AMD64)] on win32

I want to call glPolygonMode via PyOpenGL, but a GLError is raised.

Code:

from moderngl-window import *
from moderngl import *
from PyOpenGL.GL import *
import ctypes
import logging

class Config(WindowConfig)
    # Useless details....
    def render(self, time: float, frame_time: float):
        try:
            glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
        except GLError as error:
            logging.error(ctypes.cast(error.description, ctypes.c_char_p).value)
            raise error

run_window_config(Config)

Error log:

python main.py --window glfw
2019-11-16 03:26:36,106 - moderngl_window - INFO - Attempting to load window class: moderngl_window.context.glfw.Window
2019-11-16 03:26:36,487 - moderngl_window.context.base.window - INFO - Context Version:
2019-11-16 03:26:36,487 - moderngl_window.context.base.window - INFO - ModernGL: 5.5.4
2019-11-16 03:26:36,487 - moderngl_window.context.base.window - INFO - vendor: NVIDIA Corporation
2019-11-16 03:26:36,487 - moderngl_window.context.base.window - INFO - renderer: GeForce GTX 1050 Ti/PCIe/SSE2
2019-11-16 03:26:36,487 - moderngl_window.context.base.window - INFO - version: 4.5.0 NVIDIA 431.23
2019-11-16 03:26:36,487 - moderngl_window.context.base.window - INFO - python: 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)]
2019-11-16 03:26:36,488 - moderngl_window.context.base.window - INFO - platform: win32
2019-11-16 03:26:36,488 - moderngl_window.context.base.window - INFO - code: 450
ERROR:root:None
Traceback (most recent call last):
  File "main.py", line 142, in <module>
    run_window_config(Config)
  File "C:\Users\mafumafu\AppData\Local\Programs\Python\Python38\lib\site-packages\moderngl_window\__init__.py", line 198, in run_window_config
    window.render(current_time, delta)
  File "C:\Users\mafumafu\AppData\Local\Programs\Python\Python38\lib\site-packages\moderngl_window\context\base\window.py", line 588, in render
    self.render_func(time, frame_time)
  File "C:/WorkPlace/Python/glumpy_demo/main.py", line 127, in render
    raise error
  File "C:/WorkPlace/Python/glumpy_demo/main.py", line 124, in render
    glPolygonMode(GL_FRONT_AND_BACK, GL_LINE)
  File "C:\Users\mafumafu\AppData\Local\Programs\Python\Python38\lib\site-packages\OpenGL\platform\baseplatform.py", line 402, in __call__
    return self( *args, **named )
  File "C:\Users\mafumafu\AppData\Local\Programs\Python\Python38\lib\site-packages\OpenGL\error.py", line 228, in glCheckError
    raise GLError(
OpenGL.error.GLError: GLError(
	err = 1280,
	description = b'\xce\xde\xd0\xa7\xc1\xd0\xbe\xd9',
	baseOperation = glPolygonMode,
	cArguments = (GL_FRONT_AND_BACK, GL_LINE)
)

It seems that the lack of a OpenGL context.
I put a breakpoint at moderngl_window/context/glfw/__init__.py: line 61

61|    glfw.make_context_current(self._window)

after that line is executed, I could call native OpenGL functions via PyOpenGL
image
image
But I'm confused why I can't do the same thing in render function, is there a solution?
Thanks a lot.

Thanks !

I haven't used this library yet, but wanted to say thanks.

A few years ago tried a whole bunch of GL tutorials in C, C++, Python, JS on desktop, android and the web.

More X-library libs are a really good thing.

In the same way as the buffer protocol made it easy for various libraries to pass around memory areas, maybe at some point in the future there will be low level interface(s) that python graphics libraries will support + interoperate with other effortlessly.

In the meantime, this is a great step forward :)

Look into adding Kivy window

Should look into adding a windiw using Kivy. I'm not sure if this will work perfectly cross platform considering OS X only allows 3.3 core. Worth a shot,

Consider making widget for pyside2, pyqt5 and tkinter

We currently only provide a window with a single widget covering the entire window. If we could also provide a ModernglWidget that can easily be used together with other Qt widgets it would make the use of moderngl a lot easier for those kind of use cases.

A lot of information is already collected here:
moderngl/moderngl#348

copying buffer / trying to render to texture and screen again

Hello,
I'm trying to render to a texture and render to screen again (hopefully just once). However I tried 2 versions and at both I failed:
A) RTT, copy to screen
B) RTT, render to screen

min code:

self.vao = self.ctx.vertex_array(self.prog2, self.vao_content, self.ibo)
size = (1024, 1024)
self.texture = self.ctx.texture(size, components=3, dtype='f1')
depth_attachment = self.ctx.depth_renderbuffer(size)
self.fbo1 = self.ctx.framebuffer(self.texture, depth_attachment)

#render method A
self.fbo1.use()
self.vao.render()
self.ctx.detect_framebuffer().use()
self.vao.render()
self.ctx.finish()

#render method B
self.fbo1.use()
self.vao.render()
#self.ctx.detect_framebuffer().use()
self.ctx.copy_framebuffer(self.ctx.screen, self.fbo1)
self.ctx.finish()

Is there something obvious I do miss?

Test

This is a test

Events: Support unicode character callback

We need to support the standard callback when a unicode character is pressed. These are only characters that can appear in text fields and such. No control characters.

pyglet and glfw are good references. I think we can support this simply by using unicodedata.category(char) in the keypress callback. The event must be set after the actual key press event.

Version Plan

So far the following seems to be realistic.

1.x

Will only support moderngl 5.5.x

2.x

Will support both moderngl 5 and 6 using moderngl 5.6.

3.x

Only supports moderngl 6.x

Call ctx.line_width = 50 raise GL_INVALID_VALUE

Backend: glfw
Context OpenGL version: 450 core
Operation system: Windows 10
Python interpreter: Python 3.8.0 [MSC v.1916 64 bit (AMD64)] on win32

I want to change ctx.line_width but nothing happened.

Code:

from moderngl-window import *
from moderngl import *
from OpenGL.GL import *
import ctypes
import logging

class Config(WindowConfig):
    gl_version = (4, 5)
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        ctx = self.ctx
        ctx.line_width = 50
        print(ctx.error)
        print(ctx.line_width)


run_window_config(Config)

Log:

python main.py --window glfw
2019-11-16 14:15:40,698 - moderngl_window - INFO - Attempting to load window class: moderngl_window.context.glfw.Window
2019-11-16 14:15:40,995 - moderngl_window.context.base.window - INFO - Context Version:
2019-11-16 14:15:40,995 - moderngl_window.context.base.window - INFO - ModernGL: 5.5.4
2019-11-16 14:15:40,996 - moderngl_window.context.base.window - INFO - vendor: NVIDIA Corporation
2019-11-16 14:15:40,996 - moderngl_window.context.base.window - INFO - renderer: GeForce GTX 1050 Ti/PCIe/SSE2
2019-11-16 14:15:40,996 - moderngl_window.context.base.window - INFO - version: 4.5.0 NVIDIA 431.23
2019-11-16 14:15:40,996 - moderngl_window.context.base.window - INFO - python: 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)]
2019-11-16 14:15:40,996 - moderngl_window.context.base.window - INFO - platform: win32
2019-11-16 14:15:40,996 - moderngl_window.context.base.window - INFO - code: 450
GL_INVALID_VALUE
1.0

But according to the document, GL_INVALID_VALUE should be raised if param is less or equal to 0.

Use the native glLineWidth call has the same effect.
Code:

class Config(WindowConfig):
    gl_version = (4, 5)
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        try:
            glLineWidth(50)
        except GLError as error:
            print(ctypes.cast(error.description, ctypes.c_char_p).value)
            raise error

run_window_config(Config)

Log:

python main.py --window glfw
2019-11-16 14:22:41,288 - moderngl_window - INFO - Attempting to load window class: moderngl_window.context.glfw.Window
None
2019-11-16 14:22:41,796 - moderngl_window.context.base.window - INFO - Context Version:
2019-11-16 14:22:41,796 - moderngl_window.context.base.window - INFO - ModernGL: 5.5.4
2019-11-16 14:22:41,796 - moderngl_window.context.base.window - INFO - vendor: NVIDIA Corporation
2019-11-16 14:22:41,796 - moderngl_window.context.base.window - INFO - renderer: GeForce GTX 1050 Ti/PCIe/SSE2
2019-11-16 14:22:41,796 - moderngl_window.context.base.window - INFO - version: 4.5.0 NVIDIA 431.23
2019-11-16 14:22:41,796 - moderngl_window.context.base.window - INFO - python: 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)]
2019-11-16 14:22:41,796 - moderngl_window.context.base.window - INFO - platform: win32
2019-11-16 14:22:41,796 - moderngl_window.context.base.window - INFO - code: 450
Traceback (most recent call last):
  File "C:/WorkPlace/Python/glumpy_demo/main.py", line 151, in <module>
    run_window_config(Config, args=['--window', 'glfw'])
  File "c:\users\mafumafu\downloads\moderngl-window\moderngl_window\__init__.py", line 190, in run_window_config
    window.config = config_cls(ctx=window.ctx, wnd=window, timer=timer)
  File "C:/WorkPlace/Python/glumpy_demo/main.py", line 54, in __init__
    raise error
  File "C:/WorkPlace/Python/glumpy_demo/main.py", line 51, in __init__
    glLineWidth(50)
  File "C:\Users\mafumafu\AppData\Local\Programs\Python\Python38\lib\site-packages\OpenGL\platform\baseplatform.py", line 402, in __call__
    return self( *args, **named )
  File "C:\Users\mafumafu\AppData\Local\Programs\Python\Python38\lib\site-packages\OpenGL\error.py", line 228, in glCheckError
    raise GLError(
OpenGL.error.GLError: GLError(
	err = 1281,
	description = b'\xce\xde\xd0\xa7\xd6\xb5',
	baseOperation = glLineWidth,
	cArguments = (50,)
)

But everything goes well if I create a standalone context.

λ python
Python 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from moderngl import *
>>> ctx = create_standalone_context()
>>> from OpenGL.GL import *
>>> glLineWidth(50)
>>> glGetFloat(GL_LINE_WIDTH)
50.0
>>> ctx.line_width
50.0

What should I do to solve it?

PS:
ctx.point_size goes well.
Code:

class Config(WindowConfig):
    gl_version = (4, 5)
    window_size = (640, 360)
    aspect_ratio = 16 / 9
    log_level = logging.DEBUG

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        ctx = self.ctx
        glPolygonMode(GL_FRONT_AND_BACK, GL_POINT)
        print(ctx.error)
        print(ctx.point_size)
        # Useless details


run_window_config(Config)

Log:

python main.py --window glfw
2019-11-16 14:33:45,808 - moderngl_window - INFO - Attempting to load window class: moderngl_window.context.glfw.Window
2019-11-16 14:33:46,303 - moderngl_window.context.base.window - INFO - Context Version:
2019-11-16 14:33:46,303 - moderngl_window.context.base.window - INFO - ModernGL: 5.5.4
2019-11-16 14:33:46,305 - moderngl_window.context.base.window - INFO - vendor: NVIDIA Corporation
2019-11-16 14:33:46,305 - moderngl_window.context.base.window - INFO - renderer: GeForce GTX 1050 Ti/PCIe/SSE2
2019-11-16 14:33:46,305 - moderngl_window.context.base.window - INFO - version: 4.5.0 NVIDIA 431.23
2019-11-16 14:33:46,305 - moderngl_window.context.base.window - INFO - python: 3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:37:50) [MSC v.1916 64 bit (AMD64)]
2019-11-16 14:33:46,305 - moderngl_window.context.base.window - INFO - platform: win32
2019-11-16 14:33:46,305 - moderngl_window.context.base.window - INFO - code: 450
GL_NO_ERROR
50.0

Image:
image

Look into supporting mouse exclusivity

We should support mouse exclusivity consitently between all the windows and properly separate between a hidden cursor and mouse exclusivity. This ensures mouse movements are not clipped to the window borders both in fullscreen and windowed mode.

This also means we need to handle the mouse dx/dy instead of position.
A suggestion so far is only supporting it for pyglet, glfw and sdl2. Still we need to figure out how this affects other functions dealing with the mouse.

pyglet

https://pyglet.readthedocs.io/en/stable/programming_guide/mouse.html#mouse-exclusivity

glfw

We already use mouse exclusivity in glfw.

# Hide cursor
glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_DISABLED)
# Mouse exclusivity
glfwSetInputMode(m_window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN)

pyqt5 / pyside2

Possible by constraining the mouse course to the middle of the screen. There are some challenges on how different platforms handle this.

sdl2

SDL has a SDL_SetRelativeMouseMode function. This forces SDL to only report motion events, so the mouse position doesn't change.

tkinter

No idea ... might be platform dependent.

TypeError: mouse_position_event()

python3 water.py ~/coding/gpu/moderngl-window/examples/advanced(master)@Lolarch
2019-11-09 18:51:51,458 - moderngl_window - INFO - Attempting to load window class: moderngl_window.context.pyglet.Window
2019-11-09 18:51:53,908 - moderngl_window.context.base.window - INFO - Context Version:
2019-11-09 18:51:53,909 - moderngl_window.context.base.window - INFO - ModernGL: 5.5.3
2019-11-09 18:51:53,915 - moderngl_window.context.base.window - INFO - vendor: Intel Open Source Technology Center
2019-11-09 18:51:53,915 - moderngl_window.context.base.window - INFO - renderer: Mesa DRI Intel(R) Sandybridge Mobile
2019-11-09 18:51:53,915 - moderngl_window.context.base.window - INFO - version: 3.3 (Core Profile) Mesa 19.2.3
2019-11-09 18:51:53,915 - moderngl_window.context.base.window - INFO - python: 3.7.4 (default, Oct 4 2019, 06:57:26)
[GCC 9.2.0]
2019-11-09 18:51:53,915 - moderngl_window.context.base.window - INFO - platform: linux
2019-11-09 18:51:53,915 - moderngl_window.context.base.window - INFO - code: 330
2019-11-09 18:51:53,928 - moderngl_window.loaders.program.single - INFO - Loading: programs/water/drop.glsl
2019-11-09 18:51:53,930 - moderngl_window.loaders.program.single - INFO - Loading: programs/water/wave.glsl
2019-11-09 18:51:53,930 - moderngl_window.loaders.program.single - INFO - Loading: programs/water/texture.glsl
Traceback (most recent call last):
File "water.py", line 120, in
moderngl_window.run_window_config(Water)
File "/home/lolart/.local/lib/python3.7/site-packages/moderngl_window/init.py", line 198, in run_window_config
window.swap_buffers()
File "/home/lolart/.local/lib/python3.7/site-packages/moderngl_window/context/pyglet/window.py", line 102, in swap_buffers
self._window.dispatch_events()
File "/home/lolart/.local/lib/python3.7/site-packages/pyglet/window/xlib/init.py", line 837, in dispatch_events
self.dispatch_pending_events()
File "/home/lolart/.local/lib/python3.7/site-packages/pyglet/window/xlib/init.py", line 874, in dispatch_pending_events
EventDispatcher.dispatch_event(self, *self._event_queue.pop(0))
File "/home/lolart/.local/lib/python3.7/site-packages/pyglet/event.py", line 416, in dispatch_event
self._raise_dispatch_exception(event_type, args, handler, exception)
File "/home/lolart/.local/lib/python3.7/site-packages/pyglet/event.py", line 479, in _raise_dispatch_exception
raise exception
File "/home/lolart/.local/lib/python3.7/site-packages/pyglet/event.py", line 413, in dispatch_event
if handler(*args):
File "/home/lolart/.local/lib/python3.7/site-packages/moderngl_window/context/pyglet/window.py", line 159, in on_mouse_motion
self._mouse_position_event_func(x, self._buffer_height - y)
TypeError: mouse_position_event() missing 2 required positional arguments: 'dx' and 'dy'

Programs: Support passing in macros/defines

The following...

ProgramDescription(
    'program.glsl',
    defines=[('NUM_ENTRIES' '256')],
)

.. will add the macro/define

#define NUM_ENTRIES 100

It should probably also replace an existing #define in the source.

Follow up on Pyglet 2.x

Pyglet 2.x might be a good candidate for the default window. Some short exchanges with one of the pyglet devs in reddit indicates they are aiming for 3.3 as a minimum and I urged them to use forward compatible core contexts just in case.

EDIT: They are indeed doing context creation right: https://bitbucket.org/pyglet/pyglet/src/ea6080cbb3c0370124b30543757da8349f8ed3a3/pyglet/gl/cocoa.py?at=default&fileviewer=file-view-default#cocoa.py-196:204

https://www.reddit.com/r/Python/comments/acz876/looking_for_pure_python_graphics_engine_tutorial/edcr2vo/

The advantage of using Pyglet as the standard window is:

  • No external dependencies just like PyQt5
  • Vastly smaller library compared to PyQt5
  • Pyglet is using BSD License while PyQt5 can cause licensing issues for some

Screenshots of FBOs with multisampling

.. currently produces random noise.

Might be something to address in moderngl itself. No idea to even start on this one, but I'll let this hang around because it's a real issue.

Make window for PySides2

This is an alternative to PyQt5 with a less restrictive license (LGPLv3/GPLv2). The bindings are more or less the same.

Texture flip parameter should be None by default

Currently the flip parameter is True by default. This makes sense for 2d textures, but it doesn't make sense for texture arrays. Instead each loader type should have a default behavior when flip is None.

  • 2d loader use True
  • array loader use False

VAO wrapper: Add normalized floats

We just need to add these as valid types and specify a byte size.

  • nf normalized float
  • ni2 normalized signed short
  • nu4 normalized unsigned int

Examples needs more work

The current examples are a bit random and need cleanup. A proper README.md in the example directory is also needed.

Resource cache system

Resource Cache System

I'm using this library myself for fairly lage amount of data and noticing that load times can start to become a burden after a certain point.

This was solved in pywavefront by adding a cache system that stores the parsed file in a binary format with vertex data that more or less can be dumped directly into the buffers. This reduced load times 10-100x depending on the file size. I'm wondering if we can use the same technique to reduce loading times in general.

I suspect this can be improved by suporting a file caching system for all loaders. A new settings value CACHE_DIR can be added to settings. This would be an absolute path to a directory were cache files are stored.

Some Considerations

  • We probably need to calculate the hash of the original file and compare that with some manifest file that belongs to the cached resource
  • Since we support multiple resource directories the same resource can potentially exist in the same relative path if the user change the search directory order. Using the absolute path to the resource as key is probably the only way to solve this right now.
  • Store the file using a hashed version of the absolute path. <hash>.json and <hash>.bin
  • We want to support automatic detection of resource file changes. This means for example a sha256 can be performed on the original file first and compare that to the value in the manifest.
  • We also need to store some load parameters that affects the final file layout.
{
    "sha256": "XXXXXXXXXXXXX",
    "parameters": {
        "flip": true,
    }
}
  • If the sha256 and parameters don't match we will overwrite the existing file and store an updated manifest
  • Users should be able to disable the sha256 comparison to further speed up loading.
  • Implement the cache loading part as an actual loader in the same module as the normal loader. This could potentially be used for creating things in the future.
  • Using absolute path makes it impossible to transfer these files across different computers. This might be a problem if user wants a pre-created cache.

Test Case : Textures

A good test case is to support file cache for textures. If we can reduce the load time by 50% I would call it a success. The cache file will simply contain the raw texture data loaded by Pillow after modifiers (horisontal flip etc). This way we can dump this directly into a texture using GzipFile.

The question is if the sha256 checks alone will negate the benefits of the cache system.

Additonal Notes

  • GLTF 2.0 format is already very fast to load and currently don't need attention
  • Wavefront/obj loader supports cache files and would need to be integrated with the system.
  • 2D textures and arrays benefiting from file cache needs testing. I suspect larger textures like 4 and 8k textures will benefit as I've noticed PIL is very slow in those cases.
  • TextureCube from a single texture would definitly benefit from this as slicing the texture into new images can be time consuming.
  • Make sure the cache system has a simple API to build on

Pathlib issue with python 3.6

model = WindowConfig.load_scene("/input/uv.obj")
Traceback (most recent call last):
File "", line 1, in
File "/usr/local/lib/python3.6/dist-packages/moderngl_window/context/base/window.py", line 673, in load_scene
**kwargs,
File "/usr/local/lib/python3.6/dist-packages/moderngl_window/resources/scenes.py", line 18, in load
return super().load(meta)
File "/usr/local/lib/python3.6/dist-packages/moderngl_window/resources/base.py", line 46, in load
self.resolve_loader(meta)
File "/usr/local/lib/python3.6/dist-packages/moderngl_window/resources/base.py", line 97, in resolve_loader
if loader_cls.supports_file(meta):
File "/usr/local/lib/python3.6/dist-packages/moderngl_window/loaders/base.py", line 34, in supports_file
path = Path(meta.path)
File "/usr/lib/python3.6/pathlib.py", line 1001, in new
self = cls._from_parts(args, init=False)
File "/usr/lib/python3.6/pathlib.py", line 656, in _from_parts
drv, root, parts = self._parse_args(args)
File "/usr/lib/python3.6/pathlib.py", line 640, in _parse_args
a = os.fspath(a)
TypeError: expected str, bytes or os.PathLike object, not type

Package version

I suggest aligning the version of this package with the ModernGL version. At least the major version. I'm not entirely sure where to go from there, but would that will be sufficient?

Python 3.8

Test with python 3.8 when moderngl wheels are created. Add classifiers and release new version.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.