数据类型
基本数据类型
变量可为下列基本数据类型:
名称 | 描述 | 大小 | 范围 |
---|---|---|---|
int | 整数型 | 4 字节 | 带符号的: -2147483648 to 2147483647 |
long | 长整型 | 8 字节 | 带符号的: –9223372036854775808 to 9223372036854775807 |
float | 浮点数字 | 4 字节 | +/- 3.4e +/- 38 (~7 个数字) |
double | 双精度浮点数字 | 8 bytes | +/- 1.7e +/- 308 (~15 个数字) |
string | 字符串 | ||
enum | 一组有名称的整型常量 | 2 字节 | 带符号的: -2147483648 to 2147483647 |
整型
代表一个整型数字。初始值为0。
可使用十进制(base-10),十六进制 (base-16) 或 ASCII字符表示法并使用可选前置标志 (- 或 +)。
int a = -123; // 十进制负数
int b = 0x1E; // 十六进制数字 (相当于十进制计数法中的30)
int c = 'N'; // ASCII表上的字符 (相当于十进制计数法中的78 )
长整型
代表长整型数字。当需要的数值超过int型所提供的范围时,使用这种数据类型。初始值为0L。
可使用十进制(base-10)或十六进制(base-16)符号并使用强制型后缀 l 或 L及可选前置标志(- 或 +)。
long a = -123456789123456L; // 十进制负数值
long b = 0x1EL; // 十六进制数字
浮点型
单精度(32位)浮点数值。初始值为0.0f。
可使用下列任意一种符号,并使用强制型后缀f 或 F 及可选前置标志 (- 或 +).
float a = 3.14f; // 十进制记数法
float b = 1.8e15F; // 指数记数法
float c = 9.5E-7F; // 指数记数法
双精度
代表双精度DC2精度浮点值 (64位t)。初始值为0.0。
double a = 3.14; // 十进制记数法
double b = 1.8e15; // 指数记数法
double c = 9.5E-7; // 指数记数法
字符串
字符串。初始值为空字符串。
string a = "sequence of characters";
string b = "long " + a; // b = "long sequence of characters"
int b = 4;
string c = "sequence of " + b + " characters"; // d = "sequence of 4 characters"
string d = string(b) + " characters"; // d = "4 characters"
enum
一组被分配有名称的整型常量。
默认情况下,数值从0开始接着从元素到元素进行增加:
enum {
KEY_UP, // 0
KEY_DOWN, // 1
KEY_LEFT, // 2
KEY_RIGHT, // 3
};
enum {
KEY_F1 = 100, // 100
KEY_F2, // 101
KEY_F3 = 0x1E, // 30
KEY_F4, // 31
};
int key = 3;
if (key == KEY_RIGHT) {
log.message("go right\n");
};
// the output is: go right
可设置之前指定enums的值。例如:
enum {
KEY_NEW = KEY_UP,
};
3D 相关数据类型
vec3
三个浮动组件的向量。初始值为(0.0f,0.0f,0.0f)。
可以下列方式设置向量:
- 作为一个对象。这种情况下,三个向量都会得到指定。
vec3 a; a = vec3(2.0f,-3.1f,0.5f);
向量的初始化与C++不同。向量被封装在简单parentheses ()方法的条款中,而不是在一对花括弧中提供向量条款列表。 - 作为组件等同于变元的对象。
a = vec3(2.0f);
- 1-, 2-, 3-元素或任意 swizzles。
vec3 b; vec3 c; b.x = a.z; b.y = a.x; b.z = a.y; c = b.xzy; log.message("b is %s\n",typeinfo(b)); log.message("c is %s\n",typeinfo(c)); // b is vec3: 0.5 2 -3.1 // c is vec3: 0.5 -3.1 2
请注意如果您使用vec4 (或dvec4)对vec3进行初始化,接下来vec4.w将被省略:
vec3 a = vec3(vec4(2.0f,-3.1f,0.5f,7.2f)); // 最后的数字 (7.2f)会被省略
可从向量中添加或减去一个标量值(整型, 长整型, 浮点型 或 双精度型)。向量应在标量之前。
vec3 a = vec3(2.0f,-3.1f,0.5f);
a += 1;
vec3 b = a - 1.5f;
// a contents: 3, -2.1, 1.5
// b contents: 1.5, -3.6, -0
dvec3
三个双精度型组件的向量。初始值为 (0.0,0.0,0.0)。
可以下列方式设置向量:
- 作为一个对象。这种情况下,三个向量组件都会得到指定。
dvec3 a; a = dvec3(2.0,-3.1,0.5);
- 作为组件等同于变元的对象。
a = dvec3(2.0);
- Swizzling同样适用于dvec3。
dvec3 b; b.x = a.z; b.yz = a.xy; log.message("b is %s\n",typeinfo(b)); // b is dvec3: 0.5 2 -3.1
请注意如果您使用 dvec4 (或 vec4)初始化dvec3接下来dvec4.w将被省略:
dvec3 a = dvec3(dvec4(2.0,-3.1,0.5,7.2)); // 最后的数字 (7.2) 会被省略
可从向量中添加或减去一个标量值(整型, 长整型, 浮点型 或 双精度型)。向量应在标量之前。
dvec3 a = dvec3(2.0f,-3.1f,0.5f);
a += 1;
dvec3 b = a - 1.5f;
log.message("%s\n",typeinfo(a));
log.message("%s\n",typeinfo(b));
dvec3: 3 -2.1 1.5
dvec3: 1.5 -3.6 0
ivec3
三个整型组件的向量。初始值为(0,0,0)。
可以下列方式设置向量:
- 作为一个对象。
ivec3 a; a = ivec3(2,-3,5);
- 作为组件等同于变元的对象。
a = ivec3(2);
- Swizzling同样适用于ivec3。可通过与vec3相同的方式将其进行使用。
ivec3 b; b = a.zyy; log.message("b is %s\n",typeinfo(b)); // b is ivec3: 5 -3 -3
可从向量中添加或减去一个标量值(整型, 长整型, 浮点型 或 双精度型)。向量应在标量之前。
ivec3 a = ivec3(2,-3,1);
a += 1;
ivec3 b = a - 1;
log.message("%s\n",typeinfo(a));
log.message("%s\n",typeinfo(b));
ivec3: 3 -2 2
ivec3: 2 -3 1
vec4
四个 浮点类型 组件的向量。初始值为 (0f,0f,0f,0f)。
可以下列方式设置向量:
- 作为一个对象。这种情况下,所有向量组件都会得到指定。当然也可以使用vec3对vec4进行初始化。
vec4 a; a = vec4(2.0f,-3.1f,0.5f,7.2f); a = vec4(vec3(2.0f,-3.1f,0.5f),7.2f);
- 作为组件等同于变元的对象。
a = vec4(2.0f);
- Swizzling 也适用于 vec4。vec4和vec3的差别在于可为 vec4将4个组件调整在一起(x,y,z,w)。
vec4 b; vec4 c; b.x = a.z; b.y = a.w; b.zw = a.yy; c = b.xyyz; log.message("b is %s\n",typeinfo(b)); log.message("c is %s\n",typeinfo(c)); // b is vec4: 0.5 7.2 -3.1 -3.1 // c is vec4: 0.5 7.2 7.2 -3.1
请注意如果您使用vec3 (或 dvec3) 对vec4进行初始化,接下来默认情况下vec4.w 将为 1.0f :
vec4 a = vec4(vec3(2.0f,-3.1f,0.5f)); // 向量内容为: 2.0f,-3.1f,0.5f,1.0f
可从向量中添加或减去一个标量值(整型, 长整型, 浮点型 或 双精度型)。向量应在标量之前。
vec4 a = vec4(2.0f,-3.1f,0.5f,6.0f);
a += 1.5f;
vec4 b = a - 1.5f;
log.message("%s\n",typeinfo(a));
log.message("%s\n",typeinfo(b));
vec4: 3.5 -1.6 2 7.5
vec4: 2 -3.1 0.5 6
dvec4
四个双精度组件的向量。初始值为(0.0,0.0,0.0,0.0)。
可以下列方式设置向量:
- 作为一个对象。可使用vec3将dvec4初始化。
dvec4 a; a = dvec4(2.0,-3.1,0.5,7.2); a = dvec4(vec3(2.0,-3.1,0.5),7.2);
- 作为组件等同于变元的对象。
a = dvec4(2.0);
- Swizzling会以与vec4相同的方式为dvec4执行。
dvec4 b; b.x = a.z; b.yzw = a.xy0; log.message("b is %s\n",typeinfo(b)); // b is dvec4: 0.5 2 -3.1 0
请注意如果您使用dvec3 (或 vec3) 对dvec4 then dvec4进行初始化。接下来默认情况下dvec4.w 将为 1.0:
dvec4 a = dvec4(dvec3(2.0,-3.1,0.5)); // a.w = 1.0
可从向量中添加或减去一个标量值(整型, 长整型, 浮点型 或 双精度型)。向量应在标量之前。
dvec4 a = dvec4(2.0f,-3.1f,0.5f,6.0f);
a += 1.5f;
dvec4 b = a - 1.5f;
log.message("%s\n",typeinfo(a));
log.message("%s\n",typeinfo(b));
dvec4: 3.5 -1.6 2 7.5
dvec4: 2 -3.1 0.5 6
ivec4
四个整型组件的向量。初始值为(0,0,0,0)。
可以下列方式设置向量:
- 作为一个对象。
ivec4 a; a = ivec4(2,-3,5,7);
- 作为组件等同于变元的对象。
a = ivec4(2);
- Swizzling会以与vec4 和 dvec4相同的方式为 ivec4 进行执行。
ivec4 b; b = a.wyy1; log.message("b is %s\n",typeinfo(b)); // b is ivec4: 7 -3 -3 1
可从向量中添加或减去一个标量值(整型, 长整型, 浮点型 或 双精度型)。向量应在标量之前。
ivec4 a = ivec4(2,-3,1,6);
a += 1.5f;
vec4 b = a - 1.5f;
log.message("%s\n",typeinfo(a));
log.message("%s\n",typeinfo(b));
ivec4: 3 -2 2 7
ivec4: 2 -3 1 6
mat4
16个(4×4) 浮点型 组件的矩阵。初始值为恒等矩阵:
1 | 0 | 0 | 0 |
0 | 1 | 0 | 0 |
0 | 0 | 1 | 0 |
0 | 0 | 0 | 1 |
路由:
m00 m01 m02 m03
m10 m11 m12 m13
m20 m21 m22 m23
m30 m31 m32 m33
可以下列方式设置一个矩阵:
- 作为一个对象。可直接阐明每个矩阵元素。
矩阵包含下列内容:
mat4 a; a = mat4("0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15");
0 4 8 12 1 5 9 13 2 6 10 14 3 7 11 15
- 作为平移矩阵。这种情况下,使用vec3对mat4进行初始化。
另一种设置mat4元素的方式:
a = mat4(vec3(1,2,3));
结果为平移矩阵:a = mat4(1,2,3);
1 0 0 1 0 1 0 2 0 0 1 3 0 0 0 1
- 作为旋转矩阵。可使用四元数来设置矩阵元素。
可通过轴和角度值将 mat4 初始化。
a = mat4(quat(1,0,0,45));
或通过标量值。a = mat4(vec3(1,0,0),45);
结果为旋转矩阵:a = mat4(1,0,0,45);
1 0 0 1 0 0.7 -0.7 0 0 0.7 0.7 0 0 0 0 1
- Swizzling 也可用于矩阵。
例如:
结果为:
mat4 b; b.m00m01m02m03 = vec4(1,2,3,4); b.m00m10m20m30 = vec4(5,6,7,8); b.m03m13m23 = vec3(1,2,3); b.m03m23 = vec3(1,2,0); b.m00m11m22m33 = a.m30m21m12m03; log.message("b is %s\n",typeinfo(b));
3 2 3 1 6 6 0 2 7 0 9 2 8 0 0 12
- 可将矩阵的行和列 调整在一起,例如:
vec4 row = a.row0; // 返回完整的第一行: 0 4 8 12 vec4 col = a.col3; // 返回完整的第四列: 12 13 14 15 dvec3 row_3 = a.row03; // 返回第一行的前三个元素: 0 4 8 dvec3 col_3 = a.col23; // 返回第三列的前三个元素: 8 9 10
-
可以如下方式将列进行 调整:
vec4 col1 = a.binormal; // 获取col1的前三个组件 vec4 col2 = a.normal; // 获取col2的前三个组件
dmat4
12个双精度型组件的矩阵。此为4×4仿射变换矩阵,但最后一行并未保存。相反,最后一行的形式总是为"0 0 0 1"并且值不能进行编写,只能读。初始值为单位矩阵:
1 | 0 | 0 | 0 |
0 | 1 | 0 | 0 |
0 | 0 | 1 | 0 |
0 | 0 | 0 | 1 |
m00 m01 m02 m03
m10 m11 m12 m13
m20 m21 m22 m23
m30 m31 m32 m33
可以下列方式设置一个矩阵:
- 作为一个对象。可直接阐明每个矩阵元素。
The result is:
dmat4 a; a = dmat4("0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15");
0 4 8 12 1 5 9 13 2 6 10 14 0 0 0 1
- 作为平移矩阵可使用vec3 将dmat4初始化。
另一种设置dmat4元素的方式:
a = dmat4(dvec3(1,2,3));
结果为平移矩阵:a = dmat4(1,2,3);
1 0 0 1 0 1 0 2 0 0 1 3 0 0 0 1
- 作为旋转矩阵。这种情况下四元组被用来设置矩阵元素。
也可使用轴和角度值将dmat4初始化。
a = dmat4(quat(1,0,0,45));
或通过标量值。a = dmat4(vec3(1,0,0),45);
结果为旋转矩阵:a = dmat4(1,0,0,45);
1 0 0 1 0 0.7 -0.7 0 0 0.7 0.7 0 0 0 0 1
- Swizzling也可用于 dmat4。
例如:
结果为:
dmat4 b; b.m00m01m02m03 = dvec4(1,2,3,4); b.m00m10m20m30 = dvec4(5,6,7,8); // m30 will not be written b.m03m13m23 = vec3(1,2,3); b.m03m23 = vec3(1,2,0); b.m00m11m22m33 = a.m30m21m12m03; // m33 will not be written log.message("b is %s\n",typeinfo(b));
0 2 3 1 6 6 0 2 7 0 9 2 8 0 0 1
不会写入.m30 和 .m33元素。 - 可将 dmat4的行和列调整在一起。
vec4 row = a.row0; // 返回完整的第一行: 0 4 8 12 vec4 col = a.col3; //返回完整的第四列: 12 13 14 15 dvec3 row_3 = a.row03; // 返回第一行的前三个元素: 0 4 8 dvec3 col_3 = a.col23; // 返回第三列的前三个元素: 8 9 10
-
也可以下列方式将列 调整在一起:
vec4 col1 = a.binormal; // 获取col1的前三个元素 vec4 col2 = a.normal; // 获取col2的前三个元素
quat
quat为四元组。此四元组的组件为 浮动 数字。四元组为一种数学构造代表三维中的旋转。初始值为(0,0,0,1),其中 x, y 和 z 组件代表三个旋转轴,w组件代表旋转角度。
可使用不同的方法设置四元组:
- 作为一个对象。可直接设置四元组的值。
quat a; a = quat(1,2,3,4);
- 也可使用mat4用于对quat的初始化。
a = quat(mat4(1,2,3,4));
- 使用轴和角度值。
a = quat(vec3(1,2,3),0.2);
- 使用标量值。
a = quat(1,2,3,0.2);
- 四元组也支持调整。
例如:
a.xyz = a.wzx; a.wzy = vec3(1,2,3); a.xyzw = a.wzyx; a.wyzw = vec4(1,2,3,4); a.xyz += a.wyz;
- 如果 quat 为网格压缩的切线向量,可使用次法线 和 法线 组件
来获取有相应标准w组件的向量。
例如:
vec3 t = vec3(1.0f,0.0f,0.0f); // 切线基线: 切线向量 vec3 b = vec3(0.0f,1.0f,0.0f); // 次法线向量 vec3 n = vec3(0.0f,0.0f,1.0f); // 法线向量 vec4 tangent = orthoTangent(t,b,n); // 此为网格压缩的切线向量 quat q = quat(tangent); // 将 vec4 转换为quat q.binormal; // 将w规范化然后获取次法线向量 q.normal; // 将w规范化然后获取法线向量
调整
有了Swizzling,可以任意顺序选择组件。其为访问元素提供便利。 可将其用于下列与3D相关的数据类型:
- 向量 (vec3, dvec3, ivec3, vec4, dvec4, ivec4)。
可使用 x, y, z, w 分别对应第一个,第二个,第三个及第四个向量组件。使用r, g, b, a组件而不使用 x, y, z, w 来代表颜色。
当然也可使用0 或 1而不使用x, y, z 或w (或分别使用 r, g, b, a):可在单一操作中将不同的组件名称结合在一起。例如a.xrb为有效。The output is:vec4 v = vec4(10.0f,11.0f,12.0f,13.0f); // swizzles log.message("%s\n",typeinfo(v.xyzw)); log.message("%s\n",typeinfo(v.10zw)); log.message("%s\n",typeinfo(v.xy10));
vec4: 10 11 12 13 vec4: 1 0 12 13 vec4: 10 11 1 0
也可仅使用 0 或1。 - 矩阵 (mat4, dmat4).
- 四元组 (quat)。
- x, y, z, w组件被用来表示四元组组件。
- 如果 quat为网格压缩的切线向量,可使用次法线和 法线 组件 来获取对应的有标准化w 组件的向量。
示例
以下类型的调整可用:
- 一种元素的搅和。可将任意向量元素(矩阵,四元组)作为标量值(整型,长整型,浮点型,双精度型)进行访问。
此外,搅和运行任意组件采用相同向量,矩阵或四元组上任意组件的值。 例如,x组件采用z组件的值:
vec3 a = vec3(2.0f,-3.1f,0.5f); float b = a.z; log.message("%s\n",typeinfo(b)); // 输出为浮点型的0.5
将任意数量元素进行搅和也是真实的。vec3 a = vec3(2.0f,-3.1f,0.5f); a.x = a.z; log.message("%s\n",typeinfo(a.x)); // 浮点型: 0.5
- 两种元素搅和。结果为3种组件的向量,在此向量中最后一个元素是0。
log.message("%s\n",typeinfo(a.zx)); // 输出为: vec3: 0.5 2 0
如果将两种元素的搅和运用到4种组件的向量,矩阵或四元组上,结果还是为3种组件的向量。 - 三种元素的搅和可以以任意顺序访问元素。
可在向量设置中使用搅和。
log.message("%s\n",typeinfo(a.zyx)); // the output is: vec3: 0.5 -3.1 2
vec3 b = a.xzy; log.message("%s\n",typeinfo(b)); // vec3: 2 0.5 -3.1
- 任意搅和意味着可以使用任意的组件组合。还以为这可使用一种以上的相同组件。
log.message("%s\n",typeinfo(a.zyy)); // the output is: vec3: 0.5 -3.1 -3.1
- rgba搅和。可通过与xyzw 组件的相同方式使用rgba组件来设置颜色。例如:
vec3 a = vec3(2.0f,-3.1f,0.5f); vec3 b; b.r = 2.0f; b.g = a.g; b.b = 0.5f; log.message("%s\n",typeinfo(b)); log.message("%s\n",typeinfo(a.rbb)); // vec3: 2 -3.1 0.5 // vec3: 2 0.5 0.5
- 每行和每列中的搅和(针对矩阵)。这意味着可通过与元素一样的方式对行和列进行访问。
此外,还可访问某个行或列的指定数量元素。
mat4 a; a = mat4("0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15"); vec4 row = a.row0; // 返回完整的第一行: 0 4 8 12 vec4 col = a.col3; // 返回完整的第四列: 12 13 14 15
也可在列尾或行末添加0 或 1 :dvec3 row_3 = a.row03; // 返回第一行的前三个元素: 0 4 8 dvec3 col_3 = a.col23; // 返回第三列的前三个元素:8 9 10
dvec4 row_4 = a.row13_1; // 返回第二列的三个元素,并在末尾添加 + 1 : 1 5 9 1 dvec4 col_4 = a.col33_1; // 返回第四列的三个元素,并在末尾添加 + 1 : 12 13 14 1
自动类型转化
要执行操作,大多数的 运算符必须拥有相同类型的两种运算对象。这也正是自动转换发生的原因:从两种运算对象类型来看,通常会选择最大类型来保存整个数值从而避免数值截断现象出现。
标量类型的自动转换
整型 | 长整型 | 浮点型 | 双精度型 | |
---|---|---|---|---|
整型 | 整型 | 长整型 | 浮点型 | 双精度型 |
长整型 | 长整型 | 长整型 | 浮点型 | 双精度型 |
浮点型 | 浮点型 | 浮点型 | 浮点型 | 双精度型 |
双精度型 | 双精度型 | 双精度型 | 双精度型 | 双精度型 |
例如:
int a = 5;
float b = 2.3f;
log.message("%s\n",typeinfo(a+b));
// float: 7.3
可使用一种明确的转换类型进行强制转换:
int a = 5;
float b = 2.3f;
log.message("%s\n",typeinfo(float(a) + b));
矢量类型的强制转换
矢量类型之间无法自动进行转换。正是因为这种原因,仅能使用不同类型的矢量或作为参数的标量执行数种操作例如 乘法 和 除法。
安全的自动转换仅可能用于以下类型:
转换前 | 转换后 |
---|---|
vec3 | dvec3 |
vec4 | dvec4 |
例如:
vec3 a = vec3( 1, 2, 3);
dvec3 b = dvec3(2.0,-3.1,0.5);
ivec3 c = ivec3(2,-3,5);
log.message("%s\n",typeinfo(a + b)); // dvec3: 3 -1.1 3.5
log.message("%s\n",typeinfo(a + c)); // in this case, an error occurs
可使用一种明确的转换类型进行矢量类型强制转换:
vec3 a = vec3( 1, 2, 3);
dvec3 b = dvec3(2.0,-3.1,0.5);
log.message("the result is: %s\n",typeinfo(dvec3(a) + b));