public void Render(Solver solver, RenderMode renderMode, bool drawObstacles = true) { float[] src; switch (renderMode) { default: case RenderMode.Density: src = solver.DensityField; break; case RenderMode.Heat: src = solver.HeatField; break; case RenderMode.Pressure: src = solver.PressureField; break; } bmData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); int pos, x, y; float val; float r, g, b; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { pos = (x << 2) + y * (width << 2); // position in byte array (x*4)+y*(w*4) // obstacles takes precedence if (drawObstacles) { if (solver.Obstacles[solver.IX(x, y, 0)] != 0) { tmpData[pos] = tmpData[pos + 1] = 0; tmpData[pos + 2] = tmpData[pos + 3] = 255; continue; } } val = src[solver.IX(x, y, 0)]; rminVal = Math.Min(val, rminVal); rmaxVal = Math.Max(val, rmaxVal); // get RGB values depending on render mode switch (renderMode) { default: case RenderMode.Density: render_density(val, out r, out g, out b); break; case RenderMode.Heat: render_heat(val, out r, out g, out b); break; case RenderMode.Pressure: render_pressure(val, out r, out g, out b); break; } // update bitmap tmpData[pos] = (byte)(b * 255); tmpData[pos + 1] = (byte)(g * 255); tmpData[pos + 2] = (byte)(r * 255); tmpData[pos + 3] = 255; /*val = (byte)(Math.Max( Math.Min( src[solver.IX(x, y, 0)], 1f), 0f) * 255); * tmpData[pos] = tmpData[pos + 1] = tmpData[pos + 2] = val; // BGR * tmpData[pos + 3] = 255; // alpha*/ } } rminValOld = rminVal; rmaxValOld = rmaxVal; rminVal = float.MaxValue; rmaxVal = float.MinValue; System.Runtime.InteropServices.Marshal.Copy(tmpData, 0, bmData.Scan0, tmpData.Length); bitmap.UnlockBits(bmData); Invalidate(); }