glGraphicsStateGuardian_src.cxx 418 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407
  1. // Filename: glGraphicsStateGuardian_src.cxx
  2. // Created by: drose (02Feb99)
  3. // Updated by: fperazzi, PandaSE (05May10) (added
  4. // get_supports_cg_profile)
  5. //
  6. ////////////////////////////////////////////////////////////////////
  7. //
  8. // PANDA 3D SOFTWARE
  9. // Copyright (c) Carnegie Mellon University. All rights reserved.
  10. //
  11. // All use of this software is subject to the terms of the revised BSD
  12. // license. You should have received a copy of this license along
  13. // with this source code in a file named "LICENSE."
  14. //
  15. ////////////////////////////////////////////////////////////////////
  16. #include "config_util.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 "materialAttrib.h"
  59. #include "rescaleNormalAttrib.h"
  60. #include "scissorAttrib.h"
  61. #include "shadeModelAttrib.h"
  62. #include "stencilAttrib.h"
  63. #include "graphicsEngine.h"
  64. #include "shaderGenerator.h"
  65. #include "samplerState.h"
  66. #if defined(HAVE_CG) && !defined(OPENGLES)
  67. #include "Cg/cgGL.h"
  68. #endif
  69. #include <algorithm>
  70. TypeHandle CLP(GraphicsStateGuardian)::_type_handle;
  71. PStatCollector CLP(GraphicsStateGuardian)::_load_display_list_pcollector("Draw:Transfer data:Display lists");
  72. PStatCollector CLP(GraphicsStateGuardian)::_primitive_batches_display_list_pcollector("Primitive batches:Display lists");
  73. PStatCollector CLP(GraphicsStateGuardian)::_vertices_display_list_pcollector("Vertices:Display lists");
  74. PStatCollector CLP(GraphicsStateGuardian)::_vertices_immediate_pcollector("Vertices:Immediate mode");
  75. PStatCollector CLP(GraphicsStateGuardian)::_memory_barrier_pcollector("Draw:Memory barriers");
  76. PStatCollector CLP(GraphicsStateGuardian)::_vertex_array_update_pcollector("Draw:Update arrays");
  77. PStatCollector CLP(GraphicsStateGuardian)::_texture_update_pcollector("Draw:Update texture");
  78. PStatCollector CLP(GraphicsStateGuardian)::_fbo_bind_pcollector("Draw:Bind FBO");
  79. PStatCollector CLP(GraphicsStateGuardian)::_check_error_pcollector("Draw:Check errors");
  80. #ifdef OPENGLES_2
  81. PT(Shader) CLP(GraphicsStateGuardian)::_default_shader = NULL;
  82. #endif
  83. // The following noop functions are assigned to the corresponding
  84. // glext function pointers in the class, in case the functions are not
  85. // defined by the GL, just so it will always be safe to call the
  86. // extension functions.
  87. static void APIENTRY
  88. null_glPointParameterfv(GLenum, const GLfloat *) {
  89. }
  90. #ifdef OPENGLES
  91. // OpenGL ES doesn't support this, period. Might as well macro it.
  92. #define _glDrawRangeElements(mode, start, end, count, type, indices) \
  93. glDrawElements(mode, count, type, indices)
  94. #else
  95. static void APIENTRY
  96. null_glDrawRangeElements(GLenum mode, GLuint start, GLuint end,
  97. GLsizei count, GLenum type, const GLvoid *indices) {
  98. // If we don't support glDrawRangeElements(), just use the original
  99. // glDrawElements() instead.
  100. glDrawElements(mode, count, type, indices);
  101. }
  102. #endif
  103. static void APIENTRY
  104. null_glActiveTexture(GLenum gl_texture_stage) {
  105. // If we don't support multitexture, we'd better not try to request
  106. // a texture beyond the first texture stage.
  107. nassertv(gl_texture_stage == GL_TEXTURE0);
  108. }
  109. static void APIENTRY
  110. null_glBlendEquation(GLenum) {
  111. }
  112. static void APIENTRY
  113. null_glBlendColor(GLclampf, GLclampf, GLclampf, GLclampf) {
  114. }
  115. #ifdef OPENGLES_2
  116. // We have a default shader that will be applied when there
  117. // isn't any shader applied (e.g. if it failed to compile).
  118. // We need this because OpenGL ES 2.x does not have
  119. // a fixed-function pipeline.
  120. // This default shader just outputs a red color, telling
  121. // the user that something went wrong.
  122. static const string default_vshader =
  123. "uniform mediump mat4 p3d_ModelViewProjectionMatrix;\n"
  124. "attribute highp vec4 p3d_Vertex;\n"
  125. "void main(void) {\n"
  126. " gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;\n"
  127. "}\n";
  128. static const string default_fshader =
  129. "void main(void) {\n"
  130. " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
  131. "}\n";
  132. #endif
  133. ////////////////////////////////////////////////////////////////////
  134. // Function: uchar_bgr_to_rgb
  135. // Description: Recopies the given array of pixels, converting from
  136. // BGR to RGB arrangement.
  137. ////////////////////////////////////////////////////////////////////
  138. static void
  139. uchar_bgr_to_rgb(unsigned char *dest, const unsigned char *source,
  140. int num_pixels) {
  141. for (int i = 0; i < num_pixels; i++) {
  142. dest[0] = source[2];
  143. dest[1] = source[1];
  144. dest[2] = source[0];
  145. dest += 3;
  146. source += 3;
  147. }
  148. }
  149. ////////////////////////////////////////////////////////////////////
  150. // Function: uchar_bgra_to_rgba
  151. // Description: Recopies the given array of pixels, converting from
  152. // BGRA to RGBA arrangement.
  153. ////////////////////////////////////////////////////////////////////
  154. static void
  155. uchar_bgra_to_rgba(unsigned char *dest, const unsigned char *source,
  156. int num_pixels) {
  157. for (int i = 0; i < num_pixels; i++) {
  158. dest[0] = source[2];
  159. dest[1] = source[1];
  160. dest[2] = source[0];
  161. dest[3] = source[3];
  162. dest += 4;
  163. source += 4;
  164. }
  165. }
  166. ////////////////////////////////////////////////////////////////////
  167. // Function: ushort_bgr_to_rgb
  168. // Description: Recopies the given array of pixels, converting from
  169. // BGR to RGB arrangement.
  170. ////////////////////////////////////////////////////////////////////
  171. static void
  172. ushort_bgr_to_rgb(unsigned short *dest, const unsigned short *source,
  173. int num_pixels) {
  174. for (int i = 0; i < num_pixels; i++) {
  175. dest[0] = source[2];
  176. dest[1] = source[1];
  177. dest[2] = source[0];
  178. dest += 3;
  179. source += 3;
  180. }
  181. }
  182. ////////////////////////////////////////////////////////////////////
  183. // Function: ushort_bgra_to_rgba
  184. // Description: Recopies the given array of pixels, converting from
  185. // BGRA to RGBA arrangement.
  186. ////////////////////////////////////////////////////////////////////
  187. static void
  188. ushort_bgra_to_rgba(unsigned short *dest, const unsigned short *source,
  189. int num_pixels) {
  190. for (int i = 0; i < num_pixels; i++) {
  191. dest[0] = source[2];
  192. dest[1] = source[1];
  193. dest[2] = source[0];
  194. dest[3] = source[3];
  195. dest += 4;
  196. source += 4;
  197. }
  198. }
  199. ////////////////////////////////////////////////////////////////////
  200. // Function: fix_component_ordering
  201. // Description: Reverses the order of the components within the
  202. // image, to convert (for instance) GL_BGR to GL_RGB.
  203. // Returns the byte pointer representing the converted
  204. // image, or the original image if it is unchanged.
  205. //
  206. // new_image must be supplied; it is the PTA_uchar that
  207. // will be used to hold the converted image if required.
  208. // It will be modified only if the conversion is
  209. // necessary, in which case the data will be stored
  210. // there, and this pointer will be returned. If the
  211. // conversion is not necessary, this pointer will be
  212. // left unchanged.
  213. ////////////////////////////////////////////////////////////////////
  214. static const unsigned char *
  215. fix_component_ordering(PTA_uchar &new_image,
  216. const unsigned char *orig_image, size_t orig_image_size,
  217. GLenum external_format, Texture *tex) {
  218. const unsigned char *result = orig_image;
  219. switch (external_format) {
  220. case GL_RGB:
  221. switch (tex->get_component_type()) {
  222. case Texture::T_unsigned_byte:
  223. new_image = PTA_uchar::empty_array(orig_image_size);
  224. uchar_bgr_to_rgb(new_image, orig_image, orig_image_size / 3);
  225. result = new_image;
  226. break;
  227. case Texture::T_unsigned_short:
  228. new_image = PTA_uchar::empty_array(orig_image_size);
  229. ushort_bgr_to_rgb((unsigned short *)new_image.p(),
  230. (const unsigned short *)orig_image,
  231. orig_image_size / 6);
  232. result = new_image;
  233. break;
  234. default:
  235. break;
  236. }
  237. break;
  238. case GL_RGBA:
  239. switch (tex->get_component_type()) {
  240. case Texture::T_unsigned_byte:
  241. new_image = PTA_uchar::empty_array(orig_image_size);
  242. uchar_bgra_to_rgba(new_image, orig_image, orig_image_size / 4);
  243. result = new_image;
  244. break;
  245. case Texture::T_unsigned_short:
  246. new_image = PTA_uchar::empty_array(orig_image_size);
  247. ushort_bgra_to_rgba((unsigned short *)new_image.p(),
  248. (const unsigned short *)orig_image,
  249. orig_image_size / 8);
  250. result = new_image;
  251. break;
  252. default:
  253. break;
  254. }
  255. break;
  256. default:
  257. break;
  258. }
  259. return result;
  260. }
  261. //#--- Zhao Nov/2011
  262. string CLP(GraphicsStateGuardian)::get_driver_vendor() { return _gl_vendor; }
  263. string CLP(GraphicsStateGuardian)::get_driver_renderer() { return _gl_renderer; }
  264. string CLP(GraphicsStateGuardian)::get_driver_version() { return _gl_version; }
  265. int CLP(GraphicsStateGuardian)::get_driver_version_major() { return _gl_version_major; }
  266. int CLP(GraphicsStateGuardian)::get_driver_version_minor() { return _gl_version_minor; }
  267. int CLP(GraphicsStateGuardian)::get_driver_shader_version_major() { return _gl_shadlang_ver_major; }
  268. int CLP(GraphicsStateGuardian)::get_driver_shader_version_minor() { return _gl_shadlang_ver_minor; }
  269. ////////////////////////////////////////////////////////////////////
  270. // Function: GLGraphicsStateGuardian::Constructor
  271. // Access: Public
  272. // Description:
  273. ////////////////////////////////////////////////////////////////////
  274. CLP(GraphicsStateGuardian)::
  275. CLP(GraphicsStateGuardian)(GraphicsEngine *engine, GraphicsPipe *pipe) :
  276. GraphicsStateGuardian(CS_yup_right, engine, pipe)
  277. {
  278. _error_count = 0;
  279. // Hack. Turn on the flag that we turned off at a higher level,
  280. // since we know this works properly in OpenGL, and we want the
  281. // performance benefit it gives us.
  282. _prepared_objects->_support_released_buffer_cache = true;
  283. // Assume that we will get a hardware-accelerated context, unless
  284. // the window tells us otherwise.
  285. _is_hardware = true;
  286. // calling glGetError() forces a sync, this turns it on if you want to.
  287. _check_errors = gl_check_errors;
  288. _force_flush = gl_force_flush;
  289. _scissor_enabled = false;
  290. _scissor_attrib_active = false;
  291. #ifdef HAVE_CG
  292. _cg_context = 0;
  293. #endif
  294. #ifdef DO_PSTATS
  295. if (gl_finish) {
  296. GLCAT.warning()
  297. << "The config variable gl-finish is set to true. This may have a substantial negative impact on your render performance.\n";
  298. }
  299. #endif // DO_PSTATS
  300. }
  301. ////////////////////////////////////////////////////////////////////
  302. // Function: GLGraphicsStateGuardian::Destructor
  303. // Access: Public
  304. // Description:
  305. ////////////////////////////////////////////////////////////////////
  306. CLP(GraphicsStateGuardian)::
  307. ~CLP(GraphicsStateGuardian)() {
  308. if (GLCAT.is_debug()) {
  309. GLCAT.debug()
  310. << "GLGraphicsStateGuardian " << this << " destructing\n";
  311. }
  312. close_gsg();
  313. }
  314. ////////////////////////////////////////////////////////////////////
  315. // Function: GLGraphicsStateGuardian::debug_callback
  316. // Access: Public, Static
  317. // Description: This is called by the GL if an error occurs, if
  318. // gl_debug has been enabled (and the driver supports
  319. // the GL_ARB_debug_output extension).
  320. ////////////////////////////////////////////////////////////////////
  321. #ifndef OPENGLES_1
  322. void CLP(GraphicsStateGuardian)::
  323. debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *userParam) {
  324. // Determine how to map the severity level.
  325. NotifySeverity level;
  326. switch (severity) {
  327. case GL_DEBUG_SEVERITY_HIGH:
  328. level = NS_error;
  329. break;
  330. case GL_DEBUG_SEVERITY_MEDIUM:
  331. level = NS_warning;
  332. break;
  333. case GL_DEBUG_SEVERITY_LOW:
  334. level = NS_info;
  335. break;
  336. case GL_DEBUG_SEVERITY_NOTIFICATION:
  337. level = NS_debug;
  338. break;
  339. default:
  340. level = NS_fatal; //???
  341. break;
  342. }
  343. string msg_str(message, length);
  344. GLCAT.out(level) << msg_str << "\n";
  345. #ifndef NDEBUG
  346. if (level >= gl_debug_abort_level.get_value()) {
  347. abort();
  348. }
  349. #endif
  350. }
  351. #endif // OPENGLES_1
  352. ////////////////////////////////////////////////////////////////////
  353. // Function: GLGraphicsStateGuardian::reset
  354. // Access: Public, Virtual
  355. // Description: Resets all internal state as if the gsg were newly
  356. // created.
  357. ////////////////////////////////////////////////////////////////////
  358. void CLP(GraphicsStateGuardian)::
  359. reset() {
  360. free_pointers();
  361. GraphicsStateGuardian::reset();
  362. // Build _inv_state_mask as a mask of 1's where we don't care, and
  363. // 0's where we do care, about the state.
  364. //_inv_state_mask = RenderState::SlotMask::all_on();
  365. _inv_state_mask.clear_bit(ShaderAttrib::get_class_slot());
  366. _inv_state_mask.clear_bit(AlphaTestAttrib::get_class_slot());
  367. _inv_state_mask.clear_bit(AntialiasAttrib::get_class_slot());
  368. _inv_state_mask.clear_bit(ClipPlaneAttrib::get_class_slot());
  369. _inv_state_mask.clear_bit(ColorAttrib::get_class_slot());
  370. _inv_state_mask.clear_bit(ColorScaleAttrib::get_class_slot());
  371. _inv_state_mask.clear_bit(CullFaceAttrib::get_class_slot());
  372. _inv_state_mask.clear_bit(DepthOffsetAttrib::get_class_slot());
  373. _inv_state_mask.clear_bit(DepthTestAttrib::get_class_slot());
  374. _inv_state_mask.clear_bit(DepthWriteAttrib::get_class_slot());
  375. _inv_state_mask.clear_bit(RenderModeAttrib::get_class_slot());
  376. _inv_state_mask.clear_bit(RescaleNormalAttrib::get_class_slot());
  377. _inv_state_mask.clear_bit(ShadeModelAttrib::get_class_slot());
  378. _inv_state_mask.clear_bit(TransparencyAttrib::get_class_slot());
  379. _inv_state_mask.clear_bit(ColorWriteAttrib::get_class_slot());
  380. _inv_state_mask.clear_bit(ColorBlendAttrib::get_class_slot());
  381. _inv_state_mask.clear_bit(TextureAttrib::get_class_slot());
  382. _inv_state_mask.clear_bit(TexGenAttrib::get_class_slot());
  383. _inv_state_mask.clear_bit(TexMatrixAttrib::get_class_slot());
  384. _inv_state_mask.clear_bit(MaterialAttrib::get_class_slot());
  385. _inv_state_mask.clear_bit(LightAttrib::get_class_slot());
  386. _inv_state_mask.clear_bit(StencilAttrib::get_class_slot());
  387. _inv_state_mask.clear_bit(FogAttrib::get_class_slot());
  388. _inv_state_mask.clear_bit(ScissorAttrib::get_class_slot());
  389. // Output the vendor and version strings.
  390. query_gl_version();
  391. if (_gl_version_major == 0) {
  392. // Couldn't get GL. Fail.
  393. mark_new();
  394. return;
  395. }
  396. // Save the extensions tokens.
  397. _extensions.clear();
  398. save_extensions((const char *)glGetString(GL_EXTENSIONS));
  399. get_extra_extensions();
  400. report_extensions();
  401. // Initialize OpenGL debugging output first, if enabled and supported.
  402. _supports_debug = false;
  403. _use_object_labels = false;
  404. #ifndef OPENGLES_1
  405. if (gl_debug) {
  406. PFNGLDEBUGMESSAGECALLBACKPROC _glDebugMessageCallback;
  407. PFNGLDEBUGMESSAGECONTROLPROC _glDebugMessageControl;
  408. if (is_at_least_gl_version(4, 3) || has_extension("GL_KHR_debug")) {
  409. #ifdef OPENGLES
  410. _glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)
  411. get_extension_func("glDebugMessageCallbackKHR");
  412. _glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)
  413. get_extension_func("glDebugMessageControlKHR");
  414. _glObjectLabel = (PFNGLOBJECTLABELPROC)
  415. get_extension_func("glObjectLabelKHR");
  416. #else
  417. _glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)
  418. get_extension_func("glDebugMessageCallback");
  419. _glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)
  420. get_extension_func("glDebugMessageControl");
  421. _glObjectLabel = (PFNGLOBJECTLABELPROC)
  422. get_extension_func("glObjectLabel");
  423. #endif
  424. glEnable(GL_DEBUG_OUTPUT); // Not supported in ARB version
  425. _supports_debug = true;
  426. _use_object_labels = gl_debug_object_labels;
  427. #ifndef OPENGLES
  428. } else if (has_extension("GL_ARB_debug_output")) {
  429. _glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)
  430. get_extension_func("glDebugMessageCallbackARB");
  431. _glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)
  432. get_extension_func("glDebugMessageControlARB");
  433. _supports_debug = true;
  434. #endif
  435. }
  436. if (_supports_debug) {
  437. // Set the categories we want to listen to.
  438. _glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH,
  439. 0, NULL, GLCAT.is_error());
  440. _glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM,
  441. 0, NULL, GLCAT.is_warning());
  442. _glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW,
  443. 0, NULL, GLCAT.is_info());
  444. _glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION,
  445. 0, NULL, GLCAT.is_debug());
  446. // Enable the callback.
  447. _glDebugMessageCallback((GLDEBUGPROC) &debug_callback, (void*)this);
  448. if (gl_debug_synchronous) {
  449. glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
  450. }
  451. GLCAT.debug() << "gl-debug enabled.\n";
  452. } else {
  453. GLCAT.debug() << "gl-debug enabled, but NOT supported.\n";
  454. }
  455. } else {
  456. GLCAT.debug() << "gl-debug NOT enabled.\n";
  457. // However, still check if it is supported.
  458. _supports_debug = is_at_least_gl_version(4, 3)
  459. || has_extension("GL_KHR_debug")
  460. || has_extension("GL_ARB_debug_output");
  461. }
  462. #endif // OPENGLES_1
  463. _supported_geom_rendering =
  464. Geom::GR_indexed_point |
  465. Geom::GR_point | Geom::GR_point_uniform_size |
  466. Geom::GR_indexed_other |
  467. Geom::GR_triangle_strip | Geom::GR_triangle_fan |
  468. Geom::GR_line_strip |
  469. Geom::GR_flat_last_vertex;
  470. _supports_point_parameters = false;
  471. #ifndef OPENGLES_2
  472. if (is_at_least_gl_version(1, 4)) {
  473. _supports_point_parameters = true;
  474. _glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)
  475. get_extension_func("glPointParameterfv");
  476. } else if (has_extension("GL_ARB_point_parameters")) {
  477. _supports_point_parameters = true;
  478. _glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)
  479. get_extension_func("glPointParameterfvARB");
  480. }
  481. if (_supports_point_parameters) {
  482. if (_glPointParameterfv == NULL) {
  483. GLCAT.warning()
  484. << "glPointParameterfv advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  485. _supports_point_parameters = false;
  486. }
  487. }
  488. if (_supports_point_parameters) {
  489. _supported_geom_rendering |= Geom::GR_point_perspective | Geom::GR_point_scale;
  490. } else {
  491. _glPointParameterfv = null_glPointParameterfv;
  492. }
  493. #endif // !OPENGLES_2
  494. #if defined(OPENGLES_2)
  495. // OpenGL ES 2 doesn't have point sprites.
  496. _supports_point_sprite = false;
  497. #elif defined(OPENGLES_1)
  498. _supports_point_sprite = has_extension("GL_OES_point_sprite");
  499. #else
  500. _supports_point_sprite = has_extension("GL_ARB_point_sprite");
  501. #endif
  502. if (_supports_point_sprite) {
  503. // It appears that the point_sprite extension doesn't support
  504. // texture transforms on the generated texture coordinates. How
  505. // inconsistent. Because of this, we don't advertise
  506. // GR_point_sprite_tex_matrix.
  507. _supported_geom_rendering |= Geom::GR_point_sprite;
  508. }
  509. #ifndef OPENGLES
  510. _explicit_primitive_restart = false;
  511. _glPrimitiveRestartIndex = NULL;
  512. if (gl_support_primitive_restart_index) {
  513. if ((is_at_least_gl_version(4, 3) || has_extension("GL_ARB_ES3_compatibility")) &&
  514. _gl_renderer.substr(0, 7) != "Gallium") {
  515. // As long as we enable this, OpenGL will always use the highest possible index
  516. // for a numeric type as strip cut index, which coincides with our convention.
  517. // This saves us a call to glPrimitiveRestartIndex
  518. // ... of course, though, the Gallium driver bugs out here. See also:
  519. // https://www.panda3d.org/forums/viewtopic.php?f=5&t=17512
  520. glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
  521. _supported_geom_rendering |= Geom::GR_strip_cut_index;
  522. } else if (is_at_least_gl_version(3, 1)) {
  523. // We have to use an explicit primitive restart enable/index.
  524. _explicit_primitive_restart = true;
  525. _supported_geom_rendering |= Geom::GR_strip_cut_index;
  526. _glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC)
  527. get_extension_func("glPrimitiveRestartIndex");
  528. }
  529. }
  530. #endif
  531. #ifdef OPENGLES_2
  532. _supports_vertex_blend = false;
  533. #else
  534. _supports_vertex_blend = has_extension("GL_ARB_vertex_blend");
  535. if (_supports_vertex_blend) {
  536. _glWeightPointer = (PFNGLWEIGHTPOINTERARBPROC)
  537. get_extension_func("glWeightPointerARB");
  538. _glVertexBlend = (PFNGLVERTEXBLENDARBPROC)
  539. get_extension_func("glVertexBlendARB");
  540. _glWeightfv = (PFNGLWEIGHTFVARBPROC)
  541. get_extension_func("glWeightfvARB");
  542. _glWeightdv = (PFNGLWEIGHTDVARBPROC)
  543. get_extension_func("glWeightdvARB");
  544. if (_glWeightPointer == NULL || _glVertexBlend == NULL ||
  545. GLfv(_glWeight) == NULL) {
  546. GLCAT.warning()
  547. << "Vertex blending advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  548. _supports_vertex_blend = false;
  549. }
  550. }
  551. #endif
  552. #ifndef OPENGLES_2
  553. if (_supports_vertex_blend) {
  554. #ifndef OPENGLES
  555. glEnable(GL_WEIGHT_SUM_UNITY_ARB);
  556. #endif
  557. GLint max_vertex_units = 0;
  558. glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &max_vertex_units);
  559. _max_vertex_transforms = max_vertex_units;
  560. if (GLCAT.is_debug()) {
  561. GLCAT.debug()
  562. << "max vertex transforms = " << _max_vertex_transforms << "\n";
  563. }
  564. }
  565. #endif
  566. _supports_matrix_palette = false;
  567. #ifndef OPENGLES
  568. if (has_extension("GL_ARB_matrix_palette")) {
  569. _supports_matrix_palette = true;
  570. _glCurrentPaletteMatrix = (PFNGLCURRENTPALETTEMATRIXARBPROC)
  571. get_extension_func("glCurrentPaletteMatrixARB");
  572. _glMatrixIndexPointer = (PFNGLMATRIXINDEXPOINTERARBPROC)
  573. get_extension_func("glMatrixIndexPointerARB");
  574. _glMatrixIndexuiv = (PFNGLMATRIXINDEXUIVARBPROC)
  575. get_extension_func("glMatrixIndexuivARB");
  576. if (_glCurrentPaletteMatrix == NULL ||
  577. _glMatrixIndexPointer == NULL ||
  578. _glMatrixIndexuiv == NULL) {
  579. GLCAT.warning()
  580. << "Matrix palette advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  581. _supports_matrix_palette = false;
  582. }
  583. }
  584. #elif defined(OPENGLES_1)
  585. if (has_extension("GL_OES_matrix_palette")) {
  586. _supports_matrix_palette = true;
  587. _glCurrentPaletteMatrix = (PFNGLCURRENTPALETTEMATRIXOESPROC)
  588. get_extension_func("glCurrentPaletteMatrixOES");
  589. _glMatrixIndexPointer = (PFNGLMATRIXINDEXPOINTEROESPROC)
  590. get_extension_func("glMatrixIndexPointerOES");
  591. if (_glCurrentPaletteMatrix == NULL ||
  592. _glMatrixIndexPointer == NULL) {
  593. GLCAT.warning()
  594. << "Matrix palette advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  595. _supports_matrix_palette = false;
  596. }
  597. }
  598. #endif
  599. /*
  600. The matrix_palette support in this module is completely untested
  601. (because I don't happen to have a card handy whose driver supports
  602. this extension), so I have this ConfigVariable set to
  603. unconditionally set this flag off for now, to protect the unwary.
  604. When we have shown that the code works, we should remove this bit.
  605. In the meantime, you must put both "matrix-palette 1" and
  606. "gl-matrix-palette 1" in your Config.prc to exercise the new
  607. code. */
  608. if (!gl_matrix_palette) {
  609. if (_supports_matrix_palette) {
  610. if (GLCAT.is_debug()) {
  611. GLCAT.debug() << "Forcing off matrix palette support.\n";
  612. }
  613. }
  614. _supports_matrix_palette = false;
  615. }
  616. if (_supports_matrix_palette) {
  617. GLint max_palette_matrices = 0;
  618. #ifdef OPENGLES_1
  619. glGetIntegerv(GL_MAX_PALETTE_MATRICES_OES, &max_palette_matrices);
  620. #endif
  621. #ifndef OPENGLES
  622. glGetIntegerv(GL_MAX_PALETTE_MATRICES_ARB, &max_palette_matrices);
  623. #endif
  624. _max_vertex_transform_indices = max_palette_matrices;
  625. if (GLCAT.is_debug()) {
  626. GLCAT.debug()
  627. << "max vertex transform indices = " << _max_vertex_transform_indices << "\n";
  628. }
  629. }
  630. #ifndef OPENGLES
  631. _glDrawRangeElements = null_glDrawRangeElements;
  632. if (is_at_least_gl_version(1, 2)) {
  633. _glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)
  634. get_extension_func("glDrawRangeElements");
  635. } else if (has_extension("GL_EXT_draw_range_elements")) {
  636. _glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)
  637. get_extension_func("glDrawRangeElementsEXT");
  638. }
  639. if (_glDrawRangeElements == NULL) {
  640. GLCAT.warning()
  641. << "glDrawRangeElements advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  642. _glDrawRangeElements = null_glDrawRangeElements;
  643. }
  644. #endif
  645. _supports_3d_texture = false;
  646. #ifndef OPENGLES_1
  647. if (is_at_least_gl_version(1, 2)) {
  648. _supports_3d_texture = true;
  649. _glTexImage3D = (PFNGLTEXIMAGE3DPROC_P)
  650. get_extension_func("glTexImage3D");
  651. _glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)
  652. get_extension_func("glTexSubImage3D");
  653. _glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)
  654. get_extension_func("glCopyTexSubImage3D");
  655. } else if (has_extension("GL_EXT_texture3D")) {
  656. _supports_3d_texture = true;
  657. _glTexImage3D = (PFNGLTEXIMAGE3DPROC_P)
  658. get_extension_func("glTexImage3DEXT");
  659. _glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)
  660. get_extension_func("glTexSubImage3DEXT");
  661. _glCopyTexSubImage3D = NULL;
  662. if (has_extension("GL_EXT_copy_texture")) {
  663. _glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)
  664. get_extension_func("glCopyTexSubImage3DEXT");
  665. }
  666. } else if (has_extension("GL_OES_texture_3D")) {
  667. _supports_3d_texture = true;
  668. _glTexImage3D = (PFNGLTEXIMAGE3DPROC_P)
  669. get_extension_func("glTexImage3DOES");
  670. _glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)
  671. get_extension_func("glTexSubImage3DOES");
  672. _glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)
  673. get_extension_func("glCopyTexSubImage3DOES");
  674. #ifdef OPENGLES_2
  675. _glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DOES)
  676. get_extension_func("glFramebufferTexture3DOES");
  677. #endif
  678. }
  679. if (_supports_3d_texture) {
  680. if (_glTexImage3D == NULL || _glTexSubImage3D == NULL) {
  681. GLCAT.warning()
  682. << "3-D textures advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  683. _supports_3d_texture = false;
  684. }
  685. }
  686. #endif // !OPENGLES_1
  687. _supports_tex_storage = false;
  688. #ifndef OPENGLES
  689. if (is_at_least_gl_version(4, 2) || has_extension("GL_ARB_texture_storage")) {
  690. _supports_tex_storage = true;
  691. _glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)
  692. get_extension_func("glTexStorage1D");
  693. _glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)
  694. get_extension_func("glTexStorage2D");
  695. _glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)
  696. get_extension_func("glTexStorage3D");
  697. } else
  698. #endif
  699. if (has_extension("GL_EXT_texture_storage")) { // GLES case
  700. _supports_tex_storage = true;
  701. _glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)
  702. get_extension_func("glTexStorage1DEXT");
  703. _glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)
  704. get_extension_func("glTexStorage2DEXT");
  705. _glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)
  706. get_extension_func("glTexStorage3DEXT");
  707. }
  708. if (_supports_tex_storage) {
  709. if (_glTexStorage1D == NULL || _glTexStorage2D == NULL || _glTexStorage3D == NULL) {
  710. GLCAT.warning()
  711. << "Immutable texture storage advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  712. _supports_tex_storage = false;
  713. }
  714. }
  715. _supports_clear_texture = false;
  716. #ifndef OPENGLES
  717. if (is_at_least_gl_version(4, 4) || has_extension("GL_ARB_clear_texture")) {
  718. _glClearTexImage = (PFNGLCLEARTEXIMAGEPROC)
  719. get_extension_func("glClearTexImage");
  720. if (_glClearTexImage == NULL) {
  721. GLCAT.warning()
  722. << "GL_ARB_clear_texture advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  723. } else {
  724. _supports_clear_texture = true;
  725. }
  726. }
  727. #endif
  728. _supports_2d_texture_array = false;
  729. #ifndef OPENGLES
  730. _supports_2d_texture_array = has_extension("GL_EXT_texture_array");
  731. if (_supports_2d_texture_array) {
  732. _glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)
  733. get_extension_func("glFramebufferTextureLayerEXT");
  734. } else {
  735. // ARB_geometry_shader4 also provides a version.
  736. _glFramebufferTextureLayer = NULL;
  737. }
  738. #endif
  739. #ifdef OPENGLES_2
  740. _supports_cube_map = true;
  741. #else
  742. _supports_cube_map =
  743. has_extension("GL_ARB_texture_cube_map") || is_at_least_gl_version(1, 3) ||
  744. has_extension("GL_OES_texture_cube_map");
  745. #endif
  746. #ifndef OPENGLES
  747. if (_supports_cube_map && gl_cube_map_seamless) {
  748. if (is_at_least_gl_version(3, 2) || has_extension("GL_ARB_seamless_cube_map")) {
  749. glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
  750. }
  751. }
  752. #endif
  753. _supports_texture_srgb = false;
  754. if (is_at_least_gl_version(2, 1) || has_extension("GL_EXT_texture_sRGB")) {
  755. _supports_texture_srgb = true;
  756. } else if (has_extension("GL_EXT_sRGB")) { // GLES case.
  757. _supports_texture_srgb = true;
  758. }
  759. _supports_compressed_texture = false;
  760. #ifdef OPENGLES
  761. _supports_compressed_texture = true;
  762. // Supported in the core. 1D textures are not supported by OpenGL ES.
  763. _glCompressedTexImage1D = NULL;
  764. _glCompressedTexImage2D = glCompressedTexImage2D;
  765. _glCompressedTexSubImage1D = NULL;
  766. _glCompressedTexSubImage2D = glCompressedTexSubImage2D;
  767. _glGetCompressedTexImage = NULL;
  768. _glCompressedTexImage3D = NULL;
  769. _glCompressedTexSubImage3D = NULL;
  770. #ifdef OPENGLES_2
  771. if (_supports_3d_texture) {
  772. _glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)
  773. get_extension_func("glCompressedTexImage3DOES");
  774. _glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)
  775. get_extension_func("glCompressedTexSubImageOES");
  776. }
  777. #endif
  778. #else
  779. if (is_at_least_gl_version(1, 3)) {
  780. _supports_compressed_texture = true;
  781. _glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)
  782. get_extension_func("glCompressedTexImage1D");
  783. _glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)
  784. get_extension_func("glCompressedTexImage2D");
  785. _glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)
  786. get_extension_func("glCompressedTexImage3D");
  787. _glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)
  788. get_extension_func("glCompressedTexSubImage1D");
  789. _glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)
  790. get_extension_func("glCompressedTexSubImage2D");
  791. _glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)
  792. get_extension_func("glCompressedTexSubImage3D");
  793. _glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)
  794. get_extension_func("glGetCompressedTexImage");
  795. } else if (has_extension("GL_ARB_texture_compression")) {
  796. _supports_compressed_texture = true;
  797. _glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)
  798. get_extension_func("glCompressedTexImage1DARB");
  799. _glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)
  800. get_extension_func("glCompressedTexImage2DARB");
  801. _glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)
  802. get_extension_func("glCompressedTexImage3DARB");
  803. _glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)
  804. get_extension_func("glCompressedTexSubImage1DARB");
  805. _glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)
  806. get_extension_func("glCompressedTexSubImage2DARB");
  807. _glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)
  808. get_extension_func("glCompressedTexSubImage3DARB");
  809. _glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)
  810. get_extension_func("glGetCompressedTexImageARB");
  811. }
  812. if (_supports_compressed_texture) {
  813. if (_glCompressedTexImage1D == NULL ||
  814. _glCompressedTexImage2D == NULL ||
  815. _glCompressedTexImage3D == NULL ||
  816. _glCompressedTexSubImage1D == NULL ||
  817. _glCompressedTexSubImage2D == NULL ||
  818. _glCompressedTexSubImage3D == NULL ||
  819. _glGetCompressedTexImage == NULL) {
  820. GLCAT.warning()
  821. << "Compressed textures advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  822. _supports_compressed_texture = false;
  823. }
  824. }
  825. #endif
  826. if (_supports_compressed_texture) {
  827. #ifndef OPENGLES
  828. _compressed_texture_formats.set_bit(Texture::CM_on);
  829. #endif
  830. GLint num_compressed_formats = 0;
  831. glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_compressed_formats);
  832. GLint *formats = (GLint *)PANDA_MALLOC_ARRAY(num_compressed_formats * sizeof(GLint));
  833. glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats);
  834. for (int i = 0; i < num_compressed_formats; ++i) {
  835. switch (formats[i]) {
  836. case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  837. case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  838. _compressed_texture_formats.set_bit(Texture::CM_dxt1);
  839. break;
  840. #ifdef OPENGLES
  841. case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
  842. case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
  843. _compressed_texture_formats.set_bit(Texture::CM_pvr1_2bpp);
  844. break;
  845. case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
  846. case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
  847. _compressed_texture_formats.set_bit(Texture::CM_pvr1_4bpp);
  848. break;
  849. #else
  850. case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
  851. _compressed_texture_formats.set_bit(Texture::CM_dxt3);
  852. break;
  853. case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
  854. _compressed_texture_formats.set_bit(Texture::CM_dxt5);
  855. break;
  856. case GL_COMPRESSED_RGB_FXT1_3DFX:
  857. case GL_COMPRESSED_RGBA_FXT1_3DFX:
  858. _compressed_texture_formats.set_bit(Texture::CM_fxt1);
  859. break;
  860. #endif
  861. default:
  862. break;
  863. }
  864. }
  865. PANDA_FREE_ARRAY(formats);
  866. }
  867. #ifdef OPENGLES_2
  868. _supports_bgr = false;
  869. #else
  870. _supports_bgr =
  871. has_extension("GL_EXT_bgra") || is_at_least_gl_version(1, 2);
  872. #endif
  873. #ifdef OPENGLES_2
  874. _supports_rescale_normal = true;
  875. #else
  876. _supports_rescale_normal =
  877. gl_support_rescale_normal &&
  878. (has_extension("GL_EXT_rescale_normal") || is_at_least_gl_version(1, 2));
  879. #endif
  880. #ifdef OPENGLES
  881. _supports_packed_dabc = false;
  882. #else
  883. _supports_packed_dabc = /*gl_support_packed_dabc &&*/
  884. has_extension("GL_ARB_vertex_array_bgra") || has_extension("GL_EXT_vertex_array_bgra");
  885. #endif
  886. _supports_multisample =
  887. has_extension("GL_ARB_multisample") || is_at_least_gl_version(1, 3);
  888. #ifdef OPENGLES_2
  889. _supports_generate_mipmap = true;
  890. #else
  891. _supports_generate_mipmap =
  892. has_extension("GL_SGIS_generate_mipmap") || is_at_least_gl_version(1, 4) || is_at_least_gles_version(1, 1);
  893. #endif
  894. #ifdef OPENGLES
  895. _supports_tex_non_pow2 =
  896. has_extension("GL_OES_texture_npot");
  897. #else
  898. _supports_tex_non_pow2 =
  899. has_extension("GL_ARB_texture_non_power_of_two");
  900. #endif
  901. #ifdef OPENGLES_2
  902. _glActiveTexture = glActiveTexture;
  903. #else
  904. if (is_at_least_gl_version(1, 3) || is_at_least_gles_version(1, 1)) {
  905. _supports_multitexture = true;
  906. _glActiveTexture = (PFNGLACTIVETEXTUREPROC)
  907. get_extension_func("glActiveTexture");
  908. _glClientActiveTexture = (PFNGLACTIVETEXTUREPROC)
  909. get_extension_func("glClientActiveTexture");
  910. _glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)
  911. get_extension_func("glMultiTexCoord1f");
  912. _glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)
  913. get_extension_func("glMultiTexCoord2f");
  914. _glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)
  915. get_extension_func("glMultiTexCoord3f");
  916. _glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)
  917. get_extension_func("glMultiTexCoord4f");
  918. _glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)
  919. get_extension_func("glMultiTexCoord1d");
  920. _glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)
  921. get_extension_func("glMultiTexCoord2d");
  922. _glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)
  923. get_extension_func("glMultiTexCoord3d");
  924. _glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)
  925. get_extension_func("glMultiTexCoord4d");
  926. } else if (has_extension("GL_ARB_multitexture")) {
  927. _supports_multitexture = true;
  928. _glActiveTexture = (PFNGLACTIVETEXTUREPROC)
  929. get_extension_func("glActiveTextureARB");
  930. _glClientActiveTexture = (PFNGLACTIVETEXTUREPROC)
  931. get_extension_func("glClientActiveTextureARB");
  932. _glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)
  933. get_extension_func("glMultiTexCoord1fARB");
  934. _glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)
  935. get_extension_func("glMultiTexCoord2fARB");
  936. _glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)
  937. get_extension_func("glMultiTexCoord3fARB");
  938. _glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)
  939. get_extension_func("glMultiTexCoord4fARB");
  940. _glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)
  941. get_extension_func("glMultiTexCoord1dARB");
  942. _glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)
  943. get_extension_func("glMultiTexCoord2dARB");
  944. _glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)
  945. get_extension_func("glMultiTexCoord3dARB");
  946. _glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)
  947. get_extension_func("glMultiTexCoord4dARB");
  948. } else {
  949. _supports_multitexture = false;
  950. }
  951. if (_supports_multitexture) {
  952. if (_glActiveTexture == NULL || _glClientActiveTexture == NULL
  953. #ifdef SUPPORT_IMMEDIATE_MODE
  954. || GLf(_glMultiTexCoord1) == NULL || GLf(_glMultiTexCoord2) == NULL
  955. || GLf(_glMultiTexCoord3) == NULL || GLf(_glMultiTexCoord4) == NULL
  956. #endif
  957. ) {
  958. GLCAT.warning()
  959. << "Multitexture advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  960. _supports_multitexture = false;
  961. }
  962. }
  963. if (!_supports_multitexture) {
  964. // Replace with dummy no-op functions.
  965. _glActiveTexture = null_glActiveTexture;
  966. _glClientActiveTexture = null_glActiveTexture;
  967. }
  968. #endif
  969. #ifdef OPENGLES
  970. if (has_extension("GL_ANGLE_depth_texture")) {
  971. // This extension provides both depth textures and depth-stencil support.
  972. _supports_depth_texture = true;
  973. _supports_depth_stencil = true;
  974. } else if (has_extension("GL_OES_depth_texture")) {
  975. _supports_depth_texture = true;
  976. _supports_depth_stencil = has_extension("GL_OES_packed_depth_stencil");
  977. }
  978. _supports_depth24 = has_extension("GL_OES_depth24");
  979. _supports_depth32 = has_extension("GL_OES_depth32");
  980. #else
  981. _supports_depth_texture = (is_at_least_gl_version(1, 4) ||
  982. has_extension("GL_ARB_depth_texture"));
  983. #endif
  984. #ifdef OPENGLES_2
  985. if (gl_support_shadow_filter && _supports_depth_texture &&
  986. has_extension("GL_EXT_shadow_samplers")) {
  987. _supports_shadow_filter = true;
  988. }
  989. #else
  990. if (gl_support_shadow_filter &&
  991. _supports_depth_texture &&
  992. has_extension("GL_ARB_shadow") &&
  993. has_extension("GL_ARB_fragment_program_shadow")) {
  994. _supports_shadow_filter = true;
  995. }
  996. #endif
  997. // Actually, we can't keep forever disabling ARB_shadow on ATI cards,
  998. // since they do work correctly now. Maybe there is some feature
  999. // level we can check somewhere?
  1000. /*if (_gl_vendor.substr(0,3)=="ATI") {
  1001. // ATI drivers have never provided correct shadow support.
  1002. _supports_shadow_filter = false;
  1003. }*/
  1004. #ifdef OPENGLES_2
  1005. _supports_texture_combine = false;
  1006. _supports_texture_saved_result = false;
  1007. _supports_texture_dot3 = false;
  1008. #else
  1009. _supports_texture_combine =
  1010. has_extension("GL_ARB_texture_env_combine") || is_at_least_gl_version(1, 3) || is_at_least_gles_version(1, 1);
  1011. _supports_texture_saved_result =
  1012. has_extension("GL_ARB_texture_env_crossbar") || has_extension("GL_OES_texture_env_crossbar") || is_at_least_gl_version(1, 4);
  1013. _supports_texture_dot3 =
  1014. has_extension("GL_ARB_texture_env_dot3") || is_at_least_gl_version(1, 3) || is_at_least_gles_version(1, 1);
  1015. #endif
  1016. #ifdef OPENGLES_2
  1017. _supports_buffers = true;
  1018. _glGenBuffers = glGenBuffers;
  1019. _glBindBuffer = glBindBuffer;
  1020. _glBufferData = glBufferData;
  1021. _glBufferSubData = glBufferSubData;
  1022. _glDeleteBuffers = glDeleteBuffers;
  1023. #else
  1024. _supports_buffers = false;
  1025. if (is_at_least_gl_version(1, 5) || is_at_least_gles_version(1, 1)) {
  1026. _supports_buffers = true;
  1027. _glGenBuffers = (PFNGLGENBUFFERSPROC)
  1028. get_extension_func("glGenBuffers");
  1029. _glBindBuffer = (PFNGLBINDBUFFERPROC)
  1030. get_extension_func("glBindBuffer");
  1031. _glBufferData = (PFNGLBUFFERDATAPROC)
  1032. get_extension_func("glBufferData");
  1033. _glBufferSubData = (PFNGLBUFFERSUBDATAPROC)
  1034. get_extension_func("glBufferSubData");
  1035. _glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)
  1036. get_extension_func("glDeleteBuffers");
  1037. }
  1038. #ifndef OPENGLES_1
  1039. else if (has_extension("GL_ARB_vertex_buffer_object")) {
  1040. _supports_buffers = true;
  1041. _glGenBuffers = (PFNGLGENBUFFERSPROC)
  1042. get_extension_func("glGenBuffersARB");
  1043. _glBindBuffer = (PFNGLBINDBUFFERPROC)
  1044. get_extension_func("glBindBufferARB");
  1045. _glBufferData = (PFNGLBUFFERDATAPROC)
  1046. get_extension_func("glBufferDataARB");
  1047. _glBufferSubData = (PFNGLBUFFERSUBDATAPROC)
  1048. get_extension_func("glBufferSubDataARB");
  1049. _glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)
  1050. get_extension_func("glDeleteBuffersARB");
  1051. }
  1052. #endif // OPENGLES_1
  1053. if (_supports_buffers) {
  1054. if (_glGenBuffers == NULL || _glBindBuffer == NULL ||
  1055. _glBufferData == NULL || _glBufferSubData == NULL ||
  1056. _glDeleteBuffers == NULL) {
  1057. GLCAT.warning()
  1058. << "Buffers advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1059. _supports_buffers = false;
  1060. }
  1061. }
  1062. #endif
  1063. #if defined(HAVE_CG) && !defined(OPENGLES)
  1064. if (cgGLIsProfileSupported(CG_PROFILE_ARBFP1) &&
  1065. cgGLIsProfileSupported(CG_PROFILE_ARBVP1)) {
  1066. _supports_basic_shaders = true;
  1067. if (basic_shaders_only) {
  1068. _shader_caps._active_vprofile = (int)CG_PROFILE_ARBVP1;
  1069. _shader_caps._active_fprofile = (int)CG_PROFILE_ARBFP1;
  1070. _shader_caps._active_gprofile = (int)CG_PROFILE_UNKNOWN; // No geometry shader if only using basic
  1071. } else {
  1072. _shader_caps._active_vprofile = (int)cgGLGetLatestProfile(CG_GL_VERTEX);
  1073. _shader_caps._active_fprofile = (int)cgGLGetLatestProfile(CG_GL_FRAGMENT);
  1074. _shader_caps._active_gprofile = (int)cgGLGetLatestProfile(CG_GL_GEOMETRY);
  1075. // cgGLGetLatestProfile doesn't seem to return anything other
  1076. // arbvp1/arbfp1 on non-NVIDIA cards, which is severely limiting.
  1077. // So, if this happens, we set it to GLSL, which is
  1078. // usually supported on all cards.
  1079. // The GLSL profiles are horribly broken on non-NVIDIA cards, but
  1080. // I think I've worked around the issues sufficiently.
  1081. if ((_shader_caps._active_vprofile == CG_PROFILE_ARBVP1 ||
  1082. _shader_caps._active_fprofile == CG_PROFILE_ARBFP1) &&
  1083. cgGLIsProfileSupported(CG_PROFILE_GLSLV) &&
  1084. cgGLIsProfileSupported(CG_PROFILE_GLSLF)) {
  1085. _shader_caps._active_vprofile = (int)CG_PROFILE_GLSLV;
  1086. _shader_caps._active_fprofile = (int)CG_PROFILE_GLSLF;
  1087. #if CG_VERSION_NUM >= 2200
  1088. if (cgGLIsProfileSupported(CG_PROFILE_GLSLG)) {
  1089. _shader_caps._active_gprofile = (int)CG_PROFILE_GLSLG;
  1090. }
  1091. #endif
  1092. }
  1093. }
  1094. _shader_caps._ultimate_vprofile = (int)CG_PROFILE_VP40;
  1095. _shader_caps._ultimate_fprofile = (int)CG_PROFILE_FP40;
  1096. _shader_caps._ultimate_gprofile = (int)CG_PROFILE_GPU_GP;
  1097. _cg_context = cgCreateContext();
  1098. #if CG_VERSION_NUM >= 3100
  1099. // This just sounds like a good thing to do.
  1100. cgGLSetContextGLSLVersion(_cg_context, cgGLDetectGLSLVersion());
  1101. if (_shader_caps._active_vprofile == CG_PROFILE_GLSLV) {
  1102. cgGLSetContextOptimalOptions(_cg_context, CG_PROFILE_GLSLC);
  1103. }
  1104. #endif
  1105. // Bug workaround for radeons.
  1106. if (_shader_caps._active_fprofile == CG_PROFILE_ARBFP1) {
  1107. if (has_extension("GL_ATI_draw_buffers")) {
  1108. _shader_caps._bug_list.insert(Shader::SBUG_ati_draw_buffers);
  1109. }
  1110. }
  1111. }
  1112. #endif // HAVE_CG
  1113. #ifdef OPENGLES_2
  1114. _supports_glsl = true;
  1115. _supports_geometry_shaders = false;
  1116. _supports_tessellation_shaders = false;
  1117. #else
  1118. #ifdef OPENGLES_1
  1119. _supports_glsl = false;
  1120. _supports_geometry_shaders = false;
  1121. _supports_tessellation_shaders = false;
  1122. #else
  1123. _supports_glsl = is_at_least_gl_version(2, 0) || has_extension("GL_ARB_shading_language_100");
  1124. _supports_geometry_shaders = is_at_least_gl_version(3, 2) || has_extension("GL_ARB_geometry_shader4");
  1125. _supports_tessellation_shaders = is_at_least_gl_version(4, 0) || has_extension("GL_ARB_tessellation_shader");
  1126. #endif
  1127. #endif
  1128. _shader_caps._supports_glsl = _supports_glsl;
  1129. _supports_compute_shaders = false;
  1130. #ifndef OPENGLES
  1131. if (is_at_least_gl_version(4, 3) || has_extension("GL_ARB_compute_shader")) {
  1132. _glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC)
  1133. get_extension_func("glDispatchCompute");
  1134. if (_glDispatchCompute != NULL) {
  1135. _supports_compute_shaders = true;
  1136. }
  1137. }
  1138. #endif
  1139. #ifndef OPENGLES
  1140. if (_supports_glsl) {
  1141. _glAttachShader = (PFNGLATTACHSHADERPROC)
  1142. get_extension_func("glAttachShader");
  1143. _glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)
  1144. get_extension_func("glBindAttribLocation");
  1145. _glCompileShader = (PFNGLCOMPILESHADERPROC)
  1146. get_extension_func("glCompileShader");
  1147. _glCreateProgram = (PFNGLCREATEPROGRAMPROC)
  1148. get_extension_func("glCreateProgram");
  1149. _glCreateShader = (PFNGLCREATESHADERPROC)
  1150. get_extension_func("glCreateShader");
  1151. _glDeleteProgram = (PFNGLDELETEPROGRAMPROC)
  1152. get_extension_func("glDeleteProgram");
  1153. _glDeleteShader = (PFNGLDELETESHADERPROC)
  1154. get_extension_func("glDeleteShader");
  1155. _glDetachShader = (PFNGLDETACHSHADERPROC)
  1156. get_extension_func("glDetachShader");
  1157. _glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)
  1158. get_extension_func("glDisableVertexAttribArray");
  1159. _glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)
  1160. get_extension_func("glEnableVertexAttribArray");
  1161. _glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)
  1162. get_extension_func("glGetActiveAttrib");
  1163. _glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)
  1164. get_extension_func("glGetActiveUniform");
  1165. _glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)
  1166. get_extension_func("glGetAttribLocation");
  1167. _glGetProgramiv = (PFNGLGETPROGRAMIVPROC)
  1168. get_extension_func("glGetProgramiv");
  1169. _glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)
  1170. get_extension_func("glGetProgramInfoLog");
  1171. _glGetShaderiv = (PFNGLGETSHADERIVPROC)
  1172. get_extension_func("glGetShaderiv");
  1173. _glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)
  1174. get_extension_func("glGetShaderInfoLog");
  1175. _glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)
  1176. get_extension_func("glGetUniformLocation");
  1177. _glLinkProgram = (PFNGLLINKPROGRAMPROC)
  1178. get_extension_func("glLinkProgram");
  1179. _glShaderSource = (PFNGLSHADERSOURCEPROC_P)
  1180. get_extension_func("glShaderSource");
  1181. _glUseProgram = (PFNGLUSEPROGRAMPROC)
  1182. get_extension_func("glUseProgram");
  1183. _glUniform4f = (PFNGLUNIFORM4FPROC)
  1184. get_extension_func("glUniform4f");
  1185. _glUniform1i = (PFNGLUNIFORM1IPROC)
  1186. get_extension_func("glUniform1i");
  1187. _glUniform1fv = (PFNGLUNIFORM1FVPROC)
  1188. get_extension_func("glUniform1fv");
  1189. _glUniform2fv = (PFNGLUNIFORM2FVPROC)
  1190. get_extension_func("glUniform2fv");
  1191. _glUniform3fv = (PFNGLUNIFORM3FVPROC)
  1192. get_extension_func("glUniform3fv");
  1193. _glUniform4fv = (PFNGLUNIFORM4FVPROC)
  1194. get_extension_func("glUniform4fv");
  1195. _glUniform1iv = (PFNGLUNIFORM1IVPROC)
  1196. get_extension_func("glUniform1iv");
  1197. _glUniform2iv = (PFNGLUNIFORM2IVPROC)
  1198. get_extension_func("glUniform2iv");
  1199. _glUniform3iv = (PFNGLUNIFORM3IVPROC)
  1200. get_extension_func("glUniform3iv");
  1201. _glUniform4iv = (PFNGLUNIFORM4IVPROC)
  1202. get_extension_func("glUniform4iv");
  1203. _glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)
  1204. get_extension_func("glUniformMatrix3fv");
  1205. _glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)
  1206. get_extension_func("glUniformMatrix4fv");
  1207. _glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)
  1208. get_extension_func("glValidateProgram");
  1209. _glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)
  1210. get_extension_func("glVertexAttribPointer");
  1211. if (is_at_least_gl_version(3, 0)) {
  1212. _glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)
  1213. get_extension_func("glVertexAttribIPointer");
  1214. } else {
  1215. _glVertexAttribIPointer = NULL;
  1216. }
  1217. if (has_extension("GL_ARB_vertex_attrib_64bit")) {
  1218. _glVertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC)
  1219. get_extension_func("glVertexAttribLPointer");
  1220. } else {
  1221. _glVertexAttribLPointer = NULL;
  1222. }
  1223. if (_supports_geometry_shaders) {
  1224. _glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)
  1225. get_extension_func("glProgramParameteri");
  1226. _glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREARBPROC)
  1227. get_extension_func("glFramebufferTextureARB");
  1228. if (_glFramebufferTextureLayer == NULL) {
  1229. _glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)
  1230. get_extension_func("glFramebufferTextureLayerARB");
  1231. }
  1232. }
  1233. if (_supports_tessellation_shaders) {
  1234. _glPatchParameteri = (PFNGLPATCHPARAMETERIPROC)
  1235. get_extension_func("glPatchParameteri");
  1236. }
  1237. }
  1238. #endif
  1239. #ifdef OPENGLES_2
  1240. _glAttachShader = glAttachShader;
  1241. _glBindAttribLocation = glBindAttribLocation;
  1242. _glCompileShader = glCompileShader;
  1243. _glCreateProgram = glCreateProgram;
  1244. _glCreateShader = glCreateShader;
  1245. _glDeleteProgram = glDeleteProgram;
  1246. _glDeleteShader = glDeleteShader;
  1247. _glDetachShader = glDetachShader;
  1248. _glDisableVertexAttribArray = glDisableVertexAttribArray;
  1249. _glEnableVertexAttribArray = glEnableVertexAttribArray;
  1250. _glGetActiveAttrib = glGetActiveAttrib;
  1251. _glGetActiveUniform = glGetActiveUniform;
  1252. _glGetAttribLocation = glGetAttribLocation;
  1253. _glGetProgramiv = glGetProgramiv;
  1254. _glGetProgramInfoLog = glGetProgramInfoLog;
  1255. _glGetShaderiv = glGetShaderiv;
  1256. _glGetShaderInfoLog = glGetShaderInfoLog;
  1257. _glGetUniformLocation = glGetUniformLocation;
  1258. _glLinkProgram = glLinkProgram;
  1259. _glShaderSource = (PFNGLSHADERSOURCEPROC_P) glShaderSource;
  1260. _glUseProgram = glUseProgram;
  1261. _glUniform4f = glUniform4f;
  1262. _glUniform1i = glUniform1i;
  1263. _glUniform1fv = glUniform1fv;
  1264. _glUniform2fv = glUniform2fv;
  1265. _glUniform3fv = glUniform3fv;
  1266. _glUniform4fv = glUniform4fv;
  1267. _glUniformMatrix3fv = glUniformMatrix3fv;
  1268. _glUniformMatrix4fv = glUniformMatrix4fv;
  1269. _glValidateProgram = glValidateProgram;
  1270. _glVertexAttribPointer = glVertexAttribPointer;
  1271. _glVertexAttribIPointer = NULL;
  1272. _glVertexAttribLPointer = NULL;
  1273. // We need to have a default shader to apply in case
  1274. // something didn't happen to have a shader applied, or
  1275. // if it failed to compile. This default shader just outputs
  1276. // a red color, indicating that something went wrong.
  1277. if (_default_shader == NULL) {
  1278. _default_shader = Shader::make(Shader::SL_GLSL, default_vshader, default_fshader);
  1279. }
  1280. #endif
  1281. // Check whether we support geometry instancing and instanced vertex attribs.
  1282. #if defined(OPENGLES_1)
  1283. _supports_vertex_attrib_divisor = false;
  1284. _supports_geometry_instancing = false;
  1285. #elif defined(OPENGLES_2)
  1286. if (has_extension("GL_ANGLE_instanced_arrays")) {
  1287. // This extension has both things in one.
  1288. #ifdef __EMSCRIPTEN__
  1289. // Work around bug - it doesn't allow ANGLE suffix in getProcAddress.
  1290. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1291. get_extension_func("glVertexAttribDivisor");
  1292. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1293. get_extension_func("glDrawArraysInstanced");
  1294. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1295. get_extension_func("glDrawElementsInstanced");
  1296. #else
  1297. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1298. get_extension_func("glVertexAttribDivisorANGLE");
  1299. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1300. get_extension_func("glDrawArraysInstancedANGLE");
  1301. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1302. get_extension_func("glDrawElementsInstancedANGLE");
  1303. #endif
  1304. _supports_vertex_attrib_divisor = true;
  1305. _supports_geometry_instancing = true;
  1306. } else {
  1307. // Check separately for geometry instancing and instanced attribs.
  1308. if (has_extension("GL_EXT_draw_instanced")) {
  1309. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1310. get_extension_func("glDrawArraysInstancedEXT");
  1311. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1312. get_extension_func("glDrawElementsInstancedEXT");
  1313. _supports_geometry_instancing = true;
  1314. } else if (has_extension("GL_NV_draw_instanced")) {
  1315. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1316. get_extension_func("glDrawArraysInstancedNV");
  1317. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1318. get_extension_func("glDrawElementsInstancedNV");
  1319. _supports_geometry_instancing = true;
  1320. } else {
  1321. _supports_geometry_instancing = false;
  1322. }
  1323. if (has_extension("GL_EXT_instanced_arrays")) {
  1324. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1325. get_extension_func("glVertexAttribDivisorEXT");
  1326. _supports_vertex_attrib_divisor = true;
  1327. } else if (has_extension("GL_NV_instanced_arrays")) {
  1328. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1329. get_extension_func("glVertexAttribDivisorNV");
  1330. _supports_vertex_attrib_divisor = true;
  1331. } else {
  1332. _supports_vertex_attrib_divisor = false;
  1333. }
  1334. }
  1335. #else
  1336. if (is_at_least_gl_version(3, 3)) {
  1337. // This feature is in OpenGL core as of 3.3.
  1338. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1339. get_extension_func("glVertexAttribDivisor");
  1340. _supports_vertex_attrib_divisor = true;
  1341. } else if (has_extension("GL_ARB_instanced_arrays")) {
  1342. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1343. get_extension_func("glVertexAttribDivisorARB");
  1344. _supports_vertex_attrib_divisor = true;
  1345. } else {
  1346. _supports_vertex_attrib_divisor = false;
  1347. }
  1348. // Some drivers expose one extension, some expose the other.
  1349. if (is_at_least_gl_version(3, 1)) {
  1350. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1351. get_extension_func("glDrawArraysInstanced");
  1352. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1353. get_extension_func("glDrawElementsInstanced");
  1354. _supports_geometry_instancing = true;
  1355. } else if (has_extension("GL_ARB_draw_instanced")) {
  1356. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1357. get_extension_func("glDrawArraysInstancedARB");
  1358. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1359. get_extension_func("glDrawElementsInstancedARB");
  1360. _supports_geometry_instancing = true;
  1361. } else if (has_extension("GL_EXT_draw_instanced")) {
  1362. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1363. get_extension_func("glDrawArraysInstancedEXT");
  1364. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1365. get_extension_func("glDrawElementsInstancedEXT");
  1366. _supports_geometry_instancing = true;
  1367. } else {
  1368. _glDrawElementsInstanced = 0;
  1369. _glDrawArraysInstanced = 0;
  1370. _supports_geometry_instancing = false;
  1371. }
  1372. #endif
  1373. #ifndef OPENGLES_1
  1374. if (_supports_geometry_instancing) {
  1375. if (_glDrawArraysInstanced == NULL || _glDrawElementsInstanced == NULL) {
  1376. GLCAT.warning()
  1377. << "Geometry instancing advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1378. _supports_geometry_instancing = false;
  1379. }
  1380. }
  1381. if (_supports_vertex_attrib_divisor) {
  1382. if (_glVertexAttribDivisor == NULL) {
  1383. GLCAT.warning()
  1384. << "Instanced vertex arrays advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1385. _supports_vertex_attrib_divisor = false;
  1386. }
  1387. }
  1388. #endif
  1389. #ifdef OPENGLES_2
  1390. // In OpenGL ES 2.x, FBO's are supported in the core.
  1391. _supports_framebuffer_object = true;
  1392. _glIsRenderbuffer = glIsRenderbuffer;
  1393. _glBindRenderbuffer = glBindRenderbuffer;
  1394. _glDeleteRenderbuffers = glDeleteRenderbuffers;
  1395. _glGenRenderbuffers = glGenRenderbuffers;
  1396. _glRenderbufferStorage = glRenderbufferStorage;
  1397. _glGetRenderbufferParameteriv = glGetRenderbufferParameteriv;
  1398. _glIsFramebuffer = glIsFramebuffer;
  1399. _glBindFramebuffer = glBindFramebuffer;
  1400. _glDeleteFramebuffers = glDeleteFramebuffers;
  1401. _glGenFramebuffers = glGenFramebuffers;
  1402. _glCheckFramebufferStatus = glCheckFramebufferStatus;
  1403. _glFramebufferTexture1D = NULL;
  1404. _glFramebufferTexture2D = glFramebufferTexture2D;
  1405. _glFramebufferRenderbuffer = glFramebufferRenderbuffer;
  1406. _glGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameteriv;
  1407. _glGenerateMipmap = glGenerateMipmap;
  1408. #else
  1409. //TODO: add ARB/3.0 version
  1410. _supports_framebuffer_object = false;
  1411. if (has_extension("GL_EXT_framebuffer_object")) {
  1412. _supports_framebuffer_object = true;
  1413. _glIsRenderbuffer = (PFNGLISRENDERBUFFEREXTPROC)
  1414. get_extension_func("glIsRenderbufferEXT");
  1415. _glBindRenderbuffer = (PFNGLBINDRENDERBUFFEREXTPROC)
  1416. get_extension_func("glBindRenderbufferEXT");
  1417. _glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSEXTPROC)
  1418. get_extension_func("glDeleteRenderbuffersEXT");
  1419. _glGenRenderbuffers = (PFNGLGENRENDERBUFFERSEXTPROC)
  1420. get_extension_func("glGenRenderbuffersEXT");
  1421. _glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEEXTPROC)
  1422. get_extension_func("glRenderbufferStorageEXT");
  1423. _glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)
  1424. get_extension_func("glGetRenderbufferParameterivEXT");
  1425. _glIsFramebuffer = (PFNGLISFRAMEBUFFEREXTPROC)
  1426. get_extension_func("glIsFramebufferEXT");
  1427. _glBindFramebuffer = (PFNGLBINDFRAMEBUFFEREXTPROC)
  1428. get_extension_func("glBindFramebufferEXT");
  1429. _glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSEXTPROC)
  1430. get_extension_func("glDeleteFramebuffersEXT");
  1431. _glGenFramebuffers = (PFNGLGENFRAMEBUFFERSEXTPROC)
  1432. get_extension_func("glGenFramebuffersEXT");
  1433. _glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
  1434. get_extension_func("glCheckFramebufferStatusEXT");
  1435. _glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)
  1436. get_extension_func("glFramebufferTexture1DEXT");
  1437. _glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)
  1438. get_extension_func("glFramebufferTexture2DEXT");
  1439. _glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)
  1440. get_extension_func("glFramebufferTexture3DEXT");
  1441. _glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)
  1442. get_extension_func("glFramebufferRenderbufferEXT");
  1443. _glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)
  1444. get_extension_func("glGetFramebufferAttachmentParameterivEXT");
  1445. _glGenerateMipmap = (PFNGLGENERATEMIPMAPEXTPROC)
  1446. get_extension_func("glGenerateMipmapEXT");
  1447. }
  1448. #ifdef OPENGLES
  1449. else if (has_extension("GL_OES_framebuffer_object")) {
  1450. _supports_framebuffer_object = true;
  1451. _glIsRenderbuffer = (PFNGLISRENDERBUFFEROESPROC)
  1452. get_extension_func("glIsRenderbufferOES");
  1453. _glBindRenderbuffer = (PFNGLBINDRENDERBUFFEROESPROC)
  1454. get_extension_func("glBindRenderbufferOES");
  1455. _glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSOESPROC)
  1456. get_extension_func("glDeleteRenderbuffersOES");
  1457. _glGenRenderbuffers = (PFNGLGENRENDERBUFFERSOESPROC)
  1458. get_extension_func("glGenRenderbuffersOES");
  1459. _glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEOESPROC)
  1460. get_extension_func("glRenderbufferStorageOES");
  1461. _glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVOESPROC)
  1462. get_extension_func("glGetRenderbufferParameterivOES");
  1463. _glIsFramebuffer = (PFNGLISFRAMEBUFFEROESPROC)
  1464. get_extension_func("glIsFramebufferOES");
  1465. _glBindFramebuffer = (PFNGLBINDFRAMEBUFFEROESPROC)
  1466. get_extension_func("glBindFramebufferOES");
  1467. _glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSOESPROC)
  1468. get_extension_func("glDeleteFramebuffersOES");
  1469. _glGenFramebuffers = (PFNGLGENFRAMEBUFFERSOESPROC)
  1470. get_extension_func("glGenFramebuffersOES");
  1471. _glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSOESPROC)
  1472. get_extension_func("glCheckFramebufferStatusOES");
  1473. _glFramebufferTexture1D = NULL;
  1474. _glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DOESPROC)
  1475. get_extension_func("glFramebufferTexture2DOES");
  1476. _glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFEROESPROC)
  1477. get_extension_func("glFramebufferRenderbufferOES");
  1478. _glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVOESPROC)
  1479. get_extension_func("glGetFramebufferAttachmentParameterivOES");
  1480. _glGenerateMipmap = (PFNGLGENERATEMIPMAPOESPROC)
  1481. get_extension_func("glGenerateMipmapOES");
  1482. }
  1483. #endif // OPENGLES
  1484. #endif
  1485. _supports_framebuffer_multisample = false;
  1486. if ( has_extension("GL_EXT_framebuffer_multisample") ) {
  1487. _supports_framebuffer_multisample = true;
  1488. _glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)
  1489. get_extension_func("glRenderbufferStorageMultisampleEXT");
  1490. }
  1491. #ifndef OPENGLES
  1492. _supports_framebuffer_multisample_coverage_nv = false;
  1493. if ( has_extension("GL_NV_framebuffer_multisample_coverage") ) {
  1494. _supports_framebuffer_multisample_coverage_nv = true;
  1495. _glRenderbufferStorageMultisampleCoverage = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC)
  1496. get_extension_func("glRenderbufferStorageMultisampleCoverageNV");
  1497. }
  1498. #endif
  1499. #ifndef OPENGLES_1
  1500. _supports_framebuffer_blit = false;
  1501. if ( has_extension("GL_EXT_framebuffer_blit") ) {
  1502. _supports_framebuffer_blit = true;
  1503. _glBlitFramebuffer = (PFNGLBLITFRAMEBUFFEREXTPROC)
  1504. get_extension_func("glBlitFramebufferEXT");
  1505. }
  1506. #endif
  1507. #if defined(OPENGLES_1)
  1508. _glDrawBuffers = NULL;
  1509. _glClearBufferfv = NULL;
  1510. _max_color_targets = 1;
  1511. #elif defined(OPENGLES_2)
  1512. if (has_extension("GL_EXT_draw_buffers")) {
  1513. _glDrawBuffers = (PFNGLDRAWBUFFERSPROC)
  1514. get_extension_func("glDrawBuffersEXT");
  1515. } else if (has_extension("GL_NV_draw_buffers")) {
  1516. _glDrawBuffers = (PFNGLDRAWBUFFERSPROC)
  1517. get_extension_func("glDrawBuffersNV");
  1518. }
  1519. #else
  1520. if (is_at_least_gl_version(2, 0)) {
  1521. _glDrawBuffers = (PFNGLDRAWBUFFERSPROC)
  1522. get_extension_func("glDrawBuffers");
  1523. } else if (has_extension("GL_ARB_draw_buffers")) {
  1524. _glDrawBuffers = (PFNGLDRAWBUFFERSPROC)
  1525. get_extension_func("glDrawBuffersARB");
  1526. }
  1527. #endif
  1528. #ifndef OPENGLES_1
  1529. _max_color_targets = 1;
  1530. if (_glDrawBuffers != 0) {
  1531. GLint max_draw_buffers = 0;
  1532. glGetIntegerv(GL_MAX_DRAW_BUFFERS, &max_draw_buffers);
  1533. _max_color_targets = max_draw_buffers;
  1534. }
  1535. #endif // !OPENGLES_1
  1536. #ifndef OPENGLES
  1537. if (is_at_least_gl_version(3, 0)) {
  1538. _glClearBufferfv = (PFNGLCLEARBUFFERFVPROC)
  1539. get_extension_func("glClearBufferfv");
  1540. } else {
  1541. _glClearBufferfv = NULL;
  1542. }
  1543. #endif // !OPENGLES
  1544. #ifndef OPENGLES
  1545. _supports_viewport_arrays = false;
  1546. if (is_at_least_gl_version(4, 1) || has_extension("GL_ARB_viewport_array")) {
  1547. _glViewportArrayv = (PFNGLVIEWPORTARRAYVPROC)
  1548. get_extension_func("glViewportArrayv");
  1549. _glScissorArrayv = (PFNGLSCISSORARRAYVPROC)
  1550. get_extension_func("glScissorArrayv");
  1551. _glDepthRangeArrayv = (PFNGLDEPTHRANGEARRAYVPROC)
  1552. get_extension_func("glDepthRangeArrayv");
  1553. if (_glViewportArrayv == NULL || _glScissorArrayv == NULL || _glDepthRangeArrayv == NULL) {
  1554. GLCAT.warning()
  1555. << "Viewport arrays advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1556. } else {
  1557. _supports_viewport_arrays = true;
  1558. }
  1559. }
  1560. #endif // !OPENGLES
  1561. _max_fb_samples = 0;
  1562. if (_supports_framebuffer_multisample) {
  1563. GLint max_samples;
  1564. glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_samples);
  1565. _max_fb_samples = max_samples;
  1566. }
  1567. _supports_occlusion_query = false;
  1568. #ifndef OPENGLES
  1569. if (gl_support_occlusion_query) {
  1570. if (is_at_least_gl_version(1, 5)) {
  1571. _supports_occlusion_query = true;
  1572. _glGenQueries = (PFNGLGENQUERIESPROC)
  1573. get_extension_func("glGenQueries");
  1574. _glBeginQuery = (PFNGLBEGINQUERYPROC)
  1575. get_extension_func("glBeginQuery");
  1576. _glEndQuery = (PFNGLENDQUERYPROC)
  1577. get_extension_func("glEndQuery");
  1578. _glDeleteQueries = (PFNGLDELETEQUERIESPROC)
  1579. get_extension_func("glDeleteQueries");
  1580. _glGetQueryiv = (PFNGLGETQUERYIVPROC)
  1581. get_extension_func("glGetQueryiv");
  1582. _glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)
  1583. get_extension_func("glGetQueryObjectuiv");
  1584. } else if (has_extension("GL_ARB_occlusion_query")) {
  1585. _supports_occlusion_query = true;
  1586. _glGenQueries = (PFNGLGENQUERIESPROC)
  1587. get_extension_func("glGenQueriesARB");
  1588. _glBeginQuery = (PFNGLBEGINQUERYPROC)
  1589. get_extension_func("glBeginQueryARB");
  1590. _glEndQuery = (PFNGLENDQUERYPROC)
  1591. get_extension_func("glEndQueryARB");
  1592. _glDeleteQueries = (PFNGLDELETEQUERIESPROC)
  1593. get_extension_func("glDeleteQueriesARB");
  1594. _glGetQueryiv = (PFNGLGETQUERYIVPROC)
  1595. get_extension_func("glGetQueryivARB");
  1596. _glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)
  1597. get_extension_func("glGetQueryObjectuivARB");
  1598. }
  1599. }
  1600. if (_supports_occlusion_query) {
  1601. if (_glGenQueries == NULL || _glBeginQuery == NULL ||
  1602. _glEndQuery == NULL || _glDeleteQueries == NULL ||
  1603. _glGetQueryiv == NULL || _glGetQueryObjectuiv == NULL) {
  1604. GLCAT.warning()
  1605. << "Occlusion queries advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1606. _supports_occlusion_query = false;
  1607. } else {
  1608. GLint num_bits;
  1609. _glGetQueryiv(GL_SAMPLES_PASSED, GL_QUERY_COUNTER_BITS, &num_bits);
  1610. if (num_bits == 0) {
  1611. _supports_occlusion_query = false;
  1612. }
  1613. if (GLCAT.is_debug()) {
  1614. GLCAT.debug()
  1615. << "Occlusion query counter provides " << num_bits << " bits.\n";
  1616. }
  1617. }
  1618. }
  1619. #endif // !OPENGLES
  1620. _supports_timer_query = false;
  1621. #if defined(DO_PSTATS) && !defined(OPENGLES)
  1622. if (is_at_least_gl_version(3, 3) || has_extension("GL_ARB_timer_query")) {
  1623. _supports_timer_query = true;
  1624. _glQueryCounter = (PFNGLQUERYCOUNTERPROC)
  1625. get_extension_func("glQueryCounter");
  1626. _glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC)
  1627. get_extension_func("glGetQueryObjecti64v");
  1628. _glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC)
  1629. get_extension_func("glGetQueryObjectui64v");
  1630. _glGetInteger64v = (PFNGLGETINTEGER64VPROC)
  1631. get_extension_func("glGetInteger64v");
  1632. }
  1633. #endif
  1634. #ifdef OPENGLES_2
  1635. // In OpenGL ES 2.x, this is supported in the core.
  1636. _glBlendEquation = glBlendEquation;
  1637. #else
  1638. _glBlendEquation = NULL;
  1639. bool supports_blend_equation = false;
  1640. if (is_at_least_gl_version(1, 2)) {
  1641. supports_blend_equation = true;
  1642. _glBlendEquation = (PFNGLBLENDEQUATIONPROC)
  1643. get_extension_func("glBlendEquation");
  1644. } else if (has_extension("GL_OES_blend_subtract")) {
  1645. supports_blend_equation = true;
  1646. _glBlendEquation = (PFNGLBLENDEQUATIONPROC)
  1647. get_extension_func("glBlendEquationOES");
  1648. } else if (has_extension("GL_EXT_blend_minmax")) {
  1649. supports_blend_equation = true;
  1650. _glBlendEquation = (PFNGLBLENDEQUATIONPROC)
  1651. get_extension_func("glBlendEquationEXT");
  1652. }
  1653. if (supports_blend_equation && _glBlendEquation == NULL) {
  1654. GLCAT.warning()
  1655. << "BlendEquation advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  1656. }
  1657. if (_glBlendEquation == NULL) {
  1658. _glBlendEquation = null_glBlendEquation;
  1659. }
  1660. #endif
  1661. #ifdef OPENGLES_2
  1662. // In OpenGL ES 2.x, this is supported in the core.
  1663. _glBlendColor = glBlendColor;
  1664. #else
  1665. _glBlendColor = NULL;
  1666. bool supports_blend_color = false;
  1667. if (is_at_least_gl_version(1, 2)) {
  1668. supports_blend_color = true;
  1669. _glBlendColor = (PFNGLBLENDCOLORPROC)
  1670. get_extension_func("glBlendColor");
  1671. } else if (has_extension("GL_EXT_blend_color")) {
  1672. supports_blend_color = true;
  1673. _glBlendColor = (PFNGLBLENDCOLORPROC)
  1674. get_extension_func("glBlendColorEXT");
  1675. }
  1676. if (supports_blend_color && _glBlendColor == NULL) {
  1677. GLCAT.warning()
  1678. << "BlendColor advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  1679. }
  1680. if (_glBlendColor == NULL) {
  1681. _glBlendColor = null_glBlendColor;
  1682. }
  1683. #endif
  1684. #ifdef OPENGLES
  1685. _edge_clamp = GL_CLAMP_TO_EDGE;
  1686. #else
  1687. _edge_clamp = GL_CLAMP;
  1688. if (has_extension("GL_SGIS_texture_edge_clamp") ||
  1689. is_at_least_gl_version(1, 2) || is_at_least_gles_version(1, 1)) {
  1690. _edge_clamp = GL_CLAMP_TO_EDGE;
  1691. }
  1692. #endif
  1693. _border_clamp = _edge_clamp;
  1694. #ifndef OPENGLES
  1695. if (gl_support_clamp_to_border &&
  1696. (has_extension("GL_ARB_texture_border_clamp") ||
  1697. is_at_least_gl_version(1, 3))) {
  1698. _border_clamp = GL_CLAMP_TO_BORDER;
  1699. }
  1700. #endif
  1701. #ifdef OPENGLES_2
  1702. _mirror_repeat = GL_MIRRORED_REPEAT;
  1703. #else
  1704. _mirror_repeat = GL_REPEAT;
  1705. if (has_extension("GL_ARB_texture_mirrored_repeat") ||
  1706. is_at_least_gl_version(1, 4) ||
  1707. has_extension("GL_OES_texture_mirrored_repeat")) {
  1708. _mirror_repeat = GL_MIRRORED_REPEAT;
  1709. }
  1710. #endif
  1711. _mirror_clamp = _edge_clamp;
  1712. _mirror_edge_clamp = _edge_clamp;
  1713. _mirror_border_clamp = _border_clamp;
  1714. #ifndef OPENGLES
  1715. if (has_extension("GL_EXT_texture_mirror_clamp")) {
  1716. _mirror_clamp = GL_MIRROR_CLAMP_EXT;
  1717. _mirror_edge_clamp = GL_MIRROR_CLAMP_TO_EDGE_EXT;
  1718. _mirror_border_clamp = GL_MIRROR_CLAMP_TO_BORDER_EXT;
  1719. }
  1720. #endif
  1721. if (_supports_multisample) {
  1722. GLint sample_buffers = 0;
  1723. glGetIntegerv(GL_SAMPLE_BUFFERS, &sample_buffers);
  1724. if (sample_buffers != 1) {
  1725. // Even if the API supports multisample, we might have ended up
  1726. // with a framebuffer that doesn't have any multisample bits.
  1727. // (It's also possible the graphics card doesn't provide any
  1728. // framebuffers with multisample.) In this case, we don't
  1729. // really support the multisample API's, since they won't do
  1730. // anything.
  1731. _supports_multisample = false;
  1732. }
  1733. }
  1734. GLint max_texture_size = 0;
  1735. GLint max_3d_texture_size = 0;
  1736. GLint max_2d_texture_array_layers = 0;
  1737. GLint max_cube_map_size = 0;
  1738. glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
  1739. _max_texture_dimension = max_texture_size;
  1740. if (_supports_3d_texture) {
  1741. #ifndef OPENGLES_1
  1742. glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
  1743. #endif
  1744. _max_3d_texture_dimension = max_3d_texture_size;
  1745. } else {
  1746. _max_3d_texture_dimension = 0;
  1747. }
  1748. #ifndef OPENGLES
  1749. if(_supports_2d_texture_array) {
  1750. glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS_EXT, &max_2d_texture_array_layers);
  1751. _max_2d_texture_array_layers = max_2d_texture_array_layers;
  1752. }
  1753. #endif
  1754. if (_supports_cube_map) {
  1755. glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_size);
  1756. _max_cube_map_dimension = max_cube_map_size;
  1757. } else {
  1758. _max_cube_map_dimension = 0;
  1759. }
  1760. GLint max_elements_vertices = 0, max_elements_indices = 0;
  1761. #ifndef OPENGLES
  1762. glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &max_elements_vertices);
  1763. glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &max_elements_indices);
  1764. if (max_elements_vertices > 0) {
  1765. _max_vertices_per_array = max_elements_vertices;
  1766. }
  1767. if (max_elements_indices > 0) {
  1768. _max_vertices_per_primitive = max_elements_indices;
  1769. }
  1770. #endif // OPENGLES
  1771. if (GLCAT.is_debug()) {
  1772. GLCAT.debug()
  1773. << "max texture dimension = " << _max_texture_dimension
  1774. << ", max 3d texture = " << _max_3d_texture_dimension
  1775. << ", max 2d texture array = " << max_2d_texture_array_layers
  1776. << ", max cube map = " << _max_cube_map_dimension << "\n";
  1777. GLCAT.debug()
  1778. << "max_elements_vertices = " << max_elements_vertices
  1779. << ", max_elements_indices = " << max_elements_indices << "\n";
  1780. if (_supports_buffers) {
  1781. if (vertex_buffers) {
  1782. GLCAT.debug()
  1783. << "vertex buffer objects are supported.\n";
  1784. } else {
  1785. GLCAT.debug()
  1786. << "vertex buffer objects are supported (but not enabled).\n";
  1787. }
  1788. } else {
  1789. GLCAT.debug()
  1790. << "vertex buffer objects are NOT supported.\n";
  1791. }
  1792. #ifdef SUPPORT_IMMEDIATE_MODE
  1793. if (!vertex_arrays) {
  1794. GLCAT.debug()
  1795. << "immediate mode commands will be used instead of vertex arrays.\n";
  1796. }
  1797. #endif
  1798. if (!_supports_compressed_texture) {
  1799. GLCAT.debug()
  1800. << "Texture compression is not supported.\n";
  1801. } else {
  1802. GLint num_compressed_formats = 0;
  1803. glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_compressed_formats);
  1804. if (num_compressed_formats == 0) {
  1805. GLCAT.debug()
  1806. << "No specific compressed texture formats are supported.\n";
  1807. } else {
  1808. GLCAT.debug()
  1809. << "Supported compressed texture formats:\n";
  1810. GLint *formats = (GLint *)alloca(num_compressed_formats * sizeof(GLint));
  1811. glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats);
  1812. for (int i = 0; i < num_compressed_formats; ++i) {
  1813. switch (formats[i]) {
  1814. case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  1815. GLCAT.debug(false) << " GL_COMPRESSED_RGB_S3TC_DXT1_EXT\n";
  1816. break;
  1817. case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  1818. GLCAT.debug(false) << " GL_COMPRESSED_RGBA_S3TC_DXT1_EXT\n";
  1819. break;
  1820. #ifdef OPENGLES
  1821. case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
  1822. GLCAT.debug(false) << " GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG\n";
  1823. break;
  1824. case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
  1825. GLCAT.debug(false) << " GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG\n";
  1826. break;
  1827. case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
  1828. GLCAT.debug(false) << " GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG\n";
  1829. break;
  1830. case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
  1831. GLCAT.debug(false) << " GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG\n";
  1832. break;
  1833. #endif
  1834. #ifndef OPENGLES_1
  1835. case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
  1836. GLCAT.debug(false) << " GL_COMPRESSED_RGBA_S3TC_DXT3_EXT\n";
  1837. break;
  1838. case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
  1839. GLCAT.debug(false) << " GL_COMPRESSED_RGBA_S3TC_DXT5_EXT\n";
  1840. break;
  1841. #endif
  1842. #ifndef OPENGLES
  1843. case GL_COMPRESSED_RGB_FXT1_3DFX:
  1844. GLCAT.debug(false) << " GL_COMPRESSED_RGB_FXT1_3DFX\n";
  1845. break;
  1846. case GL_COMPRESSED_RGBA_FXT1_3DFX:
  1847. GLCAT.debug(false) << " GL_COMPRESSED_RGBA_FXT1_3DFX\n";
  1848. break;
  1849. #endif
  1850. default:
  1851. GLCAT.debug(false)
  1852. << " Unknown compressed format 0x" << hex << formats[i]
  1853. << dec << "\n";
  1854. }
  1855. }
  1856. }
  1857. }
  1858. }
  1859. _num_active_texture_stages = 0;
  1860. // Check availability of anisotropic texture filtering.
  1861. _supports_anisotropy = false;
  1862. _max_anisotropy = 1.0;
  1863. if (has_extension("GL_EXT_texture_filter_anisotropic")) {
  1864. GLfloat max_anisotropy;
  1865. glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy);
  1866. _max_anisotropy = (PN_stdfloat)max_anisotropy;
  1867. _supports_anisotropy = true;
  1868. }
  1869. // Check availability of image read/write functionality in shaders.
  1870. _max_image_units = 0;
  1871. #ifndef OPENGLES
  1872. if (is_at_least_gl_version(4, 2) || has_extension("GL_ARB_shader_image_load_store")) {
  1873. _glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)
  1874. get_extension_func("glBindImageTexture");
  1875. _glMemoryBarrier = (PFNGLMEMORYBARRIERPROC)
  1876. get_extension_func("glMemoryBarrier");
  1877. glGetIntegerv(GL_MAX_IMAGE_UNITS, &_max_image_units);
  1878. } else if (has_extension("GL_EXT_shader_image_load_store")) {
  1879. _glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)
  1880. get_extension_func("glBindImageTextureEXT");
  1881. _glMemoryBarrier = (PFNGLMEMORYBARRIERPROC)
  1882. get_extension_func("glMemoryBarrierEXT");
  1883. glGetIntegerv(GL_MAX_IMAGE_UNITS_EXT, &_max_image_units);
  1884. } else {
  1885. _glBindImageTexture = NULL;
  1886. _glMemoryBarrier = NULL;
  1887. }
  1888. _supports_sampler_objects = false;
  1889. #ifndef OPENGLES
  1890. if (gl_support_sampler_objects &&
  1891. ((is_at_least_gl_version(3, 3) || has_extension("GL_ARB_sampler_objects")))) {
  1892. _glGenSamplers = (PFNGLGENSAMPLERSPROC) get_extension_func("glGenSamplers");
  1893. _glDeleteSamplers = (PFNGLDELETESAMPLERSPROC) get_extension_func("glDeleteSamplers");
  1894. _glBindSampler = (PFNGLBINDSAMPLERPROC) get_extension_func("glBindSampler");
  1895. _glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC) get_extension_func("glSamplerParameteri");
  1896. _glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC) get_extension_func("glSamplerParameteriv");
  1897. _glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC) get_extension_func("glSamplerParameterf");
  1898. _glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC) get_extension_func("glSamplerParameterfv");
  1899. if (_glGenSamplers == NULL || _glDeleteSamplers == NULL ||
  1900. _glBindSampler == NULL || _glSamplerParameteri == NULL ||
  1901. _glSamplerParameteriv == NULL || _glSamplerParameterf == NULL ||
  1902. _glSamplerParameterfv == NULL) {
  1903. GLCAT.warning()
  1904. << "GL_ARB_sampler_objects advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  1905. } else {
  1906. _supports_sampler_objects = true;
  1907. }
  1908. }
  1909. #endif // OPENGLES
  1910. // Check availability of multi-bind functions.
  1911. _supports_multi_bind = false;
  1912. if (is_at_least_gl_version(4, 4) || has_extension("GL_ARB_multi_bind")) {
  1913. _glBindTextures = (PFNGLBINDTEXTURESPROC)
  1914. get_extension_func("glBindTextures");
  1915. _glBindImageTextures = (PFNGLBINDIMAGETEXTURESPROC)
  1916. get_extension_func("glBindImageTextures");
  1917. #ifndef OPENGLES
  1918. if (_supports_sampler_objects) {
  1919. _glBindSamplers = (PFNGLBINDSAMPLERSPROC)
  1920. get_extension_func("glBindSamplers");
  1921. }
  1922. #endif // OPENGLES
  1923. if (_glBindTextures != NULL && _glBindImageTextures != NULL) {
  1924. _supports_multi_bind = true;
  1925. } else {
  1926. GLCAT.warning()
  1927. << "ARB_multi_bind advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  1928. }
  1929. }
  1930. if (is_at_least_gl_version(4, 3) || has_extension("GL_ARB_internalformat_query2")) {
  1931. _glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC)
  1932. get_extension_func("glGetInternalformativ");
  1933. if (_glGetInternalformativ == NULL) {
  1934. GLCAT.warning()
  1935. << "ARB_internalformat_query2 advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  1936. }
  1937. }
  1938. _supports_bindless_texture = false;
  1939. if (has_extension("GL_ARB_bindless_texture")) {
  1940. _glGetTextureHandle = (PFNGLGETTEXTUREHANDLEPROC)
  1941. get_extension_func("glGetTextureHandleARB");
  1942. _glGetTextureSamplerHandle = (PFNGLGETTEXTURESAMPLERHANDLEPROC)
  1943. get_extension_func("glGetTextureSamplerHandleARB");
  1944. _glMakeTextureHandleResident = (PFNGLMAKETEXTUREHANDLERESIDENTPROC)
  1945. get_extension_func("glMakeTextureHandleResidentARB");
  1946. _glUniformHandleui64 = (PFNGLUNIFORMHANDLEUI64PROC)
  1947. get_extension_func("glUniformHandleui64ARB");
  1948. if (_glGetTextureHandle == NULL || _glMakeTextureHandleResident == NULL ||
  1949. _glUniformHandleui64 == NULL) {
  1950. GLCAT.warning()
  1951. << "GL_ARB_bindless_texture advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  1952. } else {
  1953. _supports_bindless_texture = true;
  1954. }
  1955. }
  1956. #endif
  1957. #ifndef OPENGLES
  1958. _supports_get_program_binary = false;
  1959. if (is_at_least_gl_version(4, 1) || has_extension("GL_ARB_get_program_binary")) {
  1960. _glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC)
  1961. get_extension_func("glGetProgramBinary");
  1962. if (_glGetProgramBinary != NULL) {
  1963. _supports_get_program_binary = true;
  1964. }
  1965. }
  1966. #endif
  1967. report_my_gl_errors();
  1968. if (support_stencil) {
  1969. GLint num_stencil_bits;
  1970. glGetIntegerv(GL_STENCIL_BITS, &num_stencil_bits);
  1971. _supports_stencil = (num_stencil_bits != 0);
  1972. }
  1973. _supports_stencil_wrap =
  1974. has_extension("GL_EXT_stencil_wrap") || has_extension("GL_OES_stencil_wrap");
  1975. _supports_two_sided_stencil = false;
  1976. #ifndef OPENGLES
  1977. if (has_extension("GL_EXT_stencil_two_side")) {
  1978. _glActiveStencilFaceEXT = (PFNGLACTIVESTENCILFACEEXTPROC)
  1979. get_extension_func("glActiveStencilFaceEXT");
  1980. _supports_two_sided_stencil = true;
  1981. } else {
  1982. _glActiveStencilFaceEXT = 0;
  1983. }
  1984. #endif
  1985. _auto_rescale_normal = false;
  1986. // Ensure the initial state is what we say it should be (in some
  1987. // cases, we don't want the GL default settings; in others, we have
  1988. // to force the point with some drivers that aren't strictly
  1989. // compliant w.r.t. initial settings).
  1990. glFrontFace(GL_CCW);
  1991. #ifndef OPENGLES_2
  1992. glDisable(GL_LINE_SMOOTH);
  1993. glDisable(GL_POINT_SMOOTH);
  1994. #ifndef OPENGLES
  1995. glDisable(GL_POLYGON_SMOOTH);
  1996. #endif // OPENGLES
  1997. if (_supports_multisample) {
  1998. glDisable(GL_MULTISAMPLE);
  1999. }
  2000. #endif
  2001. // Set up all the enabled/disabled flags to GL's known initial
  2002. // values: everything off.
  2003. _multisample_mode = 0;
  2004. _line_smooth_enabled = false;
  2005. _point_smooth_enabled = false;
  2006. _polygon_smooth_enabled = false;
  2007. _stencil_test_enabled = false;
  2008. _blend_enabled = false;
  2009. _depth_test_enabled = false;
  2010. _fog_enabled = false;
  2011. _alpha_test_enabled = false;
  2012. _polygon_offset_enabled = false;
  2013. _flat_shade_model = false;
  2014. _decal_level = 0;
  2015. _active_color_write_mask = ColorWriteAttrib::C_all;
  2016. _tex_gen_point_sprite = false;
  2017. #ifndef OPENGLES
  2018. // Dither is on by default in GL; let's turn it off
  2019. glDisable(GL_DITHER);
  2020. #endif // OPENGLES
  2021. _dithering_enabled = false;
  2022. #ifndef OPENGLES_1
  2023. _current_shader = (Shader *)NULL;
  2024. _current_shader_context = (ShaderContext *)NULL;
  2025. _vertex_array_shader = (Shader *)NULL;
  2026. _vertex_array_shader_context = (ShaderContext *)NULL;
  2027. _texture_binding_shader = (Shader *)NULL;
  2028. _texture_binding_shader_context = (ShaderContext *)NULL;
  2029. #endif
  2030. #ifdef OPENGLES_2
  2031. _max_lights = 0;
  2032. #else
  2033. // Count the max number of lights
  2034. GLint max_lights = 0;
  2035. glGetIntegerv(GL_MAX_LIGHTS, &max_lights);
  2036. _max_lights = max_lights;
  2037. if (GLCAT.is_debug()) {
  2038. GLCAT.debug()
  2039. << "max lights = " << _max_lights << "\n";
  2040. }
  2041. #endif
  2042. #ifdef OPENGLES_2
  2043. _max_clip_planes = 0;
  2044. #else
  2045. // Count the max number of clipping planes
  2046. GLint max_clip_planes = 0;
  2047. glGetIntegerv(GL_MAX_CLIP_PLANES, &max_clip_planes);
  2048. _max_clip_planes = max_clip_planes;
  2049. if (GLCAT.is_debug()) {
  2050. GLCAT.debug()
  2051. << "max clip planes = " << _max_clip_planes << "\n";
  2052. }
  2053. #endif
  2054. #ifdef OPENGLES_2
  2055. _max_texture_stages = 0;
  2056. #else
  2057. if (_supports_multitexture) {
  2058. GLint max_texture_stages = 0;
  2059. glGetIntegerv(GL_MAX_TEXTURE_UNITS, &max_texture_stages);
  2060. _max_texture_stages = max_texture_stages;
  2061. if (GLCAT.is_debug()) {
  2062. GLCAT.debug()
  2063. << "max texture stages = " << _max_texture_stages << "\n";
  2064. }
  2065. }
  2066. #endif
  2067. _current_vbuffer_index = 0;
  2068. _current_ibuffer_index = 0;
  2069. _current_fbo = 0;
  2070. _auto_antialias_mode = false;
  2071. _render_mode = RenderModeAttrib::M_filled;
  2072. _point_size = 1.0f;
  2073. _point_perspective = false;
  2074. _vertex_blending_enabled = false;
  2075. report_my_gl_errors();
  2076. #ifndef OPENGLES_2
  2077. if (gl_cheap_textures) {
  2078. GLCAT.info()
  2079. << "Setting glHint() for fastest textures.\n";
  2080. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
  2081. }
  2082. // Use per-vertex fog if per-pixel fog requires SW renderer
  2083. glHint(GL_FOG_HINT, GL_DONT_CARE);
  2084. #endif
  2085. GLint num_red_bits = 0;
  2086. glGetIntegerv(GL_RED_BITS, &num_red_bits);
  2087. if (num_red_bits < 8) {
  2088. glEnable(GL_DITHER);
  2089. _dithering_enabled = true;
  2090. if (GLCAT.is_debug()) {
  2091. GLCAT.debug()
  2092. << "frame buffer depth = " << num_red_bits
  2093. << " bits/channel, enabling dithering\n";
  2094. }
  2095. }
  2096. _error_count = 0;
  2097. report_my_gl_errors();
  2098. #if defined(HAVE_CG) && !defined(OPENGLES)
  2099. typedef struct {
  2100. CGprofile cg_profile;
  2101. int shader_model;
  2102. } CG_PROFILE_TO_SHADER_MODEL;
  2103. static CG_PROFILE_TO_SHADER_MODEL cg_profile_to_shader_model_array[] = {
  2104. // gp5fp - OpenGL fragment profile for GeForce 400 Series and up
  2105. (CGprofile)7017, /*CG_PROFILE_GP5FP,*/
  2106. SM_50,
  2107. // gp4fp - OpenGL fragment profile for G8x (GeForce 8xxx and up)
  2108. (CGprofile)7010, /*CG_PROFILE_GP4FP,*/
  2109. SM_40,
  2110. // fp40 - OpenGL fragment profile for NV4x (GeForce 6xxx and 7xxx
  2111. // Series, NV4x-based Quadro FX, etc.)
  2112. CG_PROFILE_FP40,
  2113. SM_30,
  2114. // fp30 - OpenGL fragment profile for NV3x (GeForce FX, Quadro FX, etc.)
  2115. CG_PROFILE_FP30,
  2116. SM_2X,
  2117. // This OpenGL profile corresponds to the per-fragment
  2118. // functionality introduced by GeForce FX and other DirectX 9
  2119. // GPUs.
  2120. CG_PROFILE_ARBFP1,
  2121. SM_20,
  2122. // fp20 - OpenGL fragment profile for NV2x (GeForce3, GeForce4 Ti,
  2123. // Quadro DCC, etc.)
  2124. CG_PROFILE_FP20,
  2125. SM_11,
  2126. // no shader support
  2127. CG_PROFILE_UNKNOWN,
  2128. SM_00,
  2129. };
  2130. int index;
  2131. CG_PROFILE_TO_SHADER_MODEL *cg_profile_to_shader_model;
  2132. index = 0;
  2133. cg_profile_to_shader_model = cg_profile_to_shader_model_array;
  2134. while (cg_profile_to_shader_model->shader_model != SM_00) {
  2135. if (cgGLIsProfileSupported(cg_profile_to_shader_model->cg_profile)) {
  2136. _shader_model = cg_profile_to_shader_model->shader_model;
  2137. break;
  2138. }
  2139. cg_profile_to_shader_model++;
  2140. }
  2141. // DisplayInformation may have better shader model detection
  2142. {
  2143. GraphicsPipe *pipe;
  2144. DisplayInformation *display_information;
  2145. pipe = this->get_pipe();
  2146. if (pipe) {
  2147. display_information = pipe->get_display_information ();
  2148. if (display_information) {
  2149. if (display_information->get_shader_model() > _shader_model) {
  2150. _shader_model = display_information->get_shader_model();
  2151. }
  2152. }
  2153. }
  2154. }
  2155. _auto_detect_shader_model = _shader_model;
  2156. CGprofile vertex_profile;
  2157. CGprofile pixel_profile;
  2158. vertex_profile = cgGLGetLatestProfile(CG_GL_VERTEX);
  2159. pixel_profile = cgGLGetLatestProfile(CG_GL_FRAGMENT);
  2160. if (GLCAT.is_debug()) {
  2161. #if CG_VERSION_NUM >= 2200
  2162. GLCAT.debug() << "Supported Cg profiles:\n";
  2163. int num_profiles = cgGetNumSupportedProfiles();
  2164. for (int i = 0; i < num_profiles; ++i) {
  2165. CGprofile profile = cgGetSupportedProfile(i);
  2166. if (cgGLIsProfileSupported(profile)) {
  2167. GLCAT.debug() << " " << cgGetProfileString(profile) << "\n";
  2168. }
  2169. }
  2170. #endif // CG_VERSION_NUM >= 2200
  2171. #if CG_VERSION_NUM >= 3100
  2172. if (GLCAT.is_debug()) {
  2173. CGGLglslversion ver = cgGLGetContextGLSLVersion(_cg_context);
  2174. GLCAT.debug()
  2175. << "Cg GLSL version: " << cgGLGetGLSLVersionString(ver) << "\n";
  2176. }
  2177. #endif
  2178. GLCAT.debug()
  2179. << "\nCg latest vertex profile = " << cgGetProfileString(vertex_profile) << " id = " << vertex_profile
  2180. << "\nCg latest pixel profile = " << cgGetProfileString(pixel_profile) << " id = " << pixel_profile
  2181. << "\nshader model = " << _shader_model
  2182. << "\n";
  2183. }
  2184. #endif
  2185. // Now that the GSG has been initialized, make it available for
  2186. // optimizations.
  2187. add_gsg(this);
  2188. }
  2189. ////////////////////////////////////////////////////////////////////
  2190. // Function: GLGraphicsStateGuardian::finish
  2191. // Access: Public, Virtual
  2192. // Description: Force the graphics card to finish drawing before
  2193. // returning. !!!!!HACK WARNING!!!!
  2194. // glfinish does not actually wait for the graphics card to finish drawing
  2195. // only for draw calls to finish. Thus flip may not happene
  2196. // immediately. Instead we read a single pixel from
  2197. // the framebuffer. This forces the graphics card to
  2198. // finish drawing the frame before returning.
  2199. ////////////////////////////////////////////////////////////////////
  2200. void CLP(GraphicsStateGuardian)::
  2201. finish() {
  2202. // Rather than call glfinish which returns immediately if
  2203. // draw commands have been submitted, we will read a single pixel
  2204. // from the frame. That will force the graphics card to finish
  2205. // drawing before it is called
  2206. char data[4];
  2207. glReadPixels(0,0,1,1,GL_RGBA,GL_UNSIGNED_BYTE,&data);
  2208. //glFinish();
  2209. }
  2210. ////////////////////////////////////////////////////////////////////
  2211. // Function: GraphicsStateGuardian::clear
  2212. // Access: Public
  2213. // Description: Clears the framebuffer within the current
  2214. // DisplayRegion, according to the flags indicated by
  2215. // the given DrawableRegion object.
  2216. //
  2217. // This does not set the DisplayRegion first. You
  2218. // should call prepare_display_region() to specify the
  2219. // region you wish the clear operation to apply to.
  2220. ////////////////////////////////////////////////////////////////////
  2221. void CLP(GraphicsStateGuardian)::
  2222. clear(DrawableRegion *clearable) {
  2223. PStatGPUTimer timer(this, _clear_pcollector);
  2224. report_my_gl_errors();
  2225. if (!clearable->is_any_clear_active()) {
  2226. return;
  2227. }
  2228. //XXX rdb: Is this line really necessary?
  2229. set_state_and_transform(RenderState::make_empty(), _internal_transform);
  2230. int mask = 0;
  2231. #ifndef OPENGLES
  2232. if (_current_fbo != 0 && _glClearBufferfv != NULL) {
  2233. // We can use glClearBuffer to clear all the color attachments,
  2234. // which protects us from the overhead of having to call set_draw_buffer
  2235. // for every single attachment.
  2236. int index = 0;
  2237. if (_current_properties->get_color_bits() > 0) {
  2238. if (_current_properties->is_stereo()) {
  2239. // Clear both left and right attachments.
  2240. if (clearable->get_clear_active(GraphicsOutput::RTP_color)) {
  2241. LColorf v = LCAST(float, clearable->get_clear_value(GraphicsOutput::RTP_color));
  2242. _glClearBufferfv(GL_COLOR, index, v.get_data());
  2243. _glClearBufferfv(GL_COLOR, index + 1, v.get_data());
  2244. }
  2245. index += 2;
  2246. } else {
  2247. if (clearable->get_clear_active(GraphicsOutput::RTP_color)) {
  2248. LColorf v = LCAST(float, clearable->get_clear_value(GraphicsOutput::RTP_color));
  2249. _glClearBufferfv(GL_COLOR, index, v.get_data());
  2250. }
  2251. ++index;
  2252. }
  2253. }
  2254. for (int i = 0; i < _current_properties->get_aux_rgba(); ++i) {
  2255. int layerid = GraphicsOutput::RTP_aux_rgba_0 + i;
  2256. if (clearable->get_clear_active(layerid)) {
  2257. LColorf v = LCAST(float, clearable->get_clear_value(layerid));
  2258. _glClearBufferfv(GL_COLOR, index, v.get_data());
  2259. }
  2260. ++index;
  2261. }
  2262. for (int i = 0; i < _current_properties->get_aux_hrgba(); ++i) {
  2263. int layerid = GraphicsOutput::RTP_aux_hrgba_0 + i;
  2264. if (clearable->get_clear_active(layerid)) {
  2265. LColorf v = LCAST(float, clearable->get_clear_value(layerid));
  2266. _glClearBufferfv(GL_COLOR, index, v.get_data());
  2267. }
  2268. ++index;
  2269. }
  2270. for (int i = 0; i < _current_properties->get_aux_float(); ++i) {
  2271. int layerid = GraphicsOutput::RTP_aux_float_0 + i;
  2272. if (clearable->get_clear_active(layerid)) {
  2273. LColorf v = LCAST(float, clearable->get_clear_value(layerid));
  2274. _glClearBufferfv(GL_COLOR, index, v.get_data());
  2275. }
  2276. ++index;
  2277. }
  2278. } else
  2279. #endif
  2280. {
  2281. if (_current_properties->get_aux_mask() != 0) {
  2282. for (int i = 0; i < _current_properties->get_aux_rgba(); ++i) {
  2283. int layerid = GraphicsOutput::RTP_aux_rgba_0 + i;
  2284. int layerbit = RenderBuffer::T_aux_rgba_0 << i;
  2285. if (clearable->get_clear_active(layerid)) {
  2286. LColor v = clearable->get_clear_value(layerid);
  2287. glClearColor(v[0], v[1], v[2], v[3]);
  2288. set_draw_buffer(layerbit);
  2289. glClear(GL_COLOR_BUFFER_BIT);
  2290. }
  2291. }
  2292. for (int i = 0; i < _current_properties->get_aux_hrgba(); ++i) {
  2293. int layerid = GraphicsOutput::RTP_aux_hrgba_0 + i;
  2294. int layerbit = RenderBuffer::T_aux_hrgba_0 << i;
  2295. if (clearable->get_clear_active(layerid)) {
  2296. LColor v = clearable->get_clear_value(layerid);
  2297. glClearColor(v[0], v[1], v[2], v[3]);
  2298. set_draw_buffer(layerbit);
  2299. glClear(GL_COLOR_BUFFER_BIT);
  2300. }
  2301. }
  2302. for (int i = 0; i < _current_properties->get_aux_float(); ++i) {
  2303. int layerid = GraphicsOutput::RTP_aux_float_0 + i;
  2304. int layerbit = RenderBuffer::T_aux_float_0 << i;
  2305. if (clearable->get_clear_active(layerid)) {
  2306. LColor v = clearable->get_clear_value(layerid);
  2307. glClearColor(v[0], v[1], v[2], v[3]);
  2308. set_draw_buffer(layerbit);
  2309. glClear(GL_COLOR_BUFFER_BIT);
  2310. }
  2311. }
  2312. // In the past, it was possible to set the draw buffer
  2313. // once in prepare_display_region and then forget about it.
  2314. // Now, with aux layers, it is necessary to occasionally
  2315. // change the draw buffer. In time, I think there will need
  2316. // to be a draw buffer attrib. Until then, this little hack
  2317. // to put things back the way they were after
  2318. // prepare_display_region will do.
  2319. set_draw_buffer(_draw_buffer_type);
  2320. }
  2321. if (_current_properties->get_color_bits() > 0) {
  2322. if (clearable->get_clear_color_active()) {
  2323. LColor v = clearable->get_clear_color();
  2324. glClearColor(v[0], v[1], v[2], v[3]);
  2325. clear_color_write_mask();
  2326. _state_mask.clear_bit(ColorWriteAttrib::get_class_slot());
  2327. mask |= GL_COLOR_BUFFER_BIT;
  2328. }
  2329. }
  2330. }
  2331. if (clearable->get_clear_depth_active()) {
  2332. #ifdef OPENGLES
  2333. glClearDepthf(clearable->get_clear_depth());
  2334. #else
  2335. glClearDepth(clearable->get_clear_depth());
  2336. #endif // OPENGLES
  2337. #ifdef GSG_VERBOSE
  2338. GLCAT.spam()
  2339. << "glDepthMask(GL_TRUE)" << endl;
  2340. #endif
  2341. glDepthMask(GL_TRUE);
  2342. _state_mask.clear_bit(DepthWriteAttrib::get_class_slot());
  2343. mask |= GL_DEPTH_BUFFER_BIT;
  2344. }
  2345. if (clearable->get_clear_stencil_active()) {
  2346. glStencilMask(~0);
  2347. glClearStencil(clearable->get_clear_stencil());
  2348. mask |= GL_STENCIL_BUFFER_BIT;
  2349. }
  2350. glClear(mask);
  2351. if (GLCAT.is_spam()) {
  2352. GLCAT.spam() << "glClear(";
  2353. if (mask & GL_COLOR_BUFFER_BIT) {
  2354. GLCAT.spam(false) << "GL_COLOR_BUFFER_BIT|";
  2355. }
  2356. if (mask & GL_DEPTH_BUFFER_BIT) {
  2357. GLCAT.spam(false) << "GL_DEPTH_BUFFER_BIT|";
  2358. }
  2359. if (mask & GL_STENCIL_BUFFER_BIT) {
  2360. GLCAT.spam(false) << "GL_STENCIL_BUFFER_BIT|";
  2361. }
  2362. #ifndef OPENGLES
  2363. if (mask & GL_ACCUM_BUFFER_BIT) {
  2364. GLCAT.spam(false) << "GL_ACCUM_BUFFER_BIT|";
  2365. }
  2366. #endif
  2367. GLCAT.spam(false) << ")" << endl;
  2368. }
  2369. report_my_gl_errors();
  2370. }
  2371. ////////////////////////////////////////////////////////////////////
  2372. // Function: GLGraphicsStateGuardian::prepare_display_region
  2373. // Access: Public, Virtual
  2374. // Description: Prepare a display region for rendering (set up
  2375. // scissor region and viewport)
  2376. ////////////////////////////////////////////////////////////////////
  2377. void CLP(GraphicsStateGuardian)::
  2378. prepare_display_region(DisplayRegionPipelineReader *dr) {
  2379. nassertv(dr != (DisplayRegionPipelineReader *)NULL);
  2380. GraphicsStateGuardian::prepare_display_region(dr);
  2381. int l, b, w, h;
  2382. dr->get_region_pixels(l, b, w, h);
  2383. _viewport_x = l;
  2384. _viewport_y = b;
  2385. _viewport_width = w;
  2386. _viewport_height = h;
  2387. GLint x = GLint(l);
  2388. GLint y = GLint(b);
  2389. GLsizei width = GLsizei(w);
  2390. GLsizei height = GLsizei(h);
  2391. _draw_buffer_type = dr->get_object()->get_draw_buffer_type() & _current_properties->get_buffer_mask() & _stereo_buffer_mask;
  2392. _draw_buffer_type |= _current_properties->get_aux_mask();
  2393. set_draw_buffer(_draw_buffer_type);
  2394. int count = dr->get_num_regions();
  2395. if (dr->get_scissor_enabled()) {
  2396. if (GLCAT.is_spam()) {
  2397. GLCAT.spam()
  2398. << "glEnable(GL_SCISSOR_TEST)\n";
  2399. }
  2400. glEnable(GL_SCISSOR_TEST);
  2401. _scissor_enabled = true;
  2402. _scissor_array.resize(count);
  2403. } else {
  2404. if (GLCAT.is_spam()) {
  2405. GLCAT.spam()
  2406. << "glDisable(GL_SCISSOR_TEST)\n";
  2407. }
  2408. glDisable(GL_SCISSOR_TEST);
  2409. _scissor_enabled = false;
  2410. _scissor_array.clear();
  2411. }
  2412. _scissor_attrib_active = false;
  2413. #ifndef OPENGLES
  2414. if (_supports_viewport_arrays) {
  2415. GLfloat *viewports = (GLfloat *)alloca(sizeof(GLfloat) * 4 * count);
  2416. // We store the scissor regions in a vector since we may need
  2417. // to switch back to it in do_issue_scissor.
  2418. for (int i = 0; i < count; ++i) {
  2419. LVecBase4i sr;
  2420. dr->get_region_pixels(i, sr[0], sr[1], sr[2], sr[3]);
  2421. GLfloat *vr = viewports + i * 4;
  2422. vr[0] = (GLfloat) sr[0];
  2423. vr[1] = (GLfloat) sr[1];
  2424. vr[2] = (GLfloat) sr[2];
  2425. vr[3] = (GLfloat) sr[3];
  2426. if (_scissor_enabled) {
  2427. _scissor_array[i] = sr;
  2428. }
  2429. }
  2430. _glViewportArrayv(0, count, viewports);
  2431. if (_scissor_enabled) {
  2432. _glScissorArrayv(0, count, _scissor_array[0].get_data());
  2433. }
  2434. if (GLCAT.is_spam()) {
  2435. GLCAT.spam()
  2436. << "glViewportArrayv(0, " << count << ", [\n";
  2437. for (int i = 0; i < count; ++i) {
  2438. GLfloat *vr = viewports + i * 4;
  2439. GLCAT.spam(false) << vr[0] << ", " << vr[1] << ", " << vr[2] << ", " << vr[3] << ",\n";
  2440. }
  2441. GLCAT.spam(false) << "])\n";
  2442. if (_scissor_enabled) {
  2443. GLCAT.spam()
  2444. << "glScissorArrayv(0, " << count << ", [\n";
  2445. for (int i = 0; i < count; ++i) {
  2446. const LVecBase4i &sr = _scissor_array[i];
  2447. GLCAT.spam(false) << sr << ",\n";
  2448. }
  2449. }
  2450. GLCAT.spam(false) << "])\n";
  2451. }
  2452. } else
  2453. #endif // OPENGLES
  2454. {
  2455. glViewport(x, y, width, height);
  2456. if (_scissor_enabled) {
  2457. glScissor(x, y, width, height);
  2458. _scissor_array.resize(1);
  2459. _scissor_array[0].set(x, y, width, height);
  2460. }
  2461. if (GLCAT.is_spam()) {
  2462. GLCAT.spam()
  2463. << "glViewport(" << x << ", " << y << ", " << width << ", " << height << ")\n";
  2464. if (dr->get_scissor_enabled()) {
  2465. GLCAT.spam()
  2466. << "glScissor(" << x << ", " << y << ", " << width << ", " << height << ")\n";
  2467. }
  2468. }
  2469. }
  2470. report_my_gl_errors();
  2471. do_point_size();
  2472. }
  2473. ////////////////////////////////////////////////////////////////////
  2474. // Function: GLGraphicsStateGuardian::clear_before_callback
  2475. // Access: Public, Virtual
  2476. // Description: Resets any non-standard graphics state that might
  2477. // give a callback apoplexy. Some drivers require that
  2478. // the graphics state be restored to neutral before
  2479. // performing certain operations. In OpenGL, for
  2480. // instance, this closes any open vertex buffers.
  2481. ////////////////////////////////////////////////////////////////////
  2482. void CLP(GraphicsStateGuardian)::
  2483. clear_before_callback() {
  2484. #ifndef OPENGLES_2
  2485. disable_standard_vertex_arrays();
  2486. #endif
  2487. unbind_buffers();
  2488. // Some callbacks may quite reasonably assume that the active
  2489. // texture stage is still set to stage 0. CEGUI, in particular,
  2490. // makes this assumption.
  2491. _glActiveTexture(GL_TEXTURE0);
  2492. #ifndef OPENGLES_2
  2493. _glClientActiveTexture(GL_TEXTURE0);
  2494. #endif
  2495. // Clear the bound sampler object, so that we do not inadvertently
  2496. // override the callback's desired sampler settings.
  2497. #ifndef OPENGLES
  2498. if (_supports_sampler_objects) {
  2499. _glBindSampler(0, 0);
  2500. }
  2501. #endif
  2502. }
  2503. ////////////////////////////////////////////////////////////////////
  2504. // Function: GLGraphicsStateGuardian::calc_projection_mat
  2505. // Access: Public, Virtual
  2506. // Description: Given a lens, calculates the appropriate projection
  2507. // matrix for use with this gsg. Note that the
  2508. // projection matrix depends a lot upon the coordinate
  2509. // system of the rendering API.
  2510. //
  2511. // The return value is a TransformState if the lens is
  2512. // acceptable, NULL if it is not.
  2513. ////////////////////////////////////////////////////////////////////
  2514. CPT(TransformState) CLP(GraphicsStateGuardian)::
  2515. calc_projection_mat(const Lens *lens) {
  2516. if (lens == (Lens *)NULL) {
  2517. return NULL;
  2518. }
  2519. if (!lens->is_linear()) {
  2520. return NULL;
  2521. }
  2522. // The projection matrix must always be right-handed Y-up, even if
  2523. // our coordinate system of choice is otherwise, because certain GL
  2524. // calls (specifically glTexGen(GL_SPHERE_MAP)) assume this kind of
  2525. // a coordinate system. Sigh. In order to implement a Z-up (or
  2526. // other arbitrary) coordinate system, we'll use a Y-up projection
  2527. // matrix, and store the conversion to our coordinate system of
  2528. // choice in the modelview matrix.
  2529. LMatrix4 result =
  2530. LMatrix4::convert_mat(CS_yup_right, lens->get_coordinate_system()) *
  2531. lens->get_projection_mat(_current_stereo_channel);
  2532. if (_scene_setup->get_inverted()) {
  2533. // If the scene is supposed to be inverted, then invert the
  2534. // projection matrix.
  2535. result *= LMatrix4::scale_mat(1.0f, -1.0f, 1.0f);
  2536. }
  2537. return TransformState::make_mat(result);
  2538. }
  2539. ////////////////////////////////////////////////////////////////////
  2540. // Function: GLGraphicsStateGuardian::prepare_lens
  2541. // Access: Public, Virtual
  2542. // Description: Makes the current lens (whichever lens was most
  2543. // recently specified with set_scene()) active, so
  2544. // that it will transform future rendered geometry.
  2545. // Normally this is only called from the draw process,
  2546. // and usually it is called by set_scene().
  2547. //
  2548. // The return value is true if the lens is acceptable,
  2549. // false if it is not.
  2550. ////////////////////////////////////////////////////////////////////
  2551. bool CLP(GraphicsStateGuardian)::
  2552. prepare_lens() {
  2553. #ifndef OPENGLES_2
  2554. if (GLCAT.is_spam()) {
  2555. GLCAT.spam()
  2556. << "glMatrixMode(GL_PROJECTION): " << _projection_mat->get_mat() << endl;
  2557. }
  2558. glMatrixMode(GL_PROJECTION);
  2559. GLPf(LoadMatrix)(_projection_mat->get_mat().get_data());
  2560. report_my_gl_errors();
  2561. do_point_size();
  2562. #endif
  2563. return true;
  2564. }
  2565. ////////////////////////////////////////////////////////////////////
  2566. // Function: GraphicsStateGuardian::begin_frame
  2567. // Access: Public, Virtual
  2568. // Description: Called before each frame is rendered, to allow the
  2569. // GSG a chance to do any internal cleanup before
  2570. // beginning the frame.
  2571. //
  2572. // The return value is true if successful (in which case
  2573. // the frame will be drawn and end_frame() will be
  2574. // called later), or false if unsuccessful (in which
  2575. // case nothing will be drawn and end_frame() will not
  2576. // be called).
  2577. ////////////////////////////////////////////////////////////////////
  2578. bool CLP(GraphicsStateGuardian)::
  2579. begin_frame(Thread *current_thread) {
  2580. if (!GraphicsStateGuardian::begin_frame(current_thread)) {
  2581. return false;
  2582. }
  2583. report_my_gl_errors();
  2584. #ifdef DO_PSTATS
  2585. _vertices_display_list_pcollector.clear_level();
  2586. _vertices_immediate_pcollector.clear_level();
  2587. _primitive_batches_display_list_pcollector.clear_level();
  2588. #endif
  2589. #ifndef NDEBUG
  2590. _show_texture_usage = false;
  2591. if (gl_show_texture_usage) {
  2592. // When this is true, then every other second, we show the usage
  2593. // textures instead of the real textures.
  2594. double now = ClockObject::get_global_clock()->get_frame_time();
  2595. int this_second = (int)floor(now);
  2596. if (this_second & 1) {
  2597. _show_texture_usage = true;
  2598. _show_texture_usage_index = this_second >> 1;
  2599. int max_size = gl_show_texture_usage_max_size;
  2600. if (max_size != _show_texture_usage_max_size) {
  2601. // Remove the cache of usage textures; we've changed the max
  2602. // size.
  2603. UsageTextures::iterator ui;
  2604. for (ui = _usage_textures.begin();
  2605. ui != _usage_textures.end();
  2606. ++ui) {
  2607. GLuint index = (*ui).second;
  2608. glDeleteTextures(1, &index);
  2609. }
  2610. _usage_textures.clear();
  2611. _show_texture_usage_max_size = max_size;
  2612. }
  2613. }
  2614. }
  2615. #endif // NDEBUG
  2616. #ifdef DO_PSTATS
  2617. /*if (_supports_timer_query) {
  2618. // Measure the difference between the OpenGL clock and the
  2619. // PStats clock.
  2620. GLint64 time_ns;
  2621. _glGetInteger64v(GL_TIMESTAMP, &time_ns);
  2622. _timer_delta = time_ns * -0.000000001;
  2623. _timer_delta += PStatClient::get_global_pstats()->get_real_time();
  2624. }*/
  2625. #endif
  2626. #ifndef OPENGLES
  2627. if (_current_properties->get_srgb_color()) {
  2628. glEnable(GL_FRAMEBUFFER_SRGB);
  2629. }
  2630. #endif
  2631. report_my_gl_errors();
  2632. return true;
  2633. }
  2634. ////////////////////////////////////////////////////////////////////
  2635. // Function: GraphicsStateGuardian::begin_scene
  2636. // Access: Public, Virtual
  2637. // Description: Called between begin_frame() and end_frame() to mark
  2638. // the beginning of drawing commands for a "scene"
  2639. // (usually a particular DisplayRegion) within a frame.
  2640. // All 3-D drawing commands, except the clear operation,
  2641. // must be enclosed within begin_scene() .. end_scene().
  2642. //
  2643. // The return value is true if successful (in which case
  2644. // the scene will be drawn and end_scene() will be
  2645. // called later), or false if unsuccessful (in which
  2646. // case nothing will be drawn and end_scene() will not
  2647. // be called).
  2648. ////////////////////////////////////////////////////////////////////
  2649. bool CLP(GraphicsStateGuardian)::
  2650. begin_scene() {
  2651. return GraphicsStateGuardian::begin_scene();
  2652. }
  2653. ////////////////////////////////////////////////////////////////////
  2654. // Function: GLGraphicsStateGuardian::end_scene
  2655. // Access: Protected, Virtual
  2656. // Description: Called between begin_frame() and end_frame() to mark
  2657. // the end of drawing commands for a "scene" (usually a
  2658. // particular DisplayRegion) within a frame. All 3-D
  2659. // drawing commands, except the clear operation, must be
  2660. // enclosed within begin_scene() .. end_scene().
  2661. ////////////////////////////////////////////////////////////////////
  2662. void CLP(GraphicsStateGuardian)::
  2663. end_scene() {
  2664. GraphicsStateGuardian::end_scene();
  2665. _dlights.clear();
  2666. report_my_gl_errors();
  2667. }
  2668. ////////////////////////////////////////////////////////////////////
  2669. // Function: GLGraphicsStateGuardian::end_frame
  2670. // Access: Public, Virtual
  2671. // Description: Called after each frame is rendered, to allow the
  2672. // GSG a chance to do any internal cleanup after
  2673. // rendering the frame, and before the window flips.
  2674. ////////////////////////////////////////////////////////////////////
  2675. void CLP(GraphicsStateGuardian)::
  2676. end_frame(Thread *current_thread) {
  2677. report_my_gl_errors();
  2678. #ifndef OPENGLES
  2679. if (_current_properties->get_srgb_color()) {
  2680. glDisable(GL_FRAMEBUFFER_SRGB);
  2681. }
  2682. #endif
  2683. #ifdef DO_PSTATS
  2684. // Check for textures, etc., that are no longer resident. These
  2685. // calls might be measurably expensive, and they don't have any
  2686. // benefit unless we are actually viewing PStats, so don't do them
  2687. // unless we're connected. That will just mean that we'll count
  2688. // everything as resident until the user connects PStats, at which
  2689. // point it will then correct the assessment. No harm done.
  2690. if (PStatClient::is_connected()) {
  2691. check_nonresident_texture(_prepared_objects->_texture_residency.get_inactive_resident());
  2692. check_nonresident_texture(_prepared_objects->_texture_residency.get_active_resident());
  2693. // OpenGL provides no methods for querying whether a buffer object
  2694. // (vertex buffer) is resident. In fact, the API appears geared
  2695. // towards the assumption that such buffers are always resident.
  2696. // OK.
  2697. }
  2698. #endif
  2699. #ifndef OPENGLES_1
  2700. // This breaks shaders across multiple regions.
  2701. if (_vertex_array_shader_context != 0) {
  2702. _vertex_array_shader_context->disable_shader_vertex_arrays();
  2703. _vertex_array_shader = (Shader *)NULL;
  2704. _vertex_array_shader_context = (ShaderContext *)NULL;
  2705. }
  2706. if (_texture_binding_shader_context != 0) {
  2707. _texture_binding_shader_context->disable_shader_texture_bindings();
  2708. _texture_binding_shader = (Shader *)NULL;
  2709. _texture_binding_shader_context = (ShaderContext *)NULL;
  2710. }
  2711. if (_current_shader_context != 0) {
  2712. _current_shader_context->unbind();
  2713. _current_shader = (Shader *)NULL;
  2714. _current_shader_context = (ShaderContext *)NULL;
  2715. }
  2716. #endif
  2717. // Calling glFlush() at the end of the frame is particularly
  2718. // necessary if this is a single-buffered visual, so that the frame
  2719. // will be finished drawing before we return to the application.
  2720. // It's not clear what effect this has on our total frame time.
  2721. //if (_force_flush || _current_properties->is_single_buffered()) {
  2722. // gl_flush();
  2723. //}
  2724. maybe_gl_finish();
  2725. GraphicsStateGuardian::end_frame(current_thread);
  2726. // Flush any PCollectors specific to this kind of GSG.
  2727. _primitive_batches_display_list_pcollector.flush_level();
  2728. _vertices_display_list_pcollector.flush_level();
  2729. _vertices_immediate_pcollector.flush_level();
  2730. // Now is a good time to delete any pending display lists.
  2731. #ifndef OPENGLES
  2732. if (display_lists) {
  2733. LightMutexHolder holder(_lock);
  2734. if (!_deleted_display_lists.empty()) {
  2735. DeletedNames::iterator ddli;
  2736. for (ddli = _deleted_display_lists.begin();
  2737. ddli != _deleted_display_lists.end();
  2738. ++ddli) {
  2739. if (GLCAT.is_debug()) {
  2740. GLCAT.debug()
  2741. << "releasing display list index " << (int)(*ddli) << "\n";
  2742. }
  2743. glDeleteLists((*ddli), 1);
  2744. }
  2745. _deleted_display_lists.clear();
  2746. }
  2747. }
  2748. // And deleted queries, too, unless we're using query timers
  2749. // in which case we'll need to reuse lots of them.
  2750. if (_supports_occlusion_query && !get_timer_queries_active()) {
  2751. LightMutexHolder holder(_lock);
  2752. if (!_deleted_queries.empty()) {
  2753. if (GLCAT.is_spam()) {
  2754. DeletedNames::iterator dqi;
  2755. for (dqi = _deleted_queries.begin();
  2756. dqi != _deleted_queries.end();
  2757. ++dqi) {
  2758. GLCAT.spam()
  2759. << "releasing query index " << (int)(*dqi) << "\n";
  2760. }
  2761. }
  2762. _glDeleteQueries(_deleted_queries.size(), &_deleted_queries[0]);
  2763. _deleted_queries.clear();
  2764. }
  2765. }
  2766. #endif // OPENGLES
  2767. #ifndef NDEBUG
  2768. if (_check_errors || (_supports_debug && gl_debug)) {
  2769. report_my_gl_errors();
  2770. } else {
  2771. static int frame_counter = -1;
  2772. // If _check_errors is false, we still want to check for errors
  2773. // the first few frames and once every N frames, so that we know if
  2774. // anything went wrong at all.
  2775. if (frame_counter++ <= 0) {
  2776. PStatTimer timer(_check_error_pcollector);
  2777. GLenum error_code = glGetError();
  2778. if (error_code != GL_NO_ERROR) {
  2779. int error_count = 0;
  2780. bool deactivate = !report_errors_loop(__LINE__, __FILE__, error_code, error_count);
  2781. if (error_count == 1) {
  2782. GLCAT.error()
  2783. << "An OpenGL error (" << get_error_string(error_code)
  2784. << ") has occurred.";
  2785. } else {
  2786. GLCAT.error()
  2787. << error_count << " OpenGL errors have occurred.";
  2788. }
  2789. if (_supports_debug) {
  2790. GLCAT.error(false) << " Set gl-debug #t "
  2791. << "in your PRC file to display more information.\n";
  2792. } else {
  2793. GLCAT.error(false) << " Set gl-check-errors #t "
  2794. << "in your PRC file to display more information.\n";
  2795. }
  2796. if (deactivate) {
  2797. panic_deactivate();
  2798. }
  2799. }
  2800. } else if (frame_counter > 100) {
  2801. // 100 frames have passed. Check next frame.
  2802. frame_counter = 0;
  2803. }
  2804. }
  2805. #endif
  2806. }
  2807. ////////////////////////////////////////////////////////////////////
  2808. // Function: GLGraphicsStateGuardian::begin_draw_primitives
  2809. // Access: Public, Virtual
  2810. // Description: Called before a sequence of draw_primitive()
  2811. // functions are called, this should prepare the vertex
  2812. // data for rendering. It returns true if the vertices
  2813. // are ok, false to abort this group of primitives.
  2814. ////////////////////////////////////////////////////////////////////
  2815. bool CLP(GraphicsStateGuardian)::
  2816. begin_draw_primitives(const GeomPipelineReader *geom_reader,
  2817. const GeomMunger *munger,
  2818. const GeomVertexDataPipelineReader *data_reader,
  2819. bool force) {
  2820. #ifndef NDEBUG
  2821. if (GLCAT.is_spam()) {
  2822. GLCAT.spam() << "begin_draw_primitives: " << *(data_reader->get_object()) << "\n";
  2823. }
  2824. #endif // NDEBUG
  2825. #ifdef OPENGLES_2
  2826. // We can't draw without a shader bound in OpenGL ES 2. This shouldn't
  2827. // happen anyway unless the default shader failed to compile somehow.
  2828. if (_current_shader_context == NULL) {
  2829. return false;
  2830. }
  2831. #endif
  2832. if (!GraphicsStateGuardian::begin_draw_primitives(geom_reader, munger, data_reader, force)) {
  2833. return false;
  2834. }
  2835. nassertr(_data_reader != (GeomVertexDataPipelineReader *)NULL, false);
  2836. _geom_display_list = 0;
  2837. if (_auto_antialias_mode) {
  2838. switch (geom_reader->get_primitive_type()) {
  2839. case GeomPrimitive::PT_polygons:
  2840. case GeomPrimitive::PT_patches:
  2841. setup_antialias_polygon();
  2842. break;
  2843. case GeomPrimitive::PT_points:
  2844. setup_antialias_point();
  2845. break;
  2846. case GeomPrimitive::PT_lines:
  2847. setup_antialias_line();
  2848. break;
  2849. case GeomPrimitive::PT_none:
  2850. break;
  2851. }
  2852. int transparency_slot = TransparencyAttrib::get_class_slot();
  2853. int color_write_slot = ColorWriteAttrib::get_class_slot();
  2854. int color_blend_slot = ColorBlendAttrib::get_class_slot();
  2855. if (!_state_mask.get_bit(transparency_slot) ||
  2856. !_state_mask.get_bit(color_write_slot) ||
  2857. !_state_mask.get_bit(color_blend_slot)) {
  2858. do_issue_blending();
  2859. _state_mask.set_bit(transparency_slot);
  2860. _state_mask.set_bit(color_write_slot);
  2861. _state_mask.set_bit(color_blend_slot);
  2862. }
  2863. }
  2864. const GeomVertexAnimationSpec &animation =
  2865. _data_reader->get_format()->get_animation();
  2866. bool hardware_animation = (animation.get_animation_type() == Geom::AT_hardware);
  2867. #ifndef OPENGLES
  2868. if (hardware_animation) {
  2869. // Set up the transform matrices for vertex blending.
  2870. nassertr(_supports_vertex_blend, false);
  2871. glEnable(GL_VERTEX_BLEND_ARB);
  2872. _glVertexBlend(animation.get_num_transforms());
  2873. const TransformTable *table = _data_reader->get_transform_table();
  2874. if (table != (TransformTable *)NULL) {
  2875. if (animation.get_indexed_transforms()) {
  2876. nassertr(_supports_matrix_palette, false);
  2877. // We are loading the indexed matrix palette. The ARB decided
  2878. // to change this interface from that for the list of
  2879. // nonindexed matrices, to make it easier to load an arbitrary
  2880. // number of matrices.
  2881. glEnable(GL_MATRIX_PALETTE_ARB);
  2882. glMatrixMode(GL_MATRIX_PALETTE_ARB);
  2883. for (int i = 0; i < table->get_num_transforms(); ++i) {
  2884. LMatrix4 mat;
  2885. table->get_transform(i)->mult_matrix(mat, _internal_transform->get_mat());
  2886. _glCurrentPaletteMatrix(i);
  2887. GLPf(LoadMatrix)(mat.get_data());
  2888. }
  2889. // Presumably loading the matrix palette does not step on the
  2890. // GL_MODELVIEW matrix?
  2891. } else {
  2892. // We are loading the list of nonindexed matrices. This is a
  2893. // little clumsier.
  2894. if (_supports_matrix_palette) {
  2895. glDisable(GL_MATRIX_PALETTE_ARB);
  2896. }
  2897. // GL_MODELVIEW0 and 1 are different than the rest.
  2898. int i = 0;
  2899. if (i < table->get_num_transforms()) {
  2900. LMatrix4 mat;
  2901. table->get_transform(i)->mult_matrix(mat, _internal_transform->get_mat());
  2902. glMatrixMode(GL_MODELVIEW0_ARB);
  2903. GLPf(LoadMatrix)(mat.get_data());
  2904. ++i;
  2905. }
  2906. if (i < table->get_num_transforms()) {
  2907. LMatrix4 mat;
  2908. table->get_transform(i)->mult_matrix(mat, _internal_transform->get_mat());
  2909. glMatrixMode(GL_MODELVIEW1_ARB);
  2910. GLPf(LoadMatrix)(mat.get_data());
  2911. ++i;
  2912. }
  2913. while (i < table->get_num_transforms()) {
  2914. LMatrix4 mat;
  2915. table->get_transform(i)->mult_matrix(mat, _internal_transform->get_mat());
  2916. glMatrixMode(GL_MODELVIEW2_ARB + i - 2);
  2917. GLPf(LoadMatrix)(mat.get_data());
  2918. ++i;
  2919. }
  2920. // Setting the GL_MODELVIEW0 matrix steps on the world matrix,
  2921. // so we have to set a flag to reload the world matrix later.
  2922. _transform_stale = true;
  2923. }
  2924. }
  2925. _vertex_blending_enabled = true;
  2926. } else {
  2927. // We're not using vertex blending.
  2928. if (_vertex_blending_enabled) {
  2929. glDisable(GL_VERTEX_BLEND_ARB);
  2930. if (_supports_matrix_palette) {
  2931. glDisable(GL_MATRIX_PALETTE_ARB);
  2932. }
  2933. _vertex_blending_enabled = false;
  2934. }
  2935. if (_transform_stale) {
  2936. glMatrixMode(GL_MODELVIEW);
  2937. GLPf(LoadMatrix)(_internal_transform->get_mat().get_data());
  2938. }
  2939. }
  2940. #endif
  2941. #ifndef OPENGLES_2
  2942. if (_data_reader->is_vertex_transformed()) {
  2943. // If the vertex data claims to be already transformed into clip
  2944. // coordinates, wipe out the current projection and modelview
  2945. // matrix (so we don't attempt to transform it again).
  2946. glMatrixMode(GL_PROJECTION);
  2947. glPushMatrix();
  2948. glLoadIdentity();
  2949. glMatrixMode(GL_MODELVIEW);
  2950. glPushMatrix();
  2951. glLoadIdentity();
  2952. }
  2953. #endif
  2954. #ifndef OPENGLES // Display lists not supported by OpenGL ES.
  2955. if (geom_reader->get_usage_hint() == Geom::UH_static &&
  2956. _data_reader->get_usage_hint() == Geom::UH_static &&
  2957. display_lists && (!hardware_animation || display_list_animation)) {
  2958. // If the geom claims to be totally static, try to build it into
  2959. // a display list.
  2960. // Before we compile or call a display list, make sure the current
  2961. // buffers are unbound, or the nVidia drivers may crash.
  2962. unbind_buffers();
  2963. GeomContext *gc = geom_reader->prepare_now(get_prepared_objects(), this);
  2964. nassertr(gc != (GeomContext *)NULL, false);
  2965. CLP(GeomContext) *ggc = DCAST(CLP(GeomContext), gc);
  2966. const CLP(GeomMunger) *gmunger = DCAST(CLP(GeomMunger), _munger);
  2967. UpdateSeq modified = max(geom_reader->get_modified(), _data_reader->get_modified());
  2968. if (ggc->get_display_list(_geom_display_list, gmunger, modified)) {
  2969. // If it hasn't been modified, just play the display list again.
  2970. if (GLCAT.is_spam()) {
  2971. GLCAT.spam()
  2972. << "calling display list " << (int)_geom_display_list << "\n";
  2973. }
  2974. glCallList(_geom_display_list);
  2975. #ifdef DO_PSTATS
  2976. _vertices_display_list_pcollector.add_level(ggc->_num_verts);
  2977. _primitive_batches_display_list_pcollector.add_level(1);
  2978. #endif
  2979. // And now we don't need to do anything else for this geom.
  2980. _geom_display_list = 0;
  2981. end_draw_primitives();
  2982. return false;
  2983. }
  2984. // Since we start this collector explicitly, we have to be sure to
  2985. // stop it again.
  2986. _load_display_list_pcollector.start();
  2987. if (GLCAT.is_debug()) {
  2988. GLCAT.debug()
  2989. << "compiling display list " << (int)_geom_display_list << "\n";
  2990. }
  2991. // If it has been modified, or this is the first time, then we
  2992. // need to build the display list up.
  2993. if (gl_compile_and_execute) {
  2994. glNewList(_geom_display_list, GL_COMPILE_AND_EXECUTE);
  2995. } else {
  2996. glNewList(_geom_display_list, GL_COMPILE);
  2997. }
  2998. #ifdef DO_PSTATS
  2999. // Count up the number of vertices used by primitives in the Geom,
  3000. // for PStats reporting.
  3001. ggc->_num_verts = 0;
  3002. for (int i = 0; i < geom_reader->get_num_primitives(); i++) {
  3003. ggc->_num_verts += geom_reader->get_primitive(i)->get_num_vertices();
  3004. }
  3005. #endif
  3006. }
  3007. #endif // OPENGLES
  3008. // Enable the appropriate vertex arrays, and disable any
  3009. // extra vertex arrays used by the previous rendering mode.
  3010. #ifdef SUPPORT_IMMEDIATE_MODE
  3011. _use_sender = !vertex_arrays;
  3012. #endif
  3013. {
  3014. //PStatGPUTimer timer(this, _vertex_array_update_pcollector);
  3015. #ifdef OPENGLES_1
  3016. if (!update_standard_vertex_arrays(force)) {
  3017. return false;
  3018. }
  3019. #else
  3020. if (_current_shader_context == 0) {
  3021. // No shader.
  3022. if (_vertex_array_shader_context != 0) {
  3023. _vertex_array_shader_context->disable_shader_vertex_arrays();
  3024. }
  3025. #ifndef OPENGLES_2
  3026. if (!update_standard_vertex_arrays(force)) {
  3027. return false;
  3028. }
  3029. #endif
  3030. } else {
  3031. #ifndef OPENGLES_2
  3032. // Shader.
  3033. if (_vertex_array_shader_context == 0 || _vertex_array_shader_context->uses_standard_vertex_arrays()) {
  3034. // Previous shader used standard arrays.
  3035. if (_current_shader_context->uses_standard_vertex_arrays()) {
  3036. // So does the current, so update them.
  3037. if (!update_standard_vertex_arrays(force)) {
  3038. return false;
  3039. }
  3040. } else {
  3041. // The current shader does not, so disable them entirely.
  3042. disable_standard_vertex_arrays();
  3043. }
  3044. }
  3045. #endif // !OPENGLES_2
  3046. if (_current_shader_context->uses_custom_vertex_arrays()) {
  3047. // The current shader also uses custom vertex arrays.
  3048. if (!_current_shader_context->
  3049. update_shader_vertex_arrays(_vertex_array_shader_context, force)) {
  3050. return false;
  3051. }
  3052. } else {
  3053. _vertex_array_shader_context->disable_shader_vertex_arrays();
  3054. }
  3055. }
  3056. _vertex_array_shader = _current_shader;
  3057. _vertex_array_shader_context = _current_shader_context;
  3058. #endif // OPENGLES_1
  3059. }
  3060. report_my_gl_errors();
  3061. return true;
  3062. }
  3063. #ifndef OPENGLES_2
  3064. ////////////////////////////////////////////////////////////////////
  3065. // Function: GLGraphicsStateGuardian::update_standard_vertex_arrays
  3066. // Access: Protected
  3067. // Description: Disables any unneeded vertex arrays that
  3068. // were previously enabled, and enables any vertex
  3069. // arrays that are needed that were not previously
  3070. // enabled (or, sets up an immediate-mode sender).
  3071. // Called only from begin_draw_primitives.
  3072. // Used only when the standard (non-shader) pipeline
  3073. // is about to be used - glShaderContexts are responsible
  3074. // for setting up their own vertex arrays.
  3075. ////////////////////////////////////////////////////////////////////
  3076. bool CLP(GraphicsStateGuardian)::
  3077. update_standard_vertex_arrays(bool force) {
  3078. const GeomVertexAnimationSpec &animation =
  3079. _data_reader->get_format()->get_animation();
  3080. bool hardware_animation = (animation.get_animation_type() == Geom::AT_hardware);
  3081. #ifdef SUPPORT_IMMEDIATE_MODE
  3082. if (_use_sender) {
  3083. // We must use immediate mode to render primitives.
  3084. _sender.clear();
  3085. _sender.add_column(_data_reader, InternalName::get_normal(),
  3086. NULL, NULL, GLPf(Normal3), NULL);
  3087. #ifndef NDEBUG
  3088. if (_show_texture_usage) {
  3089. // In show_texture_usage mode, all colors are white, so as not
  3090. // to contaminate the texture color.
  3091. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  3092. } else
  3093. #endif // NDEBUG
  3094. if (!_sender.add_column(_data_reader, InternalName::get_color(),
  3095. NULL, NULL, GLPf(Color3), GLPf(Color4))) {
  3096. // If we didn't have a color column, the item color is white.
  3097. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  3098. }
  3099. // Now set up each of the active texture coordinate stages--or at
  3100. // least those for which we're not generating texture coordinates
  3101. // automatically.
  3102. int max_stage_index = _target_texture->get_num_on_ff_stages();
  3103. int stage_index = 0;
  3104. while (stage_index < max_stage_index) {
  3105. TextureStage *stage = _target_texture->get_on_ff_stage(stage_index);
  3106. if (!_target_tex_gen->has_gen_texcoord_stage(stage)) {
  3107. // This stage is not one of the stages that doesn't need
  3108. // texcoords issued for it.
  3109. const InternalName *name = stage->get_texcoord_name();
  3110. if (stage_index == 0) {
  3111. // Use the original functions for stage 0, in case we don't
  3112. // support multitexture.
  3113. _sender.add_column(_data_reader, name,
  3114. GLPf(TexCoord1), GLPf(TexCoord2),
  3115. GLPf(TexCoord3), GLPf(TexCoord4));
  3116. } else {
  3117. // Other stages require the multitexture functions.
  3118. _sender.add_texcoord_column(_data_reader, name, stage_index,
  3119. GLf(_glMultiTexCoord1), GLf(_glMultiTexCoord2),
  3120. GLf(_glMultiTexCoord3), GLf(_glMultiTexCoord4));
  3121. }
  3122. }
  3123. ++stage_index;
  3124. }
  3125. // Be sure also to disable any texture stages we had enabled before.
  3126. while (stage_index < _last_max_stage_index) {
  3127. _glClientActiveTexture(GL_TEXTURE0 + stage_index);
  3128. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  3129. ++stage_index;
  3130. }
  3131. _last_max_stage_index = max_stage_index;
  3132. if (_supports_vertex_blend) {
  3133. if (hardware_animation) {
  3134. // Issue the weights and/or transform indices for vertex blending.
  3135. _sender.add_vector_column(_data_reader, InternalName::get_transform_weight(),
  3136. GLfv(_glWeight));
  3137. if (animation.get_indexed_transforms()) {
  3138. // Issue the matrix palette indices.
  3139. _sender.add_vector_uint_column(_data_reader, InternalName::get_transform_index(),
  3140. _glMatrixIndexuiv);
  3141. }
  3142. }
  3143. }
  3144. // We must add vertex last, because glVertex3f() is the key
  3145. // function call that actually issues the vertex.
  3146. _sender.add_column(_data_reader, InternalName::get_vertex(),
  3147. NULL, GLPf(Vertex2), GLPf(Vertex3), GLPf(Vertex4));
  3148. } else
  3149. #endif // SUPPORT_IMMEDIATE_MODE
  3150. {
  3151. // We may use vertex arrays or buffers to render primitives.
  3152. const GeomVertexArrayDataHandle *array_reader;
  3153. const unsigned char *client_pointer;
  3154. int num_values;
  3155. Geom::NumericType numeric_type;
  3156. int start;
  3157. int stride;
  3158. if (_data_reader->get_normal_info(array_reader, numeric_type,
  3159. start, stride)) {
  3160. if (!setup_array_data(client_pointer, array_reader, force)) {
  3161. return false;
  3162. }
  3163. glNormalPointer(get_numeric_type(numeric_type), stride,
  3164. client_pointer + start);
  3165. glEnableClientState(GL_NORMAL_ARRAY);
  3166. } else {
  3167. glDisableClientState(GL_NORMAL_ARRAY);
  3168. }
  3169. #ifndef NDEBUG
  3170. if (_show_texture_usage) {
  3171. // In show_texture_usage mode, all colors are white, so as not
  3172. // to contaminate the texture color.
  3173. glDisableClientState(GL_COLOR_ARRAY);
  3174. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  3175. } else
  3176. #endif // NDEBUG
  3177. if (_data_reader->get_color_info(array_reader, num_values, numeric_type,
  3178. start, stride)) {
  3179. if (!setup_array_data(client_pointer, array_reader, force)) {
  3180. return false;
  3181. }
  3182. if (numeric_type == Geom::NT_packed_dabc) {
  3183. glColorPointer(GL_BGRA, GL_UNSIGNED_BYTE,
  3184. stride, client_pointer + start);
  3185. } else {
  3186. glColorPointer(num_values, get_numeric_type(numeric_type),
  3187. stride, client_pointer + start);
  3188. }
  3189. glEnableClientState(GL_COLOR_ARRAY);
  3190. } else {
  3191. glDisableClientState(GL_COLOR_ARRAY);
  3192. // Since we don't have per-vertex color, the implicit color is
  3193. // white.
  3194. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  3195. }
  3196. // Now set up each of the active texture coordinate stages--or at
  3197. // least those for which we're not generating texture coordinates
  3198. // automatically.
  3199. int max_stage_index = _target_texture->get_num_on_ff_stages();
  3200. int stage_index = 0;
  3201. while (stage_index < max_stage_index) {
  3202. _glClientActiveTexture(GL_TEXTURE0 + stage_index);
  3203. TextureStage *stage = _target_texture->get_on_ff_stage(stage_index);
  3204. if (!_target_tex_gen->has_gen_texcoord_stage(stage)) {
  3205. // This stage is not one of the stages that doesn't need
  3206. // texcoords issued for it.
  3207. const InternalName *name = stage->get_texcoord_name();
  3208. if (_data_reader->get_array_info(name, array_reader, num_values,
  3209. numeric_type, start, stride)) {
  3210. // The vertex data does have texcoords for this stage.
  3211. if (!setup_array_data(client_pointer, array_reader, force)) {
  3212. return false;
  3213. }
  3214. glTexCoordPointer(num_values, get_numeric_type(numeric_type),
  3215. stride, client_pointer + start);
  3216. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  3217. } else {
  3218. // The vertex data doesn't have texcoords for this stage (even
  3219. // though they're needed).
  3220. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  3221. }
  3222. } else {
  3223. // No texcoords are needed for this stage.
  3224. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  3225. }
  3226. ++stage_index;
  3227. }
  3228. // Be sure also to disable any texture stages we had enabled before.
  3229. while (stage_index < _last_max_stage_index) {
  3230. _glClientActiveTexture(GL_TEXTURE0 + stage_index);
  3231. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  3232. ++stage_index;
  3233. }
  3234. _last_max_stage_index = max_stage_index;
  3235. #ifndef OPENGLES
  3236. if (_supports_vertex_blend) {
  3237. if (hardware_animation) {
  3238. // Issue the weights and/or transform indices for vertex blending.
  3239. if (_data_reader->get_array_info(InternalName::get_transform_weight(),
  3240. array_reader, num_values, numeric_type,
  3241. start, stride)) {
  3242. if (!setup_array_data(client_pointer, array_reader, force)) {
  3243. return false;
  3244. }
  3245. _glWeightPointer(num_values, get_numeric_type(numeric_type),
  3246. stride, client_pointer + start);
  3247. glEnableClientState(GL_WEIGHT_ARRAY_ARB);
  3248. } else {
  3249. glDisableClientState(GL_WEIGHT_ARRAY_ARB);
  3250. }
  3251. if (animation.get_indexed_transforms()) {
  3252. // Issue the matrix palette indices.
  3253. if (_data_reader->get_array_info(InternalName::get_transform_index(),
  3254. array_reader, num_values, numeric_type,
  3255. start, stride)) {
  3256. if (!setup_array_data(client_pointer, array_reader, force)) {
  3257. return false;
  3258. }
  3259. _glMatrixIndexPointer(num_values, get_numeric_type(numeric_type),
  3260. stride, client_pointer + start);
  3261. glEnableClientState(GL_MATRIX_INDEX_ARRAY_ARB);
  3262. } else {
  3263. glDisableClientState(GL_MATRIX_INDEX_ARRAY_ARB);
  3264. }
  3265. }
  3266. } else {
  3267. glDisableClientState(GL_WEIGHT_ARRAY_ARB);
  3268. if (_supports_matrix_palette) {
  3269. glDisableClientState(GL_MATRIX_INDEX_ARRAY_ARB);
  3270. }
  3271. }
  3272. }
  3273. #endif
  3274. // There's no requirement that we add vertices last, but we do
  3275. // anyway.
  3276. if (_data_reader->get_vertex_info(array_reader, num_values, numeric_type,
  3277. start, stride)) {
  3278. if (!setup_array_data(client_pointer, array_reader, force)) {
  3279. return false;
  3280. }
  3281. glVertexPointer(num_values, get_numeric_type(numeric_type),
  3282. stride, client_pointer + start);
  3283. glEnableClientState(GL_VERTEX_ARRAY);
  3284. }
  3285. }
  3286. return true;
  3287. }
  3288. #endif // !OPENGLES_2
  3289. ////////////////////////////////////////////////////////////////////
  3290. // Function: GLGraphicsStateGuardian::unbind_buffers
  3291. // Access: Protected
  3292. // Description: Ensures the vertex and array buffers are no longer
  3293. // bound. Some graphics drivers crash if these are left
  3294. // bound indiscriminantly.
  3295. ////////////////////////////////////////////////////////////////////
  3296. void CLP(GraphicsStateGuardian)::
  3297. unbind_buffers() {
  3298. if (_current_vbuffer_index != 0) {
  3299. if (GLCAT.is_spam() && gl_debug_buffers) {
  3300. GLCAT.spam()
  3301. << "unbinding vertex buffer\n";
  3302. }
  3303. _glBindBuffer(GL_ARRAY_BUFFER, 0);
  3304. _current_vbuffer_index = 0;
  3305. }
  3306. if (_current_ibuffer_index != 0) {
  3307. if (GLCAT.is_spam() && gl_debug_buffers) {
  3308. GLCAT.spam()
  3309. << "unbinding index buffer\n";
  3310. }
  3311. _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  3312. _current_ibuffer_index = 0;
  3313. }
  3314. #ifndef OPENGLES_2
  3315. disable_standard_vertex_arrays();
  3316. #endif
  3317. }
  3318. #ifndef OPENGLES_2
  3319. ////////////////////////////////////////////////////////////////////
  3320. // Function: GLGraphicsStateGuardian::disable_standard_vertex_arrays
  3321. // Access: Protected
  3322. // Description: Used to disable all the standard vertex arrays that
  3323. // are currently enabled. glShaderContexts are
  3324. // responsible for setting up their own vertex arrays,
  3325. // but before they can do so, the standard vertex
  3326. // arrays need to be disabled to get them "out of the
  3327. // way." Called only from begin_draw_primitives.
  3328. ////////////////////////////////////////////////////////////////////
  3329. void CLP(GraphicsStateGuardian)::
  3330. disable_standard_vertex_arrays() {
  3331. #ifdef SUPPORT_IMMEDIATE_MODE
  3332. if (_use_sender) return;
  3333. #endif
  3334. glDisableClientState(GL_NORMAL_ARRAY);
  3335. glDisableClientState(GL_COLOR_ARRAY);
  3336. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  3337. for (int stage_index=0; stage_index < _last_max_stage_index; stage_index++) {
  3338. _glClientActiveTexture(GL_TEXTURE0 + stage_index);
  3339. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  3340. }
  3341. _last_max_stage_index = 0;
  3342. #ifndef OPENGLES
  3343. if (_supports_vertex_blend) {
  3344. glDisableClientState(GL_WEIGHT_ARRAY_ARB);
  3345. if (_supports_matrix_palette) {
  3346. glDisableClientState(GL_MATRIX_INDEX_ARRAY_ARB);
  3347. }
  3348. }
  3349. #endif
  3350. glDisableClientState(GL_VERTEX_ARRAY);
  3351. report_my_gl_errors();
  3352. }
  3353. #endif // !OPENGLES_2
  3354. ////////////////////////////////////////////////////////////////////
  3355. // Function: GLGraphicsStateGuardian::draw_triangles
  3356. // Access: Public, Virtual
  3357. // Description: Draws a series of disconnected triangles.
  3358. ////////////////////////////////////////////////////////////////////
  3359. bool CLP(GraphicsStateGuardian)::
  3360. draw_triangles(const GeomPrimitivePipelineReader *reader, bool force) {
  3361. PStatGPUTimer timer(this, _draw_primitive_pcollector, reader->get_current_thread());
  3362. #ifndef NDEBUG
  3363. if (GLCAT.is_spam()) {
  3364. GLCAT.spam() << "draw_triangles: " << *(reader->get_object()) << "\n";
  3365. }
  3366. #endif // NDEBUG
  3367. #ifdef SUPPORT_IMMEDIATE_MODE
  3368. if (_use_sender) {
  3369. draw_immediate_simple_primitives(reader, GL_TRIANGLES);
  3370. } else
  3371. #endif // SUPPORT_IMMEDIATE_MODE
  3372. {
  3373. int num_vertices = reader->get_num_vertices();
  3374. _vertices_tri_pcollector.add_level(num_vertices);
  3375. _primitive_batches_tri_pcollector.add_level(1);
  3376. if (reader->is_indexed()) {
  3377. const unsigned char *client_pointer;
  3378. if (!setup_primitive(client_pointer, reader, force)) {
  3379. return false;
  3380. }
  3381. #ifndef OPENGLES_1
  3382. if (_supports_geometry_instancing && _instance_count > 0) {
  3383. _glDrawElementsInstanced(GL_TRIANGLES, num_vertices,
  3384. get_numeric_type(reader->get_index_type()),
  3385. client_pointer, _instance_count);
  3386. } else
  3387. #endif
  3388. {
  3389. _glDrawRangeElements(GL_TRIANGLES,
  3390. reader->get_min_vertex(),
  3391. reader->get_max_vertex(),
  3392. num_vertices,
  3393. get_numeric_type(reader->get_index_type()),
  3394. client_pointer);
  3395. }
  3396. } else {
  3397. #ifndef OPENGLES_1
  3398. if (_supports_geometry_instancing && _instance_count > 0) {
  3399. _glDrawArraysInstanced(GL_TRIANGLES,
  3400. reader->get_first_vertex(),
  3401. num_vertices, _instance_count);
  3402. } else
  3403. #endif
  3404. {
  3405. glDrawArrays(GL_TRIANGLES,
  3406. reader->get_first_vertex(),
  3407. num_vertices);
  3408. }
  3409. }
  3410. }
  3411. report_my_gl_errors();
  3412. return true;
  3413. }
  3414. ////////////////////////////////////////////////////////////////////
  3415. // Function: GLGraphicsStateGuardian::draw_tristrips
  3416. // Access: Public, Virtual
  3417. // Description: Draws a series of triangle strips.
  3418. ////////////////////////////////////////////////////////////////////
  3419. bool CLP(GraphicsStateGuardian)::
  3420. draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force) {
  3421. PStatGPUTimer timer(this, _draw_primitive_pcollector, reader->get_current_thread());
  3422. report_my_gl_errors();
  3423. #ifndef NDEBUG
  3424. if (GLCAT.is_spam()) {
  3425. GLCAT.spam() << "draw_tristrips: " << *(reader->get_object()) << "\n";
  3426. }
  3427. #endif // NDEBUG
  3428. #ifdef SUPPORT_IMMEDIATE_MODE
  3429. if (_use_sender) {
  3430. draw_immediate_composite_primitives(reader, GL_TRIANGLE_STRIP);
  3431. } else
  3432. #endif // SUPPORT_IMMEDIATE_MODE
  3433. {
  3434. if (connect_triangle_strips && _render_mode != RenderModeAttrib::M_wireframe) {
  3435. // One long triangle strip, connected by the degenerate vertices
  3436. // that have already been set up within the primitive.
  3437. int num_vertices = reader->get_num_vertices();
  3438. _vertices_tristrip_pcollector.add_level(num_vertices);
  3439. _primitive_batches_tristrip_pcollector.add_level(1);
  3440. if (reader->is_indexed()) {
  3441. const unsigned char *client_pointer;
  3442. if (!setup_primitive(client_pointer, reader, force)) {
  3443. return false;
  3444. }
  3445. #ifndef OPENGLES_1
  3446. if (_supports_geometry_instancing && _instance_count > 0) {
  3447. _glDrawElementsInstanced(GL_TRIANGLE_STRIP, num_vertices,
  3448. get_numeric_type(reader->get_index_type()),
  3449. client_pointer, _instance_count);
  3450. } else
  3451. #endif
  3452. {
  3453. _glDrawRangeElements(GL_TRIANGLE_STRIP,
  3454. reader->get_min_vertex(),
  3455. reader->get_max_vertex(),
  3456. num_vertices,
  3457. get_numeric_type(reader->get_index_type()),
  3458. client_pointer);
  3459. }
  3460. } else {
  3461. #ifndef OPENGLES_1
  3462. if (_supports_geometry_instancing && _instance_count > 0) {
  3463. _glDrawArraysInstanced(GL_TRIANGLE_STRIP,
  3464. reader->get_first_vertex(),
  3465. num_vertices, _instance_count);
  3466. } else
  3467. #endif
  3468. {
  3469. glDrawArrays(GL_TRIANGLE_STRIP,
  3470. reader->get_first_vertex(),
  3471. num_vertices);
  3472. }
  3473. }
  3474. } else {
  3475. // Send the individual triangle strips, stepping over the
  3476. // degenerate vertices.
  3477. CPTA_int ends = reader->get_ends();
  3478. _primitive_batches_tristrip_pcollector.add_level(ends.size());
  3479. if (reader->is_indexed()) {
  3480. const unsigned char *client_pointer;
  3481. if (!setup_primitive(client_pointer, reader, force)) {
  3482. return false;
  3483. }
  3484. int index_stride = reader->get_index_stride();
  3485. GeomVertexReader mins(reader->get_mins(), 0);
  3486. GeomVertexReader maxs(reader->get_maxs(), 0);
  3487. nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() &&
  3488. reader->get_maxs()->get_num_rows() == (int)ends.size(), false);
  3489. unsigned int start = 0;
  3490. for (size_t i = 0; i < ends.size(); i++) {
  3491. _vertices_tristrip_pcollector.add_level(ends[i] - start);
  3492. #ifndef OPENGLES_1
  3493. if (_supports_geometry_instancing && _instance_count > 0) {
  3494. _glDrawElementsInstanced(GL_TRIANGLE_STRIP, ends[i] - start,
  3495. get_numeric_type(reader->get_index_type()),
  3496. client_pointer + start * index_stride,
  3497. _instance_count);
  3498. } else
  3499. #endif
  3500. {
  3501. _glDrawRangeElements(GL_TRIANGLE_STRIP,
  3502. mins.get_data1i(), maxs.get_data1i(),
  3503. ends[i] - start,
  3504. get_numeric_type(reader->get_index_type()),
  3505. client_pointer + start * index_stride);
  3506. }
  3507. start = ends[i] + 2;
  3508. }
  3509. } else {
  3510. unsigned int start = 0;
  3511. int first_vertex = reader->get_first_vertex();
  3512. for (size_t i = 0; i < ends.size(); i++) {
  3513. _vertices_tristrip_pcollector.add_level(ends[i] - start);
  3514. #ifndef OPENGLES_1
  3515. if (_supports_geometry_instancing && _instance_count > 0) {
  3516. _glDrawArraysInstanced(GL_TRIANGLE_STRIP, first_vertex + start,
  3517. ends[i] - start, _instance_count);
  3518. } else
  3519. #endif
  3520. {
  3521. glDrawArrays(GL_TRIANGLE_STRIP, first_vertex + start,
  3522. ends[i] - start);
  3523. }
  3524. start = ends[i] + 2;
  3525. }
  3526. }
  3527. }
  3528. }
  3529. report_my_gl_errors();
  3530. return true;
  3531. }
  3532. ////////////////////////////////////////////////////////////////////
  3533. // Function: GLGraphicsStateGuardian::draw_trifans
  3534. // Access: Public, Virtual
  3535. // Description: Draws a series of triangle fans.
  3536. ////////////////////////////////////////////////////////////////////
  3537. bool CLP(GraphicsStateGuardian)::
  3538. draw_trifans(const GeomPrimitivePipelineReader *reader, bool force) {
  3539. PStatGPUTimer timer(this, _draw_primitive_pcollector, reader->get_current_thread());
  3540. #ifndef NDEBUG
  3541. if (GLCAT.is_spam()) {
  3542. GLCAT.spam() << "draw_trifans: " << *(reader->get_object()) << "\n";
  3543. }
  3544. #endif // NDEBUG
  3545. #ifdef SUPPORT_IMMEDIATE_MODE
  3546. if (_use_sender) {
  3547. draw_immediate_composite_primitives(reader, GL_TRIANGLE_FAN);
  3548. } else
  3549. #endif // SUPPORT_IMMEDIATE_MODE
  3550. {
  3551. // Send the individual triangle fans. There's no connecting fans
  3552. // with degenerate vertices, so no worries about that.
  3553. CPTA_int ends = reader->get_ends();
  3554. _primitive_batches_trifan_pcollector.add_level(ends.size());
  3555. if (reader->is_indexed()) {
  3556. const unsigned char *client_pointer;
  3557. if (!setup_primitive(client_pointer, reader, force)) {
  3558. return false;
  3559. }
  3560. int index_stride = reader->get_index_stride();
  3561. GeomVertexReader mins(reader->get_mins(), 0);
  3562. GeomVertexReader maxs(reader->get_maxs(), 0);
  3563. nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() &&
  3564. reader->get_maxs()->get_num_rows() == (int)ends.size(), false);
  3565. unsigned int start = 0;
  3566. for (size_t i = 0; i < ends.size(); i++) {
  3567. _vertices_trifan_pcollector.add_level(ends[i] - start);
  3568. #ifndef OPENGLES_1
  3569. if (_supports_geometry_instancing && _instance_count > 0) {
  3570. _glDrawElementsInstanced(GL_TRIANGLE_FAN, ends[i] - start,
  3571. get_numeric_type(reader->get_index_type()),
  3572. client_pointer + start * index_stride,
  3573. _instance_count);
  3574. } else
  3575. #endif
  3576. {
  3577. _glDrawRangeElements(GL_TRIANGLE_FAN,
  3578. mins.get_data1i(), maxs.get_data1i(), ends[i] - start,
  3579. get_numeric_type(reader->get_index_type()),
  3580. client_pointer + start * index_stride);
  3581. }
  3582. start = ends[i];
  3583. }
  3584. } else {
  3585. unsigned int start = 0;
  3586. int first_vertex = reader->get_first_vertex();
  3587. for (size_t i = 0; i < ends.size(); i++) {
  3588. _vertices_trifan_pcollector.add_level(ends[i] - start);
  3589. #ifndef OPENGLES_1
  3590. if (_supports_geometry_instancing && _instance_count > 0) {
  3591. _glDrawArraysInstanced(GL_TRIANGLE_FAN, first_vertex + start,
  3592. ends[i] - start, _instance_count);
  3593. } else
  3594. #endif
  3595. {
  3596. glDrawArrays(GL_TRIANGLE_FAN, first_vertex + start,
  3597. ends[i] - start);
  3598. }
  3599. start = ends[i];
  3600. }
  3601. }
  3602. }
  3603. report_my_gl_errors();
  3604. return true;
  3605. }
  3606. ////////////////////////////////////////////////////////////////////
  3607. // Function: GLGraphicsStateGuardian::draw_patches
  3608. // Access: Public, Virtual
  3609. // Description: Draws a series of "patches", which can only be
  3610. // processed by a tessellation shader.
  3611. ////////////////////////////////////////////////////////////////////
  3612. bool CLP(GraphicsStateGuardian)::
  3613. draw_patches(const GeomPrimitivePipelineReader *reader, bool force) {
  3614. PStatGPUTimer timer(this, _draw_primitive_pcollector, reader->get_current_thread());
  3615. #ifndef NDEBUG
  3616. if (GLCAT.is_spam()) {
  3617. GLCAT.spam() << "draw_patches: " << *(reader->get_object()) << "\n";
  3618. }
  3619. #endif // NDEBUG
  3620. if (!get_supports_tessellation_shaders()) {
  3621. return false;
  3622. }
  3623. #ifndef OPENGLES
  3624. _glPatchParameteri(GL_PATCH_VERTICES, reader->get_object()->get_num_vertices_per_primitive());
  3625. #ifdef SUPPORT_IMMEDIATE_MODE
  3626. if (_use_sender) {
  3627. draw_immediate_simple_primitives(reader, GL_PATCHES);
  3628. } else
  3629. #endif // SUPPORT_IMMEDIATE_MODE
  3630. {
  3631. int num_vertices = reader->get_num_vertices();
  3632. _vertices_patch_pcollector.add_level(num_vertices);
  3633. _primitive_batches_patch_pcollector.add_level(1);
  3634. if (reader->is_indexed()) {
  3635. const unsigned char *client_pointer;
  3636. if (!setup_primitive(client_pointer, reader, force)) {
  3637. return false;
  3638. }
  3639. #ifndef OPENGLES_1
  3640. if (_supports_geometry_instancing && _instance_count > 0) {
  3641. _glDrawElementsInstanced(GL_PATCHES, num_vertices,
  3642. get_numeric_type(reader->get_index_type()),
  3643. client_pointer, _instance_count);
  3644. } else
  3645. #endif
  3646. {
  3647. _glDrawRangeElements(GL_PATCHES,
  3648. reader->get_min_vertex(),
  3649. reader->get_max_vertex(),
  3650. num_vertices,
  3651. get_numeric_type(reader->get_index_type()),
  3652. client_pointer);
  3653. }
  3654. } else {
  3655. #ifndef OPENGLES_1
  3656. if (_supports_geometry_instancing && _instance_count > 0) {
  3657. _glDrawArraysInstanced(GL_PATCHES,
  3658. reader->get_first_vertex(),
  3659. num_vertices, _instance_count);
  3660. } else
  3661. #endif
  3662. {
  3663. glDrawArrays(GL_PATCHES,
  3664. reader->get_first_vertex(),
  3665. num_vertices);
  3666. }
  3667. }
  3668. }
  3669. #endif // OPENGLES
  3670. report_my_gl_errors();
  3671. return true;
  3672. }
  3673. ////////////////////////////////////////////////////////////////////
  3674. // Function: GLGraphicsStateGuardian::draw_lines
  3675. // Access: Public, Virtual
  3676. // Description: Draws a series of disconnected line segments.
  3677. ////////////////////////////////////////////////////////////////////
  3678. bool CLP(GraphicsStateGuardian)::
  3679. draw_lines(const GeomPrimitivePipelineReader *reader, bool force) {
  3680. PStatGPUTimer timer(this, _draw_primitive_pcollector, reader->get_current_thread());
  3681. #ifndef NDEBUG
  3682. if (GLCAT.is_spam()) {
  3683. GLCAT.spam() << "draw_lines: " << *(reader->get_object()) << "\n";
  3684. }
  3685. #endif // NDEBUG
  3686. #ifdef SUPPORT_IMMEDIATE_MODE
  3687. if (_use_sender) {
  3688. draw_immediate_simple_primitives(reader, GL_LINES);
  3689. } else
  3690. #endif // SUPPORT_IMMEDIATE_MODE
  3691. {
  3692. int num_vertices = reader->get_num_vertices();
  3693. _vertices_other_pcollector.add_level(num_vertices);
  3694. _primitive_batches_other_pcollector.add_level(1);
  3695. if (reader->is_indexed()) {
  3696. const unsigned char *client_pointer;
  3697. if (!setup_primitive(client_pointer, reader, force)) {
  3698. return false;
  3699. }
  3700. #ifndef OPENGLES_1
  3701. if (_supports_geometry_instancing && _instance_count > 0) {
  3702. _glDrawElementsInstanced(GL_LINES, num_vertices,
  3703. get_numeric_type(reader->get_index_type()),
  3704. client_pointer, _instance_count);
  3705. } else
  3706. #endif
  3707. {
  3708. _glDrawRangeElements(GL_LINES,
  3709. reader->get_min_vertex(),
  3710. reader->get_max_vertex(),
  3711. num_vertices,
  3712. get_numeric_type(reader->get_index_type()),
  3713. client_pointer);
  3714. }
  3715. } else {
  3716. #ifndef OPENGLES_1
  3717. if (_supports_geometry_instancing && _instance_count > 0) {
  3718. _glDrawArraysInstanced(GL_LINES,
  3719. reader->get_first_vertex(),
  3720. num_vertices, _instance_count);
  3721. } else
  3722. #endif
  3723. {
  3724. glDrawArrays(GL_LINES,
  3725. reader->get_first_vertex(),
  3726. num_vertices);
  3727. }
  3728. }
  3729. }
  3730. report_my_gl_errors();
  3731. return true;
  3732. }
  3733. ////////////////////////////////////////////////////////////////////
  3734. // Function: GLGraphicsStateGuardian::draw_linestrips
  3735. // Access: Public, Virtual
  3736. // Description: Draws a series of line strips.
  3737. ////////////////////////////////////////////////////////////////////
  3738. bool CLP(GraphicsStateGuardian)::
  3739. draw_linestrips(const GeomPrimitivePipelineReader *reader, bool force) {
  3740. PStatGPUTimer timer(this, _draw_primitive_pcollector, reader->get_current_thread());
  3741. report_my_gl_errors();
  3742. #ifndef NDEBUG
  3743. if (GLCAT.is_spam()) {
  3744. GLCAT.spam() << "draw_linestrips: " << *(reader->get_object()) << "\n";
  3745. }
  3746. #endif // NDEBUG
  3747. #ifdef SUPPORT_IMMEDIATE_MODE
  3748. if (_use_sender) {
  3749. draw_immediate_composite_primitives(reader, GL_LINE_STRIP);
  3750. } else
  3751. #endif // SUPPORT_IMMEDIATE_MODE
  3752. {
  3753. if (reader->is_indexed() &&
  3754. (_supported_geom_rendering & GeomEnums::GR_strip_cut_index) != 0) {
  3755. // One long triangle strip, connected by strip cut indices.
  3756. #ifndef OPENGLES
  3757. if (_explicit_primitive_restart) {
  3758. glEnable(GL_PRIMITIVE_RESTART);
  3759. _glPrimitiveRestartIndex(reader->get_strip_cut_index());
  3760. }
  3761. #endif // !OPENGLES
  3762. int num_vertices = reader->get_num_vertices();
  3763. _vertices_other_pcollector.add_level(num_vertices);
  3764. _primitive_batches_other_pcollector.add_level(1);
  3765. const unsigned char *client_pointer;
  3766. if (!setup_primitive(client_pointer, reader, force)) {
  3767. return false;
  3768. }
  3769. #ifndef OPENGLES_1
  3770. if (_supports_geometry_instancing && _instance_count > 0) {
  3771. _glDrawElementsInstanced(GL_LINE_STRIP, num_vertices,
  3772. get_numeric_type(reader->get_index_type()),
  3773. client_pointer, _instance_count);
  3774. } else
  3775. #endif // !OPENGLES
  3776. {
  3777. _glDrawRangeElements(GL_LINE_STRIP,
  3778. reader->get_min_vertex(),
  3779. reader->get_max_vertex(),
  3780. num_vertices,
  3781. get_numeric_type(reader->get_index_type()),
  3782. client_pointer);
  3783. }
  3784. #ifndef OPENGLES
  3785. if (_explicit_primitive_restart) {
  3786. glDisable(GL_PRIMITIVE_RESTART);
  3787. }
  3788. #endif // !OPENGLES
  3789. } else {
  3790. // Send the individual line strips, stepping over the
  3791. // strip-cut indices.
  3792. CPTA_int ends = reader->get_ends();
  3793. _primitive_batches_other_pcollector.add_level(ends.size());
  3794. if (reader->is_indexed()) {
  3795. const unsigned char *client_pointer;
  3796. if (!setup_primitive(client_pointer, reader, force)) {
  3797. return false;
  3798. }
  3799. int index_stride = reader->get_index_stride();
  3800. GeomVertexReader mins(reader->get_mins(), 0);
  3801. GeomVertexReader maxs(reader->get_maxs(), 0);
  3802. nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() &&
  3803. reader->get_maxs()->get_num_rows() == (int)ends.size(), false);
  3804. unsigned int start = 0;
  3805. for (size_t i = 0; i < ends.size(); i++) {
  3806. _vertices_other_pcollector.add_level(ends[i] - start);
  3807. #ifndef OPENGLES_1
  3808. if (_supports_geometry_instancing && _instance_count > 0) {
  3809. _glDrawElementsInstanced(GL_LINE_STRIP, ends[i] - start,
  3810. get_numeric_type(reader->get_index_type()),
  3811. client_pointer + start * index_stride,
  3812. _instance_count);
  3813. } else
  3814. #endif
  3815. {
  3816. _glDrawRangeElements(GL_LINE_STRIP,
  3817. mins.get_data1i(), maxs.get_data1i(),
  3818. ends[i] - start,
  3819. get_numeric_type(reader->get_index_type()),
  3820. client_pointer + start * index_stride);
  3821. }
  3822. start = ends[i] + 1;
  3823. }
  3824. } else {
  3825. unsigned int start = 0;
  3826. int first_vertex = reader->get_first_vertex();
  3827. for (size_t i = 0; i < ends.size(); i++) {
  3828. _vertices_other_pcollector.add_level(ends[i] - start);
  3829. #ifndef OPENGLES_1
  3830. if (_supports_geometry_instancing && _instance_count > 0) {
  3831. _glDrawArraysInstanced(GL_LINE_STRIP, first_vertex + start,
  3832. ends[i] - start, _instance_count);
  3833. } else
  3834. #endif
  3835. {
  3836. glDrawArrays(GL_LINE_STRIP, first_vertex + start, ends[i] - start);
  3837. }
  3838. start = ends[i] + 1;
  3839. }
  3840. }
  3841. }
  3842. }
  3843. report_my_gl_errors();
  3844. return true;
  3845. }
  3846. ////////////////////////////////////////////////////////////////////
  3847. // Function: GLGraphicsStateGuardian::draw_points
  3848. // Access: Public, Virtual
  3849. // Description: Draws a series of disconnected points.
  3850. ////////////////////////////////////////////////////////////////////
  3851. bool CLP(GraphicsStateGuardian)::
  3852. draw_points(const GeomPrimitivePipelineReader *reader, bool force) {
  3853. PStatGPUTimer timer(this, _draw_primitive_pcollector, reader->get_current_thread());
  3854. #ifndef NDEBUG
  3855. if (GLCAT.is_spam()) {
  3856. GLCAT.spam() << "draw_points: " << *(reader->get_object()) << "\n";
  3857. }
  3858. #endif // NDEBUG
  3859. #ifdef SUPPORT_IMMEDIATE_MODE
  3860. if (_use_sender) {
  3861. draw_immediate_simple_primitives(reader, GL_POINTS);
  3862. } else
  3863. #endif // SUPPORT_IMMEDIATE_MODE
  3864. {
  3865. int num_vertices = reader->get_num_vertices();
  3866. _vertices_other_pcollector.add_level(num_vertices);
  3867. _primitive_batches_other_pcollector.add_level(1);
  3868. if (reader->is_indexed()) {
  3869. const unsigned char *client_pointer;
  3870. if (!setup_primitive(client_pointer, reader, force)) {
  3871. return false;
  3872. }
  3873. #ifndef OPENGLES_1
  3874. if (_supports_geometry_instancing && _instance_count > 0) {
  3875. _glDrawElementsInstanced(GL_POINTS, num_vertices,
  3876. get_numeric_type(reader->get_index_type()),
  3877. client_pointer, _instance_count);
  3878. } else
  3879. #endif
  3880. {
  3881. _glDrawRangeElements(GL_POINTS,
  3882. reader->get_min_vertex(),
  3883. reader->get_max_vertex(),
  3884. num_vertices,
  3885. get_numeric_type(reader->get_index_type()),
  3886. client_pointer);
  3887. }
  3888. } else {
  3889. #ifndef OPENGLES_1
  3890. if (_supports_geometry_instancing && _instance_count > 0) {
  3891. _glDrawArraysInstanced(GL_POINTS,
  3892. reader->get_first_vertex(),
  3893. num_vertices, _instance_count);
  3894. } else
  3895. #endif
  3896. {
  3897. glDrawArrays(GL_POINTS, reader->get_first_vertex(), num_vertices);
  3898. }
  3899. }
  3900. }
  3901. report_my_gl_errors();
  3902. return true;
  3903. }
  3904. ////////////////////////////////////////////////////////////////////
  3905. // Function: GLGraphicsStateGuardian::end_draw_primitives()
  3906. // Access: Public, Virtual
  3907. // Description: Called after a sequence of draw_primitive()
  3908. // functions are called, this should do whatever cleanup
  3909. // is appropriate.
  3910. ////////////////////////////////////////////////////////////////////
  3911. void CLP(GraphicsStateGuardian)::
  3912. end_draw_primitives() {
  3913. #ifndef OPENGLES // Display lists not supported by OpenGL ES.
  3914. if (_geom_display_list != 0) {
  3915. // If we were building a display list, close it now.
  3916. glEndList();
  3917. _load_display_list_pcollector.stop();
  3918. if (!gl_compile_and_execute) {
  3919. glCallList(_geom_display_list);
  3920. }
  3921. _primitive_batches_display_list_pcollector.add_level(1);
  3922. }
  3923. _geom_display_list = 0;
  3924. // Clean up the vertex blending state.
  3925. if (_vertex_blending_enabled) {
  3926. glDisable(GL_VERTEX_BLEND_ARB);
  3927. if (_supports_matrix_palette) {
  3928. glDisable(GL_MATRIX_PALETTE_ARB);
  3929. }
  3930. _vertex_blending_enabled = false;
  3931. }
  3932. #endif
  3933. #ifndef OPENGLES_2
  3934. if (_transform_stale) {
  3935. glMatrixMode(GL_MODELVIEW);
  3936. GLPf(LoadMatrix)(_internal_transform->get_mat().get_data());
  3937. }
  3938. if (_data_reader->is_vertex_transformed()) {
  3939. // Restore the matrices that we pushed above.
  3940. glMatrixMode(GL_PROJECTION);
  3941. glPopMatrix();
  3942. glMatrixMode(GL_MODELVIEW);
  3943. glPopMatrix();
  3944. }
  3945. #endif
  3946. GraphicsStateGuardian::end_draw_primitives();
  3947. maybe_gl_finish();
  3948. report_my_gl_errors();
  3949. }
  3950. #ifndef OPENGLES
  3951. ////////////////////////////////////////////////////////////////////
  3952. // Function: GLGraphicsStateGuardian::issue_memory_barrier
  3953. // Access: Public
  3954. // Description: Issues the given memory barriers, and clears the
  3955. // list of textures marked as incoherent for the given
  3956. // bits.
  3957. ////////////////////////////////////////////////////////////////////
  3958. void CLP(GraphicsStateGuardian)::
  3959. issue_memory_barrier(GLbitfield barriers) {
  3960. if (!gl_enable_memory_barriers || _glMemoryBarrier == NULL) {
  3961. return;
  3962. }
  3963. PStatGPUTimer timer(this, _memory_barrier_pcollector);
  3964. if (GLCAT.is_spam()) {
  3965. GLCAT.spam() << "Issuing memory barriers:";
  3966. }
  3967. _glMemoryBarrier(barriers);
  3968. // Indicate that barriers no longer need to be issued for
  3969. // the relevant lists of textures.
  3970. if (barriers & GL_TEXTURE_FETCH_BARRIER_BIT) {
  3971. _textures_needing_fetch_barrier.clear();
  3972. GLCAT.spam(false) << " texture_fetch";
  3973. }
  3974. if (barriers & GL_SHADER_IMAGE_ACCESS_BARRIER_BIT) {
  3975. _textures_needing_image_access_barrier.clear();
  3976. GLCAT.spam(false) << " shader_image_access";
  3977. }
  3978. if (barriers & GL_TEXTURE_UPDATE_BARRIER_BIT) {
  3979. _textures_needing_update_barrier.clear();
  3980. GLCAT.spam(false) << " texture_update";
  3981. }
  3982. if (barriers & GL_FRAMEBUFFER_BARRIER_BIT) {
  3983. _textures_needing_framebuffer_barrier.clear();
  3984. GLCAT.spam(false) << " framebuffer";
  3985. }
  3986. GLCAT.spam(false) << "\n";
  3987. report_my_gl_errors();
  3988. }
  3989. #endif // OPENGLES
  3990. ////////////////////////////////////////////////////////////////////
  3991. // Function: GLGraphicsStateGuardian::prepare_texture
  3992. // Access: Public, Virtual
  3993. // Description: Creates whatever structures the GSG requires to
  3994. // represent the texture internally, and returns a
  3995. // newly-allocated TextureContext object with this data.
  3996. // It is the responsibility of the calling function to
  3997. // later call release_texture() with this same pointer
  3998. // (which will also delete the pointer).
  3999. //
  4000. // This function should not be called directly to
  4001. // prepare a texture. Instead, call Texture::prepare().
  4002. ////////////////////////////////////////////////////////////////////
  4003. TextureContext *CLP(GraphicsStateGuardian)::
  4004. prepare_texture(Texture *tex, int view) {
  4005. PStatGPUTimer timer(this, _prepare_texture_pcollector);
  4006. report_my_gl_errors();
  4007. // Make sure we'll support this texture when it's rendered. Don't
  4008. // bother to prepare it if we won't.
  4009. switch (tex->get_texture_type()) {
  4010. case Texture::TT_3d_texture:
  4011. if (!_supports_3d_texture) {
  4012. GLCAT.warning()
  4013. << "3-D textures are not supported by this OpenGL driver.\n";
  4014. return NULL;
  4015. }
  4016. break;
  4017. case Texture::TT_2d_texture_array:
  4018. if (!_supports_2d_texture_array) {
  4019. GLCAT.warning()
  4020. << "2-D texture arrays are not supported by this OpenGL driver.\n";
  4021. return NULL;
  4022. }
  4023. break;
  4024. case Texture::TT_cube_map:
  4025. if (!_supports_cube_map) {
  4026. GLCAT.warning()
  4027. << "Cube map textures are not supported by this OpenGL driver.\n";
  4028. return NULL;
  4029. }
  4030. default:
  4031. break;
  4032. }
  4033. CLP(TextureContext) *gtc = new CLP(TextureContext)(this, _prepared_objects, tex, view);
  4034. report_my_gl_errors();
  4035. return gtc;
  4036. }
  4037. ////////////////////////////////////////////////////////////////////
  4038. // Function: GLGraphicsStateGuardian::update_texture
  4039. // Access: Public, Virtual
  4040. // Description: Ensures that the current Texture data is refreshed
  4041. // onto the GSG. This means updating the texture
  4042. // properties and/or re-uploading the texture image, if
  4043. // necessary. This should only be called within the
  4044. // draw thread.
  4045. //
  4046. // If force is true, this function will not return until
  4047. // the texture has been fully uploaded. If force is
  4048. // false, the function may choose to upload a simple
  4049. // version of the texture instead, if the texture is not
  4050. // fully resident (and if get_incomplete_render() is
  4051. // true).
  4052. ////////////////////////////////////////////////////////////////////
  4053. bool CLP(GraphicsStateGuardian)::
  4054. update_texture(TextureContext *tc, bool force) {
  4055. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
  4056. if (gtc->was_image_modified() || !gtc->_has_storage) {
  4057. PStatGPUTimer timer(this, _texture_update_pcollector);
  4058. // If the texture image was modified, reload the texture.
  4059. apply_texture(tc);
  4060. Texture *tex = tc->get_texture();
  4061. if (gtc->was_properties_modified()) {
  4062. specify_texture(gtc, tex->get_default_sampler());
  4063. }
  4064. bool okflag = upload_texture(gtc, force, tex->uses_mipmaps());
  4065. if (!okflag) {
  4066. GLCAT.error()
  4067. << "Could not load " << *tex << "\n";
  4068. return false;
  4069. }
  4070. } else if (gtc->was_properties_modified()) {
  4071. PStatGPUTimer timer(this, _texture_update_pcollector);
  4072. // If only the properties have been modified, we don't necessarily
  4073. // need to reload the texture.
  4074. apply_texture(tc);
  4075. Texture *tex = tc->get_texture();
  4076. if (specify_texture(gtc, tex->get_default_sampler())) {
  4077. // Actually, looks like the texture *does* need to be reloaded.
  4078. gtc->mark_needs_reload();
  4079. bool okflag = upload_texture(gtc, force, tex->uses_mipmaps());
  4080. if (!okflag) {
  4081. GLCAT.error()
  4082. << "Could not load " << *tex << "\n";
  4083. return false;
  4084. }
  4085. } else {
  4086. // The texture didn't need reloading, but mark it fully updated
  4087. // now.
  4088. gtc->mark_loaded();
  4089. }
  4090. }
  4091. gtc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  4092. report_my_gl_errors();
  4093. return true;
  4094. }
  4095. ////////////////////////////////////////////////////////////////////
  4096. // Function: GLGraphicsStateGuardian::release_texture
  4097. // Access: Public, Virtual
  4098. // Description: Frees the GL resources previously allocated for the
  4099. // texture. This function should never be called
  4100. // directly; instead, call Texture::release() (or simply
  4101. // let the Texture destruct).
  4102. ////////////////////////////////////////////////////////////////////
  4103. void CLP(GraphicsStateGuardian)::
  4104. release_texture(TextureContext *tc) {
  4105. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
  4106. delete gtc;
  4107. }
  4108. ////////////////////////////////////////////////////////////////////
  4109. // Function: GLGraphicsStateGuardian::extract_texture_data
  4110. // Access: Public, Virtual
  4111. // Description: This method should only be called by the
  4112. // GraphicsEngine. Do not call it directly; call
  4113. // GraphicsEngine::extract_texture_data() instead.
  4114. //
  4115. // This method will be called in the draw thread to
  4116. // download the texture memory's image into its
  4117. // ram_image value. It returns true on success, false
  4118. // otherwise.
  4119. ////////////////////////////////////////////////////////////////////
  4120. bool CLP(GraphicsStateGuardian)::
  4121. extract_texture_data(Texture *tex) {
  4122. bool success = true;
  4123. // Make sure the error stack is cleared out before we begin.
  4124. report_my_gl_errors();
  4125. int num_views = tex->get_num_views();
  4126. for (int view = 0; view < num_views; ++view) {
  4127. TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this);
  4128. nassertr(tc != (TextureContext *)NULL, false);
  4129. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
  4130. if (!do_extract_texture_data(gtc)) {
  4131. success = false;
  4132. }
  4133. }
  4134. return success;
  4135. }
  4136. #ifndef OPENGLES
  4137. ////////////////////////////////////////////////////////////////////
  4138. // Function: GLGraphicsStateGuardian::prepare_sampler
  4139. // Access: Public, Virtual
  4140. // Description: Creates whatever structures the GSG requires to
  4141. // represent the sampler state internally, and returns a
  4142. // newly-allocated SamplerContext object with this data.
  4143. // It is the responsibility of the calling function to
  4144. // later call release_sampler() with this same pointer
  4145. // (which will also delete the pointer).
  4146. //
  4147. // This function should not be called directly to
  4148. // prepare a sampler object. Instead, call
  4149. // SamplerState::prepare().
  4150. ////////////////////////////////////////////////////////////////////
  4151. SamplerContext *CLP(GraphicsStateGuardian)::
  4152. prepare_sampler(const SamplerState &sampler) {
  4153. nassertr(_supports_sampler_objects, NULL);
  4154. PStatGPUTimer timer(this, _prepare_sampler_pcollector);
  4155. CLP(SamplerContext) *gsc = new CLP(SamplerContext)(this, sampler);
  4156. GLuint index = gsc->_index;
  4157. // Sampler contexts are immutable in Panda, so might as well just
  4158. // initialize all the settings here.
  4159. _glSamplerParameteri(index, GL_TEXTURE_WRAP_S,
  4160. get_texture_wrap_mode(sampler.get_wrap_u()));
  4161. _glSamplerParameteri(index, GL_TEXTURE_WRAP_T,
  4162. get_texture_wrap_mode(sampler.get_wrap_v()));
  4163. _glSamplerParameteri(index, GL_TEXTURE_WRAP_R,
  4164. get_texture_wrap_mode(sampler.get_wrap_w()));
  4165. #ifdef STDFLOAT_DOUBLE
  4166. LVecBase4f fvalue = LCAST(float, sampler.get_border_color());
  4167. _glSamplerParameterfv(index, GL_TEXTURE_BORDER_COLOR, fvalue.get_data());
  4168. #else
  4169. _glSamplerParameterfv(index, GL_TEXTURE_BORDER_COLOR,
  4170. sampler.get_border_color().get_data());
  4171. #endif
  4172. SamplerState::FilterType minfilter = sampler.get_effective_minfilter();
  4173. SamplerState::FilterType magfilter = sampler.get_effective_magfilter();
  4174. bool uses_mipmaps = SamplerState::is_mipmap(minfilter) && !gl_ignore_mipmaps;
  4175. #ifndef NDEBUG
  4176. if (gl_force_mipmaps) {
  4177. minfilter = SamplerState::FT_linear_mipmap_linear;
  4178. magfilter = SamplerState::FT_linear;
  4179. uses_mipmaps = true;
  4180. }
  4181. #endif
  4182. _glSamplerParameteri(index, GL_TEXTURE_MIN_FILTER,
  4183. get_texture_filter_type(minfilter, !uses_mipmaps));
  4184. _glSamplerParameteri(index, GL_TEXTURE_MAG_FILTER,
  4185. get_texture_filter_type(magfilter, true));
  4186. // Set anisotropic filtering.
  4187. if (_supports_anisotropy) {
  4188. PN_stdfloat anisotropy = sampler.get_effective_anisotropic_degree();
  4189. anisotropy = min(anisotropy, _max_anisotropy);
  4190. anisotropy = max(anisotropy, (PN_stdfloat)1.0);
  4191. _glSamplerParameterf(index, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
  4192. }
  4193. if (_supports_shadow_filter) {
  4194. if ((sampler.get_magfilter() == SamplerState::FT_shadow) ||
  4195. (sampler.get_minfilter() == SamplerState::FT_shadow)) {
  4196. _glSamplerParameteri(index, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
  4197. _glSamplerParameteri(index, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
  4198. } else {
  4199. _glSamplerParameteri(index, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
  4200. _glSamplerParameteri(index, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
  4201. }
  4202. }
  4203. _glSamplerParameterf(index, GL_TEXTURE_MIN_LOD, sampler.get_min_lod());
  4204. _glSamplerParameterf(index, GL_TEXTURE_MAX_LOD, sampler.get_max_lod());
  4205. _glSamplerParameterf(index, GL_TEXTURE_LOD_BIAS, sampler.get_lod_bias());
  4206. gsc->enqueue_lru(&_prepared_objects->_sampler_object_lru);
  4207. report_my_gl_errors();
  4208. return gsc;
  4209. }
  4210. #endif // !OPENGLES
  4211. #ifndef OPENGLES
  4212. ////////////////////////////////////////////////////////////////////
  4213. // Function: GLGraphicsStateGuardian::release_sampler
  4214. // Access: Public, Virtual
  4215. // Description: Frees the GL resources previously allocated for the
  4216. // sampler. This function should never be called
  4217. // directly; instead, call SamplerState::release().
  4218. ////////////////////////////////////////////////////////////////////
  4219. void CLP(GraphicsStateGuardian)::
  4220. release_sampler(SamplerContext *sc) {
  4221. CLP(SamplerContext) *gsc = DCAST(CLP(SamplerContext), sc);
  4222. delete gsc;
  4223. }
  4224. #endif // !OPENGLES
  4225. ////////////////////////////////////////////////////////////////////
  4226. // Function: GLGraphicsStateGuardian::prepare_geom
  4227. // Access: Public, Virtual
  4228. // Description: Creates a new retained-mode representation of the
  4229. // given geom, and returns a newly-allocated
  4230. // GeomContext pointer to reference it. It is the
  4231. // responsibility of the calling function to later
  4232. // call release_geom() with this same pointer (which
  4233. // will also delete the pointer).
  4234. //
  4235. // This function should not be called directly to
  4236. // prepare a geom. Instead, call Geom::prepare().
  4237. ////////////////////////////////////////////////////////////////////
  4238. GeomContext *CLP(GraphicsStateGuardian)::
  4239. prepare_geom(Geom *geom) {
  4240. PStatGPUTimer timer(this, _prepare_geom_pcollector);
  4241. return new CLP(GeomContext)(geom);
  4242. }
  4243. ////////////////////////////////////////////////////////////////////
  4244. // Function: GLGraphicsStateGuardian::release_geom
  4245. // Access: Public, Virtual
  4246. // Description: Frees the GL resources previously allocated for the
  4247. // geom. This function should never be called
  4248. // directly; instead, call Geom::release() (or simply
  4249. // let the Geom destruct).
  4250. ////////////////////////////////////////////////////////////////////
  4251. void CLP(GraphicsStateGuardian)::
  4252. release_geom(GeomContext *gc) {
  4253. CLP(GeomContext) *ggc = DCAST(CLP(GeomContext), gc);
  4254. ggc->release_display_lists();
  4255. report_my_gl_errors();
  4256. delete ggc;
  4257. }
  4258. ////////////////////////////////////////////////////////////////////
  4259. // Function: GLGraphicsStateGuardian::prepare_shader
  4260. // Access: Public, Virtual
  4261. // Description:
  4262. ////////////////////////////////////////////////////////////////////
  4263. ShaderContext *CLP(GraphicsStateGuardian)::
  4264. prepare_shader(Shader *se) {
  4265. PStatGPUTimer timer(this, _prepare_shader_pcollector);
  4266. #ifndef OPENGLES_1
  4267. ShaderContext *result = NULL;
  4268. switch (se->get_language()) {
  4269. case Shader::SL_GLSL:
  4270. if (_supports_glsl) {
  4271. result = new CLP(ShaderContext)(this, se);
  4272. break;
  4273. } else {
  4274. GLCAT.error()
  4275. << "Tried to load GLSL shader, but GLSL shaders not supported.\n";
  4276. return NULL;
  4277. }
  4278. #if defined(HAVE_CG) && !defined(OPENGLES)
  4279. case Shader::SL_Cg:
  4280. if (_supports_basic_shaders) {
  4281. result = new CLP(CgShaderContext)(this, se);
  4282. break;
  4283. } else {
  4284. GLCAT.error()
  4285. << "Tried to load Cg shader, but basic shaders not supported.\n";
  4286. return NULL;
  4287. }
  4288. #else
  4289. GLCAT.error()
  4290. << "Tried to load Cg shader, but Cg support not compiled in.\n";
  4291. return NULL;
  4292. #endif
  4293. default:
  4294. GLCAT.error()
  4295. << "Tried to load shader with unsupported shader language!\n";
  4296. return NULL;
  4297. }
  4298. if (result->valid()) {
  4299. return result;
  4300. }
  4301. delete result;
  4302. #endif // OPENGLES_1
  4303. return NULL;
  4304. }
  4305. ////////////////////////////////////////////////////////////////////
  4306. // Function: GLGraphicsStateGuardian::release_shader
  4307. // Access: Public, Virtual
  4308. // Description:
  4309. ////////////////////////////////////////////////////////////////////
  4310. void CLP(GraphicsStateGuardian)::
  4311. release_shader(ShaderContext *sc) {
  4312. delete sc;
  4313. }
  4314. ////////////////////////////////////////////////////////////////////
  4315. // Function: GLGraphicsStateGuardian::record_deleted_display_list
  4316. // Access: Public
  4317. // Description: This is intended to be called only from the
  4318. // GLGeomContext destructor. It saves the indicated
  4319. // display list index in the list to be deleted at the
  4320. // end of the frame.
  4321. ////////////////////////////////////////////////////////////////////
  4322. void CLP(GraphicsStateGuardian)::
  4323. record_deleted_display_list(GLuint index) {
  4324. LightMutexHolder holder(_lock);
  4325. _deleted_display_lists.push_back(index);
  4326. }
  4327. ////////////////////////////////////////////////////////////////////
  4328. // Function: GLGraphicsStateGuardian::prepare_vertex_buffer
  4329. // Access: Public, Virtual
  4330. // Description: Creates a new retained-mode representation of the
  4331. // given data, and returns a newly-allocated
  4332. // VertexBufferContext pointer to reference it. It is the
  4333. // responsibility of the calling function to later
  4334. // call release_vertex_buffer() with this same pointer (which
  4335. // will also delete the pointer).
  4336. //
  4337. // This function should not be called directly to
  4338. // prepare a buffer. Instead, call Geom::prepare().
  4339. ////////////////////////////////////////////////////////////////////
  4340. VertexBufferContext *CLP(GraphicsStateGuardian)::
  4341. prepare_vertex_buffer(GeomVertexArrayData *data) {
  4342. if (_supports_buffers) {
  4343. PStatGPUTimer timer(this, _prepare_vertex_buffer_pcollector);
  4344. CLP(VertexBufferContext) *gvbc = new CLP(VertexBufferContext)(this, _prepared_objects, data);
  4345. _glGenBuffers(1, &gvbc->_index);
  4346. if (GLCAT.is_debug() && gl_debug_buffers) {
  4347. GLCAT.debug()
  4348. << "creating vertex buffer " << (int)gvbc->_index << ": "
  4349. << data->get_num_rows() << " vertices "
  4350. << *data->get_array_format() << "\n";
  4351. }
  4352. report_my_gl_errors();
  4353. apply_vertex_buffer(gvbc, data->get_handle(), false);
  4354. return gvbc;
  4355. }
  4356. return NULL;
  4357. }
  4358. ////////////////////////////////////////////////////////////////////
  4359. // Function: GLGraphicsStateGuardian::apply_vertex_buffer
  4360. // Access: Public
  4361. // Description: Makes the data the currently available data for
  4362. // rendering.
  4363. ////////////////////////////////////////////////////////////////////
  4364. bool CLP(GraphicsStateGuardian)::
  4365. apply_vertex_buffer(VertexBufferContext *vbc,
  4366. const GeomVertexArrayDataHandle *reader, bool force) {
  4367. nassertr(_supports_buffers, false);
  4368. if (reader->get_modified() == UpdateSeq::initial()) {
  4369. // No need to re-apply.
  4370. return true;
  4371. }
  4372. CLP(VertexBufferContext) *gvbc = DCAST(CLP(VertexBufferContext), vbc);
  4373. if (_current_vbuffer_index != gvbc->_index) {
  4374. if (GLCAT.is_spam() && gl_debug_buffers) {
  4375. GLCAT.spam()
  4376. << "binding vertex buffer " << (int)gvbc->_index << "\n";
  4377. }
  4378. _glBindBuffer(GL_ARRAY_BUFFER, gvbc->_index);
  4379. _current_vbuffer_index = gvbc->_index;
  4380. gvbc->set_active(true);
  4381. }
  4382. if (gvbc->was_modified(reader)) {
  4383. int num_bytes = reader->get_data_size_bytes();
  4384. if (GLCAT.is_debug() && gl_debug_buffers) {
  4385. GLCAT.debug()
  4386. << "copying " << num_bytes
  4387. << " bytes into vertex buffer " << (int)gvbc->_index << "\n";
  4388. }
  4389. if (num_bytes != 0) {
  4390. const unsigned char *client_pointer = reader->get_read_pointer(force);
  4391. if (client_pointer == NULL) {
  4392. return false;
  4393. }
  4394. PStatGPUTimer timer(this, _load_vertex_buffer_pcollector, reader->get_current_thread());
  4395. if (gvbc->changed_size(reader) || gvbc->changed_usage_hint(reader)) {
  4396. _glBufferData(GL_ARRAY_BUFFER, num_bytes, client_pointer,
  4397. get_usage(reader->get_usage_hint()));
  4398. } else {
  4399. _glBufferSubData(GL_ARRAY_BUFFER, 0, num_bytes, client_pointer);
  4400. }
  4401. _data_transferred_pcollector.add_level(num_bytes);
  4402. }
  4403. gvbc->mark_loaded(reader);
  4404. }
  4405. gvbc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  4406. maybe_gl_finish();
  4407. report_my_gl_errors();
  4408. return true;
  4409. }
  4410. ////////////////////////////////////////////////////////////////////
  4411. // Function: GLGraphicsStateGuardian::release_vertex_buffer
  4412. // Access: Public, Virtual
  4413. // Description: Frees the GL resources previously allocated for the
  4414. // data. This function should never be called
  4415. // directly; instead, call Data::release() (or simply
  4416. // let the Data destruct).
  4417. ////////////////////////////////////////////////////////////////////
  4418. void CLP(GraphicsStateGuardian)::
  4419. release_vertex_buffer(VertexBufferContext *vbc) {
  4420. nassertv(_supports_buffers);
  4421. CLP(VertexBufferContext) *gvbc = DCAST(CLP(VertexBufferContext), vbc);
  4422. if (GLCAT.is_debug() && gl_debug_buffers) {
  4423. GLCAT.debug()
  4424. << "deleting vertex buffer " << (int)gvbc->_index << "\n";
  4425. }
  4426. // Make sure the buffer is unbound before we delete it. Not
  4427. // strictly necessary according to the OpenGL spec, but it might
  4428. // help out a flaky driver, and we need to keep our internal state
  4429. // consistent anyway.
  4430. if (_current_vbuffer_index == gvbc->_index) {
  4431. if (GLCAT.is_spam() && gl_debug_buffers) {
  4432. GLCAT.spam()
  4433. << "unbinding vertex buffer\n";
  4434. }
  4435. _glBindBuffer(GL_ARRAY_BUFFER, 0);
  4436. _current_vbuffer_index = 0;
  4437. }
  4438. _glDeleteBuffers(1, &gvbc->_index);
  4439. report_my_gl_errors();
  4440. gvbc->_index = 0;
  4441. delete gvbc;
  4442. }
  4443. ////////////////////////////////////////////////////////////////////
  4444. // Function: GLGraphicsStateGuardian::setup_array_data
  4445. // Access: Public
  4446. // Description: Internal function to bind a buffer object for the
  4447. // indicated data array, if appropriate, or to unbind a
  4448. // buffer object if it should be rendered from client
  4449. // memory.
  4450. //
  4451. // If the buffer object is bound, this function sets
  4452. // client_pointer to NULL (representing the start of the
  4453. // buffer object in server memory); if the buffer object
  4454. // is not bound, this function sets client_pointer the
  4455. // pointer to the data array in client memory, that is,
  4456. // the data array passed in.
  4457. //
  4458. // If force is not true, the function may return false
  4459. // indicating the data is not currently available.
  4460. ////////////////////////////////////////////////////////////////////
  4461. bool CLP(GraphicsStateGuardian)::
  4462. setup_array_data(const unsigned char *&client_pointer,
  4463. const GeomVertexArrayDataHandle *array_reader,
  4464. bool force) {
  4465. if (!_supports_buffers) {
  4466. // No support for buffer objects; always render from client.
  4467. client_pointer = array_reader->get_read_pointer(force);
  4468. return (client_pointer != NULL);
  4469. }
  4470. if (!vertex_buffers || _geom_display_list != 0 ||
  4471. array_reader->get_usage_hint() < gl_min_buffer_usage_hint) {
  4472. // The array specifies client rendering only, or buffer objects
  4473. // are configured off.
  4474. if (_current_vbuffer_index != 0) {
  4475. if (GLCAT.is_spam() && gl_debug_buffers) {
  4476. GLCAT.spam()
  4477. << "unbinding vertex buffer\n";
  4478. }
  4479. _glBindBuffer(GL_ARRAY_BUFFER, 0);
  4480. _current_vbuffer_index = 0;
  4481. }
  4482. client_pointer = array_reader->get_read_pointer(force);
  4483. return (client_pointer != NULL);
  4484. }
  4485. // Prepare the buffer object and bind it.
  4486. VertexBufferContext *vbc = array_reader->prepare_now(get_prepared_objects(), this);
  4487. nassertr(vbc != (VertexBufferContext *)NULL, false);
  4488. if (!apply_vertex_buffer(vbc, array_reader, force)) {
  4489. return false;
  4490. }
  4491. // NULL is the OpenGL convention for the first byte of the buffer object.
  4492. client_pointer = NULL;
  4493. return true;
  4494. }
  4495. ////////////////////////////////////////////////////////////////////
  4496. // Function: GLGraphicsStateGuardian::prepare_index_buffer
  4497. // Access: Public, Virtual
  4498. // Description: Creates a new retained-mode representation of the
  4499. // given data, and returns a newly-allocated
  4500. // IndexBufferContext pointer to reference it. It is the
  4501. // responsibility of the calling function to later
  4502. // call release_index_buffer() with this same pointer (which
  4503. // will also delete the pointer).
  4504. //
  4505. // This function should not be called directly to
  4506. // prepare a buffer. Instead, call Geom::prepare().
  4507. ////////////////////////////////////////////////////////////////////
  4508. IndexBufferContext *CLP(GraphicsStateGuardian)::
  4509. prepare_index_buffer(GeomPrimitive *data) {
  4510. if (_supports_buffers) {
  4511. PStatGPUTimer timer(this, _prepare_index_buffer_pcollector);
  4512. CLP(IndexBufferContext) *gibc = new CLP(IndexBufferContext)(this, _prepared_objects, data);
  4513. _glGenBuffers(1, &gibc->_index);
  4514. if (GLCAT.is_debug() && gl_debug_buffers) {
  4515. GLCAT.debug()
  4516. << "creating index buffer " << (int)gibc->_index << ": "
  4517. << data->get_num_vertices() << " indices ("
  4518. << data->get_vertices()->get_array_format()->get_column(0)->get_numeric_type()
  4519. << ")\n";
  4520. }
  4521. report_my_gl_errors();
  4522. GeomPrimitivePipelineReader reader(data, Thread::get_current_thread());
  4523. apply_index_buffer(gibc, &reader, false);
  4524. return gibc;
  4525. }
  4526. return NULL;
  4527. }
  4528. ////////////////////////////////////////////////////////////////////
  4529. // Function: GLGraphicsStateGuardian::apply_index_buffer
  4530. // Access: Public
  4531. // Description: Makes the data the currently available data for
  4532. // rendering.
  4533. ////////////////////////////////////////////////////////////////////
  4534. bool CLP(GraphicsStateGuardian)::
  4535. apply_index_buffer(IndexBufferContext *ibc,
  4536. const GeomPrimitivePipelineReader *reader,
  4537. bool force) {
  4538. nassertr(_supports_buffers, false);
  4539. if (reader->get_modified() == UpdateSeq::initial()) {
  4540. // No need to re-apply.
  4541. return true;
  4542. }
  4543. CLP(IndexBufferContext) *gibc = DCAST(CLP(IndexBufferContext), ibc);
  4544. if (_current_ibuffer_index != gibc->_index) {
  4545. if (GLCAT.is_spam() && gl_debug_buffers) {
  4546. GLCAT.spam()
  4547. << "binding index buffer " << (int)gibc->_index << "\n";
  4548. }
  4549. _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gibc->_index);
  4550. _current_ibuffer_index = gibc->_index;
  4551. gibc->set_active(true);
  4552. }
  4553. if (gibc->was_modified(reader)) {
  4554. int num_bytes = reader->get_data_size_bytes();
  4555. if (GLCAT.is_debug() && gl_debug_buffers) {
  4556. GLCAT.debug()
  4557. << "copying " << num_bytes
  4558. << " bytes into index buffer " << (int)gibc->_index << "\n";
  4559. }
  4560. if (num_bytes != 0) {
  4561. const unsigned char *client_pointer = reader->get_read_pointer(force);
  4562. if (client_pointer == NULL) {
  4563. return false;
  4564. }
  4565. PStatGPUTimer timer(this, _load_index_buffer_pcollector, reader->get_current_thread());
  4566. if (gibc->changed_size(reader) || gibc->changed_usage_hint(reader)) {
  4567. _glBufferData(GL_ELEMENT_ARRAY_BUFFER, num_bytes, client_pointer,
  4568. get_usage(reader->get_usage_hint()));
  4569. } else {
  4570. _glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, num_bytes,
  4571. client_pointer);
  4572. }
  4573. _data_transferred_pcollector.add_level(num_bytes);
  4574. }
  4575. gibc->mark_loaded(reader);
  4576. }
  4577. gibc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  4578. maybe_gl_finish();
  4579. report_my_gl_errors();
  4580. return true;
  4581. }
  4582. ////////////////////////////////////////////////////////////////////
  4583. // Function: GLGraphicsStateGuardian::release_index_buffer
  4584. // Access: Public, Virtual
  4585. // Description: Frees the GL resources previously allocated for the
  4586. // data. This function should never be called
  4587. // directly; instead, call Data::release() (or simply
  4588. // let the Data destruct).
  4589. ////////////////////////////////////////////////////////////////////
  4590. void CLP(GraphicsStateGuardian)::
  4591. release_index_buffer(IndexBufferContext *ibc) {
  4592. nassertv(_supports_buffers);
  4593. CLP(IndexBufferContext) *gibc = DCAST(CLP(IndexBufferContext), ibc);
  4594. if (GLCAT.is_debug() && gl_debug_buffers) {
  4595. GLCAT.debug()
  4596. << "deleting index buffer " << (int)gibc->_index << "\n";
  4597. }
  4598. // Make sure the buffer is unbound before we delete it. Not
  4599. // strictly necessary according to the OpenGL spec, but it might
  4600. // help out a flaky driver, and we need to keep our internal state
  4601. // consistent anyway.
  4602. if (_current_ibuffer_index == gibc->_index) {
  4603. if (GLCAT.is_spam() && gl_debug_buffers) {
  4604. GLCAT.spam()
  4605. << "unbinding index buffer\n";
  4606. }
  4607. _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  4608. _current_ibuffer_index = 0;
  4609. }
  4610. _glDeleteBuffers(1, &gibc->_index);
  4611. report_my_gl_errors();
  4612. gibc->_index = 0;
  4613. delete gibc;
  4614. }
  4615. ////////////////////////////////////////////////////////////////////
  4616. // Function: GLGraphicsStateGuardian::setup_primitive
  4617. // Access: Public
  4618. // Description: Internal function to bind a buffer object for the
  4619. // indicated primitive's index list, if appropriate, or
  4620. // to unbind a buffer object if it should be rendered
  4621. // from client memory.
  4622. //
  4623. // If the buffer object is bound, this function sets
  4624. // client_pointer to NULL (representing the start of the
  4625. // buffer object in server memory); if the buffer object
  4626. // is not bound, this function sets client_pointer to to
  4627. // the data array in client memory, that is, the data
  4628. // array passed in.
  4629. //
  4630. // If force is not true, the function may return false
  4631. // indicating the data is not currently available.
  4632. ////////////////////////////////////////////////////////////////////
  4633. bool CLP(GraphicsStateGuardian)::
  4634. setup_primitive(const unsigned char *&client_pointer,
  4635. const GeomPrimitivePipelineReader *reader,
  4636. bool force) {
  4637. if (!_supports_buffers) {
  4638. // No support for buffer objects; always render from client.
  4639. client_pointer = reader->get_read_pointer(force);
  4640. return (client_pointer != NULL);
  4641. }
  4642. if (!vertex_buffers || _geom_display_list != 0 ||
  4643. reader->get_usage_hint() == Geom::UH_client) {
  4644. // The array specifies client rendering only, or buffer objects
  4645. // are configured off.
  4646. if (_current_ibuffer_index != 0) {
  4647. if (GLCAT.is_spam() && gl_debug_buffers) {
  4648. GLCAT.spam()
  4649. << "unbinding index buffer\n";
  4650. }
  4651. _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  4652. _current_ibuffer_index = 0;
  4653. }
  4654. client_pointer = reader->get_read_pointer(force);
  4655. return (client_pointer != NULL);
  4656. }
  4657. // Prepare the buffer object and bind it.
  4658. IndexBufferContext *ibc = reader->prepare_now(get_prepared_objects(), this);
  4659. nassertr(ibc != (IndexBufferContext *)NULL, false);
  4660. if (!apply_index_buffer(ibc, reader, force)) {
  4661. return false;
  4662. }
  4663. // NULL is the OpenGL convention for the first byte of the buffer object.
  4664. client_pointer = NULL;
  4665. return true;
  4666. }
  4667. #ifndef OPENGLES
  4668. ////////////////////////////////////////////////////////////////////
  4669. // Function: GLGraphicsStateGuardian::begin_occlusion_query
  4670. // Access: Public, Virtual
  4671. // Description: Begins a new occlusion query. After this call, you
  4672. // may call begin_draw_primitives() and
  4673. // draw_triangles()/draw_whatever() repeatedly.
  4674. // Eventually, you should call end_occlusion_query()
  4675. // before the end of the frame; that will return a new
  4676. // OcclusionQueryContext object that will tell you how
  4677. // many pixels represented by the bracketed geometry
  4678. // passed the depth test.
  4679. //
  4680. // It is not valid to call begin_occlusion_query()
  4681. // between another begin_occlusion_query()
  4682. // .. end_occlusion_query() sequence.
  4683. ////////////////////////////////////////////////////////////////////
  4684. void CLP(GraphicsStateGuardian)::
  4685. begin_occlusion_query() {
  4686. nassertv(_supports_occlusion_query);
  4687. nassertv(_current_occlusion_query == (OcclusionQueryContext *)NULL);
  4688. PT(CLP(OcclusionQueryContext)) query = new CLP(OcclusionQueryContext)(this);
  4689. _glGenQueries(1, &query->_index);
  4690. if (GLCAT.is_debug()) {
  4691. GLCAT.debug()
  4692. << "beginning occlusion query index " << (int)query->_index << "\n";
  4693. }
  4694. _glBeginQuery(GL_SAMPLES_PASSED, query->_index);
  4695. _current_occlusion_query = query;
  4696. report_my_gl_errors();
  4697. }
  4698. #endif // !OPENGLES
  4699. #ifndef OPENGLES
  4700. ////////////////////////////////////////////////////////////////////
  4701. // Function: GLGraphicsStateGuardian::end_occlusion_query
  4702. // Access: Public, Virtual
  4703. // Description: Ends a previous call to begin_occlusion_query().
  4704. // This call returns the OcclusionQueryContext object
  4705. // that will (eventually) report the number of pixels
  4706. // that passed the depth test between the call to
  4707. // begin_occlusion_query() and end_occlusion_query().
  4708. ////////////////////////////////////////////////////////////////////
  4709. PT(OcclusionQueryContext) CLP(GraphicsStateGuardian)::
  4710. end_occlusion_query() {
  4711. nassertr(_current_occlusion_query != (OcclusionQueryContext *)NULL, NULL);
  4712. PT(OcclusionQueryContext) result = _current_occlusion_query;
  4713. GLuint index = DCAST(CLP(OcclusionQueryContext), result)->_index;
  4714. if (GLCAT.is_debug()) {
  4715. GLCAT.debug()
  4716. << "ending occlusion query index " << (int)index << "\n";
  4717. }
  4718. _current_occlusion_query = NULL;
  4719. _glEndQuery(GL_SAMPLES_PASSED);
  4720. // Temporary hack to try working around an apparent driver bug on
  4721. // iMacs. Occlusion queries sometimes incorrectly report 0 samples,
  4722. // unless we stall the pipe to keep fewer than a certain maximum
  4723. // number of queries pending at once.
  4724. static ConfigVariableInt limit_occlusion_queries("limit-occlusion-queries", 0);
  4725. if (limit_occlusion_queries > 0) {
  4726. if (index > (unsigned int)limit_occlusion_queries) {
  4727. PStatGPUTimer timer(this, _wait_occlusion_pcollector);
  4728. GLuint result;
  4729. _glGetQueryObjectuiv(index - (unsigned int)limit_occlusion_queries,
  4730. GL_QUERY_RESULT, &result);
  4731. }
  4732. }
  4733. report_my_gl_errors();
  4734. return result;
  4735. }
  4736. #endif // !OPENGLES
  4737. ////////////////////////////////////////////////////////////////////
  4738. // Function: GLGraphicsStateGuardian::issue_timer_query
  4739. // Access: Public, Virtual
  4740. // Description: Adds a timer query to the command stream, associated
  4741. // with the given PStats collector index.
  4742. ////////////////////////////////////////////////////////////////////
  4743. PT(TimerQueryContext) CLP(GraphicsStateGuardian)::
  4744. issue_timer_query(int pstats_index) {
  4745. #if defined(DO_PSTATS) && !defined(OPENGLES)
  4746. nassertr(_supports_timer_query, NULL);
  4747. PT(CLP(TimerQueryContext)) query;
  4748. // Hack
  4749. if (pstats_index == _command_latency_pcollector.get_index()) {
  4750. query = new CLP(LatencyQueryContext)(this, pstats_index);
  4751. } else {
  4752. query = new CLP(TimerQueryContext)(this, pstats_index);
  4753. }
  4754. if (_deleted_queries.size() >= 1) {
  4755. query->_index = _deleted_queries.back();
  4756. _deleted_queries.pop_back();
  4757. } else {
  4758. _glGenQueries(1, &query->_index);
  4759. if (GLCAT.is_spam()) {
  4760. GLCAT.spam() << "Generating query for " << pstats_index
  4761. << ": " << query->_index << "\n";
  4762. }
  4763. }
  4764. // Issue the timestamp query.
  4765. _glQueryCounter(query->_index, GL_TIMESTAMP);
  4766. if (_use_object_labels) {
  4767. // Assign a label to it based on the PStatCollector name.
  4768. const PStatClient *client = PStatClient::get_global_pstats();
  4769. string name = client->get_collector_fullname(pstats_index & 0x7fff);
  4770. _glObjectLabel(GL_QUERY, query->_index, name.size(), name.data());
  4771. }
  4772. _pending_timer_queries.push_back((TimerQueryContext *)query);
  4773. return (TimerQueryContext *)query;
  4774. #else
  4775. return NULL;
  4776. #endif
  4777. }
  4778. #ifndef OPENGLES
  4779. ////////////////////////////////////////////////////////////////////
  4780. // Function: GLGraphicsStateGuardian::dispatch_compute
  4781. // Access: Public, Virtual
  4782. // Description: Dispatches a currently bound compute shader using
  4783. // the given work group counts.
  4784. ////////////////////////////////////////////////////////////////////
  4785. void CLP(GraphicsStateGuardian)::
  4786. dispatch_compute(int num_groups_x, int num_groups_y, int num_groups_z) {
  4787. maybe_gl_finish();
  4788. PStatGPUTimer timer(this, _compute_dispatch_pcollector);
  4789. nassertv(_supports_compute_shaders);
  4790. nassertv(_current_shader_context != NULL);
  4791. _glDispatchCompute(num_groups_x, num_groups_y, num_groups_z);
  4792. maybe_gl_finish();
  4793. }
  4794. #endif // !OPENGLES
  4795. ////////////////////////////////////////////////////////////////////
  4796. // Function: GLGraphicsStateGuardian::make_geom_munger
  4797. // Access: Public, Virtual
  4798. // Description: Creates a new GeomMunger object to munge vertices
  4799. // appropriate to this GSG for the indicated state.
  4800. ////////////////////////////////////////////////////////////////////
  4801. PT(GeomMunger) CLP(GraphicsStateGuardian)::
  4802. make_geom_munger(const RenderState *state, Thread *current_thread) {
  4803. PT(CLP(GeomMunger)) munger = new CLP(GeomMunger)(this, state);
  4804. return GeomMunger::register_munger(munger, current_thread);
  4805. }
  4806. ////////////////////////////////////////////////////////////////////
  4807. // Function: GLGraphicsStateGuardian::compute_distance_to
  4808. // Access: Public, Virtual
  4809. // Description: This function will compute the distance to the
  4810. // indicated point, assumed to be in eye coordinates,
  4811. // from the camera plane. The point is assumed to be
  4812. // in the GSG's internal coordinate system.
  4813. ////////////////////////////////////////////////////////////////////
  4814. PN_stdfloat CLP(GraphicsStateGuardian)::
  4815. compute_distance_to(const LPoint3 &point) const {
  4816. return -point[2];
  4817. }
  4818. ////////////////////////////////////////////////////////////////////
  4819. // Function: GLGraphicsStateGuardian::framebuffer_copy_to_texture
  4820. // Access: Public, Virtual
  4821. // Description: Copy the pixels within the indicated display
  4822. // region from the framebuffer into texture memory.
  4823. //
  4824. // If z > -1, it is the cube map index or layer index
  4825. // into which to copy.
  4826. ////////////////////////////////////////////////////////////////////
  4827. bool CLP(GraphicsStateGuardian)::
  4828. framebuffer_copy_to_texture(Texture *tex, int view, int z,
  4829. const DisplayRegion *dr, const RenderBuffer &rb) {
  4830. nassertr(tex != NULL && dr != NULL, false);
  4831. set_read_buffer(rb._buffer_type);
  4832. clear_color_write_mask();
  4833. int xo, yo, w, h;
  4834. dr->get_region_pixels(xo, yo, w, h);
  4835. tex->set_size_padded(w, h, tex->get_z_size());
  4836. if (tex->get_compression() == Texture::CM_default) {
  4837. // Unless the user explicitly turned on texture compression, turn
  4838. // it off for the copy-to-texture case.
  4839. tex->set_compression(Texture::CM_off);
  4840. }
  4841. // Sanity check everything.
  4842. if (z >= 0) {
  4843. if (z >= tex->get_z_size()) {
  4844. // This can happen, when textures with different layer counts
  4845. // are attached to a buffer. We simply ignore this if it happens.
  4846. return false;
  4847. }
  4848. if ((w != tex->get_x_size()) ||
  4849. (h != tex->get_y_size())) {
  4850. return false;
  4851. }
  4852. if (tex->get_texture_type() == Texture::TT_cube_map) {
  4853. if (!_supports_cube_map) {
  4854. return false;
  4855. }
  4856. nassertr(z < 6, false);
  4857. if (w != h) {
  4858. return false;
  4859. }
  4860. } else if (tex->get_texture_type() == Texture::TT_3d_texture) {
  4861. if (!_supports_3d_texture) {
  4862. return false;
  4863. }
  4864. } else if (tex->get_texture_type() == Texture::TT_2d_texture_array) {
  4865. if (!_supports_2d_texture_array) {
  4866. return false;
  4867. }
  4868. } else {
  4869. GLCAT.error()
  4870. << "Don't know how to copy framebuffer to texture " << *tex << "\n";
  4871. }
  4872. } else {
  4873. nassertr(tex->get_texture_type() == Texture::TT_2d_texture, false);
  4874. }
  4875. // Match framebuffer format if necessary.
  4876. if (tex->get_match_framebuffer_format()) {
  4877. switch (tex->get_format()) {
  4878. case Texture::F_depth_component:
  4879. case Texture::F_depth_component16:
  4880. case Texture::F_depth_component24:
  4881. case Texture::F_depth_component32:
  4882. case Texture::F_depth_stencil:
  4883. // Don't remap if we're one of these special format.
  4884. break;
  4885. default:
  4886. // If the texture is a color format, we want to match the
  4887. // presence of sRGB and alpha according to the framebuffer.
  4888. if (_current_properties->get_srgb_color()) {
  4889. if (_current_properties->get_alpha_bits()) {
  4890. tex->set_format(Texture::F_srgb_alpha);
  4891. } else {
  4892. tex->set_format(Texture::F_srgb);
  4893. }
  4894. } else {
  4895. if (_current_properties->get_alpha_bits()) {
  4896. tex->set_format(Texture::F_rgba);
  4897. } else {
  4898. tex->set_format(Texture::F_rgb);
  4899. }
  4900. }
  4901. }
  4902. }
  4903. TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this);
  4904. nassertr(tc != (TextureContext *)NULL, false);
  4905. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
  4906. apply_texture(gtc);
  4907. bool needs_reload = specify_texture(gtc, tex->get_default_sampler());
  4908. GLenum target = get_texture_target(tex->get_texture_type());
  4909. GLint internal_format = get_internal_image_format(tex);
  4910. int width = tex->get_x_size();
  4911. int height = tex->get_y_size();
  4912. int depth = tex->get_z_size();
  4913. bool uses_mipmaps = tex->uses_mipmaps() && !gl_ignore_mipmaps;
  4914. if (uses_mipmaps) {
  4915. if (_supports_generate_mipmap) {
  4916. #ifndef OPENGLES_2
  4917. if (_glGenerateMipmap == NULL) {
  4918. glTexParameteri(target, GL_GENERATE_MIPMAP, true);
  4919. }
  4920. #endif
  4921. } else {
  4922. // If we can't auto-generate mipmaps, do without mipmaps.
  4923. glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  4924. uses_mipmaps = false;
  4925. }
  4926. }
  4927. bool new_image = needs_reload || gtc->was_image_modified();
  4928. if (z >= 0) {
  4929. if (target == GL_TEXTURE_CUBE_MAP) {
  4930. // Copy to a cube map face, which is treated as a 2D texture.
  4931. target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + z;
  4932. depth = 1;
  4933. z = -1;
  4934. // Cube map faces seem to have trouble with CopyTexSubImage, so we
  4935. // always reload the image.
  4936. new_image = true;
  4937. }
  4938. }
  4939. if (!gtc->_has_storage ||
  4940. internal_format != gtc->_internal_format ||
  4941. uses_mipmaps != gtc->_uses_mipmaps ||
  4942. width != gtc->_width ||
  4943. height != gtc->_height ||
  4944. depth != gtc->_depth) {
  4945. // If the texture properties have changed, we need to reload the
  4946. // image.
  4947. new_image = true;
  4948. }
  4949. if (new_image && gtc->_immutable) {
  4950. gtc->reset_data();
  4951. glBindTexture(target, gtc->_index);
  4952. }
  4953. #ifndef OPENGLES
  4954. if (gtc->needs_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT)) {
  4955. // Make sure that any incoherent writes to this texture have been synced.
  4956. issue_memory_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
  4957. }
  4958. #endif
  4959. if (z >= 0) {
  4960. #ifndef OPENGLES_1
  4961. if (new_image) {
  4962. // These won't be used because we pass a NULL image, but we still
  4963. // have to specify them. Might as well use the actual values.
  4964. GLint external_format = get_external_image_format(tex);
  4965. GLint component_type = get_component_type(tex->get_component_type());
  4966. _glTexImage3D(target, 0, internal_format, width, height, depth, 0, external_format, component_type, NULL);
  4967. }
  4968. _glCopyTexSubImage3D(target, 0, 0, 0, z, xo, yo, w, h);
  4969. #endif
  4970. } else {
  4971. if (new_image) {
  4972. // We have to create a new image.
  4973. // It seems that OpenGL accepts a size higher than the framebuffer,
  4974. // but if we run into trouble we'll have to replace this with
  4975. // something smarter.
  4976. glCopyTexImage2D(target, 0, internal_format, xo, yo, width, height, 0);
  4977. } else {
  4978. // We can overlay the existing image.
  4979. glCopyTexSubImage2D(target, 0, 0, 0, xo, yo, w, h);
  4980. }
  4981. }
  4982. if (uses_mipmaps && _glGenerateMipmap != NULL) {
  4983. glEnable(target);
  4984. _glGenerateMipmap(target);
  4985. glDisable(target);
  4986. }
  4987. gtc->_has_storage = true;
  4988. gtc->_uses_mipmaps = uses_mipmaps;
  4989. gtc->_internal_format = internal_format;
  4990. gtc->_width = width;
  4991. gtc->_height = height;
  4992. gtc->_depth = depth;
  4993. gtc->mark_loaded();
  4994. gtc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  4995. report_my_gl_errors();
  4996. // Force reload of texture state, since we've just monkeyed with it.
  4997. _state_mask.clear_bit(TextureAttrib::get_class_slot());
  4998. return true;
  4999. }
  5000. ////////////////////////////////////////////////////////////////////
  5001. // Function: GLGraphicsStateGuardian::framebuffer_copy_to_ram
  5002. // Access: Public, Virtual
  5003. // Description: Copy the pixels within the indicated display region
  5004. // from the framebuffer into system memory, not texture
  5005. // memory. Returns true on success, false on failure.
  5006. //
  5007. // This completely redefines the ram image of the
  5008. // indicated texture.
  5009. ////////////////////////////////////////////////////////////////////
  5010. bool CLP(GraphicsStateGuardian)::
  5011. framebuffer_copy_to_ram(Texture *tex, int view, int z,
  5012. const DisplayRegion *dr, const RenderBuffer &rb) {
  5013. nassertr(tex != NULL && dr != NULL, false);
  5014. set_read_buffer(rb._buffer_type);
  5015. glPixelStorei(GL_PACK_ALIGNMENT, 1);
  5016. clear_color_write_mask();
  5017. // Bug fix for RE, RE2, and VTX - need to disable texturing in order
  5018. // for glReadPixels() to work
  5019. // NOTE: reading the depth buffer is *much* slower than reading the
  5020. // color buffer
  5021. set_state_and_transform(RenderState::make_empty(), _internal_transform);
  5022. int xo, yo, w, h;
  5023. dr->get_region_pixels(xo, yo, w, h);
  5024. Texture::ComponentType component_type = tex->get_component_type();
  5025. bool color_mode = false;
  5026. Texture::Format format = tex->get_format();
  5027. switch (format) {
  5028. case Texture::F_depth_stencil:
  5029. if (_current_properties->get_float_depth()) {
  5030. component_type = Texture::T_float;
  5031. } else {
  5032. component_type = Texture::T_unsigned_int_24_8;
  5033. }
  5034. break;
  5035. case Texture::F_depth_component:
  5036. if (_current_properties->get_float_depth()) {
  5037. component_type = Texture::T_float;
  5038. } else if (_current_properties->get_depth_bits() <= 8) {
  5039. component_type = Texture::T_unsigned_byte;
  5040. } else if (_current_properties->get_depth_bits() <= 16) {
  5041. component_type = Texture::T_unsigned_short;
  5042. } else {
  5043. component_type = Texture::T_float;
  5044. }
  5045. break;
  5046. default:
  5047. color_mode = true;
  5048. if (_current_properties->get_srgb_color()) {
  5049. if (_current_properties->get_alpha_bits()) {
  5050. format = Texture::F_srgb_alpha;
  5051. } else {
  5052. format = Texture::F_srgb;
  5053. }
  5054. } else {
  5055. if (_current_properties->get_alpha_bits()) {
  5056. format = Texture::F_rgba;
  5057. } else {
  5058. format = Texture::F_rgb;
  5059. }
  5060. }
  5061. if (_current_properties->get_float_color()) {
  5062. component_type = Texture::T_float;
  5063. } else if (_current_properties->get_color_bits() <= 24) {
  5064. component_type = Texture::T_unsigned_byte;
  5065. } else {
  5066. component_type = Texture::T_unsigned_short;
  5067. }
  5068. }
  5069. Texture::TextureType texture_type;
  5070. int z_size;
  5071. //TODO: should be extended to support 3D textures and 2D arrays.
  5072. if (z >= 0) {
  5073. texture_type = Texture::TT_cube_map;
  5074. z_size = 6;
  5075. } else {
  5076. texture_type = Texture::TT_2d_texture;
  5077. z_size = 1;
  5078. }
  5079. if (tex->get_x_size() != w || tex->get_y_size() != h ||
  5080. tex->get_z_size() != z_size ||
  5081. tex->get_component_type() != component_type ||
  5082. tex->get_format() != format ||
  5083. tex->get_texture_type() != texture_type) {
  5084. // Re-setup the texture; its properties have changed.
  5085. tex->setup_texture(texture_type, w, h, z_size,
  5086. component_type, format);
  5087. }
  5088. nassertr(z < tex->get_z_size(), false);
  5089. GLenum external_format = get_external_image_format(tex);
  5090. if (GLCAT.is_spam()) {
  5091. GLCAT.spam()
  5092. << "glReadPixels(" << xo << ", " << yo << ", " << w << ", " << h << ", ";
  5093. switch (external_format) {
  5094. case GL_DEPTH_COMPONENT:
  5095. GLCAT.spam(false) << "GL_DEPTH_COMPONENT, ";
  5096. break;
  5097. case GL_DEPTH_STENCIL:
  5098. GLCAT.spam(false) << "GL_DEPTH_STENCIL, ";
  5099. break;
  5100. case GL_RGB:
  5101. GLCAT.spam(false) << "GL_RGB, ";
  5102. break;
  5103. case GL_RGBA:
  5104. GLCAT.spam(false) << "GL_RGBA, ";
  5105. break;
  5106. #ifndef OPENGLES
  5107. case GL_BGR:
  5108. GLCAT.spam(false) << "GL_BGR, ";
  5109. break;
  5110. #endif
  5111. case GL_BGRA:
  5112. GLCAT.spam(false) << "GL_BGRA, ";
  5113. break;
  5114. default:
  5115. GLCAT.spam(false) << "unknown, ";
  5116. break;
  5117. }
  5118. switch (get_component_type(component_type)) {
  5119. case GL_UNSIGNED_BYTE:
  5120. GLCAT.spam(false) << "GL_UNSIGNED_BYTE";
  5121. break;
  5122. case GL_UNSIGNED_SHORT:
  5123. GLCAT.spam(false) << "GL_UNSIGNED_SHORT";
  5124. break;
  5125. case GL_FLOAT:
  5126. GLCAT.spam(false) << "GL_FLOAT";
  5127. break;
  5128. #ifndef OPENGLES_1
  5129. case GL_INT:
  5130. GLCAT.spam(false) << "GL_INT";
  5131. break;
  5132. #endif
  5133. default:
  5134. GLCAT.spam(false) << "unknown";
  5135. break;
  5136. }
  5137. GLCAT.spam(false)
  5138. << ")" << endl;
  5139. }
  5140. unsigned char *image_ptr = tex->modify_ram_image();
  5141. size_t image_size = tex->get_ram_image_size();
  5142. if (z >= 0 || view > 0) {
  5143. image_size = tex->get_expected_ram_page_size();
  5144. if (z >= 0) {
  5145. image_ptr += z * image_size;
  5146. }
  5147. if (view > 0) {
  5148. image_ptr += (view * tex->get_z_size()) * image_size;
  5149. }
  5150. }
  5151. glReadPixels(xo, yo, w, h, external_format,
  5152. get_component_type(component_type), image_ptr);
  5153. // We may have to reverse the byte ordering of the image if GL
  5154. // didn't do it for us.
  5155. if (color_mode && !_supports_bgr) {
  5156. PTA_uchar new_image;
  5157. const unsigned char *result =
  5158. fix_component_ordering(new_image, image_ptr, image_size,
  5159. external_format, tex);
  5160. if (result != image_ptr) {
  5161. memcpy(image_ptr, result, image_size);
  5162. }
  5163. }
  5164. report_my_gl_errors();
  5165. return true;
  5166. }
  5167. #ifndef OPENGLES_2
  5168. ////////////////////////////////////////////////////////////////////
  5169. // Function: GLGraphicsStateGuardian::apply_fog
  5170. // Access: Public, Virtual
  5171. // Description:
  5172. ////////////////////////////////////////////////////////////////////
  5173. void CLP(GraphicsStateGuardian)::
  5174. apply_fog(Fog *fog) {
  5175. Fog::Mode fmode = fog->get_mode();
  5176. glFogf(GL_FOG_MODE, get_fog_mode_type(fmode));
  5177. if (fmode == Fog::M_linear) {
  5178. PN_stdfloat onset, opaque;
  5179. fog->get_linear_range(onset, opaque);
  5180. glFogf(GL_FOG_START, onset);
  5181. glFogf(GL_FOG_END, opaque);
  5182. } else {
  5183. // Exponential fog is always camera-relative.
  5184. glFogf(GL_FOG_DENSITY, fog->get_exp_density());
  5185. }
  5186. call_glFogfv(GL_FOG_COLOR, fog->get_color());
  5187. report_my_gl_errors();
  5188. }
  5189. #endif // OPENGLES_2
  5190. ////////////////////////////////////////////////////////////////////
  5191. // Function: GLGraphicsStateGuardian::do_issue_transform
  5192. // Access: Protected
  5193. // Description: Sends the indicated transform matrix to the graphics
  5194. // API to be applied to future vertices.
  5195. //
  5196. // This transform is the internal_transform, already
  5197. // converted into the GSG's internal coordinate system.
  5198. ////////////////////////////////////////////////////////////////////
  5199. void CLP(GraphicsStateGuardian)::
  5200. do_issue_transform() {
  5201. #ifndef OPENGLES_2
  5202. // OpenGL ES 2 does not support glLoadMatrix.
  5203. const TransformState *transform = _internal_transform;
  5204. if (GLCAT.is_spam()) {
  5205. GLCAT.spam()
  5206. << "glLoadMatrix(GL_MODELVIEW): " << transform->get_mat() << endl;
  5207. }
  5208. DO_PSTATS_STUFF(_transform_state_pcollector.add_level(1));
  5209. glMatrixMode(GL_MODELVIEW);
  5210. GLPf(LoadMatrix)(transform->get_mat().get_data());
  5211. if (_auto_rescale_normal) {
  5212. do_auto_rescale_normal();
  5213. }
  5214. #endif
  5215. _transform_stale = false;
  5216. #ifndef OPENGLES_1
  5217. if (_current_shader_context) {
  5218. _current_shader_context->issue_parameters(Shader::SSD_transform);
  5219. }
  5220. #endif
  5221. report_my_gl_errors();
  5222. }
  5223. #ifndef OPENGLES_2
  5224. ////////////////////////////////////////////////////////////////////
  5225. // Function: GLGraphicsStateGuardian::do_issue_shade_model
  5226. // Access: Protected
  5227. // Description:
  5228. ////////////////////////////////////////////////////////////////////
  5229. void CLP(GraphicsStateGuardian)::
  5230. do_issue_shade_model() {
  5231. const ShadeModelAttrib *target_shade_model;
  5232. _target_rs->get_attrib_def(target_shade_model);
  5233. switch (target_shade_model->get_mode()) {
  5234. case ShadeModelAttrib::M_smooth:
  5235. glShadeModel(GL_SMOOTH);
  5236. _flat_shade_model = false;
  5237. break;
  5238. case ShadeModelAttrib::M_flat:
  5239. glShadeModel(GL_FLAT);
  5240. _flat_shade_model = true;
  5241. break;
  5242. }
  5243. }
  5244. #endif // !OPENGLES_2
  5245. ////////////////////////////////////////////////////////////////////
  5246. // Function: GLGraphicsStateGuardian::do_issue_shader
  5247. // Access: Protected
  5248. // Description:
  5249. ////////////////////////////////////////////////////////////////////
  5250. void CLP(GraphicsStateGuardian)::
  5251. do_issue_shader(bool state_has_changed) {
  5252. #ifndef OPENGLES_1
  5253. ShaderContext *context = 0;
  5254. Shader *shader = (Shader *)(_target_shader->get_shader());
  5255. #ifdef OPENGLES_2
  5256. // If we don't have a shader, apply the default shader.
  5257. if (!shader) {
  5258. shader = _default_shader;
  5259. }
  5260. #endif
  5261. if (shader) {
  5262. context = shader->prepare_now(get_prepared_objects(), this);
  5263. }
  5264. #ifdef OPENGLES_2
  5265. // If it failed, try applying the default shader.
  5266. if (shader != _default_shader && (context == 0 || !context->valid())) {
  5267. shader = _default_shader;
  5268. context = shader->prepare_now(get_prepared_objects(), this);
  5269. }
  5270. #endif
  5271. if (context == 0 || (context->valid() == false)) {
  5272. if (_current_shader_context != 0) {
  5273. _current_shader_context->unbind();
  5274. _current_shader = 0;
  5275. _current_shader_context = 0;
  5276. }
  5277. } else {
  5278. if (context != _current_shader_context) {
  5279. // Use a completely different shader than before.
  5280. // Unbind old shader, bind the new one.
  5281. if (_current_shader_context != 0) {
  5282. _current_shader_context->unbind();
  5283. }
  5284. context->bind();
  5285. _current_shader = shader;
  5286. _current_shader_context = context;
  5287. context->issue_parameters(Shader::SSD_shaderinputs);
  5288. } else {
  5289. if (state_has_changed) {
  5290. // Use the same shader as before, but with new input arguments.
  5291. context->issue_parameters(Shader::SSD_shaderinputs);
  5292. }
  5293. }
  5294. }
  5295. report_my_gl_errors();
  5296. #endif
  5297. }
  5298. ////////////////////////////////////////////////////////////////////
  5299. // Function: GLGraphicsStateGuardian::do_issue_render_mode
  5300. // Access: Protected
  5301. // Description:
  5302. ////////////////////////////////////////////////////////////////////
  5303. void CLP(GraphicsStateGuardian)::
  5304. do_issue_render_mode() {
  5305. const RenderModeAttrib *target_render_mode;
  5306. _target_rs->get_attrib_def(target_render_mode);
  5307. _render_mode = target_render_mode->get_mode();
  5308. PN_stdfloat thickness = target_render_mode->get_thickness();
  5309. _point_perspective = target_render_mode->get_perspective();
  5310. #ifndef OPENGLES // glPolygonMode not supported by OpenGL ES.
  5311. switch (_render_mode) {
  5312. case RenderModeAttrib::M_unchanged:
  5313. case RenderModeAttrib::M_filled:
  5314. case RenderModeAttrib::M_filled_flat:
  5315. glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  5316. break;
  5317. case RenderModeAttrib::M_wireframe:
  5318. glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  5319. break;
  5320. case RenderModeAttrib::M_point:
  5321. glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
  5322. break;
  5323. default:
  5324. GLCAT.error()
  5325. << "Unknown render mode " << (int)_render_mode << endl;
  5326. }
  5327. #endif // OPENGLES
  5328. // The thickness affects both the line width and the point size.
  5329. if (thickness != _point_size) {
  5330. glLineWidth(_point_size);
  5331. #ifndef OPENGLES_2
  5332. glPointSize(_point_size);
  5333. #endif
  5334. _point_size = thickness;
  5335. }
  5336. report_my_gl_errors();
  5337. do_point_size();
  5338. }
  5339. ////////////////////////////////////////////////////////////////////
  5340. // Function: GLGraphicsStateGuardian::do_issue_antialias
  5341. // Access: Protected
  5342. // Description:
  5343. ////////////////////////////////////////////////////////////////////
  5344. void CLP(GraphicsStateGuardian)::
  5345. do_issue_antialias() {
  5346. const AntialiasAttrib *target_antialias;
  5347. _target_rs->get_attrib_def(target_antialias);
  5348. if (target_antialias->get_mode_type() == AntialiasAttrib::M_auto) {
  5349. // In this special mode, we must enable antialiasing on a
  5350. // case-by-case basis, because we enable it differently for
  5351. // polygons and for points and lines.
  5352. _auto_antialias_mode = true;
  5353. } else {
  5354. // Otherwise, explicitly enable or disable according to the bits
  5355. // that are set. But if multisample is requested and supported,
  5356. // don't use the other bits at all (they will be ignored by GL
  5357. // anyway).
  5358. _auto_antialias_mode = false;
  5359. unsigned short mode = target_antialias->get_mode();
  5360. if (_supports_multisample &&
  5361. (mode & AntialiasAttrib::M_multisample) != 0) {
  5362. enable_multisample_antialias(true);
  5363. } else {
  5364. enable_multisample_antialias(false);
  5365. enable_line_smooth((mode & AntialiasAttrib::M_line) != 0);
  5366. enable_point_smooth((mode & AntialiasAttrib::M_point) != 0);
  5367. enable_polygon_smooth((mode & AntialiasAttrib::M_polygon) != 0);
  5368. }
  5369. }
  5370. #ifndef OPENGLES_2
  5371. switch (target_antialias->get_mode_quality()) {
  5372. case AntialiasAttrib::M_faster:
  5373. glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST);
  5374. glHint(GL_POINT_SMOOTH_HINT, GL_FASTEST);
  5375. #ifndef OPENGLES
  5376. glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
  5377. #endif // OPENGLES
  5378. break;
  5379. case AntialiasAttrib::M_better:
  5380. glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
  5381. glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
  5382. #ifndef OPENGLES
  5383. glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
  5384. #endif // OPENGLES
  5385. break;
  5386. default:
  5387. glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
  5388. glHint(GL_POINT_SMOOTH_HINT, GL_DONT_CARE);
  5389. #ifndef OPENGLES
  5390. glHint(GL_POLYGON_SMOOTH_HINT, GL_DONT_CARE);
  5391. #endif // OPENGLES
  5392. break;
  5393. }
  5394. #endif // !OPENGLES_2
  5395. report_my_gl_errors();
  5396. }
  5397. #ifndef OPENGLES_2 // OpenGL ES 2.0 doesn't support rescaling normals.
  5398. ////////////////////////////////////////////////////////////////////
  5399. // Function: GLGraphicsStateGuardian::do_issue_rescale_normal
  5400. // Access: Protected
  5401. // Description:
  5402. ////////////////////////////////////////////////////////////////////
  5403. void CLP(GraphicsStateGuardian)::
  5404. do_issue_rescale_normal() {
  5405. const RescaleNormalAttrib *target_rescale_normal;
  5406. _target_rs->get_attrib_def(target_rescale_normal);
  5407. RescaleNormalAttrib::Mode mode = target_rescale_normal->get_mode();
  5408. _auto_rescale_normal = false;
  5409. switch (mode) {
  5410. case RescaleNormalAttrib::M_none:
  5411. glDisable(GL_NORMALIZE);
  5412. if (_supports_rescale_normal && support_rescale_normal) {
  5413. glDisable(GL_RESCALE_NORMAL);
  5414. }
  5415. break;
  5416. case RescaleNormalAttrib::M_rescale:
  5417. if (_supports_rescale_normal && support_rescale_normal) {
  5418. glEnable(GL_RESCALE_NORMAL);
  5419. glDisable(GL_NORMALIZE);
  5420. } else {
  5421. glEnable(GL_NORMALIZE);
  5422. }
  5423. break;
  5424. case RescaleNormalAttrib::M_normalize:
  5425. glEnable(GL_NORMALIZE);
  5426. if (_supports_rescale_normal && support_rescale_normal) {
  5427. glDisable(GL_RESCALE_NORMAL);
  5428. }
  5429. break;
  5430. case RescaleNormalAttrib::M_auto:
  5431. _auto_rescale_normal = true;
  5432. do_auto_rescale_normal();
  5433. break;
  5434. default:
  5435. GLCAT.error()
  5436. << "Unknown rescale_normal mode " << (int)mode << endl;
  5437. }
  5438. report_my_gl_errors();
  5439. }
  5440. #endif // !OPENGLES_2
  5441. // PandaCompareFunc - 1 + 0x200 === GL_NEVER, etc. order is sequential
  5442. #define PANDA_TO_GL_COMPAREFUNC(PANDACMPFUNC) (PANDACMPFUNC-1 +0x200)
  5443. ////////////////////////////////////////////////////////////////////
  5444. // Function: GLGraphicsStateGuardian::do_issue_depth_test
  5445. // Access: Protected
  5446. // Description:
  5447. ////////////////////////////////////////////////////////////////////
  5448. void CLP(GraphicsStateGuardian)::
  5449. do_issue_depth_test() {
  5450. const DepthTestAttrib *target_depth_test;
  5451. _target_rs->get_attrib_def(target_depth_test);
  5452. DepthTestAttrib::PandaCompareFunc mode = target_depth_test->get_mode();
  5453. if (mode == DepthTestAttrib::M_none) {
  5454. enable_depth_test(false);
  5455. } else {
  5456. enable_depth_test(true);
  5457. glDepthFunc(PANDA_TO_GL_COMPAREFUNC(mode));
  5458. }
  5459. report_my_gl_errors();
  5460. }
  5461. #ifndef OPENGLES_2
  5462. ////////////////////////////////////////////////////////////////////
  5463. // Function: GLGraphicsStateGuardian::do_issue_alpha_test
  5464. // Access: Protected
  5465. // Description:
  5466. ////////////////////////////////////////////////////////////////////
  5467. void CLP(GraphicsStateGuardian)::
  5468. do_issue_alpha_test() {
  5469. if (_target_shader->get_flag(ShaderAttrib::F_subsume_alpha_test)) {
  5470. enable_alpha_test(false);
  5471. } else {
  5472. const AlphaTestAttrib *target_alpha_test;
  5473. _target_rs->get_attrib_def(target_alpha_test);
  5474. AlphaTestAttrib::PandaCompareFunc mode = target_alpha_test->get_mode();
  5475. if (mode == AlphaTestAttrib::M_none) {
  5476. enable_alpha_test(false);
  5477. } else {
  5478. nassertv(GL_NEVER == (AlphaTestAttrib::M_never-1+0x200));
  5479. glAlphaFunc(PANDA_TO_GL_COMPAREFUNC(mode), target_alpha_test->get_reference_alpha());
  5480. enable_alpha_test(true);
  5481. }
  5482. }
  5483. }
  5484. #endif // !OPENGLES_2
  5485. ////////////////////////////////////////////////////////////////////
  5486. // Function: GLGraphicsStateGuardian::do_issue_depth_write
  5487. // Access: Protected
  5488. // Description:
  5489. ////////////////////////////////////////////////////////////////////
  5490. void CLP(GraphicsStateGuardian)::
  5491. do_issue_depth_write() {
  5492. const DepthWriteAttrib *target_depth_write;
  5493. _target_rs->get_attrib_def(target_depth_write);
  5494. DepthWriteAttrib::Mode mode = target_depth_write->get_mode();
  5495. if (mode == DepthWriteAttrib::M_off) {
  5496. #ifdef GSG_VERBOSE
  5497. GLCAT.spam()
  5498. << "glDepthMask(GL_FALSE)" << endl;
  5499. #endif
  5500. glDepthMask(GL_FALSE);
  5501. } else {
  5502. #ifdef GSG_VERBOSE
  5503. GLCAT.spam()
  5504. << "glDepthMask(GL_TRUE)" << endl;
  5505. #endif
  5506. glDepthMask(GL_TRUE);
  5507. }
  5508. report_my_gl_errors();
  5509. }
  5510. ////////////////////////////////////////////////////////////////////
  5511. // Function: GLGraphicsStateGuardian::do_issue_cull_face
  5512. // Access: Protected
  5513. // Description:
  5514. ////////////////////////////////////////////////////////////////////
  5515. void CLP(GraphicsStateGuardian)::
  5516. do_issue_cull_face() {
  5517. const CullFaceAttrib *target_cull_face;
  5518. _target_rs->get_attrib_def(target_cull_face);
  5519. CullFaceAttrib::Mode mode = target_cull_face->get_effective_mode();
  5520. switch (mode) {
  5521. case CullFaceAttrib::M_cull_none:
  5522. glDisable(GL_CULL_FACE);
  5523. break;
  5524. case CullFaceAttrib::M_cull_clockwise:
  5525. glEnable(GL_CULL_FACE);
  5526. glCullFace(GL_BACK);
  5527. break;
  5528. case CullFaceAttrib::M_cull_counter_clockwise:
  5529. glEnable(GL_CULL_FACE);
  5530. glCullFace(GL_FRONT);
  5531. break;
  5532. default:
  5533. GLCAT.error()
  5534. << "invalid cull face mode " << (int)mode << endl;
  5535. break;
  5536. }
  5537. report_my_gl_errors();
  5538. }
  5539. #ifndef OPENGLES_2
  5540. ////////////////////////////////////////////////////////////////////
  5541. // Function: GLGraphicsStateGuardian::do_issue_fog
  5542. // Access: Protected
  5543. // Description:
  5544. ////////////////////////////////////////////////////////////////////
  5545. void CLP(GraphicsStateGuardian)::
  5546. do_issue_fog() {
  5547. const FogAttrib *target_fog;
  5548. _target_rs->get_attrib_def(target_fog);
  5549. if (!target_fog->is_off()) {
  5550. enable_fog(true);
  5551. Fog *fog = target_fog->get_fog();
  5552. nassertv(fog != (Fog *)NULL);
  5553. apply_fog(fog);
  5554. } else {
  5555. enable_fog(false);
  5556. }
  5557. report_my_gl_errors();
  5558. }
  5559. #endif // !OPENGLES_2
  5560. ////////////////////////////////////////////////////////////////////
  5561. // Function: GLGraphicsStateGuardian::do_issue_depth_offset
  5562. // Access: Protected
  5563. // Description:
  5564. ////////////////////////////////////////////////////////////////////
  5565. void CLP(GraphicsStateGuardian)::
  5566. do_issue_depth_offset() {
  5567. const DepthOffsetAttrib *target_depth_offset = (const DepthOffsetAttrib *)
  5568. _target_rs->get_attrib_def(DepthOffsetAttrib::get_class_slot());
  5569. int offset = target_depth_offset->get_offset();
  5570. if (offset != 0) {
  5571. // The relationship between these two parameters is a little
  5572. // unclear and poorly explained in the GL man pages.
  5573. glPolygonOffset((GLfloat) -offset, (GLfloat) -offset);
  5574. enable_polygon_offset(true);
  5575. } else {
  5576. enable_polygon_offset(false);
  5577. }
  5578. PN_stdfloat min_value = target_depth_offset->get_min_value();
  5579. PN_stdfloat max_value = target_depth_offset->get_max_value();
  5580. #ifdef GSG_VERBOSE
  5581. GLCAT.spam()
  5582. << "glDepthRange(" << min_value << ", " << max_value << ")" << endl;
  5583. #endif
  5584. #ifdef OPENGLES
  5585. // OpenGL ES uses a single-precision call.
  5586. glDepthRangef((GLclampf)min_value, (GLclampf)max_value);
  5587. #else
  5588. // Mainline OpenGL uses a double-precision call.
  5589. glDepthRange((GLclampd)min_value, (GLclampd)max_value);
  5590. #endif // OPENGLES
  5591. report_my_gl_errors();
  5592. }
  5593. #ifndef OPENGLES_2
  5594. ////////////////////////////////////////////////////////////////////
  5595. // Function: GLGraphicsStateGuardian::do_issue_material
  5596. // Access: Protected
  5597. // Description:
  5598. ////////////////////////////////////////////////////////////////////
  5599. void CLP(GraphicsStateGuardian)::
  5600. do_issue_material() {
  5601. static Material empty;
  5602. const Material *material;
  5603. const MaterialAttrib *target_material;
  5604. _target_rs->get_attrib_def(target_material);
  5605. if (target_material == (MaterialAttrib *)NULL ||
  5606. target_material->is_off()) {
  5607. material = &empty;
  5608. } else {
  5609. material = target_material->get_material();
  5610. }
  5611. bool has_material_force_color = _has_material_force_color;
  5612. #ifndef NDEBUG
  5613. if (_show_texture_usage) {
  5614. // In show_texture_usage mode, all colors are white, so as not
  5615. // to contaminate the texture color. This means we disable
  5616. // lighting materials too.
  5617. material = &empty;
  5618. has_material_force_color = false;
  5619. }
  5620. #endif // NDEBUG
  5621. #ifdef OPENGLES
  5622. const GLenum face = GL_FRONT_AND_BACK;
  5623. #else
  5624. GLenum face = material->get_twoside() ? GL_FRONT_AND_BACK : GL_FRONT;
  5625. #endif
  5626. call_glMaterialfv(face, GL_SPECULAR, material->get_specular());
  5627. call_glMaterialfv(face, GL_EMISSION, material->get_emission());
  5628. glMaterialf(face, GL_SHININESS, min(material->get_shininess(), (PN_stdfloat)128.0));
  5629. if (material->has_ambient() && material->has_diffuse()) {
  5630. // The material has both an ambient and diffuse specified. This
  5631. // means we do not need glMaterialColor().
  5632. glDisable(GL_COLOR_MATERIAL);
  5633. call_glMaterialfv(face, GL_AMBIENT, material->get_ambient());
  5634. call_glMaterialfv(face, GL_DIFFUSE, material->get_diffuse());
  5635. } else if (material->has_ambient()) {
  5636. // The material specifies an ambient, but not a diffuse component.
  5637. // The diffuse component comes from the object's color.
  5638. call_glMaterialfv(face, GL_AMBIENT, material->get_ambient());
  5639. if (has_material_force_color) {
  5640. glDisable(GL_COLOR_MATERIAL);
  5641. call_glMaterialfv(face, GL_DIFFUSE, _material_force_color);
  5642. } else {
  5643. #ifndef OPENGLES
  5644. glColorMaterial(face, GL_DIFFUSE);
  5645. #endif // OPENGLES
  5646. glEnable(GL_COLOR_MATERIAL);
  5647. }
  5648. } else if (material->has_diffuse()) {
  5649. // The material specifies a diffuse, but not an ambient component.
  5650. // The ambient component comes from the object's color.
  5651. call_glMaterialfv(face, GL_DIFFUSE, material->get_diffuse());
  5652. if (has_material_force_color) {
  5653. glDisable(GL_COLOR_MATERIAL);
  5654. call_glMaterialfv(face, GL_AMBIENT, _material_force_color);
  5655. } else {
  5656. #ifndef OPENGLES
  5657. glColorMaterial(face, GL_AMBIENT);
  5658. #endif // OPENGLES
  5659. glEnable(GL_COLOR_MATERIAL);
  5660. }
  5661. } else {
  5662. // The material specifies neither a diffuse nor an ambient
  5663. // component. Both components come from the object's color.
  5664. if (has_material_force_color) {
  5665. glDisable(GL_COLOR_MATERIAL);
  5666. call_glMaterialfv(face, GL_AMBIENT, _material_force_color);
  5667. call_glMaterialfv(face, GL_DIFFUSE, _material_force_color);
  5668. } else {
  5669. #ifndef OPENGLES
  5670. glColorMaterial(face, GL_AMBIENT_AND_DIFFUSE);
  5671. #endif // OPENGLES
  5672. glEnable(GL_COLOR_MATERIAL);
  5673. }
  5674. }
  5675. #ifndef OPENGLES
  5676. glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, material->get_local());
  5677. glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, material->get_twoside());
  5678. if (gl_separate_specular_color) {
  5679. glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
  5680. } else {
  5681. glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
  5682. }
  5683. #endif
  5684. report_my_gl_errors();
  5685. }
  5686. #endif // !OPENGLES_2
  5687. ////////////////////////////////////////////////////////////////////
  5688. // Function: GLGraphicsStateGuardian::do_issue_blending
  5689. // Access: Protected
  5690. // Description:
  5691. ////////////////////////////////////////////////////////////////////
  5692. void CLP(GraphicsStateGuardian)::
  5693. do_issue_blending() {
  5694. // Handle the color_write attrib. If color_write is off, then
  5695. // all the other blending-related stuff doesn't matter. If the
  5696. // device doesn't support color-write, we use blending tricks
  5697. // to effectively disable color write.
  5698. const ColorWriteAttrib *target_color_write;
  5699. _target_rs->get_attrib_def(target_color_write);
  5700. unsigned int color_channels =
  5701. target_color_write->get_channels() & _color_write_mask;
  5702. if (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write)) {
  5703. color_channels &= ~(ColorWriteAttrib::C_alpha);
  5704. }
  5705. if (color_channels == ColorWriteAttrib::C_off) {
  5706. int color_write_slot = ColorWriteAttrib::get_class_slot();
  5707. enable_multisample_alpha_one(false);
  5708. enable_multisample_alpha_mask(false);
  5709. if (gl_color_mask) {
  5710. enable_blend(false);
  5711. set_color_write_mask(ColorWriteAttrib::C_off);
  5712. } else {
  5713. enable_blend(true);
  5714. _glBlendEquation(GL_FUNC_ADD);
  5715. glBlendFunc(GL_ZERO, GL_ONE);
  5716. }
  5717. return;
  5718. } else {
  5719. set_color_write_mask(color_channels);
  5720. }
  5721. const ColorBlendAttrib *target_color_blend;
  5722. _target_rs->get_attrib_def(target_color_blend);
  5723. CPT(ColorBlendAttrib) color_blend = target_color_blend;
  5724. ColorBlendAttrib::Mode color_blend_mode = target_color_blend->get_mode();
  5725. const TransparencyAttrib *target_transparency;
  5726. _target_rs->get_attrib_def(target_transparency);
  5727. TransparencyAttrib::Mode transparency_mode = target_transparency->get_mode();
  5728. _color_blend_involves_color_scale = color_blend->involves_color_scale();
  5729. // Is there a color blend set?
  5730. if (color_blend_mode != ColorBlendAttrib::M_none) {
  5731. enable_multisample_alpha_one(false);
  5732. enable_multisample_alpha_mask(false);
  5733. enable_blend(true);
  5734. _glBlendEquation(get_blend_equation_type(color_blend_mode));
  5735. glBlendFunc(get_blend_func(color_blend->get_operand_a()),
  5736. get_blend_func(color_blend->get_operand_b()));
  5737. if (_color_blend_involves_color_scale) {
  5738. // Apply the current color scale to the blend mode.
  5739. _glBlendColor(_current_color_scale[0], _current_color_scale[1],
  5740. _current_color_scale[2], _current_color_scale[3]);
  5741. } else {
  5742. LColor c = color_blend->get_color();
  5743. _glBlendColor(c[0], c[1], c[2], c[3]);
  5744. }
  5745. return;
  5746. }
  5747. // No color blend; is there a transparency set?
  5748. switch (transparency_mode) {
  5749. case TransparencyAttrib::M_none:
  5750. case TransparencyAttrib::M_binary:
  5751. break;
  5752. case TransparencyAttrib::M_alpha:
  5753. case TransparencyAttrib::M_dual:
  5754. enable_multisample_alpha_one(false);
  5755. enable_multisample_alpha_mask(false);
  5756. enable_blend(true);
  5757. _glBlendEquation(GL_FUNC_ADD);
  5758. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  5759. return;
  5760. case TransparencyAttrib::M_multisample:
  5761. // We need to enable *both* of these in M_multisample case.
  5762. enable_multisample_alpha_one(true);
  5763. enable_multisample_alpha_mask(true);
  5764. enable_blend(false);
  5765. return;
  5766. case TransparencyAttrib::M_multisample_mask:
  5767. enable_multisample_alpha_one(false);
  5768. enable_multisample_alpha_mask(true);
  5769. enable_blend(false);
  5770. return;
  5771. default:
  5772. GLCAT.error()
  5773. << "invalid transparency mode " << (int)transparency_mode << endl;
  5774. break;
  5775. }
  5776. if (_line_smooth_enabled || _point_smooth_enabled) {
  5777. // If we have either of these turned on, we also need to have
  5778. // blend mode enabled in order to see it.
  5779. enable_multisample_alpha_one(false);
  5780. enable_multisample_alpha_mask(false);
  5781. enable_blend(true);
  5782. _glBlendEquation(GL_FUNC_ADD);
  5783. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  5784. return;
  5785. }
  5786. // For best polygon smoothing, we need:
  5787. // (1) a frame buffer that supports alpha
  5788. // (2) sort polygons front-to-back
  5789. // (3) glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE);
  5790. //
  5791. // Since these modes have other implications for the application, we
  5792. // don't attempt to do this by default. If you really want good
  5793. // polygon smoothing (and you don't have multisample support), do
  5794. // all this yourself.
  5795. // Nothing's set, so disable blending.
  5796. enable_multisample_alpha_one(false);
  5797. enable_multisample_alpha_mask(false);
  5798. enable_blend(false);
  5799. }
  5800. #ifndef OPENGLES_2
  5801. ////////////////////////////////////////////////////////////////////
  5802. // Function: GLGraphicsStateGuardian::bind_light
  5803. // Access: Public, Virtual
  5804. // Description: Called the first time a particular light has been
  5805. // bound to a given id within a frame, this should set
  5806. // up the associated hardware light with the light's
  5807. // properties.
  5808. ////////////////////////////////////////////////////////////////////
  5809. void CLP(GraphicsStateGuardian)::
  5810. bind_light(PointLight *light_obj, const NodePath &light, int light_id) {
  5811. // static PStatCollector _draw_set_state_light_bind_point_pcollector("Draw:Set State:Light:Bind:Point");
  5812. // PStatGPUTimer timer(this, _draw_set_state_light_bind_point_pcollector);
  5813. GLenum id = get_light_id(light_id);
  5814. static const LColor black(0.0f, 0.0f, 0.0f, 1.0f);
  5815. call_glLightfv(id, GL_AMBIENT, black);
  5816. call_glLightfv(id, GL_DIFFUSE, get_light_color(light_obj));
  5817. call_glLightfv(id, GL_SPECULAR, light_obj->get_specular_color());
  5818. // Position needs to specify x, y, z, and w
  5819. // w == 1 implies non-infinite position
  5820. CPT(TransformState) transform = light.get_transform(_scene_setup->get_scene_root().get_parent());
  5821. LPoint3 pos = light_obj->get_point() * transform->get_mat();
  5822. LPoint4 fpos(pos[0], pos[1], pos[2], 1.0f);
  5823. call_glLightfv(id, GL_POSITION, fpos);
  5824. // GL_SPOT_DIRECTION is not significant when cutoff == 180
  5825. // Exponent == 0 implies uniform light distribution
  5826. glLightf(id, GL_SPOT_EXPONENT, 0.0f);
  5827. // Cutoff == 180 means uniform point light source
  5828. glLightf(id, GL_SPOT_CUTOFF, 180.0f);
  5829. const LVecBase3 &att = light_obj->get_attenuation();
  5830. glLightf(id, GL_CONSTANT_ATTENUATION, att[0]);
  5831. glLightf(id, GL_LINEAR_ATTENUATION, att[1]);
  5832. glLightf(id, GL_QUADRATIC_ATTENUATION, att[2]);
  5833. report_my_gl_errors();
  5834. }
  5835. #endif // !OPENGLES_2
  5836. #ifndef OPENGLES_2
  5837. ////////////////////////////////////////////////////////////////////
  5838. // Function: GLGraphicsStateGuardian::bind_light
  5839. // Access: Public, Virtual
  5840. // Description: Called the first time a particular light has been
  5841. // bound to a given id within a frame, this should set
  5842. // up the associated hardware light with the light's
  5843. // properties.
  5844. ////////////////////////////////////////////////////////////////////
  5845. void CLP(GraphicsStateGuardian)::
  5846. bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) {
  5847. // static PStatCollector _draw_set_state_light_bind_directional_pcollector("Draw:Set State:Light:Bind:Directional");
  5848. // PStatGPUTimer timer(this, _draw_set_state_light_bind_directional_pcollector);
  5849. pair<DirectionalLights::iterator, bool> lookup = _dlights.insert(DirectionalLights::value_type(light, DirectionalLightFrameData()));
  5850. DirectionalLightFrameData &fdata = (*lookup.first).second;
  5851. if (lookup.second) {
  5852. // The light was not computed yet this frame. Compute it now.
  5853. CPT(TransformState) transform = light.get_transform(_scene_setup->get_scene_root().get_parent());
  5854. LVector3 dir = light_obj->get_direction() * transform->get_mat();
  5855. fdata._neg_dir.set(-dir[0], -dir[1], -dir[2], 0);
  5856. }
  5857. GLenum id = get_light_id( light_id );
  5858. static const LColor black(0.0f, 0.0f, 0.0f, 1.0f);
  5859. call_glLightfv(id, GL_AMBIENT, black);
  5860. call_glLightfv(id, GL_DIFFUSE, get_light_color(light_obj));
  5861. call_glLightfv(id, GL_SPECULAR, light_obj->get_specular_color());
  5862. // Position needs to specify x, y, z, and w.
  5863. // w == 0 implies light is at infinity
  5864. call_glLightfv(id, GL_POSITION, fdata._neg_dir);
  5865. // GL_SPOT_DIRECTION is not significant when cutoff == 180
  5866. // In this case, position x, y, z specifies direction
  5867. // Exponent == 0 implies uniform light distribution
  5868. glLightf(id, GL_SPOT_EXPONENT, 0.0f);
  5869. // Cutoff == 180 means uniform point light source
  5870. glLightf(id, GL_SPOT_CUTOFF, 180.0f);
  5871. // Default attenuation values (only spotlight and point light can
  5872. // modify these)
  5873. glLightf(id, GL_CONSTANT_ATTENUATION, 1.0f);
  5874. glLightf(id, GL_LINEAR_ATTENUATION, 0.0f);
  5875. glLightf(id, GL_QUADRATIC_ATTENUATION, 0.0f);
  5876. report_my_gl_errors();
  5877. }
  5878. #endif // !OPENGLES_2
  5879. #ifndef OPENGLES_2
  5880. ////////////////////////////////////////////////////////////////////
  5881. // Function: GLGraphicsStateGuardian::bind_light
  5882. // Access: Public, Virtual
  5883. // Description: Called the first time a particular light has been
  5884. // bound to a given id within a frame, this should set
  5885. // up the associated hardware light with the light's
  5886. // properties.
  5887. ////////////////////////////////////////////////////////////////////
  5888. void CLP(GraphicsStateGuardian)::
  5889. bind_light(Spotlight *light_obj, const NodePath &light, int light_id) {
  5890. // static PStatCollector _draw_set_state_light_bind_spotlight_pcollector("Draw:Set State:Light:Bind:Spotlight");
  5891. // PStatGPUTimer timer(this, _draw_set_state_light_bind_spotlight_pcollector);
  5892. Lens *lens = light_obj->get_lens();
  5893. nassertv(lens != (Lens *)NULL);
  5894. GLenum id = get_light_id(light_id);
  5895. static const LColor black(0.0f, 0.0f, 0.0f, 1.0f);
  5896. call_glLightfv(id, GL_AMBIENT, black);
  5897. call_glLightfv(id, GL_DIFFUSE, get_light_color(light_obj));
  5898. call_glLightfv(id, GL_SPECULAR, light_obj->get_specular_color());
  5899. // Position needs to specify x, y, z, and w
  5900. // w == 1 implies non-infinite position
  5901. CPT(TransformState) transform = light.get_transform(_scene_setup->get_scene_root().get_parent());
  5902. const LMatrix4 &light_mat = transform->get_mat();
  5903. LPoint3 pos = lens->get_nodal_point() * light_mat;
  5904. LVector3 dir = lens->get_view_vector() * light_mat;
  5905. LPoint4 fpos(pos[0], pos[1], pos[2], 1.0f);
  5906. call_glLightfv(id, GL_POSITION, fpos);
  5907. call_glLightfv(id, GL_SPOT_DIRECTION, dir);
  5908. glLightf(id, GL_SPOT_EXPONENT, light_obj->get_exponent());
  5909. glLightf(id, GL_SPOT_CUTOFF, lens->get_hfov() * 0.5f);
  5910. const LVecBase3 &att = light_obj->get_attenuation();
  5911. glLightf(id, GL_CONSTANT_ATTENUATION, att[0]);
  5912. glLightf(id, GL_LINEAR_ATTENUATION, att[1]);
  5913. glLightf(id, GL_QUADRATIC_ATTENUATION, att[2]);
  5914. report_my_gl_errors();
  5915. }
  5916. #endif // !OPENGLES_2
  5917. #ifdef SUPPORT_IMMEDIATE_MODE
  5918. ////////////////////////////////////////////////////////////////////
  5919. // Function: GLGraphicsStateGuardian::draw_immediate_simple_primitives
  5920. // Access: Protected
  5921. // Description: Uses the ImmediateModeSender to draw a series of
  5922. // primitives of the indicated type.
  5923. ////////////////////////////////////////////////////////////////////
  5924. void CLP(GraphicsStateGuardian)::
  5925. draw_immediate_simple_primitives(const GeomPrimitivePipelineReader *reader, GLenum mode) {
  5926. int num_vertices = reader->get_num_vertices();
  5927. _vertices_immediate_pcollector.add_level(num_vertices);
  5928. glBegin(mode);
  5929. if (reader->is_indexed()) {
  5930. for (int v = 0; v < num_vertices; ++v) {
  5931. _sender.set_vertex(reader->get_vertex(v));
  5932. _sender.issue_vertex();
  5933. }
  5934. } else {
  5935. _sender.set_vertex(reader->get_first_vertex());
  5936. for (int v = 0; v < num_vertices; ++v) {
  5937. _sender.issue_vertex();
  5938. }
  5939. }
  5940. glEnd();
  5941. }
  5942. #endif // SUPPORT_IMMEDIATE_MODE
  5943. #ifdef SUPPORT_IMMEDIATE_MODE
  5944. ////////////////////////////////////////////////////////////////////
  5945. // Function: GLGraphicsStateGuardian::draw_immediate_composite_primitives
  5946. // Access: Protected
  5947. // Description: Uses the ImmediateModeSender to draw a series of
  5948. // primitives of the indicated type. This form is for
  5949. // primitive types like tristrips which must involve
  5950. // several begin/end groups.
  5951. ////////////////////////////////////////////////////////////////////
  5952. void CLP(GraphicsStateGuardian)::
  5953. draw_immediate_composite_primitives(const GeomPrimitivePipelineReader *reader, GLenum mode) {
  5954. int num_vertices = reader->get_num_vertices();
  5955. _vertices_immediate_pcollector.add_level(num_vertices);
  5956. CPTA_int ends = reader->get_ends();
  5957. int num_unused_vertices_per_primitive = reader->get_object()->get_num_unused_vertices_per_primitive();
  5958. if (reader->is_indexed()) {
  5959. int begin = 0;
  5960. CPTA_int::const_iterator ei;
  5961. for (ei = ends.begin(); ei != ends.end(); ++ei) {
  5962. int end = (*ei);
  5963. glBegin(mode);
  5964. for (int v = begin; v < end; ++v) {
  5965. _sender.set_vertex(reader->get_vertex(v));
  5966. _sender.issue_vertex();
  5967. }
  5968. glEnd();
  5969. begin = end + num_unused_vertices_per_primitive;
  5970. }
  5971. } else {
  5972. _sender.set_vertex(reader->get_first_vertex());
  5973. int begin = 0;
  5974. CPTA_int::const_iterator ei;
  5975. for (ei = ends.begin(); ei != ends.end(); ++ei) {
  5976. int end = (*ei);
  5977. glBegin(mode);
  5978. for (int v = begin; v < end; ++v) {
  5979. _sender.issue_vertex();
  5980. }
  5981. glEnd();
  5982. begin = end + num_unused_vertices_per_primitive;
  5983. }
  5984. }
  5985. }
  5986. #endif // SUPPORT_IMMEDIATE_MODE
  5987. ////////////////////////////////////////////////////////////////////
  5988. // Function: GLGraphicsStateGuardian::gl_flush
  5989. // Access: Protected, Virtual
  5990. // Description: Calls glFlush().
  5991. ////////////////////////////////////////////////////////////////////
  5992. void CLP(GraphicsStateGuardian)::
  5993. gl_flush() const {
  5994. PStatTimer timer(_flush_pcollector);
  5995. glFlush();
  5996. }
  5997. ////////////////////////////////////////////////////////////////////
  5998. // Function: GLGraphicsStateGuardian::gl_get_error
  5999. // Access: Protected, Virtual
  6000. // Description: Returns the result of glGetError().
  6001. ////////////////////////////////////////////////////////////////////
  6002. GLenum CLP(GraphicsStateGuardian)::
  6003. gl_get_error() const {
  6004. if (_check_errors) {
  6005. PStatTimer timer(_check_error_pcollector);
  6006. return glGetError();
  6007. } else {
  6008. return GL_NO_ERROR;
  6009. }
  6010. }
  6011. ////////////////////////////////////////////////////////////////////
  6012. // Function: GLGraphicsStateGuardian::report_errors_loop
  6013. // Access: Protected, Static
  6014. // Description: The internal implementation of report_errors().
  6015. // Don't call this function; use report_errors()
  6016. // instead. The return value is true if everything is
  6017. // ok, or false if we should shut down.
  6018. ////////////////////////////////////////////////////////////////////
  6019. bool CLP(GraphicsStateGuardian)::
  6020. report_errors_loop(int line, const char *source_file, GLenum error_code,
  6021. int &error_count) {
  6022. while ((gl_max_errors < 0 || error_count < gl_max_errors) &&
  6023. (error_code != GL_NO_ERROR)) {
  6024. GLCAT.error()
  6025. << "at " << line << " of " << source_file << " : "
  6026. << get_error_string(error_code) << "\n";
  6027. error_code = glGetError();
  6028. error_count++;
  6029. }
  6030. return (error_code == GL_NO_ERROR);
  6031. }
  6032. ////////////////////////////////////////////////////////////////////
  6033. // Function: GLGraphicsStateGuardian::get_error_string
  6034. // Access: Protected, Static
  6035. // Description: Returns an error string for an OpenGL error code.
  6036. ////////////////////////////////////////////////////////////////////
  6037. string CLP(GraphicsStateGuardian)::
  6038. get_error_string(GLenum error_code) {
  6039. // We used to use gluErrorString here, but I (rdb) took it out
  6040. // because that was really the only function we used from GLU.
  6041. // The idea with the error table was taken from SGI's sample implementation.
  6042. static const char *error_strings[GL_OUT_OF_MEMORY - GL_INVALID_ENUM + 1] = {
  6043. "invalid enumerant",
  6044. "invalid value",
  6045. "invalid operation",
  6046. "stack overflow",
  6047. "stack underflow",
  6048. "out of memory",
  6049. };
  6050. if (error_code == GL_NO_ERROR) {
  6051. return "no error";
  6052. #ifndef OPENGLES
  6053. } else if (error_code == GL_TABLE_TOO_LARGE) {
  6054. return "table too large";
  6055. #endif
  6056. } else if (error_code >= GL_INVALID_ENUM && error_code <= GL_OUT_OF_MEMORY) {
  6057. return error_strings[error_code - GL_INVALID_ENUM];
  6058. }
  6059. // Other error, somehow? Just display the error code then.
  6060. ostringstream strm;
  6061. strm << "GL error " << (int)error_code;
  6062. return strm.str();
  6063. }
  6064. ////////////////////////////////////////////////////////////////////
  6065. // Function: GLGraphicsStateGuardian::show_gl_string
  6066. // Access: Protected
  6067. // Description: Outputs the result of glGetString() on the indicated
  6068. // tag. The output string is returned.
  6069. ////////////////////////////////////////////////////////////////////
  6070. string CLP(GraphicsStateGuardian)::
  6071. show_gl_string(const string &name, GLenum id) {
  6072. string result;
  6073. const GLubyte *text = glGetString(id);
  6074. if (text == (const GLubyte *)NULL) {
  6075. if (GLCAT.is_debug()) {
  6076. GLCAT.debug()
  6077. << "Unable to query " << name << "\n";
  6078. }
  6079. } else {
  6080. result = (const char *)text;
  6081. if (GLCAT.is_debug()) {
  6082. GLCAT.debug()
  6083. << name << " = " << result << "\n";
  6084. }
  6085. }
  6086. return result;
  6087. }
  6088. ////////////////////////////////////////////////////////////////////
  6089. // Function: GLGraphicsStateGuardian::query_gl_version
  6090. // Access: Protected, Virtual
  6091. // Description: Queries the runtime version of OpenGL in use.
  6092. ////////////////////////////////////////////////////////////////////
  6093. void CLP(GraphicsStateGuardian)::
  6094. query_gl_version() {
  6095. _gl_vendor = show_gl_string("GL_VENDOR", GL_VENDOR);
  6096. _gl_renderer = show_gl_string("GL_RENDERER", GL_RENDERER);
  6097. _gl_version_major = 0;
  6098. _gl_version_minor = 0;
  6099. _gl_shadlang_ver_major = 0;
  6100. _gl_shadlang_ver_minor = 0;
  6101. const GLubyte *text = glGetString(GL_VERSION);
  6102. if (text == (const GLubyte *)NULL) {
  6103. GLCAT.warning()
  6104. << "Unable to query GL_VERSION\n";
  6105. } else {
  6106. string version((const char *)text);
  6107. _gl_version = version;
  6108. string input = version;
  6109. // Skip any initial words that don't begin with a digit.
  6110. while (!input.empty() && !isdigit(input[0])) {
  6111. size_t space = input.find(' ');
  6112. if (space == string::npos) {
  6113. break;
  6114. }
  6115. size_t next = space + 1;
  6116. while (next < input.length() && isspace(input[next])) {
  6117. ++next;
  6118. }
  6119. input = input.substr(next);
  6120. }
  6121. // Truncate after the first space.
  6122. size_t space = input.find(' ');
  6123. if (space != string::npos) {
  6124. input = input.substr(0, space);
  6125. }
  6126. vector_string components;
  6127. tokenize(input, components, ".");
  6128. if (components.size() >= 1) {
  6129. string_to_int(components[0], _gl_version_major);
  6130. }
  6131. if (components.size() >= 2) {
  6132. string_to_int(components[1], _gl_version_minor);
  6133. }
  6134. if (GLCAT.is_debug()) {
  6135. GLCAT.debug()
  6136. << "GL_VERSION = " << version << ", decoded to "
  6137. << _gl_version_major << "." << _gl_version_minor
  6138. << "\n";
  6139. }
  6140. #ifndef OPENGLES
  6141. if (_gl_version_major == 1) {
  6142. // We can't call has_extension at this point yet.
  6143. const char *extstr = (const char *) glGetString(GL_EXTENSIONS);
  6144. if (extstr != NULL) {
  6145. if (strstr(extstr, "GL_ARB_shading_language_100") != NULL) {
  6146. _gl_shadlang_ver_major = 1;
  6147. _gl_shadlang_ver_minor = 0;
  6148. }
  6149. }
  6150. } else if (_gl_version_major >= 2) {
  6151. _gl_shadlang_ver_major = 1;
  6152. _gl_shadlang_ver_minor = 1;
  6153. const char *verstr = (const char *) glGetString(GL_SHADING_LANGUAGE_VERSION);
  6154. if (verstr == NULL ||
  6155. sscanf(verstr, "%d.%d", &_gl_shadlang_ver_major,
  6156. &_gl_shadlang_ver_minor) != 2) {
  6157. GLCAT.warning() << "Invalid GL_SHADING_LANGUAGE_VERSION format.\n";
  6158. }
  6159. }
  6160. #elif defined(OPENGLES_2)
  6161. _gl_shadlang_ver_major = 1;
  6162. _gl_shadlang_ver_minor = 0;
  6163. const char *verstr = (const char *) glGetString(GL_SHADING_LANGUAGE_VERSION);
  6164. if (verstr == NULL ||
  6165. sscanf(verstr, "OpenGL ES GLSL %d.%d", &_gl_shadlang_ver_major,
  6166. &_gl_shadlang_ver_minor) != 2) {
  6167. GLCAT.warning() << "Invalid GL_SHADING_LANGUAGE_VERSION format.\n";
  6168. }
  6169. #endif
  6170. }
  6171. }
  6172. ////////////////////////////////////////////////////////////////////
  6173. // Function: GLGraphicsStateGuardian::save_extensions
  6174. // Access: Protected
  6175. // Description: Separates the string returned by GL_EXTENSIONS (or
  6176. // glx or wgl extensions) into its individual tokens
  6177. // and saves them in the _extensions member.
  6178. ////////////////////////////////////////////////////////////////////
  6179. void CLP(GraphicsStateGuardian)::
  6180. save_extensions(const char *extensions) {
  6181. if (extensions != (const char *)NULL) {
  6182. vector_string tokens;
  6183. extract_words(extensions, tokens);
  6184. vector_string::iterator ti;
  6185. for (ti = tokens.begin(); ti != tokens.end(); ++ti) {
  6186. _extensions.insert(*ti);
  6187. }
  6188. }
  6189. }
  6190. ////////////////////////////////////////////////////////////////////
  6191. // Function: GLGraphicsStateGuardian::get_extra_extensions
  6192. // Access: Protected, Virtual
  6193. // Description: This may be redefined by a derived class (e.g. glx or
  6194. // wgl) to get whatever further extensions strings may
  6195. // be appropriate to that interface, in addition to the
  6196. // GL extension strings return by glGetString().
  6197. ////////////////////////////////////////////////////////////////////
  6198. void CLP(GraphicsStateGuardian)::
  6199. get_extra_extensions() {
  6200. }
  6201. ////////////////////////////////////////////////////////////////////
  6202. // Function: GLGraphicsStateGuardian::report_extensions
  6203. // Access: Protected
  6204. // Description: Outputs the list of GL extensions to notify, if debug
  6205. // mode is enabled.
  6206. ////////////////////////////////////////////////////////////////////
  6207. void CLP(GraphicsStateGuardian)::
  6208. report_extensions() const {
  6209. if (GLCAT.is_debug()) {
  6210. GLCAT.debug()
  6211. << "GL Extensions:\n";
  6212. pset<string>::const_iterator ei;
  6213. for (ei = _extensions.begin(); ei != _extensions.end(); ++ei) {
  6214. GLCAT.debug() << (*ei) << "\n";
  6215. }
  6216. }
  6217. }
  6218. ////////////////////////////////////////////////////////////////////
  6219. // Function: GLGraphicsStateGuardian::get_extension_func
  6220. // Access: Public
  6221. // Description: Returns the pointer to the GL extension function with
  6222. // the indicated name, or NULL if the function is not
  6223. // available.
  6224. ////////////////////////////////////////////////////////////////////
  6225. void *CLP(GraphicsStateGuardian)::
  6226. get_extension_func(const char *name) {
  6227. // First, look in the static-compiled namespace. If we were
  6228. // compiled to expect at least a certain minimum runtime version of
  6229. // OpenGL, then we can expect those extension functions to be
  6230. // available at compile time. Somewhat more reliable than poking
  6231. // around in the runtime pointers.
  6232. static struct {
  6233. const char *name;
  6234. void *fptr;
  6235. } compiled_function_table[] = {
  6236. #ifdef EXPECT_GL_VERSION_1_2
  6237. { "glBlendColor", (void *)&glBlendColor },
  6238. { "glBlendEquation", (void *)&glBlendEquation },
  6239. { "glDrawRangeElements", (void *)&glDrawRangeElements },
  6240. { "glTexImage3D", (void *)&glTexImage3D },
  6241. { "glTexSubImage3D", (void *)&glTexSubImage3D },
  6242. { "glCopyTexSubImage3D", (void *)&glCopyTexSubImage3D },
  6243. #endif
  6244. #ifdef EXPECT_GL_VERSION_1_3
  6245. { "glActiveTexture", (void *)&glActiveTexture },
  6246. { "glClientActiveTexture", (void *)&glClientActiveTexture },
  6247. { "glCompressedTexImage1D", (void *)&glCompressedTexImage1D },
  6248. { "glCompressedTexImage2D", (void *)&glCompressedTexImage2D },
  6249. { "glCompressedTexImage3D", (void *)&glCompressedTexImage3D },
  6250. { "glCompressedTexSubImage1D", (void *)&glCompressedTexSubImage1D },
  6251. { "glCompressedTexSubImage2D", (void *)&glCompressedTexSubImage2D },
  6252. { "glCompressedTexSubImage3D", (void *)&glCompressedTexSubImage3D },
  6253. { "glGetCompressedTexImage", (void *)&glGetCompressedTexImage },
  6254. { "glMultiTexCoord1f", (void *)&glMultiTexCoord1f },
  6255. { "glMultiTexCoord2", (void *)&glMultiTexCoord2 },
  6256. { "glMultiTexCoord3", (void *)&glMultiTexCoord3 },
  6257. { "glMultiTexCoord4", (void *)&glMultiTexCoord4 },
  6258. #endif
  6259. #ifdef EXPECT_GL_VERSION_1_4
  6260. { "glPointParameterfv", (void *)&glPointParameterfv },
  6261. #endif
  6262. #ifdef EXPECT_GL_VERSION_1_5
  6263. { "glBeginQuery", (void *)&glBeginQuery },
  6264. { "glBindBuffer", (void *)&glBindBuffer },
  6265. { "glBufferData", (void *)&glBufferData },
  6266. { "glBufferSubData", (void *)&glBufferSubData },
  6267. { "glDeleteBuffers", (void *)&glDeleteBuffers },
  6268. { "glDeleteQueries", (void *)&glDeleteQueries },
  6269. { "glEndQuery", (void *)&glEndQuery },
  6270. { "glGenBuffers", (void *)&glGenBuffers },
  6271. { "glGenQueries", (void *)&glGenQueries },
  6272. { "glGetQueryObjectuiv", (void *)&glGetQueryObjectuiv },
  6273. { "glGetQueryiv", (void *)&glGetQueryiv },
  6274. #endif
  6275. #ifdef OPENGLES
  6276. { "glActiveTexture", (void *)&glActiveTexture },
  6277. #ifndef OPENGLES_2
  6278. { "glClientActiveTexture", (void *)&glClientActiveTexture },
  6279. #endif
  6280. { "glBindBuffer", (void *)&glBindBuffer },
  6281. { "glBufferData", (void *)&glBufferData },
  6282. { "glBufferSubData", (void *)&glBufferSubData },
  6283. { "glDeleteBuffers", (void *)&glDeleteBuffers },
  6284. { "glGenBuffers", (void *)&glGenBuffers },
  6285. #endif
  6286. { NULL, NULL }
  6287. };
  6288. int i = 0;
  6289. while (compiled_function_table[i].name != NULL) {
  6290. if (strcmp(compiled_function_table[i].name, name) == 0) {
  6291. return compiled_function_table[i].fptr;
  6292. }
  6293. ++i;
  6294. }
  6295. // If the extension function wasn't compiled in, then go get it from
  6296. // the runtime. There's a different interface for each API.
  6297. return do_get_extension_func(name);
  6298. }
  6299. ////////////////////////////////////////////////////////////////////
  6300. // Function: GLGraphicsStateGuardian::do_get_extension_func
  6301. // Access: Public, Virtual
  6302. // Description: This is the virtual implementation of
  6303. // get_extension_func(). Each API-specific GL
  6304. // implementation will map this method to the
  6305. // appropriate API call to retrieve the extension
  6306. // function pointer. Returns NULL if the function is
  6307. // not available.
  6308. ////////////////////////////////////////////////////////////////////
  6309. void *CLP(GraphicsStateGuardian)::
  6310. do_get_extension_func(const char *) {
  6311. return NULL;
  6312. }
  6313. ////////////////////////////////////////////////////////////////////
  6314. // Function: GLGraphicsStateGuardian::set_draw_buffer
  6315. // Access: Protected
  6316. // Description: Sets up the glDrawBuffer to render into the buffer
  6317. // indicated by the RenderBuffer object. This only sets
  6318. // up the color and aux bits; it does not affect the depth,
  6319. // stencil, accum layers.
  6320. ////////////////////////////////////////////////////////////////////
  6321. void CLP(GraphicsStateGuardian)::
  6322. set_draw_buffer(int rbtype) {
  6323. #ifndef OPENGLES // Draw buffers not supported by OpenGL ES.
  6324. if (_current_fbo) {
  6325. GLuint buffers[16];
  6326. int nbuffers = 0;
  6327. int index = 0;
  6328. if (_current_properties->get_color_bits() > 0) {
  6329. if (rbtype & RenderBuffer::T_left) {
  6330. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index;
  6331. }
  6332. ++index;
  6333. if (_current_properties->is_stereo()) {
  6334. if (rbtype & RenderBuffer::T_right) {
  6335. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index;
  6336. }
  6337. ++index;
  6338. }
  6339. }
  6340. for (int i = 0; i < _current_properties->get_aux_rgba(); ++i) {
  6341. if (rbtype & (RenderBuffer::T_aux_rgba_0 << i)) {
  6342. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index;
  6343. }
  6344. ++index;
  6345. }
  6346. for (int i = 0; i < _current_properties->get_aux_hrgba(); ++i) {
  6347. if (rbtype & (RenderBuffer::T_aux_hrgba_0 << i)) {
  6348. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index;
  6349. }
  6350. ++index;
  6351. }
  6352. for (int i = 0; i < _current_properties->get_aux_float(); ++i) {
  6353. if (rbtype & (RenderBuffer::T_aux_float_0 << i)) {
  6354. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index;
  6355. }
  6356. ++index;
  6357. }
  6358. _glDrawBuffers(nbuffers, buffers);
  6359. } else {
  6360. switch (rbtype & RenderBuffer::T_color) {
  6361. case RenderBuffer::T_front:
  6362. glDrawBuffer(GL_FRONT);
  6363. break;
  6364. case RenderBuffer::T_back:
  6365. glDrawBuffer(GL_BACK);
  6366. break;
  6367. case RenderBuffer::T_right:
  6368. glDrawBuffer(GL_RIGHT);
  6369. break;
  6370. case RenderBuffer::T_left:
  6371. glDrawBuffer(GL_LEFT);
  6372. break;
  6373. case RenderBuffer::T_front_right:
  6374. nassertv(_current_properties->is_stereo());
  6375. glDrawBuffer(GL_FRONT_RIGHT);
  6376. break;
  6377. case RenderBuffer::T_front_left:
  6378. nassertv(_current_properties->is_stereo());
  6379. glDrawBuffer(GL_FRONT_LEFT);
  6380. break;
  6381. case RenderBuffer::T_back_right:
  6382. nassertv(_current_properties->is_stereo());
  6383. glDrawBuffer(GL_BACK_RIGHT);
  6384. break;
  6385. case RenderBuffer::T_back_left:
  6386. nassertv(_current_properties->is_stereo());
  6387. glDrawBuffer(GL_BACK_LEFT);
  6388. break;
  6389. default:
  6390. break;
  6391. }
  6392. }
  6393. #endif // OPENGLES
  6394. // Also ensure that any global color channels are masked out.
  6395. set_color_write_mask(_color_write_mask);
  6396. report_my_gl_errors();
  6397. }
  6398. ////////////////////////////////////////////////////////////////////
  6399. // Function: GLGraphicsStateGuardian::set_read_buffer
  6400. // Access: Protected
  6401. // Description: Sets up the glReadBuffer to render into the buffer
  6402. // indicated by the RenderBuffer object. This only sets
  6403. // up the color bits; it does not affect the depth,
  6404. // stencil, accum layers.
  6405. ////////////////////////////////////////////////////////////////////
  6406. void CLP(GraphicsStateGuardian)::
  6407. set_read_buffer(int rbtype) {
  6408. #ifndef OPENGLES // Draw buffers not supported by OpenGL ES.
  6409. if (rbtype & (RenderBuffer::T_depth | RenderBuffer::T_stencil)) {
  6410. // Special case: don't have to call ReadBuffer for these.
  6411. return;
  6412. }
  6413. if (_current_fbo) {
  6414. GLuint buffer = GL_COLOR_ATTACHMENT0_EXT;
  6415. int index = 1;
  6416. if (_current_properties->is_stereo()) {
  6417. if (rbtype & RenderBuffer::T_right) {
  6418. buffer = GL_COLOR_ATTACHMENT1_EXT;
  6419. }
  6420. ++index;
  6421. }
  6422. for (int i = 0; i < _current_properties->get_aux_rgba(); ++i) {
  6423. if (rbtype & (RenderBuffer::T_aux_rgba_0 << i)) {
  6424. buffer = GL_COLOR_ATTACHMENT0_EXT + index;
  6425. }
  6426. ++index;
  6427. }
  6428. for (int i = 0; i < _current_properties->get_aux_hrgba(); ++i) {
  6429. if (rbtype & (RenderBuffer::T_aux_hrgba_0 << i)) {
  6430. buffer = GL_COLOR_ATTACHMENT0_EXT + index;
  6431. }
  6432. ++index;
  6433. }
  6434. for (int i = 0; i < _current_properties->get_aux_float(); ++i) {
  6435. if (rbtype & (RenderBuffer::T_aux_float_0 << i)) {
  6436. buffer = GL_COLOR_ATTACHMENT0_EXT + index;
  6437. }
  6438. ++index;
  6439. }
  6440. glReadBuffer(buffer);
  6441. } else {
  6442. switch (rbtype & RenderBuffer::T_color) {
  6443. case RenderBuffer::T_front:
  6444. glReadBuffer(GL_FRONT);
  6445. break;
  6446. case RenderBuffer::T_back:
  6447. glReadBuffer(GL_BACK);
  6448. break;
  6449. case RenderBuffer::T_right:
  6450. glReadBuffer(GL_RIGHT);
  6451. break;
  6452. case RenderBuffer::T_left:
  6453. glReadBuffer(GL_LEFT);
  6454. break;
  6455. case RenderBuffer::T_front_right:
  6456. glReadBuffer(GL_FRONT_RIGHT);
  6457. break;
  6458. case RenderBuffer::T_front_left:
  6459. glReadBuffer(GL_FRONT_LEFT);
  6460. break;
  6461. case RenderBuffer::T_back_right:
  6462. glReadBuffer(GL_BACK_RIGHT);
  6463. break;
  6464. case RenderBuffer::T_back_left:
  6465. glReadBuffer(GL_BACK_LEFT);
  6466. break;
  6467. default:
  6468. break;
  6469. }
  6470. }
  6471. report_my_gl_errors();
  6472. #endif // OPENGLES
  6473. }
  6474. ////////////////////////////////////////////////////////////////////
  6475. // Function: GLGraphicsStateGuardian::get_numeric_type
  6476. // Access: Protected, Static
  6477. // Description: Maps from the Geom's internal numeric type symbols
  6478. // to GL's.
  6479. ////////////////////////////////////////////////////////////////////
  6480. GLenum CLP(GraphicsStateGuardian)::
  6481. get_numeric_type(Geom::NumericType numeric_type) {
  6482. switch (numeric_type) {
  6483. case Geom::NT_uint16:
  6484. return GL_UNSIGNED_SHORT;
  6485. case Geom::NT_uint32:
  6486. #ifndef OPENGLES_1
  6487. return GL_UNSIGNED_INT;
  6488. #else
  6489. break;
  6490. #endif
  6491. case Geom::NT_uint8:
  6492. case Geom::NT_packed_dcba:
  6493. case Geom::NT_packed_dabc:
  6494. return GL_UNSIGNED_BYTE;
  6495. case Geom::NT_float32:
  6496. return GL_FLOAT;
  6497. case Geom::NT_float64:
  6498. #ifndef OPENGLES
  6499. return GL_DOUBLE;
  6500. #else
  6501. break;
  6502. #endif
  6503. case Geom::NT_stdfloat:
  6504. // Shouldn't happen, display error.
  6505. break;
  6506. }
  6507. GLCAT.error()
  6508. << "Invalid NumericType value (" << (int)numeric_type << ")\n";
  6509. return GL_UNSIGNED_BYTE;
  6510. }
  6511. ////////////////////////////////////////////////////////////////////
  6512. // Function: GLGraphicsStateGuardian::get_texture_target
  6513. // Access: Protected
  6514. // Description: Maps from the Texture's texture type symbols to
  6515. // GL's.
  6516. ////////////////////////////////////////////////////////////////////
  6517. GLenum CLP(GraphicsStateGuardian)::
  6518. get_texture_target(Texture::TextureType texture_type) const {
  6519. switch (texture_type) {
  6520. case Texture::TT_1d_texture:
  6521. // There are no 1D textures in OpenGL ES. Fall back to 2D textures.
  6522. #ifndef OPENGLES
  6523. return GL_TEXTURE_1D;
  6524. #endif
  6525. case Texture::TT_2d_texture:
  6526. return GL_TEXTURE_2D;
  6527. case Texture::TT_3d_texture:
  6528. if (_supports_3d_texture) {
  6529. #ifndef OPENGLES_1
  6530. return GL_TEXTURE_3D;
  6531. #endif
  6532. } else {
  6533. return GL_NONE;
  6534. }
  6535. case Texture::TT_2d_texture_array:
  6536. if (_supports_2d_texture_array) {
  6537. #ifndef OPENGLES
  6538. return GL_TEXTURE_2D_ARRAY_EXT;
  6539. #endif
  6540. } else {
  6541. return GL_NONE;
  6542. }
  6543. case Texture::TT_cube_map:
  6544. if (_supports_cube_map) {
  6545. return GL_TEXTURE_CUBE_MAP;
  6546. } else {
  6547. return GL_NONE;
  6548. }
  6549. }
  6550. GLCAT.error() << "Invalid Texture::TextureType value!\n";
  6551. return GL_TEXTURE_2D;
  6552. }
  6553. ////////////////////////////////////////////////////////////////////
  6554. // Function: GLGraphicsStateGuardian::get_texture_wrap_mode
  6555. // Access: Protected
  6556. // Description: Maps from the Texture's internal wrap mode symbols to
  6557. // GL's.
  6558. ////////////////////////////////////////////////////////////////////
  6559. GLenum CLP(GraphicsStateGuardian)::
  6560. get_texture_wrap_mode(SamplerState::WrapMode wm) const {
  6561. if (gl_ignore_clamp) {
  6562. return GL_REPEAT;
  6563. }
  6564. switch (wm) {
  6565. case SamplerState::WM_clamp:
  6566. return _edge_clamp;
  6567. case SamplerState::WM_repeat:
  6568. return GL_REPEAT;
  6569. case SamplerState::WM_mirror:
  6570. return _mirror_repeat;
  6571. case SamplerState::WM_mirror_once:
  6572. return _mirror_border_clamp;
  6573. case SamplerState::WM_border_color:
  6574. return _border_clamp;
  6575. case SamplerState::WM_invalid:
  6576. break;
  6577. }
  6578. GLCAT.error() << "Invalid SamplerState::WrapMode value!\n";
  6579. return _edge_clamp;
  6580. }
  6581. ////////////////////////////////////////////////////////////////////
  6582. // Function: GLGraphicsStateGuardian::get_panda_wrap_mode
  6583. // Access: Protected, Static
  6584. // Description: Maps from the GL's internal wrap mode symbols to
  6585. // Panda's.
  6586. ////////////////////////////////////////////////////////////////////
  6587. SamplerState::WrapMode CLP(GraphicsStateGuardian)::
  6588. get_panda_wrap_mode(GLenum wm) {
  6589. switch (wm) {
  6590. #ifndef OPENGLES
  6591. case GL_CLAMP:
  6592. #endif
  6593. case GL_CLAMP_TO_EDGE:
  6594. return SamplerState::WM_clamp;
  6595. #ifndef OPENGLES
  6596. case GL_CLAMP_TO_BORDER:
  6597. return SamplerState::WM_border_color;
  6598. #endif
  6599. case GL_REPEAT:
  6600. return SamplerState::WM_repeat;
  6601. #ifndef OPENGLES
  6602. case GL_MIRROR_CLAMP_EXT:
  6603. case GL_MIRROR_CLAMP_TO_EDGE_EXT:
  6604. return SamplerState::WM_mirror;
  6605. case GL_MIRROR_CLAMP_TO_BORDER_EXT:
  6606. return SamplerState::WM_mirror_once;
  6607. #endif
  6608. }
  6609. GLCAT.error() << "Unexpected GL wrap mode " << (int)wm << "\n";
  6610. return SamplerState::WM_clamp;
  6611. }
  6612. ////////////////////////////////////////////////////////////////////
  6613. // Function: GLGraphicsStateGuardian::get_texture_filter_type
  6614. // Access: Protected, Static
  6615. // Description: Maps from the Texture's internal filter type symbols
  6616. // to GL's.
  6617. ////////////////////////////////////////////////////////////////////
  6618. GLenum CLP(GraphicsStateGuardian)::
  6619. get_texture_filter_type(SamplerState::FilterType ft, bool ignore_mipmaps) {
  6620. if (gl_ignore_filters) {
  6621. return GL_NEAREST;
  6622. } else if (ignore_mipmaps) {
  6623. switch (ft) {
  6624. case SamplerState::FT_nearest_mipmap_nearest:
  6625. case SamplerState::FT_nearest:
  6626. return GL_NEAREST;
  6627. case SamplerState::FT_linear:
  6628. case SamplerState::FT_linear_mipmap_nearest:
  6629. case SamplerState::FT_nearest_mipmap_linear:
  6630. case SamplerState::FT_linear_mipmap_linear:
  6631. return GL_LINEAR;
  6632. case SamplerState::FT_shadow:
  6633. return GL_LINEAR;
  6634. case SamplerState::FT_default:
  6635. case SamplerState::FT_invalid:
  6636. break;
  6637. }
  6638. } else {
  6639. switch (ft) {
  6640. case SamplerState::FT_nearest:
  6641. return GL_NEAREST;
  6642. case SamplerState::FT_linear:
  6643. return GL_LINEAR;
  6644. case SamplerState::FT_nearest_mipmap_nearest:
  6645. return GL_NEAREST_MIPMAP_NEAREST;
  6646. case SamplerState::FT_linear_mipmap_nearest:
  6647. return GL_LINEAR_MIPMAP_NEAREST;
  6648. case SamplerState::FT_nearest_mipmap_linear:
  6649. return GL_NEAREST_MIPMAP_LINEAR;
  6650. case SamplerState::FT_linear_mipmap_linear:
  6651. return GL_LINEAR_MIPMAP_LINEAR;
  6652. case SamplerState::FT_shadow:
  6653. return GL_LINEAR;
  6654. case SamplerState::FT_default:
  6655. case SamplerState::FT_invalid:
  6656. break;
  6657. }
  6658. }
  6659. GLCAT.error() << "Invalid SamplerState::FilterType value!\n";
  6660. return GL_NEAREST;
  6661. }
  6662. ////////////////////////////////////////////////////////////////////
  6663. // Function: GLGraphicsStateGuardian::get_panda_filter_type
  6664. // Access: Protected, Static
  6665. // Description: Maps from the GL's internal filter type symbols
  6666. // to Panda's.
  6667. ////////////////////////////////////////////////////////////////////
  6668. SamplerState::FilterType CLP(GraphicsStateGuardian)::
  6669. get_panda_filter_type(GLenum ft) {
  6670. switch (ft) {
  6671. case GL_NEAREST:
  6672. return SamplerState::FT_nearest;
  6673. case GL_LINEAR:
  6674. return SamplerState::FT_linear;
  6675. case GL_NEAREST_MIPMAP_NEAREST:
  6676. return SamplerState::FT_nearest_mipmap_nearest;
  6677. case GL_LINEAR_MIPMAP_NEAREST:
  6678. return SamplerState::FT_linear_mipmap_nearest;
  6679. case GL_NEAREST_MIPMAP_LINEAR:
  6680. return SamplerState::FT_nearest_mipmap_linear;
  6681. case GL_LINEAR_MIPMAP_LINEAR:
  6682. return SamplerState::FT_linear_mipmap_linear;
  6683. }
  6684. GLCAT.error() << "Unexpected GL filter type " << (int)ft << "\n";
  6685. return SamplerState::FT_linear;
  6686. }
  6687. ////////////////////////////////////////////////////////////////////
  6688. // Function: GLGraphicsStateGuardian::get_component_type
  6689. // Access: Protected, Static
  6690. // Description: Maps from the Texture's internal ComponentType symbols
  6691. // to GL's.
  6692. ////////////////////////////////////////////////////////////////////
  6693. GLenum CLP(GraphicsStateGuardian)::
  6694. get_component_type(Texture::ComponentType component_type) {
  6695. switch (component_type) {
  6696. case Texture::T_unsigned_byte:
  6697. return GL_UNSIGNED_BYTE;
  6698. case Texture::T_unsigned_short:
  6699. return GL_UNSIGNED_SHORT;
  6700. case Texture::T_float:
  6701. return GL_FLOAT;
  6702. case Texture::T_unsigned_int_24_8:
  6703. if (_supports_depth_stencil) {
  6704. return GL_UNSIGNED_INT_24_8_EXT;
  6705. } else {
  6706. return GL_UNSIGNED_BYTE;
  6707. }
  6708. case Texture::T_int:
  6709. #ifndef OPENGLES_1
  6710. return GL_INT;
  6711. #endif
  6712. default:
  6713. GLCAT.error() << "Invalid Texture::Type value!\n";
  6714. return GL_UNSIGNED_BYTE;
  6715. }
  6716. }
  6717. ////////////////////////////////////////////////////////////////////
  6718. // Function: GLGraphicsStateGuardian::get_external_image_format
  6719. // Access: Protected
  6720. // Description: Maps from the Texture's Format symbols
  6721. // to GL's.
  6722. ////////////////////////////////////////////////////////////////////
  6723. GLint CLP(GraphicsStateGuardian)::
  6724. get_external_image_format(Texture *tex) const {
  6725. Texture::CompressionMode compression = tex->get_ram_image_compression();
  6726. Texture::Format format = tex->get_format();
  6727. if (compression != Texture::CM_off &&
  6728. get_supports_compressed_texture_format(compression)) {
  6729. switch (compression) {
  6730. case Texture::CM_on:
  6731. #ifndef OPENGLES
  6732. switch (format) {
  6733. case Texture::F_color_index:
  6734. case Texture::F_depth_component:
  6735. case Texture::F_depth_component16:
  6736. case Texture::F_depth_component24:
  6737. case Texture::F_depth_component32:
  6738. case Texture::F_depth_stencil:
  6739. // This shouldn't be possible.
  6740. nassertr(false, GL_RGB);
  6741. break;
  6742. case Texture::F_rgba:
  6743. case Texture::F_rgbm:
  6744. case Texture::F_rgba4:
  6745. case Texture::F_rgba8:
  6746. case Texture::F_rgba12:
  6747. case Texture::F_rgba16:
  6748. case Texture::F_rgba32:
  6749. case Texture::F_rgba8i:
  6750. return GL_COMPRESSED_RGBA;
  6751. case Texture::F_rgb:
  6752. case Texture::F_rgb5:
  6753. case Texture::F_rgba5:
  6754. case Texture::F_rgb8:
  6755. case Texture::F_rgb8i:
  6756. case Texture::F_rgb12:
  6757. case Texture::F_rgb332:
  6758. case Texture::F_rgb16:
  6759. case Texture::F_rgb32:
  6760. return GL_COMPRESSED_RGB;
  6761. case Texture::F_alpha:
  6762. return GL_COMPRESSED_ALPHA;
  6763. case Texture::F_red:
  6764. case Texture::F_green:
  6765. case Texture::F_blue:
  6766. case Texture::F_r8i:
  6767. case Texture::F_r16:
  6768. case Texture::F_r32:
  6769. case Texture::F_r32i:
  6770. return GL_COMPRESSED_RED;
  6771. case Texture::F_rg8i:
  6772. case Texture::F_rg16:
  6773. case Texture::F_rg32:
  6774. return GL_COMPRESSED_RG;
  6775. case Texture::F_luminance:
  6776. return GL_COMPRESSED_LUMINANCE;
  6777. case Texture::F_luminance_alpha:
  6778. case Texture::F_luminance_alphamask:
  6779. return GL_COMPRESSED_LUMINANCE_ALPHA;
  6780. case Texture::F_srgb:
  6781. return GL_COMPRESSED_SRGB;
  6782. case Texture::F_srgb_alpha:
  6783. return GL_COMPRESSED_SRGB_ALPHA;
  6784. case Texture::F_sluminance:
  6785. return GL_COMPRESSED_SLUMINANCE;
  6786. case Texture::F_sluminance_alpha:
  6787. return GL_COMPRESSED_SLUMINANCE_ALPHA;
  6788. }
  6789. #endif
  6790. break;
  6791. case Texture::CM_dxt1:
  6792. #ifndef OPENGLES
  6793. if (format == Texture::F_srgb_alpha) {
  6794. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
  6795. } else if (format == Texture::F_srgb) {
  6796. return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
  6797. } else
  6798. #endif
  6799. if (Texture::has_alpha(format)) {
  6800. return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
  6801. } else {
  6802. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  6803. }
  6804. case Texture::CM_dxt3:
  6805. #ifndef OPENGLES
  6806. if (format == Texture::F_srgb || format == Texture::F_srgb_alpha) {
  6807. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
  6808. }
  6809. #endif
  6810. #ifndef OPENGLES_1
  6811. return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
  6812. #endif
  6813. break;
  6814. case Texture::CM_dxt5:
  6815. #ifndef OPENGLES
  6816. if (format == Texture::F_srgb || format == Texture::F_srgb_alpha) {
  6817. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
  6818. }
  6819. #endif
  6820. #ifndef OPENGLES_1
  6821. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  6822. #endif
  6823. break;
  6824. case Texture::CM_fxt1:
  6825. #ifndef OPENGLES
  6826. if (Texture::has_alpha(format)) {
  6827. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  6828. } else {
  6829. return GL_COMPRESSED_RGB_FXT1_3DFX;
  6830. }
  6831. #endif
  6832. break;
  6833. #ifdef OPENGLES
  6834. case Texture::CM_pvr1_2bpp:
  6835. if (Texture::has_alpha(format)) {
  6836. return GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
  6837. } else {
  6838. return GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
  6839. }
  6840. case Texture::CM_pvr1_4bpp:
  6841. if (Texture::has_alpha(format)) {
  6842. return GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
  6843. } else {
  6844. return GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
  6845. }
  6846. #else
  6847. case Texture::CM_pvr1_2bpp:
  6848. case Texture::CM_pvr1_4bpp:
  6849. break;
  6850. #endif // OPENGLES
  6851. case Texture::CM_default:
  6852. case Texture::CM_off:
  6853. case Texture::CM_dxt2:
  6854. case Texture::CM_dxt4:
  6855. // This shouldn't happen.
  6856. nassertr(false, GL_RGB);
  6857. break;
  6858. }
  6859. }
  6860. switch (format) {
  6861. #ifndef OPENGLES
  6862. case Texture::F_color_index:
  6863. return GL_COLOR_INDEX;
  6864. #endif
  6865. case Texture::F_depth_component:
  6866. case Texture::F_depth_component16:
  6867. case Texture::F_depth_component24:
  6868. case Texture::F_depth_component32:
  6869. return GL_DEPTH_COMPONENT;
  6870. case Texture::F_depth_stencil:
  6871. return _supports_depth_stencil ? GL_DEPTH_STENCIL : GL_DEPTH_COMPONENT;
  6872. #ifndef OPENGLES
  6873. case Texture::F_red:
  6874. case Texture::F_r16:
  6875. case Texture::F_r32:
  6876. return GL_RED;
  6877. case Texture::F_green:
  6878. return GL_GREEN;
  6879. case Texture::F_blue:
  6880. return GL_BLUE;
  6881. #endif
  6882. case Texture::F_alpha:
  6883. return GL_ALPHA;
  6884. #ifndef OPENGLES_1
  6885. case Texture::F_rg16:
  6886. case Texture::F_rg32:
  6887. return GL_RG;
  6888. #endif
  6889. case Texture::F_rgb:
  6890. case Texture::F_rgb5:
  6891. case Texture::F_rgb8:
  6892. case Texture::F_rgb12:
  6893. case Texture::F_rgb332:
  6894. case Texture::F_rgb16:
  6895. case Texture::F_rgb32:
  6896. case Texture::F_srgb:
  6897. #ifdef OPENGLES
  6898. return GL_RGB;
  6899. #else
  6900. return _supports_bgr ? GL_BGR : GL_RGB;
  6901. #endif
  6902. case Texture::F_rgba:
  6903. case Texture::F_rgbm:
  6904. case Texture::F_rgba4:
  6905. case Texture::F_rgba5:
  6906. case Texture::F_rgba8:
  6907. case Texture::F_rgba12:
  6908. case Texture::F_rgba16:
  6909. case Texture::F_rgba32:
  6910. case Texture::F_srgb_alpha:
  6911. #ifdef OPENGLES_2
  6912. return GL_RGBA;
  6913. #else
  6914. return _supports_bgr ? GL_BGRA : GL_RGBA;
  6915. #endif
  6916. case Texture::F_luminance:
  6917. case Texture::F_sluminance:
  6918. return GL_LUMINANCE;
  6919. case Texture::F_luminance_alphamask:
  6920. case Texture::F_luminance_alpha:
  6921. case Texture::F_sluminance_alpha:
  6922. return GL_LUMINANCE_ALPHA;
  6923. #ifndef OPENGLES
  6924. case Texture::F_r8i:
  6925. case Texture::F_r32i:
  6926. return GL_RED_INTEGER;
  6927. case Texture::F_rg8i:
  6928. return GL_RG_INTEGER;
  6929. case Texture::F_rgb8i:
  6930. return GL_RGB_INTEGER;
  6931. case Texture::F_rgba8i:
  6932. return GL_RGBA_INTEGER;
  6933. #endif
  6934. default:
  6935. break;
  6936. }
  6937. GLCAT.error()
  6938. << "Invalid Texture::Format value in get_external_image_format(): "
  6939. << tex->get_format() << "\n";
  6940. return GL_RGB;
  6941. }
  6942. ////////////////////////////////////////////////////////////////////
  6943. // Function: GLGraphicsStateGuardian::get_internal_image_format
  6944. // Access: Protected
  6945. // Description: Maps from the Texture's Format symbols to a
  6946. // suitable internal format for GL textures.
  6947. ////////////////////////////////////////////////////////////////////
  6948. GLint CLP(GraphicsStateGuardian)::
  6949. get_internal_image_format(Texture *tex, bool force_sized) const {
  6950. Texture::CompressionMode compression = tex->get_compression();
  6951. if (compression == Texture::CM_default) {
  6952. compression = (compressed_textures) ? Texture::CM_on : Texture::CM_off;
  6953. }
  6954. Texture::Format format = tex->get_format();
  6955. if (tex->get_render_to_texture()) {
  6956. // no compression for render targets
  6957. compression = Texture::CM_off;
  6958. }
  6959. bool is_3d = (tex->get_texture_type() == Texture::TT_3d_texture ||
  6960. tex->get_texture_type() == Texture::TT_2d_texture_array);
  6961. if (get_supports_compressed_texture_format(compression)) {
  6962. switch (compression) {
  6963. case Texture::CM_on:
  6964. // The user asked for just generic compression. OpenGL supports
  6965. // requesting just generic compression, but we'd like to go ahead
  6966. // and request a specific type (if we can figure out an
  6967. // appropriate choice), since that makes saving the result as a
  6968. // pre-compressed texture more dependable--this way, we will know
  6969. // which compression algorithm was applied.
  6970. switch (format) {
  6971. case Texture::F_color_index:
  6972. case Texture::F_depth_component:
  6973. case Texture::F_depth_component16:
  6974. case Texture::F_depth_component24:
  6975. case Texture::F_depth_component32:
  6976. case Texture::F_depth_stencil:
  6977. case Texture::F_r8i:
  6978. case Texture::F_rg8i:
  6979. case Texture::F_rgb8i:
  6980. case Texture::F_rgba8i:
  6981. case Texture::F_r32i:
  6982. // Unsupported; fall through to below.
  6983. break;
  6984. case Texture::F_rgbm:
  6985. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  6986. return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
  6987. }
  6988. #ifndef OPENGLES
  6989. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  6990. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  6991. }
  6992. return GL_COMPRESSED_RGBA;
  6993. #endif
  6994. break;
  6995. case Texture::F_rgba4:
  6996. #ifndef OPENGLES_1
  6997. if (get_supports_compressed_texture_format(Texture::CM_dxt3) && !is_3d) {
  6998. return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
  6999. }
  7000. #endif
  7001. #ifndef OPENGLES
  7002. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7003. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  7004. }
  7005. return GL_COMPRESSED_RGBA;
  7006. #endif
  7007. break;
  7008. case Texture::F_rgba:
  7009. case Texture::F_rgba8:
  7010. case Texture::F_rgba12:
  7011. case Texture::F_rgba16:
  7012. case Texture::F_rgba32:
  7013. #ifndef OPENGLES_1
  7014. if (get_supports_compressed_texture_format(Texture::CM_dxt5) && !is_3d) {
  7015. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  7016. }
  7017. #endif
  7018. #ifndef OPENGLES
  7019. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7020. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  7021. }
  7022. return GL_COMPRESSED_RGBA;
  7023. #endif
  7024. break;
  7025. case Texture::F_rgb:
  7026. case Texture::F_rgb5:
  7027. case Texture::F_rgba5:
  7028. case Texture::F_rgb8:
  7029. case Texture::F_rgb12:
  7030. case Texture::F_rgb332:
  7031. case Texture::F_rgb16:
  7032. case Texture::F_rgb32:
  7033. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  7034. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  7035. }
  7036. #ifndef OPENGLES
  7037. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7038. return GL_COMPRESSED_RGB_FXT1_3DFX;
  7039. }
  7040. return GL_COMPRESSED_RGB;
  7041. #endif
  7042. break;
  7043. case Texture::F_alpha:
  7044. #ifndef OPENGLES_1
  7045. if (get_supports_compressed_texture_format(Texture::CM_dxt5) && !is_3d) {
  7046. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  7047. }
  7048. #endif
  7049. #ifndef OPENGLES
  7050. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7051. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  7052. }
  7053. return GL_COMPRESSED_ALPHA;
  7054. #endif
  7055. break;
  7056. case Texture::F_red:
  7057. case Texture::F_green:
  7058. case Texture::F_blue:
  7059. case Texture::F_r16:
  7060. case Texture::F_r32:
  7061. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  7062. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  7063. }
  7064. #ifndef OPENGLES
  7065. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7066. return GL_COMPRESSED_RGB_FXT1_3DFX;
  7067. }
  7068. return GL_COMPRESSED_RED;
  7069. #endif
  7070. break;
  7071. case Texture::F_rg16:
  7072. case Texture::F_rg32:
  7073. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  7074. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  7075. }
  7076. #ifndef OPENGLES
  7077. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7078. return GL_COMPRESSED_RGB_FXT1_3DFX;
  7079. }
  7080. return GL_COMPRESSED_RG;
  7081. #endif
  7082. break;
  7083. case Texture::F_luminance:
  7084. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  7085. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  7086. }
  7087. #ifndef OPENGLES
  7088. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7089. return GL_COMPRESSED_RGB_FXT1_3DFX;
  7090. }
  7091. return GL_COMPRESSED_LUMINANCE;
  7092. #endif
  7093. break;
  7094. case Texture::F_luminance_alpha:
  7095. case Texture::F_luminance_alphamask:
  7096. #ifndef OPENGLES_1
  7097. if (get_supports_compressed_texture_format(Texture::CM_dxt5) && !is_3d) {
  7098. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  7099. }
  7100. #endif
  7101. #ifndef OPENGLES
  7102. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7103. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  7104. }
  7105. return GL_COMPRESSED_LUMINANCE_ALPHA;
  7106. #endif
  7107. break;
  7108. #ifndef OPENGLES
  7109. case Texture::F_srgb:
  7110. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  7111. return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
  7112. }
  7113. return GL_COMPRESSED_SRGB;
  7114. case Texture::F_srgb_alpha:
  7115. if (get_supports_compressed_texture_format(Texture::CM_dxt5) && !is_3d) {
  7116. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
  7117. }
  7118. return GL_COMPRESSED_SRGB_ALPHA;
  7119. case Texture::F_sluminance:
  7120. return GL_COMPRESSED_SLUMINANCE;
  7121. case Texture::F_sluminance_alpha:
  7122. return GL_COMPRESSED_SLUMINANCE_ALPHA;
  7123. #else
  7124. // For now, we don't support compressed sRGB textures in OpenGL ES.
  7125. case Texture::F_srgb:
  7126. case Texture::F_srgb_alpha:
  7127. case Texture::F_sluminance:
  7128. case Texture::F_sluminance_alpha:
  7129. break;
  7130. #endif
  7131. }
  7132. break;
  7133. case Texture::CM_dxt1:
  7134. #ifndef OPENGLES
  7135. if (format == Texture::F_srgb_alpha) {
  7136. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
  7137. } else if (format == Texture::F_srgb) {
  7138. return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
  7139. } else
  7140. #endif
  7141. if (Texture::has_alpha(format)) {
  7142. return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
  7143. } else {
  7144. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  7145. }
  7146. case Texture::CM_dxt3:
  7147. #ifndef OPENGLES
  7148. if (format == Texture::F_srgb || format == Texture::F_srgb_alpha) {
  7149. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
  7150. }
  7151. #endif
  7152. #ifndef OPENGLES_1
  7153. return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
  7154. #endif
  7155. break;
  7156. case Texture::CM_dxt5:
  7157. #ifndef OPENGLES
  7158. if (format == Texture::F_srgb || format == Texture::F_srgb_alpha) {
  7159. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
  7160. }
  7161. #endif
  7162. #ifndef OPENGLES_1
  7163. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  7164. #endif
  7165. case Texture::CM_fxt1:
  7166. #ifndef OPENGLES
  7167. if (Texture::has_alpha(format)) {
  7168. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  7169. } else {
  7170. return GL_COMPRESSED_RGB_FXT1_3DFX;
  7171. }
  7172. #endif
  7173. break;
  7174. #ifdef OPENGLES
  7175. case Texture::CM_pvr1_2bpp:
  7176. if (Texture::has_alpha(format)) {
  7177. return GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
  7178. } else {
  7179. return GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
  7180. }
  7181. case Texture::CM_pvr1_4bpp:
  7182. if (Texture::has_alpha(format)) {
  7183. return GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
  7184. } else {
  7185. return GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
  7186. }
  7187. #else
  7188. case Texture::CM_pvr1_2bpp:
  7189. case Texture::CM_pvr1_4bpp:
  7190. break;
  7191. #endif
  7192. case Texture::CM_default:
  7193. case Texture::CM_off:
  7194. case Texture::CM_dxt2:
  7195. case Texture::CM_dxt4:
  7196. // No compression: fall through to below.
  7197. break;
  7198. }
  7199. }
  7200. switch (format) {
  7201. #ifndef OPENGLES
  7202. case Texture::F_color_index:
  7203. return GL_COLOR_INDEX;
  7204. #endif
  7205. case Texture::F_depth_stencil:
  7206. if (_supports_depth_stencil) {
  7207. #ifndef OPENGLES
  7208. if (tex->get_component_type() == Texture::T_float) {
  7209. return GL_DEPTH32F_STENCIL8;
  7210. } else
  7211. #endif
  7212. {
  7213. return force_sized ? GL_DEPTH24_STENCIL8 : GL_DEPTH_STENCIL;
  7214. }
  7215. }
  7216. // Fall through.
  7217. case Texture::F_depth_component:
  7218. #ifndef OPENGLES
  7219. if (tex->get_component_type() == Texture::T_float) {
  7220. return GL_DEPTH_COMPONENT32F;
  7221. } else
  7222. #endif
  7223. {
  7224. return force_sized ? GL_DEPTH_COMPONENT16 : GL_DEPTH_COMPONENT;
  7225. }
  7226. case Texture::F_depth_component16:
  7227. #ifdef OPENGLES
  7228. return GL_DEPTH_COMPONENT16_OES;
  7229. #else
  7230. return GL_DEPTH_COMPONENT16;
  7231. #endif
  7232. case Texture::F_depth_component24:
  7233. #ifdef OPENGLES
  7234. if (_supports_depth24) {
  7235. return GL_DEPTH_COMPONENT24_OES;
  7236. } else {
  7237. return GL_DEPTH_COMPONENT16_OES;
  7238. }
  7239. #else
  7240. return GL_DEPTH_COMPONENT24;
  7241. #endif
  7242. case Texture::F_depth_component32:
  7243. #ifdef OPENGLES
  7244. if (_supports_depth32) {
  7245. return GL_DEPTH_COMPONENT32_OES;
  7246. } else if (_supports_depth24) {
  7247. return GL_DEPTH_COMPONENT24_OES;
  7248. } else {
  7249. return GL_DEPTH_COMPONENT16_OES;
  7250. }
  7251. #else
  7252. if (tex->get_component_type() == Texture::T_float) {
  7253. return GL_DEPTH_COMPONENT32F;
  7254. } else {
  7255. return GL_DEPTH_COMPONENT32;
  7256. }
  7257. #endif
  7258. case Texture::F_rgba:
  7259. case Texture::F_rgbm:
  7260. #ifndef OPENGLES_1
  7261. if (tex->get_component_type() == Texture::T_float) {
  7262. return GL_RGBA16F;
  7263. } else
  7264. #endif
  7265. #ifndef OPENGLES
  7266. if (tex->get_component_type() == Texture::T_unsigned_short) {
  7267. return GL_RGBA16;
  7268. } else
  7269. #endif
  7270. {
  7271. return force_sized ? GL_RGBA8 : GL_RGBA;
  7272. }
  7273. case Texture::F_rgba4:
  7274. return GL_RGBA4;
  7275. #ifdef OPENGLES
  7276. case Texture::F_rgba8:
  7277. return GL_RGBA8_OES;
  7278. case Texture::F_rgba12:
  7279. return force_sized ? GL_RGBA8 : GL_RGBA;
  7280. #else
  7281. case Texture::F_rgba8:
  7282. return GL_RGBA8;
  7283. case Texture::F_r8i:
  7284. if (tex->get_component_type() == Texture::T_unsigned_byte) {
  7285. return GL_R8UI;
  7286. } else {
  7287. return GL_R8I;
  7288. }
  7289. case Texture::F_rg8i:
  7290. if (tex->get_component_type() == Texture::T_unsigned_byte) {
  7291. return GL_RG8UI;
  7292. } else {
  7293. return GL_RG8I;
  7294. }
  7295. case Texture::F_rgb8i:
  7296. if (tex->get_component_type() == Texture::T_unsigned_byte) {
  7297. return GL_RGB8UI;
  7298. } else {
  7299. return GL_RGB8I;
  7300. }
  7301. case Texture::F_rgba8i:
  7302. if (tex->get_component_type() == Texture::T_unsigned_byte) {
  7303. return GL_RGBA8UI;
  7304. } else {
  7305. return GL_RGBA8I;
  7306. }
  7307. case Texture::F_rgba12:
  7308. return GL_RGBA12;
  7309. #endif // OPENGLES
  7310. #ifndef OPENGLES
  7311. case Texture::F_rgba16:
  7312. if (tex->get_component_type() == Texture::T_float) {
  7313. return GL_RGBA16F;
  7314. } else {
  7315. return GL_RGBA16;
  7316. }
  7317. case Texture::F_rgba32:
  7318. return GL_RGBA32F;
  7319. #endif // OPENGLES
  7320. case Texture::F_rgb:
  7321. if (tex->get_component_type() == Texture::T_float) {
  7322. return GL_RGB16F;
  7323. } else {
  7324. return force_sized ? GL_RGB8 : GL_RGB;
  7325. }
  7326. case Texture::F_rgb5:
  7327. #ifdef OPENGLES
  7328. // Close enough.
  7329. return GL_RGB565_OES;
  7330. #else
  7331. return GL_RGB5;
  7332. #endif
  7333. case Texture::F_rgba5:
  7334. return GL_RGB5_A1;
  7335. #ifdef OPENGLES
  7336. case Texture::F_rgb8:
  7337. return GL_RGB8_OES;
  7338. case Texture::F_rgb12:
  7339. return force_sized ? GL_RGB8 : GL_RGB;
  7340. case Texture::F_rgb16:
  7341. return GL_RGB16F;
  7342. #else
  7343. case Texture::F_rgb8:
  7344. return GL_RGB8;
  7345. case Texture::F_rgb12:
  7346. return GL_RGB12;
  7347. case Texture::F_rgb16:
  7348. if (tex->get_component_type() == Texture::T_float) {
  7349. return GL_RGB16F;
  7350. } else {
  7351. return GL_RGB16;
  7352. }
  7353. #endif // OPENGLES
  7354. case Texture::F_rgb32:
  7355. return GL_RGB32F;
  7356. #ifndef OPENGLES
  7357. case Texture::F_rgb332:
  7358. return GL_R3_G3_B2;
  7359. #endif
  7360. #if defined(OPENGLES_2)
  7361. case Texture::F_r16:
  7362. return GL_R16F_EXT;
  7363. case Texture::F_rg16:
  7364. return GL_RG16F_EXT;
  7365. #elif !defined(OPENGLES_1)
  7366. case Texture::F_r16:
  7367. if (tex->get_component_type() == Texture::T_float) {
  7368. return GL_R16F;
  7369. } else {
  7370. return GL_R16;
  7371. }
  7372. case Texture::F_rg16:
  7373. if (tex->get_component_type() == Texture::T_float) {
  7374. return GL_RG16F;
  7375. } else {
  7376. return GL_RG16;
  7377. }
  7378. #endif
  7379. #ifndef OPENGLES_1
  7380. case Texture::F_r32:
  7381. return GL_R32F;
  7382. case Texture::F_rg32:
  7383. return GL_RG32F;
  7384. case Texture::F_red:
  7385. case Texture::F_green:
  7386. case Texture::F_blue:
  7387. return force_sized ? GL_R8 : GL_RED;
  7388. #endif
  7389. case Texture::F_alpha:
  7390. return force_sized ? GL_ALPHA8 : GL_ALPHA;
  7391. case Texture::F_luminance:
  7392. #ifndef OPENGLES
  7393. if (tex->get_component_type() == Texture::T_float) {
  7394. return GL_LUMINANCE16F_ARB;
  7395. } else if (tex->get_component_type() == Texture::T_unsigned_short) {
  7396. return GL_LUMINANCE16;
  7397. } else
  7398. #endif // OPENGLES
  7399. {
  7400. return force_sized ? GL_LUMINANCE8 : GL_LUMINANCE;
  7401. }
  7402. case Texture::F_luminance_alpha:
  7403. case Texture::F_luminance_alphamask:
  7404. #ifndef OPENGLES
  7405. if (tex->get_component_type() == Texture::T_float || tex->get_component_type() == Texture::T_unsigned_short) {
  7406. return GL_LUMINANCE_ALPHA16F_ARB;
  7407. } else
  7408. #endif // OPENGLES
  7409. {
  7410. return force_sized ? GL_LUMINANCE8_ALPHA8 : GL_LUMINANCE_ALPHA;
  7411. }
  7412. #ifndef OPENGLES_1
  7413. case Texture::F_srgb:
  7414. #ifndef OPENGLES
  7415. return GL_SRGB8;
  7416. #endif
  7417. case Texture::F_srgb_alpha:
  7418. return GL_SRGB8_ALPHA8;
  7419. #endif
  7420. #ifndef OPENGLES
  7421. case Texture::F_sluminance:
  7422. return GL_SLUMINANCE8;
  7423. case Texture::F_sluminance_alpha:
  7424. return GL_SLUMINANCE8_ALPHA8;
  7425. #endif
  7426. #ifndef OPENGLES
  7427. case Texture::F_r32i:
  7428. return GL_R32I;
  7429. #endif
  7430. default:
  7431. GLCAT.error()
  7432. << "Invalid image format in get_internal_image_format(): "
  7433. << (int)tex->get_format() << "\n";
  7434. return force_sized ? GL_RGB8 : GL_RGB;
  7435. }
  7436. }
  7437. ////////////////////////////////////////////////////////////////////
  7438. // Function: GLGraphicsStateGuardian::is_mipmap_filter
  7439. // Access: Protected, Static
  7440. // Description: Returns true if the indicated GL minfilter type
  7441. // represents a mipmap format, false otherwise.
  7442. ////////////////////////////////////////////////////////////////////
  7443. bool CLP(GraphicsStateGuardian)::
  7444. is_mipmap_filter(GLenum min_filter) {
  7445. switch (min_filter) {
  7446. case GL_NEAREST_MIPMAP_NEAREST:
  7447. case GL_LINEAR_MIPMAP_NEAREST:
  7448. case GL_NEAREST_MIPMAP_LINEAR:
  7449. case GL_LINEAR_MIPMAP_LINEAR:
  7450. return true;
  7451. default:
  7452. return false;
  7453. }
  7454. }
  7455. ////////////////////////////////////////////////////////////////////
  7456. // Function: GLGraphicsStateGuardian::is_compressed_format
  7457. // Access: Protected, Static
  7458. // Description: Returns true if the indicated GL internal format
  7459. // represents a compressed texture format, false
  7460. // otherwise.
  7461. ////////////////////////////////////////////////////////////////////
  7462. bool CLP(GraphicsStateGuardian)::
  7463. is_compressed_format(GLenum format) {
  7464. switch (format) {
  7465. case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  7466. case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  7467. #ifdef OPENGLES
  7468. case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
  7469. case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
  7470. case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
  7471. case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
  7472. #else
  7473. case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
  7474. case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
  7475. case GL_COMPRESSED_RGB_FXT1_3DFX:
  7476. case GL_COMPRESSED_RGBA_FXT1_3DFX:
  7477. case GL_COMPRESSED_RGB:
  7478. case GL_COMPRESSED_RGBA:
  7479. case GL_COMPRESSED_ALPHA:
  7480. case GL_COMPRESSED_LUMINANCE:
  7481. case GL_COMPRESSED_LUMINANCE_ALPHA:
  7482. #endif
  7483. return true;
  7484. default:
  7485. return false;
  7486. }
  7487. }
  7488. ////////////////////////////////////////////////////////////////////
  7489. // Function: GLGraphicsStateGuardian::get_texture_apply_mode_type
  7490. // Access: Protected, Static
  7491. // Description: Maps from the texture stage's mode types
  7492. // to the corresponding OpenGL ids
  7493. ////////////////////////////////////////////////////////////////////
  7494. GLint CLP(GraphicsStateGuardian)::
  7495. get_texture_apply_mode_type(TextureStage::Mode am) {
  7496. #ifndef OPENGLES_2
  7497. switch (am) {
  7498. case TextureStage::M_modulate: return GL_MODULATE;
  7499. case TextureStage::M_decal: return GL_DECAL;
  7500. case TextureStage::M_blend: return GL_BLEND;
  7501. case TextureStage::M_replace: return GL_REPLACE;
  7502. case TextureStage::M_add: return GL_ADD;
  7503. case TextureStage::M_combine: return GL_COMBINE;
  7504. case TextureStage::M_blend_color_scale: return GL_BLEND;
  7505. case TextureStage::M_modulate_glow: return GL_MODULATE;
  7506. case TextureStage::M_modulate_gloss: return GL_MODULATE;
  7507. default:
  7508. // Other modes shouldn't get here. Fall through and error.
  7509. break;
  7510. }
  7511. GLCAT.error()
  7512. << "Invalid TextureStage::Mode value" << endl;
  7513. return GL_MODULATE;
  7514. #else
  7515. return 0;
  7516. #endif
  7517. }
  7518. ////////////////////////////////////////////////////////////////////
  7519. // Function: GLGraphicsStateGuardian::get_texture_combine_type
  7520. // Access: Protected, Static
  7521. // Description: Maps from the texture stage's CombineMode types
  7522. // to the corresponding OpenGL ids
  7523. ////////////////////////////////////////////////////////////////////
  7524. GLint CLP(GraphicsStateGuardian)::
  7525. get_texture_combine_type(TextureStage::CombineMode cm) {
  7526. #ifndef OPENGLES_2
  7527. switch (cm) {
  7528. case TextureStage::CM_undefined: // fall through
  7529. case TextureStage::CM_replace: return GL_REPLACE;
  7530. case TextureStage::CM_modulate: return GL_MODULATE;
  7531. case TextureStage::CM_add: return GL_ADD;
  7532. case TextureStage::CM_add_signed: return GL_ADD_SIGNED;
  7533. case TextureStage::CM_interpolate: return GL_INTERPOLATE;
  7534. case TextureStage::CM_subtract: return GL_SUBTRACT;
  7535. case TextureStage::CM_dot3_rgb: return GL_DOT3_RGB;
  7536. case TextureStage::CM_dot3_rgba: return GL_DOT3_RGBA;
  7537. }
  7538. GLCAT.error()
  7539. << "Invalid TextureStage::CombineMode value" << endl;
  7540. #endif
  7541. return GL_REPLACE;
  7542. }
  7543. ////////////////////////////////////////////////////////////////////
  7544. // Function: GLGraphicsStateGuardian::get_texture_src_type
  7545. // Access: Protected
  7546. // Description: Maps from the texture stage's CombineSource types
  7547. // to the corresponding OpenGL ids
  7548. ////////////////////////////////////////////////////////////////////
  7549. GLint CLP(GraphicsStateGuardian)::
  7550. get_texture_src_type(TextureStage::CombineSource cs,
  7551. int last_stage, int last_saved_result,
  7552. int this_stage) const {
  7553. #ifndef OPENGLES_2
  7554. switch (cs) {
  7555. case TextureStage::CS_undefined: // fall through
  7556. case TextureStage::CS_texture: return GL_TEXTURE;
  7557. case TextureStage::CS_constant: return GL_CONSTANT;
  7558. case TextureStage::CS_primary_color: return GL_PRIMARY_COLOR;
  7559. case TextureStage::CS_constant_color_scale: return GL_CONSTANT;
  7560. case TextureStage::CS_previous:
  7561. if (last_stage == this_stage - 1) {
  7562. return GL_PREVIOUS;
  7563. } else if (last_stage == -1) {
  7564. return GL_PRIMARY_COLOR;
  7565. } else if (_supports_texture_saved_result) {
  7566. return GL_TEXTURE0 + last_stage;
  7567. } else {
  7568. GLCAT.warning()
  7569. << "Current OpenGL driver does not support texture crossbar blending.\n";
  7570. return GL_PRIMARY_COLOR;
  7571. }
  7572. case TextureStage::CS_last_saved_result:
  7573. if (last_saved_result == this_stage - 1) {
  7574. return GL_PREVIOUS;
  7575. } else if (last_saved_result == -1) {
  7576. return GL_PRIMARY_COLOR;
  7577. } else if (_supports_texture_saved_result) {
  7578. return GL_TEXTURE0 + last_saved_result;
  7579. } else {
  7580. GLCAT.warning()
  7581. << "Current OpenGL driver does not support texture crossbar blending.\n";
  7582. return GL_PRIMARY_COLOR;
  7583. }
  7584. }
  7585. GLCAT.error()
  7586. << "Invalid TextureStage::CombineSource value" << endl;
  7587. #endif
  7588. return GL_TEXTURE;
  7589. }
  7590. ////////////////////////////////////////////////////////////////////
  7591. // Function: GLGraphicsStateGuardian::get_texture_operand_type
  7592. // Access: Protected, Static
  7593. // Description: Maps from the texture stage's CombineOperand types
  7594. // to the corresponding OpenGL ids
  7595. ////////////////////////////////////////////////////////////////////
  7596. GLint CLP(GraphicsStateGuardian)::
  7597. get_texture_operand_type(TextureStage::CombineOperand co) {
  7598. switch (co) {
  7599. case TextureStage::CO_undefined: // fall through
  7600. case TextureStage::CO_src_alpha: return GL_SRC_ALPHA;
  7601. case TextureStage::CO_one_minus_src_alpha: return GL_ONE_MINUS_SRC_ALPHA;
  7602. case TextureStage::CO_src_color: return GL_SRC_COLOR;
  7603. case TextureStage::CO_one_minus_src_color: return GL_ONE_MINUS_SRC_COLOR;
  7604. }
  7605. GLCAT.error()
  7606. << "Invalid TextureStage::CombineOperand value" << endl;
  7607. return GL_SRC_COLOR;
  7608. }
  7609. ////////////////////////////////////////////////////////////////////
  7610. // Function: GLGraphicsStateGuardian::get_fog_mode_type
  7611. // Access: Protected, Static
  7612. // Description: Maps from the fog types to gl version
  7613. ////////////////////////////////////////////////////////////////////
  7614. GLenum CLP(GraphicsStateGuardian)::
  7615. get_fog_mode_type(Fog::Mode m) {
  7616. switch(m) {
  7617. case Fog::M_linear: return GL_LINEAR;
  7618. #ifndef OPENGLES_2
  7619. case Fog::M_exponential: return GL_EXP;
  7620. case Fog::M_exponential_squared: return GL_EXP2;
  7621. #endif
  7622. /*
  7623. case Fog::M_spline: return GL_FOG_FUNC_SGIS;
  7624. */
  7625. default:
  7626. GLCAT.error() << "Invalid Fog::Mode value" << endl;
  7627. #ifdef OPENGLES_2
  7628. return GL_LINEAR;
  7629. #else
  7630. return GL_EXP;
  7631. #endif
  7632. }
  7633. }
  7634. ////////////////////////////////////////////////////////////////////
  7635. // Function: GLGraphicsStateGuardian::get_blend_equation_type
  7636. // Access: Protected, Static
  7637. // Description: Maps from ColorBlendAttrib::Mode to glBlendEquation
  7638. // value.
  7639. ////////////////////////////////////////////////////////////////////
  7640. GLenum CLP(GraphicsStateGuardian)::
  7641. get_blend_equation_type(ColorBlendAttrib::Mode mode) {
  7642. switch (mode) {
  7643. case ColorBlendAttrib::M_none:
  7644. case ColorBlendAttrib::M_add:
  7645. return GL_FUNC_ADD;
  7646. case ColorBlendAttrib::M_subtract:
  7647. return GL_FUNC_SUBTRACT;
  7648. case ColorBlendAttrib::M_inv_subtract:
  7649. return GL_FUNC_REVERSE_SUBTRACT;
  7650. #ifdef OPENGLES
  7651. case ColorBlendAttrib::M_min:
  7652. return GL_MIN_EXT;
  7653. case ColorBlendAttrib::M_max:
  7654. return GL_MAX_EXT;
  7655. #else
  7656. case ColorBlendAttrib::M_min:
  7657. return GL_MIN;
  7658. case ColorBlendAttrib::M_max:
  7659. return GL_MAX;
  7660. #endif
  7661. }
  7662. GLCAT.error()
  7663. << "Unknown color blend mode " << (int)mode << endl;
  7664. return GL_FUNC_ADD;
  7665. }
  7666. ////////////////////////////////////////////////////////////////////
  7667. // Function: GLGraphicsStateGuardian::get_blend_func
  7668. // Access: Protected, Static
  7669. // Description: Maps from ColorBlendAttrib::Operand to glBlendFunc
  7670. // value.
  7671. ////////////////////////////////////////////////////////////////////
  7672. GLenum CLP(GraphicsStateGuardian)::
  7673. get_blend_func(ColorBlendAttrib::Operand operand) {
  7674. switch (operand) {
  7675. case ColorBlendAttrib::O_zero:
  7676. return GL_ZERO;
  7677. case ColorBlendAttrib::O_one:
  7678. return GL_ONE;
  7679. case ColorBlendAttrib::O_incoming_color:
  7680. return GL_SRC_COLOR;
  7681. case ColorBlendAttrib::O_one_minus_incoming_color:
  7682. return GL_ONE_MINUS_SRC_COLOR;
  7683. case ColorBlendAttrib::O_fbuffer_color:
  7684. return GL_DST_COLOR;
  7685. case ColorBlendAttrib::O_one_minus_fbuffer_color:
  7686. return GL_ONE_MINUS_DST_COLOR;
  7687. case ColorBlendAttrib::O_incoming_alpha:
  7688. return GL_SRC_ALPHA;
  7689. case ColorBlendAttrib::O_one_minus_incoming_alpha:
  7690. return GL_ONE_MINUS_SRC_ALPHA;
  7691. case ColorBlendAttrib::O_fbuffer_alpha:
  7692. return GL_DST_ALPHA;
  7693. case ColorBlendAttrib::O_one_minus_fbuffer_alpha:
  7694. return GL_ONE_MINUS_DST_ALPHA;
  7695. #ifdef OPENGLES_1
  7696. // OpenGL ES 1 has no constant blend factor.
  7697. case ColorBlendAttrib::O_constant_color:
  7698. case ColorBlendAttrib::O_color_scale:
  7699. case ColorBlendAttrib::O_one_minus_constant_color:
  7700. case ColorBlendAttrib::O_one_minus_color_scale:
  7701. case ColorBlendAttrib::O_constant_alpha:
  7702. case ColorBlendAttrib::O_alpha_scale:
  7703. case ColorBlendAttrib::O_one_minus_constant_alpha:
  7704. case ColorBlendAttrib::O_one_minus_alpha_scale:
  7705. break;
  7706. #else
  7707. case ColorBlendAttrib::O_constant_color:
  7708. case ColorBlendAttrib::O_color_scale:
  7709. return GL_CONSTANT_COLOR;
  7710. case ColorBlendAttrib::O_one_minus_constant_color:
  7711. case ColorBlendAttrib::O_one_minus_color_scale:
  7712. return GL_ONE_MINUS_CONSTANT_COLOR;
  7713. case ColorBlendAttrib::O_constant_alpha:
  7714. case ColorBlendAttrib::O_alpha_scale:
  7715. return GL_CONSTANT_ALPHA;
  7716. case ColorBlendAttrib::O_one_minus_constant_alpha:
  7717. case ColorBlendAttrib::O_one_minus_alpha_scale:
  7718. return GL_ONE_MINUS_CONSTANT_ALPHA;
  7719. #endif
  7720. case ColorBlendAttrib::O_incoming_color_saturate:
  7721. return GL_SRC_ALPHA_SATURATE;
  7722. }
  7723. GLCAT.error()
  7724. << "Unknown color blend operand " << (int)operand << endl;
  7725. return GL_ZERO;
  7726. }
  7727. ////////////////////////////////////////////////////////////////////
  7728. // Function: GLGraphicsStateGuardian::get_usage
  7729. // Access: Public, Static
  7730. // Description: Maps from UsageHint to the GL symbol.
  7731. ////////////////////////////////////////////////////////////////////
  7732. GLenum CLP(GraphicsStateGuardian)::
  7733. get_usage(Geom::UsageHint usage_hint) {
  7734. switch (usage_hint) {
  7735. case Geom::UH_stream:
  7736. #ifdef OPENGLES
  7737. return GL_DYNAMIC_DRAW;
  7738. #else
  7739. return GL_STREAM_DRAW;
  7740. #endif // OPENGLES
  7741. case Geom::UH_static:
  7742. case Geom::UH_unspecified:
  7743. return GL_STATIC_DRAW;
  7744. case Geom::UH_dynamic:
  7745. return GL_DYNAMIC_DRAW;
  7746. case Geom::UH_client:
  7747. break;
  7748. }
  7749. GLCAT.error()
  7750. << "Unexpected usage_hint " << (int)usage_hint << endl;
  7751. return GL_STATIC_DRAW;
  7752. }
  7753. ////////////////////////////////////////////////////////////////////
  7754. // Function: GLGraphicsStateGuardian::print_gfx_visual
  7755. // Access: Public
  7756. // Description: Prints a description of the current visual selected.
  7757. ////////////////////////////////////////////////////////////////////
  7758. void CLP(GraphicsStateGuardian)::
  7759. print_gfx_visual() {
  7760. GLint i;
  7761. GLboolean j;
  7762. cout << "Graphics Visual Info (# bits of each):" << endl;
  7763. cout << "RGBA: ";
  7764. glGetIntegerv( GL_RED_BITS, &i ); cout << i << " ";
  7765. glGetIntegerv( GL_GREEN_BITS, &i ); cout << i << " ";
  7766. glGetIntegerv( GL_BLUE_BITS, &i ); cout << i << " ";
  7767. glGetIntegerv( GL_ALPHA_BITS, &i ); cout << i << endl;
  7768. #ifndef OPENGLES
  7769. cout << "Accum RGBA: ";
  7770. glGetIntegerv( GL_ACCUM_RED_BITS, &i ); cout << i << " ";
  7771. glGetIntegerv( GL_ACCUM_GREEN_BITS, &i ); cout << i << " ";
  7772. glGetIntegerv( GL_ACCUM_BLUE_BITS, &i ); cout << i << " ";
  7773. glGetIntegerv( GL_ACCUM_ALPHA_BITS, &i ); cout << i << endl;
  7774. glGetIntegerv( GL_INDEX_BITS, &i ); cout << "Color Index: " << i << endl;
  7775. #endif
  7776. glGetIntegerv( GL_DEPTH_BITS, &i ); cout << "Depth: " << i << endl;
  7777. glGetIntegerv( GL_ALPHA_BITS, &i ); cout << "Alpha: " << i << endl;
  7778. glGetIntegerv( GL_STENCIL_BITS, &i ); cout << "Stencil: " << i << endl;
  7779. #ifndef OPENGLES
  7780. glGetBooleanv( GL_DOUBLEBUFFER, &j ); cout << "DoubleBuffer? "
  7781. << (int)j << endl;
  7782. glGetBooleanv( GL_STEREO, &j ); cout << "Stereo? " << (int)j << endl;
  7783. #endif
  7784. if (_supports_multisample) {
  7785. #ifndef OPENGLES_2
  7786. glGetBooleanv( GL_MULTISAMPLE, &j ); cout << "Multisample? " << (int)j << endl;
  7787. #endif
  7788. glGetIntegerv( GL_SAMPLES, &i ); cout << "Samples: " << i << endl;
  7789. }
  7790. glGetBooleanv( GL_BLEND, &j ); cout << "Blend? " << (int)j << endl;
  7791. #ifndef OPENGLES_2
  7792. glGetBooleanv( GL_POINT_SMOOTH, &j ); cout << "Point Smooth? "
  7793. << (int)j << endl;
  7794. glGetBooleanv( GL_LINE_SMOOTH, &j ); cout << "Line Smooth? "
  7795. << (int)j << endl;
  7796. #endif
  7797. #ifndef OPENGLES
  7798. glGetIntegerv( GL_AUX_BUFFERS, &i ); cout << "Aux Buffers: " << i << endl;
  7799. #endif
  7800. }
  7801. ////////////////////////////////////////////////////////////////////
  7802. // Function: GLGraphicsStateGuardian::get_light_color
  7803. // Access: Public
  7804. // Description: Returns the value that that should be issued as the
  7805. // light's color, as scaled by the current value of
  7806. // _light_color_scale, in the case of
  7807. // color_scale_via_lighting.
  7808. ////////////////////////////////////////////////////////////////////
  7809. LVecBase4 CLP(GraphicsStateGuardian)::
  7810. get_light_color(Light *light) const {
  7811. #ifndef NDEBUG
  7812. if (_show_texture_usage) {
  7813. // In show_texture_usage mode, all lights are white, so as not to
  7814. // contaminate the texture color.
  7815. return LVecBase4(1.0, 1.0, 1.0, 1.0);
  7816. }
  7817. #endif // NDEBUG
  7818. const LColor &c = light->get_color();
  7819. LVecBase4 light_color(c[0] * _light_color_scale[0],
  7820. c[1] * _light_color_scale[1],
  7821. c[2] * _light_color_scale[2],
  7822. c[3] * _light_color_scale[3]);
  7823. return light_color;
  7824. }
  7825. ////////////////////////////////////////////////////////////////////
  7826. // Function: GLGraphicsStateGuardian::reissue_transforms
  7827. // Access: Protected, Virtual
  7828. // Description: Called by clear_state_and_transform() to ensure that
  7829. // the current modelview and projection matrices are
  7830. // properly loaded in the graphics state, after a
  7831. // callback might have mucked them up.
  7832. ////////////////////////////////////////////////////////////////////
  7833. void CLP(GraphicsStateGuardian)::
  7834. reissue_transforms() {
  7835. prepare_lens();
  7836. do_issue_transform();
  7837. }
  7838. #ifndef OPENGLES_2
  7839. ////////////////////////////////////////////////////////////////////
  7840. // Function: GLGraphicsStateGuardian::enable_lighting
  7841. // Access: Protected, Virtual
  7842. // Description: Intended to be overridden by a derived class to
  7843. // enable or disable the use of lighting overall. This
  7844. // is called by do_issue_light() according to whether any
  7845. // lights are in use or not.
  7846. ////////////////////////////////////////////////////////////////////
  7847. void CLP(GraphicsStateGuardian)::
  7848. enable_lighting(bool enable) {
  7849. // static PStatCollector _draw_set_state_light_enable_lighting_pcollector("Draw:Set State:Light:Enable lighting");
  7850. // PStatGPUTimer timer(this, _draw_set_state_light_enable_lighting_pcollector);
  7851. if (enable) {
  7852. glEnable(GL_LIGHTING);
  7853. } else {
  7854. glDisable(GL_LIGHTING);
  7855. }
  7856. }
  7857. #endif // !OPENGLES_2
  7858. #ifndef OPENGLES_2
  7859. ////////////////////////////////////////////////////////////////////
  7860. // Function: GLGraphicsStateGuardian::set_ambient_light
  7861. // Access: Protected, Virtual
  7862. // Description: Intended to be overridden by a derived class to
  7863. // indicate the color of the ambient light that should
  7864. // be in effect. This is called by do_issue_light() after
  7865. // all other lights have been enabled or disabled.
  7866. ////////////////////////////////////////////////////////////////////
  7867. void CLP(GraphicsStateGuardian)::
  7868. set_ambient_light(const LColor &color) {
  7869. // static PStatCollector _draw_set_state_light_ambient_pcollector("Draw:Set State:Light:Ambient");
  7870. // PStatGPUTimer timer(this, _draw_set_state_light_ambient_pcollector);
  7871. LColor c = color;
  7872. c.set(c[0] * _light_color_scale[0],
  7873. c[1] * _light_color_scale[1],
  7874. c[2] * _light_color_scale[2],
  7875. c[3] * _light_color_scale[3]);
  7876. call_glLightModelfv(GL_LIGHT_MODEL_AMBIENT, c);
  7877. }
  7878. #endif // !OPENGLES_2
  7879. #ifndef OPENGLES_2
  7880. ////////////////////////////////////////////////////////////////////
  7881. // Function: GLGraphicsStateGuardian::enable_light
  7882. // Access: Protected, Virtual
  7883. // Description: Intended to be overridden by a derived class to
  7884. // enable the indicated light id. A specific Light will
  7885. // already have been bound to this id via bind_light().
  7886. ////////////////////////////////////////////////////////////////////
  7887. void CLP(GraphicsStateGuardian)::
  7888. enable_light(int light_id, bool enable) {
  7889. // static PStatCollector _draw_set_state_light_enable_light_pcollector("Draw:Set State:Light:Enable light");
  7890. // PStatGPUTimer timer(this, _draw_set_state_light_enable_light_pcollector);
  7891. if (enable) {
  7892. glEnable(get_light_id(light_id));
  7893. } else {
  7894. glDisable(get_light_id(light_id));
  7895. }
  7896. }
  7897. #endif // !OPENGLES_2
  7898. #ifndef OPENGLES_2
  7899. ////////////////////////////////////////////////////////////////////
  7900. // Function: GLGraphicsStateGuardian::begin_bind_lights
  7901. // Access: Protected, Virtual
  7902. // Description: Called immediately before bind_light() is called,
  7903. // this is intended to provide the derived class a hook
  7904. // in which to set up some state (like transform) that
  7905. // might apply to several lights.
  7906. //
  7907. // The sequence is: begin_bind_lights() will be called,
  7908. // then one or more bind_light() calls, then
  7909. // end_bind_lights().
  7910. ////////////////////////////////////////////////////////////////////
  7911. void CLP(GraphicsStateGuardian)::
  7912. begin_bind_lights() {
  7913. // static PStatCollector _draw_set_state_light_begin_bind_pcollector("Draw:Set State:Light:Begin bind");
  7914. // PStatGPUTimer timer(this, _draw_set_state_light_begin_bind_pcollector);
  7915. // We need to temporarily load a new matrix so we can define the
  7916. // light in a known coordinate system. We pick the transform of the
  7917. // root. (Alternatively, we could leave the current transform where
  7918. // it is and compute the light position relative to that transform
  7919. // instead of relative to the root, by composing with the matrix
  7920. // computed by _internal_transform->invert_compose(render_transform).
  7921. // But I think loading a completely new matrix is simpler.)
  7922. CPT(TransformState) render_transform =
  7923. _cs_transform->compose(_scene_setup->get_world_transform());
  7924. glMatrixMode(GL_MODELVIEW);
  7925. glPushMatrix();
  7926. GLPf(LoadMatrix)(render_transform->get_mat().get_data());
  7927. }
  7928. #endif // !OPENGLES_2
  7929. #ifndef OPENGLES_2
  7930. ////////////////////////////////////////////////////////////////////
  7931. // Function: GLGraphicsStateGuardian::end_bind_lights
  7932. // Access: Protected, Virtual
  7933. // Description: Called after before bind_light() has been called one
  7934. // or more times (but before any geometry is issued or
  7935. // additional state is changed), this is intended to
  7936. // clean up any temporary changes to the state that may
  7937. // have been made by begin_bind_lights().
  7938. ////////////////////////////////////////////////////////////////////
  7939. void CLP(GraphicsStateGuardian)::
  7940. end_bind_lights() {
  7941. // static PStatCollector _draw_set_state_light_end_bind_pcollector("Draw:Set State:Light:End bind");
  7942. // PStatGPUTimer timer(this, _draw_set_state_light_end_bind_pcollector);
  7943. glMatrixMode(GL_MODELVIEW);
  7944. glPopMatrix();
  7945. }
  7946. #endif // !OPENGLES_2
  7947. #ifndef OPENGLES_2
  7948. ////////////////////////////////////////////////////////////////////
  7949. // Function: GLGraphicsStateGuardian::enable_clip_plane
  7950. // Access: Protected, Virtual
  7951. // Description: Intended to be overridden by a derived class to
  7952. // enable the indicated clip_plane id. A specific
  7953. // PlaneNode will already have been bound to this id via
  7954. // bind_clip_plane().
  7955. ////////////////////////////////////////////////////////////////////
  7956. void CLP(GraphicsStateGuardian)::
  7957. enable_clip_plane(int plane_id, bool enable) {
  7958. if (enable) {
  7959. glEnable(get_clip_plane_id(plane_id));
  7960. } else {
  7961. glDisable(get_clip_plane_id(plane_id));
  7962. }
  7963. }
  7964. #endif // !OPENGLES_2
  7965. #ifndef OPENGLES_2
  7966. ////////////////////////////////////////////////////////////////////
  7967. // Function: GLGraphicsStateGuardian::begin_bind_clip_planes
  7968. // Access: Protected, Virtual
  7969. // Description: Called immediately before bind_clip_plane() is called,
  7970. // this is intended to provide the derived class a hook
  7971. // in which to set up some state (like transform) that
  7972. // might apply to several clip_planes.
  7973. //
  7974. // The sequence is: begin_bind_clip_planes() will be called,
  7975. // then one or more bind_clip_plane() calls, then
  7976. // end_bind_clip_planes().
  7977. ////////////////////////////////////////////////////////////////////
  7978. void CLP(GraphicsStateGuardian)::
  7979. begin_bind_clip_planes() {
  7980. // We need to temporarily load a new matrix so we can define the
  7981. // clip_plane in a known coordinate system. We pick the transform of the
  7982. // root. (Alternatively, we could leave the current transform where
  7983. // it is and compute the clip_plane position relative to that transform
  7984. // instead of relative to the root, by composing with the matrix
  7985. // computed by _internal_transform->invert_compose(render_transform).
  7986. // But I think loading a completely new matrix is simpler.)
  7987. CPT(TransformState) render_transform =
  7988. _cs_transform->compose(_scene_setup->get_world_transform());
  7989. glMatrixMode(GL_MODELVIEW);
  7990. glPushMatrix();
  7991. GLPf(LoadMatrix)(render_transform->get_mat().get_data());
  7992. }
  7993. #endif // !OPENGLES_2
  7994. #ifndef OPENGLES_2
  7995. ////////////////////////////////////////////////////////////////////
  7996. // Function: GLGraphicsStateGuardian::bind_clip_plane
  7997. // Access: Protected, Virtual
  7998. // Description: Called the first time a particular clip_plane has been
  7999. // bound to a given id within a frame, this should set
  8000. // up the associated hardware clip_plane with the clip_plane's
  8001. // properties.
  8002. ////////////////////////////////////////////////////////////////////
  8003. void CLP(GraphicsStateGuardian)::
  8004. bind_clip_plane(const NodePath &plane, int plane_id) {
  8005. GLenum id = get_clip_plane_id(plane_id);
  8006. CPT(TransformState) transform = plane.get_transform(_scene_setup->get_scene_root().get_parent());
  8007. const PlaneNode *plane_node;
  8008. DCAST_INTO_V(plane_node, plane.node());
  8009. LPlane xformed_plane = plane_node->get_plane() * transform->get_mat();
  8010. #ifdef OPENGLES
  8011. // OpenGL ES uses a single-precision call.
  8012. LPlanef single_plane(LCAST(float, xformed_plane));
  8013. glClipPlanef(id, single_plane.get_data());
  8014. #else
  8015. // Mainline OpenGL uses a double-precision call.
  8016. LPlaned double_plane(LCAST(double, xformed_plane));
  8017. glClipPlane(id, double_plane.get_data());
  8018. #endif // OPENGLES
  8019. report_my_gl_errors();
  8020. }
  8021. #endif // !OPENGLES_2
  8022. #ifndef OPENGLES_2
  8023. ////////////////////////////////////////////////////////////////////
  8024. // Function: GLGraphicsStateGuardian::end_bind_clip_planes
  8025. // Access: Protected, Virtual
  8026. // Description: Called after before bind_clip_plane() has been called one
  8027. // or more times (but before any geometry is issued or
  8028. // additional state is changed), this is intended to
  8029. // clean up any temporary changes to the state that may
  8030. // have been made by begin_bind_clip_planes().
  8031. ////////////////////////////////////////////////////////////////////
  8032. void CLP(GraphicsStateGuardian)::
  8033. end_bind_clip_planes() {
  8034. glMatrixMode(GL_MODELVIEW);
  8035. glPopMatrix();
  8036. }
  8037. #endif // !OPENGLES_2
  8038. ////////////////////////////////////////////////////////////////////
  8039. // Function: GLGraphicsStateGuardian::set_state_and_transform
  8040. // Access: Public, Virtual
  8041. // Description: Simultaneously resets the render state and the
  8042. // transform state.
  8043. //
  8044. // This transform specified is the "internal" net
  8045. // transform, already converted into the GSG's internal
  8046. // coordinate space by composing it to
  8047. // get_cs_transform(). (Previously, this used to be the
  8048. // "external" net transform, with the assumption that
  8049. // that GSG would convert it internally, but that is no
  8050. // longer the case.)
  8051. //
  8052. // Special case: if (state==NULL), then the target
  8053. // state is already stored in _target.
  8054. ////////////////////////////////////////////////////////////////////
  8055. void CLP(GraphicsStateGuardian)::
  8056. set_state_and_transform(const RenderState *target,
  8057. const TransformState *transform) {
  8058. report_my_gl_errors();
  8059. #ifndef NDEBUG
  8060. if (gsg_cat.is_spam()) {
  8061. gsg_cat.spam() << "Setting GSG state to " << (void *)target << ":\n";
  8062. target->write(gsg_cat.spam(false), 2);
  8063. }
  8064. #endif
  8065. _state_pcollector.add_level(1);
  8066. PStatGPUTimer timer1(this, _draw_set_state_pcollector);
  8067. if (transform != _internal_transform) {
  8068. //PStatGPUTimer timer(this, _draw_set_state_transform_pcollector);
  8069. _transform_state_pcollector.add_level(1);
  8070. _internal_transform = transform;
  8071. do_issue_transform();
  8072. }
  8073. if (target == _state_rs && (_state_mask | _inv_state_mask).is_all_on()) {
  8074. return;
  8075. }
  8076. _target_rs = target;
  8077. _target_shader = (const ShaderAttrib *)
  8078. _target_rs->get_attrib_def(ShaderAttrib::get_class_slot());
  8079. #ifndef OPENGLES_1
  8080. _instance_count = _target_shader->get_instance_count();
  8081. #endif
  8082. #ifndef OPENGLES_2
  8083. int alpha_test_slot = AlphaTestAttrib::get_class_slot();
  8084. if (_target_rs->get_attrib(alpha_test_slot) != _state_rs->get_attrib(alpha_test_slot) ||
  8085. !_state_mask.get_bit(alpha_test_slot) ||
  8086. (_target_shader->get_flag(ShaderAttrib::F_subsume_alpha_test) !=
  8087. _state_shader->get_flag(ShaderAttrib::F_subsume_alpha_test))) {
  8088. //PStatGPUTimer timer(this, _draw_set_state_alpha_test_pcollector);
  8089. do_issue_alpha_test();
  8090. _state_mask.set_bit(alpha_test_slot);
  8091. }
  8092. #endif
  8093. int antialias_slot = AntialiasAttrib::get_class_slot();
  8094. if (_target_rs->get_attrib(antialias_slot) != _state_rs->get_attrib(antialias_slot) ||
  8095. !_state_mask.get_bit(antialias_slot)) {
  8096. //PStatGPUTimer timer(this, _draw_set_state_antialias_pcollector);
  8097. do_issue_antialias();
  8098. _state_mask.set_bit(antialias_slot);
  8099. }
  8100. int clip_plane_slot = ClipPlaneAttrib::get_class_slot();
  8101. if (_target_rs->get_attrib(clip_plane_slot) != _state_rs->get_attrib(clip_plane_slot) ||
  8102. !_state_mask.get_bit(clip_plane_slot)) {
  8103. //PStatGPUTimer timer(this, _draw_set_state_clip_plane_pcollector);
  8104. do_issue_clip_plane();
  8105. _state_mask.set_bit(clip_plane_slot);
  8106. #ifndef OPENGLES_1
  8107. if (_current_shader_context) {
  8108. _current_shader_context->issue_parameters(Shader::SSD_clip_planes);
  8109. }
  8110. #endif
  8111. }
  8112. int color_slot = ColorAttrib::get_class_slot();
  8113. int color_scale_slot = ColorScaleAttrib::get_class_slot();
  8114. if (_target_rs->get_attrib(color_slot) != _state_rs->get_attrib(color_slot) ||
  8115. _target_rs->get_attrib(color_scale_slot) != _state_rs->get_attrib(color_scale_slot) ||
  8116. !_state_mask.get_bit(color_slot) ||
  8117. !_state_mask.get_bit(color_scale_slot)) {
  8118. //PStatGPUTimer timer(this, _draw_set_state_color_pcollector);
  8119. do_issue_color();
  8120. do_issue_color_scale();
  8121. _state_mask.set_bit(color_slot);
  8122. _state_mask.set_bit(color_scale_slot);
  8123. #ifndef OPENGLES_1
  8124. if (_current_shader_context) {
  8125. _current_shader_context->issue_parameters(Shader::SSD_color);
  8126. _current_shader_context->issue_parameters(Shader::SSD_colorscale);
  8127. }
  8128. #endif
  8129. }
  8130. int cull_face_slot = CullFaceAttrib::get_class_slot();
  8131. if (_target_rs->get_attrib(cull_face_slot) != _state_rs->get_attrib(cull_face_slot) ||
  8132. !_state_mask.get_bit(cull_face_slot)) {
  8133. //PStatGPUTimer timer(this, _draw_set_state_cull_face_pcollector);
  8134. do_issue_cull_face();
  8135. _state_mask.set_bit(cull_face_slot);
  8136. }
  8137. int depth_offset_slot = DepthOffsetAttrib::get_class_slot();
  8138. if (_target_rs->get_attrib(depth_offset_slot) != _state_rs->get_attrib(depth_offset_slot) ||
  8139. !_state_mask.get_bit(depth_offset_slot)) {
  8140. //PStatGPUTimer timer(this, _draw_set_state_depth_offset_pcollector);
  8141. do_issue_depth_offset();
  8142. _state_mask.set_bit(depth_offset_slot);
  8143. }
  8144. int depth_test_slot = DepthTestAttrib::get_class_slot();
  8145. if (_target_rs->get_attrib(depth_test_slot) != _state_rs->get_attrib(depth_test_slot) ||
  8146. !_state_mask.get_bit(depth_test_slot)) {
  8147. //PStatGPUTimer timer(this, _draw_set_state_depth_test_pcollector);
  8148. do_issue_depth_test();
  8149. _state_mask.set_bit(depth_test_slot);
  8150. }
  8151. int depth_write_slot = DepthWriteAttrib::get_class_slot();
  8152. if (_target_rs->get_attrib(depth_write_slot) != _state_rs->get_attrib(depth_write_slot) ||
  8153. !_state_mask.get_bit(depth_write_slot)) {
  8154. //PStatGPUTimer timer(this, _draw_set_state_depth_write_pcollector);
  8155. do_issue_depth_write();
  8156. _state_mask.set_bit(depth_write_slot);
  8157. }
  8158. int render_mode_slot = RenderModeAttrib::get_class_slot();
  8159. if (_target_rs->get_attrib(render_mode_slot) != _state_rs->get_attrib(render_mode_slot) ||
  8160. !_state_mask.get_bit(render_mode_slot)) {
  8161. //PStatGPUTimer timer(this, _draw_set_state_render_mode_pcollector);
  8162. do_issue_render_mode();
  8163. _state_mask.set_bit(render_mode_slot);
  8164. }
  8165. #ifndef OPENGLES_2
  8166. int rescale_normal_slot = RescaleNormalAttrib::get_class_slot();
  8167. if (_target_rs->get_attrib(rescale_normal_slot) != _state_rs->get_attrib(rescale_normal_slot) ||
  8168. !_state_mask.get_bit(rescale_normal_slot)) {
  8169. //PStatGPUTimer timer(this, _draw_set_state_rescale_normal_pcollector);
  8170. do_issue_rescale_normal();
  8171. _state_mask.set_bit(rescale_normal_slot);
  8172. }
  8173. #endif
  8174. #ifndef OPENGLES_2
  8175. int shade_model_slot = ShadeModelAttrib::get_class_slot();
  8176. if (_target_rs->get_attrib(shade_model_slot) != _state_rs->get_attrib(shade_model_slot) ||
  8177. !_state_mask.get_bit(shade_model_slot)) {
  8178. //PStatGPUTimer timer(this, _draw_set_state_shade_model_pcollector);
  8179. do_issue_shade_model();
  8180. _state_mask.set_bit(shade_model_slot);
  8181. }
  8182. #endif
  8183. int transparency_slot = TransparencyAttrib::get_class_slot();
  8184. int color_write_slot = ColorWriteAttrib::get_class_slot();
  8185. int color_blend_slot = ColorBlendAttrib::get_class_slot();
  8186. if (_target_rs->get_attrib(transparency_slot) != _state_rs->get_attrib(transparency_slot) ||
  8187. _target_rs->get_attrib(color_write_slot) != _state_rs->get_attrib(color_write_slot) ||
  8188. _target_rs->get_attrib(color_blend_slot) != _state_rs->get_attrib(color_blend_slot) ||
  8189. !_state_mask.get_bit(transparency_slot) ||
  8190. !_state_mask.get_bit(color_write_slot) ||
  8191. !_state_mask.get_bit(color_blend_slot) ||
  8192. (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write) !=
  8193. _state_shader->get_flag(ShaderAttrib::F_disable_alpha_write))) {
  8194. //PStatGPUTimer timer(this, _draw_set_state_blending_pcollector);
  8195. do_issue_blending();
  8196. _state_mask.set_bit(transparency_slot);
  8197. _state_mask.set_bit(color_write_slot);
  8198. _state_mask.set_bit(color_blend_slot);
  8199. }
  8200. if (_target_shader != _state_shader) {
  8201. //PStatGPUTimer timer(this, _draw_set_state_shader_pcollector);
  8202. #ifndef OPENGLES_1
  8203. do_issue_shader(true);
  8204. #endif
  8205. _state_shader = _target_shader;
  8206. _state_mask.clear_bit(TextureAttrib::get_class_slot());
  8207. }
  8208. #ifdef OPENGLES_2
  8209. else { // In the case of OpenGL ES 2.x, we need to glUseShader before we draw anything.
  8210. do_issue_shader(false);
  8211. }
  8212. #endif
  8213. int texture_slot = TextureAttrib::get_class_slot();
  8214. if (_target_rs->get_attrib(texture_slot) != _state_rs->get_attrib(texture_slot) ||
  8215. !_state_mask.get_bit(texture_slot)) {
  8216. //PStatGPUTimer timer(this, _draw_set_state_texture_pcollector);
  8217. determine_target_texture();
  8218. int prev_active = _num_active_texture_stages;
  8219. do_issue_texture();
  8220. // Since the TexGen and TexMatrix states depend partly on the
  8221. // particular set of textures in use, we should force both of
  8222. // those to be reissued every time we change the texture state.
  8223. _state_mask.clear_bit(TexGenAttrib::get_class_slot());
  8224. _state_mask.clear_bit(TexMatrixAttrib::get_class_slot());
  8225. _state_texture = _target_texture;
  8226. _state_mask.set_bit(texture_slot);
  8227. }
  8228. // If one of the previously-loaded TexGen modes modified the texture
  8229. // matrix, then if either state changed, we have to change both of
  8230. // them now.
  8231. #ifndef OPENGLES_2
  8232. if (_tex_gen_modifies_mat) {
  8233. int tex_gen_slot = TexGenAttrib::get_class_slot();
  8234. int tex_matrix_slot = TexMatrixAttrib::get_class_slot();
  8235. if (_target_rs->get_attrib(tex_gen_slot) != _state_rs->get_attrib(tex_gen_slot) ||
  8236. _target_rs->get_attrib(tex_matrix_slot) != _state_rs->get_attrib(tex_matrix_slot) ||
  8237. !_state_mask.get_bit(tex_gen_slot) ||
  8238. !_state_mask.get_bit(tex_matrix_slot)) {
  8239. _state_mask.clear_bit(tex_gen_slot);
  8240. _state_mask.clear_bit(tex_matrix_slot);
  8241. }
  8242. }
  8243. int tex_matrix_slot = TexMatrixAttrib::get_class_slot();
  8244. if (_target_rs->get_attrib(tex_matrix_slot) != _state_rs->get_attrib(tex_matrix_slot) ||
  8245. !_state_mask.get_bit(tex_matrix_slot)) {
  8246. //PStatGPUTimer timer(this, _draw_set_state_tex_matrix_pcollector);
  8247. do_issue_tex_matrix();
  8248. _state_mask.set_bit(tex_matrix_slot);
  8249. }
  8250. #endif
  8251. #ifndef OPENGLES_2
  8252. int tex_gen_slot = TexGenAttrib::get_class_slot();
  8253. if (_target_tex_gen != _state_tex_gen ||
  8254. !_state_mask.get_bit(tex_gen_slot)) {
  8255. //PStatGPUTimer timer(this, _draw_set_state_tex_gen_pcollector);
  8256. do_issue_tex_gen();
  8257. _state_tex_gen = _target_tex_gen;
  8258. _state_mask.set_bit(tex_gen_slot);
  8259. }
  8260. #endif
  8261. int material_slot = MaterialAttrib::get_class_slot();
  8262. if (_target_rs->get_attrib(material_slot) != _state_rs->get_attrib(material_slot) ||
  8263. !_state_mask.get_bit(material_slot)) {
  8264. //PStatGPUTimer timer(this, _draw_set_state_material_pcollector);
  8265. #ifndef OPENGLES_2
  8266. do_issue_material();
  8267. #endif
  8268. _state_mask.set_bit(material_slot);
  8269. #ifndef OPENGLES_1
  8270. if (_current_shader_context) {
  8271. _current_shader_context->issue_parameters(Shader::SSD_material);
  8272. }
  8273. #endif
  8274. }
  8275. int light_slot = LightAttrib::get_class_slot();
  8276. if (_target_rs->get_attrib(light_slot) != _state_rs->get_attrib(light_slot) ||
  8277. !_state_mask.get_bit(light_slot)) {
  8278. //PStatGPUTimer timer(this, _draw_set_state_light_pcollector);
  8279. #ifndef OPENGLES_2
  8280. do_issue_light();
  8281. #endif
  8282. _state_mask.set_bit(light_slot);
  8283. #ifndef OPENGLES_1
  8284. if (_current_shader_context) {
  8285. _current_shader_context->issue_parameters(Shader::SSD_light);
  8286. }
  8287. #endif
  8288. }
  8289. int stencil_slot = StencilAttrib::get_class_slot();
  8290. if (_target_rs->get_attrib(stencil_slot) != _state_rs->get_attrib(stencil_slot) ||
  8291. !_state_mask.get_bit(stencil_slot)) {
  8292. //PStatGPUTimer timer(this, _draw_set_state_stencil_pcollector);
  8293. do_issue_stencil();
  8294. _state_mask.set_bit(stencil_slot);
  8295. }
  8296. int fog_slot = FogAttrib::get_class_slot();
  8297. if (_target_rs->get_attrib(fog_slot) != _state_rs->get_attrib(fog_slot) ||
  8298. !_state_mask.get_bit(fog_slot)) {
  8299. //PStatGPUTimer timer(this, _draw_set_state_fog_pcollector);
  8300. #ifndef OPENGLES_2
  8301. do_issue_fog();
  8302. #endif
  8303. _state_mask.set_bit(fog_slot);
  8304. #ifndef OPENGLES_1
  8305. if (_current_shader_context) {
  8306. _current_shader_context->issue_parameters(Shader::SSD_fog);
  8307. }
  8308. #endif
  8309. }
  8310. int scissor_slot = ScissorAttrib::get_class_slot();
  8311. if (_target_rs->get_attrib(scissor_slot) != _state_rs->get_attrib(scissor_slot) ||
  8312. !_state_mask.get_bit(scissor_slot)) {
  8313. //PStatGPUTimer timer(this, _draw_set_state_scissor_pcollector);
  8314. do_issue_scissor();
  8315. _state_mask.set_bit(scissor_slot);
  8316. }
  8317. _state_rs = _target_rs;
  8318. maybe_gl_finish();
  8319. report_my_gl_errors();
  8320. }
  8321. ////////////////////////////////////////////////////////////////////
  8322. // Function: GLGraphicsStateGuardian::free_pointers
  8323. // Access: Protected, Virtual
  8324. // Description: Frees some memory that was explicitly allocated
  8325. // within the glgsg.
  8326. ////////////////////////////////////////////////////////////////////
  8327. void CLP(GraphicsStateGuardian)::
  8328. free_pointers() {
  8329. #if defined(HAVE_CG) && !defined(OPENGLES)
  8330. if (_cg_context != 0) {
  8331. cgDestroyContext(_cg_context);
  8332. _cg_context = 0;
  8333. }
  8334. #endif
  8335. }
  8336. ////////////////////////////////////////////////////////////////////
  8337. // Function: GLGraphicsStateGuardian::do_auto_rescale_normal
  8338. // Access: Protected
  8339. // Description: Issues the appropriate GL commands to either rescale
  8340. // or normalize the normals according to the current
  8341. // transform.
  8342. ////////////////////////////////////////////////////////////////////
  8343. void CLP(GraphicsStateGuardian)::
  8344. do_auto_rescale_normal() {
  8345. #ifndef OPENGLES_2
  8346. if (_internal_transform->has_identity_scale()) {
  8347. // If there's no scale at all, don't do anything.
  8348. glDisable(GL_NORMALIZE);
  8349. if (GLCAT.is_spam()) {
  8350. GLCAT.spam() << "glDisable(GL_NORMALIZE)\n";
  8351. }
  8352. if (_supports_rescale_normal && support_rescale_normal) {
  8353. glDisable(GL_RESCALE_NORMAL);
  8354. if (GLCAT.is_spam()) {
  8355. GLCAT.spam() << "glDisable(GL_RESCALE_NORMAL)\n";
  8356. }
  8357. }
  8358. } else if (_internal_transform->has_uniform_scale()) {
  8359. // There's a uniform scale; use the rescale feature if available.
  8360. if (_supports_rescale_normal && support_rescale_normal) {
  8361. glEnable(GL_RESCALE_NORMAL);
  8362. glDisable(GL_NORMALIZE);
  8363. if (GLCAT.is_spam()) {
  8364. GLCAT.spam() << "glEnable(GL_RESCALE_NORMAL)\n";
  8365. GLCAT.spam() << "glDisable(GL_NORMALIZE)\n";
  8366. }
  8367. } else {
  8368. glEnable(GL_NORMALIZE);
  8369. if (GLCAT.is_spam()) {
  8370. GLCAT.spam() << "glEnable(GL_NORMALIZE)\n";
  8371. }
  8372. }
  8373. } else {
  8374. // If there's a non-uniform scale, normalize everything.
  8375. glEnable(GL_NORMALIZE);
  8376. if (GLCAT.is_spam()) {
  8377. GLCAT.spam() << "glEnable(GL_NORMALIZE)\n";
  8378. }
  8379. if (_supports_rescale_normal && support_rescale_normal) {
  8380. glDisable(GL_RESCALE_NORMAL);
  8381. if (GLCAT.is_spam()) {
  8382. GLCAT.spam() << "glDisable(GL_RESCALE_NORMAL)\n";
  8383. }
  8384. }
  8385. }
  8386. #endif
  8387. }
  8388. ////////////////////////////////////////////////////////////////////
  8389. // Function: GLGraphicsStateGuardian::do_issue_texture
  8390. // Access: Protected, Virtual
  8391. // Description: This is called by set_state_and_transform() when
  8392. // the texture state has changed.
  8393. ////////////////////////////////////////////////////////////////////
  8394. void CLP(GraphicsStateGuardian)::
  8395. do_issue_texture() {
  8396. DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
  8397. #ifdef OPENGLES_1
  8398. update_standard_texture_bindings();
  8399. #else
  8400. if (_current_shader_context == 0 || !_current_shader_context->uses_custom_texture_bindings()) {
  8401. // No shader, or a non-Cg shader.
  8402. if (_texture_binding_shader_context != 0) {
  8403. _texture_binding_shader_context->disable_shader_texture_bindings();
  8404. }
  8405. #ifndef OPENGLES_2
  8406. update_standard_texture_bindings();
  8407. #endif
  8408. } else {
  8409. if (_texture_binding_shader_context == 0) {
  8410. #ifndef OPENGLES_2
  8411. disable_standard_texture_bindings();
  8412. #endif
  8413. _current_shader_context->update_shader_texture_bindings(NULL);
  8414. } else {
  8415. _current_shader_context->
  8416. update_shader_texture_bindings(_texture_binding_shader_context);
  8417. }
  8418. }
  8419. _texture_binding_shader = _current_shader;
  8420. _texture_binding_shader_context = _current_shader_context;
  8421. #endif
  8422. }
  8423. #ifndef OPENGLES_2
  8424. ////////////////////////////////////////////////////////////////////
  8425. // Function: GLGraphicsStateGuardian::update_standard_texture_bindings
  8426. // Access: Private
  8427. // Description: Applies the appropriate set of textures for the
  8428. // current state, using the standard fixed-function
  8429. // pipeline.
  8430. ////////////////////////////////////////////////////////////////////
  8431. void CLP(GraphicsStateGuardian)::
  8432. update_standard_texture_bindings() {
  8433. #ifndef NDEBUG
  8434. if (_show_texture_usage) {
  8435. update_show_usage_texture_bindings(-1);
  8436. return;
  8437. }
  8438. #endif // NDEBUG
  8439. int num_stages = _target_texture->get_num_on_ff_stages();
  8440. #ifndef NDEBUG
  8441. // Also check the _flash_texture. If it is non-NULL, we need to
  8442. // check to see if our flash_texture is in the texture stack here.
  8443. // If so, then we need to call the special show_texture method
  8444. // instead of the normal texture stack.
  8445. if (_flash_texture != (Texture *)NULL) {
  8446. double now = ClockObject::get_global_clock()->get_frame_time();
  8447. int this_second = (int)floor(now);
  8448. if (this_second & 1) {
  8449. int show_stage_index = -1;
  8450. for (int i = 0; i < num_stages && show_stage_index < 0; ++i) {
  8451. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  8452. Texture *texture = _target_texture->get_on_texture(stage);
  8453. if (texture == _flash_texture) {
  8454. show_stage_index = i;
  8455. }
  8456. }
  8457. if (show_stage_index >= 0) {
  8458. update_show_usage_texture_bindings(show_stage_index);
  8459. return;
  8460. }
  8461. }
  8462. }
  8463. #endif // NDEBUG
  8464. nassertv(num_stages <= _max_texture_stages &&
  8465. _num_active_texture_stages <= _max_texture_stages);
  8466. _texture_involves_color_scale = false;
  8467. int last_saved_result = -1;
  8468. int last_stage = -1;
  8469. int i;
  8470. for (i = 0; i < num_stages; i++) {
  8471. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  8472. Texture *texture = _target_texture->get_on_texture(stage);
  8473. nassertv(texture != (Texture *)NULL);
  8474. // Issue the texture on stage i.
  8475. _glActiveTexture(GL_TEXTURE0 + i);
  8476. // First, turn off the previous texture mode.
  8477. glDisable(GL_TEXTURE_2D);
  8478. if (_supports_cube_map) {
  8479. glDisable(GL_TEXTURE_CUBE_MAP);
  8480. }
  8481. #ifndef OPENGLES
  8482. glDisable(GL_TEXTURE_1D);
  8483. if (_supports_3d_texture) {
  8484. glDisable(GL_TEXTURE_3D);
  8485. }
  8486. #endif // OPENGLES
  8487. int view = get_current_tex_view_offset() + stage->get_tex_view_offset();
  8488. TextureContext *tc = texture->prepare_now(view, _prepared_objects, this);
  8489. if (tc == (TextureContext *)NULL) {
  8490. // Something wrong with this texture; skip it.
  8491. continue;
  8492. }
  8493. // Then, turn on the current texture mode.
  8494. GLenum target = get_texture_target(texture->get_texture_type());
  8495. if (target == GL_NONE) {
  8496. // Unsupported texture mode.
  8497. continue;
  8498. }
  8499. #ifndef OPENGLES
  8500. if (target == GL_TEXTURE_2D_ARRAY_EXT) {
  8501. // Cannot be applied via the FFP.
  8502. continue;
  8503. }
  8504. #endif // OPENGLES
  8505. glEnable(target);
  8506. if (!update_texture(tc, false)) {
  8507. glDisable(target);
  8508. continue;
  8509. }
  8510. apply_texture(tc);
  8511. apply_sampler(i, _target_texture->get_on_sampler(stage), tc);
  8512. if (stage->involves_color_scale() && _color_scale_enabled) {
  8513. LColor color = stage->get_color();
  8514. color.set(color[0] * _current_color_scale[0],
  8515. color[1] * _current_color_scale[1],
  8516. color[2] * _current_color_scale[2],
  8517. color[3] * _current_color_scale[3]);
  8518. _texture_involves_color_scale = true;
  8519. call_glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);
  8520. } else {
  8521. call_glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, stage->get_color());
  8522. }
  8523. if (stage->get_mode() == TextureStage::M_decal) {
  8524. if (texture->get_num_components() < 3 && _supports_texture_combine) {
  8525. // Make a special case for 1- and 2-channel decal textures.
  8526. // OpenGL does not define their use with GL_DECAL for some
  8527. // reason, so implement them using the combiner instead.
  8528. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
  8529. glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
  8530. glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, 1);
  8531. glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1);
  8532. glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
  8533. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
  8534. glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);
  8535. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
  8536. glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_TEXTURE);
  8537. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
  8538. } else {
  8539. // Normal 3- and 4-channel decal textures.
  8540. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  8541. }
  8542. } else if (stage->get_mode() == TextureStage::M_combine) {
  8543. if (!_supports_texture_combine) {
  8544. GLCAT.warning()
  8545. << "TextureStage::M_combine mode is not supported.\n";
  8546. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  8547. } else {
  8548. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
  8549. glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
  8550. glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, stage->get_rgb_scale());
  8551. glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, stage->get_alpha_scale());
  8552. glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,
  8553. get_texture_combine_type(stage->get_combine_rgb_mode()));
  8554. switch (stage->get_num_combine_rgb_operands()) {
  8555. case 3:
  8556. glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB,
  8557. get_texture_src_type(stage->get_combine_rgb_source2(),
  8558. last_stage, last_saved_result, i));
  8559. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB,
  8560. get_texture_operand_type(stage->get_combine_rgb_operand2()));
  8561. // fall through
  8562. case 2:
  8563. glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB,
  8564. get_texture_src_type(stage->get_combine_rgb_source1(),
  8565. last_stage, last_saved_result, i));
  8566. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB,
  8567. get_texture_operand_type(stage->get_combine_rgb_operand1()));
  8568. // fall through
  8569. case 1:
  8570. glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB,
  8571. get_texture_src_type(stage->get_combine_rgb_source0(),
  8572. last_stage, last_saved_result, i));
  8573. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB,
  8574. get_texture_operand_type(stage->get_combine_rgb_operand0()));
  8575. // fall through
  8576. default:
  8577. break;
  8578. }
  8579. glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,
  8580. get_texture_combine_type(stage->get_combine_alpha_mode()));
  8581. switch (stage->get_num_combine_alpha_operands()) {
  8582. case 3:
  8583. glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_ALPHA,
  8584. get_texture_src_type(stage->get_combine_alpha_source2(),
  8585. last_stage, last_saved_result, i));
  8586. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA,
  8587. get_texture_operand_type(stage->get_combine_alpha_operand2()));
  8588. // fall through
  8589. case 2:
  8590. glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA,
  8591. get_texture_src_type(stage->get_combine_alpha_source1(),
  8592. last_stage, last_saved_result, i));
  8593. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA,
  8594. get_texture_operand_type(stage->get_combine_alpha_operand1()));
  8595. // fall through
  8596. case 1:
  8597. glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA,
  8598. get_texture_src_type(stage->get_combine_alpha_source0(),
  8599. last_stage, last_saved_result, i));
  8600. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA,
  8601. get_texture_operand_type(stage->get_combine_alpha_operand0()));
  8602. // fall through
  8603. default:
  8604. break;
  8605. }
  8606. }
  8607. } else {
  8608. GLint glmode = get_texture_apply_mode_type(stage->get_mode());
  8609. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, glmode);
  8610. }
  8611. if (stage->get_saved_result()) {
  8612. // This texture's result will be "saved" for a future stage's
  8613. // input.
  8614. last_saved_result = i;
  8615. } else {
  8616. // This is a regular texture stage; it will be the "previous"
  8617. // input for the next stage.
  8618. last_stage = i;
  8619. }
  8620. }
  8621. // Disable the texture stages that are no longer used.
  8622. for (i = num_stages; i < _num_active_texture_stages; i++) {
  8623. _glActiveTexture(GL_TEXTURE0 + i);
  8624. glDisable(GL_TEXTURE_2D);
  8625. if (_supports_cube_map) {
  8626. glDisable(GL_TEXTURE_CUBE_MAP);
  8627. }
  8628. #ifndef OPENGLES
  8629. glDisable(GL_TEXTURE_1D);
  8630. if (_supports_3d_texture) {
  8631. glDisable(GL_TEXTURE_3D);
  8632. }
  8633. #endif // OPENGLES
  8634. }
  8635. // Save the count of texture stages for next time.
  8636. _num_active_texture_stages = num_stages;
  8637. report_my_gl_errors();
  8638. }
  8639. #endif // !OPENGLES_2
  8640. #ifndef NDEBUG
  8641. ////////////////////////////////////////////////////////////////////
  8642. // Function: GLGraphicsStateGuardian::update_show_usage_texture_bindings
  8643. // Access: Private
  8644. // Description: This is a special function that loads the usage
  8645. // textures in gl-show-texture-usage mode, instead of
  8646. // loading the actual used textures.
  8647. //
  8648. // If the indicated stage_index is >= 0, then it is the
  8649. // particular texture that is shown. Otherwise, the
  8650. // textures are rotated through based on
  8651. // show_texture_usage_index.
  8652. ////////////////////////////////////////////////////////////////////
  8653. void CLP(GraphicsStateGuardian)::
  8654. update_show_usage_texture_bindings(int show_stage_index) {
  8655. int num_stages = _target_texture->get_num_on_ff_stages();
  8656. nassertv(num_stages <= _max_texture_stages &&
  8657. _num_active_texture_stages <= _max_texture_stages);
  8658. _texture_involves_color_scale = false;
  8659. // First, we walk through the list of textures and pretend to render
  8660. // them all, even though we don't actually render them, just so
  8661. // Panda will keep track of the list of "active" textures correctly
  8662. // during the flash.
  8663. int i;
  8664. for (i = 0; i < num_stages; i++) {
  8665. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  8666. Texture *texture = _target_texture->get_on_texture(stage);
  8667. nassertv(texture != (Texture *)NULL);
  8668. int view = get_current_tex_view_offset() + stage->get_tex_view_offset();
  8669. TextureContext *tc = texture->prepare_now(view, _prepared_objects, this);
  8670. if (tc == (TextureContext *)NULL) {
  8671. // Something wrong with this texture; skip it.
  8672. break;
  8673. }
  8674. tc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  8675. }
  8676. #ifndef OPENGLES_2
  8677. // Disable all texture stages.
  8678. for (i = 0; i < _num_active_texture_stages; i++) {
  8679. _glActiveTexture(GL_TEXTURE0 + i);
  8680. #ifndef OPENGLES
  8681. glDisable(GL_TEXTURE_1D);
  8682. #endif // OPENGLES
  8683. glDisable(GL_TEXTURE_2D);
  8684. if (_supports_3d_texture) {
  8685. #ifndef OPENGLES_1
  8686. glDisable(GL_TEXTURE_3D);
  8687. #endif // OPENGLES_1
  8688. }
  8689. if (_supports_cube_map) {
  8690. glDisable(GL_TEXTURE_CUBE_MAP);
  8691. }
  8692. }
  8693. #endif
  8694. // Save the count of texture stages for next time.
  8695. _num_active_texture_stages = num_stages;
  8696. if (num_stages > 0) {
  8697. // Now, pick just one texture stage to apply.
  8698. if (show_stage_index >= 0 && show_stage_index < num_stages) {
  8699. i = show_stage_index;
  8700. } else {
  8701. i = _show_texture_usage_index % num_stages;
  8702. }
  8703. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  8704. Texture *texture = _target_texture->get_on_texture(stage);
  8705. nassertv(texture != (Texture *)NULL);
  8706. // Choose the corresponding usage texture and apply it.
  8707. _glActiveTexture(GL_TEXTURE0 + i);
  8708. #ifndef OPENGLES_2
  8709. glEnable(GL_TEXTURE_2D);
  8710. #endif
  8711. UsageTextureKey key(texture->get_x_size(), texture->get_y_size());
  8712. UsageTextures::iterator ui = _usage_textures.find(key);
  8713. if (ui == _usage_textures.end()) {
  8714. // Need to create a new texture for this size.
  8715. GLuint index;
  8716. glGenTextures(1, &index);
  8717. glBindTexture(GL_TEXTURE_2D, index);
  8718. //TODO: this could be a lot simpler with glTexStorage2D
  8719. // followed by a call to glClearTexImage.
  8720. upload_usage_texture(texture->get_x_size(), texture->get_y_size());
  8721. _usage_textures[key] = index;
  8722. } else {
  8723. // Just bind the previously-created texture.
  8724. GLuint index = (*ui).second;
  8725. glBindTexture(GL_TEXTURE_2D, index);
  8726. }
  8727. //TODO: glBindSampler(0) ?
  8728. }
  8729. report_my_gl_errors();
  8730. }
  8731. #endif // NDEBUG
  8732. #ifndef NDEBUG
  8733. ////////////////////////////////////////////////////////////////////
  8734. // Function: GLGraphicsStateGuardian::upload_usage_texture
  8735. // Access: Protected
  8736. // Description: Uploads a special "usage" texture intended to be
  8737. // applied only in gl-show-texture-usage mode, to reveal
  8738. // where texture memory is being spent.
  8739. ////////////////////////////////////////////////////////////////////
  8740. void CLP(GraphicsStateGuardian)::
  8741. upload_usage_texture(int width, int height) {
  8742. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  8743. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  8744. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  8745. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  8746. if (GLCAT.is_debug()) {
  8747. GLCAT.debug()
  8748. << "upload_usage_texture(" << width << ", " << height << ")\n";
  8749. }
  8750. static LColor colors[3] = {
  8751. LColor(0.4, 0.5f, 0.8f, 1.0f), // mipmap 0: blue
  8752. LColor(1.0f, 1.0f, 0.0f, 1.0f), // mipmap 1: yellow
  8753. LColor(0.8f, 0.3, 0.3, 1.0f), // mipmap 2 and higher: red
  8754. };
  8755. // Allocate a temporary array large enough to contain the toplevel
  8756. // mipmap.
  8757. PN_uint32 *buffer = (PN_uint32 *)PANDA_MALLOC_ARRAY(width * height * 4);
  8758. int n = 0;
  8759. while (true) {
  8760. // Choose the color for the nth mipmap.
  8761. LColor c = colors[min(n, 2)];
  8762. // A simple union to store the colors values bytewise, and get the
  8763. // answer wordwise, independently of machine byte-ordernig.
  8764. union {
  8765. struct {
  8766. unsigned char r, g, b, a;
  8767. } b;
  8768. PN_uint32 w;
  8769. } store;
  8770. store.b.r = (unsigned char)(c[0] * 255.0f);
  8771. store.b.g = (unsigned char)(c[1] * 255.0f);
  8772. store.b.b = (unsigned char)(c[2] * 255.0f);
  8773. store.b.a = 0xff;
  8774. // Fill in the array.
  8775. int num_pixels = width * height;
  8776. for (int p = 0; p < num_pixels; ++p) {
  8777. buffer[p] = store.w;
  8778. }
  8779. glTexImage2D(GL_TEXTURE_2D, n, GL_RGBA, width, height, 0,
  8780. GL_RGBA, GL_UNSIGNED_BYTE, buffer);
  8781. if (width == 1 && height == 1) {
  8782. // That was the last mipmap level.
  8783. break;
  8784. }
  8785. width = max(width >> 1, 1);
  8786. height = max(height >> 1, 1);
  8787. ++n;
  8788. }
  8789. PANDA_FREE_ARRAY(buffer);
  8790. }
  8791. #endif // NDEBUG
  8792. #ifndef OPENGLES_2
  8793. ////////////////////////////////////////////////////////////////////
  8794. // Function: GLGraphicsStateGuardian::disable_standard_texture_bindings
  8795. // Access: Private
  8796. // Description:
  8797. ////////////////////////////////////////////////////////////////////
  8798. void CLP(GraphicsStateGuardian)::
  8799. disable_standard_texture_bindings() {
  8800. // Disable the texture stages that are no longer used.
  8801. for (int i = 0; i < _num_active_texture_stages; i++) {
  8802. _glActiveTexture(GL_TEXTURE0 + i);
  8803. #ifndef OPENGLES
  8804. glDisable(GL_TEXTURE_1D);
  8805. #endif // OPENGLES
  8806. glDisable(GL_TEXTURE_2D);
  8807. if (_supports_3d_texture) {
  8808. #ifndef OPENGLES_1
  8809. glDisable(GL_TEXTURE_3D);
  8810. #endif // OPENGLES_1
  8811. }
  8812. if (_supports_cube_map) {
  8813. glDisable(GL_TEXTURE_CUBE_MAP);
  8814. }
  8815. }
  8816. _num_active_texture_stages = 0;
  8817. report_my_gl_errors();
  8818. }
  8819. #endif // !OPENGLES_2
  8820. #ifndef OPENGLES_2
  8821. ////////////////////////////////////////////////////////////////////
  8822. // Function: GLGraphicsStateGuardian::do_issue_tex_matrix
  8823. // Access: Protected
  8824. // Description:
  8825. ////////////////////////////////////////////////////////////////////
  8826. void CLP(GraphicsStateGuardian)::
  8827. do_issue_tex_matrix() {
  8828. nassertv(_num_active_texture_stages <= _max_texture_stages);
  8829. for (int i = 0; i < _num_active_texture_stages; i++) {
  8830. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  8831. _glActiveTexture(GL_TEXTURE0 + i);
  8832. glMatrixMode(GL_TEXTURE);
  8833. const TexMatrixAttrib *target_tex_matrix;
  8834. _target_rs->get_attrib_def(target_tex_matrix);
  8835. if (target_tex_matrix->has_stage(stage)) {
  8836. GLPf(LoadMatrix)(target_tex_matrix->get_mat(stage).get_data());
  8837. } else {
  8838. glLoadIdentity();
  8839. // For some reason, the glLoadIdentity() call doesn't work on
  8840. // my Dell laptop's IBM OpenGL driver, when used in
  8841. // conjunction with glTexGen(), below. But explicitly loading
  8842. // an identity matrix does work. But this buggy-driver
  8843. // workaround might have other performance implications, so I
  8844. // leave it out.
  8845. // GLPf(LoadMatrix)(LMatrix4::ident_mat().get_data());
  8846. }
  8847. }
  8848. report_my_gl_errors();
  8849. }
  8850. #endif // !OPENGLES_2
  8851. #ifndef OPENGLES_2
  8852. ////////////////////////////////////////////////////////////////////
  8853. // Function: GLGraphicsStateGuardian::do_issue_tex_gen
  8854. // Access: Protected
  8855. // Description:
  8856. ////////////////////////////////////////////////////////////////////
  8857. void CLP(GraphicsStateGuardian)::
  8858. do_issue_tex_gen() {
  8859. bool force_normal = false;
  8860. nassertv(_num_active_texture_stages <= _max_texture_stages);
  8861. // These are passed in for the four OBJECT_PLANE or EYE_PLANE
  8862. // values; they effectively define an identity matrix that maps
  8863. // the spatial coordinates one-for-one to UV's. If you want a
  8864. // mapping other than identity, use a TexMatrixAttrib (or a
  8865. // TexProjectorEffect).
  8866. static const PN_stdfloat s_data[4] = { 1, 0, 0, 0 };
  8867. static const PN_stdfloat t_data[4] = { 0, 1, 0, 0 };
  8868. static const PN_stdfloat r_data[4] = { 0, 0, 1, 0 };
  8869. static const PN_stdfloat q_data[4] = { 0, 0, 0, 1 };
  8870. _tex_gen_modifies_mat = false;
  8871. bool got_point_sprites = false;
  8872. for (int i = 0; i < _num_active_texture_stages; i++) {
  8873. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  8874. _glActiveTexture(GL_TEXTURE0 + i);
  8875. if (_supports_point_sprite) {
  8876. #ifdef OPENGLES
  8877. glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_FALSE);
  8878. #else
  8879. glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_FALSE);
  8880. #endif // OPENGLES
  8881. }
  8882. #ifndef OPENGLES // TexGen not supported by OpenGL ES.
  8883. glDisable(GL_TEXTURE_GEN_S);
  8884. glDisable(GL_TEXTURE_GEN_T);
  8885. glDisable(GL_TEXTURE_GEN_R);
  8886. glDisable(GL_TEXTURE_GEN_Q);
  8887. TexGenAttrib::Mode mode = _target_tex_gen->get_mode(stage);
  8888. switch (mode) {
  8889. case TexGenAttrib::M_off:
  8890. case TexGenAttrib::M_unused2:
  8891. break;
  8892. case TexGenAttrib::M_eye_sphere_map:
  8893. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  8894. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  8895. glEnable(GL_TEXTURE_GEN_S);
  8896. glEnable(GL_TEXTURE_GEN_T);
  8897. force_normal = true;
  8898. break;
  8899. case TexGenAttrib::M_eye_cube_map:
  8900. if (_supports_cube_map) {
  8901. // We need to rotate the normals out of GL's coordinate
  8902. // system and into the user's coordinate system. We do this
  8903. // by composing a transform onto the texture matrix.
  8904. LMatrix4 mat = _inv_cs_transform->get_mat();
  8905. mat.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
  8906. glMatrixMode(GL_TEXTURE);
  8907. GLPf(MultMatrix)(mat.get_data());
  8908. // Now we need to reset the texture matrix next time
  8909. // around to undo this.
  8910. _tex_gen_modifies_mat = true;
  8911. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  8912. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  8913. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  8914. glEnable(GL_TEXTURE_GEN_S);
  8915. glEnable(GL_TEXTURE_GEN_T);
  8916. glEnable(GL_TEXTURE_GEN_R);
  8917. force_normal = true;
  8918. }
  8919. break;
  8920. case TexGenAttrib::M_world_cube_map:
  8921. if (_supports_cube_map) {
  8922. // We dynamically transform normals from eye space to world
  8923. // space by applying the appropriate rotation transform to
  8924. // the current texture matrix. Unlike M_world_position, we
  8925. // can't achieve this effect by monkeying with the modelview
  8926. // transform, since the current modelview doesn't affect
  8927. // GL_REFLECTION_MAP.
  8928. CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
  8929. LMatrix4 mat = camera_transform->get_mat();
  8930. mat.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
  8931. glMatrixMode(GL_TEXTURE);
  8932. GLPf(MultMatrix)(mat.get_data());
  8933. // Now we need to reset the texture matrix next time
  8934. // around to undo this.
  8935. _tex_gen_modifies_mat = true;
  8936. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  8937. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  8938. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  8939. glEnable(GL_TEXTURE_GEN_S);
  8940. glEnable(GL_TEXTURE_GEN_T);
  8941. glEnable(GL_TEXTURE_GEN_R);
  8942. force_normal = true;
  8943. }
  8944. break;
  8945. case TexGenAttrib::M_eye_normal:
  8946. if (_supports_cube_map) {
  8947. // We need to rotate the normals out of GL's coordinate
  8948. // system and into the user's coordinate system. We do this
  8949. // by composing a transform onto the texture matrix.
  8950. LMatrix4 mat = _inv_cs_transform->get_mat();
  8951. mat.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
  8952. glMatrixMode(GL_TEXTURE);
  8953. GLPf(MultMatrix)(mat.get_data());
  8954. // Now we need to reset the texture matrix next time
  8955. // around to undo this.
  8956. _tex_gen_modifies_mat = true;
  8957. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  8958. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  8959. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  8960. glEnable(GL_TEXTURE_GEN_S);
  8961. glEnable(GL_TEXTURE_GEN_T);
  8962. glEnable(GL_TEXTURE_GEN_R);
  8963. force_normal = true;
  8964. }
  8965. break;
  8966. case TexGenAttrib::M_world_normal:
  8967. if (_supports_cube_map) {
  8968. // We dynamically transform normals from eye space to world
  8969. // space by applying the appropriate rotation transform to
  8970. // the current texture matrix. Unlike M_world_position, we
  8971. // can't achieve this effect by monkeying with the modelview
  8972. // transform, since the current modelview doesn't affect
  8973. // GL_NORMAL_MAP.
  8974. CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
  8975. LMatrix4 mat = camera_transform->get_mat();
  8976. mat.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
  8977. glMatrixMode(GL_TEXTURE);
  8978. GLPf(MultMatrix)(mat.get_data());
  8979. // Now we need to reset the texture matrix next time
  8980. // around to undo this.
  8981. _tex_gen_modifies_mat = true;
  8982. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  8983. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  8984. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  8985. glEnable(GL_TEXTURE_GEN_S);
  8986. glEnable(GL_TEXTURE_GEN_T);
  8987. glEnable(GL_TEXTURE_GEN_R);
  8988. force_normal = true;
  8989. }
  8990. break;
  8991. case TexGenAttrib::M_eye_position:
  8992. // To represent eye position correctly, we need to temporarily
  8993. // load the coordinate-system transform.
  8994. glMatrixMode(GL_MODELVIEW);
  8995. glPushMatrix();
  8996. GLPf(LoadMatrix)(_cs_transform->get_mat().get_data());
  8997. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  8998. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  8999. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  9000. glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  9001. GLPfv(TexGen)(GL_S, GL_EYE_PLANE, s_data);
  9002. GLPfv(TexGen)(GL_T, GL_EYE_PLANE, t_data);
  9003. GLPfv(TexGen)(GL_R, GL_EYE_PLANE, r_data);
  9004. GLPfv(TexGen)(GL_Q, GL_EYE_PLANE, q_data);
  9005. glEnable(GL_TEXTURE_GEN_S);
  9006. glEnable(GL_TEXTURE_GEN_T);
  9007. glEnable(GL_TEXTURE_GEN_R);
  9008. glEnable(GL_TEXTURE_GEN_Q);
  9009. glMatrixMode(GL_MODELVIEW);
  9010. glPopMatrix();
  9011. break;
  9012. case TexGenAttrib::M_world_position:
  9013. // We achieve world position coordinates by using the eye
  9014. // position mode, and loading the transform of the root
  9015. // node--thus putting the "eye" at the root.
  9016. {
  9017. glMatrixMode(GL_MODELVIEW);
  9018. glPushMatrix();
  9019. CPT(TransformState) root_transform = _cs_transform->compose(_scene_setup->get_world_transform());
  9020. GLPf(LoadMatrix)(root_transform->get_mat().get_data());
  9021. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  9022. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  9023. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  9024. glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  9025. GLPfv(TexGen)(GL_S, GL_EYE_PLANE, s_data);
  9026. GLPfv(TexGen)(GL_T, GL_EYE_PLANE, t_data);
  9027. GLPfv(TexGen)(GL_R, GL_EYE_PLANE, r_data);
  9028. GLPfv(TexGen)(GL_Q, GL_EYE_PLANE, q_data);
  9029. glEnable(GL_TEXTURE_GEN_S);
  9030. glEnable(GL_TEXTURE_GEN_T);
  9031. glEnable(GL_TEXTURE_GEN_R);
  9032. glEnable(GL_TEXTURE_GEN_Q);
  9033. glMatrixMode(GL_MODELVIEW);
  9034. glPopMatrix();
  9035. }
  9036. break;
  9037. case TexGenAttrib::M_point_sprite:
  9038. if (_supports_point_sprite) {
  9039. #ifdef OPENGLES
  9040. glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE);
  9041. #else
  9042. glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
  9043. #endif
  9044. got_point_sprites = true;
  9045. }
  9046. break;
  9047. case TexGenAttrib::M_constant:
  9048. // To generate a constant UV(w) coordinate everywhere, we use
  9049. // EYE_LINEAR mode, but we construct a special matrix that
  9050. // flattens the vertex position to zero and then adds our
  9051. // desired value.
  9052. {
  9053. const LTexCoord3 &v = _target_tex_gen->get_constant_value(stage);
  9054. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  9055. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  9056. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  9057. glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  9058. LVecBase4 s(0.0f, 0.0f, 0.0f, v[0]);
  9059. LVecBase4 t(0.0f, 0.0f, 0.0f, v[1]);
  9060. LVecBase4 r(0.0f, 0.0f, 0.0f, v[2]);
  9061. GLPfv(TexGen)(GL_S, GL_OBJECT_PLANE, s.get_data());
  9062. GLPfv(TexGen)(GL_T, GL_OBJECT_PLANE, t.get_data());
  9063. GLPfv(TexGen)(GL_R, GL_OBJECT_PLANE, r.get_data());
  9064. GLPfv(TexGen)(GL_Q, GL_OBJECT_PLANE, q_data);
  9065. glEnable(GL_TEXTURE_GEN_S);
  9066. glEnable(GL_TEXTURE_GEN_T);
  9067. glEnable(GL_TEXTURE_GEN_R);
  9068. glEnable(GL_TEXTURE_GEN_Q);
  9069. }
  9070. break;
  9071. case TexGenAttrib::M_unused:
  9072. break;
  9073. }
  9074. #endif // OPENGLES
  9075. }
  9076. if (got_point_sprites != _tex_gen_point_sprite) {
  9077. _tex_gen_point_sprite = got_point_sprites;
  9078. #ifdef OPENGLES
  9079. if (_tex_gen_point_sprite) {
  9080. glEnable(GL_POINT_SPRITE_OES);
  9081. } else {
  9082. glDisable(GL_POINT_SPRITE_OES);
  9083. }
  9084. #else
  9085. if (_tex_gen_point_sprite) {
  9086. glEnable(GL_POINT_SPRITE_ARB);
  9087. } else {
  9088. glDisable(GL_POINT_SPRITE_ARB);
  9089. }
  9090. #endif // OPENGLES
  9091. }
  9092. report_my_gl_errors();
  9093. }
  9094. #endif // !OPENGLES_2
  9095. ////////////////////////////////////////////////////////////////////
  9096. // Function: GLGraphicsStateGuardian::specify_texture
  9097. // Access: Protected
  9098. // Description: Specifies the texture parameters. Returns true if
  9099. // the texture may need to be reloaded. Pass non-NULL
  9100. // sampler argument to use different sampler settings.
  9101. ////////////////////////////////////////////////////////////////////
  9102. bool CLP(GraphicsStateGuardian)::
  9103. specify_texture(CLP(TextureContext) *gtc, const SamplerState &sampler) {
  9104. nassertr(gtc->_handle == 0 /* can't modify tex with active handle */, false);
  9105. Texture *tex = gtc->get_texture();
  9106. GLenum target = get_texture_target(tex->get_texture_type());
  9107. if (target == GL_NONE) {
  9108. // Unsupported target (e.g. 3-d texturing on GL 1.1).
  9109. return false;
  9110. }
  9111. // Record the active sampler settings.
  9112. gtc->_active_sampler = sampler;
  9113. glTexParameteri(target, GL_TEXTURE_WRAP_S,
  9114. get_texture_wrap_mode(sampler.get_wrap_u()));
  9115. #ifndef OPENGLES
  9116. if (target != GL_TEXTURE_1D) {
  9117. glTexParameteri(target, GL_TEXTURE_WRAP_T,
  9118. get_texture_wrap_mode(sampler.get_wrap_v()));
  9119. }
  9120. #endif
  9121. #ifdef OPENGLES_2
  9122. if (target == GL_TEXTURE_3D_OES) {
  9123. glTexParameteri(target, GL_TEXTURE_WRAP_R_OES,
  9124. get_texture_wrap_mode(sampler.get_wrap_w()));
  9125. }
  9126. #endif
  9127. #ifndef OPENGLES
  9128. if (target == GL_TEXTURE_3D) {
  9129. glTexParameteri(target, GL_TEXTURE_WRAP_R,
  9130. get_texture_wrap_mode(sampler.get_wrap_w()));
  9131. }
  9132. LColor border_color = sampler.get_border_color();
  9133. call_glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, border_color);
  9134. #endif // OPENGLES
  9135. SamplerState::FilterType minfilter = sampler.get_effective_minfilter();
  9136. SamplerState::FilterType magfilter = sampler.get_effective_magfilter();
  9137. bool uses_mipmaps = SamplerState::is_mipmap(minfilter) && !gl_ignore_mipmaps;
  9138. #ifndef NDEBUG
  9139. if (gl_force_mipmaps) {
  9140. minfilter = SamplerState::FT_linear_mipmap_linear;
  9141. magfilter = SamplerState::FT_linear;
  9142. uses_mipmaps = true;
  9143. }
  9144. #endif
  9145. if (!tex->might_have_ram_image()) {
  9146. // If it's a dynamically generated texture (that is, the RAM image
  9147. // isn't available so it didn't pass through the CPU), we should
  9148. // enable GL-generated mipmaps if we can.
  9149. if (!_supports_generate_mipmap) {
  9150. // However, if the GPU doesn't support mipmap generation, we
  9151. // have to turn it off.
  9152. uses_mipmaps = false;
  9153. }
  9154. }
  9155. glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
  9156. get_texture_filter_type(minfilter, !uses_mipmaps));
  9157. glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
  9158. get_texture_filter_type(magfilter, true));
  9159. // Set anisotropic filtering.
  9160. if (_supports_anisotropy) {
  9161. PN_stdfloat anisotropy = sampler.get_effective_anisotropic_degree();
  9162. anisotropy = min(anisotropy, _max_anisotropy);
  9163. anisotropy = max(anisotropy, (PN_stdfloat)1.0);
  9164. glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
  9165. }
  9166. #ifndef OPENGLES_1
  9167. if (tex->get_format() == Texture::F_depth_stencil ||
  9168. tex->get_format() == Texture::F_depth_component ||
  9169. tex->get_format() == Texture::F_depth_component16 ||
  9170. tex->get_format() == Texture::F_depth_component24 ||
  9171. tex->get_format() == Texture::F_depth_component32) {
  9172. #ifndef OPENGLES
  9173. glTexParameteri(target, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
  9174. #endif
  9175. if (_supports_shadow_filter) {
  9176. if ((sampler.get_magfilter() == SamplerState::FT_shadow) ||
  9177. (sampler.get_minfilter() == SamplerState::FT_shadow)) {
  9178. glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
  9179. glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
  9180. } else {
  9181. glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
  9182. glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
  9183. }
  9184. }
  9185. }
  9186. #endif
  9187. #ifndef OPENGLES
  9188. glTexParameterf(target, GL_TEXTURE_MIN_LOD, sampler.get_min_lod());
  9189. glTexParameterf(target, GL_TEXTURE_MAX_LOD, sampler.get_max_lod());
  9190. glTexParameterf(target, GL_TEXTURE_LOD_BIAS, sampler.get_lod_bias());
  9191. #endif
  9192. report_my_gl_errors();
  9193. if (uses_mipmaps && !gtc->_uses_mipmaps) {
  9194. // Suddenly we require mipmaps. This means the texture may need
  9195. // reloading.
  9196. return true;
  9197. }
  9198. return false;
  9199. }
  9200. ////////////////////////////////////////////////////////////////////
  9201. // Function: GLGraphicsStateGuardian::apply_texture
  9202. // Access: Protected
  9203. // Description: Updates OpenGL with the current information for this
  9204. // texture, and makes it the current texture available
  9205. // for rendering.
  9206. ////////////////////////////////////////////////////////////////////
  9207. bool CLP(GraphicsStateGuardian)::
  9208. apply_texture(TextureContext *tc) {
  9209. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
  9210. gtc->set_active(true);
  9211. GLenum target = get_texture_target(gtc->get_texture()->get_texture_type());
  9212. if (target == GL_NONE) {
  9213. return false;
  9214. }
  9215. if (gtc->_target != target) {
  9216. // The target has changed. That means we have to re-bind a new
  9217. // texture object.
  9218. gtc->reset_data();
  9219. gtc->_target = target;
  9220. }
  9221. glBindTexture(target, gtc->_index);
  9222. report_my_gl_errors();
  9223. return true;
  9224. }
  9225. ////////////////////////////////////////////////////////////////////
  9226. // Function: GLGraphicsStateGuardian::apply_sampler
  9227. // Access: Protected
  9228. // Description: Updates OpenGL with the current information for this
  9229. // sampler, and makes it the current sampler available
  9230. // for rendering. Use NULL to unbind the sampler.
  9231. //
  9232. // If the GSG doesn't support sampler objects, the
  9233. // sampler settings are applied to the given texture
  9234. // context instead.
  9235. ////////////////////////////////////////////////////////////////////
  9236. bool CLP(GraphicsStateGuardian)::
  9237. apply_sampler(GLuint unit, const SamplerState &sampler, TextureContext *tc) {
  9238. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
  9239. #ifndef OPENGLES
  9240. if (_supports_sampler_objects) {
  9241. // We support sampler objects. Prepare the sampler object and
  9242. // bind it to the indicated texture unit.
  9243. SamplerContext *sc = sampler.prepare_now(get_prepared_objects(), this);
  9244. nassertr(sc != (SamplerContext *)NULL, false);
  9245. CLP(SamplerContext) *gsc = DCAST(CLP(SamplerContext), sc);
  9246. gsc->enqueue_lru(&_prepared_objects->_sampler_object_lru);
  9247. _glBindSampler(unit, gsc->_index);
  9248. if (GLCAT.is_spam()) {
  9249. GLCAT.spam()
  9250. << "bind " << unit << " " << sampler << "\n";
  9251. }
  9252. } else
  9253. #endif // OPENGLES
  9254. {
  9255. // We don't support sampler objects. We'll have to bind the
  9256. // texture and change the texture parameters if they don't match.
  9257. if (gtc->_active_sampler != sampler) {
  9258. _glActiveTexture(GL_TEXTURE0 + unit);
  9259. apply_texture(tc);
  9260. specify_texture(gtc, sampler);
  9261. }
  9262. }
  9263. if (sampler.uses_mipmaps() && !gtc->_uses_mipmaps) {
  9264. // The texture wasn't created with mipmaps, but we are trying
  9265. // to sample it with mipmaps. We will need to reload it.
  9266. apply_texture(tc);
  9267. gtc->mark_needs_reload();
  9268. bool okflag = upload_texture(gtc, false, true);
  9269. if (!okflag) {
  9270. GLCAT.error()
  9271. << "Could not load " << *gtc->get_texture() << "\n";
  9272. return false;
  9273. }
  9274. }
  9275. report_my_gl_errors();
  9276. return true;
  9277. }
  9278. ////////////////////////////////////////////////////////////////////
  9279. // Function: GLGraphicsStateGuardian::upload_texture
  9280. // Access: Protected
  9281. // Description: Uploads the entire texture image to OpenGL, including
  9282. // all pages.
  9283. //
  9284. // The return value is true if successful, or false if
  9285. // the texture has no image.
  9286. ////////////////////////////////////////////////////////////////////
  9287. bool CLP(GraphicsStateGuardian)::
  9288. upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
  9289. PStatGPUTimer timer(this, _load_texture_pcollector);
  9290. Texture *tex = gtc->get_texture();
  9291. if (_effective_incomplete_render && !force) {
  9292. bool has_image = _supports_compressed_texture ? tex->has_ram_image() : tex->has_uncompressed_ram_image();
  9293. if (!has_image && tex->might_have_ram_image() &&
  9294. tex->has_simple_ram_image() &&
  9295. !_loader.is_null()) {
  9296. // If we don't have the texture data right now, go get it, but in
  9297. // the meantime load a temporary simple image in its place.
  9298. async_reload_texture(gtc);
  9299. has_image = _supports_compressed_texture ? tex->has_ram_image() : tex->has_uncompressed_ram_image();
  9300. if (!has_image) {
  9301. if (gtc->was_simple_image_modified()) {
  9302. return upload_simple_texture(gtc);
  9303. }
  9304. return true;
  9305. }
  9306. }
  9307. }
  9308. CPTA_uchar image;
  9309. if (_supports_compressed_texture) {
  9310. image = tex->get_ram_image();
  9311. } else {
  9312. image = tex->get_uncompressed_ram_image();
  9313. }
  9314. Texture::CompressionMode image_compression;
  9315. if (image.is_null()) {
  9316. image_compression = Texture::CM_off;
  9317. } else {
  9318. image_compression = tex->get_ram_image_compression();
  9319. }
  9320. if (!get_supports_compressed_texture_format(image_compression)) {
  9321. image = tex->get_uncompressed_ram_image();
  9322. image_compression = Texture::CM_off;
  9323. }
  9324. int mipmap_bias = 0;
  9325. int width = tex->get_x_size();
  9326. int height = tex->get_y_size();
  9327. int depth = tex->get_z_size();
  9328. // If we'll use immutable texture storage, we have to pick a sized
  9329. // image format.
  9330. bool force_sized = (gl_immutable_texture_storage && _supports_tex_storage);
  9331. GLint internal_format = get_internal_image_format(tex, force_sized);
  9332. GLint external_format = get_external_image_format(tex);
  9333. GLenum component_type = get_component_type(tex->get_component_type());
  9334. if (GLCAT.is_debug()) {
  9335. if (image.is_null()) {
  9336. GLCAT.debug()
  9337. << "loading texture with NULL image";
  9338. } else if (image_compression != Texture::CM_off) {
  9339. GLCAT.debug()
  9340. << "loading pre-compressed texture";
  9341. } else if (is_compressed_format(internal_format)) {
  9342. GLCAT.debug()
  9343. << "loading compressed texture";
  9344. } else {
  9345. GLCAT.debug()
  9346. << "loading uncompressed texture";
  9347. }
  9348. GLCAT.debug(false) << " " << tex->get_name() << "\n";
  9349. }
  9350. // Ensure that the texture fits within the GL's specified limits.
  9351. // Need to split dimensions because of texture arrays
  9352. int max_dimension_x;
  9353. int max_dimension_y;
  9354. int max_dimension_z;
  9355. switch (tex->get_texture_type()) {
  9356. case Texture::TT_3d_texture:
  9357. max_dimension_x = _max_3d_texture_dimension;
  9358. max_dimension_y = _max_3d_texture_dimension;
  9359. max_dimension_z = _max_3d_texture_dimension;
  9360. break;
  9361. case Texture::TT_cube_map:
  9362. max_dimension_x = _max_cube_map_dimension;
  9363. max_dimension_y = _max_cube_map_dimension;
  9364. max_dimension_z = 6;
  9365. break;
  9366. case Texture::TT_2d_texture_array:
  9367. max_dimension_x = _max_texture_dimension;
  9368. max_dimension_y = _max_texture_dimension;
  9369. max_dimension_z = _max_2d_texture_array_layers;
  9370. break;
  9371. default:
  9372. max_dimension_x = _max_texture_dimension;
  9373. max_dimension_y = _max_texture_dimension;
  9374. max_dimension_z = 1;
  9375. }
  9376. if (max_dimension_x == 0 || max_dimension_y == 0 || max_dimension_z == 0) {
  9377. // Guess this GL doesn't support cube mapping/3d textures/2d texture arrays.
  9378. report_my_gl_errors();
  9379. return false;
  9380. }
  9381. // If it doesn't fit, we have to reduce it on-the-fly. We do this
  9382. // by incrementing the mipmap_bias, so we're effectively loading a
  9383. // lower mipmap level. This requires generating the mipmaps on
  9384. // the CPU if they haven't already been generated. It would have
  9385. // been better if the user had specified max-texture-dimension to
  9386. // reduce the texture at load time instead; of course, the user
  9387. // doesn't always know ahead of time what the hardware limits are.
  9388. if ((max_dimension_x > 0 && max_dimension_y > 0 && max_dimension_z > 0) &&
  9389. image_compression == Texture::CM_off) {
  9390. while (tex->get_expected_mipmap_x_size(mipmap_bias) > max_dimension_x ||
  9391. tex->get_expected_mipmap_y_size(mipmap_bias) > max_dimension_y ||
  9392. tex->get_expected_mipmap_z_size(mipmap_bias) > max_dimension_z) {
  9393. ++mipmap_bias;
  9394. }
  9395. if (mipmap_bias >= tex->get_num_ram_mipmap_images()) {
  9396. // We need to generate some more mipmap images.
  9397. if (tex->has_ram_image()) {
  9398. tex->generate_ram_mipmap_images();
  9399. if (mipmap_bias >= tex->get_num_ram_mipmap_images()) {
  9400. // It didn't work. Send the smallest we've got, and hope
  9401. // for the best.
  9402. mipmap_bias = tex->get_num_ram_mipmap_images() - 1;
  9403. }
  9404. }
  9405. }
  9406. width = tex->get_expected_mipmap_x_size(mipmap_bias);
  9407. height = tex->get_expected_mipmap_y_size(mipmap_bias);
  9408. depth = tex->get_expected_mipmap_z_size(mipmap_bias);
  9409. if (mipmap_bias != 0) {
  9410. GLCAT.info()
  9411. << "Reducing image " << tex->get_name()
  9412. << " from " << tex->get_x_size() << " x " << tex->get_y_size()
  9413. << " x " << tex->get_z_size() << " to "
  9414. << width << " x " << height << " x " << depth << "\n";
  9415. }
  9416. }
  9417. if (image_compression != Texture::CM_off) {
  9418. Texture::QualityLevel quality_level = tex->get_effective_quality_level();
  9419. #ifndef OPENGLES
  9420. switch (quality_level) {
  9421. case Texture::QL_fastest:
  9422. glHint(GL_TEXTURE_COMPRESSION_HINT, GL_FASTEST);
  9423. break;
  9424. case Texture::QL_default:
  9425. case Texture::QL_normal:
  9426. glHint(GL_TEXTURE_COMPRESSION_HINT, GL_DONT_CARE);
  9427. break;
  9428. case Texture::QL_best:
  9429. glHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST);
  9430. break;
  9431. }
  9432. #endif
  9433. }
  9434. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  9435. GLenum target = get_texture_target(tex->get_texture_type());
  9436. uses_mipmaps = (uses_mipmaps && !gl_ignore_mipmaps) || gl_force_mipmaps;
  9437. bool needs_reload = false;
  9438. if (!gtc->_has_storage ||
  9439. gtc->_uses_mipmaps != uses_mipmaps ||
  9440. gtc->_internal_format != internal_format ||
  9441. gtc->_width != width ||
  9442. gtc->_height != height ||
  9443. gtc->_depth != depth) {
  9444. // We need to reload a new GL Texture object.
  9445. needs_reload = true;
  9446. }
  9447. if (needs_reload && gtc->_immutable) {
  9448. GLCAT.warning() << "Attempt to modify texture with immutable storage, recreating texture.\n";
  9449. gtc->reset_data();
  9450. glBindTexture(target, gtc->_index);
  9451. }
  9452. if (needs_reload) {
  9453. if (_use_object_labels) {
  9454. // This seems like a good time to assign a label for the debug messages.
  9455. const string &name = tex->get_name();
  9456. _glObjectLabel(GL_TEXTURE, gtc->_index, name.size(), name.data());
  9457. }
  9458. // Figure out whether mipmaps will be generated by the GPU or by
  9459. // Panda (or not at all), and how many mipmap levels should be created.
  9460. gtc->_generate_mipmaps = false;
  9461. int num_levels = 1;
  9462. CPTA_uchar image = tex->get_ram_mipmap_image(mipmap_bias);
  9463. if (image.is_null()) {
  9464. // We don't even have a RAM image, so we have no choice but to let
  9465. // mipmaps be generated on the GPU.
  9466. if (uses_mipmaps) {
  9467. if (_supports_generate_mipmap) {
  9468. num_levels = tex->get_expected_num_mipmap_levels() - mipmap_bias;
  9469. gtc->_generate_mipmaps = true;
  9470. } else {
  9471. // If it can't, do without mipmaps.
  9472. num_levels = 1;
  9473. glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  9474. }
  9475. }
  9476. } else {
  9477. if (uses_mipmaps) {
  9478. num_levels = tex->get_num_ram_mipmap_images() - mipmap_bias;
  9479. if (num_levels <= 1) {
  9480. // No RAM mipmap levels available. Should we generate some?
  9481. if (!_supports_generate_mipmap || !driver_generate_mipmaps ||
  9482. image_compression != Texture::CM_off) {
  9483. // Yes, the GL can't or won't generate them, so we need to.
  9484. // Note that some drivers (nVidia) will *corrupt memory* if
  9485. // you ask them to generate mipmaps for a pre-compressed
  9486. // texture.
  9487. tex->generate_ram_mipmap_images();
  9488. num_levels = tex->get_num_ram_mipmap_images() - mipmap_bias;
  9489. }
  9490. }
  9491. if (num_levels <= 1) {
  9492. // We don't have mipmap levels in RAM. Ask the GL to generate
  9493. // them if it can.
  9494. if (_supports_generate_mipmap) {
  9495. num_levels = tex->get_expected_num_mipmap_levels() - mipmap_bias;
  9496. gtc->_generate_mipmaps = true;
  9497. } else {
  9498. // If it can't, do without mipmaps.
  9499. glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  9500. num_levels = 1;
  9501. }
  9502. }
  9503. }
  9504. }
  9505. #ifndef OPENGLES // OpenGL ES doesn't have GL_TEXTURE_MAX_LEVEL.
  9506. if (is_at_least_gl_version(1, 2)) {
  9507. // By the time we get here, we have a pretty good prediction for
  9508. // the number of mipmaps we're going to have, so tell the GL that's
  9509. // all it's going to get.
  9510. glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, num_levels - 1);
  9511. }
  9512. #endif
  9513. #ifndef OPENGLES_2
  9514. if (gtc->_generate_mipmaps && _glGenerateMipmap == NULL) {
  9515. // The old, deprecated way to generate mipmaps.
  9516. glTexParameteri(target, GL_GENERATE_MIPMAP, GL_TRUE);
  9517. }
  9518. #endif
  9519. // Allocate immutable storage for the texture, after which we can subload it.
  9520. // Pre-allocating storage using glTexStorage is more efficient than using glTexImage
  9521. // to load all of the individual images one by one later, but we are not allowed to
  9522. // change the texture size or number of mipmap levels after this point.
  9523. if (gl_immutable_texture_storage && _supports_tex_storage && !gtc->_has_storage) {
  9524. if (GLCAT.is_debug()) {
  9525. GLCAT.debug()
  9526. << "allocating storage for texture " << tex->get_name() << ", " << width
  9527. << " x " << height << " x " << depth << ", mipmaps " << num_levels
  9528. << ", uses_mipmaps = " << uses_mipmaps << "\n";
  9529. }
  9530. switch (tex->get_texture_type()) {
  9531. case Texture::TT_1d_texture:
  9532. _glTexStorage1D(target, num_levels, internal_format, width);
  9533. break;
  9534. case Texture::TT_2d_texture:
  9535. case Texture::TT_cube_map:
  9536. _glTexStorage2D(target, num_levels, internal_format, width, height);
  9537. break;
  9538. case Texture::TT_3d_texture:
  9539. case Texture::TT_2d_texture_array:
  9540. _glTexStorage3D(target, num_levels, internal_format, width, height, depth);
  9541. break;
  9542. }
  9543. gtc->_has_storage = true;
  9544. gtc->_immutable = true;
  9545. gtc->_uses_mipmaps = uses_mipmaps;
  9546. gtc->_internal_format = internal_format;
  9547. gtc->_width = width;
  9548. gtc->_height = height;
  9549. gtc->_depth = depth;
  9550. needs_reload = false;
  9551. }
  9552. } else {
  9553. // Maybe we need to generate mipmaps on the CPU.
  9554. if (!image.is_null() && uses_mipmaps) {
  9555. if (tex->get_num_ram_mipmap_images() - mipmap_bias <= 1) {
  9556. // No RAM mipmap levels available. Should we generate some?
  9557. if (!_supports_generate_mipmap || !driver_generate_mipmaps ||
  9558. image_compression != Texture::CM_off) {
  9559. // Yes, the GL can't or won't generate them, so we need to.
  9560. // Note that some drivers (nVidia) will *corrupt memory* if
  9561. // you ask them to generate mipmaps for a pre-compressed
  9562. // texture.
  9563. tex->generate_ram_mipmap_images();
  9564. }
  9565. }
  9566. }
  9567. }
  9568. bool success = true;
  9569. if (tex->get_texture_type() == Texture::TT_cube_map) {
  9570. // A cube map must load six different 2-d images (which are stored
  9571. // as the six pages of the system ram image).
  9572. if (!_supports_cube_map) {
  9573. report_my_gl_errors();
  9574. return false;
  9575. }
  9576. nassertr(target == GL_TEXTURE_CUBE_MAP, false);
  9577. success = success && upload_texture_image
  9578. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  9579. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
  9580. internal_format, external_format, component_type,
  9581. true, 0, image_compression);
  9582. success = success && upload_texture_image
  9583. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  9584. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
  9585. internal_format, external_format, component_type,
  9586. true, 1, image_compression);
  9587. success = success && upload_texture_image
  9588. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  9589. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
  9590. internal_format, external_format, component_type,
  9591. true, 2, image_compression);
  9592. success = success && upload_texture_image
  9593. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  9594. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
  9595. internal_format, external_format, component_type,
  9596. true, 3, image_compression);
  9597. success = success && upload_texture_image
  9598. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  9599. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
  9600. internal_format, external_format, component_type,
  9601. true, 4, image_compression);
  9602. success = success && upload_texture_image
  9603. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  9604. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
  9605. internal_format, external_format, component_type,
  9606. true, 5, image_compression);
  9607. } else {
  9608. // Any other kind of texture can be loaded all at once.
  9609. success = upload_texture_image
  9610. (gtc, needs_reload, uses_mipmaps, mipmap_bias, target,
  9611. target, internal_format, external_format,
  9612. component_type, false, 0, image_compression);
  9613. }
  9614. if (gtc->_generate_mipmaps && _glGenerateMipmap != NULL &&
  9615. !image.is_null()) {
  9616. // We uploaded an image; we may need to generate mipmaps.
  9617. if (GLCAT.is_debug()) {
  9618. GLCAT.debug()
  9619. << "generating mipmaps for texture " << tex->get_name() << ", "
  9620. << width << " x " << height << " x " << depth
  9621. << ", uses_mipmaps = " << uses_mipmaps << "\n";
  9622. }
  9623. _glGenerateMipmap(target);
  9624. }
  9625. maybe_gl_finish();
  9626. if (success) {
  9627. if (needs_reload) {
  9628. gtc->_has_storage = true;
  9629. gtc->_uses_mipmaps = uses_mipmaps;
  9630. gtc->_internal_format = internal_format;
  9631. gtc->_width = width;
  9632. gtc->_height = height;
  9633. gtc->_depth = depth;
  9634. }
  9635. if (!image.is_null()) {
  9636. gtc->update_data_size_bytes(get_texture_memory_size(tex));
  9637. }
  9638. if (tex->get_post_load_store_cache()) {
  9639. tex->set_post_load_store_cache(false);
  9640. // OK, get the RAM image, and save it in a BamCache record.
  9641. if (do_extract_texture_data(gtc)) {
  9642. if (tex->has_ram_image()) {
  9643. BamCache *cache = BamCache::get_global_ptr();
  9644. PT(BamCacheRecord) record = cache->lookup(tex->get_fullpath(), "txo");
  9645. if (record != (BamCacheRecord *)NULL) {
  9646. record->set_data(tex, tex);
  9647. cache->store(record);
  9648. }
  9649. }
  9650. }
  9651. }
  9652. GraphicsEngine *engine = get_engine();
  9653. nassertr(engine != (GraphicsEngine *)NULL, false);
  9654. engine->texture_uploaded(tex);
  9655. gtc->mark_loaded();
  9656. report_my_gl_errors();
  9657. return true;
  9658. }
  9659. report_my_gl_errors();
  9660. return false;
  9661. }
  9662. ////////////////////////////////////////////////////////////////////
  9663. // Function: GLGraphicsStateGuardian::upload_texture_image
  9664. // Access: Protected
  9665. // Description: Loads a texture image, or one page of a cube map
  9666. // image, from system RAM to texture memory.
  9667. //
  9668. // texture_target is normally the same thing as
  9669. // page_target; both represent the GL target onto which
  9670. // the texture image is loaded, e.g. GL_TEXTURE_1D,
  9671. // GL_TEXTURE_2D, etc. The only time they may differ is
  9672. // in the case of cube mapping, in which case
  9673. // texture_target will be target for the overall
  9674. // texture, e.g. GL_TEXTURE_CUBE_MAP, and page_target
  9675. // will be the target for this particular page,
  9676. // e.g. GL_TEXTURE_CUBE_MAP_POSITIVE_X.
  9677. ////////////////////////////////////////////////////////////////////
  9678. bool CLP(GraphicsStateGuardian)::
  9679. upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
  9680. bool uses_mipmaps, int mipmap_bias,
  9681. GLenum texture_target, GLenum page_target,
  9682. GLint internal_format,
  9683. GLint external_format, GLenum component_type,
  9684. bool one_page_only, int z,
  9685. Texture::CompressionMode image_compression) {
  9686. // Make sure the error stack is cleared out before we begin.
  9687. clear_my_gl_errors();
  9688. if (texture_target == GL_NONE) {
  9689. // Unsupported target (e.g. 3-d texturing on GL 1.1).
  9690. return false;
  9691. }
  9692. if (image_compression != Texture::CM_off && !_supports_compressed_texture) {
  9693. return false;
  9694. }
  9695. Texture *tex = gtc->get_texture();
  9696. nassertr(tex != (Texture *)NULL, false);
  9697. CPTA_uchar image = tex->get_ram_mipmap_image(mipmap_bias);
  9698. int width = tex->get_expected_mipmap_x_size(mipmap_bias);
  9699. int height = tex->get_expected_mipmap_y_size(mipmap_bias);
  9700. int depth = tex->get_expected_mipmap_z_size(mipmap_bias);
  9701. // Determine the number of images to upload.
  9702. int num_levels = 1;
  9703. if (uses_mipmaps) {
  9704. num_levels = tex->get_expected_num_mipmap_levels();
  9705. }
  9706. int num_ram_mipmap_levels = 0;
  9707. if (!image.is_null()) {
  9708. if (uses_mipmaps) {
  9709. num_ram_mipmap_levels = tex->get_num_ram_mipmap_images();
  9710. } else {
  9711. num_ram_mipmap_levels = 1;
  9712. }
  9713. }
  9714. #ifndef OPENGLES
  9715. if (needs_reload || num_ram_mipmap_levels > 0) {
  9716. // Make sure that any incoherent writes to this texture have been synced.
  9717. if (gtc->needs_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT)) {
  9718. issue_memory_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
  9719. }
  9720. }
  9721. #endif
  9722. if (!needs_reload) {
  9723. // Try to subload the image over the existing GL Texture object,
  9724. // possibly saving on texture memory fragmentation.
  9725. if (GLCAT.is_debug()) {
  9726. if (num_ram_mipmap_levels == 0) {
  9727. if (tex->has_clear_color()) {
  9728. GLCAT.debug()
  9729. << "clearing texture " << tex->get_name() << ", "
  9730. << width << " x " << height << " x " << depth << ", z = " << z
  9731. << ", uses_mipmaps = " << uses_mipmaps << ", clear_color = "
  9732. << tex->get_clear_color() << "\n";
  9733. } else {
  9734. GLCAT.debug()
  9735. << "not loading NULL image for texture " << tex->get_name()
  9736. << ", " << width << " x " << height << " x " << depth
  9737. << ", z = " << z << ", uses_mipmaps = " << uses_mipmaps << "\n";
  9738. }
  9739. } else {
  9740. GLCAT.debug()
  9741. << "updating image data of texture " << tex->get_name()
  9742. << ", " << width << " x " << height << " x " << depth
  9743. << ", z = " << z << ", mipmaps " << num_ram_mipmap_levels
  9744. << ", uses_mipmaps = " << uses_mipmaps << "\n";
  9745. }
  9746. }
  9747. for (int n = mipmap_bias; n < num_levels; ++n) {
  9748. // we grab the mipmap pointer first, if it is NULL we grab the
  9749. // normal mipmap image pointer which is a PTA_uchar
  9750. const unsigned char *image_ptr = (unsigned char*)tex->get_ram_mipmap_pointer(n);
  9751. CPTA_uchar ptimage;
  9752. if (image_ptr == (const unsigned char *)NULL) {
  9753. ptimage = tex->get_ram_mipmap_image(n);
  9754. if (ptimage.is_null()) {
  9755. if (n < num_ram_mipmap_levels) {
  9756. // We were told we'd have this many RAM mipmap images, but
  9757. // we don't. Raise a warning.
  9758. GLCAT.warning()
  9759. << "No mipmap level " << n << " defined for " << tex->get_name()
  9760. << "\n";
  9761. break;
  9762. }
  9763. if (tex->has_clear_color()) {
  9764. // The texture has a clear color, so we should fill this mipmap
  9765. // level to a solid color.
  9766. #ifndef OPENGLES
  9767. if (_supports_clear_texture) {
  9768. // We can do that with the convenient glClearTexImage function.
  9769. string clear_data = tex->get_clear_data();
  9770. _glClearTexImage(gtc->_index, n - mipmap_bias, external_format,
  9771. component_type, (void *)clear_data.data());
  9772. continue;
  9773. }
  9774. #endif // OPENGLES
  9775. // Ask the Texture class to create the mipmap level in RAM.
  9776. // It'll fill it in with the correct clear color, which we
  9777. // can then upload.
  9778. ptimage = tex->make_ram_mipmap_image(n);
  9779. } else {
  9780. // No clear color and no more images.
  9781. break;
  9782. }
  9783. }
  9784. image_ptr = ptimage;
  9785. }
  9786. PTA_uchar bgr_image;
  9787. size_t view_size = tex->get_ram_mipmap_view_size(n);
  9788. if (image_ptr != (const unsigned char *)NULL) {
  9789. const unsigned char *orig_image_ptr = image_ptr;
  9790. image_ptr += view_size * gtc->get_view();
  9791. if (one_page_only) {
  9792. view_size = tex->get_ram_mipmap_page_size(n);
  9793. image_ptr += view_size * z;
  9794. }
  9795. nassertr(image_ptr >= orig_image_ptr && image_ptr + view_size <= orig_image_ptr + tex->get_ram_mipmap_image_size(n), false);
  9796. if (!_supports_bgr && image_compression == Texture::CM_off) {
  9797. // If the GL doesn't claim to support BGR, we may have to reverse
  9798. // the component ordering of the image.
  9799. image_ptr = fix_component_ordering(bgr_image, image_ptr, view_size,
  9800. external_format, tex);
  9801. }
  9802. }
  9803. int width = tex->get_expected_mipmap_x_size(n);
  9804. int height = tex->get_expected_mipmap_y_size(n);
  9805. int depth = tex->get_expected_mipmap_z_size(n);
  9806. #ifdef DO_PSTATS
  9807. _data_transferred_pcollector.add_level(view_size);
  9808. #endif
  9809. switch (texture_target) {
  9810. #ifndef OPENGLES_1
  9811. case GL_TEXTURE_3D:
  9812. if (_supports_3d_texture) {
  9813. if (image_compression == Texture::CM_off) {
  9814. _glTexSubImage3D(page_target, n - mipmap_bias, 0, 0, 0, width, height, depth,
  9815. external_format, component_type, image_ptr);
  9816. } else {
  9817. _glCompressedTexSubImage3D(page_target, n - mipmap_bias, 0, 0, 0, width, height, depth,
  9818. external_format, view_size, image_ptr);
  9819. }
  9820. } else {
  9821. report_my_gl_errors();
  9822. return false;
  9823. }
  9824. break;
  9825. #endif // OPENGLES_1
  9826. #ifndef OPENGLES
  9827. case GL_TEXTURE_1D:
  9828. if (image_compression == Texture::CM_off) {
  9829. glTexSubImage1D(page_target, n - mipmap_bias, 0, width,
  9830. external_format, component_type, image_ptr);
  9831. } else {
  9832. _glCompressedTexSubImage1D(page_target, n - mipmap_bias, 0, width,
  9833. external_format, view_size, image_ptr);
  9834. }
  9835. break;
  9836. #endif // OPENGLES
  9837. #ifndef OPENGLES
  9838. case GL_TEXTURE_2D_ARRAY_EXT:
  9839. if (_supports_2d_texture_array) {
  9840. if (image_compression == Texture::CM_off) {
  9841. _glTexSubImage3D(page_target, n - mipmap_bias, 0, 0, 0, width, height, depth,
  9842. external_format, component_type, image_ptr);
  9843. } else {
  9844. _glCompressedTexSubImage3D(page_target, n - mipmap_bias, 0, 0, 0, width, height, depth,
  9845. external_format, view_size, image_ptr);
  9846. }
  9847. } else {
  9848. report_my_gl_errors();
  9849. return false;
  9850. }
  9851. break;
  9852. #endif // OPENGLES
  9853. default:
  9854. if (image_compression == Texture::CM_off) {
  9855. if (n==0) {
  9856. // It's unfortunate that we can't adjust the width, too,
  9857. // but TexSubImage2D doesn't accept a row-stride parameter.
  9858. height = tex->get_y_size() - tex->get_pad_y_size();
  9859. }
  9860. glTexSubImage2D(page_target, n - mipmap_bias, 0, 0, width, height,
  9861. external_format, component_type, image_ptr);
  9862. } else {
  9863. _glCompressedTexSubImage2D(page_target, n - mipmap_bias, 0, 0, width, height,
  9864. external_format, view_size, image_ptr);
  9865. }
  9866. break;
  9867. }
  9868. }
  9869. // Did that fail? If it did, we'll immediately try again, this
  9870. // time loading the texture from scratch.
  9871. GLenum error_code = gl_get_error();
  9872. if (error_code != GL_NO_ERROR) {
  9873. if (GLCAT.is_debug()) {
  9874. GLCAT.debug()
  9875. << "GL texture subload failed for " << tex->get_name()
  9876. << " : " << get_error_string(error_code) << "\n";
  9877. }
  9878. needs_reload = true;
  9879. }
  9880. }
  9881. if (needs_reload) {
  9882. // Load the image up from scratch, creating a new GL Texture
  9883. // object.
  9884. if (GLCAT.is_debug()) {
  9885. GLCAT.debug()
  9886. << "loading new texture object for " << tex->get_name() << ", " << width
  9887. << " x " << height << " x " << depth << ", z = " << z << ", mipmaps "
  9888. << num_ram_mipmap_levels << ", uses_mipmaps = " << uses_mipmaps << "\n";
  9889. }
  9890. // If there is immutable storage, this is impossible to do, and we should
  9891. // not have gotten here at all.
  9892. nassertr(!gtc->_immutable, false);
  9893. if (num_ram_mipmap_levels == 0) {
  9894. if (GLCAT.is_debug()) {
  9895. GLCAT.debug()
  9896. << " (initializing NULL image)\n";
  9897. }
  9898. if ((external_format == GL_DEPTH_STENCIL) && get_supports_depth_stencil()) {
  9899. #ifdef OPENGLES
  9900. component_type = GL_UNSIGNED_INT_24_8_OES;
  9901. #else
  9902. component_type = GL_UNSIGNED_INT_24_8_EXT;
  9903. #endif
  9904. }
  9905. }
  9906. for (int n = mipmap_bias; n < num_levels; ++n) {
  9907. const unsigned char *image_ptr = (unsigned char*)tex->get_ram_mipmap_pointer(n);
  9908. CPTA_uchar ptimage;
  9909. if (image_ptr == (const unsigned char *)NULL) {
  9910. ptimage = tex->get_ram_mipmap_image(n);
  9911. if (ptimage.is_null()) {
  9912. if (n < num_ram_mipmap_levels) {
  9913. // We were told we'd have this many RAM mipmap images, but
  9914. // we don't. Raise a warning.
  9915. GLCAT.warning()
  9916. << "No mipmap level " << n << " defined for " << tex->get_name()
  9917. << "\n";
  9918. #ifndef OPENGLES
  9919. if (is_at_least_gl_version(1, 2)) {
  9920. // Tell the GL we have no more mipmaps for it to use.
  9921. glTexParameteri(texture_target, GL_TEXTURE_MAX_LEVEL, n - mipmap_bias);
  9922. }
  9923. #endif
  9924. break;
  9925. }
  9926. if (tex->has_clear_color()) {
  9927. // Ask the Texture class to create the mipmap level in RAM.
  9928. // It'll fill it in with the correct clear color, which we
  9929. // can then upload.
  9930. ptimage = tex->make_ram_mipmap_image(n);
  9931. }
  9932. }
  9933. image_ptr = ptimage;
  9934. }
  9935. PTA_uchar bgr_image;
  9936. size_t view_size = tex->get_ram_mipmap_view_size(n);
  9937. if (image_ptr != (const unsigned char *)NULL) {
  9938. const unsigned char *orig_image_ptr = image_ptr;
  9939. image_ptr += view_size * gtc->get_view();
  9940. if (one_page_only) {
  9941. view_size = tex->get_ram_mipmap_page_size(n);
  9942. image_ptr += view_size * z;
  9943. }
  9944. nassertr(image_ptr >= orig_image_ptr && image_ptr + view_size <= orig_image_ptr + tex->get_ram_mipmap_image_size(n), false);
  9945. if (!_supports_bgr && image_compression == Texture::CM_off) {
  9946. // If the GL doesn't claim to support BGR, we may have to reverse
  9947. // the component ordering of the image.
  9948. image_ptr = fix_component_ordering(bgr_image, image_ptr, view_size,
  9949. external_format, tex);
  9950. }
  9951. }
  9952. int width = tex->get_expected_mipmap_x_size(n);
  9953. int height = tex->get_expected_mipmap_y_size(n);
  9954. int depth = tex->get_expected_mipmap_z_size(n);
  9955. #ifdef DO_PSTATS
  9956. _data_transferred_pcollector.add_level(view_size);
  9957. #endif
  9958. switch (texture_target) {
  9959. #ifndef OPENGLES // 1-d textures not supported by OpenGL ES. Fall through.
  9960. case GL_TEXTURE_1D:
  9961. if (image_compression == Texture::CM_off) {
  9962. glTexImage1D(page_target, n - mipmap_bias, internal_format,
  9963. width, 0,
  9964. external_format, component_type, image_ptr);
  9965. } else {
  9966. _glCompressedTexImage1D(page_target, n - mipmap_bias, external_format, width,
  9967. 0, view_size, image_ptr);
  9968. }
  9969. break;
  9970. #endif // OPENGLES // OpenGL ES will fall through.
  9971. #ifdef OPENGLES_2
  9972. case GL_TEXTURE_3D_OES:
  9973. #endif
  9974. #ifndef OPENGLES
  9975. case GL_TEXTURE_3D:
  9976. #endif
  9977. #ifndef OPENGLES_1
  9978. if (_supports_3d_texture) {
  9979. if (image_compression == Texture::CM_off) {
  9980. _glTexImage3D(page_target, n - mipmap_bias, internal_format,
  9981. width, height, depth, 0,
  9982. external_format, component_type, image_ptr);
  9983. } else {
  9984. _glCompressedTexImage3D(page_target, n - mipmap_bias, external_format, width,
  9985. height, depth,
  9986. 0, view_size, image_ptr);
  9987. }
  9988. } else {
  9989. report_my_gl_errors();
  9990. return false;
  9991. }
  9992. break;
  9993. #endif
  9994. #ifndef OPENGLES
  9995. case GL_TEXTURE_2D_ARRAY_EXT:
  9996. if (_supports_2d_texture_array) {
  9997. if (image_compression == Texture::CM_off) {
  9998. _glTexImage3D(page_target, n - mipmap_bias, internal_format,
  9999. width, height, depth, 0,
  10000. external_format, component_type, image_ptr);
  10001. } else {
  10002. _glCompressedTexImage3D(page_target, n - mipmap_bias, external_format, width,
  10003. height, depth,
  10004. 0, view_size, image_ptr);
  10005. }
  10006. } else {
  10007. report_my_gl_errors();
  10008. return false;
  10009. }
  10010. break;
  10011. #endif
  10012. default:
  10013. if (image_compression == Texture::CM_off) {
  10014. glTexImage2D(page_target, n - mipmap_bias, internal_format,
  10015. width, height, 0,
  10016. external_format, component_type, image_ptr);
  10017. } else {
  10018. _glCompressedTexImage2D(page_target, n - mipmap_bias, external_format,
  10019. width, height, 0, view_size, image_ptr);
  10020. }
  10021. }
  10022. }
  10023. // Report the error message explicitly if the GL texture creation
  10024. // failed.
  10025. GLenum error_code = gl_get_error();
  10026. if (error_code != GL_NO_ERROR) {
  10027. GLCAT.error()
  10028. << "GL texture creation failed for " << tex->get_name()
  10029. << " : " << get_error_string(error_code) << "\n";
  10030. gtc->_has_storage = false;
  10031. return false;
  10032. }
  10033. }
  10034. report_my_gl_errors();
  10035. return true;
  10036. }
  10037. ////////////////////////////////////////////////////////////////////
  10038. // Function: GLGraphicsStateGuardian::upload_simple_texture
  10039. // Access: Protected
  10040. // Description: This is used as a standin for upload_texture
  10041. // when the texture in question is unavailable (e.g. it
  10042. // hasn't yet been loaded from disk). Until the texture
  10043. // image itself becomes available, we will render the
  10044. // texture's "simple" image--a sharply reduced version
  10045. // of the same texture.
  10046. ////////////////////////////////////////////////////////////////////
  10047. bool CLP(GraphicsStateGuardian)::
  10048. upload_simple_texture(CLP(TextureContext) *gtc) {
  10049. report_my_gl_errors();
  10050. PStatGPUTimer timer(this, _load_texture_pcollector);
  10051. Texture *tex = gtc->get_texture();
  10052. nassertr(tex != (Texture *)NULL, false);
  10053. int internal_format = GL_RGBA;
  10054. #ifdef OPENGLES_2
  10055. int external_format = GL_RGBA;
  10056. #else
  10057. int external_format = GL_BGRA;
  10058. #endif
  10059. const unsigned char *image_ptr = tex->get_simple_ram_image();
  10060. if (image_ptr == (const unsigned char *)NULL) {
  10061. return false;
  10062. }
  10063. size_t image_size = tex->get_simple_ram_image_size();
  10064. PTA_uchar bgr_image;
  10065. if (!_supports_bgr) {
  10066. // If the GL doesn't claim to support BGR, we may have to reverse
  10067. // the component ordering of the image.
  10068. external_format = GL_RGBA;
  10069. image_ptr = fix_component_ordering(bgr_image, image_ptr, image_size,
  10070. external_format, tex);
  10071. }
  10072. int width = tex->get_simple_x_size();
  10073. int height = tex->get_simple_y_size();
  10074. int component_type = GL_UNSIGNED_BYTE;
  10075. if (GLCAT.is_debug()) {
  10076. GLCAT.debug()
  10077. << "loading simple image for " << tex->get_name() << "\n";
  10078. }
  10079. #ifndef OPENGLES
  10080. // Turn off mipmaps for the simple texture.
  10081. if (tex->uses_mipmaps()) {
  10082. if (is_at_least_gl_version(1, 2)) {
  10083. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
  10084. }
  10085. }
  10086. #endif
  10087. #ifdef DO_PSTATS
  10088. _data_transferred_pcollector.add_level(image_size);
  10089. #endif
  10090. glTexImage2D(GL_TEXTURE_2D, 0, internal_format,
  10091. width, height, 0,
  10092. external_format, component_type, image_ptr);
  10093. gtc->mark_simple_loaded();
  10094. report_my_gl_errors();
  10095. return true;
  10096. }
  10097. ////////////////////////////////////////////////////////////////////
  10098. // Function: GLGraphicsStateGuardian::get_texture_memory_size
  10099. // Access: Protected
  10100. // Description: Asks OpenGL how much texture memory is consumed by
  10101. // the indicated texture (which is also the
  10102. // currently-selected texture).
  10103. ////////////////////////////////////////////////////////////////////
  10104. size_t CLP(GraphicsStateGuardian)::
  10105. get_texture_memory_size(Texture *tex) {
  10106. #ifdef OPENGLES // Texture querying not supported on OpenGL ES.
  10107. int width = tex->get_x_size();
  10108. int height = tex->get_y_size();
  10109. int depth = 1;
  10110. int scale = 1;
  10111. bool has_mipmaps = tex->uses_mipmaps();
  10112. size_t num_bytes = 2; // Temporary assumption?
  10113. #else
  10114. GLenum target = get_texture_target(tex->get_texture_type());
  10115. GLenum page_target = target;
  10116. GLint scale = 1;
  10117. if (target == GL_TEXTURE_CUBE_MAP) {
  10118. // We need a particular page to get the level parameter from.
  10119. page_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
  10120. scale = 6;
  10121. }
  10122. GLint minfilter;
  10123. glGetTexParameteriv(target, GL_TEXTURE_MIN_FILTER, &minfilter);
  10124. bool has_mipmaps = is_mipmap_filter(minfilter);
  10125. clear_my_gl_errors();
  10126. GLint internal_format;
  10127. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_INTERNAL_FORMAT, &internal_format);
  10128. if (is_compressed_format(internal_format)) {
  10129. // Try to get the compressed size.
  10130. GLint image_size;
  10131. glGetTexLevelParameteriv(page_target, 0,
  10132. GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &image_size);
  10133. GLenum error_code = gl_get_error();
  10134. if (error_code != GL_NO_ERROR) {
  10135. if (GLCAT.is_debug()) {
  10136. GLCAT.debug()
  10137. << "Couldn't get compressed size for " << tex->get_name()
  10138. << " : " << get_error_string(error_code) << "\n";
  10139. }
  10140. // Fall through to the noncompressed case.
  10141. } else {
  10142. return image_size * scale;
  10143. }
  10144. }
  10145. // OK, get the noncompressed size.
  10146. GLint red_size, green_size, blue_size, alpha_size,
  10147. luminance_size, intensity_size;
  10148. GLint depth_size = 0;
  10149. glGetTexLevelParameteriv(page_target, 0,
  10150. GL_TEXTURE_RED_SIZE, &red_size);
  10151. glGetTexLevelParameteriv(page_target, 0,
  10152. GL_TEXTURE_GREEN_SIZE, &green_size);
  10153. glGetTexLevelParameteriv(page_target, 0,
  10154. GL_TEXTURE_BLUE_SIZE, &blue_size);
  10155. glGetTexLevelParameteriv(page_target, 0,
  10156. GL_TEXTURE_ALPHA_SIZE, &alpha_size);
  10157. glGetTexLevelParameteriv(page_target, 0,
  10158. GL_TEXTURE_LUMINANCE_SIZE, &luminance_size);
  10159. glGetTexLevelParameteriv(page_target, 0,
  10160. GL_TEXTURE_INTENSITY_SIZE, &intensity_size);
  10161. if (_supports_depth_texture) {
  10162. glGetTexLevelParameteriv(page_target, 0,
  10163. GL_TEXTURE_DEPTH_SIZE, &depth_size);
  10164. }
  10165. GLint width = 1, height = 1, depth = 1;
  10166. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_WIDTH, &width);
  10167. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_HEIGHT, &height);
  10168. if (_supports_3d_texture || _supports_2d_texture_array) {
  10169. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_DEPTH, &depth);
  10170. }
  10171. report_my_gl_errors();
  10172. size_t num_bits = (red_size + green_size + blue_size + alpha_size + luminance_size + intensity_size + depth_size);
  10173. size_t num_bytes = (num_bits + 7) / 8;
  10174. #endif // OPENGLES
  10175. size_t result = num_bytes * width * height * depth * scale;
  10176. if (has_mipmaps) {
  10177. result = (result * 4) / 3;
  10178. }
  10179. return result;
  10180. }
  10181. ////////////////////////////////////////////////////////////////////
  10182. // Function: GLGraphicsStateGuardian::check_nonresident_texture
  10183. // Access: Private
  10184. // Description: Checks the list of resident texture objects to see if
  10185. // any have recently been evicted.
  10186. ////////////////////////////////////////////////////////////////////
  10187. void CLP(GraphicsStateGuardian)::
  10188. check_nonresident_texture(BufferContextChain &chain) {
  10189. #ifndef OPENGLES // Residency queries not supported by OpenGL ES.
  10190. size_t num_textures = chain.get_count();
  10191. if (num_textures == 0) {
  10192. return;
  10193. }
  10194. CLP(TextureContext) **gtc_list = (CLP(TextureContext) **)alloca(num_textures * sizeof(CLP(TextureContext) *));
  10195. GLuint *texture_list = (GLuint *)alloca(num_textures * sizeof(GLuint));
  10196. size_t ti = 0;
  10197. BufferContext *node = chain.get_first();
  10198. while (node != (BufferContext *)NULL) {
  10199. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), node);
  10200. gtc_list[ti] = gtc;
  10201. texture_list[ti] = gtc->_index;
  10202. node = node->get_next();
  10203. ++ti;
  10204. }
  10205. nassertv(ti == num_textures);
  10206. GLboolean *results = (GLboolean *)alloca(num_textures * sizeof(GLboolean));
  10207. bool all_resident = (glAreTexturesResident(num_textures, texture_list, results) != 0);
  10208. report_my_gl_errors();
  10209. if (!all_resident) {
  10210. // Some are now nonresident.
  10211. for (ti = 0; ti < num_textures; ++ti) {
  10212. if (!results[ti]) {
  10213. gtc_list[ti]->set_resident(false);
  10214. }
  10215. }
  10216. }
  10217. #endif // OPENGLES
  10218. }
  10219. ////////////////////////////////////////////////////////////////////
  10220. // Function: GLGraphicsStateGuardian::do_extract_texture_data
  10221. // Access: Protected
  10222. // Description: The internal implementation of
  10223. // extract_texture_data(), given an already-created
  10224. // TextureContext.
  10225. ////////////////////////////////////////////////////////////////////
  10226. bool CLP(GraphicsStateGuardian)::
  10227. do_extract_texture_data(CLP(TextureContext) *gtc) {
  10228. report_my_gl_errors();
  10229. GLenum target = gtc->_target;
  10230. if (target == GL_NONE) {
  10231. return false;
  10232. }
  10233. #ifndef OPENGLES
  10234. // Make sure any incoherent writes to the texture have been synced.
  10235. if (gtc->needs_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT)) {
  10236. issue_memory_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
  10237. }
  10238. #endif
  10239. glBindTexture(target, gtc->_index);
  10240. Texture *tex = gtc->get_texture();
  10241. GLint wrap_u, wrap_v, wrap_w;
  10242. GLint minfilter, magfilter;
  10243. GLfloat border_color[4];
  10244. glGetTexParameteriv(target, GL_TEXTURE_WRAP_S, &wrap_u);
  10245. glGetTexParameteriv(target, GL_TEXTURE_WRAP_T, &wrap_v);
  10246. wrap_w = GL_REPEAT;
  10247. if (_supports_3d_texture) {
  10248. #ifdef OPENGLES_2
  10249. glGetTexParameteriv(target, GL_TEXTURE_WRAP_R_OES, &wrap_w);
  10250. #endif
  10251. #ifndef OPENGLES
  10252. glGetTexParameteriv(target, GL_TEXTURE_WRAP_R, &wrap_w);
  10253. #endif
  10254. }
  10255. if (_supports_2d_texture_array) {
  10256. #ifndef OPENGLES
  10257. glGetTexParameteriv(target, GL_TEXTURE_WRAP_R, &wrap_w);
  10258. #endif
  10259. }
  10260. glGetTexParameteriv(target, GL_TEXTURE_MIN_FILTER, &minfilter);
  10261. glGetTexParameteriv(target, GL_TEXTURE_MAG_FILTER, &magfilter);
  10262. #ifndef OPENGLES
  10263. glGetTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, border_color);
  10264. #endif
  10265. GLenum page_target = target;
  10266. if (target == GL_TEXTURE_CUBE_MAP) {
  10267. // We need a particular page to get the level parameter from.
  10268. page_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
  10269. }
  10270. GLint width = gtc->_width, height = gtc->_height, depth = gtc->_depth;
  10271. #ifndef OPENGLES
  10272. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_WIDTH, &width);
  10273. if (target != GL_TEXTURE_1D) {
  10274. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_HEIGHT, &height);
  10275. }
  10276. if (_supports_3d_texture && target == GL_TEXTURE_3D) {
  10277. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_DEPTH, &depth);
  10278. }
  10279. #ifndef OPENGLES
  10280. else if (_supports_2d_texture_array && target == GL_TEXTURE_2D_ARRAY_EXT) {
  10281. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_DEPTH, &depth);
  10282. }
  10283. #endif
  10284. else if (target == GL_TEXTURE_CUBE_MAP) {
  10285. depth = 6;
  10286. }
  10287. #endif
  10288. clear_my_gl_errors();
  10289. if (width <= 0 || height <= 0 || depth <= 0) {
  10290. GLCAT.error()
  10291. << "No texture data for " << tex->get_name() << "\n";
  10292. return false;
  10293. }
  10294. GLint internal_format = GL_RGBA;
  10295. #ifndef OPENGLES
  10296. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_INTERNAL_FORMAT, &internal_format);
  10297. #endif // OPENGLES
  10298. // Make sure we were able to query those parameters properly.
  10299. GLenum error_code = gl_get_error();
  10300. if (error_code != GL_NO_ERROR) {
  10301. GLCAT.error()
  10302. << "Unable to query texture parameters for " << tex->get_name()
  10303. << " : " << get_error_string(error_code) << "\n";
  10304. return false;
  10305. }
  10306. Texture::ComponentType type = Texture::T_unsigned_byte;
  10307. Texture::Format format = Texture::F_rgb;
  10308. Texture::CompressionMode compression = Texture::CM_off;
  10309. switch (internal_format) {
  10310. #ifndef OPENGLES
  10311. case GL_COLOR_INDEX:
  10312. format = Texture::F_color_index;
  10313. break;
  10314. #endif
  10315. #if GL_DEPTH_COMPONENT != GL_DEPTH_COMPONENT24
  10316. case GL_DEPTH_COMPONENT:
  10317. #endif
  10318. case GL_DEPTH_COMPONENT16:
  10319. case GL_DEPTH_COMPONENT24:
  10320. case GL_DEPTH_COMPONENT32:
  10321. type = Texture::T_unsigned_short;
  10322. format = Texture::F_depth_component;
  10323. break;
  10324. #ifndef OPENGLES
  10325. case GL_DEPTH_COMPONENT32F:
  10326. type = Texture::T_float;
  10327. format = Texture::F_depth_component;
  10328. break;
  10329. #endif
  10330. case GL_DEPTH_STENCIL:
  10331. case GL_DEPTH24_STENCIL8:
  10332. type = Texture::T_unsigned_int_24_8;
  10333. format = Texture::F_depth_stencil;
  10334. break;
  10335. #ifndef OPENGLES
  10336. case GL_DEPTH32F_STENCIL8:
  10337. type = Texture::T_float;
  10338. format = Texture::F_depth_stencil;
  10339. break;
  10340. #endif
  10341. case GL_RGBA:
  10342. case 4:
  10343. format = Texture::F_rgba;
  10344. break;
  10345. case GL_RGBA4:
  10346. format = Texture::F_rgba4;
  10347. break;
  10348. #ifdef OPENGLES
  10349. case GL_RGBA8_OES:
  10350. format = Texture::F_rgba8;
  10351. break;
  10352. #else
  10353. case GL_RGBA8:
  10354. format = Texture::F_rgba8;
  10355. break;
  10356. #endif
  10357. #ifndef OPENGLES
  10358. case GL_RGBA12:
  10359. type = Texture::T_unsigned_short;
  10360. format = Texture::F_rgba12;
  10361. break;
  10362. #endif
  10363. case GL_RGB:
  10364. case 3:
  10365. format = Texture::F_rgb;
  10366. break;
  10367. #ifndef OPENGLES
  10368. case GL_RGB5:
  10369. format = Texture::F_rgb5;
  10370. break;
  10371. #endif
  10372. case GL_RGB5_A1:
  10373. format = Texture::F_rgba5;
  10374. break;
  10375. #ifndef OPENGLES
  10376. case GL_RGB8:
  10377. format = Texture::F_rgb8;
  10378. break;
  10379. case GL_RGB12:
  10380. format = Texture::F_rgb12;
  10381. break;
  10382. case GL_RGBA16:
  10383. format = Texture::F_rgba16;
  10384. break;
  10385. case GL_R3_G3_B2:
  10386. format = Texture::F_rgb332;
  10387. break;
  10388. case GL_R8I:
  10389. format = Texture::F_r8i;
  10390. break;
  10391. case GL_RG8I:
  10392. format = Texture::F_rg8i;
  10393. break;
  10394. case GL_RGB8I:
  10395. format = Texture::F_rgb8i;
  10396. break;
  10397. case GL_RGBA8I:
  10398. format = Texture::F_rgba8i;
  10399. break;
  10400. case GL_R8UI:
  10401. type = Texture::T_unsigned_byte;
  10402. format = Texture::F_r8i;
  10403. break;
  10404. case GL_RG8UI:
  10405. type = Texture::T_unsigned_byte;
  10406. format = Texture::F_rg8i;
  10407. break;
  10408. case GL_RGB8UI:
  10409. type = Texture::T_unsigned_byte;
  10410. format = Texture::F_rgb8i;
  10411. break;
  10412. case GL_RGBA8UI:
  10413. type = Texture::T_unsigned_byte;
  10414. format = Texture::F_rgba8i;
  10415. break;
  10416. #endif
  10417. #ifndef OPENGLES_1
  10418. case GL_RGBA16F:
  10419. type = Texture::T_float;
  10420. format = Texture::F_rgba16;
  10421. break;
  10422. case GL_RGB16F:
  10423. type = Texture::T_float;
  10424. format = Texture::F_rgb16;
  10425. break;
  10426. case GL_RG16F:
  10427. type = Texture::T_float;
  10428. format = Texture::F_rg16;
  10429. break;
  10430. case GL_R16F:
  10431. type = Texture::T_float;
  10432. format = Texture::F_r16;
  10433. break;
  10434. case GL_RGBA32F:
  10435. type = Texture::T_float;
  10436. format = Texture::F_rgba32;
  10437. break;
  10438. case GL_RGB32F:
  10439. type = Texture::T_float;
  10440. format = Texture::F_rgb32;
  10441. break;
  10442. case GL_RG32F:
  10443. type = Texture::T_float;
  10444. format = Texture::F_rg32;
  10445. break;
  10446. case GL_R32F:
  10447. type = Texture::T_float;
  10448. format = Texture::F_r32;
  10449. break;
  10450. #endif
  10451. #ifndef OPENGLES
  10452. case GL_RGB16:
  10453. type = Texture::T_unsigned_short;
  10454. format = Texture::F_rgb16;
  10455. break;
  10456. case GL_RG16:
  10457. type = Texture::T_unsigned_short;
  10458. format = Texture::F_rg16;
  10459. break;
  10460. case GL_R16:
  10461. type = Texture::T_unsigned_short;
  10462. format = Texture::F_r16;
  10463. break;
  10464. #endif
  10465. #ifdef OPENGLES_2
  10466. case GL_RED_EXT:
  10467. case GL_R8_EXT:
  10468. format = Texture::F_red;
  10469. break;
  10470. #endif
  10471. #ifndef OPENGLES
  10472. case GL_R32I:
  10473. type = Texture::T_int;
  10474. format = Texture::F_r32i;
  10475. break;
  10476. #endif
  10477. #ifndef OPENGLES
  10478. case GL_RED:
  10479. format = Texture::F_red;
  10480. break;
  10481. case GL_GREEN:
  10482. format = Texture::F_green;
  10483. break;
  10484. case GL_BLUE:
  10485. format = Texture::F_blue;
  10486. break;
  10487. #endif // OPENGLES
  10488. case GL_ALPHA:
  10489. format = Texture::F_alpha;
  10490. break;
  10491. case GL_LUMINANCE:
  10492. #ifndef OPENGLES
  10493. case GL_LUMINANCE16:
  10494. case GL_LUMINANCE16F_ARB:
  10495. #endif
  10496. case 1:
  10497. format = Texture::F_luminance;
  10498. break;
  10499. case GL_LUMINANCE_ALPHA:
  10500. #ifndef OPENGLES
  10501. case GL_LUMINANCE_ALPHA16F_ARB:
  10502. #endif
  10503. case 2:
  10504. format = Texture::F_luminance_alpha;
  10505. break;
  10506. #ifndef OPENGLES_1
  10507. case GL_SRGB:
  10508. #ifndef OPENGLES
  10509. case GL_SRGB8:
  10510. #endif
  10511. format = Texture::F_srgb;
  10512. break;
  10513. case GL_SRGB_ALPHA:
  10514. case GL_SRGB8_ALPHA8:
  10515. format = Texture::F_srgb_alpha;
  10516. break;
  10517. #endif // OPENGLES_1
  10518. #ifndef OPENGLES
  10519. case GL_SLUMINANCE:
  10520. case GL_SLUMINANCE8:
  10521. format = Texture::F_sluminance;
  10522. break;
  10523. case GL_SLUMINANCE_ALPHA:
  10524. case GL_SLUMINANCE8_ALPHA8:
  10525. format = Texture::F_sluminance_alpha;
  10526. break;
  10527. #endif // OPENGLES
  10528. #ifndef OPENGLES
  10529. case GL_COMPRESSED_RGB:
  10530. format = Texture::F_rgb;
  10531. compression = Texture::CM_on;
  10532. break;
  10533. case GL_COMPRESSED_RGBA:
  10534. format = Texture::F_rgba;
  10535. compression = Texture::CM_on;
  10536. break;
  10537. case GL_COMPRESSED_ALPHA:
  10538. format = Texture::F_alpha;
  10539. compression = Texture::CM_on;
  10540. break;
  10541. case GL_COMPRESSED_LUMINANCE:
  10542. format = Texture::F_luminance;
  10543. compression = Texture::CM_on;
  10544. break;
  10545. case GL_COMPRESSED_LUMINANCE_ALPHA:
  10546. format = Texture::F_luminance_alpha;
  10547. compression = Texture::CM_on;
  10548. break;
  10549. case GL_COMPRESSED_SRGB:
  10550. format = Texture::F_srgb;
  10551. compression = Texture::CM_on;
  10552. break;
  10553. case GL_COMPRESSED_SRGB_ALPHA:
  10554. format = Texture::F_srgb_alpha;
  10555. compression = Texture::CM_on;
  10556. break;
  10557. case GL_COMPRESSED_SLUMINANCE:
  10558. format = Texture::F_sluminance;
  10559. compression = Texture::CM_on;
  10560. break;
  10561. case GL_COMPRESSED_SLUMINANCE_ALPHA:
  10562. format = Texture::F_sluminance_alpha;
  10563. compression = Texture::CM_on;
  10564. break;
  10565. #endif
  10566. case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  10567. format = Texture::F_rgb;
  10568. compression = Texture::CM_dxt1;
  10569. break;
  10570. case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  10571. format = Texture::F_rgbm;
  10572. compression = Texture::CM_dxt1;
  10573. break;
  10574. #ifndef OPENGLES
  10575. case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
  10576. format = Texture::F_srgb;
  10577. compression = Texture::CM_dxt1;
  10578. break;
  10579. case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
  10580. format = Texture::F_srgb_alpha;
  10581. compression = Texture::CM_dxt1;
  10582. break;
  10583. #endif
  10584. #ifdef OPENGLES
  10585. case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
  10586. format = Texture::F_rgb;
  10587. compression = Texture::CM_pvr1_2bpp;
  10588. break;
  10589. case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
  10590. format = Texture::F_rgba;
  10591. compression = Texture::CM_pvr1_2bpp;
  10592. break;
  10593. case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
  10594. format = Texture::F_rgb;
  10595. compression = Texture::CM_pvr1_4bpp;
  10596. break;
  10597. case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
  10598. format = Texture::F_rgba;
  10599. compression = Texture::CM_pvr1_4bpp;
  10600. break;
  10601. #else
  10602. case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
  10603. format = Texture::F_rgba;
  10604. compression = Texture::CM_dxt3;
  10605. break;
  10606. case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
  10607. format = Texture::F_rgba;
  10608. compression = Texture::CM_dxt5;
  10609. break;
  10610. case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
  10611. format = Texture::F_srgb_alpha;
  10612. compression = Texture::CM_dxt3;
  10613. break;
  10614. case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
  10615. format = Texture::F_srgb_alpha;
  10616. compression = Texture::CM_dxt5;
  10617. break;
  10618. case GL_COMPRESSED_RGB_FXT1_3DFX:
  10619. format = Texture::F_rgb;
  10620. compression = Texture::CM_fxt1;
  10621. break;
  10622. case GL_COMPRESSED_RGBA_FXT1_3DFX:
  10623. format = Texture::F_rgba;
  10624. compression = Texture::CM_fxt1;
  10625. break;
  10626. #endif
  10627. default:
  10628. GLCAT.warning()
  10629. << "Unhandled internal format for " << tex->get_name()
  10630. << " : " << hex << "0x" << internal_format << dec << "\n";
  10631. return false;
  10632. }
  10633. // We don't want to call setup_texture() again; that resets too
  10634. // much. Instead, we'll just set the individual components.
  10635. tex->set_x_size(width);
  10636. tex->set_y_size(height);
  10637. tex->set_z_size(depth);
  10638. tex->set_component_type(type);
  10639. tex->set_format(format);
  10640. tex->set_wrap_u(get_panda_wrap_mode(wrap_u));
  10641. tex->set_wrap_v(get_panda_wrap_mode(wrap_v));
  10642. tex->set_wrap_w(get_panda_wrap_mode(wrap_w));
  10643. tex->set_border_color(LColor(border_color[0], border_color[1],
  10644. border_color[2], border_color[3]));
  10645. tex->set_minfilter(get_panda_filter_type(minfilter));
  10646. // tex->set_magfilter(get_panda_filter_type(magfilter));
  10647. PTA_uchar image;
  10648. size_t page_size = 0;
  10649. if (!extract_texture_image(image, page_size, tex, target, page_target,
  10650. type, compression, 0)) {
  10651. return false;
  10652. }
  10653. tex->set_ram_image(image, compression, page_size);
  10654. if (gtc->_uses_mipmaps) {
  10655. // Also get the mipmap levels.
  10656. GLint num_expected_levels = tex->get_expected_num_mipmap_levels();
  10657. GLint highest_level = num_expected_levels;
  10658. #ifndef OPENGLES
  10659. if (is_at_least_gl_version(1, 2)) {
  10660. glGetTexParameteriv(target, GL_TEXTURE_MAX_LEVEL, &highest_level);
  10661. highest_level = min(highest_level, num_expected_levels);
  10662. }
  10663. #endif
  10664. for (int n = 1; n <= highest_level; ++n) {
  10665. if (!extract_texture_image(image, page_size, tex, target, page_target,
  10666. type, compression, n)) {
  10667. return false;
  10668. }
  10669. tex->set_ram_mipmap_image(n, image, page_size);
  10670. }
  10671. }
  10672. return true;
  10673. }
  10674. ////////////////////////////////////////////////////////////////////
  10675. // Function: GLGraphicsStateGuardian::extract_texture_image
  10676. // Access: Protected
  10677. // Description: Called from extract_texture_data(), this gets just
  10678. // the image array for a particular mipmap level (or for
  10679. // the base image).
  10680. ////////////////////////////////////////////////////////////////////
  10681. bool CLP(GraphicsStateGuardian)::
  10682. extract_texture_image(PTA_uchar &image, size_t &page_size,
  10683. Texture *tex, GLenum target, GLenum page_target,
  10684. Texture::ComponentType type,
  10685. Texture::CompressionMode compression, int n) {
  10686. #ifdef OPENGLES // Extracting texture data unsupported in OpenGL ES.
  10687. nassertr(false, false);
  10688. return false;
  10689. #else
  10690. if (target == GL_TEXTURE_CUBE_MAP) {
  10691. // A cube map, compressed or uncompressed. This we must extract
  10692. // one page at a time.
  10693. // If the cube map is compressed, we assume that all the
  10694. // compressed pages are exactly the same size. OpenGL doesn't
  10695. // make this assumption, but it happens to be true for all
  10696. // currently extant compression schemes, and it makes things
  10697. // simpler for us. (It also makes things much simpler for the
  10698. // graphics hardware, so it's likely to continue to be true for a
  10699. // while at least.)
  10700. GLenum external_format = get_external_image_format(tex);
  10701. GLenum pixel_type = get_component_type(type);
  10702. page_size = tex->get_expected_ram_mipmap_page_size(n);
  10703. if (compression != Texture::CM_off) {
  10704. GLint image_size;
  10705. glGetTexLevelParameteriv(page_target, n,
  10706. GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &image_size);
  10707. nassertr(image_size <= (int)page_size, false);
  10708. page_size = image_size;
  10709. }
  10710. image = PTA_uchar::empty_array(page_size * 6);
  10711. for (int z = 0; z < 6; ++z) {
  10712. page_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + z;
  10713. if (compression == Texture::CM_off) {
  10714. glGetTexImage(page_target, n, external_format, pixel_type,
  10715. image.p() + z * page_size);
  10716. } else {
  10717. _glGetCompressedTexImage(page_target, 0, image.p() + z * page_size);
  10718. }
  10719. }
  10720. } else if (compression == Texture::CM_off) {
  10721. // An uncompressed 1-d, 2-d, or 3-d texture.
  10722. image = PTA_uchar::empty_array(tex->get_expected_ram_mipmap_image_size(n));
  10723. GLenum external_format = get_external_image_format(tex);
  10724. GLenum pixel_type = get_component_type(type);
  10725. glGetTexImage(target, n, external_format, pixel_type, image.p());
  10726. } else {
  10727. // A compressed 1-d, 2-d, or 3-d texture.
  10728. GLint image_size;
  10729. glGetTexLevelParameteriv(target, n, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &image_size);
  10730. page_size = image_size / tex->get_z_size();
  10731. image = PTA_uchar::empty_array(image_size);
  10732. // Some drivers (ATI!) seem to try to overstuff more bytes in the
  10733. // array than they asked us to allocate (that is, more bytes than
  10734. // GL_TEXTURE_COMPRESSED_IMAGE_SIZE), requiring us to overallocate
  10735. // and then copy the result into our final buffer. Sheesh.
  10736. // We'll only do this for small textures (the ATI bug doesn't
  10737. // *seem* to affect large textures), to save on the overhead of
  10738. // the double-copy, and reduce risk from an overly-large alloca().
  10739. #ifndef NDEBUG
  10740. static const int max_trouble_buffer = 102400;
  10741. #else
  10742. static const int max_trouble_buffer = 1024;
  10743. #endif
  10744. if (image_size < max_trouble_buffer) {
  10745. static const int extra_space = 32;
  10746. unsigned char *buffer = (unsigned char *)alloca(image_size + extra_space);
  10747. #ifndef NDEBUG
  10748. // Tag the buffer with a specific byte so we can report on
  10749. // whether that driver bug is still active.
  10750. static unsigned char keep_token = 0x00;
  10751. unsigned char token = ++keep_token;
  10752. memset(buffer + image_size, token, extra_space);
  10753. #endif
  10754. _glGetCompressedTexImage(target, n, buffer);
  10755. memcpy(image.p(), buffer, image_size);
  10756. #ifndef NDEBUG
  10757. int count = extra_space;
  10758. while (count > 0 && buffer[image_size + count - 1] == token) {
  10759. --count;
  10760. }
  10761. if (count != 0) {
  10762. GLCAT.warning()
  10763. << "GL graphics driver overfilled " << count
  10764. << " bytes into a " << image_size
  10765. << "-byte buffer provided to glGetCompressedTexImage()\n";
  10766. }
  10767. // This had better not equal the amount of buffer space we set
  10768. // aside. If it does, we assume the driver might have
  10769. // overfilled even our provided extra buffer.
  10770. nassertr(count != extra_space, true)
  10771. #endif // NDEBUG
  10772. } else {
  10773. _glGetCompressedTexImage(target, n, image.p());
  10774. }
  10775. }
  10776. // Now see if we were successful.
  10777. GLenum error_code = gl_get_error();
  10778. if (error_code != GL_NO_ERROR) {
  10779. GLCAT.error()
  10780. << "Unable to extract texture for " << *tex
  10781. << ", mipmap level " << n
  10782. << " : " << get_error_string(error_code) << "\n";
  10783. nassertr(false, false);
  10784. return false;
  10785. }
  10786. return true;
  10787. #endif // OPENGLES
  10788. }
  10789. ////////////////////////////////////////////////////////////////////
  10790. // Function: GLGraphicsStateGuardian::do_point_size
  10791. // Access: Protected
  10792. // Description: Internally sets the point size parameters after any
  10793. // of the properties have changed that might affect
  10794. // this.
  10795. ////////////////////////////////////////////////////////////////////
  10796. void CLP(GraphicsStateGuardian)::
  10797. do_point_size() {
  10798. #ifndef OPENGLES_2
  10799. if (!_point_perspective) {
  10800. // Normal, constant-sized points. Here _point_size is a width in
  10801. // pixels.
  10802. static LVecBase3f constant(1.0f, 0.0f, 0.0f);
  10803. _glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, constant.get_data());
  10804. } else {
  10805. // Perspective-sized points. Here _point_size is a width in 3-d
  10806. // units. To arrange that, we need to figure out the appropriate
  10807. // scaling factor based on the current viewport and projection
  10808. // matrix.
  10809. LVector3 height(0.0f, _point_size, 1.0f);
  10810. height = height * _projection_mat->get_mat();
  10811. height = height * _internal_transform->get_scale()[1];
  10812. PN_stdfloat s = height[1] * _viewport_height / _point_size;
  10813. if (_current_lens->is_orthographic()) {
  10814. // If we have an orthographic lens in effect, we don't actually
  10815. // apply a perspective transform: we just scale the points once,
  10816. // regardless of the distance from the camera.
  10817. LVecBase3f constant(1.0f / (s * s), 0.0f, 0.0f);
  10818. _glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, constant.get_data());
  10819. } else {
  10820. // Otherwise, we give it a true perspective adjustment.
  10821. LVecBase3f square(0.0f, 0.0f, 1.0f / (s * s));
  10822. _glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, square.get_data());
  10823. }
  10824. }
  10825. report_my_gl_errors();
  10826. #endif
  10827. }
  10828. ////////////////////////////////////////////////////////////////////
  10829. // Function: GLGraphicsStateGuardian::get_supports_cg_profile
  10830. // Access: Public, Virtual
  10831. // Description: Returns true if this particular GSG supports the
  10832. // specified Cg Shader Profile.
  10833. ////////////////////////////////////////////////////////////////////
  10834. bool CLP(GraphicsStateGuardian)::
  10835. get_supports_cg_profile(const string &name) const {
  10836. #if !defined(HAVE_CG) || defined(OPENGLES)
  10837. return false;
  10838. #else
  10839. CGprofile profile = cgGetProfile(name.c_str());
  10840. if (profile == CG_PROFILE_UNKNOWN) {
  10841. GLCAT.error() << name << ", unknown Cg-profile\n";
  10842. return false;
  10843. }
  10844. return (cgGLIsProfileSupported(profile) != 0);
  10845. #endif
  10846. }
  10847. ////////////////////////////////////////////////////////////////////
  10848. // Function: GLGraphicsStateGuardian::bind_fbo
  10849. // Access: Protected
  10850. // Description: Binds a framebuffer object.
  10851. ////////////////////////////////////////////////////////////////////
  10852. void CLP(GraphicsStateGuardian)::
  10853. bind_fbo(GLuint fbo) {
  10854. if (_current_fbo == fbo) {
  10855. return;
  10856. }
  10857. PStatGPUTimer timer(this, _fbo_bind_pcollector);
  10858. nassertv(_glBindFramebuffer != 0);
  10859. #if defined(OPENGLES_2)
  10860. _glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  10861. #elif defined(OPENGLES_1)
  10862. _glBindFramebuffer(GL_FRAMEBUFFER_OES, fbo);
  10863. #else
  10864. _glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
  10865. #endif
  10866. _current_fbo = fbo;
  10867. }
  10868. ////////////////////////////////////////////////////////////////////
  10869. // GL stencil code section
  10870. ////////////////////////////////////////////////////////////////////
  10871. static int gl_stencil_operations_array[] = {
  10872. GL_KEEP,
  10873. GL_ZERO,
  10874. GL_REPLACE,
  10875. #ifdef OPENGLES_1
  10876. GL_INCR_WRAP_OES,
  10877. GL_DECR_WRAP_OES,
  10878. #else
  10879. GL_INCR_WRAP,
  10880. GL_DECR_WRAP,
  10881. #endif
  10882. GL_INVERT,
  10883. GL_INCR,
  10884. GL_DECR,
  10885. };
  10886. ////////////////////////////////////////////////////////////////////
  10887. // Function: GLGraphicsStateGuardian::do_issue_stencil
  10888. // Access: Protected
  10889. // Description: Set stencil render states.
  10890. ////////////////////////////////////////////////////////////////////
  10891. void CLP(GraphicsStateGuardian)::
  10892. do_issue_stencil() {
  10893. if (!_supports_stencil) {
  10894. return;
  10895. }
  10896. const StencilAttrib *stencil;
  10897. if (_target_rs->get_attrib(stencil)) {
  10898. // DEBUG
  10899. if (false) {
  10900. GLCAT.debug() << "STENCIL STATE CHANGE\n";
  10901. GLCAT.debug() << "\n"
  10902. << "SRS_front_comparison_function " << (int)stencil->get_render_state(StencilAttrib::SRS_front_comparison_function) << "\n"
  10903. << "SRS_front_stencil_fail_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_front_stencil_fail_operation) << "\n"
  10904. << "SRS_front_stencil_pass_z_fail_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_fail_operation) << "\n"
  10905. << "SRS_front_stencil_pass_z_pass_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_pass_operation) << "\n"
  10906. << "SRS_reference " << (int)stencil->get_render_state(StencilAttrib::SRS_reference) << "\n"
  10907. << "SRS_read_mask " << (int)stencil->get_render_state(StencilAttrib::SRS_read_mask) << "\n"
  10908. << "SRS_write_mask " << (int)stencil->get_render_state(StencilAttrib::SRS_write_mask) << "\n"
  10909. << "SRS_back_comparison_function " << (int)stencil->get_render_state(StencilAttrib::SRS_back_comparison_function) << "\n"
  10910. << "SRS_back_stencil_fail_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_back_stencil_fail_operation) << "\n"
  10911. << "SRS_back_stencil_pass_z_fail_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_fail_operation) << "\n"
  10912. << "SRS_back_stencil_pass_z_pass_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_pass_operation) << "\n";
  10913. }
  10914. #ifndef OPENGLES
  10915. if (_supports_two_sided_stencil) {
  10916. //TODO: add support for OpenGL 2.0-style glStencilFuncSeparate.
  10917. unsigned int back_compare;
  10918. back_compare = stencil->get_render_state(StencilAttrib::SRS_back_comparison_function);
  10919. if (back_compare != RenderAttrib::M_none) {
  10920. glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
  10921. _glActiveStencilFaceEXT(GL_BACK);
  10922. glStencilFunc(
  10923. PANDA_TO_GL_COMPAREFUNC(back_compare),
  10924. stencil->get_render_state(StencilAttrib::SRS_reference),
  10925. stencil->get_render_state(StencilAttrib::SRS_read_mask));
  10926. glStencilOp(
  10927. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_back_stencil_fail_operation)],
  10928. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_fail_operation)],
  10929. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_pass_operation)]
  10930. );
  10931. glStencilMask(stencil->get_render_state(StencilAttrib::SRS_write_mask));
  10932. } else {
  10933. glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
  10934. }
  10935. _glActiveStencilFaceEXT(GL_FRONT);
  10936. }
  10937. #endif // OPENGLES
  10938. unsigned int front_compare;
  10939. front_compare = stencil->get_render_state(StencilAttrib::SRS_front_comparison_function);
  10940. if (front_compare != RenderAttrib::M_none) {
  10941. glEnable(GL_STENCIL_TEST);
  10942. glStencilFunc(
  10943. PANDA_TO_GL_COMPAREFUNC(front_compare),
  10944. stencil->get_render_state(StencilAttrib::SRS_reference),
  10945. stencil->get_render_state(StencilAttrib::SRS_read_mask));
  10946. glStencilOp(
  10947. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_front_stencil_fail_operation)],
  10948. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_fail_operation)],
  10949. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_pass_operation)]
  10950. );
  10951. glStencilMask(stencil->get_render_state(StencilAttrib::SRS_write_mask));
  10952. } else {
  10953. glDisable(GL_STENCIL_TEST);
  10954. }
  10955. if (stencil->get_render_state(StencilAttrib::SRS_clear)) {
  10956. // clear stencil buffer
  10957. glClearStencil(stencil->get_render_state(StencilAttrib::SRS_clear_value));
  10958. glClear(GL_STENCIL_BUFFER_BIT);
  10959. }
  10960. } else {
  10961. glDisable(GL_STENCIL_TEST);
  10962. #ifndef OPENGLES
  10963. if (_supports_two_sided_stencil) {
  10964. glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
  10965. }
  10966. #endif // OPENGLES
  10967. }
  10968. }
  10969. ////////////////////////////////////////////////////////////////////
  10970. // Function: GLGraphicsStateGuardian::do_issue_scissor
  10971. // Access: Protected
  10972. // Description:
  10973. ////////////////////////////////////////////////////////////////////
  10974. void CLP(GraphicsStateGuardian)::
  10975. do_issue_scissor() {
  10976. const ScissorAttrib *target_scissor;
  10977. _target_rs->get_attrib_def(target_scissor);
  10978. if (!target_scissor->is_off()) {
  10979. // A non-off ScissorAttrib means to override the scissor setting
  10980. // that was specified by the DisplayRegion.
  10981. if (!_scissor_enabled) {
  10982. if (GLCAT.is_spam()) {
  10983. GLCAT.spam()
  10984. << "glEnable(GL_SCISSOR_TEST)\n";
  10985. }
  10986. glEnable(GL_SCISSOR_TEST);
  10987. _scissor_enabled = true;
  10988. }
  10989. const LVecBase4 &frame = target_scissor->get_frame();
  10990. int x = (int)(_viewport_x + _viewport_width * frame[0] + 0.5f);
  10991. int y = (int)(_viewport_y + _viewport_height * frame[2] + 0.5f);
  10992. int width = (int)(_viewport_width * (frame[1] - frame[0]) + 0.5f);
  10993. int height = (int)(_viewport_height * (frame[3] - frame[2]) + 0.5f);
  10994. if (GLCAT.is_spam()) {
  10995. GLCAT.spam()
  10996. << "glScissor(" << x << ", " << y << ", " << width << ", " << height << ")\n";
  10997. }
  10998. glScissor(x, y, width, height);
  10999. _scissor_attrib_active = true;
  11000. } else if (_scissor_attrib_active) {
  11001. _scissor_attrib_active = false;
  11002. if (_scissor_array.size() > 0) {
  11003. // Scissoring is enabled on the display region.
  11004. // Revert to the scissor state specified in the DisplayRegion.
  11005. #ifndef OPENGLES
  11006. if (_supports_viewport_arrays) {
  11007. _glScissorArrayv(0, _scissor_array.size(), _scissor_array[0].get_data());
  11008. } else
  11009. #endif // OPENGLES
  11010. {
  11011. const LVecBase4i sr = _scissor_array[0];
  11012. glScissor(sr[0], sr[1], sr[2], sr[3]);
  11013. }
  11014. } else if (_scissor_enabled) {
  11015. // The display region had no scissor enabled. Disable scissoring.
  11016. if (GLCAT.is_spam()) {
  11017. GLCAT.spam()
  11018. << "glDisable(GL_SCISSOR_TEST)\n";
  11019. }
  11020. glDisable(GL_SCISSOR_TEST);
  11021. _scissor_enabled = false;
  11022. }
  11023. }
  11024. }