Writing to the OpenGL Stencil Buffer - Stack Overflow
文章推薦指數: 80 %
The stencil buffer is theoretically a buffer like the back buffer and the depth buffer. The three of them are written to at the same time (when ...
2022DeveloperSurveyisopen!Takesurvey.
Home
Public
Questions
Tags
Users
Companies
Collectives
ExploreCollectives
Teams
StackOverflowforTeams
–Startcollaboratingandsharingorganizationalknowledge.
CreateafreeTeam
WhyTeams?
Teams
CreatefreeTeam
Collectives™onStackOverflow
Findcentralized,trustedcontentandcollaboratearoundthetechnologiesyouusemost.
Learnmore
Teams
Q&Aforwork
Connectandshareknowledgewithinasinglelocationthatisstructuredandeasytosearch.
Learnmore
WritingtotheOpenGLStencilBuffer
AskQuestion
Asked
4years,4monthsago
Modified
1year,1monthago
Viewed
6ktimes
7
1
I'vebeenreadingaboutthestencilbufferinOpenGL.Thebasicconceptmakessense;afragmentisonlydrawnifitmeetsacertainconditionafterbeingbitwiseANDedwithavalueinthestencilbuffer.ButonethingIdon'tunderstandishowyouactuallywritetothestencilbuffer.IsthereafunctionthatI'mmissinghere?
P.S.WhenIsaywrite,Imeanspecifythespecificvaluesinthestencilbuffer.
c++openglglfwstencil-buffer
Share
Follow
askedJan14,2018at2:54
papermanpaperman
45644silverbadges1717bronzebadges
7
Readthis:learnopengl.com/#!Advanced-OpenGL/Stencil-testing
– FrancisCugler
Jan14,2018at3:09
WritingtostencilbufferisdonebythesamefunctionswhichwritetoRGBand/ordepth.ThisishowIexplainedafriend:stenciltesttestissomehowlikedepthtest.Youcandisableitatall.Youcanwriteonly(withouttesting).Youcanenabletesting(andoverwriteincase).
– Scheff'sCat
Jan14,2018at7:30
@ScheffhowwouldIwritetothestencilbufferwithoutdrawinganythinginthecolorbuffer?
– paperman
Jan14,2018at13:10
@Scheffnevermind,IthinkIgotit
– paperman
Jan14,2018at13:12
I'mnotsurewhetheryoucanwritetostencilbufferonly.Ijusthadalookintocodewhereweusedstencilforvertical/horicontalinterlacedstereorendering.(Thestencilbufferisinitiallywrittenwithaline/nolinepatterntorestricttherenderingtotheappropriateevenoroddrows/columns.)IbelieveitjustrendersRGBaswellbutyouwon'tseeit.Itisoverriddenbythefollowingrenderingwhichpassesthestenciltest(andbeforethefinalglSwap()iscalled).
– Scheff'sCat
Jan14,2018at15:39
|
Show2morecomments
3Answers
3
Sortedby:
Resettodefault
Highestscore(default)
Datemodified(newestfirst)
Datecreated(oldestfirst)
9
Nobodyansweredthisquestionandit'savalidquestion,somorethanayearlater,here'sananswertoyourquestion.
Thestencilbufferistheoreticallyabufferlikethebackbufferandthedepthbuffer.Thethreeofthemarewrittentoatthesametime(whenenabled).Youcanenable/disablewritingtothemwithspecificcalls:
glColorMask(red,green,blue,alpha)-forthebackbuffer
glDepthMask(t/f)-forthedepthbuffer
glStencilMask(value)-forthestencilbuffer
Forthedepthandstencilbuffer,youcanspecificallyenable/disablefurtherwith:
glEnable/glDisable(GL_DEPTH_TEST)
glEnable/glDisable(GL_STENCIL_TEST)
Anytriangleyourendertothescreenwillwritetoallenabledbuffersunlesssomeoperationfunctionalitypreventsit.Forthestencilbuffer,thesecanbesetwithseveralfunctions.PleaselookupthefunctionalitiesontheOpenGLreferencepages,buthereisasimpleexampleofmaskingapartofthescreenandthenrenderingonlyonthatmaskedpartofthescreen,justtogetyoustarted.
glClearColor(0,0,0,1);
glClearStencil(0);
glStencilMask(0xFF);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE);//Donotdrawanypixelsonthebackbuffer
glEnable(GL_STENCIL_TEST);//EnablestestingANDwritingfunctionalities
glStencilFunc(GL_ALWAYS,1,0xFF);//Donottestthecurrentvalueinthestencilbuffer,alwaysacceptanyvalueontherefordrawing
glStencilMask(0xFF);
glStencilOp(GL_REPLACE,GL_REPLACE,GL_REPLACE);//Makeeverytestsucceed
//...hereyourenderthepartofthesceneyouwantmasked,thismaybeasimpletriangleorsquare,orforexampleamonitoronacomputerinyourspaceship...
glStencilOp(GL_KEEP,GL_KEEP,GL_KEEP);//Makesureyouwillnolonger(over)writestencilvalues,evenifanytestsucceeds
glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE);//Makesurewedrawonthebackbufferagain.
glStencilFunc(GL_EQUAL,1,0xFF);//Nowwewillonlydrawpixelswherethecorrespondingstencilbuffervalueequals1
//...hereyourenderyourimageonthecomputerscreen(orwhatever)thatshouldbelimitedbythepreviousgeometry...
glDisable(GL_STENCIL_TEST);
NotethatIomittedanydepthcodeonpurposetomakesureyouseethatithasnothingtodowithstencilling.Ifyourender3Dgeometry,youmightneedtoenableit.YoumayevenneedtoNOTwriteastencilvalueifadepth-testfails.
Notethatitisimportantthatwhenyourenderthemaskinggeometry,yousetthestencilfunctoGL_ALWAYS,becauseotherwise,thecurrentvalueinthestencilbuffer(whichwasclearedintheexample)istestedagainstwhateverwaslastusedandyourmaskinggeometrymaynotevenbedrawnatall.
Sotherearenospecialfunctionstowritetothestencilbuffer.I'mnotevensureifitcanbewrittentolikeyoucanwritedatadirectlyintothebackbufferandthedepthbuffervideomemory,butthat'snotthewayitshouldbedoneanyway(becauseit'sterriblyslow).Thestencilbufferismemorysharedwiththedepthbuffer,soitmightbepossiblebychangingtheparametersofthewritefunctions.Iwouldn'tcountonitworkingonallvideodriversthough.
Goodlucktoanyonewhoneededthisinformation!
Share
Follow
editedApr9,2021at7:04
answeredSep15,2019at14:52
scippiescippie
1,88411goldbadge2424silverbadges3838bronzebadges
6
wowit'sbeenoverayearandhalfsinceIaskedthisquestion!IwasabletounderstanditeventuallybutIappreciatethatyoustillwroteananswerforanyoneelsewhocomesacrossit:)
– paperman
Sep16,2019at4:01
Thanksforacceptingit:-).Iknowfromexperiencethatyouarenottheonlyonewhostruggledwiththis,andthat'swhyIsharetheanswer.
– scippie
Sep16,2019at6:49
Youmentionthatyoucanwritetothestencilbufferaswithanormalbuffer,butI'mnotseeinghowyoucanbindthestencilbuffersothatglBufferDatawillwritetoit.glBindBufferwantsa"name"(Idon'tknowwhyonearththeycallanumberaname)createdbyglGenBuffers,whichdoesn'tseemapplicabletothestencilbuffer.
– TrevorGiddings
Apr6,2021at5:09
No,itdoesn'tworklikethat@TrevorGiddings,youmustlookatthestencilbufferasanextensiontothecurrentlyselectedrendertarget(whichcansimplybethebackbuffer),whateverhappensonthattarget,willhappenonthestencilbufferifenabledlikeI'veshowninmypost.Ifyouneedtodothiswithoutactuallychangingthatrendertarget,youdisablethecolorwrites(likeintheabovepost).Youcan'tsetthestencilbufferasarendertarget,that'snotpossible.Youshouldlookatitasifitisacarboncoatedpaperyouconnecttotherendertarget.
– scippie
Apr7,2021at7:18
@scippieifyoucanonlywritetoitbyrenderingtoit,thenIdon'tunderstand"wellnodifferentthanonanyotherbuffersthatis",andIdon'tseehow"Youcouldofcoursereallysendpixeldatatothegraphicalmemory"--unlessyoucountsendingatexturethatwilllaterbyusedwhenrenderingafull-screenquad.
– TrevorGiddings
Apr8,2021at4:12
|
Show1morecomment
0
Youcanread,writeandcopyvalues(bytes,floats,dwords...)totheframeanddepthbufferbutnottothestencilbuffer.
AllthreebuffersarelocateattheGPUmemorytheproblemarethestencilbufferusedtheremaining8bitsfromthe24bitdepthbuffer!
Thisiswhyyoumustrendersomethingtosetoroverwritevaluesinthe8bitstencilbuffer(inrealaregioninthedepthbuffer)
DJ
Share
Follow
answeredApr4,2021at11:35
DJLinuxDJLinux
1
Addacomment
|
-3
IdescribedhowtorendertoastencilbufferhereusinglibGDX.TheprocessforapplyingamaskinOpenGListhesameregardlessofOpenGLversionorplatform.
HowmaskingworksinOpenGL
TherearemanywaystocreateamaskinOpenGL,notethatthecodetocreatethemaskinmypreviousansweractuallyusesthedepthbuffer.Icouldhaveusedthestencilbufferinasimilarwaytoachievethesameresult.
Usingthedepthbuffer,youcanapplymasksinthefollowingway:
Initialiseandconfiguredepthtesting
Startbyclearingthedepthbufferanddisablerenderingtothecolorbuffer:
glClearDepthf(1.0f);
glClear(GL_DEPTH_BUFFER_BIT);
glColorMask(false,false,false,false);
Next,specifythecriteriaforthebuffer,thistellsOpenGLhowtorendertothedepthbuffertocreatethemask.YoudothisbymakingacalltoglDepthFunc(shouldthemaskedareabetheareaofthescenewheretheshapeisdrawnorshouldsomethingelse?forthedifferentkindsofinputtothedepthfunction,seetheDepthtestsectionofthissite)
glDepthFunc(GL_LESS);
glEnable(GL_DEPTH_TEST);
glDepthMask(true);
//Yourcodetorenderthemaskgoeshere
Creatingthemask
Afterenablingthebuffer,yourenderpolygonsintheshapethatyouwantforthemask.Becausewedisabledwritingtothecolorbuffer,therenderedimagewillnotbevisibleonscreen,itisrenderedtothedepthbuffer.Thedepthbufferhasthesamewidthandheightdimensionsasthecolorbufferbutconsistsof0and1values.Eachpixelhasthedepthtestappliedtoit,ifitpassesthenavalueof1isplacedinthebufferforthatlocation,otherwisethecorrespondinglocationhasavalueof0.
Enablecolorbuffer,setdepthfunctionandrendertothescene
NowyouconfigureOpenGLtorendertothecolorbufferandapplythedepthmasklikeso:
glColorMask(true,true,true,true);
glDepthMask(true);
glDepthFunc(GL_EQUAL);
//Yourcodetorenderthescenegoeshere
Sinceyouhavethedepthbufferenabled,everypixelintheviewportwillhaveacorresponding0or1value.Nowanotherdepthfunctionisappliedtothecorrespondingvalueforeachpixelandiftheresultistrue,thepixelisrenderedtothescreen.Herethechoiceofdepthfunctiondetermineshowthemaskisapplied.
Disabledepthtesting
Toallownormalrenderingtothesceneagain,youdisablethedepthbufferlikeso:
glDisable(GL_DEPTH_TEST);
Share
Follow
editedJan15,2018at13:20
answeredJan15,2018at12:02
sparkplugsparkplug
1,45944goldbadges1818silverbadges2121bronzebadges
2
3
Title:WritingtotheOpenGLStencilBuffer,answer:WritingtotheOpenGLDepthBuffer.Ilearnedhowtowritetodepthbufferbutthat'snotwhatIexpectedwhenclickingonquestiononsuchtitleandIstillhaven'tsolvedmyproblem.
– PurpleIce
Oct27,2018at17:10
Thisisprettyancient,butONEofthebestdiscussiononstencil/depth.Unfortunately.perlast"answer"itisstillmissingrelationsbetweenstencilanddepthbuffers-theyareNOTsame!Accordingthemanydoc-stenciliispecialcaseofdepthandthetestmustfirstpassdept-ifitisenabled,thenitwillpassstencil;
– JanHus
Mar23,2020at18:56
Addacomment
|
YourAnswer
ThanksforcontributingananswertoStackOverflow!Pleasebesuretoanswerthequestion.Providedetailsandshareyourresearch!Butavoid…Askingforhelp,clarification,orrespondingtootheranswers.Makingstatementsbasedonopinion;backthemupwithreferencesorpersonalexperience.Tolearnmore,seeourtipsonwritinggreatanswers.
Draftsaved
Draftdiscarded
Signuporlogin
SignupusingGoogle
SignupusingFacebook
SignupusingEmailandPassword
Submit
Postasaguest
Name
Email
Required,butnevershown
PostYourAnswer
Discard
Byclicking“PostYourAnswer”,youagreetoourtermsofservice,privacypolicyandcookiepolicy
Nottheansweryou'relookingfor?Browseotherquestionstaggedc++openglglfwstencil-bufferoraskyourownquestion.
TheOverflowBlog
Makeyouropen-sourceprojectpublicbeforeyou’reready(Ep.444)
Thescienceofinterviewingdevelopers
FeaturedonMeta
AnnouncingthearrivalofValuedAssociate#1214:Dalmarus
Improvementstositestatusandincidentcommunication
RetiringOurCommunity-SpecificClosureReasonsforServerFaultandSuperUser
Temporarilypausingthesitesatisfactionsurvey
StagingGround:ReviewerMotivation,Scaling,andOpenQuestions
Linked
3
LibgdxStencil&ShapeRenderer
Related
2844
Whatisthedifferencebetween#include
延伸文章資訊
- 1Stencil Test - OpenGL Wiki
The stencil buffer is an image that uses a stencil image format. The Default Framebuffer may have...
- 2Stencil buffer - Wikipedia
OpenGL
- 3OpenGL基礎之Stencil Testing - 台部落
stencil testing發生在fragment shader之後,depth testing之前,它利用stencil-buffer來捨棄一些片元,餘下的會進入depth testing進...
- 4Writing to the OpenGL Stencil Buffer - Stack Overflow
The stencil buffer is theoretically a buffer like the back buffer and the depth buffer. The three...
- 5模板测试
Bitwise inverts the current stencil buffer value. glStencilOp 函数默认设置为(GL_KEEP, GL_KEEP, GL_KEEP) ...