glGraphicsStateGuardian_src.cxx 360 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269
  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 "colorWriteAttrib.h"
  52. #include "depthWriteAttrib.h"
  53. #include "shadeModelAttrib.h"
  54. #include "rescaleNormalAttrib.h"
  55. #include "clipPlaneAttrib.h"
  56. #include "alphaTestAttrib.h"
  57. #include "cullFaceAttrib.h"
  58. #include "fogAttrib.h"
  59. #include "depthOffsetAttrib.h"
  60. #include "materialAttrib.h"
  61. #include "stencilAttrib.h"
  62. #include "lightAttrib.h"
  63. #include "scissorAttrib.h"
  64. #include "clipPlaneAttrib.h"
  65. #include "graphicsEngine.h"
  66. #include "shaderGenerator.h"
  67. #if defined(HAVE_CG) && !defined(OPENGLES)
  68. #include "Cg/cgGL.h"
  69. #endif
  70. #include <algorithm>
  71. TypeHandle CLP(GraphicsStateGuardian)::_type_handle;
  72. PStatCollector CLP(GraphicsStateGuardian)::_load_display_list_pcollector("Draw:Transfer data:Display lists");
  73. PStatCollector CLP(GraphicsStateGuardian)::_primitive_batches_display_list_pcollector("Primitive batches:Display lists");
  74. PStatCollector CLP(GraphicsStateGuardian)::_vertices_display_list_pcollector("Vertices:Display lists");
  75. PStatCollector CLP(GraphicsStateGuardian)::_vertices_immediate_pcollector("Vertices:Immediate mode");
  76. #ifdef OPENGLES_2
  77. PT(Shader) CLP(GraphicsStateGuardian)::_default_shader = NULL;
  78. #endif
  79. // The following noop functions are assigned to the corresponding
  80. // glext function pointers in the class, in case the functions are not
  81. // defined by the GL, just so it will always be safe to call the
  82. // extension functions.
  83. static void APIENTRY
  84. null_glPointParameterfv(GLenum, const GLfloat *) {
  85. }
  86. static void APIENTRY
  87. null_glDrawRangeElements(GLenum mode, GLuint start, GLuint end,
  88. GLsizei count, GLenum type, const GLvoid *indices) {
  89. // If we don't support glDrawRangeElements(), just use the original
  90. // glDrawElements() instead.
  91. GLP(DrawElements)(mode, count, type, indices);
  92. }
  93. static void APIENTRY
  94. null_glActiveTexture(GLenum gl_texture_stage) {
  95. // If we don't support multitexture, we'd better not try to request
  96. // a texture beyond the first texture stage.
  97. nassertv(gl_texture_stage == GL_TEXTURE0);
  98. }
  99. static void APIENTRY
  100. null_glBlendEquation(GLenum) {
  101. }
  102. static void APIENTRY
  103. null_glBlendColor(GLclampf, GLclampf, GLclampf, GLclampf) {
  104. }
  105. #ifdef OPENGLES_2
  106. // We have a default shader that will be applied when there
  107. // isn't any shader applied (e.g. if it failed to compile).
  108. // We need this because OpenGL ES 2.x does not have
  109. // a fixed-function pipeline.
  110. // This default shader just outputs a red color, telling
  111. // the user that something went wrong.
  112. CPT(Shader::ShaderFile) default_shader_name = new Shader::ShaderFile("default-shader");
  113. CPT(Shader::ShaderFile) default_shader_body = new Shader::ShaderFile("\
  114. uniform mediump mat4 p3d_ModelViewProjectionMatrix;\
  115. attribute highp vec4 p3d_Vertex;\
  116. void main(void) {\
  117. gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;\
  118. }\n",
  119. "void main(void) {\
  120. gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\
  121. }\n", "", "", "");
  122. #endif
  123. ////////////////////////////////////////////////////////////////////
  124. // Function: uchar_bgr_to_rgb
  125. // Description: Recopies the given array of pixels, converting from
  126. // BGR to RGB arrangement.
  127. ////////////////////////////////////////////////////////////////////
  128. static void
  129. uchar_bgr_to_rgb(unsigned char *dest, const unsigned char *source,
  130. int num_pixels) {
  131. for (int i = 0; i < num_pixels; i++) {
  132. dest[0] = source[2];
  133. dest[1] = source[1];
  134. dest[2] = source[0];
  135. dest += 3;
  136. source += 3;
  137. }
  138. }
  139. ////////////////////////////////////////////////////////////////////
  140. // Function: uchar_bgra_to_rgba
  141. // Description: Recopies the given array of pixels, converting from
  142. // BGRA to RGBA arrangement.
  143. ////////////////////////////////////////////////////////////////////
  144. static void
  145. uchar_bgra_to_rgba(unsigned char *dest, const unsigned char *source,
  146. int num_pixels) {
  147. for (int i = 0; i < num_pixels; i++) {
  148. dest[0] = source[2];
  149. dest[1] = source[1];
  150. dest[2] = source[0];
  151. dest[3] = source[3];
  152. dest += 4;
  153. source += 4;
  154. }
  155. }
  156. ////////////////////////////////////////////////////////////////////
  157. // Function: ushort_bgr_to_rgb
  158. // Description: Recopies the given array of pixels, converting from
  159. // BGR to RGB arrangement.
  160. ////////////////////////////////////////////////////////////////////
  161. static void
  162. ushort_bgr_to_rgb(unsigned short *dest, const unsigned short *source,
  163. int num_pixels) {
  164. for (int i = 0; i < num_pixels; i++) {
  165. dest[0] = source[2];
  166. dest[1] = source[1];
  167. dest[2] = source[0];
  168. dest += 3;
  169. source += 3;
  170. }
  171. }
  172. ////////////////////////////////////////////////////////////////////
  173. // Function: ushort_bgra_to_rgba
  174. // Description: Recopies the given array of pixels, converting from
  175. // BGRA to RGBA arrangement.
  176. ////////////////////////////////////////////////////////////////////
  177. static void
  178. ushort_bgra_to_rgba(unsigned short *dest, const unsigned short *source,
  179. int num_pixels) {
  180. for (int i = 0; i < num_pixels; i++) {
  181. dest[0] = source[2];
  182. dest[1] = source[1];
  183. dest[2] = source[0];
  184. dest[3] = source[3];
  185. dest += 4;
  186. source += 4;
  187. }
  188. }
  189. ////////////////////////////////////////////////////////////////////
  190. // Function: fix_component_ordering
  191. // Description: Reverses the order of the components within the
  192. // image, to convert (for instance) GL_BGR to GL_RGB.
  193. // Returns the byte pointer representing the converted
  194. // image, or the original image if it is unchanged.
  195. //
  196. // new_image must be supplied; it is the PTA_uchar that
  197. // will be used to hold the converted image if required.
  198. // It will be modified only if the conversion is
  199. // necessary, in which case the data will be stored
  200. // there, and this pointer will be returned. If the
  201. // conversion is not necessary, this pointer will be
  202. // left unchanged.
  203. ////////////////////////////////////////////////////////////////////
  204. static const unsigned char *
  205. fix_component_ordering(PTA_uchar &new_image,
  206. const unsigned char *orig_image, size_t orig_image_size,
  207. GLenum external_format, Texture *tex) {
  208. const unsigned char *result = orig_image;
  209. switch (external_format) {
  210. case GL_RGB:
  211. switch (tex->get_component_type()) {
  212. case Texture::T_unsigned_byte:
  213. new_image = PTA_uchar::empty_array(orig_image_size);
  214. uchar_bgr_to_rgb(new_image, orig_image, orig_image_size / 3);
  215. result = new_image;
  216. break;
  217. case Texture::T_unsigned_short:
  218. new_image = PTA_uchar::empty_array(orig_image_size);
  219. ushort_bgr_to_rgb((unsigned short *)new_image.p(),
  220. (const unsigned short *)orig_image,
  221. orig_image_size / 6);
  222. result = new_image;
  223. break;
  224. default:
  225. break;
  226. }
  227. break;
  228. case GL_RGBA:
  229. switch (tex->get_component_type()) {
  230. case Texture::T_unsigned_byte:
  231. new_image = PTA_uchar::empty_array(orig_image_size);
  232. uchar_bgra_to_rgba(new_image, orig_image, orig_image_size / 4);
  233. result = new_image;
  234. break;
  235. case Texture::T_unsigned_short:
  236. new_image = PTA_uchar::empty_array(orig_image_size);
  237. ushort_bgra_to_rgba((unsigned short *)new_image.p(),
  238. (const unsigned short *)orig_image,
  239. orig_image_size / 8);
  240. result = new_image;
  241. break;
  242. default:
  243. break;
  244. }
  245. break;
  246. default:
  247. break;
  248. }
  249. return result;
  250. }
  251. //#--- Zhao Nov/2011
  252. string CLP(GraphicsStateGuardian)::get_driver_vendor() { return _gl_vendor; }
  253. string CLP(GraphicsStateGuardian)::get_driver_renderer() { return _gl_renderer; }
  254. string CLP(GraphicsStateGuardian)::get_driver_version() { return _gl_version; }
  255. int CLP(GraphicsStateGuardian)::get_driver_version_major() { return _gl_version_major; }
  256. int CLP(GraphicsStateGuardian)::get_driver_version_minor() { return _gl_version_minor; }
  257. int CLP(GraphicsStateGuardian)::get_driver_shader_version_major() { return _gl_shadlang_ver_major; }
  258. int CLP(GraphicsStateGuardian)::get_driver_shader_version_minor() { return _gl_shadlang_ver_minor; }
  259. ////////////////////////////////////////////////////////////////////
  260. // Function: GLGraphicsStateGuardian::Constructor
  261. // Access: Public
  262. // Description:
  263. ////////////////////////////////////////////////////////////////////
  264. CLP(GraphicsStateGuardian)::
  265. CLP(GraphicsStateGuardian)(GraphicsEngine *engine, GraphicsPipe *pipe) :
  266. GraphicsStateGuardian(CS_yup_right, engine, pipe)
  267. {
  268. _error_count = 0;
  269. // Hack. Turn on the flag that we turned off at a higher level,
  270. // since we know this works properly in OpenGL, and we want the
  271. // performance benefit it gives us.
  272. _prepared_objects->_support_released_buffer_cache = true;
  273. // Assume that we will get a hardware-accelerated context, unless
  274. // the window tells us otherwise.
  275. _is_hardware = true;
  276. // calling glGetError() forces a sync, this turns it off if you want to.
  277. _track_errors = !CLP(force_no_error);
  278. _allow_flush = !CLP(force_no_flush);
  279. #ifdef DO_PSTATS
  280. if (CLP(finish)) {
  281. GLCAT.warning()
  282. << "The config variable gl-finish is set True. This may have a substantial negative impact your render performance.\n";
  283. }
  284. #endif // DO_PSTATS
  285. }
  286. ////////////////////////////////////////////////////////////////////
  287. // Function: GLGraphicsStateGuardian::Destructor
  288. // Access: Public
  289. // Description:
  290. ////////////////////////////////////////////////////////////////////
  291. CLP(GraphicsStateGuardian)::
  292. ~CLP(GraphicsStateGuardian)() {
  293. if (GLCAT.is_debug()) {
  294. GLCAT.debug()
  295. << "GLGraphicsStateGuardian " << this << " destructing\n";
  296. }
  297. close_gsg();
  298. if (_stencil_render_states) {
  299. delete _stencil_render_states;
  300. _stencil_render_states = 0;
  301. }
  302. }
  303. ////////////////////////////////////////////////////////////////////
  304. // Function: GLGraphicsStateGuardian::reset
  305. // Access: Public, Virtual
  306. // Description: Resets all internal state as if the gsg were newly
  307. // created.
  308. ////////////////////////////////////////////////////////////////////
  309. void CLP(GraphicsStateGuardian)::
  310. reset() {
  311. free_pointers();
  312. GraphicsStateGuardian::reset();
  313. // Build _inv_state_mask as a mask of 1's where we don't care, and
  314. // 0's where we do care, about the state.
  315. //_inv_state_mask = RenderState::SlotMask::all_on();
  316. _inv_state_mask.clear_bit(ShaderAttrib::get_class_slot());
  317. _inv_state_mask.clear_bit(AlphaTestAttrib::get_class_slot());
  318. _inv_state_mask.clear_bit(AntialiasAttrib::get_class_slot());
  319. _inv_state_mask.clear_bit(ClipPlaneAttrib::get_class_slot());
  320. _inv_state_mask.clear_bit(ColorAttrib::get_class_slot());
  321. _inv_state_mask.clear_bit(ColorScaleAttrib::get_class_slot());
  322. _inv_state_mask.clear_bit(CullFaceAttrib::get_class_slot());
  323. _inv_state_mask.clear_bit(DepthOffsetAttrib::get_class_slot());
  324. _inv_state_mask.clear_bit(DepthTestAttrib::get_class_slot());
  325. _inv_state_mask.clear_bit(DepthWriteAttrib::get_class_slot());
  326. _inv_state_mask.clear_bit(RenderModeAttrib::get_class_slot());
  327. _inv_state_mask.clear_bit(RescaleNormalAttrib::get_class_slot());
  328. _inv_state_mask.clear_bit(ShadeModelAttrib::get_class_slot());
  329. _inv_state_mask.clear_bit(TransparencyAttrib::get_class_slot());
  330. _inv_state_mask.clear_bit(ColorWriteAttrib::get_class_slot());
  331. _inv_state_mask.clear_bit(ColorBlendAttrib::get_class_slot());
  332. _inv_state_mask.clear_bit(TextureAttrib::get_class_slot());
  333. _inv_state_mask.clear_bit(TexGenAttrib::get_class_slot());
  334. _inv_state_mask.clear_bit(TexMatrixAttrib::get_class_slot());
  335. _inv_state_mask.clear_bit(MaterialAttrib::get_class_slot());
  336. _inv_state_mask.clear_bit(LightAttrib::get_class_slot());
  337. _inv_state_mask.clear_bit(StencilAttrib::get_class_slot());
  338. _inv_state_mask.clear_bit(FogAttrib::get_class_slot());
  339. _inv_state_mask.clear_bit(ScissorAttrib::get_class_slot());
  340. // Output the vendor and version strings.
  341. query_gl_version();
  342. if (_gl_version_major == 0) {
  343. // Couldn't get GL. Fail.
  344. mark_new();
  345. return;
  346. }
  347. // Save the extensions tokens.
  348. save_extensions((const char *)GLP(GetString)(GL_EXTENSIONS));
  349. get_extra_extensions();
  350. report_extensions();
  351. _supported_geom_rendering =
  352. Geom::GR_indexed_point |
  353. Geom::GR_point | Geom::GR_point_uniform_size |
  354. Geom::GR_indexed_other |
  355. Geom::GR_triangle_strip | Geom::GR_triangle_fan |
  356. Geom::GR_flat_last_vertex;
  357. _supports_point_parameters = false;
  358. if (is_at_least_gl_version(1, 4)) {
  359. _supports_point_parameters = true;
  360. _glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)
  361. get_extension_func(GLPREFIX_QUOTED, "PointParameterfv");
  362. } else if (has_extension("GL_ARB_point_parameters")) {
  363. _supports_point_parameters = true;
  364. _glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)
  365. get_extension_func(GLPREFIX_QUOTED, "PointParameterfvARB");
  366. }
  367. if (_supports_point_parameters) {
  368. if (_glPointParameterfv == NULL) {
  369. GLCAT.warning()
  370. << "glPointParameterfv advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  371. _supports_point_parameters = false;
  372. }
  373. }
  374. if (_supports_point_parameters) {
  375. _supported_geom_rendering |= Geom::GR_point_perspective;
  376. } else {
  377. _glPointParameterfv = null_glPointParameterfv;
  378. }
  379. _supports_point_sprite = has_extension("GL_ARB_point_sprite") || has_extension("GL_OES_point_sprite");
  380. if (_supports_point_sprite) {
  381. // It appears that the point_sprite extension doesn't support
  382. // texture transforms on the generated texture coordinates. How
  383. // inconsistent. Because of this, we don't advertise
  384. // GR_point_sprite_tex_matrix.
  385. _supported_geom_rendering |= Geom::GR_point_sprite;
  386. }
  387. _supports_vertex_blend = has_extension("GL_ARB_vertex_blend");
  388. if (_supports_vertex_blend) {
  389. _glWeightPointer = (PFNGLWEIGHTPOINTERARBPROC)
  390. get_extension_func(GLPREFIX_QUOTED, "WeightPointerARB");
  391. _glVertexBlend = (PFNGLVERTEXBLENDARBPROC)
  392. get_extension_func(GLPREFIX_QUOTED, "VertexBlendARB");
  393. _glWeightfv = (PFNGLWEIGHTFVARBPROC)
  394. get_extension_func(GLPREFIX_QUOTED, "WeightfvARB");
  395. _glWeightdv = (PFNGLWEIGHTDVARBPROC)
  396. get_extension_func(GLPREFIX_QUOTED, "WeightdvARB");
  397. if (_glWeightPointer == NULL || _glVertexBlend == NULL ||
  398. GLfv(_glWeight) == NULL) {
  399. GLCAT.warning()
  400. << "Vertex blending advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  401. _supports_vertex_blend = false;
  402. }
  403. }
  404. #ifndef OPENGLES
  405. if (_supports_vertex_blend) {
  406. GLP(Enable)(GL_WEIGHT_SUM_UNITY_ARB);
  407. GLint max_vertex_units = 0;
  408. GLP(GetIntegerv)(GL_MAX_VERTEX_UNITS_ARB, &max_vertex_units);
  409. _max_vertex_transforms = max_vertex_units;
  410. if (GLCAT.is_debug()) {
  411. GLCAT.debug()
  412. << "max vertex transforms = " << _max_vertex_transforms << "\n";
  413. }
  414. }
  415. #endif
  416. _supports_matrix_palette = false;
  417. #ifndef OPENGLES
  418. if (has_extension("GL_ARB_matrix_palette")) {
  419. _supports_matrix_palette = true;
  420. _glCurrentPaletteMatrix = (PFNGLCURRENTPALETTEMATRIXARBPROC)
  421. get_extension_func(GLPREFIX_QUOTED, "CurrentPaletteMatrixARB");
  422. _glMatrixIndexPointer = (PFNGLMATRIXINDEXPOINTERARBPROC)
  423. get_extension_func(GLPREFIX_QUOTED, "MatrixIndexPointerARB");
  424. _glMatrixIndexuiv = (PFNGLMATRIXINDEXUIVARBPROC)
  425. get_extension_func(GLPREFIX_QUOTED, "MatrixIndexuivARB");
  426. if (_glCurrentPaletteMatrix == NULL ||
  427. _glMatrixIndexPointer == NULL ||
  428. _glMatrixIndexuiv == NULL) {
  429. GLCAT.warning()
  430. << "Matrix palette advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  431. _supports_matrix_palette = false;
  432. }
  433. }
  434. #else
  435. if (has_extension("GL_OES_matrix_palette")) {
  436. _supports_matrix_palette = true;
  437. _glCurrentPaletteMatrix = (PFNGLCURRENTPALETTEMATRIXOESPROC)
  438. get_extension_func(GLPREFIX_QUOTED, "CurrentPaletteMatrixOES");
  439. _glMatrixIndexPointer = (PFNGLMATRIXINDEXPOINTEROESPROC)
  440. get_extension_func(GLPREFIX_QUOTED, "MatrixIndexPointerOES");
  441. if (_glCurrentPaletteMatrix == NULL ||
  442. _glMatrixIndexPointer == NULL) {
  443. GLCAT.warning()
  444. << "Matrix palette advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  445. _supports_matrix_palette = false;
  446. }
  447. }
  448. #endif
  449. /*
  450. The matrix_palette support in this module is completely untested
  451. (because I don't happen to have a card handy whose driver supports
  452. this extension), so I have this ConfigVariable set to
  453. unconditionally set this flag off for now, to protect the unwary.
  454. When we have shown that the code works, we should remove this bit.
  455. In the meantime, you must put both "matrix-palette 1" and
  456. "gl-matrix-palette 1" in your Config.prc to exercise the new
  457. code. */
  458. if (!CLP(matrix_palette)) {
  459. if (_supports_matrix_palette) {
  460. if (GLCAT.is_debug()) {
  461. GLCAT.debug() << "Forcing off matrix palette support.\n";
  462. }
  463. }
  464. _supports_matrix_palette = false;
  465. }
  466. if (_supports_matrix_palette) {
  467. GLint max_palette_matrices = 0;
  468. #ifdef OPENGLES_1
  469. GLP(GetIntegerv)(GL_MAX_PALETTE_MATRICES_OES, &max_palette_matrices);
  470. #endif
  471. #ifndef OPENGLES
  472. GLP(GetIntegerv)(GL_MAX_PALETTE_MATRICES_ARB, &max_palette_matrices);
  473. #endif
  474. _max_vertex_transform_indices = max_palette_matrices;
  475. if (GLCAT.is_debug()) {
  476. GLCAT.debug()
  477. << "max vertex transform indices = " << _max_vertex_transform_indices << "\n";
  478. }
  479. }
  480. _supports_draw_range_elements = false;
  481. if (is_at_least_gl_version(1, 2)) {
  482. _supports_draw_range_elements = true;
  483. _glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)
  484. get_extension_func(GLPREFIX_QUOTED, "DrawRangeElements");
  485. } else if (has_extension("GL_EXT_draw_range_elements")) {
  486. _supports_draw_range_elements = true;
  487. _glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)
  488. get_extension_func(GLPREFIX_QUOTED, "DrawRangeElementsEXT");
  489. }
  490. if (_supports_draw_range_elements) {
  491. if (_glDrawRangeElements == NULL) {
  492. GLCAT.warning()
  493. << "glDrawRangeElements advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  494. _supports_draw_range_elements = false;
  495. }
  496. }
  497. if (!_supports_draw_range_elements) {
  498. _glDrawRangeElements = null_glDrawRangeElements;
  499. }
  500. #ifdef OPENGLES
  501. _supports_depth_texture = has_extension("GL_OES_depth_texture") ||
  502. has_extension("GL_OES_depth24") || has_extension("GL_OES_depth32");
  503. #else
  504. _supports_depth_texture =
  505. has_extension("GL_ARB_depth_texture") || is_at_least_gl_version(1, 4);
  506. #endif
  507. _supports_depth_stencil = false;
  508. if (_supports_depth_texture) {
  509. _supports_depth_stencil =
  510. has_extension("GL_EXT_packed_depth_stencil") || has_extension("GL_OES_packed_depth_stencil");
  511. }
  512. _supports_3d_texture = false;
  513. if (is_at_least_gl_version(1, 2)) {
  514. _supports_3d_texture = true;
  515. _glTexImage3D = (PFNGLTEXIMAGE3DPROC_P)
  516. get_extension_func(GLPREFIX_QUOTED, "TexImage3D");
  517. _glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)
  518. get_extension_func(GLPREFIX_QUOTED, "TexSubImage3D");
  519. } else if (has_extension("GL_EXT_texture3D")) {
  520. _supports_3d_texture = true;
  521. _glTexImage3D = (PFNGLTEXIMAGE3DPROC_P)
  522. get_extension_func(GLPREFIX_QUOTED, "TexImage3DEXT");
  523. _glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)
  524. get_extension_func(GLPREFIX_QUOTED, "TexSubImage3DEXT");
  525. } else if (has_extension("GL_OES_texture3D") || has_extension("GL_OES_texture_3D")) {
  526. _supports_3d_texture = true;
  527. _glTexImage3D = (PFNGLTEXIMAGE3DPROC_P)
  528. get_extension_func(GLPREFIX_QUOTED, "TexImage3DOES");
  529. _glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)
  530. get_extension_func(GLPREFIX_QUOTED, "TexSubImage3DOES");
  531. #ifdef OPENGLES_2
  532. _glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DOES)
  533. get_extension_func(GLPREFIX_QUOTED, "FramebufferTexture3DOES");
  534. #endif
  535. }
  536. if (_supports_3d_texture) {
  537. if (_glTexImage3D == NULL || _glTexSubImage3D == NULL) {
  538. GLCAT.warning()
  539. << "3-D textures advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  540. _supports_3d_texture = false;
  541. }
  542. }
  543. #ifndef OPENGLES
  544. _supports_2d_texture_array = has_extension("GL_EXT_texture_array");
  545. #endif
  546. #ifdef OPENGLES_2
  547. _supports_cube_map = true;
  548. #else
  549. _supports_cube_map =
  550. has_extension("GL_ARB_texture_cube_map") || is_at_least_gl_version(1, 3) ||
  551. has_extension("GL_OES_texture_cube_map");
  552. #endif
  553. _supports_compressed_texture = false;
  554. #ifdef OPENGLES
  555. _supports_compressed_texture = true;
  556. // Supported in the core. 1D textures are not supported by OpenGL ES.
  557. _glCompressedTexImage1D = NULL;
  558. _glCompressedTexImage2D = glCompressedTexImage2D;
  559. _glCompressedTexSubImage1D = NULL;
  560. _glCompressedTexSubImage2D = glCompressedTexSubImage2D;
  561. _glGetCompressedTexImage = NULL;
  562. _glCompressedTexImage3D = NULL;
  563. _glCompressedTexSubImage3D = NULL;
  564. #ifdef OPENGLES_2
  565. if (_supports_3d_texture) {
  566. _glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)
  567. get_extension_func(GLPREFIX_QUOTED, "CompressedTexImage3DOES");
  568. _glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)
  569. get_extension_func(GLPREFIX_QUOTED, "CompressedTexSubImageOES");
  570. }
  571. #endif
  572. #else
  573. if (is_at_least_gl_version(1, 3)) {
  574. _supports_compressed_texture = true;
  575. _glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)
  576. get_extension_func(GLPREFIX_QUOTED, "CompressedTexImage1D");
  577. _glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)
  578. get_extension_func(GLPREFIX_QUOTED, "CompressedTexImage2D");
  579. _glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)
  580. get_extension_func(GLPREFIX_QUOTED, "CompressedTexImage3D");
  581. _glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)
  582. get_extension_func(GLPREFIX_QUOTED, "CompressedTexSubImage1D");
  583. _glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)
  584. get_extension_func(GLPREFIX_QUOTED, "CompressedTexSubImage2D");
  585. _glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)
  586. get_extension_func(GLPREFIX_QUOTED, "CompressedTexSubImage3D");
  587. _glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)
  588. get_extension_func(GLPREFIX_QUOTED, "GetCompressedTexImage");
  589. } else if (has_extension("GL_ARB_texture_compression")) {
  590. _supports_compressed_texture = true;
  591. _glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)
  592. get_extension_func(GLPREFIX_QUOTED, "CompressedTexImage1DARB");
  593. _glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)
  594. get_extension_func(GLPREFIX_QUOTED, "CompressedTexImage2DARB");
  595. _glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)
  596. get_extension_func(GLPREFIX_QUOTED, "CompressedTexImage3DARB");
  597. _glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)
  598. get_extension_func(GLPREFIX_QUOTED, "CompressedTexSubImage1DARB");
  599. _glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)
  600. get_extension_func(GLPREFIX_QUOTED, "CompressedTexSubImage2DARB");
  601. _glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)
  602. get_extension_func(GLPREFIX_QUOTED, "CompressedTexSubImage3DARB");
  603. _glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)
  604. get_extension_func(GLPREFIX_QUOTED, "GetCompressedTexImageARB");
  605. }
  606. if (_supports_compressed_texture) {
  607. if (_glCompressedTexImage1D == NULL ||
  608. _glCompressedTexImage2D == NULL ||
  609. _glCompressedTexImage3D == NULL ||
  610. _glCompressedTexSubImage1D == NULL ||
  611. _glCompressedTexSubImage2D == NULL ||
  612. _glCompressedTexSubImage3D == NULL ||
  613. _glGetCompressedTexImage == NULL) {
  614. GLCAT.warning()
  615. << "Compressed textures advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  616. _supports_compressed_texture = false;
  617. }
  618. }
  619. #endif
  620. if (_supports_compressed_texture) {
  621. #ifndef OPENGLES
  622. _compressed_texture_formats.set_bit(Texture::CM_on);
  623. #endif
  624. GLint num_compressed_formats = 0;
  625. GLP(GetIntegerv)(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_compressed_formats);
  626. GLint *formats = (GLint *)PANDA_MALLOC_ARRAY(num_compressed_formats * sizeof(GLint));
  627. GLP(GetIntegerv)(GL_COMPRESSED_TEXTURE_FORMATS, formats);
  628. for (int i = 0; i < num_compressed_formats; ++i) {
  629. switch (formats[i]) {
  630. #ifndef OPENGLES_1
  631. case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  632. case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  633. _compressed_texture_formats.set_bit(Texture::CM_dxt1);
  634. break;
  635. #endif
  636. #ifdef OPENGLES
  637. case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
  638. case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
  639. _compressed_texture_formats.set_bit(Texture::CM_pvr1_2bpp);
  640. break;
  641. case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
  642. case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
  643. _compressed_texture_formats.set_bit(Texture::CM_pvr1_4bpp);
  644. break;
  645. #else
  646. case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
  647. _compressed_texture_formats.set_bit(Texture::CM_dxt3);
  648. break;
  649. case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
  650. _compressed_texture_formats.set_bit(Texture::CM_dxt5);
  651. break;
  652. case GL_COMPRESSED_RGB_FXT1_3DFX:
  653. case GL_COMPRESSED_RGBA_FXT1_3DFX:
  654. _compressed_texture_formats.set_bit(Texture::CM_fxt1);
  655. break;
  656. #endif
  657. default:
  658. break;
  659. }
  660. }
  661. PANDA_FREE_ARRAY(formats);
  662. }
  663. #ifdef OPENGLES_2
  664. _supports_bgr = false;
  665. #else
  666. _supports_bgr =
  667. has_extension("GL_EXT_bgra") || is_at_least_gl_version(1, 2);
  668. #endif
  669. #ifdef OPENGLES_2
  670. _supports_rescale_normal = true;
  671. #else
  672. _supports_rescale_normal =
  673. CLP(support_rescale_normal) &&
  674. (has_extension("GL_EXT_rescale_normal") || is_at_least_gl_version(1, 2));
  675. #endif
  676. _supports_multisample =
  677. has_extension("GL_ARB_multisample") || is_at_least_gl_version(1, 3);
  678. #ifdef OPENGLES_2
  679. _supports_generate_mipmap = true;
  680. #else
  681. _supports_generate_mipmap =
  682. has_extension("GL_SGIS_generate_mipmap") || is_at_least_gl_version(1, 4) || is_at_least_gles_version(1, 1);
  683. #endif
  684. _supports_multitexture = false;
  685. _supports_mesa_6 = false;
  686. if (_gl_version.find("Mesa 6.",0) != string::npos) {
  687. _supports_mesa_6 = true;
  688. }
  689. #ifdef OPENGLES
  690. _supports_tex_non_pow2 =
  691. has_extension("GL_OES_texture_npot");
  692. #else
  693. _supports_tex_non_pow2 =
  694. has_extension("GL_ARB_texture_non_power_of_two");
  695. #endif
  696. #ifdef OPENGLES_2 // OpenGL ES 2.0 doesn't support multitexturing.
  697. _supports_multitexture = false;
  698. #else
  699. if (is_at_least_gl_version(1, 3) || is_at_least_gles_version(1, 1)) {
  700. _supports_multitexture = true;
  701. _glActiveTexture = (PFNGLACTIVETEXTUREPROC)
  702. get_extension_func(GLPREFIX_QUOTED, "ActiveTexture");
  703. _glClientActiveTexture = (PFNGLACTIVETEXTUREPROC)
  704. get_extension_func(GLPREFIX_QUOTED, "ClientActiveTexture");
  705. _glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)
  706. get_extension_func(GLPREFIX_QUOTED, "MultiTexCoord1f");
  707. _glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)
  708. get_extension_func(GLPREFIX_QUOTED, "MultiTexCoord2f");
  709. _glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)
  710. get_extension_func(GLPREFIX_QUOTED, "MultiTexCoord3f");
  711. _glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)
  712. get_extension_func(GLPREFIX_QUOTED, "MultiTexCoord4f");
  713. _glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)
  714. get_extension_func(GLPREFIX_QUOTED, "MultiTexCoord1d");
  715. _glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)
  716. get_extension_func(GLPREFIX_QUOTED, "MultiTexCoord2d");
  717. _glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)
  718. get_extension_func(GLPREFIX_QUOTED, "MultiTexCoord3d");
  719. _glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)
  720. get_extension_func(GLPREFIX_QUOTED, "MultiTexCoord4d");
  721. } else if (has_extension("GL_ARB_multitexture")) {
  722. _supports_multitexture = true;
  723. _glActiveTexture = (PFNGLACTIVETEXTUREPROC)
  724. get_extension_func(GLPREFIX_QUOTED, "ActiveTextureARB");
  725. _glClientActiveTexture = (PFNGLACTIVETEXTUREPROC)
  726. get_extension_func(GLPREFIX_QUOTED, "ClientActiveTextureARB");
  727. _glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)
  728. get_extension_func(GLPREFIX_QUOTED, "MultiTexCoord1fARB");
  729. _glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)
  730. get_extension_func(GLPREFIX_QUOTED, "MultiTexCoord2fARB");
  731. _glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)
  732. get_extension_func(GLPREFIX_QUOTED, "MultiTexCoord3fARB");
  733. _glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)
  734. get_extension_func(GLPREFIX_QUOTED, "MultiTexCoord4fARB");
  735. _glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)
  736. get_extension_func(GLPREFIX_QUOTED, "MultiTexCoord1dARB");
  737. _glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)
  738. get_extension_func(GLPREFIX_QUOTED, "MultiTexCoord2dARB");
  739. _glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)
  740. get_extension_func(GLPREFIX_QUOTED, "MultiTexCoord3dARB");
  741. _glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)
  742. get_extension_func(GLPREFIX_QUOTED, "MultiTexCoord4dARB");
  743. }
  744. if (_supports_multitexture) {
  745. if (_glActiveTexture == NULL || _glClientActiveTexture == NULL
  746. #ifdef SUPPORT_IMMEDIATE_MODE
  747. || GLf(_glMultiTexCoord1) == NULL || GLf(_glMultiTexCoord2) == NULL
  748. || GLf(_glMultiTexCoord3) == NULL || GLf(_glMultiTexCoord4) == NULL
  749. #endif
  750. ) {
  751. GLCAT.warning()
  752. << "Multitexture advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  753. _supports_multitexture = false;
  754. }
  755. }
  756. #endif
  757. if (!_supports_multitexture) {
  758. _glActiveTexture = null_glActiveTexture;
  759. _glClientActiveTexture = null_glActiveTexture;
  760. }
  761. if (has_extension("GL_ARB_depth_texture")) {
  762. _supports_depth_texture = true;
  763. }
  764. if (_supports_depth_texture &&
  765. has_extension("GL_ARB_shadow") &&
  766. has_extension("GL_ARB_fragment_program_shadow")) {
  767. _supports_shadow_filter = true;
  768. }
  769. if (_gl_vendor.substr(0,3)=="ATI") {
  770. // ATI drivers have never provided correct shadow support.
  771. _supports_shadow_filter = false;
  772. }
  773. _supports_texture_combine =
  774. has_extension("GL_ARB_texture_env_combine") || is_at_least_gl_version(1, 3) || is_at_least_gles_version(1, 1);
  775. _supports_texture_saved_result =
  776. has_extension("GL_ARB_texture_env_crossbar") || has_extension("GL_OES_texture_env_crossbar") || is_at_least_gl_version(1, 4);
  777. _supports_texture_dot3 =
  778. has_extension("GL_ARB_texture_env_dot3") || is_at_least_gl_version(1, 3) || is_at_least_gles_version(1, 1);
  779. _supports_buffers = false;
  780. if (is_at_least_gl_version(1, 5) || is_at_least_gles_version(1, 1)) {
  781. _supports_buffers = true;
  782. _glGenBuffers = (PFNGLGENBUFFERSPROC)
  783. get_extension_func(GLPREFIX_QUOTED, "GenBuffers");
  784. _glBindBuffer = (PFNGLBINDBUFFERPROC)
  785. get_extension_func(GLPREFIX_QUOTED, "BindBuffer");
  786. _glBufferData = (PFNGLBUFFERDATAPROC)
  787. get_extension_func(GLPREFIX_QUOTED, "BufferData");
  788. _glBufferSubData = (PFNGLBUFFERSUBDATAPROC)
  789. get_extension_func(GLPREFIX_QUOTED, "BufferSubData");
  790. _glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)
  791. get_extension_func(GLPREFIX_QUOTED, "DeleteBuffers");
  792. } else if (has_extension("GL_ARB_vertex_buffer_object")) {
  793. _supports_buffers = true;
  794. _glGenBuffers = (PFNGLGENBUFFERSPROC)
  795. get_extension_func(GLPREFIX_QUOTED, "GenBuffersARB");
  796. _glBindBuffer = (PFNGLBINDBUFFERPROC)
  797. get_extension_func(GLPREFIX_QUOTED, "BindBufferARB");
  798. _glBufferData = (PFNGLBUFFERDATAPROC)
  799. get_extension_func(GLPREFIX_QUOTED, "BufferDataARB");
  800. _glBufferSubData = (PFNGLBUFFERSUBDATAPROC)
  801. get_extension_func(GLPREFIX_QUOTED, "BufferSubDataARB");
  802. _glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)
  803. get_extension_func(GLPREFIX_QUOTED, "DeleteBuffersARB");
  804. }
  805. if (_supports_buffers) {
  806. if (_glGenBuffers == NULL || _glBindBuffer == NULL ||
  807. _glBufferData == NULL || _glBufferSubData == NULL ||
  808. _glDeleteBuffers == NULL) {
  809. GLCAT.warning()
  810. << "Buffers advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  811. _supports_buffers = false;
  812. }
  813. }
  814. #if defined(HAVE_CG) && !defined(OPENGLES)
  815. if (cgGLIsProfileSupported(CG_PROFILE_ARBFP1) &&
  816. cgGLIsProfileSupported(CG_PROFILE_ARBVP1)) {
  817. _supports_basic_shaders = true;
  818. if (basic_shaders_only) {
  819. _shader_caps._active_vprofile = (int)CG_PROFILE_ARBVP1;
  820. _shader_caps._active_fprofile = (int)CG_PROFILE_ARBFP1;
  821. _shader_caps._active_gprofile = (int)CG_PROFILE_UNKNOWN; // No geometry shader if only using basic
  822. } else {
  823. _shader_caps._active_vprofile = (int)cgGLGetLatestProfile(CG_GL_VERTEX);
  824. _shader_caps._active_fprofile = (int)cgGLGetLatestProfile(CG_GL_FRAGMENT);
  825. _shader_caps._active_gprofile = (int)cgGLGetLatestProfile(CG_GL_GEOMETRY);
  826. }
  827. _shader_caps._ultimate_vprofile = (int)CG_PROFILE_VP40;
  828. _shader_caps._ultimate_fprofile = (int)CG_PROFILE_FP40;
  829. _shader_caps._ultimate_gprofile = (int)CG_PROFILE_GPU_GP;
  830. _glBindProgram = (PFNGLBINDPROGRAMARBPROC)
  831. get_extension_func(GLPREFIX_QUOTED, "BindProgramARB");
  832. // Bug workaround for radeons.
  833. if (_shader_caps._active_fprofile == CG_PROFILE_ARBFP1) {
  834. if (has_extension("GL_ATI_draw_buffers")) {
  835. _shader_caps._bug_list.insert(Shader::SBUG_ati_draw_buffers);
  836. }
  837. }
  838. }
  839. #endif // HAVE_CG
  840. #ifdef OPENGLES_2
  841. _supports_glsl = true;
  842. _supports_tessellation_shaders = false;
  843. #else
  844. #ifdef OPENGLES_1
  845. _supports_glsl = false;
  846. _supports_tessellation_shaders = false;
  847. #else
  848. _supports_glsl = is_at_least_gl_version(2, 0) || has_extension("GL_ARB_shading_language_100");
  849. _supports_geometry_shaders = is_at_least_gl_version(3, 2) || has_extension("GL_ARB_geometry_shader4");
  850. _supports_tessellation_shaders = is_at_least_gl_version(4, 0) || has_extension("GL_ARB_tessellation_shader");
  851. #endif
  852. #endif
  853. _shader_caps._supports_glsl = _supports_glsl;
  854. #ifndef OPENGLES
  855. if (_supports_glsl) {
  856. _glAttachShader = (PFNGLATTACHSHADERPROC)
  857. get_extension_func(GLPREFIX_QUOTED, "AttachShader");
  858. _glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)
  859. get_extension_func(GLPREFIX_QUOTED, "BindAttribLocation");
  860. _glCompileShader = (PFNGLCOMPILESHADERPROC)
  861. get_extension_func(GLPREFIX_QUOTED, "CompileShader");
  862. _glCreateProgram = (PFNGLCREATEPROGRAMPROC)
  863. get_extension_func(GLPREFIX_QUOTED, "CreateProgram");
  864. _glCreateShader = (PFNGLCREATESHADERPROC)
  865. get_extension_func(GLPREFIX_QUOTED, "CreateShader");
  866. _glDeleteProgram = (PFNGLDELETEPROGRAMPROC)
  867. get_extension_func(GLPREFIX_QUOTED, "DeleteProgram");
  868. _glDeleteShader = (PFNGLDELETESHADERPROC)
  869. get_extension_func(GLPREFIX_QUOTED, "DeleteShader");
  870. _glDetachShader = (PFNGLDETACHSHADERPROC)
  871. get_extension_func(GLPREFIX_QUOTED, "DetachShader");
  872. _glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)
  873. get_extension_func(GLPREFIX_QUOTED, "DisableVertexAttribArray");
  874. _glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)
  875. get_extension_func(GLPREFIX_QUOTED, "EnableVertexAttribArray");
  876. _glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)
  877. get_extension_func(GLPREFIX_QUOTED, "GetActiveAttrib");
  878. _glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)
  879. get_extension_func(GLPREFIX_QUOTED, "GetActiveUniform");
  880. _glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)
  881. get_extension_func(GLPREFIX_QUOTED, "GetAttribLocation");
  882. _glGetProgramiv = (PFNGLGETPROGRAMIVPROC)
  883. get_extension_func(GLPREFIX_QUOTED, "GetProgramiv");
  884. _glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)
  885. get_extension_func(GLPREFIX_QUOTED, "GetProgramInfoLog");
  886. _glGetShaderiv = (PFNGLGETSHADERIVPROC)
  887. get_extension_func(GLPREFIX_QUOTED, "GetShaderiv");
  888. _glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)
  889. get_extension_func(GLPREFIX_QUOTED, "GetShaderInfoLog");
  890. _glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)
  891. get_extension_func(GLPREFIX_QUOTED, "GetUniformLocation");
  892. _glLinkProgram = (PFNGLLINKPROGRAMPROC)
  893. get_extension_func(GLPREFIX_QUOTED, "LinkProgram");
  894. _glShaderSource = (PFNGLSHADERSOURCEPROC)
  895. get_extension_func(GLPREFIX_QUOTED, "ShaderSource");
  896. _glUseProgram = (PFNGLUSEPROGRAMPROC)
  897. get_extension_func(GLPREFIX_QUOTED, "UseProgram");
  898. _glUniform4f = (PFNGLUNIFORM4FPROC)
  899. get_extension_func(GLPREFIX_QUOTED, "Uniform4f");
  900. _glUniform1i = (PFNGLUNIFORM1IPROC)
  901. get_extension_func(GLPREFIX_QUOTED, "Uniform1i");
  902. _glUniform1fv = (PFNGLUNIFORM1FVPROC)
  903. get_extension_func(GLPREFIX_QUOTED, "Uniform1fv");
  904. _glUniform2fv = (PFNGLUNIFORM2FVPROC)
  905. get_extension_func(GLPREFIX_QUOTED, "Uniform2fv");
  906. _glUniform3fv = (PFNGLUNIFORM3FVPROC)
  907. get_extension_func(GLPREFIX_QUOTED, "Uniform3fv");
  908. _glUniform4fv = (PFNGLUNIFORM4FVPROC)
  909. get_extension_func(GLPREFIX_QUOTED, "Uniform4fv");
  910. _glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)
  911. get_extension_func(GLPREFIX_QUOTED, "UniformMatrix4fv");
  912. _glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)
  913. get_extension_func(GLPREFIX_QUOTED, "ValidateProgram");
  914. _glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)
  915. get_extension_func(GLPREFIX_QUOTED, "VertexAttribPointer");
  916. if (_supports_geometry_shaders) {
  917. _glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)
  918. get_extension_func(GLPREFIX_QUOTED, "ProgramParameteri");
  919. }
  920. if (_supports_tessellation_shaders) {
  921. _glPatchParameteri = (PFNGLPATCHPARAMETERIPROC)
  922. get_extension_func(GLPREFIX_QUOTED, "PatchParameteri");
  923. }
  924. }
  925. #endif
  926. #ifdef OPENGLES_2
  927. _glAttachShader = glAttachShader;
  928. _glBindAttribLocation = glBindAttribLocation;
  929. _glCompileShader = glCompileShader;
  930. _glCreateProgram = glCreateProgram;
  931. _glCreateShader = glCreateShader;
  932. _glDeleteProgram = glDeleteProgram;
  933. _glDeleteShader = glDeleteShader;
  934. _glDetachShader = glDetachShader;
  935. _glDisableVertexAttribArray = glDisableVertexAttribArray;
  936. _glEnableVertexAttribArray = glEnableVertexAttribArray;
  937. _glGetActiveAttrib = glGetActiveAttrib;
  938. _glGetActiveUniform = glGetActiveUniform;
  939. _glGetAttribLocation = glGetAttribLocation;
  940. _glGetProgramiv = glGetProgramiv;
  941. _glGetProgramInfoLog = glGetProgramInfoLog;
  942. _glGetShaderiv = glGetShaderiv;
  943. _glGetShaderInfoLog = glGetShaderInfoLog;
  944. _glGetUniformLocation = glGetUniformLocation;
  945. _glLinkProgram = glLinkProgram;
  946. _glShaderSource = glShaderSource;
  947. _glUseProgram = glUseProgram;
  948. _glUniform4f = glUniform4f;
  949. _glUniform1i = glUniform1i;
  950. _glUniform1fv = glUniform1fv;
  951. _glUniform2fv = glUniform2fv;
  952. _glUniform3fv = glUniform3fv;
  953. _glUniform4fv = glUniform4fv;
  954. _glUniformMatrix4fv = glUniformMatrix4fv;
  955. _glValidateProgram = glValidateProgram;
  956. _glVertexAttribPointer = glVertexAttribPointer;
  957. // We need to have a default shader to apply in case
  958. // something didn't happen to have a shader applied, or
  959. // if it failed to compile. This default shader just outputs
  960. // a red color, indicating that something went wrong.
  961. if (_default_shader == NULL) {
  962. _default_shader = new Shader(default_shader_name, default_shader_body, Shader::SL_GLSL);
  963. }
  964. #endif
  965. #ifdef OPENGLES_2
  966. // In OpenGL ES 2.x, FBO's are supported in the core.
  967. _supports_framebuffer_object = true;
  968. _glIsRenderbuffer = glIsRenderbuffer;
  969. _glBindRenderbuffer = glBindRenderbuffer;
  970. _glDeleteRenderbuffers = glDeleteRenderbuffers;
  971. _glGenRenderbuffers = glGenRenderbuffers;
  972. _glRenderbufferStorage = glRenderbufferStorage;
  973. _glGetRenderbufferParameteriv = glGetRenderbufferParameteriv;
  974. _glIsFramebuffer = glIsFramebuffer;
  975. _glBindFramebuffer = glBindFramebuffer;
  976. _glDeleteFramebuffers = glDeleteFramebuffers;
  977. _glGenFramebuffers = glGenFramebuffers;
  978. _glCheckFramebufferStatus = glCheckFramebufferStatus;
  979. _glFramebufferTexture1D = NULL;
  980. _glFramebufferTexture2D = glFramebufferTexture2D;
  981. if (has_extension("GL_OES_texture3D")) {
  982. _glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DOES)
  983. get_extension_func(GLPREFIX_QUOTED, "FramebufferTexture3DOES");
  984. } else {
  985. _glFramebufferTexture3D = NULL;
  986. }
  987. _glFramebufferRenderbuffer = glFramebufferRenderbuffer;
  988. _glGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameteriv;
  989. _glGenerateMipmap = glGenerateMipmap;
  990. #else
  991. _supports_framebuffer_object = false;
  992. if (has_extension("GL_EXT_framebuffer_object")) {
  993. _supports_framebuffer_object = true;
  994. _glIsRenderbuffer = (PFNGLISRENDERBUFFEREXTPROC)
  995. get_extension_func(GLPREFIX_QUOTED, "IsRenderbufferEXT");
  996. _glBindRenderbuffer = (PFNGLBINDRENDERBUFFEREXTPROC)
  997. get_extension_func(GLPREFIX_QUOTED, "BindRenderbufferEXT");
  998. _glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSEXTPROC)
  999. get_extension_func(GLPREFIX_QUOTED, "DeleteRenderbuffersEXT");
  1000. _glGenRenderbuffers = (PFNGLGENRENDERBUFFERSEXTPROC)
  1001. get_extension_func(GLPREFIX_QUOTED, "GenRenderbuffersEXT");
  1002. _glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEEXTPROC)
  1003. get_extension_func(GLPREFIX_QUOTED, "RenderbufferStorageEXT");
  1004. _glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)
  1005. get_extension_func(GLPREFIX_QUOTED, "GetRenderbufferParameterivEXT");
  1006. _glIsFramebuffer = (PFNGLISFRAMEBUFFEREXTPROC)
  1007. get_extension_func(GLPREFIX_QUOTED, "IsFramebufferEXT");
  1008. _glBindFramebuffer = (PFNGLBINDFRAMEBUFFEREXTPROC)
  1009. get_extension_func(GLPREFIX_QUOTED, "BindFramebufferEXT");
  1010. _glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSEXTPROC)
  1011. get_extension_func(GLPREFIX_QUOTED, "DeleteFramebuffersEXT");
  1012. _glGenFramebuffers = (PFNGLGENFRAMEBUFFERSEXTPROC)
  1013. get_extension_func(GLPREFIX_QUOTED, "GenFramebuffersEXT");
  1014. _glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
  1015. get_extension_func(GLPREFIX_QUOTED, "CheckFramebufferStatusEXT");
  1016. _glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)
  1017. get_extension_func(GLPREFIX_QUOTED, "FramebufferTexture1DEXT");
  1018. _glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)
  1019. get_extension_func(GLPREFIX_QUOTED, "FramebufferTexture2DEXT");
  1020. _glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)
  1021. get_extension_func(GLPREFIX_QUOTED, "FramebufferTexture3DEXT");
  1022. _glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)
  1023. get_extension_func(GLPREFIX_QUOTED, "FramebufferRenderbufferEXT");
  1024. _glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)
  1025. get_extension_func(GLPREFIX_QUOTED, "GetFramebufferAttachmentParameterivEXT");
  1026. _glGenerateMipmap = (PFNGLGENERATEMIPMAPEXTPROC)
  1027. get_extension_func(GLPREFIX_QUOTED, "GenerateMipmapEXT");
  1028. }
  1029. #ifdef OPENGLES
  1030. else if (has_extension("GL_OES_framebuffer_object")) {
  1031. _supports_framebuffer_object = true;
  1032. _glIsRenderbuffer = (PFNGLISRENDERBUFFEROESPROC)
  1033. get_extension_func(GLPREFIX_QUOTED, "IsRenderbufferOES");
  1034. _glBindRenderbuffer = (PFNGLBINDRENDERBUFFEROESPROC)
  1035. get_extension_func(GLPREFIX_QUOTED, "BindRenderbufferOES");
  1036. _glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSOESPROC)
  1037. get_extension_func(GLPREFIX_QUOTED, "DeleteRenderbuffersOES");
  1038. _glGenRenderbuffers = (PFNGLGENRENDERBUFFERSOESPROC)
  1039. get_extension_func(GLPREFIX_QUOTED, "GenRenderbuffersOES");
  1040. _glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEOESPROC)
  1041. get_extension_func(GLPREFIX_QUOTED, "RenderbufferStorageOES");
  1042. _glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVOESPROC)
  1043. get_extension_func(GLPREFIX_QUOTED, "GetRenderbufferParameterivOES");
  1044. _glIsFramebuffer = (PFNGLISFRAMEBUFFEROESPROC)
  1045. get_extension_func(GLPREFIX_QUOTED, "IsFramebufferOES");
  1046. _glBindFramebuffer = (PFNGLBINDFRAMEBUFFEROESPROC)
  1047. get_extension_func(GLPREFIX_QUOTED, "BindFramebufferOES");
  1048. _glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSOESPROC)
  1049. get_extension_func(GLPREFIX_QUOTED, "DeleteFramebuffersOES");
  1050. _glGenFramebuffers = (PFNGLGENFRAMEBUFFERSOESPROC)
  1051. get_extension_func(GLPREFIX_QUOTED, "GenFramebuffersOES");
  1052. _glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSOESPROC)
  1053. get_extension_func(GLPREFIX_QUOTED, "CheckFramebufferStatusOES");
  1054. _glFramebufferTexture1D = NULL;
  1055. _glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DOESPROC)
  1056. get_extension_func(GLPREFIX_QUOTED, "FramebufferTexture2DOES");
  1057. _glFramebufferTexture3D = NULL;
  1058. _glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFEROESPROC)
  1059. get_extension_func(GLPREFIX_QUOTED, "FramebufferRenderbufferOES");
  1060. _glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVOESPROC)
  1061. get_extension_func(GLPREFIX_QUOTED, "GetFramebufferAttachmentParameterivOES");
  1062. _glGenerateMipmap = (PFNGLGENERATEMIPMAPOESPROC)
  1063. get_extension_func(GLPREFIX_QUOTED, "GenerateMipmapOES");
  1064. }
  1065. #endif // OPENGLES
  1066. #endif
  1067. _supports_framebuffer_multisample = false;
  1068. if ( has_extension("GL_EXT_framebuffer_multisample") ) {
  1069. _supports_framebuffer_multisample = true;
  1070. _glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)
  1071. get_extension_func(GLPREFIX_QUOTED, "RenderbufferStorageMultisampleEXT");
  1072. }
  1073. _supports_framebuffer_multisample_coverage_nv = false;
  1074. if ( has_extension("GL_NV_framebuffer_multisample_coverage") ) {
  1075. _supports_framebuffer_multisample_coverage_nv = true;
  1076. _glRenderbufferStorageMultisampleCoverage = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC)
  1077. get_extension_func(GLPREFIX_QUOTED, "RenderbufferStorageMultisampleCoverageNV");
  1078. }
  1079. _supports_framebuffer_blit = false;
  1080. if ( has_extension("GL_EXT_framebuffer_blit") ) {
  1081. _supports_framebuffer_blit = true;
  1082. _glBlitFramebuffer = (PFNGLBLITFRAMEBUFFEREXTPROC)
  1083. get_extension_func(GLPREFIX_QUOTED, "BlitFramebufferEXT");
  1084. }
  1085. _glDrawBuffers = NULL;
  1086. #ifndef OPENGLES
  1087. if (is_at_least_gl_version(2, 0)) {
  1088. _glDrawBuffers = (PFNGLDRAWBUFFERSPROC)
  1089. get_extension_func(GLPREFIX_QUOTED, "DrawBuffers");
  1090. } else if (has_extension("GL_ARB_draw_buffers")) {
  1091. _glDrawBuffers = (PFNGLDRAWBUFFERSPROC)
  1092. get_extension_func(GLPREFIX_QUOTED, "DrawBuffersARB");
  1093. }
  1094. _max_draw_buffers = 1;
  1095. if (_glDrawBuffers != 0) {
  1096. GLint max_draw_buffers = 0;
  1097. GLP(GetIntegerv)(GL_MAX_DRAW_BUFFERS, &max_draw_buffers);
  1098. _max_draw_buffers = max_draw_buffers;
  1099. _maximum_simultaneous_render_targets = max_draw_buffers;
  1100. }
  1101. #endif // OPENGLES
  1102. _max_fb_samples = 0;
  1103. #ifndef OPENGLES
  1104. if (_supports_framebuffer_multisample) {
  1105. GLint max_samples;
  1106. GLP(GetIntegerv)(GL_MAX_SAMPLES_EXT, &max_samples);
  1107. _max_fb_samples = max_samples;
  1108. }
  1109. #endif
  1110. _supports_occlusion_query = false;
  1111. if (CLP(support_occlusion_query)) {
  1112. if (is_at_least_gl_version(1, 5)) {
  1113. _supports_occlusion_query = true;
  1114. _glGenQueries = (PFNGLGENQUERIESPROC)
  1115. get_extension_func(GLPREFIX_QUOTED, "GenQueries");
  1116. _glBeginQuery = (PFNGLBEGINQUERYPROC)
  1117. get_extension_func(GLPREFIX_QUOTED, "BeginQuery");
  1118. _glEndQuery = (PFNGLENDQUERYPROC)
  1119. get_extension_func(GLPREFIX_QUOTED, "EndQuery");
  1120. _glDeleteQueries = (PFNGLDELETEQUERIESPROC)
  1121. get_extension_func(GLPREFIX_QUOTED, "DeleteQueries");
  1122. _glGetQueryiv = (PFNGLGETQUERYIVPROC)
  1123. get_extension_func(GLPREFIX_QUOTED, "GetQueryiv");
  1124. _glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)
  1125. get_extension_func(GLPREFIX_QUOTED, "GetQueryObjectuiv");
  1126. } else if (has_extension("GL_ARB_occlusion_query")) {
  1127. _supports_occlusion_query = true;
  1128. _glGenQueries = (PFNGLGENQUERIESPROC)
  1129. get_extension_func(GLPREFIX_QUOTED, "GenQueriesARB");
  1130. _glBeginQuery = (PFNGLBEGINQUERYPROC)
  1131. get_extension_func(GLPREFIX_QUOTED, "BeginQueryARB");
  1132. _glEndQuery = (PFNGLENDQUERYPROC)
  1133. get_extension_func(GLPREFIX_QUOTED, "EndQueryARB");
  1134. _glDeleteQueries = (PFNGLDELETEQUERIESPROC)
  1135. get_extension_func(GLPREFIX_QUOTED, "DeleteQueriesARB");
  1136. _glGetQueryiv = (PFNGLGETQUERYIVPROC)
  1137. get_extension_func(GLPREFIX_QUOTED, "GetQueryivARB");
  1138. _glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)
  1139. get_extension_func(GLPREFIX_QUOTED, "GetQueryObjectuivARB");
  1140. }
  1141. }
  1142. #ifndef OPENGLES
  1143. if (_supports_occlusion_query) {
  1144. if (_glGenQueries == NULL || _glBeginQuery == NULL ||
  1145. _glEndQuery == NULL || _glDeleteQueries == NULL ||
  1146. _glGetQueryiv == NULL || _glGetQueryObjectuiv == NULL) {
  1147. GLCAT.warning()
  1148. << "Occlusion queries advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1149. _supports_occlusion_query = false;
  1150. } else {
  1151. GLint num_bits;
  1152. _glGetQueryiv(GL_SAMPLES_PASSED, GL_QUERY_COUNTER_BITS, &num_bits);
  1153. if (num_bits == 0) {
  1154. _supports_occlusion_query = false;
  1155. }
  1156. if (GLCAT.is_debug()) {
  1157. GLCAT.debug()
  1158. << "Occlusion query counter provides " << num_bits << " bits.\n";
  1159. }
  1160. }
  1161. }
  1162. #endif
  1163. #ifdef OPENGLES_2
  1164. // In OpenGL ES 2.x, this is supported in the core.
  1165. _glBlendEquation = glBlendEquation;
  1166. #else
  1167. _glBlendEquation = NULL;
  1168. bool supports_blend_equation = false;
  1169. if (is_at_least_gl_version(1, 2)) {
  1170. supports_blend_equation = true;
  1171. _glBlendEquation = (PFNGLBLENDEQUATIONPROC)
  1172. get_extension_func(GLPREFIX_QUOTED, "BlendEquation");
  1173. } else if (has_extension("GL_OES_blend_subtract")) {
  1174. supports_blend_equation = true;
  1175. _glBlendEquation = (PFNGLBLENDEQUATIONPROC)
  1176. get_extension_func(GLPREFIX_QUOTED, "BlendEquationOES");
  1177. } else if (has_extension("GL_EXT_blend_minmax")) {
  1178. supports_blend_equation = true;
  1179. _glBlendEquation = (PFNGLBLENDEQUATIONPROC)
  1180. get_extension_func(GLPREFIX_QUOTED, "BlendEquationEXT");
  1181. }
  1182. if (supports_blend_equation && _glBlendEquation == NULL) {
  1183. GLCAT.warning()
  1184. << "BlendEquation advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  1185. }
  1186. if (_glBlendEquation == NULL) {
  1187. _glBlendEquation = null_glBlendEquation;
  1188. }
  1189. #endif
  1190. #ifdef OPENGLES_2
  1191. // In OpenGL ES 2.x, this is supported in the core.
  1192. _glBlendColor = glBlendColor;
  1193. #else
  1194. _glBlendColor = NULL;
  1195. bool supports_blend_color = false;
  1196. if (is_at_least_gl_version(1, 2)) {
  1197. supports_blend_color = true;
  1198. _glBlendColor = (PFNGLBLENDCOLORPROC)
  1199. get_extension_func(GLPREFIX_QUOTED, "BlendColor");
  1200. } else if (has_extension("GL_EXT_blend_color")) {
  1201. supports_blend_color = true;
  1202. _glBlendColor = (PFNGLBLENDCOLORPROC)
  1203. get_extension_func(GLPREFIX_QUOTED, "BlendColorEXT");
  1204. }
  1205. if (supports_blend_color && _glBlendColor == NULL) {
  1206. GLCAT.warning()
  1207. << "BlendColor advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  1208. }
  1209. if (_glBlendColor == NULL) {
  1210. _glBlendColor = null_glBlendColor;
  1211. }
  1212. #endif
  1213. #ifdef OPENGLES
  1214. _edge_clamp = GL_CLAMP_TO_EDGE;
  1215. #else
  1216. _edge_clamp = GL_CLAMP;
  1217. if (has_extension("GL_SGIS_texture_edge_clamp") ||
  1218. is_at_least_gl_version(1, 2) || is_at_least_gles_version(1, 1)) {
  1219. _edge_clamp = GL_CLAMP_TO_EDGE;
  1220. }
  1221. #endif
  1222. _border_clamp = _edge_clamp;
  1223. #ifndef OPENGLES
  1224. if (CLP(support_clamp_to_border) &&
  1225. (has_extension("GL_ARB_texture_border_clamp") ||
  1226. is_at_least_gl_version(1, 3))) {
  1227. _border_clamp = GL_CLAMP_TO_BORDER;
  1228. }
  1229. #endif
  1230. _mirror_repeat = GL_REPEAT;
  1231. if (has_extension("GL_ARB_texture_mirrored_repeat") ||
  1232. is_at_least_gl_version(1, 4) ||
  1233. has_extension("GL_OES_texture_mirrored_repeat")) {
  1234. _mirror_repeat = GL_MIRRORED_REPEAT;
  1235. }
  1236. _mirror_clamp = _edge_clamp;
  1237. _mirror_edge_clamp = _edge_clamp;
  1238. _mirror_border_clamp = _border_clamp;
  1239. #ifndef OPENGLES
  1240. if (has_extension("GL_EXT_texture_mirror_clamp")) {
  1241. _mirror_clamp = GL_MIRROR_CLAMP_EXT;
  1242. _mirror_edge_clamp = GL_MIRROR_CLAMP_TO_EDGE_EXT;
  1243. _mirror_border_clamp = GL_MIRROR_CLAMP_TO_BORDER_EXT;
  1244. }
  1245. #endif
  1246. if (_supports_multisample) {
  1247. GLint sample_buffers = 0;
  1248. GLP(GetIntegerv)(GL_SAMPLE_BUFFERS, &sample_buffers);
  1249. if (sample_buffers != 1) {
  1250. // Even if the API supports multisample, we might have ended up
  1251. // with a framebuffer that doesn't have any multisample bits.
  1252. // (It's also possible the graphics card doesn't provide any
  1253. // framebuffers with multisample.) In this case, we don't
  1254. // really support the multisample API's, since they won't do
  1255. // anything.
  1256. _supports_multisample = false;
  1257. }
  1258. }
  1259. GLint max_texture_size = 0;
  1260. GLint max_3d_texture_size = 0;
  1261. GLint max_2d_texture_array_layers = 0;
  1262. GLint max_cube_map_size = 0;
  1263. GLP(GetIntegerv)(GL_MAX_TEXTURE_SIZE, &max_texture_size);
  1264. _max_texture_dimension = max_texture_size;
  1265. if (_supports_3d_texture) {
  1266. #ifndef OPENGLES_1
  1267. GLP(GetIntegerv)(GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
  1268. #endif
  1269. _max_3d_texture_dimension = max_3d_texture_size;
  1270. } else {
  1271. _max_3d_texture_dimension = 0;
  1272. }
  1273. #ifndef OPENGLES
  1274. if(_supports_2d_texture_array) {
  1275. GLP(GetIntegerv)(GL_MAX_ARRAY_TEXTURE_LAYERS_EXT, &max_2d_texture_array_layers);
  1276. _max_2d_texture_array_layers = max_2d_texture_array_layers;
  1277. }
  1278. #endif
  1279. if (_supports_cube_map) {
  1280. GLP(GetIntegerv)(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_size);
  1281. _max_cube_map_dimension = max_cube_map_size;
  1282. } else {
  1283. _max_cube_map_dimension = 0;
  1284. }
  1285. GLint max_elements_vertices = 0, max_elements_indices = 0;
  1286. #ifndef OPENGLES
  1287. GLP(GetIntegerv)(GL_MAX_ELEMENTS_VERTICES, &max_elements_vertices);
  1288. GLP(GetIntegerv)(GL_MAX_ELEMENTS_INDICES, &max_elements_indices);
  1289. if (max_elements_vertices > 0) {
  1290. _max_vertices_per_array = max_elements_vertices;
  1291. }
  1292. if (max_elements_indices > 0) {
  1293. _max_vertices_per_primitive = max_elements_indices;
  1294. }
  1295. #endif // OPENGLES
  1296. if (GLCAT.is_debug()) {
  1297. GLCAT.debug()
  1298. << "max texture dimension = " << _max_texture_dimension
  1299. << ", max 3d texture = " << _max_3d_texture_dimension
  1300. << ", max 2d texture array = " << max_2d_texture_array_layers
  1301. << ", max cube map = " << _max_cube_map_dimension << "\n";
  1302. GLCAT.debug()
  1303. << "max_elements_vertices = " << max_elements_vertices
  1304. << ", max_elements_indices = " << max_elements_indices << "\n";
  1305. if (_supports_buffers) {
  1306. if (vertex_buffers) {
  1307. GLCAT.debug()
  1308. << "vertex buffer objects are supported.\n";
  1309. } else {
  1310. GLCAT.debug()
  1311. << "vertex buffer objects are supported (but not enabled).\n";
  1312. }
  1313. } else {
  1314. GLCAT.debug()
  1315. << "vertex buffer objects are NOT supported.\n";
  1316. }
  1317. #ifdef SUPPORT_IMMEDIATE_MODE
  1318. if (!vertex_arrays) {
  1319. GLCAT.debug()
  1320. << "immediate mode commands will be used instead of vertex arrays.\n";
  1321. }
  1322. #endif
  1323. if (!_supports_compressed_texture) {
  1324. GLCAT.debug()
  1325. << "Texture compression is not supported.\n";
  1326. } else {
  1327. GLint num_compressed_formats = 0;
  1328. GLP(GetIntegerv)(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_compressed_formats);
  1329. if (num_compressed_formats == 0) {
  1330. GLCAT.debug()
  1331. << "No specific compressed texture formats are supported.\n";
  1332. } else {
  1333. GLCAT.debug()
  1334. << "Supported compressed texture formats:\n";
  1335. GLint *formats = (GLint *)PANDA_MALLOC_ARRAY(num_compressed_formats * sizeof(GLint));
  1336. GLP(GetIntegerv)(GL_COMPRESSED_TEXTURE_FORMATS, formats);
  1337. for (int i = 0; i < num_compressed_formats; ++i) {
  1338. switch (formats[i]) {
  1339. #ifndef OPENGLES_1
  1340. case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  1341. GLCAT.debug(false) << " GL_COMPRESSED_RGB_S3TC_DXT1_EXT\n";
  1342. break;
  1343. case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  1344. GLCAT.debug(false) << " GL_COMPRESSED_RGBA_S3TC_DXT1_EXT\n";
  1345. break;
  1346. #endif
  1347. #ifdef OPENGLES
  1348. case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
  1349. GLCAT.debug(false) << " GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG\n";
  1350. break;
  1351. case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
  1352. GLCAT.debug(false) << " GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG\n";
  1353. break;
  1354. case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
  1355. GLCAT.debug(false) << " GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG\n";
  1356. break;
  1357. case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
  1358. GLCAT.debug(false) << " GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG\n";
  1359. break;
  1360. #else
  1361. case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
  1362. GLCAT.debug(false) << " GL_COMPRESSED_RGBA_S3TC_DXT3_EXT\n";
  1363. break;
  1364. case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
  1365. GLCAT.debug(false) << " GL_COMPRESSED_RGBA_S3TC_DXT5_EXT\n";
  1366. break;
  1367. case GL_COMPRESSED_RGB_FXT1_3DFX:
  1368. GLCAT.debug(false) << " GL_COMPRESSED_RGB_FXT1_3DFX\n";
  1369. break;
  1370. case GL_COMPRESSED_RGBA_FXT1_3DFX:
  1371. GLCAT.debug(false) << " GL_COMPRESSED_RGBA_FXT1_3DFX\n";
  1372. break;
  1373. #endif
  1374. default:
  1375. GLCAT.debug(false)
  1376. << " Unknown compressed format 0x" << hex << formats[i]
  1377. << dec << "\n";
  1378. }
  1379. }
  1380. PANDA_FREE_ARRAY(formats);
  1381. }
  1382. }
  1383. }
  1384. _num_active_texture_stages = 0;
  1385. // Check availability of anisotropic texture filtering.
  1386. _supports_anisotropy = false;
  1387. _max_anisotropy = 1.0;
  1388. if (has_extension("GL_EXT_texture_filter_anisotropic")) {
  1389. GLfloat max_anisotropy;
  1390. GLP(GetFloatv)(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy);
  1391. _max_anisotropy = (PN_stdfloat)max_anisotropy;
  1392. _supports_anisotropy = true;
  1393. }
  1394. report_my_gl_errors();
  1395. if (support_stencil) {
  1396. GLint num_stencil_bits;
  1397. GLP(GetIntegerv)(GL_STENCIL_BITS, &num_stencil_bits);
  1398. _supports_stencil = (num_stencil_bits != 0);
  1399. }
  1400. _supports_stencil_wrap =
  1401. has_extension("GL_EXT_stencil_wrap") || has_extension("GL_OES_stencil_wrap");
  1402. _supports_two_sided_stencil = has_extension("GL_EXT_stencil_two_side");
  1403. if (_supports_two_sided_stencil) {
  1404. _glActiveStencilFaceEXT = (PFNGLACTIVESTENCILFACEEXTPROC)
  1405. get_extension_func(GLPREFIX_QUOTED, "ActiveStencilFaceEXT");
  1406. }
  1407. else {
  1408. _glActiveStencilFaceEXT = 0;
  1409. }
  1410. #ifndef OPENGLES
  1411. // Some drivers expose one, some expose the other. ARB seems to be the newer one.
  1412. if (has_extension("GL_ARB_draw_instanced")) {
  1413. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1414. get_extension_func(GLPREFIX_QUOTED, "DrawArraysInstancedARB");
  1415. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1416. get_extension_func(GLPREFIX_QUOTED, "DrawElementsInstancedARB");
  1417. _supports_geometry_instancing = true;
  1418. } else if (has_extension("GL_EXT_draw_instanced")) {
  1419. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1420. get_extension_func(GLPREFIX_QUOTED, "DrawArraysInstancedEXT");
  1421. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1422. get_extension_func(GLPREFIX_QUOTED, "DrawElementsInstancedEXT");
  1423. _supports_geometry_instancing = true;
  1424. } else {
  1425. _glDrawElementsInstanced = 0;
  1426. _glDrawArraysInstanced = 0;
  1427. }
  1428. #endif
  1429. _auto_rescale_normal = false;
  1430. // Ensure the initial state is what we say it should be (in some
  1431. // cases, we don't want the GL default settings; in others, we have
  1432. // to force the point with some drivers that aren't strictly
  1433. // compliant w.r.t. initial settings).
  1434. GLP(FrontFace)(GL_CCW);
  1435. #ifndef OPENGLES_2
  1436. GLP(Disable)(GL_LINE_SMOOTH);
  1437. GLP(Disable)(GL_POINT_SMOOTH);
  1438. #ifndef OPENGLES
  1439. GLP(Disable)(GL_POLYGON_SMOOTH);
  1440. #endif // OPENGLES
  1441. if (_supports_multisample) {
  1442. GLP(Disable)(GL_MULTISAMPLE);
  1443. }
  1444. #endif
  1445. // Set up all the enabled/disabled flags to GL's known initial
  1446. // values: everything off.
  1447. _multisample_mode = 0;
  1448. _line_smooth_enabled = false;
  1449. _point_smooth_enabled = false;
  1450. _polygon_smooth_enabled = false;
  1451. _stencil_test_enabled = false;
  1452. _blend_enabled = false;
  1453. _depth_test_enabled = false;
  1454. _fog_enabled = false;
  1455. _alpha_test_enabled = false;
  1456. _polygon_offset_enabled = false;
  1457. _flat_shade_model = false;
  1458. _decal_level = 0;
  1459. _tex_gen_point_sprite = false;
  1460. #ifndef OPENGLES
  1461. // Dither is on by default in GL; let's turn it off
  1462. GLP(Disable)(GL_DITHER);
  1463. #endif // OPENGLES
  1464. _dithering_enabled = false;
  1465. #ifndef OPENGLES_1
  1466. _current_shader = (Shader *)NULL;
  1467. _current_shader_context = (CLP(ShaderContext) *)NULL;
  1468. _vertex_array_shader = (Shader *)NULL;
  1469. _vertex_array_shader_context = (CLP(ShaderContext) *)NULL;
  1470. _texture_binding_shader = (Shader *)NULL;
  1471. _texture_binding_shader_context = (CLP(ShaderContext) *)NULL;
  1472. #endif
  1473. #ifdef OPENGLES_2
  1474. _max_lights = 0;
  1475. #else
  1476. // Count the max number of lights
  1477. GLint max_lights = 0;
  1478. GLP(GetIntegerv)(GL_MAX_LIGHTS, &max_lights);
  1479. _max_lights = max_lights;
  1480. if (GLCAT.is_debug()) {
  1481. GLCAT.debug()
  1482. << "max lights = " << _max_lights << "\n";
  1483. }
  1484. #endif
  1485. #ifdef OPENGLES_2
  1486. _max_clip_planes = 0;
  1487. #else
  1488. // Count the max number of clipping planes
  1489. GLint max_clip_planes = 0;
  1490. GLP(GetIntegerv)(GL_MAX_CLIP_PLANES, &max_clip_planes);
  1491. _max_clip_planes = max_clip_planes;
  1492. if (GLCAT.is_debug()) {
  1493. GLCAT.debug()
  1494. << "max clip planes = " << _max_clip_planes << "\n";
  1495. }
  1496. #endif
  1497. if (_supports_multitexture) {
  1498. GLint max_texture_stages = 0;
  1499. #ifdef OPENGLES_2
  1500. GLP(GetIntegerv)(GL_MAX_TEXTURE_IMAGE_UNITS, &max_texture_stages);
  1501. #else
  1502. GLP(GetIntegerv)(GL_MAX_TEXTURE_UNITS, &max_texture_stages);
  1503. #endif
  1504. _max_texture_stages = max_texture_stages;
  1505. if (GLCAT.is_debug()) {
  1506. GLCAT.debug()
  1507. << "max texture stages = " << _max_texture_stages << "\n";
  1508. }
  1509. }
  1510. _current_vbuffer_index = 0;
  1511. _current_ibuffer_index = 0;
  1512. _current_fbo = 0;
  1513. _auto_antialias_mode = false;
  1514. _render_mode = RenderModeAttrib::M_filled;
  1515. _point_size = 1.0f;
  1516. _point_perspective = false;
  1517. _vertex_blending_enabled = false;
  1518. report_my_gl_errors();
  1519. #ifndef OPENGLES_2
  1520. if (CLP(cheap_textures)) {
  1521. GLCAT.info()
  1522. << "Setting GLP(Hint)() for fastest textures.\n";
  1523. GLP(Hint)(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
  1524. }
  1525. // Use per-vertex fog if per-pixel fog requires SW renderer
  1526. GLP(Hint)(GL_FOG_HINT, GL_DONT_CARE);
  1527. #endif
  1528. GLint num_red_bits = 0;
  1529. GLP(GetIntegerv)(GL_RED_BITS, &num_red_bits);
  1530. if (num_red_bits < 8) {
  1531. GLP(Enable)(GL_DITHER);
  1532. _dithering_enabled = true;
  1533. if (GLCAT.is_debug()) {
  1534. GLCAT.debug()
  1535. << "frame buffer depth = " << num_red_bits
  1536. << " bits/channel, enabling dithering\n";
  1537. }
  1538. }
  1539. _error_count = 0;
  1540. report_my_gl_errors();
  1541. void gl_set_stencil_functions (StencilRenderStates *stencil_render_states);
  1542. gl_set_stencil_functions (_stencil_render_states);
  1543. #if defined(HAVE_CG) && !defined(OPENGLES)
  1544. typedef struct
  1545. {
  1546. CGprofile cg_profile;
  1547. int shader_model;
  1548. }
  1549. CG_PROFILE_TO_SHADER_MODEL;
  1550. static CG_PROFILE_TO_SHADER_MODEL cg_profile_to_shader_model_array [ ] = {
  1551. // fp40 - OpenGL fragment profile for NV4x (GeForce 6xxx and 7xxx
  1552. // Series, NV4x-based Quadro FX, etc.)
  1553. CG_PROFILE_FP40,
  1554. SM_30,
  1555. // fp30 - OpenGL fragment profile for NV3x (GeForce FX, Quadro FX, etc.)
  1556. CG_PROFILE_FP30,
  1557. SM_2X,
  1558. // This OpenGL profile corresponds to the per-fragment
  1559. // functionality introduced by GeForce FX and other DirectX 9
  1560. // GPUs.
  1561. CG_PROFILE_ARBFP1,
  1562. SM_20,
  1563. // fp20 - OpenGL fragment profile for NV2x (GeForce3, GeForce4 Ti,
  1564. // Quadro DCC, etc.)
  1565. CG_PROFILE_FP20,
  1566. SM_11,
  1567. // no shader support
  1568. CG_PROFILE_UNKNOWN,
  1569. SM_00,
  1570. };
  1571. int index;
  1572. CG_PROFILE_TO_SHADER_MODEL *cg_profile_to_shader_model;
  1573. index = 0;
  1574. cg_profile_to_shader_model = cg_profile_to_shader_model_array;
  1575. while (cg_profile_to_shader_model -> shader_model != SM_00) {
  1576. if (cgGLIsProfileSupported(cg_profile_to_shader_model -> cg_profile)) {
  1577. _shader_model = cg_profile_to_shader_model -> shader_model;
  1578. break;
  1579. }
  1580. cg_profile_to_shader_model++;
  1581. }
  1582. // DisplayInformation may have better shader model detection
  1583. {
  1584. GraphicsPipe *pipe;
  1585. DisplayInformation *display_information;
  1586. pipe = this -> get_pipe ( );
  1587. if (pipe) {
  1588. display_information = pipe -> get_display_information ( );
  1589. if (display_information) {
  1590. if (display_information -> get_shader_model ( ) > _shader_model) {
  1591. _shader_model = display_information -> get_shader_model ( );
  1592. }
  1593. }
  1594. }
  1595. }
  1596. _auto_detect_shader_model = _shader_model;
  1597. CGprofile vertex_profile;
  1598. CGprofile pixel_profile;
  1599. vertex_profile = cgGLGetLatestProfile (CG_GL_VERTEX);
  1600. pixel_profile = cgGLGetLatestProfile (CG_GL_FRAGMENT);
  1601. if (GLCAT.is_debug()) {
  1602. // Temp ifdef: this crashes Mesa.
  1603. #ifndef OSMESA_MAJOR_VERSION
  1604. GLCAT.debug()
  1605. << "\nCg vertex profile = " << cgGetProfileString(vertex_profile) << " id = " << vertex_profile
  1606. << "\nCg pixel profile = " << cgGetProfileString(pixel_profile) << " id = " << pixel_profile
  1607. << "\nshader model = " << _shader_model
  1608. << "\n";
  1609. #endif
  1610. }
  1611. #endif
  1612. // Now that the GSG has been initialized, make it available for
  1613. // optimizations.
  1614. add_gsg(this);
  1615. }
  1616. ////////////////////////////////////////////////////////////////////
  1617. // Function: GLGraphicsStateGuardian::finish
  1618. // Access: Public, Virtual
  1619. // Description: Force the graphics card to finish drawing before
  1620. // returning. !!!!!HACK WARNING!!!!
  1621. // glfinish does not actually wait for the graphics card to finish drawing
  1622. // only for draw calls to finish. Thus flip may not happene
  1623. // immediately. Instead we read a single pixel from
  1624. // the framebuffer. This forces the graphics card to
  1625. // finish drawing the frame before returning.
  1626. ////////////////////////////////////////////////////////////////////
  1627. void CLP(GraphicsStateGuardian)::
  1628. finish() {
  1629. // Rather than call glfinish which returns immediately if
  1630. // draw commands have been submitted, we will read a single pixel
  1631. // from the frame. That will force the graphics card to finish
  1632. // drawing before it is called
  1633. char data[4];
  1634. GLP(ReadPixels)(0,0,1,1,GL_RGBA,GL_UNSIGNED_BYTE,&data);
  1635. //GLP(Finish);
  1636. }
  1637. ////////////////////////////////////////////////////////////////////
  1638. // Function: GraphicsStateGuardian::clear
  1639. // Access: Public
  1640. // Description: Clears the framebuffer within the current
  1641. // DisplayRegion, according to the flags indicated by
  1642. // the given DrawableRegion object.
  1643. //
  1644. // This does not set the DisplayRegion first. You
  1645. // should call prepare_display_region() to specify the
  1646. // region you wish the clear operation to apply to.
  1647. ////////////////////////////////////////////////////////////////////
  1648. void CLP(GraphicsStateGuardian)::
  1649. clear(DrawableRegion *clearable) {
  1650. PStatTimer timer(_clear_pcollector);
  1651. report_my_gl_errors();
  1652. if ((!clearable->get_clear_color_active())&&
  1653. (!clearable->get_clear_depth_active())&&
  1654. (!clearable->get_clear_stencil_active())) {
  1655. return;
  1656. }
  1657. set_state_and_transform(RenderState::make_empty(), _internal_transform);
  1658. int mask = 0;
  1659. for (int i=0; i<_current_properties->get_aux_rgba(); i++) {
  1660. int layerid = GraphicsOutput::RTP_aux_rgba_0 + i;
  1661. int layerbit = RenderBuffer::T_aux_rgba_0 << i;
  1662. if (clearable->get_clear_active(layerid)) {
  1663. LColor v = clearable->get_clear_value(layerid);
  1664. GLP(ClearColor)(v[0],v[1],v[2],v[3]);
  1665. set_draw_buffer(layerbit);
  1666. GLP(Clear)(GL_COLOR_BUFFER_BIT);
  1667. }
  1668. }
  1669. for (int i=0; i<_current_properties->get_aux_hrgba(); i++) {
  1670. int layerid = GraphicsOutput::RTP_aux_hrgba_0 + i;
  1671. int layerbit = RenderBuffer::T_aux_hrgba_0 << i;
  1672. if (clearable->get_clear_active(layerid)) {
  1673. LColor v = clearable->get_clear_value(layerid);
  1674. GLP(ClearColor)(v[0],v[1],v[2],v[3]);
  1675. set_draw_buffer(layerbit);
  1676. GLP(Clear)(GL_COLOR_BUFFER_BIT);
  1677. }
  1678. }
  1679. for (int i=0; i<_current_properties->get_aux_float(); i++) {
  1680. int layerid = GraphicsOutput::RTP_aux_float_0 + i;
  1681. int layerbit = RenderBuffer::T_aux_float_0 << i;
  1682. if (clearable->get_clear_active(layerid)) {
  1683. LColor v = clearable->get_clear_value(layerid);
  1684. GLP(ClearColor)(v[0],v[1],v[2],v[3]);
  1685. set_draw_buffer(layerbit);
  1686. GLP(Clear)(GL_COLOR_BUFFER_BIT);
  1687. }
  1688. }
  1689. if (clearable->get_clear_color_active()) {
  1690. LColor v = clearable->get_clear_color();
  1691. GLP(ClearColor)(v[0],v[1],v[2],v[3]);
  1692. if (CLP(color_mask)) {
  1693. GLP(ColorMask)(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  1694. }
  1695. _state_mask.clear_bit(ColorWriteAttrib::get_class_slot());
  1696. mask |= GL_COLOR_BUFFER_BIT;
  1697. set_draw_buffer(clearable->get_draw_buffer_type());
  1698. }
  1699. if (clearable->get_clear_depth_active()) {
  1700. #ifdef OPENGLES
  1701. GLP(ClearDepthf)(clearable->get_clear_depth());
  1702. #else
  1703. GLP(ClearDepth)(clearable->get_clear_depth());
  1704. #endif // OPENGLES
  1705. #ifdef GSG_VERBOSE
  1706. GLCAT.spam()
  1707. << "glDepthMask(GL_TRUE)" << endl;
  1708. #endif
  1709. GLP(DepthMask)(GL_TRUE);
  1710. _state_mask.clear_bit(DepthWriteAttrib::get_class_slot());
  1711. mask |= GL_DEPTH_BUFFER_BIT;
  1712. }
  1713. if (clearable->get_clear_stencil_active()) {
  1714. GLP(ClearStencil)(clearable->get_clear_stencil());
  1715. mask |= GL_STENCIL_BUFFER_BIT;
  1716. }
  1717. GLP(Clear)(mask);
  1718. // In the past, it was possible to set the draw buffer
  1719. // once in prepare_display_region and then forget about it.
  1720. // Now, with aux layers, it is necessary to occasionally
  1721. // change the draw buffer. In time, I think there will need
  1722. // to be a draw buffer attrib. Until then, this little hack
  1723. // to put things back the way they were after
  1724. // prepare_display_region will do.
  1725. set_draw_buffer(_draw_buffer_type);
  1726. if (GLCAT.is_spam()) {
  1727. GLCAT.spam() << "glClear(";
  1728. if (mask & GL_COLOR_BUFFER_BIT) {
  1729. GLCAT.spam(false) << "GL_COLOR_BUFFER_BIT|";
  1730. }
  1731. if (mask & GL_DEPTH_BUFFER_BIT) {
  1732. GLCAT.spam(false) << "GL_DEPTH_BUFFER_BIT|";
  1733. }
  1734. if (mask & GL_STENCIL_BUFFER_BIT) {
  1735. GLCAT.spam(false) << "GL_STENCIL_BUFFER_BIT|";
  1736. }
  1737. #ifndef OPENGLES
  1738. if (mask & GL_ACCUM_BUFFER_BIT) {
  1739. GLCAT.spam(false) << "GL_ACCUM_BUFFER_BIT|";
  1740. }
  1741. #endif
  1742. GLCAT.spam(false) << ")" << endl;
  1743. }
  1744. report_my_gl_errors();
  1745. }
  1746. ////////////////////////////////////////////////////////////////////
  1747. // Function: GLGraphicsStateGuardian::prepare_display_region
  1748. // Access: Public, Virtual
  1749. // Description: Prepare a display region for rendering (set up
  1750. // scissor region and viewport)
  1751. ////////////////////////////////////////////////////////////////////
  1752. void CLP(GraphicsStateGuardian)::
  1753. prepare_display_region(DisplayRegionPipelineReader *dr) {
  1754. nassertv(dr != (DisplayRegionPipelineReader *)NULL);
  1755. GraphicsStateGuardian::prepare_display_region(dr);
  1756. int l, b, w, h;
  1757. dr->get_region_pixels(l, b, w, h);
  1758. _viewport_x = l;
  1759. _viewport_y = b;
  1760. _viewport_width = w;
  1761. _viewport_height = h;
  1762. GLint x = GLint(l);
  1763. GLint y = GLint(b);
  1764. GLsizei width = GLsizei(w);
  1765. GLsizei height = GLsizei(h);
  1766. _draw_buffer_type = dr->get_object()->get_draw_buffer_type() & _current_properties->get_buffer_mask() & _stereo_buffer_mask;
  1767. _draw_buffer_type |= _current_properties->get_aux_mask();
  1768. set_draw_buffer(_draw_buffer_type);
  1769. GLP(Enable)(GL_SCISSOR_TEST);
  1770. GLP(Scissor)(x, y, width, height);
  1771. GLP(Viewport)(x, y, width, height);
  1772. report_my_gl_errors();
  1773. do_point_size();
  1774. }
  1775. ////////////////////////////////////////////////////////////////////
  1776. // Function: GLGraphicsStateGuardian::clear_before_callback
  1777. // Access: Public, Virtual
  1778. // Description: Resets any non-standard graphics state that might
  1779. // give a callback apoplexy. Some drivers require that
  1780. // the graphics state be restored to neutral before
  1781. // performing certain operations. In OpenGL, for
  1782. // instance, this closes any open vertex buffers.
  1783. ////////////////////////////////////////////////////////////////////
  1784. void CLP(GraphicsStateGuardian)::
  1785. clear_before_callback() {
  1786. disable_standard_vertex_arrays();
  1787. unbind_buffers();
  1788. // Some callbacks may quite reasonably assume that the active
  1789. // texture stage is still set to stage 0. CEGUI, in particular,
  1790. // makes this assumption.
  1791. _glActiveTexture(GL_TEXTURE0);
  1792. }
  1793. ////////////////////////////////////////////////////////////////////
  1794. // Function: GLGraphicsStateGuardian::calc_projection_mat
  1795. // Access: Public, Virtual
  1796. // Description: Given a lens, calculates the appropriate projection
  1797. // matrix for use with this gsg. Note that the
  1798. // projection matrix depends a lot upon the coordinate
  1799. // system of the rendering API.
  1800. //
  1801. // The return value is a TransformState if the lens is
  1802. // acceptable, NULL if it is not.
  1803. ////////////////////////////////////////////////////////////////////
  1804. CPT(TransformState) CLP(GraphicsStateGuardian)::
  1805. calc_projection_mat(const Lens *lens) {
  1806. if (lens == (Lens *)NULL) {
  1807. return NULL;
  1808. }
  1809. if (!lens->is_linear()) {
  1810. return NULL;
  1811. }
  1812. // The projection matrix must always be right-handed Y-up, even if
  1813. // our coordinate system of choice is otherwise, because certain GL
  1814. // calls (specifically glTexGen(GL_SPHERE_MAP)) assume this kind of
  1815. // a coordinate system. Sigh. In order to implement a Z-up (or
  1816. // other arbitrary) coordinate system, we'll use a Y-up projection
  1817. // matrix, and store the conversion to our coordinate system of
  1818. // choice in the modelview matrix.
  1819. LMatrix4 result =
  1820. LMatrix4::convert_mat(CS_yup_right, lens->get_coordinate_system()) *
  1821. lens->get_projection_mat(_current_stereo_channel);
  1822. if (_scene_setup->get_inverted()) {
  1823. // If the scene is supposed to be inverted, then invert the
  1824. // projection matrix.
  1825. result *= LMatrix4::scale_mat(1.0f, -1.0f, 1.0f);
  1826. }
  1827. return TransformState::make_mat(result);
  1828. }
  1829. ////////////////////////////////////////////////////////////////////
  1830. // Function: GLGraphicsStateGuardian::prepare_lens
  1831. // Access: Public, Virtual
  1832. // Description: Makes the current lens (whichever lens was most
  1833. // recently specified with set_scene()) active, so
  1834. // that it will transform future rendered geometry.
  1835. // Normally this is only called from the draw process,
  1836. // and usually it is called by set_scene().
  1837. //
  1838. // The return value is true if the lens is acceptable,
  1839. // false if it is not.
  1840. ////////////////////////////////////////////////////////////////////
  1841. bool CLP(GraphicsStateGuardian)::
  1842. prepare_lens() {
  1843. if (GLCAT.is_spam()) {
  1844. GLCAT.spam()
  1845. << "glMatrixMode(GL_PROJECTION): " << _projection_mat->get_mat() << endl;
  1846. }
  1847. #ifndef OPENGLES_2
  1848. GLP(MatrixMode)(GL_PROJECTION);
  1849. GLPf(LoadMatrix)(_projection_mat->get_mat().get_data());
  1850. #endif
  1851. report_my_gl_errors();
  1852. do_point_size();
  1853. return true;
  1854. }
  1855. ////////////////////////////////////////////////////////////////////
  1856. // Function: GraphicsStateGuardian::begin_frame
  1857. // Access: Public, Virtual
  1858. // Description: Called before each frame is rendered, to allow the
  1859. // GSG a chance to do any internal cleanup before
  1860. // beginning the frame.
  1861. //
  1862. // The return value is true if successful (in which case
  1863. // the frame will be drawn and end_frame() will be
  1864. // called later), or false if unsuccessful (in which
  1865. // case nothing will be drawn and end_frame() will not
  1866. // be called).
  1867. ////////////////////////////////////////////////////////////////////
  1868. bool CLP(GraphicsStateGuardian)::
  1869. begin_frame(Thread *current_thread) {
  1870. if (!GraphicsStateGuardian::begin_frame(current_thread)) {
  1871. return false;
  1872. }
  1873. report_my_gl_errors();
  1874. #ifdef DO_PSTATS
  1875. _vertices_display_list_pcollector.clear_level();
  1876. _vertices_immediate_pcollector.clear_level();
  1877. _primitive_batches_display_list_pcollector.clear_level();
  1878. #endif
  1879. #ifndef NDEBUG
  1880. _show_texture_usage = false;
  1881. if (CLP(show_texture_usage)) {
  1882. // When this is true, then every other second, we show the usage
  1883. // textures instead of the real textures.
  1884. double now = ClockObject::get_global_clock()->get_frame_time();
  1885. int this_second = (int)floor(now);
  1886. if (this_second & 1) {
  1887. _show_texture_usage = true;
  1888. _show_texture_usage_index = this_second >> 1;
  1889. int max_size = CLP(show_texture_usage_max_size);
  1890. if (max_size != _show_texture_usage_max_size) {
  1891. // Remove the cache of usage textures; we've changed the max
  1892. // size.
  1893. UsageTextures::iterator ui;
  1894. for (ui = _usage_textures.begin();
  1895. ui != _usage_textures.end();
  1896. ++ui) {
  1897. GLuint index = (*ui).second;
  1898. GLP(DeleteTextures)(1, &index);
  1899. }
  1900. _usage_textures.clear();
  1901. _show_texture_usage_max_size = max_size;
  1902. }
  1903. }
  1904. }
  1905. #endif // NDEBUG
  1906. report_my_gl_errors();
  1907. return true;
  1908. }
  1909. ////////////////////////////////////////////////////////////////////
  1910. // Function: GraphicsStateGuardian::begin_scene
  1911. // Access: Public, Virtual
  1912. // Description: Called between begin_frame() and end_frame() to mark
  1913. // the beginning of drawing commands for a "scene"
  1914. // (usually a particular DisplayRegion) within a frame.
  1915. // All 3-D drawing commands, except the clear operation,
  1916. // must be enclosed within begin_scene() .. end_scene().
  1917. //
  1918. // The return value is true if successful (in which case
  1919. // the scene will be drawn and end_scene() will be
  1920. // called later), or false if unsuccessful (in which
  1921. // case nothing will be drawn and end_scene() will not
  1922. // be called).
  1923. ////////////////////////////////////////////////////////////////////
  1924. bool CLP(GraphicsStateGuardian)::
  1925. begin_scene() {
  1926. return GraphicsStateGuardian::begin_scene();
  1927. }
  1928. ////////////////////////////////////////////////////////////////////
  1929. // Function: GLGraphicsStateGuardian::end_scene
  1930. // Access: Protected, Virtual
  1931. // Description: Called between begin_frame() and end_frame() to mark
  1932. // the end of drawing commands for a "scene" (usually a
  1933. // particular DisplayRegion) within a frame. All 3-D
  1934. // drawing commands, except the clear operation, must be
  1935. // enclosed within begin_scene() .. end_scene().
  1936. ////////////////////////////////////////////////////////////////////
  1937. void CLP(GraphicsStateGuardian)::
  1938. end_scene() {
  1939. GraphicsStateGuardian::end_scene();
  1940. #ifndef OPENGLES_1
  1941. if (_vertex_array_shader_context != 0) {
  1942. _vertex_array_shader_context->disable_shader_vertex_arrays(this);
  1943. _vertex_array_shader = (Shader *)NULL;
  1944. _vertex_array_shader_context = (CLP(ShaderContext) *)NULL;
  1945. }
  1946. if (_texture_binding_shader_context != 0) {
  1947. _texture_binding_shader_context->disable_shader_texture_bindings(this);
  1948. _texture_binding_shader = (Shader *)NULL;
  1949. _texture_binding_shader_context = (CLP(ShaderContext) *)NULL;
  1950. }
  1951. if (_current_shader_context != 0) {
  1952. _current_shader_context->unbind(this);
  1953. _current_shader = (Shader *)NULL;
  1954. _current_shader_context = (CLP(ShaderContext) *)NULL;
  1955. }
  1956. #endif
  1957. _dlights.clear();
  1958. report_my_gl_errors();
  1959. }
  1960. ////////////////////////////////////////////////////////////////////
  1961. // Function: GLGraphicsStateGuardian::end_frame
  1962. // Access: Public, Virtual
  1963. // Description: Called after each frame is rendered, to allow the
  1964. // GSG a chance to do any internal cleanup after
  1965. // rendering the frame, and before the window flips.
  1966. ////////////////////////////////////////////////////////////////////
  1967. void CLP(GraphicsStateGuardian)::
  1968. end_frame(Thread *current_thread) {
  1969. report_my_gl_errors();
  1970. #ifdef DO_PSTATS
  1971. // Check for textures, etc., that are no longer resident. These
  1972. // calls might be measurably expensive, and they don't have any
  1973. // benefit unless we are actually viewing PStats, so don't do them
  1974. // unless we're connected. That will just mean that we'll count
  1975. // everything as resident until the user connects PStats, at which
  1976. // point it will then correct the assessment. No harm done.
  1977. if (PStatClient::is_connected()) {
  1978. check_nonresident_texture(_prepared_objects->_texture_residency.get_inactive_resident());
  1979. check_nonresident_texture(_prepared_objects->_texture_residency.get_active_resident());
  1980. // OpenGL provides no methods for querying whether a buffer object
  1981. // (vertex buffer) is resident. In fact, the API appears geared
  1982. // towards the assumption that such buffers are always resident.
  1983. // OK.
  1984. }
  1985. #endif
  1986. GraphicsStateGuardian::end_frame(current_thread);
  1987. // Flush any PCollectors specific to this kind of GSG.
  1988. _primitive_batches_display_list_pcollector.flush_level();
  1989. _vertices_display_list_pcollector.flush_level();
  1990. _vertices_immediate_pcollector.flush_level();
  1991. // Now is a good time to delete any pending display lists.
  1992. #ifndef OPENGLES
  1993. {
  1994. LightMutexHolder holder(_lock);
  1995. if (!_deleted_display_lists.empty()) {
  1996. DeletedDisplayLists::iterator ddli;
  1997. for (ddli = _deleted_display_lists.begin();
  1998. ddli != _deleted_display_lists.end();
  1999. ++ddli) {
  2000. if (GLCAT.is_debug()) {
  2001. GLCAT.debug()
  2002. << "releasing display list index " << (int)(*ddli) << "\n";
  2003. }
  2004. GLP(DeleteLists)((*ddli), 1);
  2005. }
  2006. _deleted_display_lists.clear();
  2007. }
  2008. // And deleted occlusion queries, too.
  2009. if (!_deleted_queries.empty()) {
  2010. DeletedDisplayLists::iterator ddli;
  2011. for (ddli = _deleted_queries.begin();
  2012. ddli != _deleted_queries.end();
  2013. ++ddli) {
  2014. if (GLCAT.is_debug()) {
  2015. GLCAT.debug()
  2016. << "releasing query index " << (int)(*ddli) << "\n";
  2017. }
  2018. _glDeleteQueries(1, &(*ddli));
  2019. }
  2020. _deleted_queries.clear();
  2021. }
  2022. }
  2023. #endif // OPENGLES
  2024. // Calling glFlush() at the end of the frame is particularly
  2025. // necessary if this is a single-buffered visual, so that the frame
  2026. // will be finished drawing before we return to the application.
  2027. // It's not clear what effect this has on our total frame time.
  2028. if (_allow_flush) {
  2029. gl_flush();
  2030. }
  2031. maybe_gl_finish();
  2032. report_my_gl_errors();
  2033. }
  2034. ////////////////////////////////////////////////////////////////////
  2035. // Function: GLGraphicsStateGuardian::begin_draw_primitives
  2036. // Access: Public, Virtual
  2037. // Description: Called before a sequence of draw_primitive()
  2038. // functions are called, this should prepare the vertex
  2039. // data for rendering. It returns true if the vertices
  2040. // are ok, false to abort this group of primitives.
  2041. ////////////////////////////////////////////////////////////////////
  2042. bool CLP(GraphicsStateGuardian)::
  2043. begin_draw_primitives(const GeomPipelineReader *geom_reader,
  2044. const GeomMunger *munger,
  2045. const GeomVertexDataPipelineReader *data_reader,
  2046. bool force) {
  2047. #ifndef NDEBUG
  2048. if (GLCAT.is_spam()) {
  2049. GLCAT.spam() << "begin_draw_primitives: " << *(data_reader->get_object()) << "\n";
  2050. }
  2051. #endif // NDEBUG
  2052. if (!GraphicsStateGuardian::begin_draw_primitives(geom_reader, munger, data_reader, force)) {
  2053. return false;
  2054. }
  2055. nassertr(_data_reader != (GeomVertexDataPipelineReader *)NULL, false);
  2056. _geom_display_list = 0;
  2057. if (_auto_antialias_mode) {
  2058. switch (geom_reader->get_primitive_type()) {
  2059. case GeomPrimitive::PT_polygons:
  2060. case GeomPrimitive::PT_patches:
  2061. setup_antialias_polygon();
  2062. break;
  2063. case GeomPrimitive::PT_points:
  2064. setup_antialias_point();
  2065. break;
  2066. case GeomPrimitive::PT_lines:
  2067. setup_antialias_line();
  2068. break;
  2069. case GeomPrimitive::PT_none:
  2070. break;
  2071. }
  2072. int transparency_slot = TransparencyAttrib::get_class_slot();
  2073. int color_write_slot = ColorWriteAttrib::get_class_slot();
  2074. int color_blend_slot = ColorBlendAttrib::get_class_slot();
  2075. if (!_state_mask.get_bit(transparency_slot) ||
  2076. !_state_mask.get_bit(color_write_slot) ||
  2077. !_state_mask.get_bit(color_blend_slot)) {
  2078. do_issue_blending();
  2079. _state_mask.set_bit(transparency_slot);
  2080. _state_mask.set_bit(color_write_slot);
  2081. _state_mask.set_bit(color_blend_slot);
  2082. }
  2083. }
  2084. const GeomVertexAnimationSpec &animation =
  2085. _data_reader->get_format()->get_animation();
  2086. bool hardware_animation = (animation.get_animation_type() == Geom::AT_hardware);
  2087. #ifndef OPENGLES
  2088. if (hardware_animation) {
  2089. // Set up the transform matrices for vertex blending.
  2090. nassertr(_supports_vertex_blend, false);
  2091. GLP(Enable)(GL_VERTEX_BLEND_ARB);
  2092. _glVertexBlend(animation.get_num_transforms());
  2093. const TransformTable *table = _data_reader->get_transform_table();
  2094. if (table != (TransformTable *)NULL) {
  2095. if (animation.get_indexed_transforms()) {
  2096. nassertr(_supports_matrix_palette, false);
  2097. // We are loading the indexed matrix palette. The ARB decided
  2098. // to change this interface from that for the list of
  2099. // nonindexed matrices, to make it easier to load an arbitrary
  2100. // number of matrices.
  2101. GLP(Enable)(GL_MATRIX_PALETTE_ARB);
  2102. GLP(MatrixMode)(GL_MATRIX_PALETTE_ARB);
  2103. for (int i = 0; i < table->get_num_transforms(); ++i) {
  2104. LMatrix4 mat;
  2105. table->get_transform(i)->mult_matrix(mat, _internal_transform->get_mat());
  2106. _glCurrentPaletteMatrix(i);
  2107. GLPf(LoadMatrix)(mat.get_data());
  2108. }
  2109. // Presumably loading the matrix palette does not step on the
  2110. // GL_MODELVIEW matrix?
  2111. } else {
  2112. // We are loading the list of nonindexed matrices. This is a
  2113. // little clumsier.
  2114. if (_supports_matrix_palette) {
  2115. GLP(Disable)(GL_MATRIX_PALETTE_ARB);
  2116. }
  2117. // GL_MODELVIEW0 and 1 are different than the rest.
  2118. int i = 0;
  2119. if (i < table->get_num_transforms()) {
  2120. LMatrix4 mat;
  2121. table->get_transform(i)->mult_matrix(mat, _internal_transform->get_mat());
  2122. GLP(MatrixMode)(GL_MODELVIEW0_ARB);
  2123. GLPf(LoadMatrix)(mat.get_data());
  2124. ++i;
  2125. }
  2126. if (i < table->get_num_transforms()) {
  2127. LMatrix4 mat;
  2128. table->get_transform(i)->mult_matrix(mat, _internal_transform->get_mat());
  2129. GLP(MatrixMode)(GL_MODELVIEW1_ARB);
  2130. GLPf(LoadMatrix)(mat.get_data());
  2131. ++i;
  2132. }
  2133. while (i < table->get_num_transforms()) {
  2134. LMatrix4 mat;
  2135. table->get_transform(i)->mult_matrix(mat, _internal_transform->get_mat());
  2136. GLP(MatrixMode)(GL_MODELVIEW2_ARB + i - 2);
  2137. GLPf(LoadMatrix)(mat.get_data());
  2138. ++i;
  2139. }
  2140. // Setting the GL_MODELVIEW0 matrix steps on the world matrix,
  2141. // so we have to set a flag to reload the world matrix later.
  2142. _transform_stale = true;
  2143. }
  2144. }
  2145. _vertex_blending_enabled = true;
  2146. } else {
  2147. // We're not using vertex blending.
  2148. if (_vertex_blending_enabled) {
  2149. GLP(Disable)(GL_VERTEX_BLEND_ARB);
  2150. if (_supports_matrix_palette) {
  2151. GLP(Disable)(GL_MATRIX_PALETTE_ARB);
  2152. }
  2153. _vertex_blending_enabled = false;
  2154. }
  2155. if (_transform_stale) {
  2156. GLP(MatrixMode)(GL_MODELVIEW);
  2157. GLPf(LoadMatrix)(_internal_transform->get_mat().get_data());
  2158. }
  2159. }
  2160. #endif
  2161. #ifndef OPENGLES_2
  2162. if (_data_reader->is_vertex_transformed()) {
  2163. // If the vertex data claims to be already transformed into clip
  2164. // coordinates, wipe out the current projection and modelview
  2165. // matrix (so we don't attempt to transform it again).
  2166. GLP(MatrixMode)(GL_PROJECTION);
  2167. GLP(PushMatrix)();
  2168. GLP(LoadIdentity)();
  2169. GLP(MatrixMode)(GL_MODELVIEW);
  2170. GLP(PushMatrix)();
  2171. GLP(LoadIdentity)();
  2172. }
  2173. #endif
  2174. #ifndef OPENGLES // Display lists not supported by OpenGL ES.
  2175. if (geom_reader->get_usage_hint() == Geom::UH_static &&
  2176. _data_reader->get_usage_hint() == Geom::UH_static &&
  2177. display_lists && (!hardware_animation || display_list_animation)) {
  2178. // If the geom claims to be totally static, try to build it into
  2179. // a display list.
  2180. // Before we compile or call a display list, make sure the current
  2181. // buffers are unbound, or the nVidia drivers may crash.
  2182. unbind_buffers();
  2183. GeomContext *gc = ((Geom *)geom_reader->get_object())->prepare_now(get_prepared_objects(), this);
  2184. nassertr(gc != (GeomContext *)NULL, false);
  2185. CLP(GeomContext) *ggc = DCAST(CLP(GeomContext), gc);
  2186. const CLP(GeomMunger) *gmunger = DCAST(CLP(GeomMunger), _munger);
  2187. UpdateSeq modified = max(geom_reader->get_modified(), _data_reader->get_modified());
  2188. if (ggc->get_display_list(_geom_display_list, gmunger, modified)) {
  2189. // If it hasn't been modified, just play the display list again.
  2190. if (GLCAT.is_spam()) {
  2191. GLCAT.spam()
  2192. << "calling display list " << (int)_geom_display_list << "\n";
  2193. }
  2194. GLP(CallList)(_geom_display_list);
  2195. #ifdef DO_PSTATS
  2196. _vertices_display_list_pcollector.add_level(ggc->_num_verts);
  2197. _primitive_batches_display_list_pcollector.add_level(1);
  2198. #endif
  2199. // And now we don't need to do anything else for this geom.
  2200. _geom_display_list = 0;
  2201. end_draw_primitives();
  2202. return false;
  2203. }
  2204. // Since we start this collector explicitly, we have to be sure to
  2205. // stop it again.
  2206. _load_display_list_pcollector.start();
  2207. if (GLCAT.is_debug()) {
  2208. GLCAT.debug()
  2209. << "compiling display list " << (int)_geom_display_list << "\n";
  2210. }
  2211. // If it has been modified, or this is the first time, then we
  2212. // need to build the display list up.
  2213. if (CLP(compile_and_execute)) {
  2214. GLP(NewList)(_geom_display_list, GL_COMPILE_AND_EXECUTE);
  2215. } else {
  2216. GLP(NewList)(_geom_display_list, GL_COMPILE);
  2217. }
  2218. #ifdef DO_PSTATS
  2219. // Count up the number of vertices used by primitives in the Geom,
  2220. // for PStats reporting.
  2221. ggc->_num_verts = 0;
  2222. for (int i = 0; i < geom_reader->get_num_primitives(); i++) {
  2223. ggc->_num_verts += geom_reader->get_primitive(i)->get_num_vertices();
  2224. }
  2225. #endif
  2226. }
  2227. #endif // OPENGLES
  2228. // Enable the appropriate vertex arrays, and disable any
  2229. // extra vertex arrays used by the previous rendering mode.
  2230. #ifdef SUPPORT_IMMEDIATE_MODE
  2231. _use_sender = !vertex_arrays;
  2232. // This is a workaround for a bug in Mesa 6 vertex array handling.
  2233. if ((_supports_mesa_6) && (_current_properties->get_force_software())) {
  2234. _use_sender = true;
  2235. }
  2236. #endif
  2237. #ifdef OPENGLES_1
  2238. if (!update_standard_vertex_arrays(force)) {
  2239. return false;
  2240. }
  2241. #else
  2242. if (_current_shader_context == 0) {
  2243. // No shader.
  2244. if (_vertex_array_shader_context != 0) {
  2245. _vertex_array_shader_context->disable_shader_vertex_arrays(this);
  2246. }
  2247. if (!update_standard_vertex_arrays(force)) {
  2248. return false;
  2249. }
  2250. } else {
  2251. // Shader.
  2252. if (_vertex_array_shader_context == 0 || _vertex_array_shader_context->uses_standard_vertex_arrays()) {
  2253. // Previous shader used standard arrays.
  2254. if (_current_shader_context->uses_standard_vertex_arrays()) {
  2255. // So does the current, so update them.
  2256. if (!update_standard_vertex_arrays(force)) {
  2257. return false;
  2258. }
  2259. } else {
  2260. // The current shader does not, so disable them entirely.
  2261. disable_standard_vertex_arrays();
  2262. }
  2263. }
  2264. if (_current_shader_context->uses_custom_vertex_arrays()) {
  2265. // The current shader also uses custom vertex arrays.
  2266. if (!_current_shader_context->
  2267. update_shader_vertex_arrays(_vertex_array_shader_context, this, force)) {
  2268. return false;
  2269. }
  2270. } else {
  2271. _vertex_array_shader_context->disable_shader_vertex_arrays(this);
  2272. }
  2273. }
  2274. _vertex_array_shader = _current_shader;
  2275. _vertex_array_shader_context = _current_shader_context;
  2276. #endif // OPENGLES_1
  2277. report_my_gl_errors();
  2278. return true;
  2279. }
  2280. ////////////////////////////////////////////////////////////////////
  2281. // Function: GLGraphicsStateGuardian::update_standard_vertex_arrays
  2282. // Access: Protected
  2283. // Description: Disables any unneeded vertex arrays that
  2284. // were previously enabled, and enables any vertex
  2285. // arrays that are needed that were not previously
  2286. // enabled (or, sets up an immediate-mode sender).
  2287. // Called only from begin_draw_primitives.
  2288. // Used only when the standard (non-shader) pipeline
  2289. // is about to be used - glShaderContexts are responsible
  2290. // for setting up their own vertex arrays.
  2291. ////////////////////////////////////////////////////////////////////
  2292. bool CLP(GraphicsStateGuardian)::
  2293. update_standard_vertex_arrays(bool force) {
  2294. #ifndef OPENGLES_2
  2295. const GeomVertexAnimationSpec &animation =
  2296. _data_reader->get_format()->get_animation();
  2297. bool hardware_animation = (animation.get_animation_type() == Geom::AT_hardware);
  2298. #ifdef SUPPORT_IMMEDIATE_MODE
  2299. if (_use_sender) {
  2300. // We must use immediate mode to render primitives.
  2301. _sender.clear();
  2302. _sender.add_column(_data_reader, InternalName::get_normal(),
  2303. NULL, NULL, GLPf(Normal3), NULL);
  2304. #ifndef NDEBUG
  2305. if (_show_texture_usage) {
  2306. // In show_texture_usage mode, all colors are white, so as not
  2307. // to contaminate the texture color.
  2308. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  2309. } else
  2310. #endif // NDEBUG
  2311. if (!_sender.add_column(_data_reader, InternalName::get_color(),
  2312. NULL, NULL, GLPf(Color3), GLPf(Color4))) {
  2313. // If we didn't have a color column, the item color is white.
  2314. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  2315. }
  2316. // Now set up each of the active texture coordinate stages--or at
  2317. // least those for which we're not generating texture coordinates
  2318. // automatically.
  2319. int max_stage_index = _target_texture->get_num_on_ff_stages();
  2320. int stage_index = 0;
  2321. while (stage_index < max_stage_index) {
  2322. TextureStage *stage = _target_texture->get_on_ff_stage(stage_index);
  2323. if (!_target_tex_gen->has_gen_texcoord_stage(stage)) {
  2324. // This stage is not one of the stages that doesn't need
  2325. // texcoords issued for it.
  2326. const InternalName *name = stage->get_texcoord_name();
  2327. if (stage_index == 0) {
  2328. // Use the original functions for stage 0, in case we don't
  2329. // support multitexture.
  2330. _sender.add_column(_data_reader, name,
  2331. GLPf(TexCoord1), GLPf(TexCoord2),
  2332. GLPf(TexCoord3), GLPf(TexCoord4));
  2333. } else {
  2334. // Other stages require the multitexture functions.
  2335. _sender.add_texcoord_column(_data_reader, name, stage_index,
  2336. GLf(_glMultiTexCoord1), GLf(_glMultiTexCoord2),
  2337. GLf(_glMultiTexCoord3), GLf(_glMultiTexCoord4));
  2338. }
  2339. }
  2340. ++stage_index;
  2341. }
  2342. // Be sure also to disable any texture stages we had enabled before.
  2343. while (stage_index < _last_max_stage_index) {
  2344. _glClientActiveTexture(GL_TEXTURE0 + stage_index);
  2345. GLP(DisableClientState)(GL_TEXTURE_COORD_ARRAY);
  2346. ++stage_index;
  2347. }
  2348. _last_max_stage_index = max_stage_index;
  2349. if (_supports_vertex_blend) {
  2350. if (hardware_animation) {
  2351. // Issue the weights and/or transform indices for vertex blending.
  2352. _sender.add_vector_column(_data_reader, InternalName::get_transform_weight(),
  2353. GLfv(_glWeight));
  2354. if (animation.get_indexed_transforms()) {
  2355. // Issue the matrix palette indices.
  2356. _sender.add_vector_uint_column(_data_reader, InternalName::get_transform_index(),
  2357. _glMatrixIndexuiv);
  2358. }
  2359. }
  2360. }
  2361. // We must add vertex last, because glVertex3f() is the key
  2362. // function call that actually issues the vertex.
  2363. _sender.add_column(_data_reader, InternalName::get_vertex(),
  2364. NULL, GLPf(Vertex2), GLPf(Vertex3), GLPf(Vertex4));
  2365. } else
  2366. #endif // SUPPORT_IMMEDIATE_MODE
  2367. {
  2368. // We may use vertex arrays or buffers to render primitives.
  2369. const GeomVertexArrayDataHandle *array_reader;
  2370. const unsigned char *client_pointer;
  2371. int num_values;
  2372. Geom::NumericType numeric_type;
  2373. int start;
  2374. int stride;
  2375. if (_data_reader->get_normal_info(array_reader, numeric_type,
  2376. start, stride)) {
  2377. if (!setup_array_data(client_pointer, array_reader, force)) {
  2378. return false;
  2379. }
  2380. GLP(NormalPointer)(get_numeric_type(numeric_type), stride,
  2381. client_pointer + start);
  2382. GLP(EnableClientState)(GL_NORMAL_ARRAY);
  2383. } else {
  2384. GLP(DisableClientState)(GL_NORMAL_ARRAY);
  2385. }
  2386. #ifndef NDEBUG
  2387. if (_show_texture_usage) {
  2388. // In show_texture_usage mode, all colors are white, so as not
  2389. // to contaminate the texture color.
  2390. GLP(DisableClientState)(GL_COLOR_ARRAY);
  2391. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  2392. } else
  2393. #endif // NDEBUG
  2394. if (_data_reader->get_color_info(array_reader, num_values, numeric_type,
  2395. start, stride) &&
  2396. numeric_type != Geom::NT_packed_dabc) {
  2397. if (!setup_array_data(client_pointer, array_reader, force)) {
  2398. return false;
  2399. }
  2400. GLP(ColorPointer)(num_values, get_numeric_type(numeric_type),
  2401. stride, client_pointer + start);
  2402. GLP(EnableClientState)(GL_COLOR_ARRAY);
  2403. } else {
  2404. GLP(DisableClientState)(GL_COLOR_ARRAY);
  2405. // Since we don't have per-vertex color, the implicit color is
  2406. // white.
  2407. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  2408. }
  2409. // Now set up each of the active texture coordinate stages--or at
  2410. // least those for which we're not generating texture coordinates
  2411. // automatically.
  2412. int max_stage_index = _target_texture->get_num_on_ff_stages();
  2413. int stage_index = 0;
  2414. while (stage_index < max_stage_index) {
  2415. _glClientActiveTexture(GL_TEXTURE0 + stage_index);
  2416. TextureStage *stage = _target_texture->get_on_ff_stage(stage_index);
  2417. if (!_target_tex_gen->has_gen_texcoord_stage(stage)) {
  2418. // This stage is not one of the stages that doesn't need
  2419. // texcoords issued for it.
  2420. const InternalName *name = stage->get_texcoord_name();
  2421. if (_data_reader->get_array_info(name, array_reader, num_values,
  2422. numeric_type, start, stride)) {
  2423. // The vertex data does have texcoords for this stage.
  2424. if (!setup_array_data(client_pointer, array_reader, force)) {
  2425. return false;
  2426. }
  2427. GLP(TexCoordPointer)(num_values, get_numeric_type(numeric_type),
  2428. stride, client_pointer + start);
  2429. GLP(EnableClientState)(GL_TEXTURE_COORD_ARRAY);
  2430. } else {
  2431. // The vertex data doesn't have texcoords for this stage (even
  2432. // though they're needed).
  2433. GLP(DisableClientState)(GL_TEXTURE_COORD_ARRAY);
  2434. }
  2435. } else {
  2436. // No texcoords are needed for this stage.
  2437. GLP(DisableClientState)(GL_TEXTURE_COORD_ARRAY);
  2438. }
  2439. ++stage_index;
  2440. }
  2441. // Be sure also to disable any texture stages we had enabled before.
  2442. while (stage_index < _last_max_stage_index) {
  2443. _glClientActiveTexture(GL_TEXTURE0 + stage_index);
  2444. GLP(DisableClientState)(GL_TEXTURE_COORD_ARRAY);
  2445. ++stage_index;
  2446. }
  2447. _last_max_stage_index = max_stage_index;
  2448. #ifndef OPENGLES
  2449. if (_supports_vertex_blend) {
  2450. if (hardware_animation) {
  2451. // Issue the weights and/or transform indices for vertex blending.
  2452. if (_data_reader->get_array_info(InternalName::get_transform_weight(),
  2453. array_reader, num_values, numeric_type,
  2454. start, stride)) {
  2455. if (!setup_array_data(client_pointer, array_reader, force)) {
  2456. return false;
  2457. }
  2458. _glWeightPointer(num_values, get_numeric_type(numeric_type),
  2459. stride, client_pointer + start);
  2460. GLP(EnableClientState)(GL_WEIGHT_ARRAY_ARB);
  2461. } else {
  2462. GLP(DisableClientState)(GL_WEIGHT_ARRAY_ARB);
  2463. }
  2464. if (animation.get_indexed_transforms()) {
  2465. // Issue the matrix palette indices.
  2466. if (_data_reader->get_array_info(InternalName::get_transform_index(),
  2467. array_reader, num_values, numeric_type,
  2468. start, stride)) {
  2469. if (!setup_array_data(client_pointer, array_reader, force)) {
  2470. return false;
  2471. }
  2472. _glMatrixIndexPointer(num_values, get_numeric_type(numeric_type),
  2473. stride, client_pointer + start);
  2474. GLP(EnableClientState)(GL_MATRIX_INDEX_ARRAY_ARB);
  2475. } else {
  2476. GLP(DisableClientState)(GL_MATRIX_INDEX_ARRAY_ARB);
  2477. }
  2478. }
  2479. } else {
  2480. GLP(DisableClientState)(GL_WEIGHT_ARRAY_ARB);
  2481. if (_supports_matrix_palette) {
  2482. GLP(DisableClientState)(GL_MATRIX_INDEX_ARRAY_ARB);
  2483. }
  2484. }
  2485. }
  2486. #endif
  2487. // There's no requirement that we add vertices last, but we do
  2488. // anyway.
  2489. if (_data_reader->get_vertex_info(array_reader, num_values, numeric_type,
  2490. start, stride)) {
  2491. if (!setup_array_data(client_pointer, array_reader, force)) {
  2492. return false;
  2493. }
  2494. GLP(VertexPointer)(num_values, get_numeric_type(numeric_type),
  2495. stride, client_pointer + start);
  2496. GLP(EnableClientState)(GL_VERTEX_ARRAY);
  2497. }
  2498. }
  2499. #endif // OPENGLES_2
  2500. return true;
  2501. }
  2502. ////////////////////////////////////////////////////////////////////
  2503. // Function: GLGraphicsStateGuardian::unbind_buffers
  2504. // Access: Protected
  2505. // Description: Ensures the vertex and array buffers are no longer
  2506. // bound. Some graphics drivers crash if these are left
  2507. // bound indiscriminantly.
  2508. ////////////////////////////////////////////////////////////////////
  2509. void CLP(GraphicsStateGuardian)::
  2510. unbind_buffers() {
  2511. if (_current_vbuffer_index != 0) {
  2512. if (GLCAT.is_spam() && CLP(debug_buffers)) {
  2513. GLCAT.spam()
  2514. << "unbinding vertex buffer\n";
  2515. }
  2516. _glBindBuffer(GL_ARRAY_BUFFER, 0);
  2517. _current_vbuffer_index = 0;
  2518. }
  2519. if (_current_ibuffer_index != 0) {
  2520. if (GLCAT.is_spam() && CLP(debug_buffers)) {
  2521. GLCAT.spam()
  2522. << "unbinding index buffer\n";
  2523. }
  2524. _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  2525. _current_ibuffer_index = 0;
  2526. }
  2527. disable_standard_vertex_arrays();
  2528. }
  2529. ////////////////////////////////////////////////////////////////////
  2530. // Function: GLGraphicsStateGuardian::disable_standard_vertex_arrays
  2531. // Access: Protected
  2532. // Description: Used to disable all the standard vertex arrays that
  2533. // are currently enabled. glShaderContexts are
  2534. // responsible for setting up their own vertex arrays,
  2535. // but before they can do so, the standard vertex
  2536. // arrays need to be disabled to get them "out of the
  2537. // way." Called only from begin_draw_primitives.
  2538. ////////////////////////////////////////////////////////////////////
  2539. void CLP(GraphicsStateGuardian)::
  2540. disable_standard_vertex_arrays()
  2541. {
  2542. #ifndef OPENGLES_2
  2543. #ifdef SUPPORT_IMMEDIATE_MODE
  2544. if (_use_sender) return;
  2545. #endif
  2546. GLP(DisableClientState)(GL_NORMAL_ARRAY);
  2547. GLP(DisableClientState)(GL_COLOR_ARRAY);
  2548. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  2549. report_my_gl_errors();
  2550. for (int stage_index=0; stage_index < _last_max_stage_index; stage_index++) {
  2551. _glClientActiveTexture(GL_TEXTURE0 + stage_index);
  2552. GLP(DisableClientState)(GL_TEXTURE_COORD_ARRAY);
  2553. }
  2554. _last_max_stage_index = 0;
  2555. report_my_gl_errors();
  2556. #ifndef OPENGLES
  2557. if (_supports_vertex_blend) {
  2558. GLP(DisableClientState)(GL_WEIGHT_ARRAY_ARB);
  2559. if (_supports_matrix_palette) {
  2560. GLP(DisableClientState)(GL_MATRIX_INDEX_ARRAY_ARB);
  2561. }
  2562. }
  2563. #endif
  2564. GLP(DisableClientState)(GL_VERTEX_ARRAY);
  2565. report_my_gl_errors();
  2566. #endif
  2567. }
  2568. ////////////////////////////////////////////////////////////////////
  2569. // Function: GLGraphicsStateGuardian::draw_triangles
  2570. // Access: Public, Virtual
  2571. // Description: Draws a series of disconnected triangles.
  2572. ////////////////////////////////////////////////////////////////////
  2573. bool CLP(GraphicsStateGuardian)::
  2574. draw_triangles(const GeomPrimitivePipelineReader *reader, bool force) {
  2575. //PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread());
  2576. #ifndef NDEBUG
  2577. if (GLCAT.is_spam()) {
  2578. GLCAT.spam() << "draw_triangles: " << *(reader->get_object()) << "\n";
  2579. }
  2580. #endif // NDEBUG
  2581. #ifdef SUPPORT_IMMEDIATE_MODE
  2582. if (_use_sender) {
  2583. draw_immediate_simple_primitives(reader, GL_TRIANGLES);
  2584. } else
  2585. #endif // SUPPORT_IMMEDIATE_MODE
  2586. {
  2587. int num_vertices = reader->get_num_vertices();
  2588. _vertices_tri_pcollector.add_level(num_vertices);
  2589. _primitive_batches_tri_pcollector.add_level(1);
  2590. if (reader->is_indexed()) {
  2591. const unsigned char *client_pointer;
  2592. if (!setup_primitive(client_pointer, reader, force)) {
  2593. return false;
  2594. }
  2595. #ifndef OPENGLES
  2596. if (_supports_geometry_instancing && _instance_count > 0) {
  2597. _glDrawElementsInstanced(GL_TRIANGLES, num_vertices,
  2598. get_numeric_type(reader->get_index_type()),
  2599. client_pointer, _instance_count);
  2600. } else
  2601. #endif
  2602. {
  2603. _glDrawRangeElements(GL_TRIANGLES,
  2604. reader->get_min_vertex(),
  2605. reader->get_max_vertex(),
  2606. num_vertices,
  2607. get_numeric_type(reader->get_index_type()),
  2608. client_pointer);
  2609. }
  2610. } else {
  2611. #ifndef OPENGLES
  2612. if (_supports_geometry_instancing && _instance_count > 0) {
  2613. _glDrawArraysInstanced(GL_TRIANGLES,
  2614. reader->get_first_vertex(),
  2615. num_vertices, _instance_count);
  2616. } else
  2617. #endif
  2618. {
  2619. GLP(DrawArrays)(GL_TRIANGLES,
  2620. reader->get_first_vertex(),
  2621. num_vertices);
  2622. }
  2623. }
  2624. }
  2625. report_my_gl_errors();
  2626. return true;
  2627. }
  2628. ////////////////////////////////////////////////////////////////////
  2629. // Function: GLGraphicsStateGuardian::draw_tristrips
  2630. // Access: Public, Virtual
  2631. // Description: Draws a series of triangle strips.
  2632. ////////////////////////////////////////////////////////////////////
  2633. bool CLP(GraphicsStateGuardian)::
  2634. draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force) {
  2635. //PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread());
  2636. report_my_gl_errors();
  2637. #ifndef NDEBUG
  2638. if (GLCAT.is_spam()) {
  2639. GLCAT.spam() << "draw_tristrips: " << *(reader->get_object()) << "\n";
  2640. }
  2641. #endif // NDEBUG
  2642. #ifdef SUPPORT_IMMEDIATE_MODE
  2643. if (_use_sender) {
  2644. draw_immediate_composite_primitives(reader, GL_TRIANGLE_STRIP);
  2645. } else
  2646. #endif // SUPPORT_IMMEDIATE_MODE
  2647. {
  2648. if (connect_triangle_strips && _render_mode != RenderModeAttrib::M_wireframe) {
  2649. // One long triangle strip, connected by the degenerate vertices
  2650. // that have already been set up within the primitive.
  2651. int num_vertices = reader->get_num_vertices();
  2652. _vertices_tristrip_pcollector.add_level(num_vertices);
  2653. _primitive_batches_tristrip_pcollector.add_level(1);
  2654. if (reader->is_indexed()) {
  2655. const unsigned char *client_pointer;
  2656. if (!setup_primitive(client_pointer, reader, force)) {
  2657. return false;
  2658. }
  2659. #ifndef OPENGLES
  2660. if (_supports_geometry_instancing && _instance_count > 0) {
  2661. _glDrawElementsInstanced(GL_TRIANGLE_STRIP, num_vertices,
  2662. get_numeric_type(reader->get_index_type()),
  2663. client_pointer, _instance_count);
  2664. } else
  2665. #endif
  2666. {
  2667. _glDrawRangeElements(GL_TRIANGLE_STRIP,
  2668. reader->get_min_vertex(),
  2669. reader->get_max_vertex(),
  2670. num_vertices,
  2671. get_numeric_type(reader->get_index_type()),
  2672. client_pointer);
  2673. }
  2674. } else {
  2675. #ifndef OPENGLES
  2676. if (_supports_geometry_instancing && _instance_count > 0) {
  2677. _glDrawArraysInstanced(GL_TRIANGLE_STRIP,
  2678. reader->get_first_vertex(),
  2679. num_vertices, _instance_count);
  2680. } else
  2681. #endif
  2682. {
  2683. GLP(DrawArrays)(GL_TRIANGLE_STRIP,
  2684. reader->get_first_vertex(),
  2685. num_vertices);
  2686. }
  2687. }
  2688. } else {
  2689. // Send the individual triangle strips, stepping over the
  2690. // degenerate vertices.
  2691. CPTA_int ends = reader->get_ends();
  2692. _primitive_batches_tristrip_pcollector.add_level(ends.size());
  2693. if (reader->is_indexed()) {
  2694. const unsigned char *client_pointer;
  2695. if (!setup_primitive(client_pointer, reader, force)) {
  2696. return false;
  2697. }
  2698. int index_stride = reader->get_index_stride();
  2699. GeomVertexReader mins(reader->get_mins(), 0);
  2700. GeomVertexReader maxs(reader->get_maxs(), 0);
  2701. nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() &&
  2702. reader->get_maxs()->get_num_rows() == (int)ends.size(), false);
  2703. unsigned int start = 0;
  2704. for (size_t i = 0; i < ends.size(); i++) {
  2705. _vertices_tristrip_pcollector.add_level(ends[i] - start);
  2706. #ifndef OPENGLES
  2707. if (_supports_geometry_instancing && _instance_count > 0) {
  2708. _glDrawElementsInstanced(GL_TRIANGLE_STRIP, ends[i] - start,
  2709. get_numeric_type(reader->get_index_type()),
  2710. client_pointer + start * index_stride,
  2711. _instance_count);
  2712. } else
  2713. #endif
  2714. {
  2715. _glDrawRangeElements(GL_TRIANGLE_STRIP,
  2716. mins.get_data1i(), maxs.get_data1i(),
  2717. ends[i] - start,
  2718. get_numeric_type(reader->get_index_type()),
  2719. client_pointer + start * index_stride);
  2720. }
  2721. start = ends[i] + 2;
  2722. }
  2723. } else {
  2724. unsigned int start = 0;
  2725. int first_vertex = reader->get_first_vertex();
  2726. for (size_t i = 0; i < ends.size(); i++) {
  2727. _vertices_tristrip_pcollector.add_level(ends[i] - start);
  2728. #ifndef OPENGLES
  2729. if (_supports_geometry_instancing && _instance_count > 0) {
  2730. _glDrawArraysInstanced(GL_TRIANGLE_STRIP, first_vertex + start,
  2731. ends[i] - start, _instance_count);
  2732. } else
  2733. #endif
  2734. {
  2735. GLP(DrawArrays)(GL_TRIANGLE_STRIP, first_vertex + start,
  2736. ends[i] - start);
  2737. }
  2738. start = ends[i] + 2;
  2739. }
  2740. }
  2741. }
  2742. }
  2743. report_my_gl_errors();
  2744. return true;
  2745. }
  2746. ////////////////////////////////////////////////////////////////////
  2747. // Function: GLGraphicsStateGuardian::draw_trifans
  2748. // Access: Public, Virtual
  2749. // Description: Draws a series of triangle fans.
  2750. ////////////////////////////////////////////////////////////////////
  2751. bool CLP(GraphicsStateGuardian)::
  2752. draw_trifans(const GeomPrimitivePipelineReader *reader, bool force) {
  2753. //PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread());
  2754. #ifndef NDEBUG
  2755. if (GLCAT.is_spam()) {
  2756. GLCAT.spam() << "draw_trifans: " << *(reader->get_object()) << "\n";
  2757. }
  2758. #endif // NDEBUG
  2759. #ifdef SUPPORT_IMMEDIATE_MODE
  2760. if (_use_sender) {
  2761. draw_immediate_composite_primitives(reader, GL_TRIANGLE_FAN);
  2762. } else
  2763. #endif // SUPPORT_IMMEDIATE_MODE
  2764. {
  2765. // Send the individual triangle fans. There's no connecting fans
  2766. // with degenerate vertices, so no worries about that.
  2767. CPTA_int ends = reader->get_ends();
  2768. _primitive_batches_trifan_pcollector.add_level(ends.size());
  2769. if (reader->is_indexed()) {
  2770. const unsigned char *client_pointer;
  2771. if (!setup_primitive(client_pointer, reader, force)) {
  2772. return false;
  2773. }
  2774. int index_stride = reader->get_index_stride();
  2775. GeomVertexReader mins(reader->get_mins(), 0);
  2776. GeomVertexReader maxs(reader->get_maxs(), 0);
  2777. nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() &&
  2778. reader->get_maxs()->get_num_rows() == (int)ends.size(), false);
  2779. unsigned int start = 0;
  2780. for (size_t i = 0; i < ends.size(); i++) {
  2781. _vertices_trifan_pcollector.add_level(ends[i] - start);
  2782. #ifndef OPENGLES
  2783. if (_supports_geometry_instancing && _instance_count > 0) {
  2784. _glDrawElementsInstanced(GL_TRIANGLE_FAN, ends[i] - start,
  2785. get_numeric_type(reader->get_index_type()),
  2786. client_pointer + start * index_stride,
  2787. _instance_count);
  2788. } else
  2789. #endif
  2790. {
  2791. _glDrawRangeElements(GL_TRIANGLE_FAN,
  2792. mins.get_data1i(), maxs.get_data1i(), ends[i] - start,
  2793. get_numeric_type(reader->get_index_type()),
  2794. client_pointer + start * index_stride);
  2795. }
  2796. start = ends[i];
  2797. }
  2798. } else {
  2799. unsigned int start = 0;
  2800. int first_vertex = reader->get_first_vertex();
  2801. for (size_t i = 0; i < ends.size(); i++) {
  2802. _vertices_trifan_pcollector.add_level(ends[i] - start);
  2803. #ifndef OPENGLES
  2804. if (_supports_geometry_instancing && _instance_count > 0) {
  2805. _glDrawArraysInstanced(GL_TRIANGLE_FAN, first_vertex + start,
  2806. ends[i] - start, _instance_count);
  2807. } else
  2808. #endif
  2809. {
  2810. GLP(DrawArrays)(GL_TRIANGLE_FAN, first_vertex + start,
  2811. ends[i] - start);
  2812. }
  2813. start = ends[i];
  2814. }
  2815. }
  2816. }
  2817. report_my_gl_errors();
  2818. return true;
  2819. }
  2820. ////////////////////////////////////////////////////////////////////
  2821. // Function: GLGraphicsStateGuardian::draw_patches
  2822. // Access: Public, Virtual
  2823. // Description: Draws a series of "patches", which can only be
  2824. // processed by a tessellation shader.
  2825. ////////////////////////////////////////////////////////////////////
  2826. bool CLP(GraphicsStateGuardian)::
  2827. draw_patches(const GeomPrimitivePipelineReader *reader, bool force) {
  2828. //PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread());
  2829. #ifndef NDEBUG
  2830. if (GLCAT.is_spam()) {
  2831. GLCAT.spam() << "draw_patches: " << *(reader->get_object()) << "\n";
  2832. }
  2833. #endif // NDEBUG
  2834. if (!get_supports_tessellation_shaders()) {
  2835. return false;
  2836. }
  2837. #ifndef OPENGLES
  2838. _glPatchParameteri(GL_PATCH_VERTICES, reader->get_object()->get_num_vertices_per_primitive());
  2839. #ifdef SUPPORT_IMMEDIATE_MODE
  2840. if (_use_sender) {
  2841. draw_immediate_simple_primitives(reader, GL_PATCHES);
  2842. } else
  2843. #endif // SUPPORT_IMMEDIATE_MODE
  2844. {
  2845. int num_vertices = reader->get_num_vertices();
  2846. _vertices_patch_pcollector.add_level(num_vertices);
  2847. _primitive_batches_patch_pcollector.add_level(1);
  2848. if (reader->is_indexed()) {
  2849. const unsigned char *client_pointer;
  2850. if (!setup_primitive(client_pointer, reader, force)) {
  2851. return false;
  2852. }
  2853. #ifndef OPENGLES
  2854. if (_supports_geometry_instancing && _instance_count > 0) {
  2855. _glDrawElementsInstanced(GL_PATCHES, num_vertices,
  2856. get_numeric_type(reader->get_index_type()),
  2857. client_pointer, _instance_count);
  2858. } else
  2859. #endif
  2860. {
  2861. _glDrawRangeElements(GL_PATCHES,
  2862. reader->get_min_vertex(),
  2863. reader->get_max_vertex(),
  2864. num_vertices,
  2865. get_numeric_type(reader->get_index_type()),
  2866. client_pointer);
  2867. }
  2868. } else {
  2869. #ifndef OPENGLES
  2870. if (_supports_geometry_instancing && _instance_count > 0) {
  2871. _glDrawArraysInstanced(GL_PATCHES,
  2872. reader->get_first_vertex(),
  2873. num_vertices, _instance_count);
  2874. } else
  2875. #endif
  2876. {
  2877. GLP(DrawArrays)(GL_PATCHES,
  2878. reader->get_first_vertex(),
  2879. num_vertices);
  2880. }
  2881. }
  2882. }
  2883. #endif // OPENGLES
  2884. report_my_gl_errors();
  2885. return true;
  2886. }
  2887. ////////////////////////////////////////////////////////////////////
  2888. // Function: GLGraphicsStateGuardian::draw_lines
  2889. // Access: Public, Virtual
  2890. // Description: Draws a series of disconnected line segments.
  2891. ////////////////////////////////////////////////////////////////////
  2892. bool CLP(GraphicsStateGuardian)::
  2893. draw_lines(const GeomPrimitivePipelineReader *reader, bool force) {
  2894. //PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread());
  2895. #ifndef NDEBUG
  2896. if (GLCAT.is_spam()) {
  2897. GLCAT.spam() << "draw_lines: " << *(reader->get_object()) << "\n";
  2898. }
  2899. #endif // NDEBUG
  2900. #ifdef SUPPORT_IMMEDIATE_MODE
  2901. if (_use_sender) {
  2902. draw_immediate_simple_primitives(reader, GL_LINES);
  2903. } else
  2904. #endif // SUPPORT_IMMEDIATE_MODE
  2905. {
  2906. int num_vertices = reader->get_num_vertices();
  2907. _vertices_other_pcollector.add_level(num_vertices);
  2908. _primitive_batches_other_pcollector.add_level(1);
  2909. if (reader->is_indexed()) {
  2910. const unsigned char *client_pointer;
  2911. if (!setup_primitive(client_pointer, reader, force)) {
  2912. return false;
  2913. }
  2914. #ifndef OPENGLES
  2915. if (_supports_geometry_instancing && _instance_count > 0) {
  2916. _glDrawElementsInstanced(GL_LINES, num_vertices,
  2917. get_numeric_type(reader->get_index_type()),
  2918. client_pointer, _instance_count);
  2919. } else
  2920. #endif
  2921. {
  2922. _glDrawRangeElements(GL_LINES,
  2923. reader->get_min_vertex(),
  2924. reader->get_max_vertex(),
  2925. num_vertices,
  2926. get_numeric_type(reader->get_index_type()),
  2927. client_pointer);
  2928. }
  2929. } else {
  2930. #ifndef OPENGLES
  2931. if (_supports_geometry_instancing && _instance_count > 0) {
  2932. _glDrawArraysInstanced(GL_LINES,
  2933. reader->get_first_vertex(),
  2934. num_vertices, _instance_count);
  2935. } else
  2936. #endif
  2937. {
  2938. GLP(DrawArrays)(GL_LINES,
  2939. reader->get_first_vertex(),
  2940. num_vertices);
  2941. }
  2942. }
  2943. }
  2944. report_my_gl_errors();
  2945. return true;
  2946. }
  2947. ////////////////////////////////////////////////////////////////////
  2948. // Function: GLGraphicsStateGuardian::draw_linestrips
  2949. // Access: Public, Virtual
  2950. // Description: Draws a series of line strips.
  2951. ////////////////////////////////////////////////////////////////////
  2952. bool CLP(GraphicsStateGuardian)::
  2953. draw_linestrips(const GeomPrimitivePipelineReader *reader, bool force) {
  2954. return false;
  2955. }
  2956. ////////////////////////////////////////////////////////////////////
  2957. // Function: GLGraphicsStateGuardian::draw_points
  2958. // Access: Public, Virtual
  2959. // Description: Draws a series of disconnected points.
  2960. ////////////////////////////////////////////////////////////////////
  2961. bool CLP(GraphicsStateGuardian)::
  2962. draw_points(const GeomPrimitivePipelineReader *reader, bool force) {
  2963. //PStatTimer timer(_draw_primitive_pcollector, reader->get_current_thread());
  2964. #ifndef NDEBUG
  2965. if (GLCAT.is_spam()) {
  2966. GLCAT.spam() << "draw_points: " << *(reader->get_object()) << "\n";
  2967. }
  2968. #endif // NDEBUG
  2969. #ifdef SUPPORT_IMMEDIATE_MODE
  2970. if (_use_sender) {
  2971. draw_immediate_simple_primitives(reader, GL_POINTS);
  2972. } else
  2973. #endif // SUPPORT_IMMEDIATE_MODE
  2974. {
  2975. int num_vertices = reader->get_num_vertices();
  2976. _vertices_other_pcollector.add_level(num_vertices);
  2977. _primitive_batches_other_pcollector.add_level(1);
  2978. if (reader->is_indexed()) {
  2979. const unsigned char *client_pointer;
  2980. if (!setup_primitive(client_pointer, reader, force)) {
  2981. return false;
  2982. }
  2983. #ifndef OPENGLES
  2984. if (_supports_geometry_instancing && _instance_count > 0) {
  2985. _glDrawElementsInstanced(GL_POINTS, num_vertices,
  2986. get_numeric_type(reader->get_index_type()),
  2987. client_pointer, _instance_count);
  2988. } else
  2989. #endif
  2990. {
  2991. _glDrawRangeElements(GL_POINTS,
  2992. reader->get_min_vertex(),
  2993. reader->get_max_vertex(),
  2994. num_vertices,
  2995. get_numeric_type(reader->get_index_type()),
  2996. client_pointer);
  2997. }
  2998. } else {
  2999. #ifndef OPENGLES
  3000. if (_supports_geometry_instancing && _instance_count > 0) {
  3001. _glDrawArraysInstanced(GL_POINTS,
  3002. reader->get_first_vertex(),
  3003. num_vertices, _instance_count);
  3004. } else
  3005. #endif
  3006. {
  3007. GLP(DrawArrays)(GL_POINTS,
  3008. reader->get_first_vertex(),
  3009. num_vertices);
  3010. }
  3011. }
  3012. }
  3013. report_my_gl_errors();
  3014. return true;
  3015. }
  3016. ////////////////////////////////////////////////////////////////////
  3017. // Function: GLGraphicsStateGuardian::end_draw_primitives()
  3018. // Access: Public, Virtual
  3019. // Description: Called after a sequence of draw_primitive()
  3020. // functions are called, this should do whatever cleanup
  3021. // is appropriate.
  3022. ////////////////////////////////////////////////////////////////////
  3023. void CLP(GraphicsStateGuardian)::
  3024. end_draw_primitives() {
  3025. #ifndef OPENGLES // Display lists not supported by OpenGL ES.
  3026. if (_geom_display_list != 0) {
  3027. // If we were building a display list, close it now.
  3028. GLP(EndList)();
  3029. _load_display_list_pcollector.stop();
  3030. if (!CLP(compile_and_execute)) {
  3031. GLP(CallList)(_geom_display_list);
  3032. }
  3033. _primitive_batches_display_list_pcollector.add_level(1);
  3034. }
  3035. _geom_display_list = 0;
  3036. // Clean up the vertex blending state.
  3037. if (_vertex_blending_enabled) {
  3038. GLP(Disable)(GL_VERTEX_BLEND_ARB);
  3039. if (_supports_matrix_palette) {
  3040. GLP(Disable)(GL_MATRIX_PALETTE_ARB);
  3041. }
  3042. _vertex_blending_enabled = false;
  3043. }
  3044. #endif
  3045. #ifndef OPENGLES_2
  3046. if (_transform_stale) {
  3047. GLP(MatrixMode)(GL_MODELVIEW);
  3048. GLPf(LoadMatrix)(_internal_transform->get_mat().get_data());
  3049. }
  3050. if (_data_reader->is_vertex_transformed()) {
  3051. // Restore the matrices that we pushed above.
  3052. GLP(MatrixMode)(GL_PROJECTION);
  3053. GLP(PopMatrix)();
  3054. GLP(MatrixMode)(GL_MODELVIEW);
  3055. GLP(PopMatrix)();
  3056. }
  3057. #endif
  3058. GraphicsStateGuardian::end_draw_primitives();
  3059. maybe_gl_finish();
  3060. report_my_gl_errors();
  3061. }
  3062. ////////////////////////////////////////////////////////////////////
  3063. // Function: GLGraphicsStateGuardian::prepare_texture
  3064. // Access: Public, Virtual
  3065. // Description: Creates whatever structures the GSG requires to
  3066. // represent the texture internally, and returns a
  3067. // newly-allocated TextureContext object with this data.
  3068. // It is the responsibility of the calling function to
  3069. // later call release_texture() with this same pointer
  3070. // (which will also delete the pointer).
  3071. //
  3072. // This function should not be called directly to
  3073. // prepare a texture. Instead, call Texture::prepare().
  3074. ////////////////////////////////////////////////////////////////////
  3075. TextureContext *CLP(GraphicsStateGuardian)::
  3076. prepare_texture(Texture *tex, int view) {
  3077. report_my_gl_errors();
  3078. // Make sure we'll support this texture when it's rendered. Don't
  3079. // bother to prepare it if we won't.
  3080. switch (tex->get_texture_type()) {
  3081. case Texture::TT_3d_texture:
  3082. if (!_supports_3d_texture) {
  3083. GLCAT.warning()
  3084. << "3-D textures are not supported by this OpenGL driver.\n";
  3085. return NULL;
  3086. }
  3087. break;
  3088. case Texture::TT_2d_texture_array:
  3089. if (!_supports_2d_texture_array) {
  3090. GLCAT.warning()
  3091. << "2-D texture arrays are not supported by this OpenGL driver.\n";
  3092. return NULL;
  3093. }
  3094. break;
  3095. case Texture::TT_cube_map:
  3096. if (!_supports_cube_map) {
  3097. GLCAT.warning()
  3098. << "Cube map textures are not supported by this OpenGL driver.\n";
  3099. return NULL;
  3100. }
  3101. default:
  3102. break;
  3103. }
  3104. CLP(TextureContext) *gtc = new CLP(TextureContext)(_prepared_objects, tex, view);
  3105. GLP(GenTextures)(1, &gtc->_index);
  3106. report_my_gl_errors();
  3107. apply_texture(gtc);
  3108. return gtc;
  3109. }
  3110. ////////////////////////////////////////////////////////////////////
  3111. // Function: GLGraphicsStateGuardian::update_texture
  3112. // Access: Public, Virtual
  3113. // Description: Ensures that the current Texture data is refreshed
  3114. // onto the GSG. This means updating the texture
  3115. // properties and/or re-uploading the texture image, if
  3116. // necessary. This should only be called within the
  3117. // draw thread.
  3118. //
  3119. // If force is true, this function will not return until
  3120. // the texture has been fully uploaded. If force is
  3121. // false, the function may choose to upload a simple
  3122. // version of the texture instead, if the texture is not
  3123. // fully resident (and if get_incomplete_render() is
  3124. // true).
  3125. ////////////////////////////////////////////////////////////////////
  3126. bool CLP(GraphicsStateGuardian)::
  3127. update_texture(TextureContext *tc, bool force) {
  3128. apply_texture(tc);
  3129. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
  3130. if (gtc->was_image_modified()) {
  3131. // If the texture image was modified, reload the texture. This
  3132. // means we also re-specify the properties for good measure.
  3133. specify_texture(gtc);
  3134. bool okflag = upload_texture(gtc, force);
  3135. if (!okflag) {
  3136. GLCAT.error()
  3137. << "Could not load " << *gtc->get_texture() << "\n";
  3138. return false;
  3139. }
  3140. } else if (gtc->was_properties_modified()) {
  3141. // If only the properties have been modified, we don't necessarily
  3142. // need to reload the texture.
  3143. if (specify_texture(gtc)) {
  3144. // Actually, looks like the texture *does* need to be reloaded.
  3145. gtc->mark_needs_reload();
  3146. bool okflag = upload_texture(gtc, force);
  3147. if (!okflag) {
  3148. GLCAT.error()
  3149. << "Could not load " << *gtc->get_texture() << "\n";
  3150. return false;
  3151. }
  3152. } else {
  3153. // The texture didn't need reloading, but mark it fully updated
  3154. // now.
  3155. gtc->mark_loaded();
  3156. }
  3157. }
  3158. gtc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  3159. report_my_gl_errors();
  3160. return true;
  3161. }
  3162. ////////////////////////////////////////////////////////////////////
  3163. // Function: GLGraphicsStateGuardian::release_texture
  3164. // Access: Public, Virtual
  3165. // Description: Frees the GL resources previously allocated for the
  3166. // texture. This function should never be called
  3167. // directly; instead, call Texture::release() (or simply
  3168. // let the Texture destruct).
  3169. ////////////////////////////////////////////////////////////////////
  3170. void CLP(GraphicsStateGuardian)::
  3171. release_texture(TextureContext *tc) {
  3172. report_my_gl_errors();
  3173. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
  3174. GLP(DeleteTextures)(1, &gtc->_index);
  3175. report_my_gl_errors();
  3176. gtc->_index = 0;
  3177. delete gtc;
  3178. }
  3179. ////////////////////////////////////////////////////////////////////
  3180. // Function: GLGraphicsStateGuardian::extract_texture_data
  3181. // Access: Public, Virtual
  3182. // Description: This method should only be called by the
  3183. // GraphicsEngine. Do not call it directly; call
  3184. // GraphicsEngine::extract_texture_data() instead.
  3185. //
  3186. // This method will be called in the draw thread to
  3187. // download the texture memory's image into its
  3188. // ram_image value. It returns true on success, false
  3189. // otherwise.
  3190. ////////////////////////////////////////////////////////////////////
  3191. bool CLP(GraphicsStateGuardian)::
  3192. extract_texture_data(Texture *tex) {
  3193. bool success = true;
  3194. // Make sure the error stack is cleared out before we begin.
  3195. report_my_gl_errors();
  3196. int num_views = tex->get_num_views();
  3197. for (int view = 0; view < num_views; ++view) {
  3198. TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this);
  3199. nassertr(tc != (TextureContext *)NULL, false);
  3200. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
  3201. if (!do_extract_texture_data(gtc)) {
  3202. success = false;
  3203. }
  3204. }
  3205. return success;
  3206. }
  3207. ////////////////////////////////////////////////////////////////////
  3208. // Function: GLGraphicsStateGuardian::prepare_geom
  3209. // Access: Public, Virtual
  3210. // Description: Creates a new retained-mode representation of the
  3211. // given geom, and returns a newly-allocated
  3212. // GeomContext pointer to reference it. It is the
  3213. // responsibility of the calling function to later
  3214. // call release_geom() with this same pointer (which
  3215. // will also delete the pointer).
  3216. //
  3217. // This function should not be called directly to
  3218. // prepare a geom. Instead, call Geom::prepare().
  3219. ////////////////////////////////////////////////////////////////////
  3220. GeomContext *CLP(GraphicsStateGuardian)::
  3221. prepare_geom(Geom *geom) {
  3222. return new CLP(GeomContext)(geom);
  3223. }
  3224. ////////////////////////////////////////////////////////////////////
  3225. // Function: GLGraphicsStateGuardian::release_geom
  3226. // Access: Public, Virtual
  3227. // Description: Frees the GL resources previously allocated for the
  3228. // geom. This function should never be called
  3229. // directly; instead, call Geom::release() (or simply
  3230. // let the Geom destruct).
  3231. ////////////////////////////////////////////////////////////////////
  3232. void CLP(GraphicsStateGuardian)::
  3233. release_geom(GeomContext *gc) {
  3234. CLP(GeomContext) *ggc = DCAST(CLP(GeomContext), gc);
  3235. ggc->release_display_lists();
  3236. report_my_gl_errors();
  3237. delete ggc;
  3238. }
  3239. ////////////////////////////////////////////////////////////////////
  3240. // Function: GLGraphicsStateGuardian::prepare_shader
  3241. // Access: Public, Virtual
  3242. // Description: yadda.
  3243. ////////////////////////////////////////////////////////////////////
  3244. ShaderContext *CLP(GraphicsStateGuardian)::
  3245. prepare_shader(Shader *se) {
  3246. #ifndef OPENGLES_1
  3247. CLP(ShaderContext) *result = new CLP(ShaderContext)(se, this);
  3248. if (result->valid()) return result;
  3249. delete result;
  3250. #endif
  3251. return NULL;
  3252. }
  3253. ////////////////////////////////////////////////////////////////////
  3254. // Function: GLGraphicsStateGuardian::release_shader
  3255. // Access: Public, Virtual
  3256. // Description: yadda.
  3257. ////////////////////////////////////////////////////////////////////
  3258. void CLP(GraphicsStateGuardian)::
  3259. release_shader(ShaderContext *sc) {
  3260. #ifndef OPENGLES_1
  3261. CLP(ShaderContext) *gsc = DCAST(CLP(ShaderContext), sc);
  3262. delete gsc;
  3263. #endif
  3264. }
  3265. ////////////////////////////////////////////////////////////////////
  3266. // Function: GLGraphicsStateGuardian::record_deleted_display_list
  3267. // Access: Public
  3268. // Description: This is intended to be called only from the
  3269. // GLGeomContext destructor. It saves the indicated
  3270. // display list index in the list to be deleted at the
  3271. // end of the frame.
  3272. ////////////////////////////////////////////////////////////////////
  3273. void CLP(GraphicsStateGuardian)::
  3274. record_deleted_display_list(GLuint index) {
  3275. LightMutexHolder holder(_lock);
  3276. _deleted_display_lists.push_back(index);
  3277. }
  3278. ////////////////////////////////////////////////////////////////////
  3279. // Function: GLGraphicsStateGuardian::prepare_vertex_buffer
  3280. // Access: Public, Virtual
  3281. // Description: Creates a new retained-mode representation of the
  3282. // given data, and returns a newly-allocated
  3283. // VertexBufferContext pointer to reference it. It is the
  3284. // responsibility of the calling function to later
  3285. // call release_vertex_buffer() with this same pointer (which
  3286. // will also delete the pointer).
  3287. //
  3288. // This function should not be called directly to
  3289. // prepare a buffer. Instead, call Geom::prepare().
  3290. ////////////////////////////////////////////////////////////////////
  3291. VertexBufferContext *CLP(GraphicsStateGuardian)::
  3292. prepare_vertex_buffer(GeomVertexArrayData *data) {
  3293. if (_supports_buffers) {
  3294. CLP(VertexBufferContext) *gvbc = new CLP(VertexBufferContext)(this, _prepared_objects, data);
  3295. _glGenBuffers(1, &gvbc->_index);
  3296. if (GLCAT.is_debug() && CLP(debug_buffers)) {
  3297. GLCAT.debug()
  3298. << "creating vertex buffer " << (int)gvbc->_index << ": "
  3299. << data->get_num_rows() << " vertices "
  3300. << *data->get_array_format() << "\n";
  3301. }
  3302. report_my_gl_errors();
  3303. apply_vertex_buffer(gvbc, data->get_handle(), false);
  3304. return gvbc;
  3305. }
  3306. return NULL;
  3307. }
  3308. ////////////////////////////////////////////////////////////////////
  3309. // Function: GLGraphicsStateGuardian::apply_vertex_buffer
  3310. // Access: Public
  3311. // Description: Makes the data the currently available data for
  3312. // rendering.
  3313. ////////////////////////////////////////////////////////////////////
  3314. bool CLP(GraphicsStateGuardian)::
  3315. apply_vertex_buffer(VertexBufferContext *vbc,
  3316. const GeomVertexArrayDataHandle *reader, bool force) {
  3317. nassertr(_supports_buffers, false);
  3318. if (reader->get_modified() == UpdateSeq::initial()) {
  3319. // No need to re-apply.
  3320. return true;
  3321. }
  3322. CLP(VertexBufferContext) *gvbc = DCAST(CLP(VertexBufferContext), vbc);
  3323. if (_current_vbuffer_index != gvbc->_index) {
  3324. if (GLCAT.is_spam() && CLP(debug_buffers)) {
  3325. GLCAT.spam()
  3326. << "binding vertex buffer " << (int)gvbc->_index << "\n";
  3327. }
  3328. _glBindBuffer(GL_ARRAY_BUFFER, gvbc->_index);
  3329. _current_vbuffer_index = gvbc->_index;
  3330. gvbc->set_active(true);
  3331. }
  3332. if (gvbc->was_modified(reader)) {
  3333. int num_bytes = reader->get_data_size_bytes();
  3334. if (GLCAT.is_debug() && CLP(debug_buffers)) {
  3335. GLCAT.debug()
  3336. << "copying " << num_bytes
  3337. << " bytes into vertex buffer " << (int)gvbc->_index << "\n";
  3338. }
  3339. if (num_bytes != 0) {
  3340. const unsigned char *client_pointer = reader->get_read_pointer(force);
  3341. if (client_pointer == NULL) {
  3342. return false;
  3343. }
  3344. PStatTimer timer(_load_vertex_buffer_pcollector, reader->get_current_thread());
  3345. if (gvbc->changed_size(reader) || gvbc->changed_usage_hint(reader)) {
  3346. _glBufferData(GL_ARRAY_BUFFER, num_bytes, client_pointer,
  3347. get_usage(reader->get_usage_hint()));
  3348. } else {
  3349. _glBufferSubData(GL_ARRAY_BUFFER, 0, num_bytes, client_pointer);
  3350. }
  3351. _data_transferred_pcollector.add_level(num_bytes);
  3352. }
  3353. gvbc->mark_loaded(reader);
  3354. }
  3355. gvbc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  3356. maybe_gl_finish();
  3357. report_my_gl_errors();
  3358. return true;
  3359. }
  3360. ////////////////////////////////////////////////////////////////////
  3361. // Function: GLGraphicsStateGuardian::release_vertex_buffer
  3362. // Access: Public, Virtual
  3363. // Description: Frees the GL resources previously allocated for the
  3364. // data. This function should never be called
  3365. // directly; instead, call Data::release() (or simply
  3366. // let the Data destruct).
  3367. ////////////////////////////////////////////////////////////////////
  3368. void CLP(GraphicsStateGuardian)::
  3369. release_vertex_buffer(VertexBufferContext *vbc) {
  3370. nassertv(_supports_buffers);
  3371. CLP(VertexBufferContext) *gvbc = DCAST(CLP(VertexBufferContext), vbc);
  3372. if (GLCAT.is_debug() && CLP(debug_buffers)) {
  3373. GLCAT.debug()
  3374. << "deleting vertex buffer " << (int)gvbc->_index << "\n";
  3375. }
  3376. // Make sure the buffer is unbound before we delete it. Not
  3377. // strictly necessary according to the OpenGL spec, but it might
  3378. // help out a flaky driver, and we need to keep our internal state
  3379. // consistent anyway.
  3380. if (_current_vbuffer_index == gvbc->_index) {
  3381. if (GLCAT.is_spam() && CLP(debug_buffers)) {
  3382. GLCAT.spam()
  3383. << "unbinding vertex buffer\n";
  3384. }
  3385. _glBindBuffer(GL_ARRAY_BUFFER, 0);
  3386. _current_vbuffer_index = 0;
  3387. }
  3388. _glDeleteBuffers(1, &gvbc->_index);
  3389. report_my_gl_errors();
  3390. gvbc->_index = 0;
  3391. delete gvbc;
  3392. }
  3393. ////////////////////////////////////////////////////////////////////
  3394. // Function: GLGraphicsStateGuardian::setup_array_data
  3395. // Access: Public
  3396. // Description: Internal function to bind a buffer object for the
  3397. // indicated data array, if appropriate, or to unbind a
  3398. // buffer object if it should be rendered from client
  3399. // memory.
  3400. //
  3401. // If the buffer object is bound, this function sets
  3402. // client_pointer to NULL (representing the start of the
  3403. // buffer object in server memory); if the buffer object
  3404. // is not bound, this function sets client_pointer the
  3405. // pointer to the data array in client memory, that is,
  3406. // the data array passed in.
  3407. //
  3408. // If force is not true, the function may return false
  3409. // indicating the data is not currently available.
  3410. ////////////////////////////////////////////////////////////////////
  3411. bool CLP(GraphicsStateGuardian)::
  3412. setup_array_data(const unsigned char *&client_pointer,
  3413. const GeomVertexArrayDataHandle *array_reader,
  3414. bool force) {
  3415. if (!_supports_buffers) {
  3416. // No support for buffer objects; always render from client.
  3417. client_pointer = array_reader->get_read_pointer(force);
  3418. return (client_pointer != NULL);
  3419. }
  3420. if (!vertex_buffers || _geom_display_list != 0 ||
  3421. array_reader->get_usage_hint() < CLP(min_buffer_usage_hint)) {
  3422. // The array specifies client rendering only, or buffer objects
  3423. // are configured off.
  3424. if (_current_vbuffer_index != 0) {
  3425. if (GLCAT.is_spam() && CLP(debug_buffers)) {
  3426. GLCAT.spam()
  3427. << "unbinding vertex buffer\n";
  3428. }
  3429. _glBindBuffer(GL_ARRAY_BUFFER, 0);
  3430. _current_vbuffer_index = 0;
  3431. }
  3432. client_pointer = array_reader->get_read_pointer(force);
  3433. return (client_pointer != NULL);
  3434. }
  3435. // Prepare the buffer object and bind it.
  3436. VertexBufferContext *vbc = ((GeomVertexArrayData *)array_reader->get_object())->prepare_now(get_prepared_objects(), this);
  3437. nassertr(vbc != (VertexBufferContext *)NULL, false);
  3438. if (!apply_vertex_buffer(vbc, array_reader, force)) {
  3439. return false;
  3440. }
  3441. // NULL is the OpenGL convention for the first byte of the buffer object.
  3442. client_pointer = NULL;
  3443. return true;
  3444. }
  3445. ////////////////////////////////////////////////////////////////////
  3446. // Function: GLGraphicsStateGuardian::prepare_index_buffer
  3447. // Access: Public, Virtual
  3448. // Description: Creates a new retained-mode representation of the
  3449. // given data, and returns a newly-allocated
  3450. // IndexBufferContext pointer to reference it. It is the
  3451. // responsibility of the calling function to later
  3452. // call release_index_buffer() with this same pointer (which
  3453. // will also delete the pointer).
  3454. //
  3455. // This function should not be called directly to
  3456. // prepare a buffer. Instead, call Geom::prepare().
  3457. ////////////////////////////////////////////////////////////////////
  3458. IndexBufferContext *CLP(GraphicsStateGuardian)::
  3459. prepare_index_buffer(GeomPrimitive *data) {
  3460. if (_supports_buffers) {
  3461. CLP(IndexBufferContext) *gibc = new CLP(IndexBufferContext)(this, _prepared_objects, data);
  3462. _glGenBuffers(1, &gibc->_index);
  3463. if (GLCAT.is_debug() && CLP(debug_buffers)) {
  3464. GLCAT.debug()
  3465. << "creating index buffer " << (int)gibc->_index << ": "
  3466. << data->get_num_vertices() << " indices ("
  3467. << data->get_vertices()->get_array_format()->get_column(0)->get_numeric_type()
  3468. << ")\n";
  3469. }
  3470. report_my_gl_errors();
  3471. GeomPrimitivePipelineReader reader(data, Thread::get_current_thread());
  3472. apply_index_buffer(gibc, &reader, false);
  3473. return gibc;
  3474. }
  3475. return NULL;
  3476. }
  3477. ////////////////////////////////////////////////////////////////////
  3478. // Function: GLGraphicsStateGuardian::apply_index_buffer
  3479. // Access: Public
  3480. // Description: Makes the data the currently available data for
  3481. // rendering.
  3482. ////////////////////////////////////////////////////////////////////
  3483. bool CLP(GraphicsStateGuardian)::
  3484. apply_index_buffer(IndexBufferContext *ibc,
  3485. const GeomPrimitivePipelineReader *reader,
  3486. bool force) {
  3487. nassertr(_supports_buffers, false);
  3488. if (reader->get_modified() == UpdateSeq::initial()) {
  3489. // No need to re-apply.
  3490. return true;
  3491. }
  3492. CLP(IndexBufferContext) *gibc = DCAST(CLP(IndexBufferContext), ibc);
  3493. if (_current_ibuffer_index != gibc->_index) {
  3494. if (GLCAT.is_spam() && CLP(debug_buffers)) {
  3495. GLCAT.spam()
  3496. << "binding index buffer " << (int)gibc->_index << "\n";
  3497. }
  3498. _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gibc->_index);
  3499. _current_ibuffer_index = gibc->_index;
  3500. gibc->set_active(true);
  3501. }
  3502. if (gibc->was_modified(reader)) {
  3503. int num_bytes = reader->get_data_size_bytes();
  3504. if (GLCAT.is_debug() && CLP(debug_buffers)) {
  3505. GLCAT.debug()
  3506. << "copying " << num_bytes
  3507. << " bytes into index buffer " << (int)gibc->_index << "\n";
  3508. }
  3509. if (num_bytes != 0) {
  3510. const unsigned char *client_pointer = reader->get_read_pointer(force);
  3511. if (client_pointer == NULL) {
  3512. return false;
  3513. }
  3514. PStatTimer timer(_load_index_buffer_pcollector, reader->get_current_thread());
  3515. if (gibc->changed_size(reader) || gibc->changed_usage_hint(reader)) {
  3516. _glBufferData(GL_ELEMENT_ARRAY_BUFFER, num_bytes, client_pointer,
  3517. get_usage(reader->get_usage_hint()));
  3518. } else {
  3519. _glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, num_bytes,
  3520. client_pointer);
  3521. }
  3522. _data_transferred_pcollector.add_level(num_bytes);
  3523. }
  3524. gibc->mark_loaded(reader);
  3525. }
  3526. gibc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  3527. maybe_gl_finish();
  3528. report_my_gl_errors();
  3529. return true;
  3530. }
  3531. ////////////////////////////////////////////////////////////////////
  3532. // Function: GLGraphicsStateGuardian::release_index_buffer
  3533. // Access: Public, Virtual
  3534. // Description: Frees the GL resources previously allocated for the
  3535. // data. This function should never be called
  3536. // directly; instead, call Data::release() (or simply
  3537. // let the Data destruct).
  3538. ////////////////////////////////////////////////////////////////////
  3539. void CLP(GraphicsStateGuardian)::
  3540. release_index_buffer(IndexBufferContext *ibc) {
  3541. nassertv(_supports_buffers);
  3542. CLP(IndexBufferContext) *gibc = DCAST(CLP(IndexBufferContext), ibc);
  3543. if (GLCAT.is_debug() && CLP(debug_buffers)) {
  3544. GLCAT.debug()
  3545. << "deleting index buffer " << (int)gibc->_index << "\n";
  3546. }
  3547. // Make sure the buffer is unbound before we delete it. Not
  3548. // strictly necessary according to the OpenGL spec, but it might
  3549. // help out a flaky driver, and we need to keep our internal state
  3550. // consistent anyway.
  3551. if (_current_ibuffer_index == gibc->_index) {
  3552. if (GLCAT.is_spam() && CLP(debug_buffers)) {
  3553. GLCAT.spam()
  3554. << "unbinding index buffer\n";
  3555. }
  3556. _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  3557. _current_ibuffer_index = 0;
  3558. }
  3559. _glDeleteBuffers(1, &gibc->_index);
  3560. report_my_gl_errors();
  3561. gibc->_index = 0;
  3562. delete gibc;
  3563. }
  3564. ////////////////////////////////////////////////////////////////////
  3565. // Function: GLGraphicsStateGuardian::setup_primitive
  3566. // Access: Public
  3567. // Description: Internal function to bind a buffer object for the
  3568. // indicated primitive's index list, if appropriate, or
  3569. // to unbind a buffer object if it should be rendered
  3570. // from client memory.
  3571. //
  3572. // If the buffer object is bound, this function sets
  3573. // client_pointer to NULL (representing the start of the
  3574. // buffer object in server memory); if the buffer object
  3575. // is not bound, this function sets client_pointer to to
  3576. // the data array in client memory, that is, the data
  3577. // array passed in.
  3578. //
  3579. // If force is not true, the function may return false
  3580. // indicating the data is not currently available.
  3581. ////////////////////////////////////////////////////////////////////
  3582. bool CLP(GraphicsStateGuardian)::
  3583. setup_primitive(const unsigned char *&client_pointer,
  3584. const GeomPrimitivePipelineReader *reader,
  3585. bool force) {
  3586. if (!_supports_buffers) {
  3587. // No support for buffer objects; always render from client.
  3588. client_pointer = reader->get_read_pointer(force);
  3589. return (client_pointer != NULL);
  3590. }
  3591. if (!vertex_buffers || _geom_display_list != 0 ||
  3592. reader->get_usage_hint() == Geom::UH_client) {
  3593. // The array specifies client rendering only, or buffer objects
  3594. // are configured off.
  3595. if (_current_ibuffer_index != 0) {
  3596. if (GLCAT.is_spam() && CLP(debug_buffers)) {
  3597. GLCAT.spam()
  3598. << "unbinding index buffer\n";
  3599. }
  3600. _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  3601. _current_ibuffer_index = 0;
  3602. }
  3603. client_pointer = reader->get_read_pointer(force);
  3604. return (client_pointer != NULL);
  3605. }
  3606. // Prepare the buffer object and bind it.
  3607. IndexBufferContext *ibc = ((GeomPrimitive *)reader->get_object())->prepare_now(get_prepared_objects(), this);
  3608. nassertr(ibc != (IndexBufferContext *)NULL, false);
  3609. if (!apply_index_buffer(ibc, reader, force)) {
  3610. return false;
  3611. }
  3612. // NULL is the OpenGL convention for the first byte of the buffer object.
  3613. client_pointer = NULL;
  3614. return true;
  3615. }
  3616. ////////////////////////////////////////////////////////////////////
  3617. // Function: GLGraphicsStateGuardian::begin_occlusion_query
  3618. // Access: Public, Virtual
  3619. // Description: Begins a new occlusion query. After this call, you
  3620. // may call begin_draw_primitives() and
  3621. // draw_triangles()/draw_whatever() repeatedly.
  3622. // Eventually, you should call end_occlusion_query()
  3623. // before the end of the frame; that will return a new
  3624. // OcclusionQueryContext object that will tell you how
  3625. // many pixels represented by the bracketed geometry
  3626. // passed the depth test.
  3627. //
  3628. // It is not valid to call begin_occlusion_query()
  3629. // between another begin_occlusion_query()
  3630. // .. end_occlusion_query() sequence.
  3631. ////////////////////////////////////////////////////////////////////
  3632. void CLP(GraphicsStateGuardian)::
  3633. begin_occlusion_query() {
  3634. #ifdef OPENGLES // Occlusion queries not supported by OpenGL ES.
  3635. nassertv(false);
  3636. #else
  3637. nassertv(_supports_occlusion_query);
  3638. nassertv(_current_occlusion_query == (OcclusionQueryContext *)NULL);
  3639. PT(CLP(OcclusionQueryContext)) query = new CLP(OcclusionQueryContext)(this);
  3640. _glGenQueries(1, &query->_index);
  3641. if (GLCAT.is_debug()) {
  3642. GLCAT.debug()
  3643. << "beginning occlusion query index " << (int)query->_index << "\n";
  3644. }
  3645. _glBeginQuery(GL_SAMPLES_PASSED, query->_index);
  3646. _current_occlusion_query = query;
  3647. report_my_gl_errors();
  3648. #endif // OPENGLES
  3649. }
  3650. ////////////////////////////////////////////////////////////////////
  3651. // Function: GLGraphicsStateGuardian::end_occlusion_query
  3652. // Access: Public, Virtual
  3653. // Description: Ends a previous call to begin_occlusion_query().
  3654. // This call returns the OcclusionQueryContext object
  3655. // that will (eventually) report the number of pixels
  3656. // that passed the depth test between the call to
  3657. // begin_occlusion_query() and end_occlusion_query().
  3658. ////////////////////////////////////////////////////////////////////
  3659. PT(OcclusionQueryContext) CLP(GraphicsStateGuardian)::
  3660. end_occlusion_query() {
  3661. #ifdef OPENGLES // Occlusion queries not supported by OpenGL ES.
  3662. nassertr(false, NULL);
  3663. return NULL;
  3664. #else
  3665. nassertr(_current_occlusion_query != (OcclusionQueryContext *)NULL, NULL);
  3666. PT(OcclusionQueryContext) result = _current_occlusion_query;
  3667. GLuint index = DCAST(CLP(OcclusionQueryContext), result)->_index;
  3668. if (GLCAT.is_debug()) {
  3669. GLCAT.debug()
  3670. << "ending occlusion query index " << (int)index << "\n";
  3671. }
  3672. _current_occlusion_query = NULL;
  3673. _glEndQuery(GL_SAMPLES_PASSED);
  3674. // Temporary hack to try working around an apparent driver bug on
  3675. // iMacs. Occlusion queries sometimes incorrectly report 0 samples,
  3676. // unless we stall the pipe to keep fewer than a certain maximum
  3677. // number of queries pending at once.
  3678. static ConfigVariableInt limit_occlusion_queries("limit-occlusion-queries", 0);
  3679. if (limit_occlusion_queries > 0) {
  3680. if (index > (unsigned int)limit_occlusion_queries) {
  3681. PStatTimer timer(_wait_occlusion_pcollector);
  3682. GLuint result;
  3683. _glGetQueryObjectuiv(index - (unsigned int)limit_occlusion_queries,
  3684. GL_QUERY_RESULT, &result);
  3685. }
  3686. }
  3687. report_my_gl_errors();
  3688. return result;
  3689. #endif // OPENGLES
  3690. }
  3691. ////////////////////////////////////////////////////////////////////
  3692. // Function: GLGraphicsStateGuardian::make_geom_munger
  3693. // Access: Public, Virtual
  3694. // Description: Creates a new GeomMunger object to munge vertices
  3695. // appropriate to this GSG for the indicated state.
  3696. ////////////////////////////////////////////////////////////////////
  3697. PT(GeomMunger) CLP(GraphicsStateGuardian)::
  3698. make_geom_munger(const RenderState *state, Thread *current_thread) {
  3699. PT(CLP(GeomMunger)) munger = new CLP(GeomMunger)(this, state);
  3700. return GeomMunger::register_munger(munger, current_thread);
  3701. }
  3702. ////////////////////////////////////////////////////////////////////
  3703. // Function: GLGraphicsStateGuardian::framebuffer_copy_to_texture
  3704. // Access: Public, Virtual
  3705. // Description: Copy the pixels within the indicated display
  3706. // region from the framebuffer into texture memory.
  3707. //
  3708. // If z > -1, it is the cube map index into which to
  3709. // copy.
  3710. ////////////////////////////////////////////////////////////////////
  3711. bool CLP(GraphicsStateGuardian)::
  3712. framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
  3713. const RenderBuffer &rb) {
  3714. nassertr(tex != NULL && dr != NULL, false);
  3715. set_read_buffer(rb._buffer_type);
  3716. if (CLP(color_mask)) {
  3717. GLP(ColorMask)(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  3718. }
  3719. int xo, yo, w, h;
  3720. dr->get_region_pixels(xo, yo, w, h);
  3721. tex->set_size_padded(w, h);
  3722. if (tex->get_compression() == Texture::CM_default) {
  3723. // Unless the user explicitly turned on texture compression, turn
  3724. // it off for the copy-to-texture case.
  3725. tex->set_compression(Texture::CM_off);
  3726. }
  3727. // Sanity check everything.
  3728. if (z >= 0) {
  3729. if (!_supports_cube_map) {
  3730. return false;
  3731. }
  3732. nassertr(z < 6, false);
  3733. nassertr(tex->get_texture_type() == Texture::TT_cube_map, false);
  3734. if ((w != tex->get_x_size()) ||
  3735. (h != tex->get_y_size()) ||
  3736. (w != h)) {
  3737. return false;
  3738. }
  3739. } else {
  3740. nassertr(tex->get_texture_type() == Texture::TT_2d_texture, false);
  3741. }
  3742. // Match framebuffer format if necessary.
  3743. if (tex->get_match_framebuffer_format()) {
  3744. switch (tex->get_format()) {
  3745. case Texture::F_depth_component:
  3746. case Texture::F_depth_stencil:
  3747. // If the texture is one of these special formats, we don't want
  3748. // to adapt it to the framebuffer's color format.
  3749. break;
  3750. default:
  3751. if (_current_properties->get_alpha_bits()) {
  3752. tex->set_format(Texture::F_rgba);
  3753. } else {
  3754. tex->set_format(Texture::F_rgb);
  3755. }
  3756. }
  3757. }
  3758. int view = dr->get_tex_view_offset();
  3759. TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this);
  3760. nassertr(tc != (TextureContext *)NULL, false);
  3761. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
  3762. apply_texture(gtc);
  3763. bool needs_reload = specify_texture(gtc);
  3764. GLenum target = get_texture_target(tex->get_texture_type());
  3765. GLint internal_format = get_internal_image_format(tex);
  3766. int width = tex->get_x_size();
  3767. int height = tex->get_y_size();
  3768. bool uses_mipmaps = tex->uses_mipmaps() && !CLP(ignore_mipmaps);
  3769. if (uses_mipmaps) {
  3770. #ifndef OPENGLES_2
  3771. if (_supports_generate_mipmap) {
  3772. GLP(TexParameteri)(target, GL_GENERATE_MIPMAP, true);
  3773. } else {
  3774. #endif
  3775. // If we can't auto-generate mipmaps, do without mipmaps.
  3776. GLP(TexParameteri)(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  3777. uses_mipmaps = false;
  3778. #ifndef OPENGLES_2
  3779. }
  3780. #endif
  3781. }
  3782. bool new_image = needs_reload || gtc->was_image_modified();
  3783. if (!gtc->_already_applied ||
  3784. internal_format != gtc->_internal_format ||
  3785. uses_mipmaps != gtc->_uses_mipmaps ||
  3786. width != gtc->_width ||
  3787. height != gtc->_height ||
  3788. 1 != gtc->_depth) {
  3789. // If the texture properties have changed, we need to reload the
  3790. // image.
  3791. new_image = true;
  3792. }
  3793. if (z >= 0) {
  3794. // Copy to a cube map face.
  3795. target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + z;
  3796. // Cube map faces seem to have trouble with CopyTexSubImage, so we
  3797. // always reload the image.
  3798. new_image = true;
  3799. }
  3800. if (new_image) {
  3801. // We have to create a new image.
  3802. // It seems that OpenGL accepts a size higher than the framebuffer,
  3803. // but if we run into trouble we'll have to replace this with
  3804. // something smarter.
  3805. GLP(CopyTexImage2D)(target, 0, internal_format, xo, yo, width, height, 0);
  3806. } else {
  3807. // We can overlay the existing image.
  3808. GLP(CopyTexSubImage2D)(target, 0, 0, 0, xo, yo, w, h);
  3809. }
  3810. gtc->_already_applied = true;
  3811. gtc->_uses_mipmaps = uses_mipmaps;
  3812. gtc->_internal_format = internal_format;
  3813. gtc->_width = width;
  3814. gtc->_height = height;
  3815. gtc->_depth = 1;
  3816. gtc->mark_loaded();
  3817. gtc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  3818. report_my_gl_errors();
  3819. // Force reload of texture state, since we've just monkeyed with it.
  3820. _state_mask.clear_bit(TextureAttrib::get_class_slot());
  3821. return true;
  3822. }
  3823. ////////////////////////////////////////////////////////////////////
  3824. // Function: GLGraphicsStateGuardian::framebuffer_copy_to_ram
  3825. // Access: Public, Virtual
  3826. // Description: Copy the pixels within the indicated display region
  3827. // from the framebuffer into system memory, not texture
  3828. // memory. Returns true on success, false on failure.
  3829. //
  3830. // This completely redefines the ram image of the
  3831. // indicated texture.
  3832. ////////////////////////////////////////////////////////////////////
  3833. bool CLP(GraphicsStateGuardian)::
  3834. framebuffer_copy_to_ram(Texture *tex, int z, const DisplayRegion *dr,
  3835. const RenderBuffer &rb) {
  3836. nassertr(tex != NULL && dr != NULL, false);
  3837. set_read_buffer(rb._buffer_type);
  3838. GLP(PixelStorei)(GL_PACK_ALIGNMENT, 1);
  3839. if (CLP(color_mask)) {
  3840. GLP(ColorMask)(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
  3841. }
  3842. // Bug fix for RE, RE2, and VTX - need to disable texturing in order
  3843. // for GLP(ReadPixels)() to work
  3844. // NOTE: reading the depth buffer is *much* slower than reading the
  3845. // color buffer
  3846. set_state_and_transform(RenderState::make_empty(), _internal_transform);
  3847. int xo, yo, w, h;
  3848. dr->get_region_pixels(xo, yo, w, h);
  3849. Texture::ComponentType component_type = tex->get_component_type();
  3850. bool color_mode = false;
  3851. Texture::Format format = tex->get_format();
  3852. switch (format) {
  3853. case Texture::F_depth_component:
  3854. case Texture::F_depth_stencil:
  3855. if (_current_properties->get_depth_bits() <= 8) {
  3856. component_type = Texture::T_unsigned_byte;
  3857. } else {
  3858. component_type = Texture::T_unsigned_short;
  3859. }
  3860. break;
  3861. default:
  3862. color_mode = true;
  3863. if (_current_properties->get_alpha_bits()) {
  3864. format = Texture::F_rgba;
  3865. } else {
  3866. format = Texture::F_rgb;
  3867. }
  3868. if (_current_properties->get_color_bits() <= 24) {
  3869. component_type = Texture::T_unsigned_byte;
  3870. } else {
  3871. component_type = Texture::T_unsigned_short;
  3872. }
  3873. }
  3874. Texture::TextureType texture_type;
  3875. int z_size;
  3876. if (z >= 0) {
  3877. texture_type = Texture::TT_cube_map;
  3878. z_size = 6;
  3879. } else {
  3880. texture_type = Texture::TT_2d_texture;
  3881. z_size = 1;
  3882. }
  3883. if (tex->get_x_size() != w || tex->get_y_size() != h ||
  3884. tex->get_z_size() != z_size ||
  3885. tex->get_component_type() != component_type ||
  3886. tex->get_format() != format ||
  3887. tex->get_texture_type() != texture_type) {
  3888. // Re-setup the texture; its properties have changed.
  3889. tex->setup_texture(texture_type, w, h, z_size,
  3890. component_type, format);
  3891. }
  3892. GLenum external_format = get_external_image_format(tex);
  3893. if (GLCAT.is_spam()) {
  3894. GLCAT.spam()
  3895. << "glReadPixels(" << xo << ", " << yo << ", " << w << ", " << h << ", ";
  3896. switch (external_format) {
  3897. case GL_DEPTH_COMPONENT:
  3898. GLCAT.spam(false) << "GL_DEPTH_COMPONENT, ";
  3899. break;
  3900. #ifndef OPENGLES_2
  3901. case GL_DEPTH_STENCIL_EXT:
  3902. GLCAT.spam(false) << "GL_DEPTH_STENCIL, ";
  3903. break;
  3904. #endif
  3905. case GL_RGB:
  3906. GLCAT.spam(false) << "GL_RGB, ";
  3907. break;
  3908. case GL_RGBA:
  3909. GLCAT.spam(false) << "GL_RGBA, ";
  3910. break;
  3911. #ifndef OPENGLES
  3912. case GL_BGR:
  3913. GLCAT.spam(false) << "GL_BGR, ";
  3914. break;
  3915. #endif
  3916. #ifndef OPENGLES_2
  3917. case GL_BGRA:
  3918. GLCAT.spam(false) << "GL_BGRA, ";
  3919. break;
  3920. #endif
  3921. default:
  3922. GLCAT.spam(false) << "unknown, ";
  3923. break;
  3924. }
  3925. switch (get_component_type(component_type)) {
  3926. case GL_UNSIGNED_BYTE:
  3927. GLCAT.spam(false) << "GL_UNSIGNED_BYTE";
  3928. break;
  3929. case GL_UNSIGNED_SHORT:
  3930. GLCAT.spam(false) << "GL_UNSIGNED_SHORT";
  3931. break;
  3932. case GL_FLOAT:
  3933. GLCAT.spam(false) << "GL_FLOAT";
  3934. break;
  3935. default:
  3936. GLCAT.spam(false) << "unknown";
  3937. break;
  3938. }
  3939. GLCAT.spam(false)
  3940. << ")" << endl;
  3941. }
  3942. unsigned char *image_ptr = tex->modify_ram_image();
  3943. size_t image_size = tex->get_ram_image_size();
  3944. if (z >= 0) {
  3945. nassertr(z < tex->get_z_size(), false);
  3946. image_size = tex->get_expected_ram_page_size();
  3947. image_ptr += z * image_size;
  3948. }
  3949. GLP(ReadPixels)(xo, yo, w, h,
  3950. external_format, get_component_type(component_type),
  3951. image_ptr);
  3952. // We may have to reverse the byte ordering of the image if GL
  3953. // didn't do it for us.
  3954. if (color_mode && !_supports_bgr) {
  3955. PTA_uchar new_image;
  3956. const unsigned char *result =
  3957. fix_component_ordering(new_image, image_ptr, image_size,
  3958. external_format, tex);
  3959. if (result != image_ptr) {
  3960. memcpy(image_ptr, result, image_size);
  3961. }
  3962. }
  3963. report_my_gl_errors();
  3964. return true;
  3965. }
  3966. ////////////////////////////////////////////////////////////////////
  3967. // Function: GLGraphicsStateGuardian::apply_fog
  3968. // Access: Public, Virtual
  3969. // Description:
  3970. ////////////////////////////////////////////////////////////////////
  3971. void CLP(GraphicsStateGuardian)::
  3972. apply_fog(Fog *fog) {
  3973. #ifndef OPENGLES_2
  3974. Fog::Mode fmode = fog->get_mode();
  3975. GLP(Fogf)(GL_FOG_MODE, get_fog_mode_type(fmode));
  3976. if (fmode == Fog::M_linear) {
  3977. PN_stdfloat onset, opaque;
  3978. fog->get_linear_range(onset, opaque);
  3979. GLP(Fogf)(GL_FOG_START, onset);
  3980. GLP(Fogf)(GL_FOG_END, opaque);
  3981. } else {
  3982. // Exponential fog is always camera-relative.
  3983. GLP(Fogf)(GL_FOG_DENSITY, fog->get_exp_density());
  3984. }
  3985. call_glFogfv(GL_FOG_COLOR, fog->get_color());
  3986. report_my_gl_errors();
  3987. #endif
  3988. }
  3989. ////////////////////////////////////////////////////////////////////
  3990. // Function: GLGraphicsStateGuardian::do_issue_transform
  3991. // Access: Protected
  3992. // Description: Sends the indicated transform matrix to the graphics
  3993. // API to be applied to future vertices.
  3994. //
  3995. // This transform is the internal_transform, already
  3996. // converted into the GSG's internal coordinate system.
  3997. ////////////////////////////////////////////////////////////////////
  3998. void CLP(GraphicsStateGuardian)::
  3999. do_issue_transform() {
  4000. const TransformState *transform = _internal_transform;
  4001. if (GLCAT.is_spam()) {
  4002. GLCAT.spam()
  4003. << "glLoadMatrix(GL_MODELVIEW): " << transform->get_mat() << endl;
  4004. }
  4005. DO_PSTATS_STUFF(_transform_state_pcollector.add_level(1));
  4006. #ifndef OPENGLES_2
  4007. GLP(MatrixMode)(GL_MODELVIEW);
  4008. GLPf(LoadMatrix)(transform->get_mat().get_data());
  4009. #endif
  4010. _transform_stale = false;
  4011. if (_auto_rescale_normal) {
  4012. do_auto_rescale_normal();
  4013. }
  4014. #ifndef OPENGLES_1
  4015. if (_current_shader_context) {
  4016. _current_shader_context->issue_parameters(this, Shader::SSD_transform);
  4017. }
  4018. #endif
  4019. report_my_gl_errors();
  4020. }
  4021. ////////////////////////////////////////////////////////////////////
  4022. // Function: GLGraphicsStateGuardian::do_issue_shade_model
  4023. // Access: Protected
  4024. // Description:
  4025. ////////////////////////////////////////////////////////////////////
  4026. void CLP(GraphicsStateGuardian)::
  4027. do_issue_shade_model() {
  4028. #ifndef OPENGLES_2
  4029. const ShadeModelAttrib *target_shade_model = DCAST(ShadeModelAttrib, _target_rs->get_attrib_def(ShadeModelAttrib::get_class_slot()));
  4030. switch (target_shade_model->get_mode()) {
  4031. case ShadeModelAttrib::M_smooth:
  4032. GLP(ShadeModel)(GL_SMOOTH);
  4033. _flat_shade_model = false;
  4034. break;
  4035. case ShadeModelAttrib::M_flat:
  4036. GLP(ShadeModel)(GL_FLAT);
  4037. _flat_shade_model = true;
  4038. break;
  4039. }
  4040. #endif
  4041. }
  4042. ////////////////////////////////////////////////////////////////////
  4043. // Function: GLGraphicsStateGuardian::do_issue_shader
  4044. // Access: Protected
  4045. // Description:
  4046. ////////////////////////////////////////////////////////////////////
  4047. void CLP(GraphicsStateGuardian)::
  4048. do_issue_shader(bool state_has_changed) {
  4049. #ifndef OPENGLES_1
  4050. CLP(ShaderContext) *context = 0;
  4051. Shader *shader = (Shader *)(_target_shader->get_shader());
  4052. #ifdef OPENGLES_2
  4053. // If we don't have a shader, apply the default shader.
  4054. if (!shader) {
  4055. shader = _default_shader;
  4056. }
  4057. #endif
  4058. if (shader) {
  4059. context = (CLP(ShaderContext) *)(shader->prepare_now(get_prepared_objects(), this));
  4060. }
  4061. #ifdef OPENGLES_2
  4062. // If it failed, try applying the default shader.
  4063. if (shader != _default_shader && (context == 0 || !context->valid())) {
  4064. shader = _default_shader;
  4065. context = (CLP(ShaderContext) *)(shader->prepare_now(get_prepared_objects(), this));
  4066. }
  4067. #endif
  4068. if (context == 0 || (context->valid() == false)) {
  4069. if (_current_shader_context != 0) {
  4070. _current_shader_context->unbind(this);
  4071. _current_shader = 0;
  4072. _current_shader_context = 0;
  4073. }
  4074. } else {
  4075. if (context != _current_shader_context) {
  4076. // Use a completely different shader than before.
  4077. // Unbind old shader, bind the new one.
  4078. if (_current_shader_context != 0) {
  4079. _current_shader_context->unbind(this);
  4080. }
  4081. context->bind(this);
  4082. _current_shader = shader;
  4083. _current_shader_context = context;
  4084. context->issue_parameters(this, Shader::SSD_shaderinputs);
  4085. } else {
  4086. #ifdef OPENGLES_2
  4087. context->bind(this, false);
  4088. #endif
  4089. if (state_has_changed) {
  4090. // Use the same shader as before, but with new input arguments.
  4091. context->issue_parameters(this, Shader::SSD_shaderinputs);
  4092. }
  4093. }
  4094. }
  4095. report_my_gl_errors();
  4096. #endif
  4097. }
  4098. ////////////////////////////////////////////////////////////////////
  4099. // Function: GLGraphicsStateGuardian::do_issue_render_mode
  4100. // Access: Protected
  4101. // Description:
  4102. ////////////////////////////////////////////////////////////////////
  4103. void CLP(GraphicsStateGuardian)::
  4104. do_issue_render_mode() {
  4105. const RenderModeAttrib *target_render_mode = DCAST(RenderModeAttrib, _target_rs->get_attrib_def(RenderModeAttrib::get_class_slot()));
  4106. _render_mode = target_render_mode->get_mode();
  4107. _point_size = target_render_mode->get_thickness();
  4108. _point_perspective = target_render_mode->get_perspective();
  4109. #ifndef OPENGLES // glPolygonMode not supported by OpenGL ES.
  4110. switch (_render_mode) {
  4111. case RenderModeAttrib::M_unchanged:
  4112. case RenderModeAttrib::M_filled:
  4113. case RenderModeAttrib::M_filled_flat:
  4114. GLP(PolygonMode)(GL_FRONT_AND_BACK, GL_FILL);
  4115. break;
  4116. case RenderModeAttrib::M_wireframe:
  4117. GLP(PolygonMode)(GL_FRONT_AND_BACK, GL_LINE);
  4118. break;
  4119. case RenderModeAttrib::M_point:
  4120. GLP(PolygonMode)(GL_FRONT_AND_BACK, GL_POINT);
  4121. break;
  4122. default:
  4123. GLCAT.error()
  4124. << "Unknown render mode " << (int)_render_mode << endl;
  4125. }
  4126. #endif // OPENGLES
  4127. // The thickness affects both the line width and the point size.
  4128. GLP(LineWidth)(_point_size);
  4129. #ifndef OPENGLES_2
  4130. GLP(PointSize)(_point_size);
  4131. #endif
  4132. report_my_gl_errors();
  4133. do_point_size();
  4134. }
  4135. ////////////////////////////////////////////////////////////////////
  4136. // Function: GLGraphicsStateGuardian::do_issue_antialias
  4137. // Access: Protected
  4138. // Description:
  4139. ////////////////////////////////////////////////////////////////////
  4140. void CLP(GraphicsStateGuardian)::
  4141. do_issue_antialias() {
  4142. const AntialiasAttrib *target_antialias = DCAST(AntialiasAttrib, _target_rs->get_attrib_def(AntialiasAttrib::get_class_slot()));
  4143. if (target_antialias->get_mode_type() == AntialiasAttrib::M_auto) {
  4144. // In this special mode, we must enable antialiasing on a
  4145. // case-by-case basis, because we enable it differently for
  4146. // polygons and for points and lines.
  4147. _auto_antialias_mode = true;
  4148. } else {
  4149. // Otherwise, explicitly enable or disable according to the bits
  4150. // that are set. But if multisample is requested and supported,
  4151. // don't use the other bits at all (they will be ignored by GL
  4152. // anyway).
  4153. _auto_antialias_mode = false;
  4154. unsigned short mode = target_antialias->get_mode();
  4155. if (_supports_multisample &&
  4156. (mode & AntialiasAttrib::M_multisample) != 0) {
  4157. enable_multisample_antialias(true);
  4158. } else {
  4159. enable_multisample_antialias(false);
  4160. enable_line_smooth((mode & AntialiasAttrib::M_line) != 0);
  4161. enable_point_smooth((mode & AntialiasAttrib::M_point) != 0);
  4162. enable_polygon_smooth((mode & AntialiasAttrib::M_polygon) != 0);
  4163. }
  4164. }
  4165. #ifndef OPENGLES_2
  4166. switch (target_antialias->get_mode_quality()) {
  4167. case AntialiasAttrib::M_faster:
  4168. GLP(Hint)(GL_LINE_SMOOTH_HINT, GL_FASTEST);
  4169. GLP(Hint)(GL_POINT_SMOOTH_HINT, GL_FASTEST);
  4170. #ifndef OPENGLES
  4171. GLP(Hint)(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
  4172. #endif // OPENGLES
  4173. break;
  4174. case AntialiasAttrib::M_better:
  4175. GLP(Hint)(GL_LINE_SMOOTH_HINT, GL_NICEST);
  4176. GLP(Hint)(GL_POINT_SMOOTH_HINT, GL_NICEST);
  4177. #ifndef OPENGLES
  4178. GLP(Hint)(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
  4179. #endif // OPENGLES
  4180. break;
  4181. default:
  4182. GLP(Hint)(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
  4183. GLP(Hint)(GL_POINT_SMOOTH_HINT, GL_DONT_CARE);
  4184. #ifndef OPENGLES
  4185. GLP(Hint)(GL_POLYGON_SMOOTH_HINT, GL_DONT_CARE);
  4186. #endif // OPENGLES
  4187. break;
  4188. }
  4189. #endif
  4190. report_my_gl_errors();
  4191. }
  4192. ////////////////////////////////////////////////////////////////////
  4193. // Function: GLGraphicsStateGuardian::do_issue_rescale_normal
  4194. // Access: Protected
  4195. // Description:
  4196. ////////////////////////////////////////////////////////////////////
  4197. void CLP(GraphicsStateGuardian)::
  4198. do_issue_rescale_normal() {
  4199. const RescaleNormalAttrib *target_rescale_normal = DCAST(RescaleNormalAttrib, _target_rs->get_attrib_def(RescaleNormalAttrib::get_class_slot()));
  4200. RescaleNormalAttrib::Mode mode = target_rescale_normal->get_mode();
  4201. _auto_rescale_normal = false;
  4202. switch (mode) {
  4203. #ifndef OPENGLES_2 // OpenGL ES 2.0 doesn't support rescaling normals.
  4204. case RescaleNormalAttrib::M_none:
  4205. GLP(Disable)(GL_NORMALIZE);
  4206. if (_supports_rescale_normal && support_rescale_normal) {
  4207. GLP(Disable)(GL_RESCALE_NORMAL);
  4208. }
  4209. break;
  4210. case RescaleNormalAttrib::M_rescale:
  4211. if (_supports_rescale_normal && support_rescale_normal) {
  4212. GLP(Enable)(GL_RESCALE_NORMAL);
  4213. GLP(Disable)(GL_NORMALIZE);
  4214. } else {
  4215. GLP(Enable)(GL_NORMALIZE);
  4216. }
  4217. break;
  4218. case RescaleNormalAttrib::M_normalize:
  4219. GLP(Enable)(GL_NORMALIZE);
  4220. if (_supports_rescale_normal && support_rescale_normal) {
  4221. GLP(Disable)(GL_RESCALE_NORMAL);
  4222. }
  4223. break;
  4224. #endif
  4225. case RescaleNormalAttrib::M_auto:
  4226. _auto_rescale_normal = true;
  4227. do_auto_rescale_normal();
  4228. break;
  4229. default:
  4230. GLCAT.error()
  4231. << "Unknown rescale_normal mode " << (int)mode << endl;
  4232. }
  4233. report_my_gl_errors();
  4234. }
  4235. // PandaCompareFunc - 1 + 0x200 === GL_NEVER, etc. order is sequential
  4236. #define PANDA_TO_GL_COMPAREFUNC(PANDACMPFUNC) (PANDACMPFUNC-1 +0x200)
  4237. ////////////////////////////////////////////////////////////////////
  4238. // Function: GLGraphicsStateGuardian::do_issue_depth_test
  4239. // Access: Protected
  4240. // Description:
  4241. ////////////////////////////////////////////////////////////////////
  4242. void CLP(GraphicsStateGuardian)::
  4243. do_issue_depth_test() {
  4244. const DepthTestAttrib *target_depth_test = DCAST(DepthTestAttrib, _target_rs->get_attrib_def(DepthTestAttrib::get_class_slot()));
  4245. DepthTestAttrib::PandaCompareFunc mode = target_depth_test->get_mode();
  4246. if (mode == DepthTestAttrib::M_none) {
  4247. enable_depth_test(false);
  4248. } else {
  4249. enable_depth_test(true);
  4250. GLP(DepthFunc)(PANDA_TO_GL_COMPAREFUNC(mode));
  4251. }
  4252. report_my_gl_errors();
  4253. }
  4254. ////////////////////////////////////////////////////////////////////
  4255. // Function: GLGraphicsStateGuardian::do_issue_alpha_test
  4256. // Access: Protected
  4257. // Description:
  4258. ////////////////////////////////////////////////////////////////////
  4259. void CLP(GraphicsStateGuardian)::
  4260. do_issue_alpha_test() {
  4261. if (_target_shader->get_flag(ShaderAttrib::F_subsume_alpha_test)) {
  4262. enable_alpha_test(false);
  4263. } else {
  4264. const AlphaTestAttrib *target_alpha_test = DCAST(AlphaTestAttrib, _target_rs->get_attrib_def(AlphaTestAttrib::get_class_slot()));
  4265. AlphaTestAttrib::PandaCompareFunc mode = target_alpha_test->get_mode();
  4266. if (mode == AlphaTestAttrib::M_none) {
  4267. enable_alpha_test(false);
  4268. } else {
  4269. nassertv(GL_NEVER == (AlphaTestAttrib::M_never-1+0x200));
  4270. #ifndef OPENGLES_2
  4271. GLP(AlphaFunc)(PANDA_TO_GL_COMPAREFUNC(mode), target_alpha_test->get_reference_alpha());
  4272. #endif
  4273. enable_alpha_test(true);
  4274. }
  4275. }
  4276. }
  4277. ////////////////////////////////////////////////////////////////////
  4278. // Function: GLGraphicsStateGuardian::do_issue_depth_write
  4279. // Access: Protected
  4280. // Description:
  4281. ////////////////////////////////////////////////////////////////////
  4282. void CLP(GraphicsStateGuardian)::
  4283. do_issue_depth_write() {
  4284. const DepthWriteAttrib *target_depth_write = DCAST(DepthWriteAttrib, _target_rs->get_attrib_def(DepthWriteAttrib::get_class_slot()));
  4285. DepthWriteAttrib::Mode mode = target_depth_write->get_mode();
  4286. if (mode == DepthWriteAttrib::M_off) {
  4287. #ifdef GSG_VERBOSE
  4288. GLCAT.spam()
  4289. << "glDepthMask(GL_FALSE)" << endl;
  4290. #endif
  4291. GLP(DepthMask)(GL_FALSE);
  4292. } else {
  4293. #ifdef GSG_VERBOSE
  4294. GLCAT.spam()
  4295. << "glDepthMask(GL_TRUE)" << endl;
  4296. #endif
  4297. GLP(DepthMask)(GL_TRUE);
  4298. }
  4299. report_my_gl_errors();
  4300. }
  4301. ////////////////////////////////////////////////////////////////////
  4302. // Function: GLGraphicsStateGuardian::do_issue_cull_face
  4303. // Access: Protected
  4304. // Description:
  4305. ////////////////////////////////////////////////////////////////////
  4306. void CLP(GraphicsStateGuardian)::
  4307. do_issue_cull_face() {
  4308. const CullFaceAttrib *target_cull_face = DCAST(CullFaceAttrib, _target_rs->get_attrib_def(CullFaceAttrib::get_class_slot()));
  4309. CullFaceAttrib::Mode mode = target_cull_face->get_effective_mode();
  4310. switch (mode) {
  4311. case CullFaceAttrib::M_cull_none:
  4312. GLP(Disable)(GL_CULL_FACE);
  4313. break;
  4314. case CullFaceAttrib::M_cull_clockwise:
  4315. GLP(Enable)(GL_CULL_FACE);
  4316. GLP(CullFace)(GL_BACK);
  4317. break;
  4318. case CullFaceAttrib::M_cull_counter_clockwise:
  4319. GLP(Enable)(GL_CULL_FACE);
  4320. GLP(CullFace)(GL_FRONT);
  4321. break;
  4322. default:
  4323. GLCAT.error()
  4324. << "invalid cull face mode " << (int)mode << endl;
  4325. break;
  4326. }
  4327. report_my_gl_errors();
  4328. }
  4329. ////////////////////////////////////////////////////////////////////
  4330. // Function: GLGraphicsStateGuardian::do_issue_fog
  4331. // Access: Protected
  4332. // Description:
  4333. ////////////////////////////////////////////////////////////////////
  4334. void CLP(GraphicsStateGuardian)::
  4335. do_issue_fog() {
  4336. const FogAttrib *target_fog = DCAST(FogAttrib, _target_rs->get_attrib_def(FogAttrib::get_class_slot()));
  4337. if (!target_fog->is_off()) {
  4338. enable_fog(true);
  4339. Fog *fog = target_fog->get_fog();
  4340. nassertv(fog != (Fog *)NULL);
  4341. apply_fog(fog);
  4342. } else {
  4343. enable_fog(false);
  4344. }
  4345. report_my_gl_errors();
  4346. }
  4347. ////////////////////////////////////////////////////////////////////
  4348. // Function: GLGraphicsStateGuardian::do_issue_depth_offset
  4349. // Access: Protected
  4350. // Description:
  4351. ////////////////////////////////////////////////////////////////////
  4352. void CLP(GraphicsStateGuardian)::
  4353. do_issue_depth_offset() {
  4354. const DepthOffsetAttrib *target_depth_offset = DCAST(DepthOffsetAttrib, _target_rs->get_attrib_def(DepthOffsetAttrib::get_class_slot()));
  4355. int offset = target_depth_offset->get_offset();
  4356. if (offset != 0) {
  4357. // The relationship between these two parameters is a little
  4358. // unclear and poorly explained in the GL man pages.
  4359. GLP(PolygonOffset)((GLfloat) -offset, (GLfloat) -offset);
  4360. enable_polygon_offset(true);
  4361. } else {
  4362. enable_polygon_offset(false);
  4363. }
  4364. PN_stdfloat min_value = target_depth_offset->get_min_value();
  4365. PN_stdfloat max_value = target_depth_offset->get_max_value();
  4366. #ifdef GSG_VERBOSE
  4367. GLCAT.spam()
  4368. << "glDepthRange(" << min_value << ", " << max_value << ")" << endl;
  4369. #endif
  4370. #ifdef OPENGLES
  4371. // OpenGL ES uses a single-precision call.
  4372. GLP(DepthRangef)((GLclampf)min_value, (GLclampf)max_value);
  4373. #else
  4374. // Mainline OpenGL uses a double-precision call.
  4375. GLP(DepthRange)((GLclampd)min_value, (GLclampd)max_value);
  4376. #endif // OPENGLES
  4377. report_my_gl_errors();
  4378. }
  4379. ////////////////////////////////////////////////////////////////////
  4380. // Function: GLGraphicsStateGuardian::do_issue_material
  4381. // Access: Protected
  4382. // Description:
  4383. ////////////////////////////////////////////////////////////////////
  4384. void CLP(GraphicsStateGuardian)::
  4385. do_issue_material() {
  4386. #ifndef OPENGLES_2 // OpenGL ES 2.0 doesn't support materials.
  4387. static Material empty;
  4388. const Material *material;
  4389. const MaterialAttrib *target_material = DCAST(MaterialAttrib, _target_rs->get_attrib_def(MaterialAttrib::get_class_slot()));
  4390. if (target_material == (MaterialAttrib *)NULL ||
  4391. target_material->is_off()) {
  4392. material = &empty;
  4393. } else {
  4394. material = target_material->get_material();
  4395. }
  4396. bool has_material_force_color = _has_material_force_color;
  4397. #ifndef NDEBUG
  4398. if (_show_texture_usage) {
  4399. // In show_texture_usage mode, all colors are white, so as not
  4400. // to contaminate the texture color. This means we disable
  4401. // lighting materials too.
  4402. material = &empty;
  4403. has_material_force_color = false;
  4404. }
  4405. #endif // NDEBUG
  4406. #ifndef OPENGLES
  4407. GLenum face = material->get_twoside() ? GL_FRONT_AND_BACK : GL_FRONT;
  4408. #else
  4409. static const GLenum face = GL_FRONT_AND_BACK;
  4410. #endif // OPENGLES
  4411. call_glMaterialfv(face, GL_SPECULAR, material->get_specular());
  4412. call_glMaterialfv(face, GL_EMISSION, material->get_emission());
  4413. GLP(Materialf)(face, GL_SHININESS, min(material->get_shininess(), (PN_stdfloat)128.0));
  4414. if (material->has_ambient() && material->has_diffuse()) {
  4415. // The material has both an ambient and diffuse specified. This
  4416. // means we do not need glMaterialColor().
  4417. GLP(Disable)(GL_COLOR_MATERIAL);
  4418. call_glMaterialfv(face, GL_AMBIENT, material->get_ambient());
  4419. call_glMaterialfv(face, GL_DIFFUSE, material->get_diffuse());
  4420. } else if (material->has_ambient()) {
  4421. // The material specifies an ambient, but not a diffuse component.
  4422. // The diffuse component comes from the object's color.
  4423. call_glMaterialfv(face, GL_AMBIENT, material->get_ambient());
  4424. if (has_material_force_color) {
  4425. GLP(Disable)(GL_COLOR_MATERIAL);
  4426. call_glMaterialfv(face, GL_DIFFUSE, _material_force_color);
  4427. } else {
  4428. #ifndef OPENGLES
  4429. GLP(ColorMaterial)(face, GL_DIFFUSE);
  4430. #endif // OPENGLES
  4431. GLP(Enable)(GL_COLOR_MATERIAL);
  4432. }
  4433. } else if (material->has_diffuse()) {
  4434. // The material specifies a diffuse, but not an ambient component.
  4435. // The ambient component comes from the object's color.
  4436. call_glMaterialfv(face, GL_DIFFUSE, material->get_diffuse());
  4437. if (has_material_force_color) {
  4438. GLP(Disable)(GL_COLOR_MATERIAL);
  4439. call_glMaterialfv(face, GL_AMBIENT, _material_force_color);
  4440. } else {
  4441. #ifndef OPENGLES
  4442. GLP(ColorMaterial)(face, GL_AMBIENT);
  4443. #endif // OPENGLES
  4444. GLP(Enable)(GL_COLOR_MATERIAL);
  4445. }
  4446. } else {
  4447. // The material specifies neither a diffuse nor an ambient
  4448. // component. Both components come from the object's color.
  4449. if (has_material_force_color) {
  4450. GLP(Disable)(GL_COLOR_MATERIAL);
  4451. call_glMaterialfv(face, GL_AMBIENT, _material_force_color);
  4452. call_glMaterialfv(face, GL_DIFFUSE, _material_force_color);
  4453. } else {
  4454. #ifndef OPENGLES
  4455. GLP(ColorMaterial)(face, GL_AMBIENT_AND_DIFFUSE);
  4456. #endif // OPENGLES
  4457. GLP(Enable)(GL_COLOR_MATERIAL);
  4458. }
  4459. }
  4460. #ifndef OPENGLES
  4461. GLP(LightModeli)(GL_LIGHT_MODEL_LOCAL_VIEWER, material->get_local());
  4462. GLP(LightModeli)(GL_LIGHT_MODEL_TWO_SIDE, material->get_twoside());
  4463. #endif // OPENGLES
  4464. report_my_gl_errors();
  4465. #endif // OPENGLES_2
  4466. }
  4467. ////////////////////////////////////////////////////////////////////
  4468. // Function: GLGraphicsStateGuardian::do_issue_blending
  4469. // Access: Protected
  4470. // Description:
  4471. ////////////////////////////////////////////////////////////////////
  4472. void CLP(GraphicsStateGuardian)::
  4473. do_issue_blending() {
  4474. // Handle the color_write attrib. If color_write is off, then
  4475. // all the other blending-related stuff doesn't matter. If the
  4476. // device doesn't support color-write, we use blending tricks
  4477. // to effectively disable color write.
  4478. const ColorWriteAttrib *target_color_write = DCAST(ColorWriteAttrib, _target_rs->get_attrib_def(ColorWriteAttrib::get_class_slot()));
  4479. unsigned int color_channels =
  4480. target_color_write->get_channels() & _color_write_mask;
  4481. if (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write)) {
  4482. color_channels &= ~(ColorWriteAttrib::C_alpha);
  4483. }
  4484. if (color_channels == ColorWriteAttrib::C_off) {
  4485. int color_write_slot = ColorWriteAttrib::get_class_slot();
  4486. enable_multisample_alpha_one(false);
  4487. enable_multisample_alpha_mask(false);
  4488. if (CLP(color_mask)) {
  4489. enable_blend(false);
  4490. GLP(ColorMask)(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
  4491. } else {
  4492. enable_blend(true);
  4493. _glBlendEquation(GL_FUNC_ADD);
  4494. GLP(BlendFunc)(GL_ZERO, GL_ONE);
  4495. }
  4496. return;
  4497. } else {
  4498. if (CLP(color_mask)) {
  4499. GLP(ColorMask)((color_channels & ColorWriteAttrib::C_red) != 0,
  4500. (color_channels & ColorWriteAttrib::C_green) != 0,
  4501. (color_channels & ColorWriteAttrib::C_blue) != 0,
  4502. (color_channels & ColorWriteAttrib::C_alpha) != 0);
  4503. }
  4504. }
  4505. const ColorBlendAttrib *target_color_blend = DCAST(ColorBlendAttrib, _target_rs->get_attrib_def(ColorBlendAttrib::get_class_slot()));
  4506. CPT(ColorBlendAttrib) color_blend = target_color_blend;
  4507. ColorBlendAttrib::Mode color_blend_mode = target_color_blend->get_mode();
  4508. const TransparencyAttrib *target_transparency = DCAST(TransparencyAttrib, _target_rs->get_attrib_def(TransparencyAttrib::get_class_slot()));
  4509. TransparencyAttrib::Mode transparency_mode = target_transparency->get_mode();
  4510. _color_blend_involves_color_scale = color_blend->involves_color_scale();
  4511. // Is there a color blend set?
  4512. if (color_blend_mode != ColorBlendAttrib::M_none) {
  4513. enable_multisample_alpha_one(false);
  4514. enable_multisample_alpha_mask(false);
  4515. enable_blend(true);
  4516. _glBlendEquation(get_blend_equation_type(color_blend_mode));
  4517. GLP(BlendFunc)(get_blend_func(color_blend->get_operand_a()),
  4518. get_blend_func(color_blend->get_operand_b()));
  4519. if (_color_blend_involves_color_scale) {
  4520. // Apply the current color scale to the blend mode.
  4521. _glBlendColor(_current_color_scale[0], _current_color_scale[1],
  4522. _current_color_scale[2], _current_color_scale[3]);
  4523. } else {
  4524. LColor c = color_blend->get_color();
  4525. _glBlendColor(c[0], c[1], c[2], c[3]);
  4526. }
  4527. return;
  4528. }
  4529. // No color blend; is there a transparency set?
  4530. switch (transparency_mode) {
  4531. case TransparencyAttrib::M_none:
  4532. case TransparencyAttrib::M_binary:
  4533. break;
  4534. case TransparencyAttrib::M_alpha:
  4535. case TransparencyAttrib::M_dual:
  4536. enable_multisample_alpha_one(false);
  4537. enable_multisample_alpha_mask(false);
  4538. enable_blend(true);
  4539. _glBlendEquation(GL_FUNC_ADD);
  4540. GLP(BlendFunc)(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  4541. return;
  4542. case TransparencyAttrib::M_multisample:
  4543. // We need to enable *both* of these in M_multisample case.
  4544. enable_multisample_alpha_one(true);
  4545. enable_multisample_alpha_mask(true);
  4546. enable_blend(false);
  4547. return;
  4548. case TransparencyAttrib::M_multisample_mask:
  4549. enable_multisample_alpha_one(false);
  4550. enable_multisample_alpha_mask(true);
  4551. enable_blend(false);
  4552. return;
  4553. default:
  4554. GLCAT.error()
  4555. << "invalid transparency mode " << (int)transparency_mode << endl;
  4556. break;
  4557. }
  4558. if (_line_smooth_enabled || _point_smooth_enabled) {
  4559. // If we have either of these turned on, we also need to have
  4560. // blend mode enabled in order to see it.
  4561. enable_multisample_alpha_one(false);
  4562. enable_multisample_alpha_mask(false);
  4563. enable_blend(true);
  4564. _glBlendEquation(GL_FUNC_ADD);
  4565. GLP(BlendFunc)(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  4566. return;
  4567. }
  4568. // For best polygon smoothing, we need:
  4569. // (1) a frame buffer that supports alpha
  4570. // (2) sort polygons front-to-back
  4571. // (3) glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE);
  4572. //
  4573. // Since these modes have other implications for the application, we
  4574. // don't attempt to do this by default. If you really want good
  4575. // polygon smoothing (and you don't have multisample support), do
  4576. // all this yourself.
  4577. // Nothing's set, so disable blending.
  4578. enable_multisample_alpha_one(false);
  4579. enable_multisample_alpha_mask(false);
  4580. enable_blend(false);
  4581. }
  4582. ////////////////////////////////////////////////////////////////////
  4583. // Function: GLGraphicsStateGuardian::bind_light
  4584. // Access: Public, Virtual
  4585. // Description: Called the first time a particular light has been
  4586. // bound to a given id within a frame, this should set
  4587. // up the associated hardware light with the light's
  4588. // properties.
  4589. ////////////////////////////////////////////////////////////////////
  4590. void CLP(GraphicsStateGuardian)::
  4591. bind_light(PointLight *light_obj, const NodePath &light, int light_id) {
  4592. #ifndef OPENGLES_2
  4593. // static PStatCollector _draw_set_state_light_bind_point_pcollector("Draw:Set State:Light:Bind:Point");
  4594. // PStatTimer timer(_draw_set_state_light_bind_point_pcollector);
  4595. GLenum id = get_light_id(light_id);
  4596. static const LColor black(0.0f, 0.0f, 0.0f, 1.0f);
  4597. call_glLightfv(id, GL_AMBIENT, black);
  4598. call_glLightfv(id, GL_DIFFUSE, get_light_color(light_obj));
  4599. call_glLightfv(id, GL_SPECULAR, light_obj->get_specular_color());
  4600. // Position needs to specify x, y, z, and w
  4601. // w == 1 implies non-infinite position
  4602. CPT(TransformState) transform = light.get_transform(_scene_setup->get_scene_root().get_parent());
  4603. LPoint3 pos = light_obj->get_point() * transform->get_mat();
  4604. LPoint4 fpos(pos[0], pos[1], pos[2], 1.0f);
  4605. call_glLightfv(id, GL_POSITION, fpos);
  4606. // GL_SPOT_DIRECTION is not significant when cutoff == 180
  4607. // Exponent == 0 implies uniform light distribution
  4608. GLP(Lightf)(id, GL_SPOT_EXPONENT, 0.0f);
  4609. // Cutoff == 180 means uniform point light source
  4610. GLP(Lightf)(id, GL_SPOT_CUTOFF, 180.0f);
  4611. const LVecBase3 &att = light_obj->get_attenuation();
  4612. GLP(Lightf)(id, GL_CONSTANT_ATTENUATION, att[0]);
  4613. GLP(Lightf)(id, GL_LINEAR_ATTENUATION, att[1]);
  4614. GLP(Lightf)(id, GL_QUADRATIC_ATTENUATION, att[2]);
  4615. report_my_gl_errors();
  4616. #endif
  4617. }
  4618. ////////////////////////////////////////////////////////////////////
  4619. // Function: GLGraphicsStateGuardian::bind_light
  4620. // Access: Public, Virtual
  4621. // Description: Called the first time a particular light has been
  4622. // bound to a given id within a frame, this should set
  4623. // up the associated hardware light with the light's
  4624. // properties.
  4625. ////////////////////////////////////////////////////////////////////
  4626. void CLP(GraphicsStateGuardian)::
  4627. bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) {
  4628. #ifndef OPENGLES_2
  4629. // static PStatCollector _draw_set_state_light_bind_directional_pcollector("Draw:Set State:Light:Bind:Directional");
  4630. // PStatTimer timer(_draw_set_state_light_bind_directional_pcollector);
  4631. pair<DirectionalLights::iterator, bool> lookup = _dlights.insert(DirectionalLights::value_type(light, DirectionalLightFrameData()));
  4632. DirectionalLightFrameData &fdata = (*lookup.first).second;
  4633. if (lookup.second) {
  4634. // The light was not computed yet this frame. Compute it now.
  4635. CPT(TransformState) transform = light.get_transform(_scene_setup->get_scene_root().get_parent());
  4636. LVector3 dir = light_obj->get_direction() * transform->get_mat();
  4637. fdata._neg_dir.set(-dir[0], -dir[1], -dir[2], 0);
  4638. }
  4639. GLenum id = get_light_id( light_id );
  4640. static const LColor black(0.0f, 0.0f, 0.0f, 1.0f);
  4641. call_glLightfv(id, GL_AMBIENT, black);
  4642. call_glLightfv(id, GL_DIFFUSE, get_light_color(light_obj));
  4643. call_glLightfv(id, GL_SPECULAR, light_obj->get_specular_color());
  4644. // Position needs to specify x, y, z, and w.
  4645. // w == 0 implies light is at infinity
  4646. call_glLightfv(id, GL_POSITION, fdata._neg_dir);
  4647. // GL_SPOT_DIRECTION is not significant when cutoff == 180
  4648. // In this case, position x, y, z specifies direction
  4649. // Exponent == 0 implies uniform light distribution
  4650. GLP(Lightf)(id, GL_SPOT_EXPONENT, 0.0f);
  4651. // Cutoff == 180 means uniform point light source
  4652. GLP(Lightf)(id, GL_SPOT_CUTOFF, 180.0f);
  4653. // Default attenuation values (only spotlight and point light can
  4654. // modify these)
  4655. GLP(Lightf)(id, GL_CONSTANT_ATTENUATION, 1.0f);
  4656. GLP(Lightf)(id, GL_LINEAR_ATTENUATION, 0.0f);
  4657. GLP(Lightf)(id, GL_QUADRATIC_ATTENUATION, 0.0f);
  4658. report_my_gl_errors();
  4659. #endif
  4660. }
  4661. ////////////////////////////////////////////////////////////////////
  4662. // Function: GLGraphicsStateGuardian::bind_light
  4663. // Access: Public, Virtual
  4664. // Description: Called the first time a particular light has been
  4665. // bound to a given id within a frame, this should set
  4666. // up the associated hardware light with the light's
  4667. // properties.
  4668. ////////////////////////////////////////////////////////////////////
  4669. void CLP(GraphicsStateGuardian)::
  4670. bind_light(Spotlight *light_obj, const NodePath &light, int light_id) {
  4671. #ifndef OPENGLES_2
  4672. // static PStatCollector _draw_set_state_light_bind_spotlight_pcollector("Draw:Set State:Light:Bind:Spotlight");
  4673. // PStatTimer timer(_draw_set_state_light_bind_spotlight_pcollector);
  4674. Lens *lens = light_obj->get_lens();
  4675. nassertv(lens != (Lens *)NULL);
  4676. GLenum id = get_light_id(light_id);
  4677. static const LColor black(0.0f, 0.0f, 0.0f, 1.0f);
  4678. call_glLightfv(id, GL_AMBIENT, black);
  4679. call_glLightfv(id, GL_DIFFUSE, get_light_color(light_obj));
  4680. call_glLightfv(id, GL_SPECULAR, light_obj->get_specular_color());
  4681. // Position needs to specify x, y, z, and w
  4682. // w == 1 implies non-infinite position
  4683. CPT(TransformState) transform = light.get_transform(_scene_setup->get_scene_root().get_parent());
  4684. const LMatrix4 &light_mat = transform->get_mat();
  4685. LPoint3 pos = lens->get_nodal_point() * light_mat;
  4686. LVector3 dir = lens->get_view_vector() * light_mat;
  4687. LPoint4 fpos(pos[0], pos[1], pos[2], 1.0f);
  4688. call_glLightfv(id, GL_POSITION, fpos);
  4689. call_glLightfv(id, GL_SPOT_DIRECTION, dir);
  4690. GLP(Lightf)(id, GL_SPOT_EXPONENT, light_obj->get_exponent());
  4691. GLP(Lightf)(id, GL_SPOT_CUTOFF, lens->get_hfov() * 0.5f);
  4692. const LVecBase3 &att = light_obj->get_attenuation();
  4693. GLP(Lightf)(id, GL_CONSTANT_ATTENUATION, att[0]);
  4694. GLP(Lightf)(id, GL_LINEAR_ATTENUATION, att[1]);
  4695. GLP(Lightf)(id, GL_QUADRATIC_ATTENUATION, att[2]);
  4696. report_my_gl_errors();
  4697. #endif
  4698. }
  4699. #ifdef SUPPORT_IMMEDIATE_MODE
  4700. ////////////////////////////////////////////////////////////////////
  4701. // Function: GLGraphicsStateGuardian::draw_immediate_simple_primitives
  4702. // Access: Protected
  4703. // Description: Uses the ImmediateModeSender to draw a series of
  4704. // primitives of the indicated type.
  4705. ////////////////////////////////////////////////////////////////////
  4706. void CLP(GraphicsStateGuardian)::
  4707. draw_immediate_simple_primitives(const GeomPrimitivePipelineReader *reader, GLenum mode) {
  4708. int num_vertices = reader->get_num_vertices();
  4709. _vertices_immediate_pcollector.add_level(num_vertices);
  4710. GLP(Begin)(mode);
  4711. if (reader->is_indexed()) {
  4712. for (int v = 0; v < num_vertices; ++v) {
  4713. _sender.set_vertex(reader->get_vertex(v));
  4714. _sender.issue_vertex();
  4715. }
  4716. } else {
  4717. _sender.set_vertex(reader->get_first_vertex());
  4718. for (int v = 0; v < num_vertices; ++v) {
  4719. _sender.issue_vertex();
  4720. }
  4721. }
  4722. GLP(End)();
  4723. }
  4724. #endif // SUPPORT_IMMEDIATE_MODE
  4725. #ifdef SUPPORT_IMMEDIATE_MODE
  4726. ////////////////////////////////////////////////////////////////////
  4727. // Function: GLGraphicsStateGuardian::draw_immediate_composite_primitives
  4728. // Access: Protected
  4729. // Description: Uses the ImmediateModeSender to draw a series of
  4730. // primitives of the indicated type. This form is for
  4731. // primitive types like tristrips which must involve
  4732. // several begin/end groups.
  4733. ////////////////////////////////////////////////////////////////////
  4734. void CLP(GraphicsStateGuardian)::
  4735. draw_immediate_composite_primitives(const GeomPrimitivePipelineReader *reader, GLenum mode) {
  4736. int num_vertices = reader->get_num_vertices();
  4737. _vertices_immediate_pcollector.add_level(num_vertices);
  4738. CPTA_int ends = reader->get_ends();
  4739. int num_unused_vertices_per_primitive = reader->get_object()->get_num_unused_vertices_per_primitive();
  4740. if (reader->is_indexed()) {
  4741. int begin = 0;
  4742. CPTA_int::const_iterator ei;
  4743. for (ei = ends.begin(); ei != ends.end(); ++ei) {
  4744. int end = (*ei);
  4745. GLP(Begin)(mode);
  4746. for (int v = begin; v < end; ++v) {
  4747. _sender.set_vertex(reader->get_vertex(v));
  4748. _sender.issue_vertex();
  4749. }
  4750. GLP(End)();
  4751. begin = end + num_unused_vertices_per_primitive;
  4752. }
  4753. } else {
  4754. _sender.set_vertex(reader->get_first_vertex());
  4755. int begin = 0;
  4756. CPTA_int::const_iterator ei;
  4757. for (ei = ends.begin(); ei != ends.end(); ++ei) {
  4758. int end = (*ei);
  4759. GLP(Begin)(mode);
  4760. for (int v = begin; v < end; ++v) {
  4761. _sender.issue_vertex();
  4762. }
  4763. GLP(End)();
  4764. begin = end + num_unused_vertices_per_primitive;
  4765. }
  4766. }
  4767. }
  4768. #endif // SUPPORT_IMMEDIATE_MODE
  4769. ////////////////////////////////////////////////////////////////////
  4770. // Function: GLGraphicsStateGuardian::gl_flush
  4771. // Access: Protected, Virtual
  4772. // Description: Calls glFlush().
  4773. ////////////////////////////////////////////////////////////////////
  4774. void CLP(GraphicsStateGuardian)::
  4775. gl_flush() const {
  4776. PStatTimer timer(_flush_pcollector);
  4777. if (_allow_flush) {
  4778. GLP(Flush)();
  4779. }
  4780. }
  4781. ////////////////////////////////////////////////////////////////////
  4782. // Function: GLGraphicsStateGuardian::gl_get_error
  4783. // Access: Protected, Virtual
  4784. // Description: Returns the result of glGetError().
  4785. ////////////////////////////////////////////////////////////////////
  4786. GLenum CLP(GraphicsStateGuardian)::
  4787. gl_get_error() const {
  4788. if (_track_errors) {
  4789. return GLP(GetError)();
  4790. } else {
  4791. return GL_NO_ERROR;
  4792. }
  4793. }
  4794. ////////////////////////////////////////////////////////////////////
  4795. // Function: GLGraphicsStateGuardian::report_errors_loop
  4796. // Access: Protected, Static
  4797. // Description: The internal implementation of report_errors().
  4798. // Don't call this function; use report_errors()
  4799. // instead. The return value is true if everything is
  4800. // ok, or false if we should shut down.
  4801. ////////////////////////////////////////////////////////////////////
  4802. bool CLP(GraphicsStateGuardian)::
  4803. report_errors_loop(int line, const char *source_file, GLenum error_code,
  4804. int &error_count) {
  4805. while ((CLP(max_errors) < 0 || error_count < CLP(max_errors)) &&
  4806. (error_code != GL_NO_ERROR)) {
  4807. GLCAT.error()
  4808. << "at " << line << " of " << source_file << " : "
  4809. << get_error_string(error_code) << "\n";
  4810. error_code = GLP(GetError)();
  4811. error_count++;
  4812. }
  4813. return (error_code == GL_NO_ERROR);
  4814. }
  4815. ////////////////////////////////////////////////////////////////////
  4816. // Function: GLGraphicsStateGuardian::get_error_string
  4817. // Access: Protected, Static
  4818. // Description: Returns an error string for an OpenGL error code.
  4819. ////////////////////////////////////////////////////////////////////
  4820. string CLP(GraphicsStateGuardian)::
  4821. get_error_string(GLenum error_code) {
  4822. // We used to use gluErrorString here, but I (rdb) took it out
  4823. // because that was really the only function we used from GLU.
  4824. // The idea with the error table was taken from SGI's sample implementation.
  4825. static const char *error_strings[GL_OUT_OF_MEMORY - GL_INVALID_ENUM + 1] = {
  4826. "invalid enumerant",
  4827. "invalid value",
  4828. "invalid operation",
  4829. "stack overflow",
  4830. "stack underflow",
  4831. "out of memory",
  4832. };
  4833. if (error_code == GL_NO_ERROR) {
  4834. return "no error";
  4835. #ifndef OPENGLES
  4836. } else if (error_code == GL_TABLE_TOO_LARGE) {
  4837. return "table too large";
  4838. #endif
  4839. } else if (error_code >= GL_INVALID_ENUM && error_code <= GL_OUT_OF_MEMORY) {
  4840. return error_strings[error_code - GL_INVALID_ENUM];
  4841. }
  4842. // Other error, somehow? Just display the error code then.
  4843. ostringstream strm;
  4844. strm << "GL error " << (int)error_code;
  4845. return strm.str();
  4846. }
  4847. ////////////////////////////////////////////////////////////////////
  4848. // Function: GLGraphicsStateGuardian::show_gl_string
  4849. // Access: Protected
  4850. // Description: Outputs the result of glGetString() on the indicated
  4851. // tag. The output string is returned.
  4852. ////////////////////////////////////////////////////////////////////
  4853. string CLP(GraphicsStateGuardian)::
  4854. show_gl_string(const string &name, GLenum id) {
  4855. string result;
  4856. const GLubyte *text = GLP(GetString)(id);
  4857. if (text == (const GLubyte *)NULL) {
  4858. if (GLCAT.is_debug()) {
  4859. GLCAT.debug()
  4860. << "Unable to query " << name << "\n";
  4861. }
  4862. } else {
  4863. result = (const char *)text;
  4864. if (GLCAT.is_debug()) {
  4865. GLCAT.debug()
  4866. << name << " = " << result << "\n";
  4867. }
  4868. }
  4869. return result;
  4870. }
  4871. ////////////////////////////////////////////////////////////////////
  4872. // Function: GLGraphicsStateGuardian::query_gl_version
  4873. // Access: Protected, Virtual
  4874. // Description: Queries the runtime version of OpenGL in use.
  4875. ////////////////////////////////////////////////////////////////////
  4876. void CLP(GraphicsStateGuardian)::
  4877. query_gl_version() {
  4878. _gl_vendor = show_gl_string("GL_VENDOR", GL_VENDOR);
  4879. _gl_renderer = show_gl_string("GL_RENDERER", GL_RENDERER);
  4880. _gl_version_major = 0;
  4881. _gl_version_minor = 0;
  4882. const GLubyte *text = GLP(GetString)(GL_VERSION);
  4883. if (text == (const GLubyte *)NULL) {
  4884. GLCAT.debug()
  4885. << "Unable to query GL_VERSION\n";
  4886. } else {
  4887. string version((const char *)text);
  4888. _gl_version = version;
  4889. string input = version;
  4890. // Skip any initial words that don't begin with a digit.
  4891. while (!input.empty() && !isdigit(input[0])) {
  4892. size_t space = input.find(' ');
  4893. if (space == string::npos) {
  4894. break;
  4895. }
  4896. size_t next = space + 1;
  4897. while (next < input.length() && isspace(input[next])) {
  4898. ++next;
  4899. }
  4900. input = input.substr(next);
  4901. }
  4902. // Truncate after the first space.
  4903. size_t space = input.find(' ');
  4904. if (space != string::npos) {
  4905. input = input.substr(0, space);
  4906. }
  4907. vector_string components;
  4908. tokenize(input, components, ".");
  4909. if (components.size() >= 1) {
  4910. string_to_int(components[0], _gl_version_major);
  4911. }
  4912. if (components.size() >= 2) {
  4913. string_to_int(components[1], _gl_version_minor);
  4914. }
  4915. if (GLCAT.is_debug()) {
  4916. GLCAT.debug()
  4917. << "GL_VERSION = " << version << ", decoded to "
  4918. << _gl_version_major << "." << _gl_version_minor
  4919. << "\n";
  4920. }
  4921. #ifndef OPENGLES
  4922. if (_gl_version_major==1) {
  4923. const char *extstr = (const char *) GLP(GetString)(GL_EXTENSIONS);
  4924. if (extstr != NULL) {
  4925. if (strstr( extstr, "GL_ARB_shading_language_100") != NULL)
  4926. {
  4927. _gl_shadlang_ver_major = 1;
  4928. _gl_shadlang_ver_minor = 0;
  4929. }
  4930. }
  4931. }
  4932. else if (_gl_version_major >= 2) {
  4933. const char *verstr = (const char *) GLP(GetString)(GL_SHADING_LANGUAGE_VERSION);
  4934. if ((verstr == NULL) || (sscanf(verstr, "%d.%d", &_gl_shadlang_ver_major, &_gl_shadlang_ver_minor) != 2))
  4935. {
  4936. GLCAT.warning() << "Invalid GL_SHADING_LANGUAGE_VERSION format.\n";
  4937. }
  4938. }
  4939. #endif
  4940. }
  4941. }
  4942. ////////////////////////////////////////////////////////////////////
  4943. // Function: GLGraphicsStateGuardian::save_extensions
  4944. // Access: Protected
  4945. // Description: Separates the string returned by GL_EXTENSIONS (or
  4946. // glx or wgl extensions) into its individual tokens
  4947. // and saves them in the _extensions member.
  4948. ////////////////////////////////////////////////////////////////////
  4949. void CLP(GraphicsStateGuardian)::
  4950. save_extensions(const char *extensions) {
  4951. if (extensions != (const char *)NULL) {
  4952. vector_string tokens;
  4953. extract_words(extensions, tokens);
  4954. vector_string::iterator ti;
  4955. for (ti = tokens.begin(); ti != tokens.end(); ++ti) {
  4956. _extensions.insert(*ti);
  4957. }
  4958. }
  4959. }
  4960. ////////////////////////////////////////////////////////////////////
  4961. // Function: GLGraphicsStateGuardian::get_extra_extensions
  4962. // Access: Protected, Virtual
  4963. // Description: This may be redefined by a derived class (e.g. glx or
  4964. // wgl) to get whatever further extensions strings may
  4965. // be appropriate to that interface, in addition to the
  4966. // GL extension strings return by glGetString().
  4967. ////////////////////////////////////////////////////////////////////
  4968. void CLP(GraphicsStateGuardian)::
  4969. get_extra_extensions() {
  4970. }
  4971. ////////////////////////////////////////////////////////////////////
  4972. // Function: GLGraphicsStateGuardian::report_extensions
  4973. // Access: Protected
  4974. // Description: Outputs the list of GL extensions to notify, if debug
  4975. // mode is enabled.
  4976. ////////////////////////////////////////////////////////////////////
  4977. void CLP(GraphicsStateGuardian)::
  4978. report_extensions() const {
  4979. if (GLCAT.is_debug()) {
  4980. GLCAT.debug()
  4981. << "GL Extensions:\n";
  4982. pset<string>::const_iterator ei;
  4983. for (ei = _extensions.begin(); ei != _extensions.end(); ++ei) {
  4984. GLCAT.debug() << (*ei) << "\n";
  4985. }
  4986. }
  4987. }
  4988. ////////////////////////////////////////////////////////////////////
  4989. // Function: GLGraphicsStateGuardian::has_extension
  4990. // Access: Protected
  4991. // Description: Returns true if the indicated extension is reported
  4992. // by the GL system, false otherwise. The extension
  4993. // name is case-sensitive.
  4994. ////////////////////////////////////////////////////////////////////
  4995. bool CLP(GraphicsStateGuardian)::
  4996. has_extension(const string &extension) const {
  4997. bool state;
  4998. state = _extensions.find(extension) != _extensions.end();
  4999. if (GLCAT.is_debug()) {
  5000. GLCAT.debug()
  5001. << "HAS EXT " << extension << " " << state << "\n";
  5002. }
  5003. return state;
  5004. }
  5005. ////////////////////////////////////////////////////////////////////
  5006. // Function: GLGraphicsStateGuardian::get_extension_func
  5007. // Access: Public
  5008. // Description: Returns the pointer to the GL extension function with
  5009. // the indicated name, or NULL if the function is not
  5010. // available.
  5011. ////////////////////////////////////////////////////////////////////
  5012. void *CLP(GraphicsStateGuardian)::
  5013. get_extension_func(const char *prefix, const char *name) {
  5014. // First, look in the static-compiled namespace. If we were
  5015. // compiled to expect at least a certain minimum runtime version of
  5016. // OpenGL, then we can expect those extension functions to be
  5017. // available at compile time. Somewhat more reliable than poking
  5018. // around in the runtime pointers.
  5019. static struct {
  5020. const char *name;
  5021. void *fptr;
  5022. } compiled_function_table[] = {
  5023. #ifdef EXPECT_GL_VERSION_1_2
  5024. { "BlendColor", (void *)&GLP(BlendColor) },
  5025. { "BlendEquation", (void *)&GLP(BlendEquation) },
  5026. { "DrawRangeElements", (void *)&GLP(DrawRangeElements) },
  5027. { "TexImage3D", (void *)&GLP(TexImage3D) },
  5028. { "TexSubImage3D", (void *)&GLP(TexSubImage3D) },
  5029. #endif
  5030. #ifdef EXPECT_GL_VERSION_1_3
  5031. { "ActiveTexture", (void *)&GLP(ActiveTexture) },
  5032. { "ClientActiveTexture", (void *)&GLP(ClientActiveTexture) },
  5033. { "CompressedTexImage1D", (void *)&GLP(CompressedTexImage1D) },
  5034. { "CompressedTexImage2D", (void *)&GLP(CompressedTexImage2D) },
  5035. { "CompressedTexImage3D", (void *)&GLP(CompressedTexImage3D) },
  5036. { "CompressedTexSubImage1D", (void *)&GLP(CompressedTexSubImage1D) },
  5037. { "CompressedTexSubImage2D", (void *)&GLP(CompressedTexSubImage2D) },
  5038. { "CompressedTexSubImage3D", (void *)&GLP(CompressedTexSubImage3D) },
  5039. { "GetCompressedTexImage", (void *)&GLP(GetCompressedTexImage) },
  5040. { "MultiTexCoord1f", (void *)&GLP(MultiTexCoord1f) },
  5041. { "MultiTexCoord2", (void *)&GLP(MultiTexCoord2) },
  5042. { "MultiTexCoord3", (void *)&GLP(MultiTexCoord3) },
  5043. { "MultiTexCoord4", (void *)&GLP(MultiTexCoord4) },
  5044. #endif
  5045. #ifdef EXPECT_GL_VERSION_1_4
  5046. { "PointParameterfv", (void *)&GLP(PointParameterfv) },
  5047. #endif
  5048. #ifdef EXPECT_GL_VERSION_1_5
  5049. { "BeginQuery", (void *)&GLP(BeginQuery) },
  5050. { "BindBuffer", (void *)&GLP(BindBuffer) },
  5051. { "BufferData", (void *)&GLP(BufferData) },
  5052. { "BufferSubData", (void *)&GLP(BufferSubData) },
  5053. { "DeleteBuffers", (void *)&GLP(DeleteBuffers) },
  5054. { "DeleteQueries", (void *)&GLP(DeleteQueries) },
  5055. { "EndQuery", (void *)&GLP(EndQuery) },
  5056. { "GenBuffers", (void *)&GLP(GenBuffers) },
  5057. { "GenQueries", (void *)&GLP(GenQueries) },
  5058. { "GetQueryObjectuiv", (void *)&GLP(GetQueryObjectuiv) },
  5059. { "GetQueryiv", (void *)&GLP(GetQueryiv) },
  5060. #endif
  5061. #ifdef OPENGLES
  5062. { "ActiveTexture", (void *)&GLP(ActiveTexture) },
  5063. #ifndef OPENGLES_2
  5064. { "ClientActiveTexture", (void *)&GLP(ClientActiveTexture) },
  5065. #endif
  5066. { "BindBuffer", (void *)&GLP(BindBuffer) },
  5067. { "BufferData", (void *)&GLP(BufferData) },
  5068. { "BufferSubData", (void *)&GLP(BufferSubData) },
  5069. { "DeleteBuffers", (void *)&GLP(DeleteBuffers) },
  5070. { "GenBuffers", (void *)&GLP(GenBuffers) },
  5071. #endif
  5072. { NULL, NULL }
  5073. };
  5074. int i = 0;
  5075. while (compiled_function_table[i].name != NULL) {
  5076. if (strcmp(compiled_function_table[i].name, name) == 0) {
  5077. return compiled_function_table[i].fptr;
  5078. }
  5079. ++i;
  5080. }
  5081. // If the extension function wasn't compiled in, then go get it from
  5082. // the runtime. There's a different interface for each API.
  5083. return do_get_extension_func(prefix, name);
  5084. }
  5085. ////////////////////////////////////////////////////////////////////
  5086. // Function: GLGraphicsStateGuardian::do_get_extension_func
  5087. // Access: Public, Virtual
  5088. // Description: This is the virtual implementation of
  5089. // get_extension_func(). Each API-specific GL
  5090. // implementation will map this method to the
  5091. // appropriate API call to retrieve the extension
  5092. // function pointer. Returns NULL if the function is
  5093. // not available.
  5094. ////////////////////////////////////////////////////////////////////
  5095. void *CLP(GraphicsStateGuardian)::
  5096. do_get_extension_func(const char *, const char *) {
  5097. return NULL;
  5098. }
  5099. ////////////////////////////////////////////////////////////////////
  5100. // Function: GLGraphicsStateGuardian::set_draw_buffer
  5101. // Access: Protected
  5102. // Description: Sets up the GLP(DrawBuffer) to render into the buffer
  5103. // indicated by the RenderBuffer object. This only sets
  5104. // up the color and aux bits; it does not affect the depth,
  5105. // stencil, accum layers.
  5106. ////////////////////////////////////////////////////////////////////
  5107. void CLP(GraphicsStateGuardian)::
  5108. set_draw_buffer(int rbtype) {
  5109. #ifndef OPENGLES // Draw buffers not supported by OpenGL ES.
  5110. if (_current_fbo) {
  5111. GLuint buffers[16];
  5112. int nbuffers=0;
  5113. if (rbtype & RenderBuffer::T_color) {
  5114. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT;
  5115. }
  5116. int index = 1;
  5117. for (int i=0; i<_current_properties->get_aux_rgba(); i++) {
  5118. if (rbtype & (RenderBuffer::T_aux_rgba_0 << i)) {
  5119. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index;
  5120. }
  5121. index += 1;
  5122. }
  5123. for (int i=0; i<_current_properties->get_aux_hrgba(); i++) {
  5124. if (rbtype & (RenderBuffer::T_aux_hrgba_0 << i)) {
  5125. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index;
  5126. }
  5127. index += 1;
  5128. }
  5129. for (int i=0; i<_current_properties->get_aux_float(); i++) {
  5130. if (rbtype & (RenderBuffer::T_aux_float_0 << i)) {
  5131. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index;
  5132. }
  5133. index += 1;
  5134. }
  5135. _glDrawBuffers(nbuffers, buffers);
  5136. } else {
  5137. switch (rbtype & RenderBuffer::T_color) {
  5138. case RenderBuffer::T_front:
  5139. GLP(DrawBuffer)(GL_FRONT);
  5140. break;
  5141. case RenderBuffer::T_back:
  5142. GLP(DrawBuffer)(GL_BACK);
  5143. break;
  5144. case RenderBuffer::T_right:
  5145. GLP(DrawBuffer)(GL_RIGHT);
  5146. break;
  5147. case RenderBuffer::T_left:
  5148. GLP(DrawBuffer)(GL_LEFT);
  5149. break;
  5150. case RenderBuffer::T_front_right:
  5151. nassertv(_current_properties->is_stereo());
  5152. GLP(DrawBuffer)(GL_FRONT_RIGHT);
  5153. break;
  5154. case RenderBuffer::T_front_left:
  5155. nassertv(_current_properties->is_stereo());
  5156. GLP(DrawBuffer)(GL_FRONT_LEFT);
  5157. break;
  5158. case RenderBuffer::T_back_right:
  5159. nassertv(_current_properties->is_stereo());
  5160. GLP(DrawBuffer)(GL_BACK_RIGHT);
  5161. break;
  5162. case RenderBuffer::T_back_left:
  5163. nassertv(_current_properties->is_stereo());
  5164. GLP(DrawBuffer)(GL_BACK_LEFT);
  5165. break;
  5166. default:
  5167. break;
  5168. }
  5169. }
  5170. #endif // OPENGLES
  5171. // Also ensure that any global color channels are masked out.
  5172. if (CLP(color_mask)) {
  5173. GLP(ColorMask)((_color_write_mask & ColorWriteAttrib::C_red) != 0,
  5174. (_color_write_mask & ColorWriteAttrib::C_green) != 0,
  5175. (_color_write_mask & ColorWriteAttrib::C_blue) != 0,
  5176. (_color_write_mask & ColorWriteAttrib::C_alpha) != 0);
  5177. }
  5178. report_my_gl_errors();
  5179. }
  5180. ////////////////////////////////////////////////////////////////////
  5181. // Function: GLGraphicsStateGuardian::set_read_buffer
  5182. // Access: Protected
  5183. // Description: Sets up the GLP(ReadBuffer) to render into the buffer
  5184. // indicated by the RenderBuffer object. This only sets
  5185. // up the color bits; it does not affect the depth,
  5186. // stencil, accum layers.
  5187. ////////////////////////////////////////////////////////////////////
  5188. void CLP(GraphicsStateGuardian)::
  5189. set_read_buffer(int rbtype) {
  5190. #ifndef OPENGLES // Draw buffers not supported by OpenGL ES.
  5191. if (rbtype & (RenderBuffer::T_depth | RenderBuffer::T_stencil)) {
  5192. // Special case: don't have to call ReadBuffer for these.
  5193. return;
  5194. }
  5195. if (_current_fbo) {
  5196. GLuint buffer = GL_COLOR_ATTACHMENT0_EXT;
  5197. int index = 1;
  5198. for (int i=0; i<_current_properties->get_aux_rgba(); i++) {
  5199. if (rbtype & (RenderBuffer::T_aux_rgba_0 << i)) {
  5200. buffer = GL_COLOR_ATTACHMENT0_EXT + index;
  5201. }
  5202. index += 1;
  5203. }
  5204. for (int i=0; i<_current_properties->get_aux_hrgba(); i++) {
  5205. if (rbtype & (RenderBuffer::T_aux_hrgba_0 << i)) {
  5206. buffer = GL_COLOR_ATTACHMENT0_EXT + index;
  5207. }
  5208. index += 1;
  5209. }
  5210. for (int i=0; i<_current_properties->get_aux_float(); i++) {
  5211. if (rbtype & (RenderBuffer::T_aux_float_0 << i)) {
  5212. buffer = GL_COLOR_ATTACHMENT0_EXT + index;
  5213. }
  5214. index += 1;
  5215. }
  5216. GLP(ReadBuffer)(buffer);
  5217. } else {
  5218. switch (rbtype & RenderBuffer::T_color) {
  5219. case RenderBuffer::T_front:
  5220. GLP(ReadBuffer)(GL_FRONT);
  5221. break;
  5222. case RenderBuffer::T_back:
  5223. GLP(ReadBuffer)(GL_BACK);
  5224. break;
  5225. case RenderBuffer::T_right:
  5226. GLP(ReadBuffer)(GL_RIGHT);
  5227. break;
  5228. case RenderBuffer::T_left:
  5229. GLP(ReadBuffer)(GL_LEFT);
  5230. break;
  5231. case RenderBuffer::T_front_right:
  5232. GLP(ReadBuffer)(GL_FRONT_RIGHT);
  5233. break;
  5234. case RenderBuffer::T_front_left:
  5235. GLP(ReadBuffer)(GL_FRONT_LEFT);
  5236. break;
  5237. case RenderBuffer::T_back_right:
  5238. GLP(ReadBuffer)(GL_BACK_RIGHT);
  5239. break;
  5240. case RenderBuffer::T_back_left:
  5241. GLP(ReadBuffer)(GL_BACK_LEFT);
  5242. break;
  5243. default:
  5244. break;
  5245. }
  5246. }
  5247. report_my_gl_errors();
  5248. #endif // OPENGLES
  5249. }
  5250. ////////////////////////////////////////////////////////////////////
  5251. // Function: GLGraphicsStateGuardian::get_numeric_type
  5252. // Access: Protected, Static
  5253. // Description: Maps from the Geom's internal numeric type symbols
  5254. // to GL's.
  5255. ////////////////////////////////////////////////////////////////////
  5256. GLenum CLP(GraphicsStateGuardian)::
  5257. get_numeric_type(Geom::NumericType numeric_type) {
  5258. switch (numeric_type) {
  5259. case Geom::NT_uint16:
  5260. return GL_UNSIGNED_SHORT;
  5261. #ifndef OPENGLES_1
  5262. case Geom::NT_uint32:
  5263. return GL_UNSIGNED_INT;
  5264. #endif
  5265. case Geom::NT_uint8:
  5266. case Geom::NT_packed_dcba:
  5267. case Geom::NT_packed_dabc:
  5268. return GL_UNSIGNED_BYTE;
  5269. case Geom::NT_float32:
  5270. return GL_FLOAT;
  5271. #ifndef OPENGLES
  5272. case Geom::NT_float64:
  5273. return GL_DOUBLE;
  5274. #endif
  5275. }
  5276. GLCAT.error()
  5277. << "Invalid NumericType value (" << (int)numeric_type << ")\n";
  5278. return GL_UNSIGNED_BYTE;
  5279. }
  5280. ////////////////////////////////////////////////////////////////////
  5281. // Function: GLGraphicsStateGuardian::get_texture_target
  5282. // Access: Protected
  5283. // Description: Maps from the Texture's texture type symbols to
  5284. // GL's.
  5285. ////////////////////////////////////////////////////////////////////
  5286. GLenum CLP(GraphicsStateGuardian)::
  5287. get_texture_target(Texture::TextureType texture_type) const {
  5288. switch (texture_type) {
  5289. #ifndef OPENGLES
  5290. case Texture::TT_1d_texture:
  5291. return GL_TEXTURE_1D;
  5292. #endif
  5293. case Texture::TT_2d_texture:
  5294. return GL_TEXTURE_2D;
  5295. case Texture::TT_3d_texture:
  5296. if (_supports_3d_texture) {
  5297. #ifndef OPENGLES_1
  5298. return GL_TEXTURE_3D;
  5299. #endif
  5300. } else {
  5301. return GL_NONE;
  5302. }
  5303. case Texture::TT_2d_texture_array:
  5304. if (_supports_2d_texture_array) {
  5305. #ifndef OPENGLES
  5306. return GL_TEXTURE_2D_ARRAY_EXT;
  5307. #endif
  5308. } else {
  5309. return GL_NONE;
  5310. }
  5311. case Texture::TT_cube_map:
  5312. if (_supports_cube_map) {
  5313. return GL_TEXTURE_CUBE_MAP;
  5314. } else {
  5315. return GL_NONE;
  5316. }
  5317. }
  5318. GLCAT.error() << "Invalid Texture::TextureType value!\n";
  5319. return GL_TEXTURE_2D;
  5320. }
  5321. ////////////////////////////////////////////////////////////////////
  5322. // Function: GLGraphicsStateGuardian::get_texture_wrap_mode
  5323. // Access: Protected
  5324. // Description: Maps from the Texture's internal wrap mode symbols to
  5325. // GL's.
  5326. ////////////////////////////////////////////////////////////////////
  5327. GLenum CLP(GraphicsStateGuardian)::
  5328. get_texture_wrap_mode(Texture::WrapMode wm) const {
  5329. if (CLP(ignore_clamp)) {
  5330. return GL_REPEAT;
  5331. }
  5332. switch (wm) {
  5333. case Texture::WM_clamp:
  5334. return _edge_clamp;
  5335. case Texture::WM_repeat:
  5336. return GL_REPEAT;
  5337. case Texture::WM_mirror:
  5338. return _mirror_repeat;
  5339. case Texture::WM_mirror_once:
  5340. return _mirror_border_clamp;
  5341. case Texture::WM_border_color:
  5342. return _border_clamp;
  5343. case Texture::WM_invalid:
  5344. break;
  5345. }
  5346. GLCAT.error() << "Invalid Texture::WrapMode value!\n";
  5347. return _edge_clamp;
  5348. }
  5349. ////////////////////////////////////////////////////////////////////
  5350. // Function: GLGraphicsStateGuardian::get_panda_wrap_mode
  5351. // Access: Protected, Static
  5352. // Description: Maps from the GL's internal wrap mode symbols to
  5353. // Panda's.
  5354. ////////////////////////////////////////////////////////////////////
  5355. Texture::WrapMode CLP(GraphicsStateGuardian)::
  5356. get_panda_wrap_mode(GLenum wm) {
  5357. switch (wm) {
  5358. #ifndef OPENGLES
  5359. case GL_CLAMP:
  5360. #endif
  5361. case GL_CLAMP_TO_EDGE:
  5362. return Texture::WM_clamp;
  5363. #ifndef OPENGLES
  5364. case GL_CLAMP_TO_BORDER:
  5365. return Texture::WM_border_color;
  5366. #endif
  5367. case GL_REPEAT:
  5368. return Texture::WM_repeat;
  5369. #ifndef OPENGLES
  5370. case GL_MIRROR_CLAMP_EXT:
  5371. case GL_MIRROR_CLAMP_TO_EDGE_EXT:
  5372. return Texture::WM_mirror;
  5373. case GL_MIRROR_CLAMP_TO_BORDER_EXT:
  5374. return Texture::WM_mirror_once;
  5375. #endif
  5376. }
  5377. GLCAT.error() << "Unexpected GL wrap mode " << (int)wm << "\n";
  5378. return Texture::WM_clamp;
  5379. }
  5380. ////////////////////////////////////////////////////////////////////
  5381. // Function: GLGraphicsStateGuardian::get_texture_filter_type
  5382. // Access: Protected, Static
  5383. // Description: Maps from the Texture's internal filter type symbols
  5384. // to GL's.
  5385. ////////////////////////////////////////////////////////////////////
  5386. GLenum CLP(GraphicsStateGuardian)::
  5387. get_texture_filter_type(Texture::FilterType ft, bool ignore_mipmaps) {
  5388. if (CLP(ignore_filters)) {
  5389. return GL_NEAREST;
  5390. } else if (ignore_mipmaps) {
  5391. switch (ft) {
  5392. case Texture::FT_nearest_mipmap_nearest:
  5393. case Texture::FT_nearest:
  5394. return GL_NEAREST;
  5395. case Texture::FT_linear:
  5396. case Texture::FT_linear_mipmap_nearest:
  5397. case Texture::FT_nearest_mipmap_linear:
  5398. case Texture::FT_linear_mipmap_linear:
  5399. return GL_LINEAR;
  5400. case Texture::FT_shadow:
  5401. return GL_LINEAR;
  5402. case Texture::FT_default:
  5403. case Texture::FT_invalid:
  5404. break;
  5405. }
  5406. } else {
  5407. switch (ft) {
  5408. case Texture::FT_nearest:
  5409. return GL_NEAREST;
  5410. case Texture::FT_linear:
  5411. return GL_LINEAR;
  5412. case Texture::FT_nearest_mipmap_nearest:
  5413. return GL_NEAREST_MIPMAP_NEAREST;
  5414. case Texture::FT_linear_mipmap_nearest:
  5415. return GL_LINEAR_MIPMAP_NEAREST;
  5416. case Texture::FT_nearest_mipmap_linear:
  5417. return GL_NEAREST_MIPMAP_LINEAR;
  5418. case Texture::FT_linear_mipmap_linear:
  5419. return GL_LINEAR_MIPMAP_LINEAR;
  5420. case Texture::FT_shadow:
  5421. return GL_LINEAR;
  5422. case Texture::FT_default:
  5423. case Texture::FT_invalid:
  5424. break;
  5425. }
  5426. }
  5427. GLCAT.error() << "Invalid Texture::FilterType value!\n";
  5428. return GL_NEAREST;
  5429. }
  5430. ////////////////////////////////////////////////////////////////////
  5431. // Function: GLGraphicsStateGuardian::get_panda_filter_type
  5432. // Access: Protected, Static
  5433. // Description: Maps from the GL's internal filter type symbols
  5434. // to Panda's.
  5435. ////////////////////////////////////////////////////////////////////
  5436. Texture::FilterType CLP(GraphicsStateGuardian)::
  5437. get_panda_filter_type(GLenum ft) {
  5438. switch (ft) {
  5439. case GL_NEAREST:
  5440. return Texture::FT_nearest;
  5441. case GL_LINEAR:
  5442. return Texture::FT_linear;
  5443. case GL_NEAREST_MIPMAP_NEAREST:
  5444. return Texture::FT_nearest_mipmap_nearest;
  5445. case GL_LINEAR_MIPMAP_NEAREST:
  5446. return Texture::FT_linear_mipmap_nearest;
  5447. case GL_NEAREST_MIPMAP_LINEAR:
  5448. return Texture::FT_nearest_mipmap_linear;
  5449. case GL_LINEAR_MIPMAP_LINEAR:
  5450. return Texture::FT_linear_mipmap_linear;
  5451. }
  5452. GLCAT.error() << "Unexpected GL filter type " << (int)ft << "\n";
  5453. return Texture::FT_linear;
  5454. }
  5455. ////////////////////////////////////////////////////////////////////
  5456. // Function: GLGraphicsStateGuardian::get_component_type
  5457. // Access: Protected, Static
  5458. // Description: Maps from the Texture's internal ComponentType symbols
  5459. // to GL's.
  5460. ////////////////////////////////////////////////////////////////////
  5461. GLenum CLP(GraphicsStateGuardian)::
  5462. get_component_type(Texture::ComponentType component_type) {
  5463. switch (component_type) {
  5464. case Texture::T_unsigned_byte:
  5465. return GL_UNSIGNED_BYTE;
  5466. case Texture::T_unsigned_short:
  5467. return GL_UNSIGNED_SHORT;
  5468. case Texture::T_float:
  5469. return GL_FLOAT;
  5470. case Texture::T_unsigned_int_24_8:
  5471. #ifdef OPENGLES_2
  5472. return GL_UNSIGNED_BYTE;
  5473. #else
  5474. if (_supports_depth_stencil) {
  5475. return GL_UNSIGNED_INT_24_8_EXT;
  5476. } else {
  5477. return GL_UNSIGNED_BYTE;
  5478. }
  5479. #endif // OPENGLES_2
  5480. default:
  5481. GLCAT.error() << "Invalid Texture::Type value!\n";
  5482. return GL_UNSIGNED_BYTE;
  5483. }
  5484. }
  5485. ////////////////////////////////////////////////////////////////////
  5486. // Function: GLGraphicsStateGuardian::get_external_image_format
  5487. // Access: Protected
  5488. // Description: Maps from the Texture's Format symbols
  5489. // to GL's.
  5490. ////////////////////////////////////////////////////////////////////
  5491. GLint CLP(GraphicsStateGuardian)::
  5492. get_external_image_format(Texture *tex) const {
  5493. Texture::CompressionMode compression = tex->get_ram_image_compression();
  5494. if (compression != Texture::CM_off &&
  5495. get_supports_compressed_texture_format(compression)) {
  5496. switch (compression) {
  5497. case Texture::CM_on:
  5498. #ifndef OPENGLES
  5499. switch (tex->get_format()) {
  5500. case Texture::F_color_index:
  5501. case Texture::F_depth_component:
  5502. case Texture::F_depth_stencil:
  5503. // This shouldn't be possible.
  5504. nassertr(false, GL_RGB);
  5505. break;
  5506. case Texture::F_rgba:
  5507. case Texture::F_rgbm:
  5508. case Texture::F_rgba4:
  5509. case Texture::F_rgba8:
  5510. case Texture::F_rgba12:
  5511. return GL_COMPRESSED_RGBA;
  5512. case Texture::F_rgb:
  5513. case Texture::F_rgb5:
  5514. case Texture::F_rgba5:
  5515. case Texture::F_rgb8:
  5516. case Texture::F_rgb12:
  5517. case Texture::F_rgb332:
  5518. return GL_COMPRESSED_RGB;
  5519. case Texture::F_alpha:
  5520. return GL_COMPRESSED_ALPHA;
  5521. case Texture::F_red:
  5522. case Texture::F_green:
  5523. case Texture::F_blue:
  5524. case Texture::F_luminance:
  5525. return GL_COMPRESSED_LUMINANCE;
  5526. case Texture::F_luminance_alpha:
  5527. case Texture::F_luminance_alphamask:
  5528. return GL_COMPRESSED_LUMINANCE_ALPHA;
  5529. }
  5530. #endif
  5531. break;
  5532. #ifndef OPENGLES_1
  5533. case Texture::CM_dxt1:
  5534. if (Texture::has_alpha(tex->get_format())) {
  5535. return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
  5536. } else {
  5537. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  5538. }
  5539. #endif
  5540. #ifndef OPENGLES
  5541. case Texture::CM_dxt3:
  5542. return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
  5543. case Texture::CM_dxt5:
  5544. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  5545. case Texture::CM_fxt1:
  5546. if (Texture::has_alpha(tex->get_format())) {
  5547. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  5548. } else {
  5549. return GL_COMPRESSED_RGB_FXT1_3DFX;
  5550. }
  5551. #else
  5552. case Texture::CM_pvr1_2bpp:
  5553. if (Texture::has_alpha(tex->get_format())) {
  5554. return GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
  5555. } else {
  5556. return GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
  5557. }
  5558. case Texture::CM_pvr1_4bpp:
  5559. if (Texture::has_alpha(tex->get_format())) {
  5560. return GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
  5561. } else {
  5562. return GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
  5563. }
  5564. #endif
  5565. case Texture::CM_default:
  5566. case Texture::CM_off:
  5567. case Texture::CM_dxt2:
  5568. case Texture::CM_dxt4:
  5569. // This shouldn't happen.
  5570. nassertr(false, GL_RGB);
  5571. break;
  5572. }
  5573. }
  5574. switch (tex->get_format()) {
  5575. #ifndef OPENGLES
  5576. case Texture::F_color_index:
  5577. return GL_COLOR_INDEX;
  5578. #endif
  5579. case Texture::F_depth_component:
  5580. return GL_DEPTH_COMPONENT;
  5581. case Texture::F_depth_stencil:
  5582. #ifndef OPENGLES_2
  5583. if (CLP(force_depth_stencil)) {
  5584. return GL_DEPTH_STENCIL_EXT;
  5585. } else {
  5586. #endif
  5587. return GL_DEPTH_COMPONENT;
  5588. #ifndef OPENGLES_2
  5589. }
  5590. #endif
  5591. #ifndef OPENGLES
  5592. case Texture::F_red:
  5593. return GL_RED;
  5594. case Texture::F_green:
  5595. return GL_GREEN;
  5596. case Texture::F_blue:
  5597. return GL_BLUE;
  5598. #endif
  5599. case Texture::F_alpha:
  5600. return GL_ALPHA;
  5601. case Texture::F_rgb:
  5602. case Texture::F_rgb5:
  5603. case Texture::F_rgb8:
  5604. case Texture::F_rgb12:
  5605. case Texture::F_rgb332:
  5606. #ifdef OPENGLES
  5607. return GL_RGB;
  5608. #else
  5609. return _supports_bgr ? GL_BGR : GL_RGB;
  5610. #endif
  5611. case Texture::F_rgba:
  5612. case Texture::F_rgbm:
  5613. case Texture::F_rgba4:
  5614. case Texture::F_rgba5:
  5615. case Texture::F_rgba8:
  5616. case Texture::F_rgba12:
  5617. case Texture::F_rgba16:
  5618. case Texture::F_rgba32:
  5619. #ifdef OPENGLES_2
  5620. return GL_RGBA;
  5621. #else
  5622. return _supports_bgr ? GL_BGRA : GL_RGBA;
  5623. #endif
  5624. case Texture::F_luminance:
  5625. return GL_LUMINANCE;
  5626. case Texture::F_luminance_alphamask:
  5627. case Texture::F_luminance_alpha:
  5628. return GL_LUMINANCE_ALPHA;
  5629. }
  5630. GLCAT.error()
  5631. << "Invalid Texture::Format value in get_external_image_format(): "
  5632. << (int)tex->get_format() << "\n";
  5633. return GL_RGB;
  5634. }
  5635. ////////////////////////////////////////////////////////////////////
  5636. // Function: GLGraphicsStateGuardian::get_internal_image_format
  5637. // Access: Protected
  5638. // Description: Maps from the Texture's Format symbols to a
  5639. // suitable internal format for GL textures.
  5640. ////////////////////////////////////////////////////////////////////
  5641. GLint CLP(GraphicsStateGuardian)::
  5642. get_internal_image_format(Texture *tex) const {
  5643. Texture::CompressionMode compression = tex->get_compression();
  5644. if (compression == Texture::CM_default) {
  5645. compression = (compressed_textures) ? Texture::CM_on : Texture::CM_off;
  5646. }
  5647. if (tex->get_render_to_texture()) {
  5648. // no compression for render targets
  5649. compression = Texture::CM_off;
  5650. }
  5651. bool is_3d = (tex->get_texture_type() == Texture::TT_3d_texture ||
  5652. tex->get_texture_type() == Texture::TT_2d_texture_array);
  5653. if (get_supports_compressed_texture_format(compression)) {
  5654. switch (compression) {
  5655. // For now, we don't support generic compression with OpenGL ES.
  5656. #ifndef OPENGLES
  5657. case Texture::CM_on:
  5658. // The user asked for just generic compression. OpenGL supports
  5659. // requesting just generic compression, but we'd like to go ahead
  5660. // and request a specific type (if we can figure out an
  5661. // appropriate choice), since that makes saving the result as a
  5662. // pre-compressed texture more dependable--this way, we will know
  5663. // which compression algorithm was applied.
  5664. switch (tex->get_format()) {
  5665. case Texture::F_color_index:
  5666. case Texture::F_depth_component:
  5667. case Texture::F_depth_stencil:
  5668. // Unsupported; fall through to below.
  5669. break;
  5670. case Texture::F_rgbm:
  5671. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  5672. return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
  5673. } else if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  5674. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  5675. }
  5676. return GL_COMPRESSED_RGBA;
  5677. case Texture::F_rgba4:
  5678. if (get_supports_compressed_texture_format(Texture::CM_dxt3) && !is_3d) {
  5679. return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
  5680. } else if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  5681. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  5682. }
  5683. return GL_COMPRESSED_RGBA;
  5684. case Texture::F_rgba:
  5685. case Texture::F_rgba8:
  5686. case Texture::F_rgba12:
  5687. if (get_supports_compressed_texture_format(Texture::CM_dxt5) && !is_3d) {
  5688. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  5689. } else if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  5690. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  5691. }
  5692. return GL_COMPRESSED_RGBA;
  5693. case Texture::F_rgb:
  5694. case Texture::F_rgb5:
  5695. case Texture::F_rgba5:
  5696. case Texture::F_rgb8:
  5697. case Texture::F_rgb12:
  5698. case Texture::F_rgb332:
  5699. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  5700. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  5701. } else if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  5702. return GL_COMPRESSED_RGB_FXT1_3DFX;
  5703. }
  5704. return GL_COMPRESSED_RGB;
  5705. case Texture::F_alpha:
  5706. if (get_supports_compressed_texture_format(Texture::CM_dxt5) && !is_3d) {
  5707. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  5708. } else if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  5709. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  5710. }
  5711. return GL_COMPRESSED_ALPHA;
  5712. case Texture::F_red:
  5713. case Texture::F_green:
  5714. case Texture::F_blue:
  5715. case Texture::F_luminance:
  5716. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  5717. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  5718. } else if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  5719. return GL_COMPRESSED_RGB_FXT1_3DFX;
  5720. }
  5721. return GL_COMPRESSED_LUMINANCE;
  5722. case Texture::F_luminance_alpha:
  5723. case Texture::F_luminance_alphamask:
  5724. if (get_supports_compressed_texture_format(Texture::CM_dxt5) && !is_3d) {
  5725. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  5726. } else if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  5727. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  5728. }
  5729. return GL_COMPRESSED_LUMINANCE_ALPHA;
  5730. }
  5731. break;
  5732. #endif
  5733. #ifndef OPENGLES_1
  5734. case Texture::CM_dxt1:
  5735. if (Texture::has_alpha(tex->get_format())) {
  5736. return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
  5737. } else {
  5738. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  5739. }
  5740. #endif
  5741. #ifndef OPENGLES
  5742. case Texture::CM_dxt3:
  5743. return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
  5744. case Texture::CM_dxt5:
  5745. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  5746. case Texture::CM_fxt1:
  5747. if (Texture::has_alpha(tex->get_format())) {
  5748. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  5749. } else {
  5750. return GL_COMPRESSED_RGB_FXT1_3DFX;
  5751. }
  5752. #else
  5753. case Texture::CM_pvr1_2bpp:
  5754. if (Texture::has_alpha(tex->get_format())) {
  5755. return GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
  5756. } else {
  5757. return GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
  5758. }
  5759. case Texture::CM_pvr1_4bpp:
  5760. if (Texture::has_alpha(tex->get_format())) {
  5761. return GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
  5762. } else {
  5763. return GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
  5764. }
  5765. #endif
  5766. case Texture::CM_default:
  5767. case Texture::CM_off:
  5768. case Texture::CM_dxt2:
  5769. case Texture::CM_dxt4:
  5770. // No compression: fall through to below.
  5771. break;
  5772. }
  5773. }
  5774. switch (tex->get_format()) {
  5775. #ifndef OPENGLES
  5776. case Texture::F_color_index:
  5777. return GL_COLOR_INDEX;
  5778. #endif
  5779. case Texture::F_depth_component:
  5780. return GL_DEPTH_COMPONENT;
  5781. case Texture::F_depth_component16:
  5782. #ifdef OPENGLES_1
  5783. return GL_DEPTH_COMPONENT16_OES;
  5784. #else
  5785. return GL_DEPTH_COMPONENT16;
  5786. #endif
  5787. case Texture::F_depth_component24:
  5788. #ifdef OPENGLES
  5789. return GL_DEPTH_COMPONENT24_OES;
  5790. case Texture::F_depth_component32:
  5791. return GL_DEPTH_COMPONENT32_OES;
  5792. #else
  5793. return GL_DEPTH_COMPONENT24;
  5794. case Texture::F_depth_component32:
  5795. return GL_DEPTH_COMPONENT32;
  5796. #endif
  5797. case Texture::F_depth_stencil:
  5798. #ifndef OPENGLES_2
  5799. if (_supports_depth_stencil) {
  5800. return GL_DEPTH_STENCIL_EXT;
  5801. } else {
  5802. return GL_DEPTH_COMPONENT;
  5803. }
  5804. #else
  5805. return GL_DEPTH_COMPONENT;
  5806. #endif
  5807. case Texture::F_rgba:
  5808. case Texture::F_rgbm:
  5809. return GL_RGBA;
  5810. case Texture::F_rgba4:
  5811. return GL_RGBA4;
  5812. #ifdef OPENGLES
  5813. case Texture::F_rgba8:
  5814. case Texture::F_rgba12:
  5815. case Texture::F_rgba16:
  5816. case Texture::F_rgba32:
  5817. return GL_RGBA;
  5818. #else
  5819. case Texture::F_rgba8:
  5820. return GL_RGBA8;
  5821. case Texture::F_rgba12:
  5822. return GL_RGBA12;
  5823. case Texture::F_rgba16:
  5824. return GL_RGBA16F_ARB;
  5825. case Texture::F_rgba32:
  5826. return GL_RGBA32F_ARB;
  5827. #endif // OPENGLES
  5828. case Texture::F_rgb:
  5829. return GL_RGB;
  5830. #ifndef OPENGLES
  5831. case Texture::F_rgb5:
  5832. return GL_RGB5;
  5833. #endif
  5834. case Texture::F_rgba5:
  5835. return GL_RGB5_A1;
  5836. #ifdef OPENGLES
  5837. case Texture::F_rgb8:
  5838. case Texture::F_rgb12:
  5839. return GL_RGB;
  5840. #else
  5841. case Texture::F_rgb8:
  5842. return GL_RGB8;
  5843. case Texture::F_rgb12:
  5844. return GL_RGB12;
  5845. #endif // OPENGLES
  5846. #ifndef OPENGLES
  5847. case Texture::F_rgb332:
  5848. return GL_R3_G3_B2;
  5849. #endif
  5850. case Texture::F_alpha:
  5851. return GL_ALPHA;
  5852. case Texture::F_red:
  5853. case Texture::F_green:
  5854. case Texture::F_blue:
  5855. case Texture::F_luminance:
  5856. return GL_LUMINANCE;
  5857. case Texture::F_luminance_alpha:
  5858. case Texture::F_luminance_alphamask:
  5859. return GL_LUMINANCE_ALPHA;
  5860. default:
  5861. GLCAT.error()
  5862. << "Invalid image format in get_internal_image_format(): "
  5863. << (int)tex->get_format() << "\n";
  5864. return GL_RGB;
  5865. }
  5866. }
  5867. ////////////////////////////////////////////////////////////////////
  5868. // Function: GLGraphicsStateGuardian::is_mipmap_filter
  5869. // Access: Protected, Static
  5870. // Description: Returns true if the indicated GL minfilter type
  5871. // represents a mipmap format, false otherwise.
  5872. ////////////////////////////////////////////////////////////////////
  5873. bool CLP(GraphicsStateGuardian)::
  5874. is_mipmap_filter(GLenum min_filter) {
  5875. switch (min_filter) {
  5876. case GL_NEAREST_MIPMAP_NEAREST:
  5877. case GL_LINEAR_MIPMAP_NEAREST:
  5878. case GL_NEAREST_MIPMAP_LINEAR:
  5879. case GL_LINEAR_MIPMAP_LINEAR:
  5880. return true;
  5881. default:
  5882. return false;
  5883. }
  5884. }
  5885. ////////////////////////////////////////////////////////////////////
  5886. // Function: GLGraphicsStateGuardian::is_compressed_format
  5887. // Access: Protected, Static
  5888. // Description: Returns true if the indicated GL internal format
  5889. // represents a compressed texture format, false
  5890. // otherwise.
  5891. ////////////////////////////////////////////////////////////////////
  5892. bool CLP(GraphicsStateGuardian)::
  5893. is_compressed_format(GLenum format) {
  5894. switch (format) {
  5895. #ifndef OPENGLES_1
  5896. case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  5897. case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  5898. #endif
  5899. #ifdef OPENGLES
  5900. case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
  5901. case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
  5902. case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
  5903. case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
  5904. #else
  5905. case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
  5906. case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
  5907. case GL_COMPRESSED_RGB_FXT1_3DFX:
  5908. case GL_COMPRESSED_RGBA_FXT1_3DFX:
  5909. case GL_COMPRESSED_RGB:
  5910. case GL_COMPRESSED_RGBA:
  5911. case GL_COMPRESSED_ALPHA:
  5912. case GL_COMPRESSED_LUMINANCE:
  5913. case GL_COMPRESSED_LUMINANCE_ALPHA:
  5914. #endif
  5915. return true;
  5916. default:
  5917. return false;
  5918. }
  5919. }
  5920. ////////////////////////////////////////////////////////////////////
  5921. // Function: GLGraphicsStateGuardian::get_texture_apply_mode_type
  5922. // Access: Protected, Static
  5923. // Description: Maps from the texture stage's mode types
  5924. // to the corresponding OpenGL ids
  5925. ////////////////////////////////////////////////////////////////////
  5926. GLint CLP(GraphicsStateGuardian)::
  5927. get_texture_apply_mode_type(TextureStage::Mode am) {
  5928. #ifndef OPENGLES_2
  5929. switch (am) {
  5930. case TextureStage::M_modulate: return GL_MODULATE;
  5931. case TextureStage::M_decal: return GL_DECAL;
  5932. case TextureStage::M_blend: return GL_BLEND;
  5933. case TextureStage::M_replace: return GL_REPLACE;
  5934. case TextureStage::M_add: return GL_ADD;
  5935. case TextureStage::M_combine: return GL_COMBINE;
  5936. case TextureStage::M_blend_color_scale: return GL_BLEND;
  5937. case TextureStage::M_modulate_glow: return GL_MODULATE;
  5938. case TextureStage::M_modulate_gloss: return GL_MODULATE;
  5939. }
  5940. GLCAT.error()
  5941. << "Invalid TextureStage::Mode value" << endl;
  5942. return GL_MODULATE;
  5943. #else
  5944. return 0;
  5945. #endif
  5946. }
  5947. ////////////////////////////////////////////////////////////////////
  5948. // Function: GLGraphicsStateGuardian::get_texture_combine_type
  5949. // Access: Protected, Static
  5950. // Description: Maps from the texture stage's CombineMode types
  5951. // to the corresponding OpenGL ids
  5952. ////////////////////////////////////////////////////////////////////
  5953. GLint CLP(GraphicsStateGuardian)::
  5954. get_texture_combine_type(TextureStage::CombineMode cm) {
  5955. #ifndef OPENGLES_2
  5956. switch (cm) {
  5957. case TextureStage::CM_undefined: // fall through
  5958. case TextureStage::CM_replace: return GL_REPLACE;
  5959. case TextureStage::CM_modulate: return GL_MODULATE;
  5960. case TextureStage::CM_add: return GL_ADD;
  5961. case TextureStage::CM_add_signed: return GL_ADD_SIGNED;
  5962. case TextureStage::CM_interpolate: return GL_INTERPOLATE;
  5963. case TextureStage::CM_subtract: return GL_SUBTRACT;
  5964. case TextureStage::CM_dot3_rgb: return GL_DOT3_RGB;
  5965. case TextureStage::CM_dot3_rgba: return GL_DOT3_RGBA;
  5966. }
  5967. GLCAT.error()
  5968. << "Invalid TextureStage::CombineMode value" << endl;
  5969. #endif
  5970. return GL_REPLACE;
  5971. }
  5972. ////////////////////////////////////////////////////////////////////
  5973. // Function: GLGraphicsStateGuardian::get_texture_src_type
  5974. // Access: Protected
  5975. // Description: Maps from the texture stage's CombineSource types
  5976. // to the corresponding OpenGL ids
  5977. ////////////////////////////////////////////////////////////////////
  5978. GLint CLP(GraphicsStateGuardian)::
  5979. get_texture_src_type(TextureStage::CombineSource cs,
  5980. int last_stage, int last_saved_result,
  5981. int this_stage) const {
  5982. #ifndef OPENGLES_2
  5983. switch (cs) {
  5984. case TextureStage::CS_undefined: // fall through
  5985. case TextureStage::CS_texture: return GL_TEXTURE;
  5986. case TextureStage::CS_constant: return GL_CONSTANT;
  5987. case TextureStage::CS_primary_color: return GL_PRIMARY_COLOR;
  5988. case TextureStage::CS_constant_color_scale: return GL_CONSTANT;
  5989. case TextureStage::CS_previous:
  5990. if (last_stage == this_stage - 1) {
  5991. return GL_PREVIOUS;
  5992. } else if (last_stage == -1) {
  5993. return GL_PRIMARY_COLOR;
  5994. } else if (_supports_texture_saved_result) {
  5995. return GL_TEXTURE0 + last_stage;
  5996. } else {
  5997. GLCAT.warning()
  5998. << "Current OpenGL driver does not support texture crossbar blending.\n";
  5999. return GL_PRIMARY_COLOR;
  6000. }
  6001. case TextureStage::CS_last_saved_result:
  6002. if (last_saved_result == this_stage - 1) {
  6003. return GL_PREVIOUS;
  6004. } else if (last_saved_result == -1) {
  6005. return GL_PRIMARY_COLOR;
  6006. } else if (_supports_texture_saved_result) {
  6007. return GL_TEXTURE0 + last_saved_result;
  6008. } else {
  6009. GLCAT.warning()
  6010. << "Current OpenGL driver does not support texture crossbar blending.\n";
  6011. return GL_PRIMARY_COLOR;
  6012. }
  6013. }
  6014. GLCAT.error()
  6015. << "Invalid TextureStage::CombineSource value" << endl;
  6016. #endif
  6017. return GL_TEXTURE;
  6018. }
  6019. ////////////////////////////////////////////////////////////////////
  6020. // Function: GLGraphicsStateGuardian::get_texture_operand_type
  6021. // Access: Protected, Static
  6022. // Description: Maps from the texture stage's CombineOperand types
  6023. // to the corresponding OpenGL ids
  6024. ////////////////////////////////////////////////////////////////////
  6025. GLint CLP(GraphicsStateGuardian)::
  6026. get_texture_operand_type(TextureStage::CombineOperand co) {
  6027. switch (co) {
  6028. case TextureStage::CO_undefined: // fall through
  6029. case TextureStage::CO_src_alpha: return GL_SRC_ALPHA;
  6030. case TextureStage::CO_one_minus_src_alpha: return GL_ONE_MINUS_SRC_ALPHA;
  6031. case TextureStage::CO_src_color: return GL_SRC_COLOR;
  6032. case TextureStage::CO_one_minus_src_color: return GL_ONE_MINUS_SRC_COLOR;
  6033. }
  6034. GLCAT.error()
  6035. << "Invalid TextureStage::CombineOperand value" << endl;
  6036. return GL_SRC_COLOR;
  6037. }
  6038. ////////////////////////////////////////////////////////////////////
  6039. // Function: GLGraphicsStateGuardian::get_fog_mode_type
  6040. // Access: Protected, Static
  6041. // Description: Maps from the fog types to gl version
  6042. ////////////////////////////////////////////////////////////////////
  6043. GLenum CLP(GraphicsStateGuardian)::
  6044. get_fog_mode_type(Fog::Mode m) {
  6045. switch(m) {
  6046. case Fog::M_linear: return GL_LINEAR;
  6047. #ifndef OPENGLES_2
  6048. case Fog::M_exponential: return GL_EXP;
  6049. case Fog::M_exponential_squared: return GL_EXP2;
  6050. #endif
  6051. /*
  6052. case Fog::M_spline: return GL_FOG_FUNC_SGIS;
  6053. */
  6054. default:
  6055. GLCAT.error() << "Invalid Fog::Mode value" << endl;
  6056. #ifdef OPENGLES_2
  6057. return GL_LINEAR;
  6058. #else
  6059. return GL_EXP;
  6060. #endif
  6061. }
  6062. }
  6063. ////////////////////////////////////////////////////////////////////
  6064. // Function: GLGraphicsStateGuardian::get_blend_equation_type
  6065. // Access: Protected, Static
  6066. // Description: Maps from ColorBlendAttrib::Mode to glBlendEquation
  6067. // value.
  6068. ////////////////////////////////////////////////////////////////////
  6069. GLenum CLP(GraphicsStateGuardian)::
  6070. get_blend_equation_type(ColorBlendAttrib::Mode mode) {
  6071. switch (mode) {
  6072. case ColorBlendAttrib::M_none:
  6073. case ColorBlendAttrib::M_add:
  6074. return GL_FUNC_ADD;
  6075. case ColorBlendAttrib::M_subtract:
  6076. return GL_FUNC_SUBTRACT;
  6077. case ColorBlendAttrib::M_inv_subtract:
  6078. return GL_FUNC_REVERSE_SUBTRACT;
  6079. #ifndef OPENGLES
  6080. case ColorBlendAttrib::M_min:
  6081. return GL_MIN;
  6082. case ColorBlendAttrib::M_max:
  6083. return GL_MAX;
  6084. #endif
  6085. }
  6086. GLCAT.error()
  6087. << "Unknown color blend mode " << (int)mode << endl;
  6088. return GL_FUNC_ADD;
  6089. }
  6090. ////////////////////////////////////////////////////////////////////
  6091. // Function: GLGraphicsStateGuardian::get_blend_func
  6092. // Access: Protected, Static
  6093. // Description: Maps from ColorBlendAttrib::Operand to glBlendFunc
  6094. // value.
  6095. ////////////////////////////////////////////////////////////////////
  6096. GLenum CLP(GraphicsStateGuardian)::
  6097. get_blend_func(ColorBlendAttrib::Operand operand) {
  6098. switch (operand) {
  6099. case ColorBlendAttrib::O_zero:
  6100. return GL_ZERO;
  6101. case ColorBlendAttrib::O_one:
  6102. return GL_ONE;
  6103. case ColorBlendAttrib::O_incoming_color:
  6104. return GL_SRC_COLOR;
  6105. case ColorBlendAttrib::O_one_minus_incoming_color:
  6106. return GL_ONE_MINUS_SRC_COLOR;
  6107. case ColorBlendAttrib::O_fbuffer_color:
  6108. return GL_DST_COLOR;
  6109. case ColorBlendAttrib::O_one_minus_fbuffer_color:
  6110. return GL_ONE_MINUS_DST_COLOR;
  6111. case ColorBlendAttrib::O_incoming_alpha:
  6112. return GL_SRC_ALPHA;
  6113. case ColorBlendAttrib::O_one_minus_incoming_alpha:
  6114. return GL_ONE_MINUS_SRC_ALPHA;
  6115. case ColorBlendAttrib::O_fbuffer_alpha:
  6116. return GL_DST_ALPHA;
  6117. case ColorBlendAttrib::O_one_minus_fbuffer_alpha:
  6118. return GL_ONE_MINUS_DST_ALPHA;
  6119. #ifndef OPENGLES_1
  6120. case ColorBlendAttrib::O_constant_color:
  6121. case ColorBlendAttrib::O_color_scale:
  6122. return GL_CONSTANT_COLOR;
  6123. case ColorBlendAttrib::O_one_minus_constant_color:
  6124. case ColorBlendAttrib::O_one_minus_color_scale:
  6125. return GL_ONE_MINUS_CONSTANT_COLOR;
  6126. case ColorBlendAttrib::O_constant_alpha:
  6127. case ColorBlendAttrib::O_alpha_scale:
  6128. return GL_CONSTANT_ALPHA;
  6129. case ColorBlendAttrib::O_one_minus_constant_alpha:
  6130. case ColorBlendAttrib::O_one_minus_alpha_scale:
  6131. return GL_ONE_MINUS_CONSTANT_ALPHA;
  6132. #endif
  6133. case ColorBlendAttrib::O_incoming_color_saturate:
  6134. return GL_SRC_ALPHA_SATURATE;
  6135. }
  6136. GLCAT.error()
  6137. << "Unknown color blend operand " << (int)operand << endl;
  6138. return GL_ZERO;
  6139. }
  6140. ////////////////////////////////////////////////////////////////////
  6141. // Function: GLGraphicsStateGuardian::get_usage
  6142. // Access: Public, Static
  6143. // Description: Maps from UsageHint to the GL symbol.
  6144. ////////////////////////////////////////////////////////////////////
  6145. GLenum CLP(GraphicsStateGuardian)::
  6146. get_usage(Geom::UsageHint usage_hint) {
  6147. switch (usage_hint) {
  6148. case Geom::UH_stream:
  6149. #ifdef OPENGLES
  6150. return GL_DYNAMIC_DRAW;
  6151. #else
  6152. return GL_STREAM_DRAW;
  6153. #endif // OPENGLES
  6154. case Geom::UH_static:
  6155. case Geom::UH_unspecified:
  6156. return GL_STATIC_DRAW;
  6157. case Geom::UH_dynamic:
  6158. return GL_DYNAMIC_DRAW;
  6159. case Geom::UH_client:
  6160. break;
  6161. }
  6162. GLCAT.error()
  6163. << "Unexpected usage_hint " << (int)usage_hint << endl;
  6164. return GL_STATIC_DRAW;
  6165. }
  6166. ////////////////////////////////////////////////////////////////////
  6167. // Function: GLGraphicsStateGuardian::print_gfx_visual
  6168. // Access: Public
  6169. // Description: Prints a description of the current visual selected.
  6170. ////////////////////////////////////////////////////////////////////
  6171. void CLP(GraphicsStateGuardian)::
  6172. print_gfx_visual() {
  6173. GLint i;
  6174. GLboolean j;
  6175. cout << "Graphics Visual Info (# bits of each):" << endl;
  6176. cout << "RGBA: ";
  6177. GLP(GetIntegerv)( GL_RED_BITS, &i ); cout << i << " ";
  6178. GLP(GetIntegerv)( GL_GREEN_BITS, &i ); cout << i << " ";
  6179. GLP(GetIntegerv)( GL_BLUE_BITS, &i ); cout << i << " ";
  6180. GLP(GetIntegerv)( GL_ALPHA_BITS, &i ); cout << i << endl;
  6181. #ifndef OPENGLES
  6182. cout << "Accum RGBA: ";
  6183. GLP(GetIntegerv)( GL_ACCUM_RED_BITS, &i ); cout << i << " ";
  6184. GLP(GetIntegerv)( GL_ACCUM_GREEN_BITS, &i ); cout << i << " ";
  6185. GLP(GetIntegerv)( GL_ACCUM_BLUE_BITS, &i ); cout << i << " ";
  6186. GLP(GetIntegerv)( GL_ACCUM_ALPHA_BITS, &i ); cout << i << endl;
  6187. GLP(GetIntegerv)( GL_INDEX_BITS, &i ); cout << "Color Index: " << i << endl;
  6188. #endif
  6189. GLP(GetIntegerv)( GL_DEPTH_BITS, &i ); cout << "Depth: " << i << endl;
  6190. GLP(GetIntegerv)( GL_ALPHA_BITS, &i ); cout << "Alpha: " << i << endl;
  6191. GLP(GetIntegerv)( GL_STENCIL_BITS, &i ); cout << "Stencil: " << i << endl;
  6192. #ifndef OPENGLES
  6193. GLP(GetBooleanv)( GL_DOUBLEBUFFER, &j ); cout << "DoubleBuffer? "
  6194. << (int)j << endl;
  6195. GLP(GetBooleanv)( GL_STEREO, &j ); cout << "Stereo? " << (int)j << endl;
  6196. #endif
  6197. if (_supports_multisample) {
  6198. #ifndef OPENGLES_2
  6199. GLP(GetBooleanv)( GL_MULTISAMPLE, &j ); cout << "Multisample? " << (int)j << endl;
  6200. #endif
  6201. GLP(GetIntegerv)( GL_SAMPLES, &i ); cout << "Samples: " << i << endl;
  6202. }
  6203. GLP(GetBooleanv)( GL_BLEND, &j ); cout << "Blend? " << (int)j << endl;
  6204. #ifndef OPENGLES_2
  6205. GLP(GetBooleanv)( GL_POINT_SMOOTH, &j ); cout << "Point Smooth? "
  6206. << (int)j << endl;
  6207. GLP(GetBooleanv)( GL_LINE_SMOOTH, &j ); cout << "Line Smooth? "
  6208. << (int)j << endl;
  6209. #endif
  6210. #ifndef OPENGLES
  6211. GLP(GetIntegerv)( GL_AUX_BUFFERS, &i ); cout << "Aux Buffers: " << i << endl;
  6212. #endif
  6213. }
  6214. ////////////////////////////////////////////////////////////////////
  6215. // Function: GLGraphicsStateGuardian::get_light_color
  6216. // Access: Public
  6217. // Description: Returns the value that that should be issued as the
  6218. // light's color, as scaled by the current value of
  6219. // _light_color_scale, in the case of
  6220. // color_scale_via_lighting.
  6221. ////////////////////////////////////////////////////////////////////
  6222. LVecBase4 CLP(GraphicsStateGuardian)::
  6223. get_light_color(Light *light) const {
  6224. #ifndef NDEBUG
  6225. if (_show_texture_usage) {
  6226. // In show_texture_usage mode, all lights are white, so as not to
  6227. // contaminate the texture color.
  6228. return LVecBase4(1.0, 1.0, 1.0, 1.0);
  6229. }
  6230. #endif // NDEBUG
  6231. const LColor &c = light->get_color();
  6232. LVecBase4 light_color(c[0] * _light_color_scale[0],
  6233. c[1] * _light_color_scale[1],
  6234. c[2] * _light_color_scale[2],
  6235. c[3] * _light_color_scale[3]);
  6236. return light_color;
  6237. }
  6238. ////////////////////////////////////////////////////////////////////
  6239. // Function: GLGraphicsStateGuardian::reissue_transforms
  6240. // Access: Protected, Virtual
  6241. // Description: Called by clear_state_and_transform() to ensure that
  6242. // the current modelview and projection matrices are
  6243. // properly loaded in the graphics state, after a
  6244. // callback might have mucked them up.
  6245. ////////////////////////////////////////////////////////////////////
  6246. void CLP(GraphicsStateGuardian)::
  6247. reissue_transforms() {
  6248. prepare_lens();
  6249. do_issue_transform();
  6250. }
  6251. ////////////////////////////////////////////////////////////////////
  6252. // Function: GLGraphicsStateGuardian::enable_lighting
  6253. // Access: Protected, Virtual
  6254. // Description: Intended to be overridden by a derived class to
  6255. // enable or disable the use of lighting overall. This
  6256. // is called by do_issue_light() according to whether any
  6257. // lights are in use or not.
  6258. ////////////////////////////////////////////////////////////////////
  6259. void CLP(GraphicsStateGuardian)::
  6260. enable_lighting(bool enable) {
  6261. #ifndef OPENGLES_2
  6262. // static PStatCollector _draw_set_state_light_enable_lighting_pcollector("Draw:Set State:Light:Enable lighting");
  6263. // PStatTimer timer(_draw_set_state_light_enable_lighting_pcollector);
  6264. if (enable) {
  6265. GLP(Enable)(GL_LIGHTING);
  6266. } else {
  6267. GLP(Disable)(GL_LIGHTING);
  6268. }
  6269. #endif
  6270. }
  6271. ////////////////////////////////////////////////////////////////////
  6272. // Function: GLGraphicsStateGuardian::set_ambient_light
  6273. // Access: Protected, Virtual
  6274. // Description: Intended to be overridden by a derived class to
  6275. // indicate the color of the ambient light that should
  6276. // be in effect. This is called by do_issue_light() after
  6277. // all other lights have been enabled or disabled.
  6278. ////////////////////////////////////////////////////////////////////
  6279. void CLP(GraphicsStateGuardian)::
  6280. set_ambient_light(const LColor &color) {
  6281. #ifndef OPENGLES_2
  6282. // static PStatCollector _draw_set_state_light_ambient_pcollector("Draw:Set State:Light:Ambient");
  6283. // PStatTimer timer(_draw_set_state_light_ambient_pcollector);
  6284. LColor c = color;
  6285. c.set(c[0] * _light_color_scale[0],
  6286. c[1] * _light_color_scale[1],
  6287. c[2] * _light_color_scale[2],
  6288. c[3] * _light_color_scale[3]);
  6289. call_glLightModelfv(GL_LIGHT_MODEL_AMBIENT, c);
  6290. #endif
  6291. }
  6292. ////////////////////////////////////////////////////////////////////
  6293. // Function: GLGraphicsStateGuardian::enable_light
  6294. // Access: Protected, Virtual
  6295. // Description: Intended to be overridden by a derived class to
  6296. // enable the indicated light id. A specific Light will
  6297. // already have been bound to this id via bind_light().
  6298. ////////////////////////////////////////////////////////////////////
  6299. void CLP(GraphicsStateGuardian)::
  6300. enable_light(int light_id, bool enable) {
  6301. // static PStatCollector _draw_set_state_light_enable_light_pcollector("Draw:Set State:Light:Enable light");
  6302. // PStatTimer timer(_draw_set_state_light_enable_light_pcollector);
  6303. if (enable) {
  6304. GLP(Enable)(get_light_id(light_id));
  6305. } else {
  6306. GLP(Disable)(get_light_id(light_id));
  6307. }
  6308. }
  6309. ////////////////////////////////////////////////////////////////////
  6310. // Function: GLGraphicsStateGuardian::begin_bind_lights
  6311. // Access: Protected, Virtual
  6312. // Description: Called immediately before bind_light() is called,
  6313. // this is intended to provide the derived class a hook
  6314. // in which to set up some state (like transform) that
  6315. // might apply to several lights.
  6316. //
  6317. // The sequence is: begin_bind_lights() will be called,
  6318. // then one or more bind_light() calls, then
  6319. // end_bind_lights().
  6320. ////////////////////////////////////////////////////////////////////
  6321. void CLP(GraphicsStateGuardian)::
  6322. begin_bind_lights() {
  6323. #ifndef OPENGLES_2
  6324. // static PStatCollector _draw_set_state_light_begin_bind_pcollector("Draw:Set State:Light:Begin bind");
  6325. // PStatTimer timer(_draw_set_state_light_begin_bind_pcollector);
  6326. // We need to temporarily load a new matrix so we can define the
  6327. // light in a known coordinate system. We pick the transform of the
  6328. // root. (Alternatively, we could leave the current transform where
  6329. // it is and compute the light position relative to that transform
  6330. // instead of relative to the root, by composing with the matrix
  6331. // computed by _internal_transform->invert_compose(render_transform).
  6332. // But I think loading a completely new matrix is simpler.)
  6333. CPT(TransformState) render_transform =
  6334. _cs_transform->compose(_scene_setup->get_world_transform());
  6335. GLP(MatrixMode)(GL_MODELVIEW);
  6336. GLP(PushMatrix)();
  6337. GLPf(LoadMatrix)(render_transform->get_mat().get_data());
  6338. #endif
  6339. }
  6340. ////////////////////////////////////////////////////////////////////
  6341. // Function: GLGraphicsStateGuardian::end_bind_lights
  6342. // Access: Protected, Virtual
  6343. // Description: Called after before bind_light() has been called one
  6344. // or more times (but before any geometry is issued or
  6345. // additional state is changed), this is intended to
  6346. // clean up any temporary changes to the state that may
  6347. // have been made by begin_bind_lights().
  6348. ////////////////////////////////////////////////////////////////////
  6349. void CLP(GraphicsStateGuardian)::
  6350. end_bind_lights() {
  6351. #ifndef OPENGLES_2
  6352. // static PStatCollector _draw_set_state_light_end_bind_pcollector("Draw:Set State:Light:End bind");
  6353. // PStatTimer timer(_draw_set_state_light_end_bind_pcollector);
  6354. GLP(MatrixMode)(GL_MODELVIEW);
  6355. GLP(PopMatrix)();
  6356. #endif
  6357. }
  6358. ////////////////////////////////////////////////////////////////////
  6359. // Function: GLGraphicsStateGuardian::enable_clip_plane
  6360. // Access: Protected, Virtual
  6361. // Description: Intended to be overridden by a derived class to
  6362. // enable the indicated clip_plane id. A specific
  6363. // PlaneNode will already have been bound to this id via
  6364. // bind_clip_plane().
  6365. ////////////////////////////////////////////////////////////////////
  6366. void CLP(GraphicsStateGuardian)::
  6367. enable_clip_plane(int plane_id, bool enable) {
  6368. if (enable) {
  6369. GLP(Enable)(get_clip_plane_id(plane_id));
  6370. } else {
  6371. GLP(Disable)(get_clip_plane_id(plane_id));
  6372. }
  6373. }
  6374. ////////////////////////////////////////////////////////////////////
  6375. // Function: GLGraphicsStateGuardian::begin_bind_clip_planes
  6376. // Access: Protected, Virtual
  6377. // Description: Called immediately before bind_clip_plane() is called,
  6378. // this is intended to provide the derived class a hook
  6379. // in which to set up some state (like transform) that
  6380. // might apply to several clip_planes.
  6381. //
  6382. // The sequence is: begin_bind_clip_planes() will be called,
  6383. // then one or more bind_clip_plane() calls, then
  6384. // end_bind_clip_planes().
  6385. ////////////////////////////////////////////////////////////////////
  6386. void CLP(GraphicsStateGuardian)::
  6387. begin_bind_clip_planes() {
  6388. #ifndef OPENGLES_2
  6389. // We need to temporarily load a new matrix so we can define the
  6390. // clip_plane in a known coordinate system. We pick the transform of the
  6391. // root. (Alternatively, we could leave the current transform where
  6392. // it is and compute the clip_plane position relative to that transform
  6393. // instead of relative to the root, by composing with the matrix
  6394. // computed by _internal_transform->invert_compose(render_transform).
  6395. // But I think loading a completely new matrix is simpler.)
  6396. CPT(TransformState) render_transform =
  6397. _cs_transform->compose(_scene_setup->get_world_transform());
  6398. GLP(MatrixMode)(GL_MODELVIEW);
  6399. GLP(PushMatrix)();
  6400. GLPf(LoadMatrix)(render_transform->get_mat().get_data());
  6401. #endif
  6402. }
  6403. ////////////////////////////////////////////////////////////////////
  6404. // Function: GLGraphicsStateGuardian::bind_clip_plane
  6405. // Access: Protected, Virtual
  6406. // Description: Called the first time a particular clip_plane has been
  6407. // bound to a given id within a frame, this should set
  6408. // up the associated hardware clip_plane with the clip_plane's
  6409. // properties.
  6410. ////////////////////////////////////////////////////////////////////
  6411. void CLP(GraphicsStateGuardian)::
  6412. bind_clip_plane(const NodePath &plane, int plane_id) {
  6413. GLenum id = get_clip_plane_id(plane_id);
  6414. CPT(TransformState) transform = plane.get_transform(_scene_setup->get_scene_root().get_parent());
  6415. const PlaneNode *plane_node;
  6416. DCAST_INTO_V(plane_node, plane.node());
  6417. LPlane xformed_plane = plane_node->get_plane() * transform->get_mat();
  6418. #ifndef OPENGLES_2 // OpenGL ES 2.0 doesn't support clip planes at all.
  6419. #ifdef OPENGLES
  6420. // OpenGL ES uses a single-precision call.
  6421. LPlanef single_plane(LCAST(float, xformed_plane));
  6422. GLP(ClipPlanef)(id, single_plane.get_data());
  6423. #else
  6424. // Mainline OpenGL uses a double-precision call.
  6425. LPlaned double_plane(LCAST(double, xformed_plane));
  6426. GLP(ClipPlane)(id, double_plane.get_data());
  6427. #endif // OPENGLES
  6428. #endif // OPENGLES_2
  6429. report_my_gl_errors();
  6430. }
  6431. ////////////////////////////////////////////////////////////////////
  6432. // Function: GLGraphicsStateGuardian::end_bind_clip_planes
  6433. // Access: Protected, Virtual
  6434. // Description: Called after before bind_clip_plane() has been called one
  6435. // or more times (but before any geometry is issued or
  6436. // additional state is changed), this is intended to
  6437. // clean up any temporary changes to the state that may
  6438. // have been made by begin_bind_clip_planes().
  6439. ////////////////////////////////////////////////////////////////////
  6440. void CLP(GraphicsStateGuardian)::
  6441. end_bind_clip_planes() {
  6442. #ifndef OPENGLES_2
  6443. GLP(MatrixMode)(GL_MODELVIEW);
  6444. GLP(PopMatrix)();
  6445. #endif
  6446. }
  6447. ////////////////////////////////////////////////////////////////////
  6448. // Function: GLGraphicsStateGuardian::set_state_and_transform
  6449. // Access: Public, Virtual
  6450. // Description: Simultaneously resets the render state and the
  6451. // transform state.
  6452. //
  6453. // This transform specified is the "internal" net
  6454. // transform, already converted into the GSG's internal
  6455. // coordinate space by composing it to
  6456. // get_cs_transform(). (Previously, this used to be the
  6457. // "external" net transform, with the assumption that
  6458. // that GSG would convert it internally, but that is no
  6459. // longer the case.)
  6460. //
  6461. // Special case: if (state==NULL), then the target
  6462. // state is already stored in _target.
  6463. ////////////////////////////////////////////////////////////////////
  6464. void CLP(GraphicsStateGuardian)::
  6465. set_state_and_transform(const RenderState *target,
  6466. const TransformState *transform) {
  6467. report_my_gl_errors();
  6468. #ifndef NDEBUG
  6469. if (gsg_cat.is_spam()) {
  6470. gsg_cat.spam() << "Setting GSG state to " << (void *)target << ":\n";
  6471. target->write(gsg_cat.spam(false), 2);
  6472. }
  6473. #endif
  6474. _state_pcollector.add_level(1);
  6475. PStatTimer timer1(_draw_set_state_pcollector);
  6476. if (transform != _internal_transform) {
  6477. //PStatTimer timer(_draw_set_state_transform_pcollector);
  6478. _state_pcollector.add_level(1);
  6479. _internal_transform = transform;
  6480. do_issue_transform();
  6481. }
  6482. if (target == _state_rs && (_state_mask | _inv_state_mask).is_all_on()) {
  6483. return;
  6484. }
  6485. _target_rs = target;
  6486. _target_shader = DCAST(ShaderAttrib, _target_rs->get_attrib_def(ShaderAttrib::get_class_slot()));
  6487. #ifndef OPENGLES
  6488. _instance_count = _target_shader->get_instance_count();
  6489. #endif
  6490. #ifndef OPENGLES_1
  6491. if (_target_shader->auto_shader()) {
  6492. // If we don't have a generated shader, make sure we have a ShaderGenerator, then generate the shader.
  6493. CPT(RenderState) shader = _target_rs->get_auto_shader_state();
  6494. if (shader->_generated_shader == NULL) {
  6495. if (_shader_generator == NULL) {
  6496. _shader_generator = new ShaderGenerator(this, _scene_setup->get_display_region()->get_window());
  6497. }
  6498. const_cast<RenderState*>(shader.p())->_generated_shader = DCAST(ShaderAttrib, _shader_generator->synthesize_shader(shader));
  6499. }
  6500. _target_shader = DCAST(ShaderAttrib, shader->_generated_shader);
  6501. }
  6502. #endif
  6503. int alpha_test_slot = AlphaTestAttrib::get_class_slot();
  6504. if (_target_rs->get_attrib(alpha_test_slot) != _state_rs->get_attrib(alpha_test_slot) ||
  6505. !_state_mask.get_bit(alpha_test_slot) ||
  6506. (_target_shader->get_flag(ShaderAttrib::F_subsume_alpha_test) !=
  6507. _state_shader->get_flag(ShaderAttrib::F_subsume_alpha_test))) {
  6508. //PStatTimer timer(_draw_set_state_alpha_test_pcollector);
  6509. do_issue_alpha_test();
  6510. _state_mask.set_bit(alpha_test_slot);
  6511. }
  6512. int antialias_slot = AntialiasAttrib::get_class_slot();
  6513. if (_target_rs->get_attrib(antialias_slot) != _state_rs->get_attrib(antialias_slot) ||
  6514. !_state_mask.get_bit(antialias_slot)) {
  6515. //PStatTimer timer(_draw_set_state_antialias_pcollector);
  6516. do_issue_antialias();
  6517. _state_mask.set_bit(antialias_slot);
  6518. }
  6519. int clip_plane_slot = ClipPlaneAttrib::get_class_slot();
  6520. if (_target_rs->get_attrib(clip_plane_slot) != _state_rs->get_attrib(clip_plane_slot) ||
  6521. !_state_mask.get_bit(clip_plane_slot)) {
  6522. //PStatTimer timer(_draw_set_state_clip_plane_pcollector);
  6523. do_issue_clip_plane();
  6524. _state_mask.set_bit(clip_plane_slot);
  6525. }
  6526. int color_slot = ColorAttrib::get_class_slot();
  6527. int color_scale_slot = ColorScaleAttrib::get_class_slot();
  6528. if (_target_rs->get_attrib(color_slot) != _state_rs->get_attrib(color_slot) ||
  6529. _target_rs->get_attrib(color_scale_slot) != _state_rs->get_attrib(color_scale_slot) ||
  6530. !_state_mask.get_bit(color_slot) ||
  6531. !_state_mask.get_bit(color_scale_slot)) {
  6532. //PStatTimer timer(_draw_set_state_color_pcollector);
  6533. do_issue_color();
  6534. do_issue_color_scale();
  6535. _state_mask.set_bit(color_slot);
  6536. _state_mask.set_bit(color_scale_slot);
  6537. #ifndef OPENGLES_1
  6538. if (_current_shader_context) {
  6539. _current_shader_context->issue_parameters(this, Shader::SSD_color);
  6540. _current_shader_context->issue_parameters(this, Shader::SSD_colorscale);
  6541. }
  6542. #endif
  6543. }
  6544. int cull_face_slot = CullFaceAttrib::get_class_slot();
  6545. if (_target_rs->get_attrib(cull_face_slot) != _state_rs->get_attrib(cull_face_slot) ||
  6546. !_state_mask.get_bit(cull_face_slot)) {
  6547. //PStatTimer timer(_draw_set_state_cull_face_pcollector);
  6548. do_issue_cull_face();
  6549. _state_mask.set_bit(cull_face_slot);
  6550. }
  6551. int depth_offset_slot = DepthOffsetAttrib::get_class_slot();
  6552. if (_target_rs->get_attrib(depth_offset_slot) != _state_rs->get_attrib(depth_offset_slot) ||
  6553. !_state_mask.get_bit(depth_offset_slot)) {
  6554. //PStatTimer timer(_draw_set_state_depth_offset_pcollector);
  6555. do_issue_depth_offset();
  6556. _state_mask.set_bit(depth_offset_slot);
  6557. }
  6558. int depth_test_slot = DepthTestAttrib::get_class_slot();
  6559. if (_target_rs->get_attrib(depth_test_slot) != _state_rs->get_attrib(depth_test_slot) ||
  6560. !_state_mask.get_bit(depth_test_slot)) {
  6561. //PStatTimer timer(_draw_set_state_depth_test_pcollector);
  6562. do_issue_depth_test();
  6563. _state_mask.set_bit(depth_test_slot);
  6564. }
  6565. int depth_write_slot = DepthWriteAttrib::get_class_slot();
  6566. if (_target_rs->get_attrib(depth_write_slot) != _state_rs->get_attrib(depth_write_slot) ||
  6567. !_state_mask.get_bit(depth_write_slot)) {
  6568. //PStatTimer timer(_draw_set_state_depth_write_pcollector);
  6569. do_issue_depth_write();
  6570. _state_mask.set_bit(depth_write_slot);
  6571. }
  6572. int render_mode_slot = RenderModeAttrib::get_class_slot();
  6573. if (_target_rs->get_attrib(render_mode_slot) != _state_rs->get_attrib(render_mode_slot) ||
  6574. !_state_mask.get_bit(render_mode_slot)) {
  6575. //PStatTimer timer(_draw_set_state_render_mode_pcollector);
  6576. do_issue_render_mode();
  6577. _state_mask.set_bit(render_mode_slot);
  6578. }
  6579. int rescale_normal_slot = RescaleNormalAttrib::get_class_slot();
  6580. if (_target_rs->get_attrib(rescale_normal_slot) != _state_rs->get_attrib(rescale_normal_slot) ||
  6581. !_state_mask.get_bit(rescale_normal_slot)) {
  6582. //PStatTimer timer(_draw_set_state_rescale_normal_pcollector);
  6583. do_issue_rescale_normal();
  6584. _state_mask.set_bit(rescale_normal_slot);
  6585. }
  6586. int shade_model_slot = ShadeModelAttrib::get_class_slot();
  6587. if (_target_rs->get_attrib(shade_model_slot) != _state_rs->get_attrib(shade_model_slot) ||
  6588. !_state_mask.get_bit(shade_model_slot)) {
  6589. //PStatTimer timer(_draw_set_state_shade_model_pcollector);
  6590. do_issue_shade_model();
  6591. _state_mask.set_bit(shade_model_slot);
  6592. }
  6593. int transparency_slot = TransparencyAttrib::get_class_slot();
  6594. int color_write_slot = ColorWriteAttrib::get_class_slot();
  6595. int color_blend_slot = ColorBlendAttrib::get_class_slot();
  6596. if (_target_rs->get_attrib(transparency_slot) != _state_rs->get_attrib(transparency_slot) ||
  6597. _target_rs->get_attrib(color_write_slot) != _state_rs->get_attrib(color_write_slot) ||
  6598. _target_rs->get_attrib(color_blend_slot) != _state_rs->get_attrib(color_blend_slot) ||
  6599. !_state_mask.get_bit(transparency_slot) ||
  6600. !_state_mask.get_bit(color_write_slot) ||
  6601. !_state_mask.get_bit(color_blend_slot) ||
  6602. (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write) !=
  6603. _state_shader->get_flag(ShaderAttrib::F_disable_alpha_write))) {
  6604. //PStatTimer timer(_draw_set_state_blending_pcollector);
  6605. do_issue_blending();
  6606. _state_mask.set_bit(transparency_slot);
  6607. _state_mask.set_bit(color_write_slot);
  6608. _state_mask.set_bit(color_blend_slot);
  6609. }
  6610. if (_target_shader != _state_shader) {
  6611. //PStatTimer timer(_draw_set_state_shader_pcollector);
  6612. #ifndef OPENGLES_1
  6613. do_issue_shader(true);
  6614. #endif
  6615. _state_shader = _target_shader;
  6616. _state_mask.clear_bit(TextureAttrib::get_class_slot());
  6617. }
  6618. #ifdef OPENGLES_2
  6619. else { // In the case of OpenGL ES 2.x, we need to glUseShader before we draw anything.
  6620. do_issue_shader(false);
  6621. }
  6622. #endif
  6623. int texture_slot = TextureAttrib::get_class_slot();
  6624. if (_target_rs->get_attrib(texture_slot) != _state_rs->get_attrib(texture_slot) ||
  6625. !_state_mask.get_bit(texture_slot)) {
  6626. //PStatTimer timer(_draw_set_state_texture_pcollector);
  6627. determine_target_texture();
  6628. int prev_active = _num_active_texture_stages;
  6629. do_issue_texture();
  6630. // Since the TexGen and TexMatrix states depend partly on the
  6631. // particular set of textures in use, we should force both of
  6632. // those to be reissued every time we change the texture state.
  6633. _state_mask.clear_bit(TexGenAttrib::get_class_slot());
  6634. _state_mask.clear_bit(TexMatrixAttrib::get_class_slot());
  6635. _state_texture = _target_texture;
  6636. _state_mask.set_bit(texture_slot);
  6637. }
  6638. // If one of the previously-loaded TexGen modes modified the texture
  6639. // matrix, then if either state changed, we have to change both of
  6640. // them now.
  6641. if (_tex_gen_modifies_mat) {
  6642. int tex_gen_slot = TexGenAttrib::get_class_slot();
  6643. int tex_matrix_slot = TexMatrixAttrib::get_class_slot();
  6644. if (_target_rs->get_attrib(tex_gen_slot) != _state_rs->get_attrib(tex_gen_slot) ||
  6645. _target_rs->get_attrib(tex_matrix_slot) != _state_rs->get_attrib(tex_matrix_slot) ||
  6646. !_state_mask.get_bit(tex_gen_slot) ||
  6647. !_state_mask.get_bit(tex_matrix_slot)) {
  6648. _state_mask.clear_bit(tex_gen_slot);
  6649. _state_mask.clear_bit(tex_matrix_slot);
  6650. }
  6651. }
  6652. int tex_matrix_slot = TexMatrixAttrib::get_class_slot();
  6653. if (_target_rs->get_attrib(tex_matrix_slot) != _state_rs->get_attrib(tex_matrix_slot) ||
  6654. !_state_mask.get_bit(tex_matrix_slot)) {
  6655. //PStatTimer timer(_draw_set_state_tex_matrix_pcollector);
  6656. do_issue_tex_matrix();
  6657. _state_mask.set_bit(tex_matrix_slot);
  6658. }
  6659. int tex_gen_slot = TexGenAttrib::get_class_slot();
  6660. if (_target_tex_gen != _state_tex_gen ||
  6661. !_state_mask.get_bit(tex_gen_slot)) {
  6662. //PStatTimer timer(_draw_set_state_tex_gen_pcollector);
  6663. do_issue_tex_gen();
  6664. _state_tex_gen = _target_tex_gen;
  6665. _state_mask.set_bit(tex_gen_slot);
  6666. }
  6667. int material_slot = MaterialAttrib::get_class_slot();
  6668. if (_target_rs->get_attrib(material_slot) != _state_rs->get_attrib(material_slot) ||
  6669. !_state_mask.get_bit(material_slot)) {
  6670. //PStatTimer timer(_draw_set_state_material_pcollector);
  6671. do_issue_material();
  6672. _state_mask.set_bit(material_slot);
  6673. #ifndef OPENGLES_1
  6674. if (_current_shader_context) {
  6675. _current_shader_context->issue_parameters(this, Shader::SSD_material);
  6676. }
  6677. #endif
  6678. }
  6679. int light_slot = LightAttrib::get_class_slot();
  6680. if (_target_rs->get_attrib(light_slot) != _state_rs->get_attrib(light_slot) ||
  6681. !_state_mask.get_bit(light_slot)) {
  6682. //PStatTimer timer(_draw_set_state_light_pcollector);
  6683. do_issue_light();
  6684. _state_mask.set_bit(light_slot);
  6685. }
  6686. int stencil_slot = StencilAttrib::get_class_slot();
  6687. if (_target_rs->get_attrib(stencil_slot) != _state_rs->get_attrib(stencil_slot) ||
  6688. !_state_mask.get_bit(stencil_slot)) {
  6689. //PStatTimer timer(_draw_set_state_stencil_pcollector);
  6690. do_issue_stencil();
  6691. _state_mask.set_bit(stencil_slot);
  6692. }
  6693. int fog_slot = FogAttrib::get_class_slot();
  6694. if (_target_rs->get_attrib(fog_slot) != _state_rs->get_attrib(fog_slot) ||
  6695. !_state_mask.get_bit(fog_slot)) {
  6696. //PStatTimer timer(_draw_set_state_fog_pcollector);
  6697. do_issue_fog();
  6698. _state_mask.set_bit(fog_slot);
  6699. #ifndef OPENGLES_1
  6700. if (_current_shader_context) {
  6701. _current_shader_context->issue_parameters(this, Shader::SSD_fog);
  6702. }
  6703. #endif
  6704. }
  6705. int scissor_slot = ScissorAttrib::get_class_slot();
  6706. if (_target_rs->get_attrib(scissor_slot) != _state_rs->get_attrib(scissor_slot) ||
  6707. !_state_mask.get_bit(scissor_slot)) {
  6708. //PStatTimer timer(_draw_set_state_scissor_pcollector);
  6709. do_issue_scissor();
  6710. _state_mask.set_bit(scissor_slot);
  6711. }
  6712. _state_rs = _target_rs;
  6713. maybe_gl_finish();
  6714. report_my_gl_errors();
  6715. }
  6716. ////////////////////////////////////////////////////////////////////
  6717. // Function: GLGraphicsStateGuardian::free_pointers
  6718. // Access: Protected, Virtual
  6719. // Description: Frees some memory that was explicitly allocated
  6720. // within the glgsg.
  6721. ////////////////////////////////////////////////////////////////////
  6722. void CLP(GraphicsStateGuardian)::
  6723. free_pointers() {
  6724. }
  6725. ////////////////////////////////////////////////////////////////////
  6726. // Function: GLGraphicsStateGuardian::do_auto_rescale_normal
  6727. // Access: Protected
  6728. // Description: Issues the appropriate GL commands to either rescale
  6729. // or normalize the normals according to the current
  6730. // transform.
  6731. ////////////////////////////////////////////////////////////////////
  6732. void CLP(GraphicsStateGuardian)::
  6733. do_auto_rescale_normal() {
  6734. #ifndef OPENGLES_2
  6735. if (_internal_transform->has_identity_scale()) {
  6736. // If there's no scale at all, don't do anything.
  6737. GLP(Disable)(GL_NORMALIZE);
  6738. if (GLCAT.is_spam()) {
  6739. GLCAT.spam() << "glDisable(GL_NORMALIZE)\n";
  6740. }
  6741. if (_supports_rescale_normal && support_rescale_normal) {
  6742. GLP(Disable)(GL_RESCALE_NORMAL);
  6743. if (GLCAT.is_spam()) {
  6744. GLCAT.spam() << "glDisable(GL_RESCALE_NORMAL)\n";
  6745. }
  6746. }
  6747. } else if (_internal_transform->has_uniform_scale()) {
  6748. // There's a uniform scale; use the rescale feature if available.
  6749. if (_supports_rescale_normal && support_rescale_normal) {
  6750. GLP(Enable)(GL_RESCALE_NORMAL);
  6751. GLP(Disable)(GL_NORMALIZE);
  6752. if (GLCAT.is_spam()) {
  6753. GLCAT.spam() << "glEnable(GL_RESCALE_NORMAL)\n";
  6754. GLCAT.spam() << "glDisable(GL_NORMALIZE)\n";
  6755. }
  6756. } else {
  6757. GLP(Enable)(GL_NORMALIZE);
  6758. if (GLCAT.is_spam()) {
  6759. GLCAT.spam() << "glEnable(GL_NORMALIZE)\n";
  6760. }
  6761. }
  6762. } else {
  6763. // If there's a non-uniform scale, normalize everything.
  6764. GLP(Enable)(GL_NORMALIZE);
  6765. if (GLCAT.is_spam()) {
  6766. GLCAT.spam() << "glEnable(GL_NORMALIZE)\n";
  6767. }
  6768. if (_supports_rescale_normal && support_rescale_normal) {
  6769. GLP(Disable)(GL_RESCALE_NORMAL);
  6770. if (GLCAT.is_spam()) {
  6771. GLCAT.spam() << "glDisable(GL_RESCALE_NORMAL)\n";
  6772. }
  6773. }
  6774. }
  6775. #endif
  6776. }
  6777. ////////////////////////////////////////////////////////////////////
  6778. // Function: GLGraphicsStateGuardian::do_issue_texture
  6779. // Access: Protected, Virtual
  6780. // Description: This is called by set_state_and_transform() when
  6781. // the texture state has changed.
  6782. ////////////////////////////////////////////////////////////////////
  6783. void CLP(GraphicsStateGuardian)::
  6784. do_issue_texture() {
  6785. DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
  6786. #ifdef OPENGLES_1
  6787. update_standard_texture_bindings();
  6788. #else
  6789. if (_current_shader_context == 0 || !_current_shader_context->uses_custom_texture_bindings()) {
  6790. // No shader, or a non-Cg shader.
  6791. if (_texture_binding_shader_context != 0) {
  6792. _texture_binding_shader_context->disable_shader_texture_bindings(this);
  6793. }
  6794. update_standard_texture_bindings();
  6795. } else {
  6796. if (_texture_binding_shader_context == 0) {
  6797. disable_standard_texture_bindings();
  6798. _current_shader_context->update_shader_texture_bindings(NULL,this);
  6799. } else {
  6800. _current_shader_context->
  6801. update_shader_texture_bindings(_texture_binding_shader_context,this);
  6802. }
  6803. }
  6804. _texture_binding_shader = _current_shader;
  6805. _texture_binding_shader_context = _current_shader_context;
  6806. #endif
  6807. }
  6808. ////////////////////////////////////////////////////////////////////
  6809. // Function: GLGraphicsStateGuardian::update_standard_texture_bindings
  6810. // Access: Private
  6811. // Description: Applies the appropriate set of textures for the
  6812. // current state, using the standard fixed-function
  6813. // pipeline.
  6814. ////////////////////////////////////////////////////////////////////
  6815. void CLP(GraphicsStateGuardian)::
  6816. update_standard_texture_bindings() {
  6817. #ifndef OPENGLES_2
  6818. #ifndef NDEBUG
  6819. if (_show_texture_usage) {
  6820. update_show_usage_texture_bindings(-1);
  6821. return;
  6822. }
  6823. #endif // NDEBUG
  6824. int num_stages = _target_texture->get_num_on_ff_stages();
  6825. #ifndef NDEBUG
  6826. // Also check the _flash_texture. If it is non-NULL, we need to
  6827. // check to see if our flash_texture is in the texture stack here.
  6828. // If so, then we need to call the special show_texture method
  6829. // instead of the normal texture stack.
  6830. if (_flash_texture != (Texture *)NULL) {
  6831. double now = ClockObject::get_global_clock()->get_frame_time();
  6832. int this_second = (int)floor(now);
  6833. if (this_second & 1) {
  6834. int show_stage_index = -1;
  6835. for (int i = 0; i < num_stages && show_stage_index < 0; ++i) {
  6836. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  6837. Texture *texture = _target_texture->get_on_texture(stage);
  6838. if (texture == _flash_texture) {
  6839. show_stage_index = i;
  6840. }
  6841. }
  6842. if (show_stage_index >= 0) {
  6843. update_show_usage_texture_bindings(show_stage_index);
  6844. return;
  6845. }
  6846. }
  6847. }
  6848. #endif // NDEBUG
  6849. nassertv(num_stages <= _max_texture_stages &&
  6850. _num_active_texture_stages <= _max_texture_stages);
  6851. _texture_involves_color_scale = false;
  6852. int last_saved_result = -1;
  6853. int last_stage = -1;
  6854. int i;
  6855. for (i = 0; i < num_stages; i++) {
  6856. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  6857. Texture *texture = _target_texture->get_on_texture(stage);
  6858. nassertv(texture != (Texture *)NULL);
  6859. // Issue the texture on stage i.
  6860. _glActiveTexture(GL_TEXTURE0 + i);
  6861. // First, turn off the previous texture mode.
  6862. #ifndef OPENGLES_2
  6863. #ifndef OPENGLES
  6864. GLP(Disable)(GL_TEXTURE_1D);
  6865. #endif // OPENGLES
  6866. GLP(Disable)(GL_TEXTURE_2D);
  6867. if (_supports_3d_texture) {
  6868. #ifndef OPENGLES_1
  6869. GLP(Disable)(GL_TEXTURE_3D);
  6870. #endif // OPENGLES_1
  6871. }
  6872. if (_supports_cube_map) {
  6873. GLP(Disable)(GL_TEXTURE_CUBE_MAP);
  6874. }
  6875. #endif // OPENGLES_2
  6876. int view = get_current_tex_view_offset() + stage->get_tex_view_offset();
  6877. TextureContext *tc = texture->prepare_now(view, _prepared_objects, this);
  6878. if (tc == (TextureContext *)NULL) {
  6879. // Something wrong with this texture; skip it.
  6880. break;
  6881. }
  6882. #ifndef OPENGLES_2
  6883. // Then, turn on the current texture mode.
  6884. GLenum target = get_texture_target(texture->get_texture_type());
  6885. if (target == GL_NONE) {
  6886. // Unsupported texture mode.
  6887. break;
  6888. }
  6889. GLP(Enable)(target);
  6890. #endif
  6891. if (!update_texture(tc, false)) {
  6892. #ifndef OPENGLES_2
  6893. GLP(Disable)(target);
  6894. #endif
  6895. break;
  6896. }
  6897. if (stage->involves_color_scale() && _color_scale_enabled) {
  6898. LColor color = stage->get_color();
  6899. color.set(color[0] * _current_color_scale[0],
  6900. color[1] * _current_color_scale[1],
  6901. color[2] * _current_color_scale[2],
  6902. color[3] * _current_color_scale[3]);
  6903. _texture_involves_color_scale = true;
  6904. call_glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);
  6905. } else {
  6906. call_glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, stage->get_color());
  6907. }
  6908. if (stage->get_mode() == TextureStage::M_decal) {
  6909. if (texture->get_num_components() < 3 && _supports_texture_combine) {
  6910. // Make a special case for 1- and 2-channel decal textures.
  6911. // OpenGL does not define their use with GL_DECAL for some
  6912. // reason, so implement them using the combiner instead.
  6913. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
  6914. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
  6915. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_RGB_SCALE, 1);
  6916. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1);
  6917. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
  6918. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
  6919. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);
  6920. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
  6921. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_TEXTURE);
  6922. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
  6923. } else {
  6924. // Normal 3- and 4-channel decal textures.
  6925. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  6926. }
  6927. } else if (stage->get_mode() == TextureStage::M_combine) {
  6928. if (!_supports_texture_combine) {
  6929. GLCAT.warning()
  6930. << "TextureStage::M_combine mode is not supported.\n";
  6931. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  6932. } else {
  6933. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
  6934. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
  6935. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_RGB_SCALE, stage->get_rgb_scale());
  6936. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_ALPHA_SCALE, stage->get_alpha_scale());
  6937. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_COMBINE_RGB,
  6938. get_texture_combine_type(stage->get_combine_rgb_mode()));
  6939. switch (stage->get_num_combine_rgb_operands()) {
  6940. case 3:
  6941. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC2_RGB,
  6942. get_texture_src_type(stage->get_combine_rgb_source2(),
  6943. last_stage, last_saved_result, i));
  6944. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND2_RGB,
  6945. get_texture_operand_type(stage->get_combine_rgb_operand2()));
  6946. // fall through
  6947. case 2:
  6948. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC1_RGB,
  6949. get_texture_src_type(stage->get_combine_rgb_source1(),
  6950. last_stage, last_saved_result, i));
  6951. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND1_RGB,
  6952. get_texture_operand_type(stage->get_combine_rgb_operand1()));
  6953. // fall through
  6954. case 1:
  6955. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC0_RGB,
  6956. get_texture_src_type(stage->get_combine_rgb_source0(),
  6957. last_stage, last_saved_result, i));
  6958. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND0_RGB,
  6959. get_texture_operand_type(stage->get_combine_rgb_operand0()));
  6960. // fall through
  6961. default:
  6962. break;
  6963. }
  6964. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,
  6965. get_texture_combine_type(stage->get_combine_alpha_mode()));
  6966. switch (stage->get_num_combine_alpha_operands()) {
  6967. case 3:
  6968. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC2_ALPHA,
  6969. get_texture_src_type(stage->get_combine_alpha_source2(),
  6970. last_stage, last_saved_result, i));
  6971. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA,
  6972. get_texture_operand_type(stage->get_combine_alpha_operand2()));
  6973. // fall through
  6974. case 2:
  6975. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC1_ALPHA,
  6976. get_texture_src_type(stage->get_combine_alpha_source1(),
  6977. last_stage, last_saved_result, i));
  6978. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA,
  6979. get_texture_operand_type(stage->get_combine_alpha_operand1()));
  6980. // fall through
  6981. case 1:
  6982. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_SRC0_ALPHA,
  6983. get_texture_src_type(stage->get_combine_alpha_source0(),
  6984. last_stage, last_saved_result, i));
  6985. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA,
  6986. get_texture_operand_type(stage->get_combine_alpha_operand0()));
  6987. // fall through
  6988. default:
  6989. break;
  6990. }
  6991. }
  6992. } else {
  6993. GLint glmode = get_texture_apply_mode_type(stage->get_mode());
  6994. GLP(TexEnvi)(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, glmode);
  6995. }
  6996. if (stage->get_saved_result()) {
  6997. // This texture's result will be "saved" for a future stage's
  6998. // input.
  6999. last_saved_result = i;
  7000. } else {
  7001. // This is a regular texture stage; it will be the "previous"
  7002. // input for the next stage.
  7003. last_stage = i;
  7004. }
  7005. }
  7006. #ifndef OPENGLES_2
  7007. // Disable the texture stages that are no longer used.
  7008. for (i = num_stages; i < _num_active_texture_stages; i++) {
  7009. _glActiveTexture(GL_TEXTURE0 + i);
  7010. #ifndef OPENGLES
  7011. GLP(Disable)(GL_TEXTURE_1D);
  7012. #endif // OPENGLES
  7013. GLP(Disable)(GL_TEXTURE_2D);
  7014. if (_supports_3d_texture) {
  7015. #ifndef OPENGLES_1
  7016. GLP(Disable)(GL_TEXTURE_3D);
  7017. #endif // OPENGLES_1
  7018. }
  7019. if (_supports_cube_map) {
  7020. GLP(Disable)(GL_TEXTURE_CUBE_MAP);
  7021. }
  7022. }
  7023. #endif // OPENGLES_2
  7024. // Save the count of texture stages for next time.
  7025. _num_active_texture_stages = num_stages;
  7026. report_my_gl_errors();
  7027. #endif
  7028. }
  7029. #ifndef NDEBUG
  7030. ////////////////////////////////////////////////////////////////////
  7031. // Function: GLGraphicsStateGuardian::update_show_usage_texture_bindings
  7032. // Access: Private
  7033. // Description: This is a special function that loads the usage
  7034. // textures in gl-show-texture-usage mode, instead of
  7035. // loading the actual used textures.
  7036. //
  7037. // If the indicated stage_index is >= 0, then it is the
  7038. // particular texture that is shown. Otherwise, the
  7039. // textures are rotated through based on
  7040. // show_texture_usage_index.
  7041. ////////////////////////////////////////////////////////////////////
  7042. void CLP(GraphicsStateGuardian)::
  7043. update_show_usage_texture_bindings(int show_stage_index) {
  7044. int num_stages = _target_texture->get_num_on_ff_stages();
  7045. nassertv(num_stages <= _max_texture_stages &&
  7046. _num_active_texture_stages <= _max_texture_stages);
  7047. _texture_involves_color_scale = false;
  7048. // First, we walk through the list of textures and pretend to render
  7049. // them all, even though we don't actually render them, just so
  7050. // Panda will keep track of the list of "active" textures correctly
  7051. // during the flash.
  7052. int i;
  7053. for (i = 0; i < num_stages; i++) {
  7054. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  7055. Texture *texture = _target_texture->get_on_texture(stage);
  7056. nassertv(texture != (Texture *)NULL);
  7057. int view = get_current_tex_view_offset() + stage->get_tex_view_offset();
  7058. TextureContext *tc = texture->prepare_now(view, _prepared_objects, this);
  7059. if (tc == (TextureContext *)NULL) {
  7060. // Something wrong with this texture; skip it.
  7061. break;
  7062. }
  7063. tc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  7064. }
  7065. #ifndef OPENGLES_2
  7066. // Disable all texture stages.
  7067. for (i = 0; i < _num_active_texture_stages; i++) {
  7068. _glActiveTexture(GL_TEXTURE0 + i);
  7069. #ifndef OPENGLES
  7070. GLP(Disable)(GL_TEXTURE_1D);
  7071. #endif // OPENGLES
  7072. GLP(Disable)(GL_TEXTURE_2D);
  7073. if (_supports_3d_texture) {
  7074. #ifndef OPENGLES_1
  7075. GLP(Disable)(GL_TEXTURE_3D);
  7076. #endif // OPENGLES_1
  7077. }
  7078. if (_supports_cube_map) {
  7079. GLP(Disable)(GL_TEXTURE_CUBE_MAP);
  7080. }
  7081. }
  7082. #endif
  7083. // Save the count of texture stages for next time.
  7084. _num_active_texture_stages = num_stages;
  7085. if (num_stages > 0) {
  7086. // Now, pick just one texture stage to apply.
  7087. if (show_stage_index >= 0 && show_stage_index < num_stages) {
  7088. i = show_stage_index;
  7089. } else {
  7090. i = _show_texture_usage_index % num_stages;
  7091. }
  7092. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  7093. Texture *texture = _target_texture->get_on_texture(stage);
  7094. nassertv(texture != (Texture *)NULL);
  7095. // Choose the corresponding usage texture and apply it.
  7096. _glActiveTexture(GL_TEXTURE0 + i);
  7097. #ifndef OPENGLES_2
  7098. GLP(Enable)(GL_TEXTURE_2D);
  7099. #endif
  7100. UsageTextureKey key(texture->get_x_size(), texture->get_y_size());
  7101. UsageTextures::iterator ui = _usage_textures.find(key);
  7102. if (ui == _usage_textures.end()) {
  7103. // Need to create a new texture for this size.
  7104. GLuint index;
  7105. GLP(GenTextures)(1, &index);
  7106. GLP(BindTexture)(GL_TEXTURE_2D, index);
  7107. upload_usage_texture(texture->get_x_size(), texture->get_y_size());
  7108. _usage_textures[key] = index;
  7109. } else {
  7110. // Just bind the previously-created texture.
  7111. GLuint index = (*ui).second;
  7112. GLP(BindTexture)(GL_TEXTURE_2D, index);
  7113. }
  7114. }
  7115. report_my_gl_errors();
  7116. }
  7117. #endif // NDEBUG
  7118. #ifndef NDEBUG
  7119. ////////////////////////////////////////////////////////////////////
  7120. // Function: GLGraphicsStateGuardian::upload_usage_texture
  7121. // Access: Protected
  7122. // Description: Uploads a special "usage" texture intended to be
  7123. // applied only in gl-show-texture-usage mode, to reveal
  7124. // where texture memory is being spent.
  7125. ////////////////////////////////////////////////////////////////////
  7126. void CLP(GraphicsStateGuardian)::
  7127. upload_usage_texture(int width, int height) {
  7128. GLP(TexParameteri)(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  7129. GLP(TexParameteri)(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  7130. GLP(TexParameteri)(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  7131. GLP(TexParameteri)(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  7132. if (GLCAT.is_debug()) {
  7133. GLCAT.debug()
  7134. << "upload_usage_texture(" << width << ", " << height << ")\n";
  7135. }
  7136. static LColor colors[3] = {
  7137. LColor(0.4, 0.5f, 0.8f, 1.0f), // mipmap 0: blue
  7138. LColor(1.0f, 1.0f, 0.0f, 1.0f), // mipmap 1: yellow
  7139. LColor(0.8f, 0.3, 0.3, 1.0f), // mipmap 2 and higher: red
  7140. };
  7141. // Allocate a temporary array large enough to contain the toplevel
  7142. // mipmap.
  7143. PN_uint32 *buffer = (PN_uint32 *)PANDA_MALLOC_ARRAY(width * height * 4);
  7144. int n = 0;
  7145. while (true) {
  7146. // Choose the color for the nth mipmap.
  7147. LColor c = colors[min(n, 2)];
  7148. // A simple union to store the colors values bytewise, and get the
  7149. // answer wordwise, independently of machine byte-ordernig.
  7150. union {
  7151. struct {
  7152. unsigned char r, g, b, a;
  7153. } b;
  7154. PN_uint32 w;
  7155. } store;
  7156. store.b.r = (unsigned char)(c[0] * 255.0f);
  7157. store.b.g = (unsigned char)(c[1] * 255.0f);
  7158. store.b.b = (unsigned char)(c[2] * 255.0f);
  7159. store.b.a = 0xff;
  7160. // Fill in the array.
  7161. int num_pixels = width * height;
  7162. for (int p = 0; p < num_pixels; ++p) {
  7163. buffer[p] = store.w;
  7164. }
  7165. GLP(TexImage2D)(GL_TEXTURE_2D, n, GL_RGBA, width, height, 0,
  7166. GL_RGBA, GL_UNSIGNED_BYTE, buffer);
  7167. if (width == 1 && height == 1) {
  7168. // That was the last mipmap level.
  7169. break;
  7170. }
  7171. width = max(width >> 1, 1);
  7172. height = max(height >> 1, 1);
  7173. ++n;
  7174. }
  7175. PANDA_FREE_ARRAY(buffer);
  7176. }
  7177. #endif // NDEBUG
  7178. ////////////////////////////////////////////////////////////////////
  7179. // Function: GLGraphicsStateGuardian::disable_standard_texture_bindings
  7180. // Access: Private
  7181. // Description:
  7182. ////////////////////////////////////////////////////////////////////
  7183. void CLP(GraphicsStateGuardian)::
  7184. disable_standard_texture_bindings() {
  7185. #ifndef OPENGLES_2
  7186. // Disable the texture stages that are no longer used.
  7187. for (int i = 0; i < _num_active_texture_stages; i++) {
  7188. _glActiveTexture(GL_TEXTURE0 + i);
  7189. #ifndef OPENGLES
  7190. GLP(Disable)(GL_TEXTURE_1D);
  7191. #endif // OPENGLES
  7192. GLP(Disable)(GL_TEXTURE_2D);
  7193. if (_supports_3d_texture) {
  7194. #ifndef OPENGLES_1
  7195. GLP(Disable)(GL_TEXTURE_3D);
  7196. #endif // OPENGLES_1
  7197. }
  7198. if (_supports_cube_map) {
  7199. GLP(Disable)(GL_TEXTURE_CUBE_MAP);
  7200. }
  7201. }
  7202. _num_active_texture_stages = 0;
  7203. report_my_gl_errors();
  7204. #endif // OPENGLES_2
  7205. }
  7206. ////////////////////////////////////////////////////////////////////
  7207. // Function: GLGraphicsStateGuardian::do_issue_tex_matrix
  7208. // Access: Protected
  7209. // Description:
  7210. ////////////////////////////////////////////////////////////////////
  7211. void CLP(GraphicsStateGuardian)::
  7212. do_issue_tex_matrix() {
  7213. #ifndef OPENGLES_2 // OpenGL ES 2 doesn't support texture matrices, I think.
  7214. nassertv(_num_active_texture_stages <= _max_texture_stages);
  7215. for (int i = 0; i < _num_active_texture_stages; i++) {
  7216. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  7217. _glActiveTexture(GL_TEXTURE0 + i);
  7218. GLP(MatrixMode)(GL_TEXTURE);
  7219. const TexMatrixAttrib *target_tex_matrix = DCAST(TexMatrixAttrib, _target_rs->get_attrib_def(TexMatrixAttrib::get_class_slot()));
  7220. if (target_tex_matrix->has_stage(stage)) {
  7221. GLPf(LoadMatrix)(target_tex_matrix->get_mat(stage).get_data());
  7222. } else {
  7223. GLP(LoadIdentity)();
  7224. // For some reason, the glLoadIdentity() call doesn't work on
  7225. // my Dell laptop's IBM OpenGL driver, when used in
  7226. // conjunction with glTexGen(), below. But explicitly loading
  7227. // an identity matrix does work. But this buggy-driver
  7228. // workaround might have other performance implications, so I
  7229. // leave it out.
  7230. // GLPf(LoadMatrix)(LMatrix4::ident_mat().get_data());
  7231. }
  7232. }
  7233. report_my_gl_errors();
  7234. #endif
  7235. }
  7236. ////////////////////////////////////////////////////////////////////
  7237. // Function: GLGraphicsStateGuardian::do_issue_tex_gen
  7238. // Access: Protected
  7239. // Description:
  7240. ////////////////////////////////////////////////////////////////////
  7241. void CLP(GraphicsStateGuardian)::
  7242. do_issue_tex_gen() {
  7243. bool force_normal = false;
  7244. nassertv(_num_active_texture_stages <= _max_texture_stages);
  7245. // These are passed in for the four OBJECT_PLANE or EYE_PLANE
  7246. // values; they effectively define an identity matrix that maps
  7247. // the spatial coordinates one-for-one to UV's. If you want a
  7248. // mapping other than identity, use a TexMatrixAttrib (or a
  7249. // TexProjectorEffect).
  7250. static const PN_stdfloat s_data[4] = { 1, 0, 0, 0 };
  7251. static const PN_stdfloat t_data[4] = { 0, 1, 0, 0 };
  7252. static const PN_stdfloat r_data[4] = { 0, 0, 1, 0 };
  7253. static const PN_stdfloat q_data[4] = { 0, 0, 0, 1 };
  7254. _tex_gen_modifies_mat = false;
  7255. bool got_point_sprites = false;
  7256. for (int i = 0; i < _num_active_texture_stages; i++) {
  7257. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  7258. _glActiveTexture(GL_TEXTURE0 + i);
  7259. #ifndef OPENGLES_2
  7260. if (_supports_point_sprite) {
  7261. #ifdef OPENGLES
  7262. GLP(TexEnvi)(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_FALSE);
  7263. #else
  7264. GLP(TexEnvi)(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_FALSE);
  7265. #endif // OPENGLES
  7266. }
  7267. #endif // OPENGLES_2
  7268. #ifndef OPENGLES // TexGen not supported by OpenGL ES.
  7269. GLP(Disable)(GL_TEXTURE_GEN_S);
  7270. GLP(Disable)(GL_TEXTURE_GEN_T);
  7271. GLP(Disable)(GL_TEXTURE_GEN_R);
  7272. GLP(Disable)(GL_TEXTURE_GEN_Q);
  7273. TexGenAttrib::Mode mode = _target_tex_gen->get_mode(stage);
  7274. switch (mode) {
  7275. case TexGenAttrib::M_off:
  7276. case TexGenAttrib::M_light_vector:
  7277. break;
  7278. case TexGenAttrib::M_eye_sphere_map:
  7279. GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  7280. GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  7281. GLP(Enable)(GL_TEXTURE_GEN_S);
  7282. GLP(Enable)(GL_TEXTURE_GEN_T);
  7283. force_normal = true;
  7284. break;
  7285. case TexGenAttrib::M_eye_cube_map:
  7286. if (_supports_cube_map) {
  7287. // We need to rotate the normals out of GL's coordinate
  7288. // system and into the user's coordinate system. We do this
  7289. // by composing a transform onto the texture matrix.
  7290. LMatrix4 mat = _inv_cs_transform->get_mat();
  7291. mat.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
  7292. GLP(MatrixMode)(GL_TEXTURE);
  7293. GLPf(MultMatrix)(mat.get_data());
  7294. // Now we need to reset the texture matrix next time
  7295. // around to undo this.
  7296. _tex_gen_modifies_mat = true;
  7297. GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  7298. GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  7299. GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  7300. GLP(Enable)(GL_TEXTURE_GEN_S);
  7301. GLP(Enable)(GL_TEXTURE_GEN_T);
  7302. GLP(Enable)(GL_TEXTURE_GEN_R);
  7303. force_normal = true;
  7304. }
  7305. break;
  7306. case TexGenAttrib::M_world_cube_map:
  7307. if (_supports_cube_map) {
  7308. // We dynamically transform normals from eye space to world
  7309. // space by applying the appropriate rotation transform to
  7310. // the current texture matrix. Unlike M_world_position, we
  7311. // can't achieve this effect by monkeying with the modelview
  7312. // transform, since the current modelview doesn't affect
  7313. // GL_REFLECTION_MAP.
  7314. CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
  7315. LMatrix4 mat = camera_transform->get_mat();
  7316. mat.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
  7317. GLP(MatrixMode)(GL_TEXTURE);
  7318. GLPf(MultMatrix)(mat.get_data());
  7319. // Now we need to reset the texture matrix next time
  7320. // around to undo this.
  7321. _tex_gen_modifies_mat = true;
  7322. GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  7323. GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  7324. GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  7325. GLP(Enable)(GL_TEXTURE_GEN_S);
  7326. GLP(Enable)(GL_TEXTURE_GEN_T);
  7327. GLP(Enable)(GL_TEXTURE_GEN_R);
  7328. force_normal = true;
  7329. }
  7330. break;
  7331. case TexGenAttrib::M_eye_normal:
  7332. if (_supports_cube_map) {
  7333. // We need to rotate the normals out of GL's coordinate
  7334. // system and into the user's coordinate system. We do this
  7335. // by composing a transform onto the texture matrix.
  7336. LMatrix4 mat = _inv_cs_transform->get_mat();
  7337. mat.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
  7338. GLP(MatrixMode)(GL_TEXTURE);
  7339. GLPf(MultMatrix)(mat.get_data());
  7340. // Now we need to reset the texture matrix next time
  7341. // around to undo this.
  7342. _tex_gen_modifies_mat = true;
  7343. GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  7344. GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  7345. GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  7346. GLP(Enable)(GL_TEXTURE_GEN_S);
  7347. GLP(Enable)(GL_TEXTURE_GEN_T);
  7348. GLP(Enable)(GL_TEXTURE_GEN_R);
  7349. force_normal = true;
  7350. }
  7351. break;
  7352. case TexGenAttrib::M_world_normal:
  7353. if (_supports_cube_map) {
  7354. // We dynamically transform normals from eye space to world
  7355. // space by applying the appropriate rotation transform to
  7356. // the current texture matrix. Unlike M_world_position, we
  7357. // can't achieve this effect by monkeying with the modelview
  7358. // transform, since the current modelview doesn't affect
  7359. // GL_NORMAL_MAP.
  7360. CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
  7361. LMatrix4 mat = camera_transform->get_mat();
  7362. mat.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
  7363. GLP(MatrixMode)(GL_TEXTURE);
  7364. GLPf(MultMatrix)(mat.get_data());
  7365. // Now we need to reset the texture matrix next time
  7366. // around to undo this.
  7367. _tex_gen_modifies_mat = true;
  7368. GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  7369. GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  7370. GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  7371. GLP(Enable)(GL_TEXTURE_GEN_S);
  7372. GLP(Enable)(GL_TEXTURE_GEN_T);
  7373. GLP(Enable)(GL_TEXTURE_GEN_R);
  7374. force_normal = true;
  7375. }
  7376. break;
  7377. case TexGenAttrib::M_eye_position:
  7378. // To represent eye position correctly, we need to temporarily
  7379. // load the coordinate-system transform.
  7380. GLP(MatrixMode)(GL_MODELVIEW);
  7381. GLP(PushMatrix)();
  7382. GLPf(LoadMatrix)(_cs_transform->get_mat().get_data());
  7383. GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  7384. GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  7385. GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  7386. GLP(TexGeni)(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  7387. GLPfv(TexGen)(GL_S, GL_EYE_PLANE, s_data);
  7388. GLPfv(TexGen)(GL_T, GL_EYE_PLANE, t_data);
  7389. GLPfv(TexGen)(GL_R, GL_EYE_PLANE, r_data);
  7390. GLPfv(TexGen)(GL_Q, GL_EYE_PLANE, q_data);
  7391. GLP(Enable)(GL_TEXTURE_GEN_S);
  7392. GLP(Enable)(GL_TEXTURE_GEN_T);
  7393. GLP(Enable)(GL_TEXTURE_GEN_R);
  7394. GLP(Enable)(GL_TEXTURE_GEN_Q);
  7395. GLP(MatrixMode)(GL_MODELVIEW);
  7396. GLP(PopMatrix)();
  7397. break;
  7398. case TexGenAttrib::M_world_position:
  7399. // We achieve world position coordinates by using the eye
  7400. // position mode, and loading the transform of the root
  7401. // node--thus putting the "eye" at the root.
  7402. {
  7403. GLP(MatrixMode)(GL_MODELVIEW);
  7404. GLP(PushMatrix)();
  7405. CPT(TransformState) root_transform = _cs_transform->compose(_scene_setup->get_world_transform());
  7406. GLPf(LoadMatrix)(root_transform->get_mat().get_data());
  7407. GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  7408. GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  7409. GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  7410. GLP(TexGeni)(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  7411. GLPfv(TexGen)(GL_S, GL_EYE_PLANE, s_data);
  7412. GLPfv(TexGen)(GL_T, GL_EYE_PLANE, t_data);
  7413. GLPfv(TexGen)(GL_R, GL_EYE_PLANE, r_data);
  7414. GLPfv(TexGen)(GL_Q, GL_EYE_PLANE, q_data);
  7415. GLP(Enable)(GL_TEXTURE_GEN_S);
  7416. GLP(Enable)(GL_TEXTURE_GEN_T);
  7417. GLP(Enable)(GL_TEXTURE_GEN_R);
  7418. GLP(Enable)(GL_TEXTURE_GEN_Q);
  7419. GLP(MatrixMode)(GL_MODELVIEW);
  7420. GLP(PopMatrix)();
  7421. }
  7422. break;
  7423. case TexGenAttrib::M_point_sprite:
  7424. if (_supports_point_sprite) {
  7425. #ifdef OPENGLES
  7426. GLP(TexEnvi)(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE);
  7427. #else
  7428. GLP(TexEnvi)(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
  7429. #endif
  7430. got_point_sprites = true;
  7431. }
  7432. break;
  7433. case TexGenAttrib::M_constant:
  7434. // To generate a constant UV(w) coordinate everywhere, we use
  7435. // EYE_LINEAR mode, but we construct a special matrix that
  7436. // flattens the vertex position to zero and then adds our
  7437. // desired value.
  7438. {
  7439. const LTexCoord3 &v = _target_tex_gen->get_constant_value(stage);
  7440. GLP(TexGeni)(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  7441. GLP(TexGeni)(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  7442. GLP(TexGeni)(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  7443. GLP(TexGeni)(GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  7444. LVecBase4 s(0.0f, 0.0f, 0.0f, v[0]);
  7445. LVecBase4 t(0.0f, 0.0f, 0.0f, v[1]);
  7446. LVecBase4 r(0.0f, 0.0f, 0.0f, v[2]);
  7447. GLPfv(TexGen)(GL_S, GL_OBJECT_PLANE, s.get_data());
  7448. GLPfv(TexGen)(GL_T, GL_OBJECT_PLANE, t.get_data());
  7449. GLPfv(TexGen)(GL_R, GL_OBJECT_PLANE, r.get_data());
  7450. GLPfv(TexGen)(GL_Q, GL_OBJECT_PLANE, q_data);
  7451. GLP(Enable)(GL_TEXTURE_GEN_S);
  7452. GLP(Enable)(GL_TEXTURE_GEN_T);
  7453. GLP(Enable)(GL_TEXTURE_GEN_R);
  7454. GLP(Enable)(GL_TEXTURE_GEN_Q);
  7455. }
  7456. break;
  7457. case TexGenAttrib::M_unused:
  7458. break;
  7459. }
  7460. #endif // OPENGLES
  7461. }
  7462. if (got_point_sprites != _tex_gen_point_sprite) {
  7463. _tex_gen_point_sprite = got_point_sprites;
  7464. #ifndef OPENGLES_2
  7465. #ifdef OPENGLES
  7466. if (_tex_gen_point_sprite) {
  7467. GLP(Enable)(GL_POINT_SPRITE_OES);
  7468. } else {
  7469. GLP(Disable)(GL_POINT_SPRITE_OES);
  7470. }
  7471. #else
  7472. if (_tex_gen_point_sprite) {
  7473. GLP(Enable)(GL_POINT_SPRITE_ARB);
  7474. } else {
  7475. GLP(Disable)(GL_POINT_SPRITE_ARB);
  7476. }
  7477. #endif // OPENGLES
  7478. #endif // OPENGLES_2
  7479. }
  7480. report_my_gl_errors();
  7481. }
  7482. ////////////////////////////////////////////////////////////////////
  7483. // Function: GLGraphicsStateGuardian::specify_texture
  7484. // Access: Protected
  7485. // Description: Specifies the texture parameters. Returns true if
  7486. // the texture may need to be reloaded.
  7487. ////////////////////////////////////////////////////////////////////
  7488. bool CLP(GraphicsStateGuardian)::
  7489. specify_texture(CLP(TextureContext) *gtc) {
  7490. Texture *tex = gtc->get_texture();
  7491. GLenum target = get_texture_target(tex->get_texture_type());
  7492. if (target == GL_NONE) {
  7493. // Unsupported target (e.g. 3-d texturing on GL 1.1).
  7494. return false;
  7495. }
  7496. GLP(TexParameteri)(target, GL_TEXTURE_WRAP_S,
  7497. get_texture_wrap_mode(tex->get_wrap_u()));
  7498. #ifndef OPENGLES
  7499. if (target != GL_TEXTURE_1D) {
  7500. GLP(TexParameteri)(target, GL_TEXTURE_WRAP_T,
  7501. get_texture_wrap_mode(tex->get_wrap_v()));
  7502. }
  7503. #endif
  7504. #ifdef OPENGLES_2
  7505. if (target == GL_TEXTURE_3D_OES) {
  7506. GLP(TexParameteri)(target, GL_TEXTURE_WRAP_R_OES,
  7507. get_texture_wrap_mode(tex->get_wrap_w()));
  7508. }
  7509. #endif
  7510. #ifndef OPENGLES
  7511. if (target == GL_TEXTURE_3D) {
  7512. GLP(TexParameteri)(target, GL_TEXTURE_WRAP_R,
  7513. get_texture_wrap_mode(tex->get_wrap_w()));
  7514. }
  7515. LColor border_color = tex->get_border_color();
  7516. call_glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, border_color);
  7517. #endif // OPENGLES
  7518. Texture::FilterType minfilter = tex->get_effective_minfilter();
  7519. Texture::FilterType magfilter = tex->get_effective_magfilter();
  7520. bool uses_mipmaps = Texture::is_mipmap(minfilter) && !CLP(ignore_mipmaps);
  7521. #ifndef NDEBUG
  7522. if (CLP(force_mipmaps)) {
  7523. minfilter = Texture::FT_linear_mipmap_linear;
  7524. magfilter = Texture::FT_linear;
  7525. uses_mipmaps = true;
  7526. }
  7527. #endif
  7528. if (!tex->might_have_ram_image()) {
  7529. // If it's a dynamically generated texture (that is, the RAM image
  7530. // isn't available so it didn't pass through the CPU), we should
  7531. // enable GL-generated mipmaps here if we can.
  7532. if (_supports_generate_mipmap) {
  7533. #ifndef OPENGLES_2
  7534. GLP(TexParameteri)(target, GL_GENERATE_MIPMAP, uses_mipmaps);
  7535. #endif
  7536. } else {
  7537. // Otherwise, don't try to use mipmaps.
  7538. uses_mipmaps = false;
  7539. }
  7540. }
  7541. GLP(TexParameteri)(target, GL_TEXTURE_MIN_FILTER,
  7542. get_texture_filter_type(minfilter, !uses_mipmaps));
  7543. GLP(TexParameteri)(target, GL_TEXTURE_MAG_FILTER,
  7544. get_texture_filter_type(magfilter, true));
  7545. // Set anisotropic filtering.
  7546. if (_supports_anisotropy) {
  7547. PN_stdfloat anisotropy = tex->get_effective_anisotropic_degree();
  7548. anisotropy = min(anisotropy, _max_anisotropy);
  7549. anisotropy = max(anisotropy, (PN_stdfloat)1.0);
  7550. GLP(TexParameterf)(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
  7551. }
  7552. #ifndef OPENGLES
  7553. if (tex->get_format() == Texture::F_depth_stencil ||
  7554. tex->get_format() == Texture::F_depth_component) {
  7555. GLP(TexParameteri)(target, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
  7556. if (_supports_shadow_filter) {
  7557. if ((tex->get_magfilter() == Texture::FT_shadow) ||
  7558. (tex->get_minfilter() == Texture::FT_shadow)) {
  7559. GLP(TexParameteri)(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
  7560. GLP(TexParameteri)(target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
  7561. } else {
  7562. GLP(TexParameteri)(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
  7563. GLP(TexParameteri)(target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
  7564. }
  7565. }
  7566. }
  7567. #endif
  7568. report_my_gl_errors();
  7569. if (uses_mipmaps && !gtc->_uses_mipmaps) {
  7570. // Suddenly we require mipmaps. This means the texture may need
  7571. // reloading.
  7572. return true;
  7573. }
  7574. return false;
  7575. }
  7576. ////////////////////////////////////////////////////////////////////
  7577. // Function: GLGraphicsStateGuardian::apply_texture
  7578. // Access: Protected
  7579. // Description: Updates OpenGL with the current information for this
  7580. // texture, and makes it the current texture available
  7581. // for rendering.
  7582. ////////////////////////////////////////////////////////////////////
  7583. bool CLP(GraphicsStateGuardian)::
  7584. apply_texture(TextureContext *tc) {
  7585. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
  7586. gtc->set_active(true);
  7587. GLenum target = get_texture_target(gtc->get_texture()->get_texture_type());
  7588. if (target == GL_NONE) {
  7589. return false;
  7590. }
  7591. if (gtc->_target != target) {
  7592. // The target has changed. That means we have to re-bind a new
  7593. // texture object.
  7594. gtc->reset_data();
  7595. gtc->_target = target;
  7596. }
  7597. GLP(BindTexture)(target, gtc->_index);
  7598. report_my_gl_errors();
  7599. return true;
  7600. }
  7601. ////////////////////////////////////////////////////////////////////
  7602. // Function: GLGraphicsStateGuardian::upload_texture
  7603. // Access: Protected
  7604. // Description: Uploads the entire texture image to OpenGL, including
  7605. // all pages.
  7606. //
  7607. // The return value is true if successful, or false if
  7608. // the texture has no image.
  7609. ////////////////////////////////////////////////////////////////////
  7610. bool CLP(GraphicsStateGuardian)::
  7611. upload_texture(CLP(TextureContext) *gtc, bool force) {
  7612. Texture *tex = gtc->get_texture();
  7613. if (_effective_incomplete_render && !force) {
  7614. bool has_image = _supports_compressed_texture ? tex->has_ram_image() : tex->has_uncompressed_ram_image();
  7615. if (!has_image && tex->might_have_ram_image() &&
  7616. tex->has_simple_ram_image() &&
  7617. !_loader.is_null()) {
  7618. // If we don't have the texture data right now, go get it, but in
  7619. // the meantime load a temporary simple image in its place.
  7620. async_reload_texture(gtc);
  7621. has_image = _supports_compressed_texture ? tex->has_ram_image() : tex->has_uncompressed_ram_image();
  7622. if (!has_image) {
  7623. if (gtc->was_simple_image_modified()) {
  7624. return upload_simple_texture(gtc);
  7625. }
  7626. return true;
  7627. }
  7628. }
  7629. }
  7630. CPTA_uchar image;
  7631. if (_supports_compressed_texture) {
  7632. image = tex->get_ram_image();
  7633. } else {
  7634. image = tex->get_uncompressed_ram_image();
  7635. }
  7636. Texture::CompressionMode image_compression;
  7637. if (image.is_null()) {
  7638. image_compression = Texture::CM_off;
  7639. } else {
  7640. image_compression = tex->get_ram_image_compression();
  7641. }
  7642. if (!get_supports_compressed_texture_format(image_compression)) {
  7643. image = tex->get_uncompressed_ram_image();
  7644. image_compression = Texture::CM_off;
  7645. }
  7646. if (GLCAT.is_debug()) {
  7647. if (image.is_null()) {
  7648. GLCAT.debug()
  7649. << "Got NULL image: " << tex->get_name() << "\n";
  7650. }
  7651. }
  7652. /*
  7653. if (image.is_null()) {
  7654. // If we don't have an image, we can't upload.
  7655. return false;
  7656. }
  7657. */
  7658. int mipmap_bias = 0;
  7659. int width = tex->get_x_size();
  7660. int height = tex->get_y_size();
  7661. int depth = tex->get_z_size();
  7662. GLint internal_format = get_internal_image_format(tex);
  7663. GLint external_format = get_external_image_format(tex);
  7664. GLenum component_type = get_component_type(tex->get_component_type());
  7665. // Ensure that the texture fits within the GL's specified limits.
  7666. // Need to split dimensions because of texture arrays
  7667. int max_dimension_x;
  7668. int max_dimension_y;
  7669. int max_dimension_z;
  7670. switch (tex->get_texture_type()) {
  7671. case Texture::TT_3d_texture:
  7672. max_dimension_x = _max_3d_texture_dimension;
  7673. max_dimension_y = _max_3d_texture_dimension;
  7674. max_dimension_z = _max_3d_texture_dimension;
  7675. break;
  7676. case Texture::TT_cube_map:
  7677. max_dimension_x = _max_cube_map_dimension;
  7678. max_dimension_y = _max_cube_map_dimension;
  7679. max_dimension_z = 6;
  7680. break;
  7681. case Texture::TT_2d_texture_array:
  7682. max_dimension_x = _max_texture_dimension;
  7683. max_dimension_y = _max_texture_dimension;
  7684. max_dimension_z = _max_2d_texture_array_layers;
  7685. break;
  7686. default:
  7687. max_dimension_x = _max_texture_dimension;
  7688. max_dimension_y = _max_texture_dimension;
  7689. max_dimension_z = 1;
  7690. }
  7691. if (max_dimension_x == 0 || max_dimension_y == 0 || max_dimension_z == 0) {
  7692. // Guess this GL doesn't support cube mapping/3d textures/2d texture arrays.
  7693. report_my_gl_errors();
  7694. return false;
  7695. }
  7696. // If it doesn't fit, we have to reduce it on-the-fly. We do this
  7697. // by incrementing the mipmap_bias, so we're effectively loading a
  7698. // lower mipmap level. This requires generating the mipmaps on
  7699. // the CPU if they haven't already been generated. It would have
  7700. // been better if the user had specified max-texture-dimension to
  7701. // reduce the texture at load time instead; of course, the user
  7702. // doesn't always know ahead of time what the hardware limits are.
  7703. if ((max_dimension_x > 0 && max_dimension_y > 0 && max_dimension_z > 0) &&
  7704. image_compression == Texture::CM_off) {
  7705. while (tex->get_expected_mipmap_x_size(mipmap_bias) > max_dimension_x ||
  7706. tex->get_expected_mipmap_y_size(mipmap_bias) > max_dimension_y ||
  7707. tex->get_expected_mipmap_z_size(mipmap_bias) > max_dimension_z) {
  7708. ++mipmap_bias;
  7709. }
  7710. if (mipmap_bias >= tex->get_num_ram_mipmap_images()) {
  7711. // We need to generate some more mipmap images.
  7712. if (tex->has_ram_image()) {
  7713. tex->generate_ram_mipmap_images();
  7714. if (mipmap_bias >= tex->get_num_ram_mipmap_images()) {
  7715. // It didn't work. Send the smallest we've got, and hope
  7716. // for the best.
  7717. mipmap_bias = tex->get_num_ram_mipmap_images() - 1;
  7718. }
  7719. }
  7720. }
  7721. if (mipmap_bias != 0) {
  7722. GLCAT.info()
  7723. << "Reducing image " << tex->get_name()
  7724. << " from " << width << " x " << height << " x " << depth << " to "
  7725. << tex->get_expected_mipmap_x_size(mipmap_bias) << " x "
  7726. << tex->get_expected_mipmap_y_size(mipmap_bias) << " x "
  7727. << tex->get_expected_mipmap_z_size(mipmap_bias) << "\n";
  7728. }
  7729. }
  7730. if (image_compression != Texture::CM_off) {
  7731. Texture::QualityLevel quality_level = tex->get_effective_quality_level();
  7732. #ifndef OPENGLES
  7733. switch (quality_level) {
  7734. case Texture::QL_fastest:
  7735. GLP(Hint)(GL_TEXTURE_COMPRESSION_HINT, GL_FASTEST);
  7736. break;
  7737. case Texture::QL_default:
  7738. case Texture::QL_normal:
  7739. GLP(Hint)(GL_TEXTURE_COMPRESSION_HINT, GL_DONT_CARE);
  7740. break;
  7741. case Texture::QL_best:
  7742. GLP(Hint)(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST);
  7743. break;
  7744. }
  7745. #endif
  7746. }
  7747. GLP(PixelStorei)(GL_UNPACK_ALIGNMENT, 1);
  7748. bool uses_mipmaps = (tex->uses_mipmaps() && !CLP(ignore_mipmaps)) || CLP(force_mipmaps);
  7749. #ifndef NDEBUG
  7750. if (CLP(force_mipmaps)) {
  7751. uses_mipmaps = true;
  7752. }
  7753. #endif
  7754. bool success = true;
  7755. GLenum target = get_texture_target(tex->get_texture_type());
  7756. if (tex->get_texture_type() == Texture::TT_cube_map) {
  7757. // A cube map must load six different 2-d images (which are stored
  7758. // as the six pages of the system ram image).
  7759. if (!_supports_cube_map) {
  7760. report_my_gl_errors();
  7761. return false;
  7762. }
  7763. nassertr(target == GL_TEXTURE_CUBE_MAP, false);
  7764. success = success && upload_texture_image
  7765. (gtc, uses_mipmaps, mipmap_bias,
  7766. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
  7767. internal_format, external_format, component_type,
  7768. true, 0, image_compression);
  7769. success = success && upload_texture_image
  7770. (gtc, uses_mipmaps, mipmap_bias,
  7771. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
  7772. internal_format, external_format, component_type,
  7773. true, 1, image_compression);
  7774. success = success && upload_texture_image
  7775. (gtc, uses_mipmaps, mipmap_bias,
  7776. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
  7777. internal_format, external_format, component_type,
  7778. true, 2, image_compression);
  7779. success = success && upload_texture_image
  7780. (gtc, uses_mipmaps, mipmap_bias,
  7781. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
  7782. internal_format, external_format, component_type,
  7783. true, 3, image_compression);
  7784. success = success && upload_texture_image
  7785. (gtc, uses_mipmaps, mipmap_bias,
  7786. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
  7787. internal_format, external_format, component_type,
  7788. true, 4, image_compression);
  7789. success = success && upload_texture_image
  7790. (gtc, uses_mipmaps, mipmap_bias,
  7791. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
  7792. internal_format, external_format, component_type,
  7793. true, 5, image_compression);
  7794. } else {
  7795. // Any other kind of texture can be loaded all at once.
  7796. success = upload_texture_image
  7797. (gtc, uses_mipmaps, mipmap_bias, target, target,
  7798. internal_format, external_format, component_type,
  7799. false, 0, image_compression);
  7800. }
  7801. maybe_gl_finish();
  7802. if (success) {
  7803. gtc->_already_applied = true;
  7804. gtc->_uses_mipmaps = uses_mipmaps;
  7805. gtc->_internal_format = internal_format;
  7806. gtc->_width = width;
  7807. gtc->_height = height;
  7808. gtc->_depth = depth;
  7809. if (!image.is_null()) {
  7810. gtc->update_data_size_bytes(get_texture_memory_size(tex));
  7811. }
  7812. if (tex->get_post_load_store_cache()) {
  7813. tex->set_post_load_store_cache(false);
  7814. // OK, get the RAM image, and save it in a BamCache record.
  7815. if (do_extract_texture_data(gtc)) {
  7816. if (tex->has_ram_image()) {
  7817. BamCache *cache = BamCache::get_global_ptr();
  7818. PT(BamCacheRecord) record = cache->lookup(tex->get_fullpath(), "txo");
  7819. if (record != (BamCacheRecord *)NULL) {
  7820. record->set_data(tex, tex);
  7821. cache->store(record);
  7822. }
  7823. }
  7824. }
  7825. }
  7826. GraphicsEngine *engine = get_engine();
  7827. nassertr(engine != (GraphicsEngine *)NULL, false);
  7828. nassertr(engine == GraphicsEngine::get_global_ptr(), false); // temp hack
  7829. engine->texture_uploaded(tex);
  7830. gtc->mark_loaded();
  7831. report_my_gl_errors();
  7832. return true;
  7833. }
  7834. report_my_gl_errors();
  7835. return false;
  7836. }
  7837. ////////////////////////////////////////////////////////////////////
  7838. // Function: GLGraphicsStateGuardian::upload_texture_image
  7839. // Access: Protected
  7840. // Description: Loads a texture image, or one page of a cube map
  7841. // image, from system RAM to texture memory.
  7842. //
  7843. // texture_target is normally the same thing as
  7844. // page_target; both represent the GL target onto which
  7845. // the texture image is loaded, e.g. GL_TEXTURE_1D,
  7846. // GL_TEXTURE_2D, etc. The only time they may differ is
  7847. // in the case of cube mapping, in which case
  7848. // texture_target will be target for the overall
  7849. // texture, e.g. GL_TEXTURE_CUBE_MAP, and page_target
  7850. // will the target for this particular page,
  7851. // e.g. GL_TEXTURE_CUBE_MAP_POSITIVE_X.
  7852. ////////////////////////////////////////////////////////////////////
  7853. bool CLP(GraphicsStateGuardian)::
  7854. upload_texture_image(CLP(TextureContext) *gtc,
  7855. bool uses_mipmaps, int mipmap_bias,
  7856. GLenum texture_target, GLenum page_target,
  7857. GLint internal_format,
  7858. GLint external_format, GLenum component_type,
  7859. bool one_page_only, int z,
  7860. Texture::CompressionMode image_compression) {
  7861. // Make sure the error stack is cleared out before we begin.
  7862. clear_my_gl_errors();
  7863. if (texture_target == GL_NONE) {
  7864. // Unsupported target (e.g. 3-d texturing on GL 1.1).
  7865. return false;
  7866. }
  7867. if (image_compression != Texture::CM_off && !_supports_compressed_texture) {
  7868. return false;
  7869. }
  7870. PStatTimer timer(_load_texture_pcollector);
  7871. Texture *tex = gtc->get_texture();
  7872. nassertr(tex != (Texture *)NULL, false);
  7873. CPTA_uchar image = tex->get_ram_mipmap_image(mipmap_bias);
  7874. int width = tex->get_expected_mipmap_x_size(mipmap_bias);
  7875. int height = tex->get_expected_mipmap_y_size(mipmap_bias);
  7876. int depth = tex->get_expected_mipmap_z_size(mipmap_bias);
  7877. if (GLCAT.is_debug()) {
  7878. if (image_compression != Texture::CM_off) {
  7879. GLCAT.debug()
  7880. << "loading pre-compressed texture " << tex->get_name() << "\n";
  7881. } else if (is_compressed_format(internal_format)) {
  7882. GLCAT.debug()
  7883. << "compressing texture " << tex->get_name() << "\n";
  7884. } else {
  7885. GLCAT.debug()
  7886. << "loading uncompressed texture " << tex->get_name() << "\n";
  7887. }
  7888. }
  7889. int num_ram_mipmap_levels = 0;
  7890. bool load_ram_mipmaps = false;
  7891. if (image.is_null()) {
  7892. if (GLCAT.is_debug()) {
  7893. GLCAT.debug()
  7894. << "Not loading NULL image " << tex->get_name() << "\n";
  7895. }
  7896. if (uses_mipmaps) {
  7897. if (_supports_generate_mipmap) {
  7898. #ifndef OPENGLES_2
  7899. GLP(TexParameteri)(texture_target, GL_GENERATE_MIPMAP, true);
  7900. #endif
  7901. } else {
  7902. // If it can't, do without mipmaps.
  7903. GLP(TexParameteri)(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  7904. uses_mipmaps = false;
  7905. }
  7906. }
  7907. } else {
  7908. num_ram_mipmap_levels = 1;
  7909. if (uses_mipmaps) {
  7910. num_ram_mipmap_levels = tex->get_num_ram_mipmap_images();
  7911. if (num_ram_mipmap_levels == 1) {
  7912. // No RAM mipmap levels available. Should we generate some?
  7913. if (!_supports_generate_mipmap || !driver_generate_mipmaps ||
  7914. image_compression != Texture::CM_off) {
  7915. // Yes, the GL can't or won't generate them, so we need to.
  7916. // Note that some drivers (nVidia) will *corrupt memory* if
  7917. // you ask them to generate mipmaps for a pre-compressed
  7918. // texture.
  7919. tex->generate_ram_mipmap_images();
  7920. num_ram_mipmap_levels = tex->get_num_ram_mipmap_images();
  7921. }
  7922. }
  7923. if (num_ram_mipmap_levels != 1) {
  7924. // We will load the mipmap levels from RAM. Don't ask the GL to
  7925. // generate them.
  7926. #ifndef OPENGLES_2
  7927. if (_supports_generate_mipmap) {
  7928. GLP(TexParameteri)(texture_target, GL_GENERATE_MIPMAP, false);
  7929. }
  7930. #endif
  7931. load_ram_mipmaps = true;
  7932. } else {
  7933. // We don't have mipmap levels in RAM. Ask the GL to generate
  7934. // them if it can.
  7935. if (_supports_generate_mipmap) {
  7936. #ifndef OPENGLES_2
  7937. GLP(TexParameteri)(texture_target, GL_GENERATE_MIPMAP, true);
  7938. #endif
  7939. } else {
  7940. // If it can't, do without mipmaps.
  7941. GLP(TexParameteri)(texture_target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  7942. uses_mipmaps = false;
  7943. }
  7944. }
  7945. }
  7946. }
  7947. int highest_level = 0;
  7948. #ifdef OPENGLES // OpenGL ES doesn't support texture subloads.
  7949. static const bool needs_reload = true;
  7950. #else
  7951. bool needs_reload = false;
  7952. if (!gtc->_already_applied ||
  7953. gtc->_uses_mipmaps != uses_mipmaps ||
  7954. gtc->_internal_format != internal_format ||
  7955. gtc->_width != width ||
  7956. gtc->_height != height ||
  7957. gtc->_depth != depth) {
  7958. // We need to reload a new GL Texture object.
  7959. needs_reload = true;
  7960. }
  7961. if (!needs_reload) {
  7962. // Try to subload the image over the existing GL Texture object,
  7963. // possibly saving on texture memory fragmentation.
  7964. if (GLCAT.is_debug()) {
  7965. GLCAT.debug()
  7966. << "subloading existing texture object, " << width << " x " << height
  7967. << " x " << depth << ", mipmaps " << num_ram_mipmap_levels
  7968. << ", uses_mipmaps = " << uses_mipmaps << "\n";
  7969. }
  7970. for (int n = mipmap_bias; n < num_ram_mipmap_levels; ++n) {
  7971. // we grab the mipmap pointer first, if it is NULL we grab the
  7972. // normal mipmap image pointer which is a PTA_uchar
  7973. const unsigned char *image_ptr = (unsigned char*)tex->get_ram_mipmap_pointer(n);
  7974. CPTA_uchar ptimage;
  7975. if (image_ptr == (const unsigned char *)NULL) {
  7976. ptimage = tex->get_ram_mipmap_image(n);
  7977. if (ptimage == (const unsigned char *)NULL) {
  7978. GLCAT.warning()
  7979. << "No mipmap level " << n << " defined for " << tex->get_name()
  7980. << "\n";
  7981. // No mipmap level n; stop here.
  7982. break;
  7983. }
  7984. image_ptr = ptimage;
  7985. }
  7986. const unsigned char *orig_image_ptr = image_ptr;
  7987. size_t view_size = tex->get_ram_mipmap_view_size(n);
  7988. image_ptr += view_size * gtc->get_view();
  7989. if (one_page_only) {
  7990. view_size = tex->get_ram_mipmap_page_size(n);
  7991. image_ptr += view_size * z;
  7992. }
  7993. nassertr(image_ptr >= orig_image_ptr && image_ptr + view_size <= orig_image_ptr + tex->get_ram_mipmap_image_size(n), false);
  7994. PTA_uchar bgr_image;
  7995. if (!_supports_bgr && image_compression == Texture::CM_off) {
  7996. // If the GL doesn't claim to support BGR, we may have to reverse
  7997. // the component ordering of the image.
  7998. image_ptr = fix_component_ordering(bgr_image, image_ptr, view_size,
  7999. external_format, tex);
  8000. }
  8001. int width = tex->get_expected_mipmap_x_size(n);
  8002. int height = tex->get_expected_mipmap_y_size(n);
  8003. int depth = tex->get_expected_mipmap_z_size(n);
  8004. #ifdef DO_PSTATS
  8005. _data_transferred_pcollector.add_level(view_size);
  8006. #endif
  8007. switch (texture_target) {
  8008. case GL_TEXTURE_1D:
  8009. if (image_compression == Texture::CM_off) {
  8010. GLP(TexSubImage1D)(page_target, n - mipmap_bias, 0, width,
  8011. external_format, component_type, image_ptr);
  8012. } else {
  8013. _glCompressedTexSubImage1D(page_target, n - mipmap_bias, 0, width,
  8014. external_format, view_size, image_ptr);
  8015. }
  8016. break;
  8017. #ifdef OPENGLES_2
  8018. case GL_TEXTURE_3D_OES:
  8019. #endif
  8020. #ifndef OPENGLES
  8021. case GL_TEXTURE_3D:
  8022. #endif
  8023. #ifndef OPENGLES_1
  8024. if (_supports_3d_texture) {
  8025. if (image_compression == Texture::CM_off) {
  8026. _glTexSubImage3D(page_target, n - mipmap_bias, 0, 0, 0, width, height, depth,
  8027. external_format, component_type, image_ptr);
  8028. } else {
  8029. _glCompressedTexSubImage3D(page_target, n - mipmap_bias, 0, 0, 0, width, height, depth,
  8030. external_format, view_size, image_ptr);
  8031. }
  8032. } else {
  8033. report_my_gl_errors();
  8034. return false;
  8035. }
  8036. break;
  8037. #endif
  8038. #ifndef OPENGLES
  8039. case GL_TEXTURE_2D_ARRAY_EXT:
  8040. if (_supports_2d_texture_array) {
  8041. if (image_compression == Texture::CM_off) {
  8042. _glTexSubImage3D(page_target, n - mipmap_bias, 0, 0, 0, width, height, depth,
  8043. external_format, component_type, image_ptr);
  8044. } else {
  8045. _glCompressedTexSubImage3D(page_target, n - mipmap_bias, 0, 0, 0, width, height, depth,
  8046. external_format, view_size, image_ptr);
  8047. }
  8048. } else {
  8049. report_my_gl_errors();
  8050. return false;
  8051. }
  8052. break;
  8053. #endif
  8054. default:
  8055. if (image_compression == Texture::CM_off) {
  8056. if (n==0) {
  8057. // It's unfortunate that we can't adjust the width, too,
  8058. // but TexSubImage2D doesn't accept a row-stride parameter.
  8059. height = tex->get_y_size() - tex->get_pad_y_size();
  8060. }
  8061. GLP(TexSubImage2D)(page_target, n - mipmap_bias, 0, 0, width, height,
  8062. external_format, component_type, image_ptr);
  8063. } else {
  8064. _glCompressedTexSubImage2D(page_target, n - mipmap_bias, 0, 0, width, height,
  8065. external_format, view_size, image_ptr);
  8066. }
  8067. break;
  8068. }
  8069. highest_level = n;
  8070. }
  8071. // Did that fail? If it did, we'll immediately try again, this
  8072. // time loading the texture from scratch.
  8073. GLenum error_code = gl_get_error();
  8074. if (error_code != GL_NO_ERROR) {
  8075. if (GLCAT.is_debug()) {
  8076. GLCAT.debug()
  8077. << "GL texture subload failed for " << tex->get_name()
  8078. << " : " << get_error_string(error_code) << "\n";
  8079. }
  8080. needs_reload = true;
  8081. }
  8082. }
  8083. #endif // OPENGLES
  8084. if (needs_reload) {
  8085. // Load the image up from scratch, creating a new GL Texture
  8086. // object.
  8087. if (GLCAT.is_debug()) {
  8088. GLCAT.debug()
  8089. << "loading new texture object, " << width << " x " << height
  8090. << " x " << depth << ", mipmaps " << num_ram_mipmap_levels
  8091. << ", uses_mipmaps = " << uses_mipmaps << "\n";
  8092. }
  8093. if (num_ram_mipmap_levels == 0) {
  8094. #ifndef OPENGLES_2
  8095. if ((external_format == GL_DEPTH_STENCIL_EXT) && get_supports_depth_stencil()) {
  8096. GLP(TexImage2D)(page_target, 0, GL_DEPTH_STENCIL_EXT,
  8097. width, height, 0, GL_DEPTH_STENCIL_EXT,
  8098. #ifdef OPENGLES_1
  8099. GL_UNSIGNED_INT_24_8_OES,
  8100. #else
  8101. GL_UNSIGNED_INT_24_8_EXT,
  8102. #endif // OPENGLES_1
  8103. NULL);
  8104. } else {
  8105. #endif // OPENGLES_2
  8106. GLP(TexImage2D)(page_target, 0, internal_format,
  8107. width, height, 0,
  8108. external_format, GL_UNSIGNED_BYTE, NULL);
  8109. #ifndef OPENGLES_2
  8110. }
  8111. #endif // OPENGLES_2
  8112. }
  8113. for (int n = mipmap_bias; n < num_ram_mipmap_levels; ++n) {
  8114. const unsigned char *image_ptr = (unsigned char*)tex->get_ram_mipmap_pointer(n);
  8115. CPTA_uchar ptimage;
  8116. if (image_ptr == (const unsigned char *)NULL) {
  8117. ptimage = tex->get_ram_mipmap_image(n);
  8118. if (ptimage == (const unsigned char *)NULL) {
  8119. GLCAT.warning()
  8120. << "No mipmap level " << n << " defined for " << tex->get_name()
  8121. << "\n";
  8122. // No mipmap level n; stop here.
  8123. break;
  8124. }
  8125. image_ptr = ptimage;
  8126. }
  8127. const unsigned char *orig_image_ptr = image_ptr;
  8128. size_t view_size = tex->get_ram_mipmap_view_size(n);
  8129. image_ptr += view_size * gtc->get_view();
  8130. if (one_page_only) {
  8131. view_size = tex->get_ram_mipmap_page_size(n);
  8132. image_ptr += view_size * z;
  8133. }
  8134. nassertr(image_ptr >= orig_image_ptr && image_ptr + view_size <= orig_image_ptr + tex->get_ram_mipmap_image_size(n), false);
  8135. PTA_uchar bgr_image;
  8136. if (!_supports_bgr && image_compression == Texture::CM_off) {
  8137. // If the GL doesn't claim to support BGR, we may have to reverse
  8138. // the component ordering of the image.
  8139. image_ptr = fix_component_ordering(bgr_image, image_ptr, view_size,
  8140. external_format, tex);
  8141. }
  8142. int width = tex->get_expected_mipmap_x_size(n);
  8143. int height = tex->get_expected_mipmap_y_size(n);
  8144. int depth = tex->get_expected_mipmap_z_size(n);
  8145. #ifdef DO_PSTATS
  8146. _data_transferred_pcollector.add_level(view_size);
  8147. #endif
  8148. switch (texture_target) {
  8149. #ifndef OPENGLES // 1-d textures not supported by OpenGL ES. Fall through.
  8150. case GL_TEXTURE_1D:
  8151. if (image_compression == Texture::CM_off) {
  8152. GLP(TexImage1D)(page_target, n - mipmap_bias, internal_format,
  8153. width, 0,
  8154. external_format, component_type, image_ptr);
  8155. } else {
  8156. _glCompressedTexImage1D(page_target, n - mipmap_bias, external_format, width,
  8157. 0, view_size, image_ptr);
  8158. }
  8159. break;
  8160. #endif // OPENGLES // OpenGL ES will fall through.
  8161. #ifdef OPENGLES_2
  8162. case GL_TEXTURE_3D_OES:
  8163. #endif
  8164. #ifndef OPENGLES
  8165. case GL_TEXTURE_3D:
  8166. #endif
  8167. #ifndef OPENGLES_1
  8168. if (_supports_3d_texture) {
  8169. if (image_compression == Texture::CM_off) {
  8170. _glTexImage3D(page_target, n - mipmap_bias, internal_format,
  8171. width, height, depth, 0,
  8172. external_format, component_type, image_ptr);
  8173. } else {
  8174. _glCompressedTexImage3D(page_target, n - mipmap_bias, external_format, width,
  8175. height, depth,
  8176. 0, view_size, image_ptr);
  8177. }
  8178. } else {
  8179. report_my_gl_errors();
  8180. return false;
  8181. }
  8182. break;
  8183. #endif
  8184. #ifndef OPENGLES
  8185. case GL_TEXTURE_2D_ARRAY_EXT:
  8186. if (_supports_2d_texture_array) {
  8187. if (image_compression == Texture::CM_off) {
  8188. _glTexImage3D(page_target, n - mipmap_bias, internal_format,
  8189. width, height, depth, 0,
  8190. external_format, component_type, image_ptr);
  8191. } else {
  8192. _glCompressedTexImage3D(page_target, n - mipmap_bias, external_format, width,
  8193. height, depth,
  8194. 0, view_size, image_ptr);
  8195. }
  8196. } else {
  8197. report_my_gl_errors();
  8198. return false;
  8199. }
  8200. break;
  8201. #endif
  8202. default:
  8203. if (image_compression == Texture::CM_off) {
  8204. GLP(TexImage2D)(page_target, n - mipmap_bias, internal_format,
  8205. width, height, 0,
  8206. external_format, component_type, image_ptr);
  8207. } else {
  8208. _glCompressedTexImage2D(page_target, n - mipmap_bias, external_format, width, height,
  8209. 0, view_size, image_ptr);
  8210. }
  8211. }
  8212. highest_level = n;
  8213. }
  8214. // Report the error message explicitly if the GL texture creation
  8215. // failed.
  8216. GLenum error_code = gl_get_error();
  8217. if (error_code != GL_NO_ERROR) {
  8218. GLCAT.error()
  8219. << "GL texture creation failed for " << tex->get_name()
  8220. << " : " << get_error_string(error_code) << "\n";
  8221. gtc->_already_applied = false;
  8222. return false;
  8223. }
  8224. }
  8225. #ifndef OPENGLES // OpenGL ES doesn't have GL_TEXTURE_MAX_LEVEL.
  8226. if (is_at_least_gl_version(1, 2)) {
  8227. if (load_ram_mipmaps) {
  8228. // By the time we get here, we have successfully loaded a certain
  8229. // number of mipmap levels. Tell the GL that's all it's going to
  8230. // get.
  8231. GLP(TexParameteri)(texture_target, GL_TEXTURE_MAX_LEVEL, highest_level - mipmap_bias);
  8232. } else if (uses_mipmaps) {
  8233. // Since the mipmap levels were auto-generated and are therefore
  8234. // complete, make sure the GL doesn't remember some previous value
  8235. // for GL_TEXTURE_MAX_LEVEL from the above call--set it to the
  8236. // full count of mipmap levels.
  8237. GLP(TexParameteri)(texture_target, GL_TEXTURE_MAX_LEVEL, tex->get_expected_num_mipmap_levels() - mipmap_bias - 1);
  8238. }
  8239. }
  8240. #endif
  8241. report_my_gl_errors();
  8242. return true;
  8243. }
  8244. ////////////////////////////////////////////////////////////////////
  8245. // Function: GLGraphicsStateGuardian::upload_simple_texture
  8246. // Access: Protected
  8247. // Description: This is used as a standin for upload_texture
  8248. // when the texture in question is unavailable (e.g. it
  8249. // hasn't yet been loaded from disk). Until the texture
  8250. // image itself becomes available, we will render the
  8251. // texture's "simple" image--a sharply reduced version
  8252. // of the same texture.
  8253. ////////////////////////////////////////////////////////////////////
  8254. bool CLP(GraphicsStateGuardian)::
  8255. upload_simple_texture(CLP(TextureContext) *gtc) {
  8256. report_my_gl_errors();
  8257. PStatTimer timer(_load_texture_pcollector);
  8258. Texture *tex = gtc->get_texture();
  8259. nassertr(tex != (Texture *)NULL, false);
  8260. int internal_format = GL_RGBA;
  8261. #ifdef OPENGLES_2
  8262. int external_format = GL_RGBA;
  8263. #else
  8264. int external_format = GL_BGRA;
  8265. #endif
  8266. const unsigned char *image_ptr = tex->get_simple_ram_image();
  8267. if (image_ptr == (const unsigned char *)NULL) {
  8268. return false;
  8269. }
  8270. size_t image_size = tex->get_simple_ram_image_size();
  8271. PTA_uchar bgr_image;
  8272. if (!_supports_bgr) {
  8273. // If the GL doesn't claim to support BGR, we may have to reverse
  8274. // the component ordering of the image.
  8275. external_format = GL_RGBA;
  8276. image_ptr = fix_component_ordering(bgr_image, image_ptr, image_size,
  8277. external_format, tex);
  8278. }
  8279. int width = tex->get_simple_x_size();
  8280. int height = tex->get_simple_y_size();
  8281. int component_type = GL_UNSIGNED_BYTE;
  8282. if (GLCAT.is_debug()) {
  8283. GLCAT.debug()
  8284. << "loading simple image for " << tex->get_name() << "\n";
  8285. }
  8286. #ifndef OPENGLES
  8287. // Turn off mipmaps for the simple texture.
  8288. if (tex->uses_mipmaps()) {
  8289. if (is_at_least_gl_version(1, 2)) {
  8290. GLP(TexParameteri)(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
  8291. }
  8292. }
  8293. #endif
  8294. #ifdef DO_PSTATS
  8295. _data_transferred_pcollector.add_level(image_size);
  8296. #endif
  8297. GLP(TexImage2D)(GL_TEXTURE_2D, 0, internal_format,
  8298. width, height, 0,
  8299. external_format, component_type, image_ptr);
  8300. gtc->mark_simple_loaded();
  8301. report_my_gl_errors();
  8302. return true;
  8303. }
  8304. ////////////////////////////////////////////////////////////////////
  8305. // Function: GLGraphicsStateGuardian::get_texture_memory_size
  8306. // Access: Protected
  8307. // Description: Asks OpenGL how much texture memory is consumed by
  8308. // the indicated texture (which is also the
  8309. // currently-selected texture).
  8310. ////////////////////////////////////////////////////////////////////
  8311. size_t CLP(GraphicsStateGuardian)::
  8312. get_texture_memory_size(Texture *tex) {
  8313. #ifdef OPENGLES // Texture querying not supported on OpenGL ES.
  8314. int width = tex->get_x_size();
  8315. int height = tex->get_y_size();
  8316. int depth = 1;
  8317. int scale = 1;
  8318. bool has_mipmaps = tex->uses_mipmaps();
  8319. size_t num_bytes = 2; // Temporary assumption?
  8320. #else
  8321. GLenum target = get_texture_target(tex->get_texture_type());
  8322. GLenum page_target = target;
  8323. GLint scale = 1;
  8324. if (target == GL_TEXTURE_CUBE_MAP) {
  8325. // We need a particular page to get the level parameter from.
  8326. page_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
  8327. scale = 6;
  8328. }
  8329. GLint minfilter;
  8330. GLP(GetTexParameteriv)(target, GL_TEXTURE_MIN_FILTER, &minfilter);
  8331. bool has_mipmaps = is_mipmap_filter(minfilter);
  8332. clear_my_gl_errors();
  8333. GLint internal_format;
  8334. GLP(GetTexLevelParameteriv)(page_target, 0, GL_TEXTURE_INTERNAL_FORMAT, &internal_format);
  8335. if (is_compressed_format(internal_format)) {
  8336. // Try to get the compressed size.
  8337. GLint image_size;
  8338. GLP(GetTexLevelParameteriv)(page_target, 0,
  8339. GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &image_size);
  8340. GLenum error_code = gl_get_error();
  8341. if (error_code != GL_NO_ERROR) {
  8342. if (GLCAT.is_debug()) {
  8343. GLCAT.debug()
  8344. << "Couldn't get compressed size for " << tex->get_name()
  8345. << " : " << get_error_string(error_code) << "\n";
  8346. }
  8347. // Fall through to the noncompressed case.
  8348. } else {
  8349. return image_size * scale;
  8350. }
  8351. }
  8352. // OK, get the noncompressed size.
  8353. GLint red_size, green_size, blue_size, alpha_size,
  8354. luminance_size, intensity_size;
  8355. GLint depth_size = 0;
  8356. GLP(GetTexLevelParameteriv)(page_target, 0,
  8357. GL_TEXTURE_RED_SIZE, &red_size);
  8358. GLP(GetTexLevelParameteriv)(page_target, 0,
  8359. GL_TEXTURE_GREEN_SIZE, &green_size);
  8360. GLP(GetTexLevelParameteriv)(page_target, 0,
  8361. GL_TEXTURE_BLUE_SIZE, &blue_size);
  8362. GLP(GetTexLevelParameteriv)(page_target, 0,
  8363. GL_TEXTURE_ALPHA_SIZE, &alpha_size);
  8364. GLP(GetTexLevelParameteriv)(page_target, 0,
  8365. GL_TEXTURE_LUMINANCE_SIZE, &luminance_size);
  8366. GLP(GetTexLevelParameteriv)(page_target, 0,
  8367. GL_TEXTURE_INTENSITY_SIZE, &intensity_size);
  8368. if (_supports_depth_texture) {
  8369. // Actually, this seems to cause problems on some Mesa versions,
  8370. // even though they advertise GL_ARB_depth_texture. Who needs it.
  8371. // GLP(GetTexLevelParameteriv)(page_target, 0,
  8372. // GL_TEXTURE_DEPTH_SIZE, &depth_size);
  8373. }
  8374. GLint width = 1, height = 1, depth = 1;
  8375. GLP(GetTexLevelParameteriv)(page_target, 0, GL_TEXTURE_WIDTH, &width);
  8376. GLP(GetTexLevelParameteriv)(page_target, 0, GL_TEXTURE_HEIGHT, &height);
  8377. if (_supports_3d_texture || _supports_2d_texture_array) {
  8378. GLP(GetTexLevelParameteriv)(page_target, 0, GL_TEXTURE_DEPTH, &depth);
  8379. }
  8380. report_my_gl_errors();
  8381. size_t num_bits = (red_size + green_size + blue_size + alpha_size + luminance_size + intensity_size + depth_size);
  8382. size_t num_bytes = (num_bits + 7) / 8;
  8383. #endif // OPENGLES
  8384. size_t result = num_bytes * width * height * depth * scale;
  8385. if (has_mipmaps) {
  8386. result = (result * 4) / 3;
  8387. }
  8388. return result;
  8389. }
  8390. ////////////////////////////////////////////////////////////////////
  8391. // Function: GLGraphicsStateGuardian::check_nonresident_texture
  8392. // Access: Private
  8393. // Description: Checks the list of resident texture objects to see if
  8394. // any have recently been evicted.
  8395. ////////////////////////////////////////////////////////////////////
  8396. void CLP(GraphicsStateGuardian)::
  8397. check_nonresident_texture(BufferContextChain &chain) {
  8398. #ifndef OPENGLES // Residency queries not supported by OpenGL ES.
  8399. size_t num_textures = chain.get_count();
  8400. if (num_textures == 0) {
  8401. return;
  8402. }
  8403. CLP(TextureContext) **gtc_list = (CLP(TextureContext) **)alloca(num_textures * sizeof(CLP(TextureContext) *));
  8404. GLuint *texture_list = (GLuint *)alloca(num_textures * sizeof(GLuint));
  8405. size_t ti = 0;
  8406. BufferContext *node = chain.get_first();
  8407. while (node != (BufferContext *)NULL) {
  8408. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), node);
  8409. gtc_list[ti] = gtc;
  8410. texture_list[ti] = gtc->_index;
  8411. node = node->get_next();
  8412. ++ti;
  8413. }
  8414. nassertv(ti == num_textures);
  8415. GLboolean *results = (GLboolean *)alloca(num_textures * sizeof(GLboolean));
  8416. bool all_resident = (GLP(AreTexturesResident)(num_textures, texture_list, results) != 0);
  8417. report_my_gl_errors();
  8418. if (!all_resident) {
  8419. // Some are now nonresident.
  8420. for (ti = 0; ti < num_textures; ++ti) {
  8421. if (!results[ti]) {
  8422. gtc_list[ti]->set_resident(false);
  8423. }
  8424. }
  8425. }
  8426. #endif // OPENGLES
  8427. }
  8428. ////////////////////////////////////////////////////////////////////
  8429. // Function: GLGraphicsStateGuardian::do_extract_texture_data
  8430. // Access: Protected
  8431. // Description: The internal implementation of
  8432. // extract_texture_data(), given an already-created
  8433. // TextureContext.
  8434. ////////////////////////////////////////////////////////////////////
  8435. bool CLP(GraphicsStateGuardian)::
  8436. do_extract_texture_data(CLP(TextureContext) *gtc) {
  8437. report_my_gl_errors();
  8438. GLenum target = gtc->_target;
  8439. if (target == GL_NONE) {
  8440. return false;
  8441. }
  8442. GLP(BindTexture)(target, gtc->_index);
  8443. Texture *tex = gtc->get_texture();
  8444. GLint wrap_u, wrap_v, wrap_w;
  8445. GLint minfilter, magfilter;
  8446. GLfloat border_color[4];
  8447. GLP(GetTexParameteriv)(target, GL_TEXTURE_WRAP_S, &wrap_u);
  8448. GLP(GetTexParameteriv)(target, GL_TEXTURE_WRAP_T, &wrap_v);
  8449. wrap_w = GL_REPEAT;
  8450. if (_supports_3d_texture) {
  8451. #ifdef OPENGLES_2
  8452. GLP(GetTexParameteriv)(target, GL_TEXTURE_WRAP_R_OES, &wrap_w);
  8453. #endif
  8454. #ifndef OPENGLES
  8455. GLP(GetTexParameteriv)(target, GL_TEXTURE_WRAP_R, &wrap_w);
  8456. #endif
  8457. }
  8458. if (_supports_2d_texture_array) {
  8459. #ifndef OPENGLES
  8460. GLP(GetTexParameteriv)(target, GL_TEXTURE_WRAP_R, &wrap_w);
  8461. #endif
  8462. }
  8463. GLP(GetTexParameteriv)(target, GL_TEXTURE_MIN_FILTER, &minfilter);
  8464. // Mesa has a bug querying this property.
  8465. magfilter = GL_LINEAR;
  8466. // GLP(GetTexParameteriv)(target, GL_TEXTURE_MAG_FILTER, &magfilter);
  8467. #ifndef OPENGLES
  8468. GLP(GetTexParameterfv)(target, GL_TEXTURE_BORDER_COLOR, border_color);
  8469. #endif
  8470. GLenum page_target = target;
  8471. if (target == GL_TEXTURE_CUBE_MAP) {
  8472. // We need a particular page to get the level parameter from.
  8473. page_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
  8474. }
  8475. GLint width = gtc->_width, height = gtc->_height, depth = gtc->_depth;
  8476. #ifndef OPENGLES
  8477. GLP(GetTexLevelParameteriv)(page_target, 0, GL_TEXTURE_WIDTH, &width);
  8478. if (target != GL_TEXTURE_1D) {
  8479. GLP(GetTexLevelParameteriv)(page_target, 0, GL_TEXTURE_HEIGHT, &height);
  8480. }
  8481. if (_supports_3d_texture && target == GL_TEXTURE_3D) {
  8482. GLP(GetTexLevelParameteriv)(page_target, 0, GL_TEXTURE_DEPTH, &depth);
  8483. }
  8484. #ifndef OPENGLES
  8485. else if (_supports_2d_texture_array && target == GL_TEXTURE_2D_ARRAY_EXT) {
  8486. GLP(GetTexLevelParameteriv)(page_target, 0, GL_TEXTURE_DEPTH, &depth);
  8487. }
  8488. #endif
  8489. else if (target == GL_TEXTURE_CUBE_MAP) {
  8490. depth = 6;
  8491. }
  8492. #endif
  8493. clear_my_gl_errors();
  8494. if (width <= 0 || height <= 0 || depth <= 0) {
  8495. GLCAT.error()
  8496. << "No texture data for " << tex->get_name() << "\n";
  8497. return false;
  8498. }
  8499. GLint internal_format = GL_RGBA;
  8500. #ifndef OPENGLES
  8501. GLP(GetTexLevelParameteriv)(page_target, 0, GL_TEXTURE_INTERNAL_FORMAT, &internal_format);
  8502. #endif // OPENGLES
  8503. // Make sure we were able to query those parameters properly.
  8504. GLenum error_code = gl_get_error();
  8505. if (error_code != GL_NO_ERROR) {
  8506. GLCAT.error()
  8507. << "Unable to query texture parameters for " << tex->get_name()
  8508. << " : " << get_error_string(error_code) << "\n";
  8509. return false;
  8510. }
  8511. Texture::ComponentType type = Texture::T_unsigned_byte;
  8512. Texture::Format format = Texture::F_rgb;
  8513. Texture::CompressionMode compression = Texture::CM_off;
  8514. switch (internal_format) {
  8515. #ifndef OPENGLES
  8516. case GL_COLOR_INDEX:
  8517. format = Texture::F_color_index;
  8518. break;
  8519. #endif
  8520. #if GL_DEPTH_COMPONENT != GL_DEPTH_COMPONENT24
  8521. case GL_DEPTH_COMPONENT:
  8522. #endif
  8523. case GL_DEPTH_COMPONENT16:
  8524. case GL_DEPTH_COMPONENT24:
  8525. case GL_DEPTH_COMPONENT32:
  8526. type = Texture::T_float;
  8527. format = Texture::F_depth_component;
  8528. break;
  8529. #ifndef OPENGLES_2
  8530. case GL_DEPTH_STENCIL_EXT:
  8531. case GL_DEPTH24_STENCIL8_EXT:
  8532. type = Texture::T_float;
  8533. format = Texture::F_depth_stencil;
  8534. break;
  8535. #endif
  8536. case GL_RGBA:
  8537. case 4:
  8538. format = Texture::F_rgba;
  8539. break;
  8540. case GL_RGBA4:
  8541. format = Texture::F_rgba4;
  8542. break;
  8543. #ifndef OPENGLES_2
  8544. case GL_RGBA8:
  8545. format = Texture::F_rgba8;
  8546. break;
  8547. #endif
  8548. #ifndef OPENGLES
  8549. case GL_RGBA12:
  8550. type = Texture::T_unsigned_short;
  8551. format = Texture::F_rgba12;
  8552. break;
  8553. #endif
  8554. case GL_RGB:
  8555. case 3:
  8556. format = Texture::F_rgb;
  8557. break;
  8558. #ifndef OPENGLES
  8559. case GL_RGB5:
  8560. format = Texture::F_rgb5;
  8561. break;
  8562. #endif
  8563. case GL_RGB5_A1:
  8564. format = Texture::F_rgba5;
  8565. break;
  8566. #ifndef OPENGLES
  8567. case GL_RGB8:
  8568. format = Texture::F_rgb8;
  8569. break;
  8570. case GL_RGB12:
  8571. format = Texture::F_rgb12;
  8572. break;
  8573. case GL_R3_G3_B2:
  8574. format = Texture::F_rgb332;
  8575. case GL_RED:
  8576. format = Texture::F_red;
  8577. break;
  8578. case GL_GREEN:
  8579. format = Texture::F_green;
  8580. break;
  8581. case GL_BLUE:
  8582. format = Texture::F_blue;
  8583. break;
  8584. #endif // OPENGLES
  8585. case GL_ALPHA:
  8586. format = Texture::F_alpha;
  8587. break;
  8588. case GL_LUMINANCE:
  8589. case 1:
  8590. format = Texture::F_luminance;
  8591. break;
  8592. case GL_LUMINANCE_ALPHA:
  8593. case 2:
  8594. format = Texture::F_luminance_alpha;
  8595. break;
  8596. #ifndef OPENGLES
  8597. case GL_COMPRESSED_RGB:
  8598. format = Texture::F_rgb;
  8599. compression = Texture::CM_on;
  8600. break;
  8601. case GL_COMPRESSED_RGBA:
  8602. format = Texture::F_rgba;
  8603. compression = Texture::CM_on;
  8604. break;
  8605. case GL_COMPRESSED_ALPHA:
  8606. format = Texture::F_alpha;
  8607. compression = Texture::CM_on;
  8608. break;
  8609. case GL_COMPRESSED_LUMINANCE:
  8610. format = Texture::F_luminance;
  8611. compression = Texture::CM_on;
  8612. break;
  8613. case GL_COMPRESSED_LUMINANCE_ALPHA:
  8614. format = Texture::F_luminance_alpha;
  8615. compression = Texture::CM_on;
  8616. break;
  8617. #endif
  8618. #ifndef OPENGLES_1
  8619. case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  8620. format = Texture::F_rgb;
  8621. compression = Texture::CM_dxt1;
  8622. break;
  8623. case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  8624. format = Texture::F_rgbm;
  8625. compression = Texture::CM_dxt1;
  8626. break;
  8627. #endif
  8628. #ifdef OPENGLES
  8629. case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
  8630. format = Texture::F_rgb;
  8631. compression = Texture::CM_pvr1_2bpp;
  8632. break;
  8633. case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
  8634. format = Texture::F_rgba;
  8635. compression = Texture::CM_pvr1_2bpp;
  8636. break;
  8637. case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
  8638. format = Texture::F_rgb;
  8639. compression = Texture::CM_pvr1_4bpp;
  8640. break;
  8641. case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
  8642. format = Texture::F_rgba;
  8643. compression = Texture::CM_pvr1_4bpp;
  8644. break;
  8645. #else
  8646. case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
  8647. format = Texture::F_rgba;
  8648. compression = Texture::CM_dxt3;
  8649. break;
  8650. case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
  8651. format = Texture::F_rgba;
  8652. compression = Texture::CM_dxt5;
  8653. break;
  8654. case GL_COMPRESSED_RGB_FXT1_3DFX:
  8655. format = Texture::F_rgb;
  8656. compression = Texture::CM_fxt1;
  8657. break;
  8658. case GL_COMPRESSED_RGBA_FXT1_3DFX:
  8659. format = Texture::F_rgba;
  8660. compression = Texture::CM_fxt1;
  8661. break;
  8662. #endif
  8663. default:
  8664. GLCAT.warning()
  8665. << "Unhandled internal format for " << tex->get_name()
  8666. << " : " << hex << "0x" << internal_format << dec << "\n";
  8667. return false;
  8668. }
  8669. // We don't want to call setup_texture() again; that resets too
  8670. // much. Instead, we'll just set the individual components.
  8671. tex->set_x_size(width);
  8672. tex->set_y_size(height);
  8673. tex->set_z_size(depth);
  8674. tex->set_component_type(type);
  8675. tex->set_format(format);
  8676. tex->set_wrap_u(get_panda_wrap_mode(wrap_u));
  8677. tex->set_wrap_v(get_panda_wrap_mode(wrap_v));
  8678. tex->set_wrap_w(get_panda_wrap_mode(wrap_w));
  8679. tex->set_border_color(LColor(border_color[0], border_color[1],
  8680. border_color[2], border_color[3]));
  8681. tex->set_minfilter(get_panda_filter_type(minfilter));
  8682. // tex->set_magfilter(get_panda_filter_type(magfilter));
  8683. PTA_uchar image;
  8684. size_t page_size = 0;
  8685. if (!extract_texture_image(image, page_size, tex, target, page_target,
  8686. type, compression, 0)) {
  8687. return false;
  8688. }
  8689. tex->set_ram_image(image, compression, page_size);
  8690. if (tex->uses_mipmaps()) {
  8691. // Also get the mipmap levels.
  8692. GLint num_expected_levels = tex->get_expected_num_mipmap_levels();
  8693. GLint highest_level = num_expected_levels;
  8694. #ifndef OPENGLES
  8695. if (is_at_least_gl_version(1, 2)) {
  8696. GLP(GetTexParameteriv)(target, GL_TEXTURE_MAX_LEVEL, &highest_level);
  8697. highest_level = min(highest_level, num_expected_levels);
  8698. }
  8699. #endif
  8700. for (int n = 1; n <= highest_level; ++n) {
  8701. if (!extract_texture_image(image, page_size, tex, target, page_target,
  8702. type, compression, n)) {
  8703. return false;
  8704. }
  8705. tex->set_ram_mipmap_image(n, image, page_size);
  8706. }
  8707. }
  8708. return true;
  8709. }
  8710. ////////////////////////////////////////////////////////////////////
  8711. // Function: GLGraphicsStateGuardian::extract_texture_image
  8712. // Access: Protected
  8713. // Description: Called from extract_texture_data(), this gets just
  8714. // the image array for a particular mipmap level (or for
  8715. // the base image).
  8716. ////////////////////////////////////////////////////////////////////
  8717. bool CLP(GraphicsStateGuardian)::
  8718. extract_texture_image(PTA_uchar &image, size_t &page_size,
  8719. Texture *tex, GLenum target, GLenum page_target,
  8720. Texture::ComponentType type,
  8721. Texture::CompressionMode compression, int n) {
  8722. #ifdef OPENGLES // Extracting texture data unsupported in OpenGL ES.
  8723. nassertr(false, false);
  8724. return false;
  8725. #else
  8726. if (target == GL_TEXTURE_CUBE_MAP) {
  8727. // A cube map, compressed or uncompressed. This we must extract
  8728. // one page at a time.
  8729. // If the cube map is compressed, we assume that all the
  8730. // compressed pages are exactly the same size. OpenGL doesn't
  8731. // make this assumption, but it happens to be true for all
  8732. // currently extant compression schemes, and it makes things
  8733. // simpler for us. (It also makes things much simpler for the
  8734. // graphics hardware, so it's likely to continue to be true for a
  8735. // while at least.)
  8736. GLenum external_format = get_external_image_format(tex);
  8737. GLenum pixel_type = get_component_type(type);
  8738. page_size = tex->get_expected_ram_mipmap_page_size(n);
  8739. if (compression != Texture::CM_off) {
  8740. GLint image_size;
  8741. GLP(GetTexLevelParameteriv)(page_target, n,
  8742. GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &image_size);
  8743. nassertr(image_size <= (int)page_size, false);
  8744. page_size = image_size;
  8745. }
  8746. image = PTA_uchar::empty_array(page_size * 6);
  8747. for (int z = 0; z < 6; ++z) {
  8748. page_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + z;
  8749. if (compression == Texture::CM_off) {
  8750. GLP(GetTexImage)(page_target, n, external_format, pixel_type,
  8751. image.p() + z * page_size);
  8752. } else {
  8753. _glGetCompressedTexImage(page_target, 0, image.p() + z * page_size);
  8754. }
  8755. }
  8756. } else if (compression == Texture::CM_off) {
  8757. // An uncompressed 1-d, 2-d, or 3-d texture.
  8758. image = PTA_uchar::empty_array(tex->get_expected_ram_mipmap_image_size(n));
  8759. GLenum external_format = get_external_image_format(tex);
  8760. GLenum pixel_type = get_component_type(type);
  8761. GLP(GetTexImage)(target, n, external_format, pixel_type, image.p());
  8762. } else {
  8763. // A compressed 1-d, 2-d, or 3-d texture.
  8764. GLint image_size;
  8765. GLP(GetTexLevelParameteriv)(target, n, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &image_size);
  8766. page_size = image_size / tex->get_z_size();
  8767. image = PTA_uchar::empty_array(image_size);
  8768. // Some drivers (ATI!) seem to try to overstuff more bytes in the
  8769. // array than they asked us to allocate (that is, more bytes than
  8770. // GL_TEXTURE_COMPRESSED_IMAGE_SIZE), requiring us to overallocate
  8771. // and then copy the result into our final buffer. Sheesh.
  8772. // We'll only do this for small textures (the ATI bug doesn't
  8773. // *seem* to affect large textures), to save on the overhead of
  8774. // the double-copy, and reduce risk from an overly-large alloca().
  8775. #ifndef NDEBUG
  8776. static const int max_trouble_buffer = 102400;
  8777. #else
  8778. static const int max_trouble_buffer = 1024;
  8779. #endif
  8780. if (image_size < max_trouble_buffer) {
  8781. static const int extra_space = 32;
  8782. unsigned char *buffer = (unsigned char *)alloca(image_size + extra_space);
  8783. #ifndef NDEBUG
  8784. // Tag the buffer with a specific byte so we can report on
  8785. // whether that driver bug is still active.
  8786. static unsigned char keep_token = 0x00;
  8787. unsigned char token = ++keep_token;
  8788. memset(buffer + image_size, token, extra_space);
  8789. #endif
  8790. _glGetCompressedTexImage(target, n, buffer);
  8791. memcpy(image.p(), buffer, image_size);
  8792. #ifndef NDEBUG
  8793. int count = extra_space;
  8794. while (count > 0 && buffer[image_size + count - 1] == token) {
  8795. --count;
  8796. }
  8797. if (count != 0) {
  8798. GLCAT.warning()
  8799. << "GL graphics driver overfilled " << count
  8800. << " bytes into a " << image_size
  8801. << "-byte buffer provided to glGetCompressedTexImage()\n";
  8802. }
  8803. // This had better not equal the amount of buffer space we set
  8804. // aside. If it does, we assume the driver might have
  8805. // overfilled even our provided extra buffer.
  8806. nassertr(count != extra_space, true)
  8807. #endif // NDEBUG
  8808. } else {
  8809. _glGetCompressedTexImage(target, n, image.p());
  8810. }
  8811. }
  8812. // Now see if we were successful.
  8813. GLenum error_code = gl_get_error();
  8814. if (error_code != GL_NO_ERROR) {
  8815. GLCAT.error()
  8816. << "Unable to extract texture for " << *tex
  8817. << ", mipmap level " << n
  8818. << " : " << get_error_string(error_code) << "\n";
  8819. nassertr(false, false);
  8820. return false;
  8821. }
  8822. return true;
  8823. #endif // OPENGLES
  8824. }
  8825. ////////////////////////////////////////////////////////////////////
  8826. // Function: GLGraphicsStateGuardian::do_point_size
  8827. // Access: Protected
  8828. // Description: Internally sets the point size parameters after any
  8829. // of the properties have changed that might affect
  8830. // this.
  8831. ////////////////////////////////////////////////////////////////////
  8832. void CLP(GraphicsStateGuardian)::
  8833. do_point_size() {
  8834. #ifndef OPENGLES_2
  8835. if (!_point_perspective) {
  8836. // Normal, constant-sized points. Here _point_size is a width in
  8837. // pixels.
  8838. static LVecBase3f constant(1.0f, 0.0f, 0.0f);
  8839. _glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, constant.get_data());
  8840. } else {
  8841. // Perspective-sized points. Here _point_size is a width in 3-d
  8842. // units. To arrange that, we need to figure out the appropriate
  8843. // scaling factor based on the current viewport and projection
  8844. // matrix.
  8845. LVector3 height(0.0f, _point_size, 1.0f);
  8846. height = height * _projection_mat->get_mat();
  8847. PN_stdfloat s = height[1] * _viewport_height / _point_size;
  8848. if (_current_lens->is_orthographic()) {
  8849. // If we have an orthographic lens in effect, we don't actually
  8850. // apply a perspective transform: we just scale the points once,
  8851. // regardless of the distance from the camera.
  8852. LVecBase3f constant(1.0f / (s * s), 0.0f, 0.0f);
  8853. _glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, constant.get_data());
  8854. } else {
  8855. // Otherwise, we give it a true perspective adjustment.
  8856. LVecBase3f square(0.0f, 0.0f, 1.0f / (s * s));
  8857. _glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, square.get_data());
  8858. }
  8859. }
  8860. report_my_gl_errors();
  8861. #endif
  8862. }
  8863. ////////////////////////////////////////////////////////////////////
  8864. // Function: GLGraphicsStateGuardian::get_supports_cg_profile
  8865. // Access: Public, Virtual
  8866. // Description: Returns true if this particular GSG supports the
  8867. // specified Cg Shader Profile.
  8868. ////////////////////////////////////////////////////////////////////
  8869. bool CLP(GraphicsStateGuardian)::
  8870. get_supports_cg_profile(const string &name) const {
  8871. #if !defined(HAVE_CG) || defined(OPENGLES)
  8872. return false;
  8873. #else
  8874. CGprofile profile = cgGetProfile(name.c_str());
  8875. if (profile == CG_PROFILE_UNKNOWN) {
  8876. GLCAT.error() << name <<", unknown Cg-profile\n";
  8877. return false;
  8878. }
  8879. return (cgGLIsProfileSupported(profile) != 0);
  8880. #endif
  8881. }
  8882. ////////////////////////////////////////////////////////////////////
  8883. // Function: GLGraphicsStateGuardian::bind_fbo
  8884. // Access: Protected
  8885. // Description: Binds an FBO object.
  8886. ////////////////////////////////////////////////////////////////////
  8887. void CLP(GraphicsStateGuardian)::
  8888. bind_fbo(GLuint fbo) {
  8889. nassertv(_glBindFramebuffer != 0);
  8890. #if defined(OPENGLES_2)
  8891. _glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  8892. #elif defined(OPENGLES_1)
  8893. _glBindFramebuffer(GL_FRAMEBUFFER_OES, fbo);
  8894. #else
  8895. _glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
  8896. #endif
  8897. _current_fbo = fbo;
  8898. }
  8899. ////////////////////////////////////////////////////////////////////
  8900. // GL stencil code section
  8901. ////////////////////////////////////////////////////////////////////
  8902. static int gl_stencil_comparison_function_array [ ] = {
  8903. GL_NEVER,
  8904. GL_LESS,
  8905. GL_EQUAL,
  8906. GL_LEQUAL,
  8907. GL_GREATER,
  8908. GL_NOTEQUAL,
  8909. GL_GEQUAL,
  8910. GL_ALWAYS,
  8911. };
  8912. static int gl_stencil_operations_array [ ] = {
  8913. GL_KEEP,
  8914. GL_ZERO,
  8915. GL_REPLACE,
  8916. #ifdef OPENGLES_1
  8917. GL_INCR_WRAP_OES,
  8918. GL_DECR_WRAP_OES,
  8919. #else
  8920. GL_INCR_WRAP,
  8921. GL_DECR_WRAP,
  8922. #endif
  8923. GL_INVERT,
  8924. GL_INCR,
  8925. GL_DECR,
  8926. };
  8927. void __glActiveStencilFace (GraphicsStateGuardian *gsg, GLenum face) {
  8928. CLP(GraphicsStateGuardian) *glgsg;
  8929. glgsg = (CLP(GraphicsStateGuardian) *) gsg;
  8930. if (gsg -> get_supports_two_sided_stencil ( ) &&
  8931. glgsg -> _glActiveStencilFaceEXT) {
  8932. if (face == GL_FRONT) {
  8933. // glActiveStencilFaceEXT (GL_FRONT);
  8934. glgsg -> _glActiveStencilFaceEXT (GL_FRONT);
  8935. }
  8936. else {
  8937. // glActiveStencilFaceEXT (GL_BACK);
  8938. glgsg -> _glActiveStencilFaceEXT (GL_BACK);
  8939. }
  8940. }
  8941. }
  8942. void gl_front_stencil_function (StencilRenderStates::StencilRenderState stencil_render_state, StencilRenderStates *stencil_render_states) {
  8943. __glActiveStencilFace (stencil_render_states -> _gsg, GL_FRONT);
  8944. glStencilFunc
  8945. (
  8946. gl_stencil_comparison_function_array [stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_front_comparison_function)],
  8947. stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_reference),
  8948. stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_read_mask)
  8949. );
  8950. }
  8951. void gl_front_stencil_operation (StencilRenderStates::StencilRenderState stencil_render_state, StencilRenderStates *stencil_render_states) {
  8952. __glActiveStencilFace (stencil_render_states -> _gsg, GL_FRONT);
  8953. glStencilOp
  8954. (
  8955. gl_stencil_operations_array [stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_front_stencil_fail_operation)],
  8956. gl_stencil_operations_array [stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_front_stencil_pass_z_fail_operation)],
  8957. gl_stencil_operations_array [stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_front_stencil_pass_z_pass_operation)]
  8958. );
  8959. }
  8960. void gl_back_stencil_function (StencilRenderStates::StencilRenderState stencil_render_state, StencilRenderStates *stencil_render_states) {
  8961. bool supports_two_sided_stencil;
  8962. supports_two_sided_stencil = stencil_render_states -> _gsg -> get_supports_two_sided_stencil ( );
  8963. if (supports_two_sided_stencil) {
  8964. __glActiveStencilFace (stencil_render_states -> _gsg, GL_BACK);
  8965. glStencilFunc
  8966. (
  8967. gl_stencil_comparison_function_array [stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_back_comparison_function)],
  8968. stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_reference),
  8969. stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_read_mask)
  8970. );
  8971. }
  8972. }
  8973. void gl_back_stencil_operation (StencilRenderStates::StencilRenderState stencil_render_state, StencilRenderStates *stencil_render_states) {
  8974. bool supports_two_sided_stencil;
  8975. supports_two_sided_stencil = stencil_render_states -> _gsg -> get_supports_two_sided_stencil ( );
  8976. if (supports_two_sided_stencil) {
  8977. __glActiveStencilFace (stencil_render_states -> _gsg, GL_BACK);
  8978. glStencilOp
  8979. (
  8980. gl_stencil_operations_array [stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_back_stencil_fail_operation)],
  8981. gl_stencil_operations_array [stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_back_stencil_pass_z_fail_operation)],
  8982. gl_stencil_operations_array [stencil_render_states -> get_stencil_render_state (StencilRenderStates::SRS_back_stencil_pass_z_pass_operation)]
  8983. );
  8984. }
  8985. }
  8986. void gl_front_back_stencil_function (StencilRenderStates::StencilRenderState stencil_render_state, StencilRenderStates *stencil_render_states) {
  8987. gl_front_stencil_function (stencil_render_state, stencil_render_states);
  8988. gl_back_stencil_function (stencil_render_state, stencil_render_states);
  8989. }
  8990. void gl_stencil_function (StencilRenderStates::StencilRenderState stencil_render_state, StencilRenderStates *stencil_render_states) {
  8991. StencilType render_state_value;
  8992. bool supports_two_sided_stencil;
  8993. supports_two_sided_stencil = stencil_render_states -> _gsg -> get_supports_two_sided_stencil ( );
  8994. render_state_value = stencil_render_states -> get_stencil_render_state (stencil_render_state);
  8995. switch (stencil_render_state) {
  8996. case StencilRenderStates::SRS_front_enable:
  8997. if (render_state_value) {
  8998. glEnable (GL_STENCIL_TEST);
  8999. }
  9000. else {
  9001. glDisable (GL_STENCIL_TEST);
  9002. }
  9003. break;
  9004. #ifndef OPENGLES
  9005. case StencilRenderStates::SRS_back_enable:
  9006. if (supports_two_sided_stencil) {
  9007. if (render_state_value) {
  9008. glEnable (GL_STENCIL_TEST_TWO_SIDE_EXT);
  9009. }
  9010. else {
  9011. glDisable (GL_STENCIL_TEST_TWO_SIDE_EXT);
  9012. }
  9013. }
  9014. break;
  9015. #endif
  9016. case StencilRenderStates::SRS_write_mask:
  9017. glStencilMask (render_state_value);
  9018. break;
  9019. default:
  9020. break;
  9021. }
  9022. }
  9023. void gl_set_stencil_functions (StencilRenderStates *stencil_render_states) {
  9024. if (stencil_render_states) {
  9025. stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_front_enable, gl_stencil_function);
  9026. stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_back_enable, gl_stencil_function);
  9027. stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_front_comparison_function, gl_front_stencil_function);
  9028. stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_front_stencil_fail_operation, gl_front_stencil_operation);
  9029. stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_front_stencil_pass_z_fail_operation, gl_front_stencil_operation);
  9030. stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_front_stencil_pass_z_pass_operation, gl_front_stencil_operation);
  9031. // GL seems to support different read masks and/or reference values for front and back, but DX does not.
  9032. // This needs to be cross-platform so do it the DX way by setting the same read mask and reference for both front and back.
  9033. stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_reference, gl_front_back_stencil_function);
  9034. stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_read_mask, gl_front_back_stencil_function);
  9035. stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_write_mask, gl_stencil_function);
  9036. stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_back_comparison_function, gl_back_stencil_function);
  9037. stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_back_stencil_fail_operation, gl_back_stencil_operation);
  9038. stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_back_stencil_pass_z_fail_operation, gl_back_stencil_operation);
  9039. stencil_render_states -> set_stencil_function (StencilRenderStates::SRS_back_stencil_pass_z_pass_operation, gl_back_stencil_operation);
  9040. }
  9041. }
  9042. ////////////////////////////////////////////////////////////////////
  9043. // Function: GLGraphicsStateGuardian::do_issue_stencil
  9044. // Access: Protected
  9045. // Description: Set stencil render states.
  9046. ////////////////////////////////////////////////////////////////////
  9047. void CLP(GraphicsStateGuardian)::
  9048. do_issue_stencil() {
  9049. if (!_supports_stencil) {
  9050. return;
  9051. }
  9052. const StencilAttrib *stencil = DCAST(StencilAttrib, _target_rs->get_attrib_def(StencilAttrib::get_class_slot()));
  9053. StencilRenderStates *stencil_render_states;
  9054. stencil_render_states = this -> _stencil_render_states;
  9055. if (stencil && stencil_render_states) {
  9056. // DEBUG
  9057. if (false) {
  9058. GLCAT.debug() << "STENCIL STATE CHANGE\n";
  9059. GLCAT.debug() << "\n"
  9060. << "SRS_front_enable " << (int)stencil -> get_render_state (StencilAttrib::SRS_front_enable) << "\n"
  9061. << "SRS_back_enable " << (int)stencil -> get_render_state (StencilAttrib::SRS_back_enable) << "\n"
  9062. << "SRS_front_comparison_function " << (int)stencil -> get_render_state (StencilAttrib::SRS_front_comparison_function) << "\n"
  9063. << "SRS_front_stencil_fail_operation " << (int)stencil -> get_render_state (StencilAttrib::SRS_front_stencil_fail_operation) << "\n"
  9064. << "SRS_front_stencil_pass_z_fail_operation " << (int)stencil -> get_render_state (StencilAttrib::SRS_front_stencil_pass_z_fail_operation) << "\n"
  9065. << "SRS_front_stencil_pass_z_pass_operation " << (int)stencil -> get_render_state (StencilAttrib::SRS_front_stencil_pass_z_pass_operation) << "\n"
  9066. << "SRS_reference " << (int)stencil -> get_render_state (StencilAttrib::SRS_reference) << "\n"
  9067. << "SRS_read_mask " << (int)stencil -> get_render_state (StencilAttrib::SRS_read_mask) << "\n"
  9068. << "SRS_write_mask " << (int)stencil -> get_render_state (StencilAttrib::SRS_write_mask) << "\n"
  9069. << "SRS_back_comparison_function " << (int)stencil -> get_render_state (StencilAttrib::SRS_back_comparison_function) << "\n"
  9070. << "SRS_back_stencil_fail_operation " << (int)stencil -> get_render_state (StencilAttrib::SRS_back_stencil_fail_operation) << "\n"
  9071. << "SRS_back_stencil_pass_z_fail_operation " << (int)stencil -> get_render_state (StencilAttrib::SRS_back_stencil_pass_z_fail_operation) << "\n"
  9072. << "SRS_back_stencil_pass_z_pass_operation " << (int)stencil -> get_render_state (StencilAttrib::SRS_back_stencil_pass_z_pass_operation) << "\n";
  9073. }
  9074. {
  9075. bool on;
  9076. on = false;
  9077. stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_enable, stencil -> get_render_state (StencilAttrib::SRS_front_enable));
  9078. if (stencil -> get_render_state (StencilAttrib::SRS_front_enable)) {
  9079. stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_comparison_function, stencil -> get_render_state (StencilAttrib::SRS_front_comparison_function));
  9080. stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_stencil_fail_operation, stencil -> get_render_state (StencilAttrib::SRS_front_stencil_fail_operation));
  9081. stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_stencil_pass_z_fail_operation, stencil -> get_render_state (StencilAttrib::SRS_front_stencil_pass_z_fail_operation));
  9082. stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_stencil_pass_z_pass_operation, stencil -> get_render_state (StencilAttrib::SRS_front_stencil_pass_z_pass_operation));
  9083. on = true;
  9084. }
  9085. stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_back_enable, stencil -> get_render_state (StencilAttrib::SRS_back_enable));
  9086. if (stencil -> get_render_state (StencilAttrib::SRS_back_enable)) {
  9087. stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_back_comparison_function, stencil -> get_render_state (StencilAttrib::SRS_back_comparison_function));
  9088. stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_back_stencil_fail_operation, stencil -> get_render_state (StencilAttrib::SRS_back_stencil_fail_operation));
  9089. stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_back_stencil_pass_z_fail_operation, stencil -> get_render_state (StencilAttrib::SRS_back_stencil_pass_z_fail_operation));
  9090. stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_back_stencil_pass_z_pass_operation, stencil -> get_render_state (StencilAttrib::SRS_back_stencil_pass_z_pass_operation));
  9091. on = true;
  9092. }
  9093. if (on) {
  9094. stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_reference, stencil -> get_render_state (StencilAttrib::SRS_reference));
  9095. stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_read_mask, stencil -> get_render_state (StencilAttrib::SRS_read_mask));
  9096. stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_write_mask, stencil -> get_render_state (StencilAttrib::SRS_write_mask));
  9097. }
  9098. }
  9099. if (stencil -> get_render_state (StencilAttrib::SRS_clear)) {
  9100. GLbitfield mask = 0;
  9101. // clear stencil buffer
  9102. GLP(ClearStencil)(stencil -> get_render_state (StencilAttrib::SRS_clear_value));
  9103. mask |= GL_STENCIL_BUFFER_BIT;
  9104. GLP(Clear)(mask);
  9105. }
  9106. }
  9107. else {
  9108. stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_front_enable, 0);
  9109. stencil_render_states -> set_stencil_render_state (true, StencilRenderStates::SRS_back_enable, 0);
  9110. }
  9111. }
  9112. ////////////////////////////////////////////////////////////////////
  9113. // Function: GLGraphicsStateGuardian::do_issue_scissor
  9114. // Access: Protected
  9115. // Description:
  9116. ////////////////////////////////////////////////////////////////////
  9117. void CLP(GraphicsStateGuardian)::
  9118. do_issue_scissor() {
  9119. const ScissorAttrib *target_scissor = DCAST(ScissorAttrib, _target_rs->get_attrib_def(ScissorAttrib::get_class_slot()));
  9120. const LVecBase4 &frame = target_scissor->get_frame();
  9121. int x = (int)(_viewport_x + _viewport_width * frame[0] + 0.5f);
  9122. int y = (int)(_viewport_y + _viewport_height * frame[2] + 0.5f);
  9123. int width = (int)(_viewport_width * (frame[1] - frame[0]) + 0.5f);
  9124. int height = (int)(_viewport_height * (frame[3] - frame[2]) + 0.5f);
  9125. GLP(Enable)(GL_SCISSOR_TEST);
  9126. GLP(Scissor)(x, y, width, height);
  9127. }