由于捕获BeforeDraw与AfterDraw事件的方法相同,我们以AfterDraw为例进行说明。首先我们来看看什么时候用到BeforeDraw和AfterDraw。
在AE的帮助文档中,BeforeDraw事件备注如下:
This event method is often used by an OpenGL routine that renders something before the main features in the scene are drawn. A good example is the scene background, such as sky/sun/moon etc. Just like the art of painting, one normally needs to draw the background first and then the main feature. So this method is generally for the background rendering. It can also be used for executing some routines other than drawing.
The BeforeDraw method returns a boolean value. When it's set to true, the SceneGraph's drawing is disabled, and you as a developer take control of the drawing (e.g. via OpenGL). Otherwise, the SceneGraph takes care of drawing as usual.
译文:BeforeDraw事件常用于OpenGL编程,用于在Scene中绘出主要的要素之前进行相关的渲染操作,渲染Scene的背景就是一个很好的示例,比如天空、太阳、月亮等等。和绘画一样,我们需要首先绘制背景,然后才绘制主要的元素。所以这个事件常用于背景的渲染操作。当然它也可以执行除去绘画之外的一些其它的常用操作。
BeforeDraw方法返回一个bool类型值。当返回true的时候,SceneGraph的绘画功能失效,这时候你作为一个开发人员可以通过OpenGF来控制绘画。如果返回false,还是由SceneGraph控制绘画。
AfterDraw事件备注如下:
This event method is often used by an OpenGL routine that renders something after the main features in the scene are drawn. Just like the art of painting, one normally needs to draw the background first and then the main feature, followed by foreground features or other miscellaneous features. So this method is generally used for drawing of graphics after the background and the main features are drawn. It can also be used for executing some routines other than drawing.
译文:AfterDraw事件常用于OpenGL编程,用于在Scene中绘出主要的要素之后进行相关的渲染操作。和绘画一样,我们必须首先绘制背景,然后绘制主要的要素,最后绘制前景要素或者其它的各种各样的要素。所以这个事件常用于背景和主要要素绘制完成后对Graphics进行绘制。它也可以执行除去绘画之外的一些其它的常用操作。
我们在MapControl中很容易编写AfterDraw的代码,因为MapControl封装了该事件,但是要想编写SceneControl的AfterDraw事件代码却并未易事。
我们通过SceneControl的SceneGraph属性获得了一个ISceneGraph类型的对象,查看帮助文档可以得知,ISceneGraph接口只被SceneGraph类实现,我们然后查看SceneGraph类所实现的接口,如下图所示:
我原本希望将该接口QI到ISceneGraphEvents,进而能QI到SceneGraphClass,然后利用SceneGraphClass中的AfterDraw事件。我在调试环境下对获取的ISceneGraph对象用is关键字进行了测试,除去最后的两个事件接口外,都返回了true。所以ISceneGraph不能QI到ISceneGraphEvents,更不可能转换到SceneGraphClass,所以计划破灭。
后来我在VS编辑器中输入ISceneGraphEvents时,由于VS的智能感应看到了一个奇怪的接口ISceneGraphEvents_Event,然后我正好在Esri论坛上看到了一篇文章(http://bbs.esrichina-bj.cn/ESRI/thread-13483-1-1.html),也用到了ISceneGraphEvents_Event接口。ISceneGraphEvents_Event接口中也有AfterDraw事件,最终得到的解决方法如下:
public FrmMain() { InitializeComponent(); //(this.PipeSceneControl.SceneGraph as SceneGraphEventsClass).AfterDraw += new ISceneGraphEvents_AfterDrawEventHandler(FrmMain_AfterDraw); (this.PipeSceneControl.SceneGraph as ISceneGraphEvents_Event).AfterDraw += new ISceneGraphEvents_AfterDrawEventHandler(FrmMain_AfterDraw); } void FrmMain_AfterDraw(ISceneViewer pViewer) { }
下面我们看一下ISceneGraphEvents_Event接口和ISceneGraphEvents接口的区别:
首先,ISceneGraphEvents_Event接口只能在VS的智能感应中识别,但是在AE的帮助文档中却找不到该类型。
其次,ISceneGraphEvents接口在VS的智能感应中可以识别,在AE的帮助文档中也可以识别。
然后,ISceneGraphEvents_Event接口在VS编辑环境中的AfterDraw是以事件的形式显示的,如下图所示:
但是ISceneGraphEvents接口在VS编辑环境中的AfterDraw是以方法的形式显示的,如下图所示:
所以只能用ISceneGraphEvents_Event接口实现AfterDraw的事件绑定,而不能用ISceneGraphEvents接口。