/
FaDaQ
/
ModernGL-Demo
Обзор
Документация
Войти
/
FaDaQ
/
ModernGL-Demo
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
cube.py
207 строк
7 KB
FaDaQ
create: camera.py, cube.py, instanced_draw.py, label.py, settings.json, transform.py, fluid.png, grass.png, meteor.png, planks.png, stone.jpg
02 июн 2026, 14:37
Верифицирован
02 июн 2026, 14:37
db0a0b4
Код
Авторство
О чём код?
import numpy as np import moderngl as mgl from pyglm import glm, glm_typing import math from PIL import Image from transform import Transform from camera import Camera3D # это было удобно во время разработки, чтобы считывать шейдер из отдельного файла # def read_file(path): # buffer = "" # with open(path, "r", encoding="utf-8") as file: # buffer = file.read() # # return buffer class Cube3D: def __init__(self, gl_context: mgl.Context, image_path: str, position: glm.vec3 = glm.vec3(0, 0, 0), rotation: glm.vec3 = glm.vec3(0, 0, 0), scale: glm.vec3 = glm.vec3(1, 1, 1)): self.gl = gl_context image = Image.open(image_path).convert("RGBA") self.texture = self.gl.texture(image.size, 4, image.tobytes()) vbo = self.gl.buffer(self.__cube_vertices) ibo = self.gl.buffer(self.__cube_indices) if not self.__shader_single: self.__shader_single = self.gl.program( vertex_shader=""" #version 460 core in vec3 inPos; in vec2 inUV; out vec2 UV; uniform mat4 projection; uniform mat4 view; uniform mat4 modelMat; void main() { gl_Position = projection * view * modelMat * vec4(inPos, 1.0); UV = inUV; } """, fragment_shader=""" #version 460 core in vec2 UV; out vec4 fragColor; uniform sampler2D aTexture; void main() { fragColor = texture(aTexture, UV); } """ ) if not self.__shader_instanced: self.__shader_instanced = self.gl.program( vertex_shader= """ #version 460 core in vec3 inPos; in vec2 inUV; out vec2 UV; struct Instance { mat4 model; }; layout (std430, binding = 1) buffer InstanceData { Instance instances[]; }; uniform mat4 projection; uniform mat4 view; void main() { Instance instance = instances[gl_InstanceID]; gl_Position = projection * view * instance.model * vec4(inPos, 1.0); UV = inUV; } """, fragment_shader= """ #version 460 core in vec2 UV; out vec4 fragColor; uniform sampler2D aTexture; void main() { fragColor = texture(aTexture, UV); } """ ) self.vao = self.gl.vertex_array( self.__shader_single, [ (vbo, "3f 2f", "inPos", "inUV") ], index_buffer=ibo ) self.vao_instanced = self.gl.vertex_array( self.__shader_instanced, [ (vbo, "3f 2f", "inPos", "inUV") ], index_buffer=ibo ) self.transform = Transform(position, scale, rotation) def draw(self, camera: Camera3D = None): self.texture.use(1) self.__shader_single["aTexture"] = 1 self.__shader_single["modelMat"].write(np.array(self.transform.mat, dtype=np.float32).tobytes()) self.__shader_single["view"].write(np.array(camera.view if camera else glm.mat4(1), dtype=np.float32).tobytes()) self.__shader_single["projection"].write(np.array(camera.projection if camera else glm.mat4(), dtype=np.float32).tobytes()) self.vao.render(mgl.TRIANGLES) def draw_instanced(self, camera: Camera3D, ssbo: mgl.Buffer, count: int = 1): self.texture.use(1) self.__shader_instanced["aTexture"] = 1 self.__shader_instanced["view"].write(np.array(camera.view if camera else glm.mat4(1), dtype=np.float32).tobytes()) self.__shader_instanced["projection"].write( np.array(camera.projection if camera else glm.mat4(), dtype=np.float32).tobytes()) ssbo.bind_to_storage_buffer(1) self.vao_instanced.render(mgl.TRIANGLES, -1, 0, count) __shader_single = None __shader_instanced = None __cube_vertices = np.array([ # грань -Z (задняя): 4 вершины: (x,y,z, u,v) -0.5, -0.5, -0.5, 0.0, 0.0, 0.5, -0.5, -0.5, 1.0, 0.0, 0.5, 0.5, -0.5, 1.0, 1.0, -0.5, 0.5, -0.5, 0.0, 1.0, # грань +Z (передняя) -0.5, -0.5, 0.5, 0.0, 0.0, 0.5, -0.5, 0.5, 1.0, 0.0, 0.5, 0.5, 0.5, 1.0, 1.0, -0.5, 0.5, 0.5, 0.0, 1.0, # грань -Y (нижняя) -0.5, -0.5, -0.5, 0.0, 0.0, -0.5, -0.5, 0.5, 1.0, 0.0, -0.5, 0.5, 0.5, 1.0, 1.0, -0.5, 0.5, -0.5, 0.0, 1.0, # грань +Y (верхняя) 0.5, 0.5, 0.5, 0.0, 0.0, 0.5, 0.5, -0.5, 1.0, 0.0, 0.5, -0.5, -0.5, 1.0, 1.0, 0.5, -0.5, 0.5, 0.0, 1.0, # грань -X (левая) -0.5, -0.5, -0.5, 0.0, 0.0, 0.5, -0.5, -0.5, 1.0, 0.0, 0.5, -0.5, 0.5, 1.0, 1.0, -0.5, -0.5, 0.5, 0.0, 1.0, # грань +X (правая) 0.5, 0.5, 0.5, 0.0, 0.0, -0.5, 0.5, 0.5, 1.0, 0.0, -0.5, 0.5, -0.5, 1.0, 1.0, 0.5, 0.5, -0.5, 0.0, 1.0, ], dtype=np.float32) __cube_indices = np.array([ # Грань -Z (Задняя) 0, 1, 2, 2, 3, 0, # Грань +Z (Передняя) 4, 5, 6, 6, 7, 4, # Грань -Y (Нижняя) 8, 9, 10, 10, 11, 8, # Грань +Y (Верхняя) 12, 13, 14, 14, 15, 12, # Грань -X (Левая) 16, 17, 18, 18, 19, 16, # Грань +X (Правая) 20, 21, 22, 22, 23, 20, ], dtype=np.uint32)