CPU Rendering with a Visualizer
Overview
- Obtain a session as in earlier tutorials (rejoin or onboard)
- Subscribe to incoming render stream requests and wait for a peer (e.g. a Visualizer) to request one
- Create a CPU render sender for the requesting peer and submit a short gradient animation
Prerequisites
- Complete the GUI Panel Operations tutorial
- A running QarOS hub (for the first run, read the pairing code off its onboarding screen), with a peer that requests a render stream from this application once it is running
Build and Run
cmake --build --preset x64-windows-debug --target cpu_rendering_visualizer
./build/x64-windows/Debug/cpu_rendering_visualizer.exe
<path-to-qar-streaming-c.dll> [runtime-dir] [pairing-code]
Parse Arguments
if(argc < 2)
{
print_usage(argv[0]);
return 1;
}
const char* library_path = argv[1];
const char* runtime_dir = NULL;
char runtime_dir_buffer[1024] = { 0 };
if(argc >= 3)
{
runtime_dir = argv[2];
}
else if(get_dir_from_path(
library_path, runtime_dir_buffer, sizeof(runtime_dir_buffer)
))
{
runtime_dir = runtime_dir_buffer;
}
const char* pairing_code = (argc >= 4) ? argv[3] : NULL;
Library, Runtime, and Session Setup
The session is obtained with the shared rejoin-or-onboard helper described in the Onboarding and Rejoin tutorial.
if(!qar_library_load(library_path))
{
fprintf(stderr, "Failed to load '%s'.\n", library_path);
return 2;
}
QarLibraryInit library_init = qar_library_init_default();
library_init.enable_console_logging = true;
QarResult library_result = qar_library_init(&library_init);
if(qar_result_is_error(library_result))
{
log_result("qar_library_init", library_result);
return 3;
}
QarRuntime* runtime = NULL;
QarRuntimeInit runtime_init = qar_runtime_init_default();
runtime_init.runtime_binaries_folder_path = runtime_dir;
QarResult runtime_result = qar_runtime_create(&runtime_init, &runtime);
if(qar_result_is_error(runtime_result) || runtime == NULL)
{
log_result("qar_runtime_create", runtime_result);
return 4;
}
QarOnboardingId onboarding_id = qar_onboarding_id_default();
QarSession* session = NULL;
runtime,
pairing_code,
"cpu_rendering_visualizer.onboarding-id.txt",
"CPU Renderer",
&onboarding_id,
&session
) != 0
|| session == NULL)
{
qar_runtime_destroy(runtime);
return 5;
}
Wait for a Render Stream Request
RenderRequestState request_state = { false, qar_peer_id_default() };
QarResult subscribe_result = qar_render_sender_subscribe_requests(
session, on_render_request, &request_state, NULL
);
log_result("qar_render_sender_subscribe_requests", subscribe_result);
printf(
"Waiting for a peer to request a render stream (e.g. open a "
"Visualizer on the hub) ...\n"
);
while(!request_state.has_request)
{
Sleep(50);
}
Render and Submit Frames
QarRenderSenderInit sender_init = qar_render_sender_init_default();
sender_init.graphics_api = QAR_GRAPHICS_API_CPU;
sender_init.peer_id = request_state.target_peer_id;
QarRenderSender* sender = NULL;
QarResult sender_result =
qar_render_sender_create(session, &sender_init, NULL, &sender);
if(qar_result_is_error(sender_result) || sender == NULL)
{
log_result("qar_render_sender_create", sender_result);
log_result("qar_session_leave", qar_session_leave(session));
qar_session_handle_destroy(session);
qar_runtime_destroy(runtime);
return 6;
}
log_result("qar_render_sender_create", sender_result);
QarVideoFrameLayout layout = qar_video_frame_layout_default();
QarResult layout_result = qar_render_sender_layout(sender, &layout);
log_result("qar_render_sender_layout", layout_result);
const size_t frame_count = 3;
for(size_t frame_index = 0; frame_index < frame_count; ++frame_index)
{
QarRenderFrameInfo* frame_info = NULL;
QarResult begin_result =
qar_render_sender_begin_frame(sender, NULL, &frame_info);
log_result("qar_render_sender_begin_frame", begin_result);
if(qar_result_is_error(begin_result) || frame_info == NULL)
{
break;
}
QarVideoFrameCpu frame = qar_video_frame_cpu_default();
QarResult frame_result = qar_render_sender_frame_cpu(sender, &frame);
log_result("qar_render_sender_frame_cpu", frame_result);
if(qar_result_is_success(frame_result))
{
render_gradient(&frame, frame_index);
show.rendered_near_far.near_plane = 0.1f;
show.rendered_near_far.far_plane = 10.0f;
"qar_render_sender_show_frame",
qar_render_sender_show_frame(sender, &show)
);
}
qar_render_frame_info_handle_destroy(frame_info);
}
qar_render_stream_handle_destroy(sender);
Generated via doxygen2docusaurus 2.2.1 by Doxygen 1.9.8.