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.

Files changed (82) hide show
  1. basilisk/__init__.py +11 -11
  2. basilisk/bsk_assets/cube.obj +48 -48
  3. basilisk/collisions/broad/broad_aabb.py +102 -102
  4. basilisk/collisions/broad/broad_bvh.py +137 -137
  5. basilisk/collisions/collider.py +95 -83
  6. basilisk/collisions/collider_handler.py +225 -228
  7. basilisk/collisions/narrow/contact_manifold.py +90 -90
  8. basilisk/collisions/narrow/dataclasses.py +33 -27
  9. basilisk/collisions/narrow/deprecated.py +46 -46
  10. basilisk/collisions/narrow/epa.py +91 -91
  11. basilisk/collisions/narrow/gjk.py +66 -66
  12. basilisk/collisions/narrow/graham_scan.py +24 -24
  13. basilisk/collisions/narrow/helper.py +29 -29
  14. basilisk/collisions/narrow/line_intersections.py +106 -106
  15. basilisk/collisions/narrow/sutherland_hodgman.py +75 -75
  16. basilisk/config.py +2 -2
  17. basilisk/draw/draw.py +100 -100
  18. basilisk/draw/draw_handler.py +180 -210
  19. basilisk/draw/font_renderer.py +28 -28
  20. basilisk/engine.py +195 -195
  21. basilisk/generic/abstract_bvh.py +15 -15
  22. basilisk/generic/abstract_custom.py +133 -133
  23. basilisk/generic/collisions.py +70 -70
  24. basilisk/generic/input_validation.py +67 -28
  25. basilisk/generic/math.py +6 -6
  26. basilisk/generic/matrices.py +33 -33
  27. basilisk/generic/meshes.py +72 -72
  28. basilisk/generic/quat.py +137 -137
  29. basilisk/generic/quat_methods.py +7 -7
  30. basilisk/generic/raycast_result.py +24 -0
  31. basilisk/generic/vec3.py +143 -143
  32. basilisk/input/mouse.py +61 -59
  33. basilisk/mesh/cube.py +33 -33
  34. basilisk/mesh/mesh.py +230 -230
  35. basilisk/mesh/mesh_from_data.py +132 -132
  36. basilisk/mesh/model.py +271 -271
  37. basilisk/mesh/narrow_aabb.py +89 -89
  38. basilisk/mesh/narrow_bvh.py +91 -91
  39. basilisk/mesh/narrow_primative.py +23 -23
  40. basilisk/nodes/helper.py +29 -0
  41. basilisk/nodes/node.py +681 -617
  42. basilisk/nodes/node_handler.py +95 -118
  43. basilisk/particles/particle_handler.py +63 -54
  44. basilisk/particles/particle_renderer.py +87 -87
  45. basilisk/physics/impulse.py +112 -112
  46. basilisk/physics/physics_body.py +43 -43
  47. basilisk/physics/physics_engine.py +35 -35
  48. basilisk/render/batch.py +86 -86
  49. basilisk/render/camera.py +204 -199
  50. basilisk/render/chunk.py +99 -99
  51. basilisk/render/chunk_handler.py +154 -154
  52. basilisk/render/frame.py +181 -181
  53. basilisk/render/image.py +75 -75
  54. basilisk/render/image_handler.py +122 -122
  55. basilisk/render/light.py +96 -96
  56. basilisk/render/light_handler.py +58 -58
  57. basilisk/render/material.py +219 -219
  58. basilisk/render/material_handler.py +135 -135
  59. basilisk/render/shader.py +109 -109
  60. basilisk/render/shader_handler.py +79 -79
  61. basilisk/render/sky.py +120 -120
  62. basilisk/scene.py +250 -210
  63. basilisk/shaders/batch.frag +276 -276
  64. basilisk/shaders/batch.vert +115 -115
  65. basilisk/shaders/draw.frag +21 -21
  66. basilisk/shaders/draw.vert +21 -21
  67. basilisk/shaders/filter.frag +22 -22
  68. basilisk/shaders/frame.frag +12 -12
  69. basilisk/shaders/frame.vert +13 -13
  70. basilisk/shaders/geometry.frag +8 -8
  71. basilisk/shaders/geometry.vert +41 -41
  72. basilisk/shaders/normal.frag +59 -59
  73. basilisk/shaders/normal.vert +96 -96
  74. basilisk/shaders/particle.frag +71 -71
  75. basilisk/shaders/particle.vert +84 -84
  76. basilisk/shaders/sky.frag +9 -9
  77. basilisk/shaders/sky.vert +13 -13
  78. {basilisk_engine-0.1.2.dist-info → basilisk_engine-0.1.3.dist-info}/METADATA +45 -38
  79. basilisk_engine-0.1.3.dist-info/RECORD +97 -0
  80. {basilisk_engine-0.1.2.dist-info → basilisk_engine-0.1.3.dist-info}/WHEEL +1 -1
  81. basilisk_engine-0.1.2.dist-info/RECORD +0 -95
  82. {basilisk_engine-0.1.2.dist-info → basilisk_engine-0.1.3.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.scene.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.scene.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.scene.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):
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.scene.draw_handler
78
- if not draw_handler: return
79
-
80
- engine.scene.material_handler.image_handler.add(image)
81
-
82
- # Blit the image
83
- draw_handler.blit(image, rect)
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.scene.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)
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.scene.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.scene.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.scene.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):
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.scene.draw_handler
78
+ if not draw_handler: return
79
+
80
+ engine.scene.material_handler.image_handler.add(image)
81
+
82
+ # Blit the image
83
+ draw_handler.blit(image, rect)
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.scene.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)
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))
@@ -1,210 +1,180 @@
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
-
9
- class DrawHandler():
10
- engine: ...
11
- """Back reference to the parent engine"""
12
- scene: ...
13
- """Back reference to the parent scene"""
14
- ctx: mgl.Context
15
- """Back reference to the parent context"""
16
- program: mgl.Program
17
- """2D draw program"""
18
- draw_data: list[float]
19
- """Temporary buffer for user draw calls"""
20
- vbo: mgl.Buffer=None
21
- """Buffer for all 2D draws"""
22
- vao: mgl.VertexArray=None
23
- """VAO for rendering all 2D draw calls"""
24
-
25
- def __init__(self, scene) -> None:
26
- # Back references
27
- self.scene = scene
28
- self.engine = scene.engine
29
- self.ctx = scene.engine.ctx
30
-
31
- # Get the shader
32
- root = self.engine.root
33
- self.shader = self.scene.shader_handler.add(Shader(self.engine, root + '/shaders/draw.vert', root + '/shaders/draw.frag'))
34
-
35
- # Initialize draw data as blank
36
- self.draw_data = []
37
- self.vbo = None
38
- self.vao = None
39
-
40
- self.font_renderer = FontRenderer(self.engine.root)
41
-
42
- def render(self) -> None:
43
- """
44
- Renders all draw calls from the user since the last frame
45
- """
46
-
47
- if not self.draw_data: return
48
-
49
- # Reverse the draw order, and convert to C-like array
50
- self.draw_data.reverse()
51
- data = np.array(self.draw_data, dtype='f4')
52
- ratio = np.array([2 / self.engine.win_size[0], 2 / self.engine.win_size[1]])
53
- data[:,:2] = data[:,:2] * ratio - 1
54
-
55
- # Create buffer and VAO
56
- self.vbo = self.ctx.buffer(data)
57
- self.vao = self.ctx.vertex_array(self.shader.program, [(self.vbo, '2f 4f 1i', *['in_position', 'in_color', 'in_uses_image'])], skip_errors=True)
58
-
59
- # Render the VAO
60
- self.ctx.enable(mgl.BLEND)
61
- self.ctx.blend_equation = mgl.ADDITIVE_BLENDING
62
- self.vao.render()
63
-
64
- # Clera the draw data
65
- self.vbo.release()
66
- self.vao.release()
67
- self.vbo = None
68
- self.vao = None
69
- self.draw_data.clear()
70
-
71
- def draw_rect(self, color: tuple, rect: tuple) -> None:
72
- """
73
- Draws a rect to the screen
74
- """
75
-
76
- color = validate_color(color)
77
- rect = validate_rect(rect)
78
-
79
- p1 = (rect[0] , rect[1] )
80
- p2 = (rect[0] , rect[1] + rect[3])
81
- p3 = (rect[0] + rect[2], rect[1] )
82
- p4 = (rect[0] + rect[2], rect[1] + rect[3])
83
-
84
- v1 = (*p1, *color, 0)
85
- v2 = (*p2, *color, 0)
86
- v3 = (*p3, *color, 0)
87
- v4 = (*p4, *color, 0)
88
-
89
- self.draw_data.extend([
90
- v1, v3, v2,
91
- v2, v3, v4
92
- ])
93
-
94
- def draw_circle(self, color: tuple, center: tuple, radius: int, resolution: int=20, outer_color: tuple=None) -> None:
95
- """
96
- Draws a rect between centered on x, y with width and height
97
- Args:
98
- color: tuple(r, g, b) | tuple(r, g, b, a)
99
- The color value of the circle, with int components in range [0, 255]
100
- center: tuple (x: float, y: float)
101
- Center of the circle, given in pixels
102
- radius: float
103
- Radius of the circle, given in pixels
104
- resolution: float
105
- The number of triangles used to approximate the circle
106
- """
107
-
108
- if not outer_color: outer_color = color
109
- color = validate_color(color)
110
- outer_color = validate_color(outer_color)
111
- p1 = validate_point(center)
112
-
113
- v1 = (*p1, *color, 0)
114
- theta = 0
115
- delta_theta = (2 * 3.1415) / resolution
116
-
117
- for triangle in range(resolution):
118
- v2 = (center[0] + radius * cos(theta), center[1] + radius * sin(theta), *outer_color, 0)
119
- theta += delta_theta
120
- v3 = (center[0] + radius * cos(theta), center[1] + radius * sin(theta), *outer_color, 0)
121
- self.draw_data.extend([v1, v2, v3])
122
-
123
- def draw_line(self, color: tuple, p1: tuple, p2: tuple, thickness: int=1):
124
- """
125
- Draws a line between two points
126
- Args:
127
- color: tuple=(r, g, b) | tuple=(r, g, b, a)
128
- Color of the line
129
- p1: tuple=((x1, y1), (x2, y2))
130
- Starting point of the line. Given in pixels
131
- p1: tuple=((x1, y1), (x2, y2))
132
- Starting point of the line. Given in pixels
133
- thickness: int
134
- Size of the line on either side. pixels
135
- """
136
-
137
- color = validate_color(color)
138
-
139
- p1 = glm.vec2(validate_point(p1))
140
- p2 = glm.vec2(validate_point(p2))
141
-
142
- thickness /= 2
143
-
144
- unit = glm.normalize(p1 - p2) * thickness
145
- theta = atan2(*unit)
146
- perp_vector = glm.vec2(cos(-theta), sin(-theta)) * thickness
147
-
148
- v1 = (*(p1 - perp_vector), *color, 0)
149
- v2 = (*(p1 + perp_vector), *color, 0)
150
- v3 = (*(p2 - perp_vector), *color, 0)
151
- v4 = (*(p2 + perp_vector), *color, 0)
152
-
153
- self.draw_data.extend([v1, v3, v4, v2, v1, v4])
154
-
155
- def blit(self, image: Image, rect: tuple):
156
- rect = validate_rect(rect)
157
-
158
- p1 = (rect[0] , rect[1] )
159
- p2 = (rect[0] , rect[1] + rect[3])
160
- p3 = (rect[0] + rect[2], rect[1] )
161
- p4 = (rect[0] + rect[2], rect[1] + rect[3])
162
-
163
- v1 = (*p1, *image.index, 0, 0, 1)
164
- v2 = (*p2, *image.index, 0, 1, 1)
165
- v3 = (*p3, *image.index, 1, 0, 1)
166
- v4 = (*p4, *image.index, 1, 1, 1)
167
-
168
- self.draw_data.extend([
169
- v1, v3, v2,
170
- v2, v3, v4
171
- ])
172
-
173
- def __del__(self) -> None:
174
- """
175
- Releases any allocated data
176
- """
177
-
178
- if self.vbo: self.vbo.release()
179
- if self.vao: self.vao.release()
180
-
181
-
182
- def validate_color(color):
183
- if not (isinstance(color, tuple) or isinstance(color, list) or isinstance(color, np.ndarray)):
184
- raise TypeError(f'Invalid color type: {type(color)}. Expected a tuple, list, or numpy array')
185
- if len(color) == 4:
186
- color = (color[0] / 255.0, color[1] / 255.0, color[2] / 255.0, color[3] / 255.0)
187
- elif len(color) == 3:
188
- color = (color[0] / 255.0, color[1] / 255.0, color[2] / 255.0, 1.0)
189
- else:
190
- raise TypeError(f'Invalid number of color values. Expected 3 or 4 values, got {len(color)}')
191
- return color
192
-
193
- def validate_rect(rect):
194
- if not (isinstance(rect, tuple) or isinstance(rect, list) or isinstance(rect, np.ndarray)):
195
- raise TypeError(f'Invalid rect type: {type(rect)}. Expected a tuple, list, or numpy array')
196
- if len(rect) != 4:
197
- raise TypeError(f'Invalid number of rect values. Expected 4 values, got {len(rect)}')
198
- return list(rect)
199
-
200
- def validate_point(point):
201
- if not (isinstance(point, tuple) or isinstance(point, list) or isinstance(point, np.ndarray)):
202
- raise TypeError(f'Invalid rect type: {type(point)}. Expected a tuple, list, or numpy array')
203
- if len(point) != 2:
204
- raise TypeError(f'Invalid number of rect values. Expected 2 values, got {len(point)}')
205
- return list(point)
206
-
207
- def validate_image(image):
208
- if not (isinstance(image, Image)):
209
- raise TypeError(f'Invalid imgae type: {type(image)}. Expected a bask.Image.')
210
- return image
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
+ """Back reference to the parent engine"""
13
+ scene: ...
14
+ """Back reference to the parent scene"""
15
+ ctx: mgl.Context
16
+ """Back reference to the parent context"""
17
+ program: mgl.Program
18
+ """2D draw program"""
19
+ draw_data: list[float]
20
+ """Temporary buffer for user draw calls"""
21
+ vbo: mgl.Buffer=None
22
+ """Buffer for all 2D draws"""
23
+ vao: mgl.VertexArray=None
24
+ """VAO for rendering all 2D draw calls"""
25
+
26
+ def __init__(self, scene) -> None:
27
+ # Back references
28
+ self.scene = scene
29
+ self.engine = scene.engine
30
+ self.ctx = scene.engine.ctx
31
+
32
+ # Get the shader
33
+ root = self.engine.root
34
+ self.shader = self.scene.shader_handler.add(Shader(self.engine, root + '/shaders/draw.vert', root + '/shaders/draw.frag'))
35
+
36
+ # Initialize draw data as blank
37
+ self.draw_data = []
38
+ self.vbo = None
39
+ self.vao = None
40
+
41
+ self.font_renderer = FontRenderer(self.engine.root)
42
+
43
+ def render(self) -> None:
44
+ """
45
+ Renders all draw calls from the user since the last frame
46
+ """
47
+
48
+ if not self.draw_data: return
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', *['in_position', 'in_color', 'in_uses_image'])], skip_errors=True)
59
+
60
+ # Render the VAO
61
+ self.ctx.enable(mgl.BLEND)
62
+ self.ctx.blend_equation = mgl.ADDITIVE_BLENDING
63
+ self.vao.render()
64
+
65
+ # Clera the draw data
66
+ self.vbo.release()
67
+ self.vao.release()
68
+ self.vbo = None
69
+ self.vao = None
70
+ self.draw_data.clear()
71
+
72
+ def draw_rect(self, color: tuple, rect: tuple) -> None:
73
+ """
74
+ Draws a rect to the screen
75
+ """
76
+
77
+ color = validate_color('draw', 'color', color)
78
+ rect = validate_rect(rect)
79
+
80
+ p1 = (rect[0] , rect[1] )
81
+ p2 = (rect[0] , rect[1] + rect[3])
82
+ p3 = (rect[0] + rect[2], rect[1] )
83
+ p4 = (rect[0] + rect[2], rect[1] + rect[3])
84
+
85
+ v1 = (*p1, *color, 0)
86
+ v2 = (*p2, *color, 0)
87
+ v3 = (*p3, *color, 0)
88
+ v4 = (*p4, *color, 0)
89
+
90
+ self.draw_data.extend([
91
+ v1, v3, v2,
92
+ v2, v3, v4
93
+ ])
94
+
95
+ def draw_circle(self, color: tuple, center: tuple, radius: int, resolution: int=20, outer_color: tuple=None) -> None:
96
+ """
97
+ Draws a rect between centered on x, y with width and height
98
+ Args:
99
+ color: tuple(r, g, b) | tuple(r, g, b, a)
100
+ The color value of the circle, with int components in range [0, 255]
101
+ center: tuple (x: float, y: float)
102
+ Center of the circle, given in pixels
103
+ radius: float
104
+ Radius of the circle, given in pixels
105
+ resolution: float
106
+ The number of triangles used to approximate the circle
107
+ """
108
+
109
+ if not outer_color: outer_color = color
110
+ color = validate_color('draw', 'color', color)
111
+ outer_color = validate_color('draw', 'color', outer_color)
112
+ p1 = validate_point(center)
113
+
114
+ v1 = (*p1, *color, 0)
115
+ theta = 0
116
+ delta_theta = (2 * 3.1415) / resolution
117
+
118
+ for triangle in range(resolution):
119
+ v2 = (center[0] + radius * cos(theta), center[1] + radius * sin(theta), *outer_color, 0)
120
+ theta += delta_theta
121
+ v3 = (center[0] + radius * cos(theta), center[1] + radius * sin(theta), *outer_color, 0)
122
+ self.draw_data.extend([v1, v2, v3])
123
+
124
+ def draw_line(self, color: tuple, p1: tuple, p2: tuple, thickness: int=1):
125
+ """
126
+ Draws a line between two points
127
+ Args:
128
+ color: tuple=(r, g, b) | tuple=(r, g, b, a)
129
+ Color of the line
130
+ p1: tuple=((x1, y1), (x2, y2))
131
+ Starting point of the line. Given in pixels
132
+ p1: tuple=((x1, y1), (x2, y2))
133
+ Starting point of the line. Given in pixels
134
+ thickness: int
135
+ Size of the line on either side. pixels
136
+ """
137
+
138
+ color = validate_color('draw', 'color', color)
139
+
140
+ p1 = glm.vec2(validate_point(p1))
141
+ p2 = glm.vec2(validate_point(p2))
142
+
143
+ thickness /= 2
144
+
145
+ unit = glm.normalize(p1 - p2) * thickness
146
+ theta = atan2(*unit)
147
+ perp_vector = glm.vec2(cos(-theta), sin(-theta)) * thickness
148
+
149
+ v1 = (*(p1 - perp_vector), *color, 0)
150
+ v2 = (*(p1 + perp_vector), *color, 0)
151
+ v3 = (*(p2 - perp_vector), *color, 0)
152
+ v4 = (*(p2 + perp_vector), *color, 0)
153
+
154
+ self.draw_data.extend([v1, v3, v4, v2, v1, v4])
155
+
156
+ def blit(self, image: Image, rect: tuple):
157
+ rect = validate_rect(rect)
158
+
159
+ p1 = (rect[0] , rect[1] )
160
+ p2 = (rect[0] , rect[1] + rect[3])
161
+ p3 = (rect[0] + rect[2], rect[1] )
162
+ p4 = (rect[0] + rect[2], rect[1] + rect[3])
163
+
164
+ v1 = (*p1, *image.index, 0, 0, 1)
165
+ v2 = (*p2, *image.index, 0, 1, 1)
166
+ v3 = (*p3, *image.index, 1, 0, 1)
167
+ v4 = (*p4, *image.index, 1, 1, 1)
168
+
169
+ self.draw_data.extend([
170
+ v1, v3, v2,
171
+ v2, v3, v4
172
+ ])
173
+
174
+ def __del__(self) -> None:
175
+ """
176
+ Releases any allocated data
177
+ """
178
+
179
+ if self.vbo: self.vbo.release()
180
+ if self.vao: self.vao.release()
@@ -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))