From 2364d1a4f250f40496570646658d239edb361a1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20C=2E=20Guimaraes?= Date: Wed, 8 Oct 2025 13:32:56 -0300 Subject: [PATCH 01/11] Updated dependencies. Fixed Cmake and vcpkg dependencies. --- .gitignore | 2 +- CMakeLists.txt | 10 +++++++++- libs/BasicToolsLib | 2 +- libs/ImageProcessingToolsLib | 2 +- vcpkg.json | 6 ++++++ 5 files changed, 18 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index d7716a4..e024c33 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ build/* -EyeRendererOld/build/Desktop_Qt_6_7_0-Debug +out/* CMakeLists.txt.user diff --git a/CMakeLists.txt b/CMakeLists.txt index 2c069d6..29589f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,10 +16,13 @@ set(CMAKE_CXX_EXTENSIONS ON) set(OpenCV_STATIC ON) find_package( OpenCV REQUIRED ) - find_package( Eigen3 REQUIRED ) find_package( Iconv REQUIRED ) +if (WIN32) + find_package(glm CONFIG REQUIRED) +endif() + add_subdirectory(libs) include_directories( ${OpenCV_INCLUDE_DIRS} ) @@ -95,6 +98,11 @@ target_link_libraries(${PROJECT_NAME} PRIVATE Iconv::Iconv ${PROJ_LINK_LIBS}) +if (WIN32) + target_link_libraries(${PROJECT_NAME} PRIVATE glm::glm) +endif() + + file(COPY "${CMAKE_SOURCE_DIR}/data" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) add_custom_target(Other SOURCES diff --git a/libs/BasicToolsLib b/libs/BasicToolsLib index 676501e..aeecdd1 160000 --- a/libs/BasicToolsLib +++ b/libs/BasicToolsLib @@ -1 +1 @@ -Subproject commit 676501e1d42d842412e83f90cfa9ced2d1902683 +Subproject commit aeecdd1c26ed9511d6a6cd2bcb576877180d4762 diff --git a/libs/ImageProcessingToolsLib b/libs/ImageProcessingToolsLib index 8281080..4bb6ad5 160000 --- a/libs/ImageProcessingToolsLib +++ b/libs/ImageProcessingToolsLib @@ -1 +1 @@ -Subproject commit 828108002cb02b4d52a76e89932689ec18407995 +Subproject commit 4bb6ad55d13806d5797f9e3d2b2736dd40f5adab diff --git a/vcpkg.json b/vcpkg.json index d11a037..7c0c197 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -8,6 +8,12 @@ "glm", "libiconv" ], + "overrides": [ + { + "name": "eigen3", + "version": "3.4.0" + } + ], "builtin-baseline" : "4334d8b4c8916018600212ab4dd4bbdc343065d1" } From fe32ffd02d13eadbbc9286d043ade1c3e943f8c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20C=2E=20Guimaraes?= Date: Wed, 8 Oct 2025 14:41:07 -0300 Subject: [PATCH 02/11] Added missing defines. Removed LinuxScreenCapturer from Windows build. --- src/Eye3dModel.cpp | 5 +++++ src/{ => linux}/LinuxScreenCapturer.cpp | 0 src/{ => linux}/LinuxScreenCapturer.h | 0 3 files changed, 5 insertions(+) rename src/{ => linux}/LinuxScreenCapturer.cpp (100%) rename src/{ => linux}/LinuxScreenCapturer.h (100%) diff --git a/src/Eye3dModel.cpp b/src/Eye3dModel.cpp index 5fc27b9..4690fc0 100644 --- a/src/Eye3dModel.cpp +++ b/src/Eye3dModel.cpp @@ -6,6 +6,11 @@ #include "objects/GlRenderSphereArc.h" #include "objects/GlRenderSpherePolar.h" +#ifndef M_PI +#define M_PI 3.141592 +#endif + + namespace { const float upperLidOpenAngle = 0.75f; diff --git a/src/LinuxScreenCapturer.cpp b/src/linux/LinuxScreenCapturer.cpp similarity index 100% rename from src/LinuxScreenCapturer.cpp rename to src/linux/LinuxScreenCapturer.cpp diff --git a/src/LinuxScreenCapturer.h b/src/linux/LinuxScreenCapturer.h similarity index 100% rename from src/LinuxScreenCapturer.h rename to src/linux/LinuxScreenCapturer.h From 629b6046f49547e536cc597f9221e971eb34c3c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20C=2E=20Guimaraes?= Date: Wed, 8 Oct 2025 14:43:33 -0300 Subject: [PATCH 03/11] Updated RenderLib. Fixed Cmake to handle platform specific code. --- CMakeLists.txt | 24 ++++++++++++++++-------- libs/RenderLib | 2 +- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 29589f4..5303183 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,6 +57,8 @@ set(PROJ_SRC) # Add all files/folders under src folder automatically to the project file(GLOB_RECURSE PROJ_SRC src/*.h src/*.cpp) +file(GLOB_RECURSE srcLinux src/linux/*.h src/linux/*.cpp) +file(GLOB_RECURSE srcWindows src/windows/*.h src/windows/*.cpp) ### ### Compiler settings @@ -83,14 +85,16 @@ endif(KITGL_SUPPORT_GLFW) list(APPEND PROJ_LINK_LIBS Xinerama) -### -### Generating the project files -### -add_executable(${PROJECT_NAME} ${PROJ_SRC}) +add_executable(${PROJECT_NAME}) + +target_sources(${PROJECT_NAME} PRIVATE ${PROJ_SRC}) +if (WIN32) + target_sources(${PROJECT_NAME} PRIVATE ${srcWindows}) +elseif(UNIX) + target_sources(${PROJECT_NAME} PRIVATE ${srcLinux}) +endif() + -### -### Linking to the project -### target_link_libraries(${PROJECT_NAME} PRIVATE RenderLib ImageProcessingToolsLib @@ -99,7 +103,11 @@ target_link_libraries(${PROJECT_NAME} PRIVATE ${PROJ_LINK_LIBS}) if (WIN32) - target_link_libraries(${PROJECT_NAME} PRIVATE glm::glm) + target_link_libraries(${PROJECT_NAME} PRIVATE glm::glm-header-only) + + get_target_property(GLM_INCLUDE_DIR glm::glm-header-only INTERFACE_INCLUDE_DIRECTORIES) + message(STATUS "GLM include dir: ${GLM_INCLUDE_DIR}") + target_include_directories(${PROJECT_NAME} PRIVATE ${GLM_INCLUDE_DIR}) endif() diff --git a/libs/RenderLib b/libs/RenderLib index a3cda51..4aecb73 160000 --- a/libs/RenderLib +++ b/libs/RenderLib @@ -1 +1 @@ -Subproject commit a3cda516b61f8b2f6978ad3057c93bd7b69f6776 +Subproject commit 4aecb73e4b2a84c5c64da584639ab9a245c94d24 From 63f117f7fa1b42a30face38ff4932f1ca30b8428 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20C=2E=20Guimaraes?= Date: Wed, 8 Oct 2025 15:45:43 -0300 Subject: [PATCH 04/11] Refactored Screen capturers. Added dummy Windows screen capturer. --- CMakeLists.txt | 8 +++++-- src/AbstractScreenCapturer.h | 16 ++++++++++++++ src/MonitorPosition.cpp | 12 +++++++++++ src/MonitorPosition.h | 28 ++++++++++++++++++++++++ src/linux/LinuxScreenCapturer.cpp | 11 ---------- src/linux/LinuxScreenCapturer.h | 31 ++++++--------------------- src/main.cpp | 22 ++++++++++++++++--- src/windows/WindowsScreenCapturer.cpp | 24 +++++++++++++++++++++ src/windows/WindowsScreenCapturer.h | 15 +++++++++++++ 9 files changed, 126 insertions(+), 41 deletions(-) create mode 100644 src/AbstractScreenCapturer.h create mode 100644 src/MonitorPosition.cpp create mode 100644 src/MonitorPosition.h create mode 100644 src/windows/WindowsScreenCapturer.cpp create mode 100644 src/windows/WindowsScreenCapturer.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 5303183..c45c5a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,7 +56,7 @@ set(PROJ_LINK_LIBS) set(PROJ_SRC) # Add all files/folders under src folder automatically to the project -file(GLOB_RECURSE PROJ_SRC src/*.h src/*.cpp) +file(GLOB PROJ_SRC src/*.h src/*.cpp) file(GLOB_RECURSE srcLinux src/linux/*.h src/linux/*.cpp) file(GLOB_RECURSE srcWindows src/windows/*.h src/windows/*.cpp) @@ -83,14 +83,18 @@ if(KITGL_SUPPORT_GLFW) list(APPEND PROJ_LINK_LIBS glfw) endif(KITGL_SUPPORT_GLFW) -list(APPEND PROJ_LINK_LIBS Xinerama) +if(UNIX) + list(APPEND PROJ_LINK_LIBS Xinerama) +endif() add_executable(${PROJECT_NAME}) target_sources(${PROJECT_NAME} PRIVATE ${PROJ_SRC}) if (WIN32) + message(STATUS "Adding Windows sources") target_sources(${PROJECT_NAME} PRIVATE ${srcWindows}) elseif(UNIX) + message(STATUS "Adding Linux sources") target_sources(${PROJECT_NAME} PRIVATE ${srcLinux}) endif() diff --git a/src/AbstractScreenCapturer.h b/src/AbstractScreenCapturer.h new file mode 100644 index 0000000..cff9a75 --- /dev/null +++ b/src/AbstractScreenCapturer.h @@ -0,0 +1,16 @@ +#ifndef AbstractScreenCapturer_H +#define AbstractScreenCapturer_H + +#include + +#include "ImageData.h" +#include "MonitorPosition.h" + +class AbstractScreenCapturer +{ +public: + virtual ~AbstractScreenCapturer() = default; + virtual std::unordered_map Capture() = 0; +}; + +#endif diff --git a/src/MonitorPosition.cpp b/src/MonitorPosition.cpp new file mode 100644 index 0000000..fe65bf4 --- /dev/null +++ b/src/MonitorPosition.cpp @@ -0,0 +1,12 @@ +#include "MonitorPosition.h" + +MonitorPosition::MonitorPosition() + : xOrigin(0), yOrigin(0) +{ +} + +bool MonitorPosition::operator==(const MonitorPosition other) const +{ + return xOrigin == other.xOrigin && yOrigin == other.yOrigin; +} + diff --git a/src/MonitorPosition.h b/src/MonitorPosition.h new file mode 100644 index 0000000..661c1bb --- /dev/null +++ b/src/MonitorPosition.h @@ -0,0 +1,28 @@ +#ifndef MonitorPosition_H +#define MonitorPosition_H + +#include + +struct MonitorPosition +{ + MonitorPosition(); + + bool operator==(const MonitorPosition other) const; + + int xOrigin; + int yOrigin; + +}; + +namespace std { + template <> + struct hash { + size_t operator()(const MonitorPosition& key) const { + size_t h1 = std::hash()(key.xOrigin); + size_t h2 = std::hash()(key.yOrigin); + return h1 ^ (h2 << 1); + } + }; +} + +#endif diff --git a/src/linux/LinuxScreenCapturer.cpp b/src/linux/LinuxScreenCapturer.cpp index 062b6cb..17a610c 100644 --- a/src/linux/LinuxScreenCapturer.cpp +++ b/src/linux/LinuxScreenCapturer.cpp @@ -65,17 +65,6 @@ namespace } } -MonitorPosition::MonitorPosition() -: xOrigin(0), yOrigin(0) -{ -} - -bool MonitorPosition::operator==(const MonitorPosition other) const -{ - return xOrigin == other.xOrigin && yOrigin == other.yOrigin; -} - - std::unordered_map LinuxScreenCapturer::Capture() { std::unordered_map screenshots; diff --git a/src/linux/LinuxScreenCapturer.h b/src/linux/LinuxScreenCapturer.h index 5b6857c..3bc5cb3 100644 --- a/src/linux/LinuxScreenCapturer.h +++ b/src/linux/LinuxScreenCapturer.h @@ -1,38 +1,19 @@ #ifndef LINUXSCREENCAPTURER_H #define LINUXSCREENCAPTURER_H -#include "ImageData.h" - #include -struct MonitorPosition -{ - MonitorPosition(); - - bool operator==(const MonitorPosition other) const; - - int xOrigin; - int yOrigin; - -}; - -namespace std { -template <> -struct hash { - size_t operator()(const MonitorPosition& key) const { - size_t h1 = std::hash()(key.xOrigin); - size_t h2 = std::hash()(key.yOrigin); - return h1 ^ (h2 << 1); - } -}; -} +#include "AbstractScreenCapturer.h" +#include "ImageData.h" +#include "MonitorPosition.h" -class LinuxScreenCapturer +class LinuxScreenCapturer : public AbstractScreenCapturer { public: LinuxScreenCapturer() = default; + virtual ~LinuxScreenCapturer() = default; - virtual std::unordered_map Capture(); + std::unordered_map Capture() override; }; #endif // LINUXSCREENCAPTURER_H diff --git a/src/main.cpp b/src/main.cpp index db1ce81..8469dee 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -8,7 +8,13 @@ #include "Eye.h" #include "EyeFaceAnalyzer.h" -#include "LinuxScreenCapturer.h" +#include "MonitorPosition.h" + +#ifdef __linux + #include "linux/LinuxScreenCapturer.h" +#elif defined WIN32 + #include "windows/WindowsScreenCapturer.h" +#endif // TODO : Use a DEFINE for the data dir, and update Cmake accordingly. // For Linux, it should be /usr/share/the-eye. @@ -64,12 +70,21 @@ ImageData FindRightScreenshot(const std::unordered_mapsecond; } +AbstractScreenCapturer* CreateScreenCapturer() +{ +#ifdef __linux + return new LinuxScreenCapturer(); +#elif defined WIN32 + return new WindowsScreenCapturer(); +#endif +} + int main() { if (!glfwInit()) return -1; - LinuxScreenCapturer screenshotCapturer; - const std::unordered_map screenshots = screenshotCapturer.Capture(); + auto screenshotCapturer = CreateScreenCapturer(); + const std::unordered_map screenshots = screenshotCapturer->Capture(); GLFWmonitor* monitor = glfwGetPrimaryMonitor(); const GLFWvidmode* mode = glfwGetVideoMode(monitor); @@ -150,6 +165,7 @@ int main() // Clean up delete renderer; + delete screenshotCapturer; glfwTerminate(); return ok ? 0 : 1; } diff --git a/src/windows/WindowsScreenCapturer.cpp b/src/windows/WindowsScreenCapturer.cpp new file mode 100644 index 0000000..341625b --- /dev/null +++ b/src/windows/WindowsScreenCapturer.cpp @@ -0,0 +1,24 @@ +#include "WindowsScreenCapturer.h" + + +std::unordered_map WindowsScreenCapturer::Capture() +{ + std::unordered_map screenshots; + + // Hardcoded screen for now + MonitorPosition position; + position.xOrigin = 0; + position.yOrigin = 1; + + ImageData screenData; + screenData.width = 3960; + screenData.height = 2160; + screenData.channels = 3; + const size_t dataSize = screenData.width * screenData.height * screenData.channels; + screenData.data = new unsigned char[dataSize]; + screenshots[position] = screenData; + + memset(screenData.data, 0, dataSize * sizeof(unsigned char)); + + return screenshots; +} \ No newline at end of file diff --git a/src/windows/WindowsScreenCapturer.h b/src/windows/WindowsScreenCapturer.h new file mode 100644 index 0000000..49bf906 --- /dev/null +++ b/src/windows/WindowsScreenCapturer.h @@ -0,0 +1,15 @@ +#ifndef WindowsScreenCapturer_H +#define WindowsScreenCapturer_H + +#include "../AbstractScreenCapturer.h" + +#include +#include "../MonitorPosition.h" + +class WindowsScreenCapturer : public AbstractScreenCapturer +{ +public: + virtual ~WindowsScreenCapturer() = default; + std::unordered_map Capture() override; +}; +#endif From b80ed250aaf0b34b32196ca68ce594016f100e19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20C=2E=20Guimaraes?= Date: Sun, 19 Oct 2025 18:27:10 -0300 Subject: [PATCH 05/11] Optimized mutex lock to avoid inacessible lock. Optimized initialization to create display only after Face algorithm is initialized and working. --- src/EyeFaceAnalyzer.cpp | 3 +- src/main.cpp | 157 ++++++++++++++++++++++++---------------- 2 files changed, 95 insertions(+), 65 deletions(-) diff --git a/src/EyeFaceAnalyzer.cpp b/src/EyeFaceAnalyzer.cpp index 7fd7cc2..585194f 100644 --- a/src/EyeFaceAnalyzer.cpp +++ b/src/EyeFaceAnalyzer.cpp @@ -43,8 +43,9 @@ void EyeFaceAnalyzer::RunThreadedDetect() { while (keepRunning) { + std::optional newFacePosition = Detect(); faceMutex.lock(); - facePosition = Detect(); + facePosition = newFacePosition; faceMutex.unlock(); } } diff --git a/src/main.cpp b/src/main.cpp index 8469dee..26f31fc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -70,6 +70,11 @@ ImageData FindRightScreenshot(const std::unordered_mapsecond; } +void errorCallback(int error, const char* description) +{ + fprintf(stderr, "GLFW Error (%d): %s\n", error, description); +} + AbstractScreenCapturer* CreateScreenCapturer() { #ifdef __linux @@ -79,38 +84,50 @@ AbstractScreenCapturer* CreateScreenCapturer() #endif } -int main() +std::optional> InitializeGlDisplay() { - if (!glfwInit()) return -1; - - auto screenshotCapturer = CreateScreenCapturer(); - const std::unordered_map screenshots = screenshotCapturer->Capture(); - - GLFWmonitor* monitor = glfwGetPrimaryMonitor(); - const GLFWvidmode* mode = glfwGetVideoMode(monitor); - const int monitorWidth = mode->width; - const int monitorHeight = mode->height; - - GLFWwindow* window = glfwCreateWindow(monitorWidth, monitorHeight, "Eye Renderer", monitor, nullptr); - if (!window) - { - glfwTerminate(); - return -1; - } - - glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_FALSE); - glfwSetKeyCallback(window, keyPressCallback); - glfwSetMouseButtonCallback(window, mouseButtonCallback); - glfwSetCursorPosCallback(window, mouseMoveCallback); - glfwMakeContextCurrent(window); - - gladLoadGL(glfwGetProcAddress); + GLFWmonitor* monitor = nullptr; + GLFWwindow* window = nullptr; + + glfwSetErrorCallback(errorCallback); + if (!glfwInit()) + return std::nullopt; + + monitor = glfwGetPrimaryMonitor(); + const GLFWvidmode* mode = glfwGetVideoMode(monitor); + //const int monitorWidth = mode->width; + const int monitorWidth = 1980; + //const int monitorHeight = mode->height; + const int monitorHeight = 1080; + + window = glfwCreateWindow(monitorWidth, monitorHeight, "Eye Renderer", nullptr, nullptr); + if (!window) + return std::nullopt; + + glfwSetInputMode(window, GLFW_RAW_MOUSE_MOTION, GLFW_FALSE); + glfwSetKeyCallback(window, keyPressCallback); + glfwSetMouseButtonCallback(window, mouseButtonCallback); + glfwSetCursorPosCallback(window, mouseMoveCallback); + glfwMakeContextCurrent(window); + + gladLoadGL(glfwGetProcAddress); + glViewport(0, 0, monitorWidth, monitorHeight); + + return std::make_pair(monitor, window); +} - glViewport(0, 0, monitorWidth, monitorHeight); +GlRenderer* CreateInitializedRenderer() +{ + OrbitCamera camera(Vector3(0, 0, 0)); + auto renderer = new GlRenderer(&camera); + renderer->SetClearColor(0.0f, 0.0f, 0.0f); + return renderer; +} - OrbitCamera camera(Vector3(0, 0, 0)); - auto renderer = new GlRenderer(&camera); - renderer->SetClearColor(0.0f, 0.0f, 0.0f); +int main() +{ + auto screenshotCapturer = CreateScreenCapturer(); + const std::unordered_map screenshots = screenshotCapturer->Capture(); std::mutex faceMutex; std::optional facePosition; @@ -118,55 +135,67 @@ int main() EyeFaceAnalyzer faceAnalyzer(faceMutex, facePosition); const bool ok = faceAnalyzer.Initialize(); - if (ok) + if (!ok) { - faceAnalyzer.RunThreadedDetection(); - - Eye eye; - const ImageData rightScreen = FindRightScreenshot(screenshots, monitor); - eye.Initialize(renderer, rightScreen); - - float deltaT = 0.f; - - while (!glfwWindowShouldClose(window)) - { - const auto startIteration = std::chrono::steady_clock::now(); - glfwPollEvents(); - - std::optional* faceDataToUse = nullptr; - bool tookTheLock = false; - if (faceMutex.try_lock()) - { + std::cout << "Error initializing Face analyzer. Check if you have a working camera and if the data folder is accessible." << std::endl; + return 1; + } + faceAnalyzer.RunThreadedDetection(); + + auto glDisplay = InitializeGlDisplay(); + if (!glDisplay.has_value()) + { + std::cout << "Error creating OpenGl display." << std::endl; + glfwTerminate(); + return 2; + } + + GlRenderer* renderer = CreateInitializedRenderer(); +/* + Eye eye; + const ImageData rightScreen = FindRightScreenshot(screenshots, glDisplay->first); + eye.Initialize(renderer, rightScreen); + */ + float deltaT = 0.f; + + while (!glfwWindowShouldClose(glDisplay->second)) + { + const auto startIteration = std::chrono::steady_clock::now(); + glfwPollEvents(); + + std::optional* faceDataToUse = nullptr; + bool tookTheLock = false; + if (faceMutex.try_lock()) + { faceDataToUse = &facePosition; tookTheLock = true; - } - else + } + else faceDataToUse = &lastFacePosition; - eye.Update(*faceDataToUse, deltaT); + //eye.Update(*faceDataToUse, deltaT); - if (tookTheLock) + if (tookTheLock) + { lastFacePosition = facePosition; - faceMutex.unlock(); + faceMutex.unlock(); + } - renderer->Render(); + //renderer->Render(); - glfwSwapBuffers(window); + glfwSwapBuffers(glDisplay->second); - const auto endIteration = std::chrono::steady_clock::now(); - deltaT = std::chrono::duration(endIteration - startIteration).count(); - globalT += deltaT; - } + const auto endIteration = std::chrono::steady_clock::now(); + deltaT = std::chrono::duration(endIteration - startIteration).count(); + globalT += deltaT; + } - faceAnalyzer.StopThreadedDetection(); - } - else - std::cout << "Error initializing Face analyzer. Check if you have a working camera and if the data folder is accessible." << std::endl; + faceAnalyzer.StopThreadedDetection(); // Clean up - delete renderer; - delete screenshotCapturer; glfwTerminate(); + delete renderer; + //delete screenshotCapturer; return ok ? 0 : 1; } From 962405430a80ce682a0974e861e93ea4161c540e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20C=2E=20Guimaraes?= Date: Sun, 19 Oct 2025 21:28:49 -0300 Subject: [PATCH 06/11] Reorganized main to respect exit conditions with proper cleanups --- src/main.cpp | 127 ++++++++++++++++++++++++--------------------------- 1 file changed, 60 insertions(+), 67 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 26f31fc..90fde27 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -116,14 +116,6 @@ std::optional> InitializeGlDisplay() return std::make_pair(monitor, window); } -GlRenderer* CreateInitializedRenderer() -{ - OrbitCamera camera(Vector3(0, 0, 0)); - auto renderer = new GlRenderer(&camera); - renderer->SetClearColor(0.0f, 0.0f, 0.0f); - return renderer; -} - int main() { auto screenshotCapturer = CreateScreenCapturer(); @@ -135,67 +127,68 @@ int main() EyeFaceAnalyzer faceAnalyzer(faceMutex, facePosition); const bool ok = faceAnalyzer.Initialize(); - if (!ok) + if (ok) { - std::cout << "Error initializing Face analyzer. Check if you have a working camera and if the data folder is accessible." << std::endl; - return 1; + faceAnalyzer.RunThreadedDetection(); + + auto glDisplay = InitializeGlDisplay(); + if (glDisplay.has_value()) + { + OrbitCamera camera(Vector3(0, 0, 0)); + auto renderer = new GlRenderer(&camera); + renderer->SetClearColor(0.0f, 0.0f, 0.0f); + + Eye eye; + const ImageData rightScreen = FindRightScreenshot(screenshots, glDisplay->first); + eye.Initialize(renderer, rightScreen); + + float deltaT = 0.f; + + while (!glfwWindowShouldClose(glDisplay->second)) + { + const auto startIteration = std::chrono::steady_clock::now(); + glfwPollEvents(); + + std::optional* faceDataToUse = nullptr; + bool tookTheLock = false; + if (faceMutex.try_lock()) + { + faceDataToUse = &facePosition; + tookTheLock = true; + } + else + faceDataToUse = &lastFacePosition; + + eye.Update(*faceDataToUse, deltaT); + + if (tookTheLock) + { + lastFacePosition = facePosition; + faceMutex.unlock(); + } + + renderer->Render(); + + glfwSwapBuffers(glDisplay->second); + + const auto endIteration = std::chrono::steady_clock::now(); + deltaT = std::chrono::duration(endIteration - startIteration).count(); + globalT += deltaT; + } + + delete renderer; + } + else + std::cout << "Error creating OpenGl display." << std::endl; + + glfwTerminate(); + + faceAnalyzer.StopThreadedDetection(); } - faceAnalyzer.RunThreadedDetection(); - - auto glDisplay = InitializeGlDisplay(); - if (!glDisplay.has_value()) - { - std::cout << "Error creating OpenGl display." << std::endl; - glfwTerminate(); - return 2; - } - - GlRenderer* renderer = CreateInitializedRenderer(); -/* - Eye eye; - const ImageData rightScreen = FindRightScreenshot(screenshots, glDisplay->first); - eye.Initialize(renderer, rightScreen); - */ - float deltaT = 0.f; - - while (!glfwWindowShouldClose(glDisplay->second)) - { - const auto startIteration = std::chrono::steady_clock::now(); - glfwPollEvents(); - - std::optional* faceDataToUse = nullptr; - bool tookTheLock = false; - if (faceMutex.try_lock()) - { - faceDataToUse = &facePosition; - tookTheLock = true; - } - else - faceDataToUse = &lastFacePosition; - - //eye.Update(*faceDataToUse, deltaT); - - if (tookTheLock) - { - lastFacePosition = facePosition; - faceMutex.unlock(); - } - - //renderer->Render(); - - glfwSwapBuffers(glDisplay->second); - - const auto endIteration = std::chrono::steady_clock::now(); - deltaT = std::chrono::duration(endIteration - startIteration).count(); - globalT += deltaT; - } - - faceAnalyzer.StopThreadedDetection(); - - // Clean up - glfwTerminate(); - delete renderer; - //delete screenshotCapturer; + else + std::cout << "Error initializing Face analyzer. Check if you have a working camera and if the data folder is accessible." << std::endl; + + delete screenshotCapturer; return ok ? 0 : 1; } From 7df0966dec4c6b43c4ff4646b1b4a7318aa09941 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20C=2E=20Guimaraes?= Date: Tue, 21 Oct 2025 21:49:01 -0300 Subject: [PATCH 07/11] First version working with workaround --- CMakeLists.txt | 10 +- src/Eye3dModel.cpp | 3 +- src/windows/WindowsScreenCapturer.cpp | 269 +++++++++++++++++++++++++- src/windows/WindowsScreenCapturer.h | 10 +- 4 files changed, 277 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c45c5a6..00b2780 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -63,9 +63,11 @@ file(GLOB_RECURSE srcWindows src/windows/*.h src/windows/*.cpp) ### ### Compiler settings ### -add_definitions( - -fPIC -fcommon - ) +if(UNIX) + add_definitions( + -fPIC -fcommon + ) +endif() ### ### GLFW @@ -107,7 +109,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE ${PROJ_LINK_LIBS}) if (WIN32) - target_link_libraries(${PROJECT_NAME} PRIVATE glm::glm-header-only) + target_link_libraries(${PROJECT_NAME} PRIVATE glm::glm-header-only GdiPlus) get_target_property(GLM_INCLUDE_DIR glm::glm-header-only INTERFACE_INCLUDE_DIRECTORIES) message(STATUS "GLM include dir: ${GLM_INCLUDE_DIR}") diff --git a/src/Eye3dModel.cpp b/src/Eye3dModel.cpp index 4690fc0..37fc612 100644 --- a/src/Eye3dModel.cpp +++ b/src/Eye3dModel.cpp @@ -124,7 +124,8 @@ Material *Eye3dModel::CreateEyeMaterial(GlRenderer *renderer) const Material *Eye3dModel::CreateSkinMaterial(GlRenderer *renderer, const ImageData& screenshot) const { - const unsigned int textureId = renderer->AddTexture(screenshot, GL_BGRA); + //const unsigned int textureId = renderer->AddTexture(screenshot, GL_BGRA); + const unsigned int textureId = renderer->AddTexture(std::string(DATA_PATH) + "/liveshot.bmp", 3); auto material = new Material("skin"); material->diffuseTextureId = textureId; material->specularTextureId = whiteTextureId; diff --git a/src/windows/WindowsScreenCapturer.cpp b/src/windows/WindowsScreenCapturer.cpp index 341625b..b255ae5 100644 --- a/src/windows/WindowsScreenCapturer.cpp +++ b/src/windows/WindowsScreenCapturer.cpp @@ -1,24 +1,277 @@ #include "WindowsScreenCapturer.h" +#include +#include + +using namespace Gdiplus; + +void errHandler(const char* functionName, HWND handler) +{ + +} + + +PBITMAPINFO CreateBitmapInfoStruct(HWND hwnd, HBITMAP hBmp) +{ + BITMAP bmp; + PBITMAPINFO pbmi; + WORD cClrBits; + + // Retrieve the bitmap color format, width, and height. + if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp)) + errHandler("GetObject", hwnd); + + // Convert the color format to a count of bits. + cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel); + if (cClrBits == 1) + cClrBits = 1; + else if (cClrBits <= 4) + cClrBits = 4; + else if (cClrBits <= 8) + cClrBits = 8; + else if (cClrBits <= 16) + cClrBits = 16; + else if (cClrBits <= 24) + cClrBits = 24; + else cClrBits = 32; + + // Allocate memory for the BITMAPINFO structure. (This structure + // contains a BITMAPINFOHEADER structure and an array of RGBQUAD + // data structures.) + + if (cClrBits < 24) + pbmi = (PBITMAPINFO)LocalAlloc(LPTR, + sizeof(BITMAPINFOHEADER) + + sizeof(RGBQUAD) * (1 << cClrBits)); + + // There is no RGBQUAD array for these formats: 24-bit-per-pixel or 32-bit-per-pixel + + else + pbmi = (PBITMAPINFO)LocalAlloc(LPTR, + sizeof(BITMAPINFOHEADER)); + + // Initialize the fields in the BITMAPINFO structure. + + pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + pbmi->bmiHeader.biWidth = bmp.bmWidth; + pbmi->bmiHeader.biHeight = bmp.bmHeight; + pbmi->bmiHeader.biPlanes = bmp.bmPlanes; + pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel; + if (cClrBits < 24) + pbmi->bmiHeader.biClrUsed = (1 << cClrBits); + + // If the bitmap is not compressed, set the BI_RGB flag. + pbmi->bmiHeader.biCompression = BI_RGB; + + // Compute the number of bytes in the array of color + // indices and store the result in biSizeImage. + // The width must be DWORD aligned unless the bitmap is RLE + // compressed. + pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits + 31) & ~31) / 8 + * pbmi->bmiHeader.biHeight; + // Set biClrImportant to 0, indicating that all of the + // device colors are important. + pbmi->bmiHeader.biClrImportant = 0; + return pbmi; +} + +void CreateBMPFile(HWND hwnd, LPTSTR pszFile, PBITMAPINFO pbi, + HBITMAP hBMP, HDC hDC) +{ + HANDLE hf; // file handle + BITMAPFILEHEADER hdr; // bitmap file-header + PBITMAPINFOHEADER pbih; // bitmap info-header + LPBYTE lpBits; // memory pointer + DWORD dwTotal; // total count of bytes + DWORD cb; // incremental count of bytes + BYTE* hp; // byte pointer + DWORD dwTmp; + + pbih = (PBITMAPINFOHEADER)pbi; + lpBits = (LPBYTE)GlobalAlloc(GMEM_FIXED, pbih->biSizeImage); + + if (!lpBits) + errHandler("GlobalAlloc", hwnd); + + // Retrieve the color table (RGBQUAD array) and the bits + // (array of palette indices) from the DIB. + if (!GetDIBits(hDC, hBMP, 0, (WORD)pbih->biHeight, lpBits, pbi, + DIB_RGB_COLORS)) + { + errHandler("GetDIBits", hwnd); + } + + // Create the .BMP file. + hf = CreateFile(pszFile, + GENERIC_READ | GENERIC_WRITE, + (DWORD)0, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + (HANDLE)NULL); + if (hf == INVALID_HANDLE_VALUE) + errHandler("CreateFile", hwnd); + hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M" + // Compute the size of the entire file. + hdr.bfSize = (DWORD)(sizeof(BITMAPFILEHEADER) + + pbih->biSize + pbih->biClrUsed + * sizeof(RGBQUAD) + pbih->biSizeImage); + hdr.bfReserved1 = 0; + hdr.bfReserved2 = 0; + + // Compute the offset to the array of color indices. + hdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + + pbih->biSize + pbih->biClrUsed + * sizeof(RGBQUAD); + + // Copy the BITMAPFILEHEADER into the .BMP file. + if (!WriteFile(hf, (LPVOID)&hdr, sizeof(BITMAPFILEHEADER), + (LPDWORD)&dwTmp, NULL)) + { + errHandler("WriteFile", hwnd); + } + + // Copy the BITMAPINFOHEADER and RGBQUAD array into the file. + if (!WriteFile(hf, (LPVOID)pbih, sizeof(BITMAPINFOHEADER) + + pbih->biClrUsed * sizeof(RGBQUAD), + (LPDWORD)&dwTmp, (NULL))) + errHandler("WriteFile", hwnd); + + // Copy the array of color indices into the .BMP file. + dwTotal = cb = pbih->biSizeImage; + hp = lpBits; + if (!WriteFile(hf, (LPSTR)hp, (int)cb, (LPDWORD)&dwTmp, NULL)) + errHandler("WriteFile", hwnd); + + // Close the .BMP file. + if (!CloseHandle(hf)) + errHandler("CloseHandle", hwnd); + + // Free memory. + GlobalFree((HGLOBAL)lpBits); +} + +int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) +{ + UINT num = 0; // number of image encoders + UINT size = 0; // size of the image encoder array in bytes + + ImageCodecInfo* pImageCodecInfo = NULL; + + GetImageEncodersSize(&num, &size); + if (size == 0) + return -1; // Failure + + pImageCodecInfo = (ImageCodecInfo*)(malloc(size)); + if (pImageCodecInfo == NULL) + return -1; // Failure + + GetImageEncoders(num, size, pImageCodecInfo); + + for (UINT j = 0; j < num; ++j) + { + if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0) + { + *pClsid = pImageCodecInfo[j].Clsid; + free(pImageCodecInfo); + return j; // Success + } + } + free(pImageCodecInfo); + return -1; // Failure +} + +WindowsScreenCapturer::WindowsScreenCapturer() +{ + GdiplusStartupInput gdiplusStartupInput; + GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); +} + +WindowsScreenCapturer::~WindowsScreenCapturer() +{ + GdiplusShutdown(gdiplusToken); +} std::unordered_map WindowsScreenCapturer::Capture() { std::unordered_map screenshots; + + // 1. Create device contexts + HDC hScreenDC = GetDC(HWND_DESKTOP); + HDC hMemoryDC = CreateCompatibleDC(hScreenDC); + + // 2. Get screen dimensions + const int width = GetSystemMetrics(SM_CXSCREEN); + const int height = GetSystemMetrics(SM_CYSCREEN); + + // 3. Create compatible bitmap + HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height); + + //auto bitmapInfo = CreateBitmapInfoStruct(hBitmap); + + HGDIOBJ hOldBitmap = SelectObject(hMemoryDC, hBitmap); + + // 4. BitBlt screen to memory DC + BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY); + + hBitmap = (HBITMAP)SelectObject(hMemoryDC, hOldBitmap); + + // 5. Set up BITMAPINFO + /*BITMAPINFO bmpInfo; + ZeroMemory(&bmpInfo, sizeof(BITMAPINFO)); + bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmpInfo.bmiHeader.biWidth = width; + bmpInfo.bmiHeader.biHeight = -height; // Top-down DIB + bmpInfo.bmiHeader.biPlanes = 1; + bmpInfo.bmiHeader.biBitCount = 24; // 3 bytes (BGR) + bmpInfo.bmiHeader.biCompression = BI_RGB;*/ + + // 6. Allocate image data +/* ImageData screenData; + screenData.width = width; + screenData.height = height; + screenData.channels = bmpInfo.bmiHeader.biBitCount / 8; + const size_t dataSize = width * height * screenData.channels; + screenData.data = new unsigned char[dataSize]; + + // Get Info on BItmap + GetDIBits(hMemoryDC, hBitmap, 0, height, NULL, &bmpInfo, DIB_RGB_COLORS); + + // 7. Get pixel data + GetDIBits(hMemoryDC, hBitmap, 0, height, screenData.data, &bmpInfo, DIB_RGB_COLORS); + + // 8. Cleanup + SelectObject(hMemoryDC, hOldBitmap);*/ + + + Bitmap* image = new Bitmap(hBitmap, NULL); + + CLSID myClsId; + int retVal = GetEncoderClsid(L"image/bmp", &myClsId); + + image->Save(L"./data/liveshot.bmp", &myClsId, NULL); + delete image; + + DeleteObject(hBitmap); + DeleteDC(hMemoryDC); + ReleaseDC(HWND_DESKTOP, hScreenDC); - // Hardcoded screen for now - MonitorPosition position; - position.xOrigin = 0; - position.yOrigin = 1; ImageData screenData; - screenData.width = 3960; - screenData.height = 2160; + screenData.width = width; + screenData.height = height; + screenData.channels = 3; const size_t dataSize = screenData.width * screenData.height * screenData.channels; screenData.data = new unsigned char[dataSize]; - screenshots[position] = screenData; + for (size_t i = 0; i < dataSize; ++i) + screenData.data[i] = 50; - memset(screenData.data, 0, dataSize * sizeof(unsigned char)); + // 9. Store in map with dummy position + MonitorPosition position; + position.xOrigin = 0; + position.yOrigin = 0; + screenshots[position] = screenData; return screenshots; } \ No newline at end of file diff --git a/src/windows/WindowsScreenCapturer.h b/src/windows/WindowsScreenCapturer.h index 49bf906..8d3f5aa 100644 --- a/src/windows/WindowsScreenCapturer.h +++ b/src/windows/WindowsScreenCapturer.h @@ -3,13 +3,19 @@ #include "../AbstractScreenCapturer.h" +#include #include #include "../MonitorPosition.h" class WindowsScreenCapturer : public AbstractScreenCapturer { public: - virtual ~WindowsScreenCapturer() = default; - std::unordered_map Capture() override; + WindowsScreenCapturer(); + ~WindowsScreenCapturer(); + + std::unordered_map Capture() override; + +private: + ULONG_PTR gdiplusToken; }; #endif From 2bf802468d53e2d87a9b700df8c0815063754c03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20C=2E=20Guimaraes?= Date: Wed, 22 Oct 2025 21:48:19 -0300 Subject: [PATCH 08/11] Working with proper solution, screenshot data copy from buffer. --- src/Eye3dModel.cpp | 3 +- src/windows/WindowsScreenCapturer.cpp | 220 +------------------------- 2 files changed, 6 insertions(+), 217 deletions(-) diff --git a/src/Eye3dModel.cpp b/src/Eye3dModel.cpp index 37fc612..4690fc0 100644 --- a/src/Eye3dModel.cpp +++ b/src/Eye3dModel.cpp @@ -124,8 +124,7 @@ Material *Eye3dModel::CreateEyeMaterial(GlRenderer *renderer) const Material *Eye3dModel::CreateSkinMaterial(GlRenderer *renderer, const ImageData& screenshot) const { - //const unsigned int textureId = renderer->AddTexture(screenshot, GL_BGRA); - const unsigned int textureId = renderer->AddTexture(std::string(DATA_PATH) + "/liveshot.bmp", 3); + const unsigned int textureId = renderer->AddTexture(screenshot, GL_BGRA); auto material = new Material("skin"); material->diffuseTextureId = textureId; material->specularTextureId = whiteTextureId; diff --git a/src/windows/WindowsScreenCapturer.cpp b/src/windows/WindowsScreenCapturer.cpp index b255ae5..015197d 100644 --- a/src/windows/WindowsScreenCapturer.cpp +++ b/src/windows/WindowsScreenCapturer.cpp @@ -5,181 +5,6 @@ using namespace Gdiplus; -void errHandler(const char* functionName, HWND handler) -{ - -} - - -PBITMAPINFO CreateBitmapInfoStruct(HWND hwnd, HBITMAP hBmp) -{ - BITMAP bmp; - PBITMAPINFO pbmi; - WORD cClrBits; - - // Retrieve the bitmap color format, width, and height. - if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp)) - errHandler("GetObject", hwnd); - - // Convert the color format to a count of bits. - cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel); - if (cClrBits == 1) - cClrBits = 1; - else if (cClrBits <= 4) - cClrBits = 4; - else if (cClrBits <= 8) - cClrBits = 8; - else if (cClrBits <= 16) - cClrBits = 16; - else if (cClrBits <= 24) - cClrBits = 24; - else cClrBits = 32; - - // Allocate memory for the BITMAPINFO structure. (This structure - // contains a BITMAPINFOHEADER structure and an array of RGBQUAD - // data structures.) - - if (cClrBits < 24) - pbmi = (PBITMAPINFO)LocalAlloc(LPTR, - sizeof(BITMAPINFOHEADER) + - sizeof(RGBQUAD) * (1 << cClrBits)); - - // There is no RGBQUAD array for these formats: 24-bit-per-pixel or 32-bit-per-pixel - - else - pbmi = (PBITMAPINFO)LocalAlloc(LPTR, - sizeof(BITMAPINFOHEADER)); - - // Initialize the fields in the BITMAPINFO structure. - - pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - pbmi->bmiHeader.biWidth = bmp.bmWidth; - pbmi->bmiHeader.biHeight = bmp.bmHeight; - pbmi->bmiHeader.biPlanes = bmp.bmPlanes; - pbmi->bmiHeader.biBitCount = bmp.bmBitsPixel; - if (cClrBits < 24) - pbmi->bmiHeader.biClrUsed = (1 << cClrBits); - - // If the bitmap is not compressed, set the BI_RGB flag. - pbmi->bmiHeader.biCompression = BI_RGB; - - // Compute the number of bytes in the array of color - // indices and store the result in biSizeImage. - // The width must be DWORD aligned unless the bitmap is RLE - // compressed. - pbmi->bmiHeader.biSizeImage = ((pbmi->bmiHeader.biWidth * cClrBits + 31) & ~31) / 8 - * pbmi->bmiHeader.biHeight; - // Set biClrImportant to 0, indicating that all of the - // device colors are important. - pbmi->bmiHeader.biClrImportant = 0; - return pbmi; -} - -void CreateBMPFile(HWND hwnd, LPTSTR pszFile, PBITMAPINFO pbi, - HBITMAP hBMP, HDC hDC) -{ - HANDLE hf; // file handle - BITMAPFILEHEADER hdr; // bitmap file-header - PBITMAPINFOHEADER pbih; // bitmap info-header - LPBYTE lpBits; // memory pointer - DWORD dwTotal; // total count of bytes - DWORD cb; // incremental count of bytes - BYTE* hp; // byte pointer - DWORD dwTmp; - - pbih = (PBITMAPINFOHEADER)pbi; - lpBits = (LPBYTE)GlobalAlloc(GMEM_FIXED, pbih->biSizeImage); - - if (!lpBits) - errHandler("GlobalAlloc", hwnd); - - // Retrieve the color table (RGBQUAD array) and the bits - // (array of palette indices) from the DIB. - if (!GetDIBits(hDC, hBMP, 0, (WORD)pbih->biHeight, lpBits, pbi, - DIB_RGB_COLORS)) - { - errHandler("GetDIBits", hwnd); - } - - // Create the .BMP file. - hf = CreateFile(pszFile, - GENERIC_READ | GENERIC_WRITE, - (DWORD)0, - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - (HANDLE)NULL); - if (hf == INVALID_HANDLE_VALUE) - errHandler("CreateFile", hwnd); - hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M" - // Compute the size of the entire file. - hdr.bfSize = (DWORD)(sizeof(BITMAPFILEHEADER) + - pbih->biSize + pbih->biClrUsed - * sizeof(RGBQUAD) + pbih->biSizeImage); - hdr.bfReserved1 = 0; - hdr.bfReserved2 = 0; - - // Compute the offset to the array of color indices. - hdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + - pbih->biSize + pbih->biClrUsed - * sizeof(RGBQUAD); - - // Copy the BITMAPFILEHEADER into the .BMP file. - if (!WriteFile(hf, (LPVOID)&hdr, sizeof(BITMAPFILEHEADER), - (LPDWORD)&dwTmp, NULL)) - { - errHandler("WriteFile", hwnd); - } - - // Copy the BITMAPINFOHEADER and RGBQUAD array into the file. - if (!WriteFile(hf, (LPVOID)pbih, sizeof(BITMAPINFOHEADER) - + pbih->biClrUsed * sizeof(RGBQUAD), - (LPDWORD)&dwTmp, (NULL))) - errHandler("WriteFile", hwnd); - - // Copy the array of color indices into the .BMP file. - dwTotal = cb = pbih->biSizeImage; - hp = lpBits; - if (!WriteFile(hf, (LPSTR)hp, (int)cb, (LPDWORD)&dwTmp, NULL)) - errHandler("WriteFile", hwnd); - - // Close the .BMP file. - if (!CloseHandle(hf)) - errHandler("CloseHandle", hwnd); - - // Free memory. - GlobalFree((HGLOBAL)lpBits); -} - -int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) -{ - UINT num = 0; // number of image encoders - UINT size = 0; // size of the image encoder array in bytes - - ImageCodecInfo* pImageCodecInfo = NULL; - - GetImageEncodersSize(&num, &size); - if (size == 0) - return -1; // Failure - - pImageCodecInfo = (ImageCodecInfo*)(malloc(size)); - if (pImageCodecInfo == NULL) - return -1; // Failure - - GetImageEncoders(num, size, pImageCodecInfo); - - for (UINT j = 0; j < num; ++j) - { - if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0) - { - *pClsid = pImageCodecInfo[j].Clsid; - free(pImageCodecInfo); - return j; // Success - } - } - free(pImageCodecInfo); - return -1; // Failure -} WindowsScreenCapturer::WindowsScreenCapturer() { @@ -196,82 +21,47 @@ std::unordered_map WindowsScreenCapturer::Capture() { std::unordered_map screenshots; - // 1. Create device contexts HDC hScreenDC = GetDC(HWND_DESKTOP); HDC hMemoryDC = CreateCompatibleDC(hScreenDC); - // 2. Get screen dimensions const int width = GetSystemMetrics(SM_CXSCREEN); const int height = GetSystemMetrics(SM_CYSCREEN); - // 3. Create compatible bitmap HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, width, height); - - //auto bitmapInfo = CreateBitmapInfoStruct(hBitmap); - HGDIOBJ hOldBitmap = SelectObject(hMemoryDC, hBitmap); - // 4. BitBlt screen to memory DC BitBlt(hMemoryDC, 0, 0, width, height, hScreenDC, 0, 0, SRCCOPY); hBitmap = (HBITMAP)SelectObject(hMemoryDC, hOldBitmap); - // 5. Set up BITMAPINFO - /*BITMAPINFO bmpInfo; + BITMAPINFO bmpInfo; ZeroMemory(&bmpInfo, sizeof(BITMAPINFO)); bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmpInfo.bmiHeader.biWidth = width; bmpInfo.bmiHeader.biHeight = -height; // Top-down DIB bmpInfo.bmiHeader.biPlanes = 1; - bmpInfo.bmiHeader.biBitCount = 24; // 3 bytes (BGR) - bmpInfo.bmiHeader.biCompression = BI_RGB;*/ + bmpInfo.bmiHeader.biBitCount = 32; + bmpInfo.bmiHeader.biCompression = BI_RGB; - // 6. Allocate image data -/* ImageData screenData; + ImageData screenData; screenData.width = width; screenData.height = height; screenData.channels = bmpInfo.bmiHeader.biBitCount / 8; const size_t dataSize = width * height * screenData.channels; screenData.data = new unsigned char[dataSize]; - // Get Info on BItmap GetDIBits(hMemoryDC, hBitmap, 0, height, NULL, &bmpInfo, DIB_RGB_COLORS); - - // 7. Get pixel data GetDIBits(hMemoryDC, hBitmap, 0, height, screenData.data, &bmpInfo, DIB_RGB_COLORS); - - // 8. Cleanup - SelectObject(hMemoryDC, hOldBitmap);*/ - - - Bitmap* image = new Bitmap(hBitmap, NULL); - - CLSID myClsId; - int retVal = GetEncoderClsid(L"image/bmp", &myClsId); + SelectObject(hMemoryDC, hOldBitmap); - image->Save(L"./data/liveshot.bmp", &myClsId, NULL); - delete image; DeleteObject(hBitmap); DeleteDC(hMemoryDC); ReleaseDC(HWND_DESKTOP, hScreenDC); - - ImageData screenData; - screenData.width = width; - screenData.height = height; - - screenData.channels = 3; - const size_t dataSize = screenData.width * screenData.height * screenData.channels; - screenData.data = new unsigned char[dataSize]; - for (size_t i = 0; i < dataSize; ++i) - screenData.data[i] = 50; - - // 9. Store in map with dummy position MonitorPosition position; position.xOrigin = 0; position.yOrigin = 0; screenshots[position] = screenData; - return screenshots; } \ No newline at end of file From 5c89017678e7d9c307f6c298d81310e2659d8c0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20C=2E=20Guimaraes?= Date: Wed, 22 Oct 2025 18:53:54 -0300 Subject: [PATCH 09/11] Restored correct fullscreen and resolution --- src/main.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 90fde27..97ca8f6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -95,12 +95,10 @@ std::optional> InitializeGlDisplay() monitor = glfwGetPrimaryMonitor(); const GLFWvidmode* mode = glfwGetVideoMode(monitor); - //const int monitorWidth = mode->width; - const int monitorWidth = 1980; - //const int monitorHeight = mode->height; - const int monitorHeight = 1080; + const int monitorWidth = mode->width; + const int monitorHeight = mode->height; - window = glfwCreateWindow(monitorWidth, monitorHeight, "Eye Renderer", nullptr, nullptr); + window = glfwCreateWindow(monitorWidth, monitorHeight, "Eye Renderer", monitor, nullptr); if (!window) return std::nullopt; From 02272eab07f98f99a431919e606f4957b760530f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20C=2E=20Guimaraes?= Date: Wed, 22 Oct 2025 18:57:50 -0300 Subject: [PATCH 10/11] Fixed linux build --- src/linux/LinuxScreenCapturer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/linux/LinuxScreenCapturer.h b/src/linux/LinuxScreenCapturer.h index 3bc5cb3..f82b5cf 100644 --- a/src/linux/LinuxScreenCapturer.h +++ b/src/linux/LinuxScreenCapturer.h @@ -3,7 +3,7 @@ #include -#include "AbstractScreenCapturer.h" +#include "../AbstractScreenCapturer.h" #include "ImageData.h" #include "MonitorPosition.h" From ddbbc5892e18c10d1fe28d2bfc08a60cb5ebae91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micka=C3=ABl=20C=2E=20Guimaraes?= Date: Wed, 22 Oct 2025 19:09:28 -0300 Subject: [PATCH 11/11] Fixing Linux compile errors --- src/linux/LinuxScreenCapturer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/linux/LinuxScreenCapturer.h b/src/linux/LinuxScreenCapturer.h index f82b5cf..d5e483b 100644 --- a/src/linux/LinuxScreenCapturer.h +++ b/src/linux/LinuxScreenCapturer.h @@ -5,7 +5,7 @@ #include "../AbstractScreenCapturer.h" #include "ImageData.h" -#include "MonitorPosition.h" +#include "../MonitorPosition.h" class LinuxScreenCapturer : public AbstractScreenCapturer {