private void DrawLabel(float[] cameraViews, float[] cameraProjection)
        {
            ShaderUtil.CheckGlError(TAG, "Draw label start.");
            Matrix.MultiplyMM(modelViewMatrix, 0, cameraViews, 0, modelMatrix, 0);
            Matrix.MultiplyMM(modelViewProjectionMatrix, 0, cameraProjection, 0, modelViewMatrix, 0);

            float halfWidth  = LABEL_WIDTH / 2.0f;
            float halfHeight = LABEL_HEIGHT / 2.0f;

            float[] vertices =
            {
                -halfWidth, -halfHeight, 1,
                -halfWidth, halfHeight,  1,
                halfWidth,  halfHeight,  1,
                halfWidth,  -halfHeight, 1,
            };

            // The size of each floating point is 4 bits.
            FloatBuffer vetBuffer = ByteBuffer.AllocateDirect(4 * vertices.Length)
                                    .Order(ByteOrder.NativeOrder()).AsFloatBuffer();

            vetBuffer.Rewind();
            for (int i = 0; i < vertices.Length; ++i)
            {
                vetBuffer.Put(vertices[i]);
            }
            vetBuffer.Rewind();

            // The size of each floating point is 4 bits.
            GLES20.GlVertexAttribPointer(glPositionParameter, COORDS_PER_VERTEX, GLES20.GlFloat,
                                         false, 4 * COORDS_PER_VERTEX, vetBuffer);

            // Set the sequence of OpenGL drawing points to generate two triangles that form a plane.
            short[] indices = { 0, 1, 2, 0, 2, 3 };

            // Size of the allocated buffer.
            ShortBuffer idxBuffer = ByteBuffer.AllocateDirect(2 * indices.Length)
                                    .Order(ByteOrder.NativeOrder()).AsShortBuffer();

            idxBuffer.Rewind();
            for (int i = 0; i < indices.Length; ++i)
            {
                idxBuffer.Put(indices[i]);
            }
            idxBuffer.Rewind();

            GLES20.GlUniformMatrix4fv(glModelViewProjectionMatrix, 1, false, modelViewProjectionMatrix, 0);

            GLES20.GlDrawElements(GLES20.GlTriangleStrip, idxBuffer.Limit(), GLES20.GlUnsignedShort, idxBuffer);
            ShaderUtil.CheckGlError(TAG, "Draw label end.");
        }
        /// <summary>
        /// Converts a plane polygon from ARCore into a <see cref="Vector3"/> array.
        /// </summary>
        /// <param name="buffer">The float buffer containing 2D vertices of the polygon</param>
        /// <param name="waveVectorArray">The <see cref="Vector3"/> array with the 3D vertices of the polygon</param>
        public static void ToWave(this FloatBuffer buffer, ref Vector3[] waveVectorArray)
        {
            buffer.Rewind();

            var boundaryVertices = buffer.Limit() / 2;

            if (waveVectorArray == null)
            {
                waveVectorArray = new Vector3[boundaryVertices];
            }
            else if (waveVectorArray.Length != boundaryVertices)
            {
                Array.Resize(ref waveVectorArray, boundaryVertices);
            }

            for (int i = 0; i < boundaryVertices; i++)
            {
                waveVectorArray[i].X = buffer.Get();
                waveVectorArray[i].Z = buffer.Get();
            }
        }
Ejemplo n.º 3
0
        /**
         * Updates the plane model transform matrix and extents.
         */
        private void updatePlaneParameters(float[] planeMatrix, float extentX, float extentZ,
                                           FloatBuffer boundary)
        {
            Array.Copy(planeMatrix, 0, mModelMatrix, 0, 16);
            if (boundary == null)
            {
                mVertexBuffer.Limit(0);
                mIndexBuffer.Limit(0);
                return;
            }

            // Generate a new set of vertices and a corresponding triangle strip index set so that
            // the plane boundary polygon has a fading edge. This is done by making a copy of the
            // boundary polygon vertices and scaling it down around center to push it inwards. Then
            // the index buffer is setup accordingly.
            boundary.Rewind();
            int boundaryVertices = boundary.Limit() / 2;
            int numVertices;
            int numIndices;

            numVertices = boundaryVertices * VERTS_PER_BOUNDARY_VERT;
            // drawn as GL_TRIANGLE_STRIP with 3n-2 triangles (n-2 for fill, 2n for perimeter).
            numIndices = boundaryVertices * INDICES_PER_BOUNDARY_VERT;

            if (mVertexBuffer.Capacity() < numVertices * COORDS_PER_VERTEX)
            {
                int size = mVertexBuffer.Capacity();
                while (size < numVertices * COORDS_PER_VERTEX)
                {
                    size *= 2;
                }
                mVertexBuffer = ByteBuffer.AllocateDirect(BYTES_PER_FLOAT * size)
                                .Order(ByteOrder.NativeOrder()).AsFloatBuffer();
            }
            mVertexBuffer.Rewind();
            mVertexBuffer.Limit(numVertices * COORDS_PER_VERTEX);


            if (mIndexBuffer.Capacity() < numIndices)
            {
                int size = mIndexBuffer.Capacity();
                while (size < numIndices)
                {
                    size *= 2;
                }
                mIndexBuffer = ByteBuffer.AllocateDirect(BYTES_PER_SHORT * size)
                               .Order(ByteOrder.NativeOrder()).AsShortBuffer();
            }
            mIndexBuffer.Rewind();
            mIndexBuffer.Limit(numIndices);

            // Note: when either dimension of the bounding box is smaller than 2*FADE_RADIUS_M we
            // generate a bunch of 0-area triangles.  These don't get rendered though so it works
            // out ok.
            float xScale = Math.Max((extentX - 2 * FADE_RADIUS_M) / extentX, 0.0f);
            float zScale = Math.Max((extentZ - 2 * FADE_RADIUS_M) / extentZ, 0.0f);

            while (boundary.HasRemaining)
            {
                float x = boundary.Get();
                float z = boundary.Get();
                mVertexBuffer.Put(x);
                mVertexBuffer.Put(z);
                mVertexBuffer.Put(0.0f);
                mVertexBuffer.Put(x * xScale);
                mVertexBuffer.Put(z * zScale);
                mVertexBuffer.Put(1.0f);
            }

            // step 1, perimeter
            mIndexBuffer.Put((short)((boundaryVertices - 1) * 2));
            for (int i = 0; i < boundaryVertices; ++i)
            {
                mIndexBuffer.Put((short)(i * 2));
                mIndexBuffer.Put((short)(i * 2 + 1));
            }
            mIndexBuffer.Put((short)1);
            // This leaves us on the interior edge of the perimeter between the inset vertices
            // for boundary verts n-1 and 0.

            // step 2, interior:
            for (int i = 1; i < boundaryVertices / 2; ++i)
            {
                mIndexBuffer.Put((short)((boundaryVertices - 1 - i) * 2 + 1));
                mIndexBuffer.Put((short)(i * 2 + 1));
            }
            if (boundaryVertices % 2 != 0)
            {
                mIndexBuffer.Put((short)((boundaryVertices / 2) * 2 + 1));
            }
        }