做3d兼职网站,公司主页图片,富阳做网站方式,含山微信搭建网站建设http://blog.csdn.net/u011371324/article/details/68946779 默认情况下#xff0c;Opengl ES使用系统提供的帧缓冲区作为绘图表面#xff0c;一般情况下#xff0c;如果只在屏幕的表面绘图的话#xff0c;系统提供的默认帧缓冲区很高效#xff0c;但是很多应用程序需要渲…http://blog.csdn.net/u011371324/article/details/68946779 默认情况下Opengl ES使用系统提供的帧缓冲区作为绘图表面一般情况下如果只在屏幕的表面绘图的话系统提供的默认帧缓冲区很高效但是很多应用程序需要渲染到纹理。此时就需要我们自己来创建帧缓冲区对象。比如在VR中就需要使用帧缓冲对象在同一块屏幕上来实现双眼显示模式。 首先说下渲染到纹理的概念。 渲染到纹理Render to Texture将我们要绘制的场景保存到一张纹理当中打个比喻类似于利用手机的截图操作手机的画面就好比是已经渲染好的内容截图得到的图片相当于纹理然后将它附加到缓冲区对象上。 在Opengl中帧缓冲区是渲染管线的最后一步即可以理解为将在屏幕上显示的信息都保存在这里它像一个容器里面有颜色附着、纹理、模板、深度等信息下图就是帧缓冲区、渲染缓冲区对象、纹理的关系。 当我们自己不创建帧缓冲区对象时使用的是系统默认提供的此时当前我们的渲染操作都是针对系统的帧缓冲区对象就像向该容器中放信息而在显示时也是由该容器提供信息。 所以想要在一块屏幕上显示左右两块区域的图像时就需要再增加2个“容器”来暂时保存纹理等信息显示时再将这两个容器的信息交给系统的容器即将2个自己创建的帧缓冲区对象的纹理作为系统缓冲区对象的纹理然后进行绘图显示 有个疑问是既然都是容器为什么还要用自己创建呢 假设同一个屏幕上的两个区域显示两幅图像左右场景不同渲染管线出来只有一张纹理放到“容器”中两个管线得到两张纹理但是系统的帧缓冲区只对应一个渲染管线不能直接使用两张纹理所以就需要弄两个“容器”来缓存一下两张纹理然后在屏幕显示每一帧的过程中在左右两部分分别使用两张纹理进行绘制再得到一个整合后的纹理然后交给系统的帧缓冲区。这样就能实现同一个屏幕上的两个区域显示两幅图像利用两个“容器”自己创建的帧缓冲区对象类似于卸磨杀驴。 使用帧缓冲对象渲染到纹理的基本操作其中初始化缓冲区对象最为关键主要有以下几个步骤 a)创建帧缓冲对象b)创建与帧缓冲对象一起使用的纹理对象c)创建渲染缓冲区对象d)绑定帧缓冲区对象e)绑定纹理对象f)设置纹理的参数格式、尺寸等设置g)绑定渲染缓冲区对象并设置尺寸h)连接纹理对象到缓冲区对象的颜色附着上i)连接渲染缓冲区对象到深度附着 上面是基本的理论部分下面直接上代码 int[] temp new int[1]; //generate fbo id GLES20.glGenFramebuffers(1, temp, 0); fboId temp[0]; //generate texture GLES20.glGenTextures(1, temp, 0); fboTex temp[0]; //generate render buffer GLES20.glGenRenderbuffers(1, temp, 0); renderBufferId temp[0]; //Bind Frame buffer GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fboId); //Bind texture GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, fboTex); //Define texture parameters GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, fboWidth, fboHeight, 0, GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE,null); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); //Bind render buffer and define buffer dimension GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, renderBufferId); GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT16, fboWidth, fboHeight); //Attach texture FBO color attachment GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D, fboTex, 0); //Attach render buffer to depth attachment GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_DEPTH_ATTACHMENT, GLES20.GL_RENDERBUFFER, renderBufferId); //we are done, reset GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0); GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, 0); GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); 以上就是初始化帧缓冲对象的过程基本的操作相对比较固定 下面的函数是安卓中利用Opengl es绘制的每一帧大致过程在你想要得到的纹理前先绑定初始化好的帧缓冲对象设置窗口然后开始渲染你的纹理渲染完之后解除绑定切换到系统的帧缓冲区再进行绘制最简单的就是你可以画一个矩形然后将纹理贴到上面最终显示到屏幕上。 public void RenderToTexture (GL10 arg0){ GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fboId); GLES20.glViewport(0, 0, fboWidth, fboHeight); ******Rendering Code******* GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); } public void onDrawFrame(GL10 arg0) { //call FBORenderer to render to texture fbor.RenderToTexture();//调用RenderToTexture 方法将纹理保存在fbor的缓冲区中 //reset the projection, because viewport is set by FBO renderer is different GLES20.glViewport(0, 0, vwidth, vheight); float ratio (float)vwidth/(float)vheight; float a 5f; Matrix.orthoM(m_fProj, 0, -a*ratio, a*ratio, -a*ratio, a*ratio, 1, 10); //multiply view matrix with projection matrix Matrix.multiplyMM(m_fVPMat, 0, m_fProj, 0, m_fView, 0); //below procedure is same as any other rendering GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT|GLES20.GL_DEPTH_BUFFER_BIT); GLES20.glUseProgram(iProgId); vertexBuffer.position(0); GLES20.glVertexAttribPointer(iPosition, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer); GLES20.glEnableVertexAttribArray(iPosition); texBuffer.position(0); GLES20.glVertexAttribPointer(iTexCoords, 2, GLES20.GL_FLOAT, false, 0, texBuffer); GLES20.glEnableVertexAttribArray(iTexCoords); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, iTexId); GLES20.glUniform1i(iTexLoc, 0); //since Im multi-texturing, bind fboId to texture1 GLES20.glActiveTexture(GLES20.GL_TEXTURE1); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, fboId); GLES20.glUniform1i(iTexLoc1, 1); //for rotating cube Matrix.setIdentityM(m_fModel, 0); Matrix.rotateM(m_fModel, 0, -xAngle, 0, 1, 0); Matrix.rotateM(m_fModel, 0, -yAngle, 1, 0, 0); //multiply model matrix with view-projection matrix Matrix.multiplyMM(m_fMVPMat, 0, m_fVPMat, 0, m_fModel, 0); //pass model-view-projection matrix to shader GLES20.glUniformMatrix4fv(iMVPMat, 1, false, m_fMVPMat, 0); //draw cube GLES20.glDrawElements(GLES20.GL_TRIANGLES, cube.m_nIndeces, GLES20.GL_UNSIGNED_SHORT, indexBuffer); } 上面给出的仅仅是一个缓冲区对象的主要代码部分对于实现双眼显示的话要创建两个缓冲区对象分别渲染纹理到这两个缓冲区中 然后在onDraw()函数中可以绘制两个矩形每个矩形分别贴上这两张纹理递交给系统的帧缓冲区解绑定时已经切换到系统缓冲区对象啦 所以按照正常的绘制流程就行了 此时屏幕上就显示了左右两张图像了。 参考http://opengles2learning.blogspot.kr/2014/02/render-to-texture-rtt.html 参考Opengl ES 3.0编程指南 参考http://learnopengl-cn.readthedocs.io/zh/latest/04%20Advanced%20OpenGL/05%20Framebuffers/转载于:https://www.cnblogs.com/jukan/p/6837817.html