设为首页 收藏本站
查看: 1245|回复: 0

[经验分享] android3D open GL-ES之光效开发

[复制链接]

尚未签到

发表于 2019-1-28 06:59:19 | 显示全部楼层 |阅读模式
  本文转自:http://blog.csdn.net/hmg25/article/details/6739699

光效三要素
  在 OpenGL ES中,光由三个元素组成,分别是环境元素(ambient component), 散射元素(diffuse component)和 高光元素(specular component)。我们使用颜色来设定光线元素,这看上去有些奇怪,但是由于它允许你同时指定各光线元素的颜色和相对强度,这个方法工作得很好。明亮的白色光定义为白色 ({1.0, 1.0, 1.0, 1.0}),而暗白色可能定义为灰色 ({0.3, 0.3, 0.3 1.0})。 你还可以通过改变红,绿,蓝元素的百分比来调整色偏。
  下图说明了各要素产生的效果。

  高光元素定义了光线直接照射并反射到观察者从而形成了物体上的“热点”或光泽。光点的大小取决于一些因素,但是如果你看到如上图黄球所示一个区域明显的光斑,那通常就是来自于一个或多个光源的高光部分。
  散射元素定义了比较平均的定向光源,在物体面向光线的一面具有光泽。
  环境光则没有明显的光源。其光线折射与许多物体,因此无法确定其来源。环境元素平均作用于场景中的所有物体的所有面。

环境光
  你的光效中有越多的环境元素,那么就越不会产生引入注目的效果。所有光线的环境元素会融合在一起产生效果,意思是场景中的总环境光效是由所有启动光源的环境光组合在一起所决定的。如果你使用了不止一个光源,那么最好是只指定一个光源的环境元素,而设定其他所有光源的环境因素为黑 ({0.0, 0.0, 0.0, 1.0}),从而很容易地调整场景的环境光效。
  下面演示了怎样指定一个很暗的白色光源:
  

float lightAmbient[] = new float[] { 0.2f, 0.3f, 0.6f, 1.0f };  //环境光gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbient,0);  

  使用像这样的很低的环境元素值使场景看上去更引入注目,但同时也意味着物体没有面向光线的面或者有其他物体挡住的物体将在场景中看得不是很清楚。

散射光
  在OpenGL ES中可以设定的第二个光线元素是 散射元素(diffuse component)。在现实世界里,散射光线是诸如穿透光纤或从一堵白墙反射的光线。散射光线是发散的,因而参数较柔和的光,一般不会像直射光一样产生光斑。如果你曾经观察过职业摄影家使用摄影室灯光,你可能会看到他们使用柔光箱 或者反光伞。两者都会穿透像白布之类的轻型材料并反射与轻型有色材料从而使光线发散以产生令人愉悦的照片。在OpenGL ES中,散射元素作用类似,它使光线均匀地散布到物体之上。然而,不像环境光,由于它是定向光,只有面向光线的物体面才会反射散射光,而场景中的所有多面体都会被环境光照射。
  下面的例子演示了设定场景中的第一个散射元素:
  

float lightDiffuse[] = new float[] { 0.2f, 0.3f, 0.6f, 1.0f };//漫反射光gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuse,0);  

  位置
  还需要设定光效的另一个重要属性,即光源3D空间中的位置。这不会影响环境元素,但其他两个元素由于其本性,只有在OpenGL在知道了场景中物体与光的相对位置后才能计算。例如:
  

float[] lightPos = new float[] {0,0,3,1};  //光源位置 gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPos, 0)  

  关于光效的设置还有很多,大家有兴趣可以自己研究,这里有篇不错的文章,大家可以看看http://hsw625728.blog.163.com/blog/static/39570728200885104210400/
  我们今天例子的效果:

  实例代码:
  


  • public class CubeRenderer implements Renderer {

  •     float box[] = new float[] {
  •             // FRONT
  •             -0.5f, -0.5f,  0.5f,
  •              0.5f, -0.5f,  0.5f,
  •             -0.5f,  0.5f,  0.5f,
  •              0.5f,  0.5f,  0.5f,
  •             // BACK
  •             -0.5f, -0.5f, -0.5f,
  •             -0.5f,  0.5f, -0.5f,
  •              0.5f, -0.5f, -0.5f,
  •              0.5f,  0.5f, -0.5f,
  •             // LEFT
  •             -0.5f, -0.5f,  0.5f,
  •             -0.5f,  0.5f,  0.5f,
  •             -0.5f, -0.5f, -0.5f,
  •             -0.5f,  0.5f, -0.5f,
  •             // RIGHT
  •              0.5f, -0.5f, -0.5f,
  •              0.5f,  0.5f, -0.5f,
  •              0.5f, -0.5f,  0.5f,
  •              0.5f,  0.5f,  0.5f,
  •             // TOP
  •             -0.5f,  0.5f,  0.5f,
  •              0.5f,  0.5f,  0.5f,
  •              -0.5f,  0.5f, -0.5f,
  •              0.5f,  0.5f, -0.5f,
  •             // BOTTOM
  •             -0.5f, -0.5f,  0.5f,
  •             -0.5f, -0.5f, -0.5f,
  •              0.5f, -0.5f,  0.5f,
  •              0.5f, -0.5f, -0.5f,
  •         };
  •     float lightAmbient[] = new float[] { 0.2f, 0.3f, 0.6f, 1.0f };  //环境光
  •     float lightDiffuse[] = new float[] { 0.2f, 0.3f, 0.6f, 1.0f };//漫反射光
  •     float[] lightPos = new float[] {0,0,3,1};  //光源位置
  • /*
  • * 因为进行光照处理,你必须告知系统你定义的模型各个面的方向,以便系统计算光影情况,方向的描述是通过向量点来描述的
  • */
  •     float norms[] = new float[] { //法向量数组,用于描述个顶点的方向,以此说明各个面的方向
  •             // FRONT
  •             0f,  0f,  1f, //方向为(0,0,0)至(0,0,1)即Z轴正方向
  •             0f,  0f,  1f,
  •             0f,  0f,  1f,
  •             0f,  0f,  1f,
  •             // BACK
  •             0f,  0f,  -1f,
  •             0f,  0f,  -1f,
  •             0f,  0f,  -1f,
  •             0f,  0f,  -1f,
  •             // LEFT
  •             -1f,  0f,  0f,
  •             -1f,  0f,  0f,
  •             -1f,  0f,  0f,
  •             -1f,  0f,  0f,
  •             // RIGHT
  •             1f, 0f, 0f,
  •             1f, 0f, 0f,
  •             1f, 0f, 0f,
  •             1f, 0f, 0f,
  •             // TOP
  •             0f,  1f, 0f,
  •             0f,  1f, 0f,
  •             0f,  1f, 0f,
  •             0f,  1f, 0f,
  •             // BOTTOM
  •             0f,  -1f, 0f,
  •             0f,  -1f, 0f,
  •             0f,  -1f, 0f,
  •             0f,  -1f, 0f
  •         };


  •     FloatBuffer cubeBuff;
  •     FloatBuffer normBuff;

  •     float xrot = 0.0f;
  •     float yrot = 0.0f;

  •     /**
  •      * 将float数组转换存储在字节缓冲数组
  •      * @param arr
  •      * @return
  •      */
  •     public FloatBuffer makeFloatBuffer(float[] arr) {
  •         ByteBuffer bb = ByteBuffer.allocateDirect(arr.length * 4);//分配缓冲空间,一个float占4个字节
  •         bb.order(ByteOrder.nativeOrder()); //设置字节顺序, 其中ByteOrder.nativeOrder()是获取本机字节顺序
  •         FloatBuffer fb = bb.asFloatBuffer(); //转换为float型
  •         fb.put(arr);        //添加数据
  •         fb.position(0);      //设置数组的起始位置
  •         return fb;
  •     }

  •     public CubeRenderer() {
  •         // TODO Auto-generated constructor stub
  •         cubeBuff = makeFloatBuffer(box);//转换float数组
  •         normBuff = makeFloatBuffer(norms);
  •     }


  •     protected void init(GL10 gl) {
  •         gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);//设置清屏时背景的颜色,R,G,B,A

  •         gl.glEnable(GL10.GL_LIGHTING); //启用光照
  •         gl.glEnable(GL10.GL_LIGHT0);  //开启光源0,最多可以开启8个光源
  •         //设置光照参数,也可以使用默认的,不设置
  •         gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_AMBIENT, lightAmbient, 0);
  •         gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_DIFFUSE, lightDiffuse, 0);
  •         gl.glLightfv(GL10.GL_LIGHT0, GL10.GL_POSITION, lightPos, 0);

  •         gl.glNormalPointer(GL10.GL_FLOAT, 0, normBuff);
  •         gl.glEnableClientState(GL10.GL_NORMAL_ARRAY);

  •         gl.glEnable(GL10.GL_DEPTH_TEST); //启用深度缓存
  •         gl.glEnable(GL10.GL_CULL_FACE);  //启用背面剪裁
  •         gl.glClearDepthf(1.0f);    // 设置深度缓存值
  •         gl.glDepthFunc(GL10.GL_LEQUAL);  // 设置深度缓存比较函数,GL_LEQUAL表示新的像素的深度缓存值小于等于当前像素的深度缓存值(通过gl.glClearDepthf(1.0f)设置)时通过深度测试
  •         gl.glShadeModel(GL10.GL_SMOOTH);// 设置阴影模式GL_SMOOTH
  •     }

  •     @Override
  •     public void onSurfaceCreated(GL10 gl, EGLConfig config) {
  •         // TODO Auto-generated method stub
  •         init(gl);
  •     }

  •     @Override
  •     public void onSurfaceChanged(GL10 gl, int w, int h) {
  •         // TODO Auto-generated method stub
  •         gl.glViewport(0, 0, w, h); //设置视窗
  •         gl.glMatrixMode(GL10.GL_PROJECTION); // 设置投影矩阵
  •         gl.glLoadIdentity();  //设置矩阵为单位矩阵,相当于重置矩阵
  •         GLU.gluPerspective(gl, 45.0f, ((float) w) / h, 0.1f, 10f);//设置透视范围
  •     }

  •     @Override
  •     public void onDrawFrame(GL10 gl) {
  •         // TODO Auto-generated method stub
  •         gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);// 清除屏幕和深度缓存

  •         gl.glMatrixMode(GL10.GL_MODELVIEW);   //切换至模型观察矩阵
  •         gl.glLoadIdentity();// 重置当前的模型观察矩阵
  •         GLU.gluLookAt(gl, 0, 0, 3, 0, 0, 0, 0, 1, 0);//设置视点和模型中心位置

  •         gl.glVertexPointer(3, GL10.GL_FLOAT, 0, cubeBuff);//设置顶点数据
  •         gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);

  •         gl.glRotatef(xrot, 1, 0, 0);  //绕着(0,0,0)与(1,0,0)即x轴旋转
  •         gl.glRotatef(yrot, 0, 1, 0);

  •         gl.glColor4f(1.0f, 0, 0, 1.0f);   //设置颜色,红色
  •         gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);  //绘制正方型FRONT面
  •         gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 4, 4);

  •         gl.glColor4f(0, 1.0f, 0, 1.0f);
  •         gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 8, 4);
  •         gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 12, 4);

  •         gl.glColor4f(0, 0, 1.0f, 1.0f);
  •         gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 16, 4);
  •         gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 20, 4);

  •         xrot += 0.5f;
  •         yrot += 0.5f;
  •     }

  • }
  




运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-668415-1-1.html 上篇帖子: 设定open_basedir导致PHP程序无法上传 下篇帖子: how_to_open_AnyChat_HD_video_effects如何开启视频高清效果
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表