FLTK logo

[master] 06793c5 - Create virtual Fl_RGB_Image* Fl_Gl_Window_Driver::capture_gl_rectangle()

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.commit  ]
 
Previous Message ]Next Message ]

[master] 06793c5 - Create virtual Fl_RGB_Image* Fl_Gl_Window_Driver::capture_gl_rectangle() "ManoloFLTK" Feb 16, 2021  
 
commit 06793c50fb99366a1008ea601c218b1cb6de0bf4
Author:     ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>
AuthorDate: Tue Feb 16 10:26:42 2021 +0100
Commit:     ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com>
CommitDate: Tue Feb 16 10:26:52 2021 +0100

    Create virtual Fl_RGB_Image* Fl_Gl_Window_Driver::capture_gl_rectangle()

 FL/Fl_Gl_Window.H                               |  1 +
 src/Fl_Gl_Window_Driver.H                       |  1 +
 src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx | 53 +++++++++++++++++++
 src/drivers/OpenGL/Fl_OpenGL_Display_Device.cxx | 67 +++----------------------
 4 files changed, 63 insertions(+), 59 deletions(-)

diff --git FL/Fl_Gl_Window.H FL/Fl_Gl_Window.H
index da8a35b..0204c3e 100644
--- FL/Fl_Gl_Window.H
+++ FL/Fl_Gl_Window.H
@@ -51,6 +51,7 @@ class Fl_Gl_Window_Driver;
 class FL_EXPORT Fl_Gl_Window : public Fl_Window {
   friend class Fl_Gl_Window_Driver;
   friend class _Fl_Gl_Overlay;
+  friend class Fl_OpenGL_Display_Device;
   Fl_Gl_Window_Driver *pGlWindowDriver;
 
   /** Returns a pointer to the window's Fl_Gl_Window_Driver object */
diff --git src/Fl_Gl_Window_Driver.H src/Fl_Gl_Window_Driver.H
index d2670e2..ddc52c7 100644
--- src/Fl_Gl_Window_Driver.H
+++ src/Fl_Gl_Window_Driver.H
@@ -99,6 +99,7 @@ public:
   virtual char *alpha_mask_for_string(const char *str, int n, int w, int h);
   virtual int genlistsize() { return 0; } // support for gl_draw()
   virtual Fl_Font_Descriptor** fontnum_to_fontdescriptor(int fnum);
+  virtual Fl_RGB_Image* capture_gl_rectangle(int x, int y, int w, int h);
 };
 
 #endif /* Fl_Gl_Window_Driver_H */
diff --git src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx
index 188f4fe..a9df988 100644
--- src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx
+++ src/drivers/Cocoa/Fl_Cocoa_Gl_Window_Driver.cxx
@@ -54,6 +54,7 @@ class Fl_Cocoa_Gl_Window_Driver : public Fl_Gl_Window_Driver {
   virtual void redraw_overlay();
   virtual void gl_start();
   virtual char *alpha_mask_for_string(const char *str, int n, int w, int h);
+  virtual Fl_RGB_Image* capture_gl_rectangle(int x, int y, int w, int h);
 };
 
 // Describes crap needed to create a GLContext.
@@ -245,4 +246,56 @@ void Fl_Cocoa_Gl_Window_Driver::gl_start() {
   Fl_Cocoa_Window_Driver::gl_start(gl_start_context);
 }
 
+// convert BGRA to RGB and also exchange top and bottom
+static uchar *convert_BGRA_to_RGB(uchar *baseAddress, int w, int h, int mByteWidth)
+{
+  uchar *newimg = new uchar[3*w*h];
+  uchar *to = newimg;
+  for (int i = h-1; i >= 0; i--) {
+    uchar *from = baseAddress + i * mByteWidth;
+    for (int j = 0; j < w; j++, from += 4) {
+#if defined(__ppc__) && __ppc__
+      memcpy(to, from + 1, 3);
+      to += 3;
+#else
+      *(to++) = *(from+2);
+      *(to++) = *(from+1);
+      *(to++) = *from;
+#endif
+    }
+  }
+  delete[] baseAddress;
+  return newimg;
+}
+
+Fl_RGB_Image* Fl_Cocoa_Gl_Window_Driver::capture_gl_rectangle(int x, int y, int w, int h)
+{
+  Fl_Gl_Window* glw = pWindow;
+  float factor = glw->pixels_per_unit();
+  if (factor != 1) {
+    w *= factor; h *= factor; x *= factor; y *= factor;
+  }
+  Fl_Cocoa_Window_Driver::GLcontext_makecurrent(glw->context());
+  Fl_Cocoa_Window_Driver::flush_context(glw->context()); // to capture also the overlay and for directGL demo
+  // Read OpenGL context pixels directly.
+  // For extra safety, save & restore OpenGL states that are changed
+  glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
+  glPixelStorei(GL_PACK_ALIGNMENT, 4); /* Force 4-byte alignment */
+  glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+  glPixelStorei(GL_PACK_SKIP_ROWS, 0);
+  glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+  // Read a block of pixels from the frame buffer
+  int mByteWidth = w * 4;
+  mByteWidth = (mByteWidth + 3) & ~3;    // Align to 4 bytes
+  uchar *baseAddress = new uchar[mByteWidth * h];
+  glReadPixels(x, glw->pixel_h() - (y+h), w, h,
+               GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, baseAddress);
+  glPopClientAttrib();
+  baseAddress = convert_BGRA_to_RGB(baseAddress, w, h, mByteWidth);
+  Fl_RGB_Image *img = new Fl_RGB_Image(baseAddress, w, h, 3, 3 * w);
+  img->alloc_array = 1;
+  Fl_Cocoa_Window_Driver::flush_context(glw->context());
+  return img;
+}
+
 #endif // HAVE_GL
diff --git src/drivers/OpenGL/Fl_OpenGL_Display_Device.cxx src/drivers/OpenGL/Fl_OpenGL_Display_Device.cxx
index acd74bc..b1fb688 100644
--- src/drivers/OpenGL/Fl_OpenGL_Display_Device.cxx
+++ src/drivers/OpenGL/Fl_OpenGL_Display_Device.cxx
@@ -16,7 +16,10 @@
 
 #include "../../config_lib.h"
 #include <FL/Fl_Gl_Window.H>
+#include "../../Fl_Gl_Window_Driver.H"
 #include <FL/Fl_Image.H>
+#include "../../Fl_Screen_Driver.H"
+#include "../../Fl_Window_Driver.H"
 #include <FL/gl.h>
 #include <string.h>
 
@@ -35,69 +38,17 @@ Fl_OpenGL_Display_Device::Fl_OpenGL_Display_Device(Fl_OpenGL_Graphics_Driver *gr
 {
 }
 
-#ifdef FL_CFG_GFX_QUARTZ
-#include "../../Fl_Gl_Window_Driver.H"
-#include "../Cocoa/Fl_Cocoa_Window_Driver.H"
-
-// convert BGRA to RGB and also exchange top and bottom
-static uchar *convert_BGRA_to_RGB(uchar *baseAddress, int w, int h, int mByteWidth)
-{
-  uchar *newimg = new uchar[3*w*h];
-  uchar *to = newimg;
-  for (int i = h-1; i >= 0; i--) {
-    uchar *from = baseAddress + i * mByteWidth;
-    for (int j = 0; j < w; j++, from += 4) {
-#if defined(__ppc__) && __ppc__
-      memcpy(to, from + 1, 3);
-      to += 3;
-#else
-      *(to++) = *(from+2);
-      *(to++) = *(from+1);
-      *(to++) = *from;
-#endif
-    }
-  }
-  delete[] baseAddress;
-  return newimg;
-}
-
 Fl_RGB_Image* Fl_OpenGL_Display_Device::capture_gl_rectangle(Fl_Gl_Window* glw, int x, int y, int w, int h)
 {
-  float factor = glw->pixels_per_unit();
-  if (factor != 1) {
-    w *= factor; h *= factor; x *= factor; y *= factor;
-  }
-  Fl_Cocoa_Window_Driver::GLcontext_makecurrent(glw->context());
-  Fl_Cocoa_Window_Driver::flush_context(glw->context()); // to capture also the overlay and for directGL demo
-  // Read OpenGL context pixels directly.
-  // For extra safety, save & restore OpenGL states that are changed
-  glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
-  glPixelStorei(GL_PACK_ALIGNMENT, 4); /* Force 4-byte alignment */
-  glPixelStorei(GL_PACK_ROW_LENGTH, 0);
-  glPixelStorei(GL_PACK_SKIP_ROWS, 0);
-  glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
-  // Read a block of pixels from the frame buffer
-  int mByteWidth = w * 4;
-  mByteWidth = (mByteWidth + 3) & ~3;    // Align to 4 bytes
-  uchar *baseAddress = new uchar[mByteWidth * h];
-  glReadPixels(x, glw->pixel_h() - (y+h), w, h,
-               GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, baseAddress);
-  glPopClientAttrib();
-  baseAddress = convert_BGRA_to_RGB(baseAddress, w, h, mByteWidth);
-  Fl_RGB_Image *img = new Fl_RGB_Image(baseAddress, w, h, 3, 3 * w);
-  img->alloc_array = 1;
-  Fl_Cocoa_Window_Driver::flush_context(glw->context());
-  return img;
+  return glw->gl_driver()->capture_gl_rectangle(x, y, w, h);
 }
 
-#else
-
-#include "../../Fl_Screen_Driver.H"
-#include "../../Fl_Window_Driver.H"
-Fl_RGB_Image* Fl_OpenGL_Display_Device::capture_gl_rectangle(Fl_Gl_Window *glw, int x, int y, int w, int h)
-/* captures a rectangle of a Fl_Gl_Window window, and returns it as a RGB image
+/* Captures a rectangle of a Fl_Gl_Window and returns it as a RGB image.
+ This is the platform-independent version. Some platforms may re-implement it.
  */
+Fl_RGB_Image* Fl_Gl_Window_Driver::capture_gl_rectangle(int x, int y, int w, int h)
 {
+  Fl_Gl_Window *glw = pWindow;
   glw->flush(); // forces a GL redraw, necessary for the glpuzzle demo
   // Read OpenGL context pixels directly.
   // For extra safety, save & restore OpenGL states that are changed
@@ -135,5 +86,3 @@ Fl_RGB_Image* Fl_OpenGL_Display_Device::capture_gl_rectangle(Fl_Gl_Window *glw,
   img->alloc_array = 1;
   return img;
 }
-
-#endif
Direct Link to Message ]
 
     
Previous Message ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.