/// <summary> /// Creates initial bitmap to be used as sphere texture /// </summary> /// <param name="options">Rendering options</param> /// <returns>Bitmap instance</returns> protected Bitmap CreateTextureBitmap(RendererOptions options) { Bitmap sourceBitmap = new Bitmap(options.TextureFilePath); // render martian polar caps if (options.RenderPolarCaps) { using (Graphics g = Graphics.FromImage(sourceBitmap)) { const float df = 2.5f / 180f; { float f = (float)(options.NorthernPolarCap / 180.0); var br = new LinearGradientBrush(new Point(0, 0), new PointF(0, sourceBitmap.Height), Color.White, Color.Transparent); br.Blend = new Blend(4) { Factors = new float[] { 0, 0, 1, 1 }, Positions = new float[] { 0, Math.Max(0, f - df), Math.Min(1, f + df), 1 } }; g.FillRectangle(br, 0, 0, sourceBitmap.Width, sourceBitmap.Height); } { float f = (float)((180 - options.SouthernPolarCap) / 180.0); var br = new LinearGradientBrush(new Point(0, 0), new PointF(0, sourceBitmap.Height), Color.Transparent, Color.White); br.Blend = new Blend(4) { Factors = new float[] { 0, 0, 1, 1 }, Positions = new float[] { 0, Math.Max(0, f - df), Math.Min(1, f + df), 1 } }; g.FillRectangle(br, 0, 0, sourceBitmap.Width, sourceBitmap.Height); } } } sourceBitmap.Colorize(options.ColorSchema); return(sourceBitmap); }
public override Image Render(RendererOptions options) { if (window == null) { int size = 1; window = new GameWindow(size, size, new GraphicsMode(new ColorFormat(8, 8, 8, 8), 24, 0, 0, ColorFormat.Empty, 1), "", GameWindowFlags.Default, DisplayDevice.Default, 3, 0, GraphicsContextFlags.Offscreen) { WindowState = WindowState.Fullscreen, Visible = false }; window.TargetRenderPeriod = 1; window.TargetUpdateFrequency = 1; } GL.ClearColor(Color.Transparent); using (Bitmap sourceBitmap = CreateTextureBitmap(options)) { BitmapData data; int size = (int)options.OutputImageSize; if (window.ClientSize.Width != size || window.ClientSize.Height != size) { window.ClientSize = new Size(size, size); System.Windows.Application.Current.Dispatcher.Invoke(() => System.Windows.Application.Current.MainWindow?.Activate()); } Rectangle rect = new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height); data = sourceBitmap.LockBits(rect, ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); double crds = 1; GL.Viewport(0, 0, size, size); GL.MatrixMode(MatrixMode.Projection); GL.LoadIdentity(); GL.Ortho(-crds, crds, -crds, crds, -crds, crds); GL.Rotate(90, new Vector3d(0, 0, 1)); GL.Rotate(90 - options.LatitudeShift, new Vector3d(0, 1, 0)); GL.Rotate(-options.LongutudeShift, new Vector3d(0, 0, 1)); GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit); GL.Viewport(0, 0, size, size); GL.Color3(Color.White); GL.Disable(EnableCap.Lighting); GL.DepthMask(true); GL.Enable(EnableCap.DepthTest); //GL.ClearDepth(1.0f); GL.DepthFunc(DepthFunction.Lequal); int nx, ny; nx = 64; ny = 64; int texture; GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); GL.Enable(EnableCap.Texture2D); GL.GenTextures(1, out texture); GL.BindTexture(TextureTarget.Texture2D, texture); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0); int ix, iy; double x, y, z, sy, cy, sy1, cy1, sx, cx, piy, pix, ay, ay1, ax, tx, ty, ty1, dnx, dny, diy; dnx = 1.0 / nx; dny = 1.0 / ny; GL.Begin(PrimitiveType.QuadStrip); piy = Math.PI * dny; pix = Math.PI * dnx; for (iy = 0; iy < ny; iy++) { diy = iy; ay = diy * piy; sy = Math.Sin(ay); cy = Math.Cos(ay); ty = diy * dny; ay1 = ay + piy; sy1 = Math.Sin(ay1); cy1 = Math.Cos(ay1); ty1 = ty + dny; for (ix = 0; ix <= nx; ix++) { ax = 2.0 * ix * pix; sx = Math.Sin(ax); cx = Math.Cos(ax); x = sy * cx; y = sy * sx; z = cy; tx = ix * dnx; GL.TexCoord2(tx, ty); GL.Vertex3(x, y, z); x = sy1 * cx; y = sy1 * sx; z = cy1; GL.TexCoord2(tx, ty1); GL.Vertex3(x, y, z); } } GL.End(); GL.Disable(EnableCap.Texture2D); GL.DeleteTexture(texture); sourceBitmap.UnlockBits(data); return(GraphicsContextToBitmap(size)); } }
public override System.Drawing.Image Render(RendererOptions options) { // The main object model group. Model3DGroup group = new Model3DGroup(); // The camera OrthographicCamera camera = new OrthographicCamera(); Viewport3D viewport = new Viewport3D(); // Give the camera its initial position. viewport.Camera = camera; // The camera's current location. double cameraPhi = ToRadians(options.LatitudeShift); double cameraTheta = ToRadians(180 - options.LongutudeShift); double cameraR = 10; // Calculate the camera's position in Cartesian coordinates. double y = cameraR * Math.Sin(cameraPhi); double hyp = cameraR * Math.Cos(cameraPhi); double x = hyp * Math.Cos(cameraTheta); double z = hyp * Math.Sin(cameraTheta); camera.Position = new Point3D(x, y, z); // Look toward the origin. camera.LookDirection = new Vector3D(-x, -y, -z); // Set the Up direction. camera.UpDirection = new Vector3D(0, 1, 0); // Define lights. AmbientLight ambientLight = new AmbientLight(Colors.White); group.Children.Add(ambientLight); // Create the model. // Globe. Place it in a new model so we can transform it. Model3DGroup globe = new Model3DGroup(); group.Children.Add(globe); ImageBrush globeBrush = new ImageBrush(); using (Bitmap sourceBitmap = CreateTextureBitmap(options)) { globeBrush.ImageSource = FromWinFormsBitmap(sourceBitmap); } Material globeMaterial = new DiffuseMaterial(globeBrush); MakeSphere(globe, globeMaterial, 1, 0, 0, 0, 64, 64); // Add the group of models to a ModelVisual3D. ModelVisual3D visual = new ModelVisual3D(); visual.Content = group; // Display the main visual to the viewport. viewport.Children.Add(visual); int size = 1024; viewport.Width = size; viewport.Height = size; viewport.Measure(new System.Windows.Size(size, size)); viewport.Arrange(new System.Windows.Rect(0, 0, size, size)); viewport.InvalidateVisual(); if (targetBitmap == null) { targetBitmap = new RenderTargetBitmap(size, size, 96, 96, PixelFormats.Pbgra32); } targetBitmap.Clear(); targetBitmap.Render(viewport); return(ToWinFormsBitmap(targetBitmap)); }
public RendererOptionsInOut(RendererOptions opts, Action <Bitmap> onComplete) { Options = opts; OnComplete = onComplete; }
/// <summary> /// Creates image representing celestial body sphere as it visible from Earth. /// </summary> /// <param name="options">Rendering options</param> /// <returns>Image instance</returns> public abstract Image Render(RendererOptions options);