您的位置:首页 > 运维架构

【翻译】安卓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去使用什么颜色,使用下面的方法:

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教程之五——关于网格的更多事
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android opengl ES