stb_voxel_render.h 157 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808
  1. // stb_voxel_render.h - v0.89 - Sean Barrett, 2015 - public domain
  2. //
  3. // This library helps render large-scale "voxel" worlds for games,
  4. // in this case, one with blocks that can have textures and that
  5. // can also be a few shapes other than cubes.
  6. //
  7. // Video introduction:
  8. // http://www.youtube.com/watch?v=2vnTtiLrV1w
  9. //
  10. // Minecraft-viewer sample app (not very simple though):
  11. // http://github.com/nothings/stb/tree/master/tests/caveview
  12. //
  13. // It works by creating triangle meshes. The library includes
  14. //
  15. // - converter from dense 3D arrays of block info to vertex mesh
  16. // - vertex & fragment shaders for the vertex mesh
  17. // - assistance in setting up shader state
  18. //
  19. // For portability, none of the library code actually accesses
  20. // the 3D graphics API. (At the moment, it's not actually portable
  21. // since the shaders are GLSL only, but patches are welcome.)
  22. //
  23. // You have to do all the caching and tracking of vertex buffers
  24. // yourself. However, you could also try making a game with
  25. // a small enough world that it's fully loaded rather than
  26. // streaming. Currently the preferred vertex format is 20 bytes
  27. // per quad. There are designs to allow much more compact formats
  28. // with a slight reduction in shader features, but no roadmap
  29. // for actually implementing them.
  30. //
  31. //
  32. // USAGE
  33. //
  34. // #define the symbol STB_VOXEL_RENDER_IMPLEMENTATION in *one*
  35. // C/C++ file before the #include of this file; the implementation
  36. // will be generated in that file.
  37. //
  38. // If you define the symbols STB_VOXEL_RENDER_STATIC, then the
  39. // implementation will be private to that file.
  40. //
  41. //
  42. // FEATURES
  43. //
  44. // - you can choose textured blocks with the features below,
  45. // or colored voxels with 2^24 colors and no textures.
  46. //
  47. // - voxels are mostly just cubes, but there's support for
  48. // half-height cubes and diagonal slopes, half-height
  49. // diagonals, and even odder shapes especially for doing
  50. // more-continuous "ground".
  51. //
  52. // - texture coordinates are projections along one of the major
  53. // axes, with the per-texture scaling.
  54. //
  55. // - a number of aspects of the shader and the vertex format
  56. // are configurable; the library generally takes care of
  57. // coordinating the vertex format with the mesh for you.
  58. //
  59. //
  60. // FEATURES (SHADER PERSPECTIVE)
  61. //
  62. // - vertices aligned on integer lattice, z on multiples of 0.5
  63. // - per-vertex "lighting" or "ambient occlusion" value (6 bits)
  64. // - per-vertex texture crossfade (3 bits)
  65. //
  66. // - per-face texture #1 id (8-bit index into array texture)
  67. // - per-face texture #2 id (8-bit index into second array texture)
  68. // - per-face color (6-bit palette index, 2 bits of per-texture boolean enable)
  69. // - per-face 5-bit normal for lighting calculations & texture coord computation
  70. // - per-face 2-bit texture matrix rotation to rotate faces
  71. //
  72. // - indexed-by-texture-id scale factor (separate for texture #1 and texture #2)
  73. // - indexed-by-texture-#2-id blend mode (alpha composite or modulate/multiply);
  74. // the first is good for decals, the second for detail textures, "light maps",
  75. // etc; both modes are controlled by texture #2's alpha, scaled by the
  76. // per-vertex texture crossfade and the per-face color (if enabled on texture #2);
  77. // modulate/multiply multiplies by an extra factor of 2.0 so that if you
  78. // make detail maps whose average brightness is 0.5 everything works nicely.
  79. //
  80. // - ambient lighting: half-lambert directional plus constant, all scaled by vertex ao
  81. // - face can be fullbright (emissive), controlled by per-face color
  82. // - installable lighting, with default single-point-light
  83. // - installable fog, with default hacked smoothstep
  84. //
  85. // Note that all the variations of lighting selection and texture
  86. // blending are run-time conditions in the shader, so they can be
  87. // intermixed in a single mesh.
  88. //
  89. //
  90. // INTEGRATION ARC
  91. //
  92. // The way to get this library to work from scratch is to do the following:
  93. //
  94. // Step 1. define STBVOX_CONFIG_MODE to 0
  95. //
  96. // This mode uses only vertex attributes and uniforms, and is easiest
  97. // to get working. It requires 32 bytes per quad and limits the
  98. // size of some tables to avoid hitting uniform limits.
  99. //
  100. // Step 2. define STBVOX_CONFIG_MODE to 1
  101. //
  102. // This requires using a texture buffer to store the quad data,
  103. // reducing the size to 20 bytes per quad.
  104. //
  105. // Step 3: define STBVOX_CONFIG_PREFER_TEXBUFFER
  106. //
  107. // This causes some uniforms to be stored as texture buffers
  108. // instead. This increases the size of some of those tables,
  109. // and avoids a potential slow path (gathering non-uniform
  110. // data from uniforms) on some hardware.
  111. //
  112. // In the future I might add additional modes that have significantly
  113. // smaller meshes but reduce features, down as small as 6 bytes per quad.
  114. // See elsewhere in this file for a table of candidate modes. Switching
  115. // to a mode will require changing some of your mesh creation code, but
  116. // everything else should be seamless. (And I'd like to change the API
  117. // so that mesh creation is data-driven the way the uniforms are, and
  118. // then you wouldn't even have to change anything but the mode number.)
  119. //
  120. //
  121. // IMPROVEMENTS FOR SHIP-WORTHY PROGRAMS USING THIS LIBRARY
  122. //
  123. // I currently tolerate a certain level of "bugginess" in this library.
  124. //
  125. // I'm referring to things which look a little wrong (as long as they
  126. // don't cause holes or cracks in the output meshes), or things which
  127. // do not produce as optimal a mesh as possible. Notable examples:
  128. //
  129. // - incorrect lighting on slopes
  130. // - inefficient meshes for vheight blocks
  131. //
  132. // I am willing to do the work to improve these things if someone is
  133. // going to ship a substantial program that would be improved by them.
  134. // (It need not be commercial, nor need it be a game.) I just didn't
  135. // want to do the work up front if it might never be leveraged. So just
  136. // submit a bug report as usual (github is preferred), but add a note
  137. // that this is for a thing that is really going to ship. (That means
  138. // you need to be far enough into the project that it's clear you're
  139. // committed to it; not during early exploratory development.)
  140. //
  141. //
  142. // VOXEL MESH API
  143. //
  144. // Context
  145. //
  146. // To understand the API, make sure you first understand the feature set
  147. // listed above.
  148. //
  149. // Because the vertices are compact, they have very limited spatial
  150. // precision. Thus a single mesh can only contain the data for a limited
  151. // area. To make very large voxel maps, you'll need to build multiple
  152. // vertex buffers. (But you want this anyway for frustum culling.)
  153. //
  154. // Each generated mesh has three components:
  155. // - vertex data (vertex buffer)
  156. // - face data (optional, stored in texture buffer)
  157. // - mesh transform (uniforms)
  158. //
  159. // Once you've generated the mesh with this library, it's up to you
  160. // to upload it to the GPU, to keep track of the state, and to render
  161. // it.
  162. //
  163. // Concept
  164. //
  165. // The basic design is that you pass in one or more 3D arrays; each array
  166. // is (typically) one-byte-per-voxel and contains information about one
  167. // or more properties of some particular voxel property.
  168. //
  169. // Because there is so much per-vertex and per-face data possible
  170. // in the output, and each voxel can have 6 faces and 8 vertices, it
  171. // would require an very large data structure to describe all
  172. // of the possibilities, and this would cause the mesh-creation
  173. // process to be slow. Instead, the API provides multiple ways
  174. // to express each property, some more compact, others less so;
  175. // each such way has some limitations on what it can express.
  176. //
  177. // Note that there are so many paths and combinations, not all of them
  178. // have been tested. Just report bugs and I'll fix 'em.
  179. //
  180. // Details
  181. //
  182. // See the API documentation in the header-file section.
  183. //
  184. //
  185. // CONTRIBUTORS
  186. //
  187. // Features Porting Bugfixes & Warnings
  188. // Sean Barrett github:r-leyh Jesus Fernandez
  189. // Miguel Lechon github:Arbeiterunfallversicherungsgesetz
  190. // Thomas Frase James Hofmann
  191. // Stephen Olsen github:guitarfreak
  192. //
  193. // VERSION HISTORY
  194. //
  195. // 0.89 (2020-02-02) bugfix in sample code
  196. // 0.88 (2019-03-04) fix warnings
  197. // 0.87 (2019-02-25) fix warning
  198. // 0.86 (2019-02-07) fix typos in comments
  199. // 0.85 (2017-03-03) add block_selector (by guitarfreak)
  200. // 0.84 (2016-04-02) fix GLSL syntax error on glModelView path
  201. // 0.83 (2015-09-13) remove non-constant struct initializers to support more compilers
  202. // 0.82 (2015-08-01) added input.packed_compact to store rot, vheight & texlerp efficiently
  203. // fix broken tex_overlay2
  204. // 0.81 (2015-05-28) fix broken STBVOX_CONFIG_OPTIMIZED_VHEIGHT
  205. // 0.80 (2015-04-11) fix broken STBVOX_CONFIG_ROTATION_IN_LIGHTING refactoring
  206. // change STBVOX_MAKE_LIGHTING to STBVOX_MAKE_LIGHTING_EXT so
  207. // that header defs don't need to see config vars
  208. // add STBVOX_CONFIG_VHEIGHT_IN_LIGHTING and other vheight fixes
  209. // added documentation for vheight ("weird slopes")
  210. // 0.79 (2015-04-01) fix the missing types from 0.78; fix string constants being const
  211. // 0.78 (2015-04-02) bad "#else", compile as C++
  212. // 0.77 (2015-04-01) documentation tweaks, rename config var to STB_VOXEL_RENDER_STATIC
  213. // 0.76 (2015-04-01) typos, signed/unsigned shader issue, more documentation
  214. // 0.75 (2015-04-01) initial release
  215. //
  216. //
  217. // HISTORICAL FOUNDATION
  218. //
  219. // stb_voxel_render 20-byte quads 2015/01
  220. // zmc engine 32-byte quads 2013/12
  221. // zmc engine 96-byte quads 2011/10
  222. //
  223. //
  224. // LICENSE
  225. //
  226. // See end of file for license information.
  227. #ifndef INCLUDE_STB_VOXEL_RENDER_H
  228. #define INCLUDE_STB_VOXEL_RENDER_H
  229. #include <stdlib.h>
  230. typedef struct stbvox_mesh_maker stbvox_mesh_maker;
  231. typedef struct stbvox_input_description stbvox_input_description;
  232. #ifdef STB_VOXEL_RENDER_STATIC
  233. #define STBVXDEC static
  234. #else
  235. #define STBVXDEC extern
  236. #endif
  237. #ifdef __cplusplus
  238. extern "C" {
  239. #endif
  240. //////////////////////////////////////////////////////////////////////////////
  241. //
  242. // CONFIGURATION MACROS
  243. //
  244. // #define STBVOX_CONFIG_MODE <integer> // REQUIRED
  245. // Configures the overall behavior of stb_voxel_render. This
  246. // can affect the shaders, the uniform info, and other things.
  247. // (If you need more than one mode in the same app, you can
  248. // use STB_VOXEL_RENDER_STATIC to create multiple versions
  249. // in separate files, and then wrap them.)
  250. //
  251. // Mode value Meaning
  252. // 0 Textured blocks, 32-byte quads
  253. // 1 Textured blocks, 20-byte quads
  254. // 20 Untextured blocks, 32-byte quads
  255. // 21 Untextured blocks, 20-byte quads
  256. //
  257. //
  258. // #define STBVOX_CONFIG_PRECISION_Z <integer> // OPTIONAL
  259. // Defines the number of bits of fractional position for Z.
  260. // Only 0 or 1 are valid. 1 is the default. If 0, then a
  261. // single mesh has twice the legal Z range; e.g. in
  262. // modes 0,1,20,21, Z in the mesh can extend to 511 instead
  263. // of 255. However, half-height blocks cannot be used.
  264. //
  265. // All of the following are just #ifdef tested so need no values, and are optional.
  266. //
  267. // STBVOX_CONFIG_BLOCKTYPE_SHORT
  268. // use unsigned 16-bit values for 'blocktype' in the input instead of 8-bit values
  269. //
  270. // STBVOX_CONFIG_OPENGL_MODELVIEW
  271. // use the gl_ModelView matrix rather than the explicit uniform
  272. //
  273. // STBVOX_CONFIG_HLSL
  274. // NOT IMPLEMENTED! Define HLSL shaders instead of GLSL shaders
  275. //
  276. // STBVOX_CONFIG_PREFER_TEXBUFFER
  277. // Stores many of the uniform arrays in texture buffers instead,
  278. // so they can be larger and may be more efficient on some hardware.
  279. //
  280. // STBVOX_CONFIG_LIGHTING_SIMPLE
  281. // Creates a simple lighting engine with a single point light source
  282. // in addition to the default half-lambert ambient light.
  283. //
  284. // STBVOX_CONFIG_LIGHTING
  285. // Declares a lighting function hook; you must append a lighting function
  286. // to the shader before compiling it:
  287. // vec3 compute_lighting(vec3 pos, vec3 norm, vec3 albedo, vec3 ambient);
  288. // 'ambient' is the half-lambert ambient light with vertex ambient-occlusion applied
  289. //
  290. // STBVOX_CONFIG_FOG_SMOOTHSTEP
  291. // Defines a simple unrealistic fog system designed to maximize
  292. // unobscured view distance while not looking too weird when things
  293. // emerge from the fog. Configured using an extra array element
  294. // in the STBVOX_UNIFORM_ambient uniform.
  295. //
  296. // STBVOX_CONFIG_FOG
  297. // Defines a fog function hook; you must append a fog function to
  298. // the shader before compiling it:
  299. // vec3 compute_fog(vec3 color, vec3 relative_pos, float fragment_alpha);
  300. // "color" is the incoming pre-fogged color, fragment_alpha is the alpha value,
  301. // and relative_pos is the vector from the point to the camera in worldspace
  302. //
  303. // STBVOX_CONFIG_DISABLE_TEX2
  304. // This disables all processing of texture 2 in the shader in case
  305. // you don't use it. Eventually this could be replaced with a mode
  306. // that omits the unused data entirely.
  307. //
  308. // STBVOX_CONFIG_TEX1_EDGE_CLAMP
  309. // STBVOX_CONFIG_TEX2_EDGE_CLAMP
  310. // If you want to edge clamp the textures, instead of letting them wrap,
  311. // set this flag. By default stb_voxel_render relies on texture wrapping
  312. // to simplify texture coordinate generation. This flag forces it to do
  313. // it correctly, although there can still be minor artifacts.
  314. //
  315. // STBVOX_CONFIG_ROTATION_IN_LIGHTING
  316. // Changes the meaning of the 'lighting' mesher input variable to also
  317. // store the rotation; see later discussion.
  318. //
  319. // STBVOX_CONFIG_VHEIGHT_IN_LIGHTING
  320. // Changes the meaning of the 'lighting' mesher input variable to also
  321. // store the vheight; see later discussion. Cannot use both this and
  322. // the previous variable.
  323. //
  324. // STBVOX_CONFIG_PREMULTIPLIED_ALPHA
  325. // Adjusts the shader calculations on the assumption that tex1.rgba,
  326. // tex2.rgba, and color.rgba all use premultiplied values, and that
  327. // the output of the fragment shader should be premultiplied.
  328. //
  329. // STBVOX_CONFIG_UNPREMULTIPLY
  330. // Only meaningful if STBVOX_CONFIG_PREMULTIPLIED_ALPHA is defined.
  331. // Changes the behavior described above so that the inputs are
  332. // still premultiplied alpha, but the output of the fragment
  333. // shader is not premultiplied alpha. This is needed when allowing
  334. // non-unit alpha values but not doing alpha-blending (for example
  335. // when alpha testing).
  336. //
  337. //////////////////////////////////////////////////////////////////////////////
  338. //
  339. // MESHING
  340. //
  341. // A mesh represents a (typically) small chunk of a larger world.
  342. // Meshes encode coordinates using small integers, so those
  343. // coordinates must be relative to some base location.
  344. // All of the coordinates in the functions below use
  345. // these relative coordinates unless explicitly stated
  346. // otherwise.
  347. //
  348. // Input to the meshing step is documented further down
  349. STBVXDEC void stbvox_init_mesh_maker(stbvox_mesh_maker *mm);
  350. // Call this function to initialize a mesh-maker context structure
  351. // used to build meshes. You should have one context per thread
  352. // that's building meshes.
  353. STBVXDEC void stbvox_set_buffer(stbvox_mesh_maker *mm, int mesh, int slot, void *buffer, size_t len);
  354. // Call this to set the buffer into which stbvox will write the mesh
  355. // it creates. It can build more than one mesh in parallel (distinguished
  356. // by the 'mesh' parameter), and each mesh can be made up of more than
  357. // one buffer (distinguished by the 'slot' parameter).
  358. //
  359. // Multiple meshes are under your control; use the 'selector' input
  360. // variable to choose which mesh each voxel's vertices are written to.
  361. // For example, you can use this to generate separate meshes for opaque
  362. // and transparent data.
  363. //
  364. // You can query the number of slots by calling stbvox_get_buffer_count
  365. // described below. The meaning of the buffer for each slot depends
  366. // on STBVOX_CONFIG_MODE.
  367. //
  368. // In mode 0 & mode 20, there is only one slot. The mesh data for that
  369. // slot is two interleaved vertex attributes: attr_vertex, a single
  370. // 32-bit uint, and attr_face, a single 32-bit uint.
  371. //
  372. // In mode 1 & mode 21, there are two slots. The first buffer should
  373. // be four times as large as the second buffer. The first buffer
  374. // contains a single vertex attribute: 'attr_vertex', a single 32-bit uint.
  375. // The second buffer contains texture buffer data (an array of 32-bit uints)
  376. // that will be accessed through the sampler identified by STBVOX_UNIFORM_face_data.
  377. STBVXDEC int stbvox_get_buffer_count(stbvox_mesh_maker *mm);
  378. // Returns the number of buffers needed per mesh as described above.
  379. STBVXDEC int stbvox_get_buffer_size_per_quad(stbvox_mesh_maker *mm, int slot);
  380. // Returns how much of a given buffer will get used per quad. This
  381. // allows you to choose correct relative sizes for each buffer, although
  382. // the values are fixed based on the configuration you've selected at
  383. // compile time, and the details are described in stbvox_set_buffer.
  384. STBVXDEC void stbvox_set_default_mesh(stbvox_mesh_maker *mm, int mesh);
  385. // Selects which mesh the mesher will output to (see previous function)
  386. // if the input doesn't specify a per-voxel selector. (I doubt this is
  387. // useful, but it's here just in case.)
  388. STBVXDEC stbvox_input_description *stbvox_get_input_description(stbvox_mesh_maker *mm);
  389. // This function call returns a pointer to the stbvox_input_description part
  390. // of stbvox_mesh_maker (which you should otherwise treat as opaque). You
  391. // zero this structure, then fill out the relevant pointers to the data
  392. // describing your voxel object/world.
  393. //
  394. // See further documentation at the description of stbvox_input_description below.
  395. STBVXDEC void stbvox_set_input_stride(stbvox_mesh_maker *mm, int x_stride_in_elements, int y_stride_in_elements);
  396. // This sets the stride between successive elements of the 3D arrays
  397. // in the stbvox_input_description. Z values are always stored consecutively.
  398. // (The preferred coordinate system for stbvox is X right, Y forwards, Z up.)
  399. STBVXDEC void stbvox_set_input_range(stbvox_mesh_maker *mm, int x0, int y0, int z0, int x1, int y1, int z1);
  400. // This sets the range of values in the 3D array for the voxels that
  401. // the mesh generator will convert. The lower values are inclusive,
  402. // the higher values are exclusive, so (0,0,0) to (16,16,16) generates
  403. // mesh data associated with voxels up to (15,15,15) but no higher.
  404. //
  405. // The mesh generate generates faces at the boundary between open space
  406. // and solid space but associates them with the solid space, so if (15,0,0)
  407. // is open and (16,0,0) is solid, then the mesh will contain the boundary
  408. // between them if x0 <= 16 and x1 > 16.
  409. //
  410. // Note that the mesh generator will access array elements 1 beyond the
  411. // limits set in these parameters. For example, if you set the limits
  412. // to be (0,0,0) and (16,16,16), then the generator will access all of
  413. // the voxels between (-1,-1,-1) and (16,16,16), including (16,16,16).
  414. // You may have to do pointer arithmetic to make it work.
  415. //
  416. // For example, caveview processes mesh chunks that are 32x32x16, but it
  417. // does this using input buffers that are 34x34x18.
  418. //
  419. // The lower limits are x0 >= 0, y0 >= 0, and z0 >= 0.
  420. //
  421. // The upper limits are mode dependent, but all the current methods are
  422. // limited to x1 < 127, y1 < 127, z1 < 255. Note that these are not
  423. // powers of two; if you want to use power-of-two chunks (to make
  424. // it efficient to decide which chunk a coordinate falls in), you're
  425. // limited to at most x1=64, y1=64, z1=128. For classic Minecraft-style
  426. // worlds with limited vertical extent, I recommend using a single
  427. // chunk for the entire height, which limits the height to 255 blocks
  428. // (one less than Minecraft), and only chunk the map in X & Y.
  429. STBVXDEC int stbvox_make_mesh(stbvox_mesh_maker *mm);
  430. // Call this function to create mesh data for the currently configured
  431. // set of input data. This appends to the currently configured mesh output
  432. // buffer. Returns 1 on success. If there is not enough room in the buffer,
  433. // it outputs as much as it can, and returns 0; you need to switch output
  434. // buffers (either by calling stbvox_set_buffer to set new buffers, or
  435. // by copying the data out and calling stbvox_reset_buffers), and then
  436. // call this function again without changing any of the input parameters.
  437. //
  438. // Note that this function appends; you can call it multiple times to
  439. // build a single mesh. For example, caveview uses chunks that are
  440. // 32x32x255, but builds the mesh for it by processing 32x32x16 at atime
  441. // (this is faster as it is reuses the same 34x34x18 input buffers rather
  442. // than needing 34x34x257 input buffers).
  443. // Once you're done creating a mesh into a given buffer,
  444. // consider the following functions:
  445. STBVXDEC int stbvox_get_quad_count(stbvox_mesh_maker *mm, int mesh);
  446. // Returns the number of quads in the mesh currently generated by mm.
  447. // This is the sum of all consecutive stbvox_make_mesh runs appending
  448. // to the same buffer. 'mesh' distinguishes between the multiple user
  449. // meshes available via 'selector' or stbvox_set_default_mesh.
  450. //
  451. // Typically you use this function when you're done building the mesh
  452. // and want to record how to draw it.
  453. //
  454. // Note that there are no index buffers; the data stored in the buffers
  455. // should be drawn as quads (e.g. with GL_QUAD); if your API does not
  456. // support quads, you can create a single index buffer large enough to
  457. // draw your largest vertex buffer, and reuse it for every rendering.
  458. // (Note that if you use 32-bit indices, you'll use 24 bytes of bandwidth
  459. // per quad, more than the 20 bytes for the vertex/face mesh data.)
  460. STBVXDEC void stbvox_set_mesh_coordinates(stbvox_mesh_maker *mm, int x, int y, int z);
  461. // Sets the global coordinates for this chunk, such that (0,0,0) relative
  462. // coordinates will be at (x,y,z) in global coordinates.
  463. STBVXDEC void stbvox_get_bounds(stbvox_mesh_maker *mm, float bounds[2][3]);
  464. // Returns the bounds for the mesh in global coordinates. Use this
  465. // for e.g. frustum culling the mesh. @BUG: this just uses the
  466. // values from stbvox_set_input_range(), so if you build by
  467. // appending multiple values, this will be wrong, and you need to
  468. // set stbvox_set_input_range() to the full size. Someday this
  469. // will switch to tracking the actual bounds of the *mesh*, though.
  470. STBVXDEC void stbvox_get_transform(stbvox_mesh_maker *mm, float transform[3][3]);
  471. // Returns the 'transform' data for the shader uniforms. It is your
  472. // job to set this to the shader before drawing the mesh. It is the
  473. // only uniform that needs to change per-mesh. Note that it is not
  474. // a 3x3 matrix, but rather a scale to decode fixed point numbers as
  475. // floats, a translate from relative to global space, and a special
  476. // translation for texture coordinate generation that avoids
  477. // floating-point precision issues. @TODO: currently we add the
  478. // global translation to the vertex, than multiply by modelview,
  479. // but this means if camera location and vertex are far from the
  480. // origin, we lose precision. Need to make a special modelview with
  481. // the translation (or some of it) factored out to avoid this.
  482. STBVXDEC void stbvox_reset_buffers(stbvox_mesh_maker *mm);
  483. // Call this function if you're done with the current output buffer
  484. // but want to reuse it (e.g. you're done appending with
  485. // stbvox_make_mesh and you've copied the data out to your graphics API
  486. // so can reuse the buffer).
  487. //////////////////////////////////////////////////////////////////////////////
  488. //
  489. // RENDERING
  490. //
  491. STBVXDEC char *stbvox_get_vertex_shader(void);
  492. // Returns the (currently GLSL-only) vertex shader.
  493. STBVXDEC char *stbvox_get_fragment_shader(void);
  494. // Returns the (currently GLSL-only) fragment shader.
  495. // You can override the lighting and fogging calculations
  496. // by appending data to the end of these; see the #define
  497. // documentation for more information.
  498. STBVXDEC char *stbvox_get_fragment_shader_alpha_only(void);
  499. // Returns a slightly cheaper fragment shader that computes
  500. // alpha but not color. This is useful for e.g. a depth-only
  501. // pass when using alpha test.
  502. typedef struct stbvox_uniform_info stbvox_uniform_info;
  503. STBVXDEC int stbvox_get_uniform_info(stbvox_uniform_info *info, int uniform);
  504. // Gets the information about a uniform necessary for you to
  505. // set up each uniform with a minimal amount of explicit code.
  506. // See the sample code after the structure definition for stbvox_uniform_info,
  507. // further down in this header section.
  508. //
  509. // "uniform" is from the list immediately following. For many
  510. // of these, default values are provided which you can set.
  511. // Most values are shared for most draw calls; e.g. for stateful
  512. // APIs you can set most of the state only once. Only
  513. // STBVOX_UNIFORM_transform needs to change per draw call.
  514. //
  515. // STBVOX_UNIFORM_texscale
  516. // 64- or 128-long vec4 array. (128 only if STBVOX_CONFIG_PREFER_TEXBUFFER)
  517. // x: scale factor to apply to texture #1. must be a power of two. 1.0 means 'face-sized'
  518. // y: scale factor to apply to texture #2. must be a power of two. 1.0 means 'face-sized'
  519. // z: blend mode indexed by texture #2. 0.0 is alpha compositing; 1.0 is multiplication.
  520. // w: unused currently. @TODO use to support texture animation?
  521. //
  522. // Texscale is indexed by the bottom 6 or 7 bits of the texture id; thus for
  523. // example the texture at index 0 in the array and the texture in index 128 of
  524. // the array must be scaled the same. This means that if you only have 64 or 128
  525. // unique textures, they all get distinct values anyway; otherwise you have
  526. // to group them in pairs or sets of four.
  527. //
  528. // STBVOX_UNIFORM_ambient
  529. // 4-long vec4 array:
  530. // ambient[0].xyz - negative of direction of a directional light for half-lambert
  531. // ambient[1].rgb - color of light scaled by NdotL (can be negative)
  532. // ambient[2].rgb - constant light added to above calculation;
  533. // effectively light ranges from ambient[2]-ambient[1] to ambient[2]+ambient[1]
  534. // ambient[3].rgb - fog color for STBVOX_CONFIG_FOG_SMOOTHSTEP
  535. // ambient[3].a - reciprocal of squared distance of farthest fog point (viewing distance)
  536. // +----- has a default value
  537. // | +-- you should always use the default value
  538. enum // V V
  539. { // ------------------------------------------------
  540. STBVOX_UNIFORM_face_data, // n the sampler with the face texture buffer
  541. STBVOX_UNIFORM_transform, // n the transform data from stbvox_get_transform
  542. STBVOX_UNIFORM_tex_array, // n an array of two texture samplers containing the two texture arrays
  543. STBVOX_UNIFORM_texscale, // Y a table of texture properties, see above
  544. STBVOX_UNIFORM_color_table, // Y 64 vec4 RGBA values; a default palette is provided; if A > 1.0, fullbright
  545. STBVOX_UNIFORM_normals, // Y Y table of normals, internal-only
  546. STBVOX_UNIFORM_texgen, // Y Y table of texgen vectors, internal-only
  547. STBVOX_UNIFORM_ambient, // n lighting & fog info, see above
  548. STBVOX_UNIFORM_camera_pos, // Y camera position in global voxel space (for lighting & fog)
  549. STBVOX_UNIFORM_count,
  550. };
  551. enum
  552. {
  553. STBVOX_UNIFORM_TYPE_none,
  554. STBVOX_UNIFORM_TYPE_sampler,
  555. STBVOX_UNIFORM_TYPE_vec2,
  556. STBVOX_UNIFORM_TYPE_vec3,
  557. STBVOX_UNIFORM_TYPE_vec4,
  558. };
  559. struct stbvox_uniform_info
  560. {
  561. int type; // which type of uniform
  562. int bytes_per_element; // the size of each uniform array element (e.g. vec3 = 12 bytes)
  563. int array_length; // length of the uniform array
  564. char *name; // name in the shader @TODO use numeric binding
  565. float *default_value; // if not NULL, you can use this as the uniform pointer
  566. int use_tex_buffer; // if true, then the uniform is a sampler but the data can come from default_value
  567. };
  568. //////////////////////////////////////////////////////////////////////////////
  569. //
  570. // Uniform sample code
  571. //
  572. #if 0
  573. // Run this once per frame before drawing all the meshes.
  574. // You still need to separately set the 'transform' uniform for every mesh.
  575. void setup_uniforms(GLuint shader, float camera_pos[4], GLuint tex1, GLuint tex2)
  576. {
  577. int i;
  578. glUseProgram(shader); // so uniform binding works
  579. for (i=0; i < STBVOX_UNIFORM_count; ++i) {
  580. stbvox_uniform_info sui;
  581. if (stbvox_get_uniform_info(&sui, i)) {
  582. GLint loc = glGetUniformLocation(shader, sui.name);
  583. if (loc != -1) {
  584. switch (i) {
  585. case STBVOX_UNIFORM_camera_pos: // only needed for fog
  586. glUniform4fv(loc, sui.array_length, camera_pos);
  587. break;
  588. case STBVOX_UNIFORM_tex_array: {
  589. GLuint tex_unit[2] = { 0, 1 }; // your choice of samplers
  590. glUniform1iv(loc, 2, tex_unit);
  591. glActiveTexture(GL_TEXTURE0 + tex_unit[0]); glBindTexture(GL_TEXTURE_2D_ARRAY, tex1);
  592. glActiveTexture(GL_TEXTURE0 + tex_unit[1]); glBindTexture(GL_TEXTURE_2D_ARRAY, tex2);
  593. glActiveTexture(GL_TEXTURE0); // reset to default
  594. break;
  595. }
  596. case STBVOX_UNIFORM_face_data:
  597. glUniform1i(loc, SAMPLER_YOU_WILL_BIND_PER_MESH_FACE_DATA_TO);
  598. break;
  599. case STBVOX_UNIFORM_ambient: // you definitely want to override this
  600. case STBVOX_UNIFORM_color_table: // you might want to override this
  601. case STBVOX_UNIFORM_texscale: // you may want to override this
  602. glUniform4fv(loc, sui.array_length, sui.default_value);
  603. break;
  604. case STBVOX_UNIFORM_normals: // you never want to override this
  605. case STBVOX_UNIFORM_texgen: // you never want to override this
  606. glUniform3fv(loc, sui.array_length, sui.default_value);
  607. break;
  608. }
  609. }
  610. }
  611. }
  612. }
  613. #endif
  614. #ifdef __cplusplus
  615. }
  616. #endif
  617. //////////////////////////////////////////////////////////////////////////////
  618. //
  619. // INPUT TO MESHING
  620. //
  621. // Shapes of blocks that aren't always cubes
  622. enum
  623. {
  624. STBVOX_GEOM_empty,
  625. STBVOX_GEOM_knockout, // creates a hole in the mesh
  626. STBVOX_GEOM_solid,
  627. STBVOX_GEOM_transp, // solid geometry, but transparent contents so neighbors generate normally, unless same blocktype
  628. // following 4 can be represented by vheight as well
  629. STBVOX_GEOM_slab_upper,
  630. STBVOX_GEOM_slab_lower,
  631. STBVOX_GEOM_floor_slope_north_is_top,
  632. STBVOX_GEOM_ceil_slope_north_is_bottom,
  633. STBVOX_GEOM_floor_slope_north_is_top_as_wall_UNIMPLEMENTED, // same as floor_slope above, but uses wall's texture & texture projection
  634. STBVOX_GEOM_ceil_slope_north_is_bottom_as_wall_UNIMPLEMENTED,
  635. STBVOX_GEOM_crossed_pair, // corner-to-corner pairs, with normal vector bumped upwards
  636. STBVOX_GEOM_force, // like GEOM_transp, but faces visible even if neighbor is same type, e.g. minecraft fancy leaves
  637. // these access vheight input
  638. STBVOX_GEOM_floor_vheight_03 = 12, // diagonal is SW-NE
  639. STBVOX_GEOM_floor_vheight_12, // diagonal is SE-NW
  640. STBVOX_GEOM_ceil_vheight_03,
  641. STBVOX_GEOM_ceil_vheight_12,
  642. STBVOX_GEOM_count, // number of geom cases
  643. };
  644. enum
  645. {
  646. STBVOX_FACE_east,
  647. STBVOX_FACE_north,
  648. STBVOX_FACE_west,
  649. STBVOX_FACE_south,
  650. STBVOX_FACE_up,
  651. STBVOX_FACE_down,
  652. STBVOX_FACE_count,
  653. };
  654. #ifdef STBVOX_CONFIG_BLOCKTYPE_SHORT
  655. typedef unsigned short stbvox_block_type;
  656. #else
  657. typedef unsigned char stbvox_block_type;
  658. #endif
  659. // 24-bit color
  660. typedef struct
  661. {
  662. unsigned char r,g,b;
  663. } stbvox_rgb;
  664. #define STBVOX_COLOR_TEX1_ENABLE 64
  665. #define STBVOX_COLOR_TEX2_ENABLE 128
  666. // This is the data structure you fill out. Most of the arrays can be
  667. // NULL, except when one is required to get the value to index another.
  668. //
  669. // The compass system used in the following descriptions is:
  670. // east means increasing x
  671. // north means increasing y
  672. // up means increasing z
  673. struct stbvox_input_description
  674. {
  675. unsigned char lighting_at_vertices;
  676. // The default is lighting values (i.e. ambient occlusion) are at block
  677. // center, and the vertex light is gathered from those adjacent block
  678. // centers that the vertex is facing. This makes smooth lighting
  679. // consistent across adjacent faces with the same orientation.
  680. //
  681. // Setting this flag to non-zero gives you explicit control
  682. // of light at each vertex, but now the lighting/ao will be
  683. // shared by all vertices at the same point, even if they
  684. // have different normals.
  685. // these are mostly 3D maps you use to define your voxel world, using x_stride and y_stride
  686. // note that for cache efficiency, you want to use the block_foo palettes as much as possible instead
  687. stbvox_rgb *rgb;
  688. // Indexed by 3D coordinate.
  689. // 24-bit voxel color for STBVOX_CONFIG_MODE = 20 or 21 only
  690. unsigned char *lighting;
  691. // Indexed by 3D coordinate. The lighting value / ambient occlusion
  692. // value that is used to define the vertex lighting values.
  693. // The raw lighting values are defined at the center of blocks
  694. // (or at vertex if 'lighting_at_vertices' is true).
  695. //
  696. // If the macro STBVOX_CONFIG_ROTATION_IN_LIGHTING is defined,
  697. // then an additional 2-bit block rotation value is stored
  698. // in this field as well.
  699. //
  700. // Encode with STBVOX_MAKE_LIGHTING_EXT(lighting,rot)--here
  701. // 'lighting' should still be 8 bits, as the macro will
  702. // discard the bottom bits automatically. Similarly, if
  703. // using STBVOX_CONFIG_VHEIGHT_IN_LIGHTING, encode with
  704. // STBVOX_MAKE_LIGHTING_EXT(lighting,vheight).
  705. //
  706. // (Rationale: rotation needs to be independent of blocktype,
  707. // but is only 2 bits so doesn't want to be its own array.
  708. // Lighting is the one thing that was likely to already be
  709. // in use and that I could easily steal 2 bits from.)
  710. stbvox_block_type *blocktype;
  711. // Indexed by 3D coordinate. This is a core "block type" value, which is used
  712. // to index into other arrays; essentially a "palette". This is much more
  713. // memory-efficient and performance-friendly than storing the values explicitly,
  714. // but only makes sense if the values are always synchronized.
  715. //
  716. // If a voxel's blocktype is 0, it is assumed to be empty (STBVOX_GEOM_empty),
  717. // and no other blocktypes should be STBVOX_GEOM_empty. (Only if you do not
  718. // have blocktypes should STBVOX_GEOM_empty ever used.)
  719. //
  720. // Normally it is an unsigned byte, but you can override it to be
  721. // a short if you have too many blocktypes.
  722. unsigned char *geometry;
  723. // Indexed by 3D coordinate. Contains the geometry type for the block.
  724. // Also contains a 2-bit rotation for how the whole block is rotated.
  725. // Also includes a 2-bit vheight value when using shared vheight values.
  726. // See the separate vheight documentation.
  727. // Encode with STBVOX_MAKE_GEOMETRY(geom, rot, vheight)
  728. unsigned char *block_geometry;
  729. // Array indexed by blocktype containing the geometry for this block, plus
  730. // a 2-bit "simple rotation". Note rotation has limited use since it's not
  731. // independent of blocktype.
  732. //
  733. // Encode with STBVOX_MAKE_GEOMETRY(geom,simple_rot,0)
  734. unsigned char *block_tex1;
  735. // Array indexed by blocktype containing the texture id for texture #1.
  736. unsigned char (*block_tex1_face)[6];
  737. // Array indexed by blocktype and face containing the texture id for texture #1.
  738. // The N/E/S/W face choices can be rotated by one of the rotation selectors;
  739. // The top & bottom face textures will rotate to match.
  740. // Note that it only makes sense to use one of block_tex1 or block_tex1_face;
  741. // this pattern repeats throughout and this notice is not repeated.
  742. unsigned char *tex2;
  743. // Indexed by 3D coordinate. Contains the texture id for texture #2
  744. // to use on all faces of the block.
  745. unsigned char *block_tex2;
  746. // Array indexed by blocktype containing the texture id for texture #2.
  747. unsigned char (*block_tex2_face)[6];
  748. // Array indexed by blocktype and face containing the texture id for texture #2.
  749. // The N/E/S/W face choices can be rotated by one of the rotation selectors;
  750. // The top & bottom face textures will rotate to match.
  751. unsigned char *color;
  752. // Indexed by 3D coordinate. Contains the color for all faces of the block.
  753. // The core color value is 0..63.
  754. // Encode with STBVOX_MAKE_COLOR(color_number, tex1_enable, tex2_enable)
  755. unsigned char *block_color;
  756. // Array indexed by blocktype containing the color value to apply to the faces.
  757. // The core color value is 0..63.
  758. // Encode with STBVOX_MAKE_COLOR(color_number, tex1_enable, tex2_enable)
  759. unsigned char (*block_color_face)[6];
  760. // Array indexed by blocktype and face containing the color value to apply to that face.
  761. // The core color value is 0..63.
  762. // Encode with STBVOX_MAKE_COLOR(color_number, tex1_enable, tex2_enable)
  763. unsigned char *block_texlerp;
  764. // Array indexed by blocktype containing 3-bit scalar for texture #2 alpha
  765. // (known throughout as 'texlerp'). This is constant over every face even
  766. // though the property is potentially per-vertex.
  767. unsigned char (*block_texlerp_face)[6];
  768. // Array indexed by blocktype and face containing 3-bit scalar for texture #2 alpha.
  769. // This is constant over the face even though the property is potentially per-vertex.
  770. unsigned char *block_vheight;
  771. // Array indexed by blocktype containing the vheight values for the
  772. // top or bottom face of this block. These will rotate properly if the
  773. // block is rotated. See discussion of vheight.
  774. // Encode with STBVOX_MAKE_VHEIGHT(sw_height, se_height, nw_height, ne_height)
  775. unsigned char *selector;
  776. // Array indexed by 3D coordinates indicating which output mesh to select.
  777. unsigned char *block_selector;
  778. // Array indexed by blocktype indicating which output mesh to select.
  779. unsigned char *side_texrot;
  780. // Array indexed by 3D coordinates encoding 2-bit texture rotations for the
  781. // faces on the E/N/W/S sides of the block.
  782. // Encode with STBVOX_MAKE_SIDE_TEXROT(rot_e, rot_n, rot_w, rot_s)
  783. unsigned char *block_side_texrot;
  784. // Array indexed by blocktype encoding 2-bit texture rotations for the faces
  785. // on the E/N/W/S sides of the block.
  786. // Encode with STBVOX_MAKE_SIDE_TEXROT(rot_e, rot_n, rot_w, rot_s)
  787. unsigned char *overlay; // index into palettes listed below
  788. // Indexed by 3D coordinate. If 0, there is no overlay. If non-zero,
  789. // it indexes into to the below arrays and overrides the values
  790. // defined by the blocktype.
  791. unsigned char (*overlay_tex1)[6];
  792. // Array indexed by overlay value and face, containing an override value
  793. // for the texture id for texture #1. If 0, the value defined by blocktype
  794. // is used.
  795. unsigned char (*overlay_tex2)[6];
  796. // Array indexed by overlay value and face, containing an override value
  797. // for the texture id for texture #2. If 0, the value defined by blocktype
  798. // is used.
  799. unsigned char (*overlay_color)[6];
  800. // Array indexed by overlay value and face, containing an override value
  801. // for the face color. If 0, the value defined by blocktype is used.
  802. unsigned char *overlay_side_texrot;
  803. // Array indexed by overlay value, encoding 2-bit texture rotations for the faces
  804. // on the E/N/W/S sides of the block.
  805. // Encode with STBVOX_MAKE_SIDE_TEXROT(rot_e, rot_n, rot_w, rot_s)
  806. unsigned char *rotate;
  807. // Indexed by 3D coordinate. Allows independent rotation of several
  808. // parts of the voxel, where by rotation I mean swapping textures
  809. // and colors between E/N/S/W faces.
  810. // Block: rotates anything indexed by blocktype
  811. // Overlay: rotates anything indexed by overlay
  812. // EColor: rotates faces defined in ecolor_facemask
  813. // Encode with STBVOX_MAKE_MATROT(block,overlay,ecolor)
  814. unsigned char *tex2_for_tex1;
  815. // Array indexed by tex1 containing the texture id for texture #2.
  816. // You can use this if the two are always/almost-always strictly
  817. // correlated (e.g. if tex2 is a detail texture for tex1), as it
  818. // will be more efficient (touching fewer cache lines) than using
  819. // e.g. block_tex2_face.
  820. unsigned char *tex2_replace;
  821. // Indexed by 3D coordinate. Specifies the texture id for texture #2
  822. // to use on a single face of the voxel, which must be E/N/W/S (not U/D).
  823. // The texture id is limited to 6 bits unless tex2_facemask is also
  824. // defined (see below).
  825. // Encode with STBVOX_MAKE_TEX2_REPLACE(tex2, face)
  826. unsigned char *tex2_facemask;
  827. // Indexed by 3D coordinate. Specifies which of the six faces should
  828. // have their tex2 replaced by the value of tex2_replace. In this
  829. // case, all 8 bits of tex2_replace are used as the texture id.
  830. // Encode with STBVOX_MAKE_FACE_MASK(east,north,west,south,up,down)
  831. unsigned char *extended_color;
  832. // Indexed by 3D coordinate. Specifies a value that indexes into
  833. // the ecolor arrays below (both of which must be defined).
  834. unsigned char *ecolor_color;
  835. // Indexed by extended_color value, specifies an optional override
  836. // for the color value on some faces.
  837. // Encode with STBVOX_MAKE_COLOR(color_number, tex1_enable, tex2_enable)
  838. unsigned char *ecolor_facemask;
  839. // Indexed by extended_color value, this specifies which faces the
  840. // color in ecolor_color should be applied to. The faces can be
  841. // independently rotated by the ecolor value of 'rotate', if it exists.
  842. // Encode with STBVOX_MAKE_FACE_MASK(e,n,w,s,u,d)
  843. unsigned char *color2;
  844. // Indexed by 3D coordinates, specifies an alternative color to apply
  845. // to some of the faces of the block.
  846. // Encode with STBVOX_MAKE_COLOR(color_number, tex1_enable, tex2_enable)
  847. unsigned char *color2_facemask;
  848. // Indexed by 3D coordinates, specifies which faces should use the
  849. // color defined in color2. No rotation value is applied.
  850. // Encode with STBVOX_MAKE_FACE_MASK(e,n,w,s,u,d)
  851. unsigned char *color3;
  852. // Indexed by 3D coordinates, specifies an alternative color to apply
  853. // to some of the faces of the block.
  854. // Encode with STBVOX_MAKE_COLOR(color_number, tex1_enable, tex2_enable)
  855. unsigned char *color3_facemask;
  856. // Indexed by 3D coordinates, specifies which faces should use the
  857. // color defined in color3. No rotation value is applied.
  858. // Encode with STBVOX_MAKE_FACE_MASK(e,n,w,s,u,d)
  859. unsigned char *texlerp_simple;
  860. // Indexed by 3D coordinates, this is the smallest texlerp encoding
  861. // that can do useful work. It consits of three values: baselerp,
  862. // vertlerp, and face_vertlerp. Baselerp defines the value
  863. // to use on all of the faces but one, from the STBVOX_TEXLERP_BASE
  864. // values. face_vertlerp is one of the 6 face values (or STBVOX_FACE_NONE)
  865. // which specifies the face should use the vertlerp values.
  866. // Vertlerp defines a lerp value at every vertex of the mesh.
  867. // Thus, one face can have per-vertex texlerp values, and those
  868. // values are encoded in the space so that they will be shared
  869. // by adjacent faces that also use vertlerp, allowing continuity
  870. // (this is used for the "texture crossfade" bit of the release video).
  871. // Encode with STBVOX_MAKE_TEXLERP_SIMPLE(baselerp, vertlerp, face_vertlerp)
  872. // The following texlerp encodings are experimental and maybe not
  873. // that useful.
  874. unsigned char *texlerp;
  875. // Indexed by 3D coordinates, this defines four values:
  876. // vertlerp is a lerp value at every vertex of the mesh (using STBVOX_TEXLERP_BASE values).
  877. // ud is the value to use on up and down faces, from STBVOX_TEXLERP_FACE values
  878. // ew is the value to use on east and west faces, from STBVOX_TEXLERP_FACE values
  879. // ns is the value to use on north and south faces, from STBVOX_TEXLERP_FACE values
  880. // If any of ud, ew, or ns is STBVOX_TEXLERP_FACE_use_vert, then the
  881. // vertlerp values for the vertices are gathered and used for those faces.
  882. // Encode with STBVOX_MAKE_TEXLERP(vertlerp,ud,ew,sw)
  883. unsigned short *texlerp_vert3;
  884. // Indexed by 3D coordinates, this works with texlerp and
  885. // provides a unique texlerp value for every direction at
  886. // every vertex. The same rules of whether faces share values
  887. // applies. The STBVOX_TEXLERP_FACE vertlerp value defined in
  888. // texlerp is only used for the down direction. The values at
  889. // each vertex in other directions are defined in this array,
  890. // and each uses the STBVOX_TEXLERP3 values (i.e. full precision
  891. // 3-bit texlerp values).
  892. // Encode with STBVOX_MAKE_VERT3(vertlerp_e,vertlerp_n,vertlerp_w,vertlerp_s,vertlerp_u)
  893. unsigned short *texlerp_face3; // e:3,n:3,w:3,s:3,u:2,d:2
  894. // Indexed by 3D coordinates, this provides a compact way to
  895. // fully specify the texlerp value indepenendly for every face,
  896. // but doesn't allow per-vertex variation. E/N/W/S values are
  897. // encoded using STBVOX_TEXLERP3 values, whereas up and down
  898. // use STBVOX_TEXLERP_SIMPLE values.
  899. // Encode with STBVOX_MAKE_FACE3(face_e,face_n,face_w,face_s,face_u,face_d)
  900. unsigned char *vheight; // STBVOX_MAKE_VHEIGHT -- sw:2, se:2, nw:2, ne:2, doesn't rotate
  901. // Indexed by 3D coordinates, this defines the four
  902. // vheight values to use if the geometry is STBVOX_GEOM_vheight*.
  903. // See the vheight discussion.
  904. unsigned char *packed_compact;
  905. // Stores block rotation, vheight, and texlerp values:
  906. // block rotation: 2 bits
  907. // vertex vheight: 2 bits
  908. // use_texlerp : 1 bit
  909. // vertex texlerp: 3 bits
  910. // If STBVOX_CONFIG_UP_TEXLERP_PACKED is defined, then 'vertex texlerp' is
  911. // used for up faces if use_texlerp is 1. If STBVOX_CONFIG_DOWN_TEXLERP_PACKED
  912. // is defined, then 'vertex texlerp' is used for down faces if use_texlerp is 1.
  913. // Note if those symbols are defined but packed_compact is NULL, the normal
  914. // texlerp default will be used.
  915. // Encode with STBVOX_MAKE_PACKED_COMPACT(rot, vheight, texlerp, use_texlerp)
  916. };
  917. // @OPTIMIZE allow specializing; build a single struct with all of the
  918. // 3D-indexed arrays combined so it's AoS instead of SoA for better
  919. // cache efficiency
  920. //////////////////////////////////////////////////////////////////////////////
  921. //
  922. // VHEIGHT DOCUMENTATION
  923. //
  924. // "vheight" is the internal name for the special block types
  925. // with sloped tops or bottoms. "vheight" stands for "vertex height".
  926. //
  927. // Note that these blocks are very flexible (there are 256 of them,
  928. // although at least 17 of them should never be used), but they
  929. // also have a disadvantage that they generate extra invisible
  930. // faces; the generator does not currently detect whether adjacent
  931. // vheight blocks hide each others sides, so those side faces are
  932. // always generated. For a continuous ground terrain, this means
  933. // that you may generate 5x as many quads as needed. See notes
  934. // on "improvements for shipping products" in the introduction.
  935. enum
  936. {
  937. STBVOX_VERTEX_HEIGHT_0,
  938. STBVOX_VERTEX_HEIGHT_half,
  939. STBVOX_VERTEX_HEIGHT_1,
  940. STBVOX_VERTEX_HEIGHT_one_and_a_half,
  941. };
  942. // These are the "vheight" values. Vheight stands for "vertex height".
  943. // The idea is that for a "floor vheight" block, you take a cube and
  944. // reposition the top-most vertices at various heights as specified by
  945. // the vheight values. Similarly, a "ceiling vheight" block takes a
  946. // cube and repositions the bottom-most vertices.
  947. //
  948. // A floor block only adjusts the top four vertices; the bottom four vertices
  949. // remain at the bottom of the block. The height values are 2 bits,
  950. // measured in halves of a block; so you can specify heights of 0/2,
  951. // 1/2, 2/2, or 3/2. 0 is the bottom of the block, 1 is halfway
  952. // up the block, 2 is the top of the block, and 3 is halfway up the
  953. // next block (and actually outside of the block). The value 3 is
  954. // actually legal for floor vheight (but not ceiling), and allows you to:
  955. //
  956. // (A) have smoother terrain by having slopes that cross blocks,
  957. // e.g. (1,1,3,3) is a regular-seeming slope halfway between blocks
  958. // (B) make slopes steeper than 45-degrees, e.g. (0,0,3,3)
  959. //
  960. // (Because only z coordinates have half-block precision, and x&y are
  961. // limited to block corner precision, it's not possible to make these
  962. // things "properly" out of blocks, e.g. a half-slope block on its side
  963. // or a sloped block halfway between blocks that's made out of two blocks.)
  964. //
  965. // If you define STBVOX_CONFIG_OPTIMIZED_VHEIGHT, then the top face
  966. // (or bottom face for a ceiling vheight block) will be drawn as a
  967. // single quad even if the four vertex heights aren't planar, and a
  968. // single normal will be used over the entire quad. If you
  969. // don't define it, then if the top face is non-planar, it will be
  970. // split into two triangles, each with their own normal/lighting.
  971. // (Note that since all output from stb_voxel_render is quad meshes,
  972. // triangles are actually rendered as degenerate quads.) In this case,
  973. // the distinction between STBVOX_GEOM_floor_vheight_03 and
  974. // STBVOX_GEOM_floor_vheight_12 comes into play; the former introduces
  975. // an edge from the SW to NE corner (i.e. from <0,0,?> to <1,1,?>),
  976. // while the latter introduces an edge from the NW to SE corner
  977. // (i.e. from <0,1,?> to <1,0,?>.) For a "lazy mesh" look, use
  978. // exclusively _03 or _12. For a "classic mesh" look, alternate
  979. // _03 and _12 in a checkerboard pattern. For a "smoothest surface"
  980. // look, choose the edge based on actual vertex heights.
  981. //
  982. // The four vertex heights can come from several places. The simplest
  983. // encoding is to just use the 'vheight' parameter which stores four
  984. // explicit vertex heights for every block. This allows total independence,
  985. // but at the cost of the largest memory usage, 1 byte per 3D block.
  986. // Encode this with STBVOX_MAKE_VHEIGHT(vh_sw, vh_se, vh_nw, vh_ne).
  987. // These coordinates are absolute, not affected by block rotations.
  988. //
  989. // An alternative if you just want to encode some very specific block
  990. // types, not all the possibilities--say you just want half-height slopes,
  991. // so you want (0,0,1,1) and (1,1,2,2)--then you can use block_vheight
  992. // to specify them. The geometry rotation will cause block_vheight values
  993. // to be rotated (because it's as if you're just defining a type of
  994. // block). This value is also encoded with STBVOX_MAKE_VHEIGHT.
  995. //
  996. // If you want to save memory and you're creating a "continuous ground"
  997. // sort of effect, you can make each vertex of the lattice share the
  998. // vheight value; that is, two adjacent blocks that share a vertex will
  999. // always get the same vheight value for that vertex. Then you need to
  1000. // store two bits of vheight for every block, which you do by storing it
  1001. // as part another data structure. Store the south-west vertex's vheight
  1002. // with the block. You can either use the "geometry" mesh variable (it's
  1003. // a parameter to STBVOX_MAKE_GEOMETRY) or you can store it in the
  1004. // "lighting" mesh variable if you defined STBVOX_CONFIG_VHEIGHT_IN_LIGHTING,
  1005. // using STBVOX_MAKE_LIGHTING_EXT(lighting,vheight).
  1006. //
  1007. // Note that if you start with a 2D height map and generate vheight data from
  1008. // it, you don't necessarily store only one value per (x,y) coordinate,
  1009. // as the same value may need to be set up at multiple z heights. For
  1010. // example, if height(8,8) = 13.5, then you want the block at (8,8,13)
  1011. // to store STBVOX_VERTEX_HEIGHT_half, and this will be used by blocks
  1012. // at (7,7,13), (8,7,13), (7,8,13), and (8,8,13). However, if you're
  1013. // allowing steep slopes, it might be the case that you have a block
  1014. // at (7,7,12) which is supposed to stick up to 13.5; that means
  1015. // you also need to store STBVOX_VERTEX_HEIGHT_one_and_a_half at (8,8,12).
  1016. enum
  1017. {
  1018. STBVOX_TEXLERP_FACE_0,
  1019. STBVOX_TEXLERP_FACE_half,
  1020. STBVOX_TEXLERP_FACE_1,
  1021. STBVOX_TEXLERP_FACE_use_vert,
  1022. };
  1023. enum
  1024. {
  1025. STBVOX_TEXLERP_BASE_0, // 0.0
  1026. STBVOX_TEXLERP_BASE_2_7, // 2/7
  1027. STBVOX_TEXLERP_BASE_5_7, // 4/7
  1028. STBVOX_TEXLERP_BASE_1 // 1.0
  1029. };
  1030. enum
  1031. {
  1032. STBVOX_TEXLERP3_0_8,
  1033. STBVOX_TEXLERP3_1_8,
  1034. STBVOX_TEXLERP3_2_8,
  1035. STBVOX_TEXLERP3_3_8,
  1036. STBVOX_TEXLERP3_4_8,
  1037. STBVOX_TEXLERP3_5_8,
  1038. STBVOX_TEXLERP3_6_8,
  1039. STBVOX_TEXLERP3_7_8,
  1040. };
  1041. #define STBVOX_FACE_NONE 7
  1042. #define STBVOX_BLOCKTYPE_EMPTY 0
  1043. #ifdef STBVOX_BLOCKTYPE_SHORT
  1044. #define STBVOX_BLOCKTYPE_HOLE 65535
  1045. #else
  1046. #define STBVOX_BLOCKTYPE_HOLE 255
  1047. #endif
  1048. #define STBVOX_MAKE_GEOMETRY(geom, rotate, vheight) ((geom) + (rotate)*16 + (vheight)*64)
  1049. #define STBVOX_MAKE_VHEIGHT(v_sw, v_se, v_nw, v_ne) ((v_sw) + (v_se)*4 + (v_nw)*16 + (v_ne)*64)
  1050. #define STBVOX_MAKE_MATROT(block, overlay, color) ((block) + (overlay)*4 + (color)*64)
  1051. #define STBVOX_MAKE_TEX2_REPLACE(tex2, tex2_replace_face) ((tex2) + ((tex2_replace_face) & 3)*64)
  1052. #define STBVOX_MAKE_TEXLERP(ns2, ew2, ud2, vert) ((ew2) + (ns2)*4 + (ud2)*16 + (vert)*64)
  1053. #define STBVOX_MAKE_TEXLERP_SIMPLE(baselerp,vert,face) ((vert)*32 + (face)*4 + (baselerp))
  1054. #define STBVOX_MAKE_TEXLERP1(vert,e2,n2,w2,s2,u4,d2) STBVOX_MAKE_TEXLERP(s2, w2, d2, vert)
  1055. #define STBVOX_MAKE_TEXLERP2(vert,e2,n2,w2,s2,u4,d2) ((u2)*16 + (n2)*4 + (s2))
  1056. #define STBVOX_MAKE_FACE_MASK(e,n,w,s,u,d) ((e)+(n)*2+(w)*4+(s)*8+(u)*16+(d)*32)
  1057. #define STBVOX_MAKE_SIDE_TEXROT(e,n,w,s) ((e)+(n)*4+(w)*16+(s)*64)
  1058. #define STBVOX_MAKE_COLOR(color,t1,t2) ((color)+(t1)*64+(t2)*128)
  1059. #define STBVOX_MAKE_TEXLERP_VERT3(e,n,w,s,u) ((e)+(n)*8+(w)*64+(s)*512+(u)*4096)
  1060. #define STBVOX_MAKE_TEXLERP_FACE3(e,n,w,s,u,d) ((e)+(n)*8+(w)*64+(s)*512+(u)*4096+(d)*16384)
  1061. #define STBVOX_MAKE_PACKED_COMPACT(rot, vheight, texlerp, def) ((rot)+4*(vheight)+16*(use)+32*(texlerp))
  1062. #define STBVOX_MAKE_LIGHTING_EXT(lighting, rot) (((lighting)&~3)+(rot))
  1063. #define STBVOX_MAKE_LIGHTING(lighting) (lighting)
  1064. #ifndef STBVOX_MAX_MESHES
  1065. #define STBVOX_MAX_MESHES 2 // opaque & transparent
  1066. #endif
  1067. #define STBVOX_MAX_MESH_SLOTS 3 // one vertex & two faces, or two vertex and one face
  1068. // don't mess with this directly, it's just here so you can
  1069. // declare stbvox_mesh_maker on the stack or as a global
  1070. struct stbvox_mesh_maker
  1071. {
  1072. stbvox_input_description input;
  1073. int cur_x, cur_y, cur_z; // last unprocessed voxel if it splits into multiple buffers
  1074. int x0,y0,z0,x1,y1,z1;
  1075. int x_stride_in_bytes;
  1076. int y_stride_in_bytes;
  1077. int config_dirty;
  1078. int default_mesh;
  1079. unsigned int tags;
  1080. int cube_vertex_offset[6][4]; // this allows access per-vertex data stored block-centered (like texlerp, ambient)
  1081. int vertex_gather_offset[6][4];
  1082. int pos_x,pos_y,pos_z;
  1083. int full;
  1084. // computed from user input
  1085. char *output_cur [STBVOX_MAX_MESHES][STBVOX_MAX_MESH_SLOTS];
  1086. char *output_end [STBVOX_MAX_MESHES][STBVOX_MAX_MESH_SLOTS];
  1087. char *output_buffer[STBVOX_MAX_MESHES][STBVOX_MAX_MESH_SLOTS];
  1088. int output_len [STBVOX_MAX_MESHES][STBVOX_MAX_MESH_SLOTS];
  1089. // computed from config
  1090. int output_size [STBVOX_MAX_MESHES][STBVOX_MAX_MESH_SLOTS]; // per quad
  1091. int output_step [STBVOX_MAX_MESHES][STBVOX_MAX_MESH_SLOTS]; // per vertex or per face, depending
  1092. int num_mesh_slots;
  1093. float default_tex_scale[128][2];
  1094. };
  1095. #endif // INCLUDE_STB_VOXEL_RENDER_H
  1096. #ifdef STB_VOXEL_RENDER_IMPLEMENTATION
  1097. #include <stdlib.h>
  1098. #include <assert.h>
  1099. #include <string.h> // memset
  1100. // have to use our own names to avoid the _MSC_VER path having conflicting type names
  1101. #ifndef _MSC_VER
  1102. #include <stdint.h>
  1103. typedef uint16_t stbvox_uint16;
  1104. typedef uint32_t stbvox_uint32;
  1105. #else
  1106. typedef unsigned short stbvox_uint16;
  1107. typedef unsigned int stbvox_uint32;
  1108. #endif
  1109. #ifdef _MSC_VER
  1110. #define STBVOX_NOTUSED(v) (void)(v)
  1111. #else
  1112. #define STBVOX_NOTUSED(v) (void)sizeof(v)
  1113. #endif
  1114. #ifndef STBVOX_CONFIG_MODE
  1115. #error "Must defined STBVOX_CONFIG_MODE to select the mode"
  1116. #endif
  1117. #if defined(STBVOX_CONFIG_ROTATION_IN_LIGHTING) && defined(STBVOX_CONFIG_VHEIGHT_IN_LIGHTING)
  1118. #error "Can't store both rotation and vheight in lighting"
  1119. #endif
  1120. // The following are candidate voxel modes. Only modes 0, 1, and 20, and 21 are
  1121. // currently implemented. Reducing the storage-per-quad further
  1122. // shouldn't improve performance, although obviously it allow you
  1123. // to create larger worlds without streaming.
  1124. //
  1125. //
  1126. // ----------- Two textures ----------- -- One texture -- ---- Color only ----
  1127. // Mode: 0 1 2 3 4 5 6 10 11 12 20 21 22 23 24
  1128. // ============================================================================================================
  1129. // uses Tex Buffer n Y Y Y Y Y Y Y Y Y n Y Y Y Y
  1130. // bytes per quad 32 20 14 12 10 6 6 8 8 4 32 20 10 6 4
  1131. // non-blocks all all some some some slabs stairs some some none all all slabs slabs none
  1132. // tex1 256 256 256 256 256 256 256 256 256 256 n n n n n
  1133. // tex2 256 256 256 256 256 256 128 n n n n n n n n
  1134. // colors 64 64 64 64 64 64 64 8 n n 2^24 2^24 2^24 2^24 256
  1135. // vertex ao Y Y Y Y Y n n Y Y n Y Y Y n n
  1136. // vertex texlerp Y Y Y n n n n - - - - - - - -
  1137. // x&y extents 127 127 128 64 64 128 64 64 128 128 127 127 128 128 128
  1138. // z extents 255 255 128 64? 64? 64 64 32 64 128 255 255 128 64 128
  1139. // not sure why I only wrote down the above "result data" and didn't preserve
  1140. // the vertex formats, but here I've tried to reconstruct the designs...
  1141. // mode # 3 is wrong, one byte too large, but they may have been an error originally
  1142. // Mode: 0 1 2 3 4 5 6 10 11 12 20 21 22 23 24
  1143. // =============================================================================================================
  1144. // bytes per quad 32 20 14 12 10 6 6 8 8 4 20 10 6 4
  1145. //
  1146. // vertex x bits 7 7 0 6 0 0 0 0 0 0 7 0 0 0
  1147. // vertex y bits 7 7 0 0 0 0 0 0 0 0 7 0 0 0
  1148. // vertex z bits 9 9 7 4 2 0 0 2 2 0 9 2 0 0
  1149. // vertex ao bits 6 6 6 6 6 0 0 6 6 0 6 6 0 0
  1150. // vertex txl bits 3 3 3 0 0 0 0 0 0 0 (3) 0 0 0
  1151. //
  1152. // face tex1 bits (8) 8 8 8 8 8 8 8 8 8
  1153. // face tex2 bits (8) 8 8 8 8 8 7 - - -
  1154. // face color bits (8) 8 8 8 8 8 8 3 0 0 24 24 24 8
  1155. // face normal bits (8) 8 8 8 6 4 7 4 4 3 8 3 4 3
  1156. // face x bits 7 0 6 7 6 6 7 7 0 7 7 7
  1157. // face y bits 7 6 6 7 6 6 7 7 0 7 7 7
  1158. // face z bits 2 2 6 6 6 5 6 7 0 7 6 7
  1159. #if STBVOX_CONFIG_MODE==0 || STBVOX_CONFIG_MODE==1
  1160. #define STBVOX_ICONFIG_VERTEX_32
  1161. #define STBVOX_ICONFIG_FACE1_1
  1162. #elif STBVOX_CONFIG_MODE==20 || STBVOX_CONFIG_MODE==21
  1163. #define STBVOX_ICONFIG_VERTEX_32
  1164. #define STBVOX_ICONFIG_FACE1_1
  1165. #define STBVOX_ICONFIG_UNTEXTURED
  1166. #else
  1167. #error "Selected value of STBVOX_CONFIG_MODE is not supported"
  1168. #endif
  1169. #if STBVOX_CONFIG_MODE==0 || STBVOX_CONFIG_MODE==20
  1170. #define STBVOX_ICONFIG_FACE_ATTRIBUTE
  1171. #endif
  1172. #ifndef STBVOX_CONFIG_HLSL
  1173. // the fallback if all others are exhausted is GLSL
  1174. #define STBVOX_ICONFIG_GLSL
  1175. #endif
  1176. #ifdef STBVOX_CONFIG_OPENGL_MODELVIEW
  1177. #define STBVOX_ICONFIG_OPENGL_3_1_COMPATIBILITY
  1178. #endif
  1179. #if defined(STBVOX_ICONFIG_VERTEX_32)
  1180. typedef stbvox_uint32 stbvox_mesh_vertex;
  1181. #define stbvox_vertex_encode(x,y,z,ao,texlerp) \
  1182. ((stbvox_uint32) ((x)+((y)<<7)+((z)<<14)+((ao)<<23)+((texlerp)<<29)))
  1183. #elif defined(STBVOX_ICONFIG_VERTEX_16_1) // mode=2
  1184. typedef stbvox_uint16 stbvox_mesh_vertex;
  1185. #define stbvox_vertex_encode(x,y,z,ao,texlerp) \
  1186. ((stbvox_uint16) ((z)+((ao)<<7)+((texlerp)<<13)
  1187. #elif defined(STBVOX_ICONFIG_VERTEX_16_2) // mode=3
  1188. typedef stbvox_uint16 stbvox_mesh_vertex;
  1189. #define stbvox_vertex_encode(x,y,z,ao,texlerp) \
  1190. ((stbvox_uint16) ((x)+((z)<<6))+((ao)<<10))
  1191. #elif defined(STBVOX_ICONFIG_VERTEX_8)
  1192. typedef stbvox_uint8 stbvox_mesh_vertex;
  1193. #define stbvox_vertex_encode(x,y,z,ao,texlerp) \
  1194. ((stbvox_uint8) ((z)+((ao)<<6))
  1195. #else
  1196. #error "internal error, no vertex type"
  1197. #endif
  1198. #ifdef STBVOX_ICONFIG_FACE1_1
  1199. typedef struct
  1200. {
  1201. unsigned char tex1,tex2,color,face_info;
  1202. } stbvox_mesh_face;
  1203. #else
  1204. #error "internal error, no face type"
  1205. #endif
  1206. // 20-byte quad format:
  1207. //
  1208. // per vertex:
  1209. //
  1210. // x:7
  1211. // y:7
  1212. // z:9
  1213. // ao:6
  1214. // tex_lerp:3
  1215. //
  1216. // per face:
  1217. //
  1218. // tex1:8
  1219. // tex2:8
  1220. // face:8
  1221. // color:8
  1222. // Faces:
  1223. //
  1224. // Faces use the bottom 3 bits to choose the texgen
  1225. // mode, and all the bits to choose the normal.
  1226. // Thus the bottom 3 bits have to be:
  1227. // e, n, w, s, u, d, u, d
  1228. //
  1229. // These use compact names so tables are readable
  1230. enum
  1231. {
  1232. STBVF_e,
  1233. STBVF_n,
  1234. STBVF_w,
  1235. STBVF_s,
  1236. STBVF_u,
  1237. STBVF_d,
  1238. STBVF_eu,
  1239. STBVF_ed,
  1240. STBVF_eu_wall,
  1241. STBVF_nu_wall,
  1242. STBVF_wu_wall,
  1243. STBVF_su_wall,
  1244. STBVF_ne_u,
  1245. STBVF_ne_d,
  1246. STBVF_nu,
  1247. STBVF_nd,
  1248. STBVF_ed_wall,
  1249. STBVF_nd_wall,
  1250. STBVF_wd_wall,
  1251. STBVF_sd_wall,
  1252. STBVF_nw_u,
  1253. STBVF_nw_d,
  1254. STBVF_wu,
  1255. STBVF_wd,
  1256. STBVF_ne_u_cross,
  1257. STBVF_nw_u_cross,
  1258. STBVF_sw_u_cross,
  1259. STBVF_se_u_cross,
  1260. STBVF_sw_u,
  1261. STBVF_sw_d,
  1262. STBVF_su,
  1263. STBVF_sd,
  1264. // @TODO we need more than 5 bits to encode the normal to fit the following
  1265. // so for now we use the right projection but the wrong normal
  1266. STBVF_se_u = STBVF_su,
  1267. STBVF_se_d = STBVF_sd,
  1268. STBVF_count,
  1269. };
  1270. /////////////////////////////////////////////////////////////////////////////
  1271. //
  1272. // tables -- i'd prefer if these were at the end of the file, but: C++
  1273. //
  1274. static float stbvox_default_texgen[2][32][3] =
  1275. {
  1276. { { 0, 1,0 }, { 0, 0, 1 }, { 0,-1,0 }, { 0, 0,-1 },
  1277. { -1, 0,0 }, { 0, 0, 1 }, { 1, 0,0 }, { 0, 0,-1 },
  1278. { 0,-1,0 }, { 0, 0, 1 }, { 0, 1,0 }, { 0, 0,-1 },
  1279. { 1, 0,0 }, { 0, 0, 1 }, { -1, 0,0 }, { 0, 0,-1 },
  1280. { 1, 0,0 }, { 0, 1, 0 }, { -1, 0,0 }, { 0,-1, 0 },
  1281. { -1, 0,0 }, { 0,-1, 0 }, { 1, 0,0 }, { 0, 1, 0 },
  1282. { 1, 0,0 }, { 0, 1, 0 }, { -1, 0,0 }, { 0,-1, 0 },
  1283. { -1, 0,0 }, { 0,-1, 0 }, { 1, 0,0 }, { 0, 1, 0 },
  1284. },
  1285. { { 0, 0,-1 }, { 0, 1,0 }, { 0, 0, 1 }, { 0,-1,0 },
  1286. { 0, 0,-1 }, { -1, 0,0 }, { 0, 0, 1 }, { 1, 0,0 },
  1287. { 0, 0,-1 }, { 0,-1,0 }, { 0, 0, 1 }, { 0, 1,0 },
  1288. { 0, 0,-1 }, { 1, 0,0 }, { 0, 0, 1 }, { -1, 0,0 },
  1289. { 0,-1, 0 }, { 1, 0,0 }, { 0, 1, 0 }, { -1, 0,0 },
  1290. { 0, 1, 0 }, { -1, 0,0 }, { 0,-1, 0 }, { 1, 0,0 },
  1291. { 0,-1, 0 }, { 1, 0,0 }, { 0, 1, 0 }, { -1, 0,0 },
  1292. { 0, 1, 0 }, { -1, 0,0 }, { 0,-1, 0 }, { 1, 0,0 },
  1293. },
  1294. };
  1295. #define STBVOX_RSQRT2 0.7071067811865f
  1296. #define STBVOX_RSQRT3 0.5773502691896f
  1297. static float stbvox_default_normals[32][3] =
  1298. {
  1299. { 1,0,0 }, // east
  1300. { 0,1,0 }, // north
  1301. { -1,0,0 }, // west
  1302. { 0,-1,0 }, // south
  1303. { 0,0,1 }, // up
  1304. { 0,0,-1 }, // down
  1305. { STBVOX_RSQRT2,0, STBVOX_RSQRT2 }, // east & up
  1306. { STBVOX_RSQRT2,0, -STBVOX_RSQRT2 }, // east & down
  1307. { STBVOX_RSQRT2,0, STBVOX_RSQRT2 }, // east & up
  1308. { 0, STBVOX_RSQRT2, STBVOX_RSQRT2 }, // north & up
  1309. { -STBVOX_RSQRT2,0, STBVOX_RSQRT2 }, // west & up
  1310. { 0,-STBVOX_RSQRT2, STBVOX_RSQRT2 }, // south & up
  1311. { STBVOX_RSQRT3, STBVOX_RSQRT3, STBVOX_RSQRT3 }, // ne & up
  1312. { STBVOX_RSQRT3, STBVOX_RSQRT3,-STBVOX_RSQRT3 }, // ne & down
  1313. { 0, STBVOX_RSQRT2, STBVOX_RSQRT2 }, // north & up
  1314. { 0, STBVOX_RSQRT2, -STBVOX_RSQRT2 }, // north & down
  1315. { STBVOX_RSQRT2,0, -STBVOX_RSQRT2 }, // east & down
  1316. { 0, STBVOX_RSQRT2, -STBVOX_RSQRT2 }, // north & down
  1317. { -STBVOX_RSQRT2,0, -STBVOX_RSQRT2 }, // west & down
  1318. { 0,-STBVOX_RSQRT2, -STBVOX_RSQRT2 }, // south & down
  1319. { -STBVOX_RSQRT3, STBVOX_RSQRT3, STBVOX_RSQRT3 }, // NW & up
  1320. { -STBVOX_RSQRT3, STBVOX_RSQRT3,-STBVOX_RSQRT3 }, // NW & down
  1321. { -STBVOX_RSQRT2,0, STBVOX_RSQRT2 }, // west & up
  1322. { -STBVOX_RSQRT2,0, -STBVOX_RSQRT2 }, // west & down
  1323. { STBVOX_RSQRT3, STBVOX_RSQRT3,STBVOX_RSQRT3 }, // NE & up crossed
  1324. { -STBVOX_RSQRT3, STBVOX_RSQRT3,STBVOX_RSQRT3 }, // NW & up crossed
  1325. { -STBVOX_RSQRT3,-STBVOX_RSQRT3,STBVOX_RSQRT3 }, // SW & up crossed
  1326. { STBVOX_RSQRT3,-STBVOX_RSQRT3,STBVOX_RSQRT3 }, // SE & up crossed
  1327. { -STBVOX_RSQRT3,-STBVOX_RSQRT3, STBVOX_RSQRT3 }, // SW & up
  1328. { -STBVOX_RSQRT3,-STBVOX_RSQRT3,-STBVOX_RSQRT3 }, // SW & up
  1329. { 0,-STBVOX_RSQRT2, STBVOX_RSQRT2 }, // south & up
  1330. { 0,-STBVOX_RSQRT2, -STBVOX_RSQRT2 }, // south & down
  1331. };
  1332. static float stbvox_default_texscale[128][4] =
  1333. {
  1334. {1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},
  1335. {1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},
  1336. {1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},
  1337. {1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},
  1338. {1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},
  1339. {1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},
  1340. {1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},
  1341. {1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},
  1342. {1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},
  1343. {1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},
  1344. {1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},
  1345. {1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},
  1346. {1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},
  1347. {1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},
  1348. {1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},
  1349. {1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},{1,1,0,0},
  1350. };
  1351. static unsigned char stbvox_default_palette_compact[64][3] =
  1352. {
  1353. { 255,255,255 }, { 238,238,238 }, { 221,221,221 }, { 204,204,204 },
  1354. { 187,187,187 }, { 170,170,170 }, { 153,153,153 }, { 136,136,136 },
  1355. { 119,119,119 }, { 102,102,102 }, { 85, 85, 85 }, { 68, 68, 68 },
  1356. { 51, 51, 51 }, { 34, 34, 34 }, { 17, 17, 17 }, { 0, 0, 0 },
  1357. { 255,240,240 }, { 255,220,220 }, { 255,160,160 }, { 255, 32, 32 },
  1358. { 200,120,160 }, { 200, 60,150 }, { 220,100,130 }, { 255, 0,128 },
  1359. { 240,240,255 }, { 220,220,255 }, { 160,160,255 }, { 32, 32,255 },
  1360. { 120,160,200 }, { 60,150,200 }, { 100,130,220 }, { 0,128,255 },
  1361. { 240,255,240 }, { 220,255,220 }, { 160,255,160 }, { 32,255, 32 },
  1362. { 160,200,120 }, { 150,200, 60 }, { 130,220,100 }, { 128,255, 0 },
  1363. { 255,255,240 }, { 255,255,220 }, { 220,220,180 }, { 255,255, 32 },
  1364. { 200,160,120 }, { 200,150, 60 }, { 220,130,100 }, { 255,128, 0 },
  1365. { 255,240,255 }, { 255,220,255 }, { 220,180,220 }, { 255, 32,255 },
  1366. { 160,120,200 }, { 150, 60,200 }, { 130,100,220 }, { 128, 0,255 },
  1367. { 240,255,255 }, { 220,255,255 }, { 180,220,220 }, { 32,255,255 },
  1368. { 120,200,160 }, { 60,200,150 }, { 100,220,130 }, { 0,255,128 },
  1369. };
  1370. static float stbvox_default_ambient[4][4] =
  1371. {
  1372. { 0,0,1 ,0 }, // reversed lighting direction
  1373. { 0.5,0.5,0.5,0 }, // directional color
  1374. { 0.5,0.5,0.5,0 }, // constant color
  1375. { 0.5,0.5,0.5,1.0f/1000.0f/1000.0f }, // fog data for simple_fog
  1376. };
  1377. static float stbvox_default_palette[64][4];
  1378. static void stbvox_build_default_palette(void)
  1379. {
  1380. int i;
  1381. for (i=0; i < 64; ++i) {
  1382. stbvox_default_palette[i][0] = stbvox_default_palette_compact[i][0] / 255.0f;
  1383. stbvox_default_palette[i][1] = stbvox_default_palette_compact[i][1] / 255.0f;
  1384. stbvox_default_palette[i][2] = stbvox_default_palette_compact[i][2] / 255.0f;
  1385. stbvox_default_palette[i][3] = 1.0f;
  1386. }
  1387. }
  1388. //////////////////////////////////////////////////////////////////////////////
  1389. //
  1390. // Shaders
  1391. //
  1392. #if defined(STBVOX_ICONFIG_OPENGL_3_1_COMPATIBILITY)
  1393. #define STBVOX_SHADER_VERSION "#version 150 compatibility\n"
  1394. #elif defined(STBVOX_ICONFIG_OPENGL_3_0)
  1395. #define STBVOX_SHADER_VERSION "#version 130\n"
  1396. #elif defined(STBVOX_ICONFIG_GLSL)
  1397. #define STBVOX_SHADER_VERSION "#version 150\n"
  1398. #else
  1399. #define STBVOX_SHADER_VERSION ""
  1400. #endif
  1401. static const char *stbvox_vertex_program =
  1402. {
  1403. STBVOX_SHADER_VERSION
  1404. #ifdef STBVOX_ICONFIG_FACE_ATTRIBUTE // NOT TAG_face_sampled
  1405. "in uvec4 attr_face;\n"
  1406. #else
  1407. "uniform usamplerBuffer facearray;\n"
  1408. #endif
  1409. #ifdef STBVOX_ICONFIG_FACE_ARRAY_2
  1410. "uniform usamplerBuffer facearray2;\n"
  1411. #endif
  1412. // vertex input data
  1413. "in uint attr_vertex;\n"
  1414. // per-buffer data
  1415. "uniform vec3 transform[3];\n"
  1416. // per-frame data
  1417. "uniform vec4 camera_pos;\n" // 4th value is used for arbitrary hacking
  1418. // to simplify things, we avoid using more than 256 uniform vectors
  1419. // in fragment shader to avoid possible 1024 component limit, so
  1420. // we access this table in the fragment shader.
  1421. "uniform vec3 normal_table[32];\n"
  1422. #ifndef STBVOX_CONFIG_OPENGL_MODELVIEW
  1423. "uniform mat4x4 model_view;\n"
  1424. #endif
  1425. // fragment output data
  1426. "flat out uvec4 facedata;\n"
  1427. " out vec3 voxelspace_pos;\n"
  1428. " out vec3 vnormal;\n"
  1429. " out float texlerp;\n"
  1430. " out float amb_occ;\n"
  1431. // @TODO handle the HLSL way to do this
  1432. "void main()\n"
  1433. "{\n"
  1434. #ifdef STBVOX_ICONFIG_FACE_ATTRIBUTE
  1435. " facedata = attr_face;\n"
  1436. #else
  1437. " int faceID = gl_VertexID >> 2;\n"
  1438. " facedata = texelFetch(facearray, faceID);\n"
  1439. #endif
  1440. // extract data for vertex
  1441. " vec3 offset;\n"
  1442. " offset.x = float( (attr_vertex ) & 127u );\n" // a[0..6]
  1443. " offset.y = float( (attr_vertex >> 7u) & 127u );\n" // a[7..13]
  1444. " offset.z = float( (attr_vertex >> 14u) & 511u );\n" // a[14..22]
  1445. " amb_occ = float( (attr_vertex >> 23u) & 63u ) / 63.0;\n" // a[23..28]
  1446. " texlerp = float( (attr_vertex >> 29u) ) / 7.0;\n" // a[29..31]
  1447. " vnormal = normal_table[(facedata.w>>2u) & 31u];\n"
  1448. " voxelspace_pos = offset * transform[0];\n" // mesh-to-object scale
  1449. " vec3 position = voxelspace_pos + transform[1];\n" // mesh-to-object translate
  1450. #ifdef STBVOX_DEBUG_TEST_NORMALS
  1451. " if ((facedata.w & 28u) == 16u || (facedata.w & 28u) == 24u)\n"
  1452. " position += vnormal.xyz * camera_pos.w;\n"
  1453. #endif
  1454. #ifndef STBVOX_CONFIG_OPENGL_MODELVIEW
  1455. " gl_Position = model_view * vec4(position,1.0);\n"
  1456. #else
  1457. " gl_Position = gl_ModelViewProjectionMatrix * vec4(position,1.0);\n"
  1458. #endif
  1459. "}\n"
  1460. };
  1461. static const char *stbvox_fragment_program =
  1462. {
  1463. STBVOX_SHADER_VERSION
  1464. // rlerp is lerp but with t on the left, like god intended
  1465. #if defined(STBVOX_ICONFIG_GLSL)
  1466. "#define rlerp(t,x,y) mix(x,y,t)\n"
  1467. #elif defined(STBVOX_CONFIG_HLSL)
  1468. "#define rlerp(t,x,y) lerp(x,y,t)\n"
  1469. #else
  1470. #error "need definition of rlerp()"
  1471. #endif
  1472. // vertex-shader output data
  1473. "flat in uvec4 facedata;\n"
  1474. " in vec3 voxelspace_pos;\n"
  1475. " in vec3 vnormal;\n"
  1476. " in float texlerp;\n"
  1477. " in float amb_occ;\n"
  1478. // per-buffer data
  1479. "uniform vec3 transform[3];\n"
  1480. // per-frame data
  1481. "uniform vec4 camera_pos;\n" // 4th value is used for arbitrary hacking
  1482. // probably constant data
  1483. "uniform vec4 ambient[4];\n"
  1484. #ifndef STBVOX_ICONFIG_UNTEXTURED
  1485. // generally constant data
  1486. "uniform sampler2DArray tex_array[2];\n"
  1487. #ifdef STBVOX_CONFIG_PREFER_TEXBUFFER
  1488. "uniform samplerBuffer color_table;\n"
  1489. "uniform samplerBuffer texscale;\n"
  1490. "uniform samplerBuffer texgen;\n"
  1491. #else
  1492. "uniform vec4 color_table[64];\n"
  1493. "uniform vec4 texscale[64];\n" // instead of 128, to avoid running out of uniforms
  1494. "uniform vec3 texgen[64];\n"
  1495. #endif
  1496. #endif
  1497. "out vec4 outcolor;\n"
  1498. #if defined(STBVOX_CONFIG_LIGHTING) || defined(STBVOX_CONFIG_LIGHTING_SIMPLE)
  1499. "vec3 compute_lighting(vec3 pos, vec3 norm, vec3 albedo, vec3 ambient);\n"
  1500. #endif
  1501. #if defined(STBVOX_CONFIG_FOG) || defined(STBVOX_CONFIG_FOG_SMOOTHSTEP)
  1502. "vec3 compute_fog(vec3 color, vec3 relative_pos, float fragment_alpha);\n"
  1503. #endif
  1504. "void main()\n"
  1505. "{\n"
  1506. " vec3 albedo;\n"
  1507. " float fragment_alpha;\n"
  1508. #ifndef STBVOX_ICONFIG_UNTEXTURED
  1509. // unpack the values
  1510. " uint tex1_id = facedata.x;\n"
  1511. " uint tex2_id = facedata.y;\n"
  1512. " uint texprojid = facedata.w & 31u;\n"
  1513. " uint color_id = facedata.z;\n"
  1514. #ifndef STBVOX_CONFIG_PREFER_TEXBUFFER
  1515. // load from uniforms / texture buffers
  1516. " vec3 texgen_s = texgen[texprojid];\n"
  1517. " vec3 texgen_t = texgen[texprojid+32u];\n"
  1518. " float tex1_scale = texscale[tex1_id & 63u].x;\n"
  1519. " vec4 color = color_table[color_id & 63u];\n"
  1520. #ifndef STBVOX_CONFIG_DISABLE_TEX2
  1521. " vec4 tex2_props = texscale[tex2_id & 63u];\n"
  1522. #endif
  1523. #else
  1524. " vec3 texgen_s = texelFetch(texgen, int(texprojid)).xyz;\n"
  1525. " vec3 texgen_t = texelFetch(texgen, int(texprojid+32u)).xyz;\n"
  1526. " float tex1_scale = texelFetch(texscale, int(tex1_id & 127u)).x;\n"
  1527. " vec4 color = texelFetch(color_table, int(color_id & 63u));\n"
  1528. #ifndef STBVOX_CONFIG_DISABLE_TEX2
  1529. " vec4 tex2_props = texelFetch(texscale, int(tex1_id & 127u));\n"
  1530. #endif
  1531. #endif
  1532. #ifndef STBVOX_CONFIG_DISABLE_TEX2
  1533. " float tex2_scale = tex2_props.y;\n"
  1534. " bool texblend_mode = tex2_props.z != 0.0;\n"
  1535. #endif
  1536. " vec2 texcoord;\n"
  1537. " vec3 texturespace_pos = voxelspace_pos + transform[2].xyz;\n"
  1538. " texcoord.s = dot(texturespace_pos, texgen_s);\n"
  1539. " texcoord.t = dot(texturespace_pos, texgen_t);\n"
  1540. " vec2 texcoord_1 = tex1_scale * texcoord;\n"
  1541. #ifndef STBVOX_CONFIG_DISABLE_TEX2
  1542. " vec2 texcoord_2 = tex2_scale * texcoord;\n"
  1543. #endif
  1544. #ifdef STBVOX_CONFIG_TEX1_EDGE_CLAMP
  1545. " texcoord_1 = texcoord_1 - floor(texcoord_1);\n"
  1546. " vec4 tex1 = textureGrad(tex_array[0], vec3(texcoord_1, float(tex1_id)), dFdx(tex1_scale*texcoord), dFdy(tex1_scale*texcoord));\n"
  1547. #else
  1548. " vec4 tex1 = texture(tex_array[0], vec3(texcoord_1, float(tex1_id)));\n"
  1549. #endif
  1550. #ifndef STBVOX_CONFIG_DISABLE_TEX2
  1551. #ifdef STBVOX_CONFIG_TEX2_EDGE_CLAMP
  1552. " texcoord_2 = texcoord_2 - floor(texcoord_2);\n"
  1553. " vec4 tex2 = textureGrad(tex_array[0], vec3(texcoord_2, float(tex2_id)), dFdx(tex2_scale*texcoord), dFdy(tex2_scale*texcoord));\n"
  1554. #else
  1555. " vec4 tex2 = texture(tex_array[1], vec3(texcoord_2, float(tex2_id)));\n"
  1556. #endif
  1557. #endif
  1558. " bool emissive = (color.a > 1.0);\n"
  1559. " color.a = min(color.a, 1.0);\n"
  1560. // recolor textures
  1561. " if ((color_id & 64u) != 0u) tex1.rgba *= color.rgba;\n"
  1562. " fragment_alpha = tex1.a;\n"
  1563. #ifndef STBVOX_CONFIG_DISABLE_TEX2
  1564. " if ((color_id & 128u) != 0u) tex2.rgba *= color.rgba;\n"
  1565. #ifdef STBVOX_CONFIG_PREMULTIPLIED_ALPHA
  1566. " tex2.rgba *= texlerp;\n"
  1567. #else
  1568. " tex2.a *= texlerp;\n"
  1569. #endif
  1570. " if (texblend_mode)\n"
  1571. " albedo = tex1.xyz * rlerp(tex2.a, vec3(1.0,1.0,1.0), 2.0*tex2.xyz);\n"
  1572. " else {\n"
  1573. #ifdef STBVOX_CONFIG_PREMULTIPLIED_ALPHA
  1574. " albedo = (1.0-tex2.a)*tex1.xyz + tex2.xyz;\n"
  1575. #else
  1576. " albedo = rlerp(tex2.a, tex1.xyz, tex2.xyz);\n"
  1577. #endif
  1578. " fragment_alpha = tex1.a*(1-tex2.a)+tex2.a;\n"
  1579. " }\n"
  1580. #else
  1581. " albedo = tex1.xyz;\n"
  1582. #endif
  1583. #else // UNTEXTURED
  1584. " vec4 color;"
  1585. " color.xyz = vec3(facedata.xyz) / 255.0;\n"
  1586. " bool emissive = false;\n"
  1587. " albedo = color.xyz;\n"
  1588. " fragment_alpha = 1.0;\n"
  1589. #endif
  1590. #ifdef STBVOX_ICONFIG_VARYING_VERTEX_NORMALS
  1591. // currently, there are no modes that trigger this path; idea is that there
  1592. // could be a couple of bits per vertex to perturb the normal to e.g. get curved look
  1593. " vec3 normal = normalize(vnormal);\n"
  1594. #else
  1595. " vec3 normal = vnormal;\n"
  1596. #endif
  1597. " vec3 ambient_color = dot(normal, ambient[0].xyz) * ambient[1].xyz + ambient[2].xyz;\n"
  1598. " ambient_color = clamp(ambient_color, 0.0, 1.0);"
  1599. " ambient_color *= amb_occ;\n"
  1600. " vec3 lit_color;\n"
  1601. " if (!emissive)\n"
  1602. #if defined(STBVOX_ICONFIG_LIGHTING) || defined(STBVOX_CONFIG_LIGHTING_SIMPLE)
  1603. " lit_color = compute_lighting(voxelspace_pos + transform[1], normal, albedo, ambient_color);\n"
  1604. #else
  1605. " lit_color = albedo * ambient_color ;\n"
  1606. #endif
  1607. " else\n"
  1608. " lit_color = albedo;\n"
  1609. #if defined(STBVOX_ICONFIG_FOG) || defined(STBVOX_CONFIG_FOG_SMOOTHSTEP)
  1610. " vec3 dist = voxelspace_pos + (transform[1] - camera_pos.xyz);\n"
  1611. " lit_color = compute_fog(lit_color, dist, fragment_alpha);\n"
  1612. #endif
  1613. #ifdef STBVOX_CONFIG_UNPREMULTIPLY
  1614. " vec4 final_color = vec4(lit_color/fragment_alpha, fragment_alpha);\n"
  1615. #else
  1616. " vec4 final_color = vec4(lit_color, fragment_alpha);\n"
  1617. #endif
  1618. " outcolor = final_color;\n"
  1619. "}\n"
  1620. #ifdef STBVOX_CONFIG_LIGHTING_SIMPLE
  1621. "\n"
  1622. "uniform vec3 light_source[2];\n"
  1623. "vec3 compute_lighting(vec3 pos, vec3 norm, vec3 albedo, vec3 ambient)\n"
  1624. "{\n"
  1625. " vec3 light_dir = light_source[0] - pos;\n"
  1626. " float lambert = dot(light_dir, norm) / dot(light_dir, light_dir);\n"
  1627. " vec3 diffuse = clamp(light_source[1] * clamp(lambert, 0.0, 1.0), 0.0, 1.0);\n"
  1628. " return (diffuse + ambient) * albedo;\n"
  1629. "}\n"
  1630. #endif
  1631. #ifdef STBVOX_CONFIG_FOG_SMOOTHSTEP
  1632. "\n"
  1633. "vec3 compute_fog(vec3 color, vec3 relative_pos, float fragment_alpha)\n"
  1634. "{\n"
  1635. " float f = dot(relative_pos,relative_pos)*ambient[3].w;\n"
  1636. //" f = rlerp(f, -2,1);\n"
  1637. " f = clamp(f, 0.0, 1.0);\n"
  1638. " f = 3.0*f*f - 2.0*f*f*f;\n" // smoothstep
  1639. //" f = f*f;\n" // fade in more smoothly
  1640. #ifdef STBVOX_CONFIG_PREMULTIPLIED_ALPHA
  1641. " return rlerp(f, color.xyz, ambient[3].xyz*fragment_alpha);\n"
  1642. #else
  1643. " return rlerp(f, color.xyz, ambient[3].xyz);\n"
  1644. #endif
  1645. "}\n"
  1646. #endif
  1647. };
  1648. // still requires full alpha lookups, including tex2 if texblend is enabled
  1649. static const char *stbvox_fragment_program_alpha_only =
  1650. {
  1651. STBVOX_SHADER_VERSION
  1652. // vertex-shader output data
  1653. "flat in uvec4 facedata;\n"
  1654. " in vec3 voxelspace_pos;\n"
  1655. " in float texlerp;\n"
  1656. // per-buffer data
  1657. "uniform vec3 transform[3];\n"
  1658. #ifndef STBVOX_ICONFIG_UNTEXTURED
  1659. // generally constant data
  1660. "uniform sampler2DArray tex_array[2];\n"
  1661. #ifdef STBVOX_CONFIG_PREFER_TEXBUFFER
  1662. "uniform samplerBuffer texscale;\n"
  1663. "uniform samplerBuffer texgen;\n"
  1664. #else
  1665. "uniform vec4 texscale[64];\n" // instead of 128, to avoid running out of uniforms
  1666. "uniform vec3 texgen[64];\n"
  1667. #endif
  1668. #endif
  1669. "out vec4 outcolor;\n"
  1670. "void main()\n"
  1671. "{\n"
  1672. " vec3 albedo;\n"
  1673. " float fragment_alpha;\n"
  1674. #ifndef STBVOX_ICONFIG_UNTEXTURED
  1675. // unpack the values
  1676. " uint tex1_id = facedata.x;\n"
  1677. " uint tex2_id = facedata.y;\n"
  1678. " uint texprojid = facedata.w & 31u;\n"
  1679. " uint color_id = facedata.z;\n"
  1680. #ifndef STBVOX_CONFIG_PREFER_TEXBUFFER
  1681. // load from uniforms / texture buffers
  1682. " vec3 texgen_s = texgen[texprojid];\n"
  1683. " vec3 texgen_t = texgen[texprojid+32u];\n"
  1684. " float tex1_scale = texscale[tex1_id & 63u].x;\n"
  1685. " vec4 color = color_table[color_id & 63u];\n"
  1686. " vec4 tex2_props = texscale[tex2_id & 63u];\n"
  1687. #else
  1688. " vec3 texgen_s = texelFetch(texgen, int(texprojid)).xyz;\n"
  1689. " vec3 texgen_t = texelFetch(texgen, int(texprojid+32u)).xyz;\n"
  1690. " float tex1_scale = texelFetch(texscale, int(tex1_id & 127u)).x;\n"
  1691. " vec4 color = texelFetch(color_table, int(color_id & 63u));\n"
  1692. " vec4 tex2_props = texelFetch(texscale, int(tex2_id & 127u));\n"
  1693. #endif
  1694. #ifndef STBVOX_CONFIG_DISABLE_TEX2
  1695. " float tex2_scale = tex2_props.y;\n"
  1696. " bool texblend_mode = tex2_props.z &((facedata.w & 128u) != 0u);\n"
  1697. #endif
  1698. " color.a = min(color.a, 1.0);\n"
  1699. " vec2 texcoord;\n"
  1700. " vec3 texturespace_pos = voxelspace_pos + transform[2].xyz;\n"
  1701. " texcoord.s = dot(texturespace_pos, texgen_s);\n"
  1702. " texcoord.t = dot(texturespace_pos, texgen_t);\n"
  1703. " vec2 texcoord_1 = tex1_scale * texcoord;\n"
  1704. " vec2 texcoord_2 = tex2_scale * texcoord;\n"
  1705. #ifdef STBVOX_CONFIG_TEX1_EDGE_CLAMP
  1706. " texcoord_1 = texcoord_1 - floor(texcoord_1);\n"
  1707. " vec4 tex1 = textureGrad(tex_array[0], vec3(texcoord_1, float(tex1_id)), dFdx(tex1_scale*texcoord), dFdy(tex1_scale*texcoord));\n"
  1708. #else
  1709. " vec4 tex1 = texture(tex_array[0], vec3(texcoord_1, float(tex1_id)));\n"
  1710. #endif
  1711. " if ((color_id & 64u) != 0u) tex1.a *= color.a;\n"
  1712. " fragment_alpha = tex1.a;\n"
  1713. #ifndef STBVOX_CONFIG_DISABLE_TEX2
  1714. " if (!texblend_mode) {\n"
  1715. #ifdef STBVOX_CONFIG_TEX2_EDGE_CLAMP
  1716. " texcoord_2 = texcoord_2 - floor(texcoord_2);\n"
  1717. " vec4 tex2 = textureGrad(tex_array[0], vec3(texcoord_2, float(tex2_id)), dFdx(tex2_scale*texcoord), dFdy(tex2_scale*texcoord));\n"
  1718. #else
  1719. " vec4 tex2 = texture(tex_array[1], vec3(texcoord_2, float(tex2_id)));\n"
  1720. #endif
  1721. " tex2.a *= texlerp;\n"
  1722. " if ((color_id & 128u) != 0u) tex2.rgba *= color.a;\n"
  1723. " fragment_alpha = tex1.a*(1-tex2.a)+tex2.a;\n"
  1724. "}\n"
  1725. "\n"
  1726. #endif
  1727. #else // UNTEXTURED
  1728. " fragment_alpha = 1.0;\n"
  1729. #endif
  1730. " outcolor = vec4(0.0, 0.0, 0.0, fragment_alpha);\n"
  1731. "}\n"
  1732. };
  1733. STBVXDEC char *stbvox_get_vertex_shader(void)
  1734. {
  1735. return (char *) stbvox_vertex_program;
  1736. }
  1737. STBVXDEC char *stbvox_get_fragment_shader(void)
  1738. {
  1739. return (char *) stbvox_fragment_program;
  1740. }
  1741. STBVXDEC char *stbvox_get_fragment_shader_alpha_only(void)
  1742. {
  1743. return (char *) stbvox_fragment_program_alpha_only;
  1744. }
  1745. static float stbvox_dummy_transform[3][3];
  1746. #ifdef STBVOX_CONFIG_PREFER_TEXBUFFER
  1747. #define STBVOX_TEXBUF 1
  1748. #else
  1749. #define STBVOX_TEXBUF 0
  1750. #endif
  1751. static stbvox_uniform_info stbvox_uniforms[] =
  1752. {
  1753. { STBVOX_UNIFORM_TYPE_sampler , 4, 1, (char*) "facearray" , 0 },
  1754. { STBVOX_UNIFORM_TYPE_vec3 , 12, 3, (char*) "transform" , stbvox_dummy_transform[0] },
  1755. { STBVOX_UNIFORM_TYPE_sampler , 4, 2, (char*) "tex_array" , 0 },
  1756. { STBVOX_UNIFORM_TYPE_vec4 , 16, 128, (char*) "texscale" , stbvox_default_texscale[0] , STBVOX_TEXBUF },
  1757. { STBVOX_UNIFORM_TYPE_vec4 , 16, 64, (char*) "color_table" , stbvox_default_palette[0] , STBVOX_TEXBUF },
  1758. { STBVOX_UNIFORM_TYPE_vec3 , 12, 32, (char*) "normal_table" , stbvox_default_normals[0] },
  1759. { STBVOX_UNIFORM_TYPE_vec3 , 12, 64, (char*) "texgen" , stbvox_default_texgen[0][0], STBVOX_TEXBUF },
  1760. { STBVOX_UNIFORM_TYPE_vec4 , 16, 4, (char*) "ambient" , stbvox_default_ambient[0] },
  1761. { STBVOX_UNIFORM_TYPE_vec4 , 16, 1, (char*) "camera_pos" , stbvox_dummy_transform[0] },
  1762. };
  1763. STBVXDEC int stbvox_get_uniform_info(stbvox_uniform_info *info, int uniform)
  1764. {
  1765. if (uniform < 0 || uniform >= STBVOX_UNIFORM_count)
  1766. return 0;
  1767. *info = stbvox_uniforms[uniform];
  1768. return 1;
  1769. }
  1770. #define STBVOX_GET_GEO(geom_data) ((geom_data) & 15)
  1771. typedef struct
  1772. {
  1773. unsigned char block:2;
  1774. unsigned char overlay:2;
  1775. unsigned char facerot:2;
  1776. unsigned char ecolor:2;
  1777. } stbvox_rotate;
  1778. typedef struct
  1779. {
  1780. unsigned char x,y,z;
  1781. } stbvox_pos;
  1782. static unsigned char stbvox_rotate_face[6][4] =
  1783. {
  1784. { 0,1,2,3 },
  1785. { 1,2,3,0 },
  1786. { 2,3,0,1 },
  1787. { 3,0,1,2 },
  1788. { 4,4,4,4 },
  1789. { 5,5,5,5 },
  1790. };
  1791. #define STBVOX_ROTATE(x,r) stbvox_rotate_face[x][r] // (((x)+(r))&3)
  1792. stbvox_mesh_face stbvox_compute_mesh_face_value(stbvox_mesh_maker *mm, stbvox_rotate rot, int face, int v_off, int normal)
  1793. {
  1794. stbvox_mesh_face face_data = { 0 };
  1795. stbvox_block_type bt = mm->input.blocktype[v_off];
  1796. unsigned char bt_face = STBVOX_ROTATE(face, rot.block);
  1797. int facerot = rot.facerot;
  1798. #ifdef STBVOX_ICONFIG_UNTEXTURED
  1799. if (mm->input.rgb) {
  1800. face_data.tex1 = mm->input.rgb[v_off].r;
  1801. face_data.tex2 = mm->input.rgb[v_off].g;
  1802. face_data.color = mm->input.rgb[v_off].b;
  1803. face_data.face_info = (normal<<2);
  1804. return face_data;
  1805. }
  1806. #else
  1807. unsigned char color_face;
  1808. if (mm->input.color)
  1809. face_data.color = mm->input.color[v_off];
  1810. if (mm->input.block_tex1)
  1811. face_data.tex1 = mm->input.block_tex1[bt];
  1812. else if (mm->input.block_tex1_face)
  1813. face_data.tex1 = mm->input.block_tex1_face[bt][bt_face];
  1814. else
  1815. face_data.tex1 = bt;
  1816. if (mm->input.block_tex2)
  1817. face_data.tex2 = mm->input.block_tex2[bt];
  1818. else if (mm->input.block_tex2_face)
  1819. face_data.tex2 = mm->input.block_tex2_face[bt][bt_face];
  1820. if (mm->input.block_color) {
  1821. unsigned char mcol = mm->input.block_color[bt];
  1822. if (mcol)
  1823. face_data.color = mcol;
  1824. } else if (mm->input.block_color_face) {
  1825. unsigned char mcol = mm->input.block_color_face[bt][bt_face];
  1826. if (mcol)
  1827. face_data.color = mcol;
  1828. }
  1829. if (face <= STBVOX_FACE_south) {
  1830. if (mm->input.side_texrot)
  1831. facerot = mm->input.side_texrot[v_off] >> (2 * face);
  1832. else if (mm->input.block_side_texrot)
  1833. facerot = mm->input.block_side_texrot[v_off] >> (2 * bt_face);
  1834. }
  1835. if (mm->input.overlay) {
  1836. int over_face = STBVOX_ROTATE(face, rot.overlay);
  1837. unsigned char over = mm->input.overlay[v_off];
  1838. if (over) {
  1839. if (mm->input.overlay_tex1) {
  1840. unsigned char rep1 = mm->input.overlay_tex1[over][over_face];
  1841. if (rep1)
  1842. face_data.tex1 = rep1;
  1843. }
  1844. if (mm->input.overlay_tex2) {
  1845. unsigned char rep2 = mm->input.overlay_tex2[over][over_face];
  1846. if (rep2)
  1847. face_data.tex2 = rep2;
  1848. }
  1849. if (mm->input.overlay_color) {
  1850. unsigned char rep3 = mm->input.overlay_color[over][over_face];
  1851. if (rep3)
  1852. face_data.color = rep3;
  1853. }
  1854. if (mm->input.overlay_side_texrot && face <= STBVOX_FACE_south)
  1855. facerot = mm->input.overlay_side_texrot[over] >> (2*over_face);
  1856. }
  1857. }
  1858. if (mm->input.tex2_for_tex1)
  1859. face_data.tex2 = mm->input.tex2_for_tex1[face_data.tex1];
  1860. if (mm->input.tex2)
  1861. face_data.tex2 = mm->input.tex2[v_off];
  1862. if (mm->input.tex2_replace) {
  1863. if (mm->input.tex2_facemask[v_off] & (1 << face))
  1864. face_data.tex2 = mm->input.tex2_replace[v_off];
  1865. }
  1866. color_face = STBVOX_ROTATE(face, rot.ecolor);
  1867. if (mm->input.extended_color) {
  1868. unsigned char ec = mm->input.extended_color[v_off];
  1869. if (mm->input.ecolor_facemask[ec] & (1 << color_face))
  1870. face_data.color = mm->input.ecolor_color[ec];
  1871. }
  1872. if (mm->input.color2) {
  1873. if (mm->input.color2_facemask[v_off] & (1 << color_face))
  1874. face_data.color = mm->input.color2[v_off];
  1875. if (mm->input.color3 && (mm->input.color3_facemask[v_off] & (1 << color_face)))
  1876. face_data.color = mm->input.color3[v_off];
  1877. }
  1878. #endif
  1879. face_data.face_info = (normal<<2) + facerot;
  1880. return face_data;
  1881. }
  1882. // these are the types of faces each block can have
  1883. enum
  1884. {
  1885. STBVOX_FT_none ,
  1886. STBVOX_FT_upper ,
  1887. STBVOX_FT_lower ,
  1888. STBVOX_FT_solid ,
  1889. STBVOX_FT_diag_012,
  1890. STBVOX_FT_diag_023,
  1891. STBVOX_FT_diag_013,
  1892. STBVOX_FT_diag_123,
  1893. STBVOX_FT_force , // can't be covered up, used for internal faces, also hides nothing
  1894. STBVOX_FT_partial , // only covered by solid, never covers anything else
  1895. STBVOX_FT_count
  1896. };
  1897. static unsigned char stbvox_face_lerp[6] = { 0,2,0,2,4,4 };
  1898. static unsigned char stbvox_vert3_lerp[5] = { 0,3,6,9,12 };
  1899. static unsigned char stbvox_vert_lerp_for_face_lerp[4] = { 0, 4, 7, 7 };
  1900. static unsigned char stbvox_face3_lerp[6] = { 0,3,6,9,12,14 };
  1901. static unsigned char stbvox_vert_lerp_for_simple[4] = { 0,2,5,7 };
  1902. static unsigned char stbvox_face3_updown[8] = { 0,2,5,7,0,2,5,7 }; // ignore top bit
  1903. // vertex offsets for face vertices
  1904. static unsigned char stbvox_vertex_vector[6][4][3] =
  1905. {
  1906. { { 1,0,1 }, { 1,1,1 }, { 1,1,0 }, { 1,0,0 } }, // east
  1907. { { 1,1,1 }, { 0,1,1 }, { 0,1,0 }, { 1,1,0 } }, // north
  1908. { { 0,1,1 }, { 0,0,1 }, { 0,0,0 }, { 0,1,0 } }, // west
  1909. { { 0,0,1 }, { 1,0,1 }, { 1,0,0 }, { 0,0,0 } }, // south
  1910. { { 0,1,1 }, { 1,1,1 }, { 1,0,1 }, { 0,0,1 } }, // up
  1911. { { 0,0,0 }, { 1,0,0 }, { 1,1,0 }, { 0,1,0 } }, // down
  1912. };
  1913. // stbvox_vertex_vector, but read coordinates as binary numbers, zyx
  1914. static unsigned char stbvox_vertex_selector[6][4] =
  1915. {
  1916. { 5,7,3,1 },
  1917. { 7,6,2,3 },
  1918. { 6,4,0,2 },
  1919. { 4,5,1,0 },
  1920. { 6,7,5,4 },
  1921. { 0,1,3,2 },
  1922. };
  1923. static stbvox_mesh_vertex stbvox_vmesh_delta_normal[6][4] =
  1924. {
  1925. { stbvox_vertex_encode(1,0,1,0,0) ,
  1926. stbvox_vertex_encode(1,1,1,0,0) ,
  1927. stbvox_vertex_encode(1,1,0,0,0) ,
  1928. stbvox_vertex_encode(1,0,0,0,0) },
  1929. { stbvox_vertex_encode(1,1,1,0,0) ,
  1930. stbvox_vertex_encode(0,1,1,0,0) ,
  1931. stbvox_vertex_encode(0,1,0,0,0) ,
  1932. stbvox_vertex_encode(1,1,0,0,0) },
  1933. { stbvox_vertex_encode(0,1,1,0,0) ,
  1934. stbvox_vertex_encode(0,0,1,0,0) ,
  1935. stbvox_vertex_encode(0,0,0,0,0) ,
  1936. stbvox_vertex_encode(0,1,0,0,0) },
  1937. { stbvox_vertex_encode(0,0,1,0,0) ,
  1938. stbvox_vertex_encode(1,0,1,0,0) ,
  1939. stbvox_vertex_encode(1,0,0,0,0) ,
  1940. stbvox_vertex_encode(0,0,0,0,0) },
  1941. { stbvox_vertex_encode(0,1,1,0,0) ,
  1942. stbvox_vertex_encode(1,1,1,0,0) ,
  1943. stbvox_vertex_encode(1,0,1,0,0) ,
  1944. stbvox_vertex_encode(0,0,1,0,0) },
  1945. { stbvox_vertex_encode(0,0,0,0,0) ,
  1946. stbvox_vertex_encode(1,0,0,0,0) ,
  1947. stbvox_vertex_encode(1,1,0,0,0) ,
  1948. stbvox_vertex_encode(0,1,0,0,0) }
  1949. };
  1950. static stbvox_mesh_vertex stbvox_vmesh_pre_vheight[6][4] =
  1951. {
  1952. { stbvox_vertex_encode(1,0,0,0,0) ,
  1953. stbvox_vertex_encode(1,1,0,0,0) ,
  1954. stbvox_vertex_encode(1,1,0,0,0) ,
  1955. stbvox_vertex_encode(1,0,0,0,0) },
  1956. { stbvox_vertex_encode(1,1,0,0,0) ,
  1957. stbvox_vertex_encode(0,1,0,0,0) ,
  1958. stbvox_vertex_encode(0,1,0,0,0) ,
  1959. stbvox_vertex_encode(1,1,0,0,0) },
  1960. { stbvox_vertex_encode(0,1,0,0,0) ,
  1961. stbvox_vertex_encode(0,0,0,0,0) ,
  1962. stbvox_vertex_encode(0,0,0,0,0) ,
  1963. stbvox_vertex_encode(0,1,0,0,0) },
  1964. { stbvox_vertex_encode(0,0,0,0,0) ,
  1965. stbvox_vertex_encode(1,0,0,0,0) ,
  1966. stbvox_vertex_encode(1,0,0,0,0) ,
  1967. stbvox_vertex_encode(0,0,0,0,0) },
  1968. { stbvox_vertex_encode(0,1,0,0,0) ,
  1969. stbvox_vertex_encode(1,1,0,0,0) ,
  1970. stbvox_vertex_encode(1,0,0,0,0) ,
  1971. stbvox_vertex_encode(0,0,0,0,0) },
  1972. { stbvox_vertex_encode(0,0,0,0,0) ,
  1973. stbvox_vertex_encode(1,0,0,0,0) ,
  1974. stbvox_vertex_encode(1,1,0,0,0) ,
  1975. stbvox_vertex_encode(0,1,0,0,0) }
  1976. };
  1977. static stbvox_mesh_vertex stbvox_vmesh_delta_half_z[6][4] =
  1978. {
  1979. { stbvox_vertex_encode(1,0,2,0,0) ,
  1980. stbvox_vertex_encode(1,1,2,0,0) ,
  1981. stbvox_vertex_encode(1,1,0,0,0) ,
  1982. stbvox_vertex_encode(1,0,0,0,0) },
  1983. { stbvox_vertex_encode(1,1,2,0,0) ,
  1984. stbvox_vertex_encode(0,1,2,0,0) ,
  1985. stbvox_vertex_encode(0,1,0,0,0) ,
  1986. stbvox_vertex_encode(1,1,0,0,0) },
  1987. { stbvox_vertex_encode(0,1,2,0,0) ,
  1988. stbvox_vertex_encode(0,0,2,0,0) ,
  1989. stbvox_vertex_encode(0,0,0,0,0) ,
  1990. stbvox_vertex_encode(0,1,0,0,0) },
  1991. { stbvox_vertex_encode(0,0,2,0,0) ,
  1992. stbvox_vertex_encode(1,0,2,0,0) ,
  1993. stbvox_vertex_encode(1,0,0,0,0) ,
  1994. stbvox_vertex_encode(0,0,0,0,0) },
  1995. { stbvox_vertex_encode(0,1,2,0,0) ,
  1996. stbvox_vertex_encode(1,1,2,0,0) ,
  1997. stbvox_vertex_encode(1,0,2,0,0) ,
  1998. stbvox_vertex_encode(0,0,2,0,0) },
  1999. { stbvox_vertex_encode(0,0,0,0,0) ,
  2000. stbvox_vertex_encode(1,0,0,0,0) ,
  2001. stbvox_vertex_encode(1,1,0,0,0) ,
  2002. stbvox_vertex_encode(0,1,0,0,0) }
  2003. };
  2004. static stbvox_mesh_vertex stbvox_vmesh_crossed_pair[6][4] =
  2005. {
  2006. { stbvox_vertex_encode(1,0,2,0,0) ,
  2007. stbvox_vertex_encode(0,1,2,0,0) ,
  2008. stbvox_vertex_encode(0,1,0,0,0) ,
  2009. stbvox_vertex_encode(1,0,0,0,0) },
  2010. { stbvox_vertex_encode(1,1,2,0,0) ,
  2011. stbvox_vertex_encode(0,0,2,0,0) ,
  2012. stbvox_vertex_encode(0,0,0,0,0) ,
  2013. stbvox_vertex_encode(1,1,0,0,0) },
  2014. { stbvox_vertex_encode(0,1,2,0,0) ,
  2015. stbvox_vertex_encode(1,0,2,0,0) ,
  2016. stbvox_vertex_encode(1,0,0,0,0) ,
  2017. stbvox_vertex_encode(0,1,0,0,0) },
  2018. { stbvox_vertex_encode(0,0,2,0,0) ,
  2019. stbvox_vertex_encode(1,1,2,0,0) ,
  2020. stbvox_vertex_encode(1,1,0,0,0) ,
  2021. stbvox_vertex_encode(0,0,0,0,0) },
  2022. // not used, so we leave it non-degenerate to make sure it doesn't get gen'd accidentally
  2023. { stbvox_vertex_encode(0,1,2,0,0) ,
  2024. stbvox_vertex_encode(1,1,2,0,0) ,
  2025. stbvox_vertex_encode(1,0,2,0,0) ,
  2026. stbvox_vertex_encode(0,0,2,0,0) },
  2027. { stbvox_vertex_encode(0,0,0,0,0) ,
  2028. stbvox_vertex_encode(1,0,0,0,0) ,
  2029. stbvox_vertex_encode(1,1,0,0,0) ,
  2030. stbvox_vertex_encode(0,1,0,0,0) }
  2031. };
  2032. #define STBVOX_MAX_GEOM 16
  2033. #define STBVOX_NUM_ROTATION 4
  2034. // this is used to determine if a face is ever generated at all
  2035. static unsigned char stbvox_hasface[STBVOX_MAX_GEOM][STBVOX_NUM_ROTATION] =
  2036. {
  2037. { 0,0,0,0 }, // empty
  2038. { 0,0,0,0 }, // knockout
  2039. { 63,63,63,63 }, // solid
  2040. { 63,63,63,63 }, // transp
  2041. { 63,63,63,63 }, // slab
  2042. { 63,63,63,63 }, // slab
  2043. { 1|2|4|48, 8|1|2|48, 4|8|1|48, 2|4|8|48, }, // floor slopes
  2044. { 1|2|4|48, 8|1|2|48, 4|8|1|48, 2|4|8|48, }, // ceil slopes
  2045. { 47,47,47,47 }, // wall-projected diagonal with down face
  2046. { 31,31,31,31 }, // wall-projected diagonal with up face
  2047. { 63,63,63,63 }, // crossed-pair has special handling, but avoid early-out
  2048. { 63,63,63,63 }, // force
  2049. { 63,63,63,63 }, // vheight
  2050. { 63,63,63,63 }, // vheight
  2051. { 63,63,63,63 }, // vheight
  2052. { 63,63,63,63 }, // vheight
  2053. };
  2054. // this determines which face type above is visible on each side of the geometry
  2055. static unsigned char stbvox_facetype[STBVOX_GEOM_count][6] =
  2056. {
  2057. { 0, }, // STBVOX_GEOM_empty
  2058. { STBVOX_FT_solid, STBVOX_FT_solid, STBVOX_FT_solid, STBVOX_FT_solid, STBVOX_FT_solid, STBVOX_FT_solid }, // knockout
  2059. { STBVOX_FT_solid, STBVOX_FT_solid, STBVOX_FT_solid, STBVOX_FT_solid, STBVOX_FT_solid, STBVOX_FT_solid }, // solid
  2060. { STBVOX_FT_force, STBVOX_FT_force, STBVOX_FT_force, STBVOX_FT_force, STBVOX_FT_force, STBVOX_FT_force }, // transp
  2061. { STBVOX_FT_upper, STBVOX_FT_upper, STBVOX_FT_upper, STBVOX_FT_upper, STBVOX_FT_solid, STBVOX_FT_force },
  2062. { STBVOX_FT_lower, STBVOX_FT_lower, STBVOX_FT_lower, STBVOX_FT_lower, STBVOX_FT_force, STBVOX_FT_solid },
  2063. { STBVOX_FT_diag_123, STBVOX_FT_solid, STBVOX_FT_diag_023, STBVOX_FT_none, STBVOX_FT_force, STBVOX_FT_solid },
  2064. { STBVOX_FT_diag_012, STBVOX_FT_solid, STBVOX_FT_diag_013, STBVOX_FT_none, STBVOX_FT_solid, STBVOX_FT_force },
  2065. { STBVOX_FT_diag_123, STBVOX_FT_solid, STBVOX_FT_diag_023, STBVOX_FT_force, STBVOX_FT_none, STBVOX_FT_solid },
  2066. { STBVOX_FT_diag_012, STBVOX_FT_solid, STBVOX_FT_diag_013, STBVOX_FT_force, STBVOX_FT_solid, STBVOX_FT_none },
  2067. { STBVOX_FT_force, STBVOX_FT_force, STBVOX_FT_force, STBVOX_FT_force, 0,0 }, // crossed pair
  2068. { STBVOX_FT_force, STBVOX_FT_force, STBVOX_FT_force, STBVOX_FT_force, STBVOX_FT_force, STBVOX_FT_force }, // GEOM_force
  2069. { STBVOX_FT_partial,STBVOX_FT_partial,STBVOX_FT_partial,STBVOX_FT_partial, STBVOX_FT_force, STBVOX_FT_solid }, // floor vheight, all neighbors forced
  2070. { STBVOX_FT_partial,STBVOX_FT_partial,STBVOX_FT_partial,STBVOX_FT_partial, STBVOX_FT_force, STBVOX_FT_solid }, // floor vheight, all neighbors forced
  2071. { STBVOX_FT_partial,STBVOX_FT_partial,STBVOX_FT_partial,STBVOX_FT_partial, STBVOX_FT_solid, STBVOX_FT_force }, // ceil vheight, all neighbors forced
  2072. { STBVOX_FT_partial,STBVOX_FT_partial,STBVOX_FT_partial,STBVOX_FT_partial, STBVOX_FT_solid, STBVOX_FT_force }, // ceil vheight, all neighbors forced
  2073. };
  2074. // This table indicates what normal to use for the "up" face of a sloped geom
  2075. // @TODO this could be done with math given the current arrangement of the enum, but let's not require it
  2076. static unsigned char stbvox_floor_slope_for_rot[4] =
  2077. {
  2078. STBVF_su,
  2079. STBVF_wu, // @TODO: why is this reversed from what it should be? this is a north-is-up face, so slope should be south&up
  2080. STBVF_nu,
  2081. STBVF_eu,
  2082. };
  2083. static unsigned char stbvox_ceil_slope_for_rot[4] =
  2084. {
  2085. STBVF_sd,
  2086. STBVF_ed,
  2087. STBVF_nd,
  2088. STBVF_wd,
  2089. };
  2090. // this table indicates whether, for each pair of types above, a face is visible.
  2091. // each value indicates whether a given type is visible for all neighbor types
  2092. static unsigned short stbvox_face_visible[STBVOX_FT_count] =
  2093. {
  2094. // we encode the table by listing which cases cause *obscuration*, and bitwise inverting that
  2095. // table is pre-shifted by 5 to save a shift when it's accessed
  2096. (unsigned short) ((~0x07ffu )<<5), // none is completely obscured by everything
  2097. (unsigned short) ((~((1u<<STBVOX_FT_solid) | (1<<STBVOX_FT_upper) ))<<5), // upper
  2098. (unsigned short) ((~((1u<<STBVOX_FT_solid) | (1<<STBVOX_FT_lower) ))<<5), // lower
  2099. (unsigned short) ((~((1u<<STBVOX_FT_solid) ))<<5), // solid is only completely obscured only by solid
  2100. (unsigned short) ((~((1u<<STBVOX_FT_solid) | (1<<STBVOX_FT_diag_013)))<<5), // diag012 matches diag013
  2101. (unsigned short) ((~((1u<<STBVOX_FT_solid) | (1<<STBVOX_FT_diag_123)))<<5), // diag023 matches diag123
  2102. (unsigned short) ((~((1u<<STBVOX_FT_solid) | (1<<STBVOX_FT_diag_012)))<<5), // diag013 matches diag012
  2103. (unsigned short) ((~((1u<<STBVOX_FT_solid) | (1<<STBVOX_FT_diag_023)))<<5), // diag123 matches diag023
  2104. (unsigned short) ((~0u )<<5), // force is always rendered regardless, always forces neighbor
  2105. (unsigned short) ((~((1u<<STBVOX_FT_solid) ))<<5), // partial is only completely obscured only by solid
  2106. };
  2107. // the vertex heights of the block types, in binary vertex order (zyx):
  2108. // lower: SW, SE, NW, NE; upper: SW, SE, NW, NE
  2109. static stbvox_mesh_vertex stbvox_geometry_vheight[8][8] =
  2110. {
  2111. #define STBVOX_HEIGHTS(a,b,c,d,e,f,g,h) \
  2112. { stbvox_vertex_encode(0,0,a,0,0), \
  2113. stbvox_vertex_encode(0,0,b,0,0), \
  2114. stbvox_vertex_encode(0,0,c,0,0), \
  2115. stbvox_vertex_encode(0,0,d,0,0), \
  2116. stbvox_vertex_encode(0,0,e,0,0), \
  2117. stbvox_vertex_encode(0,0,f,0,0), \
  2118. stbvox_vertex_encode(0,0,g,0,0), \
  2119. stbvox_vertex_encode(0,0,h,0,0) }
  2120. STBVOX_HEIGHTS(0,0,0,0, 2,2,2,2),
  2121. STBVOX_HEIGHTS(0,0,0,0, 2,2,2,2),
  2122. STBVOX_HEIGHTS(0,0,0,0, 2,2,2,2),
  2123. STBVOX_HEIGHTS(0,0,0,0, 2,2,2,2),
  2124. STBVOX_HEIGHTS(1,1,1,1, 2,2,2,2),
  2125. STBVOX_HEIGHTS(0,0,0,0, 1,1,1,1),
  2126. STBVOX_HEIGHTS(0,0,0,0, 0,0,2,2),
  2127. STBVOX_HEIGHTS(2,2,0,0, 2,2,2,2),
  2128. };
  2129. // rotate vertices defined as [z][y][x] coords
  2130. static unsigned char stbvox_rotate_vertex[8][4] =
  2131. {
  2132. { 0,1,3,2 }, // zyx=000
  2133. { 1,3,2,0 }, // zyx=001
  2134. { 2,0,1,3 }, // zyx=010
  2135. { 3,2,0,1 }, // zyx=011
  2136. { 4,5,7,6 }, // zyx=100
  2137. { 5,7,6,4 }, // zyx=101
  2138. { 6,4,5,7 }, // zyx=110
  2139. { 7,6,4,5 }, // zyx=111
  2140. };
  2141. #ifdef STBVOX_CONFIG_OPTIMIZED_VHEIGHT
  2142. // optimized vheight generates a single normal over the entire face, even if it's not planar
  2143. static unsigned char stbvox_optimized_face_up_normal[4][4][4][4] =
  2144. {
  2145. {
  2146. {
  2147. { STBVF_u , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
  2148. { STBVF_nw_u, STBVF_nu , STBVF_nu , STBVF_ne_u, },
  2149. { STBVF_nw_u, STBVF_nu , STBVF_nu , STBVF_nu , },
  2150. { STBVF_nw_u, STBVF_nw_u, STBVF_nu , STBVF_nu , },
  2151. },{
  2152. { STBVF_su , STBVF_eu , STBVF_eu , STBVF_ne_u, },
  2153. { STBVF_u , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
  2154. { STBVF_nw_u, STBVF_nu , STBVF_nu , STBVF_ne_u, },
  2155. { STBVF_nw_u, STBVF_nu , STBVF_nu , STBVF_nu , },
  2156. },{
  2157. { STBVF_eu , STBVF_eu , STBVF_eu , STBVF_eu , },
  2158. { STBVF_su , STBVF_eu , STBVF_eu , STBVF_ne_u, },
  2159. { STBVF_u , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
  2160. { STBVF_nw_u, STBVF_nu , STBVF_nu , STBVF_ne_u, },
  2161. },{
  2162. { STBVF_eu , STBVF_eu , STBVF_eu , STBVF_eu , },
  2163. { STBVF_eu , STBVF_eu , STBVF_eu , STBVF_eu , },
  2164. { STBVF_su , STBVF_eu , STBVF_eu , STBVF_ne_u, },
  2165. { STBVF_u , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
  2166. },
  2167. },{
  2168. {
  2169. { STBVF_sw_u, STBVF_u , STBVF_ne_u, STBVF_ne_u, },
  2170. { STBVF_wu , STBVF_nw_u, STBVF_nu , STBVF_nu , },
  2171. { STBVF_wu , STBVF_nw_u, STBVF_nu , STBVF_nu , },
  2172. { STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, STBVF_nu , },
  2173. },{
  2174. { STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
  2175. { STBVF_sw_u, STBVF_u , STBVF_ne_u, STBVF_ne_u, },
  2176. { STBVF_wu , STBVF_nw_u, STBVF_nu , STBVF_nu , },
  2177. { STBVF_wu , STBVF_nw_u, STBVF_nu , STBVF_nu , },
  2178. },{
  2179. { STBVF_su , STBVF_eu , STBVF_eu , STBVF_eu , },
  2180. { STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
  2181. { STBVF_sw_u, STBVF_u , STBVF_ne_u, STBVF_ne_u, },
  2182. { STBVF_wu , STBVF_nw_u, STBVF_nu , STBVF_nu , },
  2183. },{
  2184. { STBVF_su , STBVF_eu , STBVF_eu , STBVF_eu , },
  2185. { STBVF_su , STBVF_eu , STBVF_eu , STBVF_eu , },
  2186. { STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
  2187. { STBVF_sw_u, STBVF_u , STBVF_ne_u, STBVF_ne_u, },
  2188. },
  2189. },{
  2190. {
  2191. { STBVF_sw_u, STBVF_sw_u, STBVF_u , STBVF_ne_u, },
  2192. { STBVF_wu , STBVF_wu , STBVF_nw_u, STBVF_nu , },
  2193. { STBVF_wu , STBVF_wu , STBVF_nw_u, STBVF_nu , },
  2194. { STBVF_wu , STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, },
  2195. },{
  2196. { STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
  2197. { STBVF_sw_u, STBVF_sw_u, STBVF_u , STBVF_ne_u, },
  2198. { STBVF_wu , STBVF_wu , STBVF_nw_u, STBVF_nu , },
  2199. { STBVF_wu , STBVF_wu , STBVF_nw_u, STBVF_nu , },
  2200. },{
  2201. { STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
  2202. { STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
  2203. { STBVF_sw_u, STBVF_sw_u, STBVF_u , STBVF_ne_u, },
  2204. { STBVF_wu , STBVF_wu , STBVF_nw_u, STBVF_nu , },
  2205. },{
  2206. { STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
  2207. { STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
  2208. { STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
  2209. { STBVF_sw_u, STBVF_sw_u, STBVF_u , STBVF_ne_u, },
  2210. },
  2211. },{
  2212. {
  2213. { STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_u , },
  2214. { STBVF_sw_u, STBVF_wu , STBVF_wu , STBVF_nw_u, },
  2215. { STBVF_wu , STBVF_wu , STBVF_wu , STBVF_nw_u, },
  2216. { STBVF_wu , STBVF_wu , STBVF_nw_u, STBVF_nw_u, },
  2217. },{
  2218. { STBVF_sw_u, STBVF_su , STBVF_su , STBVF_su , },
  2219. { STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_u , },
  2220. { STBVF_sw_u, STBVF_wu , STBVF_wu , STBVF_nw_u, },
  2221. { STBVF_wu , STBVF_wu , STBVF_wu , STBVF_nw_u, },
  2222. },{
  2223. { STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
  2224. { STBVF_sw_u, STBVF_su , STBVF_su , STBVF_su , },
  2225. { STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_u , },
  2226. { STBVF_sw_u, STBVF_wu , STBVF_wu , STBVF_nw_u, },
  2227. },{
  2228. { STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
  2229. { STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
  2230. { STBVF_sw_u, STBVF_su , STBVF_su , STBVF_su , },
  2231. { STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_u , },
  2232. },
  2233. },
  2234. };
  2235. #else
  2236. // which normal to use for a given vheight that's planar
  2237. // @TODO: this table was constructed by hand and may have bugs
  2238. // nw se sw
  2239. static unsigned char stbvox_planar_face_up_normal[4][4][4] =
  2240. {
  2241. { // sw,se,nw,ne; ne = se+nw-sw
  2242. { STBVF_u , 0 , 0 , 0 }, // 0,0,0,0; 1,0,0,-1; 2,0,0,-2; 3,0,0,-3;
  2243. { STBVF_u , STBVF_u , 0 , 0 }, // 0,1,0,1; 1,1,0, 0; 2,1,0,-1; 3,1,0,-2;
  2244. { STBVF_wu , STBVF_nw_u, STBVF_nu , 0 }, // 0,2,0,2; 1,2,0, 1; 2,2,0, 0; 3,2,0,-1;
  2245. { STBVF_wu , STBVF_nw_u, STBVF_nw_u, STBVF_nu }, // 0,3,0,3; 1,3,0, 2; 2,3,0, 1; 3,3,0, 0;
  2246. },{
  2247. { STBVF_u , STBVF_u , 0 , 0 }, // 0,0,1,1; 1,0,1, 0; 2,0,1,-1; 3,0,1,-2;
  2248. { STBVF_sw_u, STBVF_u , STBVF_ne_u, 0 }, // 0,1,1,2; 1,1,1, 1; 2,1,1, 0; 3,1,1,-1;
  2249. { STBVF_sw_u, STBVF_u , STBVF_u , STBVF_ne_u }, // 0,2,1,3; 1,2,1, 2; 2,2,1, 1; 3,2,1, 0;
  2250. { 0 , STBVF_wu , STBVF_nw_u, STBVF_nu }, // 0,3,1,4; 1,3,1, 3; 2,3,1, 2; 3,3,1, 1;
  2251. },{
  2252. { STBVF_su , STBVF_se_u, STBVF_eu , 0 }, // 0,0,2,2; 1,0,2, 1; 2,0,2, 0; 3,0,2,-1;
  2253. { STBVF_sw_u, STBVF_u , STBVF_u , STBVF_ne_u }, // 0,1,2,3; 1,1,2, 2; 2,1,2, 1; 3,1,2, 0;
  2254. { 0 , STBVF_sw_u, STBVF_u , STBVF_ne_u }, // 0,2,2,4; 1,2,2, 3; 2,2,2, 2; 3,2,2, 1;
  2255. { 0 , 0 , STBVF_u , STBVF_u }, // 0,3,2,5; 1,3,2, 4; 2,3,2, 3; 3,3,2, 2;
  2256. },{
  2257. { STBVF_su , STBVF_se_u, STBVF_se_u, STBVF_eu }, // 0,0,3,3; 1,0,3, 2; 2,0,3, 1; 3,0,3, 0;
  2258. { 0 , STBVF_su , STBVF_se_u, STBVF_eu }, // 0,1,3,4; 1,1,3, 3; 2,1,3, 2; 3,1,3, 1;
  2259. { 0 , 0 , STBVF_u , STBVF_u }, // 0,2,3,5; 1,2,3, 4; 2,2,3, 3; 3,2,3, 2;
  2260. { 0 , 0 , 0 , STBVF_u }, // 0,3,3,6; 1,3,3, 5; 2,3,3, 4; 3,3,3, 3;
  2261. }
  2262. };
  2263. // these tables were constructed automatically using a variant of the code
  2264. // below; however, they seem wrong, so who knows
  2265. static unsigned char stbvox_face_up_normal_012[4][4][4] =
  2266. {
  2267. {
  2268. { STBVF_u , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
  2269. { STBVF_wu , STBVF_nu , STBVF_ne_u, STBVF_ne_u, },
  2270. { STBVF_wu , STBVF_nw_u, STBVF_nu , STBVF_ne_u, },
  2271. { STBVF_wu , STBVF_nw_u, STBVF_nw_u, STBVF_nu , },
  2272. },{
  2273. { STBVF_su , STBVF_eu , STBVF_ne_u, STBVF_ne_u, },
  2274. { STBVF_sw_u, STBVF_u , STBVF_ne_u, STBVF_ne_u, },
  2275. { STBVF_sw_u, STBVF_wu , STBVF_nu , STBVF_ne_u, },
  2276. { STBVF_sw_u, STBVF_wu , STBVF_nw_u, STBVF_nu , },
  2277. },{
  2278. { STBVF_su , STBVF_eu , STBVF_eu , STBVF_ne_u, },
  2279. { STBVF_sw_u, STBVF_su , STBVF_eu , STBVF_ne_u, },
  2280. { STBVF_sw_u, STBVF_sw_u, STBVF_u , STBVF_ne_u, },
  2281. { STBVF_sw_u, STBVF_sw_u, STBVF_wu , STBVF_nu , },
  2282. },{
  2283. { STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
  2284. { STBVF_sw_u, STBVF_su , STBVF_eu , STBVF_eu , },
  2285. { STBVF_sw_u, STBVF_sw_u, STBVF_su , STBVF_eu , },
  2286. { STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_u , },
  2287. }
  2288. };
  2289. static unsigned char stbvox_face_up_normal_013[4][4][4] =
  2290. {
  2291. {
  2292. { STBVF_u , STBVF_eu , STBVF_eu , STBVF_eu , },
  2293. { STBVF_nw_u, STBVF_nu , STBVF_ne_u, STBVF_ne_u, },
  2294. { STBVF_nw_u, STBVF_nw_u, STBVF_nu , STBVF_ne_u, },
  2295. { STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, STBVF_nu , },
  2296. },{
  2297. { STBVF_su , STBVF_eu , STBVF_eu , STBVF_eu , },
  2298. { STBVF_wu , STBVF_u , STBVF_eu , STBVF_eu , },
  2299. { STBVF_nw_u, STBVF_nw_u, STBVF_nu , STBVF_ne_u, },
  2300. { STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, STBVF_nu , },
  2301. },{
  2302. { STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
  2303. { STBVF_sw_u, STBVF_su , STBVF_eu , STBVF_eu , },
  2304. { STBVF_wu , STBVF_wu , STBVF_u , STBVF_eu , },
  2305. { STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, STBVF_nu , },
  2306. },{
  2307. { STBVF_su , STBVF_su , STBVF_su , STBVF_eu , },
  2308. { STBVF_sw_u, STBVF_su , STBVF_su , STBVF_su , },
  2309. { STBVF_sw_u, STBVF_sw_u, STBVF_su , STBVF_eu , },
  2310. { STBVF_wu , STBVF_wu , STBVF_wu , STBVF_u , },
  2311. }
  2312. };
  2313. static unsigned char stbvox_face_up_normal_023[4][4][4] =
  2314. {
  2315. {
  2316. { STBVF_u , STBVF_nu , STBVF_nu , STBVF_nu , },
  2317. { STBVF_eu , STBVF_eu , STBVF_ne_u, STBVF_ne_u, },
  2318. { STBVF_su , STBVF_eu , STBVF_eu , STBVF_ne_u, },
  2319. { STBVF_eu , STBVF_eu , STBVF_eu , STBVF_eu , },
  2320. },{
  2321. { STBVF_wu , STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, },
  2322. { STBVF_su , STBVF_u , STBVF_nu , STBVF_nu , },
  2323. { STBVF_su , STBVF_eu , STBVF_eu , STBVF_ne_u, },
  2324. { STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
  2325. },{
  2326. { STBVF_wu , STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, },
  2327. { STBVF_sw_u, STBVF_wu , STBVF_nw_u, STBVF_nw_u, },
  2328. { STBVF_su , STBVF_su , STBVF_u , STBVF_nu , },
  2329. { STBVF_su , STBVF_su , STBVF_eu , STBVF_eu , },
  2330. },{
  2331. { STBVF_wu , STBVF_nw_u, STBVF_nw_u, STBVF_nw_u, },
  2332. { STBVF_sw_u, STBVF_wu , STBVF_nw_u, STBVF_nw_u, },
  2333. { STBVF_sw_u, STBVF_sw_u, STBVF_wu , STBVF_nw_u, },
  2334. { STBVF_su , STBVF_su , STBVF_su , STBVF_u , },
  2335. }
  2336. };
  2337. static unsigned char stbvox_face_up_normal_123[4][4][4] =
  2338. {
  2339. {
  2340. { STBVF_u , STBVF_nu , STBVF_nu , STBVF_nu , },
  2341. { STBVF_eu , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
  2342. { STBVF_eu , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
  2343. { STBVF_eu , STBVF_ne_u, STBVF_ne_u, STBVF_ne_u, },
  2344. },{
  2345. { STBVF_sw_u, STBVF_wu , STBVF_nw_u, STBVF_nw_u, },
  2346. { STBVF_su , STBVF_u , STBVF_nu , STBVF_nu , },
  2347. { STBVF_eu , STBVF_eu , STBVF_ne_u, STBVF_ne_u, },
  2348. { STBVF_eu , STBVF_eu , STBVF_ne_u, STBVF_ne_u, },
  2349. },{
  2350. { STBVF_sw_u, STBVF_sw_u, STBVF_wu , STBVF_nw_u, },
  2351. { STBVF_sw_u, STBVF_sw_u, STBVF_wu , STBVF_nw_u, },
  2352. { STBVF_su , STBVF_su , STBVF_u , STBVF_nu , },
  2353. { STBVF_su , STBVF_eu , STBVF_eu , STBVF_ne_u, },
  2354. },{
  2355. { STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_wu , },
  2356. { STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_wu , },
  2357. { STBVF_sw_u, STBVF_sw_u, STBVF_sw_u, STBVF_wu , },
  2358. { STBVF_su , STBVF_su , STBVF_su , STBVF_u , },
  2359. }
  2360. };
  2361. #endif
  2362. void stbvox_get_quad_vertex_pointer(stbvox_mesh_maker *mm, int mesh, stbvox_mesh_vertex **vertices, stbvox_mesh_face face)
  2363. {
  2364. char *p = mm->output_cur[mesh][0];
  2365. int step = mm->output_step[mesh][0];
  2366. // allocate a new quad from the mesh
  2367. vertices[0] = (stbvox_mesh_vertex *) p; p += step;
  2368. vertices[1] = (stbvox_mesh_vertex *) p; p += step;
  2369. vertices[2] = (stbvox_mesh_vertex *) p; p += step;
  2370. vertices[3] = (stbvox_mesh_vertex *) p; p += step;
  2371. mm->output_cur[mesh][0] = p;
  2372. // output the face
  2373. #ifdef STBVOX_ICONFIG_FACE_ATTRIBUTE
  2374. // write face as interleaved vertex data
  2375. *(stbvox_mesh_face *) (vertices[0]+1) = face;
  2376. *(stbvox_mesh_face *) (vertices[1]+1) = face;
  2377. *(stbvox_mesh_face *) (vertices[2]+1) = face;
  2378. *(stbvox_mesh_face *) (vertices[3]+1) = face;
  2379. #else
  2380. *(stbvox_mesh_face *) mm->output_cur[mesh][1] = face;
  2381. mm->output_cur[mesh][1] += 4;
  2382. #endif
  2383. }
  2384. void stbvox_make_mesh_for_face(stbvox_mesh_maker *mm, stbvox_rotate rot, int face, int v_off, stbvox_pos pos, stbvox_mesh_vertex vertbase, stbvox_mesh_vertex *face_coord, unsigned char mesh, int normal)
  2385. {
  2386. stbvox_mesh_face face_data = stbvox_compute_mesh_face_value(mm,rot,face,v_off, normal);
  2387. // still need to compute ao & texlerp for each vertex
  2388. // first compute texlerp into p1
  2389. stbvox_mesh_vertex p1[4] = { 0 };
  2390. #if defined(STBVOX_CONFIG_DOWN_TEXLERP_PACKED) && defined(STBVOX_CONFIG_UP_TEXLERP_PACKED)
  2391. #define STBVOX_USE_PACKED(f) ((f) == STBVOX_FACE_up || (f) == STBVOX_FACE_down)
  2392. #elif defined(STBVOX_CONFIG_UP_TEXLERP_PACKED)
  2393. #define STBVOX_USE_PACKED(f) ((f) == STBVOX_FACE_up )
  2394. #elif defined(STBVOX_CONFIG_DOWN_TEXLERP_PACKED)
  2395. #define STBVOX_USE_PACKED(f) ( (f) == STBVOX_FACE_down)
  2396. #endif
  2397. #if defined(STBVOX_CONFIG_DOWN_TEXLERP_PACKED) || defined(STBVOX_CONFIG_UP_TEXLERP_PACKED)
  2398. if (STBVOX_USE_PACKED(face)) {
  2399. if (!mm->input.packed_compact || 0==(mm->input.packed_compact[v_off]&16))
  2400. goto set_default;
  2401. p1[0] = (mm->input.packed_compact[v_off + mm->cube_vertex_offset[face][0]] >> 5);
  2402. p1[1] = (mm->input.packed_compact[v_off + mm->cube_vertex_offset[face][1]] >> 5);
  2403. p1[2] = (mm->input.packed_compact[v_off + mm->cube_vertex_offset[face][2]] >> 5);
  2404. p1[3] = (mm->input.packed_compact[v_off + mm->cube_vertex_offset[face][3]] >> 5);
  2405. p1[0] = stbvox_vertex_encode(0,0,0,0,p1[0]);
  2406. p1[1] = stbvox_vertex_encode(0,0,0,0,p1[1]);
  2407. p1[2] = stbvox_vertex_encode(0,0,0,0,p1[2]);
  2408. p1[3] = stbvox_vertex_encode(0,0,0,0,p1[3]);
  2409. goto skip;
  2410. }
  2411. #endif
  2412. if (mm->input.block_texlerp) {
  2413. stbvox_block_type bt = mm->input.blocktype[v_off];
  2414. unsigned char val = mm->input.block_texlerp[bt];
  2415. p1[0] = p1[1] = p1[2] = p1[3] = stbvox_vertex_encode(0,0,0,0,val);
  2416. } else if (mm->input.block_texlerp_face) {
  2417. stbvox_block_type bt = mm->input.blocktype[v_off];
  2418. unsigned char bt_face = STBVOX_ROTATE(face, rot.block);
  2419. unsigned char val = mm->input.block_texlerp_face[bt][bt_face];
  2420. p1[0] = p1[1] = p1[2] = p1[3] = stbvox_vertex_encode(0,0,0,0,val);
  2421. } else if (mm->input.texlerp_face3) {
  2422. unsigned char val = (mm->input.texlerp_face3[v_off] >> stbvox_face3_lerp[face]) & 7;
  2423. if (face >= STBVOX_FACE_up)
  2424. val = stbvox_face3_updown[val];
  2425. p1[0] = p1[1] = p1[2] = p1[3] = stbvox_vertex_encode(0,0,0,0,val);
  2426. } else if (mm->input.texlerp_simple) {
  2427. unsigned char val = mm->input.texlerp_simple[v_off];
  2428. unsigned char lerp_face = (val >> 2) & 7;
  2429. if (lerp_face == face) {
  2430. p1[0] = (mm->input.texlerp_simple[v_off + mm->cube_vertex_offset[face][0]] >> 5) & 7;
  2431. p1[1] = (mm->input.texlerp_simple[v_off + mm->cube_vertex_offset[face][1]] >> 5) & 7;
  2432. p1[2] = (mm->input.texlerp_simple[v_off + mm->cube_vertex_offset[face][2]] >> 5) & 7;
  2433. p1[3] = (mm->input.texlerp_simple[v_off + mm->cube_vertex_offset[face][3]] >> 5) & 7;
  2434. p1[0] = stbvox_vertex_encode(0,0,0,0,p1[0]);
  2435. p1[1] = stbvox_vertex_encode(0,0,0,0,p1[1]);
  2436. p1[2] = stbvox_vertex_encode(0,0,0,0,p1[2]);
  2437. p1[3] = stbvox_vertex_encode(0,0,0,0,p1[3]);
  2438. } else {
  2439. unsigned char base = stbvox_vert_lerp_for_simple[val&3];
  2440. p1[0] = p1[1] = p1[2] = p1[3] = stbvox_vertex_encode(0,0,0,0,base);
  2441. }
  2442. } else if (mm->input.texlerp) {
  2443. unsigned char facelerp = (mm->input.texlerp[v_off] >> stbvox_face_lerp[face]) & 3;
  2444. if (facelerp == STBVOX_TEXLERP_FACE_use_vert) {
  2445. if (mm->input.texlerp_vert3 && face != STBVOX_FACE_down) {
  2446. unsigned char shift = stbvox_vert3_lerp[face];
  2447. p1[0] = (mm->input.texlerp_vert3[mm->cube_vertex_offset[face][0]] >> shift) & 7;
  2448. p1[1] = (mm->input.texlerp_vert3[mm->cube_vertex_offset[face][1]] >> shift) & 7;
  2449. p1[2] = (mm->input.texlerp_vert3[mm->cube_vertex_offset[face][2]] >> shift) & 7;
  2450. p1[3] = (mm->input.texlerp_vert3[mm->cube_vertex_offset[face][3]] >> shift) & 7;
  2451. } else {
  2452. p1[0] = stbvox_vert_lerp_for_simple[mm->input.texlerp[mm->cube_vertex_offset[face][0]]>>6];
  2453. p1[1] = stbvox_vert_lerp_for_simple[mm->input.texlerp[mm->cube_vertex_offset[face][1]]>>6];
  2454. p1[2] = stbvox_vert_lerp_for_simple[mm->input.texlerp[mm->cube_vertex_offset[face][2]]>>6];
  2455. p1[3] = stbvox_vert_lerp_for_simple[mm->input.texlerp[mm->cube_vertex_offset[face][3]]>>6];
  2456. }
  2457. p1[0] = stbvox_vertex_encode(0,0,0,0,p1[0]);
  2458. p1[1] = stbvox_vertex_encode(0,0,0,0,p1[1]);
  2459. p1[2] = stbvox_vertex_encode(0,0,0,0,p1[2]);
  2460. p1[3] = stbvox_vertex_encode(0,0,0,0,p1[3]);
  2461. } else {
  2462. p1[0] = p1[1] = p1[2] = p1[3] = stbvox_vertex_encode(0,0,0,0,stbvox_vert_lerp_for_face_lerp[facelerp]);
  2463. }
  2464. } else {
  2465. #if defined(STBVOX_CONFIG_UP_TEXLERP_PACKED) || defined(STBVOX_CONFIG_DOWN_TEXLERP_PACKED)
  2466. set_default:
  2467. #endif
  2468. p1[0] = p1[1] = p1[2] = p1[3] = stbvox_vertex_encode(0,0,0,0,7); // @TODO make this configurable
  2469. }
  2470. #if defined(STBVOX_CONFIG_UP_TEXLERP_PACKED) || defined(STBVOX_CONFIG_DOWN_TEXLERP_PACKED)
  2471. skip:
  2472. #endif
  2473. // now compute lighting and store to vertices
  2474. {
  2475. stbvox_mesh_vertex *mv[4];
  2476. stbvox_get_quad_vertex_pointer(mm, mesh, mv, face_data);
  2477. if (mm->input.lighting) {
  2478. // @TODO: lighting at block centers, but not gathered, instead constant-per-face
  2479. if (mm->input.lighting_at_vertices) {
  2480. int i;
  2481. for (i=0; i < 4; ++i) {
  2482. *mv[i] = vertbase + face_coord[i]
  2483. + stbvox_vertex_encode(0,0,0,mm->input.lighting[v_off + mm->cube_vertex_offset[face][i]] & 63,0)
  2484. + p1[i];
  2485. }
  2486. } else {
  2487. unsigned char *amb = &mm->input.lighting[v_off];
  2488. int i,j;
  2489. #if defined(STBVOX_CONFIG_ROTATION_IN_LIGHTING) || defined(STBVOX_CONFIG_VHEIGHT_IN_LIGHTING)
  2490. #define STBVOX_GET_LIGHTING(light) ((light) & ~3)
  2491. #define STBVOX_LIGHTING_ROUNDOFF 8
  2492. #else
  2493. #define STBVOX_GET_LIGHTING(light) (light)
  2494. #define STBVOX_LIGHTING_ROUNDOFF 2
  2495. #endif
  2496. for (i=0; i < 4; ++i) {
  2497. // for each vertex, gather from the four neighbor blocks it's facing
  2498. unsigned char *vamb = &amb[mm->cube_vertex_offset[face][i]];
  2499. int total=0;
  2500. for (j=0; j < 4; ++j)
  2501. total += STBVOX_GET_LIGHTING(vamb[mm->vertex_gather_offset[face][j]]);
  2502. *mv[i] = vertbase + face_coord[i]
  2503. + stbvox_vertex_encode(0,0,0,(total+STBVOX_LIGHTING_ROUNDOFF)>>4,0)
  2504. + p1[i];
  2505. // >> 4 is because:
  2506. // >> 2 to divide by 4 to get average over 4 samples
  2507. // >> 2 because input is 8 bits, output is 6 bits
  2508. }
  2509. // @TODO: note that gathering baked *lighting*
  2510. // is different from gathering baked ao; baked ao can count
  2511. // solid blocks as 0 ao, but baked lighting wants average
  2512. // of non-blocked--not take average & treat blocked as 0. And
  2513. // we can't bake the right value into the solid blocks
  2514. // because they can have different lighting values on
  2515. // different sides. So we need to actually gather and
  2516. // then divide by 0..4 (which we can do with a table-driven
  2517. // multiply, or have an 'if' for the 3 case)
  2518. }
  2519. } else {
  2520. vertbase += stbvox_vertex_encode(0,0,0,63,0);
  2521. *mv[0] = vertbase + face_coord[0] + p1[0];
  2522. *mv[1] = vertbase + face_coord[1] + p1[1];
  2523. *mv[2] = vertbase + face_coord[2] + p1[2];
  2524. *mv[3] = vertbase + face_coord[3] + p1[3];
  2525. }
  2526. }
  2527. }
  2528. // get opposite-facing normal & texgen for opposite face, used to map up-facing vheight data to down-facing data
  2529. static unsigned char stbvox_reverse_face[STBVF_count] =
  2530. {
  2531. STBVF_w, STBVF_s, STBVF_e, STBVF_n, STBVF_d , STBVF_u , STBVF_wd, STBVF_wu,
  2532. 0, 0, 0, 0, STBVF_sw_d, STBVF_sw_u, STBVF_sd, STBVF_su,
  2533. 0, 0, 0, 0, STBVF_se_d, STBVF_se_u, STBVF_ed, STBVF_eu,
  2534. 0, 0, 0, 0, STBVF_ne_d, STBVF_ne_d, STBVF_nd, STBVF_nu
  2535. };
  2536. #ifndef STBVOX_CONFIG_OPTIMIZED_VHEIGHT
  2537. // render non-planar quads by splitting into two triangles, rendering each as a degenerate quad
  2538. static void stbvox_make_12_split_mesh_for_face(stbvox_mesh_maker *mm, stbvox_rotate rot, int face, int v_off, stbvox_pos pos, stbvox_mesh_vertex vertbase, stbvox_mesh_vertex *face_coord, unsigned char mesh, unsigned char *ht)
  2539. {
  2540. stbvox_mesh_vertex v[4];
  2541. unsigned char normal1 = stbvox_face_up_normal_012[ht[2]][ht[1]][ht[0]];
  2542. unsigned char normal2 = stbvox_face_up_normal_123[ht[3]][ht[2]][ht[1]];
  2543. if (face == STBVOX_FACE_down) {
  2544. normal1 = stbvox_reverse_face[normal1];
  2545. normal2 = stbvox_reverse_face[normal2];
  2546. }
  2547. // the floor side face_coord is stored in order NW,NE,SE,SW, but ht[] is stored SW,SE,NW,NE
  2548. v[0] = face_coord[2];
  2549. v[1] = face_coord[3];
  2550. v[2] = face_coord[0];
  2551. v[3] = face_coord[2];
  2552. stbvox_make_mesh_for_face(mm, rot, face, v_off, pos, vertbase, v, mesh, normal1);
  2553. v[1] = face_coord[0];
  2554. v[2] = face_coord[1];
  2555. stbvox_make_mesh_for_face(mm, rot, face, v_off, pos, vertbase, v, mesh, normal2);
  2556. }
  2557. static void stbvox_make_03_split_mesh_for_face(stbvox_mesh_maker *mm, stbvox_rotate rot, int face, int v_off, stbvox_pos pos, stbvox_mesh_vertex vertbase, stbvox_mesh_vertex *face_coord, unsigned char mesh, unsigned char *ht)
  2558. {
  2559. stbvox_mesh_vertex v[4];
  2560. unsigned char normal1 = stbvox_face_up_normal_013[ht[3]][ht[1]][ht[0]];
  2561. unsigned char normal2 = stbvox_face_up_normal_023[ht[3]][ht[2]][ht[0]];
  2562. if (face == STBVOX_FACE_down) {
  2563. normal1 = stbvox_reverse_face[normal1];
  2564. normal2 = stbvox_reverse_face[normal2];
  2565. }
  2566. v[0] = face_coord[1];
  2567. v[1] = face_coord[2];
  2568. v[2] = face_coord[3];
  2569. v[3] = face_coord[1];
  2570. stbvox_make_mesh_for_face(mm, rot, face, v_off, pos, vertbase, v, mesh, normal1);
  2571. v[1] = face_coord[3];
  2572. v[2] = face_coord[0];
  2573. stbvox_make_mesh_for_face(mm, rot, face, v_off, pos, vertbase, v, mesh, normal2); // this one is correct!
  2574. }
  2575. #endif
  2576. #ifndef STBVOX_CONFIG_PRECISION_Z
  2577. #define STBVOX_CONFIG_PRECISION_Z 1
  2578. #endif
  2579. // simple case for mesh generation: we have only solid and empty blocks
  2580. static void stbvox_make_mesh_for_block(stbvox_mesh_maker *mm, stbvox_pos pos, int v_off, stbvox_mesh_vertex *vmesh)
  2581. {
  2582. int ns_off = mm->y_stride_in_bytes;
  2583. int ew_off = mm->x_stride_in_bytes;
  2584. unsigned char *blockptr = &mm->input.blocktype[v_off];
  2585. stbvox_mesh_vertex basevert = stbvox_vertex_encode(pos.x, pos.y, pos.z << STBVOX_CONFIG_PRECISION_Z , 0,0);
  2586. stbvox_rotate rot = { 0,0,0,0 };
  2587. unsigned char simple_rot = 0;
  2588. unsigned char mesh = mm->default_mesh;
  2589. if (mm->input.selector)
  2590. mesh = mm->input.selector[v_off];
  2591. else if (mm->input.block_selector)
  2592. mesh = mm->input.block_selector[mm->input.blocktype[v_off]];
  2593. // check if we're going off the end
  2594. if (mm->output_cur[mesh][0] + mm->output_size[mesh][0]*6 > mm->output_end[mesh][0]) {
  2595. mm->full = 1;
  2596. return;
  2597. }
  2598. #ifdef STBVOX_CONFIG_ROTATION_IN_LIGHTING
  2599. simple_rot = mm->input.lighting[v_off] & 3;
  2600. #endif
  2601. if (mm->input.packed_compact)
  2602. simple_rot = mm->input.packed_compact[v_off] & 3;
  2603. if (blockptr[ 1]==0) {
  2604. rot.facerot = simple_rot;
  2605. stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_up , v_off, pos, basevert, vmesh+4*STBVOX_FACE_up, mesh, STBVOX_FACE_up);
  2606. }
  2607. if (blockptr[-1]==0) {
  2608. rot.facerot = (-simple_rot) & 3;
  2609. stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_down, v_off, pos, basevert, vmesh+4*STBVOX_FACE_down, mesh, STBVOX_FACE_down);
  2610. }
  2611. if (mm->input.rotate) {
  2612. unsigned char val = mm->input.rotate[v_off];
  2613. rot.block = (val >> 0) & 3;
  2614. rot.overlay = (val >> 2) & 3;
  2615. //rot.tex2 = (val >> 4) & 3;
  2616. rot.ecolor = (val >> 6) & 3;
  2617. } else {
  2618. rot.block = rot.overlay = rot.ecolor = simple_rot;
  2619. }
  2620. rot.facerot = 0;
  2621. if (blockptr[ ns_off]==0)
  2622. stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_north, v_off, pos, basevert, vmesh+4*STBVOX_FACE_north, mesh, STBVOX_FACE_north);
  2623. if (blockptr[-ns_off]==0)
  2624. stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_south, v_off, pos, basevert, vmesh+4*STBVOX_FACE_south, mesh, STBVOX_FACE_south);
  2625. if (blockptr[ ew_off]==0)
  2626. stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_east , v_off, pos, basevert, vmesh+4*STBVOX_FACE_east, mesh, STBVOX_FACE_east);
  2627. if (blockptr[-ew_off]==0)
  2628. stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_west , v_off, pos, basevert, vmesh+4*STBVOX_FACE_west, mesh, STBVOX_FACE_west);
  2629. }
  2630. // complex case for mesh generation: we have lots of different
  2631. // block types, and we don't want to generate faces of blocks
  2632. // if they're hidden by neighbors.
  2633. //
  2634. // we use lots of tables to determine this: we have a table
  2635. // which tells us what face type is generated for each type of
  2636. // geometry, and then a table that tells us whether that type
  2637. // is hidden by a neighbor.
  2638. static void stbvox_make_mesh_for_block_with_geo(stbvox_mesh_maker *mm, stbvox_pos pos, int v_off)
  2639. {
  2640. int ns_off = mm->y_stride_in_bytes;
  2641. int ew_off = mm->x_stride_in_bytes;
  2642. int visible_faces, visible_base;
  2643. unsigned char mesh;
  2644. // first gather the geometry info for this block and all neighbors
  2645. unsigned char bt, nbt[6];
  2646. unsigned char geo, ngeo[6];
  2647. unsigned char rot, nrot[6];
  2648. bt = mm->input.blocktype[v_off];
  2649. nbt[0] = mm->input.blocktype[v_off + ew_off];
  2650. nbt[1] = mm->input.blocktype[v_off + ns_off];
  2651. nbt[2] = mm->input.blocktype[v_off - ew_off];
  2652. nbt[3] = mm->input.blocktype[v_off - ns_off];
  2653. nbt[4] = mm->input.blocktype[v_off + 1];
  2654. nbt[5] = mm->input.blocktype[v_off - 1];
  2655. if (mm->input.geometry) {
  2656. int i;
  2657. geo = mm->input.geometry[v_off];
  2658. ngeo[0] = mm->input.geometry[v_off + ew_off];
  2659. ngeo[1] = mm->input.geometry[v_off + ns_off];
  2660. ngeo[2] = mm->input.geometry[v_off - ew_off];
  2661. ngeo[3] = mm->input.geometry[v_off - ns_off];
  2662. ngeo[4] = mm->input.geometry[v_off + 1];
  2663. ngeo[5] = mm->input.geometry[v_off - 1];
  2664. rot = (geo >> 4) & 3;
  2665. geo &= 15;
  2666. for (i=0; i < 6; ++i) {
  2667. nrot[i] = (ngeo[i] >> 4) & 3;
  2668. ngeo[i] &= 15;
  2669. }
  2670. } else {
  2671. int i;
  2672. assert(mm->input.block_geometry);
  2673. geo = mm->input.block_geometry[bt];
  2674. for (i=0; i < 6; ++i)
  2675. ngeo[i] = mm->input.block_geometry[nbt[i]];
  2676. if (mm->input.selector) {
  2677. #ifndef STBVOX_CONFIG_ROTATION_IN_LIGHTING
  2678. if (mm->input.packed_compact == NULL) {
  2679. rot = (mm->input.selector[v_off ] >> 4) & 3;
  2680. nrot[0] = (mm->input.selector[v_off + ew_off] >> 4) & 3;
  2681. nrot[1] = (mm->input.selector[v_off + ns_off] >> 4) & 3;
  2682. nrot[2] = (mm->input.selector[v_off - ew_off] >> 4) & 3;
  2683. nrot[3] = (mm->input.selector[v_off - ns_off] >> 4) & 3;
  2684. nrot[4] = (mm->input.selector[v_off + 1] >> 4) & 3;
  2685. nrot[5] = (mm->input.selector[v_off - 1] >> 4) & 3;
  2686. }
  2687. #endif
  2688. } else {
  2689. #ifndef STBVOX_CONFIG_ROTATION_IN_LIGHTING
  2690. if (mm->input.packed_compact == NULL) {
  2691. rot = (geo>>4)&3;
  2692. geo &= 15;
  2693. for (i=0; i < 6; ++i) {
  2694. nrot[i] = (ngeo[i]>>4)&3;
  2695. ngeo[i] &= 15;
  2696. }
  2697. }
  2698. #endif
  2699. }
  2700. }
  2701. #ifndef STBVOX_CONFIG_ROTATION_IN_LIGHTING
  2702. if (mm->input.packed_compact) {
  2703. rot = mm->input.packed_compact[rot] & 3;
  2704. nrot[0] = mm->input.packed_compact[v_off + ew_off] & 3;
  2705. nrot[1] = mm->input.packed_compact[v_off + ns_off] & 3;
  2706. nrot[2] = mm->input.packed_compact[v_off - ew_off] & 3;
  2707. nrot[3] = mm->input.packed_compact[v_off - ns_off] & 3;
  2708. nrot[4] = mm->input.packed_compact[v_off + 1] & 3;
  2709. nrot[5] = mm->input.packed_compact[v_off - 1] & 3;
  2710. }
  2711. #else
  2712. rot = mm->input.lighting[v_off] & 3;
  2713. nrot[0] = (mm->input.lighting[v_off + ew_off]) & 3;
  2714. nrot[1] = (mm->input.lighting[v_off + ns_off]) & 3;
  2715. nrot[2] = (mm->input.lighting[v_off - ew_off]) & 3;
  2716. nrot[3] = (mm->input.lighting[v_off - ns_off]) & 3;
  2717. nrot[4] = (mm->input.lighting[v_off + 1]) & 3;
  2718. nrot[5] = (mm->input.lighting[v_off - 1]) & 3;
  2719. #endif
  2720. if (geo == STBVOX_GEOM_transp) {
  2721. // transparency has a special rule: if the blocktype is the same,
  2722. // and the faces are compatible, then can hide them; otherwise,
  2723. // force them on
  2724. // Note that this means we don't support any transparentshapes other
  2725. // than solid blocks, since detecting them is too complicated. If
  2726. // you wanted to do something like minecraft water, you probably
  2727. // should just do that with a separate renderer anyway. (We don't
  2728. // support transparency sorting so you need to use alpha test
  2729. // anyway)
  2730. int i;
  2731. for (i=0; i < 6; ++i)
  2732. if (nbt[i] != bt) {
  2733. nbt[i] = 0;
  2734. ngeo[i] = STBVOX_GEOM_empty;
  2735. } else
  2736. ngeo[i] = STBVOX_GEOM_solid;
  2737. geo = STBVOX_GEOM_solid;
  2738. }
  2739. // now compute the face visibility
  2740. visible_base = stbvox_hasface[geo][rot];
  2741. // @TODO: assert(visible_base != 0); // we should have early-outted earlier in this case
  2742. visible_faces = 0;
  2743. // now, for every face that might be visible, check if neighbor hides it
  2744. if (visible_base & (1 << STBVOX_FACE_east)) {
  2745. int type = stbvox_facetype[ geo ][(STBVOX_FACE_east+ rot )&3];
  2746. int ntype = stbvox_facetype[ngeo[0]][(STBVOX_FACE_west+nrot[0])&3];
  2747. visible_faces |= ((stbvox_face_visible[type]) >> (ntype + 5 - STBVOX_FACE_east)) & (1 << STBVOX_FACE_east);
  2748. }
  2749. if (visible_base & (1 << STBVOX_FACE_north)) {
  2750. int type = stbvox_facetype[ geo ][(STBVOX_FACE_north+ rot )&3];
  2751. int ntype = stbvox_facetype[ngeo[1]][(STBVOX_FACE_south+nrot[1])&3];
  2752. visible_faces |= ((stbvox_face_visible[type]) >> (ntype + 5 - STBVOX_FACE_north)) & (1 << STBVOX_FACE_north);
  2753. }
  2754. if (visible_base & (1 << STBVOX_FACE_west)) {
  2755. int type = stbvox_facetype[ geo ][(STBVOX_FACE_west+ rot )&3];
  2756. int ntype = stbvox_facetype[ngeo[2]][(STBVOX_FACE_east+nrot[2])&3];
  2757. visible_faces |= ((stbvox_face_visible[type]) >> (ntype + 5 - STBVOX_FACE_west)) & (1 << STBVOX_FACE_west);
  2758. }
  2759. if (visible_base & (1 << STBVOX_FACE_south)) {
  2760. int type = stbvox_facetype[ geo ][(STBVOX_FACE_south+ rot )&3];
  2761. int ntype = stbvox_facetype[ngeo[3]][(STBVOX_FACE_north+nrot[3])&3];
  2762. visible_faces |= ((stbvox_face_visible[type]) >> (ntype + 5 - STBVOX_FACE_south)) & (1 << STBVOX_FACE_south);
  2763. }
  2764. if (visible_base & (1 << STBVOX_FACE_up)) {
  2765. int type = stbvox_facetype[ geo ][STBVOX_FACE_up];
  2766. int ntype = stbvox_facetype[ngeo[4]][STBVOX_FACE_down];
  2767. visible_faces |= ((stbvox_face_visible[type]) >> (ntype + 5 - STBVOX_FACE_up)) & (1 << STBVOX_FACE_up);
  2768. }
  2769. if (visible_base & (1 << STBVOX_FACE_down)) {
  2770. int type = stbvox_facetype[ geo ][STBVOX_FACE_down];
  2771. int ntype = stbvox_facetype[ngeo[5]][STBVOX_FACE_up];
  2772. visible_faces |= ((stbvox_face_visible[type]) >> (ntype + 5 - STBVOX_FACE_down)) & (1 << STBVOX_FACE_down);
  2773. }
  2774. if (geo == STBVOX_GEOM_force)
  2775. geo = STBVOX_GEOM_solid;
  2776. assert((geo == STBVOX_GEOM_crossed_pair) ? (visible_faces == 15) : 1);
  2777. // now we finally know for sure which faces are getting generated
  2778. if (visible_faces == 0)
  2779. return;
  2780. mesh = mm->default_mesh;
  2781. if (mm->input.selector)
  2782. mesh = mm->input.selector[v_off];
  2783. else if (mm->input.block_selector)
  2784. mesh = mm->input.block_selector[bt];
  2785. if (geo <= STBVOX_GEOM_ceil_slope_north_is_bottom) {
  2786. // this is the simple case, we can just use regular block gen with special vmesh calculated with vheight
  2787. stbvox_mesh_vertex basevert;
  2788. stbvox_mesh_vertex vmesh[6][4];
  2789. stbvox_rotate rotate = { 0,0,0,0 };
  2790. unsigned char simple_rot = rot;
  2791. int i;
  2792. // we only need to do this for the displayed faces, but it's easier
  2793. // to just do it up front; @OPTIMIZE check if it's faster to do it
  2794. // for visible faces only
  2795. for (i=0; i < 6*4; ++i) {
  2796. int vert = stbvox_vertex_selector[0][i];
  2797. vert = stbvox_rotate_vertex[vert][rot];
  2798. vmesh[0][i] = stbvox_vmesh_pre_vheight[0][i]
  2799. + stbvox_geometry_vheight[geo][vert];
  2800. }
  2801. basevert = stbvox_vertex_encode(pos.x, pos.y, pos.z << STBVOX_CONFIG_PRECISION_Z, 0,0);
  2802. if (mm->input.selector) {
  2803. mesh = mm->input.selector[v_off];
  2804. } else if (mm->input.block_selector)
  2805. mesh = mm->input.block_selector[bt];
  2806. // check if we're going off the end
  2807. if (mm->output_cur[mesh][0] + mm->output_size[mesh][0]*6 > mm->output_end[mesh][0]) {
  2808. mm->full = 1;
  2809. return;
  2810. }
  2811. if (geo >= STBVOX_GEOM_floor_slope_north_is_top) {
  2812. if (visible_faces & (1 << STBVOX_FACE_up)) {
  2813. int normal = geo == STBVOX_GEOM_floor_slope_north_is_top ? stbvox_floor_slope_for_rot[simple_rot] : STBVOX_FACE_up;
  2814. rotate.facerot = simple_rot;
  2815. stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_up , v_off, pos, basevert, vmesh[STBVOX_FACE_up], mesh, normal);
  2816. }
  2817. if (visible_faces & (1 << STBVOX_FACE_down)) {
  2818. int normal = geo == STBVOX_GEOM_ceil_slope_north_is_bottom ? stbvox_ceil_slope_for_rot[simple_rot] : STBVOX_FACE_down;
  2819. rotate.facerot = (-rotate.facerot) & 3;
  2820. stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_down, v_off, pos, basevert, vmesh[STBVOX_FACE_down], mesh, normal);
  2821. }
  2822. } else {
  2823. if (visible_faces & (1 << STBVOX_FACE_up)) {
  2824. rotate.facerot = simple_rot;
  2825. stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_up , v_off, pos, basevert, vmesh[STBVOX_FACE_up], mesh, STBVOX_FACE_up);
  2826. }
  2827. if (visible_faces & (1 << STBVOX_FACE_down)) {
  2828. rotate.facerot = (-rotate.facerot) & 3;
  2829. stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_down, v_off, pos, basevert, vmesh[STBVOX_FACE_down], mesh, STBVOX_FACE_down);
  2830. }
  2831. }
  2832. if (mm->input.rotate) {
  2833. unsigned char val = mm->input.rotate[v_off];
  2834. rotate.block = (val >> 0) & 3;
  2835. rotate.overlay = (val >> 2) & 3;
  2836. //rotate.tex2 = (val >> 4) & 3;
  2837. rotate.ecolor = (val >> 6) & 3;
  2838. } else {
  2839. rotate.block = rotate.overlay = rotate.ecolor = simple_rot;
  2840. }
  2841. rotate.facerot = 0;
  2842. if (visible_faces & (1 << STBVOX_FACE_north))
  2843. stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_north, v_off, pos, basevert, vmesh[STBVOX_FACE_north], mesh, STBVOX_FACE_north);
  2844. if (visible_faces & (1 << STBVOX_FACE_south))
  2845. stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_south, v_off, pos, basevert, vmesh[STBVOX_FACE_south], mesh, STBVOX_FACE_south);
  2846. if (visible_faces & (1 << STBVOX_FACE_east))
  2847. stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_east , v_off, pos, basevert, vmesh[STBVOX_FACE_east ], mesh, STBVOX_FACE_east);
  2848. if (visible_faces & (1 << STBVOX_FACE_west))
  2849. stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_west , v_off, pos, basevert, vmesh[STBVOX_FACE_west ], mesh, STBVOX_FACE_west);
  2850. }
  2851. if (geo >= STBVOX_GEOM_floor_vheight_03) {
  2852. // this case can also be generated with regular block gen with special vmesh,
  2853. // except:
  2854. // if we want to generate middle diagonal for 'weird' blocks
  2855. // it's more complicated to detect neighbor matchups
  2856. stbvox_mesh_vertex vmesh[6][4];
  2857. stbvox_mesh_vertex cube[8];
  2858. stbvox_mesh_vertex basevert;
  2859. stbvox_rotate rotate = { 0,0,0,0 };
  2860. unsigned char simple_rot = rot;
  2861. unsigned char ht[4];
  2862. int extreme;
  2863. // extract the heights
  2864. #ifdef STBVOX_CONFIG_VHEIGHT_IN_LIGHTING
  2865. ht[0] = mm->input.lighting[v_off ] & 3;
  2866. ht[1] = mm->input.lighting[v_off+ew_off ] & 3;
  2867. ht[2] = mm->input.lighting[v_off +ns_off] & 3;
  2868. ht[3] = mm->input.lighting[v_off+ew_off+ns_off] & 3;
  2869. #else
  2870. if (mm->input.vheight) {
  2871. unsigned char v = mm->input.vheight[v_off];
  2872. ht[0] = (v >> 0) & 3;
  2873. ht[1] = (v >> 2) & 3;
  2874. ht[2] = (v >> 4) & 3;
  2875. ht[3] = (v >> 6) & 3;
  2876. } else if (mm->input.block_vheight) {
  2877. unsigned char v = mm->input.block_vheight[bt];
  2878. unsigned char raw[4];
  2879. int i;
  2880. raw[0] = (v >> 0) & 3;
  2881. raw[1] = (v >> 2) & 3;
  2882. raw[2] = (v >> 4) & 3;
  2883. raw[3] = (v >> 6) & 3;
  2884. for (i=0; i < 4; ++i)
  2885. ht[i] = raw[stbvox_rotate_vertex[i][rot]];
  2886. } else if (mm->input.packed_compact) {
  2887. ht[0] = (mm->input.packed_compact[v_off ] >> 2) & 3;
  2888. ht[1] = (mm->input.packed_compact[v_off+ew_off ] >> 2) & 3;
  2889. ht[2] = (mm->input.packed_compact[v_off +ns_off] >> 2) & 3;
  2890. ht[3] = (mm->input.packed_compact[v_off+ew_off+ns_off] >> 2) & 3;
  2891. } else if (mm->input.geometry) {
  2892. ht[0] = mm->input.geometry[v_off ] >> 6;
  2893. ht[1] = mm->input.geometry[v_off+ew_off ] >> 6;
  2894. ht[2] = mm->input.geometry[v_off +ns_off] >> 6;
  2895. ht[3] = mm->input.geometry[v_off+ew_off+ns_off] >> 6;
  2896. } else {
  2897. assert(0);
  2898. }
  2899. #endif
  2900. // flag whether any sides go off the top of the block, which means
  2901. // our visible_faces test was wrong
  2902. extreme = (ht[0] == 3 || ht[1] == 3 || ht[2] == 3 || ht[3] == 3);
  2903. if (geo >= STBVOX_GEOM_ceil_vheight_03) {
  2904. cube[0] = stbvox_vertex_encode(0,0,ht[0],0,0);
  2905. cube[1] = stbvox_vertex_encode(0,0,ht[1],0,0);
  2906. cube[2] = stbvox_vertex_encode(0,0,ht[2],0,0);
  2907. cube[3] = stbvox_vertex_encode(0,0,ht[3],0,0);
  2908. cube[4] = stbvox_vertex_encode(0,0,2,0,0);
  2909. cube[5] = stbvox_vertex_encode(0,0,2,0,0);
  2910. cube[6] = stbvox_vertex_encode(0,0,2,0,0);
  2911. cube[7] = stbvox_vertex_encode(0,0,2,0,0);
  2912. } else {
  2913. cube[0] = stbvox_vertex_encode(0,0,0,0,0);
  2914. cube[1] = stbvox_vertex_encode(0,0,0,0,0);
  2915. cube[2] = stbvox_vertex_encode(0,0,0,0,0);
  2916. cube[3] = stbvox_vertex_encode(0,0,0,0,0);
  2917. cube[4] = stbvox_vertex_encode(0,0,ht[0],0,0);
  2918. cube[5] = stbvox_vertex_encode(0,0,ht[1],0,0);
  2919. cube[6] = stbvox_vertex_encode(0,0,ht[2],0,0);
  2920. cube[7] = stbvox_vertex_encode(0,0,ht[3],0,0);
  2921. }
  2922. if (!mm->input.vheight && mm->input.block_vheight) {
  2923. // @TODO: support block vheight here, I've forgotten what needs to be done specially
  2924. }
  2925. // build vertex mesh
  2926. {
  2927. int i;
  2928. for (i=0; i < 6*4; ++i) {
  2929. int vert = stbvox_vertex_selector[0][i];
  2930. vmesh[0][i] = stbvox_vmesh_pre_vheight[0][i]
  2931. + cube[vert];
  2932. }
  2933. }
  2934. basevert = stbvox_vertex_encode(pos.x, pos.y, pos.z << STBVOX_CONFIG_PRECISION_Z, 0,0);
  2935. // check if we're going off the end
  2936. if (mm->output_cur[mesh][0] + mm->output_size[mesh][0]*6 > mm->output_end[mesh][0]) {
  2937. mm->full = 1;
  2938. return;
  2939. }
  2940. // @TODO generate split faces
  2941. if (visible_faces & (1 << STBVOX_FACE_up)) {
  2942. if (geo >= STBVOX_GEOM_ceil_vheight_03)
  2943. // flat
  2944. stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_up , v_off, pos, basevert, vmesh[STBVOX_FACE_up], mesh, STBVOX_FACE_up);
  2945. else {
  2946. #ifndef STBVOX_CONFIG_OPTIMIZED_VHEIGHT
  2947. // check if it's non-planar
  2948. if (cube[5] + cube[6] != cube[4] + cube[7]) {
  2949. // not planar, split along diagonal and make degenerate quads
  2950. if (geo == STBVOX_GEOM_floor_vheight_03)
  2951. stbvox_make_03_split_mesh_for_face(mm, rotate, STBVOX_FACE_up, v_off, pos, basevert, vmesh[STBVOX_FACE_up], mesh, ht);
  2952. else
  2953. stbvox_make_12_split_mesh_for_face(mm, rotate, STBVOX_FACE_up, v_off, pos, basevert, vmesh[STBVOX_FACE_up], mesh, ht);
  2954. } else
  2955. stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_up , v_off, pos, basevert, vmesh[STBVOX_FACE_up], mesh, stbvox_planar_face_up_normal[ht[2]][ht[1]][ht[0]]);
  2956. #else
  2957. stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_up , v_off, pos, basevert, vmesh[STBVOX_FACE_up], mesh, stbvox_optimized_face_up_normal[ht[3]][ht[2]][ht[1]][ht[0]]);
  2958. #endif
  2959. }
  2960. }
  2961. if (visible_faces & (1 << STBVOX_FACE_down)) {
  2962. if (geo < STBVOX_GEOM_ceil_vheight_03)
  2963. // flat
  2964. stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_down, v_off, pos, basevert, vmesh[STBVOX_FACE_down], mesh, STBVOX_FACE_down);
  2965. else {
  2966. #ifndef STBVOX_CONFIG_OPTIMIZED_VHEIGHT
  2967. // check if it's non-planar
  2968. if (cube[1] + cube[2] != cube[0] + cube[3]) {
  2969. // not planar, split along diagonal and make degenerate quads
  2970. if (geo == STBVOX_GEOM_ceil_vheight_03)
  2971. stbvox_make_03_split_mesh_for_face(mm, rotate, STBVOX_FACE_down, v_off, pos, basevert, vmesh[STBVOX_FACE_down], mesh, ht);
  2972. else
  2973. stbvox_make_12_split_mesh_for_face(mm, rotate, STBVOX_FACE_down, v_off, pos, basevert, vmesh[STBVOX_FACE_down], mesh, ht);
  2974. } else
  2975. stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_down, v_off, pos, basevert, vmesh[STBVOX_FACE_down], mesh, stbvox_reverse_face[stbvox_planar_face_up_normal[ht[2]][ht[1]][ht[0]]]);
  2976. #else
  2977. stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_down, v_off, pos, basevert, vmesh[STBVOX_FACE_down], mesh, stbvox_reverse_face[stbvox_optimized_face_up_normal[ht[3]][ht[2]][ht[1]][ht[0]]]);
  2978. #endif
  2979. }
  2980. }
  2981. if (mm->input.rotate) {
  2982. unsigned char val = mm->input.rotate[v_off];
  2983. rotate.block = (val >> 0) & 3;
  2984. rotate.overlay = (val >> 2) & 3;
  2985. //rotate.tex2 = (val >> 4) & 3;
  2986. rotate.ecolor = (val >> 6) & 3;
  2987. } else if (mm->input.selector) {
  2988. rotate.block = rotate.overlay = rotate.ecolor = simple_rot;
  2989. }
  2990. if ((visible_faces & (1 << STBVOX_FACE_north)) || (extreme && (ht[2] == 3 || ht[3] == 3)))
  2991. stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_north, v_off, pos, basevert, vmesh[STBVOX_FACE_north], mesh, STBVOX_FACE_north);
  2992. if ((visible_faces & (1 << STBVOX_FACE_south)) || (extreme && (ht[0] == 3 || ht[1] == 3)))
  2993. stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_south, v_off, pos, basevert, vmesh[STBVOX_FACE_south], mesh, STBVOX_FACE_south);
  2994. if ((visible_faces & (1 << STBVOX_FACE_east)) || (extreme && (ht[1] == 3 || ht[3] == 3)))
  2995. stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_east , v_off, pos, basevert, vmesh[STBVOX_FACE_east ], mesh, STBVOX_FACE_east);
  2996. if ((visible_faces & (1 << STBVOX_FACE_west)) || (extreme && (ht[0] == 3 || ht[2] == 3)))
  2997. stbvox_make_mesh_for_face(mm, rotate, STBVOX_FACE_west , v_off, pos, basevert, vmesh[STBVOX_FACE_west ], mesh, STBVOX_FACE_west);
  2998. }
  2999. if (geo == STBVOX_GEOM_crossed_pair) {
  3000. // this can be generated with a special vmesh
  3001. stbvox_mesh_vertex basevert = stbvox_vertex_encode(pos.x, pos.y, pos.z << STBVOX_CONFIG_PRECISION_Z , 0,0);
  3002. unsigned char simple_rot=0;
  3003. stbvox_rotate rot = { 0,0,0,0 };
  3004. unsigned char mesh = mm->default_mesh;
  3005. if (mm->input.selector) {
  3006. mesh = mm->input.selector[v_off];
  3007. simple_rot = mesh >> 4;
  3008. mesh &= 15;
  3009. }
  3010. if (mm->input.block_selector) {
  3011. mesh = mm->input.block_selector[bt];
  3012. }
  3013. // check if we're going off the end
  3014. if (mm->output_cur[mesh][0] + mm->output_size[mesh][0]*4 > mm->output_end[mesh][0]) {
  3015. mm->full = 1;
  3016. return;
  3017. }
  3018. if (mm->input.rotate) {
  3019. unsigned char val = mm->input.rotate[v_off];
  3020. rot.block = (val >> 0) & 3;
  3021. rot.overlay = (val >> 2) & 3;
  3022. //rot.tex2 = (val >> 4) & 3;
  3023. rot.ecolor = (val >> 6) & 3;
  3024. } else if (mm->input.selector) {
  3025. rot.block = rot.overlay = rot.ecolor = simple_rot;
  3026. }
  3027. rot.facerot = 0;
  3028. stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_north, v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_north], mesh, STBVF_ne_u_cross);
  3029. stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_south, v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_south], mesh, STBVF_sw_u_cross);
  3030. stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_east , v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_east ], mesh, STBVF_se_u_cross);
  3031. stbvox_make_mesh_for_face(mm, rot, STBVOX_FACE_west , v_off, pos, basevert, stbvox_vmesh_crossed_pair[STBVOX_FACE_west ], mesh, STBVF_nw_u_cross);
  3032. }
  3033. // @TODO
  3034. // STBVOX_GEOM_floor_slope_north_is_top_as_wall,
  3035. // STBVOX_GEOM_ceil_slope_north_is_bottom_as_wall,
  3036. }
  3037. static void stbvox_make_mesh_for_column(stbvox_mesh_maker *mm, int x, int y, int z0)
  3038. {
  3039. stbvox_pos pos;
  3040. int v_off = x * mm->x_stride_in_bytes + y * mm->y_stride_in_bytes;
  3041. int ns_off = mm->y_stride_in_bytes;
  3042. int ew_off = mm->x_stride_in_bytes;
  3043. pos.x = x;
  3044. pos.y = y;
  3045. pos.z = 0;
  3046. if (mm->input.geometry) {
  3047. unsigned char *bt = mm->input.blocktype + v_off;
  3048. unsigned char *geo = mm->input.geometry + v_off;
  3049. int z;
  3050. for (z=z0; z < mm->z1; ++z) {
  3051. if (bt[z] && ( !bt[z+ns_off] || !STBVOX_GET_GEO(geo[z+ns_off]) || !bt[z-ns_off] || !STBVOX_GET_GEO(geo[z-ns_off])
  3052. || !bt[z+ew_off] || !STBVOX_GET_GEO(geo[z+ew_off]) || !bt[z-ew_off] || !STBVOX_GET_GEO(geo[z-ew_off])
  3053. || !bt[z-1] || !STBVOX_GET_GEO(geo[z-1]) || !bt[z+1] || !STBVOX_GET_GEO(geo[z+1])))
  3054. { // TODO check up and down
  3055. pos.z = z;
  3056. stbvox_make_mesh_for_block_with_geo(mm, pos, v_off+z);
  3057. if (mm->full) {
  3058. mm->cur_z = z;
  3059. return;
  3060. }
  3061. }
  3062. }
  3063. } else if (mm->input.block_geometry) {
  3064. int z;
  3065. unsigned char *bt = mm->input.blocktype + v_off;
  3066. unsigned char *geo = mm->input.block_geometry;
  3067. for (z=z0; z < mm->z1; ++z) {
  3068. if (bt[z] && ( geo[bt[z+ns_off]] != STBVOX_GEOM_solid
  3069. || geo[bt[z-ns_off]] != STBVOX_GEOM_solid
  3070. || geo[bt[z+ew_off]] != STBVOX_GEOM_solid
  3071. || geo[bt[z-ew_off]] != STBVOX_GEOM_solid
  3072. || geo[bt[z-1]] != STBVOX_GEOM_solid
  3073. || geo[bt[z+1]] != STBVOX_GEOM_solid))
  3074. {
  3075. pos.z = z;
  3076. stbvox_make_mesh_for_block_with_geo(mm, pos, v_off+z);
  3077. if (mm->full) {
  3078. mm->cur_z = z;
  3079. return;
  3080. }
  3081. }
  3082. }
  3083. } else {
  3084. unsigned char *bt = mm->input.blocktype + v_off;
  3085. int z;
  3086. #if STBVOX_CONFIG_PRECISION_Z == 1
  3087. stbvox_mesh_vertex *vmesh = stbvox_vmesh_delta_half_z[0];
  3088. #else
  3089. stbvox_mesh_vertex *vmesh = stbvox_vmesh_delta_normal[0];
  3090. #endif
  3091. for (z=z0; z < mm->z1; ++z) {
  3092. // if it's solid and at least one neighbor isn't solid
  3093. if (bt[z] && (!bt[z+ns_off] || !bt[z-ns_off] || !bt[z+ew_off] || !bt[z-ew_off] || !bt[z-1] || !bt[z+1])) {
  3094. pos.z = z;
  3095. stbvox_make_mesh_for_block(mm, pos, v_off+z, vmesh);
  3096. if (mm->full) {
  3097. mm->cur_z = z;
  3098. return;
  3099. }
  3100. }
  3101. }
  3102. }
  3103. }
  3104. static void stbvox_bring_up_to_date(stbvox_mesh_maker *mm)
  3105. {
  3106. if (mm->config_dirty) {
  3107. int i;
  3108. #ifdef STBVOX_ICONFIG_FACE_ATTRIBUTE
  3109. mm->num_mesh_slots = 1;
  3110. for (i=0; i < STBVOX_MAX_MESHES; ++i) {
  3111. mm->output_size[i][0] = 32;
  3112. mm->output_step[i][0] = 8;
  3113. }
  3114. #else
  3115. mm->num_mesh_slots = 2;
  3116. for (i=0; i < STBVOX_MAX_MESHES; ++i) {
  3117. mm->output_size[i][0] = 16;
  3118. mm->output_step[i][0] = 4;
  3119. mm->output_size[i][1] = 4;
  3120. mm->output_step[i][1] = 4;
  3121. }
  3122. #endif
  3123. mm->config_dirty = 0;
  3124. }
  3125. }
  3126. int stbvox_make_mesh(stbvox_mesh_maker *mm)
  3127. {
  3128. int x,y;
  3129. stbvox_bring_up_to_date(mm);
  3130. mm->full = 0;
  3131. if (mm->cur_x > mm->x0 || mm->cur_y > mm->y0 || mm->cur_z > mm->z0) {
  3132. stbvox_make_mesh_for_column(mm, mm->cur_x, mm->cur_y, mm->cur_z);
  3133. if (mm->full)
  3134. return 0;
  3135. ++mm->cur_y;
  3136. while (mm->cur_y < mm->y1 && !mm->full) {
  3137. stbvox_make_mesh_for_column(mm, mm->cur_x, mm->cur_y, mm->z0);
  3138. if (mm->full)
  3139. return 0;
  3140. ++mm->cur_y;
  3141. }
  3142. ++mm->cur_x;
  3143. }
  3144. for (x=mm->cur_x; x < mm->x1; ++x) {
  3145. for (y=mm->y0; y < mm->y1; ++y) {
  3146. stbvox_make_mesh_for_column(mm, x, y, mm->z0);
  3147. if (mm->full) {
  3148. mm->cur_x = x;
  3149. mm->cur_y = y;
  3150. return 0;
  3151. }
  3152. }
  3153. }
  3154. return 1;
  3155. }
  3156. void stbvox_init_mesh_maker(stbvox_mesh_maker *mm)
  3157. {
  3158. memset(mm, 0, sizeof(*mm));
  3159. stbvox_build_default_palette();
  3160. mm->config_dirty = 1;
  3161. mm->default_mesh = 0;
  3162. }
  3163. int stbvox_get_buffer_count(stbvox_mesh_maker *mm)
  3164. {
  3165. stbvox_bring_up_to_date(mm);
  3166. return mm->num_mesh_slots;
  3167. }
  3168. int stbvox_get_buffer_size_per_quad(stbvox_mesh_maker *mm, int n)
  3169. {
  3170. return mm->output_size[0][n];
  3171. }
  3172. void stbvox_reset_buffers(stbvox_mesh_maker *mm)
  3173. {
  3174. int i;
  3175. for (i=0; i < STBVOX_MAX_MESHES*STBVOX_MAX_MESH_SLOTS; ++i) {
  3176. mm->output_cur[0][i] = 0;
  3177. mm->output_buffer[0][i] = 0;
  3178. }
  3179. }
  3180. void stbvox_set_buffer(stbvox_mesh_maker *mm, int mesh, int slot, void *buffer, size_t len)
  3181. {
  3182. int i;
  3183. stbvox_bring_up_to_date(mm);
  3184. mm->output_buffer[mesh][slot] = (char *) buffer;
  3185. mm->output_cur [mesh][slot] = (char *) buffer;
  3186. mm->output_len [mesh][slot] = (int) len;
  3187. mm->output_end [mesh][slot] = (char *) buffer + len;
  3188. for (i=0; i < STBVOX_MAX_MESH_SLOTS; ++i) {
  3189. if (mm->output_buffer[mesh][i]) {
  3190. assert(mm->output_len[mesh][i] / mm->output_size[mesh][i] == mm->output_len[mesh][slot] / mm->output_size[mesh][slot]);
  3191. }
  3192. }
  3193. }
  3194. void stbvox_set_default_mesh(stbvox_mesh_maker *mm, int mesh)
  3195. {
  3196. mm->default_mesh = mesh;
  3197. }
  3198. int stbvox_get_quad_count(stbvox_mesh_maker *mm, int mesh)
  3199. {
  3200. return (int) ((mm->output_cur[mesh][0] - mm->output_buffer[mesh][0]) / mm->output_size[mesh][0]);
  3201. }
  3202. stbvox_input_description *stbvox_get_input_description(stbvox_mesh_maker *mm)
  3203. {
  3204. return &mm->input;
  3205. }
  3206. void stbvox_set_input_range(stbvox_mesh_maker *mm, int x0, int y0, int z0, int x1, int y1, int z1)
  3207. {
  3208. mm->x0 = x0;
  3209. mm->y0 = y0;
  3210. mm->z0 = z0;
  3211. mm->x1 = x1;
  3212. mm->y1 = y1;
  3213. mm->z1 = z1;
  3214. mm->cur_x = x0;
  3215. mm->cur_y = y0;
  3216. mm->cur_z = z0;
  3217. // @TODO validate that this range is representable in this mode
  3218. }
  3219. void stbvox_get_transform(stbvox_mesh_maker *mm, float transform[3][3])
  3220. {
  3221. // scale
  3222. transform[0][0] = 1.0;
  3223. transform[0][1] = 1.0;
  3224. #if STBVOX_CONFIG_PRECISION_Z==1
  3225. transform[0][2] = 0.5f;
  3226. #else
  3227. transform[0][2] = 1.0f;
  3228. #endif
  3229. // translation
  3230. transform[1][0] = (float) (mm->pos_x);
  3231. transform[1][1] = (float) (mm->pos_y);
  3232. transform[1][2] = (float) (mm->pos_z);
  3233. // texture coordinate projection translation
  3234. transform[2][0] = (float) (mm->pos_x & 255); // @TODO depends on max texture scale
  3235. transform[2][1] = (float) (mm->pos_y & 255);
  3236. transform[2][2] = (float) (mm->pos_z & 255);
  3237. }
  3238. void stbvox_get_bounds(stbvox_mesh_maker *mm, float bounds[2][3])
  3239. {
  3240. bounds[0][0] = (float) (mm->pos_x + mm->x0);
  3241. bounds[0][1] = (float) (mm->pos_y + mm->y0);
  3242. bounds[0][2] = (float) (mm->pos_z + mm->z0);
  3243. bounds[1][0] = (float) (mm->pos_x + mm->x1);
  3244. bounds[1][1] = (float) (mm->pos_y + mm->y1);
  3245. bounds[1][2] = (float) (mm->pos_z + mm->z1);
  3246. }
  3247. void stbvox_set_mesh_coordinates(stbvox_mesh_maker *mm, int x, int y, int z)
  3248. {
  3249. mm->pos_x = x;
  3250. mm->pos_y = y;
  3251. mm->pos_z = z;
  3252. }
  3253. void stbvox_set_input_stride(stbvox_mesh_maker *mm, int x_stride_in_bytes, int y_stride_in_bytes)
  3254. {
  3255. int f,v;
  3256. mm->x_stride_in_bytes = x_stride_in_bytes;
  3257. mm->y_stride_in_bytes = y_stride_in_bytes;
  3258. for (f=0; f < 6; ++f) {
  3259. for (v=0; v < 4; ++v) {
  3260. mm->cube_vertex_offset[f][v] = stbvox_vertex_vector[f][v][0] * mm->x_stride_in_bytes
  3261. + stbvox_vertex_vector[f][v][1] * mm->y_stride_in_bytes
  3262. + stbvox_vertex_vector[f][v][2] ;
  3263. mm->vertex_gather_offset[f][v] = (stbvox_vertex_vector[f][v][0]-1) * mm->x_stride_in_bytes
  3264. + (stbvox_vertex_vector[f][v][1]-1) * mm->y_stride_in_bytes
  3265. + (stbvox_vertex_vector[f][v][2]-1) ;
  3266. }
  3267. }
  3268. }
  3269. /////////////////////////////////////////////////////////////////////////////
  3270. //
  3271. // offline computation of tables
  3272. //
  3273. #if 0
  3274. // compute optimized vheight table
  3275. static char *normal_names[32] =
  3276. {
  3277. 0,0,0,0,"u ",0, "eu ",0,
  3278. 0,0,0,0,"ne_u",0, "nu ",0,
  3279. 0,0,0,0,"nw_u",0, "wu ",0,
  3280. 0,0,0,0,"sw_u",0, "su ",0,
  3281. };
  3282. static char *find_best_normal(float x, float y, float z)
  3283. {
  3284. int best_slot = 4;
  3285. float best_dot = 0;
  3286. int i;
  3287. for (i=0; i < 32; ++i) {
  3288. if (normal_names[i]) {
  3289. float dot = x * stbvox_default_normals[i][0] + y * stbvox_default_normals[i][1] + z * stbvox_default_normals[i][2];
  3290. if (dot > best_dot) {
  3291. best_dot = dot;
  3292. best_slot = i;
  3293. }
  3294. }
  3295. }
  3296. return normal_names[best_slot];
  3297. }
  3298. int main(int argc, char **argv)
  3299. {
  3300. int sw,se,nw,ne;
  3301. for (ne=0; ne < 4; ++ne) {
  3302. for (nw=0; nw < 4; ++nw) {
  3303. for (se=0; se < 4; ++se) {
  3304. printf(" { ");
  3305. for (sw=0; sw < 4; ++sw) {
  3306. float x = (float) (nw + sw - ne - se);
  3307. float y = (float) (sw + se - nw - ne);
  3308. float z = 2;
  3309. printf("STBVF_%s, ", find_best_normal(x,y,z));
  3310. }
  3311. printf("},\n");
  3312. }
  3313. }
  3314. }
  3315. return 0;
  3316. }
  3317. #endif
  3318. // @TODO
  3319. //
  3320. // - test API for texture rotation on side faces
  3321. // - API for texture rotation on top & bottom
  3322. // - better culling of vheight faces with vheight neighbors
  3323. // - better culling of non-vheight faces with vheight neighbors
  3324. // - gather vertex lighting from slopes correctly
  3325. // - better support texture edge_clamp: currently if you fall
  3326. // exactly on 1.0 you get wrapped incorrectly; this is rare, but
  3327. // can avoid: compute texcoords in vertex shader, offset towards
  3328. // center before modding, need 2 bits per vertex to know offset direction)
  3329. // - other mesh modes (10,6,4-byte quads)
  3330. //
  3331. //
  3332. // With TexBuffer for the fixed vertex data, we can actually do
  3333. // minecrafty non-blocks like stairs -- we still probably only
  3334. // want 256 or so, so we can't do the equivalent of all the vheight
  3335. // combos, but that's ok. The 256 includes baked rotations, but only
  3336. // some of them need it, and lots of block types share some faces.
  3337. //
  3338. // mode 5 (6 bytes): mode 6 (6 bytes)
  3339. // x:7 x:6
  3340. // y:7 y:6
  3341. // z:6 z:6
  3342. // tex1:8 tex1:8
  3343. // tex2:8 tex2:7
  3344. // color:8 color:8
  3345. // face:4 face:7
  3346. //
  3347. //
  3348. // side faces (all x4) top&bottom faces (2x) internal faces (1x)
  3349. // 1 regular 1 regular
  3350. // 2 slabs 2
  3351. // 8 stairs 4 stairs 16
  3352. // 4 diag side 8
  3353. // 4 upper diag side 8
  3354. // 4 lower diag side 8
  3355. // 4 crossed pairs
  3356. //
  3357. // 23*4 + 5*4 + 46
  3358. // == 92 + 20 + 46 = 158
  3359. //
  3360. // Must drop 30 of them to fit in 7 bits:
  3361. // ceiling half diagonals: 16+8 = 24
  3362. // Need to get rid of 6 more.
  3363. // ceiling diagonals: 8+4 = 12
  3364. // This brings it to 122, so can add a crossed-pair variant.
  3365. // (diagonal and non-diagonal, or randomly offset)
  3366. // Or carpet, which would be 5 more.
  3367. //
  3368. //
  3369. // Mode 4 (10 bytes):
  3370. // v: z:2,light:6
  3371. // f: x:6,y:6,z:7, t1:8,t2:8,c:8,f:5
  3372. //
  3373. // Mode ? (10 bytes)
  3374. // v: xyz:5 (27 values), light:3
  3375. // f: x:7,y:7,z:6, t1:8,t2:8,c:8,f:4
  3376. // (v: x:2,y:2,z:2,light:2)
  3377. #endif // STB_VOXEL_RENDER_IMPLEMENTATION
  3378. /*
  3379. ------------------------------------------------------------------------------
  3380. This software is available under 2 licenses -- choose whichever you prefer.
  3381. ------------------------------------------------------------------------------
  3382. ALTERNATIVE A - MIT License
  3383. Copyright (c) 2017 Sean Barrett
  3384. Permission is hereby granted, free of charge, to any person obtaining a copy of
  3385. this software and associated documentation files (the "Software"), to deal in
  3386. the Software without restriction, including without limitation the rights to
  3387. use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  3388. of the Software, and to permit persons to whom the Software is furnished to do
  3389. so, subject to the following conditions:
  3390. The above copyright notice and this permission notice shall be included in all
  3391. copies or substantial portions of the Software.
  3392. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  3393. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  3394. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  3395. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  3396. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  3397. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  3398. SOFTWARE.
  3399. ------------------------------------------------------------------------------
  3400. ALTERNATIVE B - Public Domain (www.unlicense.org)
  3401. This is free and unencumbered software released into the public domain.
  3402. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
  3403. software, either in source code form or as a compiled binary, for any purpose,
  3404. commercial or non-commercial, and by any means.
  3405. In jurisdictions that recognize copyright laws, the author or authors of this
  3406. software dedicate any and all copyright interest in the software to the public
  3407. domain. We make this dedication for the benefit of the public at large and to
  3408. the detriment of our heirs and successors. We intend this dedication to be an
  3409. overt act of relinquishment in perpetuity of all present and future rights to
  3410. this software under copyright law.
  3411. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  3412. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  3413. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  3414. AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  3415. ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  3416. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  3417. ------------------------------------------------------------------------------
  3418. */