basilisk-engine 0.1.2__py3-none-any.whl → 0.1.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of basilisk-engine might be problematic. Click here for more details.
- basilisk/__init__.py +11 -11
- basilisk/bsk_assets/cube.obj +48 -48
- basilisk/collisions/broad/broad_aabb.py +102 -102
- basilisk/collisions/broad/broad_bvh.py +137 -137
- basilisk/collisions/collider.py +95 -83
- basilisk/collisions/collider_handler.py +225 -228
- basilisk/collisions/narrow/contact_manifold.py +90 -90
- basilisk/collisions/narrow/dataclasses.py +33 -27
- basilisk/collisions/narrow/deprecated.py +46 -46
- basilisk/collisions/narrow/epa.py +91 -91
- basilisk/collisions/narrow/gjk.py +66 -66
- basilisk/collisions/narrow/graham_scan.py +24 -24
- basilisk/collisions/narrow/helper.py +29 -29
- basilisk/collisions/narrow/line_intersections.py +106 -106
- basilisk/collisions/narrow/sutherland_hodgman.py +75 -75
- basilisk/config.py +2 -2
- basilisk/draw/draw.py +100 -100
- basilisk/draw/draw_handler.py +180 -210
- basilisk/draw/font_renderer.py +28 -28
- basilisk/engine.py +195 -195
- basilisk/generic/abstract_bvh.py +15 -15
- basilisk/generic/abstract_custom.py +133 -133
- basilisk/generic/collisions.py +70 -70
- basilisk/generic/input_validation.py +67 -28
- basilisk/generic/math.py +6 -6
- basilisk/generic/matrices.py +33 -33
- basilisk/generic/meshes.py +72 -72
- basilisk/generic/quat.py +137 -137
- basilisk/generic/quat_methods.py +7 -7
- basilisk/generic/raycast_result.py +24 -0
- basilisk/generic/vec3.py +143 -143
- basilisk/input/mouse.py +61 -59
- basilisk/mesh/cube.py +33 -33
- basilisk/mesh/mesh.py +230 -230
- basilisk/mesh/mesh_from_data.py +132 -132
- basilisk/mesh/model.py +271 -271
- basilisk/mesh/narrow_aabb.py +89 -89
- basilisk/mesh/narrow_bvh.py +91 -91
- basilisk/mesh/narrow_primative.py +23 -23
- basilisk/nodes/helper.py +29 -0
- basilisk/nodes/node.py +681 -617
- basilisk/nodes/node_handler.py +95 -118
- basilisk/particles/particle_handler.py +63 -54
- basilisk/particles/particle_renderer.py +87 -87
- basilisk/physics/impulse.py +112 -112
- basilisk/physics/physics_body.py +43 -43
- basilisk/physics/physics_engine.py +35 -35
- basilisk/render/batch.py +86 -86
- basilisk/render/camera.py +204 -199
- basilisk/render/chunk.py +99 -99
- basilisk/render/chunk_handler.py +154 -154
- basilisk/render/frame.py +181 -181
- basilisk/render/image.py +75 -75
- basilisk/render/image_handler.py +122 -122
- basilisk/render/light.py +96 -96
- basilisk/render/light_handler.py +58 -58
- basilisk/render/material.py +219 -219
- basilisk/render/material_handler.py +135 -135
- basilisk/render/shader.py +109 -109
- basilisk/render/shader_handler.py +79 -79
- basilisk/render/sky.py +120 -120
- basilisk/scene.py +250 -210
- basilisk/shaders/batch.frag +276 -276
- basilisk/shaders/batch.vert +115 -115
- basilisk/shaders/draw.frag +21 -21
- basilisk/shaders/draw.vert +21 -21
- basilisk/shaders/filter.frag +22 -22
- basilisk/shaders/frame.frag +12 -12
- basilisk/shaders/frame.vert +13 -13
- basilisk/shaders/geometry.frag +8 -8
- basilisk/shaders/geometry.vert +41 -41
- basilisk/shaders/normal.frag +59 -59
- basilisk/shaders/normal.vert +96 -96
- basilisk/shaders/particle.frag +71 -71
- basilisk/shaders/particle.vert +84 -84
- basilisk/shaders/sky.frag +9 -9
- basilisk/shaders/sky.vert +13 -13
- {basilisk_engine-0.1.2.dist-info → basilisk_engine-0.1.3.dist-info}/METADATA +45 -38
- basilisk_engine-0.1.3.dist-info/RECORD +97 -0
- {basilisk_engine-0.1.2.dist-info → basilisk_engine-0.1.3.dist-info}/WHEEL +1 -1
- basilisk_engine-0.1.2.dist-info/RECORD +0 -95
- {basilisk_engine-0.1.2.dist-info → basilisk_engine-0.1.3.dist-info}/top_level.txt +0 -0
|
@@ -1,136 +1,136 @@
|
|
|
1
|
-
import moderngl as mgl
|
|
2
|
-
from ..render.image_handler import ImageHandler
|
|
3
|
-
from ..render.material import Material
|
|
4
|
-
import numpy as np
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class MaterialHandler():
|
|
8
|
-
engine: ...
|
|
9
|
-
"""Back reference to the parent engine"""
|
|
10
|
-
scene: ...
|
|
11
|
-
"""Back reference to the parent scene"""
|
|
12
|
-
ctx: mgl.Context
|
|
13
|
-
"""Back reference to the parent context"""
|
|
14
|
-
materials: list[Material]
|
|
15
|
-
"""List containing all the materials in the scene"""
|
|
16
|
-
data_texture: mgl.Texture
|
|
17
|
-
"""ModernGL texture containing all the material data for materials in the scene"""
|
|
18
|
-
|
|
19
|
-
def __init__(self, scene) -> None:
|
|
20
|
-
"""
|
|
21
|
-
Handles all the materials introduced to a scene.
|
|
22
|
-
Writes material information to the GPU
|
|
23
|
-
"""
|
|
24
|
-
|
|
25
|
-
# Back references
|
|
26
|
-
self.scene = scene
|
|
27
|
-
self.engine = scene.engine
|
|
28
|
-
self.ctx = scene.engine.ctx
|
|
29
|
-
|
|
30
|
-
# Initialize data
|
|
31
|
-
self.materials = []
|
|
32
|
-
self.data_texture = None
|
|
33
|
-
self.set_base()
|
|
34
|
-
|
|
35
|
-
self.image_handler = ImageHandler(scene)
|
|
36
|
-
|
|
37
|
-
def add(self, material: Material) -> None:
|
|
38
|
-
"""
|
|
39
|
-
Adds the given material to the handler if it is not already present
|
|
40
|
-
"""
|
|
41
|
-
|
|
42
|
-
write = False
|
|
43
|
-
|
|
44
|
-
if isinstance(material, Material): material = [material]
|
|
45
|
-
|
|
46
|
-
for mtl in material:
|
|
47
|
-
# Check that the material is not already in the scene
|
|
48
|
-
if mtl in self.materials: continue
|
|
49
|
-
# Update the material's handler
|
|
50
|
-
mtl.material_handler = self
|
|
51
|
-
# Add images
|
|
52
|
-
if mtl.texture: self.image_handler.add(mtl.texture)
|
|
53
|
-
if mtl.normal: self.image_handler.add(mtl.normal)
|
|
54
|
-
|
|
55
|
-
# Add the material
|
|
56
|
-
self.materials.append(mtl)
|
|
57
|
-
|
|
58
|
-
write = True
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
# Write materials
|
|
62
|
-
if write: self.write(regenerate=True)
|
|
63
|
-
|
|
64
|
-
def generate_material_texture(self) -> None:
|
|
65
|
-
"""
|
|
66
|
-
Generates the texture that is used to write material data to the GPU
|
|
67
|
-
"""
|
|
68
|
-
|
|
69
|
-
# Check that there are materials to write
|
|
70
|
-
if len(self.materials) == 0: return
|
|
71
|
-
|
|
72
|
-
# Release existing data texture
|
|
73
|
-
if self.data_texture: self.data_texture.release()
|
|
74
|
-
|
|
75
|
-
# Create empty texture data
|
|
76
|
-
material_data = np.zeros(shape=(len(self.materials), 25), dtype="f4")
|
|
77
|
-
|
|
78
|
-
# Get data from the materials
|
|
79
|
-
for i, mtl in enumerate(self.materials):
|
|
80
|
-
mtl.index = i
|
|
81
|
-
material_data[i] = mtl.get_data()
|
|
82
|
-
|
|
83
|
-
# Create texture from data
|
|
84
|
-
material_data = np.ravel(material_data)
|
|
85
|
-
self.data_texture = self.ctx.texture((1, len(material_data)), components=1, dtype='f4', data=material_data)
|
|
86
|
-
|
|
87
|
-
def write(self, regenerate=False) -> None:
|
|
88
|
-
"""
|
|
89
|
-
Writes all material data to relavent shaders
|
|
90
|
-
"""
|
|
91
|
-
|
|
92
|
-
if regenerate: self.generate_material_texture()
|
|
93
|
-
|
|
94
|
-
if not self.data_texture: return
|
|
95
|
-
|
|
96
|
-
for shader in self.engine.scene.shader_handler.shaders:
|
|
97
|
-
if 'materialsTexture' not in shader.uniforms: continue
|
|
98
|
-
|
|
99
|
-
shader.program['materialsTexture'] = 9
|
|
100
|
-
self.data_texture.use(location=9)
|
|
101
|
-
|
|
102
|
-
def get(self, identifier: str | int) -> any:
|
|
103
|
-
"""
|
|
104
|
-
Gets the basilisk material with the given name or index
|
|
105
|
-
Args:
|
|
106
|
-
identifier: str | int
|
|
107
|
-
The name string or index of the desired material
|
|
108
|
-
"""
|
|
109
|
-
|
|
110
|
-
# Simply use index if given
|
|
111
|
-
if isinstance(identifier, int): return self.materials[identifier]
|
|
112
|
-
|
|
113
|
-
# Else, search the list for an image material the given name
|
|
114
|
-
for material in self.materials:
|
|
115
|
-
if material.name != identifier: continue
|
|
116
|
-
return material
|
|
117
|
-
|
|
118
|
-
# No matching material found
|
|
119
|
-
return None
|
|
120
|
-
|
|
121
|
-
def set_base(self):
|
|
122
|
-
"""
|
|
123
|
-
Creates a base material
|
|
124
|
-
"""
|
|
125
|
-
|
|
126
|
-
self.base = Material('Base')
|
|
127
|
-
self.materials.append(self.base)
|
|
128
|
-
self.generate_material_texture()
|
|
129
|
-
self.write()
|
|
130
|
-
|
|
131
|
-
def __del__(self) -> None:
|
|
132
|
-
"""
|
|
133
|
-
Releases the material data texture
|
|
134
|
-
"""
|
|
135
|
-
|
|
1
|
+
import moderngl as mgl
|
|
2
|
+
from ..render.image_handler import ImageHandler
|
|
3
|
+
from ..render.material import Material
|
|
4
|
+
import numpy as np
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class MaterialHandler():
|
|
8
|
+
engine: ...
|
|
9
|
+
"""Back reference to the parent engine"""
|
|
10
|
+
scene: ...
|
|
11
|
+
"""Back reference to the parent scene"""
|
|
12
|
+
ctx: mgl.Context
|
|
13
|
+
"""Back reference to the parent context"""
|
|
14
|
+
materials: list[Material]
|
|
15
|
+
"""List containing all the materials in the scene"""
|
|
16
|
+
data_texture: mgl.Texture
|
|
17
|
+
"""ModernGL texture containing all the material data for materials in the scene"""
|
|
18
|
+
|
|
19
|
+
def __init__(self, scene) -> None:
|
|
20
|
+
"""
|
|
21
|
+
Handles all the materials introduced to a scene.
|
|
22
|
+
Writes material information to the GPU
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
# Back references
|
|
26
|
+
self.scene = scene
|
|
27
|
+
self.engine = scene.engine
|
|
28
|
+
self.ctx = scene.engine.ctx
|
|
29
|
+
|
|
30
|
+
# Initialize data
|
|
31
|
+
self.materials = []
|
|
32
|
+
self.data_texture = None
|
|
33
|
+
self.set_base()
|
|
34
|
+
|
|
35
|
+
self.image_handler = ImageHandler(scene)
|
|
36
|
+
|
|
37
|
+
def add(self, material: Material) -> None:
|
|
38
|
+
"""
|
|
39
|
+
Adds the given material to the handler if it is not already present
|
|
40
|
+
"""
|
|
41
|
+
|
|
42
|
+
write = False
|
|
43
|
+
|
|
44
|
+
if isinstance(material, Material): material = [material]
|
|
45
|
+
|
|
46
|
+
for mtl in material:
|
|
47
|
+
# Check that the material is not already in the scene
|
|
48
|
+
if mtl in self.materials: continue
|
|
49
|
+
# Update the material's handler
|
|
50
|
+
mtl.material_handler = self
|
|
51
|
+
# Add images
|
|
52
|
+
if mtl.texture: self.image_handler.add(mtl.texture)
|
|
53
|
+
if mtl.normal: self.image_handler.add(mtl.normal)
|
|
54
|
+
|
|
55
|
+
# Add the material
|
|
56
|
+
self.materials.append(mtl)
|
|
57
|
+
|
|
58
|
+
write = True
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
# Write materials
|
|
62
|
+
if write: self.write(regenerate=True)
|
|
63
|
+
|
|
64
|
+
def generate_material_texture(self) -> None:
|
|
65
|
+
"""
|
|
66
|
+
Generates the texture that is used to write material data to the GPU
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
# Check that there are materials to write
|
|
70
|
+
if len(self.materials) == 0: return
|
|
71
|
+
|
|
72
|
+
# Release existing data texture
|
|
73
|
+
if self.data_texture: self.data_texture.release()
|
|
74
|
+
|
|
75
|
+
# Create empty texture data
|
|
76
|
+
material_data = np.zeros(shape=(len(self.materials), 25), dtype="f4")
|
|
77
|
+
|
|
78
|
+
# Get data from the materials
|
|
79
|
+
for i, mtl in enumerate(self.materials):
|
|
80
|
+
mtl.index = i
|
|
81
|
+
material_data[i] = mtl.get_data()
|
|
82
|
+
|
|
83
|
+
# Create texture from data
|
|
84
|
+
material_data = np.ravel(material_data)
|
|
85
|
+
self.data_texture = self.ctx.texture((1, len(material_data)), components=1, dtype='f4', data=material_data)
|
|
86
|
+
|
|
87
|
+
def write(self, regenerate=False) -> None:
|
|
88
|
+
"""
|
|
89
|
+
Writes all material data to relavent shaders
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
if regenerate: self.generate_material_texture()
|
|
93
|
+
|
|
94
|
+
if not self.data_texture: return
|
|
95
|
+
|
|
96
|
+
for shader in self.engine.scene.shader_handler.shaders:
|
|
97
|
+
if 'materialsTexture' not in shader.uniforms: continue
|
|
98
|
+
|
|
99
|
+
shader.program['materialsTexture'] = 9
|
|
100
|
+
self.data_texture.use(location=9)
|
|
101
|
+
|
|
102
|
+
def get(self, identifier: str | int) -> any:
|
|
103
|
+
"""
|
|
104
|
+
Gets the basilisk material with the given name or index
|
|
105
|
+
Args:
|
|
106
|
+
identifier: str | int
|
|
107
|
+
The name string or index of the desired material
|
|
108
|
+
"""
|
|
109
|
+
|
|
110
|
+
# Simply use index if given
|
|
111
|
+
if isinstance(identifier, int): return self.materials[identifier]
|
|
112
|
+
|
|
113
|
+
# Else, search the list for an image material the given name
|
|
114
|
+
for material in self.materials:
|
|
115
|
+
if material.name != identifier: continue
|
|
116
|
+
return material
|
|
117
|
+
|
|
118
|
+
# No matching material found
|
|
119
|
+
return None
|
|
120
|
+
|
|
121
|
+
def set_base(self):
|
|
122
|
+
"""
|
|
123
|
+
Creates a base material
|
|
124
|
+
"""
|
|
125
|
+
|
|
126
|
+
self.base = Material('Base')
|
|
127
|
+
self.materials.append(self.base)
|
|
128
|
+
self.generate_material_texture()
|
|
129
|
+
self.write()
|
|
130
|
+
|
|
131
|
+
def __del__(self) -> None:
|
|
132
|
+
"""
|
|
133
|
+
Releases the material data texture
|
|
134
|
+
"""
|
|
135
|
+
|
|
136
136
|
if self.data_texture: self.data_texture.release()
|
basilisk/render/shader.py
CHANGED
|
@@ -1,110 +1,110 @@
|
|
|
1
|
-
import moderngl as mgl
|
|
2
|
-
import random
|
|
3
|
-
|
|
4
|
-
attribute_mappings = {
|
|
5
|
-
'in_position' : [0, 1, 2],
|
|
6
|
-
'in_uv' : [3, 4],
|
|
7
|
-
'in_normal' : [5, 6, 7],
|
|
8
|
-
'in_tangent' : [8, 9, 10],
|
|
9
|
-
'in_bitangent' : [11, 12, 13],
|
|
10
|
-
'obj_position' : [14, 15, 16],
|
|
11
|
-
'obj_rotation' : [17, 18, 19, 20],
|
|
12
|
-
'obj_scale' : [21, 22, 23],
|
|
13
|
-
'obj_material' : [24],
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class Shader:
|
|
18
|
-
program: mgl.Program=None
|
|
19
|
-
"""Shader program for the vertex and fragment shader"""
|
|
20
|
-
vertex_shader: str
|
|
21
|
-
"""String representation of the vertex shader"""
|
|
22
|
-
fragment_shader: str
|
|
23
|
-
"""String representation of the vertex shader"""
|
|
24
|
-
uniforms: list[str]=[]
|
|
25
|
-
"""List containg the names of all uniforms in the shader"""
|
|
26
|
-
attribute_indices: list[int]
|
|
27
|
-
"""List of indices that map all possible shader attributes to the ones used byu the shader"""
|
|
28
|
-
fmt: str
|
|
29
|
-
"""String representation of the format for building vaos"""
|
|
30
|
-
attributes: list[str]
|
|
31
|
-
"""List representation of the attributes for building vaos"""
|
|
32
|
-
|
|
33
|
-
def __init__(self, engine, vert: str=None, frag: str=None) -> None:
|
|
34
|
-
"""
|
|
35
|
-
Basilisk shader object. Contains shader program and shader attrbibute/uniform information
|
|
36
|
-
Args:
|
|
37
|
-
vert: str=None
|
|
38
|
-
Path to the vertex shader. Defaults to internal if none is given
|
|
39
|
-
frag: str=None
|
|
40
|
-
Path to the fragment shader. Defaults to internal if none is given
|
|
41
|
-
"""
|
|
42
|
-
|
|
43
|
-
self.engine = engine
|
|
44
|
-
self.ctx = engine.ctx
|
|
45
|
-
|
|
46
|
-
# Default class attributes values
|
|
47
|
-
self.uniforms = []
|
|
48
|
-
self.attribute_indices = []
|
|
49
|
-
self.fmt = ''
|
|
50
|
-
self.attributes = []
|
|
51
|
-
|
|
52
|
-
# Default vertex and fragment shaders
|
|
53
|
-
if vert == None: vert = self.engine.root + '/shaders/batch.vert'
|
|
54
|
-
if frag == None: frag = self.engine.root + '/shaders/batch.frag'
|
|
55
|
-
|
|
56
|
-
# Read the shaders
|
|
57
|
-
with open(vert) as file:
|
|
58
|
-
self.vertex_shader = file.read()
|
|
59
|
-
with open(frag) as file:
|
|
60
|
-
self.fragment_shader = file.read()
|
|
61
|
-
|
|
62
|
-
# Hash value for references
|
|
63
|
-
if vert == None and frag == None:
|
|
64
|
-
self.hash = hash((self.vertex_shader, self.fragment_shader, 'default'))
|
|
65
|
-
else:
|
|
66
|
-
self.hash = hash((self.vertex_shader, self.fragment_shader))
|
|
67
|
-
|
|
68
|
-
# Create a string of all lines in both shaders
|
|
69
|
-
lines = f'{self.vertex_shader}\n{self.fragment_shader}'.split('\n')
|
|
70
|
-
|
|
71
|
-
# Parse through shader to find uniforms and attributes
|
|
72
|
-
for line in lines:
|
|
73
|
-
tokens = line.strip().split(' ')
|
|
74
|
-
|
|
75
|
-
# Add uniforms
|
|
76
|
-
if tokens[0] == 'uniform' and len(tokens) > 2:
|
|
77
|
-
self.uniforms.append(tokens[-1][:-1])
|
|
78
|
-
|
|
79
|
-
# Add attributes
|
|
80
|
-
if tokens[0] == 'layout' and len(tokens) > 2 and 'in' in line:
|
|
81
|
-
self.attributes.append(tokens[-1][:-1])
|
|
82
|
-
|
|
83
|
-
if tokens[-1][:-1] not in attribute_mappings: continue
|
|
84
|
-
indices = attribute_mappings[tokens[-1][:-1]]
|
|
85
|
-
self.attribute_indices.extend(indices)
|
|
86
|
-
self.fmt += f'{len(indices)}f '
|
|
87
|
-
|
|
88
|
-
# Create a program with shaders
|
|
89
|
-
self.program = self.ctx.program(vertex_shader=self.vertex_shader, fragment_shader=self.fragment_shader)
|
|
90
|
-
|
|
91
|
-
def set_main(self):
|
|
92
|
-
"""
|
|
93
|
-
Selects a shader for use
|
|
94
|
-
"""
|
|
95
|
-
|
|
96
|
-
self.engine.scene.shader_handler.add(self)
|
|
97
|
-
self.engine.scene.node_handler.chunk_handler.update_all()
|
|
98
|
-
|
|
99
|
-
def write(self, name: str, value) -> None:
|
|
100
|
-
"""
|
|
101
|
-
Writes a uniform to the shader program
|
|
102
|
-
"""
|
|
103
|
-
|
|
104
|
-
self.program[name].write(value)
|
|
105
|
-
|
|
106
|
-
def __del__(self) -> int:
|
|
107
|
-
if self.program: self.program.release()
|
|
108
|
-
|
|
109
|
-
def __hash__(self) -> int:
|
|
1
|
+
import moderngl as mgl
|
|
2
|
+
import random
|
|
3
|
+
|
|
4
|
+
attribute_mappings = {
|
|
5
|
+
'in_position' : [0, 1, 2],
|
|
6
|
+
'in_uv' : [3, 4],
|
|
7
|
+
'in_normal' : [5, 6, 7],
|
|
8
|
+
'in_tangent' : [8, 9, 10],
|
|
9
|
+
'in_bitangent' : [11, 12, 13],
|
|
10
|
+
'obj_position' : [14, 15, 16],
|
|
11
|
+
'obj_rotation' : [17, 18, 19, 20],
|
|
12
|
+
'obj_scale' : [21, 22, 23],
|
|
13
|
+
'obj_material' : [24],
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Shader:
|
|
18
|
+
program: mgl.Program=None
|
|
19
|
+
"""Shader program for the vertex and fragment shader"""
|
|
20
|
+
vertex_shader: str
|
|
21
|
+
"""String representation of the vertex shader"""
|
|
22
|
+
fragment_shader: str
|
|
23
|
+
"""String representation of the vertex shader"""
|
|
24
|
+
uniforms: list[str]=[]
|
|
25
|
+
"""List containg the names of all uniforms in the shader"""
|
|
26
|
+
attribute_indices: list[int]
|
|
27
|
+
"""List of indices that map all possible shader attributes to the ones used byu the shader"""
|
|
28
|
+
fmt: str
|
|
29
|
+
"""String representation of the format for building vaos"""
|
|
30
|
+
attributes: list[str]
|
|
31
|
+
"""List representation of the attributes for building vaos"""
|
|
32
|
+
|
|
33
|
+
def __init__(self, engine, vert: str=None, frag: str=None) -> None:
|
|
34
|
+
"""
|
|
35
|
+
Basilisk shader object. Contains shader program and shader attrbibute/uniform information
|
|
36
|
+
Args:
|
|
37
|
+
vert: str=None
|
|
38
|
+
Path to the vertex shader. Defaults to internal if none is given
|
|
39
|
+
frag: str=None
|
|
40
|
+
Path to the fragment shader. Defaults to internal if none is given
|
|
41
|
+
"""
|
|
42
|
+
|
|
43
|
+
self.engine = engine
|
|
44
|
+
self.ctx = engine.ctx
|
|
45
|
+
|
|
46
|
+
# Default class attributes values
|
|
47
|
+
self.uniforms = []
|
|
48
|
+
self.attribute_indices = []
|
|
49
|
+
self.fmt = ''
|
|
50
|
+
self.attributes = []
|
|
51
|
+
|
|
52
|
+
# Default vertex and fragment shaders
|
|
53
|
+
if vert == None: vert = self.engine.root + '/shaders/batch.vert'
|
|
54
|
+
if frag == None: frag = self.engine.root + '/shaders/batch.frag'
|
|
55
|
+
|
|
56
|
+
# Read the shaders
|
|
57
|
+
with open(vert) as file:
|
|
58
|
+
self.vertex_shader = file.read()
|
|
59
|
+
with open(frag) as file:
|
|
60
|
+
self.fragment_shader = file.read()
|
|
61
|
+
|
|
62
|
+
# Hash value for references
|
|
63
|
+
if vert == None and frag == None:
|
|
64
|
+
self.hash = hash((self.vertex_shader, self.fragment_shader, 'default'))
|
|
65
|
+
else:
|
|
66
|
+
self.hash = hash((self.vertex_shader, self.fragment_shader))
|
|
67
|
+
|
|
68
|
+
# Create a string of all lines in both shaders
|
|
69
|
+
lines = f'{self.vertex_shader}\n{self.fragment_shader}'.split('\n')
|
|
70
|
+
|
|
71
|
+
# Parse through shader to find uniforms and attributes
|
|
72
|
+
for line in lines:
|
|
73
|
+
tokens = line.strip().split(' ')
|
|
74
|
+
|
|
75
|
+
# Add uniforms
|
|
76
|
+
if tokens[0] == 'uniform' and len(tokens) > 2:
|
|
77
|
+
self.uniforms.append(tokens[-1][:-1])
|
|
78
|
+
|
|
79
|
+
# Add attributes
|
|
80
|
+
if tokens[0] == 'layout' and len(tokens) > 2 and 'in' in line:
|
|
81
|
+
self.attributes.append(tokens[-1][:-1])
|
|
82
|
+
|
|
83
|
+
if tokens[-1][:-1] not in attribute_mappings: continue
|
|
84
|
+
indices = attribute_mappings[tokens[-1][:-1]]
|
|
85
|
+
self.attribute_indices.extend(indices)
|
|
86
|
+
self.fmt += f'{len(indices)}f '
|
|
87
|
+
|
|
88
|
+
# Create a program with shaders
|
|
89
|
+
self.program = self.ctx.program(vertex_shader=self.vertex_shader, fragment_shader=self.fragment_shader)
|
|
90
|
+
|
|
91
|
+
def set_main(self):
|
|
92
|
+
"""
|
|
93
|
+
Selects a shader for use
|
|
94
|
+
"""
|
|
95
|
+
|
|
96
|
+
self.engine.scene.shader_handler.add(self)
|
|
97
|
+
self.engine.scene.node_handler.chunk_handler.update_all()
|
|
98
|
+
|
|
99
|
+
def write(self, name: str, value) -> None:
|
|
100
|
+
"""
|
|
101
|
+
Writes a uniform to the shader program
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
self.program[name].write(value)
|
|
105
|
+
|
|
106
|
+
def __del__(self) -> int:
|
|
107
|
+
if self.program: self.program.release()
|
|
108
|
+
|
|
109
|
+
def __hash__(self) -> int:
|
|
110
110
|
return self.hash
|
|
@@ -1,80 +1,80 @@
|
|
|
1
|
-
import moderngl as mgl
|
|
2
|
-
import glm
|
|
3
|
-
from .shader import Shader
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
class ShaderHandler:
|
|
7
|
-
engine: ...
|
|
8
|
-
"""Back reference to the parent engine"""
|
|
9
|
-
scene: ...
|
|
10
|
-
"""Back reference to the parent scene"""
|
|
11
|
-
ctx: mgl.Context
|
|
12
|
-
"""Back reference to the parent context"""
|
|
13
|
-
shaders: set
|
|
14
|
-
"""Dictionary containing all the shaders"""
|
|
15
|
-
uniform_values: dict = {}
|
|
16
|
-
"""Dictionary containing uniform values"""
|
|
17
|
-
|
|
18
|
-
def __init__(self, scene) -> None:
|
|
19
|
-
"""
|
|
20
|
-
Handles all the shader programs in a basilisk scene
|
|
21
|
-
"""
|
|
22
|
-
|
|
23
|
-
# Back references
|
|
24
|
-
self.scene = scene
|
|
25
|
-
self.engine = scene.engine
|
|
26
|
-
self.ctx = scene.engine.ctx
|
|
27
|
-
|
|
28
|
-
# Initalize dictionaries
|
|
29
|
-
self.shaders = set()
|
|
30
|
-
self.add(self.engine.shader)
|
|
31
|
-
|
|
32
|
-
def add(self, shader: Shader) -> None:
|
|
33
|
-
"""
|
|
34
|
-
Creates a shader program from a file name.
|
|
35
|
-
Parses through shaders to identify uniforms and save for writting
|
|
36
|
-
"""
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
if not shader: return None
|
|
40
|
-
if shader in self.shaders: return shader
|
|
41
|
-
|
|
42
|
-
self.shaders.add(shader)
|
|
43
|
-
|
|
44
|
-
if self.scene.material_handler:
|
|
45
|
-
self.scene.light_handler.write()
|
|
46
|
-
self.scene.material_handler.write()
|
|
47
|
-
self.scene.material_handler.image_handler.write()
|
|
48
|
-
|
|
49
|
-
return shader
|
|
50
|
-
|
|
51
|
-
def get_uniforms_values(self) -> None:
|
|
52
|
-
"""
|
|
53
|
-
Gets uniforms from various parts of the scene.
|
|
54
|
-
These values are stored and used in write_all_uniforms and update_uniforms.
|
|
55
|
-
This is called by write_all_uniforms and update_uniforms, so there is no need to call this manually.
|
|
56
|
-
"""
|
|
57
|
-
|
|
58
|
-
self.uniform_values = {
|
|
59
|
-
'projectionMatrix' : self.scene.camera.m_proj,
|
|
60
|
-
'viewMatrix' : self.scene.camera.m_view,
|
|
61
|
-
'cameraPosition' : self.scene.camera.position,
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
def write(self) -> None:
|
|
65
|
-
"""
|
|
66
|
-
Writes all of the uniforms in every shader program.
|
|
67
|
-
"""
|
|
68
|
-
|
|
69
|
-
self.get_uniforms_values()
|
|
70
|
-
for uniform in self.uniform_values:
|
|
71
|
-
for shader in self.shaders:
|
|
72
|
-
if not uniform in shader.uniforms: continue # Does not write uniforms not in the shader
|
|
73
|
-
shader.write(uniform, self.uniform_values[uniform])
|
|
74
|
-
|
|
75
|
-
def release(self) -> None:
|
|
76
|
-
"""
|
|
77
|
-
Releases all shader programs in handler
|
|
78
|
-
"""
|
|
79
|
-
|
|
1
|
+
import moderngl as mgl
|
|
2
|
+
import glm
|
|
3
|
+
from .shader import Shader
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ShaderHandler:
|
|
7
|
+
engine: ...
|
|
8
|
+
"""Back reference to the parent engine"""
|
|
9
|
+
scene: ...
|
|
10
|
+
"""Back reference to the parent scene"""
|
|
11
|
+
ctx: mgl.Context
|
|
12
|
+
"""Back reference to the parent context"""
|
|
13
|
+
shaders: set
|
|
14
|
+
"""Dictionary containing all the shaders"""
|
|
15
|
+
uniform_values: dict = {}
|
|
16
|
+
"""Dictionary containing uniform values"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, scene) -> None:
|
|
19
|
+
"""
|
|
20
|
+
Handles all the shader programs in a basilisk scene
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
# Back references
|
|
24
|
+
self.scene = scene
|
|
25
|
+
self.engine = scene.engine
|
|
26
|
+
self.ctx = scene.engine.ctx
|
|
27
|
+
|
|
28
|
+
# Initalize dictionaries
|
|
29
|
+
self.shaders = set()
|
|
30
|
+
self.add(self.engine.shader)
|
|
31
|
+
|
|
32
|
+
def add(self, shader: Shader) -> None:
|
|
33
|
+
"""
|
|
34
|
+
Creates a shader program from a file name.
|
|
35
|
+
Parses through shaders to identify uniforms and save for writting
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
if not shader: return None
|
|
40
|
+
if shader in self.shaders: return shader
|
|
41
|
+
|
|
42
|
+
self.shaders.add(shader)
|
|
43
|
+
|
|
44
|
+
if self.scene.material_handler:
|
|
45
|
+
self.scene.light_handler.write()
|
|
46
|
+
self.scene.material_handler.write()
|
|
47
|
+
self.scene.material_handler.image_handler.write()
|
|
48
|
+
|
|
49
|
+
return shader
|
|
50
|
+
|
|
51
|
+
def get_uniforms_values(self) -> None:
|
|
52
|
+
"""
|
|
53
|
+
Gets uniforms from various parts of the scene.
|
|
54
|
+
These values are stored and used in write_all_uniforms and update_uniforms.
|
|
55
|
+
This is called by write_all_uniforms and update_uniforms, so there is no need to call this manually.
|
|
56
|
+
"""
|
|
57
|
+
|
|
58
|
+
self.uniform_values = {
|
|
59
|
+
'projectionMatrix' : self.scene.camera.m_proj,
|
|
60
|
+
'viewMatrix' : self.scene.camera.m_view,
|
|
61
|
+
'cameraPosition' : self.scene.camera.position,
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
def write(self) -> None:
|
|
65
|
+
"""
|
|
66
|
+
Writes all of the uniforms in every shader program.
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
self.get_uniforms_values()
|
|
70
|
+
for uniform in self.uniform_values:
|
|
71
|
+
for shader in self.shaders:
|
|
72
|
+
if not uniform in shader.uniforms: continue # Does not write uniforms not in the shader
|
|
73
|
+
shader.write(uniform, self.uniform_values[uniform])
|
|
74
|
+
|
|
75
|
+
def release(self) -> None:
|
|
76
|
+
"""
|
|
77
|
+
Releases all shader programs in handler
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
80
|
[shader.__del__() for shader in self.shaders]
|