glGraphicsStateGuardian_src.cxx 426 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420
  1. /**
  2. * PANDA 3D SOFTWARE
  3. * Copyright (c) Carnegie Mellon University. All rights reserved.
  4. *
  5. * All use of this software is subject to the terms of the revised BSD
  6. * license. You should have received a copy of this license along
  7. * with this source code in a file named "LICENSE."
  8. *
  9. * @file glGraphicsStateGuardian_src.cxx
  10. * @author drose
  11. * @date 1999-02-02
  12. * @author fperazzi, PandaSE
  13. * @date 2010-05-05
  14. * get_supports_cg_profile)
  15. */
  16. #include "config_util.h"
  17. #include "displayRegion.h"
  18. #include "renderBuffer.h"
  19. #include "geom.h"
  20. #include "geomVertexData.h"
  21. #include "geomTriangles.h"
  22. #include "geomTristrips.h"
  23. #include "geomTrifans.h"
  24. #include "geomLines.h"
  25. #include "geomLinestrips.h"
  26. #include "geomPoints.h"
  27. #include "geomVertexReader.h"
  28. #include "graphicsWindow.h"
  29. #include "lens.h"
  30. #include "perspectiveLens.h"
  31. #include "directionalLight.h"
  32. #include "pointLight.h"
  33. #include "spotlight.h"
  34. #include "planeNode.h"
  35. #include "fog.h"
  36. #include "clockObject.h"
  37. #include "string_utils.h"
  38. #include "nodePath.h"
  39. #include "dcast.h"
  40. #include "pvector.h"
  41. #include "vector_string.h"
  42. #include "string_utils.h"
  43. #include "pnmImage.h"
  44. #include "config_gobj.h"
  45. #include "lightMutexHolder.h"
  46. #include "indirectLess.h"
  47. #include "pStatTimer.h"
  48. #include "load_prc_file.h"
  49. #include "bamCache.h"
  50. #include "bamCacheRecord.h"
  51. #include "alphaTestAttrib.h"
  52. #include "clipPlaneAttrib.h"
  53. #include "cullFaceAttrib.h"
  54. #include "depthOffsetAttrib.h"
  55. #include "depthWriteAttrib.h"
  56. #include "fogAttrib.h"
  57. #include "lightAttrib.h"
  58. #include "logicOpAttrib.h"
  59. #include "materialAttrib.h"
  60. #include "rescaleNormalAttrib.h"
  61. #include "scissorAttrib.h"
  62. #include "shadeModelAttrib.h"
  63. #include "stencilAttrib.h"
  64. #include "graphicsEngine.h"
  65. #include "shaderGenerator.h"
  66. #include "samplerState.h"
  67. #include "displayInformation.h"
  68. #if defined(HAVE_CG) && !defined(OPENGLES)
  69. #include "Cg/cgGL.h"
  70. #endif
  71. #include <algorithm>
  72. TypeHandle CLP(GraphicsStateGuardian)::_type_handle;
  73. PStatCollector CLP(GraphicsStateGuardian)::_load_display_list_pcollector("Draw:Transfer data:Display lists");
  74. PStatCollector CLP(GraphicsStateGuardian)::_primitive_batches_display_list_pcollector("Primitive batches:Display lists");
  75. PStatCollector CLP(GraphicsStateGuardian)::_vertices_display_list_pcollector("Vertices:Display lists");
  76. PStatCollector CLP(GraphicsStateGuardian)::_vertices_immediate_pcollector("Vertices:Immediate mode");
  77. PStatCollector CLP(GraphicsStateGuardian)::_memory_barrier_pcollector("Draw:Memory barriers");
  78. PStatCollector CLP(GraphicsStateGuardian)::_vertex_array_update_pcollector("Draw:Update arrays");
  79. PStatCollector CLP(GraphicsStateGuardian)::_texture_update_pcollector("Draw:Update texture");
  80. PStatCollector CLP(GraphicsStateGuardian)::_fbo_bind_pcollector("Draw:Bind FBO");
  81. PStatCollector CLP(GraphicsStateGuardian)::_check_error_pcollector("Draw:Check errors");
  82. #ifndef OPENGLES_1
  83. PT(Shader) CLP(GraphicsStateGuardian)::_default_shader = NULL;
  84. #endif
  85. // The following noop functions are assigned to the corresponding glext
  86. // function pointers in the class, in case the functions are not defined by
  87. // the GL, just so it will always be safe to call the extension functions.
  88. static void APIENTRY
  89. null_glPointParameterfv(GLenum, const GLfloat *) {
  90. }
  91. #ifdef OPENGLES_1
  92. // OpenGL ES 1 doesn't support this, period. Might as well macro it.
  93. #define _glDrawRangeElements(mode, start, end, count, type, indices) \
  94. glDrawElements(mode, count, type, indices)
  95. #else
  96. static void APIENTRY
  97. null_glDrawRangeElements(GLenum mode, GLuint start, GLuint end,
  98. GLsizei count, GLenum type, const GLvoid *indices) {
  99. // If we don't support glDrawRangeElements(), just use the original
  100. // glDrawElements() instead.
  101. glDrawElements(mode, count, type, indices);
  102. }
  103. #endif
  104. #if defined(OPENGLES) && !defined(OPENGLES_1)
  105. static void APIENTRY
  106. null_glVertexAttrib4dv(GLuint index, const GLdouble *v) {
  107. GLfloat vf[4] = {(GLfloat)v[0], (GLfloat)v[1], (GLfloat)v[2], (GLfloat)v[3]};
  108. glVertexAttrib4fv(index, vf);
  109. }
  110. #endif
  111. static void APIENTRY
  112. null_glActiveTexture(GLenum gl_texture_stage) {
  113. // If we don't support multitexture, we'd better not try to request a
  114. // texture beyond the first texture stage.
  115. nassertv(gl_texture_stage == GL_TEXTURE0);
  116. }
  117. #ifdef OPENGLES_2
  118. #define _glBlendEquation glBlendEquation
  119. #define _glBlendEquationSeparate glBlendEquationSeparate
  120. #define _glBlendFuncSeparate glBlendFuncSeparate
  121. #define _glBlendColor glBlendColor
  122. #else
  123. static void APIENTRY
  124. null_glBlendEquation(GLenum) {
  125. }
  126. static void APIENTRY
  127. null_glBlendFuncSeparate(GLenum src, GLenum dest, GLenum, GLenum) {
  128. glBlendFunc(src, dest);
  129. }
  130. static void APIENTRY
  131. null_glBlendColor(GLclampf, GLclampf, GLclampf, GLclampf) {
  132. }
  133. #endif
  134. #ifndef OPENGLES_1
  135. // We have a default shader that will be applied when there isn't any shader
  136. // applied (e.g. if it failed to compile). We need this because OpenGL ES
  137. // 2.x and OpenGL 3.2+ core don't have a fixed-function pipeline. This
  138. // default shader just applies a single texture, which is good enough for
  139. // drawing GUIs and such.
  140. static const string default_vshader =
  141. #ifndef OPENGLES
  142. "#version 130\n"
  143. "in vec4 p3d_Vertex;\n"
  144. "in vec4 p3d_Color;\n"
  145. "in vec2 p3d_MultiTexCoord0;\n"
  146. "out vec2 texcoord;\n"
  147. "out vec4 color;\n"
  148. #else
  149. "precision mediump float;\n"
  150. "attribute vec4 p3d_Vertex;\n"
  151. "attribute vec4 p3d_Color;\n"
  152. "attribute vec2 p3d_MultiTexCoord0;\n"
  153. "varying vec2 texcoord;\n"
  154. "varying lowp vec4 color;\n"
  155. #endif
  156. "uniform mat4 p3d_ModelViewProjectionMatrix;\n"
  157. "uniform vec4 p3d_ColorScale;\n"
  158. "void main(void) {\n"
  159. " gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;\n"
  160. " texcoord = p3d_MultiTexCoord0;\n"
  161. " color = p3d_Color;\n"
  162. "}\n";
  163. static const string default_fshader =
  164. #ifndef OPENGLES
  165. "#version 130\n"
  166. "in vec2 texcoord;\n"
  167. "in vec4 color;\n"
  168. "out vec4 p3d_FragColor;\n"
  169. "uniform sampler2D p3d_Texture0;\n"
  170. "uniform vec4 p3d_TexAlphaOnly;\n"
  171. #else
  172. "precision mediump float;\n"
  173. "varying vec2 texcoord;\n"
  174. "varying lowp vec4 color;\n"
  175. "uniform lowp sampler2D p3d_Texture0;\n"
  176. "uniform lowp vec4 p3d_TexAlphaOnly;\n"
  177. #endif
  178. "void main(void) {\n"
  179. #ifndef OPENGLES
  180. " p3d_FragColor = texture(p3d_Texture0, texcoord);\n"
  181. " p3d_FragColor += p3d_TexAlphaOnly;\n" // Hack for text rendering
  182. " p3d_FragColor *= color;\n"
  183. #else
  184. " gl_FragColor = texture2D(p3d_Texture0, texcoord);\n"
  185. " gl_FragColor += p3d_TexAlphaOnly;\n" // Hack for text rendering
  186. " gl_FragColor *= color;\n"
  187. #endif
  188. "}\n";
  189. #endif
  190. /**
  191. * Recopies the given array of pixels, converting from BGR to RGB arrangement.
  192. */
  193. static void
  194. uchar_bgr_to_rgb(unsigned char *dest, const unsigned char *source,
  195. int num_pixels) {
  196. for (int i = 0; i < num_pixels; i++) {
  197. dest[0] = source[2];
  198. dest[1] = source[1];
  199. dest[2] = source[0];
  200. dest += 3;
  201. source += 3;
  202. }
  203. }
  204. /**
  205. * Recopies the given array of pixels, converting from BGRA to RGBA
  206. * arrangement.
  207. */
  208. static void
  209. uchar_bgra_to_rgba(unsigned char *dest, const unsigned char *source,
  210. int num_pixels) {
  211. for (int i = 0; i < num_pixels; i++) {
  212. dest[0] = source[2];
  213. dest[1] = source[1];
  214. dest[2] = source[0];
  215. dest[3] = source[3];
  216. dest += 4;
  217. source += 4;
  218. }
  219. }
  220. /**
  221. * Recopies the given array of pixels, converting from BGR to RGB arrangement.
  222. */
  223. static void
  224. ushort_bgr_to_rgb(unsigned short *dest, const unsigned short *source,
  225. int num_pixels) {
  226. for (int i = 0; i < num_pixels; i++) {
  227. dest[0] = source[2];
  228. dest[1] = source[1];
  229. dest[2] = source[0];
  230. dest += 3;
  231. source += 3;
  232. }
  233. }
  234. /**
  235. * Recopies the given array of pixels, converting from BGRA to RGBA
  236. * arrangement.
  237. */
  238. static void
  239. ushort_bgra_to_rgba(unsigned short *dest, const unsigned short *source,
  240. int num_pixels) {
  241. for (int i = 0; i < num_pixels; i++) {
  242. dest[0] = source[2];
  243. dest[1] = source[1];
  244. dest[2] = source[0];
  245. dest[3] = source[3];
  246. dest += 4;
  247. source += 4;
  248. }
  249. }
  250. /**
  251. * Reverses the order of the components within the image, to convert (for
  252. * instance) GL_BGR to GL_RGB. Returns the byte pointer representing the
  253. * converted image, or the original image if it is unchanged.
  254. *
  255. * new_image must be supplied; it is the PTA_uchar that will be used to hold
  256. * the converted image if required. It will be modified only if the
  257. * conversion is necessary, in which case the data will be stored there, and
  258. * this pointer will be returned. If the conversion is not necessary, this
  259. * pointer will be left unchanged.
  260. */
  261. static const unsigned char *
  262. fix_component_ordering(PTA_uchar &new_image,
  263. const unsigned char *orig_image, size_t orig_image_size,
  264. GLenum external_format, Texture *tex) {
  265. const unsigned char *result = orig_image;
  266. switch (external_format) {
  267. case GL_RGB:
  268. switch (tex->get_component_type()) {
  269. case Texture::T_unsigned_byte:
  270. case Texture::T_byte:
  271. new_image = PTA_uchar::empty_array(orig_image_size);
  272. uchar_bgr_to_rgb(new_image, orig_image, orig_image_size / 3);
  273. result = new_image;
  274. break;
  275. case Texture::T_unsigned_short:
  276. case Texture::T_short:
  277. new_image = PTA_uchar::empty_array(orig_image_size);
  278. ushort_bgr_to_rgb((unsigned short *)new_image.p(),
  279. (const unsigned short *)orig_image,
  280. orig_image_size / 6);
  281. result = new_image;
  282. break;
  283. default:
  284. break;
  285. }
  286. break;
  287. case GL_RGBA:
  288. switch (tex->get_component_type()) {
  289. case Texture::T_unsigned_byte:
  290. case Texture::T_byte:
  291. new_image = PTA_uchar::empty_array(orig_image_size);
  292. uchar_bgra_to_rgba(new_image, orig_image, orig_image_size / 4);
  293. result = new_image;
  294. break;
  295. case Texture::T_unsigned_short:
  296. case Texture::T_short:
  297. new_image = PTA_uchar::empty_array(orig_image_size);
  298. ushort_bgra_to_rgba((unsigned short *)new_image.p(),
  299. (const unsigned short *)orig_image,
  300. orig_image_size / 8);
  301. result = new_image;
  302. break;
  303. default:
  304. break;
  305. }
  306. break;
  307. default:
  308. break;
  309. }
  310. return result;
  311. }
  312. // #--- Zhao Nov2011
  313. string CLP(GraphicsStateGuardian)::get_driver_vendor() { return _gl_vendor; }
  314. string CLP(GraphicsStateGuardian)::get_driver_renderer() { return _gl_renderer; }
  315. string CLP(GraphicsStateGuardian)::get_driver_version() { return _gl_version; }
  316. int CLP(GraphicsStateGuardian)::get_driver_version_major() { return _gl_version_major; }
  317. int CLP(GraphicsStateGuardian)::get_driver_version_minor() { return _gl_version_minor; }
  318. int CLP(GraphicsStateGuardian)::get_driver_shader_version_major() { return _gl_shadlang_ver_major; }
  319. int CLP(GraphicsStateGuardian)::get_driver_shader_version_minor() { return _gl_shadlang_ver_minor; }
  320. /**
  321. *
  322. */
  323. CLP(GraphicsStateGuardian)::
  324. CLP(GraphicsStateGuardian)(GraphicsEngine *engine, GraphicsPipe *pipe) :
  325. GraphicsStateGuardian(gl_coordinate_system, engine, pipe),
  326. _renderbuffer_residency(get_prepared_objects()->get_name(), "renderbuffer")
  327. {
  328. _error_count = 0;
  329. _last_error_check = -1.0;
  330. // calling glGetError() forces a sync, this turns it on if you want to.
  331. _check_errors = gl_check_errors;
  332. _force_flush = gl_force_flush;
  333. _gl_shadlang_ver_major = 0;
  334. _gl_shadlang_ver_minor = 0;
  335. // Hack. Turn on the flag that we turned off at a higher level, since we
  336. // know this works properly in OpenGL, and we want the performance benefit
  337. // it gives us.
  338. _prepared_objects->_support_released_buffer_cache = true;
  339. // Assume that we will get a hardware-accelerated context, unless the window
  340. // tells us otherwise.
  341. _is_hardware = true;
  342. _scissor_enabled = false;
  343. _scissor_attrib_active = false;
  344. _white_texture = 0;
  345. #ifndef OPENGLES
  346. _shader_point_size = false;
  347. #endif
  348. #ifdef HAVE_CG
  349. _cg_context = 0;
  350. #endif
  351. #ifdef DO_PSTATS
  352. if (gl_finish) {
  353. GLCAT.warning()
  354. << "The config variable gl-finish is set to true. This may have a substantial negative impact on your render performance.\n";
  355. }
  356. #endif // DO_PSTATS
  357. }
  358. /**
  359. *
  360. */
  361. CLP(GraphicsStateGuardian)::
  362. ~CLP(GraphicsStateGuardian)() {
  363. if (GLCAT.is_debug()) {
  364. GLCAT.debug()
  365. << "GLGraphicsStateGuardian " << this << " destructing\n";
  366. }
  367. close_gsg();
  368. }
  369. /**
  370. * This is called by the GL if an error occurs, if gl_debug has been enabled
  371. * (and the driver supports the GL_ARB_debug_output extension).
  372. */
  373. void CLP(GraphicsStateGuardian)::
  374. debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *userParam) {
  375. // Determine how to map the severity level.
  376. NotifySeverity level;
  377. switch (severity) {
  378. case GL_DEBUG_SEVERITY_HIGH:
  379. level = NS_error;
  380. break;
  381. case GL_DEBUG_SEVERITY_MEDIUM:
  382. if (type == GL_DEBUG_TYPE_PERFORMANCE) {
  383. // Performance warnings should really be "info".
  384. level = NS_info;
  385. } else {
  386. level = NS_warning;
  387. }
  388. break;
  389. case GL_DEBUG_SEVERITY_LOW:
  390. level = NS_info;
  391. break;
  392. case GL_DEBUG_SEVERITY_NOTIFICATION:
  393. level = NS_debug;
  394. break;
  395. default:
  396. level = NS_fatal; //???
  397. break;
  398. }
  399. string msg_str(message, length);
  400. GLCAT.out(level) << msg_str << "\n";
  401. #ifndef NDEBUG
  402. if (level >= gl_debug_abort_level.get_value()) {
  403. abort();
  404. }
  405. #endif
  406. }
  407. /**
  408. * Resets all internal state as if the gsg were newly created.
  409. */
  410. void CLP(GraphicsStateGuardian)::
  411. reset() {
  412. _last_error_check = -1.0;
  413. _white_texture = 0;
  414. free_pointers();
  415. GraphicsStateGuardian::reset();
  416. // Build _inv_state_mask as a mask of 1's where we don't care, and 0's where
  417. // we do care, about the state. _inv_state_mask =
  418. // RenderState::SlotMask::all_on();
  419. _inv_state_mask.clear_bit(ShaderAttrib::get_class_slot());
  420. _inv_state_mask.clear_bit(AlphaTestAttrib::get_class_slot());
  421. _inv_state_mask.clear_bit(AntialiasAttrib::get_class_slot());
  422. _inv_state_mask.clear_bit(ClipPlaneAttrib::get_class_slot());
  423. _inv_state_mask.clear_bit(ColorAttrib::get_class_slot());
  424. _inv_state_mask.clear_bit(ColorScaleAttrib::get_class_slot());
  425. _inv_state_mask.clear_bit(CullFaceAttrib::get_class_slot());
  426. _inv_state_mask.clear_bit(DepthOffsetAttrib::get_class_slot());
  427. _inv_state_mask.clear_bit(DepthTestAttrib::get_class_slot());
  428. _inv_state_mask.clear_bit(DepthWriteAttrib::get_class_slot());
  429. _inv_state_mask.clear_bit(RenderModeAttrib::get_class_slot());
  430. _inv_state_mask.clear_bit(RescaleNormalAttrib::get_class_slot());
  431. _inv_state_mask.clear_bit(ShadeModelAttrib::get_class_slot());
  432. _inv_state_mask.clear_bit(TransparencyAttrib::get_class_slot());
  433. _inv_state_mask.clear_bit(ColorWriteAttrib::get_class_slot());
  434. _inv_state_mask.clear_bit(ColorBlendAttrib::get_class_slot());
  435. _inv_state_mask.clear_bit(LogicOpAttrib::get_class_slot());
  436. _inv_state_mask.clear_bit(TextureAttrib::get_class_slot());
  437. _inv_state_mask.clear_bit(TexGenAttrib::get_class_slot());
  438. _inv_state_mask.clear_bit(TexMatrixAttrib::get_class_slot());
  439. _inv_state_mask.clear_bit(MaterialAttrib::get_class_slot());
  440. _inv_state_mask.clear_bit(LightAttrib::get_class_slot());
  441. _inv_state_mask.clear_bit(StencilAttrib::get_class_slot());
  442. _inv_state_mask.clear_bit(FogAttrib::get_class_slot());
  443. _inv_state_mask.clear_bit(ScissorAttrib::get_class_slot());
  444. // Output the vendor and version strings.
  445. query_gl_version();
  446. if (_gl_version_major == 0) {
  447. // Couldn't get GL. Fail.
  448. mark_new();
  449. return;
  450. }
  451. // Save the extensions tokens.
  452. _extensions.clear();
  453. // In OpenGL (ES) 3.0 and later, glGetString(GL_EXTENSIONS) is deprecated.
  454. #ifndef OPENGLES_1
  455. if (_gl_version_major >= 3) {
  456. PFNGLGETSTRINGIPROC _glGetStringi =
  457. (PFNGLGETSTRINGIPROC)get_extension_func("glGetStringi");
  458. if (_glGetStringi != NULL) {
  459. GLint n = 0;
  460. glGetIntegerv(GL_NUM_EXTENSIONS, &n);
  461. for (GLint i = 0; i < n; ++i) {
  462. const char *extension = (const char *)_glGetStringi(GL_EXTENSIONS, i);
  463. _extensions.insert(string(extension));
  464. }
  465. } else {
  466. GLCAT.error() << "glGetStringi is not available!\n";
  467. save_extensions((const char *)glGetString(GL_EXTENSIONS));
  468. }
  469. } else
  470. #endif
  471. {
  472. save_extensions((const char *)glGetString(GL_EXTENSIONS));
  473. }
  474. get_extra_extensions();
  475. // This needs access to the extensions, so put this after save_extensions.
  476. query_glsl_version();
  477. #ifndef OPENGLES
  478. bool core_profile = is_at_least_gl_version(3, 2) &&
  479. !has_extension("GL_ARB_compatibility");
  480. if (GLCAT.is_debug()) {
  481. if (core_profile) {
  482. GLCAT.debug() << "Using core profile\n";
  483. } else {
  484. GLCAT.debug() << "Using compatibility profile\n";
  485. }
  486. }
  487. #elif defined(OPENGLES_1)
  488. static const bool core_profile = false;
  489. #else
  490. static const bool core_profile = true;
  491. #endif
  492. // Print out a list of all extensions.
  493. report_extensions();
  494. // Initialize OpenGL debugging output first, if enabled and supported.
  495. _supports_debug = false;
  496. _use_object_labels = false;
  497. if (gl_debug) {
  498. PFNGLDEBUGMESSAGECALLBACKPROC_P _glDebugMessageCallback;
  499. PFNGLDEBUGMESSAGECONTROLPROC _glDebugMessageControl;
  500. if (is_at_least_gl_version(4, 3) || has_extension("GL_KHR_debug")) {
  501. #ifdef OPENGLES
  502. _glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC_P)
  503. get_extension_func("glDebugMessageCallbackKHR");
  504. _glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)
  505. get_extension_func("glDebugMessageControlKHR");
  506. _glObjectLabel = (PFNGLOBJECTLABELPROC)
  507. get_extension_func("glObjectLabelKHR");
  508. #else
  509. _glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC_P)
  510. get_extension_func("glDebugMessageCallback");
  511. _glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)
  512. get_extension_func("glDebugMessageControl");
  513. _glObjectLabel = (PFNGLOBJECTLABELPROC)
  514. get_extension_func("glObjectLabel");
  515. #endif
  516. glEnable(GL_DEBUG_OUTPUT); // Not supported in ARB version
  517. _supports_debug = true;
  518. _use_object_labels = gl_debug_object_labels;
  519. #ifndef OPENGLES
  520. } else if (has_extension("GL_ARB_debug_output")) {
  521. _glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC_P)
  522. get_extension_func("glDebugMessageCallbackARB");
  523. _glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)
  524. get_extension_func("glDebugMessageControlARB");
  525. _supports_debug = true;
  526. #endif
  527. }
  528. if (_supports_debug) {
  529. // Set the categories we want to listen to.
  530. _glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH,
  531. 0, NULL, GLCAT.is_error());
  532. _glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM,
  533. 0, NULL, GLCAT.is_warning());
  534. _glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW,
  535. 0, NULL, GLCAT.is_info());
  536. _glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION,
  537. 0, NULL, GLCAT.is_debug());
  538. // Enable the callback.
  539. _glDebugMessageCallback((GLDEBUGPROC_P) &debug_callback, (void*)this);
  540. if (gl_debug_synchronous) {
  541. glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
  542. }
  543. GLCAT.info() << "gl-debug enabled.\n";
  544. } else {
  545. GLCAT.warning() << "gl-debug enabled, but NOT supported.\n";
  546. }
  547. } else {
  548. // However, still check if it is supported.
  549. _supports_debug = is_at_least_gl_version(4, 3)
  550. || has_extension("GL_KHR_debug")
  551. || has_extension("GL_ARB_debug_output");
  552. if (_supports_debug) {
  553. GLCAT.debug() << "gl-debug supported, but NOT enabled.\n";
  554. } else {
  555. GLCAT.debug() << "gl-debug disabled and unsupported.\n";
  556. }
  557. }
  558. _supported_geom_rendering =
  559. Geom::GR_indexed_point |
  560. Geom::GR_point | Geom::GR_point_uniform_size |
  561. Geom::GR_indexed_other |
  562. Geom::GR_triangle_strip | Geom::GR_triangle_fan |
  563. Geom::GR_line_strip |
  564. Geom::GR_flat_last_vertex;
  565. _supports_point_parameters = false;
  566. #ifdef OPENGLES_1
  567. _glPointParameterfv = glPointParameterfv;
  568. #elif defined(OPENGLES)
  569. // Other OpenGL ES versions don't support point parameters.
  570. #else
  571. if (is_at_least_gl_version(1, 4)) {
  572. _supports_point_parameters = true;
  573. _glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)
  574. get_extension_func("glPointParameterfv");
  575. } else if (has_extension("GL_ARB_point_parameters")) {
  576. _supports_point_parameters = true;
  577. _glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)
  578. get_extension_func("glPointParameterfvARB");
  579. }
  580. if (_supports_point_parameters) {
  581. if (_glPointParameterfv == NULL) {
  582. GLCAT.warning()
  583. << "glPointParameterfv advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  584. _supports_point_parameters = false;
  585. }
  586. }
  587. if (_supports_point_parameters) {
  588. _supported_geom_rendering |= Geom::GR_point_perspective | Geom::GR_point_scale;
  589. } else {
  590. _glPointParameterfv = null_glPointParameterfv;
  591. }
  592. #endif // !OPENGLES_2
  593. #if defined(OPENGLES_2)
  594. // OpenGL ES 2 doesn't have point sprites.
  595. _supports_point_sprite = false;
  596. #elif defined(OPENGLES_1)
  597. _supports_point_sprite = has_extension("GL_OES_point_sprite");
  598. #else
  599. _supports_point_sprite = is_at_least_gl_version(2, 0) ||
  600. has_extension("GL_ARB_point_sprite");
  601. #endif
  602. if (_supports_point_sprite) {
  603. // It appears that the point_sprite extension doesn't support texture
  604. // transforms on the generated texture coordinates. How inconsistent.
  605. // Because of this, we don't advertise GR_point_sprite_tex_matrix.
  606. _supported_geom_rendering |= Geom::GR_point_sprite;
  607. }
  608. #ifdef OPENGLES_1
  609. // OpenGL ES 1.0 does not support primitive restart indices.
  610. #elif defined(OPENGLES)
  611. if (gl_support_primitive_restart_index && is_at_least_gles_version(3, 0)) {
  612. glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
  613. _supported_geom_rendering |= Geom::GR_strip_cut_index;
  614. }
  615. #else
  616. _explicit_primitive_restart = false;
  617. _glPrimitiveRestartIndex = NULL;
  618. if (gl_support_primitive_restart_index) {
  619. if ((is_at_least_gl_version(4, 3) || has_extension("GL_ARB_ES3_compatibility")) &&
  620. _gl_renderer.substr(0, 7) != "Gallium") {
  621. // As long as we enable this, OpenGL will always use the highest
  622. // possible index for a numeric type as strip cut index, which coincides
  623. // with our convention. This saves us a call to glPrimitiveRestartIndex
  624. // ... of course, though, the Gallium driver bugs out here. See also:
  625. // https://www.panda3d.org/forums/viewtopic.php?f=5&t=17512
  626. glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
  627. _supported_geom_rendering |= Geom::GR_strip_cut_index;
  628. } else if (is_at_least_gl_version(3, 1)) {
  629. // We have to use an explicit primitive restart enableindex.
  630. _explicit_primitive_restart = true;
  631. _supported_geom_rendering |= Geom::GR_strip_cut_index;
  632. _glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC)
  633. get_extension_func("glPrimitiveRestartIndex");
  634. }
  635. }
  636. #endif
  637. #if !defined(OPENGLES) && defined(SUPPORT_FIXED_FUNCTION)
  638. if (is_at_least_gl_version(1, 4)) {
  639. _glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC)
  640. get_extension_func("glSecondaryColorPointer");
  641. } else if (has_extension("GL_EXT_secondary_color")) {
  642. _glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC)
  643. get_extension_func("glSecondaryColorPointerEXT");
  644. }
  645. #endif
  646. #ifndef OPENGLES_1
  647. _glDrawRangeElements = null_glDrawRangeElements;
  648. #ifdef OPENGLES
  649. if (is_at_least_gles_version(3, 0)) {
  650. _glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)
  651. get_extension_func("glDrawRangeElements");
  652. }
  653. #else
  654. if (is_at_least_gl_version(1, 2)) {
  655. _glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)
  656. get_extension_func("glDrawRangeElements");
  657. } else if (has_extension("GL_EXT_draw_range_elements")) {
  658. _glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)
  659. get_extension_func("glDrawRangeElementsEXT");
  660. }
  661. #endif
  662. if (_glDrawRangeElements == NULL) {
  663. GLCAT.warning()
  664. << "glDrawRangeElements advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  665. _glDrawRangeElements = null_glDrawRangeElements;
  666. }
  667. #endif // !OPENGLES_1
  668. _supports_3d_texture = false;
  669. #ifndef OPENGLES_1
  670. if (is_at_least_gl_version(1, 2) || is_at_least_gles_version(3, 0)) {
  671. _supports_3d_texture = true;
  672. _glTexImage3D = (PFNGLTEXIMAGE3DPROC_P)
  673. get_extension_func("glTexImage3D");
  674. _glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)
  675. get_extension_func("glTexSubImage3D");
  676. _glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)
  677. get_extension_func("glCopyTexSubImage3D");
  678. #ifndef OPENGLES
  679. } else if (has_extension("GL_EXT_texture3D")) {
  680. _supports_3d_texture = true;
  681. _glTexImage3D = (PFNGLTEXIMAGE3DPROC_P)
  682. get_extension_func("glTexImage3DEXT");
  683. _glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)
  684. get_extension_func("glTexSubImage3DEXT");
  685. _glCopyTexSubImage3D = NULL;
  686. if (has_extension("GL_EXT_copy_texture")) {
  687. _glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)
  688. get_extension_func("glCopyTexSubImage3DEXT");
  689. }
  690. #else
  691. } else if (has_extension("GL_OES_texture_3D")) {
  692. _supports_3d_texture = true;
  693. _glTexImage3D = (PFNGLTEXIMAGE3DPROC_P)
  694. get_extension_func("glTexImage3DOES");
  695. _glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)
  696. get_extension_func("glTexSubImage3DOES");
  697. _glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)
  698. get_extension_func("glCopyTexSubImage3DOES");
  699. _glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DOES)
  700. get_extension_func("glFramebufferTexture3DOES");
  701. #endif
  702. }
  703. if (_supports_3d_texture) {
  704. if (_glTexImage3D == NULL || _glTexSubImage3D == NULL) {
  705. GLCAT.warning()
  706. << "3-D textures advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  707. _supports_3d_texture = false;
  708. }
  709. }
  710. #endif // !OPENGLES_1
  711. _supports_tex_storage = false;
  712. #ifdef OPENGLES
  713. if (is_at_least_gles_version(3, 0)) {
  714. #else
  715. if (is_at_least_gl_version(4, 2) || has_extension("GL_ARB_texture_storage")) {
  716. #endif
  717. _supports_tex_storage = true;
  718. _glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)
  719. get_extension_func("glTexStorage1D");
  720. _glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)
  721. get_extension_func("glTexStorage2D");
  722. _glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)
  723. get_extension_func("glTexStorage3D");
  724. }
  725. #ifdef OPENGLES
  726. else if (has_extension("GL_EXT_texture_storage")) {
  727. _supports_tex_storage = true;
  728. _glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)
  729. get_extension_func("glTexStorage1DEXT");
  730. _glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)
  731. get_extension_func("glTexStorage2DEXT");
  732. _glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)
  733. get_extension_func("glTexStorage3DEXT");
  734. }
  735. #endif
  736. if (_supports_tex_storage) {
  737. if (_glTexStorage1D == NULL || _glTexStorage2D == NULL || _glTexStorage3D == NULL) {
  738. GLCAT.warning()
  739. << "Immutable texture storage advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  740. _supports_tex_storage = false;
  741. }
  742. }
  743. _supports_clear_texture = false;
  744. #ifndef OPENGLES
  745. if (is_at_least_gl_version(4, 4) || has_extension("GL_ARB_clear_texture")) {
  746. _glClearTexImage = (PFNGLCLEARTEXIMAGEPROC)
  747. get_extension_func("glClearTexImage");
  748. if (_glClearTexImage == NULL) {
  749. GLCAT.warning()
  750. << "GL_ARB_clear_texture advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  751. } else {
  752. _supports_clear_texture = true;
  753. }
  754. }
  755. #endif
  756. _supports_clear_buffer = false;
  757. #ifndef OPENGLES
  758. if (is_at_least_gl_version(4, 3) || has_extension("GL_ARB_clear_buffer_object")) {
  759. _glClearBufferData = (PFNGLCLEARBUFFERDATAPROC)
  760. get_extension_func("glClearBufferData");
  761. if (_glClearBufferData == NULL) {
  762. GLCAT.warning()
  763. << "GL_ARB_clear_buffer_object advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  764. } else {
  765. _supports_clear_buffer = true;
  766. }
  767. }
  768. #endif
  769. _supports_2d_texture_array = false;
  770. #ifndef OPENGLES_1
  771. if (_gl_version_major >= 3) {
  772. _supports_2d_texture_array = true;
  773. _glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)
  774. get_extension_func("glFramebufferTextureLayer");
  775. #ifndef OPENGLES
  776. } else if (has_extension("GL_EXT_texture_array")) {
  777. _supports_2d_texture_array = true;
  778. _glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)
  779. get_extension_func("glFramebufferTextureLayerEXT");
  780. #endif
  781. }
  782. if (_supports_2d_texture_array && _glFramebufferTextureLayer == NULL) {
  783. GLCAT.warning()
  784. << "Texture arrays advertised as supported by OpenGL runtime, but could not get pointer to glFramebufferTextureLayer function.\n";
  785. }
  786. #endif // !OPENGLES_1
  787. #ifdef OPENGLES_2
  788. _supports_cube_map = true;
  789. #else
  790. _supports_cube_map =
  791. is_at_least_gl_version(1, 3) ||
  792. has_extension("GL_ARB_texture_cube_map") ||
  793. has_extension("GL_OES_texture_cube_map");
  794. #endif
  795. #ifndef OPENGLES
  796. if (_supports_cube_map && gl_cube_map_seamless) {
  797. if (is_at_least_gl_version(3, 2) || has_extension("GL_ARB_seamless_cube_map")) {
  798. glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
  799. }
  800. }
  801. #endif
  802. #ifndef OPENGLES
  803. _supports_cube_map_array = is_at_least_gl_version(4, 0) ||
  804. has_extension("GL_ARB_texture_cube_map_array");
  805. #endif
  806. #ifndef OPENGLES
  807. if (is_at_least_gl_version(3, 0)) {
  808. _glTexBuffer = (PFNGLTEXBUFFERPROC)get_extension_func("glTexBuffer");
  809. _supports_buffer_texture = true;
  810. } else if (has_extension("GL_ARB_texture_buffer_object")) {
  811. _glTexBuffer = (PFNGLTEXBUFFERPROC)get_extension_func("glTexBufferARB");
  812. _supports_buffer_texture = true;
  813. }
  814. #endif
  815. #ifdef OPENGLES
  816. _supports_texture_srgb =
  817. is_at_least_gles_version(3, 0) || has_extension("GL_EXT_sRGB");
  818. #else
  819. _supports_texture_srgb =
  820. is_at_least_gl_version(2, 1) || has_extension("GL_EXT_texture_sRGB");
  821. #endif
  822. #ifdef OPENGLES
  823. _supports_compressed_texture = true;
  824. // Supported in the core. 1D textures are not supported by OpenGL ES.
  825. _glCompressedTexImage1D = NULL;
  826. _glCompressedTexImage2D = glCompressedTexImage2D;
  827. _glCompressedTexSubImage1D = NULL;
  828. _glCompressedTexSubImage2D = glCompressedTexSubImage2D;
  829. _glGetCompressedTexImage = NULL;
  830. _glCompressedTexImage3D = NULL;
  831. _glCompressedTexSubImage3D = NULL;
  832. #ifdef OPENGLES_2
  833. if (_supports_3d_texture) {
  834. _glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)
  835. get_extension_func("glCompressedTexImage3DOES");
  836. _glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)
  837. get_extension_func("glCompressedTexSubImageOES");
  838. }
  839. #endif
  840. #else
  841. if (is_at_least_gl_version(1, 3)) {
  842. _supports_compressed_texture = true;
  843. _glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)
  844. get_extension_func("glCompressedTexImage1D");
  845. _glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)
  846. get_extension_func("glCompressedTexImage2D");
  847. _glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)
  848. get_extension_func("glCompressedTexImage3D");
  849. _glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)
  850. get_extension_func("glCompressedTexSubImage1D");
  851. _glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)
  852. get_extension_func("glCompressedTexSubImage2D");
  853. _glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)
  854. get_extension_func("glCompressedTexSubImage3D");
  855. _glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)
  856. get_extension_func("glGetCompressedTexImage");
  857. } else if (has_extension("GL_ARB_texture_compression")) {
  858. _supports_compressed_texture = true;
  859. _glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)
  860. get_extension_func("glCompressedTexImage1DARB");
  861. _glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)
  862. get_extension_func("glCompressedTexImage2DARB");
  863. _glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)
  864. get_extension_func("glCompressedTexImage3DARB");
  865. _glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)
  866. get_extension_func("glCompressedTexSubImage1DARB");
  867. _glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)
  868. get_extension_func("glCompressedTexSubImage2DARB");
  869. _glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)
  870. get_extension_func("glCompressedTexSubImage3DARB");
  871. _glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)
  872. get_extension_func("glGetCompressedTexImageARB");
  873. } else {
  874. _supports_compressed_texture = false;
  875. }
  876. if (_supports_compressed_texture) {
  877. if (_glCompressedTexImage1D == NULL ||
  878. _glCompressedTexImage2D == NULL ||
  879. _glCompressedTexImage3D == NULL ||
  880. _glCompressedTexSubImage1D == NULL ||
  881. _glCompressedTexSubImage2D == NULL ||
  882. _glCompressedTexSubImage3D == NULL ||
  883. _glGetCompressedTexImage == NULL) {
  884. GLCAT.warning()
  885. << "Compressed textures advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  886. _supports_compressed_texture = false;
  887. }
  888. }
  889. #endif
  890. if (_supports_compressed_texture) {
  891. #ifndef OPENGLES
  892. _compressed_texture_formats.set_bit(Texture::CM_on);
  893. #endif
  894. GLint num_compressed_formats = 0;
  895. glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_compressed_formats);
  896. GLint *formats = (GLint *)alloca(num_compressed_formats * sizeof(GLint));
  897. glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats);
  898. for (int i = 0; i < num_compressed_formats; ++i) {
  899. switch (formats[i]) {
  900. case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  901. case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  902. _compressed_texture_formats.set_bit(Texture::CM_dxt1);
  903. break;
  904. #ifdef OPENGLES
  905. case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
  906. case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
  907. _compressed_texture_formats.set_bit(Texture::CM_pvr1_2bpp);
  908. break;
  909. case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
  910. case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
  911. _compressed_texture_formats.set_bit(Texture::CM_pvr1_4bpp);
  912. break;
  913. #else
  914. case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
  915. _compressed_texture_formats.set_bit(Texture::CM_dxt3);
  916. break;
  917. case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
  918. _compressed_texture_formats.set_bit(Texture::CM_dxt5);
  919. break;
  920. case GL_COMPRESSED_RGB_FXT1_3DFX:
  921. case GL_COMPRESSED_RGBA_FXT1_3DFX:
  922. _compressed_texture_formats.set_bit(Texture::CM_fxt1);
  923. break;
  924. #endif
  925. default:
  926. break;
  927. }
  928. }
  929. #ifndef OPENGLES
  930. // The OpenGL spec states that these are not reported by the above
  931. // mechanism, so we have to check for the extension ourselves.
  932. if (is_at_least_gl_version(3, 0) ||
  933. has_extension("GL_ARB_texture_compression_rgtc") ||
  934. has_extension("GL_EXT_texture_compression_rgtc")) {
  935. _compressed_texture_formats.set_bit(Texture::CM_rgtc);
  936. }
  937. #endif
  938. }
  939. #ifdef OPENGLES
  940. // Note that these extensions only offer support for GL_BGRA, not GL_BGR.
  941. _supports_bgr = has_extension("GL_EXT_texture_format_BGRA8888") ||
  942. has_extension("GL_APPLE_texture_format_BGRA8888");
  943. #else
  944. // In regular OpenGL, we have both GL_BGRA and GL_BGR.
  945. _supports_bgr =
  946. is_at_least_gl_version(1, 2) || has_extension("GL_EXT_bgra");
  947. #endif
  948. #ifdef SUPPORT_FIXED_FUNCTION
  949. #ifdef OPENGLES_1
  950. _supports_rescale_normal = true;
  951. #else
  952. _supports_rescale_normal =
  953. !core_profile && gl_support_rescale_normal &&
  954. (is_at_least_gl_version(1, 2) || has_extension("GL_EXT_rescale_normal"));
  955. #endif
  956. #ifndef OPENGLES
  957. _use_separate_specular_color = gl_separate_specular_color &&
  958. (is_at_least_gl_version(1, 2) || has_extension("GL_EXT_separate_specular_color"));
  959. #endif
  960. #endif // SUPPORT_FIXED_FUNCTION
  961. #ifdef OPENGLES
  962. _supports_packed_dabc = false;
  963. _supports_packed_ufloat = false;
  964. #else
  965. _supports_packed_dabc = is_at_least_gl_version(3, 2) ||
  966. has_extension("GL_ARB_vertex_array_bgra") ||
  967. has_extension("GL_EXT_vertex_array_bgra");
  968. _supports_packed_ufloat = is_at_least_gl_version(4, 4) ||
  969. has_extension("GL_ARB_vertex_type_10f_11f_11f_rev");
  970. #endif
  971. #ifdef OPENGLES
  972. //TODO
  973. _supports_multisample = false;
  974. #else
  975. _supports_multisample =
  976. has_extension("GL_ARB_multisample") || is_at_least_gl_version(1, 3);
  977. #endif
  978. #ifdef OPENGLES_1
  979. _supports_generate_mipmap = is_at_least_gles_version(1, 1);
  980. #elif defined(OPENGLES)
  981. _supports_generate_mipmap = true;
  982. #else
  983. _supports_generate_mipmap = is_at_least_gl_version(1, 4) ||
  984. has_extension("GL_SGIS_generate_mipmap");
  985. #endif
  986. #ifdef OPENGLES_1
  987. _supports_tex_non_pow2 = false;
  988. #elif defined(OPENGLES)
  989. _supports_tex_non_pow2 = is_at_least_gles_version(3, 0) ||
  990. has_extension("GL_OES_texture_npot");
  991. #else
  992. _supports_tex_non_pow2 = is_at_least_gl_version(2, 0) ||
  993. has_extension("GL_ARB_texture_non_power_of_two");
  994. #endif
  995. #ifndef OPENGLES_2
  996. bool supports_multitexture = false;
  997. if (is_at_least_gl_version(1, 3) || is_at_least_gles_version(1, 1)) {
  998. supports_multitexture = true;
  999. _glActiveTexture = (PFNGLACTIVETEXTUREPROC)
  1000. get_extension_func("glActiveTexture");
  1001. #ifdef SUPPORT_FIXED_FUNCTION
  1002. _glClientActiveTexture = (PFNGLACTIVETEXTUREPROC)
  1003. get_extension_func("glClientActiveTexture");
  1004. #endif
  1005. #ifdef SUPPORT_IMMEDIATE_MODE
  1006. _glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)
  1007. get_extension_func("glMultiTexCoord1f");
  1008. _glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)
  1009. get_extension_func("glMultiTexCoord2f");
  1010. _glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)
  1011. get_extension_func("glMultiTexCoord3f");
  1012. _glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)
  1013. get_extension_func("glMultiTexCoord4f");
  1014. _glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)
  1015. get_extension_func("glMultiTexCoord1d");
  1016. _glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)
  1017. get_extension_func("glMultiTexCoord2d");
  1018. _glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)
  1019. get_extension_func("glMultiTexCoord3d");
  1020. _glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)
  1021. get_extension_func("glMultiTexCoord4d");
  1022. #endif
  1023. } else if (has_extension("GL_ARB_multitexture")) {
  1024. supports_multitexture = true;
  1025. _glActiveTexture = (PFNGLACTIVETEXTUREPROC)
  1026. get_extension_func("glActiveTextureARB");
  1027. #ifdef SUPPORT_FIXED_FUNCTION
  1028. _glClientActiveTexture = (PFNGLACTIVETEXTUREPROC)
  1029. get_extension_func("glClientActiveTextureARB");
  1030. #endif
  1031. #ifdef SUPPORT_IMMEDIATE_MODE
  1032. _glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)
  1033. get_extension_func("glMultiTexCoord1fARB");
  1034. _glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)
  1035. get_extension_func("glMultiTexCoord2fARB");
  1036. _glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)
  1037. get_extension_func("glMultiTexCoord3fARB");
  1038. _glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)
  1039. get_extension_func("glMultiTexCoord4fARB");
  1040. _glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)
  1041. get_extension_func("glMultiTexCoord1dARB");
  1042. _glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)
  1043. get_extension_func("glMultiTexCoord2dARB");
  1044. _glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)
  1045. get_extension_func("glMultiTexCoord3dARB");
  1046. _glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)
  1047. get_extension_func("glMultiTexCoord4dARB");
  1048. #endif
  1049. } else {
  1050. supports_multitexture = false;
  1051. }
  1052. if (supports_multitexture) {
  1053. if (_glActiveTexture == NULL
  1054. #ifdef SUPPORT_FIXED_FUNCTION
  1055. || _glClientActiveTexture == NULL
  1056. #endif
  1057. #ifdef SUPPORT_IMMEDIATE_MODE
  1058. || GLf(_glMultiTexCoord1) == NULL || GLf(_glMultiTexCoord2) == NULL
  1059. || GLf(_glMultiTexCoord3) == NULL || GLf(_glMultiTexCoord4) == NULL
  1060. #endif
  1061. ) {
  1062. GLCAT.warning()
  1063. << "Multitexture advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1064. supports_multitexture = false;
  1065. }
  1066. }
  1067. if (!supports_multitexture) {
  1068. // Replace with dummy no-op functions.
  1069. _glActiveTexture = null_glActiveTexture;
  1070. }
  1071. #ifdef SUPPORT_FIXED_FUNCTION
  1072. if (!supports_multitexture || core_profile) {
  1073. _glClientActiveTexture = null_glActiveTexture;
  1074. }
  1075. #endif
  1076. #endif // OPENGLES_2
  1077. #ifdef OPENGLES_1
  1078. _supports_depth_texture = false;
  1079. _supports_depth_stencil = has_extension("GL_OES_packed_depth_stencil");
  1080. _supports_depth24 = has_extension("GL_OES_depth24");
  1081. _supports_depth32 = has_extension("GL_OES_depth32");
  1082. #elif defined(OPENGLES)
  1083. if (is_at_least_gles_version(3, 0)) {
  1084. _supports_depth_texture = true;
  1085. _supports_depth_stencil = true;
  1086. _supports_depth24 = true;
  1087. _supports_depth32 = true;
  1088. } else {
  1089. #ifdef __EMSCRIPTEN__
  1090. if (has_extension("WEBGL_depth_texture") ||
  1091. has_extension("GL_ANGLE_depth_texture")) {
  1092. #else
  1093. if (has_extension("GL_ANGLE_depth_texture")) {
  1094. #endif
  1095. // This extension provides both depth textures and depth-stencil support.
  1096. _supports_depth_texture = true;
  1097. _supports_depth_stencil = true;
  1098. } else if (has_extension("GL_OES_depth_texture")) {
  1099. _supports_depth_texture = true;
  1100. _supports_depth_stencil = has_extension("GL_OES_packed_depth_stencil");
  1101. }
  1102. _supports_depth24 = has_extension("GL_OES_depth24");
  1103. _supports_depth32 = has_extension("GL_OES_depth32");
  1104. }
  1105. #else
  1106. _supports_depth_texture = (is_at_least_gl_version(1, 4) ||
  1107. has_extension("GL_ARB_depth_texture"));
  1108. _supports_depth_stencil = (is_at_least_gl_version(3, 0) ||
  1109. has_extension("GL_ARB_framebuffer_object") ||
  1110. has_extension("GL_EXT_packed_depth_stencil"));
  1111. #endif
  1112. #ifdef OPENGLES_2
  1113. if (gl_support_shadow_filter && _supports_depth_texture &&
  1114. (is_at_least_gles_version(3, 0) || has_extension("GL_EXT_shadow_samplers"))) {
  1115. _supports_shadow_filter = true;
  1116. }
  1117. #else
  1118. if (gl_support_shadow_filter &&
  1119. _supports_depth_texture &&
  1120. (is_at_least_gl_version(1, 4) || has_extension("GL_ARB_shadow")) &&
  1121. has_extension("GL_ARB_fragment_program_shadow")) {
  1122. _supports_shadow_filter = true;
  1123. }
  1124. #endif
  1125. // Actually, we can't keep forever disabling ARB_shadow on ATI cards, since
  1126. // they do work correctly now. Maybe there is some feature level we can
  1127. // check somewhere?
  1128. /*if (_gl_vendor.substr(0,3)=="ATI") {
  1129. // ATI drivers have never provided correct shadow support.
  1130. _supports_shadow_filter = false;
  1131. }*/
  1132. #ifndef SUPPORT_FIXED_FUNCTION
  1133. _supports_texture_combine = false;
  1134. _supports_texture_saved_result = false;
  1135. _supports_texture_dot3 = false;
  1136. #else
  1137. if (!core_profile) {
  1138. _supports_texture_combine =
  1139. is_at_least_gl_version(1, 3) ||
  1140. is_at_least_gles_version(1, 1) ||
  1141. has_extension("GL_ARB_texture_env_combine");
  1142. #ifdef OPENGLES_1
  1143. _supports_texture_saved_result =
  1144. has_extension("GL_OES_texture_env_crossbar");
  1145. #else
  1146. _supports_texture_saved_result =
  1147. is_at_least_gl_version(1, 4) ||
  1148. has_extension("GL_ARB_texture_env_crossbar");
  1149. #endif
  1150. _supports_texture_dot3 =
  1151. is_at_least_gl_version(1, 3) ||
  1152. is_at_least_gles_version(1, 1) ||
  1153. has_extension("GL_ARB_texture_env_dot3");
  1154. }
  1155. #endif // SUPPORT_FIXED_FUNCTION
  1156. #ifdef OPENGLES_2
  1157. _supports_buffers = true;
  1158. _glGenBuffers = glGenBuffers;
  1159. _glBindBuffer = glBindBuffer;
  1160. _glBufferData = glBufferData;
  1161. _glBufferSubData = glBufferSubData;
  1162. _glDeleteBuffers = glDeleteBuffers;
  1163. #else
  1164. _supports_buffers = false;
  1165. if (is_at_least_gl_version(1, 5) || is_at_least_gles_version(1, 1)) {
  1166. _supports_buffers = true;
  1167. _glGenBuffers = (PFNGLGENBUFFERSPROC)
  1168. get_extension_func("glGenBuffers");
  1169. _glBindBuffer = (PFNGLBINDBUFFERPROC)
  1170. get_extension_func("glBindBuffer");
  1171. _glBufferData = (PFNGLBUFFERDATAPROC)
  1172. get_extension_func("glBufferData");
  1173. _glBufferSubData = (PFNGLBUFFERSUBDATAPROC)
  1174. get_extension_func("glBufferSubData");
  1175. _glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)
  1176. get_extension_func("glDeleteBuffers");
  1177. #ifndef OPENGLES
  1178. _glMapBuffer = (PFNGLMAPBUFFERPROC)
  1179. get_extension_func("glMapBuffer");
  1180. _glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)
  1181. get_extension_func("glUnmapBuffer");
  1182. #endif
  1183. }
  1184. #ifndef OPENGLES_1
  1185. else if (has_extension("GL_ARB_vertex_buffer_object")) {
  1186. _supports_buffers = true;
  1187. _glGenBuffers = (PFNGLGENBUFFERSPROC)
  1188. get_extension_func("glGenBuffersARB");
  1189. _glBindBuffer = (PFNGLBINDBUFFERPROC)
  1190. get_extension_func("glBindBufferARB");
  1191. _glBufferData = (PFNGLBUFFERDATAPROC)
  1192. get_extension_func("glBufferDataARB");
  1193. _glBufferSubData = (PFNGLBUFFERSUBDATAPROC)
  1194. get_extension_func("glBufferSubDataARB");
  1195. _glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)
  1196. get_extension_func("glDeleteBuffersARB");
  1197. _glMapBuffer = (PFNGLMAPBUFFERPROC)
  1198. get_extension_func("glMapBufferARB");
  1199. _glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)
  1200. get_extension_func("glUnmapBufferARB");
  1201. }
  1202. #endif // OPENGLES_1
  1203. if (_supports_buffers) {
  1204. if (_glGenBuffers == NULL || _glBindBuffer == NULL ||
  1205. _glBufferData == NULL || _glBufferSubData == NULL ||
  1206. _glDeleteBuffers == NULL) {
  1207. GLCAT.warning()
  1208. << "Buffers advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1209. _supports_buffers = false;
  1210. }
  1211. }
  1212. #endif
  1213. #ifdef OPENGLES
  1214. if (is_at_least_gles_version(3, 0)) {
  1215. _glMapBufferRange = (PFNGLMAPBUFFERRANGEEXTPROC)
  1216. get_extension_func("glMapBufferRange");
  1217. } else if (has_extension("GL_EXT_map_buffer_range")) {
  1218. _glMapBufferRange = (PFNGLMAPBUFFERRANGEEXTPROC)
  1219. get_extension_func("glMapBufferRangeEXT");
  1220. } else {
  1221. _glMapBufferRange = NULL;
  1222. }
  1223. #else
  1224. // Check for various advanced buffer management features.
  1225. if (is_at_least_gl_version(3, 0) || has_extension("GL_ARB_map_buffer_range")) {
  1226. _glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)
  1227. get_extension_func("glMapBufferRange");
  1228. } else {
  1229. _glMapBufferRange = NULL;
  1230. }
  1231. if (is_at_least_gl_version(4, 4) || has_extension("GL_ARB_buffer_storage")) {
  1232. _glBufferStorage = (PFNGLBUFFERSTORAGEPROC)
  1233. get_extension_func("glBufferStorage");
  1234. if (_glBufferStorage != NULL) {
  1235. _supports_buffer_storage = true;
  1236. } else {
  1237. GLCAT.warning()
  1238. << "Buffer storage advertised as supported by OpenGL runtime, but "
  1239. "could not get pointers to extension function.\n";
  1240. }
  1241. } else {
  1242. _supports_buffer_storage = false;
  1243. }
  1244. #endif
  1245. _supports_vao = false;
  1246. #ifdef OPENGLES
  1247. if (is_at_least_gles_version(3, 0)) {
  1248. #else
  1249. if (is_at_least_gl_version(3, 0) || has_extension("GL_ARB_vertex_array_object")) {
  1250. #endif
  1251. _supports_vao = true;
  1252. _glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)
  1253. get_extension_func("glBindVertexArray");
  1254. _glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)
  1255. get_extension_func("glDeleteVertexArrays");
  1256. _glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)
  1257. get_extension_func("glGenVertexArrays");
  1258. #ifdef OPENGLES
  1259. } else if (has_extension("GL_OES_vertex_array_object")) {
  1260. _supports_vao = true;
  1261. _glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)
  1262. get_extension_func("glBindVertexArrayOES");
  1263. _glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)
  1264. get_extension_func("glDeleteVertexArraysOES");
  1265. _glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)
  1266. get_extension_func("glGenVertexArraysOES");
  1267. #endif
  1268. }
  1269. if (_supports_vao) {
  1270. if (_glBindVertexArray == NULL || _glDeleteVertexArrays == NULL ||
  1271. _glGenVertexArrays == NULL) {
  1272. GLCAT.warning()
  1273. << "Vertex array objects advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1274. _supports_vao = false;
  1275. }
  1276. }
  1277. // Check for GLSL support.
  1278. #if defined(OPENGLES_1)
  1279. _supports_glsl = false;
  1280. _supports_geometry_shaders = false;
  1281. _supports_tessellation_shaders = false;
  1282. #elif defined(OPENGLES)
  1283. _supports_glsl = true;
  1284. _supports_geometry_shaders = false;
  1285. _supports_tessellation_shaders = false;
  1286. #else
  1287. _supports_glsl = (_gl_shadlang_ver_major >= 1);
  1288. _supports_tessellation_shaders = is_at_least_gl_version(4, 0) || has_extension("GL_ARB_tessellation_shader");
  1289. if (is_at_least_gl_version(3, 2)) {
  1290. _supports_geometry_shaders = true;
  1291. _glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREARBPROC)
  1292. get_extension_func("glFramebufferTexture");
  1293. } else if (has_extension("GL_ARB_geometry_shader4")) {
  1294. _supports_geometry_shaders = true;
  1295. _glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREARBPROC)
  1296. get_extension_func("glFramebufferTextureARB");
  1297. _glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)
  1298. get_extension_func("glProgramParameteriARB");
  1299. } else if (has_extension("GL_EXT_geometry_shader4")) {
  1300. _supports_geometry_shaders = true;
  1301. _glFramebufferTexture = NULL;
  1302. _glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)
  1303. get_extension_func("glProgramParameteriEXT");
  1304. } else {
  1305. _supports_geometry_shaders = false;
  1306. _glFramebufferTexture = NULL;
  1307. }
  1308. #endif
  1309. _shader_caps._supports_glsl = _supports_glsl;
  1310. // Check for support for other types of shaders that can be used by Cg.
  1311. _supports_basic_shaders = false;
  1312. #if defined(HAVE_CG) && !defined(OPENGLES)
  1313. if (has_extension("GL_ARB_vertex_program") &&
  1314. has_extension("GL_ARB_fragment_program")) {
  1315. _supports_basic_shaders = true;
  1316. _shader_caps._active_vprofile = (int)CG_PROFILE_ARBVP1;
  1317. _shader_caps._active_fprofile = (int)CG_PROFILE_ARBFP1;
  1318. _shader_caps._active_gprofile = (int)CG_PROFILE_UNKNOWN; // No geometry shader if only using basic
  1319. if (basic_shaders_only) {
  1320. // We're happy with ARB programs, thanks.
  1321. } else if (has_extension("GL_NV_gpu_program5")) {
  1322. _shader_caps._active_vprofile = (int)CG_PROFILE_GP5VP;
  1323. _shader_caps._active_fprofile = (int)CG_PROFILE_GP5FP;
  1324. _shader_caps._active_gprofile = (int)CG_PROFILE_GP5GP;
  1325. } else if (has_extension("GL_NV_gpu_program4")) {
  1326. _shader_caps._active_vprofile = (int)CG_PROFILE_GP4VP;
  1327. _shader_caps._active_fprofile = (int)CG_PROFILE_GP4FP;
  1328. _shader_caps._active_gprofile = (int)CG_PROFILE_GP4GP;
  1329. } else if (has_extension("GL_NV_vertex_program3") &&
  1330. has_extension("GL_NV_fragment_program2")) {
  1331. _shader_caps._active_vprofile = (int)CG_PROFILE_VP40;
  1332. _shader_caps._active_fprofile = (int)CG_PROFILE_FP40;
  1333. _shader_caps._active_gprofile = (int)CG_PROFILE_UNKNOWN;
  1334. } else if (has_extension("GL_NV_vertex_program2") &&
  1335. has_extension("GL_NV_fragment_program")) {
  1336. _shader_caps._active_vprofile = (int)CG_PROFILE_VP30;
  1337. _shader_caps._active_fprofile = (int)CG_PROFILE_FP30;
  1338. _shader_caps._active_gprofile = (int)CG_PROFILE_UNKNOWN;
  1339. } else if (has_extension("GL_NV_vertex_program1_1") &&
  1340. has_extension("GL_NV_texture_shader2") &&
  1341. has_extension("GL_NV_register_combiners2")) {
  1342. _shader_caps._active_vprofile = (int)CG_PROFILE_VP20;
  1343. _shader_caps._active_fprofile = (int)CG_PROFILE_FP20;
  1344. _shader_caps._active_gprofile = (int)CG_PROFILE_UNKNOWN;
  1345. } else if (_supports_glsl) {
  1346. // This is what will be available to non-NVIDIA cards. It is the last
  1347. // option since it is slower to compile GLSL than the other options.
  1348. _shader_caps._active_vprofile = (int)CG_PROFILE_GLSLV;
  1349. _shader_caps._active_fprofile = (int)CG_PROFILE_GLSLF;
  1350. if (_supports_geometry_shaders) {
  1351. _shader_caps._active_gprofile = (int)CG_PROFILE_GLSLG;
  1352. }
  1353. }
  1354. _shader_caps._ultimate_vprofile = (int)CG_PROFILE_VP40;
  1355. _shader_caps._ultimate_fprofile = (int)CG_PROFILE_FP40;
  1356. _shader_caps._ultimate_gprofile = (int)CG_PROFILE_GPU_GP;
  1357. // Bug workaround for radeons.
  1358. if (_shader_caps._active_fprofile == CG_PROFILE_ARBFP1) {
  1359. if (has_extension("GL_ATI_draw_buffers")) {
  1360. _shader_caps._bug_list.insert(Shader::SBUG_ati_draw_buffers);
  1361. }
  1362. }
  1363. } else if (_supports_glsl) {
  1364. // No, but we do support GLSL...
  1365. _shader_caps._active_vprofile = (int)CG_PROFILE_GLSLV;
  1366. _shader_caps._active_fprofile = (int)CG_PROFILE_GLSLF;
  1367. if (_supports_geometry_shaders) {
  1368. _shader_caps._active_gprofile = (int)CG_PROFILE_GLSLG;
  1369. } else {
  1370. _shader_caps._active_gprofile = (int)CG_PROFILE_UNKNOWN;
  1371. }
  1372. }
  1373. #endif // HAVE_CG
  1374. _supports_compute_shaders = false;
  1375. #ifndef OPENGLES_1
  1376. #ifdef OPENGLES
  1377. if (is_at_least_gles_version(3, 1)) {
  1378. #else
  1379. if (is_at_least_gl_version(4, 3) || has_extension("GL_ARB_compute_shader")) {
  1380. #endif
  1381. _glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC)
  1382. get_extension_func("glDispatchCompute");
  1383. if (_glDispatchCompute != NULL) {
  1384. _supports_compute_shaders = true;
  1385. }
  1386. }
  1387. #endif // !OPENGLES_1
  1388. #ifndef OPENGLES
  1389. if (_supports_glsl) {
  1390. _glAttachShader = (PFNGLATTACHSHADERPROC)
  1391. get_extension_func("glAttachShader");
  1392. _glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)
  1393. get_extension_func("glBindAttribLocation");
  1394. _glCompileShader = (PFNGLCOMPILESHADERPROC)
  1395. get_extension_func("glCompileShader");
  1396. _glCreateProgram = (PFNGLCREATEPROGRAMPROC)
  1397. get_extension_func("glCreateProgram");
  1398. _glCreateShader = (PFNGLCREATESHADERPROC)
  1399. get_extension_func("glCreateShader");
  1400. _glDeleteProgram = (PFNGLDELETEPROGRAMPROC)
  1401. get_extension_func("glDeleteProgram");
  1402. _glDeleteShader = (PFNGLDELETESHADERPROC)
  1403. get_extension_func("glDeleteShader");
  1404. _glDetachShader = (PFNGLDETACHSHADERPROC)
  1405. get_extension_func("glDetachShader");
  1406. _glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)
  1407. get_extension_func("glDisableVertexAttribArray");
  1408. _glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)
  1409. get_extension_func("glEnableVertexAttribArray");
  1410. _glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)
  1411. get_extension_func("glGetActiveAttrib");
  1412. _glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)
  1413. get_extension_func("glGetActiveUniform");
  1414. _glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)
  1415. get_extension_func("glGetAttribLocation");
  1416. _glGetProgramiv = (PFNGLGETPROGRAMIVPROC)
  1417. get_extension_func("glGetProgramiv");
  1418. _glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)
  1419. get_extension_func("glGetProgramInfoLog");
  1420. _glGetShaderiv = (PFNGLGETSHADERIVPROC)
  1421. get_extension_func("glGetShaderiv");
  1422. _glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)
  1423. get_extension_func("glGetShaderInfoLog");
  1424. _glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)
  1425. get_extension_func("glGetUniformLocation");
  1426. _glLinkProgram = (PFNGLLINKPROGRAMPROC)
  1427. get_extension_func("glLinkProgram");
  1428. _glShaderSource = (PFNGLSHADERSOURCEPROC_P)
  1429. get_extension_func("glShaderSource");
  1430. _glUseProgram = (PFNGLUSEPROGRAMPROC)
  1431. get_extension_func("glUseProgram");
  1432. _glUniform4f = (PFNGLUNIFORM4FPROC)
  1433. get_extension_func("glUniform4f");
  1434. _glUniform1i = (PFNGLUNIFORM1IPROC)
  1435. get_extension_func("glUniform1i");
  1436. _glUniform1fv = (PFNGLUNIFORM1FVPROC)
  1437. get_extension_func("glUniform1fv");
  1438. _glUniform2fv = (PFNGLUNIFORM2FVPROC)
  1439. get_extension_func("glUniform2fv");
  1440. _glUniform3fv = (PFNGLUNIFORM3FVPROC)
  1441. get_extension_func("glUniform3fv");
  1442. _glUniform4fv = (PFNGLUNIFORM4FVPROC)
  1443. get_extension_func("glUniform4fv");
  1444. _glUniform1iv = (PFNGLUNIFORM1IVPROC)
  1445. get_extension_func("glUniform1iv");
  1446. _glUniform2iv = (PFNGLUNIFORM2IVPROC)
  1447. get_extension_func("glUniform2iv");
  1448. _glUniform3iv = (PFNGLUNIFORM3IVPROC)
  1449. get_extension_func("glUniform3iv");
  1450. _glUniform4iv = (PFNGLUNIFORM4IVPROC)
  1451. get_extension_func("glUniform4iv");
  1452. _glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)
  1453. get_extension_func("glUniformMatrix3fv");
  1454. _glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)
  1455. get_extension_func("glUniformMatrix4fv");
  1456. _glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)
  1457. get_extension_func("glValidateProgram");
  1458. _glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)
  1459. get_extension_func("glVertexAttrib4fv");
  1460. _glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)
  1461. get_extension_func("glVertexAttrib4dv");
  1462. _glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)
  1463. get_extension_func("glVertexAttribPointer");
  1464. if (is_at_least_gl_version(3, 0)) {
  1465. _glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)
  1466. get_extension_func("glVertexAttribIPointer");
  1467. } else {
  1468. _glVertexAttribIPointer = NULL;
  1469. }
  1470. if (is_at_least_gl_version(4, 1) ||
  1471. has_extension("GL_ARB_vertex_attrib_64bit")) {
  1472. _glVertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC)
  1473. get_extension_func("glVertexAttribLPointer");
  1474. } else {
  1475. _glVertexAttribLPointer = NULL;
  1476. }
  1477. if (_supports_tessellation_shaders) {
  1478. _glPatchParameteri = (PFNGLPATCHPARAMETERIPROC)
  1479. get_extension_func("glPatchParameteri");
  1480. }
  1481. } else if (_supports_basic_shaders) {
  1482. // We don't support GLSL, but we support ARB programs.
  1483. _glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)
  1484. get_extension_func("glDisableVertexAttribArrayARB");
  1485. _glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)
  1486. get_extension_func("glEnableVertexAttribArrayARB");
  1487. _glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)
  1488. get_extension_func("glVertexAttrib4fvARB");
  1489. _glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)
  1490. get_extension_func("glVertexAttrib4dvARB");
  1491. _glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)
  1492. get_extension_func("glVertexAttribPointerARB");
  1493. _glVertexAttribIPointer = NULL;
  1494. _glVertexAttribLPointer = NULL;
  1495. }
  1496. #endif
  1497. #ifdef OPENGLES_2
  1498. _glAttachShader = glAttachShader;
  1499. _glBindAttribLocation = glBindAttribLocation;
  1500. _glCompileShader = glCompileShader;
  1501. _glCreateProgram = glCreateProgram;
  1502. _glCreateShader = glCreateShader;
  1503. _glDeleteProgram = glDeleteProgram;
  1504. _glDeleteShader = glDeleteShader;
  1505. _glDetachShader = glDetachShader;
  1506. _glDisableVertexAttribArray = glDisableVertexAttribArray;
  1507. _glEnableVertexAttribArray = glEnableVertexAttribArray;
  1508. _glGetActiveAttrib = glGetActiveAttrib;
  1509. _glGetActiveUniform = glGetActiveUniform;
  1510. _glGetAttribLocation = glGetAttribLocation;
  1511. _glGetProgramiv = glGetProgramiv;
  1512. _glGetProgramInfoLog = glGetProgramInfoLog;
  1513. _glGetShaderiv = glGetShaderiv;
  1514. _glGetShaderInfoLog = glGetShaderInfoLog;
  1515. _glGetUniformLocation = glGetUniformLocation;
  1516. _glLinkProgram = glLinkProgram;
  1517. _glShaderSource = (PFNGLSHADERSOURCEPROC_P) glShaderSource;
  1518. _glUseProgram = glUseProgram;
  1519. _glUniform4f = glUniform4f;
  1520. _glUniform1i = glUniform1i;
  1521. _glUniform1fv = glUniform1fv;
  1522. _glUniform2fv = glUniform2fv;
  1523. _glUniform3fv = glUniform3fv;
  1524. _glUniform4fv = glUniform4fv;
  1525. _glUniformMatrix3fv = glUniformMatrix3fv;
  1526. _glUniformMatrix4fv = glUniformMatrix4fv;
  1527. _glValidateProgram = glValidateProgram;
  1528. _glVertexAttrib4fv = glVertexAttrib4fv;
  1529. _glVertexAttrib4dv = null_glVertexAttrib4dv;
  1530. _glVertexAttribPointer = glVertexAttribPointer;
  1531. _glVertexAttribLPointer = NULL;
  1532. if (is_at_least_gles_version(3, 0)) {
  1533. _glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)
  1534. get_extension_func("glVertexAttribIPointer");
  1535. } else {
  1536. _glVertexAttribIPointer = NULL;
  1537. }
  1538. #endif
  1539. #ifndef OPENGLES_1
  1540. _use_vertex_attrib_binding = false;
  1541. #ifdef OPENGLES
  1542. if (is_at_least_gles_version(3, 1)) {
  1543. #else
  1544. if (is_at_least_gl_version(4, 3) || has_extension("GL_ARB_vertex_attrib_binding")) {
  1545. #endif
  1546. _glBindVertexBuffer = (PFNGLBINDVERTEXBUFFERPROC)
  1547. get_extension_func("glBindVertexBuffer");
  1548. _glVertexAttribFormat = (PFNGLVERTEXATTRIBFORMATPROC)
  1549. get_extension_func("glVertexAttribFormat");
  1550. _glVertexAttribIFormat = (PFNGLVERTEXATTRIBIFORMATPROC)
  1551. get_extension_func("glVertexAttribIFormat");
  1552. _glVertexAttribBinding = (PFNGLVERTEXATTRIBBINDINGPROC)
  1553. get_extension_func("glVertexAttribBinding");
  1554. _glVertexBindingDivisor = (PFNGLVERTEXBINDINGDIVISORPROC)
  1555. get_extension_func("glVertexBindingDivisor");
  1556. #ifndef OPENGLES
  1557. _glVertexAttribLFormat = (PFNGLVERTEXATTRIBLFORMATPROC)
  1558. get_extension_func("glVertexAttribLFormat");
  1559. #endif
  1560. if (gl_fixed_vertex_attrib_locations) {
  1561. _use_vertex_attrib_binding = true;
  1562. }
  1563. }
  1564. #endif
  1565. // We need to have a default shader to apply in case something didn't happen
  1566. // to have a shader applied, or if it failed to compile. This default
  1567. // shader just outputs a red color, indicating that something went wrong.
  1568. #ifndef SUPPORT_FIXED_FUNCTION
  1569. if (_default_shader == NULL) {
  1570. _default_shader = Shader::make(Shader::SL_GLSL, default_vshader, default_fshader);
  1571. }
  1572. #elif !defined(OPENGLES)
  1573. if (_default_shader == NULL && core_profile) {
  1574. _default_shader = Shader::make(Shader::SL_GLSL, default_vshader, default_fshader);
  1575. }
  1576. #endif
  1577. #ifndef OPENGLES
  1578. // Check for uniform buffers.
  1579. #ifdef OPENGLES
  1580. if (is_at_least_gl_version(3, 1) || has_extension("GL_ARB_uniform_buffer_object")) {
  1581. #else
  1582. if (is_at_least_gles_version(3, 0)) {
  1583. #endif
  1584. _supports_uniform_buffers = true;
  1585. _glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC)
  1586. get_extension_func("glGetActiveUniformsiv");
  1587. _glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)
  1588. get_extension_func("glGetActiveUniformBlockiv");
  1589. _glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)
  1590. get_extension_func("glGetActiveUniformBlockName");
  1591. _glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)
  1592. get_extension_func("glBindBufferBase");
  1593. } else {
  1594. _supports_uniform_buffers = false;
  1595. }
  1596. #endif
  1597. // Check whether we support geometry instancing and instanced vertex
  1598. // attribs.
  1599. #if defined(OPENGLES_1)
  1600. _supports_vertex_attrib_divisor = false;
  1601. _supports_geometry_instancing = false;
  1602. #elif defined(OPENGLES)
  1603. if (is_at_least_gles_version(3, 0)) {
  1604. // OpenGL ES 3 has all of this in the core.
  1605. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1606. get_extension_func("glVertexAttribDivisor");
  1607. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1608. get_extension_func("glDrawArraysInstanced");
  1609. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1610. get_extension_func("glDrawElementsInstanced");
  1611. _supports_vertex_attrib_divisor = true;
  1612. _supports_geometry_instancing = true;
  1613. } else if (has_extension("GL_ANGLE_instanced_arrays")) {
  1614. // This extension has both things in one.
  1615. #ifdef __EMSCRIPTEN__
  1616. // Work around bug - it doesn't allow ANGLE suffix in getProcAddress.
  1617. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1618. get_extension_func("glVertexAttribDivisor");
  1619. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1620. get_extension_func("glDrawArraysInstanced");
  1621. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1622. get_extension_func("glDrawElementsInstanced");
  1623. #else
  1624. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1625. get_extension_func("glVertexAttribDivisorANGLE");
  1626. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1627. get_extension_func("glDrawArraysInstancedANGLE");
  1628. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1629. get_extension_func("glDrawElementsInstancedANGLE");
  1630. #endif
  1631. _supports_vertex_attrib_divisor = true;
  1632. _supports_geometry_instancing = true;
  1633. } else {
  1634. // Check separately for geometry instancing and instanced attribs.
  1635. if (has_extension("GL_EXT_draw_instanced")) {
  1636. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1637. get_extension_func("glDrawArraysInstancedEXT");
  1638. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1639. get_extension_func("glDrawElementsInstancedEXT");
  1640. _supports_geometry_instancing = true;
  1641. } else if (has_extension("GL_NV_draw_instanced")) {
  1642. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1643. get_extension_func("glDrawArraysInstancedNV");
  1644. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1645. get_extension_func("glDrawElementsInstancedNV");
  1646. _supports_geometry_instancing = true;
  1647. } else {
  1648. _supports_geometry_instancing = false;
  1649. }
  1650. if (has_extension("GL_EXT_instanced_arrays")) {
  1651. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1652. get_extension_func("glVertexAttribDivisorEXT");
  1653. _supports_vertex_attrib_divisor = true;
  1654. } else if (has_extension("GL_NV_instanced_arrays")) {
  1655. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1656. get_extension_func("glVertexAttribDivisorNV");
  1657. _supports_vertex_attrib_divisor = true;
  1658. } else {
  1659. _supports_vertex_attrib_divisor = false;
  1660. }
  1661. }
  1662. #else
  1663. if (is_at_least_gl_version(3, 3)) {
  1664. // This feature is in OpenGL core as of 3.3.
  1665. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1666. get_extension_func("glVertexAttribDivisor");
  1667. _supports_vertex_attrib_divisor = true;
  1668. } else if (has_extension("GL_ARB_instanced_arrays")) {
  1669. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1670. get_extension_func("glVertexAttribDivisorARB");
  1671. _supports_vertex_attrib_divisor = true;
  1672. } else {
  1673. _supports_vertex_attrib_divisor = false;
  1674. }
  1675. // Some drivers expose one extension, some expose the other.
  1676. if (is_at_least_gl_version(3, 1)) {
  1677. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1678. get_extension_func("glDrawArraysInstanced");
  1679. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1680. get_extension_func("glDrawElementsInstanced");
  1681. _supports_geometry_instancing = true;
  1682. } else if (has_extension("GL_ARB_draw_instanced")) {
  1683. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1684. get_extension_func("glDrawArraysInstancedARB");
  1685. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1686. get_extension_func("glDrawElementsInstancedARB");
  1687. _supports_geometry_instancing = true;
  1688. } else if (has_extension("GL_EXT_draw_instanced")) {
  1689. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1690. get_extension_func("glDrawArraysInstancedEXT");
  1691. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1692. get_extension_func("glDrawElementsInstancedEXT");
  1693. _supports_geometry_instancing = true;
  1694. } else {
  1695. _glDrawElementsInstanced = 0;
  1696. _glDrawArraysInstanced = 0;
  1697. _supports_geometry_instancing = false;
  1698. }
  1699. #endif
  1700. #ifndef OPENGLES_1
  1701. if (_supports_geometry_instancing) {
  1702. if (_glDrawArraysInstanced == NULL || _glDrawElementsInstanced == NULL) {
  1703. GLCAT.warning()
  1704. << "Geometry instancing advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1705. _supports_geometry_instancing = false;
  1706. }
  1707. }
  1708. if (_supports_vertex_attrib_divisor) {
  1709. if (_glVertexAttribDivisor == NULL) {
  1710. GLCAT.warning()
  1711. << "Instanced vertex arrays advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1712. _supports_vertex_attrib_divisor = false;
  1713. }
  1714. }
  1715. #endif
  1716. // Check if we support indirect draw.
  1717. _supports_indirect_draw = false;
  1718. #ifndef OPENGLES_1
  1719. #ifdef OPENGLES
  1720. if (is_at_least_gles_version(3, 1)) {
  1721. #else
  1722. if (is_at_least_gl_version(4, 0) || has_extension("GL_ARB_draw_indirect")) {
  1723. #endif
  1724. _glDrawArraysIndirect = (PFNGLDRAWARRAYSINDIRECTPROC)
  1725. get_extension_func("glDrawArraysIndirect");
  1726. _glDrawElementsIndirect = (PFNGLDRAWELEMENTSINDIRECTPROC)
  1727. get_extension_func("glDrawElementsIndirect");
  1728. if (_glDrawArraysIndirect == NULL || _glDrawElementsIndirect == NULL) {
  1729. GLCAT.warning()
  1730. << "Indirect draw advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1731. } else {
  1732. _supports_indirect_draw = true;
  1733. }
  1734. }
  1735. #endif
  1736. #ifdef OPENGLES_1
  1737. _supports_framebuffer_multisample = false;
  1738. _supports_framebuffer_blit = false;
  1739. if (has_extension("GL_OES_framebuffer_object")) {
  1740. _supports_framebuffer_object = true;
  1741. _glIsRenderbuffer = (PFNGLISRENDERBUFFEROESPROC)
  1742. get_extension_func("glIsRenderbufferOES");
  1743. _glBindRenderbuffer = (PFNGLBINDRENDERBUFFEROESPROC)
  1744. get_extension_func("glBindRenderbufferOES");
  1745. _glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSOESPROC)
  1746. get_extension_func("glDeleteRenderbuffersOES");
  1747. _glGenRenderbuffers = (PFNGLGENRENDERBUFFERSOESPROC)
  1748. get_extension_func("glGenRenderbuffersOES");
  1749. _glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEOESPROC)
  1750. get_extension_func("glRenderbufferStorageOES");
  1751. _glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVOESPROC)
  1752. get_extension_func("glGetRenderbufferParameterivOES");
  1753. _glIsFramebuffer = (PFNGLISFRAMEBUFFEROESPROC)
  1754. get_extension_func("glIsFramebufferOES");
  1755. _glBindFramebuffer = (PFNGLBINDFRAMEBUFFEROESPROC)
  1756. get_extension_func("glBindFramebufferOES");
  1757. _glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSOESPROC)
  1758. get_extension_func("glDeleteFramebuffersOES");
  1759. _glGenFramebuffers = (PFNGLGENFRAMEBUFFERSOESPROC)
  1760. get_extension_func("glGenFramebuffersOES");
  1761. _glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSOESPROC)
  1762. get_extension_func("glCheckFramebufferStatusOES");
  1763. _glFramebufferTexture1D = NULL;
  1764. _glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DOESPROC)
  1765. get_extension_func("glFramebufferTexture2DOES");
  1766. _glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFEROESPROC)
  1767. get_extension_func("glFramebufferRenderbufferOES");
  1768. _glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVOESPROC)
  1769. get_extension_func("glGetFramebufferAttachmentParameterivOES");
  1770. _glGenerateMipmap = (PFNGLGENERATEMIPMAPOESPROC)
  1771. get_extension_func("glGenerateMipmapOES");
  1772. } else {
  1773. _supports_framebuffer_object = false;
  1774. _glGenerateMipmap = NULL;
  1775. }
  1776. #elif defined(OPENGLES)
  1777. // In OpenGL ES 2.x, FBO's are supported in the core.
  1778. _supports_framebuffer_object = true;
  1779. _glIsRenderbuffer = glIsRenderbuffer;
  1780. _glBindRenderbuffer = glBindRenderbuffer;
  1781. _glDeleteRenderbuffers = glDeleteRenderbuffers;
  1782. _glGenRenderbuffers = glGenRenderbuffers;
  1783. _glRenderbufferStorage = glRenderbufferStorage;
  1784. _glGetRenderbufferParameteriv = glGetRenderbufferParameteriv;
  1785. _glIsFramebuffer = glIsFramebuffer;
  1786. _glBindFramebuffer = glBindFramebuffer;
  1787. _glDeleteFramebuffers = glDeleteFramebuffers;
  1788. _glGenFramebuffers = glGenFramebuffers;
  1789. _glCheckFramebufferStatus = glCheckFramebufferStatus;
  1790. _glFramebufferTexture1D = NULL;
  1791. _glFramebufferTexture2D = glFramebufferTexture2D;
  1792. _glFramebufferRenderbuffer = glFramebufferRenderbuffer;
  1793. _glGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameteriv;
  1794. _glGenerateMipmap = glGenerateMipmap;
  1795. if (is_at_least_gles_version(3, 0)) {
  1796. _supports_framebuffer_multisample = true;
  1797. _supports_framebuffer_blit = true;
  1798. _glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)
  1799. get_extension_func("glRenderbufferStorageMultisample");
  1800. _glBlitFramebuffer = (PFNGLBLITFRAMEBUFFEREXTPROC)
  1801. get_extension_func("glBlitFramebuffer");
  1802. } else {
  1803. if (has_extension("GL_ANGLE_framebuffer_multisample")) {
  1804. _supports_framebuffer_multisample = true;
  1805. _glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC)
  1806. get_extension_func("glRenderbufferStorageMultisampleANGLE");
  1807. } else {
  1808. _supports_framebuffer_multisample = false;
  1809. }
  1810. if (has_extension("GL_ANGLE_framebuffer_blit")) {
  1811. _supports_framebuffer_blit = true;
  1812. _glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERANGLEPROC)
  1813. get_extension_func("glBlitFramebufferANGLE");
  1814. } else {
  1815. _supports_framebuffer_blit = false;
  1816. }
  1817. }
  1818. #else // Desktop OpenGL case.
  1819. if (is_at_least_gl_version(3, 0) || has_extension("GL_ARB_framebuffer_object")) {
  1820. _supports_framebuffer_object = true;
  1821. _supports_framebuffer_multisample = true;
  1822. _supports_framebuffer_blit = true;
  1823. _glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)
  1824. get_extension_func("glIsRenderbuffer");
  1825. _glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)
  1826. get_extension_func("glBindRenderbuffer");
  1827. _glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)
  1828. get_extension_func("glDeleteRenderbuffers");
  1829. _glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)
  1830. get_extension_func("glGenRenderbuffers");
  1831. _glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)
  1832. get_extension_func("glRenderbufferStorage");
  1833. _glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)
  1834. get_extension_func("glGetRenderbufferParameteriv");
  1835. _glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)
  1836. get_extension_func("glIsFramebuffer");
  1837. _glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)
  1838. get_extension_func("glBindFramebuffer");
  1839. _glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)
  1840. get_extension_func("glDeleteFramebuffers");
  1841. _glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)
  1842. get_extension_func("glGenFramebuffers");
  1843. _glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)
  1844. get_extension_func("glCheckFramebufferStatus");
  1845. _glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)
  1846. get_extension_func("glFramebufferTexture1D");
  1847. _glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)
  1848. get_extension_func("glFramebufferTexture2D");
  1849. _glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)
  1850. get_extension_func("glFramebufferTexture3D");
  1851. _glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)
  1852. get_extension_func("glFramebufferRenderbuffer");
  1853. _glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)
  1854. get_extension_func("glGetFramebufferAttachmentParameteriv");
  1855. _glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)
  1856. get_extension_func("glGenerateMipmap");
  1857. _glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)
  1858. get_extension_func("glRenderbufferStorageMultisampleEXT");
  1859. _glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)
  1860. get_extension_func("glBlitFramebuffer");
  1861. } else if (has_extension("GL_EXT_framebuffer_object")) {
  1862. _supports_framebuffer_object = true;
  1863. _glIsRenderbuffer = (PFNGLISRENDERBUFFEREXTPROC)
  1864. get_extension_func("glIsRenderbufferEXT");
  1865. _glBindRenderbuffer = (PFNGLBINDRENDERBUFFEREXTPROC)
  1866. get_extension_func("glBindRenderbufferEXT");
  1867. _glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSEXTPROC)
  1868. get_extension_func("glDeleteRenderbuffersEXT");
  1869. _glGenRenderbuffers = (PFNGLGENRENDERBUFFERSEXTPROC)
  1870. get_extension_func("glGenRenderbuffersEXT");
  1871. _glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEEXTPROC)
  1872. get_extension_func("glRenderbufferStorageEXT");
  1873. _glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)
  1874. get_extension_func("glGetRenderbufferParameterivEXT");
  1875. _glIsFramebuffer = (PFNGLISFRAMEBUFFEREXTPROC)
  1876. get_extension_func("glIsFramebufferEXT");
  1877. _glBindFramebuffer = (PFNGLBINDFRAMEBUFFEREXTPROC)
  1878. get_extension_func("glBindFramebufferEXT");
  1879. _glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSEXTPROC)
  1880. get_extension_func("glDeleteFramebuffersEXT");
  1881. _glGenFramebuffers = (PFNGLGENFRAMEBUFFERSEXTPROC)
  1882. get_extension_func("glGenFramebuffersEXT");
  1883. _glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
  1884. get_extension_func("glCheckFramebufferStatusEXT");
  1885. _glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)
  1886. get_extension_func("glFramebufferTexture1DEXT");
  1887. _glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)
  1888. get_extension_func("glFramebufferTexture2DEXT");
  1889. _glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)
  1890. get_extension_func("glFramebufferTexture3DEXT");
  1891. _glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)
  1892. get_extension_func("glFramebufferRenderbufferEXT");
  1893. _glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)
  1894. get_extension_func("glGetFramebufferAttachmentParameterivEXT");
  1895. _glGenerateMipmap = (PFNGLGENERATEMIPMAPEXTPROC)
  1896. get_extension_func("glGenerateMipmapEXT");
  1897. if (has_extension("GL_EXT_framebuffer_multisample")) {
  1898. _supports_framebuffer_multisample = true;
  1899. _glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)
  1900. get_extension_func("glRenderbufferStorageMultisampleEXT");
  1901. } else {
  1902. _supports_framebuffer_multisample = false;
  1903. }
  1904. if (has_extension("GL_EXT_framebuffer_blit")) {
  1905. _supports_framebuffer_blit = true;
  1906. _glBlitFramebuffer = (PFNGLBLITFRAMEBUFFEREXTPROC)
  1907. get_extension_func("glBlitFramebufferEXT");
  1908. } else {
  1909. _supports_framebuffer_blit = false;
  1910. }
  1911. } else {
  1912. _supports_framebuffer_object = false;
  1913. _supports_framebuffer_multisample = false;
  1914. _supports_framebuffer_blit = false;
  1915. _glGenerateMipmap = NULL;
  1916. }
  1917. #endif
  1918. #ifndef OPENGLES
  1919. if (is_at_least_gl_version(4, 5) || has_extension("GL_ARB_direct_state_access")) {
  1920. _glGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC)
  1921. get_extension_func("glGenerateTextureMipmap");
  1922. } else {
  1923. _glGenerateTextureMipmap = NULL;
  1924. }
  1925. #endif
  1926. #ifndef OPENGLES_1
  1927. // Do we support empty framebuffer objects?
  1928. #ifdef OPENGLES
  1929. if (is_at_least_gles_version(3, 1)) {
  1930. #else
  1931. if (is_at_least_gl_version(4, 3) || has_extension("GL_ARB_framebuffer_no_attachments")) {
  1932. #endif
  1933. _glFramebufferParameteri = (PFNGLFRAMEBUFFERPARAMETERIPROC)
  1934. get_extension_func("glFramebufferParameteri");
  1935. _supports_empty_framebuffer = true;
  1936. } else {
  1937. _supports_empty_framebuffer = false;
  1938. }
  1939. #endif // !OPENGLES_1
  1940. #ifndef OPENGLES
  1941. _supports_framebuffer_multisample_coverage_nv = false;
  1942. if (_supports_framebuffer_multisample &&
  1943. has_extension("GL_NV_framebuffer_multisample_coverage")) {
  1944. _supports_framebuffer_multisample_coverage_nv = true;
  1945. _glRenderbufferStorageMultisampleCoverage = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC)
  1946. get_extension_func("glRenderbufferStorageMultisampleCoverageNV");
  1947. }
  1948. #endif
  1949. #if defined(OPENGLES_1)
  1950. _glDrawBuffers = NULL;
  1951. _max_color_targets = 1;
  1952. #elif defined(OPENGLES_2)
  1953. if (is_at_least_gles_version(3, 0)) {
  1954. _glDrawBuffers = (PFNGLDRAWBUFFERSPROC)
  1955. get_extension_func("glDrawBuffers");
  1956. #ifdef __EMSCRIPTEN__
  1957. } else if (has_extension("WEBGL_draw_buffers")) {
  1958. _glDrawBuffers = (PFNGLDRAWBUFFERSPROC)
  1959. get_extension_func("glDrawBuffers");
  1960. #endif // EMSCRIPTEN
  1961. } else if (has_extension("GL_EXT_draw_buffers")) {
  1962. _glDrawBuffers = (PFNGLDRAWBUFFERSPROC)
  1963. get_extension_func("glDrawBuffersEXT");
  1964. } else if (has_extension("GL_NV_draw_buffers")) {
  1965. _glDrawBuffers = (PFNGLDRAWBUFFERSPROC)
  1966. get_extension_func("glDrawBuffersNV");
  1967. } else {
  1968. _glDrawBuffers = NULL;
  1969. }
  1970. #else
  1971. if (is_at_least_gl_version(2, 0)) {
  1972. _glDrawBuffers = (PFNGLDRAWBUFFERSPROC)
  1973. get_extension_func("glDrawBuffers");
  1974. } else if (has_extension("GL_ARB_draw_buffers")) {
  1975. _glDrawBuffers = (PFNGLDRAWBUFFERSPROC)
  1976. get_extension_func("glDrawBuffersARB");
  1977. } else {
  1978. _glDrawBuffers = NULL;
  1979. }
  1980. #endif
  1981. #ifndef OPENGLES_1
  1982. _max_color_targets = 1;
  1983. if (_glDrawBuffers != NULL) {
  1984. GLint max_draw_buffers = 0;
  1985. glGetIntegerv(GL_MAX_DRAW_BUFFERS, &max_draw_buffers);
  1986. _max_color_targets = max_draw_buffers;
  1987. }
  1988. #endif // !OPENGLES_1
  1989. #ifndef OPENGLES_1
  1990. if (_gl_version_major >= 3) {
  1991. _glClearBufferfv = (PFNGLCLEARBUFFERFVPROC)
  1992. get_extension_func("glClearBufferfv");
  1993. _glClearBufferiv = (PFNGLCLEARBUFFERIVPROC)
  1994. get_extension_func("glClearBufferiv");
  1995. _glClearBufferfi = (PFNGLCLEARBUFFERFIPROC)
  1996. get_extension_func("glClearBufferfi");
  1997. } else {
  1998. _glClearBufferfv = NULL;
  1999. _glClearBufferiv = NULL;
  2000. _glClearBufferfi = NULL;
  2001. }
  2002. #endif // !OPENGLES
  2003. #ifndef OPENGLES
  2004. _supports_viewport_arrays = false;
  2005. if (is_at_least_gl_version(4, 1) || has_extension("GL_ARB_viewport_array")) {
  2006. _glViewportArrayv = (PFNGLVIEWPORTARRAYVPROC)
  2007. get_extension_func("glViewportArrayv");
  2008. _glScissorArrayv = (PFNGLSCISSORARRAYVPROC)
  2009. get_extension_func("glScissorArrayv");
  2010. _glDepthRangeArrayv = (PFNGLDEPTHRANGEARRAYVPROC)
  2011. get_extension_func("glDepthRangeArrayv");
  2012. if (_glViewportArrayv == NULL || _glScissorArrayv == NULL || _glDepthRangeArrayv == NULL) {
  2013. GLCAT.warning()
  2014. << "Viewport arrays advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  2015. } else {
  2016. _supports_viewport_arrays = true;
  2017. }
  2018. }
  2019. #endif // !OPENGLES
  2020. _max_fb_samples = 0;
  2021. if (_supports_framebuffer_multisample) {
  2022. GLint max_samples;
  2023. glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_samples);
  2024. _max_fb_samples = max_samples;
  2025. }
  2026. _supports_occlusion_query = false;
  2027. #ifndef OPENGLES
  2028. if (gl_support_occlusion_query) {
  2029. if (is_at_least_gl_version(1, 5)) {
  2030. _supports_occlusion_query = true;
  2031. _glGenQueries = (PFNGLGENQUERIESPROC)
  2032. get_extension_func("glGenQueries");
  2033. _glBeginQuery = (PFNGLBEGINQUERYPROC)
  2034. get_extension_func("glBeginQuery");
  2035. _glEndQuery = (PFNGLENDQUERYPROC)
  2036. get_extension_func("glEndQuery");
  2037. _glDeleteQueries = (PFNGLDELETEQUERIESPROC)
  2038. get_extension_func("glDeleteQueries");
  2039. _glGetQueryiv = (PFNGLGETQUERYIVPROC)
  2040. get_extension_func("glGetQueryiv");
  2041. _glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)
  2042. get_extension_func("glGetQueryObjectuiv");
  2043. } else if (has_extension("GL_ARB_occlusion_query")) {
  2044. _supports_occlusion_query = true;
  2045. _glGenQueries = (PFNGLGENQUERIESPROC)
  2046. get_extension_func("glGenQueriesARB");
  2047. _glBeginQuery = (PFNGLBEGINQUERYPROC)
  2048. get_extension_func("glBeginQueryARB");
  2049. _glEndQuery = (PFNGLENDQUERYPROC)
  2050. get_extension_func("glEndQueryARB");
  2051. _glDeleteQueries = (PFNGLDELETEQUERIESPROC)
  2052. get_extension_func("glDeleteQueriesARB");
  2053. _glGetQueryiv = (PFNGLGETQUERYIVPROC)
  2054. get_extension_func("glGetQueryivARB");
  2055. _glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)
  2056. get_extension_func("glGetQueryObjectuivARB");
  2057. }
  2058. }
  2059. if (_supports_occlusion_query) {
  2060. if (_glGenQueries == NULL || _glBeginQuery == NULL ||
  2061. _glEndQuery == NULL || _glDeleteQueries == NULL ||
  2062. _glGetQueryiv == NULL || _glGetQueryObjectuiv == NULL) {
  2063. GLCAT.warning()
  2064. << "Occlusion queries advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  2065. _supports_occlusion_query = false;
  2066. } else {
  2067. GLint num_bits;
  2068. _glGetQueryiv(GL_SAMPLES_PASSED, GL_QUERY_COUNTER_BITS, &num_bits);
  2069. if (num_bits == 0) {
  2070. _supports_occlusion_query = false;
  2071. }
  2072. if (GLCAT.is_debug()) {
  2073. GLCAT.debug()
  2074. << "Occlusion query counter provides " << num_bits << " bits.\n";
  2075. }
  2076. }
  2077. }
  2078. #endif // !OPENGLES
  2079. _supports_timer_query = false;
  2080. #if defined(DO_PSTATS) && !defined(OPENGLES)
  2081. if (is_at_least_gl_version(3, 3) || has_extension("GL_ARB_timer_query")) {
  2082. _supports_timer_query = true;
  2083. _glQueryCounter = (PFNGLQUERYCOUNTERPROC)
  2084. get_extension_func("glQueryCounter");
  2085. _glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC)
  2086. get_extension_func("glGetQueryObjecti64v");
  2087. _glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC)
  2088. get_extension_func("glGetQueryObjectui64v");
  2089. _glGetInteger64v = (PFNGLGETINTEGER64VPROC)
  2090. get_extension_func("glGetInteger64v");
  2091. }
  2092. #endif
  2093. #ifdef OPENGLES_1
  2094. // In OpenGL ES 1, blending is supported via extensions.
  2095. if (has_extension("GL_OES_blend_subtract")) {
  2096. _glBlendEquation = (PFNGLBLENDEQUATIONPROC)
  2097. get_extension_func("glBlendEquationOES");
  2098. if (_glBlendEquation == NULL) {
  2099. _glBlendEquation = null_glBlendEquation;
  2100. GLCAT.warning()
  2101. << "BlendEquationOES advertised as supported by OpenGL ES runtime, but "
  2102. "could not get pointer to extension function.\n";
  2103. }
  2104. } else {
  2105. _glBlendEquation = null_glBlendEquation;
  2106. }
  2107. if (has_extension("GL_OES_blend_equation_separate")) {
  2108. _glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEOESPROC)
  2109. get_extension_func("glBlendEquationSeparateOES");
  2110. if (_glBlendEquation == NULL) {
  2111. _supports_blend_equation_separate = false;
  2112. GLCAT.warning()
  2113. << "BlendEquationSeparateOES advertised as supported by OpenGL ES "
  2114. "runtime, but could not get pointer to extension function.\n";
  2115. } else {
  2116. _supports_blend_equation_separate = true;
  2117. }
  2118. } else {
  2119. _supports_blend_equation_separate = false;
  2120. _glBlendEquationSeparate = NULL;
  2121. }
  2122. if (has_extension("GL_OES_blend_func_separate")) {
  2123. _glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEOESPROC)
  2124. get_extension_func("glBlendFuncSeparateOES");
  2125. if (_glBlendFuncSeparate == NULL) {
  2126. _glBlendFuncSeparate = null_glBlendFuncSeparate;
  2127. GLCAT.warning()
  2128. << "BlendFuncSeparateOES advertised as supported by OpenGL ES runtime, but "
  2129. "could not get pointer to extension function.\n";
  2130. }
  2131. } else {
  2132. _glBlendFuncSeparate = null_glBlendFuncSeparate;
  2133. }
  2134. #elif defined(OPENGLES)
  2135. // In OpenGL ES 2.x and above, this is supported in the core.
  2136. _supports_blend_equation_separate = false;
  2137. #else
  2138. if (is_at_least_gl_version(1, 2)) {
  2139. _glBlendEquation = (PFNGLBLENDEQUATIONPROC)
  2140. get_extension_func("glBlendEquation");
  2141. } else if (has_extension("GL_EXT_blend_minmax")) {
  2142. _glBlendEquation = (PFNGLBLENDEQUATIONPROC)
  2143. get_extension_func("glBlendEquationEXT");
  2144. } else {
  2145. _glBlendEquation = null_glBlendEquation;
  2146. }
  2147. if (_glBlendEquation == NULL) {
  2148. _glBlendEquation = null_glBlendEquation;
  2149. GLCAT.warning()
  2150. << "BlendEquation advertised as supported by OpenGL runtime, but could "
  2151. "not get pointer to extension function.\n";
  2152. }
  2153. if (is_at_least_gl_version(2, 0)) {
  2154. _supports_blend_equation_separate = true;
  2155. _glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)
  2156. get_extension_func("glBlendEquationSeparate");
  2157. } else if (has_extension("GL_EXT_blend_equation_separate")) {
  2158. _supports_blend_equation_separate = true;
  2159. _glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEEXTPROC)
  2160. get_extension_func("glBlendEquationSeparateEXT");
  2161. } else {
  2162. _supports_blend_equation_separate = false;
  2163. _glBlendEquationSeparate = NULL;
  2164. }
  2165. if (_supports_blend_equation_separate && _glBlendEquationSeparate == NULL) {
  2166. _supports_blend_equation_separate = false;
  2167. GLCAT.warning()
  2168. << "BlendEquationSeparate advertised as supported by OpenGL runtime, "
  2169. "but could not get pointer to extension function.\n";
  2170. }
  2171. if (is_at_least_gl_version(1, 4)) {
  2172. _glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)
  2173. get_extension_func("glBlendFuncSeparate");
  2174. } else if (has_extension("GL_EXT_blend_func_separate")) {
  2175. _glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEEXTPROC)
  2176. get_extension_func("glBlendFuncSeparateEXT");
  2177. } else {
  2178. _glBlendFuncSeparate = null_glBlendFuncSeparate;
  2179. }
  2180. if (_glBlendFuncSeparate == NULL) {
  2181. _glBlendFuncSeparate = null_glBlendFuncSeparate;
  2182. GLCAT.warning()
  2183. << "BlendFuncSeparate advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  2184. }
  2185. #endif
  2186. // In OpenGL ES 2.x, this is supported in the core. In 1.x, not at all.
  2187. #ifndef OPENGLES
  2188. _glBlendColor = NULL;
  2189. bool supports_blend_color = false;
  2190. if (is_at_least_gl_version(1, 2)) {
  2191. supports_blend_color = true;
  2192. _glBlendColor = (PFNGLBLENDCOLORPROC)
  2193. get_extension_func("glBlendColor");
  2194. } else if (has_extension("GL_EXT_blend_color")) {
  2195. supports_blend_color = true;
  2196. _glBlendColor = (PFNGLBLENDCOLORPROC)
  2197. get_extension_func("glBlendColorEXT");
  2198. }
  2199. if (supports_blend_color && _glBlendColor == NULL) {
  2200. GLCAT.warning()
  2201. << "BlendColor advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  2202. }
  2203. if (_glBlendColor == NULL) {
  2204. _glBlendColor = null_glBlendColor;
  2205. }
  2206. #endif
  2207. #ifdef OPENGLES_1
  2208. // OpenGL ES 1 doesn't support dual-source blending.
  2209. #elif defined(OPENGLES)
  2210. _supports_dual_source_blending = has_extension("GL_EXT_blend_func_extended");
  2211. #else
  2212. _supports_dual_source_blending =
  2213. is_at_least_gl_version(3, 3) || has_extension("GL_ARB_blend_func_extended");
  2214. #endif
  2215. #ifdef OPENGLES
  2216. _edge_clamp = GL_CLAMP_TO_EDGE;
  2217. #else
  2218. _edge_clamp = GL_CLAMP;
  2219. if (is_at_least_gl_version(1, 2) || is_at_least_gles_version(1, 1) ||
  2220. has_extension("GL_SGIS_texture_edge_clamp")) {
  2221. _edge_clamp = GL_CLAMP_TO_EDGE;
  2222. }
  2223. #endif
  2224. _border_clamp = _edge_clamp;
  2225. #ifndef OPENGLES
  2226. if (gl_support_clamp_to_border &&
  2227. (has_extension("GL_ARB_texture_border_clamp") ||
  2228. is_at_least_gl_version(1, 3))) {
  2229. _border_clamp = GL_CLAMP_TO_BORDER;
  2230. }
  2231. #endif
  2232. #ifdef OPENGLES_1
  2233. _mirror_repeat = GL_REPEAT;
  2234. if (has_extension("GL_OES_texture_mirrored_repeat")) {
  2235. _mirror_repeat = GL_MIRRORED_REPEAT;
  2236. }
  2237. #elif defined(OPENGLES)
  2238. // OpenGL 2.x and above support this in the core.
  2239. _mirror_repeat = GL_MIRRORED_REPEAT;
  2240. #else
  2241. _mirror_repeat = GL_REPEAT;
  2242. if (is_at_least_gl_version(1, 4) ||
  2243. has_extension("GL_ARB_texture_mirrored_repeat")) {
  2244. _mirror_repeat = GL_MIRRORED_REPEAT;
  2245. }
  2246. #endif
  2247. _mirror_clamp = _edge_clamp;
  2248. _mirror_edge_clamp = _edge_clamp;
  2249. _mirror_border_clamp = _border_clamp;
  2250. #ifndef OPENGLES
  2251. if (has_extension("GL_EXT_texture_mirror_clamp")) {
  2252. _mirror_clamp = GL_MIRROR_CLAMP_EXT;
  2253. _mirror_edge_clamp = GL_MIRROR_CLAMP_TO_EDGE_EXT;
  2254. _mirror_border_clamp = GL_MIRROR_CLAMP_TO_BORDER_EXT;
  2255. }
  2256. #endif
  2257. #ifdef OPENGLES
  2258. _supports_texture_lod = is_at_least_gles_version(3, 0);
  2259. _supports_texture_lod_bias = false;
  2260. #else
  2261. _supports_texture_lod = false;
  2262. _supports_texture_lod_bias = false;
  2263. if (gl_support_texture_lod &&
  2264. (is_at_least_gl_version(1, 2) || has_extension("GL_SGIS_texture_lod"))) {
  2265. _supports_texture_lod = true;
  2266. if (is_at_least_gl_version(1, 4) || has_extension("GL_EXT_texture_lod_bias")) {
  2267. _supports_texture_lod_bias = true;
  2268. }
  2269. }
  2270. #endif
  2271. #ifdef OPENGLES
  2272. _supports_texture_max_level = is_at_least_gles_version(3, 0) ||
  2273. has_extension("GL_APPLE_texture_max_level");
  2274. #else
  2275. _supports_texture_max_level = is_at_least_gl_version(1, 2);
  2276. #endif
  2277. if (_supports_multisample) {
  2278. GLint sample_buffers = 0;
  2279. glGetIntegerv(GL_SAMPLE_BUFFERS, &sample_buffers);
  2280. if (sample_buffers != 1) {
  2281. // Even if the API supports multisample, we might have ended up with a
  2282. // framebuffer that doesn't have any multisample bits. (It's also
  2283. // possible the graphics card doesn't provide any framebuffers with
  2284. // multisample.) In this case, we don't really support the multisample
  2285. // API's, since they won't do anything.
  2286. _supports_multisample = false;
  2287. }
  2288. }
  2289. GLint max_texture_size = 0;
  2290. GLint max_3d_texture_size = 0;
  2291. GLint max_2d_texture_array_layers = 0;
  2292. GLint max_cube_map_size = 0;
  2293. GLint max_buffer_texture_size = 0;
  2294. glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
  2295. _max_texture_dimension = max_texture_size;
  2296. if (_supports_3d_texture) {
  2297. #ifndef OPENGLES_1
  2298. glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
  2299. #endif
  2300. _max_3d_texture_dimension = max_3d_texture_size;
  2301. } else {
  2302. _max_3d_texture_dimension = 0;
  2303. }
  2304. #ifndef OPENGLES_1
  2305. if (_supports_2d_texture_array) {
  2306. glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &max_2d_texture_array_layers);
  2307. _max_2d_texture_array_layers = max_2d_texture_array_layers;
  2308. }
  2309. #endif
  2310. if (_supports_cube_map) {
  2311. glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_size);
  2312. _max_cube_map_dimension = max_cube_map_size;
  2313. } else {
  2314. _max_cube_map_dimension = 0;
  2315. }
  2316. #ifndef OPENGLES
  2317. if (_supports_buffer_texture) {
  2318. glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &max_buffer_texture_size);
  2319. _max_buffer_texture_size = max_buffer_texture_size;
  2320. } else {
  2321. _max_buffer_texture_size = 0;
  2322. }
  2323. #endif // !OPENGLES
  2324. GLint max_elements_vertices = 0, max_elements_indices = 0;
  2325. #ifndef OPENGLES
  2326. if (is_at_least_gl_version(1, 2) || has_extension("GL_EXT_draw_range_elements")) {
  2327. glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &max_elements_vertices);
  2328. glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &max_elements_indices);
  2329. if (max_elements_vertices > 0) {
  2330. _max_vertices_per_array = max_elements_vertices;
  2331. }
  2332. if (max_elements_indices > 0) {
  2333. _max_vertices_per_primitive = max_elements_indices;
  2334. }
  2335. }
  2336. #endif // OPENGLES
  2337. if (GLCAT.is_debug()) {
  2338. GLCAT.debug()
  2339. << "max texture dimension = " << _max_texture_dimension
  2340. << ", max 3d texture = " << _max_3d_texture_dimension
  2341. << ", max 2d texture array = " << max_2d_texture_array_layers
  2342. << ", max cube map = " << _max_cube_map_dimension << "\n";
  2343. #ifndef OPENGLES
  2344. GLCAT.debug()
  2345. << "max_elements_vertices = " << max_elements_vertices
  2346. << ", max_elements_indices = " << max_elements_indices << "\n";
  2347. #endif
  2348. if (_supports_buffers) {
  2349. if (vertex_buffers) {
  2350. GLCAT.debug()
  2351. << "vertex buffer objects are supported.\n";
  2352. } else {
  2353. GLCAT.debug()
  2354. << "vertex buffer objects are supported (but not enabled).\n";
  2355. }
  2356. } else {
  2357. GLCAT.debug()
  2358. << "vertex buffer objects are NOT supported.\n";
  2359. }
  2360. #ifdef SUPPORT_IMMEDIATE_MODE
  2361. if (!vertex_arrays) {
  2362. GLCAT.debug()
  2363. << "immediate mode commands will be used instead of vertex arrays.\n";
  2364. }
  2365. #endif
  2366. if (!_supports_compressed_texture) {
  2367. GLCAT.debug()
  2368. << "Texture compression is not supported.\n";
  2369. } else {
  2370. GLint num_compressed_formats = 0;
  2371. glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_compressed_formats);
  2372. if (num_compressed_formats == 0) {
  2373. GLCAT.debug()
  2374. << "No specific compressed texture formats are supported.\n";
  2375. } else {
  2376. #ifndef NDEBUG
  2377. GLCAT.debug()
  2378. << "Supported compressed texture formats:\n";
  2379. GLint *formats = (GLint *)alloca(num_compressed_formats * sizeof(GLint));
  2380. glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats);
  2381. for (int i = 0; i < num_compressed_formats; ++i) {
  2382. const char *format_str = get_compressed_format_string(formats[i]);
  2383. if (format_str != NULL) {
  2384. GLCAT.debug(false) << " " << format_str << '\n';
  2385. } else {
  2386. GLCAT.debug(false)
  2387. << " Unknown compressed format 0x" << hex << formats[i]
  2388. << dec << "\n";
  2389. }
  2390. }
  2391. #endif
  2392. }
  2393. }
  2394. }
  2395. _active_texture_stage = -1;
  2396. _num_active_texture_stages = 0;
  2397. // Check availability of anisotropic texture filtering.
  2398. _supports_anisotropy = false;
  2399. _max_anisotropy = 1.0;
  2400. if (has_extension("GL_EXT_texture_filter_anisotropic")) {
  2401. GLfloat max_anisotropy;
  2402. glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy);
  2403. _max_anisotropy = (PN_stdfloat)max_anisotropy;
  2404. _supports_anisotropy = true;
  2405. }
  2406. // Check availability of image read/write functionality in shaders.
  2407. _max_image_units = 0;
  2408. #ifndef OPENGLES_1
  2409. #ifdef OPENGLES
  2410. if (is_at_least_gl_version(3, 1)) {
  2411. #else
  2412. if (is_at_least_gl_version(4, 2) || has_extension("GL_ARB_shader_image_load_store")) {
  2413. #endif
  2414. _glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)
  2415. get_extension_func("glBindImageTexture");
  2416. _glMemoryBarrier = (PFNGLMEMORYBARRIERPROC)
  2417. get_extension_func("glMemoryBarrier");
  2418. glGetIntegerv(GL_MAX_IMAGE_UNITS, &_max_image_units);
  2419. #ifndef OPENGLES
  2420. } else if (has_extension("GL_EXT_shader_image_load_store")) {
  2421. _glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)
  2422. get_extension_func("glBindImageTextureEXT");
  2423. _glMemoryBarrier = (PFNGLMEMORYBARRIERPROC)
  2424. get_extension_func("glMemoryBarrierEXT");
  2425. glGetIntegerv(GL_MAX_IMAGE_UNITS_EXT, &_max_image_units);
  2426. #endif
  2427. } else {
  2428. _glBindImageTexture = NULL;
  2429. _glMemoryBarrier = NULL;
  2430. }
  2431. #endif // !OPENGLES_1
  2432. _supports_sampler_objects = false;
  2433. #ifndef OPENGLES_1
  2434. if (gl_support_sampler_objects &&
  2435. #ifdef OPENGLES
  2436. is_at_least_gles_version(3, 0)) {
  2437. #else
  2438. (is_at_least_gl_version(3, 3) || has_extension("GL_ARB_sampler_objects"))) {
  2439. #endif
  2440. _glGenSamplers = (PFNGLGENSAMPLERSPROC) get_extension_func("glGenSamplers");
  2441. _glDeleteSamplers = (PFNGLDELETESAMPLERSPROC) get_extension_func("glDeleteSamplers");
  2442. _glBindSampler = (PFNGLBINDSAMPLERPROC) get_extension_func("glBindSampler");
  2443. _glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC) get_extension_func("glSamplerParameteri");
  2444. _glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC) get_extension_func("glSamplerParameteriv");
  2445. _glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC) get_extension_func("glSamplerParameterf");
  2446. _glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC) get_extension_func("glSamplerParameterfv");
  2447. if (_glGenSamplers == NULL || _glDeleteSamplers == NULL ||
  2448. _glBindSampler == NULL || _glSamplerParameteri == NULL ||
  2449. _glSamplerParameteriv == NULL || _glSamplerParameterf == NULL ||
  2450. _glSamplerParameterfv == NULL) {
  2451. GLCAT.warning()
  2452. << "GL_ARB_sampler_objects advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  2453. } else {
  2454. _supports_sampler_objects = true;
  2455. }
  2456. }
  2457. #endif // !OPENGLES_1
  2458. // Check availability of multi-bind functions.
  2459. _supports_multi_bind = false;
  2460. #ifndef OPENGLES
  2461. if (is_at_least_gl_version(4, 4) || has_extension("GL_ARB_multi_bind")) {
  2462. _glBindTextures = (PFNGLBINDTEXTURESPROC)
  2463. get_extension_func("glBindTextures");
  2464. _glBindImageTextures = (PFNGLBINDIMAGETEXTURESPROC)
  2465. get_extension_func("glBindImageTextures");
  2466. if (_supports_sampler_objects) {
  2467. _glBindSamplers = (PFNGLBINDSAMPLERSPROC)
  2468. get_extension_func("glBindSamplers");
  2469. }
  2470. if (_use_vertex_attrib_binding) {
  2471. _glBindVertexBuffers = (PFNGLBINDVERTEXBUFFERSPROC)
  2472. get_extension_func("glBindVertexBuffers");
  2473. }
  2474. if (_glBindTextures != NULL && _glBindImageTextures != NULL) {
  2475. _supports_multi_bind = true;
  2476. } else {
  2477. GLCAT.warning()
  2478. << "ARB_multi_bind advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  2479. }
  2480. }
  2481. #endif // !OPENGLES
  2482. #ifndef OPENGLES_1
  2483. #ifdef OPENGLES
  2484. if (is_at_least_gl_version(3, 0)) {
  2485. #else
  2486. if (is_at_least_gl_version(4, 3) || has_extension("GL_ARB_internalformat_query2")) {
  2487. #endif
  2488. _glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC)
  2489. get_extension_func("glGetInternalformativ");
  2490. if (_glGetInternalformativ == NULL) {
  2491. GLCAT.warning()
  2492. << "ARB_internalformat_query2 advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  2493. }
  2494. }
  2495. #endif // !OPENGLES_1
  2496. _supports_bindless_texture = false;
  2497. #ifndef OPENGLES
  2498. if (has_extension("GL_ARB_bindless_texture")) {
  2499. _glGetTextureHandle = (PFNGLGETTEXTUREHANDLEPROC)
  2500. get_extension_func("glGetTextureHandleARB");
  2501. _glGetTextureSamplerHandle = (PFNGLGETTEXTURESAMPLERHANDLEPROC)
  2502. get_extension_func("glGetTextureSamplerHandleARB");
  2503. _glMakeTextureHandleResident = (PFNGLMAKETEXTUREHANDLERESIDENTPROC)
  2504. get_extension_func("glMakeTextureHandleResidentARB");
  2505. _glUniformHandleui64 = (PFNGLUNIFORMHANDLEUI64PROC)
  2506. get_extension_func("glUniformHandleui64ARB");
  2507. if (_glGetTextureHandle == NULL || _glMakeTextureHandleResident == NULL ||
  2508. _glUniformHandleui64 == NULL) {
  2509. GLCAT.warning()
  2510. << "GL_ARB_bindless_texture advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  2511. } else {
  2512. _supports_bindless_texture = true;
  2513. }
  2514. }
  2515. #endif // !OPENGLES
  2516. #ifndef OPENGLES_1
  2517. _supports_get_program_binary = false;
  2518. _program_binary_formats.clear();
  2519. #ifdef OPENGLES
  2520. if (is_at_least_gles_version(3, 0)) {
  2521. #else
  2522. if (is_at_least_gl_version(4, 1) || has_extension("GL_ARB_get_program_binary")) {
  2523. #endif
  2524. _glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC)
  2525. get_extension_func("glGetProgramBinary");
  2526. _glProgramBinary = (PFNGLPROGRAMBINARYPROC)
  2527. get_extension_func("glProgramBinary");
  2528. _glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)
  2529. get_extension_func("glProgramParameteri");
  2530. GLint num_binary_formats = 0;
  2531. if (_glGetProgramBinary != NULL &&
  2532. _glProgramBinary != NULL &&
  2533. _glProgramParameteri != NULL) {
  2534. glGetIntegerv(GL_NUM_PROGRAM_BINARY_FORMATS, &num_binary_formats);
  2535. }
  2536. if (num_binary_formats > 0) {
  2537. _supports_get_program_binary = true;
  2538. GLenum *binary_formats = (GLenum *)alloca(sizeof(GLenum) * num_binary_formats);
  2539. glGetIntegerv(GL_PROGRAM_BINARY_FORMATS, (GLint *)binary_formats);
  2540. for (int i = 0; i < num_binary_formats; ++i) {
  2541. _program_binary_formats.insert(binary_formats[i]);
  2542. }
  2543. }
  2544. }
  2545. #endif // !OPENGLES_1
  2546. report_my_gl_errors();
  2547. if (core_profile) {
  2548. // TODO: better detection mechanism?
  2549. _supports_stencil = support_stencil;
  2550. }
  2551. #ifdef SUPPORT_FIXED_FUNCTION
  2552. else if (support_stencil) {
  2553. GLint num_stencil_bits;
  2554. glGetIntegerv(GL_STENCIL_BITS, &num_stencil_bits);
  2555. _supports_stencil = (num_stencil_bits != 0);
  2556. }
  2557. #endif
  2558. #ifdef OPENGLES_1
  2559. _supports_stencil_wrap = has_extension("GL_OES_stencil_wrap");
  2560. #elif defined(OPENGLES)
  2561. _supports_stencil_wrap = true;
  2562. #else
  2563. _supports_stencil_wrap = is_at_least_gl_version(1, 4) ||
  2564. has_extension("GL_EXT_stencil_wrap");
  2565. #endif
  2566. _supports_two_sided_stencil = false;
  2567. #ifndef OPENGLES
  2568. //TODO: support the two-sided stencil functions that ended up in core.
  2569. if (has_extension("GL_EXT_stencil_two_side")) {
  2570. _glActiveStencilFaceEXT = (PFNGLACTIVESTENCILFACEEXTPROC)
  2571. get_extension_func("glActiveStencilFaceEXT");
  2572. _supports_two_sided_stencil = true;
  2573. } else {
  2574. _glActiveStencilFaceEXT = 0;
  2575. }
  2576. #endif
  2577. // Ensure the initial state is what we say it should be (in some cases, we
  2578. // don't want the GL default settings; in others, we have to force the point
  2579. // with some drivers that aren't strictly compliant w.r.t. initial
  2580. // settings).
  2581. glFrontFace(GL_CCW);
  2582. #ifndef OPENGLES_2
  2583. glDisable(GL_LINE_SMOOTH);
  2584. #endif
  2585. #ifdef SUPPORT_FIXED_FUNCTION
  2586. if (!core_profile) {
  2587. glDisable(GL_POINT_SMOOTH);
  2588. }
  2589. #endif
  2590. #ifndef OPENGLES
  2591. glDisable(GL_POLYGON_SMOOTH);
  2592. #endif // OPENGLES
  2593. #ifndef OPENGLES_2
  2594. if (_supports_multisample) {
  2595. glDisable(GL_MULTISAMPLE);
  2596. }
  2597. #endif
  2598. // Set up all the enableddisabled flags to GL's known initial values:
  2599. // everything off.
  2600. _multisample_mode = 0;
  2601. _line_smooth_enabled = false;
  2602. _point_smooth_enabled = false;
  2603. _polygon_smooth_enabled = false;
  2604. _stencil_test_enabled = false;
  2605. _blend_enabled = false;
  2606. _depth_test_enabled = false;
  2607. _fog_enabled = false;
  2608. _alpha_test_enabled = false;
  2609. _polygon_offset_enabled = false;
  2610. _flat_shade_model = false;
  2611. _decal_level = 0;
  2612. _active_color_write_mask = ColorWriteAttrib::C_all;
  2613. _tex_gen_point_sprite = false;
  2614. #ifndef OPENGLES_1
  2615. _enabled_vertex_attrib_arrays.clear();
  2616. memset(_vertex_attrib_divisors, 0, sizeof(GLint) * 32);
  2617. #endif
  2618. // Dither is on by default in GL; let's turn it off
  2619. glDisable(GL_DITHER);
  2620. _dithering_enabled = false;
  2621. #ifndef OPENGLES_1
  2622. _current_shader = (Shader *)NULL;
  2623. _current_shader_context = (ShaderContext *)NULL;
  2624. _vertex_array_shader = (Shader *)NULL;
  2625. _vertex_array_shader_context = (ShaderContext *)NULL;
  2626. _texture_binding_shader = (Shader *)NULL;
  2627. _texture_binding_shader_context = (ShaderContext *)NULL;
  2628. #endif
  2629. // Count the max number of lights
  2630. _max_lights = 0;
  2631. #ifdef SUPPORT_FIXED_FUNCTION
  2632. if (!core_profile) {
  2633. GLint max_lights = 0;
  2634. glGetIntegerv(GL_MAX_LIGHTS, &max_lights);
  2635. _max_lights = max_lights;
  2636. if (GLCAT.is_debug()) {
  2637. GLCAT.debug()
  2638. << "max lights = " << _max_lights << "\n";
  2639. }
  2640. }
  2641. #endif
  2642. // Count the max number of clipping planes
  2643. _max_clip_planes = 0;
  2644. #ifdef SUPPORT_FIXED_FUNCTION
  2645. if (!core_profile) {
  2646. GLint max_clip_planes = 0;
  2647. glGetIntegerv(GL_MAX_CLIP_PLANES, &max_clip_planes);
  2648. _max_clip_planes = max_clip_planes;
  2649. if (GLCAT.is_debug()) {
  2650. GLCAT.debug()
  2651. << "max clip planes = " << _max_clip_planes << "\n";
  2652. }
  2653. }
  2654. #endif
  2655. _max_texture_stages = 1;
  2656. #ifdef SUPPORT_FIXED_FUNCTION
  2657. if (supports_multitexture && !core_profile) {
  2658. GLint max_texture_stages = 0;
  2659. glGetIntegerv(GL_MAX_TEXTURE_UNITS, &max_texture_stages);
  2660. _max_texture_stages = max_texture_stages;
  2661. if (GLCAT.is_debug()) {
  2662. GLCAT.debug()
  2663. << "max texture stages = " << _max_texture_stages << "\n";
  2664. }
  2665. }
  2666. #endif
  2667. _current_vbuffer_index = 0;
  2668. _current_ibuffer_index = 0;
  2669. _current_vao_index = 0;
  2670. _current_fbo = 0;
  2671. _auto_antialias_mode = false;
  2672. _render_mode = RenderModeAttrib::M_filled;
  2673. _point_size = 1.0f;
  2674. _point_perspective = false;
  2675. #ifndef OPENGLES
  2676. _current_vertex_buffers.clear();
  2677. _current_vertex_format.clear();
  2678. memset(_vertex_attrib_columns, 0, sizeof(const GeomVertexColumn *) * 32);
  2679. #endif
  2680. report_my_gl_errors();
  2681. #ifdef SUPPORT_FIXED_FUNCTION
  2682. if (!core_profile) {
  2683. if (gl_cheap_textures) {
  2684. GLCAT.info()
  2685. << "Setting glHint() for fastest textures.\n";
  2686. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
  2687. }
  2688. // Use per-vertex fog if per-pixel fog requires SW renderer
  2689. glHint(GL_FOG_HINT, GL_DONT_CARE);
  2690. }
  2691. #endif
  2692. #ifdef SUPPORT_FIXED_FUNCTION
  2693. if (!core_profile) {
  2694. GLint num_red_bits = 0;
  2695. glGetIntegerv(GL_RED_BITS, &num_red_bits);
  2696. if (num_red_bits < 8) {
  2697. glEnable(GL_DITHER);
  2698. _dithering_enabled = true;
  2699. if (GLCAT.is_debug()) {
  2700. GLCAT.debug()
  2701. << "frame buffer depth = " << num_red_bits
  2702. << " bits/channel, enabling dithering\n";
  2703. }
  2704. }
  2705. }
  2706. #endif
  2707. _error_count = 0;
  2708. report_my_gl_errors();
  2709. #ifndef OPENGLES_1
  2710. if (GLCAT.is_debug()) {
  2711. if (_supports_get_program_binary) {
  2712. GLCAT.debug()
  2713. << "Supported shader binary formats:\n";
  2714. GLCAT.debug() << " ";
  2715. pset<GLenum>::const_iterator it;
  2716. for (it = _program_binary_formats.begin();
  2717. it != _program_binary_formats.end(); ++it) {
  2718. char number[16];
  2719. sprintf(number, "0x%04X", *it);
  2720. GLCAT.debug(false) << " " << number << "";
  2721. }
  2722. GLCAT.debug(false) << "\n";
  2723. } else {
  2724. GLCAT.debug() << "No shader binary formats supported.\n";
  2725. }
  2726. }
  2727. #endif
  2728. #ifndef OPENGLES
  2729. if (_gl_shadlang_ver_major >= 4 || has_extension("GL_NV_gpu_program5")) {
  2730. // gp5fp - OpenGL fragment profile for GeForce 400 Series and up
  2731. _shader_model = SM_50;
  2732. } else if (_gl_shadlang_ver_major >= 3 ||
  2733. has_extension("GL_NV_gpu_program4")) {
  2734. // gp4fp - OpenGL fragment profile for G8x (GeForce 8xxx and up)
  2735. _shader_model = SM_40;
  2736. } else if (has_extension("GL_NV_fragment_program2")) {
  2737. // fp40 - OpenGL fragment profile for NV4x (GeForce 6xxx and 7xxx Series,
  2738. // NV4x-based Quadro FX, etc.)
  2739. _shader_model = SM_30;
  2740. } else if (has_extension("GL_NV_fragment_program")) {
  2741. // fp30 - OpenGL fragment profile for NV3x (GeForce FX, Quadro FX, etc.)
  2742. _shader_model = SM_2X;
  2743. } else if (_gl_shadlang_ver_major >= 1 ||
  2744. has_extension("GL_ARB_fragment_program")) {
  2745. // This OpenGL profile corresponds to the per-fragment functionality
  2746. // introduced by GeForce FX and other DirectX 9 GPUs.
  2747. _shader_model = SM_20;
  2748. } else if (has_extension("GL_NV_texture_shader2")) {
  2749. // fp20 - OpenGL fragment profile for NV2x (GeForce3, GeForce4 Ti, Quadro
  2750. // DCC, etc.)
  2751. _shader_model = SM_11;
  2752. } else {
  2753. // No shader support
  2754. _shader_model = SM_00;
  2755. }
  2756. // DisplayInformation may have better shader model detection
  2757. {
  2758. GraphicsPipe *pipe;
  2759. DisplayInformation *display_information;
  2760. pipe = this->get_pipe();
  2761. if (pipe) {
  2762. display_information = pipe->get_display_information ();
  2763. if (display_information) {
  2764. if (display_information->get_shader_model() > _shader_model) {
  2765. _shader_model = display_information->get_shader_model();
  2766. }
  2767. }
  2768. }
  2769. }
  2770. _auto_detect_shader_model = _shader_model;
  2771. if (GLCAT.is_debug()) {
  2772. #ifdef HAVE_CG
  2773. #if CG_VERSION_NUM >= 2200
  2774. GLCAT.debug() << "Supported Cg profiles:\n";
  2775. int num_profiles = cgGetNumSupportedProfiles();
  2776. for (int i = 0; i < num_profiles; ++i) {
  2777. CGprofile profile = cgGetSupportedProfile(i);
  2778. if (cgGLIsProfileSupported(profile)) {
  2779. GLCAT.debug() << " " << cgGetProfileString(profile) << "\n";
  2780. }
  2781. }
  2782. #endif // CG_VERSION_NUM >= 2200
  2783. #if CG_VERSION_NUM >= 3100
  2784. GLCAT.debug() << "Cg GLSL version = "
  2785. << cgGLGetGLSLVersionString(cgGLDetectGLSLVersion()) << "\n";
  2786. #endif
  2787. GLCAT.debug()
  2788. << "Cg latest vertex profile = "
  2789. << cgGetProfileString(cgGLGetLatestProfile(CG_GL_VERTEX)) << "\n";
  2790. GLCAT.debug()
  2791. << "Cg latest fragment profile = "
  2792. << cgGetProfileString(cgGLGetLatestProfile(CG_GL_FRAGMENT)) << "\n";
  2793. #if CG_VERSION_NUM >= 2000
  2794. GLCAT.debug()
  2795. << "Cg latest geometry profile = "
  2796. << cgGetProfileString(cgGLGetLatestProfile(CG_GL_GEOMETRY)) << "\n";
  2797. #endif
  2798. GLCAT.debug() << "basic-shaders-only " << basic_shaders_only << "\n";
  2799. GLCAT.debug()
  2800. << "Cg active vertex profile = "
  2801. << cgGetProfileString((CGprofile)_shader_caps._active_vprofile) << "\n";
  2802. GLCAT.debug()
  2803. << "Cg active fragment profile = "
  2804. << cgGetProfileString((CGprofile)_shader_caps._active_fprofile) << "\n";
  2805. GLCAT.debug()
  2806. << "Cg active geometry profile = "
  2807. << cgGetProfileString((CGprofile)_shader_caps._active_gprofile) << "\n";
  2808. #endif // HAVE_CG
  2809. GLCAT.debug() << "shader model = " << _shader_model << "\n";
  2810. }
  2811. #endif // !OPENGLES
  2812. // OpenGL core profile requires a VAO to be bound. It's a bit silly,
  2813. // because we can just bind a VAO and then forget about it.
  2814. #if !defined(OPENGLES)
  2815. if (core_profile) {
  2816. if (_supports_vao) {
  2817. _glGenVertexArrays(1, &_current_vao_index);
  2818. _glBindVertexArray(_current_vao_index);
  2819. } else {
  2820. GLCAT.error()
  2821. << "Core profile enabled, but vertex array objects not supported!\n";
  2822. }
  2823. }
  2824. #endif
  2825. // Now that the GSG has been initialized, make it available for
  2826. // optimizations.
  2827. add_gsg(this);
  2828. }
  2829. /**
  2830. * Force the graphics card to finish drawing before returning. !!!!!HACK
  2831. * WARNING!!!! glfinish does not actually wait for the graphics card to finish
  2832. * drawing only for draw calls to finish. Thus flip may not happene
  2833. * immediately. Instead we read a single pixel from the framebuffer. This
  2834. * forces the graphics card to finish drawing the frame before returning.
  2835. */
  2836. void CLP(GraphicsStateGuardian)::
  2837. finish() {
  2838. // Rather than call glfinish which returns immediately if draw commands have
  2839. // been submitted, we will read a single pixel from the frame. That will
  2840. // force the graphics card to finish drawing before it is called
  2841. char data[4];
  2842. glReadPixels(0,0,1,1,GL_RGBA,GL_UNSIGNED_BYTE,&data);
  2843. // glFinish();
  2844. }
  2845. /**
  2846. * Clears the framebuffer within the current DisplayRegion, according to the
  2847. * flags indicated by the given DrawableRegion object.
  2848. *
  2849. * This does not set the DisplayRegion first. You should call
  2850. * prepare_display_region() to specify the region you wish the clear operation
  2851. * to apply to.
  2852. */
  2853. void CLP(GraphicsStateGuardian)::
  2854. clear(DrawableRegion *clearable) {
  2855. PStatGPUTimer timer(this, _clear_pcollector);
  2856. report_my_gl_errors();
  2857. if (!clearable->is_any_clear_active()) {
  2858. return;
  2859. }
  2860. // XXX rdb: Is this line really necessary? Could we perhaps just reset the
  2861. // color write mask and other relevant attributes?
  2862. set_state_and_transform(RenderState::make_empty(), _internal_transform);
  2863. int mask = 0;
  2864. #ifndef OPENGLES_1
  2865. if (_current_fbo != 0 && _glClearBufferfv != NULL) {
  2866. // We can use glClearBuffer to clear all the color attachments, which
  2867. // protects us from the overhead of having to call set_draw_buffer for
  2868. // every single attachment.
  2869. int index = 0;
  2870. if (_current_properties->get_color_bits() > 0) {
  2871. if (_current_properties->is_stereo()) {
  2872. // Clear both left and right attachments.
  2873. if (clearable->get_clear_active(GraphicsOutput::RTP_color)) {
  2874. LColorf v = LCAST(float, clearable->get_clear_value(GraphicsOutput::RTP_color));
  2875. _glClearBufferfv(GL_COLOR, index, v.get_data());
  2876. _glClearBufferfv(GL_COLOR, index + 1, v.get_data());
  2877. }
  2878. index += 2;
  2879. } else {
  2880. if (clearable->get_clear_active(GraphicsOutput::RTP_color)) {
  2881. LColorf v = LCAST(float, clearable->get_clear_value(GraphicsOutput::RTP_color));
  2882. _glClearBufferfv(GL_COLOR, index, v.get_data());
  2883. }
  2884. ++index;
  2885. }
  2886. }
  2887. for (int i = 0; i < _current_properties->get_aux_rgba(); ++i) {
  2888. int layerid = GraphicsOutput::RTP_aux_rgba_0 + i;
  2889. if (clearable->get_clear_active(layerid)) {
  2890. LColorf v = LCAST(float, clearable->get_clear_value(layerid));
  2891. _glClearBufferfv(GL_COLOR, index, v.get_data());
  2892. }
  2893. ++index;
  2894. }
  2895. for (int i = 0; i < _current_properties->get_aux_hrgba(); ++i) {
  2896. int layerid = GraphicsOutput::RTP_aux_hrgba_0 + i;
  2897. if (clearable->get_clear_active(layerid)) {
  2898. LColorf v = LCAST(float, clearable->get_clear_value(layerid));
  2899. _glClearBufferfv(GL_COLOR, index, v.get_data());
  2900. }
  2901. ++index;
  2902. }
  2903. for (int i = 0; i < _current_properties->get_aux_float(); ++i) {
  2904. int layerid = GraphicsOutput::RTP_aux_float_0 + i;
  2905. if (clearable->get_clear_active(layerid)) {
  2906. LColorf v = LCAST(float, clearable->get_clear_value(layerid));
  2907. _glClearBufferfv(GL_COLOR, index, v.get_data());
  2908. }
  2909. ++index;
  2910. }
  2911. } else
  2912. #endif
  2913. {
  2914. if (_current_properties->get_aux_mask() != 0) {
  2915. for (int i = 0; i < _current_properties->get_aux_rgba(); ++i) {
  2916. int layerid = GraphicsOutput::RTP_aux_rgba_0 + i;
  2917. int layerbit = RenderBuffer::T_aux_rgba_0 << i;
  2918. if (clearable->get_clear_active(layerid)) {
  2919. LColor v = clearable->get_clear_value(layerid);
  2920. glClearColor(v[0], v[1], v[2], v[3]);
  2921. set_draw_buffer(layerbit);
  2922. glClear(GL_COLOR_BUFFER_BIT);
  2923. }
  2924. }
  2925. for (int i = 0; i < _current_properties->get_aux_hrgba(); ++i) {
  2926. int layerid = GraphicsOutput::RTP_aux_hrgba_0 + i;
  2927. int layerbit = RenderBuffer::T_aux_hrgba_0 << i;
  2928. if (clearable->get_clear_active(layerid)) {
  2929. LColor v = clearable->get_clear_value(layerid);
  2930. glClearColor(v[0], v[1], v[2], v[3]);
  2931. set_draw_buffer(layerbit);
  2932. glClear(GL_COLOR_BUFFER_BIT);
  2933. }
  2934. }
  2935. for (int i = 0; i < _current_properties->get_aux_float(); ++i) {
  2936. int layerid = GraphicsOutput::RTP_aux_float_0 + i;
  2937. int layerbit = RenderBuffer::T_aux_float_0 << i;
  2938. if (clearable->get_clear_active(layerid)) {
  2939. LColor v = clearable->get_clear_value(layerid);
  2940. glClearColor(v[0], v[1], v[2], v[3]);
  2941. set_draw_buffer(layerbit);
  2942. glClear(GL_COLOR_BUFFER_BIT);
  2943. }
  2944. }
  2945. // In the past, it was possible to set the draw buffer once in
  2946. // prepare_display_region and then forget about it. Now, with aux
  2947. // layers, it is necessary to occasionally change the draw buffer. In
  2948. // time, I think there will need to be a draw buffer attrib. Until
  2949. // then, this little hack to put things back the way they were after
  2950. // prepare_display_region will do.
  2951. set_draw_buffer(_draw_buffer_type);
  2952. }
  2953. if (_current_properties->get_color_bits() > 0) {
  2954. if (clearable->get_clear_color_active()) {
  2955. LColor v = clearable->get_clear_color();
  2956. glClearColor(v[0], v[1], v[2], v[3]);
  2957. clear_color_write_mask();
  2958. _state_mask.clear_bit(ColorWriteAttrib::get_class_slot());
  2959. mask |= GL_COLOR_BUFFER_BIT;
  2960. }
  2961. }
  2962. }
  2963. if (clearable->get_clear_depth_active()) {
  2964. #ifdef OPENGLES
  2965. glClearDepthf(clearable->get_clear_depth());
  2966. #else
  2967. glClearDepth(clearable->get_clear_depth());
  2968. #endif // OPENGLES
  2969. #ifdef GSG_VERBOSE
  2970. GLCAT.spam()
  2971. << "glDepthMask(GL_TRUE)" << endl;
  2972. #endif
  2973. glDepthMask(GL_TRUE);
  2974. _state_mask.clear_bit(DepthWriteAttrib::get_class_slot());
  2975. mask |= GL_DEPTH_BUFFER_BIT;
  2976. }
  2977. if (_supports_stencil && clearable->get_clear_stencil_active()) {
  2978. glStencilMask(~0);
  2979. glClearStencil(clearable->get_clear_stencil());
  2980. mask |= GL_STENCIL_BUFFER_BIT;
  2981. }
  2982. if (mask != 0) {
  2983. glClear(mask);
  2984. if (GLCAT.is_spam()) {
  2985. string clear_flags;
  2986. if (mask & GL_COLOR_BUFFER_BIT) {
  2987. clear_flags += " | GL_COLOR_BUFFER_BIT";
  2988. }
  2989. if (mask & GL_DEPTH_BUFFER_BIT) {
  2990. clear_flags += " | GL_DEPTH_BUFFER_BIT";
  2991. }
  2992. if (mask & GL_STENCIL_BUFFER_BIT) {
  2993. clear_flags += " | GL_STENCIL_BUFFER_BIT";
  2994. }
  2995. #ifndef OPENGLES
  2996. if (mask & GL_ACCUM_BUFFER_BIT) {
  2997. clear_flags += " | GL_ACCUM_BUFFER_BIT";
  2998. }
  2999. #endif
  3000. GLCAT.spam() << "glClear(" << (clear_flags.c_str() + 3) << ")\n";
  3001. }
  3002. }
  3003. report_my_gl_errors();
  3004. }
  3005. /**
  3006. * Prepare a display region for rendering (set up scissor region and viewport)
  3007. */
  3008. void CLP(GraphicsStateGuardian)::
  3009. prepare_display_region(DisplayRegionPipelineReader *dr) {
  3010. nassertv(dr != (DisplayRegionPipelineReader *)NULL);
  3011. GraphicsStateGuardian::prepare_display_region(dr);
  3012. int l, b, w, h;
  3013. dr->get_region_pixels(l, b, w, h);
  3014. _viewport_x = l;
  3015. _viewport_y = b;
  3016. _viewport_width = w;
  3017. _viewport_height = h;
  3018. GLint x = GLint(l);
  3019. GLint y = GLint(b);
  3020. GLsizei width = GLsizei(w);
  3021. GLsizei height = GLsizei(h);
  3022. _draw_buffer_type = dr->get_object()->get_draw_buffer_type() & _current_properties->get_buffer_mask() & _stereo_buffer_mask;
  3023. _draw_buffer_type |= _current_properties->get_aux_mask();
  3024. set_draw_buffer(_draw_buffer_type);
  3025. int count = dr->get_num_regions();
  3026. if (dr->get_scissor_enabled()) {
  3027. if (GLCAT.is_spam()) {
  3028. GLCAT.spam()
  3029. << "glEnable(GL_SCISSOR_TEST)\n";
  3030. }
  3031. glEnable(GL_SCISSOR_TEST);
  3032. _scissor_enabled = true;
  3033. _scissor_array.resize(count);
  3034. } else {
  3035. if (GLCAT.is_spam()) {
  3036. GLCAT.spam()
  3037. << "glDisable(GL_SCISSOR_TEST)\n";
  3038. }
  3039. glDisable(GL_SCISSOR_TEST);
  3040. _scissor_enabled = false;
  3041. _scissor_array.clear();
  3042. }
  3043. _scissor_attrib_active = false;
  3044. #ifndef OPENGLES
  3045. if (_supports_viewport_arrays) {
  3046. GLfloat *viewports = (GLfloat *)alloca(sizeof(GLfloat) * 4 * count);
  3047. // We store the scissor regions in a vector since we may need to switch
  3048. // back to it in do_issue_scissor.
  3049. for (int i = 0; i < count; ++i) {
  3050. LVecBase4i sr;
  3051. dr->get_region_pixels(i, sr[0], sr[1], sr[2], sr[3]);
  3052. GLfloat *vr = viewports + i * 4;
  3053. vr[0] = (GLfloat) sr[0];
  3054. vr[1] = (GLfloat) sr[1];
  3055. vr[2] = (GLfloat) sr[2];
  3056. vr[3] = (GLfloat) sr[3];
  3057. if (_scissor_enabled) {
  3058. _scissor_array[i] = sr;
  3059. }
  3060. }
  3061. _glViewportArrayv(0, count, viewports);
  3062. if (_scissor_enabled) {
  3063. _glScissorArrayv(0, count, _scissor_array[0].get_data());
  3064. }
  3065. if (GLCAT.is_spam()) {
  3066. GLCAT.spam()
  3067. << "glViewportArrayv(0, " << count << ",";
  3068. for (int i = 0; i < count; ++i) {
  3069. GLfloat *vr = viewports + i * 4;
  3070. GLCAT.spam(false) << " [" << vr[0] << " " << vr[1] << " " << vr[2] << " " << vr[3] << "]";
  3071. }
  3072. GLCAT.spam(false) << ")\n";
  3073. if (_scissor_enabled) {
  3074. GLCAT.spam()
  3075. << "glScissorArrayv(0, " << count << ",";
  3076. for (int i = 0; i < count; ++i) {
  3077. const LVecBase4i &sr = _scissor_array[i];
  3078. GLCAT.spam(false) << " [" << sr << "]";
  3079. }
  3080. GLCAT.spam(false) << ")\n";
  3081. }
  3082. }
  3083. } else
  3084. #endif // OPENGLES
  3085. {
  3086. glViewport(x, y, width, height);
  3087. if (_scissor_enabled) {
  3088. glScissor(x, y, width, height);
  3089. _scissor_array.resize(1);
  3090. _scissor_array[0].set(x, y, width, height);
  3091. }
  3092. if (GLCAT.is_spam()) {
  3093. GLCAT.spam()
  3094. << "glViewport(" << x << ", " << y << ", " << width << ", " << height << ")\n";
  3095. if (dr->get_scissor_enabled()) {
  3096. GLCAT.spam()
  3097. << "glScissor(" << x << ", " << y << ", " << width << ", " << height << ")\n";
  3098. }
  3099. }
  3100. }
  3101. report_my_gl_errors();
  3102. }
  3103. /**
  3104. * Resets any non-standard graphics state that might give a callback apoplexy.
  3105. * Some drivers require that the graphics state be restored to neutral before
  3106. * performing certain operations. In OpenGL, for instance, this closes any
  3107. * open vertex buffers.
  3108. */
  3109. void CLP(GraphicsStateGuardian)::
  3110. clear_before_callback() {
  3111. #ifdef SUPPORT_FIXED_FUNCTION
  3112. disable_standard_vertex_arrays();
  3113. #endif
  3114. #ifndef OPENGLES_1
  3115. if (_vertex_array_shader_context != 0) {
  3116. _vertex_array_shader_context->disable_shader_vertex_arrays();
  3117. _vertex_array_shader = (Shader *)NULL;
  3118. _vertex_array_shader_context = (ShaderContext *)NULL;
  3119. }
  3120. #endif
  3121. unbind_buffers();
  3122. // Some callbacks may quite reasonably assume that the active texture stage
  3123. // is still set to stage 0. CEGUI, in particular, makes this assumption.
  3124. set_active_texture_stage(0);
  3125. #ifdef SUPPORT_FIXED_FUNCTION
  3126. _glClientActiveTexture(GL_TEXTURE0);
  3127. #endif
  3128. // Clear the bound sampler object, so that we do not inadvertently override
  3129. // the callback's desired sampler settings.
  3130. #ifndef OPENGLES_1
  3131. if (_supports_sampler_objects) {
  3132. _glBindSampler(0, 0);
  3133. if (GLCAT.is_spam()) {
  3134. GLCAT.spam()
  3135. << "glBindSampler(0, 0)\n";
  3136. }
  3137. }
  3138. #endif
  3139. }
  3140. /**
  3141. * Given a lens, calculates the appropriate projection matrix for use with
  3142. * this gsg. Note that the projection matrix depends a lot upon the
  3143. * coordinate system of the rendering API.
  3144. *
  3145. * The return value is a TransformState if the lens is acceptable, NULL if it
  3146. * is not.
  3147. */
  3148. CPT(TransformState) CLP(GraphicsStateGuardian)::
  3149. calc_projection_mat(const Lens *lens) {
  3150. if (lens == (Lens *)NULL) {
  3151. return NULL;
  3152. }
  3153. if (!lens->is_linear()) {
  3154. return NULL;
  3155. }
  3156. // The projection matrix must always be right-handed Y-up, even if our
  3157. // coordinate system of choice is otherwise, because certain GL calls
  3158. // (specifically glTexGen(GL_SPHERE_MAP)) assume this kind of a coordinate
  3159. // system. Sigh. In order to implement a Z-up (or other arbitrary)
  3160. // coordinate system, we'll use a Y-up projection matrix, and store the
  3161. // conversion to our coordinate system of choice in the modelview matrix.
  3162. LMatrix4 result =
  3163. LMatrix4::convert_mat(_internal_coordinate_system,
  3164. lens->get_coordinate_system()) *
  3165. lens->get_projection_mat(_current_stereo_channel);
  3166. if (_scene_setup->get_inverted()) {
  3167. // If the scene is supposed to be inverted, then invert the projection
  3168. // matrix.
  3169. result *= LMatrix4::scale_mat(1.0f, -1.0f, 1.0f);
  3170. }
  3171. return TransformState::make_mat(result);
  3172. }
  3173. /**
  3174. * Makes the current lens (whichever lens was most recently specified with
  3175. * set_scene()) active, so that it will transform future rendered geometry.
  3176. * Normally this is only called from the draw process, and usually it is
  3177. * called by set_scene().
  3178. *
  3179. * The return value is true if the lens is acceptable, false if it is not.
  3180. */
  3181. bool CLP(GraphicsStateGuardian)::
  3182. prepare_lens() {
  3183. #ifdef SUPPORT_FIXED_FUNCTION
  3184. if (GLCAT.is_spam()) {
  3185. GLCAT.spam()
  3186. << "glMatrixMode(GL_PROJECTION): " << _projection_mat->get_mat() << endl;
  3187. }
  3188. glMatrixMode(GL_PROJECTION);
  3189. call_glLoadMatrix(_projection_mat->get_mat());
  3190. report_my_gl_errors();
  3191. do_point_size();
  3192. #endif
  3193. #ifndef OPENGLES_1
  3194. if (_current_shader_context) {
  3195. _current_shader_context->issue_parameters(Shader::SSD_transform);
  3196. }
  3197. #endif
  3198. return true;
  3199. }
  3200. /**
  3201. * Called before each frame is rendered, to allow the GSG a chance to do any
  3202. * internal cleanup before beginning the frame.
  3203. *
  3204. * The return value is true if successful (in which case the frame will be
  3205. * drawn and end_frame() will be called later), or false if unsuccessful (in
  3206. * which case nothing will be drawn and end_frame() will not be called).
  3207. */
  3208. bool CLP(GraphicsStateGuardian)::
  3209. begin_frame(Thread *current_thread) {
  3210. if (!GraphicsStateGuardian::begin_frame(current_thread)) {
  3211. return false;
  3212. }
  3213. _renderbuffer_residency.begin_frame(current_thread);
  3214. report_my_gl_errors();
  3215. #ifdef DO_PSTATS
  3216. _vertices_display_list_pcollector.clear_level();
  3217. _vertices_immediate_pcollector.clear_level();
  3218. _primitive_batches_display_list_pcollector.clear_level();
  3219. #endif
  3220. #ifndef NDEBUG
  3221. _show_texture_usage = false;
  3222. if (gl_show_texture_usage) {
  3223. // When this is true, then every other second, we show the usage textures
  3224. // instead of the real textures.
  3225. double now = ClockObject::get_global_clock()->get_frame_time();
  3226. int this_second = (int)floor(now);
  3227. if (this_second & 1) {
  3228. _show_texture_usage = true;
  3229. _show_texture_usage_index = this_second >> 1;
  3230. int max_size = gl_show_texture_usage_max_size;
  3231. if (max_size != _show_texture_usage_max_size) {
  3232. // Remove the cache of usage textures; we've changed the max size.
  3233. UsageTextures::iterator ui;
  3234. for (ui = _usage_textures.begin();
  3235. ui != _usage_textures.end();
  3236. ++ui) {
  3237. GLuint index = (*ui).second;
  3238. glDeleteTextures(1, &index);
  3239. }
  3240. _usage_textures.clear();
  3241. _show_texture_usage_max_size = max_size;
  3242. }
  3243. }
  3244. }
  3245. #endif // NDEBUG
  3246. #ifdef DO_PSTATS
  3247. /*if (_supports_timer_query) {
  3248. // Measure the difference between the OpenGL clock and the PStats clock.
  3249. GLint64 time_ns;
  3250. _glGetInteger64v(GL_TIMESTAMP, &time_ns);
  3251. _timer_delta = time_ns * -0.000000001;
  3252. _timer_delta += PStatClient::get_global_pstats()->get_real_time();
  3253. }*/
  3254. #endif
  3255. #ifndef OPENGLES
  3256. if (_current_properties->get_srgb_color()) {
  3257. glEnable(GL_FRAMEBUFFER_SRGB);
  3258. }
  3259. #endif
  3260. report_my_gl_errors();
  3261. return true;
  3262. }
  3263. /**
  3264. * Called between begin_frame() and end_frame() to mark the beginning of
  3265. * drawing commands for a "scene" (usually a particular DisplayRegion) within
  3266. * a frame. All 3-D drawing commands, except the clear operation, must be
  3267. * enclosed within begin_scene() .. end_scene().
  3268. *
  3269. * The return value is true if successful (in which case the scene will be
  3270. * drawn and end_scene() will be called later), or false if unsuccessful (in
  3271. * which case nothing will be drawn and end_scene() will not be called).
  3272. */
  3273. bool CLP(GraphicsStateGuardian)::
  3274. begin_scene() {
  3275. return GraphicsStateGuardian::begin_scene();
  3276. }
  3277. /**
  3278. * Called between begin_frame() and end_frame() to mark the end of drawing
  3279. * commands for a "scene" (usually a particular DisplayRegion) within a frame.
  3280. * All 3-D drawing commands, except the clear operation, must be enclosed
  3281. * within begin_scene() .. end_scene().
  3282. */
  3283. void CLP(GraphicsStateGuardian)::
  3284. end_scene() {
  3285. GraphicsStateGuardian::end_scene();
  3286. _dlights.clear();
  3287. report_my_gl_errors();
  3288. }
  3289. /**
  3290. * Called after each frame is rendered, to allow the GSG a chance to do any
  3291. * internal cleanup after rendering the frame, and before the window flips.
  3292. */
  3293. void CLP(GraphicsStateGuardian)::
  3294. end_frame(Thread *current_thread) {
  3295. report_my_gl_errors();
  3296. #ifndef OPENGLES
  3297. if (_current_properties->get_srgb_color()) {
  3298. glDisable(GL_FRAMEBUFFER_SRGB);
  3299. }
  3300. #endif
  3301. #ifdef DO_PSTATS
  3302. // Check for textures, etc., that are no longer resident. These calls might
  3303. // be measurably expensive, and they don't have any benefit unless we are
  3304. // actually viewing PStats, so don't do them unless we're connected. That
  3305. // will just mean that we'll count everything as resident until the user
  3306. // connects PStats, at which point it will then correct the assessment. No
  3307. // harm done.
  3308. if (PStatClient::is_connected()) {
  3309. check_nonresident_texture(_prepared_objects->_texture_residency.get_inactive_resident());
  3310. check_nonresident_texture(_prepared_objects->_texture_residency.get_active_resident());
  3311. // OpenGL provides no methods for querying whether a buffer object (vertex
  3312. // buffer) is resident. In fact, the API appears geared towards the
  3313. // assumption that such buffers are always resident. OK.
  3314. }
  3315. #endif
  3316. #ifndef OPENGLES_1
  3317. // This breaks shaders across multiple regions.
  3318. if (_vertex_array_shader_context != 0) {
  3319. _vertex_array_shader_context->disable_shader_vertex_arrays();
  3320. _vertex_array_shader = (Shader *)NULL;
  3321. _vertex_array_shader_context = (ShaderContext *)NULL;
  3322. }
  3323. if (_texture_binding_shader_context != 0) {
  3324. _texture_binding_shader_context->disable_shader_texture_bindings();
  3325. _texture_binding_shader = (Shader *)NULL;
  3326. _texture_binding_shader_context = (ShaderContext *)NULL;
  3327. }
  3328. if (_current_shader_context != 0) {
  3329. _current_shader_context->unbind();
  3330. _current_shader = (Shader *)NULL;
  3331. _current_shader_context = (ShaderContext *)NULL;
  3332. }
  3333. #endif
  3334. // Respecify the active texture next frame, for good measure.
  3335. _active_texture_stage = -1;
  3336. // Calling glFlush() at the end of the frame is particularly necessary if
  3337. // this is a single-buffered visual, so that the frame will be finished
  3338. // drawing before we return to the application. It's not clear what effect
  3339. // this has on our total frame time. if (_force_flush ||
  3340. // _current_properties->is_single_buffered()) { gl_flush(); }
  3341. maybe_gl_finish();
  3342. GraphicsStateGuardian::end_frame(current_thread);
  3343. _renderbuffer_residency.end_frame(current_thread);
  3344. // Flush any PCollectors specific to this kind of GSG.
  3345. _primitive_batches_display_list_pcollector.flush_level();
  3346. _vertices_display_list_pcollector.flush_level();
  3347. _vertices_immediate_pcollector.flush_level();
  3348. // Now is a good time to delete any pending display lists.
  3349. #ifndef OPENGLES
  3350. #ifdef SUPPORT_FIXED_FUNCTION
  3351. if (display_lists) {
  3352. LightMutexHolder holder(_lock);
  3353. if (!_deleted_display_lists.empty()) {
  3354. DeletedNames::iterator ddli;
  3355. for (ddli = _deleted_display_lists.begin();
  3356. ddli != _deleted_display_lists.end();
  3357. ++ddli) {
  3358. if (GLCAT.is_debug()) {
  3359. GLCAT.debug()
  3360. << "releasing display list index " << (int)(*ddli) << "\n";
  3361. }
  3362. glDeleteLists((*ddli), 1);
  3363. }
  3364. _deleted_display_lists.clear();
  3365. }
  3366. }
  3367. #endif
  3368. // And deleted queries, too, unless we're using query timers in which case
  3369. // we'll need to reuse lots of them.
  3370. if (_supports_occlusion_query && !get_timer_queries_active()) {
  3371. LightMutexHolder holder(_lock);
  3372. if (!_deleted_queries.empty()) {
  3373. if (GLCAT.is_spam()) {
  3374. DeletedNames::iterator dqi;
  3375. for (dqi = _deleted_queries.begin();
  3376. dqi != _deleted_queries.end();
  3377. ++dqi) {
  3378. GLCAT.spam()
  3379. << "releasing query index " << (int)(*dqi) << "\n";
  3380. }
  3381. }
  3382. _glDeleteQueries(_deleted_queries.size(), &_deleted_queries[0]);
  3383. _deleted_queries.clear();
  3384. }
  3385. }
  3386. #endif // OPENGLES
  3387. #ifndef NDEBUG
  3388. if (_check_errors || (_supports_debug && gl_debug)) {
  3389. report_my_gl_errors();
  3390. } else {
  3391. // If _check_errors is false, we still want to check for errors once every
  3392. // second, so that we know if anything went wrong at all.
  3393. double current = ClockObject::get_global_clock()->get_frame_time();
  3394. if (current - _last_error_check >= 1.0) {
  3395. _last_error_check = current;
  3396. PStatTimer timer(_check_error_pcollector);
  3397. GLenum error_code = glGetError();
  3398. if (error_code != GL_NO_ERROR) {
  3399. int error_count = 0;
  3400. do {
  3401. ++error_count;
  3402. GLCAT.error()
  3403. << "GL error 0x" << hex << error_code << dec << " : "
  3404. << get_error_string(error_code) << "\n";
  3405. error_code = glGetError();
  3406. } while (error_code != GL_NO_ERROR);
  3407. if (error_count == 1) {
  3408. GLCAT.error()
  3409. << "An OpenGL error has occurred.";
  3410. } else {
  3411. GLCAT.error()
  3412. << error_count << " OpenGL errors have occurred.";
  3413. }
  3414. if (_supports_debug) {
  3415. GLCAT.error(false) << " Set gl-debug #t "
  3416. << "in your PRC file to display more information.\n";
  3417. } else {
  3418. GLCAT.error(false) << " Set gl-check-errors #t "
  3419. << "in your PRC file to display more information.\n";
  3420. }
  3421. _error_count += error_count;
  3422. if (_error_count >= gl_max_errors) {
  3423. panic_deactivate();
  3424. }
  3425. }
  3426. }
  3427. }
  3428. #endif
  3429. // Add in a newline to the spam output for improved legibility.
  3430. if (GLCAT.is_spam()) {
  3431. GLCAT.spam(false) << endl;
  3432. }
  3433. }
  3434. /**
  3435. * Called before a sequence of draw_primitive() functions are called, this
  3436. * should prepare the vertex data for rendering. It returns true if the
  3437. * vertices are ok, false to abort this group of primitives.
  3438. */
  3439. bool CLP(GraphicsStateGuardian)::
  3440. begin_draw_primitives(const GeomPipelineReader *geom_reader,
  3441. const GeomMunger *munger,
  3442. const GeomVertexDataPipelineReader *data_reader,
  3443. bool force) {
  3444. #ifndef NDEBUG
  3445. if (GLCAT.is_spam()) {
  3446. GLCAT.spam() << "begin_draw_primitives: " << *(data_reader->get_object()) << "\n";
  3447. }
  3448. #endif // NDEBUG
  3449. #ifndef SUPPORT_FIXED_FUNCTION
  3450. // We can't draw without a shader bound in OpenGL ES 2. This shouldn't
  3451. // happen anyway unless the default shader failed to compile somehow.
  3452. if (_current_shader_context == NULL) {
  3453. return false;
  3454. }
  3455. #endif
  3456. if (!GraphicsStateGuardian::begin_draw_primitives(geom_reader, munger, data_reader, force)) {
  3457. return false;
  3458. }
  3459. nassertr(_data_reader != (GeomVertexDataPipelineReader *)NULL, false);
  3460. _geom_display_list = 0;
  3461. if (_auto_antialias_mode) {
  3462. switch (geom_reader->get_primitive_type()) {
  3463. case GeomPrimitive::PT_polygons:
  3464. case GeomPrimitive::PT_patches:
  3465. setup_antialias_polygon();
  3466. break;
  3467. case GeomPrimitive::PT_points:
  3468. setup_antialias_point();
  3469. break;
  3470. case GeomPrimitive::PT_lines:
  3471. setup_antialias_line();
  3472. break;
  3473. case GeomPrimitive::PT_none:
  3474. break;
  3475. }
  3476. int transparency_slot = TransparencyAttrib::get_class_slot();
  3477. int color_write_slot = ColorWriteAttrib::get_class_slot();
  3478. int color_blend_slot = ColorBlendAttrib::get_class_slot();
  3479. if (!_state_mask.get_bit(transparency_slot) ||
  3480. !_state_mask.get_bit(color_write_slot) ||
  3481. !_state_mask.get_bit(color_blend_slot)) {
  3482. do_issue_blending();
  3483. _state_mask.set_bit(transparency_slot);
  3484. _state_mask.set_bit(color_write_slot);
  3485. _state_mask.set_bit(color_blend_slot);
  3486. }
  3487. }
  3488. #ifdef SUPPORT_FIXED_FUNCTION
  3489. if (_data_reader->is_vertex_transformed()) {
  3490. // If the vertex data claims to be already transformed into clip
  3491. // coordinates, wipe out the current projection and modelview matrix (so
  3492. // we don't attempt to transform it again).
  3493. glMatrixMode(GL_PROJECTION);
  3494. glPushMatrix();
  3495. glLoadIdentity();
  3496. glMatrixMode(GL_MODELVIEW);
  3497. glPushMatrix();
  3498. glLoadIdentity();
  3499. }
  3500. #endif
  3501. #if !defined(OPENGLES) && defined(SUPPORT_FIXED_FUNCTION) // Display lists not supported by OpenGL ES.
  3502. if (geom_reader->get_usage_hint() == Geom::UH_static &&
  3503. _data_reader->get_usage_hint() == Geom::UH_static &&
  3504. display_lists) {
  3505. // If the geom claims to be totally static, try to build it into a display
  3506. // list.
  3507. // Before we compile or call a display list, make sure the current buffers
  3508. // are unbound, or the nVidia drivers may crash.
  3509. unbind_buffers();
  3510. GeomContext *gc = geom_reader->prepare_now(get_prepared_objects(), this);
  3511. nassertr(gc != (GeomContext *)NULL, false);
  3512. CLP(GeomContext) *ggc = DCAST(CLP(GeomContext), gc);
  3513. const CLP(GeomMunger) *gmunger = DCAST(CLP(GeomMunger), _munger);
  3514. UpdateSeq modified = max(geom_reader->get_modified(), _data_reader->get_modified());
  3515. if (ggc->get_display_list(_geom_display_list, gmunger, modified)) {
  3516. // If it hasn't been modified, just play the display list again.
  3517. if (GLCAT.is_spam()) {
  3518. GLCAT.spam()
  3519. << "calling display list " << (int)_geom_display_list << "\n";
  3520. }
  3521. glCallList(_geom_display_list);
  3522. #ifdef DO_PSTATS
  3523. _vertices_display_list_pcollector.add_level(ggc->_num_verts);
  3524. _primitive_batches_display_list_pcollector.add_level(1);
  3525. #endif
  3526. // And now we don't need to do anything else for this geom.
  3527. _geom_display_list = 0;
  3528. end_draw_primitives();
  3529. return false;
  3530. }
  3531. // Since we start this collector explicitly, we have to be sure to stop it
  3532. // again.
  3533. _load_display_list_pcollector.start();
  3534. if (GLCAT.is_debug()) {
  3535. GLCAT.debug()
  3536. << "compiling display list " << (int)_geom_display_list << "\n";
  3537. }
  3538. // If it has been modified, or this is the first time, then we need to
  3539. // build the display list up.
  3540. if (gl_compile_and_execute) {
  3541. glNewList(_geom_display_list, GL_COMPILE_AND_EXECUTE);
  3542. } else {
  3543. glNewList(_geom_display_list, GL_COMPILE);
  3544. }
  3545. #ifdef DO_PSTATS
  3546. // Count up the number of vertices used by primitives in the Geom, for
  3547. // PStats reporting.
  3548. ggc->_num_verts = 0;
  3549. for (int i = 0; i < geom_reader->get_num_primitives(); i++) {
  3550. ggc->_num_verts += geom_reader->get_primitive(i)->get_num_vertices();
  3551. }
  3552. #endif
  3553. }
  3554. #endif // OPENGLES
  3555. // Enable the appropriate vertex arrays, and disable any extra vertex arrays
  3556. // used by the previous rendering mode.
  3557. #ifdef SUPPORT_IMMEDIATE_MODE
  3558. _use_sender = !vertex_arrays;
  3559. #endif
  3560. #ifndef OPENGLES_1
  3561. if (_use_vertex_attrib_binding) {
  3562. const GeomVertexFormat *format = data_reader->get_format();
  3563. if (format != _current_vertex_format) {
  3564. update_shader_vertex_format(format);
  3565. }
  3566. }
  3567. #endif
  3568. {
  3569. // PStatGPUTimer timer(this, _vertex_array_update_pcollector);
  3570. #ifdef OPENGLES_1
  3571. if (!update_standard_vertex_arrays(force)) {
  3572. return false;
  3573. }
  3574. #else
  3575. if (_current_shader_context == 0) {
  3576. // No shader.
  3577. if (_vertex_array_shader_context != 0) {
  3578. _vertex_array_shader_context->disable_shader_vertex_arrays();
  3579. }
  3580. #ifdef SUPPORT_FIXED_FUNCTION
  3581. if (!update_standard_vertex_arrays(force)) {
  3582. return false;
  3583. }
  3584. #endif
  3585. } else {
  3586. #ifdef SUPPORT_FIXED_FUNCTION
  3587. // Shader.
  3588. if (_vertex_array_shader_context == 0 ||
  3589. _vertex_array_shader_context->uses_standard_vertex_arrays()) {
  3590. // Previous shader used standard arrays.
  3591. if (_current_shader_context->uses_standard_vertex_arrays()) {
  3592. // So does the current, so update them.
  3593. if (!update_standard_vertex_arrays(force)) {
  3594. return false;
  3595. }
  3596. } else {
  3597. // The current shader does not, so disable them entirely.
  3598. disable_standard_vertex_arrays();
  3599. }
  3600. }
  3601. #ifdef HAVE_CG
  3602. else if (_vertex_array_shader_context->is_of_type(CLP(CgShaderContext)::get_class_type())) {
  3603. // The previous shader was a Cg shader, which can leave a messy
  3604. // situation.
  3605. _vertex_array_shader_context->disable_shader_vertex_arrays();
  3606. }
  3607. #endif
  3608. #endif // SUPPORT_FIXED_FUNCTION
  3609. // Now update the vertex arrays for the current shader.
  3610. if (!_current_shader_context->
  3611. update_shader_vertex_arrays(_vertex_array_shader_context, force)) {
  3612. return false;
  3613. }
  3614. }
  3615. _vertex_array_shader = _current_shader;
  3616. _vertex_array_shader_context = _current_shader_context;
  3617. #endif // OPENGLES_1
  3618. }
  3619. report_my_gl_errors();
  3620. return true;
  3621. }
  3622. #ifdef SUPPORT_FIXED_FUNCTION
  3623. /**
  3624. * Disables any unneeded vertex arrays that were previously enabled, and
  3625. * enables any vertex arrays that are needed that were not previously enabled
  3626. * (or, sets up an immediate-mode sender). Called only from
  3627. * begin_draw_primitives. Used only when the standard (non-shader) pipeline
  3628. * is about to be used - glShaderContexts are responsible for setting up their
  3629. * own vertex arrays.
  3630. */
  3631. bool CLP(GraphicsStateGuardian)::
  3632. update_standard_vertex_arrays(bool force) {
  3633. #ifdef SUPPORT_IMMEDIATE_MODE
  3634. if (_use_sender) {
  3635. // We must use immediate mode to render primitives.
  3636. _sender.clear();
  3637. _sender.add_column(_data_reader, InternalName::get_normal(),
  3638. NULL, NULL, GLPf(Normal3), NULL);
  3639. #ifndef NDEBUG
  3640. if (_show_texture_usage) {
  3641. // In show_texture_usage mode, all colors are white, so as not to
  3642. // contaminate the texture color.
  3643. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  3644. } else
  3645. #endif // NDEBUG
  3646. if (!_sender.add_column(_data_reader, InternalName::get_color(),
  3647. NULL, NULL, GLPf(Color3), GLPf(Color4))) {
  3648. // If we didn't have a color column, the item color is white.
  3649. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  3650. }
  3651. // Now set up each of the active texture coordinate stages--or at least
  3652. // those for which we're not generating texture coordinates automatically.
  3653. int max_stage_index = _target_texture->get_num_on_ff_stages();
  3654. int stage_index = 0;
  3655. while (stage_index < max_stage_index) {
  3656. TextureStage *stage = _target_texture->get_on_ff_stage(stage_index);
  3657. if (!_target_tex_gen->has_gen_texcoord_stage(stage)) {
  3658. // This stage is not one of the stages that doesn't need texcoords
  3659. // issued for it.
  3660. const InternalName *name = stage->get_texcoord_name();
  3661. if (stage_index == 0) {
  3662. // Use the original functions for stage 0, in case we don't support
  3663. // multitexture.
  3664. _sender.add_column(_data_reader, name,
  3665. GLPf(TexCoord1), GLPf(TexCoord2),
  3666. GLPf(TexCoord3), GLPf(TexCoord4));
  3667. } else {
  3668. // Other stages require the multitexture functions.
  3669. _sender.add_texcoord_column(_data_reader, name, stage_index,
  3670. GLf(_glMultiTexCoord1), GLf(_glMultiTexCoord2),
  3671. GLf(_glMultiTexCoord3), GLf(_glMultiTexCoord4));
  3672. }
  3673. }
  3674. ++stage_index;
  3675. }
  3676. // Be sure also to disable any texture stages we had enabled before.
  3677. while (stage_index < _last_max_stage_index) {
  3678. _glClientActiveTexture(GL_TEXTURE0 + stage_index);
  3679. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  3680. ++stage_index;
  3681. }
  3682. _last_max_stage_index = max_stage_index;
  3683. // We must add vertex last, because glVertex3f() is the key function call
  3684. // that actually issues the vertex.
  3685. _sender.add_column(_data_reader, InternalName::get_vertex(),
  3686. NULL, GLPf(Vertex2), GLPf(Vertex3), GLPf(Vertex4));
  3687. } else
  3688. #endif // SUPPORT_IMMEDIATE_MODE
  3689. {
  3690. // We may use vertex arrays or buffers to render primitives.
  3691. const GeomVertexArrayDataHandle *array_reader;
  3692. const unsigned char *client_pointer;
  3693. int num_values;
  3694. Geom::NumericType numeric_type;
  3695. int start;
  3696. int stride;
  3697. if (_data_reader->get_normal_info(array_reader, numeric_type,
  3698. start, stride)) {
  3699. if (!setup_array_data(client_pointer, array_reader, force)) {
  3700. return false;
  3701. }
  3702. glNormalPointer(get_numeric_type(numeric_type), stride,
  3703. client_pointer + start);
  3704. glEnableClientState(GL_NORMAL_ARRAY);
  3705. } else {
  3706. glDisableClientState(GL_NORMAL_ARRAY);
  3707. }
  3708. #ifndef NDEBUG
  3709. if (_show_texture_usage) {
  3710. // In show_texture_usage mode, all colors are white, so as not to
  3711. // contaminate the texture color.
  3712. glDisableClientState(GL_COLOR_ARRAY);
  3713. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  3714. } else
  3715. #endif // NDEBUG
  3716. if (_data_reader->get_color_info(array_reader, num_values, numeric_type,
  3717. start, stride)) {
  3718. if (!setup_array_data(client_pointer, array_reader, force)) {
  3719. return false;
  3720. }
  3721. if (numeric_type == Geom::NT_packed_dabc) {
  3722. glColorPointer(GL_BGRA, GL_UNSIGNED_BYTE,
  3723. stride, client_pointer + start);
  3724. } else {
  3725. glColorPointer(num_values, get_numeric_type(numeric_type),
  3726. stride, client_pointer + start);
  3727. }
  3728. glEnableClientState(GL_COLOR_ARRAY);
  3729. } else {
  3730. glDisableClientState(GL_COLOR_ARRAY);
  3731. // Since we don't have per-vertex color, the implicit color is white.
  3732. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  3733. }
  3734. // Now set up each of the active texture coordinate stages--or at least
  3735. // those for which we're not generating texture coordinates automatically.
  3736. int max_stage_index = _target_texture->get_num_on_ff_stages();
  3737. int stage_index = 0;
  3738. while (stage_index < max_stage_index) {
  3739. _glClientActiveTexture(GL_TEXTURE0 + stage_index);
  3740. TextureStage *stage = _target_texture->get_on_ff_stage(stage_index);
  3741. if (!_target_tex_gen->has_gen_texcoord_stage(stage)) {
  3742. // This stage is not one of the stages that doesn't need texcoords
  3743. // issued for it.
  3744. const InternalName *name = stage->get_texcoord_name();
  3745. if (_data_reader->get_array_info(name, array_reader, num_values,
  3746. numeric_type, start, stride)) {
  3747. // The vertex data does have texcoords for this stage.
  3748. if (!setup_array_data(client_pointer, array_reader, force)) {
  3749. return false;
  3750. }
  3751. glTexCoordPointer(num_values, get_numeric_type(numeric_type),
  3752. stride, client_pointer + start);
  3753. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  3754. } else {
  3755. // The vertex data doesn't have texcoords for this stage (even
  3756. // though they're needed).
  3757. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  3758. }
  3759. } else {
  3760. // No texcoords are needed for this stage.
  3761. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  3762. }
  3763. ++stage_index;
  3764. }
  3765. // Be sure also to disable any texture stages we had enabled before.
  3766. while (stage_index < _last_max_stage_index) {
  3767. _glClientActiveTexture(GL_TEXTURE0 + stage_index);
  3768. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  3769. ++stage_index;
  3770. }
  3771. _last_max_stage_index = max_stage_index;
  3772. // There's no requirement that we add vertices last, but we do anyway.
  3773. if (_data_reader->get_vertex_info(array_reader, num_values, numeric_type,
  3774. start, stride)) {
  3775. if (!setup_array_data(client_pointer, array_reader, force)) {
  3776. return false;
  3777. }
  3778. glVertexPointer(num_values, get_numeric_type(numeric_type),
  3779. stride, client_pointer + start);
  3780. glEnableClientState(GL_VERTEX_ARRAY);
  3781. }
  3782. }
  3783. return true;
  3784. }
  3785. #endif // SUPPORT_FIXED_FUNCTION
  3786. /**
  3787. * Ensures the vertex and array buffers are no longer bound. Some graphics
  3788. * drivers crash if these are left bound indiscriminantly.
  3789. */
  3790. void CLP(GraphicsStateGuardian)::
  3791. unbind_buffers() {
  3792. if (_current_vbuffer_index != 0) {
  3793. if (GLCAT.is_spam() && gl_debug_buffers) {
  3794. GLCAT.spam()
  3795. << "unbinding vertex buffer\n";
  3796. }
  3797. _glBindBuffer(GL_ARRAY_BUFFER, 0);
  3798. _current_vbuffer_index = 0;
  3799. }
  3800. if (_current_ibuffer_index != 0) {
  3801. if (GLCAT.is_spam() && gl_debug_buffers) {
  3802. GLCAT.spam()
  3803. << "unbinding index buffer\n";
  3804. }
  3805. _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  3806. _current_ibuffer_index = 0;
  3807. }
  3808. #ifndef OPENGLES
  3809. if (_current_vertex_buffers.size() > 1 && _supports_multi_bind) {
  3810. _glBindVertexBuffers(0, _current_vertex_buffers.size(), NULL, NULL, NULL);
  3811. } else {
  3812. for (int i = 0; i < _current_vertex_buffers.size(); ++i) {
  3813. if (_current_vertex_buffers[i] != 0) {
  3814. _glBindVertexBuffer(i, 0, 0, 0);
  3815. }
  3816. }
  3817. }
  3818. _current_vertex_buffers.clear();
  3819. #endif
  3820. #ifdef SUPPORT_FIXED_FUNCTION
  3821. disable_standard_vertex_arrays();
  3822. #endif
  3823. }
  3824. #ifdef SUPPORT_FIXED_FUNCTION
  3825. /**
  3826. * Used to disable all the standard vertex arrays that are currently enabled.
  3827. * glShaderContexts are responsible for setting up their own vertex arrays,
  3828. * but before they can do so, the standard vertex arrays need to be disabled
  3829. * to get them "out of the way." Called only from begin_draw_primitives.
  3830. */
  3831. void CLP(GraphicsStateGuardian)::
  3832. disable_standard_vertex_arrays() {
  3833. #ifdef SUPPORT_IMMEDIATE_MODE
  3834. if (_use_sender) return;
  3835. #endif
  3836. glDisableClientState(GL_NORMAL_ARRAY);
  3837. glDisableClientState(GL_COLOR_ARRAY);
  3838. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  3839. for (int stage_index=0; stage_index < _last_max_stage_index; stage_index++) {
  3840. _glClientActiveTexture(GL_TEXTURE0 + stage_index);
  3841. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  3842. }
  3843. _last_max_stage_index = 0;
  3844. glDisableClientState(GL_VERTEX_ARRAY);
  3845. report_my_gl_errors();
  3846. }
  3847. #endif // SUPPORT_FIXED_FUNCTION
  3848. #ifndef OPENGLES_1
  3849. /**
  3850. * Updates the vertex format used by the shader. This is still an
  3851. * experimental feature.
  3852. */
  3853. void CLP(GraphicsStateGuardian)::
  3854. update_shader_vertex_format(const GeomVertexFormat *format) {
  3855. size_t num_columns = format->get_num_columns();
  3856. for (size_t ci = 0; ci < num_columns; ++ci) {
  3857. GLuint binding = format->get_array_with(ci);
  3858. const GeomVertexColumn *column = format->get_column(ci);
  3859. // Needs improvement, obviously.
  3860. const InternalName *name = column->get_name();
  3861. GLuint loc;
  3862. if (name == InternalName::get_vertex()) {
  3863. loc = 0;
  3864. } else if (name == InternalName::get_transform_weight()) {
  3865. loc = 1;
  3866. } else if (name == InternalName::get_normal()) {
  3867. loc = 2;
  3868. } else if (name == InternalName::get_color()) {
  3869. loc = 3;
  3870. } else if (name == InternalName::get_transform_index()) {
  3871. loc = 7;
  3872. } else if (name == InternalName::get_texcoord()) {
  3873. loc = 8;
  3874. } else {
  3875. // Not yet supported, ignore for now. This system will be improved.
  3876. continue;
  3877. }
  3878. if (_vertex_attrib_columns[loc] != NULL &&
  3879. _vertex_attrib_columns[loc]->compare_to(*column) == 0) {
  3880. continue;
  3881. }
  3882. _vertex_attrib_columns[loc] = column;
  3883. GLuint offset = column->get_start();
  3884. GLenum type = get_numeric_type(column->get_numeric_type());
  3885. GLboolean normalized = (column->get_contents() == GeomEnums::C_color);
  3886. GLint size = column->get_num_values();
  3887. if (column->get_numeric_type() == GeomEnums::NT_packed_dabc) {
  3888. // GL_BGRA is a special accepted value available since OpenGL 3.2. It
  3889. // requires us to pass GL_TRUE for normalized.
  3890. size = GL_BGRA;
  3891. normalized = GL_TRUE;
  3892. }
  3893. for (int i = 0; i < column->get_num_elements(); ++i) {
  3894. if (loc == 7) { // Temp hack
  3895. _glVertexAttribIFormat(loc, size, type, offset);
  3896. } else {
  3897. _glVertexAttribFormat(loc, size, type, normalized, offset);
  3898. }
  3899. _glVertexAttribBinding(loc, binding);
  3900. offset += column->get_element_stride();
  3901. ++loc;
  3902. }
  3903. }
  3904. size_t num_arrays = format->get_num_arrays();
  3905. for (size_t ai = 0; ai < num_arrays; ++ai) {
  3906. _glVertexBindingDivisor(ai, format->get_array(ai)->get_divisor());
  3907. }
  3908. _current_vertex_format = format;
  3909. }
  3910. #endif
  3911. /**
  3912. * Draws a series of disconnected triangles.
  3913. */
  3914. bool CLP(GraphicsStateGuardian)::
  3915. draw_triangles(const GeomPrimitivePipelineReader *reader, bool force) {
  3916. // PStatGPUTimer timer(this, _draw_primitive_pcollector,
  3917. // reader->get_current_thread());
  3918. #ifndef NDEBUG
  3919. if (GLCAT.is_spam()) {
  3920. GLCAT.spam() << "draw_triangles: " << *(reader->get_object()) << "\n";
  3921. }
  3922. #endif // NDEBUG
  3923. #ifdef SUPPORT_IMMEDIATE_MODE
  3924. if (_use_sender) {
  3925. draw_immediate_simple_primitives(reader, GL_TRIANGLES);
  3926. } else
  3927. #endif // SUPPORT_IMMEDIATE_MODE
  3928. {
  3929. int num_vertices = reader->get_num_vertices();
  3930. _vertices_tri_pcollector.add_level(num_vertices);
  3931. _primitive_batches_tri_pcollector.add_level(1);
  3932. if (reader->is_indexed()) {
  3933. const unsigned char *client_pointer;
  3934. if (!setup_primitive(client_pointer, reader, force)) {
  3935. return false;
  3936. }
  3937. #ifndef OPENGLES_1
  3938. if (_supports_geometry_instancing && _instance_count > 0) {
  3939. _glDrawElementsInstanced(GL_TRIANGLES, num_vertices,
  3940. get_numeric_type(reader->get_index_type()),
  3941. client_pointer, _instance_count);
  3942. } else
  3943. #endif
  3944. {
  3945. _glDrawRangeElements(GL_TRIANGLES,
  3946. reader->get_min_vertex(),
  3947. reader->get_max_vertex(),
  3948. num_vertices,
  3949. get_numeric_type(reader->get_index_type()),
  3950. client_pointer);
  3951. }
  3952. } else {
  3953. #ifndef OPENGLES_1
  3954. if (_supports_geometry_instancing && _instance_count > 0) {
  3955. _glDrawArraysInstanced(GL_TRIANGLES,
  3956. reader->get_first_vertex(),
  3957. num_vertices, _instance_count);
  3958. } else
  3959. #endif
  3960. {
  3961. glDrawArrays(GL_TRIANGLES,
  3962. reader->get_first_vertex(),
  3963. num_vertices);
  3964. }
  3965. }
  3966. }
  3967. report_my_gl_errors();
  3968. return true;
  3969. }
  3970. /**
  3971. * Draws a series of triangle strips.
  3972. */
  3973. bool CLP(GraphicsStateGuardian)::
  3974. draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force) {
  3975. // PStatGPUTimer timer(this, _draw_primitive_pcollector,
  3976. // reader->get_current_thread());
  3977. report_my_gl_errors();
  3978. #ifndef NDEBUG
  3979. if (GLCAT.is_spam()) {
  3980. GLCAT.spam() << "draw_tristrips: " << *(reader->get_object()) << "\n";
  3981. }
  3982. #endif // NDEBUG
  3983. #ifdef SUPPORT_IMMEDIATE_MODE
  3984. if (_use_sender) {
  3985. draw_immediate_composite_primitives(reader, GL_TRIANGLE_STRIP);
  3986. } else
  3987. #endif // SUPPORT_IMMEDIATE_MODE
  3988. {
  3989. if (connect_triangle_strips && _render_mode != RenderModeAttrib::M_wireframe) {
  3990. // One long triangle strip, connected by the degenerate vertices that
  3991. // have already been set up within the primitive.
  3992. int num_vertices = reader->get_num_vertices();
  3993. _vertices_tristrip_pcollector.add_level(num_vertices);
  3994. _primitive_batches_tristrip_pcollector.add_level(1);
  3995. if (reader->is_indexed()) {
  3996. const unsigned char *client_pointer;
  3997. if (!setup_primitive(client_pointer, reader, force)) {
  3998. return false;
  3999. }
  4000. #ifndef OPENGLES_1
  4001. if (_supports_geometry_instancing && _instance_count > 0) {
  4002. _glDrawElementsInstanced(GL_TRIANGLE_STRIP, num_vertices,
  4003. get_numeric_type(reader->get_index_type()),
  4004. client_pointer, _instance_count);
  4005. } else
  4006. #endif
  4007. {
  4008. _glDrawRangeElements(GL_TRIANGLE_STRIP,
  4009. reader->get_min_vertex(),
  4010. reader->get_max_vertex(),
  4011. num_vertices,
  4012. get_numeric_type(reader->get_index_type()),
  4013. client_pointer);
  4014. }
  4015. } else {
  4016. #ifndef OPENGLES_1
  4017. if (_supports_geometry_instancing && _instance_count > 0) {
  4018. _glDrawArraysInstanced(GL_TRIANGLE_STRIP,
  4019. reader->get_first_vertex(),
  4020. num_vertices, _instance_count);
  4021. } else
  4022. #endif
  4023. {
  4024. glDrawArrays(GL_TRIANGLE_STRIP,
  4025. reader->get_first_vertex(),
  4026. num_vertices);
  4027. }
  4028. }
  4029. } else {
  4030. // Send the individual triangle strips, stepping over the degenerate
  4031. // vertices.
  4032. CPTA_int ends = reader->get_ends();
  4033. _primitive_batches_tristrip_pcollector.add_level(ends.size());
  4034. if (reader->is_indexed()) {
  4035. const unsigned char *client_pointer;
  4036. if (!setup_primitive(client_pointer, reader, force)) {
  4037. return false;
  4038. }
  4039. int index_stride = reader->get_index_stride();
  4040. GeomVertexReader mins(reader->get_mins(), 0);
  4041. GeomVertexReader maxs(reader->get_maxs(), 0);
  4042. nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() &&
  4043. reader->get_maxs()->get_num_rows() == (int)ends.size(), false);
  4044. unsigned int start = 0;
  4045. for (size_t i = 0; i < ends.size(); i++) {
  4046. _vertices_tristrip_pcollector.add_level(ends[i] - start);
  4047. #ifndef OPENGLES_1
  4048. if (_supports_geometry_instancing && _instance_count > 0) {
  4049. _glDrawElementsInstanced(GL_TRIANGLE_STRIP, ends[i] - start,
  4050. get_numeric_type(reader->get_index_type()),
  4051. client_pointer + start * index_stride,
  4052. _instance_count);
  4053. } else
  4054. #endif
  4055. {
  4056. _glDrawRangeElements(GL_TRIANGLE_STRIP,
  4057. mins.get_data1i(), maxs.get_data1i(),
  4058. ends[i] - start,
  4059. get_numeric_type(reader->get_index_type()),
  4060. client_pointer + start * index_stride);
  4061. }
  4062. start = ends[i] + 2;
  4063. }
  4064. } else {
  4065. unsigned int start = 0;
  4066. int first_vertex = reader->get_first_vertex();
  4067. for (size_t i = 0; i < ends.size(); i++) {
  4068. _vertices_tristrip_pcollector.add_level(ends[i] - start);
  4069. #ifndef OPENGLES_1
  4070. if (_supports_geometry_instancing && _instance_count > 0) {
  4071. _glDrawArraysInstanced(GL_TRIANGLE_STRIP, first_vertex + start,
  4072. ends[i] - start, _instance_count);
  4073. } else
  4074. #endif
  4075. {
  4076. glDrawArrays(GL_TRIANGLE_STRIP, first_vertex + start,
  4077. ends[i] - start);
  4078. }
  4079. start = ends[i] + 2;
  4080. }
  4081. }
  4082. }
  4083. }
  4084. report_my_gl_errors();
  4085. return true;
  4086. }
  4087. /**
  4088. * Draws a series of triangle fans.
  4089. */
  4090. bool CLP(GraphicsStateGuardian)::
  4091. draw_trifans(const GeomPrimitivePipelineReader *reader, bool force) {
  4092. // PStatGPUTimer timer(this, _draw_primitive_pcollector,
  4093. // reader->get_current_thread());
  4094. #ifndef NDEBUG
  4095. if (GLCAT.is_spam()) {
  4096. GLCAT.spam() << "draw_trifans: " << *(reader->get_object()) << "\n";
  4097. }
  4098. #endif // NDEBUG
  4099. #ifdef SUPPORT_IMMEDIATE_MODE
  4100. if (_use_sender) {
  4101. draw_immediate_composite_primitives(reader, GL_TRIANGLE_FAN);
  4102. } else
  4103. #endif // SUPPORT_IMMEDIATE_MODE
  4104. {
  4105. // Send the individual triangle fans. There's no connecting fans with
  4106. // degenerate vertices, so no worries about that.
  4107. CPTA_int ends = reader->get_ends();
  4108. _primitive_batches_trifan_pcollector.add_level(ends.size());
  4109. if (reader->is_indexed()) {
  4110. const unsigned char *client_pointer;
  4111. if (!setup_primitive(client_pointer, reader, force)) {
  4112. return false;
  4113. }
  4114. int index_stride = reader->get_index_stride();
  4115. GeomVertexReader mins(reader->get_mins(), 0);
  4116. GeomVertexReader maxs(reader->get_maxs(), 0);
  4117. nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() &&
  4118. reader->get_maxs()->get_num_rows() == (int)ends.size(), false);
  4119. unsigned int start = 0;
  4120. for (size_t i = 0; i < ends.size(); i++) {
  4121. _vertices_trifan_pcollector.add_level(ends[i] - start);
  4122. #ifndef OPENGLES_1
  4123. if (_supports_geometry_instancing && _instance_count > 0) {
  4124. _glDrawElementsInstanced(GL_TRIANGLE_FAN, ends[i] - start,
  4125. get_numeric_type(reader->get_index_type()),
  4126. client_pointer + start * index_stride,
  4127. _instance_count);
  4128. } else
  4129. #endif
  4130. {
  4131. _glDrawRangeElements(GL_TRIANGLE_FAN,
  4132. mins.get_data1i(), maxs.get_data1i(), ends[i] - start,
  4133. get_numeric_type(reader->get_index_type()),
  4134. client_pointer + start * index_stride);
  4135. }
  4136. start = ends[i];
  4137. }
  4138. } else {
  4139. unsigned int start = 0;
  4140. int first_vertex = reader->get_first_vertex();
  4141. for (size_t i = 0; i < ends.size(); i++) {
  4142. _vertices_trifan_pcollector.add_level(ends[i] - start);
  4143. #ifndef OPENGLES_1
  4144. if (_supports_geometry_instancing && _instance_count > 0) {
  4145. _glDrawArraysInstanced(GL_TRIANGLE_FAN, first_vertex + start,
  4146. ends[i] - start, _instance_count);
  4147. } else
  4148. #endif
  4149. {
  4150. glDrawArrays(GL_TRIANGLE_FAN, first_vertex + start,
  4151. ends[i] - start);
  4152. }
  4153. start = ends[i];
  4154. }
  4155. }
  4156. }
  4157. report_my_gl_errors();
  4158. return true;
  4159. }
  4160. /**
  4161. * Draws a series of "patches", which can only be processed by a tessellation
  4162. * shader.
  4163. */
  4164. bool CLP(GraphicsStateGuardian)::
  4165. draw_patches(const GeomPrimitivePipelineReader *reader, bool force) {
  4166. // PStatGPUTimer timer(this, _draw_primitive_pcollector,
  4167. // reader->get_current_thread());
  4168. #ifndef NDEBUG
  4169. if (GLCAT.is_spam()) {
  4170. GLCAT.spam() << "draw_patches: " << *(reader->get_object()) << "\n";
  4171. }
  4172. #endif // NDEBUG
  4173. if (!get_supports_tessellation_shaders()) {
  4174. return false;
  4175. }
  4176. #ifndef OPENGLES
  4177. _glPatchParameteri(GL_PATCH_VERTICES, reader->get_object()->get_num_vertices_per_primitive());
  4178. #ifdef SUPPORT_IMMEDIATE_MODE
  4179. if (_use_sender) {
  4180. draw_immediate_simple_primitives(reader, GL_PATCHES);
  4181. } else
  4182. #endif // SUPPORT_IMMEDIATE_MODE
  4183. {
  4184. int num_vertices = reader->get_num_vertices();
  4185. _vertices_patch_pcollector.add_level(num_vertices);
  4186. _primitive_batches_patch_pcollector.add_level(1);
  4187. if (reader->is_indexed()) {
  4188. const unsigned char *client_pointer;
  4189. if (!setup_primitive(client_pointer, reader, force)) {
  4190. return false;
  4191. }
  4192. #ifndef OPENGLES_1
  4193. if (_supports_geometry_instancing && _instance_count > 0) {
  4194. _glDrawElementsInstanced(GL_PATCHES, num_vertices,
  4195. get_numeric_type(reader->get_index_type()),
  4196. client_pointer, _instance_count);
  4197. } else
  4198. #endif
  4199. {
  4200. _glDrawRangeElements(GL_PATCHES,
  4201. reader->get_min_vertex(),
  4202. reader->get_max_vertex(),
  4203. num_vertices,
  4204. get_numeric_type(reader->get_index_type()),
  4205. client_pointer);
  4206. }
  4207. } else {
  4208. #ifndef OPENGLES_1
  4209. if (_supports_geometry_instancing && _instance_count > 0) {
  4210. _glDrawArraysInstanced(GL_PATCHES,
  4211. reader->get_first_vertex(),
  4212. num_vertices, _instance_count);
  4213. } else
  4214. #endif
  4215. {
  4216. glDrawArrays(GL_PATCHES,
  4217. reader->get_first_vertex(),
  4218. num_vertices);
  4219. }
  4220. }
  4221. }
  4222. #endif // OPENGLES
  4223. report_my_gl_errors();
  4224. return true;
  4225. }
  4226. /**
  4227. * Draws a series of disconnected line segments.
  4228. */
  4229. bool CLP(GraphicsStateGuardian)::
  4230. draw_lines(const GeomPrimitivePipelineReader *reader, bool force) {
  4231. // PStatGPUTimer timer(this, _draw_primitive_pcollector,
  4232. // reader->get_current_thread());
  4233. #ifndef NDEBUG
  4234. if (GLCAT.is_spam()) {
  4235. GLCAT.spam() << "draw_lines: " << *(reader->get_object()) << "\n";
  4236. }
  4237. #endif // NDEBUG
  4238. #ifdef SUPPORT_IMMEDIATE_MODE
  4239. if (_use_sender) {
  4240. draw_immediate_simple_primitives(reader, GL_LINES);
  4241. } else
  4242. #endif // SUPPORT_IMMEDIATE_MODE
  4243. {
  4244. int num_vertices = reader->get_num_vertices();
  4245. _vertices_other_pcollector.add_level(num_vertices);
  4246. _primitive_batches_other_pcollector.add_level(1);
  4247. if (reader->is_indexed()) {
  4248. const unsigned char *client_pointer;
  4249. if (!setup_primitive(client_pointer, reader, force)) {
  4250. return false;
  4251. }
  4252. #ifndef OPENGLES_1
  4253. if (_supports_geometry_instancing && _instance_count > 0) {
  4254. _glDrawElementsInstanced(GL_LINES, num_vertices,
  4255. get_numeric_type(reader->get_index_type()),
  4256. client_pointer, _instance_count);
  4257. } else
  4258. #endif
  4259. {
  4260. _glDrawRangeElements(GL_LINES,
  4261. reader->get_min_vertex(),
  4262. reader->get_max_vertex(),
  4263. num_vertices,
  4264. get_numeric_type(reader->get_index_type()),
  4265. client_pointer);
  4266. }
  4267. } else {
  4268. #ifndef OPENGLES_1
  4269. if (_supports_geometry_instancing && _instance_count > 0) {
  4270. _glDrawArraysInstanced(GL_LINES,
  4271. reader->get_first_vertex(),
  4272. num_vertices, _instance_count);
  4273. } else
  4274. #endif
  4275. {
  4276. glDrawArrays(GL_LINES,
  4277. reader->get_first_vertex(),
  4278. num_vertices);
  4279. }
  4280. }
  4281. }
  4282. report_my_gl_errors();
  4283. return true;
  4284. }
  4285. /**
  4286. * Draws a series of line strips.
  4287. */
  4288. bool CLP(GraphicsStateGuardian)::
  4289. draw_linestrips(const GeomPrimitivePipelineReader *reader, bool force) {
  4290. // PStatGPUTimer timer(this, _draw_primitive_pcollector,
  4291. // reader->get_current_thread());
  4292. report_my_gl_errors();
  4293. #ifndef NDEBUG
  4294. if (GLCAT.is_spam()) {
  4295. GLCAT.spam() << "draw_linestrips: " << *(reader->get_object()) << "\n";
  4296. }
  4297. #endif // NDEBUG
  4298. #ifdef SUPPORT_IMMEDIATE_MODE
  4299. if (_use_sender) {
  4300. draw_immediate_composite_primitives(reader, GL_LINE_STRIP);
  4301. } else
  4302. #endif // SUPPORT_IMMEDIATE_MODE
  4303. {
  4304. if (reader->is_indexed() &&
  4305. (_supported_geom_rendering & GeomEnums::GR_strip_cut_index) != 0) {
  4306. // One long triangle strip, connected by strip cut indices.
  4307. #ifndef OPENGLES
  4308. if (_explicit_primitive_restart) {
  4309. glEnable(GL_PRIMITIVE_RESTART);
  4310. _glPrimitiveRestartIndex(reader->get_strip_cut_index());
  4311. }
  4312. #endif // !OPENGLES
  4313. int num_vertices = reader->get_num_vertices();
  4314. _vertices_other_pcollector.add_level(num_vertices);
  4315. _primitive_batches_other_pcollector.add_level(1);
  4316. const unsigned char *client_pointer;
  4317. if (!setup_primitive(client_pointer, reader, force)) {
  4318. return false;
  4319. }
  4320. #ifndef OPENGLES_1
  4321. if (_supports_geometry_instancing && _instance_count > 0) {
  4322. _glDrawElementsInstanced(GL_LINE_STRIP, num_vertices,
  4323. get_numeric_type(reader->get_index_type()),
  4324. client_pointer, _instance_count);
  4325. } else
  4326. #endif // !OPENGLES
  4327. {
  4328. _glDrawRangeElements(GL_LINE_STRIP,
  4329. reader->get_min_vertex(),
  4330. reader->get_max_vertex(),
  4331. num_vertices,
  4332. get_numeric_type(reader->get_index_type()),
  4333. client_pointer);
  4334. }
  4335. #ifndef OPENGLES
  4336. if (_explicit_primitive_restart) {
  4337. glDisable(GL_PRIMITIVE_RESTART);
  4338. }
  4339. #endif // !OPENGLES
  4340. } else {
  4341. // Send the individual line strips, stepping over the strip-cut indices.
  4342. CPTA_int ends = reader->get_ends();
  4343. _primitive_batches_other_pcollector.add_level(ends.size());
  4344. if (reader->is_indexed()) {
  4345. const unsigned char *client_pointer;
  4346. if (!setup_primitive(client_pointer, reader, force)) {
  4347. return false;
  4348. }
  4349. int index_stride = reader->get_index_stride();
  4350. GeomVertexReader mins(reader->get_mins(), 0);
  4351. GeomVertexReader maxs(reader->get_maxs(), 0);
  4352. nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() &&
  4353. reader->get_maxs()->get_num_rows() == (int)ends.size(), false);
  4354. unsigned int start = 0;
  4355. for (size_t i = 0; i < ends.size(); i++) {
  4356. _vertices_other_pcollector.add_level(ends[i] - start);
  4357. #ifndef OPENGLES_1
  4358. if (_supports_geometry_instancing && _instance_count > 0) {
  4359. _glDrawElementsInstanced(GL_LINE_STRIP, ends[i] - start,
  4360. get_numeric_type(reader->get_index_type()),
  4361. client_pointer + start * index_stride,
  4362. _instance_count);
  4363. } else
  4364. #endif
  4365. {
  4366. _glDrawRangeElements(GL_LINE_STRIP,
  4367. mins.get_data1i(), maxs.get_data1i(),
  4368. ends[i] - start,
  4369. get_numeric_type(reader->get_index_type()),
  4370. client_pointer + start * index_stride);
  4371. }
  4372. start = ends[i] + 1;
  4373. }
  4374. } else {
  4375. unsigned int start = 0;
  4376. int first_vertex = reader->get_first_vertex();
  4377. for (size_t i = 0; i < ends.size(); i++) {
  4378. _vertices_other_pcollector.add_level(ends[i] - start);
  4379. #ifndef OPENGLES_1
  4380. if (_supports_geometry_instancing && _instance_count > 0) {
  4381. _glDrawArraysInstanced(GL_LINE_STRIP, first_vertex + start,
  4382. ends[i] - start, _instance_count);
  4383. } else
  4384. #endif
  4385. {
  4386. glDrawArrays(GL_LINE_STRIP, first_vertex + start, ends[i] - start);
  4387. }
  4388. start = ends[i] + 1;
  4389. }
  4390. }
  4391. }
  4392. }
  4393. report_my_gl_errors();
  4394. return true;
  4395. }
  4396. /**
  4397. * Draws a series of disconnected points.
  4398. */
  4399. bool CLP(GraphicsStateGuardian)::
  4400. draw_points(const GeomPrimitivePipelineReader *reader, bool force) {
  4401. // PStatGPUTimer timer(this, _draw_primitive_pcollector,
  4402. // reader->get_current_thread());
  4403. #ifndef NDEBUG
  4404. if (GLCAT.is_spam()) {
  4405. GLCAT.spam() << "draw_points: " << *(reader->get_object()) << "\n";
  4406. }
  4407. #endif // NDEBUG
  4408. #ifdef SUPPORT_IMMEDIATE_MODE
  4409. if (_use_sender) {
  4410. draw_immediate_simple_primitives(reader, GL_POINTS);
  4411. } else
  4412. #endif // SUPPORT_IMMEDIATE_MODE
  4413. {
  4414. int num_vertices = reader->get_num_vertices();
  4415. _vertices_other_pcollector.add_level(num_vertices);
  4416. _primitive_batches_other_pcollector.add_level(1);
  4417. if (reader->is_indexed()) {
  4418. const unsigned char *client_pointer;
  4419. if (!setup_primitive(client_pointer, reader, force)) {
  4420. return false;
  4421. }
  4422. #ifndef OPENGLES_1
  4423. if (_supports_geometry_instancing && _instance_count > 0) {
  4424. _glDrawElementsInstanced(GL_POINTS, num_vertices,
  4425. get_numeric_type(reader->get_index_type()),
  4426. client_pointer, _instance_count);
  4427. } else
  4428. #endif
  4429. {
  4430. _glDrawRangeElements(GL_POINTS,
  4431. reader->get_min_vertex(),
  4432. reader->get_max_vertex(),
  4433. num_vertices,
  4434. get_numeric_type(reader->get_index_type()),
  4435. client_pointer);
  4436. }
  4437. } else {
  4438. #ifndef OPENGLES_1
  4439. if (_supports_geometry_instancing && _instance_count > 0) {
  4440. _glDrawArraysInstanced(GL_POINTS,
  4441. reader->get_first_vertex(),
  4442. num_vertices, _instance_count);
  4443. } else
  4444. #endif
  4445. {
  4446. glDrawArrays(GL_POINTS, reader->get_first_vertex(), num_vertices);
  4447. }
  4448. }
  4449. }
  4450. report_my_gl_errors();
  4451. return true;
  4452. }
  4453. /**
  4454. * Called after a sequence of draw_primitive() functions are called, this
  4455. * should do whatever cleanup is appropriate.
  4456. */
  4457. void CLP(GraphicsStateGuardian)::
  4458. end_draw_primitives() {
  4459. #if !defined(OPENGLES) && defined(SUPPORT_FIXED_FUNCTION) // Display lists not supported by OpenGL ES.
  4460. if (_geom_display_list != 0) {
  4461. // If we were building a display list, close it now.
  4462. glEndList();
  4463. _load_display_list_pcollector.stop();
  4464. if (!gl_compile_and_execute) {
  4465. glCallList(_geom_display_list);
  4466. }
  4467. _primitive_batches_display_list_pcollector.add_level(1);
  4468. }
  4469. _geom_display_list = 0;
  4470. #endif
  4471. #ifdef SUPPORT_FIXED_FUNCTION
  4472. if (_transform_stale) {
  4473. glMatrixMode(GL_MODELVIEW);
  4474. call_glLoadMatrix(_internal_transform->get_mat());
  4475. }
  4476. if (_data_reader->is_vertex_transformed()) {
  4477. // Restore the matrices that we pushed above.
  4478. glMatrixMode(GL_PROJECTION);
  4479. glPopMatrix();
  4480. glMatrixMode(GL_MODELVIEW);
  4481. glPopMatrix();
  4482. }
  4483. #endif
  4484. GraphicsStateGuardian::end_draw_primitives();
  4485. maybe_gl_finish();
  4486. report_my_gl_errors();
  4487. }
  4488. #ifndef OPENGLES_1
  4489. /**
  4490. * Issues the given memory barriers, and clears the list of textures marked as
  4491. * incoherent for the given bits.
  4492. */
  4493. void CLP(GraphicsStateGuardian)::
  4494. issue_memory_barrier(GLbitfield barriers) {
  4495. if (!gl_enable_memory_barriers || _glMemoryBarrier == NULL) {
  4496. return;
  4497. }
  4498. PStatGPUTimer timer(this, _memory_barrier_pcollector);
  4499. if (GLCAT.is_spam()) {
  4500. GLCAT.spam() << "Issuing memory barriers:";
  4501. }
  4502. _glMemoryBarrier(barriers);
  4503. // Indicate that barriers no longer need to be issued for the relevant lists
  4504. // of textures.
  4505. if (barriers & GL_TEXTURE_FETCH_BARRIER_BIT) {
  4506. _textures_needing_fetch_barrier.clear();
  4507. GLCAT.spam(false) << " texture_fetch";
  4508. }
  4509. if (barriers & GL_SHADER_IMAGE_ACCESS_BARRIER_BIT) {
  4510. _textures_needing_image_access_barrier.clear();
  4511. GLCAT.spam(false) << " shader_image_access";
  4512. }
  4513. if (barriers & GL_TEXTURE_UPDATE_BARRIER_BIT) {
  4514. _textures_needing_update_barrier.clear();
  4515. GLCAT.spam(false) << " texture_update";
  4516. }
  4517. if (barriers & GL_FRAMEBUFFER_BARRIER_BIT) {
  4518. _textures_needing_framebuffer_barrier.clear();
  4519. GLCAT.spam(false) << " framebuffer";
  4520. }
  4521. GLCAT.spam(false) << "\n";
  4522. report_my_gl_errors();
  4523. }
  4524. #endif // OPENGLES_1
  4525. /**
  4526. * Creates whatever structures the GSG requires to represent the texture
  4527. * internally, and returns a newly-allocated TextureContext object with this
  4528. * data. It is the responsibility of the calling function to later call
  4529. * release_texture() with this same pointer (which will also delete the
  4530. * pointer).
  4531. *
  4532. * This function should not be called directly to prepare a texture. Instead,
  4533. * call Texture::prepare().
  4534. */
  4535. TextureContext *CLP(GraphicsStateGuardian)::
  4536. prepare_texture(Texture *tex, int view) {
  4537. PStatGPUTimer timer(this, _prepare_texture_pcollector);
  4538. report_my_gl_errors();
  4539. // Make sure we'll support this texture when it's rendered. Don't bother to
  4540. // prepare it if we won't.
  4541. switch (tex->get_texture_type()) {
  4542. case Texture::TT_3d_texture:
  4543. if (!_supports_3d_texture) {
  4544. GLCAT.warning()
  4545. << "3-D textures are not supported by this OpenGL driver.\n";
  4546. return NULL;
  4547. }
  4548. break;
  4549. case Texture::TT_2d_texture_array:
  4550. if (!_supports_2d_texture_array) {
  4551. GLCAT.warning()
  4552. << "2-D texture arrays are not supported by this OpenGL driver.\n";
  4553. return NULL;
  4554. }
  4555. break;
  4556. case Texture::TT_cube_map:
  4557. if (!_supports_cube_map) {
  4558. GLCAT.warning()
  4559. << "Cube map textures are not supported by this OpenGL driver.\n";
  4560. return NULL;
  4561. }
  4562. break;
  4563. case Texture::TT_buffer_texture:
  4564. if (!_supports_buffer_texture) {
  4565. GLCAT.warning()
  4566. << "Buffer textures are not supported by this OpenGL driver.\n";
  4567. return NULL;
  4568. }
  4569. break;
  4570. case Texture::TT_cube_map_array:
  4571. if (!_supports_cube_map_array) {
  4572. GLCAT.warning()
  4573. << "Cube map arrays are not supported by this OpenGL driver.\n";
  4574. return NULL;
  4575. }
  4576. break;
  4577. default:
  4578. break;
  4579. }
  4580. CLP(TextureContext) *gtc = new CLP(TextureContext)(this, _prepared_objects, tex, view);
  4581. report_my_gl_errors();
  4582. return gtc;
  4583. }
  4584. /**
  4585. * Ensures that the current Texture data is refreshed onto the GSG. This
  4586. * means updating the texture properties and/or re-uploading the texture
  4587. * image, if necessary. This should only be called within the draw thread.
  4588. *
  4589. * If force is true, this function will not return until the texture has been
  4590. * fully uploaded. If force is false, the function may choose to upload a
  4591. * simple version of the texture instead, if the texture is not fully resident
  4592. * (and if get_incomplete_render() is true).
  4593. */
  4594. bool CLP(GraphicsStateGuardian)::
  4595. update_texture(TextureContext *tc, bool force) {
  4596. CLP(TextureContext) *gtc;
  4597. DCAST_INTO_R(gtc, tc, false);
  4598. if (gtc->was_image_modified() || !gtc->_has_storage) {
  4599. PStatGPUTimer timer(this, _texture_update_pcollector);
  4600. // If the texture image was modified, reload the texture.
  4601. apply_texture(gtc);
  4602. Texture *tex = tc->get_texture();
  4603. if (gtc->was_properties_modified()) {
  4604. specify_texture(gtc, tex->get_default_sampler());
  4605. }
  4606. bool okflag = upload_texture(gtc, force, tex->uses_mipmaps());
  4607. if (!okflag) {
  4608. GLCAT.error()
  4609. << "Could not load " << *tex << "\n";
  4610. return false;
  4611. }
  4612. } else if (gtc->was_properties_modified()) {
  4613. PStatGPUTimer timer(this, _texture_update_pcollector);
  4614. // If only the properties have been modified, we don't necessarily need to
  4615. // reload the texture.
  4616. apply_texture(gtc);
  4617. Texture *tex = tc->get_texture();
  4618. if (specify_texture(gtc, tex->get_default_sampler())) {
  4619. // Actually, looks like the texture *does* need to be reloaded.
  4620. gtc->mark_needs_reload();
  4621. bool okflag = upload_texture(gtc, force, tex->uses_mipmaps());
  4622. if (!okflag) {
  4623. GLCAT.error()
  4624. << "Could not load " << *tex << "\n";
  4625. return false;
  4626. }
  4627. } else {
  4628. // The texture didn't need reloading, but mark it fully updated now.
  4629. gtc->mark_loaded();
  4630. }
  4631. }
  4632. gtc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  4633. report_my_gl_errors();
  4634. return true;
  4635. }
  4636. /**
  4637. * Frees the GL resources previously allocated for the texture. This function
  4638. * should never be called directly; instead, call Texture::release() (or
  4639. * simply let the Texture destruct).
  4640. */
  4641. void CLP(GraphicsStateGuardian)::
  4642. release_texture(TextureContext *tc) {
  4643. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
  4644. #ifndef OPENGLES_1
  4645. _textures_needing_fetch_barrier.erase(gtc);
  4646. _textures_needing_image_access_barrier.erase(gtc);
  4647. _textures_needing_update_barrier.erase(gtc);
  4648. _textures_needing_framebuffer_barrier.erase(gtc);
  4649. #endif
  4650. glDeleteTextures(1, &gtc->_index);
  4651. if (gtc->_buffer != 0) {
  4652. _glDeleteBuffers(1, &gtc->_buffer);
  4653. }
  4654. delete gtc;
  4655. }
  4656. /**
  4657. * This method should only be called by the GraphicsEngine. Do not call it
  4658. * directly; call GraphicsEngine::extract_texture_data() instead.
  4659. *
  4660. * This method will be called in the draw thread to download the texture
  4661. * memory's image into its ram_image value. It returns true on success, false
  4662. * otherwise.
  4663. */
  4664. bool CLP(GraphicsStateGuardian)::
  4665. extract_texture_data(Texture *tex) {
  4666. bool success = true;
  4667. // Make sure the error stack is cleared out before we begin.
  4668. report_my_gl_errors();
  4669. int num_views = tex->get_num_views();
  4670. for (int view = 0; view < num_views; ++view) {
  4671. TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this);
  4672. nassertr(tc != (TextureContext *)NULL, false);
  4673. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
  4674. if (!do_extract_texture_data(gtc)) {
  4675. success = false;
  4676. }
  4677. }
  4678. return success;
  4679. }
  4680. #ifndef OPENGLES_1
  4681. /**
  4682. * Creates whatever structures the GSG requires to represent the sampler state
  4683. * internally, and returns a newly-allocated SamplerContext object with this
  4684. * data. It is the responsibility of the calling function to later call
  4685. * release_sampler() with this same pointer (which will also delete the
  4686. * pointer).
  4687. *
  4688. * This function should not be called directly to prepare a sampler object.
  4689. * Instead, call SamplerState::prepare().
  4690. */
  4691. SamplerContext *CLP(GraphicsStateGuardian)::
  4692. prepare_sampler(const SamplerState &sampler) {
  4693. nassertr(_supports_sampler_objects, NULL);
  4694. PStatGPUTimer timer(this, _prepare_sampler_pcollector);
  4695. CLP(SamplerContext) *gsc = new CLP(SamplerContext)(this, sampler);
  4696. GLuint index = gsc->_index;
  4697. // Sampler contexts are immutable in Panda, so might as well just initialize
  4698. // all the settings here.
  4699. _glSamplerParameteri(index, GL_TEXTURE_WRAP_S,
  4700. get_texture_wrap_mode(sampler.get_wrap_u()));
  4701. _glSamplerParameteri(index, GL_TEXTURE_WRAP_T,
  4702. get_texture_wrap_mode(sampler.get_wrap_v()));
  4703. _glSamplerParameteri(index, GL_TEXTURE_WRAP_R,
  4704. get_texture_wrap_mode(sampler.get_wrap_w()));
  4705. #ifndef OPENGLES
  4706. #ifdef STDFLOAT_DOUBLE
  4707. LVecBase4f fvalue = LCAST(float, sampler.get_border_color());
  4708. _glSamplerParameterfv(index, GL_TEXTURE_BORDER_COLOR, fvalue.get_data());
  4709. #else
  4710. _glSamplerParameterfv(index, GL_TEXTURE_BORDER_COLOR,
  4711. sampler.get_border_color().get_data());
  4712. #endif
  4713. #endif // OPENGLES
  4714. SamplerState::FilterType minfilter = sampler.get_effective_minfilter();
  4715. SamplerState::FilterType magfilter = sampler.get_effective_magfilter();
  4716. bool uses_mipmaps = SamplerState::is_mipmap(minfilter) && !gl_ignore_mipmaps;
  4717. #ifndef NDEBUG
  4718. if (gl_force_mipmaps) {
  4719. minfilter = SamplerState::FT_linear_mipmap_linear;
  4720. magfilter = SamplerState::FT_linear;
  4721. uses_mipmaps = true;
  4722. }
  4723. #endif
  4724. _glSamplerParameteri(index, GL_TEXTURE_MIN_FILTER,
  4725. get_texture_filter_type(minfilter, !uses_mipmaps));
  4726. _glSamplerParameteri(index, GL_TEXTURE_MAG_FILTER,
  4727. get_texture_filter_type(magfilter, true));
  4728. // Set anisotropic filtering.
  4729. if (_supports_anisotropy) {
  4730. PN_stdfloat anisotropy = sampler.get_effective_anisotropic_degree();
  4731. anisotropy = min(anisotropy, _max_anisotropy);
  4732. anisotropy = max(anisotropy, (PN_stdfloat)1.0);
  4733. _glSamplerParameterf(index, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
  4734. }
  4735. if (_supports_shadow_filter) {
  4736. if ((sampler.get_magfilter() == SamplerState::FT_shadow) ||
  4737. (sampler.get_minfilter() == SamplerState::FT_shadow)) {
  4738. _glSamplerParameteri(index, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
  4739. _glSamplerParameteri(index, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
  4740. } else {
  4741. _glSamplerParameteri(index, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
  4742. _glSamplerParameteri(index, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
  4743. }
  4744. }
  4745. if (_supports_texture_lod) {
  4746. _glSamplerParameterf(index, GL_TEXTURE_MIN_LOD, sampler.get_min_lod());
  4747. _glSamplerParameterf(index, GL_TEXTURE_MAX_LOD, sampler.get_max_lod());
  4748. }
  4749. #ifndef OPENGLES
  4750. if (_supports_texture_lod_bias) {
  4751. _glSamplerParameterf(index, GL_TEXTURE_LOD_BIAS, sampler.get_lod_bias());
  4752. }
  4753. #endif
  4754. gsc->enqueue_lru(&_prepared_objects->_sampler_object_lru);
  4755. report_my_gl_errors();
  4756. return gsc;
  4757. }
  4758. #endif // !OPENGLES_1
  4759. #ifndef OPENGLES_1
  4760. /**
  4761. * Frees the GL resources previously allocated for the sampler. This function
  4762. * should never be called directly; instead, call SamplerState::release().
  4763. */
  4764. void CLP(GraphicsStateGuardian)::
  4765. release_sampler(SamplerContext *sc) {
  4766. CLP(SamplerContext) *gsc = DCAST(CLP(SamplerContext), sc);
  4767. if (gsc->_index != 0) {
  4768. _glDeleteSamplers(1, &gsc->_index);
  4769. }
  4770. delete gsc;
  4771. }
  4772. #endif // !OPENGLES_1
  4773. /**
  4774. * Creates a new retained-mode representation of the given geom, and returns a
  4775. * newly-allocated GeomContext pointer to reference it. It is the
  4776. * responsibility of the calling function to later call release_geom() with
  4777. * this same pointer (which will also delete the pointer).
  4778. *
  4779. * This function should not be called directly to prepare a geom. Instead,
  4780. * call Geom::prepare().
  4781. */
  4782. GeomContext *CLP(GraphicsStateGuardian)::
  4783. prepare_geom(Geom *geom) {
  4784. PStatGPUTimer timer(this, _prepare_geom_pcollector);
  4785. return new CLP(GeomContext)(geom);
  4786. }
  4787. /**
  4788. * Frees the GL resources previously allocated for the geom. This function
  4789. * should never be called directly; instead, call Geom::release() (or simply
  4790. * let the Geom destruct).
  4791. */
  4792. void CLP(GraphicsStateGuardian)::
  4793. release_geom(GeomContext *gc) {
  4794. CLP(GeomContext) *ggc = DCAST(CLP(GeomContext), gc);
  4795. ggc->release_display_lists();
  4796. report_my_gl_errors();
  4797. delete ggc;
  4798. }
  4799. /**
  4800. *
  4801. */
  4802. ShaderContext *CLP(GraphicsStateGuardian)::
  4803. prepare_shader(Shader *se) {
  4804. PStatGPUTimer timer(this, _prepare_shader_pcollector);
  4805. #ifndef OPENGLES_1
  4806. ShaderContext *result = NULL;
  4807. switch (se->get_language()) {
  4808. case Shader::SL_GLSL:
  4809. if (_supports_glsl) {
  4810. result = new CLP(ShaderContext)(this, se);
  4811. break;
  4812. } else {
  4813. GLCAT.error()
  4814. << "Tried to load GLSL shader, but GLSL shaders not supported.\n";
  4815. return NULL;
  4816. }
  4817. case Shader::SL_Cg:
  4818. #if defined(HAVE_CG) && !defined(OPENGLES)
  4819. if (_supports_basic_shaders) {
  4820. result = new CLP(CgShaderContext)(this, se);
  4821. break;
  4822. } else {
  4823. GLCAT.error()
  4824. << "Tried to load Cg shader, but basic shaders not supported.\n";
  4825. return NULL;
  4826. }
  4827. #elif defined(OPENGLES)
  4828. GLCAT.error()
  4829. << "Tried to load Cg shader, but Cg support is not available for OpenGL ES.\n";
  4830. return NULL;
  4831. #else
  4832. GLCAT.error()
  4833. << "Tried to load Cg shader, but Cg support not compiled in.\n";
  4834. return NULL;
  4835. #endif
  4836. default:
  4837. GLCAT.error()
  4838. << "Tried to load shader with unsupported shader language!\n";
  4839. return NULL;
  4840. }
  4841. if (result->valid()) {
  4842. return result;
  4843. }
  4844. delete result;
  4845. #endif // OPENGLES_1
  4846. return NULL;
  4847. }
  4848. /**
  4849. *
  4850. */
  4851. void CLP(GraphicsStateGuardian)::
  4852. release_shader(ShaderContext *sc) {
  4853. #ifndef OPENGLES_1
  4854. if (sc->is_of_type(CLP(ShaderContext)::get_class_type())) {
  4855. ((CLP(ShaderContext) *)sc)->release_resources();
  4856. }
  4857. #if defined(HAVE_CG) && !defined(OPENGLES_2)
  4858. else if (sc->is_of_type(CLP(CgShaderContext)::get_class_type())) {
  4859. ((CLP(CgShaderContext) *)sc)->release_resources();
  4860. }
  4861. #endif
  4862. #endif
  4863. delete sc;
  4864. }
  4865. /**
  4866. * This is intended to be called only from the GLGeomContext destructor. It
  4867. * saves the indicated display list index in the list to be deleted at the end
  4868. * of the frame.
  4869. */
  4870. void CLP(GraphicsStateGuardian)::
  4871. record_deleted_display_list(GLuint index) {
  4872. LightMutexHolder holder(_lock);
  4873. _deleted_display_lists.push_back(index);
  4874. }
  4875. /**
  4876. * Creates a new retained-mode representation of the given data, and returns a
  4877. * newly-allocated VertexBufferContext pointer to reference it. It is the
  4878. * responsibility of the calling function to later call
  4879. * release_vertex_buffer() with this same pointer (which will also delete the
  4880. * pointer).
  4881. *
  4882. * This function should not be called directly to prepare a buffer. Instead,
  4883. * call Geom::prepare().
  4884. */
  4885. VertexBufferContext *CLP(GraphicsStateGuardian)::
  4886. prepare_vertex_buffer(GeomVertexArrayData *data) {
  4887. if (_supports_buffers) {
  4888. PStatGPUTimer timer(this, _prepare_vertex_buffer_pcollector);
  4889. CLP(VertexBufferContext) *gvbc = new CLP(VertexBufferContext)(this, _prepared_objects, data);
  4890. _glGenBuffers(1, &gvbc->_index);
  4891. if (GLCAT.is_debug() && gl_debug_buffers) {
  4892. GLCAT.debug()
  4893. << "creating vertex buffer " << (int)gvbc->_index << ": "
  4894. << data->get_num_rows() << " vertices "
  4895. << *data->get_array_format() << "\n";
  4896. }
  4897. report_my_gl_errors();
  4898. update_vertex_buffer(gvbc, data->get_handle(), false);
  4899. return gvbc;
  4900. }
  4901. return NULL;
  4902. }
  4903. /**
  4904. * Makes sure that the data in the vertex buffer is up-to-date. This may bind
  4905. * it to the GL_ARRAY_BUFFER binding point if necessary.
  4906. */
  4907. bool CLP(GraphicsStateGuardian)::
  4908. update_vertex_buffer(CLP(VertexBufferContext) *gvbc,
  4909. const GeomVertexArrayDataHandle *reader, bool force) {
  4910. nassertr(_supports_buffers, false);
  4911. if (reader->get_modified() == UpdateSeq::initial()) {
  4912. // No need to re-apply.
  4913. return true;
  4914. }
  4915. gvbc->set_active(true);
  4916. if (gvbc->was_modified(reader)) {
  4917. int num_bytes = reader->get_data_size_bytes();
  4918. if (GLCAT.is_debug() && gl_debug_buffers) {
  4919. GLCAT.debug()
  4920. << "copying " << num_bytes
  4921. << " bytes into vertex buffer " << (int)gvbc->_index << "\n";
  4922. }
  4923. if (num_bytes != 0) {
  4924. const unsigned char *client_pointer = reader->get_read_pointer(force);
  4925. if (client_pointer == NULL) {
  4926. return false;
  4927. }
  4928. PStatGPUTimer timer(this, _load_vertex_buffer_pcollector, reader->get_current_thread());
  4929. if (_current_vbuffer_index != gvbc->_index) {
  4930. if (GLCAT.is_spam() && gl_debug_buffers) {
  4931. GLCAT.spam()
  4932. << "binding vertex buffer " << (int)gvbc->_index << "\n";
  4933. }
  4934. _glBindBuffer(GL_ARRAY_BUFFER, gvbc->_index);
  4935. _current_vbuffer_index = gvbc->_index;
  4936. }
  4937. if (gvbc->changed_size(reader) || gvbc->changed_usage_hint(reader)) {
  4938. _glBufferData(GL_ARRAY_BUFFER, num_bytes, client_pointer,
  4939. get_usage(reader->get_usage_hint()));
  4940. } else {
  4941. _glBufferSubData(GL_ARRAY_BUFFER, 0, num_bytes, client_pointer);
  4942. }
  4943. _data_transferred_pcollector.add_level(num_bytes);
  4944. }
  4945. gvbc->mark_loaded(reader);
  4946. }
  4947. gvbc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  4948. maybe_gl_finish();
  4949. report_my_gl_errors();
  4950. return true;
  4951. }
  4952. /**
  4953. * Frees the GL resources previously allocated for the data. This function
  4954. * should never be called directly; instead, call Data::release() (or simply
  4955. * let the Data destruct).
  4956. */
  4957. void CLP(GraphicsStateGuardian)::
  4958. release_vertex_buffer(VertexBufferContext *vbc) {
  4959. nassertv(_supports_buffers);
  4960. CLP(VertexBufferContext) *gvbc = DCAST(CLP(VertexBufferContext), vbc);
  4961. if (GLCAT.is_debug() && gl_debug_buffers) {
  4962. GLCAT.debug()
  4963. << "deleting vertex buffer " << (int)gvbc->_index << "\n";
  4964. }
  4965. // Make sure the buffer is unbound before we delete it. Not strictly
  4966. // necessary according to the OpenGL spec, but it might help out a flaky
  4967. // driver, and we need to keep our internal state consistent anyway.
  4968. if (_current_vbuffer_index == gvbc->_index) {
  4969. if (GLCAT.is_spam() && gl_debug_buffers) {
  4970. GLCAT.spam()
  4971. << "unbinding vertex buffer\n";
  4972. }
  4973. _glBindBuffer(GL_ARRAY_BUFFER, 0);
  4974. _current_vbuffer_index = 0;
  4975. }
  4976. _glDeleteBuffers(1, &gvbc->_index);
  4977. report_my_gl_errors();
  4978. gvbc->_index = 0;
  4979. delete gvbc;
  4980. }
  4981. /**
  4982. * Internal function to bind a buffer object for the indicated data array, if
  4983. * appropriate, or to unbind a buffer object if it should be rendered from
  4984. * client memory.
  4985. *
  4986. * If the buffer object is bound, this function sets client_pointer to NULL
  4987. * (representing the start of the buffer object in server memory); if the
  4988. * buffer object is not bound, this function sets client_pointer the pointer
  4989. * to the data array in client memory, that is, the data array passed in.
  4990. *
  4991. * If force is not true, the function may return false indicating the data is
  4992. * not currently available.
  4993. */
  4994. bool CLP(GraphicsStateGuardian)::
  4995. setup_array_data(const unsigned char *&client_pointer,
  4996. const GeomVertexArrayDataHandle *array_reader,
  4997. bool force) {
  4998. if (!_supports_buffers) {
  4999. // No support for buffer objects; always render from client.
  5000. client_pointer = array_reader->get_read_pointer(force);
  5001. return (client_pointer != NULL);
  5002. }
  5003. if (!vertex_buffers || _geom_display_list != 0 ||
  5004. array_reader->get_usage_hint() < gl_min_buffer_usage_hint) {
  5005. // The array specifies client rendering only, or buffer objects are
  5006. // configured off.
  5007. if (_current_vbuffer_index != 0) {
  5008. if (GLCAT.is_spam() && gl_debug_buffers) {
  5009. GLCAT.spam()
  5010. << "unbinding vertex buffer\n";
  5011. }
  5012. _glBindBuffer(GL_ARRAY_BUFFER, 0);
  5013. _current_vbuffer_index = 0;
  5014. }
  5015. client_pointer = array_reader->get_read_pointer(force);
  5016. return (client_pointer != NULL);
  5017. }
  5018. // Prepare the buffer object and bind it.
  5019. CLP(VertexBufferContext) *gvbc = DCAST(CLP(VertexBufferContext),
  5020. array_reader->prepare_now(get_prepared_objects(), this));
  5021. nassertr(gvbc != (CLP(VertexBufferContext) *)NULL, false);
  5022. if (!update_vertex_buffer(gvbc, array_reader, force)) {
  5023. return false;
  5024. }
  5025. if (_current_vbuffer_index != gvbc->_index) {
  5026. if (GLCAT.is_spam() && gl_debug_buffers) {
  5027. GLCAT.spam()
  5028. << "binding vertex buffer " << (int)gvbc->_index << "\n";
  5029. }
  5030. _glBindBuffer(GL_ARRAY_BUFFER, gvbc->_index);
  5031. _current_vbuffer_index = gvbc->_index;
  5032. }
  5033. // NULL is the OpenGL convention for the first byte of the buffer object.
  5034. client_pointer = NULL;
  5035. return true;
  5036. }
  5037. /**
  5038. * Creates a new retained-mode representation of the given data, and returns a
  5039. * newly-allocated IndexBufferContext pointer to reference it. It is the
  5040. * responsibility of the calling function to later call release_index_buffer()
  5041. * with this same pointer (which will also delete the pointer).
  5042. *
  5043. * This function should not be called directly to prepare a buffer. Instead,
  5044. * call Geom::prepare().
  5045. */
  5046. IndexBufferContext *CLP(GraphicsStateGuardian)::
  5047. prepare_index_buffer(GeomPrimitive *data) {
  5048. if (_supports_buffers) {
  5049. PStatGPUTimer timer(this, _prepare_index_buffer_pcollector);
  5050. CLP(IndexBufferContext) *gibc = new CLP(IndexBufferContext)(this, _prepared_objects, data);
  5051. _glGenBuffers(1, &gibc->_index);
  5052. if (GLCAT.is_debug() && gl_debug_buffers) {
  5053. GLCAT.debug()
  5054. << "creating index buffer " << (int)gibc->_index << ": "
  5055. << data->get_num_vertices() << " indices ("
  5056. << data->get_vertices()->get_array_format()->get_column(0)->get_numeric_type()
  5057. << ")\n";
  5058. }
  5059. report_my_gl_errors();
  5060. GeomPrimitivePipelineReader reader(data, Thread::get_current_thread());
  5061. apply_index_buffer(gibc, &reader, false);
  5062. return gibc;
  5063. }
  5064. return NULL;
  5065. }
  5066. /**
  5067. * Makes the data the currently available data for rendering.
  5068. */
  5069. bool CLP(GraphicsStateGuardian)::
  5070. apply_index_buffer(IndexBufferContext *ibc,
  5071. const GeomPrimitivePipelineReader *reader,
  5072. bool force) {
  5073. nassertr(_supports_buffers, false);
  5074. if (reader->get_modified() == UpdateSeq::initial()) {
  5075. // No need to re-apply.
  5076. return true;
  5077. }
  5078. CLP(IndexBufferContext) *gibc = DCAST(CLP(IndexBufferContext), ibc);
  5079. if (_current_ibuffer_index != gibc->_index) {
  5080. if (GLCAT.is_spam() && gl_debug_buffers) {
  5081. GLCAT.spam()
  5082. << "binding index buffer " << (int)gibc->_index << "\n";
  5083. }
  5084. _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gibc->_index);
  5085. _current_ibuffer_index = gibc->_index;
  5086. gibc->set_active(true);
  5087. }
  5088. if (gibc->was_modified(reader)) {
  5089. int num_bytes = reader->get_data_size_bytes();
  5090. if (GLCAT.is_debug() && gl_debug_buffers) {
  5091. GLCAT.debug()
  5092. << "copying " << num_bytes
  5093. << " bytes into index buffer " << (int)gibc->_index << "\n";
  5094. }
  5095. if (num_bytes != 0) {
  5096. const unsigned char *client_pointer = reader->get_read_pointer(force);
  5097. if (client_pointer == NULL) {
  5098. return false;
  5099. }
  5100. PStatGPUTimer timer(this, _load_index_buffer_pcollector, reader->get_current_thread());
  5101. if (gibc->changed_size(reader) || gibc->changed_usage_hint(reader)) {
  5102. _glBufferData(GL_ELEMENT_ARRAY_BUFFER, num_bytes, client_pointer,
  5103. get_usage(reader->get_usage_hint()));
  5104. } else {
  5105. _glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, num_bytes,
  5106. client_pointer);
  5107. }
  5108. _data_transferred_pcollector.add_level(num_bytes);
  5109. }
  5110. gibc->mark_loaded(reader);
  5111. }
  5112. gibc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  5113. maybe_gl_finish();
  5114. report_my_gl_errors();
  5115. return true;
  5116. }
  5117. /**
  5118. * Frees the GL resources previously allocated for the data. This function
  5119. * should never be called directly; instead, call Data::release() (or simply
  5120. * let the Data destruct).
  5121. */
  5122. void CLP(GraphicsStateGuardian)::
  5123. release_index_buffer(IndexBufferContext *ibc) {
  5124. nassertv(_supports_buffers);
  5125. CLP(IndexBufferContext) *gibc = DCAST(CLP(IndexBufferContext), ibc);
  5126. if (GLCAT.is_debug() && gl_debug_buffers) {
  5127. GLCAT.debug()
  5128. << "deleting index buffer " << (int)gibc->_index << "\n";
  5129. }
  5130. // Make sure the buffer is unbound before we delete it. Not strictly
  5131. // necessary according to the OpenGL spec, but it might help out a flaky
  5132. // driver, and we need to keep our internal state consistent anyway.
  5133. if (_current_ibuffer_index == gibc->_index) {
  5134. if (GLCAT.is_spam() && gl_debug_buffers) {
  5135. GLCAT.spam()
  5136. << "unbinding index buffer\n";
  5137. }
  5138. _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  5139. _current_ibuffer_index = 0;
  5140. }
  5141. _glDeleteBuffers(1, &gibc->_index);
  5142. report_my_gl_errors();
  5143. gibc->_index = 0;
  5144. delete gibc;
  5145. }
  5146. /**
  5147. * Internal function to bind a buffer object for the indicated primitive's
  5148. * index list, if appropriate, or to unbind a buffer object if it should be
  5149. * rendered from client memory.
  5150. *
  5151. * If the buffer object is bound, this function sets client_pointer to NULL
  5152. * (representing the start of the buffer object in server memory); if the
  5153. * buffer object is not bound, this function sets client_pointer to to the
  5154. * data array in client memory, that is, the data array passed in.
  5155. *
  5156. * If force is not true, the function may return false indicating the data is
  5157. * not currently available.
  5158. */
  5159. bool CLP(GraphicsStateGuardian)::
  5160. setup_primitive(const unsigned char *&client_pointer,
  5161. const GeomPrimitivePipelineReader *reader,
  5162. bool force) {
  5163. if (!_supports_buffers) {
  5164. // No support for buffer objects; always render from client.
  5165. client_pointer = reader->get_read_pointer(force);
  5166. return (client_pointer != NULL);
  5167. }
  5168. if (!vertex_buffers || _geom_display_list != 0 ||
  5169. reader->get_usage_hint() == Geom::UH_client) {
  5170. // The array specifies client rendering only, or buffer objects are
  5171. // configured off.
  5172. if (_current_ibuffer_index != 0) {
  5173. if (GLCAT.is_spam() && gl_debug_buffers) {
  5174. GLCAT.spam()
  5175. << "unbinding index buffer\n";
  5176. }
  5177. _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  5178. _current_ibuffer_index = 0;
  5179. }
  5180. client_pointer = reader->get_read_pointer(force);
  5181. return (client_pointer != NULL);
  5182. }
  5183. // Prepare the buffer object and bind it.
  5184. IndexBufferContext *ibc = reader->prepare_now(get_prepared_objects(), this);
  5185. nassertr(ibc != (IndexBufferContext *)NULL, false);
  5186. if (!apply_index_buffer(ibc, reader, force)) {
  5187. return false;
  5188. }
  5189. // NULL is the OpenGL convention for the first byte of the buffer object.
  5190. client_pointer = NULL;
  5191. return true;
  5192. }
  5193. #ifndef OPENGLES
  5194. /**
  5195. * Begins a new occlusion query. After this call, you may call
  5196. * begin_draw_primitives() and draw_triangles()/draw_whatever() repeatedly.
  5197. * Eventually, you should call end_occlusion_query() before the end of the
  5198. * frame; that will return a new OcclusionQueryContext object that will tell
  5199. * you how many pixels represented by the bracketed geometry passed the depth
  5200. * test.
  5201. *
  5202. * It is not valid to call begin_occlusion_query() between another
  5203. * begin_occlusion_query() .. end_occlusion_query() sequence.
  5204. */
  5205. void CLP(GraphicsStateGuardian)::
  5206. begin_occlusion_query() {
  5207. nassertv(_supports_occlusion_query);
  5208. nassertv(_current_occlusion_query == (OcclusionQueryContext *)NULL);
  5209. PT(CLP(OcclusionQueryContext)) query = new CLP(OcclusionQueryContext)(this);
  5210. _glGenQueries(1, &query->_index);
  5211. if (GLCAT.is_debug()) {
  5212. GLCAT.debug()
  5213. << "beginning occlusion query index " << (int)query->_index << "\n";
  5214. }
  5215. _glBeginQuery(GL_SAMPLES_PASSED, query->_index);
  5216. _current_occlusion_query = query;
  5217. report_my_gl_errors();
  5218. }
  5219. #endif // !OPENGLES
  5220. #ifndef OPENGLES
  5221. /**
  5222. * Ends a previous call to begin_occlusion_query(). This call returns the
  5223. * OcclusionQueryContext object that will (eventually) report the number of
  5224. * pixels that passed the depth test between the call to
  5225. * begin_occlusion_query() and end_occlusion_query().
  5226. */
  5227. PT(OcclusionQueryContext) CLP(GraphicsStateGuardian)::
  5228. end_occlusion_query() {
  5229. nassertr(_current_occlusion_query != (OcclusionQueryContext *)NULL, NULL);
  5230. PT(OcclusionQueryContext) result = _current_occlusion_query;
  5231. GLuint index = DCAST(CLP(OcclusionQueryContext), result)->_index;
  5232. if (GLCAT.is_debug()) {
  5233. GLCAT.debug()
  5234. << "ending occlusion query index " << (int)index << "\n";
  5235. }
  5236. _current_occlusion_query = NULL;
  5237. _glEndQuery(GL_SAMPLES_PASSED);
  5238. // Temporary hack to try working around an apparent driver bug on iMacs.
  5239. // Occlusion queries sometimes incorrectly report 0 samples, unless we stall
  5240. // the pipe to keep fewer than a certain maximum number of queries pending
  5241. // at once.
  5242. static ConfigVariableInt limit_occlusion_queries("limit-occlusion-queries", 0);
  5243. if (limit_occlusion_queries > 0) {
  5244. if (index > (unsigned int)limit_occlusion_queries) {
  5245. PStatGPUTimer timer(this, _wait_occlusion_pcollector);
  5246. GLuint result;
  5247. _glGetQueryObjectuiv(index - (unsigned int)limit_occlusion_queries,
  5248. GL_QUERY_RESULT, &result);
  5249. }
  5250. }
  5251. report_my_gl_errors();
  5252. return result;
  5253. }
  5254. #endif // !OPENGLES
  5255. /**
  5256. * Adds a timer query to the command stream, associated with the given PStats
  5257. * collector index.
  5258. */
  5259. PT(TimerQueryContext) CLP(GraphicsStateGuardian)::
  5260. issue_timer_query(int pstats_index) {
  5261. #if defined(DO_PSTATS) && !defined(OPENGLES)
  5262. nassertr(_supports_timer_query, NULL);
  5263. PT(CLP(TimerQueryContext)) query;
  5264. // Hack
  5265. if (pstats_index == _command_latency_pcollector.get_index()) {
  5266. query = new CLP(LatencyQueryContext)(this, pstats_index);
  5267. } else {
  5268. query = new CLP(TimerQueryContext)(this, pstats_index);
  5269. }
  5270. if (_deleted_queries.size() >= 1) {
  5271. query->_index = _deleted_queries.back();
  5272. _deleted_queries.pop_back();
  5273. } else {
  5274. _glGenQueries(1, &query->_index);
  5275. if (GLCAT.is_spam()) {
  5276. GLCAT.spam() << "Generating query for " << pstats_index
  5277. << ": " << query->_index << "\n";
  5278. }
  5279. }
  5280. // Issue the timestamp query.
  5281. _glQueryCounter(query->_index, GL_TIMESTAMP);
  5282. if (_use_object_labels) {
  5283. // Assign a label to it based on the PStatCollector name.
  5284. const PStatClient *client = PStatClient::get_global_pstats();
  5285. string name = client->get_collector_fullname(pstats_index & 0x7fff);
  5286. _glObjectLabel(GL_QUERY, query->_index, name.size(), name.data());
  5287. }
  5288. _pending_timer_queries.push_back((TimerQueryContext *)query);
  5289. return (TimerQueryContext *)query;
  5290. #else
  5291. return NULL;
  5292. #endif
  5293. }
  5294. #ifndef OPENGLES_1
  5295. /**
  5296. * Dispatches a currently bound compute shader using the given work group
  5297. * counts.
  5298. */
  5299. void CLP(GraphicsStateGuardian)::
  5300. dispatch_compute(int num_groups_x, int num_groups_y, int num_groups_z) {
  5301. maybe_gl_finish();
  5302. PStatGPUTimer timer(this, _compute_dispatch_pcollector);
  5303. nassertv(_supports_compute_shaders);
  5304. nassertv(_current_shader_context != NULL);
  5305. _glDispatchCompute(num_groups_x, num_groups_y, num_groups_z);
  5306. maybe_gl_finish();
  5307. }
  5308. #endif // !OPENGLES_1
  5309. /**
  5310. * Creates a new GeomMunger object to munge vertices appropriate to this GSG
  5311. * for the indicated state.
  5312. */
  5313. PT(GeomMunger) CLP(GraphicsStateGuardian)::
  5314. make_geom_munger(const RenderState *state, Thread *current_thread) {
  5315. PT(CLP(GeomMunger)) munger = new CLP(GeomMunger)(this, state);
  5316. return GeomMunger::register_munger(munger, current_thread);
  5317. }
  5318. /**
  5319. * This function will compute the distance to the indicated point, assumed to
  5320. * be in eye coordinates, from the camera plane. The point is assumed to be
  5321. * in the GSG's internal coordinate system.
  5322. */
  5323. PN_stdfloat CLP(GraphicsStateGuardian)::
  5324. compute_distance_to(const LPoint3 &point) const {
  5325. return -point[2];
  5326. }
  5327. /**
  5328. * Copy the pixels within the indicated display region from the framebuffer
  5329. * into texture memory.
  5330. *
  5331. * If z > -1, it is the cube map index or layer index into which to copy.
  5332. */
  5333. bool CLP(GraphicsStateGuardian)::
  5334. framebuffer_copy_to_texture(Texture *tex, int view, int z,
  5335. const DisplayRegion *dr, const RenderBuffer &rb) {
  5336. nassertr(tex != NULL && dr != NULL, false);
  5337. set_read_buffer(rb._buffer_type);
  5338. clear_color_write_mask();
  5339. int xo, yo, w, h;
  5340. dr->get_region_pixels(xo, yo, w, h);
  5341. tex->set_size_padded(w, h, tex->get_z_size());
  5342. if (tex->get_compression() == Texture::CM_default) {
  5343. // Unless the user explicitly turned on texture compression, turn it off
  5344. // for the copy-to-texture case.
  5345. tex->set_compression(Texture::CM_off);
  5346. }
  5347. // Sanity check everything.
  5348. if (z >= 0) {
  5349. if (z >= tex->get_z_size()) {
  5350. // This can happen, when textures with different layer counts are
  5351. // attached to a buffer. We simply ignore this if it happens.
  5352. return false;
  5353. }
  5354. if ((w != tex->get_x_size()) ||
  5355. (h != tex->get_y_size())) {
  5356. return false;
  5357. }
  5358. if (tex->get_texture_type() == Texture::TT_cube_map) {
  5359. if (!_supports_cube_map) {
  5360. return false;
  5361. }
  5362. nassertr(z < 6, false);
  5363. if (w != h) {
  5364. return false;
  5365. }
  5366. } else if (tex->get_texture_type() == Texture::TT_3d_texture) {
  5367. if (!_supports_3d_texture) {
  5368. return false;
  5369. }
  5370. } else if (tex->get_texture_type() == Texture::TT_2d_texture_array) {
  5371. if (!_supports_2d_texture_array) {
  5372. return false;
  5373. }
  5374. } else {
  5375. GLCAT.error()
  5376. << "Don't know how to copy framebuffer to texture " << *tex << "\n";
  5377. }
  5378. } else {
  5379. nassertr(tex->get_texture_type() == Texture::TT_2d_texture, false);
  5380. }
  5381. // Match framebuffer format if necessary.
  5382. if (tex->get_match_framebuffer_format()) {
  5383. switch (tex->get_format()) {
  5384. case Texture::F_depth_component:
  5385. case Texture::F_depth_component16:
  5386. case Texture::F_depth_component24:
  5387. case Texture::F_depth_component32:
  5388. case Texture::F_depth_stencil:
  5389. // Don't remap if we're one of these special format.
  5390. break;
  5391. default:
  5392. // If the texture is a color format, we want to match the presence of
  5393. // sRGB and alpha according to the framebuffer.
  5394. if (_current_properties->get_srgb_color()) {
  5395. if (_current_properties->get_alpha_bits()) {
  5396. tex->set_format(Texture::F_srgb_alpha);
  5397. } else {
  5398. tex->set_format(Texture::F_srgb);
  5399. }
  5400. } else {
  5401. if (_current_properties->get_alpha_bits()) {
  5402. tex->set_format(Texture::F_rgba);
  5403. } else {
  5404. tex->set_format(Texture::F_rgb);
  5405. }
  5406. }
  5407. }
  5408. }
  5409. TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this);
  5410. nassertr(tc != (TextureContext *)NULL, false);
  5411. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
  5412. apply_texture(gtc);
  5413. bool needs_reload = specify_texture(gtc, tex->get_default_sampler());
  5414. GLenum target = get_texture_target(tex->get_texture_type());
  5415. GLint internal_format = get_internal_image_format(tex);
  5416. int width = tex->get_x_size();
  5417. int height = tex->get_y_size();
  5418. int depth = tex->get_z_size();
  5419. bool uses_mipmaps = tex->uses_mipmaps() && !gl_ignore_mipmaps;
  5420. if (uses_mipmaps) {
  5421. if (_supports_generate_mipmap) {
  5422. #ifndef OPENGLES_2
  5423. if (_glGenerateMipmap == NULL) {
  5424. glTexParameteri(target, GL_GENERATE_MIPMAP, true);
  5425. }
  5426. #endif
  5427. } else {
  5428. // If we can't auto-generate mipmaps, do without mipmaps.
  5429. glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  5430. uses_mipmaps = false;
  5431. }
  5432. }
  5433. bool new_image = needs_reload || gtc->was_image_modified();
  5434. if (z >= 0) {
  5435. if (target == GL_TEXTURE_CUBE_MAP) {
  5436. // Copy to a cube map face, which is treated as a 2D texture.
  5437. target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + z;
  5438. depth = 1;
  5439. z = -1;
  5440. // Cube map faces seem to have trouble with CopyTexSubImage, so we
  5441. // always reload the image.
  5442. new_image = true;
  5443. }
  5444. }
  5445. if (!gtc->_has_storage ||
  5446. internal_format != gtc->_internal_format ||
  5447. uses_mipmaps != gtc->_uses_mipmaps ||
  5448. width != gtc->_width ||
  5449. height != gtc->_height ||
  5450. depth != gtc->_depth) {
  5451. // If the texture properties have changed, we need to reload the image.
  5452. new_image = true;
  5453. }
  5454. if (new_image && gtc->_immutable) {
  5455. gtc->reset_data();
  5456. glBindTexture(target, gtc->_index);
  5457. if (GLCAT.is_spam()) {
  5458. GLCAT.spam()
  5459. << "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << ")\n";
  5460. }
  5461. }
  5462. #ifndef OPENGLES_1
  5463. if (gtc->needs_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT)) {
  5464. // Make sure that any incoherent writes to this texture have been synced.
  5465. issue_memory_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
  5466. }
  5467. #endif
  5468. if (z >= 0) {
  5469. #ifndef OPENGLES_1
  5470. if (new_image) {
  5471. // These won't be used because we pass a NULL image, but we still have
  5472. // to specify them. Might as well use the actual values.
  5473. GLint external_format = get_external_image_format(tex);
  5474. GLint component_type = get_component_type(tex->get_component_type());
  5475. _glTexImage3D(target, 0, internal_format, width, height, depth, 0, external_format, component_type, NULL);
  5476. }
  5477. _glCopyTexSubImage3D(target, 0, 0, 0, z, xo, yo, w, h);
  5478. #endif
  5479. } else {
  5480. if (new_image) {
  5481. // We have to create a new image. It seems that OpenGL accepts a size
  5482. // higher than the framebuffer, but if we run into trouble we'll have to
  5483. // replace this with something smarter.
  5484. glCopyTexImage2D(target, 0, internal_format, xo, yo, width, height, 0);
  5485. } else {
  5486. // We can overlay the existing image.
  5487. glCopyTexSubImage2D(target, 0, 0, 0, xo, yo, w, h);
  5488. }
  5489. }
  5490. if (uses_mipmaps && _glGenerateMipmap != NULL) {
  5491. glEnable(target);
  5492. _glGenerateMipmap(target);
  5493. glDisable(target);
  5494. }
  5495. gtc->_has_storage = true;
  5496. gtc->_uses_mipmaps = uses_mipmaps;
  5497. gtc->_internal_format = internal_format;
  5498. gtc->_width = width;
  5499. gtc->_height = height;
  5500. gtc->_depth = depth;
  5501. gtc->mark_loaded();
  5502. gtc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  5503. report_my_gl_errors();
  5504. // Force reload of texture state, since we've just monkeyed with it.
  5505. _state_mask.clear_bit(TextureAttrib::get_class_slot());
  5506. return true;
  5507. }
  5508. /**
  5509. * Copy the pixels within the indicated display region from the framebuffer
  5510. * into system memory, not texture memory. Returns true on success, false on
  5511. * failure.
  5512. *
  5513. * This completely redefines the ram image of the indicated texture.
  5514. */
  5515. bool CLP(GraphicsStateGuardian)::
  5516. framebuffer_copy_to_ram(Texture *tex, int view, int z,
  5517. const DisplayRegion *dr, const RenderBuffer &rb) {
  5518. nassertr(tex != NULL && dr != NULL, false);
  5519. set_read_buffer(rb._buffer_type);
  5520. glPixelStorei(GL_PACK_ALIGNMENT, 1);
  5521. clear_color_write_mask();
  5522. // Bug fix for RE, RE2, and VTX - need to disable texturing in order for
  5523. // glReadPixels() to work NOTE: reading the depth buffer is *much* slower
  5524. // than reading the color buffer
  5525. set_state_and_transform(RenderState::make_empty(), _internal_transform);
  5526. int xo, yo, w, h;
  5527. dr->get_region_pixels(xo, yo, w, h);
  5528. Texture::ComponentType component_type = tex->get_component_type();
  5529. Texture::Format format = tex->get_format();
  5530. switch (format) {
  5531. case Texture::F_depth_stencil:
  5532. if (_current_properties->get_float_depth()) {
  5533. component_type = Texture::T_float;
  5534. } else {
  5535. component_type = Texture::T_unsigned_int_24_8;
  5536. }
  5537. break;
  5538. case Texture::F_depth_component:
  5539. if (_current_properties->get_float_depth()) {
  5540. component_type = Texture::T_float;
  5541. } else if (_current_properties->get_depth_bits() <= 8) {
  5542. component_type = Texture::T_unsigned_byte;
  5543. } else if (_current_properties->get_depth_bits() <= 16) {
  5544. component_type = Texture::T_unsigned_short;
  5545. } else {
  5546. component_type = Texture::T_float;
  5547. }
  5548. break;
  5549. default:
  5550. if (_current_properties->get_srgb_color()) {
  5551. if (_current_properties->get_alpha_bits()) {
  5552. format = Texture::F_srgb_alpha;
  5553. } else {
  5554. format = Texture::F_srgb;
  5555. }
  5556. } else {
  5557. if (_current_properties->get_alpha_bits()) {
  5558. format = Texture::F_rgba;
  5559. } else {
  5560. format = Texture::F_rgb;
  5561. }
  5562. }
  5563. if (_current_properties->get_float_color()) {
  5564. component_type = Texture::T_float;
  5565. } else if (_current_properties->get_color_bits() <= 24) {
  5566. component_type = Texture::T_unsigned_byte;
  5567. } else {
  5568. component_type = Texture::T_unsigned_short;
  5569. }
  5570. }
  5571. Texture::TextureType texture_type;
  5572. int z_size;
  5573. // TODO: should be extended to support 3D textures, 2D arrays and cube map
  5574. // arrays.
  5575. if (z >= 0) {
  5576. texture_type = Texture::TT_cube_map;
  5577. z_size = 6;
  5578. } else {
  5579. texture_type = Texture::TT_2d_texture;
  5580. z_size = 1;
  5581. }
  5582. if (tex->get_x_size() != w || tex->get_y_size() != h ||
  5583. tex->get_z_size() != z_size ||
  5584. tex->get_component_type() != component_type ||
  5585. tex->get_format() != format ||
  5586. tex->get_texture_type() != texture_type) {
  5587. // Re-setup the texture; its properties have changed.
  5588. tex->setup_texture(texture_type, w, h, z_size,
  5589. component_type, format);
  5590. }
  5591. nassertr(z < tex->get_z_size(), false);
  5592. GLenum external_format = get_external_image_format(tex);
  5593. if (GLCAT.is_spam()) {
  5594. GLCAT.spam()
  5595. << "glReadPixels(" << xo << ", " << yo << ", " << w << ", " << h << ", ";
  5596. switch (external_format) {
  5597. case GL_DEPTH_COMPONENT:
  5598. GLCAT.spam(false) << "GL_DEPTH_COMPONENT, ";
  5599. break;
  5600. case GL_DEPTH_STENCIL:
  5601. GLCAT.spam(false) << "GL_DEPTH_STENCIL, ";
  5602. break;
  5603. #ifndef OPENGLES_1
  5604. case GL_RG:
  5605. GLCAT.spam(false) << "GL_RG, ";
  5606. break;
  5607. #endif
  5608. case GL_RGB:
  5609. GLCAT.spam(false) << "GL_RGB, ";
  5610. break;
  5611. case GL_RGBA:
  5612. GLCAT.spam(false) << "GL_RGBA, ";
  5613. break;
  5614. #ifndef OPENGLES
  5615. case GL_BGR:
  5616. GLCAT.spam(false) << "GL_BGR, ";
  5617. break;
  5618. #endif
  5619. case GL_BGRA:
  5620. GLCAT.spam(false) << "GL_BGRA, ";
  5621. break;
  5622. default:
  5623. GLCAT.spam(false) << "unknown, ";
  5624. break;
  5625. }
  5626. switch (get_component_type(component_type)) {
  5627. case GL_UNSIGNED_BYTE:
  5628. GLCAT.spam(false) << "GL_UNSIGNED_BYTE";
  5629. break;
  5630. case GL_UNSIGNED_SHORT:
  5631. GLCAT.spam(false) << "GL_UNSIGNED_SHORT";
  5632. break;
  5633. case GL_FLOAT:
  5634. GLCAT.spam(false) << "GL_FLOAT";
  5635. break;
  5636. #ifndef OPENGLES_1
  5637. case GL_INT:
  5638. GLCAT.spam(false) << "GL_INT";
  5639. break;
  5640. #endif
  5641. default:
  5642. GLCAT.spam(false) << "unknown";
  5643. break;
  5644. }
  5645. GLCAT.spam(false)
  5646. << ")" << endl;
  5647. }
  5648. unsigned char *image_ptr = tex->modify_ram_image();
  5649. size_t image_size = tex->get_ram_image_size();
  5650. if (z >= 0 || view > 0) {
  5651. image_size = tex->get_expected_ram_page_size();
  5652. if (z >= 0) {
  5653. image_ptr += z * image_size;
  5654. }
  5655. if (view > 0) {
  5656. image_ptr += (view * tex->get_z_size()) * image_size;
  5657. }
  5658. }
  5659. glReadPixels(xo, yo, w, h, external_format,
  5660. get_component_type(component_type), image_ptr);
  5661. // We may have to reverse the byte ordering of the image if GL didn't do it
  5662. // for us.
  5663. if (external_format == GL_RGBA || external_format == GL_RGB) {
  5664. PTA_uchar new_image;
  5665. const unsigned char *result =
  5666. fix_component_ordering(new_image, image_ptr, image_size,
  5667. external_format, tex);
  5668. if (result != image_ptr) {
  5669. memcpy(image_ptr, result, image_size);
  5670. }
  5671. }
  5672. report_my_gl_errors();
  5673. return true;
  5674. }
  5675. #ifdef SUPPORT_FIXED_FUNCTION
  5676. /**
  5677. *
  5678. */
  5679. void CLP(GraphicsStateGuardian)::
  5680. apply_fog(Fog *fog) {
  5681. Fog::Mode fmode = fog->get_mode();
  5682. glFogf(GL_FOG_MODE, get_fog_mode_type(fmode));
  5683. if (fmode == Fog::M_linear) {
  5684. PN_stdfloat onset, opaque;
  5685. fog->get_linear_range(onset, opaque);
  5686. glFogf(GL_FOG_START, onset);
  5687. glFogf(GL_FOG_END, opaque);
  5688. } else {
  5689. // Exponential fog is always camera-relative.
  5690. glFogf(GL_FOG_DENSITY, fog->get_exp_density());
  5691. }
  5692. call_glFogfv(GL_FOG_COLOR, fog->get_color());
  5693. report_my_gl_errors();
  5694. }
  5695. #endif // SUPPORT_FIXED_FUNCTION
  5696. /**
  5697. * Sends the indicated transform matrix to the graphics API to be applied to
  5698. * future vertices.
  5699. *
  5700. * This transform is the internal_transform, already converted into the GSG's
  5701. * internal coordinate system.
  5702. */
  5703. void CLP(GraphicsStateGuardian)::
  5704. do_issue_transform() {
  5705. #ifdef SUPPORT_FIXED_FUNCTION
  5706. // OpenGL ES 2 does not support glLoadMatrix.
  5707. const TransformState *transform = _internal_transform;
  5708. if (GLCAT.is_spam()) {
  5709. GLCAT.spam()
  5710. << "glLoadMatrix(GL_MODELVIEW): " << transform->get_mat() << endl;
  5711. }
  5712. DO_PSTATS_STUFF(_transform_state_pcollector.add_level(1));
  5713. glMatrixMode(GL_MODELVIEW);
  5714. call_glLoadMatrix(transform->get_mat());
  5715. #endif
  5716. _transform_stale = false;
  5717. report_my_gl_errors();
  5718. }
  5719. #ifdef SUPPORT_FIXED_FUNCTION
  5720. /**
  5721. *
  5722. */
  5723. void CLP(GraphicsStateGuardian)::
  5724. do_issue_shade_model() {
  5725. const ShadeModelAttrib *target_shade_model;
  5726. _target_rs->get_attrib_def(target_shade_model);
  5727. switch (target_shade_model->get_mode()) {
  5728. case ShadeModelAttrib::M_smooth:
  5729. glShadeModel(GL_SMOOTH);
  5730. _flat_shade_model = false;
  5731. break;
  5732. case ShadeModelAttrib::M_flat:
  5733. glShadeModel(GL_FLAT);
  5734. _flat_shade_model = true;
  5735. break;
  5736. }
  5737. }
  5738. #endif // SUPPORT_FIXED_FUNCTION
  5739. #ifndef OPENGLES_1
  5740. /**
  5741. *
  5742. */
  5743. void CLP(GraphicsStateGuardian)::
  5744. do_issue_shader() {
  5745. ShaderContext *context = 0;
  5746. Shader *shader = (Shader *)_target_shader->get_shader();
  5747. #ifndef SUPPORT_FIXED_FUNCTION
  5748. // If we don't have a shader, apply the default shader.
  5749. if (!shader) {
  5750. shader = _default_shader;
  5751. nassertv(shader != NULL);
  5752. }
  5753. #endif
  5754. if (shader) {
  5755. context = shader->prepare_now(get_prepared_objects(), this);
  5756. }
  5757. #ifndef SUPPORT_FIXED_FUNCTION
  5758. // If it failed, try applying the default shader.
  5759. if (shader != _default_shader && (context == 0 || !context->valid())) {
  5760. shader = _default_shader;
  5761. nassertv(shader != NULL);
  5762. context = shader->prepare_now(get_prepared_objects(), this);
  5763. }
  5764. #endif
  5765. if (context == 0 || (context->valid() == false)) {
  5766. if (_current_shader_context != 0) {
  5767. _current_shader_context->unbind();
  5768. _current_shader = 0;
  5769. _current_shader_context = 0;
  5770. }
  5771. } else {
  5772. if (context != _current_shader_context) {
  5773. // Use a completely different shader than before. Unbind old shader,
  5774. // bind the new one.
  5775. if (_current_shader_context != NULL &&
  5776. _current_shader->get_language() != shader->get_language()) {
  5777. _current_shader_context->unbind();
  5778. }
  5779. context->bind();
  5780. _current_shader = shader;
  5781. _current_shader_context = context;
  5782. }
  5783. }
  5784. #ifndef OPENGLES
  5785. // Is the point size provided by the shader or by OpenGL?
  5786. bool shader_point_size = _target_shader->get_flag(ShaderAttrib::F_shader_point_size);
  5787. if (shader_point_size != _shader_point_size) {
  5788. if (shader_point_size) {
  5789. glEnable(GL_PROGRAM_POINT_SIZE);
  5790. } else {
  5791. glDisable(GL_PROGRAM_POINT_SIZE);
  5792. }
  5793. _shader_point_size = shader_point_size;
  5794. }
  5795. #endif
  5796. report_my_gl_errors();
  5797. }
  5798. #endif // !OPENGLES_1
  5799. /**
  5800. *
  5801. */
  5802. void CLP(GraphicsStateGuardian)::
  5803. do_issue_render_mode() {
  5804. const RenderModeAttrib *target_render_mode;
  5805. _target_rs->get_attrib_def(target_render_mode);
  5806. _render_mode = target_render_mode->get_mode();
  5807. PN_stdfloat thickness = target_render_mode->get_thickness();
  5808. _point_perspective = target_render_mode->get_perspective();
  5809. #ifndef OPENGLES // glPolygonMode not supported by OpenGL ES.
  5810. switch (_render_mode) {
  5811. case RenderModeAttrib::M_unchanged:
  5812. case RenderModeAttrib::M_filled:
  5813. case RenderModeAttrib::M_filled_flat:
  5814. glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  5815. break;
  5816. case RenderModeAttrib::M_wireframe:
  5817. glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  5818. break;
  5819. case RenderModeAttrib::M_point:
  5820. glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
  5821. break;
  5822. default:
  5823. GLCAT.error()
  5824. << "Unknown render mode " << (int)_render_mode << endl;
  5825. }
  5826. #endif // OPENGLES
  5827. // The thickness affects both the line width and the point size.
  5828. if (thickness != _point_size) {
  5829. if (GLCAT.is_spam()) {
  5830. GLCAT.spam() << "setting thickness to " << thickness << "\n";
  5831. }
  5832. glLineWidth(thickness);
  5833. #ifndef OPENGLES_2
  5834. glPointSize(thickness);
  5835. #endif
  5836. _point_size = thickness;
  5837. }
  5838. report_my_gl_errors();
  5839. #ifdef SUPPORT_FIXED_FUNCTION
  5840. do_point_size();
  5841. #endif
  5842. }
  5843. /**
  5844. *
  5845. */
  5846. void CLP(GraphicsStateGuardian)::
  5847. do_issue_antialias() {
  5848. const AntialiasAttrib *target_antialias;
  5849. _target_rs->get_attrib_def(target_antialias);
  5850. if (target_antialias->get_mode_type() == AntialiasAttrib::M_auto) {
  5851. // In this special mode, we must enable antialiasing on a case-by-case
  5852. // basis, because we enable it differently for polygons and for points and
  5853. // lines.
  5854. _auto_antialias_mode = true;
  5855. } else {
  5856. // Otherwise, explicitly enable or disable according to the bits that are
  5857. // set. But if multisample is requested and supported, don't use the
  5858. // other bits at all (they will be ignored by GL anyway).
  5859. _auto_antialias_mode = false;
  5860. unsigned short mode = target_antialias->get_mode();
  5861. if (_supports_multisample &&
  5862. (mode & AntialiasAttrib::M_multisample) != 0) {
  5863. enable_multisample_antialias(true);
  5864. } else {
  5865. enable_multisample_antialias(false);
  5866. enable_line_smooth((mode & AntialiasAttrib::M_line) != 0);
  5867. enable_point_smooth((mode & AntialiasAttrib::M_point) != 0);
  5868. enable_polygon_smooth((mode & AntialiasAttrib::M_polygon) != 0);
  5869. }
  5870. }
  5871. #ifndef OPENGLES_2
  5872. GLenum quality;
  5873. switch (target_antialias->get_mode_quality()) {
  5874. case AntialiasAttrib::M_faster:
  5875. quality = GL_FASTEST;
  5876. break;
  5877. case AntialiasAttrib::M_better:
  5878. quality = GL_NICEST;
  5879. break;
  5880. default:
  5881. quality = GL_DONT_CARE;
  5882. break;
  5883. }
  5884. if (_line_smooth_enabled) {
  5885. glHint(GL_LINE_SMOOTH_HINT, quality);
  5886. }
  5887. if (_point_smooth_enabled) {
  5888. glHint(GL_POINT_SMOOTH_HINT, quality);
  5889. }
  5890. #ifndef OPENGLES
  5891. if (_polygon_smooth_enabled) {
  5892. glHint(GL_POLYGON_SMOOTH_HINT, quality);
  5893. }
  5894. #endif
  5895. #endif // !OPENGLES_2
  5896. report_my_gl_errors();
  5897. }
  5898. #ifdef SUPPORT_FIXED_FUNCTION // OpenGL ES 2.0 doesn't support rescaling normals.
  5899. /**
  5900. *
  5901. */
  5902. void CLP(GraphicsStateGuardian)::
  5903. do_issue_rescale_normal() {
  5904. RescaleNormalAttrib::Mode mode = RescaleNormalAttrib::M_none;
  5905. const RescaleNormalAttrib *target_rescale_normal;
  5906. if (_target_rs->get_attrib(target_rescale_normal)) {
  5907. mode = target_rescale_normal->get_mode();
  5908. }
  5909. switch (mode) {
  5910. case RescaleNormalAttrib::M_none:
  5911. glDisable(GL_NORMALIZE);
  5912. if (_supports_rescale_normal && support_rescale_normal) {
  5913. glDisable(GL_RESCALE_NORMAL);
  5914. }
  5915. break;
  5916. case RescaleNormalAttrib::M_rescale:
  5917. if (_supports_rescale_normal && support_rescale_normal) {
  5918. glEnable(GL_RESCALE_NORMAL);
  5919. glDisable(GL_NORMALIZE);
  5920. } else {
  5921. glEnable(GL_NORMALIZE);
  5922. }
  5923. break;
  5924. case RescaleNormalAttrib::M_normalize:
  5925. glEnable(GL_NORMALIZE);
  5926. if (_supports_rescale_normal && support_rescale_normal) {
  5927. glDisable(GL_RESCALE_NORMAL);
  5928. }
  5929. break;
  5930. default:
  5931. GLCAT.error()
  5932. << "Unknown rescale_normal mode " << (int)mode << endl;
  5933. }
  5934. report_my_gl_errors();
  5935. }
  5936. #endif // SUPPORT_FIXED_FUNCTION
  5937. // PandaCompareFunc - 1 + 0x200 === GL_NEVER, etc. order is sequential
  5938. #define PANDA_TO_GL_COMPAREFUNC(PANDACMPFUNC) (PANDACMPFUNC-1 +0x200)
  5939. /**
  5940. *
  5941. */
  5942. void CLP(GraphicsStateGuardian)::
  5943. do_issue_depth_test() {
  5944. const DepthTestAttrib *target_depth_test;
  5945. _target_rs->get_attrib_def(target_depth_test);
  5946. DepthTestAttrib::PandaCompareFunc mode = target_depth_test->get_mode();
  5947. if (mode == DepthTestAttrib::M_none) {
  5948. enable_depth_test(false);
  5949. } else {
  5950. enable_depth_test(true);
  5951. glDepthFunc(PANDA_TO_GL_COMPAREFUNC(mode));
  5952. }
  5953. report_my_gl_errors();
  5954. }
  5955. #ifdef SUPPORT_FIXED_FUNCTION
  5956. /**
  5957. *
  5958. */
  5959. void CLP(GraphicsStateGuardian)::
  5960. do_issue_alpha_test() {
  5961. #ifndef OPENGLES_1
  5962. if (_target_shader->get_flag(ShaderAttrib::F_subsume_alpha_test)) {
  5963. enable_alpha_test(false);
  5964. } else
  5965. #endif
  5966. {
  5967. const AlphaTestAttrib *target_alpha_test;
  5968. _target_rs->get_attrib_def(target_alpha_test);
  5969. AlphaTestAttrib::PandaCompareFunc mode = target_alpha_test->get_mode();
  5970. if (mode == AlphaTestAttrib::M_none) {
  5971. enable_alpha_test(false);
  5972. } else {
  5973. nassertv(GL_NEVER == (AlphaTestAttrib::M_never-1+0x200));
  5974. glAlphaFunc(PANDA_TO_GL_COMPAREFUNC(mode), target_alpha_test->get_reference_alpha());
  5975. enable_alpha_test(true);
  5976. }
  5977. }
  5978. }
  5979. #endif // SUPPORT_FIXED_FUNCTION
  5980. /**
  5981. *
  5982. */
  5983. void CLP(GraphicsStateGuardian)::
  5984. do_issue_depth_write() {
  5985. const DepthWriteAttrib *target_depth_write;
  5986. _target_rs->get_attrib_def(target_depth_write);
  5987. DepthWriteAttrib::Mode mode = target_depth_write->get_mode();
  5988. if (mode == DepthWriteAttrib::M_off) {
  5989. #ifdef GSG_VERBOSE
  5990. GLCAT.spam()
  5991. << "glDepthMask(GL_FALSE)" << endl;
  5992. #endif
  5993. glDepthMask(GL_FALSE);
  5994. } else {
  5995. #ifdef GSG_VERBOSE
  5996. GLCAT.spam()
  5997. << "glDepthMask(GL_TRUE)" << endl;
  5998. #endif
  5999. glDepthMask(GL_TRUE);
  6000. }
  6001. report_my_gl_errors();
  6002. }
  6003. /**
  6004. *
  6005. */
  6006. void CLP(GraphicsStateGuardian)::
  6007. do_issue_cull_face() {
  6008. const CullFaceAttrib *target_cull_face;
  6009. _target_rs->get_attrib_def(target_cull_face);
  6010. CullFaceAttrib::Mode mode = target_cull_face->get_effective_mode();
  6011. switch (mode) {
  6012. case CullFaceAttrib::M_cull_none:
  6013. glDisable(GL_CULL_FACE);
  6014. break;
  6015. case CullFaceAttrib::M_cull_clockwise:
  6016. glEnable(GL_CULL_FACE);
  6017. glCullFace(GL_BACK);
  6018. break;
  6019. case CullFaceAttrib::M_cull_counter_clockwise:
  6020. glEnable(GL_CULL_FACE);
  6021. glCullFace(GL_FRONT);
  6022. break;
  6023. default:
  6024. GLCAT.error()
  6025. << "invalid cull face mode " << (int)mode << endl;
  6026. break;
  6027. }
  6028. report_my_gl_errors();
  6029. }
  6030. #ifdef SUPPORT_FIXED_FUNCTION
  6031. /**
  6032. *
  6033. */
  6034. void CLP(GraphicsStateGuardian)::
  6035. do_issue_fog() {
  6036. const FogAttrib *target_fog;
  6037. _target_rs->get_attrib_def(target_fog);
  6038. if (!target_fog->is_off()) {
  6039. enable_fog(true);
  6040. Fog *fog = target_fog->get_fog();
  6041. nassertv(fog != (Fog *)NULL);
  6042. apply_fog(fog);
  6043. } else {
  6044. enable_fog(false);
  6045. }
  6046. report_my_gl_errors();
  6047. }
  6048. #endif // SUPPORT_FIXED_FUNCTION
  6049. /**
  6050. *
  6051. */
  6052. void CLP(GraphicsStateGuardian)::
  6053. do_issue_depth_offset() {
  6054. const DepthOffsetAttrib *target_depth_offset = (const DepthOffsetAttrib *)
  6055. _target_rs->get_attrib_def(DepthOffsetAttrib::get_class_slot());
  6056. int offset = target_depth_offset->get_offset();
  6057. if (offset != 0) {
  6058. // The relationship between these two parameters is a little unclear and
  6059. // poorly explained in the GL man pages.
  6060. glPolygonOffset((GLfloat) -offset, (GLfloat) -offset);
  6061. enable_polygon_offset(true);
  6062. } else {
  6063. enable_polygon_offset(false);
  6064. }
  6065. PN_stdfloat min_value = target_depth_offset->get_min_value();
  6066. PN_stdfloat max_value = target_depth_offset->get_max_value();
  6067. #ifdef GSG_VERBOSE
  6068. GLCAT.spam()
  6069. << "glDepthRange(" << min_value << ", " << max_value << ")" << endl;
  6070. #endif
  6071. #ifdef OPENGLES
  6072. // OpenGL ES uses a single-precision call.
  6073. glDepthRangef((GLclampf)min_value, (GLclampf)max_value);
  6074. #else
  6075. // Mainline OpenGL uses a double-precision call.
  6076. glDepthRange((GLclampd)min_value, (GLclampd)max_value);
  6077. #endif // OPENGLES
  6078. report_my_gl_errors();
  6079. }
  6080. #ifdef SUPPORT_FIXED_FUNCTION
  6081. /**
  6082. *
  6083. */
  6084. void CLP(GraphicsStateGuardian)::
  6085. do_issue_material() {
  6086. static Material empty;
  6087. const Material *material;
  6088. const MaterialAttrib *target_material;
  6089. _target_rs->get_attrib_def(target_material);
  6090. if (target_material == (MaterialAttrib *)NULL ||
  6091. target_material->is_off()) {
  6092. material = &empty;
  6093. } else {
  6094. material = target_material->get_material();
  6095. }
  6096. bool has_material_force_color = _has_material_force_color;
  6097. #ifndef NDEBUG
  6098. if (_show_texture_usage) {
  6099. // In show_texture_usage mode, all colors are white, so as not to
  6100. // contaminate the texture color. This means we disable lighting
  6101. // materials too.
  6102. material = &empty;
  6103. has_material_force_color = false;
  6104. }
  6105. #endif // NDEBUG
  6106. #ifdef OPENGLES
  6107. const GLenum face = GL_FRONT_AND_BACK;
  6108. #else
  6109. GLenum face = material->get_twoside() ? GL_FRONT_AND_BACK : GL_FRONT;
  6110. #endif
  6111. call_glMaterialfv(face, GL_SPECULAR, material->get_specular());
  6112. call_glMaterialfv(face, GL_EMISSION, material->get_emission());
  6113. glMaterialf(face, GL_SHININESS, max(min(material->get_shininess(), (PN_stdfloat)128), (PN_stdfloat)0));
  6114. if (material->has_ambient() && material->has_diffuse()) {
  6115. // The material has both an ambient and diffuse specified. This means we
  6116. // do not need glMaterialColor().
  6117. glDisable(GL_COLOR_MATERIAL);
  6118. call_glMaterialfv(face, GL_AMBIENT, material->get_ambient());
  6119. call_glMaterialfv(face, GL_DIFFUSE, material->get_diffuse());
  6120. } else if (material->has_ambient()) {
  6121. // The material specifies an ambient, but not a diffuse component. The
  6122. // diffuse component comes from the object's color.
  6123. call_glMaterialfv(face, GL_AMBIENT, material->get_ambient());
  6124. if (has_material_force_color) {
  6125. glDisable(GL_COLOR_MATERIAL);
  6126. call_glMaterialfv(face, GL_DIFFUSE, _material_force_color);
  6127. } else {
  6128. #ifndef OPENGLES
  6129. glColorMaterial(face, GL_DIFFUSE);
  6130. #endif // OPENGLES
  6131. glEnable(GL_COLOR_MATERIAL);
  6132. }
  6133. } else if (material->has_diffuse()) {
  6134. // The material specifies a diffuse, but not an ambient component. The
  6135. // ambient component comes from the object's color.
  6136. call_glMaterialfv(face, GL_DIFFUSE, material->get_diffuse());
  6137. if (has_material_force_color) {
  6138. glDisable(GL_COLOR_MATERIAL);
  6139. call_glMaterialfv(face, GL_AMBIENT, _material_force_color);
  6140. } else {
  6141. #ifndef OPENGLES
  6142. glColorMaterial(face, GL_AMBIENT);
  6143. #endif // OPENGLES
  6144. glEnable(GL_COLOR_MATERIAL);
  6145. }
  6146. } else {
  6147. // The material specifies neither a diffuse nor an ambient component.
  6148. // Both components come from the object's color.
  6149. if (has_material_force_color) {
  6150. glDisable(GL_COLOR_MATERIAL);
  6151. call_glMaterialfv(face, GL_AMBIENT, _material_force_color);
  6152. call_glMaterialfv(face, GL_DIFFUSE, _material_force_color);
  6153. } else {
  6154. #ifndef OPENGLES
  6155. glColorMaterial(face, GL_AMBIENT_AND_DIFFUSE);
  6156. #endif // OPENGLES
  6157. glEnable(GL_COLOR_MATERIAL);
  6158. }
  6159. }
  6160. #ifndef OPENGLES
  6161. glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, material->get_local());
  6162. glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, material->get_twoside());
  6163. if (_use_separate_specular_color) {
  6164. glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
  6165. } else {
  6166. glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
  6167. }
  6168. #endif
  6169. report_my_gl_errors();
  6170. }
  6171. #endif // SUPPORT_FIXED_FUNCTION
  6172. /**
  6173. * Issues the logic operation attribute to the GL.
  6174. */
  6175. #if !defined(OPENGLES) || defined(OPENGLES_1)
  6176. void CLP(GraphicsStateGuardian)::
  6177. do_issue_logic_op() {
  6178. const LogicOpAttrib *target_logic_op;
  6179. _target_rs->get_attrib_def(target_logic_op);
  6180. if (target_logic_op->get_operation() != LogicOpAttrib::O_none) {
  6181. glEnable(GL_COLOR_LOGIC_OP);
  6182. glLogicOp(GL_CLEAR - 1 + (int)target_logic_op->get_operation());
  6183. if (GLCAT.is_spam()) {
  6184. GLCAT.spam() << "glEnable(GL_COLOR_LOGIC_OP)\n";
  6185. GLCAT.spam() << "glLogicOp(" << target_logic_op->get_operation() << ")\n";
  6186. }
  6187. } else {
  6188. glDisable(GL_COLOR_LOGIC_OP);
  6189. glLogicOp(GL_COPY);
  6190. if (GLCAT.is_spam()) {
  6191. GLCAT.spam() << "glDisable(GL_COLOR_LOGIC_OP)\n";
  6192. }
  6193. }
  6194. }
  6195. #endif
  6196. /**
  6197. *
  6198. */
  6199. void CLP(GraphicsStateGuardian)::
  6200. do_issue_blending() {
  6201. // Handle the color_write attrib. If color_write is off, then all the other
  6202. // blending-related stuff doesn't matter. If the device doesn't support
  6203. // color-write, we use blending tricks to effectively disable color write.
  6204. const ColorWriteAttrib *target_color_write;
  6205. _target_rs->get_attrib_def(target_color_write);
  6206. unsigned int color_channels =
  6207. target_color_write->get_channels() & _color_write_mask;
  6208. #ifndef OPENGLES_1
  6209. if (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write)) {
  6210. color_channels &= ~(ColorWriteAttrib::C_alpha);
  6211. }
  6212. #endif
  6213. if (color_channels == ColorWriteAttrib::C_off) {
  6214. int color_write_slot = ColorWriteAttrib::get_class_slot();
  6215. enable_multisample_alpha_one(false);
  6216. enable_multisample_alpha_mask(false);
  6217. if (gl_color_mask) {
  6218. enable_blend(false);
  6219. set_color_write_mask(ColorWriteAttrib::C_off);
  6220. } else {
  6221. enable_blend(true);
  6222. _glBlendEquation(GL_FUNC_ADD);
  6223. glBlendFunc(GL_ZERO, GL_ONE);
  6224. }
  6225. if (GLCAT.is_spam()) {
  6226. GLCAT.spam() << "glBlendEquation(GL_FUNC_ADD)\n";
  6227. GLCAT.spam() << "glBlendFunc(GL_ZERO, GL_ONE)\n";
  6228. }
  6229. return;
  6230. } else {
  6231. set_color_write_mask(color_channels);
  6232. }
  6233. const ColorBlendAttrib *target_color_blend;
  6234. _target_rs->get_attrib_def(target_color_blend);
  6235. CPT(ColorBlendAttrib) color_blend = target_color_blend;
  6236. ColorBlendAttrib::Mode color_blend_mode = target_color_blend->get_mode();
  6237. ColorBlendAttrib::Mode alpha_blend_mode = target_color_blend->get_alpha_mode();
  6238. const TransparencyAttrib *target_transparency;
  6239. _target_rs->get_attrib_def(target_transparency);
  6240. TransparencyAttrib::Mode transparency_mode = target_transparency->get_mode();
  6241. _color_blend_involves_color_scale = color_blend->involves_color_scale();
  6242. // Is there a color blend set?
  6243. if (color_blend_mode != ColorBlendAttrib::M_none) {
  6244. enable_multisample_alpha_one(false);
  6245. enable_multisample_alpha_mask(false);
  6246. enable_blend(true);
  6247. if (_supports_blend_equation_separate) {
  6248. _glBlendEquationSeparate(get_blend_equation_type(color_blend_mode),
  6249. get_blend_equation_type(alpha_blend_mode));
  6250. } else {
  6251. _glBlendEquation(get_blend_equation_type(color_blend_mode));
  6252. }
  6253. _glBlendFuncSeparate(get_blend_func(color_blend->get_operand_a()),
  6254. get_blend_func(color_blend->get_operand_b()),
  6255. get_blend_func(color_blend->get_alpha_operand_a()),
  6256. get_blend_func(color_blend->get_alpha_operand_b()));
  6257. #ifndef OPENGLES_1
  6258. LColor c;
  6259. if (_color_blend_involves_color_scale) {
  6260. // Apply the current color scale to the blend mode.
  6261. c = _current_color_scale;
  6262. } else {
  6263. c = color_blend->get_color();
  6264. }
  6265. _glBlendColor(c[0], c[1], c[2], c[3]);
  6266. #endif
  6267. if (GLCAT.is_spam()) {
  6268. if (_supports_blend_equation_separate) {
  6269. GLCAT.spam() << "glBlendEquationSeparate(" << color_blend_mode << ", "
  6270. << alpha_blend_mode << ")\n";
  6271. } else {
  6272. GLCAT.spam() << "glBlendEquation(" << color_blend_mode << ")\n";
  6273. }
  6274. GLCAT.spam() << "glBlendFuncSeparate("
  6275. << color_blend->get_operand_a() << ", "
  6276. << color_blend->get_operand_b() << ", "
  6277. << color_blend->get_alpha_operand_a() << ", "
  6278. << color_blend->get_alpha_operand_b() << ")\n";
  6279. #ifndef OPENGLES_1
  6280. GLCAT.spam() << "glBlendColor(" << c << ")\n";
  6281. #endif
  6282. }
  6283. return;
  6284. }
  6285. // No color blend; is there a transparency set?
  6286. switch (transparency_mode) {
  6287. case TransparencyAttrib::M_none:
  6288. case TransparencyAttrib::M_binary:
  6289. break;
  6290. case TransparencyAttrib::M_alpha:
  6291. case TransparencyAttrib::M_dual:
  6292. enable_multisample_alpha_one(false);
  6293. enable_multisample_alpha_mask(false);
  6294. enable_blend(true);
  6295. _glBlendEquation(GL_FUNC_ADD);
  6296. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  6297. if (GLCAT.is_spam()) {
  6298. GLCAT.spam() << "glBlendEquation(GL_FUNC_ADD)\n";
  6299. GLCAT.spam() << "glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)\n";
  6300. }
  6301. return;
  6302. case TransparencyAttrib::M_premultiplied_alpha:
  6303. enable_multisample_alpha_one(false);
  6304. enable_multisample_alpha_mask(false);
  6305. enable_blend(true);
  6306. _glBlendEquation(GL_FUNC_ADD);
  6307. glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  6308. if (GLCAT.is_spam()) {
  6309. GLCAT.spam() << "glBlendEquation(GL_FUNC_ADD)\n";
  6310. GLCAT.spam() << "glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)\n";
  6311. }
  6312. return;
  6313. case TransparencyAttrib::M_multisample:
  6314. // We need to enable *both* of these in M_multisample case.
  6315. enable_multisample_alpha_one(true);
  6316. enable_multisample_alpha_mask(true);
  6317. enable_blend(false);
  6318. return;
  6319. case TransparencyAttrib::M_multisample_mask:
  6320. enable_multisample_alpha_one(false);
  6321. enable_multisample_alpha_mask(true);
  6322. enable_blend(false);
  6323. return;
  6324. default:
  6325. GLCAT.error()
  6326. << "invalid transparency mode " << (int)transparency_mode << endl;
  6327. break;
  6328. }
  6329. if (_line_smooth_enabled || _point_smooth_enabled) {
  6330. // If we have either of these turned on, we also need to have blend mode
  6331. // enabled in order to see it.
  6332. enable_multisample_alpha_one(false);
  6333. enable_multisample_alpha_mask(false);
  6334. enable_blend(true);
  6335. _glBlendEquation(GL_FUNC_ADD);
  6336. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  6337. if (GLCAT.is_spam()) {
  6338. GLCAT.spam() << "glBlendEquation(GL_FUNC_ADD)\n";
  6339. GLCAT.spam() << "glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)\n";
  6340. }
  6341. return;
  6342. }
  6343. /*
  6344. * For best polygon smoothing, we need: (1) a frame buffer that supports alpha
  6345. * (2) sort polygons front-to-back (3) glBlendFunc(GL_SRC_ALPHA_SATURATE,
  6346. * GL_ONE); Since these modes have other implications for the application, we
  6347. * don't attempt to do this by default. If you really want good polygon
  6348. * smoothing (and you don't have multisample support), do all this yourself.
  6349. */
  6350. // Nothing's set, so disable blending.
  6351. enable_multisample_alpha_one(false);
  6352. enable_multisample_alpha_mask(false);
  6353. enable_blend(false);
  6354. }
  6355. #ifdef SUPPORT_FIXED_FUNCTION
  6356. /**
  6357. * Called the first time a particular light has been bound to a given id
  6358. * within a frame, this should set up the associated hardware light with the
  6359. * light's properties.
  6360. */
  6361. void CLP(GraphicsStateGuardian)::
  6362. bind_light(PointLight *light_obj, const NodePath &light, int light_id) {
  6363. // static PStatCollector
  6364. // _draw_set_state_light_bind_point_pcollector("Draw:Set
  6365. // State:Light:Bind:Point"); PStatGPUTimer timer(this,
  6366. // _draw_set_state_light_bind_point_pcollector);
  6367. GLenum id = get_light_id(light_id);
  6368. static const LColor black(0.0f, 0.0f, 0.0f, 1.0f);
  6369. call_glLightfv(id, GL_AMBIENT, black);
  6370. call_glLightfv(id, GL_DIFFUSE, get_light_color(light_obj));
  6371. call_glLightfv(id, GL_SPECULAR, light_obj->get_specular_color());
  6372. // Position needs to specify x, y, z, and w w == 1 implies non-infinite
  6373. // position
  6374. CPT(TransformState) transform = light.get_transform(_scene_setup->get_scene_root().get_parent());
  6375. LPoint3 pos = light_obj->get_point() * transform->get_mat();
  6376. LPoint4 fpos(pos[0], pos[1], pos[2], 1.0f);
  6377. call_glLightfv(id, GL_POSITION, fpos);
  6378. // GL_SPOT_DIRECTION is not significant when cutoff == 180
  6379. // Exponent == 0 implies uniform light distribution
  6380. glLightf(id, GL_SPOT_EXPONENT, 0.0f);
  6381. // Cutoff == 180 means uniform point light source
  6382. glLightf(id, GL_SPOT_CUTOFF, 180.0f);
  6383. const LVecBase3 &att = light_obj->get_attenuation();
  6384. glLightf(id, GL_CONSTANT_ATTENUATION, att[0]);
  6385. glLightf(id, GL_LINEAR_ATTENUATION, att[1]);
  6386. glLightf(id, GL_QUADRATIC_ATTENUATION, att[2]);
  6387. report_my_gl_errors();
  6388. }
  6389. #endif // SUPPORT_FIXED_FUNCTION
  6390. #ifdef SUPPORT_FIXED_FUNCTION
  6391. /**
  6392. * Called the first time a particular light has been bound to a given id
  6393. * within a frame, this should set up the associated hardware light with the
  6394. * light's properties.
  6395. */
  6396. void CLP(GraphicsStateGuardian)::
  6397. bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) {
  6398. // static PStatCollector
  6399. // _draw_set_state_light_bind_directional_pcollector("Draw:Set
  6400. // State:Light:Bind:Directional"); PStatGPUTimer timer(this,
  6401. // _draw_set_state_light_bind_directional_pcollector);
  6402. pair<DirectionalLights::iterator, bool> lookup = _dlights.insert(DirectionalLights::value_type(light, DirectionalLightFrameData()));
  6403. DirectionalLightFrameData &fdata = (*lookup.first).second;
  6404. if (lookup.second) {
  6405. // The light was not computed yet this frame. Compute it now.
  6406. CPT(TransformState) transform = light.get_transform(_scene_setup->get_scene_root().get_parent());
  6407. LVector3 dir = light_obj->get_direction() * transform->get_mat();
  6408. fdata._neg_dir.set(-dir[0], -dir[1], -dir[2], 0);
  6409. }
  6410. GLenum id = get_light_id( light_id );
  6411. static const LColor black(0.0f, 0.0f, 0.0f, 1.0f);
  6412. call_glLightfv(id, GL_AMBIENT, black);
  6413. call_glLightfv(id, GL_DIFFUSE, get_light_color(light_obj));
  6414. call_glLightfv(id, GL_SPECULAR, light_obj->get_specular_color());
  6415. // Position needs to specify x, y, z, and w. w == 0 implies light is at
  6416. // infinity
  6417. call_glLightfv(id, GL_POSITION, fdata._neg_dir);
  6418. // GL_SPOT_DIRECTION is not significant when cutoff == 180 In this case,
  6419. // position x, y, z specifies direction
  6420. // Exponent == 0 implies uniform light distribution
  6421. glLightf(id, GL_SPOT_EXPONENT, 0.0f);
  6422. // Cutoff == 180 means uniform point light source
  6423. glLightf(id, GL_SPOT_CUTOFF, 180.0f);
  6424. // Default attenuation values (only spotlight and point light can modify
  6425. // these)
  6426. glLightf(id, GL_CONSTANT_ATTENUATION, 1.0f);
  6427. glLightf(id, GL_LINEAR_ATTENUATION, 0.0f);
  6428. glLightf(id, GL_QUADRATIC_ATTENUATION, 0.0f);
  6429. report_my_gl_errors();
  6430. }
  6431. #endif // SUPPORT_FIXED_FUNCTION
  6432. #ifdef SUPPORT_FIXED_FUNCTION
  6433. /**
  6434. * Called the first time a particular light has been bound to a given id
  6435. * within a frame, this should set up the associated hardware light with the
  6436. * light's properties.
  6437. */
  6438. void CLP(GraphicsStateGuardian)::
  6439. bind_light(Spotlight *light_obj, const NodePath &light, int light_id) {
  6440. // static PStatCollector
  6441. // _draw_set_state_light_bind_spotlight_pcollector("Draw:Set
  6442. // State:Light:Bind:Spotlight"); PStatGPUTimer timer(this,
  6443. // _draw_set_state_light_bind_spotlight_pcollector);
  6444. Lens *lens = light_obj->get_lens();
  6445. nassertv(lens != (Lens *)NULL);
  6446. GLenum id = get_light_id(light_id);
  6447. static const LColor black(0.0f, 0.0f, 0.0f, 1.0f);
  6448. call_glLightfv(id, GL_AMBIENT, black);
  6449. call_glLightfv(id, GL_DIFFUSE, get_light_color(light_obj));
  6450. call_glLightfv(id, GL_SPECULAR, light_obj->get_specular_color());
  6451. // Position needs to specify x, y, z, and w w == 1 implies non-infinite
  6452. // position
  6453. CPT(TransformState) transform = light.get_transform(_scene_setup->get_scene_root().get_parent());
  6454. const LMatrix4 &light_mat = transform->get_mat();
  6455. LPoint3 pos = lens->get_nodal_point() * light_mat;
  6456. LVector3 dir = lens->get_view_vector() * light_mat;
  6457. LPoint4 fpos(pos[0], pos[1], pos[2], 1.0f);
  6458. call_glLightfv(id, GL_POSITION, fpos);
  6459. call_glLightfv(id, GL_SPOT_DIRECTION, dir);
  6460. glLightf(id, GL_SPOT_EXPONENT, max(min(light_obj->get_exponent(), (PN_stdfloat)128), (PN_stdfloat)0));
  6461. glLightf(id, GL_SPOT_CUTOFF, lens->get_hfov() * 0.5f);
  6462. const LVecBase3 &att = light_obj->get_attenuation();
  6463. glLightf(id, GL_CONSTANT_ATTENUATION, att[0]);
  6464. glLightf(id, GL_LINEAR_ATTENUATION, att[1]);
  6465. glLightf(id, GL_QUADRATIC_ATTENUATION, att[2]);
  6466. report_my_gl_errors();
  6467. }
  6468. #endif // SUPPORT_FIXED_FUNCTION
  6469. #ifdef SUPPORT_IMMEDIATE_MODE
  6470. /**
  6471. * Uses the ImmediateModeSender to draw a series of primitives of the
  6472. * indicated type.
  6473. */
  6474. void CLP(GraphicsStateGuardian)::
  6475. draw_immediate_simple_primitives(const GeomPrimitivePipelineReader *reader, GLenum mode) {
  6476. int num_vertices = reader->get_num_vertices();
  6477. _vertices_immediate_pcollector.add_level(num_vertices);
  6478. glBegin(mode);
  6479. if (reader->is_indexed()) {
  6480. for (int v = 0; v < num_vertices; ++v) {
  6481. _sender.set_vertex(reader->get_vertex(v));
  6482. _sender.issue_vertex();
  6483. }
  6484. } else {
  6485. _sender.set_vertex(reader->get_first_vertex());
  6486. for (int v = 0; v < num_vertices; ++v) {
  6487. _sender.issue_vertex();
  6488. }
  6489. }
  6490. glEnd();
  6491. }
  6492. #endif // SUPPORT_IMMEDIATE_MODE
  6493. #ifdef SUPPORT_IMMEDIATE_MODE
  6494. /**
  6495. * Uses the ImmediateModeSender to draw a series of primitives of the
  6496. * indicated type. This form is for primitive types like tristrips which must
  6497. * involve several begin/end groups.
  6498. */
  6499. void CLP(GraphicsStateGuardian)::
  6500. draw_immediate_composite_primitives(const GeomPrimitivePipelineReader *reader, GLenum mode) {
  6501. int num_vertices = reader->get_num_vertices();
  6502. _vertices_immediate_pcollector.add_level(num_vertices);
  6503. CPTA_int ends = reader->get_ends();
  6504. int num_unused_vertices_per_primitive = reader->get_object()->get_num_unused_vertices_per_primitive();
  6505. if (reader->is_indexed()) {
  6506. int begin = 0;
  6507. CPTA_int::const_iterator ei;
  6508. for (ei = ends.begin(); ei != ends.end(); ++ei) {
  6509. int end = (*ei);
  6510. glBegin(mode);
  6511. for (int v = begin; v < end; ++v) {
  6512. _sender.set_vertex(reader->get_vertex(v));
  6513. _sender.issue_vertex();
  6514. }
  6515. glEnd();
  6516. begin = end + num_unused_vertices_per_primitive;
  6517. }
  6518. } else {
  6519. _sender.set_vertex(reader->get_first_vertex());
  6520. int begin = 0;
  6521. CPTA_int::const_iterator ei;
  6522. for (ei = ends.begin(); ei != ends.end(); ++ei) {
  6523. int end = (*ei);
  6524. glBegin(mode);
  6525. for (int v = begin; v < end; ++v) {
  6526. _sender.issue_vertex();
  6527. }
  6528. glEnd();
  6529. begin = end + num_unused_vertices_per_primitive;
  6530. }
  6531. }
  6532. }
  6533. #endif // SUPPORT_IMMEDIATE_MODE
  6534. /**
  6535. * Calls glFlush().
  6536. */
  6537. void CLP(GraphicsStateGuardian)::
  6538. gl_flush() const {
  6539. PStatTimer timer(_flush_pcollector);
  6540. glFlush();
  6541. }
  6542. /**
  6543. * Returns the result of glGetError().
  6544. */
  6545. GLenum CLP(GraphicsStateGuardian)::
  6546. gl_get_error() const {
  6547. if (_check_errors) {
  6548. PStatTimer timer(_check_error_pcollector);
  6549. return glGetError();
  6550. } else {
  6551. return GL_NO_ERROR;
  6552. }
  6553. }
  6554. /**
  6555. * The internal implementation of report_errors(). Don't call this function;
  6556. * use report_errors() instead. The return value is true if everything is ok,
  6557. * or false if we should shut down.
  6558. */
  6559. bool CLP(GraphicsStateGuardian)::
  6560. report_errors_loop(int line, const char *source_file, GLenum error_code,
  6561. int &error_count) {
  6562. while ((gl_max_errors < 0 || error_count < gl_max_errors) &&
  6563. (error_code != GL_NO_ERROR)) {
  6564. GLCAT.error()
  6565. << "at " << line << " of " << source_file << " : "
  6566. << get_error_string(error_code) << "\n";
  6567. error_code = glGetError();
  6568. error_count++;
  6569. }
  6570. return (error_code == GL_NO_ERROR);
  6571. }
  6572. /**
  6573. * Returns an error string for an OpenGL error code.
  6574. */
  6575. string CLP(GraphicsStateGuardian)::
  6576. get_error_string(GLenum error_code) {
  6577. // We used to use gluErrorString here, but I (rdb) took it out because that
  6578. // was really the only function we used from GLU. The idea with the error
  6579. // table was taken from SGI's sample implementation.
  6580. static const char *error_strings[] = {
  6581. "invalid enumerant",
  6582. "invalid value",
  6583. "invalid operation",
  6584. "stack overflow",
  6585. "stack underflow",
  6586. "out of memory",
  6587. "invalid framebuffer operation",
  6588. "context lost",
  6589. };
  6590. if (error_code == GL_NO_ERROR) {
  6591. return "no error";
  6592. #ifndef OPENGLES
  6593. } else if (error_code == GL_TABLE_TOO_LARGE) {
  6594. return "table too large";
  6595. #endif
  6596. } else if (error_code >= 0x0500 && error_code <= 0x0507) {
  6597. return error_strings[error_code - 0x0500];
  6598. }
  6599. // Other error, somehow? Just display the error code then.
  6600. ostringstream strm;
  6601. strm << "GL error " << (int)error_code;
  6602. return strm.str();
  6603. }
  6604. /**
  6605. * Outputs the result of glGetString() on the indicated tag. The output
  6606. * string is returned.
  6607. */
  6608. string CLP(GraphicsStateGuardian)::
  6609. show_gl_string(const string &name, GLenum id) {
  6610. string result;
  6611. const GLubyte *text = glGetString(id);
  6612. if (text == (const GLubyte *)NULL) {
  6613. GLCAT.warning()
  6614. << "Unable to query " << name << "\n";
  6615. } else {
  6616. result = (const char *)text;
  6617. if (GLCAT.is_debug()) {
  6618. GLCAT.debug()
  6619. << name << " = " << result << "\n";
  6620. }
  6621. }
  6622. return result;
  6623. }
  6624. /**
  6625. * Queries the runtime version of OpenGL in use.
  6626. */
  6627. void CLP(GraphicsStateGuardian)::
  6628. query_gl_version() {
  6629. _gl_vendor = show_gl_string("GL_VENDOR", GL_VENDOR);
  6630. _gl_renderer = show_gl_string("GL_RENDERER", GL_RENDERER);
  6631. _gl_version = show_gl_string("GL_VERSION", GL_VERSION);
  6632. _gl_version_major = 0;
  6633. _gl_version_minor = 0;
  6634. // This is the most preposterous driver bug: NVIDIA drivers will claim
  6635. // that the version is 1.2 as long as the process is named pview.exe!
  6636. #ifndef OPENGLES
  6637. if (_gl_version.substr(0, 10) == "1.2 NVIDIA") {
  6638. Filename exec_name = ExecutionEnvironment::get_binary_name();
  6639. if (cmp_nocase(exec_name.get_basename(), "pview.exe") == 0) {
  6640. glGetIntegerv(GL_MAJOR_VERSION, &_gl_version_major);
  6641. glGetIntegerv(GL_MINOR_VERSION, &_gl_version_minor);
  6642. if (glGetError() == GL_INVALID_ENUM) {
  6643. _gl_version_major = 1;
  6644. _gl_version_minor = 2;
  6645. GLCAT.warning()
  6646. << "Driver possibly misreported GL_VERSION! Unable to detect "
  6647. "correct OpenGL version.\n";
  6648. } else if (_gl_version_major != 1 || _gl_version_minor != 2) {
  6649. GLCAT.debug()
  6650. << "Driver misreported GL_VERSION! Correct version detected as "
  6651. << _gl_version_major << "." << _gl_version_minor << "\n";
  6652. }
  6653. return;
  6654. }
  6655. }
  6656. // If we asked for a GL 3 context, let's first try and see if we can use the
  6657. // OpenGL 3 way to query version.
  6658. if (gl_version.get_num_words() > 0 && gl_version[0] >= 3) {
  6659. glGetIntegerv(GL_MAJOR_VERSION, &_gl_version_major);
  6660. glGetIntegerv(GL_MINOR_VERSION, &_gl_version_minor);
  6661. if (_gl_version_major >= 1) {
  6662. // Fair enough, seems to check out.
  6663. if (GLCAT.is_debug()) {
  6664. GLCAT.debug()
  6665. << "Detected OpenGL version: "
  6666. << _gl_version_major << "." << _gl_version_minor << "\n";
  6667. }
  6668. return;
  6669. }
  6670. }
  6671. #endif // !OPENGLES
  6672. // Otherwise, parse the GL_VERSION string.
  6673. if (_gl_version.empty()) {
  6674. GLCAT.error() << "Unable to detect OpenGL version\n";
  6675. } else {
  6676. string input = _gl_version;
  6677. // Skip any initial words that don't begin with a digit.
  6678. while (!input.empty() && !isdigit(input[0])) {
  6679. size_t space = input.find(' ');
  6680. if (space == string::npos) {
  6681. break;
  6682. }
  6683. size_t next = space + 1;
  6684. while (next < input.length() && isspace(input[next])) {
  6685. ++next;
  6686. }
  6687. input = input.substr(next);
  6688. }
  6689. // Truncate after the first space.
  6690. size_t space = input.find(' ');
  6691. if (space != string::npos) {
  6692. input = input.substr(0, space);
  6693. }
  6694. vector_string components;
  6695. tokenize(input, components, ".");
  6696. if (components.size() >= 1) {
  6697. string_to_int(components[0], _gl_version_major);
  6698. }
  6699. if (components.size() >= 2) {
  6700. string_to_int(components[1], _gl_version_minor);
  6701. }
  6702. if (GLCAT.is_debug()) {
  6703. GLCAT.debug()
  6704. << "GL_VERSION decoded to: "
  6705. << _gl_version_major << "." << _gl_version_minor
  6706. << "\n";
  6707. }
  6708. }
  6709. }
  6710. /**
  6711. * Queries the supported GLSL version.
  6712. */
  6713. void CLP(GraphicsStateGuardian)::
  6714. query_glsl_version() {
  6715. _gl_shadlang_ver_major = 0;
  6716. _gl_shadlang_ver_minor = 0;
  6717. #ifndef OPENGLES_1
  6718. #ifndef OPENGLES
  6719. // OpenGL 2.0 introduces GLSL in the core. In 1.x, it is an extension.
  6720. if (_gl_version_major >= 2 || has_extension("GL_ARB_shading_language_100")) {
  6721. string ver = show_gl_string("GL_SHADING_LANGUAGE_VERSION", GL_SHADING_LANGUAGE_VERSION);
  6722. _gl_shadlang_ver_major = 1;
  6723. _gl_shadlang_ver_minor = (_gl_version_major >= 2) ? 1 : 0;
  6724. if (ver.empty() ||
  6725. sscanf(ver.c_str(), "%d.%d", &_gl_shadlang_ver_major,
  6726. &_gl_shadlang_ver_minor) != 2) {
  6727. GLCAT.warning() << "Invalid GL_SHADING_LANGUAGE_VERSION format: " << ver << "\n";
  6728. }
  6729. }
  6730. #else
  6731. // OpenGL ES 2.0 and above has shader support built-in.
  6732. string ver = show_gl_string("GL_SHADING_LANGUAGE_VERSION", GL_SHADING_LANGUAGE_VERSION);
  6733. _gl_shadlang_ver_major = 1;
  6734. _gl_shadlang_ver_minor = 0;
  6735. if (ver.empty() ||
  6736. sscanf(ver.c_str(), "OpenGL ES GLSL ES %d.%d", &_gl_shadlang_ver_major,
  6737. &_gl_shadlang_ver_minor) != 2) {
  6738. #ifdef __EMSCRIPTEN__ // See emscripten bug 4070
  6739. if (sscanf(ver.c_str(), "OpenGL ES GLSL %d.%d", &_gl_shadlang_ver_major,
  6740. &_gl_shadlang_ver_minor) != 2)
  6741. #endif
  6742. GLCAT.warning() << "Invalid GL_SHADING_LANGUAGE_VERSION format: " << ver << "\n";
  6743. }
  6744. #endif
  6745. if (GLCAT.is_debug()) {
  6746. GLCAT.debug()
  6747. << "Detected GLSL "
  6748. #ifdef OPENGLES
  6749. "ES "
  6750. #endif
  6751. "version: "
  6752. << _gl_shadlang_ver_major << "." << _gl_shadlang_ver_minor << "\n";
  6753. }
  6754. #endif // !OPENGLES_1
  6755. }
  6756. /**
  6757. * Separates the string returned by GL_EXTENSIONS (or glx or wgl extensions)
  6758. * into its individual tokens and saves them in the _extensions member.
  6759. */
  6760. void CLP(GraphicsStateGuardian)::
  6761. save_extensions(const char *extensions) {
  6762. if (extensions != (const char *)NULL) {
  6763. vector_string tokens;
  6764. extract_words(extensions, tokens);
  6765. vector_string::iterator ti;
  6766. for (ti = tokens.begin(); ti != tokens.end(); ++ti) {
  6767. _extensions.insert(*ti);
  6768. }
  6769. }
  6770. }
  6771. /**
  6772. * This may be redefined by a derived class (e.g. glx or wgl) to get whatever
  6773. * further extensions strings may be appropriate to that interface, in
  6774. * addition to the GL extension strings return by glGetString().
  6775. */
  6776. void CLP(GraphicsStateGuardian)::
  6777. get_extra_extensions() {
  6778. }
  6779. /**
  6780. * Outputs the list of GL extensions to notify, if debug mode is enabled.
  6781. */
  6782. void CLP(GraphicsStateGuardian)::
  6783. report_extensions() const {
  6784. if (GLCAT.is_debug()) {
  6785. ostream &out = GLCAT.debug();
  6786. out << "GL Extensions:\n";
  6787. size_t maxlen = 0;
  6788. pset<string>::const_iterator ei;
  6789. for (ei = _extensions.begin(); ei != _extensions.end(); ++ei) {
  6790. size_t len = (*ei).size();
  6791. out << " " << (*ei);
  6792. // Display a second column.
  6793. if (len <= 38) {
  6794. if (++ei != _extensions.end()) {
  6795. for (int i = len; i < 38; ++i) {
  6796. out.put(' ');
  6797. }
  6798. out << ' ' << (*ei);
  6799. } else {
  6800. out.put('\n');
  6801. break;
  6802. }
  6803. }
  6804. out.put('\n');
  6805. }
  6806. }
  6807. }
  6808. /**
  6809. * Returns the pointer to the GL extension function with the indicated name,
  6810. * or NULL if the function is not available.
  6811. */
  6812. void *CLP(GraphicsStateGuardian)::
  6813. get_extension_func(const char *name) {
  6814. // First, look in the static-compiled namespace. If we were compiled to
  6815. // expect at least a certain minimum runtime version of OpenGL, then we can
  6816. // expect those extension functions to be available at compile time.
  6817. // Somewhat more reliable than poking around in the runtime pointers.
  6818. static struct {
  6819. const char *name;
  6820. void *fptr;
  6821. } compiled_function_table[] = {
  6822. #ifdef EXPECT_GL_VERSION_1_2
  6823. { "glBlendColor", (void *)&glBlendColor },
  6824. { "glBlendEquation", (void *)&glBlendEquation },
  6825. { "glDrawRangeElements", (void *)&glDrawRangeElements },
  6826. { "glTexImage3D", (void *)&glTexImage3D },
  6827. { "glTexSubImage3D", (void *)&glTexSubImage3D },
  6828. { "glCopyTexSubImage3D", (void *)&glCopyTexSubImage3D },
  6829. #endif
  6830. #ifdef EXPECT_GL_VERSION_1_3
  6831. { "glActiveTexture", (void *)&glActiveTexture },
  6832. { "glClientActiveTexture", (void *)&glClientActiveTexture },
  6833. { "glCompressedTexImage1D", (void *)&glCompressedTexImage1D },
  6834. { "glCompressedTexImage2D", (void *)&glCompressedTexImage2D },
  6835. { "glCompressedTexImage3D", (void *)&glCompressedTexImage3D },
  6836. { "glCompressedTexSubImage1D", (void *)&glCompressedTexSubImage1D },
  6837. { "glCompressedTexSubImage2D", (void *)&glCompressedTexSubImage2D },
  6838. { "glCompressedTexSubImage3D", (void *)&glCompressedTexSubImage3D },
  6839. { "glGetCompressedTexImage", (void *)&glGetCompressedTexImage },
  6840. { "glMultiTexCoord1f", (void *)&glMultiTexCoord1f },
  6841. { "glMultiTexCoord2", (void *)&glMultiTexCoord2 },
  6842. { "glMultiTexCoord3", (void *)&glMultiTexCoord3 },
  6843. { "glMultiTexCoord4", (void *)&glMultiTexCoord4 },
  6844. #endif
  6845. #ifdef EXPECT_GL_VERSION_1_4
  6846. { "glPointParameterfv", (void *)&glPointParameterfv },
  6847. { "glSecondaryColorPointer", (void *)&glSecondaryColorPointer },
  6848. #endif
  6849. #ifdef EXPECT_GL_VERSION_1_5
  6850. { "glBeginQuery", (void *)&glBeginQuery },
  6851. { "glBindBuffer", (void *)&glBindBuffer },
  6852. { "glBufferData", (void *)&glBufferData },
  6853. { "glBufferSubData", (void *)&glBufferSubData },
  6854. { "glDeleteBuffers", (void *)&glDeleteBuffers },
  6855. { "glDeleteQueries", (void *)&glDeleteQueries },
  6856. { "glEndQuery", (void *)&glEndQuery },
  6857. { "glGenBuffers", (void *)&glGenBuffers },
  6858. { "glGenQueries", (void *)&glGenQueries },
  6859. { "glGetQueryObjectuiv", (void *)&glGetQueryObjectuiv },
  6860. { "glGetQueryiv", (void *)&glGetQueryiv },
  6861. #endif
  6862. #ifdef OPENGLES
  6863. { "glActiveTexture", (void *)&glActiveTexture },
  6864. #ifndef OPENGLES_2
  6865. { "glClientActiveTexture", (void *)&glClientActiveTexture },
  6866. #endif
  6867. { "glBindBuffer", (void *)&glBindBuffer },
  6868. { "glBufferData", (void *)&glBufferData },
  6869. { "glBufferSubData", (void *)&glBufferSubData },
  6870. { "glDeleteBuffers", (void *)&glDeleteBuffers },
  6871. { "glGenBuffers", (void *)&glGenBuffers },
  6872. #endif
  6873. { NULL, NULL }
  6874. };
  6875. int i = 0;
  6876. while (compiled_function_table[i].name != NULL) {
  6877. if (strcmp(compiled_function_table[i].name, name) == 0) {
  6878. return compiled_function_table[i].fptr;
  6879. }
  6880. ++i;
  6881. }
  6882. // If the extension function wasn't compiled in, then go get it from the
  6883. // runtime. There's a different interface for each API.
  6884. return do_get_extension_func(name);
  6885. }
  6886. /**
  6887. * This is the virtual implementation of get_extension_func(). Each API-
  6888. * specific GL implementation will map this method to the appropriate API call
  6889. * to retrieve the extension function pointer. Returns NULL if the function
  6890. * is not available.
  6891. */
  6892. void *CLP(GraphicsStateGuardian)::
  6893. do_get_extension_func(const char *) {
  6894. return NULL;
  6895. }
  6896. /**
  6897. * Sets up the glDrawBuffer to render into the buffer indicated by the
  6898. * RenderBuffer object. This only sets up the color and aux bits; it does not
  6899. * affect the depth, stencil, accum layers.
  6900. */
  6901. void CLP(GraphicsStateGuardian)::
  6902. set_draw_buffer(int rbtype) {
  6903. #ifndef OPENGLES // Draw buffers not supported by OpenGL ES. (TODO!)
  6904. if (_current_fbo) {
  6905. GLuint buffers[16];
  6906. int nbuffers = 0;
  6907. int index = 0;
  6908. if (_current_properties->get_color_bits() > 0) {
  6909. if (rbtype & RenderBuffer::T_left) {
  6910. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index;
  6911. }
  6912. ++index;
  6913. if (_current_properties->is_stereo()) {
  6914. if (rbtype & RenderBuffer::T_right) {
  6915. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index;
  6916. }
  6917. ++index;
  6918. }
  6919. }
  6920. for (int i = 0; i < _current_properties->get_aux_rgba(); ++i) {
  6921. if (rbtype & (RenderBuffer::T_aux_rgba_0 << i)) {
  6922. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index;
  6923. }
  6924. ++index;
  6925. }
  6926. for (int i = 0; i < _current_properties->get_aux_hrgba(); ++i) {
  6927. if (rbtype & (RenderBuffer::T_aux_hrgba_0 << i)) {
  6928. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index;
  6929. }
  6930. ++index;
  6931. }
  6932. for (int i = 0; i < _current_properties->get_aux_float(); ++i) {
  6933. if (rbtype & (RenderBuffer::T_aux_float_0 << i)) {
  6934. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index;
  6935. }
  6936. ++index;
  6937. }
  6938. _glDrawBuffers(nbuffers, buffers);
  6939. } else {
  6940. switch (rbtype & RenderBuffer::T_color) {
  6941. case RenderBuffer::T_front:
  6942. glDrawBuffer(GL_FRONT);
  6943. break;
  6944. case RenderBuffer::T_back:
  6945. glDrawBuffer(GL_BACK);
  6946. break;
  6947. case RenderBuffer::T_right:
  6948. glDrawBuffer(GL_RIGHT);
  6949. break;
  6950. case RenderBuffer::T_left:
  6951. glDrawBuffer(GL_LEFT);
  6952. break;
  6953. case RenderBuffer::T_front_right:
  6954. nassertv(_current_properties->is_stereo());
  6955. glDrawBuffer(GL_FRONT_RIGHT);
  6956. break;
  6957. case RenderBuffer::T_front_left:
  6958. nassertv(_current_properties->is_stereo());
  6959. glDrawBuffer(GL_FRONT_LEFT);
  6960. break;
  6961. case RenderBuffer::T_back_right:
  6962. nassertv(_current_properties->is_stereo());
  6963. glDrawBuffer(GL_BACK_RIGHT);
  6964. break;
  6965. case RenderBuffer::T_back_left:
  6966. nassertv(_current_properties->is_stereo());
  6967. glDrawBuffer(GL_BACK_LEFT);
  6968. break;
  6969. default:
  6970. break;
  6971. }
  6972. }
  6973. #endif // OPENGLES
  6974. // Also ensure that any global color channels are masked out.
  6975. set_color_write_mask(_color_write_mask);
  6976. report_my_gl_errors();
  6977. }
  6978. /**
  6979. * Sets up the glReadBuffer to render into the buffer indicated by the
  6980. * RenderBuffer object. This only sets up the color bits; it does not affect
  6981. * the depth, stencil, accum layers.
  6982. */
  6983. void CLP(GraphicsStateGuardian)::
  6984. set_read_buffer(int rbtype) {
  6985. #ifndef OPENGLES // Draw buffers not supported by OpenGL ES. (TODO!)
  6986. if (rbtype & (RenderBuffer::T_depth | RenderBuffer::T_stencil)) {
  6987. // Special case: don't have to call ReadBuffer for these.
  6988. return;
  6989. }
  6990. if (_current_fbo) {
  6991. GLuint buffer = GL_COLOR_ATTACHMENT0_EXT;
  6992. int index = 1;
  6993. if (_current_properties->is_stereo()) {
  6994. if (rbtype & RenderBuffer::T_right) {
  6995. buffer = GL_COLOR_ATTACHMENT1_EXT;
  6996. }
  6997. ++index;
  6998. }
  6999. for (int i = 0; i < _current_properties->get_aux_rgba(); ++i) {
  7000. if (rbtype & (RenderBuffer::T_aux_rgba_0 << i)) {
  7001. buffer = GL_COLOR_ATTACHMENT0_EXT + index;
  7002. }
  7003. ++index;
  7004. }
  7005. for (int i = 0; i < _current_properties->get_aux_hrgba(); ++i) {
  7006. if (rbtype & (RenderBuffer::T_aux_hrgba_0 << i)) {
  7007. buffer = GL_COLOR_ATTACHMENT0_EXT + index;
  7008. }
  7009. ++index;
  7010. }
  7011. for (int i = 0; i < _current_properties->get_aux_float(); ++i) {
  7012. if (rbtype & (RenderBuffer::T_aux_float_0 << i)) {
  7013. buffer = GL_COLOR_ATTACHMENT0_EXT + index;
  7014. }
  7015. ++index;
  7016. }
  7017. glReadBuffer(buffer);
  7018. } else {
  7019. switch (rbtype & RenderBuffer::T_color) {
  7020. case RenderBuffer::T_front:
  7021. glReadBuffer(GL_FRONT);
  7022. break;
  7023. case RenderBuffer::T_back:
  7024. glReadBuffer(GL_BACK);
  7025. break;
  7026. case RenderBuffer::T_right:
  7027. glReadBuffer(GL_RIGHT);
  7028. break;
  7029. case RenderBuffer::T_left:
  7030. glReadBuffer(GL_LEFT);
  7031. break;
  7032. case RenderBuffer::T_front_right:
  7033. glReadBuffer(GL_FRONT_RIGHT);
  7034. break;
  7035. case RenderBuffer::T_front_left:
  7036. glReadBuffer(GL_FRONT_LEFT);
  7037. break;
  7038. case RenderBuffer::T_back_right:
  7039. glReadBuffer(GL_BACK_RIGHT);
  7040. break;
  7041. case RenderBuffer::T_back_left:
  7042. glReadBuffer(GL_BACK_LEFT);
  7043. break;
  7044. default:
  7045. break;
  7046. }
  7047. }
  7048. report_my_gl_errors();
  7049. #endif // OPENGLES
  7050. }
  7051. /**
  7052. * Maps from the Geom's internal numeric type symbols to GL's.
  7053. */
  7054. GLenum CLP(GraphicsStateGuardian)::
  7055. get_numeric_type(Geom::NumericType numeric_type) {
  7056. switch (numeric_type) {
  7057. case Geom::NT_uint16:
  7058. return GL_UNSIGNED_SHORT;
  7059. case Geom::NT_uint32:
  7060. #ifndef OPENGLES_1
  7061. return GL_UNSIGNED_INT;
  7062. #else
  7063. break;
  7064. #endif
  7065. case Geom::NT_uint8:
  7066. case Geom::NT_packed_dcba:
  7067. case Geom::NT_packed_dabc:
  7068. return GL_UNSIGNED_BYTE;
  7069. case Geom::NT_float32:
  7070. return GL_FLOAT;
  7071. case Geom::NT_float64:
  7072. #ifndef OPENGLES
  7073. return GL_DOUBLE;
  7074. #else
  7075. break;
  7076. #endif
  7077. case Geom::NT_stdfloat:
  7078. // Shouldn't happen, display error.
  7079. break;
  7080. case Geom::NT_int8:
  7081. return GL_BYTE;
  7082. case Geom::NT_int16:
  7083. return GL_SHORT;
  7084. case Geom::NT_int32:
  7085. #ifndef OPENGLES_1
  7086. return GL_INT;
  7087. #else
  7088. break;
  7089. #endif
  7090. case Geom::NT_packed_ufloat:
  7091. #ifndef OPENGLES_1
  7092. return GL_UNSIGNED_INT_10F_11F_11F_REV;
  7093. #else
  7094. break;
  7095. #endif
  7096. }
  7097. GLCAT.error()
  7098. << "Invalid NumericType value (" << (int)numeric_type << ")\n";
  7099. return GL_UNSIGNED_BYTE;
  7100. }
  7101. /**
  7102. * Maps from the Texture's texture type symbols to GL's.
  7103. */
  7104. GLenum CLP(GraphicsStateGuardian)::
  7105. get_texture_target(Texture::TextureType texture_type) const {
  7106. switch (texture_type) {
  7107. case Texture::TT_1d_texture:
  7108. // There are no 1D textures in OpenGL ES. Fall back to 2D textures.
  7109. #ifndef OPENGLES
  7110. return GL_TEXTURE_1D;
  7111. #endif
  7112. case Texture::TT_2d_texture:
  7113. return GL_TEXTURE_2D;
  7114. case Texture::TT_3d_texture:
  7115. #ifndef OPENGLES_1
  7116. if (_supports_3d_texture) {
  7117. return GL_TEXTURE_3D;
  7118. }
  7119. #endif
  7120. return GL_NONE;
  7121. case Texture::TT_2d_texture_array:
  7122. #ifndef OPENGLES_1
  7123. if (_supports_2d_texture_array) {
  7124. return GL_TEXTURE_2D_ARRAY;
  7125. }
  7126. #endif
  7127. return GL_NONE;
  7128. case Texture::TT_cube_map:
  7129. if (_supports_cube_map) {
  7130. return GL_TEXTURE_CUBE_MAP;
  7131. } else {
  7132. return GL_NONE;
  7133. }
  7134. case Texture::TT_cube_map_array:
  7135. #ifndef OPENGLES
  7136. if (_supports_cube_map_array) {
  7137. return GL_TEXTURE_CUBE_MAP_ARRAY;
  7138. }
  7139. #endif
  7140. return GL_NONE;
  7141. case Texture::TT_buffer_texture:
  7142. #ifndef OPENGLES
  7143. if (_supports_buffer_texture) {
  7144. return GL_TEXTURE_BUFFER;
  7145. }
  7146. #endif
  7147. return GL_NONE;
  7148. }
  7149. GLCAT.error() << "Invalid Texture::TextureType value!\n";
  7150. return GL_TEXTURE_2D;
  7151. }
  7152. /**
  7153. * Maps from the Texture's internal wrap mode symbols to GL's.
  7154. */
  7155. GLenum CLP(GraphicsStateGuardian)::
  7156. get_texture_wrap_mode(SamplerState::WrapMode wm) const {
  7157. if (gl_ignore_clamp) {
  7158. return GL_REPEAT;
  7159. }
  7160. switch (wm) {
  7161. case SamplerState::WM_clamp:
  7162. return _edge_clamp;
  7163. case SamplerState::WM_repeat:
  7164. return GL_REPEAT;
  7165. case SamplerState::WM_mirror:
  7166. return _mirror_repeat;
  7167. case SamplerState::WM_mirror_once:
  7168. return _mirror_border_clamp;
  7169. case SamplerState::WM_border_color:
  7170. return _border_clamp;
  7171. case SamplerState::WM_invalid:
  7172. break;
  7173. }
  7174. GLCAT.error() << "Invalid SamplerState::WrapMode value!\n";
  7175. return _edge_clamp;
  7176. }
  7177. /**
  7178. * Maps from the GL's internal wrap mode symbols to Panda's.
  7179. */
  7180. SamplerState::WrapMode CLP(GraphicsStateGuardian)::
  7181. get_panda_wrap_mode(GLenum wm) {
  7182. switch (wm) {
  7183. #ifndef OPENGLES
  7184. case GL_CLAMP:
  7185. #endif
  7186. case GL_CLAMP_TO_EDGE:
  7187. return SamplerState::WM_clamp;
  7188. #ifndef OPENGLES
  7189. case GL_CLAMP_TO_BORDER:
  7190. return SamplerState::WM_border_color;
  7191. #endif
  7192. case GL_REPEAT:
  7193. return SamplerState::WM_repeat;
  7194. #ifndef OPENGLES
  7195. case GL_MIRROR_CLAMP_EXT:
  7196. case GL_MIRROR_CLAMP_TO_EDGE_EXT:
  7197. return SamplerState::WM_mirror;
  7198. case GL_MIRROR_CLAMP_TO_BORDER_EXT:
  7199. return SamplerState::WM_mirror_once;
  7200. #endif
  7201. }
  7202. GLCAT.error() << "Unexpected GL wrap mode " << (int)wm << "\n";
  7203. return SamplerState::WM_clamp;
  7204. }
  7205. /**
  7206. * Maps from the Texture's internal filter type symbols to GL's.
  7207. */
  7208. GLenum CLP(GraphicsStateGuardian)::
  7209. get_texture_filter_type(SamplerState::FilterType ft, bool ignore_mipmaps) {
  7210. if (gl_ignore_filters) {
  7211. return GL_NEAREST;
  7212. } else if (ignore_mipmaps) {
  7213. switch (ft) {
  7214. case SamplerState::FT_nearest_mipmap_nearest:
  7215. case SamplerState::FT_nearest:
  7216. return GL_NEAREST;
  7217. case SamplerState::FT_linear:
  7218. case SamplerState::FT_linear_mipmap_nearest:
  7219. case SamplerState::FT_nearest_mipmap_linear:
  7220. case SamplerState::FT_linear_mipmap_linear:
  7221. return GL_LINEAR;
  7222. case SamplerState::FT_shadow:
  7223. return GL_LINEAR;
  7224. case SamplerState::FT_default:
  7225. case SamplerState::FT_invalid:
  7226. break;
  7227. }
  7228. } else {
  7229. switch (ft) {
  7230. case SamplerState::FT_nearest:
  7231. return GL_NEAREST;
  7232. case SamplerState::FT_linear:
  7233. return GL_LINEAR;
  7234. case SamplerState::FT_nearest_mipmap_nearest:
  7235. return GL_NEAREST_MIPMAP_NEAREST;
  7236. case SamplerState::FT_linear_mipmap_nearest:
  7237. return GL_LINEAR_MIPMAP_NEAREST;
  7238. case SamplerState::FT_nearest_mipmap_linear:
  7239. return GL_NEAREST_MIPMAP_LINEAR;
  7240. case SamplerState::FT_linear_mipmap_linear:
  7241. return GL_LINEAR_MIPMAP_LINEAR;
  7242. case SamplerState::FT_shadow:
  7243. return GL_LINEAR;
  7244. case SamplerState::FT_default:
  7245. case SamplerState::FT_invalid:
  7246. break;
  7247. }
  7248. }
  7249. GLCAT.error() << "Invalid SamplerState::FilterType value!\n";
  7250. return GL_NEAREST;
  7251. }
  7252. /**
  7253. * Maps from the GL's internal filter type symbols to Panda's.
  7254. */
  7255. SamplerState::FilterType CLP(GraphicsStateGuardian)::
  7256. get_panda_filter_type(GLenum ft) {
  7257. switch (ft) {
  7258. case GL_NEAREST:
  7259. return SamplerState::FT_nearest;
  7260. case GL_LINEAR:
  7261. return SamplerState::FT_linear;
  7262. case GL_NEAREST_MIPMAP_NEAREST:
  7263. return SamplerState::FT_nearest_mipmap_nearest;
  7264. case GL_LINEAR_MIPMAP_NEAREST:
  7265. return SamplerState::FT_linear_mipmap_nearest;
  7266. case GL_NEAREST_MIPMAP_LINEAR:
  7267. return SamplerState::FT_nearest_mipmap_linear;
  7268. case GL_LINEAR_MIPMAP_LINEAR:
  7269. return SamplerState::FT_linear_mipmap_linear;
  7270. }
  7271. GLCAT.error() << "Unexpected GL filter type " << (int)ft << "\n";
  7272. return SamplerState::FT_linear;
  7273. }
  7274. /**
  7275. * Maps from the Texture's internal ComponentType symbols to GL's.
  7276. */
  7277. GLenum CLP(GraphicsStateGuardian)::
  7278. get_component_type(Texture::ComponentType component_type) {
  7279. switch (component_type) {
  7280. case Texture::T_unsigned_byte:
  7281. return GL_UNSIGNED_BYTE;
  7282. case Texture::T_unsigned_short:
  7283. return GL_UNSIGNED_SHORT;
  7284. case Texture::T_float:
  7285. return GL_FLOAT;
  7286. case Texture::T_unsigned_int_24_8:
  7287. if (_supports_depth_stencil) {
  7288. return GL_UNSIGNED_INT_24_8_EXT;
  7289. } else {
  7290. return GL_UNSIGNED_BYTE;
  7291. }
  7292. case Texture::T_int:
  7293. #ifndef OPENGLES_1
  7294. return GL_INT;
  7295. #endif
  7296. case Texture::T_byte:
  7297. return GL_BYTE;
  7298. case Texture::T_short:
  7299. return GL_SHORT;
  7300. #ifndef OPENGLES_1
  7301. case Texture::T_half_float:
  7302. return GL_HALF_FLOAT;
  7303. #endif
  7304. default:
  7305. GLCAT.error() << "Invalid Texture::Type value!\n";
  7306. return GL_UNSIGNED_BYTE;
  7307. }
  7308. }
  7309. /**
  7310. * Maps from the Texture's Format symbols to GL's.
  7311. */
  7312. GLint CLP(GraphicsStateGuardian)::
  7313. get_external_image_format(Texture *tex) const {
  7314. Texture::CompressionMode compression = tex->get_ram_image_compression();
  7315. Texture::Format format = tex->get_format();
  7316. if (compression != Texture::CM_off &&
  7317. get_supports_compressed_texture_format(compression)) {
  7318. switch (compression) {
  7319. case Texture::CM_on:
  7320. #ifndef OPENGLES
  7321. switch (format) {
  7322. case Texture::F_color_index:
  7323. case Texture::F_depth_component:
  7324. case Texture::F_depth_component16:
  7325. case Texture::F_depth_component24:
  7326. case Texture::F_depth_component32:
  7327. case Texture::F_depth_stencil:
  7328. case Texture::F_r11_g11_b10:
  7329. case Texture::F_rgb9_e5:
  7330. // This shouldn't be possible.
  7331. nassertr(false, GL_RGB);
  7332. break;
  7333. case Texture::F_rgba:
  7334. case Texture::F_rgbm:
  7335. case Texture::F_rgba4:
  7336. case Texture::F_rgba8:
  7337. case Texture::F_rgba12:
  7338. case Texture::F_rgba16:
  7339. case Texture::F_rgba32:
  7340. case Texture::F_rgba8i:
  7341. case Texture::F_rgb10_a2:
  7342. return GL_COMPRESSED_RGBA;
  7343. case Texture::F_rgb:
  7344. case Texture::F_rgb5:
  7345. case Texture::F_rgba5:
  7346. case Texture::F_rgb8:
  7347. case Texture::F_rgb8i:
  7348. case Texture::F_rgb12:
  7349. case Texture::F_rgb332:
  7350. case Texture::F_rgb16:
  7351. case Texture::F_rgb32:
  7352. return GL_COMPRESSED_RGB;
  7353. case Texture::F_alpha:
  7354. return GL_COMPRESSED_ALPHA;
  7355. case Texture::F_red:
  7356. case Texture::F_green:
  7357. case Texture::F_blue:
  7358. case Texture::F_r8i:
  7359. case Texture::F_r16:
  7360. case Texture::F_r16i:
  7361. case Texture::F_r32:
  7362. case Texture::F_r32i:
  7363. return GL_COMPRESSED_RED;
  7364. case Texture::F_rg:
  7365. case Texture::F_rg8i:
  7366. case Texture::F_rg16:
  7367. case Texture::F_rg32:
  7368. return GL_COMPRESSED_RG;
  7369. case Texture::F_luminance:
  7370. return GL_COMPRESSED_LUMINANCE;
  7371. case Texture::F_luminance_alpha:
  7372. case Texture::F_luminance_alphamask:
  7373. return GL_COMPRESSED_LUMINANCE_ALPHA;
  7374. case Texture::F_srgb:
  7375. return GL_COMPRESSED_SRGB;
  7376. case Texture::F_srgb_alpha:
  7377. return GL_COMPRESSED_SRGB_ALPHA;
  7378. case Texture::F_sluminance:
  7379. return GL_COMPRESSED_SLUMINANCE;
  7380. case Texture::F_sluminance_alpha:
  7381. return GL_COMPRESSED_SLUMINANCE_ALPHA;
  7382. }
  7383. #endif
  7384. break;
  7385. case Texture::CM_dxt1:
  7386. #ifndef OPENGLES
  7387. if (format == Texture::F_srgb_alpha) {
  7388. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
  7389. } else if (format == Texture::F_srgb) {
  7390. return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
  7391. } else
  7392. #endif
  7393. if (Texture::has_alpha(format)) {
  7394. return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
  7395. } else {
  7396. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  7397. }
  7398. case Texture::CM_dxt3:
  7399. #ifndef OPENGLES
  7400. if (format == Texture::F_srgb || format == Texture::F_srgb_alpha) {
  7401. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
  7402. }
  7403. #endif
  7404. #ifndef OPENGLES_1
  7405. return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
  7406. #endif
  7407. break;
  7408. case Texture::CM_dxt5:
  7409. #ifndef OPENGLES
  7410. if (format == Texture::F_srgb || format == Texture::F_srgb_alpha) {
  7411. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
  7412. }
  7413. #endif
  7414. #ifndef OPENGLES_1
  7415. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  7416. #endif
  7417. break;
  7418. case Texture::CM_fxt1:
  7419. #ifndef OPENGLES
  7420. if (Texture::has_alpha(format)) {
  7421. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  7422. } else {
  7423. return GL_COMPRESSED_RGB_FXT1_3DFX;
  7424. }
  7425. #endif
  7426. break;
  7427. #ifdef OPENGLES
  7428. case Texture::CM_pvr1_2bpp:
  7429. if (Texture::has_alpha(format)) {
  7430. return GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
  7431. } else {
  7432. return GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
  7433. }
  7434. case Texture::CM_pvr1_4bpp:
  7435. if (Texture::has_alpha(format)) {
  7436. return GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
  7437. } else {
  7438. return GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
  7439. }
  7440. #else
  7441. case Texture::CM_pvr1_2bpp:
  7442. case Texture::CM_pvr1_4bpp:
  7443. break;
  7444. #endif // OPENGLES
  7445. case Texture::CM_rgtc:
  7446. #ifndef OPENGLES
  7447. if (tex->get_format() == Texture::F_luminance) {
  7448. return GL_COMPRESSED_LUMINANCE_LATC1_EXT;
  7449. } else if (tex->get_format() == Texture::F_luminance_alpha) {
  7450. return GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT;
  7451. } else if (tex->get_num_components() == 1) {
  7452. return GL_COMPRESSED_RED_RGTC1;
  7453. } else {
  7454. return GL_COMPRESSED_RG_RGTC2;
  7455. }
  7456. #endif
  7457. break;
  7458. case Texture::CM_default:
  7459. case Texture::CM_off:
  7460. case Texture::CM_dxt2:
  7461. case Texture::CM_dxt4:
  7462. // This shouldn't happen.
  7463. nassertr(false, GL_RGB);
  7464. break;
  7465. }
  7466. }
  7467. switch (format) {
  7468. #ifndef OPENGLES
  7469. case Texture::F_color_index:
  7470. return GL_COLOR_INDEX;
  7471. #endif
  7472. case Texture::F_depth_component:
  7473. case Texture::F_depth_component16:
  7474. case Texture::F_depth_component24:
  7475. case Texture::F_depth_component32:
  7476. return GL_DEPTH_COMPONENT;
  7477. case Texture::F_depth_stencil:
  7478. return _supports_depth_stencil ? GL_DEPTH_STENCIL : GL_DEPTH_COMPONENT;
  7479. #ifndef OPENGLES
  7480. case Texture::F_red:
  7481. case Texture::F_r16:
  7482. case Texture::F_r32:
  7483. return GL_RED;
  7484. case Texture::F_green:
  7485. return GL_GREEN;
  7486. case Texture::F_blue:
  7487. return GL_BLUE;
  7488. #endif
  7489. case Texture::F_alpha:
  7490. #if defined(SUPPORT_FIXED_FUNCTION) || defined(OPENGLES)
  7491. return GL_ALPHA;
  7492. #else
  7493. return GL_RED;
  7494. #endif
  7495. #ifndef OPENGLES_1
  7496. case Texture::F_rg:
  7497. case Texture::F_rg16:
  7498. case Texture::F_rg32:
  7499. return GL_RG;
  7500. #endif
  7501. case Texture::F_rgb:
  7502. case Texture::F_rgb5:
  7503. case Texture::F_rgb8:
  7504. case Texture::F_rgb12:
  7505. case Texture::F_rgb332:
  7506. case Texture::F_rgb16:
  7507. case Texture::F_rgb32:
  7508. case Texture::F_srgb:
  7509. case Texture::F_r11_g11_b10:
  7510. case Texture::F_rgb9_e5:
  7511. #ifdef OPENGLES
  7512. // OpenGL ES never supports BGR, even if _supports_bgr is true.
  7513. return GL_RGB;
  7514. #else
  7515. return _supports_bgr ? GL_BGR : GL_RGB;
  7516. #endif
  7517. case Texture::F_rgba:
  7518. case Texture::F_rgbm:
  7519. case Texture::F_rgba4:
  7520. case Texture::F_rgba5:
  7521. case Texture::F_rgba8:
  7522. case Texture::F_rgba12:
  7523. case Texture::F_rgba16:
  7524. case Texture::F_rgba32:
  7525. case Texture::F_srgb_alpha:
  7526. case Texture::F_rgb10_a2:
  7527. return _supports_bgr ? GL_BGRA : GL_RGBA;
  7528. case Texture::F_luminance:
  7529. case Texture::F_sluminance:
  7530. #if defined(SUPPORT_FIXED_FUNCTION) || defined(OPENGLES)
  7531. return GL_LUMINANCE;
  7532. #else
  7533. return GL_RED;
  7534. #endif
  7535. case Texture::F_luminance_alphamask:
  7536. case Texture::F_luminance_alpha:
  7537. case Texture::F_sluminance_alpha:
  7538. #if defined(SUPPORT_FIXED_FUNCTION) || defined(OPENGLES)
  7539. return GL_LUMINANCE_ALPHA;
  7540. #else
  7541. return GL_RG;
  7542. #endif
  7543. #ifndef OPENGLES_1
  7544. case Texture::F_r8i:
  7545. case Texture::F_r16i:
  7546. case Texture::F_r32i:
  7547. return GL_RED_INTEGER;
  7548. case Texture::F_rg8i:
  7549. return GL_RG_INTEGER;
  7550. case Texture::F_rgb8i:
  7551. return GL_RGB_INTEGER;
  7552. case Texture::F_rgba8i:
  7553. return GL_RGBA_INTEGER;
  7554. #endif
  7555. default:
  7556. break;
  7557. }
  7558. GLCAT.error()
  7559. << "Invalid Texture::Format value in get_external_image_format(): "
  7560. << tex->get_format() << "\n";
  7561. return GL_RGB;
  7562. }
  7563. /**
  7564. * Maps from the Texture's Format symbols to a suitable internal format for GL
  7565. * textures.
  7566. */
  7567. GLint CLP(GraphicsStateGuardian)::
  7568. get_internal_image_format(Texture *tex, bool force_sized) const {
  7569. Texture::CompressionMode compression = tex->get_compression();
  7570. if (compression == Texture::CM_default) {
  7571. compression = (compressed_textures) ? Texture::CM_on : Texture::CM_off;
  7572. }
  7573. Texture::Format format = tex->get_format();
  7574. if (tex->get_render_to_texture()) {
  7575. // no compression for render targets
  7576. compression = Texture::CM_off;
  7577. }
  7578. bool is_3d = (tex->get_texture_type() == Texture::TT_3d_texture ||
  7579. tex->get_texture_type() == Texture::TT_2d_texture_array);
  7580. if (get_supports_compressed_texture_format(compression)) {
  7581. switch (compression) {
  7582. case Texture::CM_on:
  7583. // The user asked for just generic compression. OpenGL supports
  7584. // requesting just generic compression, but we'd like to go ahead and
  7585. // request a specific type (if we can figure out an appropriate choice),
  7586. // since that makes saving the result as a pre-compressed texture more
  7587. // dependable--this way, we will know which compression algorithm was
  7588. // applied.
  7589. switch (format) {
  7590. case Texture::F_color_index:
  7591. case Texture::F_depth_component:
  7592. case Texture::F_depth_component16:
  7593. case Texture::F_depth_component24:
  7594. case Texture::F_depth_component32:
  7595. case Texture::F_depth_stencil:
  7596. case Texture::F_r8i:
  7597. case Texture::F_rg8i:
  7598. case Texture::F_rgb8i:
  7599. case Texture::F_rgba8i:
  7600. case Texture::F_r16i:
  7601. case Texture::F_r32i:
  7602. case Texture::F_r11_g11_b10:
  7603. case Texture::F_rgb9_e5:
  7604. // Unsupported; fall through to below.
  7605. break;
  7606. case Texture::F_rgbm:
  7607. case Texture::F_rgb10_a2:
  7608. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  7609. return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
  7610. }
  7611. #ifndef OPENGLES
  7612. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7613. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  7614. }
  7615. return GL_COMPRESSED_RGBA;
  7616. #endif
  7617. break;
  7618. case Texture::F_rgba4:
  7619. #ifndef OPENGLES_1
  7620. if (get_supports_compressed_texture_format(Texture::CM_dxt3) && !is_3d) {
  7621. return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
  7622. }
  7623. #endif
  7624. #ifndef OPENGLES
  7625. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7626. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  7627. }
  7628. return GL_COMPRESSED_RGBA;
  7629. #endif
  7630. break;
  7631. case Texture::F_rgba:
  7632. case Texture::F_rgba8:
  7633. case Texture::F_rgba12:
  7634. case Texture::F_rgba16:
  7635. case Texture::F_rgba32:
  7636. #ifndef OPENGLES_1
  7637. if (get_supports_compressed_texture_format(Texture::CM_dxt5) && !is_3d) {
  7638. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  7639. }
  7640. #endif
  7641. #ifndef OPENGLES
  7642. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7643. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  7644. }
  7645. return GL_COMPRESSED_RGBA;
  7646. #endif
  7647. break;
  7648. case Texture::F_rgb:
  7649. case Texture::F_rgb5:
  7650. case Texture::F_rgba5:
  7651. case Texture::F_rgb8:
  7652. case Texture::F_rgb12:
  7653. case Texture::F_rgb332:
  7654. case Texture::F_rgb16:
  7655. case Texture::F_rgb32:
  7656. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  7657. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  7658. }
  7659. #ifndef OPENGLES
  7660. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7661. return GL_COMPRESSED_RGB_FXT1_3DFX;
  7662. }
  7663. return GL_COMPRESSED_RGB;
  7664. #endif
  7665. break;
  7666. case Texture::F_alpha:
  7667. #ifndef OPENGLES_1
  7668. if (get_supports_compressed_texture_format(Texture::CM_dxt5) && !is_3d) {
  7669. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  7670. }
  7671. #endif
  7672. #ifndef OPENGLES
  7673. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7674. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  7675. }
  7676. return GL_COMPRESSED_ALPHA;
  7677. #endif
  7678. break;
  7679. case Texture::F_red:
  7680. case Texture::F_green:
  7681. case Texture::F_blue:
  7682. case Texture::F_r16:
  7683. case Texture::F_r32:
  7684. #ifndef OPENGLES
  7685. if (get_supports_compressed_texture_format(Texture::CM_rgtc) && !is_3d) {
  7686. return GL_COMPRESSED_RED_RGTC1;
  7687. }
  7688. #endif
  7689. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  7690. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  7691. }
  7692. #ifndef OPENGLES
  7693. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7694. return GL_COMPRESSED_RGB_FXT1_3DFX;
  7695. }
  7696. return GL_COMPRESSED_RED;
  7697. #endif
  7698. break;
  7699. case Texture::F_rg:
  7700. case Texture::F_rg16:
  7701. case Texture::F_rg32:
  7702. #ifndef OPENGLES
  7703. if (get_supports_compressed_texture_format(Texture::CM_rgtc) && !is_3d) {
  7704. return GL_COMPRESSED_RG_RGTC2;
  7705. }
  7706. #endif
  7707. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  7708. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  7709. }
  7710. #ifndef OPENGLES
  7711. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7712. return GL_COMPRESSED_RGB_FXT1_3DFX;
  7713. }
  7714. return GL_COMPRESSED_RG;
  7715. #endif
  7716. break;
  7717. case Texture::F_luminance:
  7718. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  7719. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  7720. }
  7721. #ifndef OPENGLES
  7722. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7723. return GL_COMPRESSED_RGB_FXT1_3DFX;
  7724. }
  7725. return GL_COMPRESSED_LUMINANCE;
  7726. #endif
  7727. break;
  7728. case Texture::F_luminance_alpha:
  7729. case Texture::F_luminance_alphamask:
  7730. #ifndef OPENGLES_1
  7731. if (get_supports_compressed_texture_format(Texture::CM_dxt5) && !is_3d) {
  7732. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  7733. }
  7734. #endif
  7735. #ifndef OPENGLES
  7736. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7737. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  7738. }
  7739. return GL_COMPRESSED_LUMINANCE_ALPHA;
  7740. #endif
  7741. break;
  7742. #ifndef OPENGLES
  7743. case Texture::F_srgb:
  7744. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  7745. return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
  7746. }
  7747. return GL_COMPRESSED_SRGB;
  7748. case Texture::F_srgb_alpha:
  7749. if (get_supports_compressed_texture_format(Texture::CM_dxt5) && !is_3d) {
  7750. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
  7751. }
  7752. return GL_COMPRESSED_SRGB_ALPHA;
  7753. case Texture::F_sluminance:
  7754. return GL_COMPRESSED_SLUMINANCE;
  7755. case Texture::F_sluminance_alpha:
  7756. return GL_COMPRESSED_SLUMINANCE_ALPHA;
  7757. #else
  7758. // For now, we don't support compressed sRGB textures in OpenGL ES.
  7759. case Texture::F_srgb:
  7760. case Texture::F_srgb_alpha:
  7761. case Texture::F_sluminance:
  7762. case Texture::F_sluminance_alpha:
  7763. break;
  7764. #endif
  7765. }
  7766. break;
  7767. case Texture::CM_dxt1:
  7768. #ifndef OPENGLES
  7769. if (format == Texture::F_srgb_alpha) {
  7770. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
  7771. } else if (format == Texture::F_srgb) {
  7772. return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
  7773. } else
  7774. #endif
  7775. if (Texture::has_alpha(format)) {
  7776. return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
  7777. } else {
  7778. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  7779. }
  7780. case Texture::CM_dxt3:
  7781. #ifndef OPENGLES
  7782. if (format == Texture::F_srgb || format == Texture::F_srgb_alpha) {
  7783. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
  7784. }
  7785. #endif
  7786. #ifndef OPENGLES_1
  7787. return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
  7788. #endif
  7789. break;
  7790. case Texture::CM_dxt5:
  7791. #ifndef OPENGLES
  7792. if (format == Texture::F_srgb || format == Texture::F_srgb_alpha) {
  7793. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
  7794. }
  7795. #endif
  7796. #ifndef OPENGLES_1
  7797. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  7798. #endif
  7799. case Texture::CM_fxt1:
  7800. #ifndef OPENGLES
  7801. if (Texture::has_alpha(format)) {
  7802. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  7803. } else {
  7804. return GL_COMPRESSED_RGB_FXT1_3DFX;
  7805. }
  7806. #endif
  7807. break;
  7808. #ifdef OPENGLES
  7809. case Texture::CM_pvr1_2bpp:
  7810. if (Texture::has_alpha(format)) {
  7811. return GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
  7812. } else {
  7813. return GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
  7814. }
  7815. case Texture::CM_pvr1_4bpp:
  7816. if (Texture::has_alpha(format)) {
  7817. return GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
  7818. } else {
  7819. return GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
  7820. }
  7821. #else
  7822. case Texture::CM_pvr1_2bpp:
  7823. case Texture::CM_pvr1_4bpp:
  7824. break;
  7825. #endif
  7826. case Texture::CM_rgtc:
  7827. #ifndef OPENGLES
  7828. if (tex->get_format() == Texture::F_luminance) {
  7829. return GL_COMPRESSED_LUMINANCE_LATC1_EXT;
  7830. } else if (tex->get_format() == Texture::F_luminance_alpha) {
  7831. return GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT;
  7832. } else if (tex->get_num_components() == 1) {
  7833. return GL_COMPRESSED_RED_RGTC1;
  7834. } else if (tex->get_num_components() == 2) {
  7835. return GL_COMPRESSED_RG_RGTC2;
  7836. }
  7837. #endif
  7838. break;
  7839. case Texture::CM_default:
  7840. case Texture::CM_off:
  7841. case Texture::CM_dxt2:
  7842. case Texture::CM_dxt4:
  7843. // No compression: fall through to below.
  7844. break;
  7845. }
  7846. }
  7847. #if defined(__EMSCRIPTEN__) && defined(OPENGLES)
  7848. // WebGL has no sized formats, it would seem.
  7849. return get_external_image_format(tex);
  7850. #endif
  7851. switch (format) {
  7852. #ifndef OPENGLES
  7853. case Texture::F_color_index:
  7854. return GL_COLOR_INDEX;
  7855. #endif
  7856. case Texture::F_depth_stencil:
  7857. if (_supports_depth_stencil) {
  7858. #ifndef OPENGLES
  7859. if (tex->get_component_type() == Texture::T_float) {
  7860. return GL_DEPTH32F_STENCIL8;
  7861. } else
  7862. #endif
  7863. {
  7864. return force_sized ? GL_DEPTH24_STENCIL8 : GL_DEPTH_STENCIL;
  7865. }
  7866. }
  7867. // Fall through.
  7868. case Texture::F_depth_component:
  7869. #ifndef OPENGLES
  7870. if (tex->get_component_type() == Texture::T_float) {
  7871. return GL_DEPTH_COMPONENT32F;
  7872. } else
  7873. #endif
  7874. {
  7875. return force_sized ? GL_DEPTH_COMPONENT16 : GL_DEPTH_COMPONENT;
  7876. }
  7877. case Texture::F_depth_component16:
  7878. #ifdef OPENGLES
  7879. return GL_DEPTH_COMPONENT16_OES;
  7880. #else
  7881. return GL_DEPTH_COMPONENT16;
  7882. #endif
  7883. case Texture::F_depth_component24:
  7884. #ifdef OPENGLES
  7885. if (_supports_depth24) {
  7886. return GL_DEPTH_COMPONENT24_OES;
  7887. } else {
  7888. return GL_DEPTH_COMPONENT16_OES;
  7889. }
  7890. #else
  7891. return GL_DEPTH_COMPONENT24;
  7892. #endif
  7893. case Texture::F_depth_component32:
  7894. #ifdef OPENGLES
  7895. if (_supports_depth32) {
  7896. return GL_DEPTH_COMPONENT32_OES;
  7897. } else if (_supports_depth24) {
  7898. return GL_DEPTH_COMPONENT24_OES;
  7899. } else {
  7900. return GL_DEPTH_COMPONENT16_OES;
  7901. }
  7902. #else
  7903. if (tex->get_component_type() == Texture::T_float) {
  7904. return GL_DEPTH_COMPONENT32F;
  7905. } else {
  7906. return GL_DEPTH_COMPONENT32;
  7907. }
  7908. #endif
  7909. case Texture::F_rgba:
  7910. case Texture::F_rgbm:
  7911. #ifndef OPENGLES_1
  7912. if (tex->get_component_type() == Texture::T_float) {
  7913. return GL_RGBA16F;
  7914. } else
  7915. #endif
  7916. #ifndef OPENGLES
  7917. if (tex->get_component_type() == Texture::T_unsigned_short) {
  7918. return GL_RGBA16;
  7919. } else if (tex->get_component_type() == Texture::T_short) {
  7920. return GL_RGBA16_SNORM;
  7921. } else if (tex->get_component_type() == Texture::T_byte) {
  7922. return GL_RGBA8_SNORM;
  7923. } else
  7924. #endif
  7925. {
  7926. return force_sized ? GL_RGBA8 : GL_RGBA;
  7927. }
  7928. case Texture::F_rgba4:
  7929. return GL_RGBA4;
  7930. #ifdef OPENGLES
  7931. case Texture::F_rgba8:
  7932. return GL_RGBA8_OES;
  7933. case Texture::F_rgba12:
  7934. return force_sized ? GL_RGBA8 : GL_RGBA;
  7935. #else
  7936. case Texture::F_rgba8:
  7937. if (Texture::is_unsigned(tex->get_component_type())) {
  7938. return GL_RGBA8;
  7939. } else {
  7940. return GL_RGBA8_SNORM;
  7941. }
  7942. case Texture::F_r8i:
  7943. if (Texture::is_unsigned(tex->get_component_type())) {
  7944. return GL_R8UI;
  7945. } else {
  7946. return GL_R8I;
  7947. }
  7948. case Texture::F_rg8i:
  7949. if (Texture::is_unsigned(tex->get_component_type())) {
  7950. return GL_RG8UI;
  7951. } else {
  7952. return GL_RG8I;
  7953. }
  7954. case Texture::F_rgb8i:
  7955. if (Texture::is_unsigned(tex->get_component_type())) {
  7956. return GL_RGB8UI;
  7957. } else {
  7958. return GL_RGB8I;
  7959. }
  7960. case Texture::F_rgba8i:
  7961. if (Texture::is_unsigned(tex->get_component_type())) {
  7962. return GL_RGBA8UI;
  7963. } else {
  7964. return GL_RGBA8I;
  7965. }
  7966. case Texture::F_rgba12:
  7967. return GL_RGBA12;
  7968. #endif // OPENGLES
  7969. #ifndef OPENGLES
  7970. case Texture::F_rgba16:
  7971. if (tex->get_component_type() == Texture::T_float) {
  7972. return GL_RGBA16F;
  7973. } else if (Texture::is_unsigned(tex->get_component_type())) {
  7974. return GL_RGBA16;
  7975. } else {
  7976. return GL_RGBA16_SNORM;
  7977. }
  7978. case Texture::F_rgba32:
  7979. return GL_RGBA32F;
  7980. #endif // OPENGLES
  7981. case Texture::F_rgb:
  7982. switch (tex->get_component_type()) {
  7983. case Texture::T_float: return GL_RGB16F;
  7984. #ifndef OPENGLES
  7985. case Texture::T_unsigned_short: return GL_RGB16;
  7986. case Texture::T_short: return GL_RGB16_SNORM;
  7987. case Texture::T_byte: return GL_RGB8_SNORM;
  7988. #endif
  7989. default:
  7990. return force_sized ? GL_RGB8 : GL_RGB;
  7991. }
  7992. case Texture::F_rgb5:
  7993. #ifdef OPENGLES
  7994. // Close enough.
  7995. return GL_RGB565_OES;
  7996. #else
  7997. return GL_RGB5;
  7998. #endif
  7999. case Texture::F_rgba5:
  8000. return GL_RGB5_A1;
  8001. #ifdef OPENGLES
  8002. case Texture::F_rgb8:
  8003. return GL_RGB8_OES;
  8004. case Texture::F_rgb12:
  8005. return force_sized ? GL_RGB8 : GL_RGB;
  8006. case Texture::F_rgb16:
  8007. return GL_RGB16F;
  8008. #else
  8009. case Texture::F_rgb8:
  8010. if (Texture::is_unsigned(tex->get_component_type())) {
  8011. return GL_RGB8;
  8012. } else {
  8013. return GL_RGB8_SNORM;
  8014. }
  8015. case Texture::F_rgb12:
  8016. return GL_RGB12;
  8017. case Texture::F_rgb16:
  8018. if (tex->get_component_type() == Texture::T_float) {
  8019. return GL_RGB16F;
  8020. } else if (Texture::is_unsigned(tex->get_component_type())) {
  8021. return GL_RGB16;
  8022. } else {
  8023. return GL_RGB16_SNORM;
  8024. }
  8025. #endif // OPENGLES
  8026. case Texture::F_rgb32:
  8027. return GL_RGB32F;
  8028. #ifndef OPENGLES
  8029. case Texture::F_rgb332:
  8030. return GL_R3_G3_B2;
  8031. #endif
  8032. #if defined(OPENGLES_2)
  8033. case Texture::F_r16:
  8034. return GL_R16F_EXT;
  8035. case Texture::F_rg16:
  8036. return GL_RG16F_EXT;
  8037. #elif !defined(OPENGLES_1)
  8038. case Texture::F_r16:
  8039. if (tex->get_component_type() == Texture::T_float) {
  8040. return GL_R16F;
  8041. } else if (Texture::is_unsigned(tex->get_component_type())) {
  8042. return GL_R16;
  8043. } else {
  8044. return GL_R16_SNORM;
  8045. }
  8046. case Texture::F_r16i:
  8047. if (Texture::is_unsigned(tex->get_component_type())) {
  8048. return GL_R16UI;
  8049. } else {
  8050. return GL_R16I;
  8051. }
  8052. case Texture::F_rg16:
  8053. if (tex->get_component_type() == Texture::T_float) {
  8054. return GL_RG16F;
  8055. } else if (Texture::is_unsigned(tex->get_component_type())) {
  8056. return GL_RG16;
  8057. } else {
  8058. return GL_RG16_SNORM;
  8059. }
  8060. #endif
  8061. #ifndef OPENGLES_1
  8062. case Texture::F_r32:
  8063. return GL_R32F;
  8064. case Texture::F_rg32:
  8065. return GL_RG32F;
  8066. case Texture::F_red:
  8067. case Texture::F_green:
  8068. case Texture::F_blue:
  8069. #ifndef OPENGLES
  8070. if (!Texture::is_unsigned(tex->get_component_type())) {
  8071. return GL_R8_SNORM;
  8072. } else
  8073. #endif
  8074. {
  8075. return force_sized ? GL_R8 : GL_RED;
  8076. }
  8077. #endif
  8078. case Texture::F_alpha:
  8079. #if defined(SUPPORT_FIXED_FUNCTION) || defined(OPENGLES)
  8080. return force_sized ? GL_ALPHA8 : GL_ALPHA;
  8081. #else
  8082. return force_sized ? GL_R8 : GL_RED;
  8083. #endif
  8084. case Texture::F_luminance:
  8085. #if defined(SUPPORT_FIXED_FUNCTION) || defined(OPENGLES)
  8086. #ifndef OPENGLES
  8087. if (tex->get_component_type() == Texture::T_float) {
  8088. return GL_LUMINANCE16F_ARB;
  8089. } else if (tex->get_component_type() == Texture::T_short) {
  8090. return GL_LUMINANCE16_SNORM;
  8091. } else if (tex->get_component_type() == Texture::T_unsigned_short) {
  8092. return GL_LUMINANCE16;
  8093. } else
  8094. #endif // OPENGLES
  8095. {
  8096. return force_sized ? GL_LUMINANCE8 : GL_LUMINANCE;
  8097. }
  8098. #else
  8099. return force_sized ? GL_R8 : GL_RED;
  8100. #endif
  8101. case Texture::F_luminance_alpha:
  8102. case Texture::F_luminance_alphamask:
  8103. #if defined(SUPPORT_FIXED_FUNCTION) || defined(OPENGLES)
  8104. #ifndef OPENGLES
  8105. if (tex->get_component_type() == Texture::T_float || tex->get_component_type() == Texture::T_unsigned_short) {
  8106. return GL_LUMINANCE_ALPHA16F_ARB;
  8107. } else
  8108. #endif // OPENGLES
  8109. {
  8110. return force_sized ? GL_LUMINANCE8_ALPHA8 : GL_LUMINANCE_ALPHA;
  8111. }
  8112. #else
  8113. return force_sized ? GL_RG8 : GL_RG;
  8114. #endif
  8115. #ifndef OPENGLES_1
  8116. case Texture::F_rg:
  8117. return force_sized ? GL_RG8 : GL_RG;
  8118. #endif
  8119. #ifndef OPENGLES_1
  8120. case Texture::F_srgb:
  8121. #ifndef OPENGLES
  8122. return GL_SRGB8;
  8123. #endif
  8124. case Texture::F_srgb_alpha:
  8125. return GL_SRGB8_ALPHA8;
  8126. #endif
  8127. #ifndef OPENGLES
  8128. case Texture::F_sluminance:
  8129. return GL_SLUMINANCE8;
  8130. case Texture::F_sluminance_alpha:
  8131. return GL_SLUMINANCE8_ALPHA8;
  8132. #endif
  8133. #ifndef OPENGLES
  8134. case Texture::F_r32i:
  8135. return GL_R32I;
  8136. #endif
  8137. #ifndef OPENGLES_1
  8138. case Texture::F_r11_g11_b10:
  8139. return GL_R11F_G11F_B10F;
  8140. case Texture::F_rgb9_e5:
  8141. return GL_RGB9_E5;
  8142. case Texture::F_rgb10_a2:
  8143. return GL_RGB10_A2;
  8144. #endif
  8145. default:
  8146. GLCAT.error()
  8147. << "Invalid image format in get_internal_image_format(): "
  8148. << (int)tex->get_format() << "\n";
  8149. return force_sized ? GL_RGB8 : GL_RGB;
  8150. }
  8151. }
  8152. /**
  8153. * Returns true if the indicated GL minfilter type represents a mipmap format,
  8154. * false otherwise.
  8155. */
  8156. bool CLP(GraphicsStateGuardian)::
  8157. is_mipmap_filter(GLenum min_filter) {
  8158. switch (min_filter) {
  8159. case GL_NEAREST_MIPMAP_NEAREST:
  8160. case GL_LINEAR_MIPMAP_NEAREST:
  8161. case GL_NEAREST_MIPMAP_LINEAR:
  8162. case GL_LINEAR_MIPMAP_LINEAR:
  8163. return true;
  8164. default:
  8165. return false;
  8166. }
  8167. }
  8168. /**
  8169. * Returns true if the indicated GL internal format represents a compressed
  8170. * texture format, false otherwise.
  8171. */
  8172. bool CLP(GraphicsStateGuardian)::
  8173. is_compressed_format(GLenum format) {
  8174. switch (format) {
  8175. case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  8176. case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  8177. #ifdef OPENGLES
  8178. case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
  8179. case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
  8180. case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
  8181. case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
  8182. #else
  8183. case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
  8184. case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
  8185. case GL_COMPRESSED_RGB_FXT1_3DFX:
  8186. case GL_COMPRESSED_RGBA_FXT1_3DFX:
  8187. case GL_COMPRESSED_RED_RGTC1:
  8188. case GL_COMPRESSED_SIGNED_RED_RGTC1:
  8189. case GL_COMPRESSED_RG_RGTC2:
  8190. case GL_COMPRESSED_SIGNED_RG_RGTC2:
  8191. case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
  8192. case GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT:
  8193. case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
  8194. case GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT:
  8195. case GL_COMPRESSED_RGB:
  8196. case GL_COMPRESSED_SRGB_EXT:
  8197. case GL_COMPRESSED_RGBA:
  8198. case GL_COMPRESSED_SRGB_ALPHA_EXT:
  8199. case GL_COMPRESSED_ALPHA:
  8200. case GL_COMPRESSED_LUMINANCE:
  8201. case GL_COMPRESSED_LUMINANCE_ALPHA:
  8202. #endif
  8203. return true;
  8204. default:
  8205. return false;
  8206. }
  8207. }
  8208. /**
  8209. * Maps from the texture stage's mode types to the corresponding OpenGL ids
  8210. */
  8211. GLint CLP(GraphicsStateGuardian)::
  8212. get_texture_apply_mode_type(TextureStage::Mode am) {
  8213. #ifdef SUPPORT_FIXED_FUNCTION
  8214. switch (am) {
  8215. case TextureStage::M_modulate: return GL_MODULATE;
  8216. case TextureStage::M_decal: return GL_DECAL;
  8217. case TextureStage::M_blend: return GL_BLEND;
  8218. case TextureStage::M_replace: return GL_REPLACE;
  8219. case TextureStage::M_add: return GL_ADD;
  8220. case TextureStage::M_combine: return GL_COMBINE;
  8221. case TextureStage::M_blend_color_scale: return GL_BLEND;
  8222. case TextureStage::M_modulate_glow: return GL_MODULATE;
  8223. case TextureStage::M_modulate_gloss: return GL_MODULATE;
  8224. default:
  8225. // Other modes shouldn't get here. Fall through and error.
  8226. break;
  8227. }
  8228. GLCAT.error()
  8229. << "Invalid TextureStage::Mode value" << endl;
  8230. return GL_MODULATE;
  8231. #else
  8232. return 0;
  8233. #endif
  8234. }
  8235. /**
  8236. * Maps from the texture stage's CombineMode types to the corresponding OpenGL
  8237. * ids
  8238. */
  8239. GLint CLP(GraphicsStateGuardian)::
  8240. get_texture_combine_type(TextureStage::CombineMode cm) {
  8241. #ifdef SUPPORT_FIXED_FUNCTION
  8242. switch (cm) {
  8243. case TextureStage::CM_undefined: // fall through
  8244. case TextureStage::CM_replace: return GL_REPLACE;
  8245. case TextureStage::CM_modulate: return GL_MODULATE;
  8246. case TextureStage::CM_add: return GL_ADD;
  8247. case TextureStage::CM_add_signed: return GL_ADD_SIGNED;
  8248. case TextureStage::CM_interpolate: return GL_INTERPOLATE;
  8249. case TextureStage::CM_subtract: return GL_SUBTRACT;
  8250. case TextureStage::CM_dot3_rgb: return GL_DOT3_RGB;
  8251. case TextureStage::CM_dot3_rgba: return GL_DOT3_RGBA;
  8252. }
  8253. GLCAT.error()
  8254. << "Invalid TextureStage::CombineMode value" << endl;
  8255. #endif
  8256. return GL_REPLACE;
  8257. }
  8258. /**
  8259. * Maps from the texture stage's CombineSource types to the corresponding
  8260. * OpenGL ids
  8261. */
  8262. GLint CLP(GraphicsStateGuardian)::
  8263. get_texture_src_type(TextureStage::CombineSource cs,
  8264. int last_stage, int last_saved_result,
  8265. int this_stage) const {
  8266. #ifdef SUPPORT_FIXED_FUNCTION
  8267. switch (cs) {
  8268. case TextureStage::CS_undefined: // fall through
  8269. case TextureStage::CS_texture: return GL_TEXTURE;
  8270. case TextureStage::CS_constant: return GL_CONSTANT;
  8271. case TextureStage::CS_primary_color: return GL_PRIMARY_COLOR;
  8272. case TextureStage::CS_constant_color_scale: return GL_CONSTANT;
  8273. case TextureStage::CS_previous:
  8274. if (last_stage == this_stage - 1) {
  8275. return GL_PREVIOUS;
  8276. } else if (last_stage == -1) {
  8277. return GL_PRIMARY_COLOR;
  8278. } else if (_supports_texture_saved_result) {
  8279. return GL_TEXTURE0 + last_stage;
  8280. } else {
  8281. GLCAT.warning()
  8282. << "Current OpenGL driver does not support texture crossbar blending.\n";
  8283. return GL_PRIMARY_COLOR;
  8284. }
  8285. case TextureStage::CS_last_saved_result:
  8286. if (last_saved_result == this_stage - 1) {
  8287. return GL_PREVIOUS;
  8288. } else if (last_saved_result == -1) {
  8289. return GL_PRIMARY_COLOR;
  8290. } else if (_supports_texture_saved_result) {
  8291. return GL_TEXTURE0 + last_saved_result;
  8292. } else {
  8293. GLCAT.warning()
  8294. << "Current OpenGL driver does not support texture crossbar blending.\n";
  8295. return GL_PRIMARY_COLOR;
  8296. }
  8297. }
  8298. GLCAT.error()
  8299. << "Invalid TextureStage::CombineSource value" << endl;
  8300. #endif
  8301. return GL_TEXTURE;
  8302. }
  8303. /**
  8304. * Maps from the texture stage's CombineOperand types to the corresponding
  8305. * OpenGL ids
  8306. */
  8307. GLint CLP(GraphicsStateGuardian)::
  8308. get_texture_operand_type(TextureStage::CombineOperand co) {
  8309. switch (co) {
  8310. case TextureStage::CO_undefined: // fall through
  8311. case TextureStage::CO_src_alpha: return GL_SRC_ALPHA;
  8312. case TextureStage::CO_one_minus_src_alpha: return GL_ONE_MINUS_SRC_ALPHA;
  8313. case TextureStage::CO_src_color: return GL_SRC_COLOR;
  8314. case TextureStage::CO_one_minus_src_color: return GL_ONE_MINUS_SRC_COLOR;
  8315. }
  8316. GLCAT.error()
  8317. << "Invalid TextureStage::CombineOperand value" << endl;
  8318. return GL_SRC_COLOR;
  8319. }
  8320. #ifdef SUPPORT_FIXED_FUNCTION
  8321. /**
  8322. * Maps from the fog types to gl version
  8323. */
  8324. GLenum CLP(GraphicsStateGuardian)::
  8325. get_fog_mode_type(Fog::Mode m) {
  8326. switch(m) {
  8327. case Fog::M_linear: return GL_LINEAR;
  8328. case Fog::M_exponential: return GL_EXP;
  8329. case Fog::M_exponential_squared: return GL_EXP2;
  8330. /*
  8331. case Fog::M_spline: return GL_FOG_FUNC_SGIS;
  8332. */
  8333. default:
  8334. GLCAT.error() << "Invalid Fog::Mode value" << endl;
  8335. return GL_EXP;
  8336. }
  8337. }
  8338. #endif
  8339. /**
  8340. * Maps from ColorBlendAttrib::Mode to glBlendEquation value.
  8341. */
  8342. GLenum CLP(GraphicsStateGuardian)::
  8343. get_blend_equation_type(ColorBlendAttrib::Mode mode) {
  8344. switch (mode) {
  8345. case ColorBlendAttrib::M_none:
  8346. case ColorBlendAttrib::M_add:
  8347. return GL_FUNC_ADD;
  8348. case ColorBlendAttrib::M_subtract:
  8349. return GL_FUNC_SUBTRACT;
  8350. case ColorBlendAttrib::M_inv_subtract:
  8351. return GL_FUNC_REVERSE_SUBTRACT;
  8352. #ifdef OPENGLES
  8353. case ColorBlendAttrib::M_min:
  8354. return GL_MIN_EXT;
  8355. case ColorBlendAttrib::M_max:
  8356. return GL_MAX_EXT;
  8357. #else
  8358. case ColorBlendAttrib::M_min:
  8359. return GL_MIN;
  8360. case ColorBlendAttrib::M_max:
  8361. return GL_MAX;
  8362. #endif
  8363. }
  8364. GLCAT.error()
  8365. << "Unknown color blend mode " << (int)mode << endl;
  8366. return GL_FUNC_ADD;
  8367. }
  8368. /**
  8369. * Maps from ColorBlendAttrib::Operand to glBlendFunc value.
  8370. */
  8371. GLenum CLP(GraphicsStateGuardian)::
  8372. get_blend_func(ColorBlendAttrib::Operand operand) {
  8373. switch (operand) {
  8374. case ColorBlendAttrib::O_zero:
  8375. return GL_ZERO;
  8376. case ColorBlendAttrib::O_one:
  8377. return GL_ONE;
  8378. case ColorBlendAttrib::O_incoming_color:
  8379. return GL_SRC_COLOR;
  8380. case ColorBlendAttrib::O_one_minus_incoming_color:
  8381. return GL_ONE_MINUS_SRC_COLOR;
  8382. case ColorBlendAttrib::O_fbuffer_color:
  8383. return GL_DST_COLOR;
  8384. case ColorBlendAttrib::O_one_minus_fbuffer_color:
  8385. return GL_ONE_MINUS_DST_COLOR;
  8386. case ColorBlendAttrib::O_incoming_alpha:
  8387. return GL_SRC_ALPHA;
  8388. case ColorBlendAttrib::O_one_minus_incoming_alpha:
  8389. return GL_ONE_MINUS_SRC_ALPHA;
  8390. case ColorBlendAttrib::O_fbuffer_alpha:
  8391. return GL_DST_ALPHA;
  8392. case ColorBlendAttrib::O_one_minus_fbuffer_alpha:
  8393. return GL_ONE_MINUS_DST_ALPHA;
  8394. #ifdef OPENGLES_1
  8395. // OpenGL ES 1 has no constant blend factor.
  8396. case ColorBlendAttrib::O_constant_color:
  8397. case ColorBlendAttrib::O_color_scale:
  8398. case ColorBlendAttrib::O_one_minus_constant_color:
  8399. case ColorBlendAttrib::O_one_minus_color_scale:
  8400. case ColorBlendAttrib::O_constant_alpha:
  8401. case ColorBlendAttrib::O_alpha_scale:
  8402. case ColorBlendAttrib::O_one_minus_constant_alpha:
  8403. case ColorBlendAttrib::O_one_minus_alpha_scale:
  8404. break;
  8405. // No dual-source blending, either.
  8406. case ColorBlendAttrib::O_incoming1_color:
  8407. case ColorBlendAttrib::O_one_minus_incoming1_color:
  8408. case ColorBlendAttrib::O_incoming1_alpha:
  8409. case ColorBlendAttrib::O_one_minus_incoming1_alpha:
  8410. break;
  8411. #else
  8412. case ColorBlendAttrib::O_constant_color:
  8413. case ColorBlendAttrib::O_color_scale:
  8414. return GL_CONSTANT_COLOR;
  8415. case ColorBlendAttrib::O_one_minus_constant_color:
  8416. case ColorBlendAttrib::O_one_minus_color_scale:
  8417. return GL_ONE_MINUS_CONSTANT_COLOR;
  8418. case ColorBlendAttrib::O_constant_alpha:
  8419. case ColorBlendAttrib::O_alpha_scale:
  8420. return GL_CONSTANT_ALPHA;
  8421. case ColorBlendAttrib::O_one_minus_constant_alpha:
  8422. case ColorBlendAttrib::O_one_minus_alpha_scale:
  8423. return GL_ONE_MINUS_CONSTANT_ALPHA;
  8424. case ColorBlendAttrib::O_incoming1_color:
  8425. return GL_SRC1_COLOR;
  8426. case ColorBlendAttrib::O_one_minus_incoming1_color:
  8427. return GL_ONE_MINUS_SRC1_COLOR;
  8428. case ColorBlendAttrib::O_incoming1_alpha:
  8429. return GL_SRC1_ALPHA;
  8430. case ColorBlendAttrib::O_one_minus_incoming1_alpha:
  8431. return GL_ONE_MINUS_SRC1_ALPHA;
  8432. #endif
  8433. case ColorBlendAttrib::O_incoming_color_saturate:
  8434. return GL_SRC_ALPHA_SATURATE;
  8435. }
  8436. GLCAT.error()
  8437. << "Unknown color blend operand " << (int)operand << endl;
  8438. return GL_ZERO;
  8439. }
  8440. /**
  8441. * Maps from UsageHint to the GL symbol.
  8442. */
  8443. GLenum CLP(GraphicsStateGuardian)::
  8444. get_usage(Geom::UsageHint usage_hint) {
  8445. switch (usage_hint) {
  8446. case Geom::UH_stream:
  8447. #ifdef OPENGLES_1
  8448. return GL_DYNAMIC_DRAW;
  8449. #else
  8450. return GL_STREAM_DRAW;
  8451. #endif // OPENGLES
  8452. case Geom::UH_static:
  8453. case Geom::UH_unspecified:
  8454. return GL_STATIC_DRAW;
  8455. case Geom::UH_dynamic:
  8456. return GL_DYNAMIC_DRAW;
  8457. case Geom::UH_client:
  8458. break;
  8459. }
  8460. GLCAT.error()
  8461. << "Unexpected usage_hint " << (int)usage_hint << endl;
  8462. return GL_STATIC_DRAW;
  8463. }
  8464. #ifndef NDEBUG
  8465. /**
  8466. * Returns a string describing an compression format.
  8467. */
  8468. const char *CLP(GraphicsStateGuardian)::
  8469. get_compressed_format_string(GLenum format) {
  8470. switch (format) {
  8471. case 0x83F0: return "GL_COMPRESSED_RGB_S3TC_DXT1_EXT";
  8472. case 0x83F1: return "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT";
  8473. case 0x83F2: return "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT";
  8474. case 0x83F3: return "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT";
  8475. case 0x86B0: return "GL_COMPRESSED_RGB_FXT1_3DFX";
  8476. case 0x86B1: return "GL_COMPRESSED_RGBA_FXT1_3DFX";
  8477. case 0x88EE: return "GL_ETC1_SRGB8_NV";
  8478. case 0x8A54: return "GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT";
  8479. case 0x8A55: return "GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT";
  8480. case 0x8A56: return "GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT";
  8481. case 0x8A57: return "GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT";
  8482. case 0x8B90: return "GL_PALETTE4_RGB8_OES";
  8483. case 0x8B91: return "GL_PALETTE4_RGBA8_OES";
  8484. case 0x8B92: return "GL_PALETTE4_R5_G6_B5_OES";
  8485. case 0x8B93: return "GL_PALETTE4_RGBA4_OES";
  8486. case 0x8B94: return "GL_PALETTE4_RGB5_A1_OES";
  8487. case 0x8B95: return "GL_PALETTE8_RGB8_OES";
  8488. case 0x8B96: return "GL_PALETTE8_RGBA8_OES";
  8489. case 0x8B97: return "GL_PALETTE8_R5_G6_B5_OES";
  8490. case 0x8B98: return "GL_PALETTE8_RGBA4_OES";
  8491. case 0x8B99: return "GL_PALETTE8_RGB5_A1_OES";
  8492. case 0x8C00: return "GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG";
  8493. case 0x8C01: return "GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG";
  8494. case 0x8C02: return "GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG";
  8495. case 0x8C03: return "GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG";
  8496. case 0x8C48: return "GL_COMPRESSED_SRGB_EXT";
  8497. case 0x8C49: return "GL_COMPRESSED_SRGB_ALPHA_EXT";
  8498. case 0x8C4A: return "GL_COMPRESSED_SLUMINANCE_EXT";
  8499. case 0x8C4B: return "GL_COMPRESSED_SLUMINANCE_ALPHA_EXT";
  8500. case 0x8C4C: return "GL_COMPRESSED_SRGB_S3TC_DXT1_EXT";
  8501. case 0x8C4D: return "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT";
  8502. case 0x8C4E: return "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT";
  8503. case 0x8C4F: return "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT";
  8504. case 0x8C70: return "GL_COMPRESSED_LUMINANCE_LATC1_EXT";
  8505. case 0x8C71: return "GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT";
  8506. case 0x8C72: return "GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT";
  8507. case 0x8C73: return "GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT";
  8508. case 0x8D64: return "GL_ETC1_RGB8_OES";
  8509. case 0x8DBB: return "GL_COMPRESSED_RED_RGTC1";
  8510. case 0x8DBC: return "GL_COMPRESSED_SIGNED_RED_RGTC1";
  8511. case 0x8DBD: return "GL_COMPRESSED_RG_RGTC2";
  8512. case 0x8DBE: return "GL_COMPRESSED_SIGNED_RG_RGTC2";
  8513. case 0x8E8C: return "GL_COMPRESSED_RGBA_BPTC_UNORM";
  8514. case 0x8E8D: return "GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM";
  8515. case 0x8E8E: return "GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT";
  8516. case 0x8E8F: return "GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT";
  8517. case 0x9137: return "GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG";
  8518. case 0x9138: return "GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG";
  8519. case 0x9270: return "GL_COMPRESSED_R11_EAC";
  8520. case 0x9271: return "GL_COMPRESSED_SIGNED_R11_EAC";
  8521. case 0x9272: return "GL_COMPRESSED_RG11_EAC";
  8522. case 0x9273: return "GL_COMPRESSED_SIGNED_RG11_EAC";
  8523. case 0x9274: return "GL_COMPRESSED_RGB8_ETC2";
  8524. case 0x9275: return "GL_COMPRESSED_SRGB8_ETC2";
  8525. case 0x9276: return "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2";
  8526. case 0x9277: return "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2";
  8527. case 0x9278: return "GL_COMPRESSED_RGBA8_ETC2_EAC";
  8528. case 0x9279: return "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC";
  8529. case 0x93B0: return "GL_COMPRESSED_RGBA_ASTC_4x4_KHR";
  8530. case 0x93B1: return "GL_COMPRESSED_RGBA_ASTC_5x4_KHR";
  8531. case 0x93B2: return "GL_COMPRESSED_RGBA_ASTC_5x5_KHR";
  8532. case 0x93B3: return "GL_COMPRESSED_RGBA_ASTC_6x5_KHR";
  8533. case 0x93B4: return "GL_COMPRESSED_RGBA_ASTC_6x6_KHR";
  8534. case 0x93B5: return "GL_COMPRESSED_RGBA_ASTC_8x5_KHR";
  8535. case 0x93B6: return "GL_COMPRESSED_RGBA_ASTC_8x6_KHR";
  8536. case 0x93B7: return "GL_COMPRESSED_RGBA_ASTC_8x8_KHR";
  8537. case 0x93B8: return "GL_COMPRESSED_RGBA_ASTC_10x5_KHR";
  8538. case 0x93B9: return "GL_COMPRESSED_RGBA_ASTC_10x6_KHR";
  8539. case 0x93BA: return "GL_COMPRESSED_RGBA_ASTC_10x8_KHR";
  8540. case 0x93BB: return "GL_COMPRESSED_RGBA_ASTC_10x10_KHR";
  8541. case 0x93BC: return "GL_COMPRESSED_RGBA_ASTC_12x10_KHR";
  8542. case 0x93BD: return "GL_COMPRESSED_RGBA_ASTC_12x12_KHR";
  8543. case 0x93C0: return "GL_COMPRESSED_RGBA_ASTC_3x3x3_OES";
  8544. case 0x93C1: return "GL_COMPRESSED_RGBA_ASTC_4x3x3_OES";
  8545. case 0x93C2: return "GL_COMPRESSED_RGBA_ASTC_4x4x3_OES";
  8546. case 0x93C3: return "GL_COMPRESSED_RGBA_ASTC_4x4x4_OES";
  8547. case 0x93C4: return "GL_COMPRESSED_RGBA_ASTC_5x4x4_OES";
  8548. case 0x93C5: return "GL_COMPRESSED_RGBA_ASTC_5x5x4_OES";
  8549. case 0x93C6: return "GL_COMPRESSED_RGBA_ASTC_5x5x5_OES";
  8550. case 0x93C7: return "GL_COMPRESSED_RGBA_ASTC_6x5x5_OES";
  8551. case 0x93C8: return "GL_COMPRESSED_RGBA_ASTC_6x6x5_OES";
  8552. case 0x93C9: return "GL_COMPRESSED_RGBA_ASTC_6x6x6_OES";
  8553. case 0x93D0: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR";
  8554. case 0x93D1: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR";
  8555. case 0x93D2: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR";
  8556. case 0x93D3: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR";
  8557. case 0x93D4: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR";
  8558. case 0x93D5: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR";
  8559. case 0x93D6: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR";
  8560. case 0x93D7: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR";
  8561. case 0x93D8: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR";
  8562. case 0x93D9: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR";
  8563. case 0x93DA: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR";
  8564. case 0x93DB: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR";
  8565. case 0x93DC: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR";
  8566. case 0x93DD: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR";
  8567. case 0x93E0: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES";
  8568. case 0x93E1: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES";
  8569. case 0x93E2: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES";
  8570. case 0x93E3: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES";
  8571. case 0x93E4: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES";
  8572. case 0x93E5: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES";
  8573. case 0x93E6: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES";
  8574. case 0x93E7: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES";
  8575. case 0x93E8: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES";
  8576. case 0x93E9: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES";
  8577. case 0x93F0: return "GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG";
  8578. case 0x93F1: return "GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG";
  8579. default:
  8580. return NULL;
  8581. }
  8582. }
  8583. #endif
  8584. /**
  8585. * Returns the value that that should be issued as the light's color, as
  8586. * scaled by the current value of _light_color_scale, in the case of
  8587. * color_scale_via_lighting.
  8588. */
  8589. LVecBase4 CLP(GraphicsStateGuardian)::
  8590. get_light_color(Light *light) const {
  8591. #ifndef NDEBUG
  8592. if (_show_texture_usage) {
  8593. // In show_texture_usage mode, all lights are white, so as not to
  8594. // contaminate the texture color.
  8595. return LVecBase4(1.0, 1.0, 1.0, 1.0);
  8596. }
  8597. #endif // NDEBUG
  8598. const LColor &c = light->get_color();
  8599. LVecBase4 light_color(c[0] * _light_color_scale[0],
  8600. c[1] * _light_color_scale[1],
  8601. c[2] * _light_color_scale[2],
  8602. c[3] * _light_color_scale[3]);
  8603. return light_color;
  8604. }
  8605. /**
  8606. * Called by clear_state_and_transform() to ensure that the current modelview
  8607. * and projection matrices are properly loaded in the graphics state, after a
  8608. * callback might have mucked them up.
  8609. */
  8610. void CLP(GraphicsStateGuardian)::
  8611. reissue_transforms() {
  8612. prepare_lens();
  8613. do_issue_transform();
  8614. _active_texture_stage = -1;
  8615. #ifndef OPENGLES_1
  8616. // Might also want to reissue the vertex format, for good measure.
  8617. _current_vertex_format.clear();
  8618. memset(_vertex_attrib_columns, 0, sizeof(const GeomVertexColumn *) * 32);
  8619. #endif
  8620. }
  8621. #ifdef SUPPORT_FIXED_FUNCTION
  8622. /**
  8623. * Intended to be overridden by a derived class to enable or disable the use
  8624. * of lighting overall. This is called by do_issue_light() according to
  8625. * whether any lights are in use or not.
  8626. */
  8627. void CLP(GraphicsStateGuardian)::
  8628. enable_lighting(bool enable) {
  8629. // static PStatCollector
  8630. // _draw_set_state_light_enable_lighting_pcollector("Draw:Set
  8631. // State:Light:Enable lighting"); PStatGPUTimer timer(this,
  8632. // _draw_set_state_light_enable_lighting_pcollector);
  8633. if (enable) {
  8634. glEnable(GL_LIGHTING);
  8635. } else {
  8636. glDisable(GL_LIGHTING);
  8637. }
  8638. }
  8639. #endif // SUPPORT_FIXED_FUNCTION
  8640. #ifdef SUPPORT_FIXED_FUNCTION
  8641. /**
  8642. * Intended to be overridden by a derived class to indicate the color of the
  8643. * ambient light that should be in effect. This is called by do_issue_light()
  8644. * after all other lights have been enabled or disabled.
  8645. */
  8646. void CLP(GraphicsStateGuardian)::
  8647. set_ambient_light(const LColor &color) {
  8648. // static PStatCollector _draw_set_state_light_ambient_pcollector("Draw:Set
  8649. // State:Light:Ambient"); PStatGPUTimer timer(this,
  8650. // _draw_set_state_light_ambient_pcollector);
  8651. LColor c = color;
  8652. c.set(c[0] * _light_color_scale[0],
  8653. c[1] * _light_color_scale[1],
  8654. c[2] * _light_color_scale[2],
  8655. c[3] * _light_color_scale[3]);
  8656. call_glLightModelfv(GL_LIGHT_MODEL_AMBIENT, c);
  8657. }
  8658. #endif // SUPPORT_FIXED_FUNCTION
  8659. #ifdef SUPPORT_FIXED_FUNCTION
  8660. /**
  8661. * Intended to be overridden by a derived class to enable the indicated light
  8662. * id. A specific Light will already have been bound to this id via
  8663. * bind_light().
  8664. */
  8665. void CLP(GraphicsStateGuardian)::
  8666. enable_light(int light_id, bool enable) {
  8667. // static PStatCollector
  8668. // _draw_set_state_light_enable_light_pcollector("Draw:Set
  8669. // State:Light:Enable light"); PStatGPUTimer timer(this,
  8670. // _draw_set_state_light_enable_light_pcollector);
  8671. if (enable) {
  8672. glEnable(get_light_id(light_id));
  8673. } else {
  8674. glDisable(get_light_id(light_id));
  8675. }
  8676. }
  8677. #endif // SUPPORT_FIXED_FUNCTION
  8678. #ifdef SUPPORT_FIXED_FUNCTION
  8679. /**
  8680. * Called immediately before bind_light() is called, this is intended to
  8681. * provide the derived class a hook in which to set up some state (like
  8682. * transform) that might apply to several lights.
  8683. *
  8684. * The sequence is: begin_bind_lights() will be called, then one or more
  8685. * bind_light() calls, then end_bind_lights().
  8686. */
  8687. void CLP(GraphicsStateGuardian)::
  8688. begin_bind_lights() {
  8689. // static PStatCollector
  8690. // _draw_set_state_light_begin_bind_pcollector("Draw:Set State:Light:Begin
  8691. // bind"); PStatGPUTimer timer(this,
  8692. // _draw_set_state_light_begin_bind_pcollector);
  8693. // We need to temporarily load a new matrix so we can define the light in a
  8694. // known coordinate system. We pick the transform of the root.
  8695. // (Alternatively, we could leave the current transform where it is and
  8696. // compute the light position relative to that transform instead of relative
  8697. // to the root, by composing with the matrix computed by
  8698. // _internal_transform->invert_compose(render_transform). But I think
  8699. // loading a completely new matrix is simpler.)
  8700. CPT(TransformState) render_transform =
  8701. _cs_transform->compose(_scene_setup->get_world_transform());
  8702. glMatrixMode(GL_MODELVIEW);
  8703. glPushMatrix();
  8704. call_glLoadMatrix(render_transform->get_mat());
  8705. }
  8706. #endif // SUPPORT_FIXED_FUNCTION
  8707. #ifdef SUPPORT_FIXED_FUNCTION
  8708. /**
  8709. * Called after before bind_light() has been called one or more times (but
  8710. * before any geometry is issued or additional state is changed), this is
  8711. * intended to clean up any temporary changes to the state that may have been
  8712. * made by begin_bind_lights().
  8713. */
  8714. void CLP(GraphicsStateGuardian)::
  8715. end_bind_lights() {
  8716. // static PStatCollector _draw_set_state_light_end_bind_pcollector("Draw:Set
  8717. // State:Light:End bind"); PStatGPUTimer timer(this,
  8718. // _draw_set_state_light_end_bind_pcollector);
  8719. glMatrixMode(GL_MODELVIEW);
  8720. glPopMatrix();
  8721. }
  8722. #endif // SUPPORT_FIXED_FUNCTION
  8723. #ifdef SUPPORT_FIXED_FUNCTION
  8724. /**
  8725. * Intended to be overridden by a derived class to enable the indicated
  8726. * clip_plane id. A specific PlaneNode will already have been bound to this
  8727. * id via bind_clip_plane().
  8728. */
  8729. void CLP(GraphicsStateGuardian)::
  8730. enable_clip_plane(int plane_id, bool enable) {
  8731. if (enable) {
  8732. glEnable(get_clip_plane_id(plane_id));
  8733. } else {
  8734. glDisable(get_clip_plane_id(plane_id));
  8735. }
  8736. }
  8737. #endif // SUPPORT_FIXED_FUNCTION
  8738. #ifdef SUPPORT_FIXED_FUNCTION
  8739. /**
  8740. * Called immediately before bind_clip_plane() is called, this is intended to
  8741. * provide the derived class a hook in which to set up some state (like
  8742. * transform) that might apply to several clip_planes.
  8743. *
  8744. * The sequence is: begin_bind_clip_planes() will be called, then one or more
  8745. * bind_clip_plane() calls, then end_bind_clip_planes().
  8746. */
  8747. void CLP(GraphicsStateGuardian)::
  8748. begin_bind_clip_planes() {
  8749. // We need to temporarily load a new matrix so we can define the clip_plane
  8750. // in a known coordinate system. We pick the transform of the root.
  8751. // (Alternatively, we could leave the current transform where it is and
  8752. // compute the clip_plane position relative to that transform instead of
  8753. // relative to the root, by composing with the matrix computed by
  8754. // _internal_transform->invert_compose(render_transform). But I think
  8755. // loading a completely new matrix is simpler.)
  8756. CPT(TransformState) render_transform =
  8757. _cs_transform->compose(_scene_setup->get_world_transform());
  8758. glMatrixMode(GL_MODELVIEW);
  8759. glPushMatrix();
  8760. call_glLoadMatrix(render_transform->get_mat());
  8761. }
  8762. #endif // SUPPORT_FIXED_FUNCTION
  8763. #ifdef SUPPORT_FIXED_FUNCTION
  8764. /**
  8765. * Called the first time a particular clip_plane has been bound to a given id
  8766. * within a frame, this should set up the associated hardware clip_plane with
  8767. * the clip_plane's properties.
  8768. */
  8769. void CLP(GraphicsStateGuardian)::
  8770. bind_clip_plane(const NodePath &plane, int plane_id) {
  8771. GLenum id = get_clip_plane_id(plane_id);
  8772. CPT(TransformState) transform = plane.get_transform(_scene_setup->get_scene_root().get_parent());
  8773. const PlaneNode *plane_node;
  8774. DCAST_INTO_V(plane_node, plane.node());
  8775. LPlane xformed_plane = plane_node->get_plane() * transform->get_mat();
  8776. #ifdef OPENGLES
  8777. // OpenGL ES uses a single-precision call.
  8778. LPlanef single_plane(LCAST(float, xformed_plane));
  8779. glClipPlanef(id, single_plane.get_data());
  8780. #else
  8781. // Mainline OpenGL uses a double-precision call.
  8782. LPlaned double_plane(LCAST(double, xformed_plane));
  8783. glClipPlane(id, double_plane.get_data());
  8784. #endif // OPENGLES
  8785. report_my_gl_errors();
  8786. }
  8787. #endif // SUPPORT_FIXED_FUNCTION
  8788. #ifdef SUPPORT_FIXED_FUNCTION
  8789. /**
  8790. * Called after before bind_clip_plane() has been called one or more times
  8791. * (but before any geometry is issued or additional state is changed), this is
  8792. * intended to clean up any temporary changes to the state that may have been
  8793. * made by begin_bind_clip_planes().
  8794. */
  8795. void CLP(GraphicsStateGuardian)::
  8796. end_bind_clip_planes() {
  8797. glMatrixMode(GL_MODELVIEW);
  8798. glPopMatrix();
  8799. }
  8800. #endif // SUPPORT_FIXED_FUNCTION
  8801. /**
  8802. * Simultaneously resets the render state and the transform state.
  8803. *
  8804. * This transform specified is the "internal" net transform, already converted
  8805. * into the GSG's internal coordinate space by composing it to
  8806. * get_cs_transform(). (Previously, this used to be the "external" net
  8807. * transform, with the assumption that that GSG would convert it internally,
  8808. * but that is no longer the case.)
  8809. *
  8810. * Special case: if (state==NULL), then the target state is already stored in
  8811. * _target.
  8812. */
  8813. void CLP(GraphicsStateGuardian)::
  8814. set_state_and_transform(const RenderState *target,
  8815. const TransformState *transform) {
  8816. report_my_gl_errors();
  8817. #ifndef NDEBUG
  8818. if (gsg_cat.is_spam()) {
  8819. gsg_cat.spam() << "Setting GSG state to " << (void *)target << ":\n";
  8820. target->write(gsg_cat.spam(false), 2);
  8821. }
  8822. #endif
  8823. _state_pcollector.add_level(1);
  8824. PStatGPUTimer timer1(this, _draw_set_state_pcollector);
  8825. if (transform != _internal_transform) {
  8826. // PStatGPUTimer timer(this, _draw_set_state_transform_pcollector);
  8827. _transform_state_pcollector.add_level(1);
  8828. _internal_transform = transform;
  8829. do_issue_transform();
  8830. }
  8831. if (target == _state_rs && (_state_mask | _inv_state_mask).is_all_on()) {
  8832. return;
  8833. }
  8834. _target_rs = target;
  8835. #ifndef OPENGLES_1
  8836. _target_shader = (const ShaderAttrib *)
  8837. _target_rs->get_attrib_def(ShaderAttrib::get_class_slot());
  8838. _instance_count = _target_shader->get_instance_count();
  8839. if (_target_shader != _state_shader) {
  8840. // PStatGPUTimer timer(this, _draw_set_state_shader_pcollector);
  8841. do_issue_shader();
  8842. _state_shader = _target_shader;
  8843. _state_mask.clear_bit(TextureAttrib::get_class_slot());
  8844. }
  8845. #ifndef SUPPORT_FIXED_FUNCTION
  8846. else if (_current_shader == NULL) { // In the case of OpenGL ES 2.x, we need to glUseShader before we draw anything.
  8847. do_issue_shader();
  8848. _state_mask.clear_bit(TextureAttrib::get_class_slot());
  8849. }
  8850. #endif
  8851. if (_current_shader_context != NULL) {
  8852. _current_shader_context->set_state_and_transform(target, transform, _projection_mat);
  8853. }
  8854. #endif
  8855. #ifdef SUPPORT_FIXED_FUNCTION
  8856. int alpha_test_slot = AlphaTestAttrib::get_class_slot();
  8857. if (_target_rs->get_attrib(alpha_test_slot) != _state_rs->get_attrib(alpha_test_slot) ||
  8858. !_state_mask.get_bit(alpha_test_slot)
  8859. #ifndef OPENGLES_1
  8860. || (_target_shader->get_flag(ShaderAttrib::F_subsume_alpha_test) !=
  8861. _state_shader->get_flag(ShaderAttrib::F_subsume_alpha_test))
  8862. #endif
  8863. ) {
  8864. // PStatGPUTimer timer(this, _draw_set_state_alpha_test_pcollector);
  8865. do_issue_alpha_test();
  8866. _state_mask.set_bit(alpha_test_slot);
  8867. }
  8868. #endif
  8869. int antialias_slot = AntialiasAttrib::get_class_slot();
  8870. if (_target_rs->get_attrib(antialias_slot) != _state_rs->get_attrib(antialias_slot) ||
  8871. !_state_mask.get_bit(antialias_slot)) {
  8872. // PStatGPUTimer timer(this, _draw_set_state_antialias_pcollector);
  8873. do_issue_antialias();
  8874. _state_mask.set_bit(antialias_slot);
  8875. }
  8876. int clip_plane_slot = ClipPlaneAttrib::get_class_slot();
  8877. if (_target_rs->get_attrib(clip_plane_slot) != _state_rs->get_attrib(clip_plane_slot) ||
  8878. !_state_mask.get_bit(clip_plane_slot)) {
  8879. // PStatGPUTimer timer(this, _draw_set_state_clip_plane_pcollector);
  8880. do_issue_clip_plane();
  8881. _state_mask.set_bit(clip_plane_slot);
  8882. }
  8883. int color_slot = ColorAttrib::get_class_slot();
  8884. int color_scale_slot = ColorScaleAttrib::get_class_slot();
  8885. if (_target_rs->get_attrib(color_slot) != _state_rs->get_attrib(color_slot) ||
  8886. _target_rs->get_attrib(color_scale_slot) != _state_rs->get_attrib(color_scale_slot) ||
  8887. !_state_mask.get_bit(color_slot) ||
  8888. !_state_mask.get_bit(color_scale_slot)) {
  8889. // PStatGPUTimer timer(this, _draw_set_state_color_pcollector);
  8890. do_issue_color();
  8891. do_issue_color_scale();
  8892. _state_mask.set_bit(color_slot);
  8893. _state_mask.set_bit(color_scale_slot);
  8894. }
  8895. int cull_face_slot = CullFaceAttrib::get_class_slot();
  8896. if (_target_rs->get_attrib(cull_face_slot) != _state_rs->get_attrib(cull_face_slot) ||
  8897. !_state_mask.get_bit(cull_face_slot)) {
  8898. // PStatGPUTimer timer(this, _draw_set_state_cull_face_pcollector);
  8899. do_issue_cull_face();
  8900. _state_mask.set_bit(cull_face_slot);
  8901. }
  8902. int depth_offset_slot = DepthOffsetAttrib::get_class_slot();
  8903. if (_target_rs->get_attrib(depth_offset_slot) != _state_rs->get_attrib(depth_offset_slot) ||
  8904. !_state_mask.get_bit(depth_offset_slot)) {
  8905. // PStatGPUTimer timer(this, _draw_set_state_depth_offset_pcollector);
  8906. do_issue_depth_offset();
  8907. _state_mask.set_bit(depth_offset_slot);
  8908. }
  8909. int depth_test_slot = DepthTestAttrib::get_class_slot();
  8910. if (_target_rs->get_attrib(depth_test_slot) != _state_rs->get_attrib(depth_test_slot) ||
  8911. !_state_mask.get_bit(depth_test_slot)) {
  8912. // PStatGPUTimer timer(this, _draw_set_state_depth_test_pcollector);
  8913. do_issue_depth_test();
  8914. _state_mask.set_bit(depth_test_slot);
  8915. }
  8916. int depth_write_slot = DepthWriteAttrib::get_class_slot();
  8917. if (_target_rs->get_attrib(depth_write_slot) != _state_rs->get_attrib(depth_write_slot) ||
  8918. !_state_mask.get_bit(depth_write_slot)) {
  8919. // PStatGPUTimer timer(this, _draw_set_state_depth_write_pcollector);
  8920. do_issue_depth_write();
  8921. _state_mask.set_bit(depth_write_slot);
  8922. }
  8923. int render_mode_slot = RenderModeAttrib::get_class_slot();
  8924. if (_target_rs->get_attrib(render_mode_slot) != _state_rs->get_attrib(render_mode_slot) ||
  8925. !_state_mask.get_bit(render_mode_slot)) {
  8926. // PStatGPUTimer timer(this, _draw_set_state_render_mode_pcollector);
  8927. do_issue_render_mode();
  8928. _state_mask.set_bit(render_mode_slot);
  8929. }
  8930. #ifdef SUPPORT_FIXED_FUNCTION
  8931. int rescale_normal_slot = RescaleNormalAttrib::get_class_slot();
  8932. if (_target_rs->get_attrib(rescale_normal_slot) != _state_rs->get_attrib(rescale_normal_slot) ||
  8933. !_state_mask.get_bit(rescale_normal_slot)) {
  8934. // PStatGPUTimer timer(this, _draw_set_state_rescale_normal_pcollector);
  8935. do_issue_rescale_normal();
  8936. _state_mask.set_bit(rescale_normal_slot);
  8937. }
  8938. #endif
  8939. #ifdef SUPPORT_FIXED_FUNCTION
  8940. int shade_model_slot = ShadeModelAttrib::get_class_slot();
  8941. if (_target_rs->get_attrib(shade_model_slot) != _state_rs->get_attrib(shade_model_slot) ||
  8942. !_state_mask.get_bit(shade_model_slot)) {
  8943. // PStatGPUTimer timer(this, _draw_set_state_shade_model_pcollector);
  8944. do_issue_shade_model();
  8945. _state_mask.set_bit(shade_model_slot);
  8946. }
  8947. #endif
  8948. #if !defined(OPENGLES) || defined(OPENGLES_1)
  8949. int logic_op_slot = LogicOpAttrib::get_class_slot();
  8950. if (_target_rs->get_attrib(logic_op_slot) != _state_rs->get_attrib(logic_op_slot) ||
  8951. !_state_mask.get_bit(logic_op_slot)) {
  8952. // PStatGPUTimer timer(this, _draw_set_state_logic_op_pcollector);
  8953. do_issue_logic_op();
  8954. _state_mask.set_bit(logic_op_slot);
  8955. }
  8956. #endif
  8957. int transparency_slot = TransparencyAttrib::get_class_slot();
  8958. int color_write_slot = ColorWriteAttrib::get_class_slot();
  8959. int color_blend_slot = ColorBlendAttrib::get_class_slot();
  8960. if (_target_rs->get_attrib(transparency_slot) != _state_rs->get_attrib(transparency_slot) ||
  8961. _target_rs->get_attrib(color_write_slot) != _state_rs->get_attrib(color_write_slot) ||
  8962. _target_rs->get_attrib(color_blend_slot) != _state_rs->get_attrib(color_blend_slot) ||
  8963. !_state_mask.get_bit(transparency_slot) ||
  8964. !_state_mask.get_bit(color_write_slot) ||
  8965. !_state_mask.get_bit(color_blend_slot)
  8966. #ifndef OPENGLES_1
  8967. || (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write) !=
  8968. _state_shader->get_flag(ShaderAttrib::F_disable_alpha_write))
  8969. #endif
  8970. ) {
  8971. // PStatGPUTimer timer(this, _draw_set_state_blending_pcollector);
  8972. do_issue_blending();
  8973. _state_mask.set_bit(transparency_slot);
  8974. _state_mask.set_bit(color_write_slot);
  8975. _state_mask.set_bit(color_blend_slot);
  8976. }
  8977. int texture_slot = TextureAttrib::get_class_slot();
  8978. if (_target_rs->get_attrib(texture_slot) != _state_rs->get_attrib(texture_slot) ||
  8979. !_state_mask.get_bit(texture_slot)) {
  8980. // PStatGPUTimer timer(this, _draw_set_state_texture_pcollector);
  8981. determine_target_texture();
  8982. int prev_active = _num_active_texture_stages;
  8983. do_issue_texture();
  8984. // Since the TexGen and TexMatrix states depend partly on the particular
  8985. // set of textures in use, we should force both of those to be reissued
  8986. // every time we change the texture state.
  8987. _state_mask.clear_bit(TexGenAttrib::get_class_slot());
  8988. _state_mask.clear_bit(TexMatrixAttrib::get_class_slot());
  8989. _state_texture = _target_texture;
  8990. _state_mask.set_bit(texture_slot);
  8991. }
  8992. // If one of the previously-loaded TexGen modes modified the texture matrix,
  8993. // then if either state changed, we have to change both of them now.
  8994. if (_tex_gen_modifies_mat) {
  8995. int tex_gen_slot = TexGenAttrib::get_class_slot();
  8996. int tex_matrix_slot = TexMatrixAttrib::get_class_slot();
  8997. if (_target_rs->get_attrib(tex_gen_slot) != _state_rs->get_attrib(tex_gen_slot) ||
  8998. _target_rs->get_attrib(tex_matrix_slot) != _state_rs->get_attrib(tex_matrix_slot) ||
  8999. !_state_mask.get_bit(tex_gen_slot) ||
  9000. !_state_mask.get_bit(tex_matrix_slot)) {
  9001. _state_mask.clear_bit(tex_gen_slot);
  9002. _state_mask.clear_bit(tex_matrix_slot);
  9003. }
  9004. }
  9005. int tex_matrix_slot = TexMatrixAttrib::get_class_slot();
  9006. if (_target_rs->get_attrib(tex_matrix_slot) != _state_rs->get_attrib(tex_matrix_slot) ||
  9007. !_state_mask.get_bit(tex_matrix_slot)) {
  9008. // PStatGPUTimer timer(this, _draw_set_state_tex_matrix_pcollector);
  9009. #ifdef SUPPORT_FIXED_FUNCTION
  9010. do_issue_tex_matrix();
  9011. #endif
  9012. _state_mask.set_bit(tex_matrix_slot);
  9013. #ifndef OPENGLES_1
  9014. if (_current_shader_context) {
  9015. _current_shader_context->issue_parameters(Shader::SSD_tex_matrix);
  9016. }
  9017. #endif
  9018. }
  9019. #ifdef SUPPORT_FIXED_FUNCTION
  9020. int tex_gen_slot = TexGenAttrib::get_class_slot();
  9021. if (_target_tex_gen != _state_tex_gen ||
  9022. !_state_mask.get_bit(tex_gen_slot)) {
  9023. // PStatGPUTimer timer(this, _draw_set_state_tex_gen_pcollector);
  9024. do_issue_tex_gen();
  9025. _state_tex_gen = _target_tex_gen;
  9026. _state_mask.set_bit(tex_gen_slot);
  9027. }
  9028. #endif
  9029. int material_slot = MaterialAttrib::get_class_slot();
  9030. if (_target_rs->get_attrib(material_slot) != _state_rs->get_attrib(material_slot) ||
  9031. !_state_mask.get_bit(material_slot)) {
  9032. // PStatGPUTimer timer(this, _draw_set_state_material_pcollector);
  9033. #ifdef SUPPORT_FIXED_FUNCTION
  9034. do_issue_material();
  9035. #endif
  9036. _state_mask.set_bit(material_slot);
  9037. }
  9038. int light_slot = LightAttrib::get_class_slot();
  9039. if (_target_rs->get_attrib(light_slot) != _state_rs->get_attrib(light_slot) ||
  9040. !_state_mask.get_bit(light_slot)) {
  9041. // PStatGPUTimer timer(this, _draw_set_state_light_pcollector);
  9042. #ifdef SUPPORT_FIXED_FUNCTION
  9043. do_issue_light();
  9044. #endif
  9045. _state_mask.set_bit(light_slot);
  9046. }
  9047. int stencil_slot = StencilAttrib::get_class_slot();
  9048. if (_target_rs->get_attrib(stencil_slot) != _state_rs->get_attrib(stencil_slot) ||
  9049. !_state_mask.get_bit(stencil_slot)) {
  9050. // PStatGPUTimer timer(this, _draw_set_state_stencil_pcollector);
  9051. do_issue_stencil();
  9052. _state_mask.set_bit(stencil_slot);
  9053. }
  9054. int fog_slot = FogAttrib::get_class_slot();
  9055. if (_target_rs->get_attrib(fog_slot) != _state_rs->get_attrib(fog_slot) ||
  9056. !_state_mask.get_bit(fog_slot)) {
  9057. // PStatGPUTimer timer(this, _draw_set_state_fog_pcollector);
  9058. #ifdef SUPPORT_FIXED_FUNCTION
  9059. do_issue_fog();
  9060. #endif
  9061. _state_mask.set_bit(fog_slot);
  9062. }
  9063. int scissor_slot = ScissorAttrib::get_class_slot();
  9064. if (_target_rs->get_attrib(scissor_slot) != _state_rs->get_attrib(scissor_slot) ||
  9065. !_state_mask.get_bit(scissor_slot)) {
  9066. // PStatGPUTimer timer(this, _draw_set_state_scissor_pcollector);
  9067. do_issue_scissor();
  9068. _state_mask.set_bit(scissor_slot);
  9069. }
  9070. _state_rs = _target_rs;
  9071. maybe_gl_finish();
  9072. report_my_gl_errors();
  9073. }
  9074. /**
  9075. * Frees some memory that was explicitly allocated within the glgsg.
  9076. */
  9077. void CLP(GraphicsStateGuardian)::
  9078. free_pointers() {
  9079. #if defined(HAVE_CG) && !defined(OPENGLES)
  9080. if (_cg_context != 0) {
  9081. cgDestroyContext(_cg_context);
  9082. _cg_context = 0;
  9083. }
  9084. #endif
  9085. }
  9086. /**
  9087. * This is called by set_state_and_transform() when the texture state has
  9088. * changed.
  9089. */
  9090. void CLP(GraphicsStateGuardian)::
  9091. do_issue_texture() {
  9092. DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
  9093. #ifdef OPENGLES_1
  9094. update_standard_texture_bindings();
  9095. #else
  9096. if (_current_shader_context == 0) {
  9097. // No shader, or a non-Cg shader.
  9098. if (_texture_binding_shader_context != 0) {
  9099. _texture_binding_shader_context->disable_shader_texture_bindings();
  9100. }
  9101. #ifdef SUPPORT_FIXED_FUNCTION
  9102. update_standard_texture_bindings();
  9103. #endif
  9104. } else {
  9105. if (_texture_binding_shader_context == 0) {
  9106. #ifdef SUPPORT_FIXED_FUNCTION
  9107. disable_standard_texture_bindings();
  9108. #endif
  9109. _current_shader_context->update_shader_texture_bindings(NULL);
  9110. } else {
  9111. _current_shader_context->
  9112. update_shader_texture_bindings(_texture_binding_shader_context);
  9113. }
  9114. }
  9115. _texture_binding_shader = _current_shader;
  9116. _texture_binding_shader_context = _current_shader_context;
  9117. #endif
  9118. }
  9119. #ifdef SUPPORT_FIXED_FUNCTION
  9120. /**
  9121. * Applies the appropriate set of textures for the current state, using the
  9122. * standard fixed-function pipeline.
  9123. */
  9124. void CLP(GraphicsStateGuardian)::
  9125. update_standard_texture_bindings() {
  9126. #ifndef NDEBUG
  9127. if (_show_texture_usage) {
  9128. update_show_usage_texture_bindings(-1);
  9129. return;
  9130. }
  9131. #endif // NDEBUG
  9132. int num_stages = _target_texture->get_num_on_ff_stages();
  9133. #ifndef NDEBUG
  9134. // Also check the _flash_texture. If it is non-NULL, we need to check to
  9135. // see if our flash_texture is in the texture stack here. If so, then we
  9136. // need to call the special show_texture method instead of the normal
  9137. // texture stack.
  9138. if (_flash_texture != (Texture *)NULL) {
  9139. double now = ClockObject::get_global_clock()->get_frame_time();
  9140. int this_second = (int)floor(now);
  9141. if (this_second & 1) {
  9142. int show_stage_index = -1;
  9143. for (int i = 0; i < num_stages && show_stage_index < 0; ++i) {
  9144. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  9145. Texture *texture = _target_texture->get_on_texture(stage);
  9146. if (texture == _flash_texture) {
  9147. show_stage_index = i;
  9148. }
  9149. }
  9150. if (show_stage_index >= 0) {
  9151. update_show_usage_texture_bindings(show_stage_index);
  9152. return;
  9153. }
  9154. }
  9155. }
  9156. #endif // NDEBUG
  9157. nassertv(num_stages <= _max_texture_stages &&
  9158. _num_active_texture_stages <= _max_texture_stages);
  9159. _texture_involves_color_scale = false;
  9160. int last_saved_result = -1;
  9161. int last_stage = -1;
  9162. int i;
  9163. for (i = 0; i < num_stages; i++) {
  9164. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  9165. Texture *texture = _target_texture->get_on_texture(stage);
  9166. nassertv(texture != (Texture *)NULL);
  9167. // Issue the texture on stage i.
  9168. set_active_texture_stage(i);
  9169. // First, turn off the previous texture mode.
  9170. glDisable(GL_TEXTURE_2D);
  9171. if (_supports_cube_map) {
  9172. glDisable(GL_TEXTURE_CUBE_MAP);
  9173. }
  9174. #ifndef OPENGLES
  9175. glDisable(GL_TEXTURE_1D);
  9176. if (_supports_3d_texture) {
  9177. glDisable(GL_TEXTURE_3D);
  9178. }
  9179. #endif // OPENGLES
  9180. int view = get_current_tex_view_offset() + stage->get_tex_view_offset();
  9181. TextureContext *tc = texture->prepare_now(view, _prepared_objects, this);
  9182. if (tc == (TextureContext *)NULL) {
  9183. // Something wrong with this texture; skip it.
  9184. continue;
  9185. }
  9186. // Then, turn on the current texture mode.
  9187. GLenum target = get_texture_target(texture->get_texture_type());
  9188. if (target == GL_NONE) {
  9189. // Unsupported texture mode.
  9190. continue;
  9191. }
  9192. #ifndef OPENGLES_1
  9193. if (target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_CUBE_MAP_ARRAY) {
  9194. // Cannot be applied via the FFP.
  9195. continue;
  9196. }
  9197. #endif // OPENGLES
  9198. glEnable(target);
  9199. if (!update_texture(tc, false)) {
  9200. glDisable(target);
  9201. continue;
  9202. }
  9203. // Don't DCAST(); we already did the verification in update_texture.
  9204. CLP(TextureContext) *gtc = (CLP(TextureContext) *)tc;
  9205. apply_texture(gtc);
  9206. apply_sampler(i, _target_texture->get_on_sampler(stage), gtc);
  9207. if (stage->involves_color_scale() && _color_scale_enabled) {
  9208. LColor color = stage->get_color();
  9209. color.set(color[0] * _current_color_scale[0],
  9210. color[1] * _current_color_scale[1],
  9211. color[2] * _current_color_scale[2],
  9212. color[3] * _current_color_scale[3]);
  9213. _texture_involves_color_scale = true;
  9214. call_glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);
  9215. } else {
  9216. call_glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, stage->get_color());
  9217. }
  9218. if (stage->get_mode() == TextureStage::M_decal) {
  9219. if (texture->get_num_components() < 3 && _supports_texture_combine) {
  9220. // Make a special case for 1- and 2-channel decal textures. OpenGL
  9221. // does not define their use with GL_DECAL for some reason, so
  9222. // implement them using the combiner instead.
  9223. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
  9224. glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
  9225. glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, 1);
  9226. glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1);
  9227. glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
  9228. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
  9229. glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);
  9230. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
  9231. glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_TEXTURE);
  9232. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
  9233. } else {
  9234. // Normal 3- and 4-channel decal textures.
  9235. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  9236. }
  9237. } else if (stage->get_mode() == TextureStage::M_combine) {
  9238. if (!_supports_texture_combine) {
  9239. GLCAT.warning()
  9240. << "TextureStage::M_combine mode is not supported.\n";
  9241. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  9242. } else {
  9243. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
  9244. glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
  9245. glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, stage->get_rgb_scale());
  9246. glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, stage->get_alpha_scale());
  9247. glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,
  9248. get_texture_combine_type(stage->get_combine_rgb_mode()));
  9249. switch (stage->get_num_combine_rgb_operands()) {
  9250. case 3:
  9251. glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB,
  9252. get_texture_src_type(stage->get_combine_rgb_source2(),
  9253. last_stage, last_saved_result, i));
  9254. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB,
  9255. get_texture_operand_type(stage->get_combine_rgb_operand2()));
  9256. // fall through
  9257. case 2:
  9258. glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB,
  9259. get_texture_src_type(stage->get_combine_rgb_source1(),
  9260. last_stage, last_saved_result, i));
  9261. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB,
  9262. get_texture_operand_type(stage->get_combine_rgb_operand1()));
  9263. // fall through
  9264. case 1:
  9265. glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB,
  9266. get_texture_src_type(stage->get_combine_rgb_source0(),
  9267. last_stage, last_saved_result, i));
  9268. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB,
  9269. get_texture_operand_type(stage->get_combine_rgb_operand0()));
  9270. // fall through
  9271. default:
  9272. break;
  9273. }
  9274. glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,
  9275. get_texture_combine_type(stage->get_combine_alpha_mode()));
  9276. switch (stage->get_num_combine_alpha_operands()) {
  9277. case 3:
  9278. glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_ALPHA,
  9279. get_texture_src_type(stage->get_combine_alpha_source2(),
  9280. last_stage, last_saved_result, i));
  9281. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA,
  9282. get_texture_operand_type(stage->get_combine_alpha_operand2()));
  9283. // fall through
  9284. case 2:
  9285. glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA,
  9286. get_texture_src_type(stage->get_combine_alpha_source1(),
  9287. last_stage, last_saved_result, i));
  9288. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA,
  9289. get_texture_operand_type(stage->get_combine_alpha_operand1()));
  9290. // fall through
  9291. case 1:
  9292. glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA,
  9293. get_texture_src_type(stage->get_combine_alpha_source0(),
  9294. last_stage, last_saved_result, i));
  9295. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA,
  9296. get_texture_operand_type(stage->get_combine_alpha_operand0()));
  9297. // fall through
  9298. default:
  9299. break;
  9300. }
  9301. }
  9302. } else {
  9303. GLint glmode = get_texture_apply_mode_type(stage->get_mode());
  9304. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, glmode);
  9305. }
  9306. if (stage->get_saved_result()) {
  9307. // This texture's result will be "saved" for a future stage's input.
  9308. last_saved_result = i;
  9309. } else {
  9310. // This is a regular texture stage; it will be the "previous" input for
  9311. // the next stage.
  9312. last_stage = i;
  9313. }
  9314. }
  9315. // Disable the texture stages that are no longer used.
  9316. for (i = num_stages; i < _num_active_texture_stages; i++) {
  9317. set_active_texture_stage(i);
  9318. glDisable(GL_TEXTURE_2D);
  9319. if (_supports_cube_map) {
  9320. glDisable(GL_TEXTURE_CUBE_MAP);
  9321. }
  9322. #ifndef OPENGLES
  9323. glDisable(GL_TEXTURE_1D);
  9324. if (_supports_3d_texture) {
  9325. glDisable(GL_TEXTURE_3D);
  9326. }
  9327. #endif // OPENGLES
  9328. }
  9329. // Save the count of texture stages for next time.
  9330. _num_active_texture_stages = num_stages;
  9331. report_my_gl_errors();
  9332. }
  9333. #endif // SUPPORT_FIXED_FUNCTION
  9334. /**
  9335. * Applies a white dummy texture. This is useful to bind to a texture slot
  9336. * when a texture is missing.
  9337. */
  9338. void CLP(GraphicsStateGuardian)::
  9339. apply_white_texture() {
  9340. if (_white_texture != 0) {
  9341. glBindTexture(GL_TEXTURE_2D, _white_texture);
  9342. return;
  9343. }
  9344. glGenTextures(1, &_white_texture);
  9345. glBindTexture(GL_TEXTURE_2D, _white_texture);
  9346. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  9347. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  9348. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  9349. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  9350. unsigned char data[] = {0xff, 0xff, 0xff, 0xff};
  9351. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0,
  9352. GL_RGBA, GL_UNSIGNED_BYTE, data);
  9353. }
  9354. /**
  9355. * Returns a white dummy texture. This is useful to bind to a texture slot
  9356. * when a texture is missing.
  9357. */
  9358. GLuint CLP(GraphicsStateGuardian)::
  9359. get_white_texture() {
  9360. if (_white_texture == 0) {
  9361. apply_white_texture();
  9362. }
  9363. return _white_texture;
  9364. }
  9365. #ifndef NDEBUG
  9366. /**
  9367. * This is a special function that loads the usage textures in gl-show-
  9368. * texture-usage mode, instead of loading the actual used textures.
  9369. *
  9370. * If the indicated stage_index is >= 0, then it is the particular texture
  9371. * that is shown. Otherwise, the textures are rotated through based on
  9372. * show_texture_usage_index.
  9373. */
  9374. void CLP(GraphicsStateGuardian)::
  9375. update_show_usage_texture_bindings(int show_stage_index) {
  9376. int num_stages = _target_texture->get_num_on_ff_stages();
  9377. nassertv(num_stages <= _max_texture_stages &&
  9378. _num_active_texture_stages <= _max_texture_stages);
  9379. _texture_involves_color_scale = false;
  9380. // First, we walk through the list of textures and pretend to render them
  9381. // all, even though we don't actually render them, just so Panda will keep
  9382. // track of the list of "active" textures correctly during the flash.
  9383. int i;
  9384. for (i = 0; i < num_stages; i++) {
  9385. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  9386. Texture *texture = _target_texture->get_on_texture(stage);
  9387. nassertv(texture != (Texture *)NULL);
  9388. int view = get_current_tex_view_offset() + stage->get_tex_view_offset();
  9389. TextureContext *tc = texture->prepare_now(view, _prepared_objects, this);
  9390. if (tc == (TextureContext *)NULL) {
  9391. // Something wrong with this texture; skip it.
  9392. break;
  9393. }
  9394. tc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  9395. }
  9396. #ifdef SUPPORT_FIXED_FUNCTION
  9397. // Disable all texture stages.
  9398. for (i = 0; i < _num_active_texture_stages; i++) {
  9399. set_active_texture_stage(i);
  9400. #ifndef OPENGLES
  9401. glDisable(GL_TEXTURE_1D);
  9402. #endif // OPENGLES
  9403. glDisable(GL_TEXTURE_2D);
  9404. if (_supports_3d_texture) {
  9405. #ifndef OPENGLES_1
  9406. glDisable(GL_TEXTURE_3D);
  9407. #endif // OPENGLES_1
  9408. }
  9409. if (_supports_cube_map) {
  9410. glDisable(GL_TEXTURE_CUBE_MAP);
  9411. }
  9412. }
  9413. #endif
  9414. // Save the count of texture stages for next time.
  9415. _num_active_texture_stages = num_stages;
  9416. if (num_stages > 0) {
  9417. // Now, pick just one texture stage to apply.
  9418. if (show_stage_index >= 0 && show_stage_index < num_stages) {
  9419. i = show_stage_index;
  9420. } else {
  9421. i = _show_texture_usage_index % num_stages;
  9422. }
  9423. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  9424. Texture *texture = _target_texture->get_on_texture(stage);
  9425. nassertv(texture != (Texture *)NULL);
  9426. // Choose the corresponding usage texture and apply it.
  9427. set_active_texture_stage(i);
  9428. #ifdef SUPPORT_FIXED_FUNCTION
  9429. glEnable(GL_TEXTURE_2D);
  9430. #endif
  9431. UsageTextureKey key(texture->get_x_size(), texture->get_y_size());
  9432. UsageTextures::iterator ui = _usage_textures.find(key);
  9433. GLuint index;
  9434. if (ui == _usage_textures.end()) {
  9435. // Need to create a new texture for this size.
  9436. glGenTextures(1, &index);
  9437. glBindTexture(GL_TEXTURE_2D, index);
  9438. // TODO: this could be a lot simpler with glTexStorage2D followed by a
  9439. // call to glClearTexImage.
  9440. upload_usage_texture(texture->get_x_size(), texture->get_y_size());
  9441. _usage_textures[key] = index;
  9442. } else {
  9443. // Just bind the previously-created texture.
  9444. index = (*ui).second;
  9445. glBindTexture(GL_TEXTURE_2D, index);
  9446. }
  9447. if (GLCAT.is_spam()) {
  9448. GLCAT.spam()
  9449. << "glBindTexture(GL_TEXTURE_2D, " << index << ")\n";
  9450. }
  9451. // TODO: glBindSampler(0) ?
  9452. }
  9453. report_my_gl_errors();
  9454. }
  9455. #endif // NDEBUG
  9456. #ifndef NDEBUG
  9457. /**
  9458. * Uploads a special "usage" texture intended to be applied only in gl-show-
  9459. * texture-usage mode, to reveal where texture memory is being spent.
  9460. */
  9461. void CLP(GraphicsStateGuardian)::
  9462. upload_usage_texture(int width, int height) {
  9463. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  9464. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  9465. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  9466. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  9467. if (GLCAT.is_debug()) {
  9468. GLCAT.debug()
  9469. << "upload_usage_texture(" << width << ", " << height << ")\n";
  9470. }
  9471. static LColor colors[3] = {
  9472. LColor(0.4, 0.5f, 0.8f, 1.0f), // mipmap 0: blue
  9473. LColor(1.0f, 1.0f, 0.0f, 1.0f), // mipmap 1: yellow
  9474. LColor(0.8f, 0.3, 0.3, 1.0f), // mipmap 2 and higher: red
  9475. };
  9476. // Allocate a temporary array large enough to contain the toplevel mipmap.
  9477. PN_uint32 *buffer = (PN_uint32 *)PANDA_MALLOC_ARRAY(width * height * 4);
  9478. int n = 0;
  9479. while (true) {
  9480. // Choose the color for the nth mipmap.
  9481. LColor c = colors[min(n, 2)];
  9482. // A simple union to store the colors values bytewise, and get the answer
  9483. // wordwise, independently of machine byte-ordernig.
  9484. union {
  9485. struct {
  9486. unsigned char r, g, b, a;
  9487. } b;
  9488. PN_uint32 w;
  9489. } store;
  9490. store.b.r = (unsigned char)(c[0] * 255.0f);
  9491. store.b.g = (unsigned char)(c[1] * 255.0f);
  9492. store.b.b = (unsigned char)(c[2] * 255.0f);
  9493. store.b.a = 0xff;
  9494. // Fill in the array.
  9495. int num_pixels = width * height;
  9496. for (int p = 0; p < num_pixels; ++p) {
  9497. buffer[p] = store.w;
  9498. }
  9499. glTexImage2D(GL_TEXTURE_2D, n, GL_RGBA, width, height, 0,
  9500. GL_RGBA, GL_UNSIGNED_BYTE, buffer);
  9501. if (width == 1 && height == 1) {
  9502. // That was the last mipmap level.
  9503. break;
  9504. }
  9505. width = max(width >> 1, 1);
  9506. height = max(height >> 1, 1);
  9507. ++n;
  9508. }
  9509. PANDA_FREE_ARRAY(buffer);
  9510. }
  9511. #endif // NDEBUG
  9512. #ifdef SUPPORT_FIXED_FUNCTION
  9513. /**
  9514. *
  9515. */
  9516. void CLP(GraphicsStateGuardian)::
  9517. disable_standard_texture_bindings() {
  9518. // Disable the texture stages that are no longer used.
  9519. for (int i = 0; i < _num_active_texture_stages; i++) {
  9520. set_active_texture_stage(i);
  9521. #ifndef OPENGLES
  9522. glDisable(GL_TEXTURE_1D);
  9523. #endif // OPENGLES
  9524. glDisable(GL_TEXTURE_2D);
  9525. if (_supports_3d_texture) {
  9526. #ifndef OPENGLES_1
  9527. glDisable(GL_TEXTURE_3D);
  9528. #endif // OPENGLES_1
  9529. }
  9530. if (_supports_cube_map) {
  9531. glDisable(GL_TEXTURE_CUBE_MAP);
  9532. }
  9533. }
  9534. _num_active_texture_stages = 0;
  9535. report_my_gl_errors();
  9536. }
  9537. #endif // SUPPORT_FIXED_FUNCTION
  9538. #ifdef SUPPORT_FIXED_FUNCTION
  9539. /**
  9540. *
  9541. */
  9542. void CLP(GraphicsStateGuardian)::
  9543. do_issue_tex_matrix() {
  9544. nassertv(_num_active_texture_stages <= _max_texture_stages);
  9545. for (int i = 0; i < _num_active_texture_stages; i++) {
  9546. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  9547. set_active_texture_stage(i);
  9548. glMatrixMode(GL_TEXTURE);
  9549. const TexMatrixAttrib *target_tex_matrix;
  9550. _target_rs->get_attrib_def(target_tex_matrix);
  9551. if (target_tex_matrix->has_stage(stage)) {
  9552. call_glLoadMatrix(target_tex_matrix->get_mat(stage));
  9553. } else {
  9554. glLoadIdentity();
  9555. // For some reason, the glLoadIdentity() call doesn't work on my Dell
  9556. // laptop's IBM OpenGL driver, when used in conjunction with glTexGen(),
  9557. // below. But explicitly loading an identity matrix does work. But
  9558. // this buggy-driver workaround might have other performance
  9559. // implications, so I leave it out.
  9560. // call_glLoadMatrix(LMatrix4::ident_mat());
  9561. }
  9562. }
  9563. report_my_gl_errors();
  9564. }
  9565. #endif // SUPPORT_FIXED_FUNCTION
  9566. #ifdef SUPPORT_FIXED_FUNCTION
  9567. /**
  9568. *
  9569. */
  9570. void CLP(GraphicsStateGuardian)::
  9571. do_issue_tex_gen() {
  9572. bool force_normal = false;
  9573. nassertv(_num_active_texture_stages <= _max_texture_stages);
  9574. // These are passed in for the four OBJECT_PLANE or EYE_PLANE values; they
  9575. // effectively define an identity matrix that maps the spatial coordinates
  9576. // one-for-one to UV's. If you want a mapping other than identity, use a
  9577. // TexMatrixAttrib (or a TexProjectorEffect).
  9578. static const PN_stdfloat s_data[4] = { 1, 0, 0, 0 };
  9579. static const PN_stdfloat t_data[4] = { 0, 1, 0, 0 };
  9580. static const PN_stdfloat r_data[4] = { 0, 0, 1, 0 };
  9581. static const PN_stdfloat q_data[4] = { 0, 0, 0, 1 };
  9582. _tex_gen_modifies_mat = false;
  9583. bool got_point_sprites = false;
  9584. for (int i = 0; i < _num_active_texture_stages; i++) {
  9585. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  9586. set_active_texture_stage(i);
  9587. if (_supports_point_sprite) {
  9588. #ifdef OPENGLES
  9589. glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_FALSE);
  9590. #else
  9591. glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_FALSE);
  9592. #endif // OPENGLES
  9593. }
  9594. #ifndef OPENGLES // TexGen not supported by OpenGL ES.
  9595. glDisable(GL_TEXTURE_GEN_S);
  9596. glDisable(GL_TEXTURE_GEN_T);
  9597. glDisable(GL_TEXTURE_GEN_R);
  9598. glDisable(GL_TEXTURE_GEN_Q);
  9599. TexGenAttrib::Mode mode = _target_tex_gen->get_mode(stage);
  9600. switch (mode) {
  9601. case TexGenAttrib::M_off:
  9602. case TexGenAttrib::M_unused2:
  9603. break;
  9604. case TexGenAttrib::M_eye_sphere_map:
  9605. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  9606. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  9607. glEnable(GL_TEXTURE_GEN_S);
  9608. glEnable(GL_TEXTURE_GEN_T);
  9609. force_normal = true;
  9610. break;
  9611. case TexGenAttrib::M_eye_cube_map:
  9612. if (_supports_cube_map) {
  9613. // We need to rotate the normals out of GL's coordinate system and
  9614. // into the user's coordinate system. We do this by composing a
  9615. // transform onto the texture matrix.
  9616. LMatrix4 mat = _inv_cs_transform->get_mat();
  9617. mat.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
  9618. glMatrixMode(GL_TEXTURE);
  9619. GLPf(MultMatrix)(mat.get_data());
  9620. // Now we need to reset the texture matrix next time around to undo
  9621. // this.
  9622. _tex_gen_modifies_mat = true;
  9623. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  9624. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  9625. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  9626. glEnable(GL_TEXTURE_GEN_S);
  9627. glEnable(GL_TEXTURE_GEN_T);
  9628. glEnable(GL_TEXTURE_GEN_R);
  9629. force_normal = true;
  9630. }
  9631. break;
  9632. case TexGenAttrib::M_world_cube_map:
  9633. if (_supports_cube_map) {
  9634. // We dynamically transform normals from eye space to world space by
  9635. // applying the appropriate rotation transform to the current texture
  9636. // matrix. Unlike M_world_position, we can't achieve this effect by
  9637. // monkeying with the modelview transform, since the current modelview
  9638. // doesn't affect GL_REFLECTION_MAP.
  9639. CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
  9640. LMatrix4 mat = camera_transform->get_mat();
  9641. mat.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
  9642. glMatrixMode(GL_TEXTURE);
  9643. GLPf(MultMatrix)(mat.get_data());
  9644. // Now we need to reset the texture matrix next time around to undo
  9645. // this.
  9646. _tex_gen_modifies_mat = true;
  9647. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  9648. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  9649. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  9650. glEnable(GL_TEXTURE_GEN_S);
  9651. glEnable(GL_TEXTURE_GEN_T);
  9652. glEnable(GL_TEXTURE_GEN_R);
  9653. force_normal = true;
  9654. }
  9655. break;
  9656. case TexGenAttrib::M_eye_normal:
  9657. if (_supports_cube_map) {
  9658. // We need to rotate the normals out of GL's coordinate system and
  9659. // into the user's coordinate system. We do this by composing a
  9660. // transform onto the texture matrix.
  9661. LMatrix4 mat = _inv_cs_transform->get_mat();
  9662. mat.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
  9663. glMatrixMode(GL_TEXTURE);
  9664. GLPf(MultMatrix)(mat.get_data());
  9665. // Now we need to reset the texture matrix next time around to undo
  9666. // this.
  9667. _tex_gen_modifies_mat = true;
  9668. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  9669. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  9670. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  9671. glEnable(GL_TEXTURE_GEN_S);
  9672. glEnable(GL_TEXTURE_GEN_T);
  9673. glEnable(GL_TEXTURE_GEN_R);
  9674. force_normal = true;
  9675. }
  9676. break;
  9677. case TexGenAttrib::M_world_normal:
  9678. if (_supports_cube_map) {
  9679. // We dynamically transform normals from eye space to world space by
  9680. // applying the appropriate rotation transform to the current texture
  9681. // matrix. Unlike M_world_position, we can't achieve this effect by
  9682. // monkeying with the modelview transform, since the current modelview
  9683. // doesn't affect GL_NORMAL_MAP.
  9684. CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
  9685. LMatrix4 mat = camera_transform->get_mat();
  9686. mat.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
  9687. glMatrixMode(GL_TEXTURE);
  9688. GLPf(MultMatrix)(mat.get_data());
  9689. // Now we need to reset the texture matrix next time around to undo
  9690. // this.
  9691. _tex_gen_modifies_mat = true;
  9692. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  9693. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  9694. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  9695. glEnable(GL_TEXTURE_GEN_S);
  9696. glEnable(GL_TEXTURE_GEN_T);
  9697. glEnable(GL_TEXTURE_GEN_R);
  9698. force_normal = true;
  9699. }
  9700. break;
  9701. case TexGenAttrib::M_eye_position:
  9702. // To represent eye position correctly, we need to temporarily load the
  9703. // coordinate-system transform.
  9704. glMatrixMode(GL_MODELVIEW);
  9705. glPushMatrix();
  9706. call_glLoadMatrix(_cs_transform->get_mat());
  9707. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  9708. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  9709. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  9710. glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  9711. GLPfv(TexGen)(GL_S, GL_EYE_PLANE, s_data);
  9712. GLPfv(TexGen)(GL_T, GL_EYE_PLANE, t_data);
  9713. GLPfv(TexGen)(GL_R, GL_EYE_PLANE, r_data);
  9714. GLPfv(TexGen)(GL_Q, GL_EYE_PLANE, q_data);
  9715. glEnable(GL_TEXTURE_GEN_S);
  9716. glEnable(GL_TEXTURE_GEN_T);
  9717. glEnable(GL_TEXTURE_GEN_R);
  9718. glEnable(GL_TEXTURE_GEN_Q);
  9719. glMatrixMode(GL_MODELVIEW);
  9720. glPopMatrix();
  9721. break;
  9722. case TexGenAttrib::M_world_position:
  9723. // We achieve world position coordinates by using the eye position mode,
  9724. // and loading the transform of the root node--thus putting the "eye" at
  9725. // the root.
  9726. {
  9727. glMatrixMode(GL_MODELVIEW);
  9728. glPushMatrix();
  9729. CPT(TransformState) root_transform = _cs_transform->compose(_scene_setup->get_world_transform());
  9730. call_glLoadMatrix(root_transform->get_mat());
  9731. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  9732. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  9733. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  9734. glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  9735. GLPfv(TexGen)(GL_S, GL_EYE_PLANE, s_data);
  9736. GLPfv(TexGen)(GL_T, GL_EYE_PLANE, t_data);
  9737. GLPfv(TexGen)(GL_R, GL_EYE_PLANE, r_data);
  9738. GLPfv(TexGen)(GL_Q, GL_EYE_PLANE, q_data);
  9739. glEnable(GL_TEXTURE_GEN_S);
  9740. glEnable(GL_TEXTURE_GEN_T);
  9741. glEnable(GL_TEXTURE_GEN_R);
  9742. glEnable(GL_TEXTURE_GEN_Q);
  9743. glMatrixMode(GL_MODELVIEW);
  9744. glPopMatrix();
  9745. }
  9746. break;
  9747. case TexGenAttrib::M_point_sprite:
  9748. if (_supports_point_sprite) {
  9749. #ifdef OPENGLES
  9750. glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE);
  9751. #else
  9752. glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
  9753. #endif
  9754. got_point_sprites = true;
  9755. }
  9756. break;
  9757. case TexGenAttrib::M_constant:
  9758. // To generate a constant UV(w) coordinate everywhere, we use EYE_LINEAR
  9759. // mode, but we construct a special matrix that flattens the vertex
  9760. // position to zero and then adds our desired value.
  9761. {
  9762. const LTexCoord3 &v = _target_tex_gen->get_constant_value(stage);
  9763. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  9764. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  9765. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  9766. glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  9767. LVecBase4 s(0.0f, 0.0f, 0.0f, v[0]);
  9768. LVecBase4 t(0.0f, 0.0f, 0.0f, v[1]);
  9769. LVecBase4 r(0.0f, 0.0f, 0.0f, v[2]);
  9770. GLPfv(TexGen)(GL_S, GL_OBJECT_PLANE, s.get_data());
  9771. GLPfv(TexGen)(GL_T, GL_OBJECT_PLANE, t.get_data());
  9772. GLPfv(TexGen)(GL_R, GL_OBJECT_PLANE, r.get_data());
  9773. GLPfv(TexGen)(GL_Q, GL_OBJECT_PLANE, q_data);
  9774. glEnable(GL_TEXTURE_GEN_S);
  9775. glEnable(GL_TEXTURE_GEN_T);
  9776. glEnable(GL_TEXTURE_GEN_R);
  9777. glEnable(GL_TEXTURE_GEN_Q);
  9778. }
  9779. break;
  9780. case TexGenAttrib::M_unused:
  9781. break;
  9782. }
  9783. #endif // OPENGLES
  9784. }
  9785. if (got_point_sprites != _tex_gen_point_sprite) {
  9786. _tex_gen_point_sprite = got_point_sprites;
  9787. #ifdef OPENGLES
  9788. if (_tex_gen_point_sprite) {
  9789. glEnable(GL_POINT_SPRITE_OES);
  9790. } else {
  9791. glDisable(GL_POINT_SPRITE_OES);
  9792. }
  9793. #else
  9794. if (_tex_gen_point_sprite) {
  9795. glEnable(GL_POINT_SPRITE_ARB);
  9796. } else {
  9797. glDisable(GL_POINT_SPRITE_ARB);
  9798. }
  9799. #endif // OPENGLES
  9800. }
  9801. report_my_gl_errors();
  9802. }
  9803. #endif // SUPPORT_FIXED_FUNCTION
  9804. /**
  9805. * Specifies the texture parameters. Returns true if the texture may need to
  9806. * be reloaded. Pass non-NULL sampler argument to use different sampler
  9807. * settings.
  9808. */
  9809. bool CLP(GraphicsStateGuardian)::
  9810. specify_texture(CLP(TextureContext) *gtc, const SamplerState &sampler) {
  9811. #ifndef OPENGLES
  9812. nassertr(gtc->_handle == 0 /* can't modify tex with active handle */, false);
  9813. #endif
  9814. Texture *tex = gtc->get_texture();
  9815. GLenum target = get_texture_target(tex->get_texture_type());
  9816. if (target == GL_NONE) {
  9817. // Unsupported target (e.g. 3-d texturing on GL 1.1).
  9818. return false;
  9819. }
  9820. #ifndef OPENGLES
  9821. if (target == GL_TEXTURE_BUFFER) {
  9822. // Buffer textures may not receive texture parameters.
  9823. return false;
  9824. }
  9825. #endif // OPENGLES
  9826. // Record the active sampler settings.
  9827. gtc->_active_sampler = sampler;
  9828. glTexParameteri(target, GL_TEXTURE_WRAP_S,
  9829. get_texture_wrap_mode(sampler.get_wrap_u()));
  9830. #ifndef OPENGLES
  9831. if (target != GL_TEXTURE_1D)
  9832. #endif
  9833. {
  9834. glTexParameteri(target, GL_TEXTURE_WRAP_T,
  9835. get_texture_wrap_mode(sampler.get_wrap_v()));
  9836. }
  9837. #ifndef OPENGLES_1
  9838. if (target == GL_TEXTURE_3D) {
  9839. glTexParameteri(target, GL_TEXTURE_WRAP_R,
  9840. get_texture_wrap_mode(sampler.get_wrap_w()));
  9841. }
  9842. #endif
  9843. #ifndef OPENGLES
  9844. LColor border_color = sampler.get_border_color();
  9845. call_glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, border_color);
  9846. #endif // OPENGLES
  9847. SamplerState::FilterType minfilter = sampler.get_effective_minfilter();
  9848. SamplerState::FilterType magfilter = sampler.get_effective_magfilter();
  9849. bool uses_mipmaps = SamplerState::is_mipmap(minfilter) && !gl_ignore_mipmaps;
  9850. #ifndef NDEBUG
  9851. if (gl_force_mipmaps) {
  9852. minfilter = SamplerState::FT_linear_mipmap_linear;
  9853. magfilter = SamplerState::FT_linear;
  9854. uses_mipmaps = true;
  9855. }
  9856. #endif
  9857. if (!tex->might_have_ram_image()) {
  9858. // If it's a dynamically generated texture (that is, the RAM image isn't
  9859. // available so it didn't pass through the CPU), we should enable GL-
  9860. // generated mipmaps if we can.
  9861. if (!_supports_generate_mipmap) {
  9862. // However, if the GPU doesn't support mipmap generation, we have to
  9863. // turn it off.
  9864. uses_mipmaps = false;
  9865. }
  9866. }
  9867. glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
  9868. get_texture_filter_type(minfilter, !uses_mipmaps));
  9869. glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
  9870. get_texture_filter_type(magfilter, true));
  9871. // Set anisotropic filtering.
  9872. if (_supports_anisotropy) {
  9873. PN_stdfloat anisotropy = sampler.get_effective_anisotropic_degree();
  9874. anisotropy = min(anisotropy, _max_anisotropy);
  9875. anisotropy = max(anisotropy, (PN_stdfloat)1.0);
  9876. glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
  9877. }
  9878. #ifndef OPENGLES_1
  9879. if (tex->get_format() == Texture::F_depth_stencil ||
  9880. tex->get_format() == Texture::F_depth_component ||
  9881. tex->get_format() == Texture::F_depth_component16 ||
  9882. tex->get_format() == Texture::F_depth_component24 ||
  9883. tex->get_format() == Texture::F_depth_component32) {
  9884. #ifdef SUPPORT_FIXED_FUNCTION
  9885. glTexParameteri(target, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
  9886. #endif
  9887. if (_supports_shadow_filter) {
  9888. if ((sampler.get_magfilter() == SamplerState::FT_shadow) ||
  9889. (sampler.get_minfilter() == SamplerState::FT_shadow)) {
  9890. glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
  9891. glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
  9892. } else {
  9893. glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
  9894. glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
  9895. }
  9896. }
  9897. }
  9898. #endif
  9899. #ifndef OPENGLES_1
  9900. if (_supports_texture_lod) {
  9901. glTexParameterf(target, GL_TEXTURE_MIN_LOD, sampler.get_min_lod());
  9902. glTexParameterf(target, GL_TEXTURE_MAX_LOD, sampler.get_max_lod());
  9903. }
  9904. #endif
  9905. #ifndef OPENGLES
  9906. if (_supports_texture_lod_bias) {
  9907. glTexParameterf(target, GL_TEXTURE_LOD_BIAS, sampler.get_lod_bias());
  9908. }
  9909. #endif
  9910. report_my_gl_errors();
  9911. if (uses_mipmaps && !gtc->_uses_mipmaps) {
  9912. // Suddenly we require mipmaps. This means the texture may need
  9913. // reloading.
  9914. return true;
  9915. }
  9916. return false;
  9917. }
  9918. /**
  9919. * Updates OpenGL with the current information for this texture, and makes it
  9920. * the current texture available for rendering.
  9921. */
  9922. bool CLP(GraphicsStateGuardian)::
  9923. apply_texture(CLP(TextureContext) *gtc) {
  9924. gtc->set_active(true);
  9925. GLenum target = get_texture_target(gtc->get_texture()->get_texture_type());
  9926. if (target == GL_NONE) {
  9927. return false;
  9928. }
  9929. if (gtc->_target != target) {
  9930. // The target has changed. That means we have to re-bind a new texture
  9931. // object.
  9932. gtc->reset_data();
  9933. gtc->_target = target;
  9934. }
  9935. glBindTexture(target, gtc->_index);
  9936. if (GLCAT.is_spam()) {
  9937. GLCAT.spam()
  9938. << "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << ")\n";
  9939. }
  9940. report_my_gl_errors();
  9941. return true;
  9942. }
  9943. /**
  9944. * Updates OpenGL with the current information for this sampler, and makes it
  9945. * the current sampler available for rendering. Use NULL to unbind the
  9946. * sampler.
  9947. *
  9948. * If the GSG doesn't support sampler objects, the sampler settings are
  9949. * applied to the given texture context instead.
  9950. */
  9951. bool CLP(GraphicsStateGuardian)::
  9952. apply_sampler(GLuint unit, const SamplerState &sampler, CLP(TextureContext) *gtc) {
  9953. #ifndef OPENGLES_1
  9954. if (_supports_sampler_objects) {
  9955. // We support sampler objects. Prepare the sampler object and bind it to
  9956. // the indicated texture unit.
  9957. SamplerContext *sc = sampler.prepare_now(get_prepared_objects(), this);
  9958. nassertr(sc != (SamplerContext *)NULL, false);
  9959. CLP(SamplerContext) *gsc = DCAST(CLP(SamplerContext), sc);
  9960. gsc->enqueue_lru(&_prepared_objects->_sampler_object_lru);
  9961. _glBindSampler(unit, gsc->_index);
  9962. if (GLCAT.is_spam()) {
  9963. GLCAT.spam() << "glBindSampler(" << unit << ", "
  9964. << gsc->_index << "): " << sampler << "\n";
  9965. }
  9966. } else
  9967. #endif // !OPENGLES_1
  9968. {
  9969. // We don't support sampler objects. We'll have to bind the texture and
  9970. // change the texture parameters if they don't match.
  9971. if (gtc->_active_sampler != sampler) {
  9972. set_active_texture_stage(unit);
  9973. apply_texture(gtc);
  9974. specify_texture(gtc, sampler);
  9975. }
  9976. }
  9977. if (sampler.uses_mipmaps() && !gtc->_uses_mipmaps && !gl_ignore_mipmaps) {
  9978. // The texture wasn't created with mipmaps, but we are trying to sample it
  9979. // with mipmaps. We will need to reload it.
  9980. GLCAT.info()
  9981. << "reloading texture " << gtc->get_texture()->get_name()
  9982. << " with mipmaps\n";
  9983. apply_texture(gtc);
  9984. gtc->mark_needs_reload();
  9985. bool okflag = upload_texture(gtc, false, true);
  9986. if (!okflag) {
  9987. GLCAT.error()
  9988. << "Could not load " << *gtc->get_texture() << "\n";
  9989. return false;
  9990. }
  9991. }
  9992. report_my_gl_errors();
  9993. return true;
  9994. }
  9995. /**
  9996. * Uploads the entire texture image to OpenGL, including all pages.
  9997. *
  9998. * The return value is true if successful, or false if the texture has no
  9999. * image.
  10000. */
  10001. bool CLP(GraphicsStateGuardian)::
  10002. upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
  10003. PStatGPUTimer timer(this, _load_texture_pcollector);
  10004. Texture *tex = gtc->get_texture();
  10005. if (_effective_incomplete_render && !force) {
  10006. bool has_image = _supports_compressed_texture ? tex->has_ram_image() : tex->has_uncompressed_ram_image();
  10007. if (!has_image && tex->might_have_ram_image() &&
  10008. tex->has_simple_ram_image() &&
  10009. !_loader.is_null()) {
  10010. // If we don't have the texture data right now, go get it, but in the
  10011. // meantime load a temporary simple image in its place.
  10012. async_reload_texture(gtc);
  10013. has_image = _supports_compressed_texture ? tex->has_ram_image() : tex->has_uncompressed_ram_image();
  10014. if (!has_image) {
  10015. if (gtc->was_simple_image_modified()) {
  10016. return upload_simple_texture(gtc);
  10017. }
  10018. return true;
  10019. }
  10020. }
  10021. }
  10022. CPTA_uchar image;
  10023. if (_supports_compressed_texture) {
  10024. image = tex->get_ram_image();
  10025. } else {
  10026. image = tex->get_uncompressed_ram_image();
  10027. }
  10028. Texture::CompressionMode image_compression;
  10029. if (image.is_null()) {
  10030. image_compression = Texture::CM_off;
  10031. } else {
  10032. image_compression = tex->get_ram_image_compression();
  10033. }
  10034. if (!get_supports_compressed_texture_format(image_compression)) {
  10035. image = tex->get_uncompressed_ram_image();
  10036. image_compression = Texture::CM_off;
  10037. // If this triggers, Panda cannot decompress the texture. Compile with
  10038. // libsquish support or precompress the texture.
  10039. nassertr(!image.is_null(), false);
  10040. }
  10041. int mipmap_bias = 0;
  10042. int width = tex->get_x_size();
  10043. int height = tex->get_y_size();
  10044. int depth = tex->get_z_size();
  10045. // If we'll use immutable texture storage, we have to pick a sized image
  10046. // format.
  10047. bool force_sized = (gl_immutable_texture_storage && _supports_tex_storage) ||
  10048. (tex->get_texture_type() == Texture::TT_buffer_texture);
  10049. GLint internal_format = get_internal_image_format(tex, force_sized);
  10050. GLint external_format = get_external_image_format(tex);
  10051. GLenum component_type = get_component_type(tex->get_component_type());
  10052. if (GLCAT.is_debug()) {
  10053. if (image.is_null()) {
  10054. GLCAT.debug()
  10055. << "loading texture with NULL image";
  10056. } else if (image_compression != Texture::CM_off) {
  10057. GLCAT.debug()
  10058. << "loading pre-compressed texture";
  10059. } else if (is_compressed_format(internal_format)) {
  10060. GLCAT.debug()
  10061. << "loading compressed texture";
  10062. } else {
  10063. GLCAT.debug()
  10064. << "loading uncompressed texture";
  10065. }
  10066. GLCAT.debug(false) << " " << tex->get_name() << "\n";
  10067. }
  10068. // Ensure that the texture fits within the GL's specified limits. Need to
  10069. // split dimensions because of texture arrays
  10070. int max_dimension_x;
  10071. int max_dimension_y;
  10072. int max_dimension_z;
  10073. switch (tex->get_texture_type()) {
  10074. case Texture::TT_3d_texture:
  10075. max_dimension_x = _max_3d_texture_dimension;
  10076. max_dimension_y = _max_3d_texture_dimension;
  10077. max_dimension_z = _max_3d_texture_dimension;
  10078. break;
  10079. case Texture::TT_cube_map:
  10080. max_dimension_x = _max_cube_map_dimension;
  10081. max_dimension_y = _max_cube_map_dimension;
  10082. max_dimension_z = 6;
  10083. break;
  10084. case Texture::TT_2d_texture_array:
  10085. max_dimension_x = _max_texture_dimension;
  10086. max_dimension_y = _max_texture_dimension;
  10087. max_dimension_z = _max_2d_texture_array_layers;
  10088. break;
  10089. case Texture::TT_cube_map_array:
  10090. max_dimension_x = _max_texture_dimension;
  10091. max_dimension_y = _max_texture_dimension;
  10092. max_dimension_z = int(_max_2d_texture_array_layers / 6) * 6;
  10093. break;
  10094. case Texture::TT_buffer_texture:
  10095. max_dimension_x = _max_buffer_texture_size;
  10096. max_dimension_y = 1;
  10097. max_dimension_z = 1;
  10098. break;
  10099. default:
  10100. max_dimension_x = _max_texture_dimension;
  10101. max_dimension_y = _max_texture_dimension;
  10102. max_dimension_z = 1;
  10103. }
  10104. if (max_dimension_x == 0 || max_dimension_y == 0 || max_dimension_z == 0) {
  10105. // Guess this GL doesn't support cube mapping3d textures2d texture arrays.
  10106. report_my_gl_errors();
  10107. return false;
  10108. }
  10109. // If it doesn't fit, we have to reduce it on-the-fly. We do this by
  10110. // incrementing the mipmap_bias, so we're effectively loading a lower mipmap
  10111. // level. This requires generating the mipmaps on the CPU if they haven't
  10112. // already been generated. It would have been better if the user had
  10113. // specified max-texture-dimension to reduce the texture at load time
  10114. // instead; of course, the user doesn't always know ahead of time what the
  10115. // hardware limits are.
  10116. if ((max_dimension_x > 0 && max_dimension_y > 0 && max_dimension_z > 0) &&
  10117. image_compression == Texture::CM_off) {
  10118. while (tex->get_expected_mipmap_x_size(mipmap_bias) > max_dimension_x ||
  10119. tex->get_expected_mipmap_y_size(mipmap_bias) > max_dimension_y ||
  10120. tex->get_expected_mipmap_z_size(mipmap_bias) > max_dimension_z) {
  10121. ++mipmap_bias;
  10122. }
  10123. if (mipmap_bias >= tex->get_num_ram_mipmap_images()) {
  10124. // We need to generate some more mipmap images.
  10125. if (tex->has_ram_image()) {
  10126. tex->generate_ram_mipmap_images();
  10127. if (mipmap_bias >= tex->get_num_ram_mipmap_images()) {
  10128. // It didn't work. Send the smallest we've got, and hope for the
  10129. // best.
  10130. mipmap_bias = tex->get_num_ram_mipmap_images() - 1;
  10131. }
  10132. }
  10133. }
  10134. width = tex->get_expected_mipmap_x_size(mipmap_bias);
  10135. height = tex->get_expected_mipmap_y_size(mipmap_bias);
  10136. depth = tex->get_expected_mipmap_z_size(mipmap_bias);
  10137. if (mipmap_bias != 0) {
  10138. GLCAT.info()
  10139. << "Reducing image " << tex->get_name()
  10140. << " from " << tex->get_x_size() << " x " << tex->get_y_size()
  10141. << " x " << tex->get_z_size() << " to "
  10142. << width << " x " << height << " x " << depth << "\n";
  10143. }
  10144. }
  10145. if (image_compression != Texture::CM_off) {
  10146. Texture::QualityLevel quality_level = tex->get_effective_quality_level();
  10147. #ifndef OPENGLES
  10148. switch (quality_level) {
  10149. case Texture::QL_fastest:
  10150. glHint(GL_TEXTURE_COMPRESSION_HINT, GL_FASTEST);
  10151. break;
  10152. case Texture::QL_default:
  10153. case Texture::QL_normal:
  10154. glHint(GL_TEXTURE_COMPRESSION_HINT, GL_DONT_CARE);
  10155. break;
  10156. case Texture::QL_best:
  10157. glHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST);
  10158. break;
  10159. }
  10160. #endif
  10161. }
  10162. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  10163. GLenum target = get_texture_target(tex->get_texture_type());
  10164. uses_mipmaps = (uses_mipmaps && !gl_ignore_mipmaps) || gl_force_mipmaps;
  10165. #ifndef OPENGLES
  10166. if (target == GL_TEXTURE_BUFFER) {
  10167. // Buffer textures may not have mipmaps.
  10168. uses_mipmaps = false;
  10169. }
  10170. #endif // OPENGLES
  10171. bool needs_reload = false;
  10172. if (!gtc->_has_storage ||
  10173. gtc->_uses_mipmaps != uses_mipmaps ||
  10174. gtc->_internal_format != internal_format ||
  10175. gtc->_width != width ||
  10176. gtc->_height != height ||
  10177. gtc->_depth != depth) {
  10178. // We need to reload a new GL Texture object.
  10179. needs_reload = true;
  10180. if (_use_object_labels) {
  10181. // This seems like a good time to assign a label for the debug messages.
  10182. const string &name = tex->get_name();
  10183. _glObjectLabel(GL_TEXTURE, gtc->_index, name.size(), name.data());
  10184. }
  10185. }
  10186. if (needs_reload && gtc->_immutable) {
  10187. GLCAT.info() << "Attempt to modify texture with immutable storage, recreating texture.\n";
  10188. gtc->reset_data();
  10189. glBindTexture(target, gtc->_index);
  10190. if (GLCAT.is_spam()) {
  10191. GLCAT.spam()
  10192. << "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << ")\n";
  10193. }
  10194. }
  10195. #ifndef OPENGLES
  10196. if (target == GL_TEXTURE_BUFFER) {
  10197. // Buffer textures don't support mipmappping.
  10198. gtc->_generate_mipmaps = false;
  10199. if (gtc->_buffer == 0) {
  10200. // The buffer object wasn't created yet.
  10201. _glGenBuffers(1, &gtc->_buffer);
  10202. _glBindBuffer(GL_TEXTURE_BUFFER, gtc->_buffer);
  10203. _glTexBuffer(GL_TEXTURE_BUFFER, internal_format, gtc->_buffer);
  10204. needs_reload = true;
  10205. } else {
  10206. _glBindBuffer(GL_TEXTURE_BUFFER, gtc->_buffer);
  10207. if (gtc->_internal_format != internal_format) {
  10208. _glTexBuffer(GL_TEXTURE_BUFFER, internal_format, gtc->_buffer);
  10209. }
  10210. }
  10211. } else
  10212. #endif // !OPENGLES
  10213. if (needs_reload) {
  10214. // Figure out whether mipmaps will be generated by the GPU or by Panda (or
  10215. // not at all), and how many mipmap levels should be created.
  10216. gtc->_generate_mipmaps = false;
  10217. int num_levels = 1;
  10218. CPTA_uchar image = tex->get_ram_mipmap_image(mipmap_bias);
  10219. if (image.is_null()) {
  10220. // We don't even have a RAM image, so we have no choice but to let
  10221. // mipmaps be generated on the GPU.
  10222. if (uses_mipmaps) {
  10223. if (_supports_generate_mipmap) {
  10224. num_levels = tex->get_expected_num_mipmap_levels() - mipmap_bias;
  10225. gtc->_generate_mipmaps = true;
  10226. } else {
  10227. // If it can't, do without mipmaps.
  10228. num_levels = 1;
  10229. glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  10230. }
  10231. }
  10232. } else {
  10233. if (uses_mipmaps) {
  10234. num_levels = tex->get_num_ram_mipmap_images() - mipmap_bias;
  10235. if (num_levels <= 1) {
  10236. // No RAM mipmap levels available. Should we generate some?
  10237. if (!_supports_generate_mipmap || !driver_generate_mipmaps ||
  10238. image_compression != Texture::CM_off) {
  10239. // Yes, the GL can't or won't generate them, so we need to. Note
  10240. // that some drivers (nVidia) will *corrupt memory* if you ask
  10241. // them to generate mipmaps for a pre-compressed texture.
  10242. tex->generate_ram_mipmap_images();
  10243. num_levels = tex->get_num_ram_mipmap_images() - mipmap_bias;
  10244. }
  10245. }
  10246. if (num_levels <= 1) {
  10247. // We don't have mipmap levels in RAM. Ask the GL to generate them
  10248. // if it can.
  10249. if (_supports_generate_mipmap) {
  10250. num_levels = tex->get_expected_num_mipmap_levels() - mipmap_bias;
  10251. gtc->_generate_mipmaps = true;
  10252. } else {
  10253. // If it can't, do without mipmaps.
  10254. glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  10255. num_levels = 1;
  10256. }
  10257. }
  10258. }
  10259. }
  10260. if (_supports_texture_max_level) {
  10261. // By the time we get here, we have a pretty good prediction for the
  10262. // number of mipmaps we're going to have, so tell the GL that's all it's
  10263. // going to get.
  10264. glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, num_levels - 1);
  10265. }
  10266. #ifndef OPENGLES_2
  10267. if (gtc->_generate_mipmaps && _glGenerateMipmap == NULL) {
  10268. // The old, deprecated way to generate mipmaps.
  10269. glTexParameteri(target, GL_GENERATE_MIPMAP, GL_TRUE);
  10270. }
  10271. #endif
  10272. #if !defined(SUPPORT_FIXED_FUNCTION) && !defined(OPENGLES)
  10273. // Do we need to apply a swizzle mask to emulate these deprecated texture
  10274. // formats?
  10275. switch (tex->get_format()) {
  10276. case Texture::F_alpha:
  10277. glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_ZERO);
  10278. glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, GL_ZERO);
  10279. glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_ZERO);
  10280. glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, GL_RED);
  10281. break;
  10282. case Texture::F_luminance:
  10283. glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_RED);
  10284. glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, GL_RED);
  10285. glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_RED);
  10286. glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, GL_ONE);
  10287. break;
  10288. case Texture::F_luminance_alpha:
  10289. glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_RED);
  10290. glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, GL_RED);
  10291. glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_RED);
  10292. glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, GL_GREEN);
  10293. break;
  10294. default:
  10295. break;
  10296. }
  10297. #endif
  10298. // Allocate immutable storage for the texture, after which we can subload
  10299. // it. Pre-allocating storage using glTexStorage is more efficient than
  10300. // using glTexImage to load all of the individual images one by one later,
  10301. // but we are not allowed to change the texture size or number of mipmap
  10302. // levels after this point.
  10303. if (gl_immutable_texture_storage && _supports_tex_storage && !gtc->_has_storage) {
  10304. if (GLCAT.is_debug()) {
  10305. GLCAT.debug()
  10306. << "allocating storage for texture " << tex->get_name() << ", " << width
  10307. << " x " << height << " x " << depth << ", mipmaps " << num_levels
  10308. << ", uses_mipmaps = " << uses_mipmaps << "\n";
  10309. }
  10310. switch (tex->get_texture_type()) {
  10311. case Texture::TT_buffer_texture:
  10312. // Won't get here, but squelch compiler warning
  10313. case Texture::TT_1d_texture:
  10314. _glTexStorage1D(target, num_levels, internal_format, width);
  10315. break;
  10316. case Texture::TT_2d_texture:
  10317. case Texture::TT_cube_map:
  10318. _glTexStorage2D(target, num_levels, internal_format, width, height);
  10319. break;
  10320. case Texture::TT_3d_texture:
  10321. case Texture::TT_2d_texture_array:
  10322. case Texture::TT_cube_map_array:
  10323. _glTexStorage3D(target, num_levels, internal_format, width, height, depth);
  10324. break;
  10325. }
  10326. gtc->_has_storage = true;
  10327. gtc->_immutable = true;
  10328. gtc->_uses_mipmaps = uses_mipmaps;
  10329. gtc->_internal_format = internal_format;
  10330. gtc->_width = width;
  10331. gtc->_height = height;
  10332. gtc->_depth = depth;
  10333. gtc->update_data_size_bytes(get_texture_memory_size(gtc));
  10334. needs_reload = false;
  10335. }
  10336. } else {
  10337. // Maybe we need to generate mipmaps on the CPU.
  10338. if (!image.is_null() && uses_mipmaps) {
  10339. if (tex->get_num_ram_mipmap_images() - mipmap_bias <= 1) {
  10340. // No RAM mipmap levels available. Should we generate some?
  10341. if (!_supports_generate_mipmap || !driver_generate_mipmaps ||
  10342. image_compression != Texture::CM_off) {
  10343. // Yes, the GL can't or won't generate them, so we need to. Note
  10344. // that some drivers (nVidia) will *corrupt memory* if you ask them
  10345. // to generate mipmaps for a pre-compressed texture.
  10346. tex->generate_ram_mipmap_images();
  10347. }
  10348. }
  10349. }
  10350. }
  10351. bool success = true;
  10352. if (tex->get_texture_type() == Texture::TT_cube_map) {
  10353. // A cube map must load six different 2-d images (which are stored as the
  10354. // six pages of the system ram image).
  10355. if (!_supports_cube_map) {
  10356. report_my_gl_errors();
  10357. return false;
  10358. }
  10359. nassertr(target == GL_TEXTURE_CUBE_MAP, false);
  10360. success = success && upload_texture_image
  10361. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  10362. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
  10363. internal_format, external_format, component_type,
  10364. true, 0, image_compression);
  10365. success = success && upload_texture_image
  10366. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  10367. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
  10368. internal_format, external_format, component_type,
  10369. true, 1, image_compression);
  10370. success = success && upload_texture_image
  10371. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  10372. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
  10373. internal_format, external_format, component_type,
  10374. true, 2, image_compression);
  10375. success = success && upload_texture_image
  10376. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  10377. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
  10378. internal_format, external_format, component_type,
  10379. true, 3, image_compression);
  10380. success = success && upload_texture_image
  10381. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  10382. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
  10383. internal_format, external_format, component_type,
  10384. true, 4, image_compression);
  10385. success = success && upload_texture_image
  10386. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  10387. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
  10388. internal_format, external_format, component_type,
  10389. true, 5, image_compression);
  10390. } else {
  10391. // Any other kind of texture can be loaded all at once.
  10392. success = upload_texture_image
  10393. (gtc, needs_reload, uses_mipmaps, mipmap_bias, target,
  10394. target, internal_format, external_format,
  10395. component_type, false, 0, image_compression);
  10396. }
  10397. if (gtc->_generate_mipmaps && _glGenerateMipmap != NULL &&
  10398. !image.is_null()) {
  10399. // We uploaded an image; we may need to generate mipmaps.
  10400. if (GLCAT.is_debug()) {
  10401. GLCAT.debug()
  10402. << "generating mipmaps for texture " << tex->get_name() << ", "
  10403. << width << " x " << height << " x " << depth
  10404. << ", uses_mipmaps = " << uses_mipmaps << "\n";
  10405. }
  10406. _glGenerateMipmap(target);
  10407. }
  10408. maybe_gl_finish();
  10409. if (success) {
  10410. if (needs_reload) {
  10411. gtc->_has_storage = true;
  10412. gtc->_uses_mipmaps = uses_mipmaps;
  10413. gtc->_internal_format = internal_format;
  10414. gtc->_width = width;
  10415. gtc->_height = height;
  10416. gtc->_depth = depth;
  10417. gtc->update_data_size_bytes(get_texture_memory_size(gtc));
  10418. }
  10419. nassertr(gtc->_has_storage, false);
  10420. if (tex->get_post_load_store_cache()) {
  10421. tex->set_post_load_store_cache(false);
  10422. // OK, get the RAM image, and save it in a BamCache record.
  10423. if (do_extract_texture_data(gtc)) {
  10424. if (tex->has_ram_image()) {
  10425. BamCache *cache = BamCache::get_global_ptr();
  10426. PT(BamCacheRecord) record = cache->lookup(tex->get_fullpath(), "txo");
  10427. if (record != (BamCacheRecord *)NULL) {
  10428. record->set_data(tex, tex);
  10429. cache->store(record);
  10430. }
  10431. }
  10432. }
  10433. }
  10434. GraphicsEngine *engine = get_engine();
  10435. nassertr(engine != (GraphicsEngine *)NULL, false);
  10436. engine->texture_uploaded(tex);
  10437. gtc->mark_loaded();
  10438. report_my_gl_errors();
  10439. return true;
  10440. }
  10441. report_my_gl_errors();
  10442. return false;
  10443. }
  10444. /**
  10445. * Loads a texture image, or one page of a cube map image, from system RAM to
  10446. * texture memory.
  10447. *
  10448. * texture_target is normally the same thing as page_target; both represent
  10449. * the GL target onto which the texture image is loaded, e.g. GL_TEXTURE_1D,
  10450. * GL_TEXTURE_2D, etc. The only time they may differ is in the case of cube
  10451. * mapping, in which case texture_target will be target for the overall
  10452. * texture, e.g. GL_TEXTURE_CUBE_MAP, and page_target will be the target for
  10453. * this particular page, e.g. GL_TEXTURE_CUBE_MAP_POSITIVE_X.
  10454. */
  10455. bool CLP(GraphicsStateGuardian)::
  10456. upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
  10457. bool uses_mipmaps, int mipmap_bias,
  10458. GLenum texture_target, GLenum page_target,
  10459. GLint internal_format,
  10460. GLint external_format, GLenum component_type,
  10461. bool one_page_only, int z,
  10462. Texture::CompressionMode image_compression) {
  10463. // Make sure the error stack is cleared out before we begin.
  10464. clear_my_gl_errors();
  10465. if (texture_target == GL_NONE) {
  10466. // Unsupported target (e.g. 3-d texturing on GL 1.1).
  10467. return false;
  10468. }
  10469. if (image_compression != Texture::CM_off && !_supports_compressed_texture) {
  10470. return false;
  10471. }
  10472. Texture *tex = gtc->get_texture();
  10473. nassertr(tex != (Texture *)NULL, false);
  10474. CPTA_uchar image = tex->get_ram_mipmap_image(mipmap_bias);
  10475. int width = tex->get_expected_mipmap_x_size(mipmap_bias);
  10476. int height = tex->get_expected_mipmap_y_size(mipmap_bias);
  10477. int depth = tex->get_expected_mipmap_z_size(mipmap_bias);
  10478. // Determine the number of images to upload.
  10479. int num_levels = 1;
  10480. if (uses_mipmaps) {
  10481. num_levels = tex->get_expected_num_mipmap_levels();
  10482. }
  10483. int num_ram_mipmap_levels = 0;
  10484. if (!image.is_null()) {
  10485. if (uses_mipmaps) {
  10486. num_ram_mipmap_levels = tex->get_num_ram_mipmap_images();
  10487. } else {
  10488. num_ram_mipmap_levels = 1;
  10489. }
  10490. }
  10491. #ifndef OPENGLES_1
  10492. if (needs_reload || num_ram_mipmap_levels > 0) {
  10493. // Make sure that any incoherent writes to this texture have been synced.
  10494. if (gtc->needs_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT)) {
  10495. issue_memory_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
  10496. }
  10497. }
  10498. #endif
  10499. if (!needs_reload) {
  10500. // Try to subload the image over the existing GL Texture object, possibly
  10501. // saving on texture memory fragmentation.
  10502. if (GLCAT.is_debug()) {
  10503. if (num_ram_mipmap_levels == 0) {
  10504. if (tex->has_clear_color()) {
  10505. GLCAT.debug()
  10506. << "clearing texture " << tex->get_name() << ", "
  10507. << width << " x " << height << " x " << depth << ", z = " << z
  10508. << ", uses_mipmaps = " << uses_mipmaps << ", clear_color = "
  10509. << tex->get_clear_color() << "\n";
  10510. } else {
  10511. GLCAT.debug()
  10512. << "not loading NULL image for texture " << tex->get_name()
  10513. << ", " << width << " x " << height << " x " << depth
  10514. << ", z = " << z << ", uses_mipmaps = " << uses_mipmaps << "\n";
  10515. }
  10516. } else {
  10517. GLCAT.debug()
  10518. << "updating image data of texture " << tex->get_name()
  10519. << ", " << width << " x " << height << " x " << depth
  10520. << ", z = " << z << ", mipmaps " << num_ram_mipmap_levels
  10521. << ", uses_mipmaps = " << uses_mipmaps << "\n";
  10522. }
  10523. }
  10524. for (int n = mipmap_bias; n < num_levels; ++n) {
  10525. // we grab the mipmap pointer first, if it is NULL we grab the normal
  10526. // mipmap image pointer which is a PTA_uchar
  10527. const unsigned char *image_ptr = (unsigned char*)tex->get_ram_mipmap_pointer(n);
  10528. CPTA_uchar ptimage;
  10529. if (image_ptr == (const unsigned char *)NULL) {
  10530. ptimage = tex->get_ram_mipmap_image(n);
  10531. if (ptimage.is_null()) {
  10532. if (n < num_ram_mipmap_levels) {
  10533. // We were told we'd have this many RAM mipmap images, but we
  10534. // don't. Raise a warning.
  10535. GLCAT.warning()
  10536. << "No mipmap level " << n << " defined for " << tex->get_name()
  10537. << "\n";
  10538. break;
  10539. }
  10540. if (tex->has_clear_color()) {
  10541. // The texture has a clear color, so we should fill this mipmap
  10542. // level to a solid color.
  10543. #ifndef OPENGLES
  10544. if (texture_target != GL_TEXTURE_BUFFER) {
  10545. if (_supports_clear_texture) {
  10546. // We can do that with the convenient glClearTexImage
  10547. // function.
  10548. string clear_data = tex->get_clear_data();
  10549. _glClearTexImage(gtc->_index, n - mipmap_bias, external_format,
  10550. component_type, (void *)clear_data.data());
  10551. continue;
  10552. }
  10553. } else {
  10554. if (_supports_clear_buffer) {
  10555. // For buffer textures we need to clear the underlying
  10556. // storage.
  10557. string clear_data = tex->get_clear_data();
  10558. _glClearBufferData(GL_TEXTURE_BUFFER, internal_format, external_format,
  10559. component_type, (const void *)clear_data.data());
  10560. continue;
  10561. }
  10562. }
  10563. #endif // OPENGLES
  10564. // Ask the Texture class to create the mipmap level in RAM. It'll
  10565. // fill it in with the correct clear color, which we can then
  10566. // upload.
  10567. ptimage = tex->make_ram_mipmap_image(n);
  10568. } else {
  10569. // No clear color and no more images.
  10570. break;
  10571. }
  10572. }
  10573. image_ptr = ptimage;
  10574. }
  10575. PTA_uchar bgr_image;
  10576. size_t view_size = tex->get_ram_mipmap_view_size(n);
  10577. if (image_ptr != (const unsigned char *)NULL) {
  10578. const unsigned char *orig_image_ptr = image_ptr;
  10579. image_ptr += view_size * gtc->get_view();
  10580. if (one_page_only) {
  10581. view_size = tex->get_ram_mipmap_page_size(n);
  10582. image_ptr += view_size * z;
  10583. }
  10584. nassertr(image_ptr >= orig_image_ptr && image_ptr + view_size <= orig_image_ptr + tex->get_ram_mipmap_image_size(n), false);
  10585. if (image_compression == Texture::CM_off) {
  10586. // If the GL doesn't claim to support BGR, we may have to reverse
  10587. // the component ordering of the image.
  10588. image_ptr = fix_component_ordering(bgr_image, image_ptr, view_size,
  10589. external_format, tex);
  10590. }
  10591. }
  10592. int width = tex->get_expected_mipmap_x_size(n);
  10593. int height = tex->get_expected_mipmap_y_size(n);
  10594. int depth = tex->get_expected_mipmap_z_size(n);
  10595. #ifdef DO_PSTATS
  10596. _data_transferred_pcollector.add_level(view_size);
  10597. #endif
  10598. switch (texture_target) {
  10599. #ifndef OPENGLES_1
  10600. case GL_TEXTURE_3D:
  10601. if (_supports_3d_texture) {
  10602. if (image_compression == Texture::CM_off) {
  10603. _glTexSubImage3D(page_target, n - mipmap_bias, 0, 0, 0, width, height, depth,
  10604. external_format, component_type, image_ptr);
  10605. } else {
  10606. _glCompressedTexSubImage3D(page_target, n - mipmap_bias, 0, 0, 0, width, height, depth,
  10607. external_format, view_size, image_ptr);
  10608. }
  10609. } else {
  10610. report_my_gl_errors();
  10611. return false;
  10612. }
  10613. break;
  10614. #endif // OPENGLES_1
  10615. #ifndef OPENGLES
  10616. case GL_TEXTURE_1D:
  10617. if (image_compression == Texture::CM_off) {
  10618. glTexSubImage1D(page_target, n - mipmap_bias, 0, width,
  10619. external_format, component_type, image_ptr);
  10620. } else {
  10621. _glCompressedTexSubImage1D(page_target, n - mipmap_bias, 0, width,
  10622. external_format, view_size, image_ptr);
  10623. }
  10624. break;
  10625. #endif // OPENGLES
  10626. #ifndef OPENGLES_1
  10627. case GL_TEXTURE_2D_ARRAY:
  10628. case GL_TEXTURE_CUBE_MAP_ARRAY:
  10629. if (_supports_2d_texture_array) {
  10630. if (image_compression == Texture::CM_off) {
  10631. _glTexSubImage3D(page_target, n - mipmap_bias, 0, 0, 0, width, height, depth,
  10632. external_format, component_type, image_ptr);
  10633. } else {
  10634. _glCompressedTexSubImage3D(page_target, n - mipmap_bias, 0, 0, 0, width, height, depth,
  10635. external_format, view_size, image_ptr);
  10636. }
  10637. } else {
  10638. report_my_gl_errors();
  10639. return false;
  10640. }
  10641. break;
  10642. #endif // OPENGLES_1
  10643. #ifndef OPENGLES
  10644. case GL_TEXTURE_BUFFER:
  10645. if (_supports_buffer_texture) {
  10646. _glBufferSubData(GL_TEXTURE_BUFFER, 0, view_size, image_ptr);
  10647. } else {
  10648. report_my_gl_errors();
  10649. return false;
  10650. }
  10651. break;
  10652. #endif // OPENGLES
  10653. default:
  10654. if (image_compression == Texture::CM_off) {
  10655. if (n==0) {
  10656. // It's unfortunate that we can't adjust the width, too, but
  10657. // TexSubImage2D doesn't accept a row-stride parameter.
  10658. height = tex->get_y_size() - tex->get_pad_y_size();
  10659. }
  10660. glTexSubImage2D(page_target, n - mipmap_bias, 0, 0, width, height,
  10661. external_format, component_type, image_ptr);
  10662. } else {
  10663. _glCompressedTexSubImage2D(page_target, n - mipmap_bias, 0, 0, width, height,
  10664. external_format, view_size, image_ptr);
  10665. }
  10666. break;
  10667. }
  10668. }
  10669. // Did that fail? If it did, we'll immediately try again, this time
  10670. // loading the texture from scratch.
  10671. GLenum error_code = gl_get_error();
  10672. if (error_code != GL_NO_ERROR) {
  10673. if (GLCAT.is_debug()) {
  10674. GLCAT.debug()
  10675. << "GL texture subload failed for " << tex->get_name()
  10676. << " : " << get_error_string(error_code) << "\n";
  10677. }
  10678. needs_reload = true;
  10679. }
  10680. }
  10681. if (needs_reload) {
  10682. // Load the image up from scratch, creating a new GL Texture object.
  10683. if (GLCAT.is_debug()) {
  10684. GLCAT.debug()
  10685. << "loading new texture object for " << tex->get_name() << ", " << width
  10686. << " x " << height << " x " << depth << ", z = " << z << ", mipmaps "
  10687. << num_ram_mipmap_levels << ", uses_mipmaps = " << uses_mipmaps << "\n";
  10688. }
  10689. // If there is immutable storage, this is impossible to do, and we should
  10690. // not have gotten here at all.
  10691. nassertr(!gtc->_immutable, false);
  10692. if (num_ram_mipmap_levels == 0) {
  10693. if (GLCAT.is_debug()) {
  10694. GLCAT.debug()
  10695. << " (initializing NULL image)\n";
  10696. }
  10697. if ((external_format == GL_DEPTH_STENCIL) && get_supports_depth_stencil()) {
  10698. #ifdef OPENGLES
  10699. component_type = GL_UNSIGNED_INT_24_8_OES;
  10700. #else
  10701. component_type = GL_UNSIGNED_INT_24_8_EXT;
  10702. #endif
  10703. }
  10704. }
  10705. for (int n = mipmap_bias; n < num_levels; ++n) {
  10706. const unsigned char *image_ptr = (unsigned char*)tex->get_ram_mipmap_pointer(n);
  10707. CPTA_uchar ptimage;
  10708. if (image_ptr == (const unsigned char *)NULL) {
  10709. ptimage = tex->get_ram_mipmap_image(n);
  10710. if (ptimage.is_null()) {
  10711. if (n < num_ram_mipmap_levels) {
  10712. // We were told we'd have this many RAM mipmap images, but we
  10713. // don't. Raise a warning.
  10714. GLCAT.warning()
  10715. << "No mipmap level " << n << " defined for " << tex->get_name()
  10716. << "\n";
  10717. if (_supports_texture_max_level) {
  10718. // Tell the GL we have no more mipmaps for it to use.
  10719. glTexParameteri(texture_target, GL_TEXTURE_MAX_LEVEL, n - mipmap_bias);
  10720. }
  10721. break;
  10722. }
  10723. if (tex->has_clear_color()) {
  10724. // Ask the Texture class to create the mipmap level in RAM. It'll
  10725. // fill it in with the correct clear color, which we can then
  10726. // upload.
  10727. ptimage = tex->make_ram_mipmap_image(n);
  10728. }
  10729. }
  10730. image_ptr = ptimage;
  10731. }
  10732. PTA_uchar bgr_image;
  10733. size_t view_size = tex->get_ram_mipmap_view_size(n);
  10734. if (image_ptr != (const unsigned char *)NULL) {
  10735. const unsigned char *orig_image_ptr = image_ptr;
  10736. image_ptr += view_size * gtc->get_view();
  10737. if (one_page_only) {
  10738. view_size = tex->get_ram_mipmap_page_size(n);
  10739. image_ptr += view_size * z;
  10740. }
  10741. nassertr(image_ptr >= orig_image_ptr && image_ptr + view_size <= orig_image_ptr + tex->get_ram_mipmap_image_size(n), false);
  10742. if (image_compression == Texture::CM_off) {
  10743. // If the GL doesn't claim to support BGR, we may have to reverse
  10744. // the component ordering of the image.
  10745. image_ptr = fix_component_ordering(bgr_image, image_ptr, view_size,
  10746. external_format, tex);
  10747. }
  10748. }
  10749. int width = tex->get_expected_mipmap_x_size(n);
  10750. int height = tex->get_expected_mipmap_y_size(n);
  10751. int depth = tex->get_expected_mipmap_z_size(n);
  10752. #ifdef DO_PSTATS
  10753. _data_transferred_pcollector.add_level(view_size);
  10754. #endif
  10755. switch (texture_target) {
  10756. #ifndef OPENGLES // 1-d textures not supported by OpenGL ES. Fall through.
  10757. case GL_TEXTURE_1D:
  10758. if (image_compression == Texture::CM_off) {
  10759. glTexImage1D(page_target, n - mipmap_bias, internal_format,
  10760. width, 0,
  10761. external_format, component_type, image_ptr);
  10762. } else {
  10763. _glCompressedTexImage1D(page_target, n - mipmap_bias, external_format, width,
  10764. 0, view_size, image_ptr);
  10765. }
  10766. break;
  10767. #endif // OPENGLES // OpenGL ES will fall through.
  10768. #ifndef OPENGLES_1
  10769. case GL_TEXTURE_3D:
  10770. if (_supports_3d_texture) {
  10771. if (image_compression == Texture::CM_off) {
  10772. _glTexImage3D(page_target, n - mipmap_bias, internal_format,
  10773. width, height, depth, 0,
  10774. external_format, component_type, image_ptr);
  10775. } else {
  10776. _glCompressedTexImage3D(page_target, n - mipmap_bias, external_format, width,
  10777. height, depth,
  10778. 0, view_size, image_ptr);
  10779. }
  10780. } else {
  10781. report_my_gl_errors();
  10782. return false;
  10783. }
  10784. break;
  10785. #endif // OPENGLES_1
  10786. #ifndef OPENGLES_1
  10787. case GL_TEXTURE_2D_ARRAY:
  10788. case GL_TEXTURE_CUBE_MAP_ARRAY:
  10789. if (_supports_2d_texture_array) {
  10790. if (image_compression == Texture::CM_off) {
  10791. _glTexImage3D(page_target, n - mipmap_bias, internal_format,
  10792. width, height, depth, 0,
  10793. external_format, component_type, image_ptr);
  10794. } else {
  10795. _glCompressedTexImage3D(page_target, n - mipmap_bias, external_format, width,
  10796. height, depth,
  10797. 0, view_size, image_ptr);
  10798. }
  10799. } else {
  10800. report_my_gl_errors();
  10801. return false;
  10802. }
  10803. break;
  10804. #endif // OPENGLES_1
  10805. #ifndef OPENGLES
  10806. case GL_TEXTURE_BUFFER:
  10807. if (_supports_buffer_texture) {
  10808. _glBufferData(GL_TEXTURE_BUFFER, view_size, image_ptr,
  10809. get_usage(tex->get_usage_hint()));
  10810. } else {
  10811. report_my_gl_errors();
  10812. return false;
  10813. }
  10814. break;
  10815. #endif // OPENGLES
  10816. default:
  10817. if (image_compression == Texture::CM_off) {
  10818. glTexImage2D(page_target, n - mipmap_bias, internal_format,
  10819. width, height, 0,
  10820. external_format, component_type, image_ptr);
  10821. } else {
  10822. _glCompressedTexImage2D(page_target, n - mipmap_bias, external_format,
  10823. width, height, 0, view_size, image_ptr);
  10824. }
  10825. }
  10826. }
  10827. // Report the error message explicitly if the GL texture creation failed.
  10828. GLenum error_code = gl_get_error();
  10829. if (error_code != GL_NO_ERROR) {
  10830. GLCAT.error()
  10831. << "GL texture creation failed for " << tex->get_name()
  10832. << " : " << get_error_string(error_code) << "\n";
  10833. gtc->_has_storage = false;
  10834. return false;
  10835. }
  10836. }
  10837. report_my_gl_errors();
  10838. return true;
  10839. }
  10840. /**
  10841. * Causes mipmaps to be generated for an uploaded texture.
  10842. */
  10843. void CLP(GraphicsStateGuardian)::
  10844. generate_mipmaps(CLP(TextureContext) *gtc) {
  10845. #ifndef OPENGLES
  10846. if (_glGenerateTextureMipmap != NULL) {
  10847. // OpenGL 4.5 offers an easy way to do this without binding.
  10848. _glGenerateTextureMipmap(gtc->_index);
  10849. return;
  10850. }
  10851. #endif
  10852. if (_glGenerateMipmap != NULL) {
  10853. _state_texture = 0;
  10854. update_texture(gtc, true);
  10855. apply_texture(gtc);
  10856. _glGenerateMipmap(gtc->_target);
  10857. glBindTexture(gtc->_target, 0);
  10858. }
  10859. }
  10860. /**
  10861. * This is used as a standin for upload_texture when the texture in question
  10862. * is unavailable (e.g. it hasn't yet been loaded from disk). Until the
  10863. * texture image itself becomes available, we will render the texture's
  10864. * "simple" image--a sharply reduced version of the same texture.
  10865. */
  10866. bool CLP(GraphicsStateGuardian)::
  10867. upload_simple_texture(CLP(TextureContext) *gtc) {
  10868. report_my_gl_errors();
  10869. PStatGPUTimer timer(this, _load_texture_pcollector);
  10870. Texture *tex = gtc->get_texture();
  10871. nassertr(tex != (Texture *)NULL, false);
  10872. GLenum internal_format = GL_RGBA;
  10873. GLenum external_format = GL_BGRA;
  10874. const unsigned char *image_ptr = tex->get_simple_ram_image();
  10875. if (image_ptr == (const unsigned char *)NULL) {
  10876. return false;
  10877. }
  10878. size_t image_size = tex->get_simple_ram_image_size();
  10879. PTA_uchar bgr_image;
  10880. if (!_supports_bgr) {
  10881. // If the GL doesn't claim to support BGR, we may have to reverse the
  10882. // component ordering of the image.
  10883. external_format = GL_RGBA;
  10884. image_ptr = fix_component_ordering(bgr_image, image_ptr, image_size,
  10885. external_format, tex);
  10886. }
  10887. int width = tex->get_simple_x_size();
  10888. int height = tex->get_simple_y_size();
  10889. GLenum component_type = GL_UNSIGNED_BYTE;
  10890. if (GLCAT.is_debug()) {
  10891. GLCAT.debug()
  10892. << "loading simple image for " << tex->get_name() << "\n";
  10893. }
  10894. // Turn off mipmaps for the simple texture.
  10895. if (tex->uses_mipmaps() && _supports_texture_max_level) {
  10896. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
  10897. }
  10898. #ifdef DO_PSTATS
  10899. _data_transferred_pcollector.add_level(image_size);
  10900. #endif
  10901. glTexImage2D(GL_TEXTURE_2D, 0, internal_format,
  10902. width, height, 0,
  10903. external_format, component_type, image_ptr);
  10904. gtc->mark_simple_loaded();
  10905. report_my_gl_errors();
  10906. return true;
  10907. }
  10908. /**
  10909. * Asks OpenGL how much texture memory is consumed by the indicated texture
  10910. * (which is also the currently-selected texture).
  10911. */
  10912. size_t CLP(GraphicsStateGuardian)::
  10913. get_texture_memory_size(CLP(TextureContext) *gtc) {
  10914. Texture *tex = gtc->get_texture();
  10915. #ifdef OPENGLES // Texture querying not supported on OpenGL ES.
  10916. int width = tex->get_x_size();
  10917. int height = tex->get_y_size();
  10918. int depth = 1;
  10919. int scale = 1;
  10920. bool has_mipmaps = tex->uses_mipmaps();
  10921. size_t num_bytes = 2; // Temporary assumption?
  10922. #else
  10923. GLenum target = get_texture_target(tex->get_texture_type());
  10924. GLenum page_target = target;
  10925. GLint scale = 1;
  10926. if (target == GL_TEXTURE_CUBE_MAP) {
  10927. // We need a particular page to get the level parameter from.
  10928. page_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
  10929. scale = 6;
  10930. } else if (target == GL_TEXTURE_BUFFER) {
  10931. // In the case of buffer textures, we provided the size to begin with, so
  10932. // no point in querying anything. Plus, glGetTexParameter is not even
  10933. // supported for buffer textures.
  10934. return tex->get_expected_ram_image_size();
  10935. }
  10936. clear_my_gl_errors();
  10937. GLint internal_format;
  10938. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_INTERNAL_FORMAT, &internal_format);
  10939. if (is_compressed_format(internal_format)) {
  10940. // Try to get the compressed size.
  10941. GLint image_size;
  10942. glGetTexLevelParameteriv(page_target, 0,
  10943. GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &image_size);
  10944. GLenum error_code = gl_get_error();
  10945. if (error_code != GL_NO_ERROR) {
  10946. if (GLCAT.is_debug()) {
  10947. GLCAT.debug()
  10948. << "Couldn't get compressed size for " << tex->get_name()
  10949. << " : " << get_error_string(error_code) << "\n";
  10950. }
  10951. // Fall through to the noncompressed case.
  10952. } else {
  10953. return image_size * scale;
  10954. }
  10955. }
  10956. // OK, get the noncompressed size.
  10957. GLint red_size, green_size, blue_size, alpha_size,
  10958. luminance_size, intensity_size;
  10959. GLint depth_size = 0;
  10960. glGetTexLevelParameteriv(page_target, 0,
  10961. GL_TEXTURE_RED_SIZE, &red_size);
  10962. glGetTexLevelParameteriv(page_target, 0,
  10963. GL_TEXTURE_GREEN_SIZE, &green_size);
  10964. glGetTexLevelParameteriv(page_target, 0,
  10965. GL_TEXTURE_BLUE_SIZE, &blue_size);
  10966. glGetTexLevelParameteriv(page_target, 0,
  10967. GL_TEXTURE_ALPHA_SIZE, &alpha_size);
  10968. glGetTexLevelParameteriv(page_target, 0,
  10969. GL_TEXTURE_LUMINANCE_SIZE, &luminance_size);
  10970. glGetTexLevelParameteriv(page_target, 0,
  10971. GL_TEXTURE_INTENSITY_SIZE, &intensity_size);
  10972. if (_supports_depth_texture) {
  10973. glGetTexLevelParameteriv(page_target, 0,
  10974. GL_TEXTURE_DEPTH_SIZE, &depth_size);
  10975. }
  10976. GLint width = 1, height = 1, depth = 1;
  10977. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_WIDTH, &width);
  10978. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_HEIGHT, &height);
  10979. if (_supports_3d_texture || _supports_2d_texture_array) {
  10980. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_DEPTH, &depth);
  10981. }
  10982. report_my_gl_errors();
  10983. size_t num_bits = (red_size + green_size + blue_size + alpha_size + luminance_size + intensity_size + depth_size);
  10984. size_t num_bytes = (num_bits + 7) / 8;
  10985. #endif // OPENGLES
  10986. size_t result = num_bytes * width * height * depth * scale;
  10987. if (gtc->_uses_mipmaps) {
  10988. result = (result * 4) / 3;
  10989. }
  10990. return result;
  10991. }
  10992. /**
  10993. * Checks the list of resident texture objects to see if any have recently
  10994. * been evicted.
  10995. */
  10996. void CLP(GraphicsStateGuardian)::
  10997. check_nonresident_texture(BufferContextChain &chain) {
  10998. #if defined(SUPPORT_FIXED_FUNCTION) && !defined(OPENGLES) // Residency queries not supported by OpenGL ES.
  10999. size_t num_textures = chain.get_count();
  11000. if (num_textures == 0) {
  11001. return;
  11002. }
  11003. CLP(TextureContext) **gtc_list = (CLP(TextureContext) **)alloca(num_textures * sizeof(CLP(TextureContext) *));
  11004. GLuint *texture_list = (GLuint *)alloca(num_textures * sizeof(GLuint));
  11005. size_t ti = 0;
  11006. BufferContext *node = chain.get_first();
  11007. while (node != (BufferContext *)NULL) {
  11008. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), node);
  11009. gtc_list[ti] = gtc;
  11010. texture_list[ti] = gtc->_index;
  11011. node = node->get_next();
  11012. ++ti;
  11013. }
  11014. nassertv(ti == num_textures);
  11015. GLboolean *results = (GLboolean *)alloca(num_textures * sizeof(GLboolean));
  11016. bool all_resident = (glAreTexturesResident(num_textures, texture_list, results) != 0);
  11017. report_my_gl_errors();
  11018. if (!all_resident) {
  11019. // Some are now nonresident.
  11020. for (ti = 0; ti < num_textures; ++ti) {
  11021. if (!results[ti]) {
  11022. gtc_list[ti]->set_resident(false);
  11023. }
  11024. }
  11025. }
  11026. #endif // OPENGLES
  11027. }
  11028. /**
  11029. * The internal implementation of extract_texture_data(), given an already-
  11030. * created TextureContext.
  11031. */
  11032. bool CLP(GraphicsStateGuardian)::
  11033. do_extract_texture_data(CLP(TextureContext) *gtc) {
  11034. report_my_gl_errors();
  11035. GLenum target = gtc->_target;
  11036. if (target == GL_NONE) {
  11037. return false;
  11038. }
  11039. #ifndef OPENGLES_1
  11040. // Make sure any incoherent writes to the texture have been synced.
  11041. if (gtc->needs_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT)) {
  11042. issue_memory_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
  11043. }
  11044. #endif
  11045. glBindTexture(target, gtc->_index);
  11046. if (GLCAT.is_spam()) {
  11047. GLCAT.spam()
  11048. << "glBindTexture(0x" << hex << target << dec << ", " << gtc->_index << ")\n";
  11049. }
  11050. Texture *tex = gtc->get_texture();
  11051. GLint wrap_u, wrap_v, wrap_w;
  11052. GLint minfilter, magfilter;
  11053. GLfloat border_color[4];
  11054. glGetTexParameteriv(target, GL_TEXTURE_WRAP_S, &wrap_u);
  11055. glGetTexParameteriv(target, GL_TEXTURE_WRAP_T, &wrap_v);
  11056. wrap_w = GL_REPEAT;
  11057. #ifndef OPENGLES_1
  11058. if (_supports_3d_texture) {
  11059. glGetTexParameteriv(target, GL_TEXTURE_WRAP_R, &wrap_w);
  11060. }
  11061. #endif
  11062. glGetTexParameteriv(target, GL_TEXTURE_MIN_FILTER, &minfilter);
  11063. glGetTexParameteriv(target, GL_TEXTURE_MAG_FILTER, &magfilter);
  11064. #ifndef OPENGLES
  11065. glGetTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, border_color);
  11066. #endif
  11067. GLenum page_target = target;
  11068. if (target == GL_TEXTURE_CUBE_MAP) {
  11069. // We need a particular page to get the level parameter from.
  11070. page_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
  11071. }
  11072. GLint width = gtc->_width, height = gtc->_height, depth = gtc->_depth;
  11073. #ifndef OPENGLES
  11074. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_WIDTH, &width);
  11075. if (target != GL_TEXTURE_1D) {
  11076. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_HEIGHT, &height);
  11077. }
  11078. if (_supports_3d_texture && target == GL_TEXTURE_3D) {
  11079. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_DEPTH, &depth);
  11080. } else if (target == GL_TEXTURE_2D_ARRAY || target == GL_TEXTURE_CUBE_MAP_ARRAY) {
  11081. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_DEPTH, &depth);
  11082. } else if (target == GL_TEXTURE_CUBE_MAP) {
  11083. depth = 6;
  11084. }
  11085. #endif
  11086. clear_my_gl_errors();
  11087. if (width <= 0 || height <= 0 || depth <= 0) {
  11088. GLCAT.error()
  11089. << "No texture data for " << tex->get_name() << "\n";
  11090. return false;
  11091. }
  11092. GLint internal_format = GL_RGBA;
  11093. #ifndef OPENGLES
  11094. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_INTERNAL_FORMAT, &internal_format);
  11095. #endif // OPENGLES
  11096. // Make sure we were able to query those parameters properly.
  11097. GLenum error_code = gl_get_error();
  11098. if (error_code != GL_NO_ERROR) {
  11099. GLCAT.error()
  11100. << "Unable to query texture parameters for " << tex->get_name()
  11101. << " : " << get_error_string(error_code) << "\n";
  11102. return false;
  11103. }
  11104. Texture::ComponentType type = Texture::T_unsigned_byte;
  11105. Texture::Format format = Texture::F_rgb;
  11106. Texture::CompressionMode compression = Texture::CM_off;
  11107. switch (internal_format) {
  11108. #ifndef OPENGLES
  11109. case GL_COLOR_INDEX:
  11110. format = Texture::F_color_index;
  11111. break;
  11112. #endif
  11113. #if GL_DEPTH_COMPONENT != GL_DEPTH_COMPONENT24
  11114. case GL_DEPTH_COMPONENT:
  11115. #endif
  11116. case GL_DEPTH_COMPONENT16:
  11117. case GL_DEPTH_COMPONENT24:
  11118. case GL_DEPTH_COMPONENT32:
  11119. type = Texture::T_unsigned_short;
  11120. format = Texture::F_depth_component;
  11121. break;
  11122. #ifndef OPENGLES
  11123. case GL_DEPTH_COMPONENT32F:
  11124. type = Texture::T_float;
  11125. format = Texture::F_depth_component;
  11126. break;
  11127. #endif
  11128. case GL_DEPTH_STENCIL:
  11129. case GL_DEPTH24_STENCIL8:
  11130. type = Texture::T_unsigned_int_24_8;
  11131. format = Texture::F_depth_stencil;
  11132. break;
  11133. #ifndef OPENGLES
  11134. case GL_DEPTH32F_STENCIL8:
  11135. type = Texture::T_float;
  11136. format = Texture::F_depth_stencil;
  11137. break;
  11138. #endif
  11139. case GL_RGBA:
  11140. case 4:
  11141. format = Texture::F_rgba;
  11142. break;
  11143. case GL_RGBA4:
  11144. format = Texture::F_rgba4;
  11145. break;
  11146. #ifdef OPENGLES
  11147. case GL_RGBA8_OES:
  11148. format = Texture::F_rgba8;
  11149. break;
  11150. #else
  11151. case GL_RGBA8:
  11152. format = Texture::F_rgba8;
  11153. break;
  11154. #endif
  11155. #ifndef OPENGLES
  11156. case GL_RGBA12:
  11157. type = Texture::T_unsigned_short;
  11158. format = Texture::F_rgba12;
  11159. break;
  11160. #endif
  11161. case GL_RGB:
  11162. case 3:
  11163. format = Texture::F_rgb;
  11164. break;
  11165. #ifndef OPENGLES
  11166. case GL_RGB5:
  11167. format = Texture::F_rgb5;
  11168. break;
  11169. #endif
  11170. case GL_RGB5_A1:
  11171. format = Texture::F_rgba5;
  11172. break;
  11173. #ifndef OPENGLES
  11174. case GL_RGB8:
  11175. format = Texture::F_rgb8;
  11176. break;
  11177. case GL_RGB12:
  11178. format = Texture::F_rgb12;
  11179. break;
  11180. case GL_RGBA16:
  11181. format = Texture::F_rgba16;
  11182. break;
  11183. case GL_R3_G3_B2:
  11184. format = Texture::F_rgb332;
  11185. break;
  11186. case GL_R8I:
  11187. type = Texture::T_byte;
  11188. format = Texture::F_r8i;
  11189. break;
  11190. case GL_RG8I:
  11191. type = Texture::T_byte;
  11192. format = Texture::F_rg8i;
  11193. break;
  11194. case GL_RGB8I:
  11195. type = Texture::T_byte;
  11196. format = Texture::F_rgb8i;
  11197. break;
  11198. case GL_RGBA8I:
  11199. type = Texture::T_byte;
  11200. format = Texture::F_rgba8i;
  11201. break;
  11202. case GL_R8UI:
  11203. type = Texture::T_unsigned_byte;
  11204. format = Texture::F_r8i;
  11205. break;
  11206. case GL_RG8UI:
  11207. type = Texture::T_unsigned_byte;
  11208. format = Texture::F_rg8i;
  11209. break;
  11210. case GL_RGB8UI:
  11211. type = Texture::T_unsigned_byte;
  11212. format = Texture::F_rgb8i;
  11213. break;
  11214. case GL_RGBA8UI:
  11215. type = Texture::T_unsigned_byte;
  11216. format = Texture::F_rgba8i;
  11217. break;
  11218. case GL_R16I:
  11219. type = Texture::T_short;
  11220. format = Texture::F_r16i;
  11221. break;
  11222. case GL_R16UI:
  11223. type = Texture::T_unsigned_short;
  11224. format = Texture::F_r16i;
  11225. break;
  11226. #endif
  11227. #ifndef OPENGLES_1
  11228. case GL_RGBA16F:
  11229. type = Texture::T_float;
  11230. format = Texture::F_rgba16;
  11231. break;
  11232. case GL_RGB16F:
  11233. type = Texture::T_float;
  11234. format = Texture::F_rgb16;
  11235. break;
  11236. case GL_RG16F:
  11237. type = Texture::T_float;
  11238. format = Texture::F_rg16;
  11239. break;
  11240. case GL_R16F:
  11241. type = Texture::T_float;
  11242. format = Texture::F_r16;
  11243. break;
  11244. case GL_RGBA32F:
  11245. type = Texture::T_float;
  11246. format = Texture::F_rgba32;
  11247. break;
  11248. case GL_RGB32F:
  11249. type = Texture::T_float;
  11250. format = Texture::F_rgb32;
  11251. break;
  11252. case GL_RG32F:
  11253. type = Texture::T_float;
  11254. format = Texture::F_rg32;
  11255. break;
  11256. case GL_R32F:
  11257. type = Texture::T_float;
  11258. format = Texture::F_r32;
  11259. break;
  11260. #endif
  11261. #ifndef OPENGLES
  11262. case GL_RGB16:
  11263. type = Texture::T_unsigned_short;
  11264. format = Texture::F_rgb16;
  11265. break;
  11266. case GL_RG16:
  11267. type = Texture::T_unsigned_short;
  11268. format = Texture::F_rg16;
  11269. break;
  11270. case GL_R16:
  11271. type = Texture::T_unsigned_short;
  11272. format = Texture::F_r16;
  11273. break;
  11274. case GL_RGB16_SNORM:
  11275. type = Texture::T_short;
  11276. format = Texture::F_rgb16;
  11277. break;
  11278. case GL_RG16_SNORM:
  11279. type = Texture::T_short;
  11280. format = Texture::F_rg16;
  11281. break;
  11282. case GL_R16_SNORM:
  11283. type = Texture::T_short;
  11284. format = Texture::F_r16;
  11285. break;
  11286. #endif
  11287. #ifndef OPENGLES_1
  11288. case GL_R11F_G11F_B10F:
  11289. type = Texture::T_float;
  11290. format = Texture::F_r11_g11_b10;
  11291. break;
  11292. case GL_RGB9_E5:
  11293. type = Texture::T_float;
  11294. format = Texture::F_rgb9_e5;
  11295. break;
  11296. case GL_RGB10_A2:
  11297. type = Texture::T_unsigned_short;
  11298. format = Texture::F_rgb10_a2;
  11299. break;
  11300. #endif
  11301. #ifdef OPENGLES_2
  11302. case GL_RED_EXT:
  11303. case GL_R8_EXT:
  11304. format = Texture::F_red;
  11305. break;
  11306. #endif
  11307. #ifndef OPENGLES
  11308. case GL_R32I:
  11309. type = Texture::T_int;
  11310. format = Texture::F_r32i;
  11311. break;
  11312. #endif
  11313. #ifndef OPENGLES
  11314. case GL_RED:
  11315. format = Texture::F_red;
  11316. break;
  11317. case GL_GREEN:
  11318. format = Texture::F_green;
  11319. break;
  11320. case GL_BLUE:
  11321. format = Texture::F_blue;
  11322. break;
  11323. #endif // OPENGLES
  11324. case GL_ALPHA:
  11325. format = Texture::F_alpha;
  11326. break;
  11327. case GL_LUMINANCE:
  11328. #ifndef OPENGLES
  11329. case GL_LUMINANCE16:
  11330. case GL_LUMINANCE16F_ARB:
  11331. #endif
  11332. case 1:
  11333. format = Texture::F_luminance;
  11334. break;
  11335. case GL_LUMINANCE_ALPHA:
  11336. #ifndef OPENGLES
  11337. case GL_LUMINANCE_ALPHA16F_ARB:
  11338. #endif
  11339. case 2:
  11340. format = Texture::F_luminance_alpha;
  11341. break;
  11342. #ifndef OPENGLES_1
  11343. case GL_SRGB:
  11344. #ifndef OPENGLES
  11345. case GL_SRGB8:
  11346. #endif
  11347. format = Texture::F_srgb;
  11348. break;
  11349. case GL_SRGB_ALPHA:
  11350. case GL_SRGB8_ALPHA8:
  11351. format = Texture::F_srgb_alpha;
  11352. break;
  11353. #endif // OPENGLES_1
  11354. #ifndef OPENGLES
  11355. case GL_SLUMINANCE:
  11356. case GL_SLUMINANCE8:
  11357. format = Texture::F_sluminance;
  11358. break;
  11359. case GL_SLUMINANCE_ALPHA:
  11360. case GL_SLUMINANCE8_ALPHA8:
  11361. format = Texture::F_sluminance_alpha;
  11362. break;
  11363. #endif // OPENGLES
  11364. #ifndef OPENGLES
  11365. case GL_COMPRESSED_RGB:
  11366. format = Texture::F_rgb;
  11367. compression = Texture::CM_on;
  11368. break;
  11369. case GL_COMPRESSED_RGBA:
  11370. format = Texture::F_rgba;
  11371. compression = Texture::CM_on;
  11372. break;
  11373. case GL_COMPRESSED_ALPHA:
  11374. format = Texture::F_alpha;
  11375. compression = Texture::CM_on;
  11376. break;
  11377. case GL_COMPRESSED_LUMINANCE:
  11378. format = Texture::F_luminance;
  11379. compression = Texture::CM_on;
  11380. break;
  11381. case GL_COMPRESSED_LUMINANCE_ALPHA:
  11382. format = Texture::F_luminance_alpha;
  11383. compression = Texture::CM_on;
  11384. break;
  11385. case GL_COMPRESSED_SRGB:
  11386. format = Texture::F_srgb;
  11387. compression = Texture::CM_on;
  11388. break;
  11389. case GL_COMPRESSED_SRGB_ALPHA:
  11390. format = Texture::F_srgb_alpha;
  11391. compression = Texture::CM_on;
  11392. break;
  11393. case GL_COMPRESSED_SLUMINANCE:
  11394. format = Texture::F_sluminance;
  11395. compression = Texture::CM_on;
  11396. break;
  11397. case GL_COMPRESSED_SLUMINANCE_ALPHA:
  11398. format = Texture::F_sluminance_alpha;
  11399. compression = Texture::CM_on;
  11400. break;
  11401. #endif
  11402. case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  11403. format = Texture::F_rgb;
  11404. compression = Texture::CM_dxt1;
  11405. break;
  11406. case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  11407. format = Texture::F_rgbm;
  11408. compression = Texture::CM_dxt1;
  11409. break;
  11410. #ifndef OPENGLES
  11411. case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
  11412. format = Texture::F_srgb;
  11413. compression = Texture::CM_dxt1;
  11414. break;
  11415. case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
  11416. format = Texture::F_srgb_alpha;
  11417. compression = Texture::CM_dxt1;
  11418. break;
  11419. #endif
  11420. #ifdef OPENGLES
  11421. case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
  11422. format = Texture::F_rgb;
  11423. compression = Texture::CM_pvr1_2bpp;
  11424. break;
  11425. case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
  11426. format = Texture::F_rgba;
  11427. compression = Texture::CM_pvr1_2bpp;
  11428. break;
  11429. case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
  11430. format = Texture::F_rgb;
  11431. compression = Texture::CM_pvr1_4bpp;
  11432. break;
  11433. case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
  11434. format = Texture::F_rgba;
  11435. compression = Texture::CM_pvr1_4bpp;
  11436. break;
  11437. #else
  11438. case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
  11439. format = Texture::F_rgba;
  11440. compression = Texture::CM_dxt3;
  11441. break;
  11442. case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
  11443. format = Texture::F_rgba;
  11444. compression = Texture::CM_dxt5;
  11445. break;
  11446. case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
  11447. format = Texture::F_srgb_alpha;
  11448. compression = Texture::CM_dxt3;
  11449. break;
  11450. case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
  11451. format = Texture::F_srgb_alpha;
  11452. compression = Texture::CM_dxt5;
  11453. break;
  11454. case GL_COMPRESSED_RGB_FXT1_3DFX:
  11455. format = Texture::F_rgb;
  11456. compression = Texture::CM_fxt1;
  11457. break;
  11458. case GL_COMPRESSED_RGBA_FXT1_3DFX:
  11459. format = Texture::F_rgba;
  11460. compression = Texture::CM_fxt1;
  11461. break;
  11462. case GL_COMPRESSED_LUMINANCE_LATC1_EXT:
  11463. format = Texture::F_luminance;
  11464. compression = Texture::CM_rgtc;
  11465. break;
  11466. case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT:
  11467. format = Texture::F_luminance_alpha;
  11468. compression = Texture::CM_rgtc;
  11469. break;
  11470. case GL_COMPRESSED_RED_RGTC1:
  11471. format = Texture::F_red;
  11472. compression = Texture::CM_rgtc;
  11473. break;
  11474. case GL_COMPRESSED_SIGNED_RED_RGTC1:
  11475. type = Texture::T_byte;
  11476. format = Texture::F_red;
  11477. compression = Texture::CM_rgtc;
  11478. break;
  11479. case GL_COMPRESSED_RG_RGTC2:
  11480. format = Texture::F_rg;
  11481. compression = Texture::CM_rgtc;
  11482. break;
  11483. case GL_COMPRESSED_SIGNED_RG_RGTC2:
  11484. type = Texture::T_byte;
  11485. format = Texture::F_rg;
  11486. compression = Texture::CM_rgtc;
  11487. break;
  11488. #endif
  11489. default:
  11490. GLCAT.warning()
  11491. << "Unhandled internal format for " << tex->get_name()
  11492. << " : " << hex << "0x" << internal_format << dec << "\n";
  11493. return false;
  11494. }
  11495. // We don't want to call setup_texture() again; that resets too much.
  11496. // Instead, we'll just set the individual components.
  11497. tex->set_x_size(width);
  11498. tex->set_y_size(height);
  11499. tex->set_z_size(depth);
  11500. tex->set_component_type(type);
  11501. tex->set_format(format);
  11502. tex->set_wrap_u(get_panda_wrap_mode(wrap_u));
  11503. tex->set_wrap_v(get_panda_wrap_mode(wrap_v));
  11504. tex->set_wrap_w(get_panda_wrap_mode(wrap_w));
  11505. tex->set_border_color(LColor(border_color[0], border_color[1],
  11506. border_color[2], border_color[3]));
  11507. tex->set_minfilter(get_panda_filter_type(minfilter));
  11508. // tex->set_magfilter(get_panda_filter_type(magfilter));
  11509. PTA_uchar image;
  11510. size_t page_size = 0;
  11511. if (!extract_texture_image(image, page_size, tex, target, page_target,
  11512. type, compression, 0)) {
  11513. return false;
  11514. }
  11515. tex->set_ram_image(image, compression, page_size);
  11516. if (gtc->_uses_mipmaps) {
  11517. // Also get the mipmap levels.
  11518. GLint num_expected_levels = tex->get_expected_num_mipmap_levels();
  11519. GLint highest_level = num_expected_levels;
  11520. if (_supports_texture_max_level) {
  11521. glGetTexParameteriv(target, GL_TEXTURE_MAX_LEVEL, &highest_level);
  11522. highest_level = min(highest_level, num_expected_levels);
  11523. }
  11524. for (int n = 1; n <= highest_level; ++n) {
  11525. if (!extract_texture_image(image, page_size, tex, target, page_target,
  11526. type, compression, n)) {
  11527. return false;
  11528. }
  11529. tex->set_ram_mipmap_image(n, image, page_size);
  11530. }
  11531. }
  11532. return true;
  11533. }
  11534. /**
  11535. * Called from extract_texture_data(), this gets just the image array for a
  11536. * particular mipmap level (or for the base image).
  11537. */
  11538. bool CLP(GraphicsStateGuardian)::
  11539. extract_texture_image(PTA_uchar &image, size_t &page_size,
  11540. Texture *tex, GLenum target, GLenum page_target,
  11541. Texture::ComponentType type,
  11542. Texture::CompressionMode compression, int n) {
  11543. #ifdef OPENGLES // Extracting texture data unsupported in OpenGL ES.
  11544. nassertr(false, false);
  11545. return false;
  11546. #else
  11547. // Make sure the GL driver does not align textures, otherwise we get corrupt
  11548. // memory, since we don't take alignment into account.
  11549. glPixelStorei(GL_PACK_ALIGNMENT, 1);
  11550. if (target == GL_TEXTURE_CUBE_MAP) {
  11551. // A cube map, compressed or uncompressed. This we must extract one page
  11552. // at a time.
  11553. // If the cube map is compressed, we assume that all the compressed pages
  11554. // are exactly the same size. OpenGL doesn't make this assumption, but it
  11555. // happens to be true for all currently extant compression schemes, and it
  11556. // makes things simpler for us. (It also makes things much simpler for
  11557. // the graphics hardware, so it's likely to continue to be true for a
  11558. // while at least.)
  11559. GLenum external_format = get_external_image_format(tex);
  11560. GLenum pixel_type = get_component_type(type);
  11561. page_size = tex->get_expected_ram_mipmap_page_size(n);
  11562. if (compression != Texture::CM_off) {
  11563. GLint image_size;
  11564. glGetTexLevelParameteriv(page_target, n,
  11565. GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &image_size);
  11566. nassertr(image_size <= (int)page_size, false);
  11567. page_size = image_size;
  11568. }
  11569. image = PTA_uchar::empty_array(page_size * 6);
  11570. for (int z = 0; z < 6; ++z) {
  11571. page_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + z;
  11572. if (compression == Texture::CM_off) {
  11573. glGetTexImage(page_target, n, external_format, pixel_type,
  11574. image.p() + z * page_size);
  11575. } else {
  11576. _glGetCompressedTexImage(page_target, 0, image.p() + z * page_size);
  11577. }
  11578. }
  11579. } else if (compression == Texture::CM_off) {
  11580. // An uncompressed 1-d, 2-d, or 3-d texture.
  11581. image = PTA_uchar::empty_array(tex->get_expected_ram_mipmap_image_size(n));
  11582. GLenum external_format = get_external_image_format(tex);
  11583. GLenum pixel_type = get_component_type(type);
  11584. glGetTexImage(target, n, external_format, pixel_type, image.p());
  11585. } else {
  11586. // A compressed 1-d, 2-d, or 3-d texture.
  11587. GLint image_size;
  11588. glGetTexLevelParameteriv(target, n, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &image_size);
  11589. page_size = image_size / tex->get_z_size();
  11590. image = PTA_uchar::empty_array(image_size);
  11591. // Some drivers (ATI!) seem to try to overstuff more bytes in the array
  11592. // than they asked us to allocate (that is, more bytes than
  11593. // GL_TEXTURE_COMPRESSED_IMAGE_SIZE), requiring us to overallocate and
  11594. // then copy the result into our final buffer. Sheesh.
  11595. // We'll only do this for small textures (the ATI bug doesn't *seem* to
  11596. // affect large textures), to save on the overhead of the double-copy, and
  11597. // reduce risk from an overly-large alloca().
  11598. #ifndef NDEBUG
  11599. static const int max_trouble_buffer = 102400;
  11600. #else
  11601. static const int max_trouble_buffer = 1024;
  11602. #endif
  11603. if (image_size < max_trouble_buffer) {
  11604. static const int extra_space = 32;
  11605. unsigned char *buffer = (unsigned char *)alloca(image_size + extra_space);
  11606. #ifndef NDEBUG
  11607. // Tag the buffer with a specific byte so we can report on whether that
  11608. // driver bug is still active.
  11609. static unsigned char keep_token = 0x00;
  11610. unsigned char token = ++keep_token;
  11611. memset(buffer + image_size, token, extra_space);
  11612. #endif
  11613. _glGetCompressedTexImage(target, n, buffer);
  11614. memcpy(image.p(), buffer, image_size);
  11615. #ifndef NDEBUG
  11616. int count = extra_space;
  11617. while (count > 0 && buffer[image_size + count - 1] == token) {
  11618. --count;
  11619. }
  11620. if (count != 0) {
  11621. GLCAT.warning()
  11622. << "GL graphics driver overfilled " << count
  11623. << " bytes into a " << image_size
  11624. << "-byte buffer provided to glGetCompressedTexImage()\n";
  11625. }
  11626. // This had better not equal the amount of buffer space we set aside.
  11627. // If it does, we assume the driver might have overfilled even our
  11628. // provided extra buffer.
  11629. nassertr(count != extra_space, true)
  11630. #endif // NDEBUG
  11631. } else {
  11632. _glGetCompressedTexImage(target, n, image.p());
  11633. }
  11634. }
  11635. // Now see if we were successful.
  11636. GLenum error_code = gl_get_error();
  11637. if (error_code != GL_NO_ERROR) {
  11638. GLCAT.error()
  11639. << "Unable to extract texture for " << *tex
  11640. << ", mipmap level " << n
  11641. << " : " << get_error_string(error_code) << "\n";
  11642. nassertr(false, false);
  11643. return false;
  11644. }
  11645. return true;
  11646. #endif // OPENGLES
  11647. }
  11648. /**
  11649. * Internally sets the point size parameters after any of the properties have
  11650. * changed that might affect this.
  11651. */
  11652. #ifdef SUPPORT_FIXED_FUNCTION
  11653. void CLP(GraphicsStateGuardian)::
  11654. do_point_size() {
  11655. if (!_point_perspective) {
  11656. // Normal, constant-sized points. Here _point_size is a width in pixels.
  11657. static LVecBase3f constant(1.0f, 0.0f, 0.0f);
  11658. _glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, constant.get_data());
  11659. } else {
  11660. // Perspective-sized points. Here _point_size is a width in 3-d units.
  11661. // To arrange that, we need to figure out the appropriate scaling factor
  11662. // based on the current viewport and projection matrix.
  11663. LVector3 height(0.0f, _point_size, 1.0f);
  11664. height = height * _projection_mat->get_mat();
  11665. height = height * _internal_transform->get_scale()[1];
  11666. PN_stdfloat s = height[1] * _viewport_height / _point_size;
  11667. if (_current_lens->is_orthographic()) {
  11668. // If we have an orthographic lens in effect, we don't actually apply a
  11669. // perspective transform: we just scale the points once, regardless of
  11670. // the distance from the camera.
  11671. LVecBase3f constant(1.0f / (s * s), 0.0f, 0.0f);
  11672. _glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, constant.get_data());
  11673. } else {
  11674. // Otherwise, we give it a true perspective adjustment.
  11675. LVecBase3f square(0.0f, 0.0f, 1.0f / (s * s));
  11676. _glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, square.get_data());
  11677. }
  11678. }
  11679. report_my_gl_errors();
  11680. }
  11681. #endif
  11682. /**
  11683. * Returns true if this particular GSG supports the specified Cg Shader
  11684. * Profile.
  11685. */
  11686. bool CLP(GraphicsStateGuardian)::
  11687. get_supports_cg_profile(const string &name) const {
  11688. #if !defined(HAVE_CG) || defined(OPENGLES)
  11689. return false;
  11690. #else
  11691. CGprofile profile = cgGetProfile(name.c_str());
  11692. if (profile == CG_PROFILE_UNKNOWN) {
  11693. GLCAT.error() << name << ", unknown Cg-profile\n";
  11694. return false;
  11695. }
  11696. return (cgGLIsProfileSupported(profile) != 0);
  11697. #endif
  11698. }
  11699. /**
  11700. * Binds a framebuffer object.
  11701. */
  11702. void CLP(GraphicsStateGuardian)::
  11703. bind_fbo(GLuint fbo) {
  11704. if (_current_fbo == fbo) {
  11705. return;
  11706. }
  11707. PStatGPUTimer timer(this, _fbo_bind_pcollector);
  11708. nassertv(_glBindFramebuffer != 0);
  11709. #if defined(OPENGLES_2)
  11710. _glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  11711. #elif defined(OPENGLES_1)
  11712. _glBindFramebuffer(GL_FRAMEBUFFER_OES, fbo);
  11713. #else
  11714. _glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
  11715. #endif
  11716. _current_fbo = fbo;
  11717. }
  11718. // GL stencil code section
  11719. static int gl_stencil_operations_array[] = {
  11720. GL_KEEP,
  11721. GL_ZERO,
  11722. GL_REPLACE,
  11723. #ifdef OPENGLES_1
  11724. GL_INCR_WRAP_OES,
  11725. GL_DECR_WRAP_OES,
  11726. #else
  11727. GL_INCR_WRAP,
  11728. GL_DECR_WRAP,
  11729. #endif
  11730. GL_INVERT,
  11731. GL_INCR,
  11732. GL_DECR,
  11733. };
  11734. /**
  11735. * Set stencil render states.
  11736. */
  11737. void CLP(GraphicsStateGuardian)::
  11738. do_issue_stencil() {
  11739. if (!_supports_stencil) {
  11740. return;
  11741. }
  11742. const StencilAttrib *stencil;
  11743. if (_target_rs->get_attrib(stencil)) {
  11744. // DEBUG
  11745. if (false) {
  11746. GLCAT.debug() << "STENCIL STATE CHANGE\n";
  11747. GLCAT.debug() << "\n"
  11748. << "SRS_front_comparison_function " << (int)stencil->get_render_state(StencilAttrib::SRS_front_comparison_function) << "\n"
  11749. << "SRS_front_stencil_fail_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_front_stencil_fail_operation) << "\n"
  11750. << "SRS_front_stencil_pass_z_fail_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_fail_operation) << "\n"
  11751. << "SRS_front_stencil_pass_z_pass_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_pass_operation) << "\n"
  11752. << "SRS_reference " << (int)stencil->get_render_state(StencilAttrib::SRS_reference) << "\n"
  11753. << "SRS_read_mask " << (int)stencil->get_render_state(StencilAttrib::SRS_read_mask) << "\n"
  11754. << "SRS_write_mask " << (int)stencil->get_render_state(StencilAttrib::SRS_write_mask) << "\n"
  11755. << "SRS_back_comparison_function " << (int)stencil->get_render_state(StencilAttrib::SRS_back_comparison_function) << "\n"
  11756. << "SRS_back_stencil_fail_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_back_stencil_fail_operation) << "\n"
  11757. << "SRS_back_stencil_pass_z_fail_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_fail_operation) << "\n"
  11758. << "SRS_back_stencil_pass_z_pass_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_pass_operation) << "\n";
  11759. }
  11760. #ifndef OPENGLES
  11761. if (_supports_two_sided_stencil) {
  11762. // TODO: add support for OpenGL 2.0-style glStencilFuncSeparate.
  11763. unsigned int back_compare;
  11764. back_compare = stencil->get_render_state(StencilAttrib::SRS_back_comparison_function);
  11765. if (back_compare != RenderAttrib::M_none) {
  11766. glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
  11767. _glActiveStencilFaceEXT(GL_BACK);
  11768. glStencilFunc(
  11769. PANDA_TO_GL_COMPAREFUNC(back_compare),
  11770. stencil->get_render_state(StencilAttrib::SRS_reference),
  11771. stencil->get_render_state(StencilAttrib::SRS_read_mask));
  11772. glStencilOp(
  11773. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_back_stencil_fail_operation)],
  11774. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_fail_operation)],
  11775. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_pass_operation)]
  11776. );
  11777. glStencilMask(stencil->get_render_state(StencilAttrib::SRS_write_mask));
  11778. } else {
  11779. glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
  11780. }
  11781. _glActiveStencilFaceEXT(GL_FRONT);
  11782. }
  11783. #endif // OPENGLES
  11784. unsigned int front_compare;
  11785. front_compare = stencil->get_render_state(StencilAttrib::SRS_front_comparison_function);
  11786. if (front_compare != RenderAttrib::M_none) {
  11787. glEnable(GL_STENCIL_TEST);
  11788. glStencilFunc(
  11789. PANDA_TO_GL_COMPAREFUNC(front_compare),
  11790. stencil->get_render_state(StencilAttrib::SRS_reference),
  11791. stencil->get_render_state(StencilAttrib::SRS_read_mask));
  11792. glStencilOp(
  11793. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_front_stencil_fail_operation)],
  11794. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_fail_operation)],
  11795. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_pass_operation)]
  11796. );
  11797. glStencilMask(stencil->get_render_state(StencilAttrib::SRS_write_mask));
  11798. } else {
  11799. glDisable(GL_STENCIL_TEST);
  11800. }
  11801. if (stencil->get_render_state(StencilAttrib::SRS_clear)) {
  11802. // clear stencil buffer
  11803. glClearStencil(stencil->get_render_state(StencilAttrib::SRS_clear_value));
  11804. glClear(GL_STENCIL_BUFFER_BIT);
  11805. }
  11806. } else {
  11807. glDisable(GL_STENCIL_TEST);
  11808. #ifndef OPENGLES
  11809. if (_supports_two_sided_stencil) {
  11810. glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
  11811. }
  11812. #endif // OPENGLES
  11813. }
  11814. }
  11815. /**
  11816. *
  11817. */
  11818. void CLP(GraphicsStateGuardian)::
  11819. do_issue_scissor() {
  11820. const ScissorAttrib *target_scissor;
  11821. _target_rs->get_attrib_def(target_scissor);
  11822. if (!target_scissor->is_off()) {
  11823. // A non-off ScissorAttrib means to override the scissor setting that was
  11824. // specified by the DisplayRegion.
  11825. if (!_scissor_enabled) {
  11826. if (GLCAT.is_spam()) {
  11827. GLCAT.spam()
  11828. << "glEnable(GL_SCISSOR_TEST)\n";
  11829. }
  11830. glEnable(GL_SCISSOR_TEST);
  11831. _scissor_enabled = true;
  11832. }
  11833. const LVecBase4 &frame = target_scissor->get_frame();
  11834. int x = (int)(_viewport_x + _viewport_width * frame[0] + 0.5f);
  11835. int y = (int)(_viewport_y + _viewport_height * frame[2] + 0.5f);
  11836. int width = (int)(_viewport_width * (frame[1] - frame[0]) + 0.5f);
  11837. int height = (int)(_viewport_height * (frame[3] - frame[2]) + 0.5f);
  11838. if (GLCAT.is_spam()) {
  11839. GLCAT.spam()
  11840. << "glScissor(" << x << ", " << y << ", " << width << ", " << height << ")\n";
  11841. }
  11842. glScissor(x, y, width, height);
  11843. _scissor_attrib_active = true;
  11844. } else if (_scissor_attrib_active) {
  11845. _scissor_attrib_active = false;
  11846. if (_scissor_array.size() > 0) {
  11847. // Scissoring is enabled on the display region. Revert to the scissor
  11848. // state specified in the DisplayRegion.
  11849. #ifndef OPENGLES
  11850. if (_supports_viewport_arrays) {
  11851. _glScissorArrayv(0, _scissor_array.size(), _scissor_array[0].get_data());
  11852. } else
  11853. #endif // OPENGLES
  11854. {
  11855. const LVecBase4i sr = _scissor_array[0];
  11856. glScissor(sr[0], sr[1], sr[2], sr[3]);
  11857. }
  11858. } else if (_scissor_enabled) {
  11859. // The display region had no scissor enabled. Disable scissoring.
  11860. if (GLCAT.is_spam()) {
  11861. GLCAT.spam()
  11862. << "glDisable(GL_SCISSOR_TEST)\n";
  11863. }
  11864. glDisable(GL_SCISSOR_TEST);
  11865. _scissor_enabled = false;
  11866. }
  11867. }
  11868. }