📄 solar_system.cpp
字号:
/*
我的第一个openGL程序:璀璨星空
感谢Nehe的框架程序
*/
#include "solar_system.h"
HDC hDC=NULL; // Private GDI Device Context
HGLRC hRC=NULL; // Permanent Rendering Context
HWND hWnd=NULL; // Holds Our Window Handle
HINSTANCE hInstance; // Holds The Instance Of The Application
//************************************************************************************************************
//************************************************************************************************************
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); // Declaration For WndProc
GLvoid ReSizeGLScene(GLsizei width, GLsizei height) // Resize And Initialize The GL Window
{
if (height==0) // Prevent A Divide By Zero By
{
height=1; // Making Height Equal One
}
glViewport(0,0,width,height); // Reset The Current Viewport
glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
glLoadIdentity(); // Reset The Projection Matrix
// Calculate The Aspect Ratio Of The Window
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,800.0f);
glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
glLoadIdentity(); // Reset The Modelview Matrix
}
AUX_RGBImageRec *LoadImage(char * Filename)
{
FILE * File = NULL;
if(!Filename)
return NULL;
File = fopen(Filename,"r");
if(File)
{
fclose(File);
return auxDIBImageLoad(Filename);
}
return NULL;
}
GLvoid BuildFontGL()
{
newFont = CreateFont(-18,0,0,0,FW_NORMAL,FALSE,FALSE,FALSE,GB2312_CHARSET,OUT_TT_PRECIS,CLIP_DEFAULT_PRECIS,
ANTIALIASED_QUALITY,FF_DONTCARE|DEFAULT_PITCH,"楷体");
oldFont = (HFONT)SelectObject(hDC,newFont);
end = begin = NULL;
//wglUseFontBitmaps(hDC,0,256,base);
//SelectObject(hDC,oldFont);
//DeleteObject(newFont);
}
FONTS * AddFont(DWORD dwChar)
{
if(begin == NULL)
begin = end = new FONTS;
else
{
end->next = new FONTS;
end = end->next;
}
end->next = NULL;
end->val = dwChar;
end->listName = glGenLists(1);
//产生列表
wglUseFontOutlines(hDC,dwChar,1,end->listName,0.0f,0.2f,WGL_FONT_POLYGONS,&end->gmf);
return end;
}
GLvoid KillFontGL()
{
FONTS * pNextFont;
FONTS * pCurrentFont;
pCurrentFont = begin;
while(pCurrentFont !=NULL)
{
glDeleteLists(pCurrentFont->listName,1);
pNextFont = pCurrentFont->next;
delete pCurrentFont;
pCurrentFont = pNextFont;
}
SelectObject(hDC,oldFont);
DeleteObject(newFont);
//DeleteObject(oldFont);
}
GLvoid glPrint(const char *fmt)
{
char text[256];
DWORD dwChar[128];
int length = 0;
float width = 0;
va_list ap;
if(fmt == NULL)
return;
va_start(ap,fmt);
vsprintf(text,fmt,ap);
va_end(ap);
FONTS * pfont;
for(size_t i = 0;i<strlen((char *)text);i++)
{
if(IsDBCSLeadByte(text[i]))
{
dwChar[length] = (DWORD)((text[i]<<8)|(BYTE)text[i+1]);
i++;
}
else
dwChar[length] = text[i];
for(pfont = begin;pfont != NULL;pfont = pfont->next)
{
if(pfont->val == dwChar[length])
break;
}
if(pfont == NULL)
{
pfont = AddFont(dwChar[length]);
}
width += pfont->gmf.gmfCellIncX;
length++;
}
glPushAttrib(GL_LIST_BIT);
glTranslatef(-width/2,0.0f,0.0f);
for(int k=0;k<length;k++)
{
for(pfont = begin;pfont!=NULL;pfont=pfont->next)
{
if(pfont->val == dwChar[k])
{
glCallList(pfont->listName);
break;
}
}
}
glPopAttrib();
}
BOOL LoadTextureGL()
{
BOOL State = FALSE;
AUX_RGBImageRec *TextureImage[MAXTEXTURE];
memset(TextureImage,0,sizeof(void *)* MAXTEXTURE);
if((TextureImage[0] = LoadImage("Data/星空背景.bmp")) &&
(TextureImage[1] = LoadImage("Data/水1.bmp")) &&
(TextureImage[2] = LoadImage("Data/金1.bmp")) &&
(TextureImage[3] = LoadImage("Data/地1.bmp")) &&
(TextureImage[4] = LoadImage("Data/火1.bmp")) &&
(TextureImage[5] = LoadImage("Data/木1.bmp")) &&
(TextureImage[6] = LoadImage("Data/土1.bmp")) &&
(TextureImage[7] = LoadImage("Data/天1.bmp")) &&
(TextureImage[8] = LoadImage("Data/海1.bmp")) &&
(TextureImage[9] = LoadImage("Data/月球.bmp")))
{
State = TRUE;
glGenTextures(MAXTEXTURE,&texture[0]);
for(int loop = 0; loop < MAXTEXTURE; loop++)
{
glBindTexture(GL_TEXTURE_2D,texture[loop]);
glTexImage2D(GL_TEXTURE_2D,0,3,TextureImage[loop]->sizeX,
TextureImage[loop]->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,
TextureImage[loop]->data);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
}
}
for(int loop = 0; loop < MAXTEXTURE; loop++)
{
if(TextureImage[loop])
{
if(TextureImage[loop] ->data)
{
free(TextureImage[loop] ->data);
}
free(TextureImage[loop]);
}
}
return State;
}
int InitGL(GLvoid) // All Setup For OpenGL Goes Here
{
glShadeModel(GL_SMOOTH); // Enable Smooth Shading
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
if(!LoadTextureGL()) // 载入纹理
return FALSE;
//设置光源1,并打开光源
glLightfv(GL_LIGHT1,GL_AMBIENT,LightAmbient);
glLightfv(GL_LIGHT1,GL_DIFFUSE,LightDiffuse);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT1);
//建立二次曲面对象
quadric = gluNewQuadric();
gluQuadricTexture(quadric,GLU_TRUE);
gluQuadricDrawStyle(quadric,GLU_FILL);
//设置雾的参数
glFogi(GL_FOG_MODE,GL_LINEAR); //雾的类型
glFogfv(GL_FOG_COLOR,fogColor); //雾的颜色
glFogf(GL_FOG_DENSITY,0.1f); //雾的浓度
glHint(GL_FOG_HINT,GL_DONT_CARE); //雾的渲染方式
glFogf(GL_FOG_START,1.0f); //雾的开始深度
glFogf(GL_FOG_END,30.0f); //雾的终止深度
glEnable(GL_FOG);
BuildFontGL();
return TRUE; // Initialization Went OK
}
int DrawGLScene(GLvoid) // Here's Where We Do All The Drawing
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
glLoadIdentity(); // Reset The Current Modelview Matrix
glColor3f(0.0f,0.0f,1.0f);
glPushMatrix();
if(show)
{
glColor3f(1.0f,0.0f,0.0f);
glTranslatef(0.0f,2.5f,-12.5f);
glPrint("制作人:陈寅 王雯霞 谭雪岩");
glTranslatef(-6.0f,-1.0f,0.0f);
glPrint("按P键去除字");
}
glPopMatrix();
gluLookAt(current_position[0],current_position[1],current_position[2],
0.0f,0.0f,0.0f,
0.0f,0.1f,0.0f);
glTranslatef(0.0f,0.0f,-5.0f);
//为了能够清楚地看到行星表面,将坐标系绕x轴逆时针旋转10度
glRotatef(10.0f,1.0f,0.0f,0.0f);
//打开环境光源
glEnable(GL_LIGHT0);
glPushMatrix();
//*************************绘制背景星空*****************************
//旋转星空背景
glRotatef(z_angle,0.0f,0.0f,1.0f);
z_angle += z_speed;
//将背景纹理映射到实际场景中一块区域
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,texture[0]);
glBegin(GL_QUADS);
glNormal3f(0.0f,0.0f,1.0f);
glTexCoord2f(0.0,0.0); glVertex3f(-20.0f,-20.0f,-7.0f);
glTexCoord2f(6.0,0.0); glVertex3f(20.0f,-20.0f,-7.0f);
glTexCoord2f(6.0,6.0); glVertex3f(20.0f,20.0f,-7.0f);
glTexCoord2f(0.0,6.0); glVertex3f(-20.0f,20.0f,-7.0f);
glEnd();
//******************************************************************
//*************************绘制一彗星*******************************
comet_position[0] += comet_velocity[0];
if(abs(comet_position[0]) > 0)
comet_position[0] = -3.0f;
comet_position[1] += comet_velocity[1];
if(abs(comet_position[1]) > 0)
comet_position[1] = -3.0f;
comet_position[2] += comet_velocity[2];
if(abs(comet_position[2]) > 7)
comet_position[2] = 0.0f;
glDisable(GL_TEXTURE_2D);
glTranslatef(comet_position[0],comet_position[1],comet_position[2]);
//彗星由一个实心球(r = 0.075)和一个圆锥体构成
gluSphere(quadric,comet_radius,32,32);
glutSolidCone(comet_radius,comet_length,32,32);
//******************************************************************
glPopMatrix();
//***********************绘制太阳***********************************
glDisable(GL_TEXTURE_2D);
glEnable(GL_LIGHTING);
glLightfv(GL_LIGHT1,GL_POSITION,SunLightPosition);
gluSphere(quadric,sun_radius,32,32);
//******************************************************************
//***********************绘制行星***********************************
for(int i = 0; i<PLANETNUM;i++)
{
glPushMatrix();
//行星轨道倾斜一定的角度
glRotatef(incline_angle[i],0.0f,0.0f,1.0f);
glRotatef(incline_angle[i],1.0f,0.0f,0.0f);
//绘制行星的轨道
glRotatef(-90.0f,1.0f,0.0f,0.0f);
glDisable(GL_TEXTURE_2D);
gluDisk(quadric,distance[i]-0.01,distance[i]+0.01f,100,10);
glRotatef(90.0f,1.0f,0.0f,0.0f);
//将坐标原点移动到行星在轨道上的位置(绕y轴旋转公转角度,然后平移到轨道上)
glRotatef(rev_angle[i],0.0f,1.0f,0.0f);
glTranslatef(distance[i],0.0f,0.0f);
//再绕着y轴旋转自转角度
glRotatef(rot_angle[i],0.0f,1.0f,0.0f);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,texture[i+1]);
//土星需有光环,先绘制其光环
if(i == 5)
{
glRotatef(-90.0f,1.0f,0.0f,0.0f);
//绘制土星光环
gluDisk(quadric,0.5f,0.7f,100,10);
glRotatef(90.0f,1.0f,0.0f,0.0f);
}
//绘制行星
gluSphere(quadric,radius[i],32,32);
//地球有卫星月球
if(i == 2)
{
//绘制月球轨道
glDisable(GL_TEXTURE_2D);
glColor3f(1.0f,1.0f,1.0f);
glRotatef(-90.0f,1.0f,0.0f,0.0f);
gluDisk(quadric,0.2-0.005,0.2+0.005,100,10);
glRotatef(90.0f,1.0f,0.0f,0.0f);
//将坐标原点移动到月球在轨道上的位置(绕y轴旋转公转角度,然后平移到轨道上)
glRotatef(moon_rev_angle,0.0f,1.0f,0.0f);
glTranslatef(0.2,0.0f,0.0f);
//再绕着y轴旋转自转角度
glRotatef(moon_rot_angle,0.0f,1.0f,0.0f);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D,texture[9]);
//绘制月球
gluSphere(quadric,0.05f,32,32);
//改变公转、自转角度
moon_rev_angle += moon_rev_speed;
moon_rot_angle += moon_rot_speed;
}
//木星的人造同步卫星
if(i == 4)
{
glDisable(GL_TEXTURE_2D);
//假定卫星离木星表面0.5f
glTranslatef(0.5f,0.0f,0.0f);
glRotatef(90.0f,0.0f,1.0f,0.0f);
//绘制人造同步卫星
Draw_satellite();
glRotatef(90.0f,0.0f,1.0f,0.0f);
}
glPopMatrix();
//改变行星的公转和自转角度
rev_angle[i] += rev_speed[i];
rot_angle[i] += rot_speed[i];
}
glFlush();
return TRUE; // Everything Went OK
}
//***********************绘制人造同步卫星***********************
GLvoid Draw_satellite()
{
//绘制人造同步卫星
GLfloat width = 0.2f,height = 0.35f,depth = 0.2f;
GLfloat x = 0.15f,y = -0.25,z = 0.15f;
glColor3ub(192,192,192);
//绘制卫星正中的立方体
auxSolidBox(width,height,depth);
//绘制底部的推进器(四面体,由四个三角形构成)
glBegin(GL_TRIANGLES);
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(-x,y,z);
glVertex3f(x,y,z);
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(x,y,z);
glVertex3f(x,y,-z);
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(x,y,-z);
glVertex3f(-x,y,z);
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(-x,y,z);
glVertex3f(-x,y,-z);
glEnd();
//绘制卫星的左翼,由一个三角形和三个连续的矩形构成
glBegin(GL_TRIANGLES);
glVertex3f(-0.1f,0.0f,0.0f);
glVertex3f(-0.2f,0.1f,0.0f);
glVertex3f(-0.2f,-0.1f,0.0f);
glEnd();
glBegin(GL_QUADS);
glVertex3f(-0.2f,0.15f,0.0f);
glVertex3f(-0.35f,0.15f,0.0f);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -