renderer.monkey2 25 KB

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