天天看點

OpenGL OpenGL ES 幀緩沖區位塊傳送(Blit)OpenGL ES 幀緩沖區位塊傳送聯系與交流

作者:位元組流動

來源:

https://blog.csdn.net/Kennethdroid/article/details/109032497

OpenGL ES 幀緩沖區位塊傳送

幀緩沖區位塊傳送(Blit)也是 OpenGL ES 3.0 的新特性,主要用于幀緩沖區之間的像素拷貝,性能高且使用友善,可以指定緩沖區任意矩形區域的像素拷貝。

OpenGL OpenGL ES 幀緩沖區位塊傳送(Blit)OpenGL ES 幀緩沖區位塊傳送聯系與交流

本文的繪制流程是,建立一個 FBO 綁定紋理作為顔色附着,然後綁定該幀緩沖區進行一次離屏渲染,最後綁定渲染到螢幕的緩沖區作為渲染緩沖區,從新的幀緩沖區中拷貝像素。

渲染代碼:

//首先擷取目前預設幀緩沖區的 id 
GLint defaultFrameBuffer = GL_NONE;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFrameBuffer);

//綁定我們新建立的幀緩沖區進行渲染
glBindFramebuffer(GL_FRAMEBUFFER, m_FBO);
glViewport ( 0, 0, m_RenderImage.width, m_RenderImage.height);
glClear(GL_COLOR_BUFFER_BIT);
glDrawBuffers(ATTACHMENT_NUM, attachments);

glUseProgram (m_ProgramObj);
glBindVertexArray(m_VaoId);
UpdateMVPMatrix(m_MVPMatrix, 0, m_AngleY, (float)screenW / screenH);
glUniformMatrix4fv(m_MVPMatLoc, 1, GL_FALSE, &m_MVPMatrix[0][0]);

glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, m_TextureId);
glUniform1i(m_SamplerLoc, 0);

glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (const void *)0);

//綁定預設的幀緩沖區對象,将像素從建立的幀緩沖區拷貝到目前預設的幀緩沖區
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, defaultFrameBuffer);
glViewport ( 0, 0, m_SurfaceWidth, m_SurfaceHeight);
glClear(GL_COLOR_BUFFER_BIT);

//位塊傳送
BlitTextures();
      

進行幀緩沖區間位塊傳之前,需要指定好源幀緩沖區 GL_READ_FRAMEBUFFER 和目标幀緩沖區 GL_DRAW_FRAMEBUFFER,下面代碼實作是将四個顔色附着對應的緩沖區像素,分别拷貝到目前渲染緩沖區中的 1/4 矩形區域内:

void FBOBlitSample::BlitTextures() {
    //很重要,指定源幀緩沖區
    glBindFramebuffer(GL_READ_FRAMEBUFFER, m_FBO);

    glReadBuffer(GL_COLOR_ATTACHMENT0);
    glBlitFramebuffer(0, 0, m_RenderImage.width, m_RenderImage.height,
                        0, 0, m_SurfaceWidth/2, m_SurfaceHeight/2,
                        GL_COLOR_BUFFER_BIT, GL_LINEAR);

    glReadBuffer(GL_COLOR_ATTACHMENT1);
    glBlitFramebuffer(0, 0, m_RenderImage.width, m_RenderImage.height,
                        m_SurfaceWidth/2, 0, m_SurfaceWidth, m_SurfaceHeight/2,
                        GL_COLOR_BUFFER_BIT, GL_LINEAR);

    glReadBuffer(GL_COLOR_ATTACHMENT2);
    glBlitFramebuffer(0, 0, m_RenderImage.width, m_RenderImage.height,
                        0, m_SurfaceHeight/2, m_SurfaceWidth/2, m_SurfaceHeight,
                        GL_COLOR_BUFFER_BIT, GL_LINEAR);

    glReadBuffer(GL_COLOR_ATTACHMENT3);
    glBlitFramebuffer(0, 0, m_RenderImage.width, m_RenderImage.height,
                        m_SurfaceWidth/2, m_SurfaceHeight/2, m_SurfaceWidth, m_SurfaceHeight,
                        GL_COLOR_BUFFER_BIT, GL_LINEAR);
}      

最後呈現的效果是将四張圖像渲染到一個螢幕上。

聯系與交流

技術交流/擷取源碼可以添加我的微信:Byte-Flow ,進技術交流群

「視訊雲技術」你最值得關注的音視訊技術公衆号,每周推送來自阿裡雲一線的實踐技術文章,在這裡與音視訊領域一流工程師交流切磋。
OpenGL OpenGL ES 幀緩沖區位塊傳送(Blit)OpenGL ES 幀緩沖區位塊傳送聯系與交流

繼續閱讀