How to draw mouse feedback on the globe using direct OpenGL plug-in
Development licensing
Deployment licensing
Engine Developer Kit
Engine Runtime: 3D
ArcView: 3D Analyst
ArcView: 3D Analyst
ArcEditor: 3D Analyst
ArcEditor: 3D Analyst
ArcInfo: 3D Analyst
ArcInfo: 3D Analyst
Drawing mouse feedback on the globe
This article assumes you are familiar with the following:
The Visual C# programming language
Creating commands and tools for ArcGIS Engine and ArcGIS Desktop
For a working sample of this document's content, please see Globe digitize tool.
In Visual Studio's Solution Explorer, add a new ArcGIS tool. Use the Visual Studio .NET IDE integration framework to implement a BaseTool for ArcGlobe and GlobeControl.
In your class, set member variables for the IGlobeDisplay, IGlobeViewUtil, and ISceneViewer interfaces. In addition, set member variables to store the mouse coordinates, as well as a Boolean flag that indicates whether the mouse key is pressed down. See the following code:
In the Tool OnClick() event handler method, cache GlobeDisplay, SceneViewer, and GlobeViewUtil, and then start listening to the Globe’s AfterDraw event. See the following code:
[C#]
m_globeViewUtil = m_globeHookHelper.Camera as IGlobeViewUtil;
m_globeDisplay = m_globeHookHelper.GlobeDisplay;
m_sceneViwer = m_globeHookHelper.ActiveViewer;
//Start listening to globe display events.
((IGlobeDisplayEvents_Event)m_globeDisplay).AfterDraw += new IGlobeDisplayEvents_AfterDrawEventHandler(OnAfterDraw);
Get the mouse coordinates and switch into tracking mode in the OnMouseDown event handler.
Call Redraw so that the OnAfterDraw method is called and draws the mouse position on the globe. See the following code:
[C#]
publicoverridevoid OnMouseDown(int Button, int Shift, int X, int Y)
{
m_srcX = X;
m_srcY = Y;
//Switch into tracking mode.
m_bDrawPoint = true;
//Refresh the display so that the AfterDraw gets called.
m_sceneViwer.Redraw(false);
}
Repeat the steps for the OnMouseMove event handler, except this time test whether tracking mode is in effect. See the following code:
[C#]
publicoverridevoid OnMouseMove(int Button, int Shift, int X, int Y)
{
//If not in tracking mode, just return.if (false == m_bDrawPoint)
return;
//Cache the coordinates since they are needed for the AfterDraw.
m_srcX = X;
m_srcY = Y;
//Refresh the display so that AfterDraw is called.
m_sceneViwer.Redraw(false);
}
In the OnMouseUp event handler, switch off tracking mode to stop drawing the mouse location. See the following code:
[C#]
publicoverridevoid OnMouseUp(int Button, int Shift, int X, int Y)
{
//Switch off tracking mode.
m_bDrawPoint = false;
//Refresh the display so that AfterDraw is called.
m_sceneViwer.Redraw(false);
}
Implementing OnAfterDraw event handler
The actual drawing takes place in the OnAfterDraw event handler. In fact, the AfterDraw and BeforeDraw events are the only place where you are guaranteed to safely make OpenGL calls (the OpenGL state is ready for the custom calls).
Scroll down to the OnAfterDraw method. See the following code:
[C#]
publicvoid OnAfterDraw(ISceneViewer pViewer)
{
}
Inside the OnAfterDraw method, use IGlobeViewUtil to convert from window coordinates into geocentric coordinates (used by OpenGL). See the following code:
[C#]
double glX, glY, glZ;
m_globeViewUtil.WindowToGeocentric(m_globeDisplay,
m_sceneViwer,
m_srcX,
m_srcY,
true,
out glX,
out glY,
out glZ);
Once you have converted the geographical coordinate into a geocentric coordinate system, draw the OpenGL point. See the following code:
[C#]
//Draw the converted point on the surface of the globe.
GL.glPointSize(15.0f);
GL.glColor3ub(255, 0, 0);
GL.glBegin(GL.GL_POINTS);
GL.glVertex3f((float)glX, (float)glY, (float)glZ);
GL.glEnd();