public override void OnDraw() { #if SourceDepth24 pixfmt_alpha_blend_rgb pf = new pixfmt_alpha_blend_rgb(rbuf_window(), new blender_bgr()); #else FormatRGBA pf = new FormatRGBA(rbuf_window(), new BlenderBGRA()); #endif FormatClippingProxy clippingProxy = new FormatClippingProxy(pf); clippingProxy.Clear(new RGBA_Doubles(0, 0, 0)); RasterizerScanlineAA <T> ras = new RasterizerScanlineAA <T>(); ScanlineUnpacked8 sl = new ScanlineUnpacked8(); ScanlineBin sl_bin = new ScanlineBin(); RasterizerCompoundAA <T> rasc = new RasterizerCompoundAA <T>(); SpanAllocator alloc = new SpanAllocator(); uint i; styles_gouraud styles = new styles_gouraud(m_mesh, m_gamma); start_timer(); rasc.Reset(); //rasc.clip_box(40, 40, width() - 40, height() - 40); for (i = 0; i < m_mesh.num_edges(); i++) { mesh_edge e = m_mesh.edge(i); mesh_point p1 = m_mesh.vertex(e.p1); mesh_point p2 = m_mesh.vertex(e.p2); rasc.Styles(e.tl, e.tr); rasc.MoveToDbl(p1.x, p1.y); rasc.LineToDbl(p2.x, p2.y); } Renderer <T> .RenderCompound(rasc, sl, sl_bin, clippingProxy, alloc, styles); double tm = elapsed_time(); GsvText <T> t = new GsvText <T>(); t.SetFontSize(10.0); ConvStroke <T> pt = new ConvStroke <T>(t); pt.Width = M.New <T>(1.5); pt.LineCap = LineCap.Round; pt.LineJoin = LineJoin.RoundJoin; string buf = string.Format("{0:F2} ms, {1} triangles, {2:F0} tri/sec", tm, m_mesh.num_triangles(), m_mesh.num_triangles() / tm * 1000.0); t.StartPoint(10.0, 10.0); t.Text = buf; ras.AddPath(pt); Renderer <T> .RenderSolid(clippingProxy, ras, sl, new RGBA_Bytes(1, 1, 1).GetAsRGBA_Bytes()); if (m_gamma.Gamma() != 1.0) { pf.ApplyGammaInv(m_gamma); } }
public static void RenderCompound(RasterizerCompoundAA<T> ras, IScanlineCache sl_aa, IScanlineCache sl_bin, IPixelFormat pixelFormat, SpanAllocator alloc, IStyleHandler sh) { #if true unsafe { if (ras.RewindScanlines()) { int min_x = ras.MinX; int len = ras.MaxX - min_x + 2; sl_aa.Reset(min_x, ras.MaxX); sl_bin.Reset(min_x, ras.MaxX); //typedef typename BaseRenderer::color_type color_type; ArrayPOD<RGBA_Bytes> color_span = alloc.Allocate((uint)len * 2); byte[] ManagedCoversArray = sl_aa.Covers; fixed (byte* pCovers = ManagedCoversArray) { fixed (RGBA_Bytes* pColorSpan = color_span.Array) { int mix_bufferOffset = len; uint num_spans; uint num_styles; uint style; bool solid; while ((num_styles = ras.SweepStyles()) > 0) { if (num_styles == 1) { // Optimization for a single style. Happens often //------------------------- if (ras.SweepScanline(sl_aa, 0)) { style = ras.Style(0); if (sh.IsSolid(style)) { // Just solid fill //----------------------- RenderSolidSingleScanLine(pixelFormat, sl_aa, sh.Color(style)); } else { // Arbitrary span generator //----------------------- ScanlineSpan span_aa = sl_aa.Begin(); num_spans = sl_aa.NumSpans; for (; ; ) { len = span_aa.Len; sh.GenerateSpan(pColorSpan, span_aa.X, sl_aa.Y, (uint)len, style); pixelFormat.BlendColorHSpan(span_aa.X, sl_aa.Y, (uint)span_aa.Len, pColorSpan, &pCovers[span_aa.CoverIndex], 0); if (--num_spans == 0) break; span_aa = sl_aa.GetNextScanlineSpan(); } } } } else // there are multiple styles { if (ras.SweepScanline(sl_bin, -1)) { // Clear the spans of the mix_buffer //-------------------- ScanlineSpan span_bin = sl_bin.Begin(); num_spans = sl_bin.NumSpans; for (; ; ) { Basics.MemClear((byte*)&pColorSpan[mix_bufferOffset + span_bin.X - min_x], span_bin.Len * sizeof(RGBA_Bytes)); if (--num_spans == 0) break; span_bin = sl_bin.GetNextScanlineSpan(); } for (uint i = 0; i < num_styles; i++) { style = ras.Style(i); solid = sh.IsSolid(style); if (ras.SweepScanline(sl_aa, (int)i)) { //IColorType* colors; //IColorType* cspan; //typename ScanlineAA::cover_type* covers; ScanlineSpan span_aa = sl_aa.Begin(); num_spans = sl_aa.NumSpans; if (solid) { // Just solid fill //----------------------- for (; ; ) { RGBA_Bytes c = sh.Color(style); len = span_aa.Len; RGBA_Bytes* colors = &pColorSpan[mix_bufferOffset + span_aa.X - min_x]; byte* covers = &pCovers[span_aa.CoverIndex]; do { if (*covers == CoverFull) { *colors = c; } else { colors->Add(c, *covers); } ++colors; ++covers; } while (--len != 0); if (--num_spans == 0) break; span_aa = sl_aa.GetNextScanlineSpan(); } } else { // Arbitrary span generator //----------------------- for (; ; ) { len = span_aa.Len; RGBA_Bytes* colors = &pColorSpan[mix_bufferOffset + span_aa.X - min_x]; RGBA_Bytes* cspan = pColorSpan; sh.GenerateSpan(cspan, span_aa.X, sl_aa.Y, (uint)len, style); byte* covers = &pCovers[span_aa.CoverIndex]; do { if (*covers == CoverFull) { *colors = *cspan; } else { colors->Add(*cspan, *covers); } ++cspan; ++colors; ++covers; } while (--len != 0); if (--num_spans == 0) break; span_aa = sl_aa.GetNextScanlineSpan(); } } } } // Emit the blended result as a color hspan //------------------------- span_bin = sl_bin.Begin(); num_spans = sl_bin.NumSpans; for (; ; ) { pixelFormat.BlendColorHSpan(span_bin.X, sl_bin.Y, (uint)span_bin.Len, &pColorSpan[mix_bufferOffset + span_bin.X - min_x], null, CoverFull); if (--num_spans == 0) break; span_bin = sl_bin.GetNextScanlineSpan(); } } // if(ras.sweep_scanline(sl_bin, -1)) } // if(num_styles == 1) ... else } // while((num_styles = ras.sweep_styles()) > 0) } } } // if(ras.rewind_scanlines()) #endif } }