basilisk-engine 0.1.40__py3-none-any.whl → 0.1.42__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.

@@ -39,9 +39,9 @@ class Collider():
39
39
  def __init__(self, node, collider_mesh: str|Mesh=None, static_friction: glm.vec3=0.7, kinetic_friction: glm.vec3=0.3, elasticity: glm.vec3=0.2, collision_group: str=None):
40
40
  self.collider_handler = None
41
41
  self.node = node
42
- self.static_friction = static_friction if elasticity else 0.8 # added checks to prevent floats being set to None. Also done for kinetic and elasticity
42
+ self.static_friction = static_friction if static_friction else 0.8 # added checks to prevent floats being set to None. Also done for kinetic and elasticity
43
43
  self.mesh = collider_mesh
44
- self.kinetic_friction = kinetic_friction if elasticity else 0.4
44
+ self.kinetic_friction = kinetic_friction if kinetic_friction else 0.4
45
45
  self.elasticity = elasticity if elasticity else 0.1
46
46
  self.collision_group = collision_group
47
47
  self.collision_velocity = 0
basilisk/engine.py CHANGED
@@ -107,6 +107,7 @@ class Engine():
107
107
  self.shader_handler = ShaderHandler(self)
108
108
  self.draw_handler = DrawHandler(self)
109
109
  self.frame = Frame(self)
110
+ self.frames = []
110
111
  self.material_handler.set_base()
111
112
 
112
113
  def _update(self) -> None:
@@ -115,16 +116,21 @@ class Engine():
115
116
  Updates all input, physics, and time variables. Clears the frame.
116
117
  """
117
118
 
119
+ # Used to lock this internal update until user calls engine.update()
118
120
  if self.current_frame_updated: return
121
+ self.current_frame_updated = True
119
122
 
123
+ # Clear frame data
120
124
  for fbo in self.fbos: fbo.clear()
125
+ self.frames.clear()
126
+ self.frame.clear()
127
+ self.ctx.clear()
128
+
129
+ # Update time and IO
121
130
  self.clock.update()
122
131
  self.IO.update()
123
132
 
124
- self.current_frame_updated = True
125
-
126
-
127
- def update(self) -> None:
133
+ def update(self, render=True) -> None:
128
134
  """
129
135
  Calls internal update if needed
130
136
  Renders the draw handler
@@ -133,21 +139,21 @@ class Engine():
133
139
 
134
140
 
135
141
  # Must update the frame
136
- if not self.current_frame_updated: self._update()
142
+ self._update()
137
143
  if not self.running: return
138
144
 
139
145
  # Render all draw calls from the past frame
140
- self.frame.use()
146
+ self.ctx.screen.use()
141
147
  self.draw_handler.render()
142
148
 
143
149
  # Clear the screen and render the frame
144
- self.ctx.screen.use()
145
- self.ctx.clear()
146
- self.frame.render()
147
- pg.display.flip()
148
-
149
- self.frame.clear()
150
+ if render:
151
+ for frame in self.frames:
152
+ frame.render(self.frame.output_buffer)
153
+ self.frame.render()
150
154
 
155
+ # Even though we may not render here, the user might be rendering in their file, so we need to flip
156
+ pg.display.flip()
151
157
 
152
158
  # Allow for the engine to take in input again
153
159
  self.current_frame_updated = False
basilisk/render/bloom.py CHANGED
@@ -27,13 +27,15 @@ class Bloom:
27
27
  GPU downsamples and upsamples the bloom texture to blur it
28
28
  """
29
29
 
30
- if not self.frame.engine.config.bloom_enabled:
31
- getattr(self, f'upscale_buffer_0').clear()
32
- return
30
+ self.clear()
33
31
 
34
32
  n = self.engine.config.bloom_quality
35
33
 
36
- self.downsample(self.frame.framebuffer.color_attachments[1], getattr(self, f'bloom_buffer_{0}'))
34
+
35
+ self.ctx.enable(mgl.BLEND)
36
+ self.ctx.blend_func = mgl.ADDITIVE_BLENDING
37
+
38
+ self.downsample(self.frame.input_buffer.color_attachments[1], getattr(self, f'bloom_buffer_{0}'))
37
39
  for i in range(0, n):
38
40
  self.downsample(getattr(self, f'bloom_buffer_{i}'), getattr(self, f'bloom_buffer_{i + 1}'))
39
41
 
@@ -41,6 +43,8 @@ class Bloom:
41
43
  for i in range(n - 1, -1, -1):
42
44
  self.upsample(getattr(self, f'upscale_buffer_{i + 1}'), getattr(self, f'bloom_buffer_{i}'), getattr(self, f'upscale_buffer_{i}'))
43
45
 
46
+ self.ctx.disable(mgl.BLEND)
47
+
44
48
  def downsample(self, source: Framebuffer, dest: Framebuffer) -> None:
45
49
  """
46
50
 
@@ -78,31 +82,43 @@ class Bloom:
78
82
  # Render using the upsample vao (3x3 tent filter)
79
83
  self.upsample_vao.render()
80
84
 
85
+ return dest
86
+
81
87
  def generate_bloom_buffers(self) -> None:
82
88
  """
83
89
  Generates n buffers for down/up sampling
84
90
  """
85
91
 
86
92
  n = self.engine.config.bloom_quality
87
- size = self.frame.framebuffer.size
93
+ size = self.frame.input_buffer.size
88
94
 
89
95
  for i in range(100):
90
96
  try:
91
97
  getattr(self, f'bloom_buffer_{i}').__del__()
92
98
  getattr(self, f'upscale_buffer_{i}').__del__()
93
99
  except:
94
- ...
100
+ break
95
101
 
96
102
  for i in range(n + 1):
97
- fbo = Framebuffer(self.engine, (max(size[0] // (2 ** (i)), 1), max(size[1] // (2 ** (i)), 1)))
103
+ fbo = Framebuffer(self.engine, size=(max(size[0] // (2 ** (i)), 1), max(size[1] // (2 ** (i)), 1)))
98
104
  fbo.texture.repeat_x = False
99
105
  fbo.texture.repeat_y = False
100
106
  setattr(self, f'bloom_buffer_{i}', fbo)
101
107
 
102
- fbo = Framebuffer(self.engine, (max(size[0] // (2 ** (i)), 1), max(size[1] // (2 ** (i)), 1)))
108
+ fbo = Framebuffer(self.engine, size=(max(size[0] // (2 ** (i)), 1), max(size[1] // (2 ** (i)), 1)))
103
109
  fbo.texture.repeat_x = False
104
110
  fbo.texture.repeat_y = False
105
111
  setattr(self, f'upscale_buffer_{i}', fbo)
106
112
 
113
+ def clear(self):
114
+ for i in range(100):
115
+ try:
116
+ getattr(self, f'bloom_buffer_{i}').clear()
117
+ getattr(self, f'upscale_buffer_{i}').clear()
118
+ except:
119
+ break
120
+
121
+ @property
122
+ def texture(self): return getattr(self, f'upscale_buffer_0').texture
107
123
  @property
108
- def texture(self): return getattr(self, f'upscale_buffer_0').texture
124
+ def fbo(self): return getattr(self, f'upscale_buffer_0')
basilisk/render/frame.py CHANGED
@@ -1,6 +1,7 @@
1
1
  import numpy as np
2
2
  import moderngl as mgl
3
3
  from .shader import Shader
4
+ from .image import Image
4
5
  from .framebuffer import Framebuffer
5
6
  from .post_process import PostProcess
6
7
  from .bloom import Bloom
@@ -10,7 +11,6 @@ class Frame:
10
11
  shader: Shader=None
11
12
  vbo: mgl.Buffer=None
12
13
  vao: mgl.VertexArray=None
13
- framebuffer: mgl.Framebuffer=None
14
14
 
15
15
  def __init__(self, engine, scale: float=1.0, linear_filter: bool=False) -> None:
16
16
  """
@@ -22,15 +22,12 @@ class Frame:
22
22
  self.ctx = engine.ctx
23
23
 
24
24
  # Load framebuffer
25
- self.framebuffer = Framebuffer(self.engine, scale=scale, n_color_attachments=2, linear_filter=linear_filter)
26
- self.ping_pong_buffer = Framebuffer(self.engine, scale=scale, n_color_attachments=2, linear_filter=linear_filter)
27
-
28
- self.framebuffer.texture.repeat_x = False
29
- self.framebuffer.texture.repeat_y = False
25
+ self.output_buffer = Framebuffer(self.engine, scale=scale, n_color_attachments=2, linear_filter=linear_filter)
26
+ self.input_buffer = Framebuffer(self.engine, scale=scale, n_color_attachments=3, linear_filter=linear_filter)
27
+ self.ping_pong_buffer = Framebuffer(self.engine, scale=scale, n_color_attachments=3, linear_filter=linear_filter)
30
28
 
31
29
  # Load Shaders
32
- self.shader = Shader(self.engine, self.engine.root + '/shaders/frame.vert', self.engine.root + '/shaders/bloom_frame.frag')
33
- self.engine.shader_handler.add(self.shader)
30
+ self.shader = Shader(self.engine, self.engine.root + '/shaders/frame.vert', self.engine.root + '/shaders/frame_hdr.frag')
34
31
 
35
32
  # Load VAO
36
33
  self.vbo = self.ctx.buffer(np.array([[-1, -1, 0, 0, 0], [1, -1, 0, 1, 0], [1, 1, 0, 1, 1], [-1, 1, 0, 0, 1], [-1, -1, 0, 0, 0], [1, 1, 0, 1, 1]], dtype='f4'))
@@ -42,38 +39,41 @@ class Frame:
42
39
  self.post_processes = []
43
40
 
44
41
 
45
- def render(self) -> None:
42
+ def scene_render(self, target=None) -> None:
46
43
  """
47
- Renders the current frame to the screen
44
+ Renders the current frame to the screen or the given target
48
45
  """
49
46
 
50
- self.ctx.enable(mgl.BLEND)
51
- self.ctx.blend_func = mgl.ADDITIVE_BLENDING
52
-
53
47
  if self.engine.event_resize: self.bloom.generate_bloom_buffers()
54
48
 
55
- self.bloom.render()
56
49
 
57
- for process in self.post_processes:
58
- self.ping_pong_buffer = process.apply([('screenTexture', self.framebuffer)], self.ping_pong_buffer)
50
+ # for process in self.post_processes:
51
+ # self.ping_pong_buffer = process.apply([('screenTexture', self.input_buffer)], self.ping_pong_buffer)
59
52
 
60
- temp = self.framebuffer
61
- self.framebuffer = self.ping_pong_buffer
62
- self.ping_pong_buffer = temp
53
+ # temp = self.input_buffer
54
+ # self.input_buffer = self.ping_pong_buffer
55
+ # self.ping_pong_buffer = temp
63
56
 
64
- self.ctx.screen.use()
65
- self.shader.bind(self.framebuffer.texture, 'screenTexture', 0)
57
+
58
+ self.bloom.render()
59
+ target.use() if target else self.output_buffer.use()
60
+ self.shader.bind(self.input_buffer.texture, 'screenTexture', 0)
66
61
  self.shader.bind(self.bloom.texture, 'bloomTexture', 1)
67
62
  self.vao.render()
68
63
 
69
- self.ctx.disable(mgl.BLEND)
64
+ def render(self, target=None) -> None:
65
+ """
66
+ Renders the current frame to the screen or the given target
67
+ """
68
+
69
+ self.output_buffer.render(target=target)
70
70
 
71
71
  def use(self) -> None:
72
72
  """
73
73
  Uses the frame as a render target
74
74
  """
75
75
 
76
- self.framebuffer.use()
76
+ self.input_buffer.use()
77
77
 
78
78
  def add_post_process(self, post_process: PostProcess) -> PostProcess:
79
79
  """
@@ -88,17 +88,30 @@ class Frame:
88
88
  Saves the frame as an image to the given file destination
89
89
  """
90
90
 
91
- self.framebuffer.save(destination)
91
+ self.output_buffer.save(destination)
92
92
 
93
93
  def clear(self):
94
- self.framebuffer.clear()
94
+ """
95
+ Clears the framebuffer of the frame
96
+ """
97
+
98
+ self.input_buffer.clear()
99
+ self.output_buffer.clear()
100
+ self.bloom.clear()
101
+
102
+ def bind(self, sampler: mgl.Texture | mgl.TextureArray | mgl.TextureCube | Image, name: str, slot: int=None):
103
+ """
104
+ Binds a texture to the fbo's shader
105
+ """
106
+
107
+ self.shader.bind(sampler, name, slot)
95
108
 
96
109
  def resize(self) -> None:
97
110
  """
98
111
  Resize the frame to the given size. None for window size
99
112
  """
100
113
 
101
- self.framebuffer.resize()
114
+ self.input_buffer.resize()
102
115
  self.ping_pong_buffer.resize()
103
116
  self.generate_bloom_buffers()
104
117
 
@@ -108,4 +121,9 @@ class Frame:
108
121
  """
109
122
 
110
123
  if self.vbo: self.vbo.release()
111
- if self.vao: self.vao.release()
124
+ if self.vao: self.vao.release()
125
+
126
+ @property
127
+ def texture(self): return self.output_buffer.texture
128
+ @property
129
+ def depth(self): return self.output_buffer.depth
@@ -25,7 +25,7 @@ class Framebuffer:
25
25
  _depth_attachment = None
26
26
  """"""
27
27
 
28
- def __init__(self, engine: ..., size: tuple[int]=None, n_color_attachments: int=1, scale: float=1.0, linear_filter: bool=True) -> None:
28
+ def __init__(self, engine: ..., shader: Shader=None, size: tuple[int]=None, n_color_attachments: int=1, scale: float=1.0, linear_filter: bool=True) -> None:
29
29
  """
30
30
  Abstraction of the MGL framebuffer.
31
31
  Has the given number of color attachements (4-component) and 1 depth attachment.
@@ -36,6 +36,7 @@ class Framebuffer:
36
36
  self.ctx = engine.ctx
37
37
  self._size = size
38
38
  self.scale = scale
39
+ self.shader = shader
39
40
  self.texture_filter = (mgl.LINEAR, mgl.LINEAR) if linear_filter else (mgl.NEAREST, mgl.NEAREST)
40
41
  self.n_attachments = n_color_attachments
41
42
 
@@ -50,20 +51,21 @@ class Framebuffer:
50
51
  """
51
52
 
52
53
  # Release existing memory
53
- self.__del__()
54
+ if self._color_attachments: [tex.release() for tex in self._color_attachments]
55
+ if self._depth_attachment: self._depth_attachment.release()
54
56
 
55
57
  # Create textures
56
58
  self._color_attachments = [self.ctx.texture(self.size, components=4, dtype='f4') for i in range(self.n_attachments)]
57
- for tex in self._color_attachments: tex.filter = self.texture_filter
59
+ for tex in self._color_attachments:
60
+ tex.filter = self.texture_filter
61
+ tex.repeat_x = False
62
+ tex.repeat_y = False
63
+
58
64
  self._depth_attachment = self.ctx.depth_texture(self.size)
59
65
 
60
66
  # Create the internal fbo
61
67
  self.fbo = self.ctx.framebuffer(self._color_attachments, self._depth_attachment)
62
68
 
63
- # Texture attributes
64
- self.texture.repeat_x = False
65
- self.texture.repeat_y = False
66
-
67
69
  # Set the show attachment to default
68
70
  self._show = -1
69
71
  self.show = 0
@@ -88,27 +90,28 @@ class Framebuffer:
88
90
  """
89
91
 
90
92
  # Load Shaders
91
- self.shader = Shader(self.engine, self.engine.root + '/shaders/frame.vert', self.engine.root + '/shaders/frame.frag')
93
+ if not self.shader: self.shader = Shader(self.engine, self.engine.root + '/shaders/frame.vert', self.engine.root + '/shaders/frame.frag')
92
94
  self.engine.shader_handler.add(self.shader)
93
95
 
94
96
  # Load VAO
95
97
  self.vbo = self.ctx.buffer(np.array([[-1, -1, 0, 0, 0], [1, -1, 0, 1, 0], [1, 1, 0, 1, 1], [-1, 1, 0, 0, 1], [-1, -1, 0, 0, 0], [1, 1, 0, 1, 1]], dtype='f4'))
96
98
  self.vao = self.ctx.vertex_array(self.shader.program, [(self.vbo, '3f 2f', 'in_position', 'in_uv')], skip_errors=True)
97
99
 
98
- def render(self, render_target=None, show: int=None) -> None:
100
+ def render(self, target=None, color_attachment: int=0, auto_bind=True) -> None:
99
101
  """
100
102
  Render the fbo to the screen
101
103
  If the fbo has multiple attachments, show will specifiy which is shown
102
104
  Depth is considered the last show element
103
105
  """
104
106
 
105
- if not isinstance(show, type(None)): self.show = show
107
+ # if not isinstance(show, type(None)): self.show = show
106
108
 
107
- target = render_target if render_target else self.engine.frame
108
- target.use()
109
+ target.use() if target else self.ctx.screen.use()
109
110
 
111
+ if auto_bind: self.bind(self.color_attachments[min(color_attachment, len(self.color_attachments) - 1)], 'screenTexture', 0)
110
112
  self.vao.render()
111
113
 
114
+
112
115
  def use(self) -> None:
113
116
  """
114
117
  Select this framebuffer for use
@@ -116,13 +119,20 @@ class Framebuffer:
116
119
 
117
120
  self.fbo.use()
118
121
 
119
- def clear(self) -> None:
122
+ def clear(self, color: tuple=(0, 0, 0, 0)) -> None:
120
123
  """
121
124
  Clear all data currently in the textures (set to black)
122
125
  """
123
126
 
124
127
  self.fbo.clear()
125
128
 
129
+ def bind(self, sampler: mgl.Texture | mgl.TextureArray | mgl.TextureCube , name: str, slot: int=None):
130
+ """
131
+ Binds a texture to the fbo's shader
132
+ """
133
+
134
+ self.shader.bind(sampler, name, slot)
135
+
126
136
  def save(self, destination: str=None) -> None:
127
137
  """
128
138
  Saves the frame as an image to the given file destination
@@ -180,7 +190,7 @@ class Framebuffer:
180
190
  self._show = value
181
191
 
182
192
  # Bind the correct texture
183
- self.shader.program['screenTexture'] = value+1
193
+ # self.shader.program['screenTexture'] = value+1
184
194
  src.use(location=value+1)
185
195
 
186
196
  def __repr__(self) -> str:
@@ -4,7 +4,6 @@ from .shader import Shader
4
4
  from .image import Image
5
5
  from .framebuffer import Framebuffer
6
6
 
7
-
8
7
  class PostProcess:
9
8
  engine: ...
10
9
  """Reference to the parent engine"""
@@ -14,6 +13,7 @@ class PostProcess:
14
13
  """Shader object used by the post process"""
15
14
  vao: mgl.VertexArray
16
15
  """Screenspace render vao"""
16
+ fbo: Framebuffer=None
17
17
 
18
18
  def __init__(self, engine, shader_path: str=None, size: tuple=None, components: int=4, filter=(mgl.LINEAR, mgl.LINEAR)) -> None:
19
19
  """
@@ -49,17 +49,33 @@ class PostProcess:
49
49
  self.fbo.texture.filter = self.filter
50
50
 
51
51
 
52
- def apply(self, source: list[tuple[str, mgl.Texture]] | list[tuple[str, Image]] | list[tuple[str, Framebuffer]], destination: mgl.Texture | Image | Framebuffer=None) -> mgl.Texture | Image | Framebuffer:
52
+ def apply(self, sources: list[tuple[str, mgl.Texture]] | list[tuple[str, Image]] | list[tuple[str, Framebuffer]], destination: mgl.Texture | Image | Framebuffer=None) -> mgl.Texture | Image | Framebuffer:
53
53
  """
54
54
  Applies a post process shader to a texture source.
55
55
  Returns the modified texture or renders to the destination if given
56
56
  """
57
57
 
58
- if isinstance(source[0][1], Framebuffer): return self._apply_to_framebuffer(source, destination)
59
- elif isinstance(source[0][1], mgl.Texture): return self._apply_to_texture(source, destination)
60
- elif isinstance(source[0][1], Image): return self._apply_to_image(source, destination)
61
-
62
- raise ValueError(f'PostProces.apply: Invalid postprocess source type {type(source)}')
58
+ # Write all the given sources to the GPU
59
+ self._write_sources(sources)
60
+
61
+ # Get the redner target
62
+ if isinstance(destination, Framebuffer) or isinstance(destination, type(self.engine.frame)): fbo = destination
63
+ elif isinstance(destination, mgl.Texture): fbo = self.ctx.framebuffer([destination], None)
64
+ elif isinstance(destination, Image): fbo = self.ctx.framebuffer([destination.texture], None)
65
+
66
+ # Apply the post process
67
+ fbo.use()
68
+ fbo.clear()
69
+ self.vao.render()
70
+
71
+ # Simply return the given fbo if provided
72
+ if isinstance(destination, Framebuffer) or isinstance(destination, type(self.engine.frame)): return destination
73
+
74
+ # Else, need to release the data and return the texture
75
+ texture = fbo.color_attachments[0]
76
+ fbo.release()
77
+ return texture
78
+
63
79
 
64
80
  def resize(self, size: tuple=None):
65
81
  """
@@ -68,6 +84,24 @@ class PostProcess:
68
84
 
69
85
  self.size = size if size else self.engine.win_size
70
86
 
87
+ def _write_sources(self, sources: list[tuple[str, mgl.Texture]] | list[tuple[str, Image]] | list[tuple[str, Framebuffer]]):
88
+ """
89
+ Writes all given source images to the GPU
90
+ """
91
+
92
+ for i, source in enumerate(sources):
93
+ # Get the name and data
94
+ name, data = source
95
+
96
+ # Extract the needed data
97
+ if isinstance(data, mgl.Texture): texture = data
98
+ elif isinstance(data, Image) or isinstance(data, Framebuffer) or isinstance(data, type(self.engine.frame)): texture = data.texture
99
+ else: raise ValueError(f'PostProces.apply: Invalid postprocess source type {type(source)}')
100
+
101
+ # Write the texture
102
+ self.shader.program[name] = i
103
+ texture.use(location=i)
104
+
71
105
  def _render_post_process(self, source: mgl.Texture):
72
106
  # Clear and use the fbo as a render target
73
107
  self.fbo.use()
@@ -144,4 +178,4 @@ class PostProcess:
144
178
  def __del__(self):
145
179
  if self.vao: self.vao.release()
146
180
  if self.vbo: self.vbo.release()
147
- if self.fbo: self.fbo.release()
181
+ if self.fbo: self.fbo.__del__()
@@ -3,6 +3,12 @@ import glm
3
3
  from .shader import Shader
4
4
 
5
5
 
6
+ # Camera view constants
7
+ FOV = 50 # Degrees
8
+ NEAR = 0.1
9
+ FAR = 350
10
+
11
+
6
12
  class ShaderHandler:
7
13
  engine: ...
8
14
  """Back reference to the parent engine"""
@@ -64,7 +70,10 @@ class ShaderHandler:
64
70
  'cameraPosition' : scene.camera.position,
65
71
  'viewportDimensions' : glm.vec2(self.engine.win_size),
66
72
  'gamma' : self.engine.config.gamma,
67
- 'exposure' : self.engine.config.exposure
73
+ 'exposure' : self.engine.config.exposure,
74
+ 'near' : glm.float32(NEAR),
75
+ 'far' : glm.float32(FAR),
76
+ 'FOV' : glm.float32(FOV)
68
77
  }
69
78
 
70
79
  def write(self, scene: ...) -> None:
basilisk/render/sky.py CHANGED
@@ -6,15 +6,16 @@ class Sky:
6
6
  texture_cube=None
7
7
  vbo = None
8
8
  vao = None
9
- def __init__(self, engine, sky_texture: str | list=None):
9
+ def __init__(self, scene, sky_texture: str | list=None):
10
10
  """
11
11
  Handler for all skybox rendering
12
12
  """
13
13
 
14
- self.engine = engine
15
- self.ctx = engine.ctx
14
+ self.scene = scene
15
+ self.engine = scene.engine
16
+ self.ctx = scene.ctx
16
17
 
17
- if not sky_texture: sky_texture = engine.root + '/bsk_assets/skybox.png'
18
+ if not sky_texture: sky_texture = self.engine.root + '/bsk_assets/skybox.png'
18
19
 
19
20
  self.set_renderer()
20
21
  self.set_texture(sky_texture)
basilisk/scene.py CHANGED
@@ -47,7 +47,8 @@ class Scene():
47
47
  self.node_handler = NodeHandler(self)
48
48
  self.particle = ParticleHandler(self)
49
49
  self.collider_handler = ColliderHandler(self)
50
- self.sky = Sky(self.engine)
50
+ self.sky = Sky(self)
51
+ self.frame = Frame(self.engine)
51
52
 
52
53
 
53
54
  def update(self, render: bool=True, nodes: bool=True, particles: bool=True, collisions: bool=True) -> None:
@@ -55,45 +56,42 @@ class Scene():
55
56
  Updates the physics and in the scene
56
57
  """
57
58
 
58
- # Check that the engine is still running
59
+ # Call the internal engine update (for IO and time)
59
60
  self.engine._update()
61
+
62
+ # Check that the engine is still running
60
63
  if not self.engine.running: return
61
64
 
62
65
  # Update based on the given parameters
63
66
  if nodes: self.node_handler.update()
64
67
  if particles: self.particle.update()
65
- if self.engine.event_resize: self.camera.use()
68
+
69
+ # Update the camera
66
70
  self.camera.update()
71
+ if self.engine.event_resize: self.camera.use()
67
72
 
68
73
  if collisions and self.engine.delta_time < 0.5: # TODO this will cause physics to slow down when on low frame rate, this is probabl;y acceptable
69
74
  self.collider_handler.resolve_collisions()
70
75
 
71
- # Render by default to the engine frame
72
- if not render: return
76
+ # Render by default to the scene frame
77
+ if render: self.render()
73
78
 
74
- # Check if the user is giving a destination
75
- if not isinstance(render, bool): self.render(renders)
76
- else: self.render()
77
-
78
- def render(self, render_target: Framebuffer|Frame=None) -> None:
79
+ def render(self, target=None) -> None:
79
80
  """
80
81
  Renders all the nodes with meshes in the scene
81
82
  """
82
83
 
83
- if render_target:
84
- show = False
85
- else:
86
- render_target = self.engine.frame
87
- show = True
88
-
89
- render_target.use()
84
+ target.use() if target else self.frame.use(); self.frame.clear()
90
85
  self.engine.shader_handler.write(self)
91
- self.node_handler.render()
92
86
  self.particle.render()
87
+ self.node_handler.render()
93
88
  if self.sky: self.sky.render()
94
89
 
90
+ if target: return
91
+ # This will show the frame to screen on engine.update()
92
+ self.frame.scene_render(target)
93
+ self.engine.frames.append(self.frame)
95
94
 
96
- if self.engine.headless or not show: return
97
95
 
98
96
 
99
97
  def add(self, *objects: Node | None) -> None | Node | list:
@@ -2,6 +2,8 @@
2
2
 
3
3
  layout (location = 0) out vec4 fragColor;
4
4
  layout (location = 1) out vec4 bloomColor;
5
+ layout (location = 2) out vec4 normalTexture;
6
+
5
7
 
6
8
  // Structs needed for the shader
7
9
  struct textArray {
@@ -276,15 +278,17 @@ void main() {
276
278
  // finalColor = pow(finalColor, vec3(1.0/gamma));
277
279
 
278
280
  // Output fragment color
279
- float brightness = dot(fragColor.rgb, vec3(0.2126, 0.7152, 0.0722)) + dot(mtl.emissiveColor, vec3(1));
281
+ float brightness = dot(fragColor.rgb, vec3(0.2126, 0.7152, 0.0722)) + dot(lightResult.specular, vec3(.2)) + dot(mtl.emissiveColor, vec3(1));
280
282
  fragColor = vec4(finalColor + mtl.emissiveColor, 1.0);
281
283
 
282
- // Filter out bright pixels for bloom
283
- // bloomColor = vec4(0.0, 0.0, 0.0, 1.0);
284
+ normalTexture = vec4(abs(N), 1.0);
285
+
286
+ // // Filter out bright pixels for bloom
284
287
  if (brightness > 0.5) {
285
288
  bloomColor = vec4(fragColor.rgb, 1.0);
286
289
  }
287
290
  else{
288
291
  bloomColor = vec4(0.0, 0.0, 0.0, 1.0);
289
292
  }
293
+
290
294
  }
basilisk/shaders/crt.frag CHANGED
@@ -1,6 +1,7 @@
1
1
  #version 330 core
2
2
 
3
- out vec4 fragColor;
3
+ layout (location = 0) out vec4 fragColor;
4
+ layout (location = 1) out vec4 bloomColor;
4
5
 
5
6
  in vec2 uv;
6
7
 
@@ -29,4 +30,6 @@ void main(){
29
30
  //sample the texture
30
31
  fragColor = vec4(mix(texture(screenTexture, crt_uv).rgb,vec3(0.0), apply), 1.0);
31
32
  }
33
+
34
+ bloomColor = vec4(0.0, 0.0, 0.0, 0.0);
32
35
  }
@@ -2,6 +2,7 @@
2
2
 
3
3
  layout (location = 0) out vec4 fragColor;
4
4
  layout (location = 1) out vec4 bloomColor;
5
+ layout (location = 2) out vec4 normalTexture;
5
6
 
6
7
 
7
8
  in vec4 color;
@@ -22,5 +23,6 @@ void main() {
22
23
  else {
23
24
  fragColor = color;
24
25
  }
26
+ normalTexture = vec4(0.0);
25
27
  bloomColor = vec4(0.0);
26
28
  }
@@ -1,6 +1,6 @@
1
1
  #version 330 core
2
2
 
3
- out vec4 fragColor;
3
+ layout (location = 0) out vec4 fragColor;
4
4
 
5
5
  in vec2 uv;
6
6
 
@@ -9,5 +9,6 @@ uniform sampler2D screenTexture;
9
9
 
10
10
  void main()
11
11
  {
12
- fragColor = texture(screenTexture, uv);
12
+ vec4 color = texture(screenTexture, uv);
13
+ fragColor = color;
13
14
  }
@@ -0,0 +1,28 @@
1
+ #version 330 core
2
+
3
+ layout (location = 0) out vec4 fragColor;
4
+
5
+ in vec2 uv;
6
+
7
+ uniform sampler2D screenTexture;
8
+ uniform sampler2D bloomTexture;
9
+
10
+
11
+
12
+ void main()
13
+ {
14
+ const float gamma = 2.2;
15
+ const float exposure = 1.2;
16
+
17
+ // Sammple from textures
18
+ vec4 color = texture(screenTexture, uv);
19
+ vec4 bloom = texture(bloomTexture, uv);
20
+
21
+ vec3 hdrColor = color.rgb + bloom.rgb / 2;
22
+ // exposure tone mapping
23
+ vec3 mapped = vec3(1.0) - exp(-hdrColor * exposure);
24
+ // gamma correction
25
+ mapped = pow(mapped, vec3(1.0 / gamma));
26
+
27
+ fragColor = vec4(mapped, color.a);
28
+ }
@@ -2,6 +2,8 @@
2
2
 
3
3
  layout (location = 0) out vec4 fragColor;
4
4
  layout (location = 1) out vec4 bloomColor;
5
+ layout (location = 2) out vec4 normalTexture;
6
+
5
7
 
6
8
  in vec2 uv;
7
9
  in vec3 position;
@@ -73,5 +75,8 @@ void main()
73
75
  fragColor = vec4(color * (.2 + diff), 1.0);
74
76
  fragColor.rgb = pow(fragColor.rgb, vec3(1.0/gamma));
75
77
 
78
+ normalTexture = vec4(abs(normal), 1.0);
79
+
76
80
  bloomColor = vec4(mtl.emissiveColor, 1.0);
81
+
77
82
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: basilisk-engine
3
- Version: 0.1.40
3
+ Version: 0.1.42
4
4
  Summary: Python 3D Framework
5
5
  Home-page: https://basilisk-website.vercel.app/
6
6
  Author: Name
@@ -1,7 +1,7 @@
1
1
  basilisk/__init__.py,sha256=23OM1kiXMU44J2TVp66efVSrbQAeiuTDmcdhNAftFfY,1134
2
2
  basilisk/config.py,sha256=Ajm3BjCryuX5bmJglqRZDR1SjE0sDjTbulta5GZ67hA,1712
3
- basilisk/engine.py,sha256=74ErjbThT7kGrAhayA6p3QxUOX1ff4rwsoYj8-A-2aE,5722
4
- basilisk/scene.py,sha256=NSIpvYsZsvxKVkjZTeCHq6cL-wJQETEIjPu-d4xdzbc,12260
3
+ basilisk/engine.py,sha256=_SPTyqrOkn7GSMdjIPbk2m2HVLpePU236I1KA1qgtjw,6083
4
+ basilisk/scene.py,sha256=9iWy86exN5Y48fHCJEOS0gL_yQ0VEceXALo98EqTy4c,12260
5
5
  basilisk/audio/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  basilisk/audio/sound.py,sha256=h2dQ3IKb_SRKNZqNuk-fdNg_Xfz0P7sqEXA33qiBXG4,692
7
7
  basilisk/bsk_assets/Roboto-Regular.ttf,sha256=kqYnZjMRQMpbyLulIChCLSdgYa1XF8GsUIoRi2Gcauw,168260
@@ -10,7 +10,7 @@ basilisk/bsk_assets/basilisk.png,sha256=1xePD8qDycxlRQ7hjEmfuw900BRykhRyumJePi6h
10
10
  basilisk/bsk_assets/cube.obj,sha256=r_pjU5ZT0QuemKPKeFxEsZjNps90iTXuHK7W5wk2Hig,1141
11
11
  basilisk/bsk_assets/skybox.png,sha256=0C9MvWUwNzewyiMtWLKrZJzAcLC1Ce72T3-Lq4hJZu0,1206153
12
12
  basilisk/collisions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- basilisk/collisions/collider.py,sha256=RoA-RnBmy5OiBj6qLFA4WBL27EdRuLYSaf8tHc_MvN4,4478
13
+ basilisk/collisions/collider.py,sha256=5s5WI7_sctbgM1MmGdDds__8ZQ_N8-Xeba2rV-Qs3Ag,4489
14
14
  basilisk/collisions/collider_handler.py,sha256=iyFb4cQFrrYt9kRa8PZf3jih59-JgcB1MLZqMRELiYU,11231
15
15
  basilisk/collisions/broad/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
16
16
  basilisk/collisions/broad/broad_aabb.py,sha256=gI4bq89WnJ0Za2k6U2VGedjJ9aWvKua9tCUwBFl5h1U,4606
@@ -71,44 +71,45 @@ basilisk/physics/physics_body.py,sha256=-iqo3YyCfMzpBVNA2I34JbfN7Z6phj5nnGHN-S8l
71
71
  basilisk/physics/physics_engine.py,sha256=C30oGb8rODdXORJJWjOWBPwlScnTHrp6CTPHSNcbgp0,1700
72
72
  basilisk/render/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
73
  basilisk/render/batch.py,sha256=1ULXwzcs7v9ze1IDZDJXcaydRjwdgHH9TkyXxcadNiM,3396
74
- basilisk/render/bloom.py,sha256=hE9JJJ8MIqJ7kXO9jaBmDcc0kSzwLyU578F65pjbMXI,4077
74
+ basilisk/render/bloom.py,sha256=jjkUtg3SaP1by7FGR9E4780u6Xer0GK6y6XPH66vftw,4435
75
75
  basilisk/render/camera.py,sha256=pOM5sVSHl_joHwsBLd8Y7CzLUL-16XBBQfgsnM8jc6Q,9649
76
76
  basilisk/render/chunk.py,sha256=UPfldvGjIF--sg35Lst69ORZ2xTet-ejWg3kde9-ae8,2758
77
77
  basilisk/render/chunk_handler.py,sha256=-Hozyus67mgJ8fTWx3fsLezFVt3W4d-I0I1ai29odWA,6405
78
- basilisk/render/frame.py,sha256=9QfhbVitXXiL1ag_3qRcFuFR6zbc_4A1SLPs09KuPKc,3446
79
- basilisk/render/framebuffer.py,sha256=_LdsUTOsOwfeQ3Z7vKURwmNZPwBOKQ50MbOB1fbZvNI,7007
78
+ basilisk/render/frame.py,sha256=I1M5eDzbnjo5_9U3QL02WPGUHw6X-VmGvGtE7O5ILCo,4065
79
+ basilisk/render/framebuffer.py,sha256=4QO5QyX7tCwHysaUV9S2v5rGgg8xhmMzJ6ukjyboQKE,7570
80
80
  basilisk/render/image.py,sha256=d-5RGr-TlsGqvI-GQ8_pV-FNdmTzD0mlk2K3K4XNuwQ,3984
81
81
  basilisk/render/image_handler.py,sha256=DNb-AiouziLVQu3NkoG1F90YZTHHWyhFYhaWJ9uiUOU,4175
82
82
  basilisk/render/light.py,sha256=SOOh5zAGUCgQdJjWb5MlJgtvdxkEV8AWqQ4P93bJj2g,3783
83
83
  basilisk/render/light_handler.py,sha256=gvg4OhDMy8dZg5XNcOZB4_1G2uE1gBFRxlBeoG3l3vM,2104
84
84
  basilisk/render/material.py,sha256=K2w2pdNI_ZKc0DZqhcGhlj0kQcpSLSlhbPTk-xaisU4,10072
85
85
  basilisk/render/material_handler.py,sha256=b9mf35P54CUzSxBgCkteHEY7AMJ623Ct083Xu2fHBHI,4065
86
- basilisk/render/post_process.py,sha256=ZDj03c23Zw8ewgz0uQN5UIRCOm-7rjbI6ta9ofYAieY,5261
86
+ basilisk/render/post_process.py,sha256=QAIwNccycEJqA1UVGKUqwVus11sJX9qm3Mjl0gdGYSo,6519
87
87
  basilisk/render/shader.py,sha256=3_jMKzlwLLWPsZiIjVG8bYLu4CddXrnmCk3ECTD6oZE,4820
88
- basilisk/render/shader_handler.py,sha256=rj4zbhVOyYBdxcmB6BHE4pynSMk3VtIk4Qo2z_8JVf4,2846
89
- basilisk/render/sky.py,sha256=orTtgkU35AHZTUGk9IevSXwVs6tktoDP52yEUM5Rg0E,4768
88
+ basilisk/render/shader_handler.py,sha256=eMEvtUYr7bg7PMzmJb0HByWsK1l_xlcfjDrB3ZIqX4I,3029
89
+ basilisk/render/sky.py,sha256=e_x5h59cHevJFAprItBo_M3s1BqNI-1g1pgIsdeCuMw,4806
90
90
  basilisk/render/tempCodeRunnerFile.py,sha256=ep1eVZzUd30SDCNE5l3OJsqp2fW2LEXrjYGW31AMWgw,10
91
91
  basilisk/shaders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
92
- basilisk/shaders/batch.frag,sha256=zyKxzNlPOwAYYeRQCOl-mwGS_hZMesh5JkGcUJIVtf0,9541
92
+ basilisk/shaders/batch.frag,sha256=1U2neL5t6TSMXHgwnEoOjLmG4WNNTLJAkUSIzd4x6lE,9624
93
93
  basilisk/shaders/batch.vert,sha256=LYzcqcwCyCpnxF5V-ilx79HU2cYz66hylBmZChcVmos,5555
94
94
  basilisk/shaders/bloom_downsample.frag,sha256=0ncVnEfiPYxKnQ95seLTnbm8NXjMSYUIIrDE8owLUKU,1524
95
95
  basilisk/shaders/bloom_frame.frag,sha256=Y0m8DnQKz3G9FKq7VjCGrVXZw2vSigyGX7-tlxZN0lE,567
96
96
  basilisk/shaders/bloom_upsample.frag,sha256=Pe1AupjM2OCMieW7oEYHoEx2LhbPtbpwcylruF5Ntm4,1156
97
- basilisk/shaders/crt.frag,sha256=NsFtziQb5KnhjLcSI7UnxF2Jk7mLt2Fw2v4NDwhE_xE,934
98
- basilisk/shaders/draw.frag,sha256=Beel4sjY-cwbUCUULRjT2BzXfVA-rr12Abz1HxG6inw,528
97
+ basilisk/shaders/crt.frag,sha256=ss6xhXwwOH9bXEhqyim--K4o1BOo1Wwq6tGAwjpRHEQ,1043
98
+ basilisk/shaders/draw.frag,sha256=rcPmGMh850M1ypcFNlJCyFWxfZ739lVNl6OPTxPIYIE,605
99
99
  basilisk/shaders/draw.vert,sha256=Rpi6bDsLEiFmuLRCL3yMgmBOR_WWYHQ7LLUUA787cxs,596
100
100
  basilisk/shaders/filter.frag,sha256=N4o6429d3azn1CoN0gsLD1v8bG51tdUcmxRTj8R5jg8,562
101
- basilisk/shaders/frame.frag,sha256=efR8q-iLFVwXuYIpKHr6OKfbG7BwKvmhc-83w42elgY,148
101
+ basilisk/shaders/frame.frag,sha256=_fXX2C233URDvNtOgMocs6ZnEum_kaLZVIa5qc6QNz4,194
102
102
  basilisk/shaders/frame.vert,sha256=l2--IIGeRIbfuSyQksguVj3GHZKK-0tsQ6euQ83roUA,214
103
+ basilisk/shaders/frame_hdr.frag,sha256=Jd4ggkZQ6ZkqnfRmjJPoBN3wTpe0m8xoqNL_hS2epcY,585
103
104
  basilisk/shaders/geometry.frag,sha256=mTBMWqw7x9r65wNRqHMZeG4wBHmleOD8zAXYy2hcsU0,220
104
105
  basilisk/shaders/geometry.vert,sha256=v1Vb7s-D7GDgroGCi-um7ITD7LBlJgGsTtbhwjSYGdI,1432
105
106
  basilisk/shaders/normal.frag,sha256=RGI8wORa5x5ZI9YYB56qrZDgbp4qnEWKywHWRVhv_aM,1346
106
107
  basilisk/shaders/normal.vert,sha256=Q3t9NjdLcyUggh72Jxi990QtM5Ud2egvOUIBdr9PWqI,3224
107
- basilisk/shaders/particle.frag,sha256=dQ-TFurL7Dj5Xw_ySF3DpDXUegBnE4mf_vXl7dzbjpg,1884
108
+ basilisk/shaders/particle.frag,sha256=IskhyXelHs9GqABKwTYSwooWL0nP-nkmXl6a5iT6Q3A,1977
108
109
  basilisk/shaders/particle.vert,sha256=oiBz6S_2dzqioAhyzVYT1ZKOED4h4R6IoP-UJ8KRHhU,3227
109
110
  basilisk/shaders/sky.frag,sha256=dJRdSbg16aZYYjxdoG1spVQRIVBGNVdyX0rqp4ER6v8,556
110
111
  basilisk/shaders/sky.vert,sha256=oAnrknEgsd9MawE_zx8P0u9nUSFEBYBg5ykBmWpqZ_g,332
111
- basilisk_engine-0.1.40.dist-info/METADATA,sha256=G933y6W4DHYC8733l-Lj161v2Yw2QBFDdgRYX22PTnY,3793
112
- basilisk_engine-0.1.40.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
113
- basilisk_engine-0.1.40.dist-info/top_level.txt,sha256=enlSYSf7CUyAly1jmUCNNGInTbaFUjGk4SKwyckZQkw,9
114
- basilisk_engine-0.1.40.dist-info/RECORD,,
112
+ basilisk_engine-0.1.42.dist-info/METADATA,sha256=TWa8kZNEEc5aTKupEbwuEOQsPheWfIaIeO0lQqtqa2k,3793
113
+ basilisk_engine-0.1.42.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
114
+ basilisk_engine-0.1.42.dist-info/top_level.txt,sha256=enlSYSf7CUyAly1jmUCNNGInTbaFUjGk4SKwyckZQkw,9
115
+ basilisk_engine-0.1.42.dist-info/RECORD,,