mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2024-12-28 18:46:18 +00:00
t/gui: Add two scenes
This commit is contained in:
parent
74bdb0cb38
commit
a507aee906
|
@ -21,6 +21,8 @@ set(SOURCE_FILES
|
|||
gui_ogl.c
|
||||
gui_prober.c
|
||||
gui_scene.cpp
|
||||
gui_scene_debug.c
|
||||
gui_scene_video.c
|
||||
gui_sdl2.c
|
||||
../../../external/glad/gl.h
|
||||
../../../external/glad/gl.c
|
||||
|
|
|
@ -27,6 +27,8 @@ extern "C" {
|
|||
#define NUM_XDEVS 8
|
||||
struct xrt_device;
|
||||
struct xrt_prober;
|
||||
struct xrt_fs;
|
||||
struct xrt_frame_context;
|
||||
struct time_state;
|
||||
struct gui_scene_manager;
|
||||
|
||||
|
@ -217,6 +219,32 @@ void
|
|||
gui_scene_manager_destroy(struct program *p);
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Scene creation functions.
|
||||
*
|
||||
*/
|
||||
|
||||
/*!
|
||||
* Shows a UI that lets you select a video device and mode.
|
||||
*
|
||||
* @ingroup gui
|
||||
*/
|
||||
void
|
||||
gui_scene_select_video(struct program *p);
|
||||
|
||||
/*!
|
||||
* Given the frameserver runs some debug code on it.
|
||||
*
|
||||
* @ingroup gui
|
||||
*/
|
||||
void
|
||||
gui_scene_debug_video(struct program *p,
|
||||
struct xrt_frame_context *xfctx,
|
||||
struct xrt_fs *xfs,
|
||||
size_t mode);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
240
src/xrt/targets/gui/gui_scene_debug.c
Normal file
240
src/xrt/targets/gui/gui_scene_debug.c
Normal file
|
@ -0,0 +1,240 @@
|
|||
// Copyright 2019, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief A debugging scene.
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @ingroup gui
|
||||
*/
|
||||
|
||||
#include "util/u_var.h"
|
||||
#include "util/u_misc.h"
|
||||
#include "util/u_sink.h"
|
||||
|
||||
#ifdef XRT_HAVE_OPENCV
|
||||
#include "tracking/t_tracking.h"
|
||||
#endif
|
||||
|
||||
#include "xrt/xrt_frame.h"
|
||||
#include "xrt/xrt_prober.h"
|
||||
#include "xrt/xrt_frameserver.h"
|
||||
|
||||
#include "gui_common.h"
|
||||
#include "gui_imgui.h"
|
||||
|
||||
|
||||
struct debug_scene
|
||||
{
|
||||
struct gui_scene base;
|
||||
struct xrt_frame_context *xfctx;
|
||||
};
|
||||
|
||||
/*
|
||||
*
|
||||
* Internal functions.
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
conv_rgb_f32_to_u8(struct xrt_colour_rgb_f32 *from,
|
||||
struct xrt_colour_rgb_u8 *to)
|
||||
{
|
||||
to->r = (uint8_t)(from->r * 255.0f);
|
||||
to->g = (uint8_t)(from->g * 255.0f);
|
||||
to->b = (uint8_t)(from->b * 255.0f);
|
||||
}
|
||||
|
||||
static void
|
||||
conv_rgb_u8_to_f32(struct xrt_colour_rgb_u8 *from,
|
||||
struct xrt_colour_rgb_f32 *to)
|
||||
{
|
||||
to->r = from->r / 255.0f;
|
||||
to->g = from->g / 255.0f;
|
||||
to->b = from->b / 255.0f;
|
||||
}
|
||||
|
||||
struct draw_state
|
||||
{
|
||||
bool hidden;
|
||||
};
|
||||
|
||||
static void
|
||||
on_root_enter(const char *name, void *priv)
|
||||
{
|
||||
struct draw_state *state = (struct draw_state *)priv;
|
||||
state->hidden = false;
|
||||
|
||||
igBegin(name, NULL, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
on_elem(const char *name, enum u_var_kind kind, void *ptr, void *priv)
|
||||
{
|
||||
struct draw_state *state = (struct draw_state *)priv;
|
||||
if (state->hidden && kind != U_VAR_KIND_GUI_HEADER) {
|
||||
return;
|
||||
}
|
||||
|
||||
const float drag_speed = 0.2f;
|
||||
const float power = 1.0f;
|
||||
const ImVec2 dummy = {0, 0};
|
||||
ImGuiColorEditFlags flags = ImGuiColorEditFlags_NoInputs |
|
||||
ImGuiColorEditFlags_NoLabel |
|
||||
ImGuiColorEditFlags_PickerHueWheel;
|
||||
(void)dummy;
|
||||
ImGuiInputTextFlags i_flags = ImGuiInputTextFlags_None;
|
||||
ImGuiInputTextFlags ro_i_flags = ImGuiInputTextFlags_ReadOnly;
|
||||
|
||||
switch (kind) {
|
||||
case U_VAR_KIND_BOOL: igCheckbox(name, ptr); break;
|
||||
case U_VAR_KIND_RGB_F32:
|
||||
igColorEdit3(name, (float *)ptr, flags);
|
||||
igSameLine(0.0f, 4.0f);
|
||||
igText("%s", name);
|
||||
break;
|
||||
case U_VAR_KIND_RGB_U8:;
|
||||
struct xrt_colour_rgb_f32 tmp;
|
||||
conv_rgb_u8_to_f32(ptr, &tmp);
|
||||
on_elem(name, U_VAR_KIND_RGB_F32, &tmp, priv);
|
||||
conv_rgb_f32_to_u8(&tmp, ptr);
|
||||
break;
|
||||
case U_VAR_KIND_U8:
|
||||
igDragScalar(name, ImGuiDataType_U8, ptr, drag_speed, NULL,
|
||||
NULL, NULL, power);
|
||||
break;
|
||||
case U_VAR_KIND_I32:
|
||||
igInputInt(name, (int *)ptr, 1, 10, i_flags);
|
||||
break;
|
||||
case U_VAR_KIND_VEC3_I32: igInputInt3(name, (int *)ptr, i_flags); break;
|
||||
case U_VAR_KIND_F32:
|
||||
igInputFloat(name, (float *)ptr, 1, 10, "%f", i_flags);
|
||||
break;
|
||||
case U_VAR_KIND_VEC3_F32:
|
||||
igInputFloat3(name, (float *)ptr, "%f", i_flags);
|
||||
break;
|
||||
case U_VAR_KIND_RO_TEXT: igText("%s: '%s'", name, (char *)ptr); break;
|
||||
case U_VAR_KIND_RO_I32:
|
||||
igInputInt(name, (int *)ptr, 1, 10, ro_i_flags);
|
||||
break;
|
||||
case U_VAR_KIND_RO_VEC3_I32:
|
||||
igInputInt3(name, (int *)ptr, ro_i_flags);
|
||||
break;
|
||||
case U_VAR_KIND_RO_F32:
|
||||
igInputFloat(name, (float *)ptr, 1, 10, "%f", ro_i_flags);
|
||||
break;
|
||||
case U_VAR_KIND_RO_VEC3_F32:
|
||||
igInputFloat3(name, (float *)ptr, "%f", ro_i_flags);
|
||||
break;
|
||||
case U_VAR_KIND_GUI_HEADER:
|
||||
state->hidden = !igCollapsingHeader(name, 0);
|
||||
break;
|
||||
default: igLabelText(name, "Unknown tag '%i'", kind); break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
on_root_exit(const char *name, void *priv)
|
||||
{
|
||||
struct draw_state *state = (struct draw_state *)priv;
|
||||
state->hidden = false;
|
||||
|
||||
igEnd();
|
||||
}
|
||||
|
||||
static void
|
||||
scene_render(struct gui_scene *scene, struct program *p)
|
||||
{
|
||||
struct debug_scene *ds = (struct debug_scene *)scene;
|
||||
(void)ds;
|
||||
struct draw_state state = {false};
|
||||
|
||||
u_var_visit(on_root_enter, on_root_exit, on_elem, &state);
|
||||
|
||||
for (size_t i = 0; i < ARRAY_SIZE(p->texs); i++) {
|
||||
struct gui_ogl_texture *tex = p->texs[i];
|
||||
|
||||
if (tex == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
gui_ogl_sink_update(tex);
|
||||
|
||||
igBegin(tex->name, NULL, 0);
|
||||
|
||||
igText("Sequence %u", (uint32_t)tex->seq);
|
||||
igCheckbox("Half", &tex->half);
|
||||
int w = tex->w / (tex->half ? 2 : 1);
|
||||
int h = tex->h / (tex->half ? 2 : 1);
|
||||
|
||||
ImVec2 size = {w, h};
|
||||
ImVec2 uv0 = {0, 0};
|
||||
ImVec2 uv1 = {1, 1};
|
||||
ImVec4 white = {1, 1, 1, 1};
|
||||
ImTextureID id = (ImTextureID)(intptr_t)tex->id;
|
||||
igImage(id, size, uv0, uv1, white, white);
|
||||
|
||||
igEnd();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
scene_destroy(struct gui_scene *scene)
|
||||
{
|
||||
struct debug_scene *ds = (struct debug_scene *)scene;
|
||||
|
||||
if (ds->xfctx != NULL) {
|
||||
xrt_frame_context_destroy_nodes(ds->xfctx);
|
||||
ds->xfctx = NULL;
|
||||
}
|
||||
|
||||
free(ds);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* 'Exported' functions.
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
gui_scene_debug_video(struct program *p,
|
||||
struct xrt_frame_context *xfctx,
|
||||
struct xrt_fs *xfs,
|
||||
size_t mode)
|
||||
{
|
||||
struct debug_scene *ds = U_TYPED_CALLOC(struct debug_scene);
|
||||
uint32_t num_texs = 0;
|
||||
|
||||
ds->base.render = scene_render;
|
||||
ds->base.destroy = scene_destroy;
|
||||
ds->xfctx = xfctx;
|
||||
|
||||
gui_scene_push_front(p, &ds->base);
|
||||
|
||||
struct xrt_frame_sink *xsink = NULL;
|
||||
|
||||
p->texs[num_texs++] = gui_ogl_sink_create("Stream", xfctx, &xsink);
|
||||
u_sink_create_format_converter(xfctx, XRT_FORMAT_R8G8B8, xsink, &xsink);
|
||||
u_sink_queue_create(xfctx, xsink, &xsink);
|
||||
|
||||
#ifdef XRT_HAVE_OPENCV
|
||||
struct xrt_frame_sink *split = xsink;
|
||||
xsink = NULL;
|
||||
struct xrt_frame_sink *xsinks[4] = {NULL, NULL, NULL, NULL};
|
||||
p->texs[num_texs++] = gui_ogl_sink_create("Red", xfctx, &xsinks[0]);
|
||||
p->texs[num_texs++] = gui_ogl_sink_create("Purple", xfctx, &xsinks[1]);
|
||||
p->texs[num_texs++] = gui_ogl_sink_create("Blue", xfctx, &xsinks[2]);
|
||||
p->texs[num_texs++] = gui_ogl_sink_create("White", xfctx, &xsinks[3]);
|
||||
|
||||
struct t_hsv_filter_params params = T_HSV_DEFAULT_PARAMS();
|
||||
t_hsv_filter_create(xfctx, ¶ms, xsinks, &xsink);
|
||||
u_sink_create_to_yuv_or_yuyv(xfctx, xsink, &xsink);
|
||||
u_sink_queue_create(xfctx, xsink, &xsink);
|
||||
|
||||
u_sink_split_create(xfctx, split, xsink, &xsink);
|
||||
#endif
|
||||
|
||||
// Now that we have setup a node graph, start it.
|
||||
xrt_fs_stream_start(xfs, xsink, mode);
|
||||
}
|
147
src/xrt/targets/gui/gui_scene_video.c
Normal file
147
src/xrt/targets/gui/gui_scene_video.c
Normal file
|
@ -0,0 +1,147 @@
|
|||
// Copyright 2019, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief A very small scene that lets the user select a video device.
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @ingroup gui
|
||||
*/
|
||||
|
||||
#include "util/u_misc.h"
|
||||
#include "util/u_format.h"
|
||||
|
||||
#include "xrt/xrt_prober.h"
|
||||
#include "xrt/xrt_frameserver.h"
|
||||
|
||||
#include "gui_common.h"
|
||||
#include "gui_imgui.h"
|
||||
|
||||
|
||||
struct video_select
|
||||
{
|
||||
struct gui_scene base;
|
||||
|
||||
struct xrt_frame_context *xfctx;
|
||||
struct xrt_fs *xfs;
|
||||
|
||||
struct xrt_fs_mode *modes;
|
||||
uint32_t num_modes;
|
||||
};
|
||||
|
||||
static ImVec2 button_dims = {256, 0};
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Internal functions.
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
on_video_device(struct xrt_prober *xp,
|
||||
struct xrt_prober_device *pdev,
|
||||
const char *name,
|
||||
void *ptr)
|
||||
{
|
||||
struct video_select *vs = (struct video_select *)ptr;
|
||||
|
||||
if (name == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!igButton(name, button_dims)) {
|
||||
return;
|
||||
}
|
||||
|
||||
vs->xfctx = U_TYPED_CALLOC(struct xrt_frame_context);
|
||||
xrt_prober_open_video_device(xp, pdev, vs->xfctx, &vs->xfs);
|
||||
xrt_fs_enumerate_modes(vs->xfs, &vs->modes, &vs->num_modes);
|
||||
}
|
||||
|
||||
static bool
|
||||
render_mode(struct xrt_fs_mode *mode)
|
||||
{
|
||||
char tmp[512];
|
||||
|
||||
snprintf(tmp, 512, "%ux%u: %s", mode->width, mode->height,
|
||||
u_format_str(mode->format));
|
||||
|
||||
return igButton(tmp, button_dims);
|
||||
}
|
||||
|
||||
static void
|
||||
scene_render(struct gui_scene *scene, struct program *p)
|
||||
{
|
||||
struct video_select *vs = (struct video_select *)scene;
|
||||
|
||||
igBegin("Select video device/mode", NULL, 0);
|
||||
|
||||
// If we have not found any modes keep showing the devices.
|
||||
if (vs->xfs == NULL) {
|
||||
xrt_prober_list_video_devices(p->xp, on_video_device, vs);
|
||||
} else if (vs->num_modes == 0) {
|
||||
// No modes on it :(
|
||||
igText("No modes found on '%s'!", "vs->xfs->name");
|
||||
}
|
||||
|
||||
// We have selected a stream device and it has modes.
|
||||
for (size_t i = 0; i < vs->num_modes; i++) {
|
||||
if (!render_mode(&vs->modes[i])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// User selected this mode, create the debug scene.
|
||||
gui_scene_debug_video(p, vs->xfctx, vs->xfs, i);
|
||||
// We should not clean these up, zero them out.
|
||||
vs->xfctx = NULL;
|
||||
vs->xfs = NULL;
|
||||
|
||||
// Schedule us to be deleted when it's safe.
|
||||
gui_scene_delete_me(p, scene);
|
||||
}
|
||||
|
||||
igSeparator();
|
||||
|
||||
if (igButton("Exit", button_dims)) {
|
||||
gui_scene_delete_me(p, scene);
|
||||
}
|
||||
|
||||
igEnd();
|
||||
}
|
||||
|
||||
static void
|
||||
scene_destroy(struct gui_scene *scene)
|
||||
{
|
||||
struct video_select *vs = (struct video_select *)scene;
|
||||
|
||||
if (vs->xfctx) {
|
||||
xrt_frame_context_destroy_nodes(vs->xfctx);
|
||||
free(vs->xfctx);
|
||||
vs->xfctx = NULL;
|
||||
}
|
||||
|
||||
if (vs->modes != NULL) {
|
||||
free(vs->modes);
|
||||
vs->modes = NULL;
|
||||
}
|
||||
|
||||
free(scene);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* 'Exported' functions.
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
gui_scene_select_video(struct program *p)
|
||||
{
|
||||
struct video_select *vs = U_TYPED_CALLOC(struct video_select);
|
||||
|
||||
vs->base.render = scene_render;
|
||||
vs->base.destroy = scene_destroy;
|
||||
|
||||
gui_scene_push_front(p, &vs->base);
|
||||
}
|
Loading…
Reference in a new issue