/// <summary> /// This method converts the output from the OpenGL render context provider to a /// FormatConvertedBitmap in order to show it in the image. /// </summary> /// <param name="hBitmap">The handle of the bitmap from the OpenGL render context.</param> /// <returns>Returns the new format converted bitmap.</returns> private static FormatConvertedBitmap GetFormatedBitmapSource(IntPtr hBitmap) { // TODO: We have to remove the alpha channel - for some reason it comes out as 0.0 // meaning the drawing comes out transparent. FormatConvertedBitmap newFormatedBitmapSource = new FormatConvertedBitmap(); newFormatedBitmapSource.BeginInit(); newFormatedBitmapSource.Source = BitmapConversion.HBitmapToBitmapSource(hBitmap); newFormatedBitmapSource.DestinationFormat = PixelFormats.Rgb24; newFormatedBitmapSource.EndInit(); return(newFormatedBitmapSource); }
/// <summary> /// JWH - FOR NEW RENDER METHOD /// Fill the ImageSource from the provided bits IntPtr, using the provided hBitMap IntPtr /// if needed to determine key data from the bitmap source. /// </summary> /// <param name="bits">An IntPtr to the bits for the bitmap image. Generally provided from /// DIBSectionRenderContextProvider.DIBSection.Bits or from /// FBORenderContextProvider.InternalDIBSection.Bits.</param> /// <param name="hBitmap">An IntPtr to the HBitmap for the image. Generally provided from /// DIBSectionRenderContextProvider.DIBSection.HBitmap or from /// FBORenderContextProvider.InternalDIBSection.HBitmap.</param> public void CopyToWriteableBitmap(IntPtr bits, IntPtr hBitmap) { // If DPI hasen't been set, use a call to HBitmapToBitmapSource to fill the info // This should happen only ONCE (near the start of the application) if (m_dpiX == 0) { var bitmapSource = BitmapConversion.HBitmapToBitmapSource(hBitmap); m_dpiX = bitmapSource.DpiX; m_dpiY = bitmapSource.DpiY; m_format = bitmapSource.Format; m_bytesPerPixel = gl.RenderContextProvider.BitDepth >> 3; // FBO render context flips the image vertically, so transform to compensate if (RenderContextType == SharpGL.RenderContextType.FBO || RenderContextType == SharpGL.RenderContextType.MultiSampleFBO) { image.RenderTransform = new ScaleTransform(1.0, -1.0); image.RenderTransformOrigin = new Point(0.0, 0.5); } else { image.RenderTransform = Transform.Identity; image.RenderTransformOrigin = new Point(0.0, 0.0); } } // If the image buffer is null, create it // This should happen when the size of the image changes if (m_writeableBitmap == null || m_writeableBitmap.IsFrozen) { int width = gl.RenderContextProvider.Width; int height = gl.RenderContextProvider.Height; m_imageSize = width * height * m_bytesPerPixel; m_writeableBitmap = new WriteableBitmap(width, height, m_dpiX, m_dpiY, m_format, null); m_imageRect = new Int32Rect(0, 0, width, height); image.Source = m_writeableBitmap; } // Fill the image buffer from the bits and create the writeable bitmap m_writeableBitmap.Lock(); CopyMemory(m_writeableBitmap.BackBuffer, bits, m_imageSize); m_writeableBitmap.AddDirtyRect(m_imageRect); m_writeableBitmap.Unlock(); }
/// <summary> /// Handles the Tick event of the timer control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> void timer_Tick(object sender, EventArgs e) { // Lock on OpenGL. lock (gl) { // Start the stopwatch so that we can time the rendering. stopwatch.Restart(); // Make GL current. gl.MakeCurrent(); // If there is a draw handler, then call it. var handler = OpenGLDraw; if (handler != null) { handler(this, eventArgsFast); } else { gl.Clear(OpenGL.GL_COLOR_BUFFER_BIT); } // Draw the FPS. if (DrawFPS) { gl.DrawText(5, 5, 1.0f, 0.0f, 0.0f, "Courier New", 12.0f, string.Format("Draw Time: {0:0.0000} ms ~ {1:0.0} FPS", frameTime, 1000.0 / frameTime)); gl.Flush(); } // Render. gl.Blit(IntPtr.Zero); switch (RenderContextType) { case RenderContextType.DIBSection: { RenderContextProviders.DIBSectionRenderContextProvider provider = gl.RenderContextProvider as RenderContextProviders.DIBSectionRenderContextProvider; // TODO: We have to remove the alpha channel - for some reason it comes out as 0.0 // meaning the drawing comes out transparent. FormatConvertedBitmap newFormatedBitmapSource = new FormatConvertedBitmap(); newFormatedBitmapSource.BeginInit(); newFormatedBitmapSource.Source = BitmapConversion.HBitmapToBitmapSource(provider.DIBSection.HBitmap); newFormatedBitmapSource.DestinationFormat = PixelFormats.Rgb24; newFormatedBitmapSource.EndInit(); // Copy the pixels over. image.Source = newFormatedBitmapSource; } break; case RenderContextType.NativeWindow: break; case RenderContextType.HiddenWindow: break; case RenderContextType.FBO: { RenderContextProviders.FBORenderContextProvider provider = gl.RenderContextProvider as RenderContextProviders.FBORenderContextProvider; // TODO: We have to remove the alpha channel - for some reason it comes out as 0.0 // meaning the drawing comes out transparent. FormatConvertedBitmap newFormatedBitmapSource = new FormatConvertedBitmap(); newFormatedBitmapSource.BeginInit(); newFormatedBitmapSource.Source = BitmapConversion.HBitmapToBitmapSource(provider.InternalDIBSection.HBitmap); newFormatedBitmapSource.DestinationFormat = PixelFormats.Rgb24; newFormatedBitmapSource.EndInit(); // Copy the pixels over. image.Source = newFormatedBitmapSource; } break; default: break; } // Stop the stopwatch. stopwatch.Stop(); // Store the frame time. frameTime = stopwatch.Elapsed.TotalMilliseconds; } }
/// <summary> /// Handles the Tick event of the timer control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> void timer_Tick(object sender, EventArgs e) { // If we don't have a scene, we're done. if (Scene == null) { return; } // Lock on the Scene. lock (Scene) { // Start the stopwatch so that we can time the rendering. stopwatch.Restart(); // Draw the scene. Scene.Draw(Camera); // Draw the FPS. if (DrawFPS) { Scene.CurrentOpenGLContext.DrawText(5, 5, 1.0f, 0.0f, 0.0f, "Courier New", 12.0f, string.Format("Draw Time: {0:0.0000} ms ~ {1:0.0} FPS", frameTime, 1000.0 / frameTime)); Scene.CurrentOpenGLContext.Flush(); } if (Scene.CurrentOpenGLContext.RenderContextProvider is RenderContextProviders.DIBSectionRenderContextProvider) { RenderContextProviders.DIBSectionRenderContextProvider provider = Scene.CurrentOpenGLContext.RenderContextProvider as RenderContextProviders.DIBSectionRenderContextProvider; // TODO: We have to remove the alpha channel - for some reason it comes out as 0.0 // meaning the drawing comes out transparent. FormatConvertedBitmap newFormatedBitmapSource = new FormatConvertedBitmap(); newFormatedBitmapSource.BeginInit(); newFormatedBitmapSource.Source = BitmapConversion.HBitmapToBitmapSource(provider.DIBSection.HBitmap); newFormatedBitmapSource.DestinationFormat = PixelFormats.Rgb24; newFormatedBitmapSource.EndInit(); // Copy the pixels over. image.Source = newFormatedBitmapSource; } else if (Scene.CurrentOpenGLContext.RenderContextProvider is RenderContextProviders.FBORenderContextProvider) { RenderContextProviders.FBORenderContextProvider provider = Scene.CurrentOpenGLContext.RenderContextProvider as RenderContextProviders.FBORenderContextProvider; // TODO: We have to remove the alpha channel - for some reason it comes out as 0.0 // meaning the drawing comes out transparent. FormatConvertedBitmap newFormatedBitmapSource = new FormatConvertedBitmap(); newFormatedBitmapSource.BeginInit(); newFormatedBitmapSource.Source = BitmapConversion.HBitmapToBitmapSource(provider.InternalDIBSection.HBitmap); newFormatedBitmapSource.DestinationFormat = PixelFormats.Rgb24; newFormatedBitmapSource.EndInit(); // Copy the pixels over. image.Source = newFormatedBitmapSource; } // Stop the stopwatch. stopwatch.Stop(); // Store the frame time. frameTime = stopwatch.Elapsed.TotalMilliseconds; } }
public ImageSource GetFrame() { if (!BlitImage) { return(ImgSource); } lock (Gl) { Gl.Blit(IntPtr.Zero); IntPtr hBitmap = IntPtr.Zero; switch (RenderContextType) { case RenderContextType.DIBSection: { DIBSectionRenderContextProvider provider = Gl.RenderContextProvider as DIBSectionRenderContextProvider; // TODO: We have to remove the alpha channel - for some reason it comes out as 0.0 // meaning the drawing comes out transparent. FormatConvertedBitmap newFormatedBitmapSource = new FormatConvertedBitmap(); newFormatedBitmapSource.BeginInit(); newFormatedBitmapSource.Source = BitmapConversion.HBitmapToBitmapSource(provider.DIBSection.HBitmap); newFormatedBitmapSource.DestinationFormat = PixelFormats.Rgb24; newFormatedBitmapSource.EndInit(); // Copy the pixels over. return(newFormatedBitmapSource); } case RenderContextType.NativeWindow: break; case RenderContextType.HiddenWindow: break; case RenderContextType.FBO: { FBORenderContextProvider provider = Gl.RenderContextProvider as FBORenderContextProvider; // TODO: We have to remove the alpha channel - for some reason it comes out as 0.0 // meaning the drawing comes out transparent. FormatConvertedBitmap newFormatedBitmapSource = new FormatConvertedBitmap(); newFormatedBitmapSource.BeginInit(); newFormatedBitmapSource.Source = BitmapConversion.HBitmapToBitmapSource(provider.InternalDIBSection.HBitmap); newFormatedBitmapSource.DestinationFormat = PixelFormats.Rgb24; newFormatedBitmapSource.EndInit(); // Copy the pixels over. return(newFormatedBitmapSource); } case RenderContextType.PBO: { PBORenderContextProvider provider = Gl.RenderContextProvider as PBORenderContextProvider; var width = provider.Width; var height = provider.Height; var pixelsPtr = provider.PixelPtr; if (pixelsPtr == IntPtr.Zero) { return(null); } var size = provider.Size; var stride = provider.Stride; var rect = new Int32Rect(0, 0, width, height); WriteableBitmap.WritePixels(rect, pixelsPtr, size, stride, 0, 0); return(WriteableBitmap); } default: break; } } return(null); }