GLS.MaterialEx.pas 203 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112
  1. //
  2. // The multimedia graphics platform GLScene https://github.com/glscene
  3. //
  4. unit GLS.MaterialEx;
  5. (*
  6. Handles extended material and it components:
  7. textures, samplers, combiners, shaders and etc.
  8. Features:
  9. - material can contain different level of applying accordingly to hardware i.e.
  10. Feateres scaling.
  11. - if automatically or by user selected level failed, material down to lower level.
  12. - direct state access can be used for uniforms setting.
  13. - economy mode for texture binding to active units,
  14. i.e. if textures less than maximum units may be not one binding occur per frame.
  15. *)
  16. interface
  17. {$I GLScene.inc}
  18. uses
  19. Winapi.OpenGL,
  20. Winapi.OpenGLext,
  21. System.Classes,
  22. System.SysUtils,
  23. System.Math,
  24. Vcl.Graphics,
  25. GLS.OpenGLTokens,
  26. GLS.RenderContextInfo,
  27. GLS.PipelineTransformation,
  28. GLS.BaseClasses,
  29. GLS.Context,
  30. GLS.VectorTypes,
  31. GLS.Material,
  32. GLS.Texture,
  33. GLS.Color,
  34. GLS.Coordinates,
  35. GLS.VectorGeometry,
  36. GLS.Graphics,
  37. GLS.PersistentClasses,
  38. GLS.State,
  39. GLS.TextureFormat,
  40. GLS.XCollection,
  41. GLS.TextureCombiners,
  42. GLSL.ShaderParameter,
  43. GLS.ApplicationFileIO,
  44. GLS.Strings,
  45. GLS.ImageUtils,
  46. GLS.Utils,
  47. GLS.XOpenGL,
  48. GLS.Logger;
  49. type
  50. TGLMaterialComponentName = string;
  51. TGLMaterialLibraryEx = class;
  52. TGLMatLibComponents = class;
  53. TGLLibMaterialEx = class;
  54. TGLBaseShaderModel = class;
  55. TGLASMVertexProgram = class;
  56. TOnAsmProgSetting = procedure(Sender: TGLASMVertexProgram;
  57. var ARci: TGLRenderContextInfo) of object;
  58. TOnUniformInitialize = procedure(Sender: TGLBaseShaderModel) of object;
  59. TOnUniformSetting = procedure(Sender: TGLBaseShaderModel;
  60. var ARci: TGLRenderContextInfo) of object;
  61. TGLBaseMaterialCollectionItem = class(
  62. TXCollectionItem,
  63. IGLMaterialLibrarySupported)
  64. private
  65. FNameHashKey: Integer;
  66. FUserList: TGLPersistentObjectList;
  67. FDefferedInit: Boolean;
  68. FNotifying: Boolean;
  69. FIsValid: Boolean;
  70. function GetUserList: TGLPersistentObjectList;
  71. function GetMaterialLibraryEx: TGLMaterialLibraryEx;
  72. protected
  73. procedure SetName(const AValue: TGLMaterialComponentName); override;
  74. procedure NotifyChange(Sender: TObject); virtual;
  75. property UserList: TGLPersistentObjectList read GetUserList;
  76. procedure DoOnPrepare(Sender: TGLContext); virtual; abstract;
  77. public
  78. destructor Destroy; override;
  79. procedure RegisterUser(AUser: TGLUpdateAbleObject);
  80. procedure UnregisterUser(AUser: TGLUpdateAbleObject);
  81. function GetUserCount: Integer;
  82. function GetMaterialLibrary: TGLAbstractMaterialLibrary;
  83. property MaterialLibrary: TGLMaterialLibraryEx read GetMaterialLibraryEx;
  84. property IsValid: Boolean read FIsValid;
  85. published
  86. property Name: TGLMaterialComponentName read GetName write SetName;
  87. (* Run-time flag, indicate that resource
  88. should initialize in case of failure material's level. *)
  89. property DefferedInit: Boolean read FDefferedInit write FDefferedInit
  90. default False;
  91. end;
  92. CGLBaseMaterialCollectionItem = class of TGLBaseMaterialCollectionItem;
  93. TGLLibMaterialProperty = class(TGLUpdateAbleObject, IGLMaterialLibrarySupported)
  94. protected
  95. FEnabled: Boolean;
  96. FNextPassName: TGLLibMaterialName;
  97. function GetMaterial: TGLLibMaterialEx;
  98. function GetMaterialLibraryEx: TGLMaterialLibraryEx;
  99. procedure SetEnabled(AValue: Boolean); virtual;
  100. procedure SetNextPass(const AValue: TGLLibMaterialName);
  101. procedure Loaded; virtual;
  102. property NextPass: TGLLibMaterialName read FNextPassName write SetNextPass;
  103. public
  104. procedure NotifyChange(Sender: TObject); override;
  105. function GetMaterialLibrary: TGLAbstractMaterialLibrary;
  106. property MaterialLibrary: TGLMaterialLibraryEx read GetMaterialLibraryEx;
  107. published
  108. property Enabled: Boolean read FEnabled write SetEnabled;
  109. end;
  110. TGLTextureSampler = class(TGLBaseMaterialCollectionItem)
  111. protected
  112. procedure WriteToFiler(AWriter: TWriter); override;
  113. procedure ReadFromFiler(AReader: TReader); override;
  114. private
  115. FHandle: TGLSamplerHandle;
  116. FMinFilter: TGLMinFilter;
  117. FMagFilter: TGLMagFilter;
  118. FFilteringQuality: TGLTextureFilteringQuality;
  119. FLODBias: Integer;
  120. FLODBiasFract: Single;
  121. FWrap: array[0..2] of TGLSeparateTextureWrap;
  122. FBorderColor: TGLColor;
  123. FCompareMode: TGLTextureCompareMode;
  124. FCompareFunc: TGLDepthFunction;
  125. FDecodeSRGB: Boolean;
  126. procedure SetMagFilter(AValue: TGLMagFilter);
  127. procedure SetMinFilter(AValue: TGLMinFilter);
  128. procedure SetLODBias(AValue: Integer);
  129. procedure SetFilteringQuality(AValue: TGLTextureFilteringQuality);
  130. function GetWrap(Index: Integer): TGLSeparateTextureWrap;
  131. procedure SetWrap(Index: Integer; AValue: TGLSeparateTextureWrap);
  132. procedure SetBorderColor(const AValue: TGLColor);
  133. procedure SetCompareMode(AValue: TGLTextureCompareMode);
  134. procedure SetCompareFunc(AValue: TGLDepthFunction);
  135. procedure SetDecodeSRGB(AValue: Boolean);
  136. public
  137. constructor Create(AOwner: TXCollection); override;
  138. destructor Destroy; override;
  139. procedure Assign(Source: TPersistent); override;
  140. procedure NotifyChange(Sender: TObject); override;
  141. procedure DoOnPrepare(Sender: TGLContext); override;
  142. procedure Apply(var ARci: TGLRenderContextInfo);
  143. procedure UnApply(var ARci: TGLRenderContextInfo);
  144. class function FriendlyName: string; override;
  145. property Handle: TGLSamplerHandle read FHandle;
  146. published
  147. // Texture magnification filter.
  148. property MagFilter: TGLMagFilter read FMagFilter write SetMagFilter
  149. default maLinear;
  150. // Texture minification filter.
  151. property MinFilter: TGLMinFilter read FMinFilter write SetMinFilter
  152. default miLinearMipMapLinear;
  153. property FilteringQuality: TGLTextureFilteringQuality read FFilteringQuality
  154. write SetFilteringQuality default tfAnisotropic;
  155. // Texture LOD bias.
  156. property LodBias: Integer read FLODBias write SetLODBias default 0;
  157. // Address mode for the texture.
  158. property WrapX: TGLSeparateTextureWrap index 0 read GetWrap write SetWrap
  159. default twRepeat;
  160. property WrapY: TGLSeparateTextureWrap index 1 read GetWrap write SetWrap
  161. default twRepeat;
  162. property WrapZ: TGLSeparateTextureWrap index 2 read GetWrap write SetWrap
  163. default twRepeat;
  164. // Texture border color.
  165. property BorderColor: TGLColor read FBorderColor
  166. write SetBorderColor;
  167. // Compare mode and function for depth texture
  168. property CompareMode: TGLTextureCompareMode read FCompareMode
  169. write SetCompareMode default tcmNone;
  170. property CompareFunc: TGLDepthFunction read FCompareFunc
  171. write SetCompareFunc default cfLEqual;
  172. (* Force retrieving the undecoded sRGB data from the
  173. texture and manipulate that directly. *)
  174. property sRGB_Encode: Boolean read FDecodeSRGB write SetDecodeSRGB
  175. default True;
  176. end;
  177. TGLAbstractTexture = class(TGLBaseMaterialCollectionItem)
  178. protected
  179. FHandle: TGLTextureHandle;
  180. FInternalFormat: TGLInternalFormat;
  181. FWidth: Integer;
  182. FHeight: Integer;
  183. FDepth: Integer;
  184. FSwizzles: TSwizzleVector;
  185. FApplicableSampler: TGLTextureSampler;
  186. FLastSampler: TGLTextureSampler;
  187. function GetTextureTarget: TGLTextureTarget;
  188. procedure Apply(var ARci: TGLRenderContextInfo); virtual; abstract;
  189. procedure UnApply(var ARci: TGLRenderContextInfo); virtual; abstract;
  190. public
  191. property Handle: TGLTextureHandle read FHandle;
  192. published
  193. property Shape: TGLTextureTarget read GetTextureTarget;
  194. end;
  195. TMipmapGenerationMode =
  196. (
  197. mgmNoMip,
  198. mgmLeaveExisting,
  199. mgmOnFly,
  200. mgmBoxFilter,
  201. mgmTriangleFilter,
  202. mgmHermiteFilter,
  203. mgmBellFilter,
  204. mgmSplineFilter,
  205. mgmLanczos3Filter,
  206. mgmMitchellFilter
  207. );
  208. TGLTextureImageEx = class(TGLAbstractTexture)
  209. protected
  210. procedure WriteToFiler(AWriter: TWriter); override;
  211. procedure ReadFromFiler(AReader: TReader); override;
  212. private
  213. FCompression: TGLTextureCompression;
  214. FImage: TGLBaseImage;
  215. FImageAlpha: TGLTextureImageAlpha;
  216. FImageBrightness: Single;
  217. FImageGamma: Single;
  218. FHeightToNormalScale: Single;
  219. FSourceFile: string;
  220. FApplyCounter: Integer;
  221. FInternallyStored: Boolean;
  222. FMipGenMode: TMipmapGenerationMode;
  223. FUseStreaming: Boolean;
  224. FBaseLevel: Integer;
  225. FMaxLevel: Integer;
  226. FLastTime: Double;
  227. procedure SetInternalFormat(const AValue: TGLInternalFormat);
  228. procedure SetImageAlpha(const AValue: TGLTextureImageAlpha);
  229. procedure SetImageBrightness(const AValue: Single);
  230. function StoreBrightness: Boolean;
  231. procedure SetImageGamma(const AValue: Single);
  232. function StoreGamma: Boolean;
  233. procedure SetNormalMapScale(const AValue: Single);
  234. function StoreNormalMapScale: Boolean;
  235. procedure SetCompression(const AValue: TGLTextureCompression);
  236. procedure SetSourceFile(AValue: string);
  237. procedure SetInternallyStored(const AValue: Boolean);
  238. procedure SetMipGenMode(const AValue: TMipmapGenerationMode);
  239. procedure SetUseStreaming(const AValue: Boolean);
  240. procedure PrepareImage;
  241. procedure FullTransfer;
  242. procedure StreamTransfer;
  243. procedure CalcLODRange(out AFirstLOD, ALastLOD: Integer);
  244. public
  245. constructor Create(AOwner: TXCollection); override;
  246. destructor Destroy; override;
  247. procedure Assign(Source: TPersistent); override;
  248. procedure NotifyChange(Sender: TObject); override;
  249. procedure DoOnPrepare(Sender: TGLContext); override;
  250. procedure Apply(var ARci: TGLRenderContextInfo); override;
  251. procedure UnApply(var ARci: TGLRenderContextInfo); override;
  252. class function FriendlyName: string; override;
  253. published
  254. // Factual texture properties
  255. property InternalWidth: Integer read FWidth;
  256. property InternalHeight: Integer read FHeight;
  257. property InternalDepth: Integer read FDepth;
  258. property InternalFormat: TGLInternalFormat read FInternalFormat
  259. write SetInternalFormat default tfRGBA8;
  260. (* Automatic Image Alpha setting.
  261. Allows to control how and if the image's Alpha channel (transparency)
  262. is computed. *)
  263. property ImageAlpha: TGLTextureImageAlpha read FImageAlpha write
  264. SetImageAlpha default tiaDefault;
  265. (* Texture brightness correction.
  266. This correction is applied upon loading a TGLTextureImage, it's a
  267. simple saturating scaling applied to the RGB components of
  268. the 32 bits image, before it is passed to OpenGL, and before
  269. gamma correction (if any). *)
  270. property ImageBrightness: Single read FImageBrightness write
  271. SetImageBrightness stored StoreBrightness;
  272. (*Texture gamma correction.
  273. The gamma correction is applied upon loading a TGLTextureImage,
  274. applied to the RGB components of the 32 bits image, before it is
  275. passed to OpenGL, after brightness correction (if any). *)
  276. property ImageGamma: Single read FImageGamma write SetImageGamma stored
  277. StoreGamma;
  278. (* Texture compression control.
  279. If True the compressed TextureFormat variant (the OpenGL ICD must
  280. support GL_ARB_texture_compression, or this option is ignored). *)
  281. property Compression: TGLTextureCompression read FCompression write
  282. SetCompression default tcDefault;
  283. (* Normal Map scaling.
  284. Force normal map generation from height map and controls
  285. the intensity of the bumps. *)
  286. property HeightToNormalScale: Single read FHeightToNormalScale
  287. write SetNormalMapScale stored StoreNormalMapScale;
  288. // Source file path and name.
  289. property SourceFile: string read FSourceFile write SetSourceFile;
  290. // Force to store image levels in separate files in ready to transfer format
  291. property InternallyStored: Boolean read FInternallyStored
  292. write SetInternallyStored default False;
  293. // Mipmap generation mode.
  294. property MipGenMode: TMipmapGenerationMode read FMipGenMode
  295. write SetMipGenMode default mgmOnFly;
  296. // Enable streaming loading.
  297. property UseStreaming: Boolean read FUseStreaming
  298. write SetUseStreaming default False;
  299. end;
  300. TGLFrameBufferAttachment = class(TGLAbstractTexture)
  301. protected
  302. procedure WriteToFiler(AWriter: TWriter); override;
  303. procedure ReadFromFiler(AReader: TReader); override;
  304. private
  305. FRenderBufferHandle: TGLRenderbufferHandle;
  306. FLayered: Boolean;
  307. FCubeMap: Boolean;
  308. FSamples: Integer;
  309. FOnlyWrite: Boolean;
  310. FFixedSamplesLocation: Boolean;
  311. procedure SetWidth(AValue: Integer);
  312. procedure SetHeight(AValue: Integer);
  313. procedure SetDepth(AValue: Integer);
  314. procedure SetInternalFormat(const AValue: TGLInternalFormat);
  315. procedure SetOnlyWrite(AValue: Boolean);
  316. procedure SetLayered(AValue: Boolean);
  317. procedure SetCubeMap(AValue: Boolean);
  318. procedure SetSamples(AValue: Integer);
  319. procedure SetFixedSamplesLocation(AValue: Boolean);
  320. public
  321. constructor Create(AOwner: TXCollection); override;
  322. destructor Destroy; override;
  323. procedure Assign(Source: TPersistent); override;
  324. procedure NotifyChange(Sender: TObject); override;
  325. procedure DoOnPrepare(Sender: TGLContext); override;
  326. procedure Apply(var ARci: TGLRenderContextInfo); override;
  327. procedure UnApply(var ARci: TGLRenderContextInfo); override;
  328. class function FriendlyName: string; override;
  329. published
  330. property InternalWidth: Integer read FWidth
  331. write SetWidth default 256;
  332. property InternalHeight: Integer read FHeight
  333. write SetHeight default 256;
  334. property InternalDepth: Integer read FDepth
  335. write SetDepth default 0;
  336. property InternalFormat: TGLInternalFormat read FInternalFormat
  337. write SetInternalFormat default tfRGBA8;
  338. (* This flag makes use render buffer as target which makes
  339. it impossible to read it as texture, but improves efficiency. *)
  340. property OnlyWrite: Boolean read FOnlyWrite
  341. write SetOnlyWrite default False;
  342. // Force targe be texture array.
  343. property Layered: Boolean read FLayered
  344. write SetLayered default False;
  345. // Force target be cube map.
  346. property CubeMap: Boolean read FCubeMap
  347. write SetCubeMap default False;
  348. // Number of samples. Positive value makes texture be multisample.
  349. property Samples: Integer read FSamples
  350. write SetSamples default -1;
  351. (* FixedSamplesLocation flag makes image will use identical
  352. sample locations and the same number of samples for all texels in
  353. the image, and the sample locations will not depend on the
  354. internalformat or size of the image. *)
  355. property FixedSamplesLocation: Boolean read FFixedSamplesLocation
  356. write SetFixedSamplesLocation default False;
  357. end;
  358. (* Swizzle the components of a texture fetches in
  359. shader or fixed-function pipeline. *)
  360. TGLTextureSwizzling = class(TGLUpdateAbleObject)
  361. private
  362. FSwizzles: TSwizzleVector;
  363. function GetSwizzle(AIndex: Integer): TGLTextureSwizzle;
  364. procedure SetSwizzle(AIndex: Integer; AValue: TGLTextureSwizzle);
  365. function StoreSwizzle(AIndex: Integer): Boolean;
  366. public
  367. constructor Create(AOwner: TPersistent); override;
  368. procedure Assign(Source: TPersistent); override;
  369. procedure WriteToFiler(AWriter: TWriter);
  370. procedure ReadFromFiler(AReader: TReader);
  371. published
  372. property RedFrom: TGLTextureSwizzle index 0 read GetSwizzle
  373. write SetSwizzle stored StoreSwizzle;
  374. property GreenFrom: TGLTextureSwizzle index 1 read GetSwizzle
  375. write SetSwizzle stored StoreSwizzle;
  376. property BlueFrom: TGLTextureSwizzle index 2 read GetSwizzle
  377. write SetSwizzle stored StoreSwizzle;
  378. property AlphaFrom: TGLTextureSwizzle index 3 read GetSwizzle
  379. write SetSwizzle stored StoreSwizzle;
  380. end;
  381. TGLTextureProperties = class(TGLLibMaterialProperty)
  382. private
  383. FLibTextureName: TGLMaterialComponentName;
  384. FLibSamplerName: TGLMaterialComponentName;
  385. FLibTexture: TGLAbstractTexture;
  386. FLibSampler: TGLTextureSampler;
  387. FTextureOffset, FTextureScale: TGLCoordinates;
  388. FTextureRotate: Single;
  389. FTextureMatrixIsIdentity: Boolean;
  390. FTextureOverride: Boolean;
  391. FTextureMatrix: TGLMatrix;
  392. FMappingMode: TGLTextureMappingMode;
  393. FEnvColor: TGLColor;
  394. FMapSCoordinates: TGLCoordinates4;
  395. FMapTCoordinates: TGLCoordinates4;
  396. FMapRCoordinates: TGLCoordinates4;
  397. FMapQCoordinates: TGLCoordinates4;
  398. FSwizzling: TGLTextureSwizzling;
  399. function GetLibTextureName: TGLMaterialComponentName;
  400. function GetLibSamplerName: TGLMaterialComponentName;
  401. procedure SetLibTextureName(const AValue: TGLMaterialComponentName);
  402. procedure SetLibSamplerName(const AValue: TGLMaterialComponentName);
  403. function GetTextureOffset: TGLCoordinates;
  404. procedure SetTextureOffset(const AValue: TGLCoordinates);
  405. function StoreTextureOffset: Boolean;
  406. function GetTextureScale: TGLCoordinates;
  407. procedure SetTextureScale(const AValue: TGLCoordinates);
  408. function StoreTextureScale: Boolean;
  409. procedure SetTextureMatrix(const AValue: TGLMatrix);
  410. procedure SetTextureRotate(AValue: Single);
  411. function StoreTextureRotate: Boolean;
  412. procedure SetMappingMode(const AValue: TGLTextureMappingMode);
  413. function GetMappingSCoordinates: TGLCoordinates4;
  414. procedure SetMappingSCoordinates(const AValue: TGLCoordinates4);
  415. function StoreMappingSCoordinates: Boolean;
  416. function GetMappingTCoordinates: TGLCoordinates4;
  417. procedure SetMappingTCoordinates(const AValue: TGLCoordinates4);
  418. function StoreMappingTCoordinates: Boolean;
  419. function GetMappingRCoordinates: TGLCoordinates4;
  420. procedure SetMappingRCoordinates(const AValue: TGLCoordinates4);
  421. function StoreMappingRCoordinates: Boolean;
  422. function GetMappingQCoordinates: TGLCoordinates4;
  423. procedure SetMappingQCoordinates(const AValue: TGLCoordinates4);
  424. function StoreMappingQCoordinates: Boolean;
  425. procedure SetSwizzling(const AValue: TGLTextureSwizzling);
  426. function StoreSwizzling: Boolean;
  427. procedure SetEnvColor(const AValue: TGLColor);
  428. procedure CalculateTextureMatrix;
  429. procedure ApplyMappingMode;
  430. procedure UnApplyMappingMode;
  431. protected
  432. procedure Loaded; override;
  433. public
  434. constructor Create(AOwner: TPersistent); override;
  435. destructor Destroy; override;
  436. procedure Assign(Source: TPersistent); override;
  437. procedure NotifyChange(Sender: TObject); override;
  438. procedure Notification(Sender: TObject; Operation: TOperation); override;
  439. function IsValid: Boolean;
  440. procedure Apply(var ARci: TGLRenderContextInfo);
  441. procedure UnApply(var ARci: TGLRenderContextInfo);
  442. property TextureMatrix: TGLMatrix read FTextureMatrix write SetTextureMatrix;
  443. published
  444. property LibTextureName: TGLMaterialComponentName read GetLibTextureName
  445. write SetLibTextureName;
  446. property LibSamplerName: TGLMaterialComponentName read GetLibSamplerName
  447. write SetLibSamplerName;
  448. property TextureOffset: TGLCoordinates read GetTextureOffset write
  449. SetTextureOffset stored StoreTextureOffset;
  450. (* Texture coordinates scaling.
  451. Scaling is applied before applying the offset, and is applied
  452. to the texture coordinates, meaning that a scale factor of (2, 2, 2)
  453. will make your texture look twice smaller. *)
  454. property TextureScale: TGLCoordinates read GetTextureScale write
  455. SetTextureScale stored StoreTextureScale;
  456. (* Texture coordinates rotating.
  457. Rotating is applied after applying offset and scale,
  458. and rotate ST direction around R axis. *)
  459. property TextureRotate: Single read FTextureRotate write
  460. SetTextureRotate stored StoreTextureRotate;
  461. // Texture Environment color.
  462. property EnvColor: TGLColor read FEnvColor write SetEnvColor;
  463. (* Texture coordinates mapping mode.
  464. This property controls automatic texture coordinates generation. *)
  465. property MappingMode: TGLTextureMappingMode read FMappingMode write
  466. SetMappingMode default tmmUser;
  467. (* Texture mapping coordinates mode for S, T, R and Q axis.
  468. This property stores the coordinates for automatic texture
  469. coordinates generation. *)
  470. property MappingSCoordinates: TGLCoordinates4 read GetMappingSCoordinates
  471. write SetMappingSCoordinates stored StoreMappingSCoordinates;
  472. property MappingTCoordinates: TGLCoordinates4 read GetMappingTCoordinates
  473. write SetMappingTCoordinates stored StoreMappingTCoordinates;
  474. property MappingRCoordinates: TGLCoordinates4 read GetMappingRCoordinates
  475. write SetMappingRCoordinates stored StoreMappingRCoordinates;
  476. property MappingQCoordinates: TGLCoordinates4 read GetMappingQCoordinates
  477. write SetMappingQCoordinates stored StoreMappingQCoordinates;
  478. // Texture color fetching parameters.
  479. property Swizzling: TGLTextureSwizzling read FSwizzling write
  480. SetSwizzling stored StoreSwizzling;
  481. end;
  482. TGLFixedFunctionProperties = class(TGLLibMaterialProperty)
  483. private
  484. FFrontProperties: TGLFaceProperties;
  485. FBackProperties: TGLFaceProperties;
  486. FDepthProperties: TGLDepthProperties;
  487. FBlendingMode: TGLBlendingMode;
  488. FBlendingParams: TGLBlendingParameters;
  489. FTexProp: TGLTextureProperties;
  490. FMaterialOptions: TGLMaterialOptions;
  491. FFaceCulling: TGLFaceCulling;
  492. FPolygonMode: TGLPolygonMode;
  493. FTextureMode: TGLTextureMode;
  494. function GetBackProperties: TGLFaceProperties;
  495. procedure SetBackProperties(AValues: TGLFaceProperties);
  496. procedure SetFrontProperties(AValues: TGLFaceProperties);
  497. procedure SetDepthProperties(AValues: TGLDepthProperties);
  498. procedure SetBlendingMode(const AValue: TGLBlendingMode);
  499. procedure SetMaterialOptions(const AValue: TGLMaterialOptions);
  500. procedure SetFaceCulling(const AValue: TGLFaceCulling);
  501. procedure SetPolygonMode(AValue: TGLPolygonMode);
  502. procedure SetBlendingParams(const AValue: TGLBlendingParameters);
  503. procedure SetTexProp(AValue: TGLTextureProperties);
  504. procedure SetTextureMode(AValue: TGLTextureMode);
  505. public
  506. constructor Create(AOwner: TPersistent); override;
  507. destructor Destroy; override;
  508. procedure Assign(Source: TPersistent); override;
  509. procedure Apply(var ARci: TGLRenderContextInfo);
  510. procedure UnApply(var ARci: TGLRenderContextInfo);
  511. // Returns True if the material is blended.
  512. function Blended: Boolean;
  513. published
  514. property MaterialOptions: TGLMaterialOptions read FMaterialOptions write
  515. SetMaterialOptions default [];
  516. property BackProperties: TGLFaceProperties read GetBackProperties write
  517. SetBackProperties;
  518. property FrontProperties: TGLFaceProperties read FFrontProperties write
  519. SetFrontProperties;
  520. property DepthProperties: TGLDepthProperties read FDepthProperties write
  521. SetDepthProperties;
  522. property BlendingMode: TGLBlendingMode read FBlendingMode write SetBlendingMode
  523. default bmOpaque;
  524. property BlendingParams: TGLBlendingParameters read FBlendingParams write
  525. SetBlendingParams;
  526. property FaceCulling: TGLFaceCulling read FFaceCulling write SetFaceCulling
  527. default fcBufferDefault;
  528. property PolygonMode: TGLPolygonMode read FPolygonMode write SetPolygonMode
  529. default pmFill;
  530. property Texture: TGLTextureProperties read FTexProp write SetTexProp;
  531. // Texture application mode.
  532. property TextureMode: TGLTextureMode read FTextureMode write SetTextureMode
  533. default tmDecal;
  534. // Next pass of FFP.
  535. property NextPass;
  536. end;
  537. TGLTextureCombiner = class(TGLBaseMaterialCollectionItem)
  538. protected
  539. procedure WriteToFiler(AWriter: TWriter); override;
  540. procedure ReadFromFiler(AReader: TReader); override;
  541. private
  542. FHandle: TGLVirtualHandle;
  543. FScript: TStringList;
  544. FCommandCache: TCombinerCache;
  545. procedure SetScript(AValue: TStringList);
  546. procedure DoAllocate(Sender: TGLVirtualHandle; var handle: Cardinal);
  547. procedure DoDeallocate(Sender: TGLVirtualHandle; var handle: Cardinal);
  548. public
  549. constructor Create(AOwner: TXCollection); override;
  550. destructor Destroy; override;
  551. procedure Assign(Source: TPersistent); override;
  552. procedure NotifyChange(Sender: TObject); override;
  553. procedure DoOnPrepare(Sender: TGLContext); override;
  554. class function FriendlyName: string; override;
  555. published
  556. property Script: TStringList read FScript write SetScript;
  557. end;
  558. TGLASMVertexProgram = class(TGLBaseMaterialCollectionItem)
  559. protected
  560. procedure WriteToFiler(AWriter: TWriter); override;
  561. procedure ReadFromFiler(AReader: TReader); override;
  562. private
  563. FHandle: TGLARBVertexProgramHandle;
  564. FSource: TStringList;
  565. FSourceFile: string;
  566. FInfoLog: string;
  567. procedure SetSource(AValue: TStringList);
  568. procedure SetSourceFile(AValue: string);
  569. function GetHandle: TGLARBVertexProgramHandle;
  570. public
  571. constructor Create(AOwner: TXCollection); override;
  572. destructor Destroy; override;
  573. procedure Assign(Source: TPersistent); override;
  574. procedure DoOnPrepare(Sender: TGLContext); override;
  575. class function FriendlyName: string; override;
  576. procedure NotifyChange(Sender: TObject); override;
  577. property Handle: TGLARBVertexProgramHandle read GetHandle;
  578. published
  579. property Source: TStringList read FSource write SetSource;
  580. property SourceFile: string read FSourceFile write SetSourceFile;
  581. property InfoLog: string read FInfoLog;
  582. end;
  583. TLightDir2TexEnvColor = (
  584. l2eNone,
  585. l2eEnvColor0,
  586. l2eEnvColor1,
  587. l2eEnvColor2,
  588. l2eEnvColor3
  589. );
  590. TGLMultitexturingProperties = class(TGLLibMaterialProperty)
  591. private
  592. FLibCombiner: TGLTextureCombiner;
  593. FLibAsmProg: TGLASMVertexProgram;
  594. FLibCombinerName: TGLMaterialComponentName;
  595. FLibAsmProgName: TGLMaterialComponentName;
  596. FTexProps: array[0..3] of TGLTextureProperties;
  597. FTextureMode: TGLTextureMode;
  598. FLightDir: TLightDir2TexEnvColor;
  599. FLightSourceIndex: Integer;
  600. function GetLibCombinerName: string;
  601. function GetLibAsmProgName: string;
  602. procedure SetLibCombinerName(const AValue: string);
  603. procedure SetLibAsmProgName(const AValue: string);
  604. function GetTexProps(AIndex: Integer): TGLTextureProperties;
  605. procedure SetTexProps(AIndex: Integer; AValue: TGLTextureProperties);
  606. procedure SetTextureMode(AValue: TGLTextureMode);
  607. procedure SetLightSourceIndex(AValue: Integer);
  608. protected
  609. procedure Loaded; override;
  610. public
  611. constructor Create(AOwner: TPersistent); override;
  612. destructor Destroy; override;
  613. procedure Notification(Sender: TObject; Operation: TOperation); override;
  614. function IsValid: Boolean;
  615. procedure Apply(var ARci: TGLRenderContextInfo);
  616. procedure UnApply(var ARci: TGLRenderContextInfo);
  617. published
  618. property LibCombinerName: string read GetLibCombinerName
  619. write SetLibCombinerName;
  620. property LibAsmProgName: string read GetLibAsmProgName
  621. write SetLibAsmProgName;
  622. property Texture0: TGLTextureProperties index 0 read GetTexProps write
  623. SetTexProps;
  624. property Texture1: TGLTextureProperties index 1 read GetTexProps write
  625. SetTexProps;
  626. property Texture2: TGLTextureProperties index 2 read GetTexProps write
  627. SetTexProps;
  628. property Texture3: TGLTextureProperties index 3 read GetTexProps write
  629. SetTexProps;
  630. // Texture application mode.
  631. property TextureMode: TGLTextureMode read FTextureMode write SetTextureMode
  632. default tmDecal;
  633. (* Pass light source direction to enviroment color of choosen texture.
  634. Vector in model space. *)
  635. property LightDirTo: TLightDir2TexEnvColor read FLightDir
  636. write FLightDir default l2eNone;
  637. // Specify index of light source for LightDirTo.
  638. property LightSourceIndex: Integer read FLightSourceIndex
  639. write SetLightSourceIndex default 0;
  640. // Next pass of combiner.
  641. property NextPass;
  642. end;
  643. TGLShaderType =
  644. (
  645. shtVertex,
  646. shtControl,
  647. shtEvaluation,
  648. shtGeometry,
  649. shtFragment
  650. );
  651. TGLShaderEx = class(TGLBaseMaterialCollectionItem)
  652. protected
  653. procedure WriteToFiler(AWriter: TWriter); override;
  654. procedure ReadFromFiler(AReader: TReader); override;
  655. private
  656. FHandle: array[TGLShaderType] of TGLShaderHandle;
  657. FSource: TStringList;
  658. FSourceFile: string;
  659. FShaderType: TGLShaderType;
  660. FInfoLog: string;
  661. FGeometryInput: TGLgsInTypes;
  662. FGeometryOutput: TGLgsOutTypes;
  663. FGeometryVerticesOut: Integer;
  664. procedure SetSource(AValue: TStringList);
  665. procedure SetSourceFile(AValue: string);
  666. procedure SetShaderType(AValue: TGLShaderType);
  667. procedure SetGeometryInput(AValue: TGLgsInTypes);
  668. procedure SetGeometryOutput(AValue: TGLgsOutTypes);
  669. procedure SetGeometryVerticesOut(AValue: Integer);
  670. function GetHandle: TGLShaderHandle;
  671. public
  672. constructor Create(AOwner: TXCollection); override;
  673. destructor Destroy; override;
  674. procedure Assign(Source: TPersistent); override;
  675. procedure DoOnPrepare(Sender: TGLContext); override;
  676. class function FriendlyName: string; override;
  677. procedure NotifyChange(Sender: TObject); override;
  678. property Handle: TGLShaderHandle read GetHandle;
  679. published
  680. property Source: TStringList read FSource write SetSource;
  681. property SourceFile: string read FSourceFile write SetSourceFile;
  682. property ShaderType: TGLShaderType read FShaderType
  683. write SetShaderType default shtVertex;
  684. property InfoLog: string read FInfoLog;
  685. property GeometryInput: TGLgsInTypes read FGeometryInput
  686. write SetGeometryInput default gsInPoints;
  687. property GeometryOutput: TGLgsOutTypes read FGeometryOutput
  688. write SetGeometryOutput default gsOutPoints;
  689. property GeometryVerticesOut: Integer read FGeometryVerticesOut
  690. write SetGeometryVerticesOut default 1;
  691. end;
  692. TGLAbstractShaderUniform = class(TGLUpdateAbleObject, IShaderParameter)
  693. protected
  694. FName: string;
  695. FNameHashCode: Integer;
  696. FType: TGLSLDataType;
  697. FSamplerType: TGLSLSamplerType;
  698. function GetName: string;
  699. function GetGLSLType: TGLSLDataType;
  700. function GetGLSLSamplerType: TGLSLSamplerType;
  701. function GetAutoSetMethod: string; virtual;
  702. function GetTextureName: string; virtual;
  703. function GetSamplerName: string; virtual;
  704. function GetTextureSwizzle: TSwizzleVector; virtual;
  705. procedure SetTextureName(const AValue: string); virtual;
  706. procedure SetSamplerName(const AValue: string); virtual;
  707. procedure SetAutoSetMethod(const AValue: string); virtual;
  708. procedure SetTextureSwizzle(const AValue: TSwizzleVector); virtual;
  709. function GetFloat: Single; virtual;
  710. function GetVec2: TVector2f; virtual;
  711. function GetVec3: TVector3f; virtual;
  712. function GetVec4: TGLVector; virtual;
  713. function GetInt: TGLint; virtual;
  714. function GetIVec2: TVector2i; virtual;
  715. function GetIVec3: TVector3i; virtual;
  716. function GetIVec4: TVector4i; virtual;
  717. function GetUInt: Cardinal; virtual;
  718. function GetUVec2: TVector2ui; virtual;
  719. function GetUVec3: TVector3ui; virtual;
  720. function GetUVec4: TVector4ui; virtual;
  721. procedure SetFloat(const Value: TGLFloat); virtual;
  722. procedure SetVec2(const Value: TVector2f); virtual;
  723. procedure SetVec3(const Value: TVector3f); virtual;
  724. procedure SetVec4(const Value: TVector4f); virtual;
  725. procedure SetInt(const Value: Integer); virtual;
  726. procedure SetIVec2(const Value: TVector2i); virtual;
  727. procedure SetIVec3(const Value: TVector3i); virtual;
  728. procedure SetIVec4(const Value: TVector4i); virtual;
  729. procedure SetUInt(const Value: Cardinal); virtual;
  730. procedure SetUVec2(const Value: TVector2ui); virtual;
  731. procedure SetUVec3(const Value: TVector3ui); virtual;
  732. procedure SetUVec4(const Value: TVector4ui); virtual;
  733. function GetMat2: TMatrix2f; virtual;
  734. function GetMat3: TMatrix3f; virtual;
  735. function GetMat4: TMatrix4f; virtual;
  736. procedure SetMat2(const Value: TMatrix2f); virtual;
  737. procedure SetMat3(const Value: TMatrix3f); virtual;
  738. procedure SetMat4(const Value: TMatrix4f); virtual;
  739. procedure SetFloatArray(const Values: PGLFloat; Count: Integer); virtual;
  740. procedure SetIntArray(const Values: PGLInt; Count: Integer); virtual;
  741. procedure SetUIntArray(const Values: PGLUInt; Count: Integer); virtual;
  742. procedure WriteToFiler(AWriter: TWriter); virtual;
  743. procedure ReadFromFiler(AReader: TReader); virtual;
  744. procedure Apply(var ARci: TGLRenderContextInfo); virtual;
  745. end;
  746. CGLAbstractShaderUniform = class of TGLAbstractShaderUniform;
  747. TGLShaderUniform = class(TGLAbstractShaderUniform, IShaderParameter)
  748. protected
  749. FLocation: Integer;
  750. FStoreProgram: Cardinal;
  751. FAutoSet: TUniformAutoSetMethod;
  752. function GetProgram: Cardinal; inline;
  753. procedure PushProgram; inline;
  754. procedure PopProgram; inline;
  755. function GetFloat: Single; override;
  756. function GetVec2: TVector2f; override;
  757. function GetVec3: TVector3f; override;
  758. function GetVec4: TGLVector; override;
  759. function GetInt: TGLInt; override;
  760. function GetIVec2: TVector2i; override;
  761. function GetIVec3: TVector3i; override;
  762. function GetIVec4: TVector4i; override;
  763. function GetUInt: Cardinal; override;
  764. function GetUVec2: TVector2ui; override;
  765. function GetUVec3: TVector3ui; override;
  766. function GetUVec4: TVector4ui; override;
  767. procedure SetFloat(const Value: TGLFloat); override;
  768. procedure SetVec2(const Value: TVector2f); override;
  769. procedure SetVec3(const Value: TVector3f); override;
  770. procedure SetVec4(const Value: TVector4f); override;
  771. procedure SetInt(const Value: Integer); override;
  772. procedure SetIVec2(const Value: TVector2i); override;
  773. procedure SetIVec3(const Value: TVector3i); override;
  774. procedure SetIVec4(const Value: TVector4i); override;
  775. procedure SetUInt(const Value: Cardinal); override;
  776. procedure SetUVec2(const Value: TVector2ui); override;
  777. procedure SetUVec3(const Value: TVector3ui); override;
  778. procedure SetUVec4(const Value: TVector4ui); override;
  779. function GetMat2: TMatrix2f; override;
  780. function GetMat3: TMatrix3f; override;
  781. function GetMat4: TMatrix4f; override;
  782. procedure SetMat2(const Value: TMatrix2f); override;
  783. procedure SetMat3(const Value: TMatrix3f); override;
  784. procedure SetMat4(const Value: TMatrix4f); override;
  785. function GetAutoSetMethod: string; override;
  786. procedure SetAutoSetMethod(const AValue: string); override;
  787. procedure WriteToFiler(AWriter: TWriter); override;
  788. procedure ReadFromFiler(AReader: TReader); override;
  789. public
  790. procedure SetFloatArray(const Values: PGLFloat; Count: Integer); override;
  791. procedure SetIntArray(const Values: PGLInt; Count: Integer); override;
  792. procedure SetUIntArray(const Values: PGLUInt; Count: Integer); override;
  793. procedure Assign(Source: TPersistent); override;
  794. procedure Apply(var ARci: TGLRenderContextInfo); override;
  795. property Name: string read GetName;
  796. property Location: Integer read FLocation;
  797. property GLSLType: TGLSLDataType read GetGLSLType;
  798. end;
  799. TGLShaderUniformDSA = class(TGLShaderUniform)
  800. protected
  801. procedure SetFloat(const Value: TGLFloat); override;
  802. procedure SetVec2(const Value: TVector2f); override;
  803. procedure SetVec3(const Value: TVector3f); override;
  804. procedure SetVec4(const Value: TVector4f); override;
  805. procedure SetInt(const Value: Integer); override;
  806. procedure SetIVec2(const Value: TVector2i); override;
  807. procedure SetIVec3(const Value: TVector3i); override;
  808. procedure SetIVec4(const Value: TVector4i); override;
  809. procedure SetUInt(const Value: Cardinal); override;
  810. procedure SetUVec2(const Value: TVector2ui); override;
  811. procedure SetUVec3(const Value: TVector3ui); override;
  812. procedure SetUVec4(const Value: TVector4ui); override;
  813. procedure SetMat2(const Value: TMatrix2f); override;
  814. procedure SetMat3(const Value: TMatrix3f); override;
  815. procedure SetMat4(const Value: TMatrix4f); override;
  816. public
  817. procedure SetFloatArray(const Values: PGLFloat; Count: Integer); override;
  818. procedure SetIntArray(const Values: PGLInt; Count: Integer); override;
  819. procedure SetUIntArray(const Values: PGLUInt; Count: Integer); override;
  820. end;
  821. TGLShaderUniformTexture = class(TGLShaderUniform)
  822. private
  823. FLibTexture: TGLAbstractTexture;
  824. FLibSampler: TGLTextureSampler;
  825. FTarget: TGLTextureTarget;
  826. FSwizzling: TSwizzleVector;
  827. protected
  828. FLibTexureName: TGLMaterialComponentName;
  829. FLibSamplerName: TGLMaterialComponentName;
  830. function GetTextureName: string; override;
  831. function GetSamplerName: string; override;
  832. function GetTextureSwizzle: TSwizzleVector; override;
  833. procedure SetTextureName(const AValue: string); override;
  834. procedure SetSamplerName(const AValue: string); override;
  835. procedure SetTextureSwizzle(const AValue: TSwizzleVector); override;
  836. procedure WriteToFiler(AWriter: TWriter); override;
  837. procedure ReadFromFiler(AReader: TReader); override;
  838. procedure Loaded;
  839. public
  840. constructor Create(AOwner: TPersistent); override;
  841. destructor Destroy; override;
  842. procedure Assign(Source: TPersistent); override;
  843. procedure Notification(Sender: TObject; Operation: TOperation); override;
  844. procedure Apply(var ARci: TGLRenderContextInfo); override;
  845. property LibTextureName: TGLMaterialComponentName read GetTextureName
  846. write SetTextureName;
  847. property LibSamplerName: TGLMaterialComponentName read GetSamplerName
  848. write SetSamplerName;
  849. property GLSLSampler: TGLSLSamplerType read GetGLSLSamplerType;
  850. property Swizzling: TSwizzleVector read GetTextureSwizzle write
  851. SetTextureSwizzle;
  852. end;
  853. TGLBaseShaderModel = class(TGLLibMaterialProperty)
  854. protected
  855. FHandle: TGLProgramHandle;
  856. FLibShaderName: array[TGLShaderType] of string;
  857. FShaders: array[TGLShaderType] of TGLShaderEx;
  858. FIsValid: Boolean;
  859. FInfoLog: string;
  860. FUniforms: TGLPersistentObjectList;
  861. FAutoFill: Boolean;
  862. function GetLibShaderName(AType: TGLShaderType): string;
  863. procedure SetLibShaderName(AType: TGLShaderType; const AValue: string);
  864. function GetUniform(const AName: string): IShaderParameter;
  865. class procedure ReleaseUniforms(AList: TGLPersistentObjectList);
  866. property LibVertexShaderName: TGLMaterialComponentName index shtVertex
  867. read GetLibShaderName write SetLibShaderName;
  868. property LibFragmentShaderName: TGLMaterialComponentName index shtFragment
  869. read GetLibShaderName write SetLibShaderName;
  870. property LibGeometryShaderName: TGLMaterialComponentName index shtGeometry
  871. read GetLibShaderName write SetLibShaderName;
  872. property LibTessEvalShaderName: TGLMaterialComponentName index shtEvaluation
  873. read GetLibShaderName write SetLibShaderName;
  874. property LibTessControlShaderName: TGLMaterialComponentName index shtControl
  875. read GetLibShaderName write SetLibShaderName;
  876. procedure DefineProperties(Filer: TFiler); override;
  877. procedure ReadUniforms(AStream: TStream);
  878. procedure WriteUniforms(AStream: TStream);
  879. procedure Loaded; override;
  880. class function IsSupported: Boolean; virtual; abstract;
  881. public
  882. constructor Create(AOwner: TPersistent); override;
  883. destructor Destroy; override;
  884. procedure Assign(Source: TPersistent); override;
  885. procedure NotifyChange(Sender: TObject); override;
  886. procedure Notification(Sender: TObject; Operation: TOperation); override;
  887. procedure DoOnPrepare(Sender: TGLContext);
  888. procedure Apply(var ARci: TGLRenderContextInfo); virtual;
  889. procedure UnApply(var ARci: TGLRenderContextInfo); virtual;
  890. procedure GetUniformNames(Proc: TGetStrProc);
  891. property Handle: TGLProgramHandle read FHandle;
  892. property IsValid: Boolean read FIsValid;
  893. property Uniforms[const AName: string]: IShaderParameter read GetUniform;
  894. published
  895. // Compilation info log for design time
  896. property InfoLog: string read FInfoLog;
  897. // Turn on autofill of uniforms
  898. property AutoFillOfUniforms: Boolean read FAutoFill
  899. write FAutoFill stored False;
  900. property NextPass;
  901. end;
  902. TGLShaderModel3 = class(TGLBaseShaderModel)
  903. public
  904. class function IsSupported: Boolean; override;
  905. published
  906. property LibVertexShaderName;
  907. property LibFragmentShaderName;
  908. end;
  909. TGLShaderModel4 = class(TGLBaseShaderModel)
  910. public
  911. class function IsSupported: Boolean; override;
  912. published
  913. property LibVertexShaderName;
  914. property LibGeometryShaderName;
  915. property LibFragmentShaderName;
  916. end;
  917. TGLShaderModel5 = class(TGLBaseShaderModel)
  918. public
  919. procedure Apply(var ARci: TGLRenderContextInfo); override;
  920. procedure UnApply(var ARci: TGLRenderContextInfo); override;
  921. class function IsSupported: Boolean; override;
  922. published
  923. property LibTessControlShaderName;
  924. property LibTessEvalShaderName;
  925. property LibVertexShaderName;
  926. property LibGeometryShaderName;
  927. property LibFragmentShaderName;
  928. end;
  929. TGLLibMaterialEx = class(TGLAbstractLibMaterial)
  930. private
  931. FHandle: TGLVirtualHandle;
  932. FApplicableLevel: TGLMaterialLevel;
  933. FSelectedLevel: TGLMaterialLevel;
  934. FFixedFunc: TGLFixedFunctionProperties;
  935. FMultitexturing: TGLMultitexturingProperties;
  936. FSM3: TGLShaderModel3;
  937. FSM4: TGLShaderModel4;
  938. FSM5: TGLShaderModel5;
  939. FOnAsmProgSetting: TOnAsmProgSetting;
  940. FOnSM3UniformInit: TOnUniformInitialize;
  941. FOnSM3UniformSetting: TOnUniformSetting;
  942. FOnSM4UniformInit: TOnUniformInitialize;
  943. FOnSM4UniformSetting: TOnUniformSetting;
  944. FOnSM5UniformInit: TOnUniformInitialize;
  945. FOnSM5UniformSetting: TOnUniformSetting;
  946. FNextPass: TGLLibMaterialEx;
  947. FStoreAmalgamating: Boolean;
  948. procedure SetLevel(AValue: TGLMaterialLevel);
  949. procedure SetFixedFunc(AValue: TGLFixedFunctionProperties);
  950. procedure SetMultitexturing(AValue: TGLMultitexturingProperties);
  951. procedure SetSM3(AValue: TGLShaderModel3);
  952. procedure SetSM4(AValue: TGLShaderModel4);
  953. procedure SetSM5(AValue: TGLShaderModel5);
  954. procedure DoAllocate(Sender: TGLVirtualHandle; var handle: Cardinal);
  955. procedure DoDeallocate(Sender: TGLVirtualHandle; var handle: Cardinal);
  956. protected
  957. procedure Loaded; override;
  958. procedure RemoveDefferedInit;
  959. procedure DoOnPrepare(Sender: TGLContext);
  960. public
  961. constructor Create(ACollection: TCollection); override;
  962. destructor Destroy; override;
  963. procedure Assign(Source: TPersistent); override;
  964. procedure NotifyChange(Sender: TObject); override;
  965. procedure Apply(var ARci: TGLRenderContextInfo); override;
  966. function UnApply(var ARci: TGLRenderContextInfo): Boolean; override;
  967. function Blended: Boolean; override;
  968. published
  969. property ApplicableLevel: TGLMaterialLevel read FApplicableLevel write SetLevel default mlAuto;
  970. property SelectedLevel: TGLMaterialLevel read FSelectedLevel;
  971. property FixedFunction: TGLFixedFunctionProperties read FFixedFunc write SetFixedFunc;
  972. property Multitexturing: TGLMultitexturingProperties read FMultitexturing write SetMultitexturing;
  973. property ShaderModel3: TGLShaderModel3 read FSM3 write SetSM3;
  974. property ShaderModel4: TGLShaderModel4 read FSM4 write SetSM4;
  975. property ShaderModel5: TGLShaderModel5 read FSM5 write SetSM5;
  976. // Asm vertex program event
  977. property OnAsmProgSetting: TOnAsmProgSetting read FOnAsmProgSetting
  978. write FOnAsmProgSetting;
  979. // Shader model 3 event
  980. property OnSM3UniformInitialize: TOnUniformInitialize read FOnSM3UniformInit
  981. write FOnSM3UniformInit;
  982. property OnSM3UniformSetting: TOnUniformSetting read FOnSM3UniformSetting
  983. write FOnSM3UniformSetting;
  984. // Shader model 4 event
  985. property OnSM4UniformInitialize: TOnUniformInitialize read FOnSM4UniformInit
  986. write FOnSM4UniformInit;
  987. property OnSM4UniformSetting: TOnUniformSetting read FOnSM4UniformSetting
  988. write FOnSM4UniformSetting;
  989. // Shader model 5 event
  990. property OnSM5UniformInitialize: TOnUniformInitialize read FOnSM5UniformInit
  991. write FOnSM5UniformInit;
  992. property OnSM5UniformSetting: TOnUniformSetting read FOnSM5UniformSetting
  993. write FOnSM5UniformSetting;
  994. end;
  995. TGLLibMaterialsEx = class(TGLAbstractLibMaterials)
  996. protected
  997. procedure SetItems(AIndex: Integer; const AValue: TGLLibMaterialEx);
  998. function GetItems(AIndex: Integer): TGLLibMaterialEx;
  999. public
  1000. constructor Create(AOwner: TComponent);
  1001. function MaterialLibrary: TGLMaterialLibraryEx;
  1002. function IndexOf(const Item: TGLLibMaterialEx): Integer;
  1003. function Add: TGLLibMaterialEx;
  1004. function FindItemID(ID: Integer): TGLLibMaterialEx;
  1005. property Items[index: Integer]: TGLLibMaterialEx read GetItems
  1006. write SetItems; default;
  1007. function GetLibMaterialByName(const AName: TGLLibMaterialName):
  1008. TGLLibMaterialEx;
  1009. end;
  1010. TGLMatLibComponents = class(TXCollection)
  1011. protected
  1012. function GetItems(index: Integer): TGLBaseMaterialCollectionItem;
  1013. public
  1014. function GetNamePath: string; override;
  1015. class function ItemsClass: TXCollectionItemClass; override;
  1016. property Items[index: Integer]: TGLBaseMaterialCollectionItem
  1017. read GetItems; default;
  1018. function GetItemByName(const AName: TGLMaterialComponentName):
  1019. TGLBaseMaterialCollectionItem;
  1020. function GetTextureByName(const AName: TGLMaterialComponentName):
  1021. TGLAbstractTexture;
  1022. function GetAttachmentByName(const AName: TGLMaterialComponentName):
  1023. TGLFrameBufferAttachment;
  1024. function GetSamplerByName(const AName: TGLMaterialComponentName):
  1025. TGLTextureSampler;
  1026. function GetCombinerByName(const AName: TGLMaterialComponentName):
  1027. TGLTextureCombiner;
  1028. function GetShaderByName(const AName: TGLMaterialComponentName):
  1029. TGLShaderEx;
  1030. function GetAsmProgByName(const AName: TGLMaterialComponentName):
  1031. TGLASMVertexProgram;
  1032. function MakeUniqueName(const AName: TGLMaterialComponentName):
  1033. TGLMaterialComponentName;
  1034. end;
  1035. TGLMaterialLibraryEx = class(TGLAbstractMaterialLibrary)
  1036. private
  1037. FComponents: TGLMatLibComponents;
  1038. protected
  1039. procedure Loaded; override;
  1040. function GetMaterials: TGLLibMaterialsEx;
  1041. procedure SetMaterials(AValue: TGLLibMaterialsEx);
  1042. function StoreMaterials: Boolean;
  1043. procedure SetComponents(AValue: TGLMatLibComponents);
  1044. procedure DefineProperties(Filer: TFiler); override;
  1045. procedure WriteComponents(AStream: TStream);
  1046. procedure ReadComponents(AStream: TStream);
  1047. public
  1048. constructor Create(AOwner: TComponent); override;
  1049. destructor Destroy; override;
  1050. procedure GetNames(Proc: TGetStrProc;
  1051. AClass: CGLBaseMaterialCollectionItem); overload;
  1052. function AddTexture(const AName: TGLMaterialComponentName):
  1053. TGLTextureImageEx;
  1054. function AddAttachment(const AName: TGLMaterialComponentName):
  1055. TGLFrameBufferAttachment;
  1056. function AddSampler(const AName: TGLMaterialComponentName):
  1057. TGLTextureSampler;
  1058. function AddCombiner(const AName: TGLMaterialComponentName):
  1059. TGLTextureCombiner;
  1060. function AddShader(const AName: TGLMaterialComponentName): TGLShaderEx;
  1061. function AddAsmProg(const AName: TGLMaterialComponentName):
  1062. TGLASMVertexProgram;
  1063. procedure SetLevelForAll(const ALevel: TGLMaterialLevel);
  1064. published
  1065. // The materials collection.
  1066. property Materials: TGLLibMaterialsEx read GetMaterials write SetMaterials
  1067. stored StoreMaterials;
  1068. property Components: TGLMatLibComponents read FComponents
  1069. write SetComponents;
  1070. property TexturePaths;
  1071. end;
  1072. procedure RegisterGLMaterialExNameChangeEvent(AEvent: TNotifyEvent);
  1073. procedure DeRegisterGLMaterialExNameChangeEvent(AEvent: TNotifyEvent);
  1074. //=================================================================
  1075. implementation
  1076. //=================================================================
  1077. const
  1078. cTextureMagFilter: array[maNearest..maLinear] of Cardinal =
  1079. (GL_NEAREST, GL_LINEAR);
  1080. cTextureMinFilter: array[miNearest..miLinearMipmapLinear] of Cardinal =
  1081. (GL_NEAREST, GL_LINEAR, GL_NEAREST_MIPMAP_NEAREST,
  1082. GL_LINEAR_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR,
  1083. GL_LINEAR_MIPMAP_LINEAR);
  1084. cTextureWrapMode: array[twRepeat..twMirrorClampToBorder] of Cardinal =
  1085. (GL_REPEAT, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER,
  1086. GL_MIRRORED_REPEAT, GL_MIRROR_CLAMP_TO_EDGE_ATI,
  1087. GL_MIRROR_CLAMP_TO_BORDER_EXT);
  1088. cTextureCompareMode: array[tcmNone..tcmCompareRtoTexture] of Cardinal =
  1089. (GL_NONE, GL_COMPARE_R_TO_TEXTURE);
  1090. cSamplerToTexture: array[TGLSLSamplerType] of TGLTextureTarget =
  1091. (
  1092. ttNoShape,
  1093. ttTexture1D,
  1094. ttTexture2D,
  1095. ttTexture3D,
  1096. ttTextureCube,
  1097. ttTexture1D,
  1098. ttTexture2D,
  1099. ttTexture1DArray,
  1100. ttTexture2DArray,
  1101. ttTexture1DArray,
  1102. ttTexture1DArray,
  1103. ttTextureCube,
  1104. ttTexture1D,
  1105. ttTexture2D,
  1106. ttTexture3D,
  1107. ttTextureCube,
  1108. ttTexture1DArray,
  1109. ttTexture2DArray,
  1110. ttTexture1D,
  1111. ttTexture2D,
  1112. ttTexture3D,
  1113. ttTextureCube,
  1114. ttTexture1DArray,
  1115. ttTexture2DArray,
  1116. ttTextureRect,
  1117. ttTextureRect,
  1118. ttTextureBuffer,
  1119. ttTextureRect,
  1120. ttTextureBuffer,
  1121. ttTextureRect,
  1122. ttTextureBuffer,
  1123. ttTexture2DMultisample,
  1124. ttTexture2DMultisample,
  1125. ttTexture2DMultisample,
  1126. ttTexture2DMultisampleArray,
  1127. ttTexture2DMultisampleArray,
  1128. ttTexture2DMultisample
  1129. );
  1130. cTextureSwizzle: array[TGLTextureSwizzle] of Cardinal =
  1131. (
  1132. GL_RED,
  1133. GL_GREEN,
  1134. GL_BLUE,
  1135. GL_ALPHA,
  1136. GL_ZERO,
  1137. GL_ONE
  1138. );
  1139. const
  1140. cTextureMode: array[TGLTextureMode] of Cardinal =
  1141. (GL_DECAL, GL_MODULATE, GL_BLEND, GL_REPLACE, GL_ADD);
  1142. const
  1143. cShaderTypeName: array[TGLShaderType] of string =
  1144. ('vertex', 'control', 'evaluation', 'geomtery', 'fragment');
  1145. type
  1146. TFriendlyImage = class(TGLBaseImage);
  1147. TStandartUniformAutoSetExecutor = class
  1148. public
  1149. constructor Create;
  1150. procedure SetModelMatrix(Sender: IShaderParameter; var ARci: TGLRenderContextInfo);
  1151. procedure SetViewMatrix(Sender: IShaderParameter; var ARci: TGLRenderContextInfo);
  1152. procedure SetProjectionMatrix(Sender: IShaderParameter; var ARci: TGLRenderContextInfo);
  1153. procedure SetInvModelMatrix(Sender: IShaderParameter; var ARci: TGLRenderContextInfo);
  1154. procedure SetModelViewMatrix(Sender: IShaderParameter; var ARci: TGLRenderContextInfo);
  1155. procedure SetNormalModelMatrix(Sender: IShaderParameter; var ARci: TGLRenderContextInfo);
  1156. procedure SetInvModelViewMatrix(Sender: IShaderParameter; var ARci: TGLRenderContextInfo);
  1157. procedure SetViewProjectionMatrix(Sender: IShaderParameter; var ARci: TGLRenderContextInfo);
  1158. procedure SetWorldViewProjectionMatrix(Sender: IShaderParameter; var ARci: TGLRenderContextInfo);
  1159. procedure SetCameraPosition(Sender: IShaderParameter; var ARci: TGLRenderContextInfo);
  1160. // Lighting
  1161. procedure SetLightSource0Position(Sender: IShaderParameter; var ARci: TGLRenderContextInfo);
  1162. // Material
  1163. procedure SetMaterialFrontAmbient(Sender: IShaderParameter; var ARci: TGLRenderContextInfo);
  1164. procedure SetMaterialFrontDiffuse(Sender: IShaderParameter; var ARci: TGLRenderContextInfo);
  1165. procedure SetMaterialFrontSpecular(Sender: IShaderParameter; var ARci: TGLRenderContextInfo);
  1166. procedure SetMaterialFrontEmission(Sender: IShaderParameter; var ARci: TGLRenderContextInfo);
  1167. procedure SetMaterialFrontShininess(Sender: IShaderParameter; var ARci: TGLRenderContextInfo);
  1168. procedure SetMaterialBackAmbient(Sender: IShaderParameter; var ARci: TGLRenderContextInfo);
  1169. procedure SetMaterialBackDiffuse(Sender: IShaderParameter; var ARci: TGLRenderContextInfo);
  1170. procedure SetMaterialBackSpecular(Sender: IShaderParameter; var ARci: TGLRenderContextInfo);
  1171. procedure SetMaterialBackShininess(Sender: IShaderParameter; var ARci: TGLRenderContextInfo);
  1172. procedure SetMaterialBackEmission(Sender: IShaderParameter; var ARci: TGLRenderContextInfo);
  1173. end;
  1174. var
  1175. vGLMaterialExNameChangeEvent: TNotifyEvent;
  1176. vStandartUniformAutoSetExecutor: TStandartUniformAutoSetExecutor;
  1177. vStoreBegin: procedure(mode: Cardinal);{$IFDEF MSWINDOWS}stdcall;{$ELSE}cdecl;{$ENDIF}
  1178. procedure RegisterGLMaterialExNameChangeEvent(AEvent: TNotifyEvent);
  1179. begin
  1180. vGLMaterialExNameChangeEvent := AEvent;
  1181. end;
  1182. procedure DeRegisterGLMaterialExNameChangeEvent(AEvent: TNotifyEvent);
  1183. begin
  1184. vGLMaterialExNameChangeEvent := nil;
  1185. end;
  1186. function ComputeNameHashKey(
  1187. const AName: string): Integer;
  1188. var
  1189. i, n: Integer;
  1190. begin
  1191. n := Length(AName);
  1192. Result := n;
  1193. for i := 1 to n do
  1194. Result := (Result shl 1) + Byte(AName[i]);
  1195. end;
  1196. procedure Div2(var Value: Integer); inline;
  1197. begin
  1198. Value := Value div 2;
  1199. if Value = 0 then
  1200. Value := 1;
  1201. end;
  1202. function CalcTextureLevelNumber(ATarget: TGLTextureTarget; w, h, d: Integer):
  1203. Integer;
  1204. begin
  1205. Result := 0;
  1206. case ATarget of
  1207. ttNoShape: ;
  1208. ttTexture1D, ttTexture1DArray, ttTextureCube, ttTextureCubeArray:
  1209. repeat
  1210. Inc(Result);
  1211. Div2(w);
  1212. until w <= 1;
  1213. ttTexture2D, ttTexture2DArray:
  1214. repeat
  1215. Inc(Result);
  1216. Div2(w);
  1217. Div2(h);
  1218. until (w <= 1) and (h <= 1);
  1219. ttTexture3D:
  1220. repeat
  1221. Inc(Result);
  1222. Div2(w);
  1223. Div2(h);
  1224. Div2(d);
  1225. until (w <= 1) and (h <= 1) and (d <= 1);
  1226. ttTextureRect, ttTextureBuffer,
  1227. ttTexture2DMultisample, ttTexture2DMultisampleArray:
  1228. Result := 1;
  1229. end;
  1230. end;
  1231. destructor TGLBaseMaterialCollectionItem.Destroy;
  1232. var
  1233. I: Integer;
  1234. begin
  1235. if Assigned(FUserList) then
  1236. begin
  1237. FNotifying := True;
  1238. for I := FUserList.Count - 1 downto 0 do
  1239. TGLLibMaterialProperty(FUserList[I]).Notification(Self, opRemove);
  1240. FreeAndNil(FUserList);
  1241. end;
  1242. inherited;
  1243. end;
  1244. function TGLBaseMaterialCollectionItem.GetMaterialLibrary:
  1245. TGLAbstractMaterialLibrary;
  1246. begin
  1247. Result := TGLAbstractMaterialLibrary(TGLMatLibComponents(Owner).Owner);
  1248. end;
  1249. function TGLBaseMaterialCollectionItem.GetMaterialLibraryEx:
  1250. TGLMaterialLibraryEx;
  1251. begin
  1252. Result := TGLMaterialLibraryEx(TGLMatLibComponents(Owner).Owner);
  1253. end;
  1254. function TGLBaseMaterialCollectionItem.GetUserCount: Integer;
  1255. begin
  1256. if Assigned(FUserList) then
  1257. Result := FUserList.Count
  1258. else
  1259. Result := 0;
  1260. end;
  1261. function TGLBaseMaterialCollectionItem.GetUserList: TGLPersistentObjectList;
  1262. begin
  1263. if FUserList = nil then
  1264. begin
  1265. FUserList := TGLPersistentObjectList.Create;
  1266. FNotifying := False;
  1267. end;
  1268. Result := FUserList;
  1269. end;
  1270. procedure TGLBaseMaterialCollectionItem.NotifyChange(Sender: TObject);
  1271. var
  1272. I: Integer;
  1273. begin
  1274. if FNotifying then
  1275. exit;
  1276. FNotifying := True;
  1277. if GetUserCount > 0 then
  1278. for I := 0 to FUserList.Count - 1 do
  1279. TGLUpdateAbleObject(FUserList[I]).NotifyChange(Self);
  1280. FNotifying := False;
  1281. end;
  1282. procedure TGLBaseMaterialCollectionItem.RegisterUser(
  1283. AUser: TGLUpdateAbleObject);
  1284. begin
  1285. if not FNotifying and (UserList.IndexOf(AUser) < 0) then
  1286. UserList.Add(AUser);
  1287. end;
  1288. procedure TGLBaseMaterialCollectionItem.UnregisterUser(
  1289. AUser: TGLUpdateAbleObject);
  1290. begin
  1291. if not FNotifying then
  1292. UserList.Remove(AUser);
  1293. end;
  1294. procedure TGLBaseMaterialCollectionItem.SetName(const AValue: string);
  1295. begin
  1296. if AValue <> Name then
  1297. begin
  1298. if not IsValidIdent(AValue) then
  1299. begin
  1300. if IsDesignTime then
  1301. InformationDlg(AValue + ' - is not valid component name');
  1302. exit;
  1303. end;
  1304. if not (csLoading in MaterialLibrary.ComponentState) then
  1305. begin
  1306. if TGLMatLibComponents(Owner).GetItemByName(AValue) <> Self then
  1307. inherited SetName(TGLMatLibComponents(Owner).MakeUniqueName(AValue))
  1308. else
  1309. inherited SetName(AValue);
  1310. end
  1311. else
  1312. inherited SetName(AValue);
  1313. FNameHashKey := ComputeNameHashKey(Name);
  1314. // Notify users
  1315. NotifyChange(Self);
  1316. // Notify designer
  1317. if Assigned(vGLMaterialExNameChangeEvent) then
  1318. vGLMaterialExNameChangeEvent(Self);
  1319. end;
  1320. end;
  1321. procedure TGLFixedFunctionProperties.Apply(var ARci: TGLRenderContextInfo);
  1322. begin
  1323. with ARci.GLStates do
  1324. begin
  1325. Disable(stColorMaterial);
  1326. PolygonMode := FPolygonMode;
  1327. // Fixed functionality state
  1328. if True{ not ARci.GLStates.ForwardContext} then
  1329. begin
  1330. // Lighting switch
  1331. if (moNoLighting in MaterialOptions) or not ARci.bufferLighting then
  1332. begin
  1333. Disable(stLighting);
  1334. FFrontProperties.ApplyNoLighting(ARci, cmFront);
  1335. end
  1336. else
  1337. begin
  1338. Enable(stLighting);
  1339. FFrontProperties.Apply(ARci, cmFront);
  1340. end;
  1341. if FPolygonMode = pmLines then
  1342. Disable(stLineStipple);
  1343. // Fog switch
  1344. if (moIgnoreFog in MaterialOptions) or not ARci.bufferFog then
  1345. Disable(stFog)
  1346. else
  1347. Enable(stFog);
  1348. end;
  1349. // Apply FaceCulling and BackProperties (if needs be)
  1350. case FFaceCulling of
  1351. fcBufferDefault:
  1352. begin
  1353. if ARci.bufferFaceCull then
  1354. Enable(stCullFace)
  1355. else
  1356. Disable(stCullFace);
  1357. BackProperties.Apply(ARci, cmBack);
  1358. end;
  1359. fcCull: Enable(stCullFace);
  1360. fcNoCull:
  1361. begin
  1362. Disable(stCullFace);
  1363. BackProperties.Apply(ARci, cmBack);
  1364. end;
  1365. end;
  1366. // note: Front + Back with different PolygonMode are no longer supported.
  1367. // Currently state cache just ignores back facing mode changes, changes to
  1368. // front affect both front + back PolygonMode
  1369. // Apply Blending mode
  1370. if not ARci.ignoreBlendingRequests then
  1371. case FBlendingMode of
  1372. bmOpaque:
  1373. begin
  1374. Disable(stBlend);
  1375. Disable(stAlphaTest);
  1376. end;
  1377. bmTransparency:
  1378. begin
  1379. Enable(stBlend);
  1380. Enable(stAlphaTest);
  1381. SetBlendFunc(bfSrcAlpha, bfOneMinusSrcAlpha);
  1382. SetGLAlphaFunction(cfGreater, 0);
  1383. end;
  1384. bmAdditive:
  1385. begin
  1386. Enable(stBlend);
  1387. Enable(stAlphaTest);
  1388. SetBlendFunc(bfSrcAlpha, bfOne);
  1389. SetGLAlphaFunction(cfGreater, 0);
  1390. end;
  1391. bmAlphaTest50:
  1392. begin
  1393. Disable(stBlend);
  1394. Enable(stAlphaTest);
  1395. SetGLAlphaFunction(cfGEqual, 0.5);
  1396. end;
  1397. bmAlphaTest100:
  1398. begin
  1399. Disable(stBlend);
  1400. Enable(stAlphaTest);
  1401. SetGLAlphaFunction(cfGEqual, 1.0);
  1402. end;
  1403. bmModulate:
  1404. begin
  1405. Enable(stBlend);
  1406. Enable(stAlphaTest);
  1407. SetBlendFunc(bfDstColor, bfZero);
  1408. SetGLAlphaFunction(cfGreater, 0);
  1409. end;
  1410. bmCustom:
  1411. begin
  1412. FBlendingParams.Apply(ARci);
  1413. end;
  1414. end;
  1415. // Apply depth properties
  1416. if not ARci.ignoreDepthRequests then
  1417. FDepthProperties.Apply(ARci);
  1418. // Apply texturing
  1419. if ARci.currentMaterialLevel = mlFixedFunction then
  1420. begin
  1421. if FTexProp.Enabled and FTexProp.IsValid then
  1422. begin
  1423. ARci.GLStates.ActiveTexture := 0;
  1424. FTexProp.Apply(ARci);
  1425. gl.TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
  1426. cTextureMode[FTextureMode]);
  1427. end;
  1428. end;
  1429. end;
  1430. end;
  1431. procedure TGLFixedFunctionProperties.Assign(Source: TPersistent);
  1432. var
  1433. LFFP: TGLFixedFunctionProperties;
  1434. begin
  1435. if Source is TGLFixedFunctionProperties then
  1436. begin
  1437. LFFP := TGLFixedFunctionProperties(Source);
  1438. if Assigned(LFFP.FBackProperties) then
  1439. BackProperties.Assign(LFFP.BackProperties)
  1440. else
  1441. FreeAndNil(FBackProperties);
  1442. FFrontProperties.Assign(LFFP.FFrontProperties);
  1443. FPolygonMode := LFFP.FPolygonMode;
  1444. FBlendingMode := LFFP.FBlendingMode;
  1445. FMaterialOptions := LFFP.FMaterialOptions;
  1446. FFaceCulling := LFFP.FFaceCulling;
  1447. FDepthProperties.Assign(LFFP.FDepthProperties);
  1448. FTexProp.Assign(LFFP.FTexProp);
  1449. FTextureMode := LFFP.TextureMode;
  1450. NotifyChange(Self);
  1451. end;
  1452. inherited;
  1453. end;
  1454. function TGLFixedFunctionProperties.Blended: Boolean;
  1455. begin
  1456. Result := not (FBlendingMode in [bmOpaque, bmAlphaTest50, bmAlphaTest100, bmCustom]);
  1457. end;
  1458. constructor TGLFixedFunctionProperties.Create(AOwner: TPersistent);
  1459. begin
  1460. inherited;
  1461. FFrontProperties := TGLFaceProperties.Create(Self);
  1462. FFaceCulling := fcBufferDefault;
  1463. FPolygonMode := pmFill;
  1464. FBlendingParams := TGLBlendingParameters.Create(Self);
  1465. FDepthProperties := TGLDepthProperties.Create(Self);
  1466. FTexProp := TGLTextureProperties.Create(Self);
  1467. FTextureMode := tmDecal;
  1468. FEnabled := True;
  1469. end;
  1470. destructor TGLFixedFunctionProperties.Destroy;
  1471. begin
  1472. FFrontProperties.Destroy;
  1473. FBackProperties.Free;
  1474. FDepthProperties.Destroy;
  1475. FBlendingParams.Destroy;
  1476. FTexProp.Destroy;
  1477. inherited;
  1478. end;
  1479. function TGLFixedFunctionProperties.GetBackProperties: TGLFaceProperties;
  1480. begin
  1481. if not Assigned(FBackProperties) then
  1482. FBackProperties := TGLFaceProperties.Create(Self);
  1483. Result := FBackProperties;
  1484. end;
  1485. procedure TGLFixedFunctionProperties.SetBackProperties(AValues:
  1486. TGLFaceProperties);
  1487. begin
  1488. BackProperties.Assign(AValues);
  1489. NotifyChange(Self);
  1490. end;
  1491. procedure TGLFixedFunctionProperties.SetBlendingMode(const AValue:
  1492. TGLBlendingMode);
  1493. begin
  1494. if AValue <> FBlendingMode then
  1495. begin
  1496. FBlendingMode := AValue;
  1497. NotifyChange(Self);
  1498. end;
  1499. end;
  1500. procedure TGLFixedFunctionProperties.SetBlendingParams(const AValue:
  1501. TGLBlendingParameters);
  1502. begin
  1503. FBlendingParams.Assign(AValue);
  1504. NotifyChange(Self);
  1505. end;
  1506. procedure TGLFixedFunctionProperties.SetDepthProperties(AValues:
  1507. TGLDepthProperties);
  1508. begin
  1509. FDepthProperties.Assign(AValues);
  1510. NotifyChange(Self);
  1511. end;
  1512. procedure TGLFixedFunctionProperties.SetTexProp(AValue: TGLTextureProperties);
  1513. begin
  1514. FTexProp.Assign(AValue);
  1515. end;
  1516. procedure TGLFixedFunctionProperties.SetTextureMode(AValue: TGLTextureMode);
  1517. begin
  1518. if AValue <> FTextureMode then
  1519. begin
  1520. FTextureMode := AValue;
  1521. NotifyChange(Self);
  1522. end;
  1523. end;
  1524. procedure TGLFixedFunctionProperties.SetFaceCulling(const AValue: TGLFaceCulling);
  1525. begin
  1526. if AValue <> FFaceCulling then
  1527. begin
  1528. FFaceCulling := AValue;
  1529. NotifyChange(Self);
  1530. end;
  1531. end;
  1532. procedure TGLFixedFunctionProperties.SetFrontProperties(AValues:
  1533. TGLFaceProperties);
  1534. begin
  1535. FFrontProperties.Assign(AValues);
  1536. NotifyChange(Self);
  1537. end;
  1538. procedure TGLFixedFunctionProperties.SetMaterialOptions(const AValue:
  1539. TGLMaterialOptions);
  1540. begin
  1541. if AValue <> FMaterialOptions then
  1542. begin
  1543. FMaterialOptions := AValue;
  1544. NotifyChange(Self);
  1545. end;
  1546. end;
  1547. procedure TGLFixedFunctionProperties.SetPolygonMode(AValue: TGLPolygonMode);
  1548. begin
  1549. if AValue <> FPolygonMode then
  1550. begin
  1551. FPolygonMode := AValue;
  1552. NotifyChange(Self);
  1553. end;
  1554. end;
  1555. procedure TGLFixedFunctionProperties.UnApply(var ARci: TGLRenderContextInfo);
  1556. begin
  1557. if FTexProp.Enabled and FTexProp.IsValid then
  1558. FTexProp.UnApply(ARci);
  1559. end;
  1560. function TGLAbstractTexture.GetTextureTarget: TGLTextureTarget;
  1561. begin
  1562. Result := FHandle.Target;
  1563. end;
  1564. procedure TGLTextureImageEx.Apply(var ARci: TGLRenderContextInfo);
  1565. begin
  1566. if FIsValid then
  1567. begin
  1568. // Just bind
  1569. with ARci.GLStates do
  1570. begin
  1571. TextureBinding[ActiveTexture, FHandle.Target] := FHandle.Handle;
  1572. ActiveTextureEnabled[FHandle.Target] := True;
  1573. end;
  1574. if not IsDesignTime then
  1575. begin
  1576. if not FUseStreaming and Assigned(FImage) then
  1577. begin
  1578. Inc(FApplyCounter);
  1579. if FApplyCounter > 16 then
  1580. FreeAndNil(FImage);
  1581. end;
  1582. if FUseStreaming then
  1583. begin
  1584. StreamTransfer;
  1585. end;
  1586. end;
  1587. end
  1588. else with ARci.GLStates do
  1589. TextureBinding[ActiveTexture, FHandle.Target] := 0;
  1590. end;
  1591. procedure TGLTextureImageEx.Assign(Source: TPersistent);
  1592. var
  1593. LTexture: TGLTextureImageEx;
  1594. begin
  1595. if Source is TGLTextureImageEx then
  1596. begin
  1597. LTexture := TGLTextureImageEx(Source);
  1598. FCompression := LTexture.FCompression;
  1599. if Assigned(LTexture.FImage) then
  1600. begin
  1601. if not Assigned(FImage) then
  1602. FImage := TGLImage.Create;
  1603. FImage.Assign(LTexture.FImage);
  1604. end
  1605. else
  1606. FreeAndNil(FImage);
  1607. FImageAlpha := LTexture.FImageAlpha;
  1608. FImageBrightness := LTexture.FImageBrightness;
  1609. FImageGamma := LTexture.FImageGamma;
  1610. FHeightToNormalScale := LTexture.FHeightToNormalScale;
  1611. FSourceFile := LTexture.FSourceFile;
  1612. NotifyChange(Self);
  1613. end;
  1614. inherited;
  1615. end;
  1616. constructor TGLTextureImageEx.Create(AOwner: TXCollection);
  1617. begin
  1618. inherited;
  1619. FDefferedInit := False;
  1620. FHandle := TGLTextureHandle.Create;
  1621. FHandle.OnPrapare := DoOnPrepare;
  1622. FCompression := tcDefault;
  1623. FImageAlpha := tiaDefault;
  1624. FImageBrightness := 1.0;
  1625. FImageGamma := 1.0;
  1626. FHeightToNormalScale := 1.0;
  1627. FInternalFormat := tfRGBA8;
  1628. FInternallyStored := False;
  1629. FMipGenMode := mgmOnFly;
  1630. FUseStreaming := False;
  1631. Name := TGLMatLibComponents(AOwner).MakeUniqueName('Texture');
  1632. end;
  1633. destructor TGLTextureImageEx.Destroy;
  1634. begin
  1635. FHandle.Destroy;
  1636. FImage.Free;
  1637. inherited;
  1638. end;
  1639. procedure TGLTextureImageEx.NotifyChange(Sender: TObject);
  1640. begin
  1641. FHandle.NotifyChangesOfData;
  1642. inherited;
  1643. end;
  1644. procedure TGLTextureImageEx.DoOnPrepare(Sender: TGLContext);
  1645. var
  1646. LTarget: TGLTextureTarget;
  1647. rowSize: Integer;
  1648. begin
  1649. if IsDesignTime and FDefferedInit then
  1650. exit;
  1651. FHandle.AllocateHandle;
  1652. if not FHandle.IsDataNeedUpdate then
  1653. exit;
  1654. try
  1655. PrepareImage;
  1656. // Target
  1657. LTarget := FImage.GetTextureTarget;
  1658. // Check supporting
  1659. if not IsTargetSupported(LTarget)
  1660. or not IsFormatSupported(FInternalFormat) then
  1661. Abort;
  1662. if (FHandle.Target <> LTarget)
  1663. and (FHandle.Target <> ttNoShape) then
  1664. begin
  1665. FHandle.DestroyHandle;
  1666. FHandle.AllocateHandle;
  1667. end;
  1668. FHandle.Target := LTarget;
  1669. // Check streaming support
  1670. if not IsDesignTime then
  1671. begin
  1672. FUseStreaming := FUseStreaming and TGLUnpackPBOHandle.IsSupported;
  1673. FUseStreaming := FUseStreaming and IsServiceContextAvaible;
  1674. FUseStreaming := FUseStreaming and (LTarget = ttTexture2D);
  1675. end;
  1676. with Sender.GLStates do
  1677. begin
  1678. ActiveTextureEnabled[FHandle.Target] := True;
  1679. TextureBinding[ActiveTexture, FHandle.Target] := FHandle.Handle;
  1680. UnpackRowLength := 0;
  1681. UnpackSkipRows := 0;
  1682. UnpackSkipPixels := 0;
  1683. rowSize := FImage.LevelWidth[0] * FImage.ElementSize;
  1684. if (rowSize mod 8 = 0) and (FImage.ElementSize > 4) then
  1685. UnpackAlignment := 8
  1686. else
  1687. if rowSize mod 4 = 0 then
  1688. UnpackAlignment := 4
  1689. else if rowSize mod 2 = 0 then
  1690. UnpackAlignment := 2
  1691. else
  1692. UnpackAlignment := 1;
  1693. end;
  1694. if not IsDesignTime and FUseStreaming then
  1695. begin
  1696. TFriendlyImage(FImage).StartStreaming;
  1697. FLastTime := AppTime;
  1698. StreamTransfer;
  1699. FHandle.NotifyDataUpdated;
  1700. end
  1701. else
  1702. FullTransfer;
  1703. Sender.GLStates.ActiveTextureEnabled[FHandle.Target] := False;
  1704. FApplyCounter := 0;
  1705. FIsValid := True;
  1706. except
  1707. FIsValid := False;
  1708. end;
  1709. end;
  1710. procedure TGLTextureImageEx.FullTransfer;
  1711. var
  1712. LCompression: TGLTextureCompression;
  1713. glFormat: Cardinal;
  1714. begin
  1715. begin
  1716. if GL.ARB_texture_compression then
  1717. begin
  1718. if Compression = tcDefault then
  1719. if vDefaultTextureCompression = tcDefault then
  1720. LCompression := tcNone
  1721. else
  1722. LCompression := vDefaultTextureCompression
  1723. else
  1724. LCompression := Compression;
  1725. end
  1726. else
  1727. LCompression := tcNone;
  1728. if LCompression <> tcNone then
  1729. with CurrentGLContext.GLStates do
  1730. begin
  1731. case LCompression of
  1732. tcStandard: TextureCompressionHint := hintDontCare;
  1733. tcHighQuality: TextureCompressionHint := hintNicest;
  1734. tcHighSpeed: TextureCompressionHint := hintFastest;
  1735. else
  1736. Assert(False, strErrorEx + strUnknownType);
  1737. end;
  1738. if not GetGenericCompressedFormat(
  1739. FInternalFormat,
  1740. FImage.ColorFormat, glFormat) then
  1741. glFormat := InternalFormatToOpenGLFormat(FInternalFormat);
  1742. end
  1743. else
  1744. glFormat := InternalFormatToOpenGLFormat(FInternalFormat);
  1745. FImage.RegisterAsOpenGLTexture(
  1746. FHandle,
  1747. FMipGenMode = mgmOnFly,
  1748. glFormat,
  1749. FWidth,
  1750. FHeight,
  1751. FDepth);
  1752. if gl.GetError <> GL_NO_ERROR then
  1753. begin
  1754. gl.ClearError;
  1755. CurrentGLContext.GLStates.ActiveTextureEnabled[FHandle.Target] := False;
  1756. GLSLogger.LogErrorFmt('Unable to create texture "%s"', [Self.Name]);
  1757. Abort;
  1758. end
  1759. else
  1760. FHandle.NotifyDataUpdated;
  1761. end;
  1762. end;
  1763. procedure TGLTextureImageEx.CalcLODRange(out AFirstLOD, ALastLOD: Integer);
  1764. var
  1765. I, MaxLODSize, MinLODSize, MaxLODZSize: Integer;
  1766. begin
  1767. case FHandle.Target of
  1768. ttTexture3D:
  1769. begin
  1770. MaxLODSize := CurrentGLContext.GLStates.Max3DTextureSize;
  1771. MaxLODZSize := MaxLODSize;
  1772. end;
  1773. ttTextureCube:
  1774. begin
  1775. MaxLODSize := CurrentGLContext.GLStates.MaxCubeTextureSize;
  1776. MaxLODZSize := 0;
  1777. end;
  1778. ttTexture1DArray,
  1779. ttTexture2DArray,
  1780. ttTextureCubeArray,
  1781. ttTexture2DMultisampleArray:
  1782. begin
  1783. MaxLODSize := CurrentGLContext.GLStates.MaxTextureSize;
  1784. MaxLODZSize := CurrentGLContext.GLStates.MaxArrayTextureSize;
  1785. end;
  1786. else
  1787. begin
  1788. MaxLODSize := CurrentGLContext.GLStates.MaxTextureSize;
  1789. MaxLODZSize := 0;
  1790. end;
  1791. end;
  1792. MinLODSize := 1;
  1793. AFirstLOD := 0;
  1794. for I := 0 to High(TGLImagePiramid) do
  1795. begin
  1796. if (FImage.LevelWidth[I] <= MaxLODSize)
  1797. and (FImage.LevelHeight[I] <= MaxLODSize)
  1798. and (FImage.LevelDepth[I] <= MaxLODZSize) then
  1799. break;
  1800. Inc(AFirstLOD);
  1801. end;
  1802. AFirstLOD := MinInteger(AFirstLOD, FImage.LevelCount - 1);
  1803. ALastLOD := AFirstLOD;
  1804. for I := AFirstLOD to High(TGLImagePiramid) do
  1805. begin
  1806. if (FImage.LevelWidth[I] < MinLODSize)
  1807. or (FImage.LevelHeight[I] < MinLODSize) then
  1808. break;
  1809. Inc(ALastLOD);
  1810. end;
  1811. ALastLOD := MinInteger(ALastLOD, FImage.LevelCount - 1);
  1812. end;
  1813. procedure TGLTextureImageEx.StreamTransfer;
  1814. var
  1815. LImage: TFriendlyImage;
  1816. bContinueStreaming: Boolean;
  1817. OldBaseLevel, level: Integer;
  1818. newTime: Double;
  1819. glInternalFormat: Cardinal;
  1820. transferMethod: 0..3;
  1821. begin
  1822. LImage := TFriendlyImage(FImage);
  1823. OldBaseLevel := FBaseLevel;
  1824. CalcLODRange(FBaseLevel, FMaxLevel);
  1825. // Select transfer method
  1826. if FImage.IsCompressed then
  1827. transferMethod := 1
  1828. else
  1829. transferMethod := 0;
  1830. if gl.EXT_direct_state_access then
  1831. transferMethod := transferMethod + 2;
  1832. bContinueStreaming := False;
  1833. for level := FMaxLevel downto FBaseLevel do
  1834. begin
  1835. case LImage.LevelStreamingState[level] of
  1836. ssKeeping:
  1837. begin
  1838. if FBaseLevel < Level then
  1839. FBaseLevel := FMaxLevel;
  1840. LImage.LevelStreamingState[Level] := ssLoading;
  1841. LImage.DoStreaming;
  1842. bContinueStreaming := True;
  1843. end;
  1844. ssLoading:
  1845. begin
  1846. LImage.DoStreaming;
  1847. bContinueStreaming := True;
  1848. if FBaseLevel < Level then
  1849. FBaseLevel := FMaxLevel;
  1850. end;
  1851. ssLoaded:
  1852. begin
  1853. LImage.LevelPixelBuffer[Level].AllocateHandle;
  1854. LImage.LevelPixelBuffer[Level].Bind;
  1855. glInternalFormat := InternalFormatToOpenGLFormat(FInternalFormat);
  1856. case transferMethod of
  1857. 0: gl.TexImage2D(GL_TEXTURE_2D, Level, glInternalFormat, FImage.LevelWidth[level], FImage.LevelHeight[level], 0, FImage.ColorFormat, FImage.DataType, nil);
  1858. 1: gl.CompressedTexImage2D(GL_TEXTURE_2D, Level, glInternalFormat, FImage.LevelWidth[level], FImage.LevelHeight[level], 0, FImage.LevelSizeInByte[Level], nil);
  1859. 2: gl.TextureImage2D(FHandle.Handle, GL_TEXTURE_2D, Level, glInternalFormat, FImage.LevelWidth[level], FImage.LevelHeight[level], 0, FImage.ColorFormat, FImage.DataType, nil);
  1860. 3: gl.CompressedTextureImage2D(FHandle.Handle, GL_TEXTURE_2D, Level, glInternalFormat, FImage.LevelWidth[level], FImage.LevelHeight[level], 0, FImage.LevelSizeInByte[Level], nil);
  1861. end;
  1862. LImage.LevelPixelBuffer[Level].UnBind;
  1863. LImage.LevelStreamingState[Level] := ssTransfered;
  1864. GLSLogger.LogDebug(Format('Texture "%s" level %d loaded', [Name, Level]));
  1865. end;
  1866. ssTransfered:
  1867. begin
  1868. if LImage.LevelPixelBuffer[Level].IsAllocatedForContext then
  1869. LImage.LevelPixelBuffer[Level].DestroyHandle;
  1870. FBaseLevel := Level;
  1871. end;
  1872. end; // of case
  1873. if bContinueStreaming then
  1874. break;
  1875. end; // for level
  1876. if bContinueStreaming then
  1877. begin
  1878. gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, FMaxLevel);
  1879. gl.TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, FBaseLevel);
  1880. end;
  1881. // Smooth transition between levels
  1882. if Assigned(FApplicableSampler) then
  1883. with FApplicableSampler do
  1884. begin
  1885. newTime := AppTime;
  1886. if FLODBiasFract > 0 then
  1887. FLODBiasFract := FLODBiasFract - 0.05 * (newTime - FLastTime)
  1888. else if FLODBiasFract < 0 then
  1889. FLODBiasFract := 0;
  1890. FLastTime := newTime;
  1891. if OldBaseLevel > FBaseLevel then
  1892. FLODBiasFract := FLODBiasFract + (OldBaseLevel - FBaseLevel);
  1893. if FApplicableSampler.IsValid then
  1894. gl.SamplerParameterf(FApplicableSampler.Handle.Handle,
  1895. GL_TEXTURE_LOD_BIAS, FLODBias + FLODBiasFract)
  1896. else
  1897. // To refrash texture parameters when sampler object not supported
  1898. FLastSampler := nil;
  1899. end;
  1900. end;
  1901. class function TGLTextureImageEx.FriendlyName: string;
  1902. begin
  1903. Result := 'Texture Image';
  1904. end;
  1905. procedure TGLTextureImageEx.PrepareImage;
  1906. const
  1907. cAlphaProc: array[TGLTextureImageAlpha] of TImageAlphaProc =
  1908. (
  1909. nil,
  1910. ImageAlphaFromIntensity,
  1911. ImageAlphaSuperBlackTransparent,
  1912. ImageAlphaLuminance,
  1913. ImageAlphaLuminanceSqrt,
  1914. ImageAlphaOpaque,
  1915. ImageAlphaTopLeftPointColorTransparent,
  1916. ImageAlphaInverseLuminance,
  1917. ImageAlphaInverseLuminanceSqrt,
  1918. ImageAlphaBottomRightPointColorTransparent
  1919. );
  1920. var
  1921. ext, filename: string;
  1922. BaseImageClass: TGLBaseImageClass;
  1923. LPicture: TPicture;
  1924. LGraphic: TGraphic;
  1925. LImage: TGLImage;
  1926. level: Integer;
  1927. glColorFormat, glDataType: Cardinal;
  1928. bReadFromSource: Boolean;
  1929. LStream: TStream;
  1930. ptr: PByte;
  1931. procedure ReplaceImageClass;
  1932. begin
  1933. if not (FImage is TGLImage) then
  1934. begin
  1935. LImage := TGLImage.Create;
  1936. LImage.Assign(FImage);
  1937. FImage.Destroy;
  1938. FImage := LImage;
  1939. end
  1940. else
  1941. LImage := TGLImage(FImage);
  1942. end;
  1943. begin
  1944. if not Assigned(FImage) then
  1945. begin
  1946. try
  1947. SetExeDirectory;
  1948. bReadFromSource := True;
  1949. if FInternallyStored and not IsDesignTime then
  1950. begin
  1951. filename := Name+'.image';
  1952. if FileStreamExists(filename) then
  1953. begin
  1954. FImage := TGLImage.Create;
  1955. FImage.ResourceName := filename;
  1956. TFriendlyImage(FImage).LoadHeader;
  1957. if not FUseStreaming then
  1958. begin
  1959. ReallocMem(TFriendlyImage(FImage).fData, FImage.DataSize);
  1960. for level := FImage.LevelCount - 1 downto 0 do
  1961. begin
  1962. LStream := TFileStream.Create(filename + IntToHex(level, 2), fmOpenRead);
  1963. ptr := PByte(TFriendlyImage(FImage).GetLevelAddress(level));
  1964. LStream.Read(ptr^, FImage.LevelSizeInByte[level]);
  1965. LStream.Destroy;
  1966. end;
  1967. end;
  1968. bReadFromSource := False;
  1969. end
  1970. else
  1971. begin
  1972. FInternallyStored := False;
  1973. FUseStreaming := False;
  1974. end;
  1975. end;
  1976. if bReadFromSource then
  1977. begin
  1978. if (Length(FSourceFile) > 0) and FileStreamExists(FSourceFile) then
  1979. begin
  1980. // At first check moder image file loaders
  1981. ext := ExtractFileExt(FSourceFile);
  1982. System.Delete(ext, 1, 1);
  1983. BaseImageClass := GetRasterFileFormats.FindExt(ext);
  1984. if Assigned(BaseImageClass) then
  1985. begin
  1986. FImage := BaseImageClass.Create;
  1987. FImage.LoadFromFile(FSourceFile);
  1988. end
  1989. else
  1990. begin
  1991. // Check old loaders
  1992. FImage := TGLImage.Create;
  1993. if ApplicationFileIODefined then
  1994. begin
  1995. LGraphic := CreateGraphicFromFile(FSourceFile);
  1996. FImage.Assign(LGraphic);
  1997. LGraphic.Free;
  1998. end
  1999. else
  2000. begin
  2001. LPicture := TPicture.Create;
  2002. LPicture.LoadFromFile(FSourceFile);
  2003. FImage.Assign(LPicture.Graphic);
  2004. LPicture.Destroy;
  2005. end;
  2006. end;
  2007. if FInternalFormat <> FImage.InternalFormat then
  2008. begin
  2009. ReplaceImageClass;
  2010. FindCompatibleDataFormat(FInternalFormat, glColorFormat, glDataType);
  2011. TGLImage(FImage).SetColorFormatDataType(glColorFormat, glDataType);
  2012. TFriendlyImage(FImage).fInternalFormat := FInternalFormat;
  2013. end;
  2014. if (ImageAlpha <> tiaDefault)
  2015. or (FImageBrightness <> 1.0)
  2016. or (FImageGamma <> 1.0) then
  2017. begin
  2018. ReplaceImageClass;
  2019. for level := 0 to FImage.LevelCount - 1 do
  2020. begin
  2021. AlphaGammaBrightCorrection(
  2022. TFriendlyImage(FImage).GetLevelAddress(level),
  2023. FImage.ColorFormat,
  2024. FImage.DataType,
  2025. FImage.LevelWidth[level],
  2026. FImage.LevelHeight[level],
  2027. cAlphaProc[ImageAlpha],
  2028. FImageBrightness,
  2029. FImageGamma);
  2030. end;
  2031. end
  2032. else if FHeightToNormalScale <> 1.0 then
  2033. begin
  2034. ReplaceImageClass;
  2035. // HeightToNormalMap();
  2036. {$Message Hint 'TGLTextureImageEx.HeightToNormalScale not yet implemented' }
  2037. end;
  2038. case FMipGenMode of
  2039. mgmNoMip:
  2040. FImage.UnMipmap;
  2041. mgmLeaveExisting, mgmOnFly: ;
  2042. mgmBoxFilter:
  2043. FImage.GenerateMipmap(ImageBoxFilter);
  2044. mgmTriangleFilter:
  2045. FImage.GenerateMipmap(ImageTriangleFilter);
  2046. mgmHermiteFilter:
  2047. FImage.GenerateMipmap(ImageHermiteFilter);
  2048. mgmBellFilter:
  2049. FImage.GenerateMipmap(ImageBellFilter);
  2050. mgmSplineFilter:
  2051. FImage.GenerateMipmap(ImageSplineFilter);
  2052. mgmLanczos3Filter:
  2053. FImage.GenerateMipmap(ImageLanczos3Filter);
  2054. mgmMitchellFilter:
  2055. FImage.GenerateMipmap(ImageMitchellFilter);
  2056. end;
  2057. // Store cooked image
  2058. if FInternallyStored and IsDesignTime then
  2059. begin
  2060. filename := Name+'.image';
  2061. FImage.ResourceName := filename;
  2062. TFriendlyImage(FImage).SaveHeader;
  2063. for level := FImage.LevelCount - 1 downto 0 do
  2064. begin
  2065. LStream := TFileStream.Create(filename + IntToHex(level, 2),
  2066. fmOpenWrite or fmCreate);
  2067. ptr := PByte(TFriendlyImage(FImage).GetLevelAddress(level));
  2068. LStream.Write(ptr^, FImage.LevelSizeInByte[level]);
  2069. LStream.Destroy;
  2070. end;
  2071. end;
  2072. end
  2073. else
  2074. begin // no SourceFile
  2075. FImage := TGLImage.Create;
  2076. FImage.SetErrorImage;
  2077. GLSLogger.LogErrorFmt('Source file of texture "%s" image not found',
  2078. [Self.Name]);
  2079. end;
  2080. end; // if bReadFromSource
  2081. except
  2082. on E: Exception do
  2083. begin
  2084. FImage.Free;
  2085. FImage := TGLImage.Create;
  2086. FImage.SetErrorImage;
  2087. if IsDesignTime then
  2088. InformationDlg(Self.Name + ' - ' + E.ClassName + ': ' + E.Message)
  2089. else
  2090. GLSLogger.LogError(Self.Name + ' - ' + E.ClassName + ': ' +
  2091. E.Message);
  2092. end;
  2093. end;
  2094. end; // of not Assigned
  2095. end;
  2096. procedure TGLTextureImageEx.ReadFromFiler(AReader: TReader);
  2097. var
  2098. archiveVersion: Integer;
  2099. begin
  2100. with AReader do
  2101. begin
  2102. archiveVersion := ReadInteger;
  2103. if archiveVersion = 0 then
  2104. begin
  2105. Name := ReadString;
  2106. FDefferedInit := ReadBoolean;
  2107. FInternalFormat := TGLInternalFormat(ReadInteger);
  2108. FCompression := TGLTextureCompression(ReadInteger);
  2109. FImageAlpha := TGLTextureImageAlpha(ReadInteger);
  2110. FImageBrightness := ReadFloat;
  2111. FImageBrightness := ReadFloat;
  2112. FImageGamma := ReadFloat;
  2113. FHeightToNormalScale := ReadFloat;
  2114. FSourceFile := ReadString;
  2115. FInternallyStored := ReadBoolean;
  2116. FMipGenMode := TMipmapGenerationMode(ReadInteger);
  2117. FUseStreaming := ReadBoolean;
  2118. end
  2119. else
  2120. RaiseFilerException(archiveVersion);
  2121. end;
  2122. end;
  2123. procedure TGLTextureImageEx.SetCompression(const AValue: TGLTextureCompression);
  2124. begin
  2125. if AValue <> FCompression then
  2126. begin
  2127. FCompression := AValue;
  2128. NotifyChange(Self);
  2129. end;
  2130. end;
  2131. procedure TGLTextureImageEx.SetImageAlpha(const AValue: TGLTextureImageAlpha);
  2132. begin
  2133. if FImageAlpha <> AValue then
  2134. begin
  2135. FImageAlpha := AValue;
  2136. FreeAndNil(FImage);
  2137. NotifyChange(Self);
  2138. end;
  2139. end;
  2140. procedure TGLTextureImageEx.SetImageBrightness(const AValue: Single);
  2141. begin
  2142. if FImageBrightness <> AValue then
  2143. begin
  2144. FImageBrightness := AValue;
  2145. FreeAndNil(FImage);
  2146. NotifyChange(Self);
  2147. end;
  2148. end;
  2149. procedure TGLTextureImageEx.SetImageGamma(const AValue: Single);
  2150. begin
  2151. if FImageGamma <> AValue then
  2152. begin
  2153. FImageGamma := AValue;
  2154. FreeAndNil(FImage);
  2155. NotifyChange(Self);
  2156. end;
  2157. end;
  2158. procedure TGLTextureImageEx.SetInternalFormat(const AValue: TGLInternalFormat);
  2159. begin
  2160. if AValue <> FInternalFormat then
  2161. begin
  2162. FInternalFormat := AValue;
  2163. FreeAndNil(FImage);
  2164. NotifyChange(Self);
  2165. end;
  2166. end;
  2167. procedure TGLTextureImageEx.SetInternallyStored(const AValue: Boolean);
  2168. begin
  2169. if FInternallyStored <> AValue then
  2170. begin
  2171. FInternallyStored := AValue;
  2172. if not AValue then
  2173. FUseStreaming := AValue
  2174. else
  2175. FreeAndNil(FImage);
  2176. NotifyChange(Self);
  2177. end;
  2178. end;
  2179. procedure TGLTextureImageEx.SetMipGenMode(const AValue: TMipmapGenerationMode);
  2180. begin
  2181. if FMipGenMode <> AValue then
  2182. begin
  2183. FMipGenMode := AValue;
  2184. FreeAndNil(FImage);
  2185. NotifyChange(Self);
  2186. end;
  2187. end;
  2188. procedure TGLTextureImageEx.SetNormalMapScale(const AValue: Single);
  2189. begin
  2190. if AValue <> FHeightToNormalScale then
  2191. begin
  2192. FHeightToNormalScale := AValue;
  2193. NotifyChange(Self);
  2194. end;
  2195. end;
  2196. procedure TGLTextureImageEx.SetSourceFile(AValue: string);
  2197. begin
  2198. FixPathDelimiter(AValue);
  2199. if FSourceFile <> AValue then
  2200. begin
  2201. FSourceFile := AValue;
  2202. FUseStreaming := False;
  2203. FreeAndNil(FImage);
  2204. NotifyChange(Self);
  2205. end;
  2206. end;
  2207. procedure TGLTextureImageEx.SetUseStreaming(const AValue: Boolean);
  2208. begin
  2209. if AValue <> FUseStreaming then
  2210. begin
  2211. if AValue then
  2212. begin
  2213. if not Assigned(FImage) then
  2214. exit;
  2215. if FImage.LevelCount = 1 then
  2216. begin
  2217. if IsDesignTime then
  2218. InformationDlg('Image must be more than one level');
  2219. exit;
  2220. end;
  2221. FInternallyStored := True;
  2222. end;
  2223. FUseStreaming := AValue;
  2224. NotifyChange(Self);
  2225. end;
  2226. end;
  2227. function TGLTextureImageEx.StoreBrightness: Boolean;
  2228. begin
  2229. Result := (FImageBrightness <> 1.0);
  2230. end;
  2231. function TGLTextureImageEx.StoreGamma: Boolean;
  2232. begin
  2233. Result := (FImageGamma <> 1.0);
  2234. end;
  2235. function TGLTextureImageEx.StoreNormalMapScale: Boolean;
  2236. begin
  2237. Result := (FHeightToNormalScale <> cDefaultNormalMapScale);
  2238. end;
  2239. procedure TGLTextureImageEx.UnApply(var ARci: TGLRenderContextInfo);
  2240. begin
  2241. ARci.GLStates.ActiveTextureEnabled[FHandle.Target] := False;
  2242. end;
  2243. procedure TGLTextureImageEx.WriteToFiler(AWriter: TWriter);
  2244. begin
  2245. with AWriter do
  2246. begin
  2247. WriteInteger(0); // archive version
  2248. WriteString(Name);
  2249. WriteBoolean(FDefferedInit);
  2250. WriteInteger(Integer(FInternalFormat));
  2251. WriteInteger(Integer(FCompression));
  2252. WriteInteger(Integer(FImageAlpha));
  2253. WriteFloat(FImageBrightness);
  2254. WriteFloat(FImageBrightness);
  2255. WriteFloat(FImageGamma);
  2256. WriteFloat(FHeightToNormalScale);
  2257. WriteString(FSourceFile);
  2258. WriteBoolean(FInternallyStored);
  2259. WriteInteger(Integer(FMipGenMode));
  2260. WriteBoolean(FUseStreaming);
  2261. end;
  2262. end;
  2263. procedure TGLTextureSampler.Apply(var ARci: TGLRenderContextInfo);
  2264. begin
  2265. if FIsValid then
  2266. ARci.GLStates.SamplerBinding[ARci.GLStates.ActiveTexture] := FHandle.Handle;
  2267. end;
  2268. procedure TGLTextureSampler.Assign(Source: TPersistent);
  2269. var
  2270. LSampler: TGLTextureSampler;
  2271. begin
  2272. if Source is TGLTextureSampler then
  2273. begin
  2274. LSampler := TGLTextureSampler(Source);
  2275. FMinFilter := LSampler.FMinFilter;
  2276. FMagFilter := LSampler.FMagFilter;
  2277. FFilteringQuality := LSampler.FFilteringQuality;
  2278. FLODBias := LSampler.FLODBias;
  2279. FLODBiasFract := 0;
  2280. FBorderColor.Assign(LSampler.FBorderColor);
  2281. FWrap := LSampler.FWrap;
  2282. FCompareMode := LSampler.FCompareMode;
  2283. FCompareFunc := LSampler.FCompareFunc;
  2284. FDecodeSRGB := LSampler.FDecodeSRGB;
  2285. NotifyChange(Self);
  2286. end;
  2287. inherited;
  2288. end;
  2289. constructor TGLTextureSampler.Create(AOwner: TXCollection);
  2290. begin
  2291. inherited;
  2292. FDefferedInit := False;
  2293. FHandle := TGLSamplerHandle.Create;
  2294. FHandle.OnPrapare := DoOnPrepare;
  2295. FMagFilter := maLinear;
  2296. FMinFilter := miLinearMipMapLinear;
  2297. FFilteringQuality := tfAnisotropic;
  2298. FLODBias := 0;
  2299. FLODBiasFract := 0;
  2300. FWrap[0] := twRepeat;
  2301. FWrap[1] := twRepeat;
  2302. FWrap[2] := twRepeat;
  2303. FBorderColor := TGLColor.CreateInitialized(Self, clrTransparent);
  2304. FCompareMode := tcmNone;
  2305. FCompareFunc := cfLequal;
  2306. FDecodeSRGB := True;
  2307. Name := TGLMatLibComponents(AOwner).MakeUniqueName('Sampler');
  2308. end;
  2309. destructor TGLTextureSampler.Destroy;
  2310. begin
  2311. FHandle.Destroy;
  2312. FBorderColor.Destroy;
  2313. inherited;
  2314. end;
  2315. function TGLTextureSampler.GetWrap(Index: Integer): TGLSeparateTextureWrap;
  2316. begin
  2317. Result := FWrap[Index];
  2318. end;
  2319. procedure TGLTextureSampler.NotifyChange(Sender: TObject);
  2320. begin
  2321. FHandle.NotifyChangesOfData;
  2322. inherited;
  2323. end;
  2324. procedure TGLTextureSampler.DoOnPrepare(Sender: TGLContext);
  2325. var
  2326. ID: Cardinal;
  2327. begin
  2328. if IsDesignTime and FDefferedInit then
  2329. exit;
  2330. try
  2331. if FHandle.IsSupported then
  2332. begin
  2333. FHandle.AllocateHandle;
  2334. ID := FHandle.Handle;
  2335. if FHandle.IsDataNeedUpdate then
  2336. with Sender.GL do
  2337. begin
  2338. SamplerParameterfv(ID, GL_TEXTURE_BORDER_COLOR, FBorderColor.AsAddress);
  2339. SamplerParameteri(ID, GL_TEXTURE_WRAP_S, cTextureWrapMode[FWrap[0]]);
  2340. SamplerParameteri(ID, GL_TEXTURE_WRAP_T, cTextureWrapMode[FWrap[1]]);
  2341. SamplerParameteri(ID, GL_TEXTURE_WRAP_R, cTextureWrapMode[FWrap[2]]);
  2342. SamplerParameterf(ID, GL_TEXTURE_LOD_BIAS, FLODBias + FLODBiasFract);
  2343. SamplerParameteri(ID, GL_TEXTURE_MIN_FILTER,
  2344. cTextureMinFilter[FMinFilter]);
  2345. SamplerParameteri(ID, GL_TEXTURE_MAG_FILTER,
  2346. cTextureMagFilter[FMagFilter]);
  2347. if EXT_texture_filter_anisotropic then
  2348. begin
  2349. if FFilteringQuality = tfAnisotropic then
  2350. SamplerParameteri(ID, GL_TEXTURE_MAX_ANISOTROPY_EXT,
  2351. CurrentGLContext.GLStates.MaxTextureAnisotropy)
  2352. else
  2353. SamplerParameteri(ID, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
  2354. end;
  2355. SamplerParameteri(ID, GL_TEXTURE_COMPARE_MODE,
  2356. cTextureCompareMode[FCompareMode]);
  2357. SamplerParameteri(ID, GL_TEXTURE_COMPARE_FUNC,
  2358. cGLComparisonFunctionToGLEnum[FCompareFunc]);
  2359. if EXT_texture_sRGB_decode then
  2360. begin
  2361. if FDecodeSRGB then
  2362. SamplerParameteri(ID, GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT)
  2363. else
  2364. SamplerParameteri(ID, GL_TEXTURE_SRGB_DECODE_EXT,
  2365. GL_SKIP_DECODE_EXT);
  2366. end;
  2367. {$IFDEF USE_OPENGL_DEBUG}
  2368. CheckError;
  2369. {$ENDIF}
  2370. FHandle.NotifyDataUpdated;
  2371. end;
  2372. FIsValid := True;
  2373. end
  2374. else
  2375. FIsValid := False;
  2376. except
  2377. FIsValid := False;
  2378. end;
  2379. end;
  2380. class function TGLTextureSampler.FriendlyName: string;
  2381. begin
  2382. Result := 'Texture Sampler';
  2383. end;
  2384. procedure TGLTextureSampler.ReadFromFiler(AReader: TReader);
  2385. var
  2386. archiveVersion: Integer;
  2387. begin
  2388. with AReader do
  2389. begin
  2390. archiveVersion := ReadInteger;
  2391. if archiveVersion = 0 then
  2392. begin
  2393. Name := ReadString;
  2394. FDefferedInit := ReadBoolean;
  2395. FMinFilter := TGLMinFilter(ReadInteger);
  2396. FMagFilter := TGLMagFilter(ReadInteger);
  2397. FFilteringQuality := TGLTextureFilteringQuality(ReadInteger);
  2398. FLODBias := ReadInteger;
  2399. FWrap[0] := TGLSeparateTextureWrap(ReadInteger);
  2400. FWrap[1] := TGLSeparateTextureWrap(ReadInteger);
  2401. FWrap[2] := TGLSeparateTextureWrap(ReadInteger);
  2402. Read(FBorderColor.AsAddress^, SizeOf(TGLColorVector));
  2403. FCompareMode := TGLTextureCompareMode(ReadInteger);
  2404. FCompareFunc := TGLDepthFunction(ReadInteger);
  2405. FDecodeSRGB := ReadBoolean;
  2406. end
  2407. else
  2408. RaiseFilerException(archiveVersion);
  2409. end;
  2410. end;
  2411. procedure TGLTextureSampler.SetBorderColor(const AValue: TGLColor);
  2412. begin
  2413. FBorderColor.Assign(AValue);
  2414. NotifyChange(Self);
  2415. end;
  2416. procedure TGLTextureSampler.SetCompareFunc(AValue: TGLDepthFunction);
  2417. begin
  2418. if FCompareFunc <> AValue then
  2419. begin
  2420. FCompareFunc := AValue;
  2421. NotifyChange(Self);
  2422. end;
  2423. end;
  2424. procedure TGLTextureSampler.SetCompareMode(AValue: TGLTextureCompareMode);
  2425. begin
  2426. if FCompareMode <> AValue then
  2427. begin
  2428. FCompareMode := AValue;
  2429. NotifyChange(Self);
  2430. end;
  2431. end;
  2432. procedure TGLTextureSampler.SetDecodeSRGB(AValue: Boolean);
  2433. begin
  2434. if FDecodeSRGB <> AValue then
  2435. begin
  2436. FDecodeSRGB := AValue;
  2437. NotifyChange(Self);
  2438. end;
  2439. end;
  2440. procedure TGLTextureSampler.SetFilteringQuality(
  2441. AValue: TGLTextureFilteringQuality);
  2442. begin
  2443. if FFilteringQuality <> AValue then
  2444. begin
  2445. FFilteringQuality := AValue;
  2446. NotifyChange(Self);
  2447. end;
  2448. end;
  2449. procedure TGLTextureSampler.SetLODBias(AValue: Integer);
  2450. begin
  2451. if FLODBias <> AValue then
  2452. begin
  2453. FLODBias := AValue;
  2454. NotifyChange(Self);
  2455. end;
  2456. end;
  2457. procedure TGLTextureSampler.SetMagFilter(AValue: TGLMagFilter);
  2458. begin
  2459. if FMagFilter <> AValue then
  2460. begin
  2461. FMagFilter := AValue;
  2462. NotifyChange(Self);
  2463. end;
  2464. end;
  2465. procedure TGLTextureSampler.SetMinFilter(AValue: TGLMinFilter);
  2466. begin
  2467. if FMinFilter <> AValue then
  2468. begin
  2469. FMinFilter := AValue;
  2470. NotifyChange(Self);
  2471. end;
  2472. end;
  2473. procedure TGLTextureSampler.SetWrap(Index: Integer;
  2474. AValue: TGLSeparateTextureWrap);
  2475. begin
  2476. if FWrap[Index] <> AValue then
  2477. begin
  2478. FWrap[Index] := AValue;
  2479. NotifyChange(Self);
  2480. end;
  2481. end;
  2482. procedure TGLTextureSampler.UnApply(var ARci: TGLRenderContextInfo);
  2483. begin
  2484. if FHandle.IsSupported then
  2485. with ARci.GLStates do
  2486. SamplerBinding[ActiveTexture] := 0;
  2487. end;
  2488. procedure TGLTextureSampler.WriteToFiler(AWriter: TWriter);
  2489. begin
  2490. with AWriter do
  2491. begin
  2492. WriteInteger(0); // archive version
  2493. WriteString(Name);
  2494. WriteBoolean(FDefferedInit);
  2495. WriteInteger(Integer(FMinFilter));
  2496. WriteInteger(Integer(FMagFilter));
  2497. WriteInteger(Integer(FFilteringQuality));
  2498. WriteInteger(FLODBias);
  2499. WriteInteger(Integer(FWrap[0]));
  2500. WriteInteger(Integer(FWrap[1]));
  2501. WriteInteger(Integer(FWrap[2]));
  2502. Write(FBorderColor.AsAddress^, SizeOf(TGLColorVector));
  2503. WriteInteger(Integer(FCompareMode));
  2504. WriteInteger(Integer(FCompareFunc));
  2505. WriteBoolean(FDecodeSRGB);
  2506. end;
  2507. end;
  2508. { TVXTextureCombiner }
  2509. procedure TGLTextureCombiner.Assign(Source: TPersistent);
  2510. var
  2511. LCombiner: TGLTextureCombiner;
  2512. begin
  2513. if Source is TGLTextureCombiner then
  2514. begin
  2515. LCombiner := TGLTextureCombiner(Source);
  2516. FScript.Assign(LCombiner.FScript);
  2517. end;
  2518. inherited;
  2519. end;
  2520. constructor TGLTextureCombiner.Create(AOwner: TXCollection);
  2521. begin
  2522. inherited;
  2523. FDefferedInit := False;
  2524. FHandle := TGLVirtualHandle.Create;
  2525. FHandle.OnAllocate := DoAllocate;
  2526. FHandle.OnDestroy := DoDeallocate;
  2527. FHandle.OnPrapare := DoOnPrepare;
  2528. FScript := TStringList.Create;
  2529. FScript.OnChange := NotifyChange;
  2530. FIsValid := True;
  2531. Name := TGLMatLibComponents(AOwner).MakeUniqueName('Combiner');
  2532. end;
  2533. destructor TGLTextureCombiner.Destroy;
  2534. begin
  2535. FHandle.Destroy;
  2536. FScript.Destroy;
  2537. inherited;
  2538. end;
  2539. procedure TGLTextureCombiner.NotifyChange(Sender: TObject);
  2540. begin
  2541. FHandle.NotifyChangesOfData;
  2542. inherited;
  2543. end;
  2544. procedure TGLTextureCombiner.DoAllocate(Sender: TGLVirtualHandle;
  2545. var handle: Cardinal);
  2546. begin
  2547. handle := 1;
  2548. end;
  2549. procedure TGLTextureCombiner.DoDeallocate(Sender: TGLVirtualHandle;
  2550. var handle: Cardinal);
  2551. begin
  2552. handle := 0;
  2553. end;
  2554. procedure TGLTextureCombiner.DoOnPrepare(Sender: TGLContext);
  2555. begin
  2556. if IsDesignTime and FDefferedInit then
  2557. exit;
  2558. if Sender.gl.ARB_multitexture then
  2559. begin
  2560. FHandle.AllocateHandle;
  2561. if FHandle.IsDataNeedUpdate then
  2562. begin
  2563. try
  2564. FCommandCache := GetTextureCombiners(FScript);
  2565. FIsValid := True;
  2566. except
  2567. on E: Exception do
  2568. begin
  2569. FIsValid := False;
  2570. if IsDesignTime then
  2571. InformationDlg(E.ClassName + ': ' + E.Message)
  2572. else
  2573. GLSLogger.LogError(E.ClassName + ': ' + E.Message);
  2574. end;
  2575. end;
  2576. FHandle.NotifyDataUpdated;
  2577. end;
  2578. end
  2579. else
  2580. FIsValid := False;
  2581. end;
  2582. class function TGLTextureCombiner.FriendlyName: string;
  2583. begin
  2584. Result := 'Texture Combiner';
  2585. end;
  2586. procedure TGLTextureCombiner.ReadFromFiler(AReader: TReader);
  2587. var
  2588. archiveVersion: Integer;
  2589. begin
  2590. with AReader do
  2591. begin
  2592. archiveVersion := ReadInteger;
  2593. if archiveVersion = 0 then
  2594. begin
  2595. Name := ReadString;
  2596. FDefferedInit := ReadBoolean;
  2597. FScript.Text := ReadString;
  2598. end
  2599. else
  2600. RaiseFilerException(archiveVersion);
  2601. end;
  2602. end;
  2603. procedure TGLTextureCombiner.SetScript(AValue: TStringList);
  2604. begin
  2605. FScript.Assign(AValue);
  2606. NotifyChange(Self);
  2607. end;
  2608. procedure TGLTextureCombiner.WriteToFiler(AWriter: TWriter);
  2609. begin
  2610. with AWriter do
  2611. begin
  2612. WriteInteger(0); // archive version
  2613. WriteString(Name);
  2614. WriteBoolean(FDefferedInit);
  2615. WriteString(FScript.Text);
  2616. end;
  2617. end;
  2618. { TVXLibMaterialEx }
  2619. procedure TGLLibMaterialEx.Apply(var ARci: TGLRenderContextInfo);
  2620. var
  2621. LevelReady: array[TGLMaterialLevel] of Boolean;
  2622. L, MaxLevel: TGLMaterialLevel;
  2623. begin
  2624. if Assigned(FNextPass) then
  2625. begin
  2626. FNextPass := nil;
  2627. exit;
  2628. end;
  2629. FHandle.AllocateHandle;
  2630. if FHandle.IsDataNeedUpdate then
  2631. begin
  2632. // Other value than mlAuto indicates a level failure
  2633. // Need remove deffered initialization and reinitialize used resources
  2634. if not IsDesignTime and (FSelectedLevel <> mlAuto) then
  2635. RemoveDefferedInit;
  2636. // Level selection
  2637. LevelReady[mlFixedFunction] := FFixedFunc.Enabled;
  2638. LevelReady[mlMultitexturing] := FMultitexturing.Enabled and
  2639. FMultitexturing.IsValid;
  2640. LevelReady[mlSM3] := FSM3.Enabled and FSM3.IsValid;
  2641. LevelReady[mlSM4] := FSM4.Enabled and FSM4.IsValid;
  2642. LevelReady[mlSM5] := FSM5.Enabled and FSM5.IsValid;
  2643. if FApplicableLevel = mlAuto then
  2644. MaxLevel := mlSM5
  2645. else
  2646. MaxLevel := FApplicableLevel;
  2647. FSelectedLevel := mlAuto;
  2648. for L := MaxLevel downto mlFixedFunction do
  2649. if LevelReady[L] then
  2650. begin
  2651. FSelectedLevel := L;
  2652. break;
  2653. end;
  2654. FStoreAmalgamating := ARci.amalgamating;
  2655. ARci.amalgamating := True;
  2656. FHandle.NotifyDataUpdated;
  2657. end;
  2658. ARci.currentMaterialLevel := FSelectedLevel;
  2659. case FSelectedLevel of
  2660. mlAuto: ; // No one level can be used. Worst case.
  2661. mlFixedFunction:
  2662. begin
  2663. FFixedFunc.Apply(ARci);
  2664. end;
  2665. mlMultitexturing:
  2666. begin
  2667. if LevelReady[mlFixedFunction] then
  2668. FFixedFunc.Apply(ARci);
  2669. FMultitexturing.Apply(ARci);
  2670. end;
  2671. mlSM3:
  2672. begin
  2673. if LevelReady[mlFixedFunction] then
  2674. FFixedFunc.Apply(ARci);
  2675. FSM3.Apply(ARci);
  2676. end;
  2677. mlSM4:
  2678. begin
  2679. if LevelReady[mlFixedFunction] then
  2680. FFixedFunc.Apply(ARci);
  2681. FSM4.Apply(ARci);
  2682. end;
  2683. mlSM5:
  2684. begin
  2685. if LevelReady[mlFixedFunction] then
  2686. FFixedFunc.Apply(ARci);
  2687. FSM5.Apply(ARci);
  2688. end;
  2689. end;
  2690. end;
  2691. procedure TGLLibMaterialEx.Assign(Source: TPersistent);
  2692. var
  2693. LMaterial: TGLLibMaterialEx;
  2694. begin
  2695. if Source is TGLLibMaterialEx then
  2696. begin
  2697. LMaterial := TGLLibMaterialEx(Source);
  2698. FFixedFunc.Assign(LMaterial.FFixedFunc);
  2699. FMultitexturing.Assign(LMaterial.FMultitexturing);
  2700. FSM3.Assign(LMaterial.FSM3);
  2701. FSM4.Assign(LMaterial.FSM4);
  2702. FSM5.Assign(LMaterial.FSM5);
  2703. FApplicableLevel := LMaterial.FApplicableLevel;
  2704. NotifyChange(Self);
  2705. end;
  2706. inherited;
  2707. end;
  2708. function TGLLibMaterialEx.Blended: Boolean;
  2709. begin
  2710. Result := FFixedFunc.Blended;
  2711. end;
  2712. constructor TGLLibMaterialEx.Create(ACollection: TCollection);
  2713. begin
  2714. inherited;
  2715. FHandle := TGLVirtualHandle.Create;
  2716. FHandle.OnAllocate := DoAllocate;
  2717. FHandle.OnDestroy := DoDeallocate;
  2718. FHandle.OnPrapare := DoOnPrepare;
  2719. FApplicableLevel := mlAuto;
  2720. FSelectedLevel := mlAuto;
  2721. FFixedFunc := TGLFixedFunctionProperties.Create(Self);
  2722. FMultitexturing := TGLMultitexturingProperties.Create(Self);
  2723. FSM3 := TGLShaderModel3.Create(Self);
  2724. FSM4 := TGLShaderModel4.Create(Self);
  2725. FSM5 := TGLShaderModel5.Create(Self);
  2726. end;
  2727. type
  2728. TGLFreindlyMaterial = class(TGLMaterial);
  2729. destructor TGLLibMaterialEx.Destroy;
  2730. var
  2731. I: Integer;
  2732. LUser: TObject;
  2733. begin
  2734. FHandle.Destroy;
  2735. FFixedFunc.Destroy;
  2736. FMultitexturing.Destroy;
  2737. FSM3.Destroy;
  2738. FSM4.Destroy;
  2739. FSM5.Destroy;
  2740. for I := 0 to FUserList.Count - 1 do
  2741. begin
  2742. LUser := TObject(FUserList[i]);
  2743. if LUser is TGLMaterial then
  2744. TGLFreindlyMaterial(LUser).NotifyLibMaterialDestruction;
  2745. end;
  2746. inherited;
  2747. end;
  2748. procedure TGLLibMaterialEx.DoAllocate(Sender: TGLVirtualHandle;
  2749. var handle: Cardinal);
  2750. begin
  2751. handle := 1;
  2752. end;
  2753. procedure TGLLibMaterialEx.DoDeallocate(Sender: TGLVirtualHandle;
  2754. var handle: Cardinal);
  2755. begin
  2756. handle := 0;
  2757. end;
  2758. procedure TGLLibMaterialEx.DoOnPrepare(Sender: TGLContext);
  2759. begin
  2760. end;
  2761. procedure TGLLibMaterialEx.Loaded;
  2762. begin
  2763. FFixedFunc.FTexProp.Loaded;
  2764. FMultitexturing.Loaded;
  2765. FSM3.Loaded;
  2766. FSM4.Loaded;
  2767. FSM5.Loaded;
  2768. end;
  2769. procedure TGLLibMaterialEx.NotifyChange(Sender: TObject);
  2770. begin
  2771. inherited;
  2772. FHandle.NotifyChangesOfData;
  2773. end;
  2774. procedure TGLLibMaterialEx.RemoveDefferedInit;
  2775. var
  2776. I: Integer;
  2777. ST: TGLShaderType;
  2778. begin
  2779. if FFixedFunc.FTexProp.Enabled then
  2780. begin
  2781. if Assigned(FFixedFunc.FTexProp.FLibTexture) then
  2782. FFixedFunc.FTexProp.FLibTexture.FDefferedInit := False;
  2783. if Assigned(FFixedFunc.FTexProp.FLibSampler) then
  2784. FFixedFunc.FTexProp.FLibSampler.FDefferedInit := False;
  2785. end;
  2786. if FMultitexturing.Enabled then
  2787. begin
  2788. if Assigned(FMultitexturing.FLibCombiner) then
  2789. begin
  2790. FMultitexturing.FLibCombiner.FDefferedInit := False;
  2791. for I := 0 to 3 do
  2792. if Assigned(FMultitexturing.FTexProps[I]) then
  2793. with FMultitexturing.FTexProps[I] do
  2794. begin
  2795. if Assigned(FLibTexture) then
  2796. FLibTexture.FDefferedInit := False;
  2797. if Assigned(FLibSampler) then
  2798. FLibSampler.FDefferedInit := False;
  2799. end;
  2800. end;
  2801. end;
  2802. if FSM3.Enabled then
  2803. begin
  2804. for ST := Low(TGLShaderType) to High(TGLShaderType) do
  2805. if Assigned(FSM3.FShaders[ST]) then
  2806. FSM3.FShaders[ST].FDefferedInit := False;
  2807. end;
  2808. if FSM4.Enabled then
  2809. begin
  2810. for ST := Low(TGLShaderType) to High(TGLShaderType) do
  2811. if Assigned(FSM4.FShaders[ST]) then
  2812. FSM4.FShaders[ST].FDefferedInit := False;
  2813. end;
  2814. if FSM5.Enabled then
  2815. begin
  2816. for ST := Low(TGLShaderType) to High(TGLShaderType) do
  2817. if Assigned(FSM5.FShaders[ST]) then
  2818. FSM5.FShaders[ST].FDefferedInit := False;
  2819. end;
  2820. CurrentGLContext.PrepareHandlesData;
  2821. end;
  2822. procedure TGLLibMaterialEx.SetMultitexturing(AValue:
  2823. TGLMultitexturingProperties);
  2824. begin
  2825. FMultitexturing.Assign(AValue);
  2826. end;
  2827. procedure TGLLibMaterialEx.SetFixedFunc(AValue: TGLFixedFunctionProperties);
  2828. begin
  2829. FFixedFunc.Assign(AValue);
  2830. end;
  2831. procedure TGLLibMaterialEx.SetLevel(AValue: TGLMaterialLevel);
  2832. begin
  2833. if FApplicableLevel <> AValue then
  2834. begin
  2835. FApplicableLevel := AValue;
  2836. NotifyChange(Self);
  2837. end;
  2838. end;
  2839. procedure TGLLibMaterialEx.SetSM3(AValue: TGLShaderModel3);
  2840. begin
  2841. FSM3.Assign(AValue);
  2842. end;
  2843. procedure TGLLibMaterialEx.SetSM4(AValue: TGLShaderModel4);
  2844. begin
  2845. FSM4.Assign(AValue);
  2846. end;
  2847. procedure TGLLibMaterialEx.SetSM5(AValue: TGLShaderModel5);
  2848. begin
  2849. FSM5.Assign(AValue);
  2850. end;
  2851. function TGLLibMaterialEx.UnApply(var ARci: TGLRenderContextInfo): Boolean;
  2852. procedure GetNextPass(AProp: TGLLibMaterialProperty);
  2853. begin
  2854. if Length(AProp.NextPass) > 0 then
  2855. FNextPass :=
  2856. TGLMaterialLibraryEx(GetMaterialLibrary).Materials.GetLibMaterialByName(AProp.NextPass)
  2857. else
  2858. FNextPass := nil;
  2859. if FNextPass = Self then
  2860. begin
  2861. AProp.NextPass := '';
  2862. FNextPass := nil;
  2863. end;
  2864. end;
  2865. begin
  2866. if FStoreAmalgamating <> ARci.amalgamating then
  2867. ARci.amalgamating := FStoreAmalgamating;
  2868. if Assigned(FNextPass) then
  2869. begin
  2870. Result := FNextPass.UnApply(ARci);
  2871. if Result then
  2872. FNextPass.Apply(ARci)
  2873. else
  2874. FNextPass := nil;
  2875. exit;
  2876. end;
  2877. case FSelectedLevel of
  2878. mlFixedFunction:
  2879. begin
  2880. FFixedFunc.UnApply(ARci);
  2881. GetNextPass(FFixedFunc);
  2882. end;
  2883. mlMultitexturing:
  2884. begin
  2885. if FFixedFunc.Enabled then
  2886. FFixedFunc.UnApply(ARci);
  2887. FMultitexturing.UnApply(ARci);
  2888. GetNextPass(FMultitexturing);
  2889. end;
  2890. mlSM3:
  2891. begin
  2892. if FFixedFunc.Enabled then
  2893. FFixedFunc.UnApply(ARci);
  2894. FSM3.UnApply(ARci);
  2895. GetNextPass(FSM3);
  2896. end;
  2897. mlSM4:
  2898. begin
  2899. if FFixedFunc.Enabled then
  2900. FFixedFunc.UnApply(ARci);
  2901. FSM4.UnApply(ARci);
  2902. GetNextPass(FSM4);
  2903. end;
  2904. mlSM5:
  2905. begin
  2906. if FFixedFunc.Enabled then
  2907. FFixedFunc.UnApply(ARci);
  2908. FSM5.UnApply(ARci);
  2909. GetNextPass(FSM5);
  2910. end;
  2911. else
  2912. FNextPass := nil;
  2913. end;
  2914. ARci.GLStates.ActiveTexture := 0;
  2915. Result := Assigned(FNextPass);
  2916. if Result then
  2917. FNextPass.Apply(ARCi);
  2918. end;
  2919. { TVXMultitexturingProperties }
  2920. procedure TGLMultitexturingProperties.Apply(var ARci: TGLRenderContextInfo);
  2921. var
  2922. N, U: Integer;
  2923. LDir: TGLVector;
  2924. begin
  2925. if FEnabled then
  2926. begin
  2927. if Assigned(FLibCombiner) and not FLibCombiner.FIsValid then
  2928. exit;
  2929. if Assigned(FLibAsmProg) and not FLibAsmProg.FIsValid then
  2930. exit;
  2931. U := 0;
  2932. for N := 0 to High(FTexProps) do
  2933. begin
  2934. if Assigned(FTexProps[N]) and FTexProps[N].Enabled then
  2935. begin
  2936. ARci.GLStates.ActiveTexture := N;
  2937. FTexProps[N].Apply(ARci);
  2938. if Ord(FLightDir) = N+1 then
  2939. begin
  2940. LDir := ARci.GLStates.LightPosition[FLightSourceIndex];
  2941. LDir := VectorTransform(LDir, ARci.PipelineTransformation.InvModelMatrix^);
  2942. NormalizeVector(LDir);
  2943. gl.TexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, @LDir);
  2944. end;
  2945. U := U or (1 shl N);
  2946. end;
  2947. end;
  2948. if Assigned(FLibAsmProg) then
  2949. begin
  2950. FLibAsmProg.Handle.Bind;
  2951. gl.Enable(GL_VERTEX_PROGRAM_ARB);
  2952. if Assigned(GetMaterial.FOnAsmProgSetting) then
  2953. GetMaterial.FOnAsmProgSetting(Self.FLibAsmProg, ARci);
  2954. end;
  2955. with GL, ARci.GLStates do
  2956. begin
  2957. if Assigned(FLibCombiner) and (Length(FLibCombiner.FCommandCache) > 0)
  2958. then
  2959. begin
  2960. for N := 0 to High(FLibCombiner.FCommandCache) do
  2961. begin
  2962. ActiveTexture := FLibCombiner.FCommandCache[N].ActiveUnit;
  2963. TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
  2964. TexEnvi(GL_TEXTURE_ENV,
  2965. FLibCombiner.FCommandCache[N].Arg1,
  2966. FLibCombiner.FCommandCache[N].Arg2);
  2967. end;
  2968. end;
  2969. TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, cTextureMode[FTextureMode]);
  2970. ActiveTexture := 0;
  2971. end;
  2972. XGL.BeginUpdate;
  2973. if U > 3 then
  2974. XGL.MapTexCoordToArbitrary(U)
  2975. else if (FTexProps[0].Enabled)
  2976. and (FTexProps[0].MappingMode = tmmUser) then
  2977. if FTexProps[1].MappingMode = tmmUser then
  2978. XGL.MapTexCoordToDual
  2979. else
  2980. XGL.MapTexCoordToMain
  2981. else if FTexProps[1].MappingMode = tmmUser then
  2982. XGL.MapTexCoordToSecond
  2983. else
  2984. XGL.MapTexCoordToMain;
  2985. XGL.EndUpdate;
  2986. end;
  2987. end;
  2988. constructor TGLMultitexturingProperties.Create(AOwner: TPersistent);
  2989. begin
  2990. inherited;
  2991. FEnabled := False;
  2992. FTextureMode := tmDecal;
  2993. FLightDir := l2eNone;
  2994. FLightSourceIndex := 0;
  2995. end;
  2996. destructor TGLMultitexturingProperties.Destroy;
  2997. begin
  2998. if Assigned(FLibCombiner) then
  2999. FLibCombiner.UnregisterUser(Self);
  3000. if Assigned(FLibAsmProg) then
  3001. FLibAsmProg.UnregisterUser(Self);
  3002. FTexProps[0].Free;
  3003. FTexProps[1].Free;
  3004. FTexProps[2].Free;
  3005. FTexProps[3].Free;
  3006. inherited;
  3007. end;
  3008. function TGLMultitexturingProperties.GetLibCombinerName: string;
  3009. begin
  3010. if Assigned(FLibCombiner) then
  3011. Result := FLibCombiner.Name
  3012. else
  3013. Result := '';
  3014. end;
  3015. function TGLMultitexturingProperties.GetLibAsmProgName: string;
  3016. begin
  3017. if Assigned(FLibAsmProg) then
  3018. Result := FLibAsmProg.Name
  3019. else
  3020. Result := '';
  3021. end;
  3022. function TGLMultitexturingProperties.IsValid: Boolean;
  3023. var
  3024. I: Integer;
  3025. begin
  3026. Result := True;
  3027. if Assigned(FLibCombiner) then
  3028. Result := Result and FLibCombiner.IsValid;
  3029. if Assigned(FLibAsmProg) then
  3030. Result := Result and FLibAsmProg.IsValid;
  3031. for I := 0 to High(FTexProps) do
  3032. if Assigned(FTexProps[I]) and FTexProps[I].FEnabled then
  3033. Result := Result and FTexProps[I].IsValid;
  3034. end;
  3035. procedure TGLMultitexturingProperties.Loaded;
  3036. var
  3037. I: Integer;
  3038. begin
  3039. SetLibCombinerName(FLibCombinerName);
  3040. SetLibAsmProgName(FLibAsmProgName);
  3041. for I := 0 to High(FTexProps) do
  3042. if Assigned(FTexProps[I]) then
  3043. FTexProps[I].Loaded;
  3044. end;
  3045. procedure TGLMultitexturingProperties.Notification(Sender: TObject; Operation:
  3046. TOperation);
  3047. begin
  3048. if Operation = opRemove then
  3049. begin
  3050. if Sender = FLibCombiner then
  3051. FLibCombiner := nil;
  3052. if Sender = FLibAsmProg then
  3053. FLibAsmProg := nil;
  3054. end;
  3055. inherited;
  3056. end;
  3057. procedure TGLMultitexturingProperties.SetLibCombinerName(const AValue: string);
  3058. var
  3059. LCombiner: TGLTextureCombiner;
  3060. begin
  3061. if csLoading in GetMaterialLibraryEx.ComponentState then
  3062. begin
  3063. FLibCombinerName := AValue;
  3064. exit;
  3065. end;
  3066. if Assigned(FLibCombiner) then
  3067. begin
  3068. if FLibCombiner.Name = AValue then
  3069. exit;
  3070. FLibCombiner.UnregisterUser(Self);
  3071. FLibCombiner := nil;
  3072. end;
  3073. LCombiner := GetMaterialLibraryEx.Components.GetCombinerByName(AValue);
  3074. if Assigned(LCombiner) then
  3075. begin
  3076. LCombiner.RegisterUser(Self);
  3077. FLibCombiner := LCombiner;
  3078. end;
  3079. NotifyChange(Self);
  3080. end;
  3081. procedure TGLMultitexturingProperties.SetLightSourceIndex(AValue: Integer);
  3082. begin
  3083. if AValue < 0 then
  3084. AValue := 0
  3085. else if AValue > 7 then
  3086. AValue := 7;
  3087. FLightSourceIndex := AValue;
  3088. end;
  3089. procedure TGLMultitexturingProperties.SetLibAsmProgName(const AValue: string);
  3090. var
  3091. LProg: TGLASMVertexProgram;
  3092. begin
  3093. if csLoading in GetMaterialLibraryEx.ComponentState then
  3094. begin
  3095. FLibAsmProgName := AValue;
  3096. exit;
  3097. end;
  3098. if Assigned(FLibAsmProg) then
  3099. begin
  3100. if FLibAsmProg.Name = AValue then
  3101. exit;
  3102. FLibAsmProg.UnregisterUser(Self);
  3103. FLibAsmProg := nil;
  3104. end;
  3105. LProg := GetMaterialLibraryEx.Components.GetAsmProgByName(AValue);
  3106. if Assigned(LProg) then
  3107. begin
  3108. LProg.RegisterUser(Self);
  3109. FLibAsmProg := LProg;
  3110. end;
  3111. NotifyChange(Self);
  3112. end;
  3113. function TGLMultitexturingProperties.GetTexProps(AIndex: Integer):
  3114. TGLTextureProperties;
  3115. begin
  3116. if not Assigned(FTexProps[AIndex]) then
  3117. FTexProps[AIndex] := TGLTextureProperties.Create(Self);
  3118. Result := FTexProps[AIndex];
  3119. end;
  3120. procedure TGLMultitexturingProperties.SetTexProps(AIndex: Integer;
  3121. AValue: TGLTextureProperties);
  3122. begin
  3123. FTexProps[AIndex].Assign(AValue);
  3124. end;
  3125. procedure TGLMultitexturingProperties.SetTextureMode(AValue: TGLTextureMode);
  3126. begin
  3127. if AValue <> FTextureMode then
  3128. begin
  3129. FTextureMode := AValue;
  3130. NotifyChange(Self);
  3131. end;
  3132. end;
  3133. procedure TGLMultitexturingProperties.UnApply(var ARci: TGLRenderContextInfo);
  3134. var
  3135. N: Integer;
  3136. begin
  3137. for N := 0 to High(FTexProps) do
  3138. begin
  3139. if FTexProps[N].Enabled then
  3140. begin
  3141. ARci.GLStates.ActiveTexture := N;
  3142. FTexProps[N].UnApply(ARci);
  3143. end;
  3144. end;
  3145. ARci.GLStates.ActiveTexture := 0;
  3146. if Assigned(FLibAsmProg) then
  3147. gl.Disable(GL_VERTEX_PROGRAM_ARB);
  3148. end;
  3149. { TVXTextureProperties }
  3150. procedure TGLTextureProperties.Apply(var ARci: TGLRenderContextInfo);
  3151. var
  3152. glTarget: Cardinal;
  3153. begin
  3154. if Assigned(FLibTexture) then
  3155. begin
  3156. FLibTexture.FApplicableSampler := FLibSampler;
  3157. FLibTexture.Apply(ARci);
  3158. // Apply swizzling if possible
  3159. glTarget := DecodeTextureTarget(FLibTexture.Shape);
  3160. if GL.ARB_texture_swizzle or GL.EXT_texture_swizzle then
  3161. begin
  3162. if FSwizzling.FSwizzles[0] <> FLibTexture.FSwizzles[0] then
  3163. begin
  3164. FLibTexture.FSwizzles[0] := FSwizzling.FSwizzles[0];
  3165. gl.TexParameteri(glTarget, GL_TEXTURE_SWIZZLE_R,
  3166. cTextureSwizzle[FSwizzling.FSwizzles[0]]);
  3167. end;
  3168. if FSwizzling.FSwizzles[1] <> FLibTexture.FSwizzles[1] then
  3169. begin
  3170. FLibTexture.FSwizzles[1] := FSwizzling.FSwizzles[1];
  3171. gl.TexParameteri(glTarget, GL_TEXTURE_SWIZZLE_G,
  3172. cTextureSwizzle[FSwizzling.FSwizzles[1]]);
  3173. end;
  3174. if FSwizzling.FSwizzles[2] <> FLibTexture.FSwizzles[2] then
  3175. begin
  3176. FLibTexture.FSwizzles[2] := FSwizzling.FSwizzles[2];
  3177. gl.TexParameteri(glTarget, GL_TEXTURE_SWIZZLE_B,
  3178. cTextureSwizzle[FSwizzling.FSwizzles[2]]);
  3179. end;
  3180. if FSwizzling.FSwizzles[3] <> FLibTexture.FSwizzles[3] then
  3181. begin
  3182. FLibTexture.FSwizzles[3] := FSwizzling.FSwizzles[3];
  3183. gl.TexParameteri(glTarget, GL_TEXTURE_SWIZZLE_A,
  3184. cTextureSwizzle[FSwizzling.FSwizzles[3]]);
  3185. end;
  3186. end;
  3187. if Assigned(FLibSampler) then
  3188. begin
  3189. if FLibSampler.IsValid then
  3190. FLibSampler.Apply(ARci)
  3191. else if FLibTexture.FLastSampler <> FLibSampler then
  3192. begin
  3193. // Sampler object not supported, lets use texture states
  3194. gl.TexParameterfv(glTarget, GL_TEXTURE_BORDER_COLOR,
  3195. FLibSampler.BorderColor.AsAddress);
  3196. gl.TexParameteri(glTarget, GL_TEXTURE_WRAP_S,
  3197. cTextureWrapMode[FLibSampler.WrapX]);
  3198. gl.TexParameteri(glTarget, GL_TEXTURE_WRAP_T,
  3199. cTextureWrapMode[FLibSampler.WrapY]);
  3200. gl.TexParameteri(glTarget, GL_TEXTURE_WRAP_R,
  3201. cTextureWrapMode[FLibSampler.WrapZ]);
  3202. gl.TexParameterf(glTarget, GL_TEXTURE_LOD_BIAS, FLibSampler.LODBias +
  3203. FLibSampler.FLODBiasFract);
  3204. gl.TexParameteri(glTarget, GL_TEXTURE_MIN_FILTER,
  3205. cTextureMinFilter[FLibSampler.MinFilter]);
  3206. gl.TexParameteri(glTarget, GL_TEXTURE_MAG_FILTER,
  3207. cTextureMagFilter[FLibSampler.MagFilter]);
  3208. if GL.EXT_texture_filter_anisotropic then
  3209. begin
  3210. if FLibSampler.FilteringQuality = tfAnisotropic then
  3211. gl.TexParameteri(glTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT,
  3212. CurrentGLContext.GLStates.MaxTextureAnisotropy)
  3213. else
  3214. gl.TexParameteri(glTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
  3215. end;
  3216. gl.TexParameteri(glTarget, GL_TEXTURE_COMPARE_MODE,
  3217. cTextureCompareMode[FLibSampler.CompareMode]);
  3218. gl.TexParameteri(glTarget, GL_TEXTURE_COMPARE_FUNC,
  3219. cGLComparisonFunctionToGLEnum[FLibSampler.CompareFunc]);
  3220. if GL.EXT_texture_sRGB_decode then
  3221. begin
  3222. if FLibSampler.sRGB_Encode then
  3223. gl.TexParameteri(glTarget, GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT)
  3224. else
  3225. gl.TexParameteri(glTarget, GL_TEXTURE_SRGB_DECODE_EXT,
  3226. GL_SKIP_DECODE_EXT);
  3227. end;
  3228. FLibTexture.FLastSampler := FLibSampler;
  3229. end;
  3230. end;
  3231. if not FTextureMatrixIsIdentity and (MappingMode = tmmUser) then
  3232. ARci.GLStates.SetGLTextureMatrix(FTextureMatrix);
  3233. if ARci.currentMaterialLevel < mlSM3 then
  3234. begin
  3235. gl.TexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, FEnvColor.AsAddress);
  3236. ApplyMappingMode;
  3237. if ARci.currentMaterialLevel = mlFixedFunction then
  3238. XGL.MapTexCoordToMain;
  3239. end;
  3240. end;
  3241. end;
  3242. procedure TGLTextureProperties.ApplyMappingMode;
  3243. var
  3244. R_Dim: Boolean;
  3245. begin
  3246. begin
  3247. R_Dim := GL.ARB_texture_cube_map or GL.EXT_texture3D;
  3248. case MappingMode of
  3249. tmmUser: ; // nothing to do, but checked first (common case)
  3250. tmmObjectLinear:
  3251. begin
  3252. gl.TexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  3253. gl.TexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  3254. gl.TexGenfv(GL_S, GL_OBJECT_PLANE, @MappingSCoordinates.DirectVector);
  3255. gl.TexGenfv(GL_T, GL_OBJECT_PLANE, @MappingTCoordinates.DirectVector);
  3256. gl.Enable(GL_TEXTURE_GEN_S);
  3257. gl.Enable(GL_TEXTURE_GEN_T);
  3258. if R_Dim then
  3259. begin
  3260. gl.TexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  3261. gl.TexGeni(GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
  3262. gl.TexGenfv(GL_R, GL_OBJECT_PLANE, @MappingRCoordinates.DirectVector);
  3263. gl.TexGenfv(GL_Q, GL_OBJECT_PLANE, @MappingQCoordinates.DirectVector);
  3264. gl.Enable(GL_TEXTURE_GEN_R);
  3265. gl.Enable(GL_TEXTURE_GEN_Q);
  3266. end;
  3267. end;
  3268. tmmEyeLinear:
  3269. begin
  3270. gl.TexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  3271. gl.TexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_EYE_LINEAR);
  3272. // specify planes in eye space, not world space
  3273. gl.MatrixMode(GL_MODELVIEW);
  3274. gl.PushMatrix;
  3275. gl.LoadIdentity;
  3276. gl.TexGenfv(GL_S, GL_EYE_PLANE, @MappingSCoordinates.DirectVector);
  3277. gl.TexGenfv(GL_T, GL_EYE_PLANE, @MappingTCoordinates.DirectVector);
  3278. gl.Enable(GL_TEXTURE_GEN_S);
  3279. gl.Enable(GL_TEXTURE_GEN_T);
  3280. if R_Dim then
  3281. begin
  3282. gl.TexGenfv(GL_R, GL_EYE_PLANE, @MappingRCoordinates.DirectVector);
  3283. gl.TexGenfv(GL_Q, GL_EYE_PLANE, @MappingQCoordinates.DirectVector);
  3284. gl.Enable(GL_TEXTURE_GEN_R);
  3285. gl.Enable(GL_TEXTURE_GEN_Q);
  3286. end;
  3287. gl.PopMatrix;
  3288. end;
  3289. tmmSphere:
  3290. begin
  3291. gl.TexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  3292. gl.TexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
  3293. gl.Enable(GL_TEXTURE_GEN_S);
  3294. gl.Enable(GL_TEXTURE_GEN_T);
  3295. end;
  3296. tmmCubeMapReflection, tmmCubeMapCamera:
  3297. if R_Dim then
  3298. begin
  3299. gl.TexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  3300. gl.TexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  3301. gl.TexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
  3302. gl.Enable(GL_TEXTURE_GEN_S);
  3303. gl.Enable(GL_TEXTURE_GEN_T);
  3304. gl.Enable(GL_TEXTURE_GEN_R);
  3305. end;
  3306. tmmCubeMapNormal, tmmCubeMapLight0:
  3307. if R_Dim then
  3308. begin
  3309. gl.TexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  3310. gl.TexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  3311. gl.TexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
  3312. gl.Enable(GL_TEXTURE_GEN_S);
  3313. gl.Enable(GL_TEXTURE_GEN_T);
  3314. gl.Enable(GL_TEXTURE_GEN_R);
  3315. end;
  3316. end;
  3317. end;
  3318. end;
  3319. procedure TGLTextureProperties.Assign(Source: TPersistent);
  3320. var
  3321. LTexProp: TGLTextureProperties;
  3322. begin
  3323. if Source is TGLTextureProperties then
  3324. begin
  3325. LTexProp := TGLTextureProperties(Source);
  3326. LibTextureName := LTexProp.LibTextureName;
  3327. LibSamplerName := LTexProp.LibSamplerName;
  3328. TextureOffset.Assign(LTexProp.TextureOffset);
  3329. TextureScale.Assign(LTexProp.TextureScale);
  3330. FTextureRotate := LTexProp.TextureRotate;
  3331. FEnvColor.Assign(LTexProp.EnvColor);
  3332. FMappingMode := LTexProp.MappingMode;
  3333. MappingSCoordinates.Assign(LTexProp.MappingSCoordinates);
  3334. MappingTCoordinates.Assign(LTexProp.MappingTCoordinates);
  3335. MappingRCoordinates.Assign(LTexProp.MappingRCoordinates);
  3336. MappingQCoordinates.Assign(LTexProp.MappingQCoordinates);
  3337. end;
  3338. inherited;
  3339. end;
  3340. procedure TGLTextureProperties.CalculateTextureMatrix;
  3341. begin
  3342. if not (Assigned(FTextureOffset) or Assigned(FTextureScale)
  3343. or StoreTextureRotate) then
  3344. begin
  3345. FTextureMatrixIsIdentity := True;
  3346. exit;
  3347. end;
  3348. if TextureOffset.Equals(NullHmgVector)
  3349. and TextureScale.Equals(XYZHmgVector)
  3350. and not StoreTextureRotate then
  3351. FTextureMatrixIsIdentity := True
  3352. else
  3353. begin
  3354. FTextureMatrixIsIdentity := False;
  3355. FTextureMatrix := CreateScaleAndTranslationMatrix(
  3356. TextureScale.AsVector,
  3357. TextureOffset.AsVector);
  3358. if StoreTextureRotate then
  3359. FTextureMatrix := MatrixMultiply(FTextureMatrix,
  3360. CreateRotationMatrixZ(DegToRad(FTextureRotate)));
  3361. end;
  3362. FTextureOverride := False;
  3363. NotifyChange(Self);
  3364. end;
  3365. constructor TGLTextureProperties.Create(AOwner: TPersistent);
  3366. begin
  3367. inherited;
  3368. FTextureRotate := 0;
  3369. FMappingMode := tmmUser;
  3370. FTextureMatrix := IdentityHmgMatrix;
  3371. FEnabled := False;
  3372. FSwizzling := TGLTextureSwizzling.Create(Self);
  3373. FEnvColor := TGLColor.CreateInitialized(Self, clrTransparent);
  3374. end;
  3375. destructor TGLTextureProperties.Destroy;
  3376. begin
  3377. if Assigned(FLibSampler) then
  3378. FLibSampler.UnregisterUser(Self);
  3379. if Assigned(FLibTexture) then
  3380. FLibTexture.UnregisterUser(Self);
  3381. FTextureOffset.Free;
  3382. FTextureScale.Free;
  3383. FMapSCoordinates.Free;
  3384. FMapTCoordinates.Free;
  3385. FMapRCoordinates.Free;
  3386. FMapQCoordinates.Free;
  3387. FSwizzling.Destroy;
  3388. FEnvColor.Destroy;
  3389. inherited;
  3390. end;
  3391. function TGLTextureProperties.GetLibSamplerName: TGLMaterialComponentName;
  3392. begin
  3393. if Assigned(FLibSampler) then
  3394. Result := FLibSampler.Name
  3395. else
  3396. Result := '';
  3397. end;
  3398. function TGLTextureProperties.GetLibTextureName: TGLMaterialComponentName;
  3399. begin
  3400. if Assigned(FLibTexture) then
  3401. Result := FLibTexture.Name
  3402. else
  3403. Result := '';
  3404. end;
  3405. function TGLTextureProperties.GetMappingQCoordinates: TGLCoordinates4;
  3406. begin
  3407. if not Assigned(FMapQCoordinates) then
  3408. FMapQCoordinates := TGLCoordinates4.CreateInitialized(Self, WHmgVector,
  3409. csVector);
  3410. Result := FMapQCoordinates;
  3411. end;
  3412. function TGLTextureProperties.GetMappingRCoordinates: TGLCoordinates4;
  3413. begin
  3414. if not Assigned(FMapRCoordinates) then
  3415. FMapRCoordinates := TGLCoordinates4.CreateInitialized(Self, ZHmgVector,
  3416. csVector);
  3417. Result := FMapRCoordinates;
  3418. end;
  3419. function TGLTextureProperties.GetMappingSCoordinates: TGLCoordinates4;
  3420. begin
  3421. if not Assigned(FMapSCoordinates) then
  3422. FMapSCoordinates := TGLCoordinates4.CreateInitialized(Self, XHmgVector,
  3423. csVector);
  3424. Result := FMapSCoordinates;
  3425. end;
  3426. function TGLTextureProperties.GetMappingTCoordinates: TGLCoordinates4;
  3427. begin
  3428. if not Assigned(FMapTCoordinates) then
  3429. FMapTCoordinates := TGLCoordinates4.CreateInitialized(Self, YHmgVector,
  3430. csVector);
  3431. Result := FMapTCoordinates;
  3432. end;
  3433. function TGLTextureProperties.GetTextureOffset: TGLCoordinates;
  3434. begin
  3435. if not Assigned(FTextureOffset) then
  3436. FTextureOffset :=
  3437. TGLCoordinates3.CreateInitialized(Self, NullHmgVector, csPoint);
  3438. Result := FTextureOffset;
  3439. end;
  3440. function TGLTextureProperties.GetTextureScale: TGLCoordinates;
  3441. begin
  3442. if not Assigned(FTextureScale) then
  3443. FTextureScale :=
  3444. TGLCoordinates3.CreateInitialized(Self, VectorMake(1, 1, 1, 1), csVector);
  3445. Result := FTextureScale;
  3446. end;
  3447. function TGLTextureProperties.IsValid: Boolean;
  3448. begin
  3449. if Assigned(FLibTexture) then
  3450. Result := FLibTexture.IsValid
  3451. else
  3452. Result := False;
  3453. end;
  3454. procedure TGLTextureProperties.Loaded;
  3455. begin
  3456. SetLibTextureName(FLibTextureName);
  3457. SetLibSamplerName(FLibSamplerName);
  3458. CalculateTextureMatrix;
  3459. end;
  3460. procedure TGLTextureProperties.Notification(Sender: TObject;
  3461. Operation: TOperation);
  3462. begin
  3463. if Operation = opRemove then
  3464. begin
  3465. if Sender = FLibTexture then
  3466. FLibTexture := nil
  3467. else if Sender = FLibSampler then
  3468. FLibSampler := nil;
  3469. end;
  3470. end;
  3471. procedure TGLTextureProperties.NotifyChange(Sender: TObject);
  3472. begin
  3473. inherited;
  3474. if (Sender = FTextureOffset) or (Sender = FTextureScale) then
  3475. CalculateTextureMatrix;
  3476. if (Sender = FLibSampler) and Assigned(FLibTexture) then
  3477. FLibTexture.FLastSampler := nil;
  3478. end;
  3479. procedure TGLTextureProperties.SetLibSamplerName(const AValue:
  3480. TGLMaterialComponentName);
  3481. var
  3482. LSampler: TGLTextureSampler;
  3483. begin
  3484. if csLoading in GetMaterialLibraryEx.ComponentState then
  3485. begin
  3486. FLibSamplerName := AValue;
  3487. exit;
  3488. end;
  3489. if Assigned(FLibSampler) then
  3490. begin
  3491. if FLibSampler.Name = AValue then
  3492. exit;
  3493. FLibSampler.UnregisterUser(Self);
  3494. FLibSampler := nil;
  3495. end;
  3496. LSampler := GetMaterialLibraryEx.Components.GetSamplerByName(AValue);
  3497. if Assigned(LSampler) then
  3498. begin
  3499. LSampler.RegisterUser(Self);
  3500. FLibSampler := LSampler;
  3501. end;
  3502. NotifyChange(Self);
  3503. end;
  3504. procedure TGLTextureProperties.SetLibTextureName(const AValue:
  3505. TGLMaterialComponentName);
  3506. var
  3507. LTexture: TGLAbstractTexture;
  3508. begin
  3509. if csLoading in GetMaterialLibraryEx.ComponentState then
  3510. begin
  3511. FLibTextureName := AValue;
  3512. exit;
  3513. end;
  3514. if Assigned(FLibTexture) then
  3515. begin
  3516. if FLibTexture.Name = AValue then
  3517. exit;
  3518. FLibTexture.UnregisterUser(Self);
  3519. FLibTexture := nil;
  3520. end;
  3521. LTexture := GetMaterialLibraryEx.Components.GetTextureByName(AValue);
  3522. if Assigned(LTexture) then
  3523. begin
  3524. if LTexture is TGLFrameBufferAttachment then
  3525. begin
  3526. if TGLFrameBufferAttachment(LTexture).OnlyWrite then
  3527. begin
  3528. if IsDesignTime then
  3529. InformationDlg('Can not use write only attachment as texture')
  3530. else
  3531. GLSLogger.LogErrorFmt('Attempt to use write only attachment "%s" as texture',
  3532. [LTexture.Name]);
  3533. NotifyChange(Self);
  3534. exit;
  3535. end;
  3536. end;
  3537. LTexture.RegisterUser(Self);
  3538. FLibTexture := LTexture;
  3539. end;
  3540. NotifyChange(Self);
  3541. end;
  3542. procedure TGLTextureProperties.SetMappingMode(
  3543. const AValue: TGLTextureMappingMode);
  3544. begin
  3545. if AValue <> FMappingMode then
  3546. begin
  3547. FMappingMode := AValue;
  3548. NotifyChange(Self);
  3549. end;
  3550. end;
  3551. procedure TGLTextureProperties.SetMappingQCoordinates(
  3552. const AValue: TGLCoordinates4);
  3553. begin
  3554. MappingQCoordinates.Assign(AValue);
  3555. end;
  3556. procedure TGLTextureProperties.SetMappingRCoordinates(
  3557. const AValue: TGLCoordinates4);
  3558. begin
  3559. MappingRCoordinates.Assign(AValue);
  3560. end;
  3561. procedure TGLTextureProperties.SetMappingSCoordinates(
  3562. const AValue: TGLCoordinates4);
  3563. begin
  3564. MappingSCoordinates.Assign(AValue);
  3565. end;
  3566. procedure TGLTextureProperties.SetMappingTCoordinates(
  3567. const AValue: TGLCoordinates4);
  3568. begin
  3569. MappingTCoordinates.Assign(AValue);
  3570. end;
  3571. procedure TGLTextureProperties.SetSwizzling(const AValue: TGLTextureSwizzling);
  3572. begin
  3573. FSwizzling.Assign(AValue);
  3574. end;
  3575. procedure TGLTextureProperties.SetTextureMatrix(const AValue: TGLMatrix);
  3576. begin
  3577. FTextureMatrixIsIdentity := CompareMem(@AValue.V[0], @IdentityHmgMatrix.V[0],
  3578. SizeOf(TGLMatrix));
  3579. FTextureMatrix := AValue;
  3580. FTextureOverride := True;
  3581. NotifyChange(Self);
  3582. end;
  3583. procedure TGLTextureProperties.SetTextureOffset(const AValue: TGLCoordinates);
  3584. begin
  3585. TextureOffset.Assign(AValue);
  3586. CalculateTextureMatrix;
  3587. end;
  3588. procedure TGLTextureProperties.SetTextureRotate(AValue: Single);
  3589. begin
  3590. if AValue <> FTextureRotate then
  3591. begin
  3592. FTextureRotate := AValue;
  3593. CalculateTextureMatrix;
  3594. NotifyChange(Self);
  3595. end;
  3596. end;
  3597. procedure TGLTextureProperties.SetTextureScale(const AValue: TGLCoordinates);
  3598. begin
  3599. TextureScale.Assign(AValue);
  3600. CalculateTextureMatrix;
  3601. end;
  3602. function TGLTextureProperties.StoreMappingQCoordinates: Boolean;
  3603. begin
  3604. if Assigned(FMapQCoordinates) then
  3605. Result := not VectorEquals(FMapQCoordinates.AsVector, WHmgVector)
  3606. else
  3607. Result := false;
  3608. end;
  3609. function TGLTextureProperties.StoreMappingRCoordinates: Boolean;
  3610. begin
  3611. if Assigned(FMapRCoordinates) then
  3612. Result := not VectorEquals(FMapRCoordinates.AsVector, ZHmgVector)
  3613. else
  3614. Result := false;
  3615. end;
  3616. function TGLTextureProperties.StoreMappingSCoordinates: Boolean;
  3617. begin
  3618. if Assigned(FMapSCoordinates) then
  3619. Result := not VectorEquals(FMapSCoordinates.AsVector, XHmgVector)
  3620. else
  3621. Result := false;
  3622. end;
  3623. function TGLTextureProperties.StoreMappingTCoordinates: Boolean;
  3624. begin
  3625. if Assigned(FMapTCoordinates) then
  3626. Result := not VectorEquals(FMapTCoordinates.AsVector, YHmgVector)
  3627. else
  3628. Result := false;
  3629. end;
  3630. function TGLTextureProperties.StoreSwizzling: Boolean;
  3631. begin
  3632. Result := FSwizzling.StoreSwizzle(0);
  3633. end;
  3634. function TGLTextureProperties.StoreTextureOffset: Boolean;
  3635. begin
  3636. Result := Assigned(FTextureOffset);
  3637. end;
  3638. function TGLTextureProperties.StoreTextureRotate: Boolean;
  3639. begin
  3640. Result := Abs(FTextureRotate) > EPSILON;
  3641. end;
  3642. function TGLTextureProperties.StoreTextureScale: Boolean;
  3643. begin
  3644. Result := Assigned(FTextureScale);
  3645. end;
  3646. procedure TGLTextureProperties.SetEnvColor(const AValue:
  3647. TGLColor);
  3648. begin
  3649. FEnvColor.Assign(AValue);
  3650. NotifyChange(Self);
  3651. end;
  3652. procedure TGLTextureProperties.UnApply(var ARci: TGLRenderContextInfo);
  3653. begin
  3654. if Assigned(FLibTexture) then
  3655. begin
  3656. FLibTexture.UnApply(ARci);
  3657. if Assigned(FLibSampler) then
  3658. FLibSampler.UnApply(ARci);
  3659. if ARci.currentMaterialLevel < mlSM3 then
  3660. begin
  3661. if not FTextureMatrixIsIdentity and (MappingMode = tmmUser) then
  3662. ARci.GLStates.SetGLTextureMatrix(IdentityHmgMatrix);
  3663. UnApplyMappingMode;
  3664. end;
  3665. end;
  3666. end;
  3667. procedure TGLTextureProperties.UnApplyMappingMode;
  3668. begin
  3669. if MappingMode <> tmmUser then
  3670. begin
  3671. gl.Disable(GL_TEXTURE_GEN_S);
  3672. gl.Disable(GL_TEXTURE_GEN_T);
  3673. if gl.EXT_texture3D or gl.ARB_texture_cube_map then
  3674. begin
  3675. gl.Disable(GL_TEXTURE_GEN_R);
  3676. gl.Disable(GL_TEXTURE_GEN_Q);
  3677. end;
  3678. end;
  3679. end;
  3680. { TVXShaderEx }
  3681. procedure TGLShaderEx.Assign(Source: TPersistent);
  3682. var
  3683. LShader: TGLShaderEx;
  3684. begin
  3685. if Source is TGLShaderEx then
  3686. begin
  3687. LShader := TGLShaderEx(Source);
  3688. FSource.Assign(LShader.Source);
  3689. FShaderType := LShader.FShaderType;
  3690. NotifyChange(Self);
  3691. end;
  3692. inherited;
  3693. end;
  3694. constructor TGLShaderEx.Create(AOwner: TXCollection);
  3695. const
  3696. cShaderClasses: array[TGLShaderType] of TGLShaderHandleClass =
  3697. (
  3698. TGLVertexShaderHandle,
  3699. TGLTessControlShaderHandle,
  3700. TGLTessEvaluationShaderHandle,
  3701. TGLGeometryShaderHandle,
  3702. TGLFragmentShaderHandle
  3703. );
  3704. var
  3705. S: TGLShaderType;
  3706. begin
  3707. inherited;
  3708. FDefferedInit := False;
  3709. for S := Low(TGLShaderType) to High(TGLShaderType) do
  3710. begin
  3711. FHandle[S] := cShaderClasses[S].Create;
  3712. FHandle[S].OnPrapare := DoOnPrepare;
  3713. end;
  3714. FSource := TStringList.Create;
  3715. FSource.OnChange := NotifyChange;
  3716. FShaderType := shtVertex;
  3717. FGeometryInput := gsInPoints;
  3718. FGeometryOutput := gsOutPoints;
  3719. FGeometryVerticesOut := 1;
  3720. Name := TGLMatLibComponents(AOwner).MakeUniqueName('Shader');
  3721. end;
  3722. destructor TGLShaderEx.Destroy;
  3723. var
  3724. S: TGLShaderType;
  3725. begin
  3726. for S := Low(TGLShaderType) to High(TGLShaderType) do
  3727. FHandle[S].Destroy;
  3728. FSource.Destroy;
  3729. inherited;
  3730. end;
  3731. procedure TGLShaderEx.NotifyChange(Sender: TObject);
  3732. var
  3733. S: TGLShaderType;
  3734. begin
  3735. for S := Low(TGLShaderType) to High(TGLShaderType) do
  3736. FHandle[S].NotifyChangesOfData;
  3737. if (Sender = FSource) and IsDesignTime and (Length(FSourceFile) > 0) then
  3738. FSource.SaveToFile(FSourceFile);
  3739. inherited;
  3740. end;
  3741. procedure TGLShaderEx.DoOnPrepare(Sender: TGLContext);
  3742. begin
  3743. if not IsDesignTime and FDefferedInit then
  3744. exit;
  3745. try
  3746. if FHandle[FShaderType].IsSupported then
  3747. begin
  3748. FHandle[FShaderType].AllocateHandle;
  3749. if FHandle[FShaderType].IsDataNeedUpdate then
  3750. begin
  3751. SetExeDirectory;
  3752. if (Length(FSourceFile) > 0) and FileStreamExists(FSourceFile) then
  3753. FSource.LoadFromFile(FSourceFile);
  3754. FHandle[FShaderType].ShaderSource(AnsiString(FSource.Text));
  3755. FIsValid := FHandle[FShaderType].CompileShader;
  3756. if IsDesignTime then
  3757. begin
  3758. FInfoLog := FHandle[FShaderType].InfoLog;
  3759. if (Length(FInfoLog) = 0) and FIsValid then
  3760. FInfoLog := 'Compilation successful';
  3761. end
  3762. else if FIsValid then
  3763. GLSLogger.LogInfoFmt('Shader "%s" compilation successful - %s',
  3764. [Name, FHandle[FShaderType].InfoLog])
  3765. else
  3766. GLSLogger.LogErrorFmt('Shader "%s" compilation failed - %s',
  3767. [Name, FHandle[FShaderType].InfoLog]);
  3768. FHandle[FShaderType].NotifyDataUpdated;
  3769. end;
  3770. end
  3771. else
  3772. begin
  3773. FIsValid := False;
  3774. if IsDesignTime then
  3775. FInfoLog := 'Not supported by hardware';
  3776. end;
  3777. except
  3778. on E: Exception do
  3779. begin
  3780. FIsValid := False;
  3781. if IsDesignTime then
  3782. InformationDlg(E.ClassName + ': ' + E.Message)
  3783. else
  3784. GLSLogger.LogError(E.ClassName + ': ' + E.Message);
  3785. end;
  3786. end;
  3787. end;
  3788. class function TGLShaderEx.FriendlyName: string;
  3789. begin
  3790. Result := 'GLSL Shader';
  3791. end;
  3792. function TGLShaderEx.GetHandle: TGLShaderHandle;
  3793. begin
  3794. Result := FHandle[FShaderType];
  3795. end;
  3796. procedure TGLShaderEx.ReadFromFiler(AReader: TReader);
  3797. var
  3798. archiveVersion: Integer;
  3799. begin
  3800. with AReader do
  3801. begin
  3802. archiveVersion := ReadInteger;
  3803. if archiveVersion = 0 then
  3804. begin
  3805. Name := ReadString;
  3806. FDefferedInit := ReadBoolean;
  3807. FSource.Text := ReadString;
  3808. FSourceFile := ReadString;
  3809. FShaderType := TGLShaderType(ReadInteger);
  3810. FGeometryInput := TGLgsInTypes(ReadInteger);
  3811. FGeometryOutput := TGLgsOutTypes(ReadInteger);
  3812. FGeometryVerticesOut := ReadInteger;
  3813. end
  3814. else
  3815. RaiseFilerException(archiveVersion);
  3816. end;
  3817. end;
  3818. procedure TGLShaderEx.SetGeometryInput(AValue: TGLgsInTypes);
  3819. begin
  3820. if AValue <> FGeometryInput then
  3821. begin
  3822. FGeometryInput := AValue;
  3823. NotifyChange(Self);
  3824. end;
  3825. end;
  3826. procedure TGLShaderEx.SetGeometryOutput(AValue: TGLgsOutTypes);
  3827. begin
  3828. if AValue <> FGeometryOutput then
  3829. begin
  3830. FGeometryOutput := AValue;
  3831. NotifyChange(Self);
  3832. end;
  3833. end;
  3834. procedure TGLShaderEx.SetGeometryVerticesOut(AValue: TGLint);
  3835. begin
  3836. if AValue < 1 then
  3837. AValue := 1
  3838. else if AValue > 1024 then
  3839. AValue := 1024;
  3840. if AValue <> FGeometryVerticesOut then
  3841. begin
  3842. FGeometryVerticesOut := AValue;
  3843. NotifyChange(Self);
  3844. end;
  3845. end;
  3846. procedure TGLShaderEx.SetShaderType(AValue: TGLShaderType);
  3847. begin
  3848. if FShaderType <> AValue then
  3849. begin
  3850. FShaderType := AValue;
  3851. NotifyChange(Self);
  3852. end;
  3853. end;
  3854. procedure TGLShaderEx.SetSource(AValue: TStringList);
  3855. begin
  3856. FSource.Assign(AValue);
  3857. end;
  3858. procedure TGLShaderEx.SetSourceFile(AValue: string);
  3859. begin
  3860. FixPathDelimiter(AValue);
  3861. if FSourceFile <> AValue then
  3862. begin
  3863. FSourceFile := AValue;
  3864. NotifyChange(Self);
  3865. end;
  3866. end;
  3867. procedure TGLShaderEx.WriteToFiler(AWriter: TWriter);
  3868. begin
  3869. with AWriter do
  3870. begin
  3871. WriteInteger(0); // archive version
  3872. WriteString(Name);
  3873. WriteBoolean(FDefferedInit);
  3874. if Length(FSourceFile) = 0 then
  3875. WriteString(FSource.Text)
  3876. else
  3877. WriteString('');
  3878. WriteString(FSourceFile);
  3879. WriteInteger(Integer(FShaderType));
  3880. WriteInteger(Integer(FGeometryInput));
  3881. WriteInteger(Integer(FGeometryOutput));
  3882. WriteInteger(FGeometryVerticesOut);
  3883. end;
  3884. end;
  3885. { TVXLibMaterialProperty }
  3886. function TGLLibMaterialProperty.GetMaterial: TGLLibMaterialEx;
  3887. begin
  3888. if Owner is TGLLibMaterialEx then
  3889. Result := TGLLibMaterialEx(Owner)
  3890. else if Owner is TGLLibMaterialProperty then
  3891. Result := TGLLibMaterialProperty(Owner).GetMaterial
  3892. else
  3893. Result := nil;
  3894. end;
  3895. function TGLLibMaterialProperty.GetMaterialLibrary: TGLAbstractMaterialLibrary;
  3896. begin
  3897. if Owner is TGLBaseMaterialCollectionItem then
  3898. Result := TGLBaseMaterialCollectionItem(Owner).GetMaterialLibrary
  3899. else
  3900. Result := GetMaterial.GetMaterialLibrary;
  3901. end;
  3902. function TGLLibMaterialProperty.GetMaterialLibraryEx: TGLMaterialLibraryEx;
  3903. begin
  3904. if Owner is TGLBaseMaterialCollectionItem then
  3905. Result := TGLBaseMaterialCollectionItem(Owner).GetMaterialLibraryEx
  3906. else
  3907. Result := TGLMaterialLibraryEx(GetMaterial.GetMaterialLibrary);
  3908. end;
  3909. procedure TGLLibMaterialProperty.SetNextPass(const AValue: TGLLibMaterialName);
  3910. begin
  3911. if AValue <> FNextPassName then
  3912. begin
  3913. FNextPassName := AValue;
  3914. NotifyChange(Self);
  3915. end;
  3916. end;
  3917. procedure TGLLibMaterialProperty.Loaded;
  3918. begin
  3919. end;
  3920. procedure TGLLibMaterialProperty.NotifyChange(Sender: TObject);
  3921. var
  3922. NA: IGLNotifyAble;
  3923. begin
  3924. if Assigned(Owner) then
  3925. begin
  3926. if Supports(Owner, IGLNotifyAble, NA) then
  3927. NA.NotifyChange(Self)
  3928. end;
  3929. if Assigned(OnNotifyChange) then
  3930. OnNotifyChange(Self);
  3931. end;
  3932. procedure TGLLibMaterialProperty.SetEnabled(AValue: Boolean);
  3933. begin
  3934. if FEnabled <> AValue then
  3935. begin
  3936. FEnabled := AValue;
  3937. if Owner is TGLLibMaterialEx then
  3938. GetMaterial.NotifyChange(Self);
  3939. end;
  3940. end;
  3941. { TVXLibMaterialsEx }
  3942. function TGLLibMaterialsEx.Add: TGLLibMaterialEx;
  3943. begin
  3944. Result := (inherited Add) as TGLLibMaterialEx;
  3945. end;
  3946. constructor TGLLibMaterialsEx.Create(AOwner: TComponent);
  3947. begin
  3948. inherited Create(AOwner, TGLLibMaterialEx);
  3949. end;
  3950. function TGLLibMaterialsEx.FindItemID(ID: Integer): TGLLibMaterialEx;
  3951. begin
  3952. Result := (inherited FindItemID(ID)) as TGLLibMaterialEx;
  3953. end;
  3954. function TGLLibMaterialsEx.GetItems(AIndex: Integer): TGLLibMaterialEx;
  3955. begin
  3956. Result := TGLLibMaterialEx(inherited Items[AIndex]);
  3957. end;
  3958. function TGLLibMaterialsEx.GetLibMaterialByName(
  3959. const AName: string): TGLLibMaterialEx;
  3960. var
  3961. LMaterial: TGLAbstractLibMaterial;
  3962. begin
  3963. LMaterial := GetMaterial(AName);
  3964. if Assigned(LMaterial) and (LMaterial is TGLLibMaterialEx) then
  3965. Result := TGLLibMaterialEx(LMaterial)
  3966. else
  3967. Result := nil;
  3968. end;
  3969. function TGLLibMaterialsEx.IndexOf(const Item: TGLLibMaterialEx): Integer;
  3970. var
  3971. I: Integer;
  3972. begin
  3973. Result := -1;
  3974. if Count <> 0 then
  3975. for I := 0 to Count - 1 do
  3976. if GetItems(I) = Item then
  3977. begin
  3978. Result := I;
  3979. Exit;
  3980. end;
  3981. end;
  3982. function TGLLibMaterialsEx.MaterialLibrary: TGLMaterialLibraryEx;
  3983. begin
  3984. Result := TGLMaterialLibraryEx(GetOwner);
  3985. end;
  3986. procedure TGLLibMaterialsEx.SetItems(AIndex: Integer;
  3987. const AValue: TGLLibMaterialEx);
  3988. begin
  3989. inherited Items[AIndex] := AValue;
  3990. end;
  3991. { TVXBaseShaderModel }
  3992. procedure TGLBaseShaderModel.Apply(var ARci: TGLRenderContextInfo);
  3993. var
  3994. I: Integer;
  3995. LEvent: TOnUniformSetting;
  3996. begin
  3997. if FIsValid then
  3998. begin
  3999. FHandle.UseProgramObject;
  4000. if FAutoFill then
  4001. for I := FUniforms.Count - 1 downto 0 do
  4002. TGLAbstractShaderUniform(FUniforms[I]).Apply(ARci);
  4003. if Self is TGLShaderModel3 then
  4004. LEvent := GetMaterial.FOnSM3UniformSetting
  4005. else if Self is TGLShaderModel4 then
  4006. LEvent := GetMaterial.FOnSM4UniformSetting
  4007. else if Self is TGLShaderModel5 then
  4008. LEvent := GetMaterial.FOnSM5UniformSetting
  4009. else
  4010. LEvent := nil;
  4011. if Assigned(LEvent) then
  4012. LEvent(Self, ARci);
  4013. end;
  4014. end;
  4015. procedure TGLBaseShaderModel.Assign(Source: TPersistent);
  4016. var
  4017. SM: TGLBaseShaderModel;
  4018. begin
  4019. if Source is TGLBaseShaderModel then
  4020. begin
  4021. SM := TGLBaseShaderModel(Source);
  4022. LibVertexShaderName := SM.LibVertexShaderName;
  4023. LibFragmentShaderName := SM.LibFragmentShaderName;
  4024. LibGeometryShaderName := SM.LibGeometryShaderName;
  4025. LibTessControlShaderName := SM.LibTessControlShaderName;
  4026. LibTessEvalShaderName := SM.LibTessEvalShaderName;
  4027. end;
  4028. inherited;
  4029. end;
  4030. constructor TGLBaseShaderModel.Create(AOwner: TPersistent);
  4031. begin
  4032. inherited;
  4033. FHandle := TGLProgramHandle.Create;
  4034. FHandle.OnPrapare := DoOnPrepare;
  4035. FEnabled := False;
  4036. FUniforms := TGLPersistentObjectList.Create;
  4037. FAutoFill := True;
  4038. end;
  4039. procedure TGLBaseShaderModel.DefineProperties(Filer: TFiler);
  4040. begin
  4041. inherited;
  4042. Filer.DefineBinaryProperty(
  4043. 'Uniforms',
  4044. ReadUniforms,
  4045. WriteUniforms,
  4046. FUniforms.Count > 0);
  4047. end;
  4048. destructor TGLBaseShaderModel.Destroy;
  4049. begin
  4050. FHandle.Destroy;
  4051. LibVertexShaderName := '';
  4052. LibFragmentShaderName := '';
  4053. LibGeometryShaderName := '';
  4054. LibTessControlShaderName := '';
  4055. LibTessEvalShaderName := '';
  4056. FUniforms.CleanFree;
  4057. inherited;
  4058. end;
  4059. procedure TGLBaseShaderModel.DoOnPrepare(Sender: TGLContext);
  4060. var
  4061. T: TGLShaderType;
  4062. LUniforms: TGLPersistentObjectList;
  4063. LUniform, LUniform2: TGLShaderUniform;
  4064. ID: Cardinal;
  4065. I, J, C: Integer;
  4066. buff: array[0..255] of AnsiChar;
  4067. Size: TGLInt;
  4068. Len: TGLsizei;
  4069. Loc: TGLint;
  4070. AType: Cardinal;
  4071. UName: string;
  4072. GLSLData: TGLSLDataType;
  4073. GLSLSampler: TGLSLSamplerType;
  4074. bSampler: Boolean;
  4075. bNew: Boolean;
  4076. LEvent: TOnUniformInitialize;
  4077. begin
  4078. if FEnabled then
  4079. try
  4080. if IsSupported and FHandle.IsSupported then
  4081. begin
  4082. FHandle.AllocateHandle;
  4083. if FHandle.IsDataNeedUpdate then
  4084. begin
  4085. // Validate shaders
  4086. for T := Low(TGLShaderType) to High(TGLShaderType) do
  4087. if Assigned(FShaders[T]) then
  4088. begin
  4089. FShaders[T].DoOnPrepare(Sender);
  4090. if not FShaders[T].IsValid then
  4091. begin
  4092. if IsDesignTime then
  4093. FInfoLog := Format('%s shader "%s" is invalid',
  4094. [cShaderTypeName[FShaders[T].ShaderType],
  4095. FShaders[T].Name]);
  4096. FIsValid := False;
  4097. exit;
  4098. end;
  4099. end;
  4100. // Gather shader
  4101. FHandle.DetachAllObject;
  4102. for T := Low(TGLShaderType) to High(TGLShaderType) do
  4103. if Assigned(FShaders[T]) then
  4104. FHandle.AttachObject(FShaders[T].Handle);
  4105. ID := FHandle.Handle;
  4106. begin
  4107. // Can be override by layouts in shader
  4108. if Assigned(FShaders[shtGeometry]) then
  4109. begin
  4110. gl.ProgramParameteri(ID, GL_GEOMETRY_INPUT_TYPE_EXT,
  4111. cGLgsInTypes[FShaders[shtGeometry].GeometryInput]);
  4112. gl.ProgramParameteri(ID, GL_GEOMETRY_OUTPUT_TYPE_EXT,
  4113. cGLgsOutTypes[FShaders[shtGeometry].GeometryOutput]);
  4114. gl.ProgramParameteri(ID, GL_GEOMETRY_VERTICES_OUT_EXT,
  4115. FShaders[shtGeometry].GeometryVerticesOut);
  4116. end;
  4117. if FHandle.LinkProgram then
  4118. begin
  4119. // Get final values
  4120. if Assigned(FShaders[shtGeometry]) then
  4121. begin
  4122. gl.GetProgramiv(ID, GL_GEOMETRY_INPUT_TYPE_EXT, @AType);
  4123. case AType of
  4124. GL_POINTS: FShaders[shtGeometry].FGeometryInput := gsInPoints;
  4125. GL_LINES: FShaders[shtGeometry].FGeometryInput := gsInLines;
  4126. GL_LINES_ADJACENCY_EXT: FShaders[shtGeometry].FGeometryInput
  4127. := gsInAdjLines;
  4128. GL_TRIANGLES: FShaders[shtGeometry].FGeometryInput :=
  4129. gsInTriangles;
  4130. GL_TRIANGLES_ADJACENCY_EXT:
  4131. FShaders[shtGeometry].FGeometryInput := gsInAdjTriangles;
  4132. end;
  4133. gl.GetProgramiv(ID, GL_GEOMETRY_OUTPUT_TYPE_EXT, @AType);
  4134. case AType of
  4135. GL_POINTS: FShaders[shtGeometry].FGeometryOutput :=
  4136. gsOutPoints;
  4137. GL_LINE_STRIP: FShaders[shtGeometry].FGeometryOutput :=
  4138. gsOutLineStrip;
  4139. GL_TRIANGLE_STRIP: FShaders[shtGeometry].FGeometryOutput :=
  4140. sOutTriangleStrip;
  4141. end;
  4142. gl.GetProgramiv(ID, GL_GEOMETRY_VERTICES_OUT_EXT, @I);
  4143. if I > 0 then
  4144. FShaders[shtGeometry].FGeometryVerticesOut := I;
  4145. gl.ClearError;
  4146. end;
  4147. // Get uniforms
  4148. LUniforms := TGLPersistentObjectList.Create;
  4149. gl.GetProgramiv(ID, GL_ACTIVE_UNIFORMS, @C);
  4150. for I := 0 to C - 1 do
  4151. begin
  4152. gl.GetActiveUniform(
  4153. ID,
  4154. Cardinal(I),
  4155. Length(buff),
  4156. @Len,
  4157. @Size,
  4158. @AType,
  4159. @buff[0]);
  4160. Loc := gl.GetUniformLocation(ID, @buff[0]);
  4161. if Loc < 0 then
  4162. continue;
  4163. UName := Copy(string(buff), 0, Len);
  4164. GLSLData := GLSLTypeUndefined;
  4165. GLSLSampler := GLSLSamplerUndefined;
  4166. case AType of
  4167. GL_FLOAT: GLSLData := GLSLType1F;
  4168. GL_FLOAT_VEC2: GLSLData := GLSLType2F;
  4169. GL_FLOAT_VEC3: GLSLData := GLSLType3F;
  4170. GL_FLOAT_VEC4: GLSLData := GLSLType4F;
  4171. GL_INT: GLSLData := GLSLType1I;
  4172. GL_INT_VEC2: GLSLData := GLSLType2I;
  4173. GL_INT_VEC3: GLSLData := GLSLType3I;
  4174. GL_INT_VEC4: GLSLData := GLSLType4I;
  4175. GL_UNSIGNED_INT: GLSLData := GLSLType1UI;
  4176. GL_UNSIGNED_INT_VEC2: GLSLData := GLSLType2UI;
  4177. GL_UNSIGNED_INT_VEC3: GLSLData := GLSLType3UI;
  4178. GL_UNSIGNED_INT_VEC4: GLSLData := GLSLType4UI;
  4179. GL_BOOL: GLSLData := GLSLType1I;
  4180. GL_BOOL_VEC2: GLSLData := GLSLType2I;
  4181. GL_BOOL_VEC3: GLSLData := GLSLType3I;
  4182. GL_BOOL_VEC4: GLSLData := GLSLType4I;
  4183. GL_FLOAT_MAT2: GLSLData := GLSLTypeMat2F;
  4184. GL_FLOAT_MAT3: GLSLData := GLSLTypeMat3F;
  4185. GL_FLOAT_MAT4: GLSLData := GLSLTypeMat4F;
  4186. //------------------------------------------------------------------------------
  4187. GL_SAMPLER_1D: GLSLSampler := GLSLSampler1D;
  4188. GL_SAMPLER_2D: GLSLSampler := GLSLSampler2D;
  4189. GL_SAMPLER_3D: GLSLSampler := GLSLSampler3D;
  4190. GL_SAMPLER_CUBE: GLSLSampler := GLSLSamplerCube;
  4191. GL_SAMPLER_1D_SHADOW: GLSLSampler := GLSLSampler1DShadow;
  4192. GL_SAMPLER_2D_SHADOW: GLSLSampler := GLSLSampler2DShadow;
  4193. GL_SAMPLER_2D_RECT: GLSLSampler := GLSLSamplerRect;
  4194. GL_SAMPLER_2D_RECT_SHADOW: GLSLSampler :=
  4195. GLSLSamplerRectShadow;
  4196. GL_SAMPLER_BUFFER: GLSLSampler := GLSLSamplerBuffer;
  4197. GL_INT_SAMPLER_2D_RECT: GLSLSampler :=
  4198. GLSLIntSamplerRect;
  4199. GL_INT_SAMPLER_BUFFER: GLSLSampler :=
  4200. GLSLIntSamplerBuffer;
  4201. GL_UNSIGNED_INT_SAMPLER_1D: GLSLSampler :=
  4202. GLSLUIntSampler1D;
  4203. GL_UNSIGNED_INT_SAMPLER_2D: GLSLSampler :=
  4204. GLSLUIntSampler2D;
  4205. GL_UNSIGNED_INT_SAMPLER_3D: GLSLSampler :=
  4206. GLSLUIntSampler3D;
  4207. GL_UNSIGNED_INT_SAMPLER_CUBE: GLSLSampler :=
  4208. GLSLUIntSamplerCube;
  4209. GL_UNSIGNED_INT_SAMPLER_1D_ARRAY: GLSLSampler :=
  4210. GLSLUIntSampler1DArray;
  4211. GL_UNSIGNED_INT_SAMPLER_2D_ARRAY: GLSLSampler :=
  4212. GLSLUIntSampler2DArray;
  4213. GL_UNSIGNED_INT_SAMPLER_2D_RECT: GLSLSampler :=
  4214. GLSLUIntSamplerRect;
  4215. GL_UNSIGNED_INT_SAMPLER_BUFFER: GLSLSampler :=
  4216. GLSLUIntSamplerBuffer;
  4217. GL_SAMPLER_2D_MULTISAMPLE: GLSLSampler :=
  4218. GLSLSamplerMS;
  4219. GL_INT_SAMPLER_2D_MULTISAMPLE: GLSLSampler :=
  4220. GLSLIntSamplerMS;
  4221. GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE: GLSLSampler :=
  4222. GLSLUIntSamplerMS;
  4223. GL_SAMPLER_2D_MULTISAMPLE_ARRAY: GLSLSampler :=
  4224. GLSLSamplerMSArray;
  4225. GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: GLSLSampler :=
  4226. GLSLIntSamplerMSArray;
  4227. GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY: GLSLSampler :=
  4228. GLSLUIntSamplerMSArray;
  4229. end;
  4230. bSampler := False;
  4231. if (GLSLData = GLSLTypeUndefined) and (GLSLSampler =
  4232. GLSLSamplerUndefined) then
  4233. begin
  4234. GLSLogger.LogWarningFmt(
  4235. 'Detected active uniform "%s" with unknown type', [UName]);
  4236. continue;
  4237. end
  4238. else if GLSLData <> GLSLTypeUndefined then
  4239. begin
  4240. GLSLogger.LogInfoFmt('Detected active uniform: %s %s',
  4241. [cGLSLTypeString[GLSLData], UName]);
  4242. end
  4243. else
  4244. begin
  4245. bSampler := True;
  4246. GLSLogger.LogInfoFmt('Detected active uniform: %s %s',
  4247. [cGLSLSamplerString[GLSLSampler], UName]);
  4248. end;
  4249. // Find already existing uniform
  4250. bNew := True;
  4251. for J := 0 to FUniforms.Count - 1 do
  4252. begin
  4253. if not (FUniforms[J] is TGLShaderUniform) then
  4254. continue;
  4255. LUniform := TGLShaderUniform(FUniforms[J]);
  4256. if not Assigned(LUniform) then
  4257. continue;
  4258. if LUniform.Name = UName then
  4259. begin
  4260. if bSampler and (LUniform is TGLShaderUniformTexture) then
  4261. begin
  4262. if TGLShaderUniformTexture(LUniform).FSamplerType =
  4263. GLSLSampler then
  4264. begin
  4265. LUniform.FLocation := Loc;
  4266. LUniform.FType := GLSLType1I;
  4267. TGLShaderUniformTexture(LUniform).FTarget :=
  4268. cSamplerToTexture[GLSLSampler];
  4269. LUniforms.Add(LUniform);
  4270. FUniforms[J] := nil;
  4271. bNew := False;
  4272. break;
  4273. end
  4274. end
  4275. else
  4276. begin
  4277. if LUniform.FType = GLSLData then
  4278. begin
  4279. if (LUniform is TGLShaderUniformDSA)
  4280. and not GL.EXT_direct_state_access then
  4281. begin
  4282. LUniform2 := LUniform;
  4283. LUniform := TGLShaderUniform.Create(Self);
  4284. LUniform._AddRef;
  4285. LUniform.Assign(LUniform2);
  4286. LUniform2._Release;
  4287. end;
  4288. LUniform.FLocation := Loc;
  4289. LUniforms.Add(LUniform);
  4290. FUniforms[J] := nil;
  4291. bNew := False;
  4292. break;
  4293. end;
  4294. end;
  4295. end;
  4296. end; // for J
  4297. if bNew then
  4298. begin
  4299. // Creates new uniform
  4300. if bSampler then
  4301. begin
  4302. LUniform := TGLShaderUniformTexture.Create(Self);
  4303. LUniform.FType := GLSLType1I;
  4304. TGLShaderUniformTexture(LUniform).FSamplerType :=
  4305. GLSLSampler;
  4306. TGLShaderUniformTexture(LUniform).FTarget :=
  4307. cSamplerToTexture[GLSLSampler];
  4308. end
  4309. else
  4310. begin
  4311. if GL.EXT_direct_state_access then
  4312. LUniform := TGLShaderUniformDSA.Create(Self)
  4313. else
  4314. LUniform := TGLShaderUniform.Create(Self);
  4315. LUniform.FType := GLSLData;
  4316. end;
  4317. LUniform._AddRef;
  4318. LUniform.FName := UName;
  4319. LUniform.FNameHashCode := ComputeNameHashKey(UName);
  4320. LUniform.FLocation := Loc;
  4321. LUniforms.Add(LUniform);
  4322. end;
  4323. end; // for I
  4324. // Clean old unused uniforms
  4325. ReleaseUniforms(FUniforms);
  4326. // Assign new one
  4327. FUniforms := LUniforms;
  4328. FHandle.NotifyDataUpdated;
  4329. FIsValid := True;
  4330. if Self is TGLShaderModel3 then
  4331. LEvent := GetMaterial.FOnSM3UniformInit
  4332. else if Self is TGLShaderModel4 then
  4333. LEvent := GetMaterial.FOnSM4UniformInit
  4334. else if Self is TGLShaderModel5 then
  4335. LEvent := GetMaterial.FOnSM5UniformInit
  4336. else
  4337. LEvent := nil;
  4338. if Assigned(LEvent) then
  4339. LEvent(Self);
  4340. end // if LinkProgram
  4341. else
  4342. FIsValid := False;
  4343. end; // with GL
  4344. if IsDesignTime then
  4345. begin
  4346. FInfoLog := FHandle.InfoLog;
  4347. if (Length(FInfoLog) = 0) and FIsValid then
  4348. FInfoLog := 'Link successful';
  4349. end
  4350. else if FIsValid then
  4351. GLSLogger.LogInfoFmt('Program "%s" link successful - %s',
  4352. [GetMaterial.Name, FHandle.InfoLog])
  4353. else
  4354. GLSLogger.LogErrorFmt('Program "%s" link failed! - %s',
  4355. [GetMaterial.Name, FHandle.InfoLog]);
  4356. end;
  4357. end
  4358. else
  4359. begin
  4360. if IsDesignTime then
  4361. FInfoLog := 'Not supported by hardware';
  4362. FIsValid := False;
  4363. end;
  4364. except
  4365. on E: Exception do
  4366. begin
  4367. FIsValid := False;
  4368. if IsDesignTime then
  4369. InformationDlg(E.ClassName + ': ' + E.Message)
  4370. else
  4371. GLSLogger.LogError(E.ClassName + ': ' + E.Message);
  4372. end;
  4373. end;
  4374. end;
  4375. procedure TGLBaseShaderModel.Notification(Sender: TObject; Operation:
  4376. TOperation);
  4377. var
  4378. st: TGLShaderType;
  4379. begin
  4380. if Operation = opRemove then
  4381. begin
  4382. for st := Low(TGLShaderType) to High(TGLShaderType) do
  4383. if FShaders[st] = Sender then
  4384. begin
  4385. FShaders[st] := nil;
  4386. FLibShaderName[st] := '';
  4387. NotifyChange(Self);
  4388. exit;
  4389. end;
  4390. end;
  4391. end;
  4392. procedure TGLBaseShaderModel.NotifyChange(Sender: TObject);
  4393. begin
  4394. FHandle.NotifyChangesOfData;
  4395. inherited;
  4396. end;
  4397. procedure TGLBaseShaderModel.ReadUniforms(AStream: TStream);
  4398. var
  4399. LReader: TReader;
  4400. N, I: Integer;
  4401. str: string;
  4402. LUniform: TGLAbstractShaderUniform;
  4403. LClass: CGLAbstractShaderUniform;
  4404. begin
  4405. LReader := TReader.Create(AStream, 16384);
  4406. try
  4407. N := LReader.ReadInteger;
  4408. for I := 0 to N - 1 do
  4409. begin
  4410. str := LReader.ReadString;
  4411. LClass := CGLAbstractShaderUniform(FindClass(str));
  4412. LUniform := LClass.Create(Self);
  4413. LUniform._AddRef;
  4414. LUniform.ReadFromFiler(LReader);
  4415. FUniforms.Add(LUniform);
  4416. end;
  4417. finally
  4418. LReader.Free;
  4419. end;
  4420. end;
  4421. class procedure TGLBaseShaderModel.ReleaseUniforms(
  4422. AList: TGLPersistentObjectList);
  4423. var
  4424. I: Integer;
  4425. begin
  4426. for I := 0 to AList.Count - 1 do
  4427. if Assigned(AList[I]) then
  4428. TGLAbstractShaderUniform(AList[I])._Release;
  4429. AList.Destroy;
  4430. end;
  4431. function TGLBaseShaderModel.GetLibShaderName(AType: TGLShaderType): string;
  4432. begin
  4433. if Assigned(FShaders[AType]) then
  4434. Result := FShaders[AType].Name
  4435. else
  4436. Result := '';
  4437. end;
  4438. function TGLBaseShaderModel.GetUniform(const AName: string): IShaderParameter;
  4439. var
  4440. H, I: Integer;
  4441. U: TGLAbstractShaderUniform;
  4442. begin
  4443. Result := nil;
  4444. H := ComputeNameHashKey(AName);
  4445. for I := 0 to FUniforms.Count - 1 do
  4446. begin
  4447. U := TGLAbstractShaderUniform(FUniforms[I]);
  4448. if (U.FNameHashCode = H) and (U.FName = AName) then
  4449. begin
  4450. Result := U;
  4451. exit;
  4452. end;
  4453. end;
  4454. if not IsDesignTime then
  4455. begin
  4456. GLSLogger.LogErrorFmt('Attempt to use unknow uniform "%s" for material "%s"',
  4457. [AName, GetMaterial.Name]);
  4458. U := TGLAbstractShaderUniform.Create(Self);
  4459. U._AddRef;
  4460. U.FName := AName;
  4461. U.FNameHashCode := H;
  4462. FUniforms.Add(U);
  4463. Result := U;
  4464. end;
  4465. end;
  4466. procedure TGLBaseShaderModel.Loaded;
  4467. var
  4468. T: TGLShaderType;
  4469. I: Integer;
  4470. begin
  4471. for T := Low(TGLShaderType) to High(TGLShaderType) do
  4472. SetLibShaderName(T, FLibShaderName[T]);
  4473. for I := 0 to FUniforms.Count - 1 do
  4474. if FUniforms[I] is TGLShaderUniformTexture then
  4475. TGLShaderUniformTexture(FUniforms[I]).Loaded;
  4476. end;
  4477. procedure TGLBaseShaderModel.GetUniformNames(Proc: TGetStrProc);
  4478. var
  4479. I: Integer;
  4480. begin
  4481. for I := 0 to FUniforms.Count - 1 do
  4482. Proc(TGLAbstractShaderUniform(FUniforms[I]).FName);
  4483. end;
  4484. procedure TGLBaseShaderModel.SetLibShaderName(AType: TGLShaderType;
  4485. const AValue: string);
  4486. var
  4487. LShader: TGLShaderEx;
  4488. begin
  4489. if csLoading in GetMaterialLibraryEx.ComponentState then
  4490. begin
  4491. FLibShaderName[AType] := AValue;
  4492. exit;
  4493. end;
  4494. if Assigned(FShaders[AType]) then
  4495. begin
  4496. FShaders[AType].UnregisterUser(Self);
  4497. FShaders[AType] := nil;
  4498. FLibShaderName[AType] := '';
  4499. end;
  4500. LShader := GetMaterialLibraryEx.Components.GetShaderByName(AValue);
  4501. if Assigned(LShader) then
  4502. begin
  4503. if LShader.ShaderType <> AType then
  4504. begin
  4505. if IsDesignTime then
  4506. InformationDlg(Format('Incompatible shader type, need %s shader',
  4507. [cShaderTypeName[AType]]));
  4508. exit;
  4509. end;
  4510. LShader.RegisterUser(Self);
  4511. FShaders[AType] := LShader;
  4512. FLibShaderName[AType] := AValue;
  4513. end;
  4514. NotifyChange(Self);
  4515. end;
  4516. procedure TGLBaseShaderModel.UnApply(var ARci: TGLRenderContextInfo);
  4517. begin
  4518. if FIsValid {and not ARci.GLStates.ForwardContext} then
  4519. FHandle.EndUseProgramObject;
  4520. end;
  4521. procedure TGLBaseShaderModel.WriteUniforms(AStream: TStream);
  4522. var
  4523. LWriter: TWriter;
  4524. I: Integer;
  4525. begin
  4526. LWriter := TWriter.Create(AStream, 16384);
  4527. try
  4528. LWriter.WriteInteger(FUniforms.Count);
  4529. for I := 0 to FUniforms.Count - 1 do
  4530. begin
  4531. LWriter.WriteString(FUniforms[I].ClassName);
  4532. TGLAbstractShaderUniform(FUniforms[I]).WriteToFiler(LWriter);
  4533. end;
  4534. finally
  4535. LWriter.Free;
  4536. end;
  4537. end;
  4538. class function TGLShaderModel3.IsSupported: Boolean;
  4539. begin
  4540. Result := gl.ARB_shader_objects;
  4541. end;
  4542. class function TGLShaderModel4.IsSupported: Boolean;
  4543. begin
  4544. Result := gl.EXT_gpu_shader4;
  4545. end;
  4546. class function TGLShaderModel5.IsSupported: Boolean;
  4547. begin
  4548. Result := gl.ARB_gpu_shader5;
  4549. end;
  4550. procedure BeginPatch(mode: Cardinal);{$IFDEF MSWINDOWS} stdcall{$ELSE}cdecl{$ENDIF};
  4551. begin
  4552. if mode = GL_PATCHES then
  4553. vStoreBegin(GL_PATCHES)
  4554. else if (mode = GL_TRIANGLES)
  4555. or (mode = GL_TRIANGLE_STRIP)
  4556. or (mode = GL_TRIANGLE_FAN)
  4557. or (mode = GL_QUADS) then
  4558. begin
  4559. if mode = GL_QUADS then
  4560. gl.PatchParameteri(GL_PATCH_VERTICES, 4)
  4561. else
  4562. gl.PatchParameteri(GL_PATCH_VERTICES, 3);
  4563. vStoreBegin(GL_PATCHES);
  4564. end
  4565. else
  4566. begin
  4567. gl.Begin_ := vStoreBegin;
  4568. GLSLogger.LogError('glBegin called with unsupported primitive for tessellation');
  4569. Abort;
  4570. end;
  4571. end;
  4572. procedure TGLShaderModel5.Apply(var ARci: TGLRenderContextInfo);
  4573. begin
  4574. if Assigned(FShaders[shtControl]) or Assigned(FShaders[shtEvaluation]) then
  4575. begin
  4576. vStoreBegin := gl.Begin_;
  4577. gl.Begin_ := BeginPatch;
  4578. ARci.amalgamating := True;
  4579. end;
  4580. inherited;
  4581. end;
  4582. procedure TGLShaderModel5.UnApply(var ARci: TGLRenderContextInfo);
  4583. begin
  4584. inherited;
  4585. if Assigned(FShaders[shtControl]) or Assigned(FShaders[shtEvaluation]) then
  4586. gl.Begin_ := vStoreBegin;
  4587. ARci.amalgamating := False;
  4588. end;
  4589. { TVXMatLibComponents }
  4590. function TGLMatLibComponents.GetAttachmentByName(
  4591. const AName: TGLMaterialComponentName): TGLFrameBufferAttachment;
  4592. var
  4593. N, I: Integer;
  4594. begin
  4595. N := ComputeNameHashKey(AName);
  4596. for I := 0 to Count - 1 do
  4597. begin
  4598. if (Items[I] is TGLFrameBufferAttachment) and (Items[I].FNameHashKey = N)
  4599. then
  4600. begin
  4601. if Items[I].Name = AName then
  4602. begin
  4603. Result := TGLFrameBufferAttachment(Items[I]);
  4604. exit;
  4605. end;
  4606. end;
  4607. end;
  4608. Result := nil;
  4609. end;
  4610. function TGLMatLibComponents.GetCombinerByName(
  4611. const AName: TGLMaterialComponentName): TGLTextureCombiner;
  4612. var
  4613. N, I: Integer;
  4614. begin
  4615. N := ComputeNameHashKey(AName);
  4616. for I := 0 to Count - 1 do
  4617. begin
  4618. if (Items[I] is TGLTextureCombiner) and (Items[I].FNameHashKey = N) then
  4619. begin
  4620. if Items[I].Name = AName then
  4621. begin
  4622. Result := TGLTextureCombiner(Items[I]);
  4623. exit;
  4624. end;
  4625. end;
  4626. end;
  4627. Result := nil;
  4628. end;
  4629. function TGLMatLibComponents.GetItemByName(
  4630. const AName: TGLMaterialComponentName): TGLBaseMaterialCollectionItem;
  4631. var
  4632. N, I: Integer;
  4633. begin
  4634. N := ComputeNameHashKey(AName);
  4635. for I := 0 to Count - 1 do
  4636. begin
  4637. if (Items[I].FNameHashKey = N) and (Items[I].Name = AName) then
  4638. begin
  4639. Result := Items[I];
  4640. exit;
  4641. end;
  4642. end;
  4643. Result := nil;
  4644. end;
  4645. function TGLMatLibComponents.GetItems(
  4646. index: Integer): TGLBaseMaterialCollectionItem;
  4647. begin
  4648. Result := TGLBaseMaterialCollectionItem(inherited GetItems(index));
  4649. end;
  4650. function TGLMatLibComponents.GetNamePath: string;
  4651. var
  4652. s: string;
  4653. begin
  4654. Result := ClassName;
  4655. if GetOwner = nil then
  4656. Exit;
  4657. s := GetOwner.GetNamePath;
  4658. if s = '' then
  4659. Exit;
  4660. Result := s + '.Components';
  4661. end;
  4662. function TGLMatLibComponents.GetSamplerByName(
  4663. const AName: TGLMaterialComponentName): TGLTextureSampler;
  4664. var
  4665. N, I: Integer;
  4666. begin
  4667. N := ComputeNameHashKey(AName);
  4668. for I := 0 to Count - 1 do
  4669. begin
  4670. if (Items[I] is TGLTextureSampler) and (Items[I].FNameHashKey = N) then
  4671. begin
  4672. if Items[I].Name = AName then
  4673. begin
  4674. Result := TGLTextureSampler(Items[I]);
  4675. exit;
  4676. end;
  4677. end;
  4678. end;
  4679. Result := nil;
  4680. end;
  4681. function TGLMatLibComponents.GetShaderByName(
  4682. const AName: TGLMaterialComponentName): TGLShaderEx;
  4683. var
  4684. N, I: Integer;
  4685. begin
  4686. N := ComputeNameHashKey(AName);
  4687. for I := 0 to Count - 1 do
  4688. begin
  4689. if (Items[I] is TGLShaderEx) and (Items[I].FNameHashKey = N) then
  4690. begin
  4691. if Items[I].Name = AName then
  4692. begin
  4693. Result := TGLShaderEx(Items[I]);
  4694. exit;
  4695. end;
  4696. end;
  4697. end;
  4698. Result := nil;
  4699. end;
  4700. function TGLMatLibComponents.GetAsmProgByName(
  4701. const AName: TGLMaterialComponentName): TGLASMVertexProgram;
  4702. var
  4703. N, I: Integer;
  4704. begin
  4705. N := ComputeNameHashKey(AName);
  4706. for I := 0 to Count - 1 do
  4707. begin
  4708. if (Items[I] is TGLASMVertexProgram) and (Items[I].FNameHashKey = N) then
  4709. begin
  4710. if Items[I].Name = AName then
  4711. begin
  4712. Result := TGLASMVertexProgram(Items[I]);
  4713. exit;
  4714. end;
  4715. end;
  4716. end;
  4717. Result := nil;
  4718. end;
  4719. function TGLMatLibComponents.GetTextureByName(
  4720. const AName: TGLMaterialComponentName): TGLAbstractTexture;
  4721. var
  4722. N, I: Integer;
  4723. begin
  4724. N := ComputeNameHashKey(AName);
  4725. for I := 0 to Count - 1 do
  4726. begin
  4727. if (Items[I] is TGLAbstractTexture) and (Items[I].FNameHashKey = N) then
  4728. begin
  4729. if Items[I].Name = AName then
  4730. begin
  4731. Result := TGLTextureImageEx(Items[I]);
  4732. exit;
  4733. end;
  4734. end;
  4735. end;
  4736. Result := nil;
  4737. end;
  4738. class function TGLMatLibComponents.ItemsClass: TXCollectionItemClass;
  4739. begin
  4740. Result := TGLBaseMaterialCollectionItem;
  4741. end;
  4742. function TGLMatLibComponents.MakeUniqueName(const AName:
  4743. TGLMaterialComponentName): TGLMaterialComponentName;
  4744. var
  4745. I: Integer;
  4746. begin
  4747. Result := AName;
  4748. I := 1;
  4749. while GetItemByName(Result) <> nil do
  4750. begin
  4751. Result := AName + IntToStr(i);
  4752. Inc(i);
  4753. end;
  4754. end;
  4755. { TVXMaterialLibraryEx }
  4756. function TGLMaterialLibraryEx.AddAttachment(
  4757. const AName: TGLMaterialComponentName): TGLFrameBufferAttachment;
  4758. begin
  4759. Result := TGLFrameBufferAttachment.Create(Components);
  4760. Result.Name := AName;
  4761. Components.Add(Result);
  4762. end;
  4763. function TGLMaterialLibraryEx.AddCombiner(
  4764. const AName: TGLMaterialComponentName): TGLTextureCombiner;
  4765. begin
  4766. Result := TGLTextureCombiner.Create(Components);
  4767. Result.Name := AName;
  4768. Components.Add(Result);
  4769. end;
  4770. function TGLMaterialLibraryEx.AddSampler(
  4771. const AName: TGLMaterialComponentName): TGLTextureSampler;
  4772. begin
  4773. Result := TGLTextureSampler.Create(Components);
  4774. Result.Name := AName;
  4775. Components.Add(Result);
  4776. end;
  4777. function TGLMaterialLibraryEx.AddShader(
  4778. const AName: TGLMaterialComponentName): TGLShaderEx;
  4779. begin
  4780. Result := TGLShaderEx.Create(Components);
  4781. Result.Name := AName;
  4782. Components.Add(Result);
  4783. end;
  4784. function TGLMaterialLibraryEx.AddAsmProg(
  4785. const AName: TGLMaterialComponentName): TGLASMVertexProgram;
  4786. begin
  4787. Result := TGLASMVertexProgram.Create(Components);
  4788. Result.Name := AName;
  4789. Components.Add(Result);
  4790. end;
  4791. function TGLMaterialLibraryEx.AddTexture(
  4792. const AName: TGLMaterialComponentName): TGLTextureImageEx;
  4793. begin
  4794. Result := TGLTextureImageEx.Create(Components);
  4795. Result.Name := AName;
  4796. Components.Add(Result);
  4797. end;
  4798. constructor TGLMaterialLibraryEx.Create(AOwner: TComponent);
  4799. begin
  4800. inherited;
  4801. FMaterials := TGLLibMaterialsEx.Create(Self);
  4802. FComponents := TGLMatLibComponents.Create(Self);
  4803. end;
  4804. procedure TGLMaterialLibraryEx.DefineProperties(Filer: TFiler);
  4805. begin
  4806. Filer.DefineBinaryProperty(
  4807. 'ComponentsData',
  4808. ReadComponents,
  4809. WriteComponents,
  4810. Components.Count > 0);
  4811. inherited;
  4812. end;
  4813. destructor TGLMaterialLibraryEx.Destroy;
  4814. begin
  4815. FMaterials.Destroy;
  4816. FComponents.Destroy;
  4817. inherited;
  4818. end;
  4819. function TGLMaterialLibraryEx.GetMaterials: TGLLibMaterialsEx;
  4820. begin
  4821. Result := TGLLibMaterialsEx(FMaterials);
  4822. end;
  4823. procedure TGLMaterialLibraryEx.GetNames(Proc: TGetStrProc;
  4824. AClass: CGLBaseMaterialCollectionItem);
  4825. var
  4826. I: Integer;
  4827. begin
  4828. for I := 0 to Components.Count - 1 do
  4829. if Components[I].ClassType = AClass then
  4830. Proc(Components[I].Name)
  4831. end;
  4832. procedure TGLMaterialLibraryEx.Loaded;
  4833. begin
  4834. inherited;
  4835. end;
  4836. procedure TGLMaterialLibraryEx.ReadComponents(AStream: TStream);
  4837. var
  4838. LReader: TReader;
  4839. begin
  4840. LReader := TReader.Create(AStream, 16384);
  4841. try
  4842. Components.ReadFromFiler(LReader);
  4843. finally
  4844. LReader.Free;
  4845. end;
  4846. end;
  4847. procedure TGLMaterialLibraryEx.SetComponents(AValue: TGLMatLibComponents);
  4848. begin
  4849. FComponents.Assign(AValue);
  4850. end;
  4851. procedure TGLMaterialLibraryEx.SetLevelForAll(const ALevel: TGLMaterialLevel);
  4852. var
  4853. I: Integer;
  4854. begin
  4855. for I := Materials.Count - 1 downto 0 do
  4856. Materials[I].ApplicableLevel := ALevel;
  4857. end;
  4858. procedure TGLMaterialLibraryEx.SetMaterials(AValue: TGLLibMaterialsEx);
  4859. begin
  4860. FMaterials.Assign(AValue);
  4861. end;
  4862. function TGLMaterialLibraryEx.StoreMaterials: Boolean;
  4863. begin
  4864. Result := (FMaterials.Count > 0);
  4865. end;
  4866. procedure TGLMaterialLibraryEx.WriteComponents(AStream: TStream);
  4867. var
  4868. LWriter: TWriter;
  4869. begin
  4870. LWriter := TWriter.Create(AStream, 16384);
  4871. try
  4872. Components.WriteToFiler(LWriter);
  4873. finally
  4874. LWriter.Free;
  4875. end;
  4876. end;
  4877. { TVXShaderUniformTexture }
  4878. procedure TGLShaderUniformTexture.Apply(var ARci: TGLRenderContextInfo);
  4879. function FindHotActiveUnit: Boolean;
  4880. var
  4881. ID: Cardinal;
  4882. I, J: Integer;
  4883. bindTime, minTime: Double;
  4884. LTex: TGLTextureImageEx;
  4885. begin
  4886. with ARci.GLStates do
  4887. begin
  4888. if Assigned(FLibTexture) and FLibTexture.IsValid then
  4889. begin
  4890. ID := FLibTexture.FHandle.Handle;
  4891. // Yar: may be need exract this to new method of TGLTextureImageEx ???
  4892. if FLibTexture is TGLTextureImageEx then
  4893. begin
  4894. LTex := TGLTextureImageEx(FLibTexture);
  4895. Inc(LTex.FApplyCounter);
  4896. if LTex.FApplyCounter > 16 then
  4897. FreeAndNil(LTex.FImage);
  4898. end;
  4899. end
  4900. else
  4901. ID := 0;
  4902. // Find alredy binded texture unit
  4903. for I := 0 to MaxTextureImageUnits - 1 do
  4904. begin
  4905. if TextureBinding[I, FTarget] = ID then
  4906. begin
  4907. gl.Uniform1i(FLocation, I);
  4908. ActiveTexture := I;
  4909. Result := True;
  4910. exit;
  4911. end;
  4912. end;
  4913. // Find unused texture unit
  4914. for I := 0 to MaxTextureImageUnits - 1 do
  4915. begin
  4916. if TextureBinding[I, FTarget] = 0 then
  4917. begin
  4918. TextureBinding[I, FTarget] := ID;
  4919. gl.Uniform1i(FLocation, I);
  4920. ActiveTexture := I;
  4921. Result := True;
  4922. exit;
  4923. end;
  4924. end;
  4925. // Find most useless texture unit
  4926. minTime := AppTime;
  4927. J := 0;
  4928. for I := 0 to MaxTextureImageUnits - 1 do
  4929. begin
  4930. bindTime := TextureBindingTime[I, FTarget];
  4931. if bindTime < minTime then
  4932. begin
  4933. minTime := bindTime;
  4934. J := I;
  4935. end;
  4936. end;
  4937. TextureBinding[J, FTarget] := ID;
  4938. ActiveTexture := J;
  4939. gl.Uniform1i(FLocation, J);
  4940. Result := True;
  4941. exit;
  4942. end;
  4943. Result := False;
  4944. end;
  4945. var
  4946. glTarget: Cardinal;
  4947. begin
  4948. if FLocation > -1 then
  4949. begin
  4950. if FindHotActiveUnit and Assigned(FLibTexture) and Assigned(FLibSampler)
  4951. then
  4952. begin
  4953. // Apply swizzling if possible
  4954. glTarget := DecodeTextureTarget(FLibTexture.Shape);
  4955. if GL.ARB_texture_swizzle or GL.EXT_texture_swizzle then
  4956. begin
  4957. if FSwizzling[0] <> FLibTexture.FSwizzles[0] then
  4958. begin
  4959. FLibTexture.FSwizzles[0] := FSwizzling[0];
  4960. gl.TexParameteri(glTarget, GL_TEXTURE_SWIZZLE_R,
  4961. cTextureSwizzle[FSwizzling[0]]);
  4962. end;
  4963. if FSwizzling[1] <> FLibTexture.FSwizzles[1] then
  4964. begin
  4965. FLibTexture.FSwizzles[1] := FSwizzling[1];
  4966. gl.TexParameteri(glTarget, GL_TEXTURE_SWIZZLE_G,
  4967. cTextureSwizzle[FSwizzling[1]]);
  4968. end;
  4969. if FSwizzling[2] <> FLibTexture.FSwizzles[2] then
  4970. begin
  4971. FLibTexture.FSwizzles[2] := FSwizzling[2];
  4972. gl.TexParameteri(glTarget, GL_TEXTURE_SWIZZLE_B,
  4973. cTextureSwizzle[FSwizzling[2]]);
  4974. end;
  4975. if FSwizzling[3] <> FLibTexture.FSwizzles[3] then
  4976. begin
  4977. FLibTexture.FSwizzles[3] := FSwizzling[3];
  4978. gl.TexParameteri(glTarget, GL_TEXTURE_SWIZZLE_A,
  4979. cTextureSwizzle[FSwizzling[3]]);
  4980. end;
  4981. end;
  4982. if FLibSampler.IsValid then
  4983. FLibSampler.Apply(ARci)
  4984. else if FLibTexture.FLastSampler <> FLibSampler then
  4985. begin
  4986. // Sampler object not supported, lets use texture states
  4987. gl.TexParameterfv(glTarget, GL_TEXTURE_BORDER_COLOR,
  4988. FLibSampler.BorderColor.AsAddress);
  4989. gl.TexParameteri(glTarget, GL_TEXTURE_WRAP_S,
  4990. cTextureWrapMode[FLibSampler.WrapX]);
  4991. gl.TexParameteri(glTarget, GL_TEXTURE_WRAP_T,
  4992. cTextureWrapMode[FLibSampler.WrapY]);
  4993. gl.TexParameteri(glTarget, GL_TEXTURE_WRAP_R,
  4994. cTextureWrapMode[FLibSampler.WrapZ]);
  4995. gl.TexParameterf(glTarget, GL_TEXTURE_LOD_BIAS, FLibSampler.LODBias +
  4996. FLibSampler.FLODBiasFract);
  4997. gl.TexParameteri(glTarget, GL_TEXTURE_MIN_FILTER,
  4998. cTextureMinFilter[FLibSampler.MinFilter]);
  4999. gl.TexParameteri(glTarget, GL_TEXTURE_MAG_FILTER,
  5000. cTextureMagFilter[FLibSampler.MagFilter]);
  5001. if GL.EXT_texture_filter_anisotropic then
  5002. begin
  5003. if FLibSampler.FilteringQuality = tfAnisotropic then
  5004. gl.TexParameteri(glTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT,
  5005. CurrentGLContext.GLStates.MaxTextureAnisotropy)
  5006. else
  5007. gl.TexParameteri(glTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1);
  5008. end;
  5009. gl.TexParameteri(glTarget, GL_TEXTURE_COMPARE_MODE,
  5010. cTextureCompareMode[FLibSampler.CompareMode]);
  5011. gl.TexParameteri(glTarget, GL_TEXTURE_COMPARE_FUNC,
  5012. cGLComparisonFunctionToGLEnum[FLibSampler.CompareFunc]);
  5013. if GL.EXT_texture_sRGB_decode then
  5014. begin
  5015. if FLibSampler.sRGB_Encode then
  5016. gl.TexParameteri(glTarget, GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT)
  5017. else
  5018. gl.TexParameteri(glTarget, GL_TEXTURE_SRGB_DECODE_EXT,
  5019. GL_SKIP_DECODE_EXT);
  5020. end;
  5021. FLibTexture.FLastSampler := FLibSampler;
  5022. end;
  5023. end;
  5024. end;
  5025. end;
  5026. procedure TGLShaderUniformTexture.Assign(Source: TPersistent);
  5027. var
  5028. LUniform: TGLShaderUniformTexture;
  5029. begin
  5030. if Source is TGLShaderUniformTexture then
  5031. begin
  5032. LUniform := TGLShaderUniformTexture(Source);
  5033. LibTextureName := LUniform.LibTextureName;
  5034. LibSamplerName := LUniform.LibSamplerName;
  5035. end;
  5036. inherited;
  5037. end;
  5038. constructor TGLShaderUniformTexture.Create(AOwner: TPersistent);
  5039. begin
  5040. inherited;
  5041. FSwizzling := cDefaultSwizzleVector;
  5042. end;
  5043. destructor TGLShaderUniformTexture.Destroy;
  5044. begin
  5045. LibTextureName := '';
  5046. LibSamplerName := '';
  5047. inherited;
  5048. end;
  5049. function TGLShaderUniformTexture.GetSamplerName: string;
  5050. begin
  5051. if Assigned(FLibSampler) then
  5052. Result := FLibSampler.Name
  5053. else
  5054. Result := strNothing;
  5055. end;
  5056. function TGLShaderUniformTexture.GetTextureName: string;
  5057. begin
  5058. if Assigned(FLibTexture) then
  5059. Result := FLibTexture.Name
  5060. else
  5061. Result := strNothing;
  5062. end;
  5063. function TGLShaderUniformTexture.GetTextureSwizzle: TSwizzleVector;
  5064. begin
  5065. Result := FSwizzling;
  5066. end;
  5067. procedure TGLShaderUniformTexture.Loaded;
  5068. begin
  5069. SetTextureName(FLibTexureName);
  5070. SetSamplerName(FLibSamplerName);
  5071. end;
  5072. procedure TGLShaderUniformTexture.Notification(Sender: TObject;
  5073. Operation: TOperation);
  5074. begin
  5075. if Operation = opRemove then
  5076. begin
  5077. if Sender = FLibTexture then
  5078. FLibTexture := nil
  5079. else if Sender = FLibSampler then
  5080. FLibSampler := nil;
  5081. end;
  5082. end;
  5083. procedure TGLShaderUniformTexture.ReadFromFiler(AReader: TReader);
  5084. begin
  5085. with AReader do
  5086. begin
  5087. inherited;
  5088. LibTextureName := ReadString;
  5089. LibSamplerName := ReadString;
  5090. FSwizzling[0] := TGLTextureSwizzle(ReadInteger);
  5091. FSwizzling[1] := TGLTextureSwizzle(ReadInteger);
  5092. FSwizzling[2] := TGLTextureSwizzle(ReadInteger);
  5093. FSwizzling[3] := TGLTextureSwizzle(ReadInteger);
  5094. end;
  5095. end;
  5096. procedure TGLShaderUniformTexture.SetTextureName(
  5097. const AValue: string);
  5098. var
  5099. LTexture: TGLAbstractTexture;
  5100. begin
  5101. if csLoading in TGLBaseShaderModel(Owner).GetMaterialLibraryEx.ComponentState
  5102. then
  5103. begin
  5104. FLibTexureName := AValue;
  5105. exit;
  5106. end;
  5107. if Assigned(FLibTexture) then
  5108. begin
  5109. if FLibTexture.Name = AValue then
  5110. exit;
  5111. FLibTexture.UnregisterUser(Self);
  5112. FLibTexture := nil;
  5113. end;
  5114. LTexture :=
  5115. TGLBaseShaderModel(Owner).GetMaterialLibraryEx.Components.GetTextureByName(AValue);
  5116. if Assigned(LTexture) then
  5117. begin
  5118. if LTexture is TGLFrameBufferAttachment then
  5119. begin
  5120. if TGLFrameBufferAttachment(LTexture).OnlyWrite then
  5121. begin
  5122. if IsDesignTime then
  5123. InformationDlg('Can not use write only attachment as texture')
  5124. else
  5125. GLSLogger.LogErrorFmt('Attempt to write only attachment "%s" for uniform "%s"',
  5126. [LTexture.Name, Name]);
  5127. NotifyChange(Self);
  5128. exit;
  5129. end;
  5130. end;
  5131. LTexture.RegisterUser(Self);
  5132. FLibTexture := LTexture;
  5133. end;
  5134. NotifyChange(Self);
  5135. end;
  5136. procedure TGLShaderUniformTexture.SetSamplerName(const AValue: string);
  5137. var
  5138. LSampler: TGLTextureSampler;
  5139. begin
  5140. if csLoading in TGLBaseShaderModel(Owner).GetMaterialLibraryEx.ComponentState
  5141. then
  5142. begin
  5143. FLibSamplerName := AValue;
  5144. exit;
  5145. end;
  5146. if Assigned(FLibSampler) then
  5147. begin
  5148. if FLibSampler.Name = AValue then
  5149. exit;
  5150. FLibSampler.UnregisterUser(Self);
  5151. FLibSampler := nil;
  5152. end;
  5153. LSampler :=
  5154. TGLBaseShaderModel(Owner).GetMaterialLibraryEx.Components.GetSamplerByName(AValue);
  5155. if Assigned(LSampler) then
  5156. begin
  5157. LSampler.RegisterUser(Self);
  5158. FLibSampler := LSampler;
  5159. end;
  5160. NotifyChange(Self);
  5161. end;
  5162. procedure TGLShaderUniformTexture.SetTextureSwizzle(const AValue:
  5163. TSwizzleVector);
  5164. begin
  5165. FSwizzling := AValue;
  5166. end;
  5167. procedure TGLShaderUniformTexture.WriteToFiler(AWriter: TWriter);
  5168. begin
  5169. with AWriter do
  5170. begin
  5171. inherited;
  5172. WriteString(LibTextureName);
  5173. WriteString(LibSamplerName);
  5174. WriteInteger(Integer(FSwizzling[0]));
  5175. WriteInteger(Integer(FSwizzling[1]));
  5176. WriteInteger(Integer(FSwizzling[2]));
  5177. WriteInteger(Integer(FSwizzling[3]));
  5178. end;
  5179. end;
  5180. { TVXAbstractShaderUniform }
  5181. function TGLAbstractShaderUniform.GetFloat: Single;
  5182. begin
  5183. FillChar(Result, SizeOf(Result), $00);
  5184. end;
  5185. function TGLAbstractShaderUniform.GetGLSLSamplerType: TGLSLSamplerType;
  5186. begin
  5187. Result := FSamplerType;
  5188. end;
  5189. function TGLAbstractShaderUniform.GetGLSLType: TGLSLDataType;
  5190. begin
  5191. Result := FType;
  5192. end;
  5193. function TGLAbstractShaderUniform.GetInt: TGLint;
  5194. begin
  5195. FillChar(Result, SizeOf(Result), $00);
  5196. end;
  5197. function TGLAbstractShaderUniform.GetIVec2: TVector2i;
  5198. begin
  5199. FillChar(Result, SizeOf(Result), $00);
  5200. end;
  5201. function TGLAbstractShaderUniform.GetIVec3: TVector3i;
  5202. begin
  5203. FillChar(Result, SizeOf(Result), $00);
  5204. end;
  5205. function TGLAbstractShaderUniform.GetIVec4: TVector4i;
  5206. begin
  5207. FillChar(Result, SizeOf(Result), $00);
  5208. end;
  5209. function TGLAbstractShaderUniform.GetMat2: TMatrix2f;
  5210. begin
  5211. FillChar(Result, SizeOf(Result), $00);
  5212. end;
  5213. function TGLAbstractShaderUniform.GetMat3: TMatrix3f;
  5214. begin
  5215. FillChar(Result, SizeOf(Result), $00);
  5216. end;
  5217. function TGLAbstractShaderUniform.GetMat4: TMatrix4f;
  5218. begin
  5219. FillChar(Result, SizeOf(Result), $00);
  5220. end;
  5221. function TGLAbstractShaderUniform.GetName: string;
  5222. begin
  5223. Result := FName;
  5224. end;
  5225. function TGLAbstractShaderUniform.GetSamplerName: string;
  5226. begin
  5227. Result := strNothing;
  5228. end;
  5229. procedure TGLAbstractShaderUniform.Apply(var ARci: TGLRenderContextInfo);
  5230. begin
  5231. end;
  5232. function TGLAbstractShaderUniform.GetAutoSetMethod: string;
  5233. begin
  5234. Result := strNothing;
  5235. end;
  5236. function TGLAbstractShaderUniform.GetTextureName: string;
  5237. begin
  5238. Result := strNothing;
  5239. end;
  5240. function TGLAbstractShaderUniform.GetTextureSwizzle: TSwizzleVector;
  5241. begin
  5242. Result := cDefaultSwizzleVector;
  5243. end;
  5244. function TGLAbstractShaderUniform.GetUInt: Cardinal;
  5245. begin
  5246. FillChar(Result, SizeOf(Result), $00);
  5247. end;
  5248. function TGLAbstractShaderUniform.GetUVec2: TVector2ui;
  5249. begin
  5250. FillChar(Result, SizeOf(Result), $00);
  5251. end;
  5252. function TGLAbstractShaderUniform.GetUVec3: TVector3ui;
  5253. begin
  5254. FillChar(Result, SizeOf(Result), $00);
  5255. end;
  5256. function TGLAbstractShaderUniform.GetUVec4: TVector4ui;
  5257. begin
  5258. FillChar(Result, SizeOf(Result), $00);
  5259. end;
  5260. function TGLAbstractShaderUniform.GetVec2: TVector2f;
  5261. begin
  5262. FillChar(Result, SizeOf(Result), $00);
  5263. end;
  5264. function TGLAbstractShaderUniform.GetVec3: TVector3f;
  5265. begin
  5266. FillChar(Result, SizeOf(Result), $00);
  5267. end;
  5268. function TGLAbstractShaderUniform.GetVec4: TGLVector;
  5269. begin
  5270. FillChar(Result, SizeOf(Result), $00);
  5271. end;
  5272. procedure TGLAbstractShaderUniform.ReadFromFiler(AReader: TReader);
  5273. begin
  5274. end;
  5275. procedure TGLAbstractShaderUniform.SetFloat(const Value: TGLFloat);
  5276. begin
  5277. end;
  5278. procedure TGLAbstractShaderUniform.SetFloatArray(const Values: PGLFloat;
  5279. Count: Integer);
  5280. begin
  5281. end;
  5282. procedure TGLAbstractShaderUniform.SetInt(const Value: Integer);
  5283. begin
  5284. end;
  5285. procedure TGLAbstractShaderUniform.SetIntArray(const Values: PGLInt;
  5286. Count: Integer);
  5287. begin
  5288. end;
  5289. procedure TGLAbstractShaderUniform.SetIVec2(const Value: TVector2i);
  5290. begin
  5291. end;
  5292. procedure TGLAbstractShaderUniform.SetIVec3(const Value: TVector3i);
  5293. begin
  5294. end;
  5295. procedure TGLAbstractShaderUniform.SetIVec4(const Value: TVector4i);
  5296. begin
  5297. end;
  5298. procedure TGLAbstractShaderUniform.SetMat2(const Value: TMatrix2f);
  5299. begin
  5300. end;
  5301. procedure TGLAbstractShaderUniform.SetMat3(const Value: TMatrix3f);
  5302. begin
  5303. end;
  5304. procedure TGLAbstractShaderUniform.SetMat4(const Value: TMatrix4f);
  5305. begin
  5306. end;
  5307. procedure TGLAbstractShaderUniform.SetSamplerName(const AValue: string);
  5308. begin
  5309. end;
  5310. procedure TGLAbstractShaderUniform.SetAutoSetMethod(const AValue: string);
  5311. begin
  5312. end;
  5313. procedure TGLAbstractShaderUniform.SetTextureName(const AValue: string);
  5314. begin
  5315. end;
  5316. procedure TGLAbstractShaderUniform.SetTextureSwizzle(const AValue:
  5317. TSwizzleVector);
  5318. begin
  5319. end;
  5320. procedure TGLAbstractShaderUniform.SetUInt(const Value: Cardinal);
  5321. begin
  5322. end;
  5323. procedure TGLAbstractShaderUniform.SetUIntArray(const Values: PGLUInt;
  5324. Count: Integer);
  5325. begin
  5326. end;
  5327. procedure TGLAbstractShaderUniform.SetUVec2(const Value: TVector2ui);
  5328. begin
  5329. end;
  5330. procedure TGLAbstractShaderUniform.SetUVec3(const Value: TVector3ui);
  5331. begin
  5332. end;
  5333. procedure TGLAbstractShaderUniform.SetUVec4(const Value: TVector4ui);
  5334. begin
  5335. end;
  5336. procedure TGLAbstractShaderUniform.SetVec2(const Value: TVector2f);
  5337. begin
  5338. end;
  5339. procedure TGLAbstractShaderUniform.SetVec3(const Value: TVector3f);
  5340. begin
  5341. end;
  5342. procedure TGLAbstractShaderUniform.SetVec4(const Value: TVector4f);
  5343. begin
  5344. end;
  5345. procedure TGLAbstractShaderUniform.WriteToFiler(AWriter: TWriter);
  5346. begin
  5347. end;
  5348. { TVXShaderUniform }
  5349. function TGLShaderUniform.GetFloat: Single;
  5350. begin
  5351. // TODO: Type checking
  5352. gl.GetUniformfv(GetProgram, FLocation, @Result);
  5353. end;
  5354. function TGLShaderUniform.GetInt: TGLint;
  5355. begin
  5356. gl.GetUniformiv(GetProgram, FLocation, @Result);
  5357. end;
  5358. function TGLShaderUniform.GetIVec2: TVector2i;
  5359. begin
  5360. gl.GetUniformiv(GetProgram, FLocation, @Result);
  5361. end;
  5362. function TGLShaderUniform.GetIVec3: TVector3i;
  5363. begin
  5364. gl.GetUniformiv(GetProgram, FLocation, @Result);
  5365. end;
  5366. function TGLShaderUniform.GetIVec4: TVector4i;
  5367. begin
  5368. gl.GetUniformiv(GetProgram, FLocation, @Result);
  5369. end;
  5370. function TGLShaderUniform.GetMat2: TMatrix2f;
  5371. begin
  5372. gl.GetUniformfv(GetProgram, FLocation, @Result);
  5373. end;
  5374. function TGLShaderUniform.GetMat3: TMatrix3f;
  5375. begin
  5376. gl.GetUniformfv(GetProgram, FLocation, @Result);
  5377. end;
  5378. function TGLShaderUniform.GetMat4: TMatrix4f;
  5379. begin
  5380. gl.GetUniformfv(GetProgram, FLocation, @Result);
  5381. end;
  5382. function TGLShaderUniform.GetProgram: Cardinal;
  5383. begin
  5384. Result := TGLBaseShaderModel(Owner).FHandle.Handle;
  5385. end;
  5386. procedure TGLShaderUniform.Apply(var ARci: TGLRenderContextInfo);
  5387. begin
  5388. if Assigned(FAutoSet) then
  5389. FAutoSet(Self, ARci);
  5390. end;
  5391. procedure TGLShaderUniform.Assign(Source: TPersistent);
  5392. var
  5393. LUniform: TGLShaderUniform;
  5394. begin
  5395. if Source is TGLShaderUniform then
  5396. begin
  5397. LUniform := TGLShaderUniform(Source);
  5398. FName := LUniform.Name;
  5399. FNameHashCode := LUniform.FNameHashCode;
  5400. FType := LUniform.FType;
  5401. FSamplerType := LUniform.FSamplerType;
  5402. FAutoSet := LUniform.FAutoSet;
  5403. end;
  5404. inherited;
  5405. end;
  5406. function TGLShaderUniform.GetAutoSetMethod: string;
  5407. begin
  5408. Result := GetUniformAutoSetMethodName(FAutoSet);
  5409. end;
  5410. function TGLShaderUniform.GetUInt: Cardinal;
  5411. begin
  5412. gl.GetUniformuiv(GetProgram, FLocation, @Result);
  5413. end;
  5414. function TGLShaderUniform.GetUVec2: TVector2ui;
  5415. begin
  5416. gl.GetUniformuiv(GetProgram, FLocation, @Result);
  5417. end;
  5418. function TGLShaderUniform.GetUVec3: TVector3ui;
  5419. begin
  5420. gl.GetUniformuiv(GetProgram, FLocation, @Result);
  5421. end;
  5422. function TGLShaderUniform.GetUVec4: TVector4ui;
  5423. begin
  5424. gl.GetUniformuiv(GetProgram, FLocation, @Result);
  5425. end;
  5426. function TGLShaderUniform.GetVec2: TVector2f;
  5427. begin
  5428. gl.GetUniformfv(GetProgram, FLocation, @Result);
  5429. end;
  5430. function TGLShaderUniform.GetVec3: TVector3f;
  5431. begin
  5432. gl.GetUniformfv(GetProgram, FLocation, @Result);
  5433. end;
  5434. function TGLShaderUniform.GetVec4: TGLVector;
  5435. begin
  5436. gl.GetUniformfv(GetProgram, FLocation, @Result);
  5437. end;
  5438. procedure TGLShaderUniform.PopProgram;
  5439. begin
  5440. CurrentGLContext.GLStates.CurrentProgram := FStoreProgram;
  5441. end;
  5442. procedure TGLShaderUniform.PushProgram;
  5443. begin
  5444. with CurrentGLContext.GLStates do
  5445. begin
  5446. FStoreProgram := CurrentProgram;
  5447. CurrentProgram := GetProgram;
  5448. end;
  5449. end;
  5450. procedure TGLShaderUniform.ReadFromFiler(AReader: TReader);
  5451. begin
  5452. with AReader do
  5453. begin
  5454. FName := ReadString;
  5455. FNameHashCode := ComputeNameHashKey(FName);
  5456. FType := TGLSLDataType(ReadInteger);
  5457. FSamplerType := TGLSLSamplerType(ReadInteger);
  5458. SetAutoSetMethod(ReadString);
  5459. end;
  5460. end;
  5461. procedure TGLShaderUniform.SetFloat(const Value: TGLFloat);
  5462. begin
  5463. PushProgram;
  5464. gl.Uniform1f(FLocation, Value);
  5465. PopProgram;
  5466. end;
  5467. procedure TGLShaderUniform.SetFloatArray(const Values: PGLFloat;
  5468. Count: Integer);
  5469. begin
  5470. PushProgram;
  5471. gl.Uniform1fv(FLocation, Count, Values);
  5472. PopProgram;
  5473. end;
  5474. procedure TGLShaderUniform.SetInt(const Value: Integer);
  5475. begin
  5476. PushProgram;
  5477. gl.Uniform1i(FLocation, Value);
  5478. PopProgram;
  5479. end;
  5480. procedure TGLShaderUniform.SetIntArray(const Values: PGLInt; Count: Integer);
  5481. begin
  5482. PushProgram;
  5483. gl.Uniform1iv(FLocation, Count, Values);
  5484. PopProgram;
  5485. end;
  5486. procedure TGLShaderUniform.SetIVec2(const Value: TVector2i);
  5487. begin
  5488. PushProgram;
  5489. gl.Uniform2i(FLocation, Value.X, Value.Y);
  5490. PopProgram;
  5491. end;
  5492. procedure TGLShaderUniform.SetIVec3(const Value: TVector3i);
  5493. begin
  5494. PushProgram;
  5495. gl.Uniform3i(FLocation, Value.X, Value.Y, Value.Z);
  5496. PopProgram;
  5497. end;
  5498. procedure TGLShaderUniform.SetIVec4(const Value: TVector4i);
  5499. begin
  5500. PushProgram;
  5501. gl.Uniform4i(FLocation, Value.X, Value.Y, Value.Z, Value.W);
  5502. PopProgram;
  5503. end;
  5504. procedure TGLShaderUniform.SetMat2(const Value: TMatrix2f);
  5505. begin
  5506. PushProgram;
  5507. gl.UniformMatrix2fv(FLocation, 1, False, @Value);
  5508. PopProgram;
  5509. end;
  5510. procedure TGLShaderUniform.SetMat3(const Value: TMatrix3f);
  5511. begin
  5512. PushProgram;
  5513. gl.UniformMatrix2fv(FLocation, 1, False, @Value);
  5514. PopProgram;
  5515. end;
  5516. procedure TGLShaderUniform.SetMat4(const Value: TMatrix4f);
  5517. begin
  5518. PushProgram;
  5519. gl.UniformMatrix4fv(FLocation, 1, False, @Value);
  5520. PopProgram;
  5521. end;
  5522. procedure TGLShaderUniform.SetAutoSetMethod(const AValue: string);
  5523. begin
  5524. FAutoSet := GetUniformAutoSetMethod(AValue);
  5525. end;
  5526. procedure TGLShaderUniform.SetUInt(const Value: Cardinal);
  5527. begin
  5528. PushProgram;
  5529. gl.Uniform1ui(FLocation, Value);
  5530. PopProgram;
  5531. end;
  5532. procedure TGLShaderUniform.SetUIntArray(const Values: PGLUInt; Count: Integer);
  5533. begin
  5534. PushProgram;
  5535. gl.Uniform1uiv(FLocation, Count, Values);
  5536. PopProgram;
  5537. end;
  5538. procedure TGLShaderUniform.SetUVec2(const Value: TVector2ui);
  5539. begin
  5540. PushProgram;
  5541. gl.Uniform2ui(FLocation, Value.X, Value.Y);
  5542. PopProgram;
  5543. end;
  5544. procedure TGLShaderUniform.SetUVec3(const Value: TVector3ui);
  5545. begin
  5546. PushProgram;
  5547. gl.Uniform3ui(FLocation, Value.X, Value.Y, Value.Z);
  5548. PopProgram;
  5549. end;
  5550. procedure TGLShaderUniform.SetUVec4(const Value: TVector4ui);
  5551. begin
  5552. PushProgram;
  5553. gl.Uniform4ui(FLocation, Value.X, Value.Y, Value.Z, Value.W);
  5554. PopProgram;
  5555. end;
  5556. procedure TGLShaderUniform.SetVec2(const Value: TVector2f);
  5557. begin
  5558. PushProgram;
  5559. gl.Uniform2f(FLocation, Value.X, Value.Y);
  5560. PopProgram;
  5561. end;
  5562. procedure TGLShaderUniform.SetVec3(const Value: TVector3f);
  5563. begin
  5564. PushProgram;
  5565. gl.Uniform3f(FLocation, Value.X, Value.Y, Value.Z);
  5566. PopProgram;
  5567. end;
  5568. procedure TGLShaderUniform.SetVec4(const Value: TVector4f);
  5569. begin
  5570. PushProgram;
  5571. gl.Uniform4f(FLocation, Value.X, Value.Y, Value.Z, Value.W);
  5572. PopProgram;
  5573. end;
  5574. procedure TGLShaderUniform.WriteToFiler(AWriter: TWriter);
  5575. begin
  5576. with AWriter do
  5577. begin
  5578. WriteString(FName);
  5579. WriteInteger(Integer(FType));
  5580. WriteInteger(Integer(FSamplerType));
  5581. WriteString(GetAutoSetMethod);
  5582. end;
  5583. end;
  5584. { TVXShaderUniformDSA }
  5585. procedure TGLShaderUniformDSA.SetFloat(const Value: TGLFloat);
  5586. begin
  5587. gl.ProgramUniform1f(GetProgram, FLocation, Value);
  5588. end;
  5589. procedure TGLShaderUniformDSA.SetFloatArray(const Values: PGLFloat;
  5590. Count: Integer);
  5591. begin
  5592. gl.ProgramUniform1fv(GetProgram, FLocation, Count, Values);
  5593. end;
  5594. procedure TGLShaderUniformDSA.SetInt(const Value: Integer);
  5595. begin
  5596. gl.ProgramUniform1i(GetProgram, FLocation, Value);
  5597. end;
  5598. procedure TGLShaderUniformDSA.SetIntArray(const Values: PGLInt; Count: Integer);
  5599. begin
  5600. gl.ProgramUniform1iv(GetProgram, FLocation, Count, Values);
  5601. end;
  5602. procedure TGLShaderUniformDSA.SetIVec2(const Value: TVector2i);
  5603. begin
  5604. gl.ProgramUniform2i(GetProgram, FLocation, Value.X, Value.Y);
  5605. end;
  5606. procedure TGLShaderUniformDSA.SetIVec3(const Value: TVector3i);
  5607. begin
  5608. gl.ProgramUniform3i(GetProgram, FLocation, Value.X, Value.Y, Value.Z);
  5609. end;
  5610. procedure TGLShaderUniformDSA.SetIVec4(const Value: TVector4i);
  5611. begin
  5612. gl.ProgramUniform4i(GetProgram, FLocation, Value.X, Value.Y, Value.Z,
  5613. Value.W);
  5614. end;
  5615. procedure TGLShaderUniformDSA.SetMat2(const Value: TMatrix2f);
  5616. begin
  5617. gl.ProgramUniformMatrix2fv(GetProgram, FLocation, 1, False, @Value);
  5618. end;
  5619. procedure TGLShaderUniformDSA.SetMat3(const Value: TMatrix3f);
  5620. begin
  5621. gl.ProgramUniformMatrix3fv(GetProgram, FLocation, 1, False, @Value);
  5622. end;
  5623. procedure TGLShaderUniformDSA.SetMat4(const Value: TMatrix4f);
  5624. begin
  5625. gl.ProgramUniformMatrix4fv(GetProgram, FLocation, 1, False, @Value);
  5626. end;
  5627. procedure TGLShaderUniformDSA.SetUInt(const Value: Cardinal);
  5628. begin
  5629. gl.ProgramUniform1ui(GetProgram, FLocation, Value);
  5630. end;
  5631. procedure TGLShaderUniformDSA.SetUIntArray(const Values: PGLUInt;
  5632. Count: Integer);
  5633. begin
  5634. gl.ProgramUniform1uiv(GetProgram, FLocation, Count, Values);
  5635. end;
  5636. procedure TGLShaderUniformDSA.SetUVec2(const Value: TVector2ui);
  5637. begin
  5638. gl.ProgramUniform2ui(GetProgram, FLocation, Value.X, Value.Y);
  5639. end;
  5640. procedure TGLShaderUniformDSA.SetUVec3(const Value: TVector3ui);
  5641. begin
  5642. gl.ProgramUniform3ui(GetProgram, FLocation, Value.X, Value.Y, Value.Z);
  5643. end;
  5644. procedure TGLShaderUniformDSA.SetUVec4(const Value: TVector4ui);
  5645. begin
  5646. gl.ProgramUniform4ui(GetProgram, FLocation, Value.X, Value.Y, Value.Z,
  5647. Value.W);
  5648. end;
  5649. procedure TGLShaderUniformDSA.SetVec2(const Value: TVector2f);
  5650. begin
  5651. gl.ProgramUniform2f(GetProgram, FLocation, Value.X, Value.Y);
  5652. end;
  5653. procedure TGLShaderUniformDSA.SetVec3(const Value: TVector3f);
  5654. begin
  5655. gl.ProgramUniform3f(GetProgram, FLocation, Value.X, Value.Y, Value.Z);
  5656. end;
  5657. procedure TGLShaderUniformDSA.SetVec4(const Value: TVector4f);
  5658. begin
  5659. gl.ProgramUniform4f(GetProgram, FLocation, Value.X, Value.Y, Value.Z,
  5660. Value.W);
  5661. end;
  5662. { TVXTextureSwizzling }
  5663. procedure TGLTextureSwizzling.Assign(Source: TPersistent);
  5664. var
  5665. LSwizzling: TGLTextureSwizzling;
  5666. begin
  5667. if Source is TGLTextureSwizzling then
  5668. begin
  5669. LSwizzling := TGLTextureSwizzling(Source);
  5670. FSwizzles[0] := LSwizzling.FSwizzles[0];
  5671. FSwizzles[1] := LSwizzling.FSwizzles[1];
  5672. FSwizzles[2] := LSwizzling.FSwizzles[2];
  5673. FSwizzles[3] := LSwizzling.FSwizzles[3];
  5674. end;
  5675. inherited;
  5676. end;
  5677. constructor TGLTextureSwizzling.Create(AOwner: TPersistent);
  5678. begin
  5679. inherited;
  5680. FSwizzles := cDefaultSwizzleVector;
  5681. end;
  5682. function TGLTextureSwizzling.GetSwizzle(AIndex: Integer): TGLTextureSwizzle;
  5683. begin
  5684. Result := FSwizzles[AIndex];
  5685. end;
  5686. procedure TGLTextureSwizzling.ReadFromFiler(AReader: TReader);
  5687. begin
  5688. with AReader do
  5689. begin
  5690. ReadInteger;
  5691. FSwizzles[0] := TGLTextureSwizzle(ReadInteger);
  5692. FSwizzles[1] := TGLTextureSwizzle(ReadInteger);
  5693. FSwizzles[2] := TGLTextureSwizzle(ReadInteger);
  5694. FSwizzles[3] := TGLTextureSwizzle(ReadInteger);
  5695. end;
  5696. end;
  5697. procedure TGLTextureSwizzling.SetSwizzle(AIndex: Integer;
  5698. AValue: TGLTextureSwizzle);
  5699. begin
  5700. if AValue <> FSwizzles[AIndex] then
  5701. begin
  5702. FSwizzles[AIndex] := AValue;
  5703. NotifyChange(Self);
  5704. end;
  5705. end;
  5706. function TGLTextureSwizzling.StoreSwizzle(AIndex: Integer): Boolean;
  5707. begin
  5708. Result := (FSwizzles[AIndex] <> cDefaultSwizzleVector[AIndex]);
  5709. end;
  5710. procedure TGLTextureSwizzling.WriteToFiler(AWriter: TWriter);
  5711. begin
  5712. with AWriter do
  5713. begin
  5714. WriteInteger(0);
  5715. WriteInteger(Integer(FSwizzles[0]));
  5716. WriteInteger(Integer(FSwizzles[1]));
  5717. WriteInteger(Integer(FSwizzles[2]));
  5718. WriteInteger(Integer(FSwizzles[3]));
  5719. end;
  5720. end;
  5721. { TVXFrameBufferAttachment }
  5722. procedure TGLFrameBufferAttachment.Apply(var ARci: TGLRenderContextInfo);
  5723. begin
  5724. if FIsValid and not FOnlyWrite then
  5725. begin
  5726. // Just bind
  5727. with ARci.GLStates do
  5728. begin
  5729. ActiveTextureEnabled[FHandle.Target] := True;
  5730. TextureBinding[ActiveTexture, FHandle.Target] := FHandle.Handle;
  5731. end;
  5732. end
  5733. else
  5734. ARci.GLStates.TextureBinding[ARci.GLStates.ActiveTexture, FHandle.Target] :=
  5735. 0;
  5736. end;
  5737. procedure TGLFrameBufferAttachment.Assign(Source: TPersistent);
  5738. var
  5739. LAttachment: TGLFrameBufferAttachment;
  5740. begin
  5741. if Source is TGLFrameBufferAttachment then
  5742. begin
  5743. LAttachment := TGLFrameBufferAttachment(Source);
  5744. FLayered := LAttachment.Layered;
  5745. FCubeMap := LAttachment.CubeMap;
  5746. FSamples := LAttachment.Samples;
  5747. FOnlyWrite := LAttachment.OnlyWrite;
  5748. FFixedSamplesLocation := LAttachment.FixedSamplesLocation;
  5749. FWidth := LAttachment.InternalWidth;
  5750. FHeight := LAttachment.InternalHeight;
  5751. FDepth := LAttachment.InternalDepth;
  5752. FInternalFormat := LAttachment.InternalFormat;
  5753. NotifyChange(Self);
  5754. end;
  5755. inherited;
  5756. end;
  5757. constructor TGLFrameBufferAttachment.Create(AOwner: TXCollection);
  5758. begin
  5759. inherited;
  5760. FDefferedInit := False;
  5761. FHandle := TGLTextureHandle.Create;
  5762. FHandle.OnPrapare := DoOnPrepare;
  5763. FRenderBufferHandle := TGLRenderbufferHandle.Create;
  5764. FRenderBufferHandle.OnPrapare := DoOnPrepare;
  5765. FInternalFormat := tfRGBA8;
  5766. FWidth := 256;
  5767. FHeight := 256;
  5768. FDepth := 0;
  5769. FSamples := -1;
  5770. FLayered := False;
  5771. FCubeMap := False;
  5772. FOnlyWrite := False;
  5773. FFixedSamplesLocation := False;
  5774. Name := TGLMatLibComponents(AOwner).MakeUniqueName('Attachment');
  5775. end;
  5776. destructor TGLFrameBufferAttachment.Destroy;
  5777. begin
  5778. FHandle.Destroy;
  5779. FRenderBufferHandle.Destroy;
  5780. inherited;
  5781. end;
  5782. procedure TGLFrameBufferAttachment.DoOnPrepare(Sender: TGLContext);
  5783. var
  5784. LTarget: TGLTextureTarget;
  5785. w, h, d, s, Level, MaxLevel: Integer;
  5786. glTarget, glFormat, glFace: Cardinal;
  5787. begin
  5788. if IsDesignTime and FDefferedInit then
  5789. exit;
  5790. FHandle.AllocateHandle;
  5791. FRenderBufferHandle.AllocateHandle;
  5792. if not (FHandle.IsDataNeedUpdate or FRenderBufferHandle.IsDataNeedUpdate) then
  5793. exit;
  5794. // Target
  5795. if FSamples < 0 then
  5796. begin
  5797. LTarget := ttTexture2D;
  5798. if FHeight = 1 then
  5799. LTarget := ttTexture1D;
  5800. if FCubeMap then
  5801. LTarget := ttTextureCube;
  5802. if FDepth > 0 then
  5803. LTarget := ttTexture3D;
  5804. if FLayered then
  5805. begin
  5806. if FDepth < 2 then
  5807. LTarget := ttTexture1DArray
  5808. else
  5809. LTarget := ttTexture2DArray;
  5810. if FCubeMap then
  5811. LTarget := ttTextureCubeArray;
  5812. end;
  5813. end
  5814. else
  5815. begin
  5816. if FDepth > 0 then
  5817. LTarget := ttTexture2DMultisampleArray
  5818. else
  5819. LTarget := ttTexture2DMultisample;
  5820. end;
  5821. // Check target support
  5822. if FOnlyWrite and (LTarget = ttTexture2DMultisample)
  5823. and not Sender.gl.EXT_framebuffer_multisample then
  5824. begin
  5825. FIsValid := False;
  5826. exit;
  5827. end;
  5828. if not IsTargetSupported(LTarget) then
  5829. begin
  5830. FIsValid := False;
  5831. exit;
  5832. end;
  5833. // Adjust dimension
  5834. w := FWidth;
  5835. h := FHeight;
  5836. d := FDepth;
  5837. s := FSamples;
  5838. if FCubeMap then
  5839. begin
  5840. if w > Integer(Sender.GLStates.MaxCubeTextureSize) then
  5841. w := Sender.GLStates.MaxCubeTextureSize;
  5842. h := w;
  5843. if FLayered then
  5844. begin
  5845. if d < 6 then
  5846. d := 6
  5847. else if (d mod 6) > 0 then
  5848. d := 6 * (d div 6 + 1);
  5849. end;
  5850. end
  5851. else if w > Integer(Sender.GLStates.MaxTextureSize) then
  5852. w := Sender.GLStates.MaxTextureSize;
  5853. if h > Integer(Sender.GLStates.MaxTextureSize) then
  5854. h := Sender.GLStates.MaxTextureSize;
  5855. if FLayered then
  5856. begin
  5857. if d > Integer(Sender.GLStates.MaxArrayTextureSize) then
  5858. d := Sender.GLStates.MaxArrayTextureSize;
  5859. end
  5860. else if d > Integer(Sender.GLStates.Max3DTextureSize) then
  5861. d := Sender.GLStates.Max3DTextureSize;
  5862. if (s > -1) and (s > Integer(Sender.GLStates.MaxSamples)) then
  5863. s := Sender.GLStates.MaxSamples;
  5864. glTarget := DecodeTextureTarget(LTarget);
  5865. if (FHandle.Target <> LTarget)
  5866. and (FHandle.Target <> ttNoShape) then
  5867. begin
  5868. FHandle.DestroyHandle;
  5869. FHandle.AllocateHandle;
  5870. end;
  5871. FHandle.Target := LTarget;
  5872. glFormat := InternalFormatToOpenGLFormat(FInternalFormat);
  5873. if FOnlyWrite and ((LTarget = ttTexture2D) or (LTarget =
  5874. ttTexture2DMultisample))
  5875. and FRenderBufferHandle.IsSupported then
  5876. begin
  5877. if LTarget = ttTexture2D then
  5878. FRenderBufferHandle.SetStorage(glFormat, w, h)
  5879. else
  5880. FRenderBufferHandle.SetStorageMultisample(glFormat, s, w, h);
  5881. end
  5882. else
  5883. with Sender do
  5884. begin
  5885. GLStates.ActiveTextureEnabled[FHandle.Target] := True;
  5886. GLStates.TextureBinding[GLStates.ActiveTexture, FHandle.Target] :=
  5887. FHandle.Handle;
  5888. MaxLevel := CalcTextureLevelNumber(LTarget, w, h, d);
  5889. case glTarget of
  5890. GL_TEXTURE_1D:
  5891. for Level := 0 to MaxLevel - 1 do
  5892. begin
  5893. gl.TexImage1D(glTarget, Level, glFormat, w, 0, GL_RGBA,
  5894. GL_UNSIGNED_BYTE, nil);
  5895. Div2(w);
  5896. end;
  5897. GL_TEXTURE_2D:
  5898. for Level := 0 to MaxLevel - 1 do
  5899. begin
  5900. gl.TexImage2D(glTarget, Level, glFormat, w, h, 0, GL_RGBA,
  5901. GL_UNSIGNED_BYTE, nil);
  5902. Div2(w);
  5903. Div2(h);
  5904. end;
  5905. GL_TEXTURE_RECTANGLE:
  5906. begin
  5907. gl.TexImage2D(glTarget, 0, glFormat, w, h, 0, GL_RGBA,
  5908. GL_UNSIGNED_BYTE, nil);
  5909. end;
  5910. GL_TEXTURE_3D:
  5911. for Level := 0 to MaxLevel - 1 do
  5912. begin
  5913. gl.TexImage3D(glTarget, Level, glFormat, w, h, d, 0, GL_RGBA,
  5914. GL_UNSIGNED_BYTE, nil);
  5915. Div2(w);
  5916. Div2(h);
  5917. Div2(d);
  5918. end;
  5919. GL_TEXTURE_CUBE_MAP:
  5920. for Level := 0 to MaxLevel - 1 do
  5921. begin
  5922. for glFace := GL_TEXTURE_CUBE_MAP_POSITIVE_X to
  5923. GL_TEXTURE_CUBE_MAP_NEGATIVE_Z do
  5924. gl.TexImage2D(glFace, Level, glFormat, w, w, 0, GL_RGBA,
  5925. GL_UNSIGNED_BYTE, nil);
  5926. Div2(w);
  5927. end;
  5928. GL_TEXTURE_1D_ARRAY:
  5929. for Level := 0 to MaxLevel - 1 do
  5930. begin
  5931. gl.TexImage2D(glTarget, Level, glFormat, w, h, 0, GL_RGBA,
  5932. GL_UNSIGNED_BYTE, nil);
  5933. Div2(w);
  5934. end;
  5935. GL_TEXTURE_2D_ARRAY:
  5936. for Level := 0 to MaxLevel - 1 do
  5937. begin
  5938. gl.TexImage3D(glTarget, Level, glFormat, w, h, d, 0, GL_RGBA,
  5939. GL_UNSIGNED_BYTE, nil);
  5940. Div2(w);
  5941. Div2(h);
  5942. end;
  5943. GL_TEXTURE_CUBE_MAP_ARRAY:
  5944. for Level := 0 to MaxLevel - 1 do
  5945. begin
  5946. gl.TexImage3D(glTarget, Level, glFormat, w, w, d, 0, GL_RGBA,
  5947. GL_UNSIGNED_BYTE, nil);
  5948. Div2(w);
  5949. end;
  5950. end; // of case
  5951. GLStates.ActiveTextureEnabled[FHandle.Target] := False;
  5952. FOnlyWrite := False;
  5953. end; // of texture
  5954. if gl.GetError <> GL_NO_ERROR then
  5955. begin
  5956. gl.ClearError;
  5957. GLSLogger.LogErrorFmt('Unable to create attachment "%s"', [Self.Name]);
  5958. exit;
  5959. end
  5960. else
  5961. FIsValid := True;
  5962. FHandle.NotifyDataUpdated;
  5963. FRenderBufferHandle.NotifyDataUpdated;
  5964. end;
  5965. class function TGLFrameBufferAttachment.FriendlyName: string;
  5966. begin
  5967. Result := 'Framebuffer Attachment';
  5968. end;
  5969. procedure TGLFrameBufferAttachment.NotifyChange(Sender: TObject);
  5970. begin
  5971. FHandle.NotifyChangesOfData;
  5972. FRenderBufferHandle.NotifyChangesOfData;
  5973. inherited;
  5974. end;
  5975. procedure TGLFrameBufferAttachment.ReadFromFiler(AReader: TReader);
  5976. var
  5977. archiveVersion: Integer;
  5978. begin
  5979. with AReader do
  5980. begin
  5981. archiveVersion := ReadInteger;
  5982. if archiveVersion = 0 then
  5983. begin
  5984. Name := ReadString;
  5985. FDefferedInit := ReadBoolean;
  5986. FLayered := ReadBoolean;
  5987. FCubeMap := ReadBoolean;
  5988. FSamples := ReadInteger;
  5989. FOnlyWrite := ReadBoolean;
  5990. FFixedSamplesLocation := ReadBoolean;
  5991. FWidth := ReadInteger;
  5992. FHeight := ReadInteger;
  5993. FDepth := ReadInteger;
  5994. FInternalFormat := TGLInternalFormat(ReadInteger);
  5995. end
  5996. else
  5997. RaiseFilerException(archiveVersion);
  5998. end;
  5999. end;
  6000. procedure TGLFrameBufferAttachment.SetCubeMap(AValue: Boolean);
  6001. begin
  6002. if FCubeMap <> AValue then
  6003. begin
  6004. FCubeMap := AValue;
  6005. NotifyChange(Self);
  6006. end;
  6007. end;
  6008. procedure TGLFrameBufferAttachment.SetDepth(AValue: Integer);
  6009. begin
  6010. if FDepth < 0 then
  6011. FDepth := 0
  6012. else if FDepth > 256 then
  6013. FDepth := 256;
  6014. if FDepth <> AValue then
  6015. begin
  6016. FDepth := AValue;
  6017. NotifyChange(Self);
  6018. end;
  6019. end;
  6020. procedure TGLFrameBufferAttachment.SetFixedSamplesLocation(AValue: Boolean);
  6021. begin
  6022. if FFixedSamplesLocation <> AValue then
  6023. begin
  6024. FFixedSamplesLocation := AValue;
  6025. NotifyChange(Self);
  6026. end;
  6027. end;
  6028. procedure TGLFrameBufferAttachment.SetHeight(AValue: Integer);
  6029. begin
  6030. if FHeight < 1 then
  6031. FHeight := 1
  6032. else if FHeight > 8192 then
  6033. FHeight := 8192;
  6034. if FHeight <> AValue then
  6035. begin
  6036. FHeight := AValue;
  6037. NotifyChange(Self);
  6038. end;
  6039. end;
  6040. procedure TGLFrameBufferAttachment.SetInternalFormat(
  6041. const AValue: TGLInternalFormat);
  6042. begin
  6043. if FInternalFormat <> AValue then
  6044. begin
  6045. FInternalFormat := AValue;
  6046. NotifyChange(Self);
  6047. end;
  6048. end;
  6049. procedure TGLFrameBufferAttachment.SetLayered(AValue: Boolean);
  6050. begin
  6051. if FLayered <> AValue then
  6052. begin
  6053. FLayered := AValue;
  6054. NotifyChange(Self);
  6055. end;
  6056. end;
  6057. procedure TGLFrameBufferAttachment.SetOnlyWrite(AValue: Boolean);
  6058. begin
  6059. if FOnlyWrite <> AValue then
  6060. begin
  6061. if AValue
  6062. and ((FDepth > 0) or FLayered or FFixedSamplesLocation or FCubeMap) then
  6063. exit;
  6064. FOnlyWrite := AValue;
  6065. NotifyChange(Self);
  6066. end;
  6067. end;
  6068. procedure TGLFrameBufferAttachment.SetSamples(AValue: Integer);
  6069. begin
  6070. if AValue < -1 then
  6071. AValue := -1;
  6072. if FSamples <> AValue then
  6073. begin
  6074. FSamples := AValue;
  6075. NotifyChange(Self);
  6076. end;
  6077. end;
  6078. procedure TGLFrameBufferAttachment.SetWidth(AValue: Integer);
  6079. begin
  6080. if FWidth < 1 then
  6081. FWidth := 1
  6082. else if FWidth > 8192 then
  6083. FWidth := 8192;
  6084. if FWidth <> AValue then
  6085. begin
  6086. FWidth := AValue;
  6087. NotifyChange(Self);
  6088. end;
  6089. end;
  6090. procedure TGLFrameBufferAttachment.UnApply(var ARci: TGLRenderContextInfo);
  6091. begin
  6092. ARci.GLStates.ActiveTextureEnabled[FHandle.Target] := False;
  6093. end;
  6094. procedure TGLFrameBufferAttachment.WriteToFiler(AWriter: TWriter);
  6095. begin
  6096. with AWriter do
  6097. begin
  6098. WriteInteger(0); // archive version
  6099. WriteString(Name);
  6100. WriteBoolean(FDefferedInit);
  6101. WriteBoolean(FLayered);
  6102. WriteBoolean(FCubeMap);
  6103. WriteInteger(FSamples);
  6104. WriteBoolean(FOnlyWrite);
  6105. WriteBoolean(FFixedSamplesLocation);
  6106. WriteInteger(FWidth);
  6107. WriteInteger(FHeight);
  6108. WriteInteger(FDepth);
  6109. WriteInteger(Integer(FInternalFormat));
  6110. end;
  6111. end;
  6112. constructor TStandartUniformAutoSetExecutor.Create;
  6113. begin
  6114. RegisterUniformAutoSetMethod('Camera world position', GLSLType4F,
  6115. SetCameraPosition);
  6116. RegisterUniformAutoSetMethod('LightSource[0] world position', GLSLType4F,
  6117. SetLightSource0Position);
  6118. RegisterUniformAutoSetMethod('World (model) matrix', GLSLTypeMat4F,
  6119. SetModelMatrix);
  6120. RegisterUniformAutoSetMethod('WorldView matrix', GLSLTypeMat4F,
  6121. SetModelViewMatrix);
  6122. RegisterUniformAutoSetMethod('WorldNormal matrix', GLSLTypeMat3F,
  6123. SetNormalModelMatrix);
  6124. RegisterUniformAutoSetMethod('Inverse World matrix', GLSLTypeMat4F,
  6125. SetInvModelMatrix);
  6126. RegisterUniformAutoSetMethod('View matrix', GLSLTypeMat4F, SetViewMatrix);
  6127. RegisterUniformAutoSetMethod('Inverse WorldView matrix', GLSLTypeMat4F,
  6128. SetInvModelViewMatrix);
  6129. RegisterUniformAutoSetMethod('Projection matrix', GLSLTypeMat4F,
  6130. SetProjectionMatrix);
  6131. RegisterUniformAutoSetMethod('ViewProjection matrix', GLSLTypeMat4F,
  6132. SetViewProjectionMatrix);
  6133. RegisterUniformAutoSetMethod('WorldViewProjection matrix', GLSLTypeMat4F,
  6134. SetWorldViewProjectionMatrix);
  6135. RegisterUniformAutoSetMethod('Material front face emission', GLSLType4F,
  6136. SetMaterialFrontEmission);
  6137. RegisterUniformAutoSetMethod('Material front face ambient', GLSLType4F,
  6138. SetMaterialFrontAmbient);
  6139. RegisterUniformAutoSetMethod('Material front face diffuse', GLSLType4F,
  6140. SetMaterialFrontDiffuse);
  6141. RegisterUniformAutoSetMethod('Material front face specular', GLSLType4F,
  6142. SetMaterialFrontSpecular);
  6143. RegisterUniformAutoSetMethod('Material front face shininess', GLSLType1F,
  6144. SetMaterialFrontShininess);
  6145. RegisterUniformAutoSetMethod('Material back face emission', GLSLType4F,
  6146. SetMaterialBackEmission);
  6147. RegisterUniformAutoSetMethod('Material back face ambient', GLSLType4F,
  6148. SetMaterialBackAmbient);
  6149. RegisterUniformAutoSetMethod('Material back face diffuse', GLSLType4F,
  6150. SetMaterialBackDiffuse);
  6151. RegisterUniformAutoSetMethod('Material back face specular', GLSLType4F,
  6152. SetMaterialBackSpecular);
  6153. RegisterUniformAutoSetMethod('Material back face shininess', GLSLType1F,
  6154. SetMaterialBackShininess)
  6155. end;
  6156. procedure TStandartUniformAutoSetExecutor.SetCameraPosition(Sender:
  6157. IShaderParameter; var ARci: TGLRenderContextInfo);
  6158. begin
  6159. Sender.vec4 := ARci.cameraPosition;
  6160. end;
  6161. procedure TStandartUniformAutoSetExecutor.SetInvModelMatrix(Sender:
  6162. IShaderParameter; var ARci: TGLRenderContextInfo);
  6163. begin
  6164. Sender.mat4 := ARci.PipelineTransformation.InvModelMatrix^;
  6165. end;
  6166. procedure TStandartUniformAutoSetExecutor.SetInvModelViewMatrix(Sender:
  6167. IShaderParameter; var ARci: TGLRenderContextInfo);
  6168. begin
  6169. Sender.mat4 := ARci.PipelineTransformation.InvModelViewMatrix^;
  6170. end;
  6171. procedure TStandartUniformAutoSetExecutor.SetLightSource0Position(Sender:
  6172. IShaderParameter; var ARci: TGLRenderContextInfo);
  6173. begin
  6174. Sender.vec4 := ARci.GLStates.LightPosition[0];
  6175. end;
  6176. procedure TStandartUniformAutoSetExecutor.SetMaterialBackAmbient(Sender:
  6177. IShaderParameter; var ARci: TGLRenderContextInfo);
  6178. begin
  6179. Sender.vec4 := ARci.GLStates.MaterialAmbient[cmBack];
  6180. end;
  6181. procedure TStandartUniformAutoSetExecutor.SetMaterialBackDiffuse(Sender:
  6182. IShaderParameter; var ARci: TGLRenderContextInfo);
  6183. begin
  6184. Sender.vec4 := ARci.GLStates.MaterialDiffuse[cmBack];
  6185. end;
  6186. procedure TStandartUniformAutoSetExecutor.SetMaterialBackEmission(Sender:
  6187. IShaderParameter; var ARci: TGLRenderContextInfo);
  6188. begin
  6189. Sender.vec4 := ARci.GLStates.MaterialEmission[cmBack];
  6190. end;
  6191. procedure TStandartUniformAutoSetExecutor.SetMaterialBackShininess(Sender:
  6192. IShaderParameter; var ARci: TGLRenderContextInfo);
  6193. begin
  6194. Sender.float := ARci.GLStates.MaterialShininess[cmBack];
  6195. end;
  6196. procedure TStandartUniformAutoSetExecutor.SetMaterialBackSpecular(Sender:
  6197. IShaderParameter; var ARci: TGLRenderContextInfo);
  6198. begin
  6199. Sender.vec4 := ARci.GLStates.MaterialSpecular[cmBack];
  6200. end;
  6201. procedure TStandartUniformAutoSetExecutor.SetMaterialFrontAmbient(Sender:
  6202. IShaderParameter; var ARci: TGLRenderContextInfo);
  6203. begin
  6204. Sender.vec4 := ARci.GLStates.MaterialAmbient[cmFront];
  6205. end;
  6206. procedure TStandartUniformAutoSetExecutor.SetMaterialFrontDiffuse(Sender:
  6207. IShaderParameter; var ARci: TGLRenderContextInfo);
  6208. begin
  6209. Sender.vec4 := ARci.GLStates.MaterialDiffuse[cmFront];
  6210. end;
  6211. procedure TStandartUniformAutoSetExecutor.SetMaterialFrontEmission(Sender:
  6212. IShaderParameter; var ARci: TGLRenderContextInfo);
  6213. begin
  6214. Sender.vec4 := ARci.GLStates.MaterialEmission[cmFront];
  6215. end;
  6216. procedure TStandartUniformAutoSetExecutor.SetMaterialFrontShininess(Sender:
  6217. IShaderParameter; var ARci: TGLRenderContextInfo);
  6218. begin
  6219. Sender.float := ARci.GLStates.MaterialShininess[cmFront];
  6220. end;
  6221. procedure TStandartUniformAutoSetExecutor.SetMaterialFrontSpecular(Sender:
  6222. IShaderParameter; var ARci: TGLRenderContextInfo);
  6223. begin
  6224. Sender.vec4 := ARci.GLStates.MaterialSpecular[cmFront];
  6225. end;
  6226. procedure TStandartUniformAutoSetExecutor.SetModelMatrix(Sender:
  6227. IShaderParameter; var ARci: TGLRenderContextInfo);
  6228. begin
  6229. Sender.mat4 := ARci.PipelineTransformation.ModelMatrix^;
  6230. end;
  6231. procedure TStandartUniformAutoSetExecutor.SetModelViewMatrix(Sender:
  6232. IShaderParameter; var ARci: TGLRenderContextInfo);
  6233. begin
  6234. Sender.mat4 := ARci.PipelineTransformation.ModelViewMatrix^;
  6235. end;
  6236. procedure TStandartUniformAutoSetExecutor.SetNormalModelMatrix(Sender:
  6237. IShaderParameter; var ARci: TGLRenderContextInfo);
  6238. begin
  6239. Sender.mat3 := ARci.PipelineTransformation.NormalModelMatrix^;
  6240. end;
  6241. procedure TStandartUniformAutoSetExecutor.SetProjectionMatrix(Sender:
  6242. IShaderParameter; var ARci: TGLRenderContextInfo);
  6243. begin
  6244. Sender.mat4 := ARci.PipelineTransformation.ProjectionMatrix^;
  6245. end;
  6246. procedure TStandartUniformAutoSetExecutor.SetViewMatrix(Sender:
  6247. IShaderParameter; var ARci: TGLRenderContextInfo);
  6248. begin
  6249. Sender.mat4 := ARci.PipelineTransformation.ViewMatrix^;
  6250. end;
  6251. procedure TStandartUniformAutoSetExecutor.SetViewProjectionMatrix(Sender:
  6252. IShaderParameter; var ARci: TGLRenderContextInfo);
  6253. begin
  6254. Sender.mat4 := ARci.PipelineTransformation.ViewProjectionMatrix^;
  6255. end;
  6256. procedure TStandartUniformAutoSetExecutor.SetWorldViewProjectionMatrix(Sender:
  6257. IShaderParameter; var ARci: TGLRenderContextInfo);
  6258. begin
  6259. Sender.mat4 := MatrixMultiply(
  6260. ARci.PipelineTransformation.ModelViewMatrix^,
  6261. ARci.PipelineTransformation.ProjectionMatrix^);
  6262. end;
  6263. { TVXASMVertexProgram }
  6264. procedure TGLASMVertexProgram.Assign(Source: TPersistent);
  6265. var
  6266. LProg: TGLASMVertexProgram;
  6267. begin
  6268. if Source is TGLASMVertexProgram then
  6269. begin
  6270. LProg := TGLASMVertexProgram(Source);
  6271. FSource.Assign(LProg.FSource);
  6272. end;
  6273. inherited;
  6274. end;
  6275. constructor TGLASMVertexProgram.Create(AOwner: TXCollection);
  6276. begin
  6277. inherited;
  6278. FHandle := TGLARBVertexProgramHandle.Create;
  6279. FHandle.OnPrapare := DoOnPrepare;
  6280. FSource := TStringList.Create;
  6281. FSource.OnChange := NotifyChange;
  6282. Name := TGLMatLibComponents(AOwner).MakeUniqueName('VertexProg');
  6283. end;
  6284. destructor TGLASMVertexProgram.Destroy;
  6285. begin
  6286. FHandle.Destroy;
  6287. FSource.Destroy;
  6288. inherited;
  6289. end;
  6290. procedure TGLASMVertexProgram.DoOnPrepare(Sender: TGLContext);
  6291. begin
  6292. if FDefferedInit and not IsDesignTime then
  6293. exit;
  6294. try
  6295. if FHandle.IsSupported then
  6296. begin
  6297. FHandle.AllocateHandle;
  6298. if FHandle.IsDataNeedUpdate then
  6299. begin
  6300. SetExeDirectory;
  6301. if (Length(FSourceFile) > 0) and FileStreamExists(FSourceFile) then
  6302. FSource.LoadFromFile(FSourceFile);
  6303. if FSource.Count > 0 then
  6304. begin
  6305. FHandle.LoadARBProgram(FSource.Text);
  6306. FIsValid := FHandle.Ready;
  6307. if IsDesignTime then
  6308. begin
  6309. FInfoLog := FHandle.InfoLog;
  6310. if (Length(FInfoLog) = 0) and FIsValid then
  6311. FInfoLog := 'Compilation successful';
  6312. end
  6313. else if FIsValid then
  6314. GLSLogger.LogInfoFmt('Program "%s" compilation successful - %s',
  6315. [Name, FHandle.InfoLog])
  6316. else
  6317. GLSLogger.LogErrorFmt('Program "%s" compilation failed - %s',
  6318. [Name, FHandle.InfoLog]);
  6319. FHandle.NotifyDataUpdated;
  6320. end
  6321. else
  6322. begin
  6323. if IsDesignTime then
  6324. FInfoLog := 'No source'
  6325. else
  6326. GLSLogger.LogInfoFmt('Program "%s" has no source code', [Name]);
  6327. FIsValid := False;
  6328. end;
  6329. end;
  6330. end
  6331. else
  6332. begin
  6333. FIsValid := False;
  6334. if IsDesignTime then
  6335. FInfoLog := 'Not supported by hardware';
  6336. end;
  6337. except
  6338. on E: Exception do
  6339. begin
  6340. FIsValid := False;
  6341. if IsDesignTime then
  6342. InformationDlg(E.ClassName + ': ' + E.Message)
  6343. else
  6344. GLSLogger.LogError(E.ClassName + ': ' + E.Message);
  6345. end;
  6346. end;
  6347. end;
  6348. class function TGLASMVertexProgram.FriendlyName: string;
  6349. begin
  6350. Result := 'ASM Vertex Program';
  6351. end;
  6352. function TGLASMVertexProgram.GetHandle: TGLARBVertexProgramHandle;
  6353. begin
  6354. Result := FHandle;
  6355. end;
  6356. procedure TGLASMVertexProgram.NotifyChange(Sender: TObject);
  6357. begin
  6358. FHandle.NotifyChangesOfData;
  6359. inherited;
  6360. end;
  6361. procedure TGLASMVertexProgram.ReadFromFiler(AReader: TReader);
  6362. var
  6363. archiveVersion: Integer;
  6364. begin
  6365. with AReader do
  6366. begin
  6367. archiveVersion := ReadInteger;
  6368. if archiveVersion = 0 then
  6369. begin
  6370. Name := ReadString;
  6371. FDefferedInit := ReadBoolean;
  6372. FSource.Text := ReadString;
  6373. FSourceFile := ReadString;
  6374. end
  6375. else
  6376. RaiseFilerException(archiveVersion);
  6377. end;
  6378. end;
  6379. procedure TGLASMVertexProgram.SetSource(AValue: TStringList);
  6380. begin
  6381. FSource.Assign(AValue);
  6382. end;
  6383. procedure TGLASMVertexProgram.SetSourceFile(AValue: string);
  6384. begin
  6385. FixPathDelimiter(AValue);
  6386. if FSourceFile <> AValue then
  6387. begin
  6388. FSourceFile := AValue;
  6389. NotifyChange(Self);
  6390. end;
  6391. end;
  6392. procedure TGLASMVertexProgram.WriteToFiler(AWriter: TWriter);
  6393. begin
  6394. with AWriter do
  6395. begin
  6396. WriteInteger(0); // archive version
  6397. WriteString(Name);
  6398. WriteBoolean(FDefferedInit);
  6399. if Length(FSourceFile) = 0 then
  6400. WriteString(FSource.Text)
  6401. else
  6402. WriteString('');
  6403. WriteString(FSourceFile);
  6404. end;
  6405. end;
  6406. initialization
  6407. RegisterClasses(
  6408. [
  6409. TGLTextureImageEx,
  6410. TGLFrameBufferAttachment,
  6411. TGLTextureSampler,
  6412. TGLTextureCombiner,
  6413. TGLShaderEx,
  6414. TGLASMVertexProgram,
  6415. TGLMaterialLibraryEx,
  6416. TGLShaderUniform,
  6417. TGLShaderUniformDSA,
  6418. TGLShaderUniformTexture
  6419. ]);
  6420. RegisterXCollectionItemClass(TGLTextureImageEx);
  6421. RegisterXCollectionItemClass(TGLTextureSampler);
  6422. RegisterXCollectionItemClass(TGLFrameBufferAttachment);
  6423. RegisterXCollectionItemClass(TGLTextureCombiner);
  6424. RegisterXCollectionItemClass(TGLShaderEx);
  6425. RegisterXCollectionItemClass(TGLASMVertexProgram);
  6426. vStandartUniformAutoSetExecutor := TStandartUniformAutoSetExecutor.Create;
  6427. finalization
  6428. vStandartUniformAutoSetExecutor.Destroy;
  6429. end.