/// <summary> /// For custom OpenGL layers, perform immediate drawing. /// </summary> /// <param name="pGlobeViewer"></param> /// <remarks>This is where you should add your drawings on the Globe. This method must be overridden in /// your inheriting class. DrawImmediate together with IGlobeDisplayEvents::BeforeDraw and IGlobeDisplayEvents::AfterDraw /// is the only safe place where the OpenGL state is ready for custom actions.</remarks> public abstract void DrawImmediate(IGlobeViewer pGlobeViewer);
/// <summary> /// This is where the actual drawing takes place. /// </summary> /// <param name="pGlobeViewer"></param> public override void DrawImmediate(IGlobeViewer pGlobeViewer) { //make sure that the layer is valid, visible and that the main table exists if (!m_bVisible || !m_bValid | null == m_table) return; //get the OpenGL rendering mode uint mode; unsafe { int m; GL.glGetIntegerv(GL.GL_RENDER_MODE, &m); mode = (uint)m; //GL.glGetIntegerv(GL.GL_RENDER_MODE, out mode); } //get the OpenGL matrices (required for the viewport filtering and the billboard orientation) GL.glGetDoublev(GL.GL_MODELVIEW_MATRIX, m_modelViewMatrix); GL.glGetIntegerv(GL.GL_VIEWPORT, m_viewport); GL.glGetDoublev(GL.GL_PROJECTION_MATRIX, m_projMatrix); //populate the billboard matrix m_billboardMatrix[0] = m_modelViewMatrix[0]; m_billboardMatrix[1] = m_modelViewMatrix[4]; m_billboardMatrix[2] = m_modelViewMatrix[8]; m_billboardMatrix[3] = 0; m_billboardMatrix[4] = m_modelViewMatrix[1]; m_billboardMatrix[5] = m_modelViewMatrix[5]; m_billboardMatrix[6] = m_modelViewMatrix[9]; m_billboardMatrix[7] = 0; m_billboardMatrix[8] = m_modelViewMatrix[2]; m_billboardMatrix[9] = m_modelViewMatrix[6]; m_billboardMatrix[10] = m_modelViewMatrix[10]; m_billboardMatrix[11] = 0; m_billboardMatrix[12] = 0; m_billboardMatrix[13] = 0; m_billboardMatrix[14] = 0; m_billboardMatrix[15] = 1; ISceneViewer sceneViewer = pGlobeViewer.GlobeDisplay.ActiveViewer; //only once, create display lists and do initializations if (!m_bDisplayListCreated) { CreateDisplayLists(); m_globeDisplay = pGlobeViewer.GlobeDisplay; } //get the globeViewUtil which allow to convert between the different globe coordinate systems m_globeViewUtil = sceneViewer.Camera as IGlobeViewUtil; IGlobeViewUtil globeViewUtil = sceneViewer.Camera as IGlobeViewUtil; IGlobeAdvancedOptions advOpt = m_globeDisplay.AdvancedOptions; //the ClipNear value is required for the viewport filtering (since we don't //want to draw an item which is beyond the clipping planes). double clipNear = advOpt.ClipNear; double dblObsX, dblObsY, dblObsZ, dMagnitude; ICamera camera = pGlobeViewer.GlobeDisplay.ActiveViewer.Camera; //query the camera location in geocentric coordinate (OpenGL coord system) camera.Observer.QueryCoords(out dblObsX, out dblObsY); dblObsZ = camera.Observer.Z; double lat, lon, X = 0.0, Y = 0.0, Z = 0.0; //iterate through all the records of the layer, test whether the item is within the //viewport are and draw it onto the globe. foreach (DataRow rec in m_table.Rows) { lat = Convert.ToDouble(rec[3]); lon = Convert.ToDouble(rec[4]); X = Convert.ToDouble(rec[5]); Y = Convert.ToDouble(rec[6]); Z = Convert.ToDouble(rec[7]); #region get the OGL geocentric coordinates X,Y,Z if (X == 0.0 && Y == 0.0 && Z == 0.0) { //calculate the geocentric coordinates globeViewUtil.GeographicToGeocentric(lon, lat, 1000.0, out X, out Y, out Z); //write the calculated geocentric coordinate to the table lock (m_table) { rec[5] = X; rec[6] = Y; rec[7] = Z; rec.AcceptChanges(); } } #endregion //make sure that the item is inside the viewport, otherwise no need to draw it if (!InsideViewport(X, Y, Z, clipNear, mode)) continue; //get the distance from the camera to the drawn item. //This distance will determine whether to draw the item as a dot or as //a full icon. m_vector3D.SetComponents(dblObsX - X, dblObsY - Y, dblObsZ - Z); dMagnitude = m_vector3D.Magnitude; //call the drawing method DrawItem(rec, dMagnitude); } }