/// <summary>
            /// Draw the elements instances
            /// </summary>
            ///  <param name="ctx">
            /// The <see cref="GraphicsContext"/> used for drawing.
            /// </param>
            /// <param name="instances">
            /// A <see cref="UInt32"/> that specify the number of instances to draw.
            /// </param>
            public override void DrawInstanced(GraphicsContext ctx, uint instances)
            {
                CheckCurrentContext(ctx);

                ArrayBufferObjectBase.IArraySection arraySection = ArrayIndices.GetArraySection(0);
                Debug.Assert(arraySection != null);

                // Element array must be (re)bound
                ctx.Bind(ArrayIndices, true);

                // Enable restart primitive?
                if (ArrayIndices.RestartIndexEnabled)
                {
                    if (PrimitiveRestart.IsPrimitiveRestartSupported(ctx))
                    {
                        // Enable primitive restart
                        PrimitiveRestart.EnablePrimitiveRestart(ctx, ArrayIndices.ElementsType);
                        // Draw elements as usual
                        DrawElementsInstanced(ctx, arraySection.Pointer, instances);
                        // Disable primitive restart
                        PrimitiveRestart.DisablePrimitiveRestart(ctx);
                    }
                    else
                    {
                        throw new NotSupportedException();
                    }
                }
                else
                {
                    uint count = (ElementCount == 0) ? ArrayIndices.ItemCount : ElementCount;
                    Debug.Assert(count - ElementOffset <= ArrayIndices.ItemCount, "element indices array out of bounds");

                    // Draw vertex arrays by indices
                    DrawElementsInstanced(ctx, arraySection.Pointer, instances);
                }
            }
            /// <summary>
            /// Draw the elements.
            /// </summary>
            /// <param name="ctx">
            /// The <see cref="GraphicsContext"/> used for drawing.
            /// </param>
            public override void Draw(GraphicsContext ctx)
            {
                CheckCurrentContext(ctx);

                ArrayBufferObjectBase.IArraySection arraySection = ArrayIndices.GetArraySection(0);
                Debug.Assert(arraySection != null);

                // Element array must be (re)bound
                ctx.Bind(ArrayIndices, true);

                // Enable restart primitive?
                if (ArrayIndices.RestartIndexEnabled)
                {
                    if (PrimitiveRestart.IsPrimitiveRestartSupported(ctx))
                    {
                        // Draw elements with primitive restart
                        PrimitiveRestart.EnablePrimitiveRestart(ctx, ArrayIndices.ElementsType);
                        DrawElements(ctx, arraySection.Pointer);
                        PrimitiveRestart.DisablePrimitiveRestart(ctx);
                    }
                    else
                    {
                        // Note: uses MultiDrawElements to emulate the primitive restart feature; PrimitiveRestartOffsets and
                        // PrimitiveRestartCounts are computed at element buffer creation time
                        Gl.MultiDrawElements(ElementsMode, ArrayIndices.PrimitiveRestartOffsets, ArrayIndices.ElementsType, ArrayIndices.PrimitiveRestartCounts, ArrayIndices.PrimitiveRestartOffsets.Length);
                    }
                }
                else
                {
                    uint count = (ElementCount == 0) ? ArrayIndices.ItemCount : ElementCount;
                    Debug.Assert(count - ElementOffset <= ArrayIndices.ItemCount, "element indices array out of bounds");

                    // Draw vertex arrays by indices
                    DrawElements(ctx, arraySection.Pointer);
                }
            }
Exemple #3
0
        /// <summary>
        /// Draw a specific element set.
        /// </summary>
        /// <param name="ctx">
        /// The <see cref="GraphicsContext"/> used for rendering.
        /// </param>
        /// <param name="shader">
        /// The <see cref="ShaderProgram"/> used for drawing the vertex arrays.
        /// </param>
        /// <param name="elementIndex">
        /// A <see cref="Int32"/> that specifies the index of the element to draw. If it is less than 0, it draws
        /// all elements set. The index can be obtained by the value returned by <see cref="SetElementArray"/>.
        /// </param>
        /// <param name="offset">
        /// A <see cref="UInt32"/> that specifies the offset of the first element to draw.
        /// </param>
        /// <param name="count">
        /// A <see cref="UInt32"/> that specifies the number of items to draw.
        /// </param>
        public void Draw(GraphicsContext ctx, ShaderProgram shader, int elementIndex, uint offset, uint count)
        {
            Element drawElement = GetElementArray(elementIndex) as Element;

            if (drawElement == null)
            {
                throw new InvalidOperationException("no element at index " + elementIndex);
            }

            CheckThisExistence(ctx);

            // Set vertex arrays
            SetVertexArrayState(ctx, shader);

            // Fixed or programmable pipeline?
            if (shader != null)
            {
                ctx.Bind(shader);
            }
            else
            {
                ctx.ResetProgram();
            }

            if (_FeedbackBuffer != null)
            {
                _FeedbackBuffer.Begin(ctx, drawElement.ElementsMode);
            }

            drawElement.Draw(ctx, offset, count);

            if (_FeedbackBuffer != null)
            {
                _FeedbackBuffer.End(ctx);
            }
        }
Exemple #4
0
        /// <summary>
        /// Draw a character sequence.
        /// </summary>
        /// <param name="ctx">
        /// The <see cref="GraphicsContext"/> used for drawing.
        /// </param>
        /// <param name="modelview">
        /// The <see cref="Matrix4x4"/> the model-view-projection matrix for the first character of <paramref name="s"/>.
        /// </param>
        /// <param name="color">
        /// The <see cref="ColorRGBAF"/> that specifies the glyph color.
        /// </param>
        /// <param name="s">
        /// A <see cref="String"/> that specifies the characters for be drawn.
        /// </param>
        private void DrawStringCore(GraphicsContext ctx, Matrix4x4 modelview, ColorRGBAF color, string s)
        {
            ModelMatrix charModel = new ModelMatrix(modelview);

            ctx.Bind(_FontProgram);

            _FontProgram.SetUniform(ctx, "glo_UniformColor", color);

            if (ctx.Extensions.ShaderDrawParameters_ARB)
            {
                List <VertexArrayObject.IElement> glyphElements = new List <VertexArrayObject.IElement>();
                int drawInstanceId = 0;

                foreach (char c in s)
                {
                    Glyph glyph;

                    if (_Glyphs.TryGetValue(c, out glyph) == false)
                    {
                        continue;
                    }

                    if (glyph.ElementIndex >= 0)
                    {
                        // Collect draw instance element
                        glyphElements.Add(_VertexArrays.GetElementArray(glyph.ElementIndex));
                        // Set model-view
                        _FontProgram.SetUniform(ctx, "glo_CharModelViewProjection[" + drawInstanceId + "]", charModel);
                        // Next instance
                        drawInstanceId++;
                    }
                    // Move next
                    charModel.Translate(glyph.GlyphSize.Width, 0.0f);
                }

                // Draw using Multi-Draw primitive
                VertexArrayObject.IElement multiElement = _VertexArrays.CombineArrayElements(glyphElements);

                _VertexArrays.Draw(ctx, _FontProgram, multiElement);
            }
            else
            {
                foreach (char c in s)
                {
                    Glyph glyph;

                    if (_Glyphs.TryGetValue(c, out glyph) == false)
                    {
                        continue;
                    }

                    if (glyph.ElementIndex >= 0)
                    {
                        // Set model-view
                        _FontProgram.SetUniform(ctx, "glo_ModelViewProjection", charModel);
                        // Rasterize it
                        _VertexArrays.Draw(ctx, _FontProgram, glyph.ElementIndex);
                    }
                    // Move next
                    charModel.Translate(glyph.GlyphSize.Width, 0.0f);
                }
            }
        }
Exemple #5
0
        /// <summary>
        /// Set the vertex arrays state for the shader program.
        /// </summary>
        /// <param name="ctx">
        /// A <see cref="GraphicsContext"/> on which the shader program is bound.
        /// </param>
        /// <param name="shaderProgram">
        /// A <see cref="ShaderProgram"/> on which the vertex arrays shall be bound.
        /// </param>
        private void SetVertexArrayState(GraphicsContext ctx, ShaderProgram shaderProgram)
        {
            CheckThisExistence(ctx);

            // Set vertex array state all at once...
            ctx.Bind(this, true);

            if (shaderProgram != null)
            {
                ICollection <string> activeAttributes = shaderProgram.ActiveAttributes;
                uint attributesSet = 0;

                // Set vertex array state
                foreach (string attributeName in activeAttributes)
                {
                    IVertexArray shaderVertexArray = GetVertexArray(attributeName, shaderProgram);
                    if (shaderVertexArray == null)
                    {
                        continue;
                    }

                    ShaderProgram.AttributeBinding attributeBinding = shaderProgram.GetActiveAttribute(attributeName);

                    IVertexArray currentVertexArray = _VertexArrayState[attributeBinding.Location];
                    //if (ReferenceEquals(shaderVertexArray, currentVertexArray) == false) {
                    shaderVertexArray.SetVertexAttribute(ctx, attributeBinding, attributeName);
                    _VertexArrayState[attributeBinding.Location] = shaderVertexArray;
                    //}

                    attributesSet++;
                }

                if (attributesSet == 0)
                {
                    throw new InvalidOperationException("no attribute is set");
                }
            }
            else
            {
                IVertexArray attributeArray;

                // No shader program: using fixed pipeline program. ATM enable all attributes having a semantic
                if ((attributeArray = GetVertexArray(VertexArraySemantic.Position)) == null)
                {
                    throw new InvalidOperationException("no position semantic array defined");
                }
                attributeArray.SetVertexAttribute(ctx, null, VertexArraySemantic.Position);

                // Optional attributes
                if ((attributeArray = GetVertexArray(VertexArraySemantic.Color)) != null)
                {
                    attributeArray.SetVertexAttribute(ctx, null, VertexArraySemantic.Color);
                }
                if ((attributeArray = GetVertexArray(VertexArraySemantic.Normal)) != null)
                {
                    attributeArray.SetVertexAttribute(ctx, null, VertexArraySemantic.Normal);
                }
                if ((attributeArray = GetVertexArray(VertexArraySemantic.TexCoord)) != null)
                {
                    attributeArray.SetVertexAttribute(ctx, null, VertexArraySemantic.TexCoord);
                }
            }
        }
Exemple #6
0
        /// <summary>
        /// Apply this TransformStateBase.
        /// </summary>
        /// <param name="ctx">
        /// A <see cref="GraphicsContext"/> which has defined the shader program <paramref name="shaderProgram"/>.
        /// </param>
        /// <param name="shaderProgram">
        /// The <see cref="ShaderProgram"/> which has the state set.
        /// </param>
        public override void Apply(GraphicsContext ctx, ShaderProgram shaderProgram)
        {
            GraphicsResource.CheckCurrentContext(ctx);

            if (shaderProgram == null)
            {
                // Fixed pipeline rendering requires server state

#if !MONODROID
                if (ctx.Extensions.DirectStateAccess_EXT)
                {
                    // Set projection and model-view matrix
                    Gl.MatrixLoadEXT(MatrixMode.Projection, Projection.ToArray());
                    Gl.MatrixLoadEXT(MatrixMode.Modelview, ModelView.ToArray());
                }
                else
                {
                    // Set projection matrix
                    Gl.MatrixMode(MatrixMode.Projection);
                    Gl.LoadMatrix(Projection.ToArray());
                    // Set model-view matrix
                    Gl.MatrixMode(MatrixMode.Modelview);
                    Gl.LoadMatrix(ModelView.ToArray());
                }
#else
                throw new NotSupportedException("fixed pipeline not supported");
#endif
            }
            else
            {
                // Shader implementation (TransformState.glsl)
                ctx.Bind(shaderProgram);

                // Usual matrices
                Debug.Assert(ModelViewProjection != null, "no model-view-projection matrix");
                shaderProgram.SetUniform(ctx, "glo_ModelViewProjection", ModelViewProjection);
                if (shaderProgram.IsActiveUniform("glo_NormalMatrix"))
                {
                    shaderProgram.SetUniform(ctx, "glo_NormalMatrix", NormalMatrix);
                }
                if (Projection != null)
                {
                    shaderProgram.SetUniform(ctx, "glo_Projection", Projection);
                }
                if (shaderProgram.IsActiveUniform("glo_Model"))
                {
                    shaderProgram.SetUniform(ctx, "glo_Model", Model);
                }
                if (shaderProgram.IsActiveUniform("glo_ModelView"))
                {
                    shaderProgram.SetUniform(ctx, "glo_ModelView", ModelView);
                }

                if (shaderProgram.IsActiveUniform("glo_InverseProjection"))
                {
                    shaderProgram.SetUniform(ctx, "glo_InverseProjection", InverseProjection);
                }
                if (shaderProgram.IsActiveUniform("glo_InverseModelView"))
                {
                    shaderProgram.SetUniform(ctx, "glo_InverseModelView", InverseModelView);
                }
                if (shaderProgram.IsActiveUniform("glo_InverseModelViewProjection"))
                {
                    shaderProgram.SetUniform(ctx, "glo_InverseModelViewProjection", InverseModelViewProjection);
                }

                if (Projection != null)
                {
                    shaderProgram.SetUniform(ctx, "glo_DepthDistances", DepthDistances);
                }
            }
        }
Exemple #7
0
        /// <summary>
        /// Actually create this BufferObject resources.
        /// </summary>
        /// <param name="ctx">
        /// A <see cref="GraphicsContext"/> used for allocating resources.
        /// </param>
        /// <exception cref="ArgumentNullException">
        /// Exception thrown if <paramref name="ctx"/> is null.
        /// </exception>
        /// <exception cref="ArgumentException">
        /// Exception thrown if <paramref name="ctx"/> is not current on the calling thread.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// Exception thrown if this BufferObject has not client memory allocated and the hint is different from
        /// <see cref="BufferObjectHint.StaticCpuDraw"/> or <see cref="BufferObjectHint.DynamicCpuDraw"/>.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// Exception thrown if this BufferObject is currently mapped.
        /// </exception>
        protected override void CreateObject(GraphicsContext ctx)
        {
            CheckCurrentContext(ctx);

            if ((ClientBufferAddress == IntPtr.Zero) && ((Hint != BufferObjectHint.StaticCpuDraw) && (Hint != BufferObjectHint.DynamicCpuDraw)))
            {
                throw new InvalidOperationException("no client buffer");
            }

            // Determine the client buffer size
            uint clientBufferSize = _ClientBufferSize;

            if (ClientBufferAddress != IntPtr.Zero)
            {
                clientBufferSize = ClientBufferSize;
            }

            Debug.Assert(clientBufferSize > 0);

            // Buffer must be bound
            ctx.Bind(this, true);

            if (ctx.Extensions.VertexBufferObject_ARB)
            {
                if (IsMapped)
                {
                    throw new InvalidOperationException("mapped");
                }

                // Define buffer object (type, size and hints)
                AllocateGpuBuffer(clientBufferSize, null);

                // Define buffer object contents
                if (ClientBufferAddress != IntPtr.Zero)
                {
                    // Provide buffer contents
                    Gl.BufferSubData(BufferType, IntPtr.Zero, _GpuBufferSize, ClientBufferAddress);
                    // Release memory, if it is not required anymore
                    if (_MemoryBufferAutoDispose)
                    {
                        ReleaseClientBuffer();
                    }
                }
            }
            else
            {
                // Discard previous GPU buffer, if any
                if (_GpuBuffer != null)
                {
                    _GpuBuffer.Dispose();
                }

                if (ClientBufferAddress == IntPtr.Zero)
                {
                    // Note: GPU buffer size specified by _ClientBufferSize
                    Debug.Assert(_ClientBufferSize > 0);
                    // Allocate simulated GPU buffer
                    _GpuBuffer = new AlignedMemoryBuffer(_ClientBufferSize, MinimumBufferAlignment);
                }
                else
                {
                    // Let a virtual implementation decide how pass information from the client buffer and the "GPU" buffer
                    UploadClientBuffer();
                }

                // Store GPU buffer size
                _GpuBufferSize = _GpuBuffer.Size;
            }

            // Reset requested client buffer size
            _ClientBufferSize = 0;
        }
Exemple #8
0
        /// <summary>
        /// Set the vertex arrays state for the shader program.
        /// </summary>
        /// <param name="ctx">
        /// A <see cref="GraphicsContext"/> on which the shader program is bound.
        /// </param>
        /// <param name="shaderProgram">
        /// A <see cref="ShaderProgram"/> on which the vertex arrays shall be bound.
        /// </param>
        private void SetVertexArrayState(GraphicsContext ctx, ShaderProgram shaderProgram)
        {
            CheckThisExistence(ctx);

            ctx.Bind(this, true);

            if (shaderProgram != null)
            {
                ICollection <string> activeAttributes = shaderProgram.ActiveAttributes;

                // Note: when the GL_ARB_vertex_array_object is supported, there's no need to define vertex attributes each time
                if (ctx.Extensions.VertexArrayObject_ARB && !_VertexArrayDirty)
                {
                    // CheckVertexAttributes(ctx, shaderProgram);
                    return;
                }

                uint attributesSet = 0;

                // Set vertex array state
                foreach (string attributeName in activeAttributes)
                {
                    IVertexArray shaderVertexArray = GetVertexArray(attributeName, shaderProgram);
                    if (shaderVertexArray == null)
                    {
                        continue;
                    }

                    // Set array attribute
                    shaderVertexArray.SetVertexAttribute(ctx, shaderProgram, attributeName);
                    attributesSet++;
                }

                if (attributesSet == 0)
                {
                    throw new InvalidOperationException("no attribute is set");
                }
                _VertexArrayCount = attributesSet;
            }
            else
            {
                IVertexArray attributeArray;

                // No shader program: using fixed pipeline program. ATM enable all attributes having a semantic
                if ((attributeArray = GetVertexArray(VertexArraySemantic.Position)) == null)
                {
                    throw new InvalidOperationException("no position semantic array defined");
                }
                attributeArray.SetVertexAttribute(ctx, null, VertexArraySemantic.Position);

                // Optional attributes
                if ((attributeArray = GetVertexArray(VertexArraySemantic.Color)) != null)
                {
                    attributeArray.SetVertexAttribute(ctx, null, VertexArraySemantic.Color);
                }
                if ((attributeArray = GetVertexArray(VertexArraySemantic.Normal)) != null)
                {
                    attributeArray.SetVertexAttribute(ctx, null, VertexArraySemantic.Normal);
                }
                if ((attributeArray = GetVertexArray(VertexArraySemantic.TexCoord)) != null)
                {
                    attributeArray.SetVertexAttribute(ctx, null, VertexArraySemantic.TexCoord);
                }
            }

            // Next time do not set inputs if GL_ARB_vertex_array_object is supported
            _VertexArrayDirty = false;
        }
Exemple #9
0
        /// <summary>
        /// Apply this TransformState.
        /// </summary>
        /// <param name="ctx">
        /// A <see cref="GraphicsContext"/> which has defined the shader program <paramref name="shaderProgram"/>.
        /// </param>
        /// <param name="shaderProgram">
        /// The <see cref="ShaderProgram"/> which has the state set.
        /// </param>
        public override void Apply(GraphicsContext ctx, ShaderProgram shaderProgram)
        {
            GraphicsResource.CheckCurrentContext(ctx);

            if (!ctx.Extensions.UniformBufferObject_ARB)
            {
                if (shaderProgram == null)
                {
                    // Fixed pipeline rendering requires server state
                    throw new NotImplementedException();
                }
                else
                {
                    // Custom implementation
                    ctx.Bind(shaderProgram);

                    if (shaderProgram.IsActiveUniform("glo_LightModel"))
                    {
                        LightModel.ApplyState(ctx, shaderProgram, "glo_LightModel");
                    }

                    for (int i = 0; i < Lights.Count; i++)
                    {
                        string uniformName = "glo_Light[" + i + "]";

                        if (shaderProgram.IsActiveUniform(uniformName) == false)
                        {
                            break;
                        }

                        Lights[i].ApplyState(ctx, shaderProgram, uniformName);
                    }

                    shaderProgram.SetUniform(ctx, "glo_LightsCount", LightsCount);
                }
            }
            else
            {
                base.Apply(ctx, shaderProgram);                         // Uniform block
            }
            // Dummy shadow map: Texture2D
            // Note: necessary to avoid undefined behavior on glo_ShadowMap2D samplers
            string resourceClassId = "OpenGL.Objects.ShadowMap.DummyTexture2d";

            Texture2D dummyShadowMap = (Texture2D)ctx.GetSharedResource(resourceClassId);

            if (dummyShadowMap == null)
            {
                dummyShadowMap = new Texture2D(1, 1, PixelLayout.Depth16);
                dummyShadowMap.SamplerParams.CompareMode = true;
                dummyShadowMap.SamplerParams.CompareFunc = DepthFunction.Never;
                dummyShadowMap.Create(ctx);

                ctx.SetSharedResource(resourceClassId, dummyShadowMap);
            }

            // Dummy shadow map: TextureCube

            // Apply depth maps
            bool[] tex2dSet = new bool[4];

            for (int i = 0; i < tex2dSet.Length; i++)
            {
                if (i >= Lights.Count || Lights[i].ShadowMap2D == null)
                {
                    continue;
                }

                int shadowMapIndex = Lights[i].ShadowMapIndex;

                shaderProgram.SetUniform(ctx, "glo_ShadowMap2D[" + shadowMapIndex + "]", Lights[i].ShadowMap2D);
                tex2dSet[shadowMapIndex] = true;
            }

            // Avoid undefined behavior
            for (int i = 0; i < tex2dSet.Length; i++)
            {
                if (tex2dSet[i] == false)
                {
                    shaderProgram.SetUniform(ctx, "glo_ShadowMap2D[" + i + "]", dummyShadowMap);
                }
            }
        }
Exemple #10
0
        /// <summary>
        /// Map a range of the GPU buffer allocated by this Buffer.
        /// </summary>
        /// <param name="ctx">
        /// A <see cref="GraphicsContext"/> required for mapping this Buffer.
        /// </param>
        /// <param name="mask">
        /// A <see cref="BufferAccessMask"/> that specify the map access.
        /// </param>
        /// <exception cref="InvalidOperationException">
        /// Exception thrown if this Buffer is already mapped.
        /// </exception>
        /// <exception cref="InvalidOperationException">
        /// Exception thrown if this Buffer does not exist for <paramref name="ctx"/>.
        /// </exception>
        public void Map(GraphicsContext ctx, BufferAccessMask mask, IntPtr offset = default(IntPtr), uint size = 0)
        {
            CheckThisExistence(ctx);

            uint mapSize = size != 0 ? size : Size;

            if (IsMapRangeSupported(ctx))
            {
#if !MONODROID
                if (ctx.Extensions.DirectStateAccess_ARB || ctx.Version.IsCompatible(Gl.Version_450))
                {
                    if ((MappedBuffer = Gl.MapNamedBufferRange(ObjectName, offset, mapSize, mask)) == IntPtr.Zero)
                    {
                        Gl.CheckErrors();
                    }
                }
                else
                {
#endif
                ctx.Bind(this);

                if ((MappedBuffer = Gl.MapBufferRange(Target, offset, mapSize, mask)) == IntPtr.Zero)
                {
                    Gl.CheckErrors();
                }
#if !MONODROID
            }
#endif
            }
            else
            {
                if (GpuBuffer == null)
                {
                    throw new GlException(ErrorCode.InvalidOperation);
                }
                if (GpuBuffer.AlignedBuffer == IntPtr.Zero)
                {
                    throw new GlException(ErrorCode.InvalidOperation);
                }

                MappedBuffer = new IntPtr(GpuBuffer.AlignedBuffer.ToInt64() + offset.ToInt64());
            }

            // Determine map access
            if (mask.HasFlag(BufferAccessMask.MapReadBit) && mask.HasFlag(BufferAccessMask.MapWriteBit))
            {
                _Access = BufferAccess.ReadWrite;
            }
            else if (mask.HasFlag(BufferAccessMask.MapReadBit))
            {
                _Access = BufferAccess.ReadOnly;
            }
            else if (mask.HasFlag(BufferAccessMask.MapWriteBit))
            {
                _Access = BufferAccess.WriteOnly;
            }
            else
            {
                _Access = 0;
            }

            Debug.Assert(MappedBuffer != IntPtr.Zero);

            MapOffset   = offset;
            MapSize     = mapSize;
            _AccessMask = mask;
        }
Exemple #11
0
        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);
        }
Exemple #12
0
        /// <summary>
        /// Draw a character sequence (base method).
        /// </summary>
        /// <param name="ctx">
        /// The <see cref="GraphicsContext"/> used for drawing.
        /// </param>
        /// <param name="modelview">
        /// The <see cref="Matrix4x4"/> the model-view-projection matrix for the first character of <paramref name="s"/>.
        /// </param>
        /// <param name="color">
        /// The <see cref="ColorRGBAF"/> that specifies the glyph color.
        /// </param>
        /// <param name="s">
        /// A <see cref="String"/> that specifies the characters for be drawn.
        /// </param>
        private void DrawStringCore(GraphicsContext ctx, Matrix4x4 modelview, TextureArray2d texture, ColorRGBAF color, string s)
        {
            ModelMatrix charModel = new ModelMatrix(modelview);

            ctx.Bind(_FontProgram);

            // Set uniforms
            _FontProgram.SetUniform(ctx, "glo_UniformColor", color);
            _FontProgram.SetUniform(ctx, "glo_FontGlyph", texture);

            // Set instances
            char[] fontChars = s.ToCharArray();
            uint   instances = 0;

            _GlyphInstances.Map(ctx, BufferAccessARB.WriteOnly);
            try {
                for (int i = 0; i < fontChars.Length; i++)
                {
                    Glyph glyph;

                    if (_GlyphMetadata.TryGetValue(fontChars[i], out glyph) == false)
                    {
                        continue;
                    }

                    // Set instance information
                    Matrix4x4f modelViewProjection = new Matrix4x4f(
                        new Vertex4f(charModel.GetColumn(0)),
                        new Vertex4f(charModel.GetColumn(1)),
                        new Vertex4f(charModel.GetColumn(2)),
                        new Vertex4f(charModel.GetColumn(3))
                        );
                    Vertex3f glyphVertexParams = new Vertex3f(
                        glyph.GlyphSize.Width, glyph.GlyphSize.Height,
                        glyph.Layer
                        );
                    Vertex2f glyphTexParams = new Vertex2f(
                        glyph.TexScale.Width, glyph.TexScale.Height
                        );

                    _GlyphInstances.SetElement(modelViewProjection, instances, 0);
                    _GlyphInstances.SetElement(glyphVertexParams, instances, 1);
                    _GlyphInstances.SetElement(glyphTexParams, instances, 2);

                    // Count the instance
                    instances++;

                    // Move next
                    charModel.Translate(glyph.GlyphSize.Width, 0.0f);
                }
            } finally {
                _GlyphInstances.Unmap(ctx);
            }

            // Rasterize it
            using (State.BlendState stateBlend = State.BlendState.AlphaBlending) {
                stateBlend.ApplyState(ctx, _FontProgram);

                _VertexArrays.DrawInstanced(ctx, _FontProgram, instances);
            }
        }