Пример #1
0
        protected override void PrepareRendering(IDrawDevice device, BatchInfo material)
        {
            base.PrepareRendering(device, material);

            Vector3 camPos     = device.RefCoord;
            float   camRefDist = MathF.Abs(device.FocusDist);

            // Don't pass RefDist, see note in Light.cs
            material.SetUniform("_camRefDist", camRefDist);
            material.SetUniform("_camWorldPos", camPos.X, camPos.Y, camPos.Z);

            DynamicLighting.Light.SetupLighting(device, material);
        }
Пример #2
0
        public override void PrepareRendering(IDrawDevice device, BatchInfo material)
        {
            base.PrepareRendering(device, material);

            Vector3 camPos = device.RefCoord;
            float camRefDist = MathF.Abs(device.FocusDist);

            // Don't pass RefDist, see note in Light.cs
            material.SetUniform("_camRefDist", camRefDist);
            material.SetUniform("_camWorldPos", camPos.X, camPos.Y, camPos.Z);

            DynamicLighting.Light.SetupLighting(device, material);
        }
Пример #3
0
        public static void SetupLighting(IDrawDevice device, BatchInfo material)
        {
            DeviceLightInfo info = UpdateLighting(device);

            // Prepare shader dara
            float[] _lightPos   = new float[4 * MaxVisible];
            float[] _lightDir   = new float[4 * MaxVisible];
            float[] _lightColor = new float[3 * MaxVisible];
            int     _lightCount = MathF.Min(MaxVisible, info.PriorizedLights.Count);

            int i = 0;

            foreach (Light light in info.PriorizedLights)
            {
                if (light.Disposed)
                {
                    continue;
                }

                Vector3 dir;
                Vector3 pos;
                float   uniformScale;
                bool    directional = light.IsDirectional;
                if (directional)
                {
                    dir          = light.dir;
                    pos          = Vector3.Zero;
                    uniformScale = 1.0f;
                }
                else
                {
                    dir          = light.dir;
                    pos          = light.GameObj.Transform.Pos;
                    uniformScale = light.GameObj.Transform.Scale;

                    MathF.TransformCoord(ref dir.X, ref dir.Y, light.GameObj.Transform.Angle);
                }

                if (directional)
                {
                    _lightPos[i * 4 + 0] = (float)light.ambientColor.R * light.ambientIntensity / 255.0f;
                    _lightPos[i * 4 + 1] = (float)light.ambientColor.G * light.ambientIntensity / 255.0f;
                    _lightPos[i * 4 + 2] = (float)light.ambientColor.B * light.ambientIntensity / 255.0f;
                    _lightPos[i * 4 + 3] = 0.0f;
                }
                else
                {
                    _lightPos[i * 4 + 0] = pos.X;
                    _lightPos[i * 4 + 1] = pos.Y;
                    _lightPos[i * 4 + 2] = pos.Z;
                    _lightPos[i * 4 + 3] = light.range * uniformScale;
                }

                _lightDir[i * 4 + 0] = dir.X;
                _lightDir[i * 4 + 1] = dir.Y;
                _lightDir[i * 4 + 2] = dir.Z;
                _lightDir[i * 4 + 3] = dir == Vector3.Zero ? 0.0f : MathF.Max(light.spotFocus, 1.0f);

                _lightColor[i * 3 + 0] = (float)light.color.R * light.intensity / 255.0f;
                _lightColor[i * 3 + 1] = (float)light.color.G * light.intensity / 255.0f;
                _lightColor[i * 3 + 2] = (float)light.color.B * light.intensity / 255.0f;

                i++;
                if (i >= _lightCount)
                {
                    break;
                }
            }
            if (i + 1 < _lightCount)
            {
                _lightCount = i + 1;
            }

            material.SetUniform("_lightCount", _lightCount);
            material.SetUniform("_lightPos", _lightPos);
            material.SetUniform("_lightDir", _lightDir);
            material.SetUniform("_lightColor", _lightColor);
        }
Пример #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);
        }
Пример #5
0
        public static void SetupLighting(IDrawDevice device, BatchInfo material)
        {
            DeviceLightInfo info = UpdateLighting(device);

            // Prepare shader dara
            float[] _lightPos = new float[4 * MaxVisible];
            float[] _lightDir = new float[4 * MaxVisible];
            float[] _lightColor = new float[3 * MaxVisible];
            int _lightCount = MathF.Min(MaxVisible, info.PriorizedLights.Count);

            int i = 0;
            foreach (Light light in info.PriorizedLights)
            {
                if (light.Disposed) continue;

                Vector3 dir;
                Vector3 pos;
                float uniformScale;
                bool directional = light.IsDirectional;
                if (directional)
                {
                    dir = light.dir;
                    pos = Vector3.Zero;
                    uniformScale = 1.0f;
                }
                else
                {
                    dir = light.dir;
                    pos = light.GameObj.Transform.Pos;
                    uniformScale = light.GameObj.Transform.Scale;

                    MathF.TransformCoord(ref dir.X, ref dir.Y, light.GameObj.Transform.Angle);
                }

                if (directional)
                {
                    _lightPos[i * 4 + 0] = (float)light.ambientColor.R * light.ambientIntensity / 255.0f;
                    _lightPos[i * 4 + 1] = (float)light.ambientColor.G * light.ambientIntensity / 255.0f;
                    _lightPos[i * 4 + 2] = (float)light.ambientColor.B * light.ambientIntensity / 255.0f;
                    _lightPos[i * 4 + 3] = 0.0f;
                }
                else
                {
                    _lightPos[i * 4 + 0] = pos.X;
                    _lightPos[i * 4 + 1] = pos.Y;
                    _lightPos[i * 4 + 2] = pos.Z;
                    _lightPos[i * 4 + 3] = light.range * uniformScale;
                }

                _lightDir[i * 4 + 0] = dir.X;
                _lightDir[i * 4 + 1] = dir.Y;
                _lightDir[i * 4 + 2] = dir.Z;
                _lightDir[i * 4 + 3] = dir == Vector3.Zero ? 0.0f : MathF.Max(light.spotFocus, 1.0f);

                _lightColor[i * 3 + 0] = (float)light.color.R * light.intensity / 255.0f;
                _lightColor[i * 3 + 1] = (float)light.color.G * light.intensity / 255.0f;
                _lightColor[i * 3 + 2] = (float)light.color.B * light.intensity / 255.0f;

                i++;
                if (i >= _lightCount) break;
            }
            if (i + 1 < _lightCount) _lightCount = i + 1;

            material.SetUniform("_lightCount", _lightCount);
            material.SetUniform("_lightPos", _lightPos);
            material.SetUniform("_lightDir", _lightDir);
            material.SetUniform("_lightColor", _lightColor);
        }
Пример #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);
		}
Пример #7
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);
        }