/// <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."); }
/// <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."); }
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."); }
/// <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."); }
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."); }