Android OpenGL ES->Frame Buffer Object

Frame Buffer 对象的概念可以参见前面文章Android OpenGL ES 开发教程(23):FrameBuffer

简单的和2D图像类比,Frame Buffer 如果 对应到二维图形环境中,就是一个2D的内存数组空间,缺省情况为屏幕的显存,也可以创建Offscreen 内存空间,此时Frame Buffer 可以是一个二维数组,数组每个元素代表一个像素颜色。

对于三维图形来说,除了需要代表颜色的二维数组(Color Buffer),还需要深度二维数组(Depth Buffer) 或遮罩数组(Stencil Buffer),因此在OpenGL 中的Frame Buffer为上述Color Buffer,Depth Buffer,Stencil Buffer 的集合。如果手机具有GPU,其缺省的Frame Buffer也是3D屏幕显示区域。

通过Opengl ES扩展支持,应用程序也可以创建内存中的Frame Buffer对象(不用于屏幕显示)。通过这种应用程序创建的FrameBuffer对象,OpenGL应用可以将图像显示输出重新定向到这个非屏幕显示用FrameBuffer对象中,类似于二维图形绘制中常用的Offscreen 技术。

和缺省的屏幕显示FrameBuffer一样,由应用程序创建的FrameBuffer对象也是由Color Buffer, Depth Buffer和Stencil Buffer(可选)的集合组成。这些Buffer在FrameBuffer对象中可以称为FrameBuffer-attachable 图像,FrameBuffer定义了一些接入点(Attachment Point)可以用于连接(Attach)这些Buffer数组。

OpenGL ES定义了两种FrameBuffer-attachable 图像,Texture 和 renderbuffer ,简单的可以将Texture 理解为Color buffer 或是2D图像,render buffer 对应于depth buffer。

下图表示了Texture , Renderbuffer 对象和 Frame Buffer 对象之间的关系:

但把Texture 和 Render Buffer 链接到FrameBuffer这些接入点(ATTACHMENT)之后,之后所有OpenGL绘图指令的输出结果就写入到这些内存Buffer中,而非缺省屏幕显示。

不同的Android设备支持的OpenGL ES扩展可能有所不同,因此如果需要使用应用创建FrameBuffer对象前需要检查手机是否支持Framebuffer扩展,本例使用

private boolean checkIfContextSupportsExtension(GL10 gl, String extension) { 
 String extensions = " " + gl.glGetString(GL10.GL_EXTENSIONS) + " "; 
 // The extensions string is padded with spaces between extensions, but not 
 // necessarily at the beginning or end. For simplicity, add spaces at the 
 // beginning and end of the extensions string and the extension string. 
 // This means we can avoid special-case checks for the first or last 
 // extension, as well as avoid special-case checks when an extension name 
 // is the same as the first part of another extension name. 
 return extensions.indexOf(" " + extension + " ") >= 0; 
}

使用FrameBuffer的基本步骤如下:

1. 使用glGenFramebuffersOES创建FrameBuffer对象


int[] framebuffers = new int[1]; 
gl11ep.glGenFramebuffersOES(1, framebuffers, 0); 
framebuffer = framebuffers[0];


2. 创建好FrameBuffer后,必须绑定FrameBuffer到OpenGL中,

gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, framebuffer);


第一个参数类型必须为GL_FRAMEBUFFER_OES,第二个参数为FrameBuffer的ID。如果Id为0,表示绑定到缺省的屏幕FrameBuffer。

绑定之后,后续的OpenGL绘制结果就从定向到FrameBuffer中,而不是显示到屏幕上。

3, 使用glGenRenderbuffersOES创建RenderBuffer

int depthbuffer; 
int[] renderbuffers = new int[1]; 
gl11ep.glGenRenderbuffersOES(1, renderbuffers, 0); 
depthbuffer = renderbuffers[0];


4. 和FrameBuffer类似,创建RenderBuffer对象,也需要绑定到OpengL库中

gl11ep.glBindRenderbufferOES(GL11ExtensionPack.GL_RENDERBUFFER_OES, depthbuffer);


5. 给renderBuffer 分配内存。

创建的renderBuffer 本身不含有内存空间,因此必须给它分配内存空间,这是通过glRenderbufferStorageOES来实现的。

gl11ep.glRenderbufferStorageOES(GL11ExtensionPack.GL_RENDERBUFFER_OES, 
 GL11ExtensionPack.GL_DEPTH_COMPONENT16, width, height);


第二个参数为创建的RenderBuffer的内部格式类型。

6. 创建Texture对象,可以参见Android ApiDemos示例解析(200):Graphics->OpenGL ES->Textured Triangle

7. 在创建好FrameBuffer,Texture和renderBuffer对象之后,需要把Texture,RenderBuffer对象和FrameBuffer中对应的Attachment Point链接起来。

链接Texture对象

gl11ep.glFramebufferTexture2DOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, 
 GL11ExtensionPack.GL_COLOR_ATTACHMENT0_OES, GL10.GL_TEXTURE_2D, 
 targetTextureId, 0);


链接renderBuffer 对象

l11ep.glFramebufferRenderbufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, 
 GL11ExtensionPack.GL_DEPTH_ATTACHMENT_OES, 
 GL11ExtensionPack.GL_RENDERBUFFER_OES, depthbuffer);


来看一下本例的onDrawFrame方法

private static final boolean DEBUG_RENDER_OFFSCREEN_ONSCREEN = false; 
  
public void onDrawFrame(GL10 gl) { 
 checkGLError(gl); 
 if (mContextSupportsFrameBufferObject) { 
 GL11ExtensionPack gl11ep = (GL11ExtensionPack) gl; 
 if (DEBUG_RENDER_OFFSCREEN_ONSCREEN) { 
 drawOffscreenImage(gl, mSurfaceWidth, mSurfaceHeight); 
 } else { 
 gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, mFramebuffer); 
 drawOffscreenImage(gl, mFramebufferWidth, mFramebufferHeight); 
 gl11ep.glBindFramebufferOES(GL11ExtensionPack.GL_FRAMEBUFFER_OES, 0); 
 drawOnscreen(gl, mSurfaceWidth, mSurfaceHeight); 
 } 
 } else { 
 // Current context doesn't support frame buffer objects. 
 // Indicate this by drawing a red background. 
 gl.glClearColor(1,0,0,0); 
 gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 
 } 
}


本例在创建的FrameBuffer中绘制立方体,其绘图指令和例子Android ApiDemos示例解析(203):Graphics->OpenGL ES->GLSurfaceView一样。但其显示结果存放在mFramebuffer中(可以通过将DEBUG_RENDER_OFFSCREEN_ONSCREEN设为True看到FrameBuffer的内容)。然后将mFramebuffer显示的内存作为Triangle的材质绘制三角形

### 回答1: OpenGL ES 2.0是一种用于移动设备和嵌入式设备的图形渲染API,它是针对OpenGL的一个精简版本。其设计目标是可以在资源受限的设备上高效地进行图形渲染和绘制。 OpenGL ES 2.0具有以下几个主要特点: 1. 着色语言:OpenGL ES 2.0引入了可编程的着色器,使开发者可以自定义渲染管线的各个阶段,包括顶点处理、像素处理等。这种灵活性使得开发者可以更加精确地控制图形渲染过程,实现各种高级的渲染效果。 2. 不支持固定功能管线:与OpenGL ES 1.x版本相比,OpenGL ES 2.0不再支持固定的渲染管线。这意味着开发者需要自己实现包括光照、纹理映射等在内的各种渲染特性。尽管增加了一定的复杂性,但同时也提供了更大的灵活性和自由度。 3. 存储和处理纹理:OpenGL ES 2.0支持对纹理进行更多的操作和处理。开发者可以自由地加载和创建二维和三维纹理,并进行各种操作,例如多重纹理叠加、纹理过滤等。这为实现更加逼真的图形效果提供了更多的可能性。 4. 精简的API:OpenGL ES 2.0与OpenGL相比,移除了一些不常用的功能和特性,使得API更加精简和高效。这样的设计使得OpenGL ES 2.0可以在资源受限的移动设备上运行,并提供高效的图形渲染效果。 总结来说,OpenGL ES 2.0是一种用于移动设备和嵌入式设备的图形渲染API,支持可编程着色器,不再支持固定功能管线,并提供了丰富的纹理处理功能。它的设计目标是在资源受限的设备上高效地进行图形渲染和绘制。 ### 回答2: OpenGL ES 2.0,即OpenGL for Embedded Systems 2.0,是一种在移动设备和嵌入式设备上使用的图形渲染API。它是OpenGL的子集,旨在为资源有限的移动和嵌入式平台提供高性能的2D和3D图形渲染功能。 OpenGL ES 2.0基于可编程管线的概念,从而更加灵活。它将图形渲染的各个阶段(如顶点处理、光栅化、片元处理等)交给开发者通过自定义的着色器程序来完成。这使得开发人员能够实现更精确的图形渲染、更复杂的特效和更高性能的图形处理。 与OpenGL ES 1.1相比,OpenGL ES 2.0最显著的改进之一是引入了可编程着色器。开发人员可以使用GLSL(OpenGL着色器语言)编写自定义的顶点着色器和片元着色器,从而实现更高级别的图形效果。这种可编程的特性为游戏开发人员和图形设计师提供了更大的自由度和创造力,使他们能够创建出更逼真、更具艺术感的图形效果。 此外,OpenGL ES 2.0还提供了更多的纹理功能,例如多重采样、非方形纹理等。纹理是2D或3D图像的数据映射,用于给物体表面着色,增加真实感。多重采样技术可以消除图像的锯齿状边缘,使渲染的图像更加平滑。 总的来说,OpenGL ES 2.0是一种适用于移动设备和嵌入式设备的高性能图形渲染API。它允许开发人员通过自定义的着色器程序来实现复杂的图形处理,为游戏和应用程序提供更多的创造空间和艺术表现力。它的引入使得移动设备和嵌入式设备能够展示出更逼真、更高质量的图形效果。 ### 回答3: OpenGL ES(Open Graphics Library for Embedded Systems),是一种为嵌入式系统设计的跨平台图形库,它包含了OpenGL的子集,是为了在移动设备中进行图形渲染而设计的。 OpenGL ES 2.0是其中的一个版本,它引入了一些重要的新功能和特性。它是一个基于片段着色器的渲染管线,相比于之前的版本,提供了更大的灵活性和更高的自定义性。 OpenGL ES 2.0取消了固定功能管线,引入了可编程的着色器语言—GLSL(OpenGL Shading Language)。GLSL允许开发者编写灵活的着色器程序,以处理输入数据并生成输出的像素颜色。 另外,OpenGL ES 2.0还引入了纹理压缩、多重渲染目标(MRT)和帧缓冲对象(Frame Buffer Object)等新特性。纹理压缩可以减少纹理占用的显存空间,提高渲染性能;多重渲染目标允许同时向多个渲染目标写入数据;帧缓冲对象可以创建一个自定义的渲染目标,用于高级图像处理和后期处理效果。 总的来说,OpenGL ES 2.0是一个强大且灵活的图形库,为开发者提供了更多的自由度和可定制性,使他们能够在移动设备上进行高质量的图形渲染和图形效果处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值