Skip to content

Commit ef7abfa

Browse files
committed
Support loading separate shader files
1 parent 62cfec1 commit ef7abfa

File tree

9 files changed

+124
-47
lines changed

9 files changed

+124
-47
lines changed

demosys/conf/default.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747

4848
PROGRAM_LOADERS = (
4949
'demosys.loaders.program.single.Loader',
50+
'demosys.loaders.program.separate.Loader',
5051
)
5152

5253
TEXTURE_DIRS = (

demosys/loaders/program/separate.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from demosys.loaders.base import BaseLoader
2+
from demosys.opengl import program
3+
4+
5+
class Loader(BaseLoader):
6+
name = 'separate'
7+
8+
def load(self):
9+
10+
vs_source = self.load_shader("vertex", self.meta.vertex_shader)
11+
geo_source = self.load_shader("geometry", self.meta.geometry_shader)
12+
fs_source = self.load_shader("fragment", self.meta.fragment_shader)
13+
14+
shaders = program.ProgramShaders.from_separate(
15+
self.meta,
16+
vs_source,
17+
geometry_source=geo_source,
18+
fragment_source=fs_source,
19+
)
20+
prog = shaders.create()
21+
22+
# Wrap the program if reloadable is set
23+
if self.meta.reloadable:
24+
# Disable reload flag so reloads will return Program instances
25+
self.meta.reloadable = False
26+
# Wrap it ..
27+
prog = program.ReloadableProgram(self.meta, prog)
28+
29+
return prog
30+
31+
def load_shader(self, shader_type: str, path: str):
32+
"""Load a single shader"""
33+
if path:
34+
resolved_path = self.find_program(path)
35+
if not resolved_path:
36+
raise ValueError("Cannot find {} shader '{}'".format(shader_type, path))
37+
38+
with open(resolved_path, 'r') as fd:
39+
return fd.read()

demosys/resources/base.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ def loader(self):
4747
"""
4848
return self._kwargs.get('loader') or self.default_loader
4949

50+
@loader.setter
51+
def loader(self, value):
52+
self._kwargs['loader'] = value
53+
5054
@property
5155
def loader_cls(self) -> Type:
5256
"""

demosys/resources/meta.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def __init__(self, path=None, label=None, loader=None, **kwargs):
1919
class ProgramDescription(ResourceDescription):
2020
"""Describes a program to load"""
2121
require_label = True
22-
default_loader = 'single'
22+
default_loader = None
2323
resource_type = 'programs'
2424

2525
def __init__(self, path=None, label=None, loader=None, reloadable=False,
@@ -40,11 +40,23 @@ def __init__(self, path=None, label=None, loader=None, reloadable=False,
4040

4141
@property
4242
def reloadable(self):
43-
return self.kwargs.get('reloadable')
43+
return self._kwargs.get('reloadable')
4444

4545
@reloadable.setter
4646
def reloadable(self, value):
47-
self.kwargs['reloadable'] = value
47+
self._kwargs['reloadable'] = value
48+
49+
@property
50+
def vertex_shader(self):
51+
return self._kwargs.get('vertex_shader')
52+
53+
@property
54+
def geometry_shader(self):
55+
return self._kwargs.get('geometry_shader')
56+
57+
@property
58+
def fragment_shader(self):
59+
return self._kwargs.get('fragment_shader')
4860

4961

5062
class SceneDescription(ResourceDescription):
@@ -80,12 +92,12 @@ def __init__(self, path=None, label=None, loader=None, flip=True, mipmap=True, i
8092

8193
@property
8294
def flip(self):
83-
return self.kwargs.get('flip')
95+
return self._kwargs.get('flip')
8496

8597
@property
8698
def image(self):
87-
return self.kwargs.get('image')
99+
return self._kwargs.get('image')
88100

89101
@property
90102
def mipmap(self):
91-
return self.kwargs.get('mipmap')
103+
return self._kwargs.get('mipmap')

demosys/resources/programs.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
from demosys.conf import settings
33
from demosys.resources.base import BaseRegistry
44
from demosys.utils.module_loading import import_string
5+
from demosys.resources.meta import ProgramDescription
6+
from demosys.exceptions import ImproperlyConfigured
57

68

79
class Programs(BaseRegistry):
@@ -15,5 +17,24 @@ def __init__(self):
1517
import_string(loader) for loader in settings.PROGRAM_LOADERS
1618
]
1719

20+
def resolve_loader(self, meta: ProgramDescription):
21+
"""
22+
Resolve program loader
23+
"""
24+
if not meta.loader:
25+
meta.loader = 'single' if meta.path else 'separate'
26+
27+
for loader_cls in self._loaders:
28+
if loader_cls.name == meta.loader:
29+
meta.loader_cls = loader_cls
30+
break
31+
else:
32+
raise ImproperlyConfigured(
33+
(
34+
"Program {} has no loader class registered."
35+
"Check PROGRAM_LOADERS or PROGRAM_DIRS"
36+
).format(meta.path)
37+
)
38+
1839

1940
programs = Programs()

examples/cubes/dependencies.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,12 @@
33
effect_packages = []
44

55
resources = [
6-
ProgramDescription(path="cubes/cube_plain.glsl", label="plain", reloadable=True),
7-
ProgramDescription(path="cubes/cube_light.glsl", label="light"),
8-
ProgramDescription(path="cubes/cube_textured.glsl", label="textured"),
9-
TextureDescription(path="cubes/crate.jpg", label="crate"),
6+
ProgramDescription(label="plain", path="cubes/cube_plain.glsl"),
7+
ProgramDescription(label="light", path="cubes/cube_light.glsl"),
8+
ProgramDescription(
9+
label="textured",
10+
vertex_shader="cubes/cube_textured_vs.glsl",
11+
fragment_shader="cubes/cube_textured_fs.glsl",
12+
),
13+
TextureDescription( label="crate", path="cubes/crate.jpg"),
1014
]

examples/cubes/resources/programs/cubes/cube_textured.glsl

Lines changed: 0 additions & 37 deletions
This file was deleted.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#version 330
2+
3+
out vec4 fragColor;
4+
uniform sampler2D wood;
5+
6+
in vec3 normal;
7+
in vec2 uv;
8+
9+
void main()
10+
{
11+
vec3 dir = vec3(0.0, 0.0, 1.0);
12+
float l = dot(dir, normalize(normal));
13+
fragColor = texture(wood, uv) * min(1.0, l + 0.25);
14+
}
15+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#version 330
2+
3+
in vec3 in_position;
4+
in vec3 in_normal;
5+
in vec2 in_uv;
6+
7+
uniform mat4 m_proj;
8+
uniform mat4 m_mv;
9+
uniform mat3 m_normal;
10+
11+
out vec3 normal;
12+
out vec2 uv;
13+
14+
void main() {
15+
gl_Position = m_proj * m_mv * vec4(in_position, 1.0);
16+
normal = m_normal * in_normal;
17+
uv = in_uv;
18+
}

0 commit comments

Comments
 (0)