Skip to content

Commit 6bb62ad

Browse files
authored
Merge branch 'master' into samplers
2 parents 4ca1981 + 86670e8 commit 6bb62ad

File tree

12 files changed

+399
-117
lines changed

12 files changed

+399
-117
lines changed

demosys/context/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,4 +105,4 @@ def set_default_viewport(self):
105105

106106
# How much positive or negative y padding
107107
blank_space = self.buffer_height - expected_height
108-
self.ctx.screen.viewport = (0, blank_space // 2, self.buffer_width, expected_height)
108+
self.fbo.viewport = (0, blank_space // 2, self.buffer_width, expected_height)

demosys/context/glfw.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ def __init__(self):
6666
# Create mederngl context from existing context
6767
self.ctx = moderngl.create_context()
6868
self.fbo = FBO()
69+
self.fbo.ctx = self.ctx
6970
self.fbo.fbo = self.ctx.screen
7071
self.fbo.default_framebuffer = True
7172
context.WINDOW = self

demosys/context/headless.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import moderngl
2-
from demosys.conf import settings
3-
from demosys.conf import ImproperlyConfigured
2+
from demosys import context
3+
from demosys.conf import ImproperlyConfigured, settings
44
from demosys.opengl.fbo import FBO
55

66
from .base import Window
@@ -19,7 +19,16 @@ def __init__(self):
1919

2020
self._close = False
2121
self.ctx = moderngl.create_standalone_context()
22-
self.screenbuffer = FBO.create((self.width, self.height), depth=True)
22+
23+
self.fbo = FBO()
24+
self.fbo.ctx = self.ctx
25+
self.fbo.fbo = self.ctx.framebuffer(
26+
color_attachments=self.ctx.texture((self.width, self.height), 4),
27+
depth_attachment=self.ctx.depth_texture((self.width, self.height)),
28+
)
29+
# self.fbo.default_framebuffer = True
30+
context.WINDOW = self
31+
self.set_default_viewport()
2332

2433
def draw(self, current_time, frame_time):
2534
super().draw(current_time, frame_time)
@@ -28,7 +37,7 @@ def draw(self, current_time, frame_time):
2837
self.close()
2938

3039
def use(self):
31-
self.screenbuffer.use(stack=False)
40+
self.fbo.use(stack=False)
3241

3342
def should_close(self):
3443
return self._close

demosys/text/base.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,13 @@ def __init__(self):
1919
def draw(self, *args, **kwargs):
2020
raise NotImplementedError()
2121

22-
def _translate_data(self, data):
23-
"""Translate character bytes into texture positions"""
24-
return [self._meta.characters - 1 - self._ct[c] for c in data]
22+
def _translate_string(self, data, length):
23+
"""Translate string into character texture positions"""
24+
for index, char in enumerate(data):
25+
if index == length:
26+
break
27+
28+
yield self._meta.characters - 1 - self._ct[char]
2529

2630
def _init(self, meta: 'Meta'):
2731
self._meta = meta

demosys/text/resources/shaders/demosys/text/textwriter2d.glsl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@ in vec3 in_position;
66
in uint in_char_id;
77

88
uniform vec2 char_size;
9+
uniform float line_length;
910

1011
out uint vs_char_id;
1112

1213
void main() {
13-
gl_Position = vec4(in_position + vec3(gl_InstanceID * char_size.x, 0.0, 0.0), 1.0);
14+
float ypos = int(gl_InstanceID / line_length) * char_size.y;
15+
float xpos = mod(gl_InstanceID, line_length) * char_size.x;
16+
gl_Position = vec4(in_position + vec3(xpos, -ypos, 0.0), 1.0);
1417
vs_char_id = in_char_id;
1518
}
1619

demosys/text/resources/shaders/demosys/text/textwriter3d.glsl

Lines changed: 0 additions & 78 deletions
This file was deleted.

demosys/text/writer2d.py

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,17 @@
1010

1111
class TextWriter2D(BaseText):
1212

13-
def __init__(self, area, text="", aspect_ratio=1.0):
13+
def __init__(self, area, text_lines=None, aspect_ratio=1.0):
1414
"""
1515
:param area: (x, y) Text area size (number of characters)
1616
:param size: Text size
17-
:param text: Initial text
17+
:param text: Initial text lines
1818
"""
1919
super().__init__()
2020
self.area = area
21-
self._text = text.encode('latin1')
21+
self._text_lines = text_lines
2222

23-
self.projection_bytes = None
23+
self._projection_bytes = None
2424
self._aspect_ratio = 1.0
2525
self.aspect_ratio = aspect_ratio
2626

@@ -29,29 +29,34 @@ def __init__(self, area, text="", aspect_ratio=1.0):
2929
self._shader = shaders.get('demosys/text/textwriter2d.glsl', create=True)
3030
self._config = data.get('demosys/text/meta.json', create=True)
3131

32+
self._string_buffer = None
33+
3234
data.on_loaded(self._post_load)
3335

3436
def _post_load(self):
3537
"""Parse font metadata after resources are loaded"""
3638
self._init(Meta(self._config.data))
3739

38-
self._string_data = self._translate_data(self._text)
39-
self._string_buffer = self.ctx.buffer(
40-
data=numpy.array(self._string_data, dtype=numpy.uint32).tobytes()
41-
)
42-
self._pos = self.ctx.buffer(data=bytes([0] * 4 * 3))
40+
self._string_buffer = self.ctx.buffer(reserve=self.area[0] * 4 * self.area[1])
41+
self._string_buffer.clear(chunk=b'\32')
42+
pos = self.ctx.buffer(data=bytes([0] * 4 * 3))
4343

4444
self._vao = VAO("textwriter", mode=moderngl.POINTS)
45-
self._vao.buffer(self._pos, '3f', 'in_position')
45+
self._vao.buffer(pos, '3f', 'in_position')
4646
self._vao.buffer(self._string_buffer, '1u', 'in_char_id', per_instance=True)
4747

48+
self.text_lines = self._text_lines
49+
4850
@property
49-
def text(self):
50-
return self._text
51+
def text_lines(self):
52+
return self._text_lines
5153

52-
@text.setter
53-
def text(self, value):
54-
self._text = value
54+
@text_lines.setter
55+
def text_lines(self, value):
56+
self._text_lines = value
57+
58+
for i, line in enumerate(self._text_lines):
59+
self.set_text_line(i, line)
5560

5661
@property
5762
def aspect_ratio(self):
@@ -60,7 +65,7 @@ def aspect_ratio(self):
6065
@aspect_ratio.setter
6166
def aspect_ratio(self, value):
6267
self._aspect_ratio = value
63-
self.projection_bytes = matrix44.create_orthogonal_projection_matrix(
68+
self._projection_bytes = matrix44.create_orthogonal_projection_matrix(
6469
-self.aspect_ratio, # left
6570
self.aspect_ratio, # right
6671
-1.0, # bottom
@@ -70,19 +75,41 @@ def aspect_ratio(self, value):
7075
dtype=numpy.float32,
7176
).tobytes()
7277

73-
def draw(self, pos, size=1.0):
78+
def set_text_line(self, line, text):
79+
if line >= self.area[1]:
80+
return
81+
82+
self._string_buffer.clear(size=self.area[0] * 4, offset=self.area[0] * 4 * line, chunk=b'\32')
83+
84+
self._string_buffer.write(
85+
numpy.fromiter(
86+
self._translate_string(text.encode('iso-8859-1'), self.area[0]),
87+
dtype=numpy.uint32
88+
).tobytes(),
89+
offset=(self.area[0] * 4) * line,
90+
)
91+
92+
def draw(self, pos, length=-1, size=1.0):
93+
if length < 0:
94+
length = self.area[0] * self.area[1]
95+
elif length > self.area[0] * self.area[1]:
96+
length = self.area[0] * self.area[1]
97+
7498
csize = (
7599
self._meta.character_width / self._meta.character_height * size,
76100
1.0 * size,
77101
)
102+
78103
cpos = (
79104
pos[0] - self._aspect_ratio + csize[0] / 2,
80105
-pos[1] + 1.0 - csize[1] / 2,
81106
)
82107

83108
self._texture.use(location=0)
84-
self._shader.uniform("m_proj", self.projection_bytes)
109+
self._shader.uniform("m_proj", self._projection_bytes)
85110
self._shader.uniform("text_pos", cpos)
86111
self._shader.uniform("font_texture", 0)
87112
self._shader.uniform("char_size", csize)
88-
self._vao.draw(self._shader, instances=len(self._string_data))
113+
self._shader.uniform("line_length", self.area[0])
114+
115+
self._vao.draw(self._shader, instances=length)

demosys/view/controller.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,6 @@ def run(manager=None):
6262

6363
# Main loop
6464
frame_time = 60.0 / 1000.0
65-
# time_start = glfw.get_time()
6665
time_start = time.time()
6766
prev_time = window.timer.get_time()
6867

examples/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,16 @@ python manage.py runeffect examples.sponza
7171
```
7272

7373
![screenshot](https://raw.githubusercontent.com/Contraz/demosys-py/master/examples/images/sponza.png)
74+
75+
Text Writer
76+
-----------
77+
78+
Example loading a text file displaying it on the screen. The text is drawn using instanced rendering
79+
were each instance is a character in the file. This may not be the most efficient way for drivers
80+
emulating instancing. Text renderer (render to texture) is an alternative.
81+
82+
```bash
83+
python manage.py runeffect examples.textwriter
84+
```
85+
86+
![screenshot](https://raw.githubusercontent.com/Contraz/demosys-py/master/examples/images/textwriter.png)

examples/images/textwriter.png

421 KB
Loading

0 commit comments

Comments
 (0)