glGraphicsStateGuardian_src.cxx 427 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619
  1. // Filename: glGraphicsStateGuardian_src.cxx
  2. // Created by: drose (02Feb99)
  3. // Updated by: fperazzi, PandaSE (05May10) (added
  4. // get_supports_cg_profile)
  5. //
  6. ////////////////////////////////////////////////////////////////////
  7. //
  8. // PANDA 3D SOFTWARE
  9. // Copyright (c) Carnegie Mellon University. All rights reserved.
  10. //
  11. // All use of this software is subject to the terms of the revised BSD
  12. // license. You should have received a copy of this license along
  13. // with this source code in a file named "LICENSE."
  14. //
  15. ////////////////////////////////////////////////////////////////////
  16. #include "config_util.h"
  17. #include "displayRegion.h"
  18. #include "renderBuffer.h"
  19. #include "geom.h"
  20. #include "geomVertexData.h"
  21. #include "geomTriangles.h"
  22. #include "geomTristrips.h"
  23. #include "geomTrifans.h"
  24. #include "geomLines.h"
  25. #include "geomLinestrips.h"
  26. #include "geomPoints.h"
  27. #include "geomVertexReader.h"
  28. #include "graphicsWindow.h"
  29. #include "lens.h"
  30. #include "perspectiveLens.h"
  31. #include "directionalLight.h"
  32. #include "pointLight.h"
  33. #include "spotlight.h"
  34. #include "planeNode.h"
  35. #include "fog.h"
  36. #include "clockObject.h"
  37. #include "string_utils.h"
  38. #include "nodePath.h"
  39. #include "dcast.h"
  40. #include "pvector.h"
  41. #include "vector_string.h"
  42. #include "string_utils.h"
  43. #include "pnmImage.h"
  44. #include "config_gobj.h"
  45. #include "lightMutexHolder.h"
  46. #include "indirectLess.h"
  47. #include "pStatTimer.h"
  48. #include "load_prc_file.h"
  49. #include "bamCache.h"
  50. #include "bamCacheRecord.h"
  51. #include "alphaTestAttrib.h"
  52. #include "clipPlaneAttrib.h"
  53. #include "cullFaceAttrib.h"
  54. #include "depthOffsetAttrib.h"
  55. #include "depthWriteAttrib.h"
  56. #include "fogAttrib.h"
  57. #include "lightAttrib.h"
  58. #include "materialAttrib.h"
  59. #include "rescaleNormalAttrib.h"
  60. #include "scissorAttrib.h"
  61. #include "shadeModelAttrib.h"
  62. #include "stencilAttrib.h"
  63. #include "graphicsEngine.h"
  64. #include "shaderGenerator.h"
  65. #include "samplerState.h"
  66. #include "displayInformation.h"
  67. #if defined(HAVE_CG) && !defined(OPENGLES)
  68. #include "Cg/cgGL.h"
  69. #endif
  70. #include <algorithm>
  71. TypeHandle CLP(GraphicsStateGuardian)::_type_handle;
  72. PStatCollector CLP(GraphicsStateGuardian)::_load_display_list_pcollector("Draw:Transfer data:Display lists");
  73. PStatCollector CLP(GraphicsStateGuardian)::_primitive_batches_display_list_pcollector("Primitive batches:Display lists");
  74. PStatCollector CLP(GraphicsStateGuardian)::_vertices_display_list_pcollector("Vertices:Display lists");
  75. PStatCollector CLP(GraphicsStateGuardian)::_vertices_immediate_pcollector("Vertices:Immediate mode");
  76. PStatCollector CLP(GraphicsStateGuardian)::_memory_barrier_pcollector("Draw:Memory barriers");
  77. PStatCollector CLP(GraphicsStateGuardian)::_vertex_array_update_pcollector("Draw:Update arrays");
  78. PStatCollector CLP(GraphicsStateGuardian)::_texture_update_pcollector("Draw:Update texture");
  79. PStatCollector CLP(GraphicsStateGuardian)::_fbo_bind_pcollector("Draw:Bind FBO");
  80. PStatCollector CLP(GraphicsStateGuardian)::_check_error_pcollector("Draw:Check errors");
  81. #ifndef OPENGLES_1
  82. PT(Shader) CLP(GraphicsStateGuardian)::_default_shader = NULL;
  83. #endif
  84. // The following noop functions are assigned to the corresponding
  85. // glext function pointers in the class, in case the functions are not
  86. // defined by the GL, just so it will always be safe to call the
  87. // extension functions.
  88. static void APIENTRY
  89. null_glPointParameterfv(GLenum, const GLfloat *) {
  90. }
  91. #ifdef OPENGLES
  92. // OpenGL ES 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. static void APIENTRY
  105. null_glActiveTexture(GLenum gl_texture_stage) {
  106. // If we don't support multitexture, we'd better not try to request
  107. // a texture beyond the first texture stage.
  108. nassertv(gl_texture_stage == GL_TEXTURE0);
  109. }
  110. static void APIENTRY
  111. null_glBlendEquation(GLenum) {
  112. }
  113. static void APIENTRY
  114. null_glBlendColor(GLclampf, GLclampf, GLclampf, GLclampf) {
  115. }
  116. #ifndef OPENGLES_1
  117. // We have a default shader that will be applied when there isn't any
  118. // shader applied (e.g. if it failed to compile). We need this because
  119. // OpenGL ES 2.x and OpenGL 3.2+ core don't have a fixed-function pipeline.
  120. // This default shader just applies a single texture, which is good enough
  121. // for drawing GUIs and such.
  122. static const string default_vshader =
  123. #ifndef OPENGLES
  124. "#version 130\n"
  125. "in vec4 p3d_Vertex;\n"
  126. "in vec4 p3d_Color;\n"
  127. "in vec2 p3d_MultiTexCoord0;\n"
  128. "out vec2 texcoord;\n"
  129. "out vec4 color;\n"
  130. #else
  131. "precision mediump float;\n"
  132. "attribute vec4 p3d_Vertex;\n"
  133. "attribute vec4 p3d_Color;\n"
  134. "attribute vec2 p3d_MultiTexCoord0;\n"
  135. "varying vec2 texcoord;\n"
  136. "varying vec4 color;\n"
  137. #endif
  138. "uniform mat4 p3d_ModelViewProjectionMatrix;\n"
  139. "uniform vec4 p3d_ColorScale;\n"
  140. "void main(void) {\n"
  141. " gl_Position = p3d_ModelViewProjectionMatrix * p3d_Vertex;\n"
  142. " texcoord = p3d_MultiTexCoord0;\n"
  143. " color = p3d_Color * p3d_ColorScale;\n"
  144. "}\n";
  145. static const string default_fshader =
  146. #ifndef OPENGLES
  147. "#version 130\n"
  148. "in vec2 texcoord;\n"
  149. "in vec4 color;\n"
  150. #else
  151. "precision mediump float;\n"
  152. "varying vec2 texcoord;\n"
  153. "varying vec4 color;\n"
  154. #endif
  155. "uniform sampler2D p3d_Texture0;\n"
  156. "void main(void) {\n"
  157. #ifndef OPENGLES
  158. " gl_FragColor = texture(p3d_Texture0, texcoord);\n"
  159. #else
  160. " gl_FragColor = texture2D(p3d_Texture0, texcoord).bgra;\n"
  161. #endif
  162. " gl_FragColor *= color;\n"
  163. "}\n";
  164. #endif
  165. ////////////////////////////////////////////////////////////////////
  166. // Function: uchar_bgr_to_rgb
  167. // Description: Recopies the given array of pixels, converting from
  168. // BGR to RGB arrangement.
  169. ////////////////////////////////////////////////////////////////////
  170. static void
  171. uchar_bgr_to_rgb(unsigned char *dest, const unsigned char *source,
  172. int num_pixels) {
  173. for (int i = 0; i < num_pixels; i++) {
  174. dest[0] = source[2];
  175. dest[1] = source[1];
  176. dest[2] = source[0];
  177. dest += 3;
  178. source += 3;
  179. }
  180. }
  181. ////////////////////////////////////////////////////////////////////
  182. // Function: uchar_bgra_to_rgba
  183. // Description: Recopies the given array of pixels, converting from
  184. // BGRA to RGBA arrangement.
  185. ////////////////////////////////////////////////////////////////////
  186. static void
  187. uchar_bgra_to_rgba(unsigned char *dest, const unsigned char *source,
  188. int num_pixels) {
  189. for (int i = 0; i < num_pixels; i++) {
  190. dest[0] = source[2];
  191. dest[1] = source[1];
  192. dest[2] = source[0];
  193. dest[3] = source[3];
  194. dest += 4;
  195. source += 4;
  196. }
  197. }
  198. ////////////////////////////////////////////////////////////////////
  199. // Function: ushort_bgr_to_rgb
  200. // Description: Recopies the given array of pixels, converting from
  201. // BGR to RGB arrangement.
  202. ////////////////////////////////////////////////////////////////////
  203. static void
  204. ushort_bgr_to_rgb(unsigned short *dest, const unsigned short *source,
  205. int num_pixels) {
  206. for (int i = 0; i < num_pixels; i++) {
  207. dest[0] = source[2];
  208. dest[1] = source[1];
  209. dest[2] = source[0];
  210. dest += 3;
  211. source += 3;
  212. }
  213. }
  214. ////////////////////////////////////////////////////////////////////
  215. // Function: ushort_bgra_to_rgba
  216. // Description: Recopies the given array of pixels, converting from
  217. // BGRA to RGBA arrangement.
  218. ////////////////////////////////////////////////////////////////////
  219. static void
  220. ushort_bgra_to_rgba(unsigned short *dest, const unsigned short *source,
  221. int num_pixels) {
  222. for (int i = 0; i < num_pixels; i++) {
  223. dest[0] = source[2];
  224. dest[1] = source[1];
  225. dest[2] = source[0];
  226. dest[3] = source[3];
  227. dest += 4;
  228. source += 4;
  229. }
  230. }
  231. ////////////////////////////////////////////////////////////////////
  232. // Function: fix_component_ordering
  233. // Description: Reverses the order of the components within the
  234. // image, to convert (for instance) GL_BGR to GL_RGB.
  235. // Returns the byte pointer representing the converted
  236. // image, or the original image if it is unchanged.
  237. //
  238. // new_image must be supplied; it is the PTA_uchar that
  239. // will be used to hold the converted image if required.
  240. // It will be modified only if the conversion is
  241. // necessary, in which case the data will be stored
  242. // there, and this pointer will be returned. If the
  243. // conversion is not necessary, this pointer will be
  244. // left unchanged.
  245. ////////////////////////////////////////////////////////////////////
  246. static const unsigned char *
  247. fix_component_ordering(PTA_uchar &new_image,
  248. const unsigned char *orig_image, size_t orig_image_size,
  249. GLenum external_format, Texture *tex) {
  250. const unsigned char *result = orig_image;
  251. switch (external_format) {
  252. case GL_RGB:
  253. switch (tex->get_component_type()) {
  254. case Texture::T_unsigned_byte:
  255. new_image = PTA_uchar::empty_array(orig_image_size);
  256. uchar_bgr_to_rgb(new_image, orig_image, orig_image_size / 3);
  257. result = new_image;
  258. break;
  259. case Texture::T_unsigned_short:
  260. new_image = PTA_uchar::empty_array(orig_image_size);
  261. ushort_bgr_to_rgb((unsigned short *)new_image.p(),
  262. (const unsigned short *)orig_image,
  263. orig_image_size / 6);
  264. result = new_image;
  265. break;
  266. default:
  267. break;
  268. }
  269. break;
  270. case GL_RGBA:
  271. switch (tex->get_component_type()) {
  272. case Texture::T_unsigned_byte:
  273. new_image = PTA_uchar::empty_array(orig_image_size);
  274. uchar_bgra_to_rgba(new_image, orig_image, orig_image_size / 4);
  275. result = new_image;
  276. break;
  277. case Texture::T_unsigned_short:
  278. new_image = PTA_uchar::empty_array(orig_image_size);
  279. ushort_bgra_to_rgba((unsigned short *)new_image.p(),
  280. (const unsigned short *)orig_image,
  281. orig_image_size / 8);
  282. result = new_image;
  283. break;
  284. default:
  285. break;
  286. }
  287. break;
  288. default:
  289. break;
  290. }
  291. return result;
  292. }
  293. //#--- Zhao Nov/2011
  294. string CLP(GraphicsStateGuardian)::get_driver_vendor() { return _gl_vendor; }
  295. string CLP(GraphicsStateGuardian)::get_driver_renderer() { return _gl_renderer; }
  296. string CLP(GraphicsStateGuardian)::get_driver_version() { return _gl_version; }
  297. int CLP(GraphicsStateGuardian)::get_driver_version_major() { return _gl_version_major; }
  298. int CLP(GraphicsStateGuardian)::get_driver_version_minor() { return _gl_version_minor; }
  299. int CLP(GraphicsStateGuardian)::get_driver_shader_version_major() { return _gl_shadlang_ver_major; }
  300. int CLP(GraphicsStateGuardian)::get_driver_shader_version_minor() { return _gl_shadlang_ver_minor; }
  301. ////////////////////////////////////////////////////////////////////
  302. // Function: GLGraphicsStateGuardian::Constructor
  303. // Access: Public
  304. // Description:
  305. ////////////////////////////////////////////////////////////////////
  306. CLP(GraphicsStateGuardian)::
  307. CLP(GraphicsStateGuardian)(GraphicsEngine *engine, GraphicsPipe *pipe) :
  308. GraphicsStateGuardian(gl_coordinate_system, engine, pipe),
  309. _renderbuffer_residency(get_prepared_objects()->get_name(), "renderbuffer")
  310. {
  311. _error_count = 0;
  312. _gl_shadlang_ver_major = 0;
  313. _gl_shadlang_ver_minor = 0;
  314. // Hack. Turn on the flag that we turned off at a higher level,
  315. // since we know this works properly in OpenGL, and we want the
  316. // performance benefit it gives us.
  317. _prepared_objects->_support_released_buffer_cache = true;
  318. // Assume that we will get a hardware-accelerated context, unless
  319. // the window tells us otherwise.
  320. _is_hardware = true;
  321. // calling glGetError() forces a sync, this turns it on if you want to.
  322. _check_errors = gl_check_errors;
  323. _force_flush = gl_force_flush;
  324. _scissor_enabled = false;
  325. _scissor_attrib_active = false;
  326. _white_texture = 0;
  327. #ifdef HAVE_CG
  328. _cg_context = 0;
  329. #endif
  330. #ifdef DO_PSTATS
  331. if (gl_finish) {
  332. GLCAT.warning()
  333. << "The config variable gl-finish is set to true. This may have a substantial negative impact on your render performance.\n";
  334. }
  335. #endif // DO_PSTATS
  336. }
  337. ////////////////////////////////////////////////////////////////////
  338. // Function: GLGraphicsStateGuardian::Destructor
  339. // Access: Public
  340. // Description:
  341. ////////////////////////////////////////////////////////////////////
  342. CLP(GraphicsStateGuardian)::
  343. ~CLP(GraphicsStateGuardian)() {
  344. if (GLCAT.is_debug()) {
  345. GLCAT.debug()
  346. << "GLGraphicsStateGuardian " << this << " destructing\n";
  347. }
  348. close_gsg();
  349. }
  350. ////////////////////////////////////////////////////////////////////
  351. // Function: GLGraphicsStateGuardian::debug_callback
  352. // Access: Public, Static
  353. // Description: This is called by the GL if an error occurs, if
  354. // gl_debug has been enabled (and the driver supports
  355. // the GL_ARB_debug_output extension).
  356. ////////////////////////////////////////////////////////////////////
  357. #ifndef OPENGLES_1
  358. void CLP(GraphicsStateGuardian)::
  359. debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, GLvoid *userParam) {
  360. // Determine how to map the severity level.
  361. NotifySeverity level;
  362. switch (severity) {
  363. case GL_DEBUG_SEVERITY_HIGH:
  364. level = NS_error;
  365. break;
  366. case GL_DEBUG_SEVERITY_MEDIUM:
  367. level = NS_warning;
  368. break;
  369. case GL_DEBUG_SEVERITY_LOW:
  370. level = NS_info;
  371. break;
  372. case GL_DEBUG_SEVERITY_NOTIFICATION:
  373. level = NS_debug;
  374. break;
  375. default:
  376. level = NS_fatal; //???
  377. break;
  378. }
  379. string msg_str(message, length);
  380. GLCAT.out(level) << msg_str << "\n";
  381. #ifndef NDEBUG
  382. if (level >= gl_debug_abort_level.get_value()) {
  383. abort();
  384. }
  385. #endif
  386. }
  387. #endif // OPENGLES_1
  388. ////////////////////////////////////////////////////////////////////
  389. // Function: GLGraphicsStateGuardian::reset
  390. // Access: Public, Virtual
  391. // Description: Resets all internal state as if the gsg were newly
  392. // created.
  393. ////////////////////////////////////////////////////////////////////
  394. void CLP(GraphicsStateGuardian)::
  395. reset() {
  396. free_pointers();
  397. GraphicsStateGuardian::reset();
  398. // Build _inv_state_mask as a mask of 1's where we don't care, and
  399. // 0's where we do care, about the state.
  400. //_inv_state_mask = RenderState::SlotMask::all_on();
  401. _inv_state_mask.clear_bit(ShaderAttrib::get_class_slot());
  402. _inv_state_mask.clear_bit(AlphaTestAttrib::get_class_slot());
  403. _inv_state_mask.clear_bit(AntialiasAttrib::get_class_slot());
  404. _inv_state_mask.clear_bit(ClipPlaneAttrib::get_class_slot());
  405. _inv_state_mask.clear_bit(ColorAttrib::get_class_slot());
  406. _inv_state_mask.clear_bit(ColorScaleAttrib::get_class_slot());
  407. _inv_state_mask.clear_bit(CullFaceAttrib::get_class_slot());
  408. _inv_state_mask.clear_bit(DepthOffsetAttrib::get_class_slot());
  409. _inv_state_mask.clear_bit(DepthTestAttrib::get_class_slot());
  410. _inv_state_mask.clear_bit(DepthWriteAttrib::get_class_slot());
  411. _inv_state_mask.clear_bit(RenderModeAttrib::get_class_slot());
  412. _inv_state_mask.clear_bit(RescaleNormalAttrib::get_class_slot());
  413. _inv_state_mask.clear_bit(ShadeModelAttrib::get_class_slot());
  414. _inv_state_mask.clear_bit(TransparencyAttrib::get_class_slot());
  415. _inv_state_mask.clear_bit(ColorWriteAttrib::get_class_slot());
  416. _inv_state_mask.clear_bit(ColorBlendAttrib::get_class_slot());
  417. _inv_state_mask.clear_bit(TextureAttrib::get_class_slot());
  418. _inv_state_mask.clear_bit(TexGenAttrib::get_class_slot());
  419. _inv_state_mask.clear_bit(TexMatrixAttrib::get_class_slot());
  420. _inv_state_mask.clear_bit(MaterialAttrib::get_class_slot());
  421. _inv_state_mask.clear_bit(LightAttrib::get_class_slot());
  422. _inv_state_mask.clear_bit(StencilAttrib::get_class_slot());
  423. _inv_state_mask.clear_bit(FogAttrib::get_class_slot());
  424. _inv_state_mask.clear_bit(ScissorAttrib::get_class_slot());
  425. // Output the vendor and version strings.
  426. query_gl_version();
  427. if (_gl_version_major == 0) {
  428. // Couldn't get GL. Fail.
  429. mark_new();
  430. return;
  431. }
  432. // Save the extensions tokens.
  433. _extensions.clear();
  434. // In OpenGL 3.0 and later, glGetString(GL_EXTENSIONS) is deprecated.
  435. #ifndef OPENGLES
  436. if (is_at_least_gl_version(3, 0)) {
  437. PFNGLGETSTRINGIPROC _glGetStringi =
  438. (PFNGLGETSTRINGIPROC)get_extension_func("glGetStringi");
  439. if (_glGetStringi != NULL) {
  440. GLint n = 0;
  441. glGetIntegerv(GL_NUM_EXTENSIONS, &n);
  442. for (GLint i = 0; i < n; ++i) {
  443. const char *extension = (const char *)_glGetStringi(GL_EXTENSIONS, i);
  444. _extensions.insert(string(extension));
  445. }
  446. } else {
  447. GLCAT.error() << "glGetStringi is not available!\n";
  448. save_extensions((const char *)glGetString(GL_EXTENSIONS));
  449. }
  450. } else
  451. #endif
  452. {
  453. save_extensions((const char *)glGetString(GL_EXTENSIONS));
  454. }
  455. get_extra_extensions();
  456. // This needs access to the extensions, so put this after save_extensions.
  457. query_glsl_version();
  458. #ifndef OPENGLES
  459. bool core_profile;
  460. if (_gl_version_major < 3 || has_extension("GL_ARB_compatibility")) {
  461. core_profile = false;
  462. } else {
  463. core_profile = true;
  464. }
  465. if (core_profile) {
  466. GLCAT.debug() << "Using core profile\n";
  467. } else {
  468. GLCAT.debug() << "Using compatibility profile\n";
  469. }
  470. #elif defined(OPENGLES_1)
  471. static const bool core_profile = false;
  472. #else
  473. static const bool core_profile = true;
  474. #endif
  475. // Print out a list of all extensions.
  476. report_extensions();
  477. // Initialize OpenGL debugging output first, if enabled and supported.
  478. _supports_debug = false;
  479. _use_object_labels = false;
  480. #ifndef OPENGLES_1
  481. if (gl_debug) {
  482. PFNGLDEBUGMESSAGECALLBACKPROC _glDebugMessageCallback;
  483. PFNGLDEBUGMESSAGECONTROLPROC _glDebugMessageControl;
  484. if (is_at_least_gl_version(4, 3) || has_extension("GL_KHR_debug")) {
  485. #ifdef OPENGLES
  486. _glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)
  487. get_extension_func("glDebugMessageCallbackKHR");
  488. _glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)
  489. get_extension_func("glDebugMessageControlKHR");
  490. _glObjectLabel = (PFNGLOBJECTLABELPROC)
  491. get_extension_func("glObjectLabelKHR");
  492. #else
  493. _glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)
  494. get_extension_func("glDebugMessageCallback");
  495. _glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)
  496. get_extension_func("glDebugMessageControl");
  497. _glObjectLabel = (PFNGLOBJECTLABELPROC)
  498. get_extension_func("glObjectLabel");
  499. #endif
  500. glEnable(GL_DEBUG_OUTPUT); // Not supported in ARB version
  501. _supports_debug = true;
  502. _use_object_labels = gl_debug_object_labels;
  503. #ifndef OPENGLES
  504. } else if (has_extension("GL_ARB_debug_output")) {
  505. _glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)
  506. get_extension_func("glDebugMessageCallbackARB");
  507. _glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)
  508. get_extension_func("glDebugMessageControlARB");
  509. _supports_debug = true;
  510. #endif
  511. }
  512. if (_supports_debug) {
  513. // Set the categories we want to listen to.
  514. _glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH,
  515. 0, NULL, GLCAT.is_error());
  516. _glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM,
  517. 0, NULL, GLCAT.is_warning());
  518. _glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW,
  519. 0, NULL, GLCAT.is_info());
  520. _glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION,
  521. 0, NULL, GLCAT.is_debug());
  522. // Enable the callback.
  523. _glDebugMessageCallback((GLDEBUGPROC) &debug_callback, (void*)this);
  524. if (gl_debug_synchronous) {
  525. glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
  526. }
  527. GLCAT.debug() << "gl-debug enabled.\n";
  528. } else {
  529. GLCAT.debug() << "gl-debug enabled, but NOT supported.\n";
  530. }
  531. } else {
  532. GLCAT.debug() << "gl-debug NOT enabled.\n";
  533. // However, still check if it is supported.
  534. _supports_debug = is_at_least_gl_version(4, 3)
  535. || has_extension("GL_KHR_debug")
  536. || has_extension("GL_ARB_debug_output");
  537. }
  538. #endif // OPENGLES_1
  539. _supported_geom_rendering =
  540. Geom::GR_indexed_point |
  541. Geom::GR_point | Geom::GR_point_uniform_size |
  542. Geom::GR_indexed_other |
  543. Geom::GR_triangle_strip | Geom::GR_triangle_fan |
  544. Geom::GR_line_strip |
  545. Geom::GR_flat_last_vertex;
  546. _supports_point_parameters = false;
  547. #ifndef OPENGLES_2
  548. if (is_at_least_gl_version(1, 4)) {
  549. _supports_point_parameters = true;
  550. _glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)
  551. get_extension_func("glPointParameterfv");
  552. } else if (has_extension("GL_ARB_point_parameters")) {
  553. _supports_point_parameters = true;
  554. _glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)
  555. get_extension_func("glPointParameterfvARB");
  556. }
  557. if (_supports_point_parameters) {
  558. if (_glPointParameterfv == NULL) {
  559. GLCAT.warning()
  560. << "glPointParameterfv advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  561. _supports_point_parameters = false;
  562. }
  563. }
  564. if (_supports_point_parameters) {
  565. _supported_geom_rendering |= Geom::GR_point_perspective | Geom::GR_point_scale;
  566. } else {
  567. _glPointParameterfv = null_glPointParameterfv;
  568. }
  569. #endif // !OPENGLES_2
  570. #if defined(OPENGLES_2)
  571. // OpenGL ES 2 doesn't have point sprites.
  572. _supports_point_sprite = false;
  573. #elif defined(OPENGLES_1)
  574. _supports_point_sprite = has_extension("GL_OES_point_sprite");
  575. #else
  576. _supports_point_sprite = has_extension("GL_ARB_point_sprite");
  577. #endif
  578. if (_supports_point_sprite) {
  579. // It appears that the point_sprite extension doesn't support
  580. // texture transforms on the generated texture coordinates. How
  581. // inconsistent. Because of this, we don't advertise
  582. // GR_point_sprite_tex_matrix.
  583. _supported_geom_rendering |= Geom::GR_point_sprite;
  584. }
  585. #ifndef OPENGLES
  586. _explicit_primitive_restart = false;
  587. _glPrimitiveRestartIndex = NULL;
  588. if (gl_support_primitive_restart_index) {
  589. if ((is_at_least_gl_version(4, 3) || has_extension("GL_ARB_ES3_compatibility")) &&
  590. _gl_renderer.substr(0, 7) != "Gallium") {
  591. // As long as we enable this, OpenGL will always use the highest possible index
  592. // for a numeric type as strip cut index, which coincides with our convention.
  593. // This saves us a call to glPrimitiveRestartIndex
  594. // ... of course, though, the Gallium driver bugs out here. See also:
  595. // https://www.panda3d.org/forums/viewtopic.php?f=5&t=17512
  596. glEnable(GL_PRIMITIVE_RESTART_FIXED_INDEX);
  597. _supported_geom_rendering |= Geom::GR_strip_cut_index;
  598. } else if (is_at_least_gl_version(3, 1)) {
  599. // We have to use an explicit primitive restart enable/index.
  600. _explicit_primitive_restart = true;
  601. _supported_geom_rendering |= Geom::GR_strip_cut_index;
  602. _glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC)
  603. get_extension_func("glPrimitiveRestartIndex");
  604. }
  605. }
  606. #endif
  607. #if !defined(OPENGLES) && defined(SUPPORT_FIXED_FUNCTION)
  608. if (is_at_least_gl_version(1, 4)) {
  609. _glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC)
  610. get_extension_func("glSecondaryColorPointer");
  611. } else if (has_extension("GL_EXT_secondary_color")) {
  612. _glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC)
  613. get_extension_func("glSecondaryColorPointerEXT");
  614. }
  615. #endif
  616. #ifndef OPENGLES
  617. _glDrawRangeElements = null_glDrawRangeElements;
  618. if (is_at_least_gl_version(1, 2)) {
  619. _glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)
  620. get_extension_func("glDrawRangeElements");
  621. } else if (has_extension("GL_EXT_draw_range_elements")) {
  622. _glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)
  623. get_extension_func("glDrawRangeElementsEXT");
  624. }
  625. if (_glDrawRangeElements == NULL) {
  626. GLCAT.warning()
  627. << "glDrawRangeElements advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  628. _glDrawRangeElements = null_glDrawRangeElements;
  629. }
  630. #endif
  631. _supports_3d_texture = false;
  632. #ifndef OPENGLES_1
  633. if (is_at_least_gl_version(1, 2)) {
  634. _supports_3d_texture = true;
  635. _glTexImage3D = (PFNGLTEXIMAGE3DPROC_P)
  636. get_extension_func("glTexImage3D");
  637. _glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)
  638. get_extension_func("glTexSubImage3D");
  639. _glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)
  640. get_extension_func("glCopyTexSubImage3D");
  641. } else if (has_extension("GL_EXT_texture3D")) {
  642. _supports_3d_texture = true;
  643. _glTexImage3D = (PFNGLTEXIMAGE3DPROC_P)
  644. get_extension_func("glTexImage3DEXT");
  645. _glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)
  646. get_extension_func("glTexSubImage3DEXT");
  647. _glCopyTexSubImage3D = NULL;
  648. if (has_extension("GL_EXT_copy_texture")) {
  649. _glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)
  650. get_extension_func("glCopyTexSubImage3DEXT");
  651. }
  652. } else if (has_extension("GL_OES_texture_3D")) {
  653. _supports_3d_texture = true;
  654. _glTexImage3D = (PFNGLTEXIMAGE3DPROC_P)
  655. get_extension_func("glTexImage3DOES");
  656. _glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)
  657. get_extension_func("glTexSubImage3DOES");
  658. _glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)
  659. get_extension_func("glCopyTexSubImage3DOES");
  660. #ifdef OPENGLES_2
  661. _glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DOES)
  662. get_extension_func("glFramebufferTexture3DOES");
  663. #endif
  664. }
  665. if (_supports_3d_texture) {
  666. if (_glTexImage3D == NULL || _glTexSubImage3D == NULL) {
  667. GLCAT.warning()
  668. << "3-D textures advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  669. _supports_3d_texture = false;
  670. }
  671. }
  672. #endif // !OPENGLES_1
  673. _supports_tex_storage = false;
  674. #ifndef OPENGLES
  675. if (is_at_least_gl_version(4, 2) || has_extension("GL_ARB_texture_storage")) {
  676. _supports_tex_storage = true;
  677. _glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)
  678. get_extension_func("glTexStorage1D");
  679. _glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)
  680. get_extension_func("glTexStorage2D");
  681. _glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)
  682. get_extension_func("glTexStorage3D");
  683. } else
  684. #endif
  685. if (has_extension("GL_EXT_texture_storage")) { // GLES case
  686. _supports_tex_storage = true;
  687. _glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)
  688. get_extension_func("glTexStorage1DEXT");
  689. _glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)
  690. get_extension_func("glTexStorage2DEXT");
  691. _glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)
  692. get_extension_func("glTexStorage3DEXT");
  693. }
  694. if (_supports_tex_storage) {
  695. if (_glTexStorage1D == NULL || _glTexStorage2D == NULL || _glTexStorage3D == NULL) {
  696. GLCAT.warning()
  697. << "Immutable texture storage advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  698. _supports_tex_storage = false;
  699. }
  700. }
  701. _supports_clear_texture = false;
  702. #ifndef OPENGLES
  703. if (is_at_least_gl_version(4, 4) || has_extension("GL_ARB_clear_texture")) {
  704. _glClearTexImage = (PFNGLCLEARTEXIMAGEPROC)
  705. get_extension_func("glClearTexImage");
  706. if (_glClearTexImage == NULL) {
  707. GLCAT.warning()
  708. << "GL_ARB_clear_texture advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  709. } else {
  710. _supports_clear_texture = true;
  711. }
  712. }
  713. #endif
  714. _supports_2d_texture_array = false;
  715. #ifndef OPENGLES
  716. if (is_at_least_gl_version(3, 0)) {
  717. _supports_2d_texture_array = true;
  718. _glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)
  719. get_extension_func("glFramebufferTextureLayer");
  720. } else if (has_extension("GL_EXT_texture_array")) {
  721. _supports_2d_texture_array = true;
  722. _glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)
  723. get_extension_func("glFramebufferTextureLayerEXT");
  724. }
  725. if (_supports_2d_texture_array && _glFramebufferTextureLayer == NULL) {
  726. GLCAT.warning()
  727. << "Texture arrays advertised as supported by OpenGL runtime, but could not get pointer to glFramebufferTextureLayer function.\n";
  728. }
  729. #endif
  730. #ifdef OPENGLES_2
  731. _supports_cube_map = true;
  732. #else
  733. _supports_cube_map =
  734. has_extension("GL_ARB_texture_cube_map") || is_at_least_gl_version(1, 3) ||
  735. has_extension("GL_OES_texture_cube_map");
  736. #endif
  737. #ifndef OPENGLES
  738. if (_supports_cube_map && gl_cube_map_seamless) {
  739. if (is_at_least_gl_version(3, 2) || has_extension("GL_ARB_seamless_cube_map")) {
  740. glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
  741. }
  742. }
  743. #endif
  744. #ifndef OPENGLES
  745. if (is_at_least_gl_version(3, 0)) {
  746. _glTexBuffer = (PFNGLTEXBUFFERPROC)get_extension_func("glTexBuffer");
  747. _supports_buffer_texture = true;
  748. } else if (has_extension("GL_ARB_texture_buffer_object")) {
  749. _glTexBuffer = (PFNGLTEXBUFFERPROC)get_extension_func("glTexBufferARB");
  750. _supports_buffer_texture = true;
  751. }
  752. #endif
  753. _supports_texture_srgb = false;
  754. if (is_at_least_gl_version(2, 1) || has_extension("GL_EXT_texture_sRGB")) {
  755. _supports_texture_srgb = true;
  756. } else if (has_extension("GL_EXT_sRGB")) { // GLES case.
  757. _supports_texture_srgb = true;
  758. }
  759. _supports_compressed_texture = false;
  760. #ifdef OPENGLES
  761. _supports_compressed_texture = true;
  762. // Supported in the core. 1D textures are not supported by OpenGL ES.
  763. _glCompressedTexImage1D = NULL;
  764. _glCompressedTexImage2D = glCompressedTexImage2D;
  765. _glCompressedTexSubImage1D = NULL;
  766. _glCompressedTexSubImage2D = glCompressedTexSubImage2D;
  767. _glGetCompressedTexImage = NULL;
  768. _glCompressedTexImage3D = NULL;
  769. _glCompressedTexSubImage3D = NULL;
  770. #ifdef OPENGLES_2
  771. if (_supports_3d_texture) {
  772. _glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)
  773. get_extension_func("glCompressedTexImage3DOES");
  774. _glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)
  775. get_extension_func("glCompressedTexSubImageOES");
  776. }
  777. #endif
  778. #else
  779. if (is_at_least_gl_version(1, 3)) {
  780. _supports_compressed_texture = true;
  781. _glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)
  782. get_extension_func("glCompressedTexImage1D");
  783. _glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)
  784. get_extension_func("glCompressedTexImage2D");
  785. _glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)
  786. get_extension_func("glCompressedTexImage3D");
  787. _glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)
  788. get_extension_func("glCompressedTexSubImage1D");
  789. _glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)
  790. get_extension_func("glCompressedTexSubImage2D");
  791. _glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)
  792. get_extension_func("glCompressedTexSubImage3D");
  793. _glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)
  794. get_extension_func("glGetCompressedTexImage");
  795. } else if (has_extension("GL_ARB_texture_compression")) {
  796. _supports_compressed_texture = true;
  797. _glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)
  798. get_extension_func("glCompressedTexImage1DARB");
  799. _glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)
  800. get_extension_func("glCompressedTexImage2DARB");
  801. _glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)
  802. get_extension_func("glCompressedTexImage3DARB");
  803. _glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)
  804. get_extension_func("glCompressedTexSubImage1DARB");
  805. _glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)
  806. get_extension_func("glCompressedTexSubImage2DARB");
  807. _glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)
  808. get_extension_func("glCompressedTexSubImage3DARB");
  809. _glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)
  810. get_extension_func("glGetCompressedTexImageARB");
  811. }
  812. if (_supports_compressed_texture) {
  813. if (_glCompressedTexImage1D == NULL ||
  814. _glCompressedTexImage2D == NULL ||
  815. _glCompressedTexImage3D == NULL ||
  816. _glCompressedTexSubImage1D == NULL ||
  817. _glCompressedTexSubImage2D == NULL ||
  818. _glCompressedTexSubImage3D == NULL ||
  819. _glGetCompressedTexImage == NULL) {
  820. GLCAT.warning()
  821. << "Compressed textures advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  822. _supports_compressed_texture = false;
  823. }
  824. }
  825. #endif
  826. if (_supports_compressed_texture) {
  827. #ifndef OPENGLES
  828. _compressed_texture_formats.set_bit(Texture::CM_on);
  829. #endif
  830. GLint num_compressed_formats = 0;
  831. glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_compressed_formats);
  832. GLint *formats = (GLint *)PANDA_MALLOC_ARRAY(num_compressed_formats * sizeof(GLint));
  833. glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats);
  834. for (int i = 0; i < num_compressed_formats; ++i) {
  835. switch (formats[i]) {
  836. case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  837. case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  838. _compressed_texture_formats.set_bit(Texture::CM_dxt1);
  839. break;
  840. #ifdef OPENGLES
  841. case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
  842. case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
  843. _compressed_texture_formats.set_bit(Texture::CM_pvr1_2bpp);
  844. break;
  845. case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
  846. case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
  847. _compressed_texture_formats.set_bit(Texture::CM_pvr1_4bpp);
  848. break;
  849. #else
  850. case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
  851. _compressed_texture_formats.set_bit(Texture::CM_dxt3);
  852. break;
  853. case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
  854. _compressed_texture_formats.set_bit(Texture::CM_dxt5);
  855. break;
  856. case GL_COMPRESSED_RGB_FXT1_3DFX:
  857. case GL_COMPRESSED_RGBA_FXT1_3DFX:
  858. _compressed_texture_formats.set_bit(Texture::CM_fxt1);
  859. break;
  860. #endif
  861. default:
  862. break;
  863. }
  864. }
  865. PANDA_FREE_ARRAY(formats);
  866. }
  867. #ifdef OPENGLES_2
  868. _supports_bgr = false;
  869. #else
  870. _supports_bgr =
  871. has_extension("GL_EXT_bgra") || is_at_least_gl_version(1, 2);
  872. #endif
  873. #ifdef SUPPORT_FIXED_FUNCTION
  874. _supports_rescale_normal =
  875. !core_profile && gl_support_rescale_normal &&
  876. (has_extension("GL_EXT_rescale_normal") || is_at_least_gl_version(1, 2));
  877. #endif
  878. #ifdef OPENGLES
  879. _supports_packed_dabc = false;
  880. _supports_packed_ufloat = false;
  881. #else
  882. _supports_packed_dabc = is_at_least_gl_version(3, 2) ||
  883. has_extension("GL_ARB_vertex_array_bgra") ||
  884. has_extension("GL_EXT_vertex_array_bgra");
  885. _supports_packed_ufloat = is_at_least_gl_version(4, 4) ||
  886. has_extension("GL_ARB_vertex_type_10f_11f_11f_rev");
  887. #endif
  888. _supports_multisample =
  889. has_extension("GL_ARB_multisample") || is_at_least_gl_version(1, 3);
  890. #ifdef OPENGLES_2
  891. _supports_generate_mipmap = true;
  892. #else
  893. _supports_generate_mipmap =
  894. has_extension("GL_SGIS_generate_mipmap") || is_at_least_gl_version(1, 4) || is_at_least_gles_version(1, 1);
  895. #endif
  896. #ifdef OPENGLES
  897. _supports_tex_non_pow2 =
  898. has_extension("GL_OES_texture_npot");
  899. #else
  900. _supports_tex_non_pow2 =
  901. has_extension("GL_ARB_texture_non_power_of_two");
  902. #endif
  903. #ifdef OPENGLES_2
  904. _glActiveTexture = glActiveTexture;
  905. #else
  906. bool supports_multitexture = false;
  907. if (is_at_least_gl_version(1, 3) || is_at_least_gles_version(1, 1)) {
  908. supports_multitexture = true;
  909. _glActiveTexture = (PFNGLACTIVETEXTUREPROC)
  910. get_extension_func("glActiveTexture");
  911. #ifdef SUPPORT_FIXED_FUNCTION
  912. _glClientActiveTexture = (PFNGLACTIVETEXTUREPROC)
  913. get_extension_func("glClientActiveTexture");
  914. #endif
  915. #ifdef SUPPORT_IMMEDIATE_MODE
  916. _glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)
  917. get_extension_func("glMultiTexCoord1f");
  918. _glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)
  919. get_extension_func("glMultiTexCoord2f");
  920. _glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)
  921. get_extension_func("glMultiTexCoord3f");
  922. _glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)
  923. get_extension_func("glMultiTexCoord4f");
  924. _glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)
  925. get_extension_func("glMultiTexCoord1d");
  926. _glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)
  927. get_extension_func("glMultiTexCoord2d");
  928. _glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)
  929. get_extension_func("glMultiTexCoord3d");
  930. _glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)
  931. get_extension_func("glMultiTexCoord4d");
  932. #endif
  933. } else if (has_extension("GL_ARB_multitexture")) {
  934. supports_multitexture = true;
  935. _glActiveTexture = (PFNGLACTIVETEXTUREPROC)
  936. get_extension_func("glActiveTextureARB");
  937. #ifdef SUPPORT_FIXED_FUNCTION
  938. _glClientActiveTexture = (PFNGLACTIVETEXTUREPROC)
  939. get_extension_func("glClientActiveTextureARB");
  940. #endif
  941. #ifdef SUPPORT_IMMEDIATE_MODE
  942. _glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)
  943. get_extension_func("glMultiTexCoord1fARB");
  944. _glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)
  945. get_extension_func("glMultiTexCoord2fARB");
  946. _glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)
  947. get_extension_func("glMultiTexCoord3fARB");
  948. _glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)
  949. get_extension_func("glMultiTexCoord4fARB");
  950. _glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)
  951. get_extension_func("glMultiTexCoord1dARB");
  952. _glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)
  953. get_extension_func("glMultiTexCoord2dARB");
  954. _glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)
  955. get_extension_func("glMultiTexCoord3dARB");
  956. _glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)
  957. get_extension_func("glMultiTexCoord4dARB");
  958. #endif
  959. } else {
  960. supports_multitexture = false;
  961. }
  962. if (supports_multitexture) {
  963. if (_glActiveTexture == NULL
  964. #ifdef SUPPORT_FIXED_FUNCTION
  965. || _glClientActiveTexture == NULL
  966. #endif
  967. #ifdef SUPPORT_IMMEDIATE_MODE
  968. || GLf(_glMultiTexCoord1) == NULL || GLf(_glMultiTexCoord2) == NULL
  969. || GLf(_glMultiTexCoord3) == NULL || GLf(_glMultiTexCoord4) == NULL
  970. #endif
  971. ) {
  972. GLCAT.warning()
  973. << "Multitexture advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  974. supports_multitexture = false;
  975. }
  976. }
  977. if (!supports_multitexture) {
  978. // Replace with dummy no-op functions.
  979. _glActiveTexture = null_glActiveTexture;
  980. }
  981. #ifdef SUPPORT_FIXED_FUNCTION
  982. if (!supports_multitexture || core_profile) {
  983. _glClientActiveTexture = null_glActiveTexture;
  984. }
  985. #endif
  986. #endif // OPENGLES_2
  987. #ifdef OPENGLES
  988. if (has_extension("GL_ANGLE_depth_texture")) {
  989. // This extension provides both depth textures and depth-stencil support.
  990. _supports_depth_texture = true;
  991. _supports_depth_stencil = true;
  992. } else if (has_extension("GL_OES_depth_texture")) {
  993. _supports_depth_texture = true;
  994. _supports_depth_stencil = has_extension("GL_OES_packed_depth_stencil");
  995. }
  996. _supports_depth24 = has_extension("GL_OES_depth24");
  997. _supports_depth32 = has_extension("GL_OES_depth32");
  998. #else
  999. _supports_depth_texture = (is_at_least_gl_version(1, 4) ||
  1000. has_extension("GL_ARB_depth_texture"));
  1001. _supports_depth_stencil = (is_at_least_gl_version(3, 0) ||
  1002. has_extension("GL_ARB_framebuffer_object") ||
  1003. has_extension("GL_EXT_packed_depth_stencil"));
  1004. #endif
  1005. #ifdef OPENGLES_2
  1006. if (gl_support_shadow_filter && _supports_depth_texture &&
  1007. has_extension("GL_EXT_shadow_samplers")) {
  1008. _supports_shadow_filter = true;
  1009. }
  1010. #else
  1011. if (gl_support_shadow_filter &&
  1012. _supports_depth_texture &&
  1013. has_extension("GL_ARB_shadow") &&
  1014. has_extension("GL_ARB_fragment_program_shadow")) {
  1015. _supports_shadow_filter = true;
  1016. }
  1017. #endif
  1018. // Actually, we can't keep forever disabling ARB_shadow on ATI cards,
  1019. // since they do work correctly now. Maybe there is some feature
  1020. // level we can check somewhere?
  1021. /*if (_gl_vendor.substr(0,3)=="ATI") {
  1022. // ATI drivers have never provided correct shadow support.
  1023. _supports_shadow_filter = false;
  1024. }*/
  1025. #ifndef SUPPORT_FIXED_FUNCTION
  1026. _supports_texture_combine = false;
  1027. _supports_texture_saved_result = false;
  1028. _supports_texture_dot3 = false;
  1029. #else
  1030. if (!core_profile) {
  1031. _supports_texture_combine =
  1032. has_extension("GL_ARB_texture_env_combine") || is_at_least_gl_version(1, 3) || is_at_least_gles_version(1, 1);
  1033. _supports_texture_saved_result =
  1034. has_extension("GL_ARB_texture_env_crossbar") || has_extension("GL_OES_texture_env_crossbar") || is_at_least_gl_version(1, 4);
  1035. _supports_texture_dot3 =
  1036. has_extension("GL_ARB_texture_env_dot3") || is_at_least_gl_version(1, 3) || is_at_least_gles_version(1, 1);
  1037. }
  1038. #endif
  1039. #ifdef OPENGLES_2
  1040. _supports_buffers = true;
  1041. _glGenBuffers = glGenBuffers;
  1042. _glBindBuffer = glBindBuffer;
  1043. _glBufferData = glBufferData;
  1044. _glBufferSubData = glBufferSubData;
  1045. _glDeleteBuffers = glDeleteBuffers;
  1046. #else
  1047. _supports_buffers = false;
  1048. if (is_at_least_gl_version(1, 5) || is_at_least_gles_version(1, 1)) {
  1049. _supports_buffers = true;
  1050. _glGenBuffers = (PFNGLGENBUFFERSPROC)
  1051. get_extension_func("glGenBuffers");
  1052. _glBindBuffer = (PFNGLBINDBUFFERPROC)
  1053. get_extension_func("glBindBuffer");
  1054. _glBufferData = (PFNGLBUFFERDATAPROC)
  1055. get_extension_func("glBufferData");
  1056. _glBufferSubData = (PFNGLBUFFERSUBDATAPROC)
  1057. get_extension_func("glBufferSubData");
  1058. _glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)
  1059. get_extension_func("glDeleteBuffers");
  1060. }
  1061. #ifndef OPENGLES_1
  1062. else if (has_extension("GL_ARB_vertex_buffer_object")) {
  1063. _supports_buffers = true;
  1064. _glGenBuffers = (PFNGLGENBUFFERSPROC)
  1065. get_extension_func("glGenBuffersARB");
  1066. _glBindBuffer = (PFNGLBINDBUFFERPROC)
  1067. get_extension_func("glBindBufferARB");
  1068. _glBufferData = (PFNGLBUFFERDATAPROC)
  1069. get_extension_func("glBufferDataARB");
  1070. _glBufferSubData = (PFNGLBUFFERSUBDATAPROC)
  1071. get_extension_func("glBufferSubDataARB");
  1072. _glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)
  1073. get_extension_func("glDeleteBuffersARB");
  1074. }
  1075. #endif // OPENGLES_1
  1076. if (_supports_buffers) {
  1077. if (_glGenBuffers == NULL || _glBindBuffer == NULL ||
  1078. _glBufferData == NULL || _glBufferSubData == NULL ||
  1079. _glDeleteBuffers == NULL) {
  1080. GLCAT.warning()
  1081. << "Buffers advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1082. _supports_buffers = false;
  1083. }
  1084. }
  1085. #endif
  1086. _supports_vao = false;
  1087. if (is_at_least_gl_version(3, 0) || has_extension("GL_ARB_vertex_array_object")) {
  1088. _supports_vao = true;
  1089. _glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)
  1090. get_extension_func("glBindVertexArray");
  1091. _glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)
  1092. get_extension_func("glDeleteVertexArrays");
  1093. _glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)
  1094. get_extension_func("glGenVertexArrays");
  1095. } else if (has_extension("GL_OES_vertex_array_object")) {
  1096. _supports_vao = true;
  1097. _glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)
  1098. get_extension_func("glBindVertexArrayOES");
  1099. _glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)
  1100. get_extension_func("glDeleteVertexArraysOES");
  1101. _glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)
  1102. get_extension_func("glGenVertexArraysOES");
  1103. }
  1104. if (_supports_vao) {
  1105. if (_glBindVertexArray == NULL || _glDeleteVertexArrays == NULL ||
  1106. _glGenVertexArrays == NULL) {
  1107. GLCAT.warning()
  1108. << "Vertex array objects advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1109. _supports_vao = false;
  1110. }
  1111. }
  1112. // Check for GLSL support.
  1113. #if defined(OPENGLES_1)
  1114. _supports_glsl = false;
  1115. _supports_geometry_shaders = false;
  1116. _supports_tessellation_shaders = false;
  1117. #elif defined(OPENGLES)
  1118. _supports_glsl = true;
  1119. _supports_geometry_shaders = false;
  1120. _supports_tessellation_shaders = false;
  1121. #else
  1122. _supports_glsl = (_gl_shadlang_ver_major >= 1);
  1123. _supports_tessellation_shaders = is_at_least_gl_version(4, 0) || has_extension("GL_ARB_tessellation_shader");
  1124. if (is_at_least_gl_version(3, 2)) {
  1125. _supports_geometry_shaders = true;
  1126. _glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREARBPROC)
  1127. get_extension_func("glFramebufferTexture");
  1128. } else if (has_extension("GL_ARB_geometry_shader4")) {
  1129. _supports_geometry_shaders = true;
  1130. _glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREARBPROC)
  1131. get_extension_func("glFramebufferTextureARB");
  1132. _glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)
  1133. get_extension_func("glProgramParameteriARB");
  1134. } else if (has_extension("GL_EXT_geometry_shader4")) {
  1135. _supports_geometry_shaders = true;
  1136. _glFramebufferTexture = NULL;
  1137. _glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)
  1138. get_extension_func("glProgramParameteriEXT");
  1139. } else {
  1140. _supports_geometry_shaders = false;
  1141. _glFramebufferTexture = NULL;
  1142. }
  1143. #endif
  1144. _shader_caps._supports_glsl = _supports_glsl;
  1145. // Check for support for other types of shaders that can be used by Cg.
  1146. _supports_basic_shaders = false;
  1147. #if defined(HAVE_CG) && !defined(OPENGLES)
  1148. if (has_extension("GL_ARB_vertex_program") &&
  1149. has_extension("GL_ARB_fragment_program")) {
  1150. _supports_basic_shaders = true;
  1151. _shader_caps._active_vprofile = (int)CG_PROFILE_ARBVP1;
  1152. _shader_caps._active_fprofile = (int)CG_PROFILE_ARBFP1;
  1153. _shader_caps._active_gprofile = (int)CG_PROFILE_UNKNOWN; // No geometry shader if only using basic
  1154. if (basic_shaders_only) {
  1155. // We're happy with ARB programs, thanks.
  1156. } else if (has_extension("GL_NV_gpu_program5")) {
  1157. _shader_caps._active_vprofile = (int)CG_PROFILE_GP5VP;
  1158. _shader_caps._active_fprofile = (int)CG_PROFILE_GP5FP;
  1159. _shader_caps._active_gprofile = (int)CG_PROFILE_GP5GP;
  1160. } else if (has_extension("GL_NV_gpu_program4")) {
  1161. _shader_caps._active_vprofile = (int)CG_PROFILE_GP4VP;
  1162. _shader_caps._active_fprofile = (int)CG_PROFILE_GP4FP;
  1163. _shader_caps._active_gprofile = (int)CG_PROFILE_GP4GP;
  1164. } else if (has_extension("GL_NV_vertex_program3") &&
  1165. has_extension("GL_NV_fragment_program2")) {
  1166. _shader_caps._active_vprofile = (int)CG_PROFILE_VP40;
  1167. _shader_caps._active_fprofile = (int)CG_PROFILE_FP40;
  1168. _shader_caps._active_gprofile = (int)CG_PROFILE_UNKNOWN;
  1169. } else if (has_extension("GL_NV_vertex_program2") &&
  1170. has_extension("GL_NV_fragment_program")) {
  1171. _shader_caps._active_vprofile = (int)CG_PROFILE_VP30;
  1172. _shader_caps._active_fprofile = (int)CG_PROFILE_FP30;
  1173. _shader_caps._active_gprofile = (int)CG_PROFILE_UNKNOWN;
  1174. } else if (has_extension("GL_NV_vertex_program1_1") &&
  1175. has_extension("GL_NV_texture_shader2") &&
  1176. has_extension("GL_NV_register_combiners2")) {
  1177. _shader_caps._active_vprofile = (int)CG_PROFILE_VP20;
  1178. _shader_caps._active_fprofile = (int)CG_PROFILE_FP20;
  1179. _shader_caps._active_gprofile = (int)CG_PROFILE_UNKNOWN;
  1180. } else if (_supports_glsl) {
  1181. // This is what will be available to non-NVIDIA cards. It is the last
  1182. // option since it is slower to compile GLSL than the other options.
  1183. _shader_caps._active_vprofile = (int)CG_PROFILE_GLSLV;
  1184. _shader_caps._active_fprofile = (int)CG_PROFILE_GLSLF;
  1185. if (_supports_geometry_shaders) {
  1186. _shader_caps._active_gprofile = (int)CG_PROFILE_GLSLG;
  1187. }
  1188. }
  1189. _shader_caps._ultimate_vprofile = (int)CG_PROFILE_VP40;
  1190. _shader_caps._ultimate_fprofile = (int)CG_PROFILE_FP40;
  1191. _shader_caps._ultimate_gprofile = (int)CG_PROFILE_GPU_GP;
  1192. // Bug workaround for radeons.
  1193. if (_shader_caps._active_fprofile == CG_PROFILE_ARBFP1) {
  1194. if (has_extension("GL_ATI_draw_buffers")) {
  1195. _shader_caps._bug_list.insert(Shader::SBUG_ati_draw_buffers);
  1196. }
  1197. }
  1198. } else if (_supports_glsl) {
  1199. // No, but we do support GLSL...
  1200. _shader_caps._active_vprofile = (int)CG_PROFILE_GLSLV;
  1201. _shader_caps._active_fprofile = (int)CG_PROFILE_GLSLF;
  1202. if (_supports_geometry_shaders) {
  1203. _shader_caps._active_gprofile = (int)CG_PROFILE_GLSLG;
  1204. } else {
  1205. _shader_caps._active_gprofile = (int)CG_PROFILE_UNKNOWN;
  1206. }
  1207. }
  1208. #endif // HAVE_CG
  1209. _supports_compute_shaders = false;
  1210. #ifndef OPENGLES
  1211. if (is_at_least_gl_version(4, 3) || has_extension("GL_ARB_compute_shader")) {
  1212. _glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC)
  1213. get_extension_func("glDispatchCompute");
  1214. if (_glDispatchCompute != NULL) {
  1215. _supports_compute_shaders = true;
  1216. }
  1217. }
  1218. #endif
  1219. #ifndef OPENGLES
  1220. if (_supports_glsl) {
  1221. _glAttachShader = (PFNGLATTACHSHADERPROC)
  1222. get_extension_func("glAttachShader");
  1223. _glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)
  1224. get_extension_func("glBindAttribLocation");
  1225. _glCompileShader = (PFNGLCOMPILESHADERPROC)
  1226. get_extension_func("glCompileShader");
  1227. _glCreateProgram = (PFNGLCREATEPROGRAMPROC)
  1228. get_extension_func("glCreateProgram");
  1229. _glCreateShader = (PFNGLCREATESHADERPROC)
  1230. get_extension_func("glCreateShader");
  1231. _glDeleteProgram = (PFNGLDELETEPROGRAMPROC)
  1232. get_extension_func("glDeleteProgram");
  1233. _glDeleteShader = (PFNGLDELETESHADERPROC)
  1234. get_extension_func("glDeleteShader");
  1235. _glDetachShader = (PFNGLDETACHSHADERPROC)
  1236. get_extension_func("glDetachShader");
  1237. _glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)
  1238. get_extension_func("glDisableVertexAttribArray");
  1239. _glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)
  1240. get_extension_func("glEnableVertexAttribArray");
  1241. _glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)
  1242. get_extension_func("glGetActiveAttrib");
  1243. _glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)
  1244. get_extension_func("glGetActiveUniform");
  1245. _glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)
  1246. get_extension_func("glGetAttribLocation");
  1247. _glGetProgramiv = (PFNGLGETPROGRAMIVPROC)
  1248. get_extension_func("glGetProgramiv");
  1249. _glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)
  1250. get_extension_func("glGetProgramInfoLog");
  1251. _glGetShaderiv = (PFNGLGETSHADERIVPROC)
  1252. get_extension_func("glGetShaderiv");
  1253. _glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)
  1254. get_extension_func("glGetShaderInfoLog");
  1255. _glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)
  1256. get_extension_func("glGetUniformLocation");
  1257. _glLinkProgram = (PFNGLLINKPROGRAMPROC)
  1258. get_extension_func("glLinkProgram");
  1259. _glShaderSource = (PFNGLSHADERSOURCEPROC_P)
  1260. get_extension_func("glShaderSource");
  1261. _glUseProgram = (PFNGLUSEPROGRAMPROC)
  1262. get_extension_func("glUseProgram");
  1263. _glUniform4f = (PFNGLUNIFORM4FPROC)
  1264. get_extension_func("glUniform4f");
  1265. _glUniform1i = (PFNGLUNIFORM1IPROC)
  1266. get_extension_func("glUniform1i");
  1267. _glUniform1fv = (PFNGLUNIFORM1FVPROC)
  1268. get_extension_func("glUniform1fv");
  1269. _glUniform2fv = (PFNGLUNIFORM2FVPROC)
  1270. get_extension_func("glUniform2fv");
  1271. _glUniform3fv = (PFNGLUNIFORM3FVPROC)
  1272. get_extension_func("glUniform3fv");
  1273. _glUniform4fv = (PFNGLUNIFORM4FVPROC)
  1274. get_extension_func("glUniform4fv");
  1275. _glUniform1iv = (PFNGLUNIFORM1IVPROC)
  1276. get_extension_func("glUniform1iv");
  1277. _glUniform2iv = (PFNGLUNIFORM2IVPROC)
  1278. get_extension_func("glUniform2iv");
  1279. _glUniform3iv = (PFNGLUNIFORM3IVPROC)
  1280. get_extension_func("glUniform3iv");
  1281. _glUniform4iv = (PFNGLUNIFORM4IVPROC)
  1282. get_extension_func("glUniform4iv");
  1283. _glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)
  1284. get_extension_func("glUniformMatrix3fv");
  1285. _glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)
  1286. get_extension_func("glUniformMatrix4fv");
  1287. _glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)
  1288. get_extension_func("glValidateProgram");
  1289. _glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)
  1290. get_extension_func("glVertexAttrib4fv");
  1291. _glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)
  1292. get_extension_func("glVertexAttrib4dv");
  1293. _glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)
  1294. get_extension_func("glVertexAttribPointer");
  1295. if (is_at_least_gl_version(3, 0)) {
  1296. _glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)
  1297. get_extension_func("glVertexAttribIPointer");
  1298. } else {
  1299. _glVertexAttribIPointer = NULL;
  1300. }
  1301. if (has_extension("GL_ARB_vertex_attrib_64bit")) {
  1302. _glVertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC)
  1303. get_extension_func("glVertexAttribLPointer");
  1304. } else {
  1305. _glVertexAttribLPointer = NULL;
  1306. }
  1307. if (_supports_tessellation_shaders) {
  1308. _glPatchParameteri = (PFNGLPATCHPARAMETERIPROC)
  1309. get_extension_func("glPatchParameteri");
  1310. }
  1311. }
  1312. #endif
  1313. #ifdef OPENGLES_2
  1314. _glAttachShader = glAttachShader;
  1315. _glBindAttribLocation = glBindAttribLocation;
  1316. _glCompileShader = glCompileShader;
  1317. _glCreateProgram = glCreateProgram;
  1318. _glCreateShader = glCreateShader;
  1319. _glDeleteProgram = glDeleteProgram;
  1320. _glDeleteShader = glDeleteShader;
  1321. _glDetachShader = glDetachShader;
  1322. _glDisableVertexAttribArray = glDisableVertexAttribArray;
  1323. _glEnableVertexAttribArray = glEnableVertexAttribArray;
  1324. _glGetActiveAttrib = glGetActiveAttrib;
  1325. _glGetActiveUniform = glGetActiveUniform;
  1326. _glGetAttribLocation = glGetAttribLocation;
  1327. _glGetProgramiv = glGetProgramiv;
  1328. _glGetProgramInfoLog = glGetProgramInfoLog;
  1329. _glGetShaderiv = glGetShaderiv;
  1330. _glGetShaderInfoLog = glGetShaderInfoLog;
  1331. _glGetUniformLocation = glGetUniformLocation;
  1332. _glLinkProgram = glLinkProgram;
  1333. _glShaderSource = (PFNGLSHADERSOURCEPROC_P) glShaderSource;
  1334. _glUseProgram = glUseProgram;
  1335. _glUniform4f = glUniform4f;
  1336. _glUniform1i = glUniform1i;
  1337. _glUniform1fv = glUniform1fv;
  1338. _glUniform2fv = glUniform2fv;
  1339. _glUniform3fv = glUniform3fv;
  1340. _glUniform4fv = glUniform4fv;
  1341. _glUniformMatrix3fv = glUniformMatrix3fv;
  1342. _glUniformMatrix4fv = glUniformMatrix4fv;
  1343. _glValidateProgram = glValidateProgram;
  1344. _glVertexAttrib4fv = glVertexAttrib4fv;
  1345. _glVertexAttrib4dv = NULL;
  1346. _glVertexAttribPointer = glVertexAttribPointer;
  1347. _glVertexAttribIPointer = NULL;
  1348. _glVertexAttribLPointer = NULL;
  1349. #endif
  1350. #ifndef OPENGLES_1
  1351. // We need to have a default shader to apply in case
  1352. // something didn't happen to have a shader applied, or
  1353. // if it failed to compile. This default shader just outputs
  1354. // a red color, indicating that something went wrong.
  1355. if (_default_shader == NULL && core_profile) {
  1356. _default_shader = Shader::make(Shader::SL_GLSL, default_vshader, default_fshader);
  1357. }
  1358. #endif
  1359. #ifndef OPENGLES
  1360. // Check for uniform buffers.
  1361. if (is_at_least_gl_version(3, 1) || has_extension("GL_ARB_uniform_buffer_object")) {
  1362. _supports_uniform_buffers = true;
  1363. _glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC)
  1364. get_extension_func("glGetActiveUniformsiv");
  1365. _glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)
  1366. get_extension_func("glGetActiveUniformBlockiv");
  1367. _glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)
  1368. get_extension_func("glGetActiveUniformBlockName");
  1369. } else {
  1370. _supports_uniform_buffers = false;
  1371. }
  1372. #else
  1373. _supports_uniform_buffers = false;
  1374. #endif
  1375. // Check whether we support geometry instancing and instanced vertex attribs.
  1376. #if defined(OPENGLES_1)
  1377. _supports_vertex_attrib_divisor = false;
  1378. _supports_geometry_instancing = false;
  1379. #elif defined(OPENGLES_2)
  1380. if (has_extension("GL_ANGLE_instanced_arrays")) {
  1381. // This extension has both things in one.
  1382. #ifdef __EMSCRIPTEN__
  1383. // Work around bug - it doesn't allow ANGLE suffix in getProcAddress.
  1384. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1385. get_extension_func("glVertexAttribDivisor");
  1386. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1387. get_extension_func("glDrawArraysInstanced");
  1388. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1389. get_extension_func("glDrawElementsInstanced");
  1390. #else
  1391. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1392. get_extension_func("glVertexAttribDivisorANGLE");
  1393. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1394. get_extension_func("glDrawArraysInstancedANGLE");
  1395. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1396. get_extension_func("glDrawElementsInstancedANGLE");
  1397. #endif
  1398. _supports_vertex_attrib_divisor = true;
  1399. _supports_geometry_instancing = true;
  1400. } else {
  1401. // Check separately for geometry instancing and instanced attribs.
  1402. if (has_extension("GL_EXT_draw_instanced")) {
  1403. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1404. get_extension_func("glDrawArraysInstancedEXT");
  1405. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1406. get_extension_func("glDrawElementsInstancedEXT");
  1407. _supports_geometry_instancing = true;
  1408. } else if (has_extension("GL_NV_draw_instanced")) {
  1409. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1410. get_extension_func("glDrawArraysInstancedNV");
  1411. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1412. get_extension_func("glDrawElementsInstancedNV");
  1413. _supports_geometry_instancing = true;
  1414. } else {
  1415. _supports_geometry_instancing = false;
  1416. }
  1417. if (has_extension("GL_EXT_instanced_arrays")) {
  1418. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1419. get_extension_func("glVertexAttribDivisorEXT");
  1420. _supports_vertex_attrib_divisor = true;
  1421. } else if (has_extension("GL_NV_instanced_arrays")) {
  1422. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1423. get_extension_func("glVertexAttribDivisorNV");
  1424. _supports_vertex_attrib_divisor = true;
  1425. } else {
  1426. _supports_vertex_attrib_divisor = false;
  1427. }
  1428. }
  1429. #else
  1430. if (is_at_least_gl_version(3, 3)) {
  1431. // This feature is in OpenGL core as of 3.3.
  1432. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1433. get_extension_func("glVertexAttribDivisor");
  1434. _supports_vertex_attrib_divisor = true;
  1435. } else if (has_extension("GL_ARB_instanced_arrays")) {
  1436. _glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)
  1437. get_extension_func("glVertexAttribDivisorARB");
  1438. _supports_vertex_attrib_divisor = true;
  1439. } else {
  1440. _supports_vertex_attrib_divisor = false;
  1441. }
  1442. // Some drivers expose one extension, some expose the other.
  1443. if (is_at_least_gl_version(3, 1)) {
  1444. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1445. get_extension_func("glDrawArraysInstanced");
  1446. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1447. get_extension_func("glDrawElementsInstanced");
  1448. _supports_geometry_instancing = true;
  1449. } else if (has_extension("GL_ARB_draw_instanced")) {
  1450. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1451. get_extension_func("glDrawArraysInstancedARB");
  1452. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1453. get_extension_func("glDrawElementsInstancedARB");
  1454. _supports_geometry_instancing = true;
  1455. } else if (has_extension("GL_EXT_draw_instanced")) {
  1456. _glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)
  1457. get_extension_func("glDrawArraysInstancedEXT");
  1458. _glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)
  1459. get_extension_func("glDrawElementsInstancedEXT");
  1460. _supports_geometry_instancing = true;
  1461. } else {
  1462. _glDrawElementsInstanced = 0;
  1463. _glDrawArraysInstanced = 0;
  1464. _supports_geometry_instancing = false;
  1465. }
  1466. #endif
  1467. #ifndef OPENGLES_1
  1468. if (_supports_geometry_instancing) {
  1469. if (_glDrawArraysInstanced == NULL || _glDrawElementsInstanced == NULL) {
  1470. GLCAT.warning()
  1471. << "Geometry instancing advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1472. _supports_geometry_instancing = false;
  1473. }
  1474. }
  1475. if (_supports_vertex_attrib_divisor) {
  1476. if (_glVertexAttribDivisor == NULL) {
  1477. GLCAT.warning()
  1478. << "Instanced vertex arrays advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1479. _supports_vertex_attrib_divisor = false;
  1480. }
  1481. }
  1482. #endif
  1483. #ifdef OPENGLES_2
  1484. // In OpenGL ES 2.x, FBO's are supported in the core.
  1485. _supports_framebuffer_object = true;
  1486. _glIsRenderbuffer = glIsRenderbuffer;
  1487. _glBindRenderbuffer = glBindRenderbuffer;
  1488. _glDeleteRenderbuffers = glDeleteRenderbuffers;
  1489. _glGenRenderbuffers = glGenRenderbuffers;
  1490. _glRenderbufferStorage = glRenderbufferStorage;
  1491. _glGetRenderbufferParameteriv = glGetRenderbufferParameteriv;
  1492. _glIsFramebuffer = glIsFramebuffer;
  1493. _glBindFramebuffer = glBindFramebuffer;
  1494. _glDeleteFramebuffers = glDeleteFramebuffers;
  1495. _glGenFramebuffers = glGenFramebuffers;
  1496. _glCheckFramebufferStatus = glCheckFramebufferStatus;
  1497. _glFramebufferTexture1D = NULL;
  1498. _glFramebufferTexture2D = glFramebufferTexture2D;
  1499. _glFramebufferRenderbuffer = glFramebufferRenderbuffer;
  1500. _glGetFramebufferAttachmentParameteriv = glGetFramebufferAttachmentParameteriv;
  1501. _glGenerateMipmap = glGenerateMipmap;
  1502. #else
  1503. //TODO: add ARB/3.0 version
  1504. _supports_framebuffer_object = false;
  1505. if (has_extension("GL_EXT_framebuffer_object")) {
  1506. _supports_framebuffer_object = true;
  1507. _glIsRenderbuffer = (PFNGLISRENDERBUFFEREXTPROC)
  1508. get_extension_func("glIsRenderbufferEXT");
  1509. _glBindRenderbuffer = (PFNGLBINDRENDERBUFFEREXTPROC)
  1510. get_extension_func("glBindRenderbufferEXT");
  1511. _glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSEXTPROC)
  1512. get_extension_func("glDeleteRenderbuffersEXT");
  1513. _glGenRenderbuffers = (PFNGLGENRENDERBUFFERSEXTPROC)
  1514. get_extension_func("glGenRenderbuffersEXT");
  1515. _glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEEXTPROC)
  1516. get_extension_func("glRenderbufferStorageEXT");
  1517. _glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC)
  1518. get_extension_func("glGetRenderbufferParameterivEXT");
  1519. _glIsFramebuffer = (PFNGLISFRAMEBUFFEREXTPROC)
  1520. get_extension_func("glIsFramebufferEXT");
  1521. _glBindFramebuffer = (PFNGLBINDFRAMEBUFFEREXTPROC)
  1522. get_extension_func("glBindFramebufferEXT");
  1523. _glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSEXTPROC)
  1524. get_extension_func("glDeleteFramebuffersEXT");
  1525. _glGenFramebuffers = (PFNGLGENFRAMEBUFFERSEXTPROC)
  1526. get_extension_func("glGenFramebuffersEXT");
  1527. _glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC)
  1528. get_extension_func("glCheckFramebufferStatusEXT");
  1529. _glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DEXTPROC)
  1530. get_extension_func("glFramebufferTexture1DEXT");
  1531. _glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DEXTPROC)
  1532. get_extension_func("glFramebufferTexture2DEXT");
  1533. _glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DEXTPROC)
  1534. get_extension_func("glFramebufferTexture3DEXT");
  1535. _glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC)
  1536. get_extension_func("glFramebufferRenderbufferEXT");
  1537. _glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC)
  1538. get_extension_func("glGetFramebufferAttachmentParameterivEXT");
  1539. _glGenerateMipmap = (PFNGLGENERATEMIPMAPEXTPROC)
  1540. get_extension_func("glGenerateMipmapEXT");
  1541. }
  1542. #ifdef OPENGLES
  1543. else if (has_extension("GL_OES_framebuffer_object")) {
  1544. _supports_framebuffer_object = true;
  1545. _glIsRenderbuffer = (PFNGLISRENDERBUFFEROESPROC)
  1546. get_extension_func("glIsRenderbufferOES");
  1547. _glBindRenderbuffer = (PFNGLBINDRENDERBUFFEROESPROC)
  1548. get_extension_func("glBindRenderbufferOES");
  1549. _glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSOESPROC)
  1550. get_extension_func("glDeleteRenderbuffersOES");
  1551. _glGenRenderbuffers = (PFNGLGENRENDERBUFFERSOESPROC)
  1552. get_extension_func("glGenRenderbuffersOES");
  1553. _glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEOESPROC)
  1554. get_extension_func("glRenderbufferStorageOES");
  1555. _glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVOESPROC)
  1556. get_extension_func("glGetRenderbufferParameterivOES");
  1557. _glIsFramebuffer = (PFNGLISFRAMEBUFFEROESPROC)
  1558. get_extension_func("glIsFramebufferOES");
  1559. _glBindFramebuffer = (PFNGLBINDFRAMEBUFFEROESPROC)
  1560. get_extension_func("glBindFramebufferOES");
  1561. _glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSOESPROC)
  1562. get_extension_func("glDeleteFramebuffersOES");
  1563. _glGenFramebuffers = (PFNGLGENFRAMEBUFFERSOESPROC)
  1564. get_extension_func("glGenFramebuffersOES");
  1565. _glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSOESPROC)
  1566. get_extension_func("glCheckFramebufferStatusOES");
  1567. _glFramebufferTexture1D = NULL;
  1568. _glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DOESPROC)
  1569. get_extension_func("glFramebufferTexture2DOES");
  1570. _glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFEROESPROC)
  1571. get_extension_func("glFramebufferRenderbufferOES");
  1572. _glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVOESPROC)
  1573. get_extension_func("glGetFramebufferAttachmentParameterivOES");
  1574. _glGenerateMipmap = (PFNGLGENERATEMIPMAPOESPROC)
  1575. get_extension_func("glGenerateMipmapOES");
  1576. }
  1577. #endif // OPENGLES
  1578. #endif
  1579. _supports_framebuffer_multisample = false;
  1580. if ( has_extension("GL_EXT_framebuffer_multisample") ) {
  1581. _supports_framebuffer_multisample = true;
  1582. _glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC)
  1583. get_extension_func("glRenderbufferStorageMultisampleEXT");
  1584. }
  1585. #ifndef OPENGLES
  1586. _supports_framebuffer_multisample_coverage_nv = false;
  1587. if ( has_extension("GL_NV_framebuffer_multisample_coverage") ) {
  1588. _supports_framebuffer_multisample_coverage_nv = true;
  1589. _glRenderbufferStorageMultisampleCoverage = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLECOVERAGENVPROC)
  1590. get_extension_func("glRenderbufferStorageMultisampleCoverageNV");
  1591. }
  1592. #endif
  1593. #ifndef OPENGLES_1
  1594. _supports_framebuffer_blit = false;
  1595. if ( has_extension("GL_EXT_framebuffer_blit") ) {
  1596. _supports_framebuffer_blit = true;
  1597. _glBlitFramebuffer = (PFNGLBLITFRAMEBUFFEREXTPROC)
  1598. get_extension_func("glBlitFramebufferEXT");
  1599. }
  1600. #endif
  1601. #if defined(OPENGLES_1)
  1602. _glDrawBuffers = NULL;
  1603. _glClearBufferfv = NULL;
  1604. _max_color_targets = 1;
  1605. #elif defined(OPENGLES_2)
  1606. if (has_extension("GL_EXT_draw_buffers")) {
  1607. _glDrawBuffers = (PFNGLDRAWBUFFERSPROC)
  1608. get_extension_func("glDrawBuffersEXT");
  1609. } else if (has_extension("GL_NV_draw_buffers")) {
  1610. _glDrawBuffers = (PFNGLDRAWBUFFERSPROC)
  1611. get_extension_func("glDrawBuffersNV");
  1612. }
  1613. #else
  1614. if (is_at_least_gl_version(2, 0)) {
  1615. _glDrawBuffers = (PFNGLDRAWBUFFERSPROC)
  1616. get_extension_func("glDrawBuffers");
  1617. } else if (has_extension("GL_ARB_draw_buffers")) {
  1618. _glDrawBuffers = (PFNGLDRAWBUFFERSPROC)
  1619. get_extension_func("glDrawBuffersARB");
  1620. }
  1621. #endif
  1622. #ifndef OPENGLES_1
  1623. _max_color_targets = 1;
  1624. if (_glDrawBuffers != 0) {
  1625. GLint max_draw_buffers = 0;
  1626. glGetIntegerv(GL_MAX_DRAW_BUFFERS, &max_draw_buffers);
  1627. _max_color_targets = max_draw_buffers;
  1628. }
  1629. #endif // !OPENGLES_1
  1630. #ifndef OPENGLES
  1631. if (is_at_least_gl_version(3, 0)) {
  1632. _glClearBufferfv = (PFNGLCLEARBUFFERFVPROC)
  1633. get_extension_func("glClearBufferfv");
  1634. } else {
  1635. _glClearBufferfv = NULL;
  1636. }
  1637. #endif // !OPENGLES
  1638. #ifndef OPENGLES
  1639. _supports_viewport_arrays = false;
  1640. if (is_at_least_gl_version(4, 1) || has_extension("GL_ARB_viewport_array")) {
  1641. _glViewportArrayv = (PFNGLVIEWPORTARRAYVPROC)
  1642. get_extension_func("glViewportArrayv");
  1643. _glScissorArrayv = (PFNGLSCISSORARRAYVPROC)
  1644. get_extension_func("glScissorArrayv");
  1645. _glDepthRangeArrayv = (PFNGLDEPTHRANGEARRAYVPROC)
  1646. get_extension_func("glDepthRangeArrayv");
  1647. if (_glViewportArrayv == NULL || _glScissorArrayv == NULL || _glDepthRangeArrayv == NULL) {
  1648. GLCAT.warning()
  1649. << "Viewport arrays advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1650. } else {
  1651. _supports_viewport_arrays = true;
  1652. }
  1653. }
  1654. #endif // !OPENGLES
  1655. _max_fb_samples = 0;
  1656. if (_supports_framebuffer_multisample) {
  1657. GLint max_samples;
  1658. glGetIntegerv(GL_MAX_SAMPLES_EXT, &max_samples);
  1659. _max_fb_samples = max_samples;
  1660. }
  1661. _supports_occlusion_query = false;
  1662. #ifndef OPENGLES
  1663. if (gl_support_occlusion_query) {
  1664. if (is_at_least_gl_version(1, 5)) {
  1665. _supports_occlusion_query = true;
  1666. _glGenQueries = (PFNGLGENQUERIESPROC)
  1667. get_extension_func("glGenQueries");
  1668. _glBeginQuery = (PFNGLBEGINQUERYPROC)
  1669. get_extension_func("glBeginQuery");
  1670. _glEndQuery = (PFNGLENDQUERYPROC)
  1671. get_extension_func("glEndQuery");
  1672. _glDeleteQueries = (PFNGLDELETEQUERIESPROC)
  1673. get_extension_func("glDeleteQueries");
  1674. _glGetQueryiv = (PFNGLGETQUERYIVPROC)
  1675. get_extension_func("glGetQueryiv");
  1676. _glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)
  1677. get_extension_func("glGetQueryObjectuiv");
  1678. } else if (has_extension("GL_ARB_occlusion_query")) {
  1679. _supports_occlusion_query = true;
  1680. _glGenQueries = (PFNGLGENQUERIESPROC)
  1681. get_extension_func("glGenQueriesARB");
  1682. _glBeginQuery = (PFNGLBEGINQUERYPROC)
  1683. get_extension_func("glBeginQueryARB");
  1684. _glEndQuery = (PFNGLENDQUERYPROC)
  1685. get_extension_func("glEndQueryARB");
  1686. _glDeleteQueries = (PFNGLDELETEQUERIESPROC)
  1687. get_extension_func("glDeleteQueriesARB");
  1688. _glGetQueryiv = (PFNGLGETQUERYIVPROC)
  1689. get_extension_func("glGetQueryivARB");
  1690. _glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)
  1691. get_extension_func("glGetQueryObjectuivARB");
  1692. }
  1693. }
  1694. if (_supports_occlusion_query) {
  1695. if (_glGenQueries == NULL || _glBeginQuery == NULL ||
  1696. _glEndQuery == NULL || _glDeleteQueries == NULL ||
  1697. _glGetQueryiv == NULL || _glGetQueryObjectuiv == NULL) {
  1698. GLCAT.warning()
  1699. << "Occlusion queries advertised as supported by OpenGL runtime, but could not get pointers to extension functions.\n";
  1700. _supports_occlusion_query = false;
  1701. } else {
  1702. GLint num_bits;
  1703. _glGetQueryiv(GL_SAMPLES_PASSED, GL_QUERY_COUNTER_BITS, &num_bits);
  1704. if (num_bits == 0) {
  1705. _supports_occlusion_query = false;
  1706. }
  1707. if (GLCAT.is_debug()) {
  1708. GLCAT.debug()
  1709. << "Occlusion query counter provides " << num_bits << " bits.\n";
  1710. }
  1711. }
  1712. }
  1713. #endif // !OPENGLES
  1714. _supports_timer_query = false;
  1715. #if defined(DO_PSTATS) && !defined(OPENGLES)
  1716. if (is_at_least_gl_version(3, 3) || has_extension("GL_ARB_timer_query")) {
  1717. _supports_timer_query = true;
  1718. _glQueryCounter = (PFNGLQUERYCOUNTERPROC)
  1719. get_extension_func("glQueryCounter");
  1720. _glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC)
  1721. get_extension_func("glGetQueryObjecti64v");
  1722. _glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC)
  1723. get_extension_func("glGetQueryObjectui64v");
  1724. _glGetInteger64v = (PFNGLGETINTEGER64VPROC)
  1725. get_extension_func("glGetInteger64v");
  1726. }
  1727. #endif
  1728. #ifdef OPENGLES_2
  1729. // In OpenGL ES 2.x, this is supported in the core.
  1730. _glBlendEquation = glBlendEquation;
  1731. #else
  1732. _glBlendEquation = NULL;
  1733. bool supports_blend_equation = false;
  1734. if (is_at_least_gl_version(1, 2)) {
  1735. supports_blend_equation = true;
  1736. _glBlendEquation = (PFNGLBLENDEQUATIONPROC)
  1737. get_extension_func("glBlendEquation");
  1738. } else if (has_extension("GL_OES_blend_subtract")) {
  1739. supports_blend_equation = true;
  1740. _glBlendEquation = (PFNGLBLENDEQUATIONPROC)
  1741. get_extension_func("glBlendEquationOES");
  1742. } else if (has_extension("GL_EXT_blend_minmax")) {
  1743. supports_blend_equation = true;
  1744. _glBlendEquation = (PFNGLBLENDEQUATIONPROC)
  1745. get_extension_func("glBlendEquationEXT");
  1746. }
  1747. if (supports_blend_equation && _glBlendEquation == NULL) {
  1748. GLCAT.warning()
  1749. << "BlendEquation advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  1750. }
  1751. if (_glBlendEquation == NULL) {
  1752. _glBlendEquation = null_glBlendEquation;
  1753. }
  1754. #endif
  1755. #ifdef OPENGLES_2
  1756. // In OpenGL ES 2.x, this is supported in the core.
  1757. _glBlendColor = glBlendColor;
  1758. #else
  1759. _glBlendColor = NULL;
  1760. bool supports_blend_color = false;
  1761. if (is_at_least_gl_version(1, 2)) {
  1762. supports_blend_color = true;
  1763. _glBlendColor = (PFNGLBLENDCOLORPROC)
  1764. get_extension_func("glBlendColor");
  1765. } else if (has_extension("GL_EXT_blend_color")) {
  1766. supports_blend_color = true;
  1767. _glBlendColor = (PFNGLBLENDCOLORPROC)
  1768. get_extension_func("glBlendColorEXT");
  1769. }
  1770. if (supports_blend_color && _glBlendColor == NULL) {
  1771. GLCAT.warning()
  1772. << "BlendColor advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  1773. }
  1774. if (_glBlendColor == NULL) {
  1775. _glBlendColor = null_glBlendColor;
  1776. }
  1777. #endif
  1778. #ifdef OPENGLES
  1779. _edge_clamp = GL_CLAMP_TO_EDGE;
  1780. #else
  1781. _edge_clamp = GL_CLAMP;
  1782. if (has_extension("GL_SGIS_texture_edge_clamp") ||
  1783. is_at_least_gl_version(1, 2) || is_at_least_gles_version(1, 1)) {
  1784. _edge_clamp = GL_CLAMP_TO_EDGE;
  1785. }
  1786. #endif
  1787. _border_clamp = _edge_clamp;
  1788. #ifndef OPENGLES
  1789. if (gl_support_clamp_to_border &&
  1790. (has_extension("GL_ARB_texture_border_clamp") ||
  1791. is_at_least_gl_version(1, 3))) {
  1792. _border_clamp = GL_CLAMP_TO_BORDER;
  1793. }
  1794. #endif
  1795. #ifdef OPENGLES_2
  1796. _mirror_repeat = GL_MIRRORED_REPEAT;
  1797. #else
  1798. _mirror_repeat = GL_REPEAT;
  1799. if (has_extension("GL_ARB_texture_mirrored_repeat") ||
  1800. is_at_least_gl_version(1, 4) ||
  1801. has_extension("GL_OES_texture_mirrored_repeat")) {
  1802. _mirror_repeat = GL_MIRRORED_REPEAT;
  1803. }
  1804. #endif
  1805. _mirror_clamp = _edge_clamp;
  1806. _mirror_edge_clamp = _edge_clamp;
  1807. _mirror_border_clamp = _border_clamp;
  1808. #ifndef OPENGLES
  1809. if (has_extension("GL_EXT_texture_mirror_clamp")) {
  1810. _mirror_clamp = GL_MIRROR_CLAMP_EXT;
  1811. _mirror_edge_clamp = GL_MIRROR_CLAMP_TO_EDGE_EXT;
  1812. _mirror_border_clamp = GL_MIRROR_CLAMP_TO_BORDER_EXT;
  1813. }
  1814. #endif
  1815. if (_supports_multisample) {
  1816. GLint sample_buffers = 0;
  1817. glGetIntegerv(GL_SAMPLE_BUFFERS, &sample_buffers);
  1818. if (sample_buffers != 1) {
  1819. // Even if the API supports multisample, we might have ended up
  1820. // with a framebuffer that doesn't have any multisample bits.
  1821. // (It's also possible the graphics card doesn't provide any
  1822. // framebuffers with multisample.) In this case, we don't
  1823. // really support the multisample API's, since they won't do
  1824. // anything.
  1825. _supports_multisample = false;
  1826. }
  1827. }
  1828. GLint max_texture_size = 0;
  1829. GLint max_3d_texture_size = 0;
  1830. GLint max_2d_texture_array_layers = 0;
  1831. GLint max_cube_map_size = 0;
  1832. GLint max_buffer_texture_size = 0;
  1833. glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_texture_size);
  1834. _max_texture_dimension = max_texture_size;
  1835. if (_supports_3d_texture) {
  1836. #ifndef OPENGLES_1
  1837. glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max_3d_texture_size);
  1838. #endif
  1839. _max_3d_texture_dimension = max_3d_texture_size;
  1840. } else {
  1841. _max_3d_texture_dimension = 0;
  1842. }
  1843. #ifndef OPENGLES
  1844. if(_supports_2d_texture_array) {
  1845. glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS_EXT, &max_2d_texture_array_layers);
  1846. _max_2d_texture_array_layers = max_2d_texture_array_layers;
  1847. }
  1848. #endif
  1849. if (_supports_cube_map) {
  1850. glGetIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &max_cube_map_size);
  1851. _max_cube_map_dimension = max_cube_map_size;
  1852. } else {
  1853. _max_cube_map_dimension = 0;
  1854. }
  1855. #ifndef OPENGLES
  1856. if (_supports_buffer_texture) {
  1857. glGetIntegerv(GL_MAX_TEXTURE_BUFFER_SIZE, &max_buffer_texture_size);
  1858. _max_buffer_texture_size = max_buffer_texture_size;
  1859. } else {
  1860. _max_buffer_texture_size = 0;
  1861. }
  1862. #endif // !OPENGLES
  1863. GLint max_elements_vertices = 0, max_elements_indices = 0;
  1864. #ifndef OPENGLES
  1865. glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, &max_elements_vertices);
  1866. glGetIntegerv(GL_MAX_ELEMENTS_INDICES, &max_elements_indices);
  1867. if (max_elements_vertices > 0) {
  1868. _max_vertices_per_array = max_elements_vertices;
  1869. }
  1870. if (max_elements_indices > 0) {
  1871. _max_vertices_per_primitive = max_elements_indices;
  1872. }
  1873. #endif // OPENGLES
  1874. if (GLCAT.is_debug()) {
  1875. GLCAT.debug()
  1876. << "max texture dimension = " << _max_texture_dimension
  1877. << ", max 3d texture = " << _max_3d_texture_dimension
  1878. << ", max 2d texture array = " << max_2d_texture_array_layers
  1879. << ", max cube map = " << _max_cube_map_dimension << "\n";
  1880. GLCAT.debug()
  1881. << "max_elements_vertices = " << max_elements_vertices
  1882. << ", max_elements_indices = " << max_elements_indices << "\n";
  1883. if (_supports_buffers) {
  1884. if (vertex_buffers) {
  1885. GLCAT.debug()
  1886. << "vertex buffer objects are supported.\n";
  1887. } else {
  1888. GLCAT.debug()
  1889. << "vertex buffer objects are supported (but not enabled).\n";
  1890. }
  1891. } else {
  1892. GLCAT.debug()
  1893. << "vertex buffer objects are NOT supported.\n";
  1894. }
  1895. #ifdef SUPPORT_IMMEDIATE_MODE
  1896. if (!vertex_arrays) {
  1897. GLCAT.debug()
  1898. << "immediate mode commands will be used instead of vertex arrays.\n";
  1899. }
  1900. #endif
  1901. if (!_supports_compressed_texture) {
  1902. GLCAT.debug()
  1903. << "Texture compression is not supported.\n";
  1904. } else {
  1905. GLint num_compressed_formats = 0;
  1906. glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &num_compressed_formats);
  1907. if (num_compressed_formats == 0) {
  1908. GLCAT.debug()
  1909. << "No specific compressed texture formats are supported.\n";
  1910. } else {
  1911. #ifndef NDEBUG
  1912. GLCAT.debug()
  1913. << "Supported compressed texture formats:\n";
  1914. GLint *formats = (GLint *)alloca(num_compressed_formats * sizeof(GLint));
  1915. glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS, formats);
  1916. for (int i = 0; i < num_compressed_formats; ++i) {
  1917. const char *format_str = get_compressed_format_string(formats[i]);
  1918. if (format_str != NULL) {
  1919. GLCAT.debug(false) << " " << format_str << '\n';
  1920. } else {
  1921. GLCAT.debug(false)
  1922. << " Unknown compressed format 0x" << hex << formats[i]
  1923. << dec << "\n";
  1924. }
  1925. }
  1926. #endif
  1927. }
  1928. }
  1929. }
  1930. _num_active_texture_stages = 0;
  1931. // Check availability of anisotropic texture filtering.
  1932. _supports_anisotropy = false;
  1933. _max_anisotropy = 1.0;
  1934. if (has_extension("GL_EXT_texture_filter_anisotropic")) {
  1935. GLfloat max_anisotropy;
  1936. glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy);
  1937. _max_anisotropy = (PN_stdfloat)max_anisotropy;
  1938. _supports_anisotropy = true;
  1939. }
  1940. // Check availability of image read/write functionality in shaders.
  1941. _max_image_units = 0;
  1942. #ifndef OPENGLES
  1943. if (is_at_least_gl_version(4, 2) || has_extension("GL_ARB_shader_image_load_store")) {
  1944. _glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)
  1945. get_extension_func("glBindImageTexture");
  1946. _glMemoryBarrier = (PFNGLMEMORYBARRIERPROC)
  1947. get_extension_func("glMemoryBarrier");
  1948. glGetIntegerv(GL_MAX_IMAGE_UNITS, &_max_image_units);
  1949. } else if (has_extension("GL_EXT_shader_image_load_store")) {
  1950. _glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)
  1951. get_extension_func("glBindImageTextureEXT");
  1952. _glMemoryBarrier = (PFNGLMEMORYBARRIERPROC)
  1953. get_extension_func("glMemoryBarrierEXT");
  1954. glGetIntegerv(GL_MAX_IMAGE_UNITS_EXT, &_max_image_units);
  1955. } else {
  1956. _glBindImageTexture = NULL;
  1957. _glMemoryBarrier = NULL;
  1958. }
  1959. _supports_sampler_objects = false;
  1960. #ifndef OPENGLES
  1961. if (gl_support_sampler_objects &&
  1962. ((is_at_least_gl_version(3, 3) || has_extension("GL_ARB_sampler_objects")))) {
  1963. _glGenSamplers = (PFNGLGENSAMPLERSPROC) get_extension_func("glGenSamplers");
  1964. _glDeleteSamplers = (PFNGLDELETESAMPLERSPROC) get_extension_func("glDeleteSamplers");
  1965. _glBindSampler = (PFNGLBINDSAMPLERPROC) get_extension_func("glBindSampler");
  1966. _glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC) get_extension_func("glSamplerParameteri");
  1967. _glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC) get_extension_func("glSamplerParameteriv");
  1968. _glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC) get_extension_func("glSamplerParameterf");
  1969. _glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC) get_extension_func("glSamplerParameterfv");
  1970. if (_glGenSamplers == NULL || _glDeleteSamplers == NULL ||
  1971. _glBindSampler == NULL || _glSamplerParameteri == NULL ||
  1972. _glSamplerParameteriv == NULL || _glSamplerParameterf == NULL ||
  1973. _glSamplerParameterfv == NULL) {
  1974. GLCAT.warning()
  1975. << "GL_ARB_sampler_objects advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  1976. } else {
  1977. _supports_sampler_objects = true;
  1978. }
  1979. }
  1980. #endif // OPENGLES
  1981. // Check availability of multi-bind functions.
  1982. _supports_multi_bind = false;
  1983. if (is_at_least_gl_version(4, 4) || has_extension("GL_ARB_multi_bind")) {
  1984. _glBindTextures = (PFNGLBINDTEXTURESPROC)
  1985. get_extension_func("glBindTextures");
  1986. _glBindImageTextures = (PFNGLBINDIMAGETEXTURESPROC)
  1987. get_extension_func("glBindImageTextures");
  1988. #ifndef OPENGLES
  1989. if (_supports_sampler_objects) {
  1990. _glBindSamplers = (PFNGLBINDSAMPLERSPROC)
  1991. get_extension_func("glBindSamplers");
  1992. }
  1993. #endif // OPENGLES
  1994. if (_glBindTextures != NULL && _glBindImageTextures != NULL) {
  1995. _supports_multi_bind = true;
  1996. } else {
  1997. GLCAT.warning()
  1998. << "ARB_multi_bind advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  1999. }
  2000. }
  2001. if (is_at_least_gl_version(4, 3) || has_extension("GL_ARB_internalformat_query2")) {
  2002. _glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC)
  2003. get_extension_func("glGetInternalformativ");
  2004. if (_glGetInternalformativ == NULL) {
  2005. GLCAT.warning()
  2006. << "ARB_internalformat_query2 advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  2007. }
  2008. }
  2009. _supports_bindless_texture = false;
  2010. if (has_extension("GL_ARB_bindless_texture")) {
  2011. _glGetTextureHandle = (PFNGLGETTEXTUREHANDLEPROC)
  2012. get_extension_func("glGetTextureHandleARB");
  2013. _glGetTextureSamplerHandle = (PFNGLGETTEXTURESAMPLERHANDLEPROC)
  2014. get_extension_func("glGetTextureSamplerHandleARB");
  2015. _glMakeTextureHandleResident = (PFNGLMAKETEXTUREHANDLERESIDENTPROC)
  2016. get_extension_func("glMakeTextureHandleResidentARB");
  2017. _glUniformHandleui64 = (PFNGLUNIFORMHANDLEUI64PROC)
  2018. get_extension_func("glUniformHandleui64ARB");
  2019. if (_glGetTextureHandle == NULL || _glMakeTextureHandleResident == NULL ||
  2020. _glUniformHandleui64 == NULL) {
  2021. GLCAT.warning()
  2022. << "GL_ARB_bindless_texture advertised as supported by OpenGL runtime, but could not get pointers to extension function.\n";
  2023. } else {
  2024. _supports_bindless_texture = true;
  2025. }
  2026. }
  2027. #endif
  2028. #ifndef OPENGLES
  2029. _supports_get_program_binary = false;
  2030. if (is_at_least_gl_version(4, 1) || has_extension("GL_ARB_get_program_binary")) {
  2031. _glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC)
  2032. get_extension_func("glGetProgramBinary");
  2033. _glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)
  2034. get_extension_func("glProgramParameteri");
  2035. if (_glGetProgramBinary != NULL && _glProgramParameteri != NULL) {
  2036. _supports_get_program_binary = true;
  2037. }
  2038. }
  2039. #endif
  2040. report_my_gl_errors();
  2041. if (core_profile) {
  2042. //TODO: better detection mechanism?
  2043. _supports_stencil = true;
  2044. }
  2045. #ifdef SUPPORT_FIXED_FUNCTION
  2046. else if (support_stencil) {
  2047. GLint num_stencil_bits;
  2048. glGetIntegerv(GL_STENCIL_BITS, &num_stencil_bits);
  2049. _supports_stencil = (num_stencil_bits != 0);
  2050. }
  2051. #endif
  2052. _supports_stencil_wrap =
  2053. has_extension("GL_EXT_stencil_wrap") || has_extension("GL_OES_stencil_wrap");
  2054. _supports_two_sided_stencil = false;
  2055. #ifndef OPENGLES
  2056. if (has_extension("GL_EXT_stencil_two_side")) {
  2057. _glActiveStencilFaceEXT = (PFNGLACTIVESTENCILFACEEXTPROC)
  2058. get_extension_func("glActiveStencilFaceEXT");
  2059. _supports_two_sided_stencil = true;
  2060. } else {
  2061. _glActiveStencilFaceEXT = 0;
  2062. }
  2063. #endif
  2064. // Ensure the initial state is what we say it should be (in some
  2065. // cases, we don't want the GL default settings; in others, we have
  2066. // to force the point with some drivers that aren't strictly
  2067. // compliant w.r.t. initial settings).
  2068. glFrontFace(GL_CCW);
  2069. #ifndef OPENGLES_2
  2070. glDisable(GL_LINE_SMOOTH);
  2071. #endif
  2072. #ifdef SUPPORT_FIXED_FUNCTION
  2073. if (!core_profile) {
  2074. glDisable(GL_POINT_SMOOTH);
  2075. }
  2076. #endif
  2077. #ifndef OPENGLES
  2078. glDisable(GL_POLYGON_SMOOTH);
  2079. #endif // OPENGLES
  2080. #ifndef OPENGLES_2
  2081. if (_supports_multisample) {
  2082. glDisable(GL_MULTISAMPLE);
  2083. }
  2084. #endif
  2085. // Set up all the enabled/disabled flags to GL's known initial
  2086. // values: everything off.
  2087. _multisample_mode = 0;
  2088. _line_smooth_enabled = false;
  2089. _point_smooth_enabled = false;
  2090. _polygon_smooth_enabled = false;
  2091. _stencil_test_enabled = false;
  2092. _blend_enabled = false;
  2093. _depth_test_enabled = false;
  2094. _fog_enabled = false;
  2095. _alpha_test_enabled = false;
  2096. _polygon_offset_enabled = false;
  2097. _flat_shade_model = false;
  2098. _decal_level = 0;
  2099. _active_color_write_mask = ColorWriteAttrib::C_all;
  2100. _tex_gen_point_sprite = false;
  2101. #ifndef OPENGLES
  2102. // Dither is on by default in GL; let's turn it off
  2103. glDisable(GL_DITHER);
  2104. #endif // OPENGLES
  2105. _dithering_enabled = false;
  2106. #ifndef OPENGLES_1
  2107. _current_shader = (Shader *)NULL;
  2108. _current_shader_context = (ShaderContext *)NULL;
  2109. _vertex_array_shader = (Shader *)NULL;
  2110. _vertex_array_shader_context = (ShaderContext *)NULL;
  2111. _texture_binding_shader = (Shader *)NULL;
  2112. _texture_binding_shader_context = (ShaderContext *)NULL;
  2113. #endif
  2114. // Count the max number of lights
  2115. _max_lights = 0;
  2116. #ifdef SUPPORT_FIXED_FUNCTION
  2117. if (!core_profile) {
  2118. GLint max_lights = 0;
  2119. glGetIntegerv(GL_MAX_LIGHTS, &max_lights);
  2120. _max_lights = max_lights;
  2121. if (GLCAT.is_debug()) {
  2122. GLCAT.debug()
  2123. << "max lights = " << _max_lights << "\n";
  2124. }
  2125. }
  2126. #endif
  2127. // Count the max number of clipping planes
  2128. _max_clip_planes = 0;
  2129. #ifdef SUPPORT_FIXED_FUNCTION
  2130. if (!core_profile) {
  2131. GLint max_clip_planes = 0;
  2132. glGetIntegerv(GL_MAX_CLIP_PLANES, &max_clip_planes);
  2133. _max_clip_planes = max_clip_planes;
  2134. if (GLCAT.is_debug()) {
  2135. GLCAT.debug()
  2136. << "max clip planes = " << _max_clip_planes << "\n";
  2137. }
  2138. }
  2139. #endif
  2140. _max_texture_stages = 1;
  2141. #ifdef SUPPORT_FIXED_FUNCTION
  2142. if (supports_multitexture && !core_profile) {
  2143. GLint max_texture_stages = 0;
  2144. glGetIntegerv(GL_MAX_TEXTURE_UNITS, &max_texture_stages);
  2145. _max_texture_stages = max_texture_stages;
  2146. if (GLCAT.is_debug()) {
  2147. GLCAT.debug()
  2148. << "max texture stages = " << _max_texture_stages << "\n";
  2149. }
  2150. }
  2151. #endif
  2152. _current_vbuffer_index = 0;
  2153. _current_ibuffer_index = 0;
  2154. _current_vao_index = 0;
  2155. _current_fbo = 0;
  2156. _auto_antialias_mode = false;
  2157. _render_mode = RenderModeAttrib::M_filled;
  2158. _point_size = 1.0f;
  2159. _point_perspective = false;
  2160. report_my_gl_errors();
  2161. #ifdef SUPPORT_FIXED_FUNCTION
  2162. if (!core_profile) {
  2163. if (gl_cheap_textures) {
  2164. GLCAT.info()
  2165. << "Setting glHint() for fastest textures.\n";
  2166. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
  2167. }
  2168. // Use per-vertex fog if per-pixel fog requires SW renderer
  2169. glHint(GL_FOG_HINT, GL_DONT_CARE);
  2170. }
  2171. #endif
  2172. #ifdef SUPPORT_FIXED_FUNCTION
  2173. if (!core_profile) {
  2174. GLint num_red_bits = 0;
  2175. glGetIntegerv(GL_RED_BITS, &num_red_bits);
  2176. if (num_red_bits < 8) {
  2177. glEnable(GL_DITHER);
  2178. _dithering_enabled = true;
  2179. if (GLCAT.is_debug()) {
  2180. GLCAT.debug()
  2181. << "frame buffer depth = " << num_red_bits
  2182. << " bits/channel, enabling dithering\n";
  2183. }
  2184. }
  2185. }
  2186. #endif
  2187. _error_count = 0;
  2188. report_my_gl_errors();
  2189. #ifndef OPENGLES
  2190. if (_gl_shadlang_ver_major >= 4 || has_extension("GL_NV_gpu_program5")) {
  2191. // gp5fp - OpenGL fragment profile for GeForce 400 Series and up
  2192. _shader_model = SM_50;
  2193. } else if (_gl_shadlang_ver_major >= 3 ||
  2194. has_extension("GL_NV_gpu_program4")) {
  2195. // gp4fp - OpenGL fragment profile for G8x (GeForce 8xxx and up)
  2196. _shader_model = SM_40;
  2197. } else if (has_extension("GL_NV_fragment_program2")) {
  2198. // fp40 - OpenGL fragment profile for NV4x (GeForce 6xxx and 7xxx
  2199. // Series, NV4x-based Quadro FX, etc.)
  2200. _shader_model = SM_30;
  2201. } else if (has_extension("GL_NV_fragment_program")) {
  2202. // fp30 - OpenGL fragment profile for NV3x (GeForce FX, Quadro FX, etc.)
  2203. _shader_model = SM_2X;
  2204. } else if (_gl_shadlang_ver_major >= 1 ||
  2205. has_extension("GL_ARB_fragment_program")) {
  2206. // This OpenGL profile corresponds to the per-fragment
  2207. // functionality introduced by GeForce FX and other DirectX 9 GPUs.
  2208. _shader_model = SM_20;
  2209. } else if (has_extension("GL_NV_texture_shader2")) {
  2210. // fp20 - OpenGL fragment profile for NV2x (GeForce3, GeForce4 Ti,
  2211. // Quadro DCC, etc.)
  2212. _shader_model = SM_11;
  2213. } else {
  2214. // No shader support
  2215. _shader_model = SM_00;
  2216. }
  2217. // DisplayInformation may have better shader model detection
  2218. {
  2219. GraphicsPipe *pipe;
  2220. DisplayInformation *display_information;
  2221. pipe = this->get_pipe();
  2222. if (pipe) {
  2223. display_information = pipe->get_display_information ();
  2224. if (display_information) {
  2225. if (display_information->get_shader_model() > _shader_model) {
  2226. _shader_model = display_information->get_shader_model();
  2227. }
  2228. }
  2229. }
  2230. }
  2231. _auto_detect_shader_model = _shader_model;
  2232. if (GLCAT.is_debug()) {
  2233. #ifdef HAVE_CG
  2234. #if CG_VERSION_NUM >= 2200
  2235. GLCAT.debug() << "Supported Cg profiles:\n";
  2236. int num_profiles = cgGetNumSupportedProfiles();
  2237. for (int i = 0; i < num_profiles; ++i) {
  2238. CGprofile profile = cgGetSupportedProfile(i);
  2239. if (cgGLIsProfileSupported(profile)) {
  2240. GLCAT.debug() << " " << cgGetProfileString(profile) << "\n";
  2241. }
  2242. }
  2243. #endif // CG_VERSION_NUM >= 2200
  2244. #if CG_VERSION_NUM >= 3100
  2245. GLCAT.debug() << "Cg GLSL version = "
  2246. << cgGLGetGLSLVersionString(cgGLDetectGLSLVersion()) << "\n";
  2247. #endif
  2248. GLCAT.debug()
  2249. << "Cg latest vertex profile = "
  2250. << cgGetProfileString(cgGLGetLatestProfile(CG_GL_VERTEX)) << "\n";
  2251. GLCAT.debug()
  2252. << "Cg latest fragment profile = "
  2253. << cgGetProfileString(cgGLGetLatestProfile(CG_GL_FRAGMENT)) << "\n";
  2254. #if CG_VERSION_NUM >= 2000
  2255. GLCAT.debug()
  2256. << "Cg latest geometry profile = "
  2257. << cgGetProfileString(cgGLGetLatestProfile(CG_GL_GEOMETRY)) << "\n";
  2258. #endif
  2259. GLCAT.debug() << "basic-shaders-only " << basic_shaders_only << "\n";
  2260. GLCAT.debug()
  2261. << "Cg active vertex profile = "
  2262. << cgGetProfileString((CGprofile)_shader_caps._active_vprofile) << "\n";
  2263. GLCAT.debug()
  2264. << "Cg active fragment profile = "
  2265. << cgGetProfileString((CGprofile)_shader_caps._active_fprofile) << "\n";
  2266. GLCAT.debug()
  2267. << "Cg active geometry profile = "
  2268. << cgGetProfileString((CGprofile)_shader_caps._active_gprofile) << "\n";
  2269. #endif // HAVE_CG
  2270. GLCAT.debug() << "shader model = " << _shader_model << "\n";
  2271. }
  2272. #endif // !OPENGLES
  2273. // OpenGL core profile requires a VAO to be bound. It's a bit silly,
  2274. // because we can just bind a VAO and then forget about it.
  2275. #if !defined(OPENGLES)
  2276. if (core_profile) {
  2277. if (_supports_vao) {
  2278. _glGenVertexArrays(1, &_current_vao_index);
  2279. _glBindVertexArray(_current_vao_index);
  2280. } else {
  2281. GLCAT.error()
  2282. << "Core profile enabled, but vertex array objects not supported!\n";
  2283. }
  2284. }
  2285. #endif
  2286. // Now that the GSG has been initialized, make it available for
  2287. // optimizations.
  2288. add_gsg(this);
  2289. }
  2290. ////////////////////////////////////////////////////////////////////
  2291. // Function: GLGraphicsStateGuardian::finish
  2292. // Access: Public, Virtual
  2293. // Description: Force the graphics card to finish drawing before
  2294. // returning. !!!!!HACK WARNING!!!!
  2295. // glfinish does not actually wait for the graphics card to finish drawing
  2296. // only for draw calls to finish. Thus flip may not happene
  2297. // immediately. Instead we read a single pixel from
  2298. // the framebuffer. This forces the graphics card to
  2299. // finish drawing the frame before returning.
  2300. ////////////////////////////////////////////////////////////////////
  2301. void CLP(GraphicsStateGuardian)::
  2302. finish() {
  2303. // Rather than call glfinish which returns immediately if
  2304. // draw commands have been submitted, we will read a single pixel
  2305. // from the frame. That will force the graphics card to finish
  2306. // drawing before it is called
  2307. char data[4];
  2308. glReadPixels(0,0,1,1,GL_RGBA,GL_UNSIGNED_BYTE,&data);
  2309. //glFinish();
  2310. }
  2311. ////////////////////////////////////////////////////////////////////
  2312. // Function: GraphicsStateGuardian::clear
  2313. // Access: Public
  2314. // Description: Clears the framebuffer within the current
  2315. // DisplayRegion, according to the flags indicated by
  2316. // the given DrawableRegion object.
  2317. //
  2318. // This does not set the DisplayRegion first. You
  2319. // should call prepare_display_region() to specify the
  2320. // region you wish the clear operation to apply to.
  2321. ////////////////////////////////////////////////////////////////////
  2322. void CLP(GraphicsStateGuardian)::
  2323. clear(DrawableRegion *clearable) {
  2324. PStatGPUTimer timer(this, _clear_pcollector);
  2325. report_my_gl_errors();
  2326. if (!clearable->is_any_clear_active()) {
  2327. return;
  2328. }
  2329. //XXX rdb: Is this line really necessary?
  2330. set_state_and_transform(RenderState::make_empty(), _internal_transform);
  2331. int mask = 0;
  2332. #ifndef OPENGLES
  2333. if (_current_fbo != 0 && _glClearBufferfv != NULL) {
  2334. // We can use glClearBuffer to clear all the color attachments,
  2335. // which protects us from the overhead of having to call set_draw_buffer
  2336. // for every single attachment.
  2337. int index = 0;
  2338. if (_current_properties->get_color_bits() > 0) {
  2339. if (_current_properties->is_stereo()) {
  2340. // Clear both left and right attachments.
  2341. if (clearable->get_clear_active(GraphicsOutput::RTP_color)) {
  2342. LColorf v = LCAST(float, clearable->get_clear_value(GraphicsOutput::RTP_color));
  2343. _glClearBufferfv(GL_COLOR, index, v.get_data());
  2344. _glClearBufferfv(GL_COLOR, index + 1, v.get_data());
  2345. }
  2346. index += 2;
  2347. } else {
  2348. if (clearable->get_clear_active(GraphicsOutput::RTP_color)) {
  2349. LColorf v = LCAST(float, clearable->get_clear_value(GraphicsOutput::RTP_color));
  2350. _glClearBufferfv(GL_COLOR, index, v.get_data());
  2351. }
  2352. ++index;
  2353. }
  2354. }
  2355. for (int i = 0; i < _current_properties->get_aux_rgba(); ++i) {
  2356. int layerid = GraphicsOutput::RTP_aux_rgba_0 + i;
  2357. if (clearable->get_clear_active(layerid)) {
  2358. LColorf v = LCAST(float, clearable->get_clear_value(layerid));
  2359. _glClearBufferfv(GL_COLOR, index, v.get_data());
  2360. }
  2361. ++index;
  2362. }
  2363. for (int i = 0; i < _current_properties->get_aux_hrgba(); ++i) {
  2364. int layerid = GraphicsOutput::RTP_aux_hrgba_0 + i;
  2365. if (clearable->get_clear_active(layerid)) {
  2366. LColorf v = LCAST(float, clearable->get_clear_value(layerid));
  2367. _glClearBufferfv(GL_COLOR, index, v.get_data());
  2368. }
  2369. ++index;
  2370. }
  2371. for (int i = 0; i < _current_properties->get_aux_float(); ++i) {
  2372. int layerid = GraphicsOutput::RTP_aux_float_0 + i;
  2373. if (clearable->get_clear_active(layerid)) {
  2374. LColorf v = LCAST(float, clearable->get_clear_value(layerid));
  2375. _glClearBufferfv(GL_COLOR, index, v.get_data());
  2376. }
  2377. ++index;
  2378. }
  2379. } else
  2380. #endif
  2381. {
  2382. if (_current_properties->get_aux_mask() != 0) {
  2383. for (int i = 0; i < _current_properties->get_aux_rgba(); ++i) {
  2384. int layerid = GraphicsOutput::RTP_aux_rgba_0 + i;
  2385. int layerbit = RenderBuffer::T_aux_rgba_0 << i;
  2386. if (clearable->get_clear_active(layerid)) {
  2387. LColor v = clearable->get_clear_value(layerid);
  2388. glClearColor(v[0], v[1], v[2], v[3]);
  2389. set_draw_buffer(layerbit);
  2390. glClear(GL_COLOR_BUFFER_BIT);
  2391. }
  2392. }
  2393. for (int i = 0; i < _current_properties->get_aux_hrgba(); ++i) {
  2394. int layerid = GraphicsOutput::RTP_aux_hrgba_0 + i;
  2395. int layerbit = RenderBuffer::T_aux_hrgba_0 << i;
  2396. if (clearable->get_clear_active(layerid)) {
  2397. LColor v = clearable->get_clear_value(layerid);
  2398. glClearColor(v[0], v[1], v[2], v[3]);
  2399. set_draw_buffer(layerbit);
  2400. glClear(GL_COLOR_BUFFER_BIT);
  2401. }
  2402. }
  2403. for (int i = 0; i < _current_properties->get_aux_float(); ++i) {
  2404. int layerid = GraphicsOutput::RTP_aux_float_0 + i;
  2405. int layerbit = RenderBuffer::T_aux_float_0 << i;
  2406. if (clearable->get_clear_active(layerid)) {
  2407. LColor v = clearable->get_clear_value(layerid);
  2408. glClearColor(v[0], v[1], v[2], v[3]);
  2409. set_draw_buffer(layerbit);
  2410. glClear(GL_COLOR_BUFFER_BIT);
  2411. }
  2412. }
  2413. // In the past, it was possible to set the draw buffer
  2414. // once in prepare_display_region and then forget about it.
  2415. // Now, with aux layers, it is necessary to occasionally
  2416. // change the draw buffer. In time, I think there will need
  2417. // to be a draw buffer attrib. Until then, this little hack
  2418. // to put things back the way they were after
  2419. // prepare_display_region will do.
  2420. set_draw_buffer(_draw_buffer_type);
  2421. }
  2422. if (_current_properties->get_color_bits() > 0) {
  2423. if (clearable->get_clear_color_active()) {
  2424. LColor v = clearable->get_clear_color();
  2425. glClearColor(v[0], v[1], v[2], v[3]);
  2426. clear_color_write_mask();
  2427. _state_mask.clear_bit(ColorWriteAttrib::get_class_slot());
  2428. mask |= GL_COLOR_BUFFER_BIT;
  2429. }
  2430. }
  2431. }
  2432. if (clearable->get_clear_depth_active()) {
  2433. #ifdef OPENGLES
  2434. glClearDepthf(clearable->get_clear_depth());
  2435. #else
  2436. glClearDepth(clearable->get_clear_depth());
  2437. #endif // OPENGLES
  2438. #ifdef GSG_VERBOSE
  2439. GLCAT.spam()
  2440. << "glDepthMask(GL_TRUE)" << endl;
  2441. #endif
  2442. glDepthMask(GL_TRUE);
  2443. _state_mask.clear_bit(DepthWriteAttrib::get_class_slot());
  2444. mask |= GL_DEPTH_BUFFER_BIT;
  2445. }
  2446. if (clearable->get_clear_stencil_active()) {
  2447. glStencilMask(~0);
  2448. glClearStencil(clearable->get_clear_stencil());
  2449. mask |= GL_STENCIL_BUFFER_BIT;
  2450. }
  2451. glClear(mask);
  2452. if (GLCAT.is_spam()) {
  2453. GLCAT.spam() << "glClear(";
  2454. if (mask & GL_COLOR_BUFFER_BIT) {
  2455. GLCAT.spam(false) << "GL_COLOR_BUFFER_BIT|";
  2456. }
  2457. if (mask & GL_DEPTH_BUFFER_BIT) {
  2458. GLCAT.spam(false) << "GL_DEPTH_BUFFER_BIT|";
  2459. }
  2460. if (mask & GL_STENCIL_BUFFER_BIT) {
  2461. GLCAT.spam(false) << "GL_STENCIL_BUFFER_BIT|";
  2462. }
  2463. #ifndef OPENGLES
  2464. if (mask & GL_ACCUM_BUFFER_BIT) {
  2465. GLCAT.spam(false) << "GL_ACCUM_BUFFER_BIT|";
  2466. }
  2467. #endif
  2468. GLCAT.spam(false) << ")" << endl;
  2469. }
  2470. report_my_gl_errors();
  2471. }
  2472. ////////////////////////////////////////////////////////////////////
  2473. // Function: GLGraphicsStateGuardian::prepare_display_region
  2474. // Access: Public, Virtual
  2475. // Description: Prepare a display region for rendering (set up
  2476. // scissor region and viewport)
  2477. ////////////////////////////////////////////////////////////////////
  2478. void CLP(GraphicsStateGuardian)::
  2479. prepare_display_region(DisplayRegionPipelineReader *dr) {
  2480. nassertv(dr != (DisplayRegionPipelineReader *)NULL);
  2481. GraphicsStateGuardian::prepare_display_region(dr);
  2482. int l, b, w, h;
  2483. dr->get_region_pixels(l, b, w, h);
  2484. _viewport_x = l;
  2485. _viewport_y = b;
  2486. _viewport_width = w;
  2487. _viewport_height = h;
  2488. GLint x = GLint(l);
  2489. GLint y = GLint(b);
  2490. GLsizei width = GLsizei(w);
  2491. GLsizei height = GLsizei(h);
  2492. _draw_buffer_type = dr->get_object()->get_draw_buffer_type() & _current_properties->get_buffer_mask() & _stereo_buffer_mask;
  2493. _draw_buffer_type |= _current_properties->get_aux_mask();
  2494. set_draw_buffer(_draw_buffer_type);
  2495. int count = dr->get_num_regions();
  2496. if (dr->get_scissor_enabled()) {
  2497. if (GLCAT.is_spam()) {
  2498. GLCAT.spam()
  2499. << "glEnable(GL_SCISSOR_TEST)\n";
  2500. }
  2501. glEnable(GL_SCISSOR_TEST);
  2502. _scissor_enabled = true;
  2503. _scissor_array.resize(count);
  2504. } else {
  2505. if (GLCAT.is_spam()) {
  2506. GLCAT.spam()
  2507. << "glDisable(GL_SCISSOR_TEST)\n";
  2508. }
  2509. glDisable(GL_SCISSOR_TEST);
  2510. _scissor_enabled = false;
  2511. _scissor_array.clear();
  2512. }
  2513. _scissor_attrib_active = false;
  2514. #ifndef OPENGLES
  2515. if (_supports_viewport_arrays) {
  2516. GLfloat *viewports = (GLfloat *)alloca(sizeof(GLfloat) * 4 * count);
  2517. // We store the scissor regions in a vector since we may need
  2518. // to switch back to it in do_issue_scissor.
  2519. for (int i = 0; i < count; ++i) {
  2520. LVecBase4i sr;
  2521. dr->get_region_pixels(i, sr[0], sr[1], sr[2], sr[3]);
  2522. GLfloat *vr = viewports + i * 4;
  2523. vr[0] = (GLfloat) sr[0];
  2524. vr[1] = (GLfloat) sr[1];
  2525. vr[2] = (GLfloat) sr[2];
  2526. vr[3] = (GLfloat) sr[3];
  2527. if (_scissor_enabled) {
  2528. _scissor_array[i] = sr;
  2529. }
  2530. }
  2531. _glViewportArrayv(0, count, viewports);
  2532. if (_scissor_enabled) {
  2533. _glScissorArrayv(0, count, _scissor_array[0].get_data());
  2534. }
  2535. if (GLCAT.is_spam()) {
  2536. GLCAT.spam()
  2537. << "glViewportArrayv(0, " << count << ", [\n";
  2538. for (int i = 0; i < count; ++i) {
  2539. GLfloat *vr = viewports + i * 4;
  2540. GLCAT.spam(false) << vr[0] << ", " << vr[1] << ", " << vr[2] << ", " << vr[3] << ",\n";
  2541. }
  2542. GLCAT.spam(false) << "])\n";
  2543. if (_scissor_enabled) {
  2544. GLCAT.spam()
  2545. << "glScissorArrayv(0, " << count << ", [\n";
  2546. for (int i = 0; i < count; ++i) {
  2547. const LVecBase4i &sr = _scissor_array[i];
  2548. GLCAT.spam(false) << sr << ",\n";
  2549. }
  2550. }
  2551. GLCAT.spam(false) << "])\n";
  2552. }
  2553. } else
  2554. #endif // OPENGLES
  2555. {
  2556. glViewport(x, y, width, height);
  2557. if (_scissor_enabled) {
  2558. glScissor(x, y, width, height);
  2559. _scissor_array.resize(1);
  2560. _scissor_array[0].set(x, y, width, height);
  2561. }
  2562. if (GLCAT.is_spam()) {
  2563. GLCAT.spam()
  2564. << "glViewport(" << x << ", " << y << ", " << width << ", " << height << ")\n";
  2565. if (dr->get_scissor_enabled()) {
  2566. GLCAT.spam()
  2567. << "glScissor(" << x << ", " << y << ", " << width << ", " << height << ")\n";
  2568. }
  2569. }
  2570. }
  2571. report_my_gl_errors();
  2572. do_point_size();
  2573. }
  2574. ////////////////////////////////////////////////////////////////////
  2575. // Function: GLGraphicsStateGuardian::clear_before_callback
  2576. // Access: Public, Virtual
  2577. // Description: Resets any non-standard graphics state that might
  2578. // give a callback apoplexy. Some drivers require that
  2579. // the graphics state be restored to neutral before
  2580. // performing certain operations. In OpenGL, for
  2581. // instance, this closes any open vertex buffers.
  2582. ////////////////////////////////////////////////////////////////////
  2583. void CLP(GraphicsStateGuardian)::
  2584. clear_before_callback() {
  2585. #ifdef SUPPORT_FIXED_FUNCTION
  2586. disable_standard_vertex_arrays();
  2587. #endif
  2588. unbind_buffers();
  2589. // Some callbacks may quite reasonably assume that the active
  2590. // texture stage is still set to stage 0. CEGUI, in particular,
  2591. // makes this assumption.
  2592. _glActiveTexture(GL_TEXTURE0);
  2593. #ifdef SUPPORT_FIXED_FUNCTION
  2594. _glClientActiveTexture(GL_TEXTURE0);
  2595. #endif
  2596. // Clear the bound sampler object, so that we do not inadvertently
  2597. // override the callback's desired sampler settings.
  2598. #ifndef OPENGLES
  2599. if (_supports_sampler_objects) {
  2600. _glBindSampler(0, 0);
  2601. }
  2602. #endif
  2603. }
  2604. ////////////////////////////////////////////////////////////////////
  2605. // Function: GLGraphicsStateGuardian::calc_projection_mat
  2606. // Access: Public, Virtual
  2607. // Description: Given a lens, calculates the appropriate projection
  2608. // matrix for use with this gsg. Note that the
  2609. // projection matrix depends a lot upon the coordinate
  2610. // system of the rendering API.
  2611. //
  2612. // The return value is a TransformState if the lens is
  2613. // acceptable, NULL if it is not.
  2614. ////////////////////////////////////////////////////////////////////
  2615. CPT(TransformState) CLP(GraphicsStateGuardian)::
  2616. calc_projection_mat(const Lens *lens) {
  2617. if (lens == (Lens *)NULL) {
  2618. return NULL;
  2619. }
  2620. if (!lens->is_linear()) {
  2621. return NULL;
  2622. }
  2623. // The projection matrix must always be right-handed Y-up, even if
  2624. // our coordinate system of choice is otherwise, because certain GL
  2625. // calls (specifically glTexGen(GL_SPHERE_MAP)) assume this kind of
  2626. // a coordinate system. Sigh. In order to implement a Z-up (or
  2627. // other arbitrary) coordinate system, we'll use a Y-up projection
  2628. // matrix, and store the conversion to our coordinate system of
  2629. // choice in the modelview matrix.
  2630. LMatrix4 result =
  2631. LMatrix4::convert_mat(_internal_coordinate_system,
  2632. lens->get_coordinate_system()) *
  2633. lens->get_projection_mat(_current_stereo_channel);
  2634. if (_scene_setup->get_inverted()) {
  2635. // If the scene is supposed to be inverted, then invert the
  2636. // projection matrix.
  2637. result *= LMatrix4::scale_mat(1.0f, -1.0f, 1.0f);
  2638. }
  2639. return TransformState::make_mat(result);
  2640. }
  2641. ////////////////////////////////////////////////////////////////////
  2642. // Function: GLGraphicsStateGuardian::prepare_lens
  2643. // Access: Public, Virtual
  2644. // Description: Makes the current lens (whichever lens was most
  2645. // recently specified with set_scene()) active, so
  2646. // that it will transform future rendered geometry.
  2647. // Normally this is only called from the draw process,
  2648. // and usually it is called by set_scene().
  2649. //
  2650. // The return value is true if the lens is acceptable,
  2651. // false if it is not.
  2652. ////////////////////////////////////////////////////////////////////
  2653. bool CLP(GraphicsStateGuardian)::
  2654. prepare_lens() {
  2655. #ifdef SUPPORT_FIXED_FUNCTION
  2656. if (GLCAT.is_spam()) {
  2657. GLCAT.spam()
  2658. << "glMatrixMode(GL_PROJECTION): " << _projection_mat->get_mat() << endl;
  2659. }
  2660. glMatrixMode(GL_PROJECTION);
  2661. GLPf(LoadMatrix)(_projection_mat->get_mat().get_data());
  2662. report_my_gl_errors();
  2663. do_point_size();
  2664. #endif
  2665. #ifndef OPENGLES_1
  2666. if (_current_shader_context) {
  2667. _current_shader_context->issue_parameters(Shader::SSD_transform);
  2668. }
  2669. #endif
  2670. return true;
  2671. }
  2672. ////////////////////////////////////////////////////////////////////
  2673. // Function: GraphicsStateGuardian::begin_frame
  2674. // Access: Public, Virtual
  2675. // Description: Called before each frame is rendered, to allow the
  2676. // GSG a chance to do any internal cleanup before
  2677. // beginning the frame.
  2678. //
  2679. // The return value is true if successful (in which case
  2680. // the frame will be drawn and end_frame() will be
  2681. // called later), or false if unsuccessful (in which
  2682. // case nothing will be drawn and end_frame() will not
  2683. // be called).
  2684. ////////////////////////////////////////////////////////////////////
  2685. bool CLP(GraphicsStateGuardian)::
  2686. begin_frame(Thread *current_thread) {
  2687. if (!GraphicsStateGuardian::begin_frame(current_thread)) {
  2688. return false;
  2689. }
  2690. _renderbuffer_residency.begin_frame(current_thread);
  2691. report_my_gl_errors();
  2692. #ifdef DO_PSTATS
  2693. _vertices_display_list_pcollector.clear_level();
  2694. _vertices_immediate_pcollector.clear_level();
  2695. _primitive_batches_display_list_pcollector.clear_level();
  2696. #endif
  2697. #ifndef NDEBUG
  2698. _show_texture_usage = false;
  2699. if (gl_show_texture_usage) {
  2700. // When this is true, then every other second, we show the usage
  2701. // textures instead of the real textures.
  2702. double now = ClockObject::get_global_clock()->get_frame_time();
  2703. int this_second = (int)floor(now);
  2704. if (this_second & 1) {
  2705. _show_texture_usage = true;
  2706. _show_texture_usage_index = this_second >> 1;
  2707. int max_size = gl_show_texture_usage_max_size;
  2708. if (max_size != _show_texture_usage_max_size) {
  2709. // Remove the cache of usage textures; we've changed the max
  2710. // size.
  2711. UsageTextures::iterator ui;
  2712. for (ui = _usage_textures.begin();
  2713. ui != _usage_textures.end();
  2714. ++ui) {
  2715. GLuint index = (*ui).second;
  2716. glDeleteTextures(1, &index);
  2717. }
  2718. _usage_textures.clear();
  2719. _show_texture_usage_max_size = max_size;
  2720. }
  2721. }
  2722. }
  2723. #endif // NDEBUG
  2724. #ifdef DO_PSTATS
  2725. /*if (_supports_timer_query) {
  2726. // Measure the difference between the OpenGL clock and the
  2727. // PStats clock.
  2728. GLint64 time_ns;
  2729. _glGetInteger64v(GL_TIMESTAMP, &time_ns);
  2730. _timer_delta = time_ns * -0.000000001;
  2731. _timer_delta += PStatClient::get_global_pstats()->get_real_time();
  2732. }*/
  2733. #endif
  2734. #ifndef OPENGLES
  2735. if (_current_properties->get_srgb_color()) {
  2736. glEnable(GL_FRAMEBUFFER_SRGB);
  2737. }
  2738. #endif
  2739. report_my_gl_errors();
  2740. return true;
  2741. }
  2742. ////////////////////////////////////////////////////////////////////
  2743. // Function: GraphicsStateGuardian::begin_scene
  2744. // Access: Public, Virtual
  2745. // Description: Called between begin_frame() and end_frame() to mark
  2746. // the beginning of drawing commands for a "scene"
  2747. // (usually a particular DisplayRegion) within a frame.
  2748. // All 3-D drawing commands, except the clear operation,
  2749. // must be enclosed within begin_scene() .. end_scene().
  2750. //
  2751. // The return value is true if successful (in which case
  2752. // the scene will be drawn and end_scene() will be
  2753. // called later), or false if unsuccessful (in which
  2754. // case nothing will be drawn and end_scene() will not
  2755. // be called).
  2756. ////////////////////////////////////////////////////////////////////
  2757. bool CLP(GraphicsStateGuardian)::
  2758. begin_scene() {
  2759. return GraphicsStateGuardian::begin_scene();
  2760. }
  2761. ////////////////////////////////////////////////////////////////////
  2762. // Function: GLGraphicsStateGuardian::end_scene
  2763. // Access: Protected, Virtual
  2764. // Description: Called between begin_frame() and end_frame() to mark
  2765. // the end of drawing commands for a "scene" (usually a
  2766. // particular DisplayRegion) within a frame. All 3-D
  2767. // drawing commands, except the clear operation, must be
  2768. // enclosed within begin_scene() .. end_scene().
  2769. ////////////////////////////////////////////////////////////////////
  2770. void CLP(GraphicsStateGuardian)::
  2771. end_scene() {
  2772. GraphicsStateGuardian::end_scene();
  2773. _dlights.clear();
  2774. report_my_gl_errors();
  2775. }
  2776. ////////////////////////////////////////////////////////////////////
  2777. // Function: GLGraphicsStateGuardian::end_frame
  2778. // Access: Public, Virtual
  2779. // Description: Called after each frame is rendered, to allow the
  2780. // GSG a chance to do any internal cleanup after
  2781. // rendering the frame, and before the window flips.
  2782. ////////////////////////////////////////////////////////////////////
  2783. void CLP(GraphicsStateGuardian)::
  2784. end_frame(Thread *current_thread) {
  2785. report_my_gl_errors();
  2786. #ifndef OPENGLES
  2787. if (_current_properties->get_srgb_color()) {
  2788. glDisable(GL_FRAMEBUFFER_SRGB);
  2789. }
  2790. #endif
  2791. #ifdef DO_PSTATS
  2792. // Check for textures, etc., that are no longer resident. These
  2793. // calls might be measurably expensive, and they don't have any
  2794. // benefit unless we are actually viewing PStats, so don't do them
  2795. // unless we're connected. That will just mean that we'll count
  2796. // everything as resident until the user connects PStats, at which
  2797. // point it will then correct the assessment. No harm done.
  2798. if (PStatClient::is_connected()) {
  2799. check_nonresident_texture(_prepared_objects->_texture_residency.get_inactive_resident());
  2800. check_nonresident_texture(_prepared_objects->_texture_residency.get_active_resident());
  2801. // OpenGL provides no methods for querying whether a buffer object
  2802. // (vertex buffer) is resident. In fact, the API appears geared
  2803. // towards the assumption that such buffers are always resident.
  2804. // OK.
  2805. }
  2806. #endif
  2807. #ifndef OPENGLES_1
  2808. // This breaks shaders across multiple regions.
  2809. if (_vertex_array_shader_context != 0) {
  2810. _vertex_array_shader_context->disable_shader_vertex_arrays();
  2811. _vertex_array_shader = (Shader *)NULL;
  2812. _vertex_array_shader_context = (ShaderContext *)NULL;
  2813. }
  2814. if (_texture_binding_shader_context != 0) {
  2815. _texture_binding_shader_context->disable_shader_texture_bindings();
  2816. _texture_binding_shader = (Shader *)NULL;
  2817. _texture_binding_shader_context = (ShaderContext *)NULL;
  2818. }
  2819. if (_current_shader_context != 0) {
  2820. _current_shader_context->unbind();
  2821. _current_shader = (Shader *)NULL;
  2822. _current_shader_context = (ShaderContext *)NULL;
  2823. }
  2824. #endif
  2825. // Calling glFlush() at the end of the frame is particularly
  2826. // necessary if this is a single-buffered visual, so that the frame
  2827. // will be finished drawing before we return to the application.
  2828. // It's not clear what effect this has on our total frame time.
  2829. //if (_force_flush || _current_properties->is_single_buffered()) {
  2830. // gl_flush();
  2831. //}
  2832. maybe_gl_finish();
  2833. GraphicsStateGuardian::end_frame(current_thread);
  2834. _renderbuffer_residency.end_frame(current_thread);
  2835. // Flush any PCollectors specific to this kind of GSG.
  2836. _primitive_batches_display_list_pcollector.flush_level();
  2837. _vertices_display_list_pcollector.flush_level();
  2838. _vertices_immediate_pcollector.flush_level();
  2839. // Now is a good time to delete any pending display lists.
  2840. #ifndef OPENGLES
  2841. #ifdef SUPPORT_FIXED_FUNCTION
  2842. if (display_lists) {
  2843. LightMutexHolder holder(_lock);
  2844. if (!_deleted_display_lists.empty()) {
  2845. DeletedNames::iterator ddli;
  2846. for (ddli = _deleted_display_lists.begin();
  2847. ddli != _deleted_display_lists.end();
  2848. ++ddli) {
  2849. if (GLCAT.is_debug()) {
  2850. GLCAT.debug()
  2851. << "releasing display list index " << (int)(*ddli) << "\n";
  2852. }
  2853. glDeleteLists((*ddli), 1);
  2854. }
  2855. _deleted_display_lists.clear();
  2856. }
  2857. }
  2858. #endif
  2859. // And deleted queries, too, unless we're using query timers
  2860. // in which case we'll need to reuse lots of them.
  2861. if (_supports_occlusion_query && !get_timer_queries_active()) {
  2862. LightMutexHolder holder(_lock);
  2863. if (!_deleted_queries.empty()) {
  2864. if (GLCAT.is_spam()) {
  2865. DeletedNames::iterator dqi;
  2866. for (dqi = _deleted_queries.begin();
  2867. dqi != _deleted_queries.end();
  2868. ++dqi) {
  2869. GLCAT.spam()
  2870. << "releasing query index " << (int)(*dqi) << "\n";
  2871. }
  2872. }
  2873. _glDeleteQueries(_deleted_queries.size(), &_deleted_queries[0]);
  2874. _deleted_queries.clear();
  2875. }
  2876. }
  2877. #endif // OPENGLES
  2878. #ifndef NDEBUG
  2879. if (_check_errors || (_supports_debug && gl_debug)) {
  2880. report_my_gl_errors();
  2881. } else {
  2882. static int frame_counter = -1;
  2883. // If _check_errors is false, we still want to check for errors
  2884. // the first few frames and once every N frames, so that we know if
  2885. // anything went wrong at all.
  2886. if (frame_counter++ <= 0) {
  2887. PStatTimer timer(_check_error_pcollector);
  2888. GLenum error_code = glGetError();
  2889. if (error_code != GL_NO_ERROR) {
  2890. int error_count = 0;
  2891. bool deactivate = !report_errors_loop(__LINE__, __FILE__, error_code, error_count);
  2892. if (error_count == 1) {
  2893. GLCAT.error()
  2894. << "An OpenGL error (" << get_error_string(error_code)
  2895. << ") has occurred.";
  2896. } else {
  2897. GLCAT.error()
  2898. << error_count << " OpenGL errors have occurred.";
  2899. }
  2900. if (_supports_debug) {
  2901. GLCAT.error(false) << " Set gl-debug #t "
  2902. << "in your PRC file to display more information.\n";
  2903. } else {
  2904. GLCAT.error(false) << " Set gl-check-errors #t "
  2905. << "in your PRC file to display more information.\n";
  2906. }
  2907. if (deactivate) {
  2908. panic_deactivate();
  2909. }
  2910. }
  2911. } else if (frame_counter > 100) {
  2912. // 100 frames have passed. Check next frame.
  2913. frame_counter = 0;
  2914. }
  2915. }
  2916. #endif
  2917. }
  2918. ////////////////////////////////////////////////////////////////////
  2919. // Function: GLGraphicsStateGuardian::begin_draw_primitives
  2920. // Access: Public, Virtual
  2921. // Description: Called before a sequence of draw_primitive()
  2922. // functions are called, this should prepare the vertex
  2923. // data for rendering. It returns true if the vertices
  2924. // are ok, false to abort this group of primitives.
  2925. ////////////////////////////////////////////////////////////////////
  2926. bool CLP(GraphicsStateGuardian)::
  2927. begin_draw_primitives(const GeomPipelineReader *geom_reader,
  2928. const GeomMunger *munger,
  2929. const GeomVertexDataPipelineReader *data_reader,
  2930. bool force) {
  2931. #ifndef NDEBUG
  2932. if (GLCAT.is_spam()) {
  2933. GLCAT.spam() << "begin_draw_primitives: " << *(data_reader->get_object()) << "\n";
  2934. }
  2935. #endif // NDEBUG
  2936. #ifndef SUPPORT_FIXED_FUNCTION
  2937. // We can't draw without a shader bound in OpenGL ES 2. This shouldn't
  2938. // happen anyway unless the default shader failed to compile somehow.
  2939. if (_current_shader_context == NULL) {
  2940. return false;
  2941. }
  2942. #endif
  2943. if (!GraphicsStateGuardian::begin_draw_primitives(geom_reader, munger, data_reader, force)) {
  2944. return false;
  2945. }
  2946. nassertr(_data_reader != (GeomVertexDataPipelineReader *)NULL, false);
  2947. _geom_display_list = 0;
  2948. if (_auto_antialias_mode) {
  2949. switch (geom_reader->get_primitive_type()) {
  2950. case GeomPrimitive::PT_polygons:
  2951. case GeomPrimitive::PT_patches:
  2952. setup_antialias_polygon();
  2953. break;
  2954. case GeomPrimitive::PT_points:
  2955. setup_antialias_point();
  2956. break;
  2957. case GeomPrimitive::PT_lines:
  2958. setup_antialias_line();
  2959. break;
  2960. case GeomPrimitive::PT_none:
  2961. break;
  2962. }
  2963. int transparency_slot = TransparencyAttrib::get_class_slot();
  2964. int color_write_slot = ColorWriteAttrib::get_class_slot();
  2965. int color_blend_slot = ColorBlendAttrib::get_class_slot();
  2966. if (!_state_mask.get_bit(transparency_slot) ||
  2967. !_state_mask.get_bit(color_write_slot) ||
  2968. !_state_mask.get_bit(color_blend_slot)) {
  2969. do_issue_blending();
  2970. _state_mask.set_bit(transparency_slot);
  2971. _state_mask.set_bit(color_write_slot);
  2972. _state_mask.set_bit(color_blend_slot);
  2973. }
  2974. }
  2975. #ifdef SUPPORT_FIXED_FUNCTION
  2976. if (_data_reader->is_vertex_transformed()) {
  2977. // If the vertex data claims to be already transformed into clip
  2978. // coordinates, wipe out the current projection and modelview
  2979. // matrix (so we don't attempt to transform it again).
  2980. glMatrixMode(GL_PROJECTION);
  2981. glPushMatrix();
  2982. glLoadIdentity();
  2983. glMatrixMode(GL_MODELVIEW);
  2984. glPushMatrix();
  2985. glLoadIdentity();
  2986. }
  2987. #endif
  2988. #if !defined(OPENGLES) && defined(SUPPORT_FIXED_FUNCTION) // Display lists not supported by OpenGL ES.
  2989. if (geom_reader->get_usage_hint() == Geom::UH_static &&
  2990. _data_reader->get_usage_hint() == Geom::UH_static &&
  2991. display_lists) {
  2992. // If the geom claims to be totally static, try to build it into
  2993. // a display list.
  2994. // Before we compile or call a display list, make sure the current
  2995. // buffers are unbound, or the nVidia drivers may crash.
  2996. unbind_buffers();
  2997. GeomContext *gc = geom_reader->prepare_now(get_prepared_objects(), this);
  2998. nassertr(gc != (GeomContext *)NULL, false);
  2999. CLP(GeomContext) *ggc = DCAST(CLP(GeomContext), gc);
  3000. const CLP(GeomMunger) *gmunger = DCAST(CLP(GeomMunger), _munger);
  3001. UpdateSeq modified = max(geom_reader->get_modified(), _data_reader->get_modified());
  3002. if (ggc->get_display_list(_geom_display_list, gmunger, modified)) {
  3003. // If it hasn't been modified, just play the display list again.
  3004. if (GLCAT.is_spam()) {
  3005. GLCAT.spam()
  3006. << "calling display list " << (int)_geom_display_list << "\n";
  3007. }
  3008. glCallList(_geom_display_list);
  3009. #ifdef DO_PSTATS
  3010. _vertices_display_list_pcollector.add_level(ggc->_num_verts);
  3011. _primitive_batches_display_list_pcollector.add_level(1);
  3012. #endif
  3013. // And now we don't need to do anything else for this geom.
  3014. _geom_display_list = 0;
  3015. end_draw_primitives();
  3016. return false;
  3017. }
  3018. // Since we start this collector explicitly, we have to be sure to
  3019. // stop it again.
  3020. _load_display_list_pcollector.start();
  3021. if (GLCAT.is_debug()) {
  3022. GLCAT.debug()
  3023. << "compiling display list " << (int)_geom_display_list << "\n";
  3024. }
  3025. // If it has been modified, or this is the first time, then we
  3026. // need to build the display list up.
  3027. if (gl_compile_and_execute) {
  3028. glNewList(_geom_display_list, GL_COMPILE_AND_EXECUTE);
  3029. } else {
  3030. glNewList(_geom_display_list, GL_COMPILE);
  3031. }
  3032. #ifdef DO_PSTATS
  3033. // Count up the number of vertices used by primitives in the Geom,
  3034. // for PStats reporting.
  3035. ggc->_num_verts = 0;
  3036. for (int i = 0; i < geom_reader->get_num_primitives(); i++) {
  3037. ggc->_num_verts += geom_reader->get_primitive(i)->get_num_vertices();
  3038. }
  3039. #endif
  3040. }
  3041. #endif // OPENGLES
  3042. // Enable the appropriate vertex arrays, and disable any
  3043. // extra vertex arrays used by the previous rendering mode.
  3044. #ifdef SUPPORT_IMMEDIATE_MODE
  3045. _use_sender = !vertex_arrays;
  3046. #endif
  3047. {
  3048. //PStatGPUTimer timer(this, _vertex_array_update_pcollector);
  3049. #ifdef OPENGLES_1
  3050. if (!update_standard_vertex_arrays(force)) {
  3051. return false;
  3052. }
  3053. #else
  3054. if (_current_shader_context == 0) {
  3055. // No shader.
  3056. if (_vertex_array_shader_context != 0) {
  3057. _vertex_array_shader_context->disable_shader_vertex_arrays();
  3058. }
  3059. #ifdef SUPPORT_FIXED_FUNCTION
  3060. if (!update_standard_vertex_arrays(force)) {
  3061. return false;
  3062. }
  3063. #endif
  3064. } else {
  3065. #ifdef SUPPORT_FIXED_FUNCTION
  3066. // Shader.
  3067. if (_vertex_array_shader_context == 0 || _vertex_array_shader_context->uses_standard_vertex_arrays()) {
  3068. // Previous shader used standard arrays.
  3069. if (_current_shader_context->uses_standard_vertex_arrays()) {
  3070. // So does the current, so update them.
  3071. if (!update_standard_vertex_arrays(force)) {
  3072. return false;
  3073. }
  3074. } else {
  3075. // The current shader does not, so disable them entirely.
  3076. disable_standard_vertex_arrays();
  3077. }
  3078. }
  3079. #endif // SUPPORT_FIXED_FUNCTION
  3080. if (_current_shader_context->uses_custom_vertex_arrays()) {
  3081. // The current shader also uses custom vertex arrays.
  3082. if (!_current_shader_context->
  3083. update_shader_vertex_arrays(_vertex_array_shader_context, force)) {
  3084. return false;
  3085. }
  3086. } else {
  3087. _vertex_array_shader_context->disable_shader_vertex_arrays();
  3088. }
  3089. }
  3090. _vertex_array_shader = _current_shader;
  3091. _vertex_array_shader_context = _current_shader_context;
  3092. #endif // OPENGLES_1
  3093. }
  3094. report_my_gl_errors();
  3095. return true;
  3096. }
  3097. #ifdef SUPPORT_FIXED_FUNCTION
  3098. ////////////////////////////////////////////////////////////////////
  3099. // Function: GLGraphicsStateGuardian::update_standard_vertex_arrays
  3100. // Access: Protected
  3101. // Description: Disables any unneeded vertex arrays that
  3102. // were previously enabled, and enables any vertex
  3103. // arrays that are needed that were not previously
  3104. // enabled (or, sets up an immediate-mode sender).
  3105. // Called only from begin_draw_primitives.
  3106. // Used only when the standard (non-shader) pipeline
  3107. // is about to be used - glShaderContexts are responsible
  3108. // for setting up their own vertex arrays.
  3109. ////////////////////////////////////////////////////////////////////
  3110. bool CLP(GraphicsStateGuardian)::
  3111. update_standard_vertex_arrays(bool force) {
  3112. #ifdef SUPPORT_IMMEDIATE_MODE
  3113. if (_use_sender) {
  3114. // We must use immediate mode to render primitives.
  3115. _sender.clear();
  3116. _sender.add_column(_data_reader, InternalName::get_normal(),
  3117. NULL, NULL, GLPf(Normal3), NULL);
  3118. #ifndef NDEBUG
  3119. if (_show_texture_usage) {
  3120. // In show_texture_usage mode, all colors are white, so as not
  3121. // to contaminate the texture color.
  3122. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  3123. } else
  3124. #endif // NDEBUG
  3125. if (!_sender.add_column(_data_reader, InternalName::get_color(),
  3126. NULL, NULL, GLPf(Color3), GLPf(Color4))) {
  3127. // If we didn't have a color column, the item color is white.
  3128. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  3129. }
  3130. // Now set up each of the active texture coordinate stages--or at
  3131. // least those for which we're not generating texture coordinates
  3132. // automatically.
  3133. int max_stage_index = _target_texture->get_num_on_ff_stages();
  3134. int stage_index = 0;
  3135. while (stage_index < max_stage_index) {
  3136. TextureStage *stage = _target_texture->get_on_ff_stage(stage_index);
  3137. if (!_target_tex_gen->has_gen_texcoord_stage(stage)) {
  3138. // This stage is not one of the stages that doesn't need
  3139. // texcoords issued for it.
  3140. const InternalName *name = stage->get_texcoord_name();
  3141. if (stage_index == 0) {
  3142. // Use the original functions for stage 0, in case we don't
  3143. // support multitexture.
  3144. _sender.add_column(_data_reader, name,
  3145. GLPf(TexCoord1), GLPf(TexCoord2),
  3146. GLPf(TexCoord3), GLPf(TexCoord4));
  3147. } else {
  3148. // Other stages require the multitexture functions.
  3149. _sender.add_texcoord_column(_data_reader, name, stage_index,
  3150. GLf(_glMultiTexCoord1), GLf(_glMultiTexCoord2),
  3151. GLf(_glMultiTexCoord3), GLf(_glMultiTexCoord4));
  3152. }
  3153. }
  3154. ++stage_index;
  3155. }
  3156. // Be sure also to disable any texture stages we had enabled before.
  3157. while (stage_index < _last_max_stage_index) {
  3158. _glClientActiveTexture(GL_TEXTURE0 + stage_index);
  3159. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  3160. ++stage_index;
  3161. }
  3162. _last_max_stage_index = max_stage_index;
  3163. // We must add vertex last, because glVertex3f() is the key
  3164. // function call that actually issues the vertex.
  3165. _sender.add_column(_data_reader, InternalName::get_vertex(),
  3166. NULL, GLPf(Vertex2), GLPf(Vertex3), GLPf(Vertex4));
  3167. } else
  3168. #endif // SUPPORT_IMMEDIATE_MODE
  3169. {
  3170. // We may use vertex arrays or buffers to render primitives.
  3171. const GeomVertexArrayDataHandle *array_reader;
  3172. const unsigned char *client_pointer;
  3173. int num_values;
  3174. Geom::NumericType numeric_type;
  3175. int start;
  3176. int stride;
  3177. if (_data_reader->get_normal_info(array_reader, numeric_type,
  3178. start, stride)) {
  3179. if (!setup_array_data(client_pointer, array_reader, force)) {
  3180. return false;
  3181. }
  3182. glNormalPointer(get_numeric_type(numeric_type), stride,
  3183. client_pointer + start);
  3184. glEnableClientState(GL_NORMAL_ARRAY);
  3185. } else {
  3186. glDisableClientState(GL_NORMAL_ARRAY);
  3187. }
  3188. #ifndef NDEBUG
  3189. if (_show_texture_usage) {
  3190. // In show_texture_usage mode, all colors are white, so as not
  3191. // to contaminate the texture color.
  3192. glDisableClientState(GL_COLOR_ARRAY);
  3193. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  3194. } else
  3195. #endif // NDEBUG
  3196. if (_data_reader->get_color_info(array_reader, num_values, numeric_type,
  3197. start, stride)) {
  3198. if (!setup_array_data(client_pointer, array_reader, force)) {
  3199. return false;
  3200. }
  3201. if (numeric_type == Geom::NT_packed_dabc) {
  3202. glColorPointer(GL_BGRA, GL_UNSIGNED_BYTE,
  3203. stride, client_pointer + start);
  3204. } else {
  3205. glColorPointer(num_values, get_numeric_type(numeric_type),
  3206. stride, client_pointer + start);
  3207. }
  3208. glEnableClientState(GL_COLOR_ARRAY);
  3209. } else {
  3210. glDisableClientState(GL_COLOR_ARRAY);
  3211. // Since we don't have per-vertex color, the implicit color is
  3212. // white.
  3213. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  3214. }
  3215. // Now set up each of the active texture coordinate stages--or at
  3216. // least those for which we're not generating texture coordinates
  3217. // automatically.
  3218. int max_stage_index = _target_texture->get_num_on_ff_stages();
  3219. int stage_index = 0;
  3220. while (stage_index < max_stage_index) {
  3221. _glClientActiveTexture(GL_TEXTURE0 + stage_index);
  3222. TextureStage *stage = _target_texture->get_on_ff_stage(stage_index);
  3223. if (!_target_tex_gen->has_gen_texcoord_stage(stage)) {
  3224. // This stage is not one of the stages that doesn't need
  3225. // texcoords issued for it.
  3226. const InternalName *name = stage->get_texcoord_name();
  3227. if (_data_reader->get_array_info(name, array_reader, num_values,
  3228. numeric_type, start, stride)) {
  3229. // The vertex data does have texcoords for this stage.
  3230. if (!setup_array_data(client_pointer, array_reader, force)) {
  3231. return false;
  3232. }
  3233. glTexCoordPointer(num_values, get_numeric_type(numeric_type),
  3234. stride, client_pointer + start);
  3235. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  3236. } else {
  3237. // The vertex data doesn't have texcoords for this stage (even
  3238. // though they're needed).
  3239. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  3240. }
  3241. } else {
  3242. // No texcoords are needed for this stage.
  3243. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  3244. }
  3245. ++stage_index;
  3246. }
  3247. // Be sure also to disable any texture stages we had enabled before.
  3248. while (stage_index < _last_max_stage_index) {
  3249. _glClientActiveTexture(GL_TEXTURE0 + stage_index);
  3250. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  3251. ++stage_index;
  3252. }
  3253. _last_max_stage_index = max_stage_index;
  3254. // There's no requirement that we add vertices last, but we do
  3255. // anyway.
  3256. if (_data_reader->get_vertex_info(array_reader, num_values, numeric_type,
  3257. start, stride)) {
  3258. if (!setup_array_data(client_pointer, array_reader, force)) {
  3259. return false;
  3260. }
  3261. glVertexPointer(num_values, get_numeric_type(numeric_type),
  3262. stride, client_pointer + start);
  3263. glEnableClientState(GL_VERTEX_ARRAY);
  3264. }
  3265. }
  3266. return true;
  3267. }
  3268. #endif // SUPPORT_FIXED_FUNCTION
  3269. ////////////////////////////////////////////////////////////////////
  3270. // Function: GLGraphicsStateGuardian::unbind_buffers
  3271. // Access: Protected
  3272. // Description: Ensures the vertex and array buffers are no longer
  3273. // bound. Some graphics drivers crash if these are left
  3274. // bound indiscriminantly.
  3275. ////////////////////////////////////////////////////////////////////
  3276. void CLP(GraphicsStateGuardian)::
  3277. unbind_buffers() {
  3278. if (_current_vbuffer_index != 0) {
  3279. if (GLCAT.is_spam() && gl_debug_buffers) {
  3280. GLCAT.spam()
  3281. << "unbinding vertex buffer\n";
  3282. }
  3283. _glBindBuffer(GL_ARRAY_BUFFER, 0);
  3284. _current_vbuffer_index = 0;
  3285. }
  3286. if (_current_ibuffer_index != 0) {
  3287. if (GLCAT.is_spam() && gl_debug_buffers) {
  3288. GLCAT.spam()
  3289. << "unbinding index buffer\n";
  3290. }
  3291. _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  3292. _current_ibuffer_index = 0;
  3293. }
  3294. #ifdef SUPPORT_FIXED_FUNCTION
  3295. disable_standard_vertex_arrays();
  3296. #endif
  3297. }
  3298. #ifdef SUPPORT_FIXED_FUNCTION
  3299. ////////////////////////////////////////////////////////////////////
  3300. // Function: GLGraphicsStateGuardian::disable_standard_vertex_arrays
  3301. // Access: Protected
  3302. // Description: Used to disable all the standard vertex arrays that
  3303. // are currently enabled. glShaderContexts are
  3304. // responsible for setting up their own vertex arrays,
  3305. // but before they can do so, the standard vertex
  3306. // arrays need to be disabled to get them "out of the
  3307. // way." Called only from begin_draw_primitives.
  3308. ////////////////////////////////////////////////////////////////////
  3309. void CLP(GraphicsStateGuardian)::
  3310. disable_standard_vertex_arrays() {
  3311. #ifdef SUPPORT_IMMEDIATE_MODE
  3312. if (_use_sender) return;
  3313. #endif
  3314. glDisableClientState(GL_NORMAL_ARRAY);
  3315. glDisableClientState(GL_COLOR_ARRAY);
  3316. GLPf(Color4)(1.0f, 1.0f, 1.0f, 1.0f);
  3317. for (int stage_index=0; stage_index < _last_max_stage_index; stage_index++) {
  3318. _glClientActiveTexture(GL_TEXTURE0 + stage_index);
  3319. glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  3320. }
  3321. _last_max_stage_index = 0;
  3322. glDisableClientState(GL_VERTEX_ARRAY);
  3323. report_my_gl_errors();
  3324. }
  3325. #endif // SUPPORT_FIXED_FUNCTION
  3326. ////////////////////////////////////////////////////////////////////
  3327. // Function: GLGraphicsStateGuardian::draw_triangles
  3328. // Access: Public, Virtual
  3329. // Description: Draws a series of disconnected triangles.
  3330. ////////////////////////////////////////////////////////////////////
  3331. bool CLP(GraphicsStateGuardian)::
  3332. draw_triangles(const GeomPrimitivePipelineReader *reader, bool force) {
  3333. //PStatGPUTimer timer(this, _draw_primitive_pcollector, reader->get_current_thread());
  3334. #ifndef NDEBUG
  3335. if (GLCAT.is_spam()) {
  3336. GLCAT.spam() << "draw_triangles: " << *(reader->get_object()) << "\n";
  3337. }
  3338. #endif // NDEBUG
  3339. #ifdef SUPPORT_IMMEDIATE_MODE
  3340. if (_use_sender) {
  3341. draw_immediate_simple_primitives(reader, GL_TRIANGLES);
  3342. } else
  3343. #endif // SUPPORT_IMMEDIATE_MODE
  3344. {
  3345. int num_vertices = reader->get_num_vertices();
  3346. _vertices_tri_pcollector.add_level(num_vertices);
  3347. _primitive_batches_tri_pcollector.add_level(1);
  3348. if (reader->is_indexed()) {
  3349. const unsigned char *client_pointer;
  3350. if (!setup_primitive(client_pointer, reader, force)) {
  3351. return false;
  3352. }
  3353. #ifndef OPENGLES_1
  3354. if (_supports_geometry_instancing && _instance_count > 0) {
  3355. _glDrawElementsInstanced(GL_TRIANGLES, num_vertices,
  3356. get_numeric_type(reader->get_index_type()),
  3357. client_pointer, _instance_count);
  3358. } else
  3359. #endif
  3360. {
  3361. _glDrawRangeElements(GL_TRIANGLES,
  3362. reader->get_min_vertex(),
  3363. reader->get_max_vertex(),
  3364. num_vertices,
  3365. get_numeric_type(reader->get_index_type()),
  3366. client_pointer);
  3367. }
  3368. } else {
  3369. #ifndef OPENGLES_1
  3370. if (_supports_geometry_instancing && _instance_count > 0) {
  3371. _glDrawArraysInstanced(GL_TRIANGLES,
  3372. reader->get_first_vertex(),
  3373. num_vertices, _instance_count);
  3374. } else
  3375. #endif
  3376. {
  3377. glDrawArrays(GL_TRIANGLES,
  3378. reader->get_first_vertex(),
  3379. num_vertices);
  3380. }
  3381. }
  3382. }
  3383. report_my_gl_errors();
  3384. return true;
  3385. }
  3386. ////////////////////////////////////////////////////////////////////
  3387. // Function: GLGraphicsStateGuardian::draw_tristrips
  3388. // Access: Public, Virtual
  3389. // Description: Draws a series of triangle strips.
  3390. ////////////////////////////////////////////////////////////////////
  3391. bool CLP(GraphicsStateGuardian)::
  3392. draw_tristrips(const GeomPrimitivePipelineReader *reader, bool force) {
  3393. //PStatGPUTimer timer(this, _draw_primitive_pcollector, reader->get_current_thread());
  3394. report_my_gl_errors();
  3395. #ifndef NDEBUG
  3396. if (GLCAT.is_spam()) {
  3397. GLCAT.spam() << "draw_tristrips: " << *(reader->get_object()) << "\n";
  3398. }
  3399. #endif // NDEBUG
  3400. #ifdef SUPPORT_IMMEDIATE_MODE
  3401. if (_use_sender) {
  3402. draw_immediate_composite_primitives(reader, GL_TRIANGLE_STRIP);
  3403. } else
  3404. #endif // SUPPORT_IMMEDIATE_MODE
  3405. {
  3406. if (connect_triangle_strips && _render_mode != RenderModeAttrib::M_wireframe) {
  3407. // One long triangle strip, connected by the degenerate vertices
  3408. // that have already been set up within the primitive.
  3409. int num_vertices = reader->get_num_vertices();
  3410. _vertices_tristrip_pcollector.add_level(num_vertices);
  3411. _primitive_batches_tristrip_pcollector.add_level(1);
  3412. if (reader->is_indexed()) {
  3413. const unsigned char *client_pointer;
  3414. if (!setup_primitive(client_pointer, reader, force)) {
  3415. return false;
  3416. }
  3417. #ifndef OPENGLES_1
  3418. if (_supports_geometry_instancing && _instance_count > 0) {
  3419. _glDrawElementsInstanced(GL_TRIANGLE_STRIP, num_vertices,
  3420. get_numeric_type(reader->get_index_type()),
  3421. client_pointer, _instance_count);
  3422. } else
  3423. #endif
  3424. {
  3425. _glDrawRangeElements(GL_TRIANGLE_STRIP,
  3426. reader->get_min_vertex(),
  3427. reader->get_max_vertex(),
  3428. num_vertices,
  3429. get_numeric_type(reader->get_index_type()),
  3430. client_pointer);
  3431. }
  3432. } else {
  3433. #ifndef OPENGLES_1
  3434. if (_supports_geometry_instancing && _instance_count > 0) {
  3435. _glDrawArraysInstanced(GL_TRIANGLE_STRIP,
  3436. reader->get_first_vertex(),
  3437. num_vertices, _instance_count);
  3438. } else
  3439. #endif
  3440. {
  3441. glDrawArrays(GL_TRIANGLE_STRIP,
  3442. reader->get_first_vertex(),
  3443. num_vertices);
  3444. }
  3445. }
  3446. } else {
  3447. // Send the individual triangle strips, stepping over the
  3448. // degenerate vertices.
  3449. CPTA_int ends = reader->get_ends();
  3450. _primitive_batches_tristrip_pcollector.add_level(ends.size());
  3451. if (reader->is_indexed()) {
  3452. const unsigned char *client_pointer;
  3453. if (!setup_primitive(client_pointer, reader, force)) {
  3454. return false;
  3455. }
  3456. int index_stride = reader->get_index_stride();
  3457. GeomVertexReader mins(reader->get_mins(), 0);
  3458. GeomVertexReader maxs(reader->get_maxs(), 0);
  3459. nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() &&
  3460. reader->get_maxs()->get_num_rows() == (int)ends.size(), false);
  3461. unsigned int start = 0;
  3462. for (size_t i = 0; i < ends.size(); i++) {
  3463. _vertices_tristrip_pcollector.add_level(ends[i] - start);
  3464. #ifndef OPENGLES_1
  3465. if (_supports_geometry_instancing && _instance_count > 0) {
  3466. _glDrawElementsInstanced(GL_TRIANGLE_STRIP, ends[i] - start,
  3467. get_numeric_type(reader->get_index_type()),
  3468. client_pointer + start * index_stride,
  3469. _instance_count);
  3470. } else
  3471. #endif
  3472. {
  3473. _glDrawRangeElements(GL_TRIANGLE_STRIP,
  3474. mins.get_data1i(), maxs.get_data1i(),
  3475. ends[i] - start,
  3476. get_numeric_type(reader->get_index_type()),
  3477. client_pointer + start * index_stride);
  3478. }
  3479. start = ends[i] + 2;
  3480. }
  3481. } else {
  3482. unsigned int start = 0;
  3483. int first_vertex = reader->get_first_vertex();
  3484. for (size_t i = 0; i < ends.size(); i++) {
  3485. _vertices_tristrip_pcollector.add_level(ends[i] - start);
  3486. #ifndef OPENGLES_1
  3487. if (_supports_geometry_instancing && _instance_count > 0) {
  3488. _glDrawArraysInstanced(GL_TRIANGLE_STRIP, first_vertex + start,
  3489. ends[i] - start, _instance_count);
  3490. } else
  3491. #endif
  3492. {
  3493. glDrawArrays(GL_TRIANGLE_STRIP, first_vertex + start,
  3494. ends[i] - start);
  3495. }
  3496. start = ends[i] + 2;
  3497. }
  3498. }
  3499. }
  3500. }
  3501. report_my_gl_errors();
  3502. return true;
  3503. }
  3504. ////////////////////////////////////////////////////////////////////
  3505. // Function: GLGraphicsStateGuardian::draw_trifans
  3506. // Access: Public, Virtual
  3507. // Description: Draws a series of triangle fans.
  3508. ////////////////////////////////////////////////////////////////////
  3509. bool CLP(GraphicsStateGuardian)::
  3510. draw_trifans(const GeomPrimitivePipelineReader *reader, bool force) {
  3511. //PStatGPUTimer timer(this, _draw_primitive_pcollector, reader->get_current_thread());
  3512. #ifndef NDEBUG
  3513. if (GLCAT.is_spam()) {
  3514. GLCAT.spam() << "draw_trifans: " << *(reader->get_object()) << "\n";
  3515. }
  3516. #endif // NDEBUG
  3517. #ifdef SUPPORT_IMMEDIATE_MODE
  3518. if (_use_sender) {
  3519. draw_immediate_composite_primitives(reader, GL_TRIANGLE_FAN);
  3520. } else
  3521. #endif // SUPPORT_IMMEDIATE_MODE
  3522. {
  3523. // Send the individual triangle fans. There's no connecting fans
  3524. // with degenerate vertices, so no worries about that.
  3525. CPTA_int ends = reader->get_ends();
  3526. _primitive_batches_trifan_pcollector.add_level(ends.size());
  3527. if (reader->is_indexed()) {
  3528. const unsigned char *client_pointer;
  3529. if (!setup_primitive(client_pointer, reader, force)) {
  3530. return false;
  3531. }
  3532. int index_stride = reader->get_index_stride();
  3533. GeomVertexReader mins(reader->get_mins(), 0);
  3534. GeomVertexReader maxs(reader->get_maxs(), 0);
  3535. nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() &&
  3536. reader->get_maxs()->get_num_rows() == (int)ends.size(), false);
  3537. unsigned int start = 0;
  3538. for (size_t i = 0; i < ends.size(); i++) {
  3539. _vertices_trifan_pcollector.add_level(ends[i] - start);
  3540. #ifndef OPENGLES_1
  3541. if (_supports_geometry_instancing && _instance_count > 0) {
  3542. _glDrawElementsInstanced(GL_TRIANGLE_FAN, ends[i] - start,
  3543. get_numeric_type(reader->get_index_type()),
  3544. client_pointer + start * index_stride,
  3545. _instance_count);
  3546. } else
  3547. #endif
  3548. {
  3549. _glDrawRangeElements(GL_TRIANGLE_FAN,
  3550. mins.get_data1i(), maxs.get_data1i(), ends[i] - start,
  3551. get_numeric_type(reader->get_index_type()),
  3552. client_pointer + start * index_stride);
  3553. }
  3554. start = ends[i];
  3555. }
  3556. } else {
  3557. unsigned int start = 0;
  3558. int first_vertex = reader->get_first_vertex();
  3559. for (size_t i = 0; i < ends.size(); i++) {
  3560. _vertices_trifan_pcollector.add_level(ends[i] - start);
  3561. #ifndef OPENGLES_1
  3562. if (_supports_geometry_instancing && _instance_count > 0) {
  3563. _glDrawArraysInstanced(GL_TRIANGLE_FAN, first_vertex + start,
  3564. ends[i] - start, _instance_count);
  3565. } else
  3566. #endif
  3567. {
  3568. glDrawArrays(GL_TRIANGLE_FAN, first_vertex + start,
  3569. ends[i] - start);
  3570. }
  3571. start = ends[i];
  3572. }
  3573. }
  3574. }
  3575. report_my_gl_errors();
  3576. return true;
  3577. }
  3578. ////////////////////////////////////////////////////////////////////
  3579. // Function: GLGraphicsStateGuardian::draw_patches
  3580. // Access: Public, Virtual
  3581. // Description: Draws a series of "patches", which can only be
  3582. // processed by a tessellation shader.
  3583. ////////////////////////////////////////////////////////////////////
  3584. bool CLP(GraphicsStateGuardian)::
  3585. draw_patches(const GeomPrimitivePipelineReader *reader, bool force) {
  3586. //PStatGPUTimer timer(this, _draw_primitive_pcollector, reader->get_current_thread());
  3587. #ifndef NDEBUG
  3588. if (GLCAT.is_spam()) {
  3589. GLCAT.spam() << "draw_patches: " << *(reader->get_object()) << "\n";
  3590. }
  3591. #endif // NDEBUG
  3592. if (!get_supports_tessellation_shaders()) {
  3593. return false;
  3594. }
  3595. #ifndef OPENGLES
  3596. _glPatchParameteri(GL_PATCH_VERTICES, reader->get_object()->get_num_vertices_per_primitive());
  3597. #ifdef SUPPORT_IMMEDIATE_MODE
  3598. if (_use_sender) {
  3599. draw_immediate_simple_primitives(reader, GL_PATCHES);
  3600. } else
  3601. #endif // SUPPORT_IMMEDIATE_MODE
  3602. {
  3603. int num_vertices = reader->get_num_vertices();
  3604. _vertices_patch_pcollector.add_level(num_vertices);
  3605. _primitive_batches_patch_pcollector.add_level(1);
  3606. if (reader->is_indexed()) {
  3607. const unsigned char *client_pointer;
  3608. if (!setup_primitive(client_pointer, reader, force)) {
  3609. return false;
  3610. }
  3611. #ifndef OPENGLES_1
  3612. if (_supports_geometry_instancing && _instance_count > 0) {
  3613. _glDrawElementsInstanced(GL_PATCHES, num_vertices,
  3614. get_numeric_type(reader->get_index_type()),
  3615. client_pointer, _instance_count);
  3616. } else
  3617. #endif
  3618. {
  3619. _glDrawRangeElements(GL_PATCHES,
  3620. reader->get_min_vertex(),
  3621. reader->get_max_vertex(),
  3622. num_vertices,
  3623. get_numeric_type(reader->get_index_type()),
  3624. client_pointer);
  3625. }
  3626. } else {
  3627. #ifndef OPENGLES_1
  3628. if (_supports_geometry_instancing && _instance_count > 0) {
  3629. _glDrawArraysInstanced(GL_PATCHES,
  3630. reader->get_first_vertex(),
  3631. num_vertices, _instance_count);
  3632. } else
  3633. #endif
  3634. {
  3635. glDrawArrays(GL_PATCHES,
  3636. reader->get_first_vertex(),
  3637. num_vertices);
  3638. }
  3639. }
  3640. }
  3641. #endif // OPENGLES
  3642. report_my_gl_errors();
  3643. return true;
  3644. }
  3645. ////////////////////////////////////////////////////////////////////
  3646. // Function: GLGraphicsStateGuardian::draw_lines
  3647. // Access: Public, Virtual
  3648. // Description: Draws a series of disconnected line segments.
  3649. ////////////////////////////////////////////////////////////////////
  3650. bool CLP(GraphicsStateGuardian)::
  3651. draw_lines(const GeomPrimitivePipelineReader *reader, bool force) {
  3652. //PStatGPUTimer timer(this, _draw_primitive_pcollector, reader->get_current_thread());
  3653. #ifndef NDEBUG
  3654. if (GLCAT.is_spam()) {
  3655. GLCAT.spam() << "draw_lines: " << *(reader->get_object()) << "\n";
  3656. }
  3657. #endif // NDEBUG
  3658. #ifdef SUPPORT_IMMEDIATE_MODE
  3659. if (_use_sender) {
  3660. draw_immediate_simple_primitives(reader, GL_LINES);
  3661. } else
  3662. #endif // SUPPORT_IMMEDIATE_MODE
  3663. {
  3664. int num_vertices = reader->get_num_vertices();
  3665. _vertices_other_pcollector.add_level(num_vertices);
  3666. _primitive_batches_other_pcollector.add_level(1);
  3667. if (reader->is_indexed()) {
  3668. const unsigned char *client_pointer;
  3669. if (!setup_primitive(client_pointer, reader, force)) {
  3670. return false;
  3671. }
  3672. #ifndef OPENGLES_1
  3673. if (_supports_geometry_instancing && _instance_count > 0) {
  3674. _glDrawElementsInstanced(GL_LINES, num_vertices,
  3675. get_numeric_type(reader->get_index_type()),
  3676. client_pointer, _instance_count);
  3677. } else
  3678. #endif
  3679. {
  3680. _glDrawRangeElements(GL_LINES,
  3681. reader->get_min_vertex(),
  3682. reader->get_max_vertex(),
  3683. num_vertices,
  3684. get_numeric_type(reader->get_index_type()),
  3685. client_pointer);
  3686. }
  3687. } else {
  3688. #ifndef OPENGLES_1
  3689. if (_supports_geometry_instancing && _instance_count > 0) {
  3690. _glDrawArraysInstanced(GL_LINES,
  3691. reader->get_first_vertex(),
  3692. num_vertices, _instance_count);
  3693. } else
  3694. #endif
  3695. {
  3696. glDrawArrays(GL_LINES,
  3697. reader->get_first_vertex(),
  3698. num_vertices);
  3699. }
  3700. }
  3701. }
  3702. report_my_gl_errors();
  3703. return true;
  3704. }
  3705. ////////////////////////////////////////////////////////////////////
  3706. // Function: GLGraphicsStateGuardian::draw_linestrips
  3707. // Access: Public, Virtual
  3708. // Description: Draws a series of line strips.
  3709. ////////////////////////////////////////////////////////////////////
  3710. bool CLP(GraphicsStateGuardian)::
  3711. draw_linestrips(const GeomPrimitivePipelineReader *reader, bool force) {
  3712. //PStatGPUTimer timer(this, _draw_primitive_pcollector, reader->get_current_thread());
  3713. report_my_gl_errors();
  3714. #ifndef NDEBUG
  3715. if (GLCAT.is_spam()) {
  3716. GLCAT.spam() << "draw_linestrips: " << *(reader->get_object()) << "\n";
  3717. }
  3718. #endif // NDEBUG
  3719. #ifdef SUPPORT_IMMEDIATE_MODE
  3720. if (_use_sender) {
  3721. draw_immediate_composite_primitives(reader, GL_LINE_STRIP);
  3722. } else
  3723. #endif // SUPPORT_IMMEDIATE_MODE
  3724. {
  3725. if (reader->is_indexed() &&
  3726. (_supported_geom_rendering & GeomEnums::GR_strip_cut_index) != 0) {
  3727. // One long triangle strip, connected by strip cut indices.
  3728. #ifndef OPENGLES
  3729. if (_explicit_primitive_restart) {
  3730. glEnable(GL_PRIMITIVE_RESTART);
  3731. _glPrimitiveRestartIndex(reader->get_strip_cut_index());
  3732. }
  3733. #endif // !OPENGLES
  3734. int num_vertices = reader->get_num_vertices();
  3735. _vertices_other_pcollector.add_level(num_vertices);
  3736. _primitive_batches_other_pcollector.add_level(1);
  3737. const unsigned char *client_pointer;
  3738. if (!setup_primitive(client_pointer, reader, force)) {
  3739. return false;
  3740. }
  3741. #ifndef OPENGLES_1
  3742. if (_supports_geometry_instancing && _instance_count > 0) {
  3743. _glDrawElementsInstanced(GL_LINE_STRIP, num_vertices,
  3744. get_numeric_type(reader->get_index_type()),
  3745. client_pointer, _instance_count);
  3746. } else
  3747. #endif // !OPENGLES
  3748. {
  3749. _glDrawRangeElements(GL_LINE_STRIP,
  3750. reader->get_min_vertex(),
  3751. reader->get_max_vertex(),
  3752. num_vertices,
  3753. get_numeric_type(reader->get_index_type()),
  3754. client_pointer);
  3755. }
  3756. #ifndef OPENGLES
  3757. if (_explicit_primitive_restart) {
  3758. glDisable(GL_PRIMITIVE_RESTART);
  3759. }
  3760. #endif // !OPENGLES
  3761. } else {
  3762. // Send the individual line strips, stepping over the
  3763. // strip-cut indices.
  3764. CPTA_int ends = reader->get_ends();
  3765. _primitive_batches_other_pcollector.add_level(ends.size());
  3766. if (reader->is_indexed()) {
  3767. const unsigned char *client_pointer;
  3768. if (!setup_primitive(client_pointer, reader, force)) {
  3769. return false;
  3770. }
  3771. int index_stride = reader->get_index_stride();
  3772. GeomVertexReader mins(reader->get_mins(), 0);
  3773. GeomVertexReader maxs(reader->get_maxs(), 0);
  3774. nassertr(reader->get_mins()->get_num_rows() == (int)ends.size() &&
  3775. reader->get_maxs()->get_num_rows() == (int)ends.size(), false);
  3776. unsigned int start = 0;
  3777. for (size_t i = 0; i < ends.size(); i++) {
  3778. _vertices_other_pcollector.add_level(ends[i] - start);
  3779. #ifndef OPENGLES_1
  3780. if (_supports_geometry_instancing && _instance_count > 0) {
  3781. _glDrawElementsInstanced(GL_LINE_STRIP, ends[i] - start,
  3782. get_numeric_type(reader->get_index_type()),
  3783. client_pointer + start * index_stride,
  3784. _instance_count);
  3785. } else
  3786. #endif
  3787. {
  3788. _glDrawRangeElements(GL_LINE_STRIP,
  3789. mins.get_data1i(), maxs.get_data1i(),
  3790. ends[i] - start,
  3791. get_numeric_type(reader->get_index_type()),
  3792. client_pointer + start * index_stride);
  3793. }
  3794. start = ends[i] + 1;
  3795. }
  3796. } else {
  3797. unsigned int start = 0;
  3798. int first_vertex = reader->get_first_vertex();
  3799. for (size_t i = 0; i < ends.size(); i++) {
  3800. _vertices_other_pcollector.add_level(ends[i] - start);
  3801. #ifndef OPENGLES_1
  3802. if (_supports_geometry_instancing && _instance_count > 0) {
  3803. _glDrawArraysInstanced(GL_LINE_STRIP, first_vertex + start,
  3804. ends[i] - start, _instance_count);
  3805. } else
  3806. #endif
  3807. {
  3808. glDrawArrays(GL_LINE_STRIP, first_vertex + start, ends[i] - start);
  3809. }
  3810. start = ends[i] + 1;
  3811. }
  3812. }
  3813. }
  3814. }
  3815. report_my_gl_errors();
  3816. return true;
  3817. }
  3818. ////////////////////////////////////////////////////////////////////
  3819. // Function: GLGraphicsStateGuardian::draw_points
  3820. // Access: Public, Virtual
  3821. // Description: Draws a series of disconnected points.
  3822. ////////////////////////////////////////////////////////////////////
  3823. bool CLP(GraphicsStateGuardian)::
  3824. draw_points(const GeomPrimitivePipelineReader *reader, bool force) {
  3825. //PStatGPUTimer timer(this, _draw_primitive_pcollector, reader->get_current_thread());
  3826. #ifndef NDEBUG
  3827. if (GLCAT.is_spam()) {
  3828. GLCAT.spam() << "draw_points: " << *(reader->get_object()) << "\n";
  3829. }
  3830. #endif // NDEBUG
  3831. #ifdef SUPPORT_IMMEDIATE_MODE
  3832. if (_use_sender) {
  3833. draw_immediate_simple_primitives(reader, GL_POINTS);
  3834. } else
  3835. #endif // SUPPORT_IMMEDIATE_MODE
  3836. {
  3837. int num_vertices = reader->get_num_vertices();
  3838. _vertices_other_pcollector.add_level(num_vertices);
  3839. _primitive_batches_other_pcollector.add_level(1);
  3840. if (reader->is_indexed()) {
  3841. const unsigned char *client_pointer;
  3842. if (!setup_primitive(client_pointer, reader, force)) {
  3843. return false;
  3844. }
  3845. #ifndef OPENGLES_1
  3846. if (_supports_geometry_instancing && _instance_count > 0) {
  3847. _glDrawElementsInstanced(GL_POINTS, num_vertices,
  3848. get_numeric_type(reader->get_index_type()),
  3849. client_pointer, _instance_count);
  3850. } else
  3851. #endif
  3852. {
  3853. _glDrawRangeElements(GL_POINTS,
  3854. reader->get_min_vertex(),
  3855. reader->get_max_vertex(),
  3856. num_vertices,
  3857. get_numeric_type(reader->get_index_type()),
  3858. client_pointer);
  3859. }
  3860. } else {
  3861. #ifndef OPENGLES_1
  3862. if (_supports_geometry_instancing && _instance_count > 0) {
  3863. _glDrawArraysInstanced(GL_POINTS,
  3864. reader->get_first_vertex(),
  3865. num_vertices, _instance_count);
  3866. } else
  3867. #endif
  3868. {
  3869. glDrawArrays(GL_POINTS, reader->get_first_vertex(), num_vertices);
  3870. }
  3871. }
  3872. }
  3873. report_my_gl_errors();
  3874. return true;
  3875. }
  3876. ////////////////////////////////////////////////////////////////////
  3877. // Function: GLGraphicsStateGuardian::end_draw_primitives()
  3878. // Access: Public, Virtual
  3879. // Description: Called after a sequence of draw_primitive()
  3880. // functions are called, this should do whatever cleanup
  3881. // is appropriate.
  3882. ////////////////////////////////////////////////////////////////////
  3883. void CLP(GraphicsStateGuardian)::
  3884. end_draw_primitives() {
  3885. #if !defined(OPENGLES) && defined(SUPPORT_FIXED_FUNCTION) // Display lists not supported by OpenGL ES.
  3886. if (_geom_display_list != 0) {
  3887. // If we were building a display list, close it now.
  3888. glEndList();
  3889. _load_display_list_pcollector.stop();
  3890. if (!gl_compile_and_execute) {
  3891. glCallList(_geom_display_list);
  3892. }
  3893. _primitive_batches_display_list_pcollector.add_level(1);
  3894. }
  3895. _geom_display_list = 0;
  3896. #endif
  3897. #ifdef SUPPORT_FIXED_FUNCTION
  3898. if (_transform_stale) {
  3899. glMatrixMode(GL_MODELVIEW);
  3900. GLPf(LoadMatrix)(_internal_transform->get_mat().get_data());
  3901. }
  3902. if (_data_reader->is_vertex_transformed()) {
  3903. // Restore the matrices that we pushed above.
  3904. glMatrixMode(GL_PROJECTION);
  3905. glPopMatrix();
  3906. glMatrixMode(GL_MODELVIEW);
  3907. glPopMatrix();
  3908. }
  3909. #endif
  3910. GraphicsStateGuardian::end_draw_primitives();
  3911. maybe_gl_finish();
  3912. report_my_gl_errors();
  3913. }
  3914. #ifndef OPENGLES
  3915. ////////////////////////////////////////////////////////////////////
  3916. // Function: GLGraphicsStateGuardian::issue_memory_barrier
  3917. // Access: Public
  3918. // Description: Issues the given memory barriers, and clears the
  3919. // list of textures marked as incoherent for the given
  3920. // bits.
  3921. ////////////////////////////////////////////////////////////////////
  3922. void CLP(GraphicsStateGuardian)::
  3923. issue_memory_barrier(GLbitfield barriers) {
  3924. if (!gl_enable_memory_barriers || _glMemoryBarrier == NULL) {
  3925. return;
  3926. }
  3927. PStatGPUTimer timer(this, _memory_barrier_pcollector);
  3928. if (GLCAT.is_spam()) {
  3929. GLCAT.spam() << "Issuing memory barriers:";
  3930. }
  3931. _glMemoryBarrier(barriers);
  3932. // Indicate that barriers no longer need to be issued for
  3933. // the relevant lists of textures.
  3934. if (barriers & GL_TEXTURE_FETCH_BARRIER_BIT) {
  3935. _textures_needing_fetch_barrier.clear();
  3936. GLCAT.spam(false) << " texture_fetch";
  3937. }
  3938. if (barriers & GL_SHADER_IMAGE_ACCESS_BARRIER_BIT) {
  3939. _textures_needing_image_access_barrier.clear();
  3940. GLCAT.spam(false) << " shader_image_access";
  3941. }
  3942. if (barriers & GL_TEXTURE_UPDATE_BARRIER_BIT) {
  3943. _textures_needing_update_barrier.clear();
  3944. GLCAT.spam(false) << " texture_update";
  3945. }
  3946. if (barriers & GL_FRAMEBUFFER_BARRIER_BIT) {
  3947. _textures_needing_framebuffer_barrier.clear();
  3948. GLCAT.spam(false) << " framebuffer";
  3949. }
  3950. GLCAT.spam(false) << "\n";
  3951. report_my_gl_errors();
  3952. }
  3953. #endif // OPENGLES
  3954. ////////////////////////////////////////////////////////////////////
  3955. // Function: GLGraphicsStateGuardian::prepare_texture
  3956. // Access: Public, Virtual
  3957. // Description: Creates whatever structures the GSG requires to
  3958. // represent the texture internally, and returns a
  3959. // newly-allocated TextureContext object with this data.
  3960. // It is the responsibility of the calling function to
  3961. // later call release_texture() with this same pointer
  3962. // (which will also delete the pointer).
  3963. //
  3964. // This function should not be called directly to
  3965. // prepare a texture. Instead, call Texture::prepare().
  3966. ////////////////////////////////////////////////////////////////////
  3967. TextureContext *CLP(GraphicsStateGuardian)::
  3968. prepare_texture(Texture *tex, int view) {
  3969. PStatGPUTimer timer(this, _prepare_texture_pcollector);
  3970. report_my_gl_errors();
  3971. // Make sure we'll support this texture when it's rendered. Don't
  3972. // bother to prepare it if we won't.
  3973. switch (tex->get_texture_type()) {
  3974. case Texture::TT_3d_texture:
  3975. if (!_supports_3d_texture) {
  3976. GLCAT.warning()
  3977. << "3-D textures are not supported by this OpenGL driver.\n";
  3978. return NULL;
  3979. }
  3980. break;
  3981. case Texture::TT_2d_texture_array:
  3982. if (!_supports_2d_texture_array) {
  3983. GLCAT.warning()
  3984. << "2-D texture arrays are not supported by this OpenGL driver.\n";
  3985. return NULL;
  3986. }
  3987. break;
  3988. case Texture::TT_cube_map:
  3989. if (!_supports_cube_map) {
  3990. GLCAT.warning()
  3991. << "Cube map textures are not supported by this OpenGL driver.\n";
  3992. return NULL;
  3993. }
  3994. break;
  3995. case Texture::TT_buffer_texture:
  3996. if (!_supports_buffer_texture) {
  3997. GLCAT.warning()
  3998. << "Buffer textures are not supported by this OpenGL driver.\n";
  3999. return NULL;
  4000. }
  4001. break;
  4002. default:
  4003. break;
  4004. }
  4005. CLP(TextureContext) *gtc = new CLP(TextureContext)(this, _prepared_objects, tex, view);
  4006. report_my_gl_errors();
  4007. return gtc;
  4008. }
  4009. ////////////////////////////////////////////////////////////////////
  4010. // Function: GLGraphicsStateGuardian::update_texture
  4011. // Access: Public, Virtual
  4012. // Description: Ensures that the current Texture data is refreshed
  4013. // onto the GSG. This means updating the texture
  4014. // properties and/or re-uploading the texture image, if
  4015. // necessary. This should only be called within the
  4016. // draw thread.
  4017. //
  4018. // If force is true, this function will not return until
  4019. // the texture has been fully uploaded. If force is
  4020. // false, the function may choose to upload a simple
  4021. // version of the texture instead, if the texture is not
  4022. // fully resident (and if get_incomplete_render() is
  4023. // true).
  4024. ////////////////////////////////////////////////////////////////////
  4025. bool CLP(GraphicsStateGuardian)::
  4026. update_texture(TextureContext *tc, bool force) {
  4027. CLP(TextureContext) *gtc;
  4028. DCAST_INTO_R(gtc, tc, false);
  4029. if (gtc->was_image_modified() || !gtc->_has_storage) {
  4030. PStatGPUTimer timer(this, _texture_update_pcollector);
  4031. // If the texture image was modified, reload the texture.
  4032. apply_texture(gtc);
  4033. Texture *tex = tc->get_texture();
  4034. if (gtc->was_properties_modified()) {
  4035. specify_texture(gtc, tex->get_default_sampler());
  4036. }
  4037. bool okflag = upload_texture(gtc, force, tex->uses_mipmaps());
  4038. if (!okflag) {
  4039. GLCAT.error()
  4040. << "Could not load " << *tex << "\n";
  4041. return false;
  4042. }
  4043. } else if (gtc->was_properties_modified()) {
  4044. PStatGPUTimer timer(this, _texture_update_pcollector);
  4045. // If only the properties have been modified, we don't necessarily
  4046. // need to reload the texture.
  4047. apply_texture(gtc);
  4048. Texture *tex = tc->get_texture();
  4049. if (specify_texture(gtc, tex->get_default_sampler())) {
  4050. // Actually, looks like the texture *does* need to be reloaded.
  4051. gtc->mark_needs_reload();
  4052. bool okflag = upload_texture(gtc, force, tex->uses_mipmaps());
  4053. if (!okflag) {
  4054. GLCAT.error()
  4055. << "Could not load " << *tex << "\n";
  4056. return false;
  4057. }
  4058. } else {
  4059. // The texture didn't need reloading, but mark it fully updated
  4060. // now.
  4061. gtc->mark_loaded();
  4062. }
  4063. }
  4064. gtc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  4065. report_my_gl_errors();
  4066. return true;
  4067. }
  4068. ////////////////////////////////////////////////////////////////////
  4069. // Function: GLGraphicsStateGuardian::release_texture
  4070. // Access: Public, Virtual
  4071. // Description: Frees the GL resources previously allocated for the
  4072. // texture. This function should never be called
  4073. // directly; instead, call Texture::release() (or simply
  4074. // let the Texture destruct).
  4075. ////////////////////////////////////////////////////////////////////
  4076. void CLP(GraphicsStateGuardian)::
  4077. release_texture(TextureContext *tc) {
  4078. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
  4079. delete gtc;
  4080. }
  4081. ////////////////////////////////////////////////////////////////////
  4082. // Function: GLGraphicsStateGuardian::extract_texture_data
  4083. // Access: Public, Virtual
  4084. // Description: This method should only be called by the
  4085. // GraphicsEngine. Do not call it directly; call
  4086. // GraphicsEngine::extract_texture_data() instead.
  4087. //
  4088. // This method will be called in the draw thread to
  4089. // download the texture memory's image into its
  4090. // ram_image value. It returns true on success, false
  4091. // otherwise.
  4092. ////////////////////////////////////////////////////////////////////
  4093. bool CLP(GraphicsStateGuardian)::
  4094. extract_texture_data(Texture *tex) {
  4095. bool success = true;
  4096. // Make sure the error stack is cleared out before we begin.
  4097. report_my_gl_errors();
  4098. int num_views = tex->get_num_views();
  4099. for (int view = 0; view < num_views; ++view) {
  4100. TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this);
  4101. nassertr(tc != (TextureContext *)NULL, false);
  4102. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
  4103. if (!do_extract_texture_data(gtc)) {
  4104. success = false;
  4105. }
  4106. }
  4107. return success;
  4108. }
  4109. #ifndef OPENGLES
  4110. ////////////////////////////////////////////////////////////////////
  4111. // Function: GLGraphicsStateGuardian::prepare_sampler
  4112. // Access: Public, Virtual
  4113. // Description: Creates whatever structures the GSG requires to
  4114. // represent the sampler state internally, and returns a
  4115. // newly-allocated SamplerContext object with this data.
  4116. // It is the responsibility of the calling function to
  4117. // later call release_sampler() with this same pointer
  4118. // (which will also delete the pointer).
  4119. //
  4120. // This function should not be called directly to
  4121. // prepare a sampler object. Instead, call
  4122. // SamplerState::prepare().
  4123. ////////////////////////////////////////////////////////////////////
  4124. SamplerContext *CLP(GraphicsStateGuardian)::
  4125. prepare_sampler(const SamplerState &sampler) {
  4126. nassertr(_supports_sampler_objects, NULL);
  4127. PStatGPUTimer timer(this, _prepare_sampler_pcollector);
  4128. CLP(SamplerContext) *gsc = new CLP(SamplerContext)(this, sampler);
  4129. GLuint index = gsc->_index;
  4130. // Sampler contexts are immutable in Panda, so might as well just
  4131. // initialize all the settings here.
  4132. _glSamplerParameteri(index, GL_TEXTURE_WRAP_S,
  4133. get_texture_wrap_mode(sampler.get_wrap_u()));
  4134. _glSamplerParameteri(index, GL_TEXTURE_WRAP_T,
  4135. get_texture_wrap_mode(sampler.get_wrap_v()));
  4136. _glSamplerParameteri(index, GL_TEXTURE_WRAP_R,
  4137. get_texture_wrap_mode(sampler.get_wrap_w()));
  4138. #ifdef STDFLOAT_DOUBLE
  4139. LVecBase4f fvalue = LCAST(float, sampler.get_border_color());
  4140. _glSamplerParameterfv(index, GL_TEXTURE_BORDER_COLOR, fvalue.get_data());
  4141. #else
  4142. _glSamplerParameterfv(index, GL_TEXTURE_BORDER_COLOR,
  4143. sampler.get_border_color().get_data());
  4144. #endif
  4145. SamplerState::FilterType minfilter = sampler.get_effective_minfilter();
  4146. SamplerState::FilterType magfilter = sampler.get_effective_magfilter();
  4147. bool uses_mipmaps = SamplerState::is_mipmap(minfilter) && !gl_ignore_mipmaps;
  4148. #ifndef NDEBUG
  4149. if (gl_force_mipmaps) {
  4150. minfilter = SamplerState::FT_linear_mipmap_linear;
  4151. magfilter = SamplerState::FT_linear;
  4152. uses_mipmaps = true;
  4153. }
  4154. #endif
  4155. _glSamplerParameteri(index, GL_TEXTURE_MIN_FILTER,
  4156. get_texture_filter_type(minfilter, !uses_mipmaps));
  4157. _glSamplerParameteri(index, GL_TEXTURE_MAG_FILTER,
  4158. get_texture_filter_type(magfilter, true));
  4159. // Set anisotropic filtering.
  4160. if (_supports_anisotropy) {
  4161. PN_stdfloat anisotropy = sampler.get_effective_anisotropic_degree();
  4162. anisotropy = min(anisotropy, _max_anisotropy);
  4163. anisotropy = max(anisotropy, (PN_stdfloat)1.0);
  4164. _glSamplerParameterf(index, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
  4165. }
  4166. if (_supports_shadow_filter) {
  4167. if ((sampler.get_magfilter() == SamplerState::FT_shadow) ||
  4168. (sampler.get_minfilter() == SamplerState::FT_shadow)) {
  4169. _glSamplerParameteri(index, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
  4170. _glSamplerParameteri(index, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
  4171. } else {
  4172. _glSamplerParameteri(index, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
  4173. _glSamplerParameteri(index, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
  4174. }
  4175. }
  4176. _glSamplerParameterf(index, GL_TEXTURE_MIN_LOD, sampler.get_min_lod());
  4177. _glSamplerParameterf(index, GL_TEXTURE_MAX_LOD, sampler.get_max_lod());
  4178. _glSamplerParameterf(index, GL_TEXTURE_LOD_BIAS, sampler.get_lod_bias());
  4179. gsc->enqueue_lru(&_prepared_objects->_sampler_object_lru);
  4180. report_my_gl_errors();
  4181. return gsc;
  4182. }
  4183. #endif // !OPENGLES
  4184. #ifndef OPENGLES
  4185. ////////////////////////////////////////////////////////////////////
  4186. // Function: GLGraphicsStateGuardian::release_sampler
  4187. // Access: Public, Virtual
  4188. // Description: Frees the GL resources previously allocated for the
  4189. // sampler. This function should never be called
  4190. // directly; instead, call SamplerState::release().
  4191. ////////////////////////////////////////////////////////////////////
  4192. void CLP(GraphicsStateGuardian)::
  4193. release_sampler(SamplerContext *sc) {
  4194. CLP(SamplerContext) *gsc = DCAST(CLP(SamplerContext), sc);
  4195. delete gsc;
  4196. }
  4197. #endif // !OPENGLES
  4198. ////////////////////////////////////////////////////////////////////
  4199. // Function: GLGraphicsStateGuardian::prepare_geom
  4200. // Access: Public, Virtual
  4201. // Description: Creates a new retained-mode representation of the
  4202. // given geom, and returns a newly-allocated
  4203. // GeomContext pointer to reference it. It is the
  4204. // responsibility of the calling function to later
  4205. // call release_geom() with this same pointer (which
  4206. // will also delete the pointer).
  4207. //
  4208. // This function should not be called directly to
  4209. // prepare a geom. Instead, call Geom::prepare().
  4210. ////////////////////////////////////////////////////////////////////
  4211. GeomContext *CLP(GraphicsStateGuardian)::
  4212. prepare_geom(Geom *geom) {
  4213. PStatGPUTimer timer(this, _prepare_geom_pcollector);
  4214. return new CLP(GeomContext)(geom);
  4215. }
  4216. ////////////////////////////////////////////////////////////////////
  4217. // Function: GLGraphicsStateGuardian::release_geom
  4218. // Access: Public, Virtual
  4219. // Description: Frees the GL resources previously allocated for the
  4220. // geom. This function should never be called
  4221. // directly; instead, call Geom::release() (or simply
  4222. // let the Geom destruct).
  4223. ////////////////////////////////////////////////////////////////////
  4224. void CLP(GraphicsStateGuardian)::
  4225. release_geom(GeomContext *gc) {
  4226. CLP(GeomContext) *ggc = DCAST(CLP(GeomContext), gc);
  4227. ggc->release_display_lists();
  4228. report_my_gl_errors();
  4229. delete ggc;
  4230. }
  4231. ////////////////////////////////////////////////////////////////////
  4232. // Function: GLGraphicsStateGuardian::prepare_shader
  4233. // Access: Public, Virtual
  4234. // Description:
  4235. ////////////////////////////////////////////////////////////////////
  4236. ShaderContext *CLP(GraphicsStateGuardian)::
  4237. prepare_shader(Shader *se) {
  4238. PStatGPUTimer timer(this, _prepare_shader_pcollector);
  4239. #ifndef OPENGLES_1
  4240. ShaderContext *result = NULL;
  4241. switch (se->get_language()) {
  4242. case Shader::SL_GLSL:
  4243. if (_supports_glsl) {
  4244. result = new CLP(ShaderContext)(this, se);
  4245. break;
  4246. } else {
  4247. GLCAT.error()
  4248. << "Tried to load GLSL shader, but GLSL shaders not supported.\n";
  4249. return NULL;
  4250. }
  4251. case Shader::SL_Cg:
  4252. #if defined(HAVE_CG) && !defined(OPENGLES)
  4253. if (_supports_basic_shaders) {
  4254. result = new CLP(CgShaderContext)(this, se);
  4255. break;
  4256. } else {
  4257. GLCAT.error()
  4258. << "Tried to load Cg shader, but basic shaders not supported.\n";
  4259. return NULL;
  4260. }
  4261. #elif defined(OPENGLES)
  4262. GLCAT.error()
  4263. << "Tried to load Cg shader, but Cg support is not available for OpenGL ES.\n";
  4264. return NULL;
  4265. #else
  4266. GLCAT.error()
  4267. << "Tried to load Cg shader, but Cg support not compiled in.\n";
  4268. return NULL;
  4269. #endif
  4270. default:
  4271. GLCAT.error()
  4272. << "Tried to load shader with unsupported shader language!\n";
  4273. return NULL;
  4274. }
  4275. if (result->valid()) {
  4276. return result;
  4277. }
  4278. delete result;
  4279. #endif // OPENGLES_1
  4280. return NULL;
  4281. }
  4282. ////////////////////////////////////////////////////////////////////
  4283. // Function: GLGraphicsStateGuardian::release_shader
  4284. // Access: Public, Virtual
  4285. // Description:
  4286. ////////////////////////////////////////////////////////////////////
  4287. void CLP(GraphicsStateGuardian)::
  4288. release_shader(ShaderContext *sc) {
  4289. delete sc;
  4290. }
  4291. ////////////////////////////////////////////////////////////////////
  4292. // Function: GLGraphicsStateGuardian::record_deleted_display_list
  4293. // Access: Public
  4294. // Description: This is intended to be called only from the
  4295. // GLGeomContext destructor. It saves the indicated
  4296. // display list index in the list to be deleted at the
  4297. // end of the frame.
  4298. ////////////////////////////////////////////////////////////////////
  4299. void CLP(GraphicsStateGuardian)::
  4300. record_deleted_display_list(GLuint index) {
  4301. LightMutexHolder holder(_lock);
  4302. _deleted_display_lists.push_back(index);
  4303. }
  4304. ////////////////////////////////////////////////////////////////////
  4305. // Function: GLGraphicsStateGuardian::prepare_vertex_buffer
  4306. // Access: Public, Virtual
  4307. // Description: Creates a new retained-mode representation of the
  4308. // given data, and returns a newly-allocated
  4309. // VertexBufferContext pointer to reference it. It is the
  4310. // responsibility of the calling function to later
  4311. // call release_vertex_buffer() with this same pointer (which
  4312. // will also delete the pointer).
  4313. //
  4314. // This function should not be called directly to
  4315. // prepare a buffer. Instead, call Geom::prepare().
  4316. ////////////////////////////////////////////////////////////////////
  4317. VertexBufferContext *CLP(GraphicsStateGuardian)::
  4318. prepare_vertex_buffer(GeomVertexArrayData *data) {
  4319. if (_supports_buffers) {
  4320. PStatGPUTimer timer(this, _prepare_vertex_buffer_pcollector);
  4321. CLP(VertexBufferContext) *gvbc = new CLP(VertexBufferContext)(this, _prepared_objects, data);
  4322. _glGenBuffers(1, &gvbc->_index);
  4323. if (GLCAT.is_debug() && gl_debug_buffers) {
  4324. GLCAT.debug()
  4325. << "creating vertex buffer " << (int)gvbc->_index << ": "
  4326. << data->get_num_rows() << " vertices "
  4327. << *data->get_array_format() << "\n";
  4328. }
  4329. report_my_gl_errors();
  4330. apply_vertex_buffer(gvbc, data->get_handle(), false);
  4331. return gvbc;
  4332. }
  4333. return NULL;
  4334. }
  4335. ////////////////////////////////////////////////////////////////////
  4336. // Function: GLGraphicsStateGuardian::apply_vertex_buffer
  4337. // Access: Public
  4338. // Description: Makes the data the currently available data for
  4339. // rendering.
  4340. ////////////////////////////////////////////////////////////////////
  4341. bool CLP(GraphicsStateGuardian)::
  4342. apply_vertex_buffer(VertexBufferContext *vbc,
  4343. const GeomVertexArrayDataHandle *reader, bool force) {
  4344. nassertr(_supports_buffers, false);
  4345. if (reader->get_modified() == UpdateSeq::initial()) {
  4346. // No need to re-apply.
  4347. return true;
  4348. }
  4349. CLP(VertexBufferContext) *gvbc = DCAST(CLP(VertexBufferContext), vbc);
  4350. if (_current_vbuffer_index != gvbc->_index) {
  4351. if (GLCAT.is_spam() && gl_debug_buffers) {
  4352. GLCAT.spam()
  4353. << "binding vertex buffer " << (int)gvbc->_index << "\n";
  4354. }
  4355. _glBindBuffer(GL_ARRAY_BUFFER, gvbc->_index);
  4356. _current_vbuffer_index = gvbc->_index;
  4357. gvbc->set_active(true);
  4358. }
  4359. if (gvbc->was_modified(reader)) {
  4360. int num_bytes = reader->get_data_size_bytes();
  4361. if (GLCAT.is_debug() && gl_debug_buffers) {
  4362. GLCAT.debug()
  4363. << "copying " << num_bytes
  4364. << " bytes into vertex buffer " << (int)gvbc->_index << "\n";
  4365. }
  4366. if (num_bytes != 0) {
  4367. const unsigned char *client_pointer = reader->get_read_pointer(force);
  4368. if (client_pointer == NULL) {
  4369. return false;
  4370. }
  4371. PStatGPUTimer timer(this, _load_vertex_buffer_pcollector, reader->get_current_thread());
  4372. if (gvbc->changed_size(reader) || gvbc->changed_usage_hint(reader)) {
  4373. _glBufferData(GL_ARRAY_BUFFER, num_bytes, client_pointer,
  4374. get_usage(reader->get_usage_hint()));
  4375. } else {
  4376. _glBufferSubData(GL_ARRAY_BUFFER, 0, num_bytes, client_pointer);
  4377. }
  4378. _data_transferred_pcollector.add_level(num_bytes);
  4379. }
  4380. gvbc->mark_loaded(reader);
  4381. }
  4382. gvbc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  4383. maybe_gl_finish();
  4384. report_my_gl_errors();
  4385. return true;
  4386. }
  4387. ////////////////////////////////////////////////////////////////////
  4388. // Function: GLGraphicsStateGuardian::release_vertex_buffer
  4389. // Access: Public, Virtual
  4390. // Description: Frees the GL resources previously allocated for the
  4391. // data. This function should never be called
  4392. // directly; instead, call Data::release() (or simply
  4393. // let the Data destruct).
  4394. ////////////////////////////////////////////////////////////////////
  4395. void CLP(GraphicsStateGuardian)::
  4396. release_vertex_buffer(VertexBufferContext *vbc) {
  4397. nassertv(_supports_buffers);
  4398. CLP(VertexBufferContext) *gvbc = DCAST(CLP(VertexBufferContext), vbc);
  4399. if (GLCAT.is_debug() && gl_debug_buffers) {
  4400. GLCAT.debug()
  4401. << "deleting vertex buffer " << (int)gvbc->_index << "\n";
  4402. }
  4403. // Make sure the buffer is unbound before we delete it. Not
  4404. // strictly necessary according to the OpenGL spec, but it might
  4405. // help out a flaky driver, and we need to keep our internal state
  4406. // consistent anyway.
  4407. if (_current_vbuffer_index == gvbc->_index) {
  4408. if (GLCAT.is_spam() && gl_debug_buffers) {
  4409. GLCAT.spam()
  4410. << "unbinding vertex buffer\n";
  4411. }
  4412. _glBindBuffer(GL_ARRAY_BUFFER, 0);
  4413. _current_vbuffer_index = 0;
  4414. }
  4415. _glDeleteBuffers(1, &gvbc->_index);
  4416. report_my_gl_errors();
  4417. gvbc->_index = 0;
  4418. delete gvbc;
  4419. }
  4420. ////////////////////////////////////////////////////////////////////
  4421. // Function: GLGraphicsStateGuardian::setup_array_data
  4422. // Access: Public
  4423. // Description: Internal function to bind a buffer object for the
  4424. // indicated data array, if appropriate, or to unbind a
  4425. // buffer object if it should be rendered from client
  4426. // memory.
  4427. //
  4428. // If the buffer object is bound, this function sets
  4429. // client_pointer to NULL (representing the start of the
  4430. // buffer object in server memory); if the buffer object
  4431. // is not bound, this function sets client_pointer the
  4432. // pointer to the data array in client memory, that is,
  4433. // the data array passed in.
  4434. //
  4435. // If force is not true, the function may return false
  4436. // indicating the data is not currently available.
  4437. ////////////////////////////////////////////////////////////////////
  4438. bool CLP(GraphicsStateGuardian)::
  4439. setup_array_data(const unsigned char *&client_pointer,
  4440. const GeomVertexArrayDataHandle *array_reader,
  4441. bool force) {
  4442. if (!_supports_buffers) {
  4443. // No support for buffer objects; always render from client.
  4444. client_pointer = array_reader->get_read_pointer(force);
  4445. return (client_pointer != NULL);
  4446. }
  4447. if (!vertex_buffers || _geom_display_list != 0 ||
  4448. array_reader->get_usage_hint() < gl_min_buffer_usage_hint) {
  4449. // The array specifies client rendering only, or buffer objects
  4450. // are configured off.
  4451. if (_current_vbuffer_index != 0) {
  4452. if (GLCAT.is_spam() && gl_debug_buffers) {
  4453. GLCAT.spam()
  4454. << "unbinding vertex buffer\n";
  4455. }
  4456. _glBindBuffer(GL_ARRAY_BUFFER, 0);
  4457. _current_vbuffer_index = 0;
  4458. }
  4459. client_pointer = array_reader->get_read_pointer(force);
  4460. return (client_pointer != NULL);
  4461. }
  4462. // Prepare the buffer object and bind it.
  4463. VertexBufferContext *vbc = array_reader->prepare_now(get_prepared_objects(), this);
  4464. nassertr(vbc != (VertexBufferContext *)NULL, false);
  4465. if (!apply_vertex_buffer(vbc, array_reader, force)) {
  4466. return false;
  4467. }
  4468. // NULL is the OpenGL convention for the first byte of the buffer object.
  4469. client_pointer = NULL;
  4470. return true;
  4471. }
  4472. ////////////////////////////////////////////////////////////////////
  4473. // Function: GLGraphicsStateGuardian::prepare_index_buffer
  4474. // Access: Public, Virtual
  4475. // Description: Creates a new retained-mode representation of the
  4476. // given data, and returns a newly-allocated
  4477. // IndexBufferContext pointer to reference it. It is the
  4478. // responsibility of the calling function to later
  4479. // call release_index_buffer() with this same pointer (which
  4480. // will also delete the pointer).
  4481. //
  4482. // This function should not be called directly to
  4483. // prepare a buffer. Instead, call Geom::prepare().
  4484. ////////////////////////////////////////////////////////////////////
  4485. IndexBufferContext *CLP(GraphicsStateGuardian)::
  4486. prepare_index_buffer(GeomPrimitive *data) {
  4487. if (_supports_buffers) {
  4488. PStatGPUTimer timer(this, _prepare_index_buffer_pcollector);
  4489. CLP(IndexBufferContext) *gibc = new CLP(IndexBufferContext)(this, _prepared_objects, data);
  4490. _glGenBuffers(1, &gibc->_index);
  4491. if (GLCAT.is_debug() && gl_debug_buffers) {
  4492. GLCAT.debug()
  4493. << "creating index buffer " << (int)gibc->_index << ": "
  4494. << data->get_num_vertices() << " indices ("
  4495. << data->get_vertices()->get_array_format()->get_column(0)->get_numeric_type()
  4496. << ")\n";
  4497. }
  4498. report_my_gl_errors();
  4499. GeomPrimitivePipelineReader reader(data, Thread::get_current_thread());
  4500. apply_index_buffer(gibc, &reader, false);
  4501. return gibc;
  4502. }
  4503. return NULL;
  4504. }
  4505. ////////////////////////////////////////////////////////////////////
  4506. // Function: GLGraphicsStateGuardian::apply_index_buffer
  4507. // Access: Public
  4508. // Description: Makes the data the currently available data for
  4509. // rendering.
  4510. ////////////////////////////////////////////////////////////////////
  4511. bool CLP(GraphicsStateGuardian)::
  4512. apply_index_buffer(IndexBufferContext *ibc,
  4513. const GeomPrimitivePipelineReader *reader,
  4514. bool force) {
  4515. nassertr(_supports_buffers, false);
  4516. if (reader->get_modified() == UpdateSeq::initial()) {
  4517. // No need to re-apply.
  4518. return true;
  4519. }
  4520. CLP(IndexBufferContext) *gibc = DCAST(CLP(IndexBufferContext), ibc);
  4521. if (_current_ibuffer_index != gibc->_index) {
  4522. if (GLCAT.is_spam() && gl_debug_buffers) {
  4523. GLCAT.spam()
  4524. << "binding index buffer " << (int)gibc->_index << "\n";
  4525. }
  4526. _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, gibc->_index);
  4527. _current_ibuffer_index = gibc->_index;
  4528. gibc->set_active(true);
  4529. }
  4530. if (gibc->was_modified(reader)) {
  4531. int num_bytes = reader->get_data_size_bytes();
  4532. if (GLCAT.is_debug() && gl_debug_buffers) {
  4533. GLCAT.debug()
  4534. << "copying " << num_bytes
  4535. << " bytes into index buffer " << (int)gibc->_index << "\n";
  4536. }
  4537. if (num_bytes != 0) {
  4538. const unsigned char *client_pointer = reader->get_read_pointer(force);
  4539. if (client_pointer == NULL) {
  4540. return false;
  4541. }
  4542. PStatGPUTimer timer(this, _load_index_buffer_pcollector, reader->get_current_thread());
  4543. if (gibc->changed_size(reader) || gibc->changed_usage_hint(reader)) {
  4544. _glBufferData(GL_ELEMENT_ARRAY_BUFFER, num_bytes, client_pointer,
  4545. get_usage(reader->get_usage_hint()));
  4546. } else {
  4547. _glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, num_bytes,
  4548. client_pointer);
  4549. }
  4550. _data_transferred_pcollector.add_level(num_bytes);
  4551. }
  4552. gibc->mark_loaded(reader);
  4553. }
  4554. gibc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  4555. maybe_gl_finish();
  4556. report_my_gl_errors();
  4557. return true;
  4558. }
  4559. ////////////////////////////////////////////////////////////////////
  4560. // Function: GLGraphicsStateGuardian::release_index_buffer
  4561. // Access: Public, Virtual
  4562. // Description: Frees the GL resources previously allocated for the
  4563. // data. This function should never be called
  4564. // directly; instead, call Data::release() (or simply
  4565. // let the Data destruct).
  4566. ////////////////////////////////////////////////////////////////////
  4567. void CLP(GraphicsStateGuardian)::
  4568. release_index_buffer(IndexBufferContext *ibc) {
  4569. nassertv(_supports_buffers);
  4570. CLP(IndexBufferContext) *gibc = DCAST(CLP(IndexBufferContext), ibc);
  4571. if (GLCAT.is_debug() && gl_debug_buffers) {
  4572. GLCAT.debug()
  4573. << "deleting index buffer " << (int)gibc->_index << "\n";
  4574. }
  4575. // Make sure the buffer is unbound before we delete it. Not
  4576. // strictly necessary according to the OpenGL spec, but it might
  4577. // help out a flaky driver, and we need to keep our internal state
  4578. // consistent anyway.
  4579. if (_current_ibuffer_index == gibc->_index) {
  4580. if (GLCAT.is_spam() && gl_debug_buffers) {
  4581. GLCAT.spam()
  4582. << "unbinding index buffer\n";
  4583. }
  4584. _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  4585. _current_ibuffer_index = 0;
  4586. }
  4587. _glDeleteBuffers(1, &gibc->_index);
  4588. report_my_gl_errors();
  4589. gibc->_index = 0;
  4590. delete gibc;
  4591. }
  4592. ////////////////////////////////////////////////////////////////////
  4593. // Function: GLGraphicsStateGuardian::setup_primitive
  4594. // Access: Public
  4595. // Description: Internal function to bind a buffer object for the
  4596. // indicated primitive's index list, if appropriate, or
  4597. // to unbind a buffer object if it should be rendered
  4598. // from client memory.
  4599. //
  4600. // If the buffer object is bound, this function sets
  4601. // client_pointer to NULL (representing the start of the
  4602. // buffer object in server memory); if the buffer object
  4603. // is not bound, this function sets client_pointer to to
  4604. // the data array in client memory, that is, the data
  4605. // array passed in.
  4606. //
  4607. // If force is not true, the function may return false
  4608. // indicating the data is not currently available.
  4609. ////////////////////////////////////////////////////////////////////
  4610. bool CLP(GraphicsStateGuardian)::
  4611. setup_primitive(const unsigned char *&client_pointer,
  4612. const GeomPrimitivePipelineReader *reader,
  4613. bool force) {
  4614. if (!_supports_buffers) {
  4615. // No support for buffer objects; always render from client.
  4616. client_pointer = reader->get_read_pointer(force);
  4617. return (client_pointer != NULL);
  4618. }
  4619. if (!vertex_buffers || _geom_display_list != 0 ||
  4620. reader->get_usage_hint() == Geom::UH_client) {
  4621. // The array specifies client rendering only, or buffer objects
  4622. // are configured off.
  4623. if (_current_ibuffer_index != 0) {
  4624. if (GLCAT.is_spam() && gl_debug_buffers) {
  4625. GLCAT.spam()
  4626. << "unbinding index buffer\n";
  4627. }
  4628. _glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
  4629. _current_ibuffer_index = 0;
  4630. }
  4631. client_pointer = reader->get_read_pointer(force);
  4632. return (client_pointer != NULL);
  4633. }
  4634. // Prepare the buffer object and bind it.
  4635. IndexBufferContext *ibc = reader->prepare_now(get_prepared_objects(), this);
  4636. nassertr(ibc != (IndexBufferContext *)NULL, false);
  4637. if (!apply_index_buffer(ibc, reader, force)) {
  4638. return false;
  4639. }
  4640. // NULL is the OpenGL convention for the first byte of the buffer object.
  4641. client_pointer = NULL;
  4642. return true;
  4643. }
  4644. #ifndef OPENGLES
  4645. ////////////////////////////////////////////////////////////////////
  4646. // Function: GLGraphicsStateGuardian::begin_occlusion_query
  4647. // Access: Public, Virtual
  4648. // Description: Begins a new occlusion query. After this call, you
  4649. // may call begin_draw_primitives() and
  4650. // draw_triangles()/draw_whatever() repeatedly.
  4651. // Eventually, you should call end_occlusion_query()
  4652. // before the end of the frame; that will return a new
  4653. // OcclusionQueryContext object that will tell you how
  4654. // many pixels represented by the bracketed geometry
  4655. // passed the depth test.
  4656. //
  4657. // It is not valid to call begin_occlusion_query()
  4658. // between another begin_occlusion_query()
  4659. // .. end_occlusion_query() sequence.
  4660. ////////////////////////////////////////////////////////////////////
  4661. void CLP(GraphicsStateGuardian)::
  4662. begin_occlusion_query() {
  4663. nassertv(_supports_occlusion_query);
  4664. nassertv(_current_occlusion_query == (OcclusionQueryContext *)NULL);
  4665. PT(CLP(OcclusionQueryContext)) query = new CLP(OcclusionQueryContext)(this);
  4666. _glGenQueries(1, &query->_index);
  4667. if (GLCAT.is_debug()) {
  4668. GLCAT.debug()
  4669. << "beginning occlusion query index " << (int)query->_index << "\n";
  4670. }
  4671. _glBeginQuery(GL_SAMPLES_PASSED, query->_index);
  4672. _current_occlusion_query = query;
  4673. report_my_gl_errors();
  4674. }
  4675. #endif // !OPENGLES
  4676. #ifndef OPENGLES
  4677. ////////////////////////////////////////////////////////////////////
  4678. // Function: GLGraphicsStateGuardian::end_occlusion_query
  4679. // Access: Public, Virtual
  4680. // Description: Ends a previous call to begin_occlusion_query().
  4681. // This call returns the OcclusionQueryContext object
  4682. // that will (eventually) report the number of pixels
  4683. // that passed the depth test between the call to
  4684. // begin_occlusion_query() and end_occlusion_query().
  4685. ////////////////////////////////////////////////////////////////////
  4686. PT(OcclusionQueryContext) CLP(GraphicsStateGuardian)::
  4687. end_occlusion_query() {
  4688. nassertr(_current_occlusion_query != (OcclusionQueryContext *)NULL, NULL);
  4689. PT(OcclusionQueryContext) result = _current_occlusion_query;
  4690. GLuint index = DCAST(CLP(OcclusionQueryContext), result)->_index;
  4691. if (GLCAT.is_debug()) {
  4692. GLCAT.debug()
  4693. << "ending occlusion query index " << (int)index << "\n";
  4694. }
  4695. _current_occlusion_query = NULL;
  4696. _glEndQuery(GL_SAMPLES_PASSED);
  4697. // Temporary hack to try working around an apparent driver bug on
  4698. // iMacs. Occlusion queries sometimes incorrectly report 0 samples,
  4699. // unless we stall the pipe to keep fewer than a certain maximum
  4700. // number of queries pending at once.
  4701. static ConfigVariableInt limit_occlusion_queries("limit-occlusion-queries", 0);
  4702. if (limit_occlusion_queries > 0) {
  4703. if (index > (unsigned int)limit_occlusion_queries) {
  4704. PStatGPUTimer timer(this, _wait_occlusion_pcollector);
  4705. GLuint result;
  4706. _glGetQueryObjectuiv(index - (unsigned int)limit_occlusion_queries,
  4707. GL_QUERY_RESULT, &result);
  4708. }
  4709. }
  4710. report_my_gl_errors();
  4711. return result;
  4712. }
  4713. #endif // !OPENGLES
  4714. ////////////////////////////////////////////////////////////////////
  4715. // Function: GLGraphicsStateGuardian::issue_timer_query
  4716. // Access: Public, Virtual
  4717. // Description: Adds a timer query to the command stream, associated
  4718. // with the given PStats collector index.
  4719. ////////////////////////////////////////////////////////////////////
  4720. PT(TimerQueryContext) CLP(GraphicsStateGuardian)::
  4721. issue_timer_query(int pstats_index) {
  4722. #if defined(DO_PSTATS) && !defined(OPENGLES)
  4723. nassertr(_supports_timer_query, NULL);
  4724. PT(CLP(TimerQueryContext)) query;
  4725. // Hack
  4726. if (pstats_index == _command_latency_pcollector.get_index()) {
  4727. query = new CLP(LatencyQueryContext)(this, pstats_index);
  4728. } else {
  4729. query = new CLP(TimerQueryContext)(this, pstats_index);
  4730. }
  4731. if (_deleted_queries.size() >= 1) {
  4732. query->_index = _deleted_queries.back();
  4733. _deleted_queries.pop_back();
  4734. } else {
  4735. _glGenQueries(1, &query->_index);
  4736. if (GLCAT.is_spam()) {
  4737. GLCAT.spam() << "Generating query for " << pstats_index
  4738. << ": " << query->_index << "\n";
  4739. }
  4740. }
  4741. // Issue the timestamp query.
  4742. _glQueryCounter(query->_index, GL_TIMESTAMP);
  4743. if (_use_object_labels) {
  4744. // Assign a label to it based on the PStatCollector name.
  4745. const PStatClient *client = PStatClient::get_global_pstats();
  4746. string name = client->get_collector_fullname(pstats_index & 0x7fff);
  4747. _glObjectLabel(GL_QUERY, query->_index, name.size(), name.data());
  4748. }
  4749. _pending_timer_queries.push_back((TimerQueryContext *)query);
  4750. return (TimerQueryContext *)query;
  4751. #else
  4752. return NULL;
  4753. #endif
  4754. }
  4755. #ifndef OPENGLES
  4756. ////////////////////////////////////////////////////////////////////
  4757. // Function: GLGraphicsStateGuardian::dispatch_compute
  4758. // Access: Public, Virtual
  4759. // Description: Dispatches a currently bound compute shader using
  4760. // the given work group counts.
  4761. ////////////////////////////////////////////////////////////////////
  4762. void CLP(GraphicsStateGuardian)::
  4763. dispatch_compute(int num_groups_x, int num_groups_y, int num_groups_z) {
  4764. maybe_gl_finish();
  4765. PStatGPUTimer timer(this, _compute_dispatch_pcollector);
  4766. nassertv(_supports_compute_shaders);
  4767. nassertv(_current_shader_context != NULL);
  4768. _glDispatchCompute(num_groups_x, num_groups_y, num_groups_z);
  4769. maybe_gl_finish();
  4770. }
  4771. #endif // !OPENGLES
  4772. ////////////////////////////////////////////////////////////////////
  4773. // Function: GLGraphicsStateGuardian::make_geom_munger
  4774. // Access: Public, Virtual
  4775. // Description: Creates a new GeomMunger object to munge vertices
  4776. // appropriate to this GSG for the indicated state.
  4777. ////////////////////////////////////////////////////////////////////
  4778. PT(GeomMunger) CLP(GraphicsStateGuardian)::
  4779. make_geom_munger(const RenderState *state, Thread *current_thread) {
  4780. PT(CLP(GeomMunger)) munger = new CLP(GeomMunger)(this, state);
  4781. return GeomMunger::register_munger(munger, current_thread);
  4782. }
  4783. ////////////////////////////////////////////////////////////////////
  4784. // Function: GLGraphicsStateGuardian::compute_distance_to
  4785. // Access: Public, Virtual
  4786. // Description: This function will compute the distance to the
  4787. // indicated point, assumed to be in eye coordinates,
  4788. // from the camera plane. The point is assumed to be
  4789. // in the GSG's internal coordinate system.
  4790. ////////////////////////////////////////////////////////////////////
  4791. PN_stdfloat CLP(GraphicsStateGuardian)::
  4792. compute_distance_to(const LPoint3 &point) const {
  4793. return -point[2];
  4794. }
  4795. ////////////////////////////////////////////////////////////////////
  4796. // Function: GLGraphicsStateGuardian::framebuffer_copy_to_texture
  4797. // Access: Public, Virtual
  4798. // Description: Copy the pixels within the indicated display
  4799. // region from the framebuffer into texture memory.
  4800. //
  4801. // If z > -1, it is the cube map index or layer index
  4802. // into which to copy.
  4803. ////////////////////////////////////////////////////////////////////
  4804. bool CLP(GraphicsStateGuardian)::
  4805. framebuffer_copy_to_texture(Texture *tex, int view, int z,
  4806. const DisplayRegion *dr, const RenderBuffer &rb) {
  4807. nassertr(tex != NULL && dr != NULL, false);
  4808. set_read_buffer(rb._buffer_type);
  4809. clear_color_write_mask();
  4810. int xo, yo, w, h;
  4811. dr->get_region_pixels(xo, yo, w, h);
  4812. tex->set_size_padded(w, h, tex->get_z_size());
  4813. if (tex->get_compression() == Texture::CM_default) {
  4814. // Unless the user explicitly turned on texture compression, turn
  4815. // it off for the copy-to-texture case.
  4816. tex->set_compression(Texture::CM_off);
  4817. }
  4818. // Sanity check everything.
  4819. if (z >= 0) {
  4820. if (z >= tex->get_z_size()) {
  4821. // This can happen, when textures with different layer counts
  4822. // are attached to a buffer. We simply ignore this if it happens.
  4823. return false;
  4824. }
  4825. if ((w != tex->get_x_size()) ||
  4826. (h != tex->get_y_size())) {
  4827. return false;
  4828. }
  4829. if (tex->get_texture_type() == Texture::TT_cube_map) {
  4830. if (!_supports_cube_map) {
  4831. return false;
  4832. }
  4833. nassertr(z < 6, false);
  4834. if (w != h) {
  4835. return false;
  4836. }
  4837. } else if (tex->get_texture_type() == Texture::TT_3d_texture) {
  4838. if (!_supports_3d_texture) {
  4839. return false;
  4840. }
  4841. } else if (tex->get_texture_type() == Texture::TT_2d_texture_array) {
  4842. if (!_supports_2d_texture_array) {
  4843. return false;
  4844. }
  4845. } else {
  4846. GLCAT.error()
  4847. << "Don't know how to copy framebuffer to texture " << *tex << "\n";
  4848. }
  4849. } else {
  4850. nassertr(tex->get_texture_type() == Texture::TT_2d_texture, false);
  4851. }
  4852. // Match framebuffer format if necessary.
  4853. if (tex->get_match_framebuffer_format()) {
  4854. switch (tex->get_format()) {
  4855. case Texture::F_depth_component:
  4856. case Texture::F_depth_component16:
  4857. case Texture::F_depth_component24:
  4858. case Texture::F_depth_component32:
  4859. case Texture::F_depth_stencil:
  4860. // Don't remap if we're one of these special format.
  4861. break;
  4862. default:
  4863. // If the texture is a color format, we want to match the
  4864. // presence of sRGB and alpha according to the framebuffer.
  4865. if (_current_properties->get_srgb_color()) {
  4866. if (_current_properties->get_alpha_bits()) {
  4867. tex->set_format(Texture::F_srgb_alpha);
  4868. } else {
  4869. tex->set_format(Texture::F_srgb);
  4870. }
  4871. } else {
  4872. if (_current_properties->get_alpha_bits()) {
  4873. tex->set_format(Texture::F_rgba);
  4874. } else {
  4875. tex->set_format(Texture::F_rgb);
  4876. }
  4877. }
  4878. }
  4879. }
  4880. TextureContext *tc = tex->prepare_now(view, get_prepared_objects(), this);
  4881. nassertr(tc != (TextureContext *)NULL, false);
  4882. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), tc);
  4883. apply_texture(gtc);
  4884. bool needs_reload = specify_texture(gtc, tex->get_default_sampler());
  4885. GLenum target = get_texture_target(tex->get_texture_type());
  4886. GLint internal_format = get_internal_image_format(tex);
  4887. int width = tex->get_x_size();
  4888. int height = tex->get_y_size();
  4889. int depth = tex->get_z_size();
  4890. bool uses_mipmaps = tex->uses_mipmaps() && !gl_ignore_mipmaps;
  4891. if (uses_mipmaps) {
  4892. if (_supports_generate_mipmap) {
  4893. #ifndef OPENGLES_2
  4894. if (_glGenerateMipmap == NULL) {
  4895. glTexParameteri(target, GL_GENERATE_MIPMAP, true);
  4896. }
  4897. #endif
  4898. } else {
  4899. // If we can't auto-generate mipmaps, do without mipmaps.
  4900. glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  4901. uses_mipmaps = false;
  4902. }
  4903. }
  4904. bool new_image = needs_reload || gtc->was_image_modified();
  4905. if (z >= 0) {
  4906. if (target == GL_TEXTURE_CUBE_MAP) {
  4907. // Copy to a cube map face, which is treated as a 2D texture.
  4908. target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + z;
  4909. depth = 1;
  4910. z = -1;
  4911. // Cube map faces seem to have trouble with CopyTexSubImage, so we
  4912. // always reload the image.
  4913. new_image = true;
  4914. }
  4915. }
  4916. if (!gtc->_has_storage ||
  4917. internal_format != gtc->_internal_format ||
  4918. uses_mipmaps != gtc->_uses_mipmaps ||
  4919. width != gtc->_width ||
  4920. height != gtc->_height ||
  4921. depth != gtc->_depth) {
  4922. // If the texture properties have changed, we need to reload the
  4923. // image.
  4924. new_image = true;
  4925. }
  4926. if (new_image && gtc->_immutable) {
  4927. gtc->reset_data();
  4928. glBindTexture(target, gtc->_index);
  4929. }
  4930. #ifndef OPENGLES
  4931. if (gtc->needs_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT)) {
  4932. // Make sure that any incoherent writes to this texture have been synced.
  4933. issue_memory_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
  4934. }
  4935. #endif
  4936. if (z >= 0) {
  4937. #ifndef OPENGLES_1
  4938. if (new_image) {
  4939. // These won't be used because we pass a NULL image, but we still
  4940. // have to specify them. Might as well use the actual values.
  4941. GLint external_format = get_external_image_format(tex);
  4942. GLint component_type = get_component_type(tex->get_component_type());
  4943. _glTexImage3D(target, 0, internal_format, width, height, depth, 0, external_format, component_type, NULL);
  4944. }
  4945. _glCopyTexSubImage3D(target, 0, 0, 0, z, xo, yo, w, h);
  4946. #endif
  4947. } else {
  4948. if (new_image) {
  4949. // We have to create a new image.
  4950. // It seems that OpenGL accepts a size higher than the framebuffer,
  4951. // but if we run into trouble we'll have to replace this with
  4952. // something smarter.
  4953. glCopyTexImage2D(target, 0, internal_format, xo, yo, width, height, 0);
  4954. } else {
  4955. // We can overlay the existing image.
  4956. glCopyTexSubImage2D(target, 0, 0, 0, xo, yo, w, h);
  4957. }
  4958. }
  4959. if (uses_mipmaps && _glGenerateMipmap != NULL) {
  4960. glEnable(target);
  4961. _glGenerateMipmap(target);
  4962. glDisable(target);
  4963. }
  4964. gtc->_has_storage = true;
  4965. gtc->_uses_mipmaps = uses_mipmaps;
  4966. gtc->_internal_format = internal_format;
  4967. gtc->_width = width;
  4968. gtc->_height = height;
  4969. gtc->_depth = depth;
  4970. gtc->mark_loaded();
  4971. gtc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  4972. report_my_gl_errors();
  4973. // Force reload of texture state, since we've just monkeyed with it.
  4974. _state_mask.clear_bit(TextureAttrib::get_class_slot());
  4975. return true;
  4976. }
  4977. ////////////////////////////////////////////////////////////////////
  4978. // Function: GLGraphicsStateGuardian::framebuffer_copy_to_ram
  4979. // Access: Public, Virtual
  4980. // Description: Copy the pixels within the indicated display region
  4981. // from the framebuffer into system memory, not texture
  4982. // memory. Returns true on success, false on failure.
  4983. //
  4984. // This completely redefines the ram image of the
  4985. // indicated texture.
  4986. ////////////////////////////////////////////////////////////////////
  4987. bool CLP(GraphicsStateGuardian)::
  4988. framebuffer_copy_to_ram(Texture *tex, int view, int z,
  4989. const DisplayRegion *dr, const RenderBuffer &rb) {
  4990. nassertr(tex != NULL && dr != NULL, false);
  4991. set_read_buffer(rb._buffer_type);
  4992. glPixelStorei(GL_PACK_ALIGNMENT, 1);
  4993. clear_color_write_mask();
  4994. // Bug fix for RE, RE2, and VTX - need to disable texturing in order
  4995. // for glReadPixels() to work
  4996. // NOTE: reading the depth buffer is *much* slower than reading the
  4997. // color buffer
  4998. set_state_and_transform(RenderState::make_empty(), _internal_transform);
  4999. int xo, yo, w, h;
  5000. dr->get_region_pixels(xo, yo, w, h);
  5001. Texture::ComponentType component_type = tex->get_component_type();
  5002. bool color_mode = false;
  5003. Texture::Format format = tex->get_format();
  5004. switch (format) {
  5005. case Texture::F_depth_stencil:
  5006. if (_current_properties->get_float_depth()) {
  5007. component_type = Texture::T_float;
  5008. } else {
  5009. component_type = Texture::T_unsigned_int_24_8;
  5010. }
  5011. break;
  5012. case Texture::F_depth_component:
  5013. if (_current_properties->get_float_depth()) {
  5014. component_type = Texture::T_float;
  5015. } else if (_current_properties->get_depth_bits() <= 8) {
  5016. component_type = Texture::T_unsigned_byte;
  5017. } else if (_current_properties->get_depth_bits() <= 16) {
  5018. component_type = Texture::T_unsigned_short;
  5019. } else {
  5020. component_type = Texture::T_float;
  5021. }
  5022. break;
  5023. default:
  5024. color_mode = true;
  5025. if (_current_properties->get_srgb_color()) {
  5026. if (_current_properties->get_alpha_bits()) {
  5027. format = Texture::F_srgb_alpha;
  5028. } else {
  5029. format = Texture::F_srgb;
  5030. }
  5031. } else {
  5032. if (_current_properties->get_alpha_bits()) {
  5033. format = Texture::F_rgba;
  5034. } else {
  5035. format = Texture::F_rgb;
  5036. }
  5037. }
  5038. if (_current_properties->get_float_color()) {
  5039. component_type = Texture::T_float;
  5040. } else if (_current_properties->get_color_bits() <= 24) {
  5041. component_type = Texture::T_unsigned_byte;
  5042. } else {
  5043. component_type = Texture::T_unsigned_short;
  5044. }
  5045. }
  5046. Texture::TextureType texture_type;
  5047. int z_size;
  5048. //TODO: should be extended to support 3D textures and 2D arrays.
  5049. if (z >= 0) {
  5050. texture_type = Texture::TT_cube_map;
  5051. z_size = 6;
  5052. } else {
  5053. texture_type = Texture::TT_2d_texture;
  5054. z_size = 1;
  5055. }
  5056. if (tex->get_x_size() != w || tex->get_y_size() != h ||
  5057. tex->get_z_size() != z_size ||
  5058. tex->get_component_type() != component_type ||
  5059. tex->get_format() != format ||
  5060. tex->get_texture_type() != texture_type) {
  5061. // Re-setup the texture; its properties have changed.
  5062. tex->setup_texture(texture_type, w, h, z_size,
  5063. component_type, format);
  5064. }
  5065. nassertr(z < tex->get_z_size(), false);
  5066. GLenum external_format = get_external_image_format(tex);
  5067. if (GLCAT.is_spam()) {
  5068. GLCAT.spam()
  5069. << "glReadPixels(" << xo << ", " << yo << ", " << w << ", " << h << ", ";
  5070. switch (external_format) {
  5071. case GL_DEPTH_COMPONENT:
  5072. GLCAT.spam(false) << "GL_DEPTH_COMPONENT, ";
  5073. break;
  5074. case GL_DEPTH_STENCIL:
  5075. GLCAT.spam(false) << "GL_DEPTH_STENCIL, ";
  5076. break;
  5077. case GL_RGB:
  5078. GLCAT.spam(false) << "GL_RGB, ";
  5079. break;
  5080. case GL_RGBA:
  5081. GLCAT.spam(false) << "GL_RGBA, ";
  5082. break;
  5083. #ifndef OPENGLES
  5084. case GL_BGR:
  5085. GLCAT.spam(false) << "GL_BGR, ";
  5086. break;
  5087. #endif
  5088. case GL_BGRA:
  5089. GLCAT.spam(false) << "GL_BGRA, ";
  5090. break;
  5091. default:
  5092. GLCAT.spam(false) << "unknown, ";
  5093. break;
  5094. }
  5095. switch (get_component_type(component_type)) {
  5096. case GL_UNSIGNED_BYTE:
  5097. GLCAT.spam(false) << "GL_UNSIGNED_BYTE";
  5098. break;
  5099. case GL_UNSIGNED_SHORT:
  5100. GLCAT.spam(false) << "GL_UNSIGNED_SHORT";
  5101. break;
  5102. case GL_FLOAT:
  5103. GLCAT.spam(false) << "GL_FLOAT";
  5104. break;
  5105. #ifndef OPENGLES_1
  5106. case GL_INT:
  5107. GLCAT.spam(false) << "GL_INT";
  5108. break;
  5109. #endif
  5110. default:
  5111. GLCAT.spam(false) << "unknown";
  5112. break;
  5113. }
  5114. GLCAT.spam(false)
  5115. << ")" << endl;
  5116. }
  5117. unsigned char *image_ptr = tex->modify_ram_image();
  5118. size_t image_size = tex->get_ram_image_size();
  5119. if (z >= 0 || view > 0) {
  5120. image_size = tex->get_expected_ram_page_size();
  5121. if (z >= 0) {
  5122. image_ptr += z * image_size;
  5123. }
  5124. if (view > 0) {
  5125. image_ptr += (view * tex->get_z_size()) * image_size;
  5126. }
  5127. }
  5128. glReadPixels(xo, yo, w, h, external_format,
  5129. get_component_type(component_type), image_ptr);
  5130. // We may have to reverse the byte ordering of the image if GL
  5131. // didn't do it for us.
  5132. if (color_mode && !_supports_bgr) {
  5133. PTA_uchar new_image;
  5134. const unsigned char *result =
  5135. fix_component_ordering(new_image, image_ptr, image_size,
  5136. external_format, tex);
  5137. if (result != image_ptr) {
  5138. memcpy(image_ptr, result, image_size);
  5139. }
  5140. }
  5141. report_my_gl_errors();
  5142. return true;
  5143. }
  5144. #ifdef SUPPORT_FIXED_FUNCTION
  5145. ////////////////////////////////////////////////////////////////////
  5146. // Function: GLGraphicsStateGuardian::apply_fog
  5147. // Access: Public, Virtual
  5148. // Description:
  5149. ////////////////////////////////////////////////////////////////////
  5150. void CLP(GraphicsStateGuardian)::
  5151. apply_fog(Fog *fog) {
  5152. Fog::Mode fmode = fog->get_mode();
  5153. glFogf(GL_FOG_MODE, get_fog_mode_type(fmode));
  5154. if (fmode == Fog::M_linear) {
  5155. PN_stdfloat onset, opaque;
  5156. fog->get_linear_range(onset, opaque);
  5157. glFogf(GL_FOG_START, onset);
  5158. glFogf(GL_FOG_END, opaque);
  5159. } else {
  5160. // Exponential fog is always camera-relative.
  5161. glFogf(GL_FOG_DENSITY, fog->get_exp_density());
  5162. }
  5163. call_glFogfv(GL_FOG_COLOR, fog->get_color());
  5164. report_my_gl_errors();
  5165. }
  5166. #endif // SUPPORT_FIXED_FUNCTION
  5167. ////////////////////////////////////////////////////////////////////
  5168. // Function: GLGraphicsStateGuardian::do_issue_transform
  5169. // Access: Protected
  5170. // Description: Sends the indicated transform matrix to the graphics
  5171. // API to be applied to future vertices.
  5172. //
  5173. // This transform is the internal_transform, already
  5174. // converted into the GSG's internal coordinate system.
  5175. ////////////////////////////////////////////////////////////////////
  5176. void CLP(GraphicsStateGuardian)::
  5177. do_issue_transform() {
  5178. #ifdef SUPPORT_FIXED_FUNCTION
  5179. // OpenGL ES 2 does not support glLoadMatrix.
  5180. const TransformState *transform = _internal_transform;
  5181. if (GLCAT.is_spam()) {
  5182. GLCAT.spam()
  5183. << "glLoadMatrix(GL_MODELVIEW): " << transform->get_mat() << endl;
  5184. }
  5185. DO_PSTATS_STUFF(_transform_state_pcollector.add_level(1));
  5186. glMatrixMode(GL_MODELVIEW);
  5187. GLPf(LoadMatrix)(transform->get_mat().get_data());
  5188. #endif
  5189. _transform_stale = false;
  5190. #ifndef OPENGLES_1
  5191. if (_current_shader_context) {
  5192. _current_shader_context->issue_parameters(Shader::SSD_transform);
  5193. }
  5194. #endif
  5195. report_my_gl_errors();
  5196. }
  5197. #ifdef SUPPORT_FIXED_FUNCTION
  5198. ////////////////////////////////////////////////////////////////////
  5199. // Function: GLGraphicsStateGuardian::do_issue_shade_model
  5200. // Access: Protected
  5201. // Description:
  5202. ////////////////////////////////////////////////////////////////////
  5203. void CLP(GraphicsStateGuardian)::
  5204. do_issue_shade_model() {
  5205. const ShadeModelAttrib *target_shade_model;
  5206. _target_rs->get_attrib_def(target_shade_model);
  5207. switch (target_shade_model->get_mode()) {
  5208. case ShadeModelAttrib::M_smooth:
  5209. glShadeModel(GL_SMOOTH);
  5210. _flat_shade_model = false;
  5211. break;
  5212. case ShadeModelAttrib::M_flat:
  5213. glShadeModel(GL_FLAT);
  5214. _flat_shade_model = true;
  5215. break;
  5216. }
  5217. }
  5218. #endif // SUPPORT_FIXED_FUNCTION
  5219. #ifndef OPENGLES_1
  5220. ////////////////////////////////////////////////////////////////////
  5221. // Function: GLGraphicsStateGuardian::do_issue_shader
  5222. // Access: Protected
  5223. // Description:
  5224. ////////////////////////////////////////////////////////////////////
  5225. void CLP(GraphicsStateGuardian)::
  5226. do_issue_shader(bool state_has_changed) {
  5227. ShaderContext *context = 0;
  5228. Shader *shader = (Shader *)(_target_shader->get_shader());
  5229. #ifndef SUPPORT_FIXED_FUNCTION
  5230. // If we don't have a shader, apply the default shader.
  5231. if (!shader) {
  5232. shader = _default_shader;
  5233. nassertv(shader != NULL);
  5234. }
  5235. #endif
  5236. if (shader) {
  5237. context = shader->prepare_now(get_prepared_objects(), this);
  5238. }
  5239. #ifndef SUPPORT_FIXED_FUNCTION
  5240. // If it failed, try applying the default shader.
  5241. if (shader != _default_shader && (context == 0 || !context->valid())) {
  5242. shader = _default_shader;
  5243. nassertv(shader != NULL);
  5244. context = shader->prepare_now(get_prepared_objects(), this);
  5245. }
  5246. #endif
  5247. if (context == 0 || (context->valid() == false)) {
  5248. if (_current_shader_context != 0) {
  5249. _current_shader_context->unbind();
  5250. _current_shader = 0;
  5251. _current_shader_context = 0;
  5252. }
  5253. } else {
  5254. if (context != _current_shader_context) {
  5255. // Use a completely different shader than before.
  5256. // Unbind old shader, bind the new one.
  5257. if (_current_shader_context != 0) {
  5258. _current_shader_context->unbind();
  5259. }
  5260. context->bind();
  5261. _current_shader = shader;
  5262. _current_shader_context = context;
  5263. context->issue_parameters(Shader::SSD_shaderinputs);
  5264. } else {
  5265. if (state_has_changed) {
  5266. // Use the same shader as before, but with new input arguments.
  5267. context->issue_parameters(Shader::SSD_shaderinputs);
  5268. }
  5269. }
  5270. }
  5271. report_my_gl_errors();
  5272. }
  5273. #endif // !OPENGLES_1
  5274. ////////////////////////////////////////////////////////////////////
  5275. // Function: GLGraphicsStateGuardian::do_issue_render_mode
  5276. // Access: Protected
  5277. // Description:
  5278. ////////////////////////////////////////////////////////////////////
  5279. void CLP(GraphicsStateGuardian)::
  5280. do_issue_render_mode() {
  5281. const RenderModeAttrib *target_render_mode;
  5282. _target_rs->get_attrib_def(target_render_mode);
  5283. _render_mode = target_render_mode->get_mode();
  5284. PN_stdfloat thickness = target_render_mode->get_thickness();
  5285. _point_perspective = target_render_mode->get_perspective();
  5286. #ifndef OPENGLES // glPolygonMode not supported by OpenGL ES.
  5287. switch (_render_mode) {
  5288. case RenderModeAttrib::M_unchanged:
  5289. case RenderModeAttrib::M_filled:
  5290. case RenderModeAttrib::M_filled_flat:
  5291. glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  5292. break;
  5293. case RenderModeAttrib::M_wireframe:
  5294. glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  5295. break;
  5296. case RenderModeAttrib::M_point:
  5297. glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
  5298. break;
  5299. default:
  5300. GLCAT.error()
  5301. << "Unknown render mode " << (int)_render_mode << endl;
  5302. }
  5303. #endif // OPENGLES
  5304. // The thickness affects both the line width and the point size.
  5305. if (thickness != _point_size) {
  5306. glLineWidth(_point_size);
  5307. #ifndef OPENGLES_2
  5308. glPointSize(_point_size);
  5309. #endif
  5310. _point_size = thickness;
  5311. }
  5312. report_my_gl_errors();
  5313. do_point_size();
  5314. }
  5315. ////////////////////////////////////////////////////////////////////
  5316. // Function: GLGraphicsStateGuardian::do_issue_antialias
  5317. // Access: Protected
  5318. // Description:
  5319. ////////////////////////////////////////////////////////////////////
  5320. void CLP(GraphicsStateGuardian)::
  5321. do_issue_antialias() {
  5322. const AntialiasAttrib *target_antialias;
  5323. _target_rs->get_attrib_def(target_antialias);
  5324. if (target_antialias->get_mode_type() == AntialiasAttrib::M_auto) {
  5325. // In this special mode, we must enable antialiasing on a
  5326. // case-by-case basis, because we enable it differently for
  5327. // polygons and for points and lines.
  5328. _auto_antialias_mode = true;
  5329. } else {
  5330. // Otherwise, explicitly enable or disable according to the bits
  5331. // that are set. But if multisample is requested and supported,
  5332. // don't use the other bits at all (they will be ignored by GL
  5333. // anyway).
  5334. _auto_antialias_mode = false;
  5335. unsigned short mode = target_antialias->get_mode();
  5336. if (_supports_multisample &&
  5337. (mode & AntialiasAttrib::M_multisample) != 0) {
  5338. enable_multisample_antialias(true);
  5339. } else {
  5340. enable_multisample_antialias(false);
  5341. enable_line_smooth((mode & AntialiasAttrib::M_line) != 0);
  5342. enable_point_smooth((mode & AntialiasAttrib::M_point) != 0);
  5343. enable_polygon_smooth((mode & AntialiasAttrib::M_polygon) != 0);
  5344. }
  5345. }
  5346. #ifndef OPENGLES_2
  5347. switch (target_antialias->get_mode_quality()) {
  5348. case AntialiasAttrib::M_faster:
  5349. glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST);
  5350. glHint(GL_POINT_SMOOTH_HINT, GL_FASTEST);
  5351. #ifndef OPENGLES
  5352. glHint(GL_POLYGON_SMOOTH_HINT, GL_FASTEST);
  5353. #endif // OPENGLES
  5354. break;
  5355. case AntialiasAttrib::M_better:
  5356. glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
  5357. glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
  5358. #ifndef OPENGLES
  5359. glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
  5360. #endif // OPENGLES
  5361. break;
  5362. default:
  5363. glHint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE);
  5364. glHint(GL_POINT_SMOOTH_HINT, GL_DONT_CARE);
  5365. #ifndef OPENGLES
  5366. glHint(GL_POLYGON_SMOOTH_HINT, GL_DONT_CARE);
  5367. #endif // OPENGLES
  5368. break;
  5369. }
  5370. #endif // !OPENGLES_2
  5371. report_my_gl_errors();
  5372. }
  5373. #ifdef SUPPORT_FIXED_FUNCTION // OpenGL ES 2.0 doesn't support rescaling normals.
  5374. ////////////////////////////////////////////////////////////////////
  5375. // Function: GLGraphicsStateGuardian::do_issue_rescale_normal
  5376. // Access: Protected
  5377. // Description:
  5378. ////////////////////////////////////////////////////////////////////
  5379. void CLP(GraphicsStateGuardian)::
  5380. do_issue_rescale_normal() {
  5381. RescaleNormalAttrib::Mode mode = RescaleNormalAttrib::M_none;
  5382. const RescaleNormalAttrib *target_rescale_normal;
  5383. if (_target_rs->get_attrib(target_rescale_normal)) {
  5384. mode = target_rescale_normal->get_mode();
  5385. }
  5386. switch (mode) {
  5387. case RescaleNormalAttrib::M_none:
  5388. glDisable(GL_NORMALIZE);
  5389. if (_supports_rescale_normal && support_rescale_normal) {
  5390. glDisable(GL_RESCALE_NORMAL);
  5391. }
  5392. break;
  5393. case RescaleNormalAttrib::M_rescale:
  5394. if (_supports_rescale_normal && support_rescale_normal) {
  5395. glEnable(GL_RESCALE_NORMAL);
  5396. glDisable(GL_NORMALIZE);
  5397. } else {
  5398. glEnable(GL_NORMALIZE);
  5399. }
  5400. break;
  5401. case RescaleNormalAttrib::M_normalize:
  5402. glEnable(GL_NORMALIZE);
  5403. if (_supports_rescale_normal && support_rescale_normal) {
  5404. glDisable(GL_RESCALE_NORMAL);
  5405. }
  5406. break;
  5407. default:
  5408. GLCAT.error()
  5409. << "Unknown rescale_normal mode " << (int)mode << endl;
  5410. }
  5411. report_my_gl_errors();
  5412. }
  5413. #endif // SUPPORT_FIXED_FUNCTION
  5414. // PandaCompareFunc - 1 + 0x200 === GL_NEVER, etc. order is sequential
  5415. #define PANDA_TO_GL_COMPAREFUNC(PANDACMPFUNC) (PANDACMPFUNC-1 +0x200)
  5416. ////////////////////////////////////////////////////////////////////
  5417. // Function: GLGraphicsStateGuardian::do_issue_depth_test
  5418. // Access: Protected
  5419. // Description:
  5420. ////////////////////////////////////////////////////////////////////
  5421. void CLP(GraphicsStateGuardian)::
  5422. do_issue_depth_test() {
  5423. const DepthTestAttrib *target_depth_test;
  5424. _target_rs->get_attrib_def(target_depth_test);
  5425. DepthTestAttrib::PandaCompareFunc mode = target_depth_test->get_mode();
  5426. if (mode == DepthTestAttrib::M_none) {
  5427. enable_depth_test(false);
  5428. } else {
  5429. enable_depth_test(true);
  5430. glDepthFunc(PANDA_TO_GL_COMPAREFUNC(mode));
  5431. }
  5432. report_my_gl_errors();
  5433. }
  5434. #ifdef SUPPORT_FIXED_FUNCTION
  5435. ////////////////////////////////////////////////////////////////////
  5436. // Function: GLGraphicsStateGuardian::do_issue_alpha_test
  5437. // Access: Protected
  5438. // Description:
  5439. ////////////////////////////////////////////////////////////////////
  5440. void CLP(GraphicsStateGuardian)::
  5441. do_issue_alpha_test() {
  5442. if (_target_shader->get_flag(ShaderAttrib::F_subsume_alpha_test)) {
  5443. enable_alpha_test(false);
  5444. } else {
  5445. const AlphaTestAttrib *target_alpha_test;
  5446. _target_rs->get_attrib_def(target_alpha_test);
  5447. AlphaTestAttrib::PandaCompareFunc mode = target_alpha_test->get_mode();
  5448. if (mode == AlphaTestAttrib::M_none) {
  5449. enable_alpha_test(false);
  5450. } else {
  5451. nassertv(GL_NEVER == (AlphaTestAttrib::M_never-1+0x200));
  5452. glAlphaFunc(PANDA_TO_GL_COMPAREFUNC(mode), target_alpha_test->get_reference_alpha());
  5453. enable_alpha_test(true);
  5454. }
  5455. }
  5456. }
  5457. #endif // SUPPORT_FIXED_FUNCTION
  5458. ////////////////////////////////////////////////////////////////////
  5459. // Function: GLGraphicsStateGuardian::do_issue_depth_write
  5460. // Access: Protected
  5461. // Description:
  5462. ////////////////////////////////////////////////////////////////////
  5463. void CLP(GraphicsStateGuardian)::
  5464. do_issue_depth_write() {
  5465. const DepthWriteAttrib *target_depth_write;
  5466. _target_rs->get_attrib_def(target_depth_write);
  5467. DepthWriteAttrib::Mode mode = target_depth_write->get_mode();
  5468. if (mode == DepthWriteAttrib::M_off) {
  5469. #ifdef GSG_VERBOSE
  5470. GLCAT.spam()
  5471. << "glDepthMask(GL_FALSE)" << endl;
  5472. #endif
  5473. glDepthMask(GL_FALSE);
  5474. } else {
  5475. #ifdef GSG_VERBOSE
  5476. GLCAT.spam()
  5477. << "glDepthMask(GL_TRUE)" << endl;
  5478. #endif
  5479. glDepthMask(GL_TRUE);
  5480. }
  5481. report_my_gl_errors();
  5482. }
  5483. ////////////////////////////////////////////////////////////////////
  5484. // Function: GLGraphicsStateGuardian::do_issue_cull_face
  5485. // Access: Protected
  5486. // Description:
  5487. ////////////////////////////////////////////////////////////////////
  5488. void CLP(GraphicsStateGuardian)::
  5489. do_issue_cull_face() {
  5490. const CullFaceAttrib *target_cull_face;
  5491. _target_rs->get_attrib_def(target_cull_face);
  5492. CullFaceAttrib::Mode mode = target_cull_face->get_effective_mode();
  5493. switch (mode) {
  5494. case CullFaceAttrib::M_cull_none:
  5495. glDisable(GL_CULL_FACE);
  5496. break;
  5497. case CullFaceAttrib::M_cull_clockwise:
  5498. glEnable(GL_CULL_FACE);
  5499. glCullFace(GL_BACK);
  5500. break;
  5501. case CullFaceAttrib::M_cull_counter_clockwise:
  5502. glEnable(GL_CULL_FACE);
  5503. glCullFace(GL_FRONT);
  5504. break;
  5505. default:
  5506. GLCAT.error()
  5507. << "invalid cull face mode " << (int)mode << endl;
  5508. break;
  5509. }
  5510. report_my_gl_errors();
  5511. }
  5512. #ifdef SUPPORT_FIXED_FUNCTION
  5513. ////////////////////////////////////////////////////////////////////
  5514. // Function: GLGraphicsStateGuardian::do_issue_fog
  5515. // Access: Protected
  5516. // Description:
  5517. ////////////////////////////////////////////////////////////////////
  5518. void CLP(GraphicsStateGuardian)::
  5519. do_issue_fog() {
  5520. const FogAttrib *target_fog;
  5521. _target_rs->get_attrib_def(target_fog);
  5522. if (!target_fog->is_off()) {
  5523. enable_fog(true);
  5524. Fog *fog = target_fog->get_fog();
  5525. nassertv(fog != (Fog *)NULL);
  5526. apply_fog(fog);
  5527. } else {
  5528. enable_fog(false);
  5529. }
  5530. report_my_gl_errors();
  5531. }
  5532. #endif // SUPPORT_FIXED_FUNCTION
  5533. ////////////////////////////////////////////////////////////////////
  5534. // Function: GLGraphicsStateGuardian::do_issue_depth_offset
  5535. // Access: Protected
  5536. // Description:
  5537. ////////////////////////////////////////////////////////////////////
  5538. void CLP(GraphicsStateGuardian)::
  5539. do_issue_depth_offset() {
  5540. const DepthOffsetAttrib *target_depth_offset = (const DepthOffsetAttrib *)
  5541. _target_rs->get_attrib_def(DepthOffsetAttrib::get_class_slot());
  5542. int offset = target_depth_offset->get_offset();
  5543. if (offset != 0) {
  5544. // The relationship between these two parameters is a little
  5545. // unclear and poorly explained in the GL man pages.
  5546. glPolygonOffset((GLfloat) -offset, (GLfloat) -offset);
  5547. enable_polygon_offset(true);
  5548. } else {
  5549. enable_polygon_offset(false);
  5550. }
  5551. PN_stdfloat min_value = target_depth_offset->get_min_value();
  5552. PN_stdfloat max_value = target_depth_offset->get_max_value();
  5553. #ifdef GSG_VERBOSE
  5554. GLCAT.spam()
  5555. << "glDepthRange(" << min_value << ", " << max_value << ")" << endl;
  5556. #endif
  5557. #ifdef OPENGLES
  5558. // OpenGL ES uses a single-precision call.
  5559. glDepthRangef((GLclampf)min_value, (GLclampf)max_value);
  5560. #else
  5561. // Mainline OpenGL uses a double-precision call.
  5562. glDepthRange((GLclampd)min_value, (GLclampd)max_value);
  5563. #endif // OPENGLES
  5564. report_my_gl_errors();
  5565. }
  5566. #ifdef SUPPORT_FIXED_FUNCTION
  5567. ////////////////////////////////////////////////////////////////////
  5568. // Function: GLGraphicsStateGuardian::do_issue_material
  5569. // Access: Protected
  5570. // Description:
  5571. ////////////////////////////////////////////////////////////////////
  5572. void CLP(GraphicsStateGuardian)::
  5573. do_issue_material() {
  5574. static Material empty;
  5575. const Material *material;
  5576. const MaterialAttrib *target_material;
  5577. _target_rs->get_attrib_def(target_material);
  5578. if (target_material == (MaterialAttrib *)NULL ||
  5579. target_material->is_off()) {
  5580. material = &empty;
  5581. } else {
  5582. material = target_material->get_material();
  5583. }
  5584. bool has_material_force_color = _has_material_force_color;
  5585. #ifndef NDEBUG
  5586. if (_show_texture_usage) {
  5587. // In show_texture_usage mode, all colors are white, so as not
  5588. // to contaminate the texture color. This means we disable
  5589. // lighting materials too.
  5590. material = &empty;
  5591. has_material_force_color = false;
  5592. }
  5593. #endif // NDEBUG
  5594. #ifdef OPENGLES
  5595. const GLenum face = GL_FRONT_AND_BACK;
  5596. #else
  5597. GLenum face = material->get_twoside() ? GL_FRONT_AND_BACK : GL_FRONT;
  5598. #endif
  5599. call_glMaterialfv(face, GL_SPECULAR, material->get_specular());
  5600. call_glMaterialfv(face, GL_EMISSION, material->get_emission());
  5601. glMaterialf(face, GL_SHININESS, min(material->get_shininess(), (PN_stdfloat)128.0));
  5602. if (material->has_ambient() && material->has_diffuse()) {
  5603. // The material has both an ambient and diffuse specified. This
  5604. // means we do not need glMaterialColor().
  5605. glDisable(GL_COLOR_MATERIAL);
  5606. call_glMaterialfv(face, GL_AMBIENT, material->get_ambient());
  5607. call_glMaterialfv(face, GL_DIFFUSE, material->get_diffuse());
  5608. } else if (material->has_ambient()) {
  5609. // The material specifies an ambient, but not a diffuse component.
  5610. // The diffuse component comes from the object's color.
  5611. call_glMaterialfv(face, GL_AMBIENT, material->get_ambient());
  5612. if (has_material_force_color) {
  5613. glDisable(GL_COLOR_MATERIAL);
  5614. call_glMaterialfv(face, GL_DIFFUSE, _material_force_color);
  5615. } else {
  5616. #ifndef OPENGLES
  5617. glColorMaterial(face, GL_DIFFUSE);
  5618. #endif // OPENGLES
  5619. glEnable(GL_COLOR_MATERIAL);
  5620. }
  5621. } else if (material->has_diffuse()) {
  5622. // The material specifies a diffuse, but not an ambient component.
  5623. // The ambient component comes from the object's color.
  5624. call_glMaterialfv(face, GL_DIFFUSE, material->get_diffuse());
  5625. if (has_material_force_color) {
  5626. glDisable(GL_COLOR_MATERIAL);
  5627. call_glMaterialfv(face, GL_AMBIENT, _material_force_color);
  5628. } else {
  5629. #ifndef OPENGLES
  5630. glColorMaterial(face, GL_AMBIENT);
  5631. #endif // OPENGLES
  5632. glEnable(GL_COLOR_MATERIAL);
  5633. }
  5634. } else {
  5635. // The material specifies neither a diffuse nor an ambient
  5636. // component. Both components come from the object's color.
  5637. if (has_material_force_color) {
  5638. glDisable(GL_COLOR_MATERIAL);
  5639. call_glMaterialfv(face, GL_AMBIENT, _material_force_color);
  5640. call_glMaterialfv(face, GL_DIFFUSE, _material_force_color);
  5641. } else {
  5642. #ifndef OPENGLES
  5643. glColorMaterial(face, GL_AMBIENT_AND_DIFFUSE);
  5644. #endif // OPENGLES
  5645. glEnable(GL_COLOR_MATERIAL);
  5646. }
  5647. }
  5648. #ifndef OPENGLES
  5649. glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, material->get_local());
  5650. glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, material->get_twoside());
  5651. if (gl_separate_specular_color) {
  5652. glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR);
  5653. } else {
  5654. glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SINGLE_COLOR);
  5655. }
  5656. #endif
  5657. report_my_gl_errors();
  5658. }
  5659. #endif // SUPPORT_FIXED_FUNCTION
  5660. ////////////////////////////////////////////////////////////////////
  5661. // Function: GLGraphicsStateGuardian::do_issue_blending
  5662. // Access: Protected
  5663. // Description:
  5664. ////////////////////////////////////////////////////////////////////
  5665. void CLP(GraphicsStateGuardian)::
  5666. do_issue_blending() {
  5667. // Handle the color_write attrib. If color_write is off, then
  5668. // all the other blending-related stuff doesn't matter. If the
  5669. // device doesn't support color-write, we use blending tricks
  5670. // to effectively disable color write.
  5671. const ColorWriteAttrib *target_color_write;
  5672. _target_rs->get_attrib_def(target_color_write);
  5673. unsigned int color_channels =
  5674. target_color_write->get_channels() & _color_write_mask;
  5675. if (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write)) {
  5676. color_channels &= ~(ColorWriteAttrib::C_alpha);
  5677. }
  5678. if (color_channels == ColorWriteAttrib::C_off) {
  5679. int color_write_slot = ColorWriteAttrib::get_class_slot();
  5680. enable_multisample_alpha_one(false);
  5681. enable_multisample_alpha_mask(false);
  5682. if (gl_color_mask) {
  5683. enable_blend(false);
  5684. set_color_write_mask(ColorWriteAttrib::C_off);
  5685. } else {
  5686. enable_blend(true);
  5687. _glBlendEquation(GL_FUNC_ADD);
  5688. glBlendFunc(GL_ZERO, GL_ONE);
  5689. }
  5690. return;
  5691. } else {
  5692. set_color_write_mask(color_channels);
  5693. }
  5694. const ColorBlendAttrib *target_color_blend;
  5695. _target_rs->get_attrib_def(target_color_blend);
  5696. CPT(ColorBlendAttrib) color_blend = target_color_blend;
  5697. ColorBlendAttrib::Mode color_blend_mode = target_color_blend->get_mode();
  5698. const TransparencyAttrib *target_transparency;
  5699. _target_rs->get_attrib_def(target_transparency);
  5700. TransparencyAttrib::Mode transparency_mode = target_transparency->get_mode();
  5701. _color_blend_involves_color_scale = color_blend->involves_color_scale();
  5702. // Is there a color blend set?
  5703. if (color_blend_mode != ColorBlendAttrib::M_none) {
  5704. enable_multisample_alpha_one(false);
  5705. enable_multisample_alpha_mask(false);
  5706. enable_blend(true);
  5707. _glBlendEquation(get_blend_equation_type(color_blend_mode));
  5708. glBlendFunc(get_blend_func(color_blend->get_operand_a()),
  5709. get_blend_func(color_blend->get_operand_b()));
  5710. if (_color_blend_involves_color_scale) {
  5711. // Apply the current color scale to the blend mode.
  5712. _glBlendColor(_current_color_scale[0], _current_color_scale[1],
  5713. _current_color_scale[2], _current_color_scale[3]);
  5714. } else {
  5715. LColor c = color_blend->get_color();
  5716. _glBlendColor(c[0], c[1], c[2], c[3]);
  5717. }
  5718. return;
  5719. }
  5720. // No color blend; is there a transparency set?
  5721. switch (transparency_mode) {
  5722. case TransparencyAttrib::M_none:
  5723. case TransparencyAttrib::M_binary:
  5724. break;
  5725. case TransparencyAttrib::M_alpha:
  5726. case TransparencyAttrib::M_dual:
  5727. enable_multisample_alpha_one(false);
  5728. enable_multisample_alpha_mask(false);
  5729. enable_blend(true);
  5730. _glBlendEquation(GL_FUNC_ADD);
  5731. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  5732. return;
  5733. case TransparencyAttrib::M_multisample:
  5734. // We need to enable *both* of these in M_multisample case.
  5735. enable_multisample_alpha_one(true);
  5736. enable_multisample_alpha_mask(true);
  5737. enable_blend(false);
  5738. return;
  5739. case TransparencyAttrib::M_multisample_mask:
  5740. enable_multisample_alpha_one(false);
  5741. enable_multisample_alpha_mask(true);
  5742. enable_blend(false);
  5743. return;
  5744. default:
  5745. GLCAT.error()
  5746. << "invalid transparency mode " << (int)transparency_mode << endl;
  5747. break;
  5748. }
  5749. if (_line_smooth_enabled || _point_smooth_enabled) {
  5750. // If we have either of these turned on, we also need to have
  5751. // blend mode enabled in order to see it.
  5752. enable_multisample_alpha_one(false);
  5753. enable_multisample_alpha_mask(false);
  5754. enable_blend(true);
  5755. _glBlendEquation(GL_FUNC_ADD);
  5756. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  5757. return;
  5758. }
  5759. // For best polygon smoothing, we need:
  5760. // (1) a frame buffer that supports alpha
  5761. // (2) sort polygons front-to-back
  5762. // (3) glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE);
  5763. //
  5764. // Since these modes have other implications for the application, we
  5765. // don't attempt to do this by default. If you really want good
  5766. // polygon smoothing (and you don't have multisample support), do
  5767. // all this yourself.
  5768. // Nothing's set, so disable blending.
  5769. enable_multisample_alpha_one(false);
  5770. enable_multisample_alpha_mask(false);
  5771. enable_blend(false);
  5772. }
  5773. #ifdef SUPPORT_FIXED_FUNCTION
  5774. ////////////////////////////////////////////////////////////////////
  5775. // Function: GLGraphicsStateGuardian::bind_light
  5776. // Access: Public, Virtual
  5777. // Description: Called the first time a particular light has been
  5778. // bound to a given id within a frame, this should set
  5779. // up the associated hardware light with the light's
  5780. // properties.
  5781. ////////////////////////////////////////////////////////////////////
  5782. void CLP(GraphicsStateGuardian)::
  5783. bind_light(PointLight *light_obj, const NodePath &light, int light_id) {
  5784. // static PStatCollector _draw_set_state_light_bind_point_pcollector("Draw:Set State:Light:Bind:Point");
  5785. // PStatGPUTimer timer(this, _draw_set_state_light_bind_point_pcollector);
  5786. GLenum id = get_light_id(light_id);
  5787. static const LColor black(0.0f, 0.0f, 0.0f, 1.0f);
  5788. call_glLightfv(id, GL_AMBIENT, black);
  5789. call_glLightfv(id, GL_DIFFUSE, get_light_color(light_obj));
  5790. call_glLightfv(id, GL_SPECULAR, light_obj->get_specular_color());
  5791. // Position needs to specify x, y, z, and w
  5792. // w == 1 implies non-infinite position
  5793. CPT(TransformState) transform = light.get_transform(_scene_setup->get_scene_root().get_parent());
  5794. LPoint3 pos = light_obj->get_point() * transform->get_mat();
  5795. LPoint4 fpos(pos[0], pos[1], pos[2], 1.0f);
  5796. call_glLightfv(id, GL_POSITION, fpos);
  5797. // GL_SPOT_DIRECTION is not significant when cutoff == 180
  5798. // Exponent == 0 implies uniform light distribution
  5799. glLightf(id, GL_SPOT_EXPONENT, 0.0f);
  5800. // Cutoff == 180 means uniform point light source
  5801. glLightf(id, GL_SPOT_CUTOFF, 180.0f);
  5802. const LVecBase3 &att = light_obj->get_attenuation();
  5803. glLightf(id, GL_CONSTANT_ATTENUATION, att[0]);
  5804. glLightf(id, GL_LINEAR_ATTENUATION, att[1]);
  5805. glLightf(id, GL_QUADRATIC_ATTENUATION, att[2]);
  5806. report_my_gl_errors();
  5807. }
  5808. #endif // SUPPORT_FIXED_FUNCTION
  5809. #ifdef SUPPORT_FIXED_FUNCTION
  5810. ////////////////////////////////////////////////////////////////////
  5811. // Function: GLGraphicsStateGuardian::bind_light
  5812. // Access: Public, Virtual
  5813. // Description: Called the first time a particular light has been
  5814. // bound to a given id within a frame, this should set
  5815. // up the associated hardware light with the light's
  5816. // properties.
  5817. ////////////////////////////////////////////////////////////////////
  5818. void CLP(GraphicsStateGuardian)::
  5819. bind_light(DirectionalLight *light_obj, const NodePath &light, int light_id) {
  5820. // static PStatCollector _draw_set_state_light_bind_directional_pcollector("Draw:Set State:Light:Bind:Directional");
  5821. // PStatGPUTimer timer(this, _draw_set_state_light_bind_directional_pcollector);
  5822. pair<DirectionalLights::iterator, bool> lookup = _dlights.insert(DirectionalLights::value_type(light, DirectionalLightFrameData()));
  5823. DirectionalLightFrameData &fdata = (*lookup.first).second;
  5824. if (lookup.second) {
  5825. // The light was not computed yet this frame. Compute it now.
  5826. CPT(TransformState) transform = light.get_transform(_scene_setup->get_scene_root().get_parent());
  5827. LVector3 dir = light_obj->get_direction() * transform->get_mat();
  5828. fdata._neg_dir.set(-dir[0], -dir[1], -dir[2], 0);
  5829. }
  5830. GLenum id = get_light_id( light_id );
  5831. static const LColor black(0.0f, 0.0f, 0.0f, 1.0f);
  5832. call_glLightfv(id, GL_AMBIENT, black);
  5833. call_glLightfv(id, GL_DIFFUSE, get_light_color(light_obj));
  5834. call_glLightfv(id, GL_SPECULAR, light_obj->get_specular_color());
  5835. // Position needs to specify x, y, z, and w.
  5836. // w == 0 implies light is at infinity
  5837. call_glLightfv(id, GL_POSITION, fdata._neg_dir);
  5838. // GL_SPOT_DIRECTION is not significant when cutoff == 180
  5839. // In this case, position x, y, z specifies direction
  5840. // Exponent == 0 implies uniform light distribution
  5841. glLightf(id, GL_SPOT_EXPONENT, 0.0f);
  5842. // Cutoff == 180 means uniform point light source
  5843. glLightf(id, GL_SPOT_CUTOFF, 180.0f);
  5844. // Default attenuation values (only spotlight and point light can
  5845. // modify these)
  5846. glLightf(id, GL_CONSTANT_ATTENUATION, 1.0f);
  5847. glLightf(id, GL_LINEAR_ATTENUATION, 0.0f);
  5848. glLightf(id, GL_QUADRATIC_ATTENUATION, 0.0f);
  5849. report_my_gl_errors();
  5850. }
  5851. #endif // SUPPORT_FIXED_FUNCTION
  5852. #ifdef SUPPORT_FIXED_FUNCTION
  5853. ////////////////////////////////////////////////////////////////////
  5854. // Function: GLGraphicsStateGuardian::bind_light
  5855. // Access: Public, Virtual
  5856. // Description: Called the first time a particular light has been
  5857. // bound to a given id within a frame, this should set
  5858. // up the associated hardware light with the light's
  5859. // properties.
  5860. ////////////////////////////////////////////////////////////////////
  5861. void CLP(GraphicsStateGuardian)::
  5862. bind_light(Spotlight *light_obj, const NodePath &light, int light_id) {
  5863. // static PStatCollector _draw_set_state_light_bind_spotlight_pcollector("Draw:Set State:Light:Bind:Spotlight");
  5864. // PStatGPUTimer timer(this, _draw_set_state_light_bind_spotlight_pcollector);
  5865. Lens *lens = light_obj->get_lens();
  5866. nassertv(lens != (Lens *)NULL);
  5867. GLenum id = get_light_id(light_id);
  5868. static const LColor black(0.0f, 0.0f, 0.0f, 1.0f);
  5869. call_glLightfv(id, GL_AMBIENT, black);
  5870. call_glLightfv(id, GL_DIFFUSE, get_light_color(light_obj));
  5871. call_glLightfv(id, GL_SPECULAR, light_obj->get_specular_color());
  5872. // Position needs to specify x, y, z, and w
  5873. // w == 1 implies non-infinite position
  5874. CPT(TransformState) transform = light.get_transform(_scene_setup->get_scene_root().get_parent());
  5875. const LMatrix4 &light_mat = transform->get_mat();
  5876. LPoint3 pos = lens->get_nodal_point() * light_mat;
  5877. LVector3 dir = lens->get_view_vector() * light_mat;
  5878. LPoint4 fpos(pos[0], pos[1], pos[2], 1.0f);
  5879. call_glLightfv(id, GL_POSITION, fpos);
  5880. call_glLightfv(id, GL_SPOT_DIRECTION, dir);
  5881. glLightf(id, GL_SPOT_EXPONENT, light_obj->get_exponent());
  5882. glLightf(id, GL_SPOT_CUTOFF, lens->get_hfov() * 0.5f);
  5883. const LVecBase3 &att = light_obj->get_attenuation();
  5884. glLightf(id, GL_CONSTANT_ATTENUATION, att[0]);
  5885. glLightf(id, GL_LINEAR_ATTENUATION, att[1]);
  5886. glLightf(id, GL_QUADRATIC_ATTENUATION, att[2]);
  5887. report_my_gl_errors();
  5888. }
  5889. #endif // SUPPORT_FIXED_FUNCTION
  5890. #ifdef SUPPORT_IMMEDIATE_MODE
  5891. ////////////////////////////////////////////////////////////////////
  5892. // Function: GLGraphicsStateGuardian::draw_immediate_simple_primitives
  5893. // Access: Protected
  5894. // Description: Uses the ImmediateModeSender to draw a series of
  5895. // primitives of the indicated type.
  5896. ////////////////////////////////////////////////////////////////////
  5897. void CLP(GraphicsStateGuardian)::
  5898. draw_immediate_simple_primitives(const GeomPrimitivePipelineReader *reader, GLenum mode) {
  5899. int num_vertices = reader->get_num_vertices();
  5900. _vertices_immediate_pcollector.add_level(num_vertices);
  5901. glBegin(mode);
  5902. if (reader->is_indexed()) {
  5903. for (int v = 0; v < num_vertices; ++v) {
  5904. _sender.set_vertex(reader->get_vertex(v));
  5905. _sender.issue_vertex();
  5906. }
  5907. } else {
  5908. _sender.set_vertex(reader->get_first_vertex());
  5909. for (int v = 0; v < num_vertices; ++v) {
  5910. _sender.issue_vertex();
  5911. }
  5912. }
  5913. glEnd();
  5914. }
  5915. #endif // SUPPORT_IMMEDIATE_MODE
  5916. #ifdef SUPPORT_IMMEDIATE_MODE
  5917. ////////////////////////////////////////////////////////////////////
  5918. // Function: GLGraphicsStateGuardian::draw_immediate_composite_primitives
  5919. // Access: Protected
  5920. // Description: Uses the ImmediateModeSender to draw a series of
  5921. // primitives of the indicated type. This form is for
  5922. // primitive types like tristrips which must involve
  5923. // several begin/end groups.
  5924. ////////////////////////////////////////////////////////////////////
  5925. void CLP(GraphicsStateGuardian)::
  5926. draw_immediate_composite_primitives(const GeomPrimitivePipelineReader *reader, GLenum mode) {
  5927. int num_vertices = reader->get_num_vertices();
  5928. _vertices_immediate_pcollector.add_level(num_vertices);
  5929. CPTA_int ends = reader->get_ends();
  5930. int num_unused_vertices_per_primitive = reader->get_object()->get_num_unused_vertices_per_primitive();
  5931. if (reader->is_indexed()) {
  5932. int begin = 0;
  5933. CPTA_int::const_iterator ei;
  5934. for (ei = ends.begin(); ei != ends.end(); ++ei) {
  5935. int end = (*ei);
  5936. glBegin(mode);
  5937. for (int v = begin; v < end; ++v) {
  5938. _sender.set_vertex(reader->get_vertex(v));
  5939. _sender.issue_vertex();
  5940. }
  5941. glEnd();
  5942. begin = end + num_unused_vertices_per_primitive;
  5943. }
  5944. } else {
  5945. _sender.set_vertex(reader->get_first_vertex());
  5946. int begin = 0;
  5947. CPTA_int::const_iterator ei;
  5948. for (ei = ends.begin(); ei != ends.end(); ++ei) {
  5949. int end = (*ei);
  5950. glBegin(mode);
  5951. for (int v = begin; v < end; ++v) {
  5952. _sender.issue_vertex();
  5953. }
  5954. glEnd();
  5955. begin = end + num_unused_vertices_per_primitive;
  5956. }
  5957. }
  5958. }
  5959. #endif // SUPPORT_IMMEDIATE_MODE
  5960. ////////////////////////////////////////////////////////////////////
  5961. // Function: GLGraphicsStateGuardian::gl_flush
  5962. // Access: Protected, Virtual
  5963. // Description: Calls glFlush().
  5964. ////////////////////////////////////////////////////////////////////
  5965. void CLP(GraphicsStateGuardian)::
  5966. gl_flush() const {
  5967. PStatTimer timer(_flush_pcollector);
  5968. glFlush();
  5969. }
  5970. ////////////////////////////////////////////////////////////////////
  5971. // Function: GLGraphicsStateGuardian::gl_get_error
  5972. // Access: Protected, Virtual
  5973. // Description: Returns the result of glGetError().
  5974. ////////////////////////////////////////////////////////////////////
  5975. GLenum CLP(GraphicsStateGuardian)::
  5976. gl_get_error() const {
  5977. if (_check_errors) {
  5978. PStatTimer timer(_check_error_pcollector);
  5979. return glGetError();
  5980. } else {
  5981. return GL_NO_ERROR;
  5982. }
  5983. }
  5984. ////////////////////////////////////////////////////////////////////
  5985. // Function: GLGraphicsStateGuardian::report_errors_loop
  5986. // Access: Protected, Static
  5987. // Description: The internal implementation of report_errors().
  5988. // Don't call this function; use report_errors()
  5989. // instead. The return value is true if everything is
  5990. // ok, or false if we should shut down.
  5991. ////////////////////////////////////////////////////////////////////
  5992. bool CLP(GraphicsStateGuardian)::
  5993. report_errors_loop(int line, const char *source_file, GLenum error_code,
  5994. int &error_count) {
  5995. while ((gl_max_errors < 0 || error_count < gl_max_errors) &&
  5996. (error_code != GL_NO_ERROR)) {
  5997. GLCAT.error()
  5998. << "at " << line << " of " << source_file << " : "
  5999. << get_error_string(error_code) << "\n";
  6000. error_code = glGetError();
  6001. error_count++;
  6002. }
  6003. return (error_code == GL_NO_ERROR);
  6004. }
  6005. ////////////////////////////////////////////////////////////////////
  6006. // Function: GLGraphicsStateGuardian::get_error_string
  6007. // Access: Protected, Static
  6008. // Description: Returns an error string for an OpenGL error code.
  6009. ////////////////////////////////////////////////////////////////////
  6010. string CLP(GraphicsStateGuardian)::
  6011. get_error_string(GLenum error_code) {
  6012. // We used to use gluErrorString here, but I (rdb) took it out
  6013. // because that was really the only function we used from GLU.
  6014. // The idea with the error table was taken from SGI's sample implementation.
  6015. static const char *error_strings[GL_OUT_OF_MEMORY - GL_INVALID_ENUM + 1] = {
  6016. "invalid enumerant",
  6017. "invalid value",
  6018. "invalid operation",
  6019. "stack overflow",
  6020. "stack underflow",
  6021. "out of memory",
  6022. };
  6023. if (error_code == GL_NO_ERROR) {
  6024. return "no error";
  6025. #ifndef OPENGLES
  6026. } else if (error_code == GL_TABLE_TOO_LARGE) {
  6027. return "table too large";
  6028. #endif
  6029. } else if (error_code >= GL_INVALID_ENUM && error_code <= GL_OUT_OF_MEMORY) {
  6030. return error_strings[error_code - GL_INVALID_ENUM];
  6031. }
  6032. // Other error, somehow? Just display the error code then.
  6033. ostringstream strm;
  6034. strm << "GL error " << (int)error_code;
  6035. return strm.str();
  6036. }
  6037. ////////////////////////////////////////////////////////////////////
  6038. // Function: GLGraphicsStateGuardian::show_gl_string
  6039. // Access: Protected
  6040. // Description: Outputs the result of glGetString() on the indicated
  6041. // tag. The output string is returned.
  6042. ////////////////////////////////////////////////////////////////////
  6043. string CLP(GraphicsStateGuardian)::
  6044. show_gl_string(const string &name, GLenum id) {
  6045. string result;
  6046. const GLubyte *text = glGetString(id);
  6047. if (text == (const GLubyte *)NULL) {
  6048. GLCAT.warning()
  6049. << "Unable to query " << name << "\n";
  6050. } else {
  6051. result = (const char *)text;
  6052. if (GLCAT.is_debug()) {
  6053. GLCAT.debug()
  6054. << name << " = " << result << "\n";
  6055. }
  6056. }
  6057. return result;
  6058. }
  6059. ////////////////////////////////////////////////////////////////////
  6060. // Function: GLGraphicsStateGuardian::query_gl_version
  6061. // Access: Protected, Virtual
  6062. // Description: Queries the runtime version of OpenGL in use.
  6063. ////////////////////////////////////////////////////////////////////
  6064. void CLP(GraphicsStateGuardian)::
  6065. query_gl_version() {
  6066. _gl_vendor = show_gl_string("GL_VENDOR", GL_VENDOR);
  6067. _gl_renderer = show_gl_string("GL_RENDERER", GL_RENDERER);
  6068. _gl_version = show_gl_string("GL_VERSION", GL_VERSION);
  6069. _gl_version_major = 0;
  6070. _gl_version_minor = 0;
  6071. // This is the most preposterous driver bug: NVIDIA drivers will claim
  6072. // that the version is 1.2 as long as the process is named pview.exe!
  6073. #ifndef OPENGLES
  6074. if (_gl_version.substr(0, 10) == "1.2 NVIDIA") {
  6075. Filename exec_name = ExecutionEnvironment::get_binary_name();
  6076. if (cmp_nocase(exec_name.get_basename(), "pview.exe") == 0) {
  6077. glGetIntegerv(GL_MAJOR_VERSION, &_gl_version_major);
  6078. glGetIntegerv(GL_MINOR_VERSION, &_gl_version_minor);
  6079. if (glGetError() == GL_INVALID_ENUM) {
  6080. _gl_version_major = 1;
  6081. _gl_version_minor = 2;
  6082. GLCAT.warning()
  6083. << "Driver possibly misreported GL_VERSION! Unable to detect "
  6084. "correct OpenGL version.\n";
  6085. } else if (_gl_version_major != 1 || _gl_version_minor != 2) {
  6086. GLCAT.debug()
  6087. << "Driver misreported GL_VERSION! Correct version detected as "
  6088. << _gl_version_major << "." << _gl_version_minor << "\n";
  6089. }
  6090. return;
  6091. }
  6092. }
  6093. // If we asked for a GL 3 context, let's first try and see if we
  6094. // can use the OpenGL 3 way to query version.
  6095. if (gl_version.get_num_words() > 0 && gl_version[0] >= 3) {
  6096. glGetIntegerv(GL_MAJOR_VERSION, &_gl_version_major);
  6097. glGetIntegerv(GL_MINOR_VERSION, &_gl_version_minor);
  6098. if (_gl_version_major >= 1) {
  6099. // Fair enough, seems to check out.
  6100. if (GLCAT.is_debug()) {
  6101. GLCAT.debug()
  6102. << "Detected OpenGL version: "
  6103. << _gl_version_major << "." << _gl_version_minor << "\n";
  6104. }
  6105. return;
  6106. }
  6107. }
  6108. #endif // !OPENGLES
  6109. // Otherwise, parse the GL_VERSION string.
  6110. if (_gl_version.empty()) {
  6111. GLCAT.error() << "Unable to detect OpenGL version\n";
  6112. } else {
  6113. string input = _gl_version;
  6114. // Skip any initial words that don't begin with a digit.
  6115. while (!input.empty() && !isdigit(input[0])) {
  6116. size_t space = input.find(' ');
  6117. if (space == string::npos) {
  6118. break;
  6119. }
  6120. size_t next = space + 1;
  6121. while (next < input.length() && isspace(input[next])) {
  6122. ++next;
  6123. }
  6124. input = input.substr(next);
  6125. }
  6126. // Truncate after the first space.
  6127. size_t space = input.find(' ');
  6128. if (space != string::npos) {
  6129. input = input.substr(0, space);
  6130. }
  6131. vector_string components;
  6132. tokenize(input, components, ".");
  6133. if (components.size() >= 1) {
  6134. string_to_int(components[0], _gl_version_major);
  6135. }
  6136. if (components.size() >= 2) {
  6137. string_to_int(components[1], _gl_version_minor);
  6138. }
  6139. if (GLCAT.is_debug()) {
  6140. GLCAT.debug()
  6141. << "GL_VERSION decoded to: "
  6142. << _gl_version_major << "." << _gl_version_minor
  6143. << "\n";
  6144. }
  6145. }
  6146. }
  6147. ////////////////////////////////////////////////////////////////////
  6148. // Function: GLGraphicsStateGuardian::query_glsl_version
  6149. // Access: Protected
  6150. // Description: Queries the supported GLSL version.
  6151. ////////////////////////////////////////////////////////////////////
  6152. void CLP(GraphicsStateGuardian)::
  6153. query_glsl_version() {
  6154. _gl_shadlang_ver_major = 0;
  6155. _gl_shadlang_ver_minor = 0;
  6156. #ifndef OPENGLES
  6157. // OpenGL 2.0 introduces GLSL in the core. In 1.x, it is an extension.
  6158. if (_gl_version_major >= 2 || has_extension("GL_ARB_shading_language_100")) {
  6159. string ver = show_gl_string("GL_SHADING_LANGUAGE_VERSION", GL_SHADING_LANGUAGE_VERSION);
  6160. _gl_shadlang_ver_major = 1;
  6161. _gl_shadlang_ver_minor = (_gl_version_major >= 2) ? 1 : 0;
  6162. if (ver.empty() ||
  6163. sscanf(ver.c_str(), "%d.%d", &_gl_shadlang_ver_major,
  6164. &_gl_shadlang_ver_minor) != 2) {
  6165. GLCAT.warning() << "Invalid GL_SHADING_LANGUAGE_VERSION format.\n";
  6166. }
  6167. }
  6168. #elif !defined(OPENGLES_1)
  6169. // OpenGL ES 2.0 and above has shader support built-in.
  6170. string ver = show_gl_string("GL_SHADING_LANGUAGE_VERSION", GL_SHADING_LANGUAGE_VERSION);
  6171. _gl_shadlang_ver_major = 1;
  6172. _gl_shadlang_ver_minor = 0;
  6173. if (ver.empty() ||
  6174. sscanf(ver.c_str(), "OpenGL ES GLSL %d.%d", &_gl_shadlang_ver_major,
  6175. &_gl_shadlang_ver_minor) != 2) {
  6176. GLCAT.warning() << "Invalid GL_SHADING_LANGUAGE_VERSION format.\n";
  6177. }
  6178. #endif
  6179. #ifndef OPENGLES_1
  6180. if (GLCAT.is_debug()) {
  6181. GLCAT.debug()
  6182. << "Detected GLSL version: "
  6183. << _gl_shadlang_ver_major << "." << _gl_shadlang_ver_minor << "\n";
  6184. }
  6185. #endif
  6186. }
  6187. ////////////////////////////////////////////////////////////////////
  6188. // Function: GLGraphicsStateGuardian::save_extensions
  6189. // Access: Protected
  6190. // Description: Separates the string returned by GL_EXTENSIONS (or
  6191. // glx or wgl extensions) into its individual tokens
  6192. // and saves them in the _extensions member.
  6193. ////////////////////////////////////////////////////////////////////
  6194. void CLP(GraphicsStateGuardian)::
  6195. save_extensions(const char *extensions) {
  6196. if (extensions != (const char *)NULL) {
  6197. vector_string tokens;
  6198. extract_words(extensions, tokens);
  6199. vector_string::iterator ti;
  6200. for (ti = tokens.begin(); ti != tokens.end(); ++ti) {
  6201. _extensions.insert(*ti);
  6202. }
  6203. }
  6204. }
  6205. ////////////////////////////////////////////////////////////////////
  6206. // Function: GLGraphicsStateGuardian::get_extra_extensions
  6207. // Access: Protected, Virtual
  6208. // Description: This may be redefined by a derived class (e.g. glx or
  6209. // wgl) to get whatever further extensions strings may
  6210. // be appropriate to that interface, in addition to the
  6211. // GL extension strings return by glGetString().
  6212. ////////////////////////////////////////////////////////////////////
  6213. void CLP(GraphicsStateGuardian)::
  6214. get_extra_extensions() {
  6215. }
  6216. ////////////////////////////////////////////////////////////////////
  6217. // Function: GLGraphicsStateGuardian::report_extensions
  6218. // Access: Protected
  6219. // Description: Outputs the list of GL extensions to notify, if debug
  6220. // mode is enabled.
  6221. ////////////////////////////////////////////////////////////////////
  6222. void CLP(GraphicsStateGuardian)::
  6223. report_extensions() const {
  6224. if (GLCAT.is_debug()) {
  6225. ostream &out = GLCAT.debug();
  6226. out << "GL Extensions:\n";
  6227. size_t maxlen = 0;
  6228. pset<string>::const_iterator ei;
  6229. for (ei = _extensions.begin(); ei != _extensions.end(); ++ei) {
  6230. size_t len = (*ei).size();
  6231. out << " " << (*ei);
  6232. // Display a second column.
  6233. if (len <= 38) {
  6234. if (++ei != _extensions.end()) {
  6235. for (int i = len; i < 38; ++i) {
  6236. out.put(' ');
  6237. }
  6238. out << ' ' << (*ei);
  6239. } else {
  6240. out.put('\n');
  6241. break;
  6242. }
  6243. }
  6244. out.put('\n');
  6245. }
  6246. }
  6247. }
  6248. ////////////////////////////////////////////////////////////////////
  6249. // Function: GLGraphicsStateGuardian::get_extension_func
  6250. // Access: Public
  6251. // Description: Returns the pointer to the GL extension function with
  6252. // the indicated name, or NULL if the function is not
  6253. // available.
  6254. ////////////////////////////////////////////////////////////////////
  6255. void *CLP(GraphicsStateGuardian)::
  6256. get_extension_func(const char *name) {
  6257. // First, look in the static-compiled namespace. If we were
  6258. // compiled to expect at least a certain minimum runtime version of
  6259. // OpenGL, then we can expect those extension functions to be
  6260. // available at compile time. Somewhat more reliable than poking
  6261. // around in the runtime pointers.
  6262. static struct {
  6263. const char *name;
  6264. void *fptr;
  6265. } compiled_function_table[] = {
  6266. #ifdef EXPECT_GL_VERSION_1_2
  6267. { "glBlendColor", (void *)&glBlendColor },
  6268. { "glBlendEquation", (void *)&glBlendEquation },
  6269. { "glDrawRangeElements", (void *)&glDrawRangeElements },
  6270. { "glTexImage3D", (void *)&glTexImage3D },
  6271. { "glTexSubImage3D", (void *)&glTexSubImage3D },
  6272. { "glCopyTexSubImage3D", (void *)&glCopyTexSubImage3D },
  6273. #endif
  6274. #ifdef EXPECT_GL_VERSION_1_3
  6275. { "glActiveTexture", (void *)&glActiveTexture },
  6276. { "glClientActiveTexture", (void *)&glClientActiveTexture },
  6277. { "glCompressedTexImage1D", (void *)&glCompressedTexImage1D },
  6278. { "glCompressedTexImage2D", (void *)&glCompressedTexImage2D },
  6279. { "glCompressedTexImage3D", (void *)&glCompressedTexImage3D },
  6280. { "glCompressedTexSubImage1D", (void *)&glCompressedTexSubImage1D },
  6281. { "glCompressedTexSubImage2D", (void *)&glCompressedTexSubImage2D },
  6282. { "glCompressedTexSubImage3D", (void *)&glCompressedTexSubImage3D },
  6283. { "glGetCompressedTexImage", (void *)&glGetCompressedTexImage },
  6284. { "glMultiTexCoord1f", (void *)&glMultiTexCoord1f },
  6285. { "glMultiTexCoord2", (void *)&glMultiTexCoord2 },
  6286. { "glMultiTexCoord3", (void *)&glMultiTexCoord3 },
  6287. { "glMultiTexCoord4", (void *)&glMultiTexCoord4 },
  6288. #endif
  6289. #ifdef EXPECT_GL_VERSION_1_4
  6290. { "glPointParameterfv", (void *)&glPointParameterfv },
  6291. { "glSecondaryColorPointer", (void *)&glSecondaryColorPointer },
  6292. #endif
  6293. #ifdef EXPECT_GL_VERSION_1_5
  6294. { "glBeginQuery", (void *)&glBeginQuery },
  6295. { "glBindBuffer", (void *)&glBindBuffer },
  6296. { "glBufferData", (void *)&glBufferData },
  6297. { "glBufferSubData", (void *)&glBufferSubData },
  6298. { "glDeleteBuffers", (void *)&glDeleteBuffers },
  6299. { "glDeleteQueries", (void *)&glDeleteQueries },
  6300. { "glEndQuery", (void *)&glEndQuery },
  6301. { "glGenBuffers", (void *)&glGenBuffers },
  6302. { "glGenQueries", (void *)&glGenQueries },
  6303. { "glGetQueryObjectuiv", (void *)&glGetQueryObjectuiv },
  6304. { "glGetQueryiv", (void *)&glGetQueryiv },
  6305. #endif
  6306. #ifdef OPENGLES
  6307. { "glActiveTexture", (void *)&glActiveTexture },
  6308. #ifndef OPENGLES_2
  6309. { "glClientActiveTexture", (void *)&glClientActiveTexture },
  6310. #endif
  6311. { "glBindBuffer", (void *)&glBindBuffer },
  6312. { "glBufferData", (void *)&glBufferData },
  6313. { "glBufferSubData", (void *)&glBufferSubData },
  6314. { "glDeleteBuffers", (void *)&glDeleteBuffers },
  6315. { "glGenBuffers", (void *)&glGenBuffers },
  6316. #endif
  6317. { NULL, NULL }
  6318. };
  6319. int i = 0;
  6320. while (compiled_function_table[i].name != NULL) {
  6321. if (strcmp(compiled_function_table[i].name, name) == 0) {
  6322. return compiled_function_table[i].fptr;
  6323. }
  6324. ++i;
  6325. }
  6326. // If the extension function wasn't compiled in, then go get it from
  6327. // the runtime. There's a different interface for each API.
  6328. return do_get_extension_func(name);
  6329. }
  6330. ////////////////////////////////////////////////////////////////////
  6331. // Function: GLGraphicsStateGuardian::do_get_extension_func
  6332. // Access: Public, Virtual
  6333. // Description: This is the virtual implementation of
  6334. // get_extension_func(). Each API-specific GL
  6335. // implementation will map this method to the
  6336. // appropriate API call to retrieve the extension
  6337. // function pointer. Returns NULL if the function is
  6338. // not available.
  6339. ////////////////////////////////////////////////////////////////////
  6340. void *CLP(GraphicsStateGuardian)::
  6341. do_get_extension_func(const char *) {
  6342. return NULL;
  6343. }
  6344. ////////////////////////////////////////////////////////////////////
  6345. // Function: GLGraphicsStateGuardian::set_draw_buffer
  6346. // Access: Protected
  6347. // Description: Sets up the glDrawBuffer to render into the buffer
  6348. // indicated by the RenderBuffer object. This only sets
  6349. // up the color and aux bits; it does not affect the depth,
  6350. // stencil, accum layers.
  6351. ////////////////////////////////////////////////////////////////////
  6352. void CLP(GraphicsStateGuardian)::
  6353. set_draw_buffer(int rbtype) {
  6354. #ifndef OPENGLES // Draw buffers not supported by OpenGL ES.
  6355. if (_current_fbo) {
  6356. GLuint buffers[16];
  6357. int nbuffers = 0;
  6358. int index = 0;
  6359. if (_current_properties->get_color_bits() > 0) {
  6360. if (rbtype & RenderBuffer::T_left) {
  6361. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index;
  6362. }
  6363. ++index;
  6364. if (_current_properties->is_stereo()) {
  6365. if (rbtype & RenderBuffer::T_right) {
  6366. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index;
  6367. }
  6368. ++index;
  6369. }
  6370. }
  6371. for (int i = 0; i < _current_properties->get_aux_rgba(); ++i) {
  6372. if (rbtype & (RenderBuffer::T_aux_rgba_0 << i)) {
  6373. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index;
  6374. }
  6375. ++index;
  6376. }
  6377. for (int i = 0; i < _current_properties->get_aux_hrgba(); ++i) {
  6378. if (rbtype & (RenderBuffer::T_aux_hrgba_0 << i)) {
  6379. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index;
  6380. }
  6381. ++index;
  6382. }
  6383. for (int i = 0; i < _current_properties->get_aux_float(); ++i) {
  6384. if (rbtype & (RenderBuffer::T_aux_float_0 << i)) {
  6385. buffers[nbuffers++] = GL_COLOR_ATTACHMENT0_EXT + index;
  6386. }
  6387. ++index;
  6388. }
  6389. _glDrawBuffers(nbuffers, buffers);
  6390. } else {
  6391. switch (rbtype & RenderBuffer::T_color) {
  6392. case RenderBuffer::T_front:
  6393. glDrawBuffer(GL_FRONT);
  6394. break;
  6395. case RenderBuffer::T_back:
  6396. glDrawBuffer(GL_BACK);
  6397. break;
  6398. case RenderBuffer::T_right:
  6399. glDrawBuffer(GL_RIGHT);
  6400. break;
  6401. case RenderBuffer::T_left:
  6402. glDrawBuffer(GL_LEFT);
  6403. break;
  6404. case RenderBuffer::T_front_right:
  6405. nassertv(_current_properties->is_stereo());
  6406. glDrawBuffer(GL_FRONT_RIGHT);
  6407. break;
  6408. case RenderBuffer::T_front_left:
  6409. nassertv(_current_properties->is_stereo());
  6410. glDrawBuffer(GL_FRONT_LEFT);
  6411. break;
  6412. case RenderBuffer::T_back_right:
  6413. nassertv(_current_properties->is_stereo());
  6414. glDrawBuffer(GL_BACK_RIGHT);
  6415. break;
  6416. case RenderBuffer::T_back_left:
  6417. nassertv(_current_properties->is_stereo());
  6418. glDrawBuffer(GL_BACK_LEFT);
  6419. break;
  6420. default:
  6421. break;
  6422. }
  6423. }
  6424. #endif // OPENGLES
  6425. // Also ensure that any global color channels are masked out.
  6426. set_color_write_mask(_color_write_mask);
  6427. report_my_gl_errors();
  6428. }
  6429. ////////////////////////////////////////////////////////////////////
  6430. // Function: GLGraphicsStateGuardian::set_read_buffer
  6431. // Access: Protected
  6432. // Description: Sets up the glReadBuffer to render into the buffer
  6433. // indicated by the RenderBuffer object. This only sets
  6434. // up the color bits; it does not affect the depth,
  6435. // stencil, accum layers.
  6436. ////////////////////////////////////////////////////////////////////
  6437. void CLP(GraphicsStateGuardian)::
  6438. set_read_buffer(int rbtype) {
  6439. #ifndef OPENGLES // Draw buffers not supported by OpenGL ES.
  6440. if (rbtype & (RenderBuffer::T_depth | RenderBuffer::T_stencil)) {
  6441. // Special case: don't have to call ReadBuffer for these.
  6442. return;
  6443. }
  6444. if (_current_fbo) {
  6445. GLuint buffer = GL_COLOR_ATTACHMENT0_EXT;
  6446. int index = 1;
  6447. if (_current_properties->is_stereo()) {
  6448. if (rbtype & RenderBuffer::T_right) {
  6449. buffer = GL_COLOR_ATTACHMENT1_EXT;
  6450. }
  6451. ++index;
  6452. }
  6453. for (int i = 0; i < _current_properties->get_aux_rgba(); ++i) {
  6454. if (rbtype & (RenderBuffer::T_aux_rgba_0 << i)) {
  6455. buffer = GL_COLOR_ATTACHMENT0_EXT + index;
  6456. }
  6457. ++index;
  6458. }
  6459. for (int i = 0; i < _current_properties->get_aux_hrgba(); ++i) {
  6460. if (rbtype & (RenderBuffer::T_aux_hrgba_0 << i)) {
  6461. buffer = GL_COLOR_ATTACHMENT0_EXT + index;
  6462. }
  6463. ++index;
  6464. }
  6465. for (int i = 0; i < _current_properties->get_aux_float(); ++i) {
  6466. if (rbtype & (RenderBuffer::T_aux_float_0 << i)) {
  6467. buffer = GL_COLOR_ATTACHMENT0_EXT + index;
  6468. }
  6469. ++index;
  6470. }
  6471. glReadBuffer(buffer);
  6472. } else {
  6473. switch (rbtype & RenderBuffer::T_color) {
  6474. case RenderBuffer::T_front:
  6475. glReadBuffer(GL_FRONT);
  6476. break;
  6477. case RenderBuffer::T_back:
  6478. glReadBuffer(GL_BACK);
  6479. break;
  6480. case RenderBuffer::T_right:
  6481. glReadBuffer(GL_RIGHT);
  6482. break;
  6483. case RenderBuffer::T_left:
  6484. glReadBuffer(GL_LEFT);
  6485. break;
  6486. case RenderBuffer::T_front_right:
  6487. glReadBuffer(GL_FRONT_RIGHT);
  6488. break;
  6489. case RenderBuffer::T_front_left:
  6490. glReadBuffer(GL_FRONT_LEFT);
  6491. break;
  6492. case RenderBuffer::T_back_right:
  6493. glReadBuffer(GL_BACK_RIGHT);
  6494. break;
  6495. case RenderBuffer::T_back_left:
  6496. glReadBuffer(GL_BACK_LEFT);
  6497. break;
  6498. default:
  6499. break;
  6500. }
  6501. }
  6502. report_my_gl_errors();
  6503. #endif // OPENGLES
  6504. }
  6505. ////////////////////////////////////////////////////////////////////
  6506. // Function: GLGraphicsStateGuardian::get_numeric_type
  6507. // Access: Protected, Static
  6508. // Description: Maps from the Geom's internal numeric type symbols
  6509. // to GL's.
  6510. ////////////////////////////////////////////////////////////////////
  6511. GLenum CLP(GraphicsStateGuardian)::
  6512. get_numeric_type(Geom::NumericType numeric_type) {
  6513. switch (numeric_type) {
  6514. case Geom::NT_uint16:
  6515. return GL_UNSIGNED_SHORT;
  6516. case Geom::NT_uint32:
  6517. #ifndef OPENGLES_1
  6518. return GL_UNSIGNED_INT;
  6519. #else
  6520. break;
  6521. #endif
  6522. case Geom::NT_uint8:
  6523. case Geom::NT_packed_dcba:
  6524. case Geom::NT_packed_dabc:
  6525. return GL_UNSIGNED_BYTE;
  6526. case Geom::NT_float32:
  6527. return GL_FLOAT;
  6528. case Geom::NT_float64:
  6529. #ifndef OPENGLES
  6530. return GL_DOUBLE;
  6531. #else
  6532. break;
  6533. #endif
  6534. case Geom::NT_stdfloat:
  6535. // Shouldn't happen, display error.
  6536. break;
  6537. case Geom::NT_int8:
  6538. return GL_BYTE;
  6539. case Geom::NT_int16:
  6540. return GL_SHORT;
  6541. case Geom::NT_int32:
  6542. #ifndef OPENGLES_1
  6543. return GL_INT;
  6544. #else
  6545. break;
  6546. #endif
  6547. case Geom::NT_packed_ufloat:
  6548. #ifndef OPENGLES
  6549. return GL_UNSIGNED_INT_10F_11F_11F_REV;
  6550. #else
  6551. break;
  6552. #endif
  6553. }
  6554. GLCAT.error()
  6555. << "Invalid NumericType value (" << (int)numeric_type << ")\n";
  6556. return GL_UNSIGNED_BYTE;
  6557. }
  6558. ////////////////////////////////////////////////////////////////////
  6559. // Function: GLGraphicsStateGuardian::get_texture_target
  6560. // Access: Protected
  6561. // Description: Maps from the Texture's texture type symbols to
  6562. // GL's.
  6563. ////////////////////////////////////////////////////////////////////
  6564. GLenum CLP(GraphicsStateGuardian)::
  6565. get_texture_target(Texture::TextureType texture_type) const {
  6566. switch (texture_type) {
  6567. case Texture::TT_1d_texture:
  6568. // There are no 1D textures in OpenGL ES. Fall back to 2D textures.
  6569. #ifndef OPENGLES
  6570. return GL_TEXTURE_1D;
  6571. #endif
  6572. case Texture::TT_2d_texture:
  6573. return GL_TEXTURE_2D;
  6574. case Texture::TT_3d_texture:
  6575. #ifndef OPENGLES_1
  6576. if (_supports_3d_texture) {
  6577. return GL_TEXTURE_3D;
  6578. }
  6579. #endif
  6580. return GL_NONE;
  6581. case Texture::TT_2d_texture_array:
  6582. #ifndef OPENGLES
  6583. if (_supports_2d_texture_array) {
  6584. return GL_TEXTURE_2D_ARRAY_EXT;
  6585. }
  6586. #endif
  6587. return GL_NONE;
  6588. case Texture::TT_cube_map:
  6589. if (_supports_cube_map) {
  6590. return GL_TEXTURE_CUBE_MAP;
  6591. } else {
  6592. return GL_NONE;
  6593. }
  6594. case Texture::TT_buffer_texture:
  6595. #ifndef OPENGLES
  6596. if (_supports_buffer_texture) {
  6597. return GL_TEXTURE_BUFFER;
  6598. }
  6599. #endif
  6600. return GL_NONE;
  6601. }
  6602. GLCAT.error() << "Invalid Texture::TextureType value!\n";
  6603. return GL_TEXTURE_2D;
  6604. }
  6605. ////////////////////////////////////////////////////////////////////
  6606. // Function: GLGraphicsStateGuardian::get_texture_wrap_mode
  6607. // Access: Protected
  6608. // Description: Maps from the Texture's internal wrap mode symbols to
  6609. // GL's.
  6610. ////////////////////////////////////////////////////////////////////
  6611. GLenum CLP(GraphicsStateGuardian)::
  6612. get_texture_wrap_mode(SamplerState::WrapMode wm) const {
  6613. if (gl_ignore_clamp) {
  6614. return GL_REPEAT;
  6615. }
  6616. switch (wm) {
  6617. case SamplerState::WM_clamp:
  6618. return _edge_clamp;
  6619. case SamplerState::WM_repeat:
  6620. return GL_REPEAT;
  6621. case SamplerState::WM_mirror:
  6622. return _mirror_repeat;
  6623. case SamplerState::WM_mirror_once:
  6624. return _mirror_border_clamp;
  6625. case SamplerState::WM_border_color:
  6626. return _border_clamp;
  6627. case SamplerState::WM_invalid:
  6628. break;
  6629. }
  6630. GLCAT.error() << "Invalid SamplerState::WrapMode value!\n";
  6631. return _edge_clamp;
  6632. }
  6633. ////////////////////////////////////////////////////////////////////
  6634. // Function: GLGraphicsStateGuardian::get_panda_wrap_mode
  6635. // Access: Protected, Static
  6636. // Description: Maps from the GL's internal wrap mode symbols to
  6637. // Panda's.
  6638. ////////////////////////////////////////////////////////////////////
  6639. SamplerState::WrapMode CLP(GraphicsStateGuardian)::
  6640. get_panda_wrap_mode(GLenum wm) {
  6641. switch (wm) {
  6642. #ifndef OPENGLES
  6643. case GL_CLAMP:
  6644. #endif
  6645. case GL_CLAMP_TO_EDGE:
  6646. return SamplerState::WM_clamp;
  6647. #ifndef OPENGLES
  6648. case GL_CLAMP_TO_BORDER:
  6649. return SamplerState::WM_border_color;
  6650. #endif
  6651. case GL_REPEAT:
  6652. return SamplerState::WM_repeat;
  6653. #ifndef OPENGLES
  6654. case GL_MIRROR_CLAMP_EXT:
  6655. case GL_MIRROR_CLAMP_TO_EDGE_EXT:
  6656. return SamplerState::WM_mirror;
  6657. case GL_MIRROR_CLAMP_TO_BORDER_EXT:
  6658. return SamplerState::WM_mirror_once;
  6659. #endif
  6660. }
  6661. GLCAT.error() << "Unexpected GL wrap mode " << (int)wm << "\n";
  6662. return SamplerState::WM_clamp;
  6663. }
  6664. ////////////////////////////////////////////////////////////////////
  6665. // Function: GLGraphicsStateGuardian::get_texture_filter_type
  6666. // Access: Protected, Static
  6667. // Description: Maps from the Texture's internal filter type symbols
  6668. // to GL's.
  6669. ////////////////////////////////////////////////////////////////////
  6670. GLenum CLP(GraphicsStateGuardian)::
  6671. get_texture_filter_type(SamplerState::FilterType ft, bool ignore_mipmaps) {
  6672. if (gl_ignore_filters) {
  6673. return GL_NEAREST;
  6674. } else if (ignore_mipmaps) {
  6675. switch (ft) {
  6676. case SamplerState::FT_nearest_mipmap_nearest:
  6677. case SamplerState::FT_nearest:
  6678. return GL_NEAREST;
  6679. case SamplerState::FT_linear:
  6680. case SamplerState::FT_linear_mipmap_nearest:
  6681. case SamplerState::FT_nearest_mipmap_linear:
  6682. case SamplerState::FT_linear_mipmap_linear:
  6683. return GL_LINEAR;
  6684. case SamplerState::FT_shadow:
  6685. return GL_LINEAR;
  6686. case SamplerState::FT_default:
  6687. case SamplerState::FT_invalid:
  6688. break;
  6689. }
  6690. } else {
  6691. switch (ft) {
  6692. case SamplerState::FT_nearest:
  6693. return GL_NEAREST;
  6694. case SamplerState::FT_linear:
  6695. return GL_LINEAR;
  6696. case SamplerState::FT_nearest_mipmap_nearest:
  6697. return GL_NEAREST_MIPMAP_NEAREST;
  6698. case SamplerState::FT_linear_mipmap_nearest:
  6699. return GL_LINEAR_MIPMAP_NEAREST;
  6700. case SamplerState::FT_nearest_mipmap_linear:
  6701. return GL_NEAREST_MIPMAP_LINEAR;
  6702. case SamplerState::FT_linear_mipmap_linear:
  6703. return GL_LINEAR_MIPMAP_LINEAR;
  6704. case SamplerState::FT_shadow:
  6705. return GL_LINEAR;
  6706. case SamplerState::FT_default:
  6707. case SamplerState::FT_invalid:
  6708. break;
  6709. }
  6710. }
  6711. GLCAT.error() << "Invalid SamplerState::FilterType value!\n";
  6712. return GL_NEAREST;
  6713. }
  6714. ////////////////////////////////////////////////////////////////////
  6715. // Function: GLGraphicsStateGuardian::get_panda_filter_type
  6716. // Access: Protected, Static
  6717. // Description: Maps from the GL's internal filter type symbols
  6718. // to Panda's.
  6719. ////////////////////////////////////////////////////////////////////
  6720. SamplerState::FilterType CLP(GraphicsStateGuardian)::
  6721. get_panda_filter_type(GLenum ft) {
  6722. switch (ft) {
  6723. case GL_NEAREST:
  6724. return SamplerState::FT_nearest;
  6725. case GL_LINEAR:
  6726. return SamplerState::FT_linear;
  6727. case GL_NEAREST_MIPMAP_NEAREST:
  6728. return SamplerState::FT_nearest_mipmap_nearest;
  6729. case GL_LINEAR_MIPMAP_NEAREST:
  6730. return SamplerState::FT_linear_mipmap_nearest;
  6731. case GL_NEAREST_MIPMAP_LINEAR:
  6732. return SamplerState::FT_nearest_mipmap_linear;
  6733. case GL_LINEAR_MIPMAP_LINEAR:
  6734. return SamplerState::FT_linear_mipmap_linear;
  6735. }
  6736. GLCAT.error() << "Unexpected GL filter type " << (int)ft << "\n";
  6737. return SamplerState::FT_linear;
  6738. }
  6739. ////////////////////////////////////////////////////////////////////
  6740. // Function: GLGraphicsStateGuardian::get_component_type
  6741. // Access: Protected, Static
  6742. // Description: Maps from the Texture's internal ComponentType symbols
  6743. // to GL's.
  6744. ////////////////////////////////////////////////////////////////////
  6745. GLenum CLP(GraphicsStateGuardian)::
  6746. get_component_type(Texture::ComponentType component_type) {
  6747. switch (component_type) {
  6748. case Texture::T_unsigned_byte:
  6749. return GL_UNSIGNED_BYTE;
  6750. case Texture::T_unsigned_short:
  6751. return GL_UNSIGNED_SHORT;
  6752. case Texture::T_float:
  6753. return GL_FLOAT;
  6754. case Texture::T_unsigned_int_24_8:
  6755. if (_supports_depth_stencil) {
  6756. return GL_UNSIGNED_INT_24_8_EXT;
  6757. } else {
  6758. return GL_UNSIGNED_BYTE;
  6759. }
  6760. case Texture::T_int:
  6761. #ifndef OPENGLES_1
  6762. return GL_INT;
  6763. #endif
  6764. default:
  6765. GLCAT.error() << "Invalid Texture::Type value!\n";
  6766. return GL_UNSIGNED_BYTE;
  6767. }
  6768. }
  6769. ////////////////////////////////////////////////////////////////////
  6770. // Function: GLGraphicsStateGuardian::get_external_image_format
  6771. // Access: Protected
  6772. // Description: Maps from the Texture's Format symbols
  6773. // to GL's.
  6774. ////////////////////////////////////////////////////////////////////
  6775. GLint CLP(GraphicsStateGuardian)::
  6776. get_external_image_format(Texture *tex) const {
  6777. Texture::CompressionMode compression = tex->get_ram_image_compression();
  6778. Texture::Format format = tex->get_format();
  6779. if (compression != Texture::CM_off &&
  6780. get_supports_compressed_texture_format(compression)) {
  6781. switch (compression) {
  6782. case Texture::CM_on:
  6783. #ifndef OPENGLES
  6784. switch (format) {
  6785. case Texture::F_color_index:
  6786. case Texture::F_depth_component:
  6787. case Texture::F_depth_component16:
  6788. case Texture::F_depth_component24:
  6789. case Texture::F_depth_component32:
  6790. case Texture::F_depth_stencil:
  6791. // This shouldn't be possible.
  6792. nassertr(false, GL_RGB);
  6793. break;
  6794. case Texture::F_rgba:
  6795. case Texture::F_rgbm:
  6796. case Texture::F_rgba4:
  6797. case Texture::F_rgba8:
  6798. case Texture::F_rgba12:
  6799. case Texture::F_rgba16:
  6800. case Texture::F_rgba32:
  6801. case Texture::F_rgba8i:
  6802. return GL_COMPRESSED_RGBA;
  6803. case Texture::F_rgb:
  6804. case Texture::F_rgb5:
  6805. case Texture::F_rgba5:
  6806. case Texture::F_rgb8:
  6807. case Texture::F_rgb8i:
  6808. case Texture::F_rgb12:
  6809. case Texture::F_rgb332:
  6810. case Texture::F_rgb16:
  6811. case Texture::F_rgb32:
  6812. return GL_COMPRESSED_RGB;
  6813. case Texture::F_alpha:
  6814. return GL_COMPRESSED_ALPHA;
  6815. case Texture::F_red:
  6816. case Texture::F_green:
  6817. case Texture::F_blue:
  6818. case Texture::F_r8i:
  6819. case Texture::F_r16:
  6820. case Texture::F_r32:
  6821. case Texture::F_r32i:
  6822. return GL_COMPRESSED_RED;
  6823. case Texture::F_rg8i:
  6824. case Texture::F_rg16:
  6825. case Texture::F_rg32:
  6826. return GL_COMPRESSED_RG;
  6827. case Texture::F_luminance:
  6828. return GL_COMPRESSED_LUMINANCE;
  6829. case Texture::F_luminance_alpha:
  6830. case Texture::F_luminance_alphamask:
  6831. return GL_COMPRESSED_LUMINANCE_ALPHA;
  6832. case Texture::F_srgb:
  6833. return GL_COMPRESSED_SRGB;
  6834. case Texture::F_srgb_alpha:
  6835. return GL_COMPRESSED_SRGB_ALPHA;
  6836. case Texture::F_sluminance:
  6837. return GL_COMPRESSED_SLUMINANCE;
  6838. case Texture::F_sluminance_alpha:
  6839. return GL_COMPRESSED_SLUMINANCE_ALPHA;
  6840. }
  6841. #endif
  6842. break;
  6843. case Texture::CM_dxt1:
  6844. #ifndef OPENGLES
  6845. if (format == Texture::F_srgb_alpha) {
  6846. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
  6847. } else if (format == Texture::F_srgb) {
  6848. return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
  6849. } else
  6850. #endif
  6851. if (Texture::has_alpha(format)) {
  6852. return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
  6853. } else {
  6854. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  6855. }
  6856. case Texture::CM_dxt3:
  6857. #ifndef OPENGLES
  6858. if (format == Texture::F_srgb || format == Texture::F_srgb_alpha) {
  6859. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
  6860. }
  6861. #endif
  6862. #ifndef OPENGLES_1
  6863. return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
  6864. #endif
  6865. break;
  6866. case Texture::CM_dxt5:
  6867. #ifndef OPENGLES
  6868. if (format == Texture::F_srgb || format == Texture::F_srgb_alpha) {
  6869. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
  6870. }
  6871. #endif
  6872. #ifndef OPENGLES_1
  6873. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  6874. #endif
  6875. break;
  6876. case Texture::CM_fxt1:
  6877. #ifndef OPENGLES
  6878. if (Texture::has_alpha(format)) {
  6879. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  6880. } else {
  6881. return GL_COMPRESSED_RGB_FXT1_3DFX;
  6882. }
  6883. #endif
  6884. break;
  6885. #ifdef OPENGLES
  6886. case Texture::CM_pvr1_2bpp:
  6887. if (Texture::has_alpha(format)) {
  6888. return GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
  6889. } else {
  6890. return GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
  6891. }
  6892. case Texture::CM_pvr1_4bpp:
  6893. if (Texture::has_alpha(format)) {
  6894. return GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
  6895. } else {
  6896. return GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
  6897. }
  6898. #else
  6899. case Texture::CM_pvr1_2bpp:
  6900. case Texture::CM_pvr1_4bpp:
  6901. break;
  6902. #endif // OPENGLES
  6903. case Texture::CM_default:
  6904. case Texture::CM_off:
  6905. case Texture::CM_dxt2:
  6906. case Texture::CM_dxt4:
  6907. // This shouldn't happen.
  6908. nassertr(false, GL_RGB);
  6909. break;
  6910. }
  6911. }
  6912. switch (format) {
  6913. #ifndef OPENGLES
  6914. case Texture::F_color_index:
  6915. return GL_COLOR_INDEX;
  6916. #endif
  6917. case Texture::F_depth_component:
  6918. case Texture::F_depth_component16:
  6919. case Texture::F_depth_component24:
  6920. case Texture::F_depth_component32:
  6921. return GL_DEPTH_COMPONENT;
  6922. case Texture::F_depth_stencil:
  6923. return _supports_depth_stencil ? GL_DEPTH_STENCIL : GL_DEPTH_COMPONENT;
  6924. #ifndef OPENGLES
  6925. case Texture::F_red:
  6926. case Texture::F_r16:
  6927. case Texture::F_r32:
  6928. return GL_RED;
  6929. case Texture::F_green:
  6930. return GL_GREEN;
  6931. case Texture::F_blue:
  6932. return GL_BLUE;
  6933. #endif
  6934. case Texture::F_alpha:
  6935. #ifdef SUPPORT_FIXED_FUNCTION
  6936. return GL_ALPHA;
  6937. #else
  6938. return GL_RED;
  6939. #endif
  6940. #ifndef OPENGLES_1
  6941. case Texture::F_rg16:
  6942. case Texture::F_rg32:
  6943. return GL_RG;
  6944. #endif
  6945. case Texture::F_rgb:
  6946. case Texture::F_rgb5:
  6947. case Texture::F_rgb8:
  6948. case Texture::F_rgb12:
  6949. case Texture::F_rgb332:
  6950. case Texture::F_rgb16:
  6951. case Texture::F_rgb32:
  6952. case Texture::F_srgb:
  6953. #ifdef OPENGLES
  6954. return GL_RGB;
  6955. #else
  6956. return _supports_bgr ? GL_BGR : GL_RGB;
  6957. #endif
  6958. case Texture::F_rgba:
  6959. case Texture::F_rgbm:
  6960. case Texture::F_rgba4:
  6961. case Texture::F_rgba5:
  6962. case Texture::F_rgba8:
  6963. case Texture::F_rgba12:
  6964. case Texture::F_rgba16:
  6965. case Texture::F_rgba32:
  6966. case Texture::F_srgb_alpha:
  6967. #ifdef OPENGLES_2
  6968. return GL_RGBA;
  6969. #else
  6970. return _supports_bgr ? GL_BGRA : GL_RGBA;
  6971. #endif
  6972. case Texture::F_luminance:
  6973. case Texture::F_sluminance:
  6974. #ifdef SUPPORT_FIXED_FUNCTION
  6975. return GL_LUMINANCE;
  6976. #else
  6977. return GL_RED;
  6978. #endif
  6979. case Texture::F_luminance_alphamask:
  6980. case Texture::F_luminance_alpha:
  6981. case Texture::F_sluminance_alpha:
  6982. #ifdef SUPPORT_FIXED_FUNCTION
  6983. return GL_LUMINANCE_ALPHA;
  6984. #else
  6985. return GL_RG;
  6986. #endif
  6987. #ifndef OPENGLES
  6988. case Texture::F_r8i:
  6989. case Texture::F_r32i:
  6990. return GL_RED_INTEGER;
  6991. case Texture::F_rg8i:
  6992. return GL_RG_INTEGER;
  6993. case Texture::F_rgb8i:
  6994. return GL_RGB_INTEGER;
  6995. case Texture::F_rgba8i:
  6996. return GL_RGBA_INTEGER;
  6997. #endif
  6998. default:
  6999. break;
  7000. }
  7001. GLCAT.error()
  7002. << "Invalid Texture::Format value in get_external_image_format(): "
  7003. << tex->get_format() << "\n";
  7004. return GL_RGB;
  7005. }
  7006. ////////////////////////////////////////////////////////////////////
  7007. // Function: GLGraphicsStateGuardian::get_internal_image_format
  7008. // Access: Protected
  7009. // Description: Maps from the Texture's Format symbols to a
  7010. // suitable internal format for GL textures.
  7011. ////////////////////////////////////////////////////////////////////
  7012. GLint CLP(GraphicsStateGuardian)::
  7013. get_internal_image_format(Texture *tex, bool force_sized) const {
  7014. Texture::CompressionMode compression = tex->get_compression();
  7015. if (compression == Texture::CM_default) {
  7016. compression = (compressed_textures) ? Texture::CM_on : Texture::CM_off;
  7017. }
  7018. Texture::Format format = tex->get_format();
  7019. if (tex->get_render_to_texture()) {
  7020. // no compression for render targets
  7021. compression = Texture::CM_off;
  7022. }
  7023. bool is_3d = (tex->get_texture_type() == Texture::TT_3d_texture ||
  7024. tex->get_texture_type() == Texture::TT_2d_texture_array);
  7025. if (get_supports_compressed_texture_format(compression)) {
  7026. switch (compression) {
  7027. case Texture::CM_on:
  7028. // The user asked for just generic compression. OpenGL supports
  7029. // requesting just generic compression, but we'd like to go ahead
  7030. // and request a specific type (if we can figure out an
  7031. // appropriate choice), since that makes saving the result as a
  7032. // pre-compressed texture more dependable--this way, we will know
  7033. // which compression algorithm was applied.
  7034. switch (format) {
  7035. case Texture::F_color_index:
  7036. case Texture::F_depth_component:
  7037. case Texture::F_depth_component16:
  7038. case Texture::F_depth_component24:
  7039. case Texture::F_depth_component32:
  7040. case Texture::F_depth_stencil:
  7041. case Texture::F_r8i:
  7042. case Texture::F_rg8i:
  7043. case Texture::F_rgb8i:
  7044. case Texture::F_rgba8i:
  7045. case Texture::F_r32i:
  7046. // Unsupported; fall through to below.
  7047. break;
  7048. case Texture::F_rgbm:
  7049. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  7050. return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
  7051. }
  7052. #ifndef OPENGLES
  7053. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7054. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  7055. }
  7056. return GL_COMPRESSED_RGBA;
  7057. #endif
  7058. break;
  7059. case Texture::F_rgba4:
  7060. #ifndef OPENGLES_1
  7061. if (get_supports_compressed_texture_format(Texture::CM_dxt3) && !is_3d) {
  7062. return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
  7063. }
  7064. #endif
  7065. #ifndef OPENGLES
  7066. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7067. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  7068. }
  7069. return GL_COMPRESSED_RGBA;
  7070. #endif
  7071. break;
  7072. case Texture::F_rgba:
  7073. case Texture::F_rgba8:
  7074. case Texture::F_rgba12:
  7075. case Texture::F_rgba16:
  7076. case Texture::F_rgba32:
  7077. #ifndef OPENGLES_1
  7078. if (get_supports_compressed_texture_format(Texture::CM_dxt5) && !is_3d) {
  7079. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  7080. }
  7081. #endif
  7082. #ifndef OPENGLES
  7083. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7084. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  7085. }
  7086. return GL_COMPRESSED_RGBA;
  7087. #endif
  7088. break;
  7089. case Texture::F_rgb:
  7090. case Texture::F_rgb5:
  7091. case Texture::F_rgba5:
  7092. case Texture::F_rgb8:
  7093. case Texture::F_rgb12:
  7094. case Texture::F_rgb332:
  7095. case Texture::F_rgb16:
  7096. case Texture::F_rgb32:
  7097. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  7098. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  7099. }
  7100. #ifndef OPENGLES
  7101. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7102. return GL_COMPRESSED_RGB_FXT1_3DFX;
  7103. }
  7104. return GL_COMPRESSED_RGB;
  7105. #endif
  7106. break;
  7107. case Texture::F_alpha:
  7108. #ifndef OPENGLES_1
  7109. if (get_supports_compressed_texture_format(Texture::CM_dxt5) && !is_3d) {
  7110. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  7111. }
  7112. #endif
  7113. #ifndef OPENGLES
  7114. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7115. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  7116. }
  7117. return GL_COMPRESSED_ALPHA;
  7118. #endif
  7119. break;
  7120. case Texture::F_red:
  7121. case Texture::F_green:
  7122. case Texture::F_blue:
  7123. case Texture::F_r16:
  7124. case Texture::F_r32:
  7125. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  7126. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  7127. }
  7128. #ifndef OPENGLES
  7129. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7130. return GL_COMPRESSED_RGB_FXT1_3DFX;
  7131. }
  7132. return GL_COMPRESSED_RED;
  7133. #endif
  7134. break;
  7135. case Texture::F_rg16:
  7136. case Texture::F_rg32:
  7137. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  7138. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  7139. }
  7140. #ifndef OPENGLES
  7141. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7142. return GL_COMPRESSED_RGB_FXT1_3DFX;
  7143. }
  7144. return GL_COMPRESSED_RG;
  7145. #endif
  7146. break;
  7147. case Texture::F_luminance:
  7148. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  7149. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  7150. }
  7151. #ifndef OPENGLES
  7152. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7153. return GL_COMPRESSED_RGB_FXT1_3DFX;
  7154. }
  7155. return GL_COMPRESSED_LUMINANCE;
  7156. #endif
  7157. break;
  7158. case Texture::F_luminance_alpha:
  7159. case Texture::F_luminance_alphamask:
  7160. #ifndef OPENGLES_1
  7161. if (get_supports_compressed_texture_format(Texture::CM_dxt5) && !is_3d) {
  7162. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  7163. }
  7164. #endif
  7165. #ifndef OPENGLES
  7166. if (get_supports_compressed_texture_format(Texture::CM_fxt1) && !is_3d) {
  7167. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  7168. }
  7169. return GL_COMPRESSED_LUMINANCE_ALPHA;
  7170. #endif
  7171. break;
  7172. #ifndef OPENGLES
  7173. case Texture::F_srgb:
  7174. if (get_supports_compressed_texture_format(Texture::CM_dxt1) && !is_3d) {
  7175. return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
  7176. }
  7177. return GL_COMPRESSED_SRGB;
  7178. case Texture::F_srgb_alpha:
  7179. if (get_supports_compressed_texture_format(Texture::CM_dxt5) && !is_3d) {
  7180. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
  7181. }
  7182. return GL_COMPRESSED_SRGB_ALPHA;
  7183. case Texture::F_sluminance:
  7184. return GL_COMPRESSED_SLUMINANCE;
  7185. case Texture::F_sluminance_alpha:
  7186. return GL_COMPRESSED_SLUMINANCE_ALPHA;
  7187. #else
  7188. // For now, we don't support compressed sRGB textures in OpenGL ES.
  7189. case Texture::F_srgb:
  7190. case Texture::F_srgb_alpha:
  7191. case Texture::F_sluminance:
  7192. case Texture::F_sluminance_alpha:
  7193. break;
  7194. #endif
  7195. }
  7196. break;
  7197. case Texture::CM_dxt1:
  7198. #ifndef OPENGLES
  7199. if (format == Texture::F_srgb_alpha) {
  7200. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT;
  7201. } else if (format == Texture::F_srgb) {
  7202. return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT;
  7203. } else
  7204. #endif
  7205. if (Texture::has_alpha(format)) {
  7206. return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT;
  7207. } else {
  7208. return GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
  7209. }
  7210. case Texture::CM_dxt3:
  7211. #ifndef OPENGLES
  7212. if (format == Texture::F_srgb || format == Texture::F_srgb_alpha) {
  7213. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT;
  7214. }
  7215. #endif
  7216. #ifndef OPENGLES_1
  7217. return GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
  7218. #endif
  7219. break;
  7220. case Texture::CM_dxt5:
  7221. #ifndef OPENGLES
  7222. if (format == Texture::F_srgb || format == Texture::F_srgb_alpha) {
  7223. return GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT;
  7224. }
  7225. #endif
  7226. #ifndef OPENGLES_1
  7227. return GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
  7228. #endif
  7229. case Texture::CM_fxt1:
  7230. #ifndef OPENGLES
  7231. if (Texture::has_alpha(format)) {
  7232. return GL_COMPRESSED_RGBA_FXT1_3DFX;
  7233. } else {
  7234. return GL_COMPRESSED_RGB_FXT1_3DFX;
  7235. }
  7236. #endif
  7237. break;
  7238. #ifdef OPENGLES
  7239. case Texture::CM_pvr1_2bpp:
  7240. if (Texture::has_alpha(format)) {
  7241. return GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG;
  7242. } else {
  7243. return GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG;
  7244. }
  7245. case Texture::CM_pvr1_4bpp:
  7246. if (Texture::has_alpha(format)) {
  7247. return GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG;
  7248. } else {
  7249. return GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG;
  7250. }
  7251. #else
  7252. case Texture::CM_pvr1_2bpp:
  7253. case Texture::CM_pvr1_4bpp:
  7254. break;
  7255. #endif
  7256. case Texture::CM_default:
  7257. case Texture::CM_off:
  7258. case Texture::CM_dxt2:
  7259. case Texture::CM_dxt4:
  7260. // No compression: fall through to below.
  7261. break;
  7262. }
  7263. }
  7264. switch (format) {
  7265. #ifndef OPENGLES
  7266. case Texture::F_color_index:
  7267. return GL_COLOR_INDEX;
  7268. #endif
  7269. case Texture::F_depth_stencil:
  7270. if (_supports_depth_stencil) {
  7271. #ifndef OPENGLES
  7272. if (tex->get_component_type() == Texture::T_float) {
  7273. return GL_DEPTH32F_STENCIL8;
  7274. } else
  7275. #endif
  7276. {
  7277. return force_sized ? GL_DEPTH24_STENCIL8 : GL_DEPTH_STENCIL;
  7278. }
  7279. }
  7280. // Fall through.
  7281. case Texture::F_depth_component:
  7282. #ifndef OPENGLES
  7283. if (tex->get_component_type() == Texture::T_float) {
  7284. return GL_DEPTH_COMPONENT32F;
  7285. } else
  7286. #endif
  7287. {
  7288. return force_sized ? GL_DEPTH_COMPONENT16 : GL_DEPTH_COMPONENT;
  7289. }
  7290. case Texture::F_depth_component16:
  7291. #ifdef OPENGLES
  7292. return GL_DEPTH_COMPONENT16_OES;
  7293. #else
  7294. return GL_DEPTH_COMPONENT16;
  7295. #endif
  7296. case Texture::F_depth_component24:
  7297. #ifdef OPENGLES
  7298. if (_supports_depth24) {
  7299. return GL_DEPTH_COMPONENT24_OES;
  7300. } else {
  7301. return GL_DEPTH_COMPONENT16_OES;
  7302. }
  7303. #else
  7304. return GL_DEPTH_COMPONENT24;
  7305. #endif
  7306. case Texture::F_depth_component32:
  7307. #ifdef OPENGLES
  7308. if (_supports_depth32) {
  7309. return GL_DEPTH_COMPONENT32_OES;
  7310. } else if (_supports_depth24) {
  7311. return GL_DEPTH_COMPONENT24_OES;
  7312. } else {
  7313. return GL_DEPTH_COMPONENT16_OES;
  7314. }
  7315. #else
  7316. if (tex->get_component_type() == Texture::T_float) {
  7317. return GL_DEPTH_COMPONENT32F;
  7318. } else {
  7319. return GL_DEPTH_COMPONENT32;
  7320. }
  7321. #endif
  7322. case Texture::F_rgba:
  7323. case Texture::F_rgbm:
  7324. #ifndef OPENGLES_1
  7325. if (tex->get_component_type() == Texture::T_float) {
  7326. return GL_RGBA16F;
  7327. } else
  7328. #endif
  7329. #ifndef OPENGLES
  7330. if (tex->get_component_type() == Texture::T_unsigned_short) {
  7331. return GL_RGBA16;
  7332. } else
  7333. #endif
  7334. {
  7335. return force_sized ? GL_RGBA8 : GL_RGBA;
  7336. }
  7337. case Texture::F_rgba4:
  7338. return GL_RGBA4;
  7339. #ifdef OPENGLES
  7340. case Texture::F_rgba8:
  7341. return GL_RGBA8_OES;
  7342. case Texture::F_rgba12:
  7343. return force_sized ? GL_RGBA8 : GL_RGBA;
  7344. #else
  7345. case Texture::F_rgba8:
  7346. return GL_RGBA8;
  7347. case Texture::F_r8i:
  7348. if (tex->get_component_type() == Texture::T_unsigned_byte) {
  7349. return GL_R8UI;
  7350. } else {
  7351. return GL_R8I;
  7352. }
  7353. case Texture::F_rg8i:
  7354. if (tex->get_component_type() == Texture::T_unsigned_byte) {
  7355. return GL_RG8UI;
  7356. } else {
  7357. return GL_RG8I;
  7358. }
  7359. case Texture::F_rgb8i:
  7360. if (tex->get_component_type() == Texture::T_unsigned_byte) {
  7361. return GL_RGB8UI;
  7362. } else {
  7363. return GL_RGB8I;
  7364. }
  7365. case Texture::F_rgba8i:
  7366. if (tex->get_component_type() == Texture::T_unsigned_byte) {
  7367. return GL_RGBA8UI;
  7368. } else {
  7369. return GL_RGBA8I;
  7370. }
  7371. case Texture::F_rgba12:
  7372. return GL_RGBA12;
  7373. #endif // OPENGLES
  7374. #ifndef OPENGLES
  7375. case Texture::F_rgba16:
  7376. if (tex->get_component_type() == Texture::T_float) {
  7377. return GL_RGBA16F;
  7378. } else {
  7379. return GL_RGBA16;
  7380. }
  7381. case Texture::F_rgba32:
  7382. return GL_RGBA32F;
  7383. #endif // OPENGLES
  7384. case Texture::F_rgb:
  7385. if (tex->get_component_type() == Texture::T_float) {
  7386. return GL_RGB16F;
  7387. } else {
  7388. return force_sized ? GL_RGB8 : GL_RGB;
  7389. }
  7390. case Texture::F_rgb5:
  7391. #ifdef OPENGLES
  7392. // Close enough.
  7393. return GL_RGB565_OES;
  7394. #else
  7395. return GL_RGB5;
  7396. #endif
  7397. case Texture::F_rgba5:
  7398. return GL_RGB5_A1;
  7399. #ifdef OPENGLES
  7400. case Texture::F_rgb8:
  7401. return GL_RGB8_OES;
  7402. case Texture::F_rgb12:
  7403. return force_sized ? GL_RGB8 : GL_RGB;
  7404. case Texture::F_rgb16:
  7405. return GL_RGB16F;
  7406. #else
  7407. case Texture::F_rgb8:
  7408. return GL_RGB8;
  7409. case Texture::F_rgb12:
  7410. return GL_RGB12;
  7411. case Texture::F_rgb16:
  7412. if (tex->get_component_type() == Texture::T_float) {
  7413. return GL_RGB16F;
  7414. } else {
  7415. return GL_RGB16;
  7416. }
  7417. #endif // OPENGLES
  7418. case Texture::F_rgb32:
  7419. return GL_RGB32F;
  7420. #ifndef OPENGLES
  7421. case Texture::F_rgb332:
  7422. return GL_R3_G3_B2;
  7423. #endif
  7424. #if defined(OPENGLES_2)
  7425. case Texture::F_r16:
  7426. return GL_R16F_EXT;
  7427. case Texture::F_rg16:
  7428. return GL_RG16F_EXT;
  7429. #elif !defined(OPENGLES_1)
  7430. case Texture::F_r16:
  7431. if (tex->get_component_type() == Texture::T_float) {
  7432. return GL_R16F;
  7433. } else {
  7434. return GL_R16;
  7435. }
  7436. case Texture::F_rg16:
  7437. if (tex->get_component_type() == Texture::T_float) {
  7438. return GL_RG16F;
  7439. } else {
  7440. return GL_RG16;
  7441. }
  7442. #endif
  7443. #ifndef OPENGLES_1
  7444. case Texture::F_r32:
  7445. return GL_R32F;
  7446. case Texture::F_rg32:
  7447. return GL_RG32F;
  7448. case Texture::F_red:
  7449. case Texture::F_green:
  7450. case Texture::F_blue:
  7451. return force_sized ? GL_R8 : GL_RED;
  7452. #endif
  7453. case Texture::F_alpha:
  7454. #ifdef SUPPORT_FIXED_FUNCTION
  7455. return force_sized ? GL_ALPHA8 : GL_ALPHA;
  7456. #else
  7457. return force_sized ? GL_R8 : GL_RED;
  7458. #endif
  7459. case Texture::F_luminance:
  7460. #ifndef OPENGLES
  7461. if (tex->get_component_type() == Texture::T_float) {
  7462. return GL_LUMINANCE16F_ARB;
  7463. } else if (tex->get_component_type() == Texture::T_unsigned_short) {
  7464. return GL_LUMINANCE16;
  7465. } else
  7466. #endif // OPENGLES
  7467. {
  7468. return force_sized ? GL_LUMINANCE8 : GL_LUMINANCE;
  7469. }
  7470. case Texture::F_luminance_alpha:
  7471. case Texture::F_luminance_alphamask:
  7472. #ifndef OPENGLES
  7473. if (tex->get_component_type() == Texture::T_float || tex->get_component_type() == Texture::T_unsigned_short) {
  7474. return GL_LUMINANCE_ALPHA16F_ARB;
  7475. } else
  7476. #endif // OPENGLES
  7477. {
  7478. return force_sized ? GL_LUMINANCE8_ALPHA8 : GL_LUMINANCE_ALPHA;
  7479. }
  7480. #ifndef OPENGLES_1
  7481. case Texture::F_srgb:
  7482. #ifndef OPENGLES
  7483. return GL_SRGB8;
  7484. #endif
  7485. case Texture::F_srgb_alpha:
  7486. return GL_SRGB8_ALPHA8;
  7487. #endif
  7488. #ifndef OPENGLES
  7489. case Texture::F_sluminance:
  7490. return GL_SLUMINANCE8;
  7491. case Texture::F_sluminance_alpha:
  7492. return GL_SLUMINANCE8_ALPHA8;
  7493. #endif
  7494. #ifndef OPENGLES
  7495. case Texture::F_r32i:
  7496. return GL_R32I;
  7497. #endif
  7498. default:
  7499. GLCAT.error()
  7500. << "Invalid image format in get_internal_image_format(): "
  7501. << (int)tex->get_format() << "\n";
  7502. return force_sized ? GL_RGB8 : GL_RGB;
  7503. }
  7504. }
  7505. ////////////////////////////////////////////////////////////////////
  7506. // Function: GLGraphicsStateGuardian::is_mipmap_filter
  7507. // Access: Protected, Static
  7508. // Description: Returns true if the indicated GL minfilter type
  7509. // represents a mipmap format, false otherwise.
  7510. ////////////////////////////////////////////////////////////////////
  7511. bool CLP(GraphicsStateGuardian)::
  7512. is_mipmap_filter(GLenum min_filter) {
  7513. switch (min_filter) {
  7514. case GL_NEAREST_MIPMAP_NEAREST:
  7515. case GL_LINEAR_MIPMAP_NEAREST:
  7516. case GL_NEAREST_MIPMAP_LINEAR:
  7517. case GL_LINEAR_MIPMAP_LINEAR:
  7518. return true;
  7519. default:
  7520. return false;
  7521. }
  7522. }
  7523. ////////////////////////////////////////////////////////////////////
  7524. // Function: GLGraphicsStateGuardian::is_compressed_format
  7525. // Access: Protected, Static
  7526. // Description: Returns true if the indicated GL internal format
  7527. // represents a compressed texture format, false
  7528. // otherwise.
  7529. ////////////////////////////////////////////////////////////////////
  7530. bool CLP(GraphicsStateGuardian)::
  7531. is_compressed_format(GLenum format) {
  7532. switch (format) {
  7533. case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  7534. case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  7535. #ifdef OPENGLES
  7536. case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
  7537. case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
  7538. case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
  7539. case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
  7540. #else
  7541. case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
  7542. case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
  7543. case GL_COMPRESSED_RGB_FXT1_3DFX:
  7544. case GL_COMPRESSED_RGBA_FXT1_3DFX:
  7545. case GL_COMPRESSED_RGB:
  7546. case GL_COMPRESSED_RGBA:
  7547. case GL_COMPRESSED_ALPHA:
  7548. case GL_COMPRESSED_LUMINANCE:
  7549. case GL_COMPRESSED_LUMINANCE_ALPHA:
  7550. #endif
  7551. return true;
  7552. default:
  7553. return false;
  7554. }
  7555. }
  7556. ////////////////////////////////////////////////////////////////////
  7557. // Function: GLGraphicsStateGuardian::get_texture_apply_mode_type
  7558. // Access: Protected, Static
  7559. // Description: Maps from the texture stage's mode types
  7560. // to the corresponding OpenGL ids
  7561. ////////////////////////////////////////////////////////////////////
  7562. GLint CLP(GraphicsStateGuardian)::
  7563. get_texture_apply_mode_type(TextureStage::Mode am) {
  7564. #ifdef SUPPORT_FIXED_FUNCTION
  7565. switch (am) {
  7566. case TextureStage::M_modulate: return GL_MODULATE;
  7567. case TextureStage::M_decal: return GL_DECAL;
  7568. case TextureStage::M_blend: return GL_BLEND;
  7569. case TextureStage::M_replace: return GL_REPLACE;
  7570. case TextureStage::M_add: return GL_ADD;
  7571. case TextureStage::M_combine: return GL_COMBINE;
  7572. case TextureStage::M_blend_color_scale: return GL_BLEND;
  7573. case TextureStage::M_modulate_glow: return GL_MODULATE;
  7574. case TextureStage::M_modulate_gloss: return GL_MODULATE;
  7575. default:
  7576. // Other modes shouldn't get here. Fall through and error.
  7577. break;
  7578. }
  7579. GLCAT.error()
  7580. << "Invalid TextureStage::Mode value" << endl;
  7581. return GL_MODULATE;
  7582. #else
  7583. return 0;
  7584. #endif
  7585. }
  7586. ////////////////////////////////////////////////////////////////////
  7587. // Function: GLGraphicsStateGuardian::get_texture_combine_type
  7588. // Access: Protected, Static
  7589. // Description: Maps from the texture stage's CombineMode types
  7590. // to the corresponding OpenGL ids
  7591. ////////////////////////////////////////////////////////////////////
  7592. GLint CLP(GraphicsStateGuardian)::
  7593. get_texture_combine_type(TextureStage::CombineMode cm) {
  7594. #ifdef SUPPORT_FIXED_FUNCTION
  7595. switch (cm) {
  7596. case TextureStage::CM_undefined: // fall through
  7597. case TextureStage::CM_replace: return GL_REPLACE;
  7598. case TextureStage::CM_modulate: return GL_MODULATE;
  7599. case TextureStage::CM_add: return GL_ADD;
  7600. case TextureStage::CM_add_signed: return GL_ADD_SIGNED;
  7601. case TextureStage::CM_interpolate: return GL_INTERPOLATE;
  7602. case TextureStage::CM_subtract: return GL_SUBTRACT;
  7603. case TextureStage::CM_dot3_rgb: return GL_DOT3_RGB;
  7604. case TextureStage::CM_dot3_rgba: return GL_DOT3_RGBA;
  7605. }
  7606. GLCAT.error()
  7607. << "Invalid TextureStage::CombineMode value" << endl;
  7608. #endif
  7609. return GL_REPLACE;
  7610. }
  7611. ////////////////////////////////////////////////////////////////////
  7612. // Function: GLGraphicsStateGuardian::get_texture_src_type
  7613. // Access: Protected
  7614. // Description: Maps from the texture stage's CombineSource types
  7615. // to the corresponding OpenGL ids
  7616. ////////////////////////////////////////////////////////////////////
  7617. GLint CLP(GraphicsStateGuardian)::
  7618. get_texture_src_type(TextureStage::CombineSource cs,
  7619. int last_stage, int last_saved_result,
  7620. int this_stage) const {
  7621. #ifdef SUPPORT_FIXED_FUNCTION
  7622. switch (cs) {
  7623. case TextureStage::CS_undefined: // fall through
  7624. case TextureStage::CS_texture: return GL_TEXTURE;
  7625. case TextureStage::CS_constant: return GL_CONSTANT;
  7626. case TextureStage::CS_primary_color: return GL_PRIMARY_COLOR;
  7627. case TextureStage::CS_constant_color_scale: return GL_CONSTANT;
  7628. case TextureStage::CS_previous:
  7629. if (last_stage == this_stage - 1) {
  7630. return GL_PREVIOUS;
  7631. } else if (last_stage == -1) {
  7632. return GL_PRIMARY_COLOR;
  7633. } else if (_supports_texture_saved_result) {
  7634. return GL_TEXTURE0 + last_stage;
  7635. } else {
  7636. GLCAT.warning()
  7637. << "Current OpenGL driver does not support texture crossbar blending.\n";
  7638. return GL_PRIMARY_COLOR;
  7639. }
  7640. case TextureStage::CS_last_saved_result:
  7641. if (last_saved_result == this_stage - 1) {
  7642. return GL_PREVIOUS;
  7643. } else if (last_saved_result == -1) {
  7644. return GL_PRIMARY_COLOR;
  7645. } else if (_supports_texture_saved_result) {
  7646. return GL_TEXTURE0 + last_saved_result;
  7647. } else {
  7648. GLCAT.warning()
  7649. << "Current OpenGL driver does not support texture crossbar blending.\n";
  7650. return GL_PRIMARY_COLOR;
  7651. }
  7652. }
  7653. GLCAT.error()
  7654. << "Invalid TextureStage::CombineSource value" << endl;
  7655. #endif
  7656. return GL_TEXTURE;
  7657. }
  7658. ////////////////////////////////////////////////////////////////////
  7659. // Function: GLGraphicsStateGuardian::get_texture_operand_type
  7660. // Access: Protected, Static
  7661. // Description: Maps from the texture stage's CombineOperand types
  7662. // to the corresponding OpenGL ids
  7663. ////////////////////////////////////////////////////////////////////
  7664. GLint CLP(GraphicsStateGuardian)::
  7665. get_texture_operand_type(TextureStage::CombineOperand co) {
  7666. switch (co) {
  7667. case TextureStage::CO_undefined: // fall through
  7668. case TextureStage::CO_src_alpha: return GL_SRC_ALPHA;
  7669. case TextureStage::CO_one_minus_src_alpha: return GL_ONE_MINUS_SRC_ALPHA;
  7670. case TextureStage::CO_src_color: return GL_SRC_COLOR;
  7671. case TextureStage::CO_one_minus_src_color: return GL_ONE_MINUS_SRC_COLOR;
  7672. }
  7673. GLCAT.error()
  7674. << "Invalid TextureStage::CombineOperand value" << endl;
  7675. return GL_SRC_COLOR;
  7676. }
  7677. #ifdef SUPPORT_FIXED_FUNCTION
  7678. ////////////////////////////////////////////////////////////////////
  7679. // Function: GLGraphicsStateGuardian::get_fog_mode_type
  7680. // Access: Protected, Static
  7681. // Description: Maps from the fog types to gl version
  7682. ////////////////////////////////////////////////////////////////////
  7683. GLenum CLP(GraphicsStateGuardian)::
  7684. get_fog_mode_type(Fog::Mode m) {
  7685. switch(m) {
  7686. case Fog::M_linear: return GL_LINEAR;
  7687. case Fog::M_exponential: return GL_EXP;
  7688. case Fog::M_exponential_squared: return GL_EXP2;
  7689. /*
  7690. case Fog::M_spline: return GL_FOG_FUNC_SGIS;
  7691. */
  7692. default:
  7693. GLCAT.error() << "Invalid Fog::Mode value" << endl;
  7694. return GL_EXP;
  7695. }
  7696. }
  7697. #endif
  7698. ////////////////////////////////////////////////////////////////////
  7699. // Function: GLGraphicsStateGuardian::get_blend_equation_type
  7700. // Access: Protected, Static
  7701. // Description: Maps from ColorBlendAttrib::Mode to glBlendEquation
  7702. // value.
  7703. ////////////////////////////////////////////////////////////////////
  7704. GLenum CLP(GraphicsStateGuardian)::
  7705. get_blend_equation_type(ColorBlendAttrib::Mode mode) {
  7706. switch (mode) {
  7707. case ColorBlendAttrib::M_none:
  7708. case ColorBlendAttrib::M_add:
  7709. return GL_FUNC_ADD;
  7710. case ColorBlendAttrib::M_subtract:
  7711. return GL_FUNC_SUBTRACT;
  7712. case ColorBlendAttrib::M_inv_subtract:
  7713. return GL_FUNC_REVERSE_SUBTRACT;
  7714. #ifdef OPENGLES
  7715. case ColorBlendAttrib::M_min:
  7716. return GL_MIN_EXT;
  7717. case ColorBlendAttrib::M_max:
  7718. return GL_MAX_EXT;
  7719. #else
  7720. case ColorBlendAttrib::M_min:
  7721. return GL_MIN;
  7722. case ColorBlendAttrib::M_max:
  7723. return GL_MAX;
  7724. #endif
  7725. }
  7726. GLCAT.error()
  7727. << "Unknown color blend mode " << (int)mode << endl;
  7728. return GL_FUNC_ADD;
  7729. }
  7730. ////////////////////////////////////////////////////////////////////
  7731. // Function: GLGraphicsStateGuardian::get_blend_func
  7732. // Access: Protected, Static
  7733. // Description: Maps from ColorBlendAttrib::Operand to glBlendFunc
  7734. // value.
  7735. ////////////////////////////////////////////////////////////////////
  7736. GLenum CLP(GraphicsStateGuardian)::
  7737. get_blend_func(ColorBlendAttrib::Operand operand) {
  7738. switch (operand) {
  7739. case ColorBlendAttrib::O_zero:
  7740. return GL_ZERO;
  7741. case ColorBlendAttrib::O_one:
  7742. return GL_ONE;
  7743. case ColorBlendAttrib::O_incoming_color:
  7744. return GL_SRC_COLOR;
  7745. case ColorBlendAttrib::O_one_minus_incoming_color:
  7746. return GL_ONE_MINUS_SRC_COLOR;
  7747. case ColorBlendAttrib::O_fbuffer_color:
  7748. return GL_DST_COLOR;
  7749. case ColorBlendAttrib::O_one_minus_fbuffer_color:
  7750. return GL_ONE_MINUS_DST_COLOR;
  7751. case ColorBlendAttrib::O_incoming_alpha:
  7752. return GL_SRC_ALPHA;
  7753. case ColorBlendAttrib::O_one_minus_incoming_alpha:
  7754. return GL_ONE_MINUS_SRC_ALPHA;
  7755. case ColorBlendAttrib::O_fbuffer_alpha:
  7756. return GL_DST_ALPHA;
  7757. case ColorBlendAttrib::O_one_minus_fbuffer_alpha:
  7758. return GL_ONE_MINUS_DST_ALPHA;
  7759. #ifdef OPENGLES_1
  7760. // OpenGL ES 1 has no constant blend factor.
  7761. case ColorBlendAttrib::O_constant_color:
  7762. case ColorBlendAttrib::O_color_scale:
  7763. case ColorBlendAttrib::O_one_minus_constant_color:
  7764. case ColorBlendAttrib::O_one_minus_color_scale:
  7765. case ColorBlendAttrib::O_constant_alpha:
  7766. case ColorBlendAttrib::O_alpha_scale:
  7767. case ColorBlendAttrib::O_one_minus_constant_alpha:
  7768. case ColorBlendAttrib::O_one_minus_alpha_scale:
  7769. break;
  7770. #else
  7771. case ColorBlendAttrib::O_constant_color:
  7772. case ColorBlendAttrib::O_color_scale:
  7773. return GL_CONSTANT_COLOR;
  7774. case ColorBlendAttrib::O_one_minus_constant_color:
  7775. case ColorBlendAttrib::O_one_minus_color_scale:
  7776. return GL_ONE_MINUS_CONSTANT_COLOR;
  7777. case ColorBlendAttrib::O_constant_alpha:
  7778. case ColorBlendAttrib::O_alpha_scale:
  7779. return GL_CONSTANT_ALPHA;
  7780. case ColorBlendAttrib::O_one_minus_constant_alpha:
  7781. case ColorBlendAttrib::O_one_minus_alpha_scale:
  7782. return GL_ONE_MINUS_CONSTANT_ALPHA;
  7783. #endif
  7784. case ColorBlendAttrib::O_incoming_color_saturate:
  7785. return GL_SRC_ALPHA_SATURATE;
  7786. }
  7787. GLCAT.error()
  7788. << "Unknown color blend operand " << (int)operand << endl;
  7789. return GL_ZERO;
  7790. }
  7791. ////////////////////////////////////////////////////////////////////
  7792. // Function: GLGraphicsStateGuardian::get_usage
  7793. // Access: Public, Static
  7794. // Description: Maps from UsageHint to the GL symbol.
  7795. ////////////////////////////////////////////////////////////////////
  7796. GLenum CLP(GraphicsStateGuardian)::
  7797. get_usage(Geom::UsageHint usage_hint) {
  7798. switch (usage_hint) {
  7799. case Geom::UH_stream:
  7800. #ifdef OPENGLES
  7801. return GL_DYNAMIC_DRAW;
  7802. #else
  7803. return GL_STREAM_DRAW;
  7804. #endif // OPENGLES
  7805. case Geom::UH_static:
  7806. case Geom::UH_unspecified:
  7807. return GL_STATIC_DRAW;
  7808. case Geom::UH_dynamic:
  7809. return GL_DYNAMIC_DRAW;
  7810. case Geom::UH_client:
  7811. break;
  7812. }
  7813. GLCAT.error()
  7814. << "Unexpected usage_hint " << (int)usage_hint << endl;
  7815. return GL_STATIC_DRAW;
  7816. }
  7817. ////////////////////////////////////////////////////////////////////
  7818. // Function: GLGraphicsStateGuardian::get_compressed_format_string
  7819. // Access: Public, Static
  7820. // Description: Returns a string describing an compression format.
  7821. ////////////////////////////////////////////////////////////////////
  7822. const char *CLP(GraphicsStateGuardian)::
  7823. get_compressed_format_string(GLenum format) {
  7824. switch (format) {
  7825. case 0x83F0: return "GL_COMPRESSED_RGB_S3TC_DXT1_EXT";
  7826. case 0x83F1: return "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT";
  7827. case 0x83F2: return "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT";
  7828. case 0x83F3: return "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT";
  7829. case 0x86B0: return "GL_COMPRESSED_RGB_FXT1_3DFX";
  7830. case 0x86B1: return "GL_COMPRESSED_RGBA_FXT1_3DFX";
  7831. case 0x8A54: return "GL_COMPRESSED_SRGB_PVRTC_2BPPV1_EXT";
  7832. case 0x8A55: return "GL_COMPRESSED_SRGB_PVRTC_4BPPV1_EXT";
  7833. case 0x8A56: return "GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV1_EXT";
  7834. case 0x8A57: return "GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV1_EXT";
  7835. case 0x8B90: return "GL_PALETTE4_RGB8_OES";
  7836. case 0x8B91: return "GL_PALETTE4_RGBA8_OES";
  7837. case 0x8B92: return "GL_PALETTE4_R5_G6_B5_OES";
  7838. case 0x8B93: return "GL_PALETTE4_RGBA4_OES";
  7839. case 0x8B94: return "GL_PALETTE4_RGB5_A1_OES";
  7840. case 0x8B95: return "GL_PALETTE8_RGB8_OES";
  7841. case 0x8B96: return "GL_PALETTE8_RGBA8_OES";
  7842. case 0x8B97: return "GL_PALETTE8_R5_G6_B5_OES";
  7843. case 0x8B98: return "GL_PALETTE8_RGBA4_OES";
  7844. case 0x8B99: return "GL_PALETTE8_RGB5_A1_OES";
  7845. case 0x8C00: return "GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG";
  7846. case 0x8C01: return "GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG";
  7847. case 0x8C02: return "GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG";
  7848. case 0x8C03: return "GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG";
  7849. case 0x8C48: return "GL_COMPRESSED_SRGB_EXT";
  7850. case 0x8C49: return "GL_COMPRESSED_SRGB_ALPHA_EXT";
  7851. case 0x8C4A: return "GL_COMPRESSED_SLUMINANCE_EXT";
  7852. case 0x8C4B: return "GL_COMPRESSED_SLUMINANCE_ALPHA_EXT";
  7853. case 0x8C4C: return "GL_COMPRESSED_SRGB_S3TC_DXT1_EXT";
  7854. case 0x8C4D: return "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT";
  7855. case 0x8C4E: return "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT";
  7856. case 0x8C4F: return "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT";
  7857. case 0x8C70: return "GL_COMPRESSED_LUMINANCE_LATC1_EXT";
  7858. case 0x8C71: return "GL_COMPRESSED_SIGNED_LUMINANCE_LATC1_EXT";
  7859. case 0x8C72: return "GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT";
  7860. case 0x8C73: return "GL_COMPRESSED_SIGNED_LUMINANCE_ALPHA_LATC2_EXT";
  7861. case 0x8DBB: return "GL_COMPRESSED_RED_RGTC1";
  7862. case 0x8DBC: return "GL_COMPRESSED_SIGNED_RED_RGTC1";
  7863. case 0x8DBD: return "GL_COMPRESSED_RG_RGTC2";
  7864. case 0x8DBE: return "GL_COMPRESSED_SIGNED_RG_RGTC2";
  7865. case 0x8E8C: return "GL_COMPRESSED_RGBA_BPTC_UNORM";
  7866. case 0x8E8D: return "GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM";
  7867. case 0x8E8E: return "GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT";
  7868. case 0x8E8F: return "GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT";
  7869. case 0x9137: return "GL_COMPRESSED_RGBA_PVRTC_2BPPV2_IMG";
  7870. case 0x9138: return "GL_COMPRESSED_RGBA_PVRTC_4BPPV2_IMG";
  7871. case 0x9270: return "GL_COMPRESSED_R11_EAC";
  7872. case 0x9271: return "GL_COMPRESSED_SIGNED_R11_EAC";
  7873. case 0x9272: return "GL_COMPRESSED_RG11_EAC";
  7874. case 0x9273: return "GL_COMPRESSED_SIGNED_RG11_EAC";
  7875. case 0x9274: return "GL_COMPRESSED_RGB8_ETC2";
  7876. case 0x9275: return "GL_COMPRESSED_SRGB8_ETC2";
  7877. case 0x9276: return "GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2";
  7878. case 0x9277: return "GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2";
  7879. case 0x9278: return "GL_COMPRESSED_RGBA8_ETC2_EAC";
  7880. case 0x9279: return "GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC";
  7881. case 0x93B0: return "GL_COMPRESSED_RGBA_ASTC_4x4_KHR";
  7882. case 0x93B1: return "GL_COMPRESSED_RGBA_ASTC_5x4_KHR";
  7883. case 0x93B2: return "GL_COMPRESSED_RGBA_ASTC_5x5_KHR";
  7884. case 0x93B3: return "GL_COMPRESSED_RGBA_ASTC_6x5_KHR";
  7885. case 0x93B4: return "GL_COMPRESSED_RGBA_ASTC_6x6_KHR";
  7886. case 0x93B5: return "GL_COMPRESSED_RGBA_ASTC_8x5_KHR";
  7887. case 0x93B6: return "GL_COMPRESSED_RGBA_ASTC_8x6_KHR";
  7888. case 0x93B7: return "GL_COMPRESSED_RGBA_ASTC_8x8_KHR";
  7889. case 0x93B8: return "GL_COMPRESSED_RGBA_ASTC_10x5_KHR";
  7890. case 0x93B9: return "GL_COMPRESSED_RGBA_ASTC_10x6_KHR";
  7891. case 0x93BA: return "GL_COMPRESSED_RGBA_ASTC_10x8_KHR";
  7892. case 0x93BB: return "GL_COMPRESSED_RGBA_ASTC_10x10_KHR";
  7893. case 0x93BC: return "GL_COMPRESSED_RGBA_ASTC_12x10_KHR";
  7894. case 0x93BD: return "GL_COMPRESSED_RGBA_ASTC_12x12_KHR";
  7895. case 0x93C0: return "GL_COMPRESSED_RGBA_ASTC_3x3x3_OES";
  7896. case 0x93C1: return "GL_COMPRESSED_RGBA_ASTC_4x3x3_OES";
  7897. case 0x93C2: return "GL_COMPRESSED_RGBA_ASTC_4x4x3_OES";
  7898. case 0x93C3: return "GL_COMPRESSED_RGBA_ASTC_4x4x4_OES";
  7899. case 0x93C4: return "GL_COMPRESSED_RGBA_ASTC_5x4x4_OES";
  7900. case 0x93C5: return "GL_COMPRESSED_RGBA_ASTC_5x5x4_OES";
  7901. case 0x93C6: return "GL_COMPRESSED_RGBA_ASTC_5x5x5_OES";
  7902. case 0x93C7: return "GL_COMPRESSED_RGBA_ASTC_6x5x5_OES";
  7903. case 0x93C8: return "GL_COMPRESSED_RGBA_ASTC_6x6x5_OES";
  7904. case 0x93C9: return "GL_COMPRESSED_RGBA_ASTC_6x6x6_OES";
  7905. case 0x93D0: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR";
  7906. case 0x93D1: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR";
  7907. case 0x93D2: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR";
  7908. case 0x93D3: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR";
  7909. case 0x93D4: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR";
  7910. case 0x93D5: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR";
  7911. case 0x93D6: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR";
  7912. case 0x93D7: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR";
  7913. case 0x93D8: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR";
  7914. case 0x93D9: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR";
  7915. case 0x93DA: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR";
  7916. case 0x93DB: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR";
  7917. case 0x93DC: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR";
  7918. case 0x93DD: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR";
  7919. case 0x93E0: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES";
  7920. case 0x93E1: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES";
  7921. case 0x93E2: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES";
  7922. case 0x93E3: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES";
  7923. case 0x93E4: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES";
  7924. case 0x93E5: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES";
  7925. case 0x93E6: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES";
  7926. case 0x93E7: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES";
  7927. case 0x93E8: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES";
  7928. case 0x93E9: return "GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES";
  7929. case 0x93F0: return "GL_COMPRESSED_SRGB_ALPHA_PVRTC_2BPPV2_IMG";
  7930. case 0x93F1: return "GL_COMPRESSED_SRGB_ALPHA_PVRTC_4BPPV2_IMG";
  7931. default:
  7932. return NULL;
  7933. }
  7934. }
  7935. ////////////////////////////////////////////////////////////////////
  7936. // Function: GLGraphicsStateGuardian::get_light_color
  7937. // Access: Public
  7938. // Description: Returns the value that that should be issued as the
  7939. // light's color, as scaled by the current value of
  7940. // _light_color_scale, in the case of
  7941. // color_scale_via_lighting.
  7942. ////////////////////////////////////////////////////////////////////
  7943. LVecBase4 CLP(GraphicsStateGuardian)::
  7944. get_light_color(Light *light) const {
  7945. #ifndef NDEBUG
  7946. if (_show_texture_usage) {
  7947. // In show_texture_usage mode, all lights are white, so as not to
  7948. // contaminate the texture color.
  7949. return LVecBase4(1.0, 1.0, 1.0, 1.0);
  7950. }
  7951. #endif // NDEBUG
  7952. const LColor &c = light->get_color();
  7953. LVecBase4 light_color(c[0] * _light_color_scale[0],
  7954. c[1] * _light_color_scale[1],
  7955. c[2] * _light_color_scale[2],
  7956. c[3] * _light_color_scale[3]);
  7957. return light_color;
  7958. }
  7959. ////////////////////////////////////////////////////////////////////
  7960. // Function: GLGraphicsStateGuardian::reissue_transforms
  7961. // Access: Protected, Virtual
  7962. // Description: Called by clear_state_and_transform() to ensure that
  7963. // the current modelview and projection matrices are
  7964. // properly loaded in the graphics state, after a
  7965. // callback might have mucked them up.
  7966. ////////////////////////////////////////////////////////////////////
  7967. void CLP(GraphicsStateGuardian)::
  7968. reissue_transforms() {
  7969. prepare_lens();
  7970. do_issue_transform();
  7971. }
  7972. #ifdef SUPPORT_FIXED_FUNCTION
  7973. ////////////////////////////////////////////////////////////////////
  7974. // Function: GLGraphicsStateGuardian::enable_lighting
  7975. // Access: Protected, Virtual
  7976. // Description: Intended to be overridden by a derived class to
  7977. // enable or disable the use of lighting overall. This
  7978. // is called by do_issue_light() according to whether any
  7979. // lights are in use or not.
  7980. ////////////////////////////////////////////////////////////////////
  7981. void CLP(GraphicsStateGuardian)::
  7982. enable_lighting(bool enable) {
  7983. // static PStatCollector _draw_set_state_light_enable_lighting_pcollector("Draw:Set State:Light:Enable lighting");
  7984. // PStatGPUTimer timer(this, _draw_set_state_light_enable_lighting_pcollector);
  7985. if (enable) {
  7986. glEnable(GL_LIGHTING);
  7987. } else {
  7988. glDisable(GL_LIGHTING);
  7989. }
  7990. }
  7991. #endif // SUPPORT_FIXED_FUNCTION
  7992. #ifdef SUPPORT_FIXED_FUNCTION
  7993. ////////////////////////////////////////////////////////////////////
  7994. // Function: GLGraphicsStateGuardian::set_ambient_light
  7995. // Access: Protected, Virtual
  7996. // Description: Intended to be overridden by a derived class to
  7997. // indicate the color of the ambient light that should
  7998. // be in effect. This is called by do_issue_light() after
  7999. // all other lights have been enabled or disabled.
  8000. ////////////////////////////////////////////////////////////////////
  8001. void CLP(GraphicsStateGuardian)::
  8002. set_ambient_light(const LColor &color) {
  8003. // static PStatCollector _draw_set_state_light_ambient_pcollector("Draw:Set State:Light:Ambient");
  8004. // PStatGPUTimer timer(this, _draw_set_state_light_ambient_pcollector);
  8005. LColor c = color;
  8006. c.set(c[0] * _light_color_scale[0],
  8007. c[1] * _light_color_scale[1],
  8008. c[2] * _light_color_scale[2],
  8009. c[3] * _light_color_scale[3]);
  8010. call_glLightModelfv(GL_LIGHT_MODEL_AMBIENT, c);
  8011. }
  8012. #endif // SUPPORT_FIXED_FUNCTION
  8013. #ifdef SUPPORT_FIXED_FUNCTION
  8014. ////////////////////////////////////////////////////////////////////
  8015. // Function: GLGraphicsStateGuardian::enable_light
  8016. // Access: Protected, Virtual
  8017. // Description: Intended to be overridden by a derived class to
  8018. // enable the indicated light id. A specific Light will
  8019. // already have been bound to this id via bind_light().
  8020. ////////////////////////////////////////////////////////////////////
  8021. void CLP(GraphicsStateGuardian)::
  8022. enable_light(int light_id, bool enable) {
  8023. // static PStatCollector _draw_set_state_light_enable_light_pcollector("Draw:Set State:Light:Enable light");
  8024. // PStatGPUTimer timer(this, _draw_set_state_light_enable_light_pcollector);
  8025. if (enable) {
  8026. glEnable(get_light_id(light_id));
  8027. } else {
  8028. glDisable(get_light_id(light_id));
  8029. }
  8030. }
  8031. #endif // SUPPORT_FIXED_FUNCTION
  8032. #ifdef SUPPORT_FIXED_FUNCTION
  8033. ////////////////////////////////////////////////////////////////////
  8034. // Function: GLGraphicsStateGuardian::begin_bind_lights
  8035. // Access: Protected, Virtual
  8036. // Description: Called immediately before bind_light() is called,
  8037. // this is intended to provide the derived class a hook
  8038. // in which to set up some state (like transform) that
  8039. // might apply to several lights.
  8040. //
  8041. // The sequence is: begin_bind_lights() will be called,
  8042. // then one or more bind_light() calls, then
  8043. // end_bind_lights().
  8044. ////////////////////////////////////////////////////////////////////
  8045. void CLP(GraphicsStateGuardian)::
  8046. begin_bind_lights() {
  8047. // static PStatCollector _draw_set_state_light_begin_bind_pcollector("Draw:Set State:Light:Begin bind");
  8048. // PStatGPUTimer timer(this, _draw_set_state_light_begin_bind_pcollector);
  8049. // We need to temporarily load a new matrix so we can define the
  8050. // light in a known coordinate system. We pick the transform of the
  8051. // root. (Alternatively, we could leave the current transform where
  8052. // it is and compute the light position relative to that transform
  8053. // instead of relative to the root, by composing with the matrix
  8054. // computed by _internal_transform->invert_compose(render_transform).
  8055. // But I think loading a completely new matrix is simpler.)
  8056. CPT(TransformState) render_transform =
  8057. _cs_transform->compose(_scene_setup->get_world_transform());
  8058. glMatrixMode(GL_MODELVIEW);
  8059. glPushMatrix();
  8060. GLPf(LoadMatrix)(render_transform->get_mat().get_data());
  8061. }
  8062. #endif // SUPPORT_FIXED_FUNCTION
  8063. #ifdef SUPPORT_FIXED_FUNCTION
  8064. ////////////////////////////////////////////////////////////////////
  8065. // Function: GLGraphicsStateGuardian::end_bind_lights
  8066. // Access: Protected, Virtual
  8067. // Description: Called after before bind_light() has been called one
  8068. // or more times (but before any geometry is issued or
  8069. // additional state is changed), this is intended to
  8070. // clean up any temporary changes to the state that may
  8071. // have been made by begin_bind_lights().
  8072. ////////////////////////////////////////////////////////////////////
  8073. void CLP(GraphicsStateGuardian)::
  8074. end_bind_lights() {
  8075. // static PStatCollector _draw_set_state_light_end_bind_pcollector("Draw:Set State:Light:End bind");
  8076. // PStatGPUTimer timer(this, _draw_set_state_light_end_bind_pcollector);
  8077. glMatrixMode(GL_MODELVIEW);
  8078. glPopMatrix();
  8079. }
  8080. #endif // SUPPORT_FIXED_FUNCTION
  8081. #ifdef SUPPORT_FIXED_FUNCTION
  8082. ////////////////////////////////////////////////////////////////////
  8083. // Function: GLGraphicsStateGuardian::enable_clip_plane
  8084. // Access: Protected, Virtual
  8085. // Description: Intended to be overridden by a derived class to
  8086. // enable the indicated clip_plane id. A specific
  8087. // PlaneNode will already have been bound to this id via
  8088. // bind_clip_plane().
  8089. ////////////////////////////////////////////////////////////////////
  8090. void CLP(GraphicsStateGuardian)::
  8091. enable_clip_plane(int plane_id, bool enable) {
  8092. if (enable) {
  8093. glEnable(get_clip_plane_id(plane_id));
  8094. } else {
  8095. glDisable(get_clip_plane_id(plane_id));
  8096. }
  8097. }
  8098. #endif // SUPPORT_FIXED_FUNCTION
  8099. #ifdef SUPPORT_FIXED_FUNCTION
  8100. ////////////////////////////////////////////////////////////////////
  8101. // Function: GLGraphicsStateGuardian::begin_bind_clip_planes
  8102. // Access: Protected, Virtual
  8103. // Description: Called immediately before bind_clip_plane() is called,
  8104. // this is intended to provide the derived class a hook
  8105. // in which to set up some state (like transform) that
  8106. // might apply to several clip_planes.
  8107. //
  8108. // The sequence is: begin_bind_clip_planes() will be called,
  8109. // then one or more bind_clip_plane() calls, then
  8110. // end_bind_clip_planes().
  8111. ////////////////////////////////////////////////////////////////////
  8112. void CLP(GraphicsStateGuardian)::
  8113. begin_bind_clip_planes() {
  8114. // We need to temporarily load a new matrix so we can define the
  8115. // clip_plane in a known coordinate system. We pick the transform of the
  8116. // root. (Alternatively, we could leave the current transform where
  8117. // it is and compute the clip_plane position relative to that transform
  8118. // instead of relative to the root, by composing with the matrix
  8119. // computed by _internal_transform->invert_compose(render_transform).
  8120. // But I think loading a completely new matrix is simpler.)
  8121. CPT(TransformState) render_transform =
  8122. _cs_transform->compose(_scene_setup->get_world_transform());
  8123. glMatrixMode(GL_MODELVIEW);
  8124. glPushMatrix();
  8125. GLPf(LoadMatrix)(render_transform->get_mat().get_data());
  8126. }
  8127. #endif // SUPPORT_FIXED_FUNCTION
  8128. #ifdef SUPPORT_FIXED_FUNCTION
  8129. ////////////////////////////////////////////////////////////////////
  8130. // Function: GLGraphicsStateGuardian::bind_clip_plane
  8131. // Access: Protected, Virtual
  8132. // Description: Called the first time a particular clip_plane has been
  8133. // bound to a given id within a frame, this should set
  8134. // up the associated hardware clip_plane with the clip_plane's
  8135. // properties.
  8136. ////////////////////////////////////////////////////////////////////
  8137. void CLP(GraphicsStateGuardian)::
  8138. bind_clip_plane(const NodePath &plane, int plane_id) {
  8139. GLenum id = get_clip_plane_id(plane_id);
  8140. CPT(TransformState) transform = plane.get_transform(_scene_setup->get_scene_root().get_parent());
  8141. const PlaneNode *plane_node;
  8142. DCAST_INTO_V(plane_node, plane.node());
  8143. LPlane xformed_plane = plane_node->get_plane() * transform->get_mat();
  8144. #ifdef OPENGLES
  8145. // OpenGL ES uses a single-precision call.
  8146. LPlanef single_plane(LCAST(float, xformed_plane));
  8147. glClipPlanef(id, single_plane.get_data());
  8148. #else
  8149. // Mainline OpenGL uses a double-precision call.
  8150. LPlaned double_plane(LCAST(double, xformed_plane));
  8151. glClipPlane(id, double_plane.get_data());
  8152. #endif // OPENGLES
  8153. report_my_gl_errors();
  8154. }
  8155. #endif // SUPPORT_FIXED_FUNCTION
  8156. #ifdef SUPPORT_FIXED_FUNCTION
  8157. ////////////////////////////////////////////////////////////////////
  8158. // Function: GLGraphicsStateGuardian::end_bind_clip_planes
  8159. // Access: Protected, Virtual
  8160. // Description: Called after before bind_clip_plane() has been called one
  8161. // or more times (but before any geometry is issued or
  8162. // additional state is changed), this is intended to
  8163. // clean up any temporary changes to the state that may
  8164. // have been made by begin_bind_clip_planes().
  8165. ////////////////////////////////////////////////////////////////////
  8166. void CLP(GraphicsStateGuardian)::
  8167. end_bind_clip_planes() {
  8168. glMatrixMode(GL_MODELVIEW);
  8169. glPopMatrix();
  8170. }
  8171. #endif // SUPPORT_FIXED_FUNCTION
  8172. ////////////////////////////////////////////////////////////////////
  8173. // Function: GLGraphicsStateGuardian::set_state_and_transform
  8174. // Access: Public, Virtual
  8175. // Description: Simultaneously resets the render state and the
  8176. // transform state.
  8177. //
  8178. // This transform specified is the "internal" net
  8179. // transform, already converted into the GSG's internal
  8180. // coordinate space by composing it to
  8181. // get_cs_transform(). (Previously, this used to be the
  8182. // "external" net transform, with the assumption that
  8183. // that GSG would convert it internally, but that is no
  8184. // longer the case.)
  8185. //
  8186. // Special case: if (state==NULL), then the target
  8187. // state is already stored in _target.
  8188. ////////////////////////////////////////////////////////////////////
  8189. void CLP(GraphicsStateGuardian)::
  8190. set_state_and_transform(const RenderState *target,
  8191. const TransformState *transform) {
  8192. report_my_gl_errors();
  8193. #ifndef NDEBUG
  8194. if (gsg_cat.is_spam()) {
  8195. gsg_cat.spam() << "Setting GSG state to " << (void *)target << ":\n";
  8196. target->write(gsg_cat.spam(false), 2);
  8197. }
  8198. #endif
  8199. _state_pcollector.add_level(1);
  8200. PStatGPUTimer timer1(this, _draw_set_state_pcollector);
  8201. if (transform != _internal_transform) {
  8202. //PStatGPUTimer timer(this, _draw_set_state_transform_pcollector);
  8203. _transform_state_pcollector.add_level(1);
  8204. _internal_transform = transform;
  8205. do_issue_transform();
  8206. }
  8207. if (target == _state_rs && (_state_mask | _inv_state_mask).is_all_on()) {
  8208. return;
  8209. }
  8210. _target_rs = target;
  8211. _target_shader = (const ShaderAttrib *)
  8212. _target_rs->get_attrib_def(ShaderAttrib::get_class_slot());
  8213. #ifndef OPENGLES_1
  8214. _instance_count = _target_shader->get_instance_count();
  8215. #endif
  8216. #ifdef SUPPORT_FIXED_FUNCTION
  8217. int alpha_test_slot = AlphaTestAttrib::get_class_slot();
  8218. if (_target_rs->get_attrib(alpha_test_slot) != _state_rs->get_attrib(alpha_test_slot) ||
  8219. !_state_mask.get_bit(alpha_test_slot) ||
  8220. (_target_shader->get_flag(ShaderAttrib::F_subsume_alpha_test) !=
  8221. _state_shader->get_flag(ShaderAttrib::F_subsume_alpha_test))) {
  8222. //PStatGPUTimer timer(this, _draw_set_state_alpha_test_pcollector);
  8223. do_issue_alpha_test();
  8224. _state_mask.set_bit(alpha_test_slot);
  8225. }
  8226. #endif
  8227. int antialias_slot = AntialiasAttrib::get_class_slot();
  8228. if (_target_rs->get_attrib(antialias_slot) != _state_rs->get_attrib(antialias_slot) ||
  8229. !_state_mask.get_bit(antialias_slot)) {
  8230. //PStatGPUTimer timer(this, _draw_set_state_antialias_pcollector);
  8231. do_issue_antialias();
  8232. _state_mask.set_bit(antialias_slot);
  8233. }
  8234. int clip_plane_slot = ClipPlaneAttrib::get_class_slot();
  8235. if (_target_rs->get_attrib(clip_plane_slot) != _state_rs->get_attrib(clip_plane_slot) ||
  8236. !_state_mask.get_bit(clip_plane_slot)) {
  8237. //PStatGPUTimer timer(this, _draw_set_state_clip_plane_pcollector);
  8238. do_issue_clip_plane();
  8239. _state_mask.set_bit(clip_plane_slot);
  8240. #ifndef OPENGLES_1
  8241. if (_current_shader_context) {
  8242. _current_shader_context->issue_parameters(Shader::SSD_clip_planes);
  8243. }
  8244. #endif
  8245. }
  8246. int color_slot = ColorAttrib::get_class_slot();
  8247. int color_scale_slot = ColorScaleAttrib::get_class_slot();
  8248. if (_target_rs->get_attrib(color_slot) != _state_rs->get_attrib(color_slot) ||
  8249. _target_rs->get_attrib(color_scale_slot) != _state_rs->get_attrib(color_scale_slot) ||
  8250. !_state_mask.get_bit(color_slot) ||
  8251. !_state_mask.get_bit(color_scale_slot)) {
  8252. //PStatGPUTimer timer(this, _draw_set_state_color_pcollector);
  8253. do_issue_color();
  8254. do_issue_color_scale();
  8255. _state_mask.set_bit(color_slot);
  8256. _state_mask.set_bit(color_scale_slot);
  8257. #ifndef OPENGLES_1
  8258. if (_current_shader_context) {
  8259. _current_shader_context->issue_parameters(Shader::SSD_color);
  8260. _current_shader_context->issue_parameters(Shader::SSD_colorscale);
  8261. }
  8262. #endif
  8263. }
  8264. int cull_face_slot = CullFaceAttrib::get_class_slot();
  8265. if (_target_rs->get_attrib(cull_face_slot) != _state_rs->get_attrib(cull_face_slot) ||
  8266. !_state_mask.get_bit(cull_face_slot)) {
  8267. //PStatGPUTimer timer(this, _draw_set_state_cull_face_pcollector);
  8268. do_issue_cull_face();
  8269. _state_mask.set_bit(cull_face_slot);
  8270. }
  8271. int depth_offset_slot = DepthOffsetAttrib::get_class_slot();
  8272. if (_target_rs->get_attrib(depth_offset_slot) != _state_rs->get_attrib(depth_offset_slot) ||
  8273. !_state_mask.get_bit(depth_offset_slot)) {
  8274. //PStatGPUTimer timer(this, _draw_set_state_depth_offset_pcollector);
  8275. do_issue_depth_offset();
  8276. _state_mask.set_bit(depth_offset_slot);
  8277. }
  8278. int depth_test_slot = DepthTestAttrib::get_class_slot();
  8279. if (_target_rs->get_attrib(depth_test_slot) != _state_rs->get_attrib(depth_test_slot) ||
  8280. !_state_mask.get_bit(depth_test_slot)) {
  8281. //PStatGPUTimer timer(this, _draw_set_state_depth_test_pcollector);
  8282. do_issue_depth_test();
  8283. _state_mask.set_bit(depth_test_slot);
  8284. }
  8285. int depth_write_slot = DepthWriteAttrib::get_class_slot();
  8286. if (_target_rs->get_attrib(depth_write_slot) != _state_rs->get_attrib(depth_write_slot) ||
  8287. !_state_mask.get_bit(depth_write_slot)) {
  8288. //PStatGPUTimer timer(this, _draw_set_state_depth_write_pcollector);
  8289. do_issue_depth_write();
  8290. _state_mask.set_bit(depth_write_slot);
  8291. }
  8292. int render_mode_slot = RenderModeAttrib::get_class_slot();
  8293. if (_target_rs->get_attrib(render_mode_slot) != _state_rs->get_attrib(render_mode_slot) ||
  8294. !_state_mask.get_bit(render_mode_slot)) {
  8295. //PStatGPUTimer timer(this, _draw_set_state_render_mode_pcollector);
  8296. do_issue_render_mode();
  8297. _state_mask.set_bit(render_mode_slot);
  8298. }
  8299. #ifdef SUPPORT_FIXED_FUNCTION
  8300. int rescale_normal_slot = RescaleNormalAttrib::get_class_slot();
  8301. if (_target_rs->get_attrib(rescale_normal_slot) != _state_rs->get_attrib(rescale_normal_slot) ||
  8302. !_state_mask.get_bit(rescale_normal_slot)) {
  8303. //PStatGPUTimer timer(this, _draw_set_state_rescale_normal_pcollector);
  8304. do_issue_rescale_normal();
  8305. _state_mask.set_bit(rescale_normal_slot);
  8306. }
  8307. #endif
  8308. #ifdef SUPPORT_FIXED_FUNCTION
  8309. int shade_model_slot = ShadeModelAttrib::get_class_slot();
  8310. if (_target_rs->get_attrib(shade_model_slot) != _state_rs->get_attrib(shade_model_slot) ||
  8311. !_state_mask.get_bit(shade_model_slot)) {
  8312. //PStatGPUTimer timer(this, _draw_set_state_shade_model_pcollector);
  8313. do_issue_shade_model();
  8314. _state_mask.set_bit(shade_model_slot);
  8315. }
  8316. #endif
  8317. int transparency_slot = TransparencyAttrib::get_class_slot();
  8318. int color_write_slot = ColorWriteAttrib::get_class_slot();
  8319. int color_blend_slot = ColorBlendAttrib::get_class_slot();
  8320. if (_target_rs->get_attrib(transparency_slot) != _state_rs->get_attrib(transparency_slot) ||
  8321. _target_rs->get_attrib(color_write_slot) != _state_rs->get_attrib(color_write_slot) ||
  8322. _target_rs->get_attrib(color_blend_slot) != _state_rs->get_attrib(color_blend_slot) ||
  8323. !_state_mask.get_bit(transparency_slot) ||
  8324. !_state_mask.get_bit(color_write_slot) ||
  8325. !_state_mask.get_bit(color_blend_slot) ||
  8326. (_target_shader->get_flag(ShaderAttrib::F_disable_alpha_write) !=
  8327. _state_shader->get_flag(ShaderAttrib::F_disable_alpha_write))) {
  8328. //PStatGPUTimer timer(this, _draw_set_state_blending_pcollector);
  8329. do_issue_blending();
  8330. _state_mask.set_bit(transparency_slot);
  8331. _state_mask.set_bit(color_write_slot);
  8332. _state_mask.set_bit(color_blend_slot);
  8333. }
  8334. if (_target_shader != _state_shader) {
  8335. //PStatGPUTimer timer(this, _draw_set_state_shader_pcollector);
  8336. #ifndef OPENGLES_1
  8337. do_issue_shader(true);
  8338. #endif
  8339. _state_shader = _target_shader;
  8340. _state_mask.clear_bit(TextureAttrib::get_class_slot());
  8341. }
  8342. #ifndef SUPPORT_FIXED_FUNCTION
  8343. else { // In the case of OpenGL ES 2.x, we need to glUseShader before we draw anything.
  8344. do_issue_shader(false);
  8345. }
  8346. #endif
  8347. int texture_slot = TextureAttrib::get_class_slot();
  8348. if (_target_rs->get_attrib(texture_slot) != _state_rs->get_attrib(texture_slot) ||
  8349. !_state_mask.get_bit(texture_slot)) {
  8350. //PStatGPUTimer timer(this, _draw_set_state_texture_pcollector);
  8351. determine_target_texture();
  8352. int prev_active = _num_active_texture_stages;
  8353. do_issue_texture();
  8354. // Since the TexGen and TexMatrix states depend partly on the
  8355. // particular set of textures in use, we should force both of
  8356. // those to be reissued every time we change the texture state.
  8357. _state_mask.clear_bit(TexGenAttrib::get_class_slot());
  8358. _state_mask.clear_bit(TexMatrixAttrib::get_class_slot());
  8359. _state_texture = _target_texture;
  8360. _state_mask.set_bit(texture_slot);
  8361. }
  8362. // If one of the previously-loaded TexGen modes modified the texture
  8363. // matrix, then if either state changed, we have to change both of
  8364. // them now.
  8365. if (_tex_gen_modifies_mat) {
  8366. int tex_gen_slot = TexGenAttrib::get_class_slot();
  8367. int tex_matrix_slot = TexMatrixAttrib::get_class_slot();
  8368. if (_target_rs->get_attrib(tex_gen_slot) != _state_rs->get_attrib(tex_gen_slot) ||
  8369. _target_rs->get_attrib(tex_matrix_slot) != _state_rs->get_attrib(tex_matrix_slot) ||
  8370. !_state_mask.get_bit(tex_gen_slot) ||
  8371. !_state_mask.get_bit(tex_matrix_slot)) {
  8372. _state_mask.clear_bit(tex_gen_slot);
  8373. _state_mask.clear_bit(tex_matrix_slot);
  8374. }
  8375. }
  8376. int tex_matrix_slot = TexMatrixAttrib::get_class_slot();
  8377. if (_target_rs->get_attrib(tex_matrix_slot) != _state_rs->get_attrib(tex_matrix_slot) ||
  8378. !_state_mask.get_bit(tex_matrix_slot)) {
  8379. //PStatGPUTimer timer(this, _draw_set_state_tex_matrix_pcollector);
  8380. #ifdef SUPPORT_FIXED_FUNCTION
  8381. do_issue_tex_matrix();
  8382. #endif
  8383. _state_mask.set_bit(tex_matrix_slot);
  8384. #ifndef OPENGLES_1
  8385. if (_current_shader_context) {
  8386. _current_shader_context->issue_parameters(Shader::SSD_tex_matrix);
  8387. }
  8388. #endif
  8389. }
  8390. #ifdef SUPPORT_FIXED_FUNCTION
  8391. int tex_gen_slot = TexGenAttrib::get_class_slot();
  8392. if (_target_tex_gen != _state_tex_gen ||
  8393. !_state_mask.get_bit(tex_gen_slot)) {
  8394. //PStatGPUTimer timer(this, _draw_set_state_tex_gen_pcollector);
  8395. do_issue_tex_gen();
  8396. _state_tex_gen = _target_tex_gen;
  8397. _state_mask.set_bit(tex_gen_slot);
  8398. }
  8399. #endif
  8400. int material_slot = MaterialAttrib::get_class_slot();
  8401. if (_target_rs->get_attrib(material_slot) != _state_rs->get_attrib(material_slot) ||
  8402. !_state_mask.get_bit(material_slot)) {
  8403. //PStatGPUTimer timer(this, _draw_set_state_material_pcollector);
  8404. #ifdef SUPPORT_FIXED_FUNCTION
  8405. do_issue_material();
  8406. #endif
  8407. _state_mask.set_bit(material_slot);
  8408. #ifndef OPENGLES_1
  8409. if (_current_shader_context) {
  8410. _current_shader_context->issue_parameters(Shader::SSD_material);
  8411. }
  8412. #endif
  8413. }
  8414. int light_slot = LightAttrib::get_class_slot();
  8415. if (_target_rs->get_attrib(light_slot) != _state_rs->get_attrib(light_slot) ||
  8416. !_state_mask.get_bit(light_slot)) {
  8417. //PStatGPUTimer timer(this, _draw_set_state_light_pcollector);
  8418. #ifdef SUPPORT_FIXED_FUNCTION
  8419. do_issue_light();
  8420. #endif
  8421. _state_mask.set_bit(light_slot);
  8422. #ifndef OPENGLES_1
  8423. if (_current_shader_context) {
  8424. _current_shader_context->issue_parameters(Shader::SSD_light);
  8425. }
  8426. #endif
  8427. }
  8428. int stencil_slot = StencilAttrib::get_class_slot();
  8429. if (_target_rs->get_attrib(stencil_slot) != _state_rs->get_attrib(stencil_slot) ||
  8430. !_state_mask.get_bit(stencil_slot)) {
  8431. //PStatGPUTimer timer(this, _draw_set_state_stencil_pcollector);
  8432. do_issue_stencil();
  8433. _state_mask.set_bit(stencil_slot);
  8434. }
  8435. int fog_slot = FogAttrib::get_class_slot();
  8436. if (_target_rs->get_attrib(fog_slot) != _state_rs->get_attrib(fog_slot) ||
  8437. !_state_mask.get_bit(fog_slot)) {
  8438. //PStatGPUTimer timer(this, _draw_set_state_fog_pcollector);
  8439. #ifdef SUPPORT_FIXED_FUNCTION
  8440. do_issue_fog();
  8441. #endif
  8442. _state_mask.set_bit(fog_slot);
  8443. #ifndef OPENGLES_1
  8444. if (_current_shader_context) {
  8445. _current_shader_context->issue_parameters(Shader::SSD_fog);
  8446. }
  8447. #endif
  8448. }
  8449. int scissor_slot = ScissorAttrib::get_class_slot();
  8450. if (_target_rs->get_attrib(scissor_slot) != _state_rs->get_attrib(scissor_slot) ||
  8451. !_state_mask.get_bit(scissor_slot)) {
  8452. //PStatGPUTimer timer(this, _draw_set_state_scissor_pcollector);
  8453. do_issue_scissor();
  8454. _state_mask.set_bit(scissor_slot);
  8455. }
  8456. _state_rs = _target_rs;
  8457. maybe_gl_finish();
  8458. report_my_gl_errors();
  8459. }
  8460. ////////////////////////////////////////////////////////////////////
  8461. // Function: GLGraphicsStateGuardian::free_pointers
  8462. // Access: Protected, Virtual
  8463. // Description: Frees some memory that was explicitly allocated
  8464. // within the glgsg.
  8465. ////////////////////////////////////////////////////////////////////
  8466. void CLP(GraphicsStateGuardian)::
  8467. free_pointers() {
  8468. #if defined(HAVE_CG) && !defined(OPENGLES)
  8469. if (_cg_context != 0) {
  8470. cgDestroyContext(_cg_context);
  8471. _cg_context = 0;
  8472. }
  8473. #endif
  8474. }
  8475. ////////////////////////////////////////////////////////////////////
  8476. // Function: GLGraphicsStateGuardian::do_issue_texture
  8477. // Access: Protected, Virtual
  8478. // Description: This is called by set_state_and_transform() when
  8479. // the texture state has changed.
  8480. ////////////////////////////////////////////////////////////////////
  8481. void CLP(GraphicsStateGuardian)::
  8482. do_issue_texture() {
  8483. DO_PSTATS_STUFF(_texture_state_pcollector.add_level(1));
  8484. #ifdef OPENGLES_1
  8485. update_standard_texture_bindings();
  8486. #else
  8487. if (_current_shader_context == 0 || !_current_shader_context->uses_custom_texture_bindings()) {
  8488. // No shader, or a non-Cg shader.
  8489. if (_texture_binding_shader_context != 0) {
  8490. _texture_binding_shader_context->disable_shader_texture_bindings();
  8491. }
  8492. #ifdef SUPPORT_FIXED_FUNCTION
  8493. update_standard_texture_bindings();
  8494. #endif
  8495. } else {
  8496. if (_texture_binding_shader_context == 0) {
  8497. #ifdef SUPPORT_FIXED_FUNCTION
  8498. disable_standard_texture_bindings();
  8499. #endif
  8500. _current_shader_context->update_shader_texture_bindings(NULL);
  8501. } else {
  8502. _current_shader_context->
  8503. update_shader_texture_bindings(_texture_binding_shader_context);
  8504. }
  8505. }
  8506. _texture_binding_shader = _current_shader;
  8507. _texture_binding_shader_context = _current_shader_context;
  8508. #endif
  8509. }
  8510. #ifdef SUPPORT_FIXED_FUNCTION
  8511. ////////////////////////////////////////////////////////////////////
  8512. // Function: GLGraphicsStateGuardian::update_standard_texture_bindings
  8513. // Access: Private
  8514. // Description: Applies the appropriate set of textures for the
  8515. // current state, using the standard fixed-function
  8516. // pipeline.
  8517. ////////////////////////////////////////////////////////////////////
  8518. void CLP(GraphicsStateGuardian)::
  8519. update_standard_texture_bindings() {
  8520. #ifndef NDEBUG
  8521. if (_show_texture_usage) {
  8522. update_show_usage_texture_bindings(-1);
  8523. return;
  8524. }
  8525. #endif // NDEBUG
  8526. int num_stages = _target_texture->get_num_on_ff_stages();
  8527. #ifndef NDEBUG
  8528. // Also check the _flash_texture. If it is non-NULL, we need to
  8529. // check to see if our flash_texture is in the texture stack here.
  8530. // If so, then we need to call the special show_texture method
  8531. // instead of the normal texture stack.
  8532. if (_flash_texture != (Texture *)NULL) {
  8533. double now = ClockObject::get_global_clock()->get_frame_time();
  8534. int this_second = (int)floor(now);
  8535. if (this_second & 1) {
  8536. int show_stage_index = -1;
  8537. for (int i = 0; i < num_stages && show_stage_index < 0; ++i) {
  8538. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  8539. Texture *texture = _target_texture->get_on_texture(stage);
  8540. if (texture == _flash_texture) {
  8541. show_stage_index = i;
  8542. }
  8543. }
  8544. if (show_stage_index >= 0) {
  8545. update_show_usage_texture_bindings(show_stage_index);
  8546. return;
  8547. }
  8548. }
  8549. }
  8550. #endif // NDEBUG
  8551. nassertv(num_stages <= _max_texture_stages &&
  8552. _num_active_texture_stages <= _max_texture_stages);
  8553. _texture_involves_color_scale = false;
  8554. int last_saved_result = -1;
  8555. int last_stage = -1;
  8556. int i;
  8557. for (i = 0; i < num_stages; i++) {
  8558. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  8559. Texture *texture = _target_texture->get_on_texture(stage);
  8560. nassertv(texture != (Texture *)NULL);
  8561. // Issue the texture on stage i.
  8562. _glActiveTexture(GL_TEXTURE0 + i);
  8563. // First, turn off the previous texture mode.
  8564. glDisable(GL_TEXTURE_2D);
  8565. if (_supports_cube_map) {
  8566. glDisable(GL_TEXTURE_CUBE_MAP);
  8567. }
  8568. #ifndef OPENGLES
  8569. glDisable(GL_TEXTURE_1D);
  8570. if (_supports_3d_texture) {
  8571. glDisable(GL_TEXTURE_3D);
  8572. }
  8573. #endif // OPENGLES
  8574. int view = get_current_tex_view_offset() + stage->get_tex_view_offset();
  8575. TextureContext *tc = texture->prepare_now(view, _prepared_objects, this);
  8576. if (tc == (TextureContext *)NULL) {
  8577. // Something wrong with this texture; skip it.
  8578. continue;
  8579. }
  8580. // Then, turn on the current texture mode.
  8581. GLenum target = get_texture_target(texture->get_texture_type());
  8582. if (target == GL_NONE) {
  8583. // Unsupported texture mode.
  8584. continue;
  8585. }
  8586. #ifndef OPENGLES
  8587. if (target == GL_TEXTURE_2D_ARRAY_EXT) {
  8588. // Cannot be applied via the FFP.
  8589. continue;
  8590. }
  8591. #endif // OPENGLES
  8592. glEnable(target);
  8593. if (!update_texture(tc, false)) {
  8594. glDisable(target);
  8595. continue;
  8596. }
  8597. // Don't DCAST(); we already did the verification in update_texture.
  8598. CLP(TextureContext) *gtc = (CLP(TextureContext) *)tc;
  8599. apply_texture(gtc);
  8600. apply_sampler(i, _target_texture->get_on_sampler(stage), gtc);
  8601. if (stage->involves_color_scale() && _color_scale_enabled) {
  8602. LColor color = stage->get_color();
  8603. color.set(color[0] * _current_color_scale[0],
  8604. color[1] * _current_color_scale[1],
  8605. color[2] * _current_color_scale[2],
  8606. color[3] * _current_color_scale[3]);
  8607. _texture_involves_color_scale = true;
  8608. call_glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, color);
  8609. } else {
  8610. call_glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, stage->get_color());
  8611. }
  8612. if (stage->get_mode() == TextureStage::M_decal) {
  8613. if (texture->get_num_components() < 3 && _supports_texture_combine) {
  8614. // Make a special case for 1- and 2-channel decal textures.
  8615. // OpenGL does not define their use with GL_DECAL for some
  8616. // reason, so implement them using the combiner instead.
  8617. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
  8618. glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
  8619. glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, 1);
  8620. glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, 1);
  8621. glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
  8622. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR);
  8623. glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS);
  8624. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR);
  8625. glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_TEXTURE);
  8626. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
  8627. } else {
  8628. // Normal 3- and 4-channel decal textures.
  8629. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
  8630. }
  8631. } else if (stage->get_mode() == TextureStage::M_combine) {
  8632. if (!_supports_texture_combine) {
  8633. GLCAT.warning()
  8634. << "TextureStage::M_combine mode is not supported.\n";
  8635. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
  8636. } else {
  8637. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
  8638. glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
  8639. glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, stage->get_rgb_scale());
  8640. glTexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, stage->get_alpha_scale());
  8641. glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB,
  8642. get_texture_combine_type(stage->get_combine_rgb_mode()));
  8643. switch (stage->get_num_combine_rgb_operands()) {
  8644. case 3:
  8645. glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB,
  8646. get_texture_src_type(stage->get_combine_rgb_source2(),
  8647. last_stage, last_saved_result, i));
  8648. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB,
  8649. get_texture_operand_type(stage->get_combine_rgb_operand2()));
  8650. // fall through
  8651. case 2:
  8652. glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB,
  8653. get_texture_src_type(stage->get_combine_rgb_source1(),
  8654. last_stage, last_saved_result, i));
  8655. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_RGB,
  8656. get_texture_operand_type(stage->get_combine_rgb_operand1()));
  8657. // fall through
  8658. case 1:
  8659. glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB,
  8660. get_texture_src_type(stage->get_combine_rgb_source0(),
  8661. last_stage, last_saved_result, i));
  8662. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB,
  8663. get_texture_operand_type(stage->get_combine_rgb_operand0()));
  8664. // fall through
  8665. default:
  8666. break;
  8667. }
  8668. glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA,
  8669. get_texture_combine_type(stage->get_combine_alpha_mode()));
  8670. switch (stage->get_num_combine_alpha_operands()) {
  8671. case 3:
  8672. glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_ALPHA,
  8673. get_texture_src_type(stage->get_combine_alpha_source2(),
  8674. last_stage, last_saved_result, i));
  8675. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA,
  8676. get_texture_operand_type(stage->get_combine_alpha_operand2()));
  8677. // fall through
  8678. case 2:
  8679. glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA,
  8680. get_texture_src_type(stage->get_combine_alpha_source1(),
  8681. last_stage, last_saved_result, i));
  8682. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND1_ALPHA,
  8683. get_texture_operand_type(stage->get_combine_alpha_operand1()));
  8684. // fall through
  8685. case 1:
  8686. glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA,
  8687. get_texture_src_type(stage->get_combine_alpha_source0(),
  8688. last_stage, last_saved_result, i));
  8689. glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA,
  8690. get_texture_operand_type(stage->get_combine_alpha_operand0()));
  8691. // fall through
  8692. default:
  8693. break;
  8694. }
  8695. }
  8696. } else {
  8697. GLint glmode = get_texture_apply_mode_type(stage->get_mode());
  8698. glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, glmode);
  8699. }
  8700. if (stage->get_saved_result()) {
  8701. // This texture's result will be "saved" for a future stage's
  8702. // input.
  8703. last_saved_result = i;
  8704. } else {
  8705. // This is a regular texture stage; it will be the "previous"
  8706. // input for the next stage.
  8707. last_stage = i;
  8708. }
  8709. }
  8710. // Disable the texture stages that are no longer used.
  8711. for (i = num_stages; i < _num_active_texture_stages; i++) {
  8712. _glActiveTexture(GL_TEXTURE0 + i);
  8713. glDisable(GL_TEXTURE_2D);
  8714. if (_supports_cube_map) {
  8715. glDisable(GL_TEXTURE_CUBE_MAP);
  8716. }
  8717. #ifndef OPENGLES
  8718. glDisable(GL_TEXTURE_1D);
  8719. if (_supports_3d_texture) {
  8720. glDisable(GL_TEXTURE_3D);
  8721. }
  8722. #endif // OPENGLES
  8723. }
  8724. // Save the count of texture stages for next time.
  8725. _num_active_texture_stages = num_stages;
  8726. report_my_gl_errors();
  8727. }
  8728. #endif // SUPPORT_FIXED_FUNCTION
  8729. ////////////////////////////////////////////////////////////////////
  8730. // Function: GLGraphicsStateGuardian::apply_white_texture
  8731. // Access: Private
  8732. // Description: Applies a white dummy texture. This is useful to
  8733. // bind to a texture slot when a texture is missing.
  8734. ////////////////////////////////////////////////////////////////////
  8735. void CLP(GraphicsStateGuardian)::
  8736. apply_white_texture() {
  8737. if (_white_texture != 0) {
  8738. glBindTexture(GL_TEXTURE_2D, _white_texture);
  8739. return;
  8740. }
  8741. glGenTextures(1, &_white_texture);
  8742. glBindTexture(GL_TEXTURE_2D, _white_texture);
  8743. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  8744. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  8745. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  8746. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  8747. unsigned char data[] = {0xff, 0xff, 0xff, 0xff};
  8748. glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1, 0,
  8749. GL_RGBA, GL_UNSIGNED_BYTE, data);
  8750. }
  8751. #ifndef NDEBUG
  8752. ////////////////////////////////////////////////////////////////////
  8753. // Function: GLGraphicsStateGuardian::update_show_usage_texture_bindings
  8754. // Access: Private
  8755. // Description: This is a special function that loads the usage
  8756. // textures in gl-show-texture-usage mode, instead of
  8757. // loading the actual used textures.
  8758. //
  8759. // If the indicated stage_index is >= 0, then it is the
  8760. // particular texture that is shown. Otherwise, the
  8761. // textures are rotated through based on
  8762. // show_texture_usage_index.
  8763. ////////////////////////////////////////////////////////////////////
  8764. void CLP(GraphicsStateGuardian)::
  8765. update_show_usage_texture_bindings(int show_stage_index) {
  8766. int num_stages = _target_texture->get_num_on_ff_stages();
  8767. nassertv(num_stages <= _max_texture_stages &&
  8768. _num_active_texture_stages <= _max_texture_stages);
  8769. _texture_involves_color_scale = false;
  8770. // First, we walk through the list of textures and pretend to render
  8771. // them all, even though we don't actually render them, just so
  8772. // Panda will keep track of the list of "active" textures correctly
  8773. // during the flash.
  8774. int i;
  8775. for (i = 0; i < num_stages; i++) {
  8776. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  8777. Texture *texture = _target_texture->get_on_texture(stage);
  8778. nassertv(texture != (Texture *)NULL);
  8779. int view = get_current_tex_view_offset() + stage->get_tex_view_offset();
  8780. TextureContext *tc = texture->prepare_now(view, _prepared_objects, this);
  8781. if (tc == (TextureContext *)NULL) {
  8782. // Something wrong with this texture; skip it.
  8783. break;
  8784. }
  8785. tc->enqueue_lru(&_prepared_objects->_graphics_memory_lru);
  8786. }
  8787. #ifdef SUPPORT_FIXED_FUNCTION
  8788. // Disable all texture stages.
  8789. for (i = 0; i < _num_active_texture_stages; i++) {
  8790. _glActiveTexture(GL_TEXTURE0 + i);
  8791. #ifndef OPENGLES
  8792. glDisable(GL_TEXTURE_1D);
  8793. #endif // OPENGLES
  8794. glDisable(GL_TEXTURE_2D);
  8795. if (_supports_3d_texture) {
  8796. #ifndef OPENGLES_1
  8797. glDisable(GL_TEXTURE_3D);
  8798. #endif // OPENGLES_1
  8799. }
  8800. if (_supports_cube_map) {
  8801. glDisable(GL_TEXTURE_CUBE_MAP);
  8802. }
  8803. }
  8804. #endif
  8805. // Save the count of texture stages for next time.
  8806. _num_active_texture_stages = num_stages;
  8807. if (num_stages > 0) {
  8808. // Now, pick just one texture stage to apply.
  8809. if (show_stage_index >= 0 && show_stage_index < num_stages) {
  8810. i = show_stage_index;
  8811. } else {
  8812. i = _show_texture_usage_index % num_stages;
  8813. }
  8814. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  8815. Texture *texture = _target_texture->get_on_texture(stage);
  8816. nassertv(texture != (Texture *)NULL);
  8817. // Choose the corresponding usage texture and apply it.
  8818. _glActiveTexture(GL_TEXTURE0 + i);
  8819. #ifdef SUPPORT_FIXED_FUNCTION
  8820. glEnable(GL_TEXTURE_2D);
  8821. #endif
  8822. UsageTextureKey key(texture->get_x_size(), texture->get_y_size());
  8823. UsageTextures::iterator ui = _usage_textures.find(key);
  8824. if (ui == _usage_textures.end()) {
  8825. // Need to create a new texture for this size.
  8826. GLuint index;
  8827. glGenTextures(1, &index);
  8828. glBindTexture(GL_TEXTURE_2D, index);
  8829. //TODO: this could be a lot simpler with glTexStorage2D
  8830. // followed by a call to glClearTexImage.
  8831. upload_usage_texture(texture->get_x_size(), texture->get_y_size());
  8832. _usage_textures[key] = index;
  8833. } else {
  8834. // Just bind the previously-created texture.
  8835. GLuint index = (*ui).second;
  8836. glBindTexture(GL_TEXTURE_2D, index);
  8837. }
  8838. //TODO: glBindSampler(0) ?
  8839. }
  8840. report_my_gl_errors();
  8841. }
  8842. #endif // NDEBUG
  8843. #ifndef NDEBUG
  8844. ////////////////////////////////////////////////////////////////////
  8845. // Function: GLGraphicsStateGuardian::upload_usage_texture
  8846. // Access: Protected
  8847. // Description: Uploads a special "usage" texture intended to be
  8848. // applied only in gl-show-texture-usage mode, to reveal
  8849. // where texture memory is being spent.
  8850. ////////////////////////////////////////////////////////////////////
  8851. void CLP(GraphicsStateGuardian)::
  8852. upload_usage_texture(int width, int height) {
  8853. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
  8854. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
  8855. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
  8856. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  8857. if (GLCAT.is_debug()) {
  8858. GLCAT.debug()
  8859. << "upload_usage_texture(" << width << ", " << height << ")\n";
  8860. }
  8861. static LColor colors[3] = {
  8862. LColor(0.4, 0.5f, 0.8f, 1.0f), // mipmap 0: blue
  8863. LColor(1.0f, 1.0f, 0.0f, 1.0f), // mipmap 1: yellow
  8864. LColor(0.8f, 0.3, 0.3, 1.0f), // mipmap 2 and higher: red
  8865. };
  8866. // Allocate a temporary array large enough to contain the toplevel
  8867. // mipmap.
  8868. PN_uint32 *buffer = (PN_uint32 *)PANDA_MALLOC_ARRAY(width * height * 4);
  8869. int n = 0;
  8870. while (true) {
  8871. // Choose the color for the nth mipmap.
  8872. LColor c = colors[min(n, 2)];
  8873. // A simple union to store the colors values bytewise, and get the
  8874. // answer wordwise, independently of machine byte-ordernig.
  8875. union {
  8876. struct {
  8877. unsigned char r, g, b, a;
  8878. } b;
  8879. PN_uint32 w;
  8880. } store;
  8881. store.b.r = (unsigned char)(c[0] * 255.0f);
  8882. store.b.g = (unsigned char)(c[1] * 255.0f);
  8883. store.b.b = (unsigned char)(c[2] * 255.0f);
  8884. store.b.a = 0xff;
  8885. // Fill in the array.
  8886. int num_pixels = width * height;
  8887. for (int p = 0; p < num_pixels; ++p) {
  8888. buffer[p] = store.w;
  8889. }
  8890. glTexImage2D(GL_TEXTURE_2D, n, GL_RGBA, width, height, 0,
  8891. GL_RGBA, GL_UNSIGNED_BYTE, buffer);
  8892. if (width == 1 && height == 1) {
  8893. // That was the last mipmap level.
  8894. break;
  8895. }
  8896. width = max(width >> 1, 1);
  8897. height = max(height >> 1, 1);
  8898. ++n;
  8899. }
  8900. PANDA_FREE_ARRAY(buffer);
  8901. }
  8902. #endif // NDEBUG
  8903. #ifdef SUPPORT_FIXED_FUNCTION
  8904. ////////////////////////////////////////////////////////////////////
  8905. // Function: GLGraphicsStateGuardian::disable_standard_texture_bindings
  8906. // Access: Private
  8907. // Description:
  8908. ////////////////////////////////////////////////////////////////////
  8909. void CLP(GraphicsStateGuardian)::
  8910. disable_standard_texture_bindings() {
  8911. // Disable the texture stages that are no longer used.
  8912. for (int i = 0; i < _num_active_texture_stages; i++) {
  8913. _glActiveTexture(GL_TEXTURE0 + i);
  8914. #ifndef OPENGLES
  8915. glDisable(GL_TEXTURE_1D);
  8916. #endif // OPENGLES
  8917. glDisable(GL_TEXTURE_2D);
  8918. if (_supports_3d_texture) {
  8919. #ifndef OPENGLES_1
  8920. glDisable(GL_TEXTURE_3D);
  8921. #endif // OPENGLES_1
  8922. }
  8923. if (_supports_cube_map) {
  8924. glDisable(GL_TEXTURE_CUBE_MAP);
  8925. }
  8926. }
  8927. _num_active_texture_stages = 0;
  8928. report_my_gl_errors();
  8929. }
  8930. #endif // SUPPORT_FIXED_FUNCTION
  8931. #ifdef SUPPORT_FIXED_FUNCTION
  8932. ////////////////////////////////////////////////////////////////////
  8933. // Function: GLGraphicsStateGuardian::do_issue_tex_matrix
  8934. // Access: Protected
  8935. // Description:
  8936. ////////////////////////////////////////////////////////////////////
  8937. void CLP(GraphicsStateGuardian)::
  8938. do_issue_tex_matrix() {
  8939. nassertv(_num_active_texture_stages <= _max_texture_stages);
  8940. for (int i = 0; i < _num_active_texture_stages; i++) {
  8941. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  8942. _glActiveTexture(GL_TEXTURE0 + i);
  8943. glMatrixMode(GL_TEXTURE);
  8944. const TexMatrixAttrib *target_tex_matrix;
  8945. _target_rs->get_attrib_def(target_tex_matrix);
  8946. if (target_tex_matrix->has_stage(stage)) {
  8947. GLPf(LoadMatrix)(target_tex_matrix->get_mat(stage).get_data());
  8948. } else {
  8949. glLoadIdentity();
  8950. // For some reason, the glLoadIdentity() call doesn't work on
  8951. // my Dell laptop's IBM OpenGL driver, when used in
  8952. // conjunction with glTexGen(), below. But explicitly loading
  8953. // an identity matrix does work. But this buggy-driver
  8954. // workaround might have other performance implications, so I
  8955. // leave it out.
  8956. // GLPf(LoadMatrix)(LMatrix4::ident_mat().get_data());
  8957. }
  8958. }
  8959. report_my_gl_errors();
  8960. }
  8961. #endif // SUPPORT_FIXED_FUNCTION
  8962. #ifdef SUPPORT_FIXED_FUNCTION
  8963. ////////////////////////////////////////////////////////////////////
  8964. // Function: GLGraphicsStateGuardian::do_issue_tex_gen
  8965. // Access: Protected
  8966. // Description:
  8967. ////////////////////////////////////////////////////////////////////
  8968. void CLP(GraphicsStateGuardian)::
  8969. do_issue_tex_gen() {
  8970. bool force_normal = false;
  8971. nassertv(_num_active_texture_stages <= _max_texture_stages);
  8972. // These are passed in for the four OBJECT_PLANE or EYE_PLANE
  8973. // values; they effectively define an identity matrix that maps
  8974. // the spatial coordinates one-for-one to UV's. If you want a
  8975. // mapping other than identity, use a TexMatrixAttrib (or a
  8976. // TexProjectorEffect).
  8977. static const PN_stdfloat s_data[4] = { 1, 0, 0, 0 };
  8978. static const PN_stdfloat t_data[4] = { 0, 1, 0, 0 };
  8979. static const PN_stdfloat r_data[4] = { 0, 0, 1, 0 };
  8980. static const PN_stdfloat q_data[4] = { 0, 0, 0, 1 };
  8981. _tex_gen_modifies_mat = false;
  8982. bool got_point_sprites = false;
  8983. for (int i = 0; i < _num_active_texture_stages; i++) {
  8984. TextureStage *stage = _target_texture->get_on_ff_stage(i);
  8985. _glActiveTexture(GL_TEXTURE0 + i);
  8986. if (_supports_point_sprite) {
  8987. #ifdef OPENGLES
  8988. glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_FALSE);
  8989. #else
  8990. glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_FALSE);
  8991. #endif // OPENGLES
  8992. }
  8993. #ifndef OPENGLES // TexGen not supported by OpenGL ES.
  8994. glDisable(GL_TEXTURE_GEN_S);
  8995. glDisable(GL_TEXTURE_GEN_T);
  8996. glDisable(GL_TEXTURE_GEN_R);
  8997. glDisable(GL_TEXTURE_GEN_Q);
  8998. TexGenAttrib::Mode mode = _target_tex_gen->get_mode(stage);
  8999. switch (mode) {
  9000. case TexGenAttrib::M_off:
  9001. case TexGenAttrib::M_unused2:
  9002. break;
  9003. case TexGenAttrib::M_eye_sphere_map:
  9004. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  9005. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  9006. glEnable(GL_TEXTURE_GEN_S);
  9007. glEnable(GL_TEXTURE_GEN_T);
  9008. force_normal = true;
  9009. break;
  9010. case TexGenAttrib::M_eye_cube_map:
  9011. if (_supports_cube_map) {
  9012. // We need to rotate the normals out of GL's coordinate
  9013. // system and into the user's coordinate system. We do this
  9014. // by composing a transform onto the texture matrix.
  9015. LMatrix4 mat = _inv_cs_transform->get_mat();
  9016. mat.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
  9017. glMatrixMode(GL_TEXTURE);
  9018. GLPf(MultMatrix)(mat.get_data());
  9019. // Now we need to reset the texture matrix next time
  9020. // around to undo this.
  9021. _tex_gen_modifies_mat = true;
  9022. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  9023. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  9024. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  9025. glEnable(GL_TEXTURE_GEN_S);
  9026. glEnable(GL_TEXTURE_GEN_T);
  9027. glEnable(GL_TEXTURE_GEN_R);
  9028. force_normal = true;
  9029. }
  9030. break;
  9031. case TexGenAttrib::M_world_cube_map:
  9032. if (_supports_cube_map) {
  9033. // We dynamically transform normals from eye space to world
  9034. // space by applying the appropriate rotation transform to
  9035. // the current texture matrix. Unlike M_world_position, we
  9036. // can't achieve this effect by monkeying with the modelview
  9037. // transform, since the current modelview doesn't affect
  9038. // GL_REFLECTION_MAP.
  9039. CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
  9040. LMatrix4 mat = camera_transform->get_mat();
  9041. mat.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
  9042. glMatrixMode(GL_TEXTURE);
  9043. GLPf(MultMatrix)(mat.get_data());
  9044. // Now we need to reset the texture matrix next time
  9045. // around to undo this.
  9046. _tex_gen_modifies_mat = true;
  9047. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  9048. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  9049. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  9050. glEnable(GL_TEXTURE_GEN_S);
  9051. glEnable(GL_TEXTURE_GEN_T);
  9052. glEnable(GL_TEXTURE_GEN_R);
  9053. force_normal = true;
  9054. }
  9055. break;
  9056. case TexGenAttrib::M_eye_normal:
  9057. if (_supports_cube_map) {
  9058. // We need to rotate the normals out of GL's coordinate
  9059. // system and into the user's coordinate system. We do this
  9060. // by composing a transform onto the texture matrix.
  9061. LMatrix4 mat = _inv_cs_transform->get_mat();
  9062. mat.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
  9063. glMatrixMode(GL_TEXTURE);
  9064. GLPf(MultMatrix)(mat.get_data());
  9065. // Now we need to reset the texture matrix next time
  9066. // around to undo this.
  9067. _tex_gen_modifies_mat = true;
  9068. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  9069. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  9070. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  9071. glEnable(GL_TEXTURE_GEN_S);
  9072. glEnable(GL_TEXTURE_GEN_T);
  9073. glEnable(GL_TEXTURE_GEN_R);
  9074. force_normal = true;
  9075. }
  9076. break;
  9077. case TexGenAttrib::M_world_normal:
  9078. if (_supports_cube_map) {
  9079. // We dynamically transform normals from eye space to world
  9080. // space by applying the appropriate rotation transform to
  9081. // the current texture matrix. Unlike M_world_position, we
  9082. // can't achieve this effect by monkeying with the modelview
  9083. // transform, since the current modelview doesn't affect
  9084. // GL_NORMAL_MAP.
  9085. CPT(TransformState) camera_transform = _scene_setup->get_camera_transform()->compose(_inv_cs_transform);
  9086. LMatrix4 mat = camera_transform->get_mat();
  9087. mat.set_row(3, LVecBase3(0.0f, 0.0f, 0.0f));
  9088. glMatrixMode(GL_TEXTURE);
  9089. GLPf(MultMatrix)(mat.get_data());
  9090. // Now we need to reset the texture matrix next time
  9091. // around to undo this.
  9092. _tex_gen_modifies_mat = true;
  9093. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  9094. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  9095. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  9096. glEnable(GL_TEXTURE_GEN_S);
  9097. glEnable(GL_TEXTURE_GEN_T);
  9098. glEnable(GL_TEXTURE_GEN_R);
  9099. force_normal = true;
  9100. }
  9101. break;
  9102. case TexGenAttrib::M_eye_position:
  9103. // To represent eye position correctly, we need to temporarily
  9104. // load the coordinate-system transform.
  9105. glMatrixMode(GL_MODELVIEW);
  9106. glPushMatrix();
  9107. GLPf(LoadMatrix)(_cs_transform->get_mat().get_data());
  9108. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  9109. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  9110. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  9111. glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  9112. GLPfv(TexGen)(GL_S, GL_EYE_PLANE, s_data);
  9113. GLPfv(TexGen)(GL_T, GL_EYE_PLANE, t_data);
  9114. GLPfv(TexGen)(GL_R, GL_EYE_PLANE, r_data);
  9115. GLPfv(TexGen)(GL_Q, GL_EYE_PLANE, q_data);
  9116. glEnable(GL_TEXTURE_GEN_S);
  9117. glEnable(GL_TEXTURE_GEN_T);
  9118. glEnable(GL_TEXTURE_GEN_R);
  9119. glEnable(GL_TEXTURE_GEN_Q);
  9120. glMatrixMode(GL_MODELVIEW);
  9121. glPopMatrix();
  9122. break;
  9123. case TexGenAttrib::M_world_position:
  9124. // We achieve world position coordinates by using the eye
  9125. // position mode, and loading the transform of the root
  9126. // node--thus putting the "eye" at the root.
  9127. {
  9128. glMatrixMode(GL_MODELVIEW);
  9129. glPushMatrix();
  9130. CPT(TransformState) root_transform = _cs_transform->compose(_scene_setup->get_world_transform());
  9131. GLPf(LoadMatrix)(root_transform->get_mat().get_data());
  9132. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  9133. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  9134. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  9135. glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  9136. GLPfv(TexGen)(GL_S, GL_EYE_PLANE, s_data);
  9137. GLPfv(TexGen)(GL_T, GL_EYE_PLANE, t_data);
  9138. GLPfv(TexGen)(GL_R, GL_EYE_PLANE, r_data);
  9139. GLPfv(TexGen)(GL_Q, GL_EYE_PLANE, q_data);
  9140. glEnable(GL_TEXTURE_GEN_S);
  9141. glEnable(GL_TEXTURE_GEN_T);
  9142. glEnable(GL_TEXTURE_GEN_R);
  9143. glEnable(GL_TEXTURE_GEN_Q);
  9144. glMatrixMode(GL_MODELVIEW);
  9145. glPopMatrix();
  9146. }
  9147. break;
  9148. case TexGenAttrib::M_point_sprite:
  9149. if (_supports_point_sprite) {
  9150. #ifdef OPENGLES
  9151. glTexEnvi(GL_POINT_SPRITE_OES, GL_COORD_REPLACE_OES, GL_TRUE);
  9152. #else
  9153. glTexEnvi(GL_POINT_SPRITE_ARB, GL_COORD_REPLACE_ARB, GL_TRUE);
  9154. #endif
  9155. got_point_sprites = true;
  9156. }
  9157. break;
  9158. case TexGenAttrib::M_constant:
  9159. // To generate a constant UV(w) coordinate everywhere, we use
  9160. // EYE_LINEAR mode, but we construct a special matrix that
  9161. // flattens the vertex position to zero and then adds our
  9162. // desired value.
  9163. {
  9164. const LTexCoord3 &v = _target_tex_gen->get_constant_value(stage);
  9165. glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  9166. glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  9167. glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  9168. glTexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  9169. LVecBase4 s(0.0f, 0.0f, 0.0f, v[0]);
  9170. LVecBase4 t(0.0f, 0.0f, 0.0f, v[1]);
  9171. LVecBase4 r(0.0f, 0.0f, 0.0f, v[2]);
  9172. GLPfv(TexGen)(GL_S, GL_OBJECT_PLANE, s.get_data());
  9173. GLPfv(TexGen)(GL_T, GL_OBJECT_PLANE, t.get_data());
  9174. GLPfv(TexGen)(GL_R, GL_OBJECT_PLANE, r.get_data());
  9175. GLPfv(TexGen)(GL_Q, GL_OBJECT_PLANE, q_data);
  9176. glEnable(GL_TEXTURE_GEN_S);
  9177. glEnable(GL_TEXTURE_GEN_T);
  9178. glEnable(GL_TEXTURE_GEN_R);
  9179. glEnable(GL_TEXTURE_GEN_Q);
  9180. }
  9181. break;
  9182. case TexGenAttrib::M_unused:
  9183. break;
  9184. }
  9185. #endif // OPENGLES
  9186. }
  9187. if (got_point_sprites != _tex_gen_point_sprite) {
  9188. _tex_gen_point_sprite = got_point_sprites;
  9189. #ifdef OPENGLES
  9190. if (_tex_gen_point_sprite) {
  9191. glEnable(GL_POINT_SPRITE_OES);
  9192. } else {
  9193. glDisable(GL_POINT_SPRITE_OES);
  9194. }
  9195. #else
  9196. if (_tex_gen_point_sprite) {
  9197. glEnable(GL_POINT_SPRITE_ARB);
  9198. } else {
  9199. glDisable(GL_POINT_SPRITE_ARB);
  9200. }
  9201. #endif // OPENGLES
  9202. }
  9203. report_my_gl_errors();
  9204. }
  9205. #endif // SUPPORT_FIXED_FUNCTION
  9206. ////////////////////////////////////////////////////////////////////
  9207. // Function: GLGraphicsStateGuardian::specify_texture
  9208. // Access: Protected
  9209. // Description: Specifies the texture parameters. Returns true if
  9210. // the texture may need to be reloaded. Pass non-NULL
  9211. // sampler argument to use different sampler settings.
  9212. ////////////////////////////////////////////////////////////////////
  9213. bool CLP(GraphicsStateGuardian)::
  9214. specify_texture(CLP(TextureContext) *gtc, const SamplerState &sampler) {
  9215. nassertr(gtc->_handle == 0 /* can't modify tex with active handle */, false);
  9216. Texture *tex = gtc->get_texture();
  9217. GLenum target = get_texture_target(tex->get_texture_type());
  9218. if (target == GL_NONE) {
  9219. // Unsupported target (e.g. 3-d texturing on GL 1.1).
  9220. return false;
  9221. }
  9222. #ifndef OPENGLES
  9223. if (target == GL_TEXTURE_BUFFER) {
  9224. // Buffer textures may not receive texture parameters.
  9225. return false;
  9226. }
  9227. #endif // OPENGLES
  9228. // Record the active sampler settings.
  9229. gtc->_active_sampler = sampler;
  9230. glTexParameteri(target, GL_TEXTURE_WRAP_S,
  9231. get_texture_wrap_mode(sampler.get_wrap_u()));
  9232. #ifndef OPENGLES
  9233. if (target != GL_TEXTURE_1D) {
  9234. glTexParameteri(target, GL_TEXTURE_WRAP_T,
  9235. get_texture_wrap_mode(sampler.get_wrap_v()));
  9236. }
  9237. #endif
  9238. #ifdef OPENGLES_2
  9239. if (target == GL_TEXTURE_3D_OES) {
  9240. glTexParameteri(target, GL_TEXTURE_WRAP_R_OES,
  9241. get_texture_wrap_mode(sampler.get_wrap_w()));
  9242. }
  9243. #endif
  9244. #ifndef OPENGLES
  9245. if (target == GL_TEXTURE_3D) {
  9246. glTexParameteri(target, GL_TEXTURE_WRAP_R,
  9247. get_texture_wrap_mode(sampler.get_wrap_w()));
  9248. }
  9249. LColor border_color = sampler.get_border_color();
  9250. call_glTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, border_color);
  9251. #endif // OPENGLES
  9252. SamplerState::FilterType minfilter = sampler.get_effective_minfilter();
  9253. SamplerState::FilterType magfilter = sampler.get_effective_magfilter();
  9254. bool uses_mipmaps = SamplerState::is_mipmap(minfilter) && !gl_ignore_mipmaps;
  9255. #ifndef NDEBUG
  9256. if (gl_force_mipmaps) {
  9257. minfilter = SamplerState::FT_linear_mipmap_linear;
  9258. magfilter = SamplerState::FT_linear;
  9259. uses_mipmaps = true;
  9260. }
  9261. #endif
  9262. if (!tex->might_have_ram_image()) {
  9263. // If it's a dynamically generated texture (that is, the RAM image
  9264. // isn't available so it didn't pass through the CPU), we should
  9265. // enable GL-generated mipmaps if we can.
  9266. if (!_supports_generate_mipmap) {
  9267. // However, if the GPU doesn't support mipmap generation, we
  9268. // have to turn it off.
  9269. uses_mipmaps = false;
  9270. }
  9271. }
  9272. glTexParameteri(target, GL_TEXTURE_MIN_FILTER,
  9273. get_texture_filter_type(minfilter, !uses_mipmaps));
  9274. glTexParameteri(target, GL_TEXTURE_MAG_FILTER,
  9275. get_texture_filter_type(magfilter, true));
  9276. // Set anisotropic filtering.
  9277. if (_supports_anisotropy) {
  9278. PN_stdfloat anisotropy = sampler.get_effective_anisotropic_degree();
  9279. anisotropy = min(anisotropy, _max_anisotropy);
  9280. anisotropy = max(anisotropy, (PN_stdfloat)1.0);
  9281. glTexParameterf(target, GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropy);
  9282. }
  9283. #ifndef OPENGLES_1
  9284. if (tex->get_format() == Texture::F_depth_stencil ||
  9285. tex->get_format() == Texture::F_depth_component ||
  9286. tex->get_format() == Texture::F_depth_component16 ||
  9287. tex->get_format() == Texture::F_depth_component24 ||
  9288. tex->get_format() == Texture::F_depth_component32) {
  9289. #ifdef SUPPORT_FIXED_FUNCTION
  9290. glTexParameteri(target, GL_DEPTH_TEXTURE_MODE_ARB, GL_INTENSITY);
  9291. #endif
  9292. if (_supports_shadow_filter) {
  9293. if ((sampler.get_magfilter() == SamplerState::FT_shadow) ||
  9294. (sampler.get_minfilter() == SamplerState::FT_shadow)) {
  9295. glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);
  9296. glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
  9297. } else {
  9298. glTexParameteri(target, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);
  9299. glTexParameteri(target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);
  9300. }
  9301. }
  9302. }
  9303. #endif
  9304. #ifndef OPENGLES
  9305. glTexParameterf(target, GL_TEXTURE_MIN_LOD, sampler.get_min_lod());
  9306. glTexParameterf(target, GL_TEXTURE_MAX_LOD, sampler.get_max_lod());
  9307. glTexParameterf(target, GL_TEXTURE_LOD_BIAS, sampler.get_lod_bias());
  9308. #endif
  9309. report_my_gl_errors();
  9310. if (uses_mipmaps && !gtc->_uses_mipmaps) {
  9311. // Suddenly we require mipmaps. This means the texture may need
  9312. // reloading.
  9313. return true;
  9314. }
  9315. return false;
  9316. }
  9317. ////////////////////////////////////////////////////////////////////
  9318. // Function: GLGraphicsStateGuardian::apply_texture
  9319. // Access: Protected
  9320. // Description: Updates OpenGL with the current information for this
  9321. // texture, and makes it the current texture available
  9322. // for rendering.
  9323. ////////////////////////////////////////////////////////////////////
  9324. bool CLP(GraphicsStateGuardian)::
  9325. apply_texture(CLP(TextureContext) *gtc) {
  9326. gtc->set_active(true);
  9327. GLenum target = get_texture_target(gtc->get_texture()->get_texture_type());
  9328. if (target == GL_NONE) {
  9329. return false;
  9330. }
  9331. if (gtc->_target != target) {
  9332. // The target has changed. That means we have to re-bind a new
  9333. // texture object.
  9334. gtc->reset_data();
  9335. gtc->_target = target;
  9336. }
  9337. glBindTexture(target, gtc->_index);
  9338. report_my_gl_errors();
  9339. return true;
  9340. }
  9341. ////////////////////////////////////////////////////////////////////
  9342. // Function: GLGraphicsStateGuardian::apply_sampler
  9343. // Access: Protected
  9344. // Description: Updates OpenGL with the current information for this
  9345. // sampler, and makes it the current sampler available
  9346. // for rendering. Use NULL to unbind the sampler.
  9347. //
  9348. // If the GSG doesn't support sampler objects, the
  9349. // sampler settings are applied to the given texture
  9350. // context instead.
  9351. ////////////////////////////////////////////////////////////////////
  9352. bool CLP(GraphicsStateGuardian)::
  9353. apply_sampler(GLuint unit, const SamplerState &sampler, CLP(TextureContext) *gtc) {
  9354. #ifndef OPENGLES
  9355. if (_supports_sampler_objects) {
  9356. // We support sampler objects. Prepare the sampler object and
  9357. // bind it to the indicated texture unit.
  9358. SamplerContext *sc = sampler.prepare_now(get_prepared_objects(), this);
  9359. nassertr(sc != (SamplerContext *)NULL, false);
  9360. CLP(SamplerContext) *gsc = DCAST(CLP(SamplerContext), sc);
  9361. gsc->enqueue_lru(&_prepared_objects->_sampler_object_lru);
  9362. _glBindSampler(unit, gsc->_index);
  9363. if (GLCAT.is_spam()) {
  9364. GLCAT.spam()
  9365. << "bind " << unit << " " << sampler << "\n";
  9366. }
  9367. } else
  9368. #endif // OPENGLES
  9369. {
  9370. // We don't support sampler objects. We'll have to bind the
  9371. // texture and change the texture parameters if they don't match.
  9372. if (gtc->_active_sampler != sampler) {
  9373. _glActiveTexture(GL_TEXTURE0 + unit);
  9374. apply_texture(gtc);
  9375. specify_texture(gtc, sampler);
  9376. }
  9377. }
  9378. if (sampler.uses_mipmaps() && !gtc->_uses_mipmaps) {
  9379. // The texture wasn't created with mipmaps, but we are trying
  9380. // to sample it with mipmaps. We will need to reload it.
  9381. apply_texture(gtc);
  9382. gtc->mark_needs_reload();
  9383. bool okflag = upload_texture(gtc, false, true);
  9384. if (!okflag) {
  9385. GLCAT.error()
  9386. << "Could not load " << *gtc->get_texture() << "\n";
  9387. return false;
  9388. }
  9389. }
  9390. report_my_gl_errors();
  9391. return true;
  9392. }
  9393. ////////////////////////////////////////////////////////////////////
  9394. // Function: GLGraphicsStateGuardian::upload_texture
  9395. // Access: Protected
  9396. // Description: Uploads the entire texture image to OpenGL, including
  9397. // all pages.
  9398. //
  9399. // The return value is true if successful, or false if
  9400. // the texture has no image.
  9401. ////////////////////////////////////////////////////////////////////
  9402. bool CLP(GraphicsStateGuardian)::
  9403. upload_texture(CLP(TextureContext) *gtc, bool force, bool uses_mipmaps) {
  9404. PStatGPUTimer timer(this, _load_texture_pcollector);
  9405. Texture *tex = gtc->get_texture();
  9406. if (_effective_incomplete_render && !force) {
  9407. bool has_image = _supports_compressed_texture ? tex->has_ram_image() : tex->has_uncompressed_ram_image();
  9408. if (!has_image && tex->might_have_ram_image() &&
  9409. tex->has_simple_ram_image() &&
  9410. !_loader.is_null()) {
  9411. // If we don't have the texture data right now, go get it, but in
  9412. // the meantime load a temporary simple image in its place.
  9413. async_reload_texture(gtc);
  9414. has_image = _supports_compressed_texture ? tex->has_ram_image() : tex->has_uncompressed_ram_image();
  9415. if (!has_image) {
  9416. if (gtc->was_simple_image_modified()) {
  9417. return upload_simple_texture(gtc);
  9418. }
  9419. return true;
  9420. }
  9421. }
  9422. }
  9423. CPTA_uchar image;
  9424. if (_supports_compressed_texture) {
  9425. image = tex->get_ram_image();
  9426. } else {
  9427. image = tex->get_uncompressed_ram_image();
  9428. }
  9429. Texture::CompressionMode image_compression;
  9430. if (image.is_null()) {
  9431. image_compression = Texture::CM_off;
  9432. } else {
  9433. image_compression = tex->get_ram_image_compression();
  9434. }
  9435. if (!get_supports_compressed_texture_format(image_compression)) {
  9436. image = tex->get_uncompressed_ram_image();
  9437. image_compression = Texture::CM_off;
  9438. }
  9439. int mipmap_bias = 0;
  9440. int width = tex->get_x_size();
  9441. int height = tex->get_y_size();
  9442. int depth = tex->get_z_size();
  9443. // If we'll use immutable texture storage, we have to pick a sized
  9444. // image format.
  9445. bool force_sized = (gl_immutable_texture_storage && _supports_tex_storage) ||
  9446. (tex->get_texture_type() == Texture::TT_buffer_texture);
  9447. GLint internal_format = get_internal_image_format(tex, force_sized);
  9448. GLint external_format = get_external_image_format(tex);
  9449. GLenum component_type = get_component_type(tex->get_component_type());
  9450. if (GLCAT.is_debug()) {
  9451. if (image.is_null()) {
  9452. GLCAT.debug()
  9453. << "loading texture with NULL image";
  9454. } else if (image_compression != Texture::CM_off) {
  9455. GLCAT.debug()
  9456. << "loading pre-compressed texture";
  9457. } else if (is_compressed_format(internal_format)) {
  9458. GLCAT.debug()
  9459. << "loading compressed texture";
  9460. } else {
  9461. GLCAT.debug()
  9462. << "loading uncompressed texture";
  9463. }
  9464. GLCAT.debug(false) << " " << tex->get_name() << "\n";
  9465. }
  9466. // Ensure that the texture fits within the GL's specified limits.
  9467. // Need to split dimensions because of texture arrays
  9468. int max_dimension_x;
  9469. int max_dimension_y;
  9470. int max_dimension_z;
  9471. switch (tex->get_texture_type()) {
  9472. case Texture::TT_3d_texture:
  9473. max_dimension_x = _max_3d_texture_dimension;
  9474. max_dimension_y = _max_3d_texture_dimension;
  9475. max_dimension_z = _max_3d_texture_dimension;
  9476. break;
  9477. case Texture::TT_cube_map:
  9478. max_dimension_x = _max_cube_map_dimension;
  9479. max_dimension_y = _max_cube_map_dimension;
  9480. max_dimension_z = 6;
  9481. break;
  9482. case Texture::TT_2d_texture_array:
  9483. max_dimension_x = _max_texture_dimension;
  9484. max_dimension_y = _max_texture_dimension;
  9485. max_dimension_z = _max_2d_texture_array_layers;
  9486. break;
  9487. case Texture::TT_buffer_texture:
  9488. max_dimension_x = _max_buffer_texture_size;
  9489. max_dimension_y = 1;
  9490. max_dimension_z = 1;
  9491. break;
  9492. default:
  9493. max_dimension_x = _max_texture_dimension;
  9494. max_dimension_y = _max_texture_dimension;
  9495. max_dimension_z = 1;
  9496. }
  9497. if (max_dimension_x == 0 || max_dimension_y == 0 || max_dimension_z == 0) {
  9498. // Guess this GL doesn't support cube mapping/3d textures/2d texture arrays.
  9499. report_my_gl_errors();
  9500. return false;
  9501. }
  9502. // If it doesn't fit, we have to reduce it on-the-fly. We do this
  9503. // by incrementing the mipmap_bias, so we're effectively loading a
  9504. // lower mipmap level. This requires generating the mipmaps on
  9505. // the CPU if they haven't already been generated. It would have
  9506. // been better if the user had specified max-texture-dimension to
  9507. // reduce the texture at load time instead; of course, the user
  9508. // doesn't always know ahead of time what the hardware limits are.
  9509. if ((max_dimension_x > 0 && max_dimension_y > 0 && max_dimension_z > 0) &&
  9510. image_compression == Texture::CM_off) {
  9511. while (tex->get_expected_mipmap_x_size(mipmap_bias) > max_dimension_x ||
  9512. tex->get_expected_mipmap_y_size(mipmap_bias) > max_dimension_y ||
  9513. tex->get_expected_mipmap_z_size(mipmap_bias) > max_dimension_z) {
  9514. ++mipmap_bias;
  9515. }
  9516. if (mipmap_bias >= tex->get_num_ram_mipmap_images()) {
  9517. // We need to generate some more mipmap images.
  9518. if (tex->has_ram_image()) {
  9519. tex->generate_ram_mipmap_images();
  9520. if (mipmap_bias >= tex->get_num_ram_mipmap_images()) {
  9521. // It didn't work. Send the smallest we've got, and hope
  9522. // for the best.
  9523. mipmap_bias = tex->get_num_ram_mipmap_images() - 1;
  9524. }
  9525. }
  9526. }
  9527. width = tex->get_expected_mipmap_x_size(mipmap_bias);
  9528. height = tex->get_expected_mipmap_y_size(mipmap_bias);
  9529. depth = tex->get_expected_mipmap_z_size(mipmap_bias);
  9530. if (mipmap_bias != 0) {
  9531. GLCAT.info()
  9532. << "Reducing image " << tex->get_name()
  9533. << " from " << tex->get_x_size() << " x " << tex->get_y_size()
  9534. << " x " << tex->get_z_size() << " to "
  9535. << width << " x " << height << " x " << depth << "\n";
  9536. }
  9537. }
  9538. if (image_compression != Texture::CM_off) {
  9539. Texture::QualityLevel quality_level = tex->get_effective_quality_level();
  9540. #ifndef OPENGLES
  9541. switch (quality_level) {
  9542. case Texture::QL_fastest:
  9543. glHint(GL_TEXTURE_COMPRESSION_HINT, GL_FASTEST);
  9544. break;
  9545. case Texture::QL_default:
  9546. case Texture::QL_normal:
  9547. glHint(GL_TEXTURE_COMPRESSION_HINT, GL_DONT_CARE);
  9548. break;
  9549. case Texture::QL_best:
  9550. glHint(GL_TEXTURE_COMPRESSION_HINT, GL_NICEST);
  9551. break;
  9552. }
  9553. #endif
  9554. }
  9555. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  9556. GLenum target = get_texture_target(tex->get_texture_type());
  9557. uses_mipmaps = (uses_mipmaps && !gl_ignore_mipmaps) || gl_force_mipmaps;
  9558. #ifndef OPENGLES
  9559. if (target == GL_TEXTURE_BUFFER) {
  9560. // Buffer textures may not have mipmaps.
  9561. uses_mipmaps = false;
  9562. }
  9563. #endif // OPENGLES
  9564. bool needs_reload = false;
  9565. if (!gtc->_has_storage ||
  9566. gtc->_uses_mipmaps != uses_mipmaps ||
  9567. gtc->_internal_format != internal_format ||
  9568. gtc->_width != width ||
  9569. gtc->_height != height ||
  9570. gtc->_depth != depth) {
  9571. // We need to reload a new GL Texture object.
  9572. needs_reload = true;
  9573. if (_use_object_labels) {
  9574. // This seems like a good time to assign a label for the debug messages.
  9575. const string &name = tex->get_name();
  9576. _glObjectLabel(GL_TEXTURE, gtc->_index, name.size(), name.data());
  9577. }
  9578. }
  9579. if (needs_reload && gtc->_immutable) {
  9580. GLCAT.warning() << "Attempt to modify texture with immutable storage, recreating texture.\n";
  9581. gtc->reset_data();
  9582. glBindTexture(target, gtc->_index);
  9583. }
  9584. #ifndef OPENGLES
  9585. if (target == GL_TEXTURE_BUFFER) {
  9586. // Buffer textures don't support mipmappping.
  9587. gtc->_generate_mipmaps = false;
  9588. if (gtc->_buffer == 0) {
  9589. // The buffer object wasn't created yet.
  9590. _glGenBuffers(1, &gtc->_buffer);
  9591. _glBindBuffer(GL_TEXTURE_BUFFER, gtc->_buffer);
  9592. _glTexBuffer(GL_TEXTURE_BUFFER, internal_format, gtc->_buffer);
  9593. needs_reload = true;
  9594. } else {
  9595. _glBindBuffer(GL_TEXTURE_BUFFER, gtc->_buffer);
  9596. if (gtc->_internal_format != internal_format) {
  9597. _glTexBuffer(GL_TEXTURE_BUFFER, internal_format, gtc->_buffer);
  9598. }
  9599. }
  9600. } else
  9601. #endif // !OPENGLES
  9602. if (needs_reload) {
  9603. // Figure out whether mipmaps will be generated by the GPU or by
  9604. // Panda (or not at all), and how many mipmap levels should be created.
  9605. gtc->_generate_mipmaps = false;
  9606. int num_levels = 1;
  9607. CPTA_uchar image = tex->get_ram_mipmap_image(mipmap_bias);
  9608. if (image.is_null()) {
  9609. // We don't even have a RAM image, so we have no choice but to let
  9610. // mipmaps be generated on the GPU.
  9611. if (uses_mipmaps) {
  9612. if (_supports_generate_mipmap) {
  9613. num_levels = tex->get_expected_num_mipmap_levels() - mipmap_bias;
  9614. gtc->_generate_mipmaps = true;
  9615. } else {
  9616. // If it can't, do without mipmaps.
  9617. num_levels = 1;
  9618. glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  9619. }
  9620. }
  9621. } else {
  9622. if (uses_mipmaps) {
  9623. num_levels = tex->get_num_ram_mipmap_images() - mipmap_bias;
  9624. if (num_levels <= 1) {
  9625. // No RAM mipmap levels available. Should we generate some?
  9626. if (!_supports_generate_mipmap || !driver_generate_mipmaps ||
  9627. image_compression != Texture::CM_off) {
  9628. // Yes, the GL can't or won't generate them, so we need to.
  9629. // Note that some drivers (nVidia) will *corrupt memory* if
  9630. // you ask them to generate mipmaps for a pre-compressed
  9631. // texture.
  9632. tex->generate_ram_mipmap_images();
  9633. num_levels = tex->get_num_ram_mipmap_images() - mipmap_bias;
  9634. }
  9635. }
  9636. if (num_levels <= 1) {
  9637. // We don't have mipmap levels in RAM. Ask the GL to generate
  9638. // them if it can.
  9639. if (_supports_generate_mipmap) {
  9640. num_levels = tex->get_expected_num_mipmap_levels() - mipmap_bias;
  9641. gtc->_generate_mipmaps = true;
  9642. } else {
  9643. // If it can't, do without mipmaps.
  9644. glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  9645. num_levels = 1;
  9646. }
  9647. }
  9648. }
  9649. }
  9650. #ifndef OPENGLES // OpenGL ES doesn't have GL_TEXTURE_MAX_LEVEL.
  9651. if (is_at_least_gl_version(1, 2)) {
  9652. // By the time we get here, we have a pretty good prediction for
  9653. // the number of mipmaps we're going to have, so tell the GL that's
  9654. // all it's going to get.
  9655. glTexParameteri(target, GL_TEXTURE_MAX_LEVEL, num_levels - 1);
  9656. }
  9657. #endif
  9658. #ifndef OPENGLES_2
  9659. if (gtc->_generate_mipmaps && _glGenerateMipmap == NULL) {
  9660. // The old, deprecated way to generate mipmaps.
  9661. glTexParameteri(target, GL_GENERATE_MIPMAP, GL_TRUE);
  9662. }
  9663. #endif
  9664. #if !defined(SUPPORT_FIXED_FUNCTION) && !defined(OPENGLES_2)
  9665. // Do we need to apply a swizzle mask to emulate these deprecated
  9666. // texture formats?
  9667. switch (tex->get_format()) {
  9668. case Texture::F_alpha:
  9669. glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_ONE);
  9670. glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, GL_ONE);
  9671. glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_ONE);
  9672. glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, GL_RED);
  9673. break;
  9674. case Texture::F_luminance:
  9675. glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_RED);
  9676. glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, GL_RED);
  9677. glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_RED);
  9678. glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, GL_ONE);
  9679. break;
  9680. case Texture::F_luminance_alpha:
  9681. glTexParameteri(target, GL_TEXTURE_SWIZZLE_R, GL_RED);
  9682. glTexParameteri(target, GL_TEXTURE_SWIZZLE_G, GL_RED);
  9683. glTexParameteri(target, GL_TEXTURE_SWIZZLE_B, GL_RED);
  9684. glTexParameteri(target, GL_TEXTURE_SWIZZLE_A, GL_GREEN);
  9685. break;
  9686. default:
  9687. break;
  9688. }
  9689. #endif
  9690. // Allocate immutable storage for the texture, after which we can subload it.
  9691. // Pre-allocating storage using glTexStorage is more efficient than using glTexImage
  9692. // to load all of the individual images one by one later, but we are not allowed to
  9693. // change the texture size or number of mipmap levels after this point.
  9694. if (gl_immutable_texture_storage && _supports_tex_storage && !gtc->_has_storage) {
  9695. if (GLCAT.is_debug()) {
  9696. GLCAT.debug()
  9697. << "allocating storage for texture " << tex->get_name() << ", " << width
  9698. << " x " << height << " x " << depth << ", mipmaps " << num_levels
  9699. << ", uses_mipmaps = " << uses_mipmaps << "\n";
  9700. }
  9701. switch (tex->get_texture_type()) {
  9702. case Texture::TT_buffer_texture:
  9703. // Won't get here, but squelch compiler warning
  9704. case Texture::TT_1d_texture:
  9705. _glTexStorage1D(target, num_levels, internal_format, width);
  9706. break;
  9707. case Texture::TT_2d_texture:
  9708. case Texture::TT_cube_map:
  9709. _glTexStorage2D(target, num_levels, internal_format, width, height);
  9710. break;
  9711. case Texture::TT_3d_texture:
  9712. case Texture::TT_2d_texture_array:
  9713. _glTexStorage3D(target, num_levels, internal_format, width, height, depth);
  9714. break;
  9715. }
  9716. gtc->_has_storage = true;
  9717. gtc->_immutable = true;
  9718. gtc->_uses_mipmaps = uses_mipmaps;
  9719. gtc->_internal_format = internal_format;
  9720. gtc->_width = width;
  9721. gtc->_height = height;
  9722. gtc->_depth = depth;
  9723. needs_reload = false;
  9724. }
  9725. } else {
  9726. // Maybe we need to generate mipmaps on the CPU.
  9727. if (!image.is_null() && uses_mipmaps) {
  9728. if (tex->get_num_ram_mipmap_images() - mipmap_bias <= 1) {
  9729. // No RAM mipmap levels available. Should we generate some?
  9730. if (!_supports_generate_mipmap || !driver_generate_mipmaps ||
  9731. image_compression != Texture::CM_off) {
  9732. // Yes, the GL can't or won't generate them, so we need to.
  9733. // Note that some drivers (nVidia) will *corrupt memory* if
  9734. // you ask them to generate mipmaps for a pre-compressed
  9735. // texture.
  9736. tex->generate_ram_mipmap_images();
  9737. }
  9738. }
  9739. }
  9740. }
  9741. bool success = true;
  9742. if (tex->get_texture_type() == Texture::TT_cube_map) {
  9743. // A cube map must load six different 2-d images (which are stored
  9744. // as the six pages of the system ram image).
  9745. if (!_supports_cube_map) {
  9746. report_my_gl_errors();
  9747. return false;
  9748. }
  9749. nassertr(target == GL_TEXTURE_CUBE_MAP, false);
  9750. success = success && upload_texture_image
  9751. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  9752. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_POSITIVE_X,
  9753. internal_format, external_format, component_type,
  9754. true, 0, image_compression);
  9755. success = success && upload_texture_image
  9756. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  9757. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
  9758. internal_format, external_format, component_type,
  9759. true, 1, image_compression);
  9760. success = success && upload_texture_image
  9761. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  9762. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
  9763. internal_format, external_format, component_type,
  9764. true, 2, image_compression);
  9765. success = success && upload_texture_image
  9766. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  9767. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
  9768. internal_format, external_format, component_type,
  9769. true, 3, image_compression);
  9770. success = success && upload_texture_image
  9771. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  9772. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
  9773. internal_format, external_format, component_type,
  9774. true, 4, image_compression);
  9775. success = success && upload_texture_image
  9776. (gtc, needs_reload, uses_mipmaps, mipmap_bias,
  9777. GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
  9778. internal_format, external_format, component_type,
  9779. true, 5, image_compression);
  9780. } else {
  9781. // Any other kind of texture can be loaded all at once.
  9782. success = upload_texture_image
  9783. (gtc, needs_reload, uses_mipmaps, mipmap_bias, target,
  9784. target, internal_format, external_format,
  9785. component_type, false, 0, image_compression);
  9786. }
  9787. if (gtc->_generate_mipmaps && _glGenerateMipmap != NULL &&
  9788. !image.is_null()) {
  9789. // We uploaded an image; we may need to generate mipmaps.
  9790. if (GLCAT.is_debug()) {
  9791. GLCAT.debug()
  9792. << "generating mipmaps for texture " << tex->get_name() << ", "
  9793. << width << " x " << height << " x " << depth
  9794. << ", uses_mipmaps = " << uses_mipmaps << "\n";
  9795. }
  9796. _glGenerateMipmap(target);
  9797. }
  9798. maybe_gl_finish();
  9799. if (success) {
  9800. if (needs_reload) {
  9801. gtc->_has_storage = true;
  9802. gtc->_uses_mipmaps = uses_mipmaps;
  9803. gtc->_internal_format = internal_format;
  9804. gtc->_width = width;
  9805. gtc->_height = height;
  9806. gtc->_depth = depth;
  9807. gtc->update_data_size_bytes(get_texture_memory_size(tex));
  9808. }
  9809. if (tex->get_post_load_store_cache()) {
  9810. tex->set_post_load_store_cache(false);
  9811. // OK, get the RAM image, and save it in a BamCache record.
  9812. if (do_extract_texture_data(gtc)) {
  9813. if (tex->has_ram_image()) {
  9814. BamCache *cache = BamCache::get_global_ptr();
  9815. PT(BamCacheRecord) record = cache->lookup(tex->get_fullpath(), "txo");
  9816. if (record != (BamCacheRecord *)NULL) {
  9817. record->set_data(tex, tex);
  9818. cache->store(record);
  9819. }
  9820. }
  9821. }
  9822. }
  9823. GraphicsEngine *engine = get_engine();
  9824. nassertr(engine != (GraphicsEngine *)NULL, false);
  9825. engine->texture_uploaded(tex);
  9826. gtc->mark_loaded();
  9827. report_my_gl_errors();
  9828. return true;
  9829. }
  9830. report_my_gl_errors();
  9831. return false;
  9832. }
  9833. ////////////////////////////////////////////////////////////////////
  9834. // Function: GLGraphicsStateGuardian::upload_texture_image
  9835. // Access: Protected
  9836. // Description: Loads a texture image, or one page of a cube map
  9837. // image, from system RAM to texture memory.
  9838. //
  9839. // texture_target is normally the same thing as
  9840. // page_target; both represent the GL target onto which
  9841. // the texture image is loaded, e.g. GL_TEXTURE_1D,
  9842. // GL_TEXTURE_2D, etc. The only time they may differ is
  9843. // in the case of cube mapping, in which case
  9844. // texture_target will be target for the overall
  9845. // texture, e.g. GL_TEXTURE_CUBE_MAP, and page_target
  9846. // will be the target for this particular page,
  9847. // e.g. GL_TEXTURE_CUBE_MAP_POSITIVE_X.
  9848. ////////////////////////////////////////////////////////////////////
  9849. bool CLP(GraphicsStateGuardian)::
  9850. upload_texture_image(CLP(TextureContext) *gtc, bool needs_reload,
  9851. bool uses_mipmaps, int mipmap_bias,
  9852. GLenum texture_target, GLenum page_target,
  9853. GLint internal_format,
  9854. GLint external_format, GLenum component_type,
  9855. bool one_page_only, int z,
  9856. Texture::CompressionMode image_compression) {
  9857. // Make sure the error stack is cleared out before we begin.
  9858. clear_my_gl_errors();
  9859. if (texture_target == GL_NONE) {
  9860. // Unsupported target (e.g. 3-d texturing on GL 1.1).
  9861. return false;
  9862. }
  9863. if (image_compression != Texture::CM_off && !_supports_compressed_texture) {
  9864. return false;
  9865. }
  9866. Texture *tex = gtc->get_texture();
  9867. nassertr(tex != (Texture *)NULL, false);
  9868. CPTA_uchar image = tex->get_ram_mipmap_image(mipmap_bias);
  9869. int width = tex->get_expected_mipmap_x_size(mipmap_bias);
  9870. int height = tex->get_expected_mipmap_y_size(mipmap_bias);
  9871. int depth = tex->get_expected_mipmap_z_size(mipmap_bias);
  9872. // Determine the number of images to upload.
  9873. int num_levels = 1;
  9874. if (uses_mipmaps) {
  9875. num_levels = tex->get_expected_num_mipmap_levels();
  9876. }
  9877. int num_ram_mipmap_levels = 0;
  9878. if (!image.is_null()) {
  9879. if (uses_mipmaps) {
  9880. num_ram_mipmap_levels = tex->get_num_ram_mipmap_images();
  9881. } else {
  9882. num_ram_mipmap_levels = 1;
  9883. }
  9884. }
  9885. #ifndef OPENGLES
  9886. if (needs_reload || num_ram_mipmap_levels > 0) {
  9887. // Make sure that any incoherent writes to this texture have been synced.
  9888. if (gtc->needs_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT)) {
  9889. issue_memory_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
  9890. }
  9891. }
  9892. #endif
  9893. if (!needs_reload) {
  9894. // Try to subload the image over the existing GL Texture object,
  9895. // possibly saving on texture memory fragmentation.
  9896. if (GLCAT.is_debug()) {
  9897. if (num_ram_mipmap_levels == 0) {
  9898. if (tex->has_clear_color()) {
  9899. GLCAT.debug()
  9900. << "clearing texture " << tex->get_name() << ", "
  9901. << width << " x " << height << " x " << depth << ", z = " << z
  9902. << ", uses_mipmaps = " << uses_mipmaps << ", clear_color = "
  9903. << tex->get_clear_color() << "\n";
  9904. } else {
  9905. GLCAT.debug()
  9906. << "not loading NULL image for texture " << tex->get_name()
  9907. << ", " << width << " x " << height << " x " << depth
  9908. << ", z = " << z << ", uses_mipmaps = " << uses_mipmaps << "\n";
  9909. }
  9910. } else {
  9911. GLCAT.debug()
  9912. << "updating image data of texture " << tex->get_name()
  9913. << ", " << width << " x " << height << " x " << depth
  9914. << ", z = " << z << ", mipmaps " << num_ram_mipmap_levels
  9915. << ", uses_mipmaps = " << uses_mipmaps << "\n";
  9916. }
  9917. }
  9918. for (int n = mipmap_bias; n < num_levels; ++n) {
  9919. // we grab the mipmap pointer first, if it is NULL we grab the
  9920. // normal mipmap image pointer which is a PTA_uchar
  9921. const unsigned char *image_ptr = (unsigned char*)tex->get_ram_mipmap_pointer(n);
  9922. CPTA_uchar ptimage;
  9923. if (image_ptr == (const unsigned char *)NULL) {
  9924. ptimage = tex->get_ram_mipmap_image(n);
  9925. if (ptimage.is_null()) {
  9926. if (n < num_ram_mipmap_levels) {
  9927. // We were told we'd have this many RAM mipmap images, but
  9928. // we don't. Raise a warning.
  9929. GLCAT.warning()
  9930. << "No mipmap level " << n << " defined for " << tex->get_name()
  9931. << "\n";
  9932. break;
  9933. }
  9934. if (tex->has_clear_color()) {
  9935. // The texture has a clear color, so we should fill this mipmap
  9936. // level to a solid color.
  9937. #ifndef OPENGLES
  9938. if (_supports_clear_texture) {
  9939. // We can do that with the convenient glClearTexImage function.
  9940. string clear_data = tex->get_clear_data();
  9941. _glClearTexImage(gtc->_index, n - mipmap_bias, external_format,
  9942. component_type, (void *)clear_data.data());
  9943. continue;
  9944. }
  9945. #endif // OPENGLES
  9946. // Ask the Texture class to create the mipmap level in RAM.
  9947. // It'll fill it in with the correct clear color, which we
  9948. // can then upload.
  9949. ptimage = tex->make_ram_mipmap_image(n);
  9950. } else {
  9951. // No clear color and no more images.
  9952. break;
  9953. }
  9954. }
  9955. image_ptr = ptimage;
  9956. }
  9957. PTA_uchar bgr_image;
  9958. size_t view_size = tex->get_ram_mipmap_view_size(n);
  9959. if (image_ptr != (const unsigned char *)NULL) {
  9960. const unsigned char *orig_image_ptr = image_ptr;
  9961. image_ptr += view_size * gtc->get_view();
  9962. if (one_page_only) {
  9963. view_size = tex->get_ram_mipmap_page_size(n);
  9964. image_ptr += view_size * z;
  9965. }
  9966. nassertr(image_ptr >= orig_image_ptr && image_ptr + view_size <= orig_image_ptr + tex->get_ram_mipmap_image_size(n), false);
  9967. if (!_supports_bgr && image_compression == Texture::CM_off) {
  9968. // If the GL doesn't claim to support BGR, we may have to reverse
  9969. // the component ordering of the image.
  9970. image_ptr = fix_component_ordering(bgr_image, image_ptr, view_size,
  9971. external_format, tex);
  9972. }
  9973. }
  9974. int width = tex->get_expected_mipmap_x_size(n);
  9975. int height = tex->get_expected_mipmap_y_size(n);
  9976. int depth = tex->get_expected_mipmap_z_size(n);
  9977. #ifdef DO_PSTATS
  9978. _data_transferred_pcollector.add_level(view_size);
  9979. #endif
  9980. switch (texture_target) {
  9981. #ifndef OPENGLES_1
  9982. case GL_TEXTURE_3D:
  9983. if (_supports_3d_texture) {
  9984. if (image_compression == Texture::CM_off) {
  9985. _glTexSubImage3D(page_target, n - mipmap_bias, 0, 0, 0, width, height, depth,
  9986. external_format, component_type, image_ptr);
  9987. } else {
  9988. _glCompressedTexSubImage3D(page_target, n - mipmap_bias, 0, 0, 0, width, height, depth,
  9989. external_format, view_size, image_ptr);
  9990. }
  9991. } else {
  9992. report_my_gl_errors();
  9993. return false;
  9994. }
  9995. break;
  9996. #endif // OPENGLES_1
  9997. #ifndef OPENGLES
  9998. case GL_TEXTURE_1D:
  9999. if (image_compression == Texture::CM_off) {
  10000. glTexSubImage1D(page_target, n - mipmap_bias, 0, width,
  10001. external_format, component_type, image_ptr);
  10002. } else {
  10003. _glCompressedTexSubImage1D(page_target, n - mipmap_bias, 0, width,
  10004. external_format, view_size, image_ptr);
  10005. }
  10006. break;
  10007. #endif // OPENGLES
  10008. #ifndef OPENGLES
  10009. case GL_TEXTURE_2D_ARRAY_EXT:
  10010. if (_supports_2d_texture_array) {
  10011. if (image_compression == Texture::CM_off) {
  10012. _glTexSubImage3D(page_target, n - mipmap_bias, 0, 0, 0, width, height, depth,
  10013. external_format, component_type, image_ptr);
  10014. } else {
  10015. _glCompressedTexSubImage3D(page_target, n - mipmap_bias, 0, 0, 0, width, height, depth,
  10016. external_format, view_size, image_ptr);
  10017. }
  10018. } else {
  10019. report_my_gl_errors();
  10020. return false;
  10021. }
  10022. break;
  10023. #endif // OPENGLES
  10024. #ifndef OPENGLES
  10025. case GL_TEXTURE_BUFFER:
  10026. if (_supports_buffer_texture) {
  10027. _glBufferSubData(GL_TEXTURE_BUFFER, 0, view_size, image_ptr);
  10028. } else {
  10029. report_my_gl_errors();
  10030. return false;
  10031. }
  10032. break;
  10033. #endif // OPENGLES
  10034. default:
  10035. if (image_compression == Texture::CM_off) {
  10036. if (n==0) {
  10037. // It's unfortunate that we can't adjust the width, too,
  10038. // but TexSubImage2D doesn't accept a row-stride parameter.
  10039. height = tex->get_y_size() - tex->get_pad_y_size();
  10040. }
  10041. glTexSubImage2D(page_target, n - mipmap_bias, 0, 0, width, height,
  10042. external_format, component_type, image_ptr);
  10043. } else {
  10044. _glCompressedTexSubImage2D(page_target, n - mipmap_bias, 0, 0, width, height,
  10045. external_format, view_size, image_ptr);
  10046. }
  10047. break;
  10048. }
  10049. }
  10050. // Did that fail? If it did, we'll immediately try again, this
  10051. // time loading the texture from scratch.
  10052. GLenum error_code = gl_get_error();
  10053. if (error_code != GL_NO_ERROR) {
  10054. if (GLCAT.is_debug()) {
  10055. GLCAT.debug()
  10056. << "GL texture subload failed for " << tex->get_name()
  10057. << " : " << get_error_string(error_code) << "\n";
  10058. }
  10059. needs_reload = true;
  10060. }
  10061. }
  10062. if (needs_reload) {
  10063. // Load the image up from scratch, creating a new GL Texture
  10064. // object.
  10065. if (GLCAT.is_debug()) {
  10066. GLCAT.debug()
  10067. << "loading new texture object for " << tex->get_name() << ", " << width
  10068. << " x " << height << " x " << depth << ", z = " << z << ", mipmaps "
  10069. << num_ram_mipmap_levels << ", uses_mipmaps = " << uses_mipmaps << "\n";
  10070. }
  10071. // If there is immutable storage, this is impossible to do, and we should
  10072. // not have gotten here at all.
  10073. nassertr(!gtc->_immutable, false);
  10074. if (num_ram_mipmap_levels == 0) {
  10075. if (GLCAT.is_debug()) {
  10076. GLCAT.debug()
  10077. << " (initializing NULL image)\n";
  10078. }
  10079. if ((external_format == GL_DEPTH_STENCIL) && get_supports_depth_stencil()) {
  10080. #ifdef OPENGLES
  10081. component_type = GL_UNSIGNED_INT_24_8_OES;
  10082. #else
  10083. component_type = GL_UNSIGNED_INT_24_8_EXT;
  10084. #endif
  10085. }
  10086. }
  10087. for (int n = mipmap_bias; n < num_levels; ++n) {
  10088. const unsigned char *image_ptr = (unsigned char*)tex->get_ram_mipmap_pointer(n);
  10089. CPTA_uchar ptimage;
  10090. if (image_ptr == (const unsigned char *)NULL) {
  10091. ptimage = tex->get_ram_mipmap_image(n);
  10092. if (ptimage.is_null()) {
  10093. if (n < num_ram_mipmap_levels) {
  10094. // We were told we'd have this many RAM mipmap images, but
  10095. // we don't. Raise a warning.
  10096. GLCAT.warning()
  10097. << "No mipmap level " << n << " defined for " << tex->get_name()
  10098. << "\n";
  10099. #ifndef OPENGLES
  10100. if (is_at_least_gl_version(1, 2)) {
  10101. // Tell the GL we have no more mipmaps for it to use.
  10102. glTexParameteri(texture_target, GL_TEXTURE_MAX_LEVEL, n - mipmap_bias);
  10103. }
  10104. #endif
  10105. break;
  10106. }
  10107. if (tex->has_clear_color()) {
  10108. // Ask the Texture class to create the mipmap level in RAM.
  10109. // It'll fill it in with the correct clear color, which we
  10110. // can then upload.
  10111. ptimage = tex->make_ram_mipmap_image(n);
  10112. }
  10113. }
  10114. image_ptr = ptimage;
  10115. }
  10116. PTA_uchar bgr_image;
  10117. size_t view_size = tex->get_ram_mipmap_view_size(n);
  10118. if (image_ptr != (const unsigned char *)NULL) {
  10119. const unsigned char *orig_image_ptr = image_ptr;
  10120. image_ptr += view_size * gtc->get_view();
  10121. if (one_page_only) {
  10122. view_size = tex->get_ram_mipmap_page_size(n);
  10123. image_ptr += view_size * z;
  10124. }
  10125. nassertr(image_ptr >= orig_image_ptr && image_ptr + view_size <= orig_image_ptr + tex->get_ram_mipmap_image_size(n), false);
  10126. if (!_supports_bgr && image_compression == Texture::CM_off) {
  10127. // If the GL doesn't claim to support BGR, we may have to reverse
  10128. // the component ordering of the image.
  10129. image_ptr = fix_component_ordering(bgr_image, image_ptr, view_size,
  10130. external_format, tex);
  10131. }
  10132. }
  10133. int width = tex->get_expected_mipmap_x_size(n);
  10134. int height = tex->get_expected_mipmap_y_size(n);
  10135. int depth = tex->get_expected_mipmap_z_size(n);
  10136. #ifdef DO_PSTATS
  10137. _data_transferred_pcollector.add_level(view_size);
  10138. #endif
  10139. switch (texture_target) {
  10140. #ifndef OPENGLES // 1-d textures not supported by OpenGL ES. Fall through.
  10141. case GL_TEXTURE_1D:
  10142. if (image_compression == Texture::CM_off) {
  10143. glTexImage1D(page_target, n - mipmap_bias, internal_format,
  10144. width, 0,
  10145. external_format, component_type, image_ptr);
  10146. } else {
  10147. _glCompressedTexImage1D(page_target, n - mipmap_bias, external_format, width,
  10148. 0, view_size, image_ptr);
  10149. }
  10150. break;
  10151. #endif // OPENGLES // OpenGL ES will fall through.
  10152. #ifdef OPENGLES_2
  10153. case GL_TEXTURE_3D_OES:
  10154. #endif
  10155. #ifndef OPENGLES
  10156. case GL_TEXTURE_3D:
  10157. #endif
  10158. #ifndef OPENGLES_1
  10159. if (_supports_3d_texture) {
  10160. if (image_compression == Texture::CM_off) {
  10161. _glTexImage3D(page_target, n - mipmap_bias, internal_format,
  10162. width, height, depth, 0,
  10163. external_format, component_type, image_ptr);
  10164. } else {
  10165. _glCompressedTexImage3D(page_target, n - mipmap_bias, external_format, width,
  10166. height, depth,
  10167. 0, view_size, image_ptr);
  10168. }
  10169. } else {
  10170. report_my_gl_errors();
  10171. return false;
  10172. }
  10173. break;
  10174. #endif
  10175. #ifndef OPENGLES
  10176. case GL_TEXTURE_2D_ARRAY_EXT:
  10177. if (_supports_2d_texture_array) {
  10178. if (image_compression == Texture::CM_off) {
  10179. _glTexImage3D(page_target, n - mipmap_bias, internal_format,
  10180. width, height, depth, 0,
  10181. external_format, component_type, image_ptr);
  10182. } else {
  10183. _glCompressedTexImage3D(page_target, n - mipmap_bias, external_format, width,
  10184. height, depth,
  10185. 0, view_size, image_ptr);
  10186. }
  10187. } else {
  10188. report_my_gl_errors();
  10189. return false;
  10190. }
  10191. break;
  10192. #endif // OPENGLES
  10193. #ifndef OPENGLES
  10194. case GL_TEXTURE_BUFFER:
  10195. if (_supports_buffer_texture) {
  10196. _glBufferData(GL_TEXTURE_BUFFER, view_size, image_ptr,
  10197. get_usage(tex->get_usage_hint()));
  10198. } else {
  10199. report_my_gl_errors();
  10200. return false;
  10201. }
  10202. break;
  10203. #endif // OPENGLES
  10204. default:
  10205. if (image_compression == Texture::CM_off) {
  10206. glTexImage2D(page_target, n - mipmap_bias, internal_format,
  10207. width, height, 0,
  10208. external_format, component_type, image_ptr);
  10209. } else {
  10210. _glCompressedTexImage2D(page_target, n - mipmap_bias, external_format,
  10211. width, height, 0, view_size, image_ptr);
  10212. }
  10213. }
  10214. }
  10215. // Report the error message explicitly if the GL texture creation
  10216. // failed.
  10217. GLenum error_code = gl_get_error();
  10218. if (error_code != GL_NO_ERROR) {
  10219. GLCAT.error()
  10220. << "GL texture creation failed for " << tex->get_name()
  10221. << " : " << get_error_string(error_code) << "\n";
  10222. gtc->_has_storage = false;
  10223. return false;
  10224. }
  10225. }
  10226. report_my_gl_errors();
  10227. return true;
  10228. }
  10229. ////////////////////////////////////////////////////////////////////
  10230. // Function: GLGraphicsStateGuardian::upload_simple_texture
  10231. // Access: Protected
  10232. // Description: This is used as a standin for upload_texture
  10233. // when the texture in question is unavailable (e.g. it
  10234. // hasn't yet been loaded from disk). Until the texture
  10235. // image itself becomes available, we will render the
  10236. // texture's "simple" image--a sharply reduced version
  10237. // of the same texture.
  10238. ////////////////////////////////////////////////////////////////////
  10239. bool CLP(GraphicsStateGuardian)::
  10240. upload_simple_texture(CLP(TextureContext) *gtc) {
  10241. report_my_gl_errors();
  10242. PStatGPUTimer timer(this, _load_texture_pcollector);
  10243. Texture *tex = gtc->get_texture();
  10244. nassertr(tex != (Texture *)NULL, false);
  10245. int internal_format = GL_RGBA;
  10246. #ifdef OPENGLES_2
  10247. int external_format = GL_RGBA;
  10248. #else
  10249. int external_format = GL_BGRA;
  10250. #endif
  10251. const unsigned char *image_ptr = tex->get_simple_ram_image();
  10252. if (image_ptr == (const unsigned char *)NULL) {
  10253. return false;
  10254. }
  10255. size_t image_size = tex->get_simple_ram_image_size();
  10256. PTA_uchar bgr_image;
  10257. if (!_supports_bgr) {
  10258. // If the GL doesn't claim to support BGR, we may have to reverse
  10259. // the component ordering of the image.
  10260. external_format = GL_RGBA;
  10261. image_ptr = fix_component_ordering(bgr_image, image_ptr, image_size,
  10262. external_format, tex);
  10263. }
  10264. int width = tex->get_simple_x_size();
  10265. int height = tex->get_simple_y_size();
  10266. int component_type = GL_UNSIGNED_BYTE;
  10267. if (GLCAT.is_debug()) {
  10268. GLCAT.debug()
  10269. << "loading simple image for " << tex->get_name() << "\n";
  10270. }
  10271. #ifndef OPENGLES
  10272. // Turn off mipmaps for the simple texture.
  10273. if (tex->uses_mipmaps()) {
  10274. if (is_at_least_gl_version(1, 2)) {
  10275. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
  10276. }
  10277. }
  10278. #endif
  10279. #ifdef DO_PSTATS
  10280. _data_transferred_pcollector.add_level(image_size);
  10281. #endif
  10282. glTexImage2D(GL_TEXTURE_2D, 0, internal_format,
  10283. width, height, 0,
  10284. external_format, component_type, image_ptr);
  10285. gtc->mark_simple_loaded();
  10286. report_my_gl_errors();
  10287. return true;
  10288. }
  10289. ////////////////////////////////////////////////////////////////////
  10290. // Function: GLGraphicsStateGuardian::get_texture_memory_size
  10291. // Access: Protected
  10292. // Description: Asks OpenGL how much texture memory is consumed by
  10293. // the indicated texture (which is also the
  10294. // currently-selected texture).
  10295. ////////////////////////////////////////////////////////////////////
  10296. size_t CLP(GraphicsStateGuardian)::
  10297. get_texture_memory_size(Texture *tex) {
  10298. #ifdef OPENGLES // Texture querying not supported on OpenGL ES.
  10299. int width = tex->get_x_size();
  10300. int height = tex->get_y_size();
  10301. int depth = 1;
  10302. int scale = 1;
  10303. bool has_mipmaps = tex->uses_mipmaps();
  10304. size_t num_bytes = 2; // Temporary assumption?
  10305. #else
  10306. GLenum target = get_texture_target(tex->get_texture_type());
  10307. GLenum page_target = target;
  10308. GLint scale = 1;
  10309. if (target == GL_TEXTURE_CUBE_MAP) {
  10310. // We need a particular page to get the level parameter from.
  10311. page_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
  10312. scale = 6;
  10313. } else if (target == GL_TEXTURE_BUFFER) {
  10314. // In the case of buffer textures, we provided the size to begin with,
  10315. // so no point in querying anything. Plus, glGetTexParameter is not even
  10316. // supported for buffer textures.
  10317. return tex->get_expected_ram_image_size();
  10318. }
  10319. GLint minfilter;
  10320. glGetTexParameteriv(target, GL_TEXTURE_MIN_FILTER, &minfilter);
  10321. bool has_mipmaps = is_mipmap_filter(minfilter);
  10322. clear_my_gl_errors();
  10323. GLint internal_format;
  10324. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_INTERNAL_FORMAT, &internal_format);
  10325. if (is_compressed_format(internal_format)) {
  10326. // Try to get the compressed size.
  10327. GLint image_size;
  10328. glGetTexLevelParameteriv(page_target, 0,
  10329. GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &image_size);
  10330. GLenum error_code = gl_get_error();
  10331. if (error_code != GL_NO_ERROR) {
  10332. if (GLCAT.is_debug()) {
  10333. GLCAT.debug()
  10334. << "Couldn't get compressed size for " << tex->get_name()
  10335. << " : " << get_error_string(error_code) << "\n";
  10336. }
  10337. // Fall through to the noncompressed case.
  10338. } else {
  10339. return image_size * scale;
  10340. }
  10341. }
  10342. // OK, get the noncompressed size.
  10343. GLint red_size, green_size, blue_size, alpha_size,
  10344. luminance_size, intensity_size;
  10345. GLint depth_size = 0;
  10346. glGetTexLevelParameteriv(page_target, 0,
  10347. GL_TEXTURE_RED_SIZE, &red_size);
  10348. glGetTexLevelParameteriv(page_target, 0,
  10349. GL_TEXTURE_GREEN_SIZE, &green_size);
  10350. glGetTexLevelParameteriv(page_target, 0,
  10351. GL_TEXTURE_BLUE_SIZE, &blue_size);
  10352. glGetTexLevelParameteriv(page_target, 0,
  10353. GL_TEXTURE_ALPHA_SIZE, &alpha_size);
  10354. glGetTexLevelParameteriv(page_target, 0,
  10355. GL_TEXTURE_LUMINANCE_SIZE, &luminance_size);
  10356. glGetTexLevelParameteriv(page_target, 0,
  10357. GL_TEXTURE_INTENSITY_SIZE, &intensity_size);
  10358. if (_supports_depth_texture) {
  10359. glGetTexLevelParameteriv(page_target, 0,
  10360. GL_TEXTURE_DEPTH_SIZE, &depth_size);
  10361. }
  10362. GLint width = 1, height = 1, depth = 1;
  10363. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_WIDTH, &width);
  10364. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_HEIGHT, &height);
  10365. if (_supports_3d_texture || _supports_2d_texture_array) {
  10366. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_DEPTH, &depth);
  10367. }
  10368. report_my_gl_errors();
  10369. size_t num_bits = (red_size + green_size + blue_size + alpha_size + luminance_size + intensity_size + depth_size);
  10370. size_t num_bytes = (num_bits + 7) / 8;
  10371. #endif // OPENGLES
  10372. size_t result = num_bytes * width * height * depth * scale;
  10373. if (has_mipmaps) {
  10374. result = (result * 4) / 3;
  10375. }
  10376. return result;
  10377. }
  10378. ////////////////////////////////////////////////////////////////////
  10379. // Function: GLGraphicsStateGuardian::check_nonresident_texture
  10380. // Access: Private
  10381. // Description: Checks the list of resident texture objects to see if
  10382. // any have recently been evicted.
  10383. ////////////////////////////////////////////////////////////////////
  10384. void CLP(GraphicsStateGuardian)::
  10385. check_nonresident_texture(BufferContextChain &chain) {
  10386. #ifndef OPENGLES // Residency queries not supported by OpenGL ES.
  10387. size_t num_textures = chain.get_count();
  10388. if (num_textures == 0) {
  10389. return;
  10390. }
  10391. CLP(TextureContext) **gtc_list = (CLP(TextureContext) **)alloca(num_textures * sizeof(CLP(TextureContext) *));
  10392. GLuint *texture_list = (GLuint *)alloca(num_textures * sizeof(GLuint));
  10393. size_t ti = 0;
  10394. BufferContext *node = chain.get_first();
  10395. while (node != (BufferContext *)NULL) {
  10396. CLP(TextureContext) *gtc = DCAST(CLP(TextureContext), node);
  10397. gtc_list[ti] = gtc;
  10398. texture_list[ti] = gtc->_index;
  10399. node = node->get_next();
  10400. ++ti;
  10401. }
  10402. nassertv(ti == num_textures);
  10403. GLboolean *results = (GLboolean *)alloca(num_textures * sizeof(GLboolean));
  10404. bool all_resident = (glAreTexturesResident(num_textures, texture_list, results) != 0);
  10405. report_my_gl_errors();
  10406. if (!all_resident) {
  10407. // Some are now nonresident.
  10408. for (ti = 0; ti < num_textures; ++ti) {
  10409. if (!results[ti]) {
  10410. gtc_list[ti]->set_resident(false);
  10411. }
  10412. }
  10413. }
  10414. #endif // OPENGLES
  10415. }
  10416. ////////////////////////////////////////////////////////////////////
  10417. // Function: GLGraphicsStateGuardian::do_extract_texture_data
  10418. // Access: Protected
  10419. // Description: The internal implementation of
  10420. // extract_texture_data(), given an already-created
  10421. // TextureContext.
  10422. ////////////////////////////////////////////////////////////////////
  10423. bool CLP(GraphicsStateGuardian)::
  10424. do_extract_texture_data(CLP(TextureContext) *gtc) {
  10425. report_my_gl_errors();
  10426. GLenum target = gtc->_target;
  10427. if (target == GL_NONE) {
  10428. return false;
  10429. }
  10430. #ifndef OPENGLES
  10431. // Make sure any incoherent writes to the texture have been synced.
  10432. if (gtc->needs_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT)) {
  10433. issue_memory_barrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
  10434. }
  10435. #endif
  10436. glBindTexture(target, gtc->_index);
  10437. Texture *tex = gtc->get_texture();
  10438. GLint wrap_u, wrap_v, wrap_w;
  10439. GLint minfilter, magfilter;
  10440. GLfloat border_color[4];
  10441. glGetTexParameteriv(target, GL_TEXTURE_WRAP_S, &wrap_u);
  10442. glGetTexParameteriv(target, GL_TEXTURE_WRAP_T, &wrap_v);
  10443. wrap_w = GL_REPEAT;
  10444. if (_supports_3d_texture) {
  10445. #ifdef OPENGLES_2
  10446. glGetTexParameteriv(target, GL_TEXTURE_WRAP_R_OES, &wrap_w);
  10447. #endif
  10448. #ifndef OPENGLES
  10449. glGetTexParameteriv(target, GL_TEXTURE_WRAP_R, &wrap_w);
  10450. #endif
  10451. }
  10452. if (_supports_2d_texture_array) {
  10453. #ifndef OPENGLES
  10454. glGetTexParameteriv(target, GL_TEXTURE_WRAP_R, &wrap_w);
  10455. #endif
  10456. }
  10457. glGetTexParameteriv(target, GL_TEXTURE_MIN_FILTER, &minfilter);
  10458. glGetTexParameteriv(target, GL_TEXTURE_MAG_FILTER, &magfilter);
  10459. #ifndef OPENGLES
  10460. glGetTexParameterfv(target, GL_TEXTURE_BORDER_COLOR, border_color);
  10461. #endif
  10462. GLenum page_target = target;
  10463. if (target == GL_TEXTURE_CUBE_MAP) {
  10464. // We need a particular page to get the level parameter from.
  10465. page_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X;
  10466. }
  10467. GLint width = gtc->_width, height = gtc->_height, depth = gtc->_depth;
  10468. #ifndef OPENGLES
  10469. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_WIDTH, &width);
  10470. if (target != GL_TEXTURE_1D) {
  10471. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_HEIGHT, &height);
  10472. }
  10473. if (_supports_3d_texture && target == GL_TEXTURE_3D) {
  10474. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_DEPTH, &depth);
  10475. }
  10476. #ifndef OPENGLES
  10477. else if (_supports_2d_texture_array && target == GL_TEXTURE_2D_ARRAY_EXT) {
  10478. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_DEPTH, &depth);
  10479. }
  10480. #endif
  10481. else if (target == GL_TEXTURE_CUBE_MAP) {
  10482. depth = 6;
  10483. }
  10484. #endif
  10485. clear_my_gl_errors();
  10486. if (width <= 0 || height <= 0 || depth <= 0) {
  10487. GLCAT.error()
  10488. << "No texture data for " << tex->get_name() << "\n";
  10489. return false;
  10490. }
  10491. GLint internal_format = GL_RGBA;
  10492. #ifndef OPENGLES
  10493. glGetTexLevelParameteriv(page_target, 0, GL_TEXTURE_INTERNAL_FORMAT, &internal_format);
  10494. #endif // OPENGLES
  10495. // Make sure we were able to query those parameters properly.
  10496. GLenum error_code = gl_get_error();
  10497. if (error_code != GL_NO_ERROR) {
  10498. GLCAT.error()
  10499. << "Unable to query texture parameters for " << tex->get_name()
  10500. << " : " << get_error_string(error_code) << "\n";
  10501. return false;
  10502. }
  10503. Texture::ComponentType type = Texture::T_unsigned_byte;
  10504. Texture::Format format = Texture::F_rgb;
  10505. Texture::CompressionMode compression = Texture::CM_off;
  10506. switch (internal_format) {
  10507. #ifndef OPENGLES
  10508. case GL_COLOR_INDEX:
  10509. format = Texture::F_color_index;
  10510. break;
  10511. #endif
  10512. #if GL_DEPTH_COMPONENT != GL_DEPTH_COMPONENT24
  10513. case GL_DEPTH_COMPONENT:
  10514. #endif
  10515. case GL_DEPTH_COMPONENT16:
  10516. case GL_DEPTH_COMPONENT24:
  10517. case GL_DEPTH_COMPONENT32:
  10518. type = Texture::T_unsigned_short;
  10519. format = Texture::F_depth_component;
  10520. break;
  10521. #ifndef OPENGLES
  10522. case GL_DEPTH_COMPONENT32F:
  10523. type = Texture::T_float;
  10524. format = Texture::F_depth_component;
  10525. break;
  10526. #endif
  10527. case GL_DEPTH_STENCIL:
  10528. case GL_DEPTH24_STENCIL8:
  10529. type = Texture::T_unsigned_int_24_8;
  10530. format = Texture::F_depth_stencil;
  10531. break;
  10532. #ifndef OPENGLES
  10533. case GL_DEPTH32F_STENCIL8:
  10534. type = Texture::T_float;
  10535. format = Texture::F_depth_stencil;
  10536. break;
  10537. #endif
  10538. case GL_RGBA:
  10539. case 4:
  10540. format = Texture::F_rgba;
  10541. break;
  10542. case GL_RGBA4:
  10543. format = Texture::F_rgba4;
  10544. break;
  10545. #ifdef OPENGLES
  10546. case GL_RGBA8_OES:
  10547. format = Texture::F_rgba8;
  10548. break;
  10549. #else
  10550. case GL_RGBA8:
  10551. format = Texture::F_rgba8;
  10552. break;
  10553. #endif
  10554. #ifndef OPENGLES
  10555. case GL_RGBA12:
  10556. type = Texture::T_unsigned_short;
  10557. format = Texture::F_rgba12;
  10558. break;
  10559. #endif
  10560. case GL_RGB:
  10561. case 3:
  10562. format = Texture::F_rgb;
  10563. break;
  10564. #ifndef OPENGLES
  10565. case GL_RGB5:
  10566. format = Texture::F_rgb5;
  10567. break;
  10568. #endif
  10569. case GL_RGB5_A1:
  10570. format = Texture::F_rgba5;
  10571. break;
  10572. #ifndef OPENGLES
  10573. case GL_RGB8:
  10574. format = Texture::F_rgb8;
  10575. break;
  10576. case GL_RGB12:
  10577. format = Texture::F_rgb12;
  10578. break;
  10579. case GL_RGBA16:
  10580. format = Texture::F_rgba16;
  10581. break;
  10582. case GL_R3_G3_B2:
  10583. format = Texture::F_rgb332;
  10584. break;
  10585. case GL_R8I:
  10586. format = Texture::F_r8i;
  10587. break;
  10588. case GL_RG8I:
  10589. format = Texture::F_rg8i;
  10590. break;
  10591. case GL_RGB8I:
  10592. format = Texture::F_rgb8i;
  10593. break;
  10594. case GL_RGBA8I:
  10595. format = Texture::F_rgba8i;
  10596. break;
  10597. case GL_R8UI:
  10598. type = Texture::T_unsigned_byte;
  10599. format = Texture::F_r8i;
  10600. break;
  10601. case GL_RG8UI:
  10602. type = Texture::T_unsigned_byte;
  10603. format = Texture::F_rg8i;
  10604. break;
  10605. case GL_RGB8UI:
  10606. type = Texture::T_unsigned_byte;
  10607. format = Texture::F_rgb8i;
  10608. break;
  10609. case GL_RGBA8UI:
  10610. type = Texture::T_unsigned_byte;
  10611. format = Texture::F_rgba8i;
  10612. break;
  10613. #endif
  10614. #ifndef OPENGLES_1
  10615. case GL_RGBA16F:
  10616. type = Texture::T_float;
  10617. format = Texture::F_rgba16;
  10618. break;
  10619. case GL_RGB16F:
  10620. type = Texture::T_float;
  10621. format = Texture::F_rgb16;
  10622. break;
  10623. case GL_RG16F:
  10624. type = Texture::T_float;
  10625. format = Texture::F_rg16;
  10626. break;
  10627. case GL_R16F:
  10628. type = Texture::T_float;
  10629. format = Texture::F_r16;
  10630. break;
  10631. case GL_RGBA32F:
  10632. type = Texture::T_float;
  10633. format = Texture::F_rgba32;
  10634. break;
  10635. case GL_RGB32F:
  10636. type = Texture::T_float;
  10637. format = Texture::F_rgb32;
  10638. break;
  10639. case GL_RG32F:
  10640. type = Texture::T_float;
  10641. format = Texture::F_rg32;
  10642. break;
  10643. case GL_R32F:
  10644. type = Texture::T_float;
  10645. format = Texture::F_r32;
  10646. break;
  10647. #endif
  10648. #ifndef OPENGLES
  10649. case GL_RGB16:
  10650. type = Texture::T_unsigned_short;
  10651. format = Texture::F_rgb16;
  10652. break;
  10653. case GL_RG16:
  10654. type = Texture::T_unsigned_short;
  10655. format = Texture::F_rg16;
  10656. break;
  10657. case GL_R16:
  10658. type = Texture::T_unsigned_short;
  10659. format = Texture::F_r16;
  10660. break;
  10661. #endif
  10662. #ifdef OPENGLES_2
  10663. case GL_RED_EXT:
  10664. case GL_R8_EXT:
  10665. format = Texture::F_red;
  10666. break;
  10667. #endif
  10668. #ifndef OPENGLES
  10669. case GL_R32I:
  10670. type = Texture::T_int;
  10671. format = Texture::F_r32i;
  10672. break;
  10673. #endif
  10674. #ifndef OPENGLES
  10675. case GL_RED:
  10676. format = Texture::F_red;
  10677. break;
  10678. case GL_GREEN:
  10679. format = Texture::F_green;
  10680. break;
  10681. case GL_BLUE:
  10682. format = Texture::F_blue;
  10683. break;
  10684. #endif // OPENGLES
  10685. case GL_ALPHA:
  10686. format = Texture::F_alpha;
  10687. break;
  10688. case GL_LUMINANCE:
  10689. #ifndef OPENGLES
  10690. case GL_LUMINANCE16:
  10691. case GL_LUMINANCE16F_ARB:
  10692. #endif
  10693. case 1:
  10694. format = Texture::F_luminance;
  10695. break;
  10696. case GL_LUMINANCE_ALPHA:
  10697. #ifndef OPENGLES
  10698. case GL_LUMINANCE_ALPHA16F_ARB:
  10699. #endif
  10700. case 2:
  10701. format = Texture::F_luminance_alpha;
  10702. break;
  10703. #ifndef OPENGLES_1
  10704. case GL_SRGB:
  10705. #ifndef OPENGLES
  10706. case GL_SRGB8:
  10707. #endif
  10708. format = Texture::F_srgb;
  10709. break;
  10710. case GL_SRGB_ALPHA:
  10711. case GL_SRGB8_ALPHA8:
  10712. format = Texture::F_srgb_alpha;
  10713. break;
  10714. #endif // OPENGLES_1
  10715. #ifndef OPENGLES
  10716. case GL_SLUMINANCE:
  10717. case GL_SLUMINANCE8:
  10718. format = Texture::F_sluminance;
  10719. break;
  10720. case GL_SLUMINANCE_ALPHA:
  10721. case GL_SLUMINANCE8_ALPHA8:
  10722. format = Texture::F_sluminance_alpha;
  10723. break;
  10724. #endif // OPENGLES
  10725. #ifndef OPENGLES
  10726. case GL_COMPRESSED_RGB:
  10727. format = Texture::F_rgb;
  10728. compression = Texture::CM_on;
  10729. break;
  10730. case GL_COMPRESSED_RGBA:
  10731. format = Texture::F_rgba;
  10732. compression = Texture::CM_on;
  10733. break;
  10734. case GL_COMPRESSED_ALPHA:
  10735. format = Texture::F_alpha;
  10736. compression = Texture::CM_on;
  10737. break;
  10738. case GL_COMPRESSED_LUMINANCE:
  10739. format = Texture::F_luminance;
  10740. compression = Texture::CM_on;
  10741. break;
  10742. case GL_COMPRESSED_LUMINANCE_ALPHA:
  10743. format = Texture::F_luminance_alpha;
  10744. compression = Texture::CM_on;
  10745. break;
  10746. case GL_COMPRESSED_SRGB:
  10747. format = Texture::F_srgb;
  10748. compression = Texture::CM_on;
  10749. break;
  10750. case GL_COMPRESSED_SRGB_ALPHA:
  10751. format = Texture::F_srgb_alpha;
  10752. compression = Texture::CM_on;
  10753. break;
  10754. case GL_COMPRESSED_SLUMINANCE:
  10755. format = Texture::F_sluminance;
  10756. compression = Texture::CM_on;
  10757. break;
  10758. case GL_COMPRESSED_SLUMINANCE_ALPHA:
  10759. format = Texture::F_sluminance_alpha;
  10760. compression = Texture::CM_on;
  10761. break;
  10762. #endif
  10763. case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
  10764. format = Texture::F_rgb;
  10765. compression = Texture::CM_dxt1;
  10766. break;
  10767. case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
  10768. format = Texture::F_rgbm;
  10769. compression = Texture::CM_dxt1;
  10770. break;
  10771. #ifndef OPENGLES
  10772. case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
  10773. format = Texture::F_srgb;
  10774. compression = Texture::CM_dxt1;
  10775. break;
  10776. case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
  10777. format = Texture::F_srgb_alpha;
  10778. compression = Texture::CM_dxt1;
  10779. break;
  10780. #endif
  10781. #ifdef OPENGLES
  10782. case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
  10783. format = Texture::F_rgb;
  10784. compression = Texture::CM_pvr1_2bpp;
  10785. break;
  10786. case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
  10787. format = Texture::F_rgba;
  10788. compression = Texture::CM_pvr1_2bpp;
  10789. break;
  10790. case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
  10791. format = Texture::F_rgb;
  10792. compression = Texture::CM_pvr1_4bpp;
  10793. break;
  10794. case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
  10795. format = Texture::F_rgba;
  10796. compression = Texture::CM_pvr1_4bpp;
  10797. break;
  10798. #else
  10799. case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
  10800. format = Texture::F_rgba;
  10801. compression = Texture::CM_dxt3;
  10802. break;
  10803. case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
  10804. format = Texture::F_rgba;
  10805. compression = Texture::CM_dxt5;
  10806. break;
  10807. case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
  10808. format = Texture::F_srgb_alpha;
  10809. compression = Texture::CM_dxt3;
  10810. break;
  10811. case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
  10812. format = Texture::F_srgb_alpha;
  10813. compression = Texture::CM_dxt5;
  10814. break;
  10815. case GL_COMPRESSED_RGB_FXT1_3DFX:
  10816. format = Texture::F_rgb;
  10817. compression = Texture::CM_fxt1;
  10818. break;
  10819. case GL_COMPRESSED_RGBA_FXT1_3DFX:
  10820. format = Texture::F_rgba;
  10821. compression = Texture::CM_fxt1;
  10822. break;
  10823. #endif
  10824. default:
  10825. GLCAT.warning()
  10826. << "Unhandled internal format for " << tex->get_name()
  10827. << " : " << hex << "0x" << internal_format << dec << "\n";
  10828. return false;
  10829. }
  10830. // We don't want to call setup_texture() again; that resets too
  10831. // much. Instead, we'll just set the individual components.
  10832. tex->set_x_size(width);
  10833. tex->set_y_size(height);
  10834. tex->set_z_size(depth);
  10835. tex->set_component_type(type);
  10836. tex->set_format(format);
  10837. tex->set_wrap_u(get_panda_wrap_mode(wrap_u));
  10838. tex->set_wrap_v(get_panda_wrap_mode(wrap_v));
  10839. tex->set_wrap_w(get_panda_wrap_mode(wrap_w));
  10840. tex->set_border_color(LColor(border_color[0], border_color[1],
  10841. border_color[2], border_color[3]));
  10842. tex->set_minfilter(get_panda_filter_type(minfilter));
  10843. // tex->set_magfilter(get_panda_filter_type(magfilter));
  10844. PTA_uchar image;
  10845. size_t page_size = 0;
  10846. if (!extract_texture_image(image, page_size, tex, target, page_target,
  10847. type, compression, 0)) {
  10848. return false;
  10849. }
  10850. tex->set_ram_image(image, compression, page_size);
  10851. if (gtc->_uses_mipmaps) {
  10852. // Also get the mipmap levels.
  10853. GLint num_expected_levels = tex->get_expected_num_mipmap_levels();
  10854. GLint highest_level = num_expected_levels;
  10855. #ifndef OPENGLES
  10856. if (is_at_least_gl_version(1, 2)) {
  10857. glGetTexParameteriv(target, GL_TEXTURE_MAX_LEVEL, &highest_level);
  10858. highest_level = min(highest_level, num_expected_levels);
  10859. }
  10860. #endif
  10861. for (int n = 1; n <= highest_level; ++n) {
  10862. if (!extract_texture_image(image, page_size, tex, target, page_target,
  10863. type, compression, n)) {
  10864. return false;
  10865. }
  10866. tex->set_ram_mipmap_image(n, image, page_size);
  10867. }
  10868. }
  10869. return true;
  10870. }
  10871. ////////////////////////////////////////////////////////////////////
  10872. // Function: GLGraphicsStateGuardian::extract_texture_image
  10873. // Access: Protected
  10874. // Description: Called from extract_texture_data(), this gets just
  10875. // the image array for a particular mipmap level (or for
  10876. // the base image).
  10877. ////////////////////////////////////////////////////////////////////
  10878. bool CLP(GraphicsStateGuardian)::
  10879. extract_texture_image(PTA_uchar &image, size_t &page_size,
  10880. Texture *tex, GLenum target, GLenum page_target,
  10881. Texture::ComponentType type,
  10882. Texture::CompressionMode compression, int n) {
  10883. #ifdef OPENGLES // Extracting texture data unsupported in OpenGL ES.
  10884. nassertr(false, false);
  10885. return false;
  10886. #else
  10887. if (target == GL_TEXTURE_CUBE_MAP) {
  10888. // A cube map, compressed or uncompressed. This we must extract
  10889. // one page at a time.
  10890. // If the cube map is compressed, we assume that all the
  10891. // compressed pages are exactly the same size. OpenGL doesn't
  10892. // make this assumption, but it happens to be true for all
  10893. // currently extant compression schemes, and it makes things
  10894. // simpler for us. (It also makes things much simpler for the
  10895. // graphics hardware, so it's likely to continue to be true for a
  10896. // while at least.)
  10897. GLenum external_format = get_external_image_format(tex);
  10898. GLenum pixel_type = get_component_type(type);
  10899. page_size = tex->get_expected_ram_mipmap_page_size(n);
  10900. if (compression != Texture::CM_off) {
  10901. GLint image_size;
  10902. glGetTexLevelParameteriv(page_target, n,
  10903. GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &image_size);
  10904. nassertr(image_size <= (int)page_size, false);
  10905. page_size = image_size;
  10906. }
  10907. image = PTA_uchar::empty_array(page_size * 6);
  10908. for (int z = 0; z < 6; ++z) {
  10909. page_target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + z;
  10910. if (compression == Texture::CM_off) {
  10911. glGetTexImage(page_target, n, external_format, pixel_type,
  10912. image.p() + z * page_size);
  10913. } else {
  10914. _glGetCompressedTexImage(page_target, 0, image.p() + z * page_size);
  10915. }
  10916. }
  10917. } else if (compression == Texture::CM_off) {
  10918. // An uncompressed 1-d, 2-d, or 3-d texture.
  10919. image = PTA_uchar::empty_array(tex->get_expected_ram_mipmap_image_size(n));
  10920. GLenum external_format = get_external_image_format(tex);
  10921. GLenum pixel_type = get_component_type(type);
  10922. glGetTexImage(target, n, external_format, pixel_type, image.p());
  10923. } else {
  10924. // A compressed 1-d, 2-d, or 3-d texture.
  10925. GLint image_size;
  10926. glGetTexLevelParameteriv(target, n, GL_TEXTURE_COMPRESSED_IMAGE_SIZE, &image_size);
  10927. page_size = image_size / tex->get_z_size();
  10928. image = PTA_uchar::empty_array(image_size);
  10929. // Some drivers (ATI!) seem to try to overstuff more bytes in the
  10930. // array than they asked us to allocate (that is, more bytes than
  10931. // GL_TEXTURE_COMPRESSED_IMAGE_SIZE), requiring us to overallocate
  10932. // and then copy the result into our final buffer. Sheesh.
  10933. // We'll only do this for small textures (the ATI bug doesn't
  10934. // *seem* to affect large textures), to save on the overhead of
  10935. // the double-copy, and reduce risk from an overly-large alloca().
  10936. #ifndef NDEBUG
  10937. static const int max_trouble_buffer = 102400;
  10938. #else
  10939. static const int max_trouble_buffer = 1024;
  10940. #endif
  10941. if (image_size < max_trouble_buffer) {
  10942. static const int extra_space = 32;
  10943. unsigned char *buffer = (unsigned char *)alloca(image_size + extra_space);
  10944. #ifndef NDEBUG
  10945. // Tag the buffer with a specific byte so we can report on
  10946. // whether that driver bug is still active.
  10947. static unsigned char keep_token = 0x00;
  10948. unsigned char token = ++keep_token;
  10949. memset(buffer + image_size, token, extra_space);
  10950. #endif
  10951. _glGetCompressedTexImage(target, n, buffer);
  10952. memcpy(image.p(), buffer, image_size);
  10953. #ifndef NDEBUG
  10954. int count = extra_space;
  10955. while (count > 0 && buffer[image_size + count - 1] == token) {
  10956. --count;
  10957. }
  10958. if (count != 0) {
  10959. GLCAT.warning()
  10960. << "GL graphics driver overfilled " << count
  10961. << " bytes into a " << image_size
  10962. << "-byte buffer provided to glGetCompressedTexImage()\n";
  10963. }
  10964. // This had better not equal the amount of buffer space we set
  10965. // aside. If it does, we assume the driver might have
  10966. // overfilled even our provided extra buffer.
  10967. nassertr(count != extra_space, true)
  10968. #endif // NDEBUG
  10969. } else {
  10970. _glGetCompressedTexImage(target, n, image.p());
  10971. }
  10972. }
  10973. // Now see if we were successful.
  10974. GLenum error_code = gl_get_error();
  10975. if (error_code != GL_NO_ERROR) {
  10976. GLCAT.error()
  10977. << "Unable to extract texture for " << *tex
  10978. << ", mipmap level " << n
  10979. << " : " << get_error_string(error_code) << "\n";
  10980. nassertr(false, false);
  10981. return false;
  10982. }
  10983. return true;
  10984. #endif // OPENGLES
  10985. }
  10986. ////////////////////////////////////////////////////////////////////
  10987. // Function: GLGraphicsStateGuardian::do_point_size
  10988. // Access: Protected
  10989. // Description: Internally sets the point size parameters after any
  10990. // of the properties have changed that might affect
  10991. // this.
  10992. ////////////////////////////////////////////////////////////////////
  10993. void CLP(GraphicsStateGuardian)::
  10994. do_point_size() {
  10995. #ifndef OPENGLES_2
  10996. if (!_point_perspective) {
  10997. // Normal, constant-sized points. Here _point_size is a width in
  10998. // pixels.
  10999. static LVecBase3f constant(1.0f, 0.0f, 0.0f);
  11000. _glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, constant.get_data());
  11001. } else {
  11002. // Perspective-sized points. Here _point_size is a width in 3-d
  11003. // units. To arrange that, we need to figure out the appropriate
  11004. // scaling factor based on the current viewport and projection
  11005. // matrix.
  11006. LVector3 height(0.0f, _point_size, 1.0f);
  11007. height = height * _projection_mat->get_mat();
  11008. height = height * _internal_transform->get_scale()[1];
  11009. PN_stdfloat s = height[1] * _viewport_height / _point_size;
  11010. if (_current_lens->is_orthographic()) {
  11011. // If we have an orthographic lens in effect, we don't actually
  11012. // apply a perspective transform: we just scale the points once,
  11013. // regardless of the distance from the camera.
  11014. LVecBase3f constant(1.0f / (s * s), 0.0f, 0.0f);
  11015. _glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, constant.get_data());
  11016. } else {
  11017. // Otherwise, we give it a true perspective adjustment.
  11018. LVecBase3f square(0.0f, 0.0f, 1.0f / (s * s));
  11019. _glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, square.get_data());
  11020. }
  11021. }
  11022. report_my_gl_errors();
  11023. #endif
  11024. }
  11025. ////////////////////////////////////////////////////////////////////
  11026. // Function: GLGraphicsStateGuardian::get_supports_cg_profile
  11027. // Access: Public, Virtual
  11028. // Description: Returns true if this particular GSG supports the
  11029. // specified Cg Shader Profile.
  11030. ////////////////////////////////////////////////////////////////////
  11031. bool CLP(GraphicsStateGuardian)::
  11032. get_supports_cg_profile(const string &name) const {
  11033. #if !defined(HAVE_CG) || defined(OPENGLES)
  11034. return false;
  11035. #else
  11036. CGprofile profile = cgGetProfile(name.c_str());
  11037. if (profile == CG_PROFILE_UNKNOWN) {
  11038. GLCAT.error() << name << ", unknown Cg-profile\n";
  11039. return false;
  11040. }
  11041. return (cgGLIsProfileSupported(profile) != 0);
  11042. #endif
  11043. }
  11044. ////////////////////////////////////////////////////////////////////
  11045. // Function: GLGraphicsStateGuardian::bind_fbo
  11046. // Access: Protected
  11047. // Description: Binds a framebuffer object.
  11048. ////////////////////////////////////////////////////////////////////
  11049. void CLP(GraphicsStateGuardian)::
  11050. bind_fbo(GLuint fbo) {
  11051. if (_current_fbo == fbo) {
  11052. return;
  11053. }
  11054. PStatGPUTimer timer(this, _fbo_bind_pcollector);
  11055. nassertv(_glBindFramebuffer != 0);
  11056. #if defined(OPENGLES_2)
  11057. _glBindFramebuffer(GL_FRAMEBUFFER, fbo);
  11058. #elif defined(OPENGLES_1)
  11059. _glBindFramebuffer(GL_FRAMEBUFFER_OES, fbo);
  11060. #else
  11061. _glBindFramebuffer(GL_FRAMEBUFFER_EXT, fbo);
  11062. #endif
  11063. _current_fbo = fbo;
  11064. }
  11065. ////////////////////////////////////////////////////////////////////
  11066. // GL stencil code section
  11067. ////////////////////////////////////////////////////////////////////
  11068. static int gl_stencil_operations_array[] = {
  11069. GL_KEEP,
  11070. GL_ZERO,
  11071. GL_REPLACE,
  11072. #ifdef OPENGLES_1
  11073. GL_INCR_WRAP_OES,
  11074. GL_DECR_WRAP_OES,
  11075. #else
  11076. GL_INCR_WRAP,
  11077. GL_DECR_WRAP,
  11078. #endif
  11079. GL_INVERT,
  11080. GL_INCR,
  11081. GL_DECR,
  11082. };
  11083. ////////////////////////////////////////////////////////////////////
  11084. // Function: GLGraphicsStateGuardian::do_issue_stencil
  11085. // Access: Protected
  11086. // Description: Set stencil render states.
  11087. ////////////////////////////////////////////////////////////////////
  11088. void CLP(GraphicsStateGuardian)::
  11089. do_issue_stencil() {
  11090. if (!_supports_stencil) {
  11091. return;
  11092. }
  11093. const StencilAttrib *stencil;
  11094. if (_target_rs->get_attrib(stencil)) {
  11095. // DEBUG
  11096. if (false) {
  11097. GLCAT.debug() << "STENCIL STATE CHANGE\n";
  11098. GLCAT.debug() << "\n"
  11099. << "SRS_front_comparison_function " << (int)stencil->get_render_state(StencilAttrib::SRS_front_comparison_function) << "\n"
  11100. << "SRS_front_stencil_fail_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_front_stencil_fail_operation) << "\n"
  11101. << "SRS_front_stencil_pass_z_fail_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_fail_operation) << "\n"
  11102. << "SRS_front_stencil_pass_z_pass_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_pass_operation) << "\n"
  11103. << "SRS_reference " << (int)stencil->get_render_state(StencilAttrib::SRS_reference) << "\n"
  11104. << "SRS_read_mask " << (int)stencil->get_render_state(StencilAttrib::SRS_read_mask) << "\n"
  11105. << "SRS_write_mask " << (int)stencil->get_render_state(StencilAttrib::SRS_write_mask) << "\n"
  11106. << "SRS_back_comparison_function " << (int)stencil->get_render_state(StencilAttrib::SRS_back_comparison_function) << "\n"
  11107. << "SRS_back_stencil_fail_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_back_stencil_fail_operation) << "\n"
  11108. << "SRS_back_stencil_pass_z_fail_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_fail_operation) << "\n"
  11109. << "SRS_back_stencil_pass_z_pass_operation " << (int)stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_pass_operation) << "\n";
  11110. }
  11111. #ifndef OPENGLES
  11112. if (_supports_two_sided_stencil) {
  11113. //TODO: add support for OpenGL 2.0-style glStencilFuncSeparate.
  11114. unsigned int back_compare;
  11115. back_compare = stencil->get_render_state(StencilAttrib::SRS_back_comparison_function);
  11116. if (back_compare != RenderAttrib::M_none) {
  11117. glEnable(GL_STENCIL_TEST_TWO_SIDE_EXT);
  11118. _glActiveStencilFaceEXT(GL_BACK);
  11119. glStencilFunc(
  11120. PANDA_TO_GL_COMPAREFUNC(back_compare),
  11121. stencil->get_render_state(StencilAttrib::SRS_reference),
  11122. stencil->get_render_state(StencilAttrib::SRS_read_mask));
  11123. glStencilOp(
  11124. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_back_stencil_fail_operation)],
  11125. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_fail_operation)],
  11126. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_back_stencil_pass_z_pass_operation)]
  11127. );
  11128. glStencilMask(stencil->get_render_state(StencilAttrib::SRS_write_mask));
  11129. } else {
  11130. glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
  11131. }
  11132. _glActiveStencilFaceEXT(GL_FRONT);
  11133. }
  11134. #endif // OPENGLES
  11135. unsigned int front_compare;
  11136. front_compare = stencil->get_render_state(StencilAttrib::SRS_front_comparison_function);
  11137. if (front_compare != RenderAttrib::M_none) {
  11138. glEnable(GL_STENCIL_TEST);
  11139. glStencilFunc(
  11140. PANDA_TO_GL_COMPAREFUNC(front_compare),
  11141. stencil->get_render_state(StencilAttrib::SRS_reference),
  11142. stencil->get_render_state(StencilAttrib::SRS_read_mask));
  11143. glStencilOp(
  11144. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_front_stencil_fail_operation)],
  11145. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_fail_operation)],
  11146. gl_stencil_operations_array[stencil->get_render_state(StencilAttrib::SRS_front_stencil_pass_z_pass_operation)]
  11147. );
  11148. glStencilMask(stencil->get_render_state(StencilAttrib::SRS_write_mask));
  11149. } else {
  11150. glDisable(GL_STENCIL_TEST);
  11151. }
  11152. if (stencil->get_render_state(StencilAttrib::SRS_clear)) {
  11153. // clear stencil buffer
  11154. glClearStencil(stencil->get_render_state(StencilAttrib::SRS_clear_value));
  11155. glClear(GL_STENCIL_BUFFER_BIT);
  11156. }
  11157. } else {
  11158. glDisable(GL_STENCIL_TEST);
  11159. #ifndef OPENGLES
  11160. if (_supports_two_sided_stencil) {
  11161. glDisable(GL_STENCIL_TEST_TWO_SIDE_EXT);
  11162. }
  11163. #endif // OPENGLES
  11164. }
  11165. }
  11166. ////////////////////////////////////////////////////////////////////
  11167. // Function: GLGraphicsStateGuardian::do_issue_scissor
  11168. // Access: Protected
  11169. // Description:
  11170. ////////////////////////////////////////////////////////////////////
  11171. void CLP(GraphicsStateGuardian)::
  11172. do_issue_scissor() {
  11173. const ScissorAttrib *target_scissor;
  11174. _target_rs->get_attrib_def(target_scissor);
  11175. if (!target_scissor->is_off()) {
  11176. // A non-off ScissorAttrib means to override the scissor setting
  11177. // that was specified by the DisplayRegion.
  11178. if (!_scissor_enabled) {
  11179. if (GLCAT.is_spam()) {
  11180. GLCAT.spam()
  11181. << "glEnable(GL_SCISSOR_TEST)\n";
  11182. }
  11183. glEnable(GL_SCISSOR_TEST);
  11184. _scissor_enabled = true;
  11185. }
  11186. const LVecBase4 &frame = target_scissor->get_frame();
  11187. int x = (int)(_viewport_x + _viewport_width * frame[0] + 0.5f);
  11188. int y = (int)(_viewport_y + _viewport_height * frame[2] + 0.5f);
  11189. int width = (int)(_viewport_width * (frame[1] - frame[0]) + 0.5f);
  11190. int height = (int)(_viewport_height * (frame[3] - frame[2]) + 0.5f);
  11191. if (GLCAT.is_spam()) {
  11192. GLCAT.spam()
  11193. << "glScissor(" << x << ", " << y << ", " << width << ", " << height << ")\n";
  11194. }
  11195. glScissor(x, y, width, height);
  11196. _scissor_attrib_active = true;
  11197. } else if (_scissor_attrib_active) {
  11198. _scissor_attrib_active = false;
  11199. if (_scissor_array.size() > 0) {
  11200. // Scissoring is enabled on the display region.
  11201. // Revert to the scissor state specified in the DisplayRegion.
  11202. #ifndef OPENGLES
  11203. if (_supports_viewport_arrays) {
  11204. _glScissorArrayv(0, _scissor_array.size(), _scissor_array[0].get_data());
  11205. } else
  11206. #endif // OPENGLES
  11207. {
  11208. const LVecBase4i sr = _scissor_array[0];
  11209. glScissor(sr[0], sr[1], sr[2], sr[3]);
  11210. }
  11211. } else if (_scissor_enabled) {
  11212. // The display region had no scissor enabled. Disable scissoring.
  11213. if (GLCAT.is_spam()) {
  11214. GLCAT.spam()
  11215. << "glDisable(GL_SCISSOR_TEST)\n";
  11216. }
  11217. glDisable(GL_SCISSOR_TEST);
  11218. _scissor_enabled = false;
  11219. }
  11220. }
  11221. }