编程中一个好的天空贴图会给玩家带来舒适的感觉,还有那对周围物体的反射光映射到球、等物体上或许是一个特别愉悦的事件,然而这在opengl里实现又不太难,
请看下面的代码:

#include <GL\glew.h>
#include <GL\GLAUX.H>
#define GLUT_DISABLE_ATEXIT_HACK
#include <gl\glut.h>
#include <stdio.h>
#include <stdlib.h>// 摄像机参数
static float cameraTheta = 0, cameraPhi = 0;
static int mouseX = 0, mouseY = 0, mouseDownX = 0, mouseDownY = 0;//天空渲染模式
static int cubeMapAvailable = 0;//纹理
static UINT textureObjectCubeMap;
static UINT textureObjects2d[6];//接收反射光物体参数static int rotateObject = 1;
static int objectAngle = 0;//渲染函数
static void drawSkybox(void);
static void drawSkyboxCubeEnvironment(void);//初始化函数
static BOOL initSkybox(void);
static void shutdownSkybox(void);//加载bmp图片
//swap_bytes用于翻转倒* BMP文件BOOL loadImage(GLenum target, const char *fileName);
#define SWAP_BYTES(b1,b2) (b1)=(b1)^(b2);(b2)=(b1)^(b2);(b1)=(b1)^(b2);static void onTimer(int value);
static void onDisplay(void);
static void onMouseMoveButtonDown(int x, int y);
static void onMouseDown(int b, int s, int x, int y);
static void onSpecialKey(int key, int x, int y);
static void onKey(unsigned char key, int x, int y);//用立方体环境映射绘制天空盒 Skybox的立方体绘制两三角扇形
//以立方体的相对角为中心
void drawSkyboxCubeEnvironment(void)
{drawSkybox();//绘制天空盒//设置对象矩阵glMatrixMode(GL_MODELVIEW);glPushMatrix();glLoadIdentity();glTranslatef(0, 0, -8);glRotatef(cameraPhi, 1, 0, 0);glRotatef(cameraTheta, 0, 1, 0);//旋转glRotatef((float)objectAngle, 1, 0, 0);glRotatef((float)2 * objectAngle, 0, 1, 0);//旋转纹理矩阵匹配摄像机矩阵//mode 指定哪一个矩阵堆栈是下一个矩阵操作的目标,//可选值: GL_MODELVIEW、GL_PROJECTION、GL_TEXTURE.glMatrixMode(GL_TEXTURE);glPushMatrix();glLoadIdentity();glRotatef(-cameraTheta, 0, 1, 0);glRotatef(-cameraPhi, 1, 0, 0);//绘制映射物体if (cubeMapAvailable){glDisable(GL_TEXTURE_2D);glEnable(GL_DEPTH_TEST);//开启深度测试glEnable(GL_TEXTURE_CUBE_MAP_ARB);//开启映射glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, textureObjectCubeMap);//绑定映射纹理//绘制反光物体//建立映射坐标生成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(3, 16, 16);//禁用反射映射glDisable(GL_TEXTURE_GEN_S);glDisable(GL_TEXTURE_GEN_T);glDisable(GL_TEXTURE_GEN_R);glDisable(GL_DEPTH_TEST);//关闭深度测试}glPopMatrix();//恢复模型矩阵glMatrixMode(GL_MODELVIEW);glPopMatrix();//恢复矩阵}//采用六面和六2D纹理绘制天空盒
void drawSkybox(void)
{//禁用映射glDisable(GL_TEXTURE_CUBE_MAP_ARB);glEnable(GL_TEXTURE_2D);float skyHei = 20;                      //天空的高度float skyLen = 40;                   //天空的长度float skyWid = 40;                   //天空的宽度//后面glBindTexture(GL_TEXTURE_2D, textureObjects2d[0]);glBegin(GL_TRIANGLE_FAN);glTexCoord2f(1, 0);glVertex3f(skyLen, skyHei, skyWid);glTexCoord2f(1, 1);glVertex3f(skyLen, -skyHei, skyWid);glTexCoord2f(0, 1);glVertex3f(-skyLen, -skyHei, skyWid);glTexCoord2f(0, 0);glVertex3f(-skyLen, skyHei, skyWid);glEnd();//前面glBindTexture(GL_TEXTURE_2D, textureObjects2d[1]);glBegin(GL_TRIANGLE_FAN);glTexCoord2f(1, 0);glVertex3f(-skyLen, skyHei, -skyWid);glTexCoord2f(1, 1);glVertex3f(-skyLen, -skyHei, -skyWid);glTexCoord2f(0, 1);glVertex3f(skyLen, -skyHei, -skyWid);glTexCoord2f(0, 0);glVertex3f(skyLen, skyHei, -skyWid);glEnd();//右面glBindTexture(GL_TEXTURE_2D, textureObjects2d[2]);glBegin(GL_TRIANGLE_FAN);glTexCoord2f(1, 0);glVertex3f(skyLen, skyHei, -skyWid);glTexCoord2f(1, 1);glVertex3f(skyLen, -skyHei, -skyWid);glTexCoord2f(0, 1);glVertex3f(skyLen, -skyHei, skyWid);glTexCoord2f(0, 0);glVertex3f(skyLen, skyHei, skyWid);glEnd();//左面glBindTexture(GL_TEXTURE_2D, textureObjects2d[3]);glBegin(GL_TRIANGLE_FAN);glTexCoord2f(1, 0);glVertex3f(-skyLen, skyHei, skyWid);glTexCoord2f(1, 1);glVertex3f(-skyLen, -skyHei, skyWid);glTexCoord2f(0, 1);glVertex3f(-skyLen, -skyHei, -skyWid);glTexCoord2f(0, 0);glVertex3f(-skyLen, skyHei, -skyWid);glEnd();//顶面glBindTexture(GL_TEXTURE_2D, textureObjects2d[4]);glBegin(GL_TRIANGLE_FAN);glTexCoord2f(0, 1);glVertex3f(-skyLen, skyHei, skyWid);glTexCoord2f(0, 0);glVertex3f(-skyLen, skyHei, -skyWid);glTexCoord2f(1, 0);glVertex3f(skyLen, skyHei, -skyWid);glTexCoord2f(1, 1);glVertex3f(skyLen, skyHei, skyWid);glEnd();//底面glBindTexture(GL_TEXTURE_2D, textureObjects2d[5]);glBegin(GL_TRIANGLE_FAN);glTexCoord2f(0, 1);glVertex3f(-skyLen, -skyHei, -skyWid);glTexCoord2f(0, 0);glVertex3f(-skyLen, -skyHei, skyWid);glTexCoord2f(1, 0);glVertex3f(skyLen, -skyHei, skyWid);glTexCoord2f(1, 1);glVertex3f(skyLen, -skyHei, -skyWid);glEnd();glDisable(GL_TEXTURE_2D);//关闭纹理
}void onDisplay(void)
{float w = (float)glutGet(GLUT_WINDOW_WIDTH), h = (float)glutGet(GLUT_WINDOW_HEIGHT);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(100.0, w / h, 1, 100);glMatrixMode(GL_MODELVIEW);glLoadIdentity();glRotatef(cameraPhi, 1, 0, 0);glRotatef(cameraTheta, 0, 1, 0);glClear(GL_DEPTH_BUFFER_BIT);drawSkyboxCubeEnvironment();glutSwapBuffers();glutPostRedisplay();
}//定时器
void onTimer(int value)
{if (rotateObject){objectAngle = (objectAngle + 1) % 360;}glutTimerFunc(10, onTimer, 0);
}//鼠标事件
void onMouseMoveButtonDown(int x, int y)
{cameraTheta += (float)(x - mouseDownX);cameraPhi += (float)(y - mouseDownY);cameraPhi = max(-90, min(cameraPhi, 90));mouseDownX = x;mouseDownY = y;
}void onMouseDown(int b, int s, int x, int y)
{if (s == GLUT_DOWN){mouseDownX = x;mouseDownY = y;glutMotionFunc(onMouseMoveButtonDown);}else{glutMotionFunc(0);}
}void onSpecialKey(int key, int x, int y)
{switch (key){case GLUT_KEY_RIGHT:cameraTheta = cameraTheta + 5;while (cameraTheta > 360) cameraTheta -= 360;break;case GLUT_KEY_LEFT:cameraTheta = cameraTheta - 5;while (cameraTheta < 0) cameraTheta += 360;break;case GLUT_KEY_UP:cameraPhi = cameraPhi + 5;if (cameraPhi > 90) cameraPhi = 90;break;case GLUT_KEY_DOWN:cameraPhi = cameraPhi - 5;if (cameraPhi < -90) cameraPhi = -90;break;};
}void onKey(unsigned char key, int x, int y)
{switch (key){case VK_ESCAPE:exit(0); break;case 'r':case 'R':rotateObject = !rotateObject;break;};
}//加载bmp图片
BOOL loadImage(GLenum target, const char *fileName)
{int i, topRow, bottomRow;AUX_RGBImageRec *image = auxDIBImageLoad(fileName);if (image != 0){topRow = 0;bottomRow = 3 * image->sizeX*(image->sizeY - 1);while (topRow < bottomRow){for (i = 0; i<3 * image->sizeX; i++){SWAP_BYTES(image->data[bottomRow + i], image->data[topRow + i]);}bottomRow -= 3 * image->sizeX;topRow += 3 * image->sizeX;}glTexImage2D(target, 0, 3, image->sizeX, image->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, image->data);free(image->data);free(image);return TRUE;}else{return FALSE;}
}//初始化
BOOL initSkybox(void)
{int i;int clampMode;BOOL succeeded = GL_TRUE;char *imageFiles[] = { "data/image1.bmp", "data/image2.bmp", "data/image3.bmp", "data/image4.bmp", "data/image5.bmp", "data/image6.bmp" };glGenTextures(6, textureObjects2d);glGenTextures(1, &textureObjectCubeMap);//单位化glEnable(GL_NORMALIZE);//如果我们能用gl_clamp_to_edge//判定是否支持特定的OpenGL扩展//extension是指定要测试的OpenGL扩展的名称if (glutExtensionSupported("GL_EXT_texture_edge_clamp")){clampMode = GL_CLAMP_TO_EDGE;//去除接缝间的空隙边框是否处理?(不处理)}else{clampMode = GL_CLAMP;}//生成 2d texturesfor (i = 0; i<6; i++){glBindTexture(GL_TEXTURE_2D, textureObjects2d[i]);glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, clampMode);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, clampMode);//去除接缝间的空隙边框是否处理?(不处理)succeeded = succeeded && loadImage(GL_TEXTURE_2D, imageFiles[i]);}//生成多维数据集映射,如果支持if (glutExtensionSupported("GL_ARB_texture_cube_map")){cubeMapAvailable = 1;glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, textureObjectCubeMap);glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);succeeded = succeeded && loadImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB, imageFiles[0]);succeeded = succeeded && loadImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB, imageFiles[1]);succeeded = succeeded && loadImage(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, imageFiles[2]);succeeded = succeeded && loadImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB, imageFiles[3]);succeeded = succeeded && loadImage(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB, imageFiles[4]);succeeded = succeeded && loadImage(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB, imageFiles[5]);}else{cubeMapAvailable = 0;}return succeeded;}// 删除内存
void shutdownSkybox(void)
{glDeleteTextures(6, textureObjects2d);glDeleteTextures(1, &textureObjectCubeMap);
}int main(int argc, char **argv)
{glutInit(&argc, argv);glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);glutCreateWindow("天空盒及照在物体上的反射光");glutReshapeWindow(1366, 768);glutDisplayFunc(onDisplay);glutMouseFunc(onMouseDown);glutSpecialFunc(onSpecialKey);glutKeyboardFunc(onKey);glutTimerFunc(10, onTimer, 0);if (!initSkybox()){shutdownSkybox();return 0;}glutMainLoop();shutdownSkybox();return 0;
}

实验结果截图:

OpenGL天空贴图以及反射纹理映射即镜面反射相关推荐

  1. OpenGL立方体贴图

    OpenGL 立方贴图 Copyright NVIDIA Corporation, 1999. Commercial publication in written, electronic, or ot ...

  2. OpenGL 立方贴图

    OpenGL 立方贴图 Copyright NVIDIA Corporation, 1999. Commercial publication in written, electronic, or ot ...

  3. OpenGL 立方体贴图Cubemaps

    OpenGL立方体贴图Cubemaps 立方体贴图Cubemaps简介 创建立方体贴图 天空盒 加载天空盒 显示天空盒 优化 环境映射 反射 折射 动态环境贴图 立方体贴图Cubemaps简介 我们已 ...

  4. openGL环境贴图

    openGL系列文章目录 文章目录 openGL系列文章目录 前言 一.代码 1.主程序 二.着色器程序 1.顶点着色器 2.片元着色器 运行效果 总结 源码下载 前言 在照明和材质章节中,我们考虑了 ...

  5. 使用OpenGL 立方体贴图

    openGL系列文章目录 文章目录 openGL系列文章目录 前言 一.OpenGL 立方体贴图 二.使用步骤 1.代码 2.着色器程序 运行结果 注意 源码下载 参考 前言 对于室外3D 场景,通常 ...

  6. OpenGL 位移贴图实例

    OpenGL 位移贴图 先上图,再解答. 按下D键 完整主要的源代码 源代码剖析 先上图,再解答. 按下D键 完整主要的源代码 #include <vmath.h> #include &l ...

  7. OpenGL渲染纹理和平面反射

    OpenGL渲染纹理和平面反射 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <stdio.h> #include "GL ...

  8. OpenGL阴影贴图

    OpenGL阴影贴图 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <stdio.h> #include "GL/glus ...

  9. OpenGL天空游戏

    OpenGL天空游戏 OpenGL天空游戏简介 源代码剖析 主要源代码 OpenGL天空游戏简介 天空游戏是一种在视觉上放大场景的方法,通过在环绕摄像机 360 度的观众周围创建纹理来使其更具表现力. ...

最新文章

  1. 有了这款可视化工具,Java 应用性能调优 so easy。。。
  2. ubunu16.04 TensorFlow object detection API 应用配置
  3. 工作107:插入请求头
  4. 最全面的Android Studio使用教程【申明:来源于网络】
  5. apache是干嘛用的_同学,其实用免费版的IDEA来创建SpringBoot项目挺方便的...
  6. 实操教程|Pytorch - 弹性训练极简实现( 附源码)
  7. win10 联想键盘快捷键关闭_如何关闭联想台式机电脑USB键盘的FN功能
  8. Linux内核编译 —— 配置文件
  9. java线程同步机制,实现同步锁
  10. 返利网app android版
  11. 【stm32CubeMX】STM32F103c8t6串口通信
  12. e4e反演框架:Designing an Encoder for StyleGAN Image Manipulation
  13. Python —对象的浅拷贝和深拷贝
  14. 钉钉走出国门,火遍全球离不开它的支持
  15. Beats:为 Filebeat 配置 inputs
  16. 成功中标 荣联为中国检科院打造一站式生信服务平台
  17. Windows系统怎么使用TeamViewer打印
  18. 美国知名科技博客简介
  19. Anaconda画图中文和负号乱码问题
  20. cloc JAVA文件_Cloc简介

热门文章

  1. suite No.1 , BWV 1007, In G:Prelude
  2. linux触摸屏信息,如何使用Linux获取触摸屏原始数据的坐标
  3. 启发主义——深入神经网络(Inceptionism: Going Deeper into Neural Networks)
  4. Python教程大全之如何绘制3D曲面图 3D Surface plot
  5. 今天最有成就感的事:教会一个60多岁的美国工程师说hehe
  6. 如何找到你喜欢的Premiere的动态图形模板
  7. Linux内文件编辑
  8. python自然语言处理安装NLRK(自然语言工具包)
  9. 【建议收藏】超详细ArcGIS中制作剖面图讲解(附练习数据)
  10. NetApp Ontap初始化配置详解