def draw_wire_sphere(radius, num_segments, color): coords = [] indices = [] gen_circle( radius, num_segments, lambda x, y: coords.append((x, y, 0)), indices ) gen_circle( radius, num_segments, lambda x, y: coords.append((0, x, y)), indices ) gen_circle( radius, num_segments, lambda x, y: coords.append((y, 0, x)), indices ) shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') batch = gpu_extras.batch.batch_for_shader( shader, 'LINES', {"pos": coords}, indices=indices ) shader.bind() shader.uniform_float("color", color) batch.draw(shader)
def post_view_callback(self, context): start = self.vertex_co normals_length = context.space_data.overlay.normals_length view_3d_theme = context.preferences.themes['Default'].view_3d default_color = (*view_3d_theme.split_normal, 1.0) highlight_color = (1.0, 1.0, 1.0, 1.0) # Draw unselected normals of selected vertex. coords = [] for idx in range(len(self.normals)): if idx != self.selected_idx: vn_global = self.normals[idx] end = start + mathutils.Vector(vn_global) * normals_length coords.append(start.to_tuple()) coords.append(end.to_tuple()) shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') shader.bind() shader.uniform_float('color', default_color) batch = gpu_extras.batch.batch_for_shader(shader, 'LINES', {'pos': coords}) batch.draw(shader) # Highlight selected normal. end = start + mathutils.Vector( self.normals[self.selected_idx]) * normals_length coords = [start.to_tuple(), end.to_tuple()] shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') shader.bind() shader.uniform_float('color', highlight_color) batch = gpu_extras.batch.batch_for_shader(shader, 'LINES', {'pos': coords}) batch.draw(shader)
def draw_line(start, end, color): coords = (start, end) shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') batch = gpu_extras.batch.batch_for_shader(shader, 'LINES', {"pos": coords}) shader.bind() shader.uniform_float("color", color) batch.draw(shader)
def draw_wire_cube(half_size_x, half_size_y, half_size_z, color): coords = ( (-half_size_x, -half_size_y, -half_size_z), (+half_size_x, -half_size_y, -half_size_z), (+half_size_x, +half_size_y, -half_size_z), (-half_size_x, +half_size_y, -half_size_z), (-half_size_x, -half_size_y, +half_size_z), (+half_size_x, -half_size_y, +half_size_z), (+half_size_x, +half_size_y, +half_size_z), (-half_size_x, +half_size_y, +half_size_z), ) indices = ( (0, 1), (1, 2), (2, 3), (3, 7), (2, 6), (1, 5), (0, 4), (4, 5), (5, 6), (6, 7), (4, 7), (0, 3) ) shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') batch = gpu_extras.batch.batch_for_shader( shader, 'LINES', {"pos": coords}, indices=indices ) shader.bind() shader.uniform_float("color", color) batch.draw(shader)
def draw_cross(size, color): coords = ((-size, 0, 0), (+size, 0, 0), (0, -size, 0), (0, +size, 0), (0, 0, -size), (0, 0, +size)) shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') batch = gpu_extras.batch.batch_for_shader(shader, 'LINES', {"pos": coords}) shader.bind() shader.uniform_float("color", color) batch.draw(shader)
def draw_wire_cylinder(radius, half_height, num_segments, color): coords = [] indices = [] gen_circle( radius, num_segments, lambda x, y: coords.append((x, -half_height, y)), indices ) gen_circle( radius, num_segments, lambda x, y: coords.append((x, +half_height, y)), indices ) coords.extend([ (-radius, -half_height, 0), (-radius, +half_height, 0), (+radius, -half_height, 0), (+radius, +half_height, 0), (0, -half_height, -radius), (0, +half_height, -radius), (0, -half_height, +radius), (0, +half_height, +radius) ]) start_index = indices[-1][-1] + 1 for i in range(start_index, start_index + 8, 2): indices.extend(( (i, i + 1), (i +1, i) )) shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') batch = gpu_extras.batch.batch_for_shader( shader, 'LINES', {"pos": coords}, indices=indices ) shader.bind() shader.uniform_float("color", color) batch.draw(shader)
def gen_limit_circle(rotate, radius, num_segments, axis, color, min_limit, max_limit): def gen_arc_vary(radius, start, end, indices): num_segs = math.ceil(num_segments * abs(end - start) / (math.pi * 2.0)) if num_segs: gen_arc(radius, start, end, num_segs, fconsumer, indices, close=True) coords = [] indices = [] draw_functions = { 'X': (lambda x, y: coords.append((0, -x, -y))), 'Y': (lambda x, y: coords.append((-y, 0, -x))), 'Z': (lambda x, y: coords.append((x, y, 0))) } fconsumer = draw_functions[axis] gen_arc_vary(radius, min_limit, max_limit, indices) shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') batch = gpu_extras.batch.batch_for_shader(shader, 'LINES', { "pos": coords, }, indices=indices) shader.bind() shader.uniform_float("color", color) batch.draw(shader) coords = [] indices = [] gen_arc_vary(radius, max_limit, 2.0 * math.pi + min_limit, indices) shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') batch = gpu_extras.batch.batch_for_shader(shader, 'LINES', { "pos": coords, }, indices=indices) shader.bind() shader.uniform_float("color", settings.GREY_COLOR) batch.draw(shader) coords = [] indices = [] gen_arc(radius, rotate, rotate + 1, 1, fconsumer, indices, close=False) bgl.glPointSize(settings.POINT_SIZE) shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR') batch = gpu_extras.batch.batch_for_shader(shader, 'POINTS', { "pos": coords, }) shader.bind() shader.uniform_float("color", color) batch.draw(shader)
def perform_gpu_test(frag_source, cpu_func): grid = accel.HashedGrid(3) assert grid is not None hash_grid_glsl = gpu_utils.load_shader_file("gridhash", "def") shader = gpu.types.GPUShader(vert_source, frag_source, libcode=hash_grid_glsl) screen_size = 128 offscreen = gpu.types.GPUOffScreen(screen_size, screen_size) points = [[-1, -1], [-1, 1], [1, 1], [1, -1]] indices = ((0, 1, 2), (2, 3, 0)) batch = gpu_extras.batch.batch_for_shader(shader, "TRIS", {'pos': points}, indices=indices) for z in range(-5, 5): gpu_hashes = [] with offscreen.bind(): shader.uniform_int('z', z) shader.uniform_int('screen_size', screen_size) batch.draw(shader) # Starting from blender 3.0 we can: # fb = gpu.state.active_framebuffer_get() # buffer = fb.read_color(0,0, screen_size, screen_size, 4, 0, UBYTE) buffer = bgl.Buffer(bgl.GL_BYTE, screen_size * screen_size * 4) bgl.glReadPixels(0, 0, screen_size, screen_size, bgl.GL_RGBA, bgl.GL_UNSIGNED_BYTE, buffer) x = buffer[:] gpu_hashes = [ a + 256 * (b + 256 * (c + 256 * d)) for a, b, c, d in zip(x[::4], x[1::4], x[2::4], x[3::4]) ] i = 0 for y in range(-screen_size // 2, screen_size // 2): for x in range(-screen_size // 2, screen_size // 2): cpu_hash = cpu_func(grid, [x, y, z]) assert gpu_hashes[i] == cpu_hash i += 1
def draw(): shader.bind() bgl.glPointSize(5) batch.draw(shader)