Learn OpenGLES: HelloWorld

一直没有写博客,一来平时学习做笔记,犯不着写博客;二来,一直未想好未来在哪一方面积淀技术;三来,读书少,也不好意思写博客。

写博客,对于程序员来说是有好处的,它在清晰化思维的同时能够弥补思维的漏洞。 同时,每一个笔客都是在构建自己的虚拟的世界,在梦想的世界里遨游,因此,有着同样情丝的程序员,写博客是编程之外的延续,反之亦然。

纠结了大半年,终于确定自己要走的路,然我感叹一下:

      往着计算机图形学奔跑吧,少年,别回头; 

       结合Android移动平台,做好NDK移植,少年,别回头。


之前,做项目,有过在Android平台上用OpenGL实现视频解说的经验。但是,从现在开始,还是要从头再来,一点一滴去挖掘积累,去构建一个三维的虚拟世界。


#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

大致如下:

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


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

[java]  view plain copy
  1. private GLSurfaceView glSurfaceView;  //GL窗口  
  2. private boolean rendererSet; //判断GL是否开始运行  


在onCreate方法里,创建GL窗口

[java]  view plain copy
  1. super.onCreate(savedInstanceState);  
  2. glSurfaceView = new GLSurfaceView(this);   


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


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

[java]  view plain copy
  1. glSurfaceView.setEGLContextClientVersion(2);   
  2. glSurfaceView.setRenderer(new MyGLRenderer());  
  3. rendererSet = true;  
最后将setContentView(main.xml)修改为setContentView(glSurfaceView); 
GLSurfaceView一旦创建以后,就会有一个渲染线程不停的负责刷新窗口,渲染图形。因此,我们需要让改渲染线程与 Activity的生命周期进行同步:

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

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

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

[java]  view plain copy
  1. public class MyGLRenderer implements GLSurfaceView.Renderer {  
  2.   
  3.     @Override  
  4.     public void onSurfaceCreated(GL10 gl, EGLConfig config) {  
  5.         // 当GLurfaceView初始创建或者设备唤醒时或者重新切换回该Activity时  
  6.         // 该方法会被调用  
  7.         glClearColor(1.0f, 0.0f, 0.0f, 0.0f);  
  8.     }  
  9.   
  10.     @Override  
  11.     public void onSurfaceChanged(GL10 gl, int width, int height) {  
  12.         // 当GLSurfaceView初始创建时,或者GLSurfaceView的大小改变时  
[java]  view plain copy
  1. <span style="font-family: Arial, Helvetica, sans-serif;">      //该方法会被调用</span>  
[java]  view plain copy
  1. <span style="font-family: Arial, Helvetica, sans-serif;">              glViewport(00, width, height);</span>  
[java]  view plain copy
  1. }  
  2.   
  3. @Override  
  4. public void onDrawFrame(GL10 gl) {  
  5.    glClear(GL_COLOR_BUFFER_BIT);  
  6.   
  7. }  

重点说下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

看到红色效果了么?


——————————————————————————————————————————

ARVR技术交流群:129340649

欢迎加入!



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值