Beispiel #1
0
async def mainloop():
    await main_async(canvas)
    while update_glfw_canvasses():
        await asyncio.sleep(0.001)
        glfw.poll_events()
    loop.stop()
    glfw.terminate()
def better_event_loop(max_fps=100):
    """ A simple event loop that schedules draws. """
    td = 1 / max_fps
    while update_glfw_canvasses():
        # Determine next time to draw
        now = perf_counter()
        tnext = math.ceil(now / td) * td
        # Process events until it's time to draw
        while now < tnext:
            glfw.wait_events_timeout(tnext - now)
            now = perf_counter()
def test_glfw_canvas_render():
    """Render an orange square ... in a glfw window."""

    import glfw
    from wgpu.gui.glfw import update_glfw_canvasses, WgpuCanvas

    canvas = WgpuCanvas()

    # wgpu.utils.get_default_device()
    adapter = wgpu.request_adapter(canvas=canvas,
                                   power_preference="high-performance")
    device = adapter.request_device()
    draw_frame1 = _get_draw_function(device, canvas)

    frame_counter = 0

    def draw_frame2():
        nonlocal frame_counter
        frame_counter += 1
        draw_frame1()

    canvas.request_draw(draw_frame2)

    # Give it a few rounds to start up
    for i in range(5):
        glfw.poll_events()
        update_glfw_canvasses()
    # There should have been exactly one draw now
    assert frame_counter == 1

    # Ask for a lot of draws
    for i in range(5):
        canvas.request_draw()
    # Process evens for a while
    for i in range(5):
        glfw.poll_events()
        update_glfw_canvasses()
    # We should have had just one draw
    assert frame_counter == 2

    # Change the canvase size
    canvas.set_logical_size(300, 200)
    canvas.set_logical_size(400, 300)
    for i in range(5):
        time.sleep(0.01)
        glfw.poll_events()
        update_glfw_canvasses()
    # We should have had just one draw
    assert frame_counter == 3

    # canvas.close()
    glfw.poll_events()
Beispiel #4
0
def render_to_screen(
    device,
    vertex_shader,
    fragment_shader,
    pipeline_layout,
    bind_group,
    *,
    topology=wgpu.PrimitiveTopology.triangle_strip,
    ibo=None,
    vbos=None,
    vbo_views=None,
    indirect_buffer=None,
    color_attachment=None,
    depth_stencil_state=None,
    depth_stencil_attachment=None,
    renderpass_callback=lambda *args: None,
):
    """Render to a window on screen, for debugging purposes."""
    import glfw
    from wgpu.gui.glfw import WgpuCanvas, update_glfw_canvasses

    vbos = vbos or []
    vbo_views = vbo_views or []

    # Setup canvas
    glfw.init()
    canvas = WgpuCanvas(title="wgpu test render with GLFW")

    vshader = device.create_shader_module(code=vertex_shader)
    fshader = device.create_shader_module(code=fragment_shader)

    render_pipeline = device.create_render_pipeline(
        layout=pipeline_layout,
        vertex_stage={"module": vshader, "entry_point": "main"},
        fragment_stage={"module": fshader, "entry_point": "main"},
        primitive_topology=topology,
        rasterization_state={
            "front_face": wgpu.FrontFace.ccw,
            "cull_mode": wgpu.CullMode.none,
            "depth_bias": 0,
            "depth_bias_slope_scale": 0.0,
            "depth_bias_clamp": 0.0,
        },
        color_states=[
            {
                "format": wgpu.TextureFormat.bgra8unorm_srgb,
                "alpha_blend": (
                    wgpu.BlendFactor.one,
                    wgpu.BlendFactor.zero,
                    wgpu.BlendOperation.add,
                ),
                "color_blend": (
                    wgpu.BlendFactor.one,
                    wgpu.BlendFactor.zero,
                    wgpu.BlendOperation.add,
                ),
                "write_mask": wgpu.ColorWrite.ALL,
            }
        ],
        depth_stencil_state=depth_stencil_state,
        vertex_state={
            "index_format": wgpu.IndexFormat.uint32,
            "vertex_buffers": vbo_views,
        },
        sample_count=1,
        sample_mask=0xFFFFFFFF,
        alpha_to_coverage_enabled=False,
    )

    swap_chain = device.configure_swap_chain(
        canvas, wgpu.TextureFormat.bgra8unorm_srgb, wgpu.TextureUsage.OUTPUT_ATTACHMENT
    )

    def draw_frame():
        with swap_chain as current_texture_view:
            command_encoder = device.create_command_encoder()

            ca = color_attachment or {
                "resolve_target": None,
                "load_value": (0, 0, 0, 0),  # LoadOp.load or color
                "store_op": wgpu.StoreOp.store,
            }
            ca["attachment"] = current_texture_view
            render_pass = command_encoder.begin_render_pass(
                color_attachments=[ca],
                depth_stencil_attachment=depth_stencil_attachment,
                occlusion_query_set=None,
            )
            render_pass.push_debug_group("foo")

            render_pass.insert_debug_marker("setting pipeline")
            render_pass.set_pipeline(render_pipeline)
            render_pass.insert_debug_marker("setting bind group")
            render_pass.set_bind_group(
                0, bind_group, [], 0, 999999
            )  # last 2 elements not used
            for slot, vbo in enumerate(vbos):
                render_pass.insert_debug_marker(f"setting vbo {slot}")
                render_pass.set_vertex_buffer(slot, vbo, 0, vbo.size)
            render_pass.insert_debug_marker("invoking callback")
            renderpass_callback(render_pass)
            render_pass.insert_debug_marker("draw!")
            if ibo is None:
                if indirect_buffer is None:
                    render_pass.draw(4, 1, 0, 0)
                else:
                    render_pass.draw_indirect(indirect_buffer, 0)
            else:
                render_pass.set_index_buffer(ibo, 0, ibo.size)
                if indirect_buffer is None:
                    render_pass.draw_indexed(6, 1, 0, 0, 0)
                else:
                    render_pass.draw_indexed_indirect(indirect_buffer, 0)
            render_pass.pop_debug_group()
            render_pass.end_pass()
            device.default_queue.submit([command_encoder.finish()])

    canvas.request_draw(draw_frame)

    # Enter main loop
    while update_glfw_canvasses():
        glfw.poll_events()
    glfw.terminate()
def simple_event_loop():
    """ A real simple event loop, but it keeps the CPU busy. """
    while update_glfw_canvasses():
        glfw.poll_events()
Beispiel #6
0
def draw_frame():
    with swap_chain as current_texture_view:
        command_encoder = device.create_command_encoder()

        render_pass = command_encoder.begin_render_pass(
            color_attachments=[
                {
                    "attachment": current_texture_view,
                    "resolve_target": None,
                    "load_value": (0, 0, 0, 1),  # LoadOp.load or color
                    "store_op": wgpu.StoreOp.store,
                }
            ],
        )

        render_pass.set_pipeline(render_pipeline)
        render_pass.set_bind_group(
            0, bind_group, [], 0, 999999
        )  # last 2 elements not used
        render_pass.draw(3, 1, 0, 0)
        render_pass.end_pass()
        device.default_queue.submit([command_encoder.finish()])


canvas.request_draw(draw_frame)

while update_glfw_canvasses():
    glfw.poll_events()

glfw.terminate()