Example #1
0
        internal unsafe override void Use(Camera sender)
        {
            if (!this.Enabled || (this.WObject.Layer & sender.RenderLayers) == 0 || Deleted || Label == null || Material == null || Label.Text == null)
            {
                return;
            }

            Matrix4D   transform;
            Quaternion rot = this.WObject.Rotation;

            Vector3D extents = this.Label.GlobalScale / 2.0D;
            Vector3D middle  = this.Label.GlobalPosition;


            double fontSize = Label.FontSize;

            if (Label.AutoSize)
            {
                fontSize = WMath.Min((extents.Y * 2.0D) / Label.Lines.Length, double.PositiveInfinity); //todo: min between max height and max width
            }

            double wordSpace  = (Label.WordSpace * fontSize);
            double lineSpace  = (Label.LineSpace * fontSize) / (Label.Lines.Length * 0.5D);
            double totalYSize = Label.LineSpace * fontSize * Label.Lines.Length;

            int xDir = 0, yDir = 0;

            if (Label.Aligns.HasFlag(TextAligns.Left))
            {
                xDir += 1;
            }
            if (Label.Aligns.HasFlag(TextAligns.Right))
            {
                xDir -= 1;
            }
            if (Label.Aligns.HasFlag(TextAligns.Up))
            {
                yDir -= 1;
            }
            if (Label.Aligns.HasFlag(TextAligns.Down))
            {
                yDir += 1;
            }

            double dst = Label.ShadowDistance;

            dst *= fontSize;

            Vector3D globalShift = new Vector3D(-dst, -dst, Label.Depth);
            Color256 shadColr    = Label.Color * 0.33D;
            Color256 col         = new Color256(shadColr.R, shadColr.G, shadColr.B, 0.75D);


            int dummy = 0;

            Material.MaterialData matData = this.Material._Data.Where(d => d.Name == "transform").FirstOrDefault();

            if (matData == null)
            {
                return;
            }

            bool doRotate = Label.Rotation != 0.0D;

            Quaternion labelRotation = new Quaternion(Vector3D.Forward, Label.Rotation);

            void RenderLabel()
            {
                this.Material.Use(sender);

                int count = 0;

                for (int i = 0; i < this.Label.Lines.Length; i++)
                {
                    string str = this.Label.Lines[i];

                    Glyph[] glyphs = Label.FontFamilly.Glyphs[str];

                    Mesh[] meshes = Label.FontFamilly.Glyphs.GetMeshes(str);


                    double lineXSize = 0.0D;

                    for (int j = 0; j < glyphs.Length; j++)
                    {
                        if (str[j] == ' ')
                        {
                            lineXSize += wordSpace;
                            continue;
                        }

                        double glyphratio = (double)glyphs[j].Width / (double)glyphs[j].Height;
                        lineXSize += glyphratio * fontSize;
                    }

                    double lineXStartPos, lineYPos;

                    if (xDir == 1)
                    {
                        lineXStartPos = extents.X;            // left: -extents x
                    }
                    else if (xDir == -1)
                    {
                        lineXStartPos = -extents.X + lineXSize;                  //right: starts at extents x
                    }
                    else
                    {
                        lineXStartPos = lineXSize / 2.0F;  //center: starts at -half x size
                    }
                    if (yDir == -1)
                    {
                        lineYPos = extents.Y - fontSize * (i + 1);
                    }
                    else if (yDir == 1)
                    {
                        lineYPos = -extents.Y + fontSize * ((this.Label.Lines.Length - 1) - i);
                    }
                    else
                    {
                        lineYPos = WMath.Remap((1.0D - (((double)i + 1) / ((double)this.Label.Lines.Length))), 0.0D, 1.0D, -totalYSize * 0.5D, totalYSize * 0.5D);
                    }

                    double shiftX = 0.0D;

                    /*if (xDir == 1) shiftX = 0.0F;
                     * else if (xDir == -1) shiftX = (extents.X * 2.0F) - */

                    Vector3F trans;

                    void Render(int index)
                    {
                        trans = new Vector3D(middle.X + lineXStartPos - shiftX, middle.Y + lineYPos, middle.Z) + globalShift;


                        Quaternion rotation = rot;

                        if (doRotate)
                        {
                            rotation *= labelRotation;
                            trans     = trans.RotateAround(middle, labelRotation);
                        }


                        transform =
                            new Matrix4D(new Vector3D(fontSize), true) *
                            new Matrix4D(rotation) *
                            new Matrix4D(trans, false) *
                            Matrix4D.Identity *


                            /*(Matrix4.CreateScale(fontSize, fontSize, fontSize) *
                             * Matrix4.CreateFromQuaternion(new OpenTK.Quaternion((float)rot.X, (float)rot.Y, (float)rot.Z, (float)rot.W)) *
                             * Matrix4.CreateTranslation(trans.X, trans.Y, trans.Z) *
                             * Matrix4.Identity) **/
                            sender.ViewMatrix * sender.ProjectionMatrix;

                        GL.BindVertexArray(meshes[index].VertexArrayObject);
                        GL.BindBuffer(BufferTarget.ArrayBuffer, meshes[index].VertexBufferObject);

                        //matData.Data = transform;
                        //this.Material.SetData<Matrix4>("transform", transform);

                        //this.Material.SetGLData(ref matData, ref dummy);
                        this.Material.SetMatrix4(matData.Location, (Matrix4)transform);
                        this.Material.Shader.Use();
                        GL.Disable(EnableCap.DepthTest);

                        GL.DrawElements((Wireframe | Global_Wireframe) ? PrimitiveType.LineLoop : PrimitiveType.Triangles, (int)meshes[index].Indices, DrawElementsType.UnsignedInt, 0);
                    }

                    for (int j = 0; j < glyphs.Length; j++)
                    {
                        if (str[j] == ' ')
                        {
                            shiftX += wordSpace;
                            continue;
                        }

                        float glyphratio = (float)glyphs[j].Width / (float)glyphs[j].Height;
                        shiftX += glyphratio * fontSize;

                        Render(j);
                    }
                }

                //GL.MultiDrawElementsIndirect((Wireframe | Global_Wireframe) ? PrimitiveType.LineLoop : PrimitiveType.Triangles, DrawElementsType.UnsignedInt, , , Shader.Size);
                //GL.DrawElementsInstanced((Wireframe | Global_Wireframe) ? PrimitiveType.LineLoop : PrimitiveType.Triangles, count, DrawElementsType.UnsignedInt, , 0);
            }

            if (Label.Shadows)
            {
                this.Material.SetData <OpenTK.Vector4>("color", col);
                RenderLabel();
            }

            globalShift = new Vector3F(0.0F, 0.0F, (float)Label.Depth);
            col         = Label.Color;

            this.Material.SetData <OpenTK.Vector4>("color", col);

            RenderLabel();

            _previousText = Label.Text;
        }