Skip to content

Commit 8fd289d

Browse files
authored
Merge branch 'master' into samplers
2 parents 6bb62ad + 4f8191a commit 8fd289d

File tree

13 files changed

+504
-42
lines changed

13 files changed

+504
-42
lines changed

demosys/geometry/quad.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,32 +21,32 @@ def quad_2d(width, height, xpos=0.0, ypos=0.0) -> VAO:
2121
:param xpos: Center position x
2222
:param ypos: Center position y
2323
"""
24-
pos = context.ctx().buffer(numpy.array([
24+
pos = numpy.array([
2525
xpos - width / 2.0, ypos + height / 2.0, 0.0,
2626
xpos - width / 2.0, ypos - height / 2.0, 0.0,
2727
xpos + width / 2.0, ypos - height / 2.0, 0.0,
2828
xpos - width / 2.0, ypos + height / 2.0, 0.0,
2929
xpos + width / 2.0, ypos - height / 2.0, 0.0,
3030
xpos + width / 2.0, ypos + height / 2.0, 0.0,
31-
], dtype=numpy.float32).tobytes())
31+
], dtype=numpy.float32)
3232

33-
normals = context.ctx().buffer(numpy.array([
33+
normals = numpy.array([
3434
0.0, 0.0, 1.0,
3535
0.0, 0.0, 1.0,
3636
0.0, 0.0, 1.0,
3737
0.0, 0.0, 1.0,
3838
0.0, 0.0, 1.0,
3939
0.0, 0.0, 1.0,
40-
], dtype=numpy.float32).tobytes())
40+
], dtype=numpy.float32)
4141

42-
uvs = context.ctx().buffer(numpy.array([
42+
uvs = numpy.array([
4343
0.0, 1.0,
4444
0.0, 0.0,
4545
1.0, 0.0,
4646
0.0, 1.0,
4747
1.0, 0.0,
4848
1.0, 1.0,
49-
], dtype=numpy.float32).tobytes())
49+
], dtype=numpy.float32)
5050

5151
vao = VAO("geometry:quad", mode=moderngl.TRIANGLES)
5252
vao.buffer(pos, '3f', ["in_position"])

demosys/geometry/sphere.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import numpy
44

55
import moderngl as mlg
6-
from demosys import context
76
from demosys.opengl import VAO
87

98

@@ -58,10 +57,10 @@ def sphere(radius=0.5, sectors=32, rings=16) -> VAO:
5857
indices[i + 5] = (r + 1) * sectors + (s + 1)
5958
i += 6
6059

61-
vbo_vertices = context.ctx().buffer(numpy.array(vertices, dtype=numpy.float32).tobytes())
62-
vbo_normals = context.ctx().buffer(numpy.array(normals, dtype=numpy.float32).tobytes())
63-
vbo_uvs = context.ctx().buffer(numpy.array(uvs, dtype=numpy.float32).tobytes())
64-
vbo_elements = context.ctx().buffer(numpy.array(indices, dtype=numpy.uint32).tobytes())
60+
vbo_vertices = numpy.array(vertices, dtype=numpy.float32)
61+
vbo_normals = numpy.array(normals, dtype=numpy.float32)
62+
vbo_uvs = numpy.array(uvs, dtype=numpy.float32)
63+
vbo_elements = numpy.array(indices, dtype=numpy.uint32)
6564

6665
vao = VAO("sphere", mode=mlg.TRIANGLES)
6766
# VBOs

demosys/resources/__init__.py

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
from .data import data
66
from .data import Data # noqa
77

8-
ON_LOAD_FUNCS = []
9-
108
__all__ = [
119
'shaders',
1210
'textures',
@@ -16,24 +14,55 @@
1614
'Data',
1715
'load',
1816
'count',
17+
'on_load',
1918
'on_loaded',
19+
'loading_complete',
2020
]
2121

2222

23+
class States:
24+
on_loaded_funcs = []
25+
on_load_funcs = []
26+
loaded = False
27+
28+
@classmethod
29+
def sort_callbacks(cls):
30+
cls.on_load_funcs = sorted(cls.on_load_funcs, key=lambda x: x[0])
31+
cls.on_loaded_funcs = sorted(cls.on_loaded_funcs, key=lambda x: x[0])
32+
33+
2334
def load():
35+
States.sort_callbacks()
36+
37+
for func in reversed(States.on_load_funcs):
38+
func[1]()
39+
2440
scenes.load()
2541
shaders.load()
2642
textures.load()
2743
tracks.load()
2844
data.load()
2945

30-
for func in ON_LOAD_FUNCS:
31-
func()
46+
States.loaded = True
47+
for func in reversed(States.on_loaded_funcs):
48+
func[1]()
3249

3350

3451
def count():
3552
return shaders.count + textures.count
3653

3754

38-
def on_loaded(func):
39-
ON_LOAD_FUNCS.append(func)
55+
def loading_complete():
56+
return States.loaded
57+
58+
59+
def on_load(func, priority=0):
60+
States.on_load_funcs.append((priority, func))
61+
62+
63+
def on_loaded(func, priority=0):
64+
if loading_complete():
65+
func()
66+
return
67+
68+
States.on_loaded_funcs.append((priority, func))

demosys/resources/data.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def get(self, name, create=False, cls=Data) -> Data:
6868
key = name.lower()
6969

7070
data_file = self.file_map.get(key)
71-
if not data_file:
71+
if not data_file and create:
7272
data_file = cls(name)
7373
self.files.append(data_file)
7474
self.file_map[key] = data_file

demosys/text/base.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,10 @@ def __init__(self, meta):
5555
self.character_width = self._meta['character_width']
5656
self.atlas_height = self._meta['atlas_height']
5757
self.atlas_width = self._meta['atlas_width']
58+
59+
@property
60+
def char_aspect_wh(self):
61+
return self.character_width / self.character_height
62+
63+
def char_aspect_hw(self):
64+
return self.character_height / self.character_width

demosys/text/renderer2d.py

Lines changed: 59 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,72 @@
1-
from demosys.resources import shaders
2-
from .base import BaseText
1+
import numpy
32

3+
import moderngl
4+
from demosys.opengl import FBO, VAO
5+
from demosys import resources
46

5-
class TextRenderer2D(BaseText):
7+
from .writer2d import TextWriter2D
68

7-
def __init__(self, area, size=0.1, text=""):
9+
10+
def on_load():
11+
resources.shaders.get('demosys/text/view_renderer_texture.glsl', create=True)
12+
13+
14+
resources.on_load(on_load, priority=100)
15+
16+
17+
class TextRenderer2D(TextWriter2D):
18+
19+
def __init__(self, area, text_lines=None, texture_height=64):
820
"""
921
:param area: (x, y) Text area size (number of characters)
1022
:param size: Text size
1123
:param text: Initial text
1224
"""
13-
super().__init__(text)
14-
self.area = area
15-
self.size = size
16-
self._text = text
25+
self._texture_height = texture_height
26+
self._texture_width = 0
27+
28+
self._quad = self._create_vao()
29+
self._quad_shader = resources.shaders.get('demosys/text/view_renderer_texture.glsl', create=True)
30+
self._fbo = None
31+
super().__init__(area, text_lines=text_lines)
32+
33+
def _post_load(self):
34+
print("TextRenderer2D._post_load")
35+
super()._post_load()
36+
self._texture_width = int(
37+
round(self._meta.char_aspect_wh * self._texture_height * self.area[0] / self.area[1], 0)
38+
)
1739

18-
self.fbo = None
19-
self.vao = None
20-
self.shader = shaders.get('demosys/text/textwriter.glsl', create=True)
40+
self.aspect_ratio = self._texture_width / self._texture_height
41+
self._fbo = FBO.create((self._texture_width, self._texture_height))
2142

2243
@property
23-
def text(self):
24-
return self._text
44+
def texture(self):
45+
return self._fbo.color_buffers[0]
46+
47+
def render(self):
48+
self._fbo.clear()
49+
with self._fbo:
50+
super().draw((0.0, 0.0), size=2.0 / self.area[1])
51+
52+
def draw(self, pos, size=1.0):
53+
self._fbo.color_buffers[0].use(location=0)
54+
self._quad_shader.uniform("texture0", 0)
55+
self._quad_shader.uniform("yscale", self._texture_height / self._texture_width)
56+
self._quad_shader.uniform("pos", pos)
57+
self._quad_shader.uniform("size", size)
58+
self._quad.draw(self._quad_shader)
2559

26-
@text.setter
27-
def text(self, value):
28-
self._text = value
60+
def _create_vao(self):
61+
data = numpy.array([
62+
0.0, -2.0, 0.0, 0.0, 0.0,
63+
0.0, 0.0, 0.0, 0.0, 1.0,
64+
2.0, 0.0, 0.0, 1.0, 1.0,
65+
0.0, -2.0, 0.0, 0.0, 0.0,
66+
2.0, 0.0, 0.0, 1.0, 1.0,
67+
2.0, -2.0, 0.0, 1.0, 0.0,
68+
], dtype=numpy.float32)
2969

30-
def draw(self):
31-
pass
70+
vao = VAO("textrenderer", mode=moderngl.TRIANGLES)
71+
vao.buffer(data, '3f 2f', ['in_position', 'in_uv'])
72+
return vao
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#version 330
2+
3+
#if defined VERTEX_SHADER
4+
5+
in vec3 in_position;
6+
in vec2 in_uv;
7+
8+
uniform vec2 pos;
9+
uniform float size;
10+
uniform float yscale;
11+
12+
out vec2 uv;
13+
//
14+
void main() {
15+
vec3 p = vec3(
16+
(in_position.x * size) - 1.0 + pos[0],
17+
(in_position.y * size) * yscale * 2.0 + 1.0 + pos[1],
18+
0.0
19+
);
20+
gl_Position = vec4(p, 1.0);
21+
uv = in_uv;
22+
}
23+
24+
#elif defined FRAGMENT_SHADER
25+
26+
out vec4 fragColor;
27+
uniform sampler2D texture0;
28+
in vec2 uv;
29+
30+
void main() {
31+
fragColor = texture(texture0, uv);
32+
}
33+
34+
#endif

demosys/text/writer2d.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,21 @@
22

33
import moderngl
44
from demosys.opengl import VAO, TextureArray
5-
from demosys.resources import data, shaders, textures
5+
from demosys import resources
66
from pyrr import matrix44
77

88
from .base import BaseText, Meta
99

1010

11+
def on_load():
12+
resources.textures.get('demosys/text/VeraMono.png', cls=TextureArray, layers=190, create=True)
13+
resources.shaders.get('demosys/text/textwriter2d.glsl', create=True)
14+
resources.data.get('demosys/text/meta.json', create=True)
15+
16+
17+
resources.on_load(on_load, priority=100)
18+
19+
1120
class TextWriter2D(BaseText):
1221

1322
def __init__(self, area, text_lines=None, aspect_ratio=1.0):
@@ -25,13 +34,13 @@ def __init__(self, area, text_lines=None, aspect_ratio=1.0):
2534
self.aspect_ratio = aspect_ratio
2635

2736
self._vao = None
28-
self._texture = textures.get('demosys/text/VeraMono.png', cls=TextureArray, layers=190, create=True)
29-
self._shader = shaders.get('demosys/text/textwriter2d.glsl', create=True)
30-
self._config = data.get('demosys/text/meta.json', create=True)
37+
self._texture = resources.textures.get('demosys/text/VeraMono.png', cls=TextureArray, layers=190, create=True)
38+
self._shader = resources.shaders.get('demosys/text/textwriter2d.glsl', create=True)
39+
self._config = resources.data.get('demosys/text/meta.json', create=True)
3140

3241
self._string_buffer = None
3342

34-
data.on_loaded(self._post_load)
43+
resources.on_loaded(self._post_load, priority=99)
3544

3645
def _post_load(self):
3746
"""Parse font metadata after resources are loaded"""

examples/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,16 @@ python manage.py runeffect examples.textwriter
8484
```
8585

8686
![screenshot](https://raw.githubusercontent.com/Contraz/demosys-py/master/examples/images/textwriter.png)
87+
88+
Text Renderer
89+
-------------
90+
91+
Example loading a text file displaying it on the screen. The text is rendered to a texture at initialization.
92+
We simply display the texture each frame. We are limiting the texture height to 8k in this example.
93+
94+
```bash
95+
python manage.py runeffect examples.textrenderer
96+
```
97+
98+
![screenshot](https://raw.githubusercontent.com/Contraz/demosys-py/master/examples/images/textrenderer.png)
99+

examples/images/textrenderer.png

743 KB
Loading

0 commit comments

Comments
 (0)