mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2024-12-28 02:26:16 +00:00
t/gui: Add SDL2 based GUI target
This commit is contained in:
parent
d48b3385f8
commit
44d58037b7
|
@ -29,6 +29,7 @@ find_package(OpenHMD)
|
|||
find_package(OpenCV COMPONENTS core calib3d highgui imgproc imgcodecs features2d video)
|
||||
find_package(Libusb1)
|
||||
find_package(JPEG)
|
||||
find_package(SDL2)
|
||||
|
||||
# @TODO Turn into a find_package LIBUVC file.
|
||||
pkg_check_modules(LIBUVC libuvc)
|
||||
|
@ -59,6 +60,7 @@ cmake_dependent_option(BUILD_WITH_LIBUVC "Enable libuvc video driver" ON "LIBUVC
|
|||
cmake_dependent_option(BUILD_WITH_FFMPEG "Enable ffmpeg testing video driver" ON "FFMPEG_FOUND" OFF)
|
||||
cmake_dependent_option(BUILD_WITH_HIDAPI "Enable HIDAPI-based driver(s) (OSVR HDK, PSVR)" ON "HIDAPI_FOUND" OFF)
|
||||
cmake_dependent_option(BUILD_WITH_OPENHMD "Enable OpenHMD driver" ON "OPENHMD_FOUND" OFF)
|
||||
cmake_dependent_option(BUILD_WITH_SDL2 "Enable SDL2 based test application" ON "SDL2_FOUND" OFF)
|
||||
|
||||
|
||||
###
|
||||
|
@ -101,6 +103,18 @@ if(BUILD_WITH_FFMPEG)
|
|||
add_definitions(-DXRT_HAVE_FFMPEG)
|
||||
endif()
|
||||
|
||||
if(BUILD_WITH_SDL2)
|
||||
add_definitions(-DXRT_HAVE_SDL2)
|
||||
|
||||
# Arch work around
|
||||
if(NOT DEFINED SDL2_LIBRARIES)
|
||||
set(SDL2_LIBRARIES SDL2::SDL2)
|
||||
endif()
|
||||
|
||||
# SDL2 based gui
|
||||
set(BUILD_TARGET_GUI TRUE)
|
||||
endif()
|
||||
|
||||
if(BUILD_WITH_OPENHMD)
|
||||
add_definitions(-DXRT_HAVE_OPENHMD)
|
||||
|
||||
|
|
|
@ -56,3 +56,7 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
|||
add_subdirectory(common)
|
||||
add_subdirectory(openxr)
|
||||
add_subdirectory(cli)
|
||||
|
||||
if(BUILD_TARGET_GUI)
|
||||
add_subdirectory(gui)
|
||||
endif()
|
||||
|
|
62
src/xrt/targets/gui/CMakeLists.txt
Normal file
62
src/xrt/targets/gui/CMakeLists.txt
Normal file
|
@ -0,0 +1,62 @@
|
|||
# Copyright 2019, Collabora, Ltd.
|
||||
# SPDX-License-Identifier: BSL-1.0
|
||||
|
||||
######
|
||||
# Create a small SDL2 based GUI for Monado.
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../targets/common
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../auxiliary
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../drivers
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../../external
|
||||
${SDL2_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
set(SOURCE_FILES
|
||||
gui_common.h
|
||||
gui_main.c
|
||||
gui_sdl2.c
|
||||
../../../external/glad/gl.h
|
||||
../../../external/glad/gl.c
|
||||
)
|
||||
|
||||
add_executable(gui
|
||||
${SOURCE_FILES}
|
||||
$<TARGET_OBJECTS:aux_os>
|
||||
$<TARGET_OBJECTS:aux_util>
|
||||
$<TARGET_OBJECTS:aux_math>
|
||||
$<TARGET_OBJECTS:st_prober>
|
||||
$<TARGET_OBJECTS:target_lists>
|
||||
)
|
||||
|
||||
set_target_properties(gui PROPERTIES
|
||||
OUTPUT_NAME monado-gui
|
||||
PREFIX ""
|
||||
)
|
||||
|
||||
target_link_libraries(gui PRIVATE
|
||||
${LIBUSB_LIBRARIES}
|
||||
${LIBUVC_LIBRARIES}
|
||||
${UDEV_LIBRARIES}
|
||||
${SDL2_LIBRARIES}
|
||||
)
|
||||
|
||||
if(BUILD_TRACKING)
|
||||
target_link_libraries(gui PRIVATE
|
||||
$<TARGET_OBJECTS:aux_tracking>
|
||||
${OpenCV_LIBRARIES}
|
||||
)
|
||||
endif()
|
||||
|
||||
if(DRIVER_OBJECTS)
|
||||
target_sources(gui PRIVATE ${DRIVER_OBJECTS})
|
||||
endif()
|
||||
|
||||
if(BUILD_WITH_JPEG)
|
||||
target_link_libraries(gui PRIVATE ${JPEG_LIBRARIES})
|
||||
endif()
|
||||
|
||||
if(DRIVER_LIBRARIES)
|
||||
target_link_libraries(gui PRIVATE ${DRIVER_LIBRARIES})
|
||||
endif()
|
91
src/xrt/targets/gui/gui_common.h
Normal file
91
src/xrt/targets/gui/gui_common.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
// Copyright 2019, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Common file for the Monado GUI program.
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @ingroup gui
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "xrt/xrt_defines.h"
|
||||
#include <SDL2/SDL.h>
|
||||
|
||||
/*!
|
||||
* @defgroup gui GUI Config Interface
|
||||
* @ingroup xrt
|
||||
*
|
||||
* @brief Small GUI interface to configure Monado based on SDL2.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*!
|
||||
* Common struct holding state for the GUI interface.
|
||||
*
|
||||
* @ingroup gui
|
||||
*/
|
||||
struct program
|
||||
{
|
||||
SDL_Window *win;
|
||||
SDL_GLContext ctx;
|
||||
|
||||
bool stopped;
|
||||
bool initialized;
|
||||
|
||||
struct
|
||||
{
|
||||
SDL_Surface *sf;
|
||||
uint8_t *buffer;
|
||||
size_t stride;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
bool own_buffer;
|
||||
} blit;
|
||||
};
|
||||
|
||||
/*!
|
||||
* Init SDL2, create and show a window and bring up any other structs needed.
|
||||
*
|
||||
* @ingroup gui
|
||||
*/
|
||||
int
|
||||
gui_sdl2_init(struct program *p);
|
||||
|
||||
/*!
|
||||
* Loop until quit signal has been received.
|
||||
*
|
||||
* @ingroup gui
|
||||
*/
|
||||
void
|
||||
gui_sdl2_loop(struct program *p);
|
||||
|
||||
/*!
|
||||
* Display a 24bit RGB image on the screen.
|
||||
*
|
||||
* @ingroup gui
|
||||
*/
|
||||
void
|
||||
gui_sdl2_display_R8G8B8(struct program *p,
|
||||
bool resize,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
size_t stride,
|
||||
void *data);
|
||||
|
||||
/*!
|
||||
* Destroy all SDL things and quit SDL.
|
||||
*
|
||||
* @ingroup gui
|
||||
*/
|
||||
void
|
||||
gui_sdl2_quit(struct program *p);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
30
src/xrt/targets/gui/gui_main.c
Normal file
30
src/xrt/targets/gui/gui_main.c
Normal file
|
@ -0,0 +1,30 @@
|
|||
// Copyright 2019, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief Main entrypoint for the Monado GUI program.
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @ingroup gui
|
||||
*/
|
||||
|
||||
#include "gui_common.h"
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct program p = {0};
|
||||
int ret;
|
||||
|
||||
ret = gui_sdl2_init(&p);
|
||||
if (ret != 0) {
|
||||
gui_sdl2_quit(&p);
|
||||
return ret;
|
||||
}
|
||||
|
||||
gui_sdl2_loop(&p);
|
||||
|
||||
gui_sdl2_quit(&p);
|
||||
|
||||
return 0;
|
||||
}
|
202
src/xrt/targets/gui/gui_sdl2.c
Normal file
202
src/xrt/targets/gui/gui_sdl2.c
Normal file
|
@ -0,0 +1,202 @@
|
|||
// Copyright 2019, Collabora, Ltd.
|
||||
// SPDX-License-Identifier: BSL-1.0
|
||||
/*!
|
||||
* @file
|
||||
* @brief SDL2 functions to drive the GUI.
|
||||
* @author Jakob Bornecrantz <jakob@collabora.com>
|
||||
* @ingroup gui
|
||||
*/
|
||||
|
||||
#include "gui_common.h"
|
||||
#include "glad/gl.h"
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* Internal static functions
|
||||
*
|
||||
*/
|
||||
|
||||
XRT_MAYBE_UNUSED static void
|
||||
create_blit_info(struct program *p, uint32_t width, uint32_t height)
|
||||
{
|
||||
if (p->blit.sf != NULL) {
|
||||
SDL_FreeSurface(p->blit.sf);
|
||||
p->blit.sf = NULL;
|
||||
|
||||
if (p->blit.own_buffer) {
|
||||
free(p->blit.buffer);
|
||||
}
|
||||
p->blit.buffer = NULL;
|
||||
}
|
||||
|
||||
size_t stride = width * 4;
|
||||
size_t size = stride * height;
|
||||
p->blit.width = width;
|
||||
p->blit.height = height;
|
||||
p->blit.stride = stride;
|
||||
p->blit.own_buffer = true;
|
||||
|
||||
p->blit.buffer = malloc(size);
|
||||
p->blit.sf =
|
||||
SDL_CreateRGBSurfaceFrom(p->blit.buffer, width, height, 32, stride,
|
||||
0x0000FF, 0x00FF00, 0xFF0000, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
sdl2_handle_keydown(struct program *p, const SDL_Event *e)
|
||||
{
|
||||
switch (e->key.keysym.sym) {
|
||||
case SDLK_ESCAPE: p->stopped = true; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* "Exported" functions.
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
gui_sdl2_display_R8G8B8(struct program *p,
|
||||
bool resize,
|
||||
uint32_t width,
|
||||
uint32_t height,
|
||||
size_t stride,
|
||||
void *data)
|
||||
{
|
||||
if (p->blit.buffer != data || p->blit.width != width ||
|
||||
p->blit.height != height || p->blit.sf == NULL) {
|
||||
|
||||
if (resize) {
|
||||
SDL_SetWindowSize(p->win, width, height);
|
||||
}
|
||||
|
||||
p->blit.sf =
|
||||
SDL_CreateRGBSurfaceFrom(data, width, height, 24, stride,
|
||||
0x0000FF, 0x00FF00, 0xFF0000, 0);
|
||||
|
||||
p->blit.width = width;
|
||||
p->blit.height = height;
|
||||
p->blit.stride = stride;
|
||||
p->blit.buffer = data;
|
||||
p->blit.own_buffer = false;
|
||||
}
|
||||
|
||||
SDL_Surface *win_sf = SDL_GetWindowSurface(p->win);
|
||||
|
||||
if (SDL_BlitSurface(p->blit.sf, NULL, win_sf, NULL) == 0) {
|
||||
SDL_UpdateWindowSurface(p->win);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
gui_sdl2_loop(struct program *p)
|
||||
{
|
||||
SDL_Event event;
|
||||
while (!p->stopped) {
|
||||
if (SDL_WaitEvent(&event) == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.type == SDL_QUIT) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.type == SDL_KEYDOWN) {
|
||||
sdl2_handle_keydown(p, &event);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int
|
||||
gui_sdl2_init(struct program *p)
|
||||
{
|
||||
if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *title = "Monado! ☺";
|
||||
int x = SDL_WINDOWPOS_UNDEFINED;
|
||||
int y = SDL_WINDOWPOS_UNDEFINED;
|
||||
int w = 1920;
|
||||
int h = 1080;
|
||||
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK,
|
||||
SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
||||
|
||||
SDL_WindowFlags window_flags = 0;
|
||||
window_flags |= SDL_WINDOW_SHOWN;
|
||||
window_flags |= SDL_WINDOW_OPENGL;
|
||||
window_flags |= SDL_WINDOW_RESIZABLE;
|
||||
window_flags |= SDL_WINDOW_ALLOW_HIGHDPI;
|
||||
#if 0
|
||||
window_flags |= SDL_WINDOW_MAXIMIZED;
|
||||
#endif
|
||||
|
||||
p->initialized = true;
|
||||
p->win = SDL_CreateWindow(title, x, y, w, h, window_flags);
|
||||
|
||||
if (p->win == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
p->ctx = SDL_GL_CreateContext(p->win);
|
||||
if (p->ctx == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_GL_MakeCurrent(p->win, p->ctx);
|
||||
SDL_GL_SetSwapInterval(1); // Enable vsync
|
||||
|
||||
// Setup OpenGL bindings.
|
||||
bool err = gladLoadGL((GLADloadfunc)SDL_GL_GetProcAddress) == 0;
|
||||
if (err) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
gui_sdl2_quit(struct program *p)
|
||||
{
|
||||
if (!p->initialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (p->blit.sf != NULL) {
|
||||
SDL_FreeSurface(p->blit.sf);
|
||||
p->blit.sf = NULL;
|
||||
|
||||
if (p->blit.own_buffer) {
|
||||
free(p->blit.buffer);
|
||||
}
|
||||
p->blit.buffer = NULL;
|
||||
}
|
||||
|
||||
if (p->ctx != NULL) {
|
||||
SDL_GL_DeleteContext(p->ctx);
|
||||
p->ctx = NULL;
|
||||
}
|
||||
|
||||
if (p->win != NULL) {
|
||||
SDL_DestroyWindow(p->win);
|
||||
p->win = NULL;
|
||||
}
|
||||
|
||||
SDL_Quit();
|
||||
p->initialized = false;
|
||||
}
|
Loading…
Reference in a new issue