gl_main.c 99 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910
  1. /* Emacs style mode select -*- C++ -*-
  2. *-----------------------------------------------------------------------------
  3. *
  4. *
  5. * PrBoom: a Doom port merged with LxDoom and LSDLDoom
  6. * based on BOOM, a modified and improved DOOM engine
  7. * Copyright (C) 1999 by
  8. * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
  9. * Copyright (C) 1999-2000 by
  10. * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
  11. * Copyright 2005, 2006 by
  12. * Florian Schulze, Colin Phipps, Neil Stevens, Andrey Budko
  13. *
  14. * This program is free software; you can redistribute it and/or
  15. * modify it under the terms of the GNU General Public License
  16. * as published by the Free Software Foundation; either version 2
  17. * of the License, or (at your option) any later version.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, write to the Free Software
  26. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  27. * 02111-1307, USA.
  28. *
  29. * DESCRIPTION:
  30. *
  31. *---------------------------------------------------------------------
  32. */
  33. #include "z_zone.h"
  34. #ifdef _WIN32
  35. #define WIN32_LEAN_AND_MEAN
  36. #include <windows.h>
  37. #endif
  38. #ifndef CALLBACK
  39. #define CALLBACK
  40. #endif
  41. #include <stdio.h>
  42. #include <string.h>
  43. #include <math.h>
  44. //#include <SDL.h>
  45. #include "SDL_opengl.h"
  46. #include "doomtype.h"
  47. #include "w_wad.h"
  48. #include "m_argv.h"
  49. #include "d_event.h"
  50. #include "v_video.h"
  51. #include "doomstat.h"
  52. #include "r_bsp.h"
  53. #include "r_main.h"
  54. #include "r_draw.h"
  55. #include "r_sky.h"
  56. #include "r_plane.h"
  57. #include "r_data.h"
  58. #include "r_things.h"
  59. #include "r_fps.h"
  60. #include "p_maputl.h"
  61. #include "m_bbox.h"
  62. #include "lprintf.h"
  63. #include "gl_intern.h"
  64. #include "gl_struct.h"
  65. extern int tran_filter_pct;
  66. // JDC #define USE_VERTEX_ARRAYS
  67. boolean use_fog=false;
  68. int gl_nearclip=5;
  69. char *gl_tex_filter_string;
  70. int gl_tex_filter;
  71. int gl_mipmap_filter;
  72. int gl_drawskys=true;
  73. int gl_sortsprites=true;
  74. int gl_texture_filter_anisotropic = 0;
  75. int gl_use_paletted_texture = 0;
  76. int gl_use_shared_texture_palette = 0;
  77. int gl_paletted_texture = 0;
  78. int gl_shared_texture_palette = 0;
  79. int gl_sprite_offset; // item out of floor offset Mead 8/13/03
  80. GLuint gld_DisplayList=0;
  81. int fog_density=200;
  82. static float extra_red=0.0f;
  83. static float extra_green=0.0f;
  84. static float extra_blue=0.0f;
  85. static float extra_alpha=0.0f;
  86. byte *staticPlaypal; // JDC: this was being looked up for every line
  87. GLfloat gl_whitecolor[4]={1.0f,1.0f,1.0f,1.0f};
  88. #if 0 // JDC: moved to header
  89. #define MAP_COEFF 128.0f
  90. #define MAP_SCALE (MAP_COEFF*(float)FRACUNIT)
  91. #endif
  92. /*
  93. * lookuptable for lightvalues
  94. * calculated as follow:
  95. * floatlight=(1.0-exp((light^3)*gamma)) / (1.0-exp(1.0*gamma));
  96. * gamma=-0,2;-2,0;-4,0;-6,0;-8,0
  97. * light=0,0 .. 1,0
  98. */
  99. static const float lighttable[5][256] =
  100. {
  101. {
  102. 0.00000f,0.00000f,0.00000f,0.00000f,0.00000f,0.00001f,0.00001f,0.00002f,0.00003f,0.00004f,
  103. 0.00006f,0.00008f,0.00010f,0.00013f,0.00017f,0.00020f,0.00025f,0.00030f,0.00035f,0.00041f,
  104. 0.00048f,0.00056f,0.00064f,0.00073f,0.00083f,0.00094f,0.00106f,0.00119f,0.00132f,0.00147f,
  105. 0.00163f,0.00180f,0.00198f,0.00217f,0.00237f,0.00259f,0.00281f,0.00305f,0.00331f,0.00358f,
  106. 0.00386f,0.00416f,0.00447f,0.00479f,0.00514f,0.00550f,0.00587f,0.00626f,0.00667f,0.00710f,
  107. 0.00754f,0.00800f,0.00848f,0.00898f,0.00950f,0.01003f,0.01059f,0.01117f,0.01177f,0.01239f,
  108. 0.01303f,0.01369f,0.01437f,0.01508f,0.01581f,0.01656f,0.01734f,0.01814f,0.01896f,0.01981f,
  109. 0.02069f,0.02159f,0.02251f,0.02346f,0.02444f,0.02544f,0.02647f,0.02753f,0.02862f,0.02973f,
  110. 0.03088f,0.03205f,0.03325f,0.03448f,0.03575f,0.03704f,0.03836f,0.03971f,0.04110f,0.04252f,
  111. 0.04396f,0.04545f,0.04696f,0.04851f,0.05009f,0.05171f,0.05336f,0.05504f,0.05676f,0.05852f,
  112. 0.06031f,0.06214f,0.06400f,0.06590f,0.06784f,0.06981f,0.07183f,0.07388f,0.07597f,0.07810f,
  113. 0.08027f,0.08248f,0.08473f,0.08702f,0.08935f,0.09172f,0.09414f,0.09659f,0.09909f,0.10163f,
  114. 0.10421f,0.10684f,0.10951f,0.11223f,0.11499f,0.11779f,0.12064f,0.12354f,0.12648f,0.12946f,
  115. 0.13250f,0.13558f,0.13871f,0.14188f,0.14511f,0.14838f,0.15170f,0.15507f,0.15850f,0.16197f,
  116. 0.16549f,0.16906f,0.17268f,0.17635f,0.18008f,0.18386f,0.18769f,0.19157f,0.19551f,0.19950f,
  117. 0.20354f,0.20764f,0.21179f,0.21600f,0.22026f,0.22458f,0.22896f,0.23339f,0.23788f,0.24242f,
  118. 0.24702f,0.25168f,0.25640f,0.26118f,0.26602f,0.27091f,0.27587f,0.28089f,0.28596f,0.29110f,
  119. 0.29630f,0.30156f,0.30688f,0.31226f,0.31771f,0.32322f,0.32879f,0.33443f,0.34013f,0.34589f,
  120. 0.35172f,0.35761f,0.36357f,0.36960f,0.37569f,0.38185f,0.38808f,0.39437f,0.40073f,0.40716f,
  121. 0.41366f,0.42022f,0.42686f,0.43356f,0.44034f,0.44718f,0.45410f,0.46108f,0.46814f,0.47527f,
  122. 0.48247f,0.48974f,0.49709f,0.50451f,0.51200f,0.51957f,0.52721f,0.53492f,0.54271f,0.55058f,
  123. 0.55852f,0.56654f,0.57463f,0.58280f,0.59105f,0.59937f,0.60777f,0.61625f,0.62481f,0.63345f,
  124. 0.64217f,0.65096f,0.65984f,0.66880f,0.67783f,0.68695f,0.69615f,0.70544f,0.71480f,0.72425f,
  125. 0.73378f,0.74339f,0.75308f,0.76286f,0.77273f,0.78268f,0.79271f,0.80283f,0.81304f,0.82333f,
  126. 0.83371f,0.84417f,0.85472f,0.86536f,0.87609f,0.88691f,0.89781f,0.90880f,0.91989f,0.93106f,
  127. 0.94232f,0.95368f,0.96512f,0.97665f,0.98828f,1.00000
  128. },
  129. {
  130. 0.00000f,0.00000f,0.00000f,0.00000f,0.00001f,0.00002f,0.00003f,0.00005f,0.00007f,0.00010f,
  131. 0.00014f,0.00019f,0.00024f,0.00031f,0.00038f,0.00047f,0.00057f,0.00069f,0.00081f,0.00096f,
  132. 0.00112f,0.00129f,0.00148f,0.00170f,0.00193f,0.00218f,0.00245f,0.00274f,0.00306f,0.00340f,
  133. 0.00376f,0.00415f,0.00456f,0.00500f,0.00547f,0.00597f,0.00649f,0.00704f,0.00763f,0.00825f,
  134. 0.00889f,0.00957f,0.01029f,0.01104f,0.01182f,0.01264f,0.01350f,0.01439f,0.01532f,0.01630f,
  135. 0.01731f,0.01836f,0.01945f,0.02058f,0.02176f,0.02298f,0.02424f,0.02555f,0.02690f,0.02830f,
  136. 0.02974f,0.03123f,0.03277f,0.03436f,0.03600f,0.03768f,0.03942f,0.04120f,0.04304f,0.04493f,
  137. 0.04687f,0.04886f,0.05091f,0.05301f,0.05517f,0.05738f,0.05964f,0.06196f,0.06434f,0.06677f,
  138. 0.06926f,0.07181f,0.07441f,0.07707f,0.07979f,0.08257f,0.08541f,0.08831f,0.09126f,0.09428f,
  139. 0.09735f,0.10048f,0.10368f,0.10693f,0.11025f,0.11362f,0.11706f,0.12056f,0.12411f,0.12773f,
  140. 0.13141f,0.13515f,0.13895f,0.14281f,0.14673f,0.15072f,0.15476f,0.15886f,0.16303f,0.16725f,
  141. 0.17153f,0.17587f,0.18028f,0.18474f,0.18926f,0.19383f,0.19847f,0.20316f,0.20791f,0.21272f,
  142. 0.21759f,0.22251f,0.22748f,0.23251f,0.23760f,0.24274f,0.24793f,0.25318f,0.25848f,0.26383f,
  143. 0.26923f,0.27468f,0.28018f,0.28573f,0.29133f,0.29697f,0.30266f,0.30840f,0.31418f,0.32001f,
  144. 0.32588f,0.33179f,0.33774f,0.34374f,0.34977f,0.35585f,0.36196f,0.36810f,0.37428f,0.38050f,
  145. 0.38675f,0.39304f,0.39935f,0.40570f,0.41207f,0.41847f,0.42490f,0.43136f,0.43784f,0.44434f,
  146. 0.45087f,0.45741f,0.46398f,0.47057f,0.47717f,0.48379f,0.49042f,0.49707f,0.50373f,0.51041f,
  147. 0.51709f,0.52378f,0.53048f,0.53718f,0.54389f,0.55061f,0.55732f,0.56404f,0.57075f,0.57747f,
  148. 0.58418f,0.59089f,0.59759f,0.60429f,0.61097f,0.61765f,0.62432f,0.63098f,0.63762f,0.64425f,
  149. 0.65086f,0.65746f,0.66404f,0.67060f,0.67714f,0.68365f,0.69015f,0.69662f,0.70307f,0.70948f,
  150. 0.71588f,0.72224f,0.72857f,0.73488f,0.74115f,0.74739f,0.75359f,0.75976f,0.76589f,0.77199f,
  151. 0.77805f,0.78407f,0.79005f,0.79599f,0.80189f,0.80774f,0.81355f,0.81932f,0.82504f,0.83072f,
  152. 0.83635f,0.84194f,0.84747f,0.85296f,0.85840f,0.86378f,0.86912f,0.87441f,0.87964f,0.88482f,
  153. 0.88995f,0.89503f,0.90005f,0.90502f,0.90993f,0.91479f,0.91959f,0.92434f,0.92903f,0.93366f,
  154. 0.93824f,0.94276f,0.94723f,0.95163f,0.95598f,0.96027f,0.96451f,0.96868f,0.97280f,0.97686f,
  155. 0.98086f,0.98481f,0.98869f,0.99252f,0.99629f,1.00000f
  156. },
  157. {
  158. 0.00000f,0.00000f,0.00000f,0.00001f,0.00002f,0.00003f,0.00005f,0.00008f,0.00013f,0.00018f,
  159. 0.00025f,0.00033f,0.00042f,0.00054f,0.00067f,0.00083f,0.00101f,0.00121f,0.00143f,0.00168f,
  160. 0.00196f,0.00227f,0.00261f,0.00299f,0.00339f,0.00383f,0.00431f,0.00483f,0.00538f,0.00598f,
  161. 0.00661f,0.00729f,0.00802f,0.00879f,0.00961f,0.01048f,0.01140f,0.01237f,0.01340f,0.01447f,
  162. 0.01561f,0.01680f,0.01804f,0.01935f,0.02072f,0.02215f,0.02364f,0.02520f,0.02682f,0.02850f,
  163. 0.03026f,0.03208f,0.03397f,0.03594f,0.03797f,0.04007f,0.04225f,0.04451f,0.04684f,0.04924f,
  164. 0.05172f,0.05428f,0.05691f,0.05963f,0.06242f,0.06530f,0.06825f,0.07129f,0.07441f,0.07761f,
  165. 0.08089f,0.08426f,0.08771f,0.09125f,0.09487f,0.09857f,0.10236f,0.10623f,0.11019f,0.11423f,
  166. 0.11836f,0.12257f,0.12687f,0.13125f,0.13571f,0.14027f,0.14490f,0.14962f,0.15442f,0.15931f,
  167. 0.16427f,0.16932f,0.17445f,0.17966f,0.18496f,0.19033f,0.19578f,0.20130f,0.20691f,0.21259f,
  168. 0.21834f,0.22417f,0.23007f,0.23605f,0.24209f,0.24820f,0.25438f,0.26063f,0.26694f,0.27332f,
  169. 0.27976f,0.28626f,0.29282f,0.29944f,0.30611f,0.31284f,0.31962f,0.32646f,0.33334f,0.34027f,
  170. 0.34724f,0.35426f,0.36132f,0.36842f,0.37556f,0.38273f,0.38994f,0.39718f,0.40445f,0.41174f,
  171. 0.41907f,0.42641f,0.43378f,0.44116f,0.44856f,0.45598f,0.46340f,0.47084f,0.47828f,0.48573f,
  172. 0.49319f,0.50064f,0.50809f,0.51554f,0.52298f,0.53042f,0.53784f,0.54525f,0.55265f,0.56002f,
  173. 0.56738f,0.57472f,0.58203f,0.58932f,0.59658f,0.60381f,0.61101f,0.61817f,0.62529f,0.63238f,
  174. 0.63943f,0.64643f,0.65339f,0.66031f,0.66717f,0.67399f,0.68075f,0.68746f,0.69412f,0.70072f,
  175. 0.70726f,0.71375f,0.72017f,0.72653f,0.73282f,0.73905f,0.74522f,0.75131f,0.75734f,0.76330f,
  176. 0.76918f,0.77500f,0.78074f,0.78640f,0.79199f,0.79751f,0.80295f,0.80831f,0.81359f,0.81880f,
  177. 0.82393f,0.82898f,0.83394f,0.83883f,0.84364f,0.84836f,0.85301f,0.85758f,0.86206f,0.86646f,
  178. 0.87078f,0.87502f,0.87918f,0.88326f,0.88726f,0.89118f,0.89501f,0.89877f,0.90245f,0.90605f,
  179. 0.90957f,0.91301f,0.91638f,0.91966f,0.92288f,0.92601f,0.92908f,0.93206f,0.93498f,0.93782f,
  180. 0.94059f,0.94329f,0.94592f,0.94848f,0.95097f,0.95339f,0.95575f,0.95804f,0.96027f,0.96244f,
  181. 0.96454f,0.96658f,0.96856f,0.97049f,0.97235f,0.97416f,0.97591f,0.97760f,0.97924f,0.98083f,
  182. 0.98237f,0.98386f,0.98530f,0.98669f,0.98803f,0.98933f,0.99058f,0.99179f,0.99295f,0.99408f,
  183. 0.99516f,0.99620f,0.99721f,0.99817f,0.99910f,1.00000f
  184. },
  185. {
  186. 0.00000f,0.00000f,0.00000f,0.00001f,0.00002f,0.00005f,0.00008f,0.00012f,0.00019f,0.00026f,
  187. 0.00036f,0.00048f,0.00063f,0.00080f,0.00099f,0.00122f,0.00148f,0.00178f,0.00211f,0.00249f,
  188. 0.00290f,0.00335f,0.00386f,0.00440f,0.00500f,0.00565f,0.00636f,0.00711f,0.00793f,0.00881f,
  189. 0.00975f,0.01075f,0.01182f,0.01295f,0.01416f,0.01543f,0.01678f,0.01821f,0.01971f,0.02129f,
  190. 0.02295f,0.02469f,0.02652f,0.02843f,0.03043f,0.03252f,0.03469f,0.03696f,0.03933f,0.04178f,
  191. 0.04433f,0.04698f,0.04973f,0.05258f,0.05552f,0.05857f,0.06172f,0.06498f,0.06834f,0.07180f,
  192. 0.07537f,0.07905f,0.08283f,0.08672f,0.09072f,0.09483f,0.09905f,0.10337f,0.10781f,0.11236f,
  193. 0.11701f,0.12178f,0.12665f,0.13163f,0.13673f,0.14193f,0.14724f,0.15265f,0.15817f,0.16380f,
  194. 0.16954f,0.17538f,0.18132f,0.18737f,0.19351f,0.19976f,0.20610f,0.21255f,0.21908f,0.22572f,
  195. 0.23244f,0.23926f,0.24616f,0.25316f,0.26023f,0.26739f,0.27464f,0.28196f,0.28935f,0.29683f,
  196. 0.30437f,0.31198f,0.31966f,0.32740f,0.33521f,0.34307f,0.35099f,0.35896f,0.36699f,0.37506f,
  197. 0.38317f,0.39133f,0.39952f,0.40775f,0.41601f,0.42429f,0.43261f,0.44094f,0.44929f,0.45766f,
  198. 0.46604f,0.47443f,0.48283f,0.49122f,0.49962f,0.50801f,0.51639f,0.52476f,0.53312f,0.54146f,
  199. 0.54978f,0.55807f,0.56633f,0.57457f,0.58277f,0.59093f,0.59905f,0.60713f,0.61516f,0.62314f,
  200. 0.63107f,0.63895f,0.64676f,0.65452f,0.66221f,0.66984f,0.67739f,0.68488f,0.69229f,0.69963f,
  201. 0.70689f,0.71407f,0.72117f,0.72818f,0.73511f,0.74195f,0.74870f,0.75536f,0.76192f,0.76839f,
  202. 0.77477f,0.78105f,0.78723f,0.79331f,0.79930f,0.80518f,0.81096f,0.81664f,0.82221f,0.82768f,
  203. 0.83305f,0.83832f,0.84347f,0.84853f,0.85348f,0.85832f,0.86306f,0.86770f,0.87223f,0.87666f,
  204. 0.88098f,0.88521f,0.88933f,0.89334f,0.89726f,0.90108f,0.90480f,0.90842f,0.91194f,0.91537f,
  205. 0.91870f,0.92193f,0.92508f,0.92813f,0.93109f,0.93396f,0.93675f,0.93945f,0.94206f,0.94459f,
  206. 0.94704f,0.94941f,0.95169f,0.95391f,0.95604f,0.95810f,0.96009f,0.96201f,0.96386f,0.96564f,
  207. 0.96735f,0.96900f,0.97059f,0.97212f,0.97358f,0.97499f,0.97634f,0.97764f,0.97888f,0.98007f,
  208. 0.98122f,0.98231f,0.98336f,0.98436f,0.98531f,0.98623f,0.98710f,0.98793f,0.98873f,0.98949f,
  209. 0.99021f,0.99090f,0.99155f,0.99218f,0.99277f,0.99333f,0.99387f,0.99437f,0.99486f,0.99531f,
  210. 0.99575f,0.99616f,0.99654f,0.99691f,0.99726f,0.99759f,0.99790f,0.99819f,0.99847f,0.99873f,
  211. 0.99897f,0.99920f,0.99942f,0.99963f,0.99982f,1.00000f
  212. },
  213. {
  214. 0.00000f,0.00000f,0.00000f,0.00001f,0.00003f,0.00006f,0.00010f,0.00017f,0.00025f,0.00035f,
  215. 0.00048f,0.00064f,0.00083f,0.00106f,0.00132f,0.00163f,0.00197f,0.00237f,0.00281f,0.00330f,
  216. 0.00385f,0.00446f,0.00513f,0.00585f,0.00665f,0.00751f,0.00845f,0.00945f,0.01054f,0.01170f,
  217. 0.01295f,0.01428f,0.01569f,0.01719f,0.01879f,0.02048f,0.02227f,0.02415f,0.02614f,0.02822f,
  218. 0.03042f,0.03272f,0.03513f,0.03765f,0.04028f,0.04303f,0.04589f,0.04887f,0.05198f,0.05520f,
  219. 0.05855f,0.06202f,0.06561f,0.06933f,0.07318f,0.07716f,0.08127f,0.08550f,0.08987f,0.09437f,
  220. 0.09900f,0.10376f,0.10866f,0.11369f,0.11884f,0.12414f,0.12956f,0.13512f,0.14080f,0.14662f,
  221. 0.15257f,0.15865f,0.16485f,0.17118f,0.17764f,0.18423f,0.19093f,0.19776f,0.20471f,0.21177f,
  222. 0.21895f,0.22625f,0.23365f,0.24117f,0.24879f,0.25652f,0.26435f,0.27228f,0.28030f,0.28842f,
  223. 0.29662f,0.30492f,0.31329f,0.32175f,0.33028f,0.33889f,0.34756f,0.35630f,0.36510f,0.37396f,
  224. 0.38287f,0.39183f,0.40084f,0.40989f,0.41897f,0.42809f,0.43723f,0.44640f,0.45559f,0.46479f,
  225. 0.47401f,0.48323f,0.49245f,0.50167f,0.51088f,0.52008f,0.52927f,0.53843f,0.54757f,0.55668f,
  226. 0.56575f,0.57479f,0.58379f,0.59274f,0.60164f,0.61048f,0.61927f,0.62799f,0.63665f,0.64524f,
  227. 0.65376f,0.66220f,0.67056f,0.67883f,0.68702f,0.69511f,0.70312f,0.71103f,0.71884f,0.72655f,
  228. 0.73415f,0.74165f,0.74904f,0.75632f,0.76348f,0.77053f,0.77747f,0.78428f,0.79098f,0.79756f,
  229. 0.80401f,0.81035f,0.81655f,0.82264f,0.82859f,0.83443f,0.84013f,0.84571f,0.85117f,0.85649f,
  230. 0.86169f,0.86677f,0.87172f,0.87654f,0.88124f,0.88581f,0.89026f,0.89459f,0.89880f,0.90289f,
  231. 0.90686f,0.91071f,0.91445f,0.91807f,0.92157f,0.92497f,0.92826f,0.93143f,0.93450f,0.93747f,
  232. 0.94034f,0.94310f,0.94577f,0.94833f,0.95081f,0.95319f,0.95548f,0.95768f,0.95980f,0.96183f,
  233. 0.96378f,0.96565f,0.96744f,0.96916f,0.97081f,0.97238f,0.97388f,0.97532f,0.97669f,0.97801f,
  234. 0.97926f,0.98045f,0.98158f,0.98266f,0.98369f,0.98467f,0.98560f,0.98648f,0.98732f,0.98811f,
  235. 0.98886f,0.98958f,0.99025f,0.99089f,0.99149f,0.99206f,0.99260f,0.99311f,0.99359f,0.99404f,
  236. 0.99446f,0.99486f,0.99523f,0.99559f,0.99592f,0.99623f,0.99652f,0.99679f,0.99705f,0.99729f,
  237. 0.99751f,0.99772f,0.99792f,0.99810f,0.99827f,0.99843f,0.99857f,0.99871f,0.99884f,0.99896f,
  238. 0.99907f,0.99917f,0.99926f,0.99935f,0.99943f,0.99951f,0.99958f,0.99964f,0.99970f,0.99975f,
  239. 0.99980f,0.99985f,0.99989f,0.99993f,0.99997f,1.00000f
  240. }
  241. };
  242. #define gld_CalcLightLevel(lightlevel) (lighttable[usegamma][MAX(MIN((lightlevel),255),0)])
  243. /*
  244. // experimental new lighting code
  245. static float gld_CalcLightLevel(int lightlevel) {
  246. if (lightlevel < 192) {
  247. lightlevel = lightlevel - ((192 - lightlevel) * 85 / 100);
  248. }
  249. if (lightlevel < 20)
  250. lightlevel = 20;
  251. return lightlevel / 255.0;
  252. }
  253. */
  254. static void gld_StaticLightAlpha(float light, float alpha)
  255. {
  256. player_t *player;
  257. player = &players[displayplayer];
  258. if (player->fixedcolormap)
  259. glColor4f(1.0f, 1.0f, 1.0f, alpha);
  260. else
  261. glColor4f(light, light, light, alpha);
  262. }
  263. #define gld_StaticLight(light) gld_StaticLightAlpha(light, 1.0f)
  264. static void gld_InitExtensions(const char *_extensions)
  265. {
  266. char *extensions;
  267. char *extension;
  268. char *p;
  269. if (!_extensions)
  270. return;
  271. extensions = malloc(strlen(_extensions) + 1);
  272. if (!extensions)
  273. return;
  274. memcpy(extensions, _extensions, strlen(_extensions) + 1);
  275. p = extensions;
  276. extension = p;
  277. do {
  278. while ((*p != ' ') && (*p != '\0'))
  279. p++;
  280. if (*p != '\0')
  281. *p++ = '\0';
  282. while (*p == ' ')
  283. p++;
  284. if (strcasecmp(extension, "GL_EXT_texture_filter_anisotropic") == 0)
  285. gl_texture_filter_anisotropic = true;
  286. else if (strcasecmp(extension, "GL_EXT_paletted_texture") == 0) {
  287. if (gl_use_paletted_texture) {
  288. gl_paletted_texture = true;
  289. gld_ColorTableEXT = SDL_GL_GetProcAddress("glColorTableEXT");
  290. if (gld_ColorTableEXT == NULL)
  291. gl_paletted_texture = false;
  292. else
  293. lprintf(LO_INFO,"using GL_EXT_paletted_texture\n");
  294. }
  295. }
  296. else if (strcasecmp(extension, "GL_EXT_shared_texture_palette") == 0)
  297. if (gl_use_shared_texture_palette) {
  298. gl_shared_texture_palette = true;
  299. gld_ColorTableEXT = SDL_GL_GetProcAddress("glColorTableEXT");
  300. if (gld_ColorTableEXT == NULL)
  301. gl_shared_texture_palette = false;
  302. else
  303. lprintf(LO_INFO,"using GL_EXT_shared_texture_palette\n");
  304. }
  305. extension = p;
  306. } while (*extension != '\0');
  307. free(extensions);
  308. }
  309. void gld_Init(int width, int height)
  310. {
  311. GLfloat params[4]={0.0f,0.0f,1.0f,0.0f};
  312. GLfloat BlackFogColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
  313. // JDC: read PLAYPAL just once, instead of before every line / fill / texture build
  314. // we are going to assume that this never gets changed in a wad file.
  315. {
  316. int lumpNum = W_GetNumForName( "PLAYPAL" );
  317. staticPlaypal = malloc( W_LumpLength( lumpNum ) );
  318. W_ReadLump( lumpNum, staticPlaypal );
  319. }
  320. lprintf(LO_INFO,"GL_VENDOR: %s\n",glGetString(GL_VENDOR));
  321. lprintf(LO_INFO,"GL_RENDERER: %s\n",glGetString(GL_RENDERER));
  322. lprintf(LO_INFO,"GL_VERSION: %s\n",glGetString(GL_VERSION));
  323. lprintf(LO_INFO,"GL_EXTENSIONS:\n");
  324. {
  325. char ext_name[256];
  326. const char *extensions = (char *)glGetString(GL_EXTENSIONS); // JDC: fix warning
  327. const char *rover = extensions;
  328. const char *p = rover;
  329. while (*rover)
  330. {
  331. p = rover;
  332. while (*p && *p != ' ')
  333. p++;
  334. if (*p)
  335. {
  336. int len = MIN(p-rover, sizeof(ext_name)-1);
  337. memset(ext_name, 0, sizeof(ext_name));
  338. strncpy(ext_name, rover, len);
  339. lprintf(LO_INFO,"\t%s\n", ext_name);
  340. }
  341. rover = p;
  342. while (*rover && *rover == ' ')
  343. rover++;
  344. }
  345. }
  346. gld_InitExtensions( (const char *)glGetString(GL_EXTENSIONS)); // JDC: fix pointer warning
  347. //gl_shared_texture_palette = false;
  348. gld_InitPalettedTextures();
  349. glViewport(0, 0, SCREENWIDTH, SCREENHEIGHT);
  350. glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  351. glClearDepth(1.0f);
  352. glGetIntegerv(GL_MAX_TEXTURE_SIZE,&gld_max_texturesize);
  353. //gld_max_texturesize=16;
  354. lprintf(LO_INFO,"GL_MAX_TEXTURE_SIZE=%i\n",gld_max_texturesize);
  355. glEnable(GL_BLEND);
  356. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  357. glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  358. glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // proff_dis
  359. glShadeModel(GL_FLAT);
  360. glEnable(GL_TEXTURE_2D);
  361. glDepthFunc(GL_LEQUAL);
  362. glEnable(GL_ALPHA_TEST);
  363. glAlphaFunc(GL_GEQUAL,0.5f);
  364. glDisable(GL_CULL_FACE);
  365. glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_MODULATE);
  366. glTexGenfv(GL_Q,GL_EYE_PLANE,params);
  367. glTexGenf(GL_S,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
  368. glTexGenf(GL_T,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
  369. glTexGenf(GL_Q,GL_TEXTURE_GEN_MODE,GL_EYE_LINEAR);
  370. glFogi (GL_FOG_MODE, GL_EXP);
  371. glFogfv(GL_FOG_COLOR, BlackFogColor);
  372. glFogf (GL_FOG_DENSITY, (float)fog_density/1000.0f);
  373. glHint (GL_FOG_HINT, GL_NICEST);
  374. glFogf (GL_FOG_START, 0.0f);
  375. glFogf (GL_FOG_END, 1.0f);
  376. if (!strcasecmp(gl_tex_filter_string,"GL_NEAREST_MIPMAP_NEAREST"))
  377. {
  378. use_mipmapping=true;
  379. gl_shared_texture_palette = false;
  380. lprintf(LO_INFO,"Using GL_NEAREST for normal textures.\n");
  381. lprintf(LO_INFO,"Using GL_NEAREST_MIPMAP_NEAREST for mipmap textures.\n");
  382. gl_tex_filter=GL_NEAREST;
  383. gl_mipmap_filter=GL_NEAREST_MIPMAP_NEAREST;
  384. }
  385. else
  386. if (!strcasecmp(gl_tex_filter_string,"GL_LINEAR_MIPMAP_NEAREST"))
  387. {
  388. use_mipmapping=true;
  389. gl_shared_texture_palette = false;
  390. lprintf(LO_INFO,"Using GL_LINEAR for normal textures.\n");
  391. lprintf(LO_INFO,"Using GL_LINEAR_MIPMAP_NEAREST for mipmap textures.\n");
  392. gl_tex_filter=GL_LINEAR;
  393. gl_mipmap_filter=GL_LINEAR_MIPMAP_NEAREST;
  394. }
  395. else
  396. if (!strcasecmp(gl_tex_filter_string,"GL_NEAREST_MIPMAP_LINEAR"))
  397. {
  398. use_mipmapping=true;
  399. gl_shared_texture_palette = false;
  400. lprintf(LO_INFO,"Using GL_NEAREST for normal textures.\n");
  401. lprintf(LO_INFO,"Using GL_NEAREST_MIPMAP_LINEAR for mipmap textures.\n");
  402. gl_tex_filter=GL_NEAREST;
  403. gl_mipmap_filter=GL_NEAREST_MIPMAP_LINEAR;
  404. }
  405. else
  406. if (!strcasecmp(gl_tex_filter_string,"GL_LINEAR_MIPMAP_LINEAR"))
  407. {
  408. use_mipmapping=true;
  409. gl_shared_texture_palette = false;
  410. lprintf(LO_INFO,"Using GL_LINEAR for normal textures.\n");
  411. lprintf(LO_INFO,"Using GL_LINEAR_MIPMAP_LINEAR for mipmap textures.\n");
  412. gl_tex_filter=GL_LINEAR;
  413. gl_mipmap_filter=GL_LINEAR_MIPMAP_LINEAR;
  414. }
  415. else
  416. if (!strcasecmp(gl_tex_filter_string,"GL_NEAREST"))
  417. {
  418. use_mipmapping=false;
  419. lprintf(LO_INFO,"Using GL_NEAREST for textures.\n");
  420. gl_tex_filter=GL_NEAREST;
  421. gl_mipmap_filter=GL_NEAREST;
  422. }
  423. else
  424. {
  425. use_mipmapping=false;
  426. lprintf(LO_INFO,"Using GL_LINEAR for textures.\n");
  427. gl_tex_filter=GL_LINEAR;
  428. gl_mipmap_filter=GL_LINEAR;
  429. }
  430. #ifndef USE_GLU_MIPMAP
  431. use_mipmapping = false;
  432. #endif
  433. if (!strcasecmp(gl_tex_format_string,"GL_RGBA8"))
  434. {
  435. gl_tex_format=GL_RGBA8;
  436. lprintf(LO_INFO,"Using texture format GL_RGBA8.\n");
  437. }
  438. else
  439. if (!strcasecmp(gl_tex_format_string,"GL_RGB5_A1"))
  440. {
  441. gl_tex_format=GL_RGB5_A1;
  442. lprintf(LO_INFO,"Using texture format GL_RGB5_A1.\n");
  443. }
  444. else
  445. if (!strcasecmp(gl_tex_format_string,"GL_RGBA4"))
  446. {
  447. gl_tex_format=GL_RGBA4;
  448. lprintf(LO_INFO,"Using texture format GL_RGBA4.\n");
  449. }
  450. else
  451. if (!strcasecmp(gl_tex_format_string,"GL_RGBA2"))
  452. {
  453. gl_tex_format=GL_RGBA2;
  454. lprintf(LO_INFO,"Using texture format GL_RGBA2.\n");
  455. }
  456. else
  457. {
  458. gl_tex_format=GL_RGBA;
  459. lprintf(LO_INFO,"Using texture format GL_RGBA.\n");
  460. }
  461. }
  462. void gld_InitCommandLine(void)
  463. {
  464. }
  465. #define SCALE_X(x) ((flags & VPT_STRETCH)?((float)x)*(float)SCREENWIDTH/320.0f:(float)x)
  466. #define SCALE_Y(y) ((flags & VPT_STRETCH)?((float)y)*(float)SCREENHEIGHT/200.0f:(float)y)
  467. void gld_DrawNumPatch(int x, int y, int lump, int cm, enum patch_translation_e flags)
  468. {
  469. GLTexture *gltexture;
  470. float fU1,fU2,fV1,fV2;
  471. float width,height;
  472. float xpos, ypos;
  473. if (flags & VPT_TRANS)
  474. {
  475. gltexture=gld_RegisterPatch(lump,cm);
  476. gld_BindPatch(gltexture, cm);
  477. }
  478. else
  479. {
  480. gltexture=gld_RegisterPatch(lump,CR_DEFAULT);
  481. gld_BindPatch(gltexture, CR_DEFAULT);
  482. }
  483. if (!gltexture)
  484. return;
  485. fV1=0.0f;
  486. fV2=(float)gltexture->height/(float)gltexture->tex_height;
  487. if (flags & VPT_FLIP)
  488. {
  489. fU1=(float)gltexture->width/(float)gltexture->tex_width;
  490. fU2=0.0f;
  491. }
  492. else
  493. {
  494. fU1=0.0f;
  495. fU2=(float)gltexture->width/(float)gltexture->tex_width;
  496. }
  497. xpos=SCALE_X(x-gltexture->leftoffset);
  498. ypos=SCALE_Y(y-gltexture->topoffset);
  499. width=SCALE_X(gltexture->realtexwidth);
  500. height=SCALE_Y(gltexture->realtexheight);
  501. glBegin(GL_TRIANGLE_STRIP);
  502. glTexCoord2f(fU1, fV1); glVertex2f((xpos),(ypos));
  503. glTexCoord2f(fU1, fV2); glVertex2f((xpos),(ypos+height));
  504. glTexCoord2f(fU2, fV1); glVertex2f((xpos+width),(ypos));
  505. glTexCoord2f(fU2, fV2); glVertex2f((xpos+width),(ypos+height));
  506. glEnd();
  507. }
  508. #undef SCALE_X
  509. #undef SCALE_Y
  510. void gld_DrawBackground(const char* name)
  511. {
  512. GLTexture *gltexture;
  513. float fU1,fU2,fV1,fV2;
  514. int width,height;
  515. gltexture=gld_RegisterFlat(R_FlatNumForName(name), false);
  516. gld_BindFlat(gltexture);
  517. if (!gltexture)
  518. return;
  519. fU1=0;
  520. fV1=0;
  521. fU2=(float)SCREENWIDTH/(float)gltexture->realtexwidth;
  522. fV2=(float)SCREENHEIGHT/(float)gltexture->realtexheight;
  523. width=SCREENWIDTH;
  524. height=SCREENHEIGHT;
  525. glBegin(GL_TRIANGLE_STRIP);
  526. glTexCoord2f(fU1, fV1); glVertex2f((float)(0),(float)(0));
  527. glTexCoord2f(fU1, fV2); glVertex2f((float)(0),(float)(0+height));
  528. glTexCoord2f(fU2, fV1); glVertex2f((float)(0+width),(float)(0));
  529. glTexCoord2f(fU2, fV2); glVertex2f((float)(0+width),(float)(0+height));
  530. glEnd();
  531. }
  532. void gld_DrawLine(int x0, int y0, int x1, int y1, int BaseColor)
  533. {
  534. // JDC const unsigned char *playpal=W_CacheLumpName("PLAYPAL");
  535. glBindTexture(GL_TEXTURE_2D, 0);
  536. last_gltexture = NULL;
  537. last_cm = -1;
  538. glColor3f((float)staticPlaypal[3*BaseColor]/255.0f, // JDC: changed to not lookup PLAYPAL every time
  539. (float)staticPlaypal[3*BaseColor+1]/255.0f,
  540. (float)staticPlaypal[3*BaseColor+2]/255.0f);
  541. glBegin(GL_LINES);
  542. glVertex2i( x0, y0 );
  543. glVertex2i( x1, y1 );
  544. glEnd();
  545. // JDC W_UnlockLumpName("PLAYPAL");
  546. }
  547. void gld_DrawWeapon(int weaponlump, vissprite_t *vis, int lightlevel)
  548. {
  549. GLTexture *gltexture;
  550. float fU1,fU2,fV1,fV2;
  551. int x1,y1,x2,y2;
  552. float scale;
  553. float light;
  554. gltexture=gld_RegisterPatch(firstspritelump+weaponlump, CR_DEFAULT);
  555. if (!gltexture)
  556. return;
  557. gld_BindPatch(gltexture, CR_DEFAULT);
  558. fU1=0;
  559. fV1=0;
  560. fU2=(float)gltexture->width/(float)gltexture->tex_width;
  561. fV2=(float)gltexture->height/(float)gltexture->tex_height;
  562. x1=viewwindowx+vis->x1;
  563. x2=viewwindowx+vis->x2;
  564. scale=((float)vis->scale/(float)FRACUNIT);
  565. y1=viewwindowy+centery-(int)(((float)vis->texturemid/(float)FRACUNIT)*scale);
  566. y2=y1+(int)((float)gltexture->realtexheight*scale)+1;
  567. #ifdef IPHONE
  568. // don't do the gamma table correction on the lighting
  569. light=lightlevel * (1.0/255);
  570. // some of the sprites come one line off the bottom of the screen
  571. y1++;
  572. y2++;
  573. #else
  574. light=gld_CalcLightLevel(lightlevel);
  575. #endif
  576. if (viewplayer->mo->flags & MF_SHADOW)
  577. {
  578. glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
  579. glAlphaFunc(GL_GEQUAL,0.1f);
  580. //glColor4f(0.2f,0.2f,0.2f,(float)tran_filter_pct/100.0f);
  581. glColor4f(0.2f,0.2f,0.2f,0.33f);
  582. }
  583. else
  584. {
  585. if (viewplayer->mo->flags & MF_TRANSLUCENT)
  586. gld_StaticLightAlpha(light,(float)tran_filter_pct/100.0f);
  587. else
  588. gld_StaticLight(light);
  589. }
  590. glBegin(GL_TRIANGLE_STRIP);
  591. glTexCoord2f(fU1, fV1); glVertex2f((float)(x1),(float)(y1));
  592. glTexCoord2f(fU1, fV2); glVertex2f((float)(x1),(float)(y2));
  593. glTexCoord2f(fU2, fV1); glVertex2f((float)(x2),(float)(y1));
  594. glTexCoord2f(fU2, fV2); glVertex2f((float)(x2),(float)(y2));
  595. glEnd();
  596. if(viewplayer->mo->flags & MF_SHADOW)
  597. {
  598. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  599. glAlphaFunc(GL_GEQUAL,0.5f);
  600. }
  601. glColor3f(1.0f,1.0f,1.0f);
  602. }
  603. void gld_FillBlock(int x, int y, int width, int height, int col)
  604. {
  605. // JDC const unsigned char *playpal=W_CacheLumpName("PLAYPAL");
  606. glBindTexture(GL_TEXTURE_2D, 0);
  607. last_gltexture = NULL;
  608. last_cm = -1;
  609. glColor3f((float)staticPlaypal[3*col]/255.0f, // JDC: changed to not lookup PLAYPAL every time
  610. (float)staticPlaypal[3*col+1]/255.0f,
  611. (float)staticPlaypal[3*col+2]/255.0f);
  612. glBegin(GL_TRIANGLE_STRIP);
  613. glVertex2i( x, y );
  614. glVertex2i( x, y+height );
  615. glVertex2i( x+width, y );
  616. glVertex2i( x+width, y+height );
  617. glEnd();
  618. glColor3f(1.0f,1.0f,1.0f);
  619. // JDC W_UnlockLumpName("PLAYPAL");
  620. }
  621. void gld_SetPalette(int palette)
  622. {
  623. static int last_palette = 0;
  624. extra_red=0.0f;
  625. extra_green=0.0f;
  626. extra_blue=0.0f;
  627. extra_alpha=0.0f;
  628. if (palette < 0)
  629. palette = last_palette;
  630. last_palette = palette;
  631. if (gl_shared_texture_palette) {
  632. const unsigned char *playpal;
  633. unsigned char pal[1024];
  634. int i;
  635. playpal = W_CacheLumpName("PLAYPAL");
  636. playpal += (768*palette);
  637. for (i=0; i<256; i++) {
  638. int col;
  639. if (fixedcolormap)
  640. col = fixedcolormap[i];
  641. else if (fullcolormap)
  642. col = fullcolormap[i];
  643. else
  644. col = i;
  645. pal[i*4+0] = playpal[col*3+0];
  646. pal[i*4+1] = playpal[col*3+1];
  647. pal[i*4+2] = playpal[col*3+2];
  648. pal[i*4+3] = 255;
  649. }
  650. pal[transparent_pal_index*4+0]=0;
  651. pal[transparent_pal_index*4+1]=0;
  652. pal[transparent_pal_index*4+2]=0;
  653. pal[transparent_pal_index*4+3]=0;
  654. gld_ColorTableEXT(GL_SHARED_TEXTURE_PALETTE_EXT, GL_RGBA, 256, GL_RGBA, GL_UNSIGNED_BYTE, pal);
  655. W_UnlockLumpName("PLAYPAL");
  656. } else {
  657. if (palette>0)
  658. {
  659. if (palette<=8)
  660. {
  661. extra_red=(float)palette/2.0f;
  662. extra_green=0.0f;
  663. extra_blue=0.0f;
  664. extra_alpha=(float)palette/10.0f;
  665. }
  666. else
  667. if (palette<=12)
  668. {
  669. palette=palette-8;
  670. extra_red=(float)palette*1.0f;
  671. extra_green=(float)palette*0.8f;
  672. extra_blue=(float)palette*0.1f;
  673. extra_alpha=(float)palette/11.0f;
  674. }
  675. else
  676. if (palette==13)
  677. {
  678. extra_red=0.4f;
  679. extra_green=1.0f;
  680. extra_blue=0.0f;
  681. extra_alpha=0.2f;
  682. }
  683. }
  684. if (extra_red>1.0f)
  685. extra_red=1.0f;
  686. if (extra_green>1.0f)
  687. extra_green=1.0f;
  688. if (extra_blue>1.0f)
  689. extra_blue=1.0f;
  690. if (extra_alpha>1.0f)
  691. extra_alpha=1.0f;
  692. }
  693. }
  694. unsigned char *gld_ReadScreen(void)
  695. {
  696. unsigned char *scr;
  697. unsigned char buffer[MAX_SCREENWIDTH*3];
  698. int i;
  699. scr = malloc(SCREENWIDTH * SCREENHEIGHT * 3);
  700. if (scr) {
  701. glReadPixels(0,0,SCREENWIDTH,SCREENHEIGHT,GL_RGB,GL_UNSIGNED_BYTE,scr);
  702. for (i=0; i<SCREENHEIGHT/2; i++) {
  703. memcpy(buffer, &scr[i*SCREENWIDTH*3], SCREENWIDTH*3);
  704. memcpy(&scr[i*SCREENWIDTH*3],
  705. &scr[(SCREENHEIGHT-(i+1))*SCREENWIDTH*3], SCREENWIDTH*3);
  706. memcpy(&scr[(SCREENHEIGHT-(i+1))*SCREENWIDTH*3], buffer, SCREENWIDTH*3);
  707. }
  708. }
  709. return scr;
  710. }
  711. GLvoid gld_Set2DMode(void)
  712. {
  713. glMatrixMode(GL_MODELVIEW);
  714. glLoadIdentity();
  715. glMatrixMode(GL_PROJECTION);
  716. glLoadIdentity();
  717. iphoneRotateForLandscape(); //JDC
  718. glOrtho(
  719. (GLdouble) 0,
  720. (GLdouble) SCREENWIDTH,
  721. (GLdouble) SCREENHEIGHT,
  722. (GLdouble) 0,
  723. (GLdouble) -1.0,
  724. (GLdouble) 1.0
  725. );
  726. glDisable(GL_DEPTH_TEST);
  727. }
  728. void gld_InitDrawScene(void)
  729. {
  730. }
  731. void gld_Finish(void)
  732. {
  733. gld_Set2DMode();
  734. glFinish();
  735. SDL_GL_SwapBuffers();
  736. }
  737. /*****************
  738. * *
  739. * structs *
  740. * *
  741. *****************/
  742. #if 0 // JDC: moved to header
  743. typedef struct
  744. {
  745. GLfloat x;
  746. GLfloat y;
  747. GLfloat z;
  748. } GLVertex;
  749. typedef struct
  750. {
  751. GLfloat u;
  752. GLfloat v;
  753. } GLTexcoord;
  754. #endif
  755. int gld_max_vertexes=0;
  756. int gld_num_vertexes=0;
  757. GLVertex *gld_vertexes=NULL;
  758. GLTexcoord *gld_texcoords=NULL;
  759. static void gld_AddGlobalVertexes(int count)
  760. {
  761. if ((gld_num_vertexes+count)>=gld_max_vertexes)
  762. {
  763. gld_max_vertexes+=count+1024;
  764. gld_vertexes=Z_Realloc(gld_vertexes,gld_max_vertexes*sizeof(GLVertex),PU_LEVEL,0);
  765. gld_texcoords=Z_Realloc(gld_texcoords,gld_max_vertexes*sizeof(GLTexcoord),PU_LEVEL,0);
  766. }
  767. }
  768. GLSeg *gl_segs=NULL;
  769. #if 0
  770. #define GLDWF_TOP 1
  771. #define GLDWF_M1S 2
  772. #define GLDWF_M2S 3
  773. #define GLDWF_BOT 4
  774. #define GLDWF_SKY 5
  775. #define GLDWF_SKYFLIP 6
  776. typedef struct
  777. {
  778. GLSeg *glseg;
  779. float ytop,ybottom;
  780. float ul,ur,vt,vb;
  781. float light;
  782. float alpha;
  783. float skyymid;
  784. float skyyaw;
  785. GLTexture *gltexture;
  786. byte flag;
  787. } GLWall;
  788. typedef struct
  789. {
  790. int sectornum;
  791. float light; // the lightlevel of the flat
  792. float uoffs,voffs; // the texture coordinates
  793. float z; // the z position of the flat (height)
  794. GLTexture *gltexture;
  795. boolean ceiling;
  796. } GLFlat;
  797. typedef struct
  798. {
  799. int cm;
  800. float x,y,z;
  801. float vt,vb;
  802. float ul,ur;
  803. float x1,y1;
  804. float x2,y2;
  805. float light;
  806. fixed_t scale;
  807. GLTexture *gltexture;
  808. boolean shadow;
  809. boolean trans;
  810. } GLSprite;
  811. typedef enum
  812. {
  813. GLDIT_NONE,
  814. GLDIT_WALL,
  815. GLDIT_FLAT,
  816. GLDIT_SPRITE
  817. } GLDrawItemType;
  818. typedef struct
  819. {
  820. GLDrawItemType itemtype;
  821. int itemcount;
  822. int firstitemindex;
  823. byte rendermarker;
  824. } GLDrawItem;
  825. typedef struct
  826. {
  827. GLWall *walls;
  828. int num_walls;
  829. int max_walls;
  830. GLFlat *flats;
  831. int num_flats;
  832. int max_flats;
  833. GLSprite *sprites;
  834. int num_sprites;
  835. int max_sprites;
  836. GLDrawItem *drawitems;
  837. int num_drawitems;
  838. int max_drawitems;
  839. } GLDrawInfo;
  840. #endif
  841. GLDrawInfo gld_drawinfo;
  842. // this is the list for all sectors to the loops
  843. /* JDC static */ GLSector *sectorloops;
  844. byte rendermarker=0;
  845. static byte *sectorrendered; // true if sector rendered (only here for malloc)
  846. /* JDC static */ byte *segrendered; // true if sector rendered (only here for malloc)
  847. static FILE *levelinfo;
  848. /*****************************
  849. *
  850. * FLATS
  851. *
  852. *****************************/
  853. /* proff - 05/15/2000
  854. * The idea and algorithm to compute the flats with nodes and subsectors is
  855. * originaly from JHexen. I have redone it.
  856. */
  857. #define FIX2DBL(x) ((double)(x))
  858. #define MAX_CC_SIDES 64
  859. static boolean gld_PointOnSide(vertex_t *p, divline_t *d)
  860. {
  861. // We'll return false if the point c is on the left side.
  862. return ((FIX2DBL(d->y)-FIX2DBL(p->y))*FIX2DBL(d->dx)-(FIX2DBL(d->x)-FIX2DBL(p->x))*FIX2DBL(d->dy) >= 0);
  863. }
  864. // Lines start-end and fdiv must intersect.
  865. static void gld_CalcIntersectionVertex(vertex_t *s, vertex_t *e, divline_t *d, vertex_t *i)
  866. {
  867. double ax = FIX2DBL(s->x), ay = FIX2DBL(s->y), bx = FIX2DBL(e->x), by = FIX2DBL(e->y);
  868. double cx = FIX2DBL(d->x), cy = FIX2DBL(d->y), dx = cx+FIX2DBL(d->dx), dy = cy+FIX2DBL(d->dy);
  869. double r = ((ay-cy)*(dx-cx)-(ax-cx)*(dy-cy)) / ((bx-ax)*(dy-cy)-(by-ay)*(dx-cx));
  870. i->x = (fixed_t)((double)s->x + r*((double)e->x-(double)s->x));
  871. i->y = (fixed_t)((double)s->y + r*((double)e->y-(double)s->y));
  872. }
  873. #undef FIX2DBL
  874. // Returns a pointer to the list of points. It must be used.
  875. //
  876. static vertex_t *gld_FlatEdgeClipper(int *numpoints, vertex_t *points, int numclippers, divline_t *clippers)
  877. {
  878. unsigned char sidelist[MAX_CC_SIDES];
  879. int i, k, num = *numpoints;
  880. // We'll clip the polygon with each of the divlines. The left side of
  881. // each divline is discarded.
  882. for(i=0; i<numclippers; i++)
  883. {
  884. divline_t *curclip = &clippers[i];
  885. // First we'll determine the side of each vertex. Points are allowed
  886. // to be on the line.
  887. for(k=0; k<num; k++)
  888. sidelist[k] = gld_PointOnSide(&points[k], curclip);
  889. for(k=0; k<num; k++)
  890. {
  891. int startIdx = k, endIdx = k+1;
  892. // Check the end index.
  893. if(endIdx == num) endIdx = 0; // Wrap-around.
  894. // Clipping will happen when the ends are on different sides.
  895. if(sidelist[startIdx] != sidelist[endIdx])
  896. {
  897. vertex_t newvert;
  898. gld_CalcIntersectionVertex(&points[startIdx], &points[endIdx], curclip, &newvert);
  899. // Add the new vertex. Also modify the sidelist.
  900. points = (vertex_t*)Z_Realloc(points,(++num)*sizeof(vertex_t),PU_LEVEL,0);
  901. if(num >= MAX_CC_SIDES)
  902. I_Error("gld_FlatEdgeClipper: Too many points in carver");
  903. // Make room for the new vertex.
  904. memmove(&points[endIdx+1], &points[endIdx],
  905. (num - endIdx-1)*sizeof(vertex_t));
  906. memcpy(&points[endIdx], &newvert, sizeof(newvert));
  907. memmove(&sidelist[endIdx+1], &sidelist[endIdx], num-endIdx-1);
  908. sidelist[endIdx] = 1;
  909. // Skip over the new vertex.
  910. k++;
  911. }
  912. }
  913. // Now we must discard the points that are on the wrong side.
  914. for(k=0; k<num; k++)
  915. if(!sidelist[k])
  916. {
  917. memmove(&points[k], &points[k+1], (num - k-1)*sizeof(vertex_t));
  918. memmove(&sidelist[k], &sidelist[k+1], num - k-1);
  919. num--;
  920. k--;
  921. }
  922. }
  923. // Screen out consecutive identical points.
  924. for(i=0; i<num; i++)
  925. {
  926. int previdx = i-1;
  927. if(previdx < 0) previdx = num - 1;
  928. if(points[i].x == points[previdx].x
  929. && points[i].y == points[previdx].y)
  930. {
  931. // This point (i) must be removed.
  932. memmove(&points[i], &points[i+1], sizeof(vertex_t)*(num-i-1));
  933. num--;
  934. i--;
  935. }
  936. }
  937. *numpoints = num;
  938. return points;
  939. }
  940. static void gld_FlatConvexCarver(int ssidx, int num, divline_t *list)
  941. {
  942. subsector_t *ssec=&subsectors[ssidx];
  943. int numclippers = num+ssec->numlines;
  944. divline_t *clippers;
  945. int i, numedgepoints;
  946. vertex_t *edgepoints;
  947. clippers=(divline_t*)Z_Malloc(numclippers*sizeof(divline_t),PU_LEVEL,0);
  948. if (!clippers)
  949. return;
  950. for(i=0; i<num; i++)
  951. {
  952. clippers[i].x = list[num-i-1].x;
  953. clippers[i].y = list[num-i-1].y;
  954. clippers[i].dx = list[num-i-1].dx;
  955. clippers[i].dy = list[num-i-1].dy;
  956. }
  957. for(i=num; i<numclippers; i++)
  958. {
  959. seg_t *seg = &segs[ssec->firstline+i-num];
  960. clippers[i].x = seg->v1->x;
  961. clippers[i].y = seg->v1->y;
  962. clippers[i].dx = seg->v2->x-seg->v1->x;
  963. clippers[i].dy = seg->v2->y-seg->v1->y;
  964. }
  965. // Setup the 'worldwide' polygon.
  966. numedgepoints = 4;
  967. edgepoints = (vertex_t*)Z_Malloc(numedgepoints*sizeof(vertex_t),PU_LEVEL,0);
  968. edgepoints[0].x = INT_MIN;
  969. edgepoints[0].y = INT_MAX;
  970. edgepoints[1].x = INT_MAX;
  971. edgepoints[1].y = INT_MAX;
  972. edgepoints[2].x = INT_MAX;
  973. edgepoints[2].y = INT_MIN;
  974. edgepoints[3].x = INT_MIN;
  975. edgepoints[3].y = INT_MIN;
  976. // Do some clipping, <snip> <snip>
  977. edgepoints = gld_FlatEdgeClipper(&numedgepoints, edgepoints, numclippers, clippers);
  978. if(!numedgepoints)
  979. {
  980. if (levelinfo) fprintf(levelinfo, "All carved away: subsector %i - sector %i\n", ssec-subsectors, ssec->sector->iSectorID);
  981. }
  982. else
  983. {
  984. if(numedgepoints >= 3)
  985. {
  986. gld_AddGlobalVertexes(numedgepoints);
  987. if ((gld_vertexes) && (gld_texcoords))
  988. {
  989. int currentsector=ssec->sector->iSectorID;
  990. sectorloops[ currentsector ].loopcount++;
  991. sectorloops[ currentsector ].loops=Z_Realloc(sectorloops[currentsector].loops,sizeof(GLLoopDef)*sectorloops[currentsector].loopcount, PU_LEVEL, 0);
  992. sectorloops[ currentsector ].loops[ sectorloops[currentsector].loopcount-1 ].mode=GL_TRIANGLE_FAN;
  993. sectorloops[ currentsector ].loops[ sectorloops[currentsector].loopcount-1 ].vertexcount=numedgepoints;
  994. sectorloops[ currentsector ].loops[ sectorloops[currentsector].loopcount-1 ].vertexindex=gld_num_vertexes;
  995. for(i = 0; i < numedgepoints; i++)
  996. {
  997. gld_texcoords[gld_num_vertexes].u = ( (float)edgepoints[i].x/(float)FRACUNIT)/64.0f;
  998. gld_texcoords[gld_num_vertexes].v = (-(float)edgepoints[i].y/(float)FRACUNIT)/64.0f;
  999. gld_vertexes[gld_num_vertexes].x = -(float)edgepoints[i].x/MAP_SCALE;
  1000. gld_vertexes[gld_num_vertexes].y = 0.0f;
  1001. gld_vertexes[gld_num_vertexes].z = (float)edgepoints[i].y/MAP_SCALE;
  1002. gld_num_vertexes++;
  1003. }
  1004. }
  1005. }
  1006. }
  1007. // We're done, free the edgepoints memory.
  1008. Z_Free(edgepoints);
  1009. Z_Free(clippers);
  1010. }
  1011. static void gld_CarveFlats(int bspnode, int numdivlines, divline_t *divlines, boolean *sectorclosed)
  1012. {
  1013. node_t *nod;
  1014. divline_t *childlist, *dl;
  1015. int childlistsize = numdivlines+1;
  1016. // If this is a subsector we are dealing with, begin carving with the
  1017. // given list.
  1018. if(bspnode & NF_SUBSECTOR)
  1019. {
  1020. // We have arrived at a subsector. The divline list contains all
  1021. // the partition lines that carve out the subsector.
  1022. // special case for trivial maps (no nodes, single subsector)
  1023. int ssidx = (numnodes != 0) ? bspnode & (~NF_SUBSECTOR) : 0;
  1024. if (!sectorclosed[subsectors[ssidx].sector->iSectorID])
  1025. gld_FlatConvexCarver(ssidx, numdivlines, divlines);
  1026. return;
  1027. }
  1028. // Get a pointer to the node.
  1029. nod = nodes + bspnode;
  1030. // Allocate a new list for each child.
  1031. childlist = (divline_t*)Z_Malloc(childlistsize*sizeof(divline_t),PU_LEVEL,0);
  1032. // Copy the previous lines.
  1033. if(divlines) memcpy(childlist,divlines,numdivlines*sizeof(divline_t));
  1034. dl = childlist + numdivlines;
  1035. dl->x = nod->x;
  1036. dl->y = nod->y;
  1037. // The right child gets the original line (LEFT side clipped).
  1038. dl->dx = nod->dx;
  1039. dl->dy = nod->dy;
  1040. gld_CarveFlats(nod->children[0],childlistsize,childlist,sectorclosed);
  1041. // The left side. We must reverse the line, otherwise the wrong
  1042. // side would get clipped.
  1043. dl->dx = -nod->dx;
  1044. dl->dy = -nod->dy;
  1045. gld_CarveFlats(nod->children[1],childlistsize,childlist,sectorclosed);
  1046. // We are finishing with this node, free the allocated list.
  1047. Z_Free(childlist);
  1048. }
  1049. #ifdef USE_GLU_TESS
  1050. static int currentsector; // the sector which is currently tesselated
  1051. // ntessBegin
  1052. //
  1053. // called when the tesselation of a new loop starts
  1054. static void CALLBACK ntessBegin( GLenum type )
  1055. {
  1056. #ifdef _DEBUG
  1057. if (levelinfo)
  1058. {
  1059. if (type==GL_TRIANGLES)
  1060. fprintf(levelinfo, "\t\tBegin: GL_TRIANGLES\n");
  1061. else
  1062. if (type==GL_TRIANGLE_FAN)
  1063. fprintf(levelinfo, "\t\tBegin: GL_TRIANGLE_FAN\n");
  1064. else
  1065. if (type==GL_TRIANGLE_STRIP)
  1066. fprintf(levelinfo, "\t\tBegin: GL_TRIANGLE_STRIP\n");
  1067. else
  1068. fprintf(levelinfo, "\t\tBegin: unknown\n");
  1069. }
  1070. #endif
  1071. // increase loopcount for currentsector
  1072. sectorloops[ currentsector ].loopcount++;
  1073. // reallocate to get space for another loop
  1074. // PU_LEVEL is used, so this gets freed before a new level is loaded
  1075. sectorloops[ currentsector ].loops=Z_Realloc(sectorloops[currentsector].loops,sizeof(GLLoopDef)*sectorloops[currentsector].loopcount, PU_LEVEL, 0);
  1076. // set initial values for current loop
  1077. // currentloop is -> sectorloops[currentsector].loopcount-1
  1078. sectorloops[ currentsector ].loops[ sectorloops[currentsector].loopcount-1 ].mode=type;
  1079. sectorloops[ currentsector ].loops[ sectorloops[currentsector].loopcount-1 ].vertexcount=0;
  1080. sectorloops[ currentsector ].loops[ sectorloops[currentsector].loopcount-1 ].vertexindex=gld_num_vertexes;
  1081. }
  1082. // ntessError
  1083. //
  1084. // called when the tesselation failes (DEBUG only)
  1085. static void CALLBACK ntessError(GLenum error)
  1086. {
  1087. #ifdef _DEBUG
  1088. const GLubyte *estring;
  1089. estring = gluErrorString(error);
  1090. fprintf(levelinfo, "\t\tTessellation Error: %s\n", estring);
  1091. #endif
  1092. }
  1093. // ntessCombine
  1094. //
  1095. // called when the two or more vertexes are on the same coordinate
  1096. static void CALLBACK ntessCombine( GLdouble coords[3], vertex_t *vert[4], GLfloat w[4], void **dataOut )
  1097. {
  1098. #ifdef _DEBUG
  1099. if (levelinfo)
  1100. {
  1101. fprintf(levelinfo, "\t\tVertexCombine Coords: x %10.5f, y %10.5f z %10.5f\n", coords[0], coords[1], coords[2]);
  1102. if (vert[0]) fprintf(levelinfo, "\t\tVertexCombine Vert1 : x %10i, y %10i p %p\n", vert[0]->x>>FRACBITS, vert[0]->y>>FRACBITS, vert[0]);
  1103. if (vert[1]) fprintf(levelinfo, "\t\tVertexCombine Vert2 : x %10i, y %10i p %p\n", vert[1]->x>>FRACBITS, vert[1]->y>>FRACBITS, vert[1]);
  1104. if (vert[2]) fprintf(levelinfo, "\t\tVertexCombine Vert3 : x %10i, y %10i p %p\n", vert[2]->x>>FRACBITS, vert[2]->y>>FRACBITS, vert[2]);
  1105. if (vert[3]) fprintf(levelinfo, "\t\tVertexCombine Vert4 : x %10i, y %10i p %p\n", vert[3]->x>>FRACBITS, vert[3]->y>>FRACBITS, vert[3]);
  1106. }
  1107. #endif
  1108. // just return the first vertex, because all vertexes are on the same coordinate
  1109. *dataOut = vert[0];
  1110. }
  1111. // ntessVertex
  1112. //
  1113. // called when a vertex is found
  1114. static void CALLBACK ntessVertex( vertex_t *vert )
  1115. {
  1116. #ifdef _DEBUG
  1117. if (levelinfo)
  1118. fprintf(levelinfo, "\t\tVertex : x %10i, y %10i\n", vert->x>>FRACBITS, vert->y>>FRACBITS);
  1119. #endif
  1120. // increase vertex count
  1121. sectorloops[ currentsector ].loops[ sectorloops[currentsector].loopcount-1 ].vertexcount++;
  1122. // increase vertex count
  1123. gld_AddGlobalVertexes(1);
  1124. // add the new vertex (vert is the second argument of gluTessVertex)
  1125. gld_texcoords[gld_num_vertexes].u=( (float)vert->x/(float)FRACUNIT)/64.0f;
  1126. gld_texcoords[gld_num_vertexes].v=(-(float)vert->y/(float)FRACUNIT)/64.0f;
  1127. gld_vertexes[gld_num_vertexes].x=-(float)vert->x/MAP_SCALE;
  1128. gld_vertexes[gld_num_vertexes].y=0.0f;
  1129. gld_vertexes[gld_num_vertexes].z= (float)vert->y/MAP_SCALE;
  1130. gld_num_vertexes++;
  1131. }
  1132. // ntessEnd
  1133. //
  1134. // called when the tesselation of a the current loop ends (DEBUG only)
  1135. static void CALLBACK ntessEnd( void )
  1136. {
  1137. #ifdef _DEBUG
  1138. if (levelinfo)
  1139. fprintf(levelinfo, "\t\tEnd loopcount %i vertexcount %i\n", sectorloops[currentsector].loopcount, sectorloops[ currentsector ].loops[ sectorloops[currentsector].loopcount-1 ].vertexcount);
  1140. #endif
  1141. }
  1142. // gld_PrecalculateSector
  1143. //
  1144. // this calculates the loops for the sector "num"
  1145. //
  1146. // how does it work?
  1147. // first I have to credit Michael 'Kodak' Ryssen for the usage of the
  1148. // glu tesselation functions. the rest of this stuff is entirely done by me (proff).
  1149. // if there are any similarities, then they are implications of the algorithm.
  1150. //
  1151. // I'm starting with the first line of the current sector. I take it's ending vertex and
  1152. // add it to the tesselator. the current line is marked as used. then I'm searching for
  1153. // the next line which connects to the current line. if there is more than one line, I
  1154. // choose the one with the smallest angle to the current. if there is no next line, I
  1155. // start a new loop and take the first unused line in the sector. after all lines are
  1156. // processed, the polygon is tesselated.
  1157. static void gld_PrecalculateSector(int num)
  1158. {
  1159. int i;
  1160. boolean *lineadded=NULL;
  1161. int linecount;
  1162. int currentline;
  1163. int oldline;
  1164. int currentloop;
  1165. int bestline;
  1166. int bestlinecount;
  1167. vertex_t *startvertex;
  1168. vertex_t *currentvertex;
  1169. angle_t lineangle;
  1170. angle_t angle;
  1171. angle_t bestangle;
  1172. sector_t *backsector;
  1173. GLUtesselator *tess;
  1174. double *v=NULL;
  1175. int maxvertexnum;
  1176. int vertexnum;
  1177. currentsector=num;
  1178. lineadded=Z_Malloc(sectors[num].linecount*sizeof(boolean),PU_LEVEL,0);
  1179. if (!lineadded)
  1180. {
  1181. if (levelinfo) fclose(levelinfo);
  1182. return;
  1183. }
  1184. // init tesselator
  1185. tess=gluNewTess();
  1186. if (!tess)
  1187. {
  1188. if (levelinfo) fclose(levelinfo);
  1189. Z_Free(lineadded);
  1190. return;
  1191. }
  1192. // set callbacks
  1193. gluTessCallback(tess, GLU_TESS_BEGIN, ntessBegin);
  1194. gluTessCallback(tess, GLU_TESS_VERTEX, ntessVertex);
  1195. gluTessCallback(tess, GLU_TESS_ERROR, ntessError);
  1196. gluTessCallback(tess, GLU_TESS_COMBINE, ntessCombine);
  1197. gluTessCallback(tess, GLU_TESS_END, ntessEnd);
  1198. if (levelinfo) fprintf(levelinfo, "sector %i, %i lines in sector\n", num, sectors[num].linecount);
  1199. // remove any line which has both sides in the same sector (i.e. Doom2 Map01 Sector 1)
  1200. for (i=0; i<sectors[num].linecount; i++)
  1201. {
  1202. lineadded[i]=false;
  1203. if (sectors[num].lines[i]->sidenum[0]!=NO_INDEX)
  1204. if (sectors[num].lines[i]->sidenum[1]!=NO_INDEX)
  1205. if (sides[sectors[num].lines[i]->sidenum[0]].sector
  1206. ==sides[sectors[num].lines[i]->sidenum[1]].sector)
  1207. {
  1208. lineadded[i]=true;
  1209. if (levelinfo) fprintf(levelinfo, "line %4i (iLineID %4i) has both sides in same sector (removed)\n", i, sectors[num].lines[i]->iLineID);
  1210. }
  1211. }
  1212. // initialize variables
  1213. linecount=sectors[num].linecount;
  1214. oldline=0;
  1215. currentline=0;
  1216. startvertex=sectors[num].lines[currentline]->v2;
  1217. currentloop=0;
  1218. vertexnum=0;
  1219. maxvertexnum=0;
  1220. // start tesselator
  1221. if (levelinfo) fprintf(levelinfo, "gluTessBeginPolygon\n");
  1222. gluTessBeginPolygon(tess, NULL);
  1223. if (levelinfo) fprintf(levelinfo, "\tgluTessBeginContour\n");
  1224. gluTessBeginContour(tess);
  1225. while (linecount)
  1226. {
  1227. // if there is no connected line, then start new loop
  1228. if ((oldline==currentline) || (startvertex==currentvertex))
  1229. {
  1230. currentline=-1;
  1231. for (i=0; i<sectors[num].linecount; i++)
  1232. if (!lineadded[i])
  1233. {
  1234. currentline=i;
  1235. currentloop++;
  1236. if ((sectors[num].lines[currentline]->sidenum[0]!=NO_INDEX) ? (sides[sectors[num].lines[currentline]->sidenum[0]].sector==&sectors[num]) : false)
  1237. startvertex=sectors[num].lines[currentline]->v1;
  1238. else
  1239. startvertex=sectors[num].lines[currentline]->v2;
  1240. if (levelinfo) fprintf(levelinfo, "\tNew Loop %3i\n", currentloop);
  1241. if (oldline!=0)
  1242. {
  1243. if (levelinfo) fprintf(levelinfo, "\tgluTessEndContour\n");
  1244. gluTessEndContour(tess);
  1245. // if (levelinfo) fprintf(levelinfo, "\tgluNextContour\n");
  1246. // gluNextContour(tess, GLU_CW);
  1247. if (levelinfo) fprintf(levelinfo, "\tgluTessBeginContour\n");
  1248. gluTessBeginContour(tess);
  1249. }
  1250. break;
  1251. }
  1252. }
  1253. if (currentline==-1)
  1254. break;
  1255. // add current line
  1256. lineadded[currentline]=true;
  1257. // check if currentsector is on the front side of the line ...
  1258. if ((sectors[num].lines[currentline]->sidenum[0]!=NO_INDEX) ? (sides[sectors[num].lines[currentline]->sidenum[0]].sector==&sectors[num]) : false)
  1259. {
  1260. // v2 is ending vertex
  1261. currentvertex=sectors[num].lines[currentline]->v2;
  1262. // calculate the angle of this line for use below
  1263. lineangle = R_PointToAngle2(sectors[num].lines[currentline]->v1->x,sectors[num].lines[currentline]->v1->y,sectors[num].lines[currentline]->v2->x,sectors[num].lines[currentline]->v2->y);
  1264. lineangle=(lineangle>>ANGLETOFINESHIFT)*360/8192;
  1265. if (lineangle>=180)
  1266. lineangle=lineangle-360;
  1267. if (levelinfo) fprintf(levelinfo, "\t\tAdded Line %4i to Loop, iLineID %5i, Angle: %4i, flipped false\n", currentline, sectors[num].lines[currentline]->iLineID, lineangle);
  1268. }
  1269. else // ... or on the back side
  1270. {
  1271. // v1 is ending vertex
  1272. currentvertex=sectors[num].lines[currentline]->v1;
  1273. // calculate the angle of this line for use below
  1274. lineangle = R_PointToAngle2(sectors[num].lines[currentline]->v2->x,sectors[num].lines[currentline]->v2->y,sectors[num].lines[currentline]->v1->x,sectors[num].lines[currentline]->v1->y);
  1275. lineangle=(lineangle>>ANGLETOFINESHIFT)*360/8192;
  1276. if (lineangle>=180)
  1277. lineangle=lineangle-360;
  1278. if (levelinfo) fprintf(levelinfo, "\t\tAdded Line %4i to Loop, iLineID %5i, Angle: %4i, flipped true\n", currentline, sectors[num].lines[currentline]->iLineID, lineangle);
  1279. }
  1280. if (vertexnum>=maxvertexnum)
  1281. {
  1282. maxvertexnum+=512;
  1283. v=Z_Realloc(v,maxvertexnum*3*sizeof(double),PU_LEVEL,0);
  1284. }
  1285. // calculate coordinates for the glu tesselation functions
  1286. v[vertexnum*3+0]=-(double)currentvertex->x/(double)MAP_SCALE;
  1287. v[vertexnum*3+1]=0.0;
  1288. v[vertexnum*3+2]= (double)currentvertex->y/(double)MAP_SCALE;
  1289. // add the vertex to the tesselator, currentvertex is the pointer to the vertexlist of doom
  1290. // v[vertexnum] is the GLdouble array of the current vertex
  1291. if (levelinfo) fprintf(levelinfo, "\t\tgluTessVertex(%i, %i)\n",currentvertex->x>>FRACBITS,currentvertex->y>>FRACBITS);
  1292. gluTessVertex(tess, &v[vertexnum*3], currentvertex);
  1293. // increase vertexindex
  1294. vertexnum++;
  1295. // decrease linecount of current sector
  1296. linecount--;
  1297. // find the next line
  1298. oldline=currentline; // if this isn't changed at the end of the search, a new loop will start
  1299. bestline=-1; // set to start values
  1300. bestlinecount=0;
  1301. // set backsector if there is one
  1302. if (sectors[num].lines[currentline]->sidenum[1]!=NO_INDEX)
  1303. backsector=sides[sectors[num].lines[currentline]->sidenum[1]].sector;
  1304. else
  1305. backsector=NULL;
  1306. // search through all lines of the current sector
  1307. for (i=0; i<sectors[num].linecount; i++)
  1308. if (!lineadded[i]) // if the line isn't already added ...
  1309. // check if one of the vertexes is the same as the current vertex
  1310. if ((sectors[num].lines[i]->v1==currentvertex) || (sectors[num].lines[i]->v2==currentvertex))
  1311. {
  1312. // calculate the angle of this best line candidate
  1313. if ((sectors[num].lines[i]->sidenum[0]!=NO_INDEX) ? (sides[sectors[num].lines[i]->sidenum[0]].sector==&sectors[num]) : false)
  1314. angle = R_PointToAngle2(sectors[num].lines[i]->v1->x,sectors[num].lines[i]->v1->y,sectors[num].lines[i]->v2->x,sectors[num].lines[i]->v2->y);
  1315. else
  1316. angle = R_PointToAngle2(sectors[num].lines[i]->v2->x,sectors[num].lines[i]->v2->y,sectors[num].lines[i]->v1->x,sectors[num].lines[i]->v1->y);
  1317. angle=(angle>>ANGLETOFINESHIFT)*360/8192;
  1318. if (angle>=180)
  1319. angle=angle-360;
  1320. // check if line is flipped ...
  1321. if ((sectors[num].lines[i]->sidenum[0]!=NO_INDEX) ? (sides[sectors[num].lines[i]->sidenum[0]].sector==&sectors[num]) : false)
  1322. {
  1323. // when the line is not flipped and startvertex is not the currentvertex then skip this line
  1324. if (sectors[num].lines[i]->v1!=currentvertex)
  1325. continue;
  1326. }
  1327. else
  1328. {
  1329. // when the line is flipped and endvertex is not the currentvertex then skip this line
  1330. if (sectors[num].lines[i]->v2!=currentvertex)
  1331. continue;
  1332. }
  1333. // set new best line candidate
  1334. if (bestline==-1) // if this is the first one ...
  1335. {
  1336. bestline=i;
  1337. bestangle=lineangle-angle;
  1338. bestlinecount++;
  1339. }
  1340. else
  1341. // check if the angle between the current line and this best line candidate is smaller then
  1342. // the angle of the last candidate
  1343. if (D_abs(lineangle-angle)<D_abs(bestangle))
  1344. {
  1345. bestline=i;
  1346. bestangle=lineangle-angle;
  1347. bestlinecount++;
  1348. }
  1349. }
  1350. if (bestline!=-1) // if a line is found, make it the current line
  1351. {
  1352. currentline=bestline;
  1353. if (bestlinecount>1)
  1354. if (levelinfo) fprintf(levelinfo, "\t\tBestlinecount: %4i\n", bestlinecount);
  1355. }
  1356. }
  1357. // let the tesselator calculate the loops
  1358. if (levelinfo) fprintf(levelinfo, "\tgluTessEndContour\n");
  1359. gluTessEndContour(tess);
  1360. if (levelinfo) fprintf(levelinfo, "gluTessEndPolygon\n");
  1361. gluTessEndPolygon(tess);
  1362. // clean memory
  1363. gluDeleteTess(tess);
  1364. Z_Free(v);
  1365. Z_Free(lineadded);
  1366. }
  1367. #endif /* USE_GLU_TESS */
  1368. /********************************************
  1369. * Name : gld_GetSubSectorVertices *
  1370. * created : 08/13/00 *
  1371. * modified : 09/18/00, adapted for PrBoom *
  1372. * author : figgi *
  1373. * what : prepares subsectorvertices *
  1374. * (glnodes only) *
  1375. ********************************************/
  1376. void gld_GetSubSectorVertices(boolean *sectorclosed)
  1377. {
  1378. int i, j;
  1379. int numedgepoints;
  1380. subsector_t* ssector;
  1381. for(i = 0; i < numsubsectors; i++)
  1382. {
  1383. ssector = &subsectors[i];
  1384. if (sectorclosed[ssector->sector->iSectorID])
  1385. continue;
  1386. numedgepoints = ssector->numlines;
  1387. gld_AddGlobalVertexes(numedgepoints);
  1388. if ((gld_vertexes) && (gld_texcoords))
  1389. {
  1390. int currentsector = ssector->sector->iSectorID;
  1391. sectorloops[currentsector].loopcount++;
  1392. sectorloops[currentsector].loops = Z_Realloc(sectorloops[currentsector].loops,sizeof(GLLoopDef)*sectorloops[currentsector].loopcount, PU_LEVEL, 0);
  1393. sectorloops[currentsector].loops[sectorloops[currentsector].loopcount-1].mode = GL_TRIANGLE_FAN;
  1394. sectorloops[currentsector].loops[sectorloops[currentsector].loopcount-1].vertexcount = numedgepoints;
  1395. sectorloops[currentsector].loops[sectorloops[currentsector].loopcount-1].vertexindex = gld_num_vertexes;
  1396. for(j = 0; j < numedgepoints; j++)
  1397. {
  1398. gld_texcoords[gld_num_vertexes].u =( (float)(segs[ssector->firstline + j].v1->x)/FRACUNIT)/64.0f;
  1399. gld_texcoords[gld_num_vertexes].v =(-(float)(segs[ssector->firstline + j].v1->y)/FRACUNIT)/64.0f;
  1400. gld_vertexes[gld_num_vertexes].x = -(float)(segs[ssector->firstline + j].v1->x)/MAP_SCALE;
  1401. gld_vertexes[gld_num_vertexes].y = 0.0f;
  1402. gld_vertexes[gld_num_vertexes].z = (float)(segs[ssector->firstline + j].v1->y)/MAP_SCALE;
  1403. gld_num_vertexes++;
  1404. }
  1405. }
  1406. }
  1407. }
  1408. static void gld_PrepareSectorSpecialEffects(int num)
  1409. {
  1410. int i;
  1411. // the following is for specialeffects. see r_bsp.c in R_Subsector
  1412. sectors[num].no_toptextures=true;
  1413. sectors[num].no_bottomtextures=true;
  1414. for (i=0; i<sectors[num].linecount; i++)
  1415. {
  1416. if ( (sectors[num].lines[i]->sidenum[0]!=NO_INDEX) &&
  1417. (sectors[num].lines[i]->sidenum[1]!=NO_INDEX) )
  1418. {
  1419. if (sides[sectors[num].lines[i]->sidenum[0]].toptexture!=NO_TEXTURE)
  1420. sectors[num].no_toptextures=false;
  1421. if (sides[sectors[num].lines[i]->sidenum[0]].bottomtexture!=NO_TEXTURE)
  1422. sectors[num].no_bottomtextures=false;
  1423. if (sides[sectors[num].lines[i]->sidenum[1]].toptexture!=NO_TEXTURE)
  1424. sectors[num].no_toptextures=false;
  1425. if (sides[sectors[num].lines[i]->sidenum[1]].bottomtexture!=NO_TEXTURE)
  1426. sectors[num].no_bottomtextures=false;
  1427. }
  1428. else
  1429. {
  1430. sectors[num].no_toptextures=false;
  1431. sectors[num].no_bottomtextures=false;
  1432. }
  1433. }
  1434. #ifdef _DEBUG
  1435. if (sectors[num].no_toptextures)
  1436. lprintf(LO_INFO,"Sector %i has no toptextures\n",num);
  1437. if (sectors[num].no_bottomtextures)
  1438. lprintf(LO_INFO,"Sector %i has no bottomtextures\n",num);
  1439. #endif
  1440. }
  1441. void BuildSideSegs() {
  1442. // JDC: since we are drawing with a depth buffer, we can draw complete line
  1443. // sides instead of the cut up seg_t used by the software renderer. This saves
  1444. // about 20% of the wall primitives, and also makes the drawn geometry "water tight",
  1445. // without the occasional pixel cracks that would occur at T-junctions between cut
  1446. // walls and uncut sector geometry.
  1447. // We can do more processing here to make the processing during drawing faster
  1448. // if we need more speed.
  1449. for ( int i = 0 ; i < numsegs ; i++ ) {
  1450. seg_t *seg = &segs[i];
  1451. seg_t *sideSeg = &seg->sidedef->sideSeg;
  1452. *sideSeg = *seg;
  1453. // this might be either the front or back of the line
  1454. if ( seg->frontsector == seg->linedef->frontsector ) {
  1455. sideSeg->v1 = seg->linedef->v1;
  1456. sideSeg->v2 = seg->linedef->v2;
  1457. } else {
  1458. assert( seg->frontsector == seg->linedef->backsector );
  1459. sideSeg->v1 = seg->linedef->v2;
  1460. sideSeg->v2 = seg->linedef->v1;
  1461. }
  1462. // the total length is needed for textur coordinate generation
  1463. float dx = (float)( sideSeg->v2->x - sideSeg->v1->x ) / FRACUNIT;
  1464. float dy = (float)( sideSeg->v2->y - sideSeg->v1->y ) / FRACUNIT;
  1465. sideSeg->length = sqrt( dx * dx + dy * dy );
  1466. sideSeg->offset = 0; // full-side segs will always have 0 offset
  1467. }
  1468. // check that every sidedef had a sideSeg created
  1469. for ( int i = 0 ; i < numsides ; i++ ) {
  1470. assert( sides[i].sideSeg.sidedef == &sides[i] );
  1471. }
  1472. }
  1473. #define MAX_TRIANGLE_INDEXES 0x10000
  1474. unsigned short triangleIndexes[MAX_TRIANGLE_INDEXES];
  1475. int numTriangleIndexes;
  1476. void BuildIndexedTriangles() {
  1477. numTriangleIndexes = 0;
  1478. numDrawVerts = 0;
  1479. // JDC: this chnges the multiple DrawArrays calls into a single DrawElements
  1480. // and puts the vertex data into an interleaved array, duplicated for
  1481. // the floors and ceilings so they can be combined into a single draw call
  1482. // when possible.
  1483. // There are likely duplicated vertexes in sectors with multiple loops, which
  1484. // could be a modest optimization to remove.
  1485. for ( int i = 0 ; i < numsectors ; i++ ) {
  1486. sector_t *sector = &sectors[i];
  1487. GLSector *glsector = &sectorloops[i];
  1488. sector->numIndexes = 0;
  1489. sector->numVerts = 0;
  1490. int firstIndex = numTriangleIndexes;
  1491. sector->verts[0] = &drawVerts[numDrawVerts];
  1492. sector->indexes[0] = &triangleIndexes[numTriangleIndexes];
  1493. for ( int j = 0 ; j < glsector->loopcount ; j++ ) {
  1494. int firstVert = numDrawVerts;
  1495. GLLoopDef *loop = &glsector->loops[j];
  1496. drawVert_t *dv = &drawVerts[numDrawVerts];
  1497. for ( int k = 0 ; k < loop->vertexcount ; k++ ) {
  1498. dv->xyz[0] = gld_vertexes[loop->vertexindex+k].x;
  1499. dv->xyz[1] = sector->floorheight / MAP_SCALE;
  1500. dv->xyz[2] = gld_vertexes[loop->vertexindex+k].z;
  1501. dv->st[0] = gld_texcoords[loop->vertexindex+k].u;
  1502. dv->st[1] = gld_texcoords[loop->vertexindex+k].v;
  1503. dv->rgba[0] = dv->rgba[1] = dv->rgba[2] = sector->lightlevel;
  1504. dv->rgba[3] = 255;
  1505. dv++;
  1506. }
  1507. // Find the min texcoord value so we can move them all as close
  1508. // to the origin as possible to reduce the required interpolator precision.
  1509. // Without this, there is texture jittering visible when the viewpoint
  1510. // is near the floor and far away from the origin (dead on the ground in netplay).
  1511. float minST[2] = { 99999, 99999 };
  1512. for ( int j = 0 ; j < loop->vertexcount ; j++ ) {
  1513. for ( int k = 0 ; k < 2 ; k++ ) {
  1514. if ( drawVerts[numDrawVerts+j].st[k] < minST[k] ) {
  1515. minST[k] = drawVerts[numDrawVerts+j].st[k];
  1516. }
  1517. }
  1518. }
  1519. for ( int k = 0 ; k < 2 ; k++ ) {
  1520. minST[k] = floor( minST[k] );
  1521. }
  1522. for ( int j = 0 ; j < loop->vertexcount ; j++ ) {
  1523. for ( int k = 0 ; k < 2 ; k++ ) {
  1524. drawVerts[numDrawVerts+j].st[k] -= minST[k];
  1525. }
  1526. }
  1527. sector->numVerts += loop->vertexcount;
  1528. numDrawVerts += loop->vertexcount;
  1529. assert( loop->vertexcount + numTriangleIndexes < MAX_TRIANGLE_INDEXES );
  1530. switch ( loop->mode ) {
  1531. case GL_TRIANGLES:
  1532. for ( int k = 0 ; k < loop->vertexcount ; k++ ) {
  1533. triangleIndexes[numTriangleIndexes++] = firstVert + k;
  1534. }
  1535. break;
  1536. case GL_TRIANGLE_STRIP:
  1537. for ( int k = 2 ; k < loop->vertexcount ; k++ ) {
  1538. // this doesn't keep the order correct, it flips facing every
  1539. // other one, but we don't have face culling on, so we don't care.
  1540. triangleIndexes[numTriangleIndexes++] = firstVert + k-2;
  1541. triangleIndexes[numTriangleIndexes++] = firstVert + k-1;
  1542. triangleIndexes[numTriangleIndexes++] = firstVert + k;
  1543. }
  1544. break;
  1545. case GL_TRIANGLE_FAN:
  1546. for ( int k = 2 ; k < loop->vertexcount ; k++ ) {
  1547. triangleIndexes[numTriangleIndexes++] = firstVert + 0;
  1548. triangleIndexes[numTriangleIndexes++] = firstVert + k-1;
  1549. triangleIndexes[numTriangleIndexes++] = firstVert + k;
  1550. }
  1551. break;
  1552. }
  1553. }
  1554. sector->numIndexes = numTriangleIndexes-firstIndex;
  1555. // duplicate it for the ceiling
  1556. sector->verts[1] = &drawVerts[numDrawVerts];
  1557. sector->indexes[1] = &triangleIndexes[numTriangleIndexes];
  1558. memcpy( sector->verts[1], sector->verts[0], sector->numVerts * sizeof( sector->verts[0][0] ) );
  1559. for ( int j = 0 ; j < sector->numVerts ; j++ ) {
  1560. sector->verts[1][j].xyz[1] = sector->ceilingheight / MAP_SCALE;
  1561. }
  1562. for ( int j = 0 ; j < sector->numIndexes ; j++ ) {
  1563. sector->indexes[1][j] = sector->indexes[0][j] + sector->numVerts;
  1564. }
  1565. numTriangleIndexes += sector->numIndexes;
  1566. numDrawVerts += sector->numVerts;
  1567. assert( numDrawVerts <= MAX_DRAW_VERTS );
  1568. assert( numTriangleIndexes <= MAX_TRIANGLE_INDEXES );
  1569. }
  1570. }
  1571. // gld_PreprocessLevel
  1572. //
  1573. // this checks all sectors if they are closed and calls gld_PrecalculateSector to
  1574. // calculate the loops for every sector
  1575. // the idea to check for closed sectors is from DEU. check next commentary
  1576. /*
  1577. Note from RQ:
  1578. This is a very simple idea, but it works! The first test (above)
  1579. checks that all Sectors are closed. But if a closed set of LineDefs
  1580. is moved out of a Sector and has all its "external" SideDefs pointing
  1581. to that Sector instead of the new one, then we need a second test.
  1582. That's why I check if the SideDefs facing each other are bound to
  1583. the same Sector.
  1584. Other note from RQ:
  1585. Nowadays, what makes the power of a good editor is its automatic tests.
  1586. So, if you are writing another Doom editor, you will probably want
  1587. to do the same kind of tests in your program. Fine, but if you use
  1588. these ideas, don't forget to credit DEU... Just a reminder... :-)
  1589. */
  1590. // so I credited DEU
  1591. void gld_PreprocessSectors(void)
  1592. {
  1593. boolean *sectorclosed;
  1594. int i;
  1595. #ifdef USE_GLU_TESS // figgi
  1596. char *vertexcheck;
  1597. int v1num;
  1598. int v2num;
  1599. int j;
  1600. #endif
  1601. // JDC: E3M8 has a map error that has a couple lines that should
  1602. // be part of sector 1 instead orphaned off in sector 2. I could
  1603. // let the non-closed sector carving routine handle this, but it
  1604. // would result in some pixel cracks. Instead, I merge the lines
  1605. // to where they should have been.
  1606. // This is probably not the right solution, because there are
  1607. // probably a bunch of other cases in the >100 Id maps.
  1608. extern int gameepisode, gamemap;
  1609. if ( gameepisode == 3 && gamemap == 8 ) {
  1610. void IR_MergeSectors( int fromSector, int intoSector );
  1611. IR_MergeSectors( 2, 1 );
  1612. }
  1613. #ifdef _DEBUG
  1614. levelinfo=fopen("levelinfo.txt","a");
  1615. if (levelinfo)
  1616. {
  1617. if (gamemode==commercial)
  1618. fprintf(levelinfo,"MAP%02i\n",gamemap);
  1619. else
  1620. fprintf(levelinfo,"E%iM%i\n",gameepisode,gamemap);
  1621. }
  1622. #endif
  1623. sectorclosed=Z_Malloc(numsectors*sizeof(boolean),PU_LEVEL,0);
  1624. if (!sectorclosed)
  1625. I_Error("gld_PreprocessSectors: Not enough memory for array sectorclosed");
  1626. memset(sectorclosed, 0, sizeof(boolean)*numsectors);
  1627. sectorloops=Z_Malloc(sizeof(GLSector)*numsectors,PU_LEVEL,0);
  1628. if (!sectorloops)
  1629. I_Error("gld_PreprocessSectors: Not enough memory for array sectorloops");
  1630. memset(sectorloops, 0, sizeof(GLSector)*numsectors);
  1631. sectorrendered=Z_Malloc(numsectors*sizeof(byte),PU_LEVEL,0);
  1632. if (!sectorrendered)
  1633. I_Error("gld_PreprocessSectors: Not enough memory for array sectorrendered");
  1634. memset(sectorrendered, 0, numsectors*sizeof(byte));
  1635. segrendered=Z_Malloc(numsegs*sizeof(byte),PU_LEVEL,0);
  1636. if (!segrendered)
  1637. I_Error("gld_PreprocessSectors: Not enough memory for array segrendered");
  1638. memset(segrendered, 0, numsegs*sizeof(byte));
  1639. gld_vertexes=NULL;
  1640. gld_texcoords=NULL;
  1641. gld_max_vertexes=0;
  1642. gld_num_vertexes=0;
  1643. gld_AddGlobalVertexes(numvertexes*2);
  1644. #ifdef USE_GLU_TESS
  1645. vertexcheck=Z_Malloc(numvertexes*sizeof(char),PU_LEVEL,0);
  1646. if (!vertexcheck)
  1647. {
  1648. if (levelinfo) fclose(levelinfo);
  1649. I_Error("gld_PreprocessSectors: Not enough memory for array vertexcheck");
  1650. return;
  1651. }
  1652. for (i=0; i<numsectors; i++)
  1653. {
  1654. memset(vertexcheck,0,numvertexes*sizeof(char));
  1655. for (j=0; j<sectors[i].linecount; j++)
  1656. {
  1657. v1num=((int)sectors[i].lines[j]->v1-(int)vertexes)/sizeof(vertex_t);
  1658. v2num=((int)sectors[i].lines[j]->v2-(int)vertexes)/sizeof(vertex_t);
  1659. if ((v1num>=numvertexes) || (v2num>=numvertexes))
  1660. continue;
  1661. if (sectors[i].lines[j]->sidenum[0]!=NO_INDEX)
  1662. if (sides[sectors[i].lines[j]->sidenum[0]].sector==&sectors[i])
  1663. {
  1664. vertexcheck[v1num]|=1;
  1665. vertexcheck[v2num]|=2;
  1666. }
  1667. if (sectors[i].lines[j]->sidenum[1]!=NO_INDEX)
  1668. if (sides[sectors[i].lines[j]->sidenum[1]].sector==&sectors[i])
  1669. {
  1670. vertexcheck[v1num]|=2;
  1671. vertexcheck[v2num]|=1;
  1672. }
  1673. }
  1674. if (sectors[i].linecount<3)
  1675. {
  1676. #ifdef _DEBUG
  1677. lprintf(LO_ERROR, "sector %i is not closed! %i lines in sector\n", i, sectors[i].linecount);
  1678. #endif
  1679. if (levelinfo) fprintf(levelinfo, "sector %i is not closed! %i lines in sector\n", i, sectors[i].linecount);
  1680. sectorclosed[i]=false;
  1681. }
  1682. else
  1683. {
  1684. sectorclosed[i]=true;
  1685. for (j=0; j<numvertexes; j++)
  1686. {
  1687. if ((vertexcheck[j]==1) || (vertexcheck[j]==2))
  1688. {
  1689. #ifdef _DEBUG
  1690. lprintf(LO_ERROR, "sector %i is not closed at vertex %i ! %i lines in sector\n", i, j, sectors[i].linecount);
  1691. #endif
  1692. if (levelinfo) fprintf(levelinfo, "sector %i is not closed at vertex %i ! %i lines in sector\n", i, j, sectors[i].linecount);
  1693. sectorclosed[i]=false;
  1694. }
  1695. }
  1696. }
  1697. // figgi -- adapted for glnodes
  1698. //!@# JDC seeing if this is necessary if (sectorclosed[i])
  1699. gld_PrecalculateSector(i);
  1700. }
  1701. Z_Free(vertexcheck);
  1702. #endif /* USE_GLU_TESS */
  1703. for (i=0; i<numsectors; i++)
  1704. gld_PrepareSectorSpecialEffects(i);
  1705. #if 0 // JDC!@# testing if this is necessary
  1706. // figgi -- adapted for glnodes
  1707. if (nodesVersion == 0)
  1708. gld_CarveFlats(numnodes-1, 0, 0, sectorclosed);
  1709. else
  1710. gld_GetSubSectorVertices(sectorclosed);
  1711. #endif
  1712. IR_InitLevel(); // JDC: setup for new renderer
  1713. if (levelinfo) fclose(levelinfo);
  1714. Z_Free(sectorclosed);
  1715. }
  1716. static float roll = 0.0f;
  1717. static float yaw = 0.0f;
  1718. static float inv_yaw = 0.0f;
  1719. static float pitch = 0.0f;
  1720. #define __glPi 3.14159265358979323846
  1721. static void infinitePerspective(GLdouble fovy, GLdouble aspect, GLdouble znear)
  1722. {
  1723. GLfloat left, right, bottom, top; // JDC: was GLdouble
  1724. GLfloat m[16]; // JDC: was GLdouble
  1725. top = znear * tan(fovy * __glPi / 360.0);
  1726. bottom = -top;
  1727. left = bottom * aspect;
  1728. right = top * aspect;
  1729. //qglFrustum(left, right, bottom, top, znear, zfar);
  1730. m[ 0] = (2 * znear) / (right - left);
  1731. m[ 4] = 0;
  1732. m[ 8] = (right + left) / (right - left);
  1733. m[12] = 0;
  1734. m[ 1] = 0;
  1735. m[ 5] = (2 * znear) / (top - bottom);
  1736. m[ 9] = (top + bottom) / (top - bottom);
  1737. m[13] = 0;
  1738. m[ 2] = 0;
  1739. m[ 6] = 0;
  1740. //m[10] = - (zfar + znear) / (zfar - znear);
  1741. //m[14] = - (2 * zfar * znear) / (zfar - znear);
  1742. m[10] = -1;
  1743. m[14] = -2 * znear;
  1744. m[ 3] = 0;
  1745. m[ 7] = 0;
  1746. m[11] = -1;
  1747. m[15] = 0;
  1748. glMultMatrixf(m); // JDC: was glMultMatrixd
  1749. }
  1750. void gld_StartDrawScene(void)
  1751. {
  1752. float trY ;
  1753. float xCamera,yCamera;
  1754. extern int screenblocks;
  1755. int height;
  1756. if (gl_shared_texture_palette)
  1757. glEnable(GL_SHARED_TEXTURE_PALETTE_EXT);
  1758. gld_SetPalette(-1);
  1759. if (screenblocks == 11)
  1760. height = SCREENHEIGHT;
  1761. else if (screenblocks == 10)
  1762. height = SCREENHEIGHT;
  1763. else
  1764. height = (screenblocks*SCREENHEIGHT/10) & ~7;
  1765. glViewport(viewwindowx, SCREENHEIGHT-(height+viewwindowy-((height-viewheight)/2)), viewwidth, height);
  1766. glScissor(viewwindowx, SCREENHEIGHT-(viewheight+viewwindowy), viewwidth, viewheight);
  1767. glEnable(GL_SCISSOR_TEST);
  1768. // Player coordinates
  1769. xCamera=-(float)viewx/MAP_SCALE;
  1770. yCamera=(float)viewy/MAP_SCALE;
  1771. trY=(float)viewz/MAP_SCALE;
  1772. yaw=270.0f-(float)(viewangle>>ANGLETOFINESHIFT)*360.0f/FINEANGLES;
  1773. inv_yaw=-90.0f+(float)(viewangle>>ANGLETOFINESHIFT)*360.0f/FINEANGLES;
  1774. #ifdef _DEBUG
  1775. glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  1776. #else
  1777. glClear(GL_DEPTH_BUFFER_BIT);
  1778. #endif
  1779. glEnable(GL_DEPTH_TEST);
  1780. glMatrixMode(GL_PROJECTION);
  1781. glLoadIdentity();
  1782. iphoneRotateForLandscape(); //JDC, make the 320x480 hardware seem like 480x320 in two different orientations
  1783. infinitePerspective(64.0f, 320.0f/200.0f, (float)gl_nearclip/100.0f);
  1784. glMatrixMode(GL_MODELVIEW);
  1785. glLoadIdentity();
  1786. glRotatef(roll, 0.0f, 0.0f, 1.0f);
  1787. glRotatef(pitch, 1.0f, 0.0f, 0.0f);
  1788. glRotatef(yaw, 0.0f, 1.0f, 0.0f);
  1789. glTranslatef(-xCamera, -trY, -yCamera);
  1790. if (use_fog)
  1791. glEnable(GL_FOG);
  1792. else
  1793. glDisable(GL_FOG);
  1794. rendermarker++;
  1795. gld_drawinfo.num_walls=0;
  1796. gld_drawinfo.num_flats=0;
  1797. gld_drawinfo.num_sprites=0;
  1798. gld_drawinfo.num_drawitems=0;
  1799. }
  1800. void gld_EndDrawScene(void)
  1801. {
  1802. player_t *player = &players[displayplayer];
  1803. // JDC: not in GLES, not needed since it is the default condition glDisable(GL_POLYGON_SMOOTH);
  1804. glViewport(0, 0, SCREENWIDTH, SCREENHEIGHT);
  1805. glDisable(GL_FOG);
  1806. gld_Set2DMode();
  1807. if (viewangleoffset <= 1024<<ANGLETOFINESHIFT ||
  1808. viewangleoffset >=-1024<<ANGLETOFINESHIFT)
  1809. { // don't draw on side views
  1810. R_DrawPlayerSprites();
  1811. }
  1812. if (player->fixedcolormap == 32) {
  1813. glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO);
  1814. glColor4f(1,1,1,1);
  1815. glBindTexture(GL_TEXTURE_2D, 0);
  1816. last_gltexture = NULL;
  1817. last_cm = -1;
  1818. glBegin(GL_TRIANGLE_STRIP);
  1819. glVertex2f( 0.0f, 0.0f);
  1820. glVertex2f( 0.0f, (float)SCREENHEIGHT);
  1821. glVertex2f( (float)SCREENWIDTH, 0.0f);
  1822. glVertex2f( (float)SCREENWIDTH, (float)SCREENHEIGHT);
  1823. glEnd();
  1824. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  1825. }
  1826. #ifdef IPHONE
  1827. // when taking screenshots, we usually don't want the blend
  1828. extern float *noBlend; // its actually a cvar, but the value is the first element
  1829. if ( *noBlend == 1 ) {
  1830. extra_alpha = 0;
  1831. }
  1832. if ( *noBlend == 2 ) {
  1833. extra_alpha = 0.5; // testing performance implications
  1834. }
  1835. #endif
  1836. if (extra_alpha>0.0f)
  1837. {
  1838. glDisable(GL_ALPHA_TEST);
  1839. glColor4f(extra_red, extra_green, extra_blue, extra_alpha);
  1840. glBindTexture(GL_TEXTURE_2D, 0);
  1841. last_gltexture = NULL;
  1842. last_cm = -1;
  1843. glBegin(GL_TRIANGLE_STRIP);
  1844. glVertex2f( 0.0f, 0.0f);
  1845. glVertex2f( 0.0f, (float)SCREENHEIGHT);
  1846. glVertex2f( (float)SCREENWIDTH, 0.0f);
  1847. glVertex2f( (float)SCREENWIDTH, (float)SCREENHEIGHT);
  1848. glEnd();
  1849. glEnable(GL_ALPHA_TEST);
  1850. }
  1851. glColor3f(1.0f,1.0f,1.0f);
  1852. glDisable(GL_SCISSOR_TEST);
  1853. if (gl_shared_texture_palette)
  1854. glDisable(GL_SHARED_TEXTURE_PALETTE_EXT);
  1855. // undo the 2x brightness mode now that we have drawn all the 3D stuff
  1856. glTexEnvf( GL_TEXTURE_ENV, GL_RGB_SCALE, 1.0 ); // JDC
  1857. }
  1858. static void gld_AddDrawItem(GLDrawItemType itemtype, int itemindex)
  1859. {
  1860. if (gld_drawinfo.num_drawitems>=gld_drawinfo.max_drawitems)
  1861. {
  1862. gld_drawinfo.max_drawitems+=64;
  1863. gld_drawinfo.drawitems=Z_Realloc(gld_drawinfo.drawitems,gld_drawinfo.max_drawitems*sizeof(GLDrawItem),PU_LEVEL,0);
  1864. gld_drawinfo.drawitems[gld_drawinfo.num_drawitems].itemtype=itemtype;
  1865. gld_drawinfo.drawitems[gld_drawinfo.num_drawitems].itemcount=1;
  1866. gld_drawinfo.drawitems[gld_drawinfo.num_drawitems].firstitemindex=itemindex;
  1867. gld_drawinfo.drawitems[gld_drawinfo.num_drawitems].rendermarker=rendermarker;
  1868. return;
  1869. }
  1870. if (gld_drawinfo.drawitems[gld_drawinfo.num_drawitems].rendermarker!=rendermarker)
  1871. {
  1872. gld_drawinfo.drawitems[gld_drawinfo.num_drawitems].itemtype=GLDIT_NONE;
  1873. gld_drawinfo.drawitems[gld_drawinfo.num_drawitems].rendermarker=rendermarker;
  1874. }
  1875. if (gld_drawinfo.drawitems[gld_drawinfo.num_drawitems].itemtype!=itemtype)
  1876. {
  1877. if (gld_drawinfo.drawitems[gld_drawinfo.num_drawitems].itemtype!=GLDIT_NONE)
  1878. gld_drawinfo.num_drawitems++;
  1879. if (gld_drawinfo.num_drawitems>=gld_drawinfo.max_drawitems)
  1880. {
  1881. gld_drawinfo.max_drawitems+=64;
  1882. gld_drawinfo.drawitems=Z_Realloc(gld_drawinfo.drawitems,gld_drawinfo.max_drawitems*sizeof(GLDrawItem),PU_LEVEL,0);
  1883. }
  1884. gld_drawinfo.drawitems[gld_drawinfo.num_drawitems].itemtype=itemtype;
  1885. gld_drawinfo.drawitems[gld_drawinfo.num_drawitems].itemcount=1;
  1886. gld_drawinfo.drawitems[gld_drawinfo.num_drawitems].firstitemindex=itemindex;
  1887. gld_drawinfo.drawitems[gld_drawinfo.num_drawitems].rendermarker=rendermarker;
  1888. return;
  1889. }
  1890. gld_drawinfo.drawitems[gld_drawinfo.num_drawitems].itemcount++;
  1891. }
  1892. /*****************
  1893. * *
  1894. * Walls *
  1895. * *
  1896. *****************/
  1897. static void gld_DrawWall(GLWall *wall)
  1898. {
  1899. if ( (!gl_drawskys) && (wall->flag>=GLDWF_SKY) )
  1900. wall->gltexture=NULL;
  1901. gld_BindTexture(wall->gltexture);
  1902. if (!wall->gltexture)
  1903. {
  1904. #ifdef _DEBUG
  1905. glColor4f(1.0f,0.0f,0.0f,1.0f);
  1906. #endif
  1907. }
  1908. if (wall->flag>=GLDWF_SKY)
  1909. {
  1910. if ( wall->gltexture )
  1911. {
  1912. glMatrixMode(GL_TEXTURE);
  1913. glPushMatrix();
  1914. if ((wall->flag&GLDWF_SKYFLIP)==GLDWF_SKYFLIP)
  1915. glScalef(-128.0f/(float)wall->gltexture->buffer_width,200.0f/320.0f*2.0f,1.0f);
  1916. else
  1917. glScalef(128.0f/(float)wall->gltexture->buffer_width,200.0f/320.0f*2.0f,1.0f);
  1918. glTranslatef(wall->skyyaw,wall->skyymid,0.0f);
  1919. }
  1920. glBegin(GL_TRIANGLE_STRIP);
  1921. glVertex3f(wall->glseg->x1,wall->ytop,wall->glseg->z1);
  1922. glVertex3f(wall->glseg->x1,wall->ybottom,wall->glseg->z1);
  1923. glVertex3f(wall->glseg->x2,wall->ytop,wall->glseg->z2);
  1924. glVertex3f(wall->glseg->x2,wall->ybottom,wall->glseg->z2);
  1925. glEnd();
  1926. if ( wall->gltexture )
  1927. {
  1928. glPopMatrix();
  1929. glMatrixMode(GL_MODELVIEW);
  1930. }
  1931. }
  1932. else
  1933. {
  1934. gld_StaticLightAlpha(wall->light, wall->alpha);
  1935. glBegin(GL_TRIANGLE_STRIP);
  1936. glTexCoord2f(wall->ul,wall->vt); glVertex3f(wall->glseg->x1,wall->ytop,wall->glseg->z1);
  1937. glTexCoord2f(wall->ul,wall->vb); glVertex3f(wall->glseg->x1,wall->ybottom,wall->glseg->z1);
  1938. glTexCoord2f(wall->ur,wall->vt); glVertex3f(wall->glseg->x2,wall->ytop,wall->glseg->z2);
  1939. glTexCoord2f(wall->ur,wall->vb); glVertex3f(wall->glseg->x2,wall->ybottom,wall->glseg->z2);
  1940. glEnd();
  1941. }
  1942. }
  1943. #define LINE seg->linedef
  1944. #define CALC_Y_VALUES(w, lineheight, floor_height, ceiling_height)\
  1945. (w).ytop=((float)(ceiling_height)/(float)MAP_SCALE)+0.001f;\
  1946. (w).ybottom=((float)(floor_height)/(float)MAP_SCALE)-0.001f;\
  1947. lineheight=((float)fabs(((ceiling_height)/(float)FRACUNIT)-((floor_height)/(float)FRACUNIT)))
  1948. #define OU(w,seg) (((float)((seg)->sidedef->textureoffset+(seg)->offset)/(float)FRACUNIT)/(float)(w).gltexture->buffer_width)
  1949. #define OV(w,seg) (((float)((seg)->sidedef->rowoffset)/(float)FRACUNIT)/(float)(w).gltexture->buffer_height)
  1950. #define OV_PEG(w,seg,v_offset) (OV((w),(seg))-(((float)(v_offset)/(float)FRACUNIT)/(float)(w).gltexture->buffer_height))
  1951. #define CALC_TEX_VALUES_TOP(w, seg, peg, linelength, lineheight)\
  1952. (w).flag=GLDWF_TOP;\
  1953. (w).ul=OU((w),(seg))+(0.0f);\
  1954. (w).ur=OU((w),(seg))+((linelength)/(float)(w).gltexture->buffer_width);\
  1955. (peg)?\
  1956. (\
  1957. (w).vb=OV((w),(seg))+((float)(w).gltexture->height/(float)(w).gltexture->tex_height),\
  1958. (w).vt=((w).vb-((float)(lineheight)/(float)(w).gltexture->buffer_height))\
  1959. ):(\
  1960. (w).vt=OV((w),(seg))+(0.0f),\
  1961. (w).vb=OV((w),(seg))+((float)(lineheight)/(float)(w).gltexture->buffer_height)\
  1962. )
  1963. #define CALC_TEX_VALUES_MIDDLE1S(w, seg, peg, linelength, lineheight)\
  1964. (w).flag=GLDWF_M1S;\
  1965. (w).ul=OU((w),(seg))+(0.0f);\
  1966. (w).ur=OU((w),(seg))+((linelength)/(float)(w).gltexture->buffer_width);\
  1967. (peg)?\
  1968. (\
  1969. (w).vb=OV((w),(seg))+((float)(w).gltexture->height/(float)(w).gltexture->tex_height),\
  1970. (w).vt=((w).vb-((float)(lineheight)/(float)(w).gltexture->buffer_height))\
  1971. ):(\
  1972. (w).vt=OV((w),(seg))+(0.0f),\
  1973. (w).vb=OV((w),(seg))+((float)(lineheight)/(float)(w).gltexture->buffer_height)\
  1974. )
  1975. #define CALC_TEX_VALUES_MIDDLE2S(w, seg, peg, linelength, lineheight)\
  1976. (w).flag=GLDWF_M2S;\
  1977. (w).ul=OU((w),(seg))+(0.0f);\
  1978. (w).ur=OU((w),(seg))+((linelength)/(float)(w).gltexture->buffer_width);\
  1979. (peg)?\
  1980. (\
  1981. (w).vb=((float)(w).gltexture->height/(float)(w).gltexture->tex_height),\
  1982. (w).vt=((w).vb-((float)(lineheight)/(float)(w).gltexture->buffer_height))\
  1983. ):(\
  1984. (w).vt=(0.0f),\
  1985. (w).vb=((float)(lineheight)/(float)(w).gltexture->buffer_height)\
  1986. )
  1987. #define CALC_TEX_VALUES_BOTTOM(w, seg, peg, linelength, lineheight, v_offset)\
  1988. (w).flag=GLDWF_BOT;\
  1989. (w).ul=OU((w),(seg))+(0.0f);\
  1990. (w).ur=OU((w),(seg))+((linelength)/(float)(w).gltexture->realtexwidth);\
  1991. (peg)?\
  1992. (\
  1993. (w).vb=OV_PEG((w),(seg),(v_offset))+((float)(w).gltexture->height/(float)(w).gltexture->tex_height),\
  1994. (w).vt=((w).vb-((float)(lineheight)/(float)(w).gltexture->buffer_height))\
  1995. ):(\
  1996. (w).vt=OV((w),(seg))+(0.0f),\
  1997. (w).vb=OV((w),(seg))+((float)(lineheight)/(float)(w).gltexture->buffer_height)\
  1998. )
  1999. // e6y
  2000. // Sky textures with a zero index should be forced
  2001. // See third episode of requiem.wad
  2002. #define SKYTEXTURE(sky1,sky2)\
  2003. if ((sky1) & PL_SKYFLAT)\
  2004. {\
  2005. const line_t *l = &lines[sky1 & ~PL_SKYFLAT];\
  2006. const side_t *s = *l->sidenum + sides;\
  2007. wall.gltexture=gld_RegisterTexture(texturetranslation[s->toptexture], false, texturetranslation[s->toptexture]==skytexture);\
  2008. wall.skyyaw=-2.0f*((-(float)((viewangle+s->textureoffset)>>ANGLETOFINESHIFT)*360.0f/FINEANGLES)/90.0f);\
  2009. wall.skyymid = 200.0f/319.5f*(((float)s->rowoffset/(float)FRACUNIT - 28.0f)/100.0f);\
  2010. wall.flag = l->special==272 ? GLDWF_SKY : GLDWF_SKYFLIP;\
  2011. }\
  2012. else\
  2013. if ((sky2) & PL_SKYFLAT)\
  2014. {\
  2015. const line_t *l = &lines[sky2 & ~PL_SKYFLAT];\
  2016. const side_t *s = *l->sidenum + sides;\
  2017. wall.gltexture=gld_RegisterTexture(texturetranslation[s->toptexture], false, texturetranslation[s->toptexture]==skytexture);\
  2018. wall.skyyaw=-2.0f*((-(float)((viewangle+s->textureoffset)>>ANGLETOFINESHIFT)*360.0f/FINEANGLES)/90.0f);\
  2019. wall.skyymid = 200.0f/319.5f*(((float)s->rowoffset/(float)FRACUNIT - 28.0f)/100.0f);\
  2020. wall.flag = l->special==272 ? GLDWF_SKY : GLDWF_SKYFLIP;\
  2021. }\
  2022. else\
  2023. {\
  2024. wall.gltexture=gld_RegisterTexture(skytexture, false, true);\
  2025. wall.skyyaw=-2.0f*((yaw+90.0f)/90.0f);\
  2026. wall.skyymid = 200.0f/319.5f*((100.0f)/100.0f);\
  2027. wall.flag = GLDWF_SKY;\
  2028. };
  2029. #define ADDWALL(wall)\
  2030. {\
  2031. if (gld_drawinfo.num_walls>=gld_drawinfo.max_walls)\
  2032. {\
  2033. gld_drawinfo.max_walls+=128;\
  2034. gld_drawinfo.walls=Z_Realloc(gld_drawinfo.walls,gld_drawinfo.max_walls*sizeof(GLWall),PU_LEVEL,0);\
  2035. }\
  2036. gld_AddDrawItem(GLDIT_WALL, gld_drawinfo.num_walls);\
  2037. gld_drawinfo.walls[gld_drawinfo.num_walls++]=*wall;\
  2038. };
  2039. void gld_AddWall(seg_t *seg)
  2040. {
  2041. GLWall wall;
  2042. GLTexture *temptex;
  2043. sector_t *frontsector;
  2044. sector_t *backsector;
  2045. sector_t ftempsec; // needed for R_FakeFlat
  2046. sector_t btempsec; // needed for R_FakeFlat
  2047. float lineheight;
  2048. int rellight = 0;
  2049. if (!segrendered)
  2050. return;
  2051. if (segrendered[seg->iSegID]==rendermarker)
  2052. return;
  2053. segrendered[seg->iSegID]=rendermarker;
  2054. if (!seg->frontsector)
  2055. return;
  2056. frontsector=R_FakeFlat(seg->frontsector, &ftempsec, NULL, NULL, false); // for boom effects
  2057. if (!frontsector)
  2058. return;
  2059. wall.glseg=&gl_segs[seg->iSegID];
  2060. rellight = seg->linedef->dx==0? +8 : seg->linedef->dy==0 ? -8 : 0;
  2061. wall.light=gld_CalcLightLevel(frontsector->lightlevel+rellight+(extralight<<5));
  2062. wall.alpha=1.0f;
  2063. wall.gltexture=NULL;
  2064. if (!seg->backsector) /* onesided */
  2065. {
  2066. if (frontsector->ceilingpic==skyflatnum)
  2067. {
  2068. wall.ytop=255.0f;
  2069. wall.ybottom=(float)frontsector->ceilingheight/MAP_SCALE;
  2070. SKYTEXTURE(frontsector->sky,frontsector->sky);
  2071. ADDWALL(&wall);
  2072. }
  2073. if (frontsector->floorpic==skyflatnum)
  2074. {
  2075. wall.ytop=(float)frontsector->floorheight/MAP_SCALE;
  2076. wall.ybottom=-255.0f;
  2077. SKYTEXTURE(frontsector->sky,frontsector->sky);
  2078. ADDWALL(&wall);
  2079. }
  2080. temptex=gld_RegisterTexture(texturetranslation[seg->sidedef->midtexture], true, false);
  2081. if (temptex)
  2082. {
  2083. wall.gltexture=temptex;
  2084. CALC_Y_VALUES(wall, lineheight, frontsector->floorheight, frontsector->ceilingheight);
  2085. CALC_TEX_VALUES_MIDDLE1S(
  2086. wall, seg, (LINE->flags & ML_DONTPEGBOTTOM)>0,
  2087. segs[seg->iSegID].length, lineheight
  2088. );
  2089. ADDWALL(&wall);
  2090. }
  2091. }
  2092. else /* twosided */
  2093. {
  2094. int floor_height,ceiling_height;
  2095. backsector=R_FakeFlat(seg->backsector, &btempsec, NULL, NULL, true); // for boom effects
  2096. if (!backsector)
  2097. return;
  2098. /* toptexture */
  2099. ceiling_height=frontsector->ceilingheight;
  2100. floor_height=backsector->ceilingheight;
  2101. if (frontsector->ceilingpic==skyflatnum)
  2102. {
  2103. wall.ytop=255.0f;
  2104. if (
  2105. // e6y
  2106. // Fix for HOM in the starting area on Memento Mori map29 and on map30.
  2107. // old code: (backsector->ceilingheight==backsector->floorheight) &&
  2108. (backsector->ceilingheight==backsector->floorheight||(backsector->ceilingheight<=frontsector->floorheight)) &&
  2109. (backsector->ceilingpic==skyflatnum)
  2110. )
  2111. {
  2112. wall.ybottom=(float)backsector->floorheight/MAP_SCALE;
  2113. SKYTEXTURE(frontsector->sky,backsector->sky);
  2114. ADDWALL(&wall);
  2115. }
  2116. else
  2117. {
  2118. if ( (texturetranslation[seg->sidedef->toptexture]!=NO_TEXTURE) )
  2119. {
  2120. // e6y
  2121. // It corrects some problem with sky, but I do not remember which one
  2122. // old code: wall.ybottom=(float)frontsector->ceilingheight/MAP_SCALE;
  2123. wall.ybottom=(float)MAX(frontsector->ceilingheight,backsector->ceilingheight)/MAP_SCALE;
  2124. SKYTEXTURE(frontsector->sky,backsector->sky);
  2125. ADDWALL(&wall);
  2126. }
  2127. else
  2128. if ( (backsector->ceilingheight <= frontsector->floorheight) ||
  2129. (backsector->ceilingpic != skyflatnum) )
  2130. {
  2131. wall.ybottom=(float)backsector->ceilingheight/MAP_SCALE;
  2132. SKYTEXTURE(frontsector->sky,backsector->sky);
  2133. ADDWALL(&wall);
  2134. }
  2135. }
  2136. }
  2137. if (floor_height<ceiling_height)
  2138. {
  2139. if (!((frontsector->ceilingpic==skyflatnum) && (backsector->ceilingpic==skyflatnum)))
  2140. {
  2141. temptex=gld_RegisterTexture(texturetranslation[seg->sidedef->toptexture], true, false);
  2142. if (temptex)
  2143. {
  2144. wall.gltexture=temptex;
  2145. CALC_Y_VALUES(wall, lineheight, floor_height, ceiling_height);
  2146. CALC_TEX_VALUES_TOP(
  2147. wall, seg, (LINE->flags & (ML_DONTPEGBOTTOM | ML_DONTPEGTOP))==0,
  2148. segs[seg->iSegID].length, lineheight
  2149. );
  2150. ADDWALL(&wall);
  2151. }
  2152. }
  2153. }
  2154. /* midtexture */
  2155. //e6y
  2156. if (comp[comp_maskedanim])
  2157. temptex=gld_RegisterTexture(seg->sidedef->midtexture, true, false);
  2158. else
  2159. // e6y
  2160. // Animated middle textures with a zero index should be forced
  2161. // See spacelab.wad (http://www.doomworld.com/idgames/index.php?id=6826)
  2162. temptex=gld_RegisterTexture(texturetranslation[seg->sidedef->midtexture], true, true);
  2163. if (temptex && seg->sidedef->midtexture != NO_TEXTURE)
  2164. {
  2165. wall.gltexture=temptex;
  2166. if ( (LINE->flags & ML_DONTPEGBOTTOM) >0)
  2167. {
  2168. if (seg->backsector->ceilingheight<=seg->frontsector->floorheight)
  2169. goto bottomtexture;
  2170. floor_height=MAX(seg->frontsector->floorheight,seg->backsector->floorheight)+(seg->sidedef->rowoffset);
  2171. ceiling_height=floor_height+(wall.gltexture->realtexheight<<FRACBITS);
  2172. }
  2173. else
  2174. {
  2175. if (seg->backsector->ceilingheight<=seg->frontsector->floorheight)
  2176. goto bottomtexture;
  2177. ceiling_height=MIN(seg->frontsector->ceilingheight,seg->backsector->ceilingheight)+(seg->sidedef->rowoffset);
  2178. floor_height=ceiling_height-(wall.gltexture->realtexheight<<FRACBITS);
  2179. }
  2180. // e6y
  2181. // The fix for wrong middle texture drawing
  2182. // if it exceeds the boundaries of its floor and ceiling
  2183. /*CALC_Y_VALUES(wall, lineheight, floor_height, ceiling_height);
  2184. CALC_TEX_VALUES_MIDDLE2S(
  2185. wall, seg, (LINE->flags & ML_DONTPEGBOTTOM)>0,
  2186. segs[seg->iSegID].length, lineheight
  2187. );*/
  2188. {
  2189. int floormax, ceilingmin, linelen;
  2190. float mip;
  2191. mip = (float)wall.gltexture->realtexheight/(float)wall.gltexture->buffer_height;
  2192. // if ( (texturetranslation[seg->sidedef->bottomtexture]!=R_TextureNumForName("-")) )
  2193. if (seg->sidedef->bottomtexture)
  2194. floormax=MAX(seg->frontsector->floorheight,seg->backsector->floorheight);
  2195. else
  2196. floormax=floor_height;
  2197. if (seg->sidedef->toptexture)
  2198. ceilingmin=MIN(seg->frontsector->ceilingheight,seg->backsector->ceilingheight);
  2199. else
  2200. ceilingmin=ceiling_height;
  2201. linelen=abs(ceiling_height-floor_height);
  2202. wall.ytop=((float)MIN(ceilingmin, ceiling_height)/(float)MAP_SCALE);
  2203. wall.ybottom=((float)MAX(floormax, floor_height)/(float)MAP_SCALE);
  2204. wall.flag=GLDWF_M2S;
  2205. wall.ul=OU((wall),(seg))+(0.0f);
  2206. wall.ur=OU(wall,(seg))+((segs[seg->iSegID].length)/(float)wall.gltexture->buffer_width);
  2207. if (floormax<=floor_height)
  2208. #ifdef USE_GLU_IMAGESCALE
  2209. wall.vb=1.0f;
  2210. #else // USE_GLU_IMAGESCALE
  2211. wall.vb=mip*1.0f;
  2212. #endif // USE_GLU_IMAGESCALE
  2213. else
  2214. wall.vb=mip*((float)(ceiling_height - floormax))/linelen;
  2215. if (ceilingmin>=ceiling_height)
  2216. wall.vt=0.0f;
  2217. else
  2218. wall.vt=mip*((float)(ceiling_height - ceilingmin))/linelen;
  2219. }
  2220. if (seg->linedef->tranlump >= 0 && general_translucency)
  2221. wall.alpha=(float)tran_filter_pct/100.0f;
  2222. ADDWALL(&wall);
  2223. wall.alpha=1.0f;
  2224. }
  2225. bottomtexture:
  2226. /* bottomtexture */
  2227. ceiling_height=backsector->floorheight;
  2228. floor_height=frontsector->floorheight;
  2229. if (frontsector->floorpic==skyflatnum)
  2230. {
  2231. wall.ybottom=-255.0f;
  2232. if (
  2233. (backsector->ceilingheight==backsector->floorheight) &&
  2234. (backsector->floorpic==skyflatnum)
  2235. )
  2236. {
  2237. wall.ytop=(float)backsector->floorheight/MAP_SCALE;
  2238. SKYTEXTURE(frontsector->sky,backsector->sky);
  2239. ADDWALL(&wall);
  2240. }
  2241. else
  2242. {
  2243. if ( (texturetranslation[seg->sidedef->bottomtexture]!=NO_TEXTURE) )
  2244. {
  2245. wall.ytop=(float)frontsector->floorheight/MAP_SCALE;
  2246. SKYTEXTURE(frontsector->sky,backsector->sky);
  2247. ADDWALL(&wall);
  2248. }
  2249. else
  2250. if ( (backsector->floorheight >= frontsector->ceilingheight) ||
  2251. (backsector->floorpic != skyflatnum) )
  2252. {
  2253. wall.ytop=(float)backsector->floorheight/MAP_SCALE;
  2254. SKYTEXTURE(frontsector->sky,backsector->sky);
  2255. ADDWALL(&wall);
  2256. }
  2257. }
  2258. }
  2259. if (floor_height<ceiling_height)
  2260. {
  2261. temptex=gld_RegisterTexture(texturetranslation[seg->sidedef->bottomtexture], true, false);
  2262. if (temptex)
  2263. {
  2264. wall.gltexture=temptex;
  2265. CALC_Y_VALUES(wall, lineheight, floor_height, ceiling_height);
  2266. CALC_TEX_VALUES_BOTTOM(
  2267. wall, seg, (LINE->flags & ML_DONTPEGBOTTOM)>0,
  2268. segs[seg->iSegID].length, lineheight,
  2269. floor_height-frontsector->ceilingheight
  2270. );
  2271. ADDWALL(&wall);
  2272. }
  2273. }
  2274. }
  2275. }
  2276. #undef LINE
  2277. #undef CALC_Y_VALUES
  2278. #undef OU
  2279. #undef OV
  2280. #undef OV_PEG
  2281. #undef CALC_TEX_VALUES_TOP
  2282. #undef CALC_TEX_VALUES_MIDDLE1S
  2283. #undef CALC_TEX_VALUES_MIDDLE2S
  2284. #undef CALC_TEX_VALUES_BOTTOM
  2285. #undef SKYTEXTURE
  2286. #undef ADDWALL
  2287. static void gld_PreprocessSegs(void)
  2288. {
  2289. int i;
  2290. gl_segs=Z_Malloc(numsegs*sizeof(GLSeg),PU_LEVEL,0);
  2291. for (i=0; i<numsegs; i++)
  2292. {
  2293. gl_segs[i].x1=-(float)segs[i].v1->x/(float)MAP_SCALE;
  2294. gl_segs[i].z1= (float)segs[i].v1->y/(float)MAP_SCALE;
  2295. gl_segs[i].x2=-(float)segs[i].v2->x/(float)MAP_SCALE;
  2296. gl_segs[i].z2= (float)segs[i].v2->y/(float)MAP_SCALE;
  2297. }
  2298. }
  2299. /*****************
  2300. * *
  2301. * Flats *
  2302. * *
  2303. *****************/
  2304. static void gld_DrawFlat(GLFlat *flat)
  2305. {
  2306. int loopnum; // current loop number
  2307. GLLoopDef *currentloop; // the current loop
  2308. #ifndef USE_VERTEX_ARRAYS
  2309. int vertexnum;
  2310. #endif
  2311. gld_BindFlat(flat->gltexture);
  2312. gld_StaticLight(flat->light);
  2313. glMatrixMode(GL_MODELVIEW);
  2314. glPushMatrix();
  2315. glTranslatef(0.0f,flat->z,0.0f);
  2316. glMatrixMode(GL_TEXTURE);
  2317. glPushMatrix();
  2318. glTranslatef(flat->uoffs/64.0f,flat->voffs/64.0f,0.0f);
  2319. if (flat->sectornum>=0)
  2320. {
  2321. // go through all loops of this sector
  2322. #ifndef USE_VERTEX_ARRAYS
  2323. for (loopnum=0; loopnum<sectorloops[flat->sectornum].loopcount; loopnum++)
  2324. {
  2325. // set the current loop
  2326. currentloop=&sectorloops[flat->sectornum].loops[loopnum];
  2327. if (!currentloop)
  2328. continue;
  2329. // set the mode (GL_TRIANGLES, GL_TRIANGLE_STRIP or GL_TRIANGLE_FAN)
  2330. glBegin(currentloop->mode);
  2331. // go through all vertexes of this loop
  2332. for (vertexnum=currentloop->vertexindex; vertexnum<(currentloop->vertexindex+currentloop->vertexcount); vertexnum++)
  2333. {
  2334. // set texture coordinate of this vertex
  2335. glTexCoord2fv(&gld_texcoords[vertexnum].u); // JDC: proper element address
  2336. // set vertex coordinate
  2337. glVertex3fv(&gld_vertexes[vertexnum].x); // JDC: proper element address
  2338. }
  2339. // end of loop
  2340. glEnd();
  2341. }
  2342. #else
  2343. for (loopnum=0; loopnum<sectorloops[flat->sectornum].loopcount; loopnum++)
  2344. {
  2345. // set the current loop
  2346. currentloop=&sectorloops[flat->sectornum].loops[loopnum];
  2347. glDrawArrays(currentloop->mode,currentloop->vertexindex,currentloop->vertexcount);
  2348. }
  2349. #endif
  2350. }
  2351. glPopMatrix();
  2352. glMatrixMode(GL_MODELVIEW);
  2353. glPopMatrix();
  2354. }
  2355. // gld_AddFlat
  2356. //
  2357. // This draws on flat for the sector "num"
  2358. // The ceiling boolean indicates if the flat is a floor(false) or a ceiling(true)
  2359. static void gld_AddFlat(int sectornum, boolean ceiling, visplane_t *plane)
  2360. {
  2361. sector_t *sector; // the sector we want to draw
  2362. sector_t tempsec; // needed for R_FakeFlat
  2363. int floorlightlevel; // killough 3/16/98: set floor lightlevel
  2364. int ceilinglightlevel; // killough 4/11/98
  2365. GLFlat flat;
  2366. if (sectornum<0)
  2367. return;
  2368. flat.sectornum=sectornum;
  2369. sector=&sectors[sectornum]; // get the sector
  2370. sector=R_FakeFlat(sector, &tempsec, &floorlightlevel, &ceilinglightlevel, false); // for boom effects
  2371. flat.ceiling=ceiling;
  2372. if (!ceiling) // if it is a floor ...
  2373. {
  2374. if (sector->floorpic == skyflatnum) // don't draw if sky
  2375. return;
  2376. // get the texture. flattranslation is maintained by doom and
  2377. // contains the number of the current animation frame
  2378. flat.gltexture=gld_RegisterFlat(flattranslation[sector->floorpic], true);
  2379. if (!flat.gltexture)
  2380. return;
  2381. // get the lightlevel from floorlightlevel
  2382. flat.light=gld_CalcLightLevel(floorlightlevel+(extralight<<5));
  2383. // calculate texture offsets
  2384. flat.uoffs=(float)sector->floor_xoffs/(float)FRACUNIT;
  2385. flat.voffs=(float)sector->floor_yoffs/(float)FRACUNIT;
  2386. }
  2387. else // if it is a ceiling ...
  2388. {
  2389. if (sector->ceilingpic == skyflatnum) // don't draw if sky
  2390. return;
  2391. // get the texture. flattranslation is maintained by doom and
  2392. // contains the number of the current animation frame
  2393. flat.gltexture=gld_RegisterFlat(flattranslation[sector->ceilingpic], true);
  2394. if (!flat.gltexture)
  2395. return;
  2396. // get the lightlevel from ceilinglightlevel
  2397. flat.light=gld_CalcLightLevel(ceilinglightlevel+(extralight<<5));
  2398. // calculate texture offsets
  2399. flat.uoffs=(float)sector->ceiling_xoffs/(float)FRACUNIT;
  2400. flat.voffs=(float)sector->ceiling_yoffs/(float)FRACUNIT;
  2401. }
  2402. // get height from plane
  2403. flat.z=(float)plane->height/MAP_SCALE;
  2404. if (gld_drawinfo.num_flats>=gld_drawinfo.max_flats)
  2405. {
  2406. gld_drawinfo.max_flats+=128;
  2407. gld_drawinfo.flats=Z_Realloc(gld_drawinfo.flats,gld_drawinfo.max_flats*sizeof(GLFlat),PU_LEVEL,0);
  2408. }
  2409. gld_AddDrawItem(GLDIT_FLAT, gld_drawinfo.num_flats);
  2410. gld_drawinfo.flats[gld_drawinfo.num_flats++]=flat;
  2411. }
  2412. void gld_AddPlane(int subsectornum, visplane_t *floor, visplane_t *ceiling)
  2413. {
  2414. subsector_t *subsector;
  2415. // check if all arrays are allocated
  2416. if (!sectorrendered)
  2417. return;
  2418. subsector = &subsectors[subsectornum];
  2419. if (!subsector)
  2420. return;
  2421. if (sectorrendered[subsector->sector->iSectorID]!=rendermarker) // if not already rendered
  2422. {
  2423. // render the floor
  2424. if (floor)
  2425. gld_AddFlat(subsector->sector->iSectorID, false, floor);
  2426. // render the ceiling
  2427. if (ceiling)
  2428. gld_AddFlat(subsector->sector->iSectorID, true, ceiling);
  2429. // set rendered true
  2430. sectorrendered[subsector->sector->iSectorID]=rendermarker;
  2431. }
  2432. }
  2433. /*****************
  2434. * *
  2435. * Sprites *
  2436. * *
  2437. *****************/
  2438. static void gld_DrawSprite(GLSprite *sprite)
  2439. {
  2440. gld_BindPatch(sprite->gltexture,sprite->cm);
  2441. glMatrixMode(GL_MODELVIEW);
  2442. glPushMatrix();
  2443. // Bring items up out of floor by configurable amount times .01 Mead 8/13/03
  2444. glTranslatef(sprite->x,sprite->y+ (.01f * (float)gl_sprite_offset),sprite->z);
  2445. glRotatef(inv_yaw,0.0f,1.0f,0.0f);
  2446. if(sprite->shadow)
  2447. {
  2448. glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA);
  2449. //glColor4f(0.2f,0.2f,0.2f,(float)tran_filter_pct/100.0f);
  2450. glAlphaFunc(GL_GEQUAL,0.1f);
  2451. glColor4f(0.2f,0.2f,0.2f,0.33f);
  2452. }
  2453. else
  2454. {
  2455. if(sprite->trans)
  2456. gld_StaticLightAlpha(sprite->light,(float)tran_filter_pct/100.0f);
  2457. else
  2458. gld_StaticLight(sprite->light);
  2459. }
  2460. glBegin(GL_TRIANGLE_STRIP);
  2461. glTexCoord2f(sprite->ul, sprite->vt); glVertex3f(sprite->x1, sprite->y1, 0.0f);
  2462. glTexCoord2f(sprite->ur, sprite->vt); glVertex3f(sprite->x2, sprite->y1, 0.0f);
  2463. glTexCoord2f(sprite->ul, sprite->vb); glVertex3f(sprite->x1, sprite->y2, 0.0f);
  2464. glTexCoord2f(sprite->ur, sprite->vb); glVertex3f(sprite->x2, sprite->y2, 0.0f);
  2465. glEnd();
  2466. glPopMatrix();
  2467. if(sprite->shadow)
  2468. {
  2469. glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  2470. glAlphaFunc(GL_GEQUAL,0.5f);
  2471. }
  2472. }
  2473. void gld_AddSprite(vissprite_t *vspr)
  2474. {
  2475. mobj_t *pSpr=vspr->thing;
  2476. GLSprite sprite;
  2477. float voff,hoff;
  2478. sprite.scale=vspr->scale;
  2479. if (pSpr->frame & FF_FULLBRIGHT)
  2480. sprite.light = 1.0f;
  2481. else
  2482. sprite.light = gld_CalcLightLevel(pSpr->subsector->sector->lightlevel+(extralight<<5));
  2483. sprite.cm=CR_LIMIT+(int)((pSpr->flags & MF_TRANSLATION) >> (MF_TRANSSHIFT));
  2484. sprite.gltexture=gld_RegisterPatch(vspr->patch+firstspritelump,sprite.cm);
  2485. if (!sprite.gltexture)
  2486. return;
  2487. sprite.shadow = (pSpr->flags & MF_SHADOW) != 0;
  2488. sprite.trans = (pSpr->flags & MF_TRANSLUCENT) != 0;
  2489. if (movement_smooth)
  2490. {
  2491. sprite.x = (float)(-pSpr->PrevX + FixedMul (tic_vars.frac, -pSpr->x - (-pSpr->PrevX)))/MAP_SCALE;
  2492. sprite.y = (float)(pSpr->PrevZ + FixedMul (tic_vars.frac, pSpr->z - pSpr->PrevZ))/MAP_SCALE;
  2493. sprite.z = (float)(pSpr->PrevY + FixedMul (tic_vars.frac, pSpr->y - pSpr->PrevY))/MAP_SCALE;
  2494. }
  2495. else
  2496. {
  2497. sprite.x=-(float)pSpr->x/MAP_SCALE;
  2498. sprite.y= (float)pSpr->z/MAP_SCALE;
  2499. sprite.z= (float)pSpr->y/MAP_SCALE;
  2500. }
  2501. sprite.vt=0.0f;
  2502. sprite.vb=(float)sprite.gltexture->height/(float)sprite.gltexture->tex_height;
  2503. if (vspr->flip)
  2504. {
  2505. sprite.ul=0.0f;
  2506. sprite.ur=(float)sprite.gltexture->width/(float)sprite.gltexture->tex_width;
  2507. }
  2508. else
  2509. {
  2510. sprite.ul=(float)sprite.gltexture->width/(float)sprite.gltexture->tex_width;
  2511. sprite.ur=0.0f;
  2512. }
  2513. hoff=(float)sprite.gltexture->leftoffset/(float)(MAP_COEFF);
  2514. voff=(float)sprite.gltexture->topoffset/(float)(MAP_COEFF);
  2515. sprite.x1=hoff-((float)sprite.gltexture->realtexwidth/(float)(MAP_COEFF));
  2516. sprite.x2=hoff;
  2517. sprite.y1=voff;
  2518. sprite.y2=voff-((float)sprite.gltexture->realtexheight/(float)(MAP_COEFF));
  2519. // JDC: don't let sprites poke below the ground level.
  2520. // Software rendering Doom didn't use depth buffering,
  2521. // so sprites always got drawn on top of the flat they
  2522. // were on, but in GL they tend to get a couple pixel
  2523. // rows clipped off.
  2524. if ( sprite.y2 < 0 ) {
  2525. sprite.y1 -= sprite.y2;
  2526. sprite.y2 = 0;
  2527. }
  2528. if (gld_drawinfo.num_sprites>=gld_drawinfo.max_sprites)
  2529. {
  2530. gld_drawinfo.max_sprites+=128;
  2531. gld_drawinfo.sprites=Z_Realloc(gld_drawinfo.sprites,gld_drawinfo.max_sprites*sizeof(GLSprite),PU_LEVEL,0);
  2532. }
  2533. gld_AddDrawItem(GLDIT_SPRITE, gld_drawinfo.num_sprites);
  2534. gld_drawinfo.sprites[gld_drawinfo.num_sprites++]=sprite;
  2535. }
  2536. /*****************
  2537. * *
  2538. * Draw *
  2539. * *
  2540. *****************/
  2541. void gld_DrawScene(player_t *player)
  2542. {
  2543. int i,j,k,count;
  2544. fixed_t max_scale;
  2545. glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  2546. glEnableClientState(GL_VERTEX_ARRAY);
  2547. rendered_visplanes = rendered_segs = rendered_vissprites = 0;
  2548. for (i=gld_drawinfo.num_drawitems; i>=0; i--)
  2549. {
  2550. switch (gld_drawinfo.drawitems[i].itemtype)
  2551. {
  2552. case GLDIT_FLAT:
  2553. // enable backside removing
  2554. glEnable(GL_CULL_FACE);
  2555. // floors
  2556. glCullFace(GL_FRONT);
  2557. for (j=(gld_drawinfo.drawitems[i].itemcount-1); j>=0; j--)
  2558. if (!gld_drawinfo.flats[j+gld_drawinfo.drawitems[i].firstitemindex].ceiling)
  2559. {
  2560. rendered_visplanes++;
  2561. gld_DrawFlat(&gld_drawinfo.flats[j+gld_drawinfo.drawitems[i].firstitemindex]);
  2562. }
  2563. // ceilings
  2564. glCullFace(GL_BACK);
  2565. for (j=(gld_drawinfo.drawitems[i].itemcount-1); j>=0; j--)
  2566. if (gld_drawinfo.flats[j+gld_drawinfo.drawitems[i].firstitemindex].ceiling)
  2567. {
  2568. rendered_visplanes++;
  2569. gld_DrawFlat(&gld_drawinfo.flats[j+gld_drawinfo.drawitems[i].firstitemindex]);
  2570. }
  2571. // disable backside removing
  2572. glDisable(GL_CULL_FACE);
  2573. break;
  2574. }
  2575. }
  2576. for (i=gld_drawinfo.num_drawitems; i>=0; i--)
  2577. {
  2578. switch (gld_drawinfo.drawitems[i].itemtype)
  2579. {
  2580. case GLDIT_WALL:
  2581. count=0;
  2582. for (k=GLDWF_TOP; k<=GLDWF_SKYFLIP; k++)
  2583. {
  2584. if (count>=gld_drawinfo.drawitems[i].itemcount)
  2585. continue;
  2586. if ( (gl_drawskys) && (k>=GLDWF_SKY) )
  2587. {
  2588. if (comp[comp_skymap] && gl_shared_texture_palette)
  2589. glDisable(GL_SHARED_TEXTURE_PALETTE_EXT);
  2590. glEnable(GL_TEXTURE_GEN_S);
  2591. glEnable(GL_TEXTURE_GEN_T);
  2592. glEnable(GL_TEXTURE_GEN_Q);
  2593. glColor4fv(gl_whitecolor);
  2594. }
  2595. for (j=(gld_drawinfo.drawitems[i].itemcount-1); j>=0; j--)
  2596. if (gld_drawinfo.walls[j+gld_drawinfo.drawitems[i].firstitemindex].flag==k)
  2597. {
  2598. rendered_segs++;
  2599. count++;
  2600. gld_DrawWall(&gld_drawinfo.walls[j+gld_drawinfo.drawitems[i].firstitemindex]);
  2601. }
  2602. if (gl_drawskys)
  2603. {
  2604. glDisable(GL_TEXTURE_GEN_Q);
  2605. glDisable(GL_TEXTURE_GEN_T);
  2606. glDisable(GL_TEXTURE_GEN_S);
  2607. if (comp[comp_skymap] && gl_shared_texture_palette)
  2608. glEnable(GL_SHARED_TEXTURE_PALETTE_EXT);
  2609. }
  2610. }
  2611. break;
  2612. case GLDIT_SPRITE:
  2613. if (gl_sortsprites)
  2614. {
  2615. do
  2616. {
  2617. max_scale=INT_MAX;
  2618. k=-1;
  2619. for (j=(gld_drawinfo.drawitems[i].itemcount-1); j>=0; j--)
  2620. if (gld_drawinfo.sprites[j+gld_drawinfo.drawitems[i].firstitemindex].scale<max_scale)
  2621. {
  2622. max_scale=gld_drawinfo.sprites[j+gld_drawinfo.drawitems[i].firstitemindex].scale;
  2623. k=j+gld_drawinfo.drawitems[i].firstitemindex;
  2624. }
  2625. if (k>=0)
  2626. {
  2627. rendered_vissprites++;
  2628. gld_DrawSprite(&gld_drawinfo.sprites[k]);
  2629. gld_drawinfo.sprites[k].scale=INT_MAX;
  2630. }
  2631. } while (max_scale!=INT_MAX);
  2632. }
  2633. else
  2634. {
  2635. for (j=(gld_drawinfo.drawitems[i].itemcount-1); j>=0; j--,rendered_vissprites++)
  2636. gld_DrawSprite(&gld_drawinfo.sprites[j+gld_drawinfo.drawitems[i].firstitemindex]);
  2637. }
  2638. break;
  2639. }
  2640. }
  2641. // JDC glDisableClientState(GL_TEXTURE_COORD_ARRAY);
  2642. // JDC glDisableClientState(GL_VERTEX_ARRAY);
  2643. }
  2644. void gld_PreprocessLevel(void)
  2645. {
  2646. #ifdef IPHONE
  2647. // defeer precache until after the first frame is drawn, so
  2648. // we get something in front of the user ASAP
  2649. extern int iphoneFrameNum;
  2650. extern int levelLoadFrameNum;
  2651. levelLoadFrameNum = iphoneFrameNum;
  2652. precache = 0;
  2653. #endif
  2654. if (precache)
  2655. gld_Precache();
  2656. gld_PreprocessSectors();
  2657. gld_PreprocessSegs();
  2658. memset(&gld_drawinfo,0,sizeof(GLDrawInfo));
  2659. #ifdef USE_VERTEX_ARRAYS // JDC
  2660. glTexCoordPointer(2,GL_FLOAT,0,gld_texcoords);
  2661. glVertexPointer(3,GL_FLOAT,0,gld_vertexes);
  2662. #endif
  2663. }