*/}}

la_tns_kernel.c 198 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181
  1. /*
  2. * LaGUI: A graphical application framework.
  3. * Copyright (C) 2022-2023 Wu Yiming
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "la_5.h"
  19. #include <math.h>
  20. #include "freetype/ftadvanc.h"
  21. #ifdef LA_WITH_PNG
  22. #include <png.h>
  23. #endif
  24. #define HF 0.5
  25. // 1 2
  26. // 7 9 11 13 14
  27. // 3 4
  28. // 8 10 12 15 16
  29. // 5 6
  30. real TNS_LCD_SEG_16[16][4]={
  31. {0,0,HF,0},{HF,0,1,0},{0,0.5,HF,0.5},{HF,0.5,1,0.5},{0,1,HF,1},{HF,1,1,1},
  32. {0,0,0,HF},{0,HF,0,1},{0.5,0,0.5,HF},{0.5,HF,0.5,1},{1,0,1,HF},{1,HF,1,1},
  33. {0,0,HF,HF},{1,0,HF,HF},{0,1,HF,HF},{1,1,HF,HF},
  34. };
  35. char TNS_LCD_MAP_16[][16]={
  36. {1,1,0,0,1,1,1,1,0,0,1,1,0,1,1,0},{0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0},//0-9
  37. {1,1,1,1,1,1,0,1,0,0,1,0,0,0,0,0},{1,1,1,1,1,1,0,0,0,0,1,1,0,0,0,0},
  38. {0,0,1,1,0,0,1,0,1,1,0,0,0,0,0,0},{1,1,1,1,1,1,1,0,0,0,0,1,0,0,0,0},
  39. {1,1,1,1,1,1,1,1,0,0,0,1,0,0,0,0},{1,1,0,0,0,0,0,0,0,0,0,0,0,1,1,0},
  40. {1,1,1,1,1,1,1,1,0,0,1,1,0,0,0,0},{1,1,1,1,1,1,1,0,0,0,1,1,0,0,0,0},
  41. {1,1,1,1,0,0,1,1,0,0,1,1,0,0,0,0},{1,1,0,1,1,1,0,0,1,1,1,1,0,0,0,0},//A
  42. {1,1,0,0,1,1,1,1,0,0,0,0,0,0,0,0},{1,1,0,0,1,1,0,0,1,1,1,1,0,0,0,0},
  43. {1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0},{1,1,1,1,0,0,1,1,0,0,0,0,0,0,0,0},
  44. {1,1,0,1,1,1,1,1,0,0,0,1,0,0,0,0},{0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,0},
  45. {1,1,0,0,1,1,0,0,1,1,0,0,0,0,0,0},{1,1,0,0,1,0,0,0,1,1,0,0,0,0,0,0},
  46. {0,0,1,0,0,0,1,1,0,0,0,0,0,1,0,1},{0,0,0,0,1,1,1,1,0,0,0,0,0,0,0,0},
  47. {0,0,0,0,0,0,1,1,0,0,1,1,1,1,0,0},{0,0,0,0,0,0,1,1,0,0,1,1,1,0,0,1},
  48. {1,1,0,0,1,1,1,1,0,0,1,1,0,0,0,0},{1,1,1,1,0,0,1,1,0,0,1,0,0,0,0,0},
  49. {1,1,0,0,1,1,1,1,0,0,1,1,0,0,0,1},{1,1,1,1,0,0,1,1,0,0,1,0,0,0,0,1},
  50. {1,1,0,1,1,1,0,0,0,0,0,1,1,0,0,0},{1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0},
  51. {0,0,0,0,1,1,1,1,0,0,1,1,0,0,0,0},{0,0,0,0,0,0,1,1,0,0,0,0,0,1,1,0},
  52. {0,0,0,0,0,0,1,1,0,0,1,1,0,0,1,1},{0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1},
  53. {0,0,0,0,0,0,0,0,0,1,0,0,1,1,0,0},{1,1,0,0,1,1,0,0,0,0,0,0,0,1,1,0},
  54. {0,0,1,0,1,1,0,1,0,1,0,0,0,0,0,0},{0,0,0,1,1,1,0,0,1,1,0,1,0,0,0,0},//a
  55. {0,0,1,1,1,1,0,1,0,0,0,0,0,0,0,0},{0,0,1,0,1,1,0,1,1,1,0,0,0,0,0,0},
  56. {0,0,1,0,1,1,0,1,0,0,0,0,0,0,1,0},{0,1,1,1,1,0,0,0,1,1,0,0,0,0,0,0},
  57. {0,1,0,1,1,1,0,1,1,0,1,1,0,0,0,0},{0,0,1,0,0,1,1,1,0,1,0,0,0,0,0,0},
  58. {1,0,1,0,0,1,0,0,0,1,0,0,0,0,0,0},{0,1,0,1,1,1,0,0,0,0,0,1,0,0,0,0},
  59. {0,0,1,1,0,0,0,1,1,0,0,0,0,0,0,1},{1,0,0,0,0,1,0,0,1,1,0,0,0,0,0,0},
  60. {0,0,1,1,0,0,0,1,0,1,0,1,0,0,0,0},{0,0,1,0,0,1,0,1,0,1,0,0,0,0,0,0},
  61. {0,0,1,1,1,1,0,1,0,0,0,1,0,0,0,0},{1,1,0,1,0,0,0,0,1,1,1,0,0,0,0,0},
  62. {1,1,0,0,0,0,1,0,1,1,0,0,0,0,0,0},{0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0},
  63. {0,0,0,1,1,1,0,0,0,0,0,0,0,0,0,1},{0,0,1,1,0,1,0,0,1,1,0,0,0,0,0,0},
  64. {0,0,0,0,1,1,0,1,0,1,0,0,0,0,0,0},{0,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0},
  65. {0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,1},{0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1},
  66. {0,0,0,1,1,1,0,0,1,0,1,1,0,0,0,0},{0,0,1,0,1,1,0,0,0,0,0,0,0,0,1,0},
  67. };
  68. // 1
  69. // 4 6
  70. // 2
  71. // 5 7
  72. // 3
  73. real TNS_LCD_SEG_7[7][4]={ {0,0,1,0},{0,0.5,1,0.5},{0,1,1,1},
  74. {0,0,0,HF},{0,HF,0,1},{1,0,1,HF},{1,HF,1,1},
  75. };
  76. char TNS_LCD_MAP_7[][7]={
  77. {1,0,1,1,1,1,1},{0,0,0,0,0,1,1},{1,1,1,0,1,1,0},{1,1,1,0,0,1,1},{0,1,0,1,0,1,1},// 0-4
  78. {1,1,1,1,0,0,1},{1,1,1,1,1,0,1},{1,0,0,0,0,1,1},{1,1,1,1,1,1,1},{1,1,1,1,0,1,1},// 6-9
  79. };
  80. #undef HF
  81. int tKnlAttatchShader(tnsShader *tns);
  82. tnsShader *tKnlFindShader1i(int CustomIndex);
  83. void tKnlPushMatrix();
  84. void tKnlPopMatrix();
  85. laListHandle *tKnlGetTextureList();
  86. void tnsLoadIdentity44d(tnsMatrix44d m);
  87. void tnsMakeOrthoMatrix44d(tnsMatrix44d mProjection, real xMin, real xMax, real yMin, real yMax, real zMin, real zMax);
  88. void tnsMakePerspectiveMatrix44d(tnsMatrix44d mProjection, real fFov_rad, real fAspect, real zMin, real zMax);
  89. void tnsMakeTranslationMatrix44d(tnsMatrix44d mTrans, real x, real y, real z);
  90. void tnsMakeRotationMatrix44d(tnsMatrix44d m, real angle_rad, real x, real y, real z);
  91. void tnsMakeScaleMatrix44d(tnsMatrix44d m, real x, real y, real z);
  92. void tnsMultiply44d(tnsMatrix44d result, tnsMatrix44d l, tnsMatrix44d r);
  93. void tnsInitFirstLevel(tnsMatrixStack *tms);
  94. tnsMatrixStackItem *tKnlGetCurrentMatStackItem();
  95. void tnsAttach2DOffscreenBuffer(tnsOffscreen *target, GLuint attatchment, tnsTexture *use);
  96. void tnsDetach2DOffscreenBuffer(tnsOffscreen *target, GLuint which_attach_point);
  97. //=========================================================================================
  98. tnsMain *T;
  99. real DefaultZRange[2] = {0.1, 1000};
  100. //=======================================[SYS]
  101. extern LA MAIN;
  102. void InitGLRenderEnviornment(){
  103. glEnable(GL_SCISSOR_TEST);
  104. };
  105. #ifdef __linux__
  106. void tnsContextMakeCurrent(SYSGLCONTEXT context, SYSWINDOW win, void* gles_surf){
  107. #ifdef LA_USE_GLES
  108. eglMakeCurrent(MAIN.egl_dpy,gles_surf,gles_surf,context);
  109. if(gles_surf){ EGLSurface* surf=gles_surf; T->CurrentSurface=(*surf); }else{ T->CurrentSurface=0; }
  110. #else
  111. glXMakeContextCurrent(MAIN.dpy, win, win, context);
  112. #endif
  113. T->CurrentContext=context; T->CurrentWindow=win; tnsUnbindTexture(); tnsUseNoTexture();
  114. };
  115. #endif
  116. #ifdef _WIN32
  117. void tnsContextMakeCurrent(SYSGLCONTEXT context, SYSTEMDC hdc,void* unused){
  118. wglMakeCurrent(hdc, context); T->CurrentContext=context; T->CurrentDC=hdc;
  119. tnsUnbindTexture(); tnsUseNoTexture();
  120. };
  121. #endif
  122. #ifdef LA_USE_GLES
  123. void tnsContextMakeFBOCurrent(tnsOffscreen* off){
  124. tnsContextMakeCurrent(off->FboContext,off->FboWindow,off->FboSurface);
  125. }
  126. void tnsContextMakeWindowCurrent(laWindow* w){
  127. tnsContextMakeCurrent(w->glc,w->win,w->egl_surf);
  128. }
  129. #else
  130. void tnsContextMakeFBOCurrent(tnsOffscreen* off){
  131. #ifdef _WIN32
  132. tnsContextMakeCurrent(off->FboContext,off->FboDC,0);
  133. #else
  134. tnsContextMakeCurrent(off->FboContext,off->FboWindow,0);
  135. #endif
  136. }
  137. void tnsContextMakeWindowCurrent(laWindow* w){
  138. tnsContextMakeCurrent(w->glc,w->win,0);
  139. }
  140. #endif
  141. void tnsSwitchToCurrentWindowContext(laWindow* w){
  142. tnsContextMakeWindowCurrent(w);
  143. };
  144. void tnsDeleteContext(SYSGLCONTEXT glc){
  145. #ifdef __linux__
  146. #ifdef LA_USE_GLES
  147. eglDestroyContext(MAIN.egl_dpy,glc);
  148. #else
  149. glXDestroyContext(MAIN.dpy,glc);
  150. #endif
  151. #endif
  152. #ifdef _WIN32
  153. wglDeleteContext(glc);
  154. #endif
  155. for(tnsOffscreen* o=T->Offscreens.pFirst;o;o=o->Item.pNext){
  156. if(o->FboContext==glc){ o->FboContext=0; }
  157. }
  158. }
  159. void tnsBindVertexArray(GLuint vao){
  160. T->CurrentVAO=vao; glBindVertexArray(vao);
  161. }
  162. void tnsViewportWithScissor(int x, int y, int w, int h){
  163. tnsShader *current_shader = 0;
  164. glEnable(GL_SCISSOR_TEST);
  165. glViewport(x, y, w, h); glScissor(x, y, w, h);
  166. T->vsx=x;T->vsy=y;T->vsw=w;T->vsh=h;
  167. if ((current_shader = T->CurrentShader)){
  168. tnsResetViewMatrix();
  169. tnsShaderApplyView(current_shader, tnsGetViewMatrix());
  170. tnsResetModelMatrix();
  171. tnsShaderApplyModel(current_shader, tnsGetModelMatrix());
  172. }
  173. }
  174. void tnsViewport(int x, int y, int w, int h){
  175. glViewport(x, y, w, h);
  176. }
  177. //Must At Origion!
  178. //void UseWindowMatrix_WithScissor(laWndPlacement* wp){
  179. // tnsViewportWithScissor(0, 0, VAL2_CLIENT_W_H(*wp));
  180. // SetMatrix2Di(0, VAL2_CLIENT_W_H(*wp), 0);
  181. //};
  182. //void UseBlockMatrix_WithScissor(laBlockPlacement* bp){
  183. // tnsViewportWithScissor(bp->UpperLeftX,
  184. // bp->ClientHeight - bp->LowerRightY,
  185. // bp->LowerRightX - bp->UpperLeftX,
  186. // bp->LowerRightY - bp->UpperLeftY);
  187. // SetMatrix2Di(0, bp->LowerRightX - bp->UpperLeftX,
  188. // 0, bp->UpperLeftY - bp->LowerRightY);
  189. //};
  190. void DrawWireRect2dp(real x, real y, real x2, real y2){
  191. real Verts[8];
  192. tnsMakeQuad2d(Verts, x, y, x2, y, x2, y2, x, y2);
  193. tnsVertexArray2d(Verts, 4);
  194. tnsPackAs(GL_LINE_LOOP);
  195. };
  196. void DrawWireRect4ds(real x, real y, real w, real h){
  197. real Verts[8];
  198. tnsMakeQuad2d(Verts, x, y, x + w, y, x + w, y + h, x, y + h);
  199. tnsVertexArray2d(Verts, 4);
  200. tnsPackAs(GL_LINE_LOOP);
  201. };
  202. void DrawWireRect4drs(real x, real y, real w, real h){
  203. real Verts[8];
  204. tnsMakeQuad2d(Verts, x, y, x + w, y, x + w, y - h, x, y - h);
  205. tnsVertexArray2d(Verts, 4);
  206. tnsPackAs(GL_LINE_LOOP);
  207. };
  208. void DrawSoildRect4drs(real x, real y, real w, real h){
  209. real Verts[8];
  210. tnsMakeQuad2d(Verts, x, y, x + w, y, x + w, y - h, x, y - h);
  211. tnsVertexArray2d(Verts, 4);
  212. tnsPackAs(GL_TRIANGLE_FAN);
  213. }
  214. void DrawWireCross4ds(real x, real y, real w, real h){
  215. real Verts[8];
  216. tnsMakeQuad2d(Verts, x, y, x + w, y + h, x + w, y, x, y + h);
  217. tnsVertexArray2d(Verts, 4);
  218. tnsPackAs(GL_LINES);
  219. };
  220. void DrawWireCross4drs(real x, real y, real w, real h){
  221. real Verts[8];
  222. tnsMakeQuad2d(Verts, x, y, x + w, y - h, x + w, y, x, y - h);
  223. tnsVertexArray2d(Verts, 4);
  224. tnsPackAs(GL_LINES);
  225. };
  226. void DrawGrid6f(real L, real R, real U, real B, real stepX, real stepY){
  227. //do nothing;
  228. }
  229. //=======================================[Shader]
  230. int tnsNextPowOf2(int i){
  231. int result = 2;
  232. while (result < i){
  233. result *= 2;
  234. }
  235. return result;
  236. }
  237. void tnsShaderMakeIndex(tnsShader *tns){
  238. int program;
  239. if (!tns) return;
  240. program = tns->glProgramID;
  241. tns->iModel = glGetUniformLocation(program, "mModel");
  242. tns->iProjection = glGetUniformLocation(program, "mProjection");
  243. tns->iProjectionInverse = glGetUniformLocation(program, "mProjectionInverse");
  244. tns->iView = glGetUniformLocation(program, "mView");
  245. //tns->iNormal = glGetUniformLocation(program, "mNormalScaler");
  246. tns->iShadow = glGetUniformLocation(program, "mShadow");
  247. tns->iVertex = glGetAttribLocation(program, "vVertex");
  248. tns->iNormal = glGetAttribLocation(program, "vNormal");
  249. tns->iColor = glGetAttribLocation(program, "vColor");
  250. tns->iUV = glGetAttribLocation(program, "vUV");
  251. tns->iTexColor = glGetUniformLocation(program, "TexColor");
  252. tns->iTexNormal = glGetUniformLocation(program, "TexNormal");
  253. tns->iTexGPos = glGetUniformLocation(program, "TexGPos");
  254. tns->iTexColorMS = glGetUniformLocation(program, "TexColorMS");
  255. tns->iMultiplyColor = glGetUniformLocation(program, "MultiplyColor");
  256. tns->iTextureMode = glGetUniformLocation(program, "TextureMode");
  257. tns->iColorMode = glGetUniformLocation(program, "ColorMode");
  258. tns->iHCYGamma = glGetUniformLocation(program, "HCYGamma");
  259. tns->iSampleAmount = glGetUniformLocation(program, "SampleAmount");
  260. tns->iUseNormal = glGetUniformLocation(program, "UseNormal");
  261. tns->iOutputColorSpace=glGetUniformLocation(program, "OutputColorSpace");
  262. tns->iInputColorSpace=glGetUniformLocation(program, "InputColorSpace");
  263. tns->iShowStripes=glGetUniformLocation(program, "ShowStripes");
  264. tns->iComposing=glGetUniformLocation(program, "Composing");
  265. tns->iComposingGamma=glGetUniformLocation(program, "ComposingGamma");
  266. tns->iComposingBlackpoint=glGetUniformLocation(program, "ComposingBlackpoint");
  267. if(tns->iTexColor>=0){glUniform1i(tns->iTexColor, 0);}
  268. if(tns->iTexColorMS>=0){glUniform1i(tns->iTexColorMS, 1);}
  269. tns->iDoOffset = glGetUniformLocation(program, "DoOffset");
  270. tns->iUseHalftone = glGetUniformLocation(program, "UseHalftone");
  271. tns->iHalftoneSize = glGetUniformLocation(program, "HalftoneSize");
  272. tns->uViewDir = glGetUniformLocation(program, "uViewDir");
  273. tns->uViewPos = glGetUniformLocation(program, "uViewPos");
  274. tns->uNear = glGetUniformLocation(program, "uNear");
  275. tns->uFar = glGetUniformLocation(program, "uFar");
  276. tns->uFOV = glGetUniformLocation(program, "uFOV");
  277. }
  278. void tnsShaderApplyProjection(tnsShader *tns, tnsMatrix44d m){
  279. tnsMatrix44f mf;
  280. if (T->BindedShader != tns){ glUseProgram(tns->glProgramID); T->BindedShader = tns; }
  281. tnsConvert44df(m, mf);
  282. if(tns->iProjection>-1) glUniformMatrix4fv(tns->iProjection, 1, 0, mf);
  283. }
  284. void tnsShaderApplyProjectionInverse(tnsShader *tns, tnsMatrix44d m){
  285. tnsMatrix44f mf;
  286. tnsMatrix44d i;
  287. if (T->BindedShader != tns){ glUseProgram(tns->glProgramID); T->BindedShader = tns; }
  288. tnsInverse44d(i, m);
  289. tnsConvert44df(i, mf);
  290. if(tns->iProjectionInverse>-1) glUniformMatrix4fv(tns->iProjectionInverse, 1, 0, mf);
  291. }
  292. void tnsShaderApplyModel(tnsShader *tns, tnsMatrix44d m){
  293. tnsMatrix44f mf;
  294. if (T->BindedShader != tns){ glUseProgram(tns->glProgramID); T->BindedShader = tns; }
  295. tnsConvert44df(m, mf);
  296. if(tns->iModel>-1) glUniformMatrix4fv(tns->iModel, 1, 0, mf);
  297. }
  298. void tnsShaderApplyView(tnsShader *tns, tnsMatrix44d m){
  299. tnsMatrix44f mf;
  300. if (T->BindedShader != tns){ glUseProgram(tns->glProgramID); T->BindedShader = tns; }
  301. tnsConvert44df(m, mf);
  302. if(tns->iView>-1) glUniformMatrix4fv(tns->iView, 1, 0, mf);
  303. }
  304. void tnsShaderApplyNormalScaler(tnsShader *tns, tnsMatrix44d m){
  305. tnsMatrix44f mf;
  306. if (tns->iNormal == -1) return;
  307. if (T->BindedShader != tns){ glUseProgram(tns->glProgramID); T->BindedShader = tns; }
  308. tnsConvert44df(m, mf);
  309. glUniformMatrix4fv(tns->iNormal, 1, 0, mf);
  310. }
  311. void tnsShaderApplyShadowMatrix(tnsShader *tns, tnsMatrix44d m){
  312. tnsMatrix44f mf;
  313. if (tns->iShadow == -1) return;
  314. if (T->BindedShader != tns){ glUseProgram(tns->glProgramID); T->BindedShader = tns; }
  315. tnsConvert44df(m, mf);
  316. glUniformMatrix4fv(tns->iShadow, 1, 0, mf);
  317. }
  318. char* tnsEnsureShaderCommoms(char* Content, char* Library, char* Material){
  319. char* c=0,*c1=0;
  320. c1=strSub(Content,"#with TNS_SHADER_COLOR_COMMON",TNS_SHADER_COLOR_COMMON);
  321. c=strSub(c1,"#with LA_SHADER_LIB_FXAA",LA_SHADER_LIB_FXAA); free(c1);
  322. c1=strSub(c,"#with TNS_SHADER_MATERIAL",Material?Material:""); free(c);
  323. c=strSub(c1,"#with TNS_SHADER_LIBRARY",Library?Library:""); free(c1);
  324. return c;
  325. }
  326. int tnsNewVertexShader(char *Content){
  327. int status = 0;
  328. char error[8192]={0};
  329. GLuint VertexShaderObject;
  330. tnsShader *s = 0;
  331. if (!Content) return -1;
  332. VertexShaderObject = glCreateShader(GL_VERTEX_SHADER);
  333. char* UseContent=tnsEnsureShaderCommoms(Content,0,0);
  334. glShaderSource(VertexShaderObject, 1, &UseContent, 0);
  335. glCompileShader(VertexShaderObject);
  336. glGetShaderiv(VertexShaderObject, GL_COMPILE_STATUS, &status);
  337. if (status == GL_FALSE){
  338. glGetShaderInfoLog(VertexShaderObject, sizeof(error), 0, error);
  339. printf("Vertex shader error:\n%s", error);
  340. glDeleteShader(VertexShaderObject); free(UseContent);
  341. return -1;
  342. }
  343. free(UseContent);
  344. return VertexShaderObject;
  345. }
  346. int tnsNewFragmentShaderMaterial(char *Content, char* Library, char* Material){
  347. int status = 0;
  348. char error[8192]={0};
  349. GLuint FragmentShaderObject;
  350. tnsShader *s = 0;
  351. if (!Content) return -1;
  352. FragmentShaderObject = glCreateShader(GL_FRAGMENT_SHADER);
  353. char* UseContent=tnsEnsureShaderCommoms(Content,Library,Material);
  354. glShaderSource(FragmentShaderObject, 1, &UseContent, 0);
  355. glCompileShader(FragmentShaderObject);
  356. glGetShaderiv(FragmentShaderObject, GL_COMPILE_STATUS, &status);
  357. if (status == GL_FALSE){
  358. glGetShaderInfoLog(FragmentShaderObject, sizeof(error), 0, error);
  359. printf("Fragment shader error:\n%s", error);
  360. glDeleteShader(FragmentShaderObject); free(UseContent);
  361. return -1;
  362. }
  363. free(UseContent);
  364. return FragmentShaderObject;
  365. }
  366. int tnsNewFragmentShader(char *Content){
  367. return tnsNewFragmentShaderMaterial(Content,0,0);
  368. }
  369. int tnsNewGeometryShader(char *Content){
  370. int status = 0;
  371. char error[8192]={0};
  372. GLuint GeometryShaderObject;
  373. tnsShader *s = 0;
  374. if (!Content) return -1;
  375. GeometryShaderObject = glCreateShader(GL_GEOMETRY_SHADER);
  376. char* UseContent=tnsEnsureShaderCommoms(Content,0,0);
  377. glShaderSource(GeometryShaderObject, 1, &UseContent, 0);
  378. glCompileShader(GeometryShaderObject);
  379. glGetShaderiv(GeometryShaderObject, GL_COMPILE_STATUS, &status);
  380. if (status == GL_FALSE){
  381. glGetShaderInfoLog(GeometryShaderObject, sizeof(error), 0, error);
  382. printf("Geometry shader error:\n%s", error);
  383. glDeleteShader(GeometryShaderObject); free(UseContent);
  384. return -1;
  385. }
  386. free(UseContent);
  387. return GeometryShaderObject;
  388. }
  389. tnsShader *tnsNewShaderProgram(int VertexShaderID, int FragmentShaderID, int GeometryShaderID){
  390. int vso = VertexShaderID;
  391. int fso = FragmentShaderID;
  392. int gso = GeometryShaderID;
  393. tnsShader *tns = 0;
  394. int status = 0;
  395. char error[8192];
  396. if (!vso || !fso) return 0;
  397. tns = CreateNew(tnsShader);
  398. tns->vtShaderID = vso;
  399. tns->fgShaderID = fso;
  400. tns->glProgramID = glCreateProgram();
  401. glAttachShader(tns->glProgramID, vso);
  402. glAttachShader(tns->glProgramID, fso);
  403. if (GeometryShaderID > -1){ glAttachShader(tns->glProgramID, gso); tns->gsShaderID=gso; }
  404. glLinkProgram(tns->glProgramID);
  405. glGetProgramiv(tns->glProgramID, GL_LINK_STATUS, &status);
  406. if (status == GL_FALSE){
  407. glGetProgramInfoLog(tns->glProgramID, sizeof(error), 0, error);
  408. printf("Shader Linking error:\n%s", error);
  409. glDetachShader(tns->glProgramID, vso);
  410. glDetachShader(tns->glProgramID, fso);
  411. glDeleteShader(vso);
  412. glDeleteShader(fso);
  413. glDeleteProgram(tns->glProgramID);
  414. FreeMem(tns);
  415. return 0;
  416. }
  417. glUseProgram(tns->glProgramID);
  418. tnsShaderMakeIndex(tns);
  419. return tns;
  420. }
  421. int tnsEnableShader(int index){
  422. tnsMatrixStackItem *tmsi;
  423. tnsShader *tns = tKnlFindShader1i(index);
  424. if (!tns){
  425. glUseProgram(0);
  426. T->CurrentShader = 0;
  427. T->BindedShader = 0;
  428. return 0;
  429. }
  430. glUseProgram(tns->glProgramID);
  431. T->CurrentShader = tns;
  432. T->BindedShader = tns;
  433. tmsi = tKnlGetCurrentMatStackItem();
  434. tnsShaderApplyProjection(tns, tmsi->projection);
  435. tnsShaderApplyView(tns, tmsi->view);
  436. tnsShaderApplyModel(tns, tmsi->model); tnsUseShader(tns);
  437. return 1;
  438. }
  439. int tnsEnableShaderv(tnsShader *shader){
  440. tnsMatrixStackItem *tmsi;
  441. tnsShader *s = shader;
  442. if (!s){ glUseProgram(0); T->CurrentShader = 0;T->BindedShader = 0; return 0; }
  443. glUseProgram(s->glProgramID);
  444. T->CurrentShader = s;
  445. T->BindedShader = s;
  446. tmsi = tKnlGetCurrentMatStackItem();
  447. tnsShaderApplyProjection(s, tmsi->projection);
  448. tnsShaderApplyProjectionInverse(s, tmsi->projection);
  449. tnsShaderApplyView(s, tmsi->view);
  450. tnsShaderApplyModel(s, tmsi->model); tnsUseShader(s);
  451. if(s->iUseNormal>-1) glUniform1i(s->iUseNormal,T->SetUseNormal);
  452. if(s->uViewPos>-1) glUniform3fv(s->uViewPos,1,T->SetViewPos);
  453. if(s->uViewDir>-1) glUniform3fv(s->uViewDir,1,T->SetViewDir);
  454. if(s->iUseHalftone>-1) glUniform1f(s->iUseHalftone,T->SetUseHalftone);
  455. if(s->iHalftoneSize>-1) glUniform1f(s->iHalftoneSize,T->SetHalftoneSize);
  456. //if(s->iTextureMode) glUniform1i(s->iTextureMode,T->StateTextureMode);
  457. //if(cs->iSampleAmount) glUniform1i(cs->iSampleAmount);
  458. return 1;
  459. }
  460. int tnsUseShader(tnsShader *shader){
  461. T->StateShader = shader;
  462. }
  463. void tnsDeleteShaderProgram(tnsShader* s){
  464. tnsUseShader(0); tnsEnableShaderv(0);
  465. if(s->vtShaderID>-1) glDeleteShader(s->vtShaderID);
  466. if(s->fgShaderID>-1) glDeleteShader(s->fgShaderID);
  467. if(s->gsShaderID>-1) glDeleteShader(s->gsShaderID);
  468. glDeleteProgram(s->glProgramID);
  469. free(s);
  470. }
  471. void tnsUseImmShader(){
  472. T->StateShader = T->immShader;
  473. }
  474. void tnsUseTransparentGridShader(){
  475. T->StateShader = T->TransparentGridShader;
  476. }
  477. void tnsUseExtraBufferShader(){
  478. T->StateShader = T->ExtraBuffersShader;
  479. }
  480. void tnsUseRayShader(){
  481. T->StateShader = T->RayShader;
  482. }
  483. void tnsUseShadowShader(){
  484. T->StateShader = T->ShadowShader;
  485. }
  486. void tnsUseSceneShader(){
  487. T->StateShader = T->SceneShader;
  488. }
  489. //=======================================[MAT]
  490. int tnsLineIntersectTest2d(tnsVector2d a1, tnsVector2d a2, tnsVector2d b1, tnsVector2d b2, double *aRatio){
  491. double k1, k2;
  492. double x;
  493. double y;
  494. double Ratio;
  495. double xDiff = (a2[0] - a1[0]); // +DBL_EPSILON;
  496. double xDiff2 = (b2[0] - b1[0]);
  497. if (xDiff == 0){
  498. if (xDiff2 == 0){
  499. *aRatio = 0;
  500. return 0;
  501. }
  502. double r2 = tnsGetRatiod(b1[0], b2[0], a1[0]);
  503. y = tnsLinearItp(b1[1], b2[1], r2);
  504. *aRatio = Ratio = tnsGetRatiod(a1[1], a2[1], y);
  505. }else{
  506. if (xDiff2 == 0){
  507. Ratio = tnsGetRatiod(a1[0], a2[0], b1[0]);
  508. //y = tnsLinearItp(a1[1], a2[1], r2);
  509. *aRatio = Ratio;
  510. }else{
  511. k1 = (a2[1] - a1[1]) / xDiff;
  512. k2 = (b2[1] - b1[1]) / xDiff2;
  513. if ((k1 == k2)) return 0;
  514. x = (a1[1] - b1[1] - k1 * a1[0] + k2 * b1[0]) / (k2 - k1);
  515. Ratio = (x - a1[0]) / xDiff;
  516. *aRatio = Ratio;
  517. }
  518. }
  519. if (b1[0] == b2[0]){
  520. y = tnsLinearItp(a1[1], a2[1], Ratio);
  521. if (y > TNS_MAX2(b1[1], b2[1]) || y < TNS_MIN2(b1[1], b2[1])) return 0;
  522. }else if (Ratio <= 0 || Ratio > 1 ||
  523. (b1[0] > b2[0] && x > b1[0]) ||
  524. (b1[0] < b2[0] && x < b1[0]) ||
  525. (b2[0] > b1[0] && x > b2[0]) ||
  526. (b2[0] < b1[0] && x < b2[0]))
  527. return 0;
  528. return 1;
  529. }
  530. double tnsGetLineZ(tnsVector3d L, tnsVector3d R, real Ratio){
  531. //double z = 1 / tnsLinearItp(1 / L[2], 1 / R[2], Ratio);
  532. double z = tnsLinearItp(L[2], R[2], Ratio);
  533. return z;
  534. }
  535. double tnsGetLineZPoint(tnsVector3d L, tnsVector3d R, tnsVector3d FromL){
  536. double r = (FromL[0] - L[0]) / (R[0] - L[0]);
  537. return tnsLinearItp(L[2], R[2], r);
  538. //return 1 / tnsLinearItp(1 / L[2], 1 / R[2], r);
  539. }
  540. double tnsGetRatio3d(tnsVector3d L, tnsVector3d R, tnsVector3d FromL){
  541. double r = (FromL[0] - L[0]) / (R[0] - L[0]);
  542. return r;
  543. }
  544. double tnsGetRatiod(real L, real R, real FromL){
  545. double r = (FromL - L) / (R - L);
  546. return r;
  547. }
  548. real tnsInterpolate(real L, real R, real T){
  549. return tnsLinearItp(L, R, T);
  550. }
  551. void tnsInterpolate2dv(real *L, real *R, real T, real *Result){
  552. Result[0] = tnsLinearItp(L[0], R[0], T);
  553. Result[1] = tnsLinearItp(L[1], R[1], T);
  554. }
  555. void tnsInterpolate3dv(real *L, real *R, real T, real *Result){
  556. Result[0] = tnsLinearItp(L[0], R[0], T);
  557. Result[1] = tnsLinearItp(L[1], R[1], T);
  558. Result[2] = tnsLinearItp(L[2], R[2], T);
  559. }
  560. void tnsInterpolateTripple2d(tnsVector2d v1, tnsVector2d v2, tnsVector2d v3, real ratio, tnsVector2d result){
  561. tnsVector2d i1,i2;
  562. tnsInterpolate2dv(v1,v2,ratio,i1);
  563. tnsInterpolate2dv(v2,v3,ratio,i2);
  564. tnsInterpolate2dv(i1,i2,ratio,result);
  565. }
  566. void tnsVectorMinus2d(tnsVector2d result, tnsVector2d l, tnsVector2d r){
  567. result[0] = l[0] - r[0];
  568. result[1] = l[1] - r[1];
  569. }
  570. void tnsVectorMinus3d(tnsVector3d result, tnsVector3d l, tnsVector3d r){
  571. result[0] = l[0] - r[0];
  572. result[1] = l[1] - r[1];
  573. result[2] = l[2] - r[2];
  574. }
  575. void tnsVectorSubtract3d(tnsVector3d l, tnsVector3d r){
  576. l[0] = l[0] - r[0];
  577. l[1] = l[1] - r[1];
  578. l[2] = l[2] - r[2];
  579. }
  580. void tnsVectorPlus3d(tnsVector3d result, tnsVector3d l, tnsVector3d r){
  581. result[0] = l[0] + r[0];
  582. result[1] = l[1] + r[1];
  583. result[2] = l[2] + r[2];
  584. }
  585. void tnsVectorAccum3d(tnsVector3d l, tnsVector3d r){
  586. l[0] = l[0] + r[0];
  587. l[1] = l[1] + r[1];
  588. l[2] = l[2] + r[2];
  589. }
  590. void tnsVectorAccum2d(tnsVector2d l, tnsVector2d r){
  591. l[0] = l[0] + r[0];
  592. l[1] = l[1] + r[1];
  593. }
  594. void tnsVectorNegate3d(tnsVector3d result, tnsVector3d l){
  595. result[0] = -l[0];
  596. result[1] = -l[1];
  597. result[2] = -l[2];
  598. }
  599. void tnsVectorNegateSelf3d(tnsVector3d l){
  600. l[0] = -l[0];
  601. l[1] = -l[1];
  602. l[2] = -l[2];
  603. }
  604. void tnsVectorCopy2d(tnsVector2d from, tnsVector2d to){
  605. to[0] = from[0];
  606. to[1] = from[1];
  607. }
  608. void tnsVectorCopy3d(tnsVector3d from, tnsVector3d to){
  609. to[0] = from[0];
  610. to[1] = from[1];
  611. to[2] = from[2];
  612. }
  613. void tnsVectorCopy4d(tnsVector4d from, tnsVector4d to){
  614. to[0] = from[0];
  615. to[1] = from[1];
  616. to[2] = from[2];
  617. to[3] = from[3];
  618. }
  619. void tnsVectorMultiSelf4d(tnsVector4d from, real num){
  620. from[0] *= num;
  621. from[1] *= num;
  622. from[2] *= num;
  623. from[3] *= num;
  624. }
  625. void tnsVectorMultiSelf3d(tnsVector3d from, real num){
  626. from[0] *= num;
  627. from[1] *= num;
  628. from[2] *= num;
  629. }
  630. void tnsVectorMultiSelf2d(tnsVector2d from, real num){
  631. from[0] *= num;
  632. from[1] *= num;
  633. }
  634. void tnsVectorMulti4d(tnsVector4d to, tnsVector4d from, real num){
  635. to[0]=from[0]*num;
  636. to[1]=from[1]*num;
  637. to[2]=from[2]*num;
  638. to[3]=from[3]*num;
  639. }
  640. void tnsVectorMulti3d(tnsVector3d to, tnsVector3d from, real num){
  641. to[0]=from[0]*num;
  642. to[1]=from[1]*num;
  643. to[2]=from[2]*num;
  644. }
  645. void tnsVectorMulti2d(tnsVector2d to, tnsVector2d from, real num){
  646. to[0]=from[0]*num;
  647. to[1]=from[1]*num;
  648. }
  649. real tnsDirectionToRad(tnsVector2d Dir){
  650. real arcc = acos(Dir[0]);
  651. real arcs = asin(Dir[1]);
  652. if (Dir[0] >= 0){
  653. if (Dir[1] >= 0) return arcc;
  654. else
  655. return TNS_PI * 2 - arcc;
  656. }else{
  657. if (Dir[1] >= 0) return arcs + TNS_PI / 2;
  658. else
  659. return TNS_PI + arcs;
  660. }
  661. }
  662. void tnsConvert44df(tnsMatrix44d from, tnsMatrix44f to){
  663. to[0] = from[0];
  664. to[1] = from[1];
  665. to[2] = from[2];
  666. to[3] = from[3];
  667. to[4] = from[4];
  668. to[5] = from[5];
  669. to[6] = from[6];
  670. to[7] = from[7];
  671. to[8] = from[8];
  672. to[9] = from[9];
  673. to[10] = from[10];
  674. to[11] = from[11];
  675. to[12] = from[12];
  676. to[13] = from[13];
  677. to[14] = from[14];
  678. to[15] = from[15];
  679. }
  680. void tnsLoadIdentity44d(tnsMatrix44d m){
  681. memset(m, 0, sizeof(tnsMatrix44d));
  682. m[0] = 1.0f;
  683. m[5] = 1.0f;
  684. m[10] = 1.0f;
  685. m[15] = 1.0f;
  686. };
  687. real tnsDistIdv2(real x1, real y1, real x2, real y2){
  688. real x = x2 - x1, y = y2 - y1;
  689. return sqrt((x * x + y * y));
  690. }
  691. real tnsDist3dv(tnsVector3d l, tnsVector3d r){
  692. real x = r[0] - l[0];
  693. real y = r[1] - l[1];
  694. real z = r[2] - l[2];
  695. return sqrt(x * x + y * y + z * z);
  696. }
  697. real tnsDist2dv(tnsVector2d l, tnsVector2d r){
  698. real x = r[0] - l[0];
  699. real y = r[1] - l[1];
  700. return sqrt(x * x + y * y);
  701. }
  702. real tnsLength3d(tnsVector3d l){
  703. return (sqrt(l[0] * l[0] + l[1] * l[1] + l[2] * l[2]));
  704. }
  705. real tnsLength2d(tnsVector3d l){
  706. return (sqrt(l[0] * l[0] + l[1] * l[1]));
  707. }
  708. void tnsNormalize3d(tnsVector3d result, tnsVector3d l){
  709. real r = sqrt(l[0] * l[0] + l[1] * l[1] + l[2] * l[2]);
  710. result[0] = l[0] / r;
  711. result[1] = l[1] / r;
  712. result[2] = l[2] / r;
  713. }
  714. void tnsNormalize2d(tnsVector2d result, tnsVector2d l){
  715. real r = sqrt(l[0] * l[0] + l[1] * l[1]);
  716. result[0] = l[0] / r;
  717. result[1] = l[1] / r;
  718. }
  719. void tnsNormalizeSelf2d(tnsVector3d result){
  720. real r = sqrt(result[0] * result[0] + result[1] * result[1]);
  721. result[0] /= r;
  722. result[1] /= r;
  723. }
  724. void tnsNormalizeSelf3d(tnsVector3d result){
  725. real r = sqrt(result[0] * result[0] + result[1] * result[1] + result[2] * result[2]);
  726. result[0] /= r;
  727. result[1] /= r;
  728. result[2] /= r;
  729. }
  730. real tnsDot3d(tnsVector3d l, tnsVector3d r, int normalize){
  731. tnsVector3d ln, rn;
  732. if (normalize){
  733. tnsNormalize3d(ln, l);
  734. tnsNormalize3d(rn, r);
  735. return (ln[0] * rn[0] + ln[1] * rn[1] + ln[2] * rn[2]);
  736. }
  737. return (l[0] * r[0] + l[1] * r[1] + l[2] * r[2]);
  738. }
  739. real tnsDot2d(tnsVector2d l, tnsVector2d r, int normalize){
  740. tnsVector3d ln, rn;
  741. if (normalize){
  742. tnsNormalize2d(ln, l);
  743. tnsNormalize2d(rn, r);
  744. return (ln[0] * rn[0] + ln[1] * rn[1]);
  745. }
  746. return (l[0] * r[0] + l[1] * r[1]);
  747. }
  748. real tnsVectorCross3d(tnsVector3d result, tnsVector3d l, tnsVector3d r){
  749. result[0] = l[1] * r[2] - l[2] * r[1];
  750. result[1] = l[2] * r[0] - l[0] * r[2];
  751. result[2] = l[0] * r[1] - l[1] * r[0];
  752. return tnsLength3d(result);
  753. }
  754. void tnsVectorCrossOnly3d(tnsVector3d result, tnsVector3d l, tnsVector3d r){
  755. result[0] = l[1] * r[2] - l[2] * r[1];
  756. result[1] = l[2] * r[0] - l[0] * r[2];
  757. result[2] = l[0] * r[1] - l[1] * r[0];
  758. }
  759. real tnsAngleRad3d(tnsVector3d from, tnsVector3d to, tnsVector3d PositiveReference){
  760. if (PositiveReference){
  761. tnsVector3d res;
  762. tnsVectorCross3d(res, from, to);
  763. if (tnsDot3d(res, PositiveReference, 1) > 0) return acosf(tnsDot3d(from, to, 1));
  764. else
  765. return -acosf(tnsDot3d(from, to, 1));
  766. }
  767. return acosf(tnsDot3d(from, to, 1));
  768. }
  769. void tnsApplyRotation33d(tnsVector3d result, tnsMatrix44d mat, tnsVector3d v){
  770. result[0] = mat[0] * v[0] + mat[1] * v[1] + mat[2] * v[2];
  771. result[1] = mat[3] * v[0] + mat[4] * v[1] + mat[5] * v[2];
  772. result[2] = mat[6] * v[0] + mat[7] * v[1] + mat[8] * v[2];
  773. }
  774. void tnsApplyRotation43d(tnsVector3d result, tnsMatrix44d mat, tnsVector3d v){
  775. result[0] = mat[0] * v[0] + mat[1] * v[1] + mat[2] * v[2];
  776. result[1] = mat[4] * v[0] + mat[5] * v[1] + mat[6] * v[2];
  777. result[2] = mat[8] * v[0] + mat[9] * v[1] + mat[10] * v[2];
  778. }
  779. void tnsApplyTransform43d(tnsVector3d result, tnsMatrix44d mat, tnsVector3d v){
  780. real w;
  781. result[0] = mat[0] * v[0] + mat[4] * v[1] + mat[8] * v[2] + mat[12] * 1;
  782. result[1] = mat[1] * v[0] + mat[5] * v[1] + mat[9] * v[2] + mat[13] * 1;
  783. result[2] = mat[2] * v[0] + mat[6] * v[1] + mat[10] * v[2] + mat[14] * 1;
  784. w = mat[3] * v[0] + mat[7] * v[1] + mat[11] * v[2] + mat[15] * 1;
  785. //result[0] /= w;
  786. //result[1] /= w;
  787. //result[2] /= w;
  788. }
  789. void tnsApplyNormalTransform43d(tnsVector3d result, tnsMatrix44d mat, tnsVector3d v){
  790. real w;
  791. result[0] = mat[0] * v[0] + mat[4] * v[1] + mat[8] * v[2] + mat[12] * 1;
  792. result[1] = mat[1] * v[0] + mat[5] * v[1] + mat[9] * v[2] + mat[13] * 1;
  793. result[2] = mat[2] * v[0] + mat[6] * v[1] + mat[10] * v[2] + mat[14] * 1;
  794. }
  795. void tnsApplyTransform44d(tnsVector4d result, tnsMatrix44d mat, tnsVector4d v){
  796. result[0] = mat[0] * v[0] + mat[4] * v[1] + mat[8] * v[2] + mat[12] * 1;
  797. result[1] = mat[1] * v[0] + mat[5] * v[1] + mat[9] * v[2] + mat[13] * 1;
  798. result[2] = mat[2] * v[0] + mat[6] * v[1] + mat[10] * v[2] + mat[14] * 1;
  799. result[3] = mat[3] * v[0] + mat[7] * v[1] + mat[11] * v[2] + mat[15] * 1;
  800. }
  801. void tnsApplyTransform44dTrue(tnsVector4d result, tnsMatrix44d mat, tnsVector4d v){
  802. result[0] = mat[0] * v[0] + mat[4] * v[1] + mat[8] * v[2] + mat[12] * v[3];
  803. result[1] = mat[1] * v[0] + mat[5] * v[1] + mat[9] * v[2] + mat[13] * v[3];
  804. result[2] = mat[2] * v[0] + mat[6] * v[1] + mat[10] * v[2] + mat[14] * v[3];
  805. result[3] = mat[3] * v[0] + mat[7] * v[1] + mat[11] * v[2] + mat[15] * v[3];
  806. }
  807. void tnsRemoveTranslation44d(tnsMatrix44d result, tnsMatrix44d mat){
  808. tnsLoadIdentity44d(result);
  809. result[0] = mat[0];
  810. result[1] = mat[1];
  811. result[2] = mat[2];
  812. result[4] = mat[4];
  813. result[5] = mat[5];
  814. result[6] = mat[6];
  815. result[8] = mat[8];
  816. result[9] = mat[9];
  817. result[10] = mat[10];
  818. }
  819. void tnsClearTranslation44d(tnsMatrix44d mat){
  820. mat[3] = 0;
  821. mat[7] = 0;
  822. mat[11] = 0;
  823. }
  824. void tnsCopyMatrix44d(tnsMatrix44d from, tnsMatrix44d to);
  825. void tnsExtractXYZEuler44d(tnsMatrix44d _mat, real *xyz_result){
  826. real xRot, yRot, zRot;
  827. tnsMatrix44d mat; tnsCopyMatrix44d(_mat,mat);
  828. tnsNormalizeSelf3d(&mat[0]);
  829. tnsNormalizeSelf3d(&mat[4]);
  830. tnsNormalizeSelf3d(&mat[8]);
  831. if (mat[2] < 1){
  832. if (mat[2] > -1){
  833. yRot = asin(mat[2]);
  834. xRot = atan2(-mat[6], mat[10]);
  835. zRot = atan2(-mat[1], mat[0]);
  836. }else{
  837. yRot = -TNS_PI / 2;
  838. xRot = -atan2(-mat[4], mat[5]);
  839. zRot = 0;
  840. }
  841. }else{
  842. yRot = TNS_PI / 2;
  843. xRot = atan2(-mat[4], mat[5]);
  844. zRot = 0;
  845. }
  846. xyz_result[0] = -xRot;
  847. xyz_result[1] = -yRot;
  848. xyz_result[2] = -zRot;
  849. }
  850. void tnsExtractLocation44d(tnsMatrix44d mat, real *xyz_result){
  851. xyz_result[0] = mat[12];
  852. xyz_result[1] = mat[13];
  853. xyz_result[2] = mat[14];
  854. }
  855. void tnsExtractScale44d(tnsMatrix44d mat, real *xyz_result){
  856. xyz_result[0] = tnsLength3d(&mat[0]);
  857. xyz_result[1] = tnsLength3d(&mat[4]);
  858. xyz_result[2] = tnsLength3d(&mat[8]);
  859. }
  860. #define L(row, col) l[(col << 2) + row]
  861. #define R(row, col) r[(col << 2) + row]
  862. #define P(row, col) result[(col << 2) + row]
  863. void tnsPrintMatrix44d(tnsMatrix44d l){
  864. int i, j;
  865. for (i = 0; i < 4; i++){
  866. for (j = 0; j < 4; j++){
  867. printf("%.5f ", L(i, j));
  868. }
  869. printf("\n");
  870. }
  871. }
  872. void tnsCopyMatrix44d(tnsMatrix44d from, tnsMatrix44d to){
  873. memcpy(to, from, sizeof(tnsMatrix44d));
  874. }
  875. void tnsMultiply44d(tnsMatrix44d result, tnsMatrix44d l, tnsMatrix44d r){
  876. int i;
  877. for (i = 0; i < 4; i++){
  878. real ai0 = L(i, 0), ai1 = L(i, 1), ai2 = L(i, 2), ai3 = L(i, 3);
  879. P(i, 0) = ai0 * R(0, 0) + ai1 * R(1, 0) + ai2 * R(2, 0) + ai3 * R(3, 0);
  880. P(i, 1) = ai0 * R(0, 1) + ai1 * R(1, 1) + ai2 * R(2, 1) + ai3 * R(3, 1);
  881. P(i, 2) = ai0 * R(0, 2) + ai1 * R(1, 2) + ai2 * R(2, 2) + ai3 * R(3, 2);
  882. P(i, 3) = ai0 * R(0, 3) + ai1 * R(1, 3) + ai2 * R(2, 3) + ai3 * R(3, 3);
  883. }
  884. };
  885. void tnsInverse44d(tnsMatrix44d inverse, tnsMatrix44d mat){
  886. int i, j, k;
  887. double temp;
  888. tnsMatrix44d tempmat;
  889. real max;
  890. int maxj;
  891. tnsLoadIdentity44d(inverse);
  892. tnsCopyMatrix44d(mat, tempmat);
  893. for (i = 0; i < 4; i++){
  894. /* Look for row with max pivot */
  895. max = fabsf(tempmat[i * 5]);
  896. maxj = i;
  897. for (j = i + 1; j < 4; j++){
  898. if (fabsf(tempmat[j * 4 + i]) > max){
  899. max = fabsf(tempmat[j * 4 + i]);
  900. maxj = j;
  901. }
  902. }
  903. /* Swap rows if necessary */
  904. if (maxj != i){
  905. for (k = 0; k < 4; k++){
  906. real t;
  907. t = tempmat[i * 4 + k];
  908. tempmat[i * 4 + k] = tempmat[maxj * 4 + k];
  909. tempmat[maxj * 4 + k] = t;
  910. t = inverse[i * 4 + k];
  911. inverse[i * 4 + k] = inverse[maxj * 4 + k];
  912. inverse[maxj * 4 + k] = t;
  913. }
  914. }
  915. //if (UNLIKELY(tempmat[i][i] == 0.0f)) {
  916. // return false; /* No non-zero pivot */
  917. //}
  918. temp = (double)tempmat[i * 5];
  919. for (k = 0; k < 4; k++){
  920. tempmat[i * 4 + k] = (real)((double)tempmat[i * 4 + k] / temp);
  921. inverse[i * 4 + k] = (real)((double)inverse[i * 4 + k] / temp);
  922. }
  923. for (j = 0; j < 4; j++){
  924. if (j != i){
  925. temp = tempmat[j * 4 + i];
  926. for (k = 0; k < 4; k++){
  927. tempmat[j * 4 + k] -= (real)((double)tempmat[i * 4 + k] * temp);
  928. inverse[j * 4 + k] -= (real)((double)inverse[i * 4 + k] * temp);
  929. }
  930. }
  931. }
  932. }
  933. }
  934. void tnsMakeTranslationMatrix44d(tnsMatrix44d mTrans, real x, real y, real z){
  935. tnsLoadIdentity44d(mTrans);
  936. mTrans[12] = x;
  937. mTrans[13] = y;
  938. mTrans[14] = z;
  939. }
  940. void tnsMakePerspectiveMatrix44d(tnsMatrix44d mProjection, real fFov_rad, real fAspect, real zMin, real zMax){
  941. real yMax = zMin * tanf(fFov_rad * 0.5f);
  942. real yMin = -yMax;
  943. real xMin = yMin * fAspect;
  944. real xMax = -xMin;
  945. tnsLoadIdentity44d(mProjection);
  946. mProjection[0] = (2.0f * zMin) / (xMax - xMin);
  947. mProjection[5] = (2.0f * zMin) / (yMax - yMin);
  948. mProjection[8] = (xMax + xMin) / (xMax - xMin);
  949. mProjection[9] = (yMax + yMin) / (yMax - yMin);
  950. mProjection[10] = -((zMax + zMin) / (zMax - zMin));
  951. mProjection[11] = -1.0f;
  952. mProjection[14] = -((2.0f * (zMax * zMin)) / (zMax - zMin));
  953. mProjection[15] = 0.0f;
  954. }
  955. void tnsMakeZTrackingMatrix44d(tnsMatrix44d mat, tnsVector3d this, tnsVector3d that, tnsVector3d up){
  956. tnsVector4d fwd, l, t, rt;
  957. fwd[3] = l[3] = t[3] = rt[3] = 1;
  958. t[0] = up[0];
  959. t[1] = up[1];
  960. t[2] = up[2];
  961. fwd[0] = that[0] - this[0];
  962. fwd[1] = that[1] - this[1];
  963. fwd[2] = that[2] - this[2];
  964. tnsNormalizeSelf3d(fwd);
  965. tnsVectorCross3d(l, fwd, t);
  966. tnsNormalizeSelf3d(l);
  967. tnsVectorCross3d(rt, l, fwd);
  968. tnsNormalizeSelf3d(rt);
  969. tnsLoadIdentity44d(mat);
  970. mat[0] = l[0];
  971. mat[1] = l[1];
  972. mat[2] = l[2];
  973. mat[4] = rt[0];
  974. mat[5] = rt[1];
  975. mat[6] = rt[2];
  976. mat[8] = -fwd[0];
  977. mat[9] = -fwd[1];
  978. mat[10] = -fwd[2];
  979. }
  980. void tnsMakeZTrackingMatrixDelta44d(tnsMatrix44d mat, tnsVector3d delta, tnsVector3d up){
  981. tnsVector4d fwd, l, t, rt;
  982. fwd[3] = l[3] = t[3] = rt[3] = 1;
  983. t[0] = up[0];
  984. t[1] = up[1];
  985. t[2] = up[2];
  986. fwd[0] = delta[0];
  987. fwd[1] = delta[1];
  988. fwd[2] = delta[2];
  989. tnsLoadIdentity44d(mat);
  990. tnsVectorCross3d(l, t, fwd);
  991. tnsVectorCross3d(rt, fwd, l);
  992. tnsNormalizeSelf3d(l);
  993. tnsNormalizeSelf3d(rt);
  994. tnsNormalizeSelf3d(fwd);
  995. mat[0] = l[0];
  996. mat[1] = l[1];
  997. mat[2] = l[2];
  998. mat[4] = rt[0];
  999. mat[5] = rt[1];
  1000. mat[6] = rt[2];
  1001. mat[8] = fwd[0];
  1002. mat[9] = fwd[1];
  1003. mat[10] = fwd[2];
  1004. }
  1005. void tnsMakeOrthoMatrix44d(tnsMatrix44d mProjection, real xMin, real xMax, real yMin, real yMax, real zMin, real zMax){
  1006. tnsLoadIdentity44d(mProjection);
  1007. mProjection[0] = 2.0f / (xMax - xMin);
  1008. mProjection[5] = 2.0f / (yMax - yMin);
  1009. mProjection[10] = -2.0f / (zMax - zMin);
  1010. mProjection[12] = -((xMax + xMin) / (xMax - xMin));
  1011. mProjection[13] = -((yMax + yMin) / (yMax - yMin));
  1012. mProjection[14] = -((zMax + zMin) / (zMax - zMin));
  1013. mProjection[15] = 1.0f;
  1014. }
  1015. void tnsMakeRotationMatrix44d(tnsMatrix44d m, real angle_rad, real x_, real y_, real z_){
  1016. float x = x_;
  1017. float y = y_;
  1018. float z = z_;
  1019. float c = cos(angle_rad);
  1020. float s = sin(angle_rad);
  1021. tnsMatrix44d d={
  1022. x*x*(1.0f-c)+c, x*y*(1.0f-c)-z*s, x*z*(1.0f-c)+y*s, 0.0f,
  1023. y*x*(1.0f-c)+z*s, y*y*(1.0f-c)+c, y*z*(1.0f-c)-x*s, 0.0f,
  1024. z*x*(1.0f-c)-y*s, z*y*(1.0f-c)+x*s, z*z*(1.0f-c)+c, 0.0f,
  1025. 0.0f, 0.0f, 0.0f, 1.0f };
  1026. memcpy(m,d,sizeof(tnsMatrix44d));
  1027. }
  1028. void tnsMakeRotationXMatrix44d(tnsMatrix44d m, real angle_rad){
  1029. tnsLoadIdentity44d(m);
  1030. m[5] = cos(angle_rad);
  1031. m[6] = sin(angle_rad);
  1032. m[9] = -sin(angle_rad);
  1033. m[10] = cos(angle_rad);
  1034. }
  1035. void tnsMakeRotationYMatrix44d(tnsMatrix44d m, real angle_rad){
  1036. tnsLoadIdentity44d(m);
  1037. m[0] = cos(angle_rad);
  1038. m[2] = -sin(angle_rad);
  1039. m[8] = sin(angle_rad);
  1040. m[10] = cos(angle_rad);
  1041. }
  1042. void tnsMakeRotationZMatrix44d(tnsMatrix44d m, real angle_rad){
  1043. tnsLoadIdentity44d(m);
  1044. m[0] = cos(angle_rad);
  1045. m[1] = sin(angle_rad);
  1046. m[4] = -sin(angle_rad);
  1047. m[5] = cos(angle_rad);
  1048. }
  1049. void tnsMakeScaleMatrix44d(tnsMatrix44d m, real x, real y, real z){
  1050. tnsLoadIdentity44d(m);
  1051. m[0] = x; m[5] = y; m[10] = z;
  1052. }
  1053. void tnsMakeViewportMatrix44d(tnsMatrix44d m, real w, real h, real Far, real Near){
  1054. tnsLoadIdentity44d(m);
  1055. m[0] = w / 2;
  1056. m[5] = h / 2;
  1057. m[10] = (Far - Near) / 2;
  1058. m[12] = w / 2;
  1059. m[13] = h / 2;
  1060. m[14] = (Far + Near) / 2;
  1061. m[15] = 1;
  1062. //m[0] = 2/w;
  1063. //m[5] = 2/h;
  1064. //m[10] = 1;
  1065. //m[12] = 2/w;
  1066. //m[13] = 2/h;
  1067. //m[14] = 1;
  1068. //m[15] = 1;
  1069. }
  1070. int tnsIntersectPlaneRay(tnsVector3d n, tnsVector3d p0, tnsVector3d l0, tnsVector3d l, real* t){
  1071. float denom = tnsDot3d(n, l, 0);
  1072. if (denom > 1e-6){
  1073. tnsVector3d p0l0; tnsVectorMinus3d(p0l0,p0 ,l0);
  1074. (*t) = tnsDot3d(p0l0, n, 0) / denom;
  1075. return ((*t) >= 0);
  1076. }
  1077. return 0;
  1078. }
  1079. void tnsInitFirstLevel(tnsMatrixStack *tms){
  1080. tnsLoadIdentity44d(tms->level[0].model);
  1081. tnsLoadIdentity44d(tms->level[0].projection);
  1082. tnsLoadIdentity44d(tms->level[0].view);
  1083. }
  1084. //-------------------Export
  1085. void tnsOrtho(real xMin, real xMax, real yMin, real yMax, real zMin, real zMax){
  1086. tnsShader *current_shader = 0;
  1087. real *mat = tnsGetProjectionMatrix();
  1088. T->vol=xMin; T->vor=xMax; T->vou=yMax; T->vob=yMin;
  1089. tnsMakeOrthoMatrix44d(mat, xMin, xMax, yMin, yMax, zMin, zMax);
  1090. if (current_shader = T->CurrentShader){
  1091. tnsShaderApplyProjection(current_shader, mat);
  1092. }
  1093. }
  1094. void tnsPerspective(real fFov_rad, real fAspect, real zMin, real zMax){
  1095. tnsShader *current_shader = 0;
  1096. real *mat = tnsGetProjectionMatrix();
  1097. tnsMakePerspectiveMatrix44d(mat, fFov_rad, fAspect, zMin, zMax);
  1098. if (current_shader = T->CurrentShader){
  1099. tnsShaderApplyProjection(current_shader, mat);
  1100. }
  1101. }
  1102. void tnsTranslate3d(real x, real y, real z){
  1103. tnsShader *current_shader = 0;
  1104. real *mat = tnsGetModelMatrix();
  1105. tnsMatrix44d transmat, result;
  1106. tnsMakeTranslationMatrix44d(transmat, x, y, z);
  1107. tnsMultiply44d(result, mat, transmat);
  1108. memcpy(mat, result, sizeof(tnsMatrix44d));
  1109. if (current_shader = T->CurrentShader){
  1110. tnsShaderApplyModel(current_shader, result);
  1111. }
  1112. }
  1113. void tnsPreTranslate3d(real x, real y, real z){
  1114. tnsShader *current_shader = 0;
  1115. real *mat = tnsGetModelMatrix();
  1116. tnsMatrix44d transmat, result;
  1117. //glTranslatef(x, y, z);
  1118. tnsMakeTranslationMatrix44d(transmat, x, y, z);
  1119. tnsMultiply44d(result, mat, transmat);
  1120. memcpy(mat, result, sizeof(tnsMatrix44d));
  1121. }
  1122. void tnsRotate4d(real degrees, real x, real y, real z){
  1123. tnsShader *current_shader = 0;
  1124. real *mat = tnsGetModelMatrix();
  1125. tnsMatrix44d rotmat, result;
  1126. tnsMakeRotationMatrix44d(rotmat, rad(degrees), x, y, z);
  1127. tnsMultiply44d(result, mat, rotmat);
  1128. memcpy(mat, result, sizeof(tnsMatrix44d));
  1129. if (current_shader = T->CurrentShader){
  1130. tnsShaderApplyModel(current_shader, result);
  1131. }
  1132. }
  1133. void tnsPreRotate4d(real degrees, real x, real y, real z){
  1134. tnsShader *current_shader = 0;
  1135. real *mat = tnsGetModelMatrix();
  1136. tnsMatrix44d rotmat, result;
  1137. tnsMakeRotationMatrix44d(rotmat, rad(degrees), x, y, z);
  1138. tnsMultiply44d(result, mat, rotmat);
  1139. memcpy(mat, result, sizeof(tnsMatrix44d));
  1140. }
  1141. void tnsScale3d(real x, real y, real z){
  1142. tnsShader *current_shader = 0;
  1143. real *mat = tnsGetModelMatrix();
  1144. tnsMatrix44d scalemat, normal_scaler, result;
  1145. glScalef(x, y, z);
  1146. tnsMakeScaleMatrix44d(scalemat, x, y, z);
  1147. tnsMultiply44d(result, mat, scalemat);
  1148. memcpy(mat, result, sizeof(tnsMatrix44d));
  1149. if (current_shader = T->CurrentShader){
  1150. tnsShaderApplyModel(current_shader, result);
  1151. }
  1152. }
  1153. void tnsPreScale3d(real x, real y, real z){
  1154. tnsShader *current_shader = 0;
  1155. real *mat = tnsGetModelMatrix();
  1156. tnsMatrix44d scalemat, normal_scaler, result;
  1157. glScalef(x, y, z);
  1158. tnsMakeScaleMatrix44d(scalemat, x, y, z);
  1159. tnsMultiply44d(result, mat, scalemat);
  1160. memcpy(mat, result, sizeof(tnsMatrix44d));
  1161. }
  1162. void tKnlPopMatrix();
  1163. void tKnlPushMatrix();
  1164. void tnsPushMatrix(){
  1165. tKnlPushMatrix();
  1166. };
  1167. void tnsPopMatrix(){
  1168. tKnlPopMatrix();
  1169. }
  1170. //========================================[KNL]
  1171. void tnsSetRayShaderUniformTextures(tnsOffscreen* doff){
  1172. if(!doff)return;
  1173. tnsActiveTexture(GL_TEXTURE0); glBindTexture(doff->pColor[0]->GLTexType, doff->pColor[0]->GLTexHandle);
  1174. tnsActiveTexture(GL_TEXTURE1); glBindTexture(doff->pColor[1]->GLTexType, doff->pColor[1]->GLTexHandle);
  1175. tnsActiveTexture(GL_TEXTURE2); glBindTexture(doff->pColor[2]->GLTexType, doff->pColor[2]->GLTexHandle);
  1176. glUniform1i(T->RayShader->iTexColor, 0); glUniform1i(T->RayShader->iTexNormal, 1); glUniform1i(T->RayShader->iTexGPos, 2);
  1177. }
  1178. void tnsInit(){
  1179. T = memAcquire(sizeof(tnsMain));
  1180. T->World=memAcquire(sizeof(tnsWorld));
  1181. }
  1182. void tnsInitRenderKernel(int matrixStackLevel){
  1183. tnsCommand *c;
  1184. GLuint m_nQuadVAO;
  1185. T->GLVersionStr = glGetString(GL_VERSION);
  1186. T->GLVendorStr = glGetString(GL_VENDOR);
  1187. T->GLRendererStr = glGetString(GL_RENDERER);
  1188. T->GLSLVersionStr = glGetString(GL_SHADING_LANGUAGE_VERSION);
  1189. T->stack.max_level = matrixStackLevel;
  1190. T->stack.level = CreateNewBuffer(tnsMatrixStackItem, matrixStackLevel);
  1191. T->NextShaderIndex = 1;
  1192. T->BindedShader = -1;
  1193. tnsInitFirstLevel(&T->stack);
  1194. T->StateLineWidth=T->SetLineWidth=1; T->StatePointSize=T->SetPointSize=1;
  1195. arrEnsureLength(&T->Vert, T->NextVert, &T->MaxVert, sizeof(GLfloat));
  1196. glGenBuffers(1, &T->VertBufObject);
  1197. glBindBuffer(GL_ARRAY_BUFFER, T->VertBufObject);
  1198. glBufferData(GL_ARRAY_BUFFER, T->MaxVert * sizeof(GLfloat), 0, GL_DYNAMIC_DRAW);
  1199. arrEnsureLength(&T->Color, T->NextColor, &T->MaxColor, sizeof(GLfloat));
  1200. glGenBuffers(1, &T->ColorBufObject);
  1201. glBindBuffer(GL_ARRAY_BUFFER, T->ColorBufObject);
  1202. glBufferData(GL_ARRAY_BUFFER, T->MaxColor * sizeof(GLfloat), 0, GL_DYNAMIC_DRAW);
  1203. arrEnsureLength(&T->Normal, T->NextNormal, &T->MaxNormal, sizeof(GLfloat));
  1204. glGenBuffers(1, &T->NormalBufObject);
  1205. glBindBuffer(GL_ARRAY_BUFFER, T->NormalBufObject);
  1206. glBufferData(GL_ARRAY_BUFFER, T->MaxNormal * sizeof(GLfloat), 0, GL_DYNAMIC_DRAW);
  1207. arrEnsureLength(&T->TexCoord, T->NextTexCoord, &T->MaxTexCoord, sizeof(GLfloat));
  1208. glGenBuffers(1, &T->TexCoordBufObject);
  1209. glBindBuffer(GL_ARRAY_BUFFER, T->TexCoordBufObject);
  1210. glBufferData(GL_ARRAY_BUFFER, T->MaxTexCoord * sizeof(GLfloat), 0, GL_DYNAMIC_DRAW);
  1211. arrEnsureLength(&T->Index, T->NextIndex, &T->MaxIndex, sizeof(GLuint));
  1212. glGenBuffers(1, &T->IndexBufObject);
  1213. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, T->IndexBufObject);
  1214. glBufferData(GL_ELEMENT_ARRAY_BUFFER, T->MaxIndex * sizeof(GLuint), 0, GL_DYNAMIC_DRAW);
  1215. arrEnsureLength(&T->DrawingCommand, T->NextCommand, &T->MaxCommand, sizeof(tnsCommand));
  1216. }
  1217. void tnsInitBuiltinShaders(){
  1218. T->immShader = tnsNewShaderProgram(
  1219. tnsNewVertexShader(LA_IMM_VERTEX_SHADER),tnsNewFragmentShader(LA_IMM_FRAGMENT_SHADER),-1);
  1220. T->TEST_MatcapShader = tnsNewShaderProgram(
  1221. tnsNewVertexShader(TNS_VERTEX_SIMPLE_MATCAP),
  1222. tnsNewFragmentShader(TNS_FRAGMENT_SIMPLE_MATCAP), -1);
  1223. T->TransparentGridShader = tnsNewShaderProgram(
  1224. tnsNewVertexShader(TNS_VERTEX_GRID),
  1225. tnsNewFragmentShader(TNS_FRAGMENT_TRANSPARNT_GRID), -1);
  1226. T->RayShader = tnsNewShaderProgram(
  1227. tnsNewVertexShader(LA_RAY_VERTEX_SHADER),
  1228. tnsNewFragmentShader(LA_RAY_FRAGMENT_SHADER), -1);
  1229. T->ShadowShader = tnsNewShaderProgram(
  1230. tnsNewVertexShader(LA_CASCADE_SHADOW_VERTEX_SHADER),
  1231. tnsNewFragmentShader(LA_CASCADE_SHADOW_FRAGMENT_SHADER), -1);
  1232. T->SceneShader = tnsNewShaderProgram(
  1233. tnsNewVertexShader(LA_SCENE_VERTEX_SHADER),
  1234. tnsNewFragmentShader(LA_SCENE_FRAGMENT_SHADER), -1);
  1235. T->SelectionShader = tnsNewShaderProgram(
  1236. tnsNewVertexShader(LA_SELECTION_VERTEX_SHADER),
  1237. tnsNewFragmentShader(LA_SELECTION_FRAGMENT_SHADER), -1);
  1238. T->FloorShader = tnsNewShaderProgram(
  1239. tnsNewVertexShader(LA_FLOOR_VERTEX_SHADER),
  1240. tnsNewFragmentShader(LA_FLOOR_FRAGMENT_SHADER), -1);
  1241. tnsUseShader(T->immShader);
  1242. tnsEnableShaderv(T->immShader);
  1243. }
  1244. void tnsInitWindowDefaultRenderConfig(){
  1245. tnsInitBuiltinShaders();
  1246. };
  1247. void tnsDeleteBuiltinShaders(){
  1248. tnsDeleteShaderProgram(T->immShader); T->immShader=0;
  1249. tnsDeleteShaderProgram(T->TEST_MatcapShader); T->TEST_MatcapShader=0;
  1250. tnsDeleteShaderProgram(T->TransparentGridShader); T->TransparentGridShader=0;
  1251. tnsDeleteShaderProgram(T->SelectionShader); T->SelectionShader=0;
  1252. tnsDeleteShaderProgram(T->FloorShader); T->FloorShader=0;
  1253. tnsDeleteShaderProgram(T->SceneShader); T->SceneShader=0;
  1254. tnsDeleteShaderProgram(T->ShadowShader); T->ShadowShader=0;
  1255. tnsDeleteShaderProgram(T->RayShader); T->RayShader=0;
  1256. }
  1257. void tnsQuitFontManager();
  1258. void tnsQuit(){
  1259. tnsQuitFontManager();
  1260. tnsObject*o;
  1261. while(o=lstPopItem(&T->World->AllObjects)){ tnsDestroyObject(o); }
  1262. while(o=lstPopItem(&T->World->RootObjects)){ tnsDestroyRootObject(o); }
  1263. //memFreeRemainingLeftNodes();
  1264. tnsDeleteBuiltinShaders();
  1265. tnsOffscreen* off; while(off=T->Offscreens.pFirst){ tnsDelete2DOffscreen(off); }
  1266. tnsTexture* t; while(t=T->Textures.pFirst){ tnsDeleteTexture(t); }
  1267. arrFree(&T->Vert, &T->MaxVert);
  1268. arrFree(&T->Color, &T->MaxColor);
  1269. arrFree(&T->Normal, &T->MaxNormal);
  1270. arrFree(&T->TexCoord, &T->MaxTexCoord);
  1271. arrFree(&T->Index, &T->MaxIndex);
  1272. arrFree(&T->DrawingCommand, &T->DrawingCommand);
  1273. glDeleteBuffers(1, &T->VertBufObject);
  1274. glDeleteBuffers(1, &T->ColorBufObject);
  1275. glDeleteBuffers(1, &T->NormalBufObject);
  1276. glDeleteBuffers(1, &T->TexCoordBufObject);
  1277. glDeleteBuffers(1, &T->IndexBufObject);
  1278. FreeMem(T->stack.level);
  1279. memFree(T->World);
  1280. memFree(T);
  1281. }
  1282. void tnsRestoreFromNanoVG(){
  1283. glBindVertexArray(T->CurrentVAO);
  1284. tnsUseImmShader(); tnsEnableShaderv(T->immShader);
  1285. glActiveTexture(GL_TEXTURE0);
  1286. glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,GL_ONE,GL_ONE_MINUS_SRC_ALPHA);
  1287. }
  1288. tnsMatrixStackItem *tKnlGetCurrentMatStackItem(){
  1289. return &T->stack.level[T->stack.current_level];
  1290. }
  1291. real *tnsGetModelMatrix(){
  1292. return tKnlGetCurrentMatStackItem()->model;
  1293. }
  1294. real *tnsGetViewMatrix(){
  1295. return tKnlGetCurrentMatStackItem()->view;
  1296. }
  1297. real *tnsGetProjectionMatrix(){
  1298. return tKnlGetCurrentMatStackItem()->projection;
  1299. }
  1300. void tnsGetMVMatrix(tnsMatrix44d r){
  1301. tnsMatrixStackItem *tmsi=tKnlGetCurrentMatStackItem();
  1302. tnsMatrix44d tmp;
  1303. tnsMultiply44d(r, tmsi->model, tmsi->view);
  1304. }
  1305. void tnsGetMVPMatrix(tnsMatrix44d r){
  1306. tnsMatrixStackItem *tmsi=tKnlGetCurrentMatStackItem();
  1307. tnsMatrix44d tmp;
  1308. tnsMultiply44d(tmp, tmsi->model, tmsi->view);
  1309. tnsMultiply44d(r, tmp, tmsi->projection);
  1310. }
  1311. void tnsResetModelMatrix(){
  1312. tnsLoadIdentity44d(tnsGetModelMatrix());
  1313. }
  1314. void tnsResetViewMatrix(){
  1315. tnsLoadIdentity44d(tnsGetViewMatrix());
  1316. }
  1317. void tnsResetProjectionMatrix(){
  1318. tnsLoadIdentity44d(tnsGetProjectionMatrix());
  1319. }
  1320. int tKnlAttatchShader(tnsShader *tns){
  1321. lstAppendItem(&T->Shaders, tns);
  1322. tns->CustomID = T->NextShaderIndex;
  1323. T->NextShaderIndex++;
  1324. return tns->CustomID;
  1325. };
  1326. int CMP_NUM_IsThisShader(tnsShader *tns, int *index){
  1327. return (tns->CustomID == *index);
  1328. }
  1329. tnsShader *tKnlFindShader1i(int CustomIndex){
  1330. return lstFindItem(&CustomIndex, CMP_NUM_IsThisShader, &T->Shaders);
  1331. }
  1332. void tKnlPushMatrix(){
  1333. tnsMatrixStack *tms = &T->stack;
  1334. tnsShader *current_shader = T->CurrentShader;
  1335. if (tms->current_level == tms->max_level || !current_shader) return;
  1336. memcpy(&tms->level[tms->current_level + 1], &tms->level[tms->current_level], sizeof(tnsMatrixStackItem));
  1337. tms->current_level++;
  1338. //tnsShaderApplyModel(current_shader,tms->level[tms->current_level].model);
  1339. //tnsShaderApplyView(current_shader,tms->level[tms->current_level].view);
  1340. //tnsShaderApplyProjection(current_shader,tms->level[tms->current_level].projection);
  1341. };
  1342. void tKnlPopMatrix(){
  1343. tnsMatrixStack *tms = &T->stack;
  1344. tnsShader *current_shader = T->CurrentShader;
  1345. if (tms->current_level == 0 || !current_shader) return;
  1346. tms->current_level--;
  1347. tnsShaderApplyModel(current_shader, tms->level[tms->current_level].model);
  1348. tnsShaderApplyView(current_shader, tms->level[tms->current_level].view);
  1349. tnsShaderApplyProjection(current_shader, tms->level[tms->current_level].projection);
  1350. }
  1351. laListHandle *tKnlGetTextureList(){
  1352. return &T->Textures;
  1353. }
  1354. tnsBatch *tnsCreateBatch(u32bit NumVert, int Dimension, float *Data, int NormalDimension, float *Normal, int ColorDimension, float *Colors){
  1355. tnsBatch *b = CreateNew(tnsBatch);
  1356. b->Dimension = Dimension;
  1357. b->NormalDimension=NormalDimension;
  1358. b->ColorDimension=ColorDimension;
  1359. b->NumVert = NumVert;
  1360. glGenBuffers(1, &b->VBO);
  1361. glBindBuffer(GL_ARRAY_BUFFER, b->VBO);
  1362. glBufferData(GL_ARRAY_BUFFER, NumVert * Dimension * sizeof(GLfloat), Data, GL_DYNAMIC_DRAW);
  1363. if (Normal){
  1364. glGenBuffers(1, &b->NBO); glBindBuffer(GL_ARRAY_BUFFER, b->NBO);
  1365. glBufferData(GL_ARRAY_BUFFER, NumVert * NormalDimension * sizeof(GLfloat), Normal, GL_DYNAMIC_DRAW);
  1366. b->HasNormal=1;
  1367. }
  1368. if (Colors){
  1369. glGenBuffers(1, &b->CBO); glBindBuffer(GL_ARRAY_BUFFER, b->CBO);
  1370. glBufferData(GL_ARRAY_BUFFER, NumVert * ColorDimension * sizeof(GLfloat), Colors, GL_DYNAMIC_DRAW);
  1371. b->HasColor=1;
  1372. }
  1373. return b;
  1374. }
  1375. tnsBatch *tnsCreateBatchi(u32bit NumVert, int Dimension, int *Data){
  1376. tnsBatch *b = CreateNew(tnsBatch);
  1377. b->Dimension = Dimension;
  1378. b->NumVert = NumVert;
  1379. glGenBuffers(1, &b->VBO);
  1380. glBindBuffer(GL_ARRAY_BUFFER, b->VBO);
  1381. glBufferData(GL_ARRAY_BUFFER, NumVert * Dimension * sizeof(GLuint), Data, GL_DYNAMIC_DRAW);
  1382. return b;
  1383. }
  1384. void tnsCommandUseUniformColor(tnsBatchCommand*c, real* color){
  1385. tnsVectorCopy4d(color, c->UniformColor);
  1386. c->UseUniformColor=1;
  1387. }
  1388. void tnsCommandUseMaterial(tnsBatchCommand*c, tnsMaterial* material){
  1389. c->Material=material;
  1390. }
  1391. void tnsCommandUseWidth(tnsBatchCommand*c, real width){
  1392. c->Width=width;
  1393. }
  1394. void tnsCommandOverrideColorArray(tnsBatchCommand*c, int VertCount, int ColorDimension, float* colors){
  1395. if(!colors) return;
  1396. c->OverrideColorArray=1;
  1397. glGenBuffers(1, &c->CBO); glBindBuffer(GL_ARRAY_BUFFER, c->CBO);
  1398. glBufferData(GL_ARRAY_BUFFER, VertCount* ColorDimension * sizeof(GLfloat), colors, GL_DYNAMIC_DRAW);
  1399. c->ColorDimension = ColorDimension;
  1400. }
  1401. tnsBatchCommand *tnsCreateCommand(tnsBatch *b, const char* name, u32bit ElementCount, int Dimension, GLenum DrawAs, u32bit *Elements, int HiddenByDefault){
  1402. tnsBatchCommand *bc = CreateNew(tnsBatchCommand);
  1403. bc->ElementCount = ElementCount;
  1404. bc->DrawAs = DrawAs;
  1405. bc->Dimension = Dimension;
  1406. bc->name=name;
  1407. bc->HiddenByDefault = HiddenByDefault;
  1408. if(Elements){
  1409. glGenBuffers(1, &bc->EBO); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bc->EBO);
  1410. glBufferData(GL_ELEMENT_ARRAY_BUFFER, ElementCount * Dimension * sizeof(GLuint), Elements, GL_DYNAMIC_DRAW);
  1411. bc->DrawElements=1;
  1412. }else{ bc->EBO=-1; }
  1413. //int a = GetLastError();
  1414. lstAppendItem(&b->Branches, bc);
  1415. return bc;
  1416. }
  1417. void tnsDeleteBatch(tnsBatch *b){
  1418. tnsBatchCommand *bc, *NextBc;
  1419. glDeleteBuffers(1, &b->VBO);
  1420. if (b->NBO > -1) glDeleteBuffers(1, &b->NBO);
  1421. if (b->CBO > -1) glDeleteBuffers(1, &b->CBO);
  1422. for (bc = b->Branches.pFirst; bc; bc = NextBc){
  1423. NextBc = bc->Item.pNext;
  1424. lstRemoveItem(&b->Branches, bc);
  1425. if (bc->EBO > -1) glDeleteBuffers(1, &bc->EBO);
  1426. if (bc->CBO > -1) glDeleteBuffers(1, &bc->CBO);
  1427. FreeMem(bc);
  1428. }
  1429. FreeMem(b);
  1430. }
  1431. void tnsDrawBatchInitArrayStates(tnsBatch* batch){
  1432. tnsShader* cs=T->BindedShader;
  1433. glBindBuffer(GL_ARRAY_BUFFER, batch->VBO);
  1434. glEnableVertexAttribArray(cs->iVertex);
  1435. glVertexAttribPointer(cs->iVertex, batch->Dimension, GL_FLOAT, 0, 0, 0);
  1436. if(cs->iNormal>=0){
  1437. if(batch->HasNormal){
  1438. glBindBuffer(GL_ARRAY_BUFFER, batch->NBO); glEnableVertexAttribArray(cs->iNormal);
  1439. glVertexAttribPointer(cs->iNormal, batch->NormalDimension, GL_FLOAT, 0, 0, 0); tnsUniformUseNormal(cs,T->StateUseNormal);
  1440. }else{ glDisableVertexAttribArray(cs->iNormal); glVertexAttrib3f(cs->iNormal,0,0,1); tnsUniformUseNormal(cs,0); }
  1441. }
  1442. if(cs->iColor>=0){
  1443. if(batch->HasColor){
  1444. glBindBuffer(GL_ARRAY_BUFFER, batch->CBO); glEnableVertexAttribArray(cs->iColor);
  1445. glVertexAttribPointer(cs->iColor, batch->ColorDimension, GL_FLOAT, 0, 0, 0);
  1446. }
  1447. }
  1448. if(cs->iUV>=0){ glDisableVertexAttribArray(cs->iUV); }
  1449. tnsUniformUseTexture(cs, 0, 0);
  1450. }
  1451. int tnsDrawBatch(tnsBatch* batch, const char* OverrideCommand, real* OverrideUniformColor, int OverrideAsArray) {
  1452. if (!batch) return;
  1453. int Drawn=0; tnsShader *LastShader=T->BindedShader,*SaveShader=T->BindedShader; int NeedInit=1;
  1454. int IsOverrideColor=0; int PointSizeChanged=0,LineWidthChanged=0;
  1455. for (tnsBatchCommand* bc = batch->Branches.pFirst; bc; bc = bc->Item.pNext) {
  1456. if(OverrideCommand && !strSame(OverrideCommand, bc->name)){ continue; }
  1457. if(!OverrideCommand && bc->HiddenByDefault){ continue; }
  1458. if(NeedInit || (bc->Material && LastShader!=bc->Material->Shader) || ((!bc->Material)&&LastShader!=SaveShader)){
  1459. if(bc->Material && bc->Material->Shader){ LastShader=bc->Material->Shader;
  1460. tnsUseShader(LastShader); tnsEnableShaderv(LastShader);
  1461. }else{
  1462. tnsUseShader(SaveShader); tnsEnableShaderv(SaveShader);
  1463. }
  1464. tnsDrawBatchInitArrayStates(batch); NeedInit=0;
  1465. }
  1466. tnsShader* cs=T->BindedShader;
  1467. if(cs->iColor>-1){
  1468. if(bc->OverrideColorArray){
  1469. glBindBuffer(GL_ARRAY_BUFFER, bc->CBO); glEnableVertexAttribArray(cs->iColor);
  1470. glVertexAttribPointer(cs->iColor, bc->ColorDimension, GL_FLOAT, 0, 0, 0); IsOverrideColor=1;
  1471. }else{
  1472. if(batch->HasColor){ if(IsOverrideColor){ glBindBuffer(GL_ARRAY_BUFFER, batch->CBO); glEnableVertexAttribArray(cs->iColor);
  1473. glVertexAttribPointer(cs->iColor, batch->ColorDimension, GL_FLOAT, 0, 0, 0); }
  1474. }else{ glDisableVertexAttribArray(cs->iColor); glVertexAttrib4fv(cs->iColor,T->StateColor); }
  1475. }
  1476. if(bc->UseUniformColor || OverrideUniformColor){ glDisableVertexAttribArray(cs->iColor); IsOverrideColor=1;
  1477. if(OverrideUniformColor){ glVertexAttrib4f(cs->iColor,LA_COLOR4(OverrideUniformColor)); }
  1478. else glVertexAttrib4f(cs->iColor,LA_COLOR4(bc->UniformColor));
  1479. }
  1480. }
  1481. if(bc->DrawAs == GL_POINTS && bc->Width>1e-5){ glPointSize(bc->Width); PointSizeChanged=1; }
  1482. if((bc->DrawAs == GL_LINE_STRIP||bc->DrawAs == GL_LINES||bc->DrawAs == GL_LINE_LOOP) && bc->Width>1e-5){
  1483. glLineWidth(bc->Width); LineWidthChanged=1;
  1484. }
  1485. int DrawElements=OverrideAsArray?0:bc->DrawElements;
  1486. if(DrawElements){
  1487. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, bc->EBO);
  1488. glDrawElements(bc->DrawAs, bc->ElementCount*bc->Dimension, GL_UNSIGNED_INT, 0);
  1489. }else{ glDrawArrays(bc->DrawAs,0,bc->ElementCount); }
  1490. Drawn++;
  1491. if(PointSizeChanged){ glPointSize(1); } if(LineWidthChanged){ glLineWidth(1); }
  1492. }
  1493. if(SaveShader!=LastShader){ tnsUseShader(SaveShader); tnsEnableShaderv(SaveShader); }
  1494. //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  1495. return Drawn;
  1496. }
  1497. //==========================*=======================[Texture]
  1498. int tnsGetTextureMemoryComponetCount(tnsTexture *t){
  1499. int Comp = 0;
  1500. int CompSize;
  1501. switch (t->GLTexBitsType){
  1502. case GL_RGB:
  1503. Comp = 3;
  1504. break;
  1505. case GL_RGBA:
  1506. Comp = 4;
  1507. break;
  1508. }
  1509. return t->Width * t->Height * Comp;
  1510. }
  1511. int tnsInit2DTexture(tnsTexture *t, GLint glInternalFormat, int w, int h, int Multisample){
  1512. if (!t) return 0;
  1513. if(0/*glInternalFormat==GL_DEPTH_COMPONENT32F*/){
  1514. t->Width = w;
  1515. t->Height = h;
  1516. t->GLTexBitsType = GL_DEPTH_COMPONENT32F;
  1517. t->GLTexType = GL_RENDERBUFFER;
  1518. t->Multisample = Multisample;
  1519. glGenRenderbuffers(1, &t->GLTexHandle);
  1520. tnsConfigure2DTexture(t);
  1521. }else{
  1522. t->Width = w;
  1523. t->Height = h;
  1524. t->GLTexBitsType = glInternalFormat;
  1525. t->GLTexType = Multisample?GL_TEXTURE_2D_MULTISAMPLE:GL_TEXTURE_2D;
  1526. t->Multisample = Multisample;
  1527. glGenTextures(1, &t->GLTexHandle);
  1528. tnsConfigure2DTexture(t);
  1529. }
  1530. return 1;
  1531. }
  1532. int tnsInit3DTexture(tnsTexture *t, GLint glInternalFormat, int w, int h, int slices){
  1533. if (!t) return 0;
  1534. t->Width = w;
  1535. t->Height = h;
  1536. t->GLTexBitsType = glInternalFormat;
  1537. t->GLTexType = GL_TEXTURE_3D;
  1538. glGenTextures(1, &t->GLTexHandle);
  1539. tnsConfigure3DTexture(t);
  1540. return 1;
  1541. }
  1542. void tnsConfigure2DTexture(tnsTexture *t){
  1543. tnsBindTexture(t);
  1544. if(t->GLTexType==GL_RENDERBUFFER){
  1545. if(t->Multisample){ glRenderbufferStorageMultisample(GL_RENDERBUFFER, t->Multisample, t->GLTexBitsType, t->Width, t->Height); }
  1546. else { glRenderbufferStorage(GL_RENDERBUFFER, t->GLTexBitsType, t->Width, t->Height); }
  1547. }else{
  1548. int isDepth=t->GLTexBitsType==GL_DEPTH_COMPONENT||t->GLTexBitsType==GL_DEPTH_COMPONENT16||
  1549. t->GLTexBitsType==GL_DEPTH_COMPONENT24||t->GLTexBitsType==GL_DEPTH_COMPONENT32F;
  1550. int format=isDepth?GL_DEPTH_COMPONENT:(t->GLTexBitsType==GL_R8?GL_RED:(t->GLTexBitsType==GL_RG8?GL_RG:(t->GLTexBitsType==GL_RGB8?GL_RGB:GL_RGBA)));
  1551. int type=GL_UNSIGNED_BYTE;
  1552. if(t->GLTexBitsType==GL_DEPTH_STENCIL){ format=GL_DEPTH_STENCIL; type=GL_UNSIGNED_INT_24_8_EXT; }
  1553. if(t->Multisample) glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, t->Multisample, t->GLTexBitsType, t->Width, t->Height, GL_TRUE);
  1554. else{ glTexImage2D(GL_TEXTURE_2D, 0, t->GLTexBitsType, t->Width, t->Height, 0, format, type, 0);
  1555. int a=glGetError();
  1556. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  1557. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  1558. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  1559. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  1560. //glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  1561. }
  1562. }
  1563. tnsUnbindTexture();
  1564. }
  1565. void tnsConfigure3DTexture(tnsTexture *t){
  1566. tnsBindTexture(t);
  1567. glTexImage3D(GL_TEXTURE_3D, 0, t->GLTexBitsType, t->Width, t->Height, t->Slices, 0, GL_RGBA, GL_FLOAT, 0);
  1568. glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP);
  1569. glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP);
  1570. glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP);
  1571. glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  1572. glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  1573. //glTexEnvi(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_REPLACE);
  1574. tnsUnbindTexture();
  1575. }
  1576. void tnsReconfigureTextureParameters(int Multisample){
  1577. laListHandle* l = tKnlGetTextureList();
  1578. for(tnsOffscreen* o=T->Offscreens.pFirst;o;o=o->Item.pNext){ tnsTexture* t;
  1579. for(int i=0;i<4;i++){
  1580. t=o->pColor[i];
  1581. if(t){
  1582. t->Multisample = Multisample;
  1583. int recreate=0;
  1584. if(t->Multisample){ if(t->GLTexType==GL_TEXTURE_2D){t->GLTexType=GL_TEXTURE_2D_MULTISAMPLE; recreate=1;}}
  1585. else { if(t->GLTexType==GL_TEXTURE_2D_MULTISAMPLE){t->GLTexType=GL_TEXTURE_2D; recreate=1;}}
  1586. if(recreate){
  1587. glDeleteTextures(1, &t->GLTexHandle);
  1588. glGenTextures(1, &t->GLTexHandle);
  1589. }
  1590. T->TexColor=0;
  1591. tnsConfigure2DTexture(t);
  1592. tnsAttach2DOffscreenBuffer(o, GL_COLOR_ATTACHMENT0+i, t);
  1593. }
  1594. }
  1595. t=o->pDepth;
  1596. if(t){ int recreate=0;
  1597. if((!t->Multisample && Multisample)||(t->Multisample && !Multisample)){ recreate=1; }
  1598. if(Multisample){ t->GLTexType=GL_TEXTURE_2D_MULTISAMPLE; }else{ t->GLTexType=GL_TEXTURE_2D; }
  1599. t->Multisample = Multisample;
  1600. if(recreate){
  1601. glDeleteTextures(1, &t->GLTexHandle);
  1602. glGenTextures(1, &t->GLTexHandle);
  1603. } T->TexColor=0;
  1604. tnsConfigure2DTexture(t);
  1605. tnsAttach2DOffscreenBuffer(o, GL_DEPTH_ATTACHMENT, t);
  1606. }
  1607. }
  1608. }
  1609. tnsTexture *tnsCreate2DTexture(GLint glInternalFormat, int w, int h, int Multisample){
  1610. tnsTexture *tex = memAcquire(sizeof(tnsTexture));
  1611. tnsInit2DTexture(tex, glInternalFormat, w, h, Multisample);
  1612. laNotifyUsers("tns.texture_list");
  1613. lstAppendItem(tKnlGetTextureList(), tex);
  1614. return tex;
  1615. };
  1616. tnsTexture *tnsCreate3DTexture(GLint glInternalFormat, int w, int h, int slices){
  1617. tnsTexture *tex = memAcquire(sizeof(tnsTexture));
  1618. tnsInit3DTexture(tex, glInternalFormat, w, h, slices);
  1619. laNotifyUsers("tns.texture_list");
  1620. lstAppendItem(tKnlGetTextureList(), tex);
  1621. return tex;
  1622. };
  1623. void tnsCopyScreenTo2DTexture(tnsTexture *target, int x_lower_left, int y_lower_left, int w, int h){
  1624. if(target->GLTexType!=GL_TEXTURE_2D) return;
  1625. tnsBindTexture(target);
  1626. glReadBuffer(GL_BACK);
  1627. glCopyTexSubImage2D(target->GLTexType, 0, 0, 0, x_lower_left, y_lower_left, w, h);
  1628. tnsUnbindTexture();
  1629. }
  1630. void tnsUniformUseOffset(tnsShader* s, int use){
  1631. glUniform1i(s->iDoOffset,use);
  1632. }
  1633. void tnsUseMaskTexture(tnsTexture *t){
  1634. if(!t){T->StateTextureMode=0; return;}
  1635. T->StateTexColor = t; T->StateTextureMode=1;
  1636. }
  1637. void tnsUseTexture(tnsTexture *t){
  1638. if(!t){T->StateTextureMode=0; return;}
  1639. if(t->GLTexType == GL_TEXTURE_2D){ T->StateTexColor = t; T->StateTextureMode=2; }
  1640. else if(t->GLTexType == GL_TEXTURE_2D_MULTISAMPLE){ T->StateTexColor = t; T->StateTextureMode=3; }
  1641. }
  1642. void tnsUseNoTexture(){
  1643. tnsUseTexture(0);
  1644. }
  1645. void tnsUseMultiplyColor(int enable){
  1646. T->StateMultiplyColor=enable?1:0;
  1647. }
  1648. void tnsUniformUseNormal(tnsShader* s, int Use){
  1649. if(T->SetUseNormal!=Use){ T->SetUseNormal=Use; glUniform1i(s->iUseNormal,Use); }
  1650. }
  1651. void tnsUseNormal(int Use){ T->StateUseNormal=Use; }
  1652. void tnsUniformUseHalftone(tnsShader* s, real Use){
  1653. if(T->SetUseHalftone!=Use){ T->SetUseHalftone=Use; glUniform1f(s->iUseHalftone,Use); }
  1654. }
  1655. void tnsUniformHalftoneSize(tnsShader* s, real Use){
  1656. if(T->SetHalftoneSize!=Use){ T->SetHalftoneSize=Use; glUniform1f(s->iHalftoneSize,Use); }
  1657. }
  1658. void tnsUseHalftone(real Factor){ T->StateUseHalftone=Factor; }
  1659. void tnsActiveTexture(GLenum tex){
  1660. if (T->GlTextureSets != tex) glActiveTexture(tex);
  1661. T->GlTextureSets = tex;
  1662. }
  1663. void tnsBindTexture(tnsTexture *t){
  1664. if ((!t) || T->TexColor==t) return;
  1665. if(t->GLTexType == GL_TEXTURE_2D){ tnsActiveTexture(GL_TEXTURE0); glBindTexture(t->GLTexType, t->GLTexHandle); T->TexColor=t;}
  1666. elif(t->GLTexType == GL_TEXTURE_2D_MULTISAMPLE){ tnsActiveTexture(GL_TEXTURE1); glBindTexture(t->GLTexType, t->GLTexHandle); T->TexColor=t;}
  1667. #ifndef LA_USE_GLES
  1668. elif(t->GLTexType == GL_RENDERBUFFER){ glBindRenderbufferEXT(GL_RENDERBUFFER, t->GLTexHandle); T->TexRenderbuffer = t;}
  1669. #endif
  1670. elif(t->GLTexType == GL_TEXTURE_3D){ tnsActiveTexture(GL_TEXTURE0); glBindTexture(t->GLTexType, t->GLTexHandle); T->TexColor=t;}
  1671. }
  1672. void tnsUnbindTexture(){
  1673. #ifndef LA_USE_GLES
  1674. if(T->TexRenderbuffer){ if(T->TexRenderbuffer->GLTexType == GL_RENDERBUFFER){ glBindRenderbufferEXT(GL_RENDERBUFFER, 0); T->TexRenderbuffer=0;}}
  1675. #endif
  1676. if(T->TexColor){
  1677. if(T->TexColor->GLTexType == GL_TEXTURE_2D){tnsActiveTexture(GL_TEXTURE0);}
  1678. else if(T->TexColor->GLTexType == GL_TEXTURE_2D_MULTISAMPLE){tnsActiveTexture(GL_TEXTURE1);}
  1679. else if(T->TexColor->GLTexType == GL_TEXTURE_3D){tnsActiveTexture(GL_TEXTURE0);}
  1680. glBindTexture(T->TexColor->GLTexType, 0); T->TexColor=0;
  1681. }
  1682. }
  1683. void tnsUniformUseTexture(tnsShader* s, int mode, int sample){
  1684. if(s->StateTextureMode != mode){ s->StateTextureMode=mode; glUniform1i(s->iTextureMode,mode); }
  1685. if(mode==3 && s->StateSampleAmount != sample){ s->StateSampleAmount=sample, glUniform1i(s->iSampleAmount,sample); }
  1686. }
  1687. void tnsUniformUseMultiplyColor(tnsShader* s, int enable){
  1688. int mode=enable?1:0;
  1689. if(s->StateMultiplyColor != mode){ s->StateMultiplyColor=mode; glUniform1i(s->iMultiplyColor,mode); }
  1690. }
  1691. void tnsUniformColorMode(tnsShader* s, int mode){
  1692. glUniform1i(s->iColorMode,mode);
  1693. }
  1694. void tnsUniformHCYGamma(tnsShader* s, float Gamma){
  1695. glUniform1f(s->iHCYGamma,Gamma);
  1696. }
  1697. void tnsUniformInputColorSpace(tnsShader* s, int ColorSpace){
  1698. glUniform1i(s->iInputColorSpace,ColorSpace);
  1699. }
  1700. void tnsUniformOutputColorSpace(tnsShader* s, int ColorSpace){
  1701. glUniform1i(s->iOutputColorSpace,ColorSpace);
  1702. }
  1703. void tnsUniformShowColorOverflowStripes(tnsShader* s, int Show){
  1704. glUniform1i(s->iShowStripes,Show);
  1705. }
  1706. void tnsUniformColorComposing(tnsShader* s, int Composing, real gamma, real blackpoint){
  1707. glUniform1i(s->iComposing,Composing); glUniform1f(s->iComposingGamma,gamma);
  1708. glUniform1f(s->iComposingBlackpoint,blackpoint);
  1709. }
  1710. void tnsDraw2DTextureDirectly(tnsTexture *t, real x, real y, real w, real h){
  1711. real Verts[8];
  1712. real UV[8] = {
  1713. 0.0f, 1.0f,
  1714. 1.0f, 1.0f,
  1715. 1.0f, 0.0f,
  1716. 0.0f, 0.0f};
  1717. tnsMakeQuad2d(Verts, x, y, x + w, y, x + w, y + h, x, y + h);
  1718. tnsUseTexture(t);
  1719. tnsVertexArray2d(Verts, 4);
  1720. tnsTexCoordArray2d(UV, 4);
  1721. tnsPackAs(GL_TRIANGLE_FAN);
  1722. }
  1723. void tnsDraw2DTextureArg(tnsTexture *t,
  1724. real x_upper_right, real y_upper_right, int w, int h,
  1725. real *MultiplyColor,
  1726. real LPadding, real RPadding, real TPadding, real BPadding){
  1727. real Verts[8];
  1728. real UV[8] = {
  1729. 0.0f + LPadding, 1.0f - TPadding,
  1730. 1.0f - RPadding, 1.0f - TPadding,
  1731. 1.0f - RPadding, 0.0f + BPadding,
  1732. 0.0f + LPadding, 0.0f + BPadding};
  1733. tnsMakeQuad2d(Verts,
  1734. x_upper_right, y_upper_right,
  1735. x_upper_right + w, y_upper_right,
  1736. x_upper_right + w, y_upper_right + h,
  1737. x_upper_right, y_upper_right + h);
  1738. if (MultiplyColor){ tnsColor4dv(MultiplyColor); tnsUseMultiplyColor(1); }
  1739. tnsUseTexture(t);
  1740. tnsVertexArray2d(Verts, 4);
  1741. tnsTexCoordArray2d(UV, 4);
  1742. tnsPackAs(GL_TRIANGLE_FAN);
  1743. tnsUseMultiplyColor(0);
  1744. }
  1745. void tnsDeleteTexture(tnsTexture *t){
  1746. laListHandle *lst = tKnlGetTextureList();
  1747. tnsUnbindTexture();
  1748. if (!t) return;
  1749. if (t->GLTexType == GL_RENDERBUFFER){
  1750. #ifndef LA_USE_GLES
  1751. glBindRenderbufferEXT(GL_RENDERBUFFER, t->GLTexHandle);
  1752. glDeleteRenderbuffersEXT(1, &t->GLTexHandle);
  1753. #endif
  1754. }else{
  1755. //glBindTexture(t->GLTexType, 0);
  1756. glDeleteTextures(1, &t->GLTexHandle);
  1757. }
  1758. laNotifyUsers("tns.texture_list");
  1759. lstRemoveItem(lst, t);
  1760. if (t->DrawData) FreeMem(t->DrawData);
  1761. memFree(t);
  1762. }
  1763. int tnsTextureMemorySize(tnsTexture *t, int Mem){
  1764. int ElemSize;
  1765. if (Mem) return t->Width * t->Height * sizeof(void *);
  1766. switch (t->GLTexBitsType){
  1767. default:
  1768. case GL_R8:
  1769. ElemSize = sizeof(char) * 1;
  1770. break;
  1771. case GL_RG8:
  1772. ElemSize = sizeof(char) * 2;
  1773. break;
  1774. case GL_RGB8:
  1775. ElemSize = sizeof(char) * 3;
  1776. break;
  1777. case GL_RGBA8:
  1778. ElemSize = sizeof(char) * 4;
  1779. break;
  1780. case GL_RGBA32F:
  1781. ElemSize = sizeof(float) * 4;
  1782. break;
  1783. case GL_DEPTH_COMPONENT32F:
  1784. ElemSize = sizeof(float);
  1785. break;
  1786. }
  1787. t->ElemSize = ElemSize;
  1788. return t->Width * t->Height * ElemSize;
  1789. }
  1790. #ifdef LA_WITH_PNG
  1791. tnsImage* tnsNewImage(void* MemPNG){
  1792. tnsImage* im=memAcquire(sizeof(tnsImage));
  1793. lstAppendItem(&T->Images,im);
  1794. im->MemPNG=MemPNG; return im;
  1795. }
  1796. STRUCTURE(tnsPNGRead){
  1797. unsigned char* data;
  1798. size_t NextData;
  1799. };
  1800. static void _tns_png_read(png_struct *ps, png_byte *data, png_size_t length){
  1801. tnsPNGRead *PNGRead = (tnsPNGRead*)png_get_io_ptr(ps);
  1802. memcpy(data,&PNGRead->data[PNGRead->NextData],length);
  1803. PNGRead->NextData+=length;
  1804. }
  1805. void tns_ImageToTexture(tnsImage* im){
  1806. if(!im->MemPNG) return;
  1807. png_structp png_ptr=0;
  1808. png_infop info_ptr=0;
  1809. tnsPNGRead PNGRead={0};
  1810. png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING,0,0,0); if (!png_ptr) { goto cleanup_png_read; }
  1811. info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { goto cleanup_png_read; }
  1812. if (setjmp(png_jmpbuf(png_ptr))) { goto cleanup_png_read; }
  1813. PNGRead.data=im->MemPNG; png_set_read_fn(png_ptr, &PNGRead, _tns_png_read);
  1814. png_read_info(png_ptr, info_ptr);
  1815. png_set_swap(png_ptr);
  1816. if (png_get_interlace_type (png_ptr, info_ptr) != PNG_INTERLACE_NONE){ goto cleanup_png_read; }
  1817. png_byte ColorType = png_get_color_type(png_ptr, info_ptr);
  1818. png_byte BitDepth = png_get_bit_depth(png_ptr, info_ptr);
  1819. int HasAlpha = ColorType & PNG_COLOR_MASK_ALPHA;
  1820. if (ColorType == PNG_COLOR_TYPE_PALETTE) { png_set_palette_to_rgb(png_ptr); }
  1821. //if (ColorType == PNG_COLOR_TYPE_GRAY && BitDepth < 8) { png_set_expand_gray_1_2_4_to_8(png_ptr); }
  1822. if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { png_set_tRNS_to_alpha(png_ptr); HasAlpha = 1; }
  1823. if (BitDepth>8) {png_set_strip_16(png_ptr);} if (BitDepth<8) { png_set_expand(png_ptr); }
  1824. if (!HasAlpha) { png_set_add_alpha(png_ptr, 0xFFFF, PNG_FILLER_AFTER); }
  1825. if (ColorType == PNG_COLOR_TYPE_GRAY || ColorType == PNG_COLOR_TYPE_GRAY_ALPHA) { png_set_gray_to_rgb(png_ptr); }
  1826. png_read_update_info(png_ptr, info_ptr);
  1827. if (png_get_bit_depth(png_ptr, info_ptr)!=8) { goto cleanup_png_read; }
  1828. if (png_get_color_type(png_ptr, info_ptr) != PNG_COLOR_TYPE_RGB_ALPHA){ goto cleanup_png_read; }
  1829. if (png_get_channels(png_ptr, info_ptr) != 4) { goto cleanup_png_read; }
  1830. int W = png_get_image_width(png_ptr, info_ptr);
  1831. int H = png_get_image_height(png_ptr, info_ptr);
  1832. unsigned char* buf=calloc(W*4,H*sizeof(unsigned char));
  1833. for(int i=0;i<H;i++){ png_read_row(png_ptr, &buf[((H-i-1)*W)*4], NULL); }
  1834. im->Texture=tnsCreate2DTexture(GL_RGBA8,W,H,0);
  1835. tnsBindTexture(im->Texture); glTexSubImage2D(GL_TEXTURE_2D,0,0,0,W,H,GL_RGBA,GL_UNSIGNED_BYTE,buf);
  1836. tnsUnbindTexture();
  1837. free(buf);
  1838. cleanup_png_read:
  1839. if(png_ptr && info_ptr) png_destroy_read_struct(&png_ptr,&info_ptr,0);
  1840. }
  1841. void tnsUseImage(tnsImage* im){
  1842. if(im->UserCount==0 || !im->Texture){
  1843. if(!im->MemPNG){
  1844. if(im->Texture){ tnsDeleteTexture(im->Texture); im->Texture=0; }
  1845. }else{
  1846. tns_ImageToTexture(im);
  1847. }
  1848. }
  1849. im->UserCount++;
  1850. }
  1851. void tnsRefreshImage(tnsImage* im,void* data){
  1852. if(im->MemPNG){free(im->MemPNG);}
  1853. im->MemPNG=data; tnsDeleteTexture(im->Texture); im->Texture=0;
  1854. }
  1855. void tnsStopUsingImage(tnsImage* im){
  1856. im->UserCount--;
  1857. if(im->UserCount<=0){ im->UserCount=0; tnsDeleteTexture(im->Texture); im->Texture=0; }
  1858. }
  1859. void tnsRemoveImage(tnsImage* im){
  1860. while(im->UserCount) tnsStopUsingImage(im);
  1861. if(im->MemPNG) free(im->MemPNG);
  1862. lstRemoveItem(&T->Images,im); memFree(im);
  1863. }
  1864. #endif //png
  1865. //====================================================[NEW RENDER KERNEL]
  1866. //=================[Immediate-style api]
  1867. void tnsColor4d(real r, real g, real b, real a){ tnsVectorSet4(T->StateColor,r,g,b,a); }
  1868. void tnsColor4dv(real *rgba){ tnsVectorSet4v(T->StateColor,rgba); }
  1869. void tnsLineWidth(real Width){ if(TNS_FLOAT_CLOSE_ENOUGH_WIDER(Width,T->StateLineWidth)) return;
  1870. T->StateLineWidth=Width;
  1871. }
  1872. void tnsPointSize(real PointSize){ if(TNS_FLOAT_CLOSE_ENOUGH_WIDER(PointSize,T->StatePointSize)) return;
  1873. T->StatePointSize=PointSize;
  1874. }
  1875. void tnsVertex3d(real x, real y, real z){
  1876. tnsCommand *c = &T->DrawingCommand[T->NextCommand];
  1877. int vend = c->VertEnd;
  1878. c->UseVert = 1;
  1879. if (!c->Dimensions) c->Dimensions = 3;
  1880. if(arrEnsureLength(&T->Vert, T->NextVert+c->Dimensions, &T->MaxVert, sizeof(GLfloat))){
  1881. glBindBuffer(GL_ARRAY_BUFFER, T->VertBufObject);
  1882. glBufferData(GL_ARRAY_BUFFER, T->MaxVert * sizeof(GLfloat), 0, GL_DYNAMIC_DRAW);
  1883. }
  1884. GLfloat *varr = T->Vert;
  1885. if (c->Dimensions == 3){
  1886. varr[vend] = x;
  1887. varr[vend + 1] = y;
  1888. varr[vend + 2] = z;
  1889. c->NumVert++;
  1890. T->NextVert += 3;
  1891. c->VertEnd += 3;
  1892. }else{
  1893. varr[vend] = x;
  1894. varr[vend + 1] = y;
  1895. c->NumVert++;
  1896. T->NextVert += 2;
  1897. c->VertEnd += 2;
  1898. }
  1899. }
  1900. void tnsVertex2d(real x, real y){
  1901. tnsCommand *c = &T->DrawingCommand[T->NextCommand];
  1902. int vend = c->VertEnd;
  1903. c->UseVert = 1;
  1904. if (!c->Dimensions) c->Dimensions = 2;
  1905. if(arrEnsureLength(&T->Vert, T->NextVert+c->Dimensions, &T->MaxVert, sizeof(GLfloat))){
  1906. glBindBuffer(GL_ARRAY_BUFFER, T->VertBufObject);
  1907. glBufferData(GL_ARRAY_BUFFER, T->MaxVert * sizeof(GLfloat), 0, GL_DYNAMIC_DRAW);
  1908. }
  1909. GLfloat *varr = T->Vert;
  1910. if (c->Dimensions == 2){
  1911. varr[vend] = x;
  1912. varr[vend + 1] = y;
  1913. c->NumVert++;
  1914. T->NextVert += 2;
  1915. c->VertEnd += 2;
  1916. }else{
  1917. tnsVertex3d(x, y, 0.0f);
  1918. }
  1919. }
  1920. void tnsVertexArray2d(real *verts, int amount){
  1921. tnsCommand *c = &T->DrawingCommand[T->NextCommand];
  1922. int trans = 2 * amount;
  1923. int vend = c->VertEnd;
  1924. c->UseVert = 1;
  1925. if (!c->Dimensions) c->Dimensions = 2;
  1926. if(arrEnsureLength(&T->Vert, T->NextVert+c->Dimensions*amount, &T->MaxVert, sizeof(GLfloat))){
  1927. glBindBuffer(GL_ARRAY_BUFFER, T->VertBufObject);
  1928. glBufferData(GL_ARRAY_BUFFER, T->MaxVert * sizeof(GLfloat), 0, GL_DYNAMIC_DRAW);
  1929. }
  1930. GLfloat *varr = T->Vert;
  1931. if (c->Dimensions == 2){
  1932. int i;
  1933. for (i = 0; i < trans; i++){
  1934. varr[vend] = verts[i];
  1935. vend++;
  1936. }
  1937. //memcpy(&varr[vend], verts, trans*sizeof(real));
  1938. c->VertEnd += trans;
  1939. c->NumVert += amount;
  1940. T->NextVert += trans;
  1941. }
  1942. }
  1943. void tnsVertexArray3d(real *verts, int amount){
  1944. tnsCommand *c = &T->DrawingCommand[T->NextCommand];
  1945. int trans = 3 * amount;
  1946. int vend = c->VertEnd;
  1947. c->UseVert = 1;
  1948. if (!c->Dimensions) c->Dimensions = 3;
  1949. if(arrEnsureLength(&T->Vert, T->NextVert+c->Dimensions*amount, &T->MaxVert, sizeof(GLfloat))){
  1950. glBindBuffer(GL_ARRAY_BUFFER, T->VertBufObject);
  1951. glBufferData(GL_ARRAY_BUFFER, T->MaxVert * sizeof(GLfloat), 0, GL_DYNAMIC_DRAW);
  1952. }
  1953. GLfloat *varr = T->Vert;
  1954. if (c->Dimensions == 3){
  1955. int i;
  1956. for (i = 0; i < trans; i++){
  1957. varr[vend] = verts[i];
  1958. vend++;
  1959. }
  1960. //memcpy(&varr[vend], verts, trans*sizeof(real));
  1961. c->VertEnd += trans;
  1962. c->NumVert += amount;
  1963. T->NextVert += trans;
  1964. }
  1965. }
  1966. void tnsColorArray4d(real *colors, int amount){
  1967. tnsCommand *c = &T->DrawingCommand[T->NextCommand];
  1968. int trans = 4 * amount;
  1969. int ofst = c->ColorEnd;
  1970. c->UseColor = 1;
  1971. if(arrEnsureLength(&T->Color, T->NextColor+4*amount, &T->MaxColor, sizeof(GLfloat))){
  1972. glBindBuffer(GL_ARRAY_BUFFER, T->ColorBufObject);
  1973. glBufferData(GL_ARRAY_BUFFER, T->MaxColor * sizeof(GLfloat), 0, GL_DYNAMIC_DRAW);
  1974. }
  1975. GLfloat *carr = T->Color;
  1976. int i;
  1977. for (i = 0; i < trans; i++){
  1978. carr[ofst] = colors[i];
  1979. ofst++;
  1980. }
  1981. //memcpy(&T->Color[c->ColorEnd], colors, trans*sizeof(real));
  1982. c->ColorEnd += trans;
  1983. T->NextColor += trans;
  1984. }
  1985. void tnsNormalArray3d(real *normals, int amount){
  1986. tnsCommand *c = &T->DrawingCommand[T->NextCommand];
  1987. int trans = 3 * amount;
  1988. int ofst = c->NormalEnd;
  1989. c->UseNormal = 1;
  1990. if(arrEnsureLength(&T->Normal, T->NextNormal+3*amount, &T->MaxNormal, sizeof(GLfloat))){
  1991. glBindBuffer(GL_ARRAY_BUFFER, T->NormalBufObject);
  1992. glBufferData(GL_ARRAY_BUFFER, T->MaxNormal * sizeof(GLfloat), 0, GL_DYNAMIC_DRAW);
  1993. }
  1994. GLfloat *narr = T->Normal;
  1995. int i;
  1996. for (i = 0; i < trans; i++){
  1997. narr[ofst] = normals[i];
  1998. ofst++;
  1999. }
  2000. //memcpy(&T->Normal[c->NormalEnd], normals, trans*sizeof(real));
  2001. c->NormalEnd += trans;
  2002. T->NextNormal += trans;
  2003. }
  2004. void tnsTexCoordArray2d(real *coords, int amount){
  2005. tnsCommand *c = &T->DrawingCommand[T->NextCommand];
  2006. int trans = 2 * amount;
  2007. int ofst = c->TexCoordEnd;
  2008. c->UseTexCoord = 1;
  2009. c->UVDimensions = 2;
  2010. if(arrEnsureLength(&T->TexCoord, T->NextTexCoord+2*amount, &T->MaxTexCoord, sizeof(GLfloat))){
  2011. glBindBuffer(GL_ARRAY_BUFFER, T->TexCoordBufObject);
  2012. glBufferData(GL_ARRAY_BUFFER, T->MaxTexCoord * sizeof(GLfloat), 0, GL_DYNAMIC_DRAW);
  2013. }
  2014. GLfloat *carr = T->TexCoord;
  2015. int i;
  2016. for (i = 0; i < trans; i++){
  2017. carr[ofst] = coords[i];
  2018. ofst++;
  2019. }
  2020. //memcpy(&T->TexCoord[c->TexCoordEnd], coords, trans*sizeof(real));
  2021. c->TexCoordEnd += trans;
  2022. T->NextTexCoord += trans;
  2023. }
  2024. void tnsTexCoordArray3d(real *coords, int amount){
  2025. tnsCommand *c = &T->DrawingCommand[T->NextCommand];
  2026. int trans = 3 * amount;
  2027. int ofst = c->TexCoordEnd;
  2028. c->UseTexCoord = 1;
  2029. c->UVDimensions = 3;
  2030. if(arrEnsureLength(&T->TexCoord, T->NextTexCoord+3*amount, &T->MaxTexCoord, sizeof(GLfloat))){
  2031. glBindBuffer(GL_ARRAY_BUFFER, T->TexCoordBufObject);
  2032. glBufferData(GL_ARRAY_BUFFER, T->MaxTexCoord * sizeof(GLfloat), 0, GL_DYNAMIC_DRAW);
  2033. }
  2034. GLfloat *carr = T->TexCoord;
  2035. int i;
  2036. for (i = 0; i < trans; i++){ carr[ofst] = coords[i]; ofst++; }
  2037. c->TexCoordEnd += trans;
  2038. T->NextTexCoord += trans;
  2039. }
  2040. void tnsIndexArray(GLuint *index, short amount){
  2041. tnsCommand *c = &T->DrawingCommand[T->NextCommand];
  2042. //if (c->UseIndex) return;
  2043. c->UseIndex = 1;
  2044. if(arrEnsureLength(&T->Index, T->NextIndex+amount, &T->MaxIndex, sizeof(GLuint))){
  2045. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, T->IndexBufObject);
  2046. glBufferData(GL_ELEMENT_ARRAY_BUFFER, T->MaxIndex * sizeof(GLuint), 0, GL_DYNAMIC_DRAW);
  2047. }
  2048. memcpy(&T->Index[c->IndexEnd], index, amount * sizeof(GLuint));
  2049. c->IndexEnd += amount;
  2050. c->NumIndex += amount;
  2051. T->NextIndex += amount;
  2052. }
  2053. void tnsPackAs(GLenum Mode){
  2054. arrEnsureLength(&T->DrawingCommand, T->NextCommand+1, &T->MaxCommand, sizeof(tnsCommand));
  2055. tnsCommand *c = &T->DrawingCommand[T->NextCommand];
  2056. tnsCommand *nc;
  2057. T->NextCommand++;
  2058. nc = &T->DrawingCommand[T->NextCommand];
  2059. memcpy(c->UniformColor, T->StateColor, sizeof(GLfloat) * 4);
  2060. if (Mode == GL_QUAD_STRIP || Mode == GL_QUADS) Mode=GL_TRIANGLE_STRIP;
  2061. //if (Mode == GL_QUADS) Mode=GL_TRIANGLE_STRIP;
  2062. c->Mode = Mode;
  2063. c->ReplaceShader = T->StateShader;
  2064. c->ColorTexture = T->StateTexColor;
  2065. c->TextureMode = T->StateTextureMode;
  2066. c->MultiplyColor = T->StateMultiplyColor;
  2067. c->LineWidth=T->StateLineWidth;
  2068. c->PointSize=T->StatePointSize;
  2069. c->UseHalftone = T->StateUseHalftone;
  2070. memset(nc, 0, sizeof(tnsCommand));
  2071. nc->VertBegin = nc->VertEnd = c->VertEnd;
  2072. nc->NormalBegin = nc->NormalEnd = c->NormalEnd;
  2073. nc->ColorBegin = nc->ColorEnd = c->ColorEnd;
  2074. nc->TexCoordBegin = nc->TexCoordEnd = c->TexCoordEnd;
  2075. nc->IndexBegin = nc->IndexEnd = c->IndexEnd;
  2076. }
  2077. void tnsFlush(){
  2078. tnsShader *cs = T->CurrentShader;
  2079. tnsCommand *tc = &T->DrawingCommand[0];
  2080. tnsCommand *c = tc;
  2081. int PrevDimensions = 0;
  2082. int LastVertBegin = 0;
  2083. if (!c || !cs) return;
  2084. if (T->NextVert){ glBindBuffer(GL_ARRAY_BUFFER, T->VertBufObject);
  2085. glBufferSubData(GL_ARRAY_BUFFER, 0, T->NextVert * sizeof(GLfloat), T->Vert);
  2086. }
  2087. if (T->NextColor){ glBindBuffer(GL_ARRAY_BUFFER, T->ColorBufObject);
  2088. glBufferSubData(GL_ARRAY_BUFFER, 0, T->NextColor * sizeof(GLfloat), T->Color);
  2089. }
  2090. if (T->NextNormal){ glBindBuffer(GL_ARRAY_BUFFER, T->NormalBufObject);
  2091. glBufferSubData(GL_ARRAY_BUFFER, 0, T->NextNormal * sizeof(GLfloat), T->Normal);
  2092. }
  2093. if (T->NextTexCoord){ glBindBuffer(GL_ARRAY_BUFFER, T->TexCoordBufObject);
  2094. glBufferSubData(GL_ARRAY_BUFFER, 0, T->NextTexCoord * sizeof(GLfloat), T->TexCoord);
  2095. }
  2096. for (int i=0;i<T->NextCommand;i++){ c=&T->DrawingCommand[i];
  2097. if (c->LineWidth!=T->SetLineWidth){ glLineWidth(c->LineWidth); T->SetLineWidth=c->LineWidth; }
  2098. if (c->PointSize!=T->SetPointSize){
  2099. glPointSize(c->PointSize); T->SetPointSize=c->PointSize;
  2100. }
  2101. if (c->ReplaceShader && c->ReplaceShader != T->CurrentShader){
  2102. tnsEnableShaderv(c->ReplaceShader); cs = c->ReplaceShader;
  2103. if (!cs) continue;
  2104. }
  2105. glBindBuffer(GL_ARRAY_BUFFER, T->VertBufObject);
  2106. if (c->UseVert){
  2107. glEnableVertexAttribArray(cs->iVertex);
  2108. glVertexAttribPointer(cs->iVertex, (c->Dimensions ? c->Dimensions : PrevDimensions),
  2109. GL_FLOAT, 0, 0, c->VertBegin * sizeof(GLfloat));
  2110. LastVertBegin = c->VertBegin;
  2111. }else{
  2112. glEnableVertexAttribArray(cs->iVertex);
  2113. glVertexAttribPointer(cs->iVertex, (c->Dimensions ? c->Dimensions : PrevDimensions),
  2114. GL_FLOAT, 0, 0, LastVertBegin * sizeof(GLfloat));
  2115. }
  2116. PrevDimensions = (c->Dimensions ? c->Dimensions : PrevDimensions);
  2117. if (c->UseIndex){
  2118. glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, T->IndexBufObject);
  2119. glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, c->NumIndex * sizeof(GLuint), &T->Index[c->IndexBegin]);
  2120. }
  2121. if (cs->iNormal != -1){
  2122. glBindBuffer(GL_ARRAY_BUFFER, T->NormalBufObject);
  2123. if (c->UseNormal){
  2124. glEnableVertexAttribArray(cs->iNormal); tnsUniformUseNormal(cs,1);
  2125. }
  2126. glVertexAttribPointer(cs->iNormal, 3, GL_FLOAT, 0, 0, c->NormalBegin * sizeof(GLfloat));
  2127. if (!c->UseNormal || c->Dimensions == 2){
  2128. glDisableVertexAttribArray(cs->iNormal); tnsUniformUseNormal(cs,0);
  2129. glVertexAttrib3f(cs->iNormal, 0, 0, -1);
  2130. }
  2131. }
  2132. if (cs->iColor != -1){
  2133. glBindBuffer(GL_ARRAY_BUFFER, T->ColorBufObject);
  2134. if (c->UseColor){
  2135. glEnableVertexAttribArray(cs->iColor);
  2136. glVertexAttribPointer(cs->iColor, 4, GL_FLOAT, 0, 0, c->ColorBegin * sizeof(GLfloat));
  2137. }else{
  2138. glDisableVertexAttribArray(cs->iColor);
  2139. glVertexAttrib4fv(cs->iColor, c->UniformColor);
  2140. }
  2141. }
  2142. if (cs->iUV != -1){
  2143. if (c->UseTexCoord){
  2144. glBindBuffer(GL_ARRAY_BUFFER, T->TexCoordBufObject);
  2145. if (c->UseTexCoord){ glEnableVertexAttribArray(cs->iUV);
  2146. glVertexAttribPointer(cs->iUV, c->UVDimensions, GL_FLOAT, 0, 0, c->TexCoordBegin * sizeof(GLfloat)); }
  2147. else{ glDisableVertexAttribArray(cs->iUV); }
  2148. }
  2149. }
  2150. if (c->TextureMode && c->ColorTexture && cs->iTexColor != -1){
  2151. tnsBindTexture(c->ColorTexture); tnsUniformUseTexture(cs, c->TextureMode, c->ColorTexture->Multisample);
  2152. }else{
  2153. tnsUniformUseTexture(cs, 0, 0); //tnsUnbindTexture();
  2154. }
  2155. if(cs->iMultiplyColor != -1){ tnsUniformUseMultiplyColor(cs, c->MultiplyColor); }
  2156. if(cs->iUseHalftone != -1){
  2157. tnsUniformUseHalftone(cs, c->UseHalftone);
  2158. tnsUniformHalftoneSize(cs, MAIN.ViewportHalftoneSize);
  2159. }
  2160. if (c->UseIndex){
  2161. glDrawElements(c->Mode, c->NumIndex, GL_UNSIGNED_INT, 0);
  2162. }else{
  2163. glDrawArrays(c->Mode, 0, c->NumVert);
  2164. }
  2165. }
  2166. T->NextCommand=0;
  2167. c = &T->DrawingCommand[0];
  2168. memset(c, 0, sizeof(tnsCommand));
  2169. c->ColorBegin = c->ColorEnd = T->NextColor = 0;
  2170. c->NormalBegin = c->NormalEnd = T->NextNormal = 0;
  2171. c->TexCoordBegin = c->TexCoordEnd = T->NextTexCoord = 0;
  2172. c->VertBegin = c->VertEnd = T->NextVert = 0;
  2173. c->IndexBegin = c->IndexEnd = T->NextIndex = 0;
  2174. //must --why?
  2175. //T->BindedShader = 0;
  2176. };
  2177. //============================================================================================[offscr]
  2178. const GLuint TNS_ATTACHMENT_ARRAY_NONE[] = {GL_NONE};
  2179. const GLuint TNS_ATTACHMENT_ARRAY[] = {GL_COLOR_ATTACHMENT0};
  2180. const GLuint TNS_ATTACHMENT_ARRAY_1[] = {GL_COLOR_ATTACHMENT1};
  2181. const GLuint TNS_ATTACHMENT_ARRAY_2[] = {GL_COLOR_ATTACHMENT2};
  2182. const GLuint TNS_ATTACHMENT_ARRAY_1_2[] = {GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2};
  2183. const GLuint TNS_ATTACHMENT_ARRAY_0_1_2[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2};
  2184. const GLenum TNS_WINDOW_DRAWBUFFER_ARRAY[] = {GL_BACK};
  2185. tnsOffscreen *tnsCreateOffscreenHandle(){
  2186. if(!T->CurrentContext){ printf("tnsCreateOffscreenHandle() called without GL Context. Exiting"); exit(0); }
  2187. tnsOffscreen *toff = CreateNew(tnsOffscreen); toff->FboContext=T->CurrentContext;
  2188. #ifdef LA_USE_GLES
  2189. toff->FboSurface=T->CurrentSurface;
  2190. #endif
  2191. #ifdef _WIN32
  2192. toff->FboDC=T->CurrentDC;
  2193. #endif
  2194. #ifdef __linux__
  2195. toff->FboWindow=T->CurrentWindow;
  2196. #endif
  2197. glGenFramebuffers(1, &toff->FboHandle);
  2198. lstAppendItem(&T->Offscreens, toff);
  2199. return toff;
  2200. }
  2201. void tnsAttach2DOffscreenBuffer(tnsOffscreen *target, GLuint attatchment, tnsTexture *use){
  2202. if (!target || !use || target->FboHandle == -1 || use->GLTexHandle == -1) return;
  2203. if (attatchment >= GL_COLOR_ATTACHMENT0 && attatchment <= GL_COLOR_ATTACHMENT15){
  2204. //if (target->pColor[attatchment - GL_COLOR_ATTACHMENT0]) return;
  2205. glBindFramebuffer(GL_FRAMEBUFFER, target->FboHandle);
  2206. tnsBindTexture(use);
  2207. glFramebufferTexture2D(GL_FRAMEBUFFER, attatchment, use->GLTexType, use->GLTexHandle, 0);
  2208. target->pColor[attatchment - GL_COLOR_ATTACHMENT0] = use;
  2209. tnsUnbindTexture();
  2210. glBindFramebuffer(GL_FRAMEBUFFER, 0);
  2211. }elif (attatchment == GL_DEPTH_ATTACHMENT || attatchment==GL_STENCIL_ATTACHMENT){
  2212. //if (target->pDepth) return;
  2213. glBindFramebuffer(GL_FRAMEBUFFER, target->FboHandle);
  2214. tnsBindTexture(use);
  2215. glFramebufferTexture2D(GL_FRAMEBUFFER, attatchment, use->GLTexType, use->GLTexHandle, 0);
  2216. //glBindRenderbufferEXT(GL_RENDERBUFFER, use->GLTexHandle);
  2217. //glBindFramebuffer(GL_FRAMEBUFFER, target->FboHandle);
  2218. //glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, use->GLTexHandle);
  2219. target->pDepth = use;
  2220. tnsUnbindTexture();
  2221. glBindFramebuffer(GL_FRAMEBUFFER, 0);
  2222. //glBindRenderbufferEXT(GL_RENDERBUFFER, 0);
  2223. //glBindFramebuffer(GL_FRAMEBUFFER, 0);
  2224. }
  2225. GLenum result = glCheckFramebufferStatus(GL_FRAMEBUFFER);
  2226. //if (result == GL_FRAMEBUFFER_COMPLETE) { printf("Framebuffer complete!\n"); }
  2227. //else { printf("Framebuffer incomplete!\n"); }
  2228. }
  2229. void tnsDetach2DOffscreenBuffer(tnsOffscreen *target, GLuint which_attach_point){
  2230. if (which_attach_point >= GL_COLOR_ATTACHMENT0 && which_attach_point <= GL_COLOR_ATTACHMENT15){
  2231. if (target->pColor[which_attach_point - GL_COLOR_ATTACHMENT0] == 0) return;
  2232. glBindFramebuffer(GL_FRAMEBUFFER, target->FboHandle);
  2233. glFramebufferTexture2D(GL_FRAMEBUFFER, which_attach_point, GL_TEXTURE_2D, 0, 0);
  2234. tnsDeleteTexture(target->pColor[which_attach_point - GL_COLOR_ATTACHMENT0]);
  2235. target->pColor[which_attach_point - GL_COLOR_ATTACHMENT0] = 0;
  2236. }elif (which_attach_point == GL_DEPTH_ATTACHMENT || which_attach_point==GL_STENCIL_ATTACHMENT){
  2237. if (target->pDepth) return;
  2238. glBindFramebuffer(GL_FRAMEBUFFER, target->FboHandle);
  2239. glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
  2240. tnsDeleteTexture(target->pDepth);
  2241. target->pDepth = 0;
  2242. }
  2243. glBindFramebuffer(GL_FRAMEBUFFER, 0);
  2244. tnsUnbindTexture();
  2245. }
  2246. tnsOffscreen *tnsCreate2DOffscreen(int glInternalFormat, int w, int h, int Multisample, int WithDepth, int WithStencil){
  2247. tnsOffscreen *toff = tnsCreateOffscreenHandle();
  2248. tnsTexture *color; tnsTexture *depth;
  2249. if(glInternalFormat){
  2250. color = tnsCreate2DTexture(glInternalFormat, w, h, Multisample);
  2251. tnsAttach2DOffscreenBuffer(toff, GL_COLOR_ATTACHMENT0, color);
  2252. }
  2253. if(WithDepth || WithStencil){
  2254. int format=GL_DEPTH_COMPONENT;
  2255. if(WithStencil){ format=GL_DEPTH_STENCIL; }
  2256. depth = tnsCreate2DTexture(format, w, h, Multisample);
  2257. tnsAttach2DOffscreenBuffer(toff, GL_DEPTH_ATTACHMENT, depth);
  2258. if(WithStencil){ tnsAttach2DOffscreenBuffer(toff, GL_STENCIL_ATTACHMENT, depth); }
  2259. }
  2260. return toff;
  2261. }
  2262. tnsOffscreen *tnsCreateDeferredOffscreen(int w, int h, int Multisample){
  2263. tnsOffscreen *toff = tnsCreateOffscreenHandle();
  2264. tnsTexture *color,*normal,*gpos; tnsTexture *depth;
  2265. color = tnsCreate2DTexture(GL_RGBA8, w, h, Multisample); tnsAttach2DOffscreenBuffer(toff, GL_COLOR_ATTACHMENT0, color);
  2266. normal = tnsCreate2DTexture(GL_RGB8, w, h, Multisample); tnsAttach2DOffscreenBuffer(toff, GL_COLOR_ATTACHMENT1, normal);
  2267. gpos = tnsCreate2DTexture(GL_RGB32F, w, h, Multisample); tnsAttach2DOffscreenBuffer(toff, GL_COLOR_ATTACHMENT2, gpos);
  2268. depth = tnsCreate2DTexture(GL_DEPTH_COMPONENT, w, h, Multisample); tnsAttach2DOffscreenBuffer(toff, GL_DEPTH_ATTACHMENT, depth);
  2269. return toff;
  2270. }
  2271. void tnsRecreateFBO(tnsOffscreen *off){
  2272. if(off->FboContext){
  2273. #ifdef __linux__
  2274. SYSWINDOW sw=T->CurrentWindow; SYSGLCONTEXT sc=T->CurrentContext; void* gls=0;
  2275. #ifdef LA_USE_GLES
  2276. gls=&T->CurrentSurface;
  2277. #endif
  2278. tnsContextMakeFBOCurrent(off);
  2279. glDeleteFramebuffers(1, &off->FboHandle);
  2280. tnsContextMakeCurrent(sc,sw,gls);
  2281. off->FboContext=sc; off->FboWindow=sw;
  2282. #endif
  2283. #ifdef _WIN32
  2284. SYSTEMDC sd=T->CurrentDC; SYSGLCONTEXT sc=T->CurrentContext;
  2285. tnsContextMakeFBOCurrent(off);
  2286. glDeleteFramebuffers(1, &off->FboHandle);
  2287. tnsContextMakeCurrent(sc,sd,0);
  2288. off->FboContext=sc; off->FboDC=sd;
  2289. #endif
  2290. }
  2291. glGenFramebuffers(1, &off->FboHandle);
  2292. if(off->pColor[0]) tnsAttach2DOffscreenBuffer(off, GL_COLOR_ATTACHMENT0, off->pColor[0]);
  2293. if(off->pColor[1]) tnsAttach2DOffscreenBuffer(off, GL_COLOR_ATTACHMENT1, off->pColor[1]);
  2294. if(off->pColor[2]) tnsAttach2DOffscreenBuffer(off, GL_COLOR_ATTACHMENT2, off->pColor[2]);
  2295. if(off->pColor[3]) tnsAttach2DOffscreenBuffer(off, GL_COLOR_ATTACHMENT3, off->pColor[3]);
  2296. if(off->pDepth){ tnsAttach2DOffscreenBuffer(off, GL_DEPTH_ATTACHMENT, off->pDepth);
  2297. if(off->pDepth->GLTexBitsType==GL_DEPTH_STENCIL) tnsAttach2DOffscreenBuffer(off, GL_STENCIL_ATTACHMENT, off->pDepth);
  2298. }
  2299. }
  2300. void tnsEnsureOffscreenContext(tnsOffscreen *off){
  2301. if(off->FboContext!=T->CurrentContext){ tnsRecreateFBO(off); }
  2302. }
  2303. void tnsEnsureOffscreenStatus(tnsOffscreen *off, int w, int h){
  2304. tnsTexture* t=off->pColor[0];
  2305. tnsEnsureOffscreenContext(off);
  2306. if(t->Width==w && t->Height==h) return;
  2307. t->Width = w; t->Height = h; tnsConfigure2DTexture(t);
  2308. if((t=off->pColor[1])){ t->Width = w; t->Height = h; tnsConfigure2DTexture(t); }
  2309. if((t=off->pColor[2])){ t->Width = w; t->Height = h; tnsConfigure2DTexture(t); }
  2310. if((t=off->pColor[3])){ t->Width = w; t->Height = h; tnsConfigure2DTexture(t); }
  2311. if((t=off->pDepth)){ t->Width = w; t->Height = h; tnsConfigure2DTexture(t); }
  2312. }
  2313. void tnsDelete2DOffscreen(tnsOffscreen *o){
  2314. if (!o) return;
  2315. glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
  2316. tnsEnsureOffscreenContext(o);
  2317. for(int i=0;i<16;i++){
  2318. if(o->pColor[i]){
  2319. tnsDetach2DOffscreenBuffer(o, GL_COLOR_ATTACHMENT0+i);
  2320. tnsDeleteTexture(o->pColor[0]);
  2321. }
  2322. }
  2323. if(o->pDepth){
  2324. tnsDetach2DOffscreenBuffer(o, GL_DEPTH_ATTACHMENT);
  2325. tnsDeleteTexture(o->pDepth);
  2326. }
  2327. glDeleteFramebuffers(1, &o->FboHandle);
  2328. lstRemoveItem(&T->Offscreens, o);
  2329. FreeMem(o);
  2330. }
  2331. void tnsDrawToOffscreen(tnsOffscreen *toff, int HowMany, GLuint *AttachmentArray){
  2332. if (!toff) return;
  2333. glBindFramebuffer(GL_DRAW_FRAMEBUFFER, toff->FboHandle);
  2334. if(AttachmentArray==TNS_ATTACHMENT_ARRAY_NONE){glDrawBuffer(GL_NONE);}
  2335. else glDrawBuffers((HowMany ? HowMany : 1), (AttachmentArray ? AttachmentArray : TNS_ATTACHMENT_ARRAY));
  2336. T->IsOffscreen = 1;
  2337. T->BindedShader = 0;
  2338. }
  2339. void tnsDrawToOffscreenOnlyBind(tnsOffscreen *toff, int HowMany, GLuint *AttachmentArray){
  2340. if (!toff) return;
  2341. glBindFramebuffer(GL_DRAW_FRAMEBUFFER, toff->FboHandle);
  2342. }
  2343. void tnsReadFromOffscreen(tnsOffscreen *toff){
  2344. if (!toff) return;
  2345. glBindFramebuffer(GL_READ_FRAMEBUFFER, toff->FboHandle);
  2346. }
  2347. void tnsDrawToScreen(){
  2348. glBindFramebuffer(GL_FRAMEBUFFER, 0);
  2349. //glDrawBuffer(GL_BACK); printf("%d\n", glGetError());
  2350. T->IsOffscreen = 0;
  2351. T->BindedShader = 0;
  2352. }
  2353. //===========================================================================[FONT]
  2354. tnsFontManager *FM;
  2355. void tnsSetuptnsFontManager(){
  2356. FM = CreateNew(tnsFontManager);
  2357. FM->BufferWidth = TNS_FONT_BUFFER_W_DEFAULT;
  2358. FM->L = INT_MIN; FM->R = INT_MAX; FM->B = INT_MAX; FM->U = INT_MIN;
  2359. };
  2360. void tnsQuitFontManager(){
  2361. tnsInvalidateFontCache();
  2362. tnsFont*f=FM->UsingFont;
  2363. for(int i=0;i<f->NumFaces;i++){
  2364. FT_Done_Face(f->ftface[i]);
  2365. }
  2366. if(f->ftfacemono) FT_Done_Face(f->ftfacemono);
  2367. FT_Done_FreeType(f->ftlib);
  2368. free(f->characters);
  2369. free(f->monocharacters);
  2370. free(f);
  2371. FreeMem(FM);
  2372. }
  2373. int next_p2(int a){
  2374. int rval = 1;
  2375. while (rval < a)
  2376. rval <<= 1;
  2377. return rval;
  2378. }
  2379. real tnsGetMonoFontAdvance(){
  2380. return FM->UsingFont->MonoAdvance;
  2381. }
  2382. int tnsInvalidateFontCache(){
  2383. tnsFont*f=FM->UsingFont;
  2384. for(int i=0;i<TNS_UNICODE_COUNT;i++){ if(f->characters[i]){ free(f->characters[i]); f->characters[i]=0; } }
  2385. for(int i=0;i<TNS_MONO_COUNT;i++){ if(f->monocharacters[i]){ free(f->monocharacters[i]); f->monocharacters[i]=0; } }
  2386. f->CurrentX=f->CurrentY=0;
  2387. f->height = LA_RH*(MAIN.FontSize/2.0f+0.5f);
  2388. int GenHeight=LA_RH*MAIN.FontSize;
  2389. for(int i=0;i<f->NumFaces;i++){
  2390. FT_Set_Char_Size(f->ftface[i], 0, GenHeight << 6, 96, 96);
  2391. FT_Glyph glyph; int half_adv=0;
  2392. if(!FT_Get_Advance(f->ftface[i],'a',FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP, &half_adv)){
  2393. if (FT_Load_Char(f->ftface[i], 'a', FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP)||
  2394. FT_Get_Glyph(f->ftface[i]->glyph, &glyph)){ SEND_PANIC_ERROR("Monospace font doesn't contain character 'a'"); }
  2395. f->MonoAdvance=(real)f->ftface[i]->glyph->advance.x/64.0;
  2396. if(glyph) FT_Done_Glyph(glyph);
  2397. }
  2398. }
  2399. if(f->ftfacemono){
  2400. FT_Set_Char_Size(f->ftfacemono, 0, (GenHeight << 6)*f->MonoScale, 96, 96); FT_Glyph glyph;
  2401. if (FT_Load_Char(f->ftfacemono, 'a', FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP)||
  2402. FT_Get_Glyph(f->ftfacemono->glyph, &glyph)){ SEND_PANIC_ERROR("Monospace font doesn't contain character 'a'"); }
  2403. f->MonoAdvance=(real)f->ftfacemono->glyph->advance.x/64.0;
  2404. if(glyph) FT_Done_Glyph(glyph);
  2405. }
  2406. #ifndef LA_USE_GLES
  2407. if(glClearTexImage) glClearTexImage(f->TexBuffer.GLTexHandle, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
  2408. #endif
  2409. }
  2410. tnsFontSingleCharacter *tfntFetchCharTextureIDW(uint32_t ch, int UseMono);
  2411. #ifndef LAGUI_FONT_CUSTOM_PATH
  2412. #define LAGUI_FONT_CUSTOM_PATH "/usr/share/fonts/opentype/noto/"
  2413. #endif
  2414. const char* TNS_FONT_CUSTOM=LAGUI_FONT_CUSTOM_PATH;
  2415. const char* TNS_FONT_LOAD_OPTIONS[9]={"","fonts/","lagui/fonts/","../","../fonts/","../lagui/fonts/","../../","../../fonts/","../../lagui/fonts/"};
  2416. const char* TNS_FONT_LOAD_OPTIONS_FROM_HOME[2]={".local/share/fonts/lagui/",".local/share/fonts/"};
  2417. int tnsLoadSystemFontMono(char* from, char* mono){
  2418. char buf[8192]; if(!FM->UsingFont || !mono || !mono[0]) return 0;
  2419. tnsFont *f=FM->UsingFont;
  2420. int GenHeight=LA_RH*MAIN.FontSize;
  2421. int full_adv=0,half_adv=0;
  2422. for(int i=0;i<f->NumFaces;i++){
  2423. if(!FT_Get_Advance(f->ftface[i],U'我',FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP, &full_adv)) break;
  2424. }
  2425. for(int i=-2;i<11;i++){
  2426. char* option;
  2427. if(i==-2){ sprintf(buf,"%s%s%s",TNS_FONT_CUSTOM,TNS_FONT_CUSTOM[strlen(TNS_FONT_CUSTOM)-1]=='/'?"":"/",mono); }
  2428. elif(i<9){ option=(i==-1)?from:TNS_FONT_LOAD_OPTIONS[i]; sprintf(buf,"%s%s%s",MAIN.WorkingDirectory->Ptr,option,mono); }
  2429. else{ option=TNS_FONT_LOAD_OPTIONS_FROM_HOME[i-9]; sprintf(buf,"%s/%s%s",getenv("HOME"),option,mono); }
  2430. if (FT_New_Face(f->ftlib, buf, 0, &f->ftfacemono)) continue;
  2431. FT_Select_Charmap(f->ftfacemono, FT_ENCODING_UNICODE);
  2432. FT_Set_Char_Size(f->ftfacemono, 0, GenHeight << 6, 96, 96);
  2433. logPrint("Loaded monospace font: %s\n",buf);
  2434. if(!FT_Get_Advance(f->ftfacemono,'a',FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP, &half_adv)){
  2435. f->MonoScale=(real)full_adv/(half_adv*2);
  2436. FT_Set_Char_Size(f->ftfacemono, 0, (GenHeight << 6)*f->MonoScale, 96, 96);
  2437. logPrint("Monospace font scale: %.2f\n",f->MonoScale); FT_Glyph glyph;
  2438. if (FT_Load_Char(f->ftfacemono, 'a', FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP)||
  2439. FT_Get_Glyph(f->ftfacemono->glyph, &glyph)){ SEND_PANIC_ERROR("Monospace font doesn't contain character 'a'"); }
  2440. f->MonoAdvance=(real)f->ftfacemono->glyph->advance.x/64.0;
  2441. if(glyph) FT_Done_Glyph(glyph);
  2442. }
  2443. return 1;
  2444. }
  2445. return 0;
  2446. };
  2447. int tnsLoadSystemFont(char* from, char* name){
  2448. char buf[8192];
  2449. tnsFont *f=FM->UsingFont; if(!f){
  2450. f = CreateNew(tnsFont);
  2451. f->characters=calloc(1, sizeof(tnsFontSingleCharacter*)*TNS_UNICODE_COUNT);
  2452. f->monocharacters=calloc(1, sizeof(tnsFontSingleCharacter*)*TNS_MONO_COUNT);
  2453. f->height = LA_RH*(MAIN.FontSize/2.0f+0.5f);
  2454. tnsInit2DTexture(&f->TexBuffer, GL_R8, FM->BufferWidth, FM->BufferWidth, 0);
  2455. lstAppendItem(&FM->Fonts, f); FM->UsingFont=f;
  2456. if (FT_Init_FreeType(&f->ftlib)) SEND_PANIC_ERROR("Freetype Init Failed!");
  2457. logPrintNew("Loading fonts...\n");
  2458. }
  2459. int GenHeight=LA_RH*MAIN.FontSize;
  2460. for(int i=-2;i<11;i++){
  2461. char* option;
  2462. if(i==-2){ sprintf(buf,"%s%s%s",TNS_FONT_CUSTOM,TNS_FONT_CUSTOM[strlen(TNS_FONT_CUSTOM)-1]=='/'?"":"/",name); }
  2463. elif(i<9){ option=(i==-1)?from:TNS_FONT_LOAD_OPTIONS[i]; sprintf(buf,"%s%s%s",MAIN.WorkingDirectory->Ptr,option,name); }
  2464. else{ option=TNS_FONT_LOAD_OPTIONS_FROM_HOME[i-9]; sprintf(buf,"%s/%s%s",getenv("HOME"),option,name); }
  2465. FT_Face face; FT_Long i,num_faces; FT_Open_Args args; args.flags=FT_OPEN_PATHNAME; args.pathname=buf;
  2466. if(FT_Open_Face(f->ftlib, &args, -1, &face )) continue;
  2467. num_faces = face->num_faces; FT_Done_Face(face); int found=0;
  2468. for(int fa=0;fa<num_faces;fa++){
  2469. if(FT_Open_Face(f->ftlib,&args,fa,&face)){ continue; }
  2470. if(strstr(face->family_name,"SC")){ found=1; break; }
  2471. FT_Done_Face(face);
  2472. }
  2473. if(found){ f->ftface[f->NumFaces]=face; }else{ if (FT_New_Face(f->ftlib, buf, 0, &f->ftface[f->NumFaces])) continue; }
  2474. FT_Select_Charmap(f->ftface[f->NumFaces], FT_ENCODING_UNICODE);
  2475. FT_Set_Char_Size(f->ftface[f->NumFaces], 0, GenHeight << 6, 96, 96);
  2476. f->NumFaces++; FT_Glyph glyph; int half_adv=0;
  2477. if(!f->MonoAdvance && !FT_Get_Advance(f->ftface[f->NumFaces],'a',FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP, &half_adv)){
  2478. FT_Set_Char_Size(f->ftface[f->NumFaces], 0, (GenHeight << 6)*f->MonoScale, 96, 96);
  2479. if (FT_Load_Char(f->ftface[f->NumFaces], 'a', FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP)||
  2480. FT_Get_Glyph(f->ftface[f->NumFaces]->glyph, &glyph)){ SEND_PANIC_ERROR("Monospace font doesn't contain character 'a'"); }
  2481. f->MonoAdvance=(real)f->ftface[f->NumFaces]->glyph->advance.x/64.0;
  2482. if(glyph) FT_Done_Glyph(glyph);
  2483. }
  2484. logPrint("Loaded font: %s\n",buf);
  2485. return 1;
  2486. }
  2487. return 0;
  2488. };
  2489. int tfntBufferWidthEnough(int total_width, int current_width, int this_width){
  2490. return (current_width + this_width +1 < total_width);
  2491. }
  2492. void tfntResizeFontTexture(tnsFont* f, int size){
  2493. FM->BufferWidth=size;
  2494. f->TexBuffer.Width=f->TexBuffer.Height=FM->BufferWidth;
  2495. tnsConfigure2DTexture(&f->TexBuffer);
  2496. }
  2497. void tfntApplyCharacterBufferOffset(tnsFont *f, tnsFontSingleCharacter *fsc){
  2498. if (!tfntBufferWidthEnough(FM->BufferWidth, f->CurrentX, fsc->width)){
  2499. f->CurrentY += (f->height+1);
  2500. f->CurrentX = 0;
  2501. }
  2502. fsc->bufferx = f->CurrentX;
  2503. fsc->buffery = f->CurrentY;
  2504. f->CurrentX += (fsc->width+1);
  2505. }
  2506. tnsFontSingleCharacter *tfntFetchCharTextureIDW(uint32_t ch, int UseMono){
  2507. GLuint revel = 0;
  2508. tnsFont *f = FM->UsingFont;
  2509. tnsFontSingleCharacter **use_fsc=UseMono?f->monocharacters:f->characters, *fsc = 0;
  2510. FT_Glyph glyph = 0;
  2511. FT_BitmapGlyph bitmap_glyph;
  2512. FT_Bitmap bm;
  2513. FT_Face face;
  2514. int w, h, i, j;
  2515. GLubyte *buf = 0;
  2516. if (!f) return 0;
  2517. if(ch>TNS_MONO_COUNT){ UseMono=0; use_fsc=f->characters; }
  2518. if(ch>TNS_UNICODE_COUNT){ return 0; }
  2519. fsc = use_fsc[ch];
  2520. if(!fsc){ fsc=use_fsc[ch]=calloc(1,sizeof(tnsFontSingleCharacter)); }
  2521. if (revel = fsc->Generated) return fsc;
  2522. if(UseMono && f->ftfacemono){
  2523. face = f->ftfacemono;
  2524. if(!FT_Get_Char_Index(face,ch)){return 0;}
  2525. if (FT_Load_Char(face, ch, FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP)){ return 0; }
  2526. if (FT_Get_Glyph(face->glyph, &glyph)){ return 0; }
  2527. }else{
  2528. for(int i=0;i<f->NumFaces;i++){
  2529. if(!f->ftface[i]){continue;}
  2530. face = f->ftface[i];
  2531. if(!FT_Get_Char_Index(face,ch)){continue;}
  2532. if (FT_Load_Char(face, ch, FT_LOAD_TARGET_NORMAL | FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP)){ continue; }
  2533. if (FT_Get_Glyph(face->glyph, &glyph)){ continue; }
  2534. break;
  2535. }
  2536. if(!glyph){ return 0; }
  2537. }
  2538. FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
  2539. FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1);
  2540. bitmap_glyph = glyph;
  2541. bm = bitmap_glyph->bitmap;
  2542. w = bm.width;
  2543. h = bm.rows;
  2544. fsc->width = w;
  2545. fsc->height = h;
  2546. fsc->advx = (real)face->glyph->advance.x / 64.0f;
  2547. fsc->advy = face->size->metrics.y_ppem;
  2548. fsc->deltax = bitmap_glyph->left;
  2549. fsc->deltay = bitmap_glyph->top - h;
  2550. tfntApplyCharacterBufferOffset(f, fsc);
  2551. if(fsc->buffery+h>=FM->BufferWidth){
  2552. tfntResizeFontTexture(f,FM->BufferWidth*2); tnsInvalidateFontCache();
  2553. FreeMem(buf); FT_Done_Glyph(glyph);
  2554. return tfntFetchCharTextureIDW(ch,UseMono);
  2555. }
  2556. tnsBindTexture(&f->TexBuffer);
  2557. //glBindTexture(GL_TEXTURE_2D, f->TexBuffer.GLTexHandle);
  2558. buf = CreateNewBuffer(GLubyte, w * h);
  2559. for (j = 0; j < h; j++){
  2560. for (i = 0; i < w; i++){
  2561. char _vl = bm.buffer[i + w * j];
  2562. buf[i + (h - j - 1) * w] = _vl;
  2563. }
  2564. }
  2565. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  2566. glTexSubImage2D(GL_TEXTURE_2D, 0, fsc->bufferx, fsc->buffery, w, h, GL_RED, GL_UNSIGNED_BYTE, buf);
  2567. FreeMem(buf);
  2568. FT_Done_Glyph(glyph);
  2569. fsc->Generated = 1;
  2570. return fsc;
  2571. }
  2572. tnsFontSingleCharacter *tfntFetchCharacterW(uint32_t ch, int UseMono){
  2573. tnsFontSingleCharacter* fsc = tfntFetchCharTextureIDW(ch, UseMono);
  2574. if(fsc) return fsc;
  2575. return tfntFetchCharTextureIDW('?', UseMono);
  2576. }
  2577. int CMP_NAME_IsThisFont(tnsFont *enumed, char *name){
  2578. return (!strcmp(enumed->fontName, name));
  2579. };
  2580. void tnsPushStringClip(int L, int R, int U, int B){
  2581. tnsStringClip *sc=memAcquire(sizeof(tnsStringClip)); lstPushItem(&FM->StringClips, sc);
  2582. sc->L=FM->L; sc->R=FM->R; sc->U=FM->U; sc->B=FM->B;
  2583. FM->L=L; FM->R=R; FM->U=U; FM->B=B;
  2584. }
  2585. void tnsPopStringClip(){
  2586. tnsStringClip *sc=lstPopItem(&FM->StringClips);
  2587. if(!sc){ FM->L = INT_MIN; FM->R = INT_MAX; FM->B = INT_MAX; FM->U = INT_MIN; }
  2588. FM->L=sc->L; FM->R=sc->R; FM->U=sc->U; FM->B=sc->B;
  2589. };
  2590. int tnsStringGetDimension(char* content, uint32_t* contentU, int Count, int WLimit, int* Rows, int UseMono){
  2591. if((!MAIN.CurrentWindow)||(!MAIN.CurrentWindow->win)) return 0;
  2592. real sx = 0; int sy = FM->UsingFont->height; real MA=FM->UsingFont->MonoAdvance;
  2593. int i, rows=1, advance=1;
  2594. int C = 0;
  2595. int len = contentU?strlenU(contentU):(content?strlen(content):0);
  2596. char hb;
  2597. int RestoreI;
  2598. int MaxSX=0;
  2599. if(!WLimit){WLimit=INT_MAX;}
  2600. int UC=1;
  2601. for (i = 0; i < len && UC; i+=advance){
  2602. UC = contentU?contentU[i]:laToUnicode(&content[i], &advance);
  2603. tnsFontSingleCharacter *fsc;
  2604. if (UC == U'\n'){
  2605. if(sx>MaxSX) MaxSX=sx;
  2606. sx = 0; sy += LA_RH; rows++;
  2607. continue;
  2608. }else{
  2609. fsc = tfntFetchCharacterW(UC, UseMono);
  2610. real dx=fsc->advx; if(UseMono){ dx/=MA; if(dx<1.01) dx=1; if(dx>1.01)dx=2; dx*=MA; }
  2611. if(sx+dx > WLimit){ sx = 0; sy += LA_RH; rows++; }
  2612. sx += dx;
  2613. C += 1;
  2614. if (Count && C == Count) break;
  2615. }
  2616. }
  2617. if(sx==0 && rows>1){rows--;}
  2618. if(sx>MaxSX) MaxSX=sx;
  2619. if(Rows) (*Rows)=rows;
  2620. return MaxSX+1;
  2621. }
  2622. int tnsStringGetWidth(char *content, int Count, int UseMono){
  2623. return tnsStringGetDimension(content, 0, Count, 0, 0, UseMono);
  2624. }
  2625. int tnsStringGetWidthU(uint32_t *contentU, int Count, int UseMono){
  2626. return tnsStringGetDimension(0, contentU, Count, 0, 0, UseMono);
  2627. }
  2628. int tnsDrawLCD7_ProgressSystem(real x, real y, real Percent){
  2629. real hgap=LA_RH/15; real vgap=LA_RH/5;
  2630. real MA=FM->UsingFont->MonoAdvance;
  2631. real w=MA-hgap*2, h=LA_RH-vgap*2; y+=vgap; x+=hgap-MA; real shear=h/12;
  2632. TNS_CLAMP(Percent,0,1);
  2633. char str[10]; sprintf(str,"%d",(int)(Percent*100)); int len=strlen(str);
  2634. for(int i=len-1;i>=0;i--){
  2635. int uc=str[i];
  2636. if(uc>='0' && uc<='9'){ uc-='0'; }
  2637. else { continue; }
  2638. for(int i=0;i<7;i++){
  2639. if(TNS_LCD_MAP_7[uc][i]){
  2640. real* seg=TNS_LCD_SEG_7[i];
  2641. real s1=tnsInterpolate(shear,-shear,seg[1]); real s2=tnsInterpolate(shear,-shear,seg[3]);
  2642. #ifdef __linux__
  2643. XDrawLine(MAIN.dpy,MAIN.Progress.w,MAIN.Progress.gc,
  2644. tnsInterpolate(x+s1,x+w+s1,seg[0]),tnsInterpolate(y,y+h,seg[1]),
  2645. tnsInterpolate(x+s2,x+w+s2,seg[2]),tnsInterpolate(y,y+h,seg[3]));
  2646. #endif
  2647. #ifdef _WIN32
  2648. MoveToEx(MAIN.Progress.hdc,tnsInterpolate(x+s1,x+w+s1,seg[0]),tnsInterpolate(y,y+h,seg[1]),0);
  2649. LineTo(MAIN.Progress.hdc,tnsInterpolate(x+s2,x+w+s2,seg[2]),tnsInterpolate(y,y+h,seg[3]));
  2650. #endif
  2651. }
  2652. }
  2653. x-=MA;
  2654. }
  2655. return 1;
  2656. return 0;
  2657. }
  2658. int tnsMakeLCD7(real x, real y, real w, real h, real shear, int ch){
  2659. int uc=ch;
  2660. if(ch>='0' && ch<='9'){ uc-='0'; }
  2661. else {return 0;}
  2662. for(int i=0;i<7;i++){
  2663. if(TNS_LCD_MAP_7[uc][i]){
  2664. real* seg=TNS_LCD_SEG_7[i];
  2665. real s1=tnsInterpolate(shear,-shear,seg[1]); real s2=tnsInterpolate(shear,-shear,seg[3]);
  2666. tnsVertex2d(tnsInterpolate(x+s1,x+w+s1,seg[0]),tnsInterpolate(y,y+h,seg[1]));
  2667. tnsVertex2d(tnsInterpolate(x+s2,x+w+s2,seg[2]),tnsInterpolate(y,y+h,seg[3]));
  2668. }
  2669. }
  2670. return 1;
  2671. }
  2672. int tnsMakeLCD16(real x, real y, real w, real h, real shear, int ch){
  2673. int uc=ch;
  2674. if(ch>='0' && ch<='9'){ uc-='0'; }
  2675. elif(ch>='A' && ch<='Z'){ uc-='A'; uc+=10; }
  2676. elif(ch>='a' && ch<='z'){ uc-='a'; uc+=(10+26); }
  2677. else {return 0;}
  2678. for(int i=0;i<16;i++){
  2679. if(TNS_LCD_MAP_16[uc][i]){
  2680. real* seg=TNS_LCD_SEG_16[i];
  2681. real s1=tnsInterpolate(shear,-shear,seg[1]); real s2=tnsInterpolate(shear,-shear,seg[3]);
  2682. tnsVertex2d(tnsInterpolate(x+s1,x+w+s1,seg[0]),tnsInterpolate(y,y+h,seg[1]));
  2683. tnsVertex2d(tnsInterpolate(x+s2,x+w+s2,seg[2]),tnsInterpolate(y,y+h,seg[3]));
  2684. }
  2685. }
  2686. return 1;
  2687. }
  2688. void tnsDrawStringLCD(char *content, uint32_t* contentU, real Color[4], int L, int R, int T, int Flags, real Scale){
  2689. if(Scale<1e-5) return;
  2690. real MA=FM->UsingFont->MonoAdvance;
  2691. real sx = L; int sy = T; real dx=MA; real hgap=LA_RH/15; real vgap=LA_RH/5;
  2692. int i,advance=1;
  2693. int len = contentU?strlenU(contentU):strlen(content);
  2694. int RevY=(Flags&LA_TEXT_REVERT_Y); int TH=LA_RH-vgap*2; real shear=TH/12;
  2695. if(RevY){ TH*=-1; vgap*=-1; } TH*=Scale;dx*=Scale;hgap*=Scale;vgap*=Scale;shear*=Scale;
  2696. int OneLine=(Flags&LA_TEXT_ONE_LINE);
  2697. int Use16=(Flags&LA_TEXT_LCD_16);
  2698. tnsFlush();
  2699. tnsUseNoTexture();
  2700. int any=0, UC=1; int BreakNow=0;
  2701. for (i = 0; i < len && UC; i+=advance){
  2702. UC = contentU?contentU[i]:laToUnicode(&content[i], &advance);
  2703. if (UC == U'\n'){ if(!OneLine){sx = L; sy += LA_RH; continue;}else{ UC=' '; } }
  2704. if (sx + dx > R+1){
  2705. if(Flags&LA_TEXT_LINE_WRAP){ sx=L; sy+=LA_RH; }else{ break; }
  2706. }
  2707. if(Use16){
  2708. if(tnsMakeLCD16(sx+hgap, sy+vgap, dx-hgap*2, TH, shear, UC)) any=1;
  2709. }else{
  2710. if(tnsMakeLCD7(sx+hgap, sy+vgap, dx-hgap*2, TH, shear, UC)) any=1;
  2711. }
  2712. sx += dx;
  2713. if(BreakNow){ break; }
  2714. }
  2715. if(any){ tnsColor4dv(Color); tnsPackAs(GL_LINES); }
  2716. }
  2717. //arr[0] = x1;
  2718. //arr[1] = y1;
  2719. //arr[2] = x2;
  2720. //arr[3] = y2;
  2721. //arr[4] = x3;
  2722. //arr[5] = y3;
  2723. //arr[6] = x2;
  2724. //arr[7] = y2;
  2725. //arr[8] = x3;
  2726. //arr[9] = y3;
  2727. //arr[10] = x4;
  2728. //arr[11] = y4;
  2729. int tns_ClipCharacterT2D(real* v, real* t){
  2730. real l=v[0]; if(l>FM->R) return 0; real r=v[4]; if(r<FM->L) return 0;
  2731. real u=v[1]; if(u>FM->B) return 0; real b=v[3]; if(b<FM->U) return 0;
  2732. real tl=t[0],tr=t[4],tu=t[1],tb=t[3];
  2733. if(l<FM->L){ real p=((real)FM->L-l)/(r-l); t[0]+=p*(tr-tl); t[6]=t[2]=t[0]; v[6]=v[2]=v[0]=FM->L; }
  2734. if(r>FM->R){ real p=(r-(real)FM->R)/(r-l); t[4]-=p*(tr-tl); t[8]=t[10]=t[4]; v[8]=v[10]=v[4]=FM->R; }
  2735. if(u<FM->U){ real p=((real)FM->U-u)/(b-u); t[1]+=p*(tb-tu); t[5]=t[9]=t[1]; v[5]=v[9]=v[1]=FM->U; }
  2736. if(b>FM->B){ real p=(b-(real)FM->B)/(b-u); t[3]-=p*(tb-tu); t[7]=t[11]=t[3]; v[7]=v[11]=v[3]=FM->B; }
  2737. return 1;
  2738. }
  2739. void tnsDrawStringM(char *content, uint32_t* contentU, real Color[4], int L, int R, int T, int Flags){
  2740. if(Flags&(LA_TEXT_LCD_16|LA_TEXT_LCD_7)){
  2741. tnsDrawStringLCD(content,contentU,Color,L,R,T,Flags,1.0); return;
  2742. }
  2743. real sx = L; int sy = (LA_RH!=LA_RH0)?(((((real)FM->UsingFont->height/LA_RH0-0.5)/MAIN.UiScale)+0.5)*LA_RH + T):(FM->UsingFont->height+T);
  2744. real MA=FM->UsingFont->MonoAdvance;
  2745. int i,advance=1;
  2746. int len = contentU?strlenU(contentU):(content?strlen(content):0); if(!len) return;
  2747. real xo, yo, xl, yl;
  2748. real TexCoord[12];
  2749. real VertArr[12];
  2750. int total_width = 0;
  2751. tnsFont *f = FM->UsingFont;
  2752. int FscHeight, RestoreI;
  2753. int RevY=(Flags&LA_TEXT_REVERT_Y);
  2754. int UseMono=(Flags&LA_TEXT_MONO);
  2755. int OneLine=(Flags&LA_TEXT_ONE_LINE);
  2756. if(Color) tnsColor4dv(Color);
  2757. int any=0, UC=1; int BreakNow=0;
  2758. for (i = 0; i < len && UC; i+=advance){
  2759. UC = contentU?contentU[i]:laToUnicode(&content[i], &advance);
  2760. tnsFontSingleCharacter *fsc;
  2761. real cx, cy;
  2762. if (UC == U'\n'){ if(!OneLine){sx = L; sy += LA_RH; continue;}else{ UC=' '; } }
  2763. fsc = tfntFetchCharacterW(UC, Flags&LA_TEXT_MONO);
  2764. real dx=fsc->advx; if(UseMono){ dx/=MA; if(dx<1.01) dx=1; if(dx>1.01)dx=2; dx*=MA; }
  2765. if (sx + dx > R+1){
  2766. if(Flags&LA_TEXT_LINE_WRAP){
  2767. sx=L; sy+=LA_RH;
  2768. }else{
  2769. if(Flags&LA_TEXT_OVERFLOW_ARROW){ fsc = tfntFetchCharacterW(U'▷', 0); sx=R-fsc->advx; BreakNow=1; }
  2770. else break;
  2771. }
  2772. }
  2773. cx = sx + fsc->deltax;
  2774. cy = sy - fsc->deltay;
  2775. xo = (real)fsc->bufferx / (real)FM->BufferWidth;
  2776. yo = (real)fsc->buffery / (real)FM->BufferWidth;
  2777. xl = (real)(fsc->bufferx + fsc->width) / (real)FM->BufferWidth;
  2778. yl = (real)(fsc->buffery + fsc->height) / (real)FM->BufferWidth;
  2779. tnsMakeQuadT2d(TexCoord, xo, yl, xo, yo, xl, yl, xl, yo);
  2780. if (RevY) tnsMakeQuadT2d(VertArr,
  2781. cx, 2 * T - cy + fsc->height,
  2782. cx, 2 * T - cy,
  2783. cx + fsc->width, 2 * T - cy + fsc->height,
  2784. cx + fsc->width, 2 * T - cy);
  2785. else tnsMakeQuadT2d(VertArr,
  2786. cx, +cy - fsc->height,
  2787. cx, +cy,
  2788. cx + fsc->width, +cy - fsc->height,
  2789. cx + fsc->width, +cy);
  2790. if(tns_ClipCharacterT2D(VertArr,TexCoord)){
  2791. tnsUseMaskTexture(&f->TexBuffer);
  2792. tnsVertexArray2d(VertArr, 6);
  2793. tnsTexCoordArray2d(TexCoord, 6);
  2794. any=1;
  2795. }
  2796. sx += dx;
  2797. if(BreakNow){ break; }
  2798. }
  2799. if(any) tnsPackAs(GL_TRIANGLES);
  2800. }
  2801. void tnsDrawStringAutoM(char *content, uint32_t* contentU, real Color[4], int L, int R, int T, int Flags){
  2802. int LL;
  2803. int al = Flags&LA_TEXT_ALIGN;
  2804. if (!content && !contentU) return;
  2805. switch (al){
  2806. case LA_TEXT_ALIGN_AUTO:
  2807. case LA_TEXT_ALIGN_CENTER: LL = L+(R-L-tnsStringGetDimension(content, contentU, 0, 0, 0, Flags&LA_TEXT_MONO)) / 2; if(LL<L) LL=L; break;
  2808. default:
  2809. case LA_TEXT_ALIGN_LEFT: LL = L; break;
  2810. case LA_TEXT_ALIGN_RIGHT: LL = R-(tnsStringGetDimension(content, contentU, 0, 0, 0, Flags&LA_TEXT_MONO)); if(LL<L) LL=L; break;
  2811. }
  2812. tnsDrawStringM(content, contentU, Color, LL, R, T, Flags);
  2813. }
  2814. void tnsDrawStringAuto(char *content, real Color[4], int L, int R, int T, int Flags){
  2815. tnsDrawStringAutoM(content,0,Color,L,R,T,Flags);
  2816. }
  2817. void tnsDrawStringWithPriority(char *Label, char *MajorContent, real Color[4], int TextAlign, int L, int R, int T, int Flags){
  2818. int W = R - L;
  2819. int Str1W = tnsStringGetWidth(Label, 0, Flags&LA_TEXT_MONO);
  2820. int Str2W = tnsStringGetWidth(MajorContent, 0, Flags&LA_TEXT_MONO);
  2821. if (Str1W + Str2W > W){
  2822. if (Str2W < W){
  2823. tnsDrawStringM(MajorContent, 0, Color, R - Str2W, R, T, Flags);
  2824. tnsDrawStringM(Label, 0, Color, L, R - Str2W, T, Flags);
  2825. }else
  2826. tnsDrawStringM(MajorContent, 0, Color, L, R, T, Flags);
  2827. }else{
  2828. int LL = L, ML;
  2829. switch (Flags&LA_TEXT_ALIGN){
  2830. case LA_TEXT_ALIGN_CENTER:
  2831. ML = L + Str1W + (W - (Str1W + Str2W)) / 2;
  2832. break;
  2833. case LA_TEXT_ALIGN_LEFT:
  2834. ML = L + Str1W;
  2835. break;
  2836. default:
  2837. case LA_TEXT_ALIGN_AUTO:
  2838. case LA_TEXT_ALIGN_RIGHT:
  2839. ML = R - Str2W;
  2840. break;
  2841. }
  2842. tnsDrawStringM(Label, 0, Color, LL, R, T, Flags);
  2843. tnsDrawStringM(MajorContent, 0, Color, ML, R, T, Flags);
  2844. }
  2845. }
  2846. void tnsDrawIcon(uint32_t ID, real Color[4], int L,int R, int T, int Flags){
  2847. char buf[5]={0}; char* next; laToUTF8(ID,buf,&next);
  2848. tnsDrawStringAuto(buf, Color, L,R,T,Flags);
  2849. }
  2850. //=====================================================================================[Object]
  2851. tnsObject *tnsFindObject(char *Name, tnsObject *FromObj){
  2852. tnsObject *io; tnsObject *ro;
  2853. laListHandle* l=FromObj?(&FromObj->ChildObjects):(&T->World->AllObjects);
  2854. for (laListItemPointer*lip=l->pFirst;lip;lip=lip->pNext){
  2855. io=((l==&T->World->AllObjects)?lip:lip->p); if (strSame(io->Name->Ptr, Name)){ return io; }
  2856. if (ro = tnsFindObject(Name, io)) return ro;
  2857. }
  2858. return 0;
  2859. }
  2860. void tnsExtractDeltaTransformValue(tnsObject *o){
  2861. if (!o) return;
  2862. tnsExtractLocation44d(o->DeltaTransform, o->DLocation);
  2863. tnsExtractXYZEuler44d(o->DeltaTransform, o->DRotation);
  2864. tnsExtractScale44d(o->DeltaTransform, o->DScale);
  2865. }
  2866. void tnsExtractSelfTransformValue(tnsObject *o){
  2867. if (!o) return;
  2868. tnsExtractLocation44d(o->SelfTransform, o->Location);
  2869. tnsExtractXYZEuler44d(o->SelfTransform, o->Rotation);
  2870. tnsExtractScale44d(o->SelfTransform, o->Scale);
  2871. }
  2872. void tnsExtractGlobalTransformValue(tnsObject *o){
  2873. if (!o) return;
  2874. tnsExtractLocation44d(o->GlobalTransform, o->GLocation);
  2875. tnsExtractXYZEuler44d(o->GlobalTransform, o->GRotation);
  2876. tnsExtractScale44d(o->GlobalTransform, o->GScale);
  2877. }
  2878. void tnsCopyGlobalTransform(tnsObject *to, tnsObject *from){
  2879. memcpy(to->GlobalTransform, from->GlobalTransform, sizeof(tnsMatrix44d));
  2880. memcpy(to->GLocation, from->GLocation, sizeof(tnsVector3d));
  2881. memcpy(to->GRotation, from->GRotation, sizeof(tnsVector3d));
  2882. memcpy(to->GScale, from->GScale, sizeof(tnsVector3d));
  2883. tnsGlobalTransformValueChanged(to);
  2884. }
  2885. void tnsSelfMatrixChanged(tnsObject* o, int ApplyToChild){
  2886. tnsMatrix44d mix;
  2887. if (!o->ParentObject){
  2888. tnsMultiply44d(mix, o->SelfTransform, o->DeltaTransform);
  2889. memcpy(o->GlobalTransform, mix, sizeof(tnsMatrix44d));
  2890. }
  2891. else{
  2892. tnsMultiply44d(mix, o->ParentObject->GlobalTransform, o->SelfTransform);
  2893. tnsMultiply44d(o->GlobalTransform, mix, o->DeltaTransform);
  2894. }
  2895. tnsExtractDeltaTransformValue(o);
  2896. tnsExtractSelfTransformValue(o);
  2897. tnsExtractGlobalTransformValue(o); tnsInvalidateEvaluation(o);
  2898. if(ApplyToChild) for (laListItemPointer* li=o->ChildObjects.pFirst;li;li=li->pNext){ tnsSelfMatrixChanged(li->p,1); }
  2899. }
  2900. void tnsGlobalMatrixChanged(tnsObject* o, int ApplyToChild){
  2901. tnsMatrix44d self,invd;
  2902. if (!o->ParentObject){ memcpy(self, o->GlobalTransform, sizeof(tnsMatrix44d)); }
  2903. else{ tnsMatrix44d inv;
  2904. tnsInverse44d(inv, o->ParentObject->GlobalTransform);
  2905. tnsMultiply44d(self, inv, o->GlobalTransform); }
  2906. tnsInverse44d(invd, o->DeltaTransform);
  2907. tnsMultiply44d(o->SelfTransform, self, invd);
  2908. tnsExtractSelfTransformValue(o);
  2909. tnsExtractGlobalTransformValue(o); tnsInvalidateEvaluation(o);
  2910. if(ApplyToChild) for (laListItemPointer* li=o->ChildObjects.pFirst;li;li=li->pNext){ tnsSelfMatrixChanged(li->p,1); }
  2911. }
  2912. void tnsGlobalMatrixChangedForDelta(tnsObject* o, int ApplyToChild){
  2913. tnsMatrix44d invs, invp, tmp;
  2914. if (!o->ParentObject){ tnsLoadIdentity44d(invp); }
  2915. else{ tnsInverse44d(invp, o->ParentObject->GlobalTransform); }
  2916. tnsInverse44d(invs, o->SelfTransform);
  2917. tnsMultiply44d(tmp, invs, invp);
  2918. tnsMultiply44d(o->DeltaTransform, tmp, o->GlobalTransform);
  2919. tnsExtractDeltaTransformValue(o);
  2920. //tnsExtractSelfTransformValue(o);
  2921. tnsExtractGlobalTransformValue(o); tnsInvalidateEvaluation(o);
  2922. if(ApplyToChild) for (laListItemPointer* li=o->ChildObjects.pFirst;li;li=li->pNext){ tnsSelfMatrixChanged(li->p,1); }
  2923. }
  2924. void tnsSelfTransformValueChanged(tnsObject* o){
  2925. tnsMatrix44d Trans, Rot1, Rot2, Rot3, Scale, Res1, Res2;
  2926. tnsLoadIdentity44d(o->SelfTransform);
  2927. tnsMakeTranslationMatrix44d(Trans, LA_COLOR3(o->Location));
  2928. if(o->Scale[0]<1e-5){ o->Scale[0]=1e-5; }
  2929. if(o->Scale[1]<1e-5){ o->Scale[1]=1e-5; }
  2930. if(o->Scale[2]<1e-5){ o->Scale[2]=1e-5; }
  2931. tnsMakeScaleMatrix44d(Scale, LA_COLOR3(o->Scale));
  2932. tnsMakeRotationXMatrix44d(Rot1, o->Rotation[0]);
  2933. tnsMakeRotationYMatrix44d(Rot2, o->Rotation[1]);
  2934. tnsMakeRotationZMatrix44d(Rot3, o->Rotation[2]);
  2935. switch (o->RotationMode){
  2936. case TNS_ROTATION_ZYX_EULER: tnsMultiply44d(Res1, Trans, Rot1); tnsMultiply44d(Res2, Res1, Rot2); tnsMultiply44d(Res1, Res2, Rot3); break;
  2937. case TNS_ROTATION_XZY_EULER: tnsMultiply44d(Res1, Trans, Rot1); tnsMultiply44d(Res2, Res1, Rot3); tnsMultiply44d(Res1, Res2, Rot2); break;
  2938. case TNS_ROTATION_YXZ_EULER: tnsMultiply44d(Res1, Trans, Rot2); tnsMultiply44d(Res2, Res1, Rot1); tnsMultiply44d(Res1, Res2, Rot3); break;
  2939. case TNS_ROTATION_YZX_EULER: tnsMultiply44d(Res1, Trans, Rot2); tnsMultiply44d(Res2, Res1, Rot3); tnsMultiply44d(Res1, Res2, Rot1); break;
  2940. case TNS_ROTATION_ZXY_EULER: tnsMultiply44d(Res1, Trans, Rot3); tnsMultiply44d(Res2, Res1, Rot1); tnsMultiply44d(Res1, Res2, Rot2); break;
  2941. case TNS_ROTATION_XYZ_EULER: tnsMultiply44d(Res1, Trans, Rot3); tnsMultiply44d(Res2, Res1, Rot2); tnsMultiply44d(Res1, Res2, Rot1); break;
  2942. }
  2943. tnsMultiply44d(o->SelfTransform, Res1, Scale);
  2944. tnsSelfMatrixChanged(o,1);
  2945. }
  2946. void tnsDeltaTransformValueChanged(tnsObject* o){
  2947. tnsMatrix44d Trans, Rot1, Rot2, Rot3, Scale, Res1, Res2;
  2948. tnsLoadIdentity44d(o->DeltaTransform);
  2949. tnsMakeTranslationMatrix44d(Trans, LA_COLOR3(o->DLocation));
  2950. tnsMakeScaleMatrix44d(Scale, LA_COLOR3(o->DScale));
  2951. tnsMakeRotationXMatrix44d(Rot1, o->DRotation[0]);
  2952. tnsMakeRotationYMatrix44d(Rot2, o->DRotation[1]);
  2953. tnsMakeRotationZMatrix44d(Rot3, o->DRotation[2]);
  2954. switch (o->RotationMode){
  2955. case TNS_ROTATION_ZYX_EULER: tnsMultiply44d(Res1, Trans, Rot1); tnsMultiply44d(Res2, Res1, Rot2); tnsMultiply44d(Res1, Res2, Rot3); break;
  2956. case TNS_ROTATION_XZY_EULER: tnsMultiply44d(Res1, Trans, Rot1); tnsMultiply44d(Res2, Res1, Rot3); tnsMultiply44d(Res1, Res2, Rot2); break;
  2957. case TNS_ROTATION_YXZ_EULER: tnsMultiply44d(Res1, Trans, Rot2); tnsMultiply44d(Res2, Res1, Rot1); tnsMultiply44d(Res1, Res2, Rot3); break;
  2958. case TNS_ROTATION_YZX_EULER: tnsMultiply44d(Res1, Trans, Rot2); tnsMultiply44d(Res2, Res1, Rot3); tnsMultiply44d(Res1, Res2, Rot1); break;
  2959. case TNS_ROTATION_ZXY_EULER: tnsMultiply44d(Res1, Trans, Rot3); tnsMultiply44d(Res2, Res1, Rot1); tnsMultiply44d(Res1, Res2, Rot2); break;
  2960. case TNS_ROTATION_XYZ_EULER: tnsMultiply44d(Res1, Trans, Rot3); tnsMultiply44d(Res2, Res1, Rot2); tnsMultiply44d(Res1, Res2, Rot1); break;
  2961. }
  2962. tnsMultiply44d(o->DeltaTransform, Res1, Scale);
  2963. tnsSelfMatrixChanged(o,1);
  2964. }
  2965. void tnsGlobalTransformValueChanged(tnsObject* o){
  2966. tnsMatrix44d Trans, Rot1, Rot2, Rot3, Scale, Res1, Res2;
  2967. tnsLoadIdentity44d(o->GlobalTransform);
  2968. tnsMakeTranslationMatrix44d(Trans, LA_COLOR3(o->GLocation));
  2969. tnsMakeScaleMatrix44d(Scale, LA_COLOR3(o->GScale));
  2970. tnsMakeRotationXMatrix44d(Rot1, o->GRotation[0]);
  2971. tnsMakeRotationYMatrix44d(Rot2, o->GRotation[1]);
  2972. tnsMakeRotationZMatrix44d(Rot3, o->GRotation[2]);
  2973. switch (o->RotationMode){
  2974. case TNS_ROTATION_ZYX_EULER: tnsMultiply44d(Res1, Trans, Rot1); tnsMultiply44d(Res2, Res1, Rot2); tnsMultiply44d(Res1, Res2, Rot3); break;
  2975. case TNS_ROTATION_XZY_EULER: tnsMultiply44d(Res1, Trans, Rot1); tnsMultiply44d(Res2, Res1, Rot3); tnsMultiply44d(Res1, Res2, Rot2); break;
  2976. case TNS_ROTATION_YXZ_EULER: tnsMultiply44d(Res1, Trans, Rot2); tnsMultiply44d(Res2, Res1, Rot1); tnsMultiply44d(Res1, Res2, Rot3); break;
  2977. case TNS_ROTATION_YZX_EULER: tnsMultiply44d(Res1, Trans, Rot2); tnsMultiply44d(Res2, Res1, Rot3); tnsMultiply44d(Res1, Res2, Rot1); break;
  2978. case TNS_ROTATION_ZXY_EULER: tnsMultiply44d(Res1, Trans, Rot3); tnsMultiply44d(Res2, Res1, Rot1); tnsMultiply44d(Res1, Res2, Rot2); break;
  2979. case TNS_ROTATION_XYZ_EULER: tnsMultiply44d(Res1, Trans, Rot3); tnsMultiply44d(Res2, Res1, Rot2); tnsMultiply44d(Res1, Res2, Rot1); break;
  2980. }
  2981. tnsMultiply44d(o->GlobalTransform, Res1, Scale);
  2982. tnsGlobalMatrixChanged(o,1);
  2983. }
  2984. void tnsSetCurrentRoot(tnsObject *o){
  2985. if(o->Type!=TNS_OBJECT_ROOT) return;
  2986. memAssignRef(T->World, &T->World->ActiveRoot, o);
  2987. }
  2988. void tnsInitObjectBase(tnsObject *o, tnsObject *under, char *Name, int Type,
  2989. real AtX, real AtY, real AtZ,
  2990. real RotX, real RotY, real RotZ, real RotW, u8bit RotationMode,
  2991. real Scale){
  2992. if (!o) return;
  2993. strSafeSet(&o->Name, Name);
  2994. o->Type = Type;
  2995. tnsVectorSet3(o->Location,AtX,AtY,AtZ);
  2996. tnsVectorSet4(o->Rotation,RotX,RotY,RotZ,RotW); o->RotationMode = RotationMode;
  2997. tnsVectorSet3(o->Scale,Scale,Scale,Scale);
  2998. o->Show = 1;
  2999. o->DrawMode = GL_LINE_LOOP;
  3000. tnsLoadIdentity44d(o->DeltaTransform);
  3001. tnsSelfTransformValueChanged(o);
  3002. lstAppendItem(&T->World->AllObjects, o);
  3003. if (under){ lstAppendPointer(&under->ChildObjects, o); int isroot=(under->Type==TNS_OBJECT_ROOT);
  3004. tnsObject* root=isroot?under:under->InRoot; memAssignRef(o, &o->InRoot, root);
  3005. if(!isroot){ o->ParentObject=under; }
  3006. }
  3007. }
  3008. int tnsCheckParentable(tnsObject* child, tnsObject* parent){
  3009. if(child==parent||parent->ParentObject==child)return 0; tnsObject* o=parent; while(o=o->ParentObject){ if(o==parent) return 0; } return 1;
  3010. }
  3011. void tnsParentObject(tnsObject *child, tnsObject *parent, int KeepTransform){
  3012. if (!child || !parent || child->ParentObject==parent || parent->ParentObject==child || parent==child) return;
  3013. if (child->ParentObject) lstRemovePointerLeave(&child->ParentObject->ChildObjects, child);
  3014. else lstRemovePointerLeave(&child->InRoot->ChildObjects, child);
  3015. lstAppendPointer(&parent->ChildObjects, child);
  3016. memAssignRef(child, &child->ParentObject, parent);
  3017. if(KeepTransform) tnsGlobalMatrixChanged(child, 1);
  3018. else tnsSelfMatrixChanged(child, 1);
  3019. }
  3020. void tnsUnparentObject(tnsObject *o, int KeepTransform){
  3021. if (!o || !o->ParentObject) return;
  3022. lstRemovePointerLeave(&o->ParentObject->ChildObjects, o);
  3023. lstAppendPointer(&o->InRoot->ChildObjects, o);
  3024. memAssignRef(o, &o->ParentObject, 0);
  3025. if(KeepTransform) tnsGlobalMatrixChanged(o,1);
  3026. else tnsSelfMatrixChanged(o,1);
  3027. }
  3028. void tnsCopyObjectTransformationsLocal(tnsObject* to, tnsObject* from){
  3029. tnsVectorCopy3d(from->Location, to->Location);
  3030. tnsVectorCopy3d(from->Rotation, to->Rotation); to->RotationMode=from->RotationMode;
  3031. tnsVectorCopy3d(from->Scale, to->Scale);
  3032. tnsSelfTransformValueChanged(to);
  3033. }
  3034. void tnsCopyObjectTransformationsGlobal(tnsObject* to, tnsObject* from){
  3035. tnsVectorCopy3d(from->GLocation, to->GLocation);
  3036. tnsVectorCopy3d(from->GRotation, to->GRotation); to->RotationMode=from->RotationMode;
  3037. tnsVectorCopy3d(from->GScale, to->GScale);
  3038. tnsGlobalTransformValueChanged(to);
  3039. }
  3040. void tnsRotateObjectLocalValues(tnsObject *o, real x, real y, real z){
  3041. o->Rotation[0] += x; o->Rotation[1] += y; o->Rotation[2] += z;
  3042. tnsSelfTransformValueChanged(o);
  3043. }
  3044. void tnsSetObjectPositionLocal(tnsObject*o, real x, real y, real z){
  3045. tnsVectorSet3(o->Location,x,y,z); tnsSelfTransformValueChanged(o);
  3046. }
  3047. void tnsResetObjectTransformations(tnsObject* o, int reset_loc,int reset_rot,int reset_sca){
  3048. if(reset_loc){ tnsVectorSet3(o->Location,0,0,0); }
  3049. if(reset_rot){ tnsVectorSet4(o->Rotation,0,0,0,0); }
  3050. if(reset_sca){ tnsVectorSet3(o->Rotation,1,1,1); }
  3051. tnsSelfTransformValueChanged(o);
  3052. }
  3053. void tnsMoveObjectLocal(tnsObject *o, real x, real y, real z){
  3054. tnsMatrix44d mat, res1, res2, res3;
  3055. tnsMakeTranslationMatrix44d(res2, x, y, z);
  3056. tnsMultiply44d(res1, o->SelfTransform, res2);
  3057. memcpy(o->SelfTransform, res1, sizeof(tnsMatrix44d));
  3058. tnsSelfMatrixChanged(o,1);
  3059. }
  3060. void tnsMoveObjectDelta(tnsObject *o, real x, real y, real z){
  3061. tnsMatrix44d mat, res1, res2, res3;
  3062. tnsMakeTranslationMatrix44d(res2, x, y, z);
  3063. tnsMultiply44d(res1, o->DeltaTransform, res2);
  3064. memcpy(o->DeltaTransform, res1, sizeof(tnsMatrix44d));
  3065. tnsExtractDeltaTransformValue(o);
  3066. tnsSelfMatrixChanged(o,1);
  3067. }
  3068. void tnsMoveObjectGlobal(tnsObject *o, real x, real y, real z){
  3069. tnsMatrix44d mat, res1, res2, res3;
  3070. tnsMakeTranslationMatrix44d(res2, x, y, z);
  3071. tnsMultiply44d(res1, res2, o->GlobalTransform); //if reverse then local
  3072. memcpy(o->GlobalTransform, res1, sizeof(tnsMatrix44d));
  3073. tnsGlobalMatrixChanged(o,1);
  3074. }
  3075. void tnsMoveObjectGlobalForDelta(tnsObject *o, real x, real y, real z){
  3076. tnsMatrix44d mat, res1, res2, res3;
  3077. tnsMakeTranslationMatrix44d(res2, x, y, z);
  3078. tnsMultiply44d(res1, res2, o->GlobalTransform); //if reverse then local
  3079. memcpy(o->GlobalTransform, res1, sizeof(tnsMatrix44d));
  3080. tnsGlobalMatrixChangedForDelta(o,1);
  3081. }
  3082. void tnsRotateObjectGlobal(tnsObject *o, real x, real y, real z, real angle, real cx,real cy,real cz){
  3083. tnsMatrix44d tback,tfwd,rot,rot2,res1,res2;
  3084. real xs, ys, zs;
  3085. tnsMakeRotationMatrix44d(rot,angle,x,y,z);
  3086. tnsMakeRotationMatrix44d(rot2,-angle,x,y,z);//why?
  3087. tnsMakeTranslationMatrix44d(tfwd, o->GLocation[0],o->GLocation[1],o->GLocation[2]);
  3088. tnsInverse44d(tback,tfwd);
  3089. tnsMultiply44d(res1,o->GlobalTransform,tback);
  3090. tnsMultiply44d(res2,rot,res1);
  3091. tnsMultiply44d(o->GlobalTransform,res2,tfwd);
  3092. tnsVector3d delta; delta[0]=o->GLocation[0]-cx; delta[1]=o->GLocation[1]-cy; delta[2]=o->GLocation[2]-cz;
  3093. tnsVector3d c; c[0]=cx; c[1]=cy; c[2]=cz; tnsVector3d r;
  3094. tnsApplyRotation43d(r,rot2,delta);
  3095. tnsVectorPlus3d(&o->GlobalTransform[12],c,r);
  3096. //memcpy(o->GlobalTransform, res1, sizeof(tnsMatrix44d));
  3097. tnsGlobalMatrixChanged(o,1);
  3098. }
  3099. void tnsRotateObjectLocal(tnsObject *o, real x, real y, real z, real angle){
  3100. tnsMatrix44d tback,tfwd,rot,res1,res2;
  3101. //tnsVector3d gp,gpt; gp[0]=gcx; gp[1]=gcy; gp[2]=gcz;
  3102. //tnsMakeTranslationMatrix44d(tfwd, gcx, gcy, gcz);
  3103. //tnsInverse44d(tback,tfwd);
  3104. tnsMakeRotationMatrix44d(rot,angle,x,y,z);
  3105. //tnsMultiply44d(res1,o->SelfTransform,tback);
  3106. //tnsMultiply44d(res2,res1,rot);
  3107. //tnsMultiply44d(o->SelfTransform,res2,tfwd);
  3108. tnsMultiply44d(res1,o->SelfTransform,rot);
  3109. tnsCopyMatrix44d(res1,o->SelfTransform);
  3110. tnsSelfMatrixChanged(o,1);
  3111. }
  3112. void tnsRotateObjectDelta(tnsObject *o, real x, real y, real z, real angle){
  3113. tnsMatrix44d tback,tfwd,rot,res1,res2;
  3114. //tnsVector3d gp,gpt; gp[0]=gcx; gp[1]=gcy; gp[2]=gcz;
  3115. //tnsApplyTransform43d(gpt,o->DeltaTransform,gp);
  3116. //tnsMakeTranslationMatrix44d(tfwd, gpt[0]-gcx, gpt[0]-gcy, gpt[0]-gcz);
  3117. //tnsInverse44d(tback,tfwd);
  3118. //tnsMakeRotationMatrix44d(rot,angle,x,y,z);
  3119. //tnsMultiply44d(res1,o->SelfTransform,tback);
  3120. //tnsMultiply44d(res2,res1,rot);
  3121. //tnsMultiply44d(o->SelfTransform,res2,tfwd);
  3122. tnsMakeRotationMatrix44d(rot,angle,x,y,z);
  3123. tnsMultiply44d(res1,o->DeltaTransform,rot);
  3124. tnsCopyMatrix44d(res1,o->DeltaTransform);
  3125. tnsExtractDeltaTransformValue(o);
  3126. tnsSelfMatrixChanged(o,1);
  3127. }
  3128. void tnsRotateObjectGlobalForDelta(tnsObject *o, real x, real y, real z, real angle, real cx,real cy,real cz){
  3129. tnsMatrix44d tback,tfwd,rot,rot2,res1,res2;
  3130. real xs, ys, zs;
  3131. tnsMakeRotationMatrix44d(rot,angle,x,y,z);
  3132. tnsMakeRotationMatrix44d(rot2,-angle,x,y,z);//why?
  3133. tnsMakeTranslationMatrix44d(tfwd, o->GLocation[0],o->GLocation[1],o->GLocation[2]);
  3134. tnsInverse44d(tback,tfwd);
  3135. tnsMultiply44d(res1,o->GlobalTransform,tback);
  3136. tnsMultiply44d(res2,rot,res1);
  3137. tnsMultiply44d(o->GlobalTransform,res2,tfwd);
  3138. tnsVector3d delta; delta[0]=o->GLocation[0]-cx; delta[1]=o->GLocation[1]-cy; delta[2]=o->GLocation[2]-cz;
  3139. tnsVector3d c; c[0]=cx; c[1]=cy; c[2]=cz; tnsVector3d r;
  3140. tnsApplyRotation43d(r,rot2,delta);
  3141. tnsVectorPlus3d(&o->GlobalTransform[12],c,r);
  3142. //memcpy(o->GlobalTransform, res1, sizeof(tnsMatrix44d));
  3143. tnsGlobalMatrixChangedForDelta(o,1);
  3144. }
  3145. void tnsScaleObject(tnsObject *o, real x,real y,real z, real cx,real cy,real cz){
  3146. tnsMatrix44d sca,res1,res2;
  3147. tnsMakeScaleMatrix44d(sca,x,y,z);
  3148. tnsMultiply44d(res1,o->GlobalTransform,sca);
  3149. tnsVector3d delta; delta[0]=res1[12]-cx; delta[1]=res1[13]-cy; delta[2]=res1[14]-cz;
  3150. tnsVector3d c; c[0]=cx; c[1]=cy; c[2]=cz;
  3151. delta[0]*=x; delta[1]*=y; delta[2]*=z;
  3152. tnsVectorPlus3d(&res1[12],c,delta);
  3153. memcpy(o->GlobalTransform, res1, sizeof(tnsMatrix44d));
  3154. tnsGlobalMatrixChanged(o,1);
  3155. }
  3156. void tnsScaleObjectDelta(tnsObject *o, real x,real y,real z, real cx,real cy,real cz){
  3157. tnsMatrix44d sca,res1,res2;
  3158. tnsMakeScaleMatrix44d(sca,x,y,z);
  3159. tnsMultiply44d(res1,o->GlobalTransform,sca);
  3160. tnsVector3d delta; delta[0]=res1[12]-cx; delta[1]=res1[13]-cy; delta[2]=res1[14]-cz;
  3161. tnsVector3d c; c[0]=cx; c[1]=cy; c[2]=cz;
  3162. delta[0]*=x; delta[1]*=y; delta[2]*=z;
  3163. tnsVectorPlus3d(&res1[12],c,delta);
  3164. memcpy(o->GlobalTransform, res1, sizeof(tnsMatrix44d));
  3165. tnsGlobalMatrixChangedForDelta(o,1);
  3166. }
  3167. void tnsZoomViewingCamera(tnsCamera *c, real Ratio){
  3168. if (c->FocusDistance < 0.1 && Ratio > 0) return;
  3169. tnsMoveObjectLocal(c, 0, 0, -c->FocusDistance * Ratio);
  3170. c->FocusDistance *= (1 - Ratio);
  3171. }
  3172. void tnsRotateViewingCamera(tnsCamera *c, real x, real z){
  3173. tnsMoveObjectLocal(c, 0, 0, -c->FocusDistance);
  3174. tnsRotateObjectLocalValues(c, x, 0, z);
  3175. tnsMoveObjectLocal(c, 0, 0, c->FocusDistance);
  3176. }
  3177. void tnsGetCameraMovingDeltas(tnsCamera *c, int ViewportW, int ViewportH, real x, real y, tnsVector4d p){
  3178. memset(p, 0, sizeof(tnsVector4d));
  3179. tnsVector4d tp = {0};
  3180. tnsMatrix44d combine, projection, projinv, vpinv, vp;
  3181. tnsLoadIdentity44d(projection);
  3182. tnsMakePerspectiveMatrix44d(projection, c->FOV, (real)ViewportW / (real)ViewportH, c->ZMin, c->ZMax);
  3183. tnsMakeViewportMatrix44d(vp, ViewportW, ViewportH, c->ZMax, c->ZMin);
  3184. tnsInverse44d(projinv, projection);
  3185. tnsInverse44d(vpinv, vp);
  3186. p[2] = -c->FocusDistance;
  3187. p[3] = 1;
  3188. tnsApplyTransform44d(tp, projection, p);
  3189. tnsVectorMultiSelf3d(tp, 1 / tp[3]);
  3190. tnsApplyTransform43d(p, vp, tp);
  3191. p[0] += x;
  3192. p[1] += y;
  3193. tnsApplyTransform43d(tp, vpinv, p);
  3194. tnsVectorMultiSelf3d(tp, tp[3]);
  3195. tnsApplyTransform44d(p, projinv, tp);
  3196. }
  3197. void tnsTranslateViewingCamera(tnsCamera *c, int ViewportW, int ViewportH, real x, real y){
  3198. tnsVector4d p={0};
  3199. tnsGetCameraMovingDeltas(c,ViewportW, ViewportH, x,y,p);
  3200. tnsMoveObjectLocal(c, p[0], p[1], 0);
  3201. }
  3202. tnsObject *tnsCreateRootObject(char *name, int Use2D){
  3203. tnsWorld *w = T->World;
  3204. tnsRootObject *o = memAcquireHyper(sizeof(tnsRootObject));
  3205. o->Base.Type==TNS_OBJECT_ROOT;
  3206. strSafeSet(&o->Base.Name, name);
  3207. lstAppendItem(&w->RootObjects, o);
  3208. memAssignRef(w,&w->ActiveRoot,o);
  3209. o->Base.Drivers=memAcquire(sizeof(laRackPageCollection));
  3210. o->Is2D=Use2D;
  3211. laAnimationUpdateHolderList();
  3212. return o;
  3213. }
  3214. void tnsDestroyRootObject(tnsObject *root){
  3215. tnsWorld *w = T->World;
  3216. memAssignRef(w,&w->ActiveRoot,root->Item.pPrev ? root->Item.pPrev : root->Item.pNext ? root->Item.pNext : 0);
  3217. root->Evaluated.Done=root->EvaluatedPlay.Done=0;
  3218. tnsFreeEvaluatedArray(&root->Evaluated);
  3219. tnsClearPlayDuplicate(root);
  3220. if(root->EvaluatedPlay.Commands) tnsFreeEvaluatedArray(&root->EvaluatedPlay);
  3221. tnsFreeEvaluatedScene(&root->EvaluatedPlay);
  3222. //destroy rack page; and then release memory;
  3223. laRackPage*rp;
  3224. while(rp=lstPopItem(&root->Drivers->Pages)){
  3225. laNodeRack* rr; while(rr=lstPopItem(&rp->Racks)){ laDestroyRack(rr); }
  3226. memLeave(rp);
  3227. }
  3228. memLeave(root->Drivers); // root->Drivers=0; never reset address for single, see la_GiveDiffCommand()
  3229. tnsRootObject* ro=root; laAction* aa; laActionProp* ap;
  3230. while(aa=ro->Actions.pFirst){ laAnimationRemoveAction(aa); }
  3231. while(ap=lstPopItem(&ro->ActionProps)){ strSafeDestroy(&ap->CachedName); memLeave(ap); }
  3232. lstRemoveItem(&w->RootObjects, root);
  3233. tnsObject*co;
  3234. while(co=lstPopPointerLeave(&root->ChildObjects)){ tnsDestroyObject(co); }
  3235. strSafeDestroy(&root->Name);
  3236. memLeave(root);
  3237. laAnimationUpdateHolderList();
  3238. }
  3239. void tnsDestroyObject(tnsObject *o){
  3240. if(o->Type==TNS_OBJECT_ROOT){ tnsDestroyRootObject(o); return; }
  3241. tnsFreeEvaluatedArray(&o->Evaluated);
  3242. tnsClearPlayDuplicate(o);
  3243. if(o->EvaluatedPlay.Commands) tnsFreeEvaluatedArray(&o->EvaluatedPlay);
  3244. tnsFreeEvaluatedScene(&o->EvaluatedPlay);
  3245. tnsUnparentObject(o,1);
  3246. while(o->ChildObjects.pFirst){ tnsUnparentObject(((laListItemPointer*)o->ChildObjects.pFirst)->p, 1); }
  3247. lstRemoveItem(&T->World->AllObjects, o);
  3248. if(o->InRoot){ lstRemovePointerLeave(&o->InRoot->ChildObjects, o);
  3249. tnsInvalidateEvaluation(o);
  3250. if(o->InRoot->Active==o){ memAssignRef(o->InRoot,&o->InRoot->Active,0); }
  3251. }
  3252. if(o->Type==TNS_OBJECT_MESH){ tnsMeshObject* mo=o;
  3253. if(mo->v) arrFree(&mo->v, &mo->maxv); if(mo->e) arrFree(&mo->e, &mo->maxe);
  3254. if(mo->f){ for(int i=0;i<mo->totf;i++){ free(mo->f[i].loop); mo->f[i].loop=0; } arrFree(&mo->f, &mo->maxf); }
  3255. mo->totv=mo->tote=mo->totf=0;
  3256. tnsInvalidateMeshBatch(o);
  3257. tnsMaterialSlot* ms; while(ms=lstPopItem(&mo->Materials)){ memLeave(ms); } memAssignRef(mo,&mo->CurrentMaterial,0);
  3258. }
  3259. if(o->Type==TNS_OBJECT_SHAPE){ tnsShapeObject* so=o;
  3260. tnsShape* s; while(s=lstPopItem(&so->Shapes)){ tnsSPoint* sp; while(sp=lstPopItem(&s->Points)){ memLeave(sp); } memLeave(s); }
  3261. tnsMaterialSlot* ms; while(ms=lstPopItem(&so->Materials)){ memLeave(ms); } memAssignRef(so,&so->CurrentMaterial,0);
  3262. }
  3263. strSafeDestroy(&o->Name);
  3264. memLeave(o);
  3265. }
  3266. tnsCamera *tnsCreateCamera(tnsObject *under, char *Name, real FOV,
  3267. real AtX, real AtY, real AtZ,
  3268. real RotX, real RotY, real RotZ,
  3269. real FocusDistance){
  3270. tnsCamera *c; tnsWorld *w = T->World;
  3271. c = memAcquireHyper(sizeof(tnsCamera));
  3272. tnsInitObjectBase(&c->Base, under, Name, TNS_OBJECT_CAMERA, AtX, AtY, AtZ, RotX, RotY, RotZ, 1.0f, TNS_ROTATION_XYZ_EULER, 1.0f);
  3273. c->FOV = FOV;
  3274. c->CameraType = TNS_CAMERA_PERSP;
  3275. c->ZMin = 0.1f;
  3276. c->ZMax = 200.0f;
  3277. c->FocusDistance = FocusDistance;
  3278. c->OrthScale = 1.0f;
  3279. if(under && under->Type==TNS_OBJECT_ROOT){ memAssignRef(under,&((tnsRootObject*)under)->ActiveCamera,c); }
  3280. return c;
  3281. }
  3282. tnsObject *tnsCreateInstancer(tnsObject *under, char *Name, real AtX, real AtY, real AtZ){
  3283. tnsObject *o; tnsWorld *w = T->World; if (!under) return 0;
  3284. o = memAcquireHyper(sizeof(tnsInstancer));
  3285. tnsInitObjectBase(o, under, Name, TNS_OBJECT_INSTANCER, AtX, AtY, AtZ, 0, 0, 0, 1.0f, TNS_ROTATION_XYZ_EULER, 1.0f);
  3286. return o;
  3287. }
  3288. tnsLight *tnsCreateLight(tnsObject *under, char *Name, real AtX, real AtY, real AtZ, real Strength, int UniDirectional){
  3289. tnsLight *l; tnsWorld *w = T->World; if (!under) return 0;
  3290. tnsObject* root=under->Type==TNS_OBJECT_ROOT?under:under->InRoot;
  3291. if (UniDirectional&&under){
  3292. if(root){ if(root->ParentObject) return root->ParentObject; }
  3293. }
  3294. l = memAcquireHyper(sizeof(tnsLight));
  3295. tnsInitObjectBase(&l->Base, under, Name, TNS_OBJECT_LIGHT, AtX, AtY, AtZ, 0, 0, 0, 1.0f, TNS_ROTATION_XYZ_EULER, 1.0f);
  3296. l->Strength = Strength;
  3297. l->UniDirectional = UniDirectional;
  3298. // ?????????? WTF
  3299. //if (root && UniDirectional && !root->ParentObject) memAssignRef(root, &root->ParentObject,l);
  3300. return l;
  3301. }
  3302. tnsInstancer* tnsDuplicateInstancer(tnsInstancer* from){
  3303. if(from->Base.Type!=TNS_OBJECT_INSTANCER) return 0; tnsInstancer* to = memAcquireHyper(sizeof(tnsInstancer));
  3304. tnsInitObjectBase(to, from->Base.ParentObject?from->Base.ParentObject:from->Base.InRoot, from->Base.Name->Ptr, TNS_OBJECT_INSTANCER,0,0,0,0,0,0,0,0,1);
  3305. tnsCopyObjectTransformationsLocal(to,from);
  3306. to->Instance=from->Instance;
  3307. return to;
  3308. }
  3309. int tnsSizeOfObject(tnsObject* o){
  3310. switch(o->Type){
  3311. case TNS_OBJECT_ROOT: return sizeof(tnsRootObject);
  3312. case TNS_OBJECT_INSTANCER: return sizeof(tnsInstancer);
  3313. case TNS_OBJECT_MESH: return sizeof(tnsMeshObject);
  3314. case TNS_OBJECT_CAMERA: return sizeof(tnsCamera);
  3315. case TNS_OBJECT_LIGHT: return sizeof(tnsLight);
  3316. case TNS_OBJECT_SHAPE: return sizeof(tnsShapeObject);
  3317. default: return sizeof(tnsObject);
  3318. }
  3319. }
  3320. tnsObject* tnsDuplicateObject(tnsObject* o){
  3321. tnsMeshObject* to = memAcquireHyper(tnsSizeOfObject(o));
  3322. tnsInitObjectBase(to, o->ParentObject?o->ParentObject:o->InRoot, o->Name->Ptr, TNS_OBJECT_MESH,0,0,0,0,0,0,0,0,1);
  3323. tnsCopyObjectTransformationsLocal(to,o);
  3324. }
  3325. int tnsAnyObjectsSelected(tnsObject *root){
  3326. for(laListItemPointer* lip=root->ChildObjects.pFirst;lip;lip=lip->pNext){ tnsObject* o=lip->p; if(o->Flags&TNS_OBJECT_FLAGS_SELECTED) return 1;
  3327. if(o->ChildObjects.pFirst && tnsAnyObjectsSelected(o)) return 1;
  3328. } return 0;
  3329. }
  3330. void tnsDeselectAllObjects(tnsObject *root){
  3331. for(laListItemPointer* lip=root->ChildObjects.pFirst;lip;lip=lip->pNext){ tnsObject* o=lip->p; o->Flags&=(~TNS_OBJECT_FLAGS_SELECTED);
  3332. if(o->ChildObjects.pFirst)tnsDeselectAllObjects(o);
  3333. }
  3334. memAssignRef(root,&root->Active,0);
  3335. tnsInvalidateEvaluation(root);
  3336. }
  3337. void tnsSelectAllObjects(tnsObject *root){
  3338. for(laListItemPointer* lip=root->ChildObjects.pFirst;lip;lip=lip->pNext){ tnsObject* o=lip->p; o->Flags|=TNS_OBJECT_FLAGS_SELECTED;
  3339. if(o->ChildObjects.pFirst)tnsSelectAllObjects(o);
  3340. }
  3341. tnsInvalidateEvaluation(root);
  3342. }
  3343. void tnsSelectObject(tnsObject* o, int Select, int Toggle){
  3344. if(!o) return;
  3345. if(Toggle) tnsSelectObject(o,(o->Flags&TNS_OBJECT_FLAGS_SELECTED?0:1),0);
  3346. elif(Select) o->Flags|=TNS_OBJECT_FLAGS_SELECTED; else o->Flags&=(~TNS_OBJECT_FLAGS_SELECTED);
  3347. tnsInvalidateEvaluation(o);
  3348. }
  3349. void tnsGetCameraProjection(tnsMatrix44d* mat, int w, int h, tnsCamera* Camera){
  3350. tnsMatrix44d inv, result;
  3351. tnsMakePerspectiveMatrix44d(mat, Camera->FOV, (real)w / (real)h, Camera->ZMin, Camera->ZMax);
  3352. }
  3353. void tnsGetCameraViewProjection(tnsMatrix44d* mat, int w, int h, tnsCamera* Camera){
  3354. tnsMatrix44d inv, result;
  3355. tnsMakePerspectiveMatrix44d(mat, Camera->FOV, (real)w / (real)h, Camera->ZMin, Camera->ZMax);
  3356. tnsInverse44d(inv, Camera->Base.GlobalTransform);
  3357. tnsMultiply44d(result, mat, inv);
  3358. memcpy(mat, result, sizeof(tnsMatrix44d));
  3359. }
  3360. void tnsApplyCameraView(int W, int H, tnsCamera *Camera, tnsMatrix44d out_optional_view, tnsMatrix44d out_optional_projection){
  3361. tnsMatrixStackItem *tmsi = tKnlGetCurrentMatStackItem();
  3362. tnsShader *current_shader = 0;
  3363. real *mat;
  3364. tnsMatrix44d result, inv;
  3365. if (!Camera) return;
  3366. mat = tnsGetProjectionMatrix();
  3367. tnsMakePerspectiveMatrix44d(mat, Camera->FOV, (real)W / (real)H, Camera->ZMin, Camera->ZMax);
  3368. if (current_shader = T->CurrentShader){
  3369. tnsShaderApplyProjection(current_shader, mat);
  3370. tnsShaderApplyProjectionInverse(current_shader, mat);
  3371. if(out_optional_projection){ tnsCopyMatrix44d(mat,out_optional_projection); }
  3372. }
  3373. tnsResetViewMatrix();
  3374. mat = tnsGetViewMatrix();
  3375. tnsInverse44d(inv, Camera->Base.GlobalTransform);
  3376. tnsMultiply44d(result, mat, inv);
  3377. memcpy(mat, result, sizeof(tnsMatrix44d));
  3378. tnsVector3d dir={0,0,0}; tnsSetCameraViewDir(dir);
  3379. if (current_shader = T->CurrentShader){
  3380. tnsShaderApplyView(current_shader, result);
  3381. if(out_optional_view){ tnsCopyMatrix44d(mat,out_optional_view); }
  3382. if(current_shader->uViewPos>-1) glUniform3f(current_shader->uViewPos,LA_COLOR3(Camera->Base.GLocation));
  3383. tnsVectorSet3v(T->SetViewPos,Camera->Base.GLocation);
  3384. }
  3385. }
  3386. void tnsApplyShadowCameraView(tnsLight *Light){
  3387. tnsMatrixStackItem *tmsi = tKnlGetCurrentMatStackItem();
  3388. tnsShader *current_shader = 0;
  3389. tnsMatrix44d mat;
  3390. tnsMatrix44d result, inv;
  3391. if (!Light || !Light->UniDirectional) return;
  3392. //mat = tnsGetProjectionMatrix();
  3393. tnsMakeOrthoMatrix44d(mat, -1000,1000,-1000,1000,-1000,1000);
  3394. tnsInverse44d(inv, Light->Base.GlobalTransform);
  3395. tnsMultiply44d(result, mat, inv);
  3396. memcpy(mat, result, sizeof(tnsMatrix44d));
  3397. if (current_shader = T->CurrentShader){
  3398. tnsShaderApplyShadowMatrix(current_shader,mat);
  3399. }
  3400. }
  3401. void tnsSetCameraViewDir(tnsVector3d dir){
  3402. tnsVectorSet3v(T->SetViewDir, dir);
  3403. if(T->BindedShader && T->BindedShader->uViewDir>-1){ glUniform3f(T->BindedShader->uViewDir,LA_COLOR3(dir)); }
  3404. }
  3405. void tnsApplyModelMatrix(tnsMatrix44d m){
  3406. tnsShader *current_shader = 0; real *mat;
  3407. if (!m) return;
  3408. mat = tnsGetModelMatrix();
  3409. memcpy(mat, m, sizeof(tnsMatrix44d));
  3410. if (current_shader = T->CurrentShader){ tnsShaderApplyModel(current_shader, mat); }
  3411. }
  3412. void tnsLookAt(tnsObject *o, tnsVector3d Target, tnsVector3d Up){
  3413. tnsVector4d target = {0};
  3414. tnsMatrix44d mat, res, res2;
  3415. real *d;
  3416. tnsShader *current_shader = 0;
  3417. d = tnsGetModelMatrix();
  3418. tnsMakeZTrackingMatrix44d(mat, o->GLocation, target, Up);
  3419. tnsLoadIdentity44d(res);
  3420. tnsMakeTranslationMatrix44d(res,o->GLocation[0],o->GLocation[1],o->GLocation[2]);
  3421. tnsMultiply44d(res2, res, mat);
  3422. memcpy(o->SelfTransform, res2, sizeof(tnsMatrix44d));
  3423. tnsSelfMatrixChanged(o,1);
  3424. if (current_shader = T->CurrentShader){
  3425. tnsShaderApplyModel(current_shader, d);
  3426. }
  3427. }
  3428. void tnsDrawCamera(tnsObject *o){
  3429. tnsCamera *c = o;
  3430. real fov_2 = c->FOV / 2; real len=1;
  3431. real ex, ey, ez; ey = len * sin(fov_2); ex = ey; ez = len * cos(fov_2);
  3432. tnsVertex3d(ex, ey, -ez); tnsVertex3d(ex, -ey, -ez); tnsVertex3d(0.0, 0.0, 0.0);
  3433. tnsVertex3d(ex, ey, -ez); tnsVertex3d(-ex, ey, -ez); tnsVertex3d(0.0, 0.0, 0.0);
  3434. tnsVertex3d(-ex, -ey, -ez); tnsVertex3d(-ex, ey, -ez);
  3435. tnsPackAs(GL_LINE_STRIP);
  3436. tnsVertex3d(ex,ey*1.25,-ez); tnsVertex3d(0,ey*2,-ez); tnsVertex3d(-ex,ey*1.25,-ez);
  3437. tnsPackAs(GL_LINE_LOOP);
  3438. tnsVertex3d(-ex, -ey, -ez); tnsVertex3d(ex, -ey, -ez);
  3439. tnsPackAs(GL_LINES);
  3440. }
  3441. void tnsDrawCross(real x,real y,real z,real x1,real x2,real y1,real y2,real z1,real z2){
  3442. tnsVertex3d(x+x1, y+0.0, z+0.0); tnsVertex3d(x+x2, y+0.0, z+0.0);
  3443. tnsVertex3d(x+0.0,y+ y1, z+0.0); tnsVertex3d(x+0.0,y+ y2, z+0.0);
  3444. tnsVertex3d(x+0.0,y+ 0.0,z+ z1); tnsVertex3d(x+0.0,y+ 0.0,z+ z2);
  3445. }
  3446. void tnsDrawEmptySelectionID(tnsEvaluatedInstance* ei, void* unused){
  3447. int i=ei->InstanceSelectionID; real color[4]={0,0,0,1}; TNS_ID_TO_COLOR(color,i); tnsColor4dv(color);
  3448. tnsDrawCross(0,0,0,-0.2,1,-0.2,1,-0.2,1); tnsPackAs(GL_LINES); tnsFlush();
  3449. }
  3450. void tnsDrawEmptyOutline(tnsEvaluatedInstance* ei, void* unused){
  3451. real* color=(ei->IsActive)?laAccentColor(LA_BT_TEXT):laAccentColor(LA_BT_NORMAL); tnsColor4dv(color);
  3452. tnsDrawCross(0,0,0,-0.2,1,-0.2,1,-0.2,1); tnsLineWidth(3);tnsPackAs(GL_LINES); tnsLineWidth(1); tnsFlush();
  3453. }
  3454. void tnsDrawEmptyObject(tnsEvaluatedInstance* ei, void* unused){
  3455. tnsColor4dv(laThemeColor(_LA_THEME_3D_VIEW,LA_BT_BORDER));
  3456. tnsDrawCross(0,0,0,-0.2,1,-0.2,1,-0.2,1);tnsLineWidth(3); tnsPackAs(GL_LINES); tnsLineWidth(1); tnsFlush();
  3457. }
  3458. void tnsEvaluateEmptyObject(tnsObject* o, tnsEvaluateData* ed){
  3459. if(ed->SceneEvaluateMode){ return; }
  3460. tnsAddEvaluatedInstance(ed,o,tnsDrawEmptyObject,TNS_EVAL_LAYER_SOLID,0,0,0);
  3461. if(ed->FillOutline && o->Flags&TNS_OBJECT_FLAGS_SELECTED){
  3462. tnsAddEvaluatedInstance(ed,o,tnsDrawEmptyOutline,TNS_EVAL_LAYER_OUTLINE,ed->Active==o,0,0);
  3463. }
  3464. if(ed->FillSelectionID){
  3465. tnsAddEvaluatedInstance(ed,o,tnsDrawEmptySelectionID,TNS_EVAL_LAYER_SELECTION,0,1,o->SelectID);
  3466. }
  3467. }
  3468. void tnsPushEvaluateMatrixWith(tnsEvaluateData* ed, tnsMatrix44d mat){
  3469. arrEnsureLength(&ed->MatArr,ed->NextMat,&ed->MaxMat,sizeof(tnsMatrix44d)); if(ed->NextMat<1) return;
  3470. real* new=ed->MatArr[ed->NextMat];
  3471. tnsMultiply44d(new, ed->MatArr[ed->NextMat-1], mat);
  3472. ed->NextMat++;
  3473. }
  3474. void tnsPushEvaluate2DMatrixWith(tnsEvaluateData* ed,tnsInstancer* o){
  3475. real* mat=o->Base.GlobalTransform; tnsMatrix44d tmat; int Hook=o->Hook;
  3476. if(Hook){ real X=0,Y=0;
  3477. if(Hook==TNS_INSTANCER_HOOK_TL||Hook==TNS_INSTANCER_HOOK_CL||Hook==TNS_INSTANCER_HOOK_BL){ X=-(real)ed->W/2/LA_RH; }
  3478. if(Hook==TNS_INSTANCER_HOOK_TR||Hook==TNS_INSTANCER_HOOK_CR||Hook==TNS_INSTANCER_HOOK_BR){ X=(real)ed->W/2/LA_RH; }
  3479. if(Hook==TNS_INSTANCER_HOOK_TL||Hook==TNS_INSTANCER_HOOK_TC||Hook==TNS_INSTANCER_HOOK_TR){ Y=(real)ed->H/2/LA_RH; }
  3480. if(Hook==TNS_INSTANCER_HOOK_BL||Hook==TNS_INSTANCER_HOOK_BC||Hook==TNS_INSTANCER_HOOK_BR){ Y=-(real)ed->H/2/LA_RH; }
  3481. X+=o->HookOffset[0]; Y+=o->HookOffset[1];
  3482. tnsMakeTranslationMatrix44d(tmat,X,Y,0); mat=tmat;
  3483. }
  3484. arrEnsureLength(&ed->MatArr,ed->NextMat,&ed->MaxMat,sizeof(tnsMatrix44d)); if(ed->NextMat<1) return;
  3485. real* new=ed->MatArr[ed->NextMat]; tnsCopyMatrix44d(mat,new); ed->NextMat++;
  3486. }
  3487. void tnsPopEvaluateMatrix(tnsEvaluateData* ed){ ed->NextMat--; }
  3488. void tnsEvaluateInstancerObject(tnsInstancer* o, tnsEvaluateData* ed){
  3489. int origid=ed->OverrideID; ed->OverrideID = o->Base.SelectID;
  3490. tnsEvaluateEmptyObject(o,ed);
  3491. int origoutline=ed->FillOutline; ed->FillOutline=0;
  3492. if(o->Instance){ int PrevState2D=ed->State2D;
  3493. tnsRootObject* inst=o->Instance; if(inst->Base.Type==TNS_OBJECT_ROOT&&inst->Is2D){ ed->State2D=1; }
  3494. if(ed->SceneEvaluateMode){ inst=tnsEnsurePlayDuplicate(inst); }
  3495. for(laListItemPointer* lip=ed->ParentStack.pFirst;lip;lip=lip->pNext){
  3496. if(lip->p == inst || lip->p==o->Instance){ goto eval_inst_cleanup; }
  3497. }
  3498. if(ed->State2D){ tnsPushEvaluate2DMatrixWith(ed,o); }
  3499. else{ tnsPushEvaluateMatrixWith(ed,o->Base.GlobalTransform); }
  3500. tnsEvaluateObjectTree(inst, ed, ed->SceneEvaluateMode);
  3501. tnsPopEvaluateMatrix(ed);
  3502. ed->State2D=PrevState2D;
  3503. }
  3504. eval_inst_cleanup:
  3505. ed->OverrideID=origid; ed->FillOutline=origoutline;
  3506. }
  3507. void tnsDrawCameraSelectionID(tnsEvaluatedInstance* ei, void* unused){
  3508. int i=ei->InstanceSelectionID; real color[4]={0,0,0,1}; TNS_ID_TO_COLOR(color,i); tnsColor4dv(color);
  3509. tnsDrawCamera(ei->Object); tnsFlush();
  3510. }
  3511. void tnsDrawCameraOutline(tnsEvaluatedInstance* ei, void* unused){
  3512. real* color=(ei->IsActive)?laAccentColor(LA_BT_TEXT):laAccentColor(LA_BT_NORMAL); tnsColor4dv(color); tnsLineWidth(3);
  3513. tnsDrawCamera(ei->Object); tnsLineWidth(1); tnsFlush();
  3514. }
  3515. void tnsDrawCameraObject(tnsEvaluatedInstance* ei, void* unused){
  3516. tnsColor4dv(laThemeColor(_LA_THEME_3D_VIEW,LA_BT_BORDER)); tnsLineWidth(3);
  3517. tnsDrawCamera(ei->Object); tnsLineWidth(1); tnsFlush();
  3518. }
  3519. void tnsEvaluateCameraObject(tnsObject* o, tnsEvaluateData* ed){
  3520. if(ed->SceneEvaluateMode){ return; }
  3521. tnsAddEvaluatedInstance(ed,o,tnsDrawCameraObject,TNS_EVAL_LAYER_SOLID,0,0,0);
  3522. if(ed->FillOutline && o->Flags&TNS_OBJECT_FLAGS_SELECTED){
  3523. tnsAddEvaluatedInstance(ed,o,tnsDrawCameraOutline,TNS_EVAL_LAYER_OUTLINE,ed->Active==o,0,0);
  3524. }
  3525. if(ed->FillSelectionID){
  3526. tnsAddEvaluatedInstance(ed,o,tnsDrawCameraSelectionID,TNS_EVAL_LAYER_SELECTION,0,1,o->SelectID);
  3527. }
  3528. }
  3529. void tnsRunNode(tnsEvaluatedNode* en, int func, tnsObject* root){
  3530. T->Runtime.CurrentEN = en;
  3531. tnsObject* ob=root; // should be the same as en->Target.
  3532. for(laRackPage* rp=ob->Drivers->Pages.pFirst;rp;rp=rp->Item.pNext){
  3533. if(!rp->Eval.pFirst || rp->TriggerMode!=func) continue;
  3534. laRunPage(rp, 1);
  3535. }
  3536. }
  3537. #ifdef LA_WITH_LUAJIT
  3538. void tnsLuaEnsureNode(lua_State* L,int index,tnsObject* o);
  3539. void tnsLuaRunNode(lua_State* L, tnsEvaluatedNode* en, char* func, tnsObject* root);
  3540. #endif
  3541. void tnsEvaluateThisObject(tnsObject *o, tnsEvaluateData* ed){
  3542. tnsEvaluatedNode* CP,*CC;
  3543. if(ed->SceneEvaluateMode){
  3544. tnsEvaluateSyncNode(ed,o);
  3545. if(o->Type==TNS_OBJECT_INSTANCER){
  3546. CP=ed->Scene->CurrentParent; CC=ed->Scene->CurrentChild;
  3547. ed->Scene->CurrentParent=ed->Scene->CurrentChild; ed->Scene->CurrentChild=ed->Scene->CurrentParent->Children.pFirst;
  3548. }elif(o->Type==TNS_OBJECT_ROOT){ tnsEvaluatedNode* en=ed->Scene->CurrentChild;
  3549. tnsRunNode(en,TNS_PAGE_TRIGGER_PROCESS,o);
  3550. #ifdef LA_WITH_LUAJIT
  3551. tnsLuaEnsureNode(ed->L,en->LuaID,o);
  3552. tnsLuaRunNode(ed->L,en,"run",o);
  3553. #endif
  3554. if(en->ActionRetarget){
  3555. laActionRetarget* ar;
  3556. if(en->ActionRetarget->DetachedInNode){ ar = en->ActionRetarget; }
  3557. else{ ar = ((tnsRootObject*)en->Target)->ActionRetarget; }
  3558. laAnimationSyncRetarget(ar, MAIN.Animation->RunPlayHead);
  3559. laAnimationEvaluateRetargetedActions(ar);
  3560. }
  3561. }
  3562. }
  3563. if (!o->Show) return;
  3564. switch (o->Type){
  3565. case TNS_OBJECT_MESH: tnsEvaluateMeshObject(o, ed); break;
  3566. case TNS_OBJECT_INSTANCER:
  3567. tnsEvaluateInstancerObject(o,ed);
  3568. if(ed->SceneEvaluateMode){ ed->Scene->CurrentParent=CP; ed->Scene->CurrentChild=CC;}
  3569. break;
  3570. case TNS_OBJECT_CAMERA: tnsEvaluateCameraObject(o,ed); break;
  3571. case TNS_OBJECT_SHAPE: tnsEvaluateShapeObject(o,ed); break;
  3572. default: tnsEvaluateEmptyObject(o,ed); break;
  3573. }
  3574. }
  3575. void tnsClearDriversEval(tnsObject* o){
  3576. if(!o->Drivers) return;
  3577. for(laRackPage* rp=o->Drivers->Pages.pFirst;rp;rp=rp->Item.pNext){
  3578. while(lstPopPointer(&rp->Eval)); while(lstPopPointer(&rp->AlwaysBranchers));
  3579. }
  3580. }
  3581. void tnsClearPlayDuplicate(tnsObject* o){
  3582. if(!o || !o->PlayDuplicate) return;
  3583. tnsClearDriversEval(o);
  3584. while(lstPopPointer(&o->PlayDuplicate->ChildObjects));
  3585. for(laListItemPointer* lip=o->ChildObjects.pFirst;lip;lip=lip->pNext){
  3586. tnsObject*co=lip->p; tnsClearPlayDuplicate(co);
  3587. }
  3588. if(o->Type==TNS_OBJECT_ROOT){ tnsRootObject* ro=o; laAnimationClearRetarget(&ro->ActionRetarget); }
  3589. elif(o->Type==TNS_OBJECT_INSTANCER){ tnsInstancer* oi=o; tnsClearPlayDuplicate(oi->Instance); }
  3590. memFree(o->PlayDuplicate); o->PlayDuplicate=0;
  3591. }
  3592. void tnsFreeEvaluatedNode(tnsEvaluatedNode* n){
  3593. tnsEvaluatedNode* en;
  3594. while(en=lstPopItem(&n->Children)){ tnsFreeEvaluatedNode(en); }
  3595. n->Target->LuaCacheID=0; laAnimationClearRetarget(&n->ActionRetarget);
  3596. memFree(n);
  3597. }
  3598. void tnsFreeEvaluatedScene(tnsEvaluateData* ed){
  3599. if(!ed->Scene) return;
  3600. if(ed->Scene->Root) tnsFreeEvaluatedNode(ed->Scene->Root);
  3601. #ifdef LA_WITH_LUAJIT
  3602. logPrintNew("Shutting down Lua for the evaluated scene.\n");
  3603. lua_close(ed->L);
  3604. #endif
  3605. memFree(ed->Scene); ed->Scene=0;
  3606. }
  3607. void tnsClearPlayState(tnsObject* o){
  3608. tnsClearPlayDuplicate(o);
  3609. if(o->EvaluatedPlay.Commands) tnsFreeEvaluatedArray(&o->EvaluatedPlay);
  3610. tnsFreeEvaluatedScene(&o->EvaluatedPlay);
  3611. }
  3612. void tnsEnsureDriversEval(tnsObject* o){
  3613. if(!o->Drivers) return;
  3614. for(laRackPage* rp=o->Drivers->Pages.pFirst;rp;rp=rp->Item.pNext){
  3615. laRebuildPageEval(rp);
  3616. }
  3617. }
  3618. tnsObject* tnsEnsurePlayDuplicate(tnsObject* o){
  3619. tnsEnsureDriversEval(o);
  3620. if(o->Flags&TNS_OBJECT_FLAGS_PLAY_DUPLICATE) return o;
  3621. if(o->PlayDuplicate) return o->PlayDuplicate;
  3622. int obsize=tnsSizeOfObject(o);
  3623. tnsObject* dup=memAcquireHyper(obsize);
  3624. memcpy(dup,o,obsize); o->PlayDuplicate=dup;
  3625. dup->ChildObjects.pFirst=dup->ChildObjects.pLast=0;
  3626. for(laListItemPointer* lip=o->ChildObjects.pFirst;lip;lip=lip->pNext){
  3627. tnsObject*co=lip->p; tnsEnsurePlayDuplicate(co);
  3628. lstAppendPointer(&dup->ChildObjects,co->PlayDuplicate);
  3629. co->PlayDuplicate->ParentObject=o->ParentObject?dup:0; //objects directly under root doesn't have parent object
  3630. }
  3631. if(o->Type==TNS_OBJECT_ROOT){ tnsRootObject* ro=o; laAnimationEnsureRetarget(o,&ro->Actions,&ro->ActionRetarget);
  3632. ((tnsRootObject*)o->PlayDuplicate)->ActionRetarget=ro->ActionRetarget;
  3633. }elif(o->Type==TNS_OBJECT_INSTANCER){ tnsInstancer* oi=o; tnsEnsurePlayDuplicate(oi->Instance); }
  3634. dup->Flags|=TNS_OBJECT_FLAGS_PLAY_DUPLICATE;
  3635. return o->PlayDuplicate;
  3636. }
  3637. #ifdef LA_WITH_LUAJIT
  3638. void tnsLuaPushTypedPointer(lua_State* L, char* ct, void* data){
  3639. lua_getglobal(L,"ffi"); lua_getfield(L,-1,"cast"); lua_pushstring(L,ct); lua_pushlightuserdata(L,data);
  3640. lua_call(L,2,1); lua_remove(L,-2);
  3641. }
  3642. void tnsLuaSetObject(lua_State* L, tnsObject*o){
  3643. tnsLuaPushTypedPointer(L,"struct tnsObject *",o); lua_setfield(L,-2,"object");
  3644. }
  3645. void tnsLuaInit(lua_State* L){
  3646. if(luaL_loadstring(L, LA_TNS_LIB_COMMON) || lua_pcall(L, 0, 0, 0)){ logPrint(" Error loading tns lua libs\n");
  3647. lua_getglobal(L,"log"); lua_insert(L,-2); if(lua_pcall(L,1,0,0)){ lua_pop(L,1); }
  3648. };
  3649. lua_settop(L,0);
  3650. lua_newtable(L); lua_setglobal(L,"scene");
  3651. lua_getglobal(L,"scene"); lua_pushstring(L,"nodes"); lua_newtable(L); lua_settable(L,1);
  3652. lua_pushnil(L); lua_setfield(L,1,"node"); lua_pop(L,1);
  3653. }
  3654. void tnsLuaEnsureNode(lua_State* L,int index,tnsObject* o){ lua_settop(L,0);
  3655. lua_getglobal(L,"scene"); lua_getfield(L,1,"nodes");
  3656. lua_pushinteger(L,index); lua_gettable(L,2); if(lua_isnil(L,3) || (!lua_istable(L,3))){
  3657. lua_pushinteger(L,index); lua_newtable(L); lua_settable(L,2); lua_pop(L,1);
  3658. lua_pushinteger(L,index); lua_gettable(L,2);
  3659. lua_pushlightuserdata(L,0); lua_setfield(L,3,"object");
  3660. }
  3661. lua_settop(L,0);
  3662. }
  3663. void tnsLuaRemoveNode(lua_State* L,int index){ lua_settop(L,0);
  3664. lua_getglobal(L,"scene"); lua_pushstring(L,"nodes"); lua_gettable(L,1);
  3665. lua_pushinteger(L,index); lua_pushnil(L); lua_settable(L,2); lua_pop(L,2);
  3666. }
  3667. void tnsLuaRunNode(lua_State* L, tnsEvaluatedNode* en, char* func, tnsObject* root){ lua_settop(L,0); int index=en->LuaID;
  3668. lua_getglobal(L,"scene"); lua_getfield(L,1,"nodes");
  3669. lua_pushinteger(L,index); lua_gettable(L,-2); lua_setfield(L,1,"node");
  3670. lua_getfield(L,1,"node"); tnsLuaSetObject(L,root);
  3671. lua_getfield(L,-1,"scripts");
  3672. if(lua_isnil(L,-1) || (!lua_istable(L,-1))){
  3673. lua_pop(L,1); lua_newtable(L); lua_setfield(L,-2,"scripts"); lua_getfield(L,-1,"scripts");
  3674. }
  3675. if(!en->LuaLoaded){
  3676. if(root->Drivers){
  3677. if(root->LuaCacheID){
  3678. int scrtable=lua_gettop(L);
  3679. lua_pushinteger(L,root->LuaCacheID); lua_gettable(L,2); lua_getfield(L,-1,"scripts");
  3680. lua_pushnil(L); while(lua_next(L,-2)){
  3681. lua_pushvalue(L,-2); lua_pushvalue(L,-2); lua_settable(L,scrtable);
  3682. lua_pop(L,1);
  3683. }
  3684. lua_pop(L,2);
  3685. }else{
  3686. for(laRackPage*rp=root->Drivers->Pages.pFirst;rp;rp=rp->Item.pNext){
  3687. if(!(rp->UseScript&&rp->Script&&rp->Script->Ptr)){ continue; }
  3688. char* debug_name=rp->Name&&rp->Name->Ptr?rp->Name->Ptr:"unamed_driver_page";
  3689. lua_pushinteger(L,lua_objlen(L,-1)+1);
  3690. if(!luaL_loadbuffer(L,rp->Script->Ptr,strlen(rp->Script->Ptr),debug_name)){
  3691. if(lua_pcall(L,0,1,0)){ lua_getglobal(L,"log"); lua_insert(L,-2); if(lua_pcall(L,1,0,0)){ lua_pop(L,1); } }
  3692. else{ lua_settable(L,-3); }
  3693. }else{ lua_getglobal(L,"log"); lua_insert(L,-2); if(lua_pcall(L,1,0,0)){ lua_pop(L,1); } lua_pop(L,1); /* pop index */ }
  3694. }
  3695. root->LuaCacheID=en->LuaID;
  3696. }
  3697. }
  3698. en->LuaLoaded=1;
  3699. }
  3700. //lua_getglobal(L,"ddump"); lua_getglobal(L,"scene"); lua_call(L,1,0);
  3701. lua_pushnil(L); while(lua_next(L,-2)){
  3702. lua_getfield(L,-1,func); if((!lua_isnil(L,-1))&&lua_isfunction(L,-1)){
  3703. lua_pushvalue(L,-2); if(lua_pcall(L,1,0,0)){ lua_getglobal(L,"log"); lua_insert(L,-2); if(lua_pcall(L,1,0,0)){ lua_pop(L,1); } }
  3704. }else{ lua_pop(L,1); }
  3705. lua_pop(L,1);
  3706. }
  3707. lua_pop(L,3);
  3708. }
  3709. int tnsLuaRunNodeEvent(lua_State* L, tnsEvaluatedNode* en, tnsObject* object, laEvent* e){ lua_settop(L,0); int index=en->LuaID;
  3710. if(!en->LuaLoaded){ return 0; }
  3711. lua_getglobal(L,"scene"); lua_getfield(L,1,"nodes");
  3712. lua_pushinteger(L,index); lua_gettable(L,-2); lua_setfield(L,1,"node");
  3713. lua_getfield(L,1,"node"); tnsLuaSetObject(L,object);
  3714. lua_getfield(L,-1,"scripts");
  3715. if(lua_isnil(L,-1) || (!lua_istable(L,-1))){ return 0; }
  3716. lua_pushnil(L); while(lua_next(L,-2)){
  3717. lua_getfield(L,-1,"input"); if((!lua_isnil(L,-1))&&lua_isfunction(L,-1)){
  3718. lua_pushvalue(L,-2); tnsLuaPushTypedPointer(L,"laEvent*",e);
  3719. if(lua_pcall(L,2,1,0)){ lua_getglobal(L,"log"); lua_insert(L,-2); if(lua_pcall(L,1,0,0)){ lua_pop(L,1); } lua_pop(L,1); continue; }
  3720. int result = lua_tonumber(L,-1); lua_pop(L,1);
  3721. if (result!=0){ lua_settop(L,0); return 1; }
  3722. }else{ lua_pop(L,1); }
  3723. lua_pop(L,1);
  3724. }
  3725. lua_pop(L,3);
  3726. }
  3727. #endif //luajit
  3728. void tnsAddEvaluatedInstance(tnsEvaluateData* ed, tnsObject* ob, tnsDrawEvaluatedInstanceF Draw, int Layer,
  3729. int IsActive, int MeshSelectionType, int InstanceSelectionID){
  3730. tnsEvaluatedInstance* ei;
  3731. if(Layer==TNS_EVAL_LAYER_SOLID){
  3732. arrEnsureLength(&ed->Commands,ed->NextCommand,&ed->MaxCommand,sizeof(tnsEvaluatedInstance));
  3733. ei=&ed->Commands[ed->NextCommand]; ed->NextCommand++;
  3734. }elif(Layer==TNS_EVAL_LAYER_BACKDROP){
  3735. arrEnsureLength(&ed->Backdrop,ed->NextBackdrop,&ed->MaxBackdrop,sizeof(tnsEvaluatedInstance));
  3736. ei=&ed->Backdrop[ed->NextBackdrop]; ed->NextBackdrop++;
  3737. }elif(Layer==TNS_EVAL_LAYER_OUTLINE){
  3738. arrEnsureLength(&ed->Outlines,ed->NextOutline,&ed->MaxOutline,sizeof(tnsEvaluatedInstance));
  3739. ei=&ed->Outlines[ed->NextOutline]; ed->NextOutline++;
  3740. }elif(Layer==TNS_EVAL_LAYER_OVERLAY){
  3741. arrEnsureLength(&ed->Overlays,ed->NextOverlay,&ed->MaxOverlay,sizeof(tnsEvaluatedInstance));
  3742. ei=&ed->Overlays[ed->NextOverlay]; ed->NextOverlay++;
  3743. }elif(Layer==TNS_EVAL_LAYER_SELECTION){
  3744. arrEnsureLength(&ed->Selections,ed->NextSelection,&ed->MaxSelection,sizeof(tnsEvaluatedInstance));
  3745. ei=&ed->Selections[ed->NextSelection]; ed->NextSelection++;
  3746. }else{ return; }
  3747. ei->IsActive=IsActive; ei->MeshSelectionType=MeshSelectionType;
  3748. ei->InstanceSelectionID=ed->OverrideID?ed->OverrideID:InstanceSelectionID;
  3749. ei->Draw=Draw; ei->Object=ob; ei->DrawnIn2D=ed->State2D; if(ed->State2D){ ed->Has2D=1; }
  3750. tnsMultiply44d(ei->Mat,ed->MatArr[ed->NextMat-1],ob->GlobalTransform);
  3751. }
  3752. void tnsFreeEvaluatedArray(tnsEvaluateData* ed){
  3753. ed->Done=0;
  3754. arrFree(&ed->Backdrop,&ed->MaxBackdrop);
  3755. arrFree(&ed->Commands,&ed->MaxCommand);
  3756. arrFree(&ed->Outlines,&ed->MaxOutline);
  3757. arrFree(&ed->Overlays,&ed->MaxOverlay);
  3758. arrFree(&ed->Selections,&ed->MaxSelection);
  3759. }
  3760. void tnsInvalidateEvaluation(tnsObject* o){ if(!o) return;
  3761. if(o->InRoot) o->InRoot->Evaluated.Done=0; else o->Evaluated.Done=0;
  3762. }
  3763. void tnsInvalidatePlayEvaluation(tnsObject* o){
  3764. if(o->InRoot) o->InRoot->EvaluatedPlay.Done=0; else o->EvaluatedPlay.Done=0;
  3765. }
  3766. void tnsSetObjectTreeEvaluationArgs(tnsObject* from, tnsObject* Active, int FillOutline, int FillSelectionID, int W, int H){
  3767. tnsEvaluateData* ed=&from->Evaluated; int set=0;
  3768. #define SETARG(a)\
  3769. if(ed->a==0 && a!=0){ set=1; } ed->a=a;
  3770. SETARG(Active); SETARG(FillOutline); SETARG(FillSelectionID); SETARG(W); SETARG(H);
  3771. if(set) ed->Done=0;
  3772. }
  3773. tnsEvaluatedNode* tnsAcquireEvaluateNode(tnsEvaluateData* ed){
  3774. if(!ed->Scene->WastedEvaluateNodes.pFirst){ tnsEvaluatedNode* en=memAcquire(sizeof(tnsEvaluatedNode));
  3775. ed->Scene->NextLuaID++; en->LuaID=ed->Scene->NextLuaID; return en; }
  3776. else{ return lstPopItem(&ed->Scene->WastedEvaluateNodes); }
  3777. }
  3778. void tnsEvaluateNewNode(tnsEvaluateData* ed, tnsObject* ob){
  3779. tnsEvaluatedScene* s=ed->Scene;
  3780. tnsEvaluatedNode* en=tnsAcquireEvaluateNode(ed); en->Target=ob;
  3781. if(ob->Type==TNS_OBJECT_ROOT){ tnsRootObject* ro=ob;
  3782. en->ActionRetarget=laAnimationCopyRetargetFrom(ro->ActionRetarget); en->ActionRetarget->DetachedInNode = 1;
  3783. }
  3784. tnsMultiply44d(en->Mat,ed->MatArr[ed->NextMat-1],ob->GlobalTransform);
  3785. if(s->CurrentChild) lstInsertItemBefore(&s->CurrentParent->Children,en,s->CurrentChild);
  3786. else lstAppendItem(&s->CurrentParent->Children,en);
  3787. s->CurrentChild = en;
  3788. }
  3789. int tnsEvaluateTryRelinkExistingNode(tnsEvaluateData* ed, tnsObject* ob){
  3790. tnsEvaluatedScene* s=ed->Scene;
  3791. if(!s->CurrentChild) return 0;
  3792. int done=0; for(tnsEvaluatedNode* en=s->CurrentChild->Item.pNext;en;en=en->Item.pNext){
  3793. if(ob==en->Target){ done=1; lstRemoveItem(&s->CurrentParent->Children,en);
  3794. lstInsertItemBefore(&s->CurrentParent->Children,en,s->CurrentChild); break; }
  3795. }
  3796. return done;
  3797. }
  3798. void tnsEvaluateEndNode(tnsEvaluateData* ed, tnsEvaluatedNode* en){
  3799. tnsEvaluatedNode* sen;
  3800. while(sen=lstPopItem(&en->Children)){ tnsEvaluateEndNode(ed,sen); }
  3801. if(en->Target->Type==TNS_OBJECT_ROOT){ tnsRootObject* ro=en->Target;
  3802. laAnimationClearRetarget(&en->ActionRetarget);
  3803. }
  3804. int luaid=en->LuaID; memset(en,0,sizeof(tnsEvaluatedNode)); //memFree(sen);
  3805. en->LuaID=luaid;
  3806. #ifdef LA_WITH_LUAJIT
  3807. if(en->LuaID!=0) tnsLuaRemoveNode(ed->L,en->LuaID);
  3808. #endif
  3809. lstAppendItem(&ed->Scene->WastedEvaluateNodes,en);
  3810. }
  3811. void tnsEvaluateSyncNode(tnsEvaluateData* ed, tnsObject* ob){
  3812. tnsEvaluatedScene* s=ed->Scene;
  3813. if(ob && ((!s->CurrentChild) || (s->CurrentChild->Target!=ob))){
  3814. if(!tnsEvaluateTryRelinkExistingNode(ed,ob)) tnsEvaluateNewNode(ed,ob);
  3815. }
  3816. if((!ob) && s->CurrentChild){ tnsEvaluatedNode* en=s->CurrentChild->Item.pPrev;
  3817. if(en) while(en->Item.pNext){ tnsEvaluatedNode* den=en->Item.pNext;
  3818. lstRemoveItem(&s->CurrentParent->Children,den); tnsEvaluateEndNode(ed,den); }
  3819. s->CurrentChild=0;
  3820. }
  3821. }
  3822. void tnsEnsureEvaluatedScene(tnsEvaluateData* ed, tnsObject* root){
  3823. if(!ed->Scene){
  3824. ed->Scene=memAcquire(sizeof(tnsEvaluatedScene));
  3825. #ifdef LA_WITH_LUAJIT
  3826. logPrintNew("Starting Lua for evaluated scene.\n");
  3827. ed->L = lua_open(); la_luaLoadLibs(ed->L);
  3828. la_luaPrintStatus(ed->L); tnsLuaInit(ed->L);
  3829. #else
  3830. logPrintNew("Starting evaluated scene without lua.\n");
  3831. #endif
  3832. }
  3833. if(!ed->Scene->Root){
  3834. ed->Scene->Root=tnsAcquireEvaluateNode(ed);
  3835. ed->Scene->NextLuaID++; ed->Scene->Root->LuaID=ed->Scene->NextLuaID;
  3836. if(root->Type==TNS_OBJECT_ROOT){ tnsRootObject* ro=root;
  3837. ed->Scene->Root->ActionRetarget=laAnimationCopyRetargetFrom(ro->ActionRetarget);
  3838. }
  3839. }
  3840. ed->Scene->CurrentChild=ed->Scene->Root;
  3841. ed->Scene->CurrentChild->Target=root; tnsLoadIdentity44d(ed->Scene->CurrentChild->Mat);
  3842. }
  3843. void tnsPrintEvaluatedNode(tnsEvaluatedNode* en,int level){
  3844. for(int i=0;i<level;i++){ printf(" "); }
  3845. printf("%s\n",en->Target->Name?en->Target->Name->Ptr:"?");
  3846. for(tnsEvaluatedNode* sen=en->Children.pFirst;sen;sen=sen->Item.pNext){
  3847. tnsPrintEvaluatedNode(sen,level+1);
  3848. }
  3849. if(level==0){printf("\n");}
  3850. }
  3851. void tnsEvaluateObjectTree(tnsObject* from, tnsEvaluateData* UseED, int EvaluatePlay){
  3852. if(!from) return;
  3853. tnsObject* UseRoot=from->InRoot?from->InRoot:from;
  3854. tnsEvaluateData* ed=UseED?UseED:(EvaluatePlay?&UseRoot->EvaluatedPlay:&UseRoot->Evaluated);
  3855. ed->SceneEvaluateMode=EvaluatePlay;
  3856. if(ed->Done) return;
  3857. elif(!UseED){ ed->NextCommand=ed->NextOverlay=ed->NextSelection=ed->NextOutline=ed->NextMat=0;
  3858. if(!ed->Backdrop) arrInitLength(&ed->Backdrop,16,&ed->MaxBackdrop,sizeof(tnsEvaluatedInstance));
  3859. if(!ed->Commands) arrInitLength(&ed->Commands,16,&ed->MaxCommand,sizeof(tnsEvaluatedInstance));
  3860. if(!ed->Outlines) arrInitLength(&ed->Outlines,16,&ed->MaxOutline,sizeof(tnsEvaluatedInstance));
  3861. if(!ed->Overlays) arrInitLength(&ed->Overlays,16,&ed->MaxOverlay,sizeof(tnsEvaluatedInstance));
  3862. if(!ed->Selections) arrInitLength(&ed->Selections,16,&ed->MaxSelection,sizeof(tnsEvaluatedInstance));
  3863. if(!ed->MatArr) arrInitLength(&ed->MatArr,8,&ed->MaxMat,sizeof(tnsMatrix44d));
  3864. tnsLoadIdentity44d(ed->MatArr[0]); ed->NextMat=1; ed->Has2D=0;
  3865. }
  3866. tnsEvaluatedNode* CP,*CC;
  3867. if(ed->SceneEvaluateMode){
  3868. from=tnsEnsurePlayDuplicate(from);
  3869. if(!UseED){ tnsEnsureEvaluatedScene(ed,from); }
  3870. CP=ed->Scene->CurrentParent; CC=ed->Scene->CurrentChild;
  3871. }
  3872. lstPushPointer(&ed->ParentStack,from);
  3873. tnsEvaluateThisObject(from, ed);
  3874. if(ed->SceneEvaluateMode){ ed->Scene->CurrentParent=ed->Scene->CurrentChild; ed->Scene->CurrentChild=ed->Scene->CurrentParent->Children.pFirst; }
  3875. for (laListItemPointer* lip=from->ChildObjects.pFirst;lip;lip=lip->pNext){
  3876. tnsObject *o=lip->p; if (o){ tnsEvaluateObjectTree(o,ed,EvaluatePlay); }
  3877. if(ed->SceneEvaluateMode){ ed->Scene->CurrentChild=ed->Scene->CurrentChild?ed->Scene->CurrentChild->Item.pNext:0; }
  3878. }
  3879. lstPopPointer(&ed->ParentStack);
  3880. if(ed->SceneEvaluateMode){ ed->Scene->CurrentParent=CP; ed->Scene->CurrentChild=CC; }
  3881. if(!UseED){ ed->Done=1;
  3882. //if(ed->Scene){ tnsPrintEvaluatedNode(ed->Scene->Root,0);}
  3883. }
  3884. }
  3885. int tnsEvaluateObjectTreeEvent(tnsEvaluateData* ed_play, tnsEvaluatedNode* en, laEvent* e){
  3886. int stop=0;
  3887. for(tnsEvaluatedNode* lip=en->Children.pFirst;lip;lip=lip->Item.pNext){
  3888. if(tnsEvaluateObjectTreeEvent(ed_play, lip, e)){ stop=1; }
  3889. }
  3890. if(en->Target->Type==TNS_OBJECT_ROOT){
  3891. if(e->type&LA_KEYBOARD_EVENT){
  3892. tnsRunNode(en,TNS_PAGE_TRIGGER_KEYBOARD,en->Target);
  3893. }elif(e->type&LA_MOUSE_EVENT){
  3894. tnsRunNode(en,TNS_PAGE_TRIGGER_MOUSE,en->Target);
  3895. }
  3896. #ifdef LA_WITH_LUAJIT
  3897. if(!stop){ return tnsLuaRunNodeEvent(ed_play->L,en,en->Target,e); }
  3898. #endif
  3899. }
  3900. }
  3901. void tnsDrawLayer(tnsEvaluateData* ed,int Layer,void* CustomData){
  3902. tnsEvaluatedInstance* ei; int next=0;
  3903. int No2D=Layer&TNS_EVAL_LAYER_NO_2D; int Do2D=Layer&TNS_EVAL_LAYER_SHOW_2D;
  3904. Layer&=(~(TNS_EVAL_LAYER_SHOW_2D|TNS_EVAL_LAYER_NO_2D));
  3905. if(Layer==TNS_EVAL_LAYER_SOLID){ ei=ed->Commands; next=ed->NextCommand; }
  3906. elif(Layer==TNS_EVAL_LAYER_BACKDROP){ ei=ed->Backdrop; next=ed->NextBackdrop; }
  3907. elif(Layer==TNS_EVAL_LAYER_OUTLINE){ ei=ed->Outlines; next=ed->NextOutline; }
  3908. elif(Layer==TNS_EVAL_LAYER_OVERLAY){ ei=ed->Overlays; next=ed->NextOverlay; }
  3909. elif(Layer==TNS_EVAL_LAYER_SELECTION){ ei=ed->Selections; next=ed->NextSelection; }
  3910. else{ return; } if(!next){ return; }
  3911. for(int i=0;i<next;i++){
  3912. if(No2D && ei->Object->Type==TNS_OBJECT_SHAPE){ ei++; continue; }
  3913. if((Do2D && (!ei->DrawnIn2D)) || ((!Do2D) && ei->DrawnIn2D)){ ei++; continue; }
  3914. tnsPushMatrix(); tnsApplyModelMatrix(ei->Mat);
  3915. ei->Draw(ei,CustomData);
  3916. tnsPopMatrix();
  3917. ei++;
  3918. }
  3919. }
  3920. void tnsDrawObjectTree(tnsObject* from, int Layers,void* CustomData, int DrawRuntime){
  3921. if(!from) return;
  3922. tnsEvaluateData* ed=DrawRuntime?&from->EvaluatedPlay:&from->Evaluated;
  3923. if(!ed->Done) return; int Do2D=Layers&TNS_EVAL_LAYER_SHOW_2D;
  3924. if(Layers&TNS_EVAL_LAYER_BACKDROP){ tnsDrawLayer(ed,TNS_EVAL_LAYER_BACKDROP|Do2D,CustomData); }
  3925. if(Layers&TNS_EVAL_LAYER_SOLID){ tnsDrawLayer(ed,TNS_EVAL_LAYER_SOLID|Do2D,CustomData); }
  3926. if(Layers&TNS_EVAL_LAYER_OUTLINE){ tnsDrawLayer(ed,TNS_EVAL_LAYER_OUTLINE|Do2D,CustomData);}
  3927. if(Layers&TNS_EVAL_LAYER_OVERLAY){ tnsDrawLayer(ed,TNS_EVAL_LAYER_OVERLAY|Do2D,CustomData);}
  3928. if(Layers&TNS_EVAL_LAYER_SELECTION){ tnsDrawLayer(ed,TNS_EVAL_LAYER_SELECTION|Do2D,CustomData); }
  3929. }
  3930. void tnsDrawSingleObjectOrigin(tnsObject* o){
  3931. real* c=laThemeColor(_LA_THEME_3D_VIEW,LA_BT_BORDER); tnsColor4d(LA_COLOR3(c),0.5);
  3932. tnsPointSize(8); tnsVertex3d(0,0,0); tnsPackAs(GL_POINTS);
  3933. tnsFlush(); tnsPointSize(1);
  3934. }
  3935. void tnsDrawObjectOrigins(tnsObject *from, tnsObject *active, int AllOrigins){
  3936. tnsObject *o; if(!from) return;
  3937. tnsVector4d pos;
  3938. for (laListItemPointer* lip=from->ChildObjects.pFirst;lip;lip=lip->pNext){
  3939. o=lip->p; if((!AllOrigins)){
  3940. if((o!=active) && (!(o->Flags&TNS_OBJECT_FLAGS_SELECTED))) continue;
  3941. if(o->Type==TNS_OBJECT_MESH && ((tnsMeshObject*)o)->Mode==TNS_MESH_EDIT_MODE){ continue; }
  3942. }
  3943. if(T->BindedShader==T->SelectionShader){ int i=o->SelectID; real color[4]={0,0,0,1}; TNS_ID_TO_COLOR(color,i); tnsColor4dv(color); }
  3944. else{
  3945. if(o==active){ tnsColor4dv(laAccentColor(LA_BT_TEXT_ACTIVE)); }
  3946. elif(o->Flags&TNS_OBJECT_FLAGS_SELECTED){ tnsColor4dv(laAccentColor(LA_BT_NORMAL)); }
  3947. else{ real* c=laThemeColor(_LA_THEME_3D_VIEW,LA_BT_BORDER); tnsColor4d(LA_COLOR3(c),0.5); }
  3948. }
  3949. tnsVertex3d(LA_COLOR3(o->GLocation)); tnsPackAs(GL_POINTS);
  3950. }
  3951. }
  3952. void tnsDrawCursor(tnsObject* root){
  3953. if(!root || root->Type!=TNS_OBJECT_ROOT) return;
  3954. tnsMatrix44d vp; tnsVector4d t; tnsVector4d t1={0,0,0,1};
  3955. tnsMultiply44d(vp,tnsGetProjectionMatrix(),tnsGetViewMatrix());
  3956. tnsApplyTransform44d(t,vp,root->GLocation); real w=t[3]*0.05;
  3957. tnsDrawCross(LA_COLOR3(root->GLocation),-w,w,-w,w,-w,w); tnsColor4d(0,0,0,0.5);
  3958. tnsPackAs(GL_LINES); glLineWidth(5);
  3959. tnsFlush(); w*=0.9;
  3960. tnsDrawCross(LA_COLOR3(root->GLocation),-w,w,-w,w,-w,w); tnsColor4dv(laThemeColor(_LA_THEME_3D_VIEW,LA_BT_BORDER));
  3961. tnsPackAs(GL_LINES); glLineWidth(2);
  3962. tnsFlush(); glLineWidth(1);
  3963. }
  3964. //===================================================================[Material]
  3965. tnsMaterial *tnsCreateMaterial(char *Name){
  3966. tnsMaterial *m; if(!Name || !Name[0]) return 0;
  3967. m = memAcquireHyper(sizeof(tnsMaterial));
  3968. strSafeSet(&m->Name, Name); tnsVectorSet4(m->Color,0.8,0.8,0.8,1); tnsVectorSet4(m->Color2,0.8,0.8,0.8,1);
  3969. m->Page=memAcquire(sizeof(laRackPage));
  3970. lstAppendItem(&T->World->Materials, m);
  3971. return m;
  3972. }
  3973. tnsMaterial *tnsFindMaterial(char *name){
  3974. tnsMaterial *m;
  3975. for (m = T->World->Materials.pFirst; m; m = m->Item.pNext){ if(strSame(m->Name->Ptr, name)) return m; }
  3976. return 0;
  3977. }
  3978. void tnsRemoveMaterial(tnsMaterial* mat){
  3979. lstRemoveItem(&T->World->Materials,mat);
  3980. laNodeRack* rr; while(rr=lstPopItem(&mat->Page->Racks)){ laDestroyRack(rr); }
  3981. strSafeDestroy(&mat->Page->Name); memLeave(mat->Page);
  3982. for(tnsObject* o=T->World->AllObjects.pFirst;o;o=o->Item.pNext){
  3983. if(o->Type==TNS_OBJECT_MESH){ tnsMeshObject* mo=o;
  3984. for(tnsMaterialSlot* msi=mo->Materials.pFirst;msi;msi=msi->Item.pNext){
  3985. if(msi->Material==mat){ memAssignRef(msi,&msi->Material,0); }
  3986. }
  3987. }elif(o->Type==TNS_OBJECT_SHAPE){ tnsShapeObject* so=o;
  3988. for(tnsMaterialSlot* msi=so->Materials.pFirst;msi;msi=msi->Item.pNext){
  3989. if(msi->Material==mat){ memAssignRef(msi,&msi->Material,0); }
  3990. }
  3991. }
  3992. }
  3993. tnsRefreshMaterialLibraries();
  3994. memLeave(mat);
  3995. }
  3996. tnsMaterialSlot* tnsNewMaterialSlot(tnsObject* o){
  3997. if(o->Type==TNS_OBJECT_MESH){ tnsMeshObject* mo=o; short nextid=0,found=1;
  3998. while(found){ found=0;
  3999. for(tnsMaterialSlot* msi=mo->Materials.pFirst;msi;msi=msi->Item.pNext){
  4000. if(nextid==msi->Index){ found=1; nextid++; continue; }
  4001. }
  4002. }
  4003. tnsMaterialSlot* ms=memAcquire(sizeof(tnsMaterialSlot)); lstAppendItem(&mo->Materials,ms);
  4004. ms->Index=nextid; memAssignRef(ms,&ms->Parent,mo); memAssignRef(mo,&mo->CurrentMaterial,ms);
  4005. return ms;
  4006. }elif(o->Type==TNS_OBJECT_SHAPE){ tnsShapeObject* so=o; short nextid=0,found=1;
  4007. while(found){ found=0;
  4008. for(tnsMaterialSlot* msi=so->Materials.pFirst;msi;msi=msi->Item.pNext){
  4009. if(nextid==msi->Index){ found=1; nextid++; continue; }
  4010. }
  4011. }
  4012. tnsMaterialSlot* ms=memAcquire(sizeof(tnsMaterialSlot)); lstAppendItem(&so->Materials,ms);
  4013. ms->Index=nextid; memAssignRef(ms,&ms->Parent,so); memAssignRef(so,&so->CurrentMaterial,ms);
  4014. return ms;
  4015. }
  4016. }
  4017. void tnsRemoveMaterialSlot(tnsObject* o, tnsMaterialSlot* ms){
  4018. if(o->Type==TNS_OBJECT_MESH){ tnsMeshObject* mo=o;
  4019. memAssignRef(mo,&mo->CurrentMaterial,ms->Item.pNext?ms->Item.pNext:ms->Item.pPrev);
  4020. lstRemoveItem(&mo->Materials,ms); memLeave(ms);
  4021. }elif(o->Type==TNS_OBJECT_SHAPE){ tnsShapeObject* so=o;
  4022. memAssignRef(so,&so->CurrentMaterial,ms->Item.pNext?ms->Item.pNext:ms->Item.pPrev);
  4023. lstRemoveItem(&so->Materials,ms); memLeave(ms);
  4024. }
  4025. }
  4026. void tnsAssignMaterialSlot(tnsObject* o, tnsMaterialSlot* ms){
  4027. if(o->Type==TNS_OBJECT_MESH){ tnsMeshObject* mo=o;
  4028. if(mo->Mode==TNS_MESH_OBJECT_MODE){
  4029. for(int i=0;i<mo->totf;i++){ mo->f[i].mat=ms->Index; }
  4030. }elif(mo->Mode==TNS_MESH_EDIT_MODE){
  4031. for(tnsMFace* f=mo->mf.pFirst;f;f=f->Item.pNext){ if(f->flags&TNS_MESH_FLAG_SELECTED) f->mat=ms->Index; }
  4032. }
  4033. }elif(o->Type==TNS_OBJECT_SHAPE){ tnsShapeObject* so=o;
  4034. if(so->Mode==TNS_MESH_OBJECT_MODE){
  4035. for(tnsShape*s=so->Shapes.pFirst;s;s=s->Item.pNext){ s->mat=ms->Index; }
  4036. }elif(so->Mode==TNS_MESH_EDIT_MODE){
  4037. for(tnsShape*s=so->Shapes.pFirst;s;s=s->Item.pNext){ if(tnsShapePointAnySelected(s)) s->mat=ms->Index; }
  4038. }
  4039. }
  4040. }
  4041. void tnsRefreshMaterialLibraries(){
  4042. strSafeDestroy(&T->World->MaterialLibraries);
  4043. for(tnsMaterial* mat=T->World->Materials.pFirst;mat;mat=mat->Item.pNext){
  4044. if(!mat->AsLibrary || !mat->Page->UseScript) continue;
  4045. if(mat->Page->Script) strSafeAppend(&T->World->MaterialLibraries,mat->Page->Script->Ptr);
  4046. tnsEnsureMaterialShader(mat,1);
  4047. }
  4048. for(tnsMaterial* mat=T->World->Materials.pFirst;mat;mat=mat->Item.pNext){
  4049. if(mat->AsLibrary || !mat->Page->UseScript) continue;
  4050. tnsEnsureMaterialShader(mat,1); tns_InvalidateMeshWithMaterial(mat);
  4051. }
  4052. laNotifyUsers("tns.world");
  4053. }
  4054. void tnsEnsureMaterialShader(tnsMaterial* mat, int Refresh){
  4055. if(Refresh){
  4056. if(mat->Shader && mat->Shader!=T->immShader){ tnsDeleteShaderProgram(mat->Shader); mat->Shader=0; }
  4057. }
  4058. if((!(mat->Page->Script&&mat->Page->Script->Ptr))||mat->AsLibrary){ mat->Shader=T->immShader; return; }
  4059. char* str=mat->Page->Script->Ptr;
  4060. char* lib=T->World->MaterialLibraries?T->World->MaterialLibraries->Ptr:0;
  4061. mat->Shader = tnsNewShaderProgram(
  4062. tnsNewVertexShader(LA_IMM_VERTEX_SHADER),tnsNewFragmentShaderMaterial(LA_OBJECT_FRAGMENT_SHADER,lib,str),-1);
  4063. if(!mat->Shader){ mat->Shader=T->immShader; }
  4064. }
  4065. void tnsPrintMaterials(){
  4066. for(tnsMaterial* m=T->World->Materials.pFirst;m;m=m->Item.pNext){
  4067. printf("%s %d %d\n",(m->Name&&m->Name->Ptr?m->Name->Ptr:""),m,m->Page->Racks.pFirst);
  4068. }
  4069. }
  4070. //==================================================================[Util]
  4071. #define MAX3(a, b, c) \
  4072. a > b ? (a > c ? a : c) : (b > c ? b : c)
  4073. #define MIN3(a, b, c) \
  4074. a < b ? (a < c ? a : c) : (b < c ? b : c)
  4075. extern LA MAIN;
  4076. void tnssRGB2XYZ(tnsVector3d rgb,tnsVector3d xyz){
  4077. tnsMatrix44d mat={0.4124564,0.3575761,0.1804375,0,
  4078. 0.2126729,0.7151522,0.0721750,0,
  4079. 0.0193339,0.1191920,0.9503041,0,0,0,0,0};
  4080. tnsApplyRotation33d(xyz,mat,rgb);
  4081. }
  4082. void tnsClay2XYZ(tnsVector3d rgb,tnsVector3d xyz){
  4083. tnsMatrix44d mat={0.5767309,0.1855540,0.1881852,0,
  4084. 0.2973769,0.6273491,0.0752741,0,
  4085. 0.0270343,0.0706872,0.9911085,0,0,0,0,0};
  4086. tnsApplyRotation33d(xyz,mat,rgb);
  4087. }
  4088. void tnsXYZ2sRGB(tnsVector3d xyz,tnsVector3d rgb){
  4089. tnsMatrix44d mat={3.2404542,-1.5371385,-0.4985314,0,
  4090. -0.9692660,1.8760108,0.0415560,0,
  4091. 0.0556434,-0.2040259,1.0572252,0,0,0,0,0};
  4092. tnsApplyRotation33d(rgb,mat,xyz);
  4093. }
  4094. void tnsXYZ2Clay(tnsVector3d xyz,tnsVector3d rgb){
  4095. tnsMatrix44d mat={2.0413690,-0.5649464,-0.3446944,0,
  4096. -0.9692660,1.8760108,0.0415560,0,
  4097. 0.0134474,-0.1183897,1.0154096,0,0,0,0,0};
  4098. tnsApplyRotation33d(rgb,mat,xyz);
  4099. }
  4100. void tnsRGB2Clay(tnsVector3d rgb, tnsVector3d clay){
  4101. tnsVector3d xyz; tnssRGB2XYZ(rgb,xyz);
  4102. tnsXYZ2Clay(xyz,clay);
  4103. }
  4104. void tnsClay2RGB(tnsVector3d clay, tnsVector3d rgb){
  4105. tnsVector3d xyz; tnsClay2XYZ(clay,xyz);
  4106. tnsXYZ2sRGB(xyz,rgb);
  4107. }
  4108. static real _srgb_transfer_function(real a){
  4109. return .0031308f >= a ? 12.92f * a : 1.055f * powf(a, .4166666666666667f) - .055f;
  4110. }
  4111. static real _srgb_transfer_function_inv(real a){
  4112. return .04045f < a ? powf((a + .055f) / 1.055f, 2.4f) : a / 12.92f;
  4113. }
  4114. void tns2LogsRGBSingle(real* a){
  4115. *a=_srgb_transfer_function(*a);
  4116. }
  4117. void tns2LinearsRGBSingle(real* a){
  4118. *a=_srgb_transfer_function_inv(*a);
  4119. }
  4120. void tns2LogsRGB(real* srgb){
  4121. srgb[0]=_srgb_transfer_function(srgb[0]);
  4122. srgb[1]=_srgb_transfer_function(srgb[1]);
  4123. srgb[2]=_srgb_transfer_function(srgb[2]);
  4124. }
  4125. void tns2LinearsRGB(real* srgb){
  4126. srgb[0]=_srgb_transfer_function_inv(srgb[0]);
  4127. srgb[1]=_srgb_transfer_function_inv(srgb[1]);
  4128. srgb[2]=_srgb_transfer_function_inv(srgb[2]);
  4129. }
  4130. void tnsRGB2OKLAB(real* rgb, real* oklab){
  4131. real l = 0.4122214708f * rgb[0] + 0.5363325363f * rgb[1] + 0.0514459929f * rgb[2];
  4132. real m = 0.2119034982f * rgb[0] + 0.6806995451f * rgb[1] + 0.1073969566f * rgb[2];
  4133. real s = 0.0883024619f * rgb[0] + 0.2817188376f * rgb[1] + 0.6299787005f * rgb[2];
  4134. real l_ = cbrt(l); real m_ = cbrt(m); real s_ = cbrt(s);
  4135. oklab[0]=0.2104542553f*l_ + 0.7936177850f*m_ - 0.0040720468f*s_;
  4136. oklab[1]=1.9779984951f*l_ - 2.4285922050f*m_ + 0.4505937099f*s_;
  4137. oklab[2]=0.0259040371f*l_ + 0.7827717662f*m_ - 0.8086757660f*s_;
  4138. }
  4139. void tnsOKLAB2RGB(real* oklab, real* rgb){
  4140. real l_ = oklab[0] + 0.3963377774f * oklab[1] + 0.2158037573f * oklab[2];
  4141. real m_ = oklab[0] - 0.1055613458f * oklab[1] - 0.0638541728f * oklab[2];
  4142. real s_ = oklab[0] - 0.0894841775f * oklab[1] - 1.2914855480f * oklab[2];
  4143. real l = l_*l_*l_; real m = m_*m_*m_; real s = s_*s_*s_;
  4144. rgb[0]=+4.0767416621f * l - 3.3077115913f * m + 0.2309699292f * s;
  4145. rgb[1]=-1.2684380046f * l + 2.6097574011f * m - 0.3413193965f * s;
  4146. rgb[2]=-0.0041960863f * l - 0.7034186147f * m + 1.7076147010f * s;
  4147. }
  4148. static real _compute_max_saturation(real a, real b){
  4149. real k0, k1, k2, k3, k4, wl, wm, ws;
  4150. if (-1.88170328f * a - 0.80936493f * b > 1){
  4151. k0 = +1.19086277f; k1 = +1.76576728f; k2 = +0.59662641f; k3 = +0.75515197f; k4 = +0.56771245f;
  4152. wl = +4.0767416621f; wm = -3.3077115913f; ws = +0.2309699292f;
  4153. }
  4154. else if (1.81444104f * a - 1.19445276f * b > 1){
  4155. k0 = +0.73956515f; k1 = -0.45954404f; k2 = +0.08285427f; k3 = +0.12541070f; k4 = +0.14503204f;
  4156. wl = -1.2684380046f; wm = +2.6097574011f; ws = -0.3413193965f;
  4157. }
  4158. else{
  4159. k0 = +1.35733652f; k1 = -0.00915799f; k2 = -1.15130210f; k3 = -0.50559606f; k4 = +0.00692167f;
  4160. wl = -0.0041960863f; wm = -0.7034186147f; ws = +1.7076147010f;
  4161. }
  4162. real S = k0 + k1 * a + k2 * b + k3 * a * a + k4 * a * b;
  4163. real k_l = +0.3963377774f * a + 0.2158037573f * b;
  4164. real k_m = -0.1055613458f * a - 0.0638541728f * b;
  4165. real k_s = -0.0894841775f * a - 1.2914855480f * b;
  4166. {
  4167. real l_ = 1.f + S * k_l;
  4168. real m_ = 1.f + S * k_m;
  4169. real s_ = 1.f + S * k_s;
  4170. real l = l_ * l_ * l_;
  4171. real m = m_ * m_ * m_;
  4172. real s = s_ * s_ * s_;
  4173. real l_dS = 3.f * k_l * l_ * l_;
  4174. real m_dS = 3.f * k_m * m_ * m_;
  4175. real s_dS = 3.f * k_s * s_ * s_;
  4176. real l_dS2 = 6.f * k_l * k_l * l_;
  4177. real m_dS2 = 6.f * k_m * k_m * m_;
  4178. real s_dS2 = 6.f * k_s * k_s * s_;
  4179. real f = wl * l + wm * m + ws * s;
  4180. real f1 = wl * l_dS + wm * m_dS + ws * s_dS;
  4181. real f2 = wl * l_dS2 + wm * m_dS2 + ws * s_dS2;
  4182. S = S - f * f1 / (f1 * f1 - 0.5f * f * f2);
  4183. }
  4184. return S;
  4185. }
  4186. static void _find_cusp(real a, real b, real *l, real *c)
  4187. {
  4188. real S_cusp = _compute_max_saturation(a, b);
  4189. real oklab[3]={1, S_cusp * a, S_cusp * b}; real rgb_at_max[3];
  4190. tnsOKLAB2RGB(oklab,rgb_at_max);
  4191. real L_cusp = cbrt(1.f / TNS_MAX3(rgb_at_max[0], rgb_at_max[1], rgb_at_max[2]));
  4192. real C_cusp = L_cusp * S_cusp;
  4193. *l=L_cusp; *c=C_cusp;
  4194. }
  4195. static real _find_gamut_intersection(real a, real b, real L1, real C1, real L0, real cusp_L, real cusp_C)
  4196. {
  4197. real t;
  4198. if (((L1 - L0) * cusp_C - (cusp_L - L0) * C1) <= 0.f) {
  4199. t = cusp_C * L0 / (C1 * cusp_L + cusp_C * (L0 - L1));
  4200. }else{
  4201. t = cusp_C * (L0 - 1.f) / (C1 * (cusp_L - 1.f) + cusp_C * (L0 - L1));
  4202. {
  4203. real dL = L1 - L0; real dC = C1;
  4204. real k_l = +0.3963377774f * a + 0.2158037573f * b;
  4205. real k_m = -0.1055613458f * a - 0.0638541728f * b;
  4206. real k_s = -0.0894841775f * a - 1.2914855480f * b;
  4207. real l_dt = dL + dC * k_l;
  4208. real m_dt = dL + dC * k_m;
  4209. real s_dt = dL + dC * k_s;
  4210. {
  4211. real L = L0 * (1.f - t) + t * L1;
  4212. real C = t * C1;
  4213. real l_ = L + C * k_l;
  4214. real m_ = L + C * k_m;
  4215. real s_ = L + C * k_s;
  4216. real l = l_ * l_ * l_;
  4217. real m = m_ * m_ * m_;
  4218. real s = s_ * s_ * s_;
  4219. real ldt = 3 * l_dt * l_ * l_;
  4220. real mdt = 3 * m_dt * m_ * m_;
  4221. real sdt = 3 * s_dt * s_ * s_;
  4222. real ldt2 = 6 * l_dt * l_dt * l_;
  4223. real mdt2 = 6 * m_dt * m_dt * m_;
  4224. real sdt2 = 6 * s_dt * s_dt * s_;
  4225. real r = 4.0767416621f * l - 3.3077115913f * m + 0.2309699292f * s - 1;
  4226. real r1 = 4.0767416621f * ldt - 3.3077115913f * mdt + 0.2309699292f * sdt;
  4227. real r2 = 4.0767416621f * ldt2 - 3.3077115913f * mdt2 + 0.2309699292f * sdt2;
  4228. real u_r = r1 / (r1 * r1 - 0.5f * r * r2);
  4229. real t_r = -r * u_r;
  4230. real g = -1.2684380046f * l + 2.6097574011f * m - 0.3413193965f * s - 1;
  4231. real g1 = -1.2684380046f * ldt + 2.6097574011f * mdt - 0.3413193965f * sdt;
  4232. real g2 = -1.2684380046f * ldt2 + 2.6097574011f * mdt2 - 0.3413193965f * sdt2;
  4233. real u_g = g1 / (g1 * g1 - 0.5f * g * g2);
  4234. real t_g = -g * u_g;
  4235. real b = -0.0041960863f * l - 0.7034186147f * m + 1.7076147010f * s - 1;
  4236. real b1 = -0.0041960863f * ldt - 0.7034186147f * mdt + 1.7076147010f * sdt;
  4237. real b2 = -0.0041960863f * ldt2 - 0.7034186147f * mdt2 + 1.7076147010f * sdt2;
  4238. real u_b = b1 / (b1 * b1 - 0.5f * b * b2);
  4239. real t_b = -b * u_b;
  4240. t_r = u_r >= 0.f ? t_r : FLT_MAX;
  4241. t_g = u_g >= 0.f ? t_g : FLT_MAX;
  4242. t_b = u_b >= 0.f ? t_b : FLT_MAX;
  4243. t += fmin(t_r, fmin(t_g, t_b));
  4244. }
  4245. }
  4246. }
  4247. return t;
  4248. }
  4249. static real _toe(real x) {
  4250. const real k_1 = 0.206f; const real k_2 = 0.03f; const real k_3 = (1.f + k_1) / (1.f + k_2);
  4251. return 0.5f * (k_3 * x - k_1 + sqrt((k_3 * x - k_1) * (k_3 * x - k_1) + 4 * k_2 * k_3 * x));
  4252. }
  4253. static real _toe_inv(real x) {
  4254. const real k_1 = 0.206f; const real k_2 = 0.03f; const real k_3 = (1.f + k_1) / (1.f + k_2);
  4255. return (x * x + k_1 * x) / (k_3 * (x + k_2));
  4256. }
  4257. static void _to_ST(real cusp_L, real cusp_C, real* _s, real* _t) {
  4258. real L = cusp_L; real C = cusp_C;
  4259. *_s=C / L; *_t=C / (1 - L);
  4260. }
  4261. static void _get_ST_mid(real a_, real b_, real *s,real *t){
  4262. *s = 0.11516993f + 1.f / (
  4263. +7.44778970f + 4.15901240f * b_
  4264. + a_ * (-2.19557347f + 1.75198401f * b_
  4265. + a_ * (-2.13704948f - 10.02301043f * b_
  4266. + a_ * (-4.24894561f + 5.38770819f * b_ + 4.69891013f * a_
  4267. )))
  4268. );
  4269. *t = 0.11239642f + 1.f / (
  4270. +1.61320320f - 0.68124379f * b_
  4271. + a_ * (+0.40370612f + 0.90148123f * b_
  4272. + a_ * (-0.27087943f + 0.61223990f * b_
  4273. + a_ * (+0.00299215f - 0.45399568f * b_ - 0.14661872f * a_
  4274. )))
  4275. );
  4276. }
  4277. static void _get_Cs(real L, real a_, real b_,real *rC_0, real *rC_mid, real *rC_max){
  4278. real cusp_L,cusp_C; _find_cusp(a_, b_,&cusp_L,&cusp_C);
  4279. real C_max = _find_gamut_intersection(a_, b_, L, 1, L,cusp_L,cusp_C);
  4280. real _S,_T; _to_ST(cusp_L,cusp_C,&_S, &_T);
  4281. real k = C_max / fmin((L * _S), (1 - L) * _T);
  4282. real C_mid;{
  4283. real _s, _t; _get_ST_mid(a_, b_,&_s,&_t);
  4284. real C_a = L * _s; real C_b = (1.f - L) * _t;
  4285. C_mid = 0.9f * k * sqrt(sqrt(1.f / (1.f / (C_a * C_a * C_a * C_a) + 1.f / (C_b * C_b * C_b * C_b))));
  4286. }
  4287. real C_0;{
  4288. real C_a = L * 0.4f;
  4289. real C_b = (1.f - L) * 0.8f;
  4290. C_0 = sqrt(1.f / (1.f / (C_a * C_a) + 1.f / (C_b * C_b)));
  4291. }
  4292. *rC_0=C_0; *rC_mid=C_mid; *rC_max=C_max;
  4293. }
  4294. void tnsHCY2RGBLinear(real *hcy, real *rgb){
  4295. real h = hcy[0]; real s = hcy[1]; real l = hcy[2];
  4296. if (l >= 1.0f){ tnsVectorSet3(rgb,1,1,1); return; }
  4297. else if (l <= 0.0f){ tnsVectorSet3(rgb,0,0,0); return; }
  4298. real a_ = cos(2.f * TNS_PI * h);
  4299. real b_ = sin(2.f * TNS_PI * h);
  4300. real L = _toe_inv(l);
  4301. real C_0, C_mid, C_max;
  4302. _get_Cs(L, a_, b_,&C_0,&C_mid,&C_max);
  4303. real mid = 0.8f; real mid_inv = 1.25f;
  4304. real C, t, k_0, k_1, k_2;
  4305. if (s < mid){
  4306. t = mid_inv * s;
  4307. k_1 = mid * C_0;
  4308. k_2 = (1.f - k_1 / C_mid);
  4309. C = t * k_1 / (1.f - k_2 * t);
  4310. }else{
  4311. t = (s - mid)/ (1 - mid);
  4312. k_0 = C_mid;
  4313. k_1 = (1.f - mid) * C_mid * C_mid * mid_inv * mid_inv / C_0;
  4314. k_2 = (1.f - (k_1) / (C_max - C_mid));
  4315. C = k_0 + t * k_1 / (1.f - k_2 * t);
  4316. }
  4317. real okl[3]={L, C * a_, C * b_};
  4318. tnsOKLAB2RGB(okl, rgb);
  4319. }
  4320. void tnsRGB2HCYLinear(real *rgb, real *hcy){
  4321. real lab[3]; real lrgb[3];
  4322. lrgb[0]=rgb[0]; lrgb[1]=rgb[1]; lrgb[2]=rgb[2];
  4323. tnsRGB2OKLAB(lrgb,lab);
  4324. if(lab[0]>=1.0f-1e-4){ tnsVectorSet3(hcy,0,0,1); return; }
  4325. if(lab[0]<=1e-4){ tnsVectorSet3(hcy,0,0,0); return; }
  4326. real C = sqrt(lab[1]*lab[1] + lab[2]*lab[2]);
  4327. real a_ = (!C)?0:(lab[1] / C);
  4328. real b_ = (!C)?0:(lab[2] / C);
  4329. real L = lab[0];
  4330. real h = 0.5f + 0.5f * atan2(-lab[2], -lab[1]) / TNS_PI;
  4331. real C_0, C_mid, C_max;
  4332. _get_Cs(L, a_, b_,&C_0,&C_mid,&C_max);
  4333. real mid = 0.8f; real mid_inv = 1.25f;
  4334. real s;
  4335. if (C < C_mid){
  4336. real k_1 = mid * C_0;
  4337. real k_2 = (1.f - k_1 / C_mid);
  4338. real t = C / (k_1 + k_2 * C);
  4339. s = t * mid;
  4340. }else{
  4341. real k_0 = C_mid;
  4342. real k_1 = (1.f - mid) * C_mid * C_mid * mid_inv * mid_inv / C_0;
  4343. real k_2 = (1.f - (k_1) / (C_max - C_mid));
  4344. real t = (C - k_0) / (k_1 + k_2 * (C - k_0));
  4345. s = mid + (1.f - mid) * t;
  4346. }
  4347. real l = _toe(L);
  4348. hcy[0]=h; hcy[1]=s; hcy[2]=l;
  4349. }
  4350. void tnsHCY2RGB(real *hcy, real *rgb){
  4351. tnsHCY2RGBLinear(hcy,rgb);
  4352. rgb[0]=_srgb_transfer_function(rgb[0]);
  4353. rgb[1]=_srgb_transfer_function(rgb[1]);
  4354. rgb[2]=_srgb_transfer_function(rgb[2]);
  4355. }
  4356. void tnsRGB2HCY(real *rgb, real *hcy){
  4357. real lrgb[3];
  4358. lrgb[0]=_srgb_transfer_function_inv(rgb[0]);
  4359. lrgb[1]=_srgb_transfer_function_inv(rgb[1]);
  4360. lrgb[2]=_srgb_transfer_function_inv(rgb[2]);
  4361. tnsRGB2HCYLinear(lrgb,hcy);
  4362. }
  4363. static float hue2rgb(float p, float q, float t) {
  4364. if (t < 0) t += 1; if (t > 1) t -= 1;
  4365. if (t < 1./6) return p + (q - p) * 6 * t;
  4366. if (t < 1./2) return q;
  4367. if (t < 2./3) return p + (q - p) * (2./3 - t) * 6;
  4368. return p;
  4369. }
  4370. void tnsRGB2HSL(real *rgb, real *hsl) {
  4371. float max = TNS_MAX3(rgb[0],rgb[1],rgb[2]);
  4372. float min = TNS_MIN3(rgb[0],rgb[1],rgb[2]);
  4373. hsl[0]=hsl[1]=hsl[2]=(max+min) / 2;
  4374. if (max == min) { hsl[0]=hsl[1]=0; }
  4375. else {
  4376. float d = max - min;
  4377. hsl[1] = (hsl[2] > 0.5) ? d / (2 - max - min) : d / (max + min);
  4378. if (max == rgb[0]) { hsl[0] = (rgb[1] - rgb[2]) / d + (rgb[1] < rgb[2] ? 6 : 0); }
  4379. else if (max == rgb[1]) { hsl[0] = (rgb[2] - rgb[0]) / d + 2; }
  4380. else if (max == rgb[2]) { hsl[0] = (rgb[0] - rgb[1]) / d + 4; }
  4381. hsl[0] /= 6;
  4382. }
  4383. }
  4384. void tnsHSL2RGB(real *hsl, real *rgb) {
  4385. if(hsl[1]==0) {rgb[0]=rgb[1]=rgb[2]=hsl[2];}
  4386. else {
  4387. float q = hsl[2] < 0.5 ? hsl[2] * (1 + hsl[1]) : hsl[2] + hsl[1] - hsl[2] * hsl[1];
  4388. float p = 2 * hsl[2] - q;
  4389. rgb[0] = hue2rgb(p, q, hsl[0] + 1./3);
  4390. rgb[1] = hue2rgb(p, q, hsl[0]);
  4391. rgb[2] = hue2rgb(p, q, hsl[0] - 1./3);
  4392. }
  4393. }
  4394. void tnsClearAll(){
  4395. glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT);
  4396. }
  4397. void tnsClearColorv(real *rgba){
  4398. glClearColor(rgba[0], rgba[1], rgba[2], rgba[3]);
  4399. }
  4400. void tnsClearColor(real r, real g, real b, real a){
  4401. glClearColor(r, g, b, a);
  4402. }
  4403. //Assuming *result is long enough
  4404. void tnsMakeIndexUInt(unsigned int *result, int num, ...){
  4405. int i;
  4406. va_list list;
  4407. va_start(list, num);
  4408. for (i = 0; i < num; i++){
  4409. result[i] = va_arg(list, unsigned int);
  4410. }
  4411. va_end(list);
  4412. }
  4413. void tnsMakeTriangle(real *arr, real x1, real y1, real x2, real y2, real x3, real y3){
  4414. arr[0] = x1;
  4415. arr[1] = y1;
  4416. arr[2] = x2;
  4417. arr[3] = y2;
  4418. arr[4] = x3;
  4419. arr[5] = y3;
  4420. }
  4421. void tnsMakeQuad2d(real *arr, real x1, real y1, real x2, real y2, real x3, real y3, real x4, real y4){
  4422. arr[0] = x1;
  4423. arr[1] = y1;
  4424. arr[2] = x2;
  4425. arr[3] = y2;
  4426. arr[4] = x3;
  4427. arr[5] = y3;
  4428. arr[6] = x4;
  4429. arr[7] = y4;
  4430. }
  4431. void tnsMakeQuadT2d(real *arr, real x1, real y1, real x2, real y2, real x3, real y3, real x4, real y4){
  4432. arr[0] = x1;
  4433. arr[1] = y1;
  4434. arr[2] = x2;
  4435. arr[3] = y2;
  4436. arr[4] = x3;
  4437. arr[5] = y3;
  4438. arr[6] = x2;
  4439. arr[7] = y2;
  4440. arr[8] = x3;
  4441. arr[9] = y3;
  4442. arr[10] = x4;
  4443. arr[11] = y4;
  4444. }
  4445. void tnsMakeQuad3d(real *arr, real x1, real y1, real z1, real x2, real y2, real z2, real x3, real y3, real z3, real x4, real y4, real z4){
  4446. arr[0] = x1;
  4447. arr[1] = y1;
  4448. arr[2] = z1;
  4449. arr[3] = x2;
  4450. arr[4] = y2;
  4451. arr[5] = z2;
  4452. arr[6] = x3;
  4453. arr[7] = y3;
  4454. arr[8] = z3;
  4455. arr[9] = x4;
  4456. arr[10] = y4;
  4457. arr[11] = z4;
  4458. }
  4459. void tnsMakeQuad4d(real *arr, real x1, real y1, real z1, real w1, real x2, real y2, real z2, real w2, real x3, real y3, real z3, real w3, real x4, real y4, real z4, real w4){
  4460. arr[0] = x1;
  4461. arr[1] = y1;
  4462. arr[2] = z1;
  4463. arr[3] = w1;
  4464. arr[4] = x2;
  4465. arr[5] = y2;
  4466. arr[6] = z2;
  4467. arr[7] = w2;
  4468. arr[8] = x3;
  4469. arr[9] = y3;
  4470. arr[10] = z3;
  4471. arr[11] = w3;
  4472. arr[12] = x4;
  4473. arr[13] = y4;
  4474. arr[14] = z4;
  4475. arr[15] = w4;
  4476. }
  4477. void tnsMakeCircle2d(real *arr, int slices, real ctrX, real ctrY, real r, int jump){
  4478. int i;
  4479. real radstep = 2 * TNS_PI / (real)slices;
  4480. real rd = 0;
  4481. real x, y;
  4482. for (i = 0; i < slices; i++){
  4483. x = ctrX + cos(rd) * r;
  4484. y = ctrY + sin(rd) * r;
  4485. int idx=2 * i * (1+jump);
  4486. arr[idx] = x;
  4487. arr[idx+1] = y;
  4488. rd += radstep;
  4489. }
  4490. }
  4491. void tnsMakeArc2d(real *arr, int slices, real ctrX, real ctrY, real r, real rad_begin, real rad_end){
  4492. int i;
  4493. real radstep = (rad_end - rad_begin) / (real)slices;
  4494. real rd = rad_begin;
  4495. real x, y;
  4496. for (i = 0; i <= slices; i++){
  4497. x = ctrX + cos(rd) * r;
  4498. y = ctrY + sin(rd) * r;
  4499. arr[2 * i] = x;
  4500. arr[2 * i + 1] = y;
  4501. rd += radstep;
  4502. }
  4503. }
  4504. void tnsMakeBridgedIndex(unsigned int *result, int num, int revert, int begin){
  4505. int i;
  4506. if (!revert){
  4507. for (i = 0; i < num; i++){
  4508. result[i * 2] = begin + i;
  4509. result[i * 2 + 1] = begin + i + num;
  4510. }
  4511. }else{
  4512. for (i = 0; i < num; i++){
  4513. result[i * 2] = begin + i;
  4514. result[i * 2 + 1] = begin - i + num * 2;
  4515. }
  4516. }
  4517. }
  4518. void tnsMakeRing2d(real *arr, int *index, int slices, real ctrX, real ctrY, real r1, real r2){
  4519. tnsMakeCircle2d(arr, slices, ctrX, ctrY, r1,0);
  4520. tnsMakeCircle2d(&arr[slices*2], slices, ctrX, ctrY, r2,0);
  4521. tnsMakeBridgedIndex(index, slices, 0, 0);
  4522. index[slices*2]=0; index[slices*2+1]=slices;
  4523. }
  4524. void tnsMakeLinerGradient3d(real *arr, int num_points, real r0, real g0, real b0, real r1, real g1, real b1){
  4525. int i = 0;
  4526. real sr = (r1 - r0) / (real)num_points, sg = (g1 - g0) / (real)num_points, sb = (b1 - b0) / (real)num_points;
  4527. for (i; i < num_points; i++){
  4528. int a = 3 * i;
  4529. arr[a] = r0 + sr * i;
  4530. arr[a + 1] = g0 + sg * i;
  4531. arr[a + 2] = b0 + sb * i;
  4532. }
  4533. }
  4534. void tnsMakeLinerGradient4d(real *arr, int num_points, real r0, real g0, real b0, real a0, real r1, real g1, real b1, real a1){
  4535. int i = 0;
  4536. real sr = (r1 - r0) / (real)num_points, sg = (g1 - g0) / (real)num_points, sb = (b1 - b0) / (real)num_points, sa = (a1 - a0) / (real)num_points;
  4537. for (i; i < num_points; i++){
  4538. int a = 4 * i;
  4539. arr[a] = r0 + sr * i;
  4540. arr[a + 1] = g0 + sg * i;
  4541. arr[a + 2] = b0 + sb * i;
  4542. arr[a + 3] = a0 + sa * i;
  4543. }
  4544. }
  4545. void tnsMakeLinerGradient3dv(real *arr, int num_points, real *rgb0, real *rgb1){
  4546. int i = 0;
  4547. real sr = (rgb1[0] - rgb0[0]) / (real)num_points, sg = (rgb1[1] - rgb0[1]) / (real)num_points, sb = (rgb1[2] - rgb0[2]) / (real)num_points;
  4548. for (i; i < num_points; i++){
  4549. int a = 3 * i;
  4550. arr[a] = rgb0[0] + sr * i;
  4551. arr[a + 1] = rgb0[1] + sg * i;
  4552. arr[a + 2] = rgb0[2] + sb * i;
  4553. }
  4554. }
  4555. void tnsMakeLinerGradient4dv(real *arr, int num_points, real *rgb0, real *rgb1){
  4556. int i = 0;
  4557. real sr = (rgb1[0] - rgb0[0]) / (real)(num_points - 1), sg = (rgb1[1] - rgb0[1]) / (real)(num_points - 1), sb = (rgb1[2] - rgb0[2]) / (real)(num_points - 1), sa = (rgb1[3] - rgb0[3]) / (real)(num_points - 1);
  4558. for (i; i < num_points; i++){
  4559. int a = 4 * i;
  4560. arr[a] = rgb0[0] + sr * i;
  4561. arr[a + 1] = rgb0[1] + sg * i;
  4562. arr[a + 2] = rgb0[2] + sb * i;
  4563. arr[a + 3] = rgb0[3] + sa * i;
  4564. }
  4565. }
  4566. void tnsMakeFoucsSquare(int L, int R, int U, int B, int W){
  4567. int w = W;
  4568. //int al = Len + w;
  4569. real v[16];
  4570. //v[0] = L - w; v[1] = U - l;
  4571. //v[2] = L - w; v[3] = U + w;
  4572. //v[4] = L + l; v[4] = U + w;
  4573. //v[6] = L + l; v[7] = U - w;
  4574. //v[8] = L + w; v[9] = U - w;
  4575. //v[10] = L + w; v[11] = U - l;
  4576. //v[12] = R - l; v[13] = U + w;
  4577. //v[14] = R + w; v[15] = U + w;
  4578. //v[16] = R + w; v[17] = U - l;
  4579. //v[18] = R - w; v[19] = U - l;
  4580. //v[20] = R - w; v[21] = U - w;
  4581. //v[22] = R - l; v[23] = U - w;
  4582. tnsMakeQuad2d(v, L, U, R, U, R, B, L, B);
  4583. tnsVertexArray2d(v, 4);
  4584. tnsPackAs(GL_LINE_LOOP);
  4585. tnsMakeQuad2d(&v[8], L + W, U - W, R - W, U - W, R - W, B + W, L + W, B + W);
  4586. tnsVertexArray2d(&v[8], 4);
  4587. tnsPackAs(GL_LINE_LOOP);
  4588. }
  4589. void tnsDrawFloor(real* CamPosition, real Far, int *ShowAxis){
  4590. real OrigFar=Far;
  4591. real height=CamPosition[2];
  4592. real dist=sqrt(fabs(Far*Far-height*height));
  4593. real spanstart=Far/10000;
  4594. real spanl=1e-3,spanh=1e-3;
  4595. while((spanl*10)<spanstart){ spanl*=10; } spanh=spanl;
  4596. while((spanh*10)<Far){ spanh*=10; }
  4597. float usefar=Far;
  4598. tnsFlush();
  4599. glEnable(GL_BLEND); glDepthMask(GL_FALSE); glEnable(GL_DEPTH_TEST);
  4600. tnsUseShader(T->FloorShader);
  4601. tnsEnableShaderv(T->FloorShader);
  4602. //glUniform3f(T->FloorShader->uViewPos,1,1,1);
  4603. usefar=Far; glUniform1fv(T->FloorShader->uFar,1,&usefar);
  4604. real sp=spanh;
  4605. while(sp>=spanl){
  4606. real xmin=((int)((CamPosition[0]-dist-sp)/sp))*sp,xmax=((int)((CamPosition[0]+dist+sp)/sp))*sp;
  4607. real ymin=((int)((CamPosition[1]-dist-sp)/sp))*sp,ymax=((int)((CamPosition[1]+dist+sp)/sp))*sp;
  4608. real ux=xmin; while(ux<xmax){ tnsVertex2d(ux,ymin),tnsVertex2d(ux,ymax); ux+=sp; }
  4609. real uy=ymin; while(uy<ymax){ tnsVertex2d(xmin,uy),tnsVertex2d(xmax,uy); uy+=sp; }
  4610. tnsPackAs(GL_LINES);
  4611. tnsFlush();
  4612. Far/=3; if(Far<height) break;
  4613. dist=sqrt(fabs(Far*Far-height*height)); sp/=10;
  4614. usefar=Far; glUniform1fv(T->FloorShader->uFar,1,&usefar);
  4615. }
  4616. //for (i; i < Lim; i++){
  4617. // if (i == Span && ShowAxis[0]) continue;
  4618. // tnsVertex3d(-Dist, i * Size - Dist, 0);
  4619. // tnsVertex3d(Dist, i * Size - Dist, 0);
  4620. //}
  4621. //
  4622. //for (i = 0; i < Lim; i++){
  4623. // if (i == Span && ShowAxis[1]) continue;
  4624. // tnsVertex3d(i * Size - Dist, -Dist, 0);
  4625. // tnsVertex3d(i * Size - Dist, Dist, 0);
  4626. //}
  4627. //tnsPackAs(GL_LINES);
  4628. usefar=OrigFar; glUniform1fv(T->FloorShader->uFar,1,&usefar);
  4629. if (ShowAxis[0]){ tnsColor4d(1, 0, 0, 1);
  4630. tnsVertex3d(-OrigFar, 0, 0); tnsVertex3d(OrigFar, 0, 0);
  4631. tnsPackAs(GL_LINES);
  4632. }
  4633. if (ShowAxis[1]){ tnsColor4d(0, 1, 0, 1);
  4634. tnsVertex3d(0, -OrigFar, 0); tnsVertex3d(0, OrigFar, 0);
  4635. tnsPackAs(GL_LINES);
  4636. }
  4637. if (ShowAxis[2]){ tnsColor4d(0, 0, 1, 1);
  4638. tnsVertex3d(0, 0, -OrigFar); tnsVertex3d(0, 0, OrigFar);
  4639. tnsPackAs(GL_LINES);
  4640. }
  4641. tnsFlush();
  4642. tnsUseShader(T->immShader);
  4643. tnsEnableShaderv(T->immShader);
  4644. glDepthMask(GL_TRUE);
  4645. }
  4646. void tnsDraw2DGrid10(real L, real R, real U, real B, real xmin, real xmax, real ymin, real ymax, real MostDenseW, real MostDenseH,
  4647. real* color4, real AlphaFactor, int ShowGrid, int TextAlign){
  4648. real span; real W=R-L, H=B-U, rangeX=xmax-xmin, rangeY=ymax-ymin, dW=rangeX/W, dH=rangeY/H;
  4649. real MinSpanW=fabs(MostDenseW*dW), MinSpanH=fabs(MostDenseH*dH);
  4650. for(int i=0;i<20;i++){ span=1e-5*pow(10,i); if(span>MinSpanW) break; }
  4651. real startx=((real)((int)(xmin/span)))*span; real x=startx;
  4652. while(x<xmax){
  4653. real lx=tnsInterpolate(L,R,tnsGetRatiod(xmin,xmax,x));
  4654. tnsVertex2d(lx,U);tnsVertex2d(lx,B); x+=span;
  4655. } tnsColor4d(LA_COLOR3(color4),color4[3]*AlphaFactor*AlphaFactor*AlphaFactor); tnsPackAs(GL_LINES);
  4656. x=startx; while(x<xmax){ if((((int)round(x/span))%5)){ x+=span; continue; }
  4657. real lx=tnsInterpolate(L,R,tnsGetRatiod(xmin,xmax,x));
  4658. tnsVertex2d(lx,U);tnsVertex2d(lx,B); x+=span;
  4659. } tnsColor4d(LA_COLOR3(color4),color4[3]*AlphaFactor*AlphaFactor); tnsPackAs(GL_LINES);
  4660. x=startx; while(x<xmax){ if((((int)round(x/span))%10)){ x+=span; continue; }
  4661. real lx=tnsInterpolate(L,R,tnsGetRatiod(xmin,xmax,x));
  4662. tnsVertex2d(lx,U);tnsVertex2d(lx,B); x+=span;
  4663. } tnsColor4d(LA_COLOR3(color4),color4[3]*AlphaFactor); tnsPackAs(GL_LINES);
  4664. for(int i=0;i<20;i++){ span=1e-5*pow(10,i); if(span>MinSpanH) break; }
  4665. real starty=((real)((int)(ymin/span)))*span; real y=starty;
  4666. while(y<ymax){
  4667. real ly=tnsInterpolate(B,U,tnsGetRatiod(ymin,ymax,y));
  4668. tnsVertex2d(L,ly);tnsVertex2d(R,ly); y+=span;
  4669. } tnsColor4d(LA_COLOR3(color4),color4[3]*AlphaFactor*AlphaFactor*AlphaFactor); tnsPackAs(GL_LINES);
  4670. y=starty; while(y<ymax){ if((((int)round(y/span))%5)){ y+=span; continue; }
  4671. real ly=tnsInterpolate(B,U,tnsGetRatiod(ymin,ymax,y));
  4672. tnsVertex2d(L,ly);tnsVertex2d(R,ly); y+=span;
  4673. } tnsColor4d(LA_COLOR3(color4),color4[3]*AlphaFactor*AlphaFactor); tnsPackAs(GL_LINES);
  4674. y=starty; while(y<ymax){ if((((int)round(y/span))%10)){ y+=span; continue; }
  4675. real ly=tnsInterpolate(B,U,tnsGetRatiod(ymin,ymax,y));
  4676. tnsVertex2d(L,ly);tnsVertex2d(R,ly); y+=span;
  4677. } tnsColor4d(LA_COLOR3(color4),color4[3]*AlphaFactor); tnsPackAs(GL_LINES);
  4678. }