/// <summary>
        /// Update the coordinates of hand skeleton points.
        /// </summary>
        private void UpdateHandSkeletonsData(float[] handSkeletons)
        {
            ShaderUtil.CheckGlError(TAG, "Update hand skeletons data start.");

            // Each point has a 3D coordinate. The total number of coordinates
            // is three times the number of skeleton points.
            int mPointsNum = handSkeletons.Length / 3;

            Log.Debug(TAG, "ARHand HandSkeletonNumber = " + mPointsNum);
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVbo);
            mNumPoints = mPointsNum;
            if (mVboSize < mNumPoints * BYTES_PER_POINT)
            {
                while (mVboSize < mNumPoints * BYTES_PER_POINT)
                {
                    // If the size of VBO is insufficient to accommodate the new point cloud, resize the VBO.
                    mVboSize *= 2;
                }
                GLES20.GlBufferData(GLES20.GlArrayBuffer, mVboSize, null, GLES20.GlDynamicDraw);
            }
            FloatBuffer mSkeletonPoints = FloatBuffer.Wrap(handSkeletons);

            GLES20.GlBufferSubData(GLES20.GlArrayBuffer, 0, mNumPoints * BYTES_PER_POINT,
                                   mSkeletonPoints);
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0);

            ShaderUtil.CheckGlError(TAG, "Update hand skeletons data end.");
        }
        /// <summary>
        /// Create the shader program for label display in the openGL thread.
        /// This method will be called when WorldRenderManager's OnSurfaceCreated.
        /// </summary>
        /// <param name="labelBitmaps">View data indicating the plane type.</param>
        public void Init(List <Bitmap> labelBitmaps)
        {
            ShaderUtil.CheckGlError(TAG, "Init start.");
            if (labelBitmaps.Count == 0)
            {
                Log.Debug(TAG, "No bitmap.");
            }
            CreateProgram();
            int idx = 0;

            GLES20.GlGenTextures(textures.Length, textures, 0);
            foreach (Bitmap labelBitmap in labelBitmaps)
            {
                // for semantic label plane
                GLES20.GlActiveTexture(GLES20.GlTexture0 + idx);
                GLES20.GlBindTexture(GLES20.GlTexture2d, textures[idx]);

                GLES20.GlTexParameteri(
                    GLES20.GlTexture2d, GLES20.GlTextureMinFilter, GLES20.GlLinearMipmapLinear);
                GLES20.GlTexParameteri(
                    GLES20.GlTexture2d, GLES20.GlTextureMagFilter, GLES20.GlLinear);
                GLUtils.TexImage2D(GLES20.GlTexture2d, 0, labelBitmap, 0);
                GLES20.GlGenerateMipmap(GLES20.GlTexture2d);
                GLES20.GlBindTexture(GLES20.GlTexture2d, 0);
                idx++;
                ShaderUtil.CheckGlError(TAG, "Texture loading");
            }
            ShaderUtil.CheckGlError(TAG, "Init end.");
        }
        /// <summary>
        /// Render the hand bounding box.
        /// </summary>
        private void DrawHandBox()
        {
            ShaderUtil.CheckGlError(TAG, "Draw hand box start.");
            GLES20.GlUseProgram(mProgram);
            GLES20.GlEnableVertexAttribArray(mPosition);
            GLES20.GlEnableVertexAttribArray(mColor);
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVbo);
            GLES20.GlVertexAttribPointer(
                mPosition, COORDINATE_DIMENSION, GLES20.GlFloat, false, BYTES_PER_POINT, 0);
            GLES20.GlUniform4f(mColor, 1.0f, 0.0f, 0.0f, 1.0f);

            GLES20.GlUniformMatrix4fv(mModelViewProjectionMatrix, 1, false, mMVPMatrix, 0);

            // Set the size of the rendering vertex.
            GLES20.GlUniform1f(mPointSize, 50.0f);

            // Set the width of a rendering stroke.
            GLES20.GlLineWidth(18.0f);
            GLES20.GlDrawArrays(GLES20.GlLineLoop, 0, mNumPoints);
            GLES20.GlDisableVertexAttribArray(mPosition);
            GLES20.GlDisableVertexAttribArray(mColor);
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0);

            ShaderUtil.CheckGlError(TAG, "Draw hand box end.");
        }
        private void DrawSkeletonLine(float coordinate, float[] projectionMatrix)
        {
            ShaderUtil.CheckGlError(TAG, "Draw skeleton line start.");
            GLES20.GlUseProgram(mProgram);
            GLES20.GlEnableVertexAttribArray(mPosition);
            GLES20.GlEnableVertexAttribArray(mColor);
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVbo);

            // Set the width of the rendered skeleton line.
            GLES20.GlLineWidth(18.0f);

            // The size of the vertex attribute is 4, and each vertex has four coordinate components.
            GLES20.GlVertexAttribPointer(
                mPosition, 4, GLES20.GlFloat, false, BYTES_PER_POINT, 0);
            GLES20.GlUniform4f(mColor, 1.0f, 0.0f, 0.0f, 1.0f);
            GLES20.GlUniformMatrix4fv(mProjectionMatrix, 1, false, projectionMatrix, 0);

            // Set the size of the points.
            GLES20.GlUniform1f(mPointSize, 100.0f);
            GLES20.GlUniform1f(mCoordinateSystem, coordinate);

            GLES20.GlDrawArrays(GLES20.GlLines, 0, mNumPoints);
            GLES20.GlDisableVertexAttribArray(mPosition);
            GLES20.GlDisableVertexAttribArray(mColor);
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0);

            ShaderUtil.CheckGlError(TAG, "Draw skeleton line end.");
        }
        /// <summary>
        /// Update the coordinates of the hand bounding box.
        /// </summary>
        /// <param name="gesturePoints">Gesture hand box data.</param>
        private void UpdateHandBoxData(float[] gesturePoints)
        {
            ShaderUtil.CheckGlError(TAG, "Update hand box data start.");
            float[] glGesturePoints =
            {
                // Get the four coordinates of a rectangular box bounding the hand.
                gesturePoints[0], gesturePoints[1], gesturePoints[2],
                gesturePoints[3], gesturePoints[1], gesturePoints[2],
                gesturePoints[3], gesturePoints[4], gesturePoints[5],
                gesturePoints[0], gesturePoints[4], gesturePoints[5],
            };
            int gesturePointsNum = glGesturePoints.Length / COORDINATE_DIMENSION;

            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVbo);

            mNumPoints = gesturePointsNum;
            if (mVboSize < mNumPoints * BYTES_PER_POINT)
            {
                while (mVboSize < mNumPoints * BYTES_PER_POINT)
                {
                    // If the size of VBO is insufficient to accommodate the new point cloud, resize the VBO.
                    mVboSize *= 2;
                }
                GLES20.GlBufferData(GLES20.GlArrayBuffer, mVboSize, null, GLES20.GlDynamicDraw);
            }
            Log.Debug(TAG, "gesture.getGestureHandPointsNum()" + mNumPoints);
            FloatBuffer mVertices = FloatBuffer.Wrap(glGesturePoints);

            GLES20.GlBufferSubData(GLES20.GlArrayBuffer, 0, mNumPoints * BYTES_PER_POINT,
                                   mVertices);
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0);
            ShaderUtil.CheckGlError(TAG, "Update hand box data end.");
        }
Пример #6
0
        /// <summary>
        /// Draw hand skeleton connection line.
        /// </summary>
        /// <param name="projectionMatrix">Projection matrix(4 * 4).</param>
        private void DrawHandSkeletonLine(float[] projectionMatrix)
        {
            ShaderUtil.CheckGlError(TAG, "Draw hand skeleton line start.");
            GLES20.GlUseProgram(mProgram);
            GLES20.GlEnableVertexAttribArray(mPosition);
            GLES20.GlEnableVertexAttribArray(mColor);
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVbo);

            // Set the width of the drawn line
            GLES20.GlLineWidth(18.0f);

            // Represented each point by 4D coordinates in the shader.
            GLES20.GlVertexAttribPointer(
                mPosition, 4, GLES20.GlFloat, false, BYTES_PER_POINT, 0);
            GLES20.GlUniform4f(mColor, 0.0f, 0.0f, 0.0f, 1.0f);
            GLES20.GlUniformMatrix4fv(mModelViewProjectionMatrix, 1, false, projectionMatrix, 0);

            GLES20.GlUniform1f(mPointSize, JOINT_POINT_SIZE);

            GLES20.GlDrawArrays(GLES20.GlLines, 0, mPointsNum);
            GLES20.GlDisableVertexAttribArray(mPosition);
            GLES20.GlDisableVertexAttribArray(mColor);
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0);

            ShaderUtil.CheckGlError(TAG, "Draw hand skeleton line end.");
        }
        private void InitializeGlObjectData(Context context)
        {
            ObjectData objectData         = null;
            Optional   objectDataOptional = ReadObject(context);

            if (objectDataOptional.IsPresent)
            {
                objectData = objectDataOptional.Get().JavaCast <ObjectData>();
            }
            else
            {
                Log.Debug(TAG, "Read object error.");
                return;
            }

            mTexCoordsBaseAddress = FLOAT_BYTE_SIZE * objectData.objectIndices.Limit();
            mNormalsBaseAddress   = mTexCoordsBaseAddress + FLOAT_BYTE_SIZE * objectData.texCoords.Limit();
            int totalBytes = mNormalsBaseAddress + FLOAT_BYTE_SIZE * objectData.normals.Limit();

            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVertexBufferId);
            GLES20.GlBufferData(GLES20.GlArrayBuffer, totalBytes, null, GLES20.GlStaticDraw);
            GLES20.GlBufferSubData(
                GLES20.GlArrayBuffer, 0, FLOAT_BYTE_SIZE * objectData.objectVertices.Limit(), objectData.objectVertices);
            GLES20.GlBufferSubData(GLES20.GlArrayBuffer, mTexCoordsBaseAddress,
                                   FLOAT_BYTE_SIZE * objectData.texCoords.Limit(), objectData.texCoords);
            GLES20.GlBufferSubData(GLES20.GlArrayBuffer, mNormalsBaseAddress,
                                   FLOAT_BYTE_SIZE * objectData.normals.Limit(), objectData.normals);
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0);
            GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, mIndexBufferId);
            mIndexCount = objectData.indices.Limit();
            GLES20.GlBufferData(
                GLES20.GlElementArrayBuffer, INDEX_COUNT_RATIO * mIndexCount, objectData.indices, GLES20.GlStaticDraw);
            GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, 0);
            ShaderUtil.CheckGlError(TAG, "obj buffer load");
        }
 private void CreateProgram()
 {
     ShaderUtil.CheckGlError(TAG, "Create program start.");
     mProgram   = HandShaderUtil.CreateGlProgram();
     mPosition  = GLES20.GlGetAttribLocation(mProgram, "inPosition");
     mColor     = GLES20.GlGetUniformLocation(mProgram, "inColor");
     mPointSize = GLES20.GlGetUniformLocation(mProgram, "inPointSize");
     mModelViewProjectionMatrix = GLES20.GlGetUniformLocation(mProgram, "inMVPMatrix");
     ShaderUtil.CheckGlError(TAG, "Create program start.");
 }
Пример #9
0
 private void CreateProgram()
 {
     ShaderUtil.CheckGlError(TAG, "Create gl program start.");
     mProgram          = BodyShaderUtil.CreateGlProgram();
     mColor            = GLES20.GlGetUniformLocation(mProgram, "inColor");
     mPosition         = GLES20.GlGetAttribLocation(mProgram, "inPosition");
     mPointSize        = GLES20.GlGetUniformLocation(mProgram, "inPointSize");
     mProjectionMatrix = GLES20.GlGetUniformLocation(mProgram, "inProjectionMatrix");
     mCoordinateSystem = GLES20.GlGetUniformLocation(mProgram, "inCoordinateSystem");
     ShaderUtil.CheckGlError(TAG, "Create gl program end.");
 }
 private void CreateProgram()
 {
     ShaderUtil.CheckGlError(TAG, "program start.");
     mProgram                    = WorldShaderUtil.GetLabelProgram();
     glPositionParameter         = GLES20.GlGetAttribLocation(mProgram, "inPosXZAlpha");
     glModelViewProjectionMatrix =
         GLES20.GlGetUniformLocation(mProgram, "inMVPMatrix");
     glTexture       = GLES20.GlGetUniformLocation(mProgram, "inTexture");
     glPlaneUvMatrix = GLES20.GlGetUniformLocation(mProgram, "inPlanUVMatrix");
     ShaderUtil.CheckGlError(TAG, "program end.");
 }
        /// <summary>
        /// Draw face geometrical features. This method is called on each frame.
        /// </summary>
        private void DrawFaceGeometry()
        {
            ShaderUtil.CheckGlError(TAG, "Before draw.");
            Log.Debug(TAG, "Draw face geometry: mPointsNum: " + mPointsNum + " mTrianglesNum: " + mTrianglesNum);

            GLES20.GlActiveTexture(GLES20.GlTexture0);
            GLES20.GlBindTexture(GLES20.GlTexture2d, mTextureName);
            GLES20.GlUniform1i(mTextureUniform, 0);
            ShaderUtil.CheckGlError(TAG, "Init texture.");

            GLES20.GlEnable(GLES20.GlDepthTest);
            GLES20.GlEnable(GL_CULL_FACE_CONSTANT);

            // Draw point.
            GLES20.GlUseProgram(mProgram);
            ShaderUtil.CheckGlError(TAG, "Draw point.");
            GLES20.GlEnableVertexAttribArray(mPositionAttribute);
            GLES20.GlEnableVertexAttribArray(mTextureCoordAttribute);
            GLES20.GlEnableVertexAttribArray(mColorUniform);
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVerticeId);
            GLES20.GlVertexAttribPointer(mPositionAttribute, POSITION_COMPONENTS_NUMBER, GLES20.GlFloat, false,
                                         BYTES_PER_POINT, 0);
            GLES20.GlVertexAttribPointer(mTextureCoordAttribute, TEXCOORD_COMPONENTS_NUMBER, GLES20.GlFloat, false,
                                         BYTES_PER_COORD, 0);
            GLES20.GlUniform4f(mColorUniform, 1.0f, 0.0f, 0.0f, 1.0f);
            GLES20.GlUniformMatrix4fv(mModelViewProjectionUniform, 1, false, mModelViewProjections, 0);
            GLES20.GlUniform1f(mPointSizeUniform, 5.0f); // Set the size of Point to 5.
            GLES20.GlDrawArrays(GLES20.GlPoints, 0, mPointsNum);
            GLES20.GlDisableVertexAttribArray(mColorUniform);
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0);
            ShaderUtil.CheckGlError(TAG, "Draw point.");

            // Draw triangles.
            GLES20.GlEnableVertexAttribArray(mColorUniform);

            // Clear the color and use the texture color to draw triangles.
            GLES20.GlUniform4f(mColorUniform, 0.0f, 0.0f, 0.0f, 0.0f);
            GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, mTriangleId);

            // The number of input triangle points
            GLES20.GlDrawElements(GLES20.GlTriangles, mTrianglesNum * 3, GLES20.GlUnsignedInt, 0);
            GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, 0);
            GLES20.GlDisableVertexAttribArray(mColorUniform);
            ShaderUtil.CheckGlError(TAG, "Draw triangles.");

            GLES20.GlDisableVertexAttribArray(mTextureCoordAttribute);
            GLES20.GlDisableVertexAttribArray(mPositionAttribute);
            GLES20.GlBindTexture(GLES20.GlTexture2d, 0);

            GLES20.GlDisable(GLES20.GlDepthTest);
            GLES20.GlDisable(GL_CULL_FACE_CONSTANT);
            ShaderUtil.CheckGlError(TAG, "Draw after.");
        }
 private void CreateProgram()
 {
     ShaderUtil.CheckGlError(TAG, "Create gl program start.");
     mProgram                    = CreateGlProgram();
     mPositionAttribute          = GLES20.GlGetAttribLocation(mProgram, "inPosition");
     mColorUniform               = GLES20.GlGetUniformLocation(mProgram, "inColor");
     mModelViewProjectionUniform = GLES20.GlGetUniformLocation(mProgram, "inMVPMatrix");
     mPointSizeUniform           = GLES20.GlGetUniformLocation(mProgram, "inPointSize");
     mTextureUniform             = GLES20.GlGetUniformLocation(mProgram, "inTexture");
     mTextureCoordAttribute      = GLES20.GlGetAttribLocation(mProgram, "inTexCoord");
     ShaderUtil.CheckGlError(TAG, "Create gl program end.");
 }
 /// <summary>
 /// Create and build a shader for the hand skeleton points on the OpenGL thread.
 /// this is called when HandRenderManager's OnSurfaceCreated.
 /// </summary>
 public void Init()
 {
     ShaderUtil.CheckGlError(TAG, "Init start.");
     int[] buffers = new int[1];
     GLES20.GlGenBuffers(1, buffers, 0);
     mVbo = buffers[0];
     GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVbo);
     mVboSize = INITIAL_POINTS_SIZE * BYTES_PER_POINT;
     GLES20.GlBufferData(GLES20.GlArrayBuffer, mVboSize, null, GLES20.GlDynamicDraw);
     GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0);
     CreateProgram();
     ShaderUtil.CheckGlError(TAG, "Init end.");
 }
        /// <summary>
        /// Initialize the OpenGL ES rendering related to face geometry,
        /// including creating the shader program.
        /// This method is called when FaceRenderManager's OnSurfaceCreated method calling.
        /// </summary>
        /// <param name="context">Context.</param>
        public void Init(Context context)
        {
            ShaderUtil.CheckGlError(TAG, "Init start.");
            int[] texNames = new int[1];
            GLES20.GlActiveTexture(GLES20.GlTexture0);
            GLES20.GlGenTextures(1, texNames, 0);
            mTextureName = texNames[0];

            int[] buffers = new int[BUFFER_OBJECT_NUMBER];
            GLES20.GlGenBuffers(BUFFER_OBJECT_NUMBER, buffers, 0);
            mVerticeId  = buffers[0];
            mTriangleId = buffers[1];

            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVerticeId);
            GLES20.GlBufferData(GLES20.GlArrayBuffer, mVerticeBufferSize * BYTES_PER_POINT, null, GLES20.GlDynamicDraw);
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0);

            GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, mTriangleId);

            // Each floating-point number occupies 4 bytes.
            GLES20.GlBufferData(GLES20.GlElementArrayBuffer, mTriangleBufferSize * 4, null,
                                GLES20.GlDynamicDraw);
            GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, 0);
            GLES20.GlBindTexture(GLES20.GlTexture2d, mTextureName);

            CreateProgram();

            //Add texture to facegeometry.
            Bitmap       textureBitmap = null;
            AssetManager assets        = context.Assets;

            try
            {
                Stream sr = assets.Open("face_geometry.png");
                textureBitmap = BitmapFactory.DecodeStream(sr);
            }
            catch (Exception e)
            {
                Log.Debug(TAG, " Open bitmap error!");
            }


            GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureWrapS, GLES20.GlClampToEdge);
            GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureWrapT, GLES20.GlClampToEdge);
            GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureMinFilter, GLES20.GlLinearMipmapLinear);
            GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureMagFilter, GLES20.GlLinear);
            GLUtils.TexImage2D(GLES20.GlTexture2d, 0, textureBitmap, 0);
            GLES20.GlGenerateMipmap(GLES20.GlTexture2d);
            GLES20.GlBindTexture(GLES20.GlTexture2d, 0);
            ShaderUtil.CheckGlError(TAG, "Init end.");
        }
        private void UpdateFaceGeometryData(ARFaceGeometry faceGeometry)
        {
            ShaderUtil.CheckGlError(TAG, "Before update data.");
            FloatBuffer faceVertices = faceGeometry.Vertices;

            // Obtain the number of geometric vertices of a face.
            mPointsNum = faceVertices.Limit() / 3;

            FloatBuffer textureCoordinates = faceGeometry.TextureCoordinates;

            // Obtain the number of geometric texture coordinates of the
            // face (the texture coordinates are two-dimensional).
            int texNum = textureCoordinates.Limit() / 2;

            Log.Debug(TAG, "Update face geometry data: texture coordinates size:" + texNum);

            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVerticeId);
            if (mVerticeBufferSize < (mPointsNum + texNum) * BYTES_PER_POINT)
            {
                while (mVerticeBufferSize < (mPointsNum + texNum) * BYTES_PER_POINT)
                {
                    // If the capacity of the vertex VBO buffer is insufficient, expand the capacity.
                    mVerticeBufferSize *= 2;
                }
                GLES20.GlBufferData(GLES20.GlArrayBuffer, mVerticeBufferSize, null, GLES20.GlDynamicDraw);
            }
            GLES20.GlBufferSubData(GLES20.GlArrayBuffer, 0, mPointsNum * BYTES_PER_POINT, faceVertices);

            GLES20.GlBufferSubData(GLES20.GlArrayBuffer, mPointsNum * BYTES_PER_POINT, texNum * BYTES_PER_COORD,
                                   textureCoordinates);
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0);

            mTrianglesNum = faceGeometry.TriangleCount;
            IntBuffer faceTriangleIndices = faceGeometry.TriangleIndices;

            Log.Debug(TAG, "update face geometry data: faceTriangleIndices.size: " + faceTriangleIndices.Limit());

            GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, mTriangleId);
            if (mTriangleBufferSize < mTrianglesNum * BYTES_PER_POINT)
            {
                while (mTriangleBufferSize < mTrianglesNum * BYTES_PER_POINT)
                {
                    // If the capacity of the vertex VBO buffer is insufficient, expand the capacity.
                    mTriangleBufferSize *= 2;
                }
                GLES20.GlBufferData(GLES20.GlElementArrayBuffer, mTriangleBufferSize, null, GLES20.GlDynamicDraw);
            }
            GLES20.GlBufferSubData(GLES20.GlElementArrayBuffer, 0, mTrianglesNum * BYTES_PER_POINT, faceTriangleIndices);
            GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, 0);
            ShaderUtil.CheckGlError(TAG, "After update data.");
        }
        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>
        /// Create and build a shader for the hand gestures on the OpenGL thread.
        /// This method is called when HandRenderManager's OnSurfaceCreated.
        /// </summary>
        public void Init()
        {
            ShaderUtil.CheckGlError(TAG, "Init start.");
            mMVPMatrix = MatrixUtil.GetOriginalMatrix();
            int[] buffers = new int[1];
            GLES20.GlGenBuffers(1, buffers, 0);
            mVbo = buffers[0];
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVbo);

            CreateProgram();
            GLES20.GlBufferData(GLES20.GlArrayBuffer, mVboSize, null, GLES20.GlDynamicDraw);
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0);
            ShaderUtil.CheckGlError(TAG, "Init end.");
        }
        /// <summary>
        /// Draw a virtual object at a specific location on a specified plane.
        /// This method is called when WorldRenderManager's OnDrawFrame.
        /// </summary>
        /// <param name="cameraView">The viewMatrix is a 4 * 4 matrix.</param>
        /// <param name="cameraProjection">The ProjectionMatrix is a 4 * 4 matrix.</param>
        /// <param name="lightIntensity">The lighting intensity.</param>
        /// <param name="obj">The virtual object.</param>
        public void OnDrawFrame(float[] cameraView, float[] cameraProjection, float lightIntensity, VirtualObject obj)
        {
            ShaderUtil.CheckGlError(TAG, "onDrawFrame start.");
            mModelMatrixs = obj.GetModelAnchorMatrix();
            Matrix.MultiplyMM(mModelViewMatrixs, 0, cameraView, 0, mModelMatrixs, 0);
            Matrix.MultiplyMM(mModelViewProjectionMatrixs, 0, cameraProjection, 0, mModelViewMatrixs, 0);
            GLES20.GlUseProgram(mGlProgram);
            Matrix.MultiplyMV(mViewLightDirections, 0, mModelViewMatrixs, 0, LIGHT_DIRECTIONS, 0);
            MatrixUtil.NormalizeVec3(mViewLightDirections);

            // Light direction.
            GLES20.GlUniform4f(mLightingParametersUniform,
                               mViewLightDirections[0], mViewLightDirections[1], mViewLightDirections[2], lightIntensity);
            float[] objColors = obj.GetColor();

            GLES20.GlUniform4fv(mColorUniform, 1, objColors, 0);
            GLES20.GlActiveTexture(GLES20.GlTexture0);
            GLES20.GlBindTexture(GLES20.GlTexture2d, mTextures[0]);
            GLES20.GlUniform1i(mTextureUniform, 0);
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVertexBufferId);

            // The coordinate dimension of the read virtual object is 3.
            GLES20.GlVertexAttribPointer(
                mPositionAttribute, 3, GLES20.GlFloat, false, 0, 0);

            // The dimension of the normal vector is 3.
            GLES20.GlVertexAttribPointer(
                mNormalAttribute, 3, GLES20.GlFloat, false, 0, mNormalsBaseAddress);

            // The dimension of the texture coordinate is 2.
            GLES20.GlVertexAttribPointer(
                mTexCoordAttribute, 2, GLES20.GlFloat, false, 0, mTexCoordsBaseAddress);
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0);
            GLES20.GlUniformMatrix4fv(
                mModelViewUniform, 1, false, mModelViewMatrixs, 0);
            GLES20.GlUniformMatrix4fv(
                mModelViewProjectionUniform, 1, false, mModelViewProjectionMatrixs, 0);
            GLES20.GlEnableVertexAttribArray(mPositionAttribute);
            GLES20.GlEnableVertexAttribArray(mNormalAttribute);
            GLES20.GlEnableVertexAttribArray(mTexCoordAttribute);
            GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, mIndexBufferId);
            GLES20.GlDrawElements(GLES20.GlTriangles, mIndexCount, GLES20.GlUnsignedShort, 0);
            GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, 0);
            GLES20.GlDisableVertexAttribArray(mPositionAttribute);
            GLES20.GlDisableVertexAttribArray(mNormalAttribute);
            GLES20.GlDisableVertexAttribArray(mTexCoordAttribute);
            GLES20.GlBindTexture(GLES20.GlTexture2d, 0);
            ShaderUtil.CheckGlError(TAG, "onDrawFrame end.");
        }
 private void CreateProgram()
 {
     ShaderUtil.CheckGlError(TAG, "Create program start.");
     mGlProgram                  = WorldShaderUtil.GetObjectProgram();
     mModelViewUniform           = GLES20.GlGetUniformLocation(mGlProgram, "inViewMatrix");
     mModelViewProjectionUniform = GLES20.GlGetUniformLocation(mGlProgram, "inMVPMatrix");
     mPositionAttribute          = GLES20.GlGetAttribLocation(mGlProgram, "inObjectPosition");
     mNormalAttribute            = GLES20.GlGetAttribLocation(mGlProgram, "inObjectNormalVector");
     mTexCoordAttribute          = GLES20.GlGetAttribLocation(mGlProgram, "inTexCoordinate");
     mTextureUniform             = GLES20.GlGetUniformLocation(mGlProgram, "inObjectTexture");
     mLightingParametersUniform  = GLES20.GlGetUniformLocation(mGlProgram, "inLight");
     mColorUniform               = GLES20.GlGetUniformLocation(mGlProgram, "inObjectColor");
     Android.Opengl.Matrix.SetIdentityM(mModelMatrixs, 0);
     ShaderUtil.CheckGlError(TAG, "Create program end.");
 }
        /// <summary>
        /// Create a shader program to read the data of the virtual object.
        /// This method is called when WorldRenderManager's OnSurfaceCreated.
        /// </summary>
        /// <param name="context">Context.</param>
        public void Init(Context context)
        {
            ShaderUtil.CheckGlError(TAG, "Init start.");
            CreateProgram();

            // Coordinate and index.
            int[] buffers = new int[2];
            GLES20.GlGenBuffers(2, buffers, 0);
            mVertexBufferId = buffers[0];
            mIndexBufferId  = buffers[1];
            GLES20.GlActiveTexture(GLES20.GlTexture0);
            GLES20.GlGenTextures(mTextures.Length, mTextures, 0);
            GLES20.GlBindTexture(GLES20.GlTexture2d, mTextures[0]);
            GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureMinFilter, GLES20.GlLinearMipmapLinear);
            InitGlTextureData(context);
            InitializeGlObjectData(context);
            ShaderUtil.CheckGlError(TAG, "Init end.");
        }
        private void DrawSortedPlans(List <ARPlane> sortedPlanes, float[] cameraViews, float[] cameraProjection)
        {
            ShaderUtil.CheckGlError(TAG, "Draw sorted plans start.");

            GLES20.GlDepthMask(false);
            GLES20.GlEnable(GLES20.GlBlend);
            GLES20.GlBlendFuncSeparate(
                GLES20.GlDstAlpha, GLES20.GlOne, GLES20.GlZero, GLES20.GlOneMinusSrcAlpha);
            GLES20.GlUseProgram(mProgram);
            GLES20.GlEnableVertexAttribArray(glPositionParameter);

            foreach (ARPlane plane in sortedPlanes)
            {
                float[] planeMatrix = new float[MATRIX_SIZE];
                plane.CenterPose.ToMatrix(planeMatrix, 0);

                Array.Copy(planeMatrix, modelMatrix, MATRIX_SIZE);
                float scaleU = 1.0f / LABEL_WIDTH;

                // Set the value of the plane angle uv matrix.
                planeAngleUvMatrix[0] = scaleU;
                planeAngleUvMatrix[1] = 0.0f;
                planeAngleUvMatrix[2] = 0.0f;
                float scaleV = 1.0f / LABEL_HEIGHT;
                planeAngleUvMatrix[3] = scaleV;

                int idx = plane.Label.Ordinal();
                Log.Debug(TAG, "Plane getLabel:" + idx);
                idx = Java.Lang.Math.Abs(idx);
                GLES20.GlActiveTexture(GLES20.GlTexture0 + idx);
                GLES20.GlBindTexture(GLES20.GlTexture2d, textures[idx]);
                GLES20.GlUniform1i(glTexture, idx);
                GLES20.GlUniformMatrix2fv(glPlaneUvMatrix, 1, false, planeAngleUvMatrix, 0);

                DrawLabel(cameraViews, cameraProjection);
            }

            GLES20.GlDisableVertexAttribArray(glPositionParameter);
            GLES20.GlBindTexture(GLES20.GlTexture2d, 0);
            GLES20.GlDisable(GLES20.GlBlend);
            GLES20.GlDepthMask(true);
            ShaderUtil.CheckGlError(TAG, "Draw sorted plans end.");
        }
Пример #22
0
        /// <summary>
        /// This method updates the connection data of skeleton points and is called when any frame is updated.
        /// </summary>
        /// <param name="handSkeletons">Bone point data of hand.</param>
        /// <param name="handSkeletonConnection">Data of connection between bone points of hand.</param>
        private void UpdateHandSkeletonLinesData(float[] handSkeletons, int[] handSkeletonConnection)
        {
            ShaderUtil.CheckGlError(TAG, "Update hand skeleton lines data start.");
            int pointsLineNum = 0;

            // Each point is a set of 3D coordinate. Each connection line consists of two points.
            float[] linePoint = new float[handSkeletonConnection.Length * 3 * 2];

            // The format of HandSkeletonConnection data is [p0,p1;p0,p3;p0,p5;p1,p2].
            // handSkeletonConnection saves the node indexes. Two indexes obtain a set
            // of connection point data. Therefore, j = j + 2. This loop obtains related
            // coordinates and saves them in linePoint.
            for (int j = 0; j < handSkeletonConnection.Length; j += 2)
            {
                linePoint[pointsLineNum * 3]     = handSkeletons[3 * handSkeletonConnection[j]];
                linePoint[pointsLineNum * 3 + 1] = handSkeletons[3 * handSkeletonConnection[j] + 1];
                linePoint[pointsLineNum * 3 + 2] = handSkeletons[3 * handSkeletonConnection[j] + 2];
                linePoint[pointsLineNum * 3 + 3] = handSkeletons[3 * handSkeletonConnection[j + 1]];
                linePoint[pointsLineNum * 3 + 4] = handSkeletons[3 * handSkeletonConnection[j + 1] + 1];
                linePoint[pointsLineNum * 3 + 5] = handSkeletons[3 * handSkeletonConnection[j + 1] + 2];
                pointsLineNum += 2;
            }
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVbo);
            mPointsNum = pointsLineNum;

            // If the storage space is insufficient, apply for twice the memory each time.
            if (mVboSize < mPointsNum * BYTES_PER_POINT)
            {
                while (mVboSize < mPointsNum * BYTES_PER_POINT)
                {
                    mVboSize *= 2;
                }
                GLES20.GlBufferData(GLES20.GlArrayBuffer, mVboSize, null, GLES20.GlDynamicDraw);
            }
            FloatBuffer linePoints = FloatBuffer.Wrap(linePoint);

            Log.Debug(TAG, "Skeleton skeleton line points num: " + mPointsNum);
            Log.Debug(TAG, "Skeleton line points: " + linePoints.ToString());
            GLES20.GlBufferSubData(GLES20.GlArrayBuffer, 0, mPointsNum * BYTES_PER_POINT,
                                   linePoints);
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0);
            ShaderUtil.CheckGlError(TAG, "Update hand skeleton lines data end.");
        }
 /// <summary>
 /// Update body connection data.
 /// </summary>
 private void UpdateBodySkeletonLineData(ARBody body)
 {
     FindValidConnectionSkeletonLines(body);
     ShaderUtil.CheckGlError(TAG, "Update body skeleton line data start.");
     GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVbo);
     mNumPoints = mPointsLineNum;
     if (mVboSize < mNumPoints * BYTES_PER_POINT)
     {
         while (mVboSize < mNumPoints * BYTES_PER_POINT)
         {
             // If the storage space is insufficient, allocate double the space.
             mVboSize *= 2;
         }
         GLES20.GlBufferData(GLES20.GlArrayBuffer, mVboSize, null, GLES20.GlDynamicDraw);
     }
     GLES20.GlBufferSubData(GLES20.GlArrayBuffer, 0, mNumPoints * BYTES_PER_POINT, mLinePoints);
     GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0);
     ShaderUtil.CheckGlError(TAG, "Update body skeleton line data end.");
 }
Пример #24
0
        private void UpdateBodySkeleton()
        {
            ShaderUtil.CheckGlError(TAG, "Update Body Skeleton data start.");

            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVbo);
            mNumPoints = mPointsNum;

            if (mVboSize < mNumPoints * BYTES_PER_POINT)
            {
                while (mVboSize < mNumPoints * BYTES_PER_POINT)
                {
                    // If the size of VBO is insufficient to accommodate the new point cloud, resize the VBO.
                    mVboSize *= 2;
                }
                GLES20.GlBufferData(GLES20.GlArrayBuffer, mVboSize, null, GLES20.GlDynamicDraw);
            }
            GLES20.GlBufferSubData(GLES20.GlArrayBuffer, 0, mNumPoints * BYTES_PER_POINT, mSkeletonPoints);
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0);

            ShaderUtil.CheckGlError(TAG, "Update Body Skeleton data end.");
        }
        /// <summary>
        /// Draw hand skeleton points.
        /// </summary>
        /// <param name="projectionMatrix">Projection matrix.</param>
        private void DrawHandSkeletons(float[] projectionMatrix)
        {
            ShaderUtil.CheckGlError(TAG, "Draw hand skeletons start.");
            GLES20.GlUseProgram(mProgram);
            GLES20.GlEnableVertexAttribArray(mPosition);
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVbo);

            // The size of the vertex attribute is 4, and each vertex has four coordinate components
            GLES20.GlVertexAttribPointer(
                mPosition, 4, GLES20.GlFloat, false, BYTES_PER_POINT, 0);

            // Set the color of the skeleton points to blue.
            GLES20.GlUniform4f(mColor, 0.0f, 0.0f, 1.0f, 1.0f);
            GLES20.GlUniformMatrix4fv(mModelViewProjectionMatrix, 1, false, projectionMatrix, 0);

            // Set the size of the skeleton points.
            GLES20.GlUniform1f(mPointSize, 30.0f);

            GLES20.GlDrawArrays(GLES20.GlPoints, 0, mNumPoints);
            GLES20.GlDisableVertexAttribArray(mPosition);
            GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0);

            ShaderUtil.CheckGlError(TAG, "Draw hand skeletons end.");
        }
        private void InitGlTextureData(Context context)
        {
            ShaderUtil.CheckGlError(TAG, "Init gl texture data start.");
            Bitmap       textureBitmap = null;
            AssetManager assets        = context.Assets;

            try
            {
                var sr = assets.Open("AR_logo.png");
                textureBitmap = BitmapFactory.DecodeStream(sr);
            }
            catch (Exception e)
            {
                Log.Debug(TAG, " Open Bitmap Error! ");
                return;
            }

            ShaderUtil.CheckGlError(TAG, "bitmap error.");
            GLUtils.TexImage2D(GLES20.GlTexture2d, 0, textureBitmap, 0);
            GLES20.GlGenerateMipmap(GLES20.GlTexture2d);
            GLES20.GlBindTexture(GLES20.GlTexture2d, 0);
            textureBitmap.Recycle();
            ShaderUtil.CheckGlError(TAG, "Init gl texture data end.");
        }