c++ - 强制 FLTK 在没有事件句柄的情况下重绘

标签 c++ event-handling redraw fltk

我正在使用 Fltk 渲染 openGL 图形。目前我正在调试一个由堆排序函数排序的全局数组。我的目的是在堆排序函数中每次交换元素后查看元素的图形交换。但我不想每次在交换并在断点处等待后需要重绘时都从 FLTK event_handle 捕获事件。 (heapsort函数和opengl渲染部分在2个不同的线程中运行(如果这不必说的话))。 所以我的第一次尝试是使用:

Fl::add_timeout(1.0, MyRedrawCallback, (void *)&myWindow);

Fl::run();

void MyRedrawCallback(void *myWindow)

{

    MyWindow *pMyWindow;

    pMyWindow = (MyWindow *) myWindow;
    pMyWindow->redraw();
    Fl::repeat_timeout(1.0, MyRedrawCallback, (void *)&pMyWindow);
}

但是每次第二次调用回调时,我都会收到“访问冲突读数”

我建议 FL::run 启动一个不同的线程,所以也许第一次仍然在同一个线程中,因此重绘的地址仍然可用,但之后我在不同的线程中,地址处的函数是这不是我所期待的吗?!

但我已经采取了不同的方式,因为我不确定我什至不能以这种方式使用超时。 所以我正在寻找一种方法来获取一个事件,该事件等于“设置耗时量”或“没有发生任何事情......”,但没有这样的句柄,我是对的吗?

最后有没有办法让 FLTK 在事件循环之外执行命令?或者有其他方法可以解决我的问题吗?

最佳答案

请看一下以下示例,取自此处:http://seriss.com/people/erco/fltk/#OpenGlInterp

#include <FL/Fl.H>
#include <FL/Fl_Gl_Window.H>
#include <FL/gl.h>
#include <math.h>

//
// Demonstrate interpolating shapes
// erco 06/10/05
//

class Playback : public Fl_Gl_Window {
    int frame;
    // Linear interpolation between two values based on 'frac' (0.0=a, 1.0=b)
    float Linterp(float frac, float a, float b) {
        return( a + ( frac * (b - a) ));
    }
    // Sinusoidal easein/easeout interpolation between two values based on 'frac' (0.0=a, 1.0=b)
    float SinInterp(float frac, float a, float b) {
        float pi = 3.14159;
        frac = (sin(pi/2 + frac*pi ) + 1.0 ) / 2.0;     // 0 ~ 1 -> 0 ~ 1
        return(Linterp(frac,a,b));
    }
    // DRAW SIMPLE SHAPE INTERPOLATION
    //     Interpolation is based on the current frame number
    //
    void DrawShape(int frame) {
        // Calculate a fraction that represents the frame# being shown
        float frac = ( frame % 48 ) / 48.0 * 2;
        if ( frac > 1.0 ) frac = 2.0-frac;      // saw tooth wave:  "/\/\/\"

        static float a_xy[9][2] = {
            { -.5, -1. }, { 0.0, -.5 }, { -.5, -1. }, { 0.0, -.5 },
            { 0.0, 0.0 },
            { 0.0, -.5 }, { +.5, -1. }, { 0.0, -.5 }, { +.5, -1. },
        };
        static float b_xy[9][2] = {
            { -.25, -1. }, { -.50, -.75 }, { -.75, -1.0 }, { -.50, -.75 },
            { 0.0, 0.0 },
            { +.50, -.75 }, { +.75, -1.0 }, { +.50, -.75 }, { +.25, -1.0 }
        };
        // Linterp a and b to form new shape c
        float c_xy[9][2];
        for ( int i=0; i<9; i++ )
            for ( int xy=0; xy<2; xy++ )
                c_xy[i][xy] = SinInterp(frac, a_xy[i][xy], b_xy[i][xy]);
        // Draw shape
        glColor3f(1.0, 1.0, 1.0);
        glBegin(GL_LINE_STRIP);
        for ( int i=0; i<9; i++ )
            glVertex2f(c_xy[i][0], c_xy[i][1]);
        glEnd();
    }
    // DRAW THE WIDGET
    //    Each time we're called, assume
    //
    void draw() {
        if (!valid()) {
            valid(1);
            glLoadIdentity();
            glViewport(0,0,w(),h());
        }
        glClear(GL_COLOR_BUFFER_BIT);
        // Draw shape 4x, rotated at 90 degree positions
        glPushMatrix();
            DrawShape(frame); glRotatef(90.0, 0, 0, 1);
            DrawShape(frame); glRotatef(90.0, 0, 0, 1);
            DrawShape(frame); glRotatef(90.0, 0, 0, 1);
            DrawShape(frame);
        glPopMatrix();
        // Advance frame counter
        ++frame;
    }
    // 24 FPS TIMER CALLBACK
    //     Called 24x per second to redraw the widget
    //
    static void Timer_CB(void *userdata) {
        Playback *pb = (Playback*)userdata;
        pb->redraw();
        Fl::repeat_timeout(1.0/24.0, Timer_CB, userdata);
    }
public:
    // Constructor
    Playback(int X,int Y,int W,int H,const char*L=0) : Fl_Gl_Window(X,Y,W,H,L) {
        frame = 0;
        Fl::add_timeout(1.0/24.0, Timer_CB, (void*)this);       // 24fps timer
        end();
    }
};

int main() {
     Fl_Window win(500, 500);
     Playback  playback(10, 10, win.w()-20, win.h()-20);
     win.resizable(&playback);
     win.show();
     return(Fl::run());
}

这个例子 more/less 正是你想要的。 Greg Ercolano 在他的网站上有更多 FLTK 示例。我建议看看http://seriss.com/people/erco/fltk/ .

关于c++ - 强制 FLTK 在没有事件句柄的情况下重绘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14565470/

相关文章:

c++ - std::is_constructible 为私有(private)构造函数返回不一致的值

c++ - std::optional 中不可复制的容器

c# - LiveCharts WPF 使用实时数据慢。提高 LiveCharts 实时绘图性能

c# - 如何取消订阅使用 lambda 表达式的事件?

c# - PictureBox 在 RotateFlipType 之后不重绘,但它使用断点

javascript - 在进行繁重的 JavaScript 处理时强制 HTML5 Canvas 重绘?

c++ - Visual Studio "The debug worker process exited unexpectedly"每次运行都在同一个断点上

c++ - 我如何将多态属性与 boost::spirit::qi 解析器一起使用?

events - 事件发生时出现 IllegalArgumentException,javafx

javascript - 在 Firefox、IE 和 Chrome 中检测窗口 onblur() 事件?