[转载]一步一步教你写OpenGLES之HelloWorld - OpenGL - ARSchool

#Action 在写第一个GL “Hello w

来源: [转载]一步一步教你写OpenGLES之HelloWorld – OpenGL – ARSchool

#Action
在写第一个GL “Hello world”程序之前,相关的环境配置就不多说了。开发平台自然是google新推荐的AndroidStudio(由于之前项目一直用Eclipse, 因此,对于AndroidStudio也是边实践边摸索)。

#相关简述
OpenGLES1.0 大多是官方内置的API,不允许用户对其更改,对于OpenGL的开发虽然简单,但是灵活度和定制性太差。
OpenGLES2.0 允许用户加大自由的写出自己的图形程序,也是现在Android平台主流的OpenGL API  Android 2.3以上支持
OpenGLES3.0  现在相对来说还不成熟,但是在OpenGLES2.0的基础上加了许多新的特性 Android4.3以上支持

#begin
OpenGL在正式编写之前,需要一些初始化的工作,如:
创建一个窗口,配置好其颜色格式,深度buffer大小,以及为其分配一个上下文
创建一个background线程,尽量保证OpenGL的所有API都运行在这个线程里面

好在Android平台上,GLSurfaceView为我们准备好了这一切,我们只需要在其Renderer接口的相应方法里写相应的逻辑即可。
GLSurfaceView实际上实在Android的屏幕上创建了自己的窗口, 然后在View的继承体系中开了个“洞”,使得OpenGL surface能够显示内容。但是GLSurfaceView却不能像其它View一样实现动画和变换效果。 好在Android4.0以上,推出了TextureView, 它可以不在另开一个窗口的前提下,用来渲染OpenGL(后续的教程会使用到)

# create Activity
在AndroidStudio上创键一个Android工程就像在Eclipse上一样简单。花一定的时间,了解一下AndroidStudio的视图结构,我们就可以开始编程了。
在工程目录,Scr/Main/Java下是我们创建好的package包,在该包下创建一个Activity,名字叫MyGL.java
大致如下:

复制代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class MyGL extends ActionBarActivity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         
        setContentView(main.xml);
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_my_gl, menu);
        return true;
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
    
        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }
    
        return super.onOptionsItemSelected(item);
    }
}

接下来,在Activity的Filed里加两个私有变量

复制代码

1
2
private GLSurfaceView glSurfaceView;  //GL窗口
private boolean rendererSet; //判断GL是否开始运行

在onCreate方法里,创建GL窗口

复制代码

1
2
super.onCreate(savedInstanceState);
glSurfaceView = new GLSurfaceView(this);

你可以用 ActivityManager的getDeviceConfigureationInfo().reqGLEsVersion 是否大于 0x20000来判断,你的机子是否支持OpenGL ES2.0,这里我默认设备都支持

接着,为GLSurfaceView的窗口配置OpenGL ES2.0的上下文和一个渲染的线程类

复制代码

1
2
3
glSurfaceView.setEGLContextClientVersion(2);
glSurfaceView.setRenderer(new MyGLRenderer());
rendererSet = true;


最后将setContentView(main.xml)修改为setContentView(glSurfaceView);

GLSurfaceView一旦创建以后,就会有一个渲染线程不停的负责刷新窗口,渲染图形。因此,我们需要让改渲染线程与 Activity的生命周期进行同步:

复制代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Override
   protected void onResume() {
       super.onResume();
       if(rendererSet)
       {
           glSurfaceView.onResume();
       }
   }
    
   @Override
   protected void onPause() {
       super.onPause();
       if(rendererSet)
       {
           glSurfaceView.onPause();
       }
   }

以 上步骤完成后,我们还需要创建一个渲染类,我们的虚拟世界,就是在这个类中进行构建的。 渲染类继承自GLSurfaceView的Renderer接口,该接口,有三个方法onSurfaceCreated onSurfaceChanged, onDrawFrame。 这三个方法会被GL线程调用,其方法具体的实现需要我们自己实现。

在我们的package包下创建一个继承GLSurfaceView的Renderer类,名字叫MyGLRenderer 如下:

复制代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class MyGLRenderer implements GLSurfaceView.Renderer {
    
    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        // 当GLurfaceView初始创建或者设备唤醒时或者重新切换回该Activity时
        // 该方法会被调用
        glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
    }
    
    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        // 当GLSurfaceView初始创建时,或者GLSurfaceView的大小改变时
       //该方法会被调用
      glViewport(0, 0, width, height);
    
    }
    
    @Override
    public void onDrawFrame(GL10 gl) {
       glClear(GL_COLOR_BUFFER_BIT);
    
    }
}

重点说下onDrawFrame方法, 它会被GL线程一直循环调用。每循环一次,它就会将我们编写的内容画在屏幕上。 最简单的就是如上程序,为其添加一个背景色。
每个屏幕窗口,都会为GL分配几个buffer,一般最多有16个:
4个color buffer
1个 depth buffer
1个stencil buffer
1个多采样buffer
1个或多个辅助buffer

而glClearColor就是每次向color buffer 填上色彩。 其4个参数分别是 r, g, b, a 前三个表示色彩,最后一个表示透明度在每次onDrawFrame迭代中,要使用glClear来清空color buffer,这样保证了,每一次内容的更新

在Renderer的三个接口中,都接受了GL10 gl这样的参数。这是因为,如果我们需要调用GLES1.0的Api可以使用该对象,而我们在调用GLES api时也没有使用GLES20 的前缀。 这个可以通过设置静态导入,来将其省略,便于我们的编写。在AndroidStudio的标题栏,File里,点击 Settings>Editor>Java  然后添加import static android.openg.GLES20.*; 即可

好了。到此我们这个OpenGL ES2.0的Hello world程序就写完了。
#end
看到红色效果了么?

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏