绘制2D图形
文章目录
- 绘制2D图形
- 1、OpenGL ES在Android中涉及的关键类
- 1.1、GLSurfaceView
- 1.2、GLSurfaceView.Renderer 接口
- 1.3、 GL api 调用
1、OpenGL ES在Android中涉及的关键类
Android框架中有两个基础类,可让我们使用OpenGL ES API创建和操作图形:GLSurfaceView和 GLSurfaceView.Renderer。
1.1、GLSurfaceView
GLSurfaceView从Android 1.5(API level 3)开始加入,继承自SurfaceView,实现了SurfaceHolder.Callback2接口,拥有SurfaceView的全部特性,也有view所有的功能和属性,特别是处理事件的能力,它主要是在SurfaceView的基础上它加入了EGL的管理,并自带了一个GLThread绘制线程(EGLContext创建GL环境所在线程即为GL线程),绘制的工作直接通过OpenGL在绘制线程进行,不会阻塞主线程,绘制的结果输出到SurfaceView所提供的Surface上,这使得GLSurfaceView也拥有了OpenGL ES所提供的图形处理能力。
1.2、GLSurfaceView.Renderer 接口
GLSurfaceView.Renderer 接口定义了使用 OpenGL 绘图时所需的方法。该接口通过 GLSurfaceView.setRenderer() 与 GLSurfaceView 关联在一起
GLSurfaceView.Renderer 定义了一个统一图形绘制的接口,它定义了如下三个接口函数:
⭐️ onSurfaceCreated(GL10 gl, EGLConfig config):当创建 GLSurfaceView 对象后,该方法被系统调用一次。通常在该方法中设置 OpenGL 环境的相关参数,初始化 OpenGL 图形对象等,执行一些无须改变的初始化操作。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
⭐️ onDrawFrame(GL10 gl):GLSurfaceView 对象每一次重绘时系统都会调用该方法。该方法应该执行具体的绘图工作。
⭐️ onSurfaceChanged(GL10 gl, int width, int height):当 GLSurfaceView 对象的几何外形改变时,包括 GLSurfaceView 的尺寸发生改变、设备屏幕的方向发生改变等情况,该方法被系统调用。

1.3、 GL api 调用
GL10就是OpenGL ES的绘图接口,但实际上也是GL11的实例,可通过(gl Instansof GL11)判断它是否为GL11接口的实例。
⭐️ glEnable(int cap)启用服务器端GL功能。glEnable方法和glDisable方法可以启用和禁止各种功能,各种功能(除了GL_DITHER和GL_MULTISAMPLE)的初始值为GL_FALSE。
⭐️**glDisable(int cap):**禁用服务器端GL功能。例如,要关闭抗抖动功能,可以使用gl.glDisable(GL10.GL_DITHER);
例如:
-
GL_ALPHA_TEST 如果启用,将进行alpha 测试
-
GL_DEPTH_TEST 如果启用,将进行深度测试;就是让OpenGL ES负责跟踪每个物体在Z轴上的深度,这样就可避免后面的物体遮挡前面的物体。
-
GL_BLEND 如果启用,将引入的值与颜色缓冲区中的值混合
⭐️**glHint (int target, int mode):**该方法用于对OpenGL ES某方法进行修正。
⭐️ glClearColor (float red, float green, float blue, float alpha):用于指定清除屏幕时使用的颜色,4个参数分别用于设置红、绿、蓝和透明度的值,值的范围是0.0f~1.0f。例如设置gl.glClearColor(0 , 0 , 0 , 0):就是用黑色“清屏”。
⭐️ **glShadeMode(int mode):**该方法用于设置OpenGL ES的着色。
⭐️glViewport(int x , int y , int width , int height):设置3D视窗的位置与大小。其中前两个参数指定该视窗的位置,后两个参数指定该视窗的宽、高。
⭐️ glMatrixMode (int mode)😗***设置视图的矩阵模型。通常可接受GL10.GL_PROJECTION、GL10.GL_MODEVIEW两个常量值。
当调用glMatrixMode(GL10.GL_PROJECTION):代码后,指定将屏幕视为透视图(要想看到逼真的三维物体,这是必要的),这意味着越远的东西看起来越小;当调用glMatrixMode(GL10.GL_MODEVIEW):代码后,即将当前矩阵模式设为模型视图矩阵,这意味着任何新的变换都会影响该矩阵中的所有物体。
⭐️**glLoadIdentity():**相当于reset()方法,用于初始化单位矩阵。
⭐️ **glFrustumf (float left , float right , float bottom , float top , float zNear , float zFar):**用于设置透视投影的空间大小。前路两个参数用于设置X轴上的最小坐标值、最大坐标值;中间两个参数用于设置Y轴上的最小坐标值、最大坐标值;后面两个参数用于设置Z轴上所能绘制的场景的深度的最小值、最大值。
⭐️ glClear (int mask):清理缓冲区,并设置为预设值。
glClear可以使参数为多个值按位与后的结果,以表明那个缓冲区需要清理。有如下值:
🌵 GL_COLOR_BUFFER_BIT:表明颜色缓冲区。
🌵 GL_DEPTH_BUFFER_BIT:表明深度缓冲区。
🌵 GL_STENCIL_BUFFER_BIT:表明模型缓冲区。
⭐️ glEnableClientState (int array):启用客户端的某项功能。glEnableClientState和glDisableClientState启用或禁用客户端的单个功能。默认的,所有客户端功能禁用。
array可以是下列符号常量:
🌵 GL_COLOR_ARRAY 颜色矩阵。
🌵 GL_NORMAL_ARRAY 法线矩阵。
🌵 GL_TEXTURE_COORD_ARRAY 纹理坐标矩阵。
🌵 GL_VERTEX_ARRAY 顶点矩阵。
🌵 GL_POINT_SIZE_ARRAY_OES(OES_point_size_arrayextension) 点大小矩阵。
glEnable和glEnableClientState的区别
两者的区别应该说是服务端和客户端的区别,glEnable和glDisable是管理服务端功能,glEnableClientState 和glDisableClientState是管理客户端功能。
-
客户端:计算机上的具体程序,包括它用到的内存等等
-
服务端:计算机显卡里的OpenGL“模块”,乃至整张拥有OpenGL流水线、硬件实现OpenGL功能的显卡
⭐️glColor4f (float red,float green,float blue,float alpha):设置当前颜色。
🌵red为当前颜色指明一个新的红色值,初始值为1。
🌵 green 为当前颜色指明一个新的绿色值,初始值为1。
🌵 blue 为当前颜色指明一个新的蓝色值,初始值为1。
🌵 alpha 为当前颜色指明一个新的alpha值,初始值为1。
opengl中的RGBA颜色
glColor系列函数可以用于设置颜色,其中三个参数的版本可以指定R、G、B的值,而A值采用默认;四个参数的版本可以分别指定R、G、B、A的值
例如:
void glColor3f(GLfloat red, GLfloat green, GLfloat blue);void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
将浮点数作为参数,其中0.0表示不使用该种颜色,而1.0表示将该种颜色用到最多。
注意:glColor系列函数,在参数类型不同时,表示“最大”颜色的值也不同。
-
采用f和d做后缀的函数,以1.0表示最大的使用。
-
采用b做后缀的函数,以127表示最大的使用。
-
采用ub做后缀的函数,以255表示最大的使用。
-
采用s做后缀的函数,以32767表示最大的使用。
-
采用us做后缀的函数,以65535表示最大的使用。
⭐️ glVertexPointer (int size,int type,int stride,Buffer pointer):定义一个顶点坐标矩阵。如果顶点矩阵功能启用,当调用glDrawArrays方法或glDrawElements方法时会使用。想要启用或禁止顶点矩阵,使用glEnableClientState或glDisableClientState方法,并以GL_VERTEX_ARRAY为参数。顶点矩阵初始为禁止,调用glDrawArrays方法或glDrawElements方法时无效。
🌵 size 每个顶点的坐标维数,必须是2, 3或者4,初始值是4。
🌵 type 指明每个顶点坐标的数据类型,允许的符号常量有GL_BYTE, GL_SHORT, GL_FIXED和GL_FLOAT,初始值为GL_FLOAT。
🌵 stride 指明连续顶点间的位偏移,也就是连续顶点间的字节排列方式,即<从一个数据的开始到下一个数据的开始所相隔的字节数>,为0表示数组中的顶点被认为按照紧凑方式排列,初始值为0。
🌵 pointer 指定了数组中第一个顶点的首地址(通常是数组名)。
跨距(stride)
有一个坐标数组和颜色数组,如果将坐标数组和颜色数组合并在一起,那么坐标和颜色的数据就在一个数组了
GLfloat data[]= {1.0, 0.0, 0.0,25.0,25.0, 1.0, 0.0, 0.0,100.0,100.0, 0.0, 1.0, 0.0,120.0,120.0, 0.0, 1.0, 0.0,200.0,200.0};glEnableClientState(GL_VERTEX_ARRAY);glEnableClientState(GL_COLOR_ARRAY);glColorPointer(3,GL_FLOAT,5*sizeof(GLfloat),&data[0]);glVertexPointer(2,GL_FLOAT,5*sizeof(GLfloat),&data[3]);
第3个参数指定跨距,如颜色,从数组的每组数据的第1个开始取数据,然后跨5个,坐标顶点则从数据每组数据的第4个开始取数据并跨5个
注意:由于跨距需要计算数据类型,所以数组的数据类型需要相同
⭐️ **glColorPointer(int size,int type,int stride,Bufferpointer):**定义一个颜色矩阵。
🌵 size 指明每个颜色的元素数量,必须为4。
🌵type指明每个矩阵中颜色元素的数据类型,允许的符号常量有GL_UNSIGNED_BYTE, GL_FIXED和GL_FLOAT,初始值为GL_FLOAT。
🌵stride指明连续的点之间的位偏移,如果stride为0时,颜色被紧密挤入矩阵,初始值为0。
🌵 pointer指明包含颜色的缓冲区,如果pointer为null,则为设置缓冲区。
⭐️ **glDrawArrays(int mode,int first,int count):**由矩阵数据渲染图元。可以设置独立的顶点、法线、颜色矩阵,以及纹理坐标,并仅需调用glDrawArrays就可以通过它们构建一系列图元。
🌵 mode 指明渲染哪一种图元。
允许的符号常量有
**GL_POINTS:**把每一个顶点作为一个点进行处理,顶点n即定义了点n,共绘制n个点。

**GL_LINES:**把每一对顶点被解释为一条直线,顶点2n-1和2n之间共定义了n个线段,总共绘制N/2条线段。如果N为奇数,则忽略最后一个顶点。

**GL_LINE_STRIP:**绘制从第一个顶点到最后一个顶点依次相连的一组线段,第n和n+1个顶点定义了线段n,总共绘制N-1条线段。

**GL_LINE_LOOP:**绘制从定义第一个顶点到最后一个顶点依次相连的一组线段,然后最后一个顶点与第一个顶点相连。第n和n+1个顶点定义了线段n,然后最后一个线段是由顶点N和1之间定义,总共绘制N条线段。

**GL_TRIANGLES:**把每三个顶点作为一个独立的三角形。顶点3n-2,3n-1和3n定义了第n个三角形,总共绘制N/3个三角形。

**GL_TRIANGLE_STRIP:**绘制一组相连的三角形。对于奇数点n,顶点n,n+1和n+2定义了第n个三角形;对于偶数n,顶点n+1,n和n+2定义了第n个三角形,总共绘制N-2个三角形。这是最常使用的渲染方式,第一个三角形条是由前三个顶点构成(索引0,1, 2)。第二个三角形条是由前一个三角形的两个顶点加上数组中的下一个顶点构成,继续直到整个数组结束。以V0V1V2,V1V2V3,V2V3V4,……的形式绘制

**GL_TRIANGLE_FAN:**绘制一组相连的三角形。三角形是由第一个顶点及其后给定的顶点所确定。顶点1,n+1和n+2定义了第n个三角形,总共绘制N-2个三角形。以V0V1V2,V0V2V3,V0V3V4,…的形式绘制三角形;

-
first 指明在允许访问的矩阵中的起始索引。
-
count 指明要渲染的索引的数量。
⭐️ **glDrawElements(int mode,int count,int type,Buffer indices):**由矩阵数据渲染图元。glDrawElements 方法还是需要传递顶点数据,但只需要传递物体实际上的顶点数据,也就是最少的,不重复的顶点数据。然后再向渲染管线传递要绘制的顶点数据的索引,根据索引从顶点数据中取出对应的顶点,然后再按照指定的方式进行绘制。当glDrawElements被调用,它会使用有序索引来查询可用矩阵中的元素,并以此创建序列几何图元,如果GL_VERTEX_ARRAY被禁用,则不会创建。
-
mode 指明被渲染的是哪种图元
-
count 指明被渲染的元素个数
-
type 指明索引指的类型,不是GL_UNSIGNED_BYTE就是GL_UNSIGNED_SHORT。
-
indices 指明存储索引的位置指针。
glDrawArrays和glDrawElements区别
glDrawArrays传输或指定的数据是最终的真实数据,在绘制时效能更好
glDrawElements指定的是真实数据的调用索引,在内存/显存占用上更节省
比如画一个由2个3角形组成的正方形,左上角坐标是l,t,右下角坐标是r,b
使用glDrawArrays绘制时,画2个三角形,需要这样传:
(l,t),(r,t),(l,b)(r,t),(r,b),(l,b){-1 , 1 , 0 ,
-1 ,-1 , 0 ,1 ,-1 , 0 ,-1, 1 , 0 ,1, 1 , 0 ,1, -1 , 0}
而用glDrawElements画可以这样
float coord[4][2]={{l,t},{r,t},{r,b},{l,b}};
绘制时:
0,1,3
1,2,3
在利用glDrawElements时候只需记住所有定点,在第四个参数中来秒数所需面的顶点顺序即可,且每取三个点绘图一个三角形