-
Notifications
You must be signed in to change notification settings - Fork 53
/
uniform_block.py
121 lines (93 loc) · 3.67 KB
/
uniform_block.py
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
from pyrr import Matrix44
import moderngl
import moderngl_window
from moderngl_window import geometry
class CubeSimple(moderngl_window.WindowConfig):
"""Simply shows two cubes rendered with the same uniform block data"""
title = "Uniform Blocks"
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.cube = geometry.cube(size=(2, 2, 2))
shader_source = {
'vertex_shader': '''
#version 330
in vec3 in_position;
in vec3 in_normal;
uniform vec3 pos_offset;
uniform Projection {
uniform mat4 matrix;
} proj;
uniform View {
uniform mat4 matrix;
} view;
out vec3 normal;
out vec3 pos;
void main() {
vec4 p = view.matrix * vec4(in_position + pos_offset, 1.0);
gl_Position = proj.matrix * p;
mat3 m_normal = transpose(inverse(mat3(view.matrix)));
normal = m_normal * in_normal;
pos = p.xyz;
}
''',
'fragment_shader': '''
#version 330
out vec4 color;
in vec3 normal;
in vec3 pos;
void main() {
float l = dot(normalize(-pos), normalize(normal));
color = vec4(1.0) * (0.25 + abs(l) * 0.75);
}
''',
}
self.prog1 = self.ctx.program(**shader_source)
self.prog1['pos_offset'].value = (1.1, 0, 0)
self.prog2 = self.ctx.program(**shader_source)
self.prog2['pos_offset'].value = (-1.1, 0, 0)
self.vao1 = self.cube.instance(self.prog1)
self.vao2 = self.cube.instance(self.prog2)
self.m_proj = Matrix44.perspective_projection(
75, self.wnd.aspect_ratio, # fov, aspect
0.1, 100.0, # near, far
dtype='f4',
)
proj_uniform1 = self.prog1['Projection']
view_uniform1 = self.prog1['View']
proj_uniform2 = self.prog2['Projection']
view_uniform2 = self.prog2['View']
self.proj_buffer = self.ctx.buffer(reserve=proj_uniform1.size)
self.view_buffer = self.ctx.buffer(reserve=view_uniform1.size)
proj_uniform1.binding = 1
view_uniform1.binding = 2
proj_uniform2.binding = 1
view_uniform2.binding = 2
self.proj_buffer.write(self.m_proj.tobytes())
self.scope1 = self.ctx.scope(
self.ctx.fbo,
enable_only=moderngl.CULL_FACE | moderngl.DEPTH_TEST,
uniform_buffers=[
(self.proj_buffer, 1),
(self.view_buffer, 2),
],
)
self.scope2 = self.ctx.scope(
self.ctx.fbo,
enable_only=moderngl.CULL_FACE | moderngl.DEPTH_TEST,
uniform_buffers=[
(self.proj_buffer, 1),
(self.view_buffer, 2),
],
)
def render(self, time=0.0, frametime=0.0, target: moderngl.Framebuffer = None):
self.ctx.enable_only(moderngl.CULL_FACE | moderngl.DEPTH_TEST)
rotation = Matrix44.from_eulers((time, time, time), dtype='f4')
translation = Matrix44.from_translation((0.0, 0.0, -5.0), dtype='f4')
modelview = translation * rotation
self.view_buffer.write(modelview)
with self.scope1:
self.vao1.render(mode=moderngl.TRIANGLES)
with self.scope2:
self.vao2.render(mode=moderngl.TRIANGLES)
if __name__ == '__main__':
moderngl_window.run_window_config(CubeSimple)