OpenGL 3D迷宫场景设计

最近学习用OpenGL3D库来构建一个3D场景,以及实现场景漫游、粒子系统等效果,最终算是是做了一个3D走迷宫游戏吧。感觉最近学了好多东西,所以有必要整理整理。

一 实现效果

OpenGL 3D迷宫场景设计

OpenGL 3D迷宫场景设计

OpenGL 渲染篇

Ubuntu 13.04 安装 OpenGL

OpenGL三维球体数据生成与绘制【附源码】

Ubuntu下OpenGL编程基础解析

如何在Ubuntu使用eclipse for c++配置OpenGL

《OpenGL超级宝典》学习笔记

二 实现过程详解

1、3d场景构建

1)光照与材质

通过设置光照与材质,使得场景的显示效果更真实。opengl加光源的方法:

GLfloat light_position[] = {0.0, 80.0, 0.0};
 GLfloat light_diffuse[] = {1.0, 1.0, 1.0, 1.0};
 glLightfv(GL_LIGHT0, GL_POSITION, light_position);
 glLightfv(GL_LIGHT0, GL_AMBIENT_AND_DIFFUSE, light_diffuse);
 glEnable(GL_LIGHTING);
 glEnable(GL_LIGHT0);

加一个光源至少要上面这些代码,通过glLightfv()函数给光源设置位置以及颜色,可以加环境光G_AMBIENT、漫射光GL_DIFFUSE或镜面光GLSPECULAR,可以同时加8个光源,上面的光源时GL_LIGHT0,其他的就是GL_LIGHT1、2等。
 
场景中一旦加了光源,物体就会根据自己的材质对RGB光成分反射程度而显示不同的颜色。OpenGL给一个物体设置材质的方法

GLfloat diffuse[] = {1.0, 0.9, 0.9};
 glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, diffuse);

设置材质参数后接下来画的物体就具备了这种材质。通常使用参数GL_AMBIENT_AND_DIFFUSE给环境光和漫射光设置相同的反射程度。

2)纹理映射与多重纹理映射
 
给模型加纹理是为了在表面形成复杂图案,因为设置材质只是控制表面的显示颜色,实际上物体的表面信息要更复杂些。opengl提供了给物体贴纹理图的方法,实际上有多种方法,但我用的是 glaux库。

struct IMAGE
{
 GLuint sizeX;
 GLuint sizeY;
 signed char* data;
};
IMAGE *Image[3];
GLuint Texture[3];
bool loadTexture()//设置各种纹理,从bmp图像读取
{
 FILE* myFile;
 if(!(myFile = fopen("wall.bmp", "r")))
 return false;
 Image[0] = (IMAGE*)auxDIBImageLoad("wall.bmp");
 glGenTextures(3, &Texture[0]);
 glBindTexture(GL_TEXTURE_2D, Texture[0]);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 glTexImage2D(GL_TEXTURE_2D, 0, 3, Image[0]->sizeX, Image[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, Image[0]->data);
 if(!(myFile = fopen("floor.bmp", "r")))
  return false;
 Image[1] = (IMAGE*)auxDIBImageLoad("floor.bmp");
 glBindTexture(GL_TEXTURE_2D, Texture[1]);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
 glTexImage2D(GL_TEXTURE_2D, 0, 3, Image[1]->sizeX, Image[1]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, Image[1]->data);
 if(!(myFile = fopen("water.bmp", "r")))
  return false;
 Image[2] = (IMAGE*)auxDIBImageLoad("water.bmp");
 glBindTexture(GL_TEXTURE_2D, Texture[2]);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
 glTexImage2D(GL_TEXTURE_2D, 0, 3, Image[2]->sizeX, Image[2]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, Image[2]->data);
 
 //释放内存
 if(Image[0])
 {
  if(Image[0]->data)
   free(Image[0]->data);
   free(Image[0]);
 }
 if(Image[1])
 {
  if(Image[1]->data)
   free(Image[1]->data);
  free(Image[1]);
 }
 if(Image[2])
 {
  if(Image[2]->data)
   free(Image[2]->data);
  free(Image[2]);
 }
 return true;
}

上面的代码生成了三种纹理。语句glGenTextures(3, &Texture[0])生成了三个纹理索引,存在了数组Texture中,以后每次要设置纹理信息或是想应用纹理,通过函数glBindTexture(GL_TEXTURE_2D, textureIndex)就可以取到对应的纹理,其中第二个参数就是纹理索引。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/c6782de03fbf633525029f1b0cdcf89e.html