OSDN Git Service

Local chat console implemented.
authorLatif Khalifa <latifer@streamgrid.net>
Sun, 7 Aug 2011 11:10:37 +0000 (11:10 +0000)
committerLatif Khalifa <latifer@streamgrid.net>
Sun, 7 Aug 2011 11:10:37 +0000 (11:10 +0000)
TODO, different colors for different types.

git-svn-id: https://radegast.googlecode.com/svn/trunk@1075 f7a694da-4d33-11de-9ad6-1127a62b9fcd

Radegast/Core/ChatTextManager.cs
Radegast/GUI/Rendering/ChatOverlay.cs
Radegast/GUI/Rendering/Rendering.cs
Radegast/GUI/Rendering/RenderingHelpers.cs
Radegast/GUI/Rendering/Water.cs

index 3d4d7f0..f38bc8a 100644 (file)
@@ -347,6 +347,7 @@ namespace Radegast
     public class ChatLineAddedArgs : EventArgs
     {
         ChatBufferItem mItem;
+        public ChatBufferItem Item { get { return mItem; } }
 
         public ChatLineAddedArgs(ChatBufferItem item)
         {
index d8cc49a..10b4afa 100644 (file)
@@ -34,34 +34,211 @@ using System.Linq;
 using System.Text;
 using System.Text.RegularExpressions;
 using System.Drawing;
+using System.Drawing.Imaging;
+using System.Windows.Forms;
+using OpenTK.Graphics.OpenGL;
 
 namespace Radegast.Rendering
 {
     public class ChatOverlay : IDisposable
     {
+        public static Font ChatFont = new Font(FontFamily.GenericSansSerif, 11f, FontStyle.Regular, GraphicsUnit.Point);
+        public static float ChatLineTimeOnScreen = 20f; // time in seconds chat line appears on the screen
+        public static float ChatLineFade = 1.5f; // number of seconds before expiry to start fading chat off
+        public static OpenTK.Graphics.Color4 ChatBackground = new OpenTK.Graphics.Color4(0f, 0f, 0f, 0.5f);
+
         RadegastInstance Instance;
         SceneWindow Window;
         float runningTime;
+        
+        Queue<ChatLine> chatLines;
+        int screenWidth, screenHeight;
 
         public ChatOverlay(RadegastInstance instance, SceneWindow window)
         {
             this.Instance = instance;
             this.Window = window;
             Instance.TabConsole.MainChatManger.ChatLineAdded += new EventHandler<ChatLineAddedArgs>(MainChatManger_ChatLineAdded);
+            chatLines = new Queue<ChatLine>();
         }
 
         public void Dispose()
         {
             Instance.TabConsole.MainChatManger.ChatLineAdded -= new EventHandler<ChatLineAddedArgs>(MainChatManger_ChatLineAdded);
+
+            if (chatLines != null)
+            {
+                lock (chatLines)
+                {
+                    foreach (var line in chatLines)
+                    {
+                        line.Dispose();
+                    }
+                }
+                chatLines = null;
+            }
         }
 
         void MainChatManger_ChatLineAdded(object sender, ChatLineAddedArgs e)
         {
+            lock (chatLines)
+            {
+                chatLines.Enqueue(new ChatLine(e.Item, runningTime));
+            }
         }
 
-        public void RenderChat(float time)
+        public void RenderChat(float time, RenderPass pass)
         {
             runningTime += time;
+            if (chatLines.Count == 0) return;
+
+            int c = 0;
+            int expired = 0;
+            screenWidth = Window.Viewport[2];
+            screenHeight = Window.Viewport[3];
+            ChatLine[] lines;
+
+            lock (chatLines)
+            {
+                lines = chatLines.ToArray();
+                c = lines.Length;
+                for (int i = 0; i < c; i++)
+                {
+                    if ((runningTime - lines[i].TimeAdded) > ChatLineTimeOnScreen)
+                    {
+                        expired++;
+                        ChatLine goner = chatLines.Dequeue();
+                        goner.Dispose();
+                    }
+                    else
+                    {
+                        break;
+                    }
+                }
+                if (expired > 0)
+                {
+                    lines = chatLines.ToArray();
+                    c = lines.Length;
+                }
+            }
+
+            if (c == 0)
+            {
+                runningTime = 0f;
+                return;
+            }
+
+            int maxWidth = (int)((float)screenWidth * 0.7f);
+
+            int actualMaxWidth = 0;
+            int height = 0;
+            for (int i = 0; i < c; i++)
+            {
+                lines[i].PrepareText(maxWidth);
+                if (lines[i].Width > actualMaxWidth) actualMaxWidth = lines[i].Width;
+                height += lines[i].Height;
+            }
+
+            int x = 5;
+            int y = 5;
+            GL.Enable(EnableCap.Texture2D);
+            GL.Color4(ChatBackground);
+            RHelp.Draw2DBox(x, y, actualMaxWidth + 6, height + 10, 1f);
+            GL.Color4(1f, 1f, 1f, 1f);
+            for (int i = c - 1; i >= 0; i--)
+            {
+                ChatLine line = lines[i];
+                float remain = ChatLineTimeOnScreen - (runningTime - line.TimeAdded);
+                if (remain < ChatLineFade)
+                {
+                    float alpha = remain / ChatLineFade;
+                    GL.Color4(1f, 1f, 1f, alpha);
+                }
+                line.Render(x + 3, y + 5);
+                y += line.Height;
+            }
+            GL.BindTexture(TextureTarget.Texture2D, 0);
+            GL.Disable(EnableCap.Texture2D);
+            GL.Color4(1f, 1f, 1f, 1f);
+        }
+    }
+
+    public class ChatLine : IDisposable
+    {
+        public float TimeAdded;
+        public int Width;
+        public int Height;
+
+        int textureID = -1;
+        int widthForTextureGenerated = -1;
+        ChatBufferItem item;
+       
+        public ChatLine(ChatBufferItem item, float timeAdded)
+        {
+            this.item = item;
+            this.TimeAdded = timeAdded;
+        }
+
+        public void Dispose()
+        {
+            if (textureID > 0)
+            {
+                GL.DeleteTexture(textureID);
+                textureID = -1;
+            }
+        }
+
+        public void PrepareText(int maxWidth)
+        {
+            if (maxWidth != widthForTextureGenerated)
+            {
+                string txt = item.From + item.Text;
+
+                // If we're modiefied and have texture already delete it from graphics card
+                if (textureID > 0)
+                {
+                    GL.DeleteTexture(textureID);
+                    textureID = -1;
+                }
+
+                TextFormatFlags flags = TextFormatFlags.Top | TextFormatFlags.Left | TextFormatFlags.WordBreak;
+
+                Size s = TextRenderer.MeasureText(
+                    txt,
+                    ChatOverlay.ChatFont,
+                    new Size(maxWidth, 2000), flags);
+            
+                Width = s.Width;
+                Height = s.Height;
+
+                Bitmap img = new Bitmap(
+                    Width,
+                    Height,
+                    System.Drawing.Imaging.PixelFormat.Format32bppArgb);
+                
+                Graphics g = Graphics.FromImage(img);
+
+                TextRenderer.DrawText(
+                    g,
+                    txt,
+                    ChatOverlay.ChatFont,
+                    new Rectangle(0, 0, img.Width + 2, img.Height + 2),
+                    RHelp.WinColor(new OpenTK.Graphics.Color4(0.95f, 0.95f, 0.95f, 1f)),
+                    Color.Transparent,
+                    flags);
+
+                widthForTextureGenerated = maxWidth;
+                textureID = RHelp.GLLoadImage(img, true);
+                g.Dispose();
+                img.Dispose();
+            }
+        }
+
+        public void Render(int x, int y)
+        {
+            if (textureID == -1) return;
+            GL.BindTexture(TextureTarget.Texture2D, textureID);
+            RHelp.Draw2DBox(x, y, Width, Height, 0f);
         }
     }
 }
index 673599d..c265476 100644 (file)
@@ -120,7 +120,7 @@ namespace Radegast.Rendering
         /// <summary>\r
         /// Size of OpenGL window we're drawing on\r
         /// </summary>\r
-        int[] Viewport = new int[4];\r
+        public int[] Viewport = new int[4];\r
 \r
         #endregion Public fields\r
 \r
@@ -934,49 +934,6 @@ namespace Radegast.Rendering
             GL.MatrixMode(MatrixMode.Modelview);\r
         }\r
 \r
-        public int GLLoadImage(Bitmap bitmap, bool hasAlpha)\r
-        {\r
-            int ret = -1;\r
-            GL.GenTextures(1, out ret);\r
-            GL.BindTexture(TextureTarget.Texture2D, ret);\r
-\r
-            Rectangle rectangle = new Rectangle(0, 0, bitmap.Width, bitmap.Height);\r
-\r
-            BitmapData bitmapData =\r
-                bitmap.LockBits(\r
-                rectangle,\r
-                ImageLockMode.ReadOnly,\r
-                hasAlpha ? System.Drawing.Imaging.PixelFormat.Format32bppArgb : System.Drawing.Imaging.PixelFormat.Format24bppRgb);\r
-\r
-            GL.TexImage2D(\r
-                TextureTarget.Texture2D,\r
-                0,\r
-                hasAlpha ? PixelInternalFormat.Rgba : PixelInternalFormat.Rgb8,\r
-                bitmap.Width,\r
-                bitmap.Height,\r
-                0,\r
-                hasAlpha ? OpenTK.Graphics.OpenGL.PixelFormat.Bgra : OpenTK.Graphics.OpenGL.PixelFormat.Bgr,\r
-                PixelType.UnsignedByte,\r
-                bitmapData.Scan0);\r
-\r
-            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);\r
-            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);\r
-            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);\r
-            if (RenderSettings.HasMipmap)\r
-            {\r
-                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);\r
-                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.GenerateMipmap, 1);\r
-                GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);\r
-            }\r
-            else\r
-            {\r
-                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);\r
-            }\r
-\r
-            bitmap.UnlockBits(bitmapData);\r
-            return ret;\r
-        }\r
-\r
         #region Texture thread\r
         bool TextureThreadRunning = true;\r
 \r
@@ -1068,7 +1025,7 @@ namespace Radegast.Rendering
                     Bitmap bitmap = (Bitmap)img;\r
 \r
                     bitmap.RotateFlip(RotateFlipType.RotateNoneFlipY);\r
-                    item.Data.TextureInfo.TexturePointer = GLLoadImage(bitmap, item.Data.TextureInfo.HasAlpha);\r
+                    item.Data.TextureInfo.TexturePointer = RHelp.GLLoadImage(bitmap, item.Data.TextureInfo.HasAlpha);\r
                     GL.Flush();\r
                     bitmap.Dispose();\r
                 }\r
@@ -2185,7 +2142,7 @@ namespace Radegast.Rendering
                     GL.DeleteTexture(terrainTexture);\r
                 }\r
 \r
-                terrainTexture = GLLoadImage(terrainImage, false);\r
+                terrainTexture = RHelp.GLLoadImage(terrainImage, false);\r
                 terrainImage.Dispose();\r
                 terrainImage = null;\r
             }\r
@@ -2925,7 +2882,7 @@ namespace Radegast.Rendering
                 GLHUDBegin();\r
                 RenderText(RenderPass.Simple);\r
                 RenderStats();\r
-                chatOverlay.RenderChat(lastFrameTime);\r
+                chatOverlay.RenderChat(lastFrameTime, RenderPass.Simple);\r
                 GLHUDEnd();\r
                 GL.Disable(EnableCap.Blend);\r
             }\r
index 604acaa..f828049 100644 (file)
@@ -9,6 +9,8 @@ using System.Xml;
 using System.Threading;\r
 using OpenTK.Graphics.OpenGL;\r
 using System.Runtime.InteropServices;\r
+using System.Drawing;\r
+using System.Drawing.Imaging;\r
 using OpenMetaverse;\r
 using OpenMetaverse.Rendering;\r
 \r
@@ -659,6 +661,16 @@ namespace Radegast.Rendering
             return new OpenTK.Vector4(v.X, v.Y, v.Z, v.W);\r
         }\r
 \r
+        public static Color WinColor(OpenTK.Graphics.Color4 color)\r
+        {\r
+            return Color.FromArgb((int)(color.A * 255), (int)(color.R * 255), (int)(color.G * 255), (int)(color.B * 255));\r
+        }\r
+\r
+        public static Color WinColor(Color4 color)\r
+        {\r
+            return Color.FromArgb((int)(color.A * 255), (int)(color.R * 255), (int)(color.G * 255), (int)(color.B * 255));\r
+        }\r
+\r
         #region Cached image save and load\r
         public static readonly string RAD_IMG_MAGIC = "radegast_img";\r
 \r
@@ -796,6 +808,65 @@ namespace Radegast.Rendering
                2, 3, 7, 6      // Bottom Face\r
         };\r
         #endregion Static vertices and indices for a cube (used for bounding box drawing)\r
+\r
+        public static int GLLoadImage(Bitmap bitmap, bool hasAlpha)\r
+        {\r
+            int ret = -1;\r
+            GL.GenTextures(1, out ret);\r
+            GL.BindTexture(TextureTarget.Texture2D, ret);\r
+\r
+            Rectangle rectangle = new Rectangle(0, 0, bitmap.Width, bitmap.Height);\r
+\r
+            BitmapData bitmapData =\r
+                bitmap.LockBits(\r
+                rectangle,\r
+                ImageLockMode.ReadOnly,\r
+                hasAlpha ? System.Drawing.Imaging.PixelFormat.Format32bppArgb : System.Drawing.Imaging.PixelFormat.Format24bppRgb);\r
+\r
+            GL.TexImage2D(\r
+                TextureTarget.Texture2D,\r
+                0,\r
+                hasAlpha ? PixelInternalFormat.Rgba : PixelInternalFormat.Rgb8,\r
+                bitmap.Width,\r
+                bitmap.Height,\r
+                0,\r
+                hasAlpha ? OpenTK.Graphics.OpenGL.PixelFormat.Bgra : OpenTK.Graphics.OpenGL.PixelFormat.Bgr,\r
+                PixelType.UnsignedByte,\r
+                bitmapData.Scan0);\r
+\r
+            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);\r
+            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Repeat);\r
+            GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Repeat);\r
+            if (RenderSettings.HasMipmap)\r
+            {\r
+                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.LinearMipmapLinear);\r
+                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.GenerateMipmap, 1);\r
+                GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);\r
+            }\r
+            else\r
+            {\r
+                GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);\r
+            }\r
+\r
+            bitmap.UnlockBits(bitmapData);\r
+            return ret;\r
+        }\r
+\r
+        public static void Draw2DBox(float x, float y, float width, float height, float depth)\r
+        {\r
+            GL.Begin(BeginMode.Quads);\r
+            {\r
+                GL.TexCoord2(0, 1);\r
+                GL.Vertex3(x, y, depth);\r
+                GL.TexCoord2(1, 1);\r
+                GL.Vertex3(x + width, y, depth);\r
+                GL.TexCoord2(1, 0);\r
+                GL.Vertex3(x + width, y + height, depth);\r
+                GL.TexCoord2(0, 0);\r
+                GL.Vertex3(x, y + height, depth);\r
+            }\r
+            GL.End();\r
+        }\r
     }\r
 \r
     /// <summary>\r
index 1030c9a..da55dd2 100644 (file)
@@ -72,11 +72,11 @@ namespace Radegast.Rendering
         void InitWater()
         {
             Bitmap normal = (Bitmap)Bitmap.FromFile(System.IO.Path.Combine("shader_data", "normalmap.png"));
-            reflectionTexture = GLLoadImage(normal, false);
-            refractionTexture = GLLoadImage(normal, false);
-            normalmap = GLLoadImage(normal, false);
-            depthTexture = GLLoadImage(normal, false);
-            dudvmap = GLLoadImage((Bitmap)Bitmap.FromFile(System.IO.Path.Combine("shader_data", "dudvmap.png")), false);
+            reflectionTexture = RHelp.GLLoadImage(normal, false);
+            refractionTexture = RHelp.GLLoadImage(normal, false);
+            normalmap = RHelp.GLLoadImage(normal, false);
+            depthTexture = RHelp.GLLoadImage(normal, false);
+            dudvmap = RHelp.GLLoadImage((Bitmap)Bitmap.FromFile(System.IO.Path.Combine("shader_data", "dudvmap.png")), false);
             waterProgram.Load("water.vert", "water.frag");
         }