From a22f6d46ab49828b52338e2d579dfd4246db60cb Mon Sep 17 00:00:00 2001 From: Einar Forselv Date: Sun, 29 Jul 2018 00:27:04 +0200 Subject: [PATCH 01/22] Resource test --- tests/test_resources.py | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 tests/test_resources.py diff --git a/tests/test_resources.py b/tests/test_resources.py new file mode 100644 index 0000000..55f525d --- /dev/null +++ b/tests/test_resources.py @@ -0,0 +1,9 @@ +from demosys.test import DemosysTestCase +from demosys import resources + + +class ResourceTestCase(DemosysTestCase): + + def test_stuff(self): + result = resources.shaders.get('vf_pos.glsl', create=True) + resources.shaders.load() From 0f5c1a03f89632e30557a1ae8aec039db3ed220d Mon Sep 17 00:00:00 2001 From: Einar Forselv Date: Sun, 29 Jul 2018 04:29:06 +0200 Subject: [PATCH 02/22] Resources: Use pathlib.Path --- demosys/core/finders.py | 63 ++++++--------------------- demosys/resources/data.py | 16 ++++--- demosys/resources/scenes.py | 7 ++- demosys/resources/shaders.py | 9 +++- demosys/resources/textures.py | 6 ++- demosys/scene/loaders/base.py | 14 +++--- demosys/scene/loaders/gltf.py | 70 ++++++++++++++++-------------- demosys/scene/loaders/wavefront.py | 25 ++++++----- demosys/scene/scene.py | 2 +- 9 files changed, 103 insertions(+), 109 deletions(-) diff --git a/demosys/core/finders.py b/demosys/core/finders.py index e50f4ca..2f6083f 100644 --- a/demosys/core/finders.py +++ b/demosys/core/finders.py @@ -1,8 +1,9 @@ """ Base finders """ -import os from collections import namedtuple +from pathlib import Path + from demosys.conf import settings from demosys.core.exceptions import ImproperlyConfigured @@ -20,60 +21,24 @@ def __init__(self): "This is required when using a FileSystemFinder." ) self.paths = getattr(settings, self.settings_attr) + self._cached_paths = {} - self._cache = {} - - def find(self, path): + def find(self, path: Path): """ - Find a file in the path. - When creating a custom finder, this is the method you override. + Find a file in the path. The file may exist in multiple + paths. The last found file will be returned. :param path: The path to find :return: The absolute path to the file or None if not found """ - return self._find(path) - - def _find(self, path): - """ - Similar to ``find()``, but it caches each result to speed things. + path_found = None - :param path: The path to find - :return: The absolute path to the file or None if not found - """ for entry in self.paths: - abspath = os.path.join(entry, path) - if os.path.exists(abspath): - self.cache(abspath, abspath) - return abspath - else: - self.cache(abspath, abspath, exists=False) - - return None + abspath = entry / path + if abspath.exists(): + path_found = abspath - def find_cached(self, path): - """ - Check if the path is already cached. - This method should normally not be overridden. - - :param path: The path to the file - :return: The absolute path to the file or None - """ - entry = self._cache.get(path) - if entry.exists: - return entry.abspath - - return None - - def cache(self, path, abspath, exists=True): - """ - Caches an entry. - Should ideally not be overridden. - - :param path: The path - :param abspath: The absolute path - :param exists: Did the file exist? (bool) - """ - self._cache[path] = FinderEntry(path=path, abspath=abspath, exists=exists) + return path_found class BaseEffectDirectoriesFinder(BaseFileSystemFinder): @@ -83,7 +48,7 @@ class BaseEffectDirectoriesFinder(BaseFileSystemFinder): def __init__(self): from demosys.effects.registry import effects self.paths = list(effects.get_dirs()) - self._cache = {} - def find(self, path): - return self._find(os.path.join(self.directory, path)) + def find(self, path: Path): + path = Path(self.directory) / Path(path) + return super().find(path) diff --git a/demosys/resources/data.py b/demosys/resources/data.py index 298b402..c8e1a41 100644 --- a/demosys/resources/data.py +++ b/demosys/resources/data.py @@ -1,6 +1,8 @@ """ Registry general data files """ +from pathlib import Path + from demosys.core.exceptions import ImproperlyConfigured from demosys.core.datafiles.finders import get_finders from .base import BaseRegistry @@ -53,25 +55,25 @@ def __init__(self): self.files = [] self.file_map = {} - def get(self, name, create=False, cls=Data) -> Data: + def get(self, path: str, create=False, cls=Data) -> Data: """ Get or create a Data object. - :param name: data file with relative path + :param path: data file with path (pathlib.Path) :param crate: (bool) register a new resource (or fetch existing) :param cls: (Data class) custom data class :return: Data object """ + path = Path(path) + if not hasattr(cls, 'load'): raise ImproperlyConfigured("{} must have a load(path) method".format(cls.__class__)) - key = name.lower() - - data_file = self.file_map.get(key) + data_file = self.file_map.get(path) if not data_file and create: - data_file = cls(name) + data_file = cls(path) self.files.append(data_file) - self.file_map[key] = data_file + self.file_map[path] = data_file return data_file diff --git a/demosys/resources/scenes.py b/demosys/resources/scenes.py index 48d257b..8d859cf 100644 --- a/demosys/resources/scenes.py +++ b/demosys/resources/scenes.py @@ -1,4 +1,7 @@ """Scene Regisry""" +from pathlib import Path +from typing import Union + from demosys.conf import settings from demosys.core.exceptions import ImproperlyConfigured from demosys.core.scenefiles.finders import get_finders @@ -21,7 +24,7 @@ def __init__(self): def count(self): return len(self.scenes) - def get(self, path, create=False, **kwargs) -> Scene: + def get(self, path: Union[str, Path], **kwargs) -> Scene: """ Get or create a scene object. This may return an empty object that will be filled during load @@ -31,6 +34,8 @@ def get(self, path, create=False, **kwargs) -> Scene: :param create: (bool) Create an empty scene object if it doesn't exist :return: Scene object """ + path = Path(path) + # Figure out what scene loader class should be used for loader_name in settings.SCENE_LOADERS: loader_cls = import_string(loader_name) diff --git a/demosys/resources/shaders.py b/demosys/resources/shaders.py index 61695dc..2dbeb2e 100644 --- a/demosys/resources/shaders.py +++ b/demosys/resources/shaders.py @@ -1,4 +1,7 @@ """Shader Registry""" +from pathlib import Path +from typing import Union + import moderngl from demosys.core.exceptions import ImproperlyConfigured from demosys.core.shaderfiles.finders import get_finders @@ -23,16 +26,18 @@ def count(self): """ return len(self.shaders) - def get(self, path, create=False) -> ShaderProgram: + def get(self, path: Union[str, Path], create=False) -> ShaderProgram: """ Get or create a shader object. This may return an empty object that will be filled during load based on the ``create`` parameter. - :param path: Path to the shader + :param path: Path to the shader (pathlib.Path instance) :param create: (bool) Create an empty shader object if it doesn't exist :return: Shader object """ + path = Path(path) + shader = self.shaders.get(path) if create and not shader: shader = ShaderProgram(path) diff --git a/demosys/resources/textures.py b/demosys/resources/textures.py index d5cd8ac..90657a4 100644 --- a/demosys/resources/textures.py +++ b/demosys/resources/textures.py @@ -1,5 +1,7 @@ """Shader Registry""" +from pathlib import Path from typing import Union + from PIL import Image from demosys.core.exceptions import ImproperlyConfigured @@ -25,7 +27,7 @@ def count(self): """ return len(self.textures) - def get(self, path, create=False, cls=Texture2D, **kwargs) -> Union[Texture2D, TextureArray]: + def get(self, path: Union[str, Path], create=False, cls=Texture2D, **kwargs) -> Union[Texture2D, TextureArray]: """ Get or create a texture object. This may return an empty object that will be filled during load @@ -36,6 +38,8 @@ def get(self, path, create=False, cls=Texture2D, **kwargs) -> Union[Texture2D, T :param cls: The texture class to instantiate :return: Texture object """ + path = Path(path) + texture = self.textures.get(path) if create and not texture: texture = cls(path=path, **kwargs) diff --git a/demosys/scene/loaders/base.py b/demosys/scene/loaders/base.py index 6a09290..a8fb9de 100644 --- a/demosys/scene/loaders/base.py +++ b/demosys/scene/loaders/base.py @@ -1,4 +1,8 @@ +from pathlib import Path +from typing import Union + from demosys import context +from demosys.scene import Scene class SceneLoader: @@ -6,11 +10,11 @@ class SceneLoader: # File extensions supported by this loader file_extensions = [] - def __init__(self, file_path, **kwargs): - self.file_path = file_path + def __init__(self, path: Union[str, Path], **kwargs): + self.path = path self.ctx = context.ctx() - def load(self, scene, file=None): + def load(self, scene: Scene, path: Path=None): """ Deferred loading of the scene @@ -20,10 +24,10 @@ def load(self, scene, file=None): raise NotImplementedError() @classmethod - def supports_file(cls, path): + def supports_file(cls, path: Path): """Check if the loader has a supported file extension""" for ext in cls.file_extensions: - if path.endswith(ext): + if path.suffixes[:len(ext)] == ext: return True return False diff --git a/demosys/scene/loaders/gltf.py b/demosys/scene/loaders/gltf.py index f78200c..dc5e163 100644 --- a/demosys/scene/loaders/gltf.py +++ b/demosys/scene/loaders/gltf.py @@ -1,11 +1,12 @@ # Spec: https://github.com/KhronosGroup/glTF/blob/master/specification/2.0/README.md#asset - import base64 import io import json import os import struct from collections import namedtuple +from pathlib import Path +from typing import Union import numpy from PIL import Image @@ -13,8 +14,7 @@ import moderngl from demosys import context from demosys.opengl import VAO, Texture2D -# from demosys.opengl.constants import TYPE_INFO -from demosys.scene import Material, MaterialTexture, Mesh, Node +from demosys.scene import Material, MaterialTexture, Mesh, Node, Scene from pyrr import Matrix44, matrix44, quaternion from .base import SceneLoader @@ -60,10 +60,13 @@ class GLTF2(SceneLoader): """ Loader for GLTF 2.0 files """ - file_extensions = ['.gltf', '.glb'] + file_extensions = [ + ['.gltf'], + ['.glb'], + ] supported_extensions = [] - def __init__(self, file_path): + def __init__(self, path: Union[str, Path]): """ Parse the json file and validate its contents. No actual data loading will happen. @@ -73,7 +76,7 @@ def __init__(self, file_path): - gltf embedded buffers - glb Binary format """ - super().__init__(file_path) + super().__init__(path) self.scenes = [] self.nodes = [] self.meshes = [] @@ -83,29 +86,31 @@ def __init__(self, file_path): self.textures = [] self.meta = None - self.file = file_path - self.path = "" + self.path = path self.scene = None - def load(self, scene, file=None): + def load(self, scene: Scene, path: Path=None): """ Deferred loading of the scene :param scene: The scene object :param file: Resolved path if changed by finder """ - print("Loading", self.file) + print("Loading", self.path) self.scene = scene - if file: - self.file = file - self.path = os.path.dirname(self.file) + + if path: + self.path = path + + self.path = Path(self.path) + print(self.path) # Load gltf json file - if self.file.endswith('.gltf'): + if self.path.suffix == '.gltf': self.load_gltf() # Load binary gltf file - if self.file.endswith('.glb'): + if self.path.suffix == '.glb': self.load_glb() self.meta.check_version() @@ -121,20 +126,20 @@ def load(self, scene, file=None): def load_gltf(self): """Loads a gltf json file""" - with open(self.file) as fd: - self.meta = GLTFMeta(self.file, json.load(fd)) + with open(self.path) as fd: + self.meta = GLTFMeta(self.path, json.load(fd)) def load_glb(self): """Loads a binary gltf file""" - with open(self.file, 'rb') as fd: + with open(self.path, 'rb') as fd: # Check header magic = fd.read(4) if magic != GLTF_MAGIC_HEADER: - raise ValueError("{} has incorrect header {} != {}".format(self.file, magic, GLTF_MAGIC_HEADER)) + raise ValueError("{} has incorrect header {} != {}".format(self.path, magic, GLTF_MAGIC_HEADER)) version = struct.unpack(' Date: Sun, 29 Jul 2018 04:53:15 +0200 Subject: [PATCH 03/22] Bug: load_shader fallback path --- demosys/resources/shaders.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demosys/resources/shaders.py b/demosys/resources/shaders.py index 2dbeb2e..a40b62a 100644 --- a/demosys/resources/shaders.py +++ b/demosys/resources/shaders.py @@ -65,7 +65,7 @@ def load_shader(self, shader, name=None, reload=False): :param reload: (bool) Are we reloading the shader? """ if name is None: - name = shader.path + name = Path(shader.path) finders = list(get_finders()) From 7c2f1e8c6e9482642ad3a94ba6ed1b6afd320ddb Mon Sep 17 00:00:00 2001 From: Einar Forselv Date: Sun, 29 Jul 2018 05:50:40 +0200 Subject: [PATCH 04/22] Load textures in their original format We should not auto convert all images to RGBA. Images should be loaded as is. This also speeds up loading --- demosys/opengl/texture/array.py | 7 ++++--- demosys/opengl/texture/base.py | 10 ++++++++++ demosys/opengl/texture/texture.py | 8 +++++--- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/demosys/opengl/texture/array.py b/demosys/opengl/texture/array.py index 1acb597..2c22368 100644 --- a/demosys/opengl/texture/array.py +++ b/demosys/opengl/texture/array.py @@ -2,7 +2,7 @@ from demosys import context -from .base import BaseTexture +from .base import BaseTexture, image_data class TextureArray(BaseTexture): @@ -66,11 +66,12 @@ def set_image(self, image, flip=True): image = image.transpose(Image.FLIP_TOP_BOTTOM) width, height, depth = image.size[0], image.size[1] // self.layers, self.layers + components, data = image_data(image) self.mglo = self.ctx.texture_array( (width, height, depth), - 4, - image.convert("RGBA").tobytes(), + components, + data, ) if self.mipmap: diff --git a/demosys/opengl/texture/base.py b/demosys/opengl/texture/base.py index 03dfed6..0f062a8 100644 --- a/demosys/opengl/texture/base.py +++ b/demosys/opengl/texture/base.py @@ -4,6 +4,16 @@ from demosys import context +def image_data(image): + """Get components and bytes for an image""" + # NOTE: We might want to check the actual image.mode + # and convert to an acceptable format. + # At the moment we load the data as is. + data = image.tobytes() + components = len(data) // (image.size[0] * image.size[1]) + return components, data + + class BaseTexture: """ Wraps the basic functionality of the ModernGL methods diff --git a/demosys/opengl/texture/texture.py b/demosys/opengl/texture/texture.py index 2526121..c0795aa 100644 --- a/demosys/opengl/texture/texture.py +++ b/demosys/opengl/texture/texture.py @@ -3,7 +3,7 @@ import moderngl from demosys import context -from .base import BaseTexture +from .base import BaseTexture, image_data class Texture2D(BaseTexture): @@ -91,10 +91,12 @@ def set_image(self, image, flip=True): if flip: image = image.transpose(Image.FLIP_TOP_BOTTOM) + components, data = image_data(image) + self.mglo = self.ctx.texture( image.size, - 4, - image.convert("RGBA").tobytes(), + components, + data, ) if self.mipmap: From 1bdee511c2aca212f737cabf04147380d12a7377 Mon Sep 17 00:00:00 2001 From: Einar Forselv Date: Sun, 29 Jul 2018 06:05:49 +0200 Subject: [PATCH 05/22] Defer getting context in Texture and Shader --- demosys/opengl/shader.py | 5 ++++- demosys/opengl/texture/base.py | 11 +++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/demosys/opengl/shader.py b/demosys/opengl/shader.py index da2a2fa..135b866 100644 --- a/demosys/opengl/shader.py +++ b/demosys/opengl/shader.py @@ -20,7 +20,6 @@ def __init__(self, path=None, name=None): :param path: Full file path to the shader :param name: Name of the shader (debug purposes) """ - self.ctx = context.ctx() if not path and not name: raise ShaderError("Shader must have a path or a name") @@ -47,6 +46,10 @@ def __init__(self, path=None, name=None): # Unique key for VAO instances containing shader id and attributes self.vao_key = None + @property + def ctx(self): + return context.ctx() + def __getitem__(self, key) -> Union[moderngl.Uniform, moderngl.UniformBlock, moderngl.Subroutine, moderngl.Attribute, moderngl.Varying]: return self.mglo[key] diff --git a/demosys/opengl/texture/base.py b/demosys/opengl/texture/base.py index 0f062a8..9b0b4a5 100644 --- a/demosys/opengl/texture/base.py +++ b/demosys/opengl/texture/base.py @@ -20,7 +20,11 @@ class BaseTexture: """ def __init__(self): self.mglo = None # Type: Union[moderngl.Texture, moderngl.TextureArray] - self._ctx = context.ctx() + + @property + def ctx(self) -> moderngl.Context: + """ModernGL context""" + return context.ctx() def use(self, location=0): """ @@ -75,11 +79,6 @@ def release(self): """Release/free the ModernGL object""" self.mglo.release() - @property - def ctx(self) -> moderngl.Context: - """ModernGL context""" - return self._ctx - @property def size(self) -> Tuple: """The size of the texture""" From 919bfed1d21a2400e42e0eb4e69a813ed65b63cf Mon Sep 17 00:00:00 2001 From: Einar Forselv Date: Sun, 29 Jul 2018 06:09:50 +0200 Subject: [PATCH 06/22] Document ctx property --- demosys/opengl/shader.py | 3 ++- docs/source/reference/shaderprogram.rst | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/demosys/opengl/shader.py b/demosys/opengl/shader.py index 135b866..00e8ed0 100644 --- a/demosys/opengl/shader.py +++ b/demosys/opengl/shader.py @@ -47,7 +47,8 @@ def __init__(self, path=None, name=None): self.vao_key = None @property - def ctx(self): + def ctx(self) -> moderngl.Context: + """The moderngl context""" return context.ctx() def __getitem__(self, key) -> Union[moderngl.Uniform, moderngl.UniformBlock, moderngl.Subroutine, diff --git a/docs/source/reference/shaderprogram.rst b/docs/source/reference/shaderprogram.rst index 9964fcb..da271ce 100644 --- a/docs/source/reference/shaderprogram.rst +++ b/docs/source/reference/shaderprogram.rst @@ -27,3 +27,4 @@ Attributes .. autoattribute:: ShaderProgram.geometry_vertices .. autoattribute:: ShaderProgram.mglo .. autoattribute:: ShaderProgram.glo +.. autoattribute:: ShaderProgram.ctx From 1bb2a86aa7d495aeaae9c7ec6036581608abb580 Mon Sep 17 00:00:00 2001 From: Einar Forselv Date: Thu, 2 Aug 2018 14:02:41 +0200 Subject: [PATCH 07/22] Clena up sampler in mincraft example --- examples/minecraft/effect.py | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/examples/minecraft/effect.py b/examples/minecraft/effect.py index c78505c..9f3c5e2 100644 --- a/examples/minecraft/effect.py +++ b/examples/minecraft/effect.py @@ -16,28 +16,23 @@ def __init__(self): ) self.fbo = FBO.create((self.window_width, self.window_height), depth=True) - self.sampler = self.ctx.sampler() - self.sampler.filter = moderngl.NEAREST, moderngl.NEAREST + self.sampler = self.ctx.sampler( + filter=(moderngl.NEAREST_MIPMAP_NEAREST, moderngl.NEAREST), + anisotropy=16.0, + max_lod=4.0, + ) @effect.bind_target def draw(self, time, frametime, target): self.ctx.enable(moderngl.DEPTH_TEST) self.ctx.disable(moderngl.CULL_FACE) self.sys_camera.velocity = 10.0 + self.sampler.use(location=0) # m_view = self.create_transformation(translation=(0.0, -5.0, -8.0)) m_proj = self.create_projection(75, near=0.1, far=300.0) with self.fbo: - - if math.fmod(time, 2.0) < 1.0: - self.sampler.anisotropy = 0.0 - # self.sampler.filter = moderngl.NEAREST, moderngl.NEAREST - else: - self.sampler.anisotropy = 16.0 - # self.sampler.filter = moderngl.LINEAR, moderngl.LINEAR - - self.sampler.use(location=0) self.scene.draw( projection_matrix=m_proj, camera_matrix=self.sys_camera.view_matrix, From 3b2269c1341e868108822f534318f7cf39b769fa Mon Sep 17 00:00:00 2001 From: Einar Forselv Date: Thu, 2 Aug 2018 14:32:14 +0200 Subject: [PATCH 08/22] GLTF samplers --- demosys/scene/loaders/gltf.py | 13 ++++++++++--- demosys/scene/scene.py | 8 +++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/demosys/scene/loaders/gltf.py b/demosys/scene/loaders/gltf.py index dc5e163..262ae34 100644 --- a/demosys/scene/loaders/gltf.py +++ b/demosys/scene/loaders/gltf.py @@ -21,6 +21,11 @@ GLTF_MAGIC_HEADER = b'glTF' +# Texture wrap values +REPEAT = 10497 +CLAMP_TO_EDGE = 33071 +MIRRORED_REPEAT = 33648 + # numpy dtype mapping NP_COMPONENT_DTYPE = { 5121: numpy.uint8, # GL_UNSIGNED_BYTE @@ -166,12 +171,14 @@ def load_images(self): def load_samplers(self): for sampler in self.meta.samplers: + # NOTE: Texture wrap will be changed in moderngl 6.x + # We currently only have repeat values self.samplers.append( self.ctx.sampler( filter=(sampler.minFilter, sampler.magFilter), - # self.wrapS = data.get('wrapS') - # self.wrapT = data.get('wrapT') - anisotropy=16, + repeat_x=sampler.wrapS in [REPEAT, MIRRORED_REPEAT], + repeat_y=sampler.wrapT in [REPEAT, MIRRORED_REPEAT], + anisotropy=16.0, ) ) diff --git a/demosys/scene/scene.py b/demosys/scene/scene.py index 3d337d0..a36d650 100644 --- a/demosys/scene/scene.py +++ b/demosys/scene/scene.py @@ -1,7 +1,7 @@ """ Wrapper for a loaded scene with properties. """ -from demosys import geometry +from demosys import context, geometry from demosys.resources import shaders from pyrr import matrix44, vector3 @@ -35,6 +35,10 @@ def __init__(self, name, loader=None, mesh_shaders=None, **kwargs): self._view_matrix = matrix44.create_identity() + @property + def ctx(self): + return context.ctx() + @property def view_matrix(self): return self._view_matrix @@ -63,6 +67,8 @@ def draw(self, projection_matrix=None, camera_matrix=None, time=0): time=time, ) + self.ctx.clear_samplers(0, 4) + def draw_bbox(self, projection_matrix=None, camera_matrix=None, all=True): """Draw scene and mesh bounding boxes""" projection_matrix = projection_matrix.astype('f4').tobytes() From d1b9bbb1b26d073511c5dd19217c2c95b2038965 Mon Sep 17 00:00:00 2001 From: Einar Forselv Date: Thu, 2 Aug 2018 14:33:17 +0200 Subject: [PATCH 09/22] pep8 --- examples/minecraft/effect.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/minecraft/effect.py b/examples/minecraft/effect.py index 9f3c5e2..539c015 100644 --- a/examples/minecraft/effect.py +++ b/examples/minecraft/effect.py @@ -1,8 +1,8 @@ -import math import moderngl + from demosys.effects import effect -from demosys.scene import MeshShader from demosys.opengl import FBO +from demosys.scene import MeshShader class MinecraftEffect(effect.Effect): From e687debeae7f2c2e2f970e9369c0856b0bd29268 Mon Sep 17 00:00:00 2001 From: Einar Forselv Date: Thu, 2 Aug 2018 20:19:23 +0200 Subject: [PATCH 10/22] Call post_load from effect manager --- demosys/effects/managers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/demosys/effects/managers.py b/demosys/effects/managers.py index a5d81db..6223fb4 100644 --- a/demosys/effects/managers.py +++ b/demosys/effects/managers.py @@ -86,6 +86,7 @@ def pre_load(self): return True def post_load(self): + self.active_effect.post_load() return True def draw(self, time, frametime, target): From 9d2c29666996486d55dbfef06f43e4dfad51f5fb Mon Sep 17 00:00:00 2001 From: Einar Forselv Date: Thu, 2 Aug 2018 20:19:46 +0200 Subject: [PATCH 11/22] Remove all resource callbacks --- demosys/resources/__init__.py | 47 ++++------------------------------- 1 file changed, 5 insertions(+), 42 deletions(-) diff --git a/demosys/resources/__init__.py b/demosys/resources/__init__.py index dce69e4..de5c2b6 100644 --- a/demosys/resources/__init__.py +++ b/demosys/resources/__init__.py @@ -20,49 +20,12 @@ ] -class States: - on_loaded_funcs = [] - on_load_funcs = [] - loaded = False - - @classmethod - def sort_callbacks(cls): - cls.on_load_funcs = sorted(cls.on_load_funcs, key=lambda x: x[0]) - cls.on_loaded_funcs = sorted(cls.on_loaded_funcs, key=lambda x: x[0]) - - def load(): - States.sort_callbacks() - - for func in reversed(States.on_load_funcs): - func[1]() - - scenes.load() - shaders.load() - textures.load() - tracks.load() - data.load() - - States.loaded = True - for func in reversed(States.on_loaded_funcs): - func[1]() + scenes.load_pool() + shaders.load_pool() + textures.load_pool() + data.load_pool() def count(): - return shaders.count + textures.count - - -def loading_complete(): - return States.loaded - - -def on_load(func, priority=0): - States.on_load_funcs.append((priority, func)) - - -def on_loaded(func, priority=0): - if loading_complete(): - func() - return - - States.on_loaded_funcs.append((priority, func)) + return scenes.count + shaders.count + textures.count + data.count From 0ae84033836f6ef6231e69181d6d37f193d0bbc5 Mon Sep 17 00:00:00 2001 From: Einar Forselv Date: Thu, 2 Aug 2018 20:21:43 +0200 Subject: [PATCH 12/22] Remove all callbacks from effect --- demosys/effects/effect.py | 28 +--------------------------- 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/demosys/effects/effect.py b/demosys/effects/effect.py index 13d5e74..14e36bf 100644 --- a/demosys/effects/effect.py +++ b/demosys/effects/effect.py @@ -76,13 +76,9 @@ class Effect: _ctx = None # type: moderngl.Context _sys_camera = None # type: camera.SystemCamera - def __init__(self, *args, **kwargs): - self.on_resouces_loaded(self.post_load) - def post_load(self): """ - Called when all resources are loaded before effects start running. - This assumes you have called Effect.__init__() + Called when all effects are initialized before effects start running. """ pass @@ -215,28 +211,6 @@ def get_data(self, path, local=False, **kwargs) -> Data: """ return resources.data.get(path, create=True, **kwargs) - # Register callbacks - - def on_resouces_loaded(self, func): - """Register callback function when all resources are loaded""" - resources.on_loaded(func) - - def on_shaders_loaded(self, func): - """Register callback function when shaders are loaded""" - resources.shaders.on_loaded(func) - - def on_textures_loaded(self, func): - """Register callback function when textures are loaded""" - resources.textures.on_loaded(func) - - def on_scenes_loaded(self, func): - """Register callback function when scenes are loaded""" - resources.scenes.on_loaded(func) - - def on_data_loaded(self, func): - """Register callback function when data files are loaded""" - resources.data.on_loaded(func) - # Utility methods for matrices def create_projection(self, fov=75.0, near=1.0, far=100.0, ratio=None): From e00e6cc480a3f2b28befd87629df72979e3e0d98 Mon Sep 17 00:00:00 2001 From: Einar Forselv Date: Thu, 2 Aug 2018 20:22:52 +0200 Subject: [PATCH 13/22] Add scene and texture data to test resources --- tests/resources/data/data.bin | 1 + tests/resources/data/data.txt | 1 + tests/resources/scenes/BoxTextured/README.md | 8 + .../BoxTextured/glTF-Binary/BoxTextured.glb | Bin 0 -> 25756 bytes .../glTF-Embedded/BoxTextured.gltf | 181 ++++++++++++++++ .../BoxTextured.gltf | 197 ++++++++++++++++++ .../BoxTextured0.bin | Bin 0 -> 840 bytes .../CesiumLogoFlat.png | Bin 0 -> 23516 bytes .../scenes/BoxTextured/glTF/BoxTextured.gltf | 181 ++++++++++++++++ .../scenes/BoxTextured/glTF/BoxTextured0.bin | Bin 0 -> 840 bytes .../BoxTextured/glTF/CesiumLogoFlat.png | Bin 0 -> 23516 bytes tests/resources/scenes/cube.obj | 33 +++ tests/resources/scenes/cube.obj.bin | Bin 0 -> 115 bytes tests/resources/scenes/cube.obj.json | 13 ++ tests/resources/textures/wood.jpg | Bin 0 -> 89006 bytes tests/settings.py | 17 +- 16 files changed, 627 insertions(+), 5 deletions(-) create mode 100644 tests/resources/data/data.bin create mode 100644 tests/resources/data/data.txt create mode 100644 tests/resources/scenes/BoxTextured/README.md create mode 100644 tests/resources/scenes/BoxTextured/glTF-Binary/BoxTextured.glb create mode 100644 tests/resources/scenes/BoxTextured/glTF-Embedded/BoxTextured.gltf create mode 100644 tests/resources/scenes/BoxTextured/glTF-pbrSpecularGlossiness/BoxTextured.gltf create mode 100644 tests/resources/scenes/BoxTextured/glTF-pbrSpecularGlossiness/BoxTextured0.bin create mode 100644 tests/resources/scenes/BoxTextured/glTF-pbrSpecularGlossiness/CesiumLogoFlat.png create mode 100644 tests/resources/scenes/BoxTextured/glTF/BoxTextured.gltf create mode 100644 tests/resources/scenes/BoxTextured/glTF/BoxTextured0.bin create mode 100644 tests/resources/scenes/BoxTextured/glTF/CesiumLogoFlat.png create mode 100644 tests/resources/scenes/cube.obj create mode 100644 tests/resources/scenes/cube.obj.bin create mode 100644 tests/resources/scenes/cube.obj.json create mode 100644 tests/resources/textures/wood.jpg diff --git a/tests/resources/data/data.bin b/tests/resources/data/data.bin new file mode 100644 index 0000000..82090ee --- /dev/null +++ b/tests/resources/data/data.bin @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/resources/data/data.txt b/tests/resources/data/data.txt new file mode 100644 index 0000000..274c005 --- /dev/null +++ b/tests/resources/data/data.txt @@ -0,0 +1 @@ +1234 \ No newline at end of file diff --git a/tests/resources/scenes/BoxTextured/README.md b/tests/resources/scenes/BoxTextured/README.md new file mode 100644 index 0000000..2e0b78c --- /dev/null +++ b/tests/resources/scenes/BoxTextured/README.md @@ -0,0 +1,8 @@ +# Box Textured +## Screenshot + +![screenshot](screenshot/screenshot.png) + +## License Information + +Donated by Cesium for glTF testing. Please follow the [Cesium Trademark Terms and Conditions](https://github.com/AnalyticalGraphicsInc/cesium/wiki/CesiumTrademark.pdf). \ No newline at end of file diff --git a/tests/resources/scenes/BoxTextured/glTF-Binary/BoxTextured.glb b/tests/resources/scenes/BoxTextured/glTF-Binary/BoxTextured.glb new file mode 100644 index 0000000000000000000000000000000000000000..5dae1587ec2849be9ee7956eebb9cb842200755c GIT binary patch literal 25756 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%0AI48PRRm5ilOc~OUhZQAgWP+|&KRch#zjgHb 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 YCHAOZ@c;k-07*qoM6N<$f&c&j0H0v?$N&HU literal 0 HcmV?d00001 diff --git a/tests/resources/scenes/BoxTextured/glTF-Embedded/BoxTextured.gltf b/tests/resources/scenes/BoxTextured/glTF-Embedded/BoxTextured.gltf new file mode 100644 index 0000000..4a6ab9c --- /dev/null +++ b/tests/resources/scenes/BoxTextured/glTF-Embedded/BoxTextured.gltf @@ -0,0 +1,181 @@ +{ + "asset": { + "generator": "COLLADA2GLTF", + "version": "2.0" + }, + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ], + "nodes": [ + { + "children": [ + 1 + ], + "matrix": [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -1.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ] + }, + { + "mesh": 0 + } + ], + "meshes": [ + { + "primitives": [ + { + "attributes": { + "NORMAL": 1, + "POSITION": 2, + "TEXCOORD_0": 3 + }, + "indices": 0, + "mode": 4, + "material": 0 + } + ], + "name": "Mesh" + } + ], + "accessors": [ + { + "bufferView": 0, + "byteOffset": 0, + "componentType": 5123, + "count": 36, + "max": [ + 23 + ], + "min": [ + 0 + ], + "type": "SCALAR" + }, + { + "bufferView": 1, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1.0, + 1.0, + 1.0 + ], + "min": [ + -1.0, + -1.0, + -1.0 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 288, + "componentType": 5126, + "count": 24, + "max": [ + 0.5, + 0.5, + 0.5 + ], + "min": [ + -0.5, + -0.5, + -0.5 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 6.0, + 1.0 + ], + "min": [ + 0.0, + 0.0 + ], + "type": "VEC2" + } + ], + "materials": [ + { + "pbrMetallicRoughness": { + "baseColorTexture": { + "index": 0 + }, + "metallicFactor": 0.0 + }, + "name": "Texture" + } + ], + "textures": [ + { + "sampler": 0, + "source": 0 + } + ], + "images": [ + { + "uri": "data:image/png;base64,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" + } + ], + "samplers": [ + { + "magFilter": 9729, + "minFilter": 9986, + "wrapS": 10497, + "wrapT": 10497 + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteOffset": 768, + "byteLength": 72, + "target": 34963 + }, + { + "buffer": 0, + "byteOffset": 0, + "byteLength": 576, + "byteStride": 12, + "target": 34962 + }, + { + "buffer": 0, + "byteOffset": 576, + "byteLength": 192, + "byteStride": 8, + "target": 34962 + } + ], + "buffers": [ + { + "byteLength": 840, + "uri": "data:application/octet-stream;base64,AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAACAPwAAAAAAAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgD8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAAAAAAAAgL8AAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAACAvwAAAAAAAAAAAAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAAAAAAAAAAIC/AAAAvwAAAL8AAAA/AAAAPwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAPwAAAL8AAAA/AAAAPwAAAD8AAAC/AAAAPwAAAL8AAAC/AAAAvwAAAD8AAAA/AAAAPwAAAD8AAAA/AAAAvwAAAD8AAAC/AAAAPwAAAD8AAAC/AAAAPwAAAL8AAAA/AAAAvwAAAL8AAAA/AAAAPwAAAL8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAL8AAAA/AAAAvwAAAD8AAAA/AAAAvwAAAL8AAAC/AAAAvwAAAD8AAAC/AAAAvwAAAL8AAAC/AAAAvwAAAD8AAAC/AAAAPwAAAL8AAAC/AAAAPwAAAD8AAAC/AADAQAAAAAAAAKBAAAAAAAAAwED+/38/AACgQP7/fz8AAIBAAAAAAAAAoEAAAAAAAACAQAAAgD8AAKBAAACAPwAAAEAAAAAAAACAPwAAAAAAAABAAACAPwAAgD8AAIA/AABAQAAAAAAAAIBAAAAAAAAAQEAAAIA/AACAQAAAgD8AAEBAAAAAAAAAAEAAAAAAAABAQAAAgD8AAABAAACAPwAAAAAAAAAAAAAAAP7/fz8AAIA/AAAAAAAAgD/+/38/AAABAAIAAwACAAEABAAFAAYABwAGAAUACAAJAAoACwAKAAkADAANAA4ADwAOAA0AEAARABIAEwASABEAFAAVABYAFwAWABUA" + } + ] +} diff --git a/tests/resources/scenes/BoxTextured/glTF-pbrSpecularGlossiness/BoxTextured.gltf b/tests/resources/scenes/BoxTextured/glTF-pbrSpecularGlossiness/BoxTextured.gltf new file mode 100644 index 0000000..b286239 --- /dev/null +++ b/tests/resources/scenes/BoxTextured/glTF-pbrSpecularGlossiness/BoxTextured.gltf @@ -0,0 +1,197 @@ +{ + "asset": { + "generator": "COLLADA2GLTF", + "version": "2.0" + }, + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ], + "nodes": [ + { + "children": [ + 1 + ], + "matrix": [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -1.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ] + }, + { + "mesh": 0 + } + ], + "meshes": [ + { + "primitives": [ + { + "attributes": { + "NORMAL": 1, + "POSITION": 2, + "TEXCOORD_0": 3 + }, + "indices": 0, + "mode": 4, + "material": 0 + } + ], + "name": "Mesh" + } + ], + "accessors": [ + { + "bufferView": 0, + "byteOffset": 0, + "componentType": 5123, + "count": 36, + "max": [ + 23 + ], + "min": [ + 0 + ], + "type": "SCALAR" + }, + { + "bufferView": 1, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1.0, + 1.0, + 1.0 + ], + "min": [ + -1.0, + -1.0, + -1.0 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 288, + "componentType": 5126, + "count": 24, + "max": [ + 0.5, + 0.5, + 0.5 + ], + "min": [ + -0.5, + -0.5, + -0.5 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 6.0, + 1.0 + ], + "min": [ + 0.0, + 0.0 + ], + "type": "VEC2" + } + ], + "materials": [ + { + "pbrMetallicRoughness": { + "baseColorTexture": { + "index": 0 + }, + "metallicFactor": 0.0 + }, + "extensions": { + "KHR_materials_pbrSpecularGlossiness": { + "diffuseTexture": { + "index": 0 + }, + "specularFactor": [ + 0.20000000298023225, + 0.20000000298023225, + 0.20000000298023225 + ], + "glossinessFactor": 1.0 + } + }, + "name": "Texture" + } + ], + "textures": [ + { + "sampler": 0, + "source": 0 + } + ], + "images": [ + { + "uri": "CesiumLogoFlat.png" + } + ], + "samplers": [ + { + "magFilter": 9729, + "minFilter": 9986, + "wrapS": 10497, + "wrapT": 10497 + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteOffset": 768, + "byteLength": 72, + "target": 34963 + }, + { + "buffer": 0, + "byteOffset": 0, + "byteLength": 576, + "byteStride": 12, + "target": 34962 + }, + { + "buffer": 0, + "byteOffset": 576, + "byteLength": 192, + "byteStride": 8, + "target": 34962 + } + ], + "buffers": [ + { + "byteLength": 840, + "uri": "BoxTextured0.bin" + } + ], + "extensionsUsed": [ + "KHR_materials_pbrSpecularGlossiness" + ] +} diff --git a/tests/resources/scenes/BoxTextured/glTF-pbrSpecularGlossiness/BoxTextured0.bin b/tests/resources/scenes/BoxTextured/glTF-pbrSpecularGlossiness/BoxTextured0.bin new file mode 100644 index 0000000000000000000000000000000000000000..d2a73551f9456732c7ca85b9d70895f5d9ab8171 GIT binary patch literal 840 zcma)4TMmLS5FAugR8)K(r@fgRg`3F9)Sc2X4N+i|$-K6U9|D@%NdZH8sMCdXhgs?; z>8CE)+Yvq1hwmphbb0bSz9n3Qv{?B+?(fNy1()2HW=AbfwKB4_dS!i9PnJ%1er4>H zi~S!ZIHJM{XG4VxuDIcDxZ(qtxm=$B literal 0 HcmV?d00001 diff --git a/tests/resources/scenes/BoxTextured/glTF-pbrSpecularGlossiness/CesiumLogoFlat.png b/tests/resources/scenes/BoxTextured/glTF-pbrSpecularGlossiness/CesiumLogoFlat.png new file mode 100644 index 0000000000000000000000000000000000000000..8159c4c4afd64aa84c363b66f09e75881ff890eb GIT binary patch literal 23516 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 V_9gbHUhx0`002ovPDHLkV1k&E=!gIS literal 0 HcmV?d00001 diff --git a/tests/resources/scenes/BoxTextured/glTF/BoxTextured.gltf b/tests/resources/scenes/BoxTextured/glTF/BoxTextured.gltf new file mode 100644 index 0000000..eff658f --- /dev/null +++ b/tests/resources/scenes/BoxTextured/glTF/BoxTextured.gltf @@ -0,0 +1,181 @@ +{ + "asset": { + "generator": "COLLADA2GLTF", + "version": "2.0" + }, + "scene": 0, + "scenes": [ + { + "nodes": [ + 0 + ] + } + ], + "nodes": [ + { + "children": [ + 1 + ], + "matrix": [ + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + -1.0, + 0.0, + 0.0, + 1.0, + 0.0, + 0.0, + 0.0, + 0.0, + 0.0, + 1.0 + ] + }, + { + "mesh": 0 + } + ], + "meshes": [ + { + "primitives": [ + { + "attributes": { + "NORMAL": 1, + "POSITION": 2, + "TEXCOORD_0": 3 + }, + "indices": 0, + "mode": 4, + "material": 0 + } + ], + "name": "Mesh" + } + ], + "accessors": [ + { + "bufferView": 0, + "byteOffset": 0, + "componentType": 5123, + "count": 36, + "max": [ + 23 + ], + "min": [ + 0 + ], + "type": "SCALAR" + }, + { + "bufferView": 1, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 1.0, + 1.0, + 1.0 + ], + "min": [ + -1.0, + -1.0, + -1.0 + ], + "type": "VEC3" + }, + { + "bufferView": 1, + "byteOffset": 288, + "componentType": 5126, + "count": 24, + "max": [ + 0.5, + 0.5, + 0.5 + ], + "min": [ + -0.5, + -0.5, + -0.5 + ], + "type": "VEC3" + }, + { + "bufferView": 2, + "byteOffset": 0, + "componentType": 5126, + "count": 24, + "max": [ + 6.0, + 1.0 + ], + "min": [ + 0.0, + 0.0 + ], + "type": "VEC2" + } + ], + "materials": [ + { + "pbrMetallicRoughness": { + "baseColorTexture": { + "index": 0 + }, + "metallicFactor": 0.0 + }, + "name": "Texture" + } + ], + "textures": [ + { + "sampler": 0, + "source": 0 + } + ], + "images": [ + { + "uri": "CesiumLogoFlat.png" + } + ], + "samplers": [ + { + "magFilter": 9729, + "minFilter": 9986, + "wrapS": 10497, + "wrapT": 10497 + } + ], + "bufferViews": [ + { + "buffer": 0, + "byteOffset": 768, + "byteLength": 72, + "target": 34963 + }, + { + "buffer": 0, + "byteOffset": 0, + "byteLength": 576, + "byteStride": 12, + "target": 34962 + }, + { + "buffer": 0, + "byteOffset": 576, + "byteLength": 192, + "byteStride": 8, + "target": 34962 + } + ], + "buffers": [ + { + "byteLength": 840, + "uri": "BoxTextured0.bin" + } + ] +} diff --git a/tests/resources/scenes/BoxTextured/glTF/BoxTextured0.bin b/tests/resources/scenes/BoxTextured/glTF/BoxTextured0.bin new file mode 100644 index 0000000000000000000000000000000000000000..d2a73551f9456732c7ca85b9d70895f5d9ab8171 GIT binary patch literal 840 zcma)4TMmLS5FAugR8)K(r@fgRg`3F9)Sc2X4N+i|$-K6U9|D@%NdZH8sMCdXhgs?; z>8CE)+Yvq1hwmphbb0bSz9n3Qv{?B+?(fNy1()2HW=AbfwKB4_dS!i9PnJ%1er4>H zi~S!ZIHJM{XG4VxuDIcDxZ(qtxm=$B literal 0 HcmV?d00001 diff --git a/tests/resources/scenes/BoxTextured/glTF/CesiumLogoFlat.png b/tests/resources/scenes/BoxTextured/glTF/CesiumLogoFlat.png new file mode 100644 index 0000000000000000000000000000000000000000..8159c4c4afd64aa84c363b66f09e75881ff890eb GIT binary patch literal 23516 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 V_9gbHUhx0`002ovPDHLkV1k&E=!gIS literal 0 HcmV?d00001 diff --git a/tests/resources/scenes/cube.obj b/tests/resources/scenes/cube.obj new file mode 100644 index 0000000..c4d834c --- /dev/null +++ b/tests/resources/scenes/cube.obj @@ -0,0 +1,33 @@ +# cube.obj +# + +g cube + +v 0.0 0.0 0.0 +v 0.0 0.0 1.0 +v 0.0 1.0 0.0 +v 0.0 1.0 1.0 +v 1.0 0.0 0.0 +v 1.0 0.0 1.0 +v 1.0 1.0 0.0 +v 1.0 1.0 1.0 + +vn 0.0 0.0 1.0 +vn 0.0 0.0 -1.0 +vn 0.0 1.0 0.0 +vn 0.0 -1.0 0.0 +vn 1.0 0.0 0.0 +vn -1.0 0.0 0.0 + +f 1//2 7//2 5//2 +f 1//2 3//2 7//2 +f 1//6 4//6 3//6 +f 1//6 2//6 4//6 +f 3//3 8//3 7//3 +f 3//3 4//3 8//3 +f 5//5 7//5 8//5 +f 5//5 8//5 6//5 +f 1//4 5//4 6//4 +f 1//4 6//4 2//4 +f 2//1 6//1 8//1 +f 2//1 8//1 4//1 diff --git a/tests/resources/scenes/cube.obj.bin b/tests/resources/scenes/cube.obj.bin new file mode 100644 index 0000000000000000000000000000000000000000..c2bee24a26e9ab7ca94568558b12cee7474e3270 GIT binary patch literal 115 zcmV-(0F3`1iwFqx0%KbO|6_GxWiD@GYA#}FZUAFofPsen3|Ik3yuluVv58|-kINh| zZI9o4Li*u+s2*(Mq?iLY3y1mWZpOxjyTu;6I6l4D*tpCg#XMYYC&wII>WK|&Y;jJB VIk?mhwy`unwI|LywU?9hMj0oW8cl*~d3xKsvq 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

_77IX$>FV&c*4p;k!#V8<<< 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 J$?j;6|Jh~M!Cn9W literal 0 HcmV?d00001 diff --git a/tests/settings.py b/tests/settings.py index acb7f39..df44622 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -45,16 +45,23 @@ os.path.join(PROJECT_DIR, 'resources/shaders'), ) -SHADER_FINDERS = ( - 'demosys.core.shaderfiles.finders.FileSystemFinder', - 'demosys.core.shaderfiles.finders.EffectDirectoriesFinder', +SCENE_DIRS = ( + os.path.join(PROJECT_DIR, 'resources/scenes'), ) TEXTURE_DIRS = ( - os.path.join(PROJECT_DIR, 'resource/textures'), + os.path.join(PROJECT_DIR, 'resources/textures'), +) + +DATA_DIRS = ( + os.path.join(PROJECT_DIR, 'resources/data'), +) + +SHADER_FINDERS = ( + 'demosys.core.shaderfiles.finders.FileSystemFinder', + 'demosys.core.shaderfiles.finders.EffectDirectoriesFinder', ) -# Finder classes TEXTURE_FINDERS = ( 'demosys.core.texturefiles.finders.FileSystemFinder', 'demosys.core.texturefiles.finders.EffectDirectoriesFinder' From 4480fe735e36a0a9f69a7b0ddde967aa31f143ee Mon Sep 17 00:00:00 2001 From: Einar Forselv Date: Thu, 2 Aug 2018 20:24:04 +0200 Subject: [PATCH 14/22] New resource pool base --- demosys/resources/base.py | 55 ++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/demosys/resources/base.py b/demosys/resources/base.py index ffc2101..b4f0d35 100644 --- a/demosys/resources/base.py +++ b/demosys/resources/base.py @@ -10,12 +10,53 @@ class BaseRegistry: """ def __init__(self): - self._on_loaded_funcs = [] + self.file_map = {} + self.file_meta = {} - def on_loaded(self, func): - """Register functions to call when all data is loaded""" - self._on_loaded_funcs.append(func) + @property + def count(self): + return len(self.file_map) - def _on_loaded(self): - for func in self._on_loaded_funcs: - func() + def load(self, path, **kwargs): + """Loads a resource or return existing one""" + raise NotImplementedError() + + def load_deferred(self, path, **kwargs): + """Register a resource for deferred loading""" + raise NotImplementedError() + + def load_pool(self): + """Load all resource in the pool""" + raise NotImplementedError() + + def delete(self, obj, destroy=False): + """ + Remove an object from the pool. + This only removes the reference and will not actually destroy the object itself + """ + for path, data in self.file_map.items(): + if data == obj: + del self.file_map[path] + del self.file_meta[path] + if destroy: + self._destroy(obj) + break + + def _destroy(self, obj): + """Destroys the object""" + raise NotImplementedError() + + def flush(self, destroy=False): + """Delete all resources""" + for obj in list(self.file_map.values()): + self.delete(obj, destroy=destroy) + + def _find_last_of(self, file_path, finders): + """Find the last occurance of the file in finders""" + found_path = None + for finder in finders: + path = finder.find(file_path) + if path: + found_path = path + + return found_path From 452c77a332c0ec20d73f61aff8d1d3e4a553c113 Mon Sep 17 00:00:00 2001 From: Einar Forselv Date: Thu, 2 Aug 2018 20:24:25 +0200 Subject: [PATCH 15/22] Rewrite datafiles pool --- demosys/resources/data.py | 76 ++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 21 deletions(-) diff --git a/demosys/resources/data.py b/demosys/resources/data.py index c8e1a41..27c6b38 100644 --- a/demosys/resources/data.py +++ b/demosys/resources/data.py @@ -13,7 +13,7 @@ class Data: Generic data file. This can be extended with cusomtized loading functions. """ - def __init__(self, path, mode='binary'): + def __init__(self, path, mode='binary', **kwargs): """ :param path: file with relative path :param mode: What mode the file should be read ('b': binary, 't': text) @@ -33,6 +33,9 @@ def __init__(self, path, mode='binary'): def load(self, path): self.func(path) + def destroy(self): + self.data = None + def load_binary(self, path): with open(path, 'rb') as fd: self.data = fd.read() @@ -48,16 +51,23 @@ def _get_load_funcs(self): if attr.startswith("load_")} +class DataFileMeta: + + def __init__(self, path, cls, mode, **kwargs): + self.path = path + self.cls = cls + self.mode = mode + self.kwargs = kwargs + + class DataFiles(BaseRegistry): """Registry for requested data files""" def __init__(self): super().__init__() - self.files = [] - self.file_map = {} - def get(self, path: str, create=False, cls=Data) -> Data: + def load(self, path: str, cls=Data, mode='binary', **kwargs) -> Data: """ - Get or create a Data object. + Load Data object or get existing :param path: data file with path (pathlib.Path) :param crate: (bool) register a new resource (or fetch existing) @@ -66,32 +76,56 @@ def get(self, path: str, create=False, cls=Data) -> Data: """ path = Path(path) + data_file = self.file_map.get(path) + if data_file: + return data_file + + if not data_file: + meta = self.load_deferred(path, cls=cls, mode=mode, **kwargs) + data_file = self._load(meta) + self.file_map[meta.path] = data_file + + return data_file + + def load_deferred(self, path: str, cls=Data, mode='binary', **kwargs): + """ + Register a resource to be loaded in the loading stage + + :returns: DateFileMeta object + """ if not hasattr(cls, 'load'): raise ImproperlyConfigured("{} must have a load(path) method".format(cls.__class__)) - data_file = self.file_map.get(path) - if not data_file and create: - data_file = cls(path) - self.files.append(data_file) - self.file_map[path] = data_file + meta = DataFileMeta(path, cls, mode, **kwargs) + + self.file_map[path] = None + self.file_meta[path] = meta + + return meta + + def _load(self, meta) -> Data: + """Internal loader""" + found_path = self._find_last_of(meta.path, list(get_finders())) + + if not found_path: + raise ImproperlyConfigured("Cannot find data file {}".format(meta.path)) + + print(" - {}".format(meta.path)) + data_file = meta.cls(meta.path, mode=meta.mode, **meta.kwargs) + data_file.load(found_path) return data_file - def load(self): + def _destroy(self, obj): + obj.destroy() + + def load_pool(self): """ Loads all the data files using the configured finders. """ - finders = list(get_finders()) print("Loading data files:") - for name, data_file in self.file_map.items(): - for finder in finders: - path = finder.find(name) - if path: - print(" - {}".format(path)) - data_file.load(path) - break - else: - raise ImproperlyConfigured("Cannot find data file {}".format(name)) + for path, data_file in self.file_map.items(): + self._load(self.file_meta[path]) self._on_loaded() From 47da4508c335e75c4dd7d7974b3395753cb787f9 Mon Sep 17 00:00:00 2001 From: Einar Forselv Date: Thu, 2 Aug 2018 22:10:20 +0200 Subject: [PATCH 16/22] load_pool in base class --- demosys/resources/base.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/demosys/resources/base.py b/demosys/resources/base.py index b4f0d35..6e269f6 100644 --- a/demosys/resources/base.py +++ b/demosys/resources/base.py @@ -26,8 +26,12 @@ def load_deferred(self, path, **kwargs): raise NotImplementedError() def load_pool(self): - """Load all resource in the pool""" - raise NotImplementedError() + """ + Loads all the data files using the configured finders. + """ + for path, data_file in self.file_map.items(): + if self.file_map[path] is None: + self._load(self.file_meta[path]) def delete(self, obj, destroy=False): """ From 28d57990cb3db47c4ce6e62dbfdfd97b6b0a8289 Mon Sep 17 00:00:00 2001 From: Einar Forselv Date: Thu, 2 Aug 2018 22:10:58 +0200 Subject: [PATCH 17/22] DataFiles bug fixes --- demosys/resources/data.py | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/demosys/resources/data.py b/demosys/resources/data.py index 27c6b38..13e323d 100644 --- a/demosys/resources/data.py +++ b/demosys/resources/data.py @@ -80,10 +80,8 @@ def load(self, path: str, cls=Data, mode='binary', **kwargs) -> Data: if data_file: return data_file - if not data_file: - meta = self.load_deferred(path, cls=cls, mode=mode, **kwargs) - data_file = self._load(meta) - self.file_map[meta.path] = data_file + meta = self.load_deferred(path, cls=cls, mode=mode, **kwargs) + data_file = self._load(meta) return data_file @@ -110,24 +108,15 @@ def _load(self, meta) -> Data: if not found_path: raise ImproperlyConfigured("Cannot find data file {}".format(meta.path)) - print(" - {}".format(meta.path)) + print("Loading: {}".format(meta.path)) data_file = meta.cls(meta.path, mode=meta.mode, **meta.kwargs) data_file.load(found_path) + self.file_map[meta.path] = data_file return data_file def _destroy(self, obj): obj.destroy() - def load_pool(self): - """ - Loads all the data files using the configured finders. - """ - print("Loading data files:") - for path, data_file in self.file_map.items(): - self._load(self.file_meta[path]) - - self._on_loaded() - data = DataFiles() From e481b3e4d0c42beb468f27a47bb506b7c03d4b85 Mon Sep 17 00:00:00 2001 From: Einar Forselv Date: Thu, 2 Aug 2018 22:11:27 +0200 Subject: [PATCH 18/22] Scene files rewrite --- demosys/opengl/vao.py | 11 ++++++ demosys/resources/scenes.py | 77 +++++++++++++++++++++++-------------- tests/test_resources.py | 67 ++++++++++++++++++++++++++++++-- 3 files changed, 123 insertions(+), 32 deletions(-) diff --git a/demosys/opengl/vao.py b/demosys/opengl/vao.py index 9033a63..019c27d 100644 --- a/demosys/opengl/vao.py +++ b/demosys/opengl/vao.py @@ -239,6 +239,17 @@ def _create_vao_instance(self, shader): return vao + def release(self): + """Destroy the vao object and its buffers""" + for key, vao in self.vaos: + vao.release() + + for buff in self.buffers: + buff.buffer.release() + + if self._index_buffer: + self._index_buffer.release() + class VAOError(Exception): pass diff --git a/demosys/resources/scenes.py b/demosys/resources/scenes.py index 8d859cf..51a0cef 100644 --- a/demosys/resources/scenes.py +++ b/demosys/resources/scenes.py @@ -11,6 +11,14 @@ from .base import BaseRegistry +class SceneMeta: + + def __init__(self, path, loader_cls, **kwargs): + self.path = path + self.loader_cls = loader_cls + self.kwargs = kwargs + + class Scenes(BaseRegistry): """ A registry for scense requested by effects. @@ -18,13 +26,11 @@ class Scenes(BaseRegistry): """ def __init__(self): super().__init__() - self.scenes = {} - - @property - def count(self): - return len(self.scenes) + self.scene_loaders = [ + import_string(loader) for loader in settings.SCENE_LOADERS + ] - def get(self, path: Union[str, Path], **kwargs) -> Scene: + def load(self, path: Union[str, Path], **kwargs) -> Scene: """ Get or create a scene object. This may return an empty object that will be filled during load @@ -36,33 +42,46 @@ def get(self, path: Union[str, Path], **kwargs) -> Scene: """ path = Path(path) + scene = self.file_map.get(path) + if scene: + return scene + + meta = self.load_deferred(path, **kwargs) + scene = self._load(meta) + + return scene + + def load_deferred(self, path: Union[str, Path], **kwargs) -> SceneMeta: # Figure out what scene loader class should be used - for loader_name in settings.SCENE_LOADERS: - loader_cls = import_string(loader_name) + for loader_cls in self.scene_loaders: if loader_cls.supports_file(path): - if path not in self.scenes: - loader_cls = import_string(loader_name) - self.scenes[path] = Scene(path, loader=loader_cls(path), **kwargs) break else: - raise ImproperlyConfigured("Scene {} has no loader class registered. Check settings.SCENE_LOADERS") - - return self.scenes[path] - - def load(self): - finders = list(get_finders()) - print("Loading scenes:") - for name, scene in self.scenes.items(): - for finder in finders: - path = finder.find(name) - if path: - print(" - {}".format(path)) - scene.load(path) - break - else: - raise ImproperlyConfigured("Cannot find scene {}".format(name)) - - self._on_loaded() + raise ImproperlyConfigured( + "Scene {} has no loader class registered. Check settings.SCENE_LOADERS".format(path)) + + meta = SceneMeta(path, loader_cls, **kwargs) + + self.file_meta[path] = meta + self.file_map[path] = None + + return meta + + def _load(self, meta) -> Scene: + found_path = self._find_last_of(meta.path, list(get_finders())) + + if not found_path: + raise ImproperlyConfigured("Cannot find scene file {}".format(meta.path)) + + print("Loading: {}".format(meta.path)) + scene = Scene(meta.path, loader=meta.loader_cls(meta.path), **meta.kwargs) + scene.load(found_path) + + self.file_map[meta.path] = scene + return scene + + def _destroy(self, obj): + obj.destroy() scenes = Scenes() diff --git a/tests/test_resources.py b/tests/test_resources.py index 55f525d..4f186be 100644 --- a/tests/test_resources.py +++ b/tests/test_resources.py @@ -1,9 +1,70 @@ from demosys.test import DemosysTestCase from demosys import resources +from demosys.core.exceptions import ImproperlyConfigured class ResourceTestCase(DemosysTestCase): - def test_stuff(self): - result = resources.shaders.get('vf_pos.glsl', create=True) - resources.shaders.load() + def test_datafiles(self): + """Loading data files""" + # string and binary data file + data_str = resources.data.load('data.txt', mode="text") + data_bin = resources.data.load('data.bin', mode="binary") + self.assertEqual(data_str.data, '1234') + self.assertEqual(data_bin.data, b'\x01\x02\x03\x04') + + # Ensure requesting the same file returns the existing one + data = resources.data.load('data.txt', mode="text") + self.assertEqual(data, data_str) + data = resources.data.load('data.bin', mode="binary") + self.assertEqual(data, data_bin) + self.assertEqual(resources.data.count, 2) + + # Delete and destroy + resources.data.delete(data_str, destroy=True) + self.assertIsNone(data_str.data) + self.assertEqual(resources.data.count, 1) + resources.data.flush(destroy=True) + self.assertEqual(resources.data.count, 0) + + with self.assertRaises(ImproperlyConfigured): + resources.data.load('notfound.bin') + + def test_scene(self): + scene_obj = resources.scenes.load('cube.obj') + self.assertEqual(len(scene_obj.nodes), 0) + self.assertEqual(len(scene_obj.root_nodes), 1) + + scene_gltf = resources.scenes.load('BoxTextured/glTF/BoxTextured.gltf') + self.assertEqual(len(scene_gltf.nodes), 2) + self.assertEqual(len(scene_gltf.root_nodes), 1) + + # Ensure requesting the same file returns the existing one + scene = resources.scenes.load('cube.obj') + self.assertEqual(scene, scene_obj) + scene = resources.scenes.load('BoxTextured/glTF/BoxTextured.gltf') + self.assertEqual(scene, scene_gltf) + + self.assertEqual(resources.scenes.count, 2) + + # Delete and destroy + resources.scenes.delete(scene_obj, destroy=True) + self.assertEqual(resources.scenes.count, 1) + resources.scenes.flush(destroy=True) + self.assertEqual(resources.scenes.count, 0) + + with self.assertRaises(ImproperlyConfigured): + resources.scenes.load('notfound.gltf') + + # def test_shaders(self): + # result = resources.shaders.get('vf_pos.glsl') + # resources.shaders.load() + # self.assertNotEqual(result.mglo, None) + + # def test_textures(self): + # result = resources.textures.get('wood.jpg') + # resources.textures.load() + # self.assertNotEqual(result.mglo, None) + + # def test_resource_override(self): + # pass From c186cc68d6de200f725f85aa9a3999001e1446ef Mon Sep 17 00:00:00 2001 From: Einar Forselv Date: Thu, 2 Aug 2018 22:23:12 +0200 Subject: [PATCH 19/22] Do not store loader in scene --- demosys/resources/scenes.py | 4 ++-- demosys/scene/scene.py | 19 +++++++++---------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/demosys/resources/scenes.py b/demosys/resources/scenes.py index 51a0cef..fa57d3d 100644 --- a/demosys/resources/scenes.py +++ b/demosys/resources/scenes.py @@ -74,8 +74,8 @@ def _load(self, meta) -> Scene: raise ImproperlyConfigured("Cannot find scene file {}".format(meta.path)) print("Loading: {}".format(meta.path)) - scene = Scene(meta.path, loader=meta.loader_cls(meta.path), **meta.kwargs) - scene.load(found_path) + scene = Scene(meta.path, **meta.kwargs) + scene.load(meta.loader_cls(meta.path), found_path) self.file_map[meta.path] = scene return scene diff --git a/demosys/scene/scene.py b/demosys/scene/scene.py index a36d650..d7df14a 100644 --- a/demosys/scene/scene.py +++ b/demosys/scene/scene.py @@ -10,13 +10,12 @@ class Scene: """Generic scene""" - def __init__(self, name, loader=None, mesh_shaders=None, **kwargs): + def __init__(self, name, mesh_shaders=None, **kwargs): """ :param name: Unique name or path for the scene :param loader: Loader class for the scene if relevant """ self.name = name - self.loader = loader self.root_nodes = [] # References resources in the scene @@ -31,7 +30,7 @@ def __init__(self, name, loader=None, mesh_shaders=None, **kwargs): self.diagonal_size = 1.0 self.bbox_vao = geometry.bbox() - self.bbox_shader = shaders.get('scene_default/bbox.glsl', create=True) + self.bbox_shader = shaders.get('scene_default/bbox.glsl') self._view_matrix = matrix44.create_identity() @@ -122,17 +121,17 @@ def calc_scene_bbox(self): self.diagonal_size = vector3.length(self.bbox_max - self.bbox_min) - def load(self, path): + def load(self, loader, path): """Deferred loading if a loader is specified""" - if not hasattr(self, 'loader'): - return - - if self.loader: - self.loader.load(self, path=path) - + loader.load(self, path=path) self.apply_mesh_shaders() self.view_matrix = matrix44.create_identity() + def destroy(self): + """Destroy the scene data and deallocate buffers""" + for mesh in self.meshes: + mesh.vao.release() + def __str__(self): return "".format(self.name) From 918694e4fd32afe0f87391babfb97cf2fbd2a712 Mon Sep 17 00:00:00 2001 From: Einar Forselv Date: Thu, 2 Aug 2018 23:27:07 +0200 Subject: [PATCH 20/22] Resource pool rewrites --- demosys/opengl/shader.py | 4 +- demosys/resources/shaders.py | 111 ++++++++++++++--------------- demosys/resources/textures.py | 72 +++++++++++-------- demosys/resources/tracks.py | 10 +-- demosys/scene/scene.py | 2 +- demosys/scene/shaders.py | 6 +- tests/resources/textures/crate.jpg | Bin 0 -> 76740 bytes tests/test_resources.py | 53 +++++++++++--- 8 files changed, 149 insertions(+), 109 deletions(-) create mode 100644 tests/resources/textures/crate.jpg diff --git a/demosys/opengl/shader.py b/demosys/opengl/shader.py index 00e8ed0..69952ec 100644 --- a/demosys/opengl/shader.py +++ b/demosys/opengl/shader.py @@ -153,7 +153,7 @@ def prepare(self, reload=False): program = self.ctx.program(**params) if reload: - self.program.release() + self.release() self.program = program @@ -161,7 +161,7 @@ def prepare(self, reload=False): self._build_uniform_map() self._build_attribute_map() - def _delete(self): + def release(self): """Frees the memory and invalidates the name associated with the program""" if self.program: self.program.release() diff --git a/demosys/resources/shaders.py b/demosys/resources/shaders.py index a40b62a..bee1d8b 100644 --- a/demosys/resources/shaders.py +++ b/demosys/resources/shaders.py @@ -10,6 +10,13 @@ from .base import BaseRegistry +class ShaderMeta: + + def __init__(self, path, **kwargs): + self.path = path + self.kwargs = kwargs + + class Shaders(BaseRegistry): """ A registry for shaders requested by effects. @@ -17,84 +24,72 @@ class Shaders(BaseRegistry): """ def __init__(self): super().__init__() - self.shaders = {} - - @property - def count(self): - """ - :return: Number of shaders - """ - return len(self.shaders) - def get(self, path: Union[str, Path], create=False) -> ShaderProgram: + def load(self, path: Union[str, Path], **kwargs) -> ShaderProgram: """ - Get or create a shader object. - This may return an empty object that will be filled during load - based on the ``create`` parameter. + load shader program or return an exiting program. :param path: Path to the shader (pathlib.Path instance) - :param create: (bool) Create an empty shader object if it doesn't exist :return: Shader object """ path = Path(path) - shader = self.shaders.get(path) - if create and not shader: - shader = ShaderProgram(path) - self.shaders[path] = shader + shader = self.file_map.get(path) + if shader: + return shader + + meta = self.load_deferred(path, **kwargs) + shader = self._load(meta) + return shader - def load(self, reload=False): - """ - Loads all the shaders using the configured finders. + def load_deferred(self, path: Union[str, Path], **kwargs) -> ShaderMeta: + meta = ShaderMeta(path, **kwargs) - :param reload: (bool) Are we reloading the shaders? - """ - print("Loading shaders:") - for name, shader in self.shaders.items(): - self.load_shader(shader, name=name, reload=reload) + self.file_map[path] = None + self.file_meta[path] = meta - self._on_loaded() + return meta - def load_shader(self, shader, name=None, reload=False): - """ - Loads a single shader adding it to the shader registry + def _load(self, meta, reload=False): + found_path = self._find_last_of(meta.path, list(get_finders())) - :param shader: The shader to load - :param name: Unique name in the registry. Usually the path - :param reload: (bool) Are we reloading the shader? - """ - if name is None: - name = Path(shader.path) - - finders = list(get_finders()) - - for finder in finders: - path = finder.find(name) - if path: - print(" - {}".format(path)) - with open(path, 'r') as fd: - shader.set_source(fd.read()) - - try: - shader.prepare(reload=reload) - except (ShaderError, moderngl.Error) as err: - print("ShaderError: ", err) - if not reload: - raise - except Exception as err: - print(err) - raise - - break + if not found_path: + raise ImproperlyConfigured("Cannot find shader {}".format(meta.path)) + + print("Loading: {}".format(meta.path)) + if reload: + shader = self.file_map[meta.path] else: - raise ImproperlyConfigured("Cannot find shader {}".format(name)) + shader = ShaderProgram(meta.path) + + with open(found_path, 'r') as fd: + shader.set_source(fd.read()) + + try: + shader.prepare(reload=reload) + except (ShaderError, moderngl.Error) as err: + print("ShaderError: ", err) + if not reload: + raise + except Exception as err: + print(err) + raise + + self.file_map[meta.path] = shader + + return shader + + def _destroy(self, obj): + obj.release() def reload(self): """ Reloads all shaders """ - self.load(reload=True) + for path, meta in self.file_meta.items(): + print(path, meta) + self._load(meta, reload=True) shaders = Shaders() diff --git a/demosys/resources/textures.py b/demosys/resources/textures.py index 90657a4..aa5d24c 100644 --- a/demosys/resources/textures.py +++ b/demosys/resources/textures.py @@ -11,6 +11,14 @@ from .base import BaseRegistry +class TextureMeta: + + def __init__(self, path, cls, **kwargs): + self.path = path + self.cls = cls + self.kwargs = kwargs + + class Textures(BaseRegistry): """ A registry for textures requested by effects. @@ -18,52 +26,54 @@ class Textures(BaseRegistry): """ def __init__(self): super().__init__() - self.textures = {} - - @property - def count(self): - """ - :return: Number of textures - """ - return len(self.textures) - def get(self, path: Union[str, Path], create=False, cls=Texture2D, **kwargs) -> Union[Texture2D, TextureArray]: + def load(self, path: Union[str, Path], cls=Texture2D, **kwargs) -> Union[Texture2D, TextureArray]: """ Get or create a texture object. - This may return an empty object that will be filled during load - based on the ``create`` parameter. + This may return an empty object that will be filled during loading stage :param path: Path to the texture - :param create: (bool) Create an empty texture object if it doesn't exist :param cls: The texture class to instantiate :return: Texture object """ path = Path(path) - texture = self.textures.get(path) - if create and not texture: - texture = cls(path=path, **kwargs) - self.textures[path] = texture + texture = self.file_map.get(path) + if texture: + return texture + + meta = self.load_deferred(path, cls=cls, **kwargs) + texture = self._load(meta) + return texture - def load(self): + def load_deferred(self, path: Union[str, Path], cls=Texture2D, **kwargs) -> TextureMeta: + meta = TextureMeta(path, cls, **kwargs) + + self.file_map[path] = None + self.file_meta[path] = meta + + return meta + + def _load(self, meta): """ Loads all the textures using the configured finders. """ - finders = list(get_finders()) - print("Loading textures:") - for name, texture in self.textures.items(): - for finder in finders: - path = finder.find(name) - if path: - print(" - {}".format(path)) - image = Image.open(path) - texture.set_image(image) - break - else: - raise ImproperlyConfigured("Cannot find texture {}".format(name)) - - self._on_loaded() + found_path = self._find_last_of(meta.path, list(get_finders())) + + if not found_path: + raise ImproperlyConfigured("Cannot find texture {}".format(meta.path)) + + print("Loading: {}".format(meta.path)) + texture = meta.cls(path=meta.path, **meta.kwargs) + image = Image.open(found_path) + texture.set_image(image) + self.file_map[meta.path] = texture + + return texture + + def _destroy(self, obj): + obj.release() textures = Textures() diff --git a/demosys/resources/tracks.py b/demosys/resources/tracks.py index 8a56c78..0474a8f 100644 --- a/demosys/resources/tracks.py +++ b/demosys/resources/tracks.py @@ -25,11 +25,11 @@ def get(self, name) -> Track: self.track_map[name] = track return track - def load(self): - """ - Dummy. This will be handled by the rocket library, - """ - pass + # def load(self): + # """ + # Dummy. This will be handled by the rocket library, + # """ + # pass tracks = Tracks() diff --git a/demosys/scene/scene.py b/demosys/scene/scene.py index d7df14a..7a3360e 100644 --- a/demosys/scene/scene.py +++ b/demosys/scene/scene.py @@ -30,7 +30,7 @@ def __init__(self, name, mesh_shaders=None, **kwargs): self.diagonal_size = 1.0 self.bbox_vao = geometry.bbox() - self.bbox_shader = shaders.get('scene_default/bbox.glsl') + self.bbox_shader = shaders.load('scene_default/bbox.glsl') self._view_matrix = matrix44.create_identity() diff --git a/demosys/scene/shaders.py b/demosys/scene/shaders.py index 7121b52..77d1b0b 100644 --- a/demosys/scene/shaders.py +++ b/demosys/scene/shaders.py @@ -41,7 +41,7 @@ class ColorShader(MeshShader): Simple color shader """ def __init__(self, shader=None, **kwargs): - super().__init__(shader=shaders.get("scene_default/color.glsl", create=True)) + super().__init__(shader=shaders.load("scene_default/color.glsl")) def draw(self, mesh, projection_matrix=None, view_matrix=None, camera_matrix=None, time=0): @@ -79,7 +79,7 @@ class TextureShader(MeshShader): Simple texture shader """ def __init__(self, shader=None, **kwargs): - super().__init__(shader=shaders.get("scene_default/texture.glsl", create=True)) + super().__init__(shader=shaders.load("scene_default/texture.glsl")) def draw(self, mesh, projection_matrix=None, view_matrix=None, camera_matrix=None, time=0): # if mesh.material.double_sided: @@ -112,7 +112,7 @@ class FallbackShader(MeshShader): Fallback shader only rendering positions in white """ def __init__(self, shader=None, **kwargs): - super().__init__(shader=shaders.get("scene_default/fallback.glsl", create=True)) + super().__init__(shader=shaders.load("scene_default/fallback.glsl")) def draw(self, mesh, projection_matrix=None, view_matrix=None, camera_matrix=None, time=0): diff --git a/tests/resources/textures/crate.jpg b/tests/resources/textures/crate.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e3ec89c99799f418efd1ca2d553ecee46db43273 GIT binary patch literal 76740 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 literal 0 HcmV?d00001 diff --git a/tests/test_resources.py b/tests/test_resources.py index 4f186be..a0f7c24 100644 --- a/tests/test_resources.py +++ b/tests/test_resources.py @@ -56,15 +56,50 @@ def test_scene(self): with self.assertRaises(ImproperlyConfigured): resources.scenes.load('notfound.gltf') - # def test_shaders(self): - # result = resources.shaders.get('vf_pos.glsl') - # resources.shaders.load() - # self.assertNotEqual(result.mglo, None) - - # def test_textures(self): - # result = resources.textures.get('wood.jpg') - # resources.textures.load() - # self.assertNotEqual(result.mglo, None) + def test_shaders(self): + resources.shaders.flush(destroy=True) + shader1 = resources.shaders.load('vf_pos.glsl') + shader2 = resources.shaders.load('vgf_quads.glsl') + self.assertEqual(resources.shaders.count, 2) + + # Attempt to reload shaders + resources.shaders.reload() + self.assertEqual(resources.shaders.count, 2) + + # Ensure requesting the same file returns the existing one + shader = resources.shaders.load('vf_pos.glsl') + self.assertEqual(shader, shader1) + shader = resources.shaders.load('vgf_quads.glsl') + self.assertEqual(shader, shader2) + + # Delete and destroy + resources.shaders.delete(shader1, destroy=True) + self.assertEqual(resources.shaders.count, 1) + resources.shaders.flush(destroy=True) + self.assertEqual(resources.shaders.count, 0) + + with self.assertRaises(ImproperlyConfigured): + resources.shaders.load('notfound.glsl') + + def test_textures(self): + texture1 = resources.textures.load('wood.jpg') + texture2 = resources.textures.load('crate.jpg') + self.assertEqual(resources.textures.count, 2) + + # Ensure requesting the same file returns the existing one + texture = resources.textures.load('wood.jpg') + self.assertEqual(texture, texture1) + texture = resources.textures.load('crate.jpg') + self.assertEqual(texture, texture2) + + # Delete and destroy + resources.textures.delete(texture1, destroy=True) + self.assertEqual(resources.textures.count, 1) + resources.textures.flush(destroy=True) + self.assertEqual(resources.textures.count, 0) + + with self.assertRaises(ImproperlyConfigured): + resources.textures.load('notfound.png') # def test_resource_override(self): # pass From de48a37204b1181c644fc9ce04cfea76498fb65c Mon Sep 17 00:00:00 2001 From: Einar Forselv Date: Thu, 2 Aug 2018 23:44:49 +0200 Subject: [PATCH 21/22] Working tests --- demosys/test/testcase.py | 9 ++++----- demosys/text/renderer2d.py | 14 ++------------ demosys/text/writer2d.py | 19 +++---------------- docs/source/reference/effect.rst | 9 --------- docs/source/reference/shaderprogram.rst | 1 + docs/source/reference/vao.rst | 1 + tests/test_shader.py | 2 +- tests/test_text.py | 20 ++++++++++++++++++++ 8 files changed, 32 insertions(+), 43 deletions(-) create mode 100644 tests/test_text.py diff --git a/demosys/test/testcase.py b/demosys/test/testcase.py index 7a2efbc..255f30c 100644 --- a/demosys/test/testcase.py +++ b/demosys/test/testcase.py @@ -21,22 +21,21 @@ def create_shader(self, source=None, path=None): """ Create a shader from source or file """ - program = ShaderProgram(name="test", path=path) - if source: + program = ShaderProgram(name="test", path=path) program.set_source(source) program.prepare() if path: - resources.shaders.load_shader(program) + program = resources.shaders.load(path) return program def get_texture(self, path): - return resources.textures.get(path, create=True) + return resources.textures.load(path, create=True) def get_texture_array(self, path, layers=0): - return resources.textures.get(path, create=True, cls=TextureArray, layers=layers) + return resources.textures.load(path, create=True, cls=TextureArray, layers=layers) def get_track(self, name): return resources.tracks.get(name) diff --git a/demosys/text/renderer2d.py b/demosys/text/renderer2d.py index 2854e23..50d3bc4 100644 --- a/demosys/text/renderer2d.py +++ b/demosys/text/renderer2d.py @@ -7,13 +7,6 @@ from .writer2d import TextWriter2D -def on_load(): - resources.shaders.get('demosys/text/view_renderer_texture.glsl', create=True) - - -resources.on_load(on_load, priority=100) - - class TextRenderer2D(TextWriter2D): def __init__(self, area, text_lines=None, texture_height=64): @@ -22,17 +15,14 @@ def __init__(self, area, text_lines=None, texture_height=64): :param size: Text size :param text: Initial text """ + super().__init__(area, text_lines=text_lines) self._texture_height = texture_height self._texture_width = 0 self._quad = self._create_vao() - self._quad_shader = resources.shaders.get('demosys/text/view_renderer_texture.glsl', create=True) + self._quad_shader = resources.shaders.load('demosys/text/view_renderer_texture.glsl', create=True) self._fbo = None - super().__init__(area, text_lines=text_lines) - def _post_load(self): - print("TextRenderer2D._post_load") - super()._post_load() self._texture_width = int( round(self._meta.char_aspect_wh * self._texture_height * self.area[0] / self.area[1], 0) ) diff --git a/demosys/text/writer2d.py b/demosys/text/writer2d.py index a72c1b4..8760c96 100644 --- a/demosys/text/writer2d.py +++ b/demosys/text/writer2d.py @@ -8,15 +8,6 @@ from .base import BaseText, Meta -def on_load(): - resources.textures.get('demosys/text/VeraMono.png', cls=TextureArray, layers=190, create=True) - resources.shaders.get('demosys/text/textwriter2d.glsl', create=True) - resources.data.get('demosys/text/meta.json', create=True) - - -resources.on_load(on_load, priority=100) - - class TextWriter2D(BaseText): def __init__(self, area, text_lines=None, aspect_ratio=1.0): @@ -34,16 +25,12 @@ def __init__(self, area, text_lines=None, aspect_ratio=1.0): self.aspect_ratio = aspect_ratio self._vao = None - self._texture = resources.textures.get('demosys/text/VeraMono.png', cls=TextureArray, layers=190, create=True) - self._shader = resources.shaders.get('demosys/text/textwriter2d.glsl', create=True) - self._config = resources.data.get('demosys/text/meta.json', create=True) + self._texture = resources.textures.load('demosys/text/VeraMono.png', cls=TextureArray, layers=190) + self._shader = resources.shaders.load('demosys/text/textwriter2d.glsl') + self._config = resources.data.load('demosys/text/meta.json') self._string_buffer = None - resources.on_loaded(self._post_load, priority=99) - - def _post_load(self): - """Parse font metadata after resources are loaded""" self._init(Meta(self._config.data)) self._string_buffer = self.ctx.buffer(reserve=self.area[0] * 4 * self.area[1]) diff --git a/docs/source/reference/effect.rst b/docs/source/reference/effect.rst index 55eaee1..08a6eb9 100644 --- a/docs/source/reference/effect.rst +++ b/docs/source/reference/effect.rst @@ -20,16 +20,7 @@ Resource Methods .. automethod:: Effect.get_track(name, local=False) -> Track .. automethod:: Effect.get_scene(path, local=False, **kwargs) -> Scene .. automethod:: Effect.get_data(path, local=False, **kwargs) -> Data - -Callbacks ---------- - .. automethod:: Effect.post_load() -.. automethod:: Effect.on_resouces_loaded(func) -.. automethod:: Effect.on_textures_loaded(func) -.. automethod:: Effect.on_data_loaded(func) -.. automethod:: Effect.on_shaders_loaded(func) -.. automethod:: Effect.on_scenes_loaded(func) Utility Methods --------------- diff --git a/docs/source/reference/shaderprogram.rst b/docs/source/reference/shaderprogram.rst index da271ce..9b7b878 100644 --- a/docs/source/reference/shaderprogram.rst +++ b/docs/source/reference/shaderprogram.rst @@ -17,6 +17,7 @@ Source Methods .. automethod:: ShaderProgram.set_vertex_source(source:str) .. automethod:: ShaderProgram.set_geometry_source(source:str) .. automethod:: ShaderProgram.set_fragment_source(source:str) +.. automethod:: ShaderProgram.release() Attributes ---------- diff --git a/docs/source/reference/vao.rst b/docs/source/reference/vao.rst index 5f51d41..25f6cea 100644 --- a/docs/source/reference/vao.rst +++ b/docs/source/reference/vao.rst @@ -12,6 +12,7 @@ Methods .. automethod:: VAO.buffer(buffer, buffer_format:str, attribute_names, per_instance=False) .. automethod:: VAO.index_buffer(buffer, index_element_size=4) .. automethod:: VAO.subroutines(shader, routines:tuple) +.. automethod:: VAO.release() Draw Methods ------------ diff --git a/tests/test_shader.py b/tests/test_shader.py index dadf48f..fe5ce58 100644 --- a/tests/test_shader.py +++ b/tests/test_shader.py @@ -46,4 +46,4 @@ def assertAttributes(self, shader): assert shader.attribute_key assert len(shader.attribute_list) == 1 assert len(shader.attribute_map) == 1 - assert shader.path in str(shader) + assert str(shader.path) in str(shader) diff --git a/tests/test_text.py b/tests/test_text.py new file mode 100644 index 0000000..9307900 --- /dev/null +++ b/tests/test_text.py @@ -0,0 +1,20 @@ +from demosys.test import DemosysTestCase +from demosys.text import TextWriter2D, TextRenderer2D + + +class TextTestCase(DemosysTestCase): + + def test_writer(self): + writer = TextWriter2D( + (4, 4), + text_lines=[ + "ABCD", + "!@#$", + "abcd", + "1234", + ] + ) + writer.draw((0, 0), size=1.0) + + def test_renderer(self): + pass From 50264e7edb7a31ce0261d97a90c13e4ee2a70f4b Mon Sep 17 00:00:00 2001 From: Einar Forselv Date: Fri, 3 Aug 2018 00:03:47 +0200 Subject: [PATCH 22/22] Compatiblity functions --- demosys/resources/data.py | 4 ++++ demosys/resources/scenes.py | 4 ++++ demosys/resources/shaders.py | 4 ++++ demosys/resources/textures.py | 4 ++++ 4 files changed, 16 insertions(+) diff --git a/demosys/resources/data.py b/demosys/resources/data.py index 13e323d..d579d25 100644 --- a/demosys/resources/data.py +++ b/demosys/resources/data.py @@ -65,6 +65,10 @@ class DataFiles(BaseRegistry): def __init__(self): super().__init__() + def get(self, path: str, cls=Data, mode='binary', **kwargs) -> Data: + """Compatibility function for the old resource system""" + return self.load(path, cls=cls, mode=mode, **kwargs) + def load(self, path: str, cls=Data, mode='binary', **kwargs) -> Data: """ Load Data object or get existing diff --git a/demosys/resources/scenes.py b/demosys/resources/scenes.py index fa57d3d..5cb63c1 100644 --- a/demosys/resources/scenes.py +++ b/demosys/resources/scenes.py @@ -30,6 +30,10 @@ def __init__(self): import_string(loader) for loader in settings.SCENE_LOADERS ] + def get(self, path: Union[str, Path], **kwargs) -> Scene: + """Compatibility function for the old resource system""" + return self.load(path, **kwargs) + def load(self, path: Union[str, Path], **kwargs) -> Scene: """ Get or create a scene object. diff --git a/demosys/resources/shaders.py b/demosys/resources/shaders.py index bee1d8b..3f8f2e7 100644 --- a/demosys/resources/shaders.py +++ b/demosys/resources/shaders.py @@ -25,6 +25,10 @@ class Shaders(BaseRegistry): def __init__(self): super().__init__() + def get(self, path: Union[str, Path], **kwargs) -> ShaderProgram: + """Compatibility method with the old resource system""" + return self.load(path, **kwargs) + def load(self, path: Union[str, Path], **kwargs) -> ShaderProgram: """ load shader program or return an exiting program. diff --git a/demosys/resources/textures.py b/demosys/resources/textures.py index aa5d24c..7ac90b9 100644 --- a/demosys/resources/textures.py +++ b/demosys/resources/textures.py @@ -27,6 +27,10 @@ class Textures(BaseRegistry): def __init__(self): super().__init__() + def get(self, path: Union[str, Path], cls=Texture2D, **kwargs) -> Union[Texture2D, TextureArray]: + """Compatibility with old resource system""" + return self.load(path, cls=cls, **kwargs) + def load(self, path: Union[str, Path], cls=Texture2D, **kwargs) -> Union[Texture2D, TextureArray]: """ Get or create a texture object.