diff options
| author | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2022-08-18 08:53:19 +0200 |
|---|---|---|
| committer | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2022-08-18 08:53:19 +0200 |
| commit | f927a3047c84be70387c0292f93d02aeb357f304 (patch) | |
| tree | 3cdd070744d000a2fd68ac39557797436abd9e4d /src/Fl_Gl_Window.cxx | |
| parent | 5227ee09a3fdd7d555f56cf7c9053dc42638d6cb (diff) | |
Simplify class Fl_OpenGL_Display_Device.
Diffstat (limited to 'src/Fl_Gl_Window.cxx')
| -rw-r--r-- | src/Fl_Gl_Window.cxx | 47 |
1 files changed, 45 insertions, 2 deletions
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 |
