文档章节

【翻译】安卓opengl ES教程之四——添加颜色

tnjin
 tnjin
发布于 2015/12/28 22:42
字数 1542
阅读 747
收藏 2

上一篇教程是关于变换的。这篇教程比较短,我将会告诉你如何给网格添加颜色。我会继续使用教程二的源码。

添加颜色

没有颜色的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教程之五——关于网格的更多事

© 著作权归作者所有

tnjin

tnjin

粉丝 27
博文 36
码字总数 28535
作品 0
海淀
Android工程师
私信 提问
加载中

评论(2)

即行
即行
2222
即行
即行
1
Android 使用 OpenGL ES 绘制三角形

1. OpenGL ES 简介 OpenGL 是一个跨平台的图形 API,为 3D 图形处理硬件制定了一个标准软件接口。OpenGL ES 是为嵌入式设备设计的 OpenGL 规范,Android 提供了对 OpenGL ES 的支持。 OpenGL...

落英坠露
05/02
0
0
OpenGL实现物体动画和视频特效

OpenGL实现视频的水印、滤镜?OpenGL实现视频的剪裁、旋转? 2D/3D物体的 旋转,平移,缩放? OpenGL图片滤镜与视频滤镜? 矩阵(Matrix)是一个按照长方阵列排列的复数或实数集合,最早来自于方...

shareus
2018/04/24
0
0
Android图形---OpenGL(二)

本文译自:http://developer.android.com/guide/topics/graphics/opengl.html OpenGL 包 一旦使用GLSurfaceView和GLSurfaceView.Renderer类给OpenGL建立了一个View容器,那么就可以开始使用以...

长平狐
2012/10/16
81
0
cocos2dx- call to OpenGL ES API with no current context(logged once per thread)

Android APP 在红米2(Android 5.1系统)上进行全屏应用切换的时候,会出现卡屏,不会闪退并且出现频繁.在红米note和moto x1(Android 4.4系统)中偶尔出现. 其他手机上暂时还未出现全屏切换...

GLancelot
2015/08/14
1K
3
Android图形---OpenGL(一)

本文译自:http://developer.android.com/guide/topics/graphics/opengl.html Android系统包含了OpenGL(Open Graphics Library),从而给2D和3D图形提供了高性能的支持,尤其是OpenGL ES A...

长平狐
2012/10/16
217
0

没有更多内容

加载失败,请刷新页面

加载更多

gradle grovvy中的闭包

1. 无参数的闭包 //这b1就是一个闭包def b1={ println "hello b1"}//定义方法,包含闭包类型的参数def method1(Closure closure){closure()}//执行method1method1(b1) 执行结果 ...

edison_kwok
14分钟前
1
0
基于Spring Boot + Dubbo的全链路日志追踪(一)

一、 概要 当前公司后端整体架构为:Spring Boot + Dubbo。由于早期项目进度等原因,对日志这块没有统一的规范,基本上是每个项目自己管自己的日志。这也对后面的问题排查带来了很大的困难,...

明天以后
今天
6
0
安装fastdfs文件服务器步骤

1、安装libfastcommon wget https://github.com/happyfish100/libfastcommon/archive/master.zip 解压后安装 cd fastcommon-master ./make.sh ./make.sh install 2、安装 FastDFS,从sourcef......

lsjlgo
今天
3
0
MySQL 5.7 免安装版配置

下载地址:https://dev.mysql.com/downloads/mysql/ 安装步骤 1.下载zip解压到目录下 2.配置环境变量 新建系统变量:MYSQL_HOME,值:D:\DevelopmentTool\Mysql-5.7.26-winx64 修改path变量:...

华山猛男
今天
7
0
java map的遍历

//从大的角度可以分为两类Set<String> set=map.keySet();这里面还可以分为3类, 从set的角度来分 //Set<Map.Entry<String, String>> entery=map.entrySet(); public class Test { public sta......

南桥北木
今天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部