*/}}

la_tns_kernel.c 165 KB

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