diff options
| -rw-r--r-- | src/Fl_Device.cxx | 1 | ||||
| -rw-r--r-- | src/Fl_Gl_Device_Plugin.cxx | 9 | ||||
| -rw-r--r-- | src/Fl_Gl_Window.cxx | 47 | ||||
| -rw-r--r-- | src/drivers/OpenGL/Fl_OpenGL_Display_Device.H | 5 | ||||
| -rw-r--r-- | src/drivers/OpenGL/Fl_OpenGL_Display_Device.cxx | 61 |
5 files changed, 53 insertions, 70 deletions
diff --git a/src/Fl_Device.cxx b/src/Fl_Device.cxx index c0ca99b57..c4f1dec36 100644 --- a/src/Fl_Device.cxx +++ b/src/Fl_Device.cxx @@ -24,6 +24,7 @@ +- Fl_Surface_Device: any kind of surface that we can draw onto -> uses an Fl_Graphics_Driver | +- Fl_Display_Device: some kind of video device (one object per app) + +- Fl_OpenGL_Display_Device: supports adding FLTK child widgets to an Fl_Gl_Window +- Fl_Widget_Surface: any FLTK widget can be drawn to it | +- Fl_Copy_Surface: draw into the clipboard (in vectorial form if the platform supports it) diff --git a/src/Fl_Gl_Device_Plugin.cxx b/src/Fl_Gl_Device_Plugin.cxx index 79188ed66..6abdbb514 100644 --- a/src/Fl_Gl_Device_Plugin.cxx +++ b/src/Fl_Gl_Device_Plugin.cxx @@ -1,7 +1,7 @@ // // implementation of class Fl_Gl_Device_Plugin for the Fast Light Tool Kit (FLTK). // -// Copyright 2010-2016 by Bill Spitzak and others. +// Copyright 2010-2022 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -17,7 +17,8 @@ #include <config.h> #include <FL/Fl_Gl_Window.H> #include <FL/Fl_RGB_Image.H> -#include "drivers/OpenGL/Fl_OpenGL_Display_Device.H" +#include <FL/Fl_Device.H> +#include "Fl_Gl_Window_Driver.H" /** @@ -31,7 +32,7 @@ public: virtual int print(Fl_Widget *w) { Fl_Gl_Window *glw = w->as_gl_window(); if (!glw) return 0; - Fl_RGB_Image *img = Fl_OpenGL_Display_Device::capture_gl_rectangle(glw, 0, 0, glw->w(), glw->h()); + Fl_RGB_Image *img = Fl_Gl_Window_Driver::driver(glw)->capture_gl_rectangle(0, 0, glw->w(), glw->h()); img->scale(glw->w(), glw->h()); img->draw(0, 0); delete img; @@ -40,7 +41,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 Fl_OpenGL_Display_Device::capture_gl_rectangle(glw, x, y, w, h); + return Fl_Gl_Window_Driver::driver(glw)->capture_gl_rectangle(x, y, w, h); } }; diff --git a/src/Fl_Gl_Window.cxx b/src/Fl_Gl_Window.cxx index f0e608cda..c5cda4ab2 100644 --- a/src/Fl_Gl_Window.cxx +++ b/src/Fl_Gl_Window.cxx @@ -1,7 +1,7 @@ // // OpenGL window code for the Fast Light Tool Kit (FLTK). // -// Copyright 1998-2021 by Bill Spitzak and others. +// Copyright 1998-2022 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -341,7 +341,7 @@ void Fl_Gl_Window::draw_overlay() {} void Fl_Gl_Window::draw_begin() { Fl_Surface_Device::push_current( Fl_OpenGL_Display_Device::display_device() ); - Fl_OpenGL_Graphics_Driver *drv = (Fl_OpenGL_Graphics_Driver*)fl_graphics_driver; + Fl_OpenGL_Graphics_Driver *drv = (Fl_OpenGL_Graphics_Driver*)Fl_Surface_Device::surface()->driver(); drv->pixels_per_unit_ = pixels_per_unit(); if (!valid()) { @@ -543,6 +543,49 @@ Fl_Font_Descriptor** Fl_Gl_Window_Driver::fontnum_to_fontdescriptor(int fnum) { return &(fl_fonts[fnum].first); } +/* Captures a rectangle of a Fl_Gl_Window and returns it as an RGB image. + This is the platform-independent version. Some platforms may override 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 + 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); + // + float s = glw->pixels_per_unit(); + if (s != 1) { + x = int(x * s); y = int(y * s); w = int(w * s); h = int(h * s); + } + // Read a block of pixels from the frame buffer + int mByteWidth = w * 3; + 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; +} + /** \} \endcond diff --git a/src/drivers/OpenGL/Fl_OpenGL_Display_Device.H b/src/drivers/OpenGL/Fl_OpenGL_Display_Device.H index 8e6d1c8bb..2245ee938 100644 --- a/src/drivers/OpenGL/Fl_OpenGL_Display_Device.H +++ b/src/drivers/OpenGL/Fl_OpenGL_Display_Device.H @@ -1,7 +1,7 @@ // // Definition of class Fl_OpenGL_Display_Device for the Fast Light Tool Kit (FLTK). // -// Copyright 2010-2016 by Bill Spitzak and others. +// Copyright 2010-2022 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -17,8 +17,6 @@ #include <FL/Fl_Device.H> class Fl_OpenGL_Graphics_Driver; -class Fl_Gl_Window; -class Fl_RGB_Image; /** OpenGL Surface. @@ -28,5 +26,4 @@ class FL_EXPORT Fl_OpenGL_Display_Device : public Fl_Surface_Device { Fl_OpenGL_Display_Device(Fl_OpenGL_Graphics_Driver *graphics_driver); public: 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 1d0b25ccf..007408a15 100644 --- a/src/drivers/OpenGL/Fl_OpenGL_Display_Device.cxx +++ b/src/drivers/OpenGL/Fl_OpenGL_Display_Device.cxx @@ -1,7 +1,7 @@ // // implementation of class Fl_OpenGL_Display_Device for the Fast Light Tool Kit (FLTK). // -// Copyright 2010-2017 by Bill Spitzak and others. +// Copyright 2010-2022 by Bill Spitzak and others. // // This library is free software. Distribution and use rights are outlined in // the file "COPYING" which should have been included with this file. If this @@ -14,20 +14,9 @@ // https://www.fltk.org/bugs.php // -#include <config.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> - #include "Fl_OpenGL_Graphics_Driver.H" #include "Fl_OpenGL_Display_Device.H" -// TODO: much of Fl_Gl_Choice should probably go here - Fl_OpenGL_Display_Device *Fl_OpenGL_Display_Device::display_device() { static Fl_OpenGL_Display_Device *display = new Fl_OpenGL_Display_Device(new Fl_OpenGL_Graphics_Driver()); return display; @@ -37,51 +26,3 @@ Fl_OpenGL_Display_Device::Fl_OpenGL_Display_Device(Fl_OpenGL_Graphics_Driver *gr : Fl_Surface_Device(graphics_driver) { } - -Fl_RGB_Image* Fl_OpenGL_Display_Device::capture_gl_rectangle(Fl_Gl_Window* glw, int x, int y, int w, int h) -{ - return Fl_Gl_Window_Driver::driver(glw)->capture_gl_rectangle(x, y, w, h); -} - -/* 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 - 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); - // - float s = glw->pixels_per_unit(); - if (s != 1) { - x = int(x * s); y = int(y * s); w = int(w * s); h = int(h * s); - } - // Read a block of pixels from the frame buffer - int mByteWidth = w * 3; - 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; -} |
