File: text_2d.py

package info (click to toggle)
python-moderngl-window 2.4.6-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 69,220 kB
  • sloc: python: 11,387; makefile: 21
file content (94 lines) | stat: -rw-r--r-- 2,694 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import numpy
from pyrr import matrix44

from pathlib import Path

import moderngl
from moderngl_window.opengl.vao import VAO
from moderngl_window import resources
from moderngl_window.meta import (
    DataDescription,
    TextureDescription,
    ProgramDescription,
)

from .base import BaseText, FontMeta

resources.register_dir(Path(__file__).parent.resolve())


class TextWriter2D(BaseText):
    """Simple monspaced bitmapped text renderer"""

    def __init__(self):
        super().__init__()

        meta = FontMeta(resources.data.load(
            DataDescription(path="bitmapped/text/meta.json")
        ))
        self._texture = resources.textures.load(
            TextureDescription(
                path="bitmapped/textures/VeraMono.png",
                kind="array",
                mipmap=True,
                layers=meta.characters,
            )
        )
        self._program = resources.programs.load(
            ProgramDescription(path="bitmapped/programs/text_2d.glsl")
        )

        self._init(meta)

        self._string_buffer = self.ctx.buffer(reserve=1024 * 4)
        self._string_buffer.clear(chunk=b'\32')
        pos = self.ctx.buffer(data=bytes([0] * 4 * 3))

        self._vao = VAO("textwriter", mode=moderngl.POINTS)
        self._vao.buffer(pos, '3f', 'in_position')
        self._vao.buffer(self._string_buffer, '1u/i', 'in_char_id')

        self._text: str = None

    @property
    def text(self) -> str:
        return self._text

    @text.setter
    def text(self, value: str):
        self._text = value
        self._string_buffer.orphan(size=len(value) * 4)
        self._string_buffer.clear(chunk=b'\32')
        self._write(value)

    def _write(self, text: str):
        self._string_buffer.clear(chunk=b'\32')

        self._string_buffer.write(
            numpy.fromiter(
                self._translate_string(text),
                dtype=numpy.uint32,
            )
        )

    def draw(self, pos, length=-1, size=24.0):
        # Calculate ortho projection based on viewport
        vp = self.ctx.fbo.viewport
        w, h = vp[2], vp[3]
        projection = matrix44.create_orthogonal_projection_matrix(
            0,  # left
            w,  # right
            0,  # bottom
            h,  # top
            1.0,  # near
            -1.0,  # far
            dtype=numpy.float32,
        )

        self._texture.use(location=0)
        self._program["m_proj"].write(projection)
        self._program["text_pos"].value = pos
        self._program["font_texture"].value = 0
        self._program["char_size"].value = self._meta.char_aspect_wh * size, size

        self._vao.render(self._program, instances=len(self._text))