Hello EGL
作者: 功夫羊 kongfu.yang(a)gmail.com
日期: 2010-01-28
本文介绍第一个 OpenGL ES程序:Hello EGL

注:本文中例子针对Windows CE平台编写。

OpenGL ES简化了模型描述,取消了通过在 glBegin/glEnd 之间使用大量glVertex之类的调用来逐点描述模型,统一到使用VertexArray。

下面我们就来画一个简单的物体:用三角形拼出的HELLO EGL。该物体的示意图 如下:

图:helloegl certex layout

照例,先New App:

图:new app

然后设置一下项目属性:

图:project properties

共有三处要改的,使得该项目可以利用上如下图所示的库和头文件:

图:my lib files

首先是头文件包含目录:

图:project include dir

然后是库文件目录:

图:project lib dir

最后是OpenGL ES库:

图:project egl lib

OK,环境准备好了,可以写代码了。先把我们准备好的OpenGL ES初始化代码加 上:

图:code skeleton

最后标记出来的那个draw()函数就是实际绘制HELLO EGL的代码了:

图 draw code

正如前面提过的,我们只能通过 VERTEX_ARRAY 批量的将模型顶点坐标发送给 OpenGL ES,为此需要先 glEnableClientState() 以打开相关支持。为了让世界 看上去更美好一点,我还用 ColorArray 给每个顶点指定了颜色。然后通过 glVertexPointer/glColorPointer 将数据发送出去,再通过 glDrawArrays(GL_TRIANGLES) 进行绘制。值得一提的是,目前 GLES 不支持 GL_QUADS。 除了调用 glDrawArrays(),OpenGL ES 还提供了更为灵活的 glDrawElements() 方法,值得看一下规范里的说明。


glEnableClientState (GL_VERTEX_ARRAY);
glEnableClientState (GL_NORMAL_ARRAY);
glEnableClientState (GL_TEXTURE_COORD_ARRAY);
glEnableClientState (GL_COLOR_ARRAY);

glVertexPointer (...);
glColorPointer (...);

glDrawArrays (GL_TRIANGLES);
glDrawElements ();

剩下的奥密就全在数组 helloVertex 里了。其实它的内容已经完全表示的本文 开始的那张示意图里了,建议您自己推算一下,以熟悉 TRIANGLES 建模。这个 小小的例子也可以利用 GL_TRIANG_STRIP 得到很大的优化,感兴趣的可以练习 一下。

代码如下:hellomesh.h


#ifndef _HELLO_MESH_
#define _HELLO_MESH_

GLfixed helloVertex[] = {	// HELLO EGL
	// H
	Float2Fixed(0.0f), Float2Fixed(0.0f),  Float2Fixed(0.1f), Float2Fixed(0.0f),  Float2Fixed(0.1f), Float2Fixed(0.7f),
	Float2Fixed(0.0f), Float2Fixed(0.0f),  Float2Fixed(0.1f), Float2Fixed(0.7f),  Float2Fixed(0.0f), Float2Fixed(0.7f),

	Float2Fixed(0.1f), Float2Fixed(0.3f),  Float2Fixed(0.3f), Float2Fixed(0.3f),  Float2Fixed(0.3f), Float2Fixed(0.4f),
	Float2Fixed(0.1f), Float2Fixed(0.3f),  Float2Fixed(0.3f), Float2Fixed(0.4f),  Float2Fixed(0.1f), Float2Fixed(0.4f),

	Float2Fixed(0.3f), Float2Fixed(0.0f),  Float2Fixed(0.4f), Float2Fixed(0.0f),  Float2Fixed(0.4f), Float2Fixed(0.7f),
	Float2Fixed(0.3f), Float2Fixed(0.0f),  Float2Fixed(0.4f), Float2Fixed(0.7f),  Float2Fixed(0.3f), Float2Fixed(0.7f),

	// E
	Float2Fixed(0.5f), Float2Fixed(0.0f),  Float2Fixed(0.6f), Float2Fixed(0.0f),  Float2Fixed(0.6f), Float2Fixed(0.7f),
	Float2Fixed(0.5f), Float2Fixed(0.0f),  Float2Fixed(0.6f), Float2Fixed(0.7f),  Float2Fixed(0.5f), Float2Fixed(0.7f),

	Float2Fixed(0.6f), Float2Fixed(0.0f),  Float2Fixed(0.9f), Float2Fixed(0.0f),  Float2Fixed(0.9f), Float2Fixed(0.1f),
	Float2Fixed(0.6f), Float2Fixed(0.0f),  Float2Fixed(0.9f), Float2Fixed(0.1f),  Float2Fixed(0.6f), Float2Fixed(0.1f),

	Float2Fixed(0.6f), Float2Fixed(0.3f),  Float2Fixed(0.9f), Float2Fixed(0.3f),  Float2Fixed(0.9f), Float2Fixed(0.4f),
	Float2Fixed(0.6f), Float2Fixed(0.3f),  Float2Fixed(0.9f), Float2Fixed(0.4f),  Float2Fixed(0.6f), Float2Fixed(0.4f),

	Float2Fixed(0.6f), Float2Fixed(0.6f),  Float2Fixed(0.9f), Float2Fixed(0.6f),  Float2Fixed(0.9f), Float2Fixed(0.7f),
	Float2Fixed(0.6f), Float2Fixed(0.6f),  Float2Fixed(0.9f), Float2Fixed(0.7f),  Float2Fixed(0.6f), Float2Fixed(0.7f),

	// L
	Float2Fixed(1.0f), Float2Fixed(0.0f),  Float2Fixed(1.1f), Float2Fixed(0.0f),  Float2Fixed(1.1f), Float2Fixed(0.7f),
	Float2Fixed(1.0f), Float2Fixed(0.0f),  Float2Fixed(1.1f), Float2Fixed(0.7f),  Float2Fixed(1.0f), Float2Fixed(0.7f),

	Float2Fixed(1.1f), Float2Fixed(0.0f),  Float2Fixed(1.4f), Float2Fixed(0.0f),  Float2Fixed(1.4f), Float2Fixed(0.1f),
	Float2Fixed(1.1f), Float2Fixed(0.0f),  Float2Fixed(1.4f), Float2Fixed(0.1f),  Float2Fixed(1.1f), Float2Fixed(0.1f),

	// L
	Float2Fixed(1.5f), Float2Fixed(0.0f),  Float2Fixed(1.6f), Float2Fixed(0.0f),  Float2Fixed(1.6f), Float2Fixed(0.7f),
	Float2Fixed(1.5f), Float2Fixed(0.0f),  Float2Fixed(1.6f), Float2Fixed(0.7f),  Float2Fixed(1.5f), Float2Fixed(0.7f),

	Float2Fixed(1.6f), Float2Fixed(0.0f),  Float2Fixed(1.9f), Float2Fixed(0.0f),  Float2Fixed(1.9f), Float2Fixed(0.1f),
	Float2Fixed(1.6f), Float2Fixed(0.0f),  Float2Fixed(1.9f), Float2Fixed(0.1f),  Float2Fixed(1.6f), Float2Fixed(0.1f),

	// O
	Float2Fixed(2.0f), Float2Fixed(0.0f),  Float2Fixed(2.1f), Float2Fixed(0.0f),  Float2Fixed(2.1f), Float2Fixed(0.7f),
	Float2Fixed(2.0f), Float2Fixed(0.0f),  Float2Fixed(2.1f), Float2Fixed(0.7f),  Float2Fixed(2.0f), Float2Fixed(0.7f),

	Float2Fixed(2.1f), Float2Fixed(0.0f),  Float2Fixed(2.3f), Float2Fixed(0.0f),  Float2Fixed(2.3f), Float2Fixed(0.1f),
	Float2Fixed(2.1f), Float2Fixed(0.0f),  Float2Fixed(2.3f), Float2Fixed(0.1f),  Float2Fixed(2.1f), Float2Fixed(0.1f),

	Float2Fixed(2.1f), Float2Fixed(0.6f),  Float2Fixed(2.3f), Float2Fixed(0.6f),  Float2Fixed(2.3f), Float2Fixed(0.7f),
	Float2Fixed(2.1f), Float2Fixed(0.6f),  Float2Fixed(2.3f), Float2Fixed(0.7f),  Float2Fixed(2.1f), Float2Fixed(0.7f),

	Float2Fixed(2.3f), Float2Fixed(0.0f),  Float2Fixed(2.4f), Float2Fixed(0.0f),  Float2Fixed(2.4f), Float2Fixed(0.7f),
	Float2Fixed(2.3f), Float2Fixed(0.0f),  Float2Fixed(2.4f), Float2Fixed(0.7f),  Float2Fixed(2.3f), Float2Fixed(0.7f),

	// E
	Float2Fixed(2.5f), Float2Fixed(0.0f),  Float2Fixed(2.6f), Float2Fixed(0.0f),  Float2Fixed(2.6f), Float2Fixed(0.7f),
	Float2Fixed(2.5f), Float2Fixed(0.0f),  Float2Fixed(2.6f), Float2Fixed(0.7f),  Float2Fixed(2.5f), Float2Fixed(0.7f),

	Float2Fixed(2.6f), Float2Fixed(0.0f),  Float2Fixed(2.9f), Float2Fixed(0.0f),  Float2Fixed(2.9f), Float2Fixed(0.1f),
	Float2Fixed(2.6f), Float2Fixed(0.0f),  Float2Fixed(2.9f), Float2Fixed(0.1f),  Float2Fixed(2.6f), Float2Fixed(0.1f),

	Float2Fixed(2.6f), Float2Fixed(0.3f),  Float2Fixed(2.9f), Float2Fixed(0.3f),  Float2Fixed(2.9f), Float2Fixed(0.4f),
	Float2Fixed(2.6f), Float2Fixed(0.3f),  Float2Fixed(2.9f), Float2Fixed(0.4f),  Float2Fixed(2.6f), Float2Fixed(0.4f),

	Float2Fixed(2.6f), Float2Fixed(0.6f),  Float2Fixed(2.9f), Float2Fixed(0.6f),  Float2Fixed(2.9f), Float2Fixed(0.7f),
	Float2Fixed(2.6f), Float2Fixed(0.6f),  Float2Fixed(2.9f), Float2Fixed(0.7f),  Float2Fixed(2.6f), Float2Fixed(0.7f),

	// G
	Float2Fixed(3.1f), Float2Fixed(0.6f),  Float2Fixed(3.4f), Float2Fixed(0.6f),  Float2Fixed(3.4f), Float2Fixed(0.7f),
	Float2Fixed(3.1f), Float2Fixed(0.6f),  Float2Fixed(3.4f), Float2Fixed(0.7f),  Float2Fixed(3.1f), Float2Fixed(0.7f),

	Float2Fixed(3.0f), Float2Fixed(0.0f),  Float2Fixed(3.1f), Float2Fixed(0.0f),  Float2Fixed(3.1f), Float2Fixed(0.7f),
	Float2Fixed(3.0f), Float2Fixed(0.0f),  Float2Fixed(3.1f), Float2Fixed(0.7f),  Float2Fixed(3.0f), Float2Fixed(0.7f),

	Float2Fixed(3.1f), Float2Fixed(0.0f),  Float2Fixed(3.4f), Float2Fixed(0.0f),  Float2Fixed(3.4f), Float2Fixed(0.1f),
	Float2Fixed(3.1f), Float2Fixed(0.0f),  Float2Fixed(3.4f), Float2Fixed(0.1f),  Float2Fixed(3.1f), Float2Fixed(0.1f),

	Float2Fixed(3.3f), Float2Fixed(0.1f),  Float2Fixed(3.4f), Float2Fixed(0.1f),  Float2Fixed(3.4f), Float2Fixed(0.3f),
	Float2Fixed(3.3f), Float2Fixed(0.1f),  Float2Fixed(3.4f), Float2Fixed(0.3f),  Float2Fixed(3.3f), Float2Fixed(0.3f),

	Float2Fixed(3.25f), Float2Fixed(0.3f),  Float2Fixed(3.45f), Float2Fixed(0.3f),  Float2Fixed(3.45f), Float2Fixed(0.4f),
	Float2Fixed(3.25f), Float2Fixed(0.3f),  Float2Fixed(3.45f), Float2Fixed(0.4f),  Float2Fixed(3.25f), Float2Fixed(0.4f),

	// L
	Float2Fixed(3.5f), Float2Fixed(0.0f),  Float2Fixed(3.6f), Float2Fixed(0.0f),  Float2Fixed(3.6f), Float2Fixed(0.7f),
	Float2Fixed(3.5f), Float2Fixed(0.0f),  Float2Fixed(3.6f), Float2Fixed(0.7f),  Float2Fixed(3.5f), Float2Fixed(0.7f),

	Float2Fixed(3.6f), Float2Fixed(0.0f),  Float2Fixed(3.9f), Float2Fixed(0.0f),  Float2Fixed(3.9f), Float2Fixed(0.1f),
	Float2Fixed(3.6f), Float2Fixed(0.0f),  Float2Fixed(3.9f), Float2Fixed(0.1f),  Float2Fixed(3.6f), Float2Fixed(0.1f)
};

#define RED   Float2Fixed(1.0f) , Float2Fixed(0.0f) , Float2Fixed(0.0f) , Float2Fixed(1.0f)
#define GREEN Float2Fixed(0.0f) , Float2Fixed(1.0f) , Float2Fixed(0.0f) , Float2Fixed(1.0f)
#define BLUE  Float2Fixed(0.0f) , Float2Fixed(0.0f) , Float2Fixed(1.0f) , Float2Fixed(1.0f)

float helloColor[] = {	// HELLO EGL
	// H
	// 0.0,0.0, 0.1,0.0, 0.1,0.7,
	RED,          GREEN,       BLUE,
	// 0.0,0.0, 0.1,0.7, 0.0,0.7,
	RED,          GREEN,       BLUE,

	// 0.1,0.3, 0.3,0.3, 0.3,0.4,
	RED,          GREEN,       BLUE,
	// 0.1,0.3, 0.3,0.4, 0.1,0.4,
	RED,          GREEN,       BLUE,

	// 0.3,0.0, 0.4,0.0, 0.4,0.7,
	RED,          GREEN,       BLUE,
    // 0.3,0.0, 0.4,0.7, 0.3,0.7,
	RED,          GREEN,       BLUE,

	// E
	//0.5,0.0, 0.6,0.0, 0.6,0.7,
	RED,          GREEN,       BLUE,
	//0.5,0.0, 0.6,0.7, 0.5,0.7,
	RED,          GREEN,       BLUE,

	//0.6,0.0, 0.9,0.0, 0.9,0.1,
	RED,          GREEN,       BLUE,
	//0.6,0.0, 0.9,0.1, 0.6,0.1,
	RED,          GREEN,       BLUE,

	//0.6,0.3, 0.9,0.3, 0.9,0.4,
	RED,          GREEN,       BLUE,
	//0.6,0.3, 0.9,0.4, 0.6,0.4,
	RED,          GREEN,       BLUE,

	//0.6,0.6, 0.9,0.6, 0.9,0.7,
	RED,          GREEN,       BLUE,
	//0.6,0.6, 0.9,0.7, 0.6,0.7,
	RED,          GREEN,       BLUE,

	// L
	//1.0,0.0, 1.1,0.0, 1.1,0.7,
	RED,          GREEN,       BLUE,
	//1.0,0.0, 1.1,0.7, 1.0,0.7,
	RED,          GREEN,       BLUE,

	RED,          GREEN,       BLUE,
	//1.1,0.0, 1.4,0.0, 1.4,0.1,
	RED,          GREEN,       BLUE,
	//1.1,0.0, 1.4,0.1, 1.1,0.1,

	// L
	//1.5,0.0, 1.6,0.0, 1.6,0.7,
	RED,          GREEN,       BLUE,
	//1.5,0.0, 1.6,0.7, 1.5,0.7,
	RED,          GREEN,       BLUE,

	//1.6,0.0, 1.9,0.0, 1.9,0.1,
	RED,          GREEN,       BLUE,
	//1.6,0.0, 1.9,0.1, 1.6,0.1,
	RED,          GREEN,       BLUE,

	// O
	//2.0,0.0, 2.1,0.0, 2.1,0.7,
	RED,          GREEN,       BLUE,
	//2.0,0.0, 2.1,0.7, 2.0,0.7,
	RED,          GREEN,       BLUE,

	//2.1,0.0, 2.3,0.0, 2.3,0.1,
	RED,          GREEN,       BLUE,
	//2.1,0.0, 2.3,0.1, 2.1,0.1,
	RED,          GREEN,       BLUE,

	//2.1,0.6, 2.3,0.6, 2.3,0.7,
	RED,          GREEN,       BLUE,
	//2.1,0.6, 2.3,0.7, 2.1,0.7,
	RED,          GREEN,       BLUE,

	//2.3,0.0, 2.4,0.0, 2.4,0.7,
	RED,          GREEN,       BLUE,
	//2.3,0.0, 2.4,0.7, 2.3,0.7,
	RED,          GREEN,       BLUE,

	// E
	//2.5,0.0, 2.6,0.0, 2.6,0.7,
	RED,          GREEN,       BLUE,
	//2.5,0.0, 2.6,0.7, 2.5,0.7,
	RED,          GREEN,       BLUE,

	//2.6,0.0, 2.9,0.0, 2.9,0.1,
	RED,          GREEN,       BLUE,
	//2.6,0.0, 2.9,0.1, 2.6,0.1,
	RED,          GREEN,       BLUE,

	//2.6,0.3, 2.9,0.3, 2.9,0.4,
	RED,          GREEN,       BLUE,
	//2.6,0.3, 2.9,0.4, 2.6,0.4,
	RED,          GREEN,       BLUE,

	//2.6,0.6, 2.9,0.6, 2.9,0.7,
	RED,          GREEN,       BLUE,
	//2.6,0.6, 2.9,0.7, 2.6,0.7,
	RED,          GREEN,       BLUE,

	// G
	//3.1,0.6, 3.4,0.6, 3.4,0.7,
	RED,          GREEN,       BLUE,
	//3.1,0.6, 3.4,0.7, 3.1,0.7,
	RED,          GREEN,       BLUE,

	//3.0,0.0, 3.1,0.0, 3.1,0.7,
	RED,          GREEN,       BLUE,
	//3.0,0.0, 3.1,0.7, 3.0,0.7,
	RED,          GREEN,       BLUE,

	//3.1,0.0, 3.4,0.0, 3.4,0.1,
	RED,          GREEN,       BLUE,
	//3.1,0.0, 3.4,0.1, 3.1,0.1,
	RED,          GREEN,       BLUE,

	//3.3,0.1, 3.4,0.1, 3.4,0.3
	RED,          GREEN,       BLUE,
	//3.3,0.1, 3.4,0.3, 3.3,0.3
	RED,          GREEN,       BLUE,

	//3.25,0.3, 3.45,0.3, 3.45,0.4,
	RED,          GREEN,       BLUE,
	//3.25,0.3, 3.45,0.4, 3.25,0.4,
	RED,          GREEN,       BLUE,

	// L
	//3.5,0.0, 3.6,0.0, 3.6,0.7,
	RED,          GREEN,       BLUE,
	//3.5,0.0, 3.6,0.7, 3.5,0.7,
	RED,          GREEN,       BLUE,

	//3.6,0.0, 3.9,0.0, 3.9,0.1,
	RED,          GREEN,       BLUE,
	//3.6,0.0, 3.9,0.1, 3.6,0.1
	RED,          GREEN,       BLUE
};


#endif // _HELLO_MESH_


可能注意到里面大量调用了宏 Float2Fixed,这是因为 OpenGL ES 1.0 Common Lite Profile 只支持定点数,不能直接使用浮点坐标。所谓定点数这里指的是 16 整数部份 + 16 位小数部份的 32 位数,也就是 OpenGL ES 预定义的 GLfixed 类型。 将单精度浮点数转成定点数很简单,直接乘个 65536 再强制一 下类型就行了,这也就是 Float2Fixed 所做的。