|
|
On Wednesday, 14 September 2022 at 20:41:51 UTC+1 Gonzalo wrote:
That *almost* works. What is missing is giving the button a transparent or semi-transparent color, like in the cube.cxx demo. I would need that, or a FL_STENCIL on the window, so I can implement drawing in the window (with erasing with the stencil).
OK, so in looking for some old code to answer a question on fltk.general (Hi Gonzalo...) I found another bit of code I had.
If the question is about drawing a translucent FL window over a GL surface, I have code for this... Here's an example - it's GL2, but should Just Work.
// // GL portions derived from: // OpenGL example showing text on a rotating 3D object. // erco 03/03/06 // #include <FL/x.H> #include <FL/Fl.H> #include <FL/Fl_Window.H> #include <FL/Fl_Double_Window.H> #include <FL/Fl_Gl_Window.H> #include <FL/Fl_Button.H> #include <FL/Fl_Choice.H> #include <FL/gl.h> #include <GL/glu.h> #include <string.h> #include <stdio.h>
// First, Greg's 2D-text on GL scene expample, to give a dynamic GL scene to draw the dialog on top of // Tetrahedron points #define TOP 0, 1, 0 #define RIGHT 1, -1, 1 #define LEFT -1, -1, 1 #define BACK 0, -1, -1
class MyGlWindow : public Fl_Gl_Window { float rotangle; void draw() { // First time? init viewport, etc. if (!valid()) { valid(1); // Initialize GL glClearColor(0.0, 0.0, 0.0, 0.0); glClearDepth(1.0); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glShadeModel(GL_FLAT); } glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); // Position camera/viewport init glMatrixMode(GL_PROJECTION); glLoadIdentity(); glViewport(0,0,w(),h()); gluPerspective(45.0, (float)w()/(float)h(), 1.0, 10.0); glTranslatef(0.0, 0.0, -5.0); // Position object glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glRotatef(rotangle, 1, 0, 1); glRotatef(rotangle, 0, 1, 0); glRotatef(rotangle, 1, 1, 1); // Draw tetrahedron glColor3f(1.0, 0.0, 0.0); glBegin(GL_POLYGON); glVertex3f(TOP); glVertex3f(RIGHT); glVertex3f(LEFT); glEnd(); glColor3f(0.0, 1.0, 0.0); glBegin(GL_POLYGON); glVertex3f(TOP); glVertex3f(BACK); glVertex3f(RIGHT); glEnd(); glColor3f(0.0, 0.0, 1.0); glBegin(GL_POLYGON); glVertex3f(TOP); glVertex3f(LEFT); glVertex3f(BACK); glEnd(); glColor3f(0.5, 0.5, 0.5); glBegin(GL_POLYGON); glVertex3f(RIGHT); glVertex3f(BACK); glVertex3f(LEFT); glEnd(); // Print tetrahedron's points on object // Disable depth buffer while drawing text, // so text draws /over/ object. // glDisable(GL_DEPTH_TEST); { const char *p; gl_font(1, 12); glColor3f(1.0, 1.0, 1.0); glRasterPos3f(TOP); p = "+ top"; gl_draw(p, strlen(p)); glRasterPos3f(LEFT); p = "+ left"; gl_draw(p, strlen(p)); glRasterPos3f(RIGHT); p = "+ right"; gl_draw(p, strlen(p)); glRasterPos3f(BACK); p = "+ back"; gl_draw(p, strlen(p)); } glEnable(GL_DEPTH_TEST); // Print rotangle value at fixed position at lower left char s[40]; sprintf(s, "ROT=%.2f", rotangle); glLoadIdentity(); glRasterPos2f(-3,-2); gl_draw(s, strlen(s)); } static void Timer_CB(void *userdata) { MyGlWindow *o = (MyGlWindow*)userdata; o->rotangle += 1.0; o->redraw(); Fl::repeat_timeout(1.0/24.0, Timer_CB, userdata); // 24fps } public: // CONSTRUCTOR MyGlWindow(int X,int Y,int W,int H,const char*L=0) : Fl_Gl_Window(X,Y,W,H,L) { rotangle = 0; Fl::add_timeout(3.0, Timer_CB, (void*)this); // wait 3 secs before animation begins } }; ///////////////////////////////////////////////////////////////////////////////// // Next set up the translucent dialog window class translucent_dialog : public Fl_Double_Window { public:
translucent_dialog(int X, int Y, int W, int H, const char *L = 0) : Fl_Double_Window(X, Y, W, H, L), win_alpha_(255) { clear_border(); box(FL_FLAT_BOX); } // constructor
void set_alpha(int new_alpha) { if (new_alpha < 0) { win_alpha_ = 0; } else if (new_alpha > 255) { win_alpha_ = 255; } else { win_alpha_ = new_alpha; }
#if defined (_WIN32) HWND hwnd = fl_xid(this); LONG_PTR exstyle = GetWindowLongPtr(hwnd, GWL_EXSTYLE); if (!(exstyle & WS_EX_LAYERED)) { SetWindowLongPtr(hwnd, GWL_EXSTYLE, exstyle | WS_EX_LAYERED); } SetLayeredWindowAttributes(hwnd, 0, BYTE(win_alpha_), LWA_ALPHA); // SetLayeredWindowAttributes(hwnd, RGB(0, 0, 0), 0, LWA_COLORKEY); #elif defined(__APPLE__) double alpha = (double)win_alpha_ / 255.0; setWindowTransparency(this, alpha); // defined in transp_cocoa.mm #else double alpha = (double)win_alpha_ / 255.0; uint32_t cardinal_alpha = (uint32_t)(UINT32_MAX * alpha); Atom atom = XInternAtom(fl_display, "_NET_WM_WINDOW_OPACITY", False); XChangeProperty(fl_display, fl_xid(this), atom, XA_CARDINAL, 32, PropModeReplace, (unsigned char *)&cardinal_alpha, 1); #endif } // set_alpha
int current_alpha (void) { return win_alpha_; } // current_alpha
private: int win_alpha_; }; // class translucent_dialog
///////////////////////////////////////////////////////////////////////////////// static Fl_Window *main_win = NULL; static translucent_dialog *t_dialog = NULL;
///////////////////////////////////////////////////////////////////////////////// static void cb_menu_bt(Fl_Button *, void *) { t_dialog->position(main_win->x_root() + 200, main_win->y_root() + 90); t_dialog->show(); t_dialog->set_alpha(127); } // cb_menu_bt
///////////////////////////////////////////////////////////////////////////////// static void cb_hide_bt(Fl_Button *, void *) { t_dialog->hide(); } // cb_hide_bt
///////////////////////////////////////////////////////////////////////////////// static void cb_quit_bt(Fl_Button *, void *) { // close all windows and exit if (t_dialog) t_dialog->hide(); if (main_win) main_win->hide(); } // cb_quit_bt
/////////////////////////////////////////////////////////////////////////////////// MAIN int main(int argc, char **argv) { main_win = new Fl_Window (640, 480, "Menu over GL scene test"); main_win->begin();
MyGlWindow mygl(10, 10, main_win->w()-20, main_win->h()-90); mygl.end();
Fl_Button *menu_bt = new Fl_Button(10, 430, 75, 35, "Menu"); menu_bt->callback((Fl_Callback *)cb_menu_bt);
Fl_Button *quit_bt = new Fl_Button(555, 430, 75, 35, "Exit"); quit_bt->callback((Fl_Callback *)cb_quit_bt);
main_win->end(); main_win->show(argc, argv);
// Create the translucent dialog t_dialog = new translucent_dialog (main_win->x_root() + 200, main_win->y_root() + 90, 240, 300); t_dialog->begin(); Fl_Choice *td_choice = new Fl_Choice(60, 25, 90, 25, "Test "); td_choice->down_box(FL_BORDER_BOX); td_choice->add("Line 1"); td_choice->add("Line 2"); td_choice->add("Line 3"); td_choice->add("Line 4"); td_choice->add("Line 5");
Fl_Button *bt = new Fl_Button(60, 60, 75, 35, "Test"); bt = new Fl_Button(60, 95, 75, 35, "Test"); bt = new Fl_Button(60, 130, 75, 35, "Test");
Fl_Button *hide_bt = new Fl_Button(155, 255, 75, 35, "Hide"); hide_bt->callback((Fl_Callback *)cb_hide_bt); t_dialog->end();
return Fl::run(); } // main
// end of file //
Also need to have an implementation of setWindowTransparency(this, alpha); for macOS, it looks like this:
#ifdef __APPLE__ /* The OSX Cocoa stub to do window transparency... */
#include <FL/x.H> #include <FL/Fl.H> #include <FL/Fl_Double_Window.H>
#import <Cocoa/Cocoa.h>
void setWindowTransparency(Fl_Window *w, double alpha) { [fl_xid(w) setAlphaValue:alpha]; } #endif // (__APPLE__)
/* end of file */
--
You received this message because you are subscribed to the Google Groups "fltk.coredev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to fltkcoredev+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/fltkcoredev/32fa0406-b151-48af-80cf-7229f32de30en%40googlegroups.com.
[ Direct Link to Message ] | |
|
| |