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); }
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); }
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); }
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); }
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); }
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); }
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); }