實驗要求:實現太陽系,地球系,即實現地球繞着太陽轉,月球繞着地球轉,並且給球體加上地球的貼圖。
效果如下:
附一張地球的貼圖(哎呀,我怎麼這麼賢惠)
這其中需要用到glaux系列的包,emmmmmmmm,我上傳了一個壓縮文件,大家可以去自行下載
鏈接:https://download.csdn.net/download/jennifer_love_frank/10852130
直接上代碼:
#include <GL/glut.h>
#include <math.h>
#include<GL/glaux.h>
float light_angle = 0;//光源角度
float light_radius = 8.0;//光源半徑
static float year = 0, month = 0, day = 0;
double aix_x = 0.0, aix_y = 1, aix_z = 0;
GLuint texName;//紋理名稱
GLUquadricObj* qobj;//二次曲面聲明類型
void IPosition(void);// 光源位置
void init(void);// 初始化,啓動光源、材質、消隱
void material_sun(void);//太陽材質
void material_earth(void);// 地球材質
void material_moon(void);// 月球材質
void sun(void);//繪製太陽
void earth(void);//繪製地球、月球
void display(void);
void Rotate(void); //更新旋轉參數
void myidle(void); //閒置調用函數
void reshape(int w, int h);
void mykeyboard(unsigned char key, int x, int y);
int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitWindowSize(600, 600);
glutInitWindowPosition(0, 0);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH);
glutCreateWindow("太陽系");
init();
glutDisplayFunc(display); //調用顯示回調函數
glutReshapeFunc(reshape); // 設置觀察體範圍
glutKeyboardFunc(mykeyboard); //鍵盤迴調函數
glutIdleFunc(myidle); // 閒置 回調函數
glutMainLoop();
return 0;
}
//設置光源位置
void IPosition()
{
float y, z;
y = light_radius*cos(light_angle);
z = light_radius*sin(light_angle);
float light_position[] = { 3.0,y,z,0.0 };
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
}
//啓動光源、消隱、材料
void init(void)
{
IPosition(); //光源位置
glShadeModel(GL_SMOOTH);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_DEPTH_TEST);
//glEnable(GL_COLOR_MATERIAL);//使用顏色材質
glClearDepth(1.0f);
AUX_RGBImageRec *TextureImage[1];//加載位圖
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); //多邊形的顯示方式,模式將適用於物體的所有面採用填充形式
glGenTextures(1, &texName);//glGenTextures (GLsizei n, GLuint *textures);在數組textures中返回n個當期未使用的值,表示紋理對象的名稱
glBindTexture(GL_TEXTURE_2D, texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);//紋理過濾函數,必須寫兩遍
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
memset(TextureImage, 0, sizeof(void *) * 1);//作用是將某一塊內存中的內容全部設置爲指定的值
if (TextureImage[0] = auxDIBImageLoadA("13.bmp")) //實現加載位圖文件
{
//根據指定的參數,生成一個2D紋理(Texture)。
glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
}
glMatrixMode(GL_PROJECTION);
}
void myidle(void)
{
glutPostRedisplay();
}
void display(void)
{
IPosition();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Rotate();
sun();
earth();
glutSwapBuffers();
glFlush();
}
//太陽材質
void material_sun(void)
{
GLfloat mat_specular[] = { 1.0, 0.0, 0.0, 1.0 }; //材質鏡面反射顏色參數
GLfloat mat_shininess[] = { 50.0 }; // 鏡面反射指數參數
GLfloat mat_diffuse[] = { 0.0,0.0,1.0,1.0 }; //材質散射顏色
GLfloat white_light[] = { 1.0, 0.0,0.0, 1.0 };
GLfloat lmodel_ambient[] = { 1.0,0.0,0.0,1.0 }; //太陽顏色爲紅色
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); //材質鏡面反射顏色
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); //鏡面反射指數
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); //材質的散射顏色
glMaterialfv(GL_FRONT, GL_AMBIENT, white_light); //材質的環境顏色
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); // 整個場景的環境光的RGBA強度
}
//地球材質
void material_earth(void)
{
glEnable(GL_COLOR_MATERIAL);
GLfloat mat_specular[] = { 1.0, 0.0, 0.0, 1.0 }; //材質鏡面反射顏色參數
GLfloat mat_shininess[] = { 50.0 }; // 鏡面反射指數參數
GLfloat mat_diffuse[] = { 0.0,0.0,1.0,1.0 }; //材質散射顏色
GLfloat white_light[] = { 1.0, 0.0,0.0, 1.0 };
GLfloat lmodel_ambient[] = { 0.0,0.0,1.0,1.0 }; //地球顏色爲藍色
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); //材質鏡面反射顏色
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); //鏡面反射指數
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); //材質的散射顏色
glMaterialfv(GL_FRONT, GL_AMBIENT, white_light); //材質的環境顏色
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); // 整個場景的環境光的RGBA強度
}
//月球材質
void material_moon(void)
{
glEnable(GL_COLOR_MATERIAL);
GLfloat mat_specular[] = { 1.0, 0.0, 0.0, 1.0 }; //材質鏡面反射顏色參數
GLfloat mat_shininess[] = { 50.0 }; // 鏡面反射指數參數
GLfloat mat_diffuse[] = { 0.0,0.0,1.0,1.0 }; //材質散射顏色
GLfloat white_light[] = { 1.0, 0.0,0.0, 1.0 };
GLfloat lmodel_ambient[] = { 0.5,0.5,0.5,1.0 }; //月亮顏色爲灰色
glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); //材質鏡面反射顏色
glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); //鏡面反射指數
glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); //材質的散射顏色
glMaterialfv(GL_FRONT, GL_AMBIENT, white_light); //材質的環境顏色
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); // 整個場景的環境光的RGBA強度
}
//繪製太陽
void sun()
{
qobj = gluNewQuadric();//申請空間
glPushMatrix();
glBindTexture(GL_TEXTURE_2D, texName);//允許建立一個綁定到目標紋理的有名稱的紋理。
glEnable(GL_TEXTURE_2D);//啓用二維紋理
gluQuadricTexture(qobj, GL_TRUE);//紋理函數
//material_sun();
glRotatef((GLfloat)year, 0.0, 1.0, 0.0); //太陽自轉
//glutSolidSphere(10, 200, 200); //畫球體
gluSphere(qobj, 0.65, 60, 60); //二次曲面qobj
glDisable(GL_TEXTURE_2D);//禁用二維紋理
glPopMatrix();
}
//繪製地球和月球
void earth()
{
glPushMatrix();
material_earth();
//glTranslatef((GLfloat)year, 0, 1, 0);
glRotatef((GLfloat)day, aix_x, aix_y, aix_z);//公轉
glTranslatef(1.0, 0.0, 0.0);//平移
glRotatef((GLfloat)month, 0.0, 1.0, 0.0);//自轉
//地球繞太陽的公轉 設置//繪製地球
glutSolidSphere(0.1, 20, 16);
//繪製月球
material_moon();
glRotatef((GLfloat)day, 0, 1, 0);//公轉
glTranslatef(0.25, 0, 0);
glutSolidSphere(0.05, 20, 16);
glRotatef((GLfloat)month, 0.0, 1.0, 0.0);//自轉
glPopMatrix();
}
void Rotate(void) //設置各行星的公轉週期
{
year = year + 0.2;
if (year > 360.0)
{
year = year - 360.0;
}
day = day + 0.2;
if (day > 360.0)
{
day = day - 360.0;
}
month = month + 0.5;
if (month > 360)
month -= 360;
glutPostRedisplay();
}
void reshape(int w, int h)
{
glViewport(0, 0, (GLsizei)w, (GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-2.0, 2.0, -2.0, 2.0, -2.0,2.0);
//glOrtho(-30.0, 30.0, -30.0, 30.0, -30.0, 30.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
void mykeyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 'W':
case 'w':
aix_y -= 0.01;
aix_z += 0.01;
break;
case 'S':
case 's':
aix_y += 0.01;
aix_z -= 0.01;
break;
case 'A':
case 'a':
light_angle -= 1.0;
break;
case 'D':
case 'd':
light_angle += 1.0;
break;
default:
break;
}
glutPostRedisplay();
}
記住:有問題報錯信息放到百度,一步步是能調通的(注:我的vs版本是2015),我的能調通!