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)
|