Coordinate Systems - LearnOpenGL

文章推薦指數: 80 %
投票人數:10人

We want to define a position for each object to position them inside a larger ... To transform vertex coordinates from view to clip-space we define a so ... Ifyou'rerunningAdBlock,pleaseconsiderwhitelistingthissiteifyou'dliketosupportLearnOpenGL;andnoworries,Iwon'tbemadifyoudon't:) IntroductionGettingstartedOpenGLCreatingawindowHelloWindowHelloTriangleShadersTexturesTransformationsCoordinateSystemsCameraReviewLightingColorsBasicLightingMaterialsLightingmapsLightcastersMultiplelightsReviewModelLoadingAssimpMeshModelAdvancedOpenGLDepthtestingStenciltestingBlendingFacecullingFramebuffersCubemapsAdvancedDataAdvancedGLSLGeometryShaderInstancingAntiAliasingAdvancedLightingAdvancedLightingGammaCorrectionShadowsShadowMappingPointShadowsNormalMappingParallaxMappingHDRBloomDeferredShadingSSAOPBRTheoryLightingIBLDiffuseirradianceSpecularIBLInPracticeDebuggingTextRendering2DGameBreakoutSettingupRenderingSpritesLevelsCollisionsBallCollisiondetectionCollisionresolutionParticlesPostprocessingPowerupsAudioRendertextFinalthoughtsGuestArticlesHowtopublish2020OITIntroductionWeightedBlendedSkeletalAnimation2021CSMSceneSceneGraphFrustumCullingTessellationHeightmapTessellationDSACoderepositoryTranslationsAbout BTC 1CLGKgmBSuYJ1nnvDGAepVTKNNDpUjfpRa ETH/ERC20 0x1de59bd9e52521a46309474f8372531533bd7c43 CoordinateSystems Getting-started/Coordinate-Systems Inthelastchapterwelearnedhowwecanusematricestoouradvantagebytransformingallverticeswithtransformationmatrices.OpenGLexpectsallthevertices,thatwewanttobecomevisible,tobeinnormalizeddevicecoordinatesaftereachvertexshaderrun.Thatis,thex,yandzcoordinatesofeachvertexshouldbebetween-1.0and1.0;coordinatesoutsidethisrangewillnotbevisible.Whatweusuallydo,isspecifythecoordinatesinarange(orspace)wedetermineourselvesandinthevertexshadertransformthesecoordinatestonormalizeddevicecoordinates(NDC).TheseNDCarethengiventotherasterizertotransformthemto2Dcoordinates/pixelsonyourscreen. TransformingcoordinatestoNDCisusuallyaccomplishedinastep-by-stepfashionwherewetransformanobject'sverticestoseveralcoordinatesystemsbeforefinallytransformingthemtoNDC.Theadvantageoftransformingthemtoseveralintermediatecoordinatesystemsisthatsomeoperations/calculationsareeasierincertaincoordinatesystemsaswillsoonbecomeapparent.Thereareatotalof5differentcoordinatesystemsthatareofimportancetous: Localspace(orObjectspace) Worldspace Viewspace(orEyespace) Clipspace Screenspace Thosearealladifferentstateatwhichourverticeswillbetransformedinbeforefinallyendingupasfragments. You'reprobablyquiteconfusedbynowbywhataspaceorcoordinatesystemactuallyissowe'llexplaintheminamorehigh-levelfashionfirstbyshowingthetotalpictureandwhateachspecificspacerepresents. Theglobalpicture Totransformthecoordinatesfromonespacetothenextcoordinatespacewe'lluseseveraltransformationmatricesofwhichthemostimportantarethemodel,viewandprojectionmatrix.Ourvertexcoordinatesfirststartinlocalspaceaslocalcoordinatesandarethenfurtherprocessedtoworldcoordinates,viewcoordinates,clipcoordinatesandeventuallyendupasscreencoordinates.Thefollowingimagedisplaystheprocessandshowswhateachtransformationdoes: Localcoordinatesarethecoordinatesofyourobjectrelativetoitslocalorigin;they'rethecoordinatesyourobjectbeginsin. Thenextstepistotransformthelocalcoordinatestoworld-spacecoordinateswhicharecoordinatesinrespectofalargerworld.Thesecoordinatesarerelativetosomeglobaloriginoftheworld,togetherwithmanyotherobjectsalsoplacedrelativetothisworld'sorigin. Nextwetransformtheworldcoordinatestoview-spacecoordinatesinsuchawaythateachcoordinateisasseenfromthecameraorviewer'spointofview. Afterthecoordinatesareinviewspacewewanttoprojectthemtoclipcoordinates.Clipcoordinatesareprocessedtothe-1.0and1.0rangeanddeterminewhichverticeswillenduponthescreen.Projectiontoclip-spacecoordinatescanaddperspectiveifusingperspectiveprojection. Andlastlywetransformtheclipcoordinatestoscreencoordinatesinaprocesswecallviewporttransformthattransformsthecoordinatesfrom-1.0and1.0tothecoordinaterangedefinedbyglViewport.Theresultingcoordinatesarethensenttotherasterizertoturnthemintofragments. Youprobablygotaslightideawhateachindividualspaceisusedfor.Thereasonwe'retransformingourverticesintoallthesedifferentspacesisthatsomeoperationsmakemoresenseorareeasiertouseincertaincoordinatesystems.Forexample,whenmodifyingyourobjectitmakesmostsensetodothisinlocalspace,whilecalculatingcertainoperationsontheobjectwithrespecttothepositionofotherobjectsmakesmostsenseinworldcoordinatesandsoon.Ifwewant,wecoulddefineonetransformationmatrixthatgoesfromlocalspacetoclipspaceallinonego,butthatleavesuswithlessflexibility. We'lldiscusseachcoordinatesysteminmoredetailbelow. Localspace Localspaceisthecoordinatespacethatislocaltoyourobject,i.e.whereyourobjectbeginsin.Imaginethatyou'vecreatedyourcubeinamodelingsoftwarepackage(likeBlender).Theoriginofyourcubeisprobablyat(0,0,0)eventhoughyourcubemayendupatadifferentlocationinyourfinalapplication.Probablyallthemodelsyou'vecreatedallhave(0,0,0)astheirinitialposition.Alltheverticesofyourmodelarethereforeinlocalspace:theyarealllocaltoyourobject. Theverticesofthecontainerwe'vebeenusingwerespecifiedascoordinatesbetween-0.5and0.5with0.0asitsorigin.Thesearelocalcoordinates. Worldspace Ifwewouldimportallourobjectsdirectlyintheapplicationtheywouldprobablyallbesomewherepositionedinsideeachotherattheworld'soriginof(0,0,0)whichisnotwhatwewant.Wewanttodefineapositionforeachobjecttopositiontheminsidealargerworld.Thecoordinatesinworldspaceareexactlywhattheysoundlike:thecoordinatesofallyourverticesrelativetoa(game)world.Thisisthecoordinatespacewhereyouwantyourobjectstransformedtoinsuchawaythatthey'reallscatteredaroundtheplace(preferablyinarealisticfashion).Thecoordinatesofyourobjectaretransformedfromlocaltoworldspace;thisisaccomplishedwiththemodelmatrix. Themodelmatrixisatransformationmatrixthattranslates,scalesand/orrotatesyourobjecttoplaceitintheworldatalocation/orientationtheybelongto.Thinkofitastransformingahousebyscalingitdown(itwasabittoolargeinlocalspace),translatingittoasuburbiatownandrotatingitabittotheleftonthey-axissothatitneatlyfitswiththeneighboringhouses.Youcouldthinkofthematrixinthepreviouschaptertopositionthecontaineralloverthesceneasasortofmodelmatrixaswell;wetransformedthelocalcoordinatesofthecontainertosomedifferentplaceinthescene/world. Viewspace TheviewspaceiswhatpeopleusuallyrefertoasthecameraofOpenGL(itissometimesalsoknownascameraspaceoreyespace).Theviewspaceistheresultoftransformingyourworld-spacecoordinatestocoordinatesthatareinfrontoftheuser'sview.Theviewspaceisthusthespaceasseenfromthecamera'spointofview.Thisisusuallyaccomplishedwithacombinationoftranslationsandrotationstotranslate/rotatethescenesothatcertainitemsaretransformedtothefrontofthecamera.Thesecombinedtransformationsaregenerallystoredinsideaviewmatrixthattransformsworldcoordinatestoviewspace.Inthenextchapterwe'llextensivelydiscusshowtocreatesuchaviewmatrixtosimulateacamera. Clipspace Attheendofeachvertexshaderrun,OpenGLexpectsthecoordinatestobewithinaspecificrangeandanycoordinatethatfallsoutsidethisrangeisclipped.Coordinatesthatareclippedarediscarded,sotheremainingcoordinateswillendupasfragmentsvisibleonyourscreen.Thisisalsowhereclipspacegetsitsnamefrom. Becausespecifyingallthevisiblecoordinatestobewithintherange-1.0and1.0isn'treallyintuitive,wespecifyourowncoordinatesettoworkinandconvertthosebacktoNDCasOpenGLexpectsthem. Totransformvertexcoordinatesfromviewtoclip-spacewedefineasocalledprojectionmatrixthatspecifiesarangeofcoordinatese.g.-1000and1000ineachdimension.Theprojectionmatrixthentransformscoordinateswithinthisspecifiedrangetonormalizeddevicecoordinates(-1.0,1.0).Allcoordinatesoutsidethisrangewillnotbemappedbetween-1.0and1.0andthereforebeclipped.Withthisrangewespecifiedintheprojectionmatrix,acoordinateof(1250,500,750)wouldnotbevisible,sincethexcoordinateisoutofrangeandthusgetsconvertedtoacoordinatehigherthan1.0inNDCandisthereforeclipped. Notethatifonlyapartofaprimitivee.g.atriangleisoutsidetheclippingvolumeOpenGLwillreconstructthetriangleasoneormoretrianglestofitinsidetheclippingrange. Thisviewingboxaprojectionmatrixcreatesiscalledafrustumandeachcoordinatethatendsupinsidethisfrustumwillendupontheuser'sscreen.ThetotalprocesstoconvertcoordinateswithinaspecifiedrangetoNDCthatcaneasilybemappedto2Dview-spacecoordinatesiscalledprojectionsincetheprojectionmatrixprojects3Dcoordinatestotheeasy-to-map-to-2Dnormalizeddevicecoordinates. Oncealltheverticesaretransformedtoclipspaceafinaloperationcalledperspectivedivisionisperformedwherewedividethex,yandzcomponentsofthepositionvectorsbythevector'shomogeneouswcomponent;perspectivedivisioniswhattransformsthe4Dclipspacecoordinatesto3Dnormalizeddevicecoordinates.Thisstepisperformedautomaticallyattheendofthevertexshaderstep. Itisafterthisstagewheretheresultingcoordinatesaremappedtoscreencoordinates(usingthesettingsofglViewport)andturnedintofragments. Theprojectionmatrixtotransformviewcoordinatestoclipcoordinatesusuallytakestwodifferentforms,whereeachformdefinesitsownuniquefrustum.Wecaneithercreateanorthographicprojectionmatrixoraperspectiveprojectionmatrix. Orthographicprojection Anorthographicprojectionmatrixdefinesacube-likefrustumboxthatdefinestheclippingspacewhereeachvertexoutsidethisboxisclipped.Whencreatinganorthographicprojectionmatrixwespecifythewidth,heightandlengthofthevisiblefrustum.AllthecoordinatesinsidethisfrustumwillendupwithintheNDCrangeaftertransformedbyitsmatrixandthuswon'tbeclipped.Thefrustumlooksabitlikeacontainer: Thefrustumdefinesthevisiblecoordinatesandisspecifiedbyawidth,aheightandanearandfarplane.Anycoordinateinfrontofthenearplaneisclippedandthesameappliestocoordinatesbehindthefarplane.Theorthographicfrustumdirectlymapsallcoordinatesinsidethefrustumtonormalizeddevicecoordinateswithoutanyspecialsideeffectssinceitwon'ttouchthewcomponentofthetransformedvector;ifthewcomponentremainsequalto1.0perspectivedivisionwon'tchangethecoordinates. TocreateanorthographicprojectionmatrixwemakeuseofGLM'sbuilt-infunctionglm::ortho: glm::ortho(0.0f,800.0f,0.0f,600.0f,0.1f,100.0f); Thefirsttwoparametersspecifytheleftandrightcoordinateofthefrustumandthethirdandfourthparameterspecifythebottomandtoppartofthefrustum.Withthose4pointswe'vedefinedthesizeofthenearandfarplanesandthe5thand6thparameterthendefinethedistancesbetweenthenearandfarplane.Thisspecificprojectionmatrixtransformsallcoordinatesbetweenthesex,yandzrangevaluestonormalizeddevicecoordinates. Anorthographicprojectionmatrixdirectlymapscoordinatestothe2Dplanethatisyourscreen,butinrealityadirectprojectionproducesunrealisticresultssincetheprojectiondoesn'ttakeperspectiveintoaccount.Thatissomethingtheperspectiveprojectionmatrixfixesforus. Perspectiveprojection Ifyoueverweretoenjoythegraphicsthereallifehastoofferyou'llnoticethatobjectsthatarefartherawayappearmuchsmaller.Thisweirdeffectissomethingwecallperspective.Perspectiveisespeciallynoticeablewhenlookingdowntheendofaninfinitemotorwayorrailwayasseeninthefollowingimage: Asyoucansee,duetoperspectivethelinesseemtocoincideatafarenoughdistance.Thisisexactlytheeffectperspectiveprojectiontriestomimicanditdoessousingaperspectiveprojectionmatrix.Theprojectionmatrixmapsagivenfrustumrangetoclipspace,butalsomanipulatesthewvalueofeachvertexcoordinateinsuchawaythatthefurtherawayavertexcoordinateisfromtheviewer,thehigherthiswcomponentbecomes.Oncethecoordinatesaretransformedtoclipspacetheyareintherange-wtow(anythingoutsidethisrangeisclipped).OpenGLrequiresthatthevisiblecoordinatesfallbetweentherange-1.0and1.0asthefinalvertexshaderoutput,thusoncethecoordinatesareinclipspace,perspectivedivisionisappliedtotheclipspacecoordinates: \[out=\begin{pmatrix}x/w\\y/w\\z/w\end{pmatrix}\] Eachcomponentofthevertexcoordinateisdividedbyitswcomponentgivingsmallervertexcoordinatesthefurtherawayavertexisfromtheviewer.Thisisanotherreasonwhythewcomponentisimportant,sinceithelpsuswithperspectiveprojection.Theresultingcoordinatesaretheninnormalizeddevicespace.Ifyou'reinterestedtofigureouthowtheorthographicandperspectiveprojectionmatricesareactuallycalculated(andaren'ttooscaredofthemathematics)IcanrecommendthisexcellentarticlebySongho. AperspectiveprojectionmatrixcanbecreatedinGLMasfollows: glm::mat4proj=glm::perspective(glm::radians(45.0f),(float)width/(float)height,0.1f,100.0f); Whatglm::perspectivedoesisagaincreatealargefrustumthatdefinesthevisiblespace,anythingoutsidethefrustumwillnotendupintheclipspacevolumeandwillthusbecomeclipped.Aperspectivefrustumcanbevisualizedasanon-uniformlyshapedboxfromwhereeachcoordinateinsidethisboxwillbemappedtoapointinclipspace.Animageofaperspectivefrustumisseenbelow: Itsfirstparameterdefinesthefovvalue,thatstandsforfieldofviewandsetshowlargetheviewspaceis.Forarealisticviewitisusuallysetto45degrees,butformoredoom-styleresultsyoucouldsetittoahighervalue.Thesecondparametersetstheaspectratiowhichiscalculatedbydividingtheviewport'swidthbyitsheight.Thethirdandfourthparametersetthenearandfarplaneofthefrustum.Weusuallysettheneardistanceto0.1andthefardistanceto100.0.Alltheverticesbetweenthenearandfarplaneandinsidethefrustumwillberendered. Wheneverthenearvalueofyourperspectivematrixissettoohigh(like10.0),OpenGLwillclipallcoordinatesclosetothecamera(between0.0and10.0),whichcangiveavisualresultyoumaybehaveseenbeforeinvideogameswhereyoucouldseethroughcertainobjectswhenmovinguncomfortablyclosetothem. Whenusingorthographicprojection,eachofthevertexcoordinatesaredirectlymappedtoclipspacewithoutanyfancyperspectivedivision(itstilldoesperspectivedivision,butthewcomponentisnotmanipulated(itstays1)andthushasnoeffect).Becausetheorthographicprojectiondoesn'tuseperspectiveprojection,objectsfartherawaydonotseemsmaller,whichproducesaweirdvisualoutput.Forthisreasontheorthographicprojectionismainlyusedfor2Drenderingsandforsomearchitecturalorengineeringapplicationswherewe'drathernothaveverticesdistortedbyperspective.ApplicationslikeBlenderthatareusedfor3Dmodelingsometimesuseorthographicprojectionformodeling,becauseitmoreaccuratelydepictseachobject'sdimensions.Belowyou'llseeacomparisonofbothprojectionmethodsinBlender: Youcanseethatwithperspectiveprojection,theverticesfartherawayappearmuchsmaller,whileinorthographicprojectioneachvertexhasthesamedistancetotheuser. Puttingitalltogether Wecreateatransformationmatrixforeachoftheaforementionedsteps:model,viewandprojectionmatrix.Avertexcoordinateisthentransformedtoclipcoordinatesasfollows: \[V_{clip}=M_{projection}\cdotM_{view}\cdotM_{model}\cdotV_{local}\] Notethattheorderofmatrixmultiplicationisreversed(rememberthatweneedtoreadmatrixmultiplicationfromrighttoleft).Theresultingvertexshouldthenbeassignedtogl_PositioninthevertexshaderandOpenGLwillthenautomaticallyperformperspectivedivisionandclipping. Andthen? Theoutputofthevertexshaderrequiresthecoordinatestobeinclip-spacewhichiswhatwejustdidwiththetransformationmatrices.OpenGLthenperformsperspectivedivisionontheclip-spacecoordinatestotransformthemtonormalized-devicecoordinates.OpenGLthenusestheparametersfromglViewPorttomapthenormalized-devicecoordinatestoscreencoordinateswhereeachcoordinatecorrespondstoapointonyourscreen(inourcasea800x600screen).Thisprocessiscalledtheviewporttransform. Thisisadifficulttopictounderstandsoifyou'restillnotexactlysureaboutwhateachspaceisusedforyoudon'thavetoworry.Belowyou'llseehowwecanactuallyputthesecoordinatespacestogooduseandenoughexampleswillfollowintheupcomingchapters. Going3D Nowthatweknowhowtotransform3Dcoordinatesto2Dcoordinateswecanstartrenderingreal3Dobjectsinsteadofthelame2Dplanewe'vebeenshowingsofar. Tostartdrawingin3Dwe'llfirstcreateamodelmatrix.Themodelmatrixconsistsoftranslations,scalingand/orrotationswe'dliketoapplytotransformallobject'sverticestotheglobalworldspace.Let'stransformourplaneabitbyrotatingitonthex-axissoitlookslikeit'slayingonthefloor.Themodelmatrixthenlookslikethis: glm::mat4model=glm::mat4(1.0f); model=glm::rotate(model,glm::radians(-55.0f),glm::vec3(1.0f,0.0f,0.0f)); Bymultiplyingthevertexcoordinateswiththismodelmatrixwe'retransformingthevertexcoordinatestoworldcoordinates.Ourplanethatisslightlyonthefloorthusrepresentstheplaneintheglobalworld. Nextweneedtocreateaviewmatrix.Wewanttomoveslightlybackwardsinthescenesotheobjectbecomesvisible(wheninworldspacewe'relocatedattheorigin(0,0,0)).Tomovearoundthescene,thinkaboutthefollowing: Tomoveacamerabackwards,isthesameasmovingtheentiresceneforward. Thatisexactlywhataviewmatrixdoes,wemovetheentirescenearoundinversedtowherewewantthecameratomove. BecausewewanttomovebackwardsandsinceOpenGLisaright-handedsystemwehavetomoveinthepositivez-axis.Wedothisbytranslatingthescenetowardsthenegativez-axis.Thisgivestheimpressionthatwearemovingbackwards. Right-handedsystem Byconvention,OpenGLisaright-handedsystem.Whatthisbasicallysaysisthatthepositivex-axisistoyourright,thepositivey-axisisupandthepositivez-axisisbackwards.Thinkofyourscreenbeingthecenterofthe3axesandthepositivez-axisgoingthroughyourscreentowardsyou.Theaxesaredrawnasfollows: Tounderstandwhyit'scalledright-handeddothefollowing: Stretchyourright-armalongthepositivey-axiswithyourhanduptop. Letyourthumbpointtotheright. Letyourpointingfingerpointup. Nowbendyourmiddlefingerdownwards90degrees. Ifyoudidthingsright,yourthumbshouldpointtowardsthepositivex-axis,thepointingfingertowardsthepositivey-axisandyourmiddlefingertowardsthepositivez-axis.Ifyouweretodothiswithyourleft-armyouwouldseethez-axisisreversed.Thisisknownasaleft-handedsystemandiscommonlyusedbyDirectX.NotethatinnormalizeddevicecoordinatesOpenGLactuallyusesaleft-handedsystem(theprojectionmatrixswitchesthehandedness). We'lldiscusshowtomovearoundthesceneinmoredetailinthenextchapter.Fornowtheviewmatrixlookslikethis: glm::mat4view=glm::mat4(1.0f); //notethatwe'retranslatingthesceneinthereversedirectionofwherewewanttomove view=glm::translate(view,glm::vec3(0.0f,0.0f,-3.0f)); Thelastthingweneedtodefineistheprojectionmatrix.Wewanttouseperspectiveprojectionforourscenesowe'lldeclaretheprojectionmatrixlikethis: glm::mat4projection; projection=glm::perspective(glm::radians(45.0f),800.0f/600.0f,0.1f,100.0f); Nowthatwecreatedthetransformationmatricesweshouldpassthemtoourshaders.Firstlet'sdeclarethetransformationmatricesasuniformsinthevertexshaderandmultiplythemwiththevertexcoordinates: #version330core layout(location=0)invec3aPos; ... uniformmat4model; uniformmat4view; uniformmat4projection; voidmain() { //notethatwereadthemultiplicationfromrighttoleft gl_Position=projection*view*model*vec4(aPos,1.0); ... } Weshouldalsosendthematricestotheshader(thisisusuallydoneeachframesincetransformationmatricestendtochangealot): intmodelLoc=glGetUniformLocation(ourShader.ID,"model"); glUniformMatrix4fv(modelLoc,1,GL_FALSE,glm::value_ptr(model)); ...//sameforViewMatrixandProjectionMatrix Nowthatourvertexcoordinatesaretransformedviathemodel,viewandprojectionmatrixthefinalobjectshouldbe: Tiltedbackwardstothefloor. Abitfartherawayfromus. Bedisplayedwithperspective(itshouldgetsmaller,thefurtheritsverticesare). Let'scheckiftheresultactuallydoesfulfilltheserequirements: Itdoesindeedlookliketheplaneisa3Dplanethat'srestingatsomeimaginaryfloor.Ifyou'renotgettingthesameresult,compareyourcodewiththecompletesourcecode. More3D Sofarwe'vebeenworkingwitha2Dplane,evenin3Dspace,solet'staketheadventurousrouteandextendour2Dplanetoa3Dcube.Torenderacubeweneedatotalof36vertices(6faces*2triangles*3verticeseach).36verticesarealottosumupsoyoucanretrievethemfromhere. Forfun,we'llletthecuberotateovertime: model=glm::rotate(model,(float)glfwGetTime()*glm::radians(50.0f),glm::vec3(0.5f,1.0f,0.0f)); Andthenwe'lldrawthecubeusingglDrawArrays(aswedidn'tspecifyindices),butthistimewithacountof36vertices. glDrawArrays(GL_TRIANGLES,0,36); Youshouldgetsomethingsimilartothefollowing: Itdoesresembleacubeslightlybutsomething'soff.Somesidesofthecubesarebeingdrawnoverothersidesofthecube.ThishappensbecausewhenOpenGLdrawsyourcubetriangle-by-triangle,fragmentbyfragment,itwilloverwriteanypixelcolorthatmayhavealreadybeendrawntherebefore.SinceOpenGLgivesnoguaranteeontheorderoftrianglesrendered(withinthesamedrawcall),sometrianglesaredrawnontopofeachothereventhoughoneshouldclearlybeinfrontoftheother. Luckily,OpenGLstoresdepthinformationinabuffercalledthez-bufferthatallowsOpenGLtodecidewhentodrawoverapixelandwhennotto.Usingthez-bufferwecanconfigureOpenGLtododepth-testing. Z-buffer OpenGLstoresallitsdepthinformationinaz-buffer,alsoknownasadepthbuffer.GLFWautomaticallycreatessuchabufferforyou(justlikeithasacolor-bufferthatstoresthecolorsoftheoutputimage).Thedepthisstoredwithineachfragment(asthefragment'szvalue)andwheneverthefragmentwantstooutputitscolor,OpenGLcomparesitsdepthvalueswiththez-buffer.Ifthecurrentfragmentisbehindtheotherfragmentitisdiscarded,otherwiseoverwritten.ThisprocessiscalleddepthtestingandisdoneautomaticallybyOpenGL. However,ifwewanttomakesureOpenGLactuallyperformsthedepthtestingwefirstneedtotellOpenGLwewanttoenabledepthtesting;itisdisabledbydefault.WecanenabledepthtestingusingglEnable.TheglEnableandglDisablefunctionsallowustoenable/disablecertainfunctionalityinOpenGL.Thatfunctionalityisthenenabled/disableduntilanothercallismadetodisable/enableit.RightnowwewanttoenabledepthtestingbyenablingGL_DEPTH_TEST: glEnable(GL_DEPTH_TEST); Sincewe'reusingadepthbufferwealsowanttoclearthedepthbufferbeforeeachrenderiteration(otherwisethedepthinformationofthepreviousframestaysinthebuffer).Justlikeclearingthecolorbuffer,wecanclearthedepthbufferbyspecifyingtheDEPTH_BUFFER_BITbitintheglClearfunction: glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); Let'sre-runourprogramandseeifOpenGLnowperformsdepthtesting: Therewego!Afullytexturedcubewithproperdepthtestingthatrotatesovertime.Checkthesourcecodehere. Morecubes! Saywewantedtodisplay10ofourcubesonscreen.Eachcubewilllookthesamebutwillonlydifferinwhereit'slocatedintheworldwitheachadifferentrotation.Thegraphicallayoutofthecubeisalreadydefinedsowedon'thavetochangeourbuffersorattributearrayswhenrenderingmoreobjects.Theonlythingwehavetochangeforeachobjectisitsmodelmatrixwherewetransformthecubesintotheworld. First,let'sdefineatranslationvectorforeachcubethatspecifiesitspositioninworldspace.We'lldefine10cubepositionsinaglm::vec3array: glm::vec3cubePositions[]={ glm::vec3(0.0f,0.0f,0.0f), glm::vec3(2.0f,5.0f,-15.0f), glm::vec3(-1.5f,-2.2f,-2.5f), glm::vec3(-3.8f,-2.0f,-12.3f), glm::vec3(2.4f,-0.4f,-3.5f), glm::vec3(-1.7f,3.0f,-7.5f), glm::vec3(1.3f,-2.0f,-2.5f), glm::vec3(1.5f,2.0f,-2.5f), glm::vec3(1.5f,0.2f,-1.5f), glm::vec3(-1.3f,1.0f,-1.5f) }; Now,withintherenderloopwewanttocallglDrawArrays10times,butthistimesendadifferentmodelmatrixtothevertexshadereachtimebeforewesendoutthedrawcall.Wewillcreateasmallloopwithintherenderloopthatrendersourobject10timeswithadifferentmodelmatrixeachtime.Notethatwealsoaddasmalluniquerotationtoeachcontainer. glBindVertexArray(VAO); for(unsignedinti=0;i<10;i++) { glm::mat4model=glm::mat4(1.0f); model=glm::translate(model,cubePositions[i]); floatangle=20.0f*i; model=glm::rotate(model,glm::radians(angle),glm::vec3(1.0f,0.3f,0.5f)); ourShader.setMat4("model",model); glDrawArrays(GL_TRIANGLES,0,36); } Thissnippetofcodewillupdatethemodelmatrixeachtimeanewcubeisdrawnanddothis10timesintotal.Rightnowweshouldbelookingintoaworldfilledwith10oddlyrotatedcubes: Perfect!Itlookslikeourcontainerfoundsomelike-mindedfriends.Ifyou'restuckseeifyoucancompareyourcodewiththesourcecode. Exercises TryexperimentingwiththeFoVandaspect-ratioparametersofGLM'sprojectionfunction.Seeifyoucanfigureouthowthoseaffecttheperspectivefrustum. Playwiththeviewmatrixbytranslatinginseveraldirectionsandseehowthescenechanges.Thinkoftheviewmatrixasacameraobject. Trytomakeevery3rdcontainer(includingthe1st)rotateovertime,whileleavingtheothercontainersstaticusingjustthemodelmatrix:solution. HI



請為這篇文章評分?