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> /// 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."); }
//---------------------------------------------------------------------- public virtual void loadFileToVBO(String fileName) { if (string.IsNullOrEmpty(fileName)) { return; } files.Add(fileName); int indexResult = VBOManager.getVBOIndex(fileName); if (indexResult == -1) { if (loadingBinModel(fileName)) { GLES20.GlBindBuffer(GLES20.GlArrayBuffer, VBOManager.getVBO(fileName)[0]); GLES20.GlBufferData(GLES20.GlArrayBuffer, vertexBuffer.Capacity() * FLOAT_SIZE, vertexBuffer, GLES20.GlStaticDraw); // vbb.capacity() vertexBuffer = null; GLES20.GlBindBuffer(GLES20.GlArrayBuffer, VBOManager.getVBO(fileName)[2]); GLES20.GlBufferData(GLES20.GlArrayBuffer, normalBuffer.Capacity() * FLOAT_SIZE, normalBuffer, GLES20.GlStaticDraw); // vbb.capacity() normalBuffer = null; GLES20.GlBindBuffer(GLES20.GlArrayBuffer, VBOManager.getVBO(fileName)[1]); GLES20.GlBufferData(GLES20.GlArrayBuffer, textureBuffer.Capacity() * FLOAT_SIZE, textureBuffer, GLES20.GlStaticDraw); // vbb.capacity() textureBuffer = null; System.GC.Collect(); } } }
/// <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."); }
/** * Renders the point cloud. * * @param pose the current point cloud pose, from {@link Frame#getPointCloudPose()}. * @param cameraView the camera view matrix for this frame, typically from * {@link Frame#getViewMatrix(float[], int)}. * @param cameraPerspective the camera projection matrix for this frame, typically from * {@link Session#getProjectionMatrix(float[], int, float, float)}. */ public void Draw(Pose pose, float[] cameraView, float[] cameraPerspective) { float[] modelMatrix = new float[16]; pose.ToMatrix(modelMatrix, 0); float[] modelView = new float[16]; float[] modelViewProjection = new float[16]; Matrix.MultiplyMM(modelView, 0, cameraView, 0, modelMatrix, 0); Matrix.MultiplyMM(modelViewProjection, 0, cameraPerspective, 0, modelView, 0); ShaderUtil.CheckGLError(TAG, "Before draw"); GLES20.GlUseProgram(mProgramName); GLES20.GlEnableVertexAttribArray(mPositionAttribute); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVbo); GLES20.GlVertexAttribPointer( mPositionAttribute, 4, GLES20.GlFloat, false, BYTES_PER_POINT, 0); GLES20.GlUniform4f(mColorUniform, 31.0f / 255.0f, 188.0f / 255.0f, 210.0f / 255.0f, 1.0f); GLES20.GlUniformMatrix4fv(mModelViewProjectionUniform, 1, false, modelViewProjection, 0); GLES20.GlUniform1f(mPointSizeUniform, 5.0f); GLES20.GlDrawArrays(GLES20.GlPoints, 0, mNumPoints); GLES20.GlDisableVertexAttribArray(mPositionAttribute); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0); ShaderUtil.CheckGLError(TAG, "Draw"); }
/** * Updates the OpenGL buffer contents to the provided point. Repeated calls with the same * point cloud will be ignored. */ public void Update(PointCloud cloud) { if (mLastPointCloud == cloud) { // Redundant call. return; } ShaderUtil.CheckGLError(TAG, "before update"); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVbo); mLastPointCloud = cloud; // If the VBO is not large enough to fit the new point cloud, resize it. mNumPoints = mLastPointCloud.Points.Remaining() / FLOATS_PER_POINT; if (mNumPoints * BYTES_PER_POINT > mVboSize) { while (mNumPoints * BYTES_PER_POINT > mVboSize) { mVboSize *= 2; } GLES20.GlBufferData(GLES20.GlArrayBuffer, mVboSize, null, GLES20.GlDynamicDraw); } GLES20.GlBufferSubData(GLES20.GlArrayBuffer, 0, mNumPoints * BYTES_PER_POINT, mLastPointCloud.Points); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0); ShaderUtil.CheckGLError(TAG, "after update"); }
public virtual void draw() { try { // if (levelScale) Matrix.ScaleM(mModelMatrix, 0, GlobalVar.levelScale, GlobalVar.levelScale, GlobalVar.levelScale); ShaderCompiller shader = ShaderManager.getShader(shaderName); GLES20.GlUseProgram(shader.program); int size = 4; // data count 2 for vec2 4 for vec4 int b = 0; int c = 0; GLES20.GlEnableVertexAttribArray(ShaderManager.getShader(shaderName).attrib_vertex); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, VBOManager.getVBO(fileName)[0]); GLES20.GlVertexAttribPointer(ShaderManager.getShader(shaderName).attrib_vertex, size, GLES20.GlFloat, false, b, c); GLES20.GlEnableVertexAttribArray(ShaderManager.getShader(shaderName).normal); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, VBOManager.getVBO(fileName)[2]); GLES20.GlVertexAttribPointer(ShaderManager.getShader(shaderName).normal, size, GLES20.GlFloat, false, b, c); GLES20.GlUniform3f(ShaderManager.getShader(shaderName).lightPos, render.eyeX, render.eyeY, render.eyeZ); GLES20.GlUniformMatrix4fv(ShaderManager.getShader(shaderName).mMVMatrixHandle, 1, false, render._mViewMatrix, 0); //MV Matrix //Matrix.SetIdentityM(mMVPMatrix, 0); float[] mModetView = new float[16]; Matrix.MultiplyMM(mModetView, 0, render._mViewMatrix, 0, mModelMatrix, 0); Matrix.MultiplyMM(mMVPMatrix, 0, render.mProjectionMatrix, 0, mModetView, 0); GLES20.GlUniformMatrix4fv(ShaderManager.getShader(shaderName).mMVPMatrixHandle, 1, false, mMVPMatrix, 0); //MVP Matrix if (textureResID != -1) { GLES20.GlEnableVertexAttribArray(ShaderManager.getShader(shaderName).mTextureCoordinateHandle); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, VBOManager.getVBO(fileName)[1]); int bsize = 2; GLES20.GlVertexAttribPointer(ShaderManager.getShader(shaderName).mTextureCoordinateHandle, bsize, GLES20.GlFloat, false, b, c); GLES20.GlActiveTexture(GLES20.GlTexture0); GLES20.GlBindTexture(GLES20.GlTexture2d, TextureManager.getTextureHandle(context, textureResID)); GLES20.GlUniform1i(ShaderManager.getShader(shaderName).mTextureUniformHandle, 0); GLES20.GlActiveTexture(GLES20.GlTexture1); GLES20.GlBindTexture(GLES20.GlTexture2d, TextureManager.getTextureHandle(context, texture2ResID)); GLES20.GlUniform1i(ShaderManager.getShader(shaderName).mTextureUniformHandleF, 1); GLES20.GlActiveTexture(GLES20.GlTexture2); GLES20.GlBindTexture(GLES20.GlTexture2d, TextureManager.getTextureHandle(context, texture3ResID)); GLES20.GlUniform1i(ShaderManager.getShader(shaderName).mTextureUniformHandleS, 2); } GLES20.GlDrawArrays(GLES20.GlTriangles, 0, VBOManager.getSize(fileName)); GLES20.GlUseProgram(0); } catch { } }
/// <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> /// 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 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"); }
/// <summary> /// Allocates and initializes OpenGL resources needed by the plane renderer. Must be /// called on the OpenGL thread, typically in /// {@link GLSurfaceView.Renderer#onSurfaceCreated(GL10, EGLConfig)}. /// </summary> public void CreateOnGlThread(Context context) { //ShaderHelper.CheckGLError(TAG, "before create"); var buffers = new int[1]; GLES20.GlGenBuffers(1, buffers, 0); mVbo = buffers[0]; GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVbo); mVboSize = INITIAL_BUFFER_POINTS * BYTES_PER_POINT; GLES20.GlBufferData(GLES20.GlArrayBuffer, mVboSize, null, GLES20.GlDynamicDraw); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0); var vertexShader = ShaderHelper.Load(TAG, context, GLES20.GlVertexShader, Resource.Raw.point_cloud_vertex); var passthroughShader = ShaderHelper.Load(TAG, context, GLES20.GlFragmentShader, Resource.Raw.passthrough_fragment); mProgramName = GLES20.GlCreateProgram(); GLES20.GlAttachShader(mProgramName, vertexShader); GLES20.GlAttachShader(mProgramName, passthroughShader); GLES20.GlLinkProgram(mProgramName); GLES20.GlUseProgram(mProgramName); mPositionAttribute = GLES20.GlGetAttribLocation(mProgramName, "a_Position"); mColorUniform = GLES20.GlGetUniformLocation(mProgramName, "u_Color"); mModelViewProjectionUniform = GLES20.GlGetUniformLocation( mProgramName, "u_ModelViewProjection"); mPointSizeUniform = GLES20.GlGetUniformLocation(mProgramName, "u_PointSize"); }
public void OnDrawFrame(IGL10 gl) { GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit); // Draw the triangle facing straight on. angleInDegrees += 0.2f; //Prepare model transformation matrix float[] mModelMatrix = new float[16]; Matrix.SetIdentityM(mModelMatrix, 0); Matrix.RotateM(mModelMatrix, 0, angleInDegrees, 1.0f, 0.0f, 0.0f); //Draw with VBO GLES20.GlBindBuffer(GLES20.GlArrayBuffer, VBOBuffers[0]); GLES20.GlEnableVertexAttribArray(mPositionHandle); GLES20.GlVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GlFloat, false, 0, 0); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, VBOBuffers[1]); GLES20.GlEnableVertexAttribArray(mColorHandle); GLES20.GlVertexAttribPointer(mColorHandle, mColorDataSize, GLES20.GlFloat, false, 0, 0); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, VBOBuffers[2]); GLES20.GlEnableVertexAttribArray(mTextureCoordHandle); GLES20.GlVertexAttribPointer(mTextureCoordHandle, 2, GLES20.GlFloat, false, 0, 0); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, VBOBuffers[3]); GLES20.GlEnableVertexAttribArray(mNormalHandle); GLES20.GlVertexAttribPointer(mNormalHandle, 3, GLES20.GlFloat, false, 0, 0); GLES20.GlActiveTexture(GLES20.GlTexture0); GLES20.GlBindTexture(GLES20.GlTexture2d, textureHandle[0]); GLES20.GlUniform1i(mTextureHandle, 0); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0); //END OF Draw with VBO //light position // GLES20.GlUniform3f(mLightPos, 0.0f, 0.0f, angleInDegrees); GLES20.GlUniform3f(mLightPos, 0.0f, 0.0f, 0.0f); // This multiplies the view matrix by the model matrix, and stores the result in the MVP matrix // (which currently contains model * view). // Allocate storage for the final combined matrix. This will be passed into the shader program. */ float[] mMVPMatrix = new float[16]; Matrix.MultiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0); // This multiplies the modelview matrix by the projection matrix, and stores the result in the MVP matrix // (which now contains model * view * projection). // THIS IS NOT WORK AT C# Matrix class -> Matrix.MultiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0); float[] _mMVPMatrix = new float[16]; Matrix.MultiplyMM(_mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0); GLES20.GlUniformMatrix4fv(mMVPMatrixHandle, 1, false, _mMVPMatrix, 0); GLES20.GlDrawArrays(GLES20.GlTriangles, 0, 3 * 12); //Cube has 12 triagle faces each face has 3 coord }
/// <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."); }
public void OnDrawFrame(IGL10 gl) { GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit); // Draw the triangle facing straight on. angleInDegrees += 1.0f; //Prepare model transformation matrix float[] mModelMatrix = new float[16]; //Draw with VBO GLES20.GlBindBuffer(GLES20.GlArrayBuffer, VBOBuffers[0]); GLES20.GlEnableVertexAttribArray(mPositionHandle); GLES20.GlVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GlFloat, false, 0, 0); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, VBOBuffers[1]); GLES20.GlEnableVertexAttribArray(mColorHandle); GLES20.GlVertexAttribPointer(mColorHandle, mColorDataSize, GLES20.GlFloat, false, 0, 0); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0); //END OF Draw with VBO // This multiplies the view matrix by the model matrix, and stores the result in the MVP matrix // (which currently contains model * view). // Allocate storage for the final combined matrix. This will be passed into the shader program. */ float[] mMVPMatrix = new float[16]; Matrix.MultiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0); // This multiplies the modelview matrix by the projection matrix, and stores the result in the MVP matrix // (which now contains model * view * projection). // THIS IS NOT WORK AT C# Matrix class -> Matrix.MultiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0); float[] _mMVPMatrix = new float[16]; Matrix.MultiplyMM(_mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0); GLES20.GlUniformMatrix4fv(mMVPMatrixHandle, 1, false, _mMVPMatrix, 0); //GLES20.GlDrawArrays(GLES20.GlTriangles, 0, 3); for (int y = 0; y < 30; y++) { for (int x = 0; x < 30; x++) { Matrix.SetIdentityM(mModelMatrix, 0); Matrix.ScaleM(mModelMatrix, 0, 0.5f, 0.5f, 0.5f); Matrix.TranslateM(mModelMatrix, 0, x * 2.0f, y * 2.0f, 0.0f); Matrix.RotateM(mModelMatrix, 0, angleInDegrees, 1.0f, 0.0f, 0.0f); Matrix.MultiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0); Matrix.MultiplyMM(_mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0); GLES20.GlUniformMatrix4fv(mMVPMatrixHandle, 1, false, _mMVPMatrix, 0); GLES20.GlDrawArrays(GLES20.GlTriangles, 0, 3); } } }
/// <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."); }
/// <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 ArrayToVBO(Array source, int size) { float[] floatArray = new float[size / 4]; System.Buffer.BlockCopy(source, 0, floatArray, 0, (int)size); //temp Cut vertex int cutSize = 0; for (int i = 0; i < size / 4; i += 3) { if (floatArray[i + 1] < 20.0f) { cutSize++; } } float[] cutArray = new float[cutSize * 3]; int cutArrayIndex = 0; for (int i = 0; i < size / 4; i += 3) { if (floatArray[i + 1] < 20.0f) { cutArray[cutArrayIndex] = floatArray[i]; cutArray[cutArrayIndex + 1] = floatArray[i + 1]; cutArray[cutArrayIndex + 2] = floatArray[i + 2]; cutArrayIndex += 3; } } size = cutSize * 3 * 4; objectSize = (int)(size / 4 / 3); FloatBuffer vertexBuffer; vertexBuffer = FloatBuffer.Allocate((int)size / 4); // float array to vertexBuffer.Put(cutArray, 0, (int)size / 4); vertexBuffer.Flip(); GLES20.GlGenBuffers(1, VBOBuffers, 0); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, VBOBuffers[0]); //VBOManager.setSize(fileName, vertexBuffer.Capacity() / 4); //is size of vertex count = 1 vertex 4 float x,y,z, 1 GLES20.GlBufferData(GLES20.GlArrayBuffer, vertexBuffer.Capacity() * mBytesPerFloat, vertexBuffer, GLES20.GlStaticDraw); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0); handle = VBOBuffers[0]; floatArray = null; vertexBuffer = null; }
/// <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."); }
public void afterDrawFrame() { GLES20.GlBindFramebuffer(36160, mOriginalFramebufferId /*.array()[0]*/.Get(0)); GLES20.GlViewport(0, 0, mHmd.getScreen().getWidth(), mHmd.getScreen().getHeight()); GLES20.GlGetIntegerv(2978, mViewport); GLES20.GlGetIntegerv(2884, mCullFaceEnabled); GLES20.GlGetIntegerv(3089, mScissorTestEnabled); GLES20.GlDisable(3089); GLES20.GlDisable(2884); GLES20.GlClearColor(0.0F, 0.0F, 0.0F, 1.0F); GLES20.GlClear(16640); GLES20.GlUseProgram(mProgramHolder.program); GLES20.GlEnable(3089); GLES20.GlScissor(0, 0, mHmd.getScreen().getWidth() / 2, mHmd.getScreen().getHeight()); renderDistortionMesh(mLeftEyeDistortionMesh); GLES20.GlScissor(mHmd.getScreen().getWidth() / 2, 0, mHmd.getScreen().getWidth() / 2, mHmd.getScreen().getHeight()); renderDistortionMesh(mRightEyeDistortionMesh); GLES20.GlDisableVertexAttribArray(mProgramHolder.aPosition); GLES20.GlDisableVertexAttribArray(mProgramHolder.aVignette); GLES20.GlDisableVertexAttribArray(mProgramHolder.aTextureCoord); GLES20.GlUseProgram(0); GLES20.GlBindBuffer(34962, 0); GLES20.GlBindBuffer(34963, 0); GLES20.GlDisable(3089); if (mCullFaceEnabled /*.array()[0]*/.Get(0) == 1) { GLES20.GlEnable(2884); } if (mScissorTestEnabled /*.array()[0]*/.Get(0) == 1) { GLES20.GlEnable(3089); } GLES20.GlViewport(mViewport /*.array()[0]*/.Get(0), mViewport /*.array()[1]*/.Get(1), mViewport /*.array()[2]*/.Get(2), mViewport /*.array()[3]*/.Get(3)); }
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."); }
private void renderDistortionMesh(DistortionMesh mesh) { GLES20.GlBindBuffer(34962, mesh.mArrayBufferId); /*mesh.getClass(); mesh.getClass();*/ GLES20.GlVertexAttribPointer(mProgramHolder.aPosition, 3, 5126, false, 20, 0 * 4); GLES20.GlEnableVertexAttribArray(mProgramHolder.aPosition); /*mesh.getClass(); mesh.getClass();*/ GLES20.GlVertexAttribPointer(mProgramHolder.aVignette, 1, 5126, false, 20, 2 * 4); GLES20.GlEnableVertexAttribArray(mProgramHolder.aVignette); /*mesh.getClass(); mesh.getClass();*/ GLES20.GlVertexAttribPointer(mProgramHolder.aTextureCoord, 2, 5126, false, 20, 3 * 4); GLES20.GlEnableVertexAttribArray(mProgramHolder.aTextureCoord); GLES20.GlActiveTexture(33984); GLES20.GlBindTexture(3553, mTextureId); GLES20.GlUniform1i(mProgramHolder.uTextureSampler, 0); GLES20.GlUniform1f(mProgramHolder.uTextureCoordScale, mResolutionScale); GLES20.GlBindBuffer(34963, mesh.mElementBufferId); GLES20.GlDrawElements(5, mesh.nIndices, 5125, 0); }
/// <summary> /// Updates the OpenGL buffer contents to the provided point. Repeated calls with the same /// point cloud will be ignored. /// </summary> public void Update(PointCloud cloud) { if (mLastPointCloud == cloud) { return; } GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVbo); mLastPointCloud = cloud; // If the VBO is not large enough to fit the new point cloud, resize it. mNumPoints = mLastPointCloud.Points.Remaining() / FLOATS_PER_POINT; if (mNumPoints * BYTES_PER_POINT > mVboSize) { while (mNumPoints * BYTES_PER_POINT > mVboSize) { mVboSize *= 2; } GLES20.GlBufferData(GLES20.GlArrayBuffer, mVboSize, null, GLES20.GlDynamicDraw); } GLES20.GlBufferSubData(GLES20.GlArrayBuffer, 0, mNumPoints * BYTES_PER_POINT, mLastPointCloud.Points); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0); }
/// <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 int[] VBOBuffers = new int[2]; //2 buffers for vertices and colors public void OnSurfaceCreated(IGL10 gl, Javax.Microedition.Khronos.Egl.EGLConfig config) { const float edge = 1.0f; // X, Y, Z, float[] triangleVerticesData = { -1.5f, -0.25f, 0.0f, 0.5f, -0.25f, 0.0f, 0.0f, 0.559016994f, 0.0f }; FloatBuffer mTriangleVertices = ByteBuffer.AllocateDirect(triangleVerticesData.Length * mBytesPerFloat).Order(ByteOrder.NativeOrder()).AsFloatBuffer(); mTriangleVertices.Put(triangleVerticesData).Flip(); // R, G, B, A float[] triangleColorsData = { 1.0f, 0.0f, 0.0f, 0.5f, 0.0f, 0.5f, 1.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f }; FloatBuffer mTriangleColors = ByteBuffer.AllocateDirect(triangleColorsData.Length * mBytesPerFloat).Order(ByteOrder.NativeOrder()).AsFloatBuffer(); mTriangleColors.Put(triangleColorsData).Flip(); //Use VBO GLES20.GlGenBuffers(2, VBOBuffers, 0); //2 buffers for vertices and colors GLES20.GlBindBuffer(GLES20.GlArrayBuffer, VBOBuffers[0]); GLES20.GlBufferData(GLES20.GlArrayBuffer, mTriangleVertices.Capacity() * mBytesPerFloat, mTriangleVertices, GLES20.GlStaticDraw); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, VBOBuffers[1]); GLES20.GlBufferData(GLES20.GlArrayBuffer, mTriangleColors.Capacity() * mBytesPerFloat, mTriangleColors, GLES20.GlStaticDraw); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0); GLES20.GlClearColor(1.0f, 1.0f, 1.0f, 1.0f); // Position the eye behind the origin. float eyeX = 0.0f; float eyeY = 0.0f; float eyeZ = 4.5f; // We are looking toward the distance float lookX = 0.0f; float lookY = 0.0f; float lookZ = -5.0f; // Set our up vector. This is where our head would be pointing were we holding the camera. float upX = 0.0f; float upY = 1.0f; float upZ = 0.0f; // Set the view matrix. This matrix can be said to represent the camera position. // NOTE: In OpenGL 1, a ModelView matrix is used, which is a combination of a model and // view matrix. In OpenGL 2, we can keep track of these matrices separately if we choose. Matrix.SetLookAtM(mViewMatrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ); string vertexShader = "uniform mat4 u_MVPMatrix; \n" // A constant representing the combined model/view/projection matrix. + "attribute vec4 a_Position; \n" // Per-vertex position information we will pass in. + "attribute vec4 a_Color; \n" // Per-vertex color information we will pass in. + "varying vec4 v_Color; \n" // This will be passed into the fragment shader. + "void main() \n" // The entry point for our vertex shader. + "{ \n" + " v_Color = a_Color; \n" // Pass the color through to the fragment shader. It will be interpolated across the triangle. + " gl_Position = u_MVPMatrix \n" // gl_Position is a special variable used to store the final position. + " * a_Position; \n" // Multiply the vertex by the matrix to get the final point in normalized screen coordinates. + "} \n"; string fragmentShader = "precision mediump float; \n" // Set the default precision to medium. We don't need as high of a // precision in the fragment shader. + "varying vec4 v_Color; \n" // This is the color from the vertex shader interpolated across the triangle per fragment. + "void main() \n" // The entry point for our fragment shader. + "{ \n" + " gl_FragColor = v_Color; \n" // Pass the color directly through the pipeline. + "} \n"; int vertexShaderHandle = GLES20.GlCreateShader(GLES20.GlVertexShader); if (vertexShaderHandle != 0) { // Pass in the shader source. GLES20.GlShaderSource(vertexShaderHandle, vertexShader); // Compile the shader. GLES20.GlCompileShader(vertexShaderHandle); // Get the compilation status. int[] compileStatus = new int[1]; GLES20.GlGetShaderiv(vertexShaderHandle, GLES20.GlCompileStatus, compileStatus, 0); // If the compilation failed, delete the shader. if (compileStatus[0] == 0) { GLES20.GlDeleteShader(vertexShaderHandle); vertexShaderHandle = 0; } } if (vertexShaderHandle == 0) { throw new Exception("Error creating vertex shader."); } // Load in the fragment shader shader. int fragmentShaderHandle = GLES20.GlCreateShader(GLES20.GlFragmentShader); if (fragmentShaderHandle != 0) { // Pass in the shader source. GLES20.GlShaderSource(fragmentShaderHandle, fragmentShader); // Compile the shader. GLES20.GlCompileShader(fragmentShaderHandle); // Get the compilation status. int[] compileStatus = new int[1]; GLES20.GlGetShaderiv(fragmentShaderHandle, GLES20.GlCompileStatus, compileStatus, 0); // If the compilation failed, delete the shader. if (compileStatus[0] == 0) { GLES20.GlDeleteShader(fragmentShaderHandle); fragmentShaderHandle = 0; } } if (fragmentShaderHandle == 0) { throw new Exception("Error creating fragment shader."); } // Create a program object and store the handle to it. int programHandle = GLES20.GlCreateProgram(); if (programHandle != 0) { // Bind the vertex shader to the program. GLES20.GlAttachShader(programHandle, vertexShaderHandle); // Bind the fragment shader to the program. GLES20.GlAttachShader(programHandle, fragmentShaderHandle); // Bind attributes GLES20.GlBindAttribLocation(programHandle, 0, "a_Position"); GLES20.GlBindAttribLocation(programHandle, 1, "a_Color"); // Link the two shaders together into a program. GLES20.GlLinkProgram(programHandle); // Get the link status. int[] linkStatus = new int[1]; GLES20.GlGetProgramiv(programHandle, GLES20.GlLinkStatus, linkStatus, 0); // If the link failed, delete the program. if (linkStatus[0] == 0) { GLES20.GlDeleteProgram(programHandle); programHandle = 0; } } if (programHandle == 0) { throw new Exception("Error creating program."); } // Set program handles. These will later be used to pass in values to the program. mMVPMatrixHandle = GLES20.GlGetUniformLocation(programHandle, "u_MVPMatrix"); mPositionHandle = GLES20.GlGetAttribLocation(programHandle, "a_Position"); mColorHandle = GLES20.GlGetAttribLocation(programHandle, "a_Color"); // Tell OpenGL to use this program when rendering. GLES20.GlUseProgram(programHandle); }
/** * Creates and initializes OpenGL resources needed for rendering the model. * * @param context Context for loading the shader and below-named model and texture assets. * @param objAssetName Name of the OBJ file containing the model geometry. * @param diffuseTextureAssetName Name of the PNG file containing the diffuse texture map. */ public void CreateOnGlThread(Context context, string objAssetName, string diffuseTextureAssetName) { // Read the texture. var textureBitmap = BitmapFactory.DecodeStream(context.Assets.Open(diffuseTextureAssetName)); GLES20.GlActiveTexture(GLES20.GlTexture0); GLES20.GlGenTextures(mTextures.Length, mTextures, 0); GLES20.GlBindTexture(GLES20.GlTexture2d, mTextures[0]); 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); textureBitmap.Recycle(); ShaderUtil.CheckGLError(TAG, "Texture loading"); // Read the obj file. var objInputStream = context.Assets.Open(objAssetName); var obj = ObjReader.Read(objInputStream); // Prepare the Obj so that its structure is suitable for // rendering with OpenGL: // 1. Triangulate it // 2. Make sure that texture coordinates are not ambiguous // 3. Make sure that normals are not ambiguous // 4. Convert it to single-indexed data obj = ObjUtils.ConvertToRenderable(obj); // OpenGL does not use Java arrays. ByteBuffers are used instead to provide data in a format // that OpenGL understands. // Obtain the data from the OBJ, as direct buffers: IntBuffer wideIndices = ObjData.GetFaceVertexIndices(obj, 3); FloatBuffer vertices = ObjData.GetVertices(obj); FloatBuffer texCoords = ObjData.GetTexCoords(obj, 2); FloatBuffer normals = ObjData.GetNormals(obj); // Convert int indices to shorts for GL ES 2.0 compatibility ShortBuffer indices = ByteBuffer.AllocateDirect(2 * wideIndices.Limit()) .Order(ByteOrder.NativeOrder()).AsShortBuffer(); while (wideIndices.HasRemaining) { indices.Put((short)wideIndices.Get()); } indices.Rewind(); var buffers = new int[2]; GLES20.GlGenBuffers(2, buffers, 0); mVertexBufferId = buffers[0]; mIndexBufferId = buffers[1]; // Load vertex buffer mVerticesBaseAddress = 0; mTexCoordsBaseAddress = mVerticesBaseAddress + 4 * vertices.Limit(); mNormalsBaseAddress = mTexCoordsBaseAddress + 4 * texCoords.Limit(); int totalBytes = mNormalsBaseAddress + 4 * normals.Limit(); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVertexBufferId); GLES20.GlBufferData(GLES20.GlArrayBuffer, totalBytes, null, GLES20.GlStaticDraw); GLES20.GlBufferSubData( GLES20.GlArrayBuffer, mVerticesBaseAddress, 4 * vertices.Limit(), vertices); GLES20.GlBufferSubData( GLES20.GlArrayBuffer, mTexCoordsBaseAddress, 4 * texCoords.Limit(), texCoords); GLES20.GlBufferSubData( GLES20.GlArrayBuffer, mNormalsBaseAddress, 4 * normals.Limit(), normals); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0); // Load index buffer GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, mIndexBufferId); mIndexCount = indices.Limit(); GLES20.GlBufferData( GLES20.GlElementArrayBuffer, 2 * mIndexCount, indices, GLES20.GlStaticDraw); GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, 0); ShaderUtil.CheckGLError(TAG, "OBJ buffer load"); int vertexShader = ShaderUtil.LoadGLShader(TAG, context, GLES20.GlVertexShader, Resource.Raw.object_vertex); int fragmentShader = ShaderUtil.LoadGLShader(TAG, context, GLES20.GlFragmentShader, Resource.Raw.object_fragment); mProgram = GLES20.GlCreateProgram(); GLES20.GlAttachShader(mProgram, vertexShader); GLES20.GlAttachShader(mProgram, fragmentShader); GLES20.GlLinkProgram(mProgram); GLES20.GlUseProgram(mProgram); ShaderUtil.CheckGLError(TAG, "Program creation"); mModelViewUniform = GLES20.GlGetUniformLocation(mProgram, "u_ModelView"); mModelViewProjectionUniform = GLES20.GlGetUniformLocation(mProgram, "u_ModelViewProjection"); mPositionAttribute = GLES20.GlGetAttribLocation(mProgram, "a_Position"); mNormalAttribute = GLES20.GlGetAttribLocation(mProgram, "a_Normal"); mTexCoordAttribute = GLES20.GlGetAttribLocation(mProgram, "a_TexCoord"); mTextureUniform = GLES20.GlGetUniformLocation(mProgram, "u_Texture"); mLightingParametersUniform = GLES20.GlGetUniformLocation(mProgram, "u_LightingParameters"); mMaterialParametersUniform = GLES20.GlGetUniformLocation(mProgram, "u_MaterialParameters"); ShaderUtil.CheckGLError(TAG, "Program parameters"); Android.Opengl.Matrix.SetIdentityM(mModelMatrix, 0); }
/** * Draws the model. * * @param cameraView A 4x4 view matrix, in column-major order. * @param cameraPerspective A 4x4 projection matrix, in column-major order. * @param lightIntensity Illumination intensity. Combined with diffuse and specular material * properties. * @see #setBlendMode(BlendMode) * @see #updateModelMatrix(float[], float) * @see #setMaterialProperties(float, float, float, float) * @see android.opengl.Matrix */ public void Draw(float[] cameraView, float[] cameraPerspective, float lightIntensity) { ShaderUtil.CheckGLError(TAG, "Before draw"); // Build the ModelView and ModelViewProjection matrices // for calculating object position and light. Android.Opengl.Matrix.MultiplyMM(mModelViewMatrix, 0, cameraView, 0, mModelMatrix, 0); Android.Opengl.Matrix.MultiplyMM(mModelViewProjectionMatrix, 0, cameraPerspective, 0, mModelViewMatrix, 0); GLES20.GlUseProgram(mProgram); // Set the lighting environment properties. Android.Opengl.Matrix.MultiplyMV(mViewLightDirection, 0, mModelViewMatrix, 0, LIGHT_DIRECTION, 0); normalizeVec3(mViewLightDirection); GLES20.GlUniform4f(mLightingParametersUniform, mViewLightDirection[0], mViewLightDirection[1], mViewLightDirection[2], lightIntensity); // Set the object material properties. GLES20.GlUniform4f(mMaterialParametersUniform, mAmbient, mDiffuse, mSpecular, mSpecularPower); // Attach the object texture. GLES20.GlActiveTexture(GLES20.GlTexture0); GLES20.GlBindTexture(GLES20.GlTexture2d, mTextures[0]); GLES20.GlUniform1i(mTextureUniform, 0); // Set the vertex attributes. GLES20.GlBindBuffer(GLES20.GlArrayBuffer, mVertexBufferId); GLES20.GlVertexAttribPointer( mPositionAttribute, COORDS_PER_VERTEX, GLES20.GlFloat, false, 0, mVerticesBaseAddress); GLES20.GlVertexAttribPointer( mNormalAttribute, 3, GLES20.GlFloat, false, 0, mNormalsBaseAddress); GLES20.GlVertexAttribPointer( mTexCoordAttribute, 2, GLES20.GlFloat, false, 0, mTexCoordsBaseAddress); GLES20.GlBindBuffer(GLES20.GlArrayBuffer, 0); // Set the ModelViewProjection matrix in the shader. GLES20.GlUniformMatrix4fv( mModelViewUniform, 1, false, mModelViewMatrix, 0); GLES20.GlUniformMatrix4fv( mModelViewProjectionUniform, 1, false, mModelViewProjectionMatrix, 0); // Enable vertex arrays GLES20.GlEnableVertexAttribArray(mPositionAttribute); GLES20.GlEnableVertexAttribArray(mNormalAttribute); GLES20.GlEnableVertexAttribArray(mTexCoordAttribute); if (mBlendMode != BlendMode.Null) { GLES20.GlDepthMask(false); GLES20.GlEnable(GLES20.GlBlend); switch (mBlendMode) { case BlendMode.Shadow: // Multiplicative blending function for Shadow. GLES20.GlBlendFunc(GLES20.GlZero, GLES20.GlOneMinusSrcAlpha); break; case BlendMode.Grid: // Grid, additive blending function. GLES20.GlBlendFunc(GLES20.GlSrcAlpha, GLES20.GlOneMinusSrcAlpha); break; } } GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, mIndexBufferId); GLES20.GlDrawElements(GLES20.GlTriangles, mIndexCount, GLES20.GlUnsignedShort, 0); GLES20.GlBindBuffer(GLES20.GlElementArrayBuffer, 0); if (mBlendMode != BlendMode.Null) { GLES20.GlDisable(GLES20.GlBlend); GLES20.GlDepthMask(true); } // Disable vertex arrays GLES20.GlDisableVertexAttribArray(mPositionAttribute); GLES20.GlDisableVertexAttribArray(mNormalAttribute); GLES20.GlDisableVertexAttribArray(mTexCoordAttribute); GLES20.GlBindTexture(GLES20.GlTexture2d, 0); ShaderUtil.CheckGLError(TAG, "After draw"); }