public static void updateROIImage(Rectangle roiRect, uint frameBuffer, uint imageTexName, Size imageSize, uint roiTexName, uint roiMaskTexName) { GLHelper.GetError(); // Setup viewport int[] oldViewPort = new int[4]; GL.GetInteger(GetPName.Viewport, oldViewPort); GL.Viewport(0, 0, roiRect.Size.Width, roiRect.Size.Height); int fboOld = GLHelper.bindFrameBuffer(frameBuffer, roiTexName); // Render to source texture float left = (float)roiRect.Location.X / (float)imageSize.Width; float right = (float)(roiRect.Location.X + roiRect.Size.Width) / (float)imageSize.Width; float top = (float)roiRect.Location.Y / (float)imageSize.Height; float button = (float)(roiRect.Location.Y + roiRect.Size.Height) / (float)imageSize.Height; // NB: texture coords are mirrored vertically float[] texCoords = { right, top, right, button, left, top, left, button }; // Render source Matrix4 mat = Matrix4.CreateOrthographicOffCenter(0, (float)roiRect.Size.Width, 0, (float)roiRect.Size.Height, -1.0f, 1.0f); Rectangle r = new Rectangle(0, 0, roiRect.Width, roiRect.Height); GLHelper.DrawSprite(imageTexName, r, mat, texCoords, Vector4.One); // Render mask onto source GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.Zero, BlendingFactorDest.OneMinusSrcAlpha); GLHelper.DrawSprite(roiMaskTexName, r, mat); GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.Zero); GL.Disable(EnableCap.Blend); // unbind framebuffer GL.BindFramebuffer(FramebufferTarget.Framebuffer, fboOld); GL.Viewport(oldViewPort[0], oldViewPort[1], oldViewPort[2], oldViewPort[3]); GLHelper.GetError(); }
private void ShowZoom(uint texName, IntPtr buffer, Vector4 selectPos, float viewHeight, Matrix4 projMatrix, int offsetY) { // GL has inverted y axis Vector2 invertSelectPos = new Vector2(selectPos.X, viewHeight - selectPos.Y); Rectangle readRect = new Rectangle((int)selectPos.X - zoomSize.Width / 2, (int)invertSelectPos.Y - zoomSize.Height / 2, zoomSize.Width, zoomSize.Height); Rectangle drawRect = new Rectangle((int)selectPos.X - zoomSize.Width / 2, (int)selectPos.Y - zoomSize.Height / 2 + offsetY + zoomSize.Height, zoomSize.Width, -zoomSize.Height); readPixelsToTexture(readRect, texName, buffer); GLHelper.DrawSprite(texName, drawRect, projMatrix, null, Vector4.One); // Draw edge float[] Vertices = { drawRect.X, drawRect.Y, drawRect.X + drawRect.Width, drawRect.Y, drawRect.X + drawRect.Width, drawRect.Y + drawRect.Height, drawRect.X, drawRect.Y + drawRect.Height }; GL.LineWidth(2); GL.BlendFunc(BlendingFactorSrc.One, BlendingFactorDest.SrcColor); AmbientShader shader = AmbientShader.Singleton; shader.Use(); shader.SetColor(new Vector4(0.2f, 0.2f, 0.2f, 0.7f)); shader.SetMVPMatrix(projMatrix); shader.EnableVertices(2, VertexAttribPointerType.Float, false, 0, Vertices); GL.DrawArrays(BeginMode.LineLoop, 0, 4); shader.DisableVertices(); GL.LineWidth(1); }
public static void DrawROI(RectangleF viewRect, Vector2 vROICenter, float fROIRadius, Rectangle roiRect, uint roiMaskTexName, Vector4 outlineColor, float outlineWidth, Vector4 bgColor, Matrix4 MVMatrix, Matrix4 PMatrix) { Matrix4 MVPMatrix = MVMatrix * PMatrix; GL.Enable(EnableCap.Blend); { GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); // GL.BlendFunc(All.Zero, All.OneMinusSrcAlpha); GLHelper.DrawSprite(roiMaskTexName, roiRect, MVPMatrix, null, bgColor); } // Draw 4 areas outside ROI { Vector4 vTopLeft = Vector4.Transform(new Vector4(roiRect.X, roiRect.Y, 0, 1), MVMatrix); Vector4 vButtomRight = Vector4.Transform(new Vector4(roiRect.Right, roiRect.Bottom, 0, 1), MVMatrix); RectangleF boxRect; boxRect = RectangleF.Intersect(viewRect, new RectangleF(0, 0, viewRect.Width, vTopLeft.Y)); if (boxRect != RectangleF.Empty) { GLHelper.drawRect(boxRect, bgColor, PMatrix); } boxRect = RectangleF.Intersect(viewRect, new RectangleF(0, vButtomRight.Y, viewRect.Width, viewRect.Height - vButtomRight.Y)); if (boxRect != RectangleF.Empty) { GLHelper.drawRect(boxRect, bgColor, PMatrix); } boxRect = RectangleF.Intersect(viewRect, new RectangleF(0, vTopLeft.Y, vTopLeft.X, vButtomRight.Y - vTopLeft.Y)); if (boxRect != RectangleF.Empty) { GLHelper.drawRect(boxRect, bgColor, PMatrix); } boxRect = RectangleF.Intersect(viewRect, new RectangleF(vButtomRight.X, vTopLeft.Y, viewRect.Width - vButtomRight.X, vButtomRight.Y - vTopLeft.Y)); if (boxRect != RectangleF.Empty) { GLHelper.drawRect(boxRect, bgColor, PMatrix); } } GL.Disable(EnableCap.Blend); // ROI sphere { float r = fROIRadius; Vector2 pos = vROICenter; float[] vertices = GLHelper.CreateSphereVertices(pos, r, false); float oldLineWidth = 1; GL.GetFloat(GetPName.LineWidth, out oldLineWidth); GL.LineWidth(outlineWidth); AmbientShader shader = AmbientShader.Singleton; shader.Use(); shader.SetColor(outlineColor); shader.SetMVPMatrix(MVPMatrix); shader.EnableVertices(2, VertexAttribPointerType.Float, false, 0, vertices); GL.DrawArrays(BeginMode.LineLoop, 0, vertices.Length / 2); shader.DisableVertices(); GL.LineWidth(oldLineWidth); } }
public static void updateROIMask(Rectangle roiRect, Size imageSize, uint frameBuffer, uint roiMaskTexName, uint maskTexName) { GLHelper.GetError(); // Setup viewport int[] oldViewPort = new int[4]; GL.GetInteger(GetPName.Viewport, oldViewPort); GL.Viewport(0, 0, roiRect.Size.Width, roiRect.Size.Height); int fboOld = GLHelper.bindFrameBuffer(frameBuffer, roiMaskTexName); // Fill with 1.1.1.1 GL.ClearColor(1.0f, 1.0f, 1.0f, 1.0f); GL.Clear(ClearBufferMask.ColorBufferBit); GLHelper.GetError(); // Draw crop if (true) { float[] vertices = GLHelper.CreateSphereVertices(new Vector2((float)roiRect.Size.Width * 0.5f, (float)roiRect.Size.Height * 0.5f), (float)roiRect.Size.Height * 0.5f, true); // Set Model view Matrix4 MVPMatrix = Matrix4.CreateOrthographicOffCenter(0, (float)roiRect.Size.Width, 0, (float)roiRect.Size.Height, -1.0f, 1.0f); AmbientShader shader = AmbientShader.Singleton; shader.Use(); shader.SetColor(new Vector4(0, 0, 0, 0)); shader.SetMVPMatrix(MVPMatrix); shader.EnableVertices(2, VertexAttribPointerType.Float, false, 0, vertices); GLHelper.GetError(); GL.DrawArrays(BeginMode.TriangleFan, 0, vertices.Length / 2); shader.DisableVertices(); } // Draw mask if (true) { // Render to source texture float left = (float)roiRect.Location.X / (float)imageSize.Width; float right = (float)(roiRect.Location.X + roiRect.Size.Width) / (float)imageSize.Width; float top = (float)roiRect.Location.Y / (float)imageSize.Height; float button = (float)(roiRect.Location.Y + roiRect.Size.Height) / (float)imageSize.Height; // NB: texture coords are mirrored vertically float[] texCoords = { right, top, right, button, left, top, left, button }; Matrix4 mat = Matrix4.CreateOrthographicOffCenter(0, (float)roiRect.Size.Width, 0, (float)roiRect.Size.Height, -1.0f, 1.0f); Rectangle r = new Rectangle(0, 0, roiRect.Width, roiRect.Height); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha); GLHelper.DrawSprite(maskTexName, r, mat, texCoords, Vector4.One); GL.Disable(EnableCap.Blend); } // unbind framebuffer GL.BindFramebuffer(FramebufferTarget.Framebuffer, fboOld); // Cleanup viewport GL.Viewport(oldViewPort[0], oldViewPort[1], oldViewPort[2], oldViewPort[3]); GLHelper.GetError(); }
private void CreateSaveImage(ICollection <Tag> tagArray) { if (SaveCountResult == null) { return; } Size size = ccContext.ImageSize; uint outputTexName = 0; // Generate texture GL.GenTextures(1, out outputTexName); CCContext.setupTexture(outputTexName, size, IntPtr.Zero); // Setup viewport int[] oldViewPort = new int[4]; GL.GetInteger(GetPName.Viewport, oldViewPort); GL.Viewport(0, 0, size.Width, size.Height); int fboOld = GLHelper.bindFrameBuffer(frameBuffer, outputTexName); GL.Disable(EnableCap.Blend); Matrix4 projectionMatrix = Matrix4.CreateOrthographicOffCenter(0, (float)size.Width, 0, (float)size.Height, -1.0f, 1.0f); // Matrix4 projectionMatrix = ccContext.ProjectionMatrix; Matrix4 modelViewMatrix = Matrix4.Identity; // Draw image { Matrix4 mat = modelViewMatrix * projectionMatrix; Rectangle imageRect = new Rectangle(0, 0, (int)size.Width, (int)size.Height); GLHelper.DrawSprite(ccContext.ImageTexName, imageRect, mat); } // Draw ROI Vector4 outlineColor = ColorHelper.ColorToVec(ColorHelper.ROIEdge); Vector4 bgColor = ColorHelper.ColorToVec(ColorHelper.ROIBackground); float outlineWidth = 1.0f; RectangleF rect = new RectangleF(PointF.Empty, new SizeF(size)); CountLayerHelper.DrawROI(rect, roiSphere.center, roiSphere.radius, roiRect, roiMaskTexName, outlineColor, outlineWidth, bgColor, modelViewMatrix, projectionMatrix); // Regions CountLayerHelper.DrawRegions(regions, modelViewMatrix, projectionMatrix); // Draw tags { float tagSize = 16; CountLayerHelper.drawTags(tagArray, null, true, modelViewMatrix, projectionMatrix, tagSize); } // allocate array and read pixels into it. int myDataLength = size.Width * size.Height * 4; byte[] buffer = new byte[myDataLength]; GL.ReadPixels(0, 0, size.Width, size.Height, PixelFormat.Rgba, PixelType.UnsignedByte, buffer); // Call save image event SaveCountResult(buffer, size, tags.Count, regions.Count); buffer = null; GL.DeleteTextures(1, ref outputTexName); // unbind framebuffer GL.BindFramebuffer(FramebufferTarget.Framebuffer, fboOld); GL.Viewport(oldViewPort[0], oldViewPort[1], oldViewPort[2], oldViewPort[3]); }
// Should be called from GL thread public void RenderUpdate(RectangleF rect) { //if (bUpdateImage) { // bUpdateImage = false; // Console.WriteLine("CountLayerContext UPDATE IMAGE"); // CCContext.setupTexture (maskTexName, ccContext.ImageSize, IntPtr.Zero); // int[] oldViewPort = new int[4]; // GL.GetInteger (GetPName.Viewport, oldViewPort); // GL.Viewport (0, 0, ccContext.ImageSize.Width, ccContext.ImageSize.Height); // int fboOld = GLHelper.bindFrameBuffer (frameBuffer, maskTexName); // // Clear texture // GL.ClearColor(1.0f, 1.0f, 1.0f, 1.0f); // GL.Clear (ClearBufferMask.ColorBufferBit); // // unbind framebuffer // GL.BindFramebuffer (FramebufferTarget.Framebuffer, fboOld); // GL.Viewport (oldViewPort [0], oldViewPort [1], oldViewPort [2], oldViewPort [3]); // bUpdateROI = true; // bUpdateROIThreshold = true; // bUpdateSeqmentation = true; //} //if (bUpdateROI) { // bUpdateROI = false; // Console.WriteLine("CountLayerContext UPDATE ROI"); // UpdateROI(); // bUpdateROIThreshold = true; //} List <Tag> tagsCopy = null; lock (tags) { tagsCopy = new List <Tag>(tags); } //if (bLateUpdateSegmentation) { // bLateUpdateSegmentation = false; // Console.WriteLine("CountLayerContext LATE UPDATE SEGMENTATION"); // // End running calc region task // if (cCalcRegionTokenSource != null) { // cCalcRegionTokenSource.Cancel (); // calcRegionTask = null; // } // if(bUpdateROIThreshold && tagsCopy.Count == 0) // { // CountLayerHelper.GetROIThreshold(roiRect, segmentationPixelData, roiThresholdMin, roiThresholdMax, frameBuffer, roiTexName); // bUpdateROIThreshold = false; // } // CountLayerHelper.UpdateThresholds (tagsCopy, roiRect, frameBuffer, roiTexName); // GLHelper.GetError (); // // Stop region task // CountLayerHelper.UpdateSegmentation (tagsCopy, roiRect, frameBuffer, thresholdTexName, roiTexName, // segmentationPixelData, roiThresholdMin, roiThresholdMax); // GLHelper.GetError (); // // Start calc region task // regions.Clear(); // incommingRegions.Clear(); // CountLayerHelper.SCalcRegionTask calcRegionTaskData = new CountLayerHelper.SCalcRegionTask (); // calcRegionTaskData.pixelData = segmentationPixelData; // calcRegionTaskData.roiRect = roiRect; // calcRegionTaskData.tags = tagsCopy.ToArray(); // calcRegionTaskData.debugTexture = debugTexture; // calcRegionTaskData.debugTexture.Clear (); // calcRegionTaskData.bDebugDrawEDM = false; // calcRegionTaskData.bDebugDrawRegions = false; // calcRegionTaskData.startTime = DateTime.Now; // calcRegionTaskData.regions = new List<Region>(); // calcRegionTaskData.regionAdded += delegate(object sender, EventArgs e) { // lock(incommingRegions) { // incommingRegions.Add (sender as Region); // }; // ccContext.RequestRender (); // // if (CountLayerUpdated != null) { // // CountLayerUpdated (tags.Count, regions.Count); // // } // }; // cCalcRegionTokenSource = new CancellationTokenSource (); // CancellationToken cToken = cCalcRegionTokenSource.Token; // calcRegionTask = Task.Factory.StartNew<CountLayerHelper.SCalcRegionTask> (() => CountLayerHelper.calcRegions (cToken, calcRegionTaskData), cToken); // calcRegionTask.ContinueWith (task => { // // Request render so we can get task result in render thread // ccContext.RequestRender (); // }); //} //// Handle incomming regions //lock(incommingRegions) { // if(incommingRegions.Count > 0) { // regions.AddRange(incommingRegions); // incommingRegions.Clear(); // } //}; //// Trigger segmentation update next frame //if(bUpdateSeqmentation) { // bUpdateSeqmentation = false; // bLateUpdateSegmentation = true; // Console.WriteLine("CountLayerContext UPDATE SEGMENTATION"); // ccContext.RequestRender (); //} //// Check calc region task //if (calcRegionTask != null && calcRegionTask.IsCompleted) { //calcRegionTaskComplete) // CountLayerHelper.SCalcRegionTask taskData = calcRegionTask.Result; // ICollection<Region> result = taskData.regions; // TimeSpan span = DateTime.Now.Subtract(taskData.startTime); // Console.WriteLine("CountLayerContext REGION RESULT (duration:"+span.TotalSeconds+")"); // regions.Clear (); // regions.AddRange (result); // calcRegionTask = null; // if (CountLayerUpdated != null) { // CountLayerUpdated (tagsCopy.Count, regions.Count); // } //} // RENDERING !!! // Clear background GLHelper.GetError(); GL.ClearColor(1.0f, 0.0f, 0.0f, 1); GLHelper.GetError(); GL.Clear(ClearBufferMask.ColorBufferBit); GLHelper.GetError(); Matrix4 mat = ccContext.ModelViewMatrix * ccContext.ProjectionMatrix; // Draw image { Rectangle imageRect = new Rectangle(0, 0, (int)ccContext.ImageSize.Width, (int)ccContext.ImageSize.Height); GLHelper.DrawSprite(ccContext.ImageTexName, imageRect, mat); } //// Draw ROI //{ // Vector4 outlineColor = ColorHelper.ColorToVec(ColorHelper.ROIEdge); // Vector4 bgColor = ColorHelper.ColorToVec(ColorHelper.ROIBackground); // float outlineWidth = 1.0f; // if (activeTool == Tool.ROIEdit) { // bool selected = selectedPrim != null && selectedPrim.GetPrimitive () == roiSphere; // outlineColor = selected ? ColorHelper.ColorToVec(ColorHelper.ROIEdgeSelected) : ColorHelper.ColorToVec(ColorHelper.ROIEdgeActive); // bgColor = ColorHelper.ColorToVec(ColorHelper.ROIBackgroundActive); // outlineWidth = 2; // } // CountLayerHelper.DrawROI (rect, roiSphere.center, roiSphere.radius, roiRect, roiMaskTexName, outlineColor, outlineWidth, bgColor, ccContext.ModelViewMatrix, ccContext.ProjectionMatrix); //} // // Draw debug texture // bool bDragDebugTexture = false; // if (bDragDebugTexture) { // debugTexture.prepareForRender (); //// GLHelper.DrawSprite(debugTexName, roiRect, mat); //// GLHelper.DrawSprite(roiTexName, roiRect, mat); // GLHelper.DrawSprite (roiMaskTexName, roiRect, mat); // } //{ // CountLayerHelper.DrawRegions (regions, ccContext.ModelViewMatrix, ccContext.ProjectionMatrix); //} // Draw tags { Tag selectedTag = selectedPrim != null?selectedPrim.GetPrimitive() as Tag : null; bool layerActive = activeTool == Tool.TagCreate || activeTool == Tool.TagDelete; float tagSize = ccContext.TagSize; CountLayerHelper.drawTags(tagsCopy, selectedTag, layerActive, ccContext.ModelViewMatrix, ccContext.ProjectionMatrix, tagSize); } if (bRequestSaveImage) { bRequestSaveImage = false; CreateSaveImage(tagsCopy); } }