#include<windows.h>
#include<gl/gl.h>
#include<gl/glu.h>
#include<gl/glut.h>
#include<math.h>
#defineglRGB(x,y,z)glColor3ub((GLubyte)x,(GLubyte)y,(GLubyte)z)
#defineSUN1
#defineMERCURY2
#defineVENUS3
#defineEARTH4
#defineMARS5
GLfloatfAspect;
intn;
//Lightingvalues
GLfloatwhiteLight[]=
{0.35f,0.35f,0.35f,1.0f};
GLfloatsourceLight[]=
{0.65f,0.65f,0.65f,1.0f};
GLfloatlightPos[]=
{0.0f,0.0f,0.0f,1.0f};

//Calledtodrawscene
voidRenderScene(void)

{
//Clearthewindowwithcurrentclearingcolor
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
//Savethematrixstateanddotherotations
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
//Translatethewholesceneoutandintoview
glTranslatef(0.0f,0.0f,-300.0f);
//Initializethenamesstack
glInitNames();
glPushName(0);

//Setmaterialcolor,Yellow
//Sun
glRGB(255,255,255);
glLoadName(SUN);
glutSolidSphere(15.0f,15,15);
//DrawMercury
glRGB(128,0,0);
glPushMatrix();
glTranslatef(24.0f,0.0f,0.0f);
glLoadName(MERCURY);
glutSolidSphere(2.0f,15,15);
glPopMatrix();
//DrawVenus
glPushMatrix();
glRGB(128,128,255);
glTranslatef(60.0f,0.0f,0.0f);
glLoadName(VENUS);
glutSolidSphere(4.0f,15,15);
glPopMatrix();
//DrawtheEarth
glPushMatrix();
glRGB(0,0,255);
glTranslatef(100.0f,0.0f,0.0f);
glLoadName(EARTH);
glutSolidSphere(8.0f,15,15);
glPopMatrix();
//DrawMars
glRGB(255,0,0);
glPushMatrix();
glTranslatef(150.0f,0.0f,0.0f);
glLoadName(MARS);
glutSolidSphere(4.0f,15,15);
glPopMatrix();

//Restorethematrixstate
glPopMatrix();//Modelviewmatrix
glutSwapBuffers();
}

//Presenttheinformationonwhichplanet/sunwasselectedanddisplayed
voidProcessPlanet(GLuintid)

{
switch(id)

{
caseSUN:
MessageBox(NULL,"YouclickedontheSun!","Info",MB_OK|MB_ICONEXCLAMATION);
break;
caseMERCURY:
MessageBox(NULL,"YouclickedonMercury!","Info",MB_OK|MB_ICONEXCLAMATION);
break;
caseVENUS:
MessageBox(NULL,"YouclickedonVenus!","Info",MB_OK|MB_ICONEXCLAMATION);
break;
caseEARTH:
MessageBox(NULL,"YouclickedonEarth!","Info",MB_OK|MB_ICONEXCLAMATION);
break;
caseMARS:
MessageBox(NULL,"YouclickedonMars!","Info",MB_OK|MB_ICONEXCLAMATION);
break;
default:
MessageBox(NULL,"Nothingwasclickedon!","Error",MB_OK|MB_ICONEXCLAMATION);
break;
}
}
//Processtheselection,whichistriggeredbyarightmouse
//clickat(xPos,yPos).
#defineBUFFER_LENGTH64
//重点段
voidProcessSelection(intxPos,intyPos)

{
//Spaceforselectionbuffer
GLuintselectBuff[BUFFER_LENGTH];
//Hitcounterandviewportstoreage
GLinthits,viewport[4];
//Setupselectionbuffer
glSelectBuffer(BUFFER_LENGTH,selectBuff);
//Gettheviewport
glGetIntegerv(GL_VIEWPORT,viewport);
//Switchtoprojectionandsavethematrix
glMatrixMode(GL_PROJECTION);
glPushMatrix();
//Changerendermode
glRenderMode(GL_SELECT);
//Establishnewclippingvolumetobeunitcubearound
//mousecursorpoint(xPos,yPos)andextendingtwopixels
//intheverticalandhorzontaldirection
glLoadIdentity();
gluPickMatrix(xPos,viewport[3]-yPos,2,2,viewport);
//Applyperspectivematrix
gluPerspective(45.0f,fAspect,1.0,425.0);
//Drawthescene
RenderScene();
//Collectthehits
hits=glRenderMode(GL_RENDER);
//Ifasinglehitoccured,displaytheinfo.
if(hits==1)
ProcessPlanet(selectBuff[3]);
//Restoretheprojectionmatrix
glMatrixMode(GL_PROJECTION);
glPopMatrix();
//Gobacktomodelviewfornormalrendering
glMatrixMode(GL_MODELVIEW);
//n=selectBuff[0];
//printfn;

}

//Processthemouseclick
voidMouseCallback(intbutton,intstate,intx,inty)

{
if(button==GLUT_LEFT_BUTTON&&state==GLUT_DOWN)
ProcessSelection(x,y);
}

//Thisfunctiondoesanyneededinitializationontherendering
//context.
voidSetupRC()

{
//Lightvaluesandcoordinates
glEnable(GL_DEPTH_TEST);//Hiddensurfaceremoval
glFrontFace(GL_CCW);//Counterclock-wisepolygonsfaceout
glEnable(GL_CULL_FACE);//Donotcalculateinsides
//Enablelighting
glEnable(GL_LIGHTING);
//Setupandenablelight0
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,whiteLight);
glLightfv(GL_LIGHT0,GL_DIFFUSE,sourceLight);
glLightfv(GL_LIGHT0,GL_POSITION,lightPos);
glEnable(GL_LIGHT0);
//Enablecolortracking
glEnable(GL_COLOR_MATERIAL);
//SetMaterialpropertiestofollowglColorvalues
glColorMaterial(GL_FRONT,GL_AMBIENT_AND_DIFFUSE);
//Blackbluebackground
glClearColor(0.60f,0.60f,0.60f,1.0f);
}
voidChangeSize(intw,inth)

{
//Preventadividebyzero
if(h==0)
h=1;
//SetViewporttowindowdimensions
glViewport(0,0,w,h);
//Calculateaspectratioofthewindow
fAspect=(GLfloat)w/(GLfloat)h;
//Settheperspectivecoordinatesystem
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
//Fieldofviewof45degrees,nearandfarplanes1.0and425
gluPerspective(45.0f,fAspect,1.0,425.0);
//Modelviewmatrixreset
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
intmain(intargc,char*argv[])

{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH);
glutInitWindowSize(600,300);
glutCreateWindow("PickaPlanet");
glutReshapeFunc(ChangeSize);
glutMouseFunc(MouseCallback);
glutDisplayFunc(RenderScene);
SetupRC();
glutMainLoop();
return0;
}
该程序使用OpenGL和GLUT库创建了一个3D场景,展示太阳系中的五个天体:太阳、水星、金星、地球和火星。用户可以通过点击来选择特定的行星或太阳,并通过弹出的消息框获取所选天体的信息。
456

被折叠的 条评论
为什么被折叠?



