A. android opengl es 2.0怎么学习
OpenGLES是一个让人崩溃的东西。在Andorid手机上做3D还就得用它。把我记的一些笔记分享在这里吧:
Android OpenGL ES简介 20011-6-3
Android系统使用OpenGL的标准接口来支持3D图形功能,android 3D图形系统也分为java框架和本地代码两部分。
本地代码主要实现的OpenGL接口的库,在Java框架层,javax.microedition.khronos.opengles是java标准的OpenGL包,
android.opengl包提供了OpenGL系统和Android GUI系统之间的联系。
Android的本地代码位于frameworks/base/opengl下,
JNI代码位于frameworks/base/core/com_google_android_gles_jni_GLImpl.cpp和frameworks/base/core/com_google_android_gles_jni_EGLImpl.cpp,
java类位于opengl/java/javax/microedition/khronos下
本地测试代码位于frameworks/base/opengl/tests。包括angeles、fillrate等14个测试代码,这些代码都可以通过终端进行本地调用测试(模拟器中使用adb shell)。
OpenGL ES 1.x
固定管线操作,支持glVertexPointer()等函数,不支持GLSL。头文件在ndk的GLES目录下,库文件是libGLESv1_CM.so。
OpenGL ES 2.x
可编程管线操作,不兼容1.x,不支持固定管线操作,例如glVertexPointer()等函数。支持GLSL(还必须用这个来编程)。头文件在ndk的GLES2目录下,库文件是libGLESv2.so。
OpenGL ES学习 2011-6-30
OpenGL定义了自己的数据类型。应该坚持使用这些OpenGL的数据类型,从而保证可移植性和效率。
OpenGL ES 目前不支持64位数据类型。
OpenGL ES 只支持三边形。
OpenGL ES 只支持gl开头的函数,glu库都不支持。
OpenGL ES 从 OpenGL中删除的功能:
1. glBegin/glEnd
2. glArrayElement
3. 显示列表
4. 求值器
5. 索引色模式
6. 自定义裁剪平面
7. glRect
8. 图像处理(这个一般显卡也没有,FireGL/Quadro显卡有)
9. 反馈缓冲
10. 选择缓冲
11. 累积缓冲
12. 边界标志
13. glPolygonMode
14. GL_QUADS,GL_QUAD_STRIP,GL_POLYGON
15. glPushAttrib,glPopAttrib,glPushClientAttrib,glPopClientAttrib
16. TEXTURE_1D、TEXTURE_3D、TEXTURE_RECT、TEXTURE_CUBE_MAP
17. GL_COMBINE
18. 自动纹理坐标生成
19. 纹理边界
20. GL_CLAMP、GL_CLAMP_TO_BORDER
21. 消失纹理代表
22. 纹理LOD限定
23. 纹理偏好限定
24. 纹理自动压缩、解压缩
25. glDrawPixels,glPixelTransfer,glPixelZoom
26. glReadBuffer,glDrawBuffer,glCopyPixels
OpenGL ES 2.0 2011-10-9
2.0和1.1不兼容。
- 2.0使用的头文件是ndk的include目录下的GLES2目录,有gl2.h,gl2ext.h,gl2platform.h,而1.1使用的是GLES目录。
- 2.0使用的库文件是ndk的lib目录下的libGLESv2.so,而1.1使用的是libGLESv1_CM.so。
- 2.0中取消了很多1.1函数,例如glMatrixModel和glLoadIdentity等。
OpenGL着色语言(GLSL――OpenGL Shading Language)
- 使用2.0,必须学此语言。因为很多1.1的函数都被取消了。
san-angeles NDK OpenGL ES 1.1的例子程序 2012-3-8
San Angeles,查维基网络,是一个虚构的未来概念城市,位于南加州。常在电影中出现,来源自Los Angeles和San Diego.
该程序的演示效果是,观察一个宏伟的城市,地面是镜面有建筑倒影,城市中有飞船飞过。前后有5、6个观察点,而且镜头在每个观察点不停的移动。
这个例子,用NDK(C++)调用OpenGL ES 1.1来绘制了San Angeles这个城市。基本上全部使用了NDK,Java程序只有1个。
用vc2005演示一下,目的通过跟踪代码了解一些细节。方法是:
- 将jni下所有的.h文件,以及demo.c,app-win32.c复制出来,放在一个专门的目录下,然后改造成用OpenGL的而不是ES的。(或者干脆删除大段的绘制代码,保证编译通过)
首先分析Java代码
- DemoActivity.java,这是唯一的Java文件,它主要需要下列4个jni的接口:
- private static native void nativeInit(); // 初始化
- private static native void nativeResize(int w, int h);
- private static native void nativeRender(); // 绘制1帧
- private static native void nativeDone();
其次分析C++代码 app-android.c
- 首先,调用了importGLInit(),动态导入OpenGL的库。
- 其次,调用了 appInit(),在内存中建立了平台无关的3D对象集合。建立方法是用一个数组,用类似画圆拔高的方式产生诸多三角形。
- 然后,在每个时钟周期中调用appRender(),细节是:
- prepareFrame(width, height); // 准备OpenGL ES绘制框架。其实就是清空颜色和深度缓冲,重置投影和模型矩阵。
- camTrack(); // 算好在当前时钟周期,镜头的位置、朝向及焦距等。然后调用gluLookAt来实现。
- configureLightAndMaterial(); // 设置光源和材质
- drawModels(-1); // 先绘制倒影(其实就是将所有模型z轴倒过来画)
- 第一个循环,是画精致的物体
- 第二个循环,是画运动的物体
- drawGroundPlane(); // 再绘制镜子一般的地面。在绘制前取消光照,打开混合,然后绘制。绘制后还原状态。
- drawModels(1); // 再绘制所有模型
- drawFadeQuad(); // 最后绘制淡出框,用融合的方式画一个遮住整个视口的2D框,融合系数和时间相关。
B. 如何查看android系统的openGL版本
android中查看手机系统的OpenGL版本,可以使用如下代码进行查询:
ActivityManageram=(ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
ConfigurationInfoinfo=am.getDeviceConfigurationInfo();
info.reqGlEsVersion=0x00010001//代表opengles1.1
info.reqGlEsVersion=0x00020000//代表opengles2.0
ActivityManager是Android框架的一个重要部分,它负责一新ActivityThread进程创建,Activity生命周期的维护。ActivityManagerProxy实现了接口IActivitManager,但并不真正实现这些方法,它只是一个代理类,真正动作的执行为Stub类ActivityManagerService,ActivityManagerService对象只有一个并存在于system_process进程中,ActivityManagerService继承于ActivityManagerNative存根类。
C. 为什么使用 android opengl
准备 为了开始本次的教程,你必须具备: 1.一款支持Android开发的IDE,如果你没有的话,可以在Android Developer website下载最新版本的Android studio。 2.一款运行Android4.0之上Android手机,并且GPU支持OpenGL ES2.0 3.对OpenGL的基本知识了解 设置OpenGL ES环境 创建GLSurfaceView 为了显示OpenGL的图形,你需要使用GLSurfaceView类,就像其他任何的View子类意义,你可以将它添加到你的Activity或Fragment之上,通过在布局xml文件中定义或者在代码中创建实例。 在本次的教程中,我们使用GLSurfaceView作为唯一的View在我们的Activity中,因此,为了简便,我们在代码中创建 GLSurfaceView的实例并将其传入setContentView中,这样它将会填充你的整个手机屏幕。Activity中的onCreate方 法如下: protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GLSurfaceView view = new GLSurfaceView(this); setContentView(view); }123456123456 因为媒体效果的框架仅仅支持OpenGL ES2.0及以上的版本,所以在setEGLContextClientVersion 方法中传入2; view.setEGLContextClientVersion(2);11 为了确保GLSurfaceView仅仅在必要的时候进行渲染,我们在setRenderMode 方法中进行设置: view.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);11 创建Renderer Renderer负责渲染GLSurfaceView中的内容。 创建类实现接口GLSurfaceView.Renderer,在这里我们打算将这个类命名为EffectsRenderer,添加构造函数并覆写接口中的抽象方法,如下: public class EffectsRenderer implements GLSurfaceView.Renderer { public EffectsRenderer(Context context){ super(); } @Override public void onSurfaceCreated(GL10 gl, EGLConfig config) { } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { } @Override public void onDrawFrame(GL10 gl) { } } 回到Activity中调用setRenderer方法,让GLSurfaceView使用我们创建的Renderer: view.setRenderer(new EffectsRenderer(this));11 编写Manifest文件 如果你想要发布你的App到谷歌商店,在AndroidManifest.xml文件中添加如下语句: <uses-feature android:glEsVersion="0x00020000" android:required="true" />11 这会确保你的app只能被安装在支持OpenGL ES2.0的设备之上。现在OpenGL环境准备完毕。 创建一个OpenGL平面 定义顶点 GLSurfaceView是不能直接显示一张照片的,照片首先应该被转化为纹理,应用在OpenGL square之上。在本次教程中,我将创建一个2D平面,并且具有4个顶点。为了简单,我将使用一个长方形,现在,创建一个新的类Square,用它来代表形状。 public class Square { }123123 默认的OpenGL系统的坐标系中的原点是在中心,因此4个角的坐标可以表示为: 左下角: (-1, -1) 右下角:(1, -1) 右上角:(1, 1) 左上角:(-1, 1) 我们使用OpenGL绘制的所有的物体都应该是由三角形决定的,为了画一个方形,我们需要两个具有一条公共边的三角形,那意味着这些三角形的坐标应该是: triangle 1: (-1, -1), (1, -1), 和 (-1, 1) triangle 2: (1, -1), (-1, 1), 和 (1, 1) 创建一个float数组来代表这些顶点: private float vertices[] = { -1f, -1f, 1f, -1f, -1f, 1f, 1f, 1f, };123456123456
D. android opengl es与surfaceview什么关系
1.SurfaceFlinger是一个服务,主要是负责合成各窗口的Surface,然后通过OpenGLES显示到FrameBuffer上。 2.DisplayHardware是对显示设备的抽象,包括FrameBuffer和Overlay。加载FrameBuffer和Overlay插件,并初始化OpenGLES: view plain mNativeWindow = new FramebufferNativeWindow(); framebuffer_device_t const * fbDev = mNativeWindow->getDevice(); if (hw_get_mole(OVERLAY_HARDWARE_MODULE_ID, &mole) == 0) { overlay_control_open(mole, &mOverlayEngine); } surface = eglCreateWindowSurface(display, config, mNativeWindow.get(), NULL); eglMakeCurrent(display, surface, surface, context); 3.FramebufferNativeWindow 是framebuffer 的抽象,它负责加载libgralloc,并打开framebuffer设备。FramebufferNativeWindow并不直接使用 framebuffer,而是自己创建了两个Buffer: queueBuffer负责显示一个Buffer到屏幕上,它调用fb->post去显示。 dequeueBuffer获取一个空闲的Buffer,用来在后台绘制。 这两个函数由eglSwapBuffers调过来,调到 view plain egl_window_surface_v2_t::swapBuffers: nativeWindow->queueBuffer(nativeWindow, buffer); nativeWindow->dequeueBuffer(nativeWindow, &buffer); 4.msm7k/liboverlay是Overlay的实现,与其它平台不同的是,高通平台上的Overlay并不是提供一个framebuffer设备,而通过fb0的ioctl来实现的,ioctl分为两类操作: OverlayControlChannel用于设置参数,比如设置Overlay的位置,宽度和高度: view plain bool OverlayControlChannel::setPosition(int x, int y, uint32_t w, uint32_t h) { ov.dst_rect.x = x; ov.dst_rect.y = y; ov.dst_rect.w = w; ov.dst_rect.h = h; ioctl(mFD, MSMFB_OVERLAY_SET, &ov); } OverlayDataChannel用于显示Overlay,其中最重要的函数就是queueBuffer: view plain bool OverlayDataChannel::queueBuffer(uint32_t offset) { mOvData.data.offset = offset; ioctl(mFD, MSMFB_OVERLAY_PLAY, odPtr)) } 5.msm7k/libgralloc 是显示缓存的抽象,包括framebuffer和普通Surface的Buffer。framebuffer只是/dev/graphic/fb0的包 装,Surface的Buffer则是对/dev/pmem、ashmem和GPU内存(msm_hw3dm)的包装,它的目标主要是方便硬件加速,因为 DMA传输使用物理地址,要求内存在物理地址上连续。 6.msm7k/libbit这是2D加速库,主要负责Surface的拉伸、旋转和合成等操作。它有两种实现方式: bit.cpp: 基于fb0的ioctl(MSMFB_BLIT)的实现。 bit_c2d.cpp: 基于kgsl的实现,只是对libC2D2.so的包装,libC2D2.so应该是不开源的。 7.pmem misc/pmem.c: 对物理内存的管理,算法和用户空间的接口。 board-msm7x27.c定义了物理内存的缺省大小: view plain #define MSM_PMEM_MDP_SIZE 0x1B76000 #define MSM_PMEM_ADSP_SIZE 0xB71000 #define MSM_PMEM_AUDIO_SIZE 0x5B000 #define MSM_FB_SIZE 0x177000 #define MSM_GPU_PHYS_SIZE SZ_2M #define PMEM_KERNEL_EBI1_SIZE 0x1C00 msm_msm7x2x_allocate_memory_regions分配几大块内存用于给pmem做二次分配。 8.KGSL Kernel Graphics System Layer (KGSL),3D图形加速驱动程序,源代码drivers/gpu/msm目录下,它是对GPU的包装,给OpenGLES 2.0提供抽象的接口。 9.msm_hw3dm 这个我在内核中没有找到相关代码。 10.msm_fb msm_fb.c: framebuffer, overlay和blit的用户接口。 mdp_dma.c: 对具体显示设备的包装,提供两种framebuffer更新的方式: mdp_refresh_screen: 定时更新。 mdp_dma_pan_update: 通过pan display主动更新。 mdp_dma_lcdc.c:针对LCD实现的显示设备,mdp_lcdc_update用更新framebuffer。
E. Android OpenGL 的基本使用
由于本人现在在公司做Android上的OpenGL图像处理相关功能,以前没有搞过这方面的知识,所以一切只能从头开始搞起,接下来将会慢慢分享其他方面的内容,先用这篇比较基础的文章来开头。
刚才我们谈到图像处理,在做图像处理我们不是可以用Canvas来绘制吗,怎么还要用OpenGL那么陌生的东西来搞?为什么要用OpenGL,肯定有它的好处。
接下来我们会来讲解如何在Android项目开发过程中加入OpenGL,在开始前我们先了解同OpenGL ES密切相关的载体:GLSurfaceView:
要用OpenGL绘制,首先要有GLSurfaceVie的实例
现在OpenGL ES版本已经到3.0了,Android平台上目前有1.0和2.0,我们使用的是2.0,在使用前在onCreate()方法中检查是否支持2.0的版本并且确定使用2.0
一般我们只需要使用“configurationInfo.reqGlEsVersion >= 0x20000”,至于加后面主要是用于模拟器检查,假定模拟器支持2.0。
前面说到GLSurfaceView挖了一个洞,就是为了看见下面的渲染表面,同样实在onCreate()方法中
通过setEGLContextClientVersion()方法配置surface视图,设定好使用的OpenGL版本,然后调用setRenderer()传进有自定义Renderer类的新实例。当Surface创建或者发生变化的时候,以及绘制一幅新帧时,渲染器都会被GLSurfaceView调用。
GLSurfaceView的生命周期要协同好Activity的生命周期,避免造成内存泄漏。
Renderer类也就是我们的渲染类了,它是通过实现Renderer接口来实现功能的。
渲染器接口定义的方法:
实现Renderer的接口方法
首选在onSurfaceCreated()中调用glClearColor设置清空屏幕用的颜色,这里使用红色。
设置视口的大小
在onDrawFrame()中调用glClear(GL_COLOR_BUFFER_BIT)清空屏幕,会调用glClearColor中定义的颜色来填充整个屏幕。通过这几个步骤,基本上就可以在GLSurfaceView绘制出东西了,在这里我只是简单的用红色绘制整个屏幕。
OpenGL在Android上的使用基本上是这样,但是,当然没那么简单,在使用OpenGL进行绘制算是比较繁琐的过程,后面也会慢慢去揭晓其他使用方法,来构造一幅一幅精美的特效静/动图。
F. 手机openGl是什么意思
编程作图