《Android 3D游戏开发技术宝典——OpenGL ES 2.0》第6章光照,本章将向读者介绍光照效果的开发,通过本章的学习,读者可以为场景中的物体增加逼真的光照效果,大大提升了场景的真实感。本节为大家介绍散射光。

6.2.3  散射光(2)

说明 图6-11左侧的图表示光源位于场景左侧进行照射的情况,右侧的图表示光源位于右侧进行照射的情况。从左右两幅效果图的对比中可以看出,正对光源(入射角小)的位置看起来较亮,而随着入射角的增大越来越暗,直至入射角大于90 后完全不能照亮。

了解了散射光的基本原理及案例的运行效果后,就可以进行案例的开发了。由于实际上本案例仅仅是将案例Sample6_2复制了一份并进行了修改,因此这里仅给出修改的主要步骤,具体如下所列。

(1)由于散射光效果与光源的位置密切相关,因此需要将光源的位置传递进着色器以进行光照的计算。为了方便起见,首先需要对工具类MatrixState进行升级,增加存储当前光源位置的相关成员变量以及设置光源位置的方法,具体代码如下。

代码位置:见随书光盘中源代码/第6章/Sample6_3/com/bn/Sample6_3目录下的MatrixState.java。

  1. 1   public static float[] lightLocation = new float[] { 0, 0, 0 };  //光源位置数组
  2. 2   public static FloatBuffer lightPositionFB;                      //光源位置的缓冲
  3. 3   static ByteBuffer llbbL = ByteBuffer.allocateDirect(3 * 4);     //待用的字节缓冲
  4. 4   public static void setLightLocation(float x, float y, float z) {    //设置光源位置的方法
  5. 5       llbbL.clear();                                      //清除缓冲中原有的数据
  6. 6       lightLocation[0] = x;lightLocation[1] = y;lightLocation[2] = z;                                                                         //将新的光源位置存入数组
  7. 7       llbbL.order(ByteOrder.nativeOrder());                   //设置字节顺序
  8. 8       lightPositionFB = llbbL.asFloatBuffer();                //转换为float型缓冲
  9. 9       lightPositionFB.put(lightLocation);                 //将光源位置放入缓冲
  10. 10      lightPositionFB.position(0);                        //设置缓冲区起始位置
  11. 11  }

第1-3行为该类中新增加的成员变量,主要有光源位置数组、光源位置缓冲和待用字节缓冲。

第4-11行为设置光源位置的方法,该方法主要功能为将参数中传递过来的光源位置首先存入数组,然后再存放进对应的float型缓冲供渲染时传入管线。

(2)接着需要修改的是Ball类,主要是增加初始化法向量数据以及将法向量数据传入渲染管线的相关代码,具体情况如下。

代码位置:见随书光盘中源代码/第6章/Sample6_3/com/bn/Sample6_3目录下的Ball.java。

  1. 1   public class Ball {
  2. 2       ……//此处省略了部分代码,请读者自行查看随书光盘中的源代码
  3. 3       int maNormalHandle;                                 //顶点法向量属性引用
  4. 4        int maLightLocationHandle;                         //光源位置属性引用
  5. 5       FloatBuffer mNormalBuffer;                          //顶点法向量数据缓冲引用
  6. 6       public Ball(MySurfaceView mv) {/*代码省略*/}
  7. 7       public void initVertexData() {                      //初始化顶点数据的方法
  8. 8           ……//此处省略了部分代码,请读者自行查看随书光盘中的源代码
  9. 9           ByteBuffer nbb = ByteBuffer.allocateDirect(vertices.length*4);//创建顶点法向量缓冲
  10. 10          nbb.order(ByteOrder.nativeOrder());         //设置字节顺序
  11. 11          mNormalBuffer = nbb.asFloatBuffer();            //转换为float型缓冲
  12. 12          mNormalBuffer.put(vertices);                    //向缓冲区中放入顶点法向量数据
  13. 13          mNormalBuffer.position(0);                  //设置缓冲区起始位置
  14. 14      }
  15. 15      public void initShader(MySurfaceView mv) {      //初始化着色器
  16. 16          ……//此处省略了部分代码,请读者自行查看随书光盘中的源代码
  17. 17          maNormalHandle= GLES20.glGetAttribLocation( //获取顶点法向量属性变量引用
  18. 18                  mProgram, "aNormal");
  19. 19          maLightLocationHandle=GLES20.glGetUniformLocation(
  20. 20                  mProgram, "uLightLocation");            //获取光源位置一致变量引用
  21. 21      }
  22. 22      public void drawSelf() {
  23. 23          ……//此处省略了部分代码,请读者自行查看随书光盘中的源代码
  24. 24              GLES20.glUniform3fv(                        //将光源位置传入渲染管线
  25. 25                  maLightLocationHandle, 1, MatrixState.lightPositionFB);
  26. 26          GLES20.glVertexAttribPointer(               //将顶点位置数据传入渲染管线
  27. 27                  maPositionHandle, 3, GLES20.GL_FLOAT,false, 3 * 4, mVertexBuffer);
  28. 28          GLES20.glVertexAttribPointer(               //将顶点法向量数据传入渲染管线
  29. 29                  maNormalHandle, 3, GLES20.GL_FLOAT, false,3 * 4, mNormalBuffer);
  30. 30          GLES20.glEnableVertexAttribArray(maPositionHandle);     //启用顶点位置数据
  31. 31              GLES20.glEnableVertexAttribArray(maNormalHandle);   //启用顶点法向量数据
  32. 32          GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, vCount);    //绘制球体
  33. 33  }}

第3-5行增加了声明顶点法向量属性变量引用、光源位置一致变量引用及顶点法向量数据缓冲的代码。

第7-14行为初始化顶点数据的方法,其中增加了初始化顶点法向量数据缓冲的相关代码。由于本案例中原始情况下的球心位于坐标原点,所以每个顶点法 向量的X、Y、Z轴分量与顶点的X、Y、Z坐标是一致的。这样就不必单独计算每个顶点的法向量了,直接将顶点坐标序列看作顶点法向量序列使用即可。

第15-21行在初始化着色器的方法中增加了获取顶点法向量属性变量引用以及光源位置一致变量引用的代码。

第22-33行为绘制球的drawSelf方法,其中增加了将法向量数据与光源位置数据传送进渲染管线的代码,同时也增加了启用顶点法向量数据的代码。

提示 并不是所有的情况下顶点法向量与顶点坐标都有必然联系,很多情况下顶点的法向量需要单独给出,本书中后面会有很多这样的案例。

6.2.3 散射光(2)OpenGL ES 2.0相关推荐

  1. 《OpenGL ES 2.0游戏开发(上卷):基础技术和典型案例》——6.5节光照的每顶点计算与每片元计算...

    本节书摘来自异步社区<OpenGL ES 2.0游戏开发(上卷):基础技术和典型案例>一书中的第6章,第6.5节光照的每顶点计算与每片元计算,作者 吴亚峰,更多章节内容可以访问云栖社区&q ...

  2. Android OpenGL(二) 学习《Android 3D 游戏开发技术宝典 -openGL ES 2.0》

    note: 1 1-4章相关基础 2 5-8章重点 3 9-15章重点的进阶 4 16-19章相关技术:物理,传感器,事件交互. 5 20-22章 实例. 第一章 基础环境 第二章 游戏相关开发基础 ...

  3. 《Android 3D游戏开发技术宝典——OpenGL ES 2.0》.(吴亚峰).[PDF]ckook

    图书作者: 吴亚峰 图书编号: 9787115277701 图书格式: PDF 出 版 社: 人民邮电出版社 出版年份: 2012 图书页数: 700-800 [内容简介] 随着智能手机移动嵌入式平台 ...

  4. 利用JNI技术在Android中调用C++形式的OpenGL ES 2.0函数

    1.                 打开Eclipse,File-->New-->Project--->Android-->AndroidApplication Projec ...

  5. cocos2d-x 2.X for Android中需要使用OpenGL ES 2.0

    cocos2d-x 2.X for Android中需要使用OpenGL ES 2.0 到了2.X版本中,cocos2d-x for Android已经不再支持(或者说放弃支持)opengl es 1 ...

  6. OpenGL ES 3.0 基础知识

    首先要了解OpenGL的图形管线有哪些内容,再分别去了解其中的相关的关系: 管线分别包括了顶点缓冲区/数组对象,定点着色器,纹理,片段着色器,变换反馈,图元装配,光栅化,逐片段操作,帧缓冲区.其中顶点 ...

  7. LINUX 下构建OpenGL ES 3.0

    Ubuntu LINUX 下构建OpenGL ES 3.0 Category : OpenGL LINUX 下构建OpenGL ES 3.0 软件:PowerVRSDKSetup-4.0.run-x6 ...

  8. 《OpenGL ES 2.0游戏开发(上卷):基础技术和典型案例》一6.6 本章小结

    本节书摘来异步社区<OpenGL ES 2.0游戏开发(上卷):基础技术和典型案例>一书中的第6章,第6.6节,作者: 吴亚峰 责编: 张涛,更多章节内容可以访问云栖社区"异步社 ...

  9. 【AR实验室】OpenGL ES绘制相机(OpenGL ES 1.0版本)

    0x00 - 前言 之前做一些移动端的AR应用以及目前看到的一些AR应用,基本上都是这样一个套路:手机背景显示现实场景,然后在该背景上进行图形学绘制.至于图形学绘制时,相机外参的解算使用的是V-SLA ...

最新文章

  1. 路由器、路由与路由表
  2. leetcode算法题--反转单词前缀
  3. win bat 输入参数
  4. 创建预留mb21添加附加字段的增强
  5. 关于go语言中的JWT(JSON WEB TONKE)ECHO
  6. Android之invalid address or address of corrupt block 0xabb494a0 passed to dlfree崩溃解决办法
  7. opencv 把3通道图像转成单通道_小强学Python+OpenCV之-1.4.3图像(矩阵)加减运算
  8. mysql cluster 设置单向复制_mysql单向主从配置
  9. 关于vs2008设计视图假死的原因及解决方案总结
  10. Java开发岗位面试题
  11. java中如何播放wav_如何播放.wav文件与java
  12. NXP数学电机库PI控制器参数的理解
  13. ovnif摄像头修改ip
  14. linux镜像文件iso下载RedHat,RedHat Enterprise Linux ISO文件下载镜像站点
  15. 运放专题:电压电流转换
  16. python pyodbc使用方法
  17. 程序员老外通过编程赚钱的10个途径
  18. 学习嵌入式实时操作系统(RTOS),以uc/OS-III为例
  19. zoj 3551 Bloodsucker (概率dp)
  20. rimraf : 无法加载文件 C:\Users\Admin\AppData\Roaming\npm\rimraf.ps1,因为在此系统上禁止运行脚本。有关详细信息,请参阅

热门文章

  1. 医疗专业计算机考试题库,计算机专业考试题库(附答案)
  2. 阿里资深技术岗被裁员,混到35岁真的只能坐以待毙了吗?
  3. adb shell dumpsys meminfo 内存测试指标解析
  4. 等参元八节点matlab,平面四边形八节点等参元matlab程序.docx
  5. 微信如何发送超大的gif
  6. 用Unity实现LOL游戏中聊天对话框的功能
  7. jq制作QQ简易聊天框
  8. PDF内存太大怎么压缩?三个方法教你如何压缩PDF文件
  9. Excel操作类-CSpreadSheet and BasicExcel
  10. Tryhackme-Network Security