FLTK logo

Re: [fltk.coredev] GL root Fl_Gl_Window::draw

FLTK matrix user chat room
(using Element browser app)   FLTK gitter user chat room   GitHub FLTK Project   FLTK News RSS Feed  
  FLTK Apps      FLTK Library      Forums      Links     Login 
 All Forums  |  Back to fltk.coredev  ]
 
Previous Message ]New Message | Reply ]Next Message ]

Re: GL root Fl_Gl_Window::draw imacarthur Sep 15, 2022  
 
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 ]
 
     
Previous Message ]New Message | Reply ]Next Message ]
 
 

Comments are owned by the poster. All other content is copyright 1998-2024 by Bill Spitzak and others. This project is hosted by The FLTK Team. Please report site problems to 'erco@seriss.com'.