mirror of
https://github.com/MaSzyna-EU07/maszyna.git
synced 2026-03-22 15:05:03 +01:00
extcam camera preview
This commit is contained in:
@@ -29,7 +29,8 @@ file(GLOB HEADERS "*.h"
|
||||
"network/*.h"
|
||||
"network/backend/*.h"
|
||||
"widgets/*.h"
|
||||
"launcher/*.h")
|
||||
"launcher/*.h"
|
||||
"extras/*.h")
|
||||
|
||||
if (APPLE)
|
||||
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(WITH_UART "Compile with libserialport" ON)
|
||||
option(USE_VSDEV_CAMERA "Use VS_Dev camera preview implementation" OFF)
|
||||
|
||||
set(SOURCES
|
||||
"Texture.cpp"
|
||||
@@ -140,7 +142,6 @@ set(SOURCES
|
||||
"widgets/vehicleparams.cpp"
|
||||
"widgets/trainingcard.cpp"
|
||||
"widgets/perfgraphs.cpp"
|
||||
"widgets/cameraview.cpp"
|
||||
|
||||
"ref/glad/src/glad.c"
|
||||
|
||||
@@ -163,7 +164,6 @@ set(SOURCES
|
||||
"imgui/imgui_impl_glfw.cpp"
|
||||
|
||||
"stb/stb_image.c"
|
||||
"extras/VS_Dev.cpp"
|
||||
|
||||
"launcher/launchermode.cpp"
|
||||
"launcher/scenery_list.cpp"
|
||||
@@ -186,6 +186,14 @@ if (WITH_UART)
|
||||
set(SOURCES ${SOURCES} "uart.cpp")
|
||||
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 "")
|
||||
|
||||
if (WIN32)
|
||||
|
||||
10
Globals.cpp
10
Globals.cpp
@@ -702,6 +702,16 @@ global_settings::ConfigParse(cParser &Parser) {
|
||||
Parser.getTokens( 1 );
|
||||
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
|
||||
else if (token == "loadinglog") {
|
||||
Parser.getTokens( 1 );
|
||||
|
||||
@@ -187,6 +187,11 @@ struct global_settings {
|
||||
bool captureonstart = 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::string fullscreen_monitor;
|
||||
|
||||
@@ -18,8 +18,12 @@ http://mozilla.org/MPL/2.0/.
|
||||
#include "widgets/map.h"
|
||||
#include "widgets/time.h"
|
||||
#include "widgets/trainingcard.h"
|
||||
#include "widgets/cameraview.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 {
|
||||
|
||||
|
||||
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 "widgets/cameraview.h"
|
||||
#include "widgets/cameraview_vsdev.h"
|
||||
#include "stb/stb_image.h"
|
||||
#include "Globals.h"
|
||||
#include "Logs.h"
|
||||
Reference in New Issue
Block a user