mirror of
https://github.com/fltk/fltk.git
synced 2026-05-24 16:36:37 +08:00
Fl_OpenGL_Graphics_Driver: create file Fl_OpenGL_Graphics_Driver_image.cxx
This commit is contained in:
@@ -488,6 +488,7 @@ set(GL_DRIVER_FILES
|
||||
drivers/OpenGL/Fl_OpenGL_Graphics_Driver_line_style.cxx
|
||||
drivers/OpenGL/Fl_OpenGL_Graphics_Driver_rect.cxx
|
||||
drivers/OpenGL/Fl_OpenGL_Graphics_Driver_vertex.cxx
|
||||
drivers/OpenGL/Fl_OpenGL_Graphics_Driver_image.cxx
|
||||
)
|
||||
if(FLTK_USE_WAYLAND)
|
||||
set(GL_DRIVER_FILES ${GL_DRIVER_FILES} drivers/Wayland/Fl_Wayland_Gl_Window_Driver.cxx)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Standard X11 font selection code for the Fast Light Tool Kit (FLTK).
|
||||
// Support for drawing text to Fl_Gl_Window for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 1998-2016 by Bill Spitzak and others.
|
||||
//
|
||||
@@ -29,7 +29,6 @@
|
||||
#include "Fl_OpenGL_Graphics_Driver.H"
|
||||
#include <FL/gl.h>
|
||||
#include <FL/Fl_Gl_Window.H>
|
||||
#include <FL/Fl_RGB_Image.H>
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/fl_draw.H>
|
||||
|
||||
@@ -224,114 +223,4 @@ void Fl_OpenGL_Graphics_Driver::text_extents(const char *str, int n, int& dx, in
|
||||
Fl_Surface_Device::pop_current();
|
||||
}
|
||||
|
||||
|
||||
void Fl_OpenGL_Graphics_Driver::cache_size(Fl_Image* img, int &width, int &height) {
|
||||
width *= pixels_per_unit_; // useful at least for Fl_SVG_Image's
|
||||
height *= pixels_per_unit_;
|
||||
}
|
||||
|
||||
|
||||
#ifndef GL_TEXTURE_RECTANGLE_ARB
|
||||
# define GL_TEXTURE_RECTANGLE_ARB 0x84F5
|
||||
#endif
|
||||
#ifndef GL_UNSIGNED_INT_8_8_8_8_REV
|
||||
# define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
|
||||
#endif
|
||||
|
||||
static GLuint compute_texture_rectangle(Fl_RGB_Image *rgb)
|
||||
{
|
||||
GLuint texName;
|
||||
glGenTextures(1, &texName);
|
||||
// save GL parameters GL_UNPACK_ROW_LENGTH and GL_UNPACK_ALIGNMENT
|
||||
GLint row_length, alignment;
|
||||
glGetIntegerv(GL_UNPACK_ROW_LENGTH, &row_length);
|
||||
glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
|
||||
// put the bitmap in a texture
|
||||
glPushAttrib(GL_TEXTURE_BIT);
|
||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texName);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, (rgb->ld() ? rgb->ld() / rgb->d() : rgb->data_w()));
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, (rgb->d() == 3 ? 1 : 4));
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, (rgb->d() == 3 ? GL_RGB : GL_RGBA8),
|
||||
rgb->data_w(), rgb->data_h(), 0,
|
||||
(rgb->d() == 3 ? GL_RGB : GL_RGBA),
|
||||
(rgb->d() == 3 ? GL_UNSIGNED_BYTE : GL_UNSIGNED_INT_8_8_8_8_REV),
|
||||
rgb->array);
|
||||
glPopAttrib();
|
||||
// restore saved GL parameters
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
|
||||
return texName;
|
||||
}
|
||||
|
||||
|
||||
void Fl_OpenGL_Graphics_Driver::draw_rgb(Fl_RGB_Image *img,
|
||||
int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
int X, Y, W, H;
|
||||
// Don't draw an empty image. Gray-scale image drawing not implemented yet.
|
||||
if (!img->d() || !img->array || img->d() < 3) {
|
||||
Fl_Graphics_Driver::draw_empty(img, XP, YP);
|
||||
return;
|
||||
}
|
||||
if (start_image(img, XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
|
||||
return;
|
||||
}
|
||||
Fl_RGB_Image *partial_rgb = NULL;
|
||||
if (cx || cy || W < img->w() || H < img->h()) { // Partial image drawing.
|
||||
int d = img->d();
|
||||
int ld = d * img->data_w();
|
||||
float sx = img->data_w() / float(img->w()), sy = img->data_h() / float(img->h());
|
||||
cx *= sx; cy *= sy;
|
||||
partial_rgb = new Fl_RGB_Image(img->array + cy * ld + cx * d, W * sx, H * sy, d, ld);
|
||||
img = partial_rgb;
|
||||
}
|
||||
GLuint texName = compute_texture_rectangle(img);
|
||||
// GL_TRANSFORM_BIT for GL_PROJECTION
|
||||
// GL_TEXTURE_BIT for GL_TEXTURE_RECTANGLE_ARB
|
||||
glPushAttrib(GL_TRANSFORM_BIT | GL_TEXTURE_BIT /*|GL_COLOR_BUFFER_BIT*/);
|
||||
//setup matrices
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glColor4ub(0xff, 0xff, 0xff, 0xff); // the color drawn through the texture seen as a kind of mask
|
||||
|
||||
float winw = Fl_Window::current()->as_gl_window()->pixel_w();
|
||||
float winh = Fl_Window::current()->as_gl_window()->pixel_h();
|
||||
|
||||
float R = 2;
|
||||
glScalef(R/winw, R/winh, 1.0f);
|
||||
glTranslatef(-winw/R, -winh/R, 0.0f);
|
||||
float s = Fl_Window::current()->as_gl_window()->pixels_per_unit();
|
||||
int HH = s * H, WW = s * W;
|
||||
float ox = s * X;
|
||||
float oy = winh - s * Y;
|
||||
glEnable(GL_TEXTURE_RECTANGLE_ARB);
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texName);
|
||||
//write the texture on screen
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.0f, 0.0f); // draw lower left in world coordinates
|
||||
glVertex2f(ox, oy);
|
||||
glTexCoord2f(0.0f, (GLfloat)img->data_h()); // draw upper left in world coordinates
|
||||
glVertex2f(ox, oy - HH);
|
||||
glTexCoord2f((GLfloat)img->data_w(), (GLfloat)img->data_h()); // draw upper right in world coordinates
|
||||
glVertex2f(ox + WW, oy - HH);
|
||||
glTexCoord2f((GLfloat)img->data_w(), 0.0f); // draw lower right in world coordinates
|
||||
glVertex2f(ox + WW, oy);
|
||||
glEnd();
|
||||
glDeleteTextures(1, &texName);
|
||||
color(color()); // reset current color
|
||||
// reset original matrices
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glPopAttrib(); // GL_TRANSFORM_BIT | GL_TEXTURE_BIT
|
||||
if (partial_rgb) delete partial_rgb;
|
||||
}
|
||||
|
||||
|
||||
void Fl_OpenGL_Graphics_Driver::draw_pixmap(Fl_Pixmap *img,
|
||||
int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
Fl_RGB_Image rgb(img);
|
||||
draw_rgb(&rgb, XP, YP, WP, HP, cx, cy);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
//
|
||||
// Support for drawing images to Fl_Gl_Window for the Fast Light Tool Kit (FLTK).
|
||||
//
|
||||
// Copyright 2026 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
|
||||
// file is missing or damaged, see the license at:
|
||||
//
|
||||
// https://www.fltk.org/COPYING.php
|
||||
//
|
||||
// Please see the following page on how to report bugs and issues:
|
||||
//
|
||||
// https://www.fltk.org/bugs.php
|
||||
//
|
||||
|
||||
#include "Fl_OpenGL_Graphics_Driver.H"
|
||||
#include <FL/gl.h>
|
||||
#include <FL/Fl_Gl_Window.H>
|
||||
#include <FL/Fl_RGB_Image.H>
|
||||
#include <FL/Fl.H>
|
||||
|
||||
|
||||
void Fl_OpenGL_Graphics_Driver::cache_size(Fl_Image* img, int &width, int &height) {
|
||||
width *= pixels_per_unit_; // useful at least for Fl_SVG_Image's
|
||||
height *= pixels_per_unit_;
|
||||
}
|
||||
|
||||
|
||||
#ifndef GL_TEXTURE_RECTANGLE_ARB
|
||||
# define GL_TEXTURE_RECTANGLE_ARB 0x84F5
|
||||
#endif
|
||||
#ifndef GL_UNSIGNED_INT_8_8_8_8_REV
|
||||
# define GL_UNSIGNED_INT_8_8_8_8_REV 0x8367
|
||||
#endif
|
||||
|
||||
static GLuint compute_texture_rectangle(Fl_RGB_Image *rgb)
|
||||
{
|
||||
GLuint texName;
|
||||
glGenTextures(1, &texName);
|
||||
// save GL parameters GL_UNPACK_ROW_LENGTH and GL_UNPACK_ALIGNMENT
|
||||
GLint row_length, alignment;
|
||||
glGetIntegerv(GL_UNPACK_ROW_LENGTH, &row_length);
|
||||
glGetIntegerv(GL_UNPACK_ALIGNMENT, &alignment);
|
||||
// put the bitmap in a texture
|
||||
glPushAttrib(GL_TEXTURE_BIT);
|
||||
glBindTexture (GL_TEXTURE_RECTANGLE_ARB, texName);
|
||||
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, (rgb->ld() ? rgb->ld() / rgb->d() : rgb->data_w()));
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, (rgb->d() == 3 ? 1 : 4));
|
||||
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, (rgb->d() == 3 ? GL_RGB : GL_RGBA8),
|
||||
rgb->data_w(), rgb->data_h(), 0,
|
||||
(rgb->d() == 3 ? GL_RGB : GL_RGBA),
|
||||
(rgb->d() == 3 ? GL_UNSIGNED_BYTE : GL_UNSIGNED_INT_8_8_8_8_REV),
|
||||
rgb->array);
|
||||
glPopAttrib();
|
||||
// restore saved GL parameters
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, row_length);
|
||||
glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);
|
||||
return texName;
|
||||
}
|
||||
|
||||
|
||||
void Fl_OpenGL_Graphics_Driver::draw_rgb(Fl_RGB_Image *img,
|
||||
int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
int X, Y, W, H;
|
||||
// Don't draw an empty image. Gray-scale image drawing not implemented yet.
|
||||
if (!img->d() || !img->array || img->d() < 3) {
|
||||
Fl_Graphics_Driver::draw_empty(img, XP, YP);
|
||||
return;
|
||||
}
|
||||
if (start_image(img, XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
|
||||
return;
|
||||
}
|
||||
Fl_RGB_Image *partial_rgb = NULL;
|
||||
if (cx || cy || W < img->w() || H < img->h()) { // Partial image drawing.
|
||||
int d = img->d();
|
||||
int ld = d * img->data_w();
|
||||
float sx = img->data_w() / float(img->w()), sy = img->data_h() / float(img->h());
|
||||
cx *= sx; cy *= sy;
|
||||
partial_rgb = new Fl_RGB_Image(img->array + cy * ld + cx * d, W * sx, H * sy, d, ld);
|
||||
img = partial_rgb;
|
||||
}
|
||||
GLuint texName = compute_texture_rectangle(img);
|
||||
// GL_TRANSFORM_BIT for GL_PROJECTION
|
||||
// GL_TEXTURE_BIT for GL_TEXTURE_RECTANGLE_ARB
|
||||
glPushAttrib(GL_TRANSFORM_BIT | GL_TEXTURE_BIT);
|
||||
//setup matrices
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPushMatrix();
|
||||
glLoadIdentity();
|
||||
glColor4ub(0xff, 0xff, 0xff, 0xff); // the color drawn through the texture seen as a kind of mask
|
||||
|
||||
float winw = Fl_Window::current()->as_gl_window()->pixel_w();
|
||||
float winh = Fl_Window::current()->as_gl_window()->pixel_h();
|
||||
|
||||
float R = 2;
|
||||
glScalef(R/winw, R/winh, 1.0f);
|
||||
glTranslatef(-winw/R, -winh/R, 0.0f);
|
||||
float s = Fl_Window::current()->as_gl_window()->pixels_per_unit();
|
||||
int HH = s * H, WW = s * W;
|
||||
float ox = s * X;
|
||||
float oy = winh - s * Y;
|
||||
glEnable(GL_TEXTURE_RECTANGLE_ARB);
|
||||
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texName);
|
||||
//write the texture on screen
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(0.0f, 0.0f); // draw lower left in world coordinates
|
||||
glVertex2f(ox, oy);
|
||||
glTexCoord2f(0.0f, (GLfloat)img->data_h()); // draw upper left in world coordinates
|
||||
glVertex2f(ox, oy - HH);
|
||||
glTexCoord2f((GLfloat)img->data_w(), (GLfloat)img->data_h()); // draw upper right in world coordinates
|
||||
glVertex2f(ox + WW, oy - HH);
|
||||
glTexCoord2f((GLfloat)img->data_w(), 0.0f); // draw lower right in world coordinates
|
||||
glVertex2f(ox + WW, oy);
|
||||
glEnd();
|
||||
glDeleteTextures(1, &texName);
|
||||
color(color()); // reset current color
|
||||
// reset original matrices
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glPopAttrib(); // GL_TRANSFORM_BIT | GL_TEXTURE_BIT
|
||||
if (partial_rgb) delete partial_rgb;
|
||||
}
|
||||
|
||||
|
||||
void Fl_OpenGL_Graphics_Driver::draw_pixmap(Fl_Pixmap *img,
|
||||
int XP, int YP, int WP, int HP, int cx, int cy) {
|
||||
Fl_RGB_Image rgb(img);
|
||||
draw_rgb(&rgb, XP, YP, WP, HP, cx, cy);
|
||||
}
|
||||
+2
-2
@@ -23,7 +23,7 @@
|
||||
class image_background_box : public Fl_Widget {
|
||||
public:
|
||||
image_background_box(int x, int y, int w, int h) : Fl_Widget(x, y, w, h, NULL) {}
|
||||
void draw() {
|
||||
void draw() override {
|
||||
gl_color(FL_WHITE);
|
||||
gl_rectf(x(), y(), w(), h());
|
||||
gl_color(color());
|
||||
@@ -94,7 +94,7 @@ void chooser_cb(Fl_Widget *, Gl_Image_Window *mainwin) {
|
||||
char *fname = fl_file_chooser("select image file", "*.{png,jpg,gif,svg,svgz}", NULL, 0);
|
||||
if (fname) {
|
||||
Fl_Shared_Image *shared = Fl_Shared_Image::get(fname);
|
||||
if (!shared->fail()) {
|
||||
if (shared && !shared->fail()) {
|
||||
mainwin->copy_label(fname);
|
||||
mainwin->set_image(shared);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user