private void RenderText(RenderPass pass)
{
lock (VisibleAvatars)
{
foreach (RenderAvatar av in VisibleAvatars)
{
Vector3 avPos = av.RenderPosition;
if (av.DistanceSquared > 400f) continue;
byte[] faceColor = null;
OpenTK.Vector3 tagPos = RHelp.TKVector3(avPos);
tagPos.Z += 1.2f;
OpenTK.Vector3 screenPos;
if (!Math3D.GluProject(tagPos, ModelMatrix, ProjectionMatrix, Viewport, out screenPos)) continue;
string tagText = instance.Names.Get(av.avatar.ID, av.avatar.Name);
if (!string.IsNullOrEmpty(av.avatar.GroupName))
tagText = av.avatar.GroupName + "\n" + tagText;
TextFormatFlags flags = TextFormatFlags.HorizontalCenter | TextFormatFlags.Top;
var tSize = TextRendering.Measure(tagText, AvatarTagFont, flags);
if (pass == RenderPass.Picking)
{
// Send avatar anyway, we're attached to it
int faceID = 0;
foreach (FaceData f in av.data)
{
if (f != null)
{
byte[] primNrBytes = Utils.Int16ToBytes((short)f.PickingID);
faceColor = new byte[] { primNrBytes[0], primNrBytes[1], (byte)faceID, 254 };
GL.Color4(faceColor);
break;
}
faceID++;
}
}
OpenTK.Vector3 quadPos = screenPos;
screenPos.Y = glControl.Height - screenPos.Y;
screenPos.X -= tSize.Width / 2;
screenPos.Y -= tSize.Height / 2 + 2;
if (screenPos.Y > 0)
{
// Render tag backround
float halfWidth = tSize.Width / 2 + 12;
float halfHeight = tSize.Height / 2 + 5;
GL.Color4(0f, 0f, 0f, 0.4f);
RHelp.Draw2DBox(quadPos.X - halfWidth, quadPos.Y - halfHeight, halfWidth * 2, halfHeight * 2, screenPos.Z);
if (pass == RenderPass.Simple)
{
textRendering.Begin();
Color textColor = pass == RenderPass.Simple ?
Color.Orange :
Color.FromArgb(faceColor[3], faceColor[0], faceColor[1], faceColor[2]);
textRendering.Print(tagText, AvatarTagFont, textColor,
new Rectangle((int)screenPos.X, (int)screenPos.Y, tSize.Width + 2, tSize.Height + 2),
flags);
textRendering.End();
}
}
}
}
lock (SortedObjects)
{
int primNr = 0;
foreach (SceneObject obj in SortedObjects)
{
if (!(obj is RenderPrimitive)) continue;
RenderPrimitive prim = (RenderPrimitive)obj;
primNr++;
if (!string.IsNullOrEmpty(prim.BasePrim.Text))
{
string text = System.Text.RegularExpressions.Regex.Replace(prim.BasePrim.Text, "(\r?\n)+", "\n");
OpenTK.Vector3 primPos = RHelp.TKVector3(prim.RenderPosition);
// Display hovertext only on objects that are withing 12m of the camera
if (prim.DistanceSquared > (12 * 12)) continue;
primPos.Z += prim.BasePrim.Scale.Z * 0.8f;
// Convert objects world position to 2D screen position in pixels
OpenTK.Vector3 screenPos;
if (!Math3D.GluProject(primPos, ModelMatrix, ProjectionMatrix, Viewport, out screenPos)) continue;
screenPos.Y = glControl.Height - screenPos.Y;
textRendering.Begin();
Color color = Color.FromArgb((int)(prim.BasePrim.TextColor.A * 255), (int)(prim.BasePrim.TextColor.R * 255), (int)(prim.BasePrim.TextColor.G * 255), (int)(prim.BasePrim.TextColor.B * 255));
TextFormatFlags flags = TextFormatFlags.HorizontalCenter | TextFormatFlags.Top;
var size = TextRendering.Measure(text, HoverTextFont, flags);
screenPos.X -= size.Width / 2;
screenPos.Y -= size.Height;
if (screenPos.Y + size.Height > 0)
{
if (pass == RenderPass.Picking)
{
//Send the prim anyway, we're attached to it
int faceID = 0;
foreach (Face f in prim.Faces)
{
if (f.UserData != null)
{
byte[] primNrBytes = Utils.Int16ToBytes((short)((FaceData)f.UserData).PickingID);
byte[] faceColor = new byte[] { primNrBytes[0], primNrBytes[1], (byte)faceID, 255 };
textRendering.Print(text, HoverTextFont, Color.FromArgb(faceColor[3], faceColor[0], faceColor[1], faceColor[2]), new Rectangle((int)screenPos.X, (int)screenPos.Y, size.Width + 2, size.Height + 2), flags);
break;
}
faceID++;
}
}
else
{
// Shadow
if (color != Color.Black)
textRendering.Print(text, HoverTextFont, Color.Black, new Rectangle((int)screenPos.X + 1, (int)screenPos.Y + 1, size.Width + 2, size.Height + 2), flags);
// Text
textRendering.Print(text, HoverTextFont, color, new Rectangle((int)screenPos.X, (int)screenPos.Y, size.Width + 2, size.Height + 2), flags);
}
}
textRendering.End();
}
}
}
}