glGraphicsStateGuardian_src.cxx 475 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927
  1. /**
  2. * PANDA 3D SOFTWARE
  3. * Copyright (c) Carnegie Mellon University. All rights reserved.
  4. *
  5. * All use of this software is subject to the terms of the revised BSD
  6. * license. You should have received a copy of this license along
  7. * with this source code in a file named "LICENSE."
  8. *
  9. * @file glGraphicsStateGuardian_src.cxx
  10. * @author drose
  11. * @date 1999-02-02
  12. * @author fperazzi, PandaSE
  13. * @date 2010-05-05
  14. * get_supports_cg_profile)
  15. */
  16. #include "config_putil.h"
  17. #include "displayRegion.h"
  18. #include "renderBuffer.h"
  19. #include "geom.h"
  20. #include "geomVertexData.h"
  21. #include "geomTriangles.h"
  22. #include "geomTristrips.h"
  23. #include "geomTrifans.h"
  24. #include "geomLines.h"
  25. #include "geomLinestrips.h"
  26. #include "geomPoints.h"
  27. #include "geomVertexReader.h"
  28. #include "graphicsWindow.h"
  29. #include "lens.h"
  30. #include "perspectiveLens.h"
  31. #include "directionalLight.h"
  32. #include "pointLight.h"
  33. #include "spotlight.h"
  34. #include "planeNode.h"
  35. #include "fog.h"
  36. #include "clockObject.h"
  37. #include "string_utils.h"
  38. #include "nodePath.h"
  39. #include "dcast.h"
  40. #include "pvector.h"
  41. #include "vector_string.h"
  42. #include "string_utils.h"
  43. #include "pnmImage.h"
  44. #include "config_gobj.h"
  45. #include "lightMutexHolder.h"
  46. #include "indirectLess.h"
  47. #include "pStatTimer.h"
  48. #include "load_prc_file.h"
  49. #include "bamCache.h"
  50. #include "bamCacheRecord.h"
  51. #include "alphaTestAttrib.h"
  52. #include "clipPlaneAttrib.h"
  53. #include "cullFaceAttrib.h"
  54. #include "depthOffsetAttrib.h"
  55. #include "depthWriteAttrib.h"
  56. #include "fogAttrib.h"
  57. #include "lightAttrib.h"
  58. #include "logicOpAttrib.h"
  59. #include "materialAttrib.h"
  60. #include "rescaleNormalAttrib.h"
  61. #include "scissorAttrib.h"
  62. #include "shadeModelAttrib.h"
  63. #include "stencilAttrib.h"
  64. #include "graphicsEngine.h"
  65. #include "shaderGenerator.h"
  66. #include "samplerState.h"
  67. #include "displayInformation.h"
  68. #if defined(HAVE_CG) && !defined(OPENGLES)
  69. #include <Cg/cgGL.h>
  70. #endif
  71. #include <algorithm>
  72. using std::dec;
  73. using std::endl;
  74. using std::hex;
  75. using std::max;
  76. using std::min;
  77. using std::string;
  78. TypeHandle CLP(GraphicsStateGuardian)::_type_handle;
  79. PStatCollector CLP(GraphicsStateGuardian)::_load_display_list_pcollector("Draw:Transfer data:Display lists");
  80. PStatCollector CLP(GraphicsStateGuardian)::_primitive_batches_display_list_pcollector("Primitive batches:Display lists");
  81. PStatCollector CLP(GraphicsStateGuardian)::_vertices_display_list_pcollector("Vertices:Display lists");
  82. PStatCollector CLP(GraphicsStateGuardian)::_vertices_immediate_pcollector("Vertices:Immediate mode");
  83. PStatCollector CLP(GraphicsStateGuardian)::_memory_barrier_pcollector("Draw:Memory barriers");
  84. PStatCollector CLP(GraphicsStateGuardian)::_vertex_array_update_pcollector("Draw:Update arrays");
  85. PStatCollector CLP(GraphicsStateGuardian)::_texture_update_pcollector("Draw:Update texture");
  86. PStatCollector CLP(GraphicsStateGuardian)::_fbo_bind_pcollector("Draw:Bind FBO");
  87. PStatCollector CLP(GraphicsStateGuardian)::_check_error_pcollector("Draw:Check errors");
  88. PStatCollector CLP(GraphicsStateGuardian)::_check_residency_pcollector("*:PStats:Check residency");
  89. // The following noop functions are assigned to the corresponding glext
  90. // function pointers in the class, in case the functions are not defined by
  91. // the GL, just so it will always be safe to call the extension functions.
  92. static void APIENTRY
  93. null_glPointParameterfv(GLenum, const GLfloat *) {
  94. }
  95. #ifdef OPENGLES_1
  96. // OpenGL ES 1 doesn't support this, period. Might as well macro it.
  97. #define _glDrawRangeElements(mode, start, end, count, type, indices) \
  98. glDrawElements(mode, count, type, indices)
  99. #else
  100. static void APIENTRY
  101. null_glDrawRangeElements(GLenum mode, GLuint start, GLuint end,
  102. GLsizei count, GLenum type, const GLvoid *indices) {
  103. // If we don't support glDrawRangeElements(), just use the original
  104. // glDrawElements() instead.
  105. glDrawElements(mode, count, type, indices);
  106. }
  107. #endif
  108. #if defined(OPENGLES) && !defined(OPENGLES_1)
  109. static void APIENTRY
  110. null_glVertexAttrib4dv(GLuint index, const GLdouble *v) {
  111. GLfloat vf[4] = {(GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3]};
  112. glVertexAttrib4fv(index, vf);
  113. }
  114. #endif
  115. static void APIENTRY
  116. null_glActiveTexture(GLenum gl_texture_stage) {
  117. // If we don't support multitexture, we'd better not try to request a
  118. // texture beyond the first texture stage.
  119. nassertv(gl_texture_stage == GL_TEXTURE0);
  120. }
  121. #ifdef OPENGLES_2
  122. #define _glBlendEquation glBlendEquation
  123. #define _glBlendEquationSeparate glBlendEquationSeparate
  124. #define _glBlendFuncSeparate glBlendFuncSeparate
  125. #define _glBlendColor glBlendColor
  126. #else
  127. static void APIENTRY
  128. null_glBlendEquation(GLenum) {
  129. }
  130. static void APIENTRY
  131. null_glBlendFuncSeparate(GLenum src, GLenum dest, GLenum, GLenum) {
  132. glBlendFunc(src, dest);
  133. }
  134. static void APIENTRY
  135. null_glBlendColor(GLclampf, GLclampf, GLclampf, GLclampf) {
  136. }
  137. #endif
  138. #ifndef OPENGLES_1
  139. // We have a default shader that will be applied when there isn't any shader
  140. // applied (e.g. if it failed to compile). We need this because OpenGL ES
  141. // 2.x and OpenGL 3.2+ core don't have a fixed-function pipeline. This
  142. // default shader just applies a single texture, which is good enough for
  143. // drawing GUIs and such.
  144. static const string default_vshader =
  145. #ifndef OPENGLES
  146. #ifdef __APPLE__ // Apple's GL 3.2 contexts require at least GLSL 1.50.
  147. "#version 150\n"
  148. #else
  149. "#version 130\n"
  150. #endif
  151. "in vec4 p3d_Vertex;\n"
  152. "in vec4 p3d_Color;\n"
  153. "in vec2 p3d_MultiTexCoord0;\n"
  154. "out vec2 texcoord;\n"
  155. "out vec4 color;\n"
  156. #else
  157. "#version 100\n"
  158. "precision mediump float;\n"
  159. "attribute vec4 p3d_Vertex;\n"
  160. "attribute vec4 p3d_Color;\n"
  161. "attribute vec2 p3d_MultiTexCoord0;\n"
  162. "varying vec2 texcoord;\n"
  163. "varying lowp vec4 color;\n"
  164. #endif
  165. "uniform mat4 p3d_ModelViewProjectionMatrix;\n"
  166. "uniform vec4 p3d_ColorScale;\n"
  167. "void main(void) {\n"
  168. " gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;\n"
  169. " texcoord = p3d_MultiTexCoord0;\n"
  170. " color = p3d_Color * p3d_ColorScale;\n"
  171. "}\n";
  172. #ifndef OPENGLES
  173. // This version of the shader is used if vertices-float64 is enabled.
  174. static const string default_vshader_fp64 =
  175. #ifdef __APPLE__
  176. "#version 150\n"
  177. #else
  178. "#version 130\n"
  179. #endif
  180. "#extension GL_ARB_vertex_attrib_64bit : require\n"
  181. "#extension GL_ARB_gpu_shader_fp64 : require\n"
  182. "in dvec3 p3d_Vertex;\n"
  183. "in vec4 p3d_Color;\n"
  184. "in dvec2 p3d_MultiTexCoord0;\n"
  185. "out vec2 texcoord;\n"
  186. "out vec4 color;\n"
  187. "uniform mat4 p3d_ModelViewMatrix;\n"
  188. "uniform mat4 p3d_ProjectionMatrix;\n"
  189. "uniform vec4 p3d_ColorScale;\n"
  190. "void main(void) {\n" // Apply proj & modelview in two steps, more precise
  191. " gl_Position = vec4(dmat4(p3d_ProjectionMatrix) * (dmat4(p3d_ModelViewMatrix) * dvec4(p3d_Vertex, 1)));\n"
  192. " texcoord = vec2(p3d_MultiTexCoord0);\n"
  193. " color = p3d_Color * p3d_ColorScale;\n"
  194. "}\n";
  195. // Same as above, but for OpenGL 4.1.
  196. static const string default_vshader_fp64_gl41 =
  197. "#version 410\n"
  198. "in dvec3 p3d_Vertex;\n"
  199. "in vec4 p3d_Color;\n"
  200. "in dvec2 p3d_MultiTexCoord0;\n"
  201. "out vec2 texcoord;\n"
  202. "out vec4 color;\n"
  203. "uniform mat4 p3d_ModelViewMatrix;\n"
  204. "uniform mat4 p3d_ProjectionMatrix;\n"
  205. "uniform vec4 p3d_ColorScale;\n"
  206. "void main(void) {\n" // Apply proj & modelview in two steps, more precise
  207. " gl_Position = vec4(dmat4(p3d_ProjectionMatrix) * (dmat4(p3d_ModelViewMatrix) * dvec4(p3d_Vertex, 1)));\n"
  208. " texcoord = vec2(p3d_MultiTexCoord0);\n"
  209. " color = p3d_Color * p3d_ColorScale;\n"
  210. "}\n";
  211. #endif
  212. static const string default_fshader =
  213. #ifndef OPENGLES
  214. #ifdef __APPLE__ // Apple's GL 3.2 contexts require at least GLSL 1.50.
  215. "#version 150\n"
  216. #else
  217. "#version 130\n"
  218. #endif
  219. "in vec2 texcoord;\n"
  220. "in vec4 color;\n"
  221. "out vec4 p3d_FragColor;\n"
  222. "uniform sampler2D p3d_Texture0;\n"
  223. "uniform vec4 p3d_TexAlphaOnly;\n"
  224. #else
  225. "#version 100\n"
  226. "precision mediump float;\n"
  227. "varying vec2 texcoord;\n"
  228. "varying lowp vec4 color;\n"
  229. "uniform lowp sampler2D p3d_Texture0;\n"
  230. "uniform lowp vec4 p3d_TexAlphaOnly;\n"
  231. #endif
  232. "void main(void) {\n"
  233. #ifndef OPENGLES
  234. " p3d_FragColor = texture(p3d_Texture0, texcoord);\n"
  235. " p3d_FragColor += p3d_TexAlphaOnly;\n" // Hack for text rendering
  236. " p3d_FragColor *= color;\n"
  237. #else
  238. " gl_FragColor = texture2D(p3d_Texture0, texcoord);\n"
  239. " gl_FragColor += p3d_TexAlphaOnly;\n" // Hack for text rendering
  240. " gl_FragColor *= color;\n"
  241. #endif
  242. "}\n";
  243. #endif
  244. /**
  245. * Recopies the given array of pixels, converting from BGR to RGB arrangement.
  246. */
  247. static void
  248. uchar_bgr_to_rgb(unsigned char *dest, const unsigned char *source,
  249. int num_pixels) {
  250. for (int i = 0; i < num_pixels; i++) {
  251. dest[0] = source[2];
  252. dest[1] = source[1];
  253. dest[2] = source[0];
  254. dest += 3;
  255. source += 3;
  256. }
  257. }
  258. /**
  259. * Recopies the given array of pixels, converting from luminance to RGB
  260. * arrangement.
  261. */
  262. static void
  263. uchar_l_to_rgb(unsigned char *dest, const unsigned char *source,
  264. int num_pixels) {
  265. for (int i = 0; i < num_pixels; i++) {
  266. dest[0] = source[0];
  267. dest[1] = source[0];
  268. dest[2] = source[0];
  269. dest += 3;
  270. source += 1;
  271. }
  272. }
  273. /**
  274. * Recopies the given array of pixels, converting from BGRA to RGBA
  275. * arrangement.
  276. */
  277. static void
  278. uchar_bgra_to_rgba(unsigned char *dest, const unsigned char *source,
  279. int num_pixels) {
  280. for (int i = 0; i < num_pixels; i++) {
  281. dest[0] = source[2];
  282. dest[1] = source[1];
  283. dest[2] = source[0];
  284. dest[3] = source[3];
  285. dest += 4;
  286. source += 4;
  287. }
  288. }
  289. /**
  290. * Recopies the given array of pixels, converting from luminance-alpha to RGBA
  291. * arrangement.
  292. */
  293. static void
  294. uchar_la_to_rgba(unsigned char *dest, const unsigned char *source,
  295. int num_pixels) {
  296. for (int i = 0; i < num_pixels; i++) {
  297. dest[0] = source[0];
  298. dest[1] = source[0];
  299. dest[2] = source[0];
  300. dest[3] = source[1];
  301. dest += 4;
  302. source += 2;
  303. }
  304. }
  305. /**
  306. * Recopies the given array of pixels, converting from BGR to RGB arrangement.
  307. */
  308. static void
  309. ushort_bgr_to_rgb(unsigned short *dest, const unsigned short *source,
  310. int num_pixels) {
  311. for (int i = 0; i < num_pixels; i++) {
  312. dest[0] = source[2];
  313. dest[1] = source[1];
  314. dest[2] = source[0];
  315. dest += 3;
  316. source += 3;
  317. }
  318. }
  319. /**
  320. * Recopies the given array of pixels, converting from luminance to RGB
  321. * arrangement.
  322. */
  323. static void
  324. ushort_l_to_rgb(unsigned short *dest, const unsigned short *source,
  325. int num_pixels) {
  326. for (int i = 0; i < num_pixels; i++) {
  327. dest[0] = source[0];
  328. dest[1] = source[0];
  329. dest[2] = source[0];
  330. dest += 3;
  331. source += 1;
  332. }
  333. }
  334. /**
  335. * Recopies the given array of pixels, converting from BGRA to RGBA
  336. * arrangement.
  337. */
  338. static void
  339. ushort_bgra_to_rgba(unsigned short *dest, const unsigned short *source,
  340. int num_pixels) {
  341. for (int i = 0; i < num_pixels; i++) {
  342. dest[0] = source[2];
  343. dest[1] = source[1];
  344. dest[2] = source[0];
  345. dest[3] = source[3];
  346. dest += 4;
  347. source += 4;
  348. }
  349. }
  350. /**
  351. * Recopies the given array of pixels, converting from luminance-alpha to RGBA
  352. * arrangement.
  353. */
  354. static void
  355. ushort_la_to_rgba(unsigned short *dest, const unsigned short *source,
  356. int num_pixels) {
  357. for (int i = 0; i < num_pixels; i++) {
  358. dest[0] = source[0];
  359. dest[1] = source[0];
  360. dest[2] = source[0];
  361. dest[3] = source[1];
  362. dest += 4;
  363. source += 2;
  364. }
  365. }
  366. /**
  367. * Reverses the order of the components within the image, to convert (for
  368. * instance) GL_BGR to GL_RGB. Returns the byte pointer representing the
  369. * converted image, or the original image if it is unchanged.
  370. *
  371. * new_image must be supplied; it is the PTA_uchar that will be used to hold
  372. * the converted image if required. It will be modified only if the
  373. * conversion is necessary, in which case the data will be stored there, and
  374. * this pointer will be returned. If the conversion is not necessary, this
  375. * pointer will be left unchanged.
  376. */
  377. static const unsigned char *
  378. fix_component_ordering(PTA_uchar &new_image,
  379. const unsigned char *orig_image, size_t orig_image_size,
  380. GLenum external_format, Texture *tex) {
  381. const unsigned char *result = orig_image;
  382. switch (external_format) {
  383. case GL_RGB:
  384. if (tex->get_num_components() == 1) {
  385. new_image = PTA_uchar::empty_array(orig_image_size * 3);
  386. uchar_l_to_rgb(new_image, orig_image, orig_image_size);
  387. result = new_image;
  388. break;
  389. }
  390. switch (tex->get_component_type()) {
  391. case Texture::T_unsigned_byte:
  392. case Texture::T_byte:
  393. new_image = PTA_uchar::empty_array(orig_image_size);
  394. uchar_bgr_to_rgb(new_image, orig_image, orig_image_size / 3);
  395. result = new_image;
  396. break;
  397. case Texture::T_unsigned_short:
  398. case Texture::T_short:
  399. new_image = PTA_uchar::empty_array(orig_image_size);
  400. ushort_bgr_to_rgb((unsigned short *)new_image.p(),
  401. (const unsigned short *)orig_image,
  402. orig_image_size / 6);
  403. result = new_image;
  404. break;
  405. default:
  406. break;
  407. }
  408. break;
  409. case GL_RGBA:
  410. if (tex->get_num_components() == 2) {
  411. new_image = PTA_uchar::empty_array(orig_image_size * 2);
  412. uchar_la_to_rgba(new_image, orig_image, orig_image_size / 2);
  413. result = new_image;
  414. break;
  415. }
  416. switch (tex->get_component_type()) {
  417. case Texture::T_unsigned_byte:
  418. case Texture::T_byte:
  419. new_image = PTA_uchar::empty_array(orig_image_size);
  420. uchar_bgra_to_rgba(new_image, orig_image, orig_image_size / 4);
  421. result = new_image;
  422. break;
  423. case Texture::T_unsigned_short:
  424. case Texture::T_short:
  425. new_image = PTA_uchar::empty_array(orig_image_size);
  426. ushort_bgra_to_rgba((unsigned short *)new_image.p(),
  427. (const unsigned short *)orig_image,
  428. orig_image_size / 8);
  429. result = new_image;
  430. break;
  431. default:
  432. break;
  433. }
  434. break;
  435. default:
  436. break;
  437. }
  438. return result;
  439. }
  440. // #--- Zhao Nov2011
  441. string CLP(GraphicsStateGuardian)::get_driver_vendor() { return _gl_vendor; }
  442. string CLP(GraphicsStateGuardian)::get_driver_renderer() { return _gl_renderer; }
  443. string CLP(GraphicsStateGuardian)::get_driver_version() { return _gl_version; }
  444. int CLP(GraphicsStateGuardian)::get_driver_version_major() { return _gl_version_major; }
  445. int CLP(GraphicsStateGuardian)::get_driver_version_minor() { return _gl_version_minor; }
  446. int CLP(GraphicsStateGuardian)::get_driver_shader_version_major() { return _gl_shadlang_ver_major; }
  447. int CLP(GraphicsStateGuardian)::get_driver_shader_version_minor() { return _gl_shadlang_ver_minor; }
  448. /**
  449. *
  450. */
  451. CLP(GraphicsStateGuardian)::
  452. CLP(GraphicsStateGuardian)(GraphicsEngine *engine, GraphicsPipe *pipe) :
  453. GraphicsStateGuardian(gl_coordinate_system, engine, pipe),
  454. _renderbuffer_residency(get_prepared_objects()->get_name(), "renderbuffer")
  455. {
  456. _error_count = 0;
  457. _last_error_check = -1.0;
  458. // calling glGetError() forces a sync, this turns it on if you want to.
  459. _check_errors = gl_check_errors;
  460. _force_flush = gl_force_flush;
  461. _gl_shadlang_ver_major = 0;
  462. _gl_shadlang_ver_minor = 0;
  463. // Let's say we have a core profile, to be checked later (Otherwise, if we are
  464. // wrong the user may ask for some non-available functions)
  465. #ifndef OPENGLES
  466. _core_profile = true;
  467. #endif
  468. // Hack. Turn on the flag that we turned off at a higher level, since we
  469. // know this works properly in OpenGL, and we want the performance benefit
  470. // it gives us.
  471. _prepared_objects->_support_released_buffer_cache = true;
  472. // Assume that we will get a hardware-accelerated context, unless the window
  473. // tells us otherwise.
  474. _is_hardware = true;
  475. _scissor_enabled = false;
  476. _scissor_attrib_active = false;
  477. _white_texture = 0;
  478. #ifndef OPENGLES
  479. _shader_point_size = false;
  480. #endif
  481. #ifdef HAVE_CG
  482. _cg_context = 0;
  483. #endif
  484. #ifdef DO_PSTATS
  485. if (gl_finish) {
  486. GLCAT.warning()
  487. << "The config variable gl-finish is set to true. This may have a substantial negative impact on your render performance.\n";
  488. }
  489. #endif // DO_PSTATS
  490. }
  491. /**
  492. *
  493. */
  494. CLP(GraphicsStateGuardian)::
  495. ~CLP(GraphicsStateGuardian)() {
  496. if (GLCAT.is_debug()) {
  497. GLCAT.debug()
  498. << "GLGraphicsStateGuardian " << this << " destructing\n";
  499. }
  500. close_gsg();
  501. }
  502. /**
  503. * This is called by the GL if an error occurs, if gl_debug has been enabled
  504. * (and the driver supports the GL_ARB_debug_output extension).
  505. */
  506. void CLP(GraphicsStateGuardian)::
  507. debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *userParam) {
  508. // Determine how to map the severity level.
  509. NotifySeverity level;
  510. switch (severity) {
  511. case GL_DEBUG_SEVERITY_HIGH:
  512. level = NS_error;
  513. break;
  514. case GL_DEBUG_SEVERITY_MEDIUM:
  515. if (type == GL_DEBUG_TYPE_PERFORMANCE) {
  516. // Performance warnings should really be "info".
  517. level = NS_info;
  518. } else {
  519. level = NS_warning;
  520. }
  521. break;
  522. case GL_DEBUG_SEVERITY_LOW:
  523. level = NS_info;
  524. break;
  525. case GL_DEBUG_SEVERITY_NOTIFICATION:
  526. level = NS_debug;
  527. break;
  528. default:
  529. level = NS_fatal; //???
  530. break;
  531. }
  532. string msg_str(message, length);
  533. GLCAT.out(level) << msg_str << "\n";
  534. #ifndef NDEBUG
  535. if (level >= gl_debug_abort_level.get_value()) {
  536. abort();
  537. }
  538. #endif
  539. }
  540. /**
  541. * Resets all internal state as if the gsg were newly created.
  542. */
  543. void CLP(GraphicsStateGuardian)::
  544. reset() {
  545. _last_error_check = -1.0;
  546. free_pointers();
  547. GraphicsStateGuardian::reset();
  548. // Build _inv_state_mask as a mask of 1's where we don't care, and 0's where
  549. // we do care, about the state. _inv_state_mask =
  550. // RenderState::SlotMask::all_on();
  551. _inv_state_mask.clear_bit(ShaderAttrib::get_class_slot());
  552. _inv_state_mask.clear_bit(AlphaTestAttrib::get_class_slot());
  553. _inv_state_mask.clear_bit(AntialiasAttrib::get_class_slot());
  554. _inv_state_mask.clear_bit(ClipPlaneAttrib::get_class_slot());
  555. _inv_state_mask.clear_bit(ColorAttrib::get_class_slot());
  556. _inv_state_mask.clear_bit(ColorScaleAttrib::get_class_slot());
  557. _inv_state_mask.clear_bit(CullFaceAttrib::get_class_slot());
  558. _inv_state_mask.clear_bit(DepthOffsetAttrib::get_class_slot());
  559. _inv_state_mask.clear_bit(DepthTestAttrib::get_class_slot());
  560. _inv_state_mask.clear_bit(DepthWriteAttrib::get_class_slot());
  561. _inv_state_mask.clear_bit(RenderModeAttrib::get_class_slot());
  562. _inv_state_mask.clear_bit(RescaleNormalAttrib::get_class_slot());
  563. _inv_state_mask.clear_bit(ShadeModelAttrib::get_class_slot());
  564. _inv_state_mask.clear_bit(TransparencyAttrib::get_class_slot());
  565. _inv_state_mask.clear_bit(ColorWriteAttrib::get_class_slot());
  566. _inv_state_mask.clear_bit(ColorBlendAttrib::get_class_slot());
  567. _inv_state_mask.clear_bit(LogicOpAttrib::get_class_slot());
  568. _inv_state_mask.clear_bit(TextureAttrib::get_class_slot());
  569. _inv_state_mask.clear_bit(TexGenAttrib::get_class_slot());
  570. _inv_state_mask.clear_bit(TexMatrixAttrib::get_class_slot());
  571. _inv_state_mask.clear_bit(MaterialAttrib::get_class_slot());
  572. _inv_state_mask.clear_bit(LightAttrib::get_class_slot());
  573. _inv_state_mask.clear_bit(StencilAttrib::get_class_slot());
  574. _inv_state_mask.clear_bit(FogAttrib::get_class_slot());
  575. _inv_state_mask.clear_bit(ScissorAttrib::get_class_slot());
  576. // Output the vendor and version strings.
  577. query_gl_version();
  578. if (_gl_version_major == 0) {
  579. // Couldn't get GL. Fail.
  580. mark_new();
  581. return;
  582. }
  583. // Save the extensions tokens.
  584. _extensions.clear();
  585. // In OpenGL (ES) 3.0 and later, glGetString(GL_EXTENSIONS) is deprecated.
  586. #ifndef OPENGLES_1
  587. if (_gl_version_major >= 3) {
  588. PFNGLGETSTRINGIPROC _glGetStringi =
  589. (PFNGLGETSTRINGIPROC)get_extension_func("glGetStringi");
  590. if (_glGetStringi != nullptr) {
  591. GLint n = 0;
  592. glGetIntegerv(GL_NUM_EXTENSIONS, &n);
  593. for (GLint i = 0; i < n; ++i) {
  594. const char *extension = (const char *)_glGetStringi(GL_EXTENSIONS, i);
  595. _extensions.insert(string(extension));
  596. }
  597. } else {
  598. GLCAT.error() << "glGetStringi is not available!\n";
  599. save_extensions((const char *)glGetString(GL_EXTENSIONS));
  600. }
  601. } else
  602. #endif
  603. {
  604. save_extensions((const char *)glGetString(GL_EXTENSIONS));
  605. }
  606. get_extra_extensions();
  607. // This needs access to the extensions, so put this after save_extensions.
  608. query_glsl_version();
  609. #ifndef OPENGLES
  610. // Determine whether this OpenGL context has compatibility features.
  611. bool core_profile = false;
  612. if (_gl_version_major >= 3) {
  613. if (_gl_version_major > 3 || _gl_version_minor >= 2) {
  614. // OpenGL 3.2 has a built-in way to check this.
  615. GLint profile_mask = 0;
  616. glGetIntegerv(GL_CONTEXT_PROFILE_MASK, &profile_mask);
  617. if (profile_mask & GL_CONTEXT_CORE_PROFILE_BIT) {
  618. core_profile = true;
  619. } else if (profile_mask & GL_CONTEXT_COMPATIBILITY_PROFILE_BIT) {
  620. core_profile = false;
  621. } else {
  622. core_profile = !has_extension("GL_ARB_compatibility");
  623. }
  624. } else {
  625. // OpenGL 3.0/3.1.
  626. GLint flags = 0;
  627. glGetIntegerv(GL_CONTEXT_FLAGS, &flags);
  628. if (flags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) {
  629. core_profile = true;
  630. }
  631. }
  632. }
  633. if (GLCAT.is_debug()) {
  634. if (core_profile) {
  635. GLCAT.debug() << "Using core profile\n";
  636. } else {
  637. GLCAT.debug() << "Using compatibility profile\n";
  638. }
  639. }
  640. _core_profile = core_profile;
  641. #elif defined(OPENGLES_1)
  642. static const bool core_profile = false;
  643. #else
  644. static const bool core_profile = true;
  645. #endif
  646. // Print out a list of all extensions.
  647. report_extensions();
  648. // Check if we are running under a profiling tool such as apitrace.
  649. #if !defined(NDEBUG) && !defined(OPENGLES_1)
  650. if (has_extension("GL_EXT_debug_marker")) {
  651. _glPushGroupMarker = (PFNGLPUSHGROUPMARKEREXTPROC)
  652. get_extension_func("glPushGroupMarkerEXT");
  653. _glPopGroupMarker = (PFNGLPOPGROUPMARKEREXTPROC)
  654. get_extension_func("glPopGroupMarkerEXT");
  655. // Start a group right away.
  656. push_group_marker("reset");
  657. } else {
  658. _glPushGroupMarker = nullptr;
  659. _glPopGroupMarker = nullptr;
  660. }
  661. #endif
  662. // Initialize OpenGL debugging output first, if enabled and supported.
  663. _supports_debug = false;
  664. _use_object_labels = false;
  665. if (gl_debug) {
  666. PFNGLDEBUGMESSAGECALLBACKPROC_P _glDebugMessageCallback;
  667. PFNGLDEBUGMESSAGECONTROLPROC _glDebugMessageControl;
  668. if (is_at_least_gl_version(4, 3) || has_extension("GL_KHR_debug")) {
  669. #ifdef OPENGLES
  670. _glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC_P)
  671. get_extension_func("glDebugMessageCallbackKHR");
  672. _glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)
  673. get_extension_func("glDebugMessageControlKHR");
  674. _glObjectLabel = (PFNGLOBJECTLABELPROC)
  675. get_extension_func("glObjectLabelKHR");
  676. #else
  677. _glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC_P)
  678. get_extension_func("glDebugMessageCallback");
  679. _glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)
  680. get_extension_func("glDebugMessageControl");
  681. _glObjectLabel = (PFNGLOBJECTLABELPROC)
  682. get_extension_func("glObjectLabel");
  683. #endif
  684. glEnable(GL_DEBUG_OUTPUT); // Not supported in ARB version
  685. _supports_debug = true;
  686. _use_object_labels = gl_debug_object_labels;
  687. #ifndef OPENGLES
  688. } else if (has_extension("GL_ARB_debug_output")) {
  689. _glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC_P)
  690. get_extension_func("glDebugMessageCallbackARB");
  691. _glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)
  692. get_extension_func("glDebugMessageControlARB");
  693. _supports_debug = true;
  694. #endif
  695. } else {
  696. _supports_debug = false;
  697. }
  698. if (_supports_debug) {
  699. // Set the categories we want to listen to.
  700. _glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH,
  701. 0, nullptr, GLCAT.is_error());
  702. _glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM,
  703. 0, nullptr, GLCAT.is_warning());
  704. _glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW,
  705. 0, nullptr, GLCAT.is_info());
  706. _glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION,
  707. 0, nullptr, GLCAT.is_debug());
  708. // Enable the callback.
  709. _glDebugMessageCallback((GLDEBUGPROC_P) &debug_callback, (void*)this);
  710. if (gl_debug_synchronous) {
  711. glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
  712. }
  713. GLCAT.info() << "gl-debug enabled.\n";
  714. } else {
  715. GLCAT.warning() << "gl-debug enabled, but NOT supported.\n";
  716. }
  717. } else {
  718. // However, still check if it is supported.
  719. _supports_debug = is_at_least_gl_version(4, 3)
  720. || has_extension("GL_KHR_debug")
  721. || has_extension("GL_ARB_debug_output");
  722. if (GLCAT.is_debug()) {
  723. if (_supports_debug) {
  724. GLCAT.debug() << "gl-debug supported, but NOT enabled.\n";
  725. } else {
  726. GLCAT.debug() << "gl-debug disabled and unsupported.\n";
  727. }
  728. }
  729. }
  730. _supported_geom_rendering =
  731. #ifndef OPENGLES
  732. Geom::GR_render_mode_wireframe | Geom::GR_render_mode_point |
  733. #endif
  734. Geom::GR_indexed_point |
  735. Geom::GR_point | Geom::GR_point_uniform_size |
  736. Geom::GR_indexed_other |
  737. Geom::GR_triangle_strip | Geom::GR_triangle_fan |
  738. Geom::GR_line_strip |
  739. Geom::GR_flat_last_vertex;
  740. #ifndef OPENGLES
  741. if (_supports_geometry_shaders) {
  742. _supported_geom_rendering |= Geom::GR_adjacency;
  743. }
  744. #endif
  745. _supports_point_parameters = false;
  746. #ifdef OPENGLES_1
  747. _glPointParameterfv = glPointParameterfv;
  748. #elif defined(OPENGLES)
  749. // Other OpenGL ES versions don't support point parameters.
  750. #else
  751. if (is_at_least_gl_version(1, 4)) {
  752. _supports_point_parameters = true;
  753. _glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)
  754. get_extension_func("glPointParameterfv");
  755. } else if (has_extension("GL_ARB_point_parameters")) {
  756. _supports_point_parameters = true;
  757. _glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)
  758. get_extension_func("glPointParameterfvARB");
  759. }
  760. if (_supports_point_parameters) {
  761. if (_glPointParameterfv == nullptr) {
  762. GLCAT.warning()
  763. << "glPointParameterfv advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  764. _supports_point_parameters = false;
  765. }
  766. }
  767. if (_supports_point_parameters) {
  768. _supported_geom_rendering |= Geom::GR_point_perspective | Geom::GR_point_scale;
  769. } else {
  770. _glPointParameterfv = null_glPointParameterfv;
  771. }
  772. #endif // !OPENGLES_2
  773. #if defined(OPENGLES_2)
  774. // OpenGL ES 2 doesn't have point sprites.
  775. _supports_point_sprite = false;
  776. #elif defined(OPENGLES_1)
  777. _supports_point_sprite = has_extension("GL_OES_point_sprite");
  778. #else
  779. _supports_point_sprite = is_at_least_gl_version(2, 0) ||
  780. has_extension("GL_ARB_point_sprite");
  781. #endif
  782. if (_supports_point_sprite) {
  783. // It appears that the point_sprite extension doesn't support texture
  784. // transforms on the generated texture coordinates. How inconsistent.
  785. // Because of this, we don't advertise GR_point_sprite_tex_matrix.
  786. _supported_geom_rendering |= Geom::GR_point_sprite;
  787. }
  788. // Determine whether we support wide lines (and how wide they can be).
  789. {
  790. GLfloat aliased_range[2] = {1.0f, 1.0f};
  791. glGetFloatv(GL_ALIASED_LINE_WIDTH_RANGE, aliased_range);
  792. _max_line_width = aliased_range[1];
  793. #ifdef SUPPORT_FIXED_FUNCTION
  794. if (has_fixed_function_pipeline()) {
  795. #ifndef OPENGLES
  796. GLfloat range[2] = {1.0f, 1.0f};
  797. glGetFloatv(GL_LINE_WIDTH_RANGE, range);
  798. _max_line_width = std::max(_max_line_width, range[1]);
  799. #endif
  800. GLfloat smooth_range[2] = {1.0f, 1.0f};
  801. glGetFloatv(GL_SMOOTH_LINE_WIDTH_RANGE, smooth_range);
  802. _max_line_width = std::max(_max_line_width, smooth_range[1]);
  803. }
  804. #endif
  805. }
  806. #ifdef OPENGLES_1
  807. // OpenGL ES 1.0 does not support primitive restart indices.
  808. #elif defined(OPENGLES)
  809. if (gl_support_primitive_restart_index && is_at_least_gles_version(3, 0)) {
  810. glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
  811. _supported_geom_rendering |= Geom::GR_strip_cut_index;
  812. }
  813. #else
  814. _explicit_primitive_restart = false;
  815. _glPrimitiveRestartIndex = nullptr;
  816. if (gl_support_primitive_restart_index) {
  817. if ((is_at_least_gl_version(4, 3) || has_extension("GL_ARB_ES3_compatibility")) &&
  818. _gl_renderer.substr(0, 7) != "Gallium") {
  819. // As long as we enable this, OpenGL will always use the highest
  820. // possible index for a numeric type as strip cut index, which coincides
  821. // with our convention. This saves us a call to glPrimitiveRestartIndex
  822. // ... of course, though, the Gallium driver bugs out here. See also:
  823. // https://www.panda3d.org/forums/viewtopic.php?f=5&t=17512
  824. glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
  825. _supported_geom_rendering |= Geom::GR_strip_cut_index;
  826. } else if (is_at_least_gl_version(3, 1)) {
  827. // We have to use an explicit primitive restart enableindex.
  828. _explicit_primitive_restart = true;
  829. _supported_geom_rendering |= Geom::GR_strip_cut_index;
  830. _glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC)
  831. get_extension_func("glPrimitiveRestartIndex");
  832. }
  833. }
  834. #endif
  835. #if !defined(OPENGLES) && defined(SUPPORT_FIXED_FUNCTION)
  836. if (has_fixed_function_pipeline() && is_at_least_gl_version(1, 4)) {
  837. _glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC)
  838. get_extension_func("glSecondaryColorPointer");
  839. } else if (has_extension("GL_EXT_secondary_color")) {
  840. _glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC)
  841. get_extension_func("glSecondaryColorPointerEXT");
  842. }
  843. #endif
  844. #ifndef OPENGLES_1
  845. _glDrawRangeElements = null_glDrawRangeElements;
  846. #ifdef OPENGLES
  847. if (is_at_least_gles_version(3, 0)) {
  848. _glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)
  849. get_extension_func("glDrawRangeElements");
  850. }
  851. #else
  852. if (is_at_least_gl_version(1, 2)) {
  853. _glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)
  854. get_extension_func("glDrawRangeElements");
  855. } else if (has_extension("GL_EXT_draw_range_elements")) {
  856. _glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)
  857. get_extension_func("glDrawRangeElementsEXT");
  858. }
  859. #endif
  860. if (_glDrawRangeElements == nullptr) {
  861. GLCAT.warning()
  862. << "glDrawRangeElements advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  863. _glDrawRangeElements = null_glDrawRangeElements;
  864. }
  865. #endif // !OPENGLES_1
  866. _supports_3d_texture = false;
  867. #ifndef OPENGLES_1
  868. if (is_at_least_gl_version(1, 2) || is_at_least_gles_version(3, 0)) {
  869. _supports_3d_texture = true;
  870. _glTexImage3D = (PFNGLTEXIMAGE3DPROC_P)
  871. get_extension_func("glTexImage3D");
  872. _glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)
  873. get_extension_func("glTexSubImage3D");
  874. _glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)
  875. get_extension_func("glCopyTexSubImage3D");
  876. #ifndef OPENGLES
  877. } else if (has_extension("GL_EXT_texture3D")) {
  878. _supports_3d_texture = true;
  879. _glTexImage3D = (PFNGLTEXIMAGE3DPROC_P)
  880. get_extension_func("glTexImage3DEXT");
  881. _glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)
  882. get_extension_func("glTexSubImage3DEXT");
  883. _glCopyTexSubImage3D = nullptr;
  884. if (has_extension("GL_EXT_copy_texture")) {
  885. _glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)
  886. get_extension_func("glCopyTexSubImage3DEXT");
  887. }
  888. #else
  889. } else if (has_extension("GL_OES_texture_3D")) {
  890. _supports_3d_texture = true;
  891. _glTexImage3D = (PFNGLTEXIMAGE3DPROC_P)
  892. get_extension_func("glTexImage3DOES");
  893. _glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)
  894. get_extension_func("glTexSubImage3DOES");
  895. _glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)
  896. get_extension_func("glCopyTexSubImage3DOES");
  897. _glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DOES)
  898. get_extension_func("glFramebufferTexture3DOES");
  899. #endif
  900. }
  901. if (_supports_3d_texture) {
  902. if (_glTexImage3D == nullptr || _glTexSubImage3D == nullptr) {
  903. GLCAT.warning()
  904. << "3-D textures advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  905. _supports_3d_texture = false;
  906. }
  907. }
  908. #endif // !OPENGLES_1
  909. _supports_tex_storage = false;
  910. #ifdef OPENGLES
  911. if (is_at_least_gles_version(3, 0)) {
  912. #else
  913. if (is_at_least_gl_version(4, 2) || has_extension("GL_ARB_texture_storage")) {
  914. #endif
  915. _supports_tex_storage = true;
  916. _glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)
  917. get_extension_func("glTexStorage1D");
  918. _glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)
  919. get_extension_func("glTexStorage2D");
  920. _glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)
  921. get_extension_func("glTexStorage3D");
  922. }
  923. #ifdef OPENGLES
  924. else if (has_extension("GL_EXT_texture_storage")) {
  925. _supports_tex_storage = true;
  926. _glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)
  927. get_extension_func("glTexStorage1DEXT");
  928. _glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)
  929. get_extension_func("glTexStorage2DEXT");
  930. _glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)
  931. get_extension_func("glTexStorage3DEXT");
  932. }
  933. #endif
  934. if (_supports_tex_storage) {
  935. if (_glTexStorage1D == nullptr || _glTexStorage2D == nullptr || _glTexStorage3D == nullptr) {
  936. GLCAT.warning()
  937. << "Immutable texture storage advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  938. _supports_tex_storage = false;
  939. }
  940. }
  941. _supports_clear_texture = false;
  942. #ifndef OPENGLES
  943. if (is_at_least_gl_version(4, 4) || has_extension("GL_ARB_clear_texture")) {
  944. _glClearTexImage = (PFNGLCLEARTEXIMAGEPROC)
  945. get_extension_func("glClearTexImage");
  946. if (_glClearTexImage == nullptr) {
  947. GLCAT.warning()
  948. << "GL_ARB_clear_texture advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  949. } else {
  950. _supports_clear_texture = true;
  951. }
  952. }
  953. #endif
  954. _supports_clear_buffer = false;
  955. #ifndef OPENGLES
  956. if (is_at_least_gl_version(4, 3) || has_extension("GL_ARB_clear_buffer_object")) {
  957. _glClearBufferData = (PFNGLCLEARBUFFERDATAPROC)
  958. get_extension_func("glClearBufferData");
  959. if (_glClearBufferData == nullptr) {
  960. GLCAT.warning()
  961. << "GL_ARB_clear_buffer_object advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  962. } else {
  963. _supports_clear_buffer = true;
  964. }
  965. }
  966. #endif
  967. _supports_2d_texture_array = false;
  968. #ifndef OPENGLES_1
  969. if (_gl_version_major >= 3) {
  970. _supports_2d_texture_array = true;
  971. _glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)
  972. get_extension_func("glFramebufferTextureLayer");
  973. #ifndef OPENGLES
  974. } else if (has_extension("GL_EXT_texture_array")) {
  975. _supports_2d_texture_array = true;
  976. _glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)
  977. get_extension_func("glFramebufferTextureLayerEXT");
  978. #endif
  979. }
  980. if (_supports_2d_texture_array && _glFramebufferTextureLayer == nullptr) {
  981. GLCAT.warning()
  982. << "Texture arrays advertised as supported by OpenGL runtime, but could not get pointer to glFramebufferTextureLayer function.\n";
  983. }
  984. #endif // !OPENGLES_1
  985. #ifdef OPENGLES_2
  986. _supports_cube_map = true;
  987. #else
  988. _supports_cube_map =
  989. is_at_least_gl_version(1, 3) ||
  990. has_extension("GL_ARB_texture_cube_map") ||
  991. has_extension("GL_OES_texture_cube_map");
  992. #endif
  993. #ifndef OPENGLES
  994. if (_supports_cube_map && gl_cube_map_seamless) {
  995. if (is_at_least_gl_version(3, 2) || has_extension("GL_ARB_seamless_cube_map")) {
  996. glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
  997. }
  998. }
  999. #endif
  1000. #ifndef OPENGLES
  1001. _supports_cube_map_array = is_at_least_gl_version(4, 0) ||
  1002. has_extension("GL_ARB_texture_cube_map_array");
  1003. #endif
  1004. #ifndef OPENGLES
  1005. if (is_at_least_gl_version(3, 1)) {
  1006. _glTexBuffer = (PFNGLTEXBUFFERPROC)get_extension_func("glTexBuffer");
  1007. _supports_buffer_texture = true;
  1008. } else if (has_extension("GL_ARB_texture_buffer_object")) {
  1009. _glTexBuffer = (PFNGLTEXBUFFERPROC)get_extension_func("glTexBufferARB");
  1010. _supports_buffer_texture = true;
  1011. }
  1012. #endif
  1013. #ifdef OPENGLES
  1014. _supports_texture_srgb =
  1015. is_at_least_gles_version(3, 0) || has_extension("GL_EXT_sRGB");
  1016. #else
  1017. _supports_texture_srgb =
  1018. is_at_least_gl_version(2, 1) || has_extension("GL_EXT_texture_sRGB");
  1019. #endif
  1020. #ifdef OPENGLES
  1021. _supports_compressed_texture = true;
  1022. // Supported in the core. 1D textures are not supported by OpenGL ES.
  1023. _glCompressedTexImage1D = nullptr;
  1024. _glCompressedTexImage2D = glCompressedTexImage2D;
  1025. _glCompressedTexSubImage1D = nullptr;
  1026. _glCompressedTexSubImage2D = glCompressedTexSubImage2D;
  1027. _glGetCompressedTexImage = nullptr;
  1028. _glCompressedTexImage3D = nullptr;
  1029. _glCompressedTexSubImage3D = nullptr;
  1030. #ifdef OPENGLES_2
  1031. if (_supports_3d_texture) {
  1032. _glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)
  1033. get_extension_func("glCompressedTexImage3DOES");
  1034. _glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)
  1035. get_extension_func("glCompressedTexSubImageOES");
  1036. }
  1037. #endif
  1038. #else
  1039. if (is_at_least_gl_version(1, 3)) {
  1040. _supports_compressed_texture = true;
  1041. _glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)
  1042. get_extension_func("glCompressedTexImage1D");
  1043. _glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)
  1044. get_extension_func("glCompressedTexImage2D");
  1045. _glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)
  1046. get_extension_func("glCompressedTexImage3D");
  1047. _glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)
  1048. get_extension_func("glCompressedTexSubImage1D");
  1049. _glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)
  1050. get_extension_func("glCompressedTexSubImage2D");
  1051. _glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)
  1052. get_extension_func("glCompressedTexSubImage3D");
  1053. _glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)
  1054. get_extension_func("glGetCompressedTexImage");
  1055. } else if (has_extension("GL_ARB_texture_compression")) {
  1056. _supports_compressed_texture = true;
  1057. _glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)
  1058. get_extension_func("glCompressedTexImage1DARB");
  1059. _glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)
  1060. get_extension_func("glCompressedTexImage2DARB");
  1061. _glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)
  1062. get_extension_func("glCompressedTexImage3DARB");
  1063. _glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)
  1064. get_extension_func("glCompressedTexSubImage1DARB");
  1065. _glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)
  1066. get_extension_func("glCompressedTexSubImage2DARB");
  1067. _glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)
  1068. get_extension_func("glCompressedTexSubImage3DARB");
  1069. _glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)
  1070. get_extension_func("glGetCompressedTexImageARB");
  1071. } else {
  1072. _supports_compressed_texture = false;
  1073. }
  1074. if (_supports_compressed_texture) {
  1075. if (_glCompressedTexImage1D == nullptr ||
  1076. _glCompressedTexImage2D == nullptr ||
  1077. _glCompressedTexImage3D == nullptr ||
  1078. _glCompressedTexSubImage1D == nullptr ||
  1079. _glCompressedTexSubImage2D == nullptr ||
  1080. _glCompressedTexSubImage3D == nullptr ||
  1081. _glGetCompressedTexImage == nullptr) {
  1082. GLCAT.warning()
  1083. << "Compressed textures advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1084. _supports_compressed_texture = false;
  1085. }
  1086. }
  1087. #endif
  1088. if (_supports_compressed_texture) {
  1089. #ifndef OPENGLES
  1090. _compressed_texture_formats.set_bit(Texture::CM_on);
  1091. #endif
  1092. GLint num_compressed_formats = 0;
  1093. glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_compressed_formats);
  1094. GLint *formats = (GLint *)alloca(num_compressed_formats * sizeof(GLint));
  1095. glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats);
  1096. for (int i = 0; i < num_compressed_formats; ++i) {
  1097. switch (formats[i]) {
  1098. case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  1099. case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  1100. _compressed_texture_formats.set_bit(Texture::CM_dxt1);
  1101. break;
  1102. #ifdef OPENGLES
  1103. case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
  1104. case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
  1105. _compressed_texture_formats.set_bit(Texture::CM_pvr1_2bpp);
  1106. break;
  1107. case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
  1108. case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
  1109. _compressed_texture_formats.set_bit(Texture::CM_pvr1_4bpp);
  1110. break;
  1111. #else
  1112. case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
  1113. _compressed_texture_formats.set_bit(Texture::CM_dxt3);
  1114. break;
  1115. case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
  1116. _compressed_texture_formats.set_bit(Texture::CM_dxt5);
  1117. break;
  1118. case GL_COMPRESSED_RGB_FXT1_3DFX:
  1119. case GL_COMPRESSED_RGBA_FXT1_3DFX:
  1120. _compressed_texture_formats.set_bit(Texture::CM_fxt1);
  1121. break;
  1122. #endif
  1123. case GL_COMPRESSED_R11_EAC:
  1124. case GL_COMPRESSED_RG11_EAC:
  1125. _compressed_texture_formats.set_bit(Texture::CM_eac);
  1126. break;
  1127. case GL_COMPRESSED_RGB8_ETC2:
  1128. case GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
  1129. case GL_COMPRESSED_RGBA8_ETC2_EAC:
  1130. _compressed_texture_formats.set_bit(Texture::CM_etc1);
  1131. _compressed_texture_formats.set_bit(Texture::CM_etc2);
  1132. break;
  1133. #ifdef OPENGLES
  1134. case GL_ETC1_RGB8_OES:
  1135. _compressed_texture_formats.set_bit(Texture::CM_etc1);
  1136. break;
  1137. #endif
  1138. default:
  1139. break;
  1140. }
  1141. }
  1142. #ifndef OPENGLES
  1143. // The OpenGL spec states that these are not reported by the above
  1144. // mechanism, so we have to check for the extension ourselves.
  1145. if (is_at_least_gl_version(3, 0) ||
  1146. has_extension("GL_ARB_texture_compression_rgtc") ||
  1147. has_extension("GL_EXT_texture_compression_rgtc")) {
  1148. _compressed_texture_formats.set_bit(Texture::CM_rgtc);
  1149. }
  1150. #endif
  1151. }
  1152. #ifdef OPENGLES
  1153. // Note that these extensions only offer support for GL_BGRA, not GL_BGR.
  1154. _supports_bgr = has_extension("GL_EXT_texture_format_BGRA8888") ||
  1155. has_extension("GL_APPLE_texture_format_BGRA8888");
  1156. _supports_bgra_read = has_extension("GL_EXT_read_format_bgra");
  1157. #else
  1158. // In regular OpenGL, we have both GL_BGRA and GL_BGR.
  1159. _supports_bgr =
  1160. is_at_least_gl_version(1, 2) || has_extension("GL_EXT_bgra");
  1161. _supports_bgra_read = _supports_bgr;
  1162. #endif
  1163. #ifdef SUPPORT_FIXED_FUNCTION
  1164. #ifdef OPENGLES_1
  1165. _supports_rescale_normal = true;
  1166. #else
  1167. _supports_rescale_normal =
  1168. has_fixed_function_pipeline() && gl_support_rescale_normal &&
  1169. (is_at_least_gl_version(1, 2) || has_extension("GL_EXT_rescale_normal"));
  1170. #endif
  1171. #ifndef OPENGLES
  1172. _use_separate_specular_color =
  1173. has_fixed_function_pipeline() && gl_separate_specular_color &&
  1174. (is_at_least_gl_version(1, 2) || has_extension("GL_EXT_separate_specular_color"));
  1175. #endif
  1176. #endif // SUPPORT_FIXED_FUNCTION
  1177. #ifdef OPENGLES
  1178. _supports_packed_dabc = false;
  1179. _supports_packed_ufloat = false;
  1180. #else
  1181. _supports_packed_dabc = is_at_least_gl_version(3, 2) ||
  1182. has_extension("GL_ARB_vertex_array_bgra") ||
  1183. has_extension("GL_EXT_vertex_array_bgra");
  1184. _supports_packed_ufloat = is_at_least_gl_version(4, 4) ||
  1185. has_extension("GL_ARB_vertex_type_10f_11f_11f_rev");
  1186. #endif
  1187. #ifdef OPENGLES
  1188. //TODO
  1189. _supports_multisample = false;
  1190. #else
  1191. _supports_multisample =
  1192. is_at_least_gl_version(1, 3) || has_extension("GL_ARB_multisample");
  1193. #endif
  1194. #ifdef OPENGLES_1
  1195. _supports_generate_mipmap = is_at_least_gles_version(1, 1);
  1196. #elif defined(OPENGLES)
  1197. _supports_generate_mipmap = true;
  1198. #else
  1199. _supports_generate_mipmap = is_at_least_gl_version(1, 4) ||
  1200. has_extension("GL_SGIS_generate_mipmap");
  1201. #endif
  1202. #ifdef OPENGLES_1
  1203. _supports_tex_non_pow2 = false;
  1204. #elif defined(OPENGLES)
  1205. _supports_tex_non_pow2 = is_at_least_gles_version(3, 0) ||
  1206. has_extension("GL_OES_texture_npot");
  1207. #else
  1208. _supports_tex_non_pow2 = is_at_least_gl_version(2, 0) ||
  1209. has_extension("GL_ARB_texture_non_power_of_two");
  1210. #endif
  1211. #ifndef OPENGLES_2
  1212. bool supports_multitexture = false;
  1213. if (is_at_least_gl_version(1, 3) || is_at_least_gles_version(1, 1)) {
  1214. supports_multitexture = true;
  1215. _glActiveTexture = (PFNGLACTIVETEXTUREPROC)
  1216. get_extension_func("glActiveTexture");
  1217. #ifdef SUPPORT_FIXED_FUNCTION
  1218. if (has_fixed_function_pipeline()) {
  1219. _glClientActiveTexture = (PFNGLACTIVETEXTUREPROC)
  1220. get_extension_func("glClientActiveTexture");
  1221. }
  1222. #endif
  1223. #ifdef SUPPORT_IMMEDIATE_MODE
  1224. _glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)
  1225. get_extension_func("glMultiTexCoord1f");
  1226. _glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)
  1227. get_extension_func("glMultiTexCoord2f");
  1228. _glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)
  1229. get_extension_func("glMultiTexCoord3f");
  1230. _glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)
  1231. get_extension_func("glMultiTexCoord4f");
  1232. _glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)
  1233. get_extension_func("glMultiTexCoord1d");
  1234. _glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)
  1235. get_extension_func("glMultiTexCoord2d");
  1236. _glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)
  1237. get_extension_func("glMultiTexCoord3d");
  1238. _glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)
  1239. get_extension_func("glMultiTexCoord4d");
  1240. #endif
  1241. } else if (has_extension("GL_ARB_multitexture")) {
  1242. supports_multitexture = true;
  1243. _glActiveTexture = (PFNGLACTIVETEXTUREPROC)
  1244. get_extension_func("glActiveTextureARB");
  1245. #ifdef SUPPORT_FIXED_FUNCTION
  1246. if (has_fixed_function_pipeline()) {
  1247. _glClientActiveTexture = (PFNGLACTIVETEXTUREPROC)
  1248. get_extension_func("glClientActiveTextureARB");
  1249. }
  1250. #endif
  1251. #ifdef SUPPORT_IMMEDIATE_MODE
  1252. _glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)
  1253. get_extension_func("glMultiTexCoord1fARB");
  1254. _glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)
  1255. get_extension_func("glMultiTexCoord2fARB");
  1256. _glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)
  1257. get_extension_func("glMultiTexCoord3fARB");
  1258. _glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)
  1259. get_extension_func("glMultiTexCoord4fARB");
  1260. _glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)
  1261. get_extension_func("glMultiTexCoord1dARB");
  1262. _glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)
  1263. get_extension_func("glMultiTexCoord2dARB");
  1264. _glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)
  1265. get_extension_func("glMultiTexCoord3dARB");
  1266. _glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)
  1267. get_extension_func("glMultiTexCoord4dARB");
  1268. #endif
  1269. } else {
  1270. supports_multitexture = false;
  1271. }
  1272. if (supports_multitexture) {
  1273. if (_glActiveTexture == nullptr
  1274. #ifdef SUPPORT_FIXED_FUNCTION
  1275. || (has_fixed_function_pipeline() && _glClientActiveTexture == nullptr)
  1276. #endif
  1277. #ifdef SUPPORT_IMMEDIATE_MODE
  1278. || GLf(_glMultiTexCoord1) == nullptr || GLf(_glMultiTexCoord2) == nullptr
  1279. || GLf(_glMultiTexCoord3) == nullptr || GLf(_glMultiTexCoord4) == nullptr
  1280. #endif
  1281. ) {
  1282. GLCAT.warning()
  1283. << "Multitexture advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1284. supports_multitexture = false;
  1285. }
  1286. }
  1287. if (!supports_multitexture) {
  1288. // Replace with dummy no-op functions.
  1289. _glActiveTexture = null_glActiveTexture;
  1290. }
  1291. #ifdef SUPPORT_FIXED_FUNCTION
  1292. if (!supports_multitexture || !has_fixed_function_pipeline()) {
  1293. _glClientActiveTexture = null_glActiveTexture;
  1294. }
  1295. #endif
  1296. #endif // OPENGLES_2
  1297. #ifdef OPENGLES_1
  1298. _supports_depth_texture = false;
  1299. _supports_depth_stencil = has_extension("GL_OES_packed_depth_stencil");
  1300. _supports_depth24 = has_extension("GL_OES_depth24");
  1301. _supports_depth32 = has_extension("GL_OES_depth32");
  1302. _supports_luminance_texture = true;
  1303. #elif defined(OPENGLES)
  1304. if (is_at_least_gles_version(3, 0)) {
  1305. _supports_depth_texture = true;
  1306. _supports_depth_stencil = true;
  1307. _supports_depth24 = true;
  1308. _supports_depth32 = true;
  1309. } else {
  1310. if (has_extension("GL_ANGLE_depth_texture")) {
  1311. // This extension provides both depth textures and depth-stencil support.
  1312. _supports_depth_texture = true;
  1313. _supports_depth_stencil = true;
  1314. } else if (has_extension("GL_OES_depth_texture")) {
  1315. _supports_depth_texture = true;
  1316. _supports_depth_stencil = has_extension("GL_OES_packed_depth_stencil");
  1317. }
  1318. _supports_depth24 = has_extension("GL_OES_depth24");
  1319. _supports_depth32 = has_extension("GL_OES_depth32");
  1320. }
  1321. _supports_luminance_texture = true;
  1322. #else
  1323. _supports_depth_texture = (is_at_least_gl_version(1, 4) ||
  1324. has_extension("GL_ARB_depth_texture"));
  1325. _supports_depth_stencil = (is_at_least_gl_version(3, 0) ||
  1326. has_extension("GL_ARB_framebuffer_object") ||
  1327. has_extension("GL_EXT_packed_depth_stencil"));
  1328. // OpenGL 3 deprecates luminance, luminance-alpha and alpha textures.
  1329. _supports_luminance_texture = !core_profile;
  1330. #endif
  1331. #ifdef OPENGLES_2
  1332. if (gl_support_shadow_filter && _supports_depth_texture &&
  1333. (is_at_least_gles_version(3, 0) || has_extension("GL_EXT_shadow_samplers"))) {
  1334. _supports_shadow_filter = true;
  1335. }
  1336. #else
  1337. if (gl_support_shadow_filter &&
  1338. _supports_depth_texture &&
  1339. (is_at_least_gl_version(1, 4) || has_extension("GL_ARB_shadow")) &&
  1340. (is_at_least_gl_version(2, 0) || has_extension("GL_ARB_fragment_program_shadow"))) {
  1341. _supports_shadow_filter = true;
  1342. }
  1343. #endif
  1344. // Actually, we can't keep forever disabling ARB_shadow on ATI cards, since
  1345. // they do work correctly now. Maybe there is some feature level we can
  1346. // check somewhere?
  1347. /*if (_gl_vendor.substr(0,3)=="ATI") {
  1348. // ATI drivers have never provided correct shadow support.
  1349. _supports_shadow_filter = false;
  1350. }*/
  1351. _supports_texture_combine = false;
  1352. _supports_texture_saved_result = false;
  1353. _supports_texture_dot3 = false;
  1354. #ifdef SUPPORT_FIXED_FUNCTION
  1355. if (has_fixed_function_pipeline()) {
  1356. _supports_texture_combine =
  1357. is_at_least_gl_version(1, 3) ||
  1358. is_at_least_gles_version(1, 1) ||
  1359. has_extension("GL_ARB_texture_env_combine");
  1360. #ifdef OPENGLES_1
  1361. _supports_texture_saved_result =
  1362. has_extension("GL_OES_texture_env_crossbar");
  1363. #else
  1364. _supports_texture_saved_result =
  1365. is_at_least_gl_version(1, 4) ||
  1366. has_extension("GL_ARB_texture_env_crossbar");
  1367. #endif
  1368. _supports_texture_dot3 =
  1369. is_at_least_gl_version(1, 3) ||
  1370. is_at_least_gles_version(1, 1) ||
  1371. has_extension("GL_ARB_texture_env_dot3");
  1372. }
  1373. #endif // SUPPORT_FIXED_FUNCTION
  1374. #ifdef OPENGLES_2
  1375. _supports_buffers = true;
  1376. _glGenBuffers = glGenBuffers;
  1377. _glBindBuffer = glBindBuffer;
  1378. _glBufferData = glBufferData;
  1379. _glBufferSubData = glBufferSubData;
  1380. _glDeleteBuffers = glDeleteBuffers;
  1381. #else
  1382. _supports_buffers = false;
  1383. if (is_at_least_gl_version(1, 5) || is_at_least_gles_version(1, 1)) {
  1384. _supports_buffers = true;
  1385. _glGenBuffers = (PFNGLGENBUFFERSPROC)
  1386. get_extension_func("glGenBuffers");
  1387. _glBindBuffer = (PFNGLBINDBUFFERPROC)
  1388. get_extension_func("glBindBuffer");
  1389. _glBufferData = (PFNGLBUFFERDATAPROC)
  1390. get_extension_func("glBufferData");
  1391. _glBufferSubData = (PFNGLBUFFERSUBDATAPROC)
  1392. get_extension_func("glBufferSubData");
  1393. _glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)
  1394. get_extension_func("glDeleteBuffers");
  1395. #ifndef OPENGLES
  1396. _glMapBuffer = (PFNGLMAPBUFFERPROC)
  1397. get_extension_func("glMapBuffer");
  1398. _glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)
  1399. get_extension_func("glUnmapBuffer");
  1400. _glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)
  1401. get_extension_func("glGetBufferSubData");
  1402. #endif
  1403. }
  1404. #ifndef OPENGLES_1
  1405. else if (has_extension("GL_ARB_vertex_buffer_object")) {
  1406. _supports_buffers = true;
  1407. _glGenBuffers = (PFNGLGENBUFFERSPROC)
  1408. get_extension_func("glGenBuffersARB");
  1409. _glBindBuffer = (PFNGLBINDBUFFERPROC)
  1410. get_extension_func("glBindBufferARB");
  1411. _glBufferData = (PFNGLBUFFERDATAPROC)
  1412. get_extension_func("glBufferDataARB");
  1413. _glBufferSubData = (PFNGLBUFFERSUBDATAPROC)
  1414. get_extension_func("glBufferSubDataARB");
  1415. _glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)
  1416. get_extension_func("glDeleteBuffersARB");
  1417. _glMapBuffer = (PFNGLMAPBUFFERPROC)
  1418. get_extension_func("glMapBufferARB");
  1419. _glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)
  1420. get_extension_func("glUnmapBufferARB");
  1421. _glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)
  1422. get_extension_func("glGetBufferSubDataARB");
  1423. }
  1424. #endif // OPENGLES_1
  1425. if (_supports_buffers) {
  1426. if (_glGenBuffers == nullptr || _glBindBuffer == nullptr ||
  1427. _glBufferData == nullptr || _glBufferSubData == nullptr ||
  1428. _glDeleteBuffers == nullptr) {
  1429. GLCAT.warning()
  1430. << "Buffers advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1431. _supports_buffers = false;
  1432. }
  1433. }
  1434. #endif
  1435. #ifdef OPENGLES
  1436. if (is_at_least_gles_version(3, 0)) {
  1437. _glMapBufferRange = (PFNGLMAPBUFFERRANGEEXTPROC)
  1438. get_extension_func("glMapBufferRange");
  1439. } else if (has_extension("GL_EXT_map_buffer_range")) {
  1440. _glMapBufferRange = (PFNGLMAPBUFFERRANGEEXTPROC)
  1441. get_extension_func("glMapBufferRangeEXT");
  1442. } else {
  1443. _glMapBufferRange = nullptr;
  1444. }
  1445. #else
  1446. // Check for various advanced buffer management features.
  1447. if (is_at_least_gl_version(3, 0) || has_extension("GL_ARB_map_buffer_range")) {
  1448. _glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)
  1449. get_extension_func("glMapBufferRange");
  1450. } else {
  1451. _glMapBufferRange = nullptr;
  1452. }
  1453. if (is_at_least_gl_version(4, 4) || has_extension("GL_ARB_buffer_storage")) {
  1454. _glBufferStorage = (PFNGLBUFFERSTORAGEPROC)
  1455. get_extension_func("glBufferStorage");
  1456. if (_glBufferStorage != nullptr) {
  1457. _supports_buffer_storage = true;
  1458. } else {
  1459. GLCAT.warning()
  1460. << "Buffer storage advertised as supported by OpenGL runtime, but "
  1461. "could not get pointers to extension function.\n";
  1462. }
  1463. } else {
  1464. _supports_buffer_storage = false;
  1465. }
  1466. #endif
  1467. _supports_vao = false;
  1468. #ifdef OPENGLES
  1469. if (is_at_least_gles_version(3, 0)) {
  1470. #else
  1471. if (is_at_least_gl_version(3, 0) || has_extension("GL_ARB_vertex_array_object")) {
  1472. #endif
  1473. _supports_vao = true;
  1474. _glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)
  1475. get_extension_func("glBindVertexArray");
  1476. _glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)
  1477. get_extension_func("glDeleteVertexArrays");
  1478. _glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)
  1479. get_extension_func("glGenVertexArrays");
  1480. #ifdef OPENGLES
  1481. } else if (has_extension("GL_OES_vertex_array_object")) {
  1482. _supports_vao = true;
  1483. _glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)
  1484. get_extension_func("glBindVertexArrayOES");
  1485. _glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)
  1486. get_extension_func("glDeleteVertexArraysOES");
  1487. _glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)
  1488. get_extension_func("glGenVertexArraysOES");
  1489. #endif
  1490. }
  1491. if (_supports_vao) {
  1492. if (_glBindVertexArray == nullptr || _glDeleteVertexArrays == nullptr ||
  1493. _glGenVertexArrays == nullptr) {
  1494. GLCAT.warning()
  1495. << "Vertex array objects advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1496. _supports_vao = false;
  1497. }
  1498. }
  1499. // Check for GLSL support.
  1500. #if defined(OPENGLES_1)
  1501. _supports_glsl = false;
  1502. _supports_geometry_shaders = false;
  1503. _supports_tessellation_shaders = false;
  1504. #elif defined(OPENGLES)
  1505. _supports_glsl = true;
  1506. _supports_geometry_shaders = false;
  1507. _supports_tessellation_shaders = false;
  1508. #else
  1509. _supports_glsl = (_gl_shadlang_ver_major >= 1);
  1510. _supports_tessellation_shaders = is_at_least_gl_version(4, 0) || has_extension("GL_ARB_tessellation_shader");
  1511. if (is_at_least_gl_version(3, 2)) {
  1512. _supports_geometry_shaders = true;
  1513. _glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREARBPROC)
  1514. get_extension_func("glFramebufferTexture");
  1515. } else if (has_extension("GL_ARB_geometry_shader4")) {
  1516. _supports_geometry_shaders = true;
  1517. _glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREARBPROC)
  1518. get_extension_func("glFramebufferTextureARB");
  1519. _glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)
  1520. get_extension_func("glProgramParameteriARB");
  1521. } else if (has_extension("GL_EXT_geometry_shader4")) {
  1522. _supports_geometry_shaders = true;
  1523. _glFramebufferTexture = nullptr;
  1524. _glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)
  1525. get_extension_func("glProgramParameteriEXT");
  1526. } else {
  1527. _supports_geometry_shaders = false;
  1528. _glFramebufferTexture = nullptr;
  1529. }
  1530. #endif
  1531. _shader_caps._supports_glsl = _supports_glsl;
  1532. // Check for support for other types of shaders that can be used by Cg.
  1533. _supports_basic_shaders = false;
  1534. #if defined(HAVE_CG) && !defined(OPENGLES)
  1535. if (has_extension("GL_ARB_vertex_program") &&
  1536. has_extension("GL_ARB_fragment_program")) {
  1537. _supports_basic_shaders = true;
  1538. _shader_caps._active_vprofile = (int)CG_PROFILE_ARBVP1;
  1539. _shader_caps._active_fprofile = (int)CG_PROFILE_ARBFP1;
  1540. _shader_caps._active_gprofile = (int)CG_PROFILE_UNKNOWN; // No geometry shader if only using basic
  1541. if (basic_shaders_only) {
  1542. // We're happy with ARB programs, thanks.
  1543. } else if (has_extension("GL_NV_gpu_program5")) {
  1544. _shader_caps._active_vprofile = (int)CG_PROFILE_GP5VP;
  1545. _shader_caps._active_fprofile = (int)CG_PROFILE_GP5FP;
  1546. _shader_caps._active_gprofile = (int)CG_PROFILE_GP5GP;
  1547. } else if (has_extension("GL_NV_gpu_program4")) {
  1548. _shader_caps._active_vprofile = (int)CG_PROFILE_GP4VP;
  1549. _shader_caps._active_fprofile = (int)CG_PROFILE_GP4FP;
  1550. _shader_caps._active_gprofile = (int)CG_PROFILE_GP4GP;
  1551. } else if (has_extension("GL_NV_vertex_program3") &&
  1552. has_extension("GL_NV_fragment_program2")) {
  1553. _shader_caps._active_vprofile = (int)CG_PROFILE_VP40;
  1554. _shader_caps._active_fprofile = (int)CG_PROFILE_FP40;
  1555. _shader_caps._active_gprofile = (int)CG_PROFILE_UNKNOWN;
  1556. } else if (has_extension("GL_NV_vertex_program2") &&
  1557. has_extension("GL_NV_fragment_program")) {
  1558. _shader_caps._active_vprofile = (int)CG_PROFILE_VP30;
  1559. _shader_caps._active_fprofile = (int)CG_PROFILE_FP30;
  1560. _shader_caps._active_gprofile = (int)CG_PROFILE_UNKNOWN;
  1561. } else if (has_extension("GL_NV_vertex_program1_1") &&
  1562. has_extension("GL_NV_texture_shader2") &&
  1563. has_extension("GL_NV_register_combiners2")) {
  1564. _shader_caps._active_vprofile = (int)CG_PROFILE_VP20;
  1565. _shader_caps._active_fprofile = (int)CG_PROFILE_FP20;
  1566. _shader_caps._active_gprofile = (int)CG_PROFILE_UNKNOWN;
  1567. } else if (_supports_glsl) {
  1568. // This is what will be available to non-NVIDIA cards. It is the last
  1569. // option since it is slower to compile GLSL than the other options.
  1570. _shader_caps._active_vprofile = (int)CG_PROFILE_GLSLV;
  1571. _shader_caps._active_fprofile = (int)CG_PROFILE_GLSLF;
  1572. if (_supports_geometry_shaders) {
  1573. _shader_caps._active_gprofile = (int)CG_PROFILE_GLSLG;
  1574. }
  1575. }
  1576. _shader_caps._ultimate_vprofile = (int)CG_PROFILE_GLSLV;
  1577. _shader_caps._ultimate_fprofile = (int)CG_PROFILE_GLSLF;
  1578. _shader_caps._ultimate_gprofile = (int)CG_PROFILE_GLSLG;
  1579. // Bug workaround for radeons.
  1580. if (_shader_caps._active_fprofile == CG_PROFILE_ARBFP1) {
  1581. if (has_extension("GL_ATI_draw_buffers")) {
  1582. _shader_caps._bug_list.insert(Shader::SBUG_ati_draw_buffers);
  1583. }
  1584. }
  1585. Shader::set_default_caps(_shader_caps);
  1586. } else if (_supports_glsl) {
  1587. // No, but we do support GLSL...
  1588. _shader_caps._active_vprofile = (int)CG_PROFILE_GLSLV;
  1589. _shader_caps._active_fprofile = (int)CG_PROFILE_GLSLF;
  1590. if (_supports_geometry_shaders) {
  1591. _shader_caps._active_gprofile = (int)CG_PROFILE_GLSLG;
  1592. } else {
  1593. _shader_caps._active_gprofile = (int)CG_PROFILE_UNKNOWN;
  1594. }
  1595. }
  1596. #endif // HAVE_CG
  1597. _supports_compute_shaders = false;
  1598. #ifndef OPENGLES_1
  1599. #ifdef OPENGLES
  1600. if (is_at_least_gles_version(3, 1)) {
  1601. #else
  1602. if (is_at_least_gl_version(4, 3) || has_extension("GL_ARB_compute_shader")) {
  1603. #endif
  1604. _glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC)
  1605. get_extension_func("glDispatchCompute");
  1606. if (_glDispatchCompute != nullptr) {
  1607. _supports_compute_shaders = true;
  1608. }
  1609. }
  1610. #endif // !OPENGLES_1
  1611. #ifndef OPENGLES
  1612. if (_supports_glsl) {
  1613. _glAttachShader = (PFNGLATTACHSHADERPROC)
  1614. get_extension_func("glAttachShader");
  1615. _glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)
  1616. get_extension_func("glBindAttribLocation");
  1617. _glCompileShader = (PFNGLCOMPILESHADERPROC)
  1618. get_extension_func("glCompileShader");
  1619. _glCreateProgram = (PFNGLCREATEPROGRAMPROC)
  1620. get_extension_func("glCreateProgram");
  1621. _glCreateShader = (PFNGLCREATESHADERPROC)
  1622. get_extension_func("glCreateShader");
  1623. _glDeleteProgram = (PFNGLDELETEPROGRAMPROC)
  1624. get_extension_func("glDeleteProgram");
  1625. _glDeleteShader = (PFNGLDELETESHADERPROC)
  1626. get_extension_func("glDeleteShader");
  1627. _glDetachShader = (PFNGLDETACHSHADERPROC)
  1628. get_extension_func("glDetachShader");
  1629. _glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)
  1630. get_extension_func("glDisableVertexAttribArray");
  1631. _glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)
  1632. get_extension_func("glEnableVertexAttribArray");
  1633. _glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)
  1634. get_extension_func("glGetActiveAttrib");
  1635. _glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)
  1636. get_extension_func("glGetActiveUniform");
  1637. _glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)
  1638. get_extension_func("glGetAttribLocation");
  1639. _glGetProgramiv = (PFNGLGETPROGRAMIVPROC)
  1640. get_extension_func("glGetProgramiv");
  1641. _glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)
  1642. get_extension_func("glGetProgramInfoLog");
  1643. _glGetShaderiv = (PFNGLGETSHADERIVPROC)
  1644. get_extension_func("glGetShaderiv");
  1645. _glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)
  1646. get_extension_func("glGetShaderInfoLog");
  1647. _glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)
  1648. get_extension_func("glGetUniformLocation");
  1649. _glLinkProgram = (PFNGLLINKPROGRAMPROC)
  1650. get_extension_func("glLinkProgram");
  1651. _glShaderSource = (PFNGLSHADERSOURCEPROC_P)
  1652. get_extension_func("glShaderSource");
  1653. _glUseProgram = (PFNGLUSEPROGRAMPROC)
  1654. get_extension_func("glUseProgram");
  1655. _glUniform4f = (PFNGLUNIFORM4FPROC)
  1656. get_extension_func("glUniform4f");
  1657. _glUniform1i = (PFNGLUNIFORM1IPROC)
  1658. get_extension_func("glUniform1i");
  1659. _glUniform1fv = (PFNGLUNIFORM1FVPROC)
  1660. get_extension_func("glUniform1fv");
  1661. _glUniform2fv = (PFNGLUNIFORM2FVPROC)
  1662. get_extension_func("glUniform2fv");
  1663. _glUniform3fv = (PFNGLUNIFORM3FVPROC)
  1664. get_extension_func("glUniform3fv");
  1665. _glUniform4fv = (PFNGLUNIFORM4FVPROC)
  1666. get_extension_func("glUniform4fv");
  1667. _glUniform1iv = (PFNGLUNIFORM1IVPROC)
  1668. get_extension_func("glUniform1iv");
  1669. _glUniform2iv = (PFNGLUNIFORM2IVPROC)
  1670. get_extension_func("glUniform2iv");
  1671. _glUniform3iv = (PFNGLUNIFORM3IVPROC)
  1672. get_extension_func("glUniform3iv");
  1673. _glUniform4iv = (PFNGLUNIFORM4IVPROC)
  1674. get_extension_func("glUniform4iv");
  1675. _glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)
  1676. get_extension_func("glUniformMatrix3fv");
  1677. _glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)
  1678. get_extension_func("glUniformMatrix4fv");
  1679. _glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)
  1680. get_extension_func("glValidateProgram");
  1681. _glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)
  1682. get_extension_func("glVertexAttrib4fv");
  1683. _glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)
  1684. get_extension_func("glVertexAttrib4dv");
  1685. _glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)
  1686. get_extension_func("glVertexAttribPointer");
  1687. if (is_at_least_gl_version(3, 0)) {
  1688. _glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)
  1689. get_extension_func("glBindFragDataLocation");
  1690. _glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)
  1691. get_extension_func("glVertexAttribIPointer");
  1692. _glUniform1uiv = (PFNGLUNIFORM1UIVPROC)
  1693. get_extension_func("glUniform1uiv");
  1694. _glUniform2uiv = (PFNGLUNIFORM2UIVPROC)
  1695. get_extension_func("glUniform2uiv");
  1696. _glUniform3uiv = (PFNGLUNIFORM3UIVPROC)
  1697. get_extension_func("glUniform3uiv");
  1698. _glUniform4uiv = (PFNGLUNIFORM4UIVPROC)
  1699. get_extension_func("glUniform4uiv");
  1700. } else if (has_extension("GL_EXT_gpu_shader4")) {
  1701. _glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)
  1702. get_extension_func("glBindFragDataLocationEXT");
  1703. _glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)
  1704. get_extension_func("glVertexAttribIPointerEXT");
  1705. _glUniform1uiv = (PFNGLUNIFORM1UIVPROC)
  1706. get_extension_func("glUniform1uivEXT");
  1707. _glUniform2uiv = (PFNGLUNIFORM2UIVPROC)
  1708. get_extension_func("glUniform2uivEXT");
  1709. _glUniform3uiv = (PFNGLUNIFORM3UIVPROC)
  1710. get_extension_func("glUniform3uivEXT");
  1711. _glUniform4uiv = (PFNGLUNIFORM4UIVPROC)
  1712. get_extension_func("glUniform4uivEXT");
  1713. } else {
  1714. _glBindFragDataLocation = nullptr;
  1715. _glVertexAttribIPointer = nullptr;
  1716. }
  1717. if (is_at_least_gl_version(4, 1) ||
  1718. has_extension("GL_ARB_vertex_attrib_64bit")) {
  1719. _glVertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC)
  1720. get_extension_func("glVertexAttribLPointer");
  1721. } else {
  1722. _glVertexAttribLPointer = nullptr;
  1723. }
  1724. if (_supports_tessellation_shaders) {
  1725. _glPatchParameteri = (PFNGLPATCHPARAMETERIPROC)
  1726. get_extension_func("glPatchParameteri");
  1727. }
  1728. } else if (_supports_basic_shaders) {
  1729. // We don't support GLSL, but we support ARB programs.
  1730. _glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)
  1731. get_extension_func("glDisableVertexAttribArrayARB");
  1732. _glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)
  1733. get_extension_func("glEnableVertexAttribArrayARB");
  1734. _glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)
  1735. get_extension_func("glVertexAttrib4fvARB");
  1736. _glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)
  1737. get_extension_func("glVertexAttrib4dvARB");
  1738. _glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)
  1739. get_extension_func("glVertexAttribPointerARB");
  1740. _glBindFragDataLocation = nullptr;
  1741. _glVertexAttribIPointer = nullptr;
  1742. _glVertexAttribLPointer = nullptr;
  1743. }
  1744. #endif
  1745. #ifdef OPENGLES_2
  1746. _glAttachShader = glAttachShader;
  1747. _glBindAttribLocation = glBindAttribLocation;
  1748. _glCompileShader = glCompileShader;
  1749. _glCreateProgram = glCreateProgram;
  1750. _glCreateShader = glCreateShader;
  1751. _glDeleteProgram = glDeleteProgram;
  1752. _glDeleteShader = glDeleteShader;
  1753. _glDetachShader = glDetachShader;
  1754. _glDisableVertexAttribArray = glDisableVertexAttribArray;
  1755. _glEnableVertexAttribArray = glEnableVertexAttribArray;
  1756. _glGetActiveAttrib = glGetActiveAttrib;
  1757. _glGetActiveUniform = glGetActiveUniform;
  1758. _glGetAttribLocation = glGetAttribLocation;
  1759. _glGetProgramiv = glGetProgramiv;
  1760. _glGetProgramInfoLog = glGetProgramInfoLog;
  1761. _glGetShaderiv = glGetShaderiv;
  1762. _glGetShaderInfoLog = glGetShaderInfoLog;
  1763. _glGetUniformLocation = glGetUniformLocation;
  1764. _glLinkProgram = glLinkProgram;
  1765. _glShaderSource = (PFNGLSHADERSOURCEPROC_P) glShaderSource;
  1766. _glUseProgram = glUseProgram;
  1767. _glUniform4f = glUniform4f;
  1768. _glUniform1i = glUniform1i;
  1769. _glUniform1fv = glUniform1fv;
  1770. _glUniform2fv = glUniform2fv;
  1771. _glUniform3fv = glUniform3fv;
  1772. _glUniform4fv = glUniform4fv;
  1773. _glUniform1iv = glUniform1iv;
  1774. _glUniform2iv = glUniform2iv;
  1775. _glUniform3iv = glUniform3iv;
  1776. _glUniform4iv = glUniform4iv;
  1777. _glUniformMatrix3fv = glUniformMatrix3fv;
  1778. _glUniformMatrix4fv = glUniformMatrix4fv;
  1779. _glValidateProgram = glValidateProgram;
  1780. _glVertexAttrib4fv = glVertexAttrib4fv;
  1781. _glVertexAttrib4dv = null_glVertexAttrib4dv;
  1782. _glVertexAttribPointer = glVertexAttribPointer;
  1783. _glVertexAttribLPointer = nullptr;
  1784. if (is_at_least_gles_version(3, 0)) {
  1785. _glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)
  1786. get_extension_func("glVertexAttribIPointer");
  1787. } else {
  1788. _glVertexAttribIPointer = nullptr;
  1789. }
  1790. if (has_extension("GL_EXT_blend_func_extended")) {
  1791. _glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)
  1792. get_extension_func("glBindFragDataLocationEXT");
  1793. } else {
  1794. _glBindFragDataLocation = nullptr;
  1795. }
  1796. #endif
  1797. #ifndef OPENGLES_1
  1798. _use_vertex_attrib_binding = false;
  1799. #ifdef OPENGLES
  1800. if (is_at_least_gles_version(3, 1)) {
  1801. #else
  1802. if (is_at_least_gl_version(4, 3) || has_extension("GL_ARB_vertex_attrib_binding")) {
  1803. #endif
  1804. _glBindVertexBuffer = (PFNGLBINDVERTEXBUFFERPROC)
  1805. get_extension_func("glBindVertexBuffer");
  1806. _glVertexAttribFormat = (PFNGLVERTEXATTRIBFORMATPROC)
  1807. get_extension_func("glVertexAttribFormat");
  1808. _glVertexAttribIFormat = (PFNGLVERTEXATTRIBIFORMATPROC)
  1809. get_extension_func("glVertexAttribIFormat");
  1810. _glVertexAttribBinding = (PFNGLVERTEXATTRIBBINDINGPROC)
  1811. get_extension_func("glVertexAttribBinding");
  1812. _glVertexBindingDivisor = (PFNGLVERTEXBINDINGDIVISORPROC)
  1813. get_extension_func("glVertexBindingDivisor");
  1814. #ifndef OPENGLES
  1815. _glVertexAttribLFormat = (PFNGLVERTEXATTRIBLFORMATPROC)
  1816. get_extension_func("glVertexAttribLFormat");
  1817. #endif
  1818. if (gl_fixed_vertex_attrib_locations) {
  1819. _use_vertex_attrib_binding = true;
  1820. }
  1821. }
  1822. #endif
  1823. // We need to have a default shader to apply in case something didn't happen
  1824. // to have a shader applied, or if it failed to compile. This default
  1825. // shader just outputs a red color, indicating that something went wrong.
  1826. #ifndef OPENGLES_1
  1827. if (_default_shader == nullptr && !has_fixed_function_pipeline()) {
  1828. #ifndef OPENGLES
  1829. bool use_float64 = vertices_float64;
  1830. if (use_float64 && is_at_least_gl_version(4, 1)) {
  1831. _default_shader = Shader::make(Shader::SL_GLSL, default_vshader_fp64_gl41, default_fshader);
  1832. } else if (use_float64 && has_extension("GL_ARB_vertex_attrib_64bit")) {
  1833. _default_shader = Shader::make(Shader::SL_GLSL, default_vshader_fp64, default_fshader);
  1834. } else
  1835. #endif
  1836. {
  1837. _default_shader = Shader::make(Shader::SL_GLSL, default_vshader, default_fshader);
  1838. }
  1839. }
  1840. #endif
  1841. #ifndef OPENGLES_1
  1842. // Check for uniform buffers.
  1843. #ifdef OPENGLES
  1844. if (is_at_least_gl_version(3, 1) || has_extension("GL_ARB_uniform_buffer_object")) {
  1845. #else
  1846. if (is_at_least_gles_version(3, 0)) {
  1847. #endif
  1848. _supports_uniform_buffers = true;
  1849. _glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC)
  1850. get_extension_func("glGetActiveUniformsiv");
  1851. _glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)
  1852. get_extension_func("glGetActiveUniformBlockiv");
  1853. _glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)
  1854. get_extension_func("glGetActiveUniformBlockName");
  1855. } else {
  1856. _supports_uniform_buffers = false;
  1857. }
  1858. #ifndef OPENGLES
  1859. // Check for SSBOs.
  1860. if (is_at_least_gl_version(4, 3) || has_extension("ARB_shader_storage_buffer_object")) {
  1861. _supports_shader_buffers = true;
  1862. _glGetProgramInterfaceiv = (PFNGLGETPROGRAMINTERFACEIVPROC)
  1863. get_extension_func("glGetProgramInterfaceiv");
  1864. _glGetProgramResourceName = (PFNGLGETPROGRAMRESOURCENAMEPROC)
  1865. get_extension_func("glGetProgramResourceName");
  1866. _glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC)
  1867. get_extension_func("glGetProgramResourceiv");
  1868. } else
  1869. #endif
  1870. {
  1871. _supports_shader_buffers = false;
  1872. }
  1873. if (_supports_uniform_buffers || _supports_shader_buffers) {
  1874. _glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)
  1875. get_extension_func("glBindBufferBase");
  1876. }
  1877. #endif
  1878. // Check whether we support geometry instancing and instanced vertex
  1879. // attribs.
  1880. #if defined(OPENGLES_1)
  1881. _supports_vertex_attrib_divisor = false;
  1882. _supports_geometry_instancing = false;
  1883. #elif defined(OPENGLES)
  1884. if (is_at_least_gles_version(3, 0)) {
  1885. // OpenGL ES 3 has all of this in the core.
  1886. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1887. get_extension_func("glVertexAttribDivisor");
  1888. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1889. get_extension_func("glDrawArraysInstanced");
  1890. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1891. get_extension_func("glDrawElementsInstanced");
  1892. _supports_vertex_attrib_divisor = true;
  1893. _supports_geometry_instancing = true;
  1894. } else if (has_extension("GL_ANGLE_instanced_arrays")) {
  1895. // This extension has both things in one.
  1896. #ifdef __EMSCRIPTEN__
  1897. // Work around bug - it doesn't allow ANGLE suffix in getProcAddress.
  1898. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1899. get_extension_func("glVertexAttribDivisor");
  1900. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1901. get_extension_func("glDrawArraysInstanced");
  1902. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1903. get_extension_func("glDrawElementsInstanced");
  1904. #else
  1905. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1906. get_extension_func("glVertexAttribDivisorANGLE");
  1907. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1908. get_extension_func("glDrawArraysInstancedANGLE");
  1909. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1910. get_extension_func("glDrawElementsInstancedANGLE");
  1911. #endif
  1912. _supports_vertex_attrib_divisor = true;
  1913. _supports_geometry_instancing = true;
  1914. } else {
  1915. // Check separately for geometry instancing and instanced attribs.
  1916. if (has_extension("GL_EXT_draw_instanced")) {
  1917. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1918. get_extension_func("glDrawArraysInstancedEXT");
  1919. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1920. get_extension_func("glDrawElementsInstancedEXT");
  1921. _supports_geometry_instancing = true;
  1922. } else if (has_extension("GL_NV_draw_instanced")) {
  1923. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1924. get_extension_func("glDrawArraysInstancedNV");
  1925. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1926. get_extension_func("glDrawElementsInstancedNV");
  1927. _supports_geometry_instancing = true;
  1928. } else {
  1929. _supports_geometry_instancing = false;
  1930. }
  1931. if (has_extension("GL_EXT_instanced_arrays")) {
  1932. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1933. get_extension_func("glVertexAttribDivisorEXT");
  1934. _supports_vertex_attrib_divisor = true;
  1935. } else if (has_extension("GL_NV_instanced_arrays")) {
  1936. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1937. get_extension_func("glVertexAttribDivisorNV");
  1938. _supports_vertex_attrib_divisor = true;
  1939. } else {
  1940. _supports_vertex_attrib_divisor = false;
  1941. }
  1942. }
  1943. #else
  1944. if (is_at_least_gl_version(3, 3)) {
  1945. // This feature is in OpenGL core as of 3.3.
  1946. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1947. get_extension_func("glVertexAttribDivisor");
  1948. _supports_vertex_attrib_divisor = true;
  1949. } else if (has_extension("GL_ARB_instanced_arrays")) {
  1950. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1951. get_extension_func("glVertexAttribDivisorARB");
  1952. _supports_vertex_attrib_divisor = true;
  1953. } else {
  1954. _supports_vertex_attrib_divisor = false;
  1955. }
  1956. // Some drivers expose one extension, some expose the other.
  1957. if (is_at_least_gl_version(3, 1)) {
  1958. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1959. get_extension_func("glDrawArraysInstanced");
  1960. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1961. get_extension_func("glDrawElementsInstanced");
  1962. _supports_geometry_instancing = true;
  1963. } else if (has_extension("GL_ARB_draw_instanced")) {
  1964. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1965. get_extension_func("glDrawArraysInstancedARB");
  1966. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1967. get_extension_func("glDrawElementsInstancedARB");
  1968. _supports_geometry_instancing = true;
  1969. } else if (has_extension("GL_EXT_draw_instanced")) {
  1970. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1971. get_extension_func("glDrawArraysInstancedEXT");
  1972. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1973. get_extension_func("glDrawElementsInstancedEXT");
  1974. _supports_geometry_instancing = true;
  1975. } else {
  1976. _glDrawElementsInstanced = 0;
  1977. _glDrawArraysInstanced = 0;
  1978. _supports_geometry_instancing = false;
  1979. }
  1980. #endif
  1981. #ifndef OPENGLES_1
  1982. if (_supports_geometry_instancing) {
  1983. if (_glDrawArraysInstanced == nullptr || _glDrawElementsInstanced == nullptr) {
  1984. GLCAT.warning()
  1985. << "Geometry instancing advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1986. _supports_geometry_instancing = false;
  1987. }
  1988. }
  1989. if (_supports_vertex_attrib_divisor) {
  1990. if (_glVertexAttribDivisor == nullptr) {
  1991. GLCAT.warning()
  1992. << "Instanced vertex arrays advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1993. _supports_vertex_attrib_divisor = false;
  1994. }
  1995. }
  1996. #endif
  1997. // Check if we support indirect draw.
  1998. _supports_indirect_draw = false;
  1999. #ifndef OPENGLES_1
  2000. #ifdef OPENGLES
  2001. if (is_at_least_gles_version(3, 1)) {
  2002. #else
  2003. if (is_at_least_gl_version(4, 0) || has_extension("GL_ARB_draw_indirect")) {
  2004. #endif
  2005. _glDrawArraysIndirect = (PFNGLDRAWARRAYSINDIRECTPROC)
  2006. get_extension_func("glDrawArraysIndirect");
  2007. _glDrawElementsIndirect = (PFNGLDRAWELEMENTSINDIRECTPROC)
  2008. get_extension_func("glDrawElementsIndirect");
  2009. if (_glDrawArraysIndirect == nullptr || _glDrawElementsIndirect == nullptr) {
  2010. GLCAT.warning()
  2011. << "Indirect draw advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  2012. } else {
  2013. _supports_indirect_draw = true;
  2014. }
  2015. }
  2016. #endif
  2017. #ifdef OPENGLES_1
  2018. _supports_framebuffer_multisample = false;
  2019. _supports_framebuffer_blit = false;
  2020. if (has_extension("GL_OES_framebuffer_object")) {
  2021. _supports_framebuffer_object = true;
  2022. _glIsRenderbuffer = (PFNGLISRENDERBUFFEROESPROC)
  2023. get_extension_func("glIsRenderbufferOES");
  2024. _glBindRenderbuffer = (PFNGLBINDRENDERBUFFEROESPROC)
  2025. get_extension_func("glBindRenderbufferOES");
  2026. _glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSOESPROC)
  2027. get_extension_func("glDeleteRenderbuffersOES");
  2028. _glGenRenderbuffers = (PFNGLGENRENDERBUFFERSOESPROC)
  2029. get_extension_func("glGenRenderbuffersOES");
  2030. _glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEOESPROC)
  2031. get_extension_func("glRenderbufferStorageOES");
  2032. _glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVOESPROC)
  2033. get_extension_func("glGetRenderbufferParameterivOES");
  2034. _glIsFramebuffer = (PFNGLISFRAMEBUFFEROESPROC)
  2035. get_extension_func("glIsFramebufferOES");
  2036. _glBindFramebuffer = (PFNGLBINDFRAMEBUFFEROESPROC)
  2037. get_extension_func("glBindFramebufferOES");
  2038. _glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSOESPROC)
  2039. get_extension_func("glDeleteFramebuffersOES");
  2040. _glGenFramebuffers = (PFNGLGENFRAMEBUFFERSOESPROC)
  2041. get_extension_func("glGenFramebuffersOES");
  2042. _glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSOESPROC)
  2043. get_extension_func("glCheckFramebufferStatusOES");
  2044. _glFramebufferTexture1D = nullptr;
  2045. _glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DOESPROC)
  2046. get_extension_func("glFramebufferTexture2DOES");
  2047. _glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFEROESPROC)
  2048. get_extension_func("glFramebufferRenderbufferOES");
  2049. _glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVOESPROC)
  2050. get_extension_func("glGetFramebufferAttachmentParameterivOES");
  2051. _glGenerateMipmap = (PFNGLGENERATEMIPMAPOESPROC)
  2052. get_extension_func("glGenerateMipmapOES");
  2053. } else {
  2054. _supports_framebuffer_object = false;
  2055. _glGenerateMipmap = nullptr;
  2056. }
  2057. #elif defined(OPENGLES)
  2058. // In OpenGL ES 2.x, FBO's are supported in the core.
  2059. _supports_framebuffer_object = true;
  2060. _glIsRenderbuffer = glIsRenderbuffer;
  2061. _glBindRenderbuffer = glBindRenderbuffer;
  2062. _glDeleteRenderbuffers = glDeleteRenderbuffers;
  2063. _glGenRenderbuffers = glGenRenderbuffers;
  2064. _glRenderbufferStorage = glRenderbufferStorage;
  2065. _glGetRenderbufferParameteriv = glGetRenderbufferParameteriv;
  2066. _glIsFramebuffer = glIsFramebuffer;
  2067. _glBindFramebuffer = glBindFramebuffer;
  2068. _glDeleteFramebuffers = glDeleteFramebuffers;
  2069. _glGenFramebuffers = glGenFramebuffers;
  2070. _glCheckFramebufferStatus = glCheckFramebufferStatus;
  2071. _glFramebufferTexture1D = nullptr;
  2072. _glFramebufferTexture2D = glFramebufferTexture2D;
  2073. _glFramebufferRenderbuffer = glFramebufferRenderbuffer;
  2074. _glGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameteriv;
  2075. _glGenerateMipmap = glGenerateMipmap;
  2076. if (is_at_least_gles_version(3, 0)) {
  2077. _supports_framebuffer_multisample = true;
  2078. _supports_framebuffer_blit = true;
  2079. _glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)
  2080. get_extension_func("glRenderbufferStorageMultisample");
  2081. _glBlitFramebuffer = (PFNGLBLITFRAMEBUFFEREXTPROC)
  2082. get_extension_func("glBlitFramebuffer");
  2083. } else {
  2084. if (has_extension("GL_ANGLE_framebuffer_multisample")) {
  2085. _supports_framebuffer_multisample = true;
  2086. _glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC)
  2087. get_extension_func("glRenderbufferStorageMultisampleANGLE");
  2088. } else {
  2089. _supports_framebuffer_multisample = false;
  2090. }
  2091. if (has_extension("GL_ANGLE_framebuffer_blit")) {
  2092. _supports_framebuffer_blit = true;
  2093. _glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERANGLEPROC)
  2094. get_extension_func("glBlitFramebufferANGLE");
  2095. } else {
  2096. _supports_framebuffer_blit = false;
  2097. }
  2098. }
  2099. #else // Desktop OpenGL case.
  2100. if (is_at_least_gl_version(3, 0) || has_extension("GL_ARB_framebuffer_object")) {
  2101. _supports_framebuffer_object = true;
  2102. _supports_framebuffer_multisample = true;
  2103. _supports_framebuffer_blit = true;
  2104. _glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)
  2105. get_extension_func("glIsRenderbuffer");
  2106. _glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)
  2107. get_extension_func("glBindRenderbuffer");
  2108. _glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)
  2109. get_extension_func("glDeleteRenderbuffers");
  2110. _glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)
  2111. get_extension_func("glGenRenderbuffers");
  2112. _glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)
  2113. get_extension_func("glRenderbufferStorage");
  2114. _glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)
  2115. get_extension_func("glGetRenderbufferParameteriv");
  2116. _glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)
  2117. get_extension_func("glIsFramebuffer");
  2118. _glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)
  2119. get_extension_func("glBindFramebuffer");
  2120. _glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)
  2121. get_extension_func("glDeleteFramebuffers");
  2122. _glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)
  2123. get_extension_func("glGenFramebuffers");
  2124. _glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)
  2125. get_extension_func("glCheckFramebufferStatus");
  2126. _glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)
  2127. get_extension_func("glFramebufferTexture1D");
  2128. _glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)
  2129. get_extension_func("glFramebufferTexture2D");
  2130. _glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)
  2131. get_extension_func("glFramebufferTexture3D");
  2132. _glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)
  2133. get_extension_func("glFramebufferRenderbuffer");
  2134. _glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)
  2135. get_extension_func("glGetFramebufferAttachmentParameteriv");
  2136. _glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)
  2137. get_extension_func("glGenerateMipmap");
  2138. _glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)
  2139. get_extension_func("glRenderbufferStorageMultisample");
  2140. _glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)
  2141. get_extension_func("glBlitFramebuffer");
  2142. } else if (has_extension("GL_EXT_framebuffer_object")) {
  2143. _supports_framebuffer_object = true;
  2144. _glIsRenderbuffer = (PFNGLISRENDERBUFFEREXTPROC)
  2145. get_extension_func("glIsRenderbufferEXT");
  2146. _glBindRenderbuffer = (PFNGLBINDRENDERBUFFEREXTPROC)
  2147. get_extension_func("glBindRenderbufferEXT");
  2148. _glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSEXTPROC)
  2149. get_extension_func("glDeleteRenderbuffersEXT");
  2150. _glGenRenderbuffers = (PFNGLGENRENDERBUFFERSEXTPROC)
  2151. get_extension_func("glGenRenderbuffersEXT");
  2152. _glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEEXTPROC)
  2153. get_extension_func("glRenderbufferStorageEXT");
  2154. _glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)
  2155. get_extension_func("glGetRenderbufferParameterivEXT");
  2156. _glIsFramebuffer = (PFNGLISFRAMEBUFFEREXTPROC)
  2157. get_extension_func("glIsFramebufferEXT");
  2158. _glBindFramebuffer = (PFNGLBINDFRAMEBUFFEREXTPROC)
  2159. get_extension_func("glBindFramebufferEXT");
  2160. _glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSEXTPROC)
  2161. get_extension_func("glDeleteFramebuffersEXT");
  2162. _glGenFramebuffers = (PFNGLGENFRAMEBUFFERSEXTPROC)
  2163. get_extension_func("glGenFramebuffersEXT");
  2164. _glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
  2165. get_extension_func("glCheckFramebufferStatusEXT");
  2166. _glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)
  2167. get_extension_func("glFramebufferTexture1DEXT");
  2168. _glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)
  2169. get_extension_func("glFramebufferTexture2DEXT");
  2170. _glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)
  2171. get_extension_func("glFramebufferTexture3DEXT");
  2172. _glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)
  2173. get_extension_func("glFramebufferRenderbufferEXT");
  2174. _glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)
  2175. get_extension_func("glGetFramebufferAttachmentParameterivEXT");
  2176. _glGenerateMipmap = (PFNGLGENERATEMIPMAPEXTPROC)
  2177. get_extension_func("glGenerateMipmapEXT");
  2178. if (has_extension("GL_EXT_framebuffer_multisample")) {
  2179. _supports_framebuffer_multisample = true;
  2180. _glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)
  2181. get_extension_func("glRenderbufferStorageMultisampleEXT");
  2182. } else {
  2183. _supports_framebuffer_multisample = false;
  2184. }
  2185. if (has_extension("GL_EXT_framebuffer_blit")) {
  2186. _supports_framebuffer_blit = true;
  2187. _glBlitFramebuffer = (PFNGLBLITFRAMEBUFFEREXTPROC)
  2188. get_extension_func("glBlitFramebufferEXT");
  2189. } else {
  2190. _supports_framebuffer_blit = false;
  2191. }
  2192. } else {
  2193. _supports_framebuffer_object = false;
  2194. _supports_framebuffer_multisample = false;
  2195. _supports_framebuffer_blit = false;
  2196. _glGenerateMipmap = nullptr;
  2197. }
  2198. #endif
  2199. #ifndef OPENGLES
  2200. if (is_at_least_gl_version(4, 5) || has_extension("GL_ARB_direct_state_access")) {
  2201. _glGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC)
  2202. get_extension_func("glGenerateTextureMipmap");
  2203. _supports_dsa = true;
  2204. } else {
  2205. _supports_dsa = false;
  2206. }
  2207. #endif
  2208. #ifndef OPENGLES_1
  2209. // Do we support empty framebuffer objects?
  2210. #ifdef OPENGLES
  2211. if (is_at_least_gles_version(3, 1)) {
  2212. #else
  2213. if (is_at_least_gl_version(4, 3) || has_extension("GL_ARB_framebuffer_no_attachments")) {
  2214. #endif
  2215. _glFramebufferParameteri = (PFNGLFRAMEBUFFERPARAMETERIPROC)
  2216. get_extension_func("glFramebufferParameteri");
  2217. _supports_empty_framebuffer = true;
  2218. } else {
  2219. _supports_empty_framebuffer = false;
  2220. }
  2221. #endif // !OPENGLES_1
  2222. #ifndef OPENGLES
  2223. _supports_framebuffer_multisample_coverage_nv = false;
  2224. if (_supports_framebuffer_multisample &&
  2225. has_extension("GL_NV_framebuffer_multisample_coverage")) {
  2226. _supports_framebuffer_multisample_coverage_nv = true;
  2227. _glRenderbufferStorageMultisampleCoverage = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC)
  2228. get_extension_func("glRenderbufferStorageMultisampleCoverageNV");
  2229. }
  2230. #endif
  2231. #if defined(OPENGLES_1)
  2232. _glDrawBuffers = nullptr;
  2233. _max_color_targets = 1;
  2234. #elif defined(OPENGLES_2)
  2235. if (is_at_least_gles_version(3, 0)) {
  2236. _glDrawBuffers = (PFNGLDRAWBUFFERSPROC)
  2237. get_extension_func("glDrawBuffers");
  2238. } else if (has_extension("GL_EXT_draw_buffers")) {
  2239. _glDrawBuffers = (PFNGLDRAWBUFFERSPROC)
  2240. get_extension_func("glDrawBuffersEXT");
  2241. } else if (has_extension("GL_NV_draw_buffers")) {
  2242. _glDrawBuffers = (PFNGLDRAWBUFFERSPROC)
  2243. get_extension_func("glDrawBuffersNV");
  2244. } else {
  2245. _glDrawBuffers = nullptr;
  2246. }
  2247. #else
  2248. if (is_at_least_gl_version(2, 0)) {
  2249. _glDrawBuffers = (PFNGLDRAWBUFFERSPROC)
  2250. get_extension_func("glDrawBuffers");
  2251. } else if (has_extension("GL_ARB_draw_buffers")) {
  2252. _glDrawBuffers = (PFNGLDRAWBUFFERSPROC)
  2253. get_extension_func("glDrawBuffersARB");
  2254. } else {
  2255. _glDrawBuffers = nullptr;
  2256. }
  2257. #endif
  2258. #if defined(OPENGLES) && !defined(OPENGLES_1)
  2259. if (is_at_least_gles_version(3, 0)) {
  2260. _glReadBuffer = (PFNGLREADBUFFERPROC)
  2261. get_extension_func("glReadBuffer");
  2262. } else if (has_extension("GL_NV_read_buffer")) {
  2263. _glReadBuffer = (PFNGLREADBUFFERPROC)
  2264. get_extension_func("glReadBufferNV");
  2265. } else {
  2266. _glReadBuffer = nullptr;
  2267. }
  2268. #endif
  2269. #ifndef OPENGLES_1
  2270. _max_color_targets = 1;
  2271. if (_glDrawBuffers != nullptr) {
  2272. GLint max_draw_buffers = 0;
  2273. glGetIntegerv(GL_MAX_DRAW_BUFFERS, &max_draw_buffers);
  2274. _max_color_targets = max_draw_buffers;
  2275. }
  2276. #endif // !OPENGLES_1
  2277. #ifndef OPENGLES_1
  2278. if (_gl_version_major >= 3) {
  2279. _glClearBufferfv = (PFNGLCLEARBUFFERFVPROC)
  2280. get_extension_func("glClearBufferfv");
  2281. _glClearBufferiv = (PFNGLCLEARBUFFERIVPROC)
  2282. get_extension_func("glClearBufferiv");
  2283. _glClearBufferfi = (PFNGLCLEARBUFFERFIPROC)
  2284. get_extension_func("glClearBufferfi");
  2285. } else {
  2286. _glClearBufferfv = nullptr;
  2287. _glClearBufferiv = nullptr;
  2288. _glClearBufferfi = nullptr;
  2289. }
  2290. #endif // !OPENGLES
  2291. #ifndef OPENGLES
  2292. _supports_viewport_arrays = false;
  2293. if (is_at_least_gl_version(4, 1) || has_extension("GL_ARB_viewport_array")) {
  2294. _glViewportArrayv = (PFNGLVIEWPORTARRAYVPROC)
  2295. get_extension_func("glViewportArrayv");
  2296. _glScissorArrayv = (PFNGLSCISSORARRAYVPROC)
  2297. get_extension_func("glScissorArrayv");
  2298. _glDepthRangeArrayv = (PFNGLDEPTHRANGEARRAYVPROC)
  2299. get_extension_func("glDepthRangeArrayv");
  2300. if (_glViewportArrayv == nullptr || _glScissorArrayv == nullptr || _glDepthRangeArrayv == nullptr) {
  2301. GLCAT.warning()
  2302. << "Viewport arrays advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  2303. } else {
  2304. _supports_viewport_arrays = true;
  2305. }
  2306. }
  2307. #endif // !OPENGLES
  2308. _max_fb_samples = 0;
  2309. if (_supports_framebuffer_multisample) {
  2310. GLint max_samples;
  2311. glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_samples);
  2312. _max_fb_samples = max_samples;
  2313. }
  2314. _supports_occlusion_query = false;
  2315. #ifndef OPENGLES
  2316. if (gl_support_occlusion_query) {
  2317. if (is_at_least_gl_version(1, 5)) {
  2318. _supports_occlusion_query = true;
  2319. _glGenQueries = (PFNGLGENQUERIESPROC)
  2320. get_extension_func("glGenQueries");
  2321. _glBeginQuery = (PFNGLBEGINQUERYPROC)
  2322. get_extension_func("glBeginQuery");
  2323. _glEndQuery = (PFNGLENDQUERYPROC)
  2324. get_extension_func("glEndQuery");
  2325. _glDeleteQueries = (PFNGLDELETEQUERIESPROC)
  2326. get_extension_func("glDeleteQueries");
  2327. _glGetQueryiv = (PFNGLGETQUERYIVPROC)
  2328. get_extension_func("glGetQueryiv");
  2329. _glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)
  2330. get_extension_func("glGetQueryObjectuiv");
  2331. } else if (has_extension("GL_ARB_occlusion_query")) {
  2332. _supports_occlusion_query = true;
  2333. _glGenQueries = (PFNGLGENQUERIESPROC)
  2334. get_extension_func("glGenQueriesARB");
  2335. _glBeginQuery = (PFNGLBEGINQUERYPROC)
  2336. get_extension_func("glBeginQueryARB");
  2337. _glEndQuery = (PFNGLENDQUERYPROC)
  2338. get_extension_func("glEndQueryARB");
  2339. _glDeleteQueries = (PFNGLDELETEQUERIESPROC)
  2340. get_extension_func("glDeleteQueriesARB");
  2341. _glGetQueryiv = (PFNGLGETQUERYIVPROC)
  2342. get_extension_func("glGetQueryivARB");
  2343. _glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)
  2344. get_extension_func("glGetQueryObjectuivARB");
  2345. }
  2346. }
  2347. if (_supports_occlusion_query) {
  2348. if (_glGenQueries == nullptr || _glBeginQuery == nullptr ||
  2349. _glEndQuery == nullptr || _glDeleteQueries == nullptr ||
  2350. _glGetQueryiv == nullptr || _glGetQueryObjectuiv == nullptr) {
  2351. GLCAT.warning()
  2352. << "Occlusion queries advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  2353. _supports_occlusion_query = false;
  2354. } else {
  2355. GLint num_bits;
  2356. _glGetQueryiv(GL_SAMPLES_PASSED, GL_QUERY_COUNTER_BITS, &num_bits);
  2357. if (num_bits == 0) {
  2358. _supports_occlusion_query = false;
  2359. }
  2360. if (GLCAT.is_debug()) {
  2361. GLCAT.debug()
  2362. << "Occlusion query counter provides " << num_bits << " bits.\n";
  2363. }
  2364. }
  2365. }
  2366. #endif // !OPENGLES
  2367. _supports_timer_query = false;
  2368. #if defined(DO_PSTATS) && !defined(OPENGLES)
  2369. if (is_at_least_gl_version(3, 3) || has_extension("GL_ARB_timer_query")) {
  2370. _supports_timer_query = true;
  2371. _glQueryCounter = (PFNGLQUERYCOUNTERPROC)
  2372. get_extension_func("glQueryCounter");
  2373. _glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC)
  2374. get_extension_func("glGetQueryObjecti64v");
  2375. _glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC)
  2376. get_extension_func("glGetQueryObjectui64v");
  2377. _glGetInteger64v = (PFNGLGETINTEGER64VPROC)
  2378. get_extension_func("glGetInteger64v");
  2379. }
  2380. #endif
  2381. #ifdef OPENGLES_1
  2382. // In OpenGL ES 1, blending is supported via extensions.
  2383. if (has_extension("GL_OES_blend_subtract")) {
  2384. _glBlendEquation = (PFNGLBLENDEQUATIONPROC)
  2385. get_extension_func("glBlendEquationOES");
  2386. if (_glBlendEquation == nullptr) {
  2387. _glBlendEquation = null_glBlendEquation;
  2388. GLCAT.warning()
  2389. << "BlendEquationOES advertised as supported by OpenGL ES runtime, but "
  2390. "could not get pointer to extension function.\n";
  2391. }
  2392. } else {
  2393. _glBlendEquation = null_glBlendEquation;
  2394. }
  2395. if (has_extension("GL_OES_blend_equation_separate")) {
  2396. _glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEOESPROC)
  2397. get_extension_func("glBlendEquationSeparateOES");
  2398. if (_glBlendEquation == nullptr) {
  2399. _supports_blend_equation_separate = false;
  2400. GLCAT.warning()
  2401. << "BlendEquationSeparateOES advertised as supported by OpenGL ES "
  2402. "runtime, but could not get pointer to extension function.\n";
  2403. } else {
  2404. _supports_blend_equation_separate = true;
  2405. }
  2406. } else {
  2407. _supports_blend_equation_separate = false;
  2408. _glBlendEquationSeparate = nullptr;
  2409. }
  2410. if (has_extension("GL_OES_blend_func_separate")) {
  2411. _glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEOESPROC)
  2412. get_extension_func("glBlendFuncSeparateOES");
  2413. if (_glBlendFuncSeparate == nullptr) {
  2414. _glBlendFuncSeparate = null_glBlendFuncSeparate;
  2415. GLCAT.warning()
  2416. << "BlendFuncSeparateOES advertised as supported by OpenGL ES runtime, but "
  2417. "could not get pointer to extension function.\n";
  2418. }
  2419. } else {
  2420. _glBlendFuncSeparate = null_glBlendFuncSeparate;
  2421. }
  2422. #elif defined(OPENGLES)
  2423. // In OpenGL ES 2.x and above, this is supported in the core.
  2424. _supports_blend_equation_separate = false;
  2425. #else
  2426. if (is_at_least_gl_version(1, 2)) {
  2427. _glBlendEquation = (PFNGLBLENDEQUATIONPROC)
  2428. get_extension_func("glBlendEquation");
  2429. } else if (has_extension("GL_EXT_blend_minmax")) {
  2430. _glBlendEquation = (PFNGLBLENDEQUATIONPROC)
  2431. get_extension_func("glBlendEquationEXT");
  2432. } else {
  2433. _glBlendEquation = null_glBlendEquation;
  2434. }
  2435. if (_glBlendEquation == nullptr) {
  2436. _glBlendEquation = null_glBlendEquation;
  2437. GLCAT.warning()
  2438. << "BlendEquation advertised as supported by OpenGL runtime, but could "
  2439. "not get pointer to extension function.\n";
  2440. }
  2441. if (is_at_least_gl_version(2, 0)) {
  2442. _supports_blend_equation_separate = true;
  2443. _glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)
  2444. get_extension_func("glBlendEquationSeparate");
  2445. } else if (has_extension("GL_EXT_blend_equation_separate")) {
  2446. _supports_blend_equation_separate = true;
  2447. _glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEEXTPROC)
  2448. get_extension_func("glBlendEquationSeparateEXT");
  2449. } else {
  2450. _supports_blend_equation_separate = false;
  2451. _glBlendEquationSeparate = nullptr;
  2452. }
  2453. if (_supports_blend_equation_separate && _glBlendEquationSeparate == nullptr) {
  2454. _supports_blend_equation_separate = false;
  2455. GLCAT.warning()
  2456. << "BlendEquationSeparate advertised as supported by OpenGL runtime, "
  2457. "but could not get pointer to extension function.\n";
  2458. }
  2459. if (is_at_least_gl_version(1, 4)) {
  2460. _glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)
  2461. get_extension_func("glBlendFuncSeparate");
  2462. } else if (has_extension("GL_EXT_blend_func_separate")) {
  2463. _glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEEXTPROC)
  2464. get_extension_func("glBlendFuncSeparateEXT");
  2465. } else {
  2466. _glBlendFuncSeparate = null_glBlendFuncSeparate;
  2467. }
  2468. if (_glBlendFuncSeparate == nullptr) {
  2469. _glBlendFuncSeparate = null_glBlendFuncSeparate;
  2470. GLCAT.warning()
  2471. << "BlendFuncSeparate advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  2472. }
  2473. #endif
  2474. // In OpenGL ES 2.x, this is supported in the core. In 1.x, not at all.
  2475. #ifndef OPENGLES
  2476. _glBlendColor = nullptr;
  2477. bool supports_blend_color = false;
  2478. if (is_at_least_gl_version(1, 2)) {
  2479. supports_blend_color = true;
  2480. _glBlendColor = (PFNGLBLENDCOLORPROC)
  2481. get_extension_func("glBlendColor");
  2482. } else if (has_extension("GL_EXT_blend_color")) {
  2483. supports_blend_color = true;
  2484. _glBlendColor = (PFNGLBLENDCOLORPROC)
  2485. get_extension_func("glBlendColorEXT");
  2486. }
  2487. if (supports_blend_color && _glBlendColor == nullptr) {
  2488. GLCAT.warning()
  2489. << "BlendColor advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  2490. }
  2491. if (_glBlendColor == nullptr) {
  2492. _glBlendColor = null_glBlendColor;
  2493. }
  2494. #endif
  2495. #ifdef OPENGLES_1
  2496. // OpenGL ES 1 doesn't support dual-source blending.
  2497. #elif defined(OPENGLES)
  2498. _supports_dual_source_blending = has_extension("GL_EXT_blend_func_extended");
  2499. #else
  2500. _supports_dual_source_blending =
  2501. is_at_least_gl_version(3, 3) || has_extension("GL_ARB_blend_func_extended");
  2502. #endif
  2503. #ifdef OPENGLES
  2504. _edge_clamp = GL_CLAMP_TO_EDGE;
  2505. #else
  2506. _edge_clamp = GL_CLAMP;
  2507. if (is_at_least_gl_version(1, 2) || is_at_least_gles_version(1, 1) ||
  2508. has_extension("GL_SGIS_texture_edge_clamp")) {
  2509. _edge_clamp = GL_CLAMP_TO_EDGE;
  2510. }
  2511. #endif
  2512. _border_clamp = _edge_clamp;
  2513. #ifndef OPENGLES
  2514. if (gl_support_clamp_to_border &&
  2515. (is_at_least_gl_version(1, 3) ||
  2516. has_extension("GL_ARB_texture_border_clamp"))) {
  2517. _border_clamp = GL_CLAMP_TO_BORDER;
  2518. }
  2519. #endif
  2520. #ifdef OPENGLES_1
  2521. _mirror_repeat = GL_REPEAT;
  2522. if (has_extension("GL_OES_texture_mirrored_repeat")) {
  2523. _mirror_repeat = GL_MIRRORED_REPEAT;
  2524. }
  2525. #elif defined(OPENGLES)
  2526. // OpenGL 2.x and above support this in the core.
  2527. _mirror_repeat = GL_MIRRORED_REPEAT;
  2528. #else
  2529. _mirror_repeat = GL_REPEAT;
  2530. if (is_at_least_gl_version(1, 4) ||
  2531. has_extension("GL_ARB_texture_mirrored_repeat")) {
  2532. _mirror_repeat = GL_MIRRORED_REPEAT;
  2533. }
  2534. #endif
  2535. _mirror_clamp = _edge_clamp;
  2536. _mirror_edge_clamp = _edge_clamp;
  2537. _mirror_border_clamp = _border_clamp;
  2538. #ifndef OPENGLES
  2539. if (has_extension("GL_EXT_texture_mirror_clamp")) {
  2540. _mirror_clamp = GL_MIRROR_CLAMP_EXT;
  2541. _mirror_edge_clamp = GL_MIRROR_CLAMP_TO_EDGE_EXT;
  2542. _mirror_border_clamp = GL_MIRROR_CLAMP_TO_BORDER_EXT;
  2543. } else if (is_at_least_gl_version(4, 4) ||
  2544. has_extension("GL_ARB_texture_mirror_clamp_to_edge")) {
  2545. _mirror_clamp = GL_MIRROR_CLAMP_TO_EDGE;
  2546. _mirror_edge_clamp = GL_MIRROR_CLAMP_TO_EDGE;
  2547. }
  2548. #endif
  2549. #ifdef OPENGLES
  2550. _supports_texture_lod = is_at_least_gles_version(3, 0);
  2551. _supports_texture_lod_bias = false;
  2552. #else
  2553. _supports_texture_lod = false;
  2554. _supports_texture_lod_bias = false;
  2555. if (gl_support_texture_lod &&
  2556. (is_at_least_gl_version(1, 2) || has_extension("GL_SGIS_texture_lod"))) {
  2557. _supports_texture_lod = true;
  2558. if (is_at_least_gl_version(1, 4) || has_extension("GL_EXT_texture_lod_bias")) {
  2559. _supports_texture_lod_bias = true;
  2560. }
  2561. }
  2562. #endif
  2563. #ifdef OPENGLES
  2564. _supports_texture_max_level = is_at_least_gles_version(3, 0) ||
  2565. has_extension("GL_APPLE_texture_max_level");
  2566. #else
  2567. _supports_texture_max_level = is_at_least_gl_version(1, 2);
  2568. #endif
  2569. if (_supports_multisample) {
  2570. GLint sample_buffers = 0;
  2571. glGetIntegerv(GL_SAMPLE_BUFFERS, &sample_buffers);
  2572. if (sample_buffers != 1) {
  2573. // Even if the API supports multisample, we might have ended up with a
  2574. // framebuffer that doesn't have any multisample bits. (It's also
  2575. // possible the graphics card doesn't provide any framebuffers with
  2576. // multisample.) In this case, we don't really support the multisample
  2577. // API's, since they won't do anything.
  2578. _supports_multisample = false;
  2579. }
  2580. }
  2581. GLint max_texture_size = 0;
  2582. GLint max_3d_texture_size = 0;
  2583. GLint max_2d_texture_array_layers = 0;
  2584. GLint max_cube_map_size = 0;
  2585. glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
  2586. _max_texture_dimension = max_texture_size;
  2587. if (_supports_3d_texture) {
  2588. #ifndef OPENGLES_1
  2589. glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
  2590. #endif
  2591. _max_3d_texture_dimension = max_3d_texture_size;
  2592. } else {
  2593. _max_3d_texture_dimension = 0;
  2594. }
  2595. #ifndef OPENGLES_1
  2596. if (_supports_2d_texture_array) {
  2597. glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &max_2d_texture_array_layers);
  2598. _max_2d_texture_array_layers = max_2d_texture_array_layers;
  2599. }
  2600. #endif
  2601. if (_supports_cube_map) {
  2602. glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_size);
  2603. _max_cube_map_dimension = max_cube_map_size;
  2604. } else {
  2605. _max_cube_map_dimension = 0;
  2606. }
  2607. #ifndef OPENGLES
  2608. if (_supports_buffer_texture) {
  2609. GLint max_buffer_texture_size = 0;
  2610. glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &max_buffer_texture_size);
  2611. _max_buffer_texture_size = max_buffer_texture_size;
  2612. } else {
  2613. _max_buffer_texture_size = 0;
  2614. }
  2615. #endif // !OPENGLES
  2616. #ifndef OPENGLES
  2617. GLint max_elements_vertices = 0, max_elements_indices = 0;
  2618. if (is_at_least_gl_version(1, 2) || has_extension("GL_EXT_draw_range_elements")) {
  2619. glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &max_elements_vertices);
  2620. glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &max_elements_indices);
  2621. if (max_elements_vertices > 0) {
  2622. _max_vertices_per_array = max_elements_vertices;
  2623. }
  2624. if (max_elements_indices > 0) {
  2625. _max_vertices_per_primitive = max_elements_indices;
  2626. }
  2627. }
  2628. #endif // OPENGLES
  2629. if (GLCAT.is_debug()) {
  2630. GLCAT.debug()
  2631. << "max texture dimension = " << _max_texture_dimension
  2632. << ", max 3d texture = " << _max_3d_texture_dimension
  2633. << ", max 2d texture array = " << max_2d_texture_array_layers
  2634. << ", max cube map = " << _max_cube_map_dimension << "\n";
  2635. #ifndef OPENGLES
  2636. GLCAT.debug()
  2637. << "max_elements_vertices = " << max_elements_vertices
  2638. << ", max_elements_indices = " << max_elements_indices << "\n";
  2639. #endif
  2640. if (_supports_buffers) {
  2641. if (vertex_buffers) {
  2642. GLCAT.debug()
  2643. << "vertex buffer objects are supported.\n";
  2644. } else {
  2645. GLCAT.debug()
  2646. << "vertex buffer objects are supported (but not enabled).\n";
  2647. }
  2648. } else {
  2649. GLCAT.debug()
  2650. << "vertex buffer objects are NOT supported.\n";
  2651. }
  2652. #ifdef SUPPORT_IMMEDIATE_MODE
  2653. if (!vertex_arrays) {
  2654. GLCAT.debug()
  2655. << "immediate mode commands will be used instead of vertex arrays.\n";
  2656. }
  2657. #endif
  2658. if (!_supports_compressed_texture) {
  2659. GLCAT.debug()
  2660. << "Texture compression is not supported.\n";
  2661. } else {
  2662. GLint num_compressed_formats = 0;
  2663. glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_compressed_formats);
  2664. if (num_compressed_formats == 0) {
  2665. GLCAT.debug()
  2666. << "No specific compressed texture formats are supported.\n";
  2667. } else {
  2668. #ifndef NDEBUG
  2669. GLCAT.debug()
  2670. << "Supported compressed texture formats:\n";
  2671. GLint *formats = (GLint *)alloca(num_compressed_formats * sizeof(GLint));
  2672. glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats);
  2673. for (int i = 0; i < num_compressed_formats; ++i) {
  2674. const char *format_str = get_compressed_format_string(formats[i]);
  2675. if (format_str != nullptr) {
  2676. GLCAT.debug(false) << " " << format_str << '\n';
  2677. } else {
  2678. GLCAT.debug(false)
  2679. << " Unknown compressed format 0x" << hex << formats[i]
  2680. << dec << "\n";
  2681. }
  2682. }
  2683. #endif
  2684. }
  2685. }
  2686. }
  2687. _active_texture_stage = -1;
  2688. _num_active_texture_stages = 0;
  2689. // Check availability of anisotropic texture filtering.
  2690. _supports_anisotropy = false;
  2691. _max_anisotropy = 1.0;
  2692. if (is_at_least_gl_version(4, 6) ||
  2693. has_extension("GL_EXT_texture_filter_anisotropic") ||
  2694. has_extension("GL_ARB_texture_filter_anisotropic")) {
  2695. GLfloat max_anisotropy;
  2696. glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy);
  2697. _max_anisotropy = (PN_stdfloat)max_anisotropy;
  2698. _supports_anisotropy = true;
  2699. }
  2700. // Check availability of image read/write functionality in shaders.
  2701. _max_image_units = 0;
  2702. #ifndef OPENGLES_1
  2703. #ifdef OPENGLES
  2704. if (is_at_least_gl_version(3, 1)) {
  2705. #else
  2706. if (is_at_least_gl_version(4, 2) || has_extension("GL_ARB_shader_image_load_store")) {
  2707. #endif
  2708. _glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)
  2709. get_extension_func("glBindImageTexture");
  2710. _glMemoryBarrier = (PFNGLMEMORYBARRIERPROC)
  2711. get_extension_func("glMemoryBarrier");
  2712. glGetIntegerv(GL_MAX_IMAGE_UNITS, &_max_image_units);
  2713. #ifndef OPENGLES
  2714. } else if (has_extension("GL_EXT_shader_image_load_store")) {
  2715. _glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)
  2716. get_extension_func("glBindImageTextureEXT");
  2717. _glMemoryBarrier = (PFNGLMEMORYBARRIERPROC)
  2718. get_extension_func("glMemoryBarrierEXT");
  2719. glGetIntegerv(GL_MAX_IMAGE_UNITS_EXT, &_max_image_units);
  2720. #endif
  2721. } else {
  2722. _glBindImageTexture = nullptr;
  2723. _glMemoryBarrier = nullptr;
  2724. }
  2725. #endif // !OPENGLES_1
  2726. _supports_sampler_objects = false;
  2727. #ifndef OPENGLES_1
  2728. if (gl_support_sampler_objects &&
  2729. #ifdef OPENGLES
  2730. is_at_least_gles_version(3, 0)) {
  2731. #else
  2732. (is_at_least_gl_version(3, 3) || has_extension("GL_ARB_sampler_objects"))) {
  2733. #endif
  2734. _glGenSamplers = (PFNGLGENSAMPLERSPROC) get_extension_func("glGenSamplers");
  2735. _glDeleteSamplers = (PFNGLDELETESAMPLERSPROC) get_extension_func("glDeleteSamplers");
  2736. _glBindSampler = (PFNGLBINDSAMPLERPROC) get_extension_func("glBindSampler");
  2737. _glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC) get_extension_func("glSamplerParameteri");
  2738. _glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC) get_extension_func("glSamplerParameteriv");
  2739. _glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC) get_extension_func("glSamplerParameterf");
  2740. _glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC) get_extension_func("glSamplerParameterfv");
  2741. if (_glGenSamplers == nullptr || _glDeleteSamplers == nullptr ||
  2742. _glBindSampler == nullptr || _glSamplerParameteri == nullptr ||
  2743. _glSamplerParameteriv == nullptr || _glSamplerParameterf == nullptr ||
  2744. _glSamplerParameterfv == nullptr) {
  2745. GLCAT.warning()
  2746. << "GL_ARB_sampler_objects advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  2747. } else {
  2748. _supports_sampler_objects = true;
  2749. }
  2750. }
  2751. #endif // !OPENGLES_1
  2752. // Check availability of multi-bind functions.
  2753. _supports_multi_bind = false;
  2754. #ifndef OPENGLES
  2755. if (is_at_least_gl_version(4, 4) || has_extension("GL_ARB_multi_bind")) {
  2756. _glBindTextures = (PFNGLBINDTEXTURESPROC)
  2757. get_extension_func("glBindTextures");
  2758. _glBindImageTextures = (PFNGLBINDIMAGETEXTURESPROC)
  2759. get_extension_func("glBindImageTextures");
  2760. if (_supports_sampler_objects) {
  2761. _glBindSamplers = (PFNGLBINDSAMPLERSPROC)
  2762. get_extension_func("glBindSamplers");
  2763. }
  2764. if (_use_vertex_attrib_binding) {
  2765. _glBindVertexBuffers = (PFNGLBINDVERTEXBUFFERSPROC)
  2766. get_extension_func("glBindVertexBuffers");
  2767. }
  2768. if (_glBindTextures != nullptr && _glBindImageTextures != nullptr) {
  2769. _supports_multi_bind = true;
  2770. } else {
  2771. GLCAT.warning()
  2772. << "ARB_multi_bind advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  2773. }
  2774. }
  2775. #endif // !OPENGLES
  2776. #ifndef OPENGLES_1
  2777. #ifdef OPENGLES
  2778. if (is_at_least_gl_version(3, 0)) {
  2779. #else
  2780. if (is_at_least_gl_version(4, 3) || has_extension("GL_ARB_internalformat_query2")) {
  2781. #endif
  2782. _glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC)
  2783. get_extension_func("glGetInternalformativ");
  2784. if (_glGetInternalformativ == nullptr) {
  2785. GLCAT.warning()
  2786. << "ARB_internalformat_query2 advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  2787. }
  2788. }
  2789. #endif // !OPENGLES_1
  2790. _supports_bindless_texture = false;
  2791. #ifndef OPENGLES
  2792. if (has_extension("GL_ARB_bindless_texture")) {
  2793. _glGetTextureHandle = (PFNGLGETTEXTUREHANDLEPROC)
  2794. get_extension_func("glGetTextureHandleARB");
  2795. _glGetTextureSamplerHandle = (PFNGLGETTEXTURESAMPLERHANDLEPROC)
  2796. get_extension_func("glGetTextureSamplerHandleARB");
  2797. _glMakeTextureHandleResident = (PFNGLMAKETEXTUREHANDLERESIDENTPROC)
  2798. get_extension_func("glMakeTextureHandleResidentARB");
  2799. _glUniformHandleui64 = (PFNGLUNIFORMHANDLEUI64PROC)
  2800. get_extension_func("glUniformHandleui64ARB");
  2801. if (_glGetTextureHandle == nullptr || _glMakeTextureHandleResident == nullptr ||
  2802. _glUniformHandleui64 == nullptr) {
  2803. GLCAT.warning()
  2804. << "GL_ARB_bindless_texture advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  2805. } else {
  2806. _supports_bindless_texture = true;
  2807. }
  2808. }
  2809. #endif // !OPENGLES
  2810. #ifndef OPENGLES_1
  2811. _supports_get_program_binary = false;
  2812. _program_binary_formats.clear();
  2813. #ifdef OPENGLES
  2814. if (is_at_least_gles_version(3, 0)) {
  2815. #else
  2816. if (is_at_least_gl_version(4, 1) || has_extension("GL_ARB_get_program_binary")) {
  2817. #endif
  2818. _glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC)
  2819. get_extension_func("glGetProgramBinary");
  2820. _glProgramBinary = (PFNGLPROGRAMBINARYPROC)
  2821. get_extension_func("glProgramBinary");
  2822. _glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)
  2823. get_extension_func("glProgramParameteri");
  2824. GLint num_binary_formats = 0;
  2825. if (_glGetProgramBinary != nullptr &&
  2826. _glProgramBinary != nullptr &&
  2827. _glProgramParameteri != nullptr) {
  2828. glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &num_binary_formats);
  2829. }
  2830. if (num_binary_formats > 0) {
  2831. _supports_get_program_binary = true;
  2832. GLenum *binary_formats = (GLenum *)alloca(sizeof(GLenum) * num_binary_formats);
  2833. glGetIntegerv(GL_PROGRAM_BINARY_FORMATS, (GLint *)binary_formats);
  2834. for (int i = 0; i < num_binary_formats; ++i) {
  2835. _program_binary_formats.insert(binary_formats[i]);
  2836. }
  2837. }
  2838. }
  2839. #endif // !OPENGLES_1
  2840. report_my_gl_errors();
  2841. if (core_profile) {
  2842. // TODO: better detection mechanism?
  2843. _supports_stencil = support_stencil;
  2844. }
  2845. #ifdef SUPPORT_FIXED_FUNCTION
  2846. else if (support_stencil) {
  2847. GLint num_stencil_bits;
  2848. glGetIntegerv(GL_STENCIL_BITS, &num_stencil_bits);
  2849. _supports_stencil = (num_stencil_bits != 0);
  2850. }
  2851. #endif
  2852. #ifdef OPENGLES_1
  2853. _supports_stencil_wrap = has_extension("GL_OES_stencil_wrap");
  2854. #elif defined(OPENGLES)
  2855. _supports_stencil_wrap = true;
  2856. #else
  2857. _supports_stencil_wrap = is_at_least_gl_version(1, 4) ||
  2858. has_extension("GL_EXT_stencil_wrap");
  2859. #endif
  2860. _supports_two_sided_stencil = false;
  2861. #ifndef OPENGLES
  2862. //TODO: support the two-sided stencil functions that ended up in core.
  2863. if (has_extension("GL_EXT_stencil_two_side")) {
  2864. _glActiveStencilFaceEXT = (PFNGLACTIVESTENCILFACEEXTPROC)
  2865. get_extension_func("glActiveStencilFaceEXT");
  2866. _supports_two_sided_stencil = true;
  2867. } else {
  2868. _glActiveStencilFaceEXT = 0;
  2869. }
  2870. #endif
  2871. // Ensure the initial state is what we say it should be (in some cases, we
  2872. // don't want the GL default settings; in others, we have to force the point
  2873. // with some drivers that aren't strictly compliant w.r.t. initial
  2874. // settings).
  2875. glFrontFace(GL_CCW);
  2876. #ifndef OPENGLES_2
  2877. glDisable(GL_LINE_SMOOTH);
  2878. #endif
  2879. #ifdef SUPPORT_FIXED_FUNCTION
  2880. if (has_fixed_function_pipeline()) {
  2881. glDisable(GL_POINT_SMOOTH);
  2882. }
  2883. #endif
  2884. #ifndef OPENGLES
  2885. glDisable(GL_POLYGON_SMOOTH);
  2886. #endif // OPENGLES
  2887. #ifndef OPENGLES_2
  2888. if (_supports_multisample) {
  2889. glDisable(GL_MULTISAMPLE);
  2890. }
  2891. #endif
  2892. // Set depth range from zero to one if requested.
  2893. #ifndef OPENGLES
  2894. _use_depth_zero_to_one = false;
  2895. _use_remapped_depth_range = false;
  2896. if (gl_depth_zero_to_one) {
  2897. if (is_at_least_gl_version(4, 5) || has_extension("GL_ARB_clip_control")) {
  2898. PFNGLCLIPCONTROLPROC pglClipControl =
  2899. (PFNGLCLIPCONTROLPROC)get_extension_func("glClipControl");
  2900. if (pglClipControl != nullptr) {
  2901. pglClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);
  2902. _use_depth_zero_to_one = true;
  2903. if (GLCAT.is_debug()) {
  2904. GLCAT.debug()
  2905. << "Set zero-to-one depth using glClipControl\n";
  2906. }
  2907. }
  2908. }/* else if (has_extension("GL_NV_depth_buffer_float")) {
  2909. // Alternatively, all GeForce 8+ and even some AMD drivers support this
  2910. // extension, which (unlike the core glDepthRange, which clamps its
  2911. // input parameters) can compensate for the built-in depth remapping.
  2912. _glDepthRangedNV = (PFNGLDEPTHRANGEDNVPROC)get_extension_func("glDepthRangedNV");
  2913. if (_glDepthRangedNV != nullptr) {
  2914. _glDepthRangedNV(-1.0, 1.0);
  2915. _use_depth_zero_to_one = true;
  2916. _use_remapped_depth_range = true;
  2917. if (GLCAT.is_debug()) {
  2918. GLCAT.debug()
  2919. << "Set zero-to-one depth using glDepthRangedNV\n";
  2920. }
  2921. }
  2922. }*/
  2923. if (!_use_depth_zero_to_one) {
  2924. GLCAT.warning()
  2925. << "Zero-to-one depth was requested, but driver does not support it.\n";
  2926. }
  2927. }
  2928. #endif
  2929. // Set up all the enableddisabled flags to GL's known initial values:
  2930. // everything off.
  2931. _multisample_mode = 0;
  2932. _line_smooth_enabled = false;
  2933. _point_smooth_enabled = false;
  2934. _polygon_smooth_enabled = false;
  2935. _stencil_test_enabled = false;
  2936. _blend_enabled = false;
  2937. _depth_test_enabled = false;
  2938. _fog_enabled = false;
  2939. _alpha_test_enabled = false;
  2940. _polygon_offset_enabled = false;
  2941. _flat_shade_model = false;
  2942. _decal_level = 0;
  2943. _active_color_write_mask = ColorWriteAttrib::C_all;
  2944. _tex_gen_point_sprite = false;
  2945. #ifndef OPENGLES_1
  2946. _enabled_vertex_attrib_arrays.clear();
  2947. memset(_vertex_attrib_divisors, 0, sizeof(GLuint) * 32);
  2948. #endif
  2949. // Dither is on by default in GL; let's turn it off
  2950. glDisable(GL_DITHER);
  2951. _dithering_enabled = false;
  2952. #ifndef OPENGLES_1
  2953. _current_shader = nullptr;
  2954. _current_shader_context = nullptr;
  2955. _vertex_array_shader = nullptr;
  2956. _vertex_array_shader_context = nullptr;
  2957. _texture_binding_shader = nullptr;
  2958. _texture_binding_shader_context = nullptr;
  2959. #endif
  2960. // Count the max number of lights
  2961. _max_lights = 0;
  2962. #ifdef SUPPORT_FIXED_FUNCTION
  2963. if (has_fixed_function_pipeline()) {
  2964. GLint max_lights = 0;
  2965. glGetIntegerv(GL_MAX_LIGHTS, &max_lights);
  2966. _max_lights = max_lights;
  2967. if (GLCAT.is_debug()) {
  2968. GLCAT.debug()
  2969. << "max lights = " << _max_lights << "\n";
  2970. }
  2971. }
  2972. #endif
  2973. // Count the max number of clipping planes
  2974. _max_clip_planes = 0;
  2975. #ifdef SUPPORT_FIXED_FUNCTION
  2976. if (has_fixed_function_pipeline()) {
  2977. GLint max_clip_planes = 0;
  2978. glGetIntegerv(GL_MAX_CLIP_PLANES, &max_clip_planes);
  2979. _max_clip_planes = max_clip_planes;
  2980. if (GLCAT.is_debug()) {
  2981. GLCAT.debug()
  2982. << "max clip planes = " << _max_clip_planes << "\n";
  2983. }
  2984. }
  2985. #endif
  2986. _max_texture_stages = 1;
  2987. #ifdef SUPPORT_FIXED_FUNCTION
  2988. if (supports_multitexture && has_fixed_function_pipeline()) {
  2989. GLint max_texture_stages = 0;
  2990. glGetIntegerv(GL_MAX_TEXTURE_UNITS, &max_texture_stages);
  2991. _max_texture_stages = max_texture_stages;
  2992. if (GLCAT.is_debug()) {
  2993. GLCAT.debug()
  2994. << "max texture stages = " << _max_texture_stages << "\n";
  2995. }
  2996. }
  2997. #endif
  2998. _current_vbuffer_index = 0;
  2999. _current_ibuffer_index = 0;
  3000. _current_vao_index = 0;
  3001. _current_fbo = 0;
  3002. _auto_antialias_mode = false;
  3003. _render_mode = RenderModeAttrib::M_filled;
  3004. _point_size = 1.0f;
  3005. _point_perspective = false;
  3006. #ifndef OPENGLES
  3007. _current_vertex_buffers.clear();
  3008. _current_vertex_format.clear();
  3009. memset(_vertex_attrib_columns, 0, sizeof(const GeomVertexColumn *) * 32);
  3010. _current_sbuffer_index = 0;
  3011. _current_sbuffer_base.clear();
  3012. #endif
  3013. report_my_gl_errors();
  3014. #ifdef SUPPORT_FIXED_FUNCTION
  3015. if (has_fixed_function_pipeline()) {
  3016. if (gl_cheap_textures) {
  3017. GLCAT.info()
  3018. << "Setting glHint() for fastest textures.\n";
  3019. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
  3020. }
  3021. // Use per-vertex fog if per-pixel fog requires SW renderer
  3022. glHint(GL_FOG_HINT, GL_DONT_CARE);
  3023. }
  3024. #endif
  3025. #ifdef SUPPORT_FIXED_FUNCTION
  3026. if (has_fixed_function_pipeline()) {
  3027. GLint num_red_bits = 0;
  3028. glGetIntegerv(GL_RED_BITS, &num_red_bits);
  3029. if (num_red_bits < 8) {
  3030. glEnable(GL_DITHER);
  3031. _dithering_enabled = true;
  3032. if (GLCAT.is_debug()) {
  3033. GLCAT.debug()
  3034. << "frame buffer depth = " << num_red_bits
  3035. << " bits/channel, enabling dithering\n";
  3036. }
  3037. }
  3038. }
  3039. #endif
  3040. _error_count = 0;
  3041. report_my_gl_errors();
  3042. #ifndef OPENGLES_1
  3043. if (GLCAT.is_debug()) {
  3044. if (_supports_get_program_binary) {
  3045. GLCAT.debug()
  3046. << "Supported program binary formats:\n";
  3047. GLCAT.debug() << " ";
  3048. pset<GLenum>::const_iterator it;
  3049. for (it = _program_binary_formats.begin();
  3050. it != _program_binary_formats.end(); ++it) {
  3051. char number[16];
  3052. sprintf(number, "0x%04X", *it);
  3053. GLCAT.debug(false) << " " << number << "";
  3054. }
  3055. GLCAT.debug(false) << "\n";
  3056. } else {
  3057. GLCAT.debug() << "No program binary formats supported.\n";
  3058. }
  3059. }
  3060. #endif
  3061. // Do we guarantee that we can apply the color scale via a shader? We set
  3062. // this false if there is a chance that the fixed-function pipeline is used.
  3063. _runtime_color_scale = !has_fixed_function_pipeline();
  3064. #ifndef OPENGLES
  3065. if (_gl_shadlang_ver_major >= 4 || has_extension("GL_NV_gpu_program5")) {
  3066. // gp5fp - OpenGL fragment profile for GeForce 400 Series and up
  3067. _shader_model = SM_50;
  3068. } else if (_gl_shadlang_ver_major >= 3 ||
  3069. has_extension("GL_NV_gpu_program4")) {
  3070. // gp4fp - OpenGL fragment profile for G8x (GeForce 8xxx and up)
  3071. _shader_model = SM_40;
  3072. } else if (has_extension("GL_NV_fragment_program2")) {
  3073. // fp40 - OpenGL fragment profile for NV4x (GeForce 6xxx and 7xxx Series,
  3074. // NV4x-based Quadro FX, etc.)
  3075. _shader_model = SM_30;
  3076. } else if (has_extension("GL_NV_fragment_program")) {
  3077. // fp30 - OpenGL fragment profile for NV3x (GeForce FX, Quadro FX, etc.)
  3078. _shader_model = SM_2X;
  3079. } else if (_gl_shadlang_ver_major >= 1 ||
  3080. has_extension("GL_ARB_fragment_program")) {
  3081. // This OpenGL profile corresponds to the per-fragment functionality
  3082. // introduced by GeForce FX and other DirectX 9 GPUs.
  3083. _shader_model = SM_20;
  3084. } else if (has_extension("GL_NV_texture_shader2")) {
  3085. // fp20 - OpenGL fragment profile for NV2x (GeForce3, GeForce4 Ti, Quadro
  3086. // DCC, etc.)
  3087. _shader_model = SM_11;
  3088. } else {
  3089. // No shader support
  3090. _shader_model = SM_00;
  3091. }
  3092. // DisplayInformation may have better shader model detection
  3093. {
  3094. GraphicsPipe *pipe;
  3095. DisplayInformation *display_information;
  3096. pipe = this->get_pipe();
  3097. if (pipe) {
  3098. display_information = pipe->get_display_information ();
  3099. if (display_information) {
  3100. if (display_information->get_shader_model() > _shader_model) {
  3101. _shader_model = display_information->get_shader_model();
  3102. }
  3103. }
  3104. }
  3105. }
  3106. _auto_detect_shader_model = _shader_model;
  3107. if (GLCAT.is_debug()) {
  3108. #ifdef HAVE_CG
  3109. #if CG_VERSION_NUM >= 2200
  3110. GLCAT.debug() << "Supported Cg profiles:\n";
  3111. int num_profiles = cgGetNumSupportedProfiles();
  3112. for (int i = 0; i < num_profiles; ++i) {
  3113. CGprofile profile = cgGetSupportedProfile(i);
  3114. if (cgGLIsProfileSupported(profile)) {
  3115. GLCAT.debug() << " " << cgGetProfileString(profile) << "\n";
  3116. }
  3117. }
  3118. #endif // CG_VERSION_NUM >= 2200
  3119. #if CG_VERSION_NUM >= 3100
  3120. GLCAT.debug() << "Cg GLSL version = "
  3121. << cgGLGetGLSLVersionString(cgGLDetectGLSLVersion()) << "\n";
  3122. #endif
  3123. GLCAT.debug()
  3124. << "Cg latest vertex profile = "
  3125. << cgGetProfileString(cgGLGetLatestProfile(CG_GL_VERTEX)) << "\n";
  3126. GLCAT.debug()
  3127. << "Cg latest fragment profile = "
  3128. << cgGetProfileString(cgGLGetLatestProfile(CG_GL_FRAGMENT)) << "\n";
  3129. #if CG_VERSION_NUM >= 2000
  3130. GLCAT.debug()
  3131. << "Cg latest geometry profile = "
  3132. << cgGetProfileString(cgGLGetLatestProfile(CG_GL_GEOMETRY)) << "\n";
  3133. #endif
  3134. GLCAT.debug() << "basic-shaders-only " << basic_shaders_only << "\n";
  3135. GLCAT.debug()
  3136. << "Cg active vertex profile = "
  3137. << cgGetProfileString((CGprofile)_shader_caps._active_vprofile) << "\n";
  3138. GLCAT.debug()
  3139. << "Cg active fragment profile = "
  3140. << cgGetProfileString((CGprofile)_shader_caps._active_fprofile) << "\n";
  3141. GLCAT.debug()
  3142. << "Cg active geometry profile = "
  3143. << cgGetProfileString((CGprofile)_shader_caps._active_gprofile) << "\n";
  3144. #endif // HAVE_CG
  3145. GLCAT.debug() << "shader model = " << _shader_model << "\n";
  3146. }
  3147. #endif // !OPENGLES
  3148. // OpenGL core profile requires a VAO to be bound. It's a bit silly,
  3149. // because we can just bind a VAO and then forget about it.
  3150. #if !defined(OPENGLES)
  3151. if (core_profile) {
  3152. if (_supports_vao) {
  3153. _glGenVertexArrays(1, &_current_vao_index);
  3154. _glBindVertexArray(_current_vao_index);
  3155. } else {
  3156. GLCAT.error()
  3157. << "Core profile enabled, but vertex array objects not supported!\n";
  3158. }
  3159. }
  3160. #endif
  3161. pop_group_marker();
  3162. // Now that the GSG has been initialized, make it available for
  3163. // optimizations.
  3164. add_gsg(this);
  3165. }
  3166. /**
  3167. * Force the graphics card to finish drawing before returning. !!!!!HACK
  3168. * WARNING!!!! glfinish does not actually wait for the graphics card to finish
  3169. * drawing only for draw calls to finish. Thus flip may not happene
  3170. * immediately. Instead we read a single pixel from the framebuffer. This
  3171. * forces the graphics card to finish drawing the frame before returning.
  3172. */
  3173. void CLP(GraphicsStateGuardian)::
  3174. finish() {
  3175. // Rather than call glfinish which returns immediately if draw commands have
  3176. // been submitted, we will read a single pixel from the frame. That will
  3177. // force the graphics card to finish drawing before it is called
  3178. char data[4];
  3179. glReadPixels(0,0,1,1,GL_RGBA,GL_UNSIGNED_BYTE,&data);
  3180. // glFinish();
  3181. }
  3182. /**
  3183. * Clears the framebuffer within the current DisplayRegion, according to the
  3184. * flags indicated by the given DrawableRegion object.
  3185. *
  3186. * This does not set the DisplayRegion first. You should call
  3187. * prepare_display_region() to specify the region you wish the clear operation
  3188. * to apply to.
  3189. */
  3190. void CLP(GraphicsStateGuardian)::
  3191. clear(DrawableRegion *clearable) {
  3192. report_my_gl_errors();
  3193. if (!clearable->is_any_clear_active()) {
  3194. return;
  3195. }
  3196. // XXX rdb: Is this line really necessary? Could we perhaps just reset the
  3197. // color write mask and other relevant attributes?
  3198. set_state_and_transform(RenderState::make_empty(), _internal_transform);
  3199. int mask = 0;
  3200. #ifndef OPENGLES_1
  3201. if (_current_fbo != 0 && _glClearBufferfv != nullptr) {
  3202. // We can use glClearBuffer to clear all the color attachments, which
  3203. // protects us from the overhead of having to call set_draw_buffer for
  3204. // every single attachment.
  3205. int index = 0;
  3206. if (_current_properties->get_color_bits() > 0) {
  3207. if (_current_properties->is_stereo()) {
  3208. // Clear both left and right attachments.
  3209. if (clearable->get_clear_active(GraphicsOutput::RTP_color)) {
  3210. LColorf v = LCAST(float, clearable->get_clear_value(GraphicsOutput::RTP_color));
  3211. _glClearBufferfv(GL_COLOR, index, v.get_data());
  3212. _glClearBufferfv(GL_COLOR, index + 1, v.get_data());
  3213. }
  3214. index += 2;
  3215. } else {
  3216. if (clearable->get_clear_active(GraphicsOutput::RTP_color)) {
  3217. LColorf v = LCAST(float, clearable->get_clear_value(GraphicsOutput::RTP_color));
  3218. _glClearBufferfv(GL_COLOR, index, v.get_data());
  3219. }
  3220. ++index;
  3221. }
  3222. }
  3223. for (int i = 0; i < _current_properties->get_aux_rgba(); ++i) {
  3224. int layerid = GraphicsOutput::RTP_aux_rgba_0 + i;
  3225. if (clearable->get_clear_active(layerid)) {
  3226. LColorf v = LCAST(float, clearable->get_clear_value(layerid));
  3227. _glClearBufferfv(GL_COLOR, index, v.get_data());
  3228. }
  3229. ++index;
  3230. }
  3231. for (int i = 0; i < _current_properties->get_aux_hrgba(); ++i) {
  3232. int layerid = GraphicsOutput::RTP_aux_hrgba_0 + i;
  3233. if (clearable->get_clear_active(layerid)) {
  3234. LColorf v = LCAST(float, clearable->get_clear_value(layerid));
  3235. _glClearBufferfv(GL_COLOR, index, v.get_data());
  3236. }
  3237. ++index;
  3238. }
  3239. for (int i = 0; i < _current_properties->get_aux_float(); ++i) {
  3240. int layerid = GraphicsOutput::RTP_aux_float_0 + i;
  3241. if (clearable->get_clear_active(layerid)) {
  3242. LColorf v = LCAST(float, clearable->get_clear_value(layerid));
  3243. _glClearBufferfv(GL_COLOR, index, v.get_data());
  3244. }
  3245. ++index;
  3246. }
  3247. } else
  3248. #endif
  3249. {
  3250. if (_current_properties->get_aux_mask() != 0) {
  3251. for (int i = 0; i < _current_properties->get_aux_rgba(); ++i) {
  3252. int layerid = GraphicsOutput::RTP_aux_rgba_0 + i;
  3253. int layerbit = RenderBuffer::T_aux_rgba_0 << i;
  3254. if (clearable->get_clear_active(layerid)) {
  3255. LColor v = clearable->get_clear_value(layerid);
  3256. glClearColor(v[0], v[1], v[2], v[3]);
  3257. set_draw_buffer(layerbit);
  3258. glClear(GL_COLOR_BUFFER_BIT);
  3259. }
  3260. }
  3261. for (int i = 0; i < _current_properties->get_aux_hrgba(); ++i) {
  3262. int layerid = GraphicsOutput::RTP_aux_hrgba_0 + i;
  3263. int layerbit = RenderBuffer::T_aux_hrgba_0 << i;
  3264. if (clearable->get_clear_active(layerid)) {
  3265. LColor v = clearable->get_clear_value(layerid);
  3266. glClearColor(v[0], v[1], v[2], v[3]);
  3267. set_draw_buffer(layerbit);
  3268. glClear(GL_COLOR_BUFFER_BIT);
  3269. }
  3270. }
  3271. for (int i = 0; i < _current_properties->get_aux_float(); ++i) {
  3272. int layerid = GraphicsOutput::RTP_aux_float_0 + i;
  3273. int layerbit = RenderBuffer::T_aux_float_0 << i;
  3274. if (clearable->get_clear_active(layerid)) {
  3275. LColor v = clearable->get_clear_value(layerid);
  3276. glClearColor(v[0], v[1], v[2], v[3]);
  3277. set_draw_buffer(layerbit);
  3278. glClear(GL_COLOR_BUFFER_BIT);
  3279. }
  3280. }
  3281. // In the past, it was possible to set the draw buffer once in
  3282. // prepare_display_region and then forget about it. Now, with aux
  3283. // layers, it is necessary to occasionally change the draw buffer. In
  3284. // time, I think there will need to be a draw buffer attrib. Until
  3285. // then, this little hack to put things back the way they were after
  3286. // prepare_display_region will do.
  3287. set_draw_buffer(_draw_buffer_type);
  3288. }
  3289. if (_current_properties->get_color_bits() > 0) {
  3290. if (clearable->get_clear_color_active()) {
  3291. LColor v = clearable->get_clear_color();
  3292. glClearColor(v[0], v[1], v[2], v[3]);
  3293. clear_color_write_mask();
  3294. _state_mask.clear_bit(ColorWriteAttrib::get_class_slot());
  3295. mask |= GL_COLOR_BUFFER_BIT;
  3296. }
  3297. }
  3298. }
  3299. if (clearable->get_clear_depth_active()) {
  3300. #ifdef OPENGLES
  3301. glClearDepthf(clearable->get_clear_depth());
  3302. #else
  3303. glClearDepth(clearable->get_clear_depth());
  3304. #endif // OPENGLES
  3305. #ifdef GSG_VERBOSE
  3306. GLCAT.spam()
  3307. << "glDepthMask(GL_TRUE)" << endl;
  3308. #endif
  3309. glDepthMask(GL_TRUE);
  3310. _state_mask.clear_bit(DepthWriteAttrib::get_class_slot());
  3311. mask |= GL_DEPTH_BUFFER_BIT;
  3312. }
  3313. if (_supports_stencil && clearable->get_clear_stencil_active()) {
  3314. glStencilMask(~0);
  3315. glClearStencil(clearable->get_clear_stencil());
  3316. mask |= GL_STENCIL_BUFFER_BIT;
  3317. }
  3318. if (mask != 0) {
  3319. glClear(mask);
  3320. if (GLCAT.is_spam()) {
  3321. string clear_flags;
  3322. if (mask & GL_COLOR_BUFFER_BIT) {
  3323. clear_flags += " | GL_COLOR_BUFFER_BIT";
  3324. }
  3325. if (mask & GL_DEPTH_BUFFER_BIT) {
  3326. clear_flags += " | GL_DEPTH_BUFFER_BIT";
  3327. }
  3328. if (mask & GL_STENCIL_BUFFER_BIT) {
  3329. clear_flags += " | GL_STENCIL_BUFFER_BIT";
  3330. }
  3331. #ifndef OPENGLES
  3332. if (mask & GL_ACCUM_BUFFER_BIT) {
  3333. clear_flags += " | GL_ACCUM_BUFFER_BIT";
  3334. }
  3335. #endif
  3336. GLCAT.spam() << "glClear(" << (clear_flags.c_str() + 3) << ")\n";
  3337. }
  3338. }
  3339. report_my_gl_errors();
  3340. }
  3341. /**
  3342. * Prepare a display region for rendering (set up scissor region and viewport)
  3343. */
  3344. void CLP(GraphicsStateGuardian)::
  3345. prepare_display_region(DisplayRegionPipelineReader *dr) {
  3346. nassertv(dr != nullptr);
  3347. GraphicsStateGuardian::prepare_display_region(dr);
  3348. int l, b, w, h;
  3349. dr->get_region_pixels(l, b, w, h);
  3350. _viewport_x = l;
  3351. _viewport_y = b;
  3352. _viewport_width = w;
  3353. _viewport_height = h;
  3354. GLint x = GLint(l);
  3355. GLint y = GLint(b);
  3356. GLsizei width = GLsizei(w);
  3357. GLsizei height = GLsizei(h);
  3358. _draw_buffer_type = dr->get_object()->get_draw_buffer_type() & _current_properties->get_buffer_mask() & _stereo_buffer_mask;
  3359. _draw_buffer_type |= _current_properties->get_aux_mask();
  3360. set_draw_buffer(_draw_buffer_type);
  3361. int count = dr->get_num_regions();
  3362. if (dr->get_scissor_enabled()) {
  3363. if (GLCAT.is_spam()) {
  3364. GLCAT.spam()
  3365. << "glEnable(GL_SCISSOR_TEST)\n";
  3366. }
  3367. glEnable(GL_SCISSOR_TEST);
  3368. _scissor_enabled = true;
  3369. _scissor_array.resize(count);
  3370. } else {
  3371. if (GLCAT.is_spam()) {
  3372. GLCAT.spam()
  3373. << "glDisable(GL_SCISSOR_TEST)\n";
  3374. }
  3375. glDisable(GL_SCISSOR_TEST);
  3376. _scissor_enabled = false;
  3377. _scissor_array.clear();
  3378. }
  3379. _scissor_attrib_active = false;
  3380. #ifndef OPENGLES
  3381. if (_supports_viewport_arrays) {
  3382. GLfloat *viewports = (GLfloat *)alloca(sizeof(GLfloat) * 4 * count);
  3383. // We store the scissor regions in a vector since we may need to switch
  3384. // back to it in do_issue_scissor.
  3385. for (int i = 0; i < count; ++i) {
  3386. LVecBase4i sr;
  3387. dr->get_region_pixels(i, sr[0], sr[1], sr[2], sr[3]);
  3388. GLfloat *vr = viewports + i * 4;
  3389. vr[0] = (GLfloat) sr[0];
  3390. vr[1] = (GLfloat) sr[1];
  3391. vr[2] = (GLfloat) sr[2];
  3392. vr[3] = (GLfloat) sr[3];
  3393. if (_scissor_enabled) {
  3394. _scissor_array[i] = sr;
  3395. }
  3396. }
  3397. _glViewportArrayv(0, count, viewports);
  3398. if (_scissor_enabled) {
  3399. _glScissorArrayv(0, count, _scissor_array[0].get_data());
  3400. }
  3401. if (GLCAT.is_spam()) {
  3402. GLCAT.spam()
  3403. << "glViewportArrayv(0, " << count << ",";
  3404. for (int i = 0; i < count; ++i) {
  3405. GLfloat *vr = viewports + i * 4;
  3406. GLCAT.spam(false) << " [" << vr[0] << " " << vr[1] << " " << vr[2] << " " << vr[3] << "]";
  3407. }
  3408. GLCAT.spam(false) << ")\n";
  3409. if (_scissor_enabled) {
  3410. GLCAT.spam()
  3411. << "glScissorArrayv(0, " << count << ",";
  3412. for (int i = 0; i < count; ++i) {
  3413. const LVecBase4i &sr = _scissor_array[i];
  3414. GLCAT.spam(false) << " [" << sr << "]";
  3415. }
  3416. GLCAT.spam(false) << ")\n";
  3417. }
  3418. }
  3419. } else
  3420. #endif // OPENGLES
  3421. {
  3422. glViewport(x, y, width, height);
  3423. if (_scissor_enabled) {
  3424. glScissor(x, y, width, height);
  3425. _scissor_array.resize(1);
  3426. _scissor_array[0].set(x, y, width, height);
  3427. }
  3428. if (GLCAT.is_spam()) {
  3429. GLCAT.spam()
  3430. << "glViewport(" << x << ", " << y << ", " << width << ", " << height << ")\n";
  3431. if (dr->get_scissor_enabled()) {
  3432. GLCAT.spam()
  3433. << "glScissor(" << x << ", " << y << ", " << width << ", " << height << ")\n";
  3434. }
  3435. }
  3436. }
  3437. report_my_gl_errors();
  3438. }
  3439. /**
  3440. * Resets any non-standard graphics state that might give a callback apoplexy.
  3441. * Some drivers require that the graphics state be restored to neutral before
  3442. * performing certain operations. In OpenGL, for instance, this closes any
  3443. * open vertex buffers.
  3444. */
  3445. void CLP(GraphicsStateGuardian)::
  3446. clear_before_callback() {
  3447. #ifdef SUPPORT_FIXED_FUNCTION
  3448. if (has_fixed_function_pipeline()) {
  3449. disable_standard_vertex_arrays();
  3450. }
  3451. #endif
  3452. #ifndef OPENGLES_1
  3453. if (_vertex_array_shader_context != 0) {
  3454. _vertex_array_shader_context->disable_shader_vertex_arrays();
  3455. _vertex_array_shader = nullptr;
  3456. _vertex_array_shader_context = nullptr;
  3457. }
  3458. #endif
  3459. unbind_buffers();
  3460. // Some callbacks may quite reasonably assume that the active texture stage
  3461. // is still set to stage 0. CEGUI, in particular, makes this assumption.
  3462. set_active_texture_stage(0);
  3463. #ifdef SUPPORT_FIXED_FUNCTION
  3464. _glClientActiveTexture(GL_TEXTURE0);
  3465. #endif
  3466. // It's also quite reasonable to presume there aren't any funny color write
  3467. // mask settings active.
  3468. clear_color_write_mask();
  3469. // Clear the bound sampler object, so that we do not inadvertently override
  3470. // the callback's desired sampler settings.
  3471. #ifndef OPENGLES_1
  3472. if (_supports_sampler_objects) {
  3473. _glBindSampler(0, 0);
  3474. if (GLCAT.is_spam()) {
  3475. GLCAT.spam()
  3476. << "glBindSampler(0, 0)\n";
  3477. }
  3478. }
  3479. #endif
  3480. }
  3481. /**
  3482. * Given a lens, calculates the appropriate projection matrix for use with
  3483. * this gsg. Note that the projection matrix depends a lot upon the
  3484. * coordinate system of the rendering API.
  3485. *
  3486. * The return value is a TransformState if the lens is acceptable, NULL if it
  3487. * is not.
  3488. */
  3489. CPT(TransformState) CLP(GraphicsStateGuardian)::
  3490. calc_projection_mat(const Lens *lens) {
  3491. if (lens == nullptr) {
  3492. return nullptr;
  3493. }
  3494. if (!lens->is_linear()) {
  3495. return nullptr;
  3496. }
  3497. // The projection matrix must always be right-handed Y-up, even if our
  3498. // coordinate system of choice is otherwise, because certain GL calls
  3499. // (specifically glTexGen(GL_SPHERE_MAP)) assume this kind of a coordinate
  3500. // system. Sigh. In order to implement a Z-up (or other arbitrary)
  3501. // coordinate system, we'll use a Y-up projection matrix, and store the
  3502. // conversion to our coordinate system of choice in the modelview matrix.
  3503. LMatrix4 result =
  3504. LMatrix4::convert_mat(_internal_coordinate_system,
  3505. lens->get_coordinate_system()) *
  3506. lens->get_projection_mat(_current_stereo_channel);
  3507. #ifndef OPENGLES
  3508. if (_use_depth_zero_to_one) {
  3509. // If we requested that the OpenGL NDC Z goes from zero to one like in
  3510. // Direct3D, we need to scale the projection matrix, which assumes -1..1.
  3511. static const LMatrix4 rescale_mat
  3512. (1, 0, 0, 0,
  3513. 0, 1, 0, 0,
  3514. 0, 0, 0.5, 0,
  3515. 0, 0, 0.5, 1);
  3516. result *= rescale_mat;
  3517. }
  3518. #endif
  3519. if (_scene_setup->get_inverted()) {
  3520. // If the scene is supposed to be inverted, then invert the projection
  3521. // matrix.
  3522. result *= LMatrix4::scale_mat(1.0f, -1.0f, 1.0f);
  3523. }
  3524. return TransformState::make_mat(result);
  3525. }
  3526. /**
  3527. * Makes the current lens (whichever lens was most recently specified with
  3528. * set_scene()) active, so that it will transform future rendered geometry.
  3529. * Normally this is only called from the draw process, and usually it is
  3530. * called by set_scene().
  3531. *
  3532. * The return value is true if the lens is acceptable, false if it is not.
  3533. */
  3534. bool CLP(GraphicsStateGuardian)::
  3535. prepare_lens() {
  3536. #ifdef SUPPORT_FIXED_FUNCTION
  3537. if (has_fixed_function_pipeline()) {
  3538. if (GLCAT.is_spam()) {
  3539. GLCAT.spam()
  3540. << "glMatrixMode(GL_PROJECTION): " << _projection_mat->get_mat() << endl;
  3541. }
  3542. glMatrixMode(GL_PROJECTION);
  3543. call_glLoadMatrix(_projection_mat->get_mat());
  3544. report_my_gl_errors();
  3545. do_point_size();
  3546. }
  3547. #endif
  3548. return true;
  3549. }
  3550. /**
  3551. * Called before each frame is rendered, to allow the GSG a chance to do any
  3552. * internal cleanup before beginning the frame.
  3553. *
  3554. * The return value is true if successful (in which case the frame will be
  3555. * drawn and end_frame() will be called later), or false if unsuccessful (in
  3556. * which case nothing will be drawn and end_frame() will not be called).
  3557. */
  3558. bool CLP(GraphicsStateGuardian)::
  3559. begin_frame(Thread *current_thread) {
  3560. if (!GraphicsStateGuardian::begin_frame(current_thread)) {
  3561. return false;
  3562. }
  3563. _renderbuffer_residency.begin_frame(current_thread);
  3564. report_my_gl_errors();
  3565. #ifdef DO_PSTATS
  3566. _vertices_display_list_pcollector.clear_level();
  3567. _vertices_immediate_pcollector.clear_level();
  3568. _primitive_batches_display_list_pcollector.clear_level();
  3569. #endif
  3570. #ifndef NDEBUG
  3571. _show_texture_usage = false;
  3572. if (gl_show_texture_usage) {
  3573. // When this is true, then every other second, we show the usage textures
  3574. // instead of the real textures.
  3575. double now = ClockObject::get_global_clock()->get_frame_time();
  3576. int this_second = (int)floor(now);
  3577. if (this_second & 1) {
  3578. _show_texture_usage = true;
  3579. _show_texture_usage_index = this_second >> 1;
  3580. int max_size = gl_show_texture_usage_max_size;
  3581. if (max_size != _show_texture_usage_max_size) {
  3582. // Remove the cache of usage textures; we've changed the max size.
  3583. UsageTextures::iterator ui;
  3584. for (ui = _usage_textures.begin();
  3585. ui != _usage_textures.end();
  3586. ++ui) {
  3587. GLuint index = (*ui).second;
  3588. glDeleteTextures(1, &index);
  3589. }
  3590. _usage_textures.clear();
  3591. _show_texture_usage_max_size = max_size;
  3592. }
  3593. }
  3594. }
  3595. #endif // NDEBUG
  3596. #ifdef DO_PSTATS
  3597. /*if (_supports_timer_query) {
  3598. // Measure the difference between the OpenGL clock and the PStats clock.
  3599. GLint64 time_ns;
  3600. _glGetInteger64v(GL_TIMESTAMP, &time_ns);
  3601. _timer_delta = time_ns * -0.000000001;
  3602. _timer_delta += PStatClient::get_global_pstats()->get_real_time();
  3603. }*/
  3604. #endif
  3605. #ifndef OPENGLES
  3606. if (_current_properties->get_srgb_color()) {
  3607. glEnable(GL_FRAMEBUFFER_SRGB);
  3608. }
  3609. #endif
  3610. report_my_gl_errors();
  3611. return true;
  3612. }
  3613. /**
  3614. * Called between begin_frame() and end_frame() to mark the beginning of
  3615. * drawing commands for a "scene" (usually a particular DisplayRegion) within
  3616. * a frame. All 3-D drawing commands, except the clear operation, must be
  3617. * enclosed within begin_scene() .. end_scene().
  3618. *
  3619. * The return value is true if successful (in which case the scene will be
  3620. * drawn and end_scene() will be called later), or false if unsuccessful (in
  3621. * which case nothing will be drawn and end_scene() will not be called).
  3622. */
  3623. bool CLP(GraphicsStateGuardian)::
  3624. begin_scene() {
  3625. return GraphicsStateGuardian::begin_scene();
  3626. }
  3627. /**
  3628. * Called between begin_frame() and end_frame() to mark the end of drawing
  3629. * commands for a "scene" (usually a particular DisplayRegion) within a frame.
  3630. * All 3-D drawing commands, except the clear operation, must be enclosed
  3631. * within begin_scene() .. end_scene().
  3632. */
  3633. void CLP(GraphicsStateGuardian)::
  3634. end_scene() {
  3635. GraphicsStateGuardian::end_scene();
  3636. _dlights.clear();
  3637. report_my_gl_errors();
  3638. }
  3639. /**
  3640. * Called after each frame is rendered, to allow the GSG a chance to do any
  3641. * internal cleanup after rendering the frame, and before the window flips.
  3642. */
  3643. void CLP(GraphicsStateGuardian)::
  3644. end_frame(Thread *current_thread) {
  3645. report_my_gl_errors();
  3646. #ifndef OPENGLES
  3647. if (_current_properties->get_srgb_color()) {
  3648. glDisable(GL_FRAMEBUFFER_SRGB);
  3649. }
  3650. #endif
  3651. #ifdef DO_PSTATS
  3652. // Check for textures, etc., that are no longer resident. These calls might
  3653. // be measurably expensive, and they don't have any benefit unless we are
  3654. // actually viewing PStats, so don't do them unless we're connected. That
  3655. // will just mean that we'll count everything as resident until the user
  3656. // connects PStats, at which point it will then correct the assessment. No
  3657. // harm done.
  3658. if (has_fixed_function_pipeline() && PStatClient::is_connected()) {
  3659. PStatTimer timer(_check_residency_pcollector);
  3660. check_nonresident_texture(_prepared_objects->_texture_residency.get_inactive_resident());
  3661. check_nonresident_texture(_prepared_objects->_texture_residency.get_active_resident());
  3662. // OpenGL provides no methods for querying whether a buffer object (vertex
  3663. // buffer) is resident. In fact, the API appears geared towards the
  3664. // assumption that such buffers are always resident. OK.
  3665. }
  3666. #endif
  3667. #ifndef OPENGLES_1
  3668. // This breaks shaders across multiple regions.
  3669. if (_vertex_array_shader_context != 0) {
  3670. _vertex_array_shader_context->disable_shader_vertex_arrays();
  3671. _vertex_array_shader = nullptr;
  3672. _vertex_array_shader_context = nullptr;
  3673. }
  3674. if (_texture_binding_shader_context != 0) {
  3675. _texture_binding_shader_context->disable_shader_texture_bindings();
  3676. _texture_binding_shader = nullptr;
  3677. _texture_binding_shader_context = nullptr;
  3678. }
  3679. if (_current_shader_context != 0) {
  3680. _current_shader_context->unbind();
  3681. _current_shader = nullptr;
  3682. _current_shader_context = nullptr;
  3683. }
  3684. _state_shader = nullptr;
  3685. #endif
  3686. // Respecify the active texture next frame, for good measure.
  3687. _active_texture_stage = -1;
  3688. // Calling glFlush() at the end of the frame is particularly necessary if
  3689. // this is a single-buffered visual, so that the frame will be finished
  3690. // drawing before we return to the application. It's not clear what effect
  3691. // this has on our total frame time. if (_force_flush ||
  3692. // _current_properties->is_single_buffered()) { gl_flush(); }
  3693. maybe_gl_finish();
  3694. GraphicsStateGuardian::end_frame(current_thread);
  3695. _renderbuffer_residency.end_frame(current_thread);
  3696. // Flush any PCollectors specific to this kind of GSG.
  3697. _primitive_batches_display_list_pcollector.flush_level();
  3698. _vertices_display_list_pcollector.flush_level();
  3699. _vertices_immediate_pcollector.flush_level();
  3700. // Now is a good time to delete any pending display lists.
  3701. #ifndef OPENGLES
  3702. #ifdef SUPPORT_FIXED_FUNCTION
  3703. if (has_fixed_function_pipeline() && display_lists) {
  3704. LightMutexHolder holder(_lock);
  3705. if (!_deleted_display_lists.empty()) {
  3706. DeletedNames::iterator ddli;
  3707. for (ddli = _deleted_display_lists.begin();
  3708. ddli != _deleted_display_lists.end();
  3709. ++ddli) {
  3710. if (GLCAT.is_debug()) {
  3711. GLCAT.debug()
  3712. << "releasing display list index " << (int)(*ddli) << "\n";
  3713. }
  3714. glDeleteLists((*ddli), 1);
  3715. }
  3716. _deleted_display_lists.clear();
  3717. }
  3718. }
  3719. #endif
  3720. // And deleted queries, too, unless we're using query timers in which case
  3721. // we'll need to reuse lots of them.
  3722. if (_supports_occlusion_query && !get_timer_queries_active()) {
  3723. LightMutexHolder holder(_lock);
  3724. if (!_deleted_queries.empty()) {
  3725. if (GLCAT.is_spam()) {
  3726. DeletedNames::iterator dqi;
  3727. for (dqi = _deleted_queries.begin();
  3728. dqi != _deleted_queries.end();
  3729. ++dqi) {
  3730. GLCAT.spam()
  3731. << "releasing query index " << (int)(*dqi) << "\n";
  3732. }
  3733. }
  3734. _glDeleteQueries(_deleted_queries.size(), &_deleted_queries[0]);
  3735. _deleted_queries.clear();
  3736. }
  3737. }
  3738. #endif // OPENGLES
  3739. #ifndef NDEBUG
  3740. if (_check_errors || (_supports_debug && gl_debug)) {
  3741. report_my_gl_errors();
  3742. } else {
  3743. // If _check_errors is false, we still want to check for errors once every
  3744. // second, so that we know if anything went wrong at all.
  3745. double current = ClockObject::get_global_clock()->get_frame_time();
  3746. if (current - _last_error_check >= 1.0) {
  3747. _last_error_check = current;
  3748. PStatTimer timer(_check_error_pcollector);
  3749. GLenum error_code = glGetError();
  3750. if (error_code != GL_NO_ERROR) {
  3751. int error_count = 0;
  3752. do {
  3753. ++error_count;
  3754. GLCAT.error()
  3755. << "GL error 0x" << hex << error_code << dec << " : "
  3756. << get_error_string(error_code) << "\n";
  3757. error_code = glGetError();
  3758. } while (error_code != GL_NO_ERROR);
  3759. if (error_count == 1) {
  3760. GLCAT.error()
  3761. << "An OpenGL error has occurred.";
  3762. } else {
  3763. GLCAT.error()
  3764. << error_count << " OpenGL errors have occurred.";
  3765. }
  3766. if (_supports_debug) {
  3767. GLCAT.error(false) << " Set gl-debug #t "
  3768. << "in your PRC file to display more information.\n";
  3769. } else {
  3770. GLCAT.error(false) << " Set gl-check-errors #t "
  3771. << "in your PRC file to display more information.\n";
  3772. }
  3773. _error_count += error_count;
  3774. if (_error_count >= gl_max_errors) {
  3775. panic_deactivate();
  3776. }
  3777. }
  3778. }
  3779. }
  3780. #endif
  3781. // Add in a newline to the spam output for improved legibility.
  3782. if (GLCAT.is_spam()) {
  3783. GLCAT.spam(false) << endl;
  3784. }
  3785. }
  3786. /**
  3787. * Called before a sequence of draw_primitive() functions are called, this
  3788. * should prepare the vertex data for rendering. It returns true if the
  3789. * vertices are ok, false to abort this group of primitives.
  3790. */
  3791. bool CLP(GraphicsStateGuardian)::
  3792. begin_draw_primitives(const GeomPipelineReader *geom_reader,
  3793. const GeomVertexDataPipelineReader *data_reader,
  3794. bool force) {
  3795. #ifndef NDEBUG
  3796. if (GLCAT.is_spam()) {
  3797. GLCAT.spam() << "begin_draw_primitives: " << *(data_reader->get_object()) << "\n";
  3798. }
  3799. #endif // NDEBUG
  3800. #ifndef OPENGLES_1
  3801. if (!has_fixed_function_pipeline()) {
  3802. // We can't draw without a shader bound in OpenGL ES 2. This shouldn't
  3803. // happen anyway unless the default shader failed to compile somehow.
  3804. if (_current_shader_context == nullptr) {
  3805. return false;
  3806. }
  3807. }
  3808. #endif
  3809. if (!GraphicsStateGuardian::begin_draw_primitives(geom_reader, data_reader, force)) {
  3810. return false;
  3811. }
  3812. nassertr(_data_reader != nullptr, false);
  3813. _geom_display_list = 0;
  3814. if (_auto_antialias_mode) {
  3815. switch (geom_reader->get_primitive_type()) {
  3816. case GeomPrimitive::PT_polygons:
  3817. case GeomPrimitive::PT_patches:
  3818. setup_antialias_polygon();
  3819. break;
  3820. case GeomPrimitive::PT_points:
  3821. setup_antialias_point();
  3822. break;
  3823. case GeomPrimitive::PT_lines:
  3824. setup_antialias_line();
  3825. break;
  3826. case GeomPrimitive::PT_none:
  3827. break;
  3828. }
  3829. int transparency_slot = TransparencyAttrib::get_class_slot();
  3830. int color_write_slot = ColorWriteAttrib::get_class_slot();
  3831. int color_blend_slot = ColorBlendAttrib::get_class_slot();
  3832. if (!_state_mask.get_bit(transparency_slot) ||
  3833. !_state_mask.get_bit(color_write_slot) ||
  3834. !_state_mask.get_bit(color_blend_slot)) {
  3835. do_issue_blending();
  3836. _state_mask.set_bit(transparency_slot);
  3837. _state_mask.set_bit(color_write_slot);
  3838. _state_mask.set_bit(color_blend_slot);
  3839. }
  3840. }
  3841. #ifdef SUPPORT_FIXED_FUNCTION
  3842. if (has_fixed_function_pipeline() && _data_reader->is_vertex_transformed()) {
  3843. // If the vertex data claims to be already transformed into clip
  3844. // coordinates, wipe out the current projection and modelview matrix (so
  3845. // we don't attempt to transform it again).
  3846. glMatrixMode(GL_PROJECTION);
  3847. glPushMatrix();
  3848. glLoadIdentity();
  3849. glMatrixMode(GL_MODELVIEW);
  3850. glPushMatrix();
  3851. glLoadIdentity();
  3852. }
  3853. #endif
  3854. #if !defined(OPENGLES) && defined(SUPPORT_FIXED_FUNCTION) // Display lists not supported by OpenGL ES.
  3855. if (has_fixed_function_pipeline() &&
  3856. /*geom_reader->get_usage_hint() == Geom::UH_static &&*/
  3857. _data_reader->get_usage_hint() == Geom::UH_static &&
  3858. display_lists) {
  3859. // If the geom claims to be totally static, try to build it into a display
  3860. // list.
  3861. // Before we compile or call a display list, make sure the current buffers
  3862. // are unbound, or the nVidia drivers may crash.
  3863. unbind_buffers();
  3864. GeomContext *gc = geom_reader->prepare_now(get_prepared_objects(), this);
  3865. nassertr(gc != nullptr, false);
  3866. CLP(GeomContext) *ggc = DCAST(CLP(GeomContext), gc);
  3867. //const CLP(GeomMunger) *gmunger = DCAST(CLP(GeomMunger), _munger);
  3868. UpdateSeq modified = max(geom_reader->get_modified(), _data_reader->get_modified());
  3869. if (ggc->get_display_list(_geom_display_list, nullptr, modified)) {
  3870. // If it hasn't been modified, just play the display list again.
  3871. if (GLCAT.is_spam()) {
  3872. GLCAT.spam()
  3873. << "calling display list " << (int)_geom_display_list << "\n";
  3874. }
  3875. glCallList(_geom_display_list);
  3876. #ifdef DO_PSTATS
  3877. _vertices_display_list_pcollector.add_level(ggc->_num_verts);
  3878. _primitive_batches_display_list_pcollector.add_level(1);
  3879. #endif
  3880. // And now we don't need to do anything else for this geom.
  3881. _geom_display_list = 0;
  3882. end_draw_primitives();
  3883. return false;
  3884. }
  3885. // Since we start this collector explicitly, we have to be sure to stop it
  3886. // again.
  3887. _load_display_list_pcollector.start();
  3888. if (GLCAT.is_debug()) {
  3889. GLCAT.debug()
  3890. << "compiling display list " << (int)_geom_display_list << "\n";
  3891. }
  3892. // If it has been modified, or this is the first time, then we need to
  3893. // build the display list up.
  3894. if (gl_compile_and_execute) {
  3895. glNewList(_geom_display_list, GL_COMPILE_AND_EXECUTE);
  3896. } else {
  3897. glNewList(_geom_display_list, GL_COMPILE);
  3898. }
  3899. #ifdef DO_PSTATS
  3900. // Count up the number of vertices used by primitives in the Geom, for
  3901. // PStats reporting.
  3902. ggc->_num_verts = 0;
  3903. for (int i = 0; i < geom_reader->get_num_primitives(); i++) {
  3904. ggc->_num_verts += geom_reader->get_primitive(i)->get_num_vertices();
  3905. }
  3906. #endif
  3907. }
  3908. #endif // OPENGLES
  3909. // Enable the appropriate vertex arrays, and disable any extra vertex arrays
  3910. // used by the previous rendering mode.
  3911. #ifdef SUPPORT_IMMEDIATE_MODE
  3912. _use_sender = !vertex_arrays;
  3913. #endif
  3914. #ifndef OPENGLES_1
  3915. if (_use_vertex_attrib_binding) {
  3916. const GeomVertexFormat *format = data_reader->get_format();
  3917. if (format != _current_vertex_format) {
  3918. update_shader_vertex_format(format);
  3919. }
  3920. }
  3921. #endif
  3922. {
  3923. // PStatGPUTimer timer(this, _vertex_array_update_pcollector);
  3924. #ifdef OPENGLES_1
  3925. if (!update_standard_vertex_arrays(force)) {
  3926. return false;
  3927. }
  3928. #else
  3929. if (_current_shader_context == 0) {
  3930. // No shader.
  3931. if (_vertex_array_shader_context != 0) {
  3932. _vertex_array_shader_context->disable_shader_vertex_arrays();
  3933. }
  3934. #ifdef SUPPORT_FIXED_FUNCTION
  3935. if (has_fixed_function_pipeline() && !update_standard_vertex_arrays(force)) {
  3936. return false;
  3937. }
  3938. #endif
  3939. } else {
  3940. #ifdef SUPPORT_FIXED_FUNCTION
  3941. if (has_fixed_function_pipeline()) {
  3942. // Shader.
  3943. if (_vertex_array_shader_context == 0 ||
  3944. _vertex_array_shader_context->uses_standard_vertex_arrays()) {
  3945. // Previous shader used standard arrays.
  3946. if (_current_shader_context->uses_standard_vertex_arrays()) {
  3947. // So does the current, so update them.
  3948. if (!update_standard_vertex_arrays(force)) {
  3949. return false;
  3950. }
  3951. } else {
  3952. // The current shader does not, so disable them entirely.
  3953. disable_standard_vertex_arrays();
  3954. }
  3955. }
  3956. #ifdef HAVE_CG
  3957. else if (_vertex_array_shader_context->is_of_type(CLP(CgShaderContext)::get_class_type())) {
  3958. // The previous shader was a Cg shader, which can leave a messy
  3959. // situation.
  3960. _vertex_array_shader_context->disable_shader_vertex_arrays();
  3961. }
  3962. #endif
  3963. }
  3964. #endif // SUPPORT_FIXED_FUNCTION
  3965. // Now update the vertex arrays for the current shader.
  3966. if (!_current_shader_context->
  3967. update_shader_vertex_arrays(_vertex_array_shader_context, force)) {
  3968. return false;
  3969. }
  3970. }
  3971. _vertex_array_shader = _current_shader;
  3972. _vertex_array_shader_context = _current_shader_context;
  3973. #endif // OPENGLES_1
  3974. }
  3975. report_my_gl_errors();
  3976. return true;
  3977. }
  3978. #ifdef SUPPORT_FIXED_FUNCTION
  3979. /**
  3980. * Disables any unneeded vertex arrays that were previously enabled, and
  3981. * enables any vertex arrays that are needed that were not previously enabled
  3982. * (or, sets up an immediate-mode sender). Called only from
  3983. * begin_draw_primitives. Used only when the standard (non-shader) pipeline
  3984. * is about to be used - glShaderContexts are responsible for setting up their
  3985. * own vertex arrays.
  3986. */
  3987. bool CLP(GraphicsStateGuardian)::
  3988. update_standard_vertex_arrays(bool force) {
  3989. #ifdef SUPPORT_IMMEDIATE_MODE
  3990. if (_use_sender) {
  3991. // We must use immediate mode to render primitives.
  3992. _sender.clear();
  3993. _sender.add_column(_data_reader, InternalName::get_normal(),
  3994. nullptr, nullptr, GLPf(Normal3), nullptr);
  3995. #ifndef NDEBUG
  3996. if (_show_texture_usage) {
  3997. // In show_texture_usage mode, all colors are white, so as not to
  3998. // contaminate the texture color.
  3999. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  4000. } else
  4001. #endif // NDEBUG
  4002. if (!_sender.add_column(_data_reader, InternalName::get_color(),
  4003. nullptr, nullptr, GLPf(Color3), GLPf(Color4))) {
  4004. // If we didn't have a color column, the item color is white.
  4005. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  4006. }
  4007. // Now set up each of the active texture coordinate stages--or at least
  4008. // those for which we're not generating texture coordinates automatically.
  4009. int max_stage_index = _target_texture->get_num_on_ff_stages();
  4010. int stage_index = 0;
  4011. while (stage_index < max_stage_index) {
  4012. TextureStage *stage = _target_texture->get_on_ff_stage(stage_index);
  4013. if (!_target_tex_gen->has_gen_texcoord_stage(stage)) {
  4014. // This stage is not one of the stages that doesn't need texcoords
  4015. // issued for it.
  4016. const InternalName *name = stage->get_texcoord_name();
  4017. if (stage_index == 0) {
  4018. // Use the original functions for stage 0, in case we don't support
  4019. // multitexture.
  4020. _sender.add_column(_data_reader, name,
  4021. GLPf(TexCoord1), GLPf(TexCoord2),
  4022. GLPf(TexCoord3), GLPf(TexCoord4));
  4023. } else {
  4024. // Other stages require the multitexture functions.
  4025. _sender.add_texcoord_column(_data_reader, name, stage_index,
  4026. GLf(_glMultiTexCoord1), GLf(_glMultiTexCoord2),
  4027. GLf(_glMultiTexCoord3), GLf(_glMultiTexCoord4));
  4028. }
  4029. }
  4030. ++stage_index;
  4031. }
  4032. // Be sure also to disable any texture stages we had enabled before.
  4033. while (stage_index < _last_max_stage_index) {
  4034. _glClientActiveTexture(GL_TEXTURE0 + stage_index);
  4035. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  4036. ++stage_index;
  4037. }
  4038. _last_max_stage_index = max_stage_index;
  4039. // We must add vertex last, because glVertex3f() is the key function call
  4040. // that actually issues the vertex.
  4041. _sender.add_column(_data_reader, InternalName::get_vertex(),
  4042. nullptr, GLPf(Vertex2), GLPf(Vertex3), GLPf(Vertex4));
  4043. } else
  4044. #endif // SUPPORT_IMMEDIATE_MODE
  4045. {
  4046. // We may use vertex arrays or buffers to render primitives.
  4047. const GeomVertexArrayDataHandle *array_reader;
  4048. const unsigned char *client_pointer;
  4049. int num_values;
  4050. Geom::NumericType numeric_type;
  4051. int start;
  4052. int stride;
  4053. if (_data_reader->get_normal_info(array_reader, numeric_type,
  4054. start, stride)) {
  4055. if (!setup_array_data(client_pointer, array_reader, force)) {
  4056. return false;
  4057. }
  4058. glNormalPointer(get_numeric_type(numeric_type), stride,
  4059. client_pointer + start);
  4060. glEnableClientState(GL_NORMAL_ARRAY);
  4061. } else {
  4062. glDisableClientState(GL_NORMAL_ARRAY);
  4063. }
  4064. #ifndef NDEBUG
  4065. if (_show_texture_usage) {
  4066. // In show_texture_usage mode, all colors are white, so as not to
  4067. // contaminate the texture color.
  4068. glDisableClientState(GL_COLOR_ARRAY);
  4069. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  4070. } else
  4071. #endif // NDEBUG
  4072. if (_vertex_colors_enabled &&
  4073. _data_reader->get_color_info(array_reader, num_values, numeric_type,
  4074. start, stride)) {
  4075. if (!setup_array_data(client_pointer, array_reader, force)) {
  4076. return false;
  4077. }
  4078. if (numeric_type == Geom::NT_packed_dabc) {
  4079. glColorPointer(GL_BGRA, GL_UNSIGNED_BYTE,
  4080. stride, client_pointer + start);
  4081. } else {
  4082. glColorPointer(num_values, get_numeric_type(numeric_type),
  4083. stride, client_pointer + start);
  4084. }
  4085. glEnableClientState(GL_COLOR_ARRAY);
  4086. } else {
  4087. glDisableClientState(GL_COLOR_ARRAY);
  4088. // Since we don't have per-vertex color, the implicit color is white.
  4089. if (_color_scale_via_lighting) {
  4090. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  4091. } else {
  4092. LColor color = _scene_graph_color;
  4093. color.componentwise_mult(_current_color_scale);
  4094. GLPf(Color4)(color[0], color[1], color[2], color[3]);
  4095. }
  4096. }
  4097. // Now set up each of the active texture coordinate stages--or at least
  4098. // those for which we're not generating texture coordinates automatically.
  4099. int max_stage_index = _target_texture->get_num_on_ff_stages();
  4100. int stage_index = 0;
  4101. while (stage_index < max_stage_index) {
  4102. _glClientActiveTexture(GL_TEXTURE0 + stage_index);
  4103. TextureStage *stage = _target_texture->get_on_ff_stage(stage_index);
  4104. if (!_target_tex_gen->has_gen_texcoord_stage(stage)) {
  4105. // This stage is not one of the stages that doesn't need texcoords
  4106. // issued for it.
  4107. const InternalName *name = stage->get_texcoord_name();
  4108. if (_data_reader->get_array_info(name, array_reader, num_values,
  4109. numeric_type, start, stride)) {
  4110. // The vertex data does have texcoords for this stage.
  4111. if (!setup_array_data(client_pointer, array_reader, force)) {
  4112. return false;
  4113. }
  4114. glTexCoordPointer(num_values, get_numeric_type(numeric_type),
  4115. stride, client_pointer + start);
  4116. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  4117. } else {
  4118. // The vertex data doesn't have texcoords for this stage (even
  4119. // though they're needed).
  4120. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  4121. }
  4122. } else {
  4123. // No texcoords are needed for this stage.
  4124. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  4125. }
  4126. ++stage_index;
  4127. }
  4128. // Be sure also to disable any texture stages we had enabled before.
  4129. while (stage_index < _last_max_stage_index) {
  4130. _glClientActiveTexture(GL_TEXTURE0 + stage_index);
  4131. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  4132. ++stage_index;
  4133. }
  4134. _last_max_stage_index = max_stage_index;
  4135. // There's no requirement that we add vertices last, but we do anyway.
  4136. if (_data_reader->get_vertex_info(array_reader, num_values, numeric_type,
  4137. start, stride)) {
  4138. if (!setup_array_data(client_pointer, array_reader, force)) {
  4139. return false;
  4140. }
  4141. glVertexPointer(num_values, get_numeric_type(numeric_type),
  4142. stride, client_pointer + start);
  4143. glEnableClientState(GL_VERTEX_ARRAY);
  4144. }
  4145. }
  4146. return true;
  4147. }
  4148. #endif // SUPPORT_FIXED_FUNCTION
  4149. /**
  4150. * Ensures the vertex and array buffers are no longer bound. Some graphics
  4151. * drivers crash if these are left bound indiscriminantly.
  4152. */
  4153. void CLP(GraphicsStateGuardian)::
  4154. unbind_buffers() {
  4155. if (_current_vbuffer_index != 0) {
  4156. if (GLCAT.is_spam() && gl_debug_buffers) {
  4157. GLCAT.spam()
  4158. << "unbinding vertex buffer\n";
  4159. }
  4160. _glBindBuffer(GL_ARRAY_BUFFER, 0);
  4161. _current_vbuffer_index = 0;
  4162. }
  4163. if (_current_ibuffer_index != 0) {
  4164. if (GLCAT.is_spam() && gl_debug_buffers) {
  4165. GLCAT.spam()
  4166. << "unbinding index buffer\n";
  4167. }
  4168. _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  4169. _current_ibuffer_index = 0;
  4170. }
  4171. #ifndef OPENGLES
  4172. if (_current_vertex_buffers.size() > 1 && _supports_multi_bind) {
  4173. _glBindVertexBuffers(0, _current_vertex_buffers.size(), nullptr, nullptr, nullptr);
  4174. } else {
  4175. for (size_t i = 0; i < _current_vertex_buffers.size(); ++i) {
  4176. if (_current_vertex_buffers[i] != 0) {
  4177. _glBindVertexBuffer((GLuint)i, 0, 0, 0);
  4178. }
  4179. }
  4180. }
  4181. _current_vertex_buffers.clear();
  4182. #endif
  4183. #ifdef SUPPORT_FIXED_FUNCTION
  4184. if (has_fixed_function_pipeline()) {
  4185. disable_standard_vertex_arrays();
  4186. }
  4187. #endif
  4188. }
  4189. #ifdef SUPPORT_FIXED_FUNCTION
  4190. /**
  4191. * Used to disable all the standard vertex arrays that are currently enabled.
  4192. * glShaderContexts are responsible for setting up their own vertex arrays,
  4193. * but before they can do so, the standard vertex arrays need to be disabled
  4194. * to get them "out of the way." Called only from begin_draw_primitives.
  4195. */
  4196. void CLP(GraphicsStateGuardian)::
  4197. disable_standard_vertex_arrays() {
  4198. #ifdef SUPPORT_IMMEDIATE_MODE
  4199. if (_use_sender) return;
  4200. #endif
  4201. glDisableClientState(GL_NORMAL_ARRAY);
  4202. glDisableClientState(GL_COLOR_ARRAY);
  4203. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  4204. for (int stage_index=0; stage_index < _last_max_stage_index; stage_index++) {
  4205. _glClientActiveTexture(GL_TEXTURE0 + stage_index);
  4206. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  4207. }
  4208. _last_max_stage_index = 0;
  4209. glDisableClientState(GL_VERTEX_ARRAY);
  4210. report_my_gl_errors();
  4211. }
  4212. #endif // SUPPORT_FIXED_FUNCTION
  4213. #ifndef OPENGLES_1
  4214. /**
  4215. * Updates the vertex format used by the shader. This is still an
  4216. * experimental feature.
  4217. */
  4218. void CLP(GraphicsStateGuardian)::
  4219. update_shader_vertex_format(const GeomVertexFormat *format) {
  4220. size_t num_columns = format->get_num_columns();
  4221. for (size_t ci = 0; ci < num_columns; ++ci) {
  4222. GLuint binding = format->get_array_with(ci);
  4223. const GeomVertexColumn *column = format->get_column(ci);
  4224. // Needs improvement, obviously.
  4225. const InternalName *name = column->get_name();
  4226. GLuint loc;
  4227. if (name == InternalName::get_vertex()) {
  4228. loc = 0;
  4229. } else if (name == InternalName::get_transform_weight()) {
  4230. loc = 1;
  4231. } else if (name == InternalName::get_normal()) {
  4232. loc = 2;
  4233. } else if (name == InternalName::get_color()) {
  4234. loc = 3;
  4235. } else if (name == InternalName::get_transform_index()) {
  4236. loc = 7;
  4237. } else if (name == InternalName::get_texcoord()) {
  4238. loc = 8;
  4239. } else {
  4240. // Not yet supported, ignore for now. This system will be improved.
  4241. continue;
  4242. }
  4243. if (_vertex_attrib_columns[loc] != nullptr &&
  4244. _vertex_attrib_columns[loc]->compare_to(*column) == 0) {
  4245. continue;
  4246. }
  4247. _vertex_attrib_columns[loc] = column;
  4248. GLuint offset = column->get_start();
  4249. GLenum type = get_numeric_type(column->get_numeric_type());
  4250. GLboolean normalized = (column->get_contents() == GeomEnums::C_color);
  4251. GLint size = column->get_num_values();
  4252. if (column->get_numeric_type() == GeomEnums::NT_packed_dabc) {
  4253. // GL_BGRA is a special accepted value available since OpenGL 3.2. It
  4254. // requires us to pass GL_TRUE for normalized.
  4255. size = GL_BGRA;
  4256. normalized = GL_TRUE;
  4257. }
  4258. for (int i = 0; i < column->get_num_elements(); ++i) {
  4259. if (loc == 7) { // Temp hack
  4260. _glVertexAttribIFormat(loc, size, type, offset);
  4261. } else {
  4262. _glVertexAttribFormat(loc, size, type, normalized, offset);
  4263. }
  4264. _glVertexAttribBinding(loc, binding);
  4265. offset += column->get_element_stride();
  4266. ++loc;
  4267. }
  4268. }
  4269. size_t num_arrays = format->get_num_arrays();
  4270. for (size_t ai = 0; ai < num_arrays; ++ai) {
  4271. _glVertexBindingDivisor(ai, format->get_array(ai)->get_divisor());
  4272. }
  4273. _current_vertex_format = format;
  4274. }
  4275. #endif
  4276. /**
  4277. * Draws a series of disconnected triangles.
  4278. */
  4279. bool CLP(GraphicsStateGuardian)::
  4280. draw_triangles(const GeomPrimitivePipelineReader *reader, bool force) {
  4281. // PStatGPUTimer timer(this, _draw_primitive_pcollector,
  4282. // reader->get_current_thread());
  4283. #ifndef NDEBUG
  4284. if (GLCAT.is_spam()) {
  4285. GLCAT.spam() << "draw_triangles: " << *(reader->get_object()) << "\n";
  4286. }
  4287. #endif // NDEBUG
  4288. #ifdef SUPPORT_IMMEDIATE_MODE
  4289. if (_use_sender) {
  4290. draw_immediate_simple_primitives(reader, GL_TRIANGLES);
  4291. } else
  4292. #endif // SUPPORT_IMMEDIATE_MODE
  4293. {
  4294. int num_vertices = reader->get_num_vertices();
  4295. _vertices_tri_pcollector.add_level(num_vertices);
  4296. _primitive_batches_tri_pcollector.add_level(1);
  4297. if (reader->is_indexed()) {
  4298. const unsigned char *client_pointer;
  4299. if (!setup_primitive(client_pointer, reader, force)) {
  4300. return false;
  4301. }
  4302. #ifndef OPENGLES_1
  4303. if (_supports_geometry_instancing && _instance_count > 0) {
  4304. _glDrawElementsInstanced(GL_TRIANGLES, num_vertices,
  4305. get_numeric_type(reader->get_index_type()),
  4306. client_pointer, _instance_count);
  4307. } else
  4308. #endif
  4309. {
  4310. _glDrawRangeElements(GL_TRIANGLES,
  4311. reader->get_min_vertex(),
  4312. reader->get_max_vertex(),
  4313. num_vertices,
  4314. get_numeric_type(reader->get_index_type()),
  4315. client_pointer);
  4316. }
  4317. } else {
  4318. #ifndef OPENGLES_1
  4319. if (_supports_geometry_instancing && _instance_count > 0) {
  4320. _glDrawArraysInstanced(GL_TRIANGLES,
  4321. reader->get_first_vertex(),
  4322. num_vertices, _instance_count);
  4323. } else
  4324. #endif
  4325. {
  4326. glDrawArrays(GL_TRIANGLES,
  4327. reader->get_first_vertex(),
  4328. num_vertices);
  4329. }
  4330. }
  4331. }
  4332. report_my_gl_errors();
  4333. return true;
  4334. }
  4335. /**
  4336. * Draws a series of disconnected triangles with adjacency information.
  4337. */
  4338. #ifndef OPENGLES
  4339. bool CLP(GraphicsStateGuardian)::
  4340. draw_triangles_adj(const GeomPrimitivePipelineReader *reader, bool force) {
  4341. // PStatGPUTimer timer(this, _draw_primitive_pcollector,
  4342. // reader->get_current_thread());
  4343. #ifndef NDEBUG
  4344. if (GLCAT.is_spam()) {
  4345. GLCAT.spam() << "draw_triangles_adj: " << *(reader->get_object()) << "\n";
  4346. }
  4347. #endif // NDEBUG
  4348. #ifdef SUPPORT_IMMEDIATE_MODE
  4349. if (_use_sender) {
  4350. draw_immediate_simple_primitives(reader, GL_TRIANGLES_ADJACENCY);
  4351. } else
  4352. #endif // SUPPORT_IMMEDIATE_MODE
  4353. {
  4354. int num_vertices = reader->get_num_vertices();
  4355. _vertices_tri_pcollector.add_level(num_vertices);
  4356. _primitive_batches_tri_pcollector.add_level(1);
  4357. if (reader->is_indexed()) {
  4358. const unsigned char *client_pointer;
  4359. if (!setup_primitive(client_pointer, reader, force)) {
  4360. return false;
  4361. }
  4362. if (_supports_geometry_instancing && _instance_count > 0) {
  4363. _glDrawElementsInstanced(GL_TRIANGLES_ADJACENCY, num_vertices,
  4364. get_numeric_type(reader->get_index_type()),
  4365. client_pointer, _instance_count);
  4366. } else {
  4367. _glDrawRangeElements(GL_TRIANGLES_ADJACENCY,
  4368. reader->get_min_vertex(),
  4369. reader->get_max_vertex(),
  4370. num_vertices,
  4371. get_numeric_type(reader->get_index_type()),
  4372. client_pointer);
  4373. }
  4374. } else {
  4375. if (_supports_geometry_instancing && _instance_count > 0) {
  4376. _glDrawArraysInstanced(GL_TRIANGLES_ADJACENCY,
  4377. reader->get_first_vertex(),
  4378. num_vertices, _instance_count);
  4379. } else {
  4380. glDrawArrays(GL_TRIANGLES_ADJACENCY,
  4381. reader->get_first_vertex(),
  4382. num_vertices);
  4383. }
  4384. }
  4385. }
  4386. report_my_gl_errors();
  4387. return true;
  4388. }
  4389. #endif // OPENGLES
  4390. /**
  4391. * Draws a series of triangle strips.
  4392. */
  4393. bool CLP(GraphicsStateGuardian)::
  4394. draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force) {
  4395. // PStatGPUTimer timer(this, _draw_primitive_pcollector,
  4396. // reader->get_current_thread());
  4397. report_my_gl_errors();
  4398. #ifndef NDEBUG
  4399. if (GLCAT.is_spam()) {
  4400. GLCAT.spam() << "draw_tristrips: " << *(reader->get_object()) << "\n";
  4401. }
  4402. #endif // NDEBUG
  4403. #ifdef SUPPORT_IMMEDIATE_MODE
  4404. if (_use_sender) {
  4405. draw_immediate_composite_primitives(reader, GL_TRIANGLE_STRIP);
  4406. } else
  4407. #endif // SUPPORT_IMMEDIATE_MODE
  4408. {
  4409. if (connect_triangle_strips && _render_mode != RenderModeAttrib::M_wireframe) {
  4410. // One long triangle strip, connected by the degenerate vertices that
  4411. // have already been set up within the primitive.
  4412. int num_vertices = reader->get_num_vertices();
  4413. _vertices_tristrip_pcollector.add_level(num_vertices);
  4414. _primitive_batches_tristrip_pcollector.add_level(1);
  4415. if (reader->is_indexed()) {
  4416. const unsigned char *client_pointer;
  4417. if (!setup_primitive(client_pointer, reader, force)) {
  4418. return false;
  4419. }
  4420. #ifndef OPENGLES_1
  4421. if (_supports_geometry_instancing && _instance_count > 0) {
  4422. _glDrawElementsInstanced(GL_TRIANGLE_STRIP, num_vertices,
  4423. get_numeric_type(reader->get_index_type()),
  4424. client_pointer, _instance_count);
  4425. } else
  4426. #endif
  4427. {
  4428. _glDrawRangeElements(GL_TRIANGLE_STRIP,
  4429. reader->get_min_vertex(),
  4430. reader->get_max_vertex(),
  4431. num_vertices,
  4432. get_numeric_type(reader->get_index_type()),
  4433. client_pointer);
  4434. }
  4435. } else {
  4436. #ifndef OPENGLES_1
  4437. if (_supports_geometry_instancing && _instance_count > 0) {
  4438. _glDrawArraysInstanced(GL_TRIANGLE_STRIP,
  4439. reader->get_first_vertex(),
  4440. num_vertices, _instance_count);
  4441. } else
  4442. #endif
  4443. {
  4444. glDrawArrays(GL_TRIANGLE_STRIP,
  4445. reader->get_first_vertex(),
  4446. num_vertices);
  4447. }
  4448. }
  4449. } else {
  4450. // Send the individual triangle strips, stepping over the degenerate
  4451. // vertices.
  4452. CPTA_int ends = reader->get_ends();
  4453. _primitive_batches_tristrip_pcollector.add_level(ends.size());
  4454. if (reader->is_indexed()) {
  4455. const unsigned char *client_pointer;
  4456. if (!setup_primitive(client_pointer, reader, force)) {
  4457. return false;
  4458. }
  4459. int index_stride = reader->get_index_stride();
  4460. GeomVertexReader mins(reader->get_mins(), 0);
  4461. GeomVertexReader maxs(reader->get_maxs(), 0);
  4462. nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() &&
  4463. reader->get_maxs()->get_num_rows() == (int)ends.size(), false);
  4464. unsigned int start = 0;
  4465. for (size_t i = 0; i < ends.size(); i++) {
  4466. _vertices_tristrip_pcollector.add_level(ends[i] - start);
  4467. #ifndef OPENGLES_1
  4468. if (_supports_geometry_instancing && _instance_count > 0) {
  4469. _glDrawElementsInstanced(GL_TRIANGLE_STRIP, ends[i] - start,
  4470. get_numeric_type(reader->get_index_type()),
  4471. client_pointer + start * index_stride,
  4472. _instance_count);
  4473. } else
  4474. #endif
  4475. {
  4476. _glDrawRangeElements(GL_TRIANGLE_STRIP,
  4477. mins.get_data1i(), maxs.get_data1i(),
  4478. ends[i] - start,
  4479. get_numeric_type(reader->get_index_type()),
  4480. client_pointer + start * index_stride);
  4481. }
  4482. start = ends[i] + 2;
  4483. }
  4484. } else {
  4485. unsigned int start = 0;
  4486. int first_vertex = reader->get_first_vertex();
  4487. for (size_t i = 0; i < ends.size(); i++) {
  4488. _vertices_tristrip_pcollector.add_level(ends[i] - start);
  4489. #ifndef OPENGLES_1
  4490. if (_supports_geometry_instancing && _instance_count > 0) {
  4491. _glDrawArraysInstanced(GL_TRIANGLE_STRIP, first_vertex + start,
  4492. ends[i] - start, _instance_count);
  4493. } else
  4494. #endif
  4495. {
  4496. glDrawArrays(GL_TRIANGLE_STRIP, first_vertex + start,
  4497. ends[i] - start);
  4498. }
  4499. start = ends[i] + 2;
  4500. }
  4501. }
  4502. }
  4503. }
  4504. report_my_gl_errors();
  4505. return true;
  4506. }
  4507. /**
  4508. * Draws a series of triangle strips with adjacency information.
  4509. */
  4510. #ifndef OPENGLES
  4511. bool CLP(GraphicsStateGuardian)::
  4512. draw_tristrips_adj(const GeomPrimitivePipelineReader *reader, bool force) {
  4513. // PStatGPUTimer timer(this, _draw_primitive_pcollector,
  4514. // reader->get_current_thread());
  4515. report_my_gl_errors();
  4516. #ifndef NDEBUG
  4517. if (GLCAT.is_spam()) {
  4518. GLCAT.spam() << "draw_tristrips_adj: " << *(reader->get_object()) << "\n";
  4519. }
  4520. #endif // NDEBUG
  4521. #ifdef SUPPORT_IMMEDIATE_MODE
  4522. if (_use_sender) {
  4523. draw_immediate_composite_primitives(reader, GL_TRIANGLE_STRIP_ADJACENCY);
  4524. } else
  4525. #endif // SUPPORT_IMMEDIATE_MODE
  4526. {
  4527. if (reader->is_indexed() &&
  4528. (_supported_geom_rendering & GeomEnums::GR_strip_cut_index) != 0) {
  4529. // One long line strip, connected by strip cut indices.
  4530. if (_explicit_primitive_restart) {
  4531. glEnable(GL_PRIMITIVE_RESTART);
  4532. _glPrimitiveRestartIndex(reader->get_strip_cut_index());
  4533. }
  4534. int num_vertices = reader->get_num_vertices();
  4535. _vertices_tristrip_pcollector.add_level(num_vertices);
  4536. _primitive_batches_tristrip_pcollector.add_level(1);
  4537. if (reader->is_indexed()) {
  4538. const unsigned char *client_pointer;
  4539. if (!setup_primitive(client_pointer, reader, force)) {
  4540. return false;
  4541. }
  4542. if (_supports_geometry_instancing && _instance_count > 0) {
  4543. _glDrawElementsInstanced(GL_TRIANGLE_STRIP_ADJACENCY, num_vertices,
  4544. get_numeric_type(reader->get_index_type()),
  4545. client_pointer, _instance_count);
  4546. } else {
  4547. _glDrawRangeElements(GL_TRIANGLE_STRIP_ADJACENCY,
  4548. reader->get_min_vertex(),
  4549. reader->get_max_vertex(),
  4550. num_vertices,
  4551. get_numeric_type(reader->get_index_type()),
  4552. client_pointer);
  4553. }
  4554. } else {
  4555. if (_supports_geometry_instancing && _instance_count > 0) {
  4556. _glDrawArraysInstanced(GL_TRIANGLE_STRIP_ADJACENCY,
  4557. reader->get_first_vertex(),
  4558. num_vertices, _instance_count);
  4559. } else {
  4560. glDrawArrays(GL_TRIANGLE_STRIP_ADJACENCY,
  4561. reader->get_first_vertex(),
  4562. num_vertices);
  4563. }
  4564. }
  4565. if (_explicit_primitive_restart) {
  4566. glDisable(GL_PRIMITIVE_RESTART);
  4567. }
  4568. } else {
  4569. // Send the individual triangle strips, stepping over the degenerate
  4570. // vertices.
  4571. CPTA_int ends = reader->get_ends();
  4572. _primitive_batches_tristrip_pcollector.add_level(ends.size());
  4573. if (reader->is_indexed()) {
  4574. const unsigned char *client_pointer;
  4575. if (!setup_primitive(client_pointer, reader, force)) {
  4576. return false;
  4577. }
  4578. int index_stride = reader->get_index_stride();
  4579. GeomVertexReader mins(reader->get_mins(), 0);
  4580. GeomVertexReader maxs(reader->get_maxs(), 0);
  4581. nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() &&
  4582. reader->get_maxs()->get_num_rows() == (int)ends.size(), false);
  4583. unsigned int start = 0;
  4584. for (size_t i = 0; i < ends.size(); i++) {
  4585. _vertices_tristrip_pcollector.add_level(ends[i] - start);
  4586. if (_supports_geometry_instancing && _instance_count > 0) {
  4587. _glDrawElementsInstanced(GL_TRIANGLE_STRIP_ADJACENCY, ends[i] - start,
  4588. get_numeric_type(reader->get_index_type()),
  4589. client_pointer + start * index_stride,
  4590. _instance_count);
  4591. } else {
  4592. _glDrawRangeElements(GL_TRIANGLE_STRIP_ADJACENCY,
  4593. mins.get_data1i(), maxs.get_data1i(),
  4594. ends[i] - start,
  4595. get_numeric_type(reader->get_index_type()),
  4596. client_pointer + start * index_stride);
  4597. }
  4598. start = ends[i] + 1;
  4599. }
  4600. } else {
  4601. unsigned int start = 0;
  4602. int first_vertex = reader->get_first_vertex();
  4603. for (size_t i = 0; i < ends.size(); i++) {
  4604. _vertices_tristrip_pcollector.add_level(ends[i] - start);
  4605. if (_supports_geometry_instancing && _instance_count > 0) {
  4606. _glDrawArraysInstanced(GL_TRIANGLE_STRIP_ADJACENCY, first_vertex + start,
  4607. ends[i] - start, _instance_count);
  4608. } else {
  4609. glDrawArrays(GL_TRIANGLE_STRIP_ADJACENCY, first_vertex + start,
  4610. ends[i] - start);
  4611. }
  4612. start = ends[i] + 1;
  4613. }
  4614. }
  4615. }
  4616. }
  4617. report_my_gl_errors();
  4618. return true;
  4619. }
  4620. #endif // OPENGLES
  4621. /**
  4622. * Draws a series of triangle fans.
  4623. */
  4624. bool CLP(GraphicsStateGuardian)::
  4625. draw_trifans(const GeomPrimitivePipelineReader *reader, bool force) {
  4626. // PStatGPUTimer timer(this, _draw_primitive_pcollector,
  4627. // reader->get_current_thread());
  4628. #ifndef NDEBUG
  4629. if (GLCAT.is_spam()) {
  4630. GLCAT.spam() << "draw_trifans: " << *(reader->get_object()) << "\n";
  4631. }
  4632. #endif // NDEBUG
  4633. #ifdef SUPPORT_IMMEDIATE_MODE
  4634. if (_use_sender) {
  4635. draw_immediate_composite_primitives(reader, GL_TRIANGLE_FAN);
  4636. } else
  4637. #endif // SUPPORT_IMMEDIATE_MODE
  4638. {
  4639. // Send the individual triangle fans. There's no connecting fans with
  4640. // degenerate vertices, so no worries about that.
  4641. CPTA_int ends = reader->get_ends();
  4642. _primitive_batches_trifan_pcollector.add_level(ends.size());
  4643. if (reader->is_indexed()) {
  4644. const unsigned char *client_pointer;
  4645. if (!setup_primitive(client_pointer, reader, force)) {
  4646. return false;
  4647. }
  4648. int index_stride = reader->get_index_stride();
  4649. GeomVertexReader mins(reader->get_mins(), 0);
  4650. GeomVertexReader maxs(reader->get_maxs(), 0);
  4651. nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() &&
  4652. reader->get_maxs()->get_num_rows() == (int)ends.size(), false);
  4653. unsigned int start = 0;
  4654. for (size_t i = 0; i < ends.size(); i++) {
  4655. _vertices_trifan_pcollector.add_level(ends[i] - start);
  4656. #ifndef OPENGLES_1
  4657. if (_supports_geometry_instancing && _instance_count > 0) {
  4658. _glDrawElementsInstanced(GL_TRIANGLE_FAN, ends[i] - start,
  4659. get_numeric_type(reader->get_index_type()),
  4660. client_pointer + start * index_stride,
  4661. _instance_count);
  4662. } else
  4663. #endif
  4664. {
  4665. _glDrawRangeElements(GL_TRIANGLE_FAN,
  4666. mins.get_data1i(), maxs.get_data1i(), ends[i] - start,
  4667. get_numeric_type(reader->get_index_type()),
  4668. client_pointer + start * index_stride);
  4669. }
  4670. start = ends[i];
  4671. }
  4672. } else {
  4673. unsigned int start = 0;
  4674. int first_vertex = reader->get_first_vertex();
  4675. for (size_t i = 0; i < ends.size(); i++) {
  4676. _vertices_trifan_pcollector.add_level(ends[i] - start);
  4677. #ifndef OPENGLES_1
  4678. if (_supports_geometry_instancing && _instance_count > 0) {
  4679. _glDrawArraysInstanced(GL_TRIANGLE_FAN, first_vertex + start,
  4680. ends[i] - start, _instance_count);
  4681. } else
  4682. #endif
  4683. {
  4684. glDrawArrays(GL_TRIANGLE_FAN, first_vertex + start,
  4685. ends[i] - start);
  4686. }
  4687. start = ends[i];
  4688. }
  4689. }
  4690. }
  4691. report_my_gl_errors();
  4692. return true;
  4693. }
  4694. /**
  4695. * Draws a series of "patches", which can only be processed by a tessellation
  4696. * shader.
  4697. */
  4698. bool CLP(GraphicsStateGuardian)::
  4699. draw_patches(const GeomPrimitivePipelineReader *reader, bool force) {
  4700. // PStatGPUTimer timer(this, _draw_primitive_pcollector,
  4701. // reader->get_current_thread());
  4702. #ifndef NDEBUG
  4703. if (GLCAT.is_spam()) {
  4704. GLCAT.spam() << "draw_patches: " << *(reader->get_object()) << "\n";
  4705. }
  4706. #endif // NDEBUG
  4707. if (!get_supports_tessellation_shaders()) {
  4708. return false;
  4709. }
  4710. #ifndef OPENGLES
  4711. _glPatchParameteri(GL_PATCH_VERTICES, reader->get_object()->get_num_vertices_per_primitive());
  4712. #ifdef SUPPORT_IMMEDIATE_MODE
  4713. if (_use_sender) {
  4714. draw_immediate_simple_primitives(reader, GL_PATCHES);
  4715. } else
  4716. #endif // SUPPORT_IMMEDIATE_MODE
  4717. {
  4718. int num_vertices = reader->get_num_vertices();
  4719. _vertices_patch_pcollector.add_level(num_vertices);
  4720. _primitive_batches_patch_pcollector.add_level(1);
  4721. if (reader->is_indexed()) {
  4722. const unsigned char *client_pointer;
  4723. if (!setup_primitive(client_pointer, reader, force)) {
  4724. return false;
  4725. }
  4726. #ifndef OPENGLES_1
  4727. if (_supports_geometry_instancing && _instance_count > 0) {
  4728. _glDrawElementsInstanced(GL_PATCHES, num_vertices,
  4729. get_numeric_type(reader->get_index_type()),
  4730. client_pointer, _instance_count);
  4731. } else
  4732. #endif
  4733. {
  4734. _glDrawRangeElements(GL_PATCHES,
  4735. reader->get_min_vertex(),
  4736. reader->get_max_vertex(),
  4737. num_vertices,
  4738. get_numeric_type(reader->get_index_type()),
  4739. client_pointer);
  4740. }
  4741. } else {
  4742. #ifndef OPENGLES_1
  4743. if (_supports_geometry_instancing && _instance_count > 0) {
  4744. _glDrawArraysInstanced(GL_PATCHES,
  4745. reader->get_first_vertex(),
  4746. num_vertices, _instance_count);
  4747. } else
  4748. #endif
  4749. {
  4750. glDrawArrays(GL_PATCHES,
  4751. reader->get_first_vertex(),
  4752. num_vertices);
  4753. }
  4754. }
  4755. }
  4756. #endif // OPENGLES
  4757. report_my_gl_errors();
  4758. return true;
  4759. }
  4760. /**
  4761. * Draws a series of disconnected line segments.
  4762. */
  4763. bool CLP(GraphicsStateGuardian)::
  4764. draw_lines(const GeomPrimitivePipelineReader *reader, bool force) {
  4765. // PStatGPUTimer timer(this, _draw_primitive_pcollector,
  4766. // reader->get_current_thread());
  4767. #ifndef NDEBUG
  4768. if (GLCAT.is_spam()) {
  4769. GLCAT.spam() << "draw_lines: " << *(reader->get_object()) << "\n";
  4770. }
  4771. #endif // NDEBUG
  4772. #ifdef SUPPORT_IMMEDIATE_MODE
  4773. if (_use_sender) {
  4774. draw_immediate_simple_primitives(reader, GL_LINES);
  4775. } else
  4776. #endif // SUPPORT_IMMEDIATE_MODE
  4777. {
  4778. int num_vertices = reader->get_num_vertices();
  4779. _vertices_other_pcollector.add_level(num_vertices);
  4780. _primitive_batches_other_pcollector.add_level(1);
  4781. if (reader->is_indexed()) {
  4782. const unsigned char *client_pointer;
  4783. if (!setup_primitive(client_pointer, reader, force)) {
  4784. return false;
  4785. }
  4786. #ifndef OPENGLES_1
  4787. if (_supports_geometry_instancing && _instance_count > 0) {
  4788. _glDrawElementsInstanced(GL_LINES, num_vertices,
  4789. get_numeric_type(reader->get_index_type()),
  4790. client_pointer, _instance_count);
  4791. } else
  4792. #endif
  4793. {
  4794. _glDrawRangeElements(GL_LINES,
  4795. reader->get_min_vertex(),
  4796. reader->get_max_vertex(),
  4797. num_vertices,
  4798. get_numeric_type(reader->get_index_type()),
  4799. client_pointer);
  4800. }
  4801. } else {
  4802. #ifndef OPENGLES_1
  4803. if (_supports_geometry_instancing && _instance_count > 0) {
  4804. _glDrawArraysInstanced(GL_LINES,
  4805. reader->get_first_vertex(),
  4806. num_vertices, _instance_count);
  4807. } else
  4808. #endif
  4809. {
  4810. glDrawArrays(GL_LINES,
  4811. reader->get_first_vertex(),
  4812. num_vertices);
  4813. }
  4814. }
  4815. }
  4816. report_my_gl_errors();
  4817. return true;
  4818. }
  4819. /**
  4820. * Draws a series of disconnected line segments with adjacency information.
  4821. */
  4822. #ifndef OPENGLES
  4823. bool CLP(GraphicsStateGuardian)::
  4824. draw_lines_adj(const GeomPrimitivePipelineReader *reader, bool force) {
  4825. // PStatGPUTimer timer(this, _draw_primitive_pcollector,
  4826. // reader->get_current_thread());
  4827. #ifndef NDEBUG
  4828. if (GLCAT.is_spam()) {
  4829. GLCAT.spam() << "draw_lines_adj: " << *(reader->get_object()) << "\n";
  4830. }
  4831. #endif // NDEBUG
  4832. #ifdef SUPPORT_IMMEDIATE_MODE
  4833. if (_use_sender) {
  4834. draw_immediate_simple_primitives(reader, GL_LINES_ADJACENCY);
  4835. } else
  4836. #endif // SUPPORT_IMMEDIATE_MODE
  4837. {
  4838. int num_vertices = reader->get_num_vertices();
  4839. _vertices_other_pcollector.add_level(num_vertices);
  4840. _primitive_batches_other_pcollector.add_level(1);
  4841. if (reader->is_indexed()) {
  4842. const unsigned char *client_pointer;
  4843. if (!setup_primitive(client_pointer, reader, force)) {
  4844. return false;
  4845. }
  4846. if (_supports_geometry_instancing && _instance_count > 0) {
  4847. _glDrawElementsInstanced(GL_LINES_ADJACENCY, num_vertices,
  4848. get_numeric_type(reader->get_index_type()),
  4849. client_pointer, _instance_count);
  4850. } else {
  4851. _glDrawRangeElements(GL_LINES_ADJACENCY,
  4852. reader->get_min_vertex(),
  4853. reader->get_max_vertex(),
  4854. num_vertices,
  4855. get_numeric_type(reader->get_index_type()),
  4856. client_pointer);
  4857. }
  4858. } else {
  4859. if (_supports_geometry_instancing && _instance_count > 0) {
  4860. _glDrawArraysInstanced(GL_LINES_ADJACENCY,
  4861. reader->get_first_vertex(),
  4862. num_vertices, _instance_count);
  4863. } else {
  4864. glDrawArrays(GL_LINES_ADJACENCY,
  4865. reader->get_first_vertex(),
  4866. num_vertices);
  4867. }
  4868. }
  4869. }
  4870. report_my_gl_errors();
  4871. return true;
  4872. }
  4873. #endif // OPENGLES
  4874. /**
  4875. * Draws a series of line strips.
  4876. */
  4877. bool CLP(GraphicsStateGuardian)::
  4878. draw_linestrips(const GeomPrimitivePipelineReader *reader, bool force) {
  4879. // PStatGPUTimer timer(this, _draw_primitive_pcollector,
  4880. // reader->get_current_thread());
  4881. report_my_gl_errors();
  4882. #ifndef NDEBUG
  4883. if (GLCAT.is_spam()) {
  4884. GLCAT.spam() << "draw_linestrips: " << *(reader->get_object()) << "\n";
  4885. }
  4886. #endif // NDEBUG
  4887. #ifdef SUPPORT_IMMEDIATE_MODE
  4888. if (_use_sender) {
  4889. draw_immediate_composite_primitives(reader, GL_LINE_STRIP);
  4890. } else
  4891. #endif // SUPPORT_IMMEDIATE_MODE
  4892. {
  4893. if (reader->is_indexed() &&
  4894. (_supported_geom_rendering & GeomEnums::GR_strip_cut_index) != 0) {
  4895. // One long triangle strip, connected by strip cut indices.
  4896. #ifndef OPENGLES
  4897. if (_explicit_primitive_restart) {
  4898. glEnable(GL_PRIMITIVE_RESTART);
  4899. _glPrimitiveRestartIndex(reader->get_strip_cut_index());
  4900. }
  4901. #endif // !OPENGLES
  4902. int num_vertices = reader->get_num_vertices();
  4903. _vertices_other_pcollector.add_level(num_vertices);
  4904. _primitive_batches_other_pcollector.add_level(1);
  4905. const unsigned char *client_pointer;
  4906. if (!setup_primitive(client_pointer, reader, force)) {
  4907. return false;
  4908. }
  4909. #ifndef OPENGLES_1
  4910. if (_supports_geometry_instancing && _instance_count > 0) {
  4911. _glDrawElementsInstanced(GL_LINE_STRIP, num_vertices,
  4912. get_numeric_type(reader->get_index_type()),
  4913. client_pointer, _instance_count);
  4914. } else
  4915. #endif // !OPENGLES
  4916. {
  4917. _glDrawRangeElements(GL_LINE_STRIP,
  4918. reader->get_min_vertex(),
  4919. reader->get_max_vertex(),
  4920. num_vertices,
  4921. get_numeric_type(reader->get_index_type()),
  4922. client_pointer);
  4923. }
  4924. #ifndef OPENGLES
  4925. if (_explicit_primitive_restart) {
  4926. glDisable(GL_PRIMITIVE_RESTART);
  4927. }
  4928. #endif // !OPENGLES
  4929. } else {
  4930. // Send the individual line strips, stepping over the strip-cut indices.
  4931. CPTA_int ends = reader->get_ends();
  4932. _primitive_batches_other_pcollector.add_level(ends.size());
  4933. if (reader->is_indexed()) {
  4934. const unsigned char *client_pointer;
  4935. if (!setup_primitive(client_pointer, reader, force)) {
  4936. return false;
  4937. }
  4938. int index_stride = reader->get_index_stride();
  4939. GeomVertexReader mins(reader->get_mins(), 0);
  4940. GeomVertexReader maxs(reader->get_maxs(), 0);
  4941. nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() &&
  4942. reader->get_maxs()->get_num_rows() == (int)ends.size(), false);
  4943. unsigned int start = 0;
  4944. for (size_t i = 0; i < ends.size(); i++) {
  4945. _vertices_other_pcollector.add_level(ends[i] - start);
  4946. #ifndef OPENGLES_1
  4947. if (_supports_geometry_instancing && _instance_count > 0) {
  4948. _glDrawElementsInstanced(GL_LINE_STRIP, ends[i] - start,
  4949. get_numeric_type(reader->get_index_type()),
  4950. client_pointer + start * index_stride,
  4951. _instance_count);
  4952. } else
  4953. #endif
  4954. {
  4955. _glDrawRangeElements(GL_LINE_STRIP,
  4956. mins.get_data1i(), maxs.get_data1i(),
  4957. ends[i] - start,
  4958. get_numeric_type(reader->get_index_type()),
  4959. client_pointer + start * index_stride);
  4960. }
  4961. start = ends[i] + 1;
  4962. }
  4963. } else {
  4964. unsigned int start = 0;
  4965. int first_vertex = reader->get_first_vertex();
  4966. for (size_t i = 0; i < ends.size(); i++) {
  4967. _vertices_other_pcollector.add_level(ends[i] - start);
  4968. #ifndef OPENGLES_1
  4969. if (_supports_geometry_instancing && _instance_count > 0) {
  4970. _glDrawArraysInstanced(GL_LINE_STRIP, first_vertex + start,
  4971. ends[i] - start, _instance_count);
  4972. } else
  4973. #endif
  4974. {
  4975. glDrawArrays(GL_LINE_STRIP, first_vertex + start, ends[i] - start);
  4976. }
  4977. start = ends[i] + 1;
  4978. }
  4979. }
  4980. }
  4981. }
  4982. report_my_gl_errors();
  4983. return true;
  4984. }
  4985. /**
  4986. * Draws a series of line strips with adjacency information.
  4987. */
  4988. #ifndef OPENGLES
  4989. bool CLP(GraphicsStateGuardian)::
  4990. draw_linestrips_adj(const GeomPrimitivePipelineReader *reader, bool force) {
  4991. // PStatGPUTimer timer(this, _draw_primitive_pcollector,
  4992. // reader->get_current_thread());
  4993. report_my_gl_errors();
  4994. #ifndef NDEBUG
  4995. if (GLCAT.is_spam()) {
  4996. GLCAT.spam() << "draw_linestrips_adj: " << *(reader->get_object()) << "\n";
  4997. }
  4998. #endif // NDEBUG
  4999. #ifdef SUPPORT_IMMEDIATE_MODE
  5000. if (_use_sender) {
  5001. draw_immediate_composite_primitives(reader, GL_LINE_STRIP_ADJACENCY);
  5002. } else
  5003. #endif // SUPPORT_IMMEDIATE_MODE
  5004. {
  5005. if (reader->is_indexed() &&
  5006. (_supported_geom_rendering & GeomEnums::GR_strip_cut_index) != 0) {
  5007. // One long line strip, connected by strip cut indices.
  5008. if (_explicit_primitive_restart) {
  5009. glEnable(GL_PRIMITIVE_RESTART);
  5010. _glPrimitiveRestartIndex(reader->get_strip_cut_index());
  5011. }
  5012. int num_vertices = reader->get_num_vertices();
  5013. _vertices_other_pcollector.add_level(num_vertices);
  5014. _primitive_batches_other_pcollector.add_level(1);
  5015. const unsigned char *client_pointer;
  5016. if (!setup_primitive(client_pointer, reader, force)) {
  5017. return false;
  5018. }
  5019. if (_supports_geometry_instancing && _instance_count > 0) {
  5020. _glDrawElementsInstanced(GL_LINE_STRIP_ADJACENCY, num_vertices,
  5021. get_numeric_type(reader->get_index_type()),
  5022. client_pointer, _instance_count);
  5023. } else {
  5024. _glDrawRangeElements(GL_LINE_STRIP_ADJACENCY,
  5025. reader->get_min_vertex(),
  5026. reader->get_max_vertex(),
  5027. num_vertices,
  5028. get_numeric_type(reader->get_index_type()),
  5029. client_pointer);
  5030. }
  5031. if (_explicit_primitive_restart) {
  5032. glDisable(GL_PRIMITIVE_RESTART);
  5033. }
  5034. } else {
  5035. // Send the individual line strips, stepping over the strip-cut indices.
  5036. CPTA_int ends = reader->get_ends();
  5037. _primitive_batches_other_pcollector.add_level(ends.size());
  5038. if (reader->is_indexed()) {
  5039. const unsigned char *client_pointer;
  5040. if (!setup_primitive(client_pointer, reader, force)) {
  5041. return false;
  5042. }
  5043. int index_stride = reader->get_index_stride();
  5044. GeomVertexReader mins(reader->get_mins(), 0);
  5045. GeomVertexReader maxs(reader->get_maxs(), 0);
  5046. nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() &&
  5047. reader->get_maxs()->get_num_rows() == (int)ends.size(), false);
  5048. unsigned int start = 0;
  5049. for (size_t i = 0; i < ends.size(); i++) {
  5050. _vertices_other_pcollector.add_level(ends[i] - start);
  5051. if (_supports_geometry_instancing && _instance_count > 0) {
  5052. _glDrawElementsInstanced(GL_LINE_STRIP_ADJACENCY, ends[i] - start,
  5053. get_numeric_type(reader->get_index_type()),
  5054. client_pointer + start * index_stride,
  5055. _instance_count);
  5056. } else {
  5057. _glDrawRangeElements(GL_LINE_STRIP_ADJACENCY,
  5058. mins.get_data1i(), maxs.get_data1i(),
  5059. ends[i] - start,
  5060. get_numeric_type(reader->get_index_type()),
  5061. client_pointer + start * index_stride);
  5062. }
  5063. start = ends[i] + 1;
  5064. }
  5065. } else {
  5066. unsigned int start = 0;
  5067. int first_vertex = reader->get_first_vertex();
  5068. for (size_t i = 0; i < ends.size(); i++) {
  5069. _vertices_other_pcollector.add_level(ends[i] - start);
  5070. if (_supports_geometry_instancing && _instance_count > 0) {
  5071. _glDrawArraysInstanced(GL_LINE_STRIP_ADJACENCY, first_vertex + start,
  5072. ends[i] - start, _instance_count);
  5073. } else {
  5074. glDrawArrays(GL_LINE_STRIP_ADJACENCY, first_vertex + start, ends[i] - start);
  5075. }
  5076. start = ends[i] + 1;
  5077. }
  5078. }
  5079. }
  5080. }
  5081. report_my_gl_errors();
  5082. return true;
  5083. }
  5084. #endif // OPENGLES
  5085. /**
  5086. * Draws a series of disconnected points.
  5087. */
  5088. bool CLP(GraphicsStateGuardian)::
  5089. draw_points(const GeomPrimitivePipelineReader *reader, bool force) {
  5090. // PStatGPUTimer timer(this, _draw_primitive_pcollector,
  5091. // reader->get_current_thread());
  5092. #ifndef NDEBUG
  5093. if (GLCAT.is_spam()) {
  5094. GLCAT.spam() << "draw_points: " << *(reader->get_object()) << "\n";
  5095. }
  5096. #endif // NDEBUG
  5097. #ifdef SUPPORT_IMMEDIATE_MODE
  5098. if (_use_sender) {
  5099. draw_immediate_simple_primitives(reader, GL_POINTS);
  5100. } else
  5101. #endif // SUPPORT_IMMEDIATE_MODE
  5102. {
  5103. int num_vertices = reader->get_num_vertices();
  5104. _vertices_other_pcollector.add_level(num_vertices);
  5105. _primitive_batches_other_pcollector.add_level(1);
  5106. if (reader->is_indexed()) {
  5107. const unsigned char *client_pointer;
  5108. if (!setup_primitive(client_pointer, reader, force)) {
  5109. return false;
  5110. }
  5111. #ifndef OPENGLES_1
  5112. if (_supports_geometry_instancing && _instance_count > 0) {
  5113. _glDrawElementsInstanced(GL_POINTS, num_vertices,
  5114. get_numeric_type(reader->get_index_type()),
  5115. client_pointer, _instance_count);
  5116. } else
  5117. #endif
  5118. {
  5119. _glDrawRangeElements(GL_POINTS,
  5120. reader->get_min_vertex(),
  5121. reader->get_max_vertex(),
  5122. num_vertices,
  5123. get_numeric_type(reader->get_index_type()),
  5124. client_pointer);
  5125. }
  5126. } else {
  5127. #ifndef OPENGLES_1
  5128. if (_supports_geometry_instancing && _instance_count > 0) {
  5129. _glDrawArraysInstanced(GL_POINTS,
  5130. reader->get_first_vertex(),
  5131. num_vertices, _instance_count);
  5132. } else
  5133. #endif
  5134. {
  5135. glDrawArrays(GL_POINTS, reader->get_first_vertex(), num_vertices);
  5136. }
  5137. }
  5138. }
  5139. report_my_gl_errors();
  5140. return true;
  5141. }
  5142. /**
  5143. * Called after a sequence of draw_primitive() functions are called, this
  5144. * should do whatever cleanup is appropriate.
  5145. */
  5146. void CLP(GraphicsStateGuardian)::
  5147. end_draw_primitives() {
  5148. #if !defined(OPENGLES) && defined(SUPPORT_FIXED_FUNCTION) // Display lists not supported by OpenGL ES.
  5149. if (has_fixed_function_pipeline() && _geom_display_list != 0) {
  5150. // If we were building a display list, close it now.
  5151. glEndList();
  5152. _load_display_list_pcollector.stop();
  5153. if (!gl_compile_and_execute) {
  5154. glCallList(_geom_display_list);
  5155. }
  5156. _primitive_batches_display_list_pcollector.add_level(1);
  5157. }
  5158. _geom_display_list = 0;
  5159. #endif
  5160. #ifdef SUPPORT_FIXED_FUNCTION
  5161. if (has_fixed_function_pipeline() && _transform_stale) {
  5162. glMatrixMode(GL_MODELVIEW);
  5163. call_glLoadMatrix(_internal_transform->get_mat());
  5164. }
  5165. if (has_fixed_function_pipeline() && _data_reader->is_vertex_transformed()) {
  5166. // Restore the matrices that we pushed above.
  5167. glMatrixMode(GL_PROJECTION);
  5168. glPopMatrix();
  5169. glMatrixMode(GL_MODELVIEW);
  5170. glPopMatrix();
  5171. }
  5172. #endif
  5173. GraphicsStateGuardian::end_draw_primitives();
  5174. maybe_gl_finish();
  5175. report_my_gl_errors();
  5176. }
  5177. #ifndef OPENGLES_1
  5178. /**
  5179. * Issues the given memory barriers, and clears the list of textures marked as
  5180. * incoherent for the given bits.
  5181. */
  5182. void CLP(GraphicsStateGuardian)::
  5183. issue_memory_barrier(GLbitfield barriers) {
  5184. if (!gl_enable_memory_barriers || _glMemoryBarrier == nullptr) {
  5185. return;
  5186. }
  5187. PStatGPUTimer timer(this, _memory_barrier_pcollector);
  5188. if (GLCAT.is_spam()) {
  5189. GLCAT.spam() << "Issuing memory barriers:";
  5190. }
  5191. _glMemoryBarrier(barriers);
  5192. // Indicate that barriers no longer need to be issued for the relevant lists
  5193. // of textures.
  5194. if (barriers & GL_TEXTURE_FETCH_BARRIER_BIT) {
  5195. _textures_needing_fetch_barrier.clear();
  5196. GLCAT.spam(false) << " texture_fetch";
  5197. }
  5198. if (barriers & GL_SHADER_IMAGE_ACCESS_BARRIER_BIT) {
  5199. _textures_needing_image_access_barrier.clear();
  5200. GLCAT.spam(false) << " shader_image_access";
  5201. }
  5202. if (barriers & GL_TEXTURE_UPDATE_BARRIER_BIT) {
  5203. _textures_needing_update_barrier.clear();
  5204. GLCAT.spam(false) << " texture_update";
  5205. }
  5206. if (barriers & GL_FRAMEBUFFER_BARRIER_BIT) {
  5207. _textures_needing_framebuffer_barrier.clear();
  5208. GLCAT.spam(false) << " framebuffer";
  5209. }
  5210. GLCAT.spam(false) << "\n";
  5211. report_my_gl_errors();
  5212. }
  5213. #endif // OPENGLES_1
  5214. /**
  5215. * Creates whatever structures the GSG requires to represent the texture
  5216. * internally, and returns a newly-allocated TextureContext object with this
  5217. * data. It is the responsibility of the calling function to later call
  5218. * release_texture() with this same pointer (which will also delete the
  5219. * pointer).
  5220. *
  5221. * This function should not be called directly to prepare a texture. Instead,
  5222. * call Texture::prepare().
  5223. */
  5224. TextureContext *CLP(GraphicsStateGuardian)::
  5225. prepare_texture(Texture *tex, int view) {
  5226. PStatGPUTimer timer(this, _prepare_texture_pcollector);
  5227. report_my_gl_errors();
  5228. // Make sure we'll support this texture when it's rendered. Don't bother to
  5229. // prepare it if we won't.
  5230. Texture::TextureType texture_type = tex->get_texture_type();
  5231. switch (texture_type) {
  5232. case Texture::TT_3d_texture:
  5233. if (!_supports_3d_texture) {
  5234. GLCAT.warning()
  5235. << "3-D textures are not supported by this OpenGL driver.\n";
  5236. return nullptr;
  5237. }
  5238. break;
  5239. case Texture::TT_2d_texture_array:
  5240. if (!_supports_2d_texture_array) {
  5241. GLCAT.warning()
  5242. << "2-D texture arrays are not supported by this OpenGL driver.\n";
  5243. return nullptr;
  5244. }
  5245. break;
  5246. case Texture::TT_cube_map:
  5247. if (!_supports_cube_map) {
  5248. GLCAT.warning()
  5249. << "Cube map textures are not supported by this OpenGL driver.\n";
  5250. return nullptr;
  5251. }
  5252. break;
  5253. case Texture::TT_buffer_texture:
  5254. if (!_supports_buffer_texture) {
  5255. GLCAT.warning()
  5256. << "Buffer textures are not supported by this OpenGL driver.\n";
  5257. return nullptr;
  5258. }
  5259. break;
  5260. case Texture::TT_cube_map_array:
  5261. if (!_supports_cube_map_array) {
  5262. GLCAT.warning()
  5263. << "Cube map arrays are not supported by this OpenGL driver.\n";
  5264. return nullptr;
  5265. }
  5266. break;
  5267. default:
  5268. break;
  5269. }
  5270. CLP(TextureContext) *gtc = new CLP(TextureContext)(this, _prepared_objects, tex, view);
  5271. gtc->_target = get_texture_target(texture_type);
  5272. report_my_gl_errors();
  5273. return gtc;
  5274. }
  5275. /**
  5276. * Ensures that the current Texture data is refreshed onto the GSG. This
  5277. * means updating the texture properties and/or re-uploading the texture
  5278. * image, if necessary. This should only be called within the draw thread.
  5279. *
  5280. * If force is true, this function will not return until the texture has been
  5281. * fully uploaded. If force is false, the function may choose to upload a
  5282. * simple version of the texture instead, if the texture is not fully resident
  5283. * (and if get_incomplete_render() is true).
  5284. */
  5285. bool CLP(GraphicsStateGuardian)::
  5286. update_texture(TextureContext *tc, bool force) {
  5287. CLP(TextureContext) *gtc;
  5288. DCAST_INTO_R(gtc, tc, false);
  5289. if (gtc->was_image_modified() || !gtc->_has_storage) {
  5290. PStatGPUTimer timer(this, _texture_update_pcollector);
  5291. // If the texture image was modified, reload the texture.
  5292. apply_texture(gtc);
  5293. Texture *tex = tc->get_texture();
  5294. if (gtc->was_properties_modified()) {
  5295. specify_texture(gtc, tex->get_default_sampler());
  5296. }
  5297. bool okflag = upload_texture(gtc, force, tex->uses_mipmaps());
  5298. if (!okflag) {
  5299. GLCAT.error()
  5300. << "Could not load " << *tex << "\n";
  5301. return false;
  5302. }
  5303. } else if (gtc->was_properties_modified()) {
  5304. PStatGPUTimer timer(this, _texture_update_pcollector);
  5305. // If only the properties have been modified, we don't necessarily need to
  5306. // reload the texture.
  5307. apply_texture(gtc);
  5308. Texture *tex = tc->get_texture();
  5309. if (specify_texture(gtc, tex->get_default_sampler())) {
  5310. // Actually, looks like the texture *does* need to be reloaded.
  5311. gtc->mark_needs_reload();
  5312. bool okflag = upload_texture(gtc, force, tex->uses_mipmaps());
  5313. if (!okflag) {
  5314. GLCAT.error()
  5315. << "Could not load " << *tex << "\n";
  5316. return false;
  5317. }
  5318. } else {
  5319. // The texture didn't need reloading, but mark it fully updated now.
  5320. gtc->mark_loaded();
  5321. }
  5322. }
  5323. gtc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  5324. report_my_gl_errors();
  5325. return true;
  5326. }
  5327. /**
  5328. * Frees the GL resources previously allocated for the texture. This function
  5329. * should never be called directly; instead, call Texture::release() (or
  5330. * simply let the Texture destruct).
  5331. */
  5332. void CLP(GraphicsStateGuardian)::
  5333. release_texture(TextureContext *tc) {
  5334. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
  5335. #ifndef OPENGLES_1
  5336. _textures_needing_fetch_barrier.erase(gtc);
  5337. _textures_needing_image_access_barrier.erase(gtc);
  5338. _textures_needing_update_barrier.erase(gtc);
  5339. _textures_needing_framebuffer_barrier.erase(gtc);
  5340. #endif
  5341. glDeleteTextures(1, &gtc->_index);
  5342. if (gtc->_buffer != 0) {
  5343. _glDeleteBuffers(1, &gtc->_buffer);
  5344. }
  5345. delete gtc;
  5346. }
  5347. /**
  5348. * Frees the GL resources previously allocated for the textures. This function
  5349. * should never be called directly; instead, call Texture::release() (or
  5350. * simply let the Texture destruct).
  5351. */
  5352. void CLP(GraphicsStateGuardian)::
  5353. release_textures(const pvector<TextureContext *> &contexts) {
  5354. if (contexts.empty()) {
  5355. return;
  5356. }
  5357. GLuint *indices = (GLuint *)alloca(sizeof(GLuint) * contexts.size() * 2);
  5358. GLuint *buffers = indices + contexts.size();
  5359. size_t num_indices = 0;
  5360. size_t num_buffers = 0;
  5361. for (TextureContext *tc : contexts) {
  5362. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
  5363. #ifndef OPENGLES_1
  5364. _textures_needing_fetch_barrier.erase(gtc);
  5365. _textures_needing_image_access_barrier.erase(gtc);
  5366. _textures_needing_update_barrier.erase(gtc);
  5367. _textures_needing_framebuffer_barrier.erase(gtc);
  5368. #endif
  5369. indices[num_indices++] = gtc->_index;
  5370. if (gtc->_buffer != 0) {
  5371. buffers[num_buffers++] = gtc->_buffer;
  5372. }
  5373. delete gtc;
  5374. }
  5375. glDeleteTextures(num_indices, indices);
  5376. if (num_buffers > 0) {
  5377. _glDeleteBuffers(num_buffers, buffers);
  5378. }
  5379. }
  5380. /**
  5381. * This method should only be called by the GraphicsEngine. Do not call it
  5382. * directly; call GraphicsEngine::extract_texture_data() instead.
  5383. *
  5384. * This method will be called in the draw thread to download the texture
  5385. * memory's image into its ram_image value. It returns true on success, false
  5386. * otherwise.
  5387. */
  5388. bool CLP(GraphicsStateGuardian)::
  5389. extract_texture_data(Texture *tex) {
  5390. bool success = true;
  5391. // Make sure the error stack is cleared out before we begin.
  5392. report_my_gl_errors();
  5393. int num_views = tex->get_num_views();
  5394. for (int view = 0; view < num_views; ++view) {
  5395. TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this);
  5396. nassertr(tc != nullptr, false);
  5397. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
  5398. if (!do_extract_texture_data(gtc)) {
  5399. success = false;
  5400. }
  5401. }
  5402. return success;
  5403. }
  5404. #ifndef OPENGLES_1
  5405. /**
  5406. * Creates whatever structures the GSG requires to represent the sampler state
  5407. * internally, and returns a newly-allocated SamplerContext object with this
  5408. * data. It is the responsibility of the calling function to later call
  5409. * release_sampler() with this same pointer (which will also delete the
  5410. * pointer).
  5411. *
  5412. * This function should not be called directly to prepare a sampler object.
  5413. * Instead, call SamplerState::prepare().
  5414. */
  5415. SamplerContext *CLP(GraphicsStateGuardian)::
  5416. prepare_sampler(const SamplerState &sampler) {
  5417. nassertr(_supports_sampler_objects, nullptr);
  5418. PStatGPUTimer timer(this, _prepare_sampler_pcollector);
  5419. CLP(SamplerContext) *gsc = new CLP(SamplerContext)(this, sampler);
  5420. GLuint index = gsc->_index;
  5421. // Sampler contexts are immutable in Panda, so might as well just initialize
  5422. // all the settings here.
  5423. _glSamplerParameteri(index, GL_TEXTURE_WRAP_S,
  5424. get_texture_wrap_mode(sampler.get_wrap_u()));
  5425. _glSamplerParameteri(index, GL_TEXTURE_WRAP_T,
  5426. get_texture_wrap_mode(sampler.get_wrap_v()));
  5427. _glSamplerParameteri(index, GL_TEXTURE_WRAP_R,
  5428. get_texture_wrap_mode(sampler.get_wrap_w()));
  5429. #ifndef OPENGLES
  5430. #ifdef STDFLOAT_DOUBLE
  5431. LVecBase4f fvalue = LCAST(float, sampler.get_border_color());
  5432. _glSamplerParameterfv(index, GL_TEXTURE_BORDER_COLOR, fvalue.get_data());
  5433. #else
  5434. _glSamplerParameterfv(index, GL_TEXTURE_BORDER_COLOR,
  5435. sampler.get_border_color().get_data());
  5436. #endif
  5437. #endif // OPENGLES
  5438. SamplerState::FilterType minfilter = sampler.get_effective_minfilter();
  5439. SamplerState::FilterType magfilter = sampler.get_effective_magfilter();
  5440. bool uses_mipmaps = SamplerState::is_mipmap(minfilter) && !gl_ignore_mipmaps;
  5441. #ifndef NDEBUG
  5442. if (gl_force_mipmaps) {
  5443. minfilter = SamplerState::FT_linear_mipmap_linear;
  5444. magfilter = SamplerState::FT_linear;
  5445. uses_mipmaps = true;
  5446. }
  5447. #endif
  5448. _glSamplerParameteri(index, GL_TEXTURE_MIN_FILTER,
  5449. get_texture_filter_type(minfilter, !uses_mipmaps));
  5450. _glSamplerParameteri(index, GL_TEXTURE_MAG_FILTER,
  5451. get_texture_filter_type(magfilter, true));
  5452. // Set anisotropic filtering.
  5453. if (_supports_anisotropy) {
  5454. PN_stdfloat anisotropy = sampler.get_effective_anisotropic_degree();
  5455. anisotropy = min(anisotropy, _max_anisotropy);
  5456. anisotropy = max(anisotropy, (PN_stdfloat)1.0);
  5457. _glSamplerParameterf(index, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
  5458. }
  5459. if (_supports_shadow_filter) {
  5460. if ((sampler.get_magfilter() == SamplerState::FT_shadow) ||
  5461. (sampler.get_minfilter() == SamplerState::FT_shadow)) {
  5462. _glSamplerParameteri(index, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
  5463. _glSamplerParameteri(index, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
  5464. } else {
  5465. _glSamplerParameteri(index, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
  5466. _glSamplerParameteri(index, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
  5467. }
  5468. }
  5469. if (_supports_texture_lod) {
  5470. _glSamplerParameterf(index, GL_TEXTURE_MIN_LOD, sampler.get_min_lod());
  5471. _glSamplerParameterf(index, GL_TEXTURE_MAX_LOD, sampler.get_max_lod());
  5472. }
  5473. #ifndef OPENGLES
  5474. if (_supports_texture_lod_bias) {
  5475. _glSamplerParameterf(index, GL_TEXTURE_LOD_BIAS, sampler.get_lod_bias());
  5476. }
  5477. #endif
  5478. gsc->enqueue_lru(&_prepared_objects->_sampler_object_lru);
  5479. report_my_gl_errors();
  5480. return gsc;
  5481. }
  5482. #endif // !OPENGLES_1
  5483. #ifndef OPENGLES_1
  5484. /**
  5485. * Frees the GL resources previously allocated for the sampler. This function
  5486. * should never be called directly; instead, call SamplerState::release().
  5487. */
  5488. void CLP(GraphicsStateGuardian)::
  5489. release_sampler(SamplerContext *sc) {
  5490. CLP(SamplerContext) *gsc = DCAST(CLP(SamplerContext), sc);
  5491. if (gsc->_index != 0) {
  5492. _glDeleteSamplers(1, &gsc->_index);
  5493. }
  5494. delete gsc;
  5495. }
  5496. #endif // !OPENGLES_1
  5497. /**
  5498. * Creates a new retained-mode representation of the given geom, and returns a
  5499. * newly-allocated GeomContext pointer to reference it. It is the
  5500. * responsibility of the calling function to later call release_geom() with
  5501. * this same pointer (which will also delete the pointer).
  5502. *
  5503. * This function should not be called directly to prepare a geom. Instead,
  5504. * call Geom::prepare().
  5505. */
  5506. GeomContext *CLP(GraphicsStateGuardian)::
  5507. prepare_geom(Geom *geom) {
  5508. PStatGPUTimer timer(this, _prepare_geom_pcollector);
  5509. return new CLP(GeomContext)(geom);
  5510. }
  5511. /**
  5512. * Frees the GL resources previously allocated for the geom. This function
  5513. * should never be called directly; instead, call Geom::release() (or simply
  5514. * let the Geom destruct).
  5515. */
  5516. void CLP(GraphicsStateGuardian)::
  5517. release_geom(GeomContext *gc) {
  5518. CLP(GeomContext) *ggc = DCAST(CLP(GeomContext), gc);
  5519. if (has_fixed_function_pipeline()) {
  5520. ggc->release_display_lists();
  5521. }
  5522. report_my_gl_errors();
  5523. delete ggc;
  5524. }
  5525. /**
  5526. *
  5527. */
  5528. ShaderContext *CLP(GraphicsStateGuardian)::
  5529. prepare_shader(Shader *se) {
  5530. PStatGPUTimer timer(this, se->get_prepare_shader_pcollector());
  5531. #ifndef OPENGLES_1
  5532. ShaderContext *result = nullptr;
  5533. switch (se->get_language()) {
  5534. case Shader::SL_GLSL:
  5535. if (_supports_glsl) {
  5536. push_group_marker(std::string("Prepare Shader ") + se->get_debug_name());
  5537. result = new CLP(ShaderContext)(this, se);
  5538. pop_group_marker();
  5539. break;
  5540. } else {
  5541. GLCAT.error()
  5542. << "Tried to load GLSL shader, but GLSL shaders not supported.\n";
  5543. return nullptr;
  5544. }
  5545. case Shader::SL_Cg:
  5546. #if defined(HAVE_CG) && !defined(OPENGLES)
  5547. if (_supports_basic_shaders) {
  5548. push_group_marker(std::string("Prepare Shader ") + se->get_debug_name());
  5549. result = new CLP(CgShaderContext)(this, se);
  5550. pop_group_marker();
  5551. break;
  5552. } else {
  5553. GLCAT.error()
  5554. << "Tried to load Cg shader, but basic shaders not supported.\n";
  5555. return nullptr;
  5556. }
  5557. #elif defined(OPENGLES)
  5558. GLCAT.error()
  5559. << "Tried to load Cg shader, but Cg support is not available for OpenGL ES.\n";
  5560. return nullptr;
  5561. #else
  5562. GLCAT.error()
  5563. << "Tried to load Cg shader, but Cg support not compiled in.\n";
  5564. return nullptr;
  5565. #endif
  5566. default:
  5567. GLCAT.error()
  5568. << "Tried to load shader with unsupported shader language!\n";
  5569. return nullptr;
  5570. }
  5571. if (result->valid()) {
  5572. return result;
  5573. }
  5574. delete result;
  5575. #endif // OPENGLES_1
  5576. return nullptr;
  5577. }
  5578. /**
  5579. *
  5580. */
  5581. void CLP(GraphicsStateGuardian)::
  5582. release_shader(ShaderContext *sc) {
  5583. #ifndef OPENGLES_1
  5584. if (sc->is_of_type(CLP(ShaderContext)::get_class_type())) {
  5585. ((CLP(ShaderContext) *)sc)->release_resources();
  5586. }
  5587. #if defined(HAVE_CG) && !defined(OPENGLES_2)
  5588. else if (sc->is_of_type(CLP(CgShaderContext)::get_class_type())) {
  5589. ((CLP(CgShaderContext) *)sc)->release_resources();
  5590. }
  5591. #endif
  5592. #endif
  5593. delete sc;
  5594. }
  5595. /**
  5596. * This is intended to be called only from the GLGeomContext destructor. It
  5597. * saves the indicated display list index in the list to be deleted at the end
  5598. * of the frame.
  5599. */
  5600. void CLP(GraphicsStateGuardian)::
  5601. record_deleted_display_list(GLuint index) {
  5602. LightMutexHolder holder(_lock);
  5603. _deleted_display_lists.push_back(index);
  5604. }
  5605. /**
  5606. * Creates a new retained-mode representation of the given data, and returns a
  5607. * newly-allocated VertexBufferContext pointer to reference it. It is the
  5608. * responsibility of the calling function to later call
  5609. * release_vertex_buffer() with this same pointer (which will also delete the
  5610. * pointer).
  5611. *
  5612. * This function should not be called directly to prepare a buffer. Instead,
  5613. * call Geom::prepare().
  5614. */
  5615. VertexBufferContext *CLP(GraphicsStateGuardian)::
  5616. prepare_vertex_buffer(GeomVertexArrayData *data) {
  5617. if (_supports_buffers) {
  5618. PStatGPUTimer timer(this, _prepare_vertex_buffer_pcollector);
  5619. CLP(VertexBufferContext) *gvbc = new CLP(VertexBufferContext)(this, _prepared_objects, data);
  5620. _glGenBuffers(1, &gvbc->_index);
  5621. if (GLCAT.is_debug() && gl_debug_buffers) {
  5622. GLCAT.debug()
  5623. << "creating vertex buffer " << (int)gvbc->_index << ": "
  5624. << data->get_num_rows() << " vertices "
  5625. << *data->get_array_format() << "\n";
  5626. }
  5627. report_my_gl_errors();
  5628. update_vertex_buffer(gvbc, data->get_handle(), false);
  5629. return gvbc;
  5630. }
  5631. return nullptr;
  5632. }
  5633. /**
  5634. * Makes sure that the data in the vertex buffer is up-to-date. This may bind
  5635. * it to the GL_ARRAY_BUFFER binding point if necessary.
  5636. */
  5637. bool CLP(GraphicsStateGuardian)::
  5638. update_vertex_buffer(CLP(VertexBufferContext) *gvbc,
  5639. const GeomVertexArrayDataHandle *reader, bool force) {
  5640. nassertr(_supports_buffers, false);
  5641. if (reader->get_modified() == UpdateSeq::initial()) {
  5642. // No need to re-apply.
  5643. return true;
  5644. }
  5645. gvbc->set_active(true);
  5646. if (gvbc->was_modified(reader)) {
  5647. int num_bytes = reader->get_data_size_bytes();
  5648. if (GLCAT.is_debug() && gl_debug_buffers) {
  5649. GLCAT.debug()
  5650. << "copying " << num_bytes
  5651. << " bytes into vertex buffer " << (int)gvbc->_index << "\n";
  5652. }
  5653. if (num_bytes != 0) {
  5654. const unsigned char *client_pointer = reader->get_read_pointer(force);
  5655. if (client_pointer == nullptr) {
  5656. return false;
  5657. }
  5658. PStatGPUTimer timer(this, _load_vertex_buffer_pcollector, reader->get_current_thread());
  5659. if (_current_vbuffer_index != gvbc->_index) {
  5660. if (GLCAT.is_spam() && gl_debug_buffers) {
  5661. GLCAT.spam()
  5662. << "binding vertex buffer " << (int)gvbc->_index << "\n";
  5663. }
  5664. _glBindBuffer(GL_ARRAY_BUFFER, gvbc->_index);
  5665. _current_vbuffer_index = gvbc->_index;
  5666. }
  5667. if (gvbc->changed_size(reader) || gvbc->changed_usage_hint(reader)) {
  5668. _glBufferData(GL_ARRAY_BUFFER, num_bytes, client_pointer,
  5669. get_usage(reader->get_usage_hint()));
  5670. } else {
  5671. _glBufferSubData(GL_ARRAY_BUFFER, 0, num_bytes, client_pointer);
  5672. }
  5673. _data_transferred_pcollector.add_level(num_bytes);
  5674. }
  5675. gvbc->mark_loaded(reader);
  5676. }
  5677. gvbc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  5678. maybe_gl_finish();
  5679. report_my_gl_errors();
  5680. return true;
  5681. }
  5682. /**
  5683. * Frees the GL resources previously allocated for the data. This function
  5684. * should never be called directly; instead, call Data::release() (or simply
  5685. * let the Data destruct).
  5686. */
  5687. void CLP(GraphicsStateGuardian)::
  5688. release_vertex_buffer(VertexBufferContext *vbc) {
  5689. nassertv(_supports_buffers);
  5690. CLP(VertexBufferContext) *gvbc = DCAST(CLP(VertexBufferContext), vbc);
  5691. if (GLCAT.is_debug() && gl_debug_buffers) {
  5692. GLCAT.debug()
  5693. << "deleting vertex buffer " << (int)gvbc->_index << "\n";
  5694. }
  5695. // Make sure the buffer is unbound before we delete it. Not strictly
  5696. // necessary according to the OpenGL spec, but it might help out a flaky
  5697. // driver, and we need to keep our internal state consistent anyway.
  5698. if (_current_vbuffer_index == gvbc->_index) {
  5699. if (GLCAT.is_spam() && gl_debug_buffers) {
  5700. GLCAT.spam()
  5701. << "unbinding vertex buffer\n";
  5702. }
  5703. _glBindBuffer(GL_ARRAY_BUFFER, 0);
  5704. _current_vbuffer_index = 0;
  5705. }
  5706. _glDeleteBuffers(1, &gvbc->_index);
  5707. report_my_gl_errors();
  5708. gvbc->_index = 0;
  5709. delete gvbc;
  5710. }
  5711. /**
  5712. * Frees the GL resources previously allocated for the data. This function
  5713. * should never be called directly; instead, call Data::release() (or simply
  5714. * let the Data destruct).
  5715. */
  5716. void CLP(GraphicsStateGuardian)::
  5717. release_vertex_buffers(const pvector<BufferContext *> &contexts) {
  5718. if (contexts.empty()) {
  5719. return;
  5720. }
  5721. nassertv(_supports_buffers);
  5722. bool debug = GLCAT.is_debug() && gl_debug_buffers;
  5723. GLuint *indices = (GLuint *)alloca(sizeof(GLuint) * contexts.size());
  5724. size_t num_indices = 0;
  5725. for (BufferContext *bc : contexts) {
  5726. CLP(VertexBufferContext) *gvbc = DCAST(CLP(VertexBufferContext), bc);
  5727. // Make sure the buffer is unbound before we delete it. Not strictly
  5728. // necessary according to the OpenGL spec, but it might help out a flaky
  5729. // driver, and we need to keep our internal state consistent anyway.
  5730. if (_current_vbuffer_index == gvbc->_index) {
  5731. if (debug && GLCAT.is_spam()) {
  5732. GLCAT.spam()
  5733. << "unbinding vertex buffer " << gvbc->_index << "\n";
  5734. }
  5735. _glBindBuffer(GL_ARRAY_BUFFER, 0);
  5736. _current_vbuffer_index = 0;
  5737. }
  5738. if (debug) {
  5739. GLCAT.debug()
  5740. << "deleting vertex buffer " << gvbc->_index << "\n";
  5741. }
  5742. indices[num_indices++] = gvbc->_index;
  5743. gvbc->_index = 0;
  5744. delete gvbc;
  5745. }
  5746. _glDeleteBuffers(num_indices, indices);
  5747. report_my_gl_errors();
  5748. }
  5749. /**
  5750. * Internal function to bind a buffer object for the indicated data array, if
  5751. * appropriate, or to unbind a buffer object if it should be rendered from
  5752. * client memory.
  5753. *
  5754. * If the buffer object is bound, this function sets client_pointer to NULL
  5755. * (representing the start of the buffer object in server memory); if the
  5756. * buffer object is not bound, this function sets client_pointer the pointer
  5757. * to the data array in client memory, that is, the data array passed in.
  5758. *
  5759. * If force is not true, the function may return false indicating the data is
  5760. * not currently available.
  5761. */
  5762. bool CLP(GraphicsStateGuardian)::
  5763. setup_array_data(const unsigned char *&client_pointer,
  5764. const GeomVertexArrayDataHandle *array_reader,
  5765. bool force) {
  5766. if (!_supports_buffers) {
  5767. // No support for buffer objects; always render from client.
  5768. client_pointer = array_reader->get_read_pointer(force);
  5769. return (client_pointer != nullptr);
  5770. }
  5771. if (!vertex_buffers || _geom_display_list != 0 ||
  5772. array_reader->get_usage_hint() < gl_min_buffer_usage_hint) {
  5773. // The array specifies client rendering only, or buffer objects are
  5774. // configured off.
  5775. if (_current_vbuffer_index != 0) {
  5776. if (GLCAT.is_spam() && gl_debug_buffers) {
  5777. GLCAT.spam()
  5778. << "unbinding vertex buffer\n";
  5779. }
  5780. _glBindBuffer(GL_ARRAY_BUFFER, 0);
  5781. _current_vbuffer_index = 0;
  5782. }
  5783. client_pointer = array_reader->get_read_pointer(force);
  5784. return (client_pointer != nullptr);
  5785. }
  5786. // Prepare the buffer object and bind it.
  5787. CLP(VertexBufferContext) *gvbc = DCAST(CLP(VertexBufferContext),
  5788. array_reader->prepare_now(get_prepared_objects(), this));
  5789. nassertr(gvbc != (CLP(VertexBufferContext) *)nullptr, false);
  5790. if (!update_vertex_buffer(gvbc, array_reader, force)) {
  5791. return false;
  5792. }
  5793. if (_current_vbuffer_index != gvbc->_index) {
  5794. if (GLCAT.is_spam() && gl_debug_buffers) {
  5795. GLCAT.spam()
  5796. << "binding vertex buffer " << (int)gvbc->_index << "\n";
  5797. }
  5798. _glBindBuffer(GL_ARRAY_BUFFER, gvbc->_index);
  5799. _current_vbuffer_index = gvbc->_index;
  5800. }
  5801. // NULL is the OpenGL convention for the first byte of the buffer object.
  5802. client_pointer = nullptr;
  5803. return true;
  5804. }
  5805. /**
  5806. * Creates a new retained-mode representation of the given data, and returns a
  5807. * newly-allocated IndexBufferContext pointer to reference it. It is the
  5808. * responsibility of the calling function to later call release_index_buffer()
  5809. * with this same pointer (which will also delete the pointer).
  5810. *
  5811. * This function should not be called directly to prepare a buffer. Instead,
  5812. * call Geom::prepare().
  5813. */
  5814. IndexBufferContext *CLP(GraphicsStateGuardian)::
  5815. prepare_index_buffer(GeomPrimitive *data) {
  5816. if (_supports_buffers) {
  5817. PStatGPUTimer timer(this, _prepare_index_buffer_pcollector);
  5818. CLP(IndexBufferContext) *gibc = new CLP(IndexBufferContext)(this, _prepared_objects, data);
  5819. _glGenBuffers(1, &gibc->_index);
  5820. if (GLCAT.is_debug() && gl_debug_buffers) {
  5821. GLCAT.debug()
  5822. << "creating index buffer " << (int)gibc->_index << ": "
  5823. << data->get_num_vertices() << " indices ("
  5824. << data->get_vertices()->get_array_format()->get_column(0)->get_numeric_type()
  5825. << ")\n";
  5826. }
  5827. report_my_gl_errors();
  5828. GeomPrimitivePipelineReader reader(data, Thread::get_current_thread());
  5829. apply_index_buffer(gibc, &reader, false);
  5830. return gibc;
  5831. }
  5832. return nullptr;
  5833. }
  5834. /**
  5835. * Makes the data the currently available data for rendering.
  5836. */
  5837. bool CLP(GraphicsStateGuardian)::
  5838. apply_index_buffer(IndexBufferContext *ibc,
  5839. const GeomPrimitivePipelineReader *reader,
  5840. bool force) {
  5841. nassertr(_supports_buffers, false);
  5842. if (reader->get_modified() == UpdateSeq::initial()) {
  5843. // No need to re-apply.
  5844. return true;
  5845. }
  5846. CLP(IndexBufferContext) *gibc = DCAST(CLP(IndexBufferContext), ibc);
  5847. if (_current_ibuffer_index != gibc->_index) {
  5848. if (GLCAT.is_spam() && gl_debug_buffers) {
  5849. GLCAT.spam()
  5850. << "binding index buffer " << (int)gibc->_index << "\n";
  5851. }
  5852. _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gibc->_index);
  5853. _current_ibuffer_index = gibc->_index;
  5854. gibc->set_active(true);
  5855. }
  5856. if (gibc->was_modified(reader)) {
  5857. int num_bytes = reader->get_data_size_bytes();
  5858. if (GLCAT.is_debug() && gl_debug_buffers) {
  5859. GLCAT.debug()
  5860. << "copying " << num_bytes
  5861. << " bytes into index buffer " << (int)gibc->_index << "\n";
  5862. }
  5863. if (num_bytes != 0) {
  5864. const unsigned char *client_pointer = reader->get_read_pointer(force);
  5865. if (client_pointer == nullptr) {
  5866. return false;
  5867. }
  5868. PStatGPUTimer timer(this, _load_index_buffer_pcollector, reader->get_current_thread());
  5869. if (gibc->changed_size(reader) || gibc->changed_usage_hint(reader)) {
  5870. _glBufferData(GL_ELEMENT_ARRAY_BUFFER, num_bytes, client_pointer,
  5871. get_usage(reader->get_usage_hint()));
  5872. } else {
  5873. _glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, num_bytes,
  5874. client_pointer);
  5875. }
  5876. _data_transferred_pcollector.add_level(num_bytes);
  5877. }
  5878. gibc->mark_loaded(reader);
  5879. }
  5880. gibc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  5881. maybe_gl_finish();
  5882. report_my_gl_errors();
  5883. return true;
  5884. }
  5885. /**
  5886. * Frees the GL resources previously allocated for the data. This function
  5887. * should never be called directly; instead, call Data::release() (or simply
  5888. * let the Data destruct).
  5889. */
  5890. void CLP(GraphicsStateGuardian)::
  5891. release_index_buffer(IndexBufferContext *ibc) {
  5892. nassertv(_supports_buffers);
  5893. CLP(IndexBufferContext) *gibc = DCAST(CLP(IndexBufferContext), ibc);
  5894. if (GLCAT.is_debug() && gl_debug_buffers) {
  5895. GLCAT.debug()
  5896. << "deleting index buffer " << (int)gibc->_index << "\n";
  5897. }
  5898. // Make sure the buffer is unbound before we delete it. Not strictly
  5899. // necessary according to the OpenGL spec, but it might help out a flaky
  5900. // driver, and we need to keep our internal state consistent anyway.
  5901. if (_current_ibuffer_index == gibc->_index) {
  5902. if (GLCAT.is_spam() && gl_debug_buffers) {
  5903. GLCAT.spam()
  5904. << "unbinding index buffer\n";
  5905. }
  5906. _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  5907. _current_ibuffer_index = 0;
  5908. }
  5909. _glDeleteBuffers(1, &gibc->_index);
  5910. report_my_gl_errors();
  5911. gibc->_index = 0;
  5912. delete gibc;
  5913. }
  5914. /**
  5915. * Frees the GL resources previously allocated for the data. This function
  5916. * should never be called directly; instead, call Data::release() (or simply
  5917. * let the Data destruct).
  5918. */
  5919. void CLP(GraphicsStateGuardian)::
  5920. release_index_buffers(const pvector<BufferContext *> &contexts) {
  5921. if (contexts.empty()) {
  5922. return;
  5923. }
  5924. nassertv(_supports_buffers);
  5925. bool debug = GLCAT.is_debug() && gl_debug_buffers;
  5926. GLuint *indices = (GLuint *)alloca(sizeof(GLuint) * contexts.size());
  5927. size_t num_indices = 0;
  5928. for (BufferContext *bc : contexts) {
  5929. CLP(IndexBufferContext) *gibc = DCAST(CLP(IndexBufferContext), bc);
  5930. // Make sure the buffer is unbound before we delete it. Not strictly
  5931. // necessary according to the OpenGL spec, but it might help out a flaky
  5932. // driver, and we need to keep our internal state consistent anyway.
  5933. if (_current_ibuffer_index == gibc->_index) {
  5934. if (debug && GLCAT.is_spam()) {
  5935. GLCAT.spam()
  5936. << "unbinding index buffer " << gibc->_index << "\n";
  5937. }
  5938. _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  5939. _current_ibuffer_index = 0;
  5940. }
  5941. if (debug) {
  5942. GLCAT.debug()
  5943. << "deleting index buffer " << gibc->_index << "\n";
  5944. }
  5945. indices[num_indices++] = gibc->_index;
  5946. gibc->_index = 0;
  5947. delete gibc;
  5948. }
  5949. _glDeleteBuffers(num_indices, indices);
  5950. report_my_gl_errors();
  5951. }
  5952. /**
  5953. * Internal function to bind a buffer object for the indicated primitive's
  5954. * index list, if appropriate, or to unbind a buffer object if it should be
  5955. * rendered from client memory.
  5956. *
  5957. * If the buffer object is bound, this function sets client_pointer to NULL
  5958. * (representing the start of the buffer object in server memory); if the
  5959. * buffer object is not bound, this function sets client_pointer to to the
  5960. * data array in client memory, that is, the data array passed in.
  5961. *
  5962. * If force is not true, the function may return false indicating the data is
  5963. * not currently available.
  5964. */
  5965. bool CLP(GraphicsStateGuardian)::
  5966. setup_primitive(const unsigned char *&client_pointer,
  5967. const GeomPrimitivePipelineReader *reader,
  5968. bool force) {
  5969. if (!_supports_buffers) {
  5970. // No support for buffer objects; always render from client.
  5971. client_pointer = reader->get_read_pointer(force);
  5972. return (client_pointer != nullptr);
  5973. }
  5974. if (!vertex_buffers || _geom_display_list != 0 ||
  5975. reader->get_usage_hint() == Geom::UH_client) {
  5976. // The array specifies client rendering only, or buffer objects are
  5977. // configured off.
  5978. if (_current_ibuffer_index != 0) {
  5979. if (GLCAT.is_spam() && gl_debug_buffers) {
  5980. GLCAT.spam()
  5981. << "unbinding index buffer\n";
  5982. }
  5983. _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  5984. _current_ibuffer_index = 0;
  5985. }
  5986. client_pointer = reader->get_read_pointer(force);
  5987. return (client_pointer != nullptr);
  5988. }
  5989. // Prepare the buffer object and bind it.
  5990. IndexBufferContext *ibc = reader->prepare_now(get_prepared_objects(), this);
  5991. nassertr(ibc != nullptr, false);
  5992. if (!apply_index_buffer(ibc, reader, force)) {
  5993. return false;
  5994. }
  5995. // NULL is the OpenGL convention for the first byte of the buffer object.
  5996. client_pointer = nullptr;
  5997. return true;
  5998. }
  5999. #ifndef OPENGLES
  6000. /**
  6001. * Creates a new retained-mode representation of the given data, and returns a
  6002. * newly-allocated BufferContext pointer to reference it. It is the
  6003. * responsibility of the calling function to later call release_shader_buffer()
  6004. * with this same pointer (which will also delete the pointer).
  6005. *
  6006. * This function should not be called directly to prepare a buffer. Instead,
  6007. * call ShaderBuffer::prepare().
  6008. */
  6009. BufferContext *CLP(GraphicsStateGuardian)::
  6010. prepare_shader_buffer(ShaderBuffer *data) {
  6011. if (_supports_shader_buffers) {
  6012. PStatGPUTimer timer(this, _prepare_shader_buffer_pcollector);
  6013. CLP(BufferContext) *gbc = new CLP(BufferContext)(this, _prepared_objects, data);
  6014. _glGenBuffers(1, &gbc->_index);
  6015. if (GLCAT.is_debug() && gl_debug_buffers) {
  6016. GLCAT.debug()
  6017. << "creating shader buffer " << (int)gbc->_index << ": "<< *data << "\n";
  6018. }
  6019. _glBindBuffer(GL_SHADER_STORAGE_BUFFER, gbc->_index);
  6020. _current_sbuffer_index = gbc->_index;
  6021. if (_use_object_labels) {
  6022. string name = data->get_name();
  6023. _glObjectLabel(GL_BUFFER, gbc->_index, name.size(), name.data());
  6024. }
  6025. // Some drivers require the buffer to be padded to 16 byte boundary.
  6026. uint64_t num_bytes = (data->get_data_size_bytes() + 15u) & ~15u;
  6027. if (_supports_buffer_storage) {
  6028. _glBufferStorage(GL_SHADER_STORAGE_BUFFER, num_bytes, data->get_initial_data(), 0);
  6029. } else {
  6030. _glBufferData(GL_SHADER_STORAGE_BUFFER, num_bytes, data->get_initial_data(), get_usage(data->get_usage_hint()));
  6031. }
  6032. gbc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  6033. report_my_gl_errors();
  6034. return gbc;
  6035. }
  6036. return nullptr;
  6037. }
  6038. /**
  6039. * Binds the given shader buffer to the given binding slot.
  6040. */
  6041. void CLP(GraphicsStateGuardian)::
  6042. apply_shader_buffer(GLuint base, ShaderBuffer *buffer) {
  6043. GLuint index = 0;
  6044. if (buffer != nullptr) {
  6045. BufferContext *bc = buffer->prepare_now(get_prepared_objects(), this);
  6046. if (bc != nullptr) {
  6047. CLP(BufferContext) *gbc = DCAST(CLP(BufferContext), bc);
  6048. index = gbc->_index;
  6049. gbc->set_active(true);
  6050. }
  6051. }
  6052. if (base >= _current_sbuffer_base.size()) {
  6053. _current_sbuffer_base.resize(base + 1, 0);
  6054. }
  6055. if (_current_sbuffer_base[base] != index) {
  6056. if (GLCAT.is_spam() && gl_debug_buffers) {
  6057. GLCAT.spam()
  6058. << "binding shader buffer " << (int)index
  6059. << " to index " << base << "\n";
  6060. }
  6061. _glBindBufferBase(GL_SHADER_STORAGE_BUFFER, base, index);
  6062. _current_sbuffer_base[base] = index;
  6063. _current_sbuffer_index = index;
  6064. report_my_gl_errors();
  6065. }
  6066. }
  6067. /**
  6068. * Frees the GL resources previously allocated for the data. This function
  6069. * should never be called directly; instead, call Data::release() (or simply
  6070. * let the Data destruct).
  6071. */
  6072. void CLP(GraphicsStateGuardian)::
  6073. release_shader_buffer(BufferContext *bc) {
  6074. nassertv(_supports_buffers);
  6075. CLP(BufferContext) *gbc = DCAST(CLP(BufferContext), bc);
  6076. if (GLCAT.is_debug() && gl_debug_buffers) {
  6077. GLCAT.debug()
  6078. << "deleting shader buffer " << (int)gbc->_index << "\n";
  6079. }
  6080. // Make sure the buffer is unbound before we delete it. Not strictly
  6081. // necessary according to the OpenGL spec, but it might help out a flaky
  6082. // driver, and we need to keep our internal state consistent anyway.
  6083. if (_current_sbuffer_index == gbc->_index) {
  6084. if (GLCAT.is_spam() && gl_debug_buffers) {
  6085. GLCAT.spam()
  6086. << "unbinding shader buffer\n";
  6087. }
  6088. _glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
  6089. _current_sbuffer_index = 0;
  6090. }
  6091. _glDeleteBuffers(1, &gbc->_index);
  6092. report_my_gl_errors();
  6093. gbc->_index = 0;
  6094. delete gbc;
  6095. }
  6096. /**
  6097. * Frees the GL resources previously allocated for the data. This function
  6098. * should never be called directly; instead, call Data::release() (or simply
  6099. * let the Data destruct).
  6100. */
  6101. void CLP(GraphicsStateGuardian)::
  6102. release_shader_buffers(const pvector<BufferContext *> &contexts) {
  6103. if (contexts.empty()) {
  6104. return;
  6105. }
  6106. nassertv(_supports_buffers);
  6107. bool debug = GLCAT.is_debug() && gl_debug_buffers;
  6108. GLuint *indices = (GLuint *)alloca(sizeof(GLuint) * contexts.size());
  6109. size_t num_indices = 0;
  6110. for (BufferContext *bc : contexts) {
  6111. CLP(BufferContext) *gbc = DCAST(CLP(BufferContext), bc);
  6112. // Make sure the buffer is unbound before we delete it. Not strictly
  6113. // necessary according to the OpenGL spec, but it might help out a flaky
  6114. // driver, and we need to keep our internal state consistent anyway.
  6115. if (_current_sbuffer_index == gbc->_index) {
  6116. if (debug && GLCAT.is_spam()) {
  6117. GLCAT.spam()
  6118. << "unbinding shader buffer " << gbc->_index << "\n";
  6119. }
  6120. _glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
  6121. _current_sbuffer_index = 0;
  6122. }
  6123. if (debug) {
  6124. GLCAT.debug()
  6125. << "deleting shader buffer " << gbc->_index << "\n";
  6126. }
  6127. indices[num_indices++] = gbc->_index;
  6128. gbc->_index = 0;
  6129. delete gbc;
  6130. }
  6131. _glDeleteBuffers(num_indices, indices);
  6132. report_my_gl_errors();
  6133. }
  6134. #endif
  6135. #ifndef OPENGLES
  6136. /**
  6137. * Begins a new occlusion query. After this call, you may call
  6138. * begin_draw_primitives() and draw_triangles()/draw_whatever() repeatedly.
  6139. * Eventually, you should call end_occlusion_query() before the end of the
  6140. * frame; that will return a new OcclusionQueryContext object that will tell
  6141. * you how many pixels represented by the bracketed geometry passed the depth
  6142. * test.
  6143. *
  6144. * It is not valid to call begin_occlusion_query() between another
  6145. * begin_occlusion_query() .. end_occlusion_query() sequence.
  6146. */
  6147. void CLP(GraphicsStateGuardian)::
  6148. begin_occlusion_query() {
  6149. nassertv(_supports_occlusion_query);
  6150. nassertv(_current_occlusion_query == nullptr);
  6151. PT(CLP(OcclusionQueryContext)) query = new CLP(OcclusionQueryContext)(this);
  6152. _glGenQueries(1, &query->_index);
  6153. if (GLCAT.is_debug()) {
  6154. GLCAT.debug()
  6155. << "beginning occlusion query index " << (int)query->_index << "\n";
  6156. }
  6157. _glBeginQuery(GL_SAMPLES_PASSED, query->_index);
  6158. _current_occlusion_query = query;
  6159. report_my_gl_errors();
  6160. }
  6161. #endif // !OPENGLES
  6162. #ifndef OPENGLES
  6163. /**
  6164. * Ends a previous call to begin_occlusion_query(). This call returns the
  6165. * OcclusionQueryContext object that will (eventually) report the number of
  6166. * pixels that passed the depth test between the call to
  6167. * begin_occlusion_query() and end_occlusion_query().
  6168. */
  6169. PT(OcclusionQueryContext) CLP(GraphicsStateGuardian)::
  6170. end_occlusion_query() {
  6171. nassertr(_current_occlusion_query != nullptr, nullptr);
  6172. PT(OcclusionQueryContext) result = _current_occlusion_query;
  6173. GLuint index = DCAST(CLP(OcclusionQueryContext), result)->_index;
  6174. if (GLCAT.is_debug()) {
  6175. GLCAT.debug()
  6176. << "ending occlusion query index " << (int)index << "\n";
  6177. }
  6178. _current_occlusion_query = nullptr;
  6179. _glEndQuery(GL_SAMPLES_PASSED);
  6180. // Temporary hack to try working around an apparent driver bug on iMacs.
  6181. // Occlusion queries sometimes incorrectly report 0 samples, unless we stall
  6182. // the pipe to keep fewer than a certain maximum number of queries pending
  6183. // at once.
  6184. static ConfigVariableInt limit_occlusion_queries("limit-occlusion-queries", 0);
  6185. if (limit_occlusion_queries > 0) {
  6186. if (index > (unsigned int)limit_occlusion_queries) {
  6187. PStatGPUTimer timer(this, _wait_occlusion_pcollector);
  6188. GLuint result;
  6189. _glGetQueryObjectuiv(index - (unsigned int)limit_occlusion_queries,
  6190. GL_QUERY_RESULT, &result);
  6191. }
  6192. }
  6193. report_my_gl_errors();
  6194. return result;
  6195. }
  6196. #endif // !OPENGLES
  6197. /**
  6198. * Adds a timer query to the command stream, associated with the given PStats
  6199. * collector index.
  6200. */
  6201. PT(TimerQueryContext) CLP(GraphicsStateGuardian)::
  6202. issue_timer_query(int pstats_index) {
  6203. #if defined(DO_PSTATS) && !defined(OPENGLES)
  6204. nassertr(_supports_timer_query, nullptr);
  6205. PT(CLP(TimerQueryContext)) query;
  6206. // Hack
  6207. if (pstats_index == _command_latency_pcollector.get_index()) {
  6208. query = new CLP(LatencyQueryContext)(this, pstats_index);
  6209. } else {
  6210. query = new CLP(TimerQueryContext)(this, pstats_index);
  6211. }
  6212. if (_deleted_queries.size() >= 1) {
  6213. query->_index = _deleted_queries.back();
  6214. _deleted_queries.pop_back();
  6215. } else {
  6216. _glGenQueries(1, &query->_index);
  6217. if (GLCAT.is_spam()) {
  6218. GLCAT.spam() << "Generating query for " << pstats_index
  6219. << ": " << query->_index << "\n";
  6220. }
  6221. }
  6222. // Issue the timestamp query.
  6223. _glQueryCounter(query->_index, GL_TIMESTAMP);
  6224. if (_use_object_labels) {
  6225. // Assign a label to it based on the PStatCollector name.
  6226. const PStatClient *client = PStatClient::get_global_pstats();
  6227. string name = client->get_collector_fullname(pstats_index & 0x7fff);
  6228. _glObjectLabel(GL_QUERY, query->_index, name.size(), name.data());
  6229. }
  6230. _pending_timer_queries.push_back((TimerQueryContext *)query);
  6231. return (TimerQueryContext *)query;
  6232. #else
  6233. return nullptr;
  6234. #endif
  6235. }
  6236. #ifndef OPENGLES_1
  6237. /**
  6238. * Dispatches a currently bound compute shader using the given work group
  6239. * counts.
  6240. */
  6241. void CLP(GraphicsStateGuardian)::
  6242. dispatch_compute(int num_groups_x, int num_groups_y, int num_groups_z) {
  6243. maybe_gl_finish();
  6244. PStatGPUTimer timer(this, _compute_dispatch_pcollector);
  6245. nassertv(_supports_compute_shaders);
  6246. nassertv(_current_shader_context != nullptr);
  6247. _glDispatchCompute(num_groups_x, num_groups_y, num_groups_z);
  6248. maybe_gl_finish();
  6249. }
  6250. #endif // !OPENGLES_1
  6251. /**
  6252. * Creates a new GeomMunger object to munge vertices appropriate to this GSG
  6253. * for the indicated state.
  6254. */
  6255. PT(GeomMunger) CLP(GraphicsStateGuardian)::
  6256. make_geom_munger(const RenderState *state, Thread *current_thread) {
  6257. PT(CLP(GeomMunger)) munger = new CLP(GeomMunger)(this, state);
  6258. return GeomMunger::register_munger(munger, current_thread);
  6259. }
  6260. /**
  6261. * Copy the pixels within the indicated display region from the framebuffer
  6262. * into texture memory.
  6263. *
  6264. * If z > -1, it is the cube map index or layer index into which to copy.
  6265. */
  6266. bool CLP(GraphicsStateGuardian)::
  6267. framebuffer_copy_to_texture(Texture *tex, int view, int z,
  6268. const DisplayRegion *dr, const RenderBuffer &rb) {
  6269. nassertr(tex != nullptr && dr != nullptr, false);
  6270. set_read_buffer(rb._buffer_type);
  6271. clear_color_write_mask();
  6272. int xo, yo, w, h;
  6273. dr->get_region_pixels(xo, yo, w, h);
  6274. tex->set_size_padded(w, h, tex->get_z_size());
  6275. if (tex->get_compression() == Texture::CM_default) {
  6276. // Unless the user explicitly turned on texture compression, turn it off
  6277. // for the copy-to-texture case.
  6278. tex->set_compression(Texture::CM_off);
  6279. }
  6280. // Sanity check everything.
  6281. if (z >= 0) {
  6282. if (z >= tex->get_z_size()) {
  6283. // This can happen, when textures with different layer counts are
  6284. // attached to a buffer. We simply ignore this if it happens.
  6285. return false;
  6286. }
  6287. if ((w != tex->get_x_size()) ||
  6288. (h != tex->get_y_size())) {
  6289. return false;
  6290. }
  6291. if (tex->get_texture_type() == Texture::TT_cube_map) {
  6292. if (!_supports_cube_map) {
  6293. return false;
  6294. }
  6295. nassertr(z < 6, false);
  6296. if (w != h) {
  6297. return false;
  6298. }
  6299. } else if (tex->get_texture_type() == Texture::TT_3d_texture) {
  6300. if (!_supports_3d_texture) {
  6301. return false;
  6302. }
  6303. } else if (tex->get_texture_type() == Texture::TT_2d_texture_array) {
  6304. if (!_supports_2d_texture_array) {
  6305. return false;
  6306. }
  6307. } else {
  6308. GLCAT.error()
  6309. << "Don't know how to copy framebuffer to texture " << *tex << "\n";
  6310. }
  6311. } else {
  6312. nassertr(tex->get_texture_type() == Texture::TT_2d_texture, false);
  6313. }
  6314. // Match framebuffer format if necessary.
  6315. if (tex->get_match_framebuffer_format()) {
  6316. switch (tex->get_format()) {
  6317. case Texture::F_depth_component:
  6318. case Texture::F_depth_component16:
  6319. case Texture::F_depth_component24:
  6320. case Texture::F_depth_component32:
  6321. case Texture::F_depth_stencil:
  6322. // Don't remap if we're one of these special format.
  6323. break;
  6324. default:
  6325. // If the texture is a color format, we want to match the presence of
  6326. // sRGB and alpha according to the framebuffer.
  6327. if (_current_properties->get_srgb_color()) {
  6328. if (_current_properties->get_alpha_bits()) {
  6329. tex->set_format(Texture::F_srgb_alpha);
  6330. } else {
  6331. tex->set_format(Texture::F_srgb);
  6332. }
  6333. } else {
  6334. if (_current_properties->get_alpha_bits()) {
  6335. tex->set_format(Texture::F_rgba);
  6336. } else {
  6337. tex->set_format(Texture::F_rgb);
  6338. }
  6339. }
  6340. }
  6341. }
  6342. TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this);
  6343. nassertr(tc != nullptr, false);
  6344. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
  6345. apply_texture(gtc);
  6346. bool needs_reload = specify_texture(gtc, tex->get_default_sampler());
  6347. GLenum target = get_texture_target(tex->get_texture_type());
  6348. GLint internal_format = get_internal_image_format(tex);
  6349. int width = tex->get_x_size();
  6350. int height = tex->get_y_size();
  6351. int depth = tex->get_z_size();
  6352. bool uses_mipmaps = tex->uses_mipmaps() && !gl_ignore_mipmaps;
  6353. if (uses_mipmaps) {
  6354. if (_supports_generate_mipmap) {
  6355. #ifndef OPENGLES_2
  6356. if (_glGenerateMipmap == nullptr) {
  6357. glTexParameteri(target, GL_GENERATE_MIPMAP, true);
  6358. }
  6359. #endif
  6360. } else {
  6361. // If we can't auto-generate mipmaps, do without mipmaps.
  6362. glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  6363. uses_mipmaps = false;
  6364. }
  6365. }
  6366. bool new_image = needs_reload || gtc->was_image_modified();
  6367. if (z >= 0) {
  6368. if (target == GL_TEXTURE_CUBE_MAP) {
  6369. // Copy to a cube map face, which is treated as a 2D texture.
  6370. target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + z;
  6371. depth = 1;
  6372. z = -1;
  6373. // Cube map faces seem to have trouble with CopyTexSubImage, so we
  6374. // always reload the image.
  6375. new_image = true;
  6376. }
  6377. }
  6378. if (!gtc->_has_storage ||
  6379. internal_format != gtc->_internal_format ||
  6380. uses_mipmaps != gtc->_uses_mipmaps ||
  6381. width != gtc->_width ||
  6382. height != gtc->_height ||
  6383. depth != gtc->_depth) {
  6384. // If the texture properties have changed, we need to reload the image.
  6385. new_image = true;
  6386. }
  6387. if (new_image && gtc->_immutable) {
  6388. gtc->reset_data();
  6389. glBindTexture(target, gtc->_index);
  6390. if (GLCAT.is_spam()) {
  6391. GLCAT.spam()
  6392. << "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << "): " << *tex << "\n";
  6393. }
  6394. }
  6395. #ifndef OPENGLES_1
  6396. if (gtc->needs_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT)) {
  6397. // Make sure that any incoherent writes to this texture have been synced.
  6398. issue_memory_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
  6399. }
  6400. #endif
  6401. if (z >= 0) {
  6402. #ifndef OPENGLES_1
  6403. if (new_image) {
  6404. // These won't be used because we pass a NULL image, but we still have
  6405. // to specify them. Might as well use the actual values.
  6406. GLint external_format = get_external_image_format(tex);
  6407. GLint component_type = get_component_type(tex->get_component_type());
  6408. _glTexImage3D(target, 0, internal_format, width, height, depth, 0, external_format, component_type, nullptr);
  6409. }
  6410. _glCopyTexSubImage3D(target, 0, 0, 0, z, xo, yo, w, h);
  6411. #endif
  6412. } else {
  6413. if (new_image) {
  6414. // We have to create a new image. It seems that OpenGL accepts a size
  6415. // higher than the framebuffer, but if we run into trouble we'll have to
  6416. // replace this with something smarter.
  6417. glCopyTexImage2D(target, 0, internal_format, xo, yo, width, height, 0);
  6418. } else {
  6419. // We can overlay the existing image.
  6420. glCopyTexSubImage2D(target, 0, 0, 0, xo, yo, w, h);
  6421. }
  6422. }
  6423. if (uses_mipmaps && _glGenerateMipmap != nullptr) {
  6424. glEnable(target);
  6425. _glGenerateMipmap(target);
  6426. glDisable(target);
  6427. }
  6428. gtc->_has_storage = true;
  6429. gtc->_uses_mipmaps = uses_mipmaps;
  6430. gtc->_internal_format = internal_format;
  6431. gtc->_width = width;
  6432. gtc->_height = height;
  6433. gtc->_depth = depth;
  6434. gtc->mark_loaded();
  6435. gtc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  6436. report_my_gl_errors();
  6437. // Force reload of texture state, since we've just monkeyed with it.
  6438. _state_mask.clear_bit(TextureAttrib::get_class_slot());
  6439. return true;
  6440. }
  6441. /**
  6442. * Copy the pixels within the indicated display region from the framebuffer
  6443. * into system memory, not texture memory. Returns true on success, false on
  6444. * failure.
  6445. *
  6446. * This completely redefines the ram image of the indicated texture.
  6447. */
  6448. bool CLP(GraphicsStateGuardian)::
  6449. framebuffer_copy_to_ram(Texture *tex, int view, int z,
  6450. const DisplayRegion *dr, const RenderBuffer &rb) {
  6451. nassertr(tex != nullptr && dr != nullptr, false);
  6452. set_read_buffer(rb._buffer_type);
  6453. glPixelStorei(GL_PACK_ALIGNMENT, 1);
  6454. clear_color_write_mask();
  6455. // Bug fix for RE, RE2, and VTX - need to disable texturing in order for
  6456. // glReadPixels() to work NOTE: reading the depth buffer is *much* slower
  6457. // than reading the color buffer
  6458. set_state_and_transform(RenderState::make_empty(), _internal_transform);
  6459. int xo, yo, w, h;
  6460. dr->get_region_pixels(xo, yo, w, h);
  6461. Texture::ComponentType component_type = tex->get_component_type();
  6462. Texture::Format format = tex->get_format();
  6463. switch (format) {
  6464. case Texture::F_depth_stencil:
  6465. if (_current_properties->get_float_depth()) {
  6466. component_type = Texture::T_float;
  6467. } else {
  6468. component_type = Texture::T_unsigned_int_24_8;
  6469. }
  6470. break;
  6471. case Texture::F_depth_component:
  6472. if (_current_properties->get_float_depth()) {
  6473. component_type = Texture::T_float;
  6474. } else if (_current_properties->get_depth_bits() <= 8) {
  6475. component_type = Texture::T_unsigned_byte;
  6476. } else if (_current_properties->get_depth_bits() <= 16) {
  6477. component_type = Texture::T_unsigned_short;
  6478. } else {
  6479. component_type = Texture::T_float;
  6480. }
  6481. break;
  6482. case Texture::F_depth_component16:
  6483. component_type = Texture::T_unsigned_short;
  6484. break;
  6485. case Texture::F_depth_component24:
  6486. case Texture::F_depth_component32:
  6487. component_type = Texture::T_float;
  6488. break;
  6489. default:
  6490. if (_current_properties->get_srgb_color()) {
  6491. if (_current_properties->get_alpha_bits()) {
  6492. format = Texture::F_srgb_alpha;
  6493. } else {
  6494. format = Texture::F_srgb;
  6495. }
  6496. } else if (_current_properties->get_float_color()) {
  6497. if (_current_properties->get_alpha_bits()) {
  6498. format = Texture::F_rgba32;
  6499. } else if (_current_properties->get_blue_bits()) {
  6500. format = Texture::F_rgb32;
  6501. } else if (_current_properties->get_green_bits()) {
  6502. format = Texture::F_rg32;
  6503. } else {
  6504. format = Texture::F_r32;
  6505. }
  6506. } else {
  6507. if (_current_properties->get_alpha_bits()) {
  6508. format = Texture::F_rgba;
  6509. } else {
  6510. format = Texture::F_rgb;
  6511. }
  6512. }
  6513. if (_current_properties->get_float_color()) {
  6514. component_type = Texture::T_float;
  6515. } else if (_current_properties->get_color_bits() <= 24
  6516. && _current_properties->get_red_bits() <= 8
  6517. && _current_properties->get_green_bits() <= 8
  6518. && _current_properties->get_blue_bits() <= 8
  6519. && _current_properties->get_alpha_bits() <= 8) {
  6520. component_type = Texture::T_unsigned_byte;
  6521. } else {
  6522. component_type = Texture::T_unsigned_short;
  6523. }
  6524. }
  6525. Texture::TextureType texture_type;
  6526. int z_size;
  6527. // TODO: should be extended to support 3D textures, 2D arrays and cube map
  6528. // arrays.
  6529. if (z >= 0) {
  6530. texture_type = Texture::TT_cube_map;
  6531. z_size = 6;
  6532. } else {
  6533. texture_type = Texture::TT_2d_texture;
  6534. z_size = 1;
  6535. }
  6536. int num_views = tex->get_num_views();
  6537. if (tex->get_x_size() != w || tex->get_y_size() != h ||
  6538. tex->get_z_size() != z_size ||
  6539. tex->get_component_type() != component_type ||
  6540. tex->get_format() != format ||
  6541. tex->get_texture_type() != texture_type ||
  6542. view >= num_views) {
  6543. tex->setup_texture(texture_type, w, h, z_size, component_type, format);
  6544. // The above resets the number of views to 1, so set this back.
  6545. num_views = std::max(view + 1, num_views);
  6546. if (num_views > 1) {
  6547. tex->set_num_views(num_views);
  6548. }
  6549. }
  6550. nassertr(z < tex->get_z_size(), false);
  6551. GLenum external_format = get_external_image_format(tex);
  6552. // OpenGL ES implementations may support BGRA, but that doesn't imply they
  6553. // also support it for glReadPixels specifically.
  6554. if (!_supports_bgra_read && external_format == GL_BGRA) {
  6555. external_format = GL_RGBA;
  6556. }
  6557. if (GLCAT.is_spam()) {
  6558. GLCAT.spam()
  6559. << "glReadPixels(" << xo << ", " << yo << ", " << w << ", " << h << ", ";
  6560. switch (external_format) {
  6561. case GL_DEPTH_COMPONENT:
  6562. GLCAT.spam(false) << "GL_DEPTH_COMPONENT, ";
  6563. break;
  6564. case GL_DEPTH_STENCIL:
  6565. GLCAT.spam(false) << "GL_DEPTH_STENCIL, ";
  6566. break;
  6567. #ifndef OPENGLES_1
  6568. case GL_RG:
  6569. GLCAT.spam(false) << "GL_RG, ";
  6570. break;
  6571. #endif
  6572. case GL_RGB:
  6573. GLCAT.spam(false) << "GL_RGB, ";
  6574. break;
  6575. case GL_RGBA:
  6576. GLCAT.spam(false) << "GL_RGBA, ";
  6577. break;
  6578. #ifndef OPENGLES
  6579. case GL_BGR:
  6580. GLCAT.spam(false) << "GL_BGR, ";
  6581. break;
  6582. #endif
  6583. case GL_BGRA:
  6584. GLCAT.spam(false) << "GL_BGRA, ";
  6585. break;
  6586. default:
  6587. GLCAT.spam(false) << "unknown, ";
  6588. break;
  6589. }
  6590. switch (get_component_type(component_type)) {
  6591. case GL_UNSIGNED_BYTE:
  6592. GLCAT.spam(false) << "GL_UNSIGNED_BYTE";
  6593. break;
  6594. case GL_UNSIGNED_SHORT:
  6595. GLCAT.spam(false) << "GL_UNSIGNED_SHORT";
  6596. break;
  6597. case GL_FLOAT:
  6598. GLCAT.spam(false) << "GL_FLOAT";
  6599. break;
  6600. #ifndef OPENGLES_1
  6601. case GL_INT:
  6602. GLCAT.spam(false) << "GL_INT";
  6603. break;
  6604. #endif
  6605. default:
  6606. GLCAT.spam(false) << "unknown";
  6607. break;
  6608. }
  6609. GLCAT.spam(false)
  6610. << ")" << endl;
  6611. }
  6612. unsigned char *image_ptr = tex->modify_ram_image();
  6613. size_t image_size = tex->get_ram_image_size();
  6614. if (z >= 0 || view > 0) {
  6615. image_size = tex->get_expected_ram_page_size();
  6616. if (z >= 0) {
  6617. image_ptr += z * image_size;
  6618. }
  6619. if (view > 0) {
  6620. image_ptr += (view * tex->get_z_size()) * image_size;
  6621. nassertr(view < tex->get_num_views(), false);
  6622. }
  6623. }
  6624. glReadPixels(xo, yo, w, h, external_format,
  6625. get_component_type(component_type), image_ptr);
  6626. // We may have to reverse the byte ordering of the image if GL didn't do it
  6627. // for us.
  6628. if (external_format == GL_RGBA || external_format == GL_RGB) {
  6629. PTA_uchar new_image;
  6630. const unsigned char *result =
  6631. fix_component_ordering(new_image, image_ptr, image_size,
  6632. external_format, tex);
  6633. if (result != image_ptr) {
  6634. memcpy(image_ptr, result, image_size);
  6635. }
  6636. }
  6637. report_my_gl_errors();
  6638. return true;
  6639. }
  6640. #ifdef SUPPORT_FIXED_FUNCTION
  6641. /**
  6642. *
  6643. */
  6644. void CLP(GraphicsStateGuardian)::
  6645. apply_fog(Fog *fog) {
  6646. Fog::Mode fmode = fog->get_mode();
  6647. glFogf(GL_FOG_MODE, get_fog_mode_type(fmode));
  6648. if (fmode == Fog::M_linear) {
  6649. PN_stdfloat onset, opaque;
  6650. fog->get_linear_range(onset, opaque);
  6651. glFogf(GL_FOG_START, onset);
  6652. glFogf(GL_FOG_END, opaque);
  6653. } else {
  6654. // Exponential fog is always camera-relative.
  6655. glFogf(GL_FOG_DENSITY, fog->get_exp_density());
  6656. }
  6657. call_glFogfv(GL_FOG_COLOR, fog->get_color());
  6658. report_my_gl_errors();
  6659. }
  6660. #endif // SUPPORT_FIXED_FUNCTION
  6661. /**
  6662. * Sends the indicated transform matrix to the graphics API to be applied to
  6663. * future vertices.
  6664. *
  6665. * This transform is the internal_transform, already converted into the GSG's
  6666. * internal coordinate system.
  6667. */
  6668. void CLP(GraphicsStateGuardian)::
  6669. do_issue_transform() {
  6670. #ifdef SUPPORT_FIXED_FUNCTION
  6671. if (has_fixed_function_pipeline()) {
  6672. // OpenGL ES 2 does not support glLoadMatrix.
  6673. const TransformState *transform = _internal_transform;
  6674. if (GLCAT.is_spam()) {
  6675. GLCAT.spam()
  6676. << "glLoadMatrix(GL_MODELVIEW): " << transform->get_mat() << endl;
  6677. }
  6678. DO_PSTATS_STUFF(_transform_state_pcollector.add_level(1));
  6679. glMatrixMode(GL_MODELVIEW);
  6680. call_glLoadMatrix(transform->get_mat());
  6681. }
  6682. #endif
  6683. _transform_stale = false;
  6684. report_my_gl_errors();
  6685. }
  6686. #ifdef SUPPORT_FIXED_FUNCTION
  6687. /**
  6688. *
  6689. */
  6690. void CLP(GraphicsStateGuardian)::
  6691. do_issue_shade_model() {
  6692. const ShadeModelAttrib *target_shade_model;
  6693. _target_rs->get_attrib_def(target_shade_model);
  6694. switch (target_shade_model->get_mode()) {
  6695. case ShadeModelAttrib::M_smooth:
  6696. glShadeModel(GL_SMOOTH);
  6697. _flat_shade_model = false;
  6698. break;
  6699. case ShadeModelAttrib::M_flat:
  6700. glShadeModel(GL_FLAT);
  6701. _flat_shade_model = true;
  6702. break;
  6703. }
  6704. }
  6705. #endif // SUPPORT_FIXED_FUNCTION
  6706. #ifndef OPENGLES_1
  6707. /**
  6708. * Called when the current ShaderAttrib state has changed.
  6709. */
  6710. void CLP(GraphicsStateGuardian)::
  6711. do_issue_shader() {
  6712. PStatTimer timer(_draw_set_state_shader_pcollector);
  6713. ShaderContext *context = 0;
  6714. Shader *shader = (Shader *)_target_shader->get_shader();
  6715. // If we don't have a shader, apply the default shader.
  6716. if (!has_fixed_function_pipeline() && !shader) {
  6717. shader = _default_shader;
  6718. nassertv(shader != nullptr);
  6719. }
  6720. if (shader) {
  6721. if (_current_shader != shader) {
  6722. context = shader->prepare_now(get_prepared_objects(), this);
  6723. } else {
  6724. context = _current_shader_context;
  6725. }
  6726. }
  6727. // If it failed, try applying the default shader.
  6728. if (_default_shader != nullptr && shader != _default_shader &&
  6729. (context == 0 || !context->valid())) {
  6730. shader = _default_shader;
  6731. nassertv(shader != nullptr);
  6732. if (_current_shader != shader) {
  6733. context = shader->prepare_now(get_prepared_objects(), this);
  6734. } else {
  6735. context = _current_shader_context;
  6736. }
  6737. }
  6738. if (context == 0 || !context->valid()) {
  6739. if (_current_shader_context != 0) {
  6740. _current_shader_context->unbind();
  6741. _current_shader = 0;
  6742. _current_shader_context = 0;
  6743. }
  6744. } else {
  6745. if (context != _current_shader_context) {
  6746. // Use a completely different shader than before. Unbind old shader,
  6747. // bind the new one.
  6748. if (_current_shader_context != nullptr &&
  6749. _current_shader->get_language() != shader->get_language()) {
  6750. // If it's a different type of shader, make sure to unbind the old.
  6751. _current_shader_context->unbind();
  6752. }
  6753. context->bind();
  6754. _current_shader = shader;
  6755. }
  6756. // Bind the shader storage buffers.
  6757. context->update_shader_buffer_bindings(_current_shader_context);
  6758. _current_shader_context = context;
  6759. }
  6760. #ifndef OPENGLES
  6761. // Is the point size provided by the shader or by OpenGL?
  6762. bool shader_point_size = _target_shader->get_flag(ShaderAttrib::F_shader_point_size);
  6763. if (shader_point_size != _shader_point_size) {
  6764. if (shader_point_size) {
  6765. glEnable(GL_PROGRAM_POINT_SIZE);
  6766. } else {
  6767. glDisable(GL_PROGRAM_POINT_SIZE);
  6768. }
  6769. _shader_point_size = shader_point_size;
  6770. }
  6771. #endif
  6772. report_my_gl_errors();
  6773. }
  6774. #endif // !OPENGLES_1
  6775. /**
  6776. *
  6777. */
  6778. void CLP(GraphicsStateGuardian)::
  6779. do_issue_render_mode() {
  6780. const RenderModeAttrib *target_render_mode;
  6781. _target_rs->get_attrib_def(target_render_mode);
  6782. _render_mode = target_render_mode->get_mode();
  6783. PN_stdfloat thickness = target_render_mode->get_thickness();
  6784. _point_perspective = target_render_mode->get_perspective();
  6785. #ifndef OPENGLES // glPolygonMode not supported by OpenGL ES.
  6786. switch (_render_mode) {
  6787. case RenderModeAttrib::M_unchanged:
  6788. case RenderModeAttrib::M_filled:
  6789. case RenderModeAttrib::M_filled_flat:
  6790. glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  6791. break;
  6792. case RenderModeAttrib::M_wireframe:
  6793. glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  6794. break;
  6795. case RenderModeAttrib::M_point:
  6796. glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
  6797. break;
  6798. default:
  6799. GLCAT.error()
  6800. << "Unknown render mode " << (int)_render_mode << endl;
  6801. }
  6802. #endif // OPENGLES
  6803. // The thickness affects both the line width and the point size.
  6804. if (thickness != _point_size) {
  6805. if (GLCAT.is_spam()) {
  6806. GLCAT.spam() << "setting thickness to " << thickness << "\n";
  6807. }
  6808. glLineWidth(std::min((GLfloat)thickness, _max_line_width));
  6809. #ifndef OPENGLES_2
  6810. glPointSize(thickness);
  6811. #endif
  6812. _point_size = thickness;
  6813. }
  6814. report_my_gl_errors();
  6815. #ifdef SUPPORT_FIXED_FUNCTION
  6816. if (has_fixed_function_pipeline()) {
  6817. do_point_size();
  6818. }
  6819. #endif
  6820. }
  6821. /**
  6822. *
  6823. */
  6824. void CLP(GraphicsStateGuardian)::
  6825. do_issue_antialias() {
  6826. const AntialiasAttrib *target_antialias;
  6827. _target_rs->get_attrib_def(target_antialias);
  6828. if (target_antialias->get_mode_type() == AntialiasAttrib::M_auto) {
  6829. // In this special mode, we must enable antialiasing on a case-by-case
  6830. // basis, because we enable it differently for polygons and for points and
  6831. // lines.
  6832. _auto_antialias_mode = true;
  6833. } else {
  6834. // Otherwise, explicitly enable or disable according to the bits that are
  6835. // set. But if multisample is requested and supported, don't use the
  6836. // other bits at all (they will be ignored by GL anyway).
  6837. _auto_antialias_mode = false;
  6838. unsigned short mode = target_antialias->get_mode();
  6839. if (_supports_multisample &&
  6840. (mode & AntialiasAttrib::M_multisample) != 0) {
  6841. enable_multisample_antialias(true);
  6842. } else {
  6843. enable_multisample_antialias(false);
  6844. enable_line_smooth((mode & AntialiasAttrib::M_line) != 0);
  6845. enable_point_smooth((mode & AntialiasAttrib::M_point) != 0);
  6846. enable_polygon_smooth((mode & AntialiasAttrib::M_polygon) != 0);
  6847. }
  6848. }
  6849. #ifndef OPENGLES_2
  6850. GLenum quality;
  6851. switch (target_antialias->get_mode_quality()) {
  6852. case AntialiasAttrib::M_faster:
  6853. quality = GL_FASTEST;
  6854. break;
  6855. case AntialiasAttrib::M_better:
  6856. quality = GL_NICEST;
  6857. break;
  6858. default:
  6859. quality = GL_DONT_CARE;
  6860. break;
  6861. }
  6862. if (_line_smooth_enabled) {
  6863. glHint(GL_LINE_SMOOTH_HINT, quality);
  6864. }
  6865. if (_point_smooth_enabled) {
  6866. glHint(GL_POINT_SMOOTH_HINT, quality);
  6867. }
  6868. #ifndef OPENGLES
  6869. if (_polygon_smooth_enabled) {
  6870. glHint(GL_POLYGON_SMOOTH_HINT, quality);
  6871. }
  6872. #endif
  6873. #endif // !OPENGLES_2
  6874. report_my_gl_errors();
  6875. }
  6876. #ifdef SUPPORT_FIXED_FUNCTION // OpenGL ES 2.0 doesn't support rescaling normals.
  6877. /**
  6878. *
  6879. */
  6880. void CLP(GraphicsStateGuardian)::
  6881. do_issue_rescale_normal() {
  6882. RescaleNormalAttrib::Mode mode = RescaleNormalAttrib::M_none;
  6883. const RescaleNormalAttrib *target_rescale_normal;
  6884. if (_target_rs->get_attrib(target_rescale_normal)) {
  6885. mode = target_rescale_normal->get_mode();
  6886. }
  6887. switch (mode) {
  6888. case RescaleNormalAttrib::M_none:
  6889. glDisable(GL_NORMALIZE);
  6890. if (_supports_rescale_normal && support_rescale_normal) {
  6891. glDisable(GL_RESCALE_NORMAL);
  6892. }
  6893. break;
  6894. case RescaleNormalAttrib::M_rescale:
  6895. if (_supports_rescale_normal && support_rescale_normal) {
  6896. glEnable(GL_RESCALE_NORMAL);
  6897. glDisable(GL_NORMALIZE);
  6898. } else {
  6899. glEnable(GL_NORMALIZE);
  6900. }
  6901. break;
  6902. case RescaleNormalAttrib::M_normalize:
  6903. glEnable(GL_NORMALIZE);
  6904. if (_supports_rescale_normal && support_rescale_normal) {
  6905. glDisable(GL_RESCALE_NORMAL);
  6906. }
  6907. break;
  6908. default:
  6909. GLCAT.error()
  6910. << "Unknown rescale_normal mode " << (int)mode << endl;
  6911. }
  6912. report_my_gl_errors();
  6913. }
  6914. #endif // SUPPORT_FIXED_FUNCTION
  6915. // PandaCompareFunc - 1 + 0x200 === GL_NEVER, etc. order is sequential
  6916. #define PANDA_TO_GL_COMPAREFUNC(PANDACMPFUNC) (PANDACMPFUNC-1 +0x200)
  6917. /**
  6918. *
  6919. */
  6920. void CLP(GraphicsStateGuardian)::
  6921. do_issue_depth_test() {
  6922. const DepthTestAttrib *target_depth_test;
  6923. _target_rs->get_attrib_def(target_depth_test);
  6924. DepthTestAttrib::PandaCompareFunc mode = target_depth_test->get_mode();
  6925. if (mode == DepthTestAttrib::M_none) {
  6926. enable_depth_test(false);
  6927. } else {
  6928. enable_depth_test(true);
  6929. glDepthFunc(PANDA_TO_GL_COMPAREFUNC(mode));
  6930. }
  6931. report_my_gl_errors();
  6932. }
  6933. #ifdef SUPPORT_FIXED_FUNCTION
  6934. /**
  6935. *
  6936. */
  6937. void CLP(GraphicsStateGuardian)::
  6938. do_issue_alpha_test() {
  6939. #ifndef OPENGLES_1
  6940. if (_target_shader->get_flag(ShaderAttrib::F_subsume_alpha_test)) {
  6941. enable_alpha_test(false);
  6942. } else
  6943. #endif
  6944. {
  6945. const AlphaTestAttrib *target_alpha_test;
  6946. _target_rs->get_attrib_def(target_alpha_test);
  6947. AlphaTestAttrib::PandaCompareFunc mode = target_alpha_test->get_mode();
  6948. if (mode == AlphaTestAttrib::M_none) {
  6949. enable_alpha_test(false);
  6950. } else {
  6951. nassertv(GL_NEVER == (AlphaTestAttrib::M_never-1+0x200));
  6952. glAlphaFunc(PANDA_TO_GL_COMPAREFUNC(mode), target_alpha_test->get_reference_alpha());
  6953. enable_alpha_test(true);
  6954. }
  6955. }
  6956. }
  6957. #endif // SUPPORT_FIXED_FUNCTION
  6958. /**
  6959. *
  6960. */
  6961. void CLP(GraphicsStateGuardian)::
  6962. do_issue_depth_write() {
  6963. const DepthWriteAttrib *target_depth_write;
  6964. _target_rs->get_attrib_def(target_depth_write);
  6965. DepthWriteAttrib::Mode mode = target_depth_write->get_mode();
  6966. if (mode == DepthWriteAttrib::M_off) {
  6967. #ifdef GSG_VERBOSE
  6968. GLCAT.spam()
  6969. << "glDepthMask(GL_FALSE)" << endl;
  6970. #endif
  6971. glDepthMask(GL_FALSE);
  6972. } else {
  6973. #ifdef GSG_VERBOSE
  6974. GLCAT.spam()
  6975. << "glDepthMask(GL_TRUE)" << endl;
  6976. #endif
  6977. glDepthMask(GL_TRUE);
  6978. }
  6979. report_my_gl_errors();
  6980. }
  6981. /**
  6982. *
  6983. */
  6984. void CLP(GraphicsStateGuardian)::
  6985. do_issue_cull_face() {
  6986. const CullFaceAttrib *target_cull_face;
  6987. _target_rs->get_attrib_def(target_cull_face);
  6988. CullFaceAttrib::Mode mode = target_cull_face->get_effective_mode();
  6989. switch (mode) {
  6990. case CullFaceAttrib::M_cull_none:
  6991. glDisable(GL_CULL_FACE);
  6992. break;
  6993. case CullFaceAttrib::M_cull_clockwise:
  6994. glEnable(GL_CULL_FACE);
  6995. glCullFace(GL_BACK);
  6996. break;
  6997. case CullFaceAttrib::M_cull_counter_clockwise:
  6998. glEnable(GL_CULL_FACE);
  6999. glCullFace(GL_FRONT);
  7000. break;
  7001. default:
  7002. GLCAT.error()
  7003. << "invalid cull face mode " << (int)mode << endl;
  7004. break;
  7005. }
  7006. report_my_gl_errors();
  7007. }
  7008. #ifdef SUPPORT_FIXED_FUNCTION
  7009. /**
  7010. *
  7011. */
  7012. void CLP(GraphicsStateGuardian)::
  7013. do_issue_fog() {
  7014. const FogAttrib *target_fog;
  7015. _target_rs->get_attrib_def(target_fog);
  7016. if (!target_fog->is_off()) {
  7017. enable_fog(true);
  7018. Fog *fog = target_fog->get_fog();
  7019. nassertv(fog != nullptr);
  7020. apply_fog(fog);
  7021. } else {
  7022. enable_fog(false);
  7023. }
  7024. report_my_gl_errors();
  7025. }
  7026. #endif // SUPPORT_FIXED_FUNCTION
  7027. /**
  7028. *
  7029. */
  7030. void CLP(GraphicsStateGuardian)::
  7031. do_issue_depth_offset() {
  7032. const DepthOffsetAttrib *target_depth_offset = (const DepthOffsetAttrib *)
  7033. _target_rs->get_attrib_def(DepthOffsetAttrib::get_class_slot());
  7034. int offset = target_depth_offset->get_offset();
  7035. if (offset != 0) {
  7036. // The relationship between these two parameters is a little unclear and
  7037. // poorly explained in the GL man pages.
  7038. glPolygonOffset((GLfloat) -offset, (GLfloat) -offset);
  7039. enable_polygon_offset(true);
  7040. } else {
  7041. enable_polygon_offset(false);
  7042. }
  7043. PN_stdfloat min_value = target_depth_offset->get_min_value();
  7044. PN_stdfloat max_value = target_depth_offset->get_max_value();
  7045. #ifdef GSG_VERBOSE
  7046. GLCAT.spam()
  7047. << "glDepthRange(" << min_value << ", " << max_value << ")" << endl;
  7048. #endif
  7049. #ifdef OPENGLES
  7050. // OpenGL ES uses a single-precision call.
  7051. glDepthRangef((GLclampf)min_value, (GLclampf)max_value);
  7052. #else
  7053. // Mainline OpenGL uses a double-precision call.
  7054. if (!_use_remapped_depth_range) {
  7055. glDepthRange((GLclampd)min_value, (GLclampd)max_value);
  7056. } else {
  7057. // If we have a remapped depth range, we should adjust the values to range
  7058. // from -1 to 1. We need to use an NV extension to pass unclamped values.
  7059. _glDepthRangedNV(min_value * 2.0 - 1.0, max_value * 2.0 - 1.0);
  7060. }
  7061. #endif // OPENGLES
  7062. report_my_gl_errors();
  7063. }
  7064. #ifdef SUPPORT_FIXED_FUNCTION
  7065. /**
  7066. *
  7067. */
  7068. void CLP(GraphicsStateGuardian)::
  7069. do_issue_material() {
  7070. static Material empty;
  7071. const Material *material;
  7072. const MaterialAttrib *target_material;
  7073. _target_rs->get_attrib_def(target_material);
  7074. if (target_material == nullptr ||
  7075. target_material->is_off()) {
  7076. material = &empty;
  7077. } else {
  7078. material = target_material->get_material();
  7079. }
  7080. bool has_material_force_color = _has_material_force_color;
  7081. #ifndef NDEBUG
  7082. if (_show_texture_usage) {
  7083. // In show_texture_usage mode, all colors are white, so as not to
  7084. // contaminate the texture color. This means we disable lighting
  7085. // materials too.
  7086. material = &empty;
  7087. has_material_force_color = false;
  7088. }
  7089. #endif // NDEBUG
  7090. #ifdef OPENGLES
  7091. const GLenum face = GL_FRONT_AND_BACK;
  7092. #else
  7093. GLenum face = material->get_twoside() ? GL_FRONT_AND_BACK : GL_FRONT;
  7094. #endif
  7095. call_glMaterialfv(face, GL_SPECULAR, material->get_specular());
  7096. call_glMaterialfv(face, GL_EMISSION, material->get_emission());
  7097. glMaterialf(face, GL_SHININESS, max(min(material->get_shininess(), (PN_stdfloat)128), (PN_stdfloat)0));
  7098. if ((material->has_ambient() && material->has_diffuse()) || material->has_base_color()) {
  7099. // The material has both an ambient and diffuse specified. This means we
  7100. // do not need glMaterialColor().
  7101. glDisable(GL_COLOR_MATERIAL);
  7102. call_glMaterialfv(face, GL_AMBIENT, material->get_ambient());
  7103. call_glMaterialfv(face, GL_DIFFUSE, material->get_diffuse());
  7104. } else if (material->has_ambient()) {
  7105. // The material specifies an ambient, but not a diffuse component. The
  7106. // diffuse component comes from the object's color.
  7107. if (has_material_force_color) {
  7108. glDisable(GL_COLOR_MATERIAL);
  7109. call_glMaterialfv(face, GL_DIFFUSE, _material_force_color);
  7110. } else {
  7111. #ifndef OPENGLES
  7112. glColorMaterial(face, GL_DIFFUSE);
  7113. #endif // OPENGLES
  7114. glEnable(GL_COLOR_MATERIAL);
  7115. }
  7116. call_glMaterialfv(face, GL_AMBIENT, material->get_ambient());
  7117. } else if (material->has_diffuse()) {
  7118. // The material specifies a diffuse, but not an ambient component. The
  7119. // ambient component comes from the object's color.
  7120. if (has_material_force_color) {
  7121. glDisable(GL_COLOR_MATERIAL);
  7122. call_glMaterialfv(face, GL_AMBIENT, _material_force_color);
  7123. } else {
  7124. #ifndef OPENGLES
  7125. glColorMaterial(face, GL_AMBIENT);
  7126. #endif // OPENGLES
  7127. glEnable(GL_COLOR_MATERIAL);
  7128. }
  7129. call_glMaterialfv(face, GL_DIFFUSE, material->get_diffuse());
  7130. } else {
  7131. // The material specifies neither a diffuse nor an ambient component.
  7132. // Both components come from the object's color.
  7133. if (has_material_force_color) {
  7134. glDisable(GL_COLOR_MATERIAL);
  7135. call_glMaterialfv(face, GL_AMBIENT, _material_force_color);
  7136. call_glMaterialfv(face, GL_DIFFUSE, _material_force_color);
  7137. } else {
  7138. #ifndef OPENGLES
  7139. glColorMaterial(face, GL_AMBIENT_AND_DIFFUSE);
  7140. #endif // OPENGLES
  7141. glEnable(GL_COLOR_MATERIAL);
  7142. }
  7143. }
  7144. #ifndef OPENGLES
  7145. glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, material->get_local());
  7146. glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, material->get_twoside());
  7147. if (_use_separate_specular_color) {
  7148. glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
  7149. } else {
  7150. glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
  7151. }
  7152. #endif
  7153. report_my_gl_errors();
  7154. }
  7155. #endif // SUPPORT_FIXED_FUNCTION
  7156. /**
  7157. * Issues the logic operation attribute to the GL.
  7158. */
  7159. #if !defined(OPENGLES) || defined(OPENGLES_1)
  7160. void CLP(GraphicsStateGuardian)::
  7161. do_issue_logic_op() {
  7162. const LogicOpAttrib *target_logic_op;
  7163. _target_rs->get_attrib_def(target_logic_op);
  7164. if (target_logic_op->get_operation() != LogicOpAttrib::O_none) {
  7165. glEnable(GL_COLOR_LOGIC_OP);
  7166. glLogicOp(GL_CLEAR - 1 + (int)target_logic_op->get_operation());
  7167. if (GLCAT.is_spam()) {
  7168. GLCAT.spam() << "glEnable(GL_COLOR_LOGIC_OP)\n";
  7169. GLCAT.spam() << "glLogicOp(" << target_logic_op->get_operation() << ")\n";
  7170. }
  7171. } else {
  7172. glDisable(GL_COLOR_LOGIC_OP);
  7173. glLogicOp(GL_COPY);
  7174. if (GLCAT.is_spam()) {
  7175. GLCAT.spam() << "glDisable(GL_COLOR_LOGIC_OP)\n";
  7176. }
  7177. }
  7178. }
  7179. #endif
  7180. /**
  7181. *
  7182. */
  7183. void CLP(GraphicsStateGuardian)::
  7184. do_issue_blending() {
  7185. // Handle the color_write attrib. If color_write is off, then all the other
  7186. // blending-related stuff doesn't matter. If the device doesn't support
  7187. // color-write, we use blending tricks to effectively disable color write.
  7188. const ColorWriteAttrib *target_color_write;
  7189. _target_rs->get_attrib_def(target_color_write);
  7190. unsigned int color_channels =
  7191. target_color_write->get_channels() & _color_write_mask;
  7192. #ifndef OPENGLES_1
  7193. if (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write)) {
  7194. color_channels &= ~(ColorWriteAttrib::C_alpha);
  7195. }
  7196. #endif
  7197. if (color_channels == ColorWriteAttrib::C_off) {
  7198. enable_multisample_alpha_one(false);
  7199. enable_multisample_alpha_mask(false);
  7200. if (gl_color_mask) {
  7201. enable_blend(false);
  7202. set_color_write_mask(ColorWriteAttrib::C_off);
  7203. } else {
  7204. enable_blend(true);
  7205. _glBlendEquation(GL_FUNC_ADD);
  7206. glBlendFunc(GL_ZERO, GL_ONE);
  7207. }
  7208. if (GLCAT.is_spam()) {
  7209. GLCAT.spam() << "glBlendEquation(GL_FUNC_ADD)\n";
  7210. GLCAT.spam() << "glBlendFunc(GL_ZERO, GL_ONE)\n";
  7211. }
  7212. return;
  7213. } else {
  7214. set_color_write_mask(color_channels);
  7215. }
  7216. const ColorBlendAttrib *target_color_blend;
  7217. _target_rs->get_attrib_def(target_color_blend);
  7218. CPT(ColorBlendAttrib) color_blend = target_color_blend;
  7219. ColorBlendAttrib::Mode color_blend_mode = target_color_blend->get_mode();
  7220. ColorBlendAttrib::Mode alpha_blend_mode = target_color_blend->get_alpha_mode();
  7221. const TransparencyAttrib *target_transparency;
  7222. _target_rs->get_attrib_def(target_transparency);
  7223. TransparencyAttrib::Mode transparency_mode = target_transparency->get_mode();
  7224. _color_blend_involves_color_scale = color_blend->involves_color_scale();
  7225. // Is there a color blend set?
  7226. if (color_blend_mode != ColorBlendAttrib::M_none) {
  7227. enable_multisample_alpha_one(false);
  7228. enable_multisample_alpha_mask(false);
  7229. enable_blend(true);
  7230. if (_supports_blend_equation_separate) {
  7231. _glBlendEquationSeparate(get_blend_equation_type(color_blend_mode),
  7232. get_blend_equation_type(alpha_blend_mode));
  7233. } else {
  7234. _glBlendEquation(get_blend_equation_type(color_blend_mode));
  7235. }
  7236. _glBlendFuncSeparate(get_blend_func(color_blend->get_operand_a()),
  7237. get_blend_func(color_blend->get_operand_b()),
  7238. get_blend_func(color_blend->get_alpha_operand_a()),
  7239. get_blend_func(color_blend->get_alpha_operand_b()));
  7240. #ifndef OPENGLES_1
  7241. LColor c;
  7242. if (_color_blend_involves_color_scale) {
  7243. // Apply the current color scale to the blend mode.
  7244. c = _current_color_scale;
  7245. } else {
  7246. c = color_blend->get_color();
  7247. }
  7248. _glBlendColor(c[0], c[1], c[2], c[3]);
  7249. #endif
  7250. if (GLCAT.is_spam()) {
  7251. if (_supports_blend_equation_separate) {
  7252. GLCAT.spam() << "glBlendEquationSeparate(" << color_blend_mode << ", "
  7253. << alpha_blend_mode << ")\n";
  7254. } else {
  7255. GLCAT.spam() << "glBlendEquation(" << color_blend_mode << ")\n";
  7256. }
  7257. GLCAT.spam() << "glBlendFuncSeparate("
  7258. << color_blend->get_operand_a() << ", "
  7259. << color_blend->get_operand_b() << ", "
  7260. << color_blend->get_alpha_operand_a() << ", "
  7261. << color_blend->get_alpha_operand_b() << ")\n";
  7262. #ifndef OPENGLES_1
  7263. GLCAT.spam() << "glBlendColor(" << c << ")\n";
  7264. #endif
  7265. }
  7266. return;
  7267. }
  7268. // No color blend; is there a transparency set?
  7269. switch (transparency_mode) {
  7270. case TransparencyAttrib::M_none:
  7271. case TransparencyAttrib::M_binary:
  7272. break;
  7273. case TransparencyAttrib::M_alpha:
  7274. case TransparencyAttrib::M_dual:
  7275. enable_multisample_alpha_one(false);
  7276. enable_multisample_alpha_mask(false);
  7277. enable_blend(true);
  7278. _glBlendEquation(GL_FUNC_ADD);
  7279. if (old_alpha_blend) {
  7280. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  7281. } else {
  7282. _glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  7283. }
  7284. if (GLCAT.is_spam()) {
  7285. GLCAT.spam() << "glBlendEquation(GL_FUNC_ADD)\n";
  7286. if (_supports_blend_equation_separate && !old_alpha_blend) {
  7287. GLCAT.spam() << "glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA)\n";
  7288. } else {
  7289. GLCAT.spam() << "glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)\n";
  7290. }
  7291. }
  7292. return;
  7293. case TransparencyAttrib::M_premultiplied_alpha:
  7294. enable_multisample_alpha_one(false);
  7295. enable_multisample_alpha_mask(false);
  7296. enable_blend(true);
  7297. _glBlendEquation(GL_FUNC_ADD);
  7298. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  7299. if (GLCAT.is_spam()) {
  7300. GLCAT.spam() << "glBlendEquation(GL_FUNC_ADD)\n";
  7301. GLCAT.spam() << "glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)\n";
  7302. }
  7303. return;
  7304. case TransparencyAttrib::M_multisample:
  7305. // We need to enable *both* of these in M_multisample case.
  7306. enable_multisample_alpha_one(true);
  7307. enable_multisample_alpha_mask(true);
  7308. enable_blend(false);
  7309. return;
  7310. case TransparencyAttrib::M_multisample_mask:
  7311. enable_multisample_alpha_one(false);
  7312. enable_multisample_alpha_mask(true);
  7313. enable_blend(false);
  7314. return;
  7315. default:
  7316. GLCAT.error()
  7317. << "invalid transparency mode " << (int)transparency_mode << endl;
  7318. break;
  7319. }
  7320. if (_line_smooth_enabled || _point_smooth_enabled) {
  7321. // If we have either of these turned on, we also need to have blend mode
  7322. // enabled in order to see it.
  7323. enable_multisample_alpha_one(false);
  7324. enable_multisample_alpha_mask(false);
  7325. enable_blend(true);
  7326. _glBlendEquation(GL_FUNC_ADD);
  7327. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  7328. if (GLCAT.is_spam()) {
  7329. GLCAT.spam() << "glBlendEquation(GL_FUNC_ADD)\n";
  7330. GLCAT.spam() << "glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)\n";
  7331. }
  7332. return;
  7333. }
  7334. /*
  7335. * For best polygon smoothing, we need: (1) a frame buffer that supports alpha
  7336. * (2) sort polygons front-to-back (3) glBlendFunc(GL_SRC_ALPHA_SATURATE,
  7337. * GL_ONE); Since these modes have other implications for the application, we
  7338. * don't attempt to do this by default. If you really want good polygon
  7339. * smoothing (and you don't have multisample support), do all this yourself.
  7340. */
  7341. // Nothing's set, so disable blending.
  7342. enable_multisample_alpha_one(false);
  7343. enable_multisample_alpha_mask(false);
  7344. enable_blend(false);
  7345. }
  7346. #ifdef SUPPORT_FIXED_FUNCTION
  7347. /**
  7348. * Called the first time a particular light has been bound to a given id
  7349. * within a frame, this should set up the associated hardware light with the
  7350. * light's properties.
  7351. */
  7352. void CLP(GraphicsStateGuardian)::
  7353. bind_light(PointLight *light_obj, const NodePath &light, int light_id) {
  7354. nassertv(has_fixed_function_pipeline());
  7355. // static PStatCollector
  7356. // _draw_set_state_light_bind_point_pcollector("Draw:Set
  7357. // State:Light:Bind:Point"); PStatGPUTimer timer(this,
  7358. // _draw_set_state_light_bind_point_pcollector);
  7359. GLenum id = get_light_id(light_id);
  7360. static const LColor black(0.0f, 0.0f, 0.0f, 1.0f);
  7361. call_glLightfv(id, GL_AMBIENT, black);
  7362. call_glLightfv(id, GL_DIFFUSE, get_light_color(light_obj));
  7363. call_glLightfv(id, GL_SPECULAR, light_obj->get_specular_color());
  7364. // Position needs to specify x, y, z, and w w == 1 implies non-infinite
  7365. // position
  7366. CPT(TransformState) transform = light.get_transform(_scene_setup->get_scene_root().get_parent());
  7367. LPoint3 pos = light_obj->get_point() * transform->get_mat();
  7368. LPoint4 fpos(pos[0], pos[1], pos[2], 1.0f);
  7369. call_glLightfv(id, GL_POSITION, fpos);
  7370. // GL_SPOT_DIRECTION is not significant when cutoff == 180
  7371. // Exponent == 0 implies uniform light distribution
  7372. glLightf(id, GL_SPOT_EXPONENT, 0.0f);
  7373. // Cutoff == 180 means uniform point light source
  7374. glLightf(id, GL_SPOT_CUTOFF, 180.0f);
  7375. const LVecBase3 &att = light_obj->get_attenuation();
  7376. glLightf(id, GL_CONSTANT_ATTENUATION, att[0]);
  7377. glLightf(id, GL_LINEAR_ATTENUATION, att[1]);
  7378. glLightf(id, GL_QUADRATIC_ATTENUATION, att[2]);
  7379. report_my_gl_errors();
  7380. }
  7381. #endif // SUPPORT_FIXED_FUNCTION
  7382. #ifdef SUPPORT_FIXED_FUNCTION
  7383. /**
  7384. * Called the first time a particular light has been bound to a given id
  7385. * within a frame, this should set up the associated hardware light with the
  7386. * light's properties.
  7387. */
  7388. void CLP(GraphicsStateGuardian)::
  7389. bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) {
  7390. nassertv(has_fixed_function_pipeline());
  7391. // static PStatCollector
  7392. // _draw_set_state_light_bind_directional_pcollector("Draw:Set
  7393. // State:Light:Bind:Directional"); PStatGPUTimer timer(this,
  7394. // _draw_set_state_light_bind_directional_pcollector);
  7395. std::pair<DirectionalLights::iterator, bool> lookup = _dlights.insert(DirectionalLights::value_type(light, DirectionalLightFrameData()));
  7396. DirectionalLightFrameData &fdata = (*lookup.first).second;
  7397. if (lookup.second) {
  7398. // The light was not computed yet this frame. Compute it now.
  7399. CPT(TransformState) transform = light.get_transform(_scene_setup->get_scene_root().get_parent());
  7400. LVector3 dir = light_obj->get_direction() * transform->get_mat();
  7401. fdata._neg_dir.set(-dir[0], -dir[1], -dir[2], 0);
  7402. }
  7403. GLenum id = get_light_id( light_id );
  7404. static const LColor black(0.0f, 0.0f, 0.0f, 1.0f);
  7405. call_glLightfv(id, GL_AMBIENT, black);
  7406. call_glLightfv(id, GL_DIFFUSE, get_light_color(light_obj));
  7407. call_glLightfv(id, GL_SPECULAR, light_obj->get_specular_color());
  7408. // Position needs to specify x, y, z, and w. w == 0 implies light is at
  7409. // infinity
  7410. call_glLightfv(id, GL_POSITION, fdata._neg_dir);
  7411. // GL_SPOT_DIRECTION is not significant when cutoff == 180 In this case,
  7412. // position x, y, z specifies direction
  7413. // Exponent == 0 implies uniform light distribution
  7414. glLightf(id, GL_SPOT_EXPONENT, 0.0f);
  7415. // Cutoff == 180 means uniform point light source
  7416. glLightf(id, GL_SPOT_CUTOFF, 180.0f);
  7417. // Default attenuation values (only spotlight and point light can modify
  7418. // these)
  7419. glLightf(id, GL_CONSTANT_ATTENUATION, 1.0f);
  7420. glLightf(id, GL_LINEAR_ATTENUATION, 0.0f);
  7421. glLightf(id, GL_QUADRATIC_ATTENUATION, 0.0f);
  7422. report_my_gl_errors();
  7423. }
  7424. #endif // SUPPORT_FIXED_FUNCTION
  7425. #ifdef SUPPORT_FIXED_FUNCTION
  7426. /**
  7427. * Called the first time a particular light has been bound to a given id
  7428. * within a frame, this should set up the associated hardware light with the
  7429. * light's properties.
  7430. */
  7431. void CLP(GraphicsStateGuardian)::
  7432. bind_light(Spotlight *light_obj, const NodePath &light, int light_id) {
  7433. nassertv(has_fixed_function_pipeline());
  7434. // static PStatCollector
  7435. // _draw_set_state_light_bind_spotlight_pcollector("Draw:Set
  7436. // State:Light:Bind:Spotlight"); PStatGPUTimer timer(this,
  7437. // _draw_set_state_light_bind_spotlight_pcollector);
  7438. Lens *lens = light_obj->get_lens();
  7439. nassertv(lens != nullptr);
  7440. GLenum id = get_light_id(light_id);
  7441. static const LColor black(0.0f, 0.0f, 0.0f, 1.0f);
  7442. call_glLightfv(id, GL_AMBIENT, black);
  7443. call_glLightfv(id, GL_DIFFUSE, get_light_color(light_obj));
  7444. call_glLightfv(id, GL_SPECULAR, light_obj->get_specular_color());
  7445. // Position needs to specify x, y, z, and w w == 1 implies non-infinite
  7446. // position
  7447. CPT(TransformState) transform = light.get_transform(_scene_setup->get_scene_root().get_parent());
  7448. const LMatrix4 &light_mat = transform->get_mat();
  7449. LPoint3 pos = lens->get_nodal_point() * light_mat;
  7450. LVector3 dir = lens->get_view_vector() * light_mat;
  7451. LPoint4 fpos(pos[0], pos[1], pos[2], 1.0f);
  7452. call_glLightfv(id, GL_POSITION, fpos);
  7453. call_glLightfv(id, GL_SPOT_DIRECTION, dir);
  7454. glLightf(id, GL_SPOT_EXPONENT, max(min(light_obj->get_exponent(), (PN_stdfloat)128), (PN_stdfloat)0));
  7455. glLightf(id, GL_SPOT_CUTOFF, lens->get_hfov() * 0.5f);
  7456. const LVecBase3 &att = light_obj->get_attenuation();
  7457. glLightf(id, GL_CONSTANT_ATTENUATION, att[0]);
  7458. glLightf(id, GL_LINEAR_ATTENUATION, att[1]);
  7459. glLightf(id, GL_QUADRATIC_ATTENUATION, att[2]);
  7460. report_my_gl_errors();
  7461. }
  7462. #endif // SUPPORT_FIXED_FUNCTION
  7463. /**
  7464. * Creates a depth buffer for shadow mapping. A derived GSG can override this
  7465. * if it knows that a particular buffer type works best for shadow rendering.
  7466. */
  7467. GraphicsOutput *CLP(GraphicsStateGuardian)::
  7468. make_shadow_buffer(LightLensNode *light, Texture *tex, GraphicsOutput *host) {
  7469. // We override this to circumvent the fact that GraphicsEngine::make_output
  7470. // can only be called from the app thread.
  7471. if (!_supports_framebuffer_object) {
  7472. return GraphicsStateGuardian::make_shadow_buffer(light, tex, host);
  7473. }
  7474. bool is_point = light->is_of_type(PointLight::get_class_type());
  7475. // Determine the properties for creating the depth buffer.
  7476. FrameBufferProperties fbp;
  7477. fbp.set_depth_bits(shadow_depth_bits);
  7478. WindowProperties props = WindowProperties::size(light->get_shadow_buffer_size());
  7479. int flags = GraphicsPipe::BF_refuse_window;
  7480. if (is_point) {
  7481. flags |= GraphicsPipe::BF_size_square;
  7482. }
  7483. if (host != nullptr) {
  7484. host = host->get_host();
  7485. }
  7486. CLP(GraphicsBuffer) *sbuffer = new CLP(GraphicsBuffer)(get_engine(), get_pipe(), light->get_name(), fbp, props, flags, this, host);
  7487. sbuffer->add_render_texture(tex, GraphicsOutput::RTM_bind_or_copy, GraphicsOutput::RTP_depth);
  7488. get_engine()->add_window(sbuffer, light->get_shadow_buffer_sort());
  7489. return sbuffer;
  7490. }
  7491. #ifdef SUPPORT_IMMEDIATE_MODE
  7492. /**
  7493. * Uses the ImmediateModeSender to draw a series of primitives of the
  7494. * indicated type.
  7495. */
  7496. void CLP(GraphicsStateGuardian)::
  7497. draw_immediate_simple_primitives(const GeomPrimitivePipelineReader *reader, GLenum mode) {
  7498. int num_vertices = reader->get_num_vertices();
  7499. _vertices_immediate_pcollector.add_level(num_vertices);
  7500. glBegin(mode);
  7501. if (reader->is_indexed()) {
  7502. for (int v = 0; v < num_vertices; ++v) {
  7503. _sender.set_vertex(reader->get_vertex(v));
  7504. _sender.issue_vertex();
  7505. }
  7506. } else {
  7507. _sender.set_vertex(reader->get_first_vertex());
  7508. for (int v = 0; v < num_vertices; ++v) {
  7509. _sender.issue_vertex();
  7510. }
  7511. }
  7512. glEnd();
  7513. }
  7514. #endif // SUPPORT_IMMEDIATE_MODE
  7515. #ifdef SUPPORT_IMMEDIATE_MODE
  7516. /**
  7517. * Uses the ImmediateModeSender to draw a series of primitives of the
  7518. * indicated type. This form is for primitive types like tristrips which must
  7519. * involve several begin/end groups.
  7520. */
  7521. void CLP(GraphicsStateGuardian)::
  7522. draw_immediate_composite_primitives(const GeomPrimitivePipelineReader *reader, GLenum mode) {
  7523. int num_vertices = reader->get_num_vertices();
  7524. _vertices_immediate_pcollector.add_level(num_vertices);
  7525. CPTA_int ends = reader->get_ends();
  7526. int num_unused_vertices_per_primitive = reader->get_object()->get_num_unused_vertices_per_primitive();
  7527. if (reader->is_indexed()) {
  7528. int begin = 0;
  7529. CPTA_int::const_iterator ei;
  7530. for (ei = ends.begin(); ei != ends.end(); ++ei) {
  7531. int end = (*ei);
  7532. glBegin(mode);
  7533. for (int v = begin; v < end; ++v) {
  7534. _sender.set_vertex(reader->get_vertex(v));
  7535. _sender.issue_vertex();
  7536. }
  7537. glEnd();
  7538. begin = end + num_unused_vertices_per_primitive;
  7539. }
  7540. } else {
  7541. _sender.set_vertex(reader->get_first_vertex());
  7542. int begin = 0;
  7543. CPTA_int::const_iterator ei;
  7544. for (ei = ends.begin(); ei != ends.end(); ++ei) {
  7545. int end = (*ei);
  7546. glBegin(mode);
  7547. for (int v = begin; v < end; ++v) {
  7548. _sender.issue_vertex();
  7549. }
  7550. glEnd();
  7551. begin = end + num_unused_vertices_per_primitive;
  7552. }
  7553. }
  7554. }
  7555. #endif // SUPPORT_IMMEDIATE_MODE
  7556. /**
  7557. * Calls glFlush().
  7558. */
  7559. void CLP(GraphicsStateGuardian)::
  7560. gl_flush() const {
  7561. PStatTimer timer(_flush_pcollector);
  7562. glFlush();
  7563. }
  7564. /**
  7565. * Returns the result of glGetError().
  7566. */
  7567. GLenum CLP(GraphicsStateGuardian)::
  7568. gl_get_error() const {
  7569. if (_check_errors) {
  7570. PStatTimer timer(_check_error_pcollector);
  7571. return glGetError();
  7572. } else {
  7573. return GL_NO_ERROR;
  7574. }
  7575. }
  7576. /**
  7577. * The internal implementation of report_errors(). Don't call this function;
  7578. * use report_errors() instead. The return value is true if everything is ok,
  7579. * or false if we should shut down.
  7580. */
  7581. bool CLP(GraphicsStateGuardian)::
  7582. report_errors_loop(int line, const char *source_file, GLenum error_code,
  7583. int &error_count) {
  7584. while ((gl_max_errors < 0 || error_count < gl_max_errors) &&
  7585. (error_code != GL_NO_ERROR)) {
  7586. GLCAT.error()
  7587. << "at " << line << " of " << source_file << " : "
  7588. << get_error_string(error_code) << "\n";
  7589. error_code = glGetError();
  7590. error_count++;
  7591. }
  7592. return (error_code == GL_NO_ERROR);
  7593. }
  7594. /**
  7595. * Returns an error string for an OpenGL error code.
  7596. */
  7597. string CLP(GraphicsStateGuardian)::
  7598. get_error_string(GLenum error_code) {
  7599. // We used to use gluErrorString here, but I (rdb) took it out because that
  7600. // was really the only function we used from GLU. The idea with the error
  7601. // table was taken from SGI's sample implementation.
  7602. static const char *error_strings[] = {
  7603. "invalid enumerant",
  7604. "invalid value",
  7605. "invalid operation",
  7606. "stack overflow",
  7607. "stack underflow",
  7608. "out of memory",
  7609. "invalid framebuffer operation",
  7610. "context lost",
  7611. };
  7612. if (error_code == GL_NO_ERROR) {
  7613. return "no error";
  7614. #ifndef OPENGLES
  7615. } else if (error_code == GL_TABLE_TOO_LARGE) {
  7616. return "table too large";
  7617. #endif
  7618. } else if (error_code >= 0x0500 && error_code <= 0x0507) {
  7619. return error_strings[error_code - 0x0500];
  7620. }
  7621. // Other error, somehow? Just display the error code then.
  7622. std::ostringstream strm;
  7623. strm << "GL error " << (int)error_code;
  7624. return strm.str();
  7625. }
  7626. /**
  7627. * Outputs the result of glGetString() on the indicated tag. The output
  7628. * string is returned.
  7629. */
  7630. string CLP(GraphicsStateGuardian)::
  7631. show_gl_string(const string &name, GLenum id) {
  7632. string result;
  7633. const GLubyte *text = glGetString(id);
  7634. if (text == nullptr) {
  7635. GLCAT.warning()
  7636. << "Unable to query " << name << "\n";
  7637. } else {
  7638. result = (const char *)text;
  7639. if (GLCAT.is_debug()) {
  7640. GLCAT.debug()
  7641. << name << " = " << result << "\n";
  7642. }
  7643. }
  7644. return result;
  7645. }
  7646. /**
  7647. * Queries the runtime version of OpenGL in use.
  7648. */
  7649. void CLP(GraphicsStateGuardian)::
  7650. query_gl_version() {
  7651. _gl_vendor = show_gl_string("GL_VENDOR", GL_VENDOR);
  7652. _gl_renderer = show_gl_string("GL_RENDERER", GL_RENDERER);
  7653. _gl_version = show_gl_string("GL_VERSION", GL_VERSION);
  7654. _gl_version_major = 0;
  7655. _gl_version_minor = 0;
  7656. // This is the most preposterous driver bug: NVIDIA drivers will claim
  7657. // that the version is 1.2 as long as the process is named pview.exe!
  7658. #ifndef OPENGLES
  7659. if (_gl_version.substr(0, 10) == "1.2 NVIDIA") {
  7660. Filename exec_name = ExecutionEnvironment::get_binary_name();
  7661. if (cmp_nocase(exec_name.get_basename(), "pview.exe") == 0) {
  7662. glGetIntegerv(GL_MAJOR_VERSION, &_gl_version_major);
  7663. glGetIntegerv(GL_MINOR_VERSION, &_gl_version_minor);
  7664. if (glGetError() == GL_INVALID_ENUM) {
  7665. _gl_version_major = 1;
  7666. _gl_version_minor = 2;
  7667. GLCAT.warning()
  7668. << "Driver possibly misreported GL_VERSION! Unable to detect "
  7669. "correct OpenGL version.\n";
  7670. } else if (_gl_version_major != 1 || _gl_version_minor != 2) {
  7671. GLCAT.debug()
  7672. << "Driver misreported GL_VERSION! Correct version detected as "
  7673. << _gl_version_major << "." << _gl_version_minor << "\n";
  7674. }
  7675. return;
  7676. }
  7677. }
  7678. // If we asked for a GL 3 context, let's first try and see if we can use the
  7679. // OpenGL 3 way to query version.
  7680. if (gl_version.get_num_words() > 0 && gl_version[0] >= 3) {
  7681. glGetIntegerv(GL_MAJOR_VERSION, &_gl_version_major);
  7682. glGetIntegerv(GL_MINOR_VERSION, &_gl_version_minor);
  7683. if (_gl_version_major >= 1) {
  7684. // Fair enough, seems to check out.
  7685. if (GLCAT.is_debug()) {
  7686. GLCAT.debug()
  7687. << "Detected OpenGL version: "
  7688. << _gl_version_major << "." << _gl_version_minor << "\n";
  7689. }
  7690. return;
  7691. }
  7692. }
  7693. #endif // !OPENGLES
  7694. // Otherwise, parse the GL_VERSION string.
  7695. if (_gl_version.empty()) {
  7696. GLCAT.error() << "Unable to detect OpenGL version\n";
  7697. } else {
  7698. string input = _gl_version;
  7699. // Skip any initial words that don't begin with a digit.
  7700. while (!input.empty() && !isdigit(input[0])) {
  7701. size_t space = input.find(' ');
  7702. if (space == string::npos) {
  7703. break;
  7704. }
  7705. size_t next = space + 1;
  7706. while (next < input.length() && isspace(input[next])) {
  7707. ++next;
  7708. }
  7709. input = input.substr(next);
  7710. }
  7711. // Truncate after the first space.
  7712. size_t space = input.find(' ');
  7713. if (space != string::npos) {
  7714. input = input.substr(0, space);
  7715. }
  7716. vector_string components;
  7717. tokenize(input, components, ".");
  7718. if (components.size() >= 1) {
  7719. string_to_int(components[0], _gl_version_major);
  7720. }
  7721. if (components.size() >= 2) {
  7722. string_to_int(components[1], _gl_version_minor);
  7723. }
  7724. if (GLCAT.is_debug()) {
  7725. GLCAT.debug()
  7726. << "GL_VERSION decoded to: "
  7727. << _gl_version_major << "." << _gl_version_minor
  7728. << "\n";
  7729. }
  7730. }
  7731. }
  7732. /**
  7733. * Queries the supported GLSL version.
  7734. */
  7735. void CLP(GraphicsStateGuardian)::
  7736. query_glsl_version() {
  7737. _gl_shadlang_ver_major = 0;
  7738. _gl_shadlang_ver_minor = 0;
  7739. #ifndef OPENGLES_1
  7740. #ifndef OPENGLES
  7741. // OpenGL 2.0 introduces GLSL in the core. In 1.x, it is an extension.
  7742. if (_gl_version_major >= 2 || has_extension("GL_ARB_shading_language_100")) {
  7743. string ver = show_gl_string("GL_SHADING_LANGUAGE_VERSION", GL_SHADING_LANGUAGE_VERSION);
  7744. _gl_shadlang_ver_major = 1;
  7745. _gl_shadlang_ver_minor = (_gl_version_major >= 2) ? 1 : 0;
  7746. if (ver.empty() ||
  7747. sscanf(ver.c_str(), "%d.%d", &_gl_shadlang_ver_major,
  7748. &_gl_shadlang_ver_minor) != 2) {
  7749. GLCAT.warning() << "Invalid GL_SHADING_LANGUAGE_VERSION format.\n";
  7750. }
  7751. }
  7752. #else
  7753. // OpenGL ES 2.0 and above has shader support built-in.
  7754. string ver = show_gl_string("GL_SHADING_LANGUAGE_VERSION", GL_SHADING_LANGUAGE_VERSION);
  7755. _gl_shadlang_ver_major = 1;
  7756. _gl_shadlang_ver_minor = 0;
  7757. if (ver.empty() ||
  7758. sscanf(ver.c_str(), "OpenGL ES GLSL ES %d.%d", &_gl_shadlang_ver_major,
  7759. &_gl_shadlang_ver_minor) != 2) {
  7760. GLCAT.warning() << "Invalid GL_SHADING_LANGUAGE_VERSION format.\n";
  7761. }
  7762. #endif
  7763. if (GLCAT.is_debug()) {
  7764. GLCAT.debug()
  7765. << "Detected GLSL "
  7766. #ifdef OPENGLES
  7767. "ES "
  7768. #endif
  7769. "version: "
  7770. << _gl_shadlang_ver_major << "." << _gl_shadlang_ver_minor << "\n";
  7771. }
  7772. #endif // !OPENGLES_1
  7773. }
  7774. /**
  7775. * Separates the string returned by GL_EXTENSIONS (or glx or wgl extensions)
  7776. * into its individual tokens and saves them in the _extensions member.
  7777. */
  7778. void CLP(GraphicsStateGuardian)::
  7779. save_extensions(const char *extensions) {
  7780. if (extensions != nullptr) {
  7781. vector_string tokens;
  7782. extract_words(extensions, tokens);
  7783. vector_string::iterator ti;
  7784. for (ti = tokens.begin(); ti != tokens.end(); ++ti) {
  7785. _extensions.insert(*ti);
  7786. }
  7787. }
  7788. }
  7789. /**
  7790. * This may be redefined by a derived class (e.g. glx or wgl) to get whatever
  7791. * further extensions strings may be appropriate to that interface, in
  7792. * addition to the GL extension strings return by glGetString().
  7793. */
  7794. void CLP(GraphicsStateGuardian)::
  7795. get_extra_extensions() {
  7796. }
  7797. /**
  7798. * Outputs the list of GL extensions to notify, if debug mode is enabled.
  7799. */
  7800. void CLP(GraphicsStateGuardian)::
  7801. report_extensions() const {
  7802. if (GLCAT.is_debug()) {
  7803. std::ostream &out = GLCAT.debug();
  7804. out << "GL Extensions:\n";
  7805. pset<string>::const_iterator ei;
  7806. for (ei = _extensions.begin(); ei != _extensions.end(); ++ei) {
  7807. size_t len = (*ei).size();
  7808. out << " " << (*ei);
  7809. // Display a second column.
  7810. if (len <= 38) {
  7811. if (++ei != _extensions.end()) {
  7812. for (int i = len; i < 38; ++i) {
  7813. out.put(' ');
  7814. }
  7815. out << ' ' << (*ei);
  7816. } else {
  7817. out.put('\n');
  7818. break;
  7819. }
  7820. }
  7821. out.put('\n');
  7822. }
  7823. }
  7824. }
  7825. /**
  7826. * Returns the pointer to the GL extension function with the indicated name,
  7827. * or NULL if the function is not available.
  7828. */
  7829. void *CLP(GraphicsStateGuardian)::
  7830. get_extension_func(const char *name) {
  7831. // First, look in the static-compiled namespace. If we were compiled to
  7832. // expect at least a certain minimum runtime version of OpenGL, then we can
  7833. // expect those extension functions to be available at compile time.
  7834. // Somewhat more reliable than poking around in the runtime pointers.
  7835. static struct {
  7836. const char *name;
  7837. void *fptr;
  7838. } compiled_function_table[] = {
  7839. #ifdef EXPECT_GL_VERSION_1_2
  7840. { "glBlendColor", (void *)&glBlendColor },
  7841. { "glBlendEquation", (void *)&glBlendEquation },
  7842. { "glDrawRangeElements", (void *)&glDrawRangeElements },
  7843. { "glTexImage3D", (void *)&glTexImage3D },
  7844. { "glTexSubImage3D", (void *)&glTexSubImage3D },
  7845. { "glCopyTexSubImage3D", (void *)&glCopyTexSubImage3D },
  7846. #endif
  7847. #ifdef EXPECT_GL_VERSION_1_3
  7848. { "glActiveTexture", (void *)&glActiveTexture },
  7849. { "glClientActiveTexture", (void *)&glClientActiveTexture },
  7850. { "glCompressedTexImage1D", (void *)&glCompressedTexImage1D },
  7851. { "glCompressedTexImage2D", (void *)&glCompressedTexImage2D },
  7852. { "glCompressedTexImage3D", (void *)&glCompressedTexImage3D },
  7853. { "glCompressedTexSubImage1D", (void *)&glCompressedTexSubImage1D },
  7854. { "glCompressedTexSubImage2D", (void *)&glCompressedTexSubImage2D },
  7855. { "glCompressedTexSubImage3D", (void *)&glCompressedTexSubImage3D },
  7856. { "glGetCompressedTexImage", (void *)&glGetCompressedTexImage },
  7857. { "glMultiTexCoord1f", (void *)&glMultiTexCoord1f },
  7858. { "glMultiTexCoord2", (void *)&glMultiTexCoord2 },
  7859. { "glMultiTexCoord3", (void *)&glMultiTexCoord3 },
  7860. { "glMultiTexCoord4", (void *)&glMultiTexCoord4 },
  7861. #endif
  7862. #ifdef EXPECT_GL_VERSION_1_4
  7863. { "glPointParameterfv", (void *)&glPointParameterfv },
  7864. { "glSecondaryColorPointer", (void *)&glSecondaryColorPointer },
  7865. #endif
  7866. #ifdef EXPECT_GL_VERSION_1_5
  7867. { "glBeginQuery", (void *)&glBeginQuery },
  7868. { "glBindBuffer", (void *)&glBindBuffer },
  7869. { "glBufferData", (void *)&glBufferData },
  7870. { "glBufferSubData", (void *)&glBufferSubData },
  7871. { "glDeleteBuffers", (void *)&glDeleteBuffers },
  7872. { "glDeleteQueries", (void *)&glDeleteQueries },
  7873. { "glEndQuery", (void *)&glEndQuery },
  7874. { "glGenBuffers", (void *)&glGenBuffers },
  7875. { "glGenQueries", (void *)&glGenQueries },
  7876. { "glGetQueryObjectuiv", (void *)&glGetQueryObjectuiv },
  7877. { "glGetQueryiv", (void *)&glGetQueryiv },
  7878. #endif
  7879. #ifdef OPENGLES
  7880. { "glActiveTexture", (void *)&glActiveTexture },
  7881. #ifndef OPENGLES_2
  7882. { "glClientActiveTexture", (void *)&glClientActiveTexture },
  7883. #endif
  7884. { "glBindBuffer", (void *)&glBindBuffer },
  7885. { "glBufferData", (void *)&glBufferData },
  7886. { "glBufferSubData", (void *)&glBufferSubData },
  7887. { "glDeleteBuffers", (void *)&glDeleteBuffers },
  7888. { "glGenBuffers", (void *)&glGenBuffers },
  7889. #endif
  7890. { nullptr, nullptr }
  7891. };
  7892. int i = 0;
  7893. while (compiled_function_table[i].name != nullptr) {
  7894. if (strcmp(compiled_function_table[i].name, name) == 0) {
  7895. return compiled_function_table[i].fptr;
  7896. }
  7897. ++i;
  7898. }
  7899. // If the extension function wasn't compiled in, then go get it from the
  7900. // runtime. There's a different interface for each API.
  7901. return do_get_extension_func(name);
  7902. }
  7903. /**
  7904. * This is the virtual implementation of get_extension_func(). Each API-
  7905. * specific GL implementation will map this method to the appropriate API call
  7906. * to retrieve the extension function pointer. Returns NULL if the function
  7907. * is not available.
  7908. */
  7909. void *CLP(GraphicsStateGuardian)::
  7910. do_get_extension_func(const char *) {
  7911. return nullptr;
  7912. }
  7913. /**
  7914. * Sets up the glDrawBuffer to render into the buffer indicated by the
  7915. * RenderBuffer object. This only sets up the color and aux bits; it does not
  7916. * affect the depth, stencil, accum layers.
  7917. */
  7918. void CLP(GraphicsStateGuardian)::
  7919. set_draw_buffer(int rbtype) {
  7920. #ifndef OPENGLES_1 // Draw buffers not supported by OpenGL ES 1.
  7921. if (_current_fbo) {
  7922. GLuint buffers[16];
  7923. int nbuffers = 0;
  7924. int index = 0;
  7925. if (_current_properties->get_color_bits() > 0) {
  7926. if (rbtype & RenderBuffer::T_left) {
  7927. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index;
  7928. }
  7929. ++index;
  7930. if (_current_properties->is_stereo()) {
  7931. if (rbtype & RenderBuffer::T_right) {
  7932. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index;
  7933. }
  7934. ++index;
  7935. }
  7936. }
  7937. for (int i = 0; i < _current_properties->get_aux_rgba(); ++i) {
  7938. if (rbtype & (RenderBuffer::T_aux_rgba_0 << i)) {
  7939. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index;
  7940. }
  7941. ++index;
  7942. }
  7943. for (int i = 0; i < _current_properties->get_aux_hrgba(); ++i) {
  7944. if (rbtype & (RenderBuffer::T_aux_hrgba_0 << i)) {
  7945. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index;
  7946. }
  7947. ++index;
  7948. }
  7949. for (int i = 0; i < _current_properties->get_aux_float(); ++i) {
  7950. if (rbtype & (RenderBuffer::T_aux_float_0 << i)) {
  7951. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index;
  7952. }
  7953. ++index;
  7954. }
  7955. if (_glDrawBuffers != nullptr) {
  7956. _glDrawBuffers(nbuffers, buffers);
  7957. } else {
  7958. nassertv(nbuffers == 1 && buffers[0] == GL_COLOR_ATTACHMENT0_EXT);
  7959. }
  7960. } else {
  7961. #ifndef OPENGLES
  7962. switch (rbtype & RenderBuffer::T_color) {
  7963. case RenderBuffer::T_front:
  7964. glDrawBuffer(GL_FRONT);
  7965. break;
  7966. case RenderBuffer::T_back:
  7967. glDrawBuffer(GL_BACK);
  7968. break;
  7969. case RenderBuffer::T_right:
  7970. glDrawBuffer(GL_RIGHT);
  7971. break;
  7972. case RenderBuffer::T_left:
  7973. glDrawBuffer(GL_LEFT);
  7974. break;
  7975. case RenderBuffer::T_front_right:
  7976. nassertv(_current_properties->is_stereo());
  7977. glDrawBuffer(GL_FRONT_RIGHT);
  7978. break;
  7979. case RenderBuffer::T_front_left:
  7980. nassertv(_current_properties->is_stereo());
  7981. glDrawBuffer(GL_FRONT_LEFT);
  7982. break;
  7983. case RenderBuffer::T_back_right:
  7984. nassertv(_current_properties->is_stereo());
  7985. glDrawBuffer(GL_BACK_RIGHT);
  7986. break;
  7987. case RenderBuffer::T_back_left:
  7988. nassertv(_current_properties->is_stereo());
  7989. glDrawBuffer(GL_BACK_LEFT);
  7990. break;
  7991. default:
  7992. break;
  7993. }
  7994. #endif // OPENGLES
  7995. }
  7996. #endif // OPENGLES_1
  7997. // Also ensure that any global color channels are masked out.
  7998. set_color_write_mask(_color_write_mask);
  7999. report_my_gl_errors();
  8000. }
  8001. /**
  8002. * Sets up the glReadBuffer to render into the buffer indicated by the
  8003. * RenderBuffer object. This only sets up the color bits; it does not affect
  8004. * the depth, stencil, accum layers.
  8005. */
  8006. void CLP(GraphicsStateGuardian)::
  8007. set_read_buffer(int rbtype) {
  8008. #ifndef OPENGLES_1 // Draw buffers not supported by OpenGL ES 1.
  8009. if (rbtype & (RenderBuffer::T_depth | RenderBuffer::T_stencil)) {
  8010. // Special case: don't have to call ReadBuffer for these.
  8011. return;
  8012. }
  8013. if (_current_fbo) {
  8014. GLuint buffer = GL_COLOR_ATTACHMENT0_EXT;
  8015. int index = 1;
  8016. if (_current_properties->is_stereo()) {
  8017. if (rbtype & RenderBuffer::T_right) {
  8018. buffer = GL_COLOR_ATTACHMENT1_EXT;
  8019. }
  8020. ++index;
  8021. }
  8022. for (int i = 0; i < _current_properties->get_aux_rgba(); ++i) {
  8023. if (rbtype & (RenderBuffer::T_aux_rgba_0 << i)) {
  8024. buffer = GL_COLOR_ATTACHMENT0_EXT + index;
  8025. }
  8026. ++index;
  8027. }
  8028. for (int i = 0; i < _current_properties->get_aux_hrgba(); ++i) {
  8029. if (rbtype & (RenderBuffer::T_aux_hrgba_0 << i)) {
  8030. buffer = GL_COLOR_ATTACHMENT0_EXT + index;
  8031. }
  8032. ++index;
  8033. }
  8034. for (int i = 0; i < _current_properties->get_aux_float(); ++i) {
  8035. if (rbtype & (RenderBuffer::T_aux_float_0 << i)) {
  8036. buffer = GL_COLOR_ATTACHMENT0_EXT + index;
  8037. }
  8038. ++index;
  8039. }
  8040. #ifdef OPENGLES
  8041. _glReadBuffer(buffer);
  8042. #else
  8043. glReadBuffer(buffer);
  8044. #endif
  8045. } else {
  8046. #ifndef OPENGLES
  8047. switch (rbtype & RenderBuffer::T_color) {
  8048. case RenderBuffer::T_front:
  8049. glReadBuffer(GL_FRONT);
  8050. break;
  8051. case RenderBuffer::T_back:
  8052. glReadBuffer(GL_BACK);
  8053. break;
  8054. case RenderBuffer::T_right:
  8055. glReadBuffer(GL_RIGHT);
  8056. break;
  8057. case RenderBuffer::T_left:
  8058. glReadBuffer(GL_LEFT);
  8059. break;
  8060. case RenderBuffer::T_front_right:
  8061. glReadBuffer(GL_FRONT_RIGHT);
  8062. break;
  8063. case RenderBuffer::T_front_left:
  8064. glReadBuffer(GL_FRONT_LEFT);
  8065. break;
  8066. case RenderBuffer::T_back_right:
  8067. glReadBuffer(GL_BACK_RIGHT);
  8068. break;
  8069. case RenderBuffer::T_back_left:
  8070. glReadBuffer(GL_BACK_LEFT);
  8071. break;
  8072. default:
  8073. break;
  8074. }
  8075. #endif // OPENGLES
  8076. }
  8077. report_my_gl_errors();
  8078. #endif // OPENGLES_1
  8079. }
  8080. /**
  8081. * Maps from the Geom's internal numeric type symbols to GL's.
  8082. */
  8083. GLenum CLP(GraphicsStateGuardian)::
  8084. get_numeric_type(Geom::NumericType numeric_type) {
  8085. switch (numeric_type) {
  8086. case Geom::NT_uint16:
  8087. return GL_UNSIGNED_SHORT;
  8088. case Geom::NT_uint32:
  8089. #ifndef OPENGLES_1
  8090. return GL_UNSIGNED_INT;
  8091. #else
  8092. break;
  8093. #endif
  8094. case Geom::NT_uint8:
  8095. case Geom::NT_packed_dcba:
  8096. case Geom::NT_packed_dabc:
  8097. return GL_UNSIGNED_BYTE;
  8098. case Geom::NT_float32:
  8099. return GL_FLOAT;
  8100. case Geom::NT_float64:
  8101. #ifndef OPENGLES
  8102. return GL_DOUBLE;
  8103. #else
  8104. break;
  8105. #endif
  8106. case Geom::NT_stdfloat:
  8107. // Shouldn't happen, display error.
  8108. break;
  8109. case Geom::NT_int8:
  8110. return GL_BYTE;
  8111. case Geom::NT_int16:
  8112. return GL_SHORT;
  8113. case Geom::NT_int32:
  8114. #ifndef OPENGLES_1
  8115. return GL_INT;
  8116. #else
  8117. break;
  8118. #endif
  8119. case Geom::NT_packed_ufloat:
  8120. #ifndef OPENGLES_1
  8121. return GL_UNSIGNED_INT_10F_11F_11F_REV;
  8122. #else
  8123. break;
  8124. #endif
  8125. }
  8126. GLCAT.error()
  8127. << "Invalid NumericType value (" << (int)numeric_type << ")\n";
  8128. return GL_UNSIGNED_BYTE;
  8129. }
  8130. /**
  8131. * Maps from the Texture's texture type symbols to GL's.
  8132. */
  8133. GLenum CLP(GraphicsStateGuardian)::
  8134. get_texture_target(Texture::TextureType texture_type) const {
  8135. switch (texture_type) {
  8136. case Texture::TT_1d_texture:
  8137. // There are no 1D textures in OpenGL ES. Fall back to 2D textures.
  8138. #ifndef OPENGLES
  8139. return GL_TEXTURE_1D;
  8140. #endif
  8141. case Texture::TT_1d_texture_array:
  8142. // There are no 1D array textures in OpenGL ES. Fall back to 2D textures.
  8143. #ifndef OPENGLES
  8144. return GL_TEXTURE_1D_ARRAY;
  8145. #endif
  8146. case Texture::TT_2d_texture:
  8147. return GL_TEXTURE_2D;
  8148. case Texture::TT_3d_texture:
  8149. #ifndef OPENGLES_1
  8150. if (_supports_3d_texture) {
  8151. return GL_TEXTURE_3D;
  8152. }
  8153. #endif
  8154. return GL_NONE;
  8155. case Texture::TT_2d_texture_array:
  8156. #ifndef OPENGLES_1
  8157. if (_supports_2d_texture_array) {
  8158. return GL_TEXTURE_2D_ARRAY;
  8159. }
  8160. #endif
  8161. return GL_NONE;
  8162. case Texture::TT_cube_map:
  8163. if (_supports_cube_map) {
  8164. return GL_TEXTURE_CUBE_MAP;
  8165. } else {
  8166. return GL_NONE;
  8167. }
  8168. case Texture::TT_cube_map_array:
  8169. #ifndef OPENGLES
  8170. if (_supports_cube_map_array) {
  8171. return GL_TEXTURE_CUBE_MAP_ARRAY;
  8172. }
  8173. #endif
  8174. return GL_NONE;
  8175. case Texture::TT_buffer_texture:
  8176. #ifndef OPENGLES
  8177. if (_supports_buffer_texture) {
  8178. return GL_TEXTURE_BUFFER;
  8179. }
  8180. #endif
  8181. return GL_NONE;
  8182. }
  8183. GLCAT.error() << "Invalid Texture::TextureType value!\n";
  8184. return GL_TEXTURE_2D;
  8185. }
  8186. /**
  8187. * Maps from the Texture's internal wrap mode symbols to GL's.
  8188. */
  8189. GLenum CLP(GraphicsStateGuardian)::
  8190. get_texture_wrap_mode(SamplerState::WrapMode wm) const {
  8191. if (gl_ignore_clamp) {
  8192. return GL_REPEAT;
  8193. }
  8194. switch (wm) {
  8195. case SamplerState::WM_clamp:
  8196. return _edge_clamp;
  8197. case SamplerState::WM_repeat:
  8198. return GL_REPEAT;
  8199. case SamplerState::WM_mirror:
  8200. return _mirror_repeat;
  8201. case SamplerState::WM_mirror_once:
  8202. return _mirror_border_clamp;
  8203. case SamplerState::WM_border_color:
  8204. return _border_clamp;
  8205. case SamplerState::WM_invalid:
  8206. break;
  8207. }
  8208. GLCAT.error() << "Invalid SamplerState::WrapMode value!\n";
  8209. return _edge_clamp;
  8210. }
  8211. /**
  8212. * Maps from the GL's internal wrap mode symbols to Panda's.
  8213. */
  8214. SamplerState::WrapMode CLP(GraphicsStateGuardian)::
  8215. get_panda_wrap_mode(GLenum wm) {
  8216. switch (wm) {
  8217. #ifndef OPENGLES
  8218. case GL_CLAMP:
  8219. #endif
  8220. case GL_CLAMP_TO_EDGE:
  8221. return SamplerState::WM_clamp;
  8222. #ifndef OPENGLES
  8223. case GL_CLAMP_TO_BORDER:
  8224. return SamplerState::WM_border_color;
  8225. #endif
  8226. case GL_REPEAT:
  8227. return SamplerState::WM_repeat;
  8228. case GL_MIRRORED_REPEAT:
  8229. return SamplerState::WM_mirror;
  8230. #ifndef OPENGLES
  8231. case GL_MIRROR_CLAMP_EXT:
  8232. case GL_MIRROR_CLAMP_TO_EDGE_EXT:
  8233. return SamplerState::WM_mirror;
  8234. case GL_MIRROR_CLAMP_TO_BORDER_EXT:
  8235. return SamplerState::WM_mirror_once;
  8236. #endif
  8237. }
  8238. GLCAT.error() << "Unexpected GL wrap mode " << (int)wm << "\n";
  8239. return SamplerState::WM_clamp;
  8240. }
  8241. /**
  8242. * Maps from the Texture's internal filter type symbols to GL's.
  8243. */
  8244. GLenum CLP(GraphicsStateGuardian)::
  8245. get_texture_filter_type(SamplerState::FilterType ft, bool ignore_mipmaps) {
  8246. if (gl_ignore_filters) {
  8247. return GL_NEAREST;
  8248. } else if (ignore_mipmaps) {
  8249. switch (ft) {
  8250. case SamplerState::FT_nearest_mipmap_nearest:
  8251. case SamplerState::FT_nearest:
  8252. return GL_NEAREST;
  8253. case SamplerState::FT_linear:
  8254. case SamplerState::FT_linear_mipmap_nearest:
  8255. case SamplerState::FT_nearest_mipmap_linear:
  8256. case SamplerState::FT_linear_mipmap_linear:
  8257. return GL_LINEAR;
  8258. case SamplerState::FT_shadow:
  8259. return GL_LINEAR;
  8260. case SamplerState::FT_default:
  8261. case SamplerState::FT_invalid:
  8262. break;
  8263. }
  8264. } else {
  8265. switch (ft) {
  8266. case SamplerState::FT_nearest:
  8267. return GL_NEAREST;
  8268. case SamplerState::FT_linear:
  8269. return GL_LINEAR;
  8270. case SamplerState::FT_nearest_mipmap_nearest:
  8271. return GL_NEAREST_MIPMAP_NEAREST;
  8272. case SamplerState::FT_linear_mipmap_nearest:
  8273. return GL_LINEAR_MIPMAP_NEAREST;
  8274. case SamplerState::FT_nearest_mipmap_linear:
  8275. return GL_NEAREST_MIPMAP_LINEAR;
  8276. case SamplerState::FT_linear_mipmap_linear:
  8277. return GL_LINEAR_MIPMAP_LINEAR;
  8278. case SamplerState::FT_shadow:
  8279. return GL_LINEAR;
  8280. case SamplerState::FT_default:
  8281. case SamplerState::FT_invalid:
  8282. break;
  8283. }
  8284. }
  8285. GLCAT.error() << "Invalid SamplerState::FilterType value!\n";
  8286. return GL_NEAREST;
  8287. }
  8288. /**
  8289. * Maps from the GL's internal filter type symbols to Panda's.
  8290. */
  8291. SamplerState::FilterType CLP(GraphicsStateGuardian)::
  8292. get_panda_filter_type(GLenum ft) {
  8293. switch (ft) {
  8294. case GL_NEAREST:
  8295. return SamplerState::FT_nearest;
  8296. case GL_LINEAR:
  8297. return SamplerState::FT_linear;
  8298. case GL_NEAREST_MIPMAP_NEAREST:
  8299. return SamplerState::FT_nearest_mipmap_nearest;
  8300. case GL_LINEAR_MIPMAP_NEAREST:
  8301. return SamplerState::FT_linear_mipmap_nearest;
  8302. case GL_NEAREST_MIPMAP_LINEAR:
  8303. return SamplerState::FT_nearest_mipmap_linear;
  8304. case GL_LINEAR_MIPMAP_LINEAR:
  8305. return SamplerState::FT_linear_mipmap_linear;
  8306. }
  8307. GLCAT.error() << "Unexpected GL filter type " << (int)ft << "\n";
  8308. return SamplerState::FT_linear;
  8309. }
  8310. /**
  8311. * Maps from the Texture's internal ComponentType symbols to GL's.
  8312. */
  8313. GLenum CLP(GraphicsStateGuardian)::
  8314. get_component_type(Texture::ComponentType component_type) {
  8315. switch (component_type) {
  8316. case Texture::T_unsigned_byte:
  8317. return GL_UNSIGNED_BYTE;
  8318. case Texture::T_unsigned_short:
  8319. return GL_UNSIGNED_SHORT;
  8320. case Texture::T_float:
  8321. return GL_FLOAT;
  8322. case Texture::T_unsigned_int_24_8:
  8323. if (_supports_depth_stencil) {
  8324. return GL_UNSIGNED_INT_24_8_EXT;
  8325. } else {
  8326. return GL_UNSIGNED_BYTE;
  8327. }
  8328. case Texture::T_int:
  8329. #ifndef OPENGLES_1
  8330. return GL_INT;
  8331. #endif
  8332. case Texture::T_byte:
  8333. return GL_BYTE;
  8334. case Texture::T_short:
  8335. return GL_SHORT;
  8336. #ifndef OPENGLES_1
  8337. case Texture::T_half_float:
  8338. return GL_HALF_FLOAT;
  8339. #endif
  8340. #ifndef OPENGLES_1
  8341. case Texture::T_unsigned_int:
  8342. return GL_UNSIGNED_INT;
  8343. #endif
  8344. default:
  8345. GLCAT.error() << "Invalid Texture::Type value!\n";
  8346. return GL_UNSIGNED_BYTE;
  8347. }
  8348. }
  8349. /**
  8350. * Maps from the Texture's Format symbols to GL's.
  8351. */
  8352. GLint CLP(GraphicsStateGuardian)::
  8353. get_external_image_format(Texture *tex) const {
  8354. Texture::CompressionMode compression = tex->get_ram_image_compression();
  8355. Texture::Format format = tex->get_format();
  8356. if (compression != Texture::CM_off &&
  8357. get_supports_compressed_texture_format(compression)) {
  8358. switch (compression) {
  8359. case Texture::CM_on:
  8360. #ifndef OPENGLES
  8361. switch (format) {
  8362. case Texture::F_color_index:
  8363. case Texture::F_depth_component:
  8364. case Texture::F_depth_component16:
  8365. case Texture::F_depth_component24:
  8366. case Texture::F_depth_component32:
  8367. case Texture::F_depth_stencil:
  8368. case Texture::F_r11_g11_b10:
  8369. case Texture::F_rgb9_e5:
  8370. // This shouldn't be possible.
  8371. nassertr(false, GL_RGB);
  8372. break;
  8373. case Texture::F_rgba:
  8374. case Texture::F_rgbm:
  8375. case Texture::F_rgba4:
  8376. case Texture::F_rgba8:
  8377. case Texture::F_rgba12:
  8378. case Texture::F_rgba16:
  8379. case Texture::F_rgba32:
  8380. case Texture::F_rgba8i:
  8381. case Texture::F_rgb10_a2:
  8382. return GL_COMPRESSED_RGBA;
  8383. case Texture::F_rgb:
  8384. case Texture::F_rgb5:
  8385. case Texture::F_rgba5:
  8386. case Texture::F_rgb8:
  8387. case Texture::F_rgb8i:
  8388. case Texture::F_rgb12:
  8389. case Texture::F_rgb332:
  8390. case Texture::F_rgb16:
  8391. case Texture::F_rgb32:
  8392. return GL_COMPRESSED_RGB;
  8393. case Texture::F_alpha:
  8394. return GL_COMPRESSED_ALPHA;
  8395. case Texture::F_red:
  8396. case Texture::F_green:
  8397. case Texture::F_blue:
  8398. case Texture::F_r8i:
  8399. case Texture::F_r16:
  8400. case Texture::F_r16i:
  8401. case Texture::F_r32:
  8402. case Texture::F_r32i:
  8403. return GL_COMPRESSED_RED;
  8404. case Texture::F_rg:
  8405. case Texture::F_rg8i:
  8406. case Texture::F_rg16:
  8407. case Texture::F_rg32:
  8408. return GL_COMPRESSED_RG;
  8409. case Texture::F_luminance:
  8410. return GL_COMPRESSED_LUMINANCE;
  8411. case Texture::F_luminance_alpha:
  8412. case Texture::F_luminance_alphamask:
  8413. return GL_COMPRESSED_LUMINANCE_ALPHA;
  8414. case Texture::F_srgb:
  8415. return GL_COMPRESSED_SRGB;
  8416. case Texture::F_srgb_alpha:
  8417. return GL_COMPRESSED_SRGB_ALPHA;
  8418. case Texture::F_sluminance:
  8419. return GL_COMPRESSED_SLUMINANCE;
  8420. case Texture::F_sluminance_alpha:
  8421. return GL_COMPRESSED_SLUMINANCE_ALPHA;
  8422. }
  8423. #endif
  8424. break;
  8425. case Texture::CM_dxt1:
  8426. #ifndef OPENGLES
  8427. if (format == Texture::F_srgb_alpha) {
  8428. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
  8429. } else if (format == Texture::F_srgb) {
  8430. return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
  8431. } else
  8432. #endif
  8433. if (Texture::has_alpha(format)) {
  8434. return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
  8435. } else {
  8436. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  8437. }
  8438. case Texture::CM_dxt3:
  8439. #ifndef OPENGLES
  8440. if (format == Texture::F_srgb || format == Texture::F_srgb_alpha) {
  8441. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
  8442. }
  8443. #endif
  8444. #ifndef OPENGLES_1
  8445. return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
  8446. #endif
  8447. break;
  8448. case Texture::CM_dxt5:
  8449. #ifndef OPENGLES
  8450. if (format == Texture::F_srgb || format == Texture::F_srgb_alpha) {
  8451. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
  8452. }
  8453. #endif
  8454. #ifndef OPENGLES_1
  8455. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  8456. #endif
  8457. break;
  8458. case Texture::CM_fxt1:
  8459. #ifndef OPENGLES
  8460. if (Texture::has_alpha(format)) {
  8461. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  8462. } else {
  8463. return GL_COMPRESSED_RGB_FXT1_3DFX;
  8464. }
  8465. #endif
  8466. break;
  8467. #ifdef OPENGLES
  8468. case Texture::CM_pvr1_2bpp:
  8469. if (Texture::has_alpha(format)) {
  8470. return GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
  8471. } else {
  8472. return GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
  8473. }
  8474. case Texture::CM_pvr1_4bpp:
  8475. if (Texture::has_alpha(format)) {
  8476. return GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
  8477. } else {
  8478. return GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
  8479. }
  8480. #else
  8481. case Texture::CM_pvr1_2bpp:
  8482. case Texture::CM_pvr1_4bpp:
  8483. break;
  8484. #endif // OPENGLES
  8485. case Texture::CM_rgtc:
  8486. #ifndef OPENGLES
  8487. if (format == Texture::F_luminance) {
  8488. return GL_COMPRESSED_LUMINANCE_LATC1_EXT;
  8489. } else if (format == Texture::F_luminance_alpha) {
  8490. return GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT;
  8491. } else if (tex->get_num_components() == 1) {
  8492. return GL_COMPRESSED_RED_RGTC1;
  8493. } else {
  8494. return GL_COMPRESSED_RG_RGTC2;
  8495. }
  8496. #endif
  8497. break;
  8498. case Texture::CM_etc1:
  8499. #ifdef OPENGLES
  8500. return GL_ETC1_RGB8_OES;
  8501. #endif
  8502. // Fall through - ETC2 is backward compatible
  8503. case Texture::CM_etc2:
  8504. if (format == Texture::F_rgbm) {
  8505. return GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
  8506. } else if (format == Texture::F_srgb_alpha) {
  8507. return GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
  8508. } else if (format == Texture::F_srgb) {
  8509. return GL_COMPRESSED_SRGB8_ETC2;
  8510. } else if (Texture::has_alpha(format)) {
  8511. return GL_COMPRESSED_RGBA8_ETC2_EAC;
  8512. } else {
  8513. return GL_COMPRESSED_RGB8_ETC2;
  8514. }
  8515. break;
  8516. case Texture::CM_eac:
  8517. if (Texture::is_unsigned(tex->get_component_type())) {
  8518. if (tex->get_num_components() == 1) {
  8519. return GL_COMPRESSED_R11_EAC;
  8520. } else {
  8521. return GL_COMPRESSED_RG11_EAC;
  8522. }
  8523. } else {
  8524. if (tex->get_num_components() == 1) {
  8525. return GL_COMPRESSED_SIGNED_R11_EAC;
  8526. } else {
  8527. return GL_COMPRESSED_SIGNED_RG11_EAC;
  8528. }
  8529. }
  8530. break;
  8531. case Texture::CM_default:
  8532. case Texture::CM_off:
  8533. case Texture::CM_dxt2:
  8534. case Texture::CM_dxt4:
  8535. // This shouldn't happen.
  8536. nassertr(false, GL_RGB);
  8537. break;
  8538. }
  8539. }
  8540. switch (format) {
  8541. #ifndef OPENGLES
  8542. case Texture::F_color_index:
  8543. return GL_COLOR_INDEX;
  8544. #endif
  8545. case Texture::F_depth_component:
  8546. case Texture::F_depth_component16:
  8547. case Texture::F_depth_component24:
  8548. case Texture::F_depth_component32:
  8549. return GL_DEPTH_COMPONENT;
  8550. case Texture::F_depth_stencil:
  8551. return _supports_depth_stencil ? GL_DEPTH_STENCIL : GL_DEPTH_COMPONENT;
  8552. #ifndef OPENGLES
  8553. case Texture::F_red:
  8554. case Texture::F_r16:
  8555. case Texture::F_r32:
  8556. return GL_RED;
  8557. case Texture::F_green:
  8558. return GL_GREEN;
  8559. case Texture::F_blue:
  8560. return GL_BLUE;
  8561. #endif
  8562. case Texture::F_alpha:
  8563. #ifdef OPENGLES
  8564. return GL_ALPHA;
  8565. #else
  8566. return _supports_luminance_texture ? GL_ALPHA : GL_RED;
  8567. #endif
  8568. #ifndef OPENGLES_1
  8569. case Texture::F_rg:
  8570. case Texture::F_rg16:
  8571. case Texture::F_rg32:
  8572. return GL_RG;
  8573. #endif
  8574. case Texture::F_rgb:
  8575. case Texture::F_rgb5:
  8576. case Texture::F_rgb8:
  8577. case Texture::F_rgb12:
  8578. case Texture::F_rgb332:
  8579. case Texture::F_rgb16:
  8580. case Texture::F_rgb32:
  8581. case Texture::F_srgb:
  8582. case Texture::F_r11_g11_b10:
  8583. case Texture::F_rgb9_e5:
  8584. #ifdef OPENGLES
  8585. // OpenGL ES never supports BGR, even if _supports_bgr is true.
  8586. return GL_RGB;
  8587. #else
  8588. return _supports_bgr ? GL_BGR : GL_RGB;
  8589. #endif
  8590. case Texture::F_rgba:
  8591. case Texture::F_rgbm:
  8592. case Texture::F_rgba4:
  8593. case Texture::F_rgba5:
  8594. case Texture::F_rgba8:
  8595. case Texture::F_rgba12:
  8596. case Texture::F_rgba16:
  8597. case Texture::F_rgba32:
  8598. case Texture::F_srgb_alpha:
  8599. case Texture::F_rgb10_a2:
  8600. return _supports_bgr ? GL_BGRA : GL_RGBA;
  8601. case Texture::F_luminance:
  8602. #ifdef OPENGLES
  8603. return GL_LUMINANCE;
  8604. #else
  8605. return _supports_luminance_texture ? GL_LUMINANCE : GL_RED;
  8606. #endif
  8607. case Texture::F_luminance_alphamask:
  8608. case Texture::F_luminance_alpha:
  8609. #ifdef OPENGLES
  8610. return GL_LUMINANCE_ALPHA;
  8611. #else
  8612. return _supports_luminance_texture ? GL_LUMINANCE_ALPHA : GL_RG;
  8613. #endif
  8614. case Texture::F_sluminance:
  8615. #ifdef OPENGLES
  8616. return GL_LUMINANCE;
  8617. #else
  8618. return _supports_luminance_texture ? GL_LUMINANCE : GL_RGB;
  8619. #endif
  8620. case Texture::F_sluminance_alpha:
  8621. #ifdef OPENGLES
  8622. return GL_LUMINANCE_ALPHA;
  8623. #else
  8624. return _supports_luminance_texture ? GL_LUMINANCE_ALPHA : GL_RGBA;
  8625. #endif
  8626. #ifndef OPENGLES_1
  8627. case Texture::F_r8i:
  8628. case Texture::F_r16i:
  8629. case Texture::F_r32i:
  8630. return GL_RED_INTEGER;
  8631. case Texture::F_rg8i:
  8632. return GL_RG_INTEGER;
  8633. case Texture::F_rgb8i:
  8634. return GL_RGB_INTEGER;
  8635. case Texture::F_rgba8i:
  8636. return GL_RGBA_INTEGER;
  8637. #endif
  8638. default:
  8639. break;
  8640. }
  8641. GLCAT.error()
  8642. << "Invalid Texture::Format value in get_external_image_format(): "
  8643. << format << "\n";
  8644. return GL_RGB;
  8645. }
  8646. /**
  8647. * Maps from the Texture's Format symbols to a suitable internal format for GL
  8648. * textures.
  8649. */
  8650. GLint CLP(GraphicsStateGuardian)::
  8651. get_internal_image_format(Texture *tex, bool force_sized) const {
  8652. Texture::CompressionMode compression = tex->get_compression();
  8653. if (compression == Texture::CM_default) {
  8654. compression = (compressed_textures) ? Texture::CM_on : Texture::CM_off;
  8655. }
  8656. Texture::Format format = tex->get_format();
  8657. if (tex->get_render_to_texture()) {
  8658. // no compression for render targets
  8659. compression = Texture::CM_off;
  8660. }
  8661. bool is_3d = (tex->get_texture_type() == Texture::TT_3d_texture ||
  8662. tex->get_texture_type() == Texture::TT_2d_texture_array);
  8663. if (get_supports_compressed_texture_format(compression)) {
  8664. switch (compression) {
  8665. case Texture::CM_on:
  8666. // The user asked for just generic compression. OpenGL supports
  8667. // requesting just generic compression, but we'd like to go ahead and
  8668. // request a specific type (if we can figure out an appropriate choice),
  8669. // since that makes saving the result as a pre-compressed texture more
  8670. // dependable--this way, we will know which compression algorithm was
  8671. // applied.
  8672. switch (format) {
  8673. case Texture::F_color_index:
  8674. case Texture::F_depth_component:
  8675. case Texture::F_depth_component16:
  8676. case Texture::F_depth_component24:
  8677. case Texture::F_depth_component32:
  8678. case Texture::F_depth_stencil:
  8679. case Texture::F_r8i:
  8680. case Texture::F_rg8i:
  8681. case Texture::F_rgb8i:
  8682. case Texture::F_rgba8i:
  8683. case Texture::F_r16i:
  8684. case Texture::F_r32i:
  8685. case Texture::F_r11_g11_b10:
  8686. case Texture::F_rgb9_e5:
  8687. // Unsupported; fall through to below.
  8688. break;
  8689. case Texture::F_rgbm:
  8690. case Texture::F_rgba5:
  8691. case Texture::F_rgb10_a2:
  8692. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  8693. return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
  8694. }
  8695. if (get_supports_compressed_texture_format(Texture::CM_etc2) && !is_3d) {
  8696. return GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
  8697. }
  8698. #ifndef OPENGLES
  8699. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  8700. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  8701. }
  8702. return GL_COMPRESSED_RGBA;
  8703. #endif
  8704. break;
  8705. case Texture::F_rgba4:
  8706. #ifndef OPENGLES_1
  8707. if (get_supports_compressed_texture_format(Texture::CM_dxt3) && !is_3d) {
  8708. return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
  8709. }
  8710. #endif
  8711. if (get_supports_compressed_texture_format(Texture::CM_etc2) && !is_3d) {
  8712. return GL_COMPRESSED_RGBA8_ETC2_EAC;
  8713. }
  8714. #ifndef OPENGLES
  8715. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  8716. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  8717. }
  8718. return GL_COMPRESSED_RGBA;
  8719. #endif
  8720. break;
  8721. case Texture::F_rgba:
  8722. case Texture::F_rgba8:
  8723. case Texture::F_rgba12:
  8724. case Texture::F_rgba16:
  8725. case Texture::F_rgba32:
  8726. #ifndef OPENGLES_1
  8727. if (get_supports_compressed_texture_format(Texture::CM_dxt5) && !is_3d) {
  8728. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  8729. }
  8730. #endif
  8731. if (get_supports_compressed_texture_format(Texture::CM_etc2) && !is_3d) {
  8732. return GL_COMPRESSED_RGBA8_ETC2_EAC;
  8733. }
  8734. #ifndef OPENGLES
  8735. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  8736. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  8737. }
  8738. return GL_COMPRESSED_RGBA;
  8739. #endif
  8740. break;
  8741. case Texture::F_rgb:
  8742. case Texture::F_rgb5:
  8743. case Texture::F_rgb8:
  8744. case Texture::F_rgb12:
  8745. case Texture::F_rgb332:
  8746. case Texture::F_rgb16:
  8747. case Texture::F_rgb32:
  8748. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  8749. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  8750. }
  8751. if (get_supports_compressed_texture_format(Texture::CM_etc2) && !is_3d) {
  8752. return GL_COMPRESSED_RGB8_ETC2;
  8753. }
  8754. #ifdef OPENGLES
  8755. if (get_supports_compressed_texture_format(Texture::CM_etc1) && !is_3d) {
  8756. return GL_ETC1_RGB8_OES;
  8757. }
  8758. #else
  8759. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  8760. return GL_COMPRESSED_RGB_FXT1_3DFX;
  8761. }
  8762. return GL_COMPRESSED_RGB;
  8763. #endif
  8764. break;
  8765. case Texture::F_alpha:
  8766. #ifndef OPENGLES_1
  8767. if (get_supports_compressed_texture_format(Texture::CM_dxt5) && !is_3d) {
  8768. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  8769. }
  8770. #endif
  8771. #ifndef OPENGLES
  8772. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  8773. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  8774. }
  8775. return GL_COMPRESSED_ALPHA;
  8776. #endif
  8777. break;
  8778. case Texture::F_red:
  8779. case Texture::F_green:
  8780. case Texture::F_blue:
  8781. case Texture::F_r16:
  8782. case Texture::F_r32:
  8783. #ifndef OPENGLES
  8784. if (get_supports_compressed_texture_format(Texture::CM_rgtc) && !is_3d) {
  8785. return GL_COMPRESSED_RED_RGTC1;
  8786. }
  8787. #endif
  8788. if (get_supports_compressed_texture_format(Texture::CM_eac) && !is_3d) {
  8789. if (Texture::is_unsigned(tex->get_component_type())) {
  8790. return GL_COMPRESSED_R11_EAC;
  8791. } else {
  8792. return GL_COMPRESSED_SIGNED_R11_EAC;
  8793. }
  8794. }
  8795. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  8796. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  8797. }
  8798. #ifndef OPENGLES
  8799. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  8800. return GL_COMPRESSED_RGB_FXT1_3DFX;
  8801. }
  8802. return GL_COMPRESSED_RED;
  8803. #endif
  8804. break;
  8805. case Texture::F_rg:
  8806. case Texture::F_rg16:
  8807. case Texture::F_rg32:
  8808. #ifndef OPENGLES
  8809. if (get_supports_compressed_texture_format(Texture::CM_rgtc) && !is_3d) {
  8810. return GL_COMPRESSED_RG_RGTC2;
  8811. }
  8812. #endif
  8813. if (get_supports_compressed_texture_format(Texture::CM_eac) && !is_3d) {
  8814. if (Texture::is_unsigned(tex->get_component_type())) {
  8815. return GL_COMPRESSED_RG11_EAC;
  8816. } else {
  8817. return GL_COMPRESSED_SIGNED_RG11_EAC;
  8818. }
  8819. }
  8820. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  8821. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  8822. }
  8823. #ifndef OPENGLES
  8824. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  8825. return GL_COMPRESSED_RGB_FXT1_3DFX;
  8826. }
  8827. return GL_COMPRESSED_RG;
  8828. #endif
  8829. break;
  8830. case Texture::F_luminance:
  8831. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  8832. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  8833. }
  8834. #ifndef OPENGLES
  8835. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  8836. return GL_COMPRESSED_RGB_FXT1_3DFX;
  8837. }
  8838. return GL_COMPRESSED_LUMINANCE;
  8839. #endif
  8840. break;
  8841. case Texture::F_luminance_alpha:
  8842. case Texture::F_luminance_alphamask:
  8843. #ifndef OPENGLES_1
  8844. if (get_supports_compressed_texture_format(Texture::CM_dxt5) && !is_3d) {
  8845. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  8846. }
  8847. #endif
  8848. #ifndef OPENGLES
  8849. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  8850. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  8851. }
  8852. return GL_COMPRESSED_LUMINANCE_ALPHA;
  8853. #endif
  8854. break;
  8855. #ifndef OPENGLES
  8856. case Texture::F_srgb:
  8857. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  8858. return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
  8859. }
  8860. if (get_supports_compressed_texture_format(Texture::CM_etc2) && !is_3d) {
  8861. return GL_COMPRESSED_SRGB8_ETC2;
  8862. }
  8863. return GL_COMPRESSED_SRGB;
  8864. case Texture::F_srgb_alpha:
  8865. if (get_supports_compressed_texture_format(Texture::CM_dxt5) && !is_3d) {
  8866. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
  8867. }
  8868. if (get_supports_compressed_texture_format(Texture::CM_etc2) && !is_3d) {
  8869. return GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
  8870. }
  8871. return GL_COMPRESSED_SRGB_ALPHA;
  8872. case Texture::F_sluminance:
  8873. return GL_COMPRESSED_SLUMINANCE;
  8874. case Texture::F_sluminance_alpha:
  8875. return GL_COMPRESSED_SLUMINANCE_ALPHA;
  8876. #else
  8877. // For now, we don't support compressed sRGB textures in OpenGL ES.
  8878. case Texture::F_srgb:
  8879. case Texture::F_srgb_alpha:
  8880. case Texture::F_sluminance:
  8881. case Texture::F_sluminance_alpha:
  8882. break;
  8883. #endif
  8884. }
  8885. break;
  8886. case Texture::CM_dxt1:
  8887. #ifndef OPENGLES
  8888. if (format == Texture::F_srgb_alpha) {
  8889. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
  8890. } else if (format == Texture::F_srgb) {
  8891. return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
  8892. } else
  8893. #endif
  8894. if (Texture::has_alpha(format)) {
  8895. return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
  8896. } else {
  8897. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  8898. }
  8899. case Texture::CM_dxt3:
  8900. #ifndef OPENGLES
  8901. if (format == Texture::F_srgb || format == Texture::F_srgb_alpha) {
  8902. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
  8903. }
  8904. #endif
  8905. #ifndef OPENGLES_1
  8906. return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
  8907. #endif
  8908. break;
  8909. case Texture::CM_dxt5:
  8910. #ifndef OPENGLES
  8911. if (format == Texture::F_srgb || format == Texture::F_srgb_alpha) {
  8912. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
  8913. }
  8914. #endif
  8915. #ifndef OPENGLES_1
  8916. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  8917. #endif
  8918. case Texture::CM_fxt1:
  8919. #ifndef OPENGLES
  8920. if (Texture::has_alpha(format)) {
  8921. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  8922. } else {
  8923. return GL_COMPRESSED_RGB_FXT1_3DFX;
  8924. }
  8925. #endif
  8926. break;
  8927. #ifdef OPENGLES
  8928. case Texture::CM_pvr1_2bpp:
  8929. if (Texture::has_alpha(format)) {
  8930. return GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
  8931. } else {
  8932. return GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
  8933. }
  8934. case Texture::CM_pvr1_4bpp:
  8935. if (Texture::has_alpha(format)) {
  8936. return GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
  8937. } else {
  8938. return GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
  8939. }
  8940. #else
  8941. case Texture::CM_pvr1_2bpp:
  8942. case Texture::CM_pvr1_4bpp:
  8943. break;
  8944. #endif
  8945. case Texture::CM_rgtc:
  8946. #ifndef OPENGLES
  8947. if (format == Texture::F_luminance) {
  8948. return GL_COMPRESSED_LUMINANCE_LATC1_EXT;
  8949. } else if (format == Texture::F_luminance_alpha) {
  8950. return GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT;
  8951. } else if (tex->get_num_components() == 1) {
  8952. return GL_COMPRESSED_RED_RGTC1;
  8953. } else if (tex->get_num_components() == 2) {
  8954. return GL_COMPRESSED_RG_RGTC2;
  8955. }
  8956. #endif
  8957. break;
  8958. case Texture::CM_etc1:
  8959. #ifdef OPENGLES
  8960. return GL_ETC1_RGB8_OES;
  8961. #endif
  8962. // Fall through - ETC2 is backward compatible
  8963. case Texture::CM_etc2:
  8964. if (format == Texture::F_rgbm) {
  8965. return GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2;
  8966. } else if (format == Texture::F_srgb_alpha) {
  8967. return GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC;
  8968. } else if (format == Texture::F_srgb) {
  8969. return GL_COMPRESSED_SRGB8_ETC2;
  8970. } else if (Texture::has_alpha(format)) {
  8971. return GL_COMPRESSED_RGBA8_ETC2_EAC;
  8972. } else {
  8973. return GL_COMPRESSED_RGB8_ETC2;
  8974. }
  8975. break;
  8976. case Texture::CM_eac:
  8977. if (Texture::is_unsigned(tex->get_component_type())) {
  8978. if (tex->get_num_components() == 1) {
  8979. return GL_COMPRESSED_R11_EAC;
  8980. } else {
  8981. return GL_COMPRESSED_RG11_EAC;
  8982. }
  8983. } else {
  8984. if (tex->get_num_components() == 1) {
  8985. return GL_COMPRESSED_SIGNED_R11_EAC;
  8986. } else {
  8987. return GL_COMPRESSED_SIGNED_RG11_EAC;
  8988. }
  8989. }
  8990. break;
  8991. case Texture::CM_default:
  8992. case Texture::CM_off:
  8993. case Texture::CM_dxt2:
  8994. case Texture::CM_dxt4:
  8995. // No compression: fall through to below.
  8996. break;
  8997. }
  8998. }
  8999. switch (format) {
  9000. #ifndef OPENGLES
  9001. case Texture::F_color_index:
  9002. return GL_COLOR_INDEX;
  9003. #endif
  9004. case Texture::F_depth_stencil:
  9005. if (_supports_depth_stencil) {
  9006. #ifndef OPENGLES
  9007. if (tex->get_component_type() == Texture::T_float) {
  9008. return GL_DEPTH32F_STENCIL8;
  9009. } else
  9010. #endif
  9011. {
  9012. return force_sized ? GL_DEPTH24_STENCIL8 : GL_DEPTH_STENCIL;
  9013. }
  9014. }
  9015. // Fall through.
  9016. case Texture::F_depth_component:
  9017. #ifndef OPENGLES
  9018. if (tex->get_component_type() == Texture::T_float) {
  9019. return GL_DEPTH_COMPONENT32F;
  9020. } else
  9021. #endif
  9022. {
  9023. return force_sized ? GL_DEPTH_COMPONENT16 : GL_DEPTH_COMPONENT;
  9024. }
  9025. case Texture::F_depth_component16:
  9026. #ifdef OPENGLES
  9027. return GL_DEPTH_COMPONENT16_OES;
  9028. #else
  9029. return GL_DEPTH_COMPONENT16;
  9030. #endif
  9031. case Texture::F_depth_component24:
  9032. #ifdef OPENGLES
  9033. if (_supports_depth24) {
  9034. return GL_DEPTH_COMPONENT24_OES;
  9035. } else {
  9036. return GL_DEPTH_COMPONENT16_OES;
  9037. }
  9038. #else
  9039. return GL_DEPTH_COMPONENT24;
  9040. #endif
  9041. case Texture::F_depth_component32:
  9042. #ifdef OPENGLES
  9043. if (_supports_depth32) {
  9044. return GL_DEPTH_COMPONENT32_OES;
  9045. } else if (_supports_depth24) {
  9046. return GL_DEPTH_COMPONENT24_OES;
  9047. } else {
  9048. return GL_DEPTH_COMPONENT16_OES;
  9049. }
  9050. #else
  9051. if (tex->get_component_type() == Texture::T_float) {
  9052. return GL_DEPTH_COMPONENT32F;
  9053. } else {
  9054. return GL_DEPTH_COMPONENT32;
  9055. }
  9056. #endif
  9057. case Texture::F_rgba:
  9058. case Texture::F_rgbm:
  9059. #ifndef OPENGLES_1
  9060. if (tex->get_component_type() == Texture::T_float) {
  9061. return GL_RGBA16F;
  9062. } else
  9063. #endif
  9064. #ifdef OPENGLES
  9065. {
  9066. // In OpenGL ES, the internal format must match the external format.
  9067. return _supports_bgr ? GL_BGRA : GL_RGBA;
  9068. }
  9069. #else
  9070. if (tex->get_component_type() == Texture::T_unsigned_short) {
  9071. return GL_RGBA16;
  9072. } else if (tex->get_component_type() == Texture::T_short) {
  9073. return GL_RGBA16_SNORM;
  9074. } else if (tex->get_component_type() == Texture::T_byte) {
  9075. return GL_RGBA8_SNORM;
  9076. } else {
  9077. return force_sized ? GL_RGBA8 : GL_RGBA;
  9078. }
  9079. #endif
  9080. case Texture::F_rgba4:
  9081. return GL_RGBA4;
  9082. #ifdef OPENGLES
  9083. case Texture::F_rgba8:
  9084. return GL_RGBA8_OES;
  9085. case Texture::F_rgba12:
  9086. return force_sized ? GL_RGBA8 : GL_RGBA;
  9087. #else
  9088. case Texture::F_rgba8:
  9089. if (Texture::is_unsigned(tex->get_component_type())) {
  9090. return GL_RGBA8;
  9091. } else {
  9092. return GL_RGBA8_SNORM;
  9093. }
  9094. case Texture::F_r8i:
  9095. if (Texture::is_unsigned(tex->get_component_type())) {
  9096. return GL_R8UI;
  9097. } else {
  9098. return GL_R8I;
  9099. }
  9100. case Texture::F_rg8i:
  9101. if (Texture::is_unsigned(tex->get_component_type())) {
  9102. return GL_RG8UI;
  9103. } else {
  9104. return GL_RG8I;
  9105. }
  9106. case Texture::F_rgb8i:
  9107. if (Texture::is_unsigned(tex->get_component_type())) {
  9108. return GL_RGB8UI;
  9109. } else {
  9110. return GL_RGB8I;
  9111. }
  9112. case Texture::F_rgba8i:
  9113. if (Texture::is_unsigned(tex->get_component_type())) {
  9114. return GL_RGBA8UI;
  9115. } else {
  9116. return GL_RGBA8I;
  9117. }
  9118. case Texture::F_rgba12:
  9119. return GL_RGBA12;
  9120. #endif // OPENGLES
  9121. #ifndef OPENGLES
  9122. case Texture::F_rgba16:
  9123. if (tex->get_component_type() == Texture::T_float) {
  9124. return GL_RGBA16F;
  9125. } else if (Texture::is_unsigned(tex->get_component_type())) {
  9126. return GL_RGBA16;
  9127. } else {
  9128. return GL_RGBA16_SNORM;
  9129. }
  9130. case Texture::F_rgba32:
  9131. return GL_RGBA32F;
  9132. #endif // OPENGLES
  9133. case Texture::F_rgb:
  9134. switch (tex->get_component_type()) {
  9135. case Texture::T_float: return GL_RGB16F;
  9136. #ifndef OPENGLES
  9137. case Texture::T_unsigned_short: return GL_RGB16;
  9138. case Texture::T_short: return GL_RGB16_SNORM;
  9139. case Texture::T_byte: return GL_RGB8_SNORM;
  9140. #endif
  9141. default:
  9142. return force_sized ? GL_RGB8 : GL_RGB;
  9143. }
  9144. case Texture::F_rgb5:
  9145. #ifdef OPENGLES
  9146. // Close enough.
  9147. return GL_RGB565_OES;
  9148. #else
  9149. return GL_RGB5;
  9150. #endif
  9151. case Texture::F_rgba5:
  9152. return GL_RGB5_A1;
  9153. #ifdef OPENGLES
  9154. case Texture::F_rgb8:
  9155. return GL_RGB8_OES;
  9156. case Texture::F_rgb12:
  9157. return force_sized ? GL_RGB8 : GL_RGB;
  9158. case Texture::F_rgb16:
  9159. return GL_RGB16F;
  9160. #else
  9161. case Texture::F_rgb8:
  9162. if (Texture::is_unsigned(tex->get_component_type())) {
  9163. return GL_RGB8;
  9164. } else {
  9165. return GL_RGB8_SNORM;
  9166. }
  9167. case Texture::F_rgb12:
  9168. return GL_RGB12;
  9169. case Texture::F_rgb16:
  9170. if (tex->get_component_type() == Texture::T_float) {
  9171. return GL_RGB16F;
  9172. } else if (Texture::is_unsigned(tex->get_component_type())) {
  9173. return GL_RGB16;
  9174. } else {
  9175. return GL_RGB16_SNORM;
  9176. }
  9177. #endif // OPENGLES
  9178. case Texture::F_rgb32:
  9179. return GL_RGB32F;
  9180. #ifndef OPENGLES
  9181. case Texture::F_rgb332:
  9182. return GL_R3_G3_B2;
  9183. #endif
  9184. #if defined(OPENGLES_2)
  9185. case Texture::F_r16:
  9186. return GL_R16F_EXT;
  9187. case Texture::F_rg16:
  9188. return GL_RG16F_EXT;
  9189. #elif !defined(OPENGLES_1)
  9190. case Texture::F_r16:
  9191. if (tex->get_component_type() == Texture::T_float) {
  9192. return GL_R16F;
  9193. } else if (Texture::is_unsigned(tex->get_component_type())) {
  9194. return GL_R16;
  9195. } else {
  9196. return GL_R16_SNORM;
  9197. }
  9198. case Texture::F_r16i:
  9199. if (Texture::is_unsigned(tex->get_component_type())) {
  9200. return GL_R16UI;
  9201. } else {
  9202. return GL_R16I;
  9203. }
  9204. case Texture::F_rg16:
  9205. if (tex->get_component_type() == Texture::T_float) {
  9206. return GL_RG16F;
  9207. } else if (Texture::is_unsigned(tex->get_component_type())) {
  9208. return GL_RG16;
  9209. } else {
  9210. return GL_RG16_SNORM;
  9211. }
  9212. #endif
  9213. #ifndef OPENGLES_1
  9214. case Texture::F_r32:
  9215. return GL_R32F;
  9216. case Texture::F_rg32:
  9217. return GL_RG32F;
  9218. case Texture::F_red:
  9219. case Texture::F_green:
  9220. case Texture::F_blue:
  9221. #ifndef OPENGLES
  9222. if (!Texture::is_unsigned(tex->get_component_type())) {
  9223. return GL_R8_SNORM;
  9224. } else
  9225. #endif
  9226. {
  9227. return force_sized ? GL_R8 : GL_RED;
  9228. }
  9229. #endif
  9230. case Texture::F_alpha:
  9231. #ifdef OPENGLES
  9232. return force_sized ? GL_ALPHA8 : GL_ALPHA;
  9233. #else
  9234. if (_supports_luminance_texture) {
  9235. return force_sized ? GL_ALPHA8 : GL_ALPHA;
  9236. } else {
  9237. return force_sized ? GL_R8 : GL_RED;
  9238. }
  9239. #endif
  9240. case Texture::F_luminance:
  9241. #ifdef OPENGLES
  9242. return force_sized ? GL_LUMINANCE8 : GL_LUMINANCE;
  9243. #else
  9244. if (_supports_luminance_texture) {
  9245. switch (tex->get_component_type()) {
  9246. case Texture::T_float:
  9247. case Texture::T_half_float:
  9248. return GL_LUMINANCE16F_ARB;
  9249. case Texture::T_short:
  9250. return GL_LUMINANCE16_SNORM;
  9251. case Texture::T_unsigned_short:
  9252. return GL_LUMINANCE16;
  9253. default:
  9254. return force_sized ? GL_LUMINANCE8 : GL_LUMINANCE;
  9255. }
  9256. } else {
  9257. switch (tex->get_component_type()) {
  9258. case Texture::T_float:
  9259. case Texture::T_half_float:
  9260. return GL_R16F;
  9261. case Texture::T_short:
  9262. return GL_R16_SNORM;
  9263. case Texture::T_unsigned_short:
  9264. return GL_R16;
  9265. default:
  9266. return force_sized ? GL_R8 : GL_RED;
  9267. }
  9268. }
  9269. #endif
  9270. case Texture::F_luminance_alpha:
  9271. case Texture::F_luminance_alphamask:
  9272. #ifdef OPENGLES
  9273. return force_sized ? GL_LUMINANCE8_ALPHA8 : GL_LUMINANCE_ALPHA;
  9274. #else
  9275. if (_supports_luminance_texture) {
  9276. switch (tex->get_component_type()) {
  9277. case Texture::T_float:
  9278. case Texture::T_half_float:
  9279. return GL_LUMINANCE_ALPHA16F_ARB;
  9280. case Texture::T_short:
  9281. return GL_LUMINANCE16_SNORM;
  9282. case Texture::T_unsigned_short:
  9283. return GL_LUMINANCE16_ALPHA16;
  9284. default:
  9285. return force_sized ? GL_LUMINANCE8_ALPHA8 : GL_LUMINANCE_ALPHA;
  9286. }
  9287. } else {
  9288. switch (tex->get_component_type()) {
  9289. case Texture::T_float:
  9290. case Texture::T_half_float:
  9291. return GL_RG16F;
  9292. case Texture::T_short:
  9293. return GL_RG16_SNORM;
  9294. case Texture::T_unsigned_short:
  9295. return GL_RG16;
  9296. default:
  9297. return force_sized ? GL_RG8 : GL_RG;
  9298. }
  9299. }
  9300. #endif
  9301. #ifndef OPENGLES_1
  9302. case Texture::F_rg:
  9303. return force_sized ? GL_RG8 : GL_RG;
  9304. #endif
  9305. #ifndef OPENGLES_1
  9306. case Texture::F_srgb:
  9307. return _supports_texture_srgb ? GL_SRGB8 : GL_RGB8;
  9308. case Texture::F_srgb_alpha:
  9309. return _supports_texture_srgb ? GL_SRGB8_ALPHA8 : GL_RGBA8;
  9310. #endif
  9311. #ifndef OPENGLES
  9312. case Texture::F_sluminance:
  9313. return _core_profile ? GL_SRGB8 : GL_SLUMINANCE8;
  9314. case Texture::F_sluminance_alpha:
  9315. return _core_profile ? GL_SRGB8_ALPHA8 : GL_SLUMINANCE8_ALPHA8;
  9316. #endif
  9317. #ifndef OPENGLES
  9318. case Texture::F_r32i:
  9319. return GL_R32I;
  9320. #endif
  9321. #ifndef OPENGLES_1
  9322. case Texture::F_r11_g11_b10:
  9323. return GL_R11F_G11F_B10F;
  9324. case Texture::F_rgb9_e5:
  9325. return GL_RGB9_E5;
  9326. case Texture::F_rgb10_a2:
  9327. return GL_RGB10_A2;
  9328. #endif
  9329. default:
  9330. GLCAT.error()
  9331. << "Invalid image format in get_internal_image_format(): "
  9332. << (int)format << "\n";
  9333. return force_sized ? GL_RGB8 : GL_RGB;
  9334. }
  9335. }
  9336. /**
  9337. * Returns true if the indicated GL minfilter type represents a mipmap format,
  9338. * false otherwise.
  9339. */
  9340. bool CLP(GraphicsStateGuardian)::
  9341. is_mipmap_filter(GLenum min_filter) {
  9342. switch (min_filter) {
  9343. case GL_NEAREST_MIPMAP_NEAREST:
  9344. case GL_LINEAR_MIPMAP_NEAREST:
  9345. case GL_NEAREST_MIPMAP_LINEAR:
  9346. case GL_LINEAR_MIPMAP_LINEAR:
  9347. return true;
  9348. default:
  9349. return false;
  9350. }
  9351. }
  9352. /**
  9353. * Returns true if the indicated GL internal format represents a compressed
  9354. * texture format, false otherwise.
  9355. */
  9356. bool CLP(GraphicsStateGuardian)::
  9357. is_compressed_format(GLenum format) {
  9358. switch (format) {
  9359. case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  9360. case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  9361. #ifdef OPENGLES
  9362. case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
  9363. case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
  9364. case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
  9365. case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
  9366. #else
  9367. case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
  9368. case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
  9369. case GL_COMPRESSED_RGB_FXT1_3DFX:
  9370. case GL_COMPRESSED_RGBA_FXT1_3DFX:
  9371. case GL_COMPRESSED_RED_RGTC1:
  9372. case GL_COMPRESSED_SIGNED_RED_RGTC1:
  9373. case GL_COMPRESSED_RG_RGTC2:
  9374. case GL_COMPRESSED_SIGNED_RG_RGTC2:
  9375. case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
  9376. case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:
  9377. case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
  9378. case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:
  9379. case GL_COMPRESSED_RGB:
  9380. case GL_COMPRESSED_SRGB_EXT:
  9381. case GL_COMPRESSED_RGBA:
  9382. case GL_COMPRESSED_SRGB_ALPHA_EXT:
  9383. case GL_COMPRESSED_ALPHA:
  9384. case GL_COMPRESSED_LUMINANCE:
  9385. case GL_COMPRESSED_LUMINANCE_ALPHA:
  9386. #endif
  9387. return true;
  9388. default:
  9389. return false;
  9390. }
  9391. }
  9392. /**
  9393. * Maps from the texture stage's mode types to the corresponding OpenGL ids
  9394. */
  9395. GLint CLP(GraphicsStateGuardian)::
  9396. get_texture_apply_mode_type(TextureStage::Mode am) {
  9397. #ifdef SUPPORT_FIXED_FUNCTION
  9398. switch (am) {
  9399. case TextureStage::M_modulate: return GL_MODULATE;
  9400. case TextureStage::M_decal: return GL_DECAL;
  9401. case TextureStage::M_blend: return GL_BLEND;
  9402. case TextureStage::M_replace: return GL_REPLACE;
  9403. case TextureStage::M_add: return GL_ADD;
  9404. case TextureStage::M_combine: return GL_COMBINE;
  9405. case TextureStage::M_blend_color_scale: return GL_BLEND;
  9406. case TextureStage::M_modulate_glow: return GL_MODULATE;
  9407. case TextureStage::M_modulate_gloss: return GL_MODULATE;
  9408. default:
  9409. // Other modes shouldn't get here. Fall through and error.
  9410. break;
  9411. }
  9412. GLCAT.error()
  9413. << "Invalid TextureStage::Mode value" << endl;
  9414. return GL_MODULATE;
  9415. #else
  9416. return 0;
  9417. #endif
  9418. }
  9419. /**
  9420. * Maps from the texture stage's CombineMode types to the corresponding OpenGL
  9421. * ids
  9422. */
  9423. GLint CLP(GraphicsStateGuardian)::
  9424. get_texture_combine_type(TextureStage::CombineMode cm) {
  9425. #ifdef SUPPORT_FIXED_FUNCTION
  9426. switch (cm) {
  9427. case TextureStage::CM_undefined: // fall through
  9428. case TextureStage::CM_replace: return GL_REPLACE;
  9429. case TextureStage::CM_modulate: return GL_MODULATE;
  9430. case TextureStage::CM_add: return GL_ADD;
  9431. case TextureStage::CM_add_signed: return GL_ADD_SIGNED;
  9432. case TextureStage::CM_interpolate: return GL_INTERPOLATE;
  9433. case TextureStage::CM_subtract: return GL_SUBTRACT;
  9434. case TextureStage::CM_dot3_rgb: return GL_DOT3_RGB;
  9435. case TextureStage::CM_dot3_rgba: return GL_DOT3_RGBA;
  9436. }
  9437. GLCAT.error()
  9438. << "Invalid TextureStage::CombineMode value" << endl;
  9439. #endif
  9440. return GL_REPLACE;
  9441. }
  9442. /**
  9443. * Maps from the texture stage's CombineSource types to the corresponding
  9444. * OpenGL ids
  9445. */
  9446. GLint CLP(GraphicsStateGuardian)::
  9447. get_texture_src_type(TextureStage::CombineSource cs,
  9448. int last_stage, int last_saved_result,
  9449. int this_stage) const {
  9450. #ifdef SUPPORT_FIXED_FUNCTION
  9451. switch (cs) {
  9452. case TextureStage::CS_undefined: // fall through
  9453. case TextureStage::CS_texture: return GL_TEXTURE;
  9454. case TextureStage::CS_constant: return GL_CONSTANT;
  9455. case TextureStage::CS_primary_color: return GL_PRIMARY_COLOR;
  9456. case TextureStage::CS_constant_color_scale: return GL_CONSTANT;
  9457. case TextureStage::CS_previous:
  9458. if (last_stage == this_stage - 1) {
  9459. return GL_PREVIOUS;
  9460. } else if (last_stage == -1) {
  9461. return GL_PRIMARY_COLOR;
  9462. } else if (_supports_texture_saved_result) {
  9463. return GL_TEXTURE0 + last_stage;
  9464. } else {
  9465. GLCAT.warning()
  9466. << "Current OpenGL driver does not support texture crossbar blending.\n";
  9467. return GL_PRIMARY_COLOR;
  9468. }
  9469. case TextureStage::CS_last_saved_result:
  9470. if (last_saved_result == this_stage - 1) {
  9471. return GL_PREVIOUS;
  9472. } else if (last_saved_result == -1) {
  9473. return GL_PRIMARY_COLOR;
  9474. } else if (_supports_texture_saved_result) {
  9475. return GL_TEXTURE0 + last_saved_result;
  9476. } else {
  9477. GLCAT.warning()
  9478. << "Current OpenGL driver does not support texture crossbar blending.\n";
  9479. return GL_PRIMARY_COLOR;
  9480. }
  9481. }
  9482. GLCAT.error()
  9483. << "Invalid TextureStage::CombineSource value" << endl;
  9484. #endif
  9485. return GL_TEXTURE;
  9486. }
  9487. /**
  9488. * Maps from the texture stage's CombineOperand types to the corresponding
  9489. * OpenGL ids
  9490. */
  9491. GLint CLP(GraphicsStateGuardian)::
  9492. get_texture_operand_type(TextureStage::CombineOperand co) {
  9493. switch (co) {
  9494. case TextureStage::CO_undefined: // fall through
  9495. case TextureStage::CO_src_alpha: return GL_SRC_ALPHA;
  9496. case TextureStage::CO_one_minus_src_alpha: return GL_ONE_MINUS_SRC_ALPHA;
  9497. case TextureStage::CO_src_color: return GL_SRC_COLOR;
  9498. case TextureStage::CO_one_minus_src_color: return GL_ONE_MINUS_SRC_COLOR;
  9499. }
  9500. GLCAT.error()
  9501. << "Invalid TextureStage::CombineOperand value" << endl;
  9502. return GL_SRC_COLOR;
  9503. }
  9504. #ifdef SUPPORT_FIXED_FUNCTION
  9505. /**
  9506. * Maps from the fog types to gl version
  9507. */
  9508. GLenum CLP(GraphicsStateGuardian)::
  9509. get_fog_mode_type(Fog::Mode m) {
  9510. switch(m) {
  9511. case Fog::M_linear: return GL_LINEAR;
  9512. case Fog::M_exponential: return GL_EXP;
  9513. case Fog::M_exponential_squared: return GL_EXP2;
  9514. /*
  9515. case Fog::M_spline: return GL_FOG_FUNC_SGIS;
  9516. */
  9517. default:
  9518. GLCAT.error() << "Invalid Fog::Mode value" << endl;
  9519. return GL_EXP;
  9520. }
  9521. }
  9522. #endif
  9523. /**
  9524. * Maps from ColorBlendAttrib::Mode to glBlendEquation value.
  9525. */
  9526. GLenum CLP(GraphicsStateGuardian)::
  9527. get_blend_equation_type(ColorBlendAttrib::Mode mode) {
  9528. switch (mode) {
  9529. case ColorBlendAttrib::M_none:
  9530. case ColorBlendAttrib::M_add:
  9531. return GL_FUNC_ADD;
  9532. case ColorBlendAttrib::M_subtract:
  9533. return GL_FUNC_SUBTRACT;
  9534. case ColorBlendAttrib::M_inv_subtract:
  9535. return GL_FUNC_REVERSE_SUBTRACT;
  9536. #ifdef OPENGLES
  9537. case ColorBlendAttrib::M_min:
  9538. return GL_MIN_EXT;
  9539. case ColorBlendAttrib::M_max:
  9540. return GL_MAX_EXT;
  9541. #else
  9542. case ColorBlendAttrib::M_min:
  9543. return GL_MIN;
  9544. case ColorBlendAttrib::M_max:
  9545. return GL_MAX;
  9546. #endif
  9547. }
  9548. GLCAT.error()
  9549. << "Unknown color blend mode " << (int)mode << endl;
  9550. return GL_FUNC_ADD;
  9551. }
  9552. /**
  9553. * Maps from ColorBlendAttrib::Operand to glBlendFunc value.
  9554. */
  9555. GLenum CLP(GraphicsStateGuardian)::
  9556. get_blend_func(ColorBlendAttrib::Operand operand) {
  9557. switch (operand) {
  9558. case ColorBlendAttrib::O_zero:
  9559. return GL_ZERO;
  9560. case ColorBlendAttrib::O_one:
  9561. return GL_ONE;
  9562. case ColorBlendAttrib::O_incoming_color:
  9563. return GL_SRC_COLOR;
  9564. case ColorBlendAttrib::O_one_minus_incoming_color:
  9565. return GL_ONE_MINUS_SRC_COLOR;
  9566. case ColorBlendAttrib::O_fbuffer_color:
  9567. return GL_DST_COLOR;
  9568. case ColorBlendAttrib::O_one_minus_fbuffer_color:
  9569. return GL_ONE_MINUS_DST_COLOR;
  9570. case ColorBlendAttrib::O_incoming_alpha:
  9571. return GL_SRC_ALPHA;
  9572. case ColorBlendAttrib::O_one_minus_incoming_alpha:
  9573. return GL_ONE_MINUS_SRC_ALPHA;
  9574. case ColorBlendAttrib::O_fbuffer_alpha:
  9575. return GL_DST_ALPHA;
  9576. case ColorBlendAttrib::O_one_minus_fbuffer_alpha:
  9577. return GL_ONE_MINUS_DST_ALPHA;
  9578. #ifdef OPENGLES_1
  9579. // OpenGL ES 1 has no constant blend factor.
  9580. case ColorBlendAttrib::O_constant_color:
  9581. case ColorBlendAttrib::O_color_scale:
  9582. case ColorBlendAttrib::O_one_minus_constant_color:
  9583. case ColorBlendAttrib::O_one_minus_color_scale:
  9584. case ColorBlendAttrib::O_constant_alpha:
  9585. case ColorBlendAttrib::O_alpha_scale:
  9586. case ColorBlendAttrib::O_one_minus_constant_alpha:
  9587. case ColorBlendAttrib::O_one_minus_alpha_scale:
  9588. break;
  9589. // No dual-source blending, either.
  9590. case ColorBlendAttrib::O_incoming1_color:
  9591. case ColorBlendAttrib::O_one_minus_incoming1_color:
  9592. case ColorBlendAttrib::O_incoming1_alpha:
  9593. case ColorBlendAttrib::O_one_minus_incoming1_alpha:
  9594. break;
  9595. #else
  9596. case ColorBlendAttrib::O_constant_color:
  9597. case ColorBlendAttrib::O_color_scale:
  9598. return GL_CONSTANT_COLOR;
  9599. case ColorBlendAttrib::O_one_minus_constant_color:
  9600. case ColorBlendAttrib::O_one_minus_color_scale:
  9601. return GL_ONE_MINUS_CONSTANT_COLOR;
  9602. case ColorBlendAttrib::O_constant_alpha:
  9603. case ColorBlendAttrib::O_alpha_scale:
  9604. return GL_CONSTANT_ALPHA;
  9605. case ColorBlendAttrib::O_one_minus_constant_alpha:
  9606. case ColorBlendAttrib::O_one_minus_alpha_scale:
  9607. return GL_ONE_MINUS_CONSTANT_ALPHA;
  9608. case ColorBlendAttrib::O_incoming1_color:
  9609. return GL_SRC1_COLOR;
  9610. case ColorBlendAttrib::O_one_minus_incoming1_color:
  9611. return GL_ONE_MINUS_SRC1_COLOR;
  9612. case ColorBlendAttrib::O_incoming1_alpha:
  9613. return GL_SRC1_ALPHA;
  9614. case ColorBlendAttrib::O_one_minus_incoming1_alpha:
  9615. return GL_ONE_MINUS_SRC1_ALPHA;
  9616. #endif
  9617. case ColorBlendAttrib::O_incoming_color_saturate:
  9618. return GL_SRC_ALPHA_SATURATE;
  9619. }
  9620. GLCAT.error()
  9621. << "Unknown color blend operand " << (int)operand << endl;
  9622. return GL_ZERO;
  9623. }
  9624. /**
  9625. * Maps from UsageHint to the GL symbol.
  9626. */
  9627. GLenum CLP(GraphicsStateGuardian)::
  9628. get_usage(Geom::UsageHint usage_hint) {
  9629. switch (usage_hint) {
  9630. case Geom::UH_stream:
  9631. #ifdef OPENGLES_1
  9632. return GL_DYNAMIC_DRAW;
  9633. #else
  9634. return GL_STREAM_DRAW;
  9635. #endif // OPENGLES
  9636. case Geom::UH_static:
  9637. case Geom::UH_unspecified:
  9638. return GL_STATIC_DRAW;
  9639. case Geom::UH_dynamic:
  9640. return GL_DYNAMIC_DRAW;
  9641. case Geom::UH_client:
  9642. break;
  9643. }
  9644. GLCAT.error()
  9645. << "Unexpected usage_hint " << (int)usage_hint << endl;
  9646. return GL_STATIC_DRAW;
  9647. }
  9648. #ifndef NDEBUG
  9649. /**
  9650. * Returns a string describing an compression format.
  9651. */
  9652. const char *CLP(GraphicsStateGuardian)::
  9653. get_compressed_format_string(GLenum format) {
  9654. switch (format) {
  9655. case 0x83F0: return "GL_COMPRESSED_RGB_S3TC_DXT1_EXT";
  9656. case 0x83F1: return "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT";
  9657. case 0x83F2: return "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT";
  9658. case 0x83F3: return "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT";
  9659. case 0x86B0: return "GL_COMPRESSED_RGB_FXT1_3DFX";
  9660. case 0x86B1: return "GL_COMPRESSED_RGBA_FXT1_3DFX";
  9661. case 0x88EE: return "GL_ETC1_SRGB8_NV";
  9662. case 0x8A54: return "GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT";
  9663. case 0x8A55: return "GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT";
  9664. case 0x8A56: return "GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT";
  9665. case 0x8A57: return "GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT";
  9666. case 0x8B90: return "GL_PALETTE4_RGB8_OES";
  9667. case 0x8B91: return "GL_PALETTE4_RGBA8_OES";
  9668. case 0x8B92: return "GL_PALETTE4_R5_G6_B5_OES";
  9669. case 0x8B93: return "GL_PALETTE4_RGBA4_OES";
  9670. case 0x8B94: return "GL_PALETTE4_RGB5_A1_OES";
  9671. case 0x8B95: return "GL_PALETTE8_RGB8_OES";
  9672. case 0x8B96: return "GL_PALETTE8_RGBA8_OES";
  9673. case 0x8B97: return "GL_PALETTE8_R5_G6_B5_OES";
  9674. case 0x8B98: return "GL_PALETTE8_RGBA4_OES";
  9675. case 0x8B99: return "GL_PALETTE8_RGB5_A1_OES";
  9676. case 0x8C00: return "GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG";
  9677. case 0x8C01: return "GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG";
  9678. case 0x8C02: return "GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG";
  9679. case 0x8C03: return "GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG";
  9680. case 0x8C48: return "GL_COMPRESSED_SRGB_EXT";
  9681. case 0x8C49: return "GL_COMPRESSED_SRGB_ALPHA_EXT";
  9682. case 0x8C4A: return "GL_COMPRESSED_SLUMINANCE_EXT";
  9683. case 0x8C4B: return "GL_COMPRESSED_SLUMINANCE_ALPHA_EXT";
  9684. case 0x8C4C: return "GL_COMPRESSED_SRGB_S3TC_DXT1_EXT";
  9685. case 0x8C4D: return "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT";
  9686. case 0x8C4E: return "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT";
  9687. case 0x8C4F: return "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT";
  9688. case 0x8C70: return "GL_COMPRESSED_LUMINANCE_LATC1_EXT";
  9689. case 0x8C71: return "GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT";
  9690. case 0x8C72: return "GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT";
  9691. case 0x8C73: return "GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT";
  9692. case 0x8D64: return "GL_ETC1_RGB8_OES";
  9693. case 0x8DBB: return "GL_COMPRESSED_RED_RGTC1";
  9694. case 0x8DBC: return "GL_COMPRESSED_SIGNED_RED_RGTC1";
  9695. case 0x8DBD: return "GL_COMPRESSED_RG_RGTC2";
  9696. case 0x8DBE: return "GL_COMPRESSED_SIGNED_RG_RGTC2";
  9697. case 0x8E8C: return "GL_COMPRESSED_RGBA_BPTC_UNORM";
  9698. case 0x8E8D: return "GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM";
  9699. case 0x8E8E: return "GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT";
  9700. case 0x8E8F: return "GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT";
  9701. case 0x9137: return "GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG";
  9702. case 0x9138: return "GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG";
  9703. case 0x9270: return "GL_COMPRESSED_R11_EAC";
  9704. case 0x9271: return "GL_COMPRESSED_SIGNED_R11_EAC";
  9705. case 0x9272: return "GL_COMPRESSED_RG11_EAC";
  9706. case 0x9273: return "GL_COMPRESSED_SIGNED_RG11_EAC";
  9707. case 0x9274: return "GL_COMPRESSED_RGB8_ETC2";
  9708. case 0x9275: return "GL_COMPRESSED_SRGB8_ETC2";
  9709. case 0x9276: return "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2";
  9710. case 0x9277: return "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2";
  9711. case 0x9278: return "GL_COMPRESSED_RGBA8_ETC2_EAC";
  9712. case 0x9279: return "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC";
  9713. case 0x93B0: return "GL_COMPRESSED_RGBA_ASTC_4x4_KHR";
  9714. case 0x93B1: return "GL_COMPRESSED_RGBA_ASTC_5x4_KHR";
  9715. case 0x93B2: return "GL_COMPRESSED_RGBA_ASTC_5x5_KHR";
  9716. case 0x93B3: return "GL_COMPRESSED_RGBA_ASTC_6x5_KHR";
  9717. case 0x93B4: return "GL_COMPRESSED_RGBA_ASTC_6x6_KHR";
  9718. case 0x93B5: return "GL_COMPRESSED_RGBA_ASTC_8x5_KHR";
  9719. case 0x93B6: return "GL_COMPRESSED_RGBA_ASTC_8x6_KHR";
  9720. case 0x93B7: return "GL_COMPRESSED_RGBA_ASTC_8x8_KHR";
  9721. case 0x93B8: return "GL_COMPRESSED_RGBA_ASTC_10x5_KHR";
  9722. case 0x93B9: return "GL_COMPRESSED_RGBA_ASTC_10x6_KHR";
  9723. case 0x93BA: return "GL_COMPRESSED_RGBA_ASTC_10x8_KHR";
  9724. case 0x93BB: return "GL_COMPRESSED_RGBA_ASTC_10x10_KHR";
  9725. case 0x93BC: return "GL_COMPRESSED_RGBA_ASTC_12x10_KHR";
  9726. case 0x93BD: return "GL_COMPRESSED_RGBA_ASTC_12x12_KHR";
  9727. case 0x93C0: return "GL_COMPRESSED_RGBA_ASTC_3x3x3_OES";
  9728. case 0x93C1: return "GL_COMPRESSED_RGBA_ASTC_4x3x3_OES";
  9729. case 0x93C2: return "GL_COMPRESSED_RGBA_ASTC_4x4x3_OES";
  9730. case 0x93C3: return "GL_COMPRESSED_RGBA_ASTC_4x4x4_OES";
  9731. case 0x93C4: return "GL_COMPRESSED_RGBA_ASTC_5x4x4_OES";
  9732. case 0x93C5: return "GL_COMPRESSED_RGBA_ASTC_5x5x4_OES";
  9733. case 0x93C6: return "GL_COMPRESSED_RGBA_ASTC_5x5x5_OES";
  9734. case 0x93C7: return "GL_COMPRESSED_RGBA_ASTC_6x5x5_OES";
  9735. case 0x93C8: return "GL_COMPRESSED_RGBA_ASTC_6x6x5_OES";
  9736. case 0x93C9: return "GL_COMPRESSED_RGBA_ASTC_6x6x6_OES";
  9737. case 0x93D0: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR";
  9738. case 0x93D1: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR";
  9739. case 0x93D2: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR";
  9740. case 0x93D3: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR";
  9741. case 0x93D4: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR";
  9742. case 0x93D5: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR";
  9743. case 0x93D6: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR";
  9744. case 0x93D7: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR";
  9745. case 0x93D8: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR";
  9746. case 0x93D9: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR";
  9747. case 0x93DA: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR";
  9748. case 0x93DB: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR";
  9749. case 0x93DC: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR";
  9750. case 0x93DD: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR";
  9751. case 0x93E0: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES";
  9752. case 0x93E1: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES";
  9753. case 0x93E2: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES";
  9754. case 0x93E3: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES";
  9755. case 0x93E4: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES";
  9756. case 0x93E5: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES";
  9757. case 0x93E6: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES";
  9758. case 0x93E7: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES";
  9759. case 0x93E8: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES";
  9760. case 0x93E9: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES";
  9761. case 0x93F0: return "GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG";
  9762. case 0x93F1: return "GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG";
  9763. default:
  9764. return nullptr;
  9765. }
  9766. }
  9767. #endif
  9768. /**
  9769. * Returns the value that that should be issued as the light's color, as
  9770. * scaled by the current value of _light_color_scale, in the case of
  9771. * color_scale_via_lighting.
  9772. */
  9773. LVecBase4 CLP(GraphicsStateGuardian)::
  9774. get_light_color(Light *light) const {
  9775. #ifndef NDEBUG
  9776. if (_show_texture_usage) {
  9777. // In show_texture_usage mode, all lights are white, so as not to
  9778. // contaminate the texture color.
  9779. return LVecBase4(1.0, 1.0, 1.0, 1.0);
  9780. }
  9781. #endif // NDEBUG
  9782. const LColor &c = light->get_color();
  9783. LVecBase4 light_color(c[0] * _light_color_scale[0],
  9784. c[1] * _light_color_scale[1],
  9785. c[2] * _light_color_scale[2],
  9786. c[3] * _light_color_scale[3]);
  9787. return light_color;
  9788. }
  9789. /**
  9790. * Called by clear_state_and_transform() to ensure that the current modelview
  9791. * and projection matrices are properly loaded in the graphics state, after a
  9792. * callback might have mucked them up.
  9793. */
  9794. void CLP(GraphicsStateGuardian)::
  9795. reissue_transforms() {
  9796. prepare_lens();
  9797. do_issue_transform();
  9798. _active_texture_stage = -1;
  9799. #ifndef OPENGLES_1
  9800. // Might also want to reissue the vertex format, for good measure.
  9801. _current_vertex_format.clear();
  9802. memset(_vertex_attrib_columns, 0, sizeof(const GeomVertexColumn *) * 32);
  9803. #endif
  9804. // Some libraries (Kivy) leave their buffers bound. How clumsy of them.
  9805. if (_supports_buffers) {
  9806. _glBindBuffer(GL_ARRAY_BUFFER, 0);
  9807. _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  9808. _current_vbuffer_index = 0;
  9809. _current_ibuffer_index = 0;
  9810. }
  9811. #ifndef OPENGLES
  9812. if (_supports_glsl) {
  9813. _glDisableVertexAttribArray(0);
  9814. _glDisableVertexAttribArray(1);
  9815. }
  9816. #endif
  9817. // Since this is called by clear_state_and_transform(), we also should reset
  9818. // the states that won't automatically be respecified when clearing the
  9819. // state mask.
  9820. _active_color_write_mask = ColorWriteAttrib::C_all;
  9821. glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  9822. if (_dithering_enabled) {
  9823. glEnable(GL_DITHER);
  9824. } else {
  9825. glDisable(GL_DITHER);
  9826. }
  9827. if (_depth_test_enabled) {
  9828. glEnable(GL_DEPTH_TEST);
  9829. } else {
  9830. glDisable(GL_DEPTH_TEST);
  9831. }
  9832. if (_stencil_test_enabled) {
  9833. glEnable(GL_STENCIL_TEST);
  9834. } else {
  9835. glDisable(GL_STENCIL_TEST);
  9836. }
  9837. if (_blend_enabled) {
  9838. glEnable(GL_BLEND);
  9839. } else {
  9840. glDisable(GL_BLEND);
  9841. }
  9842. #ifndef OPENGLES_2
  9843. if (_multisample_mode != 0) {
  9844. glEnable(GL_MULTISAMPLE);
  9845. } else {
  9846. glDisable(GL_MULTISAMPLE);
  9847. glDisable(GL_SAMPLE_ALPHA_TO_ONE);
  9848. glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
  9849. }
  9850. if (_line_smooth_enabled) {
  9851. glEnable(GL_LINE_SMOOTH);
  9852. } else {
  9853. glDisable(GL_LINE_SMOOTH);
  9854. }
  9855. #endif
  9856. #ifndef OPENGLES
  9857. if (_polygon_smooth_enabled) {
  9858. glEnable(GL_POLYGON_SMOOTH);
  9859. } else {
  9860. glDisable(GL_POLYGON_SMOOTH);
  9861. }
  9862. #endif
  9863. #ifdef SUPPORT_FIXED_FUNCTION
  9864. if (has_fixed_function_pipeline()) {
  9865. if (_alpha_test_enabled) {
  9866. glEnable(GL_ALPHA_TEST);
  9867. } else {
  9868. glDisable(GL_ALPHA_TEST);
  9869. }
  9870. if (_point_smooth_enabled) {
  9871. glEnable(GL_POINT_SMOOTH);
  9872. } else {
  9873. glDisable(GL_POINT_SMOOTH);
  9874. }
  9875. }
  9876. #endif
  9877. }
  9878. #ifdef SUPPORT_FIXED_FUNCTION
  9879. /**
  9880. * Intended to be overridden by a derived class to enable or disable the use
  9881. * of lighting overall. This is called by do_issue_light() according to
  9882. * whether any lights are in use or not.
  9883. */
  9884. void CLP(GraphicsStateGuardian)::
  9885. enable_lighting(bool enable) {
  9886. nassertv(has_fixed_function_pipeline());
  9887. // static PStatCollector
  9888. // _draw_set_state_light_enable_lighting_pcollector("Draw:Set
  9889. // State:Light:Enable lighting"); PStatGPUTimer timer(this,
  9890. // _draw_set_state_light_enable_lighting_pcollector);
  9891. if (enable) {
  9892. glEnable(GL_LIGHTING);
  9893. } else {
  9894. glDisable(GL_LIGHTING);
  9895. }
  9896. }
  9897. #endif // SUPPORT_FIXED_FUNCTION
  9898. #ifdef SUPPORT_FIXED_FUNCTION
  9899. /**
  9900. * Intended to be overridden by a derived class to indicate the color of the
  9901. * ambient light that should be in effect. This is called by do_issue_light()
  9902. * after all other lights have been enabled or disabled.
  9903. */
  9904. void CLP(GraphicsStateGuardian)::
  9905. set_ambient_light(const LColor &color) {
  9906. nassertv(has_fixed_function_pipeline());
  9907. // static PStatCollector _draw_set_state_light_ambient_pcollector("Draw:Set
  9908. // State:Light:Ambient"); PStatGPUTimer timer(this,
  9909. // _draw_set_state_light_ambient_pcollector);
  9910. LColor c = color;
  9911. c.set(c[0] * _light_color_scale[0],
  9912. c[1] * _light_color_scale[1],
  9913. c[2] * _light_color_scale[2],
  9914. c[3] * _light_color_scale[3]);
  9915. call_glLightModelfv(GL_LIGHT_MODEL_AMBIENT, c);
  9916. }
  9917. #endif // SUPPORT_FIXED_FUNCTION
  9918. #ifdef SUPPORT_FIXED_FUNCTION
  9919. /**
  9920. * Intended to be overridden by a derived class to enable the indicated light
  9921. * id. A specific Light will already have been bound to this id via
  9922. * bind_light().
  9923. */
  9924. void CLP(GraphicsStateGuardian)::
  9925. enable_light(int light_id, bool enable) {
  9926. nassertv(has_fixed_function_pipeline());
  9927. // static PStatCollector
  9928. // _draw_set_state_light_enable_light_pcollector("Draw:Set
  9929. // State:Light:Enable light"); PStatGPUTimer timer(this,
  9930. // _draw_set_state_light_enable_light_pcollector);
  9931. if (enable) {
  9932. glEnable(get_light_id(light_id));
  9933. } else {
  9934. glDisable(get_light_id(light_id));
  9935. }
  9936. }
  9937. #endif // SUPPORT_FIXED_FUNCTION
  9938. #ifdef SUPPORT_FIXED_FUNCTION
  9939. /**
  9940. * Called immediately before bind_light() is called, this is intended to
  9941. * provide the derived class a hook in which to set up some state (like
  9942. * transform) that might apply to several lights.
  9943. *
  9944. * The sequence is: begin_bind_lights() will be called, then one or more
  9945. * bind_light() calls, then end_bind_lights().
  9946. */
  9947. void CLP(GraphicsStateGuardian)::
  9948. begin_bind_lights() {
  9949. nassertv(has_fixed_function_pipeline());
  9950. // static PStatCollector
  9951. // _draw_set_state_light_begin_bind_pcollector("Draw:Set State:Light:Begin
  9952. // bind"); PStatGPUTimer timer(this,
  9953. // _draw_set_state_light_begin_bind_pcollector);
  9954. // We need to temporarily load a new matrix so we can define the light in a
  9955. // known coordinate system. We pick the transform of the root.
  9956. // (Alternatively, we could leave the current transform where it is and
  9957. // compute the light position relative to that transform instead of relative
  9958. // to the root, by composing with the matrix computed by
  9959. // _internal_transform->invert_compose(render_transform). But I think
  9960. // loading a completely new matrix is simpler.)
  9961. CPT(TransformState) render_transform =
  9962. _cs_transform->compose(_scene_setup->get_world_transform());
  9963. glMatrixMode(GL_MODELVIEW);
  9964. glPushMatrix();
  9965. call_glLoadMatrix(render_transform->get_mat());
  9966. }
  9967. #endif // SUPPORT_FIXED_FUNCTION
  9968. #ifdef SUPPORT_FIXED_FUNCTION
  9969. /**
  9970. * Called after before bind_light() has been called one or more times (but
  9971. * before any geometry is issued or additional state is changed), this is
  9972. * intended to clean up any temporary changes to the state that may have been
  9973. * made by begin_bind_lights().
  9974. */
  9975. void CLP(GraphicsStateGuardian)::
  9976. end_bind_lights() {
  9977. nassertv(has_fixed_function_pipeline());
  9978. // static PStatCollector _draw_set_state_light_end_bind_pcollector("Draw:Set
  9979. // State:Light:End bind"); PStatGPUTimer timer(this,
  9980. // _draw_set_state_light_end_bind_pcollector);
  9981. glMatrixMode(GL_MODELVIEW);
  9982. glPopMatrix();
  9983. }
  9984. #endif // SUPPORT_FIXED_FUNCTION
  9985. #ifdef SUPPORT_FIXED_FUNCTION
  9986. /**
  9987. * Intended to be overridden by a derived class to enable the indicated
  9988. * clip_plane id. A specific PlaneNode will already have been bound to this
  9989. * id via bind_clip_plane().
  9990. */
  9991. void CLP(GraphicsStateGuardian)::
  9992. enable_clip_plane(int plane_id, bool enable) {
  9993. nassertv(has_fixed_function_pipeline());
  9994. if (enable) {
  9995. glEnable(get_clip_plane_id(plane_id));
  9996. } else {
  9997. glDisable(get_clip_plane_id(plane_id));
  9998. }
  9999. }
  10000. #endif // SUPPORT_FIXED_FUNCTION
  10001. #ifdef SUPPORT_FIXED_FUNCTION
  10002. /**
  10003. * Called immediately before bind_clip_plane() is called, this is intended to
  10004. * provide the derived class a hook in which to set up some state (like
  10005. * transform) that might apply to several clip_planes.
  10006. *
  10007. * The sequence is: begin_bind_clip_planes() will be called, then one or more
  10008. * bind_clip_plane() calls, then end_bind_clip_planes().
  10009. */
  10010. void CLP(GraphicsStateGuardian)::
  10011. begin_bind_clip_planes() {
  10012. nassertv(has_fixed_function_pipeline());
  10013. // We need to temporarily load a new matrix so we can define the clip_plane
  10014. // in a known coordinate system. We pick the transform of the root.
  10015. // (Alternatively, we could leave the current transform where it is and
  10016. // compute the clip_plane position relative to that transform instead of
  10017. // relative to the root, by composing with the matrix computed by
  10018. // _internal_transform->invert_compose(render_transform). But I think
  10019. // loading a completely new matrix is simpler.)
  10020. CPT(TransformState) render_transform =
  10021. _cs_transform->compose(_scene_setup->get_world_transform());
  10022. glMatrixMode(GL_MODELVIEW);
  10023. glPushMatrix();
  10024. call_glLoadMatrix(render_transform->get_mat());
  10025. }
  10026. #endif // SUPPORT_FIXED_FUNCTION
  10027. #ifdef SUPPORT_FIXED_FUNCTION
  10028. /**
  10029. * Called the first time a particular clip_plane has been bound to a given id
  10030. * within a frame, this should set up the associated hardware clip_plane with
  10031. * the clip_plane's properties.
  10032. */
  10033. void CLP(GraphicsStateGuardian)::
  10034. bind_clip_plane(const NodePath &plane, int plane_id) {
  10035. nassertv(has_fixed_function_pipeline());
  10036. GLenum id = get_clip_plane_id(plane_id);
  10037. CPT(TransformState) transform = plane.get_transform(_scene_setup->get_scene_root().get_parent());
  10038. const PlaneNode *plane_node;
  10039. DCAST_INTO_V(plane_node, plane.node());
  10040. LPlane xformed_plane = plane_node->get_plane() * transform->get_mat();
  10041. #ifdef OPENGLES
  10042. // OpenGL ES uses a single-precision call.
  10043. LPlanef single_plane(LCAST(float, xformed_plane));
  10044. glClipPlanef(id, single_plane.get_data());
  10045. #else
  10046. // Mainline OpenGL uses a double-precision call.
  10047. LPlaned double_plane(LCAST(double, xformed_plane));
  10048. glClipPlane(id, double_plane.get_data());
  10049. #endif // OPENGLES
  10050. report_my_gl_errors();
  10051. }
  10052. #endif // SUPPORT_FIXED_FUNCTION
  10053. #ifdef SUPPORT_FIXED_FUNCTION
  10054. /**
  10055. * Called after before bind_clip_plane() has been called one or more times
  10056. * (but before any geometry is issued or additional state is changed), this is
  10057. * intended to clean up any temporary changes to the state that may have been
  10058. * made by begin_bind_clip_planes().
  10059. */
  10060. void CLP(GraphicsStateGuardian)::
  10061. end_bind_clip_planes() {
  10062. nassertv(has_fixed_function_pipeline());
  10063. glMatrixMode(GL_MODELVIEW);
  10064. glPopMatrix();
  10065. }
  10066. #endif // SUPPORT_FIXED_FUNCTION
  10067. /**
  10068. * Simultaneously resets the render state and the transform state.
  10069. *
  10070. * This transform specified is the "internal" net transform, already converted
  10071. * into the GSG's internal coordinate space by composing it to
  10072. * get_cs_transform(). (Previously, this used to be the "external" net
  10073. * transform, with the assumption that that GSG would convert it internally,
  10074. * but that is no longer the case.)
  10075. *
  10076. * Special case: if (state==NULL), then the target state is already stored in
  10077. * _target.
  10078. */
  10079. void CLP(GraphicsStateGuardian)::
  10080. set_state_and_transform(const RenderState *target,
  10081. const TransformState *transform) {
  10082. report_my_gl_errors();
  10083. #ifndef NDEBUG
  10084. if (gsg_cat.is_spam()) {
  10085. gsg_cat.spam() << "Setting GSG state to " << (void *)target << ":\n";
  10086. target->write(gsg_cat.spam(false), 2);
  10087. }
  10088. #endif
  10089. _state_pcollector.add_level(1);
  10090. PStatGPUTimer timer1(this, _draw_set_state_pcollector);
  10091. if (transform != _internal_transform) {
  10092. // PStatGPUTimer timer(this, _draw_set_state_transform_pcollector);
  10093. _transform_state_pcollector.add_level(1);
  10094. _internal_transform = transform;
  10095. do_issue_transform();
  10096. }
  10097. //XXX the _inv_state_mask system does not appear to be used at the moment.
  10098. //if (target == _state_rs && (_state_mask | _inv_state_mask).is_all_on()) {
  10099. // return;
  10100. //}
  10101. _target_rs = target;
  10102. #ifndef OPENGLES_1
  10103. determine_target_shader();
  10104. _instance_count = _target_shader->get_instance_count();
  10105. if (_target_shader != _state_shader) {
  10106. do_issue_shader();
  10107. _state_shader = _target_shader;
  10108. _state_mask.clear_bit(TextureAttrib::get_class_slot());
  10109. }
  10110. else if (!has_fixed_function_pipeline() && _current_shader == nullptr) { // In the case of OpenGL ES 2.x, we need to glUseShader before we draw anything.
  10111. do_issue_shader();
  10112. _state_mask.clear_bit(TextureAttrib::get_class_slot());
  10113. }
  10114. // Update all of the state that is bound to the shader program.
  10115. if (_current_shader_context != nullptr) {
  10116. _current_shader_context->set_state_and_transform(target, transform, _scene_setup->get_camera_transform(), _projection_mat);
  10117. }
  10118. #endif
  10119. #ifdef SUPPORT_FIXED_FUNCTION
  10120. if (has_fixed_function_pipeline()) {
  10121. int alpha_test_slot = AlphaTestAttrib::get_class_slot();
  10122. if (_target_rs->get_attrib(alpha_test_slot) != _state_rs->get_attrib(alpha_test_slot) ||
  10123. !_state_mask.get_bit(alpha_test_slot)
  10124. #ifndef OPENGLES_1
  10125. || (_target_shader->get_flag(ShaderAttrib::F_subsume_alpha_test) !=
  10126. _state_shader->get_flag(ShaderAttrib::F_subsume_alpha_test))
  10127. #endif
  10128. ) {
  10129. // PStatGPUTimer timer(this, _draw_set_state_alpha_test_pcollector);
  10130. do_issue_alpha_test();
  10131. _state_mask.set_bit(alpha_test_slot);
  10132. }
  10133. }
  10134. #endif
  10135. int antialias_slot = AntialiasAttrib::get_class_slot();
  10136. if (_target_rs->get_attrib(antialias_slot) != _state_rs->get_attrib(antialias_slot) ||
  10137. !_state_mask.get_bit(antialias_slot)) {
  10138. // PStatGPUTimer timer(this, _draw_set_state_antialias_pcollector);
  10139. do_issue_antialias();
  10140. _state_mask.set_bit(antialias_slot);
  10141. }
  10142. int clip_plane_slot = ClipPlaneAttrib::get_class_slot();
  10143. if (_target_rs->get_attrib(clip_plane_slot) != _state_rs->get_attrib(clip_plane_slot) ||
  10144. !_state_mask.get_bit(clip_plane_slot)) {
  10145. // PStatGPUTimer timer(this, _draw_set_state_clip_plane_pcollector);
  10146. do_issue_clip_plane();
  10147. _state_mask.set_bit(clip_plane_slot);
  10148. }
  10149. int color_slot = ColorAttrib::get_class_slot();
  10150. int color_scale_slot = ColorScaleAttrib::get_class_slot();
  10151. if (_target_rs->get_attrib(color_slot) != _state_rs->get_attrib(color_slot) ||
  10152. _target_rs->get_attrib(color_scale_slot) != _state_rs->get_attrib(color_scale_slot) ||
  10153. !_state_mask.get_bit(color_slot) ||
  10154. !_state_mask.get_bit(color_scale_slot)) {
  10155. // PStatGPUTimer timer(this, _draw_set_state_color_pcollector);
  10156. do_issue_color();
  10157. do_issue_color_scale();
  10158. _state_mask.set_bit(color_slot);
  10159. _state_mask.set_bit(color_scale_slot);
  10160. }
  10161. int cull_face_slot = CullFaceAttrib::get_class_slot();
  10162. if (_target_rs->get_attrib(cull_face_slot) != _state_rs->get_attrib(cull_face_slot) ||
  10163. !_state_mask.get_bit(cull_face_slot)) {
  10164. // PStatGPUTimer timer(this, _draw_set_state_cull_face_pcollector);
  10165. do_issue_cull_face();
  10166. _state_mask.set_bit(cull_face_slot);
  10167. }
  10168. int depth_offset_slot = DepthOffsetAttrib::get_class_slot();
  10169. if (_target_rs->get_attrib(depth_offset_slot) != _state_rs->get_attrib(depth_offset_slot) ||
  10170. !_state_mask.get_bit(depth_offset_slot)) {
  10171. // PStatGPUTimer timer(this, _draw_set_state_depth_offset_pcollector);
  10172. do_issue_depth_offset();
  10173. _state_mask.set_bit(depth_offset_slot);
  10174. }
  10175. int depth_test_slot = DepthTestAttrib::get_class_slot();
  10176. if (_target_rs->get_attrib(depth_test_slot) != _state_rs->get_attrib(depth_test_slot) ||
  10177. !_state_mask.get_bit(depth_test_slot)) {
  10178. // PStatGPUTimer timer(this, _draw_set_state_depth_test_pcollector);
  10179. do_issue_depth_test();
  10180. _state_mask.set_bit(depth_test_slot);
  10181. }
  10182. int depth_write_slot = DepthWriteAttrib::get_class_slot();
  10183. if (_target_rs->get_attrib(depth_write_slot) != _state_rs->get_attrib(depth_write_slot) ||
  10184. !_state_mask.get_bit(depth_write_slot)) {
  10185. // PStatGPUTimer timer(this, _draw_set_state_depth_write_pcollector);
  10186. do_issue_depth_write();
  10187. _state_mask.set_bit(depth_write_slot);
  10188. }
  10189. int render_mode_slot = RenderModeAttrib::get_class_slot();
  10190. if (_target_rs->get_attrib(render_mode_slot) != _state_rs->get_attrib(render_mode_slot) ||
  10191. !_state_mask.get_bit(render_mode_slot)) {
  10192. // PStatGPUTimer timer(this, _draw_set_state_render_mode_pcollector);
  10193. do_issue_render_mode();
  10194. _state_mask.set_bit(render_mode_slot);
  10195. }
  10196. #ifdef SUPPORT_FIXED_FUNCTION
  10197. if (has_fixed_function_pipeline()) {
  10198. int rescale_normal_slot = RescaleNormalAttrib::get_class_slot();
  10199. if (_target_rs->get_attrib(rescale_normal_slot) != _state_rs->get_attrib(rescale_normal_slot) ||
  10200. !_state_mask.get_bit(rescale_normal_slot)) {
  10201. // PStatGPUTimer timer(this, _draw_set_state_rescale_normal_pcollector);
  10202. do_issue_rescale_normal();
  10203. _state_mask.set_bit(rescale_normal_slot);
  10204. }
  10205. int shade_model_slot = ShadeModelAttrib::get_class_slot();
  10206. if (_target_rs->get_attrib(shade_model_slot) != _state_rs->get_attrib(shade_model_slot) ||
  10207. !_state_mask.get_bit(shade_model_slot)) {
  10208. // PStatGPUTimer timer(this, _draw_set_state_shade_model_pcollector);
  10209. do_issue_shade_model();
  10210. _state_mask.set_bit(shade_model_slot);
  10211. }
  10212. }
  10213. #endif
  10214. #if !defined(OPENGLES) || defined(OPENGLES_1)
  10215. int logic_op_slot = LogicOpAttrib::get_class_slot();
  10216. if (_target_rs->get_attrib(logic_op_slot) != _state_rs->get_attrib(logic_op_slot) ||
  10217. !_state_mask.get_bit(logic_op_slot)) {
  10218. // PStatGPUTimer timer(this, _draw_set_state_logic_op_pcollector);
  10219. do_issue_logic_op();
  10220. _state_mask.set_bit(logic_op_slot);
  10221. }
  10222. #endif
  10223. int transparency_slot = TransparencyAttrib::get_class_slot();
  10224. int color_write_slot = ColorWriteAttrib::get_class_slot();
  10225. int color_blend_slot = ColorBlendAttrib::get_class_slot();
  10226. if (_target_rs->get_attrib(transparency_slot) != _state_rs->get_attrib(transparency_slot) ||
  10227. _target_rs->get_attrib(color_write_slot) != _state_rs->get_attrib(color_write_slot) ||
  10228. _target_rs->get_attrib(color_blend_slot) != _state_rs->get_attrib(color_blend_slot) ||
  10229. !_state_mask.get_bit(transparency_slot) ||
  10230. !_state_mask.get_bit(color_write_slot) ||
  10231. !_state_mask.get_bit(color_blend_slot)
  10232. #ifndef OPENGLES_1
  10233. || (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write) !=
  10234. _state_shader->get_flag(ShaderAttrib::F_disable_alpha_write))
  10235. #endif
  10236. ) {
  10237. // PStatGPUTimer timer(this, _draw_set_state_blending_pcollector);
  10238. do_issue_blending();
  10239. _state_mask.set_bit(transparency_slot);
  10240. _state_mask.set_bit(color_write_slot);
  10241. _state_mask.set_bit(color_blend_slot);
  10242. }
  10243. int texture_slot = TextureAttrib::get_class_slot();
  10244. if (_target_rs->get_attrib(texture_slot) != _state_rs->get_attrib(texture_slot) ||
  10245. !_state_mask.get_bit(texture_slot)) {
  10246. PStatGPUTimer timer(this, _draw_set_state_texture_pcollector);
  10247. determine_target_texture();
  10248. do_issue_texture();
  10249. // Since the TexGen and TexMatrix states depend partly on the particular
  10250. // set of textures in use, we should force both of those to be reissued
  10251. // every time we change the texture state.
  10252. _state_mask.clear_bit(TexGenAttrib::get_class_slot());
  10253. _state_mask.clear_bit(TexMatrixAttrib::get_class_slot());
  10254. _state_texture = _target_texture;
  10255. _state_mask.set_bit(texture_slot);
  10256. }
  10257. // If one of the previously-loaded TexGen modes modified the texture matrix,
  10258. // then if either state changed, we have to change both of them now.
  10259. if (_tex_gen_modifies_mat) {
  10260. int tex_gen_slot = TexGenAttrib::get_class_slot();
  10261. int tex_matrix_slot = TexMatrixAttrib::get_class_slot();
  10262. if (_target_rs->get_attrib(tex_gen_slot) != _state_rs->get_attrib(tex_gen_slot) ||
  10263. _target_rs->get_attrib(tex_matrix_slot) != _state_rs->get_attrib(tex_matrix_slot) ||
  10264. !_state_mask.get_bit(tex_gen_slot) ||
  10265. !_state_mask.get_bit(tex_matrix_slot)) {
  10266. _state_mask.clear_bit(tex_gen_slot);
  10267. _state_mask.clear_bit(tex_matrix_slot);
  10268. }
  10269. }
  10270. int tex_matrix_slot = TexMatrixAttrib::get_class_slot();
  10271. if (_target_rs->get_attrib(tex_matrix_slot) != _state_rs->get_attrib(tex_matrix_slot) ||
  10272. !_state_mask.get_bit(tex_matrix_slot)) {
  10273. // PStatGPUTimer timer(this, _draw_set_state_tex_matrix_pcollector);
  10274. #ifdef SUPPORT_FIXED_FUNCTION
  10275. if (has_fixed_function_pipeline()) {
  10276. do_issue_tex_matrix();
  10277. }
  10278. #endif
  10279. _state_mask.set_bit(tex_matrix_slot);
  10280. #ifndef OPENGLES_1
  10281. if (_current_shader_context) {
  10282. _current_shader_context->issue_parameters(Shader::SSD_tex_matrix);
  10283. }
  10284. #endif
  10285. }
  10286. #ifdef SUPPORT_FIXED_FUNCTION
  10287. if (has_fixed_function_pipeline()) {
  10288. int tex_gen_slot = TexGenAttrib::get_class_slot();
  10289. if (_target_tex_gen != _state_tex_gen ||
  10290. !_state_mask.get_bit(tex_gen_slot)) {
  10291. // PStatGPUTimer timer(this, _draw_set_state_tex_gen_pcollector);
  10292. do_issue_tex_gen();
  10293. _state_tex_gen = _target_tex_gen;
  10294. _state_mask.set_bit(tex_gen_slot);
  10295. }
  10296. int material_slot = MaterialAttrib::get_class_slot();
  10297. if (_target_rs->get_attrib(material_slot) != _state_rs->get_attrib(material_slot) ||
  10298. !_state_mask.get_bit(material_slot)) {
  10299. // PStatGPUTimer timer(this, _draw_set_state_material_pcollector);
  10300. do_issue_material();
  10301. _state_mask.set_bit(material_slot);
  10302. }
  10303. int light_slot = LightAttrib::get_class_slot();
  10304. if (_target_rs->get_attrib(light_slot) != _state_rs->get_attrib(light_slot) ||
  10305. !_state_mask.get_bit(light_slot)) {
  10306. // PStatGPUTimer timer(this, _draw_set_state_light_pcollector);
  10307. do_issue_light();
  10308. _state_mask.set_bit(light_slot);
  10309. }
  10310. int fog_slot = FogAttrib::get_class_slot();
  10311. if (_target_rs->get_attrib(fog_slot) != _state_rs->get_attrib(fog_slot) ||
  10312. !_state_mask.get_bit(fog_slot)) {
  10313. // PStatGPUTimer timer(this, _draw_set_state_fog_pcollector);
  10314. do_issue_fog();
  10315. _state_mask.set_bit(fog_slot);
  10316. }
  10317. }
  10318. #endif
  10319. int stencil_slot = StencilAttrib::get_class_slot();
  10320. if (_target_rs->get_attrib(stencil_slot) != _state_rs->get_attrib(stencil_slot) ||
  10321. !_state_mask.get_bit(stencil_slot)) {
  10322. // PStatGPUTimer timer(this, _draw_set_state_stencil_pcollector);
  10323. do_issue_stencil();
  10324. _state_mask.set_bit(stencil_slot);
  10325. }
  10326. int scissor_slot = ScissorAttrib::get_class_slot();
  10327. if (_target_rs->get_attrib(scissor_slot) != _state_rs->get_attrib(scissor_slot) ||
  10328. !_state_mask.get_bit(scissor_slot)) {
  10329. // PStatGPUTimer timer(this, _draw_set_state_scissor_pcollector);
  10330. do_issue_scissor();
  10331. _state_mask.set_bit(scissor_slot);
  10332. }
  10333. _state_rs = _target_rs;
  10334. maybe_gl_finish();
  10335. report_my_gl_errors();
  10336. }
  10337. /**
  10338. * Frees some memory that was explicitly allocated within the glgsg.
  10339. */
  10340. void CLP(GraphicsStateGuardian)::
  10341. free_pointers() {
  10342. #if defined(HAVE_CG) && !defined(OPENGLES)
  10343. if (_cg_context != 0) {
  10344. cgDestroyContext(_cg_context);
  10345. _cg_context = 0;
  10346. }
  10347. #endif
  10348. }
  10349. /**
  10350. * This is called by set_state_and_transform() when the texture state has
  10351. * changed.
  10352. */
  10353. void CLP(GraphicsStateGuardian)::
  10354. do_issue_texture() {
  10355. DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
  10356. #ifdef OPENGLES_1
  10357. update_standard_texture_bindings();
  10358. #else
  10359. if (_current_shader_context == 0) {
  10360. // No shader, or a non-Cg shader.
  10361. if (_texture_binding_shader_context != 0) {
  10362. _texture_binding_shader_context->disable_shader_texture_bindings();
  10363. }
  10364. #ifdef SUPPORT_FIXED_FUNCTION
  10365. if (has_fixed_function_pipeline()) {
  10366. update_standard_texture_bindings();
  10367. }
  10368. #endif
  10369. } else {
  10370. if (_texture_binding_shader_context == 0) {
  10371. #ifdef SUPPORT_FIXED_FUNCTION
  10372. if (has_fixed_function_pipeline()) {
  10373. disable_standard_texture_bindings();
  10374. }
  10375. #endif
  10376. _current_shader_context->update_shader_texture_bindings(nullptr);
  10377. } else {
  10378. _current_shader_context->
  10379. update_shader_texture_bindings(_texture_binding_shader_context);
  10380. }
  10381. }
  10382. _texture_binding_shader = _current_shader;
  10383. _texture_binding_shader_context = _current_shader_context;
  10384. #endif
  10385. }
  10386. #ifdef SUPPORT_FIXED_FUNCTION
  10387. /**
  10388. * Applies the appropriate set of textures for the current state, using the
  10389. * standard fixed-function pipeline.
  10390. */
  10391. void CLP(GraphicsStateGuardian)::
  10392. update_standard_texture_bindings() {
  10393. #ifndef NDEBUG
  10394. if (_show_texture_usage) {
  10395. update_show_usage_texture_bindings(-1);
  10396. return;
  10397. }
  10398. #endif // NDEBUG
  10399. int num_stages = _target_texture->get_num_on_ff_stages();
  10400. #ifndef NDEBUG
  10401. // Also check the _flash_texture. If it is non-NULL, we need to check to
  10402. // see if our flash_texture is in the texture stack here. If so, then we
  10403. // need to call the special show_texture method instead of the normal
  10404. // texture stack.
  10405. if (_flash_texture != nullptr) {
  10406. double now = ClockObject::get_global_clock()->get_frame_time();
  10407. int this_second = (int)floor(now);
  10408. if (this_second & 1) {
  10409. int show_stage_index = -1;
  10410. for (int i = 0; i < num_stages && show_stage_index < 0; ++i) {
  10411. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  10412. Texture *texture = _target_texture->get_on_texture(stage);
  10413. if (texture == _flash_texture) {
  10414. show_stage_index = i;
  10415. }
  10416. }
  10417. if (show_stage_index >= 0) {
  10418. update_show_usage_texture_bindings(show_stage_index);
  10419. return;
  10420. }
  10421. }
  10422. }
  10423. #endif // NDEBUG
  10424. nassertv(num_stages <= _max_texture_stages &&
  10425. _num_active_texture_stages <= _max_texture_stages);
  10426. _texture_involves_color_scale = false;
  10427. int last_saved_result = -1;
  10428. int last_stage = -1;
  10429. int i;
  10430. for (i = 0; i < num_stages; i++) {
  10431. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  10432. Texture *texture = _target_texture->get_on_texture(stage);
  10433. nassertv(texture != nullptr);
  10434. // Issue the texture on stage i.
  10435. set_active_texture_stage(i);
  10436. // First, turn off the previous texture mode.
  10437. glDisable(GL_TEXTURE_2D);
  10438. if (_supports_cube_map) {
  10439. glDisable(GL_TEXTURE_CUBE_MAP);
  10440. }
  10441. #ifndef OPENGLES
  10442. glDisable(GL_TEXTURE_1D);
  10443. if (_supports_3d_texture) {
  10444. glDisable(GL_TEXTURE_3D);
  10445. }
  10446. #endif // OPENGLES
  10447. int view = get_current_tex_view_offset() + stage->get_tex_view_offset();
  10448. TextureContext *tc = texture->prepare_now(view, _prepared_objects, this);
  10449. if (tc == nullptr) {
  10450. // Something wrong with this texture; skip it.
  10451. continue;
  10452. }
  10453. // Then, turn on the current texture mode.
  10454. GLenum target = get_texture_target(texture->get_texture_type());
  10455. if (target == GL_NONE) {
  10456. // Unsupported texture mode.
  10457. continue;
  10458. }
  10459. #ifndef OPENGLES_1
  10460. if (target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_CUBE_MAP_ARRAY) {
  10461. // Cannot be applied via the FFP.
  10462. continue;
  10463. }
  10464. #endif // OPENGLES
  10465. glEnable(target);
  10466. if (!update_texture(tc, false)) {
  10467. glDisable(target);
  10468. continue;
  10469. }
  10470. // Don't DCAST(); we already did the verification in update_texture.
  10471. CLP(TextureContext) *gtc = (CLP(TextureContext) *)tc;
  10472. apply_texture(gtc);
  10473. apply_sampler(i, _target_texture->get_on_sampler(stage), gtc);
  10474. if (stage->involves_color_scale() && _color_scale_enabled) {
  10475. LColor color = stage->get_color();
  10476. color.set(color[0] * _current_color_scale[0],
  10477. color[1] * _current_color_scale[1],
  10478. color[2] * _current_color_scale[2],
  10479. color[3] * _current_color_scale[3]);
  10480. _texture_involves_color_scale = true;
  10481. call_glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);
  10482. } else {
  10483. call_glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, stage->get_color());
  10484. }
  10485. if (stage->get_mode() == TextureStage::M_decal) {
  10486. if (texture->get_num_components() < 3 && _supports_texture_combine) {
  10487. // Make a special case for 1- and 2-channel decal textures. OpenGL
  10488. // does not define their use with GL_DECAL for some reason, so
  10489. // implement them using the combiner instead.
  10490. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
  10491. glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
  10492. glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, 1);
  10493. glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1);
  10494. glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
  10495. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
  10496. glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);
  10497. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
  10498. glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_TEXTURE);
  10499. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
  10500. } else {
  10501. // Normal 3- and 4-channel decal textures.
  10502. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  10503. }
  10504. } else if (stage->get_mode() == TextureStage::M_combine) {
  10505. if (!_supports_texture_combine) {
  10506. GLCAT.warning()
  10507. << "TextureStage::M_combine mode is not supported.\n";
  10508. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  10509. } else {
  10510. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
  10511. glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
  10512. glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, stage->get_rgb_scale());
  10513. glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, stage->get_alpha_scale());
  10514. glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,
  10515. get_texture_combine_type(stage->get_combine_rgb_mode()));
  10516. switch (stage->get_num_combine_rgb_operands()) {
  10517. case 3:
  10518. glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB,
  10519. get_texture_src_type(stage->get_combine_rgb_source2(),
  10520. last_stage, last_saved_result, i));
  10521. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB,
  10522. get_texture_operand_type(stage->get_combine_rgb_operand2()));
  10523. // fall through
  10524. case 2:
  10525. glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB,
  10526. get_texture_src_type(stage->get_combine_rgb_source1(),
  10527. last_stage, last_saved_result, i));
  10528. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB,
  10529. get_texture_operand_type(stage->get_combine_rgb_operand1()));
  10530. // fall through
  10531. case 1:
  10532. glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB,
  10533. get_texture_src_type(stage->get_combine_rgb_source0(),
  10534. last_stage, last_saved_result, i));
  10535. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB,
  10536. get_texture_operand_type(stage->get_combine_rgb_operand0()));
  10537. // fall through
  10538. default:
  10539. break;
  10540. }
  10541. glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,
  10542. get_texture_combine_type(stage->get_combine_alpha_mode()));
  10543. switch (stage->get_num_combine_alpha_operands()) {
  10544. case 3:
  10545. glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_ALPHA,
  10546. get_texture_src_type(stage->get_combine_alpha_source2(),
  10547. last_stage, last_saved_result, i));
  10548. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA,
  10549. get_texture_operand_type(stage->get_combine_alpha_operand2()));
  10550. // fall through
  10551. case 2:
  10552. glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA,
  10553. get_texture_src_type(stage->get_combine_alpha_source1(),
  10554. last_stage, last_saved_result, i));
  10555. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA,
  10556. get_texture_operand_type(stage->get_combine_alpha_operand1()));
  10557. // fall through
  10558. case 1:
  10559. glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA,
  10560. get_texture_src_type(stage->get_combine_alpha_source0(),
  10561. last_stage, last_saved_result, i));
  10562. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA,
  10563. get_texture_operand_type(stage->get_combine_alpha_operand0()));
  10564. // fall through
  10565. default:
  10566. break;
  10567. }
  10568. }
  10569. } else {
  10570. GLint glmode = get_texture_apply_mode_type(stage->get_mode());
  10571. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, glmode);
  10572. }
  10573. if (stage->get_saved_result()) {
  10574. // This texture's result will be "saved" for a future stage's input.
  10575. last_saved_result = i;
  10576. } else {
  10577. // This is a regular texture stage; it will be the "previous" input for
  10578. // the next stage.
  10579. last_stage = i;
  10580. }
  10581. }
  10582. // Disable the texture stages that are no longer used.
  10583. for (i = num_stages; i < _num_active_texture_stages; i++) {
  10584. set_active_texture_stage(i);
  10585. glDisable(GL_TEXTURE_2D);
  10586. if (_supports_cube_map) {
  10587. glDisable(GL_TEXTURE_CUBE_MAP);
  10588. }
  10589. #ifndef OPENGLES
  10590. glDisable(GL_TEXTURE_1D);
  10591. if (_supports_3d_texture) {
  10592. glDisable(GL_TEXTURE_3D);
  10593. }
  10594. #endif // OPENGLES
  10595. }
  10596. // Save the count of texture stages for next time.
  10597. _num_active_texture_stages = num_stages;
  10598. report_my_gl_errors();
  10599. }
  10600. #endif // SUPPORT_FIXED_FUNCTION
  10601. /**
  10602. * Applies a white dummy texture. This is useful to bind to a texture slot
  10603. * when a texture is missing. Also binds the default sampler to the unit.
  10604. */
  10605. void CLP(GraphicsStateGuardian)::
  10606. apply_white_texture(GLuint unit) {
  10607. set_active_texture_stage(unit);
  10608. glBindTexture(GL_TEXTURE_2D, get_white_texture());
  10609. // Also apply the default sampler, if there's a chance we'd applied anything
  10610. // else.
  10611. #ifndef OPENGLES_1
  10612. if (_supports_sampler_objects) {
  10613. _glBindSampler(unit, 0);
  10614. }
  10615. #endif
  10616. }
  10617. /**
  10618. * Returns a white dummy texture. This is useful to bind to a texture slot
  10619. * when a texture is missing.
  10620. */
  10621. GLuint CLP(GraphicsStateGuardian)::
  10622. get_white_texture() {
  10623. if (_white_texture == 0) {
  10624. glGenTextures(1, &_white_texture);
  10625. glBindTexture(GL_TEXTURE_2D, _white_texture);
  10626. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  10627. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  10628. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  10629. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  10630. unsigned char data[] = {0xff, 0xff, 0xff, 0xff};
  10631. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0,
  10632. GL_RGBA, GL_UNSIGNED_BYTE, data);
  10633. }
  10634. return _white_texture;
  10635. }
  10636. #ifndef NDEBUG
  10637. /**
  10638. * This is a special function that loads the usage textures in gl-show-
  10639. * texture-usage mode, instead of loading the actual used textures.
  10640. *
  10641. * If the indicated stage_index is >= 0, then it is the particular texture
  10642. * that is shown. Otherwise, the textures are rotated through based on
  10643. * show_texture_usage_index.
  10644. */
  10645. void CLP(GraphicsStateGuardian)::
  10646. update_show_usage_texture_bindings(int show_stage_index) {
  10647. int num_stages = _target_texture->get_num_on_ff_stages();
  10648. nassertv(num_stages <= _max_texture_stages &&
  10649. _num_active_texture_stages <= _max_texture_stages);
  10650. _texture_involves_color_scale = false;
  10651. // First, we walk through the list of textures and pretend to render them
  10652. // all, even though we don't actually render them, just so Panda will keep
  10653. // track of the list of "active" textures correctly during the flash.
  10654. int i;
  10655. for (i = 0; i < num_stages; i++) {
  10656. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  10657. Texture *texture = _target_texture->get_on_texture(stage);
  10658. nassertv(texture != nullptr);
  10659. int view = get_current_tex_view_offset() + stage->get_tex_view_offset();
  10660. TextureContext *tc = texture->prepare_now(view, _prepared_objects, this);
  10661. if (tc == nullptr) {
  10662. // Something wrong with this texture; skip it.
  10663. break;
  10664. }
  10665. tc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  10666. }
  10667. #ifdef SUPPORT_FIXED_FUNCTION
  10668. if (has_fixed_function_pipeline()) {
  10669. // Disable all texture stages.
  10670. for (i = 0; i < _num_active_texture_stages; i++) {
  10671. set_active_texture_stage(i);
  10672. #ifndef OPENGLES
  10673. glDisable(GL_TEXTURE_1D);
  10674. #endif // OPENGLES
  10675. glDisable(GL_TEXTURE_2D);
  10676. if (_supports_3d_texture) {
  10677. #ifndef OPENGLES_1
  10678. glDisable(GL_TEXTURE_3D);
  10679. #endif // OPENGLES_1
  10680. }
  10681. if (_supports_cube_map) {
  10682. glDisable(GL_TEXTURE_CUBE_MAP);
  10683. }
  10684. }
  10685. }
  10686. #endif
  10687. // Save the count of texture stages for next time.
  10688. _num_active_texture_stages = num_stages;
  10689. if (num_stages > 0) {
  10690. // Now, pick just one texture stage to apply.
  10691. if (show_stage_index >= 0 && show_stage_index < num_stages) {
  10692. i = show_stage_index;
  10693. } else {
  10694. i = _show_texture_usage_index % num_stages;
  10695. }
  10696. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  10697. Texture *texture = _target_texture->get_on_texture(stage);
  10698. nassertv(texture != nullptr);
  10699. // Choose the corresponding usage texture and apply it.
  10700. set_active_texture_stage(i);
  10701. #ifdef SUPPORT_FIXED_FUNCTION
  10702. if (has_fixed_function_pipeline()) {
  10703. glEnable(GL_TEXTURE_2D);
  10704. }
  10705. #endif
  10706. UsageTextureKey key(texture->get_x_size(), texture->get_y_size());
  10707. UsageTextures::iterator ui = _usage_textures.find(key);
  10708. GLuint index;
  10709. if (ui == _usage_textures.end()) {
  10710. // Need to create a new texture for this size.
  10711. glGenTextures(1, &index);
  10712. glBindTexture(GL_TEXTURE_2D, index);
  10713. // TODO: this could be a lot simpler with glTexStorage2D followed by a
  10714. // call to glClearTexImage.
  10715. upload_usage_texture(texture->get_x_size(), texture->get_y_size());
  10716. _usage_textures[key] = index;
  10717. } else {
  10718. // Just bind the previously-created texture.
  10719. index = (*ui).second;
  10720. glBindTexture(GL_TEXTURE_2D, index);
  10721. }
  10722. if (GLCAT.is_spam()) {
  10723. GLCAT.spam()
  10724. << "glBindTexture(GL_TEXTURE_2D, " << index << ")\n";
  10725. }
  10726. // TODO: glBindSampler(0) ?
  10727. }
  10728. report_my_gl_errors();
  10729. }
  10730. #endif // NDEBUG
  10731. #ifndef NDEBUG
  10732. /**
  10733. * Uploads a special "usage" texture intended to be applied only in gl-show-
  10734. * texture-usage mode, to reveal where texture memory is being spent.
  10735. */
  10736. void CLP(GraphicsStateGuardian)::
  10737. upload_usage_texture(int width, int height) {
  10738. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  10739. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  10740. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  10741. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  10742. if (GLCAT.is_debug()) {
  10743. GLCAT.debug()
  10744. << "upload_usage_texture(" << width << ", " << height << ")\n";
  10745. }
  10746. static LColor colors[3] = {
  10747. LColor(0.4, 0.5f, 0.8f, 1.0f), // mipmap 0: blue
  10748. LColor(1.0f, 1.0f, 0.0f, 1.0f), // mipmap 1: yellow
  10749. LColor(0.8f, 0.3, 0.3, 1.0f), // mipmap 2 and higher: red
  10750. };
  10751. // Allocate a temporary array large enough to contain the toplevel mipmap.
  10752. uint32_t *buffer = (uint32_t *)PANDA_MALLOC_ARRAY(width * height * 4);
  10753. int n = 0;
  10754. while (true) {
  10755. // Choose the color for the nth mipmap.
  10756. LColor c = colors[min(n, 2)];
  10757. // A simple union to store the colors values bytewise, and get the answer
  10758. // wordwise, independently of machine byte-ordernig.
  10759. union {
  10760. struct {
  10761. unsigned char r, g, b, a;
  10762. } b;
  10763. uint32_t w;
  10764. } store;
  10765. store.b.r = (unsigned char)(c[0] * 255.0f);
  10766. store.b.g = (unsigned char)(c[1] * 255.0f);
  10767. store.b.b = (unsigned char)(c[2] * 255.0f);
  10768. store.b.a = 0xff;
  10769. // Fill in the array.
  10770. int num_pixels = width * height;
  10771. for (int p = 0; p < num_pixels; ++p) {
  10772. buffer[p] = store.w;
  10773. }
  10774. glTexImage2D(GL_TEXTURE_2D, n, GL_RGBA, width, height, 0,
  10775. GL_RGBA, GL_UNSIGNED_BYTE, buffer);
  10776. if (width == 1 && height == 1) {
  10777. // That was the last mipmap level.
  10778. break;
  10779. }
  10780. width = max(width >> 1, 1);
  10781. height = max(height >> 1, 1);
  10782. ++n;
  10783. }
  10784. PANDA_FREE_ARRAY(buffer);
  10785. }
  10786. #endif // NDEBUG
  10787. #ifdef SUPPORT_FIXED_FUNCTION
  10788. /**
  10789. *
  10790. */
  10791. void CLP(GraphicsStateGuardian)::
  10792. disable_standard_texture_bindings() {
  10793. // Disable the texture stages that are no longer used.
  10794. for (int i = 0; i < _num_active_texture_stages; i++) {
  10795. set_active_texture_stage(i);
  10796. #ifndef OPENGLES
  10797. glDisable(GL_TEXTURE_1D);
  10798. #endif // OPENGLES
  10799. glDisable(GL_TEXTURE_2D);
  10800. if (_supports_3d_texture) {
  10801. #ifndef OPENGLES_1
  10802. glDisable(GL_TEXTURE_3D);
  10803. #endif // OPENGLES_1
  10804. }
  10805. if (_supports_cube_map) {
  10806. glDisable(GL_TEXTURE_CUBE_MAP);
  10807. }
  10808. }
  10809. _num_active_texture_stages = 0;
  10810. report_my_gl_errors();
  10811. }
  10812. #endif // SUPPORT_FIXED_FUNCTION
  10813. #ifdef SUPPORT_FIXED_FUNCTION
  10814. /**
  10815. *
  10816. */
  10817. void CLP(GraphicsStateGuardian)::
  10818. do_issue_tex_matrix() {
  10819. nassertv(_num_active_texture_stages <= _max_texture_stages);
  10820. for (int i = 0; i < _num_active_texture_stages; i++) {
  10821. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  10822. set_active_texture_stage(i);
  10823. glMatrixMode(GL_TEXTURE);
  10824. const TexMatrixAttrib *target_tex_matrix;
  10825. _target_rs->get_attrib_def(target_tex_matrix);
  10826. if (target_tex_matrix->has_stage(stage)) {
  10827. call_glLoadMatrix(target_tex_matrix->get_mat(stage));
  10828. } else {
  10829. glLoadIdentity();
  10830. // For some reason, the glLoadIdentity() call doesn't work on my Dell
  10831. // laptop's IBM OpenGL driver, when used in conjunction with glTexGen(),
  10832. // below. But explicitly loading an identity matrix does work. But
  10833. // this buggy-driver workaround might have other performance
  10834. // implications, so I leave it out.
  10835. // call_glLoadMatrix(LMatrix4::ident_mat());
  10836. }
  10837. }
  10838. report_my_gl_errors();
  10839. }
  10840. #endif // SUPPORT_FIXED_FUNCTION
  10841. #ifdef SUPPORT_FIXED_FUNCTION
  10842. /**
  10843. *
  10844. */
  10845. void CLP(GraphicsStateGuardian)::
  10846. do_issue_tex_gen() {
  10847. nassertv(_num_active_texture_stages <= _max_texture_stages);
  10848. // These are passed in for the four OBJECT_PLANE or EYE_PLANE values; they
  10849. // effectively define an identity matrix that maps the spatial coordinates
  10850. // one-for-one to UV's. If you want a mapping other than identity, use a
  10851. // TexMatrixAttrib (or a TexProjectorEffect).
  10852. #ifndef OPENGLES
  10853. static const PN_stdfloat s_data[4] = { 1, 0, 0, 0 };
  10854. static const PN_stdfloat t_data[4] = { 0, 1, 0, 0 };
  10855. static const PN_stdfloat r_data[4] = { 0, 0, 1, 0 };
  10856. static const PN_stdfloat q_data[4] = { 0, 0, 0, 1 };
  10857. #endif
  10858. _tex_gen_modifies_mat = false;
  10859. for (int i = 0; i < _num_active_texture_stages; i++) {
  10860. set_active_texture_stage(i);
  10861. if (_supports_point_sprite) {
  10862. #ifdef OPENGLES
  10863. glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_FALSE);
  10864. #else
  10865. glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_FALSE);
  10866. #endif // OPENGLES
  10867. }
  10868. #ifndef OPENGLES // TexGen not supported by OpenGL ES.
  10869. glDisable(GL_TEXTURE_GEN_S);
  10870. glDisable(GL_TEXTURE_GEN_T);
  10871. glDisable(GL_TEXTURE_GEN_R);
  10872. glDisable(GL_TEXTURE_GEN_Q);
  10873. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  10874. TexGenAttrib::Mode mode = _target_tex_gen->get_mode(stage);
  10875. switch (mode) {
  10876. case TexGenAttrib::M_off:
  10877. case TexGenAttrib::M_unused2:
  10878. break;
  10879. case TexGenAttrib::M_eye_sphere_map:
  10880. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  10881. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  10882. glEnable(GL_TEXTURE_GEN_S);
  10883. glEnable(GL_TEXTURE_GEN_T);
  10884. break;
  10885. case TexGenAttrib::M_eye_cube_map:
  10886. if (_supports_cube_map) {
  10887. // We need to rotate the normals out of GL's coordinate system and
  10888. // into the user's coordinate system. We do this by composing a
  10889. // transform onto the texture matrix.
  10890. LMatrix4 mat = _inv_cs_transform->get_mat();
  10891. mat.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
  10892. glMatrixMode(GL_TEXTURE);
  10893. GLPf(MultMatrix)(mat.get_data());
  10894. // Now we need to reset the texture matrix next time around to undo
  10895. // this.
  10896. _tex_gen_modifies_mat = true;
  10897. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  10898. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  10899. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  10900. glEnable(GL_TEXTURE_GEN_S);
  10901. glEnable(GL_TEXTURE_GEN_T);
  10902. glEnable(GL_TEXTURE_GEN_R);
  10903. }
  10904. break;
  10905. case TexGenAttrib::M_world_cube_map:
  10906. if (_supports_cube_map) {
  10907. // We dynamically transform normals from eye space to world space by
  10908. // applying the appropriate rotation transform to the current texture
  10909. // matrix. Unlike M_world_position, we can't achieve this effect by
  10910. // monkeying with the modelview transform, since the current modelview
  10911. // doesn't affect GL_REFLECTION_MAP.
  10912. CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
  10913. LMatrix4 mat = camera_transform->get_mat();
  10914. mat.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
  10915. glMatrixMode(GL_TEXTURE);
  10916. GLPf(MultMatrix)(mat.get_data());
  10917. // Now we need to reset the texture matrix next time around to undo
  10918. // this.
  10919. _tex_gen_modifies_mat = true;
  10920. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  10921. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  10922. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  10923. glEnable(GL_TEXTURE_GEN_S);
  10924. glEnable(GL_TEXTURE_GEN_T);
  10925. glEnable(GL_TEXTURE_GEN_R);
  10926. }
  10927. break;
  10928. case TexGenAttrib::M_eye_normal:
  10929. if (_supports_cube_map) {
  10930. // We need to rotate the normals out of GL's coordinate system and
  10931. // into the user's coordinate system. We do this by composing a
  10932. // transform onto the texture matrix.
  10933. LMatrix4 mat = _inv_cs_transform->get_mat();
  10934. mat.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
  10935. glMatrixMode(GL_TEXTURE);
  10936. GLPf(MultMatrix)(mat.get_data());
  10937. // Now we need to reset the texture matrix next time around to undo
  10938. // this.
  10939. _tex_gen_modifies_mat = true;
  10940. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  10941. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  10942. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  10943. glEnable(GL_TEXTURE_GEN_S);
  10944. glEnable(GL_TEXTURE_GEN_T);
  10945. glEnable(GL_TEXTURE_GEN_R);
  10946. }
  10947. break;
  10948. case TexGenAttrib::M_world_normal:
  10949. if (_supports_cube_map) {
  10950. // We dynamically transform normals from eye space to world space by
  10951. // applying the appropriate rotation transform to the current texture
  10952. // matrix. Unlike M_world_position, we can't achieve this effect by
  10953. // monkeying with the modelview transform, since the current modelview
  10954. // doesn't affect GL_NORMAL_MAP.
  10955. CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
  10956. LMatrix4 mat = camera_transform->get_mat();
  10957. mat.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
  10958. glMatrixMode(GL_TEXTURE);
  10959. GLPf(MultMatrix)(mat.get_data());
  10960. // Now we need to reset the texture matrix next time around to undo
  10961. // this.
  10962. _tex_gen_modifies_mat = true;
  10963. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  10964. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  10965. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  10966. glEnable(GL_TEXTURE_GEN_S);
  10967. glEnable(GL_TEXTURE_GEN_T);
  10968. glEnable(GL_TEXTURE_GEN_R);
  10969. }
  10970. break;
  10971. case TexGenAttrib::M_eye_position:
  10972. // To represent eye position correctly, we need to temporarily load the
  10973. // coordinate-system transform.
  10974. glMatrixMode(GL_MODELVIEW);
  10975. glPushMatrix();
  10976. call_glLoadMatrix(_cs_transform->get_mat());
  10977. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  10978. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  10979. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  10980. glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  10981. GLPfv(TexGen)(GL_S, GL_EYE_PLANE, s_data);
  10982. GLPfv(TexGen)(GL_T, GL_EYE_PLANE, t_data);
  10983. GLPfv(TexGen)(GL_R, GL_EYE_PLANE, r_data);
  10984. GLPfv(TexGen)(GL_Q, GL_EYE_PLANE, q_data);
  10985. glEnable(GL_TEXTURE_GEN_S);
  10986. glEnable(GL_TEXTURE_GEN_T);
  10987. glEnable(GL_TEXTURE_GEN_R);
  10988. glEnable(GL_TEXTURE_GEN_Q);
  10989. glMatrixMode(GL_MODELVIEW);
  10990. glPopMatrix();
  10991. break;
  10992. case TexGenAttrib::M_world_position:
  10993. // We achieve world position coordinates by using the eye position mode,
  10994. // and loading the transform of the root node--thus putting the "eye" at
  10995. // the root.
  10996. {
  10997. glMatrixMode(GL_MODELVIEW);
  10998. glPushMatrix();
  10999. CPT(TransformState) root_transform = _cs_transform->compose(_scene_setup->get_world_transform());
  11000. call_glLoadMatrix(root_transform->get_mat());
  11001. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  11002. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  11003. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  11004. glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  11005. GLPfv(TexGen)(GL_S, GL_EYE_PLANE, s_data);
  11006. GLPfv(TexGen)(GL_T, GL_EYE_PLANE, t_data);
  11007. GLPfv(TexGen)(GL_R, GL_EYE_PLANE, r_data);
  11008. GLPfv(TexGen)(GL_Q, GL_EYE_PLANE, q_data);
  11009. glEnable(GL_TEXTURE_GEN_S);
  11010. glEnable(GL_TEXTURE_GEN_T);
  11011. glEnable(GL_TEXTURE_GEN_R);
  11012. glEnable(GL_TEXTURE_GEN_Q);
  11013. glMatrixMode(GL_MODELVIEW);
  11014. glPopMatrix();
  11015. }
  11016. break;
  11017. case TexGenAttrib::M_point_sprite:
  11018. if (_supports_point_sprite) {
  11019. #ifdef OPENGLES
  11020. glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE);
  11021. #else
  11022. glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
  11023. #endif
  11024. }
  11025. break;
  11026. case TexGenAttrib::M_constant:
  11027. // To generate a constant UV(w) coordinate everywhere, we use EYE_LINEAR
  11028. // mode, but we construct a special matrix that flattens the vertex
  11029. // position to zero and then adds our desired value.
  11030. {
  11031. const LTexCoord3 &v = _target_tex_gen->get_constant_value(stage);
  11032. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  11033. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  11034. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  11035. glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  11036. LVecBase4 s(0.0f, 0.0f, 0.0f, v[0]);
  11037. LVecBase4 t(0.0f, 0.0f, 0.0f, v[1]);
  11038. LVecBase4 r(0.0f, 0.0f, 0.0f, v[2]);
  11039. GLPfv(TexGen)(GL_S, GL_OBJECT_PLANE, s.get_data());
  11040. GLPfv(TexGen)(GL_T, GL_OBJECT_PLANE, t.get_data());
  11041. GLPfv(TexGen)(GL_R, GL_OBJECT_PLANE, r.get_data());
  11042. GLPfv(TexGen)(GL_Q, GL_OBJECT_PLANE, q_data);
  11043. glEnable(GL_TEXTURE_GEN_S);
  11044. glEnable(GL_TEXTURE_GEN_T);
  11045. glEnable(GL_TEXTURE_GEN_R);
  11046. glEnable(GL_TEXTURE_GEN_Q);
  11047. }
  11048. break;
  11049. case TexGenAttrib::M_unused:
  11050. break;
  11051. }
  11052. #endif // OPENGLES
  11053. }
  11054. bool got_point_sprites = _supports_point_sprite &&
  11055. (_target_tex_gen->get_geom_rendering(Geom::GR_point) & GeomEnums::GR_point_sprite) != 0;
  11056. if (got_point_sprites != _tex_gen_point_sprite) {
  11057. _tex_gen_point_sprite = got_point_sprites;
  11058. #ifdef OPENGLES
  11059. if (_tex_gen_point_sprite) {
  11060. glEnable(GL_POINT_SPRITE_OES);
  11061. } else {
  11062. glDisable(GL_POINT_SPRITE_OES);
  11063. }
  11064. #else
  11065. if (_tex_gen_point_sprite) {
  11066. glEnable(GL_POINT_SPRITE_ARB);
  11067. } else {
  11068. glDisable(GL_POINT_SPRITE_ARB);
  11069. }
  11070. #endif // OPENGLES
  11071. }
  11072. report_my_gl_errors();
  11073. }
  11074. #endif // SUPPORT_FIXED_FUNCTION
  11075. /**
  11076. * Specifies the texture parameters. Returns true if the texture may need to
  11077. * be reloaded. Pass non-NULL sampler argument to use different sampler
  11078. * settings.
  11079. */
  11080. bool CLP(GraphicsStateGuardian)::
  11081. specify_texture(CLP(TextureContext) *gtc, const SamplerState &sampler) {
  11082. #ifndef OPENGLES
  11083. nassertr(gtc->_handle == 0 /* can't modify tex with active handle */, false);
  11084. #endif
  11085. Texture *tex = gtc->get_texture();
  11086. GLenum target = get_texture_target(tex->get_texture_type());
  11087. if (target == GL_NONE) {
  11088. // Unsupported target (e.g. 3-d texturing on GL 1.1).
  11089. return false;
  11090. }
  11091. #ifndef OPENGLES
  11092. if (target == GL_TEXTURE_BUFFER) {
  11093. // Buffer textures may not receive texture parameters.
  11094. return false;
  11095. }
  11096. #endif // OPENGLES
  11097. // Record the active sampler settings.
  11098. gtc->_active_sampler = sampler;
  11099. glTexParameteri(target, GL_TEXTURE_WRAP_S,
  11100. get_texture_wrap_mode(sampler.get_wrap_u()));
  11101. #ifndef OPENGLES
  11102. if (target != GL_TEXTURE_1D)
  11103. #endif
  11104. {
  11105. glTexParameteri(target, GL_TEXTURE_WRAP_T,
  11106. get_texture_wrap_mode(sampler.get_wrap_v()));
  11107. }
  11108. #ifndef OPENGLES_1
  11109. if (target == GL_TEXTURE_3D) {
  11110. glTexParameteri(target, GL_TEXTURE_WRAP_R,
  11111. get_texture_wrap_mode(sampler.get_wrap_w()));
  11112. }
  11113. #endif
  11114. #ifndef OPENGLES
  11115. LColor border_color = sampler.get_border_color();
  11116. call_glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, border_color);
  11117. #endif // OPENGLES
  11118. SamplerState::FilterType minfilter = sampler.get_effective_minfilter();
  11119. SamplerState::FilterType magfilter = sampler.get_effective_magfilter();
  11120. bool uses_mipmaps = SamplerState::is_mipmap(minfilter) && !gl_ignore_mipmaps;
  11121. #ifndef NDEBUG
  11122. if (gl_force_mipmaps) {
  11123. minfilter = SamplerState::FT_linear_mipmap_linear;
  11124. magfilter = SamplerState::FT_linear;
  11125. uses_mipmaps = true;
  11126. }
  11127. #endif
  11128. if (!tex->might_have_ram_image()) {
  11129. // If it's a dynamically generated texture (that is, the RAM image isn't
  11130. // available so it didn't pass through the CPU), we should enable GL-
  11131. // generated mipmaps if we can.
  11132. if (!_supports_generate_mipmap) {
  11133. // However, if the GPU doesn't support mipmap generation, we have to
  11134. // turn it off.
  11135. uses_mipmaps = false;
  11136. }
  11137. }
  11138. glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
  11139. get_texture_filter_type(minfilter, !uses_mipmaps));
  11140. glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
  11141. get_texture_filter_type(magfilter, true));
  11142. // Set anisotropic filtering.
  11143. if (_supports_anisotropy) {
  11144. PN_stdfloat anisotropy = sampler.get_effective_anisotropic_degree();
  11145. anisotropy = min(anisotropy, _max_anisotropy);
  11146. anisotropy = max(anisotropy, (PN_stdfloat)1.0);
  11147. glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
  11148. }
  11149. #ifndef OPENGLES_1
  11150. if (tex->get_format() == Texture::F_depth_stencil ||
  11151. tex->get_format() == Texture::F_depth_component ||
  11152. tex->get_format() == Texture::F_depth_component16 ||
  11153. tex->get_format() == Texture::F_depth_component24 ||
  11154. tex->get_format() == Texture::F_depth_component32) {
  11155. #ifdef SUPPORT_FIXED_FUNCTION
  11156. if (has_fixed_function_pipeline()) {
  11157. glTexParameteri(target, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
  11158. }
  11159. #endif
  11160. if (_supports_shadow_filter) {
  11161. if ((sampler.get_magfilter() == SamplerState::FT_shadow) ||
  11162. (sampler.get_minfilter() == SamplerState::FT_shadow)) {
  11163. glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
  11164. glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
  11165. } else {
  11166. glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
  11167. glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
  11168. }
  11169. }
  11170. }
  11171. #endif
  11172. #ifndef OPENGLES_1
  11173. if (_supports_texture_lod) {
  11174. glTexParameterf(target, GL_TEXTURE_MIN_LOD, sampler.get_min_lod());
  11175. glTexParameterf(target, GL_TEXTURE_MAX_LOD, sampler.get_max_lod());
  11176. }
  11177. #endif
  11178. #ifndef OPENGLES
  11179. if (_supports_texture_lod_bias) {
  11180. glTexParameterf(target, GL_TEXTURE_LOD_BIAS, sampler.get_lod_bias());
  11181. }
  11182. #endif
  11183. report_my_gl_errors();
  11184. if (uses_mipmaps && !gtc->_uses_mipmaps) {
  11185. // Suddenly we require mipmaps. This means the texture may need
  11186. // reloading.
  11187. return true;
  11188. }
  11189. return false;
  11190. }
  11191. /**
  11192. * Updates OpenGL with the current information for this texture, and makes it
  11193. * the current texture available for rendering.
  11194. */
  11195. bool CLP(GraphicsStateGuardian)::
  11196. apply_texture(CLP(TextureContext) *gtc) {
  11197. gtc->set_active(true);
  11198. GLenum target = get_texture_target(gtc->get_texture()->get_texture_type());
  11199. if (target == GL_NONE) {
  11200. return false;
  11201. }
  11202. if (gtc->_target != target) {
  11203. // The target has changed. That means we have to re-bind a new texture
  11204. // object.
  11205. gtc->reset_data();
  11206. gtc->_target = target;
  11207. }
  11208. glBindTexture(target, gtc->_index);
  11209. if (GLCAT.is_spam()) {
  11210. GLCAT.spam()
  11211. << "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << "): " << *gtc->get_texture() << "\n";
  11212. }
  11213. report_my_gl_errors();
  11214. return true;
  11215. }
  11216. /**
  11217. * Updates OpenGL with the current information for this sampler, and makes it
  11218. * the current sampler available for rendering. Use NULL to unbind the
  11219. * sampler.
  11220. *
  11221. * If the GSG doesn't support sampler objects, the sampler settings are
  11222. * applied to the given texture context instead.
  11223. */
  11224. bool CLP(GraphicsStateGuardian)::
  11225. apply_sampler(GLuint unit, const SamplerState &sampler, CLP(TextureContext) *gtc) {
  11226. #ifndef OPENGLES_1
  11227. if (_supports_sampler_objects) {
  11228. // We support sampler objects. Prepare the sampler object and bind it to
  11229. // the indicated texture unit.
  11230. SamplerContext *sc = sampler.prepare_now(get_prepared_objects(), this);
  11231. nassertr(sc != nullptr, false);
  11232. CLP(SamplerContext) *gsc = DCAST(CLP(SamplerContext), sc);
  11233. gsc->enqueue_lru(&_prepared_objects->_sampler_object_lru);
  11234. _glBindSampler(unit, gsc->_index);
  11235. if (GLCAT.is_spam()) {
  11236. GLCAT.spam() << "glBindSampler(" << unit << ", "
  11237. << gsc->_index << "): " << sampler << "\n";
  11238. }
  11239. } else
  11240. #endif // !OPENGLES_1
  11241. {
  11242. // We don't support sampler objects. We'll have to bind the texture and
  11243. // change the texture parameters if they don't match.
  11244. if (gtc->_active_sampler != sampler) {
  11245. set_active_texture_stage(unit);
  11246. apply_texture(gtc);
  11247. specify_texture(gtc, sampler);
  11248. }
  11249. }
  11250. if (sampler.uses_mipmaps() && !gtc->_uses_mipmaps && !gl_ignore_mipmaps) {
  11251. // The texture wasn't created with mipmaps, but we are trying to sample it
  11252. // with mipmaps. We will need to reload it.
  11253. GLCAT.info()
  11254. << "reloading texture " << gtc->get_texture()->get_name()
  11255. << " with mipmaps\n";
  11256. apply_texture(gtc);
  11257. gtc->mark_needs_reload();
  11258. bool okflag = upload_texture(gtc, false, true);
  11259. if (!okflag) {
  11260. GLCAT.error()
  11261. << "Could not load " << *gtc->get_texture() << "\n";
  11262. return false;
  11263. }
  11264. }
  11265. report_my_gl_errors();
  11266. return true;
  11267. }
  11268. /**
  11269. * Uploads the entire texture image to OpenGL, including all pages.
  11270. *
  11271. * The return value is true if successful, or false if the texture has no
  11272. * image.
  11273. */
  11274. bool CLP(GraphicsStateGuardian)::
  11275. upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
  11276. PStatGPUTimer timer(this, _load_texture_pcollector);
  11277. Texture *tex = gtc->get_texture();
  11278. if (_effective_incomplete_render && !force) {
  11279. bool has_image = _supports_compressed_texture ? tex->has_ram_image() : tex->has_uncompressed_ram_image();
  11280. if (!has_image && tex->might_have_ram_image() &&
  11281. tex->has_simple_ram_image() &&
  11282. !_loader.is_null()) {
  11283. // If we don't have the texture data right now, go get it, but in the
  11284. // meantime load a temporary simple image in its place.
  11285. async_reload_texture(gtc);
  11286. has_image = _supports_compressed_texture ? tex->has_ram_image() : tex->has_uncompressed_ram_image();
  11287. if (!has_image) {
  11288. if (gtc->was_simple_image_modified()) {
  11289. return upload_simple_texture(gtc);
  11290. }
  11291. return true;
  11292. }
  11293. }
  11294. }
  11295. CPTA_uchar image;
  11296. if (_supports_compressed_texture) {
  11297. image = tex->get_ram_image();
  11298. } else {
  11299. image = tex->get_uncompressed_ram_image();
  11300. }
  11301. Texture::CompressionMode image_compression;
  11302. if (image.is_null()) {
  11303. image_compression = Texture::CM_off;
  11304. } else {
  11305. image_compression = tex->get_ram_image_compression();
  11306. }
  11307. if (!get_supports_compressed_texture_format(image_compression)) {
  11308. image = tex->get_uncompressed_ram_image();
  11309. image_compression = Texture::CM_off;
  11310. // If this triggers, Panda cannot decompress the texture. Compile with
  11311. // libsquish support or precompress the texture.
  11312. nassertr(!image.is_null(), false);
  11313. }
  11314. int mipmap_bias = 0;
  11315. int width = tex->get_x_size();
  11316. int height = tex->get_y_size();
  11317. int depth = tex->get_z_size();
  11318. // If we'll use immutable texture storage, we have to pick a sized image
  11319. // format.
  11320. bool force_sized = (gl_immutable_texture_storage && _supports_tex_storage) ||
  11321. (tex->get_texture_type() == Texture::TT_buffer_texture);
  11322. GLint internal_format = get_internal_image_format(tex, force_sized);
  11323. GLint external_format = get_external_image_format(tex);
  11324. GLenum component_type = get_component_type(tex->get_component_type());
  11325. if (GLCAT.is_debug()) {
  11326. if (image.is_null()) {
  11327. GLCAT.debug()
  11328. << "loading texture with NULL image";
  11329. } else if (image_compression != Texture::CM_off) {
  11330. GLCAT.debug()
  11331. << "loading pre-compressed texture";
  11332. } else if (is_compressed_format(internal_format)) {
  11333. GLCAT.debug()
  11334. << "loading compressed texture";
  11335. } else {
  11336. GLCAT.debug()
  11337. << "loading uncompressed texture";
  11338. }
  11339. GLCAT.debug(false) << " " << tex->get_name() << "\n";
  11340. }
  11341. // Ensure that the texture fits within the GL's specified limits. Need to
  11342. // split dimensions because of texture arrays
  11343. int max_dimension_x;
  11344. int max_dimension_y;
  11345. int max_dimension_z;
  11346. switch (tex->get_texture_type()) {
  11347. case Texture::TT_3d_texture:
  11348. max_dimension_x = _max_3d_texture_dimension;
  11349. max_dimension_y = _max_3d_texture_dimension;
  11350. max_dimension_z = _max_3d_texture_dimension;
  11351. break;
  11352. case Texture::TT_cube_map:
  11353. max_dimension_x = _max_cube_map_dimension;
  11354. max_dimension_y = _max_cube_map_dimension;
  11355. max_dimension_z = 6;
  11356. break;
  11357. case Texture::TT_2d_texture_array:
  11358. max_dimension_x = _max_texture_dimension;
  11359. max_dimension_y = _max_texture_dimension;
  11360. max_dimension_z = _max_2d_texture_array_layers;
  11361. break;
  11362. case Texture::TT_cube_map_array:
  11363. max_dimension_x = _max_texture_dimension;
  11364. max_dimension_y = _max_texture_dimension;
  11365. max_dimension_z = int(_max_2d_texture_array_layers / 6) * 6;
  11366. break;
  11367. case Texture::TT_buffer_texture:
  11368. max_dimension_x = _max_buffer_texture_size;
  11369. max_dimension_y = 1;
  11370. max_dimension_z = 1;
  11371. break;
  11372. default:
  11373. max_dimension_x = _max_texture_dimension;
  11374. max_dimension_y = _max_texture_dimension;
  11375. max_dimension_z = 1;
  11376. }
  11377. if (max_dimension_x == 0 || max_dimension_y == 0 || max_dimension_z == 0) {
  11378. // Guess this GL doesn't support cube mapping3d textures2d texture arrays.
  11379. report_my_gl_errors();
  11380. return false;
  11381. }
  11382. // If it doesn't fit, we have to reduce it on-the-fly. We do this by
  11383. // incrementing the mipmap_bias, so we're effectively loading a lower mipmap
  11384. // level. This requires generating the mipmaps on the CPU if they haven't
  11385. // already been generated. It would have been better if the user had
  11386. // specified max-texture-dimension to reduce the texture at load time
  11387. // instead; of course, the user doesn't always know ahead of time what the
  11388. // hardware limits are.
  11389. if ((max_dimension_x > 0 && max_dimension_y > 0 && max_dimension_z > 0) &&
  11390. image_compression == Texture::CM_off) {
  11391. while (tex->get_expected_mipmap_x_size(mipmap_bias) > max_dimension_x ||
  11392. tex->get_expected_mipmap_y_size(mipmap_bias) > max_dimension_y ||
  11393. tex->get_expected_mipmap_z_size(mipmap_bias) > max_dimension_z) {
  11394. ++mipmap_bias;
  11395. }
  11396. if (mipmap_bias >= tex->get_num_ram_mipmap_images()) {
  11397. // We need to generate some more mipmap images.
  11398. if (tex->has_ram_image()) {
  11399. tex->generate_ram_mipmap_images();
  11400. if (mipmap_bias >= tex->get_num_ram_mipmap_images()) {
  11401. // It didn't work. Send the smallest we've got, and hope for the
  11402. // best.
  11403. mipmap_bias = tex->get_num_ram_mipmap_images() - 1;
  11404. }
  11405. }
  11406. }
  11407. width = tex->get_expected_mipmap_x_size(mipmap_bias);
  11408. height = tex->get_expected_mipmap_y_size(mipmap_bias);
  11409. depth = tex->get_expected_mipmap_z_size(mipmap_bias);
  11410. if (mipmap_bias != 0) {
  11411. GLCAT.info()
  11412. << "Reducing image " << tex->get_name()
  11413. << " from " << tex->get_x_size() << " x " << tex->get_y_size()
  11414. << " x " << tex->get_z_size() << " to "
  11415. << width << " x " << height << " x " << depth << "\n";
  11416. }
  11417. }
  11418. if (image_compression != Texture::CM_off) {
  11419. #ifndef OPENGLES
  11420. switch (tex->get_effective_quality_level()) {
  11421. case Texture::QL_fastest:
  11422. glHint(GL_TEXTURE_COMPRESSION_HINT, GL_FASTEST);
  11423. break;
  11424. case Texture::QL_default:
  11425. case Texture::QL_normal:
  11426. glHint(GL_TEXTURE_COMPRESSION_HINT, GL_DONT_CARE);
  11427. break;
  11428. case Texture::QL_best:
  11429. glHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST);
  11430. break;
  11431. }
  11432. #endif
  11433. }
  11434. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  11435. GLenum target = get_texture_target(tex->get_texture_type());
  11436. uses_mipmaps = (uses_mipmaps && !gl_ignore_mipmaps) || gl_force_mipmaps;
  11437. #ifndef OPENGLES
  11438. if (target == GL_TEXTURE_BUFFER) {
  11439. // Buffer textures may not have mipmaps.
  11440. uses_mipmaps = false;
  11441. }
  11442. #endif // OPENGLES
  11443. bool needs_reload = false;
  11444. if (!gtc->_has_storage ||
  11445. gtc->_uses_mipmaps != uses_mipmaps ||
  11446. gtc->_internal_format != internal_format ||
  11447. gtc->_width != width ||
  11448. gtc->_height != height ||
  11449. gtc->_depth != depth) {
  11450. // We need to reload a new GL Texture object.
  11451. needs_reload = true;
  11452. if (_use_object_labels) {
  11453. // This seems like a good time to assign a label for the debug messages.
  11454. const string &name = tex->get_name();
  11455. _glObjectLabel(GL_TEXTURE, gtc->_index, name.size(), name.data());
  11456. }
  11457. }
  11458. if (needs_reload && gtc->_immutable) {
  11459. GLCAT.info() << "Attempt to modify texture with immutable storage, recreating texture.\n";
  11460. gtc->reset_data();
  11461. glBindTexture(target, gtc->_index);
  11462. if (GLCAT.is_spam()) {
  11463. GLCAT.spam()
  11464. << "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << "): " << *tex << "\n";
  11465. }
  11466. }
  11467. #ifndef OPENGLES
  11468. if (target == GL_TEXTURE_BUFFER) {
  11469. // Buffer textures don't support mipmappping.
  11470. gtc->_generate_mipmaps = false;
  11471. if (gtc->_buffer == 0) {
  11472. // The buffer object wasn't created yet.
  11473. _glGenBuffers(1, &gtc->_buffer);
  11474. _glBindBuffer(GL_TEXTURE_BUFFER, gtc->_buffer);
  11475. _glTexBuffer(GL_TEXTURE_BUFFER, internal_format, gtc->_buffer);
  11476. needs_reload = true;
  11477. } else {
  11478. _glBindBuffer(GL_TEXTURE_BUFFER, gtc->_buffer);
  11479. if (gtc->_internal_format != internal_format) {
  11480. _glTexBuffer(GL_TEXTURE_BUFFER, internal_format, gtc->_buffer);
  11481. }
  11482. }
  11483. } else
  11484. #endif // !OPENGLES
  11485. if (needs_reload) {
  11486. // Figure out whether mipmaps will be generated by the GPU or by Panda (or
  11487. // not at all), and how many mipmap levels should be created.
  11488. gtc->_generate_mipmaps = false;
  11489. int num_levels = 1;
  11490. CPTA_uchar image = tex->get_ram_mipmap_image(mipmap_bias);
  11491. bool can_generate = _supports_generate_mipmap;
  11492. #if defined(OPENGLES) && !defined(OPENGLES_1)
  11493. // OpenGL ES doesn't support generating mipmaps for sRGB textures, so we
  11494. // have to do this on the CPU, unless we have a special extension.
  11495. if (internal_format == GL_SRGB8 || internal_format == GL_SRGB8_ALPHA8) {
  11496. can_generate = has_extension("GL_NV_generate_mipmap_sRGB");
  11497. }
  11498. #endif
  11499. if (image.is_null()) {
  11500. // We don't even have a RAM image, so we have no choice but to let
  11501. // mipmaps be generated on the GPU.
  11502. if (uses_mipmaps) {
  11503. if (can_generate) {
  11504. num_levels = tex->get_expected_num_mipmap_levels() - mipmap_bias;
  11505. gtc->_generate_mipmaps = true;
  11506. } else {
  11507. // If it can't, do without mipmaps.
  11508. num_levels = 1;
  11509. glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  11510. }
  11511. }
  11512. } else {
  11513. if (uses_mipmaps) {
  11514. num_levels = tex->get_num_ram_mipmap_images() - mipmap_bias;
  11515. if (num_levels <= 1) {
  11516. // No RAM mipmap levels available. Should we generate some?
  11517. if (!can_generate || !driver_generate_mipmaps ||
  11518. image_compression != Texture::CM_off) {
  11519. // Yes, the GL can't or won't generate them, so we need to. Note
  11520. // that some drivers (nVidia) will *corrupt memory* if you ask
  11521. // them to generate mipmaps for a pre-compressed texture.
  11522. tex->generate_ram_mipmap_images();
  11523. num_levels = tex->get_num_ram_mipmap_images() - mipmap_bias;
  11524. }
  11525. }
  11526. if (num_levels <= 1) {
  11527. // We don't have mipmap levels in RAM. Ask the GL to generate them
  11528. // if it can.
  11529. if (can_generate) {
  11530. num_levels = tex->get_expected_num_mipmap_levels() - mipmap_bias;
  11531. gtc->_generate_mipmaps = true;
  11532. } else {
  11533. // If it can't, do without mipmaps.
  11534. glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  11535. num_levels = 1;
  11536. }
  11537. }
  11538. }
  11539. }
  11540. if (_supports_texture_max_level) {
  11541. // By the time we get here, we have a pretty good prediction for the
  11542. // number of mipmaps we're going to have, so tell the GL that's all it's
  11543. // going to get.
  11544. glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, num_levels - 1);
  11545. }
  11546. #ifndef OPENGLES_2
  11547. if (gtc->_generate_mipmaps && _glGenerateMipmap == nullptr) {
  11548. // The old, deprecated way to generate mipmaps.
  11549. glTexParameteri(target, GL_GENERATE_MIPMAP, GL_TRUE);
  11550. }
  11551. #endif
  11552. #ifndef OPENGLES
  11553. if (!_supports_luminance_texture) {
  11554. // Do we need to apply a swizzle mask to emulate these deprecated texture
  11555. // formats?
  11556. switch (tex->get_format()) {
  11557. case Texture::F_alpha:
  11558. glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_ZERO);
  11559. glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, GL_ZERO);
  11560. glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_ZERO);
  11561. glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, GL_RED);
  11562. break;
  11563. case Texture::F_luminance:
  11564. glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_RED);
  11565. glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, GL_RED);
  11566. glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_RED);
  11567. glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, GL_ONE);
  11568. break;
  11569. case Texture::F_luminance_alpha:
  11570. glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_RED);
  11571. glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, GL_RED);
  11572. glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_RED);
  11573. glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, GL_GREEN);
  11574. break;
  11575. default:
  11576. break;
  11577. }
  11578. }
  11579. #endif
  11580. // Allocate immutable storage for the texture, after which we can subload
  11581. // it. Pre-allocating storage using glTexStorage is more efficient than
  11582. // using glTexImage to load all of the individual images one by one later,
  11583. // but we are not allowed to change the texture size or number of mipmap
  11584. // levels after this point.
  11585. if (gl_immutable_texture_storage && _supports_tex_storage && !gtc->_has_storage) {
  11586. if (GLCAT.is_debug()) {
  11587. GLCAT.debug()
  11588. << "allocating storage for texture " << tex->get_name() << ", " << width
  11589. << " x " << height << " x " << depth << ", mipmaps " << num_levels
  11590. << ", uses_mipmaps = " << uses_mipmaps << "\n";
  11591. }
  11592. switch (tex->get_texture_type()) {
  11593. case Texture::TT_buffer_texture:
  11594. // Won't get here, but squelch compiler warning
  11595. case Texture::TT_1d_texture:
  11596. _glTexStorage1D(target, num_levels, internal_format, width);
  11597. break;
  11598. case Texture::TT_2d_texture:
  11599. case Texture::TT_cube_map:
  11600. case Texture::TT_1d_texture_array:
  11601. _glTexStorage2D(target, num_levels, internal_format, width, height);
  11602. break;
  11603. case Texture::TT_3d_texture:
  11604. case Texture::TT_2d_texture_array:
  11605. case Texture::TT_cube_map_array:
  11606. _glTexStorage3D(target, num_levels, internal_format, width, height, depth);
  11607. break;
  11608. }
  11609. gtc->_has_storage = true;
  11610. gtc->_immutable = true;
  11611. gtc->_uses_mipmaps = uses_mipmaps;
  11612. gtc->_internal_format = internal_format;
  11613. gtc->_width = width;
  11614. gtc->_height = height;
  11615. gtc->_depth = depth;
  11616. gtc->update_data_size_bytes(get_texture_memory_size(gtc));
  11617. needs_reload = false;
  11618. }
  11619. } else {
  11620. // Maybe we need to generate mipmaps on the CPU.
  11621. if (!image.is_null() && uses_mipmaps) {
  11622. if (tex->get_num_ram_mipmap_images() - mipmap_bias <= 1) {
  11623. // No RAM mipmap levels available. Should we generate some?
  11624. if (!_supports_generate_mipmap || !driver_generate_mipmaps ||
  11625. image_compression != Texture::CM_off) {
  11626. // Yes, the GL can't or won't generate them, so we need to. Note
  11627. // that some drivers (nVidia) will *corrupt memory* if you ask them
  11628. // to generate mipmaps for a pre-compressed texture.
  11629. tex->generate_ram_mipmap_images();
  11630. }
  11631. }
  11632. }
  11633. }
  11634. bool success = true;
  11635. if (tex->get_texture_type() == Texture::TT_cube_map) {
  11636. // A cube map must load six different 2-d images (which are stored as the
  11637. // six pages of the system ram image).
  11638. if (!_supports_cube_map) {
  11639. report_my_gl_errors();
  11640. return false;
  11641. }
  11642. nassertr(target == GL_TEXTURE_CUBE_MAP, false);
  11643. success = success && upload_texture_image
  11644. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  11645. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
  11646. internal_format, external_format, component_type,
  11647. true, 0, image_compression);
  11648. success = success && upload_texture_image
  11649. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  11650. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
  11651. internal_format, external_format, component_type,
  11652. true, 1, image_compression);
  11653. success = success && upload_texture_image
  11654. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  11655. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
  11656. internal_format, external_format, component_type,
  11657. true, 2, image_compression);
  11658. success = success && upload_texture_image
  11659. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  11660. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
  11661. internal_format, external_format, component_type,
  11662. true, 3, image_compression);
  11663. success = success && upload_texture_image
  11664. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  11665. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
  11666. internal_format, external_format, component_type,
  11667. true, 4, image_compression);
  11668. success = success && upload_texture_image
  11669. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  11670. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
  11671. internal_format, external_format, component_type,
  11672. true, 5, image_compression);
  11673. } else {
  11674. // Any other kind of texture can be loaded all at once.
  11675. success = upload_texture_image
  11676. (gtc, needs_reload, uses_mipmaps, mipmap_bias, target,
  11677. target, internal_format, external_format,
  11678. component_type, false, 0, image_compression);
  11679. }
  11680. if (gtc->_generate_mipmaps && _glGenerateMipmap != nullptr &&
  11681. !image.is_null()) {
  11682. // We uploaded an image; we may need to generate mipmaps.
  11683. if (GLCAT.is_debug()) {
  11684. GLCAT.debug()
  11685. << "generating mipmaps for texture " << tex->get_name() << ", "
  11686. << width << " x " << height << " x " << depth
  11687. << ", uses_mipmaps = " << uses_mipmaps << "\n";
  11688. }
  11689. _glGenerateMipmap(target);
  11690. }
  11691. maybe_gl_finish();
  11692. if (success) {
  11693. if (needs_reload) {
  11694. gtc->_has_storage = true;
  11695. gtc->_uses_mipmaps = uses_mipmaps;
  11696. gtc->_internal_format = internal_format;
  11697. gtc->_width = width;
  11698. gtc->_height = height;
  11699. gtc->_depth = depth;
  11700. gtc->update_data_size_bytes(get_texture_memory_size(gtc));
  11701. }
  11702. nassertr(gtc->_has_storage, false);
  11703. if (tex->get_post_load_store_cache()) {
  11704. tex->set_post_load_store_cache(false);
  11705. // OK, get the RAM image, and save it in a BamCache record.
  11706. if (do_extract_texture_data(gtc)) {
  11707. if (tex->has_ram_image()) {
  11708. BamCache *cache = BamCache::get_global_ptr();
  11709. PT(BamCacheRecord) record = cache->lookup(tex->get_fullpath(), "txo");
  11710. if (record != nullptr) {
  11711. record->set_data(tex, tex);
  11712. cache->store(record);
  11713. }
  11714. }
  11715. }
  11716. }
  11717. GraphicsEngine *engine = get_engine();
  11718. nassertr(engine != nullptr, false);
  11719. engine->texture_uploaded(tex);
  11720. gtc->mark_loaded();
  11721. report_my_gl_errors();
  11722. return true;
  11723. }
  11724. report_my_gl_errors();
  11725. return false;
  11726. }
  11727. /**
  11728. * Loads a texture image, or one page of a cube map image, from system RAM to
  11729. * texture memory.
  11730. *
  11731. * texture_target is normally the same thing as page_target; both represent
  11732. * the GL target onto which the texture image is loaded, e.g. GL_TEXTURE_1D,
  11733. * GL_TEXTURE_2D, etc. The only time they may differ is in the case of cube
  11734. * mapping, in which case texture_target will be target for the overall
  11735. * texture, e.g. GL_TEXTURE_CUBE_MAP, and page_target will be the target for
  11736. * this particular page, e.g. GL_TEXTURE_CUBE_MAP_POSITIVE_X.
  11737. */
  11738. bool CLP(GraphicsStateGuardian)::
  11739. upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
  11740. bool uses_mipmaps, int mipmap_bias,
  11741. GLenum texture_target, GLenum page_target,
  11742. GLint internal_format,
  11743. GLint external_format, GLenum component_type,
  11744. bool one_page_only, int z,
  11745. Texture::CompressionMode image_compression) {
  11746. // Make sure the error stack is cleared out before we begin.
  11747. clear_my_gl_errors();
  11748. if (texture_target == GL_NONE) {
  11749. // Unsupported target (e.g. 3-d texturing on GL 1.1).
  11750. return false;
  11751. }
  11752. if (image_compression != Texture::CM_off && !_supports_compressed_texture) {
  11753. return false;
  11754. }
  11755. Texture *tex = gtc->get_texture();
  11756. nassertr(tex != nullptr, false);
  11757. CPTA_uchar image = tex->get_ram_mipmap_image(mipmap_bias);
  11758. int width = tex->get_expected_mipmap_x_size(mipmap_bias);
  11759. int height = tex->get_expected_mipmap_y_size(mipmap_bias);
  11760. int depth = tex->get_expected_mipmap_z_size(mipmap_bias);
  11761. // Determine the number of images to upload.
  11762. int num_levels = mipmap_bias + 1;
  11763. if (uses_mipmaps) {
  11764. num_levels = tex->get_expected_num_mipmap_levels();
  11765. }
  11766. int num_ram_mipmap_levels = 0;
  11767. if (!image.is_null()) {
  11768. if (uses_mipmaps) {
  11769. num_ram_mipmap_levels = tex->get_num_ram_mipmap_images();
  11770. } else {
  11771. num_ram_mipmap_levels = 1;
  11772. }
  11773. }
  11774. #ifndef OPENGLES_1
  11775. if (needs_reload || num_ram_mipmap_levels > 0) {
  11776. // Make sure that any incoherent writes to this texture have been synced.
  11777. if (gtc->needs_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT)) {
  11778. issue_memory_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
  11779. }
  11780. }
  11781. #endif
  11782. if (!needs_reload) {
  11783. // Try to subload the image over the existing GL Texture object, possibly
  11784. // saving on texture memory fragmentation.
  11785. if (GLCAT.is_debug()) {
  11786. if (num_ram_mipmap_levels == 0) {
  11787. if (tex->has_clear_color()) {
  11788. GLCAT.debug()
  11789. << "clearing texture " << tex->get_name() << ", "
  11790. << width << " x " << height << " x " << depth << ", z = " << z
  11791. << ", uses_mipmaps = " << uses_mipmaps << ", clear_color = "
  11792. << tex->get_clear_color() << "\n";
  11793. } else {
  11794. GLCAT.debug()
  11795. << "not loading NULL image for texture " << tex->get_name()
  11796. << ", " << width << " x " << height << " x " << depth
  11797. << ", z = " << z << ", uses_mipmaps = " << uses_mipmaps << "\n";
  11798. }
  11799. } else {
  11800. GLCAT.debug()
  11801. << "updating image data of texture " << tex->get_name()
  11802. << ", " << width << " x " << height << " x " << depth
  11803. << ", z = " << z << ", mipmaps " << num_ram_mipmap_levels
  11804. << ", uses_mipmaps = " << uses_mipmaps << "\n";
  11805. }
  11806. }
  11807. for (int n = mipmap_bias; n < num_levels; ++n) {
  11808. // we grab the mipmap pointer first, if it is NULL we grab the normal
  11809. // mipmap image pointer which is a PTA_uchar
  11810. const unsigned char *image_ptr = (unsigned char*)tex->get_ram_mipmap_pointer(n);
  11811. CPTA_uchar ptimage;
  11812. if (image_ptr == nullptr) {
  11813. ptimage = tex->get_ram_mipmap_image(n);
  11814. if (ptimage.is_null()) {
  11815. if (n < num_ram_mipmap_levels) {
  11816. // We were told we'd have this many RAM mipmap images, but we
  11817. // don't. Raise a warning.
  11818. GLCAT.warning()
  11819. << "No mipmap level " << n << " defined for " << tex->get_name()
  11820. << "\n";
  11821. break;
  11822. }
  11823. if (tex->has_clear_color()) {
  11824. // The texture has a clear color, so we should fill this mipmap
  11825. // level to a solid color.
  11826. #ifndef OPENGLES
  11827. if (texture_target != GL_TEXTURE_BUFFER) {
  11828. if (_supports_clear_texture) {
  11829. // We can do that with the convenient glClearTexImage
  11830. // function.
  11831. vector_uchar clear_data = tex->get_clear_data();
  11832. _glClearTexImage(gtc->_index, n - mipmap_bias, external_format,
  11833. component_type, (void *)&clear_data[0]);
  11834. continue;
  11835. }
  11836. } else {
  11837. if (_supports_clear_buffer) {
  11838. // For buffer textures we need to clear the underlying
  11839. // storage.
  11840. vector_uchar clear_data = tex->get_clear_data();
  11841. _glClearBufferData(GL_TEXTURE_BUFFER, internal_format, external_format,
  11842. component_type, (const void *)&clear_data[0]);
  11843. continue;
  11844. }
  11845. }
  11846. #endif // OPENGLES
  11847. // Ask the Texture class to create the mipmap level in RAM. It'll
  11848. // fill it in with the correct clear color, which we can then
  11849. // upload.
  11850. ptimage = tex->make_ram_mipmap_image(n);
  11851. } else {
  11852. // No clear color and no more images.
  11853. break;
  11854. }
  11855. }
  11856. image_ptr = ptimage;
  11857. }
  11858. PTA_uchar bgr_image;
  11859. size_t view_size = tex->get_ram_mipmap_view_size(n);
  11860. if (image_ptr != nullptr) {
  11861. const unsigned char *orig_image_ptr = image_ptr;
  11862. image_ptr += view_size * gtc->get_view();
  11863. if (one_page_only) {
  11864. view_size = tex->get_ram_mipmap_page_size(n);
  11865. image_ptr += view_size * z;
  11866. }
  11867. nassertr(image_ptr >= orig_image_ptr && image_ptr + view_size <= orig_image_ptr + tex->get_ram_mipmap_image_size(n), false);
  11868. if (image_compression == Texture::CM_off) {
  11869. // If the GL doesn't claim to support BGR, we may have to reverse
  11870. // the component ordering of the image.
  11871. image_ptr = fix_component_ordering(bgr_image, image_ptr, view_size,
  11872. external_format, tex);
  11873. }
  11874. }
  11875. int width = tex->get_expected_mipmap_x_size(n);
  11876. int height = tex->get_expected_mipmap_y_size(n);
  11877. #ifndef OPENGLES_1
  11878. int depth = tex->get_expected_mipmap_z_size(n);
  11879. #endif
  11880. #ifdef DO_PSTATS
  11881. _data_transferred_pcollector.add_level(view_size);
  11882. #endif
  11883. switch (texture_target) {
  11884. #ifndef OPENGLES_1
  11885. case GL_TEXTURE_3D:
  11886. if (_supports_3d_texture) {
  11887. if (image_compression == Texture::CM_off) {
  11888. _glTexSubImage3D(page_target, n - mipmap_bias, 0, 0, 0, width, height, depth,
  11889. external_format, component_type, image_ptr);
  11890. } else {
  11891. _glCompressedTexSubImage3D(page_target, n - mipmap_bias, 0, 0, 0, width, height, depth,
  11892. external_format, view_size, image_ptr);
  11893. }
  11894. } else {
  11895. report_my_gl_errors();
  11896. return false;
  11897. }
  11898. break;
  11899. #endif // OPENGLES_1
  11900. #ifndef OPENGLES
  11901. case GL_TEXTURE_1D:
  11902. if (image_compression == Texture::CM_off) {
  11903. glTexSubImage1D(page_target, n - mipmap_bias, 0, width,
  11904. external_format, component_type, image_ptr);
  11905. } else {
  11906. _glCompressedTexSubImage1D(page_target, n - mipmap_bias, 0, width,
  11907. external_format, view_size, image_ptr);
  11908. }
  11909. break;
  11910. #endif // OPENGLES
  11911. #ifndef OPENGLES_1
  11912. case GL_TEXTURE_2D_ARRAY:
  11913. case GL_TEXTURE_CUBE_MAP_ARRAY:
  11914. if (_supports_2d_texture_array) {
  11915. if (image_compression == Texture::CM_off) {
  11916. _glTexSubImage3D(page_target, n - mipmap_bias, 0, 0, 0, width, height, depth,
  11917. external_format, component_type, image_ptr);
  11918. } else {
  11919. _glCompressedTexSubImage3D(page_target, n - mipmap_bias, 0, 0, 0, width, height, depth,
  11920. external_format, view_size, image_ptr);
  11921. }
  11922. } else {
  11923. report_my_gl_errors();
  11924. return false;
  11925. }
  11926. break;
  11927. #endif // OPENGLES_1
  11928. #ifndef OPENGLES
  11929. case GL_TEXTURE_BUFFER:
  11930. if (_supports_buffer_texture) {
  11931. _glBufferSubData(GL_TEXTURE_BUFFER, 0, view_size, image_ptr);
  11932. } else {
  11933. report_my_gl_errors();
  11934. return false;
  11935. }
  11936. break;
  11937. #endif // OPENGLES
  11938. default:
  11939. if (image_compression == Texture::CM_off) {
  11940. if (n==0) {
  11941. // It's unfortunate that we can't adjust the width, too, but
  11942. // TexSubImage2D doesn't accept a row-stride parameter.
  11943. height = tex->get_y_size() - tex->get_pad_y_size();
  11944. }
  11945. glTexSubImage2D(page_target, n - mipmap_bias, 0, 0, width, height,
  11946. external_format, component_type, image_ptr);
  11947. } else {
  11948. _glCompressedTexSubImage2D(page_target, n - mipmap_bias, 0, 0, width, height,
  11949. external_format, view_size, image_ptr);
  11950. }
  11951. break;
  11952. }
  11953. }
  11954. // Did that fail? If it did, we'll immediately try again, this time
  11955. // loading the texture from scratch.
  11956. GLenum error_code = gl_get_error();
  11957. if (error_code != GL_NO_ERROR) {
  11958. if (GLCAT.is_debug()) {
  11959. GLCAT.debug()
  11960. << "GL texture subload failed for " << tex->get_name()
  11961. << " : " << get_error_string(error_code) << "\n";
  11962. }
  11963. needs_reload = true;
  11964. }
  11965. }
  11966. if (needs_reload) {
  11967. // Load the image up from scratch, creating a new GL Texture object.
  11968. if (GLCAT.is_debug()) {
  11969. GLCAT.debug()
  11970. << "loading new texture object for " << tex->get_name() << ", " << width
  11971. << " x " << height << " x " << depth << ", z = " << z << ", mipmaps "
  11972. << num_ram_mipmap_levels << ", uses_mipmaps = " << uses_mipmaps << "\n";
  11973. }
  11974. // If there is immutable storage, this is impossible to do, and we should
  11975. // not have gotten here at all.
  11976. nassertr(!gtc->_immutable, false);
  11977. if (num_ram_mipmap_levels == 0) {
  11978. if (GLCAT.is_debug()) {
  11979. GLCAT.debug()
  11980. << " (initializing NULL image)\n";
  11981. }
  11982. if ((external_format == GL_DEPTH_STENCIL) && get_supports_depth_stencil()) {
  11983. #ifdef OPENGLES
  11984. component_type = GL_UNSIGNED_INT_24_8_OES;
  11985. #else
  11986. component_type = GL_UNSIGNED_INT_24_8_EXT;
  11987. #endif
  11988. }
  11989. }
  11990. for (int n = mipmap_bias; n < num_levels; ++n) {
  11991. const unsigned char *image_ptr = (unsigned char*)tex->get_ram_mipmap_pointer(n);
  11992. CPTA_uchar ptimage;
  11993. if (image_ptr == nullptr) {
  11994. ptimage = tex->get_ram_mipmap_image(n);
  11995. if (ptimage.is_null()) {
  11996. if (n < num_ram_mipmap_levels) {
  11997. // We were told we'd have this many RAM mipmap images, but we
  11998. // don't. Raise a warning.
  11999. GLCAT.warning()
  12000. << "No mipmap level " << n << " defined for " << tex->get_name()
  12001. << "\n";
  12002. if (_supports_texture_max_level) {
  12003. // Tell the GL we have no more mipmaps for it to use.
  12004. glTexParameteri(texture_target, GL_TEXTURE_MAX_LEVEL, n - mipmap_bias);
  12005. }
  12006. break;
  12007. }
  12008. if (tex->has_clear_color()) {
  12009. // Ask the Texture class to create the mipmap level in RAM. It'll
  12010. // fill it in with the correct clear color, which we can then
  12011. // upload.
  12012. ptimage = tex->make_ram_mipmap_image(n);
  12013. } else if (image_compression != Texture::CM_off) {
  12014. // We can't upload a NULL compressed texture.
  12015. if (_supports_texture_max_level) {
  12016. // Tell the GL we have no more mipmaps for it to use.
  12017. glTexParameteri(texture_target, GL_TEXTURE_MAX_LEVEL, n - mipmap_bias);
  12018. }
  12019. break;
  12020. }
  12021. }
  12022. image_ptr = ptimage;
  12023. }
  12024. PTA_uchar bgr_image;
  12025. size_t view_size = tex->get_ram_mipmap_view_size(n);
  12026. if (image_ptr != nullptr) {
  12027. const unsigned char *orig_image_ptr = image_ptr;
  12028. image_ptr += view_size * gtc->get_view();
  12029. if (one_page_only) {
  12030. view_size = tex->get_ram_mipmap_page_size(n);
  12031. image_ptr += view_size * z;
  12032. }
  12033. nassertr(image_ptr >= orig_image_ptr && image_ptr + view_size <= orig_image_ptr + tex->get_ram_mipmap_image_size(n), false);
  12034. if (image_compression == Texture::CM_off) {
  12035. // If the GL doesn't claim to support BGR, we may have to reverse
  12036. // the component ordering of the image.
  12037. image_ptr = fix_component_ordering(bgr_image, image_ptr, view_size,
  12038. external_format, tex);
  12039. }
  12040. }
  12041. int width = tex->get_expected_mipmap_x_size(n);
  12042. int height = tex->get_expected_mipmap_y_size(n);
  12043. #ifndef OPENGLES_1
  12044. int depth = tex->get_expected_mipmap_z_size(n);
  12045. #endif
  12046. #ifdef DO_PSTATS
  12047. _data_transferred_pcollector.add_level(view_size);
  12048. #endif
  12049. switch (texture_target) {
  12050. #ifndef OPENGLES // 1-d textures not supported by OpenGL ES. Fall through.
  12051. case GL_TEXTURE_1D:
  12052. if (image_compression == Texture::CM_off) {
  12053. glTexImage1D(page_target, n - mipmap_bias, internal_format,
  12054. width, 0,
  12055. external_format, component_type, image_ptr);
  12056. } else {
  12057. _glCompressedTexImage1D(page_target, n - mipmap_bias, external_format, width,
  12058. 0, view_size, image_ptr);
  12059. }
  12060. break;
  12061. #endif // OPENGLES // OpenGL ES will fall through.
  12062. #ifndef OPENGLES_1
  12063. case GL_TEXTURE_3D:
  12064. if (_supports_3d_texture) {
  12065. if (image_compression == Texture::CM_off) {
  12066. _glTexImage3D(page_target, n - mipmap_bias, internal_format,
  12067. width, height, depth, 0,
  12068. external_format, component_type, image_ptr);
  12069. } else {
  12070. _glCompressedTexImage3D(page_target, n - mipmap_bias, external_format, width,
  12071. height, depth,
  12072. 0, view_size, image_ptr);
  12073. }
  12074. } else {
  12075. report_my_gl_errors();
  12076. return false;
  12077. }
  12078. break;
  12079. #endif // OPENGLES_1
  12080. #ifndef OPENGLES_1
  12081. case GL_TEXTURE_2D_ARRAY:
  12082. case GL_TEXTURE_CUBE_MAP_ARRAY:
  12083. if (_supports_2d_texture_array) {
  12084. if (image_compression == Texture::CM_off) {
  12085. _glTexImage3D(page_target, n - mipmap_bias, internal_format,
  12086. width, height, depth, 0,
  12087. external_format, component_type, image_ptr);
  12088. } else {
  12089. _glCompressedTexImage3D(page_target, n - mipmap_bias, external_format, width,
  12090. height, depth,
  12091. 0, view_size, image_ptr);
  12092. }
  12093. } else {
  12094. report_my_gl_errors();
  12095. return false;
  12096. }
  12097. break;
  12098. #endif // OPENGLES_1
  12099. #ifndef OPENGLES
  12100. case GL_TEXTURE_BUFFER:
  12101. if (_supports_buffer_texture) {
  12102. _glBufferData(GL_TEXTURE_BUFFER, view_size, image_ptr,
  12103. get_usage(tex->get_usage_hint()));
  12104. } else {
  12105. report_my_gl_errors();
  12106. return false;
  12107. }
  12108. break;
  12109. #endif // OPENGLES
  12110. default:
  12111. if (image_compression == Texture::CM_off) {
  12112. glTexImage2D(page_target, n - mipmap_bias, internal_format,
  12113. width, height, 0,
  12114. external_format, component_type, image_ptr);
  12115. } else {
  12116. _glCompressedTexImage2D(page_target, n - mipmap_bias, external_format,
  12117. width, height, 0, view_size, image_ptr);
  12118. }
  12119. }
  12120. }
  12121. // Report the error message explicitly if the GL texture creation failed.
  12122. GLenum error_code = gl_get_error();
  12123. if (error_code != GL_NO_ERROR) {
  12124. GLCAT.error()
  12125. << "GL texture creation failed for " << tex->get_name()
  12126. << " : " << get_error_string(error_code) << "\n";
  12127. gtc->_has_storage = false;
  12128. return false;
  12129. }
  12130. }
  12131. report_my_gl_errors();
  12132. return true;
  12133. }
  12134. /**
  12135. * Causes mipmaps to be generated for an uploaded texture.
  12136. */
  12137. void CLP(GraphicsStateGuardian)::
  12138. generate_mipmaps(CLP(TextureContext) *gtc) {
  12139. #ifndef OPENGLES
  12140. if (_supports_dsa) {
  12141. // OpenGL 4.5 offers an easy way to do this without binding.
  12142. _glGenerateTextureMipmap(gtc->_index);
  12143. return;
  12144. }
  12145. #endif
  12146. if (_glGenerateMipmap != nullptr) {
  12147. _state_texture = 0;
  12148. update_texture(gtc, true);
  12149. apply_texture(gtc);
  12150. _glGenerateMipmap(gtc->_target);
  12151. glBindTexture(gtc->_target, 0);
  12152. }
  12153. }
  12154. /**
  12155. * This is used as a standin for upload_texture when the texture in question
  12156. * is unavailable (e.g. it hasn't yet been loaded from disk). Until the
  12157. * texture image itself becomes available, we will render the texture's
  12158. * "simple" image--a sharply reduced version of the same texture.
  12159. */
  12160. bool CLP(GraphicsStateGuardian)::
  12161. upload_simple_texture(CLP(TextureContext) *gtc) {
  12162. report_my_gl_errors();
  12163. PStatGPUTimer timer(this, _load_texture_pcollector);
  12164. Texture *tex = gtc->get_texture();
  12165. nassertr(tex != nullptr, false);
  12166. GLenum internal_format = GL_RGBA;
  12167. GLenum external_format = GL_BGRA;
  12168. const unsigned char *image_ptr = tex->get_simple_ram_image();
  12169. if (image_ptr == nullptr) {
  12170. return false;
  12171. }
  12172. size_t image_size = tex->get_simple_ram_image_size();
  12173. PTA_uchar bgr_image;
  12174. if (!_supports_bgr) {
  12175. // If the GL doesn't claim to support BGR, we may have to reverse the
  12176. // component ordering of the image.
  12177. external_format = GL_RGBA;
  12178. image_ptr = fix_component_ordering(bgr_image, image_ptr, image_size,
  12179. external_format, tex);
  12180. }
  12181. int width = tex->get_simple_x_size();
  12182. int height = tex->get_simple_y_size();
  12183. GLenum component_type = GL_UNSIGNED_BYTE;
  12184. if (GLCAT.is_debug()) {
  12185. GLCAT.debug()
  12186. << "loading simple image for " << tex->get_name() << "\n";
  12187. }
  12188. // Turn off mipmaps for the simple texture.
  12189. if (tex->uses_mipmaps() && _supports_texture_max_level) {
  12190. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
  12191. }
  12192. #ifdef DO_PSTATS
  12193. _data_transferred_pcollector.add_level(image_size);
  12194. #endif
  12195. #ifdef OPENGLES
  12196. internal_format = external_format;
  12197. #endif
  12198. glTexImage2D(GL_TEXTURE_2D, 0, internal_format,
  12199. width, height, 0,
  12200. external_format, component_type, image_ptr);
  12201. gtc->mark_simple_loaded();
  12202. report_my_gl_errors();
  12203. return true;
  12204. }
  12205. /**
  12206. * Asks OpenGL how much texture memory is consumed by the indicated texture
  12207. * (which is also the currently-selected texture).
  12208. */
  12209. size_t CLP(GraphicsStateGuardian)::
  12210. get_texture_memory_size(CLP(TextureContext) *gtc) {
  12211. Texture *tex = gtc->get_texture();
  12212. #ifdef OPENGLES // Texture querying not supported on OpenGL ES.
  12213. int width = tex->get_x_size();
  12214. int height = tex->get_y_size();
  12215. int depth = 1;
  12216. int scale = 1;
  12217. size_t num_bytes = 2; // Temporary assumption?
  12218. #else
  12219. GLenum target = get_texture_target(tex->get_texture_type());
  12220. GLenum page_target = target;
  12221. GLint scale = 1;
  12222. if (target == GL_TEXTURE_CUBE_MAP) {
  12223. // We need a particular page to get the level parameter from.
  12224. page_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
  12225. scale = 6;
  12226. } else if (target == GL_TEXTURE_BUFFER) {
  12227. // In the case of buffer textures, we provided the size to begin with, so
  12228. // no point in querying anything. Plus, glGetTexParameter is not even
  12229. // supported for buffer textures.
  12230. return tex->get_expected_ram_image_size();
  12231. }
  12232. clear_my_gl_errors();
  12233. GLint internal_format;
  12234. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_INTERNAL_FORMAT, &internal_format);
  12235. if (is_compressed_format(internal_format)) {
  12236. // Try to get the compressed size.
  12237. GLint image_size;
  12238. glGetTexLevelParameteriv(page_target, 0,
  12239. GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &image_size);
  12240. GLenum error_code = gl_get_error();
  12241. if (error_code != GL_NO_ERROR) {
  12242. if (GLCAT.is_debug()) {
  12243. GLCAT.debug()
  12244. << "Couldn't get compressed size for " << tex->get_name()
  12245. << " : " << get_error_string(error_code) << "\n";
  12246. }
  12247. // Fall through to the noncompressed case.
  12248. } else {
  12249. return image_size * scale;
  12250. }
  12251. }
  12252. // OK, get the noncompressed size.
  12253. GLint red_size, green_size, blue_size, alpha_size;
  12254. GLint depth_size = 0, luminance_size = 0, intensity_size = 0;
  12255. glGetTexLevelParameteriv(page_target, 0,
  12256. GL_TEXTURE_RED_SIZE, &red_size);
  12257. glGetTexLevelParameteriv(page_target, 0,
  12258. GL_TEXTURE_GREEN_SIZE, &green_size);
  12259. glGetTexLevelParameteriv(page_target, 0,
  12260. GL_TEXTURE_BLUE_SIZE, &blue_size);
  12261. glGetTexLevelParameteriv(page_target, 0,
  12262. GL_TEXTURE_ALPHA_SIZE, &alpha_size);
  12263. if (get_supports_luminance_texture()) {
  12264. glGetTexLevelParameteriv(page_target, 0,
  12265. GL_TEXTURE_LUMINANCE_SIZE, &luminance_size);
  12266. glGetTexLevelParameteriv(page_target, 0,
  12267. GL_TEXTURE_INTENSITY_SIZE, &intensity_size);
  12268. }
  12269. if (get_supports_depth_texture()) {
  12270. glGetTexLevelParameteriv(page_target, 0,
  12271. GL_TEXTURE_DEPTH_SIZE, &depth_size);
  12272. }
  12273. GLint width = 1, height = 1, depth = 1;
  12274. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_WIDTH, &width);
  12275. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_HEIGHT, &height);
  12276. if (_supports_3d_texture || _supports_2d_texture_array) {
  12277. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_DEPTH, &depth);
  12278. }
  12279. report_my_gl_errors();
  12280. size_t num_bits = (red_size + green_size + blue_size + alpha_size + luminance_size + intensity_size + depth_size);
  12281. size_t num_bytes = (num_bits + 7) / 8;
  12282. #endif // OPENGLES
  12283. size_t result = num_bytes * width * height * depth * scale;
  12284. if (gtc->_uses_mipmaps) {
  12285. result = (result * 4) / 3;
  12286. }
  12287. return result;
  12288. }
  12289. /**
  12290. * Checks the list of resident texture objects to see if any have recently
  12291. * been evicted.
  12292. */
  12293. void CLP(GraphicsStateGuardian)::
  12294. check_nonresident_texture(BufferContextChain &chain) {
  12295. #if defined(SUPPORT_FIXED_FUNCTION) && !defined(OPENGLES) // Residency queries not supported by OpenGL ES.
  12296. size_t num_textures = chain.get_count();
  12297. if (num_textures == 0) {
  12298. return;
  12299. }
  12300. CLP(TextureContext) **gtc_list = (CLP(TextureContext) **)alloca(num_textures * sizeof(CLP(TextureContext) *));
  12301. GLuint *texture_list = (GLuint *)alloca(num_textures * sizeof(GLuint));
  12302. size_t ti = 0;
  12303. BufferContext *node = chain.get_first();
  12304. while (node != nullptr) {
  12305. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), node);
  12306. gtc_list[ti] = gtc;
  12307. texture_list[ti] = gtc->_index;
  12308. node = node->get_next();
  12309. ++ti;
  12310. }
  12311. nassertv(ti == num_textures);
  12312. GLboolean *results = (GLboolean *)alloca(num_textures * sizeof(GLboolean));
  12313. bool all_resident = (glAreTexturesResident(num_textures, texture_list, results) != 0);
  12314. report_my_gl_errors();
  12315. if (!all_resident) {
  12316. // Some are now nonresident.
  12317. for (ti = 0; ti < num_textures; ++ti) {
  12318. if (!results[ti]) {
  12319. gtc_list[ti]->set_resident(false);
  12320. }
  12321. }
  12322. }
  12323. #endif // OPENGLES
  12324. }
  12325. /**
  12326. * The internal implementation of extract_texture_data(), given an already-
  12327. * created TextureContext.
  12328. */
  12329. bool CLP(GraphicsStateGuardian)::
  12330. do_extract_texture_data(CLP(TextureContext) *gtc) {
  12331. report_my_gl_errors();
  12332. GLenum target = gtc->_target;
  12333. if (target == GL_NONE) {
  12334. return false;
  12335. }
  12336. #ifndef OPENGLES_1
  12337. // Make sure any incoherent writes to the texture have been synced.
  12338. if (gtc->needs_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT)) {
  12339. issue_memory_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
  12340. }
  12341. #endif
  12342. Texture *tex = gtc->get_texture();
  12343. glBindTexture(target, gtc->_index);
  12344. if (GLCAT.is_spam()) {
  12345. GLCAT.spam()
  12346. << "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << "): " << *tex << "\n";
  12347. }
  12348. #ifndef OPENGLES
  12349. if (target == GL_TEXTURE_BUFFER) {
  12350. _glBindBuffer(GL_TEXTURE_BUFFER, gtc->_buffer);
  12351. }
  12352. #endif
  12353. GLint wrap_u, wrap_v, wrap_w;
  12354. GLint minfilter, magfilter;
  12355. #ifndef OPENGLES
  12356. GLfloat border_color[4];
  12357. #endif
  12358. #ifdef OPENGLES
  12359. if (true) {
  12360. #else
  12361. if (target != GL_TEXTURE_BUFFER) {
  12362. #endif
  12363. glGetTexParameteriv(target, GL_TEXTURE_WRAP_S, &wrap_u);
  12364. glGetTexParameteriv(target, GL_TEXTURE_WRAP_T, &wrap_v);
  12365. wrap_w = GL_REPEAT;
  12366. #ifndef OPENGLES_1
  12367. if (_supports_3d_texture) {
  12368. glGetTexParameteriv(target, GL_TEXTURE_WRAP_R, &wrap_w);
  12369. }
  12370. #endif
  12371. glGetTexParameteriv(target, GL_TEXTURE_MIN_FILTER, &minfilter);
  12372. glGetTexParameteriv(target, GL_TEXTURE_MAG_FILTER, &magfilter);
  12373. #ifndef OPENGLES
  12374. glGetTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, border_color);
  12375. #endif
  12376. }
  12377. GLenum page_target = target;
  12378. if (target == GL_TEXTURE_CUBE_MAP) {
  12379. // We need a particular page to get the level parameter from.
  12380. page_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
  12381. }
  12382. GLint width = gtc->_width, height = gtc->_height, depth = gtc->_depth;
  12383. #ifndef OPENGLES
  12384. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_WIDTH, &width);
  12385. if (target != GL_TEXTURE_1D) {
  12386. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_HEIGHT, &height);
  12387. }
  12388. if (_supports_3d_texture && target == GL_TEXTURE_3D) {
  12389. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_DEPTH, &depth);
  12390. } else if (target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_CUBE_MAP_ARRAY) {
  12391. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_DEPTH, &depth);
  12392. } else if (target == GL_TEXTURE_CUBE_MAP) {
  12393. depth = 6;
  12394. }
  12395. #endif
  12396. clear_my_gl_errors();
  12397. if (width <= 0 || height <= 0 || depth <= 0) {
  12398. GLCAT.error()
  12399. << "No texture data for " << tex->get_name() << "\n";
  12400. return false;
  12401. }
  12402. GLint internal_format = GL_RGBA;
  12403. #ifndef OPENGLES
  12404. if (target != GL_TEXTURE_BUFFER) {
  12405. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_INTERNAL_FORMAT, &internal_format);
  12406. } else {
  12407. // Some drivers give the wrong result for the above call. No problem; we
  12408. // already know the internal format of a buffer texture since glTexBuffer
  12409. // required passing the exact sized format.
  12410. internal_format = gtc->_internal_format;
  12411. }
  12412. #endif // OPENGLES
  12413. // Make sure we were able to query those parameters properly.
  12414. GLenum error_code = gl_get_error();
  12415. if (error_code != GL_NO_ERROR) {
  12416. GLCAT.error()
  12417. << "Unable to query texture parameters for " << tex->get_name()
  12418. << " : " << get_error_string(error_code) << "\n";
  12419. return false;
  12420. }
  12421. Texture::ComponentType type = Texture::T_unsigned_byte;
  12422. Texture::Format format = Texture::F_rgb;
  12423. Texture::CompressionMode compression = Texture::CM_off;
  12424. switch (internal_format) {
  12425. #ifndef OPENGLES
  12426. case GL_COLOR_INDEX:
  12427. format = Texture::F_color_index;
  12428. break;
  12429. #endif
  12430. #if GL_DEPTH_COMPONENT != GL_DEPTH_COMPONENT24
  12431. case GL_DEPTH_COMPONENT:
  12432. #endif
  12433. case GL_DEPTH_COMPONENT16:
  12434. case GL_DEPTH_COMPONENT24:
  12435. case GL_DEPTH_COMPONENT32:
  12436. type = Texture::T_unsigned_short;
  12437. format = Texture::F_depth_component;
  12438. break;
  12439. #ifndef OPENGLES
  12440. case GL_DEPTH_COMPONENT32F:
  12441. type = Texture::T_float;
  12442. format = Texture::F_depth_component;
  12443. break;
  12444. #endif
  12445. case GL_DEPTH_STENCIL:
  12446. case GL_DEPTH24_STENCIL8:
  12447. type = Texture::T_unsigned_int_24_8;
  12448. format = Texture::F_depth_stencil;
  12449. break;
  12450. #ifndef OPENGLES
  12451. case GL_DEPTH32F_STENCIL8:
  12452. type = Texture::T_float;
  12453. format = Texture::F_depth_stencil;
  12454. break;
  12455. #endif
  12456. case GL_RGBA:
  12457. case 4:
  12458. format = Texture::F_rgba;
  12459. break;
  12460. case GL_RGBA4:
  12461. format = Texture::F_rgba4;
  12462. break;
  12463. #ifdef OPENGLES
  12464. case GL_RGBA8_OES:
  12465. format = Texture::F_rgba8;
  12466. break;
  12467. #else
  12468. case GL_RGBA8:
  12469. format = Texture::F_rgba8;
  12470. break;
  12471. #endif
  12472. #ifndef OPENGLES
  12473. case GL_RGBA12:
  12474. type = Texture::T_unsigned_short;
  12475. format = Texture::F_rgba12;
  12476. break;
  12477. #endif
  12478. case GL_RGB:
  12479. case 3:
  12480. format = Texture::F_rgb;
  12481. break;
  12482. #ifndef OPENGLES
  12483. case GL_RGB5:
  12484. format = Texture::F_rgb5;
  12485. break;
  12486. #endif
  12487. case GL_RGB5_A1:
  12488. format = Texture::F_rgba5;
  12489. break;
  12490. #ifndef OPENGLES
  12491. case GL_RGB8:
  12492. format = Texture::F_rgb8;
  12493. break;
  12494. case GL_RGB12:
  12495. format = Texture::F_rgb12;
  12496. break;
  12497. case GL_RGBA16:
  12498. format = Texture::F_rgba16;
  12499. break;
  12500. case GL_R3_G3_B2:
  12501. format = Texture::F_rgb332;
  12502. break;
  12503. case GL_R8I:
  12504. type = Texture::T_byte;
  12505. format = Texture::F_r8i;
  12506. break;
  12507. case GL_RG8I:
  12508. type = Texture::T_byte;
  12509. format = Texture::F_rg8i;
  12510. break;
  12511. case GL_RGB8I:
  12512. type = Texture::T_byte;
  12513. format = Texture::F_rgb8i;
  12514. break;
  12515. case GL_RGBA8I:
  12516. type = Texture::T_byte;
  12517. format = Texture::F_rgba8i;
  12518. break;
  12519. case GL_R8UI:
  12520. type = Texture::T_unsigned_byte;
  12521. format = Texture::F_r8i;
  12522. break;
  12523. case GL_RG8UI:
  12524. type = Texture::T_unsigned_byte;
  12525. format = Texture::F_rg8i;
  12526. break;
  12527. case GL_RGB8UI:
  12528. type = Texture::T_unsigned_byte;
  12529. format = Texture::F_rgb8i;
  12530. break;
  12531. case GL_RGBA8UI:
  12532. type = Texture::T_unsigned_byte;
  12533. format = Texture::F_rgba8i;
  12534. break;
  12535. case GL_R16I:
  12536. type = Texture::T_short;
  12537. format = Texture::F_r16i;
  12538. break;
  12539. case GL_R16UI:
  12540. type = Texture::T_unsigned_short;
  12541. format = Texture::F_r16i;
  12542. break;
  12543. #endif
  12544. #ifndef OPENGLES_1
  12545. case GL_RGBA16F:
  12546. type = Texture::T_float;
  12547. format = Texture::F_rgba16;
  12548. break;
  12549. case GL_RGB16F:
  12550. type = Texture::T_float;
  12551. format = Texture::F_rgb16;
  12552. break;
  12553. case GL_RG16F:
  12554. type = Texture::T_float;
  12555. format = Texture::F_rg16;
  12556. break;
  12557. case GL_R16F:
  12558. type = Texture::T_float;
  12559. format = Texture::F_r16;
  12560. break;
  12561. case GL_RGBA32F:
  12562. type = Texture::T_float;
  12563. format = Texture::F_rgba32;
  12564. break;
  12565. case GL_RGB32F:
  12566. type = Texture::T_float;
  12567. format = Texture::F_rgb32;
  12568. break;
  12569. case GL_RG32F:
  12570. type = Texture::T_float;
  12571. format = Texture::F_rg32;
  12572. break;
  12573. case GL_R32F:
  12574. type = Texture::T_float;
  12575. format = Texture::F_r32;
  12576. break;
  12577. #endif
  12578. #ifndef OPENGLES
  12579. case GL_RGB16:
  12580. type = Texture::T_unsigned_short;
  12581. format = Texture::F_rgb16;
  12582. break;
  12583. case GL_RG16:
  12584. type = Texture::T_unsigned_short;
  12585. format = Texture::F_rg16;
  12586. break;
  12587. case GL_R16:
  12588. type = Texture::T_unsigned_short;
  12589. format = Texture::F_r16;
  12590. break;
  12591. case GL_RGB16_SNORM:
  12592. type = Texture::T_short;
  12593. format = Texture::F_rgb16;
  12594. break;
  12595. case GL_RG16_SNORM:
  12596. type = Texture::T_short;
  12597. format = Texture::F_rg16;
  12598. break;
  12599. case GL_R16_SNORM:
  12600. type = Texture::T_short;
  12601. format = Texture::F_r16;
  12602. break;
  12603. #endif
  12604. #ifndef OPENGLES_1
  12605. case GL_R11F_G11F_B10F:
  12606. type = Texture::T_float;
  12607. format = Texture::F_r11_g11_b10;
  12608. break;
  12609. case GL_RGB9_E5:
  12610. type = Texture::T_float;
  12611. format = Texture::F_rgb9_e5;
  12612. break;
  12613. case GL_RGB10_A2:
  12614. type = Texture::T_unsigned_short;
  12615. format = Texture::F_rgb10_a2;
  12616. break;
  12617. #endif
  12618. #ifdef OPENGLES_2
  12619. case GL_RED_EXT:
  12620. case GL_R8_EXT:
  12621. format = Texture::F_red;
  12622. break;
  12623. #endif
  12624. #ifndef OPENGLES
  12625. case GL_R32I:
  12626. type = Texture::T_int;
  12627. format = Texture::F_r32i;
  12628. break;
  12629. #endif
  12630. #ifndef OPENGLES
  12631. case GL_RED:
  12632. format = Texture::F_red;
  12633. break;
  12634. case GL_GREEN:
  12635. format = Texture::F_green;
  12636. break;
  12637. case GL_BLUE:
  12638. format = Texture::F_blue;
  12639. break;
  12640. #endif // OPENGLES
  12641. case GL_ALPHA:
  12642. format = Texture::F_alpha;
  12643. break;
  12644. case GL_LUMINANCE:
  12645. #ifndef OPENGLES
  12646. case GL_LUMINANCE16:
  12647. case GL_LUMINANCE16F_ARB:
  12648. #endif
  12649. case 1:
  12650. format = Texture::F_luminance;
  12651. break;
  12652. case GL_LUMINANCE_ALPHA:
  12653. #ifndef OPENGLES
  12654. case GL_LUMINANCE_ALPHA16F_ARB:
  12655. #endif
  12656. case 2:
  12657. format = Texture::F_luminance_alpha;
  12658. break;
  12659. #ifndef OPENGLES_1
  12660. case GL_SRGB:
  12661. case GL_SRGB8:
  12662. format = Texture::F_srgb;
  12663. break;
  12664. case GL_SRGB_ALPHA:
  12665. case GL_SRGB8_ALPHA8:
  12666. format = Texture::F_srgb_alpha;
  12667. break;
  12668. #endif // OPENGLES_1
  12669. #ifndef OPENGLES
  12670. case GL_SLUMINANCE:
  12671. case GL_SLUMINANCE8:
  12672. format = Texture::F_sluminance;
  12673. break;
  12674. case GL_SLUMINANCE_ALPHA:
  12675. case GL_SLUMINANCE8_ALPHA8:
  12676. format = Texture::F_sluminance_alpha;
  12677. break;
  12678. #endif // OPENGLES
  12679. #ifndef OPENGLES
  12680. case GL_COMPRESSED_RGB:
  12681. format = Texture::F_rgb;
  12682. compression = Texture::CM_on;
  12683. break;
  12684. case GL_COMPRESSED_RGBA:
  12685. format = Texture::F_rgba;
  12686. compression = Texture::CM_on;
  12687. break;
  12688. case GL_COMPRESSED_ALPHA:
  12689. format = Texture::F_alpha;
  12690. compression = Texture::CM_on;
  12691. break;
  12692. case GL_COMPRESSED_LUMINANCE:
  12693. format = Texture::F_luminance;
  12694. compression = Texture::CM_on;
  12695. break;
  12696. case GL_COMPRESSED_LUMINANCE_ALPHA:
  12697. format = Texture::F_luminance_alpha;
  12698. compression = Texture::CM_on;
  12699. break;
  12700. case GL_COMPRESSED_SRGB:
  12701. format = Texture::F_srgb;
  12702. compression = Texture::CM_on;
  12703. break;
  12704. case GL_COMPRESSED_SRGB_ALPHA:
  12705. format = Texture::F_srgb_alpha;
  12706. compression = Texture::CM_on;
  12707. break;
  12708. case GL_COMPRESSED_SLUMINANCE:
  12709. format = Texture::F_sluminance;
  12710. compression = Texture::CM_on;
  12711. break;
  12712. case GL_COMPRESSED_SLUMINANCE_ALPHA:
  12713. format = Texture::F_sluminance_alpha;
  12714. compression = Texture::CM_on;
  12715. break;
  12716. #endif
  12717. case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  12718. format = Texture::F_rgb;
  12719. compression = Texture::CM_dxt1;
  12720. break;
  12721. case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  12722. format = Texture::F_rgbm;
  12723. compression = Texture::CM_dxt1;
  12724. break;
  12725. #ifndef OPENGLES
  12726. case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
  12727. format = Texture::F_srgb;
  12728. compression = Texture::CM_dxt1;
  12729. break;
  12730. case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
  12731. format = Texture::F_srgb_alpha;
  12732. compression = Texture::CM_dxt1;
  12733. break;
  12734. #endif
  12735. #ifdef OPENGLES
  12736. case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
  12737. format = Texture::F_rgb;
  12738. compression = Texture::CM_pvr1_2bpp;
  12739. break;
  12740. case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
  12741. format = Texture::F_rgba;
  12742. compression = Texture::CM_pvr1_2bpp;
  12743. break;
  12744. case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
  12745. format = Texture::F_rgb;
  12746. compression = Texture::CM_pvr1_4bpp;
  12747. break;
  12748. case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
  12749. format = Texture::F_rgba;
  12750. compression = Texture::CM_pvr1_4bpp;
  12751. break;
  12752. #else
  12753. case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
  12754. format = Texture::F_rgba;
  12755. compression = Texture::CM_dxt3;
  12756. break;
  12757. case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
  12758. format = Texture::F_rgba;
  12759. compression = Texture::CM_dxt5;
  12760. break;
  12761. case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
  12762. format = Texture::F_srgb_alpha;
  12763. compression = Texture::CM_dxt3;
  12764. break;
  12765. case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
  12766. format = Texture::F_srgb_alpha;
  12767. compression = Texture::CM_dxt5;
  12768. break;
  12769. case GL_COMPRESSED_RGB_FXT1_3DFX:
  12770. format = Texture::F_rgb;
  12771. compression = Texture::CM_fxt1;
  12772. break;
  12773. case GL_COMPRESSED_RGBA_FXT1_3DFX:
  12774. format = Texture::F_rgba;
  12775. compression = Texture::CM_fxt1;
  12776. break;
  12777. case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
  12778. format = Texture::F_luminance;
  12779. compression = Texture::CM_rgtc;
  12780. break;
  12781. case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
  12782. format = Texture::F_luminance_alpha;
  12783. compression = Texture::CM_rgtc;
  12784. break;
  12785. case GL_COMPRESSED_RED_RGTC1:
  12786. format = Texture::F_red;
  12787. compression = Texture::CM_rgtc;
  12788. break;
  12789. case GL_COMPRESSED_SIGNED_RED_RGTC1:
  12790. type = Texture::T_byte;
  12791. format = Texture::F_red;
  12792. compression = Texture::CM_rgtc;
  12793. break;
  12794. case GL_COMPRESSED_RG_RGTC2:
  12795. format = Texture::F_rg;
  12796. compression = Texture::CM_rgtc;
  12797. break;
  12798. case GL_COMPRESSED_SIGNED_RG_RGTC2:
  12799. type = Texture::T_byte;
  12800. format = Texture::F_rg;
  12801. compression = Texture::CM_rgtc;
  12802. break;
  12803. #endif
  12804. default:
  12805. GLCAT.warning()
  12806. << "Unhandled internal format for " << tex->get_name()
  12807. << " : " << hex << "0x" << internal_format << dec << "\n";
  12808. return false;
  12809. }
  12810. // We don't want to call setup_texture() again; that resets too much.
  12811. // Instead, we'll just set the individual components.
  12812. tex->set_x_size(width);
  12813. tex->set_y_size(height);
  12814. tex->set_z_size(depth);
  12815. tex->set_component_type(type);
  12816. tex->set_format(format);
  12817. #ifdef OPENGLES
  12818. if (true) {
  12819. #else
  12820. if (target != GL_TEXTURE_BUFFER) {
  12821. #endif
  12822. tex->set_wrap_u(get_panda_wrap_mode(wrap_u));
  12823. tex->set_wrap_v(get_panda_wrap_mode(wrap_v));
  12824. tex->set_wrap_w(get_panda_wrap_mode(wrap_w));
  12825. tex->set_minfilter(get_panda_filter_type(minfilter));
  12826. //tex->set_magfilter(get_panda_filter_type(magfilter));
  12827. #ifndef OPENGLES
  12828. tex->set_border_color(LColor(border_color[0], border_color[1],
  12829. border_color[2], border_color[3]));
  12830. #endif
  12831. }
  12832. PTA_uchar image;
  12833. size_t page_size = 0;
  12834. if (!extract_texture_image(image, page_size, tex, target, page_target,
  12835. type, compression, 0)) {
  12836. return false;
  12837. }
  12838. int num_views = tex->get_num_views();
  12839. if (num_views == 1) {
  12840. // Replace the entire image, since we are modifying the only view.
  12841. tex->set_ram_image(image, compression, page_size);
  12842. } else {
  12843. // We're only modifying a single view, so we can't stomp all over the
  12844. // existing content.
  12845. PTA_uchar ram_image = tex->modify_ram_image();
  12846. nassertr(ram_image.size() == image.size() * num_views, false);
  12847. memcpy(ram_image.p() + image.size() * gtc->get_view(), image.p(), image.size());
  12848. }
  12849. if (gtc->_uses_mipmaps) {
  12850. // Also get the mipmap levels.
  12851. GLint num_expected_levels = tex->get_expected_num_mipmap_levels();
  12852. GLint highest_level = num_expected_levels;
  12853. if (_supports_texture_max_level) {
  12854. glGetTexParameteriv(target, GL_TEXTURE_MAX_LEVEL, &highest_level);
  12855. highest_level = min(highest_level, num_expected_levels);
  12856. }
  12857. for (int n = 1; n <= highest_level; ++n) {
  12858. if (!extract_texture_image(image, page_size, tex, target, page_target,
  12859. type, compression, n)) {
  12860. return false;
  12861. }
  12862. if (num_views == 1) {
  12863. tex->set_ram_mipmap_image(n, image, page_size);
  12864. } else {
  12865. PTA_uchar ram_mipmap_image = tex->modify_ram_mipmap_image(n);
  12866. memcpy(ram_mipmap_image.p() + image.size() * gtc->get_view(), image.p(), image.size());
  12867. }
  12868. }
  12869. }
  12870. return true;
  12871. }
  12872. /**
  12873. * Called from extract_texture_data(), this gets just the image array for a
  12874. * particular mipmap level (or for the base image).
  12875. */
  12876. bool CLP(GraphicsStateGuardian)::
  12877. extract_texture_image(PTA_uchar &image, size_t &page_size,
  12878. Texture *tex, GLenum target, GLenum page_target,
  12879. Texture::ComponentType type,
  12880. Texture::CompressionMode compression, int n) {
  12881. #ifdef OPENGLES // Extracting texture data unsupported in OpenGL ES.
  12882. nassert_raise("OpenGL ES does not support extracting texture data");
  12883. return false;
  12884. #else
  12885. // Make sure the GL driver does not align textures, otherwise we get corrupt
  12886. // memory, since we don't take alignment into account.
  12887. glPixelStorei(GL_PACK_ALIGNMENT, 1);
  12888. if (target == GL_TEXTURE_CUBE_MAP) {
  12889. // A cube map, compressed or uncompressed. This we must extract one page
  12890. // at a time.
  12891. // If the cube map is compressed, we assume that all the compressed pages
  12892. // are exactly the same size. OpenGL doesn't make this assumption, but it
  12893. // happens to be true for all currently extant compression schemes, and it
  12894. // makes things simpler for us. (It also makes things much simpler for
  12895. // the graphics hardware, so it's likely to continue to be true for a
  12896. // while at least.)
  12897. GLenum external_format = get_external_image_format(tex);
  12898. GLenum pixel_type = get_component_type(type);
  12899. page_size = tex->get_expected_ram_mipmap_page_size(n);
  12900. if (compression != Texture::CM_off) {
  12901. GLint image_size;
  12902. glGetTexLevelParameteriv(page_target, n,
  12903. GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &image_size);
  12904. nassertr(image_size <= (int)page_size, false);
  12905. page_size = image_size;
  12906. }
  12907. image = PTA_uchar::empty_array(page_size * 6);
  12908. for (int z = 0; z < 6; ++z) {
  12909. page_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + z;
  12910. if (compression == Texture::CM_off) {
  12911. glGetTexImage(page_target, n, external_format, pixel_type,
  12912. image.p() + z * page_size);
  12913. } else {
  12914. _glGetCompressedTexImage(page_target, 0, image.p() + z * page_size);
  12915. }
  12916. }
  12917. #ifndef OPENGLES
  12918. } else if (target == GL_TEXTURE_BUFFER) {
  12919. // In the case of a buffer texture, we need to get it from the buffer.
  12920. image = PTA_uchar::empty_array(tex->get_expected_ram_mipmap_view_size(n));
  12921. _glGetBufferSubData(target, 0, image.size(), image.p());
  12922. #endif
  12923. } else if (compression == Texture::CM_off) {
  12924. // An uncompressed 1-d, 2-d, or 3-d texture.
  12925. image = PTA_uchar::empty_array(tex->get_expected_ram_mipmap_view_size(n));
  12926. GLenum external_format = get_external_image_format(tex);
  12927. GLenum pixel_type = get_component_type(type);
  12928. glGetTexImage(target, n, external_format, pixel_type, image.p());
  12929. } else {
  12930. // A compressed 1-d, 2-d, or 3-d texture.
  12931. GLint image_size;
  12932. glGetTexLevelParameteriv(target, n, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &image_size);
  12933. page_size = image_size / tex->get_z_size();
  12934. image = PTA_uchar::empty_array(image_size);
  12935. // Some drivers (ATI!) seem to try to overstuff more bytes in the array
  12936. // than they asked us to allocate (that is, more bytes than
  12937. // GL_TEXTURE_COMPRESSED_IMAGE_SIZE), requiring us to overallocate and
  12938. // then copy the result into our final buffer. Sheesh.
  12939. // We'll only do this for small textures (the ATI bug doesn't *seem* to
  12940. // affect large textures), to save on the overhead of the double-copy, and
  12941. // reduce risk from an overly-large alloca().
  12942. #ifndef NDEBUG
  12943. static const int max_trouble_buffer = 102400;
  12944. #else
  12945. static const int max_trouble_buffer = 1024;
  12946. #endif
  12947. if (image_size < max_trouble_buffer) {
  12948. static const int extra_space = 32;
  12949. unsigned char *buffer = (unsigned char *)alloca(image_size + extra_space);
  12950. #ifndef NDEBUG
  12951. // Tag the buffer with a specific byte so we can report on whether that
  12952. // driver bug is still active.
  12953. static unsigned char keep_token = 0x00;
  12954. unsigned char token = ++keep_token;
  12955. memset(buffer + image_size, token, extra_space);
  12956. #endif
  12957. _glGetCompressedTexImage(target, n, buffer);
  12958. memcpy(image.p(), buffer, image_size);
  12959. #ifndef NDEBUG
  12960. int count = extra_space;
  12961. while (count > 0 && buffer[image_size + count - 1] == token) {
  12962. --count;
  12963. }
  12964. if (count != 0) {
  12965. GLCAT.warning()
  12966. << "GL graphics driver overfilled " << count
  12967. << " bytes into a " << image_size
  12968. << "-byte buffer provided to glGetCompressedTexImage()\n";
  12969. }
  12970. // This had better not equal the amount of buffer space we set aside.
  12971. // If it does, we assume the driver might have overfilled even our
  12972. // provided extra buffer.
  12973. nassertr(count != extra_space, true)
  12974. #endif // NDEBUG
  12975. } else {
  12976. _glGetCompressedTexImage(target, n, image.p());
  12977. }
  12978. }
  12979. // Now see if we were successful.
  12980. GLenum error_code = gl_get_error();
  12981. if (error_code != GL_NO_ERROR) {
  12982. GLCAT.error()
  12983. << "Unable to extract texture for " << *tex
  12984. << ", mipmap level " << n
  12985. << " : " << get_error_string(error_code) << "\n";
  12986. nassertr(false, false);
  12987. return false;
  12988. }
  12989. return true;
  12990. #endif // OPENGLES
  12991. }
  12992. /**
  12993. * Internally sets the point size parameters after any of the properties have
  12994. * changed that might affect this.
  12995. */
  12996. #ifdef SUPPORT_FIXED_FUNCTION
  12997. void CLP(GraphicsStateGuardian)::
  12998. do_point_size() {
  12999. if (!_point_perspective) {
  13000. // Normal, constant-sized points. Here _point_size is a width in pixels.
  13001. static LVecBase3f constant(1.0f, 0.0f, 0.0f);
  13002. _glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, constant.get_data());
  13003. } else {
  13004. // Perspective-sized points. Here _point_size is a width in 3-d units.
  13005. // To arrange that, we need to figure out the appropriate scaling factor
  13006. // based on the current viewport and projection matrix.
  13007. LVector3 height(0.0f, _point_size, 1.0f);
  13008. height = height * _projection_mat->get_mat();
  13009. height = height * _internal_transform->get_scale()[1];
  13010. PN_stdfloat s = height[1] * _viewport_height / _point_size;
  13011. if (_current_lens->is_orthographic()) {
  13012. // If we have an orthographic lens in effect, we don't actually apply a
  13013. // perspective transform: we just scale the points once, regardless of
  13014. // the distance from the camera.
  13015. LVecBase3f constant(1.0f / (s * s), 0.0f, 0.0f);
  13016. _glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, constant.get_data());
  13017. } else {
  13018. // Otherwise, we give it a true perspective adjustment.
  13019. LVecBase3f square(0.0f, 0.0f, 1.0f / (s * s));
  13020. _glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, square.get_data());
  13021. }
  13022. }
  13023. report_my_gl_errors();
  13024. }
  13025. #endif
  13026. /**
  13027. * Returns true if this particular GSG supports the specified Cg Shader
  13028. * Profile.
  13029. */
  13030. bool CLP(GraphicsStateGuardian)::
  13031. get_supports_cg_profile(const string &name) const {
  13032. #if !defined(HAVE_CG) || defined(OPENGLES)
  13033. return false;
  13034. #else
  13035. CGprofile profile = cgGetProfile(name.c_str());
  13036. if (profile == CG_PROFILE_UNKNOWN) {
  13037. GLCAT.error() << name << ", unknown Cg-profile\n";
  13038. return false;
  13039. }
  13040. return (cgGLIsProfileSupported(profile) != 0);
  13041. #endif
  13042. }
  13043. /**
  13044. * Binds a framebuffer object.
  13045. */
  13046. void CLP(GraphicsStateGuardian)::
  13047. bind_fbo(GLuint fbo) {
  13048. if (_current_fbo == fbo) {
  13049. return;
  13050. }
  13051. PStatGPUTimer timer(this, _fbo_bind_pcollector);
  13052. nassertv(_glBindFramebuffer != 0);
  13053. #if defined(OPENGLES_2)
  13054. _glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  13055. #elif defined(OPENGLES_1)
  13056. _glBindFramebuffer(GL_FRAMEBUFFER_OES, fbo);
  13057. #else
  13058. _glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
  13059. #endif
  13060. _current_fbo = fbo;
  13061. }
  13062. // GL stencil code section
  13063. static int gl_stencil_operations_array[] = {
  13064. GL_KEEP,
  13065. GL_ZERO,
  13066. GL_REPLACE,
  13067. #ifdef OPENGLES_1
  13068. GL_INCR_WRAP_OES,
  13069. GL_DECR_WRAP_OES,
  13070. #else
  13071. GL_INCR_WRAP,
  13072. GL_DECR_WRAP,
  13073. #endif
  13074. GL_INVERT,
  13075. GL_INCR,
  13076. GL_DECR,
  13077. };
  13078. /**
  13079. * Set stencil render states.
  13080. */
  13081. void CLP(GraphicsStateGuardian)::
  13082. do_issue_stencil() {
  13083. if (!_supports_stencil) {
  13084. return;
  13085. }
  13086. const StencilAttrib *stencil;
  13087. if (_target_rs->get_attrib(stencil)) {
  13088. // DEBUG
  13089. if (false) {
  13090. GLCAT.debug() << "STENCIL STATE CHANGE\n";
  13091. GLCAT.debug() << "\n"
  13092. << "SRS_front_comparison_function " << (int)stencil->get_render_state(StencilAttrib::SRS_front_comparison_function) << "\n"
  13093. << "SRS_front_stencil_fail_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_front_stencil_fail_operation) << "\n"
  13094. << "SRS_front_stencil_pass_z_fail_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_fail_operation) << "\n"
  13095. << "SRS_front_stencil_pass_z_pass_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_pass_operation) << "\n"
  13096. << "SRS_reference " << (int)stencil->get_render_state(StencilAttrib::SRS_reference) << "\n"
  13097. << "SRS_read_mask " << (int)stencil->get_render_state(StencilAttrib::SRS_read_mask) << "\n"
  13098. << "SRS_write_mask " << (int)stencil->get_render_state(StencilAttrib::SRS_write_mask) << "\n"
  13099. << "SRS_back_comparison_function " << (int)stencil->get_render_state(StencilAttrib::SRS_back_comparison_function) << "\n"
  13100. << "SRS_back_stencil_fail_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_back_stencil_fail_operation) << "\n"
  13101. << "SRS_back_stencil_pass_z_fail_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_fail_operation) << "\n"
  13102. << "SRS_back_stencil_pass_z_pass_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_pass_operation) << "\n";
  13103. }
  13104. #ifndef OPENGLES
  13105. if (_supports_two_sided_stencil) {
  13106. // TODO: add support for OpenGL 2.0-style glStencilFuncSeparate.
  13107. unsigned int back_compare;
  13108. back_compare = stencil->get_render_state(StencilAttrib::SRS_back_comparison_function);
  13109. if (back_compare != RenderAttrib::M_none) {
  13110. glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
  13111. _glActiveStencilFaceEXT(GL_BACK);
  13112. glStencilFunc(
  13113. PANDA_TO_GL_COMPAREFUNC(back_compare),
  13114. stencil->get_render_state(StencilAttrib::SRS_reference),
  13115. stencil->get_render_state(StencilAttrib::SRS_read_mask));
  13116. glStencilOp(
  13117. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_back_stencil_fail_operation)],
  13118. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_fail_operation)],
  13119. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_pass_operation)]
  13120. );
  13121. glStencilMask(stencil->get_render_state(StencilAttrib::SRS_write_mask));
  13122. } else {
  13123. glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
  13124. }
  13125. _glActiveStencilFaceEXT(GL_FRONT);
  13126. }
  13127. #endif // OPENGLES
  13128. unsigned int front_compare;
  13129. front_compare = stencil->get_render_state(StencilAttrib::SRS_front_comparison_function);
  13130. if (front_compare != RenderAttrib::M_none) {
  13131. glEnable(GL_STENCIL_TEST);
  13132. glStencilFunc(
  13133. PANDA_TO_GL_COMPAREFUNC(front_compare),
  13134. stencil->get_render_state(StencilAttrib::SRS_reference),
  13135. stencil->get_render_state(StencilAttrib::SRS_read_mask));
  13136. glStencilOp(
  13137. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_front_stencil_fail_operation)],
  13138. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_fail_operation)],
  13139. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_pass_operation)]
  13140. );
  13141. glStencilMask(stencil->get_render_state(StencilAttrib::SRS_write_mask));
  13142. } else {
  13143. glDisable(GL_STENCIL_TEST);
  13144. }
  13145. if (stencil->get_render_state(StencilAttrib::SRS_clear)) {
  13146. // clear stencil buffer
  13147. glClearStencil(stencil->get_render_state(StencilAttrib::SRS_clear_value));
  13148. glClear(GL_STENCIL_BUFFER_BIT);
  13149. }
  13150. } else {
  13151. glDisable(GL_STENCIL_TEST);
  13152. #ifndef OPENGLES
  13153. if (_supports_two_sided_stencil) {
  13154. glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
  13155. }
  13156. #endif // OPENGLES
  13157. }
  13158. }
  13159. /**
  13160. *
  13161. */
  13162. void CLP(GraphicsStateGuardian)::
  13163. do_issue_scissor() {
  13164. const ScissorAttrib *target_scissor;
  13165. _target_rs->get_attrib_def(target_scissor);
  13166. if (!target_scissor->is_off()) {
  13167. // A non-off ScissorAttrib means to override the scissor setting that was
  13168. // specified by the DisplayRegion.
  13169. if (!_scissor_enabled) {
  13170. if (GLCAT.is_spam()) {
  13171. GLCAT.spam()
  13172. << "glEnable(GL_SCISSOR_TEST)\n";
  13173. }
  13174. glEnable(GL_SCISSOR_TEST);
  13175. _scissor_enabled = true;
  13176. }
  13177. const LVecBase4 &frame = target_scissor->get_frame();
  13178. int x = (int)(_viewport_x + _viewport_width * frame[0] + 0.5f);
  13179. int y = (int)(_viewport_y + _viewport_height * frame[2] + 0.5f);
  13180. int width = (int)(_viewport_width * (frame[1] - frame[0]) + 0.5f);
  13181. int height = (int)(_viewport_height * (frame[3] - frame[2]) + 0.5f);
  13182. if (GLCAT.is_spam()) {
  13183. GLCAT.spam()
  13184. << "glScissor(" << x << ", " << y << ", " << width << ", " << height << ")\n";
  13185. }
  13186. glScissor(x, y, width, height);
  13187. _scissor_attrib_active = true;
  13188. } else if (_scissor_attrib_active) {
  13189. _scissor_attrib_active = false;
  13190. if (_scissor_array.size() > 0) {
  13191. // Scissoring is enabled on the display region. Revert to the scissor
  13192. // state specified in the DisplayRegion.
  13193. #ifndef OPENGLES
  13194. if (_supports_viewport_arrays) {
  13195. _glScissorArrayv(0, _scissor_array.size(), _scissor_array[0].get_data());
  13196. } else
  13197. #endif // OPENGLES
  13198. {
  13199. const LVecBase4i sr = _scissor_array[0];
  13200. glScissor(sr[0], sr[1], sr[2], sr[3]);
  13201. }
  13202. } else if (_scissor_enabled) {
  13203. // The display region had no scissor enabled. Disable scissoring.
  13204. if (GLCAT.is_spam()) {
  13205. GLCAT.spam()
  13206. << "glDisable(GL_SCISSOR_TEST)\n";
  13207. }
  13208. glDisable(GL_SCISSOR_TEST);
  13209. _scissor_enabled = false;
  13210. }
  13211. }
  13212. }