The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

t/gui: Add two scenes

authored by

Jakob Bornecrantz and committed by
Jakob Bornecrantz
a507aee9 74bdb0cb

+417
+2
src/xrt/targets/gui/CMakeLists.txt
··· 21 21 gui_ogl.c 22 22 gui_prober.c 23 23 gui_scene.cpp 24 + gui_scene_debug.c 25 + gui_scene_video.c 24 26 gui_sdl2.c 25 27 ../../../external/glad/gl.h 26 28 ../../../external/glad/gl.c
+28
src/xrt/targets/gui/gui_common.h
··· 27 27 #define NUM_XDEVS 8 28 28 struct xrt_device; 29 29 struct xrt_prober; 30 + struct xrt_fs; 31 + struct xrt_frame_context; 30 32 struct time_state; 31 33 struct gui_scene_manager; 32 34 ··· 215 217 */ 216 218 void 217 219 gui_scene_manager_destroy(struct program *p); 220 + 221 + 222 + /* 223 + * 224 + * Scene creation functions. 225 + * 226 + */ 227 + 228 + /*! 229 + * Shows a UI that lets you select a video device and mode. 230 + * 231 + * @ingroup gui 232 + */ 233 + void 234 + gui_scene_select_video(struct program *p); 235 + 236 + /*! 237 + * Given the frameserver runs some debug code on it. 238 + * 239 + * @ingroup gui 240 + */ 241 + void 242 + gui_scene_debug_video(struct program *p, 243 + struct xrt_frame_context *xfctx, 244 + struct xrt_fs *xfs, 245 + size_t mode); 218 246 219 247 220 248 #ifdef __cplusplus
+240
src/xrt/targets/gui/gui_scene_debug.c
··· 1 + // Copyright 2019, Collabora, Ltd. 2 + // SPDX-License-Identifier: BSL-1.0 3 + /*! 4 + * @file 5 + * @brief A debugging scene. 6 + * @author Jakob Bornecrantz <jakob@collabora.com> 7 + * @ingroup gui 8 + */ 9 + 10 + #include "util/u_var.h" 11 + #include "util/u_misc.h" 12 + #include "util/u_sink.h" 13 + 14 + #ifdef XRT_HAVE_OPENCV 15 + #include "tracking/t_tracking.h" 16 + #endif 17 + 18 + #include "xrt/xrt_frame.h" 19 + #include "xrt/xrt_prober.h" 20 + #include "xrt/xrt_frameserver.h" 21 + 22 + #include "gui_common.h" 23 + #include "gui_imgui.h" 24 + 25 + 26 + struct debug_scene 27 + { 28 + struct gui_scene base; 29 + struct xrt_frame_context *xfctx; 30 + }; 31 + 32 + /* 33 + * 34 + * Internal functions. 35 + * 36 + */ 37 + 38 + static void 39 + conv_rgb_f32_to_u8(struct xrt_colour_rgb_f32 *from, 40 + struct xrt_colour_rgb_u8 *to) 41 + { 42 + to->r = (uint8_t)(from->r * 255.0f); 43 + to->g = (uint8_t)(from->g * 255.0f); 44 + to->b = (uint8_t)(from->b * 255.0f); 45 + } 46 + 47 + static void 48 + conv_rgb_u8_to_f32(struct xrt_colour_rgb_u8 *from, 49 + struct xrt_colour_rgb_f32 *to) 50 + { 51 + to->r = from->r / 255.0f; 52 + to->g = from->g / 255.0f; 53 + to->b = from->b / 255.0f; 54 + } 55 + 56 + struct draw_state 57 + { 58 + bool hidden; 59 + }; 60 + 61 + static void 62 + on_root_enter(const char *name, void *priv) 63 + { 64 + struct draw_state *state = (struct draw_state *)priv; 65 + state->hidden = false; 66 + 67 + igBegin(name, NULL, 0); 68 + } 69 + 70 + static void 71 + on_elem(const char *name, enum u_var_kind kind, void *ptr, void *priv) 72 + { 73 + struct draw_state *state = (struct draw_state *)priv; 74 + if (state->hidden && kind != U_VAR_KIND_GUI_HEADER) { 75 + return; 76 + } 77 + 78 + const float drag_speed = 0.2f; 79 + const float power = 1.0f; 80 + const ImVec2 dummy = {0, 0}; 81 + ImGuiColorEditFlags flags = ImGuiColorEditFlags_NoInputs | 82 + ImGuiColorEditFlags_NoLabel | 83 + ImGuiColorEditFlags_PickerHueWheel; 84 + (void)dummy; 85 + ImGuiInputTextFlags i_flags = ImGuiInputTextFlags_None; 86 + ImGuiInputTextFlags ro_i_flags = ImGuiInputTextFlags_ReadOnly; 87 + 88 + switch (kind) { 89 + case U_VAR_KIND_BOOL: igCheckbox(name, ptr); break; 90 + case U_VAR_KIND_RGB_F32: 91 + igColorEdit3(name, (float *)ptr, flags); 92 + igSameLine(0.0f, 4.0f); 93 + igText("%s", name); 94 + break; 95 + case U_VAR_KIND_RGB_U8:; 96 + struct xrt_colour_rgb_f32 tmp; 97 + conv_rgb_u8_to_f32(ptr, &tmp); 98 + on_elem(name, U_VAR_KIND_RGB_F32, &tmp, priv); 99 + conv_rgb_f32_to_u8(&tmp, ptr); 100 + break; 101 + case U_VAR_KIND_U8: 102 + igDragScalar(name, ImGuiDataType_U8, ptr, drag_speed, NULL, 103 + NULL, NULL, power); 104 + break; 105 + case U_VAR_KIND_I32: 106 + igInputInt(name, (int *)ptr, 1, 10, i_flags); 107 + break; 108 + case U_VAR_KIND_VEC3_I32: igInputInt3(name, (int *)ptr, i_flags); break; 109 + case U_VAR_KIND_F32: 110 + igInputFloat(name, (float *)ptr, 1, 10, "%f", i_flags); 111 + break; 112 + case U_VAR_KIND_VEC3_F32: 113 + igInputFloat3(name, (float *)ptr, "%f", i_flags); 114 + break; 115 + case U_VAR_KIND_RO_TEXT: igText("%s: '%s'", name, (char *)ptr); break; 116 + case U_VAR_KIND_RO_I32: 117 + igInputInt(name, (int *)ptr, 1, 10, ro_i_flags); 118 + break; 119 + case U_VAR_KIND_RO_VEC3_I32: 120 + igInputInt3(name, (int *)ptr, ro_i_flags); 121 + break; 122 + case U_VAR_KIND_RO_F32: 123 + igInputFloat(name, (float *)ptr, 1, 10, "%f", ro_i_flags); 124 + break; 125 + case U_VAR_KIND_RO_VEC3_F32: 126 + igInputFloat3(name, (float *)ptr, "%f", ro_i_flags); 127 + break; 128 + case U_VAR_KIND_GUI_HEADER: 129 + state->hidden = !igCollapsingHeader(name, 0); 130 + break; 131 + default: igLabelText(name, "Unknown tag '%i'", kind); break; 132 + } 133 + } 134 + 135 + static void 136 + on_root_exit(const char *name, void *priv) 137 + { 138 + struct draw_state *state = (struct draw_state *)priv; 139 + state->hidden = false; 140 + 141 + igEnd(); 142 + } 143 + 144 + static void 145 + scene_render(struct gui_scene *scene, struct program *p) 146 + { 147 + struct debug_scene *ds = (struct debug_scene *)scene; 148 + (void)ds; 149 + struct draw_state state = {false}; 150 + 151 + u_var_visit(on_root_enter, on_root_exit, on_elem, &state); 152 + 153 + for (size_t i = 0; i < ARRAY_SIZE(p->texs); i++) { 154 + struct gui_ogl_texture *tex = p->texs[i]; 155 + 156 + if (tex == NULL) { 157 + continue; 158 + } 159 + 160 + gui_ogl_sink_update(tex); 161 + 162 + igBegin(tex->name, NULL, 0); 163 + 164 + igText("Sequence %u", (uint32_t)tex->seq); 165 + igCheckbox("Half", &tex->half); 166 + int w = tex->w / (tex->half ? 2 : 1); 167 + int h = tex->h / (tex->half ? 2 : 1); 168 + 169 + ImVec2 size = {w, h}; 170 + ImVec2 uv0 = {0, 0}; 171 + ImVec2 uv1 = {1, 1}; 172 + ImVec4 white = {1, 1, 1, 1}; 173 + ImTextureID id = (ImTextureID)(intptr_t)tex->id; 174 + igImage(id, size, uv0, uv1, white, white); 175 + 176 + igEnd(); 177 + } 178 + } 179 + 180 + static void 181 + scene_destroy(struct gui_scene *scene) 182 + { 183 + struct debug_scene *ds = (struct debug_scene *)scene; 184 + 185 + if (ds->xfctx != NULL) { 186 + xrt_frame_context_destroy_nodes(ds->xfctx); 187 + ds->xfctx = NULL; 188 + } 189 + 190 + free(ds); 191 + } 192 + 193 + 194 + /* 195 + * 196 + * 'Exported' functions. 197 + * 198 + */ 199 + 200 + void 201 + gui_scene_debug_video(struct program *p, 202 + struct xrt_frame_context *xfctx, 203 + struct xrt_fs *xfs, 204 + size_t mode) 205 + { 206 + struct debug_scene *ds = U_TYPED_CALLOC(struct debug_scene); 207 + uint32_t num_texs = 0; 208 + 209 + ds->base.render = scene_render; 210 + ds->base.destroy = scene_destroy; 211 + ds->xfctx = xfctx; 212 + 213 + gui_scene_push_front(p, &ds->base); 214 + 215 + struct xrt_frame_sink *xsink = NULL; 216 + 217 + p->texs[num_texs++] = gui_ogl_sink_create("Stream", xfctx, &xsink); 218 + u_sink_create_format_converter(xfctx, XRT_FORMAT_R8G8B8, xsink, &xsink); 219 + u_sink_queue_create(xfctx, xsink, &xsink); 220 + 221 + #ifdef XRT_HAVE_OPENCV 222 + struct xrt_frame_sink *split = xsink; 223 + xsink = NULL; 224 + struct xrt_frame_sink *xsinks[4] = {NULL, NULL, NULL, NULL}; 225 + p->texs[num_texs++] = gui_ogl_sink_create("Red", xfctx, &xsinks[0]); 226 + p->texs[num_texs++] = gui_ogl_sink_create("Purple", xfctx, &xsinks[1]); 227 + p->texs[num_texs++] = gui_ogl_sink_create("Blue", xfctx, &xsinks[2]); 228 + p->texs[num_texs++] = gui_ogl_sink_create("White", xfctx, &xsinks[3]); 229 + 230 + struct t_hsv_filter_params params = T_HSV_DEFAULT_PARAMS(); 231 + t_hsv_filter_create(xfctx, &params, xsinks, &xsink); 232 + u_sink_create_to_yuv_or_yuyv(xfctx, xsink, &xsink); 233 + u_sink_queue_create(xfctx, xsink, &xsink); 234 + 235 + u_sink_split_create(xfctx, split, xsink, &xsink); 236 + #endif 237 + 238 + // Now that we have setup a node graph, start it. 239 + xrt_fs_stream_start(xfs, xsink, mode); 240 + }
+147
src/xrt/targets/gui/gui_scene_video.c
··· 1 + // Copyright 2019, Collabora, Ltd. 2 + // SPDX-License-Identifier: BSL-1.0 3 + /*! 4 + * @file 5 + * @brief A very small scene that lets the user select a video device. 6 + * @author Jakob Bornecrantz <jakob@collabora.com> 7 + * @ingroup gui 8 + */ 9 + 10 + #include "util/u_misc.h" 11 + #include "util/u_format.h" 12 + 13 + #include "xrt/xrt_prober.h" 14 + #include "xrt/xrt_frameserver.h" 15 + 16 + #include "gui_common.h" 17 + #include "gui_imgui.h" 18 + 19 + 20 + struct video_select 21 + { 22 + struct gui_scene base; 23 + 24 + struct xrt_frame_context *xfctx; 25 + struct xrt_fs *xfs; 26 + 27 + struct xrt_fs_mode *modes; 28 + uint32_t num_modes; 29 + }; 30 + 31 + static ImVec2 button_dims = {256, 0}; 32 + 33 + 34 + /* 35 + * 36 + * Internal functions. 37 + * 38 + */ 39 + 40 + static void 41 + on_video_device(struct xrt_prober *xp, 42 + struct xrt_prober_device *pdev, 43 + const char *name, 44 + void *ptr) 45 + { 46 + struct video_select *vs = (struct video_select *)ptr; 47 + 48 + if (name == NULL) { 49 + return; 50 + } 51 + 52 + if (!igButton(name, button_dims)) { 53 + return; 54 + } 55 + 56 + vs->xfctx = U_TYPED_CALLOC(struct xrt_frame_context); 57 + xrt_prober_open_video_device(xp, pdev, vs->xfctx, &vs->xfs); 58 + xrt_fs_enumerate_modes(vs->xfs, &vs->modes, &vs->num_modes); 59 + } 60 + 61 + static bool 62 + render_mode(struct xrt_fs_mode *mode) 63 + { 64 + char tmp[512]; 65 + 66 + snprintf(tmp, 512, "%ux%u: %s", mode->width, mode->height, 67 + u_format_str(mode->format)); 68 + 69 + return igButton(tmp, button_dims); 70 + } 71 + 72 + static void 73 + scene_render(struct gui_scene *scene, struct program *p) 74 + { 75 + struct video_select *vs = (struct video_select *)scene; 76 + 77 + igBegin("Select video device/mode", NULL, 0); 78 + 79 + // If we have not found any modes keep showing the devices. 80 + if (vs->xfs == NULL) { 81 + xrt_prober_list_video_devices(p->xp, on_video_device, vs); 82 + } else if (vs->num_modes == 0) { 83 + // No modes on it :( 84 + igText("No modes found on '%s'!", "vs->xfs->name"); 85 + } 86 + 87 + // We have selected a stream device and it has modes. 88 + for (size_t i = 0; i < vs->num_modes; i++) { 89 + if (!render_mode(&vs->modes[i])) { 90 + continue; 91 + } 92 + 93 + // User selected this mode, create the debug scene. 94 + gui_scene_debug_video(p, vs->xfctx, vs->xfs, i); 95 + // We should not clean these up, zero them out. 96 + vs->xfctx = NULL; 97 + vs->xfs = NULL; 98 + 99 + // Schedule us to be deleted when it's safe. 100 + gui_scene_delete_me(p, scene); 101 + } 102 + 103 + igSeparator(); 104 + 105 + if (igButton("Exit", button_dims)) { 106 + gui_scene_delete_me(p, scene); 107 + } 108 + 109 + igEnd(); 110 + } 111 + 112 + static void 113 + scene_destroy(struct gui_scene *scene) 114 + { 115 + struct video_select *vs = (struct video_select *)scene; 116 + 117 + if (vs->xfctx) { 118 + xrt_frame_context_destroy_nodes(vs->xfctx); 119 + free(vs->xfctx); 120 + vs->xfctx = NULL; 121 + } 122 + 123 + if (vs->modes != NULL) { 124 + free(vs->modes); 125 + vs->modes = NULL; 126 + } 127 + 128 + free(scene); 129 + } 130 + 131 + 132 + /* 133 + * 134 + * 'Exported' functions. 135 + * 136 + */ 137 + 138 + void 139 + gui_scene_select_video(struct program *p) 140 + { 141 + struct video_select *vs = U_TYPED_CALLOC(struct video_select); 142 + 143 + vs->base.render = scene_render; 144 + vs->base.destroy = scene_destroy; 145 + 146 + gui_scene_push_front(p, &vs->base); 147 + }