精华内容
下载资源
问答
  • OpenGL ES

    千次阅读 2017-05-11 22:47:06
    学习内容Ø OpenGL ES的基本概念 Ø Android下3D开发的基本知识Ø 利用OpenGL ES进行2D图形的开发Ø 利用OpenGL ES进行3D图形的开发 能力目标Ø 了解OpenGL ES的基本概念Ø 了解Android下3D开发的基本知识Ø...

    视频课:https://edu.csdn.net/course/play/7621 

    学习内容

     OpenGL ES的基本概念

     Android3D开发的基本知识

     利用OpenGL ES进行2D图形的开发

     利用OpenGL ES进行3D图形的开发 

    能力目标

     了解OpenGL ES的基本概念

     了解Android3D开发的基本知识

     掌握如何利用OpenGL ES进行2D图形的开发

    掌握如何利用OpenGL ES进行3D图形的开发


    本章简介

    游戏在Android中一个非常重要的开发方向,也是可以预料到的未来Android开发中最赚钱的。从最初单机2D游戏到现在的网络3D游戏,无论是显示效果,还是娱乐性上都有了显著的提高。这其中最重要的功臣就是扮演着重要角色的3D图形库。目前PC领域,一直有两种标准的3D API进行竞争OpenGL  DirectX。一般主流的游戏和显卡都支持这两种渲染方式,DirectXWindows平台上有很大的优势,但是 OpenGL 具有更好的跨平台性。在移动平台上使用到的最多的3D图形库就是本章中将要讲到的OpenGL ES,我们Android系统的3D 引擎采用的是OpenGL ES图形库。

    核心技能部分 

    3.1 3D开发基本知识

    OpenGLOpen Graphics Library)是个定义了一个跨编程语言、跨平台的编程接口,它用于二维三维图象绘制OpenGL是个专业的图形程序接口,是一个功能强大,调用方便的底层图形库。

    OpenGL ESOpen Graphics Library for Embedded System是一套为手持和嵌入式系统设计的2D/3D轻量图形库它是基于OpenGL API设计的,是OpenGL三维图形API的一个子集。OpenGL ES是从OpenGL裁剪定制而来的,它去除了OpenGL中很多特性,并针对移动设备改善了图形显示效果,大大降低了内存消耗。

    OpenGL ESKhronos公司推广维护Khronos是一个图形软硬件行业协会,该协会主要关注图形和多媒体方面的开放标准。OpenGL ES的官方主页是http:www.khronos.org/opengles

    Android系统使用 OpenGL ES的标准接口来支持3D图形功能,android 3D 图形系统也分为 java 框架和本地代码两部分。本地代码主要实现的 OpenGL 接口的库,在 Java 框架层,javax.microedition.khronos.opengles  java 标准的 OpenGL 包,android.opengl包提供了 OpenGL 系统和 Android GUI 系统之间的联系。

    OpenGL ES不仅可以绘制3D图形,还可以绘制2D图形。OpenGL ES只能绘制三角形,但这并不影响多边形的绘制,因为任何模型形都可以拆分成三角形。

    OpenGL ES的坐标系是三维的,其中坐标系原点是手机的中心。如下图3.1.1所示:

     

    3.1.1 OpenGL ES坐标系 

    3.2 绘制2D图形

    3D桌球之类的游戏中,华丽的界面、流畅的体验一定给大家留下了深刻的印象。相信大家一定会希望自己也能开发出属于自己的3D游戏。其实所谓的3D其实也比较简单,它是由大量的平面图形按一定的方式组合而成的,比如如下图3.1.2中的桌球游戏的界面,就可以简单的认为是由一些矩形、球形组合而成。在接下来的两节中,我们就分别从2D3D的角度来讲解Android中如何利用OpenGL ES绘制图形。

     

    3.1.2 3D桌球

    像第一章Android中的绘图一样,为了方便程序的编写,我们也先搭建一个程序框架,以后的程序就在这个框架的基础之上进行编写。

    搭建OpenGL ES开发框架,需要以下两步:

    1)提供一个实现了Renderer接口的回调类,并实现这个接口的相关方法。

    2)在Activity类中显示第一步中的Renderer

    示例2.1

    搭建OpenGL ES的基本开发框架。

    首先定义Renderer接口的实现类,代码如下:

    public class MyRenderer implements Renderer {

    @Override

    public void onDrawFrame(GL10 gl) {

    //可以在这个方法中绘制2D3D图形

    }

     

    @Override

    public void onSurfaceChanged(GL10 gl, int width, int height) {

    //可以在这个方法中设置场景的大小

    }

     

    @Override

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {

    //可以在这个方法中做一些初始化工作,比如设置背景颜色、启动平滑模型等

    }

     

    }

    上述代码中的onSurfaceCreated()方法在创建或重建OpenGL ES绘制窗口时会被调用到。可以在这个方法中做一些初始化的操作,比如设置背景颜色、启动平滑模型等。onSurfaceChanged()在窗口尺寸发生变化时被调用,不管窗口的大小是否发生改变,该方法在程序启动时至少执行一次,可以在这个方法中设置场景的大小。onDrawFrame( )在绘制每一帧时被调用,类似于View中的onDraw()方法,一般在这个方法中绘制2D3D图形。注意,在绘图之前一般需要将屏幕清除成指定的颜色、清除深度缓存并重置场景。

    上面3个方法的第一个参数的类型都是GL1.0,这是OpenGL ES 1.0的接口,我们就是利用它业完成2D/3D图形的绘制及渲染的。

    再提供一个Activity类,用来显示我们在上面Renderer类中绘制的图形,具体的代码如下:

    public class Frame3DActivity extends Activity {

     

    @Override

    protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    GLSurfaceView glView = new GLSurfaceView(this);

    MyRenderer renderer = new MyRenderer();

    glView.setRenderer(renderer);

    setContentView(glView);

    }

    }

    接下来,我们在这个程序框架上绘制2D图形。

    示例2.2

    在手机屏幕上绘制一个三角形和一个四边形,要求三角形沿X轴旋转、四边开沿Y轴旋转。

    我们只需要修改示例2.1中的MyRenderer类,为其增加图形绘制的功能,具体代码如下:

    public class MyRenderer implements Renderer {

    int one = 0x10000;

     

    private float triRotate;

    private float quaterRotate;

    // 三角形三个顶点:上顶点、左下点、右下点

    private IntBuffer triBuffer = IntBuffer.wrap(new int[] { 0, one, 0, -one, -one, 0, one, -one, 0, });

    private IntBuffer quaterBuffer = IntBuffer.wrap(new int[] { one, one, 0, -one, one, 0, one, -one, 0, -one, -one, 0 });

     

    // 三角形的顶点颜色值(r,g,b,a)

    private IntBuffer colorBuffer = IntBuffer.wrap(new int[] { one, 0, 0, one, 0, one, 0, one, 0, 0, one, one});

     

    @Override

    public void onDrawFrame(GL10 gl) {

    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);// 清除屏幕和深度缓存

     

    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);// 允许设置顶点

    gl.glEnableClientState(GL10.GL_COLOR_ARRAY);//设置颜色数组,开启颜色渲染功能

    gl.glColorPointer(4, GL10.GL_FIXED, 0, colorBuffer);

    gl.glLoadIdentity();// 重置当前的模型观察矩阵

    gl.glTranslatef(-1.5f, 0.0f, -6.0f);// 左移 1.5 单位,并移入屏幕 6.0

    gl.glRotatef(triRotate, 0.0f, 1.0f, 0.0f); //设置旋转,应该在坐标确定后再旋转

    gl.glVertexPointer(3, GL10.GL_FIXED, 0, triBuffer);// 设置三角形

    gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);// 绘制三角形

    gl.glDisableClientState(GL10.GL_COLOR_ARRAY);

    gl.glColor4f(1.0f, 0.0f, 0.5f, 1.0f);

    gl.glLoadIdentity();// 重置当前的模型观察矩阵

    gl.glTranslatef(1.5f, 0.0f, -6.0f);

    gl.glRotatef(quaterRotate, 1.0f, 0.0f, 0.0f); //设置旋转

    gl.glVertexPointer(3, GL10.GL_FIXED, 0, quaterBuffer);

    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);

     

    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);// 取消顶点设置

    //改变旋转角度

    triRotate += 0.5f;

    quaterRotate -= 0.5f;

    }

     

    @Override

    public void onSurfaceChanged(GL10 gl, int width, int height) {

    float ratio = (float) width / height;

    gl.glViewport(0, 0, width, height);// 设置OpenGL场景的大小

    gl.glMatrixMode(GL10.GL_PROJECTION);// 设置投影矩阵

    gl.glLoadIdentity();// 重置投影矩阵

    gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);// 设置视口的大小

    gl.glMatrixMode(GL10.GL_MODELVIEW);// 选择模型观察矩阵

    gl.glLoadIdentity();// 重置模型观察矩阵

    }

     

    @Override

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {

    gl.glShadeModel(GL10.GL_SMOOTH);// 启用阴影平滑

    gl.glClearColor(0, 0.5f, 0.5f, 0.5f);// 黑色背景

    gl.glClearDepthf(1.0f);// 设置深度缓存

    gl.glEnable(GL10.GL_DEPTH_TEST);// 启用深度测试

    gl.glDepthFunc(GL10.GL_LEQUAL);// 所作深度测试的类型

    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);// 告诉系统对透视进行修正

    }

     

    }

    在本示例中我们用到了GL10的大量的方法,现列举如下:

    Ø void glClear(int mask)

    清理缓冲区,也就是glClearColor或者glClearDepth等函数所指定的值来清除指定的缓冲区。参数表明哪个缓冲区需要清理,取值如下表3-1-1所示:

    3-1-1 mask取值及含义

    参数mask取值

    说明

    GL_COLOR_BUFFER_BIT

    表明颜色缓冲区

    GL_DEPTH_BUFFER_BIT

    表明深度缓冲区

    GL_STENCIL_BUFFER_BIT

    表明模型缓冲区

     

    Ø void glEnableClientState(int array)

    开启指定功能。默认的所有客户端功能都是禁用。在OpenGL中使用glEnableClientState之后都要使用glDisableClientState来关闭或取消对应的功能。参数取值如下表3-1-2所示。

    3-1-2 array取值及含义

    参数array取值

    说明

    GL_COLOR_ARRAY

    如果启用,颜色矩阵可以用来写入以及调用glDrawArrays方法或者glDrawElements方法时进行渲染

    GL_NORMAL_ARRAY

    如果启用,法线矩阵可以用来写入以及调用glDrawArrays方法或者glDrawElements方法时进行渲染

    GL_TEXTURE_COORD_ARRAY

    如果启用,纹理坐标矩阵可以用来写入以及调用glDrawArrays方法或者glDrawElements方法时进行渲染

    GL_VERTEX_ARRAY

    如果启用,顶点矩阵可以用来写入以及调用glDrawArrays方法或者glDrawElements方法时进行渲染

    GL_POINT_SIZE_ARRAY_OES

    如果启用,点大小矩阵控制大小以渲染点和点sprites。这时由glPointSize定义的点大小将被忽略,由点大小矩阵提供的大小将被用来渲染点和点sprites

    Ø void glDisableClientState(int array)

    关闭指定功能。参数取值参看glEnableClientState()方法的array参数讲解。

    Ø void glColorPointer(int size, int type, int stride, Buffer pointer)

    指明渲染时使用的颜色矩阵。其中size指明每个颜色的元素数量,必须为4type指明每个颜色元素的数据类型允许的符号常量有GL_UNSIGNED_BYTE, GL_FIXEDGL_FLOAT,初始值为GL_FLOATstride指明连续的点之间的位偏移,如果stride0时,颜色被紧密挤入矩阵,初始值为0pointer指明包含颜色的缓冲区,如果pointernull,则为设置缓冲区

    Ø void glLoadIdentity()

    将所选的矩阵状态恢复成原始状态,即将当前点移到了屏幕中心。

    Ø void glTranslatef(float x, float y, float z)

    将光标移动到指定的位置。其中x指明平移向量的x坐标y指明平移向量的y坐标z指明平移向量的z坐标z必须得在zNearzFar之间,否则我们看不到图形的效果。

    Ø void glRotatef(float angle, float x, float y, float z)

    将物体沿指定的轴旋转。其中angle指明旋转的角度,单位为度x指明旋转向量的x坐标y指明旋转向量的y坐标z指明旋转向量的z坐标

    Ø void glVertexPointer(int size, int type, int stride, Buffer pointer)

    用来设置顶点缓存。其中size用于描述顶点的尺寸,当使用xyz坐标系时,值取3;type顶点的类型,GL10.GL_FIXED表示固定的顶点;stride表示步长;pointer表示顶点缓存。

    Ø void glDrawArrays(int mode, int first, int count)

    绘制顶点。其中first表示开始位置,count表示要绘制的顶点数,mode表示绘制的模式,它的具体取值参看下表3-1-3所示 。

    3-1-3:mode取值及含义

    mode取值

    说明

    GL10.GL_TRIANGLES

    画三角形

    GL10.GL_TRIANGLE_STRIP

    画四边形,取点顺序如下图3.1.3中左图所示

    GL10.GL_TRIANGLE_FAN

    画四边开,取点顺序如下图3.1.3中右图所示

     

    3.1.3 四边形取点顺序

    Ø void  glColor4f(float red, float green, float blue, float alpha)

    设置当前所使用的颜色,之后绘制的所有内容都会使用这个颜色,即使在完全采用纹理贴图的时候,仍然可以用来调节纹理的色调。利用此方法不需要开启渲染功能。

    Ø void  glViewport(int x, int y, int width, int height)

    设置OpenGL的场景。其中x指明场景矩形的左下角x坐标,初始值为0;y指明场景矩形的左下角y坐标,初始值为0;width指明场景的宽,如果GL上下文首次附于一个surface则宽、高为这个surface大小;height指明视口的高,如果GL上下文首次附于一个surface则宽、高为这个surface大小。

    Ø void glMatrixMode(int mode)

    设置当前矩阵模式,mode允许的值参看表3-1-4所示。

    3-1-4mode取值及含义

    mode的取值

    说明

    GL_MODELVIEW

    应用视图矩阵堆的后续矩阵操作

    GL_PROJECTION

    应用投射矩阵堆的后续矩阵操作

    GL_TEXTURE

    应用纹理矩阵堆的后续矩阵操作

    GL_MATRIX_PALETTE_OES

    启用矩阵调色板堆栈扩展,并应用矩阵调色板堆栈

     void glFrustumf(float left, float right, float bottom, float top, float zNear, float zFar)

    设置窗口的大小。其中前四个参数用于确定窗口的大小,zNearzFar分别代表所能绘制深度的起点和终点。

     void glShadeModel(int mode)

    设置明暗处理模式。所谓明暗处理指的是用单一的颜色或许多不同的颜色来勾画(或填充)。其中参数mod指明一个符号常量来代表要使用的着色技术。允许的值有GL_FLAT GL_SMOOTH,初始值为GL_SMOOTH

     void glClearColor(float red, float green, float blue, float alpha)

    设置清除屏幕时所使用的颜色。色彩范围从0.0f~1.0f0.0f最黑,1.0f最亮。

    void glClearDepthf(float depth)

    指明深度缓冲区的清理值

    void glEnable(int cap)

    启用服务器端GL功能。当参数取值为GL_DEPTH_TEST时表示如果启用,做深度比较和更新深度缓存。

    整个程序的运行效果如下图3.1.4所示。

     

    3.1.4  绘制的2D图形效果

    在本示例中,我们不仅讲到了基本图形(三角形、矩形)的绘制,还讲到了颜色的填充、以及图形的旋转的知识,属于一个比较综合的案例,也是我们下面绘制3D图形的基础。

    3.3 绘制3D图形

    我们可以通过这些2D图形构建简单的诸如“超级马里奥”等常见横版游戏,但随着手机配置的提高,越来越多的3D游戏已经可以在手机上流畅运行,这也推动着越来越多的程序开发者加入到手机3D游戏的开发中来,那么在Android系统中,我们又如何绘制漂亮的3D图形呢?

    其实绘制2D图形对于OpenGL ES来说是很简单的,OpenGL ES的主要功能还是在于绘制3D图形,它从绘制简单的立体图形到设置不同的纹理、以及光照、混合等效果,可谓无所不能。在本节中我们就学习如所利用OpenGL ES来绘制3D图形

    示例3.3

    在屏幕上绘制一个三棱锥和一个立方体,然后给这两个图形填充上颜色,最后设置三棱锥沿Y轴旋转,立方体沿X轴旋转。整个程序的运行效果如下图3.1.5所示。

     

    3.1.5 简单3D图形效果

    修改示例3.1中的MyRenderer类,修改后的代码如下图所示:

    public class GLRenderer3D implements Renderer {

    float rotateTri, rotateCube;

    int one = 0x10000;

    //定义六面体颜色

    private IntBuffer colorBufferForCube = IntBuffer.wrap(new int[]{

     0,one,0,one,

     0,one,0,one,

     0,one,0,one,

     0,one,0,one,

     

     one, one/2, 0, one,

     one, one/2, 0, one,

     one, one/2, 0, one,

     one, one/2, 0, one,

     

     one,0,0,one,

     one,0,0,one,

     one,0,0,one,

     one,0,0,one,

     

     one,one,0,one,

     one,one,0,one,

     one,one,0,one,

     one,one,0,one,

     

     0,0,one,one,

     0,0,one,one,

     0,0,one,one,

     0,0,one,one,

     

     one,0,one,one,

     one,0,one,one,

     one,0,one,one,

     one,0,one,one,

    });

    //四棱锥颜色

     private IntBuffer colorBufferForPyramid = IntBuffer.wrap(new int[]{

     one,0,0,one,

     0,one,0,one,

     0,0,one,one,

     

     one,0,0,one,

     0,one,0,one,

     0,0,one,one,

     

     one,0,0,one,

     0,one,0,one,

     0,0,one,one,

     

     one,0,0,one,

     0,one,0,one,

     0,0,one,one,

     });

     

     

     private IntBuffer PyramidBuffer = IntBuffer.wrap(new int[]{//四棱锥坐标

    0,one,0,

    -one,-one,0,

    one,-one,one,

    0,one,0,

    one,-one,one,

    one,-one,-one,

    0,one,0,

    one,-one,-one,

    -one,-one,-one,

    0,one,0,

    -one,-one,-one,

    -one,-one,one

     

     });

     private IntBuffer cubeBuffer = IntBuffer.wrap(new int[]{//六面体坐标

    one,one,-one,

    -one,one,-one,

    one,one,one,

    -one,one,one,

    one,-one,one,

    -one,-one,one,

    one,-one,-one,

    -one,-one,-one,

    one,one,one,

    -one,one,one,

    one,-one,one,

    -one,-one,one,

    one,-one,-one,

    -one,-one,-one,

    one,one,-one,

    -one,one,-one,

    -one,one,one,

    -one,one,-one,

    -one,-one,one,

    -one,-one,-one,

    one, one, -one,

    one, one, one,

    one, -one, -one,

    one, -one, one,

     });

    @Override

    public void onDrawFrame(GL10 gl) {

    // 清除屏幕和深度缓存

    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

    // 重置当前的模型观察矩阵

    gl.glLoadIdentity();

    // 左移 1.5 单位,并移入屏幕 6.0

    gl.glTranslatef(-1.5f, 0.0f, -6.0f);

    // 设置旋转

    gl.glRotatef(rotateTri, 0.0f, 1.0f, 0.0f);

    // 设置定点数组

    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

    // 设置颜色数组

    gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

    gl.glColorPointer(4, GL10.GL_FIXED, 0, colorBufferForPyramid);

    // 设置三角形顶点

    gl.glVertexPointer(3, GL10.GL_FIXED, 0, PyramidBuffer);

    // 绘制三角锥

    for (int i = 0; i < 4; i++) {

    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, i * 3, 3);

    }

    /* 渲染正方体 */

    // 重置当前的模型观察矩阵

    gl.glLoadIdentity();

    // 左移 1.5 单位,并移入屏幕 6.0

    gl.glTranslatef(1.5f, 0.0f, -6.0f);

    // 设置旋转

    gl.glRotatef(rotateCube, 1.0f, 0.0f, 0.0f);

    // 设置和绘制正方形

    gl.glColorPointer(4, GL10.GL_FIXED, 0, colorBufferForCube);

    gl.glVertexPointer(3, GL10.GL_FIXED, 0, cubeBuffer);

    for (int i = 0; i < 6; i++) {

    gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, i * 4, 4);

    }

    // 绘制正方形结束

    gl.glFinish();

    // 取消顶点数组

    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

    gl.glDisableClientState(GL10.GL_COLOR_ARRAY);

    // 改变旋转的角度

    rotateTri += 0.5f;

    rotateCube -= 0.5f;

    }

     

    @Override

    public void onSurfaceChanged(GL10 gl, int width, int height) {

    float ratio = (float) width / height;

    gl.glViewport(0, 0, width, height);// 设置OpenGL场景的大小

    gl.glMatrixMode(GL10.GL_PROJECTION);// 设置投影矩阵

    gl.glLoadIdentity();// 重置投影矩阵

    gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);// 设置视口的大小

    gl.glMatrixMode(GL10.GL_MODELVIEW);// 选择模型观察矩阵

    gl.glLoadIdentity();// 重置模型观察矩阵

    }

     

    @Override

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {

    gl.glShadeModel(GL10.GL_SMOOTH);// 启用阴影平滑

    gl.glClearColor(0, 0.5f, 0.5f, 0.5f);// 黑色背景

    gl.glClearDepthf(1.0f);// 设置深度缓存

    gl.glEnable(GL10.GL_DEPTH_TEST);// 启用深度测试

    gl.glDepthFunc(GL10.GL_LEQUAL);// 所作深度测试的类型

    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);// 告诉系统对透视进行修正

    }

    }

    在本示例中我们用到的GL10的方法如下:

    Ø void glHint(int target, int mode)

    用来对视图进行修正。

    target用来来表明被控制的行为,当取值为GL_PERSPECTIVE_CORRECTION_HINT时用来指定颜色和纹理坐标的插值质量。

    mode来表明想要执行的行为,取值如下表3-1-5所示。

    3-1-5 mode取值及含义

    mode取值

    说明

    GL_FASTEST

    使用速度最快的模式

    GL_NICEST

    使用质量最好的模式.

    GL_DONT_CAR

    由驱动设备来决定

    Ø void glDepthFunc(int func)

    设置所做深度测试的类型。 


    任务实训部分 

    1绘制一个带纹理的旋转的立方体

    训练技能点

    Ø 基本3D图形的绘制

    Ø 纹理的使用

    Ø 3D图形的旋转控制

    需求说明

    3D游戏相较于普通2D游戏的优点就在于可以让玩家不断变换视角,可以360度查看游戏角色,这里我们用一个立方体模拟一个3D游戏角色,使之不断旋转来模拟查看其各个方位不同的状态。程序最终运行效果如下图3.2.1所示。

     

    3.2.1 旋转的立方体

    实现思路:

     

    核心代码如下

    public class GLRotateCubeRender implements Renderer

    {

    float xrot, yrot, zrot;

    int texture = -1;

    int one = 0x10000;

    IntBuffer vertices = IntBuffer.wrap(new int[]{

    -one,-one,one,

    one,-one,one,

    one,one,one,

    -one,one,one,

    -one,-one,-one,

    -one,one,-one,

    one,one,-one,

    one,-one,-one,

    -one,one,-one,

    -one,one,one,

    one,one,one,

    one,one,-one,

    -one,-one,-one,

    one,-one,-one,

    one,-one,one,

    -one,-one,one,

    one,-one,-one,

    one,one,-one,

    one,one,one,

    one,-one,one,

    -one,-one,-one,

    -one,-one,one,

    -one,one,one,

    -one,one,-one,

    });

    //对立方体的每一个面所设置的纹理映射数据

    IntBuffer texCoords = IntBuffer.wrap(new int[]{

    one,0,0,0,0,one,one,one,

    0,0,0,one,one,one,one,0,

    one,one,one,0,0,0,0,one,

    0,one,one,one,one,0,0,0,

    0,0,0,one,one,one,one,0,

    one,0,0,0,0,one,one,one,

    });

    ByteBuffer indices = ByteBuffer.wrap(new byte[]{

    0,1,3,2,

    4,5,7,6,

    8,9,11,10,

    12,13,15,14,

    16,17,19,18,

    20,21,23,22,

    });

    @Override

    public void onDrawFrame(GL10 gl)

    {

    // 清除屏幕和深度缓存

    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

    // 重置当前的模型观察矩阵

    gl.glLoadIdentity();

    gl.glTranslatef(0.0f, 0.0f, -5.0f);

    //设置3个方向的旋转

    gl.glRotatef(xrot, 1.0f, 0.0f, 0.0f);

    gl.glRotatef(yrot, 0.0f, 1.0f, 0.0f);

    gl.glRotatef(zrot, 0.0f, 0.0f, 1.0f);

     

    // 绑定纹理

    gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);

    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

    gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

    //纹理和四边形对应的顶点

    gl.glVertexPointer(3, GL10.GL_FIXED, 0, vertices);

    gl.glTexCoordPointer(2, GL10.GL_FIXED, 0, texCoords);

     

    //绘制

    gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 24,  GL10.GL_UNSIGNED_BYTE, indices);

     

        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);

        

        xrot+=0.5f;

        yrot+=0.6f;

        zrot+=0.3f;

    }

     

    @Override

    public void onSurfaceChanged(GL10 gl, int width, int height)

    {

    float ratio = (float) width / height;

    //设置OpenGL场景的大小

    gl.glViewport(0, 0, width, height);

    //设置投影矩阵

    gl.glMatrixMode(GL10.GL_PROJECTION);

    //重置投影矩阵

    gl.glLoadIdentity();

    // 设置视口的大小

    gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);

    // 选择模型观察矩阵

    gl.glMatrixMode(GL10.GL_MODELVIEW);

    // 重置模型观察矩阵

    gl.glLoadIdentity();

    }

     

    @Override

    public void onSurfaceCreated(GL10 gl, EGLConfig config)

    {

    // 黑色背景

    gl.glClearColor(0, 0, 0, 0);

    gl.glEnable(GL10.GL_CULL_FACE);

    // 启用阴影平滑

    gl.glShadeModel(GL10.GL_SMOOTH);

    // 启用深度测试

    gl.glEnable(GL10.GL_DEPTH_TEST);

    //启用纹理映射

    gl.glClearDepthf(1.0f);

    //深度测试的类型

    gl.glDepthFunc(GL10.GL_LEQUAL);

    //精细的透视修正

    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);

    //允许2D贴图,纹理

    gl.glEnable(GL10.GL_TEXTURE_2D);

    IntBuffer intBuffer = IntBuffer.allocate(1);

    // 创建纹理

    gl.glGenTextures(1, intBuffer);

    texture = intBuffer.get();

    // 设置要使用的纹理

    gl.glBindTexture(GL10.GL_TEXTURE_2D, texture);

    //生成纹理

    GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, GLImage.mBitmap, 0);

    // 线形滤波

    gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);

    gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

    }

     

    }

     

    class GLImage

    {

    public static Bitmap mBitmap;

    public static void load(Resources resources)

    {

    mBitmap = BitmapFactory.decodeResource(resources, R.drawable.img);

    }

    }

     

    提示:

    本例中用到两个纹理处理的方法,语法及解释如下:

    Ø void glGenTextures(int n, IntBuffer textures)

    创建纹理,用于通知OpenGL我们所要生成的纹理的名字。其中参数n表示要载入的纹理的个数,textures表示纹理的名字。

    Ø void glBindTexture(int target, int texture)

    设置要使用的纹理,绑定纹理操作必须在绘图之前完成。用于通知OpenGL将纹理名字texture绑定到纹理目标上。其中参数target描述了要绑定的纹理的类型,texture表示纹理的名字。


    巩固练习

    一、简答题

    1. 简述OpenGLOpenGL ES的关系及区别。 

    2. 简述在Android中使用OpenGL ES的基本步骤。 

    二、上机练习

    利用基本图形组合的形式,采用OpenGL ES的知识绘制一个简单的机器人,然后为机器人添加走动的功能(此步选做)。 

    展开全文
  • openGLES

    2011-06-21 23:19:00
    西蒙系列的openGLES教学由简到难,很容易让开发者进入openGLES的世界。下面介绍四篇OpenGLES开发相关文章。OpenGL ES for iPhone : A Simple Tutorial Part 1OpenGL ES for iPhone : Part 2 with touch ...
    展开全文
  • openGL ES

    2015-04-12 17:03:28
    文章主要是对opengl的一些重要的知识点进行总结: 1、opengl的工作原理 通常采用图形卡驱动程序的形式: 管线(pipeline)是一个过程,可能涉及两个或多个独特的阶段或步骤....2、OpenGL ES(OpenG

    文章主要是对opengl的一些重要的知识点进行总结:
    1、opengl的工作原理
    通常采用图形卡驱动程序的形式:
    这里写图片描述

    管线(pipeline)是一个过程,可能涉及两个或多个独特的阶段或步骤.应用程序进行OpenGL函数调用时,这些命令被放置在一个命令缓冲区.该缓冲区最终填满了命令,定点数据,纹理数据等东西.缓冲区被刷新时,命令和数据就传递给下一个阶段.
    这里写图片描述

    2、OpenGL ES(OpenGL for Embedded Systems)是从OpenGL剪裁或定制过来了,去除了glBegin/glEnd,四边形(GL_QUADS),多边形(GL_POLYGON)等复杂图元等许多非必要的特性.
    这里写图片描述
    pipeline:(管线)
    opengl application: geometry(几何图形) + texture(纹理贴图)
    vertex data(顶点数据): lighting(光照) +transform(变换) +scale(缩放)
    geometry(几何图形): rasterization(光栅) +clipping(剪裁)
    fragment(段): fog(雾) + texture(纹理).
    framebufer(帧缓冲区): stecil(蒙版) z-test(深度测试) alpha(透明) blending(混合)
    eyeball(眼球): 就看到物体了
    3、对OpenGL ES各个版本的简单介绍
    OpenGL ES1.x针对固定管线硬件,OpenGL ES1.0是以OpenGL1.3规范为基础的,OpenGL ES1.1是以OpenGL1.5为基础的,他们分别又支持common和common lite两种profile.
    OpenGLES2.x针对可编程管线硬件. OpenGL ES2.0是参照OpenGL2.0规范定义的.
    OpenGL ES 3.x 目前在高通骁龙600系列及其以上的版本中支持。
    小插曲:对3.x中新特性的描述:(可以忽略)
    OpenGL ES 3.0 带来很多新特性,根据 AnandTech 的解释:
     支持更多缓冲区对象,在 OpenGL ES 2.0 时中,缓冲区对象的规范有模糊之处。名字一样缓冲区对象,在实际渲染中对表现却有细微的差别。针对这个问题 OpenGL ES 3.0 制定了更详细对格式规范。新版 OpenGl ES 还增加对 Uniform Buffer Object 的支持;
     新版 GLSL ES 3.0 着色语言,支持 32 位整数和浮点数据类型以及操作。之前版本的着色语言只支持精度更低的,这样虽然能够加快计算的速度,所需的资源也更少,但当着色器的复杂度增加,出错也随之增加。同时,新版着色语言的语法更贴近 GLSL;
     支持遮挡查询(Occlusion Query)以及几何体实例化(Geometry Instancing)。通过遮挡查询,能够让 GPU 知道 3D 场景中,哪些物体被其它物体完全遮挡,这些完全被遮挡的物体 GPU 不会去渲染。几何体实例化是通过对具有相同顶点数据的几何体,赋予不同的空间位置、颜色或纹理等特征,从而创造出不同实例对象的技术。这两个特性都能够节省硬件资源,提高 3D 图形渲染的性能。
     增加多个纹理的支持。包括浮点纹理、深度纹理、顶点纹理等等。
     多重渲染目标(Multiple Render Targets),让 GPU 一次性渲染多个纹理。
     多重采样抗锯齿(MSAA Render To Texture),让 3D 物体对边缘不出现毛刺,可提升图像效果。
     使用统一的纹理压缩格式 ETC;
    4、OpenGL中的坐标系
    对象空间,相对于每个对象自身
    相机,眼睛,空间是针对视点
    投影,剪裁,空间他们是平面的屏幕或者是图像上的视口
    5、OpenGL中常见的几个概念
    GLSurfaceView:GL表层视图,输出openGL画面的控件.
    GLSurfaceView.Renderer:openGL渲染器,绘制openGL的类.
    平截头体(frustum)也叫视景体,拍摄画面的一个区域,是一个棱台,对投影矩阵进行操纵.
    投影:
    透视投影:有深度,越远越小.
    正投影:没有深度,相同大小.
    6、使用openGL步骤:

    1.创建GLSurfaceView对象
    2.创建GLSurfaceView.renderer实现类.
    3.设置activity的contentView,以及设置view的render对象.
    4.实现render类的过程.
        a.onSurfaceCreate()方法
            1.设置清屏的颜色和启用顶点缓冲区
            //设置清屏色
            gl.glClearColor(0, 0, 0, 1);
            //启用顶点缓冲区.
            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        b.onSurfaceChanged()方法
            1.设置viewport(视口)
                gl.glViewport(0, 0, width, height);
            2.操纵投影矩阵,设置平截头体(比例通常和视口比例相同,否则输出画面会走样)
                //矩阵模式,投影矩阵,openGL基于状态机
                gl.glMatrixMode(GL10.GL_PROJECTION);
                //加载单位矩阵
                gl.glLoadIdentity();
                //平截头体
                gl.glFrustumf(-1f, 1f, -ratio, ratio, 3, 7);//这些参数都是单位不是真正的距离
        c.onDrawFrame()方法
            1.清除颜色缓冲区
                gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
            2.操纵模型视图矩阵,设置眼球的参数
                gl.glMatrixMode(GL10.GL_MODELVIEW);
                gl.glLoadIdentity();//加载单位矩阵
                GLU.gluLookAt(gl, 0, 0, 5, 0, 0, 0, 0, 1, 0);
            3.定义图形顶点坐标值数组
                float[] coords = {
                    0f,0.5f,0f,
                    -0.5f,-0.5f,0f,
                    0.5f,-0.5f,0f};
            4.将顶点坐标转换成缓冲区数据
                //分配字节缓存区空间,存放顶点坐标数据
                ByteBuffer ibb = ByteBuffer.allocateDirect(coords.length * 4);
                //设置的顺序(本地顺序)
                ibb.order(ByteOrder.nativeOrder());
                //放置顶点坐标数组
                FloatBuffer fbb = ibb.asFloatBuffer();
                fbb.put(coords);
                //定位指针的位置,从该位置开始读取顶点数据
                ibb.position(0);
            5.设置绘图颜色
                gl.glColor4f(1f, 0f, 0f, 1f);
            6.指定顶点缓冲区指针
                //3:3维点,使用三个坐标值表示一个点
                //type:每个点的数据类型 
                //stride:0,跨度.
                //ibb:指定顶点缓冲区
                gl.glVertexPointer(3, GL10.GL_FLOAT, 0, ibb);
            7.绘图
                //0:起始点:
                //3:绘制点的数量
                gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 3);
    
    展开全文
  • OpenGL ES

    千次阅读 2010-04-13 15:10:00
    OpenGL ES1.2 什么是OpenGL ES图形系统 OpenGL ES是访问已经图形加速器的软件接口,大部分需要framebuffer. OpenGL ES1.1是基于OpenGL 1.5的,去掉了很多冗余和遗留的函数。它们之间的不同在文档Specification>>, ...

    OpenGL ES

    1.2 什么是OpenGL ES图形系统

         OpenGL ES是访问已经图形加速器的软件接口,大部分需要framebuffer. OpenGL ES1.1是基于OpenGL 1.5的,去掉了很多冗余和遗留的函数。它们之间的不同在文档<<OpenGL ES Common/Common-Lite Profile Specification (Difference
    Specification>>, common-lite是面向硬件上没有浮点运算的目标机,它的参数全是定点,common则还支持浮点参数。OpenGL ES2.0是基于OpenGL2.0的

     

    OpenGL版本比较

    1 opengl的版本区别(在opengl官方文档中有详细说明)
    针对Opengl不同版本的升级是主要是扩展指令集。

    1.1 opengl1.1

    1995年,SGI推出了更为完善的OpenGL 1.1版本。OpenGL 1.1的性能比1.0版提高甚多。其中包括改进打印机支持,在增强元文件中包含OpenGL的调用,顶点数组的新特性,提高顶点位置、法线、颜色、色彩指数、纹理坐标、多边形边缘标识的传输速度,引入了新的纹理特性等等。

    1.2 opengl1.3

    2001年8月,ARB发布OpenGL 1.3规范,它增加了立方纹理贴图、纹理环境、多重采样、纹理框架压缩等扩展指令,但是改进程度非常有限。

    1.3 opengl1.4

    2002年7月,ARB正式发布OpenGL 1.4,它也只加入了深度纹理/阴影纹理、顶点设计框架、自动纹理贴图等简单的功能。

    1.3 opengl1.5

    2003年的7月,ARB公布OpenGL 1.5规范。OpenGL 1.5内包含ARB制定的“正式扩展规格绘制语言”(OpenGL Shading Language v1.0),该语言用于着色对象、顶点着色、片断着色等扩展功能,同时也将作为下一代OpenGL 2.0版本的内核。OpenGL 1.5的变化还增加了顶点缓冲对象(可提高透视性能)、非乘方纹理(可提高纹理内存的使用效率)以及阴影功能、隐蔽查询功能等等。其主要内容包括

    a.   顶点Buffer Object:进行顶点配列方式可以提高透视性能
    b.   Shadow功能:增加用来比较Shadow映射的函数
    c.   隐蔽查询(QUERY):为提高Curling性能采用非同步隐蔽测试
    d.   非乘方纹理(Texture):提高mipmap等纹理内存的使用效率
    e.  OpenGL Shading Language v.1.0:用于着色(shader)对象、顶点着色以及片断着色技术(fragment shader )的扩展功能

    1.4 opengl2.0

    OpenGL 1.0推出后的相当长的一段时间里,OpenGL唯一做的只是增加了一些扩展指令集,这些扩展指令是一些绘图功能,像是ClearCoat、Multisample、视频及绘图的整合工具(某些是通过OpenML的努力而开发出来的,它本身属于OpenGL ARB扩展指令之一。
    去年8月已经推出opengl2.0。OpenGL 2.0将在OpenGL 1.3基础上进行修改扩充、但它将有下面五个方面的重大改进:①复杂的核心被彻底精简;②完全的硬件可编程能力;③改进的内存管理机制、支持高级像素处理;④扩展至数字媒体领域,使之跨越高端图形和多媒体范畴;⑤支持嵌入式图形应用。为了在获得强大功能的同时保持理想的兼容性,OpenGL 2.0经历以下两个发展阶段:第一个阶段注重兼容能力和平滑过渡,为此,OpenGL 2.0核心将在精简后的OpenGL 1.3功能模块的基础上加上可完全兼容的新功能共同组成,这种做法在满足兼容性的同时,还可将原有OpenGL中数量众多、且相互纠缠不清的扩展指令进行彻底精简。 第一阶段的任务只是为了过渡,而第二阶段才是OpenGL 2.0的真正成熟期。此时,ARB将合成出一个“纯OpenGL 2.0”内核,纯内核将包含更多新增加的“精简型API函数”,这些函数具有完全的可编程特性、结构简单高效、功能强大且应用灵活。除了完成这项任务外,ARB组织还得指导开发商抛弃繁琐的OpenGL 1.X, 转用更具弹性的“纯OpenGL 2.0”。

    2 OpenGL扩展(OpenGL Extensions)

    OpenGL和Direct3D比较起来,最大的一个长处就是其扩展机制。硬件厂商开发出一个新功能,可以针对新功能开发OpenGL扩展,软件开发人员通过这个扩展就可以使用新的硬件功能。所以虽然显卡的发展速度比OpenGL版本更新速度快得多,但程序员仍然可以通过OpenGL使用最新的硬件功能。而Direct3D则没有扩展机制,硬件的新功能要等到微软发布新版DirectX后才可能支持。
    OpenGL扩展也不是没有缺点,正因为各个硬件厂商都可以开发自己的扩展,所以扩展的数目比较大,而且有点混乱,有些扩展实现的相同的功能,可因为是不同厂商开发的,接口却不一样,所以程序中为了实现这个功能,往往要为不同的显卡写不同的程序。这个问题在OpenGL 2.0出来后可能会得到解决,OpenGL 2.0的一个目标就是统一扩展,减少扩展数目。

    2.1 扩展名
    每个扩展都有一个扩展名,扩展名类似如下形式:

    GL_ARB_multitexture

    第一段GL,用来表示针对OpenGL哪部分开发的扩展,有以下几个值:

    GL – 针对OpenGL核心的扩展
    WGL – 针对Windows平台的扩展
    GLX – 针对Unix / Linux平台的扩展
    GLU – 针对OpenGL Utility Library的扩展

    第二段ARB,用来表示是谁开发的这个扩展,常见以下几个值:

    ARB – 经OpenGL Architecture Review Board(OpenGL管理机构)正式核准的扩展,往往由厂商开发的扩展发展而来,如果同时存在厂商开发的扩展和ARB扩展,应该优先使用ARB扩展

    EXT – 被多个硬件厂商支持的扩展
    NV – nVIDIA 公司开发的扩展
    ATI – ATI公司开发的扩展
    ATIX– ATI公司开发的实验性扩展
    SGI – Silicon Graphics(SGI)公司开发的扩展
    SGIX– Silicon Graphics(SGI)公司开发的实验性扩展

    第三段multitexture就是真正的扩展名了,如multitexture就是多重纹理扩展。

     


    展开全文
  • OpenglEs简介

    2020-10-08 13:14:54
    OpenglEs简介OpenglEs简介OpenglEs简介OpenglEs简介OpenglEs简介OpenglEs简介OpenglEs简介OpenglEs简介
  • Android OpenGLES 3.0 开发系统性学习教程 备注: 其中一些 Case 的 3D 效果是通过手势触发(转动和缩放)。 展示图 基础篇 OpenGL ES 3.0 开发(01):绘制一个三角形 OpenGL ES 3.0 开发(02):纹理...
  • 相比于 OpenGL ES 1.x 系列的固定功能管线,OpenGL ES 2.0 和 OpenGL ES 3.0 都是可编程图形管线。开发者可以自己编写图形管线中的 顶点着色器 和 片段着色器 两个阶段的代码。 二、不同点 OpenGL ES 3.0 是向后...
  • OpenGL ESOpenGL ES简介

    千次阅读 2017-04-25 20:12:48
    【参考-khronos】https://www.khronos.org/opengles/1、简介OpenGL ES(OpenGL for Embeded System)是OpenGL(Open Graphics Library)的精简子集,是以手持和嵌入式设备为目标的高级3D图形API,如现在火爆的智能...
  • Android OpenGL ES 开发教程 2 关于OpenGL ES
  • 一、什么是OpenGL ES OpenGL ES (OpenGL for Embedded Systems) 是 OpenGL 三维图形 API 的子集,针对手机、PDA和游戏主机等嵌入式设备而设计。OpenGL ES 是从 OpenGL 裁剪的定制而来的,去除了glBegin/glEnd,...
  • OpenGL/OpenGL ES入门:图形API以及专业名词解析 OpenGL/OpenGL ES入门:渲染流程以及固定存储着色器 OpenGL/OpenGL ES入门:图像渲染实现以及渲染问题 OpenGL/OpenGL ES入门:基础变换 - 初识向量/矩阵 OpenGL/...
  • 上一篇主要想要脱离Android平台介绍一下OpenGLOpenGL ES到底是什么,从本篇起开始从零开始搭建自己的Android平台下OpenGL ES知识体系。 一.Android基本架构中OpenGL ES 1.1 OpenGL ES在Android的基本架构中位置 如...
  • 什么是OpenGL ES? OpenGL ES (为OpenGL for Embedded System的缩写)为适用于嵌入式系统的一个免费二维和三维图形库。 为桌面版本OpenGL 的一个子集。 OpenGL ES 定义了一个在移动平台上能够支持OpenGL最基本...
  • 关于OPENGL 1.x与OPENGL ES 1.x的区别 早先定义OpenGL ESOpenGL的嵌入式设备版本,但由于嵌入式设备要求的是高性能,所以一些其它纯追求高性能的设备也开始用这种API方式,比如 SONY PlayStation 3。   ...
  • 之前的总结的文章是写OpenGLES1.0的使用,可能有些不对的地方。接下来讲的是OpenGLES2.0. Android 支持OpenGL ES API版本的详细状态: OpenGL ES 1.0 和 1.1 能够被Android 1.0及以上版本支持 OpenGL ES 2.0 能够...
  • 1什么是OpenGL ES? 2OpenGLOpenGL ES的关系 3OpenGL ES Profiles 什么是OpenGL ES? OpenGL ES (为OpenGL for Embedded System的缩写) 为适用于嵌入式系统的一个免费二维和三维图形库。 为桌面版本OpenGL 的...
  • [OpenGL ES 01]OpenGL ES之初体验

    万次阅读 多人点赞 2012-11-25 08:38:28
    [OpenGL ES 01]OpenGL ES之初体验 罗朝辉 (http://blog.csdn.net/kesalin) 本文遵循“署名-非商业用途-保持一致”创作公用协议   一,什么是 OpenGL ESOpenGL ES 是专门为手持设备制定的 3D 规范,...
  • OpenGL ES 入门指南 - Getting Started with OpenGL ES
  • OpenGLES自定义相机

    2019-04-12 10:34:11
    本课程将教会大家如何使用OpenGLES完成自定义相机,提升学生在行业内的竞争
  • OpenGL ESOpenGL三维图形API的子集,主要针对手机等嵌入式设备。 OpenGL ES主要分为两个版本 一个是OpenGL ES1.x,其采用的是固定功能渲染管线,可以由硬件GPU支持或用软件模拟实现,渲染能力有限,在纯...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 18,949
精华内容 7,579
关键字:

opengles