Example #1
0
        public override bool Convert(ConvertOperation convert)
        {
            bool finishConvertOp = false;
            List<Texture> availData = convert.Perform<Texture>().ToList();

            // Generate objects
            foreach (Texture baseRes in availData)
            {
                if (convert.IsObjectHandled(baseRes)) continue;

                // Find target Resource matching the source - or create one.
                Material targetRes =
                    this.FindMatchingResources<Texture,Material>(baseRes, IsMatch)
                    .FirstOrDefault();
                if (targetRes == null && convert.AllowedOperations.HasFlag(ConvertOperation.Operation.CreateRes))
                {
                    string resPath = PathHelper.GetFreePath(baseRes.FullName, Resource.GetFileExtByType<Material>());
                    targetRes = new Material(DrawTechnique.Mask, ColorRgba.White, baseRes);
                    targetRes.Save(resPath);
                }

                if (targetRes == null) continue;
                convert.AddResult(targetRes);
                finishConvertOp = true;
                convert.MarkObjectHandled(baseRes);
            }

            return finishConvertOp;
        }
        public override bool Convert(ConvertOperation convert)
        {
            bool finishConvertOp = false;
            List<BatchInfo> availData = convert.Perform<BatchInfo>().ToList();

            // Generate objects
            foreach (BatchInfo info in availData)
            {
                if (convert.IsObjectHandled(info)) continue;

                // Auto-Generate Material
                string matName = "Material";
                if (!info.MainTexture.IsExplicitNull) matName = info.MainTexture.FullName;
                string matPath = PathHelper.GetFreePath(matName, Resource.GetFileExtByType<Material>());
                Material mat = new Material(info);
                mat.Save(matPath);

                convert.AddResult(mat);
                finishConvertOp = true;
                convert.MarkObjectHandled(info);
            }

            return finishConvertOp;
        }
Example #3
0
 private static bool IsMatch(Texture source, Material target)
 {
     return target.MainTexture == source;
 }
Example #4
0
        private void GenerateResources()
        {
            if (this.mat != null || this.texture != null || this.pixelData != null)
                this.ReleaseResources();

            TextRenderingHint textRenderingHint;
            if (this.renderMode == RenderMode.MonochromeBitmap)
                textRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;
            else
                textRenderingHint = TextRenderingHint.AntiAliasGridFit;

            int cols;
            int rows;
            cols = rows = (int)Math.Ceiling(Math.Sqrt(SupportedChars.Length));

            Pixmap.Layer pixelLayer = new Pixmap.Layer(MathF.RoundToInt(cols * this.internalFont.Size * 1.2f), MathF.RoundToInt(rows * this.internalFont.Height * 1.2f));
            Pixmap.Layer glyphTemp;
            Pixmap.Layer glyphTempTypo;
            Bitmap bm;
            Bitmap measureBm = new Bitmap(1, 1);
            Rect[] atlas = new Rect[SupportedChars.Length];
            using (Graphics measureGraphics = Graphics.FromImage(measureBm))
            {
                Brush fntBrush = new SolidBrush(Color.Black);

                StringFormat formatDef = StringFormat.GenericDefault;
                formatDef.LineAlignment = StringAlignment.Near;
                formatDef.FormatFlags = 0;
                StringFormat formatTypo = StringFormat.GenericTypographic;
                formatTypo.LineAlignment = StringAlignment.Near;

                int x = 1;
                int y = 1;
                for (int i = 0; i < SupportedChars.Length; ++i)
                {
                    string str = SupportedChars[i].ToString(CultureInfo.InvariantCulture);
                    bool isSpace = str == " ";
                    SizeF charSize = measureGraphics.MeasureString(str, this.internalFont, pixelLayer.Width, formatDef);

                    // Rasterize a single glyph for rendering
                    bm = new Bitmap((int)Math.Ceiling(Math.Max(1, charSize.Width)), this.internalFont.Height + 1);
                    using (Graphics glyphGraphics = Graphics.FromImage(bm))
                    {
                        glyphGraphics.Clear(Color.Transparent);
                        glyphGraphics.TextRenderingHint = textRenderingHint;
                        glyphGraphics.DrawString(str, this.internalFont, fntBrush, new RectangleF(0, 0, bm.Width, bm.Height), formatDef);
                    }
                    glyphTemp = new Pixmap.Layer(bm);

                    // Rasterize a single glyph in typographic mode for metric analysis
                    if (!isSpace)
                    {
                        Rectangle glyphTempBounds = glyphTemp.OpaqueBounds();
                        glyphTemp.SubImage(glyphTempBounds.X, 0, glyphTempBounds.Width, glyphTemp.Height);
                        if (BodyAscentRef.Contains(SupportedChars[i]))
                            this.bodyAscent += glyphTempBounds.Height;

                        bm = new Bitmap((int)Math.Ceiling(Math.Max(1, charSize.Width)), this.internalFont.Height + 1);
                        using (Graphics glyphGraphics = Graphics.FromImage(bm))
                        {
                            glyphGraphics.Clear(Color.Transparent);
                            glyphGraphics.TextRenderingHint = textRenderingHint;
                            glyphGraphics.DrawString(str, this.internalFont, fntBrush, new RectangleF(0, 0, bm.Width, bm.Height), formatTypo);
                        }
                        glyphTempTypo = new Pixmap.Layer(bm);
                        glyphTempTypo.Crop(true, false);
                    }
                    else
                    {
                        glyphTempTypo = glyphTemp;
                    }

                    // Update xy values if it doesn't fit anymore
                    if (x + glyphTemp.Width + 2 > pixelLayer.Width)
                    {
                        x = 1;
                        y += this.internalFont.Height + MathF.Clamp((int)MathF.Ceiling(this.internalFont.Height * 0.1875f), 3, 10);
                    }

                    // Memorize atlas coordinates & glyph data
                    this.maxGlyphWidth = Math.Max(this.maxGlyphWidth, glyphTemp.Width);
                    this.glyphs[i].width = glyphTemp.Width;
                    this.glyphs[i].height = glyphTemp.Height;
                    this.glyphs[i].offsetX = glyphTemp.Width - glyphTempTypo.Width;
                    if (isSpace)
                    {
                        this.glyphs[i].width /= 2;
                        this.glyphs[i].offsetX /= 2;
                    }
                    atlas[i].X = x;
                    atlas[i].Y = y;
                    atlas[i].W = glyphTemp.Width;
                    atlas[i].H = (this.internalFont.Height + 1);

                    // Draw it onto the font surface
                    glyphTemp.DrawOnto(pixelLayer, BlendMode.Solid, x, y);

                    x += glyphTemp.Width + MathF.Clamp((int)MathF.Ceiling(this.internalFont.Height * 0.125f), 2, 10);
                }
            }

            // White out texture except alpha channel.
            for (int i = 0; i < pixelLayer.Data.Length; i++)
            {
                pixelLayer.Data[i].R = 255;
                pixelLayer.Data[i].G = 255;
                pixelLayer.Data[i].B = 255;
            }

            // Determine Font properties
            this.height = this.internalFont.Height;
            this.ascent = (int)Math.Round(this.internalFont.FontFamily.GetCellAscent(this.internalFont.Style) * this.internalFont.Size / this.internalFont.FontFamily.GetEmHeight(this.internalFont.Style));
            this.bodyAscent /= BodyAscentRef.Length;
            this.descent = (int)Math.Round(this.internalFont.FontFamily.GetCellDescent(this.internalFont.Style) * this.internalFont.GetHeight() / this.internalFont.FontFamily.GetLineSpacing(this.internalFont.Style));
            this.baseLine = (int)Math.Round(this.internalFont.FontFamily.GetCellAscent(this.internalFont.Style) * this.internalFont.GetHeight() / this.internalFont.FontFamily.GetLineSpacing(this.internalFont.Style));

            // Create internal Pixmap and Texture Resources
            this.pixelData = new Pixmap(pixelLayer);
            this.pixelData.Atlas = new List<Rect>(atlas);
            this.texture = new Texture(this.pixelData,
                Texture.SizeMode.Enlarge,
                this.IsPixelGridAligned ? TextureMagFilter.Nearest : TextureMagFilter.Linear,
                this.IsPixelGridAligned ? TextureMinFilter.Nearest : TextureMinFilter.LinearMipmapLinear);

            // Select DrawTechnique to use
            ContentRef<DrawTechnique> technique;
            if (this.renderMode == RenderMode.MonochromeBitmap)
                technique = DrawTechnique.Mask;
            else if (this.renderMode == RenderMode.GrayscaleBitmap)
                technique = DrawTechnique.Alpha;
            else if (this.renderMode == RenderMode.SmoothBitmap)
                technique = DrawTechnique.Alpha;
            else
                technique = DrawTechnique.SharpAlpha;

            // Create and configure internal BatchInfo
            BatchInfo matInfo = new BatchInfo(technique, ColorRgba.White, this.texture);
            if (technique == DrawTechnique.SharpAlpha)
            {
                matInfo.SetUniform("smoothness", this.size * 3.0f);
            }
            this.mat = new Material(matInfo);
        }
Example #5
0
        private void ReleaseResources()
        {
            if (this.mat != null) this.mat.Dispose();
            if (this.texture != null) this.texture.Dispose();
            if (this.pixelData != null) this.pixelData.Dispose();

            this.mat = null;
            this.texture = null;
            this.pixelData = null;

            this.needsReload = true;
        }
Example #6
0
		private void GenerateTexMat()
		{
			if (this.material != null) this.material.Dispose();
			if (this.texture != null) this.texture.Dispose();

			if (this.pixelData == null)
				return;

			this.texture = new Texture(this.pixelData, 
				TextureSizeMode.Enlarge, 
				this.IsPixelGridAligned ? TextureMagFilter.Nearest : TextureMagFilter.Linear,
				this.IsPixelGridAligned ? TextureMinFilter.Nearest : TextureMinFilter.LinearMipmapLinear);

			// Select DrawTechnique to use
			ContentRef<DrawTechnique> technique;
			if (this.renderMode == RenderMode.MonochromeBitmap)
				technique = DrawTechnique.Mask;
			else if (this.renderMode == RenderMode.GrayscaleBitmap)
				technique = DrawTechnique.Alpha;
			else if (this.renderMode == RenderMode.SmoothBitmap)
				technique = DrawTechnique.Alpha;
			else
				technique = DrawTechnique.SharpAlpha;

			// Create and configure internal BatchInfo
			BatchInfo matInfo = new BatchInfo(technique, ColorRgba.White, this.texture);
			if (technique == DrawTechnique.SharpAlpha)
			{
				matInfo.SetUniform("smoothness", this.size * 4.0f);
			}
			this.material = new Material(matInfo);
		}
Example #7
0
		private void ReleaseResources()
		{
			if (this.material != null) this.material.Dispose();
			if (this.texture != null) this.texture.Dispose();
			if (this.pixelData != null) this.pixelData.Dispose();

			this.material = null;
			this.texture = null;
			this.pixelData = null;

			this.glyphsDirty = true;
		}
Example #8
0
		private void GenerateResources()
		{
			if (this.mat != null || this.texture != null || this.pixelData != null)
				this.ReleaseResources();

			int cols;
			int rows;
			cols = rows = (int)Math.Ceiling(Math.Sqrt(SupportedChars.Length));

			Pixmap.Layer pixelLayer = new Pixmap.Layer(MathF.RoundToInt(cols * this.internalFont.Size), MathF.RoundToInt(rows * (this.internalFont.Height + 1)));
			Pixmap.Layer glyphTemp;
			Pixmap.Layer glyphTempTypo;
			Bitmap bm;
			Bitmap measureBm = new Bitmap(1, 1);
			Rect[] atlas = new Rect[SupportedChars.Length];
			using (Graphics measureGraphics = Graphics.FromImage(measureBm))
			{
				Brush fntBrush = new SolidBrush(Color.Black);

				StringFormat formatDef = StringFormat.GenericDefault;
				formatDef.LineAlignment = StringAlignment.Near;
				formatDef.FormatFlags = 0;
				StringFormat formatTypo = StringFormat.GenericTypographic;
				formatTypo.LineAlignment = StringAlignment.Near;

				int x = 0;
				int y = 0;
				for (int i = 0; i < SupportedChars.Length; ++i)
				{
					string str = SupportedChars[i].ToString(CultureInfo.InvariantCulture);
					bool isSpace = str == " ";
					SizeF charSize = measureGraphics.MeasureString(str, this.internalFont, pixelLayer.Width, formatDef);

					// Render a single glyph
					bm = new Bitmap((int)Math.Ceiling(Math.Max(1, charSize.Width)), this.internalFont.Height + 1);
					using (Graphics glyphGraphics = Graphics.FromImage(bm))
					{
						glyphGraphics.Clear(Color.Transparent);
						glyphGraphics.TextRenderingHint = (System.Drawing.Text.TextRenderingHint)this.hint;
						glyphGraphics.DrawString(str, this.internalFont, fntBrush, new RectangleF(0, 0, bm.Width, bm.Height), formatDef);
					}
					glyphTemp = new Pixmap.Layer(bm);
					
					if (!isSpace)
					{
						Rectangle glyphTempBounds = glyphTemp.OpaqueBounds();
						glyphTemp.SubImage(glyphTempBounds.X, 0, glyphTempBounds.Width, glyphTemp.Height);
						if (BodyAscentRef.Contains(SupportedChars[i]))
							this.bodyAscent += glyphTempBounds.Height;
						
						// Render a single glyph in typographic mode
						bm = new Bitmap((int)Math.Ceiling(Math.Max(1, charSize.Width)), this.internalFont.Height + 1);
						using (Graphics glyphGraphics = Graphics.FromImage(bm))
						{
							glyphGraphics.Clear(Color.Transparent);
							glyphGraphics.TextRenderingHint = (System.Drawing.Text.TextRenderingHint)this.hint;
							glyphGraphics.DrawString(str, this.internalFont, fntBrush, new RectangleF(0, 0, bm.Width, bm.Height), formatTypo);
						}
						glyphTempTypo = new Pixmap.Layer(bm);
						glyphTempTypo.Crop(true, false);
					}
					else
						glyphTempTypo = glyphTemp;

					// Update xy values if it doesn't fit anymore
					if (x + glyphTemp.Width + 2 > pixelLayer.Width)
					{
						x = 0;
						y += (this.internalFont.Height + 1) + 2;
					}
					
					// Memorize atlas coordinates & glyph data
					this.maxGlyphWidth = Math.Max(this.maxGlyphWidth, glyphTemp.Width);
					this.glyphs[i].width = glyphTemp.Width;
					this.glyphs[i].height = glyphTemp.Height;
					this.glyphs[i].offsetX = glyphTemp.Width - glyphTempTypo.Width;
					if (isSpace)
					{
						this.glyphs[i].width /= 2;
						this.glyphs[i].offsetX /= 2;
					}
					atlas[i].X = x;
					atlas[i].Y = y;
					atlas[i].W = glyphTemp.Width;
					atlas[i].H = (this.internalFont.Height + 1);

					// Draw it onto the font surface
					glyphTemp.DrawOnto(pixelLayer, BlendMode.Solid, x, y);

					x += glyphTemp.Width + 2;
				}
			}

			// Adjust colors based on alpha value
			//for (int i = 0; i < pixelLayer.Data.Length; i++)
			System.Threading.Tasks.Parallel.For(0, pixelLayer.Data.Length, i =>
			{
				float factor = pixelLayer.Data[i].A / 255.0f;
				float invFactor = 1.0f - factor;
				pixelLayer.Data[i].R = (byte)Math.Min(255.0f, Math.Max(0.0f, this.bgColor.R * invFactor + this.color.R * factor));
				pixelLayer.Data[i].G = (byte)Math.Min(255.0f, Math.Max(0.0f, this.bgColor.G * invFactor + this.color.G * factor));
				pixelLayer.Data[i].B = (byte)Math.Min(255.0f, Math.Max(0.0f, this.bgColor.B * invFactor + this.color.B * factor));
				pixelLayer.Data[i].A = (byte)Math.Min(255.0f, Math.Max(0.0f, this.bgColor.A * invFactor + this.color.A * factor));
			});

			this.height = this.internalFont.Height;
			this.ascent = (int)Math.Round(this.internalFont.FontFamily.GetCellAscent(this.internalFont.Style) * this.internalFont.Size / this.internalFont.FontFamily.GetEmHeight(this.internalFont.Style));
			this.bodyAscent /= BodyAscentRef.Length;
			this.descent = (int)Math.Round(this.internalFont.FontFamily.GetCellDescent(this.internalFont.Style) * this.internalFont.GetHeight() / this.internalFont.FontFamily.GetLineSpacing(this.internalFont.Style));
			this.baseLine = (int)Math.Round(this.internalFont.FontFamily.GetCellAscent(this.internalFont.Style) * this.internalFont.GetHeight() / this.internalFont.FontFamily.GetLineSpacing(this.internalFont.Style));

			bool useNearest = this.hint == RenderHint.Monochrome || !this.filtering;

			this.pixelData = new Pixmap(pixelLayer);
			this.pixelData.Atlas = new List<Rect>(atlas);
			this.texture = new Texture(this.pixelData, 
				Texture.SizeMode.Enlarge, 
				useNearest ? OpenTK.Graphics.OpenGL.TextureMagFilter.Nearest : OpenTK.Graphics.OpenGL.TextureMagFilter.Linear,
				useNearest ? OpenTK.Graphics.OpenGL.TextureMinFilter.Nearest : OpenTK.Graphics.OpenGL.TextureMinFilter.LinearMipmapLinear);

			this.mat = new Material(this.hint == RenderHint.Monochrome ? DrawTechnique.Mask : DrawTechnique.Alpha, ColorRgba.White, this.texture);
		}
Example #9
0
        private void GenerateMaterial()
        {
            if (this.material != null) this.material.Dispose();

            if (this.texture == null)
                return;

            // Select DrawTechnique to use
            ContentRef<DrawTechnique> technique;
            if (this.renderMode == RenderMode.MonochromeBitmap)
                technique = DrawTechnique.Mask;
            else if (this.renderMode == RenderMode.GrayscaleBitmap)
                technique = DrawTechnique.Alpha;
            else if (this.renderMode == RenderMode.SmoothBitmap)
                technique = DrawTechnique.Alpha;
            else
                technique = DrawTechnique.SharpAlpha;

            // Create and configure internal BatchInfo
            BatchInfo matInfo = new BatchInfo(technique, ColorRgba.White, this.texture);
            if (technique == DrawTechnique.SharpAlpha)
            {
                matInfo.SetUniform("smoothness", this.size * 4.0f);
            }
            this.material = new Material(matInfo);
        }
Example #10
0
 /// <summary>
 /// Creates a new Material Resource based on the specified Texture, saves it and returns a reference to it.
 /// </summary>
 /// <param name="baseRes"></param>
 /// <returns></returns>
 public static ContentRef<Material> CreateFromTexture(ContentRef<Texture> baseRes)
 {
     string resPath = PathHelper.GetFreePath(baseRes.FullName, Resource.GetFileExtByType<Material>());
     Material res = new Material(DrawTechnique.Mask, ColorRgba.White, baseRes);
     res.Save(resPath);
     return res;
 }