mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-07-22 20:59:19 +02:00
extcam camera preview
This commit is contained in:
@@ -29,7 +29,8 @@ file(GLOB HEADERS "*.h"
|
|||||||
"network/*.h"
|
"network/*.h"
|
||||||
"network/backend/*.h"
|
"network/backend/*.h"
|
||||||
"widgets/*.h"
|
"widgets/*.h"
|
||||||
"launcher/*.h")
|
"launcher/*.h"
|
||||||
|
"extras/*.h")
|
||||||
|
|
||||||
if (APPLE)
|
if (APPLE)
|
||||||
set (CMAKE_EXE_LINKER_FLAGS "-pagezero_size 10000 -image_base 100000000")
|
set (CMAKE_EXE_LINKER_FLAGS "-pagezero_size 10000 -image_base 100000000")
|
||||||
@@ -37,6 +38,7 @@ endif()
|
|||||||
|
|
||||||
option(USE_IMGUI_GL3 "Use OpenGL3+ imgui implementation" ON)
|
option(USE_IMGUI_GL3 "Use OpenGL3+ imgui implementation" ON)
|
||||||
option(WITH_UART "Compile with libserialport" ON)
|
option(WITH_UART "Compile with libserialport" ON)
|
||||||
|
option(USE_VSDEV_CAMERA "Use VS_Dev camera preview implementation" OFF)
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
"Texture.cpp"
|
"Texture.cpp"
|
||||||
@@ -140,7 +142,6 @@ set(SOURCES
|
|||||||
"widgets/vehicleparams.cpp"
|
"widgets/vehicleparams.cpp"
|
||||||
"widgets/trainingcard.cpp"
|
"widgets/trainingcard.cpp"
|
||||||
"widgets/perfgraphs.cpp"
|
"widgets/perfgraphs.cpp"
|
||||||
"widgets/cameraview.cpp"
|
|
||||||
|
|
||||||
"ref/glad/src/glad.c"
|
"ref/glad/src/glad.c"
|
||||||
|
|
||||||
@@ -163,7 +164,6 @@ set(SOURCES
|
|||||||
"imgui/imgui_impl_glfw.cpp"
|
"imgui/imgui_impl_glfw.cpp"
|
||||||
|
|
||||||
"stb/stb_image.c"
|
"stb/stb_image.c"
|
||||||
"extras/VS_Dev.cpp"
|
|
||||||
|
|
||||||
"launcher/launchermode.cpp"
|
"launcher/launchermode.cpp"
|
||||||
"launcher/scenery_list.cpp"
|
"launcher/scenery_list.cpp"
|
||||||
@@ -186,6 +186,14 @@ if (WITH_UART)
|
|||||||
set(SOURCES ${SOURCES} "uart.cpp")
|
set(SOURCES ${SOURCES} "uart.cpp")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (USE_VSDEV_CAMERA)
|
||||||
|
add_definitions(-DUSE_VSDEV_CAMERA)
|
||||||
|
set(SOURCES ${SOURCES} "extras/VS_Dev.cpp" "widgets/cameraview_vsdev.cpp")
|
||||||
|
else()
|
||||||
|
add_definitions(-DUSE_EXTCAM_CAMERA)
|
||||||
|
set(SOURCES ${SOURCES} "extras/piped_proc.cpp" "widgets/cameraview_extcam.cpp")
|
||||||
|
endif()
|
||||||
|
|
||||||
set (PREFIX "")
|
set (PREFIX "")
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
|
|||||||
10
Globals.cpp
10
Globals.cpp
@@ -702,6 +702,16 @@ global_settings::ConfigParse(cParser &Parser) {
|
|||||||
Parser.getTokens( 1 );
|
Parser.getTokens( 1 );
|
||||||
Parser >> uart_conf.debug;
|
Parser >> uart_conf.debug;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef USE_EXTCAM_CAMERA
|
||||||
|
else if( token == "extcam.cmd" ) {
|
||||||
|
Parser.getTokens( 1 );
|
||||||
|
Parser >> extcam_cmd;
|
||||||
|
}
|
||||||
|
else if( token == "extcam.res" ) {
|
||||||
|
Parser.getTokens( 2 );
|
||||||
|
Parser >> extcam_res.x >> extcam_res.y;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
else if (token == "loadinglog") {
|
else if (token == "loadinglog") {
|
||||||
Parser.getTokens( 1 );
|
Parser.getTokens( 1 );
|
||||||
|
|||||||
@@ -187,6 +187,11 @@ struct global_settings {
|
|||||||
bool captureonstart = true;
|
bool captureonstart = true;
|
||||||
bool render_cab = true;
|
bool render_cab = true;
|
||||||
|
|
||||||
|
#ifdef USE_EXTCAM_CAMERA
|
||||||
|
std::string extcam_cmd;
|
||||||
|
glm::ivec2 extcam_res{800, 600};
|
||||||
|
#endif
|
||||||
|
|
||||||
std::chrono::duration<float> minframetime {0.0f};
|
std::chrono::duration<float> minframetime {0.0f};
|
||||||
|
|
||||||
std::string fullscreen_monitor;
|
std::string fullscreen_monitor;
|
||||||
|
|||||||
@@ -18,8 +18,12 @@ http://mozilla.org/MPL/2.0/.
|
|||||||
#include "widgets/map.h"
|
#include "widgets/map.h"
|
||||||
#include "widgets/time.h"
|
#include "widgets/time.h"
|
||||||
#include "widgets/trainingcard.h"
|
#include "widgets/trainingcard.h"
|
||||||
#include "widgets/cameraview.h"
|
|
||||||
#include "widgets/perfgraphs.h"
|
#include "widgets/perfgraphs.h"
|
||||||
|
#ifdef USE_EXTCAM_CAMERA
|
||||||
|
#include "widgets/cameraview_extcam.h"
|
||||||
|
#elif USE_VSDEV_CAMERA
|
||||||
|
#include "widgets/cameraview_vsdev.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
class driver_ui : public ui_layer {
|
class driver_ui : public ui_layer {
|
||||||
|
|
||||||
|
|||||||
87
extras/piped_proc.cpp
Normal file
87
extras/piped_proc.cpp
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "piped_proc.h"
|
||||||
|
#include "Logs.h"
|
||||||
|
|
||||||
|
#ifdef __unix__
|
||||||
|
piped_proc::piped_proc(std::string cmd)
|
||||||
|
{
|
||||||
|
file = popen(cmd.c_str(), "r");
|
||||||
|
}
|
||||||
|
|
||||||
|
piped_proc::~piped_proc()
|
||||||
|
{
|
||||||
|
if (file)
|
||||||
|
pclose(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t piped_proc::read(unsigned char *buf, size_t len)
|
||||||
|
{
|
||||||
|
if (!file)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return fread(buf, 1, len, file);
|
||||||
|
}
|
||||||
|
#elif _WIN32
|
||||||
|
piped_proc::piped_proc(std::string cmd)
|
||||||
|
{
|
||||||
|
PROCESS_INFORMATION process;
|
||||||
|
STARTUPINFO siStartInfo;
|
||||||
|
SECURITY_ATTRIBUTES saAttr;
|
||||||
|
|
||||||
|
memset(&process, 0, sizeof(PROCESS_INFORMATION));
|
||||||
|
memset(&siStartInfo, 0, sizeof(STARTUPINFO));
|
||||||
|
memset(&saAttr, 0, sizeof(SECURITY_ATTRIBUTES));
|
||||||
|
|
||||||
|
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||||
|
saAttr.bInheritHandle = TRUE;
|
||||||
|
saAttr.lpSecurityDescriptor = NULL;
|
||||||
|
|
||||||
|
if (!CreatePipe(&pipe_rd, &pipe_wr, &saAttr, 0)) {
|
||||||
|
ErrorLog("piped_proc: CreatePipe failed!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SetHandleInformation(pipe_rd, HANDLE_FLAG_INHERIT, 0)) {
|
||||||
|
ErrorLog("piped_proc: SetHandleInformation failed!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
siStartInfo.cb = sizeof(STARTUPINFO);
|
||||||
|
siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
|
||||||
|
siStartInfo.hStdOutput = pipe_wr;
|
||||||
|
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
|
||||||
|
|
||||||
|
if (!CreateProcessA(NULL, (char*)cmd.c_str(), NULL, NULL, TRUE, 0, NULL, NULL, &siStartInfo, &process)) {
|
||||||
|
ErrorLog("piped_proc: CreateProcess failed!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.hProcess)
|
||||||
|
CloseHandle(process.hProcess);
|
||||||
|
if (process.hThread)
|
||||||
|
CloseHandle(process.hThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
piped_proc::~piped_proc()
|
||||||
|
{
|
||||||
|
if (pipe_wr)
|
||||||
|
CloseHandle(pipe_wr);
|
||||||
|
if (pipe_rd)
|
||||||
|
CloseHandle(pipe_rd);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t piped_proc::read(unsigned char *buf, size_t len)
|
||||||
|
{
|
||||||
|
if (!pipe_rd)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
DWORD read = 0;
|
||||||
|
BOOL ret = ReadFile(pipe_rd, buf, len, &read, NULL);
|
||||||
|
|
||||||
|
return read;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
28
extras/piped_proc.h
Normal file
28
extras/piped_proc.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __unix__
|
||||||
|
#include <cstdio>
|
||||||
|
#elif _WIN32
|
||||||
|
#include "winheaders.h"
|
||||||
|
#endif
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class piped_proc
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
#ifdef __unix__
|
||||||
|
FILE *file = nullptr;
|
||||||
|
#elif _WIN32
|
||||||
|
HANDLE pipe_rd = nullptr;
|
||||||
|
HANDLE pipe_wr = nullptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
public:
|
||||||
|
piped_proc(std::string cmd);
|
||||||
|
size_t read(unsigned char *buf, size_t len);
|
||||||
|
~piped_proc();
|
||||||
|
};
|
||||||
105
widgets/cameraview_extcam.cpp
Normal file
105
widgets/cameraview_extcam.cpp
Normal file
@@ -0,0 +1,105 @@
|
|||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "widgets/cameraview_extcam.h"
|
||||||
|
#include "stb/stb_image.h"
|
||||||
|
#include "Globals.h"
|
||||||
|
#include "Logs.h"
|
||||||
|
#include "extras/piped_proc.h"
|
||||||
|
|
||||||
|
ui::cameraview_panel::cameraview_panel()
|
||||||
|
: ui_panel(STR_C("Camera preview"), false)
|
||||||
|
{
|
||||||
|
size_min = { -2, -2 };
|
||||||
|
}
|
||||||
|
|
||||||
|
void cameraview_window_callback(ImGuiSizeCallbackData *data) {
|
||||||
|
data->DesiredSize.y = data->DesiredSize.x * (float)Global.extcam_res.y / (float)Global.extcam_res.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
ui::cameraview_panel::~cameraview_panel() {
|
||||||
|
exit_thread = true;
|
||||||
|
if (workthread.joinable())
|
||||||
|
workthread.detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui::cameraview_panel::render()
|
||||||
|
{
|
||||||
|
if (!is_open)
|
||||||
|
exit_thread = true;
|
||||||
|
|
||||||
|
if (is_open)
|
||||||
|
ImGui::SetNextWindowSizeConstraints(ImVec2(200, 200), ImVec2(2500, 2500), cameraview_window_callback);
|
||||||
|
|
||||||
|
ui_panel::render();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui::cameraview_panel::render_contents()
|
||||||
|
{
|
||||||
|
if (exit_thread) {
|
||||||
|
if (workthread.joinable())
|
||||||
|
workthread.join();
|
||||||
|
exit_thread = false;
|
||||||
|
if (!Global.extcam_cmd.empty())
|
||||||
|
workthread = std::thread(&cameraview_panel::workthread_func, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!texture) {
|
||||||
|
texture.emplace();
|
||||||
|
texture->make_stub();
|
||||||
|
}
|
||||||
|
|
||||||
|
texture->bind(0);
|
||||||
|
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
if (image_ptr) {
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
|
glTexImage2D(
|
||||||
|
GL_TEXTURE_2D, 0,
|
||||||
|
GL_SRGB8_ALPHA8,
|
||||||
|
Global.extcam_res.x, Global.extcam_res.y, 0,
|
||||||
|
GL_RGB, GL_UNSIGNED_BYTE, image_ptr);
|
||||||
|
image_ptr = nullptr;
|
||||||
|
|
||||||
|
if (Global.python_mipmaps) {
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
|
||||||
|
glGenerateMipmap(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImVec2 surface_size = ImGui::GetContentRegionAvail();
|
||||||
|
ImGui::Image(reinterpret_cast<void*>(texture->id), surface_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ui::cameraview_panel::workthread_func()
|
||||||
|
{
|
||||||
|
piped_proc proc(Global.extcam_cmd);
|
||||||
|
|
||||||
|
size_t frame_size = Global.extcam_res.x * Global.extcam_res.y * 3;
|
||||||
|
uint8_t *read_buffer = new uint8_t[frame_size];
|
||||||
|
uint8_t *active_buffer = new uint8_t[frame_size];
|
||||||
|
|
||||||
|
while (!exit_thread) {
|
||||||
|
if (proc.read(read_buffer, frame_size) != frame_size)
|
||||||
|
break;
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
image_ptr = read_buffer;
|
||||||
|
read_buffer = active_buffer;
|
||||||
|
active_buffer = image_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
image_ptr = nullptr;
|
||||||
|
delete[] read_buffer;
|
||||||
|
delete[] active_buffer;
|
||||||
|
}
|
||||||
31
widgets/cameraview_extcam.h
Normal file
31
widgets/cameraview_extcam.h
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "uilayer.h"
|
||||||
|
|
||||||
|
namespace ui
|
||||||
|
{
|
||||||
|
class cameraview_panel : public ui_panel
|
||||||
|
{
|
||||||
|
std::atomic_bool exit_thread = true;
|
||||||
|
std::thread workthread;
|
||||||
|
|
||||||
|
uint8_t* image_ptr = nullptr;
|
||||||
|
std::mutex mutex;
|
||||||
|
|
||||||
|
std::optional<opengl_texture> texture;
|
||||||
|
|
||||||
|
void workthread_func();
|
||||||
|
|
||||||
|
public:
|
||||||
|
cameraview_panel();
|
||||||
|
~cameraview_panel();
|
||||||
|
|
||||||
|
void render() override;
|
||||||
|
void render_contents() override;
|
||||||
|
};
|
||||||
|
} // namespace ui
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "widgets/cameraview.h"
|
#include "widgets/cameraview_vsdev.h"
|
||||||
#include "stb/stb_image.h"
|
#include "stb/stb_image.h"
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "Logs.h"
|
#include "Logs.h"
|
||||||
Reference in New Issue
Block a user