summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorManolo Gouy <Manolo>2016-03-09 10:30:29 +0000
committerManolo Gouy <Manolo>2016-03-09 10:30:29 +0000
commitfc3adbd7cbd73106dd3ec47216b485b6cd39a2a9 (patch)
tree6bcc6b76c59c45dfc7e6b0efb124aff4c415fcd7 /src
parent309213bfaeaff9b3beec9548aeb7762d7dbaa2f8 (diff)
Rewrite Fl_Gl_Device_Plugin.cxx in a platform-independent way.
The platform-specific code lands in src/Drivers/OpenGL/Fl_OpenGL_Display_Device.cxx and the FL_PORTING clause should be compilable. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11327 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src')
-rw-r--r--src/Fl_Gl_Device_Plugin.cxx92
-rw-r--r--src/drivers/OpenGL/Fl_OpenGL_Display_Device.H3
-rw-r--r--src/drivers/OpenGL/Fl_OpenGL_Display_Device.cxx116
3 files changed, 122 insertions, 89 deletions
diff --git a/src/Fl_Gl_Device_Plugin.cxx b/src/Fl_Gl_Device_Plugin.cxx
index 269a9ef02..fd428c96f 100644
--- a/src/Fl_Gl_Device_Plugin.cxx
+++ b/src/Fl_Gl_Device_Plugin.cxx
@@ -16,98 +16,12 @@
// http://www.fltk.org/str.php
//
-#include <config.h>
#include "config_lib.h"
-#include <FL/Fl_Printer.H>
#include <FL/Fl_Gl_Window.H>
-#include "Fl_Gl_Choice.H"
#include <FL/Fl_RGB_Image.H>
#include <FL/Fl_Shared_Image.H>
-#include "FL/Fl.H"
+#include "drivers/OpenGL/Fl_OpenGL_Display_Device.H"
-#if defined(WIN32) || defined(__APPLE__) // PORTME: Fl_Surface_Driver - platform OpenGL management
-#elif defined(FL_PORTING)
-# pragma message "FL_PORTING: implement code to read OpenGL renderings into RGB maps"
-#else
-#endif
-
-
-#if defined(__APPLE__) // PORTME: Fl_Surface_Driver - platform OpenGL management
-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 = 0; i < h; i++) {
- uchar *from = baseAddress + i * mByteWidth;
- for (int j = 0; j < w; j++, from += 4) {
-#if __ppc__
- memcpy(to, from + 1, 3);
- to += 3;
-#else
- *(to++) = *(from+2);
- *(to++) = *(from+1);
- *(to++) = *from;
-#endif
- }
- }
- delete[] baseAddress;
- return newimg;
-}
-#endif
-
-static Fl_RGB_Image* 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
- */
-{
-#if defined(__APPLE__) // PORTME: Fl_Surface_Driver - platform OpenGL management
- const int bytesperpixel = 4;
- int factor = glw->pixels_per_unit();
- if (factor > 1) {
- w *= factor; h *= factor; x *= factor; y *= factor;
- }
-#else
- const int bytesperpixel = 3;
-#endif
- 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
- 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 * bytesperpixel;
- mByteWidth = (mByteWidth + 3) & ~3; // Align to 4 bytes
- uchar *baseAddress = new uchar[mByteWidth * h];
- glReadPixels(x, glw->pixel_h() - (y+h), w, h,
-#if defined(__APPLE__) // PORTME: Fl_Surface_Driver - platform OpenGL management
- GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
-#else
- GL_RGB, GL_UNSIGNED_BYTE,
-#endif
- baseAddress);
- glPopClientAttrib();
-#if defined(__APPLE__) // PORTME: Fl_Surface_Driver - platform OpenGL management
- baseAddress = convert_BGRA_to_RGB(baseAddress, w, h, mByteWidth);
- mByteWidth = 3 * w;
-#endif
-
- // GL gives a bottom-to-top image, convert it to top-to-bottom
- uchar *tmp = new uchar[mByteWidth];
- uchar *p = baseAddress ;
- uchar *q = baseAddress + (h-1)*mByteWidth;
- for (int i = 0; i < h/2; i++, p += mByteWidth, q -= mByteWidth) {
- memcpy(tmp, p, mByteWidth);
- memcpy(p, q, mByteWidth);
- memcpy(q, tmp, mByteWidth);
- }
- delete[] tmp;
-
- Fl_RGB_Image *img = new Fl_RGB_Image(baseAddress, w, h, 3, mByteWidth);
- img->alloc_array = 1;
- return img;
-}
/**
This class will make sure that OpenGL printing/screen capture is available if fltk_gl
@@ -120,7 +34,7 @@ public:
virtual int print(Fl_Widget *w, int x, int y, int height /*useless*/) {
Fl_Gl_Window *glw = w->as_gl_window();
if (!glw) return 0;
- Fl_RGB_Image *img = capture_gl_rectangle(glw, 0, 0, glw->w(), glw->h());
+ Fl_RGB_Image *img = Fl_OpenGL_Display_Device::capture_gl_rectangle(glw, 0, 0, glw->w(), glw->h());
Fl_Shared_Image *shared = Fl_Shared_Image::get(img);
shared->scale(glw->w(), glw->h());
shared->draw(x, y);
@@ -130,7 +44,7 @@ public:
virtual Fl_RGB_Image* rectangle_capture(Fl_Widget *widget, int x, int y, int w, int h) {
Fl_Gl_Window *glw = widget->as_gl_window();
if (!glw) return NULL;
- return capture_gl_rectangle(glw, x, y, w, h);
+ return Fl_OpenGL_Display_Device::capture_gl_rectangle(glw, x, y, w, h);
}
};
diff --git a/src/drivers/OpenGL/Fl_OpenGL_Display_Device.H b/src/drivers/OpenGL/Fl_OpenGL_Display_Device.H
index 9730fc9c4..5637e6525 100644
--- a/src/drivers/OpenGL/Fl_OpenGL_Display_Device.H
+++ b/src/drivers/OpenGL/Fl_OpenGL_Display_Device.H
@@ -20,6 +20,8 @@
#include <FL/Fl_Device.H>
class Fl_OpenGL_Graphics_Driver;
+class Fl_Gl_Window;
+class Fl_RGB_Image;
/**
OpenGL Surface.
@@ -29,6 +31,7 @@ class FL_EXPORT Fl_OpenGL_Display_Device : public Fl_Surface_Device {
public:
Fl_OpenGL_Display_Device(Fl_OpenGL_Graphics_Driver *graphics_driver);
static Fl_OpenGL_Display_Device *display_device();
+ static Fl_RGB_Image* capture_gl_rectangle(Fl_Gl_Window*, int, int, int, int);
};
diff --git a/src/drivers/OpenGL/Fl_OpenGL_Display_Device.cxx b/src/drivers/OpenGL/Fl_OpenGL_Display_Device.cxx
index 707bd1e52..a9a181f7c 100644
--- a/src/drivers/OpenGL/Fl_OpenGL_Display_Device.cxx
+++ b/src/drivers/OpenGL/Fl_OpenGL_Display_Device.cxx
@@ -19,8 +19,10 @@
#include <config.h>
#include "../../config_lib.h"
#include <FL/Fl_Gl_Window.H>
+#include <FL/Fl_Image.H>
#include <FL/Fl_Device.H>
#include <FL/gl.h>
+#include <string.h>
#include "Fl_OpenGL_Graphics_Driver.H"
#include "Fl_OpenGL_Display_Device.H"
@@ -37,6 +39,120 @@ Fl_OpenGL_Display_Device::Fl_OpenGL_Display_Device(Fl_OpenGL_Graphics_Driver *gr
{
}
+#ifdef FL_CFG_GFX_QUARTZ
+
+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 = 0; i < h; i++) {
+ uchar *from = baseAddress + i * mByteWidth;
+ for (int j = 0; j < w; j++, from += 4) {
+#if __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)
+{
+ const int bytesperpixel = 4;
+ int factor = glw->pixels_per_unit();
+ if (factor > 1) {
+ w *= factor; h *= factor; x *= factor; y *= factor;
+ }
+ 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
+ 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 * bytesperpixel;
+ 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);
+ mByteWidth = 3 * w;
+
+ // GL gives a bottom-to-top image, convert it to top-to-bottom
+ uchar *tmp = new uchar[mByteWidth];
+ uchar *p = baseAddress ;
+ uchar *q = baseAddress + (h-1)*mByteWidth;
+ for (int i = 0; i < h/2; i++, p += mByteWidth, q -= mByteWidth) {
+ memcpy(tmp, p, mByteWidth);
+ memcpy(p, q, mByteWidth);
+ memcpy(q, tmp, mByteWidth);
+ }
+ delete[] tmp;
+
+ Fl_RGB_Image *img = new Fl_RGB_Image(baseAddress, w, h, 3, mByteWidth);
+ img->alloc_array = 1;
+ return img;
+
+}
+#elif defined(FL_CFG_GFX_GDI) || defined(FL_CFG_GFX_XLIB)
+
+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
+ */
+{
+ const int bytesperpixel = 3;
+ 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
+ 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 * bytesperpixel;
+ mByteWidth = (mByteWidth + 3) & ~3; // Align to 4 bytes
+ uchar *baseAddress = new uchar[mByteWidth * h];
+ glReadPixels(x, glw->pixel_h() - (y+h), w, h,
+ GL_RGB, GL_UNSIGNED_BYTE,
+ baseAddress);
+ glPopClientAttrib();
+
+ // GL gives a bottom-to-top image, convert it to top-to-bottom
+ uchar *tmp = new uchar[mByteWidth];
+ uchar *p = baseAddress ;
+ uchar *q = baseAddress + (h-1)*mByteWidth;
+ for (int i = 0; i < h/2; i++, p += mByteWidth, q -= mByteWidth) {
+ memcpy(tmp, p, mByteWidth);
+ memcpy(p, q, mByteWidth);
+ memcpy(q, tmp, mByteWidth);
+ }
+ delete[] tmp;
+
+ Fl_RGB_Image *img = new Fl_RGB_Image(baseAddress, w, h, 3, mByteWidth);
+ img->alloc_array = 1;
+ return img;
+}
+
+#elif defined(FL_PORTING)
+
+# pragma message "FL_PORTING: implement Fl_OpenGL_Display_Device::capture_gl_rectangle() for your platform"
+Fl_RGB_Image* Fl_OpenGL_Display_Device::capture_gl_rectangle(Fl_Gl_Window* glw, int x, int y, int w, int h)
+{
+ return NULL;
+}
+
+#endif
//
// End of "$Id$".
//