2020-10-11

opengl 里面的 callback function

一、回调函数的意义:

打个比方,有一家旅馆提供叫醒服务,但是要求旅客自己决定叫醒的方法。可以是打客房电话,也可以是派服务员去敲门,睡得死怕耽误事的,还可以要求往自己头上浇盆水。这里,“叫醒”这个行为是旅馆提供的,相当于库函数,但是叫醒的方式是由旅客决定并告诉旅馆的,也就是回调函数。而旅客告诉旅馆怎么叫醒自己的动作,也就是把回调函数传入库函数的动作,称为 登记回调函数(to register a callback function)。

在这里插入图片描述
可以说,回调函数就是在main函数里调用函数,但是传的参数是之前定义的函数。

二、callback function 在opengl中的应用


#include <GLUT/GLUT.h>

typedef struct {GLfloat x, y;} point;
point p0={0,50};
GLfloat finishx=300;


void display(void){
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    
    gluOrtho2D(0, 600, 0, 400);
    
    glClearColor(0, 0, 1, 1);
    glClear(GL_COLOR_BUFFER_BIT);
    
    glColor3f(1, 1, 1);
    glBegin(GL_LINES);
        glVertex2f(finishx, 50);
        glVertex2f(finishx, 350);
    glEnd();
    
    glColor3f(0, 1, 0);
    glBegin(GL_POLYGON);
        glVertex2f(0,0);
        glVertex2f(0,50);
        glVertex2f(600,50);
        glVertex2f(600,0);
    glEnd();
    
    glColor3f(1,0,0);
    glBegin(GL_POLYGON);
        glVertex2f(p0.x,p0.y);
        glVertex2f(p0.x,p0.y+20);
        glVertex2f(p0.x+30,p0.y+20);
        glVertex2f(p0.x+30,p0.y);
    glEnd();
    
    glutSwapBuffers();
}


//task2
GLfloat step=10; // declare step
int time_interval=16; // declare refresh interval in ms


void when_in_mainloop() { // idle callback function
    glutPostRedisplay(); // force OpenGL to redraw the current window
}


void OnTimer(int value) {
    p0.x+=step;
    if(p0.x>=600)
        p0.x=0;
    else if(p0.x<=0)
        p0.x=599;
// when_in_mainloop();
    glutTimerFunc(time_interval, OnTimer, 1);
}


//task3
void keyboard_input(unsigned char key, int x, int y) {// keyboard interaction
    if(key=='q' || key=='Q')
        exit(0);
    else if(key=='f' || key=='F')// change direction of movement
        step=-step;
    else if(key=='s' || key=='S')// stop
        step=0;
    else if(key=='r' || key=='R')// set step
        step=10;
}

//task4

void mouse_input(int button, int state, int x, int y) { // mouse interaction
    if(state==GLUT_DOWN && button==GLUT_LEFT_BUTTON && step>=-15)
        step-=1; // decrement step
    else if(state==GLUT_DOWN && button==GLUT_RIGHT_BUTTON && step<=15)
        step+=1; // increment step
}

int main(int argc,char** argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowPosition(100,100);
    glutInitWindowSize(600,400);
    glutCreateWindow("My Interactive Window");
    glutDisplayFunc(display);
    //Task 2
    
    glutIdleFunc(when_in_mainloop);
    /* glutIdleFunc sets the global idle callback to be func so a GLUT program
    can perform background processing tasks or continuous animation when window
    system events are not being received.
    If enabled, the idle callback is continuously called when events are not
    being received. The callback routine has no parameters. The current window
    and current menu will not be changed before the idle callback. Programs with
    multiple windows and/or menus should explicitly set the current window and/or
    current menu and not rely on its current setting. The amount of computation
    and rendering done in an idle callback should be minimized to avoid affecting
    the program's interactive response. In general, not more than a single frame
    of rendering should be done in an idle callback.
    Assigning NULL to glutIdleFunc disables the generation of the idle
    callback.*/
    glutTimerFunc(time_interval,OnTimer,1);
    
    //
    //Task 3
    
    
    
    glutKeyboardFunc(keyboard_input);
    
    
    //Task 4
    //
    
    glutMouseFunc(mouse_input);//mouse callback function
    
    
    glutMainLoop();
}


这里值得注意的是:
每一次callback function被调用是相当于重新调用了一次main函数 但是传参不同。

三、编写代码时的一点小心得

c++和java类似,一个文件里只能有一个main函数,所以虽然配环境很困难,但是每次有新的任务还是得重新建个文件,而且记得不要重复命名!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值