/**
         * Draws a frame for an eye.
         *
         * @param eye The eye to render. Includes all required transformations.
         */
        public void OnDrawEye(Eye eye)
        {
            GLES20.GlEnable(GLES20.GlDepthTest);
            GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit);

            CheckGLError("colorParam");

            // Apply the eye transformation to the camera.
            Matrix.MultiplyMM(view, 0, eye.GetEyeView(), 0, camera, 0);

            // Set the position of the light
            Matrix.MultiplyMV(lightPosInEyeSpace, 0, view, 0, LIGHT_POS_IN_WORLD_SPACE, 0);

            // Build the ModelView and ModelViewProjection matrices
            // for calculating cube position and light.
            float [] perspective = eye.GetPerspective(Z_NEAR, Z_FAR);
            Matrix.MultiplyMM(modelView, 0, view, 0, modelCube, 0);
            Matrix.MultiplyMM(modelViewProjection, 0, perspective, 0, modelView, 0);

            DrawCube();

            // Set modelView for the floor, so we draw floor in the correct location
            Matrix.MultiplyMM(modelView, 0, view, 0, modelFloor, 0);
            Matrix.MultiplyMM(modelViewProjection, 0, perspective, 0, modelView, 0);

            DrawFloor();
        }
Esempio n. 2
0
        public void Draw(float[] eyeView, float[] perspective)
        {
            GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit);

            positionParam = GLES20.GlGetAttribLocation(glProgram, "a_Position");
            normalParam   = GLES20.GlGetAttribLocation(glProgram, "a_Normal");
            colorParam    = GLES20.GlGetAttribLocation(glProgram, "a_Color");
            texCoordParam = GLES20.GlGetAttribLocation(glProgram, "a_texcoord");

            GLES20.GlEnableVertexAttribArray(positionParam);
            GLES20.GlEnableVertexAttribArray(normalParam);
            GLES20.GlEnableVertexAttribArray(texCoordParam);

            // Apply the eye transformation to the camera.
            Matrix.MultiplyMM(view, 0, eyeView, 0, camera, 0);

            // Set the position of the light
            Matrix.MultiplyMV(lightPosInEyeSpace, 0, view, 0, lightPosInWorldSpace, 0);
            GLES20.GlUniform3f(lightPosParam, lightPosInEyeSpace[0], lightPosInEyeSpace[1],
                               lightPosInEyeSpace[2]);

            // Build the ModelView and ModelViewProjection matrices
            // for calculating cube position and light.
            Matrix.MultiplyMM(modelView, 0, view, 0, modelCube, 0);
            Matrix.MultiplyMM(modelViewProjection, 0, perspective, 0, modelView, 0);
            DrawCube();

            // Set mModelView for the floor, so we draw floor in the correct location
            Matrix.MultiplyMM(modelView, 0, view, 0, modelFloor, 0);
            Matrix.MultiplyMM(modelViewProjection, 0, perspective, 0,
                              modelView, 0);
            DrawFloor(perspective);
        }
Esempio n. 3
0
        public void OnDrawFrame(IGL10 gl)
        {
            if (Width == 0 || Height == 0)
            {
                return;
            }

            SystemTime.Tick();
            var rightNow = SystemTime.Now;

            step = (now == 0 ? 0 : rightNow - now);
            now  = rightNow;

            if (step <= 0)
            {
                return;
            }

            Step();

            NoosaScript.Get().ResetCamera();
            GLES20.GlScissor(0, 0, Width, Height);
            GLES20.GlClear(GLES20.GlColorBufferBit);
            Draw();
        }
        public void OnDrawFrame(Javax.Microedition.Khronos.Opengles.IGL10 gl)
        {
            // Draw background color
            GLES20.GlClear((int)GLES20.GlColorBufferBit);

            // Set the camera position (View matrix)
            Matrix.SetLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

            // Calculate the projection and view transformation
            Matrix.MultiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0);

            // Draw square
            mSquare.Draw(mMVPMatrix);

            // Create a rotation for the triangle
            // long time = SystemClock.UptimeMillis() % 4000L;
            // float angle = 0.090f * ((int) time);
            Matrix.SetRotateM(mRotationMatrix, 0, Angle, 0, 0, -1.0f);

            // Combine the rotation matrix with the projection and camera view
            Matrix.MultiplyMM(mMVPMatrix, 0, mRotationMatrix, 0, mMVPMatrix, 0);

            // Draw triangle
            mTriangle.Draw(mMVPMatrix);
        }
Esempio n. 5
0
 void GLSurfaceView.IRenderer.OnDrawFrame(Javax.Microedition.Khronos.Opengles.IGL10 gl)
 {
     GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit);
     mGrid.draw(mViewMatrix, mProjectionMatrix);
     mPointCloud.draw(mViewMatrix, mProjectionMatrix);
     mCameraFrustumAndAxis.draw(mViewMatrix, mProjectionMatrix);
 }
Esempio n. 6
0
 public void OnDrawFrame(IGL10 gl)
 {
     GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit);
     mTrajectory.draw(ViewMatrix, mProjectionMatrix);
     mFloorGrid.draw(ViewMatrix, mProjectionMatrix);
     mCameraFrustumAndAxis.draw(ViewMatrix, mProjectionMatrix);
 }
Esempio n. 7
0
            public void OnSurfaceChanged(IGL10 gl, int width, int height)
            {
                if (mShuttingDown)
                {
                    return;
                }

                ScreenParams screen = mHmd.getScreen();

                if ((width != screen.getWidth()) || (height != screen.getHeight()))
                {
                    if (!mInvalidSurfaceSize)
                    {
                        GLES20.GlClear(GLES20.GlColorBufferBit);
                        Android.Util.Log.Warn("CardboardView", "Surface size " + width + "x" + height + " does not match the expected screen size " + screen.getWidth() + "x" + screen.getHeight() + ". Rendering is disabled.");
                    }

                    mInvalidSurfaceSize = true;
                }
                else
                {
                    mInvalidSurfaceSize = false;
                }

                mRenderer.OnSurfaceChanged(width, height);
            }
Esempio n. 8
0
        public override void OnDrawFrame(IGL10 gl)
        {
            GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit);


            base.OnDrawFrame(gl);
        }
Esempio n. 9
0
        public override void OnDrawFrame(IGL10 gl)
        {
            GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit);
            base.OnDrawFrame(gl);

            cube.angleX = this.angleX;
            cube.angleY = this.angleY;
        }
Esempio n. 10
0
        void GLSurfaceView.IRenderer.OnDrawFrame(IGL10 gl)
        {
            GLES20.GlClear(GLES20.GlDepthBufferBit | GLES20.GlColorBufferBit);

            Matrix.SetIdentityM(mModelMatrix, 0);
            Matrix.RotateM(mModelMatrix, 0, 60, 0.0f, 0.0f, 1.0f);
            DrawTriangle(mTriangle1Vertices);
        }
Esempio n. 11
0
        public void OnDrawFrame(IGL10 unused)
        {
            // Draw background color
            GLES20.GlClear(GLES20.GL_COLOR_BUFFER_BIT);

            // Draw triangle
            mTriangle.Draw();
        }
Esempio n. 12
0
        public void OnDrawFrame(IGL10 gl)
        {
            GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit);

            if (mSession == null)
            {
                return;
            }
            if (mDisplayRotationManager.GetDeviceRotation())
            {
                mDisplayRotationManager.UpdateArSessionDisplayGeometry(mSession);
            }

            try {
                mSession.SetCameraTextureName(mTextureDisplay.GetExternalTextureId());
                ARFrame  arFrame  = mSession.Update();
                ARCamera arCamera = arFrame.Camera;

                // The size of the projection matrix is 4 * 4.
                float[] projectionMatrix = new float[16];

                arCamera.GetProjectionMatrix(projectionMatrix, PROJ_MATRIX_OFFSET, PROJ_MATRIX_NEAR, PROJ_MATRIX_FAR);
                mTextureDisplay.OnDrawFrame(arFrame);
                StringBuilder sb = new StringBuilder();
                UpdateMessageData(sb);
                mTextDisplay.OnDrawFrame(sb);

                // The size of ViewMatrix is 4 * 4.
                float[] viewMatrix = new float[16];
                arCamera.GetViewMatrix(viewMatrix, 0);
                var allTrackables = mSession.GetAllTrackables(Java.Lang.Class.FromType(typeof(ARPlane)));

                foreach (ARPlane plane in allTrackables)
                {
                    if (plane.Type != ARPlane.PlaneType.UnknownFacing &&
                        plane.TrackingState == ARTrackableTrackingState.Tracking)
                    {
                        HideLoadingMessage();
                        break;
                    }
                }
                mLabelDisplay.OnDrawFrame(allTrackables, arCamera.DisplayOrientedPose,
                                          projectionMatrix);
                HandleGestureEvent(arFrame, arCamera, projectionMatrix, viewMatrix);
                ARLightEstimate lightEstimate       = arFrame.LightEstimate;
                float           lightPixelIntensity = 1;
                if (lightEstimate.GetState() != ARLightEstimate.State.NotValid)
                {
                    lightPixelIntensity = lightEstimate.PixelIntensity;
                }
                DrawAllObjects(projectionMatrix, viewMatrix, lightPixelIntensity);
            } catch (ArDemoRuntimeException e) {
                Log.Info(TAG, "Exception on the ArDemoRuntimeException!");
            } catch (Exception t) {
                // This prevents the app from crashing due to unhandled exceptions.
                Log.Info(TAG, "Exception on the OpenGL thread: " + t.Message);
            }
        }
Esempio n. 13
0
        public void OnDrawFrame(IGL10 gl)
        {
            // Clear the color buffer and notify the driver not to load the data of the previous frame.
            GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit);

            if (mSession == null)
            {
                return;
            }
            if (mDisplayRotationManager.GetDeviceRotation())
            {
                mDisplayRotationManager.UpdateArSessionDisplayGeometry(mSession);
            }

            try
            {
                mSession.SetCameraTextureName(mTextureDisplay.GetExternalTextureId());
                ARFrame  arFrame  = mSession.Update();
                ARCamera arCamera = arFrame.Camera;

                // The size of the projection matrix is 4 * 4.
                float[] projectionMatrix = new float[16];

                // Obtain the projection matrix through ARCamera.
                arCamera.GetProjectionMatrix(projectionMatrix, PROJECTION_MATRIX_OFFSET, PROJECTION_MATRIX_NEAR,
                                             PROJECTION_MATRIX_FAR);
                mTextureDisplay.OnDrawFrame(arFrame);
                ICollection hands = mSession.GetAllTrackables(Java.Lang.Class.FromType(typeof(ARHand)));
                if (hands.Count == 0)
                {
                    mTextDisplay.OnDrawFrame(null);
                    return;
                }
                foreach (ARHand hand in hands)
                {
                    // Update the hand recognition information to be displayed on the screen.
                    StringBuilder sb = new StringBuilder();
                    UpdateMessageData(sb, hand);

                    // Display hand recognition information on the screen.
                    mTextDisplay.OnDrawFrame(sb);
                }
                foreach (HandRelatedDisplay handRelatedDisplay in mHandRelatedDisplays)
                {
                    handRelatedDisplay.OnDrawFrame(hands, projectionMatrix);
                }
            }
            catch (ArDemoRuntimeException e)
            {
                Log.Info(TAG, "Exception on the ArDemoRuntimeException!");
            }
            catch (Exception t)
            {
                // This prevents the app from crashing due to unhandled exceptions.
                Log.Info(TAG, "Exception on the OpenGL thread " + t.Message);
            }
        }
Esempio n. 14
0
        public void OnDrawFrame(Javax.Microedition.Khronos.Opengles.IGL10 gl)
        {
            float[] scratch = new float[16];

            // Draw background color
            GLES20.GlClear(GLES20.GlColorBufferBit);

            //synchronized (this) {
            if (mUpdateST)
            {
                mSTexture.UpdateTexImage();
                mUpdateST = false;
            }
            //}

            GLES20.GlUseProgram(hProgram);

            int ph  = GLES20.GlGetAttribLocation(hProgram, "vPosition");
            int tch = GLES20.GlGetAttribLocation(hProgram, "vTexCoord");
            int th  = GLES20.GlGetUniformLocation(hProgram, "sTexture");

            GLES20.GlActiveTexture(GLES20.GlTexture0);
            GLES20.GlBindTexture(GLES11Ext.GlTextureExternalOes, hTex[0]);
            GLES20.GlUniform1i(th, 0);

            GLES20.GlVertexAttribPointer(ph, 2, GLES20.GlFloat, false, 4 * 2, pVertex);
            GLES20.GlVertexAttribPointer(tch, 2, GLES20.GlFloat, false, 4 * 2, pTexCoord);
            GLES20.GlEnableVertexAttribArray(ph);
            GLES20.GlEnableVertexAttribArray(tch);

            GLES20.GlDrawArrays(GLES20.GlTriangleStrip, 0, 4);


            // Set the camera position (View matrix)
            Android.Opengl.Matrix.SetLookAtM(mViewMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f);

            // Calculate the projection and view transformation
            Android.Opengl.Matrix.MultiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);


            // Create a rotation for the triangle

            // Use the following code to generate constant rotation.
            // Leave this code out when using TouchEvents.
            // long time = SystemClock.uptimeMillis() % 4000L;
            // float angle = 0.090f * ((int) time);

            Android.Opengl.Matrix.SetRotateM(mRotationMatrix, 0, mAngle, 0, 0, 1.0f);

            // Combine the rotation matrix with the projection and camera view
            // Note that the mMVPMatrix factor *must be first* in order
            // for the matrix multiplication product to be correct.
            Android.Opengl.Matrix.MultiplyMM(scratch, 0, mMVPMatrix, 0, mRotationMatrix, 0);

            // Draw triangle
            mTriangle.draw(scratch);
        }
Esempio n. 15
0
        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
        }
Esempio n. 16
0
        public void OnDrawFrame(IGL10 gl)
        {
            GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit);

            // Draw the triangle facing straight on.
            angleInDegrees += 1.0f;
            float[] mModelMatrix = new float[16];
            Matrix.SetIdentityM(mModelMatrix, 0);

            Matrix.RotateM(mModelMatrix, 0, angleInDegrees, 0.0f, 0.0f, 1.0f);
            //  Matrix.ScaleM(mModelMatrix, 0, angleInDegrees / 1000.0f, 1.0f, 1.0f);
            //  Matrix.TranslateM(mModelMatrix, 0, angleInDegrees / 1000.0f, angleInDegrees / 1000.0f, 0.0f);

            // Pass in the position information
            mTriangle1Vertices.Position(mPositionOffset);
            GLES20.GlVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GlFloat, false, mStrideBytes, mTriangle1Vertices);
            GLES20.GlEnableVertexAttribArray(mPositionHandle);

            // Pass in the color information
            mTriangle1Vertices.Position(mColorOffset);
            GLES20.GlVertexAttribPointer(mColorHandle, mColorDataSize, GLES20.GlFloat, false, mStrideBytes, mTriangle1Vertices);
            GLES20.GlEnableVertexAttribArray(mColorHandle);

            // 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 < 10; y++)
            {
                for (int x = 0; x < 10; x++)
                {
                    Matrix.SetIdentityM(mModelMatrix, 0);
                    Matrix.ScaleM(mModelMatrix, 0, 0.1f, 0.1f, 0.1f);
                    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);
                }
            }
        }
        public void OnDrawFrame(IGL10 gl)
        {
            GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit);

            if (mArSession == null)
            {
                return;
            }
            if (mDisplayRotationManager.GetDeviceRotation())
            {
                mDisplayRotationManager.UpdateArSessionDisplayGeometry(mArSession);
            }

            try
            {
                mArSession.SetCameraTextureName(mTextureDisplay.GetExternalTextureId());
                ARFrame frame = mArSession.Update();
                mTextureDisplay.OnDrawFrame(frame);
                float fpsResult = DoFpsCalculate();

                System.Collections.ICollection faces = (System.Collections.ICollection)mArSession.GetAllTrackables(Java.Lang.Class.FromType(typeof(ARFace)));

                if (faces.Count == 0)
                {
                    mTextDisplay.OnDrawFrame(null);
                    return;
                }
                Log.Debug(TAG, "Face number: " + faces.Count);
                ARCamera camera = frame.Camera;
                foreach (ARFace face in faces)
                {
                    if (face.TrackingState == ARTrackableTrackingState.Tracking)
                    {
                        mFaceGeometryDisplay.OnDrawFrame(camera, face);
                        StringBuilder sb = new StringBuilder();
                        UpdateMessageData(sb, fpsResult, face);
                        mTextDisplay.OnDrawFrame(sb);
                    }
                }
            }
            catch (ArDemoRuntimeException e)
            {
                Log.Debug(TAG, "Exception on the ArDemoRuntimeException!");
            }
            catch (Throwable t)
            {
                // This prevents the app from crashing due to unhandled exceptions.
                Log.Debug(TAG, "Exception on the OpenGL thread", t);
            }
        }
Esempio n. 18
0
        public void OnDrawFrame(IGL10 gl)
        {
            // Move
            ShellViewModel.Animate();

            mLightDir[0] = -0.5f; mLightDir[1] = -1.0f; mLightDir[2] = -0.5f;                   // in left-handed region
            Vector.normalize(mLightDir);

            mRT["screen"].switchTargetFrameBuffer();
            GLES20.GlClear(GL10.GlColorBufferBit | GL10.GlDepthBufferBit);

            ////////////////////////////////////////////////////////////////////
            //// draw models
            ShellViewModel.LockWith(() => {
                foreach (var shell in ShellViewModel.Shells)
                {
                    if (shell.Loaded)
                    {
                        foreach (var rs in shell.RenderSets)
                        {
                            mRT[rs.target].switchTargetFrameBuffer();
                            GLSL glsl = mGLSL[rs.shader];

                            GLES20.GlUseProgram(glsl.mProgram);

                            // Projection Matrix
                            GLES20.GlUniformMatrix4fv(glsl.muPMatrix, 1, false, ShellViewModel.ProjectionMatrix, 0);

                            // LightPosition
                            GLES20.GlUniform3fv(glsl.muLightDir, 1, mLightDir, 0);

                            bindBuffer(shell.Surface, glsl);
                            if (!rs.shader.EndsWith("alpha"))
                            {
                                drawNonAlpha(shell.Surface, glsl);
                                drawAlpha(shell.Surface, glsl, false);
                            }
                            else
                            {
                                drawAlpha(shell.Surface, glsl, true);
                            }
                        }
                    }
                }
            });

            GLES20.GlFlush();
            checkGlError(TAG);
        }
        public void OnDrawFrame(IGL10 gl)
        {
            GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit | GLES20.GlStencilBufferBit);

            // create the contexts if not done already
            if (context == null)
            {
                var glInterface = GRGlInterface.CreateNativeGlInterface();
                context = GRContext.Create(GRBackend.OpenGL, glInterface);
            }

            // manage the drawing surface
            if (renderTarget == null || surface == null || renderTarget.Width != surfaceWidth || renderTarget.Height != surfaceHeight)
            {
                // create or update the dimensions
                renderTarget?.Dispose();
                var buffer = new int[3];
                GLES20.GlGetIntegerv(GLES20.GlFramebufferBinding, buffer, 0);
                GLES20.GlGetIntegerv(GLES20.GlStencilBits, buffer, 1);
                GLES20.GlGetIntegerv(GLES20.GlSamples, buffer, 2);
                var samples    = buffer[2];
                var maxSamples = context.GetMaxSurfaceSampleCount(colorType);
                if (samples > maxSamples)
                {
                    samples = maxSamples;
                }
                var glInfo = new GRGlFramebufferInfo((uint)buffer[0], colorType.ToGlSizedFormat());
                renderTarget = new GRBackendRenderTarget(surfaceWidth, surfaceHeight, samples, buffer[1], glInfo);

                // create the surface
                surface?.Dispose();
                surface = SKSurface.Create(context, renderTarget, surfaceOrigin, colorType);
            }

            using (new SKAutoCanvasRestore(surface.Canvas, true))
            {
                // start drawing
                var e = new SKPaintGLSurfaceEventArgs(surface, renderTarget, surfaceOrigin, colorType);
                OnPaintSurface(e);
#pragma warning disable CS0618 // Type or member is obsolete
                OnDrawFrame(e.Surface, e.RenderTarget);
#pragma warning restore CS0618 // Type or member is obsolete
            }

            // flush the SkiaSharp contents to GL
            surface.Canvas.Flush();
            context.Flush();
        }
Esempio n. 20
0
        public void OnDrawFrame(IGL10 unused)
        {
            GLES20.GlClear(GLES20.GlColorBufferBit);
            drawRectangle(yuvTextures[1], remoteVertices);
            drawRectangle(yuvTextures[0], localVertices);
            ++numFramesSinceLastLog;
            long now = JavaSystem.NanoTime();

            if (lastFPSLogTime == -1 || now - lastFPSLogTime > 1e9)
            {
                double fps = numFramesSinceLastLog / ((now - lastFPSLogTime) / 1e9);
                Log.Debug(TAG, "Rendered FPS: " + fps);
                lastFPSLogTime        = now;
                numFramesSinceLastLog = 1;
            }
            checkNoGLES2Error();
        }
        private void Render(float[] matrix)
        {
            // clear Screen and Depth Buffer, we have set the clear color as black.
            GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit);

            // get handle to vertex shader's vPosition member
            int positionHandle = GLES20.GlGetAttribLocation(ShaderHelper.SpImage, "vPosition");

            // Enable generic vertex attribute array
            GLES20.GlEnableVertexAttribArray(positionHandle);

            // Prepare the triangle coordinate data
            GLES20.GlVertexAttribPointer(positionHandle, 3,
                                         GLES20.GlFloat, false,
                                         0, vertexBuffer);

            // Get handle to texture coordinates location
            int textureCoordinatesLocation = GLES20.GlGetAttribLocation(ShaderHelper.SpImage, "a_texCoord");

            // Enable generic vertex attribute array
            GLES20.GlEnableVertexAttribArray(textureCoordinatesLocation);

            // Prepare the texturecoordinates
            GLES20.GlVertexAttribPointer(textureCoordinatesLocation, 2, GLES20.GlFloat, false, 0, uvBuffer);

            // Get handle to shape's transformation matrix
            int matrixhandle = GLES20.GlGetUniformLocation(ShaderHelper.SpImage, "uMVPMatrix");

            // Apply the projection and view transformation
            GLES20.GlUniformMatrix4fv(matrixhandle, 1, false, matrix, 0);

            // Get handle to textures locations
            int samplerLocation = GLES20.GlGetUniformLocation(ShaderHelper.SpImage, "s_texture");

            // Set the sampler texture unit to 0, where we have saved the texture.
            GLES20.GlUniform1i(samplerLocation, 0);

            // Draw the triangle
            GLES20.GlDrawElements(GLES20.GlTriangles, indices.Length,
                                  GLES20.GlUnsignedShort, drawListBuffer);

            // Disable vertex array
            GLES20.GlDisableVertexAttribArray(positionHandle);
            GLES20.GlDisableVertexAttribArray(textureCoordinatesLocation);
        }
Esempio n. 22
0
        /// <summary>
        /// This method will clear the surface view from its last rendered pixels.
        /// This is used to avoid seeing the previous video rendering when setting
        /// a video source to null.
        /// </summary>
        internal void Clear()
        {
#pragma warning disable 618
            // The solution is as described here:
            // https://stackoverflow.com/questions/25660994/clear-video-frame-from-surfaceview-on-video-complete
            if (Holder?.Surface == null)
            {
                return;
            }

            var egl     = Javax.Microedition.Khronos.Egl.EGLContext.EGL.JavaCast <IEGL10>();
            var display = egl.EglGetDisplay(EGL10.EglDefaultDisplay);
            egl.EglInitialize(display, null);

            int[] attribList =
            {
                EGL10.EglRedSize,                         8,
                EGL10.EglGreenSize,                       8,
                EGL10.EglBlueSize,                        8,
                EGL10.EglAlphaSize,                       8,
                EGL10.EglRenderableType, EGL10.EglWindowBit,
                EGL10.EglNone,                            0, // placeholder for recordable [@-3]
                EGL10.EglNone
            };

            var configs    = new Javax.Microedition.Khronos.Egl.EGLConfig[1];
            var numConfigs = new int[1];

            egl.EglChooseConfig(display, attribList, configs, configs.Length, numConfigs);
            var config  = configs[0];
            var context = egl.EglCreateContext(display, config, EGL10.EglNoContext, new int[] { 12440, 2, EGL10.EglNone });

            var eglSurface = egl.EglCreateWindowSurface(display, config, Holder.Surface, new int[] { EGL10.EglNone });

            egl.EglMakeCurrent(display, eglSurface, eglSurface, context);
            GLES20.GlClearColor(0, 0, 0, 1);
            GLES20.GlClear(GLES20.GlColorBufferBit);
            egl.EglSwapBuffers(display, eglSurface);
            egl.EglDestroySurface(display, eglSurface);
            egl.EglMakeCurrent(display, EGL10.EglNoSurface, EGL10.EglNoSurface, EGL10.EglNoContext);
            egl.EglDestroyContext(display, context);
            egl.EglTerminate(display);
#pragma warning restore 618
        }
Esempio n. 23
0
            /**
             * Draws the external texture in SurfaceTexture onto the current EGL surface.
             */
            public void drawFrame(SurfaceTexture st, bool invert)
            {
                checkGlError("onDrawFrame start");
                st.GetTransformMatrix(mSTMatrix);
                if (invert)
                {
                    mSTMatrix[5]  = -mSTMatrix[5];
                    mSTMatrix[13] = 1.0f - mSTMatrix[13];
                }

                // (optional) clear to green so we can see if we're failing to set pixels
                GLES20.GlClearColor(0.0f, 1.0f, 0.0f, 1.0f);
                GLES20.GlClear(GLES20.GlColorBufferBit);

                GLES20.GlUseProgram(mProgram);
                checkGlError("glUseProgram");

                GLES20.GlActiveTexture(GLES20.GlTexture0);
                GLES20.GlBindTexture(GLES11Ext.GlTextureExternalOes, mTextureID);

                mTriangleVertices.Position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
                GLES20.GlVertexAttribPointer(maPositionHandle, 3, GLES20.GlFloat, false,
                                             TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
                checkGlError("glVertexAttribPointer maPosition");
                GLES20.GlEnableVertexAttribArray(maPositionHandle);
                checkGlError("glEnableVertexAttribArray maPositionHandle");

                mTriangleVertices.Position(TRIANGLE_VERTICES_DATA_UV_OFFSET);
                GLES20.GlVertexAttribPointer(maTextureHandle, 2, GLES20.GlFloat, false,
                                             TRIANGLE_VERTICES_DATA_STRIDE_BYTES, mTriangleVertices);
                checkGlError("glVertexAttribPointer maTextureHandle");
                GLES20.GlEnableVertexAttribArray(maTextureHandle);
                checkGlError("glEnableVertexAttribArray maTextureHandle");

                Android.Opengl.Matrix.SetIdentityM(mMVPMatrix, 0);
                GLES20.GlUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0);
                GLES20.GlUniformMatrix4fv(muSTMatrixHandle, 1, false, mSTMatrix, 0);

                GLES20.GlDrawArrays(GLES20.GlTriangleStrip, 0, 4);
                checkGlError("glDrawArrays");

                GLES20.GlBindTexture(GLES11Ext.GlTextureExternalOes, 0);
            }
Esempio n. 24
0
        public void OnDrawFrame(IGL10 gl)
        {
            GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit);
            // Draw the triangle facing straight on.
            angleInDegrees += 0.1f;
            lb             += 0.0001f;
            if (lb > 0.05f)
            {
                lb = 0.001f;
            }

            for (int x = -2; x < 3; x++)
            {
                for (int z = -2; z < 3; z++)
                {
                    DrawObject(x * 10.0f, 0.0f, z * 10.0f);
                }
            }
        }
        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));
        }
        public void RenderTexture(int texId)
        {
            try
            {
                // Bind default FBO
                GLES20.GlBindFramebuffer(GLES20.GlFramebuffer, 0);

                // Use our shader program
                GLES20.GlUseProgram(MProgram);
                GlToolbox.CheckGlError("glUseProgram");

                // Set viewport
                GLES20.GlViewport(0, 0, MViewWidth, MViewHeight);
                GlToolbox.CheckGlError("glViewport");

                // Disable blending
                GLES20.GlDisable(GLES20.GlBlend);

                // Set the vertex attributes
                GLES20.GlVertexAttribPointer(MTexCoordHandle, 2, GLES20.GlFloat, false, 0, MTexVertices);
                GLES20.GlEnableVertexAttribArray(MTexCoordHandle);
                GLES20.GlVertexAttribPointer(MPosCoordHandle, 2, GLES20.GlFloat, false, 0, MPosVertices);
                GLES20.GlEnableVertexAttribArray(MPosCoordHandle);
                GlToolbox.CheckGlError("vertex attribute setup");

                // Set the input texture
                GLES20.GlActiveTexture(GLES20.GlTexture0);
                GlToolbox.CheckGlError("glActiveTexture");
                GLES20.GlBindTexture(GLES20.GlTexture2d, texId);
                GlToolbox.CheckGlError("glBindTexture");
                GLES20.GlUniform1i(MTexSamplerHandle, 0);

                // Draw
                GLES20.GlClearColor(0.0f, 0.0f, 0.0f, 1.0f);
                GLES20.GlClear(GLES20.GlColorBufferBit);
                GLES20.GlDrawArrays(GLES20.GlTriangleStrip, 0, 4);
            }
            catch (Exception e)
            {
                Methods.DisplayReportResultTrack(e);
            }
        }
        /**
         * Generates a frame of data using GL commands.
         * <p>
         * We have an 8-frame animation sequence that wraps around. It looks like this:
         * <pre>
         * 0 1 2 3
         * 7 6 5 4
         * </pre>
         * We draw one of the eight rectangles and leave the rest set to the zero-fill color. */
        private void generateSurfaceFrame(int frameIndex)
        {
            frameIndex %= 8;
            int startX, startY;

            if (frameIndex < 4)
            {
                // (0,0) is bottom-left in GL
                startX = frameIndex * (mWidth / 4);
                startY = mHeight / 2;
            }
            else
            {
                startX = (7 - frameIndex) * (mWidth / 4);
                startY = 0;
            }
            GLES20.GlDisable(GLES20.GlScissorTest);
            GLES20.GlClearColor(TEST_R0 / 255.0f, TEST_G0 / 255.0f, TEST_B0 / 255.0f, 1.0f);
            GLES20.GlClear(GLES20.GlColorBufferBit);
            GLES20.GlEnable(GLES20.GlScissorTest);
            GLES20.GlScissor(startX, startY, mWidth / 4, mHeight / 2);
            GLES20.GlClearColor(TEST_R1 / 255.0f, TEST_G1 / 255.0f, TEST_B1 / 255.0f, 1.0f);
            GLES20.GlClear(GLES20.GlColorBufferBit);
        }
Esempio n. 28
0
        public void OnDrawFrame(IGL10 gl)
        {
            // Clear screen to notify driver it should not load any pixels from previous frame.
            GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit);

            if (mSession == null)
            {
                return;
            }

            // Notify ARCore session that the view size changed so that the perspective matrix and the video background
            // can be properly adjusted
            mDisplayRotationHelper.UpdateSessionIfNeeded(mSession);

            try
            {
                // Obtain the current frame from ARSession. When the configuration is set to
                // UpdateMode.BLOCKING (it is by default), this will throttle the rendering to the
                // camera framerate.
                Frame  frame  = mSession.Update();
                Camera camera = frame.Camera;

                // Handle taps. Handling only one tap per frame, as taps are usually low frequency
                // compared to frame rate.
                MotionEvent tap = null;
                mQueuedSingleTaps.TryDequeue(out tap);

                if (tap != null && camera.TrackingState == TrackingState.Tracking)
                {
                    foreach (var hit in frame.HitTest(tap))
                    {
                        var trackable = hit.Trackable;

                        // Check if any plane was hit, and if it was hit inside the plane polygon.
                        if (trackable is Plane && ((Plane)trackable).IsPoseInPolygon(hit.HitPose))
                        {
                            // Cap the number of objects created. This avoids overloading both the
                            // rendering system and ARCore.
                            if (mAnchors.Count >= 16)
                            {
                                mAnchors[0].Detach();
                                mAnchors.RemoveAt(0);
                            }
                            // Adding an Anchor tells ARCore that it should track this position in
                            // space.  This anchor is created on the Plane to place the 3d model
                            // in the correct position relative to both the world and to the plane
                            mAnchors.Add(hit.CreateAnchor());

                            // Hits are sorted by depth. Consider only closest hit on a plane.
                            break;
                        }
                    }
                }

                // Draw background.
                mBackgroundRenderer.Draw(frame);

                // If not tracking, don't draw 3d objects.
                if (camera.TrackingState == TrackingState.Paused)
                {
                    return;
                }

                // Get projection matrix.
                float[] projmtx = new float[16];
                camera.GetProjectionMatrix(projmtx, 0, 0.1f, 100.0f);

                // Get camera matrix and draw.
                float[] viewmtx = new float[16];
                camera.GetViewMatrix(viewmtx, 0);

                // Compute lighting from average intensity of the image.
                var lightIntensity = frame.LightEstimate.PixelIntensity;

                // Visualize tracked points.
                var pointCloud = frame.AcquirePointCloud();
                mPointCloud.Update(pointCloud);
                mPointCloud.Draw(camera.DisplayOrientedPose, viewmtx, projmtx);

                // App is repsonsible for releasing point cloud resources after using it
                pointCloud.Release();

                var planes = new List <Plane>();
                foreach (var p in mSession.GetAllTrackables(Java.Lang.Class.FromType(typeof(Plane))))
                {
                    var plane = (Plane)p;
                    planes.Add(plane);
                }

                // Check if we detected at least one plane. If so, hide the loading message.
                if (mLoadingMessageSnackbar != null)
                {
                    foreach (var plane in planes)
                    {
                        if (plane.GetType() == Plane.Type.HorizontalUpwardFacing &&
                            plane.TrackingState == TrackingState.Tracking)
                        {
                            hideLoadingMessage();
                            break;
                        }
                    }
                }

                // Visualize planes.
                mPlaneRenderer.DrawPlanes(planes, camera.DisplayOrientedPose, projmtx);

                // Visualize anchors created by touch.
                float scaleFactor = 1.0f;
                foreach (var anchor in mAnchors)
                {
                    if (anchor.TrackingState != TrackingState.Tracking)
                    {
                        continue;
                    }

                    // Get the current combined pose of an Anchor and Plane in world space. The Anchor
                    // and Plane poses are updated during calls to session.update() as ARCore refines
                    // its estimate of the world.
                    anchor.Pose.ToMatrix(mAnchorMatrix, 0);

                    // Update and draw the model and its shadow.
                    mVirtualObject.updateModelMatrix(mAnchorMatrix, scaleFactor);
                    mVirtualObjectShadow.updateModelMatrix(mAnchorMatrix, scaleFactor);
                    mVirtualObject.Draw(viewmtx, projmtx, lightIntensity);
                    mVirtualObjectShadow.Draw(viewmtx, projmtx, lightIntensity);
                }
            }
            catch (System.Exception ex)
            {
                // Avoid crashing the application due to unhandled exceptions.
                Log.Error(TAG, "Exception on the OpenGL thread", ex);
            }
        }
Esempio n. 29
0
        public void OnDrawFrame(IGL10 gl)
        {
            GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit);

            // Pass in the edge position information
            mTriangle1Vertices.Position(mPositionOffset);
            GLES20.GlVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GlFloat, false, mStrideBytes, mTriangle1Vertices);
            GLES20.GlEnableVertexAttribArray(mPositionHandle);

            // Pass in the color information
            mTriangle1Vertices.Position(mColorOffset);
            GLES20.GlVertexAttribPointer(mColorHandle, mColorDataSize, GLES20.GlFloat, false, mStrideBytes, mTriangle1Vertices);
            GLES20.GlEnableVertexAttribArray(mColorHandle);

            // 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];

            // This multiplies the modelview matrix by the projection matrix, and stores the result in the MVP matrix
            // (which now contains model * view * projection).
            float[] _mMVPMatrix = new float[16];

            //Model matrix
            float[] mModelMatrix = new float[16];

            //move world forward by z
            globalWorldPosition += 0.01f; //the number value is world move speed
            //if END OF THE WORLD - reset world Z move position to ZERO and relocate ALL trees (Matrix is HAPPY NOW)
            if (globalWorldPosition > worldSpace)
            {
                globalWorldPosition = 0; //reset world move forward to start
                InitTree();              //reset trees positions
            }

            //Enumerate and draw all trees
            for (int i = 0; i < treeCount; i++)
            {
                //Draw top of tree
                Matrix.SetIdentityM(mModelMatrix, 0);
                //translate top of tree to tree postion and move to global Z (world move) coord
                Matrix.TranslateM(mModelMatrix, 0, treePostions[i, 0], 0, globalWorldPosition + treePostions[i, 1]); //tree to X <-> Z world position
                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);

                //Draw middle of tree
                Matrix.SetIdentityM(mModelMatrix, 0);
                //translate by middle section of current tree and move down by Y
                Matrix.TranslateM(mModelMatrix, 0, treePostions[i, 0], -0.5f, globalWorldPosition + treePostions[i, 1]); //move tree with all world forward by Z
                //scale middle sction
                Matrix.ScaleM(mModelMatrix, 0, 1.5f, 1.5f, 1.5f);
                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);

                //Draw bottom section of tree
                Matrix.SetIdentityM(mModelMatrix, 0);
                //translate by buttom section of current tree and move down by Y
                Matrix.TranslateM(mModelMatrix, 0, treePostions[i, 0], -1.0f, globalWorldPosition + treePostions[i, 1]); //move tree with all world forward by Z
                //scal bottom section
                Matrix.ScaleM(mModelMatrix, 0, 1.8f, 1.8f, 1.8f);
                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);
                //-> Draw next tree -->
            }
        }
Esempio n. 30
0
        public void OnDrawFrame(IGL10 gl)
        {
            GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit);

            // Draw the triangle facing straight on.
            angleInDegrees  += 1.0f;
            angleInDegrees2 -= 1.0f;

            float[] mModelMatrix = new float[16];
            Matrix.SetIdentityM(mModelMatrix, 0);

            Matrix.RotateM(mModelMatrix, 0, angleInDegrees, 0.0f, 0.0f, 1.0f);
            //  Matrix.ScaleM(mModelMatrix, 0, angleInDegrees / 1000.0f, 1.0f, 1.0f);
            //  Matrix.TranslateM(mModelMatrix, 0, angleInDegrees / 1000.0f, angleInDegrees / 1000.0f, 0.0f);

            // Pass in the position information
            mTriangle1Vertices.Position(mPositionOffset);
            GLES20.GlVertexAttribPointer(mPositionHandle, mPositionDataSize, GLES20.GlFloat, false, mStrideBytes, mTriangle1Vertices);
            GLES20.GlEnableVertexAttribArray(mPositionHandle);

            // Pass in the color information
            mTriangle1Vertices.Position(mColorOffset);
            GLES20.GlVertexAttribPointer(mColorHandle, mColorDataSize, GLES20.GlFloat, false, mStrideBytes, mTriangle1Vertices);
            GLES20.GlEnableVertexAttribArray(mColorHandle);

            // 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);
            //  Console.WriteLine(System.DateTime.Now.Ticks / System.TimeSpan.TicksPerMillisecond - milliseconds);


            if (kofi <= 0)
            {
            }
            else
            {
                kofi -= 0.001f;
            }



            Matrix.SetIdentityM(mModelMatrix, 0);
            Matrix.ScaleM(mModelMatrix, 0, 0.4f + kofi, 0.4f + kofi, 0.4f + kofi);
            Matrix.TranslateM(mModelMatrix, 0, 0.0f + kofi, 0.0f + kofi, 0.0f + kofi);
            Matrix.RotateM(mModelMatrix, 0, angleInDegrees2, 0, 0.0001F, 0);
            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);

            Matrix.SetIdentityM(mModelMatrix, 0);
            Matrix.ScaleM(mModelMatrix, 0, 0.4f - kofi, 0.4f - kofi, 0.4f - kofi);
            Matrix.TranslateM(mModelMatrix, 0, 0.0f - kofi, 0.0f - kofi, 0.0f - kofi);
            Matrix.RotateM(mModelMatrix, 0, angleInDegrees2 + 90, 0, 0.0001F, 0);
            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);



            Matrix.SetIdentityM(mModelMatrix, 0);
            Matrix.ScaleM(mModelMatrix, 0, 0.53f - kofi, 0.53f - kofi, 0.53f - kofi);
            Matrix.TranslateM(mModelMatrix, 0, 0.0f - kofi, -0.73f - kofi, 0.0f - kofi);
            Matrix.RotateM(mModelMatrix, 0, angleInDegrees, 0, 0.0001F, 0);
            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);


            Matrix.SetIdentityM(mModelMatrix, 0);
            Matrix.ScaleM(mModelMatrix, 0, 0.53f + kofi, 0.53f + kofi, 0.53f + kofi);
            Matrix.TranslateM(mModelMatrix, 0, 0.0f + kofi, -0.73f + kofi, 0.0f + kofi);
            Matrix.RotateM(mModelMatrix, 0, angleInDegrees + 90, 0, 0.0001F, 0);
            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);


            Matrix.SetIdentityM(mModelMatrix, 0);
            Matrix.ScaleM(mModelMatrix, 0, 0.66f + kofi, 0.66f + kofi, 0.66f + kofi);
            Matrix.TranslateM(mModelMatrix, 0, 0.0f + kofi, -1.32f + kofi, 0.0f + kofi);
            Matrix.RotateM(mModelMatrix, 0, angleInDegrees2, 0, 0.0001F, 0);
            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);

            Matrix.SetIdentityM(mModelMatrix, 0);
            Matrix.ScaleM(mModelMatrix, 0, 0.66f - kofi, 0.66f - kofi, 0.66f - kofi);
            Matrix.TranslateM(mModelMatrix, 0, 0.0f - kofi, -1.32f - kofi, 0.0f - kofi);
            Matrix.RotateM(mModelMatrix, 0, angleInDegrees2 + 90, 0, 0.0001F, 0);
            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);
        }