} // end childTracer static void Main(string[] args) { Stopwatch sw = Stopwatch.StartNew(); string input_config_filename = @"input.txt"; // default output file name string output_filename = @"outfile.png"; // default output file name if (args.Length > 0) { input_config_filename = args[0]; } if (args.Length > 1) { output_filename = args[1]; } ConfigFile.readFile(input_config_filename); ConfigFile.workOnConfig(); Vec3 lookfrom = ConfigParams.look_from; Vec3 lookat = ConfigParams.look_at; float dist_to_focus = (lookfrom - lookat).length(); float aperture = ConfigParams.aperture_size; float field_of_view = ConfigParams.field_of_view; int nx = ConfigParams.X_pixels; // width int ny = ConfigParams.Y_pixels; // height int ns = ConfigParams.num_samples; // number of photon samples new Camera(lookfrom, lookat, new Vec3(0.0f, 1.0f, 0.0f), field_of_view, (float)nx / (float)ny, aperture, dist_to_focus); world = ConfigParams.getScene(); sky_active_flag = ConfigParams.sky_on; //world = Scenery.my_light_scene(); sky_active_flag = false; // alternative way rc = new RayCanvas(nx, ny, ns); // call threads here. if (numThreads < 1) { numThreads = 1; } progressList = new List <int>(); for (int cc = 0; cc < numThreads; cc++) { int a = 0; progressList.Add(a); } for (int cc = 0; cc < numThreads; cc++) { Thread thread1 = new Thread( new ParameterizedThreadStart(childTracer) ); thread1.Start(cc); } // wait here until finished threads while (Interlocked.Read(ref threadCounter) < numThreads) { int pi = 0; for (int i = 0; i < progressList.Count; i++) { pi += progressList[i]; } float pp = (((float)pi / (float)progressList.Count) / (float)ny) * 100.0f; if (pp > 100.0f) { pp = 100.0f; } Console.WriteLine(pp.ToString("F2") + "%"); Thread.Sleep(1000); } // now when finished, finalize the values rc.finalize(); // write the PNG file Helper.writeToPng(output_filename, rc); sw.Stop(); Console.WriteLine(String.Format("Elapsed time: {0:N1} sec", sw.Elapsed.TotalSeconds)); Console.WriteLine("Finished."); } // end Main
public static void writeToPng(string fileName, RayCanvas rc) { // X := width :: col // Y := height :: row int width = rc.getNumXPixels(); int height = rc.getNumYPixels(); WriteableBitmap wbitmap = new WriteableBitmap( width, height, 96, 96, PixelFormats.Bgra32, null); byte[, ,] pixels = new byte[height, width, 4]; for (int col = 0; col < width; col++) { for (int row = 0; row < height; row++) { //for (int i = 0; i < 3; i++) //{ pixels[row, col, 3] = 255; // alpha? //} int ir = (int)(256 * rc.getR(col, height - row - 1)); int ig = (int)(256 * rc.getG(col, height - row - 1)); int ib = (int)(256 * rc.getB(col, height - row - 1)); if (ir > 255) { ir = 255; } if (ig > 255) { ig = 255; } if (ib > 255) { ib = 255; } pixels[row, col, 0] = (byte)ib; // Blue first, PixelFormats.Bgra32 pixels[row, col, 1] = (byte)ig; // Green pixels[row, col, 2] = (byte)ir; // Red last } } // X := width :: col // Y := height :: row byte[] pixels1d = new byte[height * width * 4]; int index = 0; for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { for (int i = 0; i < 4; i++) { pixels1d[index++] = pixels[row, col, i]; } } } Int32Rect rect = new Int32Rect(0, 0, width, height); int stride = 4 * width; wbitmap.WritePixels(rect, pixels1d, stride, 0); string filePath = fileName; var fileStream = new FileStream(filePath, FileMode.Create); BitmapEncoder encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(wbitmap)); encoder.Save(fileStream); fileStream.Close(); }