把Android原生的View渲染到OpenGL Texture.docx_第1页
把Android原生的View渲染到OpenGL Texture.docx_第2页
把Android原生的View渲染到OpenGL Texture.docx_第3页
把Android原生的View渲染到OpenGL Texture.docx_第4页
把Android原生的View渲染到OpenGL Texture.docx_第5页
已阅读5页,还剩18页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

把Android原生的View渲染到OpenGL Texture最近要把Android 原生的View渲染到OpenGL GLSurfaceView中,起初想到的是截图的方法,也就是把View截取成bitmap后,再把Bitmap渲染到OpenGL中;但是明显这种方法是不可行的,面对一些高速动态更新的View,只有不停的对view 进行截图才能渲染出原生View的效果。通过大量的Google终于在国外的网站找到了一个做过类似的先例。不过经过测试该方法只能渲染直接父类为View的view,也就是只能渲染一层View(如progressbar,没不能添加child的view),当该原生Android View包含很多子view时(也就是根View为FramLayout、或者linearLayout之类),无法实时的监听到View动态改变,OpenGL中只能不停的渲染该view,才能渲染出原生View的效果。但是这样一来不同的渲染会耗费大量的资源,降低应用程序的效率。理想中的话,是监听到了该View的内容或者其子view 的内容发生了变化(如:View中的字幕发生滚动)才进行渲染。经过接近两周的努力我终于完美地实现了该效果,既然是站在别人的基础上得来的成果,那么该方法就应当被共享,所以产生了此文,不过只支持api 15以上的步骤一:重写根View1.设置该View 绘制自己:java view plain copy 在CODE上查看代码片派生到我的代码片setWillNotDraw(false);2.监听View的变化,重写View,用ViewTreeObServer来监听,方法如下:java view plain copy 在CODE上查看代码片派生到我的代码片private void addOnPreDrawListener() if (Build.VERSION.SDK_INT = Build.VERSION_CODES.HONEYCOMB) final ViewTreeObserver mObserver = getViewTreeObserver();if (mObserver != null) mObserver.addOnPreDrawListener(new OnPreDrawListener() Overridepublic boolean onPreDraw() if (isDirty() /View或者子view发生变化invalidate();return true;);3.重写该View的onDraw方法:java view plain copy 在CODE上查看代码片派生到我的代码片Overrideprotected void onDraw(Canvas canvas) try if (mSurface != null) Canvas surfaceCanvas = mSurface.lockCanvas(null);super.dispatchDraw(surfaceCanvas);mSurface.unlockCanvasAndPost(surfaceCanvas);mSurface.release();mSurface = null;mSurface = new Surface(mSurfaceTexture); catch (OutOfResourcesException e) e.printStackTrace();步骤二:GLSurfaceView.Rendererjava view plain copy 在CODE上查看代码片派生到我的代码片class CustomRenderer implements GLSurfaceView.Renderer int glSurfaceTex;private final int GL_TEXTURE_EXTERNAL_OES = 0x8D65;long currentTime;long previousTime;boolean b = false;int frameCount = 0;DirectDrawer mDirectDrawer;ActivityManager activityManager;MemoryInfo _memoryInfo;/ Fixed valuesprivate int TEXTURE_WIDTH = 360;private int TEXTURE_HEIGHT = 360;Context context;private LauncherAppWidgetHostView addedWidgetView;private SurfaceTexture surfaceTexture = null;private Surface surface;float fps;public CustomRenderer(Context context, LauncherAppWidgetHostView addedWidgetView, Display mDisplay)this.context = context;this.addedWidgetView = addedWidgetView;TEXTURE_WIDTH = mDisplay.getWidth();TEXTURE_HEIGHT = mDisplay.getHeight();_memoryInfo = new MemoryInfo();activityManager = (ActivityManager) context.getApplicationContext().getSystemService(Context.ACTIVITY_SERVICE);Overridepublic void onDrawFrame(GL10 gl) synchronized (this) surfaceTexture.updateTexImage();activityManager.getMemoryInfo(_memoryInfo);GLES20.glClearColor(0.0f, 0.0f, 1.0f, 1.0f);GLES20.glClear(GLES20.GL_DEPTH_BUFFER_BIT | GLES20.GL_COLOR_BUFFER_BIT);GLES20.glEnable(GLES20.GL_BLEND);GLES20.glBlendFunc(GLES20.GL_ONE, GLES20.GL_ONE_MINUS_SRC_ALPHA);float mtx = new float16;surfaceTexture.getTransformMatrix(mtx);mDirectDrawer.draw(mtx);calculateFps();/getAppMemorySize();/getRunningAppProcessInfo();/Log.v(onDrawFrame, FPS: + Math.round(fps) + , availMem: + Math.round(_memoryInfo.availMem / 1048576) + MB);private void getAppMemorySize()ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);android.os.Debug.MemoryInfo memoryInfos = mActivityManager.getProcessMemoryInfo(new intandroid.os.Process.myPid();int size = memoryInfos0.dalvikPrivateDirty;Log.w(getAppMemorySize, size / 1024 + MB);private void getRunningAppProcessInfo() ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);/获得系统里正在运行的所有进程List runningAppProcessesList = mActivityManager.getRunningAppProcesses();for (RunningAppProcessInfo runningAppProcessInfo : runningAppProcessesList) / 进程ID号int pid = runningAppProcessInfo.pid;/ 用户IDint uid = runningAppProcessInfo.uid;/ 进程名String processName = runningAppProcessIcessName;/ 占用的内存int pids = new int pid;Debug.MemoryInfo memoryInfo = mActivityManager.getProcessMemoryInfo(pids);int memorySize = memoryInfo0.dalvikPrivateDirty;System.out.println(processName=+processName+,currentPid: + pid= +android.os.Process.myPid()+-+pid+,uid=+uid+,memorySize=+memorySize+kb);Overridepublic void onSurfaceCreated(GL10 gl, EGLConfig config) surface = null;surfaceTexture = null;glSurfaceTex = Engine_CreateSurfaceTexture(TEXTURE_WIDTH, TEXTURE_HEIGHT);Log.d(GLES20Ext, glSurfaceTex + glSurfaceTex);if (glSurfaceTex 0) surfaceTexture = new SurfaceTexture(glSurfaceTex);surfaceTexture.setDefaultBufferSize(TEXTURE_WIDTH, TEXTURE_HEIGHT);surface = new Surface(surfaceTexture);addedWidgetView.setSurface(surface);addedWidgetView.setSurfaceTexture(surfaceTexture);/addedWidgetView.setSurfaceTexture(surfaceTexture);mDirectDrawer = new DirectDrawer(glSurfaceTex);float calculateFps() frameCount+;if (!b) b = true;previousTime = System.currentTimeMillis();long intervalTime = System.currentTimeMillis() - previousTime;if (intervalTime = 1000) b = false;fps = frameCount / (intervalTime / 1000f);frameCount = 0;Log.w(calculateFps, FPS: + fps);return fps;int Engine_CreateSurfaceTexture(int width, int height) /* Create our texture. This has to be done each time the surface is* created.*/int textures = new int1;GLES20.glGenTextures(1, textures, 0);glSurfaceTex = textures0;if (glSurfaceTex 0) GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, glSurfaceTex);/ Notice the use of GL_TEXTURE_2D for texture creationGLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGB, width, height, 0, GLES20.GL_RGB, GLES20.GL_UNSIGNED_BYTE, null);GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);GLES20.glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);return glSurfaceTex;Overridepublic void onSurfaceChanged(GL10 gl, int width, int height) java view plain copy 在CODE上查看代码片派生到我的代码片public class DirectDrawer private final String vertexShaderCode =attribute vec4 vPosition; +attribute vec2 inputTextureCoordinate; +varying vec2 textureCoordinate; +void main() +gl_Position = vPosition;+textureCoordinate = inputTextureCoordinate; +;private final String fragmentShaderCode =#extension GL_OES_EGL_image_external : requiren+precision mediump float; +varying vec2 textureCoordinate;n +uniform samplerExternalOES s_texture;n +void main() + gl_FragColor = texture2D( s_texture, textureCoordinate );n +;private FloatBuffer vertexBuffer, textureVerticesBuffer;private ShortBuffer drawListBuffer;private final int mProgram;private int mPositionHandle;private int mTextureCoordHandle;private short drawOrder = 0, 1, 2, 0, 2, 3 ; / order to draw vertices/ number of coordinates per vertex in this arrayprivate static final int COORDS_PER_VERTEX = 2;private final int vertexStride = COORDS_PER_VERTEX * 4; / 4 bytes per vertexstatic float squareCoords = -1.0f, 0.0f,-1.0f, -2.2f,1.0f, -2.2f,1.0f, 0.0f,;static float textureVertices = 0f, 0f,0f, 1f,1f, 1f,1f, 0f,;private int texture;public DirectDrawer(int texture)this.texture = texture;/ initialize vertex byte buffer for shape coordinatesByteBuffer bb = ByteBuffer.allocateDirect(squareCoords.length * 4);bb.order(ByteOrder.nativeOrder();vertexBuffer = bb.asFloatBuffer();vertexBuffer.put(squareCoords);vertexBuffer.position(0);/ initialize byte buffer for the draw listByteBuffer dlb = ByteBuffer.allocateDirect(drawOrder.length * 2);dlb.order(ByteOrder.nativeOrder();drawListBuffer = dlb.asShortBuffer();drawListBuffer.put(drawOrder);drawListBuffer.position(0);ByteBuffer bb2 = ByteBuffer.allocateDirect(textureVertices.length * 4);bb2.order(ByteOrder.nativeOrder();textureVerticesBuffer = bb2.asFloatBuffer();textureVerticesBuffer.put(textureVertices);textureVerticesBuffer.position(0);int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode);int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode);mProgram = GLES20.glCreateProgram(); / create empty OpenGL ES ProgramGLES20.glAttachShader(mProgram, vertexShader); / add the vertex shader to programGLES20.glAttachShader(mProgram, fragmentShader); / add the fragment shader to programGLES20.glLinkProgram(mProgram); / creates OpenGL ES program executablespublic void draw(float mtx)GLES20.glUseProgram(mProgram);GLES20.glActiveTexture(GLES20.GL_TEXTURE0);GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, texture);/ get handle to vertex shaders vPosition membermPositionHandle = GLES20.glGetAttribLocation(mProgram, vPosition);/ Enable a handle to the triangle verticesGLES20.glEnableVertexAttribArray(mPositionHandle);/ Prepare the coordinate dataGLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, vertexBuffer);mTextureCoordHandle = GLES20.glGetAttribLocation(mProgram, inputTextureCoordinate);GLES20.glEnableVertexAttribArray(mTextureCoordHandle);/ textureVerticesBuffer.clear();/ textureVerticesBuffer.put( transformTextureCoordinates(/ textureVertices, mtx );/ textureVerticesBuffer.position(0);GLES20.glVertexAttribPointer(mTextureCoordHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, textureVerticesBuffer);GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length, GLES20.GL_UNSIGNED_SHORT, drawListBuffer);/ Disable vertex arrayGLES20.glDisableVertexAttribArray(mPositionHandle);GLES20.glDisableVertexAttribArray(mTextureCoordHandle);private int loadShader(int type, String shaderCode)/ create a vertex shader type (GLES20.GL_VERTEX_SHADER)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论