1) 场景中分别绘制太阳、地球、月球,要求位置关系大体正确,并为三者贴
上纹理。三者的旋转符合实际公转自转规律;
(2) 启用z-buffer,实现面消隐;
(3) 启用光照系统,光源的环境光设置为(0.2,0.2,0.2,1) 漫反射(1,
1,1,1)和镜面反射光(1,1,1,1);
(4) 材料特性: 太阳黄色且自己向外辐射光,地球蓝色,月球灰色;
(5) 视角可以通过键盘a,d,s,w切换;
(6) 采用动画设计,使得场景能够自动运行;
(7) 分别采用透视、正交投影方式。
#include "stdafx.h"
#include <GL/glut.h>
#include<math.h>
#include<GL\GLAUX.H>
_AUX_RGBImageRec *sun, *earth, *moon;//纹理数据
unsigned int sunID,earthID,moonID; //纹理ID
double angle=0;
float theta=60,phi=60,r=2;
float eyex=0, eyey=0, eyez=0, atx=0, aty=0, atz=0;
void myinit();
void texInit();//纹理初始化
void display();
void gltDrawSphere(GLfloat fRadius, GLint iSlices, GLint iStacks);
void idle();
void myKeyboard();
//键盘控制视角函数
void myKeyboard(unsigned char key,int x,int y){
switch(key)
{
case'A':
case'a':
if(phi-1>-180)
phi=phi-5;
break;
case'D':
case'd':
if(phi+1<0)
phi=phi+5;
break;
case'S':
case's':
if(theta+1<180)
theta=theta+5;
break;
case'W':
case'w':
if(theta-1>0)
theta=theta-5;
break;
}
glutPostRedisplay();
}
//设置光照函数
void myinit()
{
GLfloat light_ambient[] = { 0.2,0.2,0.2,1 }; //环境光
GLfloat light_diffuse[] = { 1.0,1.0,1.0,1.0 }; //漫反射光
GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; //镜面反射光
glClearColor(0.5f, 0.5f, 0.5f, 1.0f); //设置背景颜色
GLfloat light_position[] = { 0, 0, 0 ,1 }; // 光源位置设置
// 创建光源
//glLightModelfv(GL_LIGHT_MODEL_TWO_SIDE,GL_FALSE);//双面光照
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
glEnable(GL_LIGHTING); // 开启光照效果
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST); // 开启深度测试
}
//设置太阳,地球,月亮
void display()
{
/*材质参数*/
glClearColor(0.1, 0.1, 0.1, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// 清空屏幕和深度缓存
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); // 重置当前的模型观察矩阵
glOrtho(-10, 10, -6, 6, -50, 50);
//glFrustum(-5, 5, -3, 3, 1, 100);
gluLookAt(r*sin(theta*3.14159/180)*sin(phi*3.14159/180),r*cos(theta*3.14159/180),r*sin(theta*3.14159/180)*cos(phi*3.14159/180),0.0,0.0,0.0,0.0,0.0,1.0);
//透视投影gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//太阳
glBindTexture(GL_TEXTURE_2D, sunID);// 绑定sunID,后续操作是对sun纹理进行的操作
//设置纹理环境
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); //纹理 与 颜色的处理模式 GL_REPLACE 替换GL_DECAL贴花 GL_BLEND混合 GL_MODULATE调节
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //纹理缩小 情况
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //纹理放大 情况
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); //在S方向 重复纹理
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //在T方向 重复纹理
//指定纹理数据和绑定对象关联BLEND
glTexImage2D(GL_TEXTURE_2D,0, GL_RGB, sun->sizeX, sun->sizeY, 0, GL_RGB,GL_UNSIGNED_BYTE, sun->data);
//设置材质
GLfloat em[4] ={0.8F, 0.7F, 0.0F,0.0f}; //黄色辐射光
GLfloat sun_mat_diffuse[] = {0.8f, 0.7f, 0.0f, 1.0f}; //定义材质的漫反射光颜色,偏黄色
GLfloat sun_mat_specular[] = {0.8f, 0.57, 0.0f, 1.0f}; //定义材质的镜面反射光颜色,黄色
GLfloat sun_mat_shininess = 100.0f;
glMaterialfv(GL_FRONT, GL_DIFFUSE, sun_mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, sun_mat_specular);
glMaterialf (GL_FRONT, GL_SHININESS, sun_mat_shininess);
//glMaterialfv(GL_FRONT,GL_EMISSION, em);//自发光
//
glRotatef(angle, 1, 1, 1);
gltDrawSphere(0.8, 200, 200); //绘制球体
//地球
glBindTexture(GL_TEXTURE_2D, earthID);
//设置纹理环境
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); //纹理 与 颜色的处理模式 GL_REPLACE GL_DECAL GL_BLEND GL_MODULATE
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //纹理缩小 情况
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //纹理放大 情况
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); //在S方向 重复纹理
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //在T方向 重复纹理
//指定纹理数据和绑定对象关联
glTexImage2D(GL_TEXTURE_2D,0, GL_RGB, earth->sizeX, earth->sizeY, 0, GL_RGB,GL_UNSIGNED_BYTE, earth->data);
GLfloat earth_mat_diffuse[] = {0.5f, 0.5f, 0.5f, 1.0f}; //定义材质的漫反射光颜色,偏蓝色
GLfloat earth_mat_specular[] = {1.0f,1.0f, 1.0f, 1.0f}; //定义材质的镜面反射光颜色,蓝色
GLfloat earth_mat_shininess = 100.0f;
glMaterialfv(GL_FRONT, GL_DIFFUSE, earth_mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, earth_mat_specular);
glMaterialf (GL_FRONT, GL_SHININESS, earth_mat_shininess);
//GLfloat bm[4] ={0.5F, 0.6F, 0.8F,1.0f}; //蓝色辐射光
//glMaterialfv(GL_FRONT,GL_EMISSION, bm);//自发光
glRotatef(angle/360.0*360.0, 1,1,1);
glTranslatef(-3,0,0);
gltDrawSphere(0.5, 200, 200); //绘制球体
//glFlush();
glPopMatrix();
//月亮,
glBindTexture(GL_TEXTURE_2D, moonID);
//设置纹理环境
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); //纹理与颜色的处理模式 GL_REPLACE GL_DECAL GL_BLEND GL_MODULATE
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //纹理缩小情况
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //纹理放大情况
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); //在S方向 重复纹理
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); //在T方向 重复纹理
//指定纹理数据和绑定对象关联
glTexImage2D(GL_TEXTURE_2D,0, GL_RGB, moon->sizeX, moon->sizeY, 0, GL_RGB,GL_UNSIGNED_BYTE, moon->data);
//材质
GLfloat moon_mat_diffuse[] = {0.5f, 0.5f, 0.5f, 1.0f}; //定义材质的漫反射光颜色,偏灰色
GLfloat moon_mat_specular[] = {0.5f, 0.5f, 0.5f, 1.0f}; //定义材质的镜面反射光颜色,灰色
GLfloat moon_mat_shininess = 100.0f;
glMaterialfv(GL_FRONT, GL_DIFFUSE, moon_mat_diffuse);
glMaterialfv(GL_FRONT, GL_SPECULAR, moon_mat_specular);
glMaterialf (GL_FRONT, GL_SHININESS, moon_mat_shininess);
glRotatef(angle/30.0*360.0 - angle/360.0*360.0,0,1,0);
glTranslatef(0.5,0,1);
gltDrawSphere(0.2, 200, 200); //绘制球体
glutSwapBuffers();
}
//画圆函数
void gltDrawSphere(GLfloat fRadius, GLint iSlices, GLint iStacks)
{
GLfloat drho = (GLfloat)(3.141592653589) / (GLfloat)iStacks;
GLfloat dtheta = 2.0f *(GLfloat)(3.141592653589) / (GLfloat)iSlices;
GLfloat ds = 1.0f / (GLfloat)iSlices;
GLfloat dt = 1.0f / (GLfloat)iStacks;
GLfloat t = 1.0f;
GLfloat s = 0.0f;
GLint i, j;
for (i = 0; i < iStacks; i++)
{
GLfloat rho = (GLfloat)i * drho;
GLfloat srho = (GLfloat)(sin(rho));
GLfloat crho = (GLfloat)(cos(rho));
GLfloat srhodrho = (GLfloat)(sin(rho + drho));
GLfloat crhodrho = (GLfloat)(cos(rho + drho));
glBegin(GL_TRIANGLE_STRIP);
s = 0.0f;
for (j = 0; j <= iSlices; j++)
{
GLfloat theta = (j == iSlices) ? 0.0f : j *dtheta;
GLfloat stheta = (GLfloat)(-sin(theta));
GLfloat ctheta = (GLfloat)(cos(theta));
GLfloat x = stheta *srho;
GLfloat y = ctheta *srho;
GLfloat z = crho;
glTexCoord2f(s, t);
glNormal3f(x, y, z);
glVertex3f(x * fRadius, y * fRadius, z * fRadius);
x = stheta *srhodrho;
y = ctheta *srhodrho;
z = crhodrho;
glTexCoord2f(s, t - dt);
s += ds;
glNormal3f(x, y, z);
glVertex3f(x * fRadius, y * fRadius, z * fRadius);
}
glEnd();
t -= dt;
}
}
void texInit()
{
//启用二维纹理
glEnable(GL_TEXTURE_2D);
//创建3个纹理ID
glGenTextures(1, &sunID);
glGenTextures(1, &earthID);
glGenTextures(1, &moonID);
//载入纹理数据 将bmp文件 放在 .cpp/.c所在文件夹下
char *filename = "sun.bmp";
sun = auxDIBImageLoadA(filename);
char * filename1 = "earth.bmp";
earth = auxDIBImageLoadA(filename1);
char *filename2 = "moon.bmp";
moon = auxDIBImageLoadA(filename2);
}
void idle()
{
angle = angle + 1;
if (angle > 360)
angle = 0;
glutPostRedisplay();
}
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
glutInitWindowSize(1000, 600);
glutCreateWindow("Texture");
myinit(); //纹理初始化
texInit();//纹理初始化
glutDisplayFunc(display);
glutIdleFunc(idle);
glutKeyboardFunc(myKeyboard);
glutMainLoop();
return 0;
}
扫描二维码关注公众号,回复:
13224356 查看本文章