use np array

pull/35357/head
deanlee 3 months ago
parent 4645f5e72f
commit f731b9cf75
  1. 42
      system/ui/lib/shader_polygon.py

@ -1,4 +1,5 @@
import pyray as rl import pyray as rl
import numpy as np
from typing import Any from typing import Any
@ -220,7 +221,7 @@ class ShaderState:
self.initialized = False self.initialized = False
def draw_polygon(points, color=None, gradient=None): def draw_polygon(points: np.ndarray, color: rl.Color | None =None, gradient=None):
""" """
Draw a complex polygon using shader-based even-odd fill rule Draw a complex polygon using shader-based even-odd fill rule
@ -246,44 +247,45 @@ def draw_polygon(points, color=None, gradient=None):
state.initialize() state.initialize()
# Find bounding box # Find bounding box
min_x = min(p[0] for p in points) min_xy = np.min(points, axis=0)
max_x = max(p[0] for p in points) min_x, min_y = min_xy
min_y = min(p[1] for p in points) max_x, max_y = np.max(points, axis=0)
max_y = max(p[1] for p in points)
width = max(1, max_x - min_x) width = max(1, max_x - min_x)
height = max(1, max_y - min_y) height = max(1, max_y - min_y)
# Transform points to shader space # Transform points to shader space
transformed_points = [(p[0] - min_x, p[1] - min_y) for p in points] transformed_points = points - min_xy
# Set basic shader uniforms using cached locations # Set basic shader uniforms using cached locations
point_count_ptr = rl.ffi.new("int[]", [len(transformed_points)]) point_count_ptr = rl.ffi.new("int[]", [len(transformed_points)])
rl.set_shader_value(state.shader, state.locations['pointCount'], point_count_ptr, rl.SHADER_UNIFORM_INT) rl.set_shader_value(state.shader, state.locations['pointCount'], point_count_ptr, rl.ShaderUniformDataType.SHADER_UNIFORM_INT)
resolution_ptr = rl.ffi.new("float[]", [width, height]) resolution_ptr = rl.ffi.new("float[]", [width, height])
rl.set_shader_value(state.shader, state.locations['resolution'], resolution_ptr, rl.SHADER_UNIFORM_VEC2) rl.set_shader_value(state.shader, state.locations['resolution'], resolution_ptr, rl.ShaderUniformDataType.SHADER_UNIFORM_VEC2)
# Set points # Set points
points_ptr = rl.ffi.new("float[]", len(transformed_points) * 2) points_ptr = rl.ffi.new("float[]", len(transformed_points) * 2)
for i, p in enumerate(transformed_points): flat_points = transformed_points.flatten()
points_ptr[i * 2] = float(p[0]) if not flat_points.flags['C_CONTIGUOUS']:
points_ptr[i * 2 + 1] = float(p[1]) flat_points = np.ascontiguousarray(flat_points)
points_ptr = rl.ffi.cast("float *", flat_points.ctypes.data)
rl.set_shader_value_v( rl.set_shader_value_v(
state.shader, state.locations['points'], points_ptr, rl.SHADER_UNIFORM_VEC2, len(transformed_points) state.shader, state.locations['points'], points_ptr, rl.ShaderUniformDataType.SHADER_UNIFORM_VEC2, len(transformed_points)
) )
# Set gradient or solid color based on what was provided # Set gradient or solid color based on what was provided
if gradient: if gradient:
# Enable gradient # Enable gradient
use_gradient_ptr = rl.ffi.new("int[]", [1]) use_gradient_ptr = rl.ffi.new("int[]", [1])
rl.set_shader_value(state.shader, state.locations['useGradient'], use_gradient_ptr, rl.SHADER_UNIFORM_INT) rl.set_shader_value(state.shader, state.locations['useGradient'], use_gradient_ptr, rl.ShaderUniformDataType.SHADER_UNIFORM_INT)
# Set gradient start/end # Set gradient start/end
start_ptr = rl.ffi.new("float[]", [gradient['start'][0], gradient['start'][1]]) start_ptr = rl.ffi.new("float[]", [gradient['start'][0], gradient['start'][1]])
end_ptr = rl.ffi.new("float[]", [gradient['end'][0], gradient['end'][1]]) end_ptr = rl.ffi.new("float[]", [gradient['end'][0], gradient['end'][1]])
rl.set_shader_value(state.shader, state.locations['gradientStart'], start_ptr, rl.SHADER_UNIFORM_VEC2) rl.set_shader_value(state.shader, state.locations['gradientStart'], start_ptr, rl.ShaderUniformDataType.SHADER_UNIFORM_VEC2)
rl.set_shader_value(state.shader, state.locations['gradientEnd'], end_ptr, rl.SHADER_UNIFORM_VEC2) rl.set_shader_value(state.shader, state.locations['gradientEnd'], end_ptr, rl.ShaderUniformDataType.SHADER_UNIFORM_VEC2)
# Set gradient colors # Set gradient colors
colors = gradient['colors'] colors = gradient['colors']
@ -295,7 +297,7 @@ def draw_polygon(points, color=None, gradient=None):
colors_ptr[i * 4 + 2] = c.b / 255.0 colors_ptr[i * 4 + 2] = c.b / 255.0
colors_ptr[i * 4 + 3] = c.a / 255.0 colors_ptr[i * 4 + 3] = c.a / 255.0
rl.set_shader_value_v( rl.set_shader_value_v(
state.shader, state.locations['gradientColors'], colors_ptr, rl.SHADER_UNIFORM_VEC4, color_count state.shader, state.locations['gradientColors'], colors_ptr, rl.ShaderUniformDataType.SHADER_UNIFORM_VEC4, color_count
) )
# Set gradient stops # Set gradient stops
@ -304,22 +306,22 @@ def draw_polygon(points, color=None, gradient=None):
for i, s in enumerate(stops[:color_count]): for i, s in enumerate(stops[:color_count]):
stops_ptr[i] = s stops_ptr[i] = s
rl.set_shader_value_v( rl.set_shader_value_v(
state.shader, state.locations['gradientStops'], stops_ptr, rl.SHADER_UNIFORM_FLOAT, color_count state.shader, state.locations['gradientStops'], stops_ptr, rl.ShaderUniformDataType.SHADER_UNIFORM_FLOAT, color_count
) )
# Set color count # Set color count
color_count_ptr = rl.ffi.new("int[]", [color_count]) color_count_ptr = rl.ffi.new("int[]", [color_count])
rl.set_shader_value(state.shader, state.locations['gradientColorCount'], color_count_ptr, rl.SHADER_UNIFORM_INT) rl.set_shader_value(state.shader, state.locations['gradientColorCount'], color_count_ptr, rl.ShaderUniformDataType.SHADER_UNIFORM_INT)
else: else:
# Disable gradient # Disable gradient
use_gradient_ptr = rl.ffi.new("int[]", [0]) use_gradient_ptr = rl.ffi.new("int[]", [0])
rl.set_shader_value(state.shader, state.locations['useGradient'], use_gradient_ptr, rl.SHADER_UNIFORM_INT) rl.set_shader_value(state.shader, state.locations['useGradient'], use_gradient_ptr, rl.ShaderUniformDataType.SHADER_UNIFORM_INT)
# Set solid color # Set solid color
if color is None: if color is None:
color = rl.WHITE color = rl.WHITE
fill_color_ptr = rl.ffi.new("float[]", [color.r / 255.0, color.g / 255.0, color.b / 255.0, color.a / 255.0]) fill_color_ptr = rl.ffi.new("float[]", [color.r / 255.0, color.g / 255.0, color.b / 255.0, color.a / 255.0])
rl.set_shader_value(state.shader, state.locations['fillColor'], fill_color_ptr, rl.SHADER_UNIFORM_VEC4) rl.set_shader_value(state.shader, state.locations['fillColor'], fill_color_ptr, rl.ShaderUniformDataType.SHADER_UNIFORM_VEC4)
# Draw with shader # Draw with shader
rl.begin_shader_mode(state.shader) rl.begin_shader_mode(state.shader)

Loading…
Cancel
Save