- 理论基础
三维场景中的物体不仅受光照影响,而且受周围环境的影响,如金属,水面等材质都可以映射出周围环境的图像。模拟物体光滑表面能够映射出周围环境的技术叫做环境映射(也称反射映射)。
其原理是通过立方体纹理(cube)实现的,具体是:把摄像机放在反射物体旁边,分别朝6个方向照得6张纹理,组成立方体纹理。然后就是利用这个立方体纹理通过一些复杂的数学计算,把反射纹理映射到我们的光亮物体表面,从而形成物体反射周围环境的效果。其本质还是纹理贴图,只是纹理来源于周围环境。
#include
#ifdef __APPLE__
#include
#else
#define FREEGLUT_STATIC
#include
#endif
const char *szCubeFaces[6] = {
"/Users/app05/Desktop/opengl/pos_x.tga",
"/Users/app05/Desktop/opengl/neg_x.tga",
"/Users/app05/Desktop/opengl/pos_y.tga",
"/Users/app05/Desktop/opengl/neg_y.tga",
"/Users/app05/Desktop/opengl/pos_z.tga",
"/Users/app05/Desktop/opengl/neg_z.tga" };
GLenum cube[6] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z };
GLuint cubeTexture;
void init()
{
GLbyte *pBytes;
GLint iWidth, iHeight, iComponents;
GLenum eFormat;
int i;
glCullFace(GL_BACK);
glFrontFace(GL_CCW);
glEnable(GL_DEPTH_TEST);
glGenTextures(1, &cubeTexture);
glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTexture);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
for(i = 0; i < 6; i++)
{
pBytes = gltReadTGABits(szCubeFaces[i], &iWidth, &iHeight, &iComponents, &eFormat);
glTexImage2D(cube[i], 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes);
free(pBytes);
}
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
}
void RenderScene(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_CUBE_MAP_ARB);
glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, cubeTexture);
glBegin(GL_QUADS);
glTexCoord3f(1.0f, 1.0f, -1.0f); glVertex3f(12.0f, 12.0f, -20.0f);
glTexCoord3f(-1.0f, 1.0f, -1.0f); glVertex3f(-12.0f, 12.0f, -20.0f);
glTexCoord3f(-1.0f, -1.0f, -1.0f); glVertex3f(-12.0f, -12.0f, -20.0f);
glTexCoord3f(1.0f, -1.0f, -1.0f); glVertex3f(12.0f, -12.0f, -20.0f);
glEnd();
glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
glTexGenf(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_ARB);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
glutSolidSphere (2.0, 30, 30);
glutSwapBuffers();
}
void ChangeSize(int w, int h)
{
if(h == 0)
h = 1;
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(35.0, (GLfloat) w/(GLfloat) h, 1.0, 1000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glTranslatef(0.0f, 0.0f, -15.0f);
}
void ShutdownRC(void)
{
glDeleteTextures(1, &cubeTexture);
}
int main(int argc, char* argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(500,500);
glutCreateWindow("OpenGL Cube Maps");
glutReshapeFunc(ChangeSize);
glutDisplayFunc(RenderScene);
GLenum err = glewInit();
if (GLEW_OK != err) {
fprintf(stderr, "GLEW Error: %s\n", glewGetErrorString(err));
return 1;
}
init();
glutMainLoop();
ShutdownRC();
return 0;
}