xp12camera

Owner: IIIlllIIIllI URL: git@github.com:nyangkosense/xp12camera.git

broken branch

Commit 264bb5f021fb5e3bcbec2470bea864d16546c01d by SM <seb.michalk@gmail.com> on 2025-07-01 09:52:09 +0200
diff --git a/FLIR_Camera.cpp b/FLIR_Camera.cpp
index b119e17..216a8eb 100644
--- a/FLIR_Camera.cpp
+++ b/FLIR_Camera.cpp
@@ -130,6 +130,8 @@ PLUGIN_API void XPluginStop(void)
         XPLMDontControlCamera();
         gCameraActive = 0;
     }
+    
+    CleanupVisualEffects();
 }
 PLUGIN_API void XPluginDisable(void) { }
 PLUGIN_API int XPluginEnable(void) { return 1; }
diff --git a/FLIR_Camera.o b/FLIR_Camera.o
index e6a69be..ac69dda 100644
Binary files a/FLIR_Camera.o and b/FLIR_Camera.o differ
diff --git a/FLIR_VisualEffects.cpp b/FLIR_VisualEffects.cpp
index 9c98aac..1bd22ad 100644
--- a/FLIR_VisualEffects.cpp
+++ b/FLIR_VisualEffects.cpp
@@ -53,12 +53,165 @@ static float gContrast = 1.2f;
 static float gNoiseIntensity = 0.1f;
 static float gScanLineOpacity = 0.05f;
 static int gFrameCounter = 0;
+static int gPostProcessingEnabled = 1;
+static unsigned char* gPixelBuffer = NULL;
+static int gBufferWidth = 0;
+static int gBufferHeight = 0;
 
 void InitializeVisualEffects()
 {
     srand(time(NULL));
 }
 
+void CleanupVisualEffects()
+{
+    if (gPixelBuffer) {
+        free(gPixelBuffer);
+        gPixelBuffer = NULL;
+    }
+}
+
+// Safety function to allocate pixel buffer
+int AllocatePixelBuffer(int width, int height)
+{
+    int newSize = width * height * 3; // RGB
+    
+    if (!gPixelBuffer || gBufferWidth != width || gBufferHeight != height) {
+        if (gPixelBuffer) {
+            free(gPixelBuffer);
+        }
+        
+        gPixelBuffer = (unsigned char*)malloc(newSize);
+        if (!gPixelBuffer) {
+            return 0; // Failed to allocate
+        }
+        
+        gBufferWidth = width;
+        gBufferHeight = height;
+    }
+    
+    return 1; // Success
+}
+
+// Convert RGB to grayscale with EO/IR processing
+void ProcessEOIR(unsigned char* pixels, int width, int height, int mode)
+{
+    for (int i = 0; i < width * height; i++) {
+        int idx = i * 3;
+        unsigned char r = pixels[idx];
+        unsigned char g = pixels[idx + 1];
+        unsigned char b = pixels[idx + 2];
+        
+        // Convert to grayscale (0.0 - 1.0 range)
+        float gray = (0.299f * r + 0.587f * g + 0.114f * b) / 255.0f;
+        
+        // Apply EO/IR processing based on mode
+        switch (mode) {
+            case 1: // Monochrome with enhancement
+                // Aggressive contrast curve
+                gray = powf(gray, 0.6f);
+                gray = gray * 1.8f - 0.4f;
+                gray = fmaxf(0.0f, fminf(1.0f, gray));
+                
+                // Crush blacks and blow highlights for military look
+                if (gray < 0.25f) gray = gray * 0.3f;        // Crush darks
+                else if (gray > 0.75f) gray = 0.8f + (gray - 0.75f) * 0.8f; // Compress highlights
+                break;
+                
+            case 2: // Thermal simulation
+                // Thermal processing with inversion
+                gray = powf(gray, 0.5f) * 1.6f;
+                gray = 1.0f - gray; // Invert for thermal (hot = white)
+                gray = fmaxf(0.0f, fminf(1.0f, gray));
+                break;
+                
+            case 3: // Enhanced IR
+                // Extreme contrast for IR look
+                gray = powf(gray, 0.4f);
+                gray = gray * 2.5f - 0.8f;
+                gray = fmaxf(0.0f, fminf(1.0f, gray));
+                
+                // Quantize to simulate limited bit depth
+                gray = floorf(gray * 32.0f) / 32.0f;
+                break;
+                
+            default:
+                // Standard - minimal processing
+                break;
+        }
+        
+        // Add very subtle noise for realism
+        if (mode > 0) {
+            float noise = ((rand() % 21) - 10) / 2000.0f; // -0.005 to +0.005
+            gray += noise;
+            gray = fmaxf(0.0f, fminf(1.0f, gray));
+        }
+        
+        // Convert back to RGB
+        unsigned char finalGray = (unsigned char)(gray * 255.0f);
+        
+        // For monochrome, add slight green tint
+        if (mode == 1) {
+            pixels[idx] = (unsigned char)(finalGray * 0.7f);     // R
+            pixels[idx + 1] = finalGray;                         // G  
+            pixels[idx + 2] = (unsigned char)(finalGray * 0.7f); // B
+        } else {
+            pixels[idx] = finalGray;     // R
+            pixels[idx + 1] = finalGray; // G
+            pixels[idx + 2] = finalGray; // B
+        }
+    }
+}
+
+// Main post-processing function with safety checks
+void RenderPostProcessing(int screenWidth, int screenHeight)
+{
+    // Safety check: skip if too small or too large
+    if (screenWidth < 100 || screenHeight < 100 || 
+        screenWidth > 4096 || screenHeight > 4096) {
+        return;
+    }
+    
+    // Allocate buffer if needed
+    if (!AllocatePixelBuffer(screenWidth, screenHeight)) {
+        return; // Failed to allocate, skip processing
+    }
+    
+    // Clear any OpenGL errors before we start
+    while (glGetError() != GL_NO_ERROR) { }
+    
+    // Read the current framebuffer
+    glReadPixels(0, 0, screenWidth, screenHeight, GL_RGB, GL_UNSIGNED_BYTE, gPixelBuffer);
+    
+    // Check for OpenGL errors
+    GLenum error = glGetError();
+    if (error != GL_NO_ERROR) {
+        return; // Failed to read pixels, skip processing
+    }
+    
+    // Determine processing mode based on current visual effects
+    int processingMode = 0;
+    if (gMonochromeEnabled) processingMode = 1;
+    else if (gThermalEnabled) processingMode = 2;
+    else if (gIREnabled) processingMode = 3;
+    
+    // Only process if we have an active mode
+    if (processingMode > 0) {
+        ProcessEOIR(gPixelBuffer, screenWidth, screenHeight, processingMode);
+    }
+    
+    // Draw the processed image back
+    glRasterPos2f(0, 0);
+    glDrawPixels(screenWidth, screenHeight, GL_RGB, GL_UNSIGNED_BYTE, gPixelBuffer);
+    
+    // Check for errors again
+    error = glGetError();
+    if (error != GL_NO_ERROR) {
+        // If drawing failed, disable post-processing for safety
+        gPostProcessingEnabled = 0;
+    }
+}
+
 void SetMonochromeFilter(int enabled)
 {
     gMonochromeEnabled = enabled;
@@ -84,6 +237,42 @@ void RenderVisualEffects(int screenWidth, int screenHeight)
 {
     gFrameCounter++;
     
+    // Try post-processing first (real image processing)
+    if (gPostProcessingEnabled && (gMonochromeEnabled || gThermalEnabled || gIREnabled)) {
+        RenderPostProcessing(screenWidth, screenHeight);
+        
+        // Still add overlays like noise and scan lines
+        glMatrixMode(GL_PROJECTION);
+        glPushMatrix();
+        glLoadIdentity();
+        glOrtho(0, screenWidth, screenHeight, 0, -1, 1);
+        
+        glMatrixMode(GL_MODELVIEW);
+        glPushMatrix();
+        glLoadIdentity();
+        
+        glDisable(GL_DEPTH_TEST);
+        glEnable(GL_BLEND);
+        
+        if (gNoiseEnabled) {
+            RenderCameraNoise(screenWidth, screenHeight);
+        }
+        
+        if (gScanLinesEnabled) {
+            RenderScanLines(screenWidth, screenHeight);
+        }
+        
+        glEnable(GL_DEPTH_TEST);
+        glDisable(GL_BLEND);
+        glPopMatrix();
+        glMatrixMode(GL_PROJECTION);
+        glPopMatrix();
+        glMatrixMode(GL_MODELVIEW);
+        
+        return;
+    }
+    
+    // Fallback to overlay mode if post-processing fails
     glMatrixMode(GL_PROJECTION);
     glPushMatrix();
     glLoadIdentity();
diff --git a/FLIR_VisualEffects.h b/FLIR_VisualEffects.h
index 5aa8f7e..9205d87 100644
--- a/FLIR_VisualEffects.h
+++ b/FLIR_VisualEffects.h
@@ -32,7 +32,9 @@ extern "C" {
 #endif
 
 void InitializeVisualEffects();
+void CleanupVisualEffects();
 void RenderVisualEffects(int screenWidth, int screenHeight);
+void RenderPostProcessing(int screenWidth, int screenHeight);
 
 void SetMonochromeFilter(int enabled);
 void SetThermalMode(int enabled);
diff --git a/FLIR_VisualEffects.o b/FLIR_VisualEffects.o
index 6fe768c..63090df 100644
Binary files a/FLIR_VisualEffects.o and b/FLIR_VisualEffects.o differ
diff --git a/build/FLIR_Camera/win_x64/FLIR_Camera.xpl b/build/FLIR_Camera/win_x64/FLIR_Camera.xpl
index a9f3566..37b281e 100755
Binary files a/build/FLIR_Camera/win_x64/FLIR_Camera.xpl and b/build/FLIR_Camera/win_x64/FLIR_Camera.xpl differ