在實現中,我使用openGL的函數庫,以及一些重要的標頭檔:glut.h、windows.h、math.h等。使用自訂宏DEG_TO_RAD。然後使用TEXTUREIMAGE對程式所需要的外部參考圖形變數進行定義。然後使用GLunit建立textureObjects對象。具體如下:
#include <GL/glut.h>
#include <windows.h>
#include <mmsystem.h>
#include <math.h>
#include "rf.h"
#include "mf.h"
#include "draw.h"
#define DEG_TO_RAD 0.017453
static GLuint texName;
bool g_bOrbitOn = true;
float g_fSpeedmodifier = 1.0f;
float g_fElpasedTime;
double g_dCurrentTime;
double g_dLastTime;
static GLdouble viewer[]= {-sin(10*DEG_TO_RAD),10*cos(10*DEG_TO_RAD), -25}; /* initial viewer location */
static int year =0 ,day = 0;
float angle=0.0;在程式中使用的MATERIAL對將要構建的圖形的物理效能進行了定義,包括環境光線、漫射光、鏡面光、光源位置:
#define NUM_TEXTURES 10
GLuint textureObjects[NUM_TEXTURES];
MATERIAL material[NUM_TEXTURES];
//
光照
LIGHT light =
{
{0.0, 0.0, 0.0, 1.0}, //
環境光線參數
{1.0, 1.0, 1.0, 1.0}, //
漫射光參數
{1.0, 1.0, 1.0, 1.0}, //
鏡面光參數
{0.0, 0.0, 0.0, 1.0} //
光源位置
};
//
材質
MATERIAL materialSpace =
{
{0.4, 0.4, 0.4, 1.0},
{0.0, 0.0, 0.0, 1.0},
{0.0, 0.0, 0.0, 1.0},
0.0
};然後就是對映像的初始化init(),以及預先處理:
void init()
{
glClearColor(0.0,0.0,0.0,0.0);
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_FLAT);
material[0]=materialSun;
material[1]=materialEarth ;
material[2]=materialMoon ;
material[3]=materialSpace ;
GLfloat light_ambient[]={1.0, 1.0, 1.0, 1.0};
GLfloat light_diffuse[]={1.0, 1.0, 1.0, 1.0};
GLfloat light_specular[]={1.0, 1.0, 1.0, 1.0};
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);
}
void reshape(int w,int h)
{
glViewport(0,0,(GLfloat) w, (GLfloat) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60.0,(GLfloat)w/(GLfloat)h,1.0,200.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(viewer[0],viewer[1],viewer[2],0,0,0,0,0,1);
}
void ShutdownRC(void)
{
// Delete the textures
glDeleteTextures(NUM_TEXTURES, textureObjects);
}接著的display()函數則是對整個太陽系的具體繪製:
glLoadIdentity();
//
設定觀察點的位置和觀察的方向
gluLookAt(viewer[0],viewer[1],viewer[2],0,0,0,0,0,1);
//
獲得系統時間使太陽系有動態效果
g_dCurrentTime = timeGetTime();
g_fElpasedTime = (float)((g_dCurrentTime - g_dLastTime) * 0.001);
g_dLastTime = g_dCurrentTime;
GLfloat light_position[]={0.0, 0.0, 0.0, 1.0}; 接著初始化太陽的自轉速度和其他星球的自轉和公轉速度。例如:
static float fSunSpin = 0.0f;//
太陽自轉速度
static float fMercuSpin = 0.0f;//
水星自轉速度
static float fMercuOrbit = 0.0f;//
水星公轉速度
static float fJupiterSpin = 0.0f;//
木星自轉速度
static float fJupiterOrbit = 0.0f;//
木星公轉速度
static float fSaturnSpin = 0.0f;//
土星自轉速度
static float fSaturnOrbit = 0.0f;//
土星公轉速度
static float fPlutoSpin = 0.0f;//
冥王星自轉速度
static float fPlutoOrbit = 0.0f;//
冥王星公轉速度
//static float fSpace = 0.0f;//
太空的轉動
float spaceWidth =28.50;
float spacedepth =18.0; 接著又定義各星球的間距:例如:
static float MercuToSun=-3.0;//
水星離太陽的距離
static float VenToSun =-5.0;//
金星離太陽的距離
static float NeptuneToSun =-15.0;//
海王星離太陽的距離
static float PlutoToSun =-17.0; //
冥王星離太陽的距離然後就是對各星球的速度的具體限制以體現各星球的特異性和真實性。然後進入對各星球的實際繪製階段:首先是對整個空間的繪製,然後是太陽,然後按照太陽系的實際情況進行逐個繪製。例如天王星:
//
天王星的位置,大小,轉速,和紋理,材質大致與地球相同
//
天王星使用的材質大致與地球相同
glColor3f(192,122,24);
glPushMatrix();
glRotatef(fUranusOrbit,0.0,1.0,0.0);
glTranslatef(0.0,0.0,UranusToSun);
glRotatef(fUranusSpin,0.0,1.0,0.0);
glRotatef(90,1,0.0,0.0);
mf(uranusImg,& textureObjects[0]);
gltDrawSphere(0.5,150,200);
glPopMatrix();
glBegin(GL_LINE_LOOP);
for(angle=0;angle<=360;angle++)
glVertex3f(UranusToSun*sin(DEG_TO_RAD*angle),0,UranusToSun*cos(DEG_TO_RAD*angle));
glEnd();
glDeleteTextures(1, &textureObjects[0]); 接著就是對使用者輸入的控制keyboard()以及滑鼠的控制mouse(),以便實現視角的轉換和星球轉動速度的控制,實現使用者有好性。然後就是主函數main():在這個函數中,首先是載入了要繪製的星球的“皮膚”圖片,讓星球更具有真實性。然後調用初始化函數對圖形,空間,表單等進行初始化。然後就是調用前面的函數進行圖形的繪製,最終實現太陽系:
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB);
glutInitWindowSize(800,600);
glutCreateWindow("sean");
init();
glutDisplayFunc(display);
glutIdleFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutMainLoop();
ShutdownRC();