glsurfaceview怎么知道renderervue dom渲染完毕毕

您所在的位置: &
使用OpenGL图形接口的程序结构
使用OpenGL图形接口的程序结构
电子工业出版社
《Android经典应用程序开发》第4章图形接口,本章介绍2D图形系统结构和绘制,3D图形系统的结构和绘制,可绘制内容,动画。本节为大家介绍使用OpenGL图形接口的程序结构。
4.2.1& 使用OpenGL图形接口的程序结构
在Android中,可以直接支持3D图形的绘制,主要使用OpenGL标准包javax.microedition.khronos中的各个类,并且需要结合Android GUI系统使用。Android中的android.opengl包提供Android系统和OpenGL标准结合的功能。
Android中OpenGL接口典型的使用方法是从Android 1.5(API级别为3)引入的,在使用3D的图形API方面,主要的步骤通常如下所示:
(1)扩展android.opengl.GLSurfaceView类(可选)。
(2)实现android.opengl.GLSurfaceView中的Renderer(渲染器)接口。
(3)将所实现的GLSurfaceView.Renderer接口设置成GLSurfaceView中的渲染器。
android.opengl.GLSurfaceView扩展了android.view包中的SurfaceView,SurfaceView又继承了android.view.View,因此GLSurfaceView本身可以作为Android中的一个控件来使用,它可以负责事件处理方面。
Android中OpenGL绘图接口使用的结构如图4-9所示。
GLSurfaceView.Renderer是一个接口,主要需要实现其中的onDrawFrame(GL10 gl)函数,并在其中实现OpenGL绘制内容。
在实现3D绘制的时候,需要具有一个类GLSurfaceView并重新实现其中的Renderer,并且设置Renderer为GLSurfaceView当中的渲染器。渲染器是真正实现绘制功能的地方。
图4-9& Android中OpenGL绘图接口结构
【责任编辑: TEL:(010)】&&&&&&
关于&&&&的更多文章
IE浏览器不支持很多CSS属性是出了名的,即便在支持的部分中,也
本书描述了黑客用默默无闻的行动为数字世界照亮了一条道路的故事。
《C#高级编程(第8版)》是C# 2012和.NET 4.5高级技术的
《Android 4 游戏入门经典(第3版)》将赋予您惊人的灵
本书这一卷是介绍构建面向对象的联网与并发中间件的开
本书由Symantec首席反病毒研究员执笔,是讲述现代病毒威胁、防御技术和分析工具的权威指南。与多数讲述计算机病毒的书籍不同,
51CTO旗下网站博客访问: 113680
博文数量: 69
博客积分: 2627
博客等级: 少校
技术积分: 705
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: Java
1. new一个GLSurfaceView()2. setRenderer(自定义renderer)3. setContentView(GLSurfaceView对象)4. 自定义的renderer要implements GLSurfaceView.Renderer接口.public class MainActivity extends Activity {&&& @Override&&& public void onCreate(Bundle savedInstanceState) {&&&&&&& super.onCreate(savedInstanceState);&&&&&& &&&&&&&& //full screen&&&&&&& requestWindowFeature(Window.FEATURE_NO_TITLE);& &&&&&&&& getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);&&&&&&& GLSurfaceView glSurfaceView=new GLSurfaceView(this);&&&&&&& glSurfaceView.setRenderer(new OpenGLESRenderer());&&&&&&& setContentView(glSurfaceView);&&& }}public class OpenGLESRender implements Renderer{&&& @Override&&& public void onSurfaceCreated(GL10 gl,EGLConfig config){&&& }&& &&&& @Override&&& public void onDrawFrame(GL10 gl){&&& }&& &&&& @Override&&& public void onSurfaceChanged(GL10 gl,int width,int height){&&& }}
阅读(943) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。下次自动登录
现在的位置:
& 综合 & 正文
Android GLSurfaceView
android.opengl这个包下,我看了下,无论是2.2还是4.1.2(最新的sdk),都有14个类,就不一一列举,从哪个类看起呢?
看到一个GLSurfaceView,从它开始吧。
先看类的定义:class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback,继承自SurfaceView,并实现了
SurfaceView的回调方法。
先看下SurfaceView, 类定义:class SurfaceView extends MockView,里面很简单,其中有一个: private SurfaceHolder mSurfaceHolder = new SurfaceHolder(),
去SurfaceHolder的源码看,public interface Callback,callback这个接口里有3个方法:
public void surfaceCreated(SurfaceHolder holder);
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height);
public void surfaceDestroyed(SurfaceHolder holder);
从方法名称,大致知道方法的作用了。
使用的SurfaceView的时候,一般情况下还要对其进行创建,销毁,改变时的情况进行监视,这就要用到SurfaceHolder.Callback.
只要继承SurfaceView类并实现SurfaceHolder.Callback接口就可以实现一个自定义的SurfaceView了,SurfaceHolder.Callback在底层的Surface状态发生变化的时候通知View,SurfaceHolder.Callback具有如下的接口:
surfaceCreated(SurfaceHolder holder):当Surface第一次创建后会立即调用该函数。可以在该函数中做些和绘制界面相关的初始化工作,一般情况下都是在另外的线程来绘制界面,所以不要在这个函数中绘制Surface。
surfaceChanged(SurfaceHolder holder, int format, int width,int height):当Surface的状态(大小和格式)发生变化的时候会调用该函数,在surfaceCreated调用后该函数至少会被调用一次。
surfaceDestroyed(SurfaceHolder holder):当Surface被摧毁前会调用该函数,该函数被调用后就不能继续使用Surface了,一般在该函数中来清理使用的资源。
通过SurfaceView的getHolder()函数可以获取SurfaceHolder对象,Surface 就在SurfaceHolder对象内。虽然Surface保存了当前窗口的像素数据,但是在使用过程中是不直接和Surface打交道的,由SurfaceHolder的Canvas lockCanvas()或则Canvas lockCanvas(Rect dirty)函数来获取Canvas对象,通过在Canvas上绘制内容来修改Surface中的数据。如果Surface不可编辑或则尚未创建调用该函数会返回null,在
unlockCanvas() 和 lockCanvas()中Surface的内容是不缓存的,所以需要完全重绘Surface的内容,为了提高效率只重绘变化的部分则可以调用lockCanvas(Rect dirty)函数来指定一个dirty区域,这样该区域外的内容会缓存起来。在调用lockCanvas函数获取Canvas后,SurfaceView会获取Surface的一个同步锁直到调用unlockCanvasAndPost(Canvas canvas)函数才释放该锁,这里的同步机制保证在Surface绘制过程中不会被改变(被摧毁、修改)。
当在Canvas中绘制完成后,调用函数unlockCanvasAndPost(Canvas canvas)来通知系统Surface已经绘制完成,这样系统会把绘制完的内容显示出来。为了充分利用不同平台的资源,发挥平台的最优效果可以通过SurfaceHolder的setType函数来设置绘制的类型,目前接收如下的参数:
SURFACE_TYPE_NORMAL:用RAM缓存原生数据的普通Surface
SURFACE_TYPE_HARDWARE:适用于DMA(Direct memory access )引擎和硬件加速的Surface
SURFACE_TYPE_GPU:适用于GPU加速的Surface
SURFACE_TYPE_PUSH_BUFFERS:表明该Surface不包含原生数据,Surface用到的数据由其他对象提供,在Camera图像预览中就使用该类型的Surface,有Camera负责提供给预览Surface数据,这样图像预览会比较流畅。如果设置这种类型则就不能调用lockCanvas来获取Canvas对象了。
访问SurfaceView的底层图形是通过SurfaceHolder接口来实现的,通过getHolder()方法可以得到这个SurfaceHolder对象。你应该实现surfaceCreated(SurfaceHolder)和surfaceDestroyed(SurfaceHolder)方法来知道在这个Surface在窗口的显示和隐藏过程中是什么时候创建和销毁的。
注意:一个SurfaceView只在SurfaceHolder.Callback.surfaceCreated() 和 SurfaceHolder.Callback.surfaceDestroyed()调用之间是可用的,其他时间是得不到它的Canvas对象的(null)。
附:SurfaceView和View最本质的区别
SurfaceView和View最本质的区别在于,surfaceView是在一个新起的单独线程中可以重新绘制画面而View必须在UI的主线程中更新画面。
那么在UI的主线程中更新画面 可能会引发问题,比如你更新画面的时间过长,那么你的主UI线程会被你正在画的函数阻塞。那么将无法响应按键,触屏等消息。
当使用surfaceView 由于是在新的线程中更新画面所以不会阻塞你的UI主线程。但这也带来了另外一个问题,就是事件同步。比如你触屏了一下,
你需要surfaceView中thread处理,一般就需要有一个event queue的设计来保存touch event,这会稍稍复杂一点,因为涉及到线程同步。
再回到GLSurfaceView。标准的构造函数:
public GLSurfaceView(Context context) {
super(context);
init中对surfaceholder做了初始化:
private void init() {
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed
SurfaceHolder holder = getHolder();
holder.addCallback(this);
holder.setFormat(PixelFormat.RGB_565);
// setType is not needed for SDK 2.0 or newer. Uncomment this
// statement if back-porting this code to older SDKs.
// holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
后面还有很多方法,都是对基础属相的设置,不再重复。
有几个接口,可能需要我们注意下:
public interface GLWrapper:An interface used to wrap a GL interface
public interface Renderer:这个接口相当重要,细看下。Called when the surface is created or recreated.
DefaultContextFactory
DefaultWindowSurfaceFactory
EGLConfigChooser
有个内部静态类:private class EglHelper
竟然还有个线程:class GLThread extends Thread(A generic GL Thread),予以对应的:private static class GLThreadManager
自定义了一个Writer: static class LogWriter extends Writer
大致就是这些,细节的地方当然还需要再仔细思考下。
GLSurfaceView是一个视图,继承至SurfaceView,它内嵌的surface专门负责OpenGL渲染。
GLSurfaceView提供了下列特性:
1& 管理一个surface,这个surface就是一块特殊的内存,能直接排版到android的视图view上。
2& 管理一个EGL display,它能让opengl把内容渲染到上述的surface上。
3& 用户自定义渲染器(render)。
4& 让渲染器在独立的线程里运作,和UI线程分离。
5& 支持按需渲染(on-demand)和连续渲染(continuous)。
6& 一些可选工具,如调试。
使用GLSurfaceView
通常会继承GLSurfaceView,并重载一些和用户输入事件有关的方法。如果你不需要重载事件方法,GLSurfaceView也可以直接使用,你可以使用set方法来为该类提供自定义的行为。例如,GLSurfaceView的渲染被委托给渲染器在独立的渲染线程里进行,这一点和普通视图不一样,setRenderer(Renderer)设置渲染器。
初始化GLSurfaceView
初始化过程其实仅需要你使用setRenderer(Renderer)设置一个渲染器(render)。当然,你也可以修改GLSurfaceView一些默认配置。
* setDebugFlags(int)
* setEGLConfigChooser(boolean)
* setEGLConfigChooser(EGLConfigChooser)
* setEGLConfigChooser(int, int, int, int, int, int)
* setGLWrapper(GLWrapper)
定制android.view.Surface
GLSurfaceView默认会创建像素格式为PixelFormat.RGB_565的surface。如果需要透明效果,调用getHolder().setFormat(PixelFormat.TRANSLUCENT)。透明(TRANSLUCENT)的surface的像素格式都是32位,每个色彩单元都是8位深度,像素格式是设备相关的,这意味着它可能是ARGB、RGBA或其它。
选择EGL配置
Android设备往往支持多种EGL配置,可以使用不同数目的通道(channel),也可以指定每个通道具有不同数目的位(bits)深度。因此,在渲染器工作之前就应该指定EGL的配置。GLSurfaceView默认EGL配置的像素格式为RGB_656,16位的深度缓存(depth buffer),默认不开启遮罩缓存(stencil buffer)。
如果你要选择不同的EGL配置,请使用setEGLConfigChooser方法中的一种。
你可以调用调试方法setDebugFlags(int)或setGLWrapper(GLSurfaceView.GLWrapper)来自定义GLSurfaceView一些行为。在setRenderer方法之前或之后都可以调用调试方法,不过最好是在之前调用,这样它们能立即生效。
设置渲染器
总之,你必须调用setRenderer(GLSurfaceView.Renderer)来注册一个GLSurfaceView.Renderer渲染器。渲染器负责真正的GL渲染工作。
渲染器设定之后,你可以使用setRenderMode(int)指定渲染模式是按需(on demand)还是连续(continuous)。默认是连续渲染。
Activity生命周期
Activity窗口暂停(pause)或恢复(resume)时,GLSurfaceView都会收到通知,此时它的onPause方法和onResume方法应该被调用。这样做是为了让GLSurfaceView暂停或恢复它的渲染线程,以便它及时释放或重建OpenGL的资源。
为了处理事件,一般都是继承GLSurfaceView类并重载它的事件方法。但是由于GLSurfaceView是多线程操作,所以需要一些特殊的处理。由于渲染器在独立的渲染线程里,你应该使用Java的跨线程机制跟渲染器通讯。queueEvent(Runnable)方法就是一种相对简单的操作,例如下面的例子。
class MyGLSurfaceView extends GLSurfaceView {
private MyRenderer mMyR
public void start() {
mMyRenderer = ...;
setRenderer(mMyRenderer);
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
queueEvent(new Runnable() {
// 这个方法会在渲染线程里被调用
void run() {
mMyRenderer.handleDpadCenter();
return super.onKeyDown(keyCode, event);
(注:如果在UI线程里调用渲染器的方法,很容易收到“call to OpenGL ES API with no current context”的警告,典型的误区就是在键盘或鼠标事件方法里直接调用opengl es的API,因为UI事件和渲染绘制在不同的线程里。更甚者,这种情况下调用glDeleteBuffers这种释放资源的方法,可能引起程序的崩溃,因为UI线程想释放它,渲染线程却要使用它。)
&&&&推荐文章:
【上篇】【下篇】君,已阅读到文档的结尾了呢~~
基于j2ee的mmorpg 手机游戏框架的设计与实现
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
基于j2ee的mmorpg 手机游戏框架的设计与实现
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer--144.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口

我要回帖

更多关于 div渲染完毕 的文章

 

随机推荐