OpenGL入门笔记(六)

其实纹理滤波是什么概念我也还不了解,图形学就是这样,理论和实践都不可偏废,可究竟从何处入手也是个两难的问题,有人说图形血到最后就是数学,对我这样的新手来说,快速有个概念也许不失为一个笨办法吧。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

Nehe在第6课里已经用了线性滤波了,并且还推荐我们把gl_nearest(不光滑)滤波方式和线性滤波结合起来使用,在近处时用线性滤波,在远处时用gl_nearest(不光滑)滤波,因为线性滤波对运行机器的要求高些。


ContractedBlock.gif ExpandedBlockStart.gif Demo7
<!--<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(NEW)
None.gif
boollp;//LPressed?(NEW)
None.gif
boolfp;//FPressed?(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/Crate.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
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("NeHe'sTextures,Lighting&KeyboardTutorial",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
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("NeHe'sTextures,Lighting&KeyboardTutorial",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

这一课里还讲解了如何使用光照。他使用了两种不同的光。第一种称为环境光。环境光来自于四面八方。所有场景中的对象都处于环境光的照射中。第二种类型的光源叫做漫射光。漫射光由特定的光源产生,并在您的场景中的对象表面上产生反射。处于漫射光直接照射下的任何对象表面都变得很亮,而几乎未被照射到的区域就显得要暗一些。创建光源的过程和颜色的创建完全一致,先设置用来创建光源的数组。前三个参数分别是RGB三色分量,最后一个是alpha通道参数。

GLfloat LightAmbient[]= { <?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue=".5" unitname="F">0.5f</chmetcnv>, <chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue=".5" unitname="F">0.5f</chmetcnv>, <chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue=".5" unitname="F">0.5f</chmetcnv>, <chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="1" unitname="F">1.0f</chmetcnv> };     // 环境光参数

GLfloat LightDiffuse[]= { <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="1" unitname="F">1.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="1" unitname="F">1.0f</chmetcnv> };     // 漫射光参数

最后保存光源的位置。前三个参数和glTranslate中的一样。依次分别是XYZ轴上的位移。最后一个参数取为<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="1" unitname="F"><span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Verdana">1.0f</span></chmetcnv>。这将告诉OpenGL这里指定的坐标就是光源的位置。

GLfloat LightPosition[]= { <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>, <chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="2" unitname="F">2.0f</chmetcnv>, <chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="1" unitname="F">1.0f</chmetcnv> };    // 光源位置

教程里使用三种纹理滤波方式,第一种纹理(texture 0)使用gl_nearest(不光滑)滤波方式构建。第二种纹理(texture 1)使用gl_linear(线性滤波)方式,离屏幕越近的图像看起来就越光滑。第三种纹理 texture 2)使用mipmapped滤波方式,这将创建一个外观十分优秀的纹理。

下面是创建纹理的新方法:Mip-mapping(纹理细化)。您可能会注意到当图像在屏幕上变得很小的时候,很多细节将会丢失。刚才还很不错的图案变得很难看。当您告诉OpenGL创建一个mipmapped的纹理后,OpenGL将尝试创建不同尺寸的高质量纹理。当您向屏幕绘制一个mipmapped纹理的时候,OpenGL将选择它已经创建的外观最佳的纹理(带有更多细节)来绘制,而不仅仅是缩放原先的图像(这将导致细节丢失)。

要绕过OpenGL对纹理宽度和高度所加的限制 64128256等等)。办法就是 gluBuild2DMipmaps,我们可以使用任意的位图来创建纹理。OpenGL将自动将它缩放到正常的大小。

// 创建 MipMapped 纹理
glBindTexture(GL_TEXTURE_2D, texture[2]);
           glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
           glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);

下面生成mipmapped纹理。我们使用三种颜色(红,绿,蓝)来生成一个2D纹理。TextureImage[0]->sizeX 是位图宽度,extureImage[0]->sizeY是位图高度,GL_RGB意味着我们依次使用RGB色彩。GL_UNSIGNED_BYTE意味着纹理数据的单位是字节。TextureImage[0]->data指向我们创建纹理所用的位图。

gluBuild2DMipmaps(GL_TEXTURE_2D, 3,
TextureImage[0]->sizeX, TextureImage[0]->sizeY,
GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
 

现在开始设置光源。下面一行设置环境光的发光量,光源light1开始发光:

  glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);  // 设置环境光

设置漫射光的发光量:

glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);  // 设置漫射光

然后设置光源的位置:

glLightfv(GL_LIGHT1, GL_POSITION,LightPosition);  // 光源位置

最后,我们启用一号光源,没有启用GL_LIGHTING,所以您看不见任何光线(只对光源进行设置、定位、甚至启用,光源都不会工作。除非我们启用GL_LIGHTING)。

glEnable(GL_LIGHT1);                // 启用一号光源

课程中还学习了一个新的函数glNormal<chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="3" unitname="F">3f</chmetcnv>Normal就是法线的意思,所谓法线是指经过面(多边形)上的一点且垂直于这个面(多边形)的直线。使用光源的时候必须指定一条法线。法线告诉OpenGL这个多边形的朝向,并指明多边形的正面和背面。如果没有指定法线,什么怪事情都可能发生。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值