V3d_View中回调函数的使用

在类V3d_View的成员函数SetWindow中,共有两个函数原型:

1) Standard_EXPORT  

      void SetWindow(const Handle(Aspect_Window)& aWindow,const Aspect_RenderingContext      

      aContext,const Aspect_GraphicCallbackProc& aDisplayCB,const Standard_Address aClientData) ;

2) Standard_EXPORT  

      void SetWindow(const Handle(Aspect_Window)& IdWin) ;

对于第一个函数,各参数的含义如下:

// 引自opencascade 文档

Activates the view in the specified Window
If <acontext> is not NULL the graphic context is used
to draw something in this view.
Otherwise an internal graphic context is created.
If <adisplaycb> is not NULL then a user display CB is
call at the end of the OCC graphic traversal and just
before the swap of buffers. The <aclientdata> is pass
to this call back.
//! Warning! raises MultiplyDefined from Standard
if the view is already activated in a window.
Warning: The view is centered and resized to preserve
the height/width ratio of the window.

参数3 aDisplayCB 为一个函数指针,其函数声明为:

typedef int (* Aspect_GraphicCallbackProc )(Aspect_Drawable , void *, Aspect_GraphicCallbackStruct *)

若该回调函数指针部位null,则当在opengl的绘制过程结束前(swap buffer之前,绘制主场景之后)将会调用该函数。

参数4 aClientData 为void*,通常传入绘制窗口的指针(如CWnd*);

该回调函数的作用类似于top layer,但要灵活的多,我们可以再这里面使用opengl的所有函数。

在绘制过程中,各部分绘制的顺序如下:

// under layer

call_togl_redraw_layer2d (aview, anunderlayer);

// main scene

call_func_redraw_all_structs_proc (aview->WsId);

// top layer

call_togl_redraw_layer2d (aview, anoverlayer);

// call back func

call_subr_displayCB(aview,OCC_REDRAW_BITMAP);

在call_subr_displayCB中若SetWindow中的回调函数不为空,则执行该函数。

扩展:

上面的回调函数在场景全部绘制完成后,可以在最上层绘制其他的图元,如:

{

glDisable(GL_LIGHTING);
    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();
    glLoadIdentity();
    glMatrixMode(GL_PROJECTION);
    glPushMatrix();
    glLoadIdentity();

    glEnable(GL_BLEND);              
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR);
    glShadeModel(GL_SMOOTH);   

    glOrtho( left, right, bottom, top, 1.0, -1.0);

    glPushAttrib (
        GL_LIGHTING_BIT | GL_LINE_BIT | GL_POLYGON_BIT |
        GL_DEPTH_BUFFER_BIT | GL_CURRENT_BIT|GL_COLOR_BUFFER_BIT);
    glDisable (GL_DEPTH_TEST);

    glBegin(GL_QUADS);
    {
        glColor4f(1.0, 1.0, 1.0, 1.0);
        glVertex3d( 0.0, 0.0, 1.0);
        glVertex3d( 10,  0.0, 1.0);
        glColor4f(1.0, 1.0, 1.0, 1.0);
        glVertex3d( 10, 10, 1.0);
        glVertex3d( 0.0,10, 1.0);
    }
    glEnd();


    glColor4f(1.0,0.0,0.0,1.0);


    char* str = "123456";

     int len = (int)strlen(str);

     glRasterPos2f(10,10);

     for( int i = 0; i < len ; i++ )
     {
         glutBitmapCharacter(GLUT_BITMAP_HELVETICA_12,str[i]);
     }

     glPopAttrib ();

    glPopMatrix();
    glMatrixMode(GL_MODELVIEW);
    glPopMatrix();

    glFlush();

}

可以实现混合等特效。

我们同样可以加入一个同样的回调函数来实现under layer的功能,为此,为V3d_View重载函数SetWindow();函数声明为:

Standard_EXPORT   void SetWindow(const Handle(Aspect_Window)& aWindow,const Aspect_RenderingContext

                               aContext,const Aspect_GraphicCallbackProc& aDisplayCB, const Aspect_GraphicCallbackProc&

                               aDisplayCB2, const Standard_Address aClientData) ;

参数4 aDisplayCB2为新加入的回调函数,其调用的位置为绘制过程刚开始的时候,为将他放在了under layer之后。

修改动的部分为:

1) V3d_View.hxx    line 273

       加入函数声明如上。

2) V3d_View.cxx    line 254

       添加函数定义,  注意函数体的区别。

3) Visual3d_View.hxx/cxx  

       重载函数SetWindow(),与V3d_View类似,V3d_View实际上调用Visual3d_View的SetWindow函数。

      V3d_View的两个构造函数中MyCView.GContext = 0;后面添加
            MyCView.GDisplayCB = 0;

      初始化第二个回调函数为空。

4)  InterfaceGraphic_Visual3d.hxx

     修改CALL_DEF_VIEW的定义,添加成员:

    Aspect_GraphicCallbackProc GDisplayCB2;

5)  OpenGl_tgl_subrvis.h/c

    添加函数 extern  int   call_subr_displayCB2(CALL_DEF_VIEW* /*aview*/, int /*reason*/ );的声明和定义。

6) OpenGl_togl_begin_immediat_mode.c    line 256     func:call_togl_clear_immediat_mode

    OpenGl_togl_print.c    line 112    func:call_togl_print

    OpenGl_togl_redraw.c  

    line 94   func:call_togl_redraw

    line 271 func:call_togl_redraw_area

    修改的内容相同,改变原来的绘制顺序为:

   call_func_redraw_all_structs_begin (aview->WsId);
    if (anunderlayer->ptrLayer)
      call_togl_redraw_layer2d (aview, anunderlayer);
#ifdef RIC120302
    call_subr_displayCB2(aview,OCC_REDRAW_WINDOWAREA);
#endif
    call_func_redraw_all_structs_proc (aview->WsId);
#ifdef RIC120302
    call_subr_displayCB(aview,OCC_REDRAW_WINDOWAREA);
#endif
    if (anoverlayer->ptrLayer)
      call_togl_redraw_layer2d (aview, anoverlayer);

    call_func_redraw_all_structs_end (aview->WsId, 0);
    call_togl_redraw_immediat_mode (aview);

   我将回调函数的位置放在了top,under layer的中间,主要使用回调函数。

我们可以利用第二个回调函数来绘制渐变背景,从而避免opencascade绘制layer时存在的bug。

参考:http://www.opencascade.org/org/forum/thread_11428/

你可能感兴趣的:(null,文档,buffer,Blend,layer,traversal)