OpenGL入门笔记(七)

本文介绍OpenGL中的混色技术,详细解释了如何通过混色因子控制透明度,实现图像的透明和半透明效果。同时提供了混色公式及示例代码。

OpenGL中的绝大多数特效都与某些类型的(色彩)混合有关。混色的定义为,将某个象素的颜色和已绘制在屏幕上与其对应的象素颜色相互结合。至于如何结合这两个颜色则依赖于颜色的alpha通道的分量值,以及/或者所使用的混色函数。Alpha通常是位于颜色值末尾的第4个颜色组成分量。前面这些课我们都是用GL_RGB来指定颜色的三个分量。相应的GL_RGBA可以指定alpha分量的值。更进一步,我们可以使用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>()来代替glColor<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="3" unitname="F">3f</chmetcnv>()<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


   绝大多数人都认为Alpha分量代表材料的透明度。这就是说,alpha值为0.0时所代表的材料是完全透明的。alpha值为1.0时所代表的材料则是完全不透明的。

混合的基本原理是就将要分色的图像各象素的颜色以及背景颜色均按照RGB规则各自分离之后,根据图像的RGB颜色分量*alpha+背景的RGB颜色分量*(1-alpha) — 这样一个简单公式来混合之后,最后将混合得到的RGB分量重新合并。)公式如下:

(Rs Sr + Rd Dr, Gs Sg + Gd Dg, Bs Sb + Bd Db, As Sa + Ad Da)


   OpenGL按照上面的公式计算这两个象素的混色结果。小写的sr分别代表源象素和目标象素。大写的SD则是相应的混色因子。这些决定了您如何对这些象素混色。绝大多数情况下,各颜色通道的alpha混色值大小相同,这样对源象素就有(As, As, As, As),目标象素则有(1, 1, 1, 1) - (As, As, As, As)。上面的公式就成了下面的模样:

(Rs As + Rd (1 - As), Gs As + Gd (1 - As), Bs As + Bs (1 - As), As As + Ad (1 - As))

这个公式会生成透明/半透明的效果。

OpenGL中首先我们得打开混合, 然后设置混合式。在绘制透明物体的时候, 我们关闭深度缓存, 因为我们仍然希望在半透明物体后面的物体能被绘制。 这并不是使用混合的正确方式, 但是在情况简单的时候它会工作得很好。正确的混色过程应该是先绘制全部的场景之后再绘制透明的图形。并且要按照与深度缓存相反的次序来绘制(先画最远的物体)。考虑对两个多边形(12)进行alpha混合,不同的绘制次序会得到不同的结果。(这里假定多边形1离观察者最近,那么正确的过程应该先画多边形2,再画多边形1。正如您再现实中所见到的那样,从这两个透明的多边形背后照射来的光线总是先穿过多边形2,再穿过多边形1,最后才到达观察者的眼睛)。 在深度缓存启用时,您应该将透明图形按照深度进行排序,并在全部场景绘制完毕之后再绘制这些透明物体。否则您将得到不正确的结果。

ContractedBlock.gifExpandedBlockStart.gifdemo8
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->None.gif#include<windows.h>//HeaderFileForWindows
None.gif
#include<stdio.h>//HeaderFileForStandardInput/Output
None.gif
#include<gl/gl.h>//HeaderFileForTheOpenGL32Library
None.gif
#include<gl/glu.h>//HeaderFileForTheGLu32Library
None.gif
#include<gl/glaux.h>//HeaderFileForTheGlauxLibrary
None.gif

None.gifHDChDC
=NULL;//PrivateGDIDeviceContext
None.gif
HGLRChRC=NULL;//PermanentRenderingContext
None.gif
HWNDhWnd=NULL;//HoldsOurWindowHandle
None.gif
HINSTANCEhInstance;//HoldsTheInstanceOfTheApplication
None.gif

None.gif
boolkeys[256];//ArrayUsedForTheKeyboardRoutine
None.gif
boolactive=TRUE;//WindowActiveFlagSetToTRUEByDefault
None.gif
boolfullscreen=TRUE;//FullscreenFlagSetToFullscreenModeByDefault
None.gif
boollight;//LightingON/OFF
None.gif
boolblend;//BlendingOFF/ON?(NEW)
None.gif
boollp;//LPressed?
None.gif
boolfp;//FPressed?
None.gif
boolbp;//BPressed?(NEW)
None.gif

None.gifGLfloatxrot;
//XRotation
None.gif
GLfloatyrot;//YRotation
None.gif
GLfloatxspeed;//XRotationSpeed
None.gif
GLfloatyspeed;//YRotationSpeed
None.gif
GLfloatz=-5.0f;//DepthIntoTheScreen
None.gif

ExpandedBlockStart.gifContractedBlock.gifGLfloatLightAmbient[]
=dot.gif{0.5f,0.5f,0.5f,1.0f};
ExpandedBlockStart.gifContractedBlock.gifGLfloatLightDiffuse[]
=dot.gif{1.0f,1.0f,1.0f,1.0f};
ExpandedBlockStart.gifContractedBlock.gifGLfloatLightPosition[]
=dot.gif{0.0f,0.0f,2.0f,1.0f};
None.gif
None.gifGLuintfilter;
//WhichFilterToUse
None.gif
GLuinttexture[3];//StorageFor3Textures
None.gif

None.gifLRESULTCALLBACKWndProc(HWND,UINT,WPARAM,LPARAM);
//DeclarationForWndProc
None.gif

None.gifAUX_RGBImageRec
*LoadBMP(char*Filename)//LoadsABitmapImage
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gifFILE
*File=NULL;//FileHandle
InBlock.gif

InBlock.gif
if(!Filename)//MakeSureAFilenameWasGiven
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
returnNULL;//IfNotReturnNULL
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gifFile
=fopen(Filename,"r");//CheckToSeeIfTheFileExists
InBlock.gif

InBlock.gif
if(File)//DoesTheFileExist?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.giffclose(File);
//CloseTheHandle
InBlock.gif
returnauxDIBImageLoad(Filename);//LoadTheBitmapAndReturnAPointer
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
returnNULL;//IfLoadFailedReturnNULL
ExpandedBlockEnd.gif
}

None.gif
None.gif
intLoadGLTextures()//LoadBitmapsAndConvertToTextures
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif
intStatus=FALSE;//StatusIndicator
InBlock.gif

InBlock.gifAUX_RGBImageRec
*TextureImage[1];//CreateStorageSpaceForTheTexture
InBlock.gif

InBlock.gifmemset(TextureImage,
0,sizeof(void*)*1);//SetThePointerToNULL
InBlock.gif
InBlock.gif
//LoadTheBitmap,CheckForErrors,IfBitmap'sNotFoundQuit
InBlock.gif
if(TextureImage[0]=LoadBMP("Data/glass.bmp"))
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifStatus
=TRUE;//SetTheStatusToTRUE
InBlock.gif

InBlock.gifglGenTextures(
3,&texture[0]);//CreateThreeTextures
InBlock.gif
InBlock.gif
//CreateNearestFilteredTexture
InBlock.gif
glBindTexture(GL_TEXTURE_2D,texture[0]);
InBlock.gifglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
InBlock.gifglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
InBlock.gifglTexImage2D(GL_TEXTURE_2D,
0,3,TextureImage[0]->sizeX,TextureImage[0]->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,TextureImage[0]->data);
InBlock.gif
InBlock.gif
//CreateLinearFilteredTexture
InBlock.gif
glBindTexture(GL_TEXTURE_2D,texture[1]);
InBlock.gifglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
InBlock.gifglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
InBlock.gifglTexImage2D(GL_TEXTURE_2D,
0,3,TextureImage[0]->sizeX,TextureImage[0]->sizeY,0,GL_RGB,GL_UNSIGNED_BYTE,TextureImage[0]->data);
InBlock.gif
InBlock.gif
//CreateMipMappedTexture
InBlock.gif
glBindTexture(GL_TEXTURE_2D,texture[2]);
InBlock.gifglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
InBlock.gifglTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
InBlock.gifgluBuild2DMipmaps(GL_TEXTURE_2D,
3,TextureImage[0]->sizeX,TextureImage[0]->sizeY,GL_RGB,GL_UNSIGNED_BYTE,TextureImage[0]->data);
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
if(TextureImage[0])//IfTextureExists
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
if(TextureImage[0]->data)//IfTextureImageExists
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.giffree(TextureImage[
0]->data);//FreeTheTextureImageMemory
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.giffree(TextureImage[
0]);//FreeTheImageStructure
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
returnStatus;//ReturnTheStatus
ExpandedBlockEnd.gif
}

None.gif
None.gifGLvoidReSizeGLScene(GLsizeiwidth,GLsizeiheight)
//ResizeAndInitializeTheGLWindow
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif
if(height==0)//PreventADivideByZeroBy
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifheight
=1;//MakingHeightEqualOne
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gifglViewport(
0,0,width,height);//ResetTheCurrentViewport
InBlock.gif

InBlock.gifglMatrixMode(GL_PROJECTION);
//SelectTheProjectionMatrix
InBlock.gif
glLoadIdentity();//ResetTheProjectionMatrix
InBlock.gif
InBlock.gif
//CalculateTheAspectRatioOfTheWindow
InBlock.gif
gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);
InBlock.gif
InBlock.gifglMatrixMode(GL_MODELVIEW);
//SelectTheModelviewMatrix
InBlock.gif
glLoadIdentity();//ResetTheModelviewMatrix
ExpandedBlockEnd.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
glEnable(GL_DEPTH_TEST);//EnablesDepthTesting
InBlock.gif
glDepthFunc(GL_LEQUAL);//TheTypeOfDepthTestingToDo
InBlock.gif
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);//ReallyNicePerspectiveCalculations
InBlock.gif

InBlock.gifglLightfv(GL_LIGHT1,GL_AMBIENT,LightAmbient);
//SetupTheAmbientLight
InBlock.gif
glLightfv(GL_LIGHT1,GL_DIFFUSE,LightDiffuse);//SetupTheDiffuseLight
InBlock.gif
glLightfv(GL_LIGHT1,GL_POSITION,LightPosition);//PositionTheLight
InBlock.gif
glEnable(GL_LIGHT1);//EnableLightOne
InBlock.gif

InBlock.gifglColor4f(
1.0f,1.0f,1.0f,0.5);//FullBrightness.50%Alpha
InBlock.gif
glBlendFunc(GL_SRC_ALPHA,GL_ONE);//SetTheBlendingFunctionForTranslucency
InBlock.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
glLoadIdentity();//ResetTheView
InBlock.gif
glTranslatef(0.0f,0.0f,z);
InBlock.gif
InBlock.gifglRotatef(xrot,
1.0f,0.0f,0.0f);
InBlock.gifglRotatef(yrot,
0.0f,1.0f,0.0f);
InBlock.gif
InBlock.gifglBindTexture(GL_TEXTURE_2D,texture[filter]);
InBlock.gif
InBlock.gifglBegin(GL_QUADS);
InBlock.gif
//FrontFace
InBlock.gif
glNormal3f(0.0f,0.0f,1.0f);
InBlock.gifglTexCoord2f(
0.0f,0.0f);glVertex3f(-1.0f,-1.0f,1.0f);
InBlock.gifglTexCoord2f(
1.0f,0.0f);glVertex3f(1.0f,-1.0f,1.0f);
InBlock.gifglTexCoord2f(
1.0f,1.0f);glVertex3f(1.0f,1.0f,1.0f);
InBlock.gifglTexCoord2f(
0.0f,1.0f);glVertex3f(-1.0f,1.0f,1.0f);
InBlock.gif
//BackFace
InBlock.gif
glNormal3f(0.0f,0.0f,-1.0f);
InBlock.gifglTexCoord2f(
1.0f,0.0f);glVertex3f(-1.0f,-1.0f,-1.0f);
InBlock.gifglTexCoord2f(
1.0f,1.0f);glVertex3f(-1.0f,1.0f,-1.0f);
InBlock.gifglTexCoord2f(
0.0f,1.0f);glVertex3f(1.0f,1.0f,-1.0f);
InBlock.gifglTexCoord2f(
0.0f,0.0f);glVertex3f(1.0f,-1.0f,-1.0f);
InBlock.gif
//TopFace
InBlock.gif
glNormal3f(0.0f,1.0f,0.0f);
InBlock.gifglTexCoord2f(
0.0f,1.0f);glVertex3f(-1.0f,1.0f,-1.0f);
InBlock.gifglTexCoord2f(
0.0f,0.0f);glVertex3f(-1.0f,1.0f,1.0f);
InBlock.gifglTexCoord2f(
1.0f,0.0f);glVertex3f(1.0f,1.0f,1.0f);
InBlock.gifglTexCoord2f(
1.0f,1.0f);glVertex3f(1.0f,1.0f,-1.0f);
InBlock.gif
//BottomFace
InBlock.gif
glNormal3f(0.0f,-1.0f,0.0f);
InBlock.gifglTexCoord2f(
1.0f,1.0f);glVertex3f(-1.0f,-1.0f,-1.0f);
InBlock.gifglTexCoord2f(
0.0f,1.0f);glVertex3f(1.0f,-1.0f,-1.0f);
InBlock.gifglTexCoord2f(
0.0f,0.0f);glVertex3f(1.0f,-1.0f,1.0f);
InBlock.gifglTexCoord2f(
1.0f,0.0f);glVertex3f(-1.0f,-1.0f,1.0f);
InBlock.gif
//Rightface
InBlock.gif
glNormal3f(1.0f,0.0f,0.0f);
InBlock.gifglTexCoord2f(
1.0f,0.0f);glVertex3f(1.0f,-1.0f,-1.0f);
InBlock.gifglTexCoord2f(
1.0f,1.0f);glVertex3f(1.0f,1.0f,-1.0f);
InBlock.gifglTexCoord2f(
0.0f,1.0f);glVertex3f(1.0f,1.0f,1.0f);
InBlock.gifglTexCoord2f(
0.0f,0.0f);glVertex3f(1.0f,-1.0f,1.0f);
InBlock.gif
//LeftFace
InBlock.gif
glNormal3f(-1.0f,0.0f,0.0f);
InBlock.gifglTexCoord2f(
0.0f,0.0f);glVertex3f(-1.0f,-1.0f,-1.0f);
InBlock.gifglTexCoord2f(
1.0f,0.0f);glVertex3f(-1.0f,-1.0f,1.0f);
InBlock.gifglTexCoord2f(
1.0f,1.0f);glVertex3f(-1.0f,1.0f,1.0f);
InBlock.gifglTexCoord2f(
0.0f,1.0f);glVertex3f(-1.0f,1.0f,-1.0f);
InBlock.gifglEnd();
InBlock.gif
InBlock.gifxrot
+=xspeed;
InBlock.gifyrot
+=yspeed;
InBlock.gif
returnTRUE;//KeepGoing
ExpandedBlockEnd.gif
}

None.gif
None.gifGLvoidKillGLWindow(GLvoid)
//ProperlyKillTheWindow
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif
if(fullscreen)//AreWeInFullscreenMode?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifChangeDisplaySettings(NULL,
0);//IfSoSwitchBackToTheDesktop
InBlock.gif
ShowCursor(TRUE);//ShowMousePointer
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
if(hRC)//DoWeHaveARenderingContext?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
if(!wglMakeCurrent(NULL,NULL))//AreWeAbleToReleaseTheDCAndRCContexts?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifMessageBox(NULL,
"ReleaseOfDCAndRCFailed.","SHUTDOWNERROR",MB_OK|MB_ICONINFORMATION);
ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
if(!wglDeleteContext(hRC))//AreWeAbleToDeleteTheRC?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifMessageBox(NULL,
"ReleaseRenderingContextFailed.","SHUTDOWNERROR",MB_OK|MB_ICONINFORMATION);
ExpandedSubBlockEnd.gif}

InBlock.gifhRC
=NULL;//SetRCToNULL
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
if(hDC&&!ReleaseDC(hWnd,hDC))//AreWeAbleToReleaseTheDC
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifMessageBox(NULL,
"ReleaseDeviceContextFailed.","SHUTDOWNERROR",MB_OK|MB_ICONINFORMATION);
InBlock.gifhDC
=NULL;//SetDCToNULL
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
if(hWnd&&!DestroyWindow(hWnd))//AreWeAbleToDestroyTheWindow?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifMessageBox(NULL,
"CouldNotReleasehWnd.","SHUTDOWNERROR",MB_OK|MB_ICONINFORMATION);
InBlock.gifhWnd
=NULL;//SethWndToNULL
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
if(!UnregisterClass("OpenGL",hInstance))//AreWeAbleToUnregisterClass
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifMessageBox(NULL,
"CouldNotUnregisterClass.","SHUTDOWNERROR",MB_OK|MB_ICONINFORMATION);
InBlock.gifhInstance
=NULL;//SethInstanceToNULL
ExpandedSubBlockEnd.gif
}

ExpandedBlockEnd.gif}

None.gif
ExpandedBlockStart.gifContractedBlock.gif
/**//*ThisCodeCreatesOurOpenGLWindow.ParametersAre:*
InBlock.gif*title-TitleToAppearAtTheTopOfTheWindow*
InBlock.gif*width-WidthOfTheGLWindowOrFullscreenMode*
InBlock.gif*height-HeightOfTheGLWindowOrFullscreenMode*
InBlock.gif*bits-NumberOfBitsToUseForColor(8/16/24/32)*
ExpandedBlockEnd.gif*fullscreenflag-UseFullscreenMode(TRUE)OrWindowedMode(FALSE)
*/

None.gif
None.gifBOOLCreateGLWindow(
char*title,intwidth,intheight,intbits,boolfullscreenflag)
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gifGLuintPixelFormat;
//HoldsTheResultsAfterSearchingForAMatch
InBlock.gif
WNDCLASSwc;//WindowsClassStructure
InBlock.gif
DWORDdwExStyle;//WindowExtendedStyle
InBlock.gif
DWORDdwStyle;//WindowStyle
InBlock.gif
RECTWindowRect;//GrabsRectangleUpperLeft/LowerRightValues
InBlock.gif
WindowRect.left=(long)0;//SetLeftValueTo0
InBlock.gif
WindowRect.right=(long)width;//SetRightValueToRequestedWidth
InBlock.gif
WindowRect.top=(long)0;//SetTopValueTo0
InBlock.gif
WindowRect.bottom=(long)height;//SetBottomValueToRequestedHeight
InBlock.gif

InBlock.giffullscreen
=fullscreenflag;//SetTheGlobalFullscreenFlag
InBlock.gif

InBlock.gifhInstance
=GetModuleHandle(NULL);//GrabAnInstanceForOurWindow
InBlock.gif
wc.style=CS_HREDRAW|CS_VREDRAW|CS_OWNDC;//RedrawOnSize,AndOwnDCForWindow.
InBlock.gif
wc.lpfnWndProc=(WNDPROC)WndProc;//WndProcHandlesMessages
InBlock.gif
wc.cbClsExtra=0;//NoExtraWindowData
InBlock.gif
wc.cbWndExtra=0;//NoExtraWindowData
InBlock.gif
wc.hInstance=hInstance;//SetTheInstance
InBlock.gif
wc.hIcon=LoadIcon(NULL,IDI_WINLOGO);//LoadTheDefaultIcon
InBlock.gif
wc.hCursor=LoadCursor(NULL,IDC_ARROW);//LoadTheArrowPointer
InBlock.gif
wc.hbrBackground=NULL;//NoBackgroundRequiredForGL
InBlock.gif
wc.lpszMenuName=NULL;//WeDon'tWantAMenu
InBlock.gif
wc.lpszClassName="OpenGL";//SetTheClassName
InBlock.gif

InBlock.gif
if(!RegisterClass(&wc))//AttemptToRegisterTheWindowClass
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifMessageBox(NULL,
"FailedToRegisterTheWindowClass.","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif
returnFALSE;//ReturnFALSE
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
if(fullscreen)//AttemptFullscreenMode?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifDEVMODEdmScreenSettings;
//DeviceMode
InBlock.gif
memset(&dmScreenSettings,0,sizeof(dmScreenSettings));//MakesSureMemory'sCleared
InBlock.gif
dmScreenSettings.dmSize=sizeof(dmScreenSettings);//SizeOfTheDevmodeStructure
InBlock.gif
dmScreenSettings.dmPelsWidth=width;//SelectedScreenWidth
InBlock.gif
dmScreenSettings.dmPelsHeight=height;//SelectedScreenHeight
InBlock.gif
dmScreenSettings.dmBitsPerPel=bits;//SelectedBitsPerPixel
InBlock.gif
dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;
InBlock.gif
InBlock.gif
//TryToSetSelectedModeAndGetResults.NOTE:CDS_FULLSCREENGetsRidOfStartBar.
InBlock.gif
if(ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
//IfTheModeFails,OfferTwoOptions.QuitOrUseWindowedMode.
InBlock.gif
if(MessageBox(NULL,"TheRequestedFullscreenModeIsNotSupportedBy/nYourVideoCard.UseWindowedModeInstead?","NeHeGL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.giffullscreen
=FALSE;//WindowedModeSelected.Fullscreen=FALSE
ExpandedSubBlockEnd.gif
}

InBlock.gif
else
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
//PopUpAMessageBoxLettingUserKnowTheProgramIsClosing.
InBlock.gif
MessageBox(NULL,"ProgramWillNowClose.","ERROR",MB_OK|MB_ICONSTOP);
InBlock.gif
returnFALSE;//ReturnFALSE
ExpandedSubBlockEnd.gif
}

ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
if(fullscreen)//AreWeStillInFullscreenMode?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifdwExStyle
=WS_EX_APPWINDOW;//WindowExtendedStyle
InBlock.gif
dwStyle=WS_POPUP;//WindowsStyle
InBlock.gif
ShowCursor(FALSE);//HideMousePointer
ExpandedSubBlockEnd.gif
}

InBlock.gif
else
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifdwExStyle
=WS_EX_APPWINDOW|WS_EX_WINDOWEDGE;//WindowExtendedStyle
InBlock.gif
dwStyle=WS_OVERLAPPEDWINDOW;//WindowsStyle
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gifAdjustWindowRectEx(
&WindowRect,dwStyle,FALSE,dwExStyle);//AdjustWindowToTrueRequestedSize
InBlock.gif
InBlock.gif
//CreateTheWindow
InBlock.gif
if(!(hWnd=CreateWindowEx(dwExStyle,//ExtendedStyleForTheWindow
InBlock.gif
"OpenGL",//ClassName
InBlock.gif
title,//WindowTitle
InBlock.gif
dwStyle|//DefinedWindowStyle
InBlock.gif
WS_CLIPSIBLINGS|//RequiredWindowStyle
InBlock.gif
WS_CLIPCHILDREN,//RequiredWindowStyle
InBlock.gif
0,0,//WindowPosition
InBlock.gif
WindowRect.right-WindowRect.left,//CalculateWindowWidth
InBlock.gif
WindowRect.bottom-WindowRect.top,//CalculateWindowHeight
InBlock.gif
NULL,//NoParentWindow
InBlock.gif
NULL,//NoMenu
InBlock.gif
hInstance,//Instance
InBlock.gif
NULL)))//DontPassAnythingToWM_CREATE
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifKillGLWindow();
//ResetTheDisplay
InBlock.gif
MessageBox(NULL,"WindowCreationError.","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif
returnFALSE;//ReturnFALSE
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
staticPIXELFORMATDESCRIPTORpfd=//pfdTellsWindowsHowWeWantThingsToBe
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
sizeof(PIXELFORMATDESCRIPTOR),//SizeOfThisPixelFormatDescriptor
InBlock.gif
1,//VersionNumber
InBlock.gif
PFD_DRAW_TO_WINDOW|//FormatMustSupportWindow
InBlock.gif
PFD_SUPPORT_OPENGL|//FormatMustSupportOpenGL
InBlock.gif
PFD_DOUBLEBUFFER,//MustSupportDoubleBuffering
InBlock.gif
PFD_TYPE_RGBA,//RequestAnRGBAFormat
InBlock.gif
bits,//SelectOurColorDepth
InBlock.gif
0,0,0,0,0,0,//ColorBitsIgnored
InBlock.gif
0,//NoAlphaBuffer
InBlock.gif
0,//ShiftBitIgnored
InBlock.gif
0,//NoAccumulationBuffer
InBlock.gif
0,0,0,0,//AccumulationBitsIgnored
InBlock.gif
16,//16BitZ-Buffer(DepthBuffer)
InBlock.gif
0,//NoStencilBuffer
InBlock.gif
0,//NoAuxiliaryBuffer
InBlock.gif
PFD_MAIN_PLANE,//MainDrawingLayer
InBlock.gif
0,//Reserved
InBlock.gif
0,0,0//LayerMasksIgnored
ExpandedSubBlockEnd.gif
}
;
InBlock.gif
InBlock.gif
if(!(hDC=GetDC(hWnd)))//DidWeGetADeviceContext?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifKillGLWindow();
//ResetTheDisplay
InBlock.gif
MessageBox(NULL,"Can'tCreateAGLDeviceContext.","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif
returnFALSE;//ReturnFALSE
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
if(!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))//DidWindowsFindAMatchingPixelFormat?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifKillGLWindow();
//ResetTheDisplay
InBlock.gif
MessageBox(NULL,"Can'tFindASuitablePixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif
returnFALSE;//ReturnFALSE
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
if(!SetPixelFormat(hDC,PixelFormat,&pfd))//AreWeAbleToSetThePixelFormat?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifKillGLWindow();
//ResetTheDisplay
InBlock.gif
MessageBox(NULL,"Can'tSetThePixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif
returnFALSE;//ReturnFALSE
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
if(!(hRC=wglCreateContext(hDC)))//AreWeAbleToGetARenderingContext?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifKillGLWindow();
//ResetTheDisplay
InBlock.gif
MessageBox(NULL,"Can'tCreateAGLRenderingContext.","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif
returnFALSE;//ReturnFALSE
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
if(!wglMakeCurrent(hDC,hRC))//TryToActivateTheRenderingContext
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifKillGLWindow();
//ResetTheDisplay
InBlock.gif
MessageBox(NULL,"Can'tActivateTheGLRenderingContext.","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif
returnFALSE;//ReturnFALSE
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gifShowWindow(hWnd,SW_SHOW);
//ShowTheWindow
InBlock.gif
SetForegroundWindow(hWnd);//SlightlyHigherPriority
InBlock.gif
SetFocus(hWnd);//SetsKeyboardFocusToTheWindow
InBlock.gif
ReSizeGLScene(width,height);//SetUpOurPerspectiveGLScreen
InBlock.gif

InBlock.gif
if(!InitGL())//InitializeOurNewlyCreatedGLWindow
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifKillGLWindow();
//ResetTheDisplay
InBlock.gif
MessageBox(NULL,"InitializationFailed.","ERROR",MB_OK|MB_ICONEXCLAMATION);
InBlock.gif
returnFALSE;//ReturnFALSE
ExpandedSubBlockEnd.gif
}

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

None.gif
None.gifLRESULTCALLBACKWndProc(HWNDhWnd,
//HandleForThisWindow
None.gif
UINTuMsg,//MessageForThisWindow
None.gif
WPARAMwParam,//AdditionalMessageInformation
None.gif
LPARAMlParam)//AdditionalMessageInformation
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gif
switch(uMsg)//CheckForWindowsMessages
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
caseWM_ACTIVATE://WatchForWindowActivateMessage
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
if(!HIWORD(wParam))//CheckMinimizationState
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifactive
=TRUE;//ProgramIsActive
ExpandedSubBlockEnd.gif
}

InBlock.gif
else
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifactive
=FALSE;//ProgramIsNoLongerActive
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
return0;//ReturnToTheMessageLoop
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
caseWM_SYSCOMMAND://InterceptSystemCommands
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
switch(wParam)//CheckSystemCalls
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
caseSC_SCREENSAVE://ScreensaverTryingToStart?
InBlock.gif
caseSC_MONITORPOWER://MonitorTryingToEnterPowersave?
InBlock.gif
return0;//PreventFromHappening
ExpandedSubBlockEnd.gif
}

InBlock.gif
break;//Exit
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
caseWM_CLOSE://DidWeReceiveACloseMessage?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifPostQuitMessage(
0);//SendAQuitMessage
InBlock.gif
return0;//JumpBack
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
caseWM_KEYDOWN://IsAKeyBeingHeldDown?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifkeys[wParam]
=TRUE;//IfSo,MarkItAsTRUE
InBlock.gif
return0;//JumpBack
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
caseWM_KEYUP://HasAKeyBeenReleased?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifkeys[wParam]
=FALSE;//IfSo,MarkItAsFALSE
InBlock.gif
return0;//JumpBack
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
caseWM_SIZE://ResizeTheOpenGLWindow
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifReSizeGLScene(LOWORD(lParam),HIWORD(lParam));
//LoWord=Width,HiWord=Height
InBlock.gif
return0;//JumpBack
ExpandedSubBlockEnd.gif
}

ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
//PassAllUnhandledMessagesToDefWindowProc
InBlock.gif
returnDefWindowProc(hWnd,uMsg,wParam,lParam);
ExpandedBlockEnd.gif}

None.gif
None.gif
intWINAPIWinMain(HINSTANCEhInstance,//Instance
None.gif
HINSTANCEhPrevInstance,//PreviousInstance
None.gif
LPSTRlpCmdLine,//CommandLineParameters
None.gif
intnCmdShow)//WindowShowState
ExpandedBlockStart.gifContractedBlock.gif
dot.gif{
InBlock.gifMSGmsg;
//WindowsMessageStructure
InBlock.gif
BOOLdone=FALSE;//BoolVariableToExitLoop
InBlock.gif
InBlock.gif
//AskTheUserWhichScreenModeTheyPrefer
InBlock.gif
if(MessageBox(NULL,"WouldYouLikeToRunInFullscreenMode?","StartFullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.giffullscreen
=FALSE;//WindowedMode
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
//CreateOurOpenGLWindow
InBlock.gif
if(!CreateGLWindow("TomStanis&NeHe'sBlendingTutorial",640,480,16,fullscreen))
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
return0;//QuitIfWindowWasNotCreated
ExpandedSubBlockEnd.gif
}

InBlock.gif
InBlock.gif
while(!done)//LoopThatRunsWhiledone=FALSE
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))//IsThereAMessageWaiting?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
if(msg.message==WM_QUIT)//HaveWeReceivedAQuitMessage?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifdone
=TRUE;//IfSodone=TRUE
ExpandedSubBlockEnd.gif
}

InBlock.gif
else//IfNot,DealWithWindowMessages
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifTranslateMessage(
&msg);//TranslateTheMessage
InBlock.gif
DispatchMessage(&msg);//DispatchTheMessage
ExpandedSubBlockEnd.gif
}

ExpandedSubBlockEnd.gif}

InBlock.gif
else//IfThereAreNoMessages
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
//DrawTheScene.WatchForESCKeyAndQuitMessagesFromDrawGLScene()
InBlock.gif
if((active&&!DrawGLScene())||keys[VK_ESCAPE])//Active?WasThereAQuitReceived?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifdone
=TRUE;//ESCorDrawGLSceneSignalledAQuit
ExpandedSubBlockEnd.gif
}

InBlock.gif
else//NotTimeToQuit,UpdateScreen
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifSwapBuffers(hDC);
//SwapBuffers(DoubleBuffering)
InBlock.gif
if(keys['L']&&!lp)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.giflp
=TRUE;
InBlock.giflight
=!light;
InBlock.gif
if(!light)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifglDisable(GL_LIGHTING);
ExpandedSubBlockEnd.gif}

InBlock.gif
else
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifglEnable(GL_LIGHTING);
ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

InBlock.gif
if(!keys['L'])
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.giflp
=FALSE;
ExpandedSubBlockEnd.gif}

InBlock.gif
if(keys['F']&&!fp)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.giffp
=TRUE;
InBlock.giffilter
+=1;
InBlock.gif
if(filter>2)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.giffilter
=0;
ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

InBlock.gif
if(!keys['F'])
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.giffp
=FALSE;
ExpandedSubBlockEnd.gif}

InBlock.gif
if(keys[VK_PRIOR])
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifz
-=0.02f;
ExpandedSubBlockEnd.gif}

InBlock.gif
if(keys[VK_NEXT])
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifz
+=0.02f;
ExpandedSubBlockEnd.gif}

InBlock.gif
if(keys[VK_UP])
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifxspeed
-=0.01f;
ExpandedSubBlockEnd.gif}

InBlock.gif
if(keys[VK_DOWN])
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifxspeed
+=0.01f;
ExpandedSubBlockEnd.gif}

InBlock.gif
if(keys[VK_RIGHT])
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifyspeed
+=0.01f;
ExpandedSubBlockEnd.gif}

InBlock.gif
if(keys[VK_LEFT])
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifyspeed
-=0.01f;
ExpandedSubBlockEnd.gif}

InBlock.gif
//BlendingCodeStartsHere
InBlock.gif
if(keys['B']&&!bp)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifbp
=TRUE;
InBlock.gifblend
=!blend;
InBlock.gif
if(blend)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifglEnable(GL_BLEND);
//TurnBlendingOn
InBlock.gif
glDisable(GL_DEPTH_TEST);//TurnDepthTestingOff
ExpandedSubBlockEnd.gif
}

InBlock.gif
else
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifglDisable(GL_BLEND);
//TurnBlendingOff
InBlock.gif
glEnable(GL_DEPTH_TEST);//TurnDepthTestingOn
ExpandedSubBlockEnd.gif
}

ExpandedSubBlockEnd.gif}

InBlock.gif
if(!keys['B'])
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifbp
=FALSE;
ExpandedSubBlockEnd.gif}

InBlock.gif
//BlendingCodeEndsHere
InBlock.gif

InBlock.gif
if(keys[VK_F1])//IsF1BeingPressed?
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifkeys[VK_F1]
=FALSE;//IfSoMakeKeyFALSE
InBlock.gif
KillGLWindow();//KillOurCurrentWindow
InBlock.gif
fullscreen=!fullscreen;//ToggleFullscreen/WindowedMode
InBlock.gif
//RecreateOurOpenGLWindow
InBlock.gif
if(!CreateGLWindow("TomStanis&NeHe'sBlendingTutorial",640,480,16,fullscreen))
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
return0;//QuitIfWindowWasNotCreated
ExpandedSubBlockEnd.gif
}

ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

ExpandedSubBlockEnd.gif}

InBlock.gif
InBlock.gif
//Shutdown
InBlock.gif
KillGLWindow();//KillTheWindow
InBlock.gif
return(msg.wParam);//ExitTheProgram
ExpandedBlockEnd.gif
}

None.gif
None.gif
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值