openGL对基本几何图形的定义
2017-09-05 23:10
274 查看
通常在二维空间中可以绘制点,线,多边形,圆弧,路径等。而OpenGL ES 支持的基本几何图形有三种: 点 、 线段、 三角形。 也就是在OpenGLEs中,任何其他的图形都可以通过这三种基本图形构造出来。比如通常来讲 复杂的3D图形,都需要将其分割成细小的三角形,然后构造出一个3d的基本模体,继而通过处理颜色,添加纹理,添加光照来构造出3d的图形效果。点,线,三角形都是通过顶点 (vertexs)来定义的,即顶点数组。在平面上,将多个孤立的点通过线段连接起来就可以构造出线段(line
segment)或者三角形(triangle)。
下面是几种openglES定义的几种模式:
GL_POINTS :绘制独立的点
GL_LINE_STRIP :绘制一系列线段。
GL_LINE_LOOP : 封闭曲线。
GL_LINES:顶点两两连接,为多条线段构成。
GL_TRIANGLES : 每隔三个顶点构成一个三角形,为多个三角形组成。
GL_TRIANGLE_STRIP :每相邻三个顶点组成一个三角形,为一系列相接三角形构成。
GL_TRIANGLE_FAN : 以一个点为三角形公共顶点,组成一系列相邻的三角形。
以上模式对应到 Android 渲染方法:
OpenGL ES 提供了两类方法来绘制一个空间几何图形:
public abstract void glDrawArrays(int mode, int first, int count)
使用 VetexBuffer 来绘制,顶点的顺序由 vertexBuffer 中的顺序指定。下面是glDrawArrays() 方法的使用说明:
功能:由矩阵数据渲染图元。
详细:
glDrawArrays通过很少的子程序调用指明多层几何图元。你可以设置独立的顶点、法线、颜色矩阵,以及纹理坐标,并仅需调用glDrawArrays就可以通过它们构建一系列图元。
当glDrawArrays被调用,它从被允许访问的矩阵中计算连续count个元素来构建一系列几何图元,从first元素开始。mode指明哪一种图元将被构建及矩阵元素怎样构建这些图元。如果GL_VERTEX_ARRAY没有启用,则不会有图元产生。
当glDrawArrays返回后,由glDrawArrays改变的顶点属性会得到一个未指明的值。举个例子,如果GL_COLOR_ARRAY被启用,则glDrawArrays执行后当前颜色的值是未定义的。未改变的属性仍然是已定义的。
错误:
如果mode不是被允许的值,将会产生GL_INVALID_ENUM。
如果count是负数,将会产生GL_INVALID_VALUE。
参数:
mode——指明渲染哪一种图元。允许的符号常量有GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP,GL_TRIANGLE_FAN和GL_TRIANGLES。
first——指明在允许访问的矩阵中的起始索引。
count——指明要渲染的索引的数量。
抛出:
java.lang.ArrayIndexOutOfBoundsException——如果序列中任一索引first至first + count – 1,导致引用出界。这个序列包括当前顶点、颜色、法线、纹理坐标,点大小,矩阵索引,或加权矩阵。
publicabstract void glDrawElements(int mode, int count, int type, Buffer indices)
,可以重新定义顶点的顺序,顶点的顺序由 indices Buffer 指定。
功能:由矩阵数据渲染图元。
详细:
glDrawElements用少量调用指明多重几何图元,你可以事先指明独立的顶点、法线、颜色和纹理坐标矩阵并且可以通过调用glDrawElements方法来使用它们创建序列图元。
当glDrawElements被调用,它会使用有序索引来查询可用矩阵中的元素,并以此创建序列几何图元,如果GL_VERTEX_ARRAY被禁用,则不会创建。
顶点属性由glDrawElements修改,glDrawElements在返回后会有一个未指明的值。举一个例子,如果GL_COLOR_ARRAY启用,当执行glDrawElements方法后,当前颜色的值是未定义的,属性不会维持它之前的值。
错误:
如果mode的值不被允许,将产生GL_INVALID_ENUM。
如果type的值不被允许,将产生GL_INVALID_ENUM。
如果count是负数,将产生GL_INVALID_VALUE。
参数:
mode——指明被渲染的是哪种图元,被允许的符号常量有GL_POINTS,GL_LINE_STRIP,GL_LINE_LOOP,GL_LINES,GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN和GL_TRIANGLES
count——指明被渲染的元素个数。
type——指明索引指的类型,不是GL_UNSIGNED_BYTE就是GL_UNSIGNED_SHORT。
indices——指明存储索引的位置指针。
抛出:
java.lang.IllegalStateException——如果最近一次调用glBindBuffer方法以GL_ELEMENT_ARRAY_BUFFER为目标时,有一个非0缓冲区参数。
java.lang.IllegalArgumentException——如果索引为空。
java.lang.ArrayIndexOutOfBoundsException——如果索引序列中从0到count-1中任意索引超出现有索引或数据矩阵范围。
其中 mode 为上述解释顶点的模式,如下面定义三个顶点坐标,并把它们存放在 FloatBuffer
中:
float[] vertexArray = new float[]{
-0.8f , -0.4f * 1.732f ,0.0f ,
0.8f , -0.4f * 1.732f ,0.0f ,
0.0f , 0.4f * 1.732f ,0.0f ,
};
ByteBuffer vbb=ByteBuffer.allocateDirect(vertexArray.length*4);
vbb.order(ByteOrder.nativeOrder());
FloatBuffer vertex = vbb.asFloatBuffer();
vertex.put(vertexArray);
vertex.position(0);
有了顶点的定义,下面就可以通过打开 OpenGL ES
管道(Pipeline)的相应开关将顶点参数传给 OpenGL
库:
打开顶点开关和关闭顶点开关的方法如下:
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
...
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
在打开顶点开关后,将顶点坐标传给 OpenGL 管道的方法为:glVertexPointer:
public void glVertexPointer(int size,int type,int stride,Bufferpointer)
· size:每个顶点坐标维数,可以为2,3,4。
· type:顶点的数据类型,可以为 GL_BYTE, GL_SHORT, GL_FIXED,或 GL_FLOAT,缺省为浮点类型 GL_FLOAT。
· stride:每个相邻顶点之间在数组中的间隔(字节数),缺省为 0,表示顶点存储之间无间隔。
· pointer:存储顶点的数组。
应用用上可以般顶点的颜色值存放在对应顶点后面,如下图,RGB 采用 4 字节表示,此时相邻顶点就不是连续存放的,stride 值为 4 。
对应顶点除了可以为其定义坐标外,还可以指定颜色,材质,法线(用于光照处理)等。
glEnableClientState 和 glDisableClientState
可以控制的 pipeline 开关可以有:GL_COLOR_ARRAY (颜色),GL_NORMAL_ARRAY (法线),GL_TEXTURE_COORD_ARRAY (材质),GL_VERTEX_ARRAY(顶点), GL_POINT_SIZE_ARRAY_OES等。
对应的传入颜色,顶点,材质,法线的方法如下:
glColorPointer(int size,int type,int stride,Buffer pointer)
glVertexPointer(int size, int type, int stride, Buffer pointer)
glTexCoordPointer(int size, int type, int stride, Bufferpointer)
glNormalPointer(int type, int stride, Buffer pointer)
如果需要使用三角形来构造复杂图形,可以使用 GL_TRIANGLE_STRIP 或 GL_TRIANGLE_FAN 模式,另外一种是通过定义顶点序列:
如下图定义了一个正方形:
对应的顶点和 buffer 定义代码:
private short[] indices = { 0, 1, 2, 0, 2, 3 };
//To gain some performance we also put this ones in a bytebuffer.
// short is 2 bytes, therefore we multiply the number ifvertices with 2.
ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
ibb.order(ByteOrder.nativeOrder());
ShortBuffer indexBuffer = ibb.asShortBuffer();
indexBuffer.put(indices);
indexBuffer.position(0);
定义三角形的顶点的顺序很重要在拼接曲面的时候,用来定义面的顶点的顺序非常重要,因为顶点的顺序定义了面的朝向(前向或是后向),为了获取绘制的高性能,一般情况不会绘制面的前面和后面,只绘制面的“前面”。虽然“前面”“后面”的定义可以应人而易,但一般为所有的“前面”定义统一的顶点顺序(顺时针或是逆时针方向)。
下面代码设置逆时针方法为面的“前面”:
gl.glFrontFace(GL10.GL_CCW);
打开 忽略“后面”设置:
gl.glEnable(GL10.GL_CULL_FACE);
明确指明“忽略“哪个面的代码如下:
gl.glCullFace(GL10.GL_BACK);
看到这里,搞明白了一件事情,就是opengles 1.0 和 2.0 的区别,
所以,到这里可以基本终止这次资源的学习了,因为目前在操作的是opengl es1.0 的api,和opengles 2.0 是完全不同的实现,也没有任何的集成兼容关系:)。
鸣谢:http://wiki.jikexueyuan.com/project/opengl-es-basics/
segment)或者三角形(triangle)。
下面是几种openglES定义的几种模式:
GL_POINTS :绘制独立的点
GL_LINE_STRIP :绘制一系列线段。
GL_LINE_LOOP : 封闭曲线。
GL_LINES:顶点两两连接,为多条线段构成。
GL_TRIANGLES : 每隔三个顶点构成一个三角形,为多个三角形组成。
GL_TRIANGLE_STRIP :每相邻三个顶点组成一个三角形,为一系列相接三角形构成。
GL_TRIANGLE_FAN : 以一个点为三角形公共顶点,组成一系列相邻的三角形。
以上模式对应到 Android 渲染方法:
OpenGL ES 提供了两类方法来绘制一个空间几何图形:
public abstract void glDrawArrays(int mode, int first, int count)
使用 VetexBuffer 来绘制,顶点的顺序由 vertexBuffer 中的顺序指定。下面是glDrawArrays() 方法的使用说明:
功能:由矩阵数据渲染图元。
详细:
glDrawArrays通过很少的子程序调用指明多层几何图元。你可以设置独立的顶点、法线、颜色矩阵,以及纹理坐标,并仅需调用glDrawArrays就可以通过它们构建一系列图元。
当glDrawArrays被调用,它从被允许访问的矩阵中计算连续count个元素来构建一系列几何图元,从first元素开始。mode指明哪一种图元将被构建及矩阵元素怎样构建这些图元。如果GL_VERTEX_ARRAY没有启用,则不会有图元产生。
当glDrawArrays返回后,由glDrawArrays改变的顶点属性会得到一个未指明的值。举个例子,如果GL_COLOR_ARRAY被启用,则glDrawArrays执行后当前颜色的值是未定义的。未改变的属性仍然是已定义的。
错误:
如果mode不是被允许的值,将会产生GL_INVALID_ENUM。
如果count是负数,将会产生GL_INVALID_VALUE。
参数:
mode——指明渲染哪一种图元。允许的符号常量有GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP,GL_TRIANGLE_FAN和GL_TRIANGLES。
first——指明在允许访问的矩阵中的起始索引。
count——指明要渲染的索引的数量。
抛出:
java.lang.ArrayIndexOutOfBoundsException——如果序列中任一索引first至first + count – 1,导致引用出界。这个序列包括当前顶点、颜色、法线、纹理坐标,点大小,矩阵索引,或加权矩阵。
publicabstract void glDrawElements(int mode, int count, int type, Buffer indices)
,可以重新定义顶点的顺序,顶点的顺序由 indices Buffer 指定。
功能:由矩阵数据渲染图元。
详细:
glDrawElements用少量调用指明多重几何图元,你可以事先指明独立的顶点、法线、颜色和纹理坐标矩阵并且可以通过调用glDrawElements方法来使用它们创建序列图元。
当glDrawElements被调用,它会使用有序索引来查询可用矩阵中的元素,并以此创建序列几何图元,如果GL_VERTEX_ARRAY被禁用,则不会创建。
顶点属性由glDrawElements修改,glDrawElements在返回后会有一个未指明的值。举一个例子,如果GL_COLOR_ARRAY启用,当执行glDrawElements方法后,当前颜色的值是未定义的,属性不会维持它之前的值。
错误:
如果mode的值不被允许,将产生GL_INVALID_ENUM。
如果type的值不被允许,将产生GL_INVALID_ENUM。
如果count是负数,将产生GL_INVALID_VALUE。
参数:
mode——指明被渲染的是哪种图元,被允许的符号常量有GL_POINTS,GL_LINE_STRIP,GL_LINE_LOOP,GL_LINES,GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN和GL_TRIANGLES
count——指明被渲染的元素个数。
type——指明索引指的类型,不是GL_UNSIGNED_BYTE就是GL_UNSIGNED_SHORT。
indices——指明存储索引的位置指针。
抛出:
java.lang.IllegalStateException——如果最近一次调用glBindBuffer方法以GL_ELEMENT_ARRAY_BUFFER为目标时,有一个非0缓冲区参数。
java.lang.IllegalArgumentException——如果索引为空。
java.lang.ArrayIndexOutOfBoundsException——如果索引序列中从0到count-1中任意索引超出现有索引或数据矩阵范围。
其中 mode 为上述解释顶点的模式,如下面定义三个顶点坐标,并把它们存放在 FloatBuffer
中:
float[] vertexArray = new float[]{
-0.8f , -0.4f * 1.732f ,0.0f ,
0.8f , -0.4f * 1.732f ,0.0f ,
0.0f , 0.4f * 1.732f ,0.0f ,
};
ByteBuffer vbb=ByteBuffer.allocateDirect(vertexArray.length*4);
vbb.order(ByteOrder.nativeOrder());
FloatBuffer vertex = vbb.asFloatBuffer();
vertex.put(vertexArray);
vertex.position(0);
有了顶点的定义,下面就可以通过打开 OpenGL ES
管道(Pipeline)的相应开关将顶点参数传给 OpenGL
库:
打开顶点开关和关闭顶点开关的方法如下:
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
...
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
在打开顶点开关后,将顶点坐标传给 OpenGL 管道的方法为:glVertexPointer:
public void glVertexPointer(int size,int type,int stride,Bufferpointer)
· size:每个顶点坐标维数,可以为2,3,4。
· type:顶点的数据类型,可以为 GL_BYTE, GL_SHORT, GL_FIXED,或 GL_FLOAT,缺省为浮点类型 GL_FLOAT。
· stride:每个相邻顶点之间在数组中的间隔(字节数),缺省为 0,表示顶点存储之间无间隔。
· pointer:存储顶点的数组。
应用用上可以般顶点的颜色值存放在对应顶点后面,如下图,RGB 采用 4 字节表示,此时相邻顶点就不是连续存放的,stride 值为 4 。
对应顶点除了可以为其定义坐标外,还可以指定颜色,材质,法线(用于光照处理)等。
glEnableClientState 和 glDisableClientState
可以控制的 pipeline 开关可以有:GL_COLOR_ARRAY (颜色),GL_NORMAL_ARRAY (法线),GL_TEXTURE_COORD_ARRAY (材质),GL_VERTEX_ARRAY(顶点), GL_POINT_SIZE_ARRAY_OES等。
对应的传入颜色,顶点,材质,法线的方法如下:
glColorPointer(int size,int type,int stride,Buffer pointer)
glVertexPointer(int size, int type, int stride, Buffer pointer)
glTexCoordPointer(int size, int type, int stride, Bufferpointer)
glNormalPointer(int type, int stride, Buffer pointer)
如果需要使用三角形来构造复杂图形,可以使用 GL_TRIANGLE_STRIP 或 GL_TRIANGLE_FAN 模式,另外一种是通过定义顶点序列:
如下图定义了一个正方形:
对应的顶点和 buffer 定义代码:
private short[] indices = { 0, 1, 2, 0, 2, 3 };
//To gain some performance we also put this ones in a bytebuffer.
// short is 2 bytes, therefore we multiply the number ifvertices with 2.
ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
ibb.order(ByteOrder.nativeOrder());
ShortBuffer indexBuffer = ibb.asShortBuffer();
indexBuffer.put(indices);
indexBuffer.position(0);
定义三角形的顶点的顺序很重要在拼接曲面的时候,用来定义面的顶点的顺序非常重要,因为顶点的顺序定义了面的朝向(前向或是后向),为了获取绘制的高性能,一般情况不会绘制面的前面和后面,只绘制面的“前面”。虽然“前面”“后面”的定义可以应人而易,但一般为所有的“前面”定义统一的顶点顺序(顺时针或是逆时针方向)。
下面代码设置逆时针方法为面的“前面”:
gl.glFrontFace(GL10.GL_CCW);
打开 忽略“后面”设置:
gl.glEnable(GL10.GL_CULL_FACE);
明确指明“忽略“哪个面的代码如下:
gl.glCullFace(GL10.GL_BACK);
看到这里,搞明白了一件事情,就是opengles 1.0 和 2.0 的区别,
其实是两种不同的实现。在android framework中,1.0的实现是javax.microedition.khronos.opengles 其中的主要类是GL10.
而2.0的实现是android.opengl.GLES20。
所以,到这里可以基本终止这次资源的学习了,因为目前在操作的是opengl es1.0 的api,和opengles 2.0 是完全不同的实现,也没有任何的集成兼容关系:)。
鸣谢:http://wiki.jikexueyuan.com/project/opengl-es-basics/
相关文章推荐
- Android OpenGL ES(七)基本几何图形定义 .
- Android OpenGL ES 开发教程(8):基本几何图形定义
- Android OpenGL ES 开发教程(8):基本几何图形定义
- OpenGL织梦之旅【第二章】第1节.绘制基本的几何图形
- OpenGL.ES在Android上的简单实践:1-曲棍球(基本环境和定义顶点)
- Android OpenGL ES(七):基本几何图形定义
- Android OpenGL ES 开发教程(8):基本几何图形定义
- OPENGL_ES同样的顶点,可以定义的几何图形可以有所不同
- OpenGL编程讲座之基本图元
- 栈的基本定义
- C语言版数据结构中顺序表的基本操作定义和初始化
- IEC61850变电站基本通信结构-原理和模型_7建模规则中的类定义以及MMS映射模型
- C语言(各种基本定义)
- clojure-基本语法-函数定义
- OpenGL+Qt界面(三) Qt中实现OPENGL的基本交互+代码
- OpenGL 坐标系定义
- 特殊的线性表-栈的定义及基本运算
- pg学习_基本表定义_创建表
- Http的定义及其基本概念介绍
- OpenGL基础图形编程(十)真实感图形基本概念