4.4 使用新的颜色进行渲染(Rendering with the New Color Attribute)

现在我们已经在顶点数据中增加了一个颜色属性数据并且已经更新了相应的顶点着色器及片元着色器,下一步是移除老的使用uniform类型数据进行绘制的代码并且告诉OpenGL使用顶点属性颜色进行绘制。

4.4.1 更新常量(Updating Constants)

在AirHockeyRenderer的开始处添加如下常量:

//AirHockey2/src/com/airhockey/android/AirHockeyRenderer.java
private static final String A_COLOR = "a_Color";
private static final int COLOR_COMPONENT_COUNT = 3;
private static final int STRIDE =
(POSITION_COMPONENT_COUNT + COLOR_COMPONENT_COUNT) * BYTES_PER_FLOAT;

    同时也增加一个变量存储a_Color着色器变量的位置引用,代码如下:

//AirHockey2/src/com/airhockey/android/AirHockeyRenderer.java
private int aColorLocation;

现在我们可以移除与u_Color关联的一些常量及变量了。
    你注意到我们添加了一个特殊的常量STRIDE了吗?因为我们现在在同一个数组中存储了顶点位置数据及属性颜色数据,OpenGL在读取位置数据的时候不能再认为每一个顶点位置数据都是相邻的,一旦OpenGL已经读取了一个顶点位置数据,如果它还想读取下一个位置数据那么必须跳过当前位置的颜色属性数据。 这里我们使用stride(步长)告诉OpenGL在相邻两个顶点之间间隔多少字节,这样OpenGL才知道要跳过多少字节的数据。
    如下图1展示了颜色与顶点位置数据是如何存储在同一个数组中的,stride(步长)告诉OpenGL每两个相邻的顶点或者颜色数据之前的间隔是多少。如果你不喜欢这种方式,你也可以针对每个属性使用一个数组进行数据存储,就如下图2所示一样,当然使用同一个数组会理高效,但是当我们想要使用同一个偏移量进行顶点数据或者颜色数据的更新时或许使用多个数组会更有意义。

图 1(单个数组存储数据)

图 2(多个数组进行存储数据)

4.4.2 更新onSurfaceCreated(Updating onSurfaceCreated())

下一步是更新onSurfaceCreated()使用新的颜色属性,第一步是得到颜色属性的位置引用,所以先把与u_Color变量相关的代码去掉并且增加如下代码:

//AirHockey2/src/com/airhockey/android/AirHockeyRenderer.java
aColorLocation = glGetAttribLocation(program, A_COLOR);

同时也需要更新对glVertexAttribPointer()的调用以使用stride参数:

//AirHockey2/src/com/airhockey/android/AirHockeyRenderer.java
glVertexAttribPointer(aPositionLocation, POSITION_COMPONENT_COUNT, GL_FLOAT,
false, STRIDE, vertexData);

现在我们需要告诉OpenGL将颜色数据与着色器变量a_Color更新关联,在OnSurfaceCreated()最后增加如下代码:

//AirHockey2/src/com/airhockey/android/AirHockeyRenderer.java
vertexData.position(POSITION_COMPONENT_COUNT);
glVertexAttribPointer(aColorLocation, COLOR_COMPONENT_COUNT, GL_FLOAT,
false, STRIDE, vertexData);
glEnableVertexAttribArray(aColorLocation);

这段代码相当重要,所以让我们来稍微理解下:
    1)首先把vertexData 的位置更新为 值为2的常量POSITION_COMPONENT_COUNT,为什么要做这一步呢?因为当OpenGL开始读取颜色数据的时候是从第一人颜色数据开始读取而不是从第一个顶点数据开始读取。
    因为我们需要跳过第一个顶点数据,因此我把位置设置为POSITION_COMPONENT_COUNT, 这样的话当OpenGLd 在读取颜色数据的时候就会读取到第一个颜色数据而不是第一个顶点数据。如果我们把位置设置成0,那么OpenGL就会把第一个位置数据当成颜色数据进行使用,这样的结果肯定是不对的。
    2)然后调用glVertexAttribPointer() 把数组中的颜色数据与着色器变量a_Color进行关联,同样的stride参数告诉OpenGL在每两个颜色之间间隔多少个字节,这样的话当OpenGL在读取颜色数据的时候才会知道下一个顶点的颜色数据要跳过字节,很关键的一点是stride因子是以字节为单位计算的。
    即使在OpenGL中的颜色是用四个分量进行表示的,我们也并不需要指定所有的分量。不像uniform类型的颜色变量,OpenGL会把没有指定的分量指定为默认值:RGB分别指定为0,A指定为1。
    3)最后就像顶点属性一样,我们开启对颜色属性的使用(enable the vertex attribute for the color attribute)

4.4.3 更新onDrawFrame(Updating onDrawFrame)

最后一步就是删除glUniform4f()的调用,因为我们已经不需要了。我们已经把颜色数组与a_Color进行关联,现在需要调用的是glDrawArrays(),这样OpenGL就可以从数组中读取颜色数据了。

4.4.4 运行结果(Putting It All Together)

现在运行代码将会看到如下效果图:

现在我们的球台桌面看起来比之前更好了,而且也可以清楚的看到桌面的中心更明亮边缘更暗。然而我们也可以清楚的辨认出每一个三角形的大体轮廓,这是因为线性混合的方向也三角形有关,因此虽然三角形的颜色看起来更平滑,但我们也可以看出哪个三角形在哪里开始哪个三角形在哪里结束。
    要减少或者消除这种效应,我们可以使用更多的三角形或者使用光照算法计算每个片元的颜色值,在第13章中将会学习光照算法相关知识。

Part I 空气曲棍球 Chapter4 (4.4 Rendering with the New Color Attribute)相关推荐

  1. Part I 空气曲棍球 Chapter4 Adding Color and Shade)

    由于后面的章节篇幅比较大点,所以我们会把每一章单独分成几篇文章来写(后面将采用这种模式,除非篇幅比较小). 在实际中,每个物体都会有不同的颜色:比如我们的家里面的墙壁,它都是使用同一种颜色进行粉刷的, ...

  2. Part I 空气曲棍球 Chapter4 (4.2 Introducing Triangle Fans)

    4.2 引入Triangle Fans(Introducing Triangle Fans) 在新的顶点结构中,中心处将会有一个顶点坐标,这样的话绘制矩形就必须采用四个三角形而不是两个了.我们把新的中 ...

  3. Part I 空气曲棍球 Chapter4 (4.3 Adding a New Color Attribute)

    4.3 增加新的颜色属性(Adding a New Color Attribute) 我们已经通过加入中心点更新了我们桌面顶点结构,现在可以对每个顶点增加一个颜色属性了,现在更新到到整个顶点数组,如下 ...

  4. Part I 空气曲棍球 Chapter4 (4.1 Smooth Shading)

    4.1 平滑着色(Smooth Shading) 在第二章中,我们学习了如何使用uniform类型变量定义要绘制的三角形的颜色,如下图所示: 我们已经知道OpenGL只支持绘制点.线.三角形的命令,如 ...

  5. 《OpenGL ES应用开发实践指南:Android卷》—— 2.1 为什么选择空气曲棍球

    本节书摘来自华章出版社<OpenGL ES应用开发实践指南:Android卷>一 书中的第2章,第2.1节,作者:(美)Kevin Brothaler ,更多章节内容可以访问云栖社区&qu ...

  6. Part I 空气曲棍球 Chapter8(Building Simple Objects)

    我们的空气曲棍球项目已经捣鼓好久了,现在绘制出来的桌面也是呈现出了一个好视角并且配合纹理映射后看起来更好了:然而由于球棍只是一个点所以看起来并不像真正的球棍,你能想象下使用像一个点一样的球棍打球会是什 ...

  7. 空气曲棍球 由哪几部分组成_Excel中的曲棍球运动员数据分析

    空气曲棍球 由哪几部分组成 Congratulations to the USA Women's Hockey team, who won the Olympic gold medal. They b ...

  8. 《OpenGL ES应用开发实践指南:Android卷》—— 2.3 定义空气曲棍球桌子的结构...

    本节书摘来自华章出版社<OpenGL ES应用开发实践指南:Android卷>一 书中的第2章,第2.3节,作者:(美)Kevin Brothaler ,更多章节内容可以访问云栖社区&qu ...

  9. Part I 空气曲棍球 Chapter9(Adding Touch Feedback)

    通过支持触控反馈获得好的用户交互体验是很多应用和游戏的基石,这样会让用户觉得他们能真正使用一些真实的东西,即使用户只是对着空白的屏幕也是如此.一些手机游戏之所以非常流行只是因为增加了一些触控而已:此时 ...

最新文章

  1. http协议的Request Payload 和 Form Data 的区别
  2. 【错误记录】Android Studio 编译报错 ( AppCompat does not support the current theme features )
  3. [团队项目]后续安排 Github
  4. c++ primer 5th 笔记:第二章
  5. Got minus one from a read call异常
  6. 华为tsm_台积电:如果不能向华为销售芯片,其他订单可快速取代华为空缺
  7. [导入]ASP常用函数:getIMG()
  8. c++多线程基础4(条件变量)
  9. Linux(Centos7) 设置静态IP
  10. sql用于字符串的聚合函数_SQL字符串函数用于数据整理(争用)
  11. 最新即时通讯聊天安卓APP源码+全开源/Uniapp内核
  12. linux的源码安装步骤(以安装nginx为例)
  13. oracle 绑定变量语法,Delphi使用绑定变量法操作Oracle
  14. [C++]判断齐次坐标系中三点是否共线(三个向量是否共面)
  15. 小米路由器4刷padavan固件
  16. 安装谷歌浏览器步骤:
  17. 超级计算机 弦理论,关于灵魂的六大猜想
  18. SRAM和DRAM存储原理
  19. 川崎机器人f控制柜接线图_川崎机器人PROFINET总线通信图文教程
  20. Lined List

热门文章

  1. 高斯消元法python编程_高斯消元法的Python实现
  2. 有时候Mac下删除文件磁盘空间无法释放
  3. hanlp词性对照表
  4. 2011年托业考试时间
  5. 自动驾驶岗位招聘——感知算法、决策规划算法、系统架构师
  6. 解决Linux环境下重启后Java环境变量失效
  7. 日常工作笔记(持续更新中。。)
  8. ILP(Interledger)书信教程
  9. 通过yum安装iftop
  10. 【2023 年第十三届 MathorCup 高校数学建模挑战赛】A 题 量子计算机在信用评分卡组合优化中的应用 详细建模过程解析及代码实现