basilisk-engine 0.1.52__py3-none-any.whl → 0.1.53__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 +27 -27
- basilisk/audio/sound.py +40 -40
- 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 -95
- basilisk/collisions/collider_handler.py +225 -225
- basilisk/collisions/narrow/contact_manifold.py +95 -95
- basilisk/collisions/narrow/dataclasses.py +34 -34
- 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 +53 -53
- basilisk/draw/draw.py +100 -100
- basilisk/draw/draw_handler.py +181 -181
- basilisk/draw/font_renderer.py +28 -28
- basilisk/engine.py +168 -168
- 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 +82 -82
- basilisk/generic/math.py +17 -17
- basilisk/generic/matrices.py +35 -35
- basilisk/generic/meshes.py +72 -72
- basilisk/generic/quat.py +142 -142
- basilisk/generic/quat_methods.py +7 -7
- basilisk/generic/raycast_result.py +26 -26
- basilisk/generic/vec3.py +143 -143
- basilisk/input_output/IO_handler.py +91 -91
- basilisk/input_output/clock.py +49 -49
- basilisk/input_output/keys.py +43 -43
- basilisk/input_output/mouse.py +90 -90
- basilisk/input_output/path.py +14 -14
- basilisk/mesh/cube.py +33 -33
- basilisk/mesh/mesh.py +233 -233
- basilisk/mesh/mesh_from_data.py +150 -150
- 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 +28 -28
- basilisk/nodes/node.py +709 -709
- basilisk/nodes/node_handler.py +106 -106
- basilisk/particles/particle_handler.py +68 -68
- basilisk/particles/particle_renderer.py +92 -92
- basilisk/physics/impulse.py +112 -112
- basilisk/physics/physics_body.py +43 -43
- basilisk/physics/physics_engine.py +35 -35
- basilisk/render/batch.py +103 -103
- basilisk/render/bloom.py +117 -117
- basilisk/render/camera.py +260 -260
- basilisk/render/chunk.py +113 -113
- basilisk/render/chunk_handler.py +167 -167
- basilisk/render/frame.py +130 -130
- basilisk/render/framebuffer.py +192 -192
- basilisk/render/image.py +128 -128
- basilisk/render/image_handler.py +120 -120
- basilisk/render/light.py +96 -96
- basilisk/render/light_handler.py +58 -58
- basilisk/render/material.py +232 -232
- basilisk/render/material_handler.py +133 -133
- basilisk/render/post_process.py +180 -180
- basilisk/render/shader.py +135 -135
- basilisk/render/shader_handler.py +109 -109
- basilisk/render/sky.py +119 -119
- basilisk/scene.py +295 -295
- basilisk/shaders/batch.frag +291 -291
- basilisk/shaders/batch.vert +117 -117
- basilisk/shaders/bloom_downsample.frag +23 -23
- basilisk/shaders/bloom_upsample.frag +33 -33
- basilisk/shaders/crt.frag +34 -34
- basilisk/shaders/draw.frag +27 -27
- basilisk/shaders/draw.vert +25 -25
- basilisk/shaders/filter.frag +22 -22
- basilisk/shaders/frame.frag +13 -13
- basilisk/shaders/frame.vert +13 -13
- basilisk/shaders/frame_hdr.frag +27 -27
- basilisk/shaders/geometry.frag +10 -10
- basilisk/shaders/geometry.vert +41 -41
- basilisk/shaders/normal.frag +62 -62
- basilisk/shaders/normal.vert +96 -96
- basilisk/shaders/particle.frag +81 -81
- basilisk/shaders/particle.vert +86 -86
- basilisk/shaders/sky.frag +23 -23
- basilisk/shaders/sky.vert +13 -13
- {basilisk_engine-0.1.52.dist-info → basilisk_engine-0.1.53.dist-info}/METADATA +82 -89
- basilisk_engine-0.1.53.dist-info/RECORD +110 -0
- {basilisk_engine-0.1.52.dist-info → basilisk_engine-0.1.53.dist-info}/WHEEL +1 -1
- basilisk_engine-0.1.52.dist-info/RECORD +0 -110
- {basilisk_engine-0.1.52.dist-info → basilisk_engine-0.1.53.dist-info}/top_level.txt +0 -0
basilisk/draw/draw.py
CHANGED
|
@@ -1,101 +1,101 @@
|
|
|
1
|
-
from ..engine import Engine
|
|
2
|
-
from ..render.image import Image
|
|
3
|
-
|
|
4
|
-
def rect(engine: Engine, color: tuple, rect: tuple) -> None:
|
|
5
|
-
"""
|
|
6
|
-
Draws a rectagle to the screen
|
|
7
|
-
Args:
|
|
8
|
-
engine: bsk.Engine
|
|
9
|
-
The destination engine for the rectangle
|
|
10
|
-
color: tuple(r, g, b) | tuple(r, g, b, a)
|
|
11
|
-
The color value of the rectangle, with int components in range [0, 255]
|
|
12
|
-
rect: tuple(x, y, w, h)
|
|
13
|
-
The screen position and size of the rectangle given in pixels
|
|
14
|
-
"""
|
|
15
|
-
|
|
16
|
-
# Get the draw handler from the engine
|
|
17
|
-
draw_handler = engine.draw_handler
|
|
18
|
-
if not draw_handler: return
|
|
19
|
-
|
|
20
|
-
# Draw the rect
|
|
21
|
-
draw_handler.draw_rect(color, rect)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def circle(engine: Engine, color: tuple, center: tuple, radius: int, resolution: int=20, outer_color: tuple=None) -> None:
|
|
25
|
-
"""
|
|
26
|
-
Draws a rect between centered on x, y with width and height
|
|
27
|
-
Args:
|
|
28
|
-
color: tuple(r, g, b) | tuple(r, g, b, a)
|
|
29
|
-
The color value of the circle, with int components in range [0, 255]
|
|
30
|
-
center: tuple (x: float, y: float)
|
|
31
|
-
Center of the circle, given in pixels
|
|
32
|
-
radius: float
|
|
33
|
-
Radius of the circle, given in pixels
|
|
34
|
-
resolution: float
|
|
35
|
-
The number of triangles used to approximate the circle
|
|
36
|
-
"""
|
|
37
|
-
|
|
38
|
-
# Get the draw handler from the engine
|
|
39
|
-
draw_handler = engine.draw_handler
|
|
40
|
-
if not draw_handler: return
|
|
41
|
-
|
|
42
|
-
# Draw the circle
|
|
43
|
-
draw_handler.draw_circle(color, center, radius, resolution, outer_color)
|
|
44
|
-
|
|
45
|
-
def line(engine: Engine, color: tuple, p1: tuple, p2: tuple, thickness: int=1) -> None:
|
|
46
|
-
"""
|
|
47
|
-
Draws a line between two points
|
|
48
|
-
Args:
|
|
49
|
-
color: tuple=(r, g, b) | tuple=(r, g, b, a)
|
|
50
|
-
Color of the line
|
|
51
|
-
p1: tuple=((x1, y1), (x2, y2))
|
|
52
|
-
Starting point of the line. Given in pixels
|
|
53
|
-
p1: tuple=((x1, y1), (x2, y2))
|
|
54
|
-
Starting point of the line. Given in pixels
|
|
55
|
-
thickness: int
|
|
56
|
-
Size of the line on either side. pixels
|
|
57
|
-
"""
|
|
58
|
-
|
|
59
|
-
# Get the draw handler from the engine
|
|
60
|
-
draw_handler = engine.draw_handler
|
|
61
|
-
if not draw_handler: return
|
|
62
|
-
|
|
63
|
-
# Draw the line
|
|
64
|
-
draw_handler.draw_line(color, p1, p2, thickness)
|
|
65
|
-
|
|
66
|
-
def blit(engine: Engine, image: Image, rect: tuple, alpha: float=1.0):
|
|
67
|
-
"""
|
|
68
|
-
Blits a basilisk image to the engine screen.
|
|
69
|
-
Args:
|
|
70
|
-
image: bsk.Image
|
|
71
|
-
The image to display on the screen
|
|
72
|
-
rect: tuple(x, y, w, h)
|
|
73
|
-
The screen position and size of the image given in pixels
|
|
74
|
-
"""
|
|
75
|
-
|
|
76
|
-
# Get the draw handler from the engine
|
|
77
|
-
draw_handler = engine.draw_handler
|
|
78
|
-
if not draw_handler: return
|
|
79
|
-
|
|
80
|
-
engine.material_handler.image_handler.add(image)
|
|
81
|
-
|
|
82
|
-
# Blit the image
|
|
83
|
-
draw_handler.blit(image, rect, alpha)
|
|
84
|
-
|
|
85
|
-
def text(engine: Engine, text: str, position: tuple, scale: float=1.0):
|
|
86
|
-
"""
|
|
87
|
-
Renders text do the screen
|
|
88
|
-
USE SPARINGLY, INEFFICIENT IMPLAMENTATION
|
|
89
|
-
"""
|
|
90
|
-
|
|
91
|
-
font_renderer = engine.draw_handler.font_renderer
|
|
92
|
-
|
|
93
|
-
# Render the text if it has not been cached
|
|
94
|
-
if text not in font_renderer.text_renders:
|
|
95
|
-
surf = font_renderer.render(text).convert_alpha()
|
|
96
|
-
text_image = Image(surf, flip_y=False)
|
|
97
|
-
font_renderer.text_renders[text] = (text_image, surf.get_rect())
|
|
98
|
-
|
|
99
|
-
# Blit the text image
|
|
100
|
-
img, rect = font_renderer.text_renders[text]
|
|
1
|
+
from ..engine import Engine
|
|
2
|
+
from ..render.image import Image
|
|
3
|
+
|
|
4
|
+
def rect(engine: Engine, color: tuple, rect: tuple) -> None:
|
|
5
|
+
"""
|
|
6
|
+
Draws a rectagle to the screen
|
|
7
|
+
Args:
|
|
8
|
+
engine: bsk.Engine
|
|
9
|
+
The destination engine for the rectangle
|
|
10
|
+
color: tuple(r, g, b) | tuple(r, g, b, a)
|
|
11
|
+
The color value of the rectangle, with int components in range [0, 255]
|
|
12
|
+
rect: tuple(x, y, w, h)
|
|
13
|
+
The screen position and size of the rectangle given in pixels
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
# Get the draw handler from the engine
|
|
17
|
+
draw_handler = engine.draw_handler
|
|
18
|
+
if not draw_handler: return
|
|
19
|
+
|
|
20
|
+
# Draw the rect
|
|
21
|
+
draw_handler.draw_rect(color, rect)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def circle(engine: Engine, color: tuple, center: tuple, radius: int, resolution: int=20, outer_color: tuple=None) -> None:
|
|
25
|
+
"""
|
|
26
|
+
Draws a rect between centered on x, y with width and height
|
|
27
|
+
Args:
|
|
28
|
+
color: tuple(r, g, b) | tuple(r, g, b, a)
|
|
29
|
+
The color value of the circle, with int components in range [0, 255]
|
|
30
|
+
center: tuple (x: float, y: float)
|
|
31
|
+
Center of the circle, given in pixels
|
|
32
|
+
radius: float
|
|
33
|
+
Radius of the circle, given in pixels
|
|
34
|
+
resolution: float
|
|
35
|
+
The number of triangles used to approximate the circle
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
# Get the draw handler from the engine
|
|
39
|
+
draw_handler = engine.draw_handler
|
|
40
|
+
if not draw_handler: return
|
|
41
|
+
|
|
42
|
+
# Draw the circle
|
|
43
|
+
draw_handler.draw_circle(color, center, radius, resolution, outer_color)
|
|
44
|
+
|
|
45
|
+
def line(engine: Engine, color: tuple, p1: tuple, p2: tuple, thickness: int=1) -> None:
|
|
46
|
+
"""
|
|
47
|
+
Draws a line between two points
|
|
48
|
+
Args:
|
|
49
|
+
color: tuple=(r, g, b) | tuple=(r, g, b, a)
|
|
50
|
+
Color of the line
|
|
51
|
+
p1: tuple=((x1, y1), (x2, y2))
|
|
52
|
+
Starting point of the line. Given in pixels
|
|
53
|
+
p1: tuple=((x1, y1), (x2, y2))
|
|
54
|
+
Starting point of the line. Given in pixels
|
|
55
|
+
thickness: int
|
|
56
|
+
Size of the line on either side. pixels
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
# Get the draw handler from the engine
|
|
60
|
+
draw_handler = engine.draw_handler
|
|
61
|
+
if not draw_handler: return
|
|
62
|
+
|
|
63
|
+
# Draw the line
|
|
64
|
+
draw_handler.draw_line(color, p1, p2, thickness)
|
|
65
|
+
|
|
66
|
+
def blit(engine: Engine, image: Image, rect: tuple, alpha: float=1.0):
|
|
67
|
+
"""
|
|
68
|
+
Blits a basilisk image to the engine screen.
|
|
69
|
+
Args:
|
|
70
|
+
image: bsk.Image
|
|
71
|
+
The image to display on the screen
|
|
72
|
+
rect: tuple(x, y, w, h)
|
|
73
|
+
The screen position and size of the image given in pixels
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
# Get the draw handler from the engine
|
|
77
|
+
draw_handler = engine.draw_handler
|
|
78
|
+
if not draw_handler: return
|
|
79
|
+
|
|
80
|
+
engine.material_handler.image_handler.add(image)
|
|
81
|
+
|
|
82
|
+
# Blit the image
|
|
83
|
+
draw_handler.blit(image, rect, alpha)
|
|
84
|
+
|
|
85
|
+
def text(engine: Engine, text: str, position: tuple, scale: float=1.0):
|
|
86
|
+
"""
|
|
87
|
+
Renders text do the screen
|
|
88
|
+
USE SPARINGLY, INEFFICIENT IMPLAMENTATION
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
font_renderer = engine.draw_handler.font_renderer
|
|
92
|
+
|
|
93
|
+
# Render the text if it has not been cached
|
|
94
|
+
if text not in font_renderer.text_renders:
|
|
95
|
+
surf = font_renderer.render(text).convert_alpha()
|
|
96
|
+
text_image = Image(surf, flip_y=False)
|
|
97
|
+
font_renderer.text_renders[text] = (text_image, surf.get_rect())
|
|
98
|
+
|
|
99
|
+
# Blit the text image
|
|
100
|
+
img, rect = font_renderer.text_renders[text]
|
|
101
101
|
blit(engine, img, (position[0] - rect[2] * scale / 2, position[1] - rect[3] * scale / 2, rect[2] * scale, rect[3] * scale))
|
basilisk/draw/draw_handler.py
CHANGED
|
@@ -1,182 +1,182 @@
|
|
|
1
|
-
import moderngl as mgl
|
|
2
|
-
import numpy as np
|
|
3
|
-
import glm
|
|
4
|
-
from math import cos, sin, atan2
|
|
5
|
-
from ..render.image import Image
|
|
6
|
-
from .font_renderer import FontRenderer
|
|
7
|
-
from ..render.shader import Shader
|
|
8
|
-
from ..generic.input_validation import validate_color, validate_rect, validate_point
|
|
9
|
-
|
|
10
|
-
class DrawHandler():
|
|
11
|
-
engine: ...
|
|
12
|
-
ctx: mgl.Context
|
|
13
|
-
"""Back reference to the parent context"""
|
|
14
|
-
program: mgl.Program
|
|
15
|
-
"""2D draw program"""
|
|
16
|
-
draw_data: list[float]
|
|
17
|
-
"""Temporary buffer for user draw calls"""
|
|
18
|
-
vbo: mgl.Buffer=None
|
|
19
|
-
"""Buffer for all 2D draws"""
|
|
20
|
-
vao: mgl.VertexArray=None
|
|
21
|
-
"""VAO for rendering all 2D draw calls"""
|
|
22
|
-
|
|
23
|
-
def __init__(self, engine) -> None:
|
|
24
|
-
# Back references
|
|
25
|
-
self.engine = engine
|
|
26
|
-
self.ctx = engine.ctx
|
|
27
|
-
|
|
28
|
-
# Get the shader
|
|
29
|
-
root = self.engine.root
|
|
30
|
-
self.shader = self.engine.shader_handler.add(Shader(self.engine, root + '/shaders/draw.vert', root + '/shaders/draw.frag'))
|
|
31
|
-
|
|
32
|
-
# Initialize draw data as blank
|
|
33
|
-
self.draw_data = []
|
|
34
|
-
self.vbo = None
|
|
35
|
-
self.vao = None
|
|
36
|
-
|
|
37
|
-
self.font_renderer = FontRenderer(self.engine.root)
|
|
38
|
-
|
|
39
|
-
def render(self) -> None:
|
|
40
|
-
"""
|
|
41
|
-
Renders all draw calls from the user since the last frame
|
|
42
|
-
"""
|
|
43
|
-
|
|
44
|
-
if not self.draw_data: return
|
|
45
|
-
|
|
46
|
-
self.ctx.enable(mgl.BLEND)
|
|
47
|
-
self.ctx.disable(mgl.DEPTH_TEST)
|
|
48
|
-
# self.ctx.blend_func = mgl.DEFAULT_BLENDING
|
|
49
|
-
|
|
50
|
-
# Reverse the draw order, and convert to C-like array
|
|
51
|
-
# self.draw_data.reverse()
|
|
52
|
-
data = np.array(self.draw_data, dtype='f4')
|
|
53
|
-
ratio = np.array([2 / self.engine.win_size[0], 2 / self.engine.win_size[1]])
|
|
54
|
-
data[:,:2] = data[:,:2] * ratio - 1
|
|
55
|
-
|
|
56
|
-
# Create buffer and VAO
|
|
57
|
-
self.vbo = self.ctx.buffer(data)
|
|
58
|
-
self.vao = self.ctx.vertex_array(self.shader.program, [(self.vbo, '2f 4f 1i 1f', *['in_position', 'in_color', 'in_uses_image', 'in_alpha'])], skip_errors=True)
|
|
59
|
-
|
|
60
|
-
# Render the VAO
|
|
61
|
-
self.vao.render()
|
|
62
|
-
|
|
63
|
-
# Clera the draw data
|
|
64
|
-
self.vbo.release()
|
|
65
|
-
self.vao.release()
|
|
66
|
-
self.vbo = None
|
|
67
|
-
self.vao = None
|
|
68
|
-
self.draw_data.clear()
|
|
69
|
-
|
|
70
|
-
self.ctx.disable(mgl.BLEND)
|
|
71
|
-
self.ctx.enable(mgl.DEPTH_TEST)
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
def draw_rect(self, color: tuple, rect: tuple) -> None:
|
|
75
|
-
"""
|
|
76
|
-
Draws a rect to the screen
|
|
77
|
-
"""
|
|
78
|
-
|
|
79
|
-
color = validate_color('draw', 'color', color)
|
|
80
|
-
rect = validate_rect(rect)
|
|
81
|
-
|
|
82
|
-
p1 = (rect[0] , rect[1] )
|
|
83
|
-
p2 = (rect[0] , rect[1] + rect[3])
|
|
84
|
-
p3 = (rect[0] + rect[2], rect[1] )
|
|
85
|
-
p4 = (rect[0] + rect[2], rect[1] + rect[3])
|
|
86
|
-
|
|
87
|
-
v1 = (*p1, *color, 0, 0.0)
|
|
88
|
-
v2 = (*p2, *color, 0, 0.0)
|
|
89
|
-
v3 = (*p3, *color, 0, 0.0)
|
|
90
|
-
v4 = (*p4, *color, 0, 0.0)
|
|
91
|
-
|
|
92
|
-
self.draw_data.extend([
|
|
93
|
-
v1, v2, v3,
|
|
94
|
-
v2, v4, v3
|
|
95
|
-
])
|
|
96
|
-
|
|
97
|
-
def draw_circle(self, color: tuple, center: tuple, radius: int, resolution: int=20, outer_color: tuple=None) -> None:
|
|
98
|
-
"""
|
|
99
|
-
Draws a rect between centered on x, y with width and height
|
|
100
|
-
Args:
|
|
101
|
-
color: tuple(r, g, b) | tuple(r, g, b, a)
|
|
102
|
-
The color value of the circle, with int components in range [0, 255]
|
|
103
|
-
center: tuple (x: float, y: float)
|
|
104
|
-
Center of the circle, given in pixels
|
|
105
|
-
radius: float
|
|
106
|
-
Radius of the circle, given in pixels
|
|
107
|
-
resolution: float
|
|
108
|
-
The number of triangles used to approximate the circle
|
|
109
|
-
"""
|
|
110
|
-
|
|
111
|
-
if not outer_color: outer_color = color
|
|
112
|
-
color = validate_color('draw', 'color', color)
|
|
113
|
-
outer_color = validate_color('draw', 'color', outer_color)
|
|
114
|
-
p1 = validate_point(center)
|
|
115
|
-
|
|
116
|
-
v1 = (*p1, *color, 0, 0.0)
|
|
117
|
-
theta = 0
|
|
118
|
-
delta_theta = (2 * 3.1415) / resolution
|
|
119
|
-
|
|
120
|
-
for triangle in range(resolution):
|
|
121
|
-
v2 = (center[0] + radius * cos(theta), center[1] + radius * sin(theta), *outer_color, 0, 0.0)
|
|
122
|
-
theta += delta_theta
|
|
123
|
-
v3 = (center[0] + radius * cos(theta), center[1] + radius * sin(theta), *outer_color, 0, 0.0)
|
|
124
|
-
self.draw_data.extend([v1, v3, v2])
|
|
125
|
-
|
|
126
|
-
def draw_line(self, color: tuple, p1: tuple, p2: tuple, thickness: int=1):
|
|
127
|
-
"""
|
|
128
|
-
Draws a line between two points
|
|
129
|
-
Args:
|
|
130
|
-
color: tuple=(r, g, b) | tuple=(r, g, b, a)
|
|
131
|
-
Color of the line
|
|
132
|
-
p1: tuple=((x1, y1), (x2, y2))
|
|
133
|
-
Starting point of the line. Given in pixels
|
|
134
|
-
p1: tuple=((x1, y1), (x2, y2))
|
|
135
|
-
Starting point of the line. Given in pixels
|
|
136
|
-
thickness: int
|
|
137
|
-
Size of the line on either side. pixels
|
|
138
|
-
"""
|
|
139
|
-
|
|
140
|
-
color = validate_color('draw', 'color', color)
|
|
141
|
-
|
|
142
|
-
p1 = glm.vec2(validate_point(p1))
|
|
143
|
-
p2 = glm.vec2(validate_point(p2))
|
|
144
|
-
|
|
145
|
-
thickness /= 2
|
|
146
|
-
|
|
147
|
-
unit = glm.normalize(p1 - p2) * thickness
|
|
148
|
-
theta = atan2(*unit)
|
|
149
|
-
perp_vector = glm.vec2(cos(-theta), sin(-theta)) * thickness
|
|
150
|
-
|
|
151
|
-
v1 = (*(p1 - perp_vector), *color, 0, 0.0)
|
|
152
|
-
v2 = (*(p1 + perp_vector), *color, 0, 0.0)
|
|
153
|
-
v3 = (*(p2 - perp_vector), *color, 0, 0.0)
|
|
154
|
-
v4 = (*(p2 + perp_vector), *color, 0, 0.0)
|
|
155
|
-
|
|
156
|
-
self.draw_data.extend([v1, v4, v3, v2, v4, v1])
|
|
157
|
-
|
|
158
|
-
def blit(self, image: Image, rect: tuple, alpha: float=1.0):
|
|
159
|
-
rect = validate_rect(rect)
|
|
160
|
-
|
|
161
|
-
p1 = (rect[0] , rect[1] )
|
|
162
|
-
p2 = (rect[0] , rect[1] + rect[3])
|
|
163
|
-
p3 = (rect[0] + rect[2], rect[1] )
|
|
164
|
-
p4 = (rect[0] + rect[2], rect[1] + rect[3])
|
|
165
|
-
|
|
166
|
-
v1 = (*p1, *image.index, 0, 0, 1, alpha)
|
|
167
|
-
v2 = (*p2, *image.index, 0, 1, 1, alpha)
|
|
168
|
-
v3 = (*p3, *image.index, 1, 0, 1, alpha)
|
|
169
|
-
v4 = (*p4, *image.index, 1, 1, 1, alpha)
|
|
170
|
-
|
|
171
|
-
self.draw_data.extend([
|
|
172
|
-
v1, v2, v3,
|
|
173
|
-
v2, v4, v3
|
|
174
|
-
])
|
|
175
|
-
|
|
176
|
-
def __del__(self) -> None:
|
|
177
|
-
"""
|
|
178
|
-
Releases any allocated data
|
|
179
|
-
"""
|
|
180
|
-
|
|
181
|
-
if self.vbo: self.vbo.release()
|
|
1
|
+
import moderngl as mgl
|
|
2
|
+
import numpy as np
|
|
3
|
+
import glm
|
|
4
|
+
from math import cos, sin, atan2
|
|
5
|
+
from ..render.image import Image
|
|
6
|
+
from .font_renderer import FontRenderer
|
|
7
|
+
from ..render.shader import Shader
|
|
8
|
+
from ..generic.input_validation import validate_color, validate_rect, validate_point
|
|
9
|
+
|
|
10
|
+
class DrawHandler():
|
|
11
|
+
engine: ...
|
|
12
|
+
ctx: mgl.Context
|
|
13
|
+
"""Back reference to the parent context"""
|
|
14
|
+
program: mgl.Program
|
|
15
|
+
"""2D draw program"""
|
|
16
|
+
draw_data: list[float]
|
|
17
|
+
"""Temporary buffer for user draw calls"""
|
|
18
|
+
vbo: mgl.Buffer=None
|
|
19
|
+
"""Buffer for all 2D draws"""
|
|
20
|
+
vao: mgl.VertexArray=None
|
|
21
|
+
"""VAO for rendering all 2D draw calls"""
|
|
22
|
+
|
|
23
|
+
def __init__(self, engine) -> None:
|
|
24
|
+
# Back references
|
|
25
|
+
self.engine = engine
|
|
26
|
+
self.ctx = engine.ctx
|
|
27
|
+
|
|
28
|
+
# Get the shader
|
|
29
|
+
root = self.engine.root
|
|
30
|
+
self.shader = self.engine.shader_handler.add(Shader(self.engine, root + '/shaders/draw.vert', root + '/shaders/draw.frag'))
|
|
31
|
+
|
|
32
|
+
# Initialize draw data as blank
|
|
33
|
+
self.draw_data = []
|
|
34
|
+
self.vbo = None
|
|
35
|
+
self.vao = None
|
|
36
|
+
|
|
37
|
+
self.font_renderer = FontRenderer(self.engine.root)
|
|
38
|
+
|
|
39
|
+
def render(self) -> None:
|
|
40
|
+
"""
|
|
41
|
+
Renders all draw calls from the user since the last frame
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
if not self.draw_data: return
|
|
45
|
+
|
|
46
|
+
self.ctx.enable(mgl.BLEND)
|
|
47
|
+
self.ctx.disable(mgl.DEPTH_TEST)
|
|
48
|
+
# self.ctx.blend_func = mgl.DEFAULT_BLENDING
|
|
49
|
+
|
|
50
|
+
# Reverse the draw order, and convert to C-like array
|
|
51
|
+
# self.draw_data.reverse()
|
|
52
|
+
data = np.array(self.draw_data, dtype='f4')
|
|
53
|
+
ratio = np.array([2 / self.engine.win_size[0], 2 / self.engine.win_size[1]])
|
|
54
|
+
data[:,:2] = data[:,:2] * ratio - 1
|
|
55
|
+
|
|
56
|
+
# Create buffer and VAO
|
|
57
|
+
self.vbo = self.ctx.buffer(data)
|
|
58
|
+
self.vao = self.ctx.vertex_array(self.shader.program, [(self.vbo, '2f 4f 1i 1f', *['in_position', 'in_color', 'in_uses_image', 'in_alpha'])], skip_errors=True)
|
|
59
|
+
|
|
60
|
+
# Render the VAO
|
|
61
|
+
self.vao.render()
|
|
62
|
+
|
|
63
|
+
# Clera the draw data
|
|
64
|
+
self.vbo.release()
|
|
65
|
+
self.vao.release()
|
|
66
|
+
self.vbo = None
|
|
67
|
+
self.vao = None
|
|
68
|
+
self.draw_data.clear()
|
|
69
|
+
|
|
70
|
+
self.ctx.disable(mgl.BLEND)
|
|
71
|
+
self.ctx.enable(mgl.DEPTH_TEST)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def draw_rect(self, color: tuple, rect: tuple) -> None:
|
|
75
|
+
"""
|
|
76
|
+
Draws a rect to the screen
|
|
77
|
+
"""
|
|
78
|
+
|
|
79
|
+
color = validate_color('draw', 'color', color)
|
|
80
|
+
rect = validate_rect(rect)
|
|
81
|
+
|
|
82
|
+
p1 = (rect[0] , rect[1] )
|
|
83
|
+
p2 = (rect[0] , rect[1] + rect[3])
|
|
84
|
+
p3 = (rect[0] + rect[2], rect[1] )
|
|
85
|
+
p4 = (rect[0] + rect[2], rect[1] + rect[3])
|
|
86
|
+
|
|
87
|
+
v1 = (*p1, *color, 0, 0.0)
|
|
88
|
+
v2 = (*p2, *color, 0, 0.0)
|
|
89
|
+
v3 = (*p3, *color, 0, 0.0)
|
|
90
|
+
v4 = (*p4, *color, 0, 0.0)
|
|
91
|
+
|
|
92
|
+
self.draw_data.extend([
|
|
93
|
+
v1, v2, v3,
|
|
94
|
+
v2, v4, v3
|
|
95
|
+
])
|
|
96
|
+
|
|
97
|
+
def draw_circle(self, color: tuple, center: tuple, radius: int, resolution: int=20, outer_color: tuple=None) -> None:
|
|
98
|
+
"""
|
|
99
|
+
Draws a rect between centered on x, y with width and height
|
|
100
|
+
Args:
|
|
101
|
+
color: tuple(r, g, b) | tuple(r, g, b, a)
|
|
102
|
+
The color value of the circle, with int components in range [0, 255]
|
|
103
|
+
center: tuple (x: float, y: float)
|
|
104
|
+
Center of the circle, given in pixels
|
|
105
|
+
radius: float
|
|
106
|
+
Radius of the circle, given in pixels
|
|
107
|
+
resolution: float
|
|
108
|
+
The number of triangles used to approximate the circle
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
if not outer_color: outer_color = color
|
|
112
|
+
color = validate_color('draw', 'color', color)
|
|
113
|
+
outer_color = validate_color('draw', 'color', outer_color)
|
|
114
|
+
p1 = validate_point(center)
|
|
115
|
+
|
|
116
|
+
v1 = (*p1, *color, 0, 0.0)
|
|
117
|
+
theta = 0
|
|
118
|
+
delta_theta = (2 * 3.1415) / resolution
|
|
119
|
+
|
|
120
|
+
for triangle in range(resolution):
|
|
121
|
+
v2 = (center[0] + radius * cos(theta), center[1] + radius * sin(theta), *outer_color, 0, 0.0)
|
|
122
|
+
theta += delta_theta
|
|
123
|
+
v3 = (center[0] + radius * cos(theta), center[1] + radius * sin(theta), *outer_color, 0, 0.0)
|
|
124
|
+
self.draw_data.extend([v1, v3, v2])
|
|
125
|
+
|
|
126
|
+
def draw_line(self, color: tuple, p1: tuple, p2: tuple, thickness: int=1):
|
|
127
|
+
"""
|
|
128
|
+
Draws a line between two points
|
|
129
|
+
Args:
|
|
130
|
+
color: tuple=(r, g, b) | tuple=(r, g, b, a)
|
|
131
|
+
Color of the line
|
|
132
|
+
p1: tuple=((x1, y1), (x2, y2))
|
|
133
|
+
Starting point of the line. Given in pixels
|
|
134
|
+
p1: tuple=((x1, y1), (x2, y2))
|
|
135
|
+
Starting point of the line. Given in pixels
|
|
136
|
+
thickness: int
|
|
137
|
+
Size of the line on either side. pixels
|
|
138
|
+
"""
|
|
139
|
+
|
|
140
|
+
color = validate_color('draw', 'color', color)
|
|
141
|
+
|
|
142
|
+
p1 = glm.vec2(validate_point(p1))
|
|
143
|
+
p2 = glm.vec2(validate_point(p2))
|
|
144
|
+
|
|
145
|
+
thickness /= 2
|
|
146
|
+
|
|
147
|
+
unit = glm.normalize(p1 - p2) * thickness
|
|
148
|
+
theta = atan2(*unit)
|
|
149
|
+
perp_vector = glm.vec2(cos(-theta), sin(-theta)) * thickness
|
|
150
|
+
|
|
151
|
+
v1 = (*(p1 - perp_vector), *color, 0, 0.0)
|
|
152
|
+
v2 = (*(p1 + perp_vector), *color, 0, 0.0)
|
|
153
|
+
v3 = (*(p2 - perp_vector), *color, 0, 0.0)
|
|
154
|
+
v4 = (*(p2 + perp_vector), *color, 0, 0.0)
|
|
155
|
+
|
|
156
|
+
self.draw_data.extend([v1, v4, v3, v2, v4, v1])
|
|
157
|
+
|
|
158
|
+
def blit(self, image: Image, rect: tuple, alpha: float=1.0):
|
|
159
|
+
rect = validate_rect(rect)
|
|
160
|
+
|
|
161
|
+
p1 = (rect[0] , rect[1] )
|
|
162
|
+
p2 = (rect[0] , rect[1] + rect[3])
|
|
163
|
+
p3 = (rect[0] + rect[2], rect[1] )
|
|
164
|
+
p4 = (rect[0] + rect[2], rect[1] + rect[3])
|
|
165
|
+
|
|
166
|
+
v1 = (*p1, *image.index, 0, 0, 1, alpha)
|
|
167
|
+
v2 = (*p2, *image.index, 0, 1, 1, alpha)
|
|
168
|
+
v3 = (*p3, *image.index, 1, 0, 1, alpha)
|
|
169
|
+
v4 = (*p4, *image.index, 1, 1, 1, alpha)
|
|
170
|
+
|
|
171
|
+
self.draw_data.extend([
|
|
172
|
+
v1, v2, v3,
|
|
173
|
+
v2, v4, v3
|
|
174
|
+
])
|
|
175
|
+
|
|
176
|
+
def __del__(self) -> None:
|
|
177
|
+
"""
|
|
178
|
+
Releases any allocated data
|
|
179
|
+
"""
|
|
180
|
+
|
|
181
|
+
if self.vbo: self.vbo.release()
|
|
182
182
|
if self.vao: self.vao.release()
|
basilisk/draw/font_renderer.py
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import pygame as pg
|
|
2
|
-
|
|
3
|
-
class FontRenderer():
|
|
4
|
-
def __init__(self, root):
|
|
5
|
-
pg.font.init()
|
|
6
|
-
self.font = pg.font.Font(root + '/bsk_assets/Roboto-Regular.ttf', 48)
|
|
7
|
-
self.text_renders = {}
|
|
8
|
-
|
|
9
|
-
def render(self, text, color=(255, 255, 255), bold=False, underline=False, italic=False):
|
|
10
|
-
'''
|
|
11
|
-
Renders any font which has been loaded to the class instance.
|
|
12
|
-
Args:
|
|
13
|
-
text::str
|
|
14
|
-
Text to be rendered
|
|
15
|
-
color::(int, int, int) =(255, 255, 255)
|
|
16
|
-
The RGB value of the text
|
|
17
|
-
bold::bool (=False)
|
|
18
|
-
Specifies if the text should be rendered in bolded font
|
|
19
|
-
underline::bool (=False)
|
|
20
|
-
Specifies if the text should be underlined in bolded font
|
|
21
|
-
italic::bool (=False)
|
|
22
|
-
Specifies if the text should be rendered in italicized font
|
|
23
|
-
'''
|
|
24
|
-
self.font.set_bold(bold)
|
|
25
|
-
self.font.set_underline(underline)
|
|
26
|
-
self.font.set_italic(italic)
|
|
27
|
-
|
|
28
|
-
return self.font.render(text, True, color, (0, 0, 0, 0))
|
|
1
|
+
import pygame as pg
|
|
2
|
+
|
|
3
|
+
class FontRenderer():
|
|
4
|
+
def __init__(self, root):
|
|
5
|
+
pg.font.init()
|
|
6
|
+
self.font = pg.font.Font(root + '/bsk_assets/Roboto-Regular.ttf', 48)
|
|
7
|
+
self.text_renders = {}
|
|
8
|
+
|
|
9
|
+
def render(self, text, color=(255, 255, 255), bold=False, underline=False, italic=False):
|
|
10
|
+
'''
|
|
11
|
+
Renders any font which has been loaded to the class instance.
|
|
12
|
+
Args:
|
|
13
|
+
text::str
|
|
14
|
+
Text to be rendered
|
|
15
|
+
color::(int, int, int) =(255, 255, 255)
|
|
16
|
+
The RGB value of the text
|
|
17
|
+
bold::bool (=False)
|
|
18
|
+
Specifies if the text should be rendered in bolded font
|
|
19
|
+
underline::bool (=False)
|
|
20
|
+
Specifies if the text should be underlined in bolded font
|
|
21
|
+
italic::bool (=False)
|
|
22
|
+
Specifies if the text should be rendered in italicized font
|
|
23
|
+
'''
|
|
24
|
+
self.font.set_bold(bold)
|
|
25
|
+
self.font.set_underline(underline)
|
|
26
|
+
self.font.set_italic(italic)
|
|
27
|
+
|
|
28
|
+
return self.font.render(text, True, color, (0, 0, 0, 0))
|