st/gui: Refactor a few OpenGL drawing code into helper

This commit is contained in:
Jakob Bornecrantz 2023-09-13 14:04:18 +01:00
parent bde2dce2b6
commit 15743d822b
5 changed files with 159 additions and 59 deletions

View file

@ -8,6 +8,8 @@ add_library(
st_gui STATIC
gui_common.h
gui_imgui.h
gui_ogl.c
gui_ogl.h
gui_ogl_sink.c
gui_prober.c
gui_scene.cpp

View file

@ -0,0 +1,96 @@
// Copyright 2019-2023, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief OpenGL helper functions for drawing GUI elements.
* @author Jakob Bornecrantz <jakob@collabora.com>
* @author Moses Turner <moses@collabora.com>
* @ingroup gui
*/
#include "math/m_api.h"
#include "gui_ogl.h"
#include "gui_imgui.h"
/*
*
* Helpers.
*
*/
static void
get_uvs(ImVec2 *uv0, ImVec2 *uv1, bool rotate_180, bool flip_y)
{
// Flip direction of y (x) if we are rotating.
float u0 = rotate_180 ? 1.f : 0.f;
float u1 = rotate_180 ? 0.f : 1.f;
// Flip direction of v (y) if either flip_y or rotate_180 is true.
float v0 = (rotate_180 ^ flip_y) ? 1.f : 0.f;
float v1 = (rotate_180 ^ flip_y) ? 0.f : 1.f;
// Note: We can't easily do 90 or 270-degree rotations: https://github.com/ocornut/imgui/issues/3267
*uv0 = (ImVec2){u0, v0};
*uv1 = (ImVec2){u1, v1};
}
/*
*
* 'Exported' functions.
*
*/
void
gui_ogl_draw_image(uint32_t width, uint32_t height, uint32_t tex_id, float scale, bool rotate_180, bool flip_y)
{
ImVec2 uv0, uv1;
get_uvs(&uv0, &uv1, rotate_180, flip_y);
// Need to go via ints to get integer steps.
int w = (float)width * scale;
int h = (float)height * scale;
ImVec2 size = {(float)w, (float)h};
ImVec4 white = {1, 1, 1, 1};
ImVec4 black = {0, 0, 0, 1};
ImTextureID id = (ImTextureID)(intptr_t)tex_id;
igImageBg(id, size, uv0, uv1, white, white, black);
}
void
gui_ogl_draw_background(uint32_t width, uint32_t height, uint32_t tex_id, bool rotate_180, bool flip_y)
{
ImVec2 uv0, uv1;
get_uvs(&uv0, &uv1, rotate_180, flip_y);
const ImU32 white = 0xffffffff;
ImTextureID id = (ImTextureID)(intptr_t)tex_id;
ImGuiIO *io = igGetIO();
float in_w = (float)width;
float in_h = (float)height;
float out_w = io->DisplaySize.x;
float out_h = io->DisplaySize.y;
float scale_w = (float)out_w / in_w; // 128 / 1280 = 0.1
float scale_h = (float)out_h / in_h; // 128 / 800 = 0.16
float scale = MIN(scale_w, scale_h); // 0.1
float inside_w = in_w * scale;
float inside_h = in_h * scale;
float translate_x = (out_w - inside_w) / 2; // Should be 0 for 1280x800
float translate_y = (out_h - inside_h) / 2; // Should be (1280 - 800) / 2 = 240
ImVec2 p_min = {translate_x, translate_y};
ImVec2 p_max = {translate_x + inside_w, translate_y + inside_h};
ImDrawList *bg = igGetBackgroundDrawList();
ImDrawList_AddImage(bg, id, p_min, p_max, uv0, uv1, white);
}

View file

@ -0,0 +1,39 @@
// Copyright 2019-2023, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief OpenGL helper functions for drawing GUI elements.
* @author Jakob Bornecrantz <jakob@collabora.com>
* @ingroup gui
*/
#pragma once
#include "xrt/xrt_compiler.h"
#ifdef __cplusplus
extern "C" {
#endif
/*!
* Draw the given textures as igImage, scale of 1.0f == 100%.
*
* @ingroup gui
*/
void
gui_ogl_draw_image(uint32_t width, uint32_t height, uint32_t tex_id, float scale, bool rotate_180, bool flip_y);
/*!
* Draw the given texture to the background of the current OS window.
*
* @ingroup gui
*/
void
gui_ogl_draw_background(uint32_t width, uint32_t height, uint32_t tex_id, bool rotate_180, bool flip_y);
#ifdef __cplusplus
}
#endif

View file

@ -27,6 +27,7 @@
#include "gui_common.h"
#include "gui_imgui.h"
#include "gui_ogl.h"
#include <assert.h>
@ -134,15 +135,14 @@ draw_texture(struct gui_ogl_texture *tex, bool header)
gui_ogl_sink_update(tex);
int w = tex->w / (tex->half ? 2 : 1);
int h = tex->h / (tex->half ? 2 : 1);
gui_ogl_draw_image( //
(uint32_t)tex->w, // width
(uint32_t)tex->h, // height
tex->id, // tex_id
tex->half ? 0.5f : 1.0f, // scale
false, // rotate_180
false); // flip_y
ImVec2 size = {(float)w, (float)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);
igText("Sequence %u", (uint32_t)tex->seq);
char temp[512];

View file

@ -34,6 +34,7 @@
#include "gstreamer/gst_pipeline.h"
#endif
#include "gui_ogl.h"
#include "gui_imgui.h"
#include "gui_common.h"
#include "gui_window_record.h"
@ -313,42 +314,12 @@ gui_window_record_to_background(struct gui_record_window *rw, struct gui_program
gui_ogl_sink_update(tex);
ImVec2 uv0 = {0, 0};
ImVec2 uv1 = {1, 1};
// Note: We can't easily do 90 or 270-degree rotations: https://github.com/ocornut/imgui/issues/3267
if (rw->texture.rotate_180) {
uv0 = (ImVec2){1, 1};
uv1 = (ImVec2){0, 0};
}
const ImU32 white = 0xffffffff;
ImTextureID id = (ImTextureID)(intptr_t)tex->id;
ImGuiIO *io = igGetIO();
// Shamelessly stolen from hg_model.cpp
float in_w = tex->w;
float in_h = tex->h;
float out_w = io->DisplaySize.x;
float out_h = io->DisplaySize.y;
float scale_w = (float)out_w / in_w; // 128 / 1280 = 0.1
float scale_h = (float)out_h / in_h; // 128 / 800 = 0.16
float scale = MIN(scale_w, scale_h); // 0.1
float inside_w = in_w * scale;
float inside_h = in_h * scale;
float translate_x = (out_w - inside_w) / 2; // Should be 0 for 1280x800
float translate_y = (out_h - inside_h) / 2; // Should be (1280 - 800) / 2 = 240
ImVec2 p_min = {translate_x, translate_y};
ImVec2 p_max = {translate_x + inside_w, translate_y + inside_h};
ImDrawList *bg = igGetBackgroundDrawList();
ImDrawList_AddImage(bg, id, p_min, p_max, uv0, uv1, white);
gui_ogl_draw_background( //
(uint32_t)tex->w, // width
(uint32_t)tex->h, // height
tex->id, // tex_id
rw->texture.rotate_180, // rotate_180
false); // flip_y
}
void
@ -363,22 +334,14 @@ gui_window_record_render(struct gui_record_window *rw, struct gui_program *p)
struct gui_ogl_texture *tex = rw->texture.ogl;
int w = tex->w * rw->texture.scale / 100.0f;
int h = tex->h * rw->texture.scale / 100.0f;
gui_ogl_draw_image( //
(uint32_t)tex->w, // width
(uint32_t)tex->h, // height
tex->id, // tex_id
rw->texture.scale / 100.0f, // scale
rw->texture.rotate_180, // rotate_180
false); // flip_y
ImVec2 size = {(float)w, (float)h};
ImVec2 uv0 = {0, 0};
ImVec2 uv1 = {1, 1};
// Note: We can't easily do 90 or 270-degree rotations: https://github.com/ocornut/imgui/issues/3267
if (rw->texture.rotate_180) {
uv0 = (ImVec2){1, 1};
uv1 = (ImVec2){0, 0};
}
ImVec4 white = {1, 1, 1, 1};
ImTextureID id = (ImTextureID)(intptr_t)tex->id;
igImage(id, size, uv0, uv1, white, white);
#ifdef XRT_HAVE_GST
draw_gst(rw);