OpenGL入门笔记(八)

ContractedBlock.gif ExpandedBlockStart.gifDemo8
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->None.gif
None.gif
booltwinkle;//TwinklingStars
None.gif
booltp;//'T'KeyPressed?
None.gif

None.gif
constnum=50;//NumberOfStarsToDraw
None.gif

None.giftypedef
struct//CreateAStructureForStar
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif
intr,g,b;//StarsColor
InBlock.gif
GLfloatdist,//StarsDistanceFromCenter
InBlock.gif
angle;//StarsCurrentAngle
ExpandedBlockEnd.gif
}

None.gifstars;
None.gifstarsstar[num];
//NeedToKeepTrackOf'num'Stars
None.gif

None.gifGLfloatzoom
=-15.0f;//DistanceAwayFromStars
None.gif
GLfloattilt=90.0f;//TiltTheView
None.gif
GLfloatspin;//SpinStars
None.gif

None.gifGLuintloop;
//GeneralLoopVariable
None.gif
GLuinttexture[1];//StorageForOnetextures
None.gif

None.gif
None.gif
intInitGL(GLvoid)//AllSetupForOpenGLGoesHere
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif
if(!LoadGLTextures())//JumpToTextureLoadingRoutine
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
returnFALSE;//IfTextureDidn'tLoadReturnFALSE
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gifglEnable(GL_TEXTURE_2D);
//EnableTextureMapping
InBlock.gif
glShadeModel(GL_SMOOTH);//EnableSmoothShading
InBlock.gif
glClearColor(0.0f,0.0f,0.0f,0.5f);//BlackBackground
InBlock.gif
glClearDepth(1.0f);//DepthBufferSetup
InBlock.gif
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);//ReallyNicePerspectiveCalculations
InBlock.gif
glBlendFunc(GL_SRC_ALPHA,GL_ONE);//SetTheBlendingFunctionForTranslucency
InBlock.gif
glEnable(GL_BLEND);
InBlock.gif
InBlock.gif
for(loop=0;loop<num;loop++)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifstar[loop].angle
=0.0f;
InBlock.gifstar[loop].dist
=(float(loop)/num)*5.0f;
InBlock.gifstar[loop].r
=rand()%256;
InBlock.gifstar[loop].g
=rand()%256;
InBlock.gifstar[loop].b
=rand()%256;
ExpandedSubBlockEnd.gif}

InBlock.gif
returnTRUE;//InitializationWentOK
ExpandedBlockEnd.gif
}

None.gif
None.gif
intDrawGLScene(GLvoid)//Here'sWhereWeDoAllTheDrawing
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gifglClear(GL_COLOR_BUFFER_BIT
|GL_DEPTH_BUFFER_BIT);//ClearTheScreenAndTheDepthBuffer
InBlock.gif
glBindTexture(GL_TEXTURE_2D,texture[0]);//SelectOurTexture
InBlock.gif

InBlock.gif
for(loop=0;loop<num;loop++)//LoopThroughAllTheStars
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
//glPushMatrix();
InBlock.gif
glLoadIdentity();//ResetTheViewBeforeWeDrawEachStar
InBlock.gif
glTranslatef(0.0f,0.0f,zoom);//ZoomIntoTheScreen(UsingTheValueIn'zoom')
InBlock.gif
glRotatef(tilt,1.0f,0.0f,0.0f);//TiltTheView(UsingTheValueIn'tilt')
InBlock.gif
glRotatef(star[loop].angle,0.0f,1.0f,0.0f);//RotateToTheCurrentStarsAngle
InBlock.gif
glTranslatef(star[loop].dist,0.0f,0.0f);//MoveForwardOnTheXPlane
InBlock.gif
glRotatef(-star[loop].angle,0.0f,1.0f,0.0f);//CancelTheCurrentStarsAngle
InBlock.gif
glRotatef(-tilt,1.0f,0.0f,0.0f);//CancelTheScreenTilt
InBlock.gif

InBlock.gif
if(twinkle)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifglColor4ub(star[(num
-loop)-1].r,star[(num-loop)-1].g,star[(num-loop)-1].b,255);
InBlock.gifglBegin(GL_QUADS);
InBlock.gifglTexCoord2f(
0.0f,0.0f);glVertex3f(-1.0f,-1.0f,0.0f);
InBlock.gifglTexCoord2f(
1.0f,0.0f);glVertex3f(1.0f,-1.0f,0.0f);
InBlock.gifglTexCoord2f(
1.0f,1.0f);glVertex3f(1.0f,1.0f,0.0f);
InBlock.gifglTexCoord2f(
0.0f,1.0f);glVertex3f(-1.0f,1.0f,0.0f);
InBlock.gifglEnd();
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gifglRotatef(spin,
0.0f,0.0f,1.0f);
InBlock.gifglColor4ub(star[loop].r,star[loop].g,star[loop].b,
255);
InBlock.gifglBegin(GL_QUADS);
InBlock.gifglTexCoord2f(
0.0f,0.0f);glVertex3f(-1.0f,-1.0f,0.0f);
InBlock.gifglTexCoord2f(
1.0f,0.0f);glVertex3f(1.0f,-1.0f,0.0f);
InBlock.gifglTexCoord2f(
1.0f,1.0f);glVertex3f(1.0f,1.0f,0.0f);
InBlock.gifglTexCoord2f(
0.0f,1.0f);glVertex3f(-1.0f,1.0f,0.0f);
InBlock.gifglEnd();
InBlock.gif
InBlock.gifspin
+=0.01f;
InBlock.gifstar[loop].angle
+=float(loop)/num;
InBlock.gifstar[loop].dist
-=0.01f;
InBlock.gif
if(star[loop].dist<0.0f)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifstar[loop].dist
+=5.0f;
InBlock.gifstar[loop].r
=rand()%256;
InBlock.gifstar[loop].g
=rand()%256;
InBlock.gifstar[loop].b
=rand()%256;
ExpandedSubBlockEnd.gif}

InBlock.gif
//glPopMatrix();
ExpandedSubBlockEnd.gif
}

InBlock.gif
returnTRUE;
ExpandedBlockEnd.gif}

None.gif

这里设置OpenGL的渲染方式不打算使用深度测试,如果使用第一课的代码的话,请确认是否已经去掉了glDepthFunc(GL_LEQUAL);glEnable(GL_DEPTH_TEST);两行。否则,所见到的效果将会一团糟。这里我们使用了纹理映射,可以注意到我们通过混色来启用了纹理映射。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

这里我们使用的颜色设置函数是glColor4ub,而不是以前的glColor<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="4" unitname="F">4f</chmetcnv>ub意味着参数是Unsigned Byte型的。一个byte的取值范围是0255

不过代码中有一处我没有看明白什么意思:

None.gif glTranslatef( 0.0f , 0.0f ,zoom); // ZoomIntoTheScreen(UsingTheValueIn'zoom')
None.gif
glRotatef(tilt, 1.0f , 0.0f , 0.0f ); // TiltTheView(UsingTheValueIn'tilt')
None.gif
glRotatef(star[loop].angle, 0.0f , 1.0f , 0.0f ); // RotateToTheCurrentStarsAngle
None.gif
glTranslatef(star[loop].dist, 0.0f , 0.0f ); // MoveForwardOnTheXPlane
None.gif
glRotatef( - star[loop].angle, 0.0f , 1.0f , 0.0f ); // CancelTheCurrentStarsAngle
None.gif
glRotatef( - tilt, 1.0f , 0.0f , 0.0f ); // CancelTheScreenTilt
None.gif


教材上给的解释如下,捉摸不透:

  现在我们来移动星星。星星开始时位于屏幕的中心。我们要做的第一件事是把场景沿Y轴旋转。如果我们旋转90度的话,X轴不再是自左至右的了,他将由里向外穿出屏幕。为了让大家更清楚些,举个例子。假想您站在房子中间。再设想您左侧的墙上写着-x,前面的墙上写着-z,右面墙上就是+x咯,您身后的墙上则是+z。加入整个房子向右转90度,但您没有动,那么前面的墙上将是-x而不再是-z了。所有其他的墙也都跟着移动。-z出现在右侧,+z出现在左侧,+x出现在您背后。神经错乱了吧?通过旋转场景,我们改变了xz平面的方向。
   第二行代码沿x轴移动一个正值。通常x轴上的正值代表移向了屏幕的右侧(也就是通常的x轴的正向),但这里由于我们绕y轴旋转了坐标系,x轴的正向可以是任意方向。如果我们转180度的话,屏幕的左右侧就镜像反向了。因此,当我们沿 x轴正向移动。

   glRotatef(star[loop].angle,<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="0" unitname="F">0.0f</chmetcnv>,<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="1" unitname="F">1.0f</chmetcnv>,<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="0" unitname="F">0.0f</chmetcnv>); // 旋转至当前所画星星的角度
          glTranslatef(star[loop].dist,<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="0" unitname="F">0.0f</chmetcnv>,<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="0" unitname="F">0.0f</chmetcnv>);  // 沿X轴正向移动

   接着的代码带点小技巧。星星实际上是一个平面的纹理。现在您在屏幕中心画了个平面的四边形然后贴上纹理,这看起来很不错。一切都如您所想的那样。但是当您当您沿着y轴转上个90度的话,纹理在屏幕上就只剩右侧和左侧的两条边朝着您。看起来就是一条细线。这不是我们所想要的。我们希望星星永远正面朝着我们,而不管屏幕如何旋转或倾斜。
   我们通过在绘制星星之前,抵消对星星所作的任何旋转来实现这个愿望。您可以采用逆序来抵消旋转。当我们倾斜屏幕时,我们实际上以当前角度旋转了星星。通过逆序,我们又以当前角度反旋转星星。也就是以当前角度的负值来旋转星星。就是说,如果我们将星星旋转了10度的话,又将其旋转-10度来使星星在那个轴上重新面对屏幕。下面的第一行抵消了沿y轴的旋转。然后,我们还需要抵消掉沿x轴的屏幕倾斜。要做到这一点,我们只需要将屏幕再旋转-tilt倾角。在抵消掉xy轴的旋转后,星星又完全面对着我们了。

           glRotatef(-star[loop].angle,<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="0" unitname="F">0.0f</chmetcnv>,<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="1" unitname="F">1.0f</chmetcnv>,<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="0" unitname="F">0.0f</chmetcnv>); // 取消当前星星的角度
          glRotatef(-tilt,<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="1" unitname="F">1.0f</chmetcnv>,<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="0" unitname="F">0.0f</chmetcnv>,<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="0" unitname="F">0.0f</chmetcnv>);       // 取消屏幕倾斜

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值