// Should be called from GL thread public void RenderUpdate(RectangleF rect) { if (bSetupGL) { bSetupGL = false; SetupGL(); countLayerContext.SetupGL(); } if (bUpdateImage) { bUpdateImage = false; if (SetupImageTexture != null) { SetupImageTexture(imageTexName, out imageSize); } countLayerContext.OnImageUpdated(); } countLayerContext.RenderUpdate(rect); if (countLayerContext.Selection != null) { Vector2 selectCenter = CountLayerContext.Selection.GetCenter(); Vector4 selectPos = Vector4.Transform(new Vector4(selectCenter.X, selectCenter.Y, 0, 1), modelViewMatrix); ShowZoom(zoomTexName, zoomBuffer, selectPos, rect.Height, projectionMatrix, zoomOffset); } GLHelper.GetError(); }
private static int loadShader(ShaderType type, string shaderCode) { // create a vertex shader type (GLES20.GL_VERTEX_SHADER) // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER) int shader = GL.CreateShader(type); // add the source code to the shader and compile it string[] code = { shaderCode }; int[] length = { shaderCode.Length }; GL.ShaderSource(shader, 1, code, length); GL.CompileShader(shader); GLHelper.GetError(); int result = (int)All.True; GL.GetShader(shader, ShaderParameter.CompileStatus, out result); if (result == (int)All.False) { int logLength = 0; GL.GetShader(shader, ShaderParameter.InfoLogLength, out logLength); System.Text.StringBuilder info = new System.Text.StringBuilder(logLength); GL.GetShaderInfoLog(shader, logLength, out logLength, info); Console.WriteLine("Shader compile failed:" + info); return(0); } return(shader); }
public static void drawRect(RectangleF rect, Vector4 color, Matrix4 MVPMatrix) { float x = rect.X; float y = rect.Y; float width = rect.Width; float height = rect.Height; float[] Vertices = { x + width, y, x + width, y + height, x, y, x, y + height }; AmbientShader shader = AmbientShader.Singleton; // Use shader shader.Use(); shader.SetColor(color); shader.SetMVPMatrix(MVPMatrix); shader.EnableVertices(2, VertexAttribPointerType.Float, false, 0, Vertices); GL.DrawArrays(BeginMode.TriangleStrip, 0, 4); shader.DisableVertices(); GLHelper.GetError(); }
public static void DrawSprite(uint texId, Rectangle rect, Matrix4 mat, float[] texCoords, Vector4 colorScale) { float x = rect.X; float y = rect.Y; float width = rect.Width; float height = rect.Height; float[] Vertices = { x + width, y, x + width, y + height, x, y, x, y + height }; if (texCoords == null) { float[] tx = { 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }; texCoords = tx; } GLHelper.GetError(); TextureShader shader = TextureShader.Singleton; // Use shader GL.UseProgram(shader.mProgram); shader.SetColorScale(colorScale); // Set texture GL.ActiveTexture(TextureUnit.Texture0); // Set active texture slot to 0 GL.BindTexture(TextureTarget.Texture2D, texId); // Bind 2D texture to current slot GL.Uniform1(shader.muTextureHandle, 0); // Set shader sampler to texture slot 0 // Set Model view GL.UniformMatrix4(shader.muMVPMatrixHandle, 1, false, ref mat.Row0.X); // Set vertex and texture coords GL.EnableVertexAttribArray(shader.maPositionHandle); GL.EnableVertexAttribArray(shader.maTexCoordHandle); GL.VertexAttribPointer(shader.maPositionHandle, 2, VertexAttribPointerType.Float, false, 0, Vertices); GL.VertexAttribPointer(shader.maTexCoordHandle, 2, VertexAttribPointerType.Float, false, 0, texCoords); GL.DrawArrays(BeginMode.TriangleStrip, 0, 4); GL.DisableVertexAttribArray(shader.maPositionHandle); GL.DisableVertexAttribArray(shader.maTexCoordHandle); GLHelper.GetError(); }
public void SetupGL() { // get an id from OpenGL GLHelper.GetError(); GL.GenTextures(1, out roiTexName); GL.GenTextures(1, out roiMaskTexName); GL.GenTextures(1, out maskTexName); GL.GenTextures(1, out thresholdTexName); GL.GenTextures(1, out debugTexName); GL.GenFramebuffers(1, out frameBuffer); GLHelper.GetError(); debugTexture = new MutableTexture(debugTexName); }
private static void readPixelsToTexture(Rectangle rect, uint texName, IntPtr buffer) { GL.ReadPixels(rect.X, rect.Y, rect.Width, rect.Height, PixelFormat.Rgba, PixelType.UnsignedByte, buffer); GLHelper.GetError(); GL.BindTexture(TextureTarget.Texture2D, texName); GLHelper.GetError(); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, rect.Width, rect.Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, buffer); GL.BindTexture(TextureTarget.Texture2D, 0); GLHelper.GetError(); }
public static void setupTexture(uint texName, SizeF size, IntPtr data) { GL.BindTexture(TextureTarget.Texture2D, texName); GLHelper.GetError(); SetDefaultTexParameters(); GLHelper.GetError(); // generate the OpenGL texture GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, (int)size.Width, (int)size.Height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, data); GLHelper.GetError(); GL.BindTexture(TextureTarget.Texture2D, 0); GLHelper.GetError(); }
public static int createProgram(String vertexShaderCode, String fragmentShaderCode) { GLHelper.GetError(); int vertexShader = loadShader(ShaderType.VertexShader, vertexShaderCode); int fragmentShader = loadShader(ShaderType.FragmentShader, fragmentShaderCode); int mProgram = GL.CreateProgram(); // create empty OpenGL Program GL.AttachShader(mProgram, vertexShader); // add the vertex shader to program GL.AttachShader(mProgram, fragmentShader); // add the fragment shader to program GL.LinkProgram(mProgram); // creates OpenGL program executables GLHelper.GetError(); return(mProgram); }
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(); }
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(); }
public static void MaskDraw(Vector2 pos, Vector2 prevPos, bool bForeground, uint frameBuffer, uint texName, Size texSize, float[] sphereVertices, int scale) { // FIXME: radius is in image space and needs to be dps adjusted // Setup viewport int[] oldViewPort = new int[4]; GL.GetInteger(GetPName.Viewport, oldViewPort); GL.Viewport(0, 0, texSize.Width, texSize.Height); int fboOld = GLHelper.bindFrameBuffer(frameBuffer, texName); Vector4 foreground = new Vector4(1, 1, 1, 1); Vector4 background = new Vector4(0, 0, 0, 0); Vector4 color = bForeground ? foreground : background; AmbientShader shader = AmbientShader.Singleton; shader.Use(); shader.SetColor(color); Matrix4 ProjMatrix = Matrix4.CreateOrthographicOffCenter(0, (float)texSize.Width, 0, (float)texSize.Height, -1.0f, 1.0f); // Draw sphere at pos { // Set Model view Matrix4 MVPMatrix = Matrix4.Scale(scale) * Matrix4.CreateTranslation(new Vector3(pos)) * ProjMatrix; shader.SetMVPMatrix(MVPMatrix); shader.EnableVertices(2, VertexAttribPointerType.Float, false, 0, sphereVertices); GLHelper.GetError(); GL.DrawArrays(BeginMode.TriangleFan, 0, sphereVertices.Length / 2); shader.DisableVertices(); } // Connect prev to current if (!pos.Equals(prevPos)) { shader.SetMVPMatrix(ProjMatrix); // shader.SetMVPMatrix(projMatrix); // Vector2 v0 = CCContext.ViewToModel(prevPos, modelViewMatrix); // Vector2 v1 = CCContext.ViewToModel(pos, modelViewMatrix); Vector2 v0 = prevPos; Vector2 v1 = pos; Vector3 up = new Vector3(0, 0, 1); Vector3 dir = new Vector3(v1) - new Vector3(v0); dir = Vector3.Normalize(dir); Vector3 cross = Vector3.Cross(up, dir) * scale; float[] vertices = new float[4 * 2]; int i = 0; vertices[i++] = v0.X - cross.X; vertices[i++] = v0.Y - cross.Y; vertices[i++] = v0.X + cross.X; vertices[i++] = v0.Y + cross.Y; vertices[i++] = v1.X - cross.X; vertices[i++] = v1.Y - cross.Y; vertices[i++] = v1.X + cross.X; vertices[i++] = v1.Y + cross.Y; shader.EnableVertices(2, VertexAttribPointerType.Float, false, 0, vertices); GL.DrawArrays(BeginMode.TriangleStrip, 0, 4); // GLES20.glDrawArrays(GLES20.GL_LINE_STRIP, 0, 4); shader.DisableVertices(); } // 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); } }