private void VisionControl_Render(object sender, OpenGL.GlControlEventArgs e) { #region Draw Basic Picture // Update image input _Framebuffer.BindDraw(_GraphicsContext); Gl.Viewport(0, 0, (int)_Framebuffer.Width, (int)_Framebuffer.Height); _Framebuffer.Clear(_GraphicsContext, ClearBufferMask.ColorBufferBit); { // Draw a quad Matrix4x4f quadProj = Matrix4x4f.Ortho2D(-1.0f, +1.0f, -1.0f, +1.0f); Matrix4x4f quadModel = new Matrix4x4f(); _Angle += 1.0f; quadModel.RotateZ(10.0f * (float)Math.Cos(Angle.ToRadians(_Angle))); _GraphicsContext.Bind(_ProgramStd); _ProgramStd.SetUniform(_GraphicsContext, "glo_ModelViewProjection", quadProj * quadModel); _ProgramStd.SetUniform(_GraphicsContext, "glo_UniformColor", Vertex4f.One); _ArraysQuad.Draw(_GraphicsContext, _ProgramStd); } _Framebuffer.UnbindDraw(_GraphicsContext); #endregion #region Track Corners // Read back image input pixels using (OpenGL.Objects.Image imageInput = _FramebufferTexture.Get(_GraphicsContext, PixelLayout.RGB24, 0)) { // Copy the input RGB frame from OpenGL to OpenVX Rectangle cv_rgb_image_region = new Rectangle(); cv_rgb_image_region.StartX = 0; cv_rgb_image_region.StartY = 0; cv_rgb_image_region.EndX = imageInput.Width; cv_rgb_image_region.EndY = imageInput.Height; ImagePatchAddressing cv_rgb_image_layout = new ImagePatchAddressing(); cv_rgb_image_layout.StrideX = 3; cv_rgb_image_layout.StrideY = (int)imageInput.Stride; VX.CopyImagePatch(_ImageInput, ref cv_rgb_image_region, 0, ref cv_rgb_image_layout, imageInput.ImageBuffer, Accessor.WriteOnly, MemoryType.Host); } // Now that input RGB image is ready, just run a graph. // Run Harris at the beginning to initialize the previous keypoints, // on other frames run the tracking graph. VX.ProcessGraph(_DetectCorners ? _GraphHarris : _GraphTrack); _DetectCorners = false; #endregion #region Store Markers on GPU // To mark the keypoints in display, you need to access the output // keypoint array and draw each item on the output window using gui.DrawArrow(). UIntPtr num_corners = UIntPtr.Zero; uint num_tracking = 0; _KeypointsPrevious = VX.GetReferenceFromDelay(_KeypointsDelay, -1); _KeypointsCurrent = VX.GetReferenceFromDelay(_KeypointsDelay, 0); VX.Query(_KeypointsPrevious, ArrayAttribute.Numitems, out num_corners); if (num_corners.ToUInt64() > 0) { UIntPtr kp_old_stride = UIntPtr.Zero, kp_new_stride = UIntPtr.Zero; MapId kp_old_map = new MapId(), kp_new_map = new MapId(); IntPtr kp_old_buf, kp_new_buf; VX.MapArrayRange(_KeypointsPrevious, (UIntPtr)0, num_corners, ref kp_old_map, ref kp_old_stride, out kp_old_buf, Accessor.ReadOnly, MemoryType.Host, 0); VX.MapArrayRange(_KeypointsCurrent, (UIntPtr)0, num_corners, ref kp_new_map, ref kp_new_stride, out kp_new_buf, Accessor.ReadOnly, MemoryType.Host, 0); _BufferOpticalMarkers.Map(_GraphicsContext, BufferAccess.WriteOnly); for (uint i = 0; i < num_corners.ToUInt64(); i++) { KeyPoint kp_old = VX.ArrayItem <KeyPoint>(kp_old_buf, i, kp_old_stride); KeyPoint kp_new = VX.ArrayItem <KeyPoint>(kp_new_buf, i, kp_new_stride); if (kp_new.TrackingStatus != 0) { Vertex2f vOld = new Vertex2f(kp_old.X / 1024.0f, kp_old.Y / 1024.0f); Vertex2f vNew = new Vertex2f(kp_new.X / 1024.0f, kp_new.Y / 1024.0f); _BufferOpticalMarkers.SetElement(vOld, (num_tracking * 2) + 0, 0); _BufferOpticalMarkers.SetElement(vNew, (num_tracking * 2) + 1, 0); num_tracking++; } } _BufferOpticalMarkers.Unmap(_GraphicsContext); VX.UnmapArrayRange(_KeypointsPrevious, kp_old_map); VX.UnmapArrayRange(_KeypointsCurrent, kp_new_map); } #endregion Gl.Viewport(0, 0, VisionControl.Width, VisionControl.Height); Gl.ClearColor(1.0f, 0.0f, 0.0f, 0.0f); Gl.Clear(ClearBufferMask.ColorBufferBit); #region Draw Input Image _GraphicsContext.Bind(_ProgramStdTex); _ProgramStdTex.SetUniform(_GraphicsContext, "glo_ModelViewProjection", Matrix4x4f.Ortho2D(0.0f, 1.0f, 0.0f, 1.0f)); _ProgramStdTex.SetUniform(_GraphicsContext, "glo_Texture", _FramebufferTexture); _ArraysPostQuad.Draw(_GraphicsContext, _ProgramStdTex); #endregion #region Draw Markers if (num_tracking > 0) { _GraphicsContext.Bind(_ProgramStd); _ProgramStd.SetUniform(_GraphicsContext, "glo_ModelViewProjection", Matrix4x4f.Ortho2D(0.0f, 1.0f, 0.0f, 1.0f)); _ProgramStd.SetUniform(_GraphicsContext, "glo_UniformColor", new Vertex4f(1.0f, 0.0f, 0.0f, 1.0f)); _ArraysOpticalMarkers.Draw(_GraphicsContext, _ProgramStd, 0, 0, num_tracking * 2); } #endregion // Increase the age of the delay objects to make the current entry become previous entry VX.AgeDelay(_PyramidDelay); VX.AgeDelay(_KeypointsDelay); }