【翻译】安卓opengl ES教程之四——添加颜色
2015-12-28 22:42
861 查看
上一篇教程是关于变换的。这篇教程比较短,我将会告诉你如何给网格添加颜色。我会继续使用教程二的源码。
添加颜色
没有颜色的3D模型看起来很无趣,那么,接下来,让我们给它添加点颜色吧。一般来说,颜色不用过多解释。OpenGL使用RGBA(red,green,blue,alpha)颜色模式。前三个见字知意,不多说。第四个值代表透明度,即颜色有多纯净。如果你想阅读关于颜色的更多信息,可以看这里:RGB颜色模式——维基百科,免费的百科全书
你也许对使用十六进制(#FF00FF)或者十进制(255,0,255)定义颜色很熟悉,在OpenGL中,我们使用0~1来定义颜色,其中0代表十进制定义颜色的0(#00),1代表十进制定义颜色的255(#FF)。
最简单给网格上色的方式称之为顶点着色,我将讲解两个不同的方法来实现它。纯色着色是指每个顶点用纯色填充,渐变着色是指混合每个顶点的颜色。
纯色填充
纯色填充很简单,只需要告诉OpenGL ES在渲染时使用什么颜色即可。有一点需要记住的是,一旦你设置了OpenGL使用的颜色,那么,直到你再次改变颜色,OpenGL才会改变颜色。这也就意味着,如果你有两个不同的四边形,当你在渲染第二个四边形第一帧的时候去告诉OpenGL 改变颜色,这两个四边形的颜色将会不一样,但是在下一帧,两个的颜色就变得一样了。
告诉OpenGL ES去使用什么颜色,使用下面的方法:
默认的值是red=1,green=1,blue=1,alpha=1。这个颜色是白色,这也是为什么所有的四边形最开始的时候是白色的原因。
创建一个新的class。命名为FlatColoredSquare,和square几乎一样。在FlatColoredSquare的draw方法中,增加如下代码:
我通常会增加一个像上面那样的注释,因为我习惯读这样的格式。这让我review我的代码时会变得比较容易。
现在这个方法应该看起来像这样:
然后改变renderer类,使用FlatColoredSquare代替Square:
记住,在你设置颜色之后,所有被渲染的对象都会使用同一个颜色,在两帧之间不会被重置。
如果你编译运行,就会看到一个被纯色填充的蓝色四边形。
为了给接下来的渐变着色的四边形腾开位置,我们把这个四边形平移一下。
注意:对于纯色填充,你无需告诉OpenGL ES去开启或者关闭什么状态,因为openGL ES默认使用纯色作为着色方式。
渐变填充
渐变填充,只要你给每个顶点赋予不同颜色。openGL ES会插值计算两个顶点间的颜色,你将会得到一个渐变的颜色效果。和纯色填充一样,渐变填充也是会一直使用你设定的颜色,直到你告诉openGL ES去做点改变。
创建一个新的class,命名为SmoothColoredSquare,和Square类,FlatColoredSquare类几乎一样,像下面这样修改这个类:
定义每个顶点的颜色:
颜色的定义顺序是很重要的,因为他们是按顺序映射到顶点上的,第一个颜色(1f, 0f, 0f, 1f ) 会被映射到左上角,第二个颜色 ( -1.0f, 1.0f, 0.0f ) 会被映射给左下角,其余的你可以自己推断了。提示,看上图。
就像我们处理顶点和顺序索引一样,把他们放到buffer中:
别忘了添加colorBuffer作为这个类的属性变量。
同样,我们需要开始颜色缓冲,并告诉openGL ES颜色缓冲的位置。
别忘了禁用颜色缓冲,如果你不禁用,那么两个四边形都会被渲染成渐变色。
让我们使用这个新的类,把它添加到renderer中:
我们把这个四边形下移一点,这样他们俩就不会重叠了。
现在如果你编译运行,就会看到两个四边形,一个是蓝色填充,一个是渐变色填充。
引用
这篇教程引用如下文献:
Android Developers
OpenGL ES 1.1 Reference Pages
你可以下载教程的源码:Tutorial_Part_IV
你也可以检出代码:code.google.com
上一篇教程:【翻译】安卓opengl ES教程之三——变换
下一篇教程:安卓openGL ES教程之五——关于网格的更多事
添加颜色
没有颜色的3D模型看起来很无趣,那么,接下来,让我们给它添加点颜色吧。一般来说,颜色不用过多解释。OpenGL使用RGBA(red,green,blue,alpha)颜色模式。前三个见字知意,不多说。第四个值代表透明度,即颜色有多纯净。如果你想阅读关于颜色的更多信息,可以看这里:RGB颜色模式——维基百科,免费的百科全书你也许对使用十六进制(#FF00FF)或者十进制(255,0,255)定义颜色很熟悉,在OpenGL中,我们使用0~1来定义颜色,其中0代表十进制定义颜色的0(#00),1代表十进制定义颜色的255(#FF)。
最简单给网格上色的方式称之为顶点着色,我将讲解两个不同的方法来实现它。纯色着色是指每个顶点用纯色填充,渐变着色是指混合每个顶点的颜色。
纯色填充
纯色填充很简单,只需要告诉OpenGL ES在渲染时使用什么颜色即可。有一点需要记住的是,一旦你设置了OpenGL使用的颜色,那么,直到你再次改变颜色,OpenGL才会改变颜色。这也就意味着,如果你有两个不同的四边形,当你在渲染第二个四边形第一帧的时候去告诉OpenGL 改变颜色,这两个四边形的颜色将会不一样,但是在下一帧,两个的颜色就变得一样了。告诉OpenGL ES去使用什么颜色,使用下面的方法:
public abstract void glColor4f(float red, float green, float blue, float alpha)
默认的值是red=1,green=1,blue=1,alpha=1。这个颜色是白色,这也是为什么所有的四边形最开始的时候是白色的原因。
创建一个新的class。命名为FlatColoredSquare,和square几乎一样。在FlatColoredSquare的draw方法中,增加如下代码:
gl.glColor4f(0.5f, 0.5f, 1.0f, 1.0f); // 0x8080FFFF
我通常会增加一个像上面那样的注释,因为我习惯读这样的格式。这让我review我的代码时会变得比较容易。
现在这个方法应该看起来像这样:
public void draw(GL10 gl) { gl.glColor4f(0.5f, 0.5f, 1.0f, 1.0f); ...
然后改变renderer类,使用FlatColoredSquare代替Square:
public class OpenGLRenderer implements Renderer { private FlatColoredSquare flatSquare; // 改动 public OpenGLRenderer() { // 初始化这个四边形 flatSquare = new FlatColoredSquare(); // 改动 } public void onDrawFrame(GL10 gl) { ... flatSquare.draw(gl); // 别忘了改变这个位置 ... }
记住,在你设置颜色之后,所有被渲染的对象都会使用同一个颜色,在两帧之间不会被重置。
如果你编译运行,就会看到一个被纯色填充的蓝色四边形。
为了给接下来的渐变着色的四边形腾开位置,我们把这个四边形平移一下。
public void onDrawFrame(GL10 gl) { gl.glLoadIdentity(); // 向屏幕里移动7个单位,向上移动1.5个单位 gl.glTranslatef(0, 1.5f, -7); // 绘制我们的纯色四边形 flatSquare.draw(gl); }
注意:对于纯色填充,你无需告诉OpenGL ES去开启或者关闭什么状态,因为openGL ES默认使用纯色作为着色方式。
渐变填充
渐变填充,只要你给每个顶点赋予不同颜色。openGL ES会插值计算两个顶点间的颜色,你将会得到一个渐变的颜色效果。和纯色填充一样,渐变填充也是会一直使用你设定的颜色,直到你告诉openGL ES去做点改变。创建一个新的class,命名为SmoothColoredSquare,和Square类,FlatColoredSquare类几乎一样,像下面这样修改这个类:
定义每个顶点的颜色:
public class SmoothColoredSquare { ... // 映射给每个顶点的颜色 float[] colors = { 1f, 0f, 0f, 1f, // vertex 0 red 0f, 1f, 0f, 1f, // vertex 1 green 0f, 0f, 1f, 1f, // vertex 2 blue 1f, 0f, 1f, 1f, // vertex 3 magenta }; ...
颜色的定义顺序是很重要的,因为他们是按顺序映射到顶点上的,第一个颜色(1f, 0f, 0f, 1f ) 会被映射到左上角,第二个颜色 ( -1.0f, 1.0f, 0.0f ) 会被映射给左下角,其余的你可以自己推断了。提示,看上图。
就像我们处理顶点和顺序索引一样,把他们放到buffer中:
public SmoothColoredSquare() { ... // float为3字节, colors (RGBA) * 4 bytes ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4); cbb.order(ByteOrder.nativeOrder()); colorBuffer = cbb.asFloatBuffer(); colorBuffer.put(colors); colorBuffer.position(0); }
别忘了添加colorBuffer作为这个类的属性变量。
//我们的颜色缓冲 private FloatBuffer colorBuffer;
同样,我们需要开始颜色缓冲,并告诉openGL ES颜色缓冲的位置。
public void draw(GL10 gl) { ... gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer); // 开启渲染时的颜色缓冲 gl.glEnableClientState(GL10.GL_COLOR_ARRAY); // NEW LINE ADDED. // 指出颜色缓冲的位置 gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer); // NEW LINE ADDED. gl.glDrawElements(GL10.GL_TRIANGLES, indices.length, GL10.GL_UNSIGNED_SHORT, indexBuffer); ... // 禁用颜色缓冲 gl.glDisableClientState(GL10.GL_COLOR_ARRAY); ... }
别忘了禁用颜色缓冲,如果你不禁用,那么两个四边形都会被渲染成渐变色。
让我们使用这个新的类,把它添加到renderer中:
public class OpenGLRenderer implements Renderer { private FlatColoredSquare flatSquare; private SmoothColoredSquare smoothSquare; // 新添加的代码 public OpenGLRenderer() { // Initialize our squares. flatSquare = new FlatColoredSquare(); smoothSquare = new SmoothColoredSquare(); // 新添加的代码 }
我们把这个四边形下移一点,这样他们俩就不会重叠了。
public void onDrawFrame(GL10 gl) { ... // 向下平移 gl.glTranslatef(0, -3f, 0); // 绘制我们的渐变四边形 smoothSquare.draw(gl); }
现在如果你编译运行,就会看到两个四边形,一个是蓝色填充,一个是渐变色填充。
引用
这篇教程引用如下文献:Android Developers
OpenGL ES 1.1 Reference Pages
你可以下载教程的源码:Tutorial_Part_IV
你也可以检出代码:code.google.com
上一篇教程:【翻译】安卓opengl ES教程之三——变换
下一篇教程:安卓openGL ES教程之五——关于网格的更多事
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories