private void setFBO(GL10 glUnused, boolean useBuffer) { if (useBuffer) { // Bind the framebuffer GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fb[0]); // specify texture as color attachment GLES20.glFramebufferTexture2D( GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, renderTex[0], 0); // attach render buffer as depth buffer GLES20.glFramebufferRenderbuffer( GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, depthRb[0]); // check status int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER); if (status != GLES20.GL_FRAMEBUFFER_COMPLETE) Log.e("Selection", "Frame buffer couldn't attach!"); GLES20.glClearColor(.0f, .0f, .0f, 1.0f); GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT); } else { GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); } }
public static void a( IntBuffer intbuffer, IntBuffer intbuffer1, IntBuffer intbuffer2, int i, int j) { intbuffer.position(0); GLES20.glGenFramebuffers(1, intbuffer); GLES20.glBindFramebuffer(36160, intbuffer.get(0)); a(i, j, intbuffer2); if (GLES20.glCheckFramebufferStatus(36160) != 36053) { Log.e("FBO-Helper", "Failure with framebuffer generation"); } GLES20.glBindFramebuffer(36160, 0); }
@Override public void attach() { if (!isPrepared()) { prepare(); } glBindFramebuffer(GL_FRAMEBUFFER, glRes()); }
public void beforeDrawFrame() { this.mDrawingFrame = true; if (this.mFovsChanged || this.mTextureFormatChanged) { this.updateTextureAndDistortionMesh(); } GLES20.glGetIntegerv(GLES20.GL_FRAMEBUFFER_BINDING, this.mOriginalFramebufferId); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, this.mFramebufferId); }
private int setupRenderTextureAndRenderbuffer(final int width, final int height) { if (this.mTextureId != -1) { GLES20.glDeleteTextures(1, new int[] {this.mTextureId}, 0); } if (this.mRenderbufferId != -1) { GLES20.glDeleteRenderbuffers(1, new int[] {this.mRenderbufferId}, 0); } if (this.mFramebufferId != -1) { GLES20.glDeleteFramebuffers(1, new int[] {this.mFramebufferId}, 0); } this.mTextureId = this.createTexture(width, height, this.mTextureFormat, this.mTextureType); this.mTextureFormatChanged = false; this.checkGlError("setupRenderTextureAndRenderbuffer: create texture"); final int[] renderbufferIds = {0}; GLES20.glGenRenderbuffers(1, renderbufferIds, 0); GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, renderbufferIds[0]); GLES20.glRenderbufferStorage( GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT16, width, height); this.mRenderbufferId = renderbufferIds[0]; this.checkGlError("setupRenderTextureAndRenderbuffer: create renderbuffer"); final int[] framebufferIds = {0}; GLES20.glGenFramebuffers(1, framebufferIds, 0); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, framebufferIds[0]); this.mFramebufferId = framebufferIds[0]; GLES20.glFramebufferTexture2D( GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, this.mTextureId, 0); GLES20.glFramebufferRenderbuffer( GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, renderbufferIds[0]); final int status = GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER); if (status != GLES20.GL_FRAMEBUFFER_COMPLETE) { final String s = "Framebuffer is not complete: "; final String value = String.valueOf(Integer.toHexString(status)); throw new RuntimeException((value.length() != 0) ? s.concat(value) : new String(s)); } GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); return framebufferIds[0]; }
@Override public void onDrawFrame(GL10 glUnused) { // PREPARE mTexturedRectangle.reset(); // FETCH AND TRANSFER FRAME TO TEXTURE if (mRenderRequest == RenderRequest.ALL || mExternalSurfaceTexture.isTextureUpdateAvailable()) { mExternalSurfaceTexture.updateTexture(); mFramebufferIn.bind(); mReadExternalTextureShaderProgram.use(); mReadExternalTextureShaderProgram.setTexture(mExternalSurfaceTexture); mTexturedRectangle.draw(mReadExternalTextureShaderProgram); mRenderRequest = RenderRequest.EFFECT; } // MANIPULATE TEXTURE WITH SHADER(S) if (mRenderRequest == RenderRequest.EFFECT) { if (mEffect != null) { mEffect.apply(mFramebufferIn.getTexture(), mFramebufferOut); } else { mFramebufferOut.bind(); mDefaultShaderProgram.use(); mDefaultShaderProgram.setTexture(mFramebufferIn.getTexture()); mTexturedRectangle.draw(mDefaultShaderProgram); } mRenderRequest = RenderRequest.GEOMETRY; } // RENDER TEXTURE TO SCREEN if (mRenderRequest == RenderRequest.GEOMETRY) { GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); // framebuffer 0 is the screen GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT); mTextureToScreenShaderProgram.use(); mTextureToScreenShaderProgram.setTexture(mFramebufferOut.getTexture()); mTexturedRectangle.translate(0.0f, 0.0f, -1.0f); mTexturedRectangle.calculateMVP(mViewMatrix, mProjectionMatrix); mTexturedRectangle.draw(mTextureToScreenShaderProgram); } // STUFF // mFrameRateCalculator.frame(); mRenderRequest = RenderRequest.DEFAULT; }
@Override public void glBindFramebuffer(int target, int framebuffer) { GLES20.glBindFramebuffer(target, framebuffer); }
@Override public void detach() { glBindFramebuffer(GL_FRAMEBUFFER, 0); }
public void afterDrawFrame() { GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, this.mOriginalFramebufferId.array()[0]); this.undistortTexture(this.mTextureId); this.mDrawingFrame = false; }
private void draw(GlRectDrawer drawer) { if (!seenFrame) { // No frame received yet - nothing to render. return; } long now = System.nanoTime(); final boolean isNewFrame; synchronized (pendingFrameLock) { isNewFrame = (pendingFrame != null); if (isNewFrame && startTimeNs == -1) { startTimeNs = now; } if (isNewFrame) { if (pendingFrame.yuvFrame) { rendererType = RendererType.RENDERER_YUV; drawer.uploadYuvData( yuvTextures, pendingFrame.width, pendingFrame.height, pendingFrame.yuvStrides, pendingFrame.yuvPlanes); // The convention in WebRTC is that the first element in a ByteBuffer corresponds to the // top-left corner of the image, but in glTexImage2D() the first element corresponds to // the bottom-left corner. We correct this discrepancy by setting a vertical flip as // sampling matrix. final float[] samplingMatrix = RendererCommon.verticalFlipMatrix(); rotatedSamplingMatrix = RendererCommon.rotateTextureMatrix(samplingMatrix, pendingFrame.rotationDegree); } else { rendererType = RendererType.RENDERER_TEXTURE; // External texture rendering. Update texture image to latest and make a deep copy of // the external texture. // TODO(magjed): Move updateTexImage() to the video source instead. final SurfaceTexture surfaceTexture = (SurfaceTexture) pendingFrame.textureObject; surfaceTexture.updateTexImage(); final float[] samplingMatrix = new float[16]; surfaceTexture.getTransformMatrix(samplingMatrix); rotatedSamplingMatrix = RendererCommon.rotateTextureMatrix(samplingMatrix, pendingFrame.rotationDegree); // Reallocate offscreen texture if necessary. textureCopy.setSize(pendingFrame.rotatedWidth(), pendingFrame.rotatedHeight()); // Bind our offscreen framebuffer. GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, textureCopy.getFrameBufferId()); GlUtil.checkNoGLES2Error("glBindFramebuffer"); // Copy the OES texture content. This will also normalize the sampling matrix. GLES20.glViewport(0, 0, textureCopy.getWidth(), textureCopy.getHeight()); drawer.drawOes(pendingFrame.textureId, rotatedSamplingMatrix); rotatedSamplingMatrix = RendererCommon.identityMatrix(); // Restore normal framebuffer. GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); } copyTimeNs += (System.nanoTime() - now); VideoRenderer.renderFrameDone(pendingFrame); pendingFrame = null; } } // OpenGL defaults to lower left origin - flip vertically. GLES20.glViewport( displayLayout.left, screenHeight - displayLayout.bottom, displayLayout.width(), displayLayout.height()); updateLayoutMatrix(); final float[] texMatrix = RendererCommon.multiplyMatrices(rotatedSamplingMatrix, layoutMatrix); if (rendererType == RendererType.RENDERER_YUV) { drawer.drawYuv(yuvTextures, texMatrix); } else { drawer.drawRgb(textureCopy.getTextureId(), texMatrix); } if (isNewFrame) { framesRendered++; drawTimeNs += (System.nanoTime() - now); if ((framesRendered % 300) == 0) { logStatistics(); } } }