File: basic_colors_and_texture.py

package info (click to toggle)
python-moderngl 5.12.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 4,700 kB
  • sloc: python: 15,758; cpp: 14,665; makefile: 14
file content (127 lines) | stat: -rw-r--r-- 4,061 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
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
122
123
124
125
126
127
'''
    Renders a floating, oscillating, 3d islans with lights
'''

import numpy as np
from pyrr import Matrix44

import moderngl
from _example import Example


class ColorsAndTexture(Example):
    gl_version = (3, 3)
    title = "Colors and Textures"

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        self.prog = self.ctx.program(
            vertex_shader='''
                #version 330

                uniform mat4 Mvp;

                in vec3 in_position;
                in vec3 in_normal;
                in vec2 in_texcoord_0;

                out vec3 v_vert;
                out vec3 v_norm;
                out vec2 v_text;

                void main() {
                    gl_Position = Mvp * vec4(in_position, 1.0);
                    v_vert = in_position;
                    v_norm = in_normal;
                    v_text = in_texcoord_0;
                }
            ''',
            fragment_shader='''
                #version 330

                uniform vec3 Light;
                uniform vec3 Color;
                uniform bool UseTexture;
                uniform sampler2D Texture;

                in vec3 v_vert;
                in vec3 v_norm;
                in vec2 v_text;

                out vec4 f_color;

                void main() {
                    float lum = clamp(dot(normalize(Light - v_vert), normalize(v_norm)), 0.0, 1.0) * 0.8 + 0.2;
                    if (UseTexture) {
                        f_color = vec4(texture(Texture, v_text).rgb * lum, 1.0);
                    } else {
                        f_color = vec4(Color * lum, 1.0);
                    }
                }
            ''',
        )

        self.mvp = self.prog['Mvp']
        self.light = self.prog['Light']
        self.color = self.prog['Color']
        self.use_texture = self.prog['UseTexture']

        # Note: This is a fairly manual way to loading and rendering wavefront files.
        # There are easier ways when loading multiple objects in a single obj file.

        # Load obj files
        self.scene_ground = self.load_scene('scene-1-ground.obj')
        self.scene_grass = self.load_scene('scene-1-grass.obj')
        self.scene_billboard = self.load_scene('scene-1-billboard.obj')
        self.scene_holder = self.load_scene('scene-1-billboard-holder.obj')
        self.scene_image = self.load_scene('scene-1-billboard-image.obj')

        # Extract the VAOs from the scene
        self.vao_ground = self.scene_ground.root_nodes[0].mesh.vao.instance(self.prog)
        self.vao_grass = self.scene_grass.root_nodes[0].mesh.vao.instance(self.prog)
        self.vao_billboard = self.scene_billboard.root_nodes[0].mesh.vao.instance(self.prog)
        self.vao_holder = self.scene_holder.root_nodes[0].mesh.vao.instance(self.prog)
        self.vao_image = self.scene_image.root_nodes[0].mesh.vao.instance(self.prog)

        # texture on billboard
        self.texture = self.load_texture_2d('infographic-1.jpg')

    def render(self, time: float, frame_time: float):
        self.ctx.clear(1.0, 1.0, 1.0)
        self.ctx.enable(moderngl.DEPTH_TEST | moderngl.CULL_FACE)

        proj = Matrix44.perspective_projection(45.0, self.aspect_ratio, 0.1, 1000.0)
        lookat = Matrix44.look_at(
            (47.697, -8.147, 24.498),
            (0.0, 0.0, 8.0),
            (0.0, 0.0, 1.0),
        )

        rotate = Matrix44.from_z_rotation(np.sin(time) * 0.5 + 0.2)

        self.use_texture.value = False

        self.light.value = (67.69, -8.14, 52.49)
        self.mvp.write((proj * lookat * rotate).astype('f4'))

        self.color.value = (0.67, 0.49, 0.29)
        self.vao_ground.render()

        self.color.value = (0.46, 0.67, 0.29)
        self.vao_grass.render()

        self.color.value = (1.0, 1.0, 1.0)
        self.vao_billboard.render()

        self.color.value = (0.2, 0.2, 0.2)
        self.vao_holder.render()

        self.use_texture.value = True
        self.texture.use()

        self.vao_image.render()


if __name__ == '__main__':
    ColorsAndTexture.run()