Exemple #1
0
 public void switchTargetFrameBuffer()
 {
     GLES20.GlBindFramebuffer(GLES20.GlFramebuffer, FBO);
     if (FBO == 0)
     {
         GLES20.GlViewport(0, 0, ShellViewModel.Width, ShellViewModel.Height);
     }
     else
     {
         GLES20.GlViewport(0, 0, mWidth, mHeight);
     }
 }
        private int setupRenderTextureAndRenderbuffer(int width, int height)
        {
            if (mTextureId != -1)
            {
                GLES20.GlDeleteTextures(1, new int[] { mTextureId }, 0);
            }
            if (mRenderbufferId != -1)
            {
                GLES20.GlDeleteRenderbuffers(1, new int[] { mRenderbufferId }, 0);
            }
            if (mFramebufferId != -1)
            {
                GLES20.GlDeleteFramebuffers(1, new int[] { mFramebufferId }, 0);
            }

            mTextureId = createTexture(width, height);
            checkGlError("setupRenderTextureAndRenderbuffer: create texture");

            int[] renderbufferIds = new int[1];
            GLES20.GlGenRenderbuffers(1, renderbufferIds, 0);
            GLES20.GlBindRenderbuffer(36161, renderbufferIds[0]);
            GLES20.GlRenderbufferStorage(36161, 33189, width, height);

            mRenderbufferId = renderbufferIds[0];
            checkGlError("setupRenderTextureAndRenderbuffer: create renderbuffer");

            int[] framebufferIds = new int[1];
            GLES20.GlGenFramebuffers(1, framebufferIds, 0);
            GLES20.GlBindFramebuffer(36160, framebufferIds[0]);
            mFramebufferId = framebufferIds[0];

            GLES20.GlFramebufferTexture2D(36160, 36064, 3553, mTextureId, 0);

            GLES20.GlFramebufferRenderbuffer(36160, 36096, 36161, renderbufferIds[0]);

            int status = GLES20.GlCheckFramebufferStatus(36160);

            if (status != 36053)
            {
                throw new Java.Lang.RuntimeException("Framebuffer is not complete: " + Java.Lang.Integer.ToHexString(status));
            }

            GLES20.GlBindFramebuffer(36160, 0);

            return(framebufferIds[0]);
        }
Exemple #3
0
        public void OnSurfaceCreated(IGL10 gl, EGLConfig config)
        {
            // GL configurations
            int bonenum = 48;

            GLES20.GlGetIntegerv(GLES20.GlMaxTextureSize, mTexSize, 0);
            ShellViewModel.MaxBone = bonenum;
            mNpot = hasExt("GL_OES_texture_npot");

            // initialize
            GLES20.GlClearColor(0, 0, 0, 1);
            GLES20.GlEnable(GLES20.GlDepthTest);
            GLES20.GlEnable(GLES20.GlBlend);
            checkGlError("GlEnable");

            // GLUtils.texImage2D generates premultiplied-alpha texture. so we use GL_ONE instead of GL_ALPHA
            GLES20.GlBlendFunc(GL10.GlOne, GL10.GlOneMinusSrcAlpha);
            GLES20.GlDepthFunc(GLES20.GlLequal);
            GLES20.GlFrontFace(GLES20.GlCw);
            checkGlError("GlMiscSettings");

            // shader programs
            mGLSL = new Dictionary <String, GLSL>();

            mGLSL.Add("builtin:default",
                      new GLSL(String.Format(Util.ReadAssetString("shader/vs.vsh"), ShellViewModel.MaxBone),
                               Util.ReadAssetString("shader/fs.fsh")));

            mGLSL.Add("builtin:default_alpha",
                      new GLSL(String.Format(Util.ReadAssetString("shader/vs.vsh"), ShellViewModel.MaxBone),
                               Util.ReadAssetString("shader/fs_alpha.fsh")));

            mGLSL.Add("builtin:nomotion",
                      new GLSL(Util.ReadAssetString("shader/vs_nm.vsh"), Util.ReadAssetString("shader/fs.fsh")));

            mGLSL.Add("builtin:nomotion_alpha",
                      new GLSL(Util.ReadAssetString("shader/vs_nm.vsh"), Util.ReadAssetString("shader/fs_alpha.fsh")));

            // render targets
            mRT = new Dictionary <String, RenderTarget>();
            mRT.Add("screen", new RenderTarget());

            GLES20.GlBindFramebuffer(GLES20.GlFramebuffer, 0);
        }
        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);
            }
        }
        /**
         * Initializes FBO with given parameters. Width and height are used to
         * generate textures out of which all are sized same to this FBO. If you
         * give genRenderBuffer a value 'true', depth buffer will be generated also.
         *
         * @param width
         *            FBO width in pixels
         * @param height
         *            FBO height in pixels
         * @param textureCount
         *            Number of textures to generate
         * @param genDepthBuffer
         *            If true, depth buffer is allocated for this FBO @ param
         *            genStencilBuffer If true, stencil buffer is allocated for this
         *            FBO
         */
        public void init(int width, int height, int textureCount,
                         bool textureExternalOES)
        {
            // Just in case.
            Reset();

            // Store FBO size.
            _width  = width;
            _height = height;

            // Genereta FBO.
            var handle = new int[] { 0 };

            GLES20.GlGenFramebuffers(1, handle, 0);
            _frameBufferHandle = handle[0];
            GLES20.GlBindFramebuffer(GLES20.GlFramebuffer, _frameBufferHandle);

            // Generate textures.
            _textureHandles = new int[textureCount];
            GLES20.GlGenTextures(textureCount, _textureHandles, 0);
            var target = textureExternalOES ? GLES11Ext.GlTextureExternalOes
                                : GLES20.GlTexture2d;

            foreach (var texture in _textureHandles)
            {
                GLES20.GlBindTexture(target, texture);
                GLES20.GlTexParameteri(GLES20.GlTexture2d,
                                       GLES20.GlTextureWrapS, GLES20.GlClampToEdge);
                GLES20.GlTexParameteri(target, GLES20.GlTextureWrapT,
                                       GLES20.GlClampToEdge);
                GLES20.GlTexParameteri(target, GLES20.GlTextureMinFilter,
                                       GLES20.GlNearest);
                GLES20.GlTexParameteri(target, GLES20.GlTextureMagFilter,
                                       GLES20.GlLinear);
                if (target == GLES20.GlTexture2d)
                {
                    GLES20.GlTexImage2D(GLES20.GlTexture2d, 0, GLES20.GlRgba,
                                        _width, _height, 0, GLES20.GlRgba,
                                        GLES20.GlUnsignedByte, null);
                }
            }
        }
        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));
        }
Exemple #7
0
        private void create(int width, int height)
        {
            // FBO
            int[] ret = new int[1];

            // frame buffer
            GLES20.GlGenFramebuffers(1, ret, 0);
            FBO = ret[0];
            GLES20.GlBindFramebuffer(GLES20.GlFramebuffer, FBO);

            // depth buffer
            GLES20.GlGenRenderbuffers(1, ret, 0);
            RBOD = ret[0];
            GLES20.GlBindRenderbuffer(GLES20.GlFramebuffer, RBOD);
            GLES20.GlRenderbufferStorage(GLES20.GlRenderbuffer, GLES20.GlDepthComponent16, width, height);
            GLES20.GlFramebufferRenderbuffer(GLES20.GlFramebuffer, GLES20.GlDepthAttachment, GLES20.GlRenderbuffer, RBOD);

            // color buffer (is texture)
            GLES20.GlPixelStorei(GLES20.GlUnpackAlignment, 1);
            GLES20.GlGenTextures(1, ret, 0);
            RBOC = ret[0];
            GLES20.GlBindTexture(GLES20.GlTexture2d, RBOC);
            GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureWrapS, GLES20.GlClampToEdge);
            GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureWrapT, GLES20.GlClampToEdge);
            GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureMagFilter, GLES20.GlLinear);
            GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureMinFilter, GLES20.GlLinear);
            GLES20.GlTexImage2D(GLES20.GlTexture2d, 0, GLES20.GlRgba, width, height, 0, GLES20.GlRgba, GLES20.GlUnsignedByte, null);
            GLES20.GlFramebufferTexture2D(GLES20.GlFramebuffer, GLES20.GlColorAttachment0, GLES20.GlTexture2d, RBOC, 0);

            if (GLES20.GlCheckFramebufferStatus(GLES20.GlFramebuffer) != GLES20.GlFramebufferComplete)
            {
                Log.Debug(TAG, "Fail to create FBO.");
                FBO  = 0;
                RBOD = 0;
                RBOC = 0;
            }
        }
        public void OnDrawFrame(IGL10 unused)
        {
            // Clear view.
            GLES20.GlClearColor(0.5f, 0.5f, 0.5f, 1.0f);
            GLES20.GlClear(GLES20.GlColorBufferBit);

            // If we have new preview texture.
            if (_surfaceTextureUpdate)
            {
                // Update surface texture.
                _surfaceTexture.UpdateTexImage();
                // Update texture transform matrix.
                _surfaceTexture.GetTransformMatrix(_transformM);
                _surfaceTextureUpdate = false;

                // Bind offscreen texture into use.
                _fboOffscreen.Bind();
                _fboOffscreen.BindTexture(0);

                // Take copy shader into use.
                _shaderCopyOes.UseProgram();

                // Uniform variables.
                var uOrientationM = _shaderCopyOes.GetHandle("uOrientationM");
                var uTransformM   = _shaderCopyOes.GetHandle("uTransformM");

                // We're about to transform external texture here already.
                GLES20.GlUniformMatrix4fv(uOrientationM, 1, false,
                                          _sharedData._orientationM, 0);
                GLES20.GlUniformMatrix4fv(uTransformM, 1, false, _transformM, 0);

                // We're using external OES texture as source.
                GLES20.GlActiveTexture(GLES20.GlTexture0);
                //GLES20.GlBindTexture(GLES20.GlTexture2d, mFboExternal.getTexture(0));

                // Trigger actual rendering.
                renderQuad(_shaderCopyOes.GetHandle("aPosition"));
            }
            else
            {
                System.Diagnostics.Debug.WriteLine("OK");
            }

            // Bind screen buffer into use.
            GLES20.GlBindFramebuffer(GLES20.GlFramebuffer, 0);
            GLES20.GlViewport(0, 0, _width, _height);

            // Take filter shader into use.
            _shaderFilterDefault.UseProgram();

            // Uniform variables.
            var uBrightness   = _shaderFilterDefault.GetHandle("uBrightness");
            var uContrast     = _shaderFilterDefault.GetHandle("uContrast");
            var uSaturation   = _shaderFilterDefault.GetHandle("uSaturation");
            var uCornerRadius = _shaderFilterDefault.GetHandle("uCornerRadius");

            var uAspectRatio        = _shaderFilterDefault.GetHandle("uAspectRatio");
            var uAspectRatioPreview = _shaderFilterDefault.GetHandle("uAspectRatioPreview");

            // Store uniform variables into use.
            GLES20.GlUniform1f(uBrightness, _sharedData._brightness);
            GLES20.GlUniform1f(uContrast, _sharedData._contrast);
            GLES20.GlUniform1f(uSaturation, _sharedData._saturation);
            GLES20.GlUniform1f(uCornerRadius, _sharedData._cornerRadius);

            GLES20.GlUniform2fv(uAspectRatio, 1, _aspectRatio, 0);
            GLES20.GlUniform2fv(uAspectRatioPreview, 1,
                                _sharedData._aspectRatioPreview, 0);

            // Use offscreen texture as source.
            GLES20.GlActiveTexture(GLES20.GlTexture1);
            GLES20.GlBindTexture(GLES20.GlTexture2d, _fboOffscreen.GetTexture(0));

            // Trigger actual rendering.
            renderQuad(_shaderCopyOes.GetHandle("aPosition"));
        }
Exemple #9
0
 public virtual void bind()
 {
     GLES20.GlBindFramebuffer(GLES20.GlFramebuffer, id);
 }
 /**
  * Binds this FBO into use and adjusts viewport to FBO size.
  */
 public void Bind()
 {
     GLES20.GlBindFramebuffer(GLES20.GlFramebuffer, _frameBufferHandle);
     GLES20.GlViewport(0, 0, _width, _height);
 }
Exemple #11
0
        public void OnDrawFrame(IGL10 gl)
        {
            // Clear screen to notify driver it should not load any pixels from previous frame.
            GLES20.GlBindFramebuffer(GLES20.GlFramebuffer, 0);
            GLES20.GlViewport(0, 0, glSurfaceView.Width, glSurfaceView.Height);
            GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit);

            if (arSession == null)
            {
                return;
            }

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

            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 = arSession.Update();
                Google.AR.Core.Camera camera = frame.Camera;


                // Draw background.
                GLES20.GlViewport(0, 0, glSurfaceView.Width, glSurfaceView.Height);
                backgroundRenderer.Draw(frame);

                GLES20.GlBindFramebuffer(GLES20.GlFramebuffer, fboId);
                GLES20.GlViewport(0, 0, targetResolution.Width, targetResolution.Height);
                GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit);
                backgroundRenderer.Draw(frame);
                GLES20.GlBindFramebuffer(GLES20.GlFramebuffer, 0);
                GLES20.GlViewport(0, 0, glSurfaceView.Width, glSurfaceView.Height);
                GlUtil.CheckNoGLES2Error("Switch framebuffers.");

                // Handle taps. Handling only one tap per frame, as taps are usually low frequency
                // compared to frame rate.
                MotionEvent tap = null;
                queuedSingleTaps.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 (anchors.Count >= 16)
                            {
                                anchors[0].Detach();
                                anchors.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
                            anchors.Add(hit.CreateAnchor());

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

                // 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();
                pointCloudRenderer.Update(pointCloud);

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

                var planes = new List <Plane>();
                foreach (var p in arSession.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 (loadingMessageSnackbar != null)
                {
                    foreach (var plane in planes)
                    {
                        if (plane.GetType() == Plane.Type.HorizontalUpwardFacing &&
                            plane.TrackingState == TrackingState.Tracking)
                        {
                            HideLoadingMessage();
                            break;
                        }
                    }
                }

                // Draw(frame, camera, projmtx, viewmtx, lightIntensity, planes);


                GLES20.GlBindFramebuffer(GLES20.GlFramebuffer, fboId);
                GLES20.GlViewport(0, 0, targetResolution.Width, targetResolution.Height);
                // Restore the depth state for further drawing.
                GLES20.GlDepthMask(true);
                GLES20.GlEnable(GLES20.GlDepthTest);
                // Draw(frame, camera, projmtx, viewmtx, lightIntensity, planes);
                // DrawModels(projmtx, viewmtx, lightIntensity);


                if (doCaptureCameraFrame)
                {
                    var displayOrientedPose = camera.DisplayOrientedPose;
                    var pose = new VirtualStudio.Shared.DTOs.Tracking.Pose
                    {
                        Position    = new System.Numerics.Vector3(displayOrientedPose.Tx(), displayOrientedPose.Ty(), displayOrientedPose.Tz()),
                        Orientation = new System.Numerics.Vector4(displayOrientedPose.Qx(), displayOrientedPose.Qy(), displayOrientedPose.Qz(), displayOrientedPose.Qw()),
                        Projection  = new System.Numerics.Matrix4x4(
                            projmtx[0], projmtx[1], projmtx[2], projmtx[3],
                            projmtx[4], projmtx[5], projmtx[6], projmtx[7],
                            projmtx[8], projmtx[9], projmtx[10], projmtx[11],
                            projmtx[12], projmtx[13], projmtx[14], projmtx[15]
                            )
                    };
                    webRtcClient.SendMessage(pose.ToBinary());
                    counter = 0;

                    var textureBuffer = new TextureBufferImpl(targetResolution.Width, targetResolution.Height, VideoFrame.TextureBufferType.Rgb, renderTextureId, new Android.Graphics.Matrix(), null, null, null);
                    var i420Buffer    = yuvConverter.Convert(textureBuffer);
                    VideoFrameAvailable?.Invoke(this, i420Buffer);
                }
            }
            catch (System.Exception ex)
            {
                // Avoid crashing the application due to unhandled exceptions.
                Log.Error(TAG, "Exception on the OpenGL thread", ex);
            }
        }
Exemple #12
0
        public void OnSurfaceCreated(IGL10 gl, Javax.Microedition.Khronos.Egl.EGLConfig config)
        {
            GLES20.GlClearColor(0.9f, 0.1f, 0.1f, 1.0f);
            // GLES20.GlViewport(0, 0, glSurfaceView.Width, glSurfaceView.Height);

            textureSize = arSession.CameraConfig.TextureSize;
            arSession.SetDisplayGeometry(1, targetResolution.Width, targetResolution.Height);

            int[] glObjs = new int[1];
            GLES20.GlGenFramebuffers(1, glObjs, 0);
            fboId = glObjs[0];
            GLES20.GlBindFramebuffer(GLES20.GlFramebuffer, fboId);
            GLES20.GlViewport(0, 0, targetResolution.Width, targetResolution.Height);
            GLES20.GlGenTextures(1, glObjs, 0);
            renderTextureId = glObjs[0];;
            GLES20.GlBindTexture(GLES20.GlTexture2d, renderTextureId);
            GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureWrapS, GLES20.GlClampToEdge);
            GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureWrapT, GLES20.GlClampToEdge);
            GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureMinFilter, GLES20.GlNearest);
            GLES20.GlTexParameteri(GLES20.GlTexture2d, GLES20.GlTextureMagFilter, GLES20.GlNearest);
            GLES20.GlTexImage2D(GLES20.GlTexture2d, 0, GLES20.GlRgba, targetResolution.Width, targetResolution.Height, 0, GLES20.GlRgba, GLES20.GlUnsignedByte, null);

            GLES20.GlBindTexture(GLES20.GlTexture2d, 0);
            GLES20.GlFramebufferTexture2D(GLES20.GlFramebuffer, GLES20.GlColorAttachment0, GLES20.GlTexture2d, renderTextureId, 0);
            GLES20.GlBindFramebuffer(GLES20.GlFramebuffer, 0);

            GlUtil.CheckNoGLES2Error("Create render texture.");

            // Create the texture and pass it to ARCore session to be filled during update().
            backgroundRenderer.CreateOnGlThread(/*context=*/ this);
            if (arSession != null)
            {
                arSession.SetCameraTextureName(BackgroundRenderer.TextureId);
            }


            // Prepare the other rendering objects.
            try
            {
                virtualObject.CreateOnGlThread(/*context=*/ this, "andy.obj", "andy.png");
                virtualObject.setMaterialProperties(0.0f, 3.5f, 1.0f, 6.0f);

                virtualObjectShadow.CreateOnGlThread(/*context=*/ this,
                                                     "andy_shadow.obj", "andy_shadow.png");
                virtualObjectShadow.SetBlendMode(ObjectRenderer.BlendMode.Shadow);
                virtualObjectShadow.setMaterialProperties(1.0f, 0.0f, 0.0f, 1.0f);
            }
            catch (Java.IO.IOException e)
            {
                Log.Error(TAG, "Failed to read obj file");
            }

            try
            {
                planeRenderer.CreateOnGlThread(/*context=*/ this, "trigrid.png");
            }
            catch (Java.IO.IOException e)
            {
                Log.Error(TAG, "Failed to read plane texture");
            }
            pointCloudRenderer.CreateOnGlThread(/*context=*/ this);
        }
 public void beforeDrawFrame()
 {
     GLES20.GlGetIntegerv(36006, mOriginalFramebufferId);
     GLES20.GlBindFramebuffer(36160, mFramebufferId);
 }