blob: 61b6aafd882ce7cbcd94d69d419b8d5a6af2fb52 (
plain)
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
|
import typing
if typing.TYPE_CHECKING:
from ..app import TxtGameApp
class Shader:
"""Wrapper class for a GL program"""
UNIFORMS: typing.Dict[str, str] = dict()
VERTEX_PATH: str
FRAGMENT_PATH: str
def __init__(self, app: 'TxtGameApp'):
self.app = app
self._prog_id = self.app.shaders.load_shaders(self.VERTEX_PATH, self.FRAGMENT_PATH)
self._is_bound = 0
self.uniform_locations = {}
self._fill_uniforms()
def _fill_uniforms(self):
with self:
for prop_name, shader_name in self.UNIFORMS.items():
self.uniform_locations[prop_name] = \
self.app.shaders.get_uniform_location(self._prog_id, shader_name)
def __getattr__(self, item):
if item in self.uniform_locations:
return self.uniform_locations[item]
raise AttributeError("Shader '%s' has no attribute or uniform named %s" % (type(self).__name__, item))
def _require_bound(self, required=False):
assert self._is_bound > 0 or not required
return self
def get_uniform_location(self, name: str):
return self.uniform_locations[name]
def __enter__(self):
self._is_bound += 1
if self._is_bound == 1:
self.app.shaders.bind_shader(self._prog_id)
def __exit__(self, exc_type, exc_val, exc_tb):
self._is_bound -= 1
if self._is_bound == 0:
self.app.shaders.bind_shader(0)
def __repr__(self):
return '<Shader prog_id=%d uniforms=%r>' % (self._prog_id, self.uniform_locations)
|