openg es egl笔记

来源:互联网 发布:mac快捷键重启 编辑:程序博客网 时间:2024/05/01 23:09

openg es egl笔记

opengl es: java端开发
// 导入类
import android.opengl.GLES20;
//函数调用加上GLES20.glxxx(), 类的静态函数形式调用
//GLSurfaceView集成了EGL部分,两个重要的接口setEGLContextClientVersion和setRenderer
//setEGLContextClientVersion用来设置OpenGL ES的版本, 如:OpenGL ES 2.0
/*
//Renderer
//public class GLRenderer implements Renderer {
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height) {}
@Override
public void onDrawFrame(GL10 gl) {}
}
*/
GLES20.glClearColor()
GLES20.glCreateProgram()

opengl es: jni端开发
// 包含相关头文件

#include <GLES2/gl2.h> #include <GLES2/gl2ext.h>#include <EGL/egl.h> // EGL 头文件

//函数调用, C语言风格使用, 与java端使用整体差别不大
//jni需增加EGL操作部分,搭建opengl es本地运行环境
glClearColor()
glCreateProgram()

OpenGL
OpenGL是和编程语言、平台无关的一套interface ,主要是为了rendering 2D 和 3D图形等。一般这套接口是用来和GPU进行交互的,使用GPU进行rendering硬件加速
(一个操作GPU的API,它通过驱动向GPU发送相关指令,控制图形渲染管线状态机的运行状态)
本地代码:
framework/base/opengl/libagl //Android提供的OpenGL软件库, 编译生成libGLES_android.so:
是一个由系统提供的纯软件3D加速库,可以兼容各种环境。包含一个EGL框架的实现和OpenGL各种API的实现。OpenGL的API底层是通过libpixelflinger.so库实现
libGLES_android.so提供了两种API:一种是egl实现API,另一种是OpenGL标准API。
Pixelflinger: 是Android系统中为OpenGL ES引擎提供的一套软件渲染器(renderer)
Pixelflinger作为软件渲染器,为OpenGL ES引擎提供了一系列基础绘图功能。这些功能包括定义各种颜色格式像素位置、画点画线、绘制矩形及三角形、填充纹理等等。
由于OpenGL ES相当于一个状态机,配置OpenGL ES状态的函数也均由Pixelflinger提供。
Pixelflinger的源代码:
system/core/libpixelflinger。
system/core/include/libpixelflinger
system/core/include/private/pixelflinger
JNI代码:
framework/base/core/jni/com_google_android_gles_jni_GLImpl.cpp
framework/base/core/jni/android_opengl_GLESXXX.cpp
Java代码:
framework/base/opengl/java/javax/microedition/khronos/opengles
framework/base/opengl/java/com/google/android/gles_jni/
framework/base/opengl/android/opengl

OpenGL支持Java层、JNI层开发,使用opengl函数时,首先利用egl的函数去构建本地环境,然后再使用opengl绘图
opengl在android中主要有2个用途:上层使用opengl render,即绘图, 下层surfaceflinger中使用opengl去做layer的合成

OpenGL的各种数据类型: 类似与GL***, 即以GL作前缀;
GLenum: 用于GL枚举的无符号整型。
GLboolean: 用于单布尔值。GL_TRUE和GL_FALSE
GLbyte: 有符号单字节整型,包含数值从-128 到 127
GLshort: 有符号双字节整型,包含数值从−32,768 到 32,767
GLint: 有符号四字节整型,包含数值从−2,147,483,648 到 2,147,483,647
GLsizei: 有符号四字节整型,用于代表数据的尺寸(字节),类似于C中的size_t
GLubyte: 无符号单字节整型,包含数值从0 到 255。
GLushort: 无符号双字节整型,包含数值从0 到 65,535
GLuint: 无符号四字节整型,包含数值从0 到 4,294,967,295
GLfloat: 四字节精度IEEE 754-1985 浮点数
GLclampf: 这也是四字节精度浮点数,但OpenGL使用GLclampf特别表示数值为0.0 到 1.0
GLvoid: void值用于指示一个函数没有返回值,或没有参数
GLfixed: 定点数 使用整型数存储实数。

EGL:
OpenGL ES和底层Native平台视窗系统之间的接口,是OpenGL ES和本地窗口的桥梁。
EGL API独立于OpenGL ES各版本标准的独立API,其主要作用是为OpenGL指令创建Context 、绘制目标Surface 、配置Framebuffer属性、Swap提交绘制结果等
它被用于处理图形管理、表面/缓冲捆绑、渲染同步及支援使用其他Khronos API进行的高效、加速、混合模式2D和3D渲染.
EGL主要用来管理绘图表面(Drawing surfaces),并提供如下的功能:
1、与本地窗口系统进行通信
2、查找绘图表面可用的类型和配置信息
3、创建绘图表面
4、同步OpenGL ES 2.0和其他的渲染API(Open VG、本地窗口系统的绘图命令等)
5、管理渲染资源,比如材质
OpenGL ES图形管线的状态被存储于EGL管理的一个Context中, 而Frame Buffers和其他绘制Surfaces通过 EGL API进行创建、管理和销毁。同时EGL也控制和提供了对设备显示和可能的设备渲染配置的访问
本地代码:
framework/base/opengl/libs/egl
Android EGL框架,负责加载OpenGL函数库和EGL本地实现, 编译生成libEGL.so
JNI代码:
framework/base/core/jni/com_google_android_gles_jni_EGLImpl.cpp //EGL本地代码的JNI调用接口
Java代码:
framework/base/opengl/java/javax/microedition/khronos/egl

Android OpenGL库加载和调用过程:
http://blog.sina.com.cn/s/blog_7213e0310102wzbn.html

EGL支持Java层、JNI层开发, EGL10、EGL11、EGL14几个版本,
Android 4.2(API 17)后使用的是EGL14, 可通过eglQueryString(display, EGL10.EGL_VERSION)进行查询:
EGL14设定EGL渲染类型API的参数: EGL_OPENGL_ES2_BIT // 支持opengl es 2.0
EGL10、EGL11只能手写的硬编码类型来指定: EGL_RENDERABLE_TYPE = 4; // 支持opengl es 2.0

EGL 数据类型
数据类型 值
EGLBoolean — EGL_TRUE =1, EGL_FALSE=0
EGLint/ — int 数据类型
EGLDisplay —系统显示 ID 或句柄
EGLConfig —Surface 的 EGL 配置
EGLSurface —系统窗口或 frame buffer 句柄
EGLContext —OpenGL ES 图形上下文
NativeDisplayType—Native 系统显示类型
NativeWindowType—Native 系统窗口缓存类型
NativePixmapType—Native 系统 frame buffer

OpenGL ES/EGL的初始化过程:
Application –>OpenGL Command–>EGLContext(Context)
EGLSurface<– EGLConfig <–EGLDisplay

平台编译后可使用的库:
//android中的egl库,可加载具体的平台(厂商)实现
system\lib\libEGL.so //用来加载具体的egl和opengl实现的,起到桥梁作用,需要和EGL实现的库区分开
//opengl具体实现的wrapper, 可加载具体的平台(厂商)实现
system\lib\libGLESv1_CM.so
system\lib\libGLESv2.so
//opengl软件实现,即agl, 包括egl、opengl es实现(硬件需求低,无gpu,无overlay,只能通过agl去合成layer的应用场景)
system\lib\egl\libGLES_android.so

//以下针对具体平台(厂商)egl、opengl es实现库:
//egl的实现
system\vendor\lib\egl\libEGL_adreno.so
//opengl硬件实现
system\vendor\lib\egl\libGLESv1_CM_adreno.so
system\vendor\lib\egl\libGLESv2_adreno.so

EGL主要数据结构
egl_object_t结构用来描述没一个elg对象。
egl_display_t结构用来存储get_display函数获取的物理显示设备。
egl_surface_t结构用来存储surface对象,系统可以同时拥有多个surface对象。
egl_context_t结构用用来存储OpenGL状态机信息。
egl_image_t结构用来存储EGLImage对象。

EGL操作流程
init流程:
ANativeWindow *mWin = ANativeWindow_fromSurface(env, jsurface);
EGLDisplay mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); // 1、获取显示设备
//EGLDisplay eglGetDisplay (NativeDisplayType display); //display 参数是native系统的窗口显示ID值
eglInitialize(mEglDisplay, &major, &minor); // 2、初始化显示设备、获取EGL版本号

EGLint config_attribs[] = {    EGL_BLUE_SIZE, 8,    EGL_GREEN_SIZE, 8,    EGL_RED_SIZE, 8,    EGL_RENDERABLE_TYPE, //指定渲染api类别, 这里或者是硬编码的4    EGL_OPENGL_ES2_BIT,  //或者是EGL14.EGL_OPENGL_ES2_BIT     EGL_SURFACE_TYPE,     EGL_WINDOW_BIT,    EGL_NONE};int num_configs = 0;EGLConfig   eglConfig;//3、获取满足attributes的所有config, EGLConfig---描述EGLSurface配置信息的数据类型(绘制目标framebuffer的配置属性)eglChooseConfig(mEglDisplay, config_attribs, &eglConfig, 1, &num_configs)) /*eglChooseConfig(display, attributes, configs, num, configNum); 功能:用于获取满足attributes的所有config参数1当前显示设备参数2需满足的attributes参数3用于存放输出的configs,参数4指定最多输出多少个config,参数5由EGL系统写入,表明满足attributes的config一共有多少个。如用eglChooseConfig(display, attributes, null, 0, configNum)形式调用,则会在configNum中输出所有满足条件的config个数。*///通过ANativeWindow 创建本地surface---EGLSurface,它是系统窗口或frame buffer句柄,可以理解为一个后端的渲染目标窗口EGLSurface mEglSurface = eglCreateWindowSurface(mEglDisplay, eglConfig, mWin, NULL); // 4、将Surface转换为本地窗口eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &mSurfaceWidth); // 5、查询高宽eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &mSurfaceHeight);EGLint context_attrib[] = {    EGL_CONTEXT_CLIENT_VERSION, 2,    EGL_NONE};//创建EGL环境, EGLContext: OpenGL ES图形上下文,它代表了OpenGL状态机EGLContext mEglContext = eglCreateContext(mEglDisplay, eglConfig, EGL_NO_CONTEXT, context_attrib); // 6、根据EGLConfig、context_attrib创建EGLContext//7、将EGLDisplay、EGLSurface和EGLContext进行绑定(渲染上下文绑定到渲染面,指定当前的环境为绘制环境 EGLContext->context)//eglMakeCurrent后生成的surface就可以利用opengl画图了eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext); 

render:
//双缓冲刷新 front buffer 和 back buffer
//eglSwapBuffers会去触发queuebuffer,dequeuebuffer,
//queuebuffer将画好的buffer(back->front)交给surfaceflinger处理,
//dequeuebuffer新创建一个buffer用来画图
eglSwapBuffers(mEglDisplay, mEglSurface);

release流程:
eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); //1、
eglDestroyContext(mEglDisplay, mEglContext); // 2、
eglDestroySurface(mEglDisplay, mEglSurface); // 3、
eglTerminate(mEglDisplay); // 4、

mEglDisplay = EGL_NO_DISPLAY; // 5、
mEglContext = EGL_NO_CONTEXT;
mEglSurface = EGL_NO_SURFACE;

opengl es 大致程序开发流程:
(opengl es绘制流程:读取顶点数据――执行顶点着色器――组装图元――光栅化图元――执行片段着色器――写入帧缓冲区――显示到屏幕上)
1、使用GLSL编写顶点着色器、片元着色器脚本
2、读取顶点着色器、片元着色器,创建着色器程序
glCreateShader(shaderType);
glShaderSource(shader, 1, &pSource, NULL);
glCompileShader(shader);
glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);

GLuint gProgram = glCreateProgram();
glAttachShader(program, vertexShader);
glAttachShader(program, pixelShader);
glLinkProgram(program);
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
3、获取着色器程序中的相关变量的引用
_phandle = glGetAttribLocation(gProgram, “vPosition”);

4、清屏、深度缓存等,传入顶点位置、纹理坐标、纹理单元等所需数据到着色器,由着色器程序完成绘制
glClearColor(0, 0, 0, 1.0f); //设置颜色,黑色
glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); //清除颜色缓冲、深度缓冲
glUseProgram(gProgram); // 使用着色器程序
glVertexAttribPointer(_phandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
// 将顶点位置数据传入渲染管线
glEnableVertexAttribArray(_phandle); //启用顶点位置数据
glDrawArrays(GL_TRIANGLES, 0, 3); //绘制

0 0
原创粉丝点击