OpenGL--环境映射

来源:互联网 发布:视频广告制作软件 编辑:程序博客网 时间:2024/05/21 22:13
  • 理论基础
    三维场景中的物体不仅受光照影响,而且受周围环境的影响,如金属,水面等材质都可以映射出周围环境的图像。模拟物体光滑表面能够映射出周围环境的技术叫做环境映射(也称反射映射)。
    其原理是通过立方体纹理(cube)实现的,具体是:把摄像机放在反射物体旁边,分别朝6个方向照得6张纹理,组成立方体纹理。然后就是利用这个立方体纹理通过一些复杂的数学计算,把反射纹理映射到我们的光亮物体表面,从而形成物体反射周围环境的效果。其本质还是纹理贴图,只是纹理来源于周围环境。

  • 代码示例
#include <GLTools.h>#ifdef __APPLE__#include <glut/glut.h>#else#define FREEGLUT_STATIC#include <GL/glut.h>#endif//立方体6个面纹理:其实就是摄像机在光亮物体附件分别朝6个方向照下的纹理,这里直接手动指定。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" };//立方体6个面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);        //指定立方体6个面纹理        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;}

这里写图片描述

0 0
原创粉丝点击