/// <summary> /// 从缓存中获得当前图层的纹理对象,若不存在,则返回null /// </summary> protected IconTexture GetTexture(Icon icon) { object key = null; if (icon.Image == null) { key = icon.TextureFileName; } else { key = icon.Image; } if (key == null) { return(null); } IconTexture res = (IconTexture)m_textures[key]; return(res); }
/// <summary> /// 刷新图标集合图层 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void refreshTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { if (isUpdating) { return; } isUpdating = true; try { for (int i = 0; i < this.ChildObjects.Count; i++) { RenderableObject ro = (RenderableObject)this.ChildObjects[i]; if (ro != null && ro.IsOn && ro is Icon) { Icon icon = (Icon)ro; if (icon.RefreshInterval == TimeSpan.MaxValue || icon.LastRefresh > System.DateTime.Now - icon.RefreshInterval) { continue; } object key = null; IconTexture iconTexture = null; if (icon.TextureFileName != null && icon.TextureFileName.Length > 0) { if (icon.TextureFileName.ToLower().StartsWith("http://") && icon.SaveFilePath != null) { //download it try { Qrst.Net.WebDownload webDownload = new Qrst.Net.WebDownload(icon.TextureFileName); webDownload.DownloadType = Qrst.Net.DownloadType.Unspecified; System.IO.FileInfo saveFile = new System.IO.FileInfo(icon.SaveFilePath); if (!saveFile.Directory.Exists) { saveFile.Directory.Create(); } webDownload.DownloadFile(saveFile.FullName); } catch { } iconTexture = (IconTexture)m_textures[icon.SaveFilePath]; if (iconTexture != null) { IconTexture tempTexture = iconTexture; m_textures[icon.SaveFilePath] = new IconTexture(DrawArgs.Device, icon.SaveFilePath); tempTexture.Dispose(); } else { key = icon.SaveFilePath; iconTexture = new IconTexture(DrawArgs.Device, icon.SaveFilePath); // New texture, cache it m_textures.Add(key, iconTexture); // Use default dimensions if not set if (icon.Width == 0) { icon.Width = iconTexture.Width; } if (icon.Height == 0) { icon.Height = iconTexture.Height; } } } else { // Icon image from file iconTexture = (IconTexture)m_textures[icon.TextureFileName]; if (iconTexture != null) { IconTexture tempTexture = iconTexture; m_textures[icon.SaveFilePath] = new IconTexture(DrawArgs.Device, icon.TextureFileName); tempTexture.Dispose(); } else { key = icon.SaveFilePath; iconTexture = new IconTexture(DrawArgs.Device, icon.TextureFileName); // New texture, cache it m_textures.Add(key, iconTexture); // Use default dimensions if not set if (icon.Width == 0) { icon.Width = iconTexture.Width; } if (icon.Height == 0) { icon.Height = iconTexture.Height; } } } } else { // Icon image from bitmap if (icon.Image != null) { iconTexture = (IconTexture)m_textures[icon.Image]; if (iconTexture != null) { IconTexture tempTexture = iconTexture; m_textures[icon.SaveFilePath] = new IconTexture(DrawArgs.Device, icon.Image); tempTexture.Dispose(); } else { key = icon.SaveFilePath; iconTexture = new IconTexture(DrawArgs.Device, icon.Image); // New texture, cache it m_textures.Add(key, iconTexture); // Use default dimensions if not set if (icon.Width == 0) { icon.Width = iconTexture.Width; } if (icon.Height == 0) { icon.Height = iconTexture.Height; } } } } icon.LastRefresh = System.DateTime.Now; } } } catch { } finally { isUpdating = false; } }
/// <summary> /// 渲染图标 /// </summary> protected virtual void Render(DrawArgs drawArgs, Icon icon, Vector3 projectedPoint) { //判断当前Icon是否呗初始化了,比如,若重新定义了图标的位置,则它的isInitialized就是false if (!icon.isInitialized) { icon.Initialize(drawArgs); } //判断当前图标是否在视地范围内,若不在,则不进行绘制 if (!drawArgs.WorldCamera.ViewFrustum.ContainsPoint(icon.Position)) { return; } // 判断图标是否在最大,最小可见的范围内,若不在,则不进行绘制 double distanceToIcon = Vector3.Length(icon.Position - drawArgs.WorldCamera.Position); if (distanceToIcon > icon.MaximumDisplayDistance) { return; } if (distanceToIcon < icon.MinimumDisplayDistance) { return; } //获得当前图层的纹理对象 IconTexture iconTexture = GetTexture(icon); //判断是否是MouseOver对象 bool isMouseOver = icon == mouseOverIcon; //若是MouseOver对象,则绘制Description里的内容 if (isMouseOver) { //若是MouseOver对象 isMouseOver = true; //若当前图层可以操作,则设置当前的鼠标是Hand if (icon.isSelectable) { DrawArgs.MouseCursor = CursorType.Hand; } ////显示文字描述信息,暂时不需要 //string description = icon.Description; //if(description==null) // description = icon.ClickableActionURL; ////绘制文字信息 //if(description!=null) //{ // //设置文字的绘制区域 // DrawTextFormat format = DrawTextFormat.NoClip | DrawTextFormat.WordBreak | DrawTextFormat.Bottom; // int left = 10; // if(World.Settings.showLayerManager) // left += World.Settings.layerManagerWidth; // Rectangle rect = Rectangle.FromLTRB(left, 10, drawArgs.screenWidth - 10, drawArgs.screenHeight - 10 ); // //绘制边框 // drawArgs.defaultDrawingFont.DrawText( // m_sprite, description, // rect, // format, 0xb0 << 24 ); // rect.Offset(2,0); // drawArgs.defaultDrawingFont.DrawText( // m_sprite, description, // rect, // format, 0xb0 << 24 ); // rect.Offset(0,2); // drawArgs.defaultDrawingFont.DrawText( // m_sprite, description, // rect, // format, 0xb0 << 24 ); // rect.Offset(-2,0); // drawArgs.defaultDrawingFont.DrawText( // m_sprite, description, // rect, // format, 0xb0 << 24 ); // // 绘制文字信息 // rect.Offset(1,-1); // drawArgs.defaultDrawingFont.DrawText( // m_sprite, description, // rect, // format, descriptionColor ); //} } //获取颜色 int color = isMouseOver ? hotColor : normalColor; if (iconTexture == null || isMouseOver || icon.NameAlwaysVisible) { // 绘制图标的名称 if (icon.Name != null) { // Render name field const int labelWidth = 1000; // Dummy value needed for centering the text if (iconTexture == null) { // Center over target as we have no bitmap Rectangle rect = new Rectangle( (int)projectedPoint.X - (labelWidth >> 1), (int)(projectedPoint.Y - (drawArgs.iconNameFont.Description.Height >> 1)), labelWidth, drawArgs.screenHeight); drawArgs.iconNameFont.DrawText(m_sprite, icon.Name, rect, DrawTextFormat.Center, color); } else { // Adjust text to make room for icon int spacing = (int)(icon.Width * 0.3f); if (spacing > 10) { spacing = 10; } int offsetForIcon = (icon.Width >> 1) + spacing; Rectangle rect = new Rectangle( (int)projectedPoint.X + offsetForIcon, (int)(projectedPoint.Y - (drawArgs.iconNameFont.Description.Height >> 1)), labelWidth, drawArgs.screenHeight); drawArgs.iconNameFont.DrawText(m_sprite, icon.Name, rect, DrawTextFormat.WordBreak, color); } } } //绘制图标 if (iconTexture != null) { // Render icon float xscale = (float)icon.Width / iconTexture.Width; float yscale = (float)icon.Height / iconTexture.Height; m_sprite.Transform = Matrix.Scaling(xscale, yscale, 0); if (icon.IsRotated) { m_sprite.Transform *= Matrix.RotationZ((float)icon.Rotation.Radians - (float)drawArgs.WorldCamera.Heading.Radians); } m_sprite.Transform *= Matrix.Translation(projectedPoint.X, projectedPoint.Y, 0); m_sprite.Draw(iconTexture.Texture, new Vector3(iconTexture.Width >> 1, iconTexture.Height >> 1, 0), Vector3.Empty, color); // Reset transform to prepare for text rendering later m_sprite.Transform = Matrix.Identity; } }
/// <summary> /// 初始化图标集合:1.把所有的图标读到缓存Hashtable中去,并设置Icon的高宽.2.计算每个Icon的包围范围 /// </summary> /// <param name="drawArgs"></param> public override void Initialize(DrawArgs drawArgs) { //判断是否显示此图层,若不显示,则返回 if (!isOn) { return; } //判断绘制Icon的对象,是否存在,若不存在,则创建,若存在,则先释放 if (m_sprite != null) { m_sprite.Dispose(); m_sprite = null; } m_sprite = new Sprite(drawArgs.device); System.TimeSpan smallestRefreshInterval = System.TimeSpan.MaxValue; // 添加所有的Icon对象的纹理到缓存中去,并设置Icon的宽与高 foreach (RenderableObject ro in m_children) { Icon icon = ro as Icon; if (icon == null) { // 判断当前Icon是否显示,若不显示,则Continue下一个 if (ro.IsOn) { ro.Initialize(drawArgs); } continue; } if (icon.RefreshInterval.TotalMilliseconds != 0 && icon.RefreshInterval != TimeSpan.MaxValue && icon.RefreshInterval < smallestRefreshInterval) { smallestRefreshInterval = icon.RefreshInterval; } // 子Icon初始化 icon.Initialize(drawArgs); object key = null; //创建一个IconeTexture对象 IconTexture iconTexture = null; //从文件中读取当前Icon if (icon.TextureFileName != null && icon.TextureFileName.Length > 0) { // 从缓存中读取Icon纹理对象 iconTexture = (IconTexture)m_textures[icon.TextureFileName]; //若缓存中不存在,则从文件中读取Icon对象 if (iconTexture == null) { key = icon.TextureFileName; iconTexture = new IconTexture(drawArgs.device, icon.TextureFileName); } } //从Bitmap对象中读取Icon对象 else { if (icon.Image != null) { iconTexture = (IconTexture)m_textures[icon.Image]; if (iconTexture == null) { key = icon.Image; iconTexture = new IconTexture(drawArgs.device, icon.Image); } } } //若仍然没有纹理,则循环下一个 if (iconTexture == null) { continue; } //若有纹理的话 if (key != null) { //把纹理放到缓存中去 m_textures.Add(key, iconTexture); // 设置Icon的宽度 if (icon.Width == 0) { icon.Width = iconTexture.Width; } // 设置Icon的高度 if (icon.Height == 0) { icon.Height = iconTexture.Height; } } } // 计算Icon的包围盒 foreach (RenderableObject ro in m_children) { Icon icon = ro as Icon; if (icon == null) { continue; } if (GetTexture(icon) == null) { //计算文字的范围 icon.SelectionRectangle = drawArgs.defaultDrawingFont.MeasureString(null, icon.Name, DrawTextFormat.None, 0); } else { //计算图标的范围 icon.SelectionRectangle = new Rectangle(0, 0, icon.Width, icon.Height); } // Center the box at (0,0) icon.SelectionRectangle.Offset(-icon.SelectionRectangle.Width / 2, -icon.SelectionRectangle.Height / 2); } if (refreshTimer == null && smallestRefreshInterval != TimeSpan.MaxValue) { refreshTimer = new System.Timers.Timer(smallestRefreshInterval.TotalMilliseconds); refreshTimer.Elapsed += new System.Timers.ElapsedEventHandler(refreshTimer_Elapsed); refreshTimer.Start(); } isInitialized = true; }