File: external_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 (111 lines) | stat: -rw-r--r-- 3,367 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
import math
import os
import sys

import glm
import moderngl
import pygame
from objloader import Obj
from PIL import Image

os.environ['SDL_WINDOWS_DPI_AWARENESS'] = 'permonitorv2'

pygame.init()
pygame.display.set_mode((800, 800), flags=pygame.OPENGL | pygame.DOUBLEBUF, vsync=True)


class Scene:
    def __init__(self):
        self.ctx = moderngl.get_context()

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

                uniform mat4 camera;

                layout (location = 0) in vec3 in_vertex;
                layout (location = 1) in vec3 in_normal;
                layout (location = 2) in vec2 in_uv;

                out vec3 v_vertex;
                out vec3 v_normal;
                out vec2 v_uv;

                void main() {
                    v_vertex = in_vertex;
                    v_normal = in_normal;
                    v_uv = in_uv;

                    gl_Position = camera * vec4(v_vertex, 1.0);
                }
            ''',
            fragment_shader='''
                #version 330 core

                uniform sampler2D Texture;
                uniform vec3 light_direction;

                in vec3 v_vertex;
                in vec3 v_normal;
                in vec2 v_uv;

                layout (location = 0) out vec4 out_color;

                void main() {
                    float lum = max(dot(normalize(v_normal), normalize(light_direction)), 0.0) * 0.5 + 0.5;
                    out_color = texture(Texture, v_uv) * lum;
                }
            ''',
        )

        self.texture = self.load_texture('examples/data/textures/crate.png')
        self.vertex_buffer = self.load_model('examples/data/models/crate.obj')

        self.sampler = self.ctx.sampler(texture=self.texture)
        self.vertex_array = self.ctx.vertex_array(self.program, [
            (self.vertex_buffer, '3f 3f 2f', 'in_vertex', 'in_normal', 'in_uv'),
        ])

    def load_model(self, path):
        obj = Obj.open(path)
        return self.ctx.buffer(obj.pack('vx vy vz nx ny nz tx ty'))

    def load_texture(self, path):
        from OpenGL import GL
        img = Image.open(path).convert('RGBA')
        width, height = img.size
        pixels = img.tobytes()
        texture = GL.glGenTextures(1)
        GL.glActiveTexture(GL.GL_TEXTURE0)
        GL.glBindTexture(GL.GL_TEXTURE_2D, texture)
        GL.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA8, width, height, 0, GL.GL_RGBA, GL.GL_UNSIGNED_BYTE, pixels)
        return self.ctx.external_texture(texture, (width, height), 4, 0, 'f1')

    def camera_matrix(self):
        now = pygame.time.get_ticks() / 1000.0
        eye = (math.cos(now) * 3.0, math.sin(now) * 3.0, 1.75)
        proj = glm.perspective(45.0, 1.0, 0.1, 1000.0)
        look = glm.lookAt(eye, (0.0, 0.0, 0.5), (0.0, 0.0, 1.0))
        return proj * look

    def render(self):
        self.ctx.clear()
        self.ctx.enable_only(self.ctx.DEPTH_TEST)
        self.program['light_direction'] = (1.0, 2.0, 3.0)
        self.program['camera'].write(self.camera_matrix())
        self.sampler.use()
        self.vertex_array.render()


scene = Scene()

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()

    scene.render()

    pygame.display.flip()