作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用 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甚至在eventloop之外执行命令呢?还是有其他方法可以解决我的问题?
最佳答案
请查看以下示例,取自此处: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());
}
此示例或多或少完全符合您的要求。 Greg Ercolano 在他的网站上有更多 FLTK 示例。我建议看看 http://seriss.com/people/erco/fltk/ .
关于c++ - 强制 FLTK 在没有事件句柄的情况下重绘,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14565470/
我是一名优秀的程序员,十分优秀!