예제 #1
0
        private static GlyphServer Create(List <ChunkBase> chunkList, int maxTextureWidth, int maxTextureHeight, int maxTextureCount)
        {
            var context = new PagesContext(maxTextureWidth, maxTextureHeight, maxTextureCount);

            foreach (var item in chunkList)
            {
                item.Put(context);
            }

            Bitmap[] bitmaps = GenerateBitmaps(chunkList, context.PageList.Count);
            PrintChunks(chunkList, context, bitmaps);

            Dictionary <string, GlyphInfo> dictionary = GetDictionary(chunkList, bitmaps[0].Width, bitmaps[0].Height);

            Texture texture = GenerateTexture(bitmaps);

            var server = new GlyphServer();

            server.dictionary    = dictionary;
            server.GlyphTexture  = texture;
            server.TextureWidth  = bitmaps[0].Width;
            server.TextureHeight = bitmaps[0].Height;

            //// test: save bitmaps to disk.
            //Test(server.dictionary, bitmaps);

            foreach (var item in bitmaps)
            {
                item.Dispose();
            }

            return(server);
        }
예제 #2
0
        private TextBillboardNode(int width, int height, GlyphsModel model, RenderMethodBuilder renderUnitBuilder, GlyphServer glyphServer = null)
            : base(model, renderUnitBuilder)
        {
            if (width <= 0)
            {
                width = 1;
            }
            if (height <= 0)
            {
                height = 1;
            }

            this._width        = width;
            this._height       = height;
            this.widthByHeight = (float)width / (float)height;
            this.heightByWidth = (float)height / (float)width;

            this.textModel = model;

            if (glyphServer == null)
            {
                this.glyphServer = GlyphServer.DefaultServer;
            }
            else
            {
                this.glyphServer = glyphServer;
            }
        }
예제 #3
0
        /// <summary>
        /// start from (0, 0) to the right.
        /// </summary>
        /// <param name="text"></param>
        /// <param name="server"></param>
        /// <param name="totalWidth"></param>
        /// <param name="totalHeight"></param>
        unsafe private void PositionPass(string text, GlyphServer server,
                                         out float totalWidth, out float totalHeight)
        {
            int          textureWidth  = server.TextureWidth;
            int          textureHeight = server.TextureHeight;
            VertexBuffer buffer        = this.positionBuffer;
            var          positionArray = (QuadStruct *)buffer.MapBuffer(MapBufferAccess.ReadWrite);
            const float  height        = 2.0f; // let's say height is 2.0f.

            totalWidth  = 0;
            totalHeight = height;
            int index = 0;

            foreach (var c in text)
            {
                GlyphInfo glyphInfo;
                float     wByH = 0;
                if (server.GetGlyphInfo(c, out glyphInfo))
                {
                    float w = (glyphInfo.quad.rightBottom.x - glyphInfo.quad.leftBottom.x) * textureWidth;
                    float h = (glyphInfo.quad.rightBottom.y - glyphInfo.quad.rightTop.y) * textureHeight;
                    wByH = height * w / h;
                }
                else
                {
                    // put an empty glyph(square) here.
                    wByH = height * 1.0f / 1.0f;
                }

                var leftTop     = new vec2(totalWidth, 1f);
                var leftBottom  = new vec2(totalWidth, -1f);
                var rightBottom = new vec2(totalWidth + wByH, -1f);
                var rightTop    = new vec2(totalWidth + wByH, 1f);
                positionArray[index++] = new QuadStruct(leftTop, leftBottom, rightBottom, rightTop);
                totalWidth            += wByH;
            }

            // move to center.
            const float scale = 1f;

            for (int i = 0; i < text.Length; i++)
            {
                QuadStruct quad   = positionArray[i];
                var        newPos = new QuadStruct(
                    // y is already in [-1, 1], so just shrink x to [-1, 1]
                    new vec2(quad.leftTop.x / totalWidth * 2.0f - 1f, quad.leftTop.y) * scale,
                    new vec2(quad.leftBottom.x / totalWidth * 2.0f - 1f, quad.leftBottom.y) * scale,
                    new vec2(quad.rightBottom.x / totalWidth * 2.0f - 1f, quad.rightBottom.y) * scale,
                    new vec2(quad.rightTop.x / totalWidth * 2.0f - 1f, quad.rightTop.y) * scale
                    );

                positionArray[i] = newPos;
            }

            buffer.UnmapBuffer();
        }
예제 #4
0
        unsafe private void ArrangeCharaters(string text, GlyphServer server)
        {
            float totalWidth, totalHeight;

            PositionPass(text, server, out totalWidth, out totalHeight);
            UVPass(text, server);

            this.drawCmd.VertexCount = text.Length * 4;                 // each alphabet needs 4 vertexes.

            this.Width = (int)(totalWidth * this.Height / totalHeight); // auto size means auto width.
        }
예제 #5
0
        unsafe private void ArrangeCharaters(string text, GlyphServer server)
        {
            float totalWidth, totalHeight;

            PositionPass(text, server, out totalWidth, out totalHeight);
            UVPass(text, server);

            this.indexBuffer.RenderingVertexCount = text.Length * 4; // each alphabet needs 4 vertexes.

            this.widthByHeight = totalWidth / totalHeight;
            this.heightByWidth = totalHeight / totalWidth;
            this.Width         = (int)(this.Height * this.widthByHeight);// auto size means auto width.
        }
예제 #6
0
        /// <summary>
        ///
        /// </summary>
        protected override void DoInitialize()
        {
            this.RenderUnit.Initialize();

            this.positionBuffer = this.labelModel.GetVertexAttributeBuffer(GlyphsModel.position);
            this.strBuffer      = this.labelModel.GetVertexAttributeBuffer(GlyphsModel.STR);
            this.indexBuffer    = this.labelModel.GetIndexBuffer() as ZeroIndexBuffer;

            GlyphServer server  = GlyphServer.DefaultServer;
            Texture     texture = server.GlyphTexture;
            string      name    = glyphTexture;

            this.RenderUnit.Methods[0].Program.SetUniform(name, texture);
        }
예제 #7
0
        static GlyphServer()
        {
            var builder = new StringBuilder();

            for (char c = (char)20; c < (char)127; c++)
            {
                builder.Append(c);
            }
            string charSet = builder.ToString();
            var    font    = new Font("Arial", 32, GraphicsUnit.Pixel);

            defaultServer = GlyphServer.Create(font, charSet);
            font.Dispose();
        }
예제 #8
0
        /// <summary>
        /// Creates a billboard in 3D world. Its size is described by Width\Height(in pixels).
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="capacity">Maximum characters count.</param>
        /// <param name="glyphServer"></param>
        /// <returns></returns>
        public static TextBillboardNode Create(int width, int height, int capacity, GlyphServer glyphServer = null)
        {
            var vs = new VertexShader(vertexCode);// this vertex shader has no vertex attributes.
            var fs = new FragmentShader(fragmentCode);
            var provider = new ShaderArray(vs, fs);
            var map = new AttributeMap();
            map.Add(inPosition, GlyphsModel.position);
            map.Add(inSTR, GlyphsModel.STR);
            var blendState = new BlendFuncSwitch(BlendSrcFactor.SrcAlpha, BlendDestFactor.OneMinusSrcAlpha);
            var builder = new RenderMethodBuilder(provider, map, blendState);
            var node = new TextBillboardNode(width, height, new GlyphsModel(capacity), builder, glyphServer);
            node.Initialize();
            node.blend = blendState;

            return node;
        }
예제 #9
0
        /// <summary>
        /// start from (0, 0) to the right.
        /// </summary>
        /// <param name="text"></param>
        /// <param name="server"></param>
        /// <param name="totalWidth"></param>
        /// <param name="totalHeight"></param>
        unsafe private void PositionPass(string text, GlyphServer server,
                                         out float totalWidth, out float totalHeight)
        {
            int          textureWidth  = server.TextureWidth;
            int          textureHeight = server.TextureHeight;
            VertexBuffer buffer        = this.positionBuffer;
            var          positionArray = (QuadPositionStruct *)buffer.MapBuffer(MapBufferAccess.ReadWrite);
            const float  height        = 2; // 2 is the height value in clip space.

            totalWidth  = 0;
            totalHeight = height;
            int index = 0;

            foreach (var c in text)
            {
                if (index >= this.textModel.Capacity)
                {
                    break;
                }

                GlyphInfo glyphInfo;
                float     wByH = 0;
                if (server.GetGlyphInfo(c, out glyphInfo))
                {
                    float w = (glyphInfo.quad.rightBottom.x - glyphInfo.quad.leftBottom.x) * textureWidth;
                    float h = (glyphInfo.quad.rightBottom.y - glyphInfo.quad.rightTop.y) * textureHeight;
                    wByH = height * w / h;
                }
                else
                {
                    // put an empty glyph(square) here.
                    wByH = height * 1.0f / 1.0f;
                }

                var leftTop     = new vec2(totalWidth, height);
                var leftBottom  = new vec2(totalWidth, 0);
                var rightBottom = new vec2(totalWidth + wByH, 0);
                var rightTop    = new vec2(totalWidth + wByH, height);
                positionArray[index++] = new QuadPositionStruct(leftTop, leftBottom, rightBottom, rightTop);

                totalWidth += wByH;
            }

            buffer.UnmapBuffer();
        }
예제 #10
0
        /// <summary>
        /// 
        /// </summary>
        protected override void DoInitialize()
        {
            base.DoInitialize();

            // make sure textModel only returns once.
            this.positionBuffer = (from item in this.textModel.GetVertexAttribute(GlyphsModel.position) select item).First();
            this.strBuffer = (from item in this.textModel.GetVertexAttribute(GlyphsModel.STR) select item).First();
            this.drawCmd = (from item in this.textModel.GetDrawCommand() select item).First() as DrawArraysCmd;

            GlyphServer server = this.glyphServer;
            Texture texture = server.GlyphTexture;
            RenderMethod method = this.RenderUnit.Methods[0]; // the only render unit in this node.
            ShaderProgram program = method.Program;
            program.SetUniform(glyphTexture, texture);
            program.SetUniform(width, this._width);
            program.SetUniform(height, this._height);
            program.SetUniform(textColor, this._color);
        }
예제 #11
0
        /// <summary>
        ///
        /// </summary>
        protected override void DoInitialize()
        {
            base.DoInitialize();

            this.positionBuffer = this.textModel.GetVertexAttributeBuffer(GlyphsModel.position);
            this.strBuffer      = this.textModel.GetVertexAttributeBuffer(GlyphsModel.STR);
            this.indexBuffer    = this.textModel.GetIndexBuffer() as ZeroIndexBuffer;

            GlyphServer   server  = this.glyphServer;
            Texture       texture = server.GlyphTexture;
            RenderMethod  method  = this.RenderUnit.Methods[0]; // the only render unit in this node.
            ShaderProgram program = method.Program;

            program.SetUniform(glyphTexture, texture);
            program.SetUniform(width, this._width);
            program.SetUniform(height, this._height);
            program.SetUniform(textColor, this._color);
        }
예제 #12
0
        /// <summary>
        /// start from (0, 0) to the right.
        /// </summary>
        /// <param name="text"></param>
        /// <param name="server"></param>
        unsafe private void UVPass(string text, GlyphServer server)
        {
            VertexBuffer buffer  = this.uvBuffer;
            var          uvArray = (QuadStruct *)buffer.MapBuffer(MapBufferAccess.WriteOnly);
            int          index   = 0;

            foreach (var c in text)
            {
                GlyphInfo glyphInfo;
                if (server.GetGlyphInfo(c, out glyphInfo))
                {
                    uvArray[index] = glyphInfo.quad;
                }

                index++;
            }

            buffer.UnmapBuffer();
        }
예제 #13
0
        /// <summary>
        /// start from (0, 0) to the right.
        /// </summary>
        /// <param name="text"></param>
        /// <param name="server"></param>
        unsafe private void TextureIndexPass(string text, GlyphServer server)
        {
            VertexBuffer buffer            = this.textureIndexBuffer;
            var          textureIndexArray = (float *)buffer.MapBuffer(MapBufferAccess.WriteOnly);
            int          index             = 0;

            foreach (var c in text)
            {
                GlyphInfo glyphInfo;
                if (server.GetGlyphInfo(c, out glyphInfo))
                {
                    textureIndexArray[index] = glyphInfo.textureIndex;
                }

                index++;
            }

            buffer.UnmapBuffer();
        }
        unsafe private void ArrangeCharaters(string text, GlyphServer server)
        {
            float totalWidth, totalHeight;

            PositionPass(text, server, out totalWidth, out totalHeight);
            UVPass(text, server);

            this.drawCmd.VertexCount = text.Length * 4; // each alphabet needs 4 vertexes.

            if (totalWidth != 0.0f && totalHeight != 0.0f)
            {
                this.widthByHeight = totalWidth / totalHeight;
                this.heightByWidth = totalHeight / totalWidth;
                this.Width         = (int)(this.Height * this.widthByHeight);// auto size means auto width.
            }
            else
            {
                this.Width = 0;
            }
        }
예제 #15
0
        /// <summary>
        /// start from (0, 0) to the right.
        /// </summary>
        /// <param name="text"></param>
        /// <param name="server"></param>
        unsafe private void UVPass(string text, GlyphServer server)
        {
            VertexBuffer buffer            = this.stringBuffer;
            var          textureIndexArray = (QuadSTRStruct *)buffer.MapBuffer(MapBufferAccess.WriteOnly);
            int          index             = 0;

            foreach (var c in text)
            {
                if (index >= this.labelModel.Capacity)
                {
                    break;
                }

                GlyphInfo glyphInfo;
                if (server.GetGlyphInfo(c, out glyphInfo))
                {
                    textureIndexArray[index] = glyphInfo.quad;
                }

                index++;
            }

            buffer.UnmapBuffer();
        }
예제 #16
0
        private static void Create(int maxTextureWidth, int maxTextureHeight, int maxTextureCount, GlyphServer server, List <ChunkBase> chunkList)
        {
            var context = new PagesContext(maxTextureWidth, maxTextureHeight, maxTextureCount);

            foreach (var item in chunkList)
            {
                item.Put(context);
            }

            Bitmap[] bitmaps = GenerateBitmaps(chunkList, context);
            PrintChunks(chunkList, context, bitmaps);

            FillDictionary(chunkList, context, server.dictionary, bitmaps[0].Width, bitmaps[0].Height);

            Texture texture = GenerateTexture(bitmaps);

            server.GlyphTexture  = texture;
            server.TextureWidth  = bitmaps[0].Width;
            server.TextureHeight = bitmaps[0].Height;

            //// test: save bitmaps to disk.
            //Test(server.dictionary, bitmaps);

            foreach (var item in bitmaps)
            {
                item.Dispose();
            }
        }
예제 #17
0
 /// <summary>
 /// Create a <see cref="GlyphServer"/> instance that provides glyph information according to specified characters.
 /// </summary>
 /// <param name="font"></param>
 /// <param name="charset"></param>
 /// <returns></returns>
 public static GlyphServer CreateGlyphServer(this Font font, IEnumerable <string> charset)
 {
     return(GlyphServer.Create(font, charset));
 }
예제 #18
0
        private static void Create(int textureWidth, int textureHeight, int maxTextureCount, GlyphServer server, List <ChunkBase> chunkList)
        {
            var context = new PagesContext(textureWidth, textureHeight, maxTextureCount);

            foreach (var item in chunkList)
            {
                item.Put(context);
            }

            Bitmap[] bitmaps = GenerateBitmaps(chunkList, context);
            PrintChunks(chunkList, context, bitmaps);
            //for (int i = 0; i < bitmaps.Length; i++)
            //{
            //    bitmaps[i].Save(string.Format("{0}.png", i));
            //}
            Texture texture = GenerateTexture(bitmaps);

            server.GlyphTexture  = texture;
            server.TextureWidth  = bitmaps[0].Width;
            server.TextureHeight = bitmaps[0].Height;
            FillDictionary(chunkList, context, server.dictionary, bitmaps[0].Width, bitmaps[0].Height);
        }