/// <summary> /// Take a screenshot of the host framebuffer. /// </summary> /// <returns>Hash of the screenshot.</returns> public static unsafe string TakeScreenshot() { int w = (int)Engine.Host.Size.X; int h = (int)Engine.Host.Size.Y; byte[] pixels = new byte[3 * w * h]; // Read the pixels. GLThread.ExecuteGLThread(() => { Engine.GraphicsManager.CheckError("before screenshot"); fixed(byte *pixel = &pixels[0]) { Gl.ReadPixels(0, 0, w, h, PixelFormat.Bgr, PixelType.UnsignedByte, new IntPtr(pixel)); } Engine.GraphicsManager.CheckError("after screenshot"); }); // Compute the hash. string hash = Convert.ToBase64String(new SHA256Managed().ComputeHash(pixels)); // Save the file. FIBITMAP image = FreeImage.ConvertFromRawBitsArray(pixels, w, h, w * 3, 24, 0, 0, 0, false); FreeImage.Save(FREE_IMAGE_FORMAT.FIF_PNG, image, $".{Path.DirectorySeparatorChar}ReferenceImages{Path.DirectorySeparatorChar}{_id} ~ {hash.Replace("+", "_").Replace("/", "-").Replace("=", " ")}.png", FREE_IMAGE_SAVE_FLAGS.DEFAULT); _id++; // Check if the hash is an alternative. if (_alternativeHashes.ContainsKey(hash)) { return(_alternativeHashes[hash]); } // Return hash. return(hash); }