Preface
red book 上对于一些内容的讲解,确实比较简略,比如 cube map texturing。
GL 1.2 时,cube map texturing 还是作为 extension 存在,目前 2.1/3.0 早已成为正式标准。
这里有详细的介绍,看完就懂了。
http://developer.nvidia.com/object/cube_map_ogl_tutorial.html
Cube Mapping Explained
对于金属直感的物体,会映射出周围场景的环境(environment mapping),如何在程序中模拟出这个效果呢,cube map texturing 是一种方法。其他方法如:sphere mapping、dual paraboloid mapping 等等。
对于 cube map texturing,其实就是用6张贴图(6 targets),一个 cube,作为当前物体的环境贴图(environment),在绘制物体时,不同的点,会对应到不同的 target 上,取得不同的 tex pixel 信息。
对于 (x, y, z),哪个值最大,就选取那个为 mayor(ma)。
major axis
direction target sc tc ma
---------- --------------------------------- --- --- ---
+rx GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx
-rx GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx
+ry GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry
-ry GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry
+rz GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz
-rz GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz
s = ( sc/|ma| + 1 ) / 2
t = ( tc/|ma| + 1 ) / 2
sc / |ma| = -1.0 ~ 1.0
(sc / |ma| + 1)/2 = 0.0 ~ 1.0
对于每个 target surface,s/t 会映射为:
(0.0, 0.0)
+-----------------------------+
| |
| |
| |
+-----------------------------+
(1.0, 1.0)
Sample
---- init ----
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_CUBE_MAP, texName);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_REPEAT);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, TEX_WIDTH, TEX_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, mytex1);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, TEX_WIDTH, TEX_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, mytex2);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, TEX_WIDTH, TEX_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, mytex3);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, TEX_WIDTH, TEX_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, mytex4);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, TEX_WIDTH, TEX_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, mytex5);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, TEX_WIDTH, TEX_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, mytex6);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
---- draw it ----
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_CUBE_MAP);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBindTexture(GL_TEXTURE_CUBE_MAP, texName);
glutSolidSphere(1.0, 30, 10);
对于 mytex1 ~ 6 就是简单的 64x64 single-color texture。使用 cube mapping 也只是设置到 target 即可。