graphics.bmx 83 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307
  1. '
  2. ' BlitzMax port, 2015 Bruce A Henderson
  3. '
  4. ' Copyright (c) 2015 Mark Sibly
  5. '
  6. ' This software is provided 'as-is', without any express or implied
  7. ' warranty. In no event will the authors be held liable for any damages
  8. ' arising from the use of this software.
  9. '
  10. ' Permission is granted to anyone to use this software for any purpose,
  11. ' including commercial applications, and to alter it and redistribute it
  12. ' freely, subject to the following restrictions:
  13. '
  14. ' 1. The origin of this software must not be misrepresented; you must not
  15. ' claim that you wrote the original software. If you use this software
  16. ' in a product, an acknowledgement in the product documentation would be
  17. ' appreciated but is not required.
  18. ' 2. Altered source versions must be plainly marked as such, and must not be
  19. ' misrepresented as being the original software.
  20. ' 3. This notice may not be removed or altered from any source distribution.
  21. '
  22. SuperStrict
  23. 'Framework brl.standardio
  24. Import brl.bank
  25. Import brl.map
  26. Import brl.ramstream
  27. Import brl.pixmap
  28. Import brl.filesystem
  29. Import brl.system
  30. Import brl.Graphics
  31. Import "math3d.bmx"
  32. Import "glutil.bmx"
  33. Import "glslparser.bmx"
  34. Import "maps.bmx"
  35. Incbin "data/mojo2_font.png"
  36. Incbin "data/mojo2_program.glsl"
  37. Incbin "data/mojo2_fastshader.glsl"
  38. Incbin "data/mojo2_bumpshader.glsl"
  39. Incbin "data/mojo2_matteshader.glsl"
  40. Incbin "data/mojo2_shadowshader.glsl"
  41. Incbin "data/mojo2_lightmapshader.glsl"
  42. Private
  43. Global _inited:Int
  44. Global mainShader:String
  45. Global _fastShader:TShader
  46. Global _bumpShader:TShader
  47. Global _matteShader:TShader
  48. Global _shadowShader:TShader
  49. Global _lightMapShader:TShader
  50. Global defaultFont:TFont
  51. Global _defaultShader:TShader
  52. Global freeOps:TDrawOpStack=New TDrawOpStack
  53. Global nullOp:TDrawOp=New TDrawOp
  54. Global defaultFbo:Int
  55. Global tmpMat2d:Float[6]
  56. Global tmpMat3d:Float[16]
  57. Global tmpMat3d2:Float[16]
  58. Global flipYMatrix:Float[]=Mat4New()
  59. Global vbosSeq:Int
  60. 'shader params
  61. Global rs_projMatrix:Float[]=Mat4New()
  62. Global rs_modelViewMatrix:Float[]=Mat4New()
  63. Global rs_modelViewProjMatrix:Float[]=Mat4New()
  64. Global rs_clipPosScale:Float[]=[1.0,1.0,1.0,1.0]
  65. Global rs_globalColor:Float[]=[1.0,1.0,1.0,1.0]
  66. Global rs_numLights:Int
  67. Global rs_fogColor:Float[]=[0.0,0.0,0.0,0.0]
  68. Global rs_ambientLight:Float[]=[0.0,0.0,0.0,1.0]
  69. Global rs_lightColors:Float[MAX_LIGHTS*4]
  70. Global rs_lightVectors:Float[MAX_LIGHTS*4]
  71. Global rs_shadowTexture:TTexture
  72. Global rs_program:TGLProgram
  73. Global rs_material:TMaterial
  74. Global rs_blend:Int=-1
  75. Global rs_vbo:Int
  76. Global rs_ibo:Int
  77. Const VBO_USAGE:Int=GL_STREAM_DRAW
  78. Const VBO_ORPHANING_ENABLED:Int=False
  79. Const MAX_LIGHTS:Int=4
  80. Const BYTES_PER_VERTEX:Int=28
  81. 'can really be anything <64K (due to 16bit indices) but this keeps total VBO size<64K, and making it bigger doesn't seem to improve performance much.
  82. Const MAX_VERTICES:Int=65536/BYTES_PER_VERTEX
  83. Const MAX_QUADS:Int=MAX_VERTICES/4
  84. Const MAX_QUAD_INDICES:Int=MAX_QUADS*6
  85. Const PRIM_VBO_SIZE:Int=MAX_VERTICES*BYTES_PER_VERTEX
  86. Function IsPow2:Int( sz:Int )
  87. Return (sz & (sz-1))=0
  88. End Function
  89. Public
  90. Type TLightData
  91. Field kind:Int=0
  92. Field color:Float[]=[1.0,1.0,1.0,1.0]
  93. Field position:Float[]=[0.0,0.0,-10.0]
  94. Field Range:Float=10
  95. '
  96. Field vector:Float[]=[0.0,0.0,-10.0,1.0]
  97. Field tvector:Float[4]
  98. End Type
  99. Private
  100. Function InitVbos()
  101. If vbosSeq=graphicsSeq
  102. BindVbos()
  103. Return
  104. EndIf
  105. vbosSeq=graphicsSeq
  106. glGenBuffers 1, Varptr rs_vbo
  107. glBindBuffer GL_ARRAY_BUFFER,rs_vbo
  108. glBufferData GL_ARRAY_BUFFER,PRIM_VBO_SIZE,Null,VBO_USAGE
  109. glEnableVertexAttribArray 0
  110. glVertexAttribPointer 0,2,GL_FLOAT,False,BYTES_PER_VERTEX,Byte Ptr(0)
  111. glEnableVertexAttribArray 1
  112. glVertexAttribPointer 1,2,GL_FLOAT,False,BYTES_PER_VERTEX,Byte Ptr(8)
  113. glEnableVertexAttribArray 2
  114. glVertexAttribPointer 2,2,GL_FLOAT,False,BYTES_PER_VERTEX,Byte Ptr(16)
  115. glEnableVertexAttribArray 3
  116. glVertexAttribPointer 3,4,GL_UNSIGNED_BYTE,True,BYTES_PER_VERTEX,Byte Ptr(24)
  117. glGenBuffers(1, Varptr rs_ibo)
  118. glBindBuffer GL_ELEMENT_ARRAY_BUFFER,rs_ibo
  119. Local idxs:TBank=New TBank.Create( MAX_QUAD_INDICES*4*2 )
  120. ?bmxng
  121. For Local j:Size_t = 0 Until 4
  122. Local k:Size_T = j*MAX_QUAD_INDICES*2
  123. For Local i:Size_T = 0 Until MAX_QUADS
  124. ?Not bmxng
  125. For Local j:Int = 0 Until 4
  126. Local k:Int = j*MAX_QUAD_INDICES*2
  127. For Local i:Int = 0 Until MAX_QUADS
  128. ?
  129. idxs.PokeShort i*12+k+0,Int(i*4+j+0)
  130. idxs.PokeShort i*12+k+2,Int(i*4+j+1)
  131. idxs.PokeShort i*12+k+4,Int(i*4+j+2)
  132. idxs.PokeShort i*12+k+6,Int(i*4+j+0)
  133. idxs.PokeShort i*12+k+8,Int(i*4+j+2)
  134. idxs.PokeShort i*12+k+10,Int(i*4+j+3)
  135. Next
  136. Next
  137. glBufferData GL_ELEMENT_ARRAY_BUFFER,Int(idxs.Size()),idxs._buf,GL_STATIC_DRAW
  138. 'idxs.Discard
  139. End Function
  140. Function BindVbos()
  141. glBindBuffer( GL_ARRAY_BUFFER,rs_vbo )
  142. glEnableVertexAttribArray( 0 ) ; glVertexAttribPointer 0,2,GL_FLOAT,False,BYTES_PER_VERTEX, Byte Ptr(0)
  143. glEnableVertexAttribArray( 1 ) ; glVertexAttribPointer 1,2,GL_FLOAT,False,BYTES_PER_VERTEX, Byte Ptr(8)
  144. glEnableVertexAttribArray( 2 ) ; glVertexAttribPointer 2,2,GL_FLOAT,False,BYTES_PER_VERTEX, Byte Ptr(16)
  145. glEnableVertexAttribArray( 3 ) ; glVertexAttribPointer 3,4,GL_UNSIGNED_BYTE,True,BYTES_PER_VERTEX, Byte Ptr(24)
  146. glBindBuffer( GL_ELEMENT_ARRAY_BUFFER,rs_ibo )
  147. End Function
  148. Global inited:Int
  149. Function InitMojo2()
  150. If inited Return
  151. inited=True
  152. ?Not opengles
  153. glewInit()
  154. ?
  155. InitVbos
  156. glGetIntegerv GL_FRAMEBUFFER_BINDING, Varptr defaultFbo
  157. mainShader=LoadString( "incbin::data/mojo2_program.glsl" )
  158. _fastShader=New TShader.Create( LoadString( "incbin::data/mojo2_fastshader.glsl" ) )
  159. _bumpShader=New TBumpShader.Create( LoadString( "incbin::data/mojo2_bumpshader.glsl" ) )
  160. _matteShader=New TMatteShader.Create( LoadString( "incbin::data/mojo2_matteshader.glsl" ) )
  161. _shadowShader=New TShader.Create( LoadString( "incbin::data/mojo2_shadowshader.glsl" ) )
  162. _lightMapShader=New TShader.Create( LoadString( "incbin::data/mojo2_lightmapshader.glsl" ) )
  163. _defaultShader=_bumpShader
  164. defaultFont=TFont.Load( "incbin::data/mojo2_font.png",32,96,True )'9,13,1,0,7,13,32,96 )
  165. If Not defaultFont Throw "Can't load default font"
  166. flipYMatrix[5]=-1
  167. End Function
  168. Public
  169. Type TRefCounted
  170. Method Retain()
  171. If _refs<=0 Throw "Internal error"
  172. _refs:+1
  173. End Method
  174. Method Free()
  175. If _refs<=0 Throw "Internal error"
  176. _refs:-1
  177. If _refs Return
  178. _refs=-1
  179. Destroy
  180. End Method
  181. Method Destroy() Abstract
  182. Field _refs:Int=1
  183. End Type
  184. '***** Texture *****
  185. Rem
  186. bbdoc: Textures contains image data for use by shaders when rendering.
  187. about: For more information, please see the #TShader type.
  188. end rem
  189. Type TTexture Extends TRefCounted
  190. 'flags
  191. Const Filter:Int=1
  192. Const Mipmap:Int=2
  193. Const ClampS:Int=4
  194. Const ClampT:Int=8
  195. Const ClampST:Int=12
  196. Const RenderTarget:Int=16
  197. Const Managed:Int=256
  198. Rem
  199. bbdoc: Creates a new texture.
  200. about: The @width and @height are parameters are the size of the new texture.
  201. The @format parameter must be 4.
  202. The @flags parameter can be a bitwise combination of:
  203. | @ Flags | @Description
  204. | Texture.Filter | The texture is filtered when magnified
  205. | Texture.Mipmap | The texture is mipmapped when minified
  206. | Texture.ClampS | Texture S coordinate is clamped
  207. | Texture.ClampT | Texture T coordinate is clamped
  208. | Texture.ClampST | Texture S and T coordinates are clamped.
  209. | Texture.RenderTarget | The texture can rendered to using a #Canvas.
  210. | Texture.Managed | Texture contents are preserved when graphics are lost
  211. End Rem
  212. Method Create:TTexture( width:Int,height:Int,format:Int,flags:Int, data:TPixmap = Null )
  213. If format<>PF_RGBA8888 Then
  214. Throw "Invalid texture format: "+format
  215. End If
  216. 'can't mipmap NPOT textures on gles20
  217. If Not IsPow2( width ) Or Not IsPow2( height ) flags:&~Mipmap
  218. _width=width
  219. _height=height
  220. _format=format
  221. _flags=flags
  222. _data=data
  223. If _flags & Managed
  224. _managed=New TPixmap.Create( width,height,PF_RGBA8888 )
  225. If _data
  226. _managed.Paste( _data,0,0 )
  227. _data=Null
  228. Else
  229. _managed.ClearPixels( $ffff00ff )
  230. EndIf
  231. EndIf
  232. Validate()
  233. Return Self
  234. End Method
  235. Method Destroy()
  236. If _seq=graphicsSeq glDeleteTextures 1, Varptr _glTexture
  237. _glTexture=0
  238. _glFramebuffer=0
  239. End Method
  240. Rem
  241. bbdoc: Gets texture width.
  242. end rem
  243. Method Width:Int()
  244. Return _width
  245. End Method
  246. Rem
  247. bbdoc: Gets texture height.
  248. end rem
  249. Method Height:Int()
  250. Return _height
  251. End Method
  252. Rem
  253. bbdoc: Gets texture format.
  254. end rem
  255. Method Format:Int()
  256. Return _format
  257. End Method
  258. Rem
  259. bbdoc: Gets texture flags.
  260. end rem
  261. Method Flags:Int()
  262. Return _flags
  263. End Method
  264. Rem
  265. bbdoc: Writes pixel data to texture.
  266. about: Pixels should be in premultiplied alpha format.
  267. end rem
  268. Method WritePixels( x:Int,y:Int,width:Int,height:Int,data:TPixmap,dataOffset:Int=0,dataPitch:Int=0 )
  269. glPushTexture2d GLTexture()
  270. If Not dataPitch Or dataPitch=width*4
  271. glTexSubImage2D GL_TEXTURE_2D,0,x,y,width,height,GL_RGBA,GL_UNSIGNED_BYTE,data.pixels + dataOffset
  272. Else
  273. For Local iy:Int=0 Until height
  274. glTexSubImage2D GL_TEXTURE_2D,0,x,y+iy,width,1,GL_RGBA,GL_UNSIGNED_BYTE,data.pixels + dataOffset+iy*dataPitch
  275. Next
  276. EndIf
  277. glPopTexture2d
  278. If _flags & Managed
  279. Local texPitch:Int=_width*4
  280. If Not dataPitch dataPitch=width*4
  281. For Local iy:Int=0 Until height
  282. ?bmxng
  283. MemCopy _data.pixels + (y+iy)*texPitch+x*4, data.pixels + dataOffset+iy*dataPitch, Size_T(width*4)
  284. ?Not bmxng
  285. MemCopy _data.pixels + (y+iy)*texPitch+x*4, data.pixels + dataOffset+iy*dataPitch, width*4
  286. ?
  287. Next
  288. EndIf
  289. End Method
  290. Method SetData( x:Int,y:Int,pixmap:TPixmap )
  291. If _managed
  292. If pixmap<>_managed _managed.Paste( pixmap,x,y )
  293. Else If _data
  294. If pixmap<>_data Throw "Texture is read only"
  295. EndIf
  296. glPushTexture2d( GLTexture() )
  297. Local width:Int=pixmap.Width
  298. Local height:Int=pixmap.Height
  299. If pixmap.Pitch=_width*4
  300. glTexSubImage2D( GL_TEXTURE_2D,0,x,y,width,height,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels )
  301. Else
  302. For Local iy:Int=0 Until height
  303. glTexSubImage2D( GL_TEXTURE_2D,0,x,y+iy,width,1,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.PixelPtr( 0,iy ) )
  304. Next
  305. EndIf
  306. glPopTexture2d
  307. End Method
  308. Method UpdateMipmaps()
  309. If Not (_flags & Mipmap) Return
  310. If _seq<>graphicsSeq
  311. Validate()
  312. Return
  313. EndIf
  314. glPushTexture2d GLTexture()
  315. glGenerateMipmap GL_TEXTURE_2D
  316. glPopTexture2d
  317. End Method
  318. Method Loading:Int()
  319. Return False
  320. End Method
  321. Method GLTexture:Int()
  322. Validate
  323. Return _glTexture
  324. End Method
  325. Method GLFramebuffer:Int()
  326. Validate
  327. Return _glFramebuffer
  328. End Method
  329. Function TexturesLoading:Int()
  330. Return 0
  331. End Function
  332. Rem
  333. bbdoc: Loads a texture from a url.
  334. end rem
  335. Function Load:TTexture( url:Object,format:Int=PF_RGBA8888,flags:Int=Filter|Mipmap|ClampST )
  336. Local info:Int[2]
  337. Local data:TPixmap=LoadPixmap(url)
  338. If Not data Return Null
  339. ' convert to RGBA
  340. If data.format <> format Then
  341. data = data.Convert(format)
  342. End If
  343. PremultiplyAlpha(data)
  344. Local tex:TTexture=New TTexture.Create( data.width,data.height,format,flags,data )
  345. Return tex
  346. End Function
  347. Function PremultiplyAlpha(pix:TPixmap)
  348. For Local y:Int=0 Until pix.height
  349. For Local x:Int=0 Until pix.width
  350. Local pixel:Int=pix.ReadPixel( x,y )
  351. Local a:Int=pixel Shr 24 & 255
  352. Local b:Int=(pixel Shr 16 & 255)*a/255
  353. Local g:Int=(pixel Shr 8 & 255)*a/255
  354. Local r:Int=(pixel & 255)*a/255
  355. pixel=a Shl 24 | b Shl 16 | g Shl 8 | r
  356. pix.WritePixel( x,y,pixel )
  357. Next
  358. Next
  359. End Function
  360. Function Color:TTexture( color:Int )
  361. ?bmxng
  362. Local tex:TTexture=TTexture(_colors.ValueForKey( color ))
  363. ?Not bmxng
  364. Local c:TIntVal = New TIntVal
  365. c.value = color
  366. Local tex:TTexture=TTexture(_colors.ValueForKey( c ))
  367. ?
  368. If tex Return tex
  369. Local pixmap:TPixmap=New TPixmap.Create( 1,1,PF_RGBA8888 )
  370. pixmap.ClearPixels( color )
  371. tex=New TTexture.Create( 1,1,PF_RGBA8888,ClampST,pixmap )
  372. ?bmxng
  373. _colors.Insert color,tex
  374. ?Not bmxng
  375. _colors.Insert c,tex
  376. ?
  377. Return tex
  378. End Function
  379. Rem
  380. bbdoc: Returns a stock single texel black texture.
  381. end rem
  382. Function Black:TTexture()
  383. If Not _black _black=Color( $ff000000 )
  384. Return _black
  385. End Function
  386. Rem
  387. bbdoc: Returns a stock single texel white texture.
  388. end rem
  389. Function White:TTexture()
  390. If Not _white _white=Color( $ffffffff )
  391. Return _white
  392. End Function
  393. Rem
  394. bbdoc: Returnss a stock single texel magenta texture.
  395. end rem
  396. Function Magenta:TTexture()
  397. If Not _magenta _magenta=Color( $ffff00ff )
  398. Return _magenta
  399. End Function
  400. Rem
  401. bbdoc: Returns a stock single texel 'flat' texture for normal mapping.
  402. end rem
  403. Function Flat:TTexture()
  404. If Not _flat _flat=Color( $ff888888 )
  405. Return _flat
  406. End Function
  407. Method Data:TPixmap()
  408. Return _data
  409. End Method
  410. ?bmxng
  411. Private
  412. ?
  413. Field _seq:Int
  414. Field _width:Int
  415. Field _height:Int
  416. Field _format:Int
  417. Field _flags:Int
  418. Field _data:TPixmap
  419. Field _managed:TPixmap
  420. Field _glTexture:Int
  421. Field _glFramebuffer:Int
  422. ?bmxng
  423. Global _colors:TIntMap=New TIntMap
  424. ?Not bmxng
  425. Global _colors:TMap=New TMap
  426. ?
  427. Global _black:TTexture
  428. Global _white:TTexture
  429. Global _magenta:TTexture
  430. Global _flat:TTexture
  431. Method Validate()
  432. If _seq=graphicsSeq Return
  433. InitMojo2()
  434. _seq=graphicsSeq
  435. glGenTextures(1, Varptr _glTexture)
  436. glPushTexture2d _glTexture
  437. If _flags & Filter
  438. glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR
  439. Else
  440. glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST
  441. EndIf
  442. If (_flags & Mipmap) And (_flags & Filter)
  443. glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR
  444. Else If _flags & Mipmap
  445. glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST_MIPMAP_NEAREST
  446. Else If _flags & Filter
  447. glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR
  448. Else
  449. glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST
  450. EndIf
  451. If _flags & ClampS glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE
  452. If _flags & ClampT glTexParameteri GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE
  453. glTexImage2D GL_TEXTURE_2D,0,GL_RGBA,_width,_height,0,GL_RGBA,GL_UNSIGNED_BYTE,Null
  454. glPopTexture2d
  455. If _flags & RenderTarget
  456. glGenFramebuffers(1, Varptr _glFramebuffer)
  457. glPushFramebuffer _glFramebuffer
  458. glBindFramebuffer GL_FRAMEBUFFER,_glFramebuffer
  459. glFramebufferTexture2D GL_FRAMEBUFFER,GL_COLOR_ATTACHMENT0,GL_TEXTURE_2D,_glTexture,0
  460. If glCheckFramebufferStatus( GL_FRAMEBUFFER )<>GL_FRAMEBUFFER_COMPLETE Throw "Incomplete framebuffer"
  461. glPopFramebuffer
  462. EndIf
  463. If _managed Then
  464. SetData( 0,0,_managed )
  465. UpdateMipmaps()
  466. Else If _data
  467. SetData( 0,0,_data )
  468. UpdateMipmaps()
  469. EndIf
  470. End Method
  471. Method LoadData( data:TPixmap )
  472. glPushTexture2d GLTexture()
  473. glTexImage2D GL_TEXTURE_2D,0,GL_RGBA,_width,_height,0,GL_RGBA,GL_UNSIGNED_BYTE,data.pixels
  474. glPopTexture2d
  475. UpdateMipmaps
  476. End Method
  477. End Type
  478. '***** Shader ****
  479. Public
  480. Type TGLUniform
  481. Field name:String
  482. Field location:Int
  483. Field size:Int
  484. Field kind:Int
  485. Method Create:TGLUniform( name:String,location:Int,size:Int,kind:Int )
  486. Self.name=name
  487. Self.location=location
  488. Self.size=size
  489. Self.kind=kind
  490. Return Self
  491. End Method
  492. End Type
  493. Type TGLProgram
  494. Field program:Int
  495. 'material uniforms
  496. Field matuniforms:TGLUniform[]
  497. 'hard coded uniform locations
  498. Field mvpMatrix:Int
  499. Field mvMatrix:Int
  500. Field clipPosScale:Int
  501. Field globalColor:Int
  502. Field AmbientLight:Int
  503. Field fogColor:Int
  504. Field lightColors:Int
  505. Field lightVectors:Int
  506. Field shadowTexture:Int
  507. Method Create:TGLProgram( program:Int,matuniforms:TGLUniform[] )
  508. Self.program=program
  509. Self.matuniforms=matuniforms
  510. mvpMatrix=glGetUniformLocation( program,"ModelViewProjectionMatrix" )
  511. mvMatrix=glGetUniformLocation( program,"ModelViewMatrix" )
  512. clipPosScale=glGetUniformLocation( program,"ClipPosScale" )
  513. globalColor=glGetUniformLocation( program,"GlobalColor" )
  514. fogColor=glGetUniformLocation( program,"FogColor" )
  515. AmbientLight=glGetUniformLocation( program,"AmbientLight" )
  516. lightColors=glGetUniformLocation( program,"LightColors" )
  517. lightVectors=glGetUniformLocation( program,"LightVectors" )
  518. shadowTexture=glGetUniformLocation( program,"ShadowTexture" )
  519. Return Self
  520. End Method
  521. Method Bind()
  522. glUseProgram program
  523. If mvpMatrix<>-1 glUniformMatrix4fv mvpMatrix,1,False,rs_modelViewProjMatrix
  524. If mvMatrix<>-1 glUniformMatrix4fv mvMatrix,1,False,rs_modelViewMatrix
  525. If clipPosScale<>-1 glUniform4fv clipPosScale,1,rs_clipPosScale
  526. If globalColor<>-1 glUniform4fv globalColor,1,rs_globalColor
  527. If fogColor<>-1 glUniform4fv fogColor,1,rs_fogColor
  528. If AmbientLight<>-1 glUniform4fv AmbientLight,1,rs_ambientLight
  529. If lightColors<>-1 glUniform4fv lightColors,rs_numLights,rs_lightColors
  530. If lightVectors<>-1 glUniform4fv lightVectors,rs_numLights,rs_lightVectors
  531. glActiveTexture GL_TEXTURE0+7
  532. If shadowTexture<>-1 And rs_shadowTexture
  533. glBindTexture GL_TEXTURE_2D,rs_shadowTexture.GLTexture()
  534. glUniform1i shadowTexture,7
  535. Else
  536. glBindTexture GL_TEXTURE_2D,TTexture.White().GLTexture()
  537. End If
  538. glActiveTexture GL_TEXTURE0
  539. End Method
  540. End Type
  541. Public
  542. Type TShader
  543. Method Create:TShader( source:String )
  544. Build source
  545. Return Self
  546. End Method
  547. Method DefaultMaterial:TMaterial()
  548. If Not _defaultMaterial _defaultMaterial=New TMaterial.Create( Self )
  549. Return _defaultMaterial
  550. End Method
  551. Function FastShader:TShader()
  552. Return _fastShader
  553. End Function
  554. Rem
  555. bbdoc: Returns a stock bump shader for drawing lit sprites with specular and normal maps.
  556. about:
  557. The following material properties are supported:
  558. | @Property | @Type | @Default
  559. | ColorTexture | Texture | White
  560. | SpecularTexture | Texture | Black
  561. | NormalTexture | Texture | Flat
  562. | AmbientColor | Float[4] | [0.0,0.0,0.0,1.0]
  563. | Roughness | Float | 0.5
  564. The shader b3d_Ambient value is computed by multiplying ColorTexture by AmbientColor.
  565. The shader b3d_Diffuse value is computed by multiplying ColorTexture by 1-AmbientColor.
  566. When loading materials that use the bump shader, diffuse, specular and normal maps can be given the following files names:
  567. | @Texture map | @Valid paths
  568. | Diffuse | (FILE).(EXT) ; (FILE)_d.(EXT) ; (FILE)_diff.(EXT) ; (FILE)_diffuse.(EXT)
  569. | Specular | (FILE)_s.(EXT) ; (FILE)_spec.(EXT) ; (FILE)_specular.(EXT) ;(FILE)_SPECUALR.(EXT)
  570. | Normal | (FILE)_n.(EXT) ; (FILE)_norm.(EXT) ; (FILE)_normal.(EXT) ; (FILE)_NORMALS.(EXT)
  571. Where (FILE) is the filename component of the path provided to Material.Load or Image.Load, and (EXT) is the file extension, eg: png, jpg.
  572. end rem
  573. Function BumpShader:TShader()
  574. Return _bumpShader
  575. End Function
  576. Rem
  577. bbdoc: Returns a stock matte shader for drawing lit sprites with no specular or normal maps.
  578. about:
  579. The following material properties are supported:
  580. | @Property | @Type | @Default
  581. | ColorTexture | Texture | White
  582. | AmbientColor | Float[4] | [0.0,0.0,0.0,1.0]
  583. | Roughness | Float | 0.5
  584. end rem
  585. Function MatteShader:TShader()
  586. Return _matteShader
  587. End Function
  588. Rem
  589. bbdoc: Returns a stock shadow shader for drawing shadows.
  590. about: This shader simply writes 'black' to b3d_FragColor.
  591. end rem
  592. Function ShadowShader:TShader()
  593. Return _shadowShader
  594. End Function
  595. Rem
  596. bbdoc: Returns a stock shader for drawing light textures and light mask effects.
  597. about:
  598. This shader performs a texture lookup, and writes the red component to b3d_FragColor.
  599. The following material properties are supported:
  600. | @Property | @Type | @Default
  601. | ColorTexture | Texture | White
  602. end rem
  603. Function LightMapShader:TShader()
  604. Return _lightMapShader
  605. End Function
  606. Rem
  607. bbdoc: Returns the default shader used when a material is created with a 'Null' shader.
  608. about: This is initially the #BumpShader, but can be modified using #SetDefaultShader.
  609. end rem
  610. Function DefaultShader:TShader()
  611. Return _defaultShader
  612. End Function
  613. Rem
  614. bbdoc: Sets the default shader used when a material is created with a 'Null' shader.
  615. end rem
  616. Function SetDefaultShader( shader:TShader )
  617. If Not shader shader=_bumpShader
  618. _defaultShader=shader
  619. End Function
  620. 'Protected
  621. Rem
  622. bbdoc: Compiles and links the shader.
  623. about: Types that extend Shader must call this method at some point. This is usually done in the subclasses constructor.
  624. end rem
  625. Method Build( source:String )
  626. _source=source
  627. BuildInit
  628. End Method
  629. Rem
  630. bbdoc: Types that extend Shader must set defalut values for all valid shader parameters in this method.
  631. end rem
  632. Method OnInitMaterial( material:TMaterial )
  633. material.SetTexture "ColorTexture",TTexture.White()
  634. End Method
  635. Rem
  636. bbdoc: Classes that extend Shader should load textures and other valid shader parameters from @path into @material in this method.
  637. about: The interpretation of @path is completely up to the shader. The @texFlags parameter contains texture flag values that should be used for any textures loaded.
  638. The @material parameter is an already initialized material.
  639. This method should return @material if successful, or null on failure.
  640. end rem
  641. Method OnLoadMaterial:TMaterial( material:TMaterial,url:Object,texFlags:Int )
  642. Local texture:TTexture=TTexture.Load( url,PF_RGBA8888,texFlags )
  643. If Not texture Return Null
  644. material.SetTexture "ColorTexture",texture
  645. If texture texture.Free
  646. Return material
  647. End Method
  648. 'Private
  649. Const MAX_FLAGS:Int=8
  650. Field _seq:Int
  651. Field _source:String
  652. Field _vsource:String
  653. Field _fsource:String
  654. ?bmxng
  655. Field _uniforms:TStringMap=New TStringMap
  656. ?Not bmxng
  657. Field _uniforms:TMap=New TMap
  658. ?
  659. Field _glPrograms:TGLProgram[MAX_LIGHTS+1]
  660. Field _defaultMaterial:TMaterial
  661. Method Bind()
  662. Local program:TGLProgram=GLProgram()
  663. If program=rs_program Return
  664. rs_program=program
  665. rs_material=Null
  666. program.Bind
  667. End Method
  668. Method GLProgram:TGLProgram()
  669. If _seq<>graphicsSeq
  670. _seq=graphicsSeq
  671. rs_program=Null
  672. BuildInit
  673. EndIf
  674. Return _glPrograms[rs_numLights]
  675. End Method
  676. Method BuildProgram:TGLProgram( numLights:Int )
  677. Local defs:String=""
  678. defs:+"#define NUM_LIGHTS "+numLights+"~n"
  679. Local vshader:Int=glCompile( GL_VERTEX_SHADER,defs+_vsource )
  680. Local fshader:Int=glCompile( GL_FRAGMENT_SHADER,defs+_fsource )
  681. Local program:Int=glCreateProgram()
  682. glAttachShader program,vshader
  683. glAttachShader program,fshader
  684. glDeleteShader vshader
  685. glDeleteShader fshader
  686. glBindAttribLocation program,0,"Position"
  687. glBindAttribLocation program,1,"Texcoord0"
  688. glBindAttribLocation program,2,"Tangent"
  689. glBindAttribLocation program,3,"Color"
  690. glLink program
  691. 'enumerate program uniforms
  692. Local matuniforms:TGLUniform[] = New TGLUniform[0]
  693. Local size:Int
  694. Local kind:Int
  695. Local buf:Byte[1024]
  696. Local l:Int
  697. Local n:Int
  698. glGetProgramiv program,GL_ACTIVE_UNIFORMS, Varptr n
  699. For Local i:Int=0 Until n
  700. glGetActiveUniform program,i,1024,Varptr l,Varptr size, Varptr kind, buf
  701. Local name:String = String.FromBytes(buf, l)
  702. If _uniforms.Contains( name )
  703. Local location:Int=glGetUniformLocation( program,name )
  704. If location=-1 Continue 'IE fix...
  705. matuniforms :+ [New TGLUniform.Create( name,location,size,kind )]
  706. ' Print name[0]+"->"+location
  707. EndIf
  708. Next
  709. Return New TGLProgram.Create( program,matuniforms )
  710. End Method
  711. Method BuildInit()
  712. InitMojo2
  713. Local p:TGlslParser=TGlslParser(New TGlslParser.Create( _source ))
  714. Local vars:TMap=New TMap
  715. While p.Toke()
  716. If p.CParse( "uniform" )
  717. 'uniform decl
  718. Local ty:String=p.ParseType()
  719. Local id:String=p.ParseIdent()
  720. p.ParseToke ";"
  721. _uniforms.Insert id, id
  722. ' Print "uniform "+ty+" "+id+";"
  723. Continue
  724. EndIf
  725. Local id:String=p.CParseIdent()
  726. If id
  727. If id.StartsWith( "gl_" )
  728. vars.Insert "B3D_"+id.ToUpper(), ""
  729. Else If id.StartsWith( "b3d_" )
  730. vars.Insert id.ToUpper(), ""
  731. EndIf
  732. Continue
  733. EndIf
  734. p.Bump
  735. Wend
  736. Local vardefs:String=""
  737. For Local v:String=EachIn vars.Keys()
  738. vardefs:+"#define "+v+" 1~n"
  739. Next
  740. ' Print "Vardefs:";Print vardefs
  741. Local source:String=mainShader
  742. Local i0:Int=source.Find( "//@vertex" )
  743. If i0=-1 Throw "Can't find //@vertex chunk"
  744. Local i1:Int=source.Find( "//@fragment" )
  745. If i1=-1 Throw "Can't find //@fragment chunk"
  746. Local header:String=vardefs+source[..i0]
  747. _vsource=header+source[i0..i1]
  748. _fsource=header+source[i1..].Replace( "${SHADER}",_source )
  749. For Local numLights:Int=0 To MAX_LIGHTS
  750. _glPrograms[numLights]=BuildProgram( numLights )
  751. If numLights Or vars.Contains( "B3D_DIFFUSE" ) Or vars.Contains( "B3D_SPECULAR" ) Continue
  752. For Local i:Int=1 To MAX_LIGHTS
  753. _glPrograms[i]=_glPrograms[0]
  754. Next
  755. Exit
  756. Next
  757. End Method
  758. End Type
  759. Type TBumpShader Extends TShader
  760. ' Method New( source:String )
  761. ' Super.New( source )
  762. ' End
  763. 'Protected
  764. Method OnInitMaterial( material:TMaterial )
  765. material.SetTexture "ColorTexture",TTexture.White()
  766. material.SetTexture "SpecularTexture",TTexture.Black()
  767. material.SetTexture "NormalTexture",TTexture.Flat()
  768. material.SetVector "AmbientColor",[1.0,1.0,1.0,1.0]
  769. material.SetScalar "Roughness",1.0
  770. End Method
  771. Method OnLoadMaterial:TMaterial( material:TMaterial,url:Object,texFlags:Int )
  772. Local format:Int = PF_RGBA8888
  773. Local path:String = String(url)
  774. Local colorTex:TTexture
  775. Local specularTex:TTexture
  776. Local normalTex:TTexture
  777. If Not path Then
  778. colorTex=TTexture.Load( url,format,texFlags )
  779. Else
  780. Local ext:String = ExtractExt( path )
  781. If ext path=StripExt( path ) Else ext="png"
  782. colorTex=TTexture.Load( path+"."+ext,format,texFlags )
  783. If Not colorTex colorTex=TTexture.Load( path+"_d."+ext,format,texFlags )
  784. If Not colorTex colorTex=TTexture.Load( path+"_diff."+ext,format,texFlags )
  785. If Not colorTex colorTex=TTexture.Load( path+"_diffuse."+ext,format,texFlags )
  786. specularTex = TTexture.Load( path+"_s."+ext,format,texFlags )
  787. If Not specularTex specularTex=TTexture.Load( path+"_spec."+ext,format,texFlags )
  788. If Not specularTex specularTex=TTexture.Load( path+"_specular."+ext,format,texFlags )
  789. If Not specularTex specularTex=TTexture.Load( path+"_SPECULAR."+ext,format,texFlags )
  790. normalTex = TTexture.Load( path+"_n."+ext,format,texFlags )
  791. If Not normalTex normalTex=TTexture.Load( path+"_norm."+ext,format,texFlags )
  792. If Not normalTex normalTex=TTexture.Load( path+"_normal."+ext,format,texFlags )
  793. If Not normalTex normalTex=TTexture.Load( path+"_NORMALS."+ext,format,texFlags )
  794. End If
  795. If Not colorTex And Not specularTex And Not normalTex Return Null
  796. material.SetTexture "ColorTexture",colorTex
  797. material.SetTexture "SpecularTexture",specularTex
  798. material.SetTexture "NormalTexture",normalTex
  799. If specularTex Or normalTex
  800. material.SetVector "AmbientColor",[0.0,0.0,0.0,1.0]
  801. material.SetScalar "Roughness",.5
  802. EndIf
  803. If colorTex colorTex.Free
  804. If specularTex specularTex.Free
  805. If normalTex normalTex.Free
  806. Return material
  807. End Method
  808. End Type
  809. Type TMatteShader Extends TShader
  810. ' Method Create( source:String )
  811. ' Super.New( source )
  812. ' End
  813. ' Protected
  814. Method OnInitMaterial( material:TMaterial )
  815. material.SetTexture "ColorTexture",TTexture.White()
  816. material.SetVector "AmbientColor",[0.0,0.0,0.0,1.0]
  817. material.SetScalar "Roughness",1.0
  818. End Method
  819. End Type
  820. '***** Material *****
  821. Rem
  822. bbdoc: Materials contain shader parameters that map to shader uniforms variables when rendering.
  823. End Rem
  824. Type TMaterial Extends TRefCounted
  825. Rem
  826. bbdoc: Creates a new material.
  827. End Rem
  828. Method Create:TMaterial( shader:TShader=Null )
  829. InitMojo2
  830. If Not shader shader=_defaultShader
  831. _shader=shader
  832. _shader.OnInitMaterial( Self )
  833. _inited=True
  834. Return Self
  835. End Method
  836. Method Destroy()
  837. For Local tex:TTexture=EachIn _textures
  838. tex.Free()
  839. Next
  840. End Method
  841. Rem
  842. bbdoc: Gets material shader.
  843. End Rem
  844. Method Shader:TShader()
  845. Return _shader
  846. End Method
  847. Method ColorTexture:TTexture()
  848. Return _colorTexture
  849. End Method
  850. Method Width:Int()
  851. If _colorTexture Return _colorTexture.Width()
  852. Return 0
  853. End Method
  854. Method Height:Int()
  855. If _colorTexture Return _colorTexture.Height()
  856. Return 0
  857. End Method
  858. Rem
  859. bbdoc: Sets float shader parameter.
  860. End Rem
  861. Method SetScalar( param:String,scalar:Float )
  862. If _inited And Not _scalars.Contains( param ) Return
  863. _scalars.Insert param,scalar
  864. End Method
  865. Rem
  866. bbdoc: Gets float shader parameter.
  867. End Rem
  868. Method GetScalar:Float( param:String,defValue:Float=1.0 )
  869. If Not _scalars.Contains( param ) Return defValue
  870. Return _scalars.ValueForKey( param )
  871. End Method
  872. Rem
  873. bbdoc: Sets vector shader parameter.
  874. End Rem
  875. Method SetVector( param:String,vector:Float[] )
  876. If _inited And Not _vectors.Contains( param ) Return
  877. _vectors.Insert param,vector
  878. End Method
  879. Rem
  880. bbdoc: Gets vector shader parameter.
  881. End Rem
  882. Method GetVector:Float[]( param:String,defValue:Float[]=Null )
  883. If Not _vectors.Contains( param ) Then
  884. If defValue Then
  885. Return defValue
  886. Else
  887. Return [1.0,1.0,1.0,1.0]
  888. End If
  889. End If
  890. Return Float[](_vectors.ValueForKey( param ))
  891. End Method
  892. Rem
  893. bbdoc: Sets texture shader parameter.
  894. End Rem
  895. Method SetTexture( param:String,texture:TTexture )
  896. If Not texture Return
  897. If _inited And Not _textures.Contains( param ) Return
  898. Local old:TTexture=TTexture(_textures.ValueForKey( param ))
  899. texture.Retain
  900. _textures.Insert param,texture
  901. If old old.Free
  902. If param="ColorTexture" _colorTexture=texture
  903. End Method
  904. Rem
  905. bbdoc: Gets texture shader parameter.
  906. End Rem
  907. Method GetTexture:TTexture( param:String,defValue:TTexture=Null )
  908. If Not _textures.Contains( param ) Return defValue
  909. Return TTexture(_textures.ValueForKey( param ))
  910. End Method
  911. Method Loading:Int()
  912. Return False
  913. End Method
  914. Rem
  915. bbdoc: Loads a material.
  916. about: If @shader is null, the TShader.DefaultShader is used.
  917. End Rem
  918. Function Load:TMaterial( url:Object,texFlags:Int,shader:TShader )
  919. Local material:TMaterial=New TMaterial.Create( shader )
  920. material=material.Shader().OnLoadMaterial( material,url,texFlags )
  921. Return material
  922. End Function
  923. 'Private
  924. Field _shader:TShader
  925. Field _colorTexture:TTexture
  926. Field _scalars:TStringFloatMap=New TStringFloatMap
  927. ?bmxng
  928. Field _vectors:TStringMap=New TStringMap
  929. Field _textures:TStringMap=New TStringMap
  930. ?Not bmxng
  931. Field _vectors:TMap=New TMap
  932. Field _textures:TMap=New TMap
  933. ?
  934. Field _inited:Int
  935. Method Bind:Int()
  936. _shader.Bind
  937. If rs_material=Self Return True
  938. rs_material=Self
  939. Local texid:Int=0
  940. For Local u:TGLUniform=EachIn rs_program.matuniforms
  941. Select u.kind
  942. Case GL_FLOAT
  943. glUniform1f u.location,GetScalar( u.name )
  944. Case GL_FLOAT_VEC4
  945. glUniform4fv u.location,1,GetVector( u.name )
  946. Case GL_SAMPLER_2D
  947. Local tex:TTexture=GetTexture( u.name )
  948. ' If tex.Loading
  949. ' rs_material=Null
  950. ' Exit
  951. ' Endif
  952. glActiveTexture GL_TEXTURE0+texid
  953. glBindTexture GL_TEXTURE_2D,tex.GLTexture()
  954. glUniform1i u.location,texid
  955. texid:+1
  956. Default
  957. Throw "Unsupported uniform type:"+u.kind
  958. End Select
  959. Next
  960. If texid glActiveTexture GL_TEXTURE0
  961. Return rs_material=Self
  962. End Method
  963. End Type
  964. '***** ShaderCaster *****
  965. Rem
  966. bbdoc: The ShadowCaster class provides support for simple 2d shadow rendering.
  967. about: Shadow casters are used by #Renderer objects when rendering layers. To render shadows, you will need to add
  968. shadow casters to the drawlists returned by ILayer.OnRenderLayer.
  969. A shadow caster can either be added to a drawlist using [[DrawList.AddShadowCaster]], or attached to images using [[Image.SetShadowCaster]]. Shadow casters attached to images are automatically added to drawlists when an image is drawn.
  970. A shadow caster contains a set of 2d vertices which describe the geometric shape of the object that casts a shadow. The vertices should describe a convex polygon.
  971. End Rem
  972. Type TShadowCaster
  973. Method Create:TShadowCaster( verts:Float[] = Null,kind:Int = -1 )
  974. If verts Then
  975. _verts=verts
  976. End If
  977. If kind >= 0 Then
  978. _kind=kind
  979. End If
  980. Return Self
  981. End Method
  982. Rem
  983. bbdoc: Set shadow caster vertices.
  984. end rem
  985. Method SetVertices( vertices:Float[] )
  986. _verts=vertices
  987. End Method
  988. Rem
  989. bbdoc: Get shadow caster vertices.
  990. end rem
  991. Method Vertices:Float[]()
  992. Return _verts
  993. End Method
  994. Method SetKind( kind:Int )
  995. _kind=kind
  996. End Method
  997. Method Kind:Int()
  998. Return _kind
  999. End Method
  1000. 'Private
  1001. Field _verts:Float[]
  1002. Field _kind:Int
  1003. End Type
  1004. '***** Image *****
  1005. Rem
  1006. bbdoc: An image is a rectangular area of pixels within a material, that can be drawn using one of the [[DrawList.DrawImage]] methods.
  1007. about: You can create a new image using one of the [[Image.Create]] methods, or load an image from file using [[Image.Load|Image.Load]].
  1008. An image also has a handle, an offset within the image that represents it's origin whan it is drawn. Image handles are specified in fractional values, where 0,0 is the top-left of an image, 1,1 is the bottom-right and .5,.5 is the center.
  1009. end rem
  1010. Type TImage
  1011. Const Filter:Int=TTexture.Filter
  1012. Const Mipmap:Int=TTexture.Mipmap
  1013. Const Managed:Int=TTexture.Managed
  1014. Rem
  1015. bbdoc: Creates a new image for rendering.
  1016. about: The new image can be used as a render target for a [[Canvas]].
  1017. The @flags parameter can be any bitwise combination of:
  1018. | @Flags | @Description
  1019. | TImage.Filter | The image is filtered
  1020. | TImage.Mipmap | The image is mipmapped
  1021. | TImage.Managed | The image is managed
  1022. The TImage.Managed flag should be used if you want mojo2 to preserve the image contents when the graphics mode changes. This is not necessary if the image is being re-rendered every frame.
  1023. TImage.Managed consumes more memory, and slows down image rendering somewhat so should be avoided if possible.
  1024. End Rem
  1025. Method Create:TImage( width:Int,height:Int,xhandle:Float=.5,yhandle:Float=.5,flags:Int=TImage.Filter )
  1026. flags:&_flagsMask
  1027. Local texture:TTexture=New TTexture.Create( width,height,PF_RGBA8888,flags|TTexture.ClampST|TTexture.RenderTarget )
  1028. _material=New TMaterial.Create( _fastShader )
  1029. _material.SetTexture "ColorTexture",texture
  1030. _width=width
  1031. _height=height
  1032. SetHandle xhandle,yhandle
  1033. Return Self
  1034. End Method
  1035. Rem
  1036. bbdoc: Creates a new image from a region within an existing image.
  1037. about: The new image shares the same material and image flags as @image.
  1038. End Rem
  1039. Method CreateImage:TImage( image:TImage,x:Int,y:Int,width:Int,height:Int,xhandle:Float=.5,yhandle:Float=.5 )
  1040. _material=image._material
  1041. _material.Retain
  1042. _x=image._x+x
  1043. _y=image._y+y
  1044. _width=width
  1045. _height=height
  1046. SetHandle xhandle,yhandle
  1047. Return Self
  1048. End Method
  1049. Rem
  1050. bbdoc: Creates a new image from a material.
  1051. End Rem
  1052. Method CreateMaterial:TImage( material:TMaterial,xhandle:Float=.5,yhandle:Float=.5 )
  1053. Local texture:TTexture=material.ColorTexture()
  1054. If Not texture Throw "Material has no ColorTexture"
  1055. _material=material
  1056. _material.Retain
  1057. _width=_material.Width()
  1058. _height=_material.Height()
  1059. SetHandle xhandle,yhandle
  1060. Return Self
  1061. End Method
  1062. Rem
  1063. bbdoc: Creates a new image representing a rect within a material.
  1064. End Rem
  1065. Method CreateMaterialRect:TImage( material:TMaterial,x:Int,y:Int,width:Int,height:Int,xhandle:Float=.5,yhandle:Float=.5 )
  1066. Local texture:TTexture=material.ColorTexture()
  1067. If Not texture Throw "Material has no ColorTexture"
  1068. _material=material
  1069. _material.Retain
  1070. _x=x
  1071. _y=y
  1072. _width=width
  1073. _height=height
  1074. SetHandle xhandle,yhandle
  1075. Return Self
  1076. End Method
  1077. Method Delete()
  1078. Discard()
  1079. End Method
  1080. Rem
  1081. bbdoc: Discards any internal resources such as videomem used by the image.
  1082. End Rem
  1083. Method Discard()
  1084. If _material _material.Free
  1085. _material=Null
  1086. End Method
  1087. Method Material:TMaterial()
  1088. Return _material
  1089. End Method
  1090. Rem
  1091. bbdoc: Gets x coordinate of the left edge of the image rect.
  1092. End Rem
  1093. Method X0:Float()
  1094. Return _x0
  1095. End Method
  1096. Rem
  1097. bbdoc: Gets y coordinate of the top edge of the image rect.
  1098. End Rem
  1099. Method Y0:Float()
  1100. Return _y0
  1101. End Method
  1102. Rem
  1103. bbdoc: Gets x coordinate of the right edge of the image rect.
  1104. End Rem
  1105. Method X1:Float()
  1106. Return _x1
  1107. End Method
  1108. Rem
  1109. bbdoc: Gets y coordinate of the bottom edge of the image rect.
  1110. End Rem
  1111. Method Y1:Float()
  1112. Return _y1
  1113. End Method
  1114. Rem
  1115. bbdoc: Gets image width.
  1116. End Rem
  1117. Method Width:Int()
  1118. Return _width
  1119. End Method
  1120. Rem
  1121. bbdoc: Gets image height.
  1122. End Rem
  1123. Method Height:Int()
  1124. Return _height
  1125. End Method
  1126. Rem
  1127. bbdoc: Gets image x handle.
  1128. End Rem
  1129. Method HandleX:Float()
  1130. Return -_x0/(_x1-_x0)
  1131. End Method
  1132. Rem
  1133. bbdoc: Gets image y handle.
  1134. End Rem
  1135. Method HandleY:Float()
  1136. Return -_y0/(_y1-_y0)
  1137. End Method
  1138. Rem
  1139. bbdoc: Writes pixel data to image.
  1140. about: Pixels should be in premultiplied alpha format.
  1141. End Rem
  1142. Method WritePixels( x:Int,y:Int,width:Int,height:Int,data:TPixmap,dataOffset:Int=0,dataPitch:Int=0 )
  1143. _material.ColorTexture().WritePixels( x+_x,y+_y,width,height,data,dataOffset,dataPitch )
  1144. End Method
  1145. Method SetHandle( xhandle:Float,yhandle:Float )
  1146. _x0=Float(_width)*-xhandle
  1147. _x1=Float(_width)*(1-xhandle)
  1148. _y0=Float(_height)*-yhandle
  1149. _y1=Float(_height)*(1-yhandle)
  1150. _s0=Float(_x)/Float(_material.Width())
  1151. _t0=Float(_y)/Float(_material.Height())
  1152. _s1=Float(_x+_width)/Float(_material.Width())
  1153. _t1=Float(_y+_height)/Float(_material.Height())
  1154. End Method
  1155. Rem
  1156. bbdoc: Set image shadow caster.
  1157. about: Attaching a shadow caster to an image will cause the shadow caster to be automatically added to the
  1158. drawlist whenever the image is drawn.
  1159. End Rem
  1160. Method SetShadowCaster( shadowCaster:TShadowCaster )
  1161. _caster=shadowCaster
  1162. End Method
  1163. Rem
  1164. bbdoc: Gets attached shadow caster.
  1165. End Rem
  1166. Method ShadowCaster:TShadowCaster()
  1167. Return _caster
  1168. End Method
  1169. Method Loading:Int()
  1170. Return _material.Loading()
  1171. End Method
  1172. Function ImagesLoading:Int()
  1173. Return TTexture.TexturesLoading()>0
  1174. End Function
  1175. Rem
  1176. bbdoc: Sets an internal 'flags mask' that can be used to filter out specific image flags when creating images.
  1177. about: The flags mask value is 'anded' with any flags values passed to Image.New, Image.Load or Image.LoadFrames.
  1178. For example, by setting the flags mask to just Image.Managed, the Image.Filter and Image.Mipmap flags will be effectively disabled for all images - useful for pixel art or retro style graphics.
  1179. The default flags mask is Image.Filter|Image.Mipmap|Image.Managed, which effectively disables the filter.
  1180. End Rem
  1181. Function SetFlagsMask( mask:Int )
  1182. _flagsMask=mask
  1183. End Function
  1184. Rem
  1185. bbdoc: Returns the current flags mask.
  1186. End Rem
  1187. Function FlagsMask:Int()
  1188. Return _flagsMask
  1189. End Function
  1190. Rem
  1191. bbdoc:
  1192. End Rem
  1193. Function Load:TImage( url:Object,xhandle:Float=.5,yhandle:Float=.5,flags:Int=TImage.Filter|TImage.Mipmap,shader:TShader=Null )
  1194. flags:&_flagsMask
  1195. Local material:TMaterial=TMaterial.Load( url,flags|TTexture.ClampST,shader )
  1196. If Not material Return Null
  1197. Return New TImage.CreateMaterial( material,xhandle,yhandle )
  1198. End Function
  1199. Function LoadFrames:TImage[]( url:Object,numFrames:Int,padded:Int=False,xhandle:Float=.5,yhandle:Float=.5,flags:Int=TImage.Filter|TImage.Mipmap,shader:TShader=Null )
  1200. flags:&_flagsMask
  1201. Local material:TMaterial=TMaterial.Load( url,flags|TTexture.ClampST,shader )
  1202. If Not material Return Null
  1203. Local cellWidth:Int=material.Width()/numFrames
  1204. Local cellHeight:Int=material.Height()
  1205. Local x:Int=0
  1206. Local width:Int=cellWidth
  1207. If padded Then
  1208. x:+1
  1209. width:-2
  1210. End If
  1211. Local frames:TImage[]=New TImage[numFrames]
  1212. For Local i:Int=0 Until numFrames
  1213. frames[i]=New TImage.CreateMaterialRect( material,i*cellWidth+x,0,width,cellHeight,xhandle,yhandle )
  1214. Next
  1215. Return frames
  1216. End Function
  1217. 'Private
  1218. Global _flagsMask:Int=Filter|Mipmap|Managed
  1219. Field _material:TMaterial
  1220. Field _x:Int,_y:Int,_width:Int,_height:Int
  1221. Field _x0:Float=-1,_y0:Float=-1,_x1:Float=1,_y1:Float=1
  1222. Field _s0:Float=0 ,_t0:Float=0 ,_s1:Float=1,_t1:Float=1
  1223. Field _caster:TShadowCaster
  1224. End Type
  1225. '***** Font *****
  1226. Type TGlyph
  1227. Field image:TImage
  1228. Field char:Int
  1229. Field x:Int
  1230. Field y:Int
  1231. Field width:Int
  1232. Field height:Int
  1233. Field advance:Float
  1234. Method Create:TGlyph( image:TImage,char:Int,x:Int,y:Int,width:Int,height:Int,advance:Float )
  1235. Self.image=image
  1236. Self.char=char
  1237. Self.x=x
  1238. Self.y=y
  1239. Self.width=width
  1240. Self.height=height
  1241. Self.advance=advance
  1242. Return Self
  1243. End Method
  1244. End Type
  1245. Rem
  1246. bbdoc: Provides support for simple fixed width bitmap fonts.
  1247. End Rem
  1248. Type TFont
  1249. Method Create:TFont( glyphs:TGlyph[],firstChar:Int,height:Float )
  1250. _glyphs=glyphs
  1251. _firstChar=firstChar
  1252. _height=height
  1253. Return Self
  1254. End Method
  1255. Method GetGlyph:TGlyph( char:Int )
  1256. Local i:Int=char-_firstChar
  1257. If i>=0 And i<_glyphs.Length Return _glyphs[i]
  1258. Return Null
  1259. End Method
  1260. Rem
  1261. bbdoc: Gets width of @text drawn in this font.
  1262. End Rem
  1263. Method TextWidth:Float( Text:String )
  1264. Local w:Float=0.0
  1265. ?bmxng
  1266. For Local char:Int=EachIn Text
  1267. ?Not bmxng
  1268. For Local i:Int=0 Until Text.length
  1269. Local char:Int = Text[i]
  1270. ?
  1271. Local glyph:TGlyph=GetGlyph( char )
  1272. If Not glyph Continue
  1273. w:+glyph.advance
  1274. Next
  1275. Return w
  1276. End Method
  1277. Rem
  1278. bbdoc: Gets height of @text drawn in this font.
  1279. End Rem
  1280. Method TextHeight:Float( Text:String )
  1281. Return _height
  1282. End Method
  1283. Rem
  1284. bbdoc: Loads a fixed width font from @path.
  1285. about: Glyphs should be laid out horizontally within the source image.
  1286. If @padded is true, then each glyph is assumed to have a transparent one pixel padding border around it.
  1287. End Rem
  1288. Function Load:TFont( url:Object,firstChar:Int,numChars:Int,padded:Int )
  1289. Local image:TImage=TImage.Load( url )
  1290. If Not image Return Null
  1291. Local cellWidth:Int=image.Width()/numChars
  1292. Local cellHeight:Int=image.Height()
  1293. Local glyphX:Int=0,glyphY:Int=0,glyphWidth:Int=cellWidth,glyphHeight:Int=cellHeight
  1294. If padded glyphX:+1;glyphY:+1;glyphWidth:-2;glyphHeight:-2
  1295. Local w:Int=image.Width()/cellWidth
  1296. Local h:Int=image.Height()/cellHeight
  1297. Local glyphs:TGlyph[]=New TGlyph[numChars]
  1298. For Local i:Int=0 Until numChars
  1299. Local y:Int=i / w
  1300. Local x:Int=i Mod w
  1301. Local glyph:TGlyph=New TGlyph.Create( image,firstChar+i,x*cellWidth+glyphX,y*cellHeight+glyphY,glyphWidth,glyphHeight,glyphWidth )
  1302. glyphs[i]=glyph
  1303. Next
  1304. Return New TFont.Create( glyphs,firstChar,glyphHeight )
  1305. End Function
  1306. Function LoadSize:TFont( url:Object,cellWidth:Int,cellHeight:Int,glyphX:Int,glyphY:Int,glyphWidth:Int,glyphHeight:Int,firstChar:Int,numChars:Int )
  1307. Local image:TImage=TImage.Load( url )
  1308. If Not image Return Null
  1309. Local w:Int=image.Width()/cellWidth
  1310. Local h:Int=image.Height()/cellHeight
  1311. Local glyphs:TGlyph[]=New TGlyph[numChars]
  1312. For Local i:Int=0 Until numChars
  1313. Local y:Int=i / w
  1314. Local x:Int=i Mod w
  1315. Local glyph:TGlyph=New TGlyph.Create( image,firstChar+i,x*cellWidth+glyphX,y*cellHeight+glyphY,glyphWidth,glyphHeight,glyphWidth )
  1316. glyphs[i]=glyph
  1317. Next
  1318. Return New TFont.Create( glyphs,firstChar,glyphHeight )
  1319. End Function
  1320. 'Private
  1321. Field _glyphs:TGlyph[]
  1322. Field _firstChar:Int
  1323. Field _height:Float
  1324. End Type
  1325. '***** DrawList *****
  1326. Type TDrawOp
  1327. ' Field shader:Shader
  1328. Field material:TMaterial
  1329. Field blend:Int
  1330. Field order:Int
  1331. Field count:Int
  1332. End Type
  1333. Type TBlendMode
  1334. Const Opaque:Int=0
  1335. Const Alpha:Int=1
  1336. Const Additive:Int=2
  1337. Const Multiply:Int=3
  1338. Const Multiply2:Int=4
  1339. End Type
  1340. Rem
  1341. bbdoc: A drawlist contains drawing state and a sequence of 2d drawing operations.
  1342. about:
  1343. You add drawing operations to a drawlist using any of the Draw methods. When a drawing operation is added, the current drawing state is captured by the drawing operation. Further changes to the drawing state will not affect drawing operations already in the drawlist.
  1344. A [[Canvas]] extends [[DrawList]], and can be used to draw directly to the app window or an image. A drawlist can also be rendered to a canvas using [[Canvas.RenderDrawList]].
  1345. A drawlist's drawing state consists of:
  1346. | @Drawing state | @Description
  1347. | Current color | [[SetColor]]
  1348. | Current 2d matrix | [[Translate]], [[Rotate]], [[Scale]], [[PushMatrix]], [[PopMatrix]]
  1349. | Current blend mode | [[SetBlendMode]]
  1350. | Current font | [[DrawText]]
  1351. End Rem
  1352. Type TDrawList
  1353. Method New()
  1354. InitMojo2
  1355. _color = __colorArray
  1356. SetFont Null
  1357. SetDefaultMaterial _fastShader.DefaultMaterial()
  1358. End Method
  1359. Method SetBlendMode( blend:Int )
  1360. _blend=blend
  1361. End Method
  1362. Method BlendMode:Int()
  1363. Return _blend
  1364. End Method
  1365. Method SetColor( r:Float,g:Float,b:Float,a:Float = -1 )
  1366. Local c:Float Ptr = _color
  1367. c[0]=r
  1368. c[1]=g
  1369. c[2]=b
  1370. If a >= 0
  1371. c[3]=a
  1372. _alpha=a*255
  1373. End If
  1374. _pmcolor=Int(_alpha) Shl 24 | Int(c[2]*_alpha) Shl 16 | Int(c[1]*_alpha) Shl 8 | Int(c[0]*_alpha)
  1375. End Method
  1376. Method SetAlpha( a:Float )
  1377. _color[3]=a
  1378. _alpha=a*255
  1379. _pmcolor=Int(_alpha) Shl 24 | Int(_color[2]*_alpha) Shl 16 | Int(_color[1]*_alpha) Shl 8 | Int(_color[0]*_alpha)
  1380. End Method
  1381. Method Color:Float[]()
  1382. Return [_color[0],_color[1],_color[2],_color[3]]
  1383. End Method
  1384. Method GetColor( color:Float[] )
  1385. color[0]=_color[0]
  1386. color[1]=_color[1]
  1387. color[2]=_color[2]
  1388. If color.Length>3 color[3]=_color[3]
  1389. End Method
  1390. Method Alpha:Float()
  1391. Return _color[3]
  1392. End Method
  1393. Rem
  1394. bbdoc: Sets the current 2d matrix to the identity matrix.
  1395. about: Same as SetMatrix( 1,0,0,1,0,0 ).
  1396. end rem
  1397. Method ResetMatrix()
  1398. _ix=1;_iy=0
  1399. _jx=0;_jy=1
  1400. _tx=0;_ty=0
  1401. End Method
  1402. Rem
  1403. bbdoc: Sets the current 2d matrix to the given matrix.
  1404. end rem
  1405. Method SetMatrix( ix:Float,iy:Float,jx:Float,jy:Float,tx:Float,ty:Float )
  1406. _ix=ix;_iy=iy
  1407. _jx=jx;_jy=jy
  1408. _tx=tx;_ty=ty
  1409. End Method
  1410. Rem
  1411. bbdoc: Gets the current 2d matrix.
  1412. end rem
  1413. Method GetMatrix( matrix:Float[] )
  1414. matrix[0]=_ix
  1415. matrix[1]=_iy
  1416. matrix[2]=_jx
  1417. matrix[3]=_jy
  1418. matrix[4]=_tx
  1419. matrix[5]=_ty
  1420. End Method
  1421. Rem
  1422. bbdoc: Multiplies the current 2d matrix by the given matrix.
  1423. end rem
  1424. Method Transform( ix:Float,iy:Float,jx:Float,jy:Float,tx:Float,ty:Float )
  1425. Local ix2:Float=ix*_ix+iy*_jx
  1426. Local iy2:Float=ix*_iy+iy*_jy
  1427. Local jx2:Float=jx*_ix+jy*_jx
  1428. Local jy2:Float=jx*_iy+jy*_jy
  1429. Local tx2:Float=tx*_ix+ty*_jx+_tx
  1430. Local ty2:Float=tx*_iy+ty*_jy+_ty
  1431. SetMatrix ix2,iy2,jx2,jy2,tx2,ty2
  1432. End Method
  1433. Rem
  1434. bbdoc: Translates the current 2d matrix.
  1435. end rem
  1436. Method Translate( tx:Float,ty:Float )
  1437. Transform 1,0,0,1,tx,ty
  1438. End Method
  1439. Rem
  1440. bbdoc: Rotates the current 2d matrix.
  1441. end rem
  1442. Method Rotate( rz:Float )
  1443. Transform Float(Cos( rz )),Float(-Sin( rz )),Float(Sin( rz )),Float(Cos( rz )),0,0
  1444. End Method
  1445. Rem
  1446. bbdoc: Scales the current 2d matrix.
  1447. end rem
  1448. Method Scale( sx:Float,sy:Float )
  1449. Transform sx,0,0,sy,0,0
  1450. End Method
  1451. Rem
  1452. bbdoc: Translates and rotates (in that order) the current 2d matrix.
  1453. end rem
  1454. Method TranslateRotate( tx:Float,ty:Float,rz:Float )
  1455. Translate tx,ty
  1456. Rotate rz
  1457. End Method
  1458. Rem
  1459. bbdoc: Rotates and scales (in that order) the current 2d matrix.
  1460. end rem
  1461. Method RotateScale( rz:Float,sx:Float,sy:Float )
  1462. Rotate rz
  1463. Scale sx,sy
  1464. End Method
  1465. Method TranslateScale( tx:Float,ty:Float,sx:Float,sy:Float )
  1466. Translate tx,ty
  1467. Scale sx,sy
  1468. End Method
  1469. Rem
  1470. bbdoc: Translates, rotates and scales (in that order) the current 2d matrix.
  1471. end rem
  1472. Method TranslateRotateScale( tx:Float,ty:Float,rz:Float,sx:Float,sy:Float )
  1473. Translate tx,ty
  1474. Rotate rz
  1475. Scale sx,sy
  1476. End Method
  1477. Rem
  1478. bbdoc: Sets the maximum number of 2d matrices that can be pushed onto the matrix stack using @PushMatrix.
  1479. end rem
  1480. Method SetMatrixStackCapacity( capacity:Int )
  1481. '_matStack=_matStack.Resize( capacity*6 )
  1482. _matStack = _matStack[..capacity*6]
  1483. _matSp=0
  1484. End Method
  1485. Rem
  1486. bbdoc: Gets the maximum number of 2d matrices that can be pushed onto the matrix stack using @PushMatrix.
  1487. end rem
  1488. Method MatrixStackCapacity:Int()
  1489. Return _matStack.Length/6
  1490. End Method
  1491. Rem
  1492. bbdoc: Pushes the current 2d matrix on the 2d matrix stack.
  1493. end rem
  1494. Method PushMatrix()
  1495. _matStack[_matSp+0]=_ix;_matStack[_matSp+1]=_iy
  1496. _matStack[_matSp+2]=_jx;_matStack[_matSp+3]=_jy
  1497. _matStack[_matSp+4]=_tx;_matStack[_matSp+5]=_ty
  1498. _matSp:+6
  1499. If _matSp>=_matStack.Length _matSp:-_matStack.Length
  1500. End Method
  1501. Rem
  1502. bbdoc: Pops the current 2d matrix from the 2d matrix stack.
  1503. end rem
  1504. Method PopMatrix()
  1505. _matSp:-6
  1506. If _matSp<0 _matSp:+_matStack.Length
  1507. _ix=_matStack[_matSp+0]
  1508. _iy=_matStack[_matSp+1]
  1509. _jx=_matStack[_matSp+2]
  1510. _jy=_matStack[_matSp+3]
  1511. _tx=_matStack[_matSp+4]
  1512. _ty=_matStack[_matSp+5]
  1513. End Method
  1514. Rem
  1515. bbdoc: Sets current font for use with #DrawText.
  1516. about: If @font is null, a default font is used.
  1517. end rem
  1518. Method SetFont( font:TFont )
  1519. If Not font font=defaultFont
  1520. _font=font
  1521. End Method
  1522. Rem
  1523. bbdoc: Gets the current font.
  1524. end rem
  1525. Method Font:TFont()
  1526. Return _font
  1527. End Method
  1528. Rem
  1529. bbdoc: Sets the default material used for drawing operations that use a null material.
  1530. end rem
  1531. Method SetDefaultMaterial( material:TMaterial )
  1532. _defaultMaterial=material
  1533. End Method
  1534. Rem
  1535. bbdoc: Returns the current default material.
  1536. end rem
  1537. Method DefaultMaterial:TMaterial()
  1538. Return _defaultMaterial
  1539. End Method
  1540. Rem
  1541. bbdoc: Draws a point at @x0,@y0.
  1542. about: If @material is null, the current default material is used.
  1543. end rem
  1544. Method DrawPoint( x0:Float,y0:Float,material:TMaterial=Null,s0:Float=0,t0:Float=0 )
  1545. BeginPrim material,1
  1546. PrimVert x0+.5,y0+.5,s0,t0
  1547. End Method
  1548. Rem
  1549. bbdoc: Draws a line from @x0,@y0 to @x1,@y1.
  1550. about: If @material is null, the current default material is used.
  1551. end rem
  1552. Method DrawLine( x0:Float,y0:Float,x1:Float,y1:Float,material:TMaterial=Null,s0:Float=0,t0:Float=0,s1:Float=1,t1:Float=0 )
  1553. BeginPrim material,2
  1554. PrimVert x0+.5,y0+.5,s0,t0
  1555. PrimVert x1+.5,y1+.5,s1,t1
  1556. End Method
  1557. Rem
  1558. bbdoc: Draw a triangle.
  1559. about: If @material is null, the current default material is used.
  1560. End Rem
  1561. Method DrawTriangle( x0:Float,y0:Float,x1:Float,y1:Float,x2:Float,y2:Float,material:TMaterial=Null,s0:Float=.5,t0:Float=0,s1:Float=1,t1:Float=1,s2:Float=0,t2:Float=1 )
  1562. BeginPrim material,3
  1563. PrimVert x0,y0,s0,t0
  1564. PrimVert x1,y1,s1,t1
  1565. PrimVert x2,y2,s2,t2
  1566. End Method
  1567. Rem
  1568. bbdoc: Draw a quad.
  1569. about: If @material is null, the current default material is used.
  1570. end rem
  1571. Method DrawQuad( x0:Float,y0:Float,x1:Float,y1:Float,x2:Float,y2:Float,x3:Float,y3:Float,material:TMaterial=Null,s0:Float=.5,t0:Float=0,s1:Float=1,t1:Float=1,s2:Float=0,t2:Float=1 )
  1572. BeginPrim material,4
  1573. PrimVert x0,y0,s0,t0
  1574. PrimVert x1,y1,s1,t1
  1575. PrimVert x2,y2,s2,t2
  1576. PrimVert x3,y3,s2,t2
  1577. End Method
  1578. Rem
  1579. bbdoc: Draw an oval in the given rectangle.
  1580. about: If @material is null, the current default material is used.
  1581. end rem
  1582. Method DrawOval( x:Float,y:Float,width:Float,height:Float,material:TMaterial=Null )
  1583. Local xr:Float=width/2.0
  1584. Local yr:Float=height/2.0
  1585. Local dx_x:Float=xr*_ix
  1586. Local dx_y:Float=xr*_iy
  1587. Local dy_x:Float=yr*_jx
  1588. Local dy_y:Float=yr*_jy
  1589. Local dx:Float=Sqr( dx_x*dx_x+dx_y*dx_y )
  1590. Local dy:Float=Sqr( dy_x*dy_x+dy_y*dy_y )
  1591. Local n:Int=Int( dx+dy )
  1592. If n<12
  1593. n=12
  1594. Else If n>MAX_VERTICES
  1595. n=MAX_VERTICES
  1596. Else
  1597. n:&~3
  1598. EndIf
  1599. Local x0:Float=x+xr
  1600. Local y0:Float=y+yr
  1601. BeginPrim material,n
  1602. For Local i:Int=0 Until n
  1603. Local th:Float=i*360.0/n
  1604. Local px:Float=x0+Cos( th ) * xr
  1605. Local py:Float=y0+Sin( th ) * yr
  1606. PrimVert px,py,0,0
  1607. Next
  1608. End Method
  1609. Rem
  1610. bbdoc: Draw an ellipse at @x, @y with radii @xRadius, @yRadius.
  1611. about: If @material is null, the current default material is used.
  1612. end rem
  1613. Method DrawEllipse( x:Float,y:Float,xr:Float,yr:Float,material:TMaterial=Null )
  1614. DrawOval x-xr,y-yr,xr*2,yr*2,material
  1615. End Method
  1616. Rem
  1617. bbdoc: Draw a circle at @x, @y with radius @radius.
  1618. about: If @material is null, the current default material is used.
  1619. end rem
  1620. Method DrawCircle( x:Float,y:Float,r:Float,material:TMaterial=Null )
  1621. DrawOval x-r,y-r,r*2,r*2,material
  1622. End Method
  1623. Method DrawPoly( vertices:Float[],material:TMaterial=Null )
  1624. Local n:Int=vertices.Length/2
  1625. If n<3 Or n>MAX_VERTICES Return
  1626. BeginPrim material,n
  1627. For Local i:Int=0 Until n
  1628. PrimVert vertices[i*2],vertices[i*2+1],0,0
  1629. Next
  1630. End Method
  1631. Rem
  1632. bbdoc: Draw a batch of primtives.
  1633. about:
  1634. @order is the number of vertices for each primitive, eg: 1 for points, 2 for lines, 3 for triangles etc.
  1635. @count is the number of primitives to draw.
  1636. The @vertices array contains x,y vertex data, and must be at least @count \* @order \* 2 long.
  1637. If @material is null, the current default material is used.
  1638. end rem
  1639. Method DrawPrimitives( order:Int,count:Int,vertices:Float[],material:TMaterial=Null )
  1640. BeginPrims material,order,count
  1641. Local p:Int=0
  1642. For Local i:Int=0 Until count
  1643. For Local j:Int=0 Until order
  1644. PrimVert vertices[p],vertices[p+1],0,0
  1645. p:+2
  1646. Next
  1647. Next
  1648. End Method
  1649. Rem
  1650. bbdoc: Draw a batch of primtives.
  1651. about:
  1652. @order is the number of vertices for each primitive, eg: 1 for points, 2 for lines, 3 for triangles etc.
  1653. @count is the number of primitives to draw.
  1654. The @vertices array contains x,y vertex data, and must be at least @count \* @order \* 2 long.
  1655. The @texcoords array contains s,t texture coordinate data, and must be at least @count \* @order \* 2 long.
  1656. If @material is null, the current default material is used.
  1657. end rem
  1658. Method DrawPrimitivesCoords( order:Int,count:Int,vertices:Float[],texcoords:Float[],material:TMaterial=Null )
  1659. BeginPrims material,order,count
  1660. Local p:Int=0
  1661. For Local i:Int=0 Until count
  1662. For Local j:Int=0 Until order
  1663. PrimVert vertices[p],vertices[p+1],texcoords[p],texcoords[p+1]
  1664. p:+2
  1665. Next
  1666. Next
  1667. End Method
  1668. Rem
  1669. bbdoc: Draw a batch of indexed primtives.
  1670. about:
  1671. @order is the number of vertices for each primitive, eg: 1 for points, 2 for lines, 3 for triangles etc.
  1672. @count is the number of primitives to draw.
  1673. The @vertices array contains x,y vertex data.
  1674. The @indices array contains vertex indices, and must be at least @count \* @order long.
  1675. If @material is null, the current default material is used.
  1676. end rem
  1677. Method DrawIndexedPrimitives( order:Int,count:Int,vertices:Float[],indices:Int[],material:TMaterial=Null )
  1678. BeginPrims material,order,count
  1679. Local p:Int=0
  1680. For Local i:Int=0 Until count
  1681. For Local j:Int=0 Until order
  1682. Local k:Int=indices[p+j]*2
  1683. PrimVert vertices[k],vertices[k+1],0,0
  1684. Next
  1685. p:+order
  1686. Next
  1687. End Method
  1688. Method DrawIndexedPrimitivesCoords( order:Int,count:Int,vertices:Float[],texcoords:Float[],indices:Int[],material:TMaterial=Null )
  1689. BeginPrims material,order,count
  1690. Local p:Int=0
  1691. For Local i:Int=0 Until count
  1692. For Local j:Int=0 Until order
  1693. Local k:Int=indices[p+j]*2
  1694. PrimVert vertices[k],vertices[k+1],texcoords[k],texcoords[k+1]
  1695. Next
  1696. p:+order
  1697. Next
  1698. End Method
  1699. Rem
  1700. bbdoc: Draws a rect from @x,@y to @x+@width,@y+@height.
  1701. about: If @material is null, the current default material is used.
  1702. end rem
  1703. Method DrawRect( x0:Float,y0:Float,width:Float,height:Float,material:TMaterial=Null,s0:Float=0,t0:Float=0,s1:Float=1,t1:Float=1 )
  1704. Local x1:Float=x0+width
  1705. Local y1:Float=y0+height
  1706. BeginPrim material,4
  1707. PrimVert x0,y0,s0,t0
  1708. PrimVert x1,y0,s1,t0
  1709. PrimVert x1,y1,s1,t1
  1710. PrimVert x0,y1,s0,t1
  1711. End Method
  1712. Rem
  1713. bbdoc: Draws a rect from @x,@y to @x+@width,@y+@height filled with @image.
  1714. about: The image's handle is ignored.
  1715. end rem
  1716. Method DrawRectImage( x0:Float,y0:Float,width:Float,height:Float,image:TImage )
  1717. DrawRect x0,y0,width,height,image._material,image._s0,image._t0,image._s1,image._t1
  1718. End Method
  1719. Rem
  1720. bbdoc: Draws a rect at @x,@y filled with the given subrect of @image.
  1721. about: The image's handle is ignored.
  1722. end rem
  1723. Method DrawRectImageSource( x:Float,y:Float,image:TImage,sourceX:Int,sourceY:Int,sourceWidth:Int,sourceHeight:Int )
  1724. DrawRectImageSourceSize( x,y,sourceWidth,sourceHeight,image,sourceX,sourceY,sourceWidth,sourceHeight )
  1725. End Method
  1726. Rem
  1727. bbdoc: Draws a rect from @x,@y to @x+@width,@y+@height filled with the given subrect of @image.
  1728. about: The image's handle is ignored.
  1729. end rem
  1730. Method DrawRectImageSourceSize( x0:Float,y0:Float,width:Float,height:Float,image:TImage,sourceX:Int,sourceY:Int,sourceWidth:Int,sourceHeight:Int )
  1731. Local material:TMaterial=image._material
  1732. Local s0:Float=Float(image._x+sourceX)/Float(material.Width())
  1733. Local t0:Float=Float(image._y+sourceY)/Float(material.Height())
  1734. Local s1:Float=Float(image._x+sourceX+sourceWidth)/Float(material.Width())
  1735. Local t1:Float=Float(image._y+sourceY+sourceHeight)/Float(material.Height())
  1736. DrawRect x0,y0,width,height,material,s0,t0,s1,t1
  1737. End Method
  1738. 'gradient rect - kinda hacky, but doesn't slow anything else down
  1739. Method DrawGradientRect( x0:Float,y0:Float,width:Float,height:Float,r0:Float,g0:Float,b0:Float,a0:Float,r1:Float,g1:Float,b1:Float,a1:Float,axis:Int )
  1740. r0:*_color[0];g0:*_color[1];b0:*_color[2];a0:*_alpha
  1741. r1:*_color[0];g1:*_color[1];b1:*_color[2];a1:*_alpha
  1742. Local pm0:Int=Int( a0 ) Shl 24 | Int( b0*a0 ) Shl 16 | Int( g0*a0 ) Shl 8 | Int( r0*a0 )
  1743. Local pm1:Int=Int( a1 ) Shl 24 | Int( b1*a0 ) Shl 16 | Int( g1*a0 ) Shl 8 | Int( r1*a0 )
  1744. Local x1:Float=x0+width
  1745. Local y1:Float=y0+height
  1746. Local s0:Float=0.0
  1747. Local t0:Float=0.0
  1748. Local s1:Float=1.0
  1749. Local t1:Float=1.0
  1750. BeginPrim Null,4
  1751. Local pmcolor:Int=_pmcolor
  1752. BeginPrim Null,4
  1753. Select axis
  1754. Case 0 'left->right
  1755. _pmcolor=pm0
  1756. PrimVert x0,y0,s0,t0
  1757. _pmcolor=pm1
  1758. PrimVert x1,y0,s1,t0
  1759. PrimVert x1,y1,s1,t1
  1760. _pmcolor=pm0
  1761. PrimVert x0,y1,s0,t1
  1762. Default 'top->bottom
  1763. _pmcolor=pm0
  1764. PrimVert x0,y0,s0,t0
  1765. PrimVert x1,y0,s1,t0
  1766. _pmcolor=pm1
  1767. PrimVert x1,y1,s1,t1
  1768. PrimVert x0,y1,s0,t1
  1769. End Select
  1770. _pmcolor=pmcolor
  1771. End Method
  1772. Method DrawImageImage( image:TImage )
  1773. BeginPrim image._material,4
  1774. PrimVert image._x0,image._y0,image._s0,image._t0
  1775. PrimVert image._x1,image._y0,image._s1,image._t0
  1776. PrimVert image._x1,image._y1,image._s1,image._t1
  1777. PrimVert image._x0,image._y1,image._s0,image._t1
  1778. If image._caster AddShadowCaster image._caster
  1779. End Method
  1780. Method DrawImage( image:TImage,tx:Float,ty:Float )
  1781. PushMatrix
  1782. Translate tx,ty
  1783. DrawImageImage image
  1784. PopMatrix
  1785. End Method
  1786. Method DrawImageXYZ( image:TImage,tx:Float,ty:Float,rz:Float )
  1787. PushMatrix
  1788. TranslateRotate tx,ty,rz
  1789. DrawImageImage image
  1790. PopMatrix
  1791. End Method
  1792. Method DrawImageXYZS( image:TImage,tx:Float,ty:Float,rz:Float,sx:Float,sy:Float )
  1793. PushMatrix
  1794. TranslateRotateScale tx,ty,rz,sx,sy
  1795. DrawImageImage image
  1796. PopMatrix
  1797. End Method
  1798. Rem
  1799. bbdoc: Draws @text at @x,@y in the current font.
  1800. end rem
  1801. Method DrawText( Text:String,x:Float,y:Float,xhandle:Float=0,yhandle:Float=0 )
  1802. x:-_font.TextWidth( Text )*xhandle
  1803. y:-_font.TextHeight( Text )*yhandle
  1804. ?bmxng
  1805. For Local char:Int=EachIn Text
  1806. ?Not bmxng
  1807. For Local i:Int=0 Until Text.length
  1808. Local char:Int = Text[i]
  1809. ?
  1810. Local glyph:TGlyph=_font.GetGlyph( char )
  1811. If Not glyph Continue
  1812. DrawRectImageSource x,y,glyph.image,glyph.x,glyph.y,glyph.width,glyph.height
  1813. x:+glyph.advance
  1814. Next
  1815. End Method
  1816. Rem
  1817. bbdoc: Draws a shadow volume.
  1818. end rem
  1819. Method DrawShadow:Int( lx:Float,ly:Float,x0:Float,y0:Float,x1:Float,y1:Float )
  1820. Local ext:Int=1024
  1821. Local dx:Float=x1-x0
  1822. Local dy:Float=y1-y0
  1823. Local d0:Float=Sqr( dx*dx+dy*dy )
  1824. Local nx:Float=-dy/d0
  1825. Local ny:Float=dx/d0
  1826. Local pd:Float=-(x0*nx+y0*ny)
  1827. Local d:Float=lx*nx+ly*ny+pd
  1828. If d<0 Return False
  1829. Local x2:Float=x1-lx
  1830. Local y2:Float=y1-ly
  1831. 'Local d2:Float=ext/Sqr( x2*x2+y2*y2 )
  1832. x2=lx+x2*ext;y2=ly+y2*ext
  1833. Local x3:Float=x0-lx
  1834. Local y3:Float=y0-ly
  1835. 'Local d3:Float=ext/Sqr( x3*x3+y3*y3 )
  1836. x3=lx+x3*ext;y3=ly+y3*ext
  1837. Local x4:Float=(x2+x3)/2-lx
  1838. Local y4:Float=(y2+y3)/2-ly
  1839. 'Local d4:Float=ext/Sqr( x4*x4+y4*y4 )
  1840. x4=lx+x4*ext;y4=ly+y4*ext
  1841. DrawTriangle x0,y0,x4,y4,x3,y3
  1842. DrawTriangle x0,y0,x1,y1,x4,y4
  1843. DrawTriangle x1,y1,x2,y2,x4,y4
  1844. Return True
  1845. End Method
  1846. Rem
  1847. bbdoc: Draws multiple shadow volumes.
  1848. end rem
  1849. Method DrawShadows( x0:Float,y0:Float,drawList:TDrawList )
  1850. Local lx:Float= x0 * _ix + y0 * _jx + _tx
  1851. Local ly:Float= x0 * _iy + y0 * _jy + _ty
  1852. Local verts:Float[]=drawList._casterVerts.Data
  1853. Local v0:Int=0
  1854. For Local i:Int=0 Until drawList._casters.Length
  1855. Local caster:TShadowCaster=drawList._casters.Get( i )
  1856. Local n:Int=caster._verts.Length
  1857. Select caster._kind
  1858. Case 0 'closed loop
  1859. Local x0:Float=verts[v0+n-2]
  1860. Local y0:Float=verts[v0+n-1]
  1861. For Local i:Int=0 Until n-1 Step 2
  1862. Local x1:Float=verts[v0+i]
  1863. Local y1:Float=verts[v0+i+1]
  1864. DrawShadow( lx,ly,x0,y0,x1,y1 )
  1865. x0=x1
  1866. y0=y1
  1867. Next
  1868. Case 1 'open loop
  1869. Case 2 'edge soup
  1870. End Select
  1871. v0:+n
  1872. Next
  1873. End Method
  1874. Rem
  1875. bbdoc: Adds a shadow caster to the drawlist.
  1876. end rem
  1877. Method AddShadowCaster( caster:TShadowCaster )
  1878. _casters.Push caster
  1879. Local verts:Float[]=caster._verts
  1880. For Local i:Int=0 Until verts.Length-1 Step 2
  1881. Local x0:Float=verts[i]
  1882. Local y0:Float=verts[i+1]
  1883. _casterVerts.Push x0*_ix+y0*_jx+_tx
  1884. _casterVerts.Push x0*_iy+y0*_jy+_ty
  1885. Next
  1886. End Method
  1887. Rem
  1888. bbdoc: Adds a shadow caster to the drawlist at @tx,@ty.
  1889. end rem
  1890. Method AddShadowCasterXY( caster:TShadowCaster,tx:Float,ty:Float )
  1891. PushMatrix
  1892. Translate tx,ty
  1893. AddShadowCaster caster
  1894. PopMatrix
  1895. End Method
  1896. Method AddShadowCasterXYZ( caster:TShadowCaster,tx:Float,ty:Float,rz:Float )
  1897. PushMatrix
  1898. TranslateRotate tx,ty,rz
  1899. AddShadowCaster caster
  1900. PopMatrix
  1901. End Method
  1902. Method AddShadowCasterXYZS( caster:TShadowCaster,tx:Float,ty:Float,rz:Float,sx:Float,sy:Float )
  1903. PushMatrix
  1904. TranslateRotateScale tx,ty,rz,sx,sy
  1905. AddShadowCaster caster
  1906. PopMatrix
  1907. End Method
  1908. Method IsEmpty:Int()
  1909. Return _next=0
  1910. End Method
  1911. Method Compact()
  1912. If _data.Size()=_next Return
  1913. Local data:TBank=New TBank.Create( _next )
  1914. '_data.CopyBytes 0,data,0,_next
  1915. '_data.Discard
  1916. ?bmxng
  1917. MemCopy(data._buf,_data._buf,Size_T(_next))
  1918. ?Not bmxng
  1919. MemCopy(data._buf,_data._buf,_next)
  1920. ?
  1921. _data=data
  1922. End Method
  1923. Method RenderOp( op:TDrawOp,index:Int,count:Int )
  1924. If Not op.material.Bind() Return
  1925. If op.blend<>rs_blend
  1926. rs_blend=op.blend
  1927. Select rs_blend
  1928. Case TBlendMode.Opaque
  1929. glDisable GL_BLEND
  1930. Case TBlendMode.Alpha
  1931. glEnable GL_BLEND
  1932. glBlendFunc GL_ONE,GL_ONE_MINUS_SRC_ALPHA
  1933. Case TBlendMode.Additive
  1934. glEnable GL_BLEND
  1935. glBlendFunc GL_ONE,GL_ONE
  1936. Case TBlendMode.Multiply
  1937. glEnable GL_BLEND
  1938. glBlendFunc GL_DST_COLOR,GL_ONE_MINUS_SRC_ALPHA
  1939. Case TBlendMode.Multiply2
  1940. glEnable GL_BLEND
  1941. glBlendFunc GL_DST_COLOR,GL_ZERO
  1942. End Select
  1943. End If
  1944. Select op.order
  1945. Case 1
  1946. glDrawArrays GL_POINTS,index,count
  1947. Case 2
  1948. glDrawArrays GL_LINES,index,count
  1949. Case 3
  1950. glDrawArrays GL_TRIANGLES,index,count
  1951. Case 4
  1952. glDrawElements GL_TRIANGLES,count/4*6,GL_UNSIGNED_SHORT,Byte Ptr((index/4*6 + (index&3)*MAX_QUAD_INDICES)*2)
  1953. Default
  1954. Local j:Int=0
  1955. While j<count
  1956. glDrawArrays GL_TRIANGLE_FAN,index+j,op.order
  1957. j:+op.order
  1958. Wend
  1959. End Select
  1960. End Method
  1961. Method Render()
  1962. If Not _next Return
  1963. Local offset:Int=0
  1964. Local opid:Int=0
  1965. Local ops:Object[]=_ops.Data
  1966. Local length:Int=_ops.length
  1967. While offset<_next
  1968. Local size:Int=_next-offset
  1969. Local lastop:Int=length
  1970. If size>PRIM_VBO_SIZE
  1971. size=0
  1972. lastop=opid
  1973. While lastop<length
  1974. Local op:TDrawOp=TDrawOp(ops[lastop])
  1975. Local n:Int=op.count*BYTES_PER_VERTEX
  1976. If size+n>PRIM_VBO_SIZE Exit
  1977. size:+n
  1978. lastop:+1
  1979. Wend
  1980. If Not size
  1981. Local op:TDrawOp=TDrawOp(ops[opid])
  1982. Local count:Int=op.count
  1983. While count
  1984. Local n:Int=count
  1985. If n>MAX_VERTICES n=MAX_VERTICES/op.order*op.order
  1986. Local size:Int=n*BYTES_PER_VERTEX
  1987. If VBO_ORPHANING_ENABLED glBufferData GL_ARRAY_BUFFER,PRIM_VBO_SIZE,Null,VBO_USAGE
  1988. glBufferSubData GL_ARRAY_BUFFER,0,size,_data._buf + offset
  1989. RenderOp op,0,n
  1990. offset:+size
  1991. count:-n
  1992. Wend
  1993. opid:+1
  1994. Continue
  1995. EndIf
  1996. EndIf
  1997. If VBO_ORPHANING_ENABLED glBufferData GL_ARRAY_BUFFER,PRIM_VBO_SIZE,Null,VBO_USAGE
  1998. glBufferSubData GL_ARRAY_BUFFER,0,size,_data._buf + offset
  1999. Local index:Int=0
  2000. While opid<lastop
  2001. Local op:TDrawOp=TDrawOp(ops[opid])
  2002. RenderOp op,index,op.count
  2003. index:+op.count
  2004. opid:+1
  2005. Wend
  2006. offset:+size
  2007. Wend
  2008. glGetError
  2009. End Method
  2010. Method Reset()
  2011. _next=0
  2012. Local data:TDrawOp[]=_ops.Data
  2013. For Local i:Int=0 Until _ops.Length
  2014. data[i].material=Null
  2015. freeOps.Push data[i]
  2016. Next
  2017. _ops.Clear()
  2018. _op=nullOp
  2019. _casters.Clear
  2020. _casterVerts.Clear
  2021. End Method
  2022. Method Flush()
  2023. Render
  2024. Reset
  2025. End Method
  2026. ' Protected
  2027. Field _blend:Float=1
  2028. Field _alpha:Float=255.0
  2029. Field _color:Float Ptr
  2030. Field __colorArray:Float[]=[1.0,1.0,1.0,1.0]
  2031. Field _pmcolor:Int=$ffffffff
  2032. Field _ix:Float=1,_iy:Float
  2033. Field _jx:Float,_jy:Float=1
  2034. Field _tx:Float,_ty:Float
  2035. Field _matStack:Float[64*6]
  2036. Field _matSp:Int
  2037. Field _font:TFont
  2038. Field _defaultMaterial:TMaterial
  2039. ' Private
  2040. Field _data:TBank=New TBank.Create( 4096 )
  2041. Field _next:Int=0
  2042. Field _op:TDrawOp=nullOp
  2043. Field _ops:TDrawOpStack=New TDrawOpStack'<DrawOp>
  2044. Field _casters:TShadowCasterStack=New TShadowCasterStack'<ShadowCaster>
  2045. Field _casterVerts:TFloatStack=New TFloatStack
  2046. Method BeginPrim( material:TMaterial,order:Int ) Final
  2047. If Not material material=_defaultMaterial
  2048. If _next+order*BYTES_PER_VERTEX>_data.Size()
  2049. Local newsize:Int=Max( _data.Size()+_data.Size()/2,_next+order*BYTES_PER_VERTEX )
  2050. Local data:TBank=New TBank.Create( newsize )
  2051. ?bmxng
  2052. MemCopy(data._buf, _data._buf, Size_T(_next))
  2053. ?Not bmxng
  2054. MemCopy(data._buf, _data._buf, _next)
  2055. ?
  2056. '_data.CopyBytes 0,data,0,_next
  2057. '_data.Discard
  2058. _data=data
  2059. EndIf
  2060. If material=_op.material And _blend=_op.blend And order=_op.order
  2061. _op.count:+order
  2062. Return
  2063. EndIf
  2064. If freeOps.Length _op=freeOps.Pop() Else _op=New TDrawOp
  2065. _ops.Push _op
  2066. _op.material=material
  2067. _op.blend=_blend
  2068. _op.order=order
  2069. _op.count=order
  2070. End Method
  2071. Method BeginPrims( material:TMaterial,order:Int,count:Int ) Final
  2072. If Not material material=_defaultMaterial
  2073. count:*order
  2074. If _next+count*BYTES_PER_VERTEX>_data.Size()
  2075. Local newsize:Int=Max( _data.Size()+_data.Size()/2,_next+count*BYTES_PER_VERTEX )
  2076. Local data:TBank=New TBank.Create( newsize )
  2077. ?bmxng
  2078. MemCopy data._buf, _data._buf, Size_T(_next)
  2079. ?Not bmxng
  2080. MemCopy data._buf, _data._buf, _next
  2081. ?
  2082. _data=data
  2083. EndIf
  2084. If material=_op.material And _blend=_op.blend And order=_op.order
  2085. _op.count:+count
  2086. Return
  2087. EndIf
  2088. If freeOps.Length _op=freeOps.Pop() Else _op=New TDrawOp
  2089. _ops.Push _op
  2090. _op.material=material
  2091. _op.blend=_blend
  2092. _op.order=order
  2093. _op.count=count
  2094. End Method
  2095. Method PrimVert( x0:Float,y0:Float,s0:Float,t0:Float ) Final
  2096. Local df:Float Ptr = Float Ptr(_data._buf + _next)
  2097. Local di:Int Ptr = Int Ptr(_data._buf + _next)
  2098. df[0] = x0 * _ix + y0 * _jx + _tx
  2099. df[1] = x0 * _iy + y0 * _jy + _ty
  2100. df[2] = s0
  2101. df[3] = t0
  2102. df[4] = _ix
  2103. df[5] = _iy
  2104. di[6] = _pmcolor
  2105. _next:+BYTES_PER_VERTEX
  2106. End Method
  2107. End Type
  2108. '***** Canvas *****
  2109. Type TCanvas Extends TDrawList
  2110. Const MaxLights:Int=MAX_LIGHTS
  2111. Method CreateCanvas:TCanvas( target:Object=Null )
  2112. ' Super.Create()
  2113. Init
  2114. SetRenderTarget target
  2115. SetViewport 0,0,_width,_height
  2116. SetProjection2d 0,_width,0,_height
  2117. Return Self
  2118. End Method
  2119. Method Discard()
  2120. End Method
  2121. Method SetRenderTarget( target:Object )
  2122. FlushPrims
  2123. If Not target
  2124. _image=Null
  2125. _texture=Null
  2126. _width=GraphicsWidth()
  2127. _height=GraphicsHeight()
  2128. _twidth=_width
  2129. _theight=_height
  2130. Else If TImage( target )
  2131. _image=TImage( target )
  2132. _texture=_image.Material().ColorTexture()
  2133. If Not (_texture.Flags() & TTexture.RenderTarget) Throw "Texture is not a render target texture"
  2134. _width=_image.Width()
  2135. _height=_image.Height()
  2136. _twidth=_texture.Width()
  2137. _theight=_texture.Height()
  2138. Else If TTexture( target )
  2139. _image=Null
  2140. _texture=TTexture( target )
  2141. If Not (_texture.Flags() & TTexture.RenderTarget) Throw "Texture is not a render target texture"
  2142. _width=_texture.Width()
  2143. _height=_texture.Height()
  2144. _twidth=_texture.Width()
  2145. _theight=_texture.Height()
  2146. Else
  2147. Throw "RenderTarget object must a TImage, a TTexture or Null"
  2148. EndIf
  2149. _dirty=-1
  2150. End Method
  2151. Method RenderTarget:Object()
  2152. If _image Return _image Else Return _texture
  2153. End Method
  2154. Method Width:Int()
  2155. Return _width
  2156. End Method
  2157. Method Height:Int()
  2158. Return _height
  2159. End Method
  2160. Method SetColorMask( r:Int,g:Int,b:Int,a:Int )
  2161. FlushPrims
  2162. _colorMask[0]=r
  2163. _colorMask[1]=g
  2164. _colorMask[2]=b
  2165. _colorMask[3]=a
  2166. _dirty:|DIRTY_COLORMASK
  2167. End Method
  2168. Method ColorMask:Int[]()
  2169. Return _colorMask
  2170. End Method
  2171. Method SetViewport( x:Int,y:Int,w:Int,h:Int )
  2172. FlushPrims
  2173. _viewport[0]=x
  2174. _viewport[1]=y
  2175. _viewport[2]=w
  2176. _viewport[3]=h
  2177. _dirty:|DIRTY_VIEWPORT
  2178. End Method
  2179. Method Viewport:Int[]()
  2180. Return _viewport
  2181. End Method
  2182. Method SetScissor( x:Int,y:Int,w:Int,h:Int )
  2183. FlushPrims
  2184. _scissor[0]=x
  2185. _scissor[1]=y
  2186. _scissor[2]=w
  2187. _scissor[3]=h
  2188. _dirty:|DIRTY_VIEWPORT
  2189. End Method
  2190. Method Scissor:Int[]()
  2191. Return _scissor
  2192. End Method
  2193. Method SetProjectionMatrix( projMatrix:Float[] )
  2194. FlushPrims
  2195. If projMatrix
  2196. Mat4Copy projMatrix,_projMatrix
  2197. Else
  2198. Mat4InitArray _projMatrix
  2199. EndIf
  2200. _dirty:|DIRTY_SHADER
  2201. End Method
  2202. Method SetProjection2d( Left:Float,Right:Float,top:Float,bottom:Float,znear:Float=-1,zfar:Float=1 )
  2203. FlushPrims
  2204. Mat4Ortho Left,Right,top,bottom,znear,zfar,_projMatrix
  2205. _dirty:|DIRTY_SHADER
  2206. End Method
  2207. Method ProjectionMatrix:Float[]()
  2208. Return _projMatrix
  2209. End Method
  2210. Method SetViewMatrix( viewMatrix:Float[] )
  2211. FlushPrims
  2212. If viewMatrix
  2213. Mat4Copy viewMatrix,_viewMatrix
  2214. Else
  2215. Mat4InitArray _viewMatrix
  2216. End If
  2217. _dirty:|DIRTY_SHADER
  2218. End Method
  2219. Method ViewMatrix:Float[]()
  2220. Return _viewMatrix
  2221. End Method
  2222. Method SetModelMatrix( modelMatrix:Float[] )
  2223. FlushPrims
  2224. If modelMatrix
  2225. Mat4Copy modelMatrix,_modelMatrix
  2226. Else
  2227. Mat4InitArray _modelMatrix
  2228. EndIf
  2229. _dirty:|DIRTY_SHADER
  2230. End Method
  2231. Method ModelMatrix:Float[]()
  2232. Return _modelMatrix
  2233. End Method
  2234. Method SetAmbientLight( r:Float,g:Float,b:Float,a:Float=1 )
  2235. FlushPrims
  2236. _ambientLight[0]=r
  2237. _ambientLight[1]=g
  2238. _ambientLight[2]=b
  2239. _ambientLight[3]=a
  2240. _dirty:|DIRTY_SHADER
  2241. End Method
  2242. Method AmbientLight:Float[]()
  2243. Return _ambientLight
  2244. End Method
  2245. Method SetFogColor( r:Float,g:Float,b:Float,a:Float )
  2246. FlushPrims
  2247. _fogColor[0]=r
  2248. _fogColor[1]=g
  2249. _fogColor[2]=b
  2250. _fogColor[3]=a
  2251. _dirty:|DIRTY_SHADER
  2252. End Method
  2253. Method FogColor:Float[]()
  2254. Return _fogColor
  2255. End Method
  2256. Method SetLightType( index:Int,kind:Int )
  2257. FlushPrims
  2258. Local light:TLightData=_lights[index]
  2259. light.kind=kind
  2260. _dirty:|DIRTY_SHADER
  2261. End Method
  2262. Method GetLightType:Int( index:Int )
  2263. Return _lights[index].kind
  2264. End Method
  2265. Method SetLightColor( index:Int,r:Float,g:Float,b:Float,a:Float=1 )
  2266. FlushPrims
  2267. Local light:TLightData=_lights[index]
  2268. light.color[0]=r
  2269. light.color[1]=g
  2270. light.color[2]=b
  2271. light.color[3]=a
  2272. _dirty:|DIRTY_SHADER
  2273. End Method
  2274. Method GetLightColor:Float[]( index:Int )
  2275. Return _lights[index].color
  2276. End Method
  2277. Method SetLightPosition( index:Int,x:Float,y:Float,z:Float )
  2278. FlushPrims
  2279. Local light:TLightData=_lights[index]
  2280. light.position[0]=x
  2281. light.position[1]=y
  2282. light.position[2]=z
  2283. light.vector[0]=x
  2284. light.vector[1]=y
  2285. light.vector[2]=z
  2286. _dirty:|DIRTY_SHADER
  2287. End Method
  2288. Method GetLightPosition:Float[]( index:Int )
  2289. Return _lights[index].position
  2290. End Method
  2291. Method SetLightRange( index:Int,Range:Float )
  2292. FlushPrims
  2293. Local light:TLightData=_lights[index]
  2294. light.Range=Range
  2295. _dirty:|DIRTY_SHADER
  2296. End Method
  2297. Method GetLightRange:Float( index:Int )
  2298. Return _lights[index].Range
  2299. End Method
  2300. Method SetShadowMap( image:TImage )
  2301. FlushPrims
  2302. _shadowMap=image
  2303. _dirty:|DIRTY_SHADER
  2304. End Method
  2305. Method ShadowMap:TImage()
  2306. Return _shadowMap
  2307. End Method
  2308. Method SetLineWidth( lineWidth:Float )
  2309. FlushPrims
  2310. _lineWidth=lineWidth
  2311. _dirty:|DIRTY_LINEWIDTH
  2312. End Method
  2313. Method LineWidth:Float()
  2314. Return _lineWidth
  2315. End Method
  2316. Method Clear( r:Float=0,g:Float=0,b:Float=0,a:Float=1 )
  2317. FlushPrims
  2318. Validate
  2319. If _clsScissor
  2320. glEnable GL_SCISSOR_TEST
  2321. glScissor _vpx,_vpy,_vpw,_vph
  2322. EndIf
  2323. glClearColor r,g,b,a
  2324. glClear GL_COLOR_BUFFER_BIT
  2325. If _clsScissor glDisable GL_SCISSOR_TEST
  2326. End Method
  2327. Method ReadPixels( x:Int,y:Int,width:Int,height:Int,data:TBank,dataOffset:Int=0,dataPitch:Int=0 )
  2328. FlushPrims
  2329. If Not dataPitch Or dataPitch=width*4
  2330. glReadPixels x,y,width,height,GL_RGBA,GL_UNSIGNED_BYTE,data._buf + dataOffset
  2331. Else
  2332. For Local iy:Int=0 Until height
  2333. glReadPixels x,y+iy,width,1,GL_RGBA,GL_UNSIGNED_BYTE,data._buf + dataOffset+dataPitch*iy
  2334. Next
  2335. EndIf
  2336. End Method
  2337. Method RenderDrawList( drawbuf:TDrawList )
  2338. Local fast:Int=_ix=1 And _iy=0 And _jx=0 And _jy=1 And _tx=0 And _ty=0 And _color[0]=1 And _color[1]=1 And _color[2]=1 And _color[3]=1
  2339. If fast
  2340. FlushPrims
  2341. Validate
  2342. drawbuf.Render
  2343. Return
  2344. EndIf
  2345. tmpMat3d[0]=_ix
  2346. tmpMat3d[1]=_iy
  2347. tmpMat3d[4]=_jx
  2348. tmpMat3d[5]=_jy
  2349. tmpMat3d[12]=_tx
  2350. tmpMat3d[13]=_ty
  2351. tmpMat3d[10]=1
  2352. tmpMat3d[15]=1
  2353. Mat4Multiply _modelMatrix,tmpMat3d,tmpMat3d2
  2354. FlushPrims
  2355. Local tmp:Float[]=_modelMatrix
  2356. _modelMatrix=tmpMat3d2
  2357. rs_globalColor[0]=_color[0]*_color[3]
  2358. rs_globalColor[1]=_color[1]*_color[3]
  2359. rs_globalColor[2]=_color[2]*_color[3]
  2360. rs_globalColor[3]=_color[3]
  2361. _dirty:|DIRTY_SHADER
  2362. Validate
  2363. drawbuf.Render
  2364. _modelMatrix=tmp
  2365. rs_globalColor[0]=1
  2366. rs_globalColor[1]=1
  2367. rs_globalColor[2]=1
  2368. rs_globalColor[3]=1
  2369. _dirty:|DIRTY_SHADER
  2370. End Method
  2371. Method RenderDrawListXYZ( drawList:TDrawList,tx:Float,ty:Float,rz:Float=0,sx:Float=1,sy:Float=1 )
  2372. Super.PushMatrix
  2373. Super.TranslateRotateScale tx,ty,rz,sx,sy
  2374. RenderDrawList( drawList )
  2375. Super.PopMatrix
  2376. End Method
  2377. Method Flush()
  2378. FlushPrims
  2379. If Not _texture Return
  2380. If _texture.Flags() & TTexture.Managed
  2381. Validate
  2382. glDisable GL_SCISSOR_TEST
  2383. glViewport 0,0,_twidth,_theight
  2384. If _width=_twidth And _height=_theight
  2385. glReadPixels 0,0,_twidth,_theight,GL_RGBA,GL_UNSIGNED_BYTE, _texture.Data().pixels
  2386. Else
  2387. For Local y:Int=0 Until _height
  2388. glReadPixels _image._x,_image._y+y,_width,1,GL_RGBA,GL_UNSIGNED_BYTE,_texture.Data().pixels + (_image._y+y) * (_twidth*4) + (_image._x*4)
  2389. Next
  2390. EndIf
  2391. _dirty:|DIRTY_VIEWPORT
  2392. EndIf
  2393. _texture.UpdateMipmaps
  2394. End Method
  2395. Global _tformInvProj:Float[16]
  2396. Global _tformT:Float[]=[0.0,0.0,-1.0,1.0]
  2397. Global _tformP:Float[4]
  2398. Method TransformCoords( coords_in:Float[],coords_out:Float[],Mode:Int=0 )
  2399. Mat4Inverse _projMatrix,_tformInvProj
  2400. Select Mode
  2401. Case 0
  2402. _tformT[0]=(coords_in[0]-_viewport[0])/_viewport[2]*2-1
  2403. _tformT[1]=(coords_in[1]-_viewport[1])/_viewport[3]*2-1
  2404. Mat4Transform _tformInvProj,_tformT,_tformP
  2405. _tformP[0]:/_tformP[3]
  2406. _tformP[1]:/_tformP[3]
  2407. _tformP[2]:/_tformP[3]
  2408. _tformP[3]=1
  2409. coords_out[0]=_tformP[0]
  2410. coords_out[1]=_tformP[1]
  2411. If coords_out.Length>2 coords_out[2]=_tformP[2]
  2412. Default
  2413. Throw "Invalid TransformCoords mode"
  2414. End Select
  2415. End Method
  2416. 'Private
  2417. Const DIRTY_RENDERTARGET:Int=1
  2418. Const DIRTY_VIEWPORT:Int=2
  2419. Const DIRTY_SHADER:Int=4
  2420. Const DIRTY_LINEWIDTH:Int=8
  2421. Const DIRTY_COLORMASK:Int=16
  2422. Field _seq:Int
  2423. Field _dirty:Int=-1
  2424. Field _image:TImage
  2425. Field _texture:TTexture
  2426. Field _width:Int
  2427. Field _height:Int
  2428. Field _twidth:Int
  2429. Field _theight:Int
  2430. Field _shadowMap:TImage
  2431. Field _colorMask:Int[]=[True,True,True,True]
  2432. Field _viewport:Int[]=[0,0,640,480]
  2433. Field _scissor:Int[]=[0,0,100000,100000]
  2434. Field _vpx:Int,_vpy:Int,_vpw:Int,_vph:Int
  2435. Field _scx:Int,_scy:Int,_scw:Int,_sch:Int
  2436. Field _clsScissor:Int
  2437. Field _projMatrix:Float[]=Mat4New()
  2438. Field _invProjMatrix:Float[]=Mat4New()
  2439. Field _viewMatrix:Float[]=Mat4New()
  2440. Field _modelMatrix:Float[]=Mat4New()
  2441. Field _ambientLight:Float[]=[0.0,0.0,0.0,1.0]
  2442. Field _fogColor:Float[]=[0.0,0.0,0.0,0.0]
  2443. Field _lights:TLightData[4]
  2444. Field _lineWidth:Float=1
  2445. Global _active:TCanvas
  2446. Method Init()
  2447. For Local i:Int=0 Until 4
  2448. _lights[i]=New TLightData
  2449. Next
  2450. _dirty=-1
  2451. End Method
  2452. Method FlushPrims()
  2453. If Super.IsEmpty() Return
  2454. Validate
  2455. Super.Flush
  2456. End Method
  2457. Method Validate()
  2458. If _seq<>graphicsSeq
  2459. _seq=graphicsSeq
  2460. InitVbos
  2461. _dirty=-1
  2462. EndIf
  2463. If _active=Self
  2464. If Not _dirty Return
  2465. Else
  2466. If _active _active.Flush
  2467. _active=Self
  2468. _dirty=-1
  2469. EndIf
  2470. ' _dirty=-1
  2471. If _dirty & DIRTY_RENDERTARGET
  2472. If _texture
  2473. glBindFramebuffer GL_FRAMEBUFFER,_texture.GLFramebuffer()
  2474. Else
  2475. glBindFramebuffer GL_FRAMEBUFFER,defaultFbo
  2476. EndIf
  2477. End If
  2478. If _dirty & DIRTY_VIEWPORT
  2479. _vpx=_viewport[0];_vpy=_viewport[1];_vpw=_viewport[2];_vph=_viewport[3]
  2480. If _image
  2481. _vpx:+_image._x
  2482. _vpy:+_image._y
  2483. EndIf
  2484. _scx=_scissor[0];_scy=_scissor[1];_scw=_scissor[2];_sch=_scissor[3]
  2485. If _scx<0 _scx=0 Else If _scx>_vpw _scx=_vpw
  2486. If _scw<0 _scw=0 Else If _scx+_scw>_vpw _scw=_vpw-_scx
  2487. If _scy<0 _scy=0 Else If _scy>_vph _scy=_vph
  2488. If _sch<0 _sch=0 Else If _scy+_sch>_vph _sch=_vph-_scy
  2489. _scx:+_vpx;_scy:+_vpy
  2490. If Not _texture
  2491. _vpy=_theight-_vpy-_vph
  2492. _scy=_theight-_scy-_sch
  2493. EndIf
  2494. glViewport _vpx,_vpy,_vpw,_vph
  2495. If _scx<>_vpx Or _scy<>_vpy Or _scw<>_vpw Or _sch<>_vph
  2496. glEnable GL_SCISSOR_TEST
  2497. glScissor _scx,_scy,_scw,_sch
  2498. _clsScissor=False
  2499. Else
  2500. glDisable GL_SCISSOR_TEST
  2501. _clsScissor=(_scx<>0 Or _scy<>0 Or _vpw<>_twidth Or _vph<>_theight)
  2502. EndIf
  2503. EndIf
  2504. If _dirty & DIRTY_SHADER
  2505. rs_program=Null
  2506. If _texture
  2507. rs_clipPosScale[1]=1
  2508. Mat4Copy _projMatrix,rs_projMatrix
  2509. Else
  2510. rs_clipPosScale[1]=-1
  2511. Mat4Multiply flipYMatrix,_projMatrix,rs_projMatrix
  2512. EndIf
  2513. Mat4Multiply _viewMatrix,_modelMatrix,rs_modelViewMatrix
  2514. Mat4Multiply rs_projMatrix,rs_modelViewMatrix,rs_modelViewProjMatrix
  2515. Vec4Copy _ambientLight,rs_ambientLight
  2516. Vec4Copy _fogColor,rs_fogColor
  2517. rs_numLights=0
  2518. For Local i:Int=0 Until MAX_LIGHTS
  2519. Local light:TLightData=_lights[i]
  2520. If Not light.kind Continue
  2521. Mat4Transform _viewMatrix,light.vector,light.tvector
  2522. rs_lightColors[rs_numLights*4+0]=light.color[0]
  2523. rs_lightColors[rs_numLights*4+1]=light.color[1]
  2524. rs_lightColors[rs_numLights*4+2]=light.color[2]
  2525. rs_lightColors[rs_numLights*4+3]=light.color[3]
  2526. rs_lightVectors[rs_numLights*4+0]=light.tvector[0]
  2527. rs_lightVectors[rs_numLights*4+1]=light.tvector[1]
  2528. rs_lightVectors[rs_numLights*4+2]=light.tvector[2]
  2529. rs_lightVectors[rs_numLights*4+3]=light.Range
  2530. rs_numLights:+1
  2531. Next
  2532. If _shadowMap
  2533. rs_shadowTexture=_shadowMap._material._colorTexture
  2534. Else
  2535. rs_shadowTexture=Null
  2536. EndIf
  2537. rs_blend=-1
  2538. End If
  2539. If _dirty & DIRTY_LINEWIDTH
  2540. glLineWidth _lineWidth
  2541. EndIf
  2542. If _dirty & DIRTY_COLORMASK
  2543. glColorMask Byte(_colorMask[0]),Byte(_colorMask[1]),Byte(_colorMask[2]),Byte(_colorMask[3])
  2544. End If
  2545. _dirty=0
  2546. End Method
  2547. End Type
  2548. ' stacks
  2549. Type TFloatStack
  2550. Field data:Float[]
  2551. Field length:Int
  2552. Method Push( value:Float )
  2553. If length=data.Length
  2554. data=data[..length*2+10]
  2555. EndIf
  2556. data[length]=value
  2557. length:+1
  2558. End Method
  2559. Method Pop:Float()
  2560. length:-1
  2561. Local v:Float=data[length]
  2562. data[length]=Null
  2563. Return v
  2564. End Method
  2565. Method Top:Float()
  2566. Return data[length-1]
  2567. End Method
  2568. Method Clear()
  2569. For Local i:Int=0 Until length
  2570. data[i]=Null
  2571. Next
  2572. length=0
  2573. End Method
  2574. End Type
  2575. Type TDrawOpStack
  2576. Field data:TDrawOp[]
  2577. Field length:Int
  2578. Method Push( value:TDrawOp )
  2579. If length=data.Length
  2580. data=data[..length*2+10]
  2581. EndIf
  2582. data[length]=value
  2583. length:+1
  2584. End Method
  2585. Method Pop:TDrawOp()
  2586. length:-1
  2587. Local v:TDrawOp=data[length]
  2588. data[length]=Null
  2589. Return v
  2590. End Method
  2591. Method Top:TDrawOp()
  2592. Return data[length-1]
  2593. End Method
  2594. Method Clear()
  2595. For Local i:Int=0 Until length
  2596. data[i]=Null
  2597. Next
  2598. length=0
  2599. End Method
  2600. End Type
  2601. Type TShadowCasterStack
  2602. Field data:TShadowCaster[]
  2603. Field length:Int
  2604. Method Push( value:TShadowCaster )
  2605. If length=data.Length
  2606. data=data[..length*2+10]
  2607. EndIf
  2608. data[length]=value
  2609. length:+1
  2610. End Method
  2611. Method Pop:TShadowCaster()
  2612. length:-1
  2613. Local v:TShadowCaster=data[length]
  2614. data[length]=Null
  2615. Return v
  2616. End Method
  2617. Method Top:TShadowCaster()
  2618. Return data[length-1]
  2619. End Method
  2620. Method Get:TShadowCaster(index:Int)
  2621. Return data[index]
  2622. End Method
  2623. Method Clear()
  2624. For Local i:Int=0 Until length
  2625. data[i]=Null
  2626. Next
  2627. length=0
  2628. End Method
  2629. End Type
  2630. Type TDrawListStack
  2631. Field data:TDrawList[]
  2632. Field length:Int
  2633. Method Push( value:TDrawList )
  2634. If length=data.Length
  2635. data=data[..length*2+10]
  2636. EndIf
  2637. data[length]=value
  2638. length:+1
  2639. End Method
  2640. Method Pop:TDrawList()
  2641. length:-1
  2642. Local v:TDrawList=data[length]
  2643. data[length]=Null
  2644. Return v
  2645. End Method
  2646. Method Top:TDrawList()
  2647. Return data[length-1]
  2648. End Method
  2649. Method Get:TDrawList(index:Int)
  2650. Return data[index]
  2651. End Method
  2652. Method Clear()
  2653. For Local i:Int=0 Until length
  2654. data[i]=Null
  2655. Next
  2656. length=0
  2657. End Method
  2658. End Type
  2659. ?Not bmxng
  2660. Type TIntVal
  2661. Field value:Int
  2662. Method Compare:Int(v:Object)
  2663. Return value - TIntVal(v).value
  2664. End Method
  2665. End Type
  2666. ?