renderer.monkey2 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
  1. Namespace mojo3d
  2. #rem monkeydoc The mojo3d Renderer class.
  3. A renderer is an object that renders scenes. There is normally only ever one renderer created and it is created for you automatically when required so you don't normally need to worry about renderers at all.
  4. When a new renderer is created, the config setting `MOJO3D\_RENDERER` can be used to control the type of renderer created. Use "deferred" to create a deferred renderer and "foward" to create a forward renderer. See [[std:std.filesystem.SetConfig|SetConfig]] for more information about config settings. By default, a deferred renderer is created for desktop and web targets and a forward renderer for mobile targets.
  5. #end
  6. Class Renderer
  7. #rem monkeydoc Creates a new renderer.
  8. When a new renderer is created, the config setting `MOJO3D\_RENDERER` can be used to control the type of renderer created. Use "deferred" to create a deferred renderer and "foward" to create a forward renderer. See [[std:std.filesystem.SetConfig|SetConfig]] for more information about config settings. By default, a deferred renderer is created for desktop and web targets and a forward renderer for mobile targets.
  9. #end
  10. Method New()
  11. If Not _current _current=Self
  12. _direct=False
  13. _deferred=False
  14. Local cfg:=GetConfig( "MOJO3D_RENDERER" )
  15. Select cfg
  16. Case "deferred"
  17. _deferred=True
  18. Case "forward"
  19. _deferred=False
  20. Case ""
  21. #If __DESKTOP_TARGET__ Or __WEB_TARGET__
  22. _deferred=True
  23. #else
  24. _deferred=False
  25. #endif
  26. Default
  27. RuntimeError( "Unrecognized MOJO3D_RENDERER config setting value '"+cfg+"'" )
  28. End
  29. Print "GL_VERSION="+opengl.glGetString( opengl.GL_VERSION )
  30. Print "GL_VENDOR="+opengl.glGetString( opengl.GL_VENDOR )
  31. If _deferred
  32. Print "Renderer is using deferred rendering"
  33. Else
  34. Print "Renderer is using forward rendering"
  35. Endif
  36. If _deferred _defs="MX2_DEFERREDRENDERER" Else _defs="MX2_FORWARDRENDERER"
  37. _defs+=";MX2_LINEAROUTPUT"
  38. End
  39. #rem monkeydoc True if renderer is using deferred rendering.
  40. #end
  41. Property Deferred:Bool()
  42. Return _deferred
  43. End
  44. #rem monkeydoc @hidden
  45. #end
  46. Property ShaderDefs:String()
  47. Return _defs
  48. End
  49. #rem monkeydoc Size of the cascaded shadow map texture.
  50. Must be a power of 2 size. Defaults to 2048.
  51. #end
  52. Property CSMTextureSize:Int()
  53. Return _csmSize
  54. Setter( size:Int )
  55. Assert( Log2( size )=Floor( Log2( size ) ),"CSMTextureSize must be a power of 2" )
  56. _csmSize=size
  57. End
  58. #rem monkeydoc Size of the cube texture used for point light shadow mapping.
  59. Must be a power of 2. Defaults to 2048.
  60. #end
  61. Property PSMTextureSize:Int()
  62. Return _psmSize
  63. Setter( size:Int )
  64. Assert( Log2( size )=Floor( Log2( size ) ),"PSMTextureSize must be a power of 2" )
  65. _psmSize=size
  66. End
  67. #rem monkeydoc Gets the current renderer.
  68. If there is no current renderer and new renderer is created.
  69. #end
  70. Function GetCurrent:Renderer()
  71. If Not _current New Renderer
  72. Return _current
  73. End
  74. Method Render( target:RenderTarget,targetSize:Vec2i,viewport:Recti,scene:Scene,viewMatrix:AffineMat4f,projMatrix:Mat4f,near:Float,far:Float ) Virtual
  75. Init()
  76. ValidateCSMShadows()
  77. ValidatePSMShadows()
  78. SetOutputRenderTarget( target,targetSize,viewport )
  79. SetScene( scene )
  80. SetCamera( viewMatrix,projMatrix,near,far )
  81. RenderBackground()
  82. RenderOpaque()
  83. RenderTransparent()
  84. RenderPostEffects()
  85. RenderCopy()
  86. End
  87. Method RenderBackground()
  88. If _scene.SkyTexture
  89. _gdevice.ColorMask=ColorMask.None
  90. _gdevice.DepthMask=True
  91. _gdevice.Clear( Null,1.0 )
  92. _gdevice.ColorMask=ColorMask.All
  93. _gdevice.DepthMask=False
  94. _gdevice.DepthFunc=DepthFunc.Always
  95. _gdevice.BlendMode=BlendMode.Opaque
  96. _gdevice.CullMode=CullMode.None
  97. _gdevice.Shader=_skyboxShader
  98. _gdevice.RenderPass=0
  99. RenderQuad()
  100. Else
  101. _gdevice.ColorMask=ColorMask.All
  102. _gdevice.DepthMask=True
  103. Local color:=_scene.ClearColor
  104. color.r=Pow( color.r,2.2 )
  105. color.g=Pow( color.g,2.2 )
  106. color.b=Pow( color.b,2.2 )
  107. _gdevice.Clear( color,1.0 )
  108. Endif
  109. End
  110. Method RenderDeferredLighting( light:Light )
  111. Local renderPass:=0
  112. Local lvmatrix:=_viewMatrix * light.Matrix
  113. Local qscale:=New Vec2f( 1 )
  114. Local qtrans:=New Vec2f( 0 )
  115. Select light.Type
  116. Case LightType.Directional
  117. If light.CastsShadow RenderDirectionalShadows( light ) ; renderPass|=16
  118. renderPass|=4
  119. Case LightType.Point
  120. Local r:=light.Range
  121. If lvmatrix.t.z<-r
  122. ' Print "clip1, z="+lvmatrix.t.z
  123. Return
  124. Endif
  125. If lvmatrix.t.z>r
  126. Local box:=New Boxf( lvmatrix.t+New Vec3f( -r ),lvmatrix.t+New Vec3f( r ) )
  127. Local cmin:=New Vec2f( 1 ),cmax:=New Vec2f( 0 )
  128. For Local i:=0 Until 8
  129. Local v:=(_projMatrix * box.Corner( i ) ).XY * 0.5 + 0.5
  130. cmin.x=Min( cmin.x,v.x );cmin.y=Min( cmin.y,v.y )
  131. cmax.x=Max( cmax.x,v.x );cmax.y=Max( cmax.y,v.y )
  132. Next
  133. If cmin.x>=1.0 Or cmin.y>=1.0 Return
  134. If cmax.x<0.0 Or cmax.y<0.0 Return
  135. qscale=cmax-cmin
  136. qtrans=cmin
  137. Endif
  138. If light.CastsShadow RenderPointShadows( light ) ; renderPass|=16
  139. renderPass|=8
  140. Case LightType.Spot
  141. If light.CastsShadow RenderSpotShadows( light ) ; renderPass|=16
  142. renderPass|=12
  143. Default
  144. Return
  145. End
  146. _runiforms.SetVec2f( "QuadCoordScale",qscale )
  147. _runiforms.SetVec2f( "QuadCoordTrans",qtrans )
  148. _runiforms.SetMat4f( "LightViewMatrix",lvmatrix )
  149. _runiforms.SetMat4f( "InverseLightViewMatrix",-lvmatrix )
  150. _runiforms.SetColor( "LightColor",light.Color )
  151. _runiforms.SetFloat( "LightRange",light.Range )
  152. _runiforms.SetFloat( "LightInnerAngle",light.InnerAngle*Pi/180.0 )
  153. _runiforms.SetFloat( "LightOuterAngle",light.OuterAngle*Pi/180.0 )
  154. _runiforms.SetTexture( "LightCubeTexture",light.Texture ?Else _whiteCubeTexture )
  155. _runiforms.SetTexture( "LightTexture",light.Texture ?Else _whiteTexture )
  156. _gdevice.ColorMask=ColorMask.All
  157. _gdevice.DepthMask=False
  158. _gdevice.DepthFunc=DepthFunc.Always
  159. _gdevice.BlendMode=BlendMode.Additive
  160. _gdevice.RenderPass=renderPass
  161. _gdevice.Shader=_deferredLightingShader
  162. _gdevice.CullMode=CullMode.None
  163. _runiforms.SetMat4f( "InverseProjectionMatrix",_invProjMatrix )
  164. RenderQuad()
  165. End
  166. Method RenderDeferredFog()
  167. If _scene.FogColor.a=0 Return
  168. _gdevice.ColorMask=ColorMask.All
  169. _gdevice.DepthMask=False
  170. _gdevice.DepthFunc=DepthFunc.Always
  171. _gdevice.BlendMode=BlendMode.Alpha
  172. _gdevice.RenderPass=0
  173. _gdevice.Shader=_deferredFogShader
  174. _gdevice.CullMode=CullMode.None
  175. RenderQuad()
  176. End
  177. Method RenderOpaqueDeferred()
  178. _gdevice.ColorMask=ColorMask.All
  179. _gdevice.DepthMask=True
  180. _gdevice.DepthFunc=DepthFunc.LessEqual
  181. _gdevice.BlendMode=BlendMode.Opaque
  182. _gdevice.RenderPass=1
  183. RenderOpaqueOps()
  184. 'only write to accum buffer only from now on...
  185. _gdevice.RenderTarget=_renderTarget1
  186. For Local light:=Eachin _scene.Lights
  187. RenderDeferredLighting( light )
  188. Next
  189. RenderDeferredFog()
  190. End
  191. Method RenderOpaqueForward()
  192. Local first:=True
  193. For Local light:=Eachin _scene.Lights
  194. Local renderPass:=2
  195. Select light.Type
  196. Case LightType.Directional
  197. If light.CastsShadow RenderDirectionalShadows( light ) ; renderPass|=16
  198. renderPass|=4
  199. Case LightType.Point
  200. If light.CastsShadow RenderPointShadows( light ) ; renderPass|=16
  201. renderPass|=8
  202. Case LightType.Spot
  203. If light.CastsShadow RenderSpotShadows( light ) ; renderPass|=16
  204. renderPass|=12
  205. End
  206. Local lvmatrix:=_viewMatrix * light.Matrix
  207. _runiforms.SetMat4f( "LightViewMatrix",lvmatrix )
  208. _runiforms.SetMat4f( "InverseLightViewMatrix",-lvmatrix )
  209. _runiforms.SetColor( "LightColor",light.Color )
  210. _runiforms.SetFloat( "LightRange",light.Range )
  211. _runiforms.SetFloat( "LightInnerAngle",light.InnerAngle*Pi/180.0 )
  212. _runiforms.SetFloat( "LightOuterAngle",light.OuterAngle*Pi/180.0 )
  213. _runiforms.SetTexture( "LightCubeTexture",light.Texture ?Else _whiteCubeTexture )
  214. _runiforms.SetTexture( "LightTexture",light.Texture ?Else _whiteTexture )
  215. _gdevice.ColorMask=ColorMask.All
  216. _gdevice.DepthMask=first
  217. _gdevice.DepthFunc=DepthFunc.LessEqual
  218. _gdevice.BlendMode=first ? BlendMode.Opaque Else BlendMode.Additive
  219. _gdevice.RenderPass=renderPass
  220. RenderOpaqueOps()
  221. first=False
  222. Next
  223. If first
  224. _gdevice.ColorMask=ColorMask.All
  225. _gdevice.DepthMask=True
  226. _gdevice.DepthFunc=DepthFunc.LessEqual
  227. _gdevice.BlendMode=BlendMode.Opaque
  228. _gdevice.RenderPass=2
  229. RenderOpaqueOps()
  230. Endif
  231. End
  232. Method RenderOpaque()
  233. If _deferred
  234. RenderOpaqueDeferred()
  235. Else
  236. RenderOpaqueForward()
  237. Endif
  238. End
  239. Method RenderSelfIlluminated()
  240. _gdevice.ColorMask=ColorMask.All
  241. _gdevice.DepthMask=True
  242. _gdevice.DepthFunc=DepthFunc.LessEqual
  243. _gdevice.RenderPass=1
  244. RenderSelfIlluminatedOps()
  245. End
  246. Method RenderTransparent()
  247. If _deferred _gdevice.RenderTarget=_renderTarget0
  248. Local first:=True
  249. For Local light:=Eachin _scene.Lights
  250. Local renderPass:=2
  251. Select light.Type
  252. Case LightType.Directional
  253. ' If light.CastsShadow RenderDirectionalShadows( light ) ; renderPass|=16
  254. renderPass|=4
  255. Case LightType.Point
  256. ' If light.CastsShadow RenderPointShadows( light ) ; renderPass|=16
  257. renderPass|=8
  258. Case LightType.Spot
  259. ' If light.CastsShadow RenderSpotShadows( light ) ; renderPass|=16
  260. renderPass|=12
  261. End
  262. _runiforms.SetColor( "LightColor",light.Color )
  263. _runiforms.SetFloat( "LightRange",light.Range )
  264. _runiforms.SetMat4f( "LightViewMatrix",_viewMatrix * light.Matrix )
  265. _gdevice.ColorMask=ColorMask.All
  266. _gdevice.DepthMask=False
  267. _gdevice.DepthFunc=DepthFunc.LessEqual
  268. _gdevice.RenderPass=renderPass
  269. RenderTransparentOps()
  270. first=False
  271. Exit
  272. Next
  273. If first
  274. _gdevice.ColorMask=ColorMask.All
  275. _gdevice.DepthMask=False
  276. _gdevice.DepthFunc=DepthFunc.LessEqual
  277. _gdevice.RenderPass=2
  278. RenderTransparentOps()
  279. Endif
  280. End
  281. Method RenderDirectionalShadows( light:Light )
  282. 'Perhaps use a different device for CSM...?
  283. '
  284. Local t_rtarget:=_gdevice.RenderTarget
  285. Local t_viewport:=_gdevice.Viewport
  286. Local t_scissor:=_gdevice.Scissor
  287. _gdevice.RenderTarget=_csmTarget
  288. _gdevice.Viewport=New Recti( 0,0,_csmTexture.Size )
  289. _gdevice.Scissor=_gdevice.Viewport
  290. _gdevice.ColorMask=ColorMask.All
  291. _gdevice.DepthMask=True
  292. _gdevice.Clear( Color.White,1.0 )
  293. _gdevice.DepthFunc=DepthFunc.LessEqual
  294. _gdevice.BlendMode=BlendMode.Opaque
  295. _gdevice.CullMode=CullMode.Front
  296. _gdevice.RenderPass=3|4
  297. Local viewLight:=light.InverseMatrix * _invViewMatrix
  298. For Local i:=0 Until _csmSplitDepths.Length-1
  299. Local znear:=_csmSplitDepths[i]
  300. Local zfar:=_csmSplitDepths[i+1]
  301. Local splitProj:=_projMatrix
  302. splitProj.k.z=(zfar+znear)/(zfar-znear)
  303. splitProj.t.z=-(zfar*znear*2)/(zfar-znear)
  304. Local invSplitProj:=-splitProj
  305. Local bounds:=Boxf.EmptyBounds
  306. For Local z:=-1 To 1 Step 2
  307. For Local y:=-1 To 1 Step 2
  308. For Local x:=-1 To 1 Step 2
  309. Local c:=New Vec3f( x,y,z ) 'clip coords
  310. Local v:=invSplitProj * c 'clip->view
  311. Local l:=viewLight * v 'view->light
  312. bounds|=l
  313. Next
  314. Next
  315. Next
  316. bounds.min.z-=100
  317. Local lightProj:=Mat4f.Ortho( bounds.min.x,bounds.max.x,bounds.min.y,bounds.max.y,bounds.min.z,bounds.max.z )
  318. 'set matrices for next pass...
  319. _runiforms.SetMat4f( "ShadowMatrix"+i,lightProj * viewLight )
  320. Local size:=_csmTexture.Size,hsize:=size/2
  321. Select i
  322. Case 0 _gdevice.Viewport=New Recti( 0,0,hsize.x,hsize.y )
  323. Case 1 _gdevice.Viewport=New Recti( hsize.x,0,size.x,hsize.y )
  324. Case 2 _gdevice.Viewport=New Recti( 0,hsize.y,hsize.x,size.y )
  325. Case 3 _gdevice.Viewport=New Recti( hsize.x,hsize.y,size.x,size.y )
  326. End
  327. _gdevice.Scissor=_gdevice.Viewport
  328. RenderShadowOps( light.InverseMatrix,lightProj )
  329. Next
  330. _gdevice.RenderTarget=t_rtarget
  331. _gdevice.Viewport=t_viewport
  332. _gdevice.Scissor=t_scissor
  333. End
  334. Method RenderPointShadows( light:Light )
  335. 'Perhaps use a different device for CSM...?
  336. '
  337. Local t_rtarget:=_gdevice.RenderTarget
  338. Local t_viewport:=_gdevice.Viewport
  339. Local t_scissor:=_gdevice.Scissor
  340. _gdevice.Viewport=New Recti( 0,0,_psmTexture.Size )
  341. _gdevice.Scissor=_gdevice.Viewport
  342. _gdevice.ColorMask=ColorMask.All
  343. _gdevice.DepthMask=True
  344. _gdevice.DepthFunc=DepthFunc.LessEqual
  345. _gdevice.BlendMode=BlendMode.Opaque
  346. _gdevice.CullMode=CullMode.Back'Front
  347. _gdevice.RenderPass=3|8
  348. Local near:=0.1
  349. Local lightProj:=Mat4f.Frustum( -near,+near,-near,+near,near,light.Range )
  350. lightProj.k.z=1'(zfar+znear)/(zfar-znear)
  351. lightProj.t.z=0'-(zfar*znear*2)/(zfar-znear)
  352. Local viewLight:=light.InverseMatrix * _invViewMatrix
  353. _runiforms.SetFloat( "LightRange",light.Range )
  354. _runiforms.SetMat4f( "ShadowMatrix0",viewLight )
  355. For Local i:=0 Until 6
  356. _gdevice.RenderTarget=_psmTargets[i]
  357. _gdevice.Clear( Color.White,1.0 )
  358. Local viewMatrix:=New AffineMat4f( _psmFaceTransforms[i] ) * light.InverseMatrix
  359. RenderShadowOps( viewMatrix,lightProj )
  360. Next
  361. _gdevice.RenderTarget=t_rtarget
  362. _gdevice.Viewport=t_viewport
  363. _gdevice.Scissor=t_scissor
  364. End
  365. Method RenderSpotShadows( light:Light )
  366. Local t_rtarget:=_gdevice.RenderTarget
  367. Local t_viewport:=_gdevice.Viewport
  368. Local t_scissor:=_gdevice.Scissor
  369. Local near:=0.1
  370. Local lightProj:=Mat4f.Frustum( -near,+near,-near,+near,near,light.Range )
  371. Local viewLight:=light.InverseMatrix * _invViewMatrix
  372. _runiforms.SetFloat( "LightRange",light.Range )
  373. _runiforms.SetMat4f( "ShadowMatrix0",lightProj * viewLight )
  374. _gdevice.RenderTarget=_csmTarget
  375. _gdevice.Viewport=New Recti( 0,0,_csmTexture.Size/2 )
  376. _gdevice.Scissor=_gdevice.Viewport
  377. _gdevice.ColorMask=ColorMask.All
  378. _gdevice.DepthMask=True
  379. _gdevice.Clear( Color.White,1.0 )
  380. _gdevice.DepthFunc=DepthFunc.LessEqual
  381. _gdevice.BlendMode=BlendMode.Opaque
  382. _gdevice.CullMode=CullMode.Front'Back
  383. _gdevice.RenderPass=3|12
  384. RenderShadowOps( light.InverseMatrix,lightProj )
  385. _gdevice.RenderTarget=t_rtarget
  386. _gdevice.Viewport=t_viewport
  387. _gdevice.Scissor=t_scissor
  388. End
  389. Method RenderPostEffects()
  390. If _deferred _gdevice.RenderTarget=_renderTarget1
  391. PostEffect.BeginRendering( _gdevice,_runiforms )
  392. For Local effect:=Eachin _scene.PostEffects
  393. If Not effect.Enabled Continue
  394. _gdevice.ColorMask=ColorMask.All
  395. _gdevice.DepthMask=False
  396. _gdevice.CullMode=CullMode.None
  397. _gdevice.DepthFunc=DepthFunc.Always
  398. _gdevice.BlendMode=BlendMode.Opaque
  399. _gdevice.RenderPass=0
  400. effect.Render()
  401. Next
  402. PostEffect.EndRendering()
  403. End
  404. Method RenderCopy()
  405. If _direct Return
  406. Local rsize:=_gdevice.Viewport.Size
  407. Local rtarget:=_gdevice.RenderTarget
  408. Local rtexture:=rtarget.GetColorTexture( 0 )
  409. _runiforms.SetTexture( "SourceBuffer",rtexture )
  410. _runiforms.SetVec2f( "SourceBufferSize",Cast<Vec2f>( rsize ) )
  411. _runiforms.SetVec2f( "SourceBufferScale",Cast<Vec2f>( rsize )/Cast<Vec2f>( rtexture.Size ) )
  412. _gdevice.RenderTarget=_outputRenderTarget
  413. _gdevice.Resize( _outputRenderTargetSize )
  414. _gdevice.Viewport=_outputViewport
  415. _gdevice.Scissor=_outputViewport
  416. _gdevice.ColorMask=ColorMask.All
  417. _gdevice.DepthMask=False
  418. _gdevice.DepthFunc=DepthFunc.Always
  419. _gdevice.BlendMode=BlendMode.Opaque
  420. _gdevice.CullMode=CullMode.None
  421. _gdevice.Shader=_copyShader
  422. _gdevice.RenderPass=0
  423. RenderCopyQuad()
  424. _gdevice.RenderTarget=Null
  425. _gdevice.Resize( Null )
  426. End
  427. Method RenderCopyQuad() Virtual 'So VRRenderer can override, ie: cheeze it for now!
  428. If _outputRenderTarget
  429. RenderInvertedQuad()
  430. Else
  431. RenderQuad()
  432. Endif
  433. End
  434. Method RenderInvertedQuad()
  435. Global _vertices:=New VertexBuffer( New Vertex3f[](
  436. New Vertex3f( 0,1,0,0,0 ),
  437. New Vertex3f( 1,1,0,1,0, ),
  438. New Vertex3f( 1,0,0,1,1 ),
  439. New Vertex3f( 0,0,0,0,1 ) ) )
  440. _gdevice.VertexBuffer=_vertices
  441. _gdevice.Render( 4,1 )
  442. End
  443. Method RenderQuad()
  444. Global _vertices:=New VertexBuffer( New Vertex3f[](
  445. New Vertex3f( 0,1,0,0,1 ),
  446. New Vertex3f( 1,1,0,1,1 ),
  447. New Vertex3f( 1,0,0,1,0 ),
  448. New Vertex3f( 0,0,0,0,0 ) ) )
  449. _gdevice.VertexBuffer=_vertices
  450. _gdevice.Render( 4,1 )
  451. End
  452. Method SortTransparentOps()
  453. _renderQueue.TransparentOps.Sort( Lambda:Int( x:RenderOp,y:RenderOp )
  454. If y.distance<x.distance Return -1
  455. If x.distance<y.distance Return 1
  456. Return 0
  457. End )
  458. End
  459. Method SortSpriteOps()
  460. _renderQueue.SpriteOps.Sort( Lambda:Int( x:SpriteOp,y:SpriteOp )
  461. If y.distance<x.distance Return -1
  462. If x.distance<y.distance Return 1
  463. Return 0
  464. End )
  465. End
  466. Method RenderOpaqueOps()
  467. RenderRenderOps( _renderQueue.OpaqueOps,_viewMatrix,_projMatrix )
  468. End
  469. Method RenderSelfIlluminatedOps()
  470. RenderRenderOps( _renderQueue.SelfIlluminatedOps,_viewMatrix,_projMatrix )
  471. End
  472. Method RenderTransparentOps()
  473. RenderRenderOps( _renderQueue.TransparentOps,_viewMatrix,_projMatrix )
  474. End
  475. Method RenderRenderOps( ops:Stack<RenderOp>,viewMatrix:AffineMat4f,projMatrix:Mat4f )
  476. Local viewProjMatrix:=projMatrix * viewMatrix
  477. _runiforms.SetMat4f( "ViewMatrix",viewMatrix )
  478. _runiforms.SetMat4f( "ProjectionMatrix",projMatrix )
  479. _runiforms.SetMat4f( "ViewProjectionMatrix",viewProjMatrix )
  480. _runiforms.SetMat4f( "InverseProjectionMatrix",-projMatrix )
  481. Local instance:Entity=Null,first:=True
  482. Local material:Material
  483. Local bones:Mat4f[]
  484. For Local op:=Eachin ops
  485. If op.instance<>instance Or first
  486. first=False
  487. instance=op.instance
  488. Local modelMat:=instance ? instance.Matrix Else New AffineMat4f
  489. Local modelViewMat:=viewMatrix * modelMat
  490. Local modelViewNormMat:=modelViewMat.m.Cofactor()
  491. Local modelViewProjMat:=projMatrix * modelViewMat
  492. _iuniforms.SetMat4f( "ModelMatrix",modelMat )
  493. _iuniforms.SetMat4f( "ModelViewMatrix",modelViewMat )
  494. _iuniforms.SetMat3f( "ModelViewNormalMatrix",modelViewNormMat )
  495. _iuniforms.SetMat4f( "ModelViewProjectionMatrix",modelViewProjMat )
  496. _iuniforms.SetColor( "Color",instance ? instance.Color Else Color.White )
  497. _iuniforms.SetFloat( "Alpha",instance ? instance.Alpha Else 1.0 )
  498. Endif
  499. If op.bones
  500. _iuniforms.SetMat4fArray( "ModelBoneMatrices",op.bones )
  501. Endif
  502. If op.uniforms
  503. _gdevice.BindUniformBlock( op.uniforms )
  504. Endif
  505. If op.material<>material
  506. material=op.material
  507. _gdevice.Shader=op.shader
  508. _gdevice.BindUniformBlock( material.Uniforms )
  509. _gdevice.CullMode=material.CullMode
  510. Endif
  511. _gdevice.BlendMode=op.blendMode
  512. _gdevice.VertexBuffer=op.vbuffer
  513. If op.ibuffer
  514. _gdevice.IndexBuffer=op.ibuffer
  515. _gdevice.RenderIndexed( op.order,op.count,op.first )
  516. Else
  517. _gdevice.Render( op.order,op.count,op.first )
  518. Endif
  519. Next
  520. End
  521. Method RenderShadowOps( viewMatrix:AffineMat4f,projMatrix:Mat4f )
  522. Local ops:=_renderQueue.ShadowOps
  523. Local viewProjMatrix:=projMatrix * viewMatrix
  524. _runiforms.SetMat4f( "ViewMatrix",viewMatrix )
  525. _runiforms.SetMat4f( "ProjectionMatrix",projMatrix )
  526. _runiforms.SetMat4f( "ViewProjectionMatrix",viewProjMatrix )
  527. _runiforms.SetMat4f( "InverseProjectionMatrix",-projMatrix )
  528. Local instance:Entity=Null,first:=True
  529. Local material:Material
  530. Local bones:Mat4f[]
  531. For Local op:=Eachin ops
  532. If op.instance<>instance Or first
  533. first=False
  534. instance=op.instance
  535. Local modelMat:=instance ? instance.Matrix Else New AffineMat4f
  536. Local modelViewMat:=viewMatrix * modelMat
  537. Local modelViewNormMat:=modelViewMat.m.Cofactor()
  538. Local modelViewProjMat:=projMatrix * modelViewMat
  539. _iuniforms.SetMat4f( "ModelMatrix",modelMat )
  540. _iuniforms.SetMat4f( "ModelViewMatrix",modelViewMat )
  541. _iuniforms.SetMat3f( "ModelViewNormalMatrix",modelViewNormMat )
  542. _iuniforms.SetMat4f( "ModelViewProjectionMatrix",modelViewProjMat )
  543. Endif
  544. If op.bones _iuniforms.SetMat4fArray( "ModelBoneMatrices",op.bones )
  545. If op.uniforms _gdevice.BindUniformBlock( op.uniforms )
  546. If op.material<>material
  547. material=op.material
  548. _gdevice.Shader=material.GetRenderShader()
  549. _gdevice.BindUniformBlock( material.Uniforms )
  550. Endif
  551. _gdevice.VertexBuffer=op.vbuffer
  552. If op.ibuffer
  553. _gdevice.IndexBuffer=op.ibuffer
  554. _gdevice.RenderIndexed( op.order,op.count,op.first )
  555. Else
  556. _gdevice.Render( op.order,op.count,op.first )
  557. Endif
  558. Next
  559. End
  560. Private
  561. Field _direct:Bool=False
  562. Field _deferred:Bool=True
  563. Field _defs:String
  564. Field _gdevice:GraphicsDevice
  565. Field _runiforms:UniformBlock
  566. Field _iuniforms:UniformBlock
  567. Field _defaultEnv:Texture
  568. Field _skyboxShader:Shader
  569. Field _copyShader:Shader
  570. Field _deferredLightingShader:Shader
  571. Field _deferredFogShader:Shader
  572. Field _renderQueue:RenderQueue
  573. Field _spriteBuffer:=New SpriteBuffer
  574. Field _accumBuffer:Texture
  575. Field _colorBuffer:Texture
  576. Field _normalBuffer:Texture
  577. Field _depthBuffer:Texture
  578. Field _renderTarget0:RenderTarget 'all buffers
  579. Field _renderTarget1:RenderTarget 'accum buffer only
  580. Field _effectBuffer:Texture
  581. Field _effectTarget:RenderTarget
  582. Field _csmSize:=2048
  583. Field _csmSplits:Float[]
  584. Field _csmSplitDepths:=New Float[5]
  585. Field _csmTexture:Texture
  586. Field _csmDepth:Texture
  587. Field _csmTarget:RenderTarget
  588. Field _psmSize:=2048
  589. Field _psmTexture:Texture
  590. Field _psmDepth:Texture
  591. Field _psmTargets:=New RenderTarget[6]
  592. Field _psmFaceTransforms:Mat3f[]
  593. Field _outputRenderTarget:RenderTarget
  594. Field _outputRenderTargetSize:Vec2i
  595. Field _outputViewport:Recti
  596. Field _scene:Scene
  597. Field _viewMatrix:AffineMat4f
  598. Field _projMatrix:Mat4f
  599. Field _near:Float
  600. Field _far:Float
  601. Field _invViewMatrix:AffineMat4f
  602. Field _invProjMatrix:Mat4f
  603. Field _ambientRendered:Bool
  604. Field _whiteCubeTexture:Texture
  605. Field _whiteTexture:Texture
  606. Global _current:Renderer
  607. Method Init()
  608. Global inited:Bool
  609. If inited Return
  610. inited=True
  611. _gdevice=New GraphicsDevice( 0,0 )
  612. _runiforms=New UniformBlock( 1,True )
  613. _iuniforms=New UniformBlock( 2,True )
  614. _gdevice.BindUniformBlock( _runiforms )
  615. _gdevice.BindUniformBlock( _iuniforms )
  616. _defaultEnv=Texture.Load( "asset::textures/env_default.jpg",TextureFlags.FilterMipmap|TextureFlags.Cubemap|TextureFlags.Envmap )
  617. _skyboxShader=Shader.Open( "misc/skybox",ShaderDefs )
  618. _copyShader=Shader.Open( "misc/copy" )
  619. If _deferred
  620. _deferredLightingShader=Shader.Open( "misc/lighting-deferred",ShaderDefs )
  621. _deferredFogShader=Shader.Open( "misc/fog-deferred",ShaderDefs )
  622. Endif
  623. _renderQueue=New RenderQueue
  624. _psmFaceTransforms=New Mat3f[](
  625. New Mat3f( 0,0,+1, 0,-1,0, -1, 0,0 ), '+X
  626. New Mat3f( 0,0,-1, 0,-1,0, +1, 0,0 ), '-X
  627. New Mat3f( +1,0, 0, 0,0,+1, 0,+1,0 ), '+Y
  628. New Mat3f( +1,0, 0, 0,0,-1, 0,-1,0 ), '-Y
  629. New Mat3f( +1,0, 0, 0,-1,0, 0,0,+1 ), '+Z
  630. New Mat3f( -1,0, 0, 0,-1,0, 0,0,-1 ) ) '-Z
  631. Local pixmap:=New Pixmap( 1,1,PixelFormat.I8 )
  632. pixmap.Clear( Color.White )
  633. _whiteCubeTexture=New Texture( pixmap,TextureFlags.Cubemap )
  634. _whiteTexture=Texture.ColorTexture( Color.White )
  635. ValidateSize( New Vec2i( 1920,1080 ) )
  636. End
  637. Method ValidateSize( size:Vec2i )
  638. If _direct Return
  639. If _accumBuffer And size.x<=_accumBuffer.Size.x And size.y<=_accumBuffer.Size.y Return
  640. _accumBuffer?.Discard()
  641. _colorBuffer?.Discard()
  642. _normalBuffer?.Discard()
  643. _depthBuffer?.Discard()
  644. _renderTarget0?.Discard()
  645. _renderTarget1?.Discard()
  646. Local color_format:=PixelFormat.RGBA32F
  647. Local depth_format:=PixelFormat.Depth32
  648. If GetConfig("MOJO_OPENGL_PROFILE")="es"
  649. color_format=PixelFormat.RGBA8
  650. Endif
  651. If _deferred
  652. _accumBuffer=New Texture( size.x,size.y,color_format,TextureFlags.Dynamic|TextureFlags.Filter )
  653. _colorBuffer=New Texture( size.x,size.y,color_format,TextureFlags.Dynamic|TextureFlags.Filter )
  654. _normalBuffer=New Texture( size.x,size.y,color_format,TextureFlags.Dynamic|TextureFlags.Filter )
  655. _depthBuffer=New Texture( size.x,size.y,depth_format,TextureFlags.Dynamic )
  656. _renderTarget0=New RenderTarget( New Texture[]( _accumBuffer,_colorBuffer,_normalBuffer ),_depthBuffer )
  657. _renderTarget1=New RenderTarget( New Texture[]( _accumBuffer ),Null )
  658. _runiforms.SetTexture( "AccumBuffer",_accumBuffer )
  659. _runiforms.SetTexture( "ColorBuffer",_colorBuffer )
  660. _runiforms.SetTexture( "NormalBuffer",_normalBuffer )
  661. _runiforms.SetTexture( "DepthBuffer",_depthBuffer )
  662. Else
  663. _accumBuffer=New Texture( size.x,size.y,color_format,TextureFlags.Dynamic|TextureFlags.Filter )
  664. _depthBuffer=New Texture( size.x,size.y,depth_format,TextureFlags.Dynamic )
  665. _renderTarget0=New RenderTarget( New Texture[]( _accumBuffer ),_depthBuffer )
  666. _renderTarget1=New RenderTarget( New Texture[]( _accumBuffer ),Null )
  667. _runiforms.SetTexture( "AccumBuffer",_accumBuffer )
  668. _runiforms.SetTexture( "DepthBuffer",_depthBuffer )
  669. Endif
  670. End
  671. Method ValidateCSMShadows()
  672. If Not _csmTexture Or _csmSize*2<>_csmTexture.Size.x
  673. _csmTarget?.Discard()
  674. _csmTexture?.Discard()
  675. _csmDepth?.Discard()
  676. const depth_format:=PixelFormat.Depth32
  677. _csmTexture=New Texture( _csmSize*2,_csmSize*2,depth_format,TextureFlags.Dynamic )'|TextureFlags.Filter )
  678. _csmTarget=New RenderTarget( Null,_csmTexture )
  679. _csmDepth=Null
  680. _runiforms.SetTexture( "ShadowCSMTexture",_csmTexture )
  681. Endif
  682. End
  683. Method ValidatePSMShadows()
  684. If Not _psmTexture Or _psmSize<>_psmTexture.Size.x
  685. _psmTexture?.Discard()
  686. _psmDepth?.Discard()
  687. For Local i:=0 Until 6
  688. _psmTargets[i]?.Discard()
  689. Next
  690. const color_format:=PixelFormat.RGBA8
  691. const depth_format:=PixelFormat.Depth32
  692. _psmTexture=New Texture( _psmSize,_psmSize,color_format,TextureFlags.Cubemap|TextureFlags.Dynamic )
  693. _psmDepth=New Texture( _psmSize,_psmSize,depth_format,TextureFlags.Dynamic )
  694. For Local i:=0 Until 6
  695. Local face:=_psmTexture.GetCubeFace( Cast<CubeFace>( i ) )
  696. _psmTargets[i]=New RenderTarget( New Texture[]( face ),_psmDepth )
  697. Next
  698. _runiforms.SetTexture( "ShadowCubeTexture",_psmTexture )
  699. Endif
  700. End
  701. Method SetOutputRenderTarget( renderTarget:RenderTarget,renderTargetSize:Vec2i,viewport:Recti )
  702. _outputRenderTarget=renderTarget
  703. _outputRenderTargetSize=renderTargetSize
  704. _outputViewport=viewport
  705. ValidateSize( viewport.Size )
  706. If _direct
  707. _gdevice.RenderTarget=renderTarget
  708. _gdevice.Resize( renderTargetSize )
  709. _gdevice.Viewport=viewport
  710. _gdevice.Scissor=viewport
  711. Return
  712. Endif
  713. _gdevice.RenderTarget=_renderTarget0
  714. _gdevice.Viewport=New Recti( 0,0,viewport.Size )
  715. _gdevice.Scissor=_gdevice.Viewport
  716. _runiforms.SetVec2f( "BufferCoordScale",Cast<Vec2f>( viewport.Size )/Cast<Vec2f>( _accumBuffer.Size ) )
  717. End
  718. Method SetScene( scene:Scene )
  719. _scene=scene
  720. Local sky:=_scene.SkyTexture
  721. If sky
  722. _runiforms.SetColor( "SkyColor",_scene.SkyColor )
  723. If sky.Flags & TextureFlags.Cubemap
  724. _runiforms.SetTexture( "SkyTextureCube",sky )
  725. _runiforms.SetTexture( "SkyTexture2D",_whiteTexture )
  726. _runiforms.SetInt( "SkyCube",1 )
  727. Else
  728. _runiforms.SetTexture( "SkyTextureCube",_whiteCubeTexture )
  729. _runiforms.SetTexture( "SkyTexture2D",sky )
  730. _runiforms.SetInt( "SkyCube",0 )
  731. Endif
  732. Else
  733. _runiforms.SetTexture( "SkyTextureCube",Null )
  734. _runiforms.SetTexture( "SkyTexture2D",Null )
  735. Endif
  736. _runiforms.SetColor( "ClearColor",_scene.ClearColor )
  737. _runiforms.SetColor( "AmbientDiffuse",_scene.AmbientLight )
  738. Local env:=(_scene.EnvTexture ?Else _scene.SkyTexture) ?Else _defaultEnv
  739. If env.Flags & TextureFlags.Cubemap
  740. _runiforms.SetTexture( "EnvTextureCube",env )
  741. _runiforms.SetTexture( "EnvTexture2D",_whiteTexture )
  742. _runiforms.SetInt( "EnvCube",1 )
  743. Else
  744. _runiforms.SetTexture( "EnvTextureCube",_whiteCubeTexture )
  745. _runiforms.SetTexture( "EnvTexture2D",env )
  746. _runiforms.SetInt( "EnvCube",0 )
  747. Endif
  748. _runiforms.SetFloat( "EnvTextureMaxLod",Log2( env.Size.x ) )
  749. _runiforms.SetColor( "EnvColor",_scene.EnvColor )
  750. _runiforms.SetColor( "FogColor",_scene.FogColor )
  751. _runiforms.SetFloat( "FogNear",_scene.FogNear )
  752. _runiforms.SetFloat( "FogFar",_scene.FogFar )
  753. _runiforms.SetFloat( "ShadowAlpha",_scene.ShadowAlpha )
  754. _csmSplits=_scene.CSMSplits
  755. End
  756. Method SetCamera( viewMatrix:AffineMat4f,projMatrix:Mat4f,near:Float,far:Float )
  757. _viewMatrix=viewMatrix
  758. _projMatrix=projMatrix
  759. _near=near
  760. _far=far
  761. _invViewMatrix=-_viewMatrix
  762. _invProjMatrix=-_projMatrix
  763. _runiforms.SetMat3f( "EnvMatrix",_invViewMatrix.m )
  764. _runiforms.SetMat4f( "ProjectionMatrix",_projMatrix )
  765. _runiforms.SetMat4f( "InverseProjectionMatrix",_invProjMatrix )
  766. _runiforms.SetMat4f( "ViewMatrix",_viewMatrix )
  767. _runiforms.SetMat4f( "CameraMatrix",_invViewMatrix )
  768. _runiforms.SetFloat( "DepthNear",_near )
  769. _runiforms.SetFloat( "DepthFar",_far )
  770. _csmSplitDepths[0]=_near
  771. For Local i:=1 Until 5
  772. _csmSplitDepths[i]=Min( _csmSplitDepths[i-1]+_csmSplits[i-1],_far )
  773. Next
  774. _runiforms.SetVec4f( "ShadowCSMSplits",New Vec4f( _csmSplitDepths[1],_csmSplitDepths[2],_csmSplitDepths[3],_csmSplitDepths[4] ) )
  775. _renderQueue.Clear()
  776. Local time:=Float( Now() )
  777. _renderQueue.Time=time
  778. _runiforms.SetFloat( "Time",time )
  779. _renderQueue.EyePos=_invViewMatrix.t
  780. For Local r:=Eachin _scene.Renderables
  781. _renderQueue.AddShadowOps=r.CastsShadow
  782. r.OnRender( _renderQueue )
  783. Next
  784. SortTransparentOps()
  785. SortSpriteOps()
  786. _spriteBuffer.InsertRenderOps( _renderQueue,_invViewMatrix )
  787. End
  788. End