/** * 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(); }
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); }
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); }
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); }
public void OnDrawFrame(IGL10 gl) { GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit); mTrajectory.draw(ViewMatrix, mProjectionMatrix); mFloorGrid.draw(ViewMatrix, mProjectionMatrix); mCameraFrustumAndAxis.draw(ViewMatrix, mProjectionMatrix); }
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); }
public override void OnDrawFrame(IGL10 gl) { GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit); base.OnDrawFrame(gl); }
public override void OnDrawFrame(IGL10 gl) { GLES20.GlClear(GLES20.GlColorBufferBit | GLES20.GlDepthBufferBit); base.OnDrawFrame(gl); cube.angleX = this.angleX; cube.angleY = this.angleY; }
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); }
public void OnDrawFrame(IGL10 unused) { // Draw background color GLES20.GlClear(GLES20.GL_COLOR_BUFFER_BIT); // Draw triangle mTriangle.Draw(); }
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); } }
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); } }
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); }
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 }
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); } }
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(); }
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); }
/// <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 }
/** * 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); }
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); }
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); } }
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 --> } }
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); }