///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Copyright (c) 2016 Raytrix GmbH. All rights reserved. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // namespace: Example.LFR.CS.BasicA ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// namespace Example.LFR.CS.BasicA { ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// /// The application's main form. /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public partial class MainForm : Form { // The CLUViz Control instance which creates the open gl context. CLUViz.Net.ViewCtrl m_xCluView; // The CLUViz Engine instance. CLUViz.Net.EngineCtrl m_xCluEngine; // A slider for changing the focus System.Windows.Forms.TrackBar m_xSliderFocus; // The CUDA compute instance. Rx.LFR.Net.CudaCompute m_xCudaCompute; // The open GL interop instance that holes the open GL context Rx.LFR.Net.OpenGlInterop m_xOpenGlInterop; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// /// Default constructor. /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public MainForm() { try { InitializeComponent(); // Initialize m_xSliderFocus = new System.Windows.Forms.TrackBar(); m_xSliderFocus.Enabled = false; // Set the starting slider value (0.5) and its range [0.0,1.0] scaled by 100. m_xSliderFocus.Minimum = 0; m_xSliderFocus.Maximum = 100; m_xSliderFocus.Value = 50; m_xSliderFocus.SmallChange = 1; m_xSliderFocus.Width = 300; // Add an event handler to the Scroll event, so that we can react to it m_xSliderFocus.Scroll += new EventHandler(m_xSliderFocus_Scroll); // Throw the slider control into a flow control panel panelCtrl.Controls.Add(m_xSliderFocus); } catch (Rx.Net.RxException xEx) { MessageBox.Show(xEx.ToString()); } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// /// Event handler. Called by MainForm for shown events. /// /// /// Source of the event. /// Event information. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private void MainForm_Shown(object sender, EventArgs e) { try { // Start the CLU engine m_xCluEngine = new CLUViz.Net.EngineCtrl(); m_xCluEngine.Start(); // Now create the CLU control and embed it into the "panelClu" control. // Changes in size and position of panelClu are automatically applied // to the CLU control. // Since the CLU control display runs in a separate thread, we must // create an OpenGL rendering context for the CUDA thread (this thread) // that shares its texture memory with the OpenGL rendering context in // the CLU control thread. This is done automatically by setting the second // parameter to "true". m_xCluView = new CLUViz.Net.ViewCtrl(true, 0); // We now have to make this shared rendering context current, // since otherwise all CUDA commands will fail. That is, // CUDA is only initialized once this rendering context is made current. // Note that the shared rendering context for this thread is attached to // an invisible dummy window that is held internally. m_xCluView.MakeCurrentSharedRC(); // Initialize the open GL interop instance and store the current context in it. m_xOpenGlInterop = new Rx.LFR.Net.OpenGlInterop(); m_xOpenGlInterop.StoreCurrentContext(); // Authenticate the light field runtime Rx.LFR.Net.LightFieldRuntime.Authenticate(); // Enumerate all CUDA devices at the beginning Rx.LFR.Net.Cuda.EnumerateCudaDevices(); // Assign the CUDA device and the calibration m_xCudaCompute = new Rx.LFR.Net.CudaCompute(); m_xCudaCompute.GetParams().SetValue(Rx.LFR.Net.Params.ECudaCompute.PreProc_DataType, (uint) Rx.InteropNet.Runtime28.EDataType.UByte); if (Rx.LFR.Net.Cuda.GetDeviceCount() == 0) { throw new Exception("No Cuda device found"); } m_xCudaCompute.SetCudaDevice(Rx.LFR.Net.Cuda.GetDevice((int) 0)); // Add the CluView to the panel panelClu.Controls.Add(m_xCluView); m_xCluView.Dock = DockStyle.Fill; // Now set the visualization CLUScript from the resources. m_xCluView.SetScript(Example.LFR.CS.BasicA.Properties.Resources.View_Image_01); } catch (Rx.Net.RxException xEx) { MessageBox.Show(xEx.ToString()); } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// /// Event handler. Called by _xSliderFocus for scroll events. /// /// /// Source of the event. /// Event information. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private void m_xSliderFocus_Scroll(object sender, EventArgs e) { try { // Refocus from raw image UpdateFocus(); } catch (Rx.Net.RxException xEx) { MessageBox.Show(xEx.ToString()); } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// /// Event handler. Called by loadRayImageToolStripMenuItem for click events. /// /// /// Source of the event. /// Event information. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private void loadRayImageToolStripMenuItem_Click(object sender, EventArgs e) { try { openFileDialog1.Filter = "Ray Image|*.ray"; DialogResult diagRes = openFileDialog1.ShowDialog(); if (diagRes == DialogResult.OK) { Rx.LFR.Net.RayImage xRayImg = new Rx.LFR.Net.RayImage(); // Read the ray file Rx.LFR.Net.RayFileReader.Read(openFileDialog1.FileName, xRayImg); // Upload the new image to the compute class and apply the calibration m_xCudaCompute.ApplyCalibration(xRayImg.GetCalibration(), true); m_xCudaCompute.UploadRawImage(xRayImg); // Initialize image view, since new image may have different dimensions. NewImage(); // Enable the slider m_xSliderFocus.Enabled = true; // And finally refocus the image. UpdateFocus(); } } catch (Rx.Net.RxException xEx) { MessageBox.Show(xEx.ToString()); } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// /// Initialize visualization for new image. /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private void NewImage() { try { // Preprocess the image -> must be done before any other image processing can be performened m_xCudaCompute.Compute_PreProcess(); // Create a refocused image m_xCudaCompute.Compute_RefocusBasic(); // Get the texture access interface. This interface allows: // * Updating the texture. Rx.LFR.Net.ICudaDataTextures xTexture = (m_xCudaCompute.GetInterface(Rx.LFR.Net.Interfaces.ECudaCompute.Textures)) as Rx.LFR.Net.ICudaDataTextures; // Update texture stored in the open GL interop instance with the given image id. xTexture.UpdateTexture(Rx.LFR.Net.EImage.RefocusBasic, m_xOpenGlInterop); // Get the image access interface. This interface allows: // * Download CUDA image into host memory // * Upload a host image to CUDA to overwrite a certain CUDA image // * Access to CUDA device pointer to do own CUDA image processing Rx.LFR.Net.ICudaDataImages xImages = (m_xCudaCompute.GetInterface(Rx.LFR.Net.Interfaces.ECudaCompute.Images)) as Rx.LFR.Net.ICudaDataImages; Rx.Net.ImageFormat xImgF = xImages.GetImageFormat(Rx.LFR.Net.EImage.RefocusBasic); // Initialize the CLUScript variables iWidth and iHeight with // the dimensions of the refocused image. m_xCluView.SetVarNumber("iWidth", xImgF.Width); m_xCluView.SetVarNumber("iHeight", xImgF.Height); // Check if this is a luminance image bool bLuminance = ((xImgF.PixelType == Rx.InteropNet.Runtime28.EPixelType.Lum) || (xImgF.PixelType == Rx.InteropNet.Runtime28.EPixelType.LumA)); // Execute the script with ToolName == "Image_Create". // This prepared the image view for an image of the given size. // The image itself is not copied at this point. m_xCluView.ExecScript("Image_Create"); // Get the texture id uint uiTexID = m_xOpenGlInterop.GetTextureID(Rx.LFR.Net.EImage.RefocusBasic); if (uiTexID > 0) { // Set the id to the CluView script m_xCluView.SetVarNumber("texImage", (int) uiTexID); // If the refocused image is of luminance type, we need to select // a different shader for the image display. if (bLuminance) { m_xCluView.ExecScript("Image_Lum_Enable"); } // Tell the CLU control to redraw the current scene tree. // This does not re-execute the script itself. // It needs to be called to ensure that the new content of // the image texture is displayed. m_xCluView.Update(); } } catch (Rx.Net.RxException xEx) { MessageBox.Show(xEx.ToString()); } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// /// Update the focus setting. /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private void UpdateFocus() { try { // Set the new refocus parameter m_xCudaCompute.GetParams().SetValue(Rx.LFR.Net.Params.ECudaCompute.Focus_RelativeFocusPlane, System.Convert.ToDouble(m_xSliderFocus.Value) / 100.0); //Refocus image m_xCudaCompute.Compute_RefocusBasic(); // Redisplay the refocused image UpdateImage(); } catch (Rx.Net.RxException xEx) { MessageBox.Show(xEx.ToString()); } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// /// Redisplay the image. /// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private void UpdateImage() { try { // Get the texture access interface. This interface allows: // * Updating the texture. Rx.LFR.Net.ICudaDataTextures xTexture = (m_xCudaCompute.GetInterface(Rx.LFR.Net.Interfaces.ECudaCompute.Textures)) as Rx.LFR.Net.ICudaDataTextures; // Update texture stored in the open GL interop instance with the given image id. xTexture.UpdateTexture(Rx.LFR.Net.EImage.RefocusBasic, m_xOpenGlInterop); // Get the texture id uint uiTexID = m_xOpenGlInterop.GetTextureID(Rx.LFR.Net.EImage.RefocusBasic); if (uiTexID > 0) { // Set the id to the CluView script m_xCluView.SetVarNumber("texImage", (int) uiTexID); // Tell the CLU control to redraw the current scene tree. // This does not re-execute the script itself. // It needs to be called to ensure that the new content of // the image texture is displayed. m_xCluView.Update(); } } catch (Rx.Net.RxException xEx) { MessageBox.Show(xEx.ToString()); } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /// /// Event handler. Called by MainForm for form closing events. /// /// /// Source of the event. /// Form closing event information. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { try { // End the CLU engine. This closes all CLU controls m_xCluEngine.End(); // Finalize the Lightfield Runtime. This frees all internal memory also on the CUDA device. Rx.LFR.Net.LightFieldRuntime.End(); } catch (Rx.Net.RxException xEx) { MessageBox.Show(xEx.ToString()); } } } }