android es中的openGL es...

Android中的OpenGL ES简介 - CSDN博客
Android中的OpenGL ES简介
OpenGL ES软件层次栈,本章介绍了Android系统中OpenGL ES的调用层次栈,详细分析了库之间如何通过钩子(hook)实现API调用关联,让我们明白各个库之间的依赖关系。本节为Android中的OpenGL ES简介。
Android中的OpenGL ES简介
Android支持使用OpenGL(Open Graphics Library)API进行2D和3D图形的绘制 ,尤其使用OpenGL ES(Embedded System) API。OpenGL是一个跨平台的图形API规范,它为3D图形处理硬件定义了一套标准的软件接口。OpenGL ES是在OpenGL API的基础上专为嵌入式设备选取的一套API规范。自早期的版本Android 1.0就开始支持OpenGL ES 1.0和1.1规范,自Android 2.2版本开始支持OpenGL ES 2.0规范。Android提供的OpenGL
ES API类似于J2ME JSR239标准,但不同。
我们既可通过Android Framework中提供的API,也可以通过Native层(Native Development Kit ,NDK)的API去使用OpenGL。开发者可以使用Framework中两个基本的类GLSurfaceView和GLSurfaceView。Renderer在Android应用程序中进行图形绘制操作,也就是在Renderer中使用OpenGL API在GLSurfaceView上进行绘制,具体如何使用它们,详见官方文档 、 。
在使用GLSurfaceView和GLSurfaceView.Renderer进行绘制时,可以使用下面这些OpenGL ES API包。
(1)包javax.microedition.khronos.opengles提供OpenGL ES 1.0/1.1标准实现,可以使用的API类包括:GL10、 GL10Ext、 GL11、 GL11Ext和GL11ExtensionPack。
(2)包android.opengl,提供了一套静态函数接口,包括OpenGL ES 1.0/1.1和2.0,其性能优于包javax.microedition.khronos.opengles。支持OpenGL ES 1.0/1.1的类包括:GLES10、 GLES10Ext、 GLES11和GLES10Ext;支持OpenGL ES 2.0的API类是:android.opengl.GLES20 (自Android 2.2开始)。
由于Android支持OpenGL ES 1.0/1.1、2.0,且由于二者有显著差异。那么该选择哪个版本呢?在本节参考的Google文档里的&Choosing an OpenGL API Version&部分列出了四项因素,介绍如下。
(1)性能 :通常,OpenGL ES 2.0能比ES 1.0/1.1提供较快的性能。但是,这最终依赖于Android设备,不同的设备平台OpenGL的实现不同。
(2)设备兼容性:开发者开发的应用程序需要考虑Android设备类型,不同的Android版本对OpenGL版本支持不同,如OpenGL ES 2.0自Android 2.2才开始支持。
(3)编码便利性:OpenGL ES 1.0/1.1 API编程较为方便,2.0版本相对复杂些。
(4)图形控制:通过使用shaders,OpenGL ES 2.0对图形绘制能提供较多的控制,可以创建更好的效果,在1.0/1.1版本上则很难达到。
本文已收录于以下专栏:
相关文章推荐
Github项目地址好久没有更新了,不行不行,怎么可以太监呢(`⌒´メ)滤镜结构滤镜主要是对于图像的处理,关于一款滤镜的制作方法可以看这里既然是图像处理,那么滤镜的操作就主要是:卷积、像素映射、坐标映...
回到目录最近需要做短按拍照,长按录像功能,虽然长按只需要LongClickListener就好了,但是要同时做出动画效果。
在网上转了一圈,发现仿微信长按录像的不少,例如这个,但是仿FaceU的好像...
在网上看到android不透明度对应的值,记录一下 方便以后做项目查看
不透明度16进制值
不透明度 16进制值
100% — FF
97% — F7
...
It’s a collection of references while I’m working on my own project
Omoshiroi —— a fully-featured C...
在android中使用OpenGL ES需要三个步骤:
1. 创建GLSurfaceView组件,使用Activity来显示GLSurfaceView组建。
2. 为GLSurfaceView组建...
@page { margin: 0.79in }
PRE.cjk { font-family: &WenQuanYi Micro Hei&, monospace }
对于很多初学者,视图投影之类非常的难理解,然而这个东西非常非常的重要,如果不是非常清楚,根本无法定位3D Object(空间坐标)和观察角度(观察角度不一样,效果就不一样),自己阅博无数,发现了一篇非...
@page { margin: 0.79in }
PRE.western { font-family: &Courier New&, monospace }
PRE.cjk { ...
Android Lollipop 增加了Camera2 API,并将原来的Camera API标记为废弃了。相对原来的Camera API来说,Camera2是重新定义的相机 API,也重构了相机 A...
他的最新文章
讲师:吴岸城
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)博客分类:
最近在学习OpenGL ES,上网看了一些资料,有一些比较好的资料,在此分享一下!:)
Android OpenGL ES 简明开发教程
Android OpenGL ES 开发教程
wangleyiang
浏览: 108478 次
为什么我的TestHall里面看不到RomeA RomeB R ...
uyerp 写道这样的话,只能将插件的元素显示到Hall中。有 ...
这样的话,只能将插件的元素显示到Hall中。有什么办法能在不安 ...
提高文学修养 写道不好意思,有时间尝试一下,谢谢!有问题提出来 ...
不好意思,有时间尝试一下,谢谢!
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'android graphic(14)—EGL和OpenGL ES之间的关系 - CSDN博客
android graphic(14)—EGL和OpenGL ES之间的关系
什么是OpenGL?
Open Graphics Library (OpenGL) is a cross-language, cross-platform application programming interface (API) for rendering 2D and 3D vector graphics. The API is typically used to interact with a graphics processing unit (GPU), to achieve hardware-accelerated rendering.
OpenGL是和编程语言、平台无关的一套interface ,主要是为了rendering 2D 和 3D图形等。一般这套接口是用来和GPU进行交互的,使用GPU进行rendering 硬件加速。 说白了OpenGL就是一组函数名,类似java中的interface,并不能直接用。
什么是OpenGL ES?
Android includes support for high performance 2D and 3D graphics with the Open Graphics Library (OpenGL(R)), specifically, the OpenGL ES API. OpenGL is a cross-platform graphics API that specifies a standard software interface for 3D graphics processing hardware. OpenGL ES is a flavor of the OpenGL specification intended for embedded devices.
OpenGL ES就是专为嵌入式设备设计的,当然手机也是嵌入式设备,那么OpenGL ES和OpenGL中的函数接口肯定有一些是不一样的,因为嵌入式设备和pc等的硬件处理能力还是有差距的,不然手机卡死了。
既然OpenGL ES只是一组函数接口,那么如何使用呢?我们肯定首先要去实现这些函数接口,而android提供了两种类型的实现:软件实现,硬件实现。
a, 硬件实现,前面提到这组函数接口主要是为了和GPU这个硬件进行打交道的。所以各个硬件厂商会提供相关的实现,例如高通平台的adreno解决方案;
b,软件实现,android也提供了一套OpenGL ES的软件实现,就是说不用GPU了,完全用软件实现画图的相关功能,也就是libagl,代码在frameworks\native\opengl\libagl,其makefile中,
LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/egl
LOCAL_MODULE:= libGLES_android
到此,已经有了OpenGL ES的具体实现了,但是由于其实现的平台无关性,所以在android上还不能使用,必须借助EGL。
EGL - Native Platform Interface
EGL? is an interface between Khronos rendering APIs such as OpenGL ES or OpenVG and the underlying native platform window system.
It handles graphics context management, surface/buffer binding, and rendering synchronization and enables high-performance, accelerated, mixed-mode 2D and 3D rendering using other Khronos APIs.
那么什么是EGL?EGL是OpenGL ES和底层的native window system之间的接口,承上启下。
EGL is a complement to OpenGL ES. EGL is used for getting surfaces to render to using functions like eglCreateWindowSurface, and you can then draw to that surface with OpenGL ES. Its role is similar to GLX/WGL/CGL.
Whether or not EGL can give you a context that supports OpenGL ES 2.0 may vary by platform, but if the Android device supports ES 2.0 and EGL, you should be able to get such a context from EGL. Take a look at the EGL_RENDERABLE_TYPE attribute and the EGL_OPENGL_ES2_BIT when requesting an EGLConfig.
在Android上,EGL完善了OpenGL ES。利用类似eglCreateWindowSurface的EGL函数可以创建surface 用来render ,有了这个surface你就能往这个surface中利用OpenGL ES函数去画图了。
下面看个实际例子,一般EGL和OpenGL ES使用时都会先利用egl函数(egl开头)创建opengl本地环境,然后再利用opengl函数(gl开头)去画图。
下面是开机动画BootAnimation中的实现,首先是创建本地环境,
status_t BootAnimation::readyToRun() {
sp&SurfaceControl& control = session()-&createSurface(String8("BootAnimation"),
dinfo.w, dinfo.h, PIXEL_FORMAT_RGB_565);
SurfaceComposerClient::openGlobalTransaction();
control-&setLayer(0x);
SurfaceComposerClient::closeGlobalTransaction();
sp&Surface& s = control-&getSurface();
const EGLint attribs[] = {
EGL_RED_SIZE,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE,
EGL_DEPTH_SIZE, 0,
EGLint w, h,
EGLint numC
EGLSurface surface;
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(display, 0, 0);
eglChooseConfig(display, attribs, &config, 1, &numConfigs);
surface = eglCreateWindowSurface(display, config, s.get(), NULL);
context = eglCreateContext(display, config, NULL, NULL);
eglQuerySurface(display, surface, EGL_WIDTH, &w);
eglQuerySurface(display, surface, EGL_HEIGHT, &h);
if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE)
return NO_INIT;
return NO_ERROR;
egl创建好环境后,调用gl相关命令去画图,注意eglSwapBuffers(mDisplay, mSurface) 函数是非常重要的一个函数,会去触发queueBuffer和dequeueBuffer,图画就一副一副的画出来了。
bool BootAnimation::android()
initTexture(&mAndroid[0], mAssets, "images/android-logo-mask.png");
initTexture(&mAndroid[1], mAssets, "images/android-logo-shine.png");
glShadeModel(GL_FLAT);
glDisable(GL_DITHER);
glDisable(GL_SCISSOR_TEST);
glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
eglSwapBuffers(mDisplay, mSurface);
glEnable(GL_TEXTURE_2D);
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
const GLint xc = (mWidth
- mAndroid[0].w) / 2;
const GLint yc = (mHeight - mAndroid[0].h) / 2;
const Rect updateRect(xc, yc, xc + mAndroid[0].w, yc + mAndroid[0].h);
glScissor(updateRect.left, mHeight - updateRect.bottom, updateRect.width(),
updateRect.height());
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
const nsecs_t startTime = systemTime();
nsecs_t now = systemTime();
double time = now - startT
float t = 4.0f * float(time / us2ns(16667)) / mAndroid[1].w;
GLint offset = (1 - (t - floorf(t))) * mAndroid[1].w;
GLint x = xc -
glDisable(GL_SCISSOR_TEST);
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_SCISSOR_TEST);
glDisable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, mAndroid[1].name);
glDrawTexiOES(x,
yc, 0, mAndroid[1].w, mAndroid[1].h);
glDrawTexiOES(x + mAndroid[1].w, yc, 0, mAndroid[1].w, mAndroid[1].h);
glEnable(GL_BLEND);
glBindTexture(GL_TEXTURE_2D, mAndroid[0].name);
glDrawTexiOES(xc, yc, 0, mAndroid[0].w, mAndroid[0].h);
EGLBoolean res = eglSwapBuffers(mDisplay, mSurface);
if (res == EGL_FALSE)
const nsecs_t sleepTime = 83333 - ns2us(systemTime() - now);
if (sleepTime & 0)
usleep(sleepTime);
checkExit();
} while (!exitPending());
glDeleteTextures(1, &mAndroid[0].name);
glDeleteTextures(1, &mAndroid[1].name);
return false;
EGL加载OpenGL ES库
从上面的例子中,我们发现通过egl*函数调用后,直接就能调用gl*函数去画图了,为何?难道在egl*函数调用过程中,已经将opengl相关实现的库加载了吗?
首先,由于涉及的库较多,先列出来(高通平台,原生的只有前4个),
system\lib\libEGL.so
system\lib\libGLESv1_CM.so
system\lib\libGLESv2.so
system\lib\egl\libGLES_android.so
system\vendor\lib\egl\libEGL_adreno.so
system\vendor\lib\egl\libGLESv1_CM_adreno.so
system\vendor\lib\egl\libGLESv2_adreno.so
继续以bootanimation为例,在bootanimation的makefile中,使用了libEGL 库,
LOCAL_SHARED_LIBRARIES := \
libcutils \
libandroidfw \
libutils \
libbinder \
libGLESv1_CM \
LOCAL_MODULE:= bootanimation
在frameworks\native\opengl\libs\Android.mk中,定义了libEGL.so,makefile中并未指定特殊的存放path,所以最终生成的库保存在system\lib\libEGL.so,这个库是用来加载具体的egl和opengl实现的,起到桥梁作用,需要和EGL实现的库区分开。
//frameworks\native\opengl\libs\Android.mk
include $(CLEAR_VARS)
LOCAL_SRC_FILES:=
EGL/egl_tls.cpp
EGL/egl_cache.cpp
EGL/egl_display.cpp
EGL/egl_object.cpp
EGL/egl.cpp
EGL/eglApi.cpp
EGL/trace.cpp
EGL/getProcAddress.cpp.arm \
EGL/Loader.cpp
LOCAL_MODULE:= libEGL
include $(BUILD_SHARED_LIBRARY)
接下来看eglGetDisplay(),这个函数就是在system\lib\libEGL.so中实现的。
EGLDisplay eglGetDisplay(EGLNativeDisplayType display)
clearError();
uint32_t index = uint32_t(display);
if (index &= NUM_DISPLAYS) {
return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
if (egl_init_drivers() == EGL_FALSE) {
return setError(EGL_BAD_PARAMETER, EGL_NO_DISPLAY);
EGLDisplay dpy = egl_display_t(display);
EGLBoolean egl_init_drivers() {
pthread_mutex_lock(&sInitDriverMutex);
res = egl_init_drivers_locked();
pthread_mutex_unlock(&sInitDriverMutex);
static EGLBoolean egl_init_drivers_locked() {
if (sEarlyInitState) {
return EGL_FALSE;
Loader& loader(Loader());
egl_connection_t* cnx = &gEGLI
if (cnx-&dso == 0) {
cnx-&hooks[egl_connection_t] =
&gHooks[egl_connection_t];
cnx-&hooks[egl_connection_t] =
&gHooks[egl_connection_t];
cnx-&dso = loader.open(cnx);
return cnx-&dso ? EGL_TRUE : EGL_FALSE;
egl_connection_t gEGLI
gl_hooks_t gHooks[2];
struct egl_connection_t {
GLESv1_INDEX = 0,
GLESv2_INDEX = 1
inline egl_connection_t() : dso(0) { }
gl_hooks_t *
struct egl_t {
#include "EGL/egl_entries.in"
struct gl_hooks_t {
struct gl_t {
#include "entries.in"
struct gl_ext_t {
__eglMustCastToProperFunctionPointerType extensions[MAX_NUMBER_OF_GL_EXTENSIONS];
EGL/egl_entries.in文件中都是如下的一条一条entry,以egl开头,都是函数声明,
EGL_ENTRY(EGLDisplay, eglGetDisplay, NativeDisplayType)
entries.in文件中,都是以gl开头的entry,都是函数声明,
GL_ENTRY(void, glActiveShaderProgramEXT, GLuint pipeline, GLuint program)
从下面的宏可以看出,转换完成后,上面的entry都是返回值,函数名,函数参数的型式。
#undef GL_ENTRY
#undef EGL_ENTRY
#define GL_ENTRY(_r, _api, ...) _r (*_api)(__VA_ARGS__);
#define EGL_ENTRY(_r, _api, ...) _r (*_api)(__VA_ARGS__);
struct egl_t {
EGLDisplay eglGetDisplay(NativeDisplayType );
struct gl_t {
glActiveShaderProgramEXT(GLuint pipeline, GLuint program);
下面看cnx-&dso = loader.open(cnx),
void* Loader(egl_connection_t* cnx)
driver_t* hnd = 0;
dso = load_driver("GLES", cnx, EGL | GLESv1_CM | GLESv2);
if (dso) {
hnd = new driver_t(dso);
dso = load_driver("EGL", cnx, EGL);
if (dso) {
hnd = new driver_t(dso);
hnd-&set( load_driver("GLESv1_CM", cnx, GLESv1_CM), GLESv1_CM );
hnd-&set( load_driver("GLESv2",
cnx, GLESv2),
LOG_ALWAYS_FATAL_IF(!hnd, "couldn't find an OpenGL ES implementation");
cnx-&libGles2 = load_wrapper("/system/lib/libGLESv2.so");
cnx-&libGles1 = load_wrapper("/system/lib/libGLESv1_CM.so");
LOG_ALWAYS_FATAL_IF(!cnx-&libGles2 || !cnx-&libGles1,
"couldn't load system OpenGL ES wrapper libraries");
return (void*)
void *Loader::load_driver(const char* kind,
egl_connection_t* cnx, uint32_t mask)
class MatchFile {
static String8 find(const char* kind) {
pattern.appendFormat("lib%s", kind);
const char* const searchPaths[] = {
"/vendor/lib/egl",
"/system/lib/egl"
for (size_t i=0 ; i&NELEM(searchPaths) ; i++) {
if (find(result, pattern, searchPaths[i], true)) {
pattern.append("_");
for (size_t i=0 ; i&NELEM(searchPaths) ; i++) {
if (find(result, pattern, searchPaths[i], false)) {
result.clear();
static bool find(String8& result,
const String8& pattern, const char* const search, bool exact) {
if (checkGlesEmulationStatus() == 0) {
ALOGD("Emulator without GPU support detected. "
"Fallback to software renderer.");
result.setTo("/system/lib/egl/libGLES_android.so");
return true;
if (exact) {
String8 absoluteP
absolutePath.appendFormat("%s/%s.so", search, pattern.string());
if (!access(absolutePath.string(), R_OK)) {
result = absoluteP
return true;
return false;
DIR* d = opendir(search);
if (d != NULL) {
struct dirent*
while (readdir_r(d, &cur, &e) == 0 && e) {
if (e-&d_type == DT_DIR) {
if (!strcmp(e-&d_name, "libGLES_android.so")) {
if (strstr(e-&d_name, pattern.string()) == e-&d_name) {
if (!strcmp(e-&d_name + strlen(e-&d_name) - 3, ".so")) {
result.clear();
result.appendFormat("%s/%s", search, e-&d_name);
closedir(d);
return true;
closedir(d);
return false;
String8 absolutePath = MatchFile::find(kind);
if (absolutePath.isEmpty()) {
const char* const driver_absolute_path = absolutePath.string();
void* dso = dlopen(driver_absolute_path, RTLD_NOW | RTLD_LOCAL);
if (dso == 0) {
const char* err = dlerror();
ALOGE("load_driver(%s): %s", driver_absolute_path, err?err:"unknown");
ALOGD("loaded %s", driver_absolute_path);
if (mask & EGL) {
getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress");
ALOGE_IF(!getProcAddress,
"can't find eglGetProcAddress() in %s", driver_absolute_path);
egl_t* egl = &cnx-&
__eglMustCastToProperFunctionPointerType* curr =
(__eglMustCastToProperFunctionPointerType*)
char const * const * api = egl_
while (*api) {
char const * name = *
__eglMustCastToProperFunctionPointerType f =
(__eglMustCastToProperFunctionPointerType)dlsym(dso, name);
if (f == NULL) {
f = getProcAddress(name);
if (f == NULL) {
f = (__eglMustCastToProperFunctionPointerType)0;
if (mask & GLESv1_CM) {
init_api(dso, gl_names,
(__eglMustCastToProperFunctionPointerType*)
&cnx-&hooks[egl_connection_t::GLESv1_INDEX]-&gl,
getProcAddress);
if (mask & GLESv2) {
init_api(dso, gl_names,
(__eglMustCastToProperFunctionPointerType*)
&cnx-&hooks[egl_connection_t::GLESv2_INDEX]-&gl,
getProcAddress);
需要使用opengl函数的进程,首先加载system\lib\libEGL.so共享库,调用库中的eglGetDisplay()函数来加载具体opengl的实现;
b, 如果系统中只有opengl的软件实现,也就是只找到system\lib\egl\libGLES_android.so,那么egl和opengl的实现都在libGLES_android.so库中。虽然4.4已经不使用这个库了(代码中直接忽略),但是我接触过一个平台,硬件需求低,无gpu,无overlay,只能通过agl去合成layer,所以还是有使用价值的;
c, 如果系统中有GPU,同时找到了egl的实现库system\vendor\lib\egl\libEGL_adreno.so,opengl的实现库system\vendor\lib\egl\libGLESv1_CM_adreno.so,system\vendor\lib\egl\libGLESv2_adreno.so,这就使用的是opengl的硬件实现。
d, 使用opengl函数时,首先利用egl的函数去构建本地环境,然后再使用opengl绘图。
e, 关于opengl在android中主要有2个用途:上层使用opengl render,即绘图;下层surfaceflinger中使用opengl去做layer的合成,后续将继续分析layer的合成,其中还将牵扯到fence。
本文已收录于以下专栏:
相关文章推荐
本文介绍:EGL接口与初始化介绍,Android系统上EGL的一些理解
一.EGL 介绍
通俗上讲,OpenGL是一个操作GPU的API,它通过驱动向GPU发送相关指令,控制图形渲染管线状态机的运...
前面已经在android平台上使用OpenGL ES的API了解了如何创建3D图形已经使用FBO渲染到纹理进行一些其他的操作,起初我学习OpenGL ES的目的就是为了研究Android平台上录制屏幕...
OpenGL、OpenGL ES、OpenVG、GLX、EGL简介
图形方面一直是软肋,以后得找个图形方面的task来熟悉。
转自:/view/...
转载地址:/kiffa/archive//2921123.html?utm_source=tuicool&utm_medium=refe...
OpenGL ES图形库最终的结果是在二维平面上显示3D物体(常称作模型Model)这是因为目前的打部分显示器还只能显示二维图形。但我们在构造3D模型时必须要有空间现象能力,所有对模型的描述还是使用三...
Linux的图形系统真是复杂到深不可测,我很怀疑是否大学可以开个课程,用一个学期来讲清楚。例如,最近看资料看到的EGL/GLX/Xegl/XGL/XGLX,感觉是字母G、E、L、X几个字母在排列组合,...
本文简单介绍了EGL, Native API 和 3D API之间的关系
zhuanzaizhhttp://blog.csdn.net/xiaowei_cqu/article/details/8470376
他的最新文章
讲师:吴岸城
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)

我要回帖

更多关于 android es 的文章

 

随机推荐