在“Pudn.com > 下载中心 > OpenGL > Sky”中找来Sky.h 和Sky.cpp 这个叫天空球,或叫天空穹,顶的代码
把它加到我们的场景中,为了匹配我们的程序,部分代码需要修改.
修改后的Sky.h:
// Sky.h: CSky 类接口.
//
//
#if !defined(AFX_SKY_H__F6C8078A_2217_4F98_BD37_F5F00D2F3E16__INCLUDED_)
#define AFX_SKY_H__F6C8078A_2217_4F98_BD37_F5F00D2F3E16__INCLUDED_
#include<gl/glut.h>
#include<gl/glu.h>
#include<gl/gl.h>
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CSky
{
public:
CSky();
virtual ~CSky();
float X;
float Y;
float Z;
float R;
unsigned int T;
GLUquadricObj *qobj;
//初始化天空的位置,半径和纹理
void InitSky(float skyX,float skyY,float skyZ,float skyR,unsigned int texture);
//显示天空
void ShowSky(void);
//获得天空的属性
float GetSkyX(void);
float GetSkyY(void);
float GetSkyZ(void);
float GetSkyR(void);
unsigned int GetSkyTexture(void);
};
#endif // !defined(AFX_SKY_H__F6C8078A_2217_4F98_BD37_F5F00D2F3E16__INCLUDED_)
修改后的Sky.cpp:
// Sky.cpp: CSky类的实现。
//
//
#include "Sky.h"
//
// 建造/销毁
//
CSky::CSky()
{
X = 0;
Y = 0;
Z = 0;
R = 100;
}
CSky::~CSky()
{
}
void CSky::InitSky(float skyX,float skyY,float skyZ,float skyR,unsigned int texture)
{
X = skyX;
Y = skyY;
Z = skyZ;
R = skyR;
T = texture;
//
qobj = gluNewQuadric();
gluQuadricDrawStyle(qobj, GLU_FILL);
gluQuadricNormals(qobj,GLU_SMOOTH); // //GLU_NONE
gluQuadricTexture(qobj,GL_TRUE); //GL_FALSE
}
void CSky::ShowSky()
{
static float r=0.0;
r+=0.8;
/* 获得场景中光照状态 */
GLboolean lp;
glGetBooleanv(GL_LIGHTING,&lp);
glDisable(GL_LIGHTING); /*< 关闭光照 */
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, T);
//glTranslatef(X,Y,Z);
glRotatef(r,0.0f,1.0f,0.0f); //天空慢慢旋转,模拟云流动
glRotatef(90,1,0,0);
glColor4f(1,1,1,1);
gluSphere(qobj,R,32,32);
glPopMatrix();
if(lp) /* 恢复光照状态 */
glEnable(GL_LIGHTING);
}
float CSky::GetSkyR()
{
return R;
}
float CSky::GetSkyX()
{
return X;
}
float CSky::GetSkyY()
{
return Y;
}
float CSky::GetSkyZ()
{
return Z;
}
我们的主cpp也稍修改:
//49 天空顶 + 场景漫游 + +
#include <stdio.h>
//1,主程序:
#include<gl/glut.h>
#include<gl/glu.h>
#include<gl/gl.h>
#include "motionModel.h"
#include "Camera.h"
#include "Sky.h"
//#include "SkyBox.h"
/** 定义光源的属性值 */
GLfloat LightAmbient[] = { 0.5f, 0.5f, 0.5f, 1.0f }; /**< 环境光参数 */
GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f }; /**< 漫射光参数 */
GLfloat LightSpecular[] = { 1.0f, 1.0f, 1.0f, 1.0f }; /**< 镜面光参数 */
GLfloat LightPosition[] = { 0.0f, 0.0f, 2.0f, 1.0f }; /**< 光源位置 */
Camera m_Camera;
//CSkyBox m_SkyBox;
CSky m_sky;
int BuildTexture(char *szPathName, GLuint &texid);
void init(void)
{
/* 用户自定义的初始化过程 */
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
glClearDepth(1.0f);
glDepthFunc(GL_LEQUAL);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
/* 启用纹理 */
glEnable(GL_TEXTURE_2D);
ModelInit();
/* 初始化天空 */
//载入天空纹理图
GLuint SkyTexture;
BuildTexture("sky.jpg",SkyTexture);//请放到一起(和其它图)
m_sky.InitSky(0,0,0,100,SkyTexture);//初始化天空球
/** 设置光源的属性值 */
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); /**< 设置环境光 */
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); /**< 设置漫射光 */
glLightfv(GL_LIGHT1, GL_SPECULAR, LightSpecular); /**< 设置漫射光 */
glLightfv(GL_LIGHT1, GL_POSITION, LightPosition); /**< 设置光源位置 */
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT1);
/* 设置摄像机 */
m_Camera.setCamera(500, 35, 400, 501, 35, 400, 0, 1, 0);
m_Camera.setViewByMouse();
}
void display(void)
{
/* 用户自定义的绘制过程 */
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
/* 放置摄像机 */
m_Camera.setLook();
glPushAttrib(GL_CURRENT_BIT); /**< 保存当前属性 */
glPushMatrix();
//由于相对于天空盒所以要加以平移和缩放
glTranslatef(600.0f, 22.0f, 600.0f);//平移:表示将当前图形向x轴平移5,向y轴平移-2,向z轴平移-10
glScalef(12.0f, 12.0f, 12.0f);//缩放:表示将当前图形沿x,y,z轴分别放大为原来的12倍
/* 绘制天空 */
m_sky.ShowSky() ;
drawAllModel();//绘制所有模型
glPopMatrix();
glPopAttrib();
glFlush(); /*< 强制执行所有的OpenGL命令 */
}
void ChangeSize(int width, int height)
{
glViewport(0, 0, width, height); /*< 重新设置视口 */
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 0.1f, 4000.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void motion(int x, int y)
{
m_Camera.setViewByMouse();
glutPostRedisplay();
}
void keyboard(unsigned char key, int x, int y)
{
switch (key) {
case 27:
exit(0);
break;
case '1':
m_Camera.setSpeed(0.2f);
break;
case '2':
m_Camera.setSpeed(1.0f);
break;
case 'w':
m_Camera.moveCamera(m_Camera.getSpeed());
break;
case 's':
m_Camera.moveCamera(-m_Camera.getSpeed());
break;
case 'a':
m_Camera.yawCamera(-m_Camera.getSpeed());
break;
case 'd':
m_Camera.yawCamera(m_Camera.getSpeed());
break;
}
glutPostRedisplay();
printf("key::%d\n", key);
}
void SpinDisplay()
{
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DEPTH | GLUT_RGB);
glutInitWindowSize(800, 600);
glutInitWindowPosition((GetSystemMetrics(SM_CXSCREEN) >> 1) - 400, (GetSystemMetrics(SM_CYSCREEN) >> 1) - 300);
glutCreateWindow("天空盒");
init();
glutReshapeFunc(ChangeSize);
glutDisplayFunc(display);
glutMotionFunc(motion);
glutKeyboardFunc(keyboard);
glutIdleFunc( SpinDisplay );//注册旋转
glutMainLoop();
return 0;
}
效果图:
天空纹理图: