GLMaterialEx.pas 210 KB

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