From 317af2e5ba97c0921b35bbebbe053a54c7718d96 Mon Sep 17 00:00:00 2001 From: milek7 Date: Tue, 9 Apr 2019 00:58:36 +0200 Subject: [PATCH] cameraview --- stb/stb_image.c | 1 - stb/stb_image.h | 3 ++ widgets/cameraview.cpp | 80 +++++++++++++++++++++++++++++++++++++++--- widgets/cameraview.h | 8 +++++ 4 files changed, 87 insertions(+), 5 deletions(-) diff --git a/stb/stb_image.c b/stb/stb_image.c index 7064419d..38c72e92 100644 --- a/stb/stb_image.c +++ b/stb/stb_image.c @@ -1,3 +1,2 @@ #define STB_IMAGE_IMPLEMENTATION -#define STBI_ONLY_JPEG #include "stb/stb_image.h" diff --git a/stb/stb_image.h b/stb/stb_image.h index a6202a31..106e1927 100644 --- a/stb/stb_image.h +++ b/stb/stb_image.h @@ -110,6 +110,9 @@ RECENT REVISION HISTORY: #ifndef STBI_INCLUDE_STB_IMAGE_H #define STBI_INCLUDE_STB_IMAGE_H +#define STBI_ONLY_JPEG +#define STBI_NO_STDIO + // DOCUMENTATION // // Limitations: diff --git a/widgets/cameraview.cpp b/widgets/cameraview.cpp index 77ba62ce..e19b10a5 100644 --- a/widgets/cameraview.cpp +++ b/widgets/cameraview.cpp @@ -1,15 +1,27 @@ #include "widgets/cameraview.h" +#include "extras/VS_Dev.h" +#include "stb/stb_image.h" +#include "Globals.h" +#include "Logs.h" ui::cameraview_panel::cameraview_panel() : ui_panel(LOC_STR(cameraview_window), false) { - + size_min = {200, 200}; + size_max = {2000, 2000}; } void ui::cameraview_panel::render() { - if (!is_open && !exit_thread) + if (!is_open && !exit_thread) { exit_thread = true; + { + std::lock_guard lock(mutex); + stbi_image_free(image_ptr); + image_ptr = nullptr; + } + cv.notify_all(); + } ui_panel::render(); } @@ -21,10 +33,70 @@ void ui::cameraview_panel::render_contents() workthread = std::thread(&cameraview_panel::workthread_func, this); exit_thread = false; } + + if (!texture) { + texture.emplace(); + texture->make_stub(); + } + + texture->bind(0); + + { + std::lock_guard lock(mutex); + if (image_ptr) { + + glActiveTexture(GL_TEXTURE0); + + glTexImage2D( + GL_TEXTURE_2D, 0, + GL_SRGB8_ALPHA8, + image_w, image_h, 0, + GL_RGBA, GL_UNSIGNED_BYTE, image_ptr); + + stbi_image_free(image_ptr); + + 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); + } + + image_ptr = nullptr; + } + } + cv.notify_all(); + + ImVec2 surface_size = ImGui::GetContentRegionAvail(); + ImGui::Image(reinterpret_cast(texture->id), surface_size); } void ui::cameraview_panel::workthread_func() { - while (!exit_thread); - std::this_thread::sleep_for(std::chrono::seconds(1)); + VSDev vsdev; + + while (!exit_thread) { + uint8_t *buffer = nullptr; + size_t len = vsdev.GetFrameFromStream((char**)&buffer); + + if (buffer) { + int w, h; + uint8_t *image = stbi_load_from_memory(buffer, len, &w, &h, nullptr, 4); + if (!image) + ErrorLog(std::string(stbi_failure_reason())); + + vsdev.FreeFrameBuffer((char*)buffer); + + std::unique_lock lock(mutex); + if (image_ptr) + cv.wait(lock, [this]{return !image_ptr;}); + + image_w = w; + image_h = h; + image_ptr = image; + } + else + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + } } diff --git a/widgets/cameraview.h b/widgets/cameraview.h index 899542b9..e1cdbe6e 100644 --- a/widgets/cameraview.h +++ b/widgets/cameraview.h @@ -9,6 +9,14 @@ class cameraview_panel : public ui_panel std::atomic_bool exit_thread = true; std::thread workthread; + uint8_t* image_ptr = nullptr; + int image_w, image_h; + + std::mutex mutex; + std::condition_variable cv; + + std::optional texture; + void workthread_func(); public: