From 7ee6fb506906534891defdf7a5d012bd03cc6c2c Mon Sep 17 00:00:00 2001 From: Thomas Jebson Date: Wed, 23 Oct 2024 14:36:54 +0100 Subject: [PATCH] fixed line rendering in the wrong place... --- experiments/drawing test.py | 16 +-- python_src/draw.py | 19 +-- python_src/utility/display_utils.py | 175 +++++++++++++++------------ shaders/draw_line/vertex_shader.glsl | 5 +- 4 files changed, 118 insertions(+), 97 deletions(-) diff --git a/experiments/drawing test.py b/experiments/drawing test.py index 741442e6..78042174 100644 --- a/experiments/drawing test.py +++ b/experiments/drawing test.py @@ -19,13 +19,13 @@ events = pmma.Events() -""" + line = pmma.Line() -line.set_start((300, 300)) -line.set_end((500, 300)) -line.set_color([255, 0, 0]) +line.set_start((10, 10)) +line.set_end((200, 200)) +line.set_color([255, 0, 255]) line.set_width(1) - +""" pixel = pmma.Pixel() pixel.set_position((100, 100)) pixel.set_color([255, 255, 255]) @@ -70,8 +70,8 @@ display.clear([0, 0, 0]) - radial_polygon.render() - #line.render() + #radial_polygon.render() + line.render() #rectangle.render() #pixel.render() #arc.render() @@ -79,7 +79,7 @@ #polygon.render() #radial_polygon.set_rotation((time.perf_counter()-s)*60) - #line.set_rotation((time.perf_counter()-s)*5) + line.set_rotation((time.perf_counter()-s)*5) #line.set_end((500, 60*(time.perf_counter()-start))) #rectangle.set_rotation((time.perf_counter()-s)*10) diff --git a/python_src/draw.py b/python_src/draw.py index 59c7e9a6..a79655c8 100644 --- a/python_src/draw.py +++ b/python_src/draw.py @@ -137,16 +137,23 @@ def get_surface(self): def _rotate_point_around_center(self, point, center, angle): """ - Rotates a 2D point around a given center by the given angle in radians. + Rotates a 2D point around a given center by the given angle in radians, accounting for aspect ratio. :param point: A list or tuple representing the x and y coordinates (x, y) :param center: The center of rotation as (cx, cy) :param angle: The angle to rotate by, in radians. :return: The rotated point as a [x', y'] list. """ + # Get the aspect ratio (width/height) + aspect_ratio = self._surface.get_width() / self._surface.get_height() + + # Scale the point and center coordinates to account for aspect ratio + scaled_point = [point[0] * aspect_ratio, point[1]] + scaled_center = [center[0] * aspect_ratio, center[1]] + # Translate the point to the origin (relative to the center) - translated_x = point[0] - center[0] - translated_y = point[1] - center[1] + translated_x = scaled_point[0] - scaled_center[0] + translated_y = scaled_point[1] - scaled_center[1] # Apply 2D rotation matrix cos_angle = _numpy.cos(angle) @@ -156,7 +163,8 @@ def _rotate_point_around_center(self, point, center, angle): y_prime = sin_angle * translated_x + cos_angle * translated_y # Translate the point back to its original position (relative to the center) - return [x_prime + center[0], y_prime + center[1]] + # Scale back the x-coordinate to remove aspect ratio effect + return [x_prime / aspect_ratio + center[0], y_prime + center[1]] def _rotate_line(self, angle): """ @@ -179,9 +187,6 @@ def _rotate_line(self, angle): def _update_buffers(self): if self._vertices_changed: - if _Constants.DISPLAY_OBJECT in _Registry.pmma_module_spine: - self._program.set_shader_variable('aspect_ratio', _Registry.pmma_module_spine[_Constants.DISPLAY_OBJECT].get_aspect_ratio()) - _Registry.number_of_render_updates += 1 rotated_line_points = self._rotate_line(self._rotation.get_angle(format=_Constants.RADIANS)) diff --git a/python_src/utility/display_utils.py b/python_src/utility/display_utils.py index 674ba139..f1a30d1e 100644 --- a/python_src/utility/display_utils.py +++ b/python_src/utility/display_utils.py @@ -120,68 +120,71 @@ def __init__(self): self._projection_intermediary = _Registry.pmma_module_spine[_Constants.PROJECTION_INTERMEDIARY_OBJECT] - def update_class(self): - if self._object_updated is False: - self._object_updated = True - - if _Registry.displayed_pygame_start_message is False: - _Registry.displayed_pygame_start_message = True - self._logger.log_information(_Registry.pygame_launch_message) - _pygame__init() - def get_clear_called_but_skipped(self): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return return self._clear_called_but_skipped def set_clear_called_but_skipped(self, value): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return self._clear_called_but_skipped = value def get_render_calls(self): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return return self._render_calls def set_render_calls(self, value): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return self._render_calls = value def update_render_calls(self, value): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return self._attempted_render_calls += value def get_attempted_render_calls(self): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return return self._render_calls def set_attempted_render_calls(self, value): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return self._render_calls = value def update_attempted_render_calls(self, value): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return self._attempted_render_calls += value def get_refresh_optimization_override(self): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return return self._refresh_optimization_override def set_refresh_optimization_override(self, value): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return self._refresh_optimization_override = value def clear(self, color=None, format=_Constants.RGB): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return + if color is None or color == [] or color == (): self._color_converter.set_color((0, 0, 0), format=_Constants.RGB) @@ -225,13 +228,15 @@ def clear(self, color=None, format=_Constants.RGB): _Registry.context.clear(*self._color_converter.get_color(format=_Constants.SMALL_RGB)) def set_window_in_focus(self, value): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return self._window_in_focus = value def set_window_minimized(self, value): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return self._window_minimized = value def __del__(self, do_garbage_collection=False): @@ -246,8 +251,9 @@ def quit(self, do_garbage_collection=True): self._shut_down = True def _setup_layers(self, size): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return if _Registry.do_anti_aliasing is False: samples = 0 else: @@ -259,8 +265,9 @@ def _setup_layers(self, size): self._three_dimension_frame_buffer.create(color_attachments=[self._three_dimension_texture]) def get_2D_hardware_accelerated_surface(self, set_to_be_used=True): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return if set_to_be_used: if self._currently_active_frame_buffer != _Constants.TWO_DIMENSION_FRAME_BUFFER: self._currently_active_frame_buffer = _Constants.TWO_DIMENSION_FRAME_BUFFER @@ -268,8 +275,9 @@ def get_2D_hardware_accelerated_surface(self, set_to_be_used=True): return self._two_dimension_frame_buffer def get_3D_hardware_accelerated_surface(self, set_to_be_used=True): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return if set_to_be_used: if self._currently_active_frame_buffer != _Constants.THREE_DIMENSION_FRAME_BUFFER: self._currently_active_frame_buffer = _Constants.THREE_DIMENSION_FRAME_BUFFER @@ -277,8 +285,6 @@ def get_3D_hardware_accelerated_surface(self, set_to_be_used=True): return self._three_dimension_frame_buffer def _generate_pygame_flags(self, care_about_full_screen=True): - if self._object_updated is False: - self.update_class() flags = _pygame__OPENGL | _pygame__DOUBLEBUF if self._display_attribute_no_frame: @@ -303,8 +309,10 @@ def create( transparent_display=False, centered=True): - if self._object_updated is False: - self.update_class() + if _Registry.displayed_pygame_start_message is False: + _Registry.displayed_pygame_start_message = True + self._logger.log_information(_Registry.pygame_launch_message) + _pygame__init() if vsync: self._logger.log_development("Your display is using vsync. Therefore the \ @@ -403,15 +411,11 @@ def create( self._gpu_distribution_manager.update_gpu_roles(initialization_override=True) def set_caption(self, caption=None): - if self._object_updated is False: - self.update_class() if caption is None: caption = self._display_attribute_caption _pygame__display.set_caption(str(caption)) def set_icon(self, icon=None): - if self._object_updated is False: - self.update_class() if icon is None: icon = self._display_attribute_icon icon_img = _pygame__image.load(icon) @@ -419,14 +423,15 @@ def set_icon(self, icon=None): del icon_img def get_display_projection(self): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return return self._orthographic_projection def on_window_size_changed(self): - if self._object_updated is False: - self.update_class() - + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return size = _pygame__display.get_window_size() self._current_display_size = size @@ -442,16 +447,17 @@ def on_window_size_changed(self): self._currently_active_frame_buffer = _Constants.DISPLAY_FRAME_BUFFER def hex_color_to_windows_raw_color(self, value): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return color_key = int(value[1:], 16) color_key = ((color_key & 0xFF0000) >> 16) | (color_key & 0x00FF00) | ((color_key & 0x0000FF) << 16) return color_key def toggle_full_screen(self): - if self._object_updated is False: - self.update_class() - + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return flags = self._generate_pygame_flags(care_about_full_screen=False) self._display_attribute_full_screen = not self._display_attribute_full_screen @@ -468,28 +474,33 @@ def toggle_full_screen(self): self.on_window_size_changed() def get_size(self): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return return self._current_display_size def get_frame_time(self): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return return 1/self.get_fps() def get_height(self): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return return self._current_display_size[1] def get_width(self): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return return self._current_display_size[0] def get_aspect_ratio(self): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return return self._current_display_size[0] / self._current_display_size[1] def refresh( @@ -499,9 +510,9 @@ def refresh( lower_refresh_rate_when_unfocused=True, lower_refresh_rate_on_low_battery=True): - if self._object_updated is False: - self.update_class() - + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return if _Registry.handled_events is False: self._logger.log_development("You are not using PMMA's event manager. This is \ important as it tells the operating system that the window is responding and \ @@ -583,23 +594,27 @@ def get_clock(self): return self._clock def close(self): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return _pygame__quit() def get_fps(self): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return return self._clock.get_fps() def get_refresh_rate(self): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return return self.get_fps() def get_center(self, as_integer=True): - if self._object_updated is False: - self.update_class() + if _Registry.display_initialized is False: + self._logger.log_development("You need to create a display with the `create` before you can use this function.") + return if as_integer: return self._display.get_width() // 2, self._display.get_height() // 2 return self._display.get_width() / 2, self._display.get_height() / 2 \ No newline at end of file diff --git a/shaders/draw_line/vertex_shader.glsl b/shaders/draw_line/vertex_shader.glsl index c02f4d66..fca273ee 100644 --- a/shaders/draw_line/vertex_shader.glsl +++ b/shaders/draw_line/vertex_shader.glsl @@ -1,6 +1,7 @@ #version 330 + in vec2 in_position; -uniform float aspect_ratio; + void main() { - gl_Position = vec4(in_position.x / aspect_ratio, in_position.y, 0.0, 1.0); + gl_Position = vec4(in_position.x, in_position.y, 0.0, 1.0); } \ No newline at end of file