gl_main.c 101 KB

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