2
0

canvas.monkey2 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122
  1. Namespace mojo.graphics
  2. #rem monkeydoc @hidden
  3. #end
  4. Class DrawOp
  5. Field blendMode:BlendMode
  6. Field material:Material
  7. Field order:Int
  8. Field count:Int
  9. End
  10. #rem monkeydoc The Canvas class.
  11. Canvas objects are used to perform rendering to either a mojo [[app.View]] or an 'off screen' [[mojo.graphics.Image]].
  12. To draw to a canvas, use one of the 'Draw' methods. Drawing is affected by a number of draw states, including:
  13. * [[Color]] - the current drawing color. This is combined with the current alpha to produce the final rendering color and alpha values.
  14. * [[Alpha]] - the current drawing alpha level.
  15. * [[Matrix]] - the current drawing matrix. All drawing coordinates are multiplied by this matrix before rendering.
  16. * [[BlendMode]] - the blending mode for drawing, eg: opaque, alpha, additive, multiply.
  17. * [[Viewport]] - the current viewport. All drawing coordinates are relative to the top-left of the viewport.
  18. * [[Scissor]] - the current scissor rect. All rendering is clipped to the union of the viewport and the scissor rect.
  19. * [[Font]] - The current font to use when drawing text with [[DrawText]].
  20. Drawing does not occur immediately. Drawing commands are 'buffered' to reduce the overhead of sending lots of draw calls to the lower level graphics API. You can force all drawing commands in the buffer to actually render using [[Flush]].
  21. #end
  22. Class Canvas
  23. #rem monkeydoc Creates a new canvas.
  24. @param image Canvas render target image.
  25. #end
  26. Method New( image:Image )
  27. Init( image.Texture,image.Texture.Rect.Size,image.Rect )
  28. BeginRender( New Recti( 0,0,image.Rect.Size ),New AffineMat3f )
  29. End
  30. #rem monkeydoc @hidden
  31. #End
  32. Method New( texture:Texture )
  33. Init( texture,texture.Rect.Size,texture.Rect )
  34. BeginRender( texture.Rect,New AffineMat3f )
  35. End
  36. #rem monkeydoc @hidden
  37. #end
  38. Method New( width:Int,height:Int )
  39. Init( Null,New Vec2i( width,height ),New Recti( 0,0,width,height ) )
  40. End
  41. #rem monkeydoc The current viewport.
  42. The viewport describes the rect within the render target that rendering occurs in.
  43. All rendering is relative to the top-left of the viewport, and is clipped to the intersection of the current viewport and scissor rects.
  44. #end
  45. Property Viewport:Recti()
  46. Return _viewport
  47. Setter( viewport:Recti )
  48. Flush()
  49. _viewport=viewport
  50. _dirty|=Dirty.EnvParams|Dirty.Scissor
  51. End
  52. #rem monkeydoc The current scissor rect.
  53. The scissor rect is rect within the viewport that can be used for additional clipping.
  54. Scissor rect coorindates are relative to the current viewport viewport.
  55. #end
  56. Property Scissor:Recti()
  57. Return _scissor
  58. Setter( scissor:Recti )
  59. Flush()
  60. _scissor=scissor
  61. _dirty|=Dirty.Scissor
  62. End
  63. #rem monkeydoc @hidden
  64. #end
  65. Property ViewMatrix:Mat4f()
  66. Return _viewMatrix
  67. Setter( viewMatrix:Mat4f )
  68. Flush()
  69. _viewMatrix=viewMatrix
  70. _dirty|=Dirty.EnvParams
  71. End
  72. #rem monkeydoc @hidden
  73. #end
  74. Property ModelMatrix:Mat4f()
  75. Return _modelMatrix
  76. Setter( modelMatrix:Mat4f )
  77. Flush()
  78. _modelMatrix=modelMatrix
  79. _dirty|=Dirty.EnvParams
  80. End
  81. #rem monkeydoc @hidden
  82. #end
  83. Property AmbientLight:Color()
  84. Return _ambientLight
  85. Setter( ambientLight:Color )
  86. Flush()
  87. _ambientLight=ambientLight
  88. _dirty|=Dirty.EnvParams
  89. End
  90. #rem monkeydoc @hidden
  91. #end
  92. Property RenderColor:Color()
  93. Return _renderColor
  94. Setter( renderColor:Color )
  95. Flush()
  96. _renderColor=renderColor
  97. _dirty|=Dirty.EnvParams
  98. End
  99. #rem monkeydoc Texture filtering control.
  100. Set this to false to render cool 'pixel art' style graphics.
  101. #end
  102. Property TextureFilteringEnabled:Bool()
  103. Return _filter
  104. Setter( enabled:Bool )
  105. Flush()
  106. _filter=enabled
  107. End
  108. #rem monkeydoc @hidden
  109. #end
  110. Method Resize( size:Vec2i )
  111. Flush()
  112. _targetSize=size
  113. _targetRect=New Recti( 0,0,size )
  114. _dirty|=Dirty.Target
  115. End
  116. #rem monkeydoc Clears the viewport.
  117. Clears the viewport to `color`.
  118. @param color Color to clear the viewport to.
  119. #end
  120. Method Clear( color:Color )
  121. Flush()
  122. Validate()
  123. _device.Clear( color )
  124. End
  125. #rem monkeydoc Copies a pixmap from the rendertarget.
  126. @param rect The rect to copy.
  127. #end
  128. Method CopyPixmap:Pixmap( rect:Recti )
  129. Flush()
  130. Validate()
  131. rect=TransformRecti( rect,_renderMatrix )
  132. rect=(rect & _renderBounds)+_targetRect.Origin
  133. Local pixmap:=_device.CopyPixmap( rect )
  134. Return pixmap
  135. End
  136. #rem monkeydoc @hidden
  137. #end
  138. Method BeginRender( bounds:Recti,matrix:AffineMat3f )
  139. Flush()
  140. _device.ShaderEnv=_ambientEnv
  141. _renderMatrixStack.Push( _renderMatrix )
  142. _renderBoundsStack.Push( _renderBounds )
  143. _renderMatrix*=matrix
  144. _renderBounds&=TransformRecti( bounds,_renderMatrix )
  145. _dirty|=Dirty.EnvParams|Dirty.Scissor
  146. Viewport=bounds
  147. Scissor=New Recti( 0,0,bounds.Size )
  148. PointSize=1
  149. LineWidth=1
  150. BlendMode=BlendMode.Alpha
  151. TextureFilteringEnabled=True
  152. ClearMatrix()
  153. End
  154. #rem monkeydoc @hidden
  155. #end
  156. Method EndRender()
  157. Flush()
  158. _renderBounds=_renderBoundsStack.Pop()
  159. _renderMatrix=_renderMatrixStack.Pop()
  160. End
  161. #rem monkeydoc Flushes drawing commands.
  162. Flushes any outstanding drawing commands in the draw buffer.
  163. #end
  164. Method Flush()
  165. Validate()
  166. RenderDrawOps()
  167. ClearDrawOps()
  168. End
  169. '***** DrawList *****
  170. #rem monkeydoc The current font for use with DrawText.
  171. Set font to null to use the default mojo font.
  172. #end
  173. Property Font:Font()
  174. Return _font
  175. Setter( font:Font )
  176. If Not font font=_defaultFont
  177. _font=font
  178. End
  179. #rem monkeydoc The current drawing alpha level.
  180. Note that [[Alpha]] and the alpha component of [[Color]] are multiplied together to produce the final alpha value for rendering. This allows you to use [[Alpha]] as a 'master' alpha level.
  181. #end
  182. Property Alpha:Float()
  183. Return _alpha
  184. Setter( alpha:Float )
  185. _alpha=alpha
  186. Local a:=_color.a * _alpha * 255.0
  187. _pmcolor=UInt(a) Shl 24 | UInt(_color.b*a) Shl 16 | UInt(_color.g*a) Shl 8 | UInt(_color.r*a)
  188. End
  189. #rem monkeydoc The current drawing color.
  190. Note that [[Alpha]] and the alpha component of [[Color]] are multiplied together to produce the final alpha value for rendering. This allows you to use [[Alpha]] as a 'master' alpha level.
  191. #end
  192. Property Color:Color()
  193. Return _color
  194. Setter( color:Color )
  195. _color=color
  196. Local a:=_color.a * _alpha * 255.0
  197. _pmcolor=UInt(a) Shl 24 | UInt(_color.b*a) Shl 16 | UInt(_color.g*a) Shl 8 | UInt(_color.r*a)
  198. End
  199. #rem monkeydoc The current drawing matrix.
  200. All coordinates passed to draw methods are multiplied by this matrix for rendering.
  201. #end
  202. Property Matrix:AffineMat3f()
  203. Return _matrix
  204. Setter( matrix:AffineMat3f )
  205. _matrix=matrix
  206. End
  207. #rem monkeydoc The current blend mode.
  208. #end
  209. Property BlendMode:BlendMode()
  210. Return _blendMode
  211. Setter( blendMode:BlendMode )
  212. _blendMode=blendMode
  213. End
  214. #rem monkeydoc The current point size for use with DrawPoint.
  215. #end
  216. Property PointSize:Float()
  217. Return _pointSize
  218. Setter( pointSize:Float )
  219. _pointSize=pointSize
  220. End
  221. #rem monkeydoc The current line width for use with DrawLine.
  222. #end
  223. Property LineWidth:Float()
  224. Return _lineWidth
  225. Setter( lineWidth:Float )
  226. _lineWidth=lineWidth
  227. End
  228. #rem monkeydoc @hidden The materials used to render primitives.
  229. #end
  230. Property PrimitiveMaterials:Material[]()
  231. Return _materials
  232. End
  233. #rem monkeydoc Pushes the drawing matrix onto the internal matrix stack.
  234. #end
  235. Method PushMatrix()
  236. _matrixStack.Push( Matrix )
  237. End
  238. #rem monkeydoc Pops the drawing matrix off the internal matrix stack.
  239. #end
  240. Method PopMatrix()
  241. Matrix=_matrixStack.Pop()
  242. End
  243. #rem monkeydoc Clears the internal matrix stack and sets matrix to the identitity matrix.
  244. #end
  245. Method ClearMatrix()
  246. _matrixStack.Clear()
  247. Matrix=New AffineMat3f
  248. End
  249. #rem monkeydoc Translates the drawing matrix.
  250. Translates the drawing matrix. This has the effect of translating all drawing coordinates by `tx` and `ty`.
  251. #end
  252. Method Translate( tx:Float,ty:Float )
  253. Matrix=Matrix.Translate( tx,ty )
  254. End
  255. #rem monkeydoc Rotates the drawing matrix.
  256. Rotates the drawing matrix. This has the effect of rotating all drawing coordinates by the angle `rz'.
  257. @param rz Rotation angle in radians.
  258. #end
  259. Method Rotate( rz:Float )
  260. Matrix=Matrix.Rotate( rz )
  261. End
  262. #rem monkeydoc Scales the drawing matrix.
  263. Scales the drawing matrix. This has the effect of scaling all drawing coordinates by `sx` and `sy`.
  264. @param sx X scale factor.
  265. @param sy Y scale factor.
  266. #end
  267. Method Scale( sx:Float,sy:Float )
  268. Matrix=Matrix.Scale( sx,sy )
  269. End
  270. #rem monkeydoc Draws a point.
  271. Draws a point in the current [[Color]] using the current [[BlendMode]].
  272. The point coordinates are also transform by the current [[Matrix]].
  273. The
  274. @param v Point coordinates.
  275. @param x Point x coordinate.
  276. @param y Point y coordinate.
  277. #end
  278. Method DrawPoint( x:Float,y:Float )
  279. If _pointSize<=1
  280. AddDrawOp( _materials[1],1,1 )
  281. AddVertex( x+.5,y+.5,0,0 )
  282. Return
  283. Endif
  284. Local d:=_pointSize/2
  285. AddDrawOp( _materials[1],4,1 )
  286. AddVertex( x-d,y-d,0,0 )
  287. AddVertex( x+d,y-d,1,0 )
  288. AddVertex( x+d,y+d,1,1 )
  289. AddVertex( x-d,y+d,0,1 )
  290. End
  291. Method DrawPoint( v:Vec2f )
  292. AddDrawOp( _materials[1],1,1 )
  293. AddVertex( v.x+.5,v.y+.5,0,0 )
  294. End
  295. #rem monkeydoc Draws a line.
  296. Draws a line in the current [[Color]] using the current [[BlendMode]].
  297. The line end coordinates are transform by the current [[Matrix]] and clipped to the current [[Viewport]] and [[Scissor]].
  298. @param v0 First endpoint of the line.
  299. @param v1 Second endpoint of the line.
  300. @param x0 X coordinate of first endpoint of the line.
  301. @param y0 Y coordinate of first endpoint of the line.
  302. @param x1 X coordinate of first endpoint of the line.
  303. @param y1 Y coordinate of first endpoint of the line.
  304. #end
  305. Method DrawLine( x0:Float,y0:Float,x1:Float,y1:Float )
  306. If _lineWidth<=1
  307. AddDrawOp( _materials[2],2,1 )
  308. AddVertex( x0+.5,y0+.5,0,0 )
  309. AddVertex( x1+.5,y1+.5,1,1 )
  310. Return
  311. Endif
  312. Local dx:=y0-y1,dy:=x1-x0
  313. Local sc:=0.5/Sqrt( dx*dx+dy*dy )*_lineWidth
  314. dx*=sc;dy*=sc
  315. If _blendMode=BlendMode.Opaque
  316. AddDrawOp( _materials[2],4,1 )
  317. AddVertex( x0-dx,y0-dy,0,0 )
  318. AddVertex( x0+dx,y0+dy,0,0 )
  319. AddVertex( x1+dx,y1+dy,0,0 )
  320. AddVertex( x1-dx,y1-dy,0,0 )
  321. Return
  322. End
  323. Local pmcolor:=_pmcolor
  324. AddDrawOp( _materials[2],4,2 )
  325. AddVertex( x0,y0,0,0 )
  326. AddVertex( x1,y1,0,0 )
  327. _pmcolor=0
  328. AddVertex( x1-dx,y1-dy,0,0 )
  329. AddVertex( x0-dx,y0-dy,0,0 )
  330. AddVertex( x0+dx,y0+dy,0,0 )
  331. AddVertex( x1+dx,y1+dy,0,0 )
  332. _pmcolor=pmcolor
  333. AddVertex( x1,y1,0,0 )
  334. AddVertex( x0,y0,0,0 )
  335. End
  336. Method DrawLine( v0:Vec2f,v1:Vec2f )
  337. DrawLine( v0.x,v0.y,v1.x,v1.y )
  338. End
  339. #rem monkeydoc Draws a triangle.
  340. Draws a triangle in the current [[Color]] using the current [[BlendMode]].
  341. The triangle vertex coordinates are also transform by the current [[Matrix]].
  342. #End
  343. Method DrawTriangle( v0:Vec2f,v1:Vec2f,v2:Vec2f )
  344. AddDrawOp( _materials[3],3,1 )
  345. AddVertex( v0.x,v0.y,.5,0 )
  346. AddVertex( v1.x,v1.y,1,1 )
  347. AddVertex( v2.x,v2.y,0,1 )
  348. End
  349. Method DrawTriangle( x0:Float,y0:Float,x1:Float,y1:Float,x2:Float,y2:Float )
  350. AddDrawOp( _materials[3],3,1 )
  351. AddVertex( x0,y0,0,0 )
  352. AddVertex( x1,y1,1,0 )
  353. AddVertex( x2,y2,1,1 )
  354. End
  355. #rem monkeydoc Draws a quad.
  356. Draws a quad in the current [[Color]] using the current [[BlendMode]].
  357. The quad vertex coordinates are also transform by the current [[Matrix]].
  358. #end
  359. Method DrawQuad( x0:Float,y0:Float,x1:Float,y1:Float,x2:Float,y2:Float,x3:Float,y3:Float )
  360. AddDrawOp( _materials[4],4,1 )
  361. AddVertex( x0,y0,0,0 )
  362. AddVertex( x1,y1,1,0 )
  363. AddVertex( x2,y2,1,1 )
  364. AddVertex( x3,y3,0,1 )
  365. End
  366. #rem monkeydoc Draws a rectangle.
  367. Draws a rectangle in the current [[Color]] using the current [[BlendMode]].
  368. The rectangle vertex coordinates are also transform by the current [[Matrix]].
  369. #end
  370. Method DrawRect( rect:Rectf )
  371. AddDrawOp( _materials[4],4,1 )
  372. AddVertex( rect.min.x,rect.min.y,0,0 )
  373. AddVertex( rect.max.x,rect.min.y,1,0 )
  374. AddVertex( rect.max.x,rect.max.y,1,1 )
  375. AddVertex( rect.min.x,rect.max.y,0,1 )
  376. End
  377. Method DrawRect( x:Float,y:Float,width:Float,height:Float )
  378. DrawRect( New Rectf( x,y,x+width,y+height ) )
  379. End
  380. Method DrawRect( rect:Rectf,srcImage:Image )
  381. Local tc:=srcImage.TexCoords
  382. AddDrawOp( srcImage.Material,4,1 )
  383. AddVertex( rect.min.x,rect.min.y,tc.min.x,tc.min.y )
  384. AddVertex( rect.max.x,rect.min.y,tc.max.x,tc.min.y )
  385. AddVertex( rect.max.x,rect.max.y,tc.max.x,tc.max.y )
  386. AddVertex( rect.min.x,rect.max.y,tc.min.x,tc.max.y )
  387. End
  388. Method DrawRect( x:Float,y:Float,width:Float,height:Float,srcImage:Image )
  389. DrawRect( New Rectf( x,y,x+width,y+height ),srcImage )
  390. End
  391. Method DrawRect( rect:Rectf,srcImage:Image,srcRect:Recti )
  392. Local s0:=Float(srcImage.Rect.min.x+srcRect.min.x)/srcImage.Texture.Width
  393. Local t0:=Float(srcImage.Rect.min.y+srcRect.min.y)/srcImage.Texture.Height
  394. Local s1:=Float(srcImage.Rect.min.x+srcRect.max.x)/srcImage.Texture.Width
  395. Local t1:=Float(srcImage.Rect.min.y+srcRect.max.y)/srcImage.Texture.Height
  396. AddDrawOp( srcImage.Material,4,1 )
  397. AddVertex( rect.min.x,rect.min.y,s0,t0 )
  398. AddVertex( rect.max.x,rect.min.y,s1,t0 )
  399. AddVertex( rect.max.x,rect.max.y,s1,t1 )
  400. AddVertex( rect.min.x,rect.max.y,s0,t1 )
  401. End
  402. Method DrawRect( x:Float,y:Float,width:Float,height:Float,srcImage:Image,srcX:Int,srcY:Int )
  403. DrawRect( New Rectf( x,y,x+width,y+height ),srcImage,New Recti( srcX,srcY,srcX+width,srcY+height ) )
  404. End
  405. Method DrawRect( x:Float,y:Float,width:Float,height:Float,srcImage:Image,srcX:Int,srcY:Int,srcWidth:Int,srcHeight:Int )
  406. DrawRect( New Rectf( x,y,x+width,y+height ),srcImage,New Recti( srcX,srcY,srcX+srcWidth,srcY+srcHeight ) )
  407. End
  408. #rem monkeydoc Draws an oval.
  409. Draws an oval in the current [[Color]] using the current [[BlendMode]].
  410. The oval vertex coordinates are also transform by the current [[Matrix]].
  411. @param x Top left x coordinate for the oval.
  412. @param y Top left y coordinate for the oval.
  413. @param width Width of the oval.
  414. @param height Height of the oval.
  415. #end
  416. Method DrawOval( x:Float,y:Float,width:Float,height:Float )
  417. Local xr:=width/2.0,yr:=height/2.0
  418. Local dx_x:=xr*_matrix.i.x
  419. Local dx_y:=xr*_matrix.i.y
  420. Local dy_x:=yr*_matrix.j.x
  421. Local dy_y:=yr*_matrix.j.y
  422. Local dx:=Sqrt( dx_x*dx_x+dx_y*dx_y )
  423. Local dy:=Sqrt( dy_x*dy_x+dy_y*dy_y )
  424. Local n:=Max( Int( dx+dy ),12 ) & ~3
  425. Local x0:=x+xr,y0:=y+yr
  426. AddDrawOp( _materials[5],n,1 )
  427. For Local i:=0 Until n
  428. Local th:=i*Pi*2/n
  429. Local px:=x0+Cos( th ) * xr
  430. Local py:=y0+Sin( th ) * yr
  431. AddVertex( px,py,0,0 )
  432. Next
  433. End
  434. #rem monkeydoc Draws an ellipse.
  435. Draws an ellipse in the current [[Color]] using the current [[BlendMode]].
  436. The ellipse is also transformed by the current [[Matrix]].
  437. @param x Center x coordinate for the ellipse.
  438. @param y Center y coordinate for the ellipse.
  439. @param xRadius X axis radius for the ellipse.
  440. @param yRadius Y axis radius for the ellipse.
  441. #end
  442. Method DrawEllipse( x:Float,y:Float,xRadius:Float,yRadius:Float )
  443. DrawOval( x-xRadius,y-yRadius,xRadius*2,yRadius*2 )
  444. End
  445. #rem monkeydoc Draws a circle.
  446. Draws a circle in the current [[Color]] using the current [[BlendMode]] and transformed by the current [[Matrix]].
  447. @param x Center x coordinate for the circle.
  448. @param y Center y coordinate for the circle.
  449. @param radius The circle radius.
  450. #end
  451. Method DrawCircle( x:Float,y:Float,radius:Float )
  452. DrawOval( x-radius,y-radius,radius*2,radius*2 )
  453. End
  454. #rem monkeydoc Draws a polygon.
  455. Draws a polygon using the current [[Color]], [[BlendMode]] and [[Matrix]].
  456. @param vertices Array of x/y vertex coordinate pairs.
  457. #end
  458. Method DrawPoly( vertices:Float[] )
  459. DebugAssert( vertices.Length>=6 And vertices.Length&1=0 )
  460. Local n:=vertices.Length/2
  461. AddDrawOp( _materials[5],n,1 )
  462. For Local i:=0 Until n*2 Step 2
  463. AddVertex( vertices[i],vertices[i+1],0,0 )
  464. Next
  465. End
  466. #rem monkeydoc Draws a sequence of primtives.
  467. Draws a sequence of convex primtives using the current [[Color]], [[BlendMode]] and [[Matrix]].
  468. @param order The type of primitive: 1=points, 2=lines, 3=triangles, 4=quads, >4=n-gons.
  469. @param count The number of primitives to draw.
  470. @param vertices Pointer to the first vertex x,y pair.
  471. @param verticesPitch Number of bytes from one vertex x,y pair to the next - set to 8 for 'tightly packed' vertices.
  472. @param texCoords Pointer to the first texCoord s,t pair. This can be null.
  473. @param texCoordsPitch Number of bytes from one texCoord s,y to the next.
  474. @param indices Pointer to sequence of integer indices for indexed drawing. This can by null for non-indexed drawing.
  475. #end
  476. Method DrawPrimitives( order:Int,count:Int,vertices:Float Ptr,verticesPitch:Int,texCoords:Float Ptr,texCoordsPitch:Int,indices:Int Ptr )
  477. DebugAssert( order>0,"Illegal primtive type" )
  478. If Not texCoords
  479. Global _texCoords:=New Stack<Float>
  480. If _texCoords.Length<>order*2
  481. _texCoords.Resize( order*2 )
  482. For Local i:=0 Until order*2 Step 2
  483. _texCoords[i]=0
  484. _texCoords[i=1]=0
  485. Next
  486. Endif
  487. texCoords=_texCoords.Data.Data
  488. texCoordsPitch=8
  489. Endif
  490. AddDrawOp( _materials[ Min( order,5 ) ],order,count )
  491. If indices
  492. For Local i:=0 Until count
  493. For Local j:=0 Until order
  494. Local k:=indices[j]
  495. Local vp:=Cast<Float Ptr>( Cast<UByte Ptr>( vertices )+k*verticesPitch )
  496. Local tp:=Cast<Float Ptr>( Cast<UByte Ptr>( texCoords )+k*texCoordsPitch )
  497. AddVertex( vp[0],vp[1],tp[0],tp[1] )
  498. Next
  499. indices=indices+order
  500. Next
  501. Else
  502. For Local i:=0 Until count
  503. For Local j:=0 Until order
  504. AddVertex( vertices[0],vertices[1],texCoords[0],texCoords[1] )
  505. vertices=Cast<Float Ptr>( Cast<UByte Ptr>( vertices )+verticesPitch )
  506. texCoords=Cast<Float Ptr>( Cast<UByte Ptr>( texCoords )+texCoordsPitch )
  507. Next
  508. Next
  509. End
  510. End
  511. #rem monkeydoc Draws an image.
  512. Draws an image using the current [[Color]], [[BlendMode]] and [[Matrix]].
  513. @param tx X coordinate to draw image at.
  514. @param ty Y coordinate to draw image at.
  515. @param translation X/Y coordinates to draw image at.
  516. @param rz Rotation angle, in radians, for drawing.
  517. @param sx X axis scale factor for drawing.
  518. @param sy Y axis scale factor for drawing.
  519. @param scale X/Y scale factor for drawing.
  520. #end
  521. Method DrawImage( image:Image,tx:Float,ty:Float )
  522. Local vs:=image.Vertices
  523. Local tc:=image.TexCoords
  524. AddDrawOp( image.Material,4,1 )
  525. AddVertex( vs.min.x+tx,vs.min.y+ty,tc.min.x,tc.min.y )
  526. AddVertex( vs.max.x+tx,vs.min.y+ty,tc.max.x,tc.min.y )
  527. AddVertex( vs.max.x+tx,vs.max.y+ty,tc.max.x,tc.max.y )
  528. AddVertex( vs.min.x+tx,vs.max.y+ty,tc.min.x,tc.max.y )
  529. End
  530. Method DrawImage( image:Image,translation:Vec2f )
  531. DrawImage( image,translation.x,translation.y )
  532. End
  533. Method DrawImage( image:Image,tx:Float,ty:Float,rz:Float )
  534. Local matrix:=_matrix
  535. Translate( tx,ty )
  536. Rotate( rz )
  537. DrawImage( image,0,0 )
  538. _matrix=matrix
  539. End
  540. Method DrawImage( image:Image,translation:Vec2f,rz:Float )
  541. DrawImage( image,translation.x,translation.y,rz )
  542. End
  543. Method DrawImage( image:Image,tx:Float,ty:Float,rz:Float,sx:Float,sy:Float )
  544. Local matrix:=_matrix
  545. Translate( tx,ty )
  546. Rotate( rz )
  547. Scale( sx,sy )
  548. DrawImage( image,0,0 )
  549. _matrix=matrix
  550. End
  551. Method DrawImage( image:Image,translation:Vec2f,rz:Float,scale:Vec2f )
  552. DrawImage( image,translation.x,translation.y,rz,scale.x,scale.y )
  553. End
  554. #rem monkeydoc Draws text.
  555. Draws text using the current [[Color]], [[BlendMode]] and [[Matrix]].
  556. @param text The text to draw.
  557. @param tx X coordinate to draw text at.
  558. @param ty Y coordinate to draw text at.
  559. @param handleX X handle for drawing.
  560. @param handleY Y handle for drawing.
  561. #end
  562. Method DrawText( text:String,tx:Float,ty:Float,handleX:Float=0,handleY:Float=0 )
  563. tx-=_font.TextWidth( text ) * handleX
  564. ty-=_font.Height * handleY
  565. Local image:=_font.Image
  566. Local sx:=image.Rect.min.x,sy:=image.Rect.min.y
  567. Local tw:=image.Texture.Width,th:=image.Texture.Height
  568. AddDrawOp( image.Material,4,text.Length )
  569. For Local char:=Eachin text
  570. Local g:=_font.GetGlyph( char )
  571. Local s0:=Float(g.rect.min.x+sx)/tw
  572. Local t0:=Float(g.rect.min.y+sy)/th
  573. Local s1:=Float(g.rect.max.x+sx)/tw
  574. Local t1:=Float(g.rect.max.y+sy)/th
  575. Local x0:=Round( tx+g.offset.x )
  576. Local y0:=Round( ty+g.offset.y )
  577. Local x1:=x0+g.rect.Width
  578. Local y1:=y0+g.rect.Height
  579. AddVertex( x0,y0,s0,t0 )
  580. AddVertex( x1,y0,s1,t0 )
  581. AddVertex( x1,y1,s1,t1 )
  582. AddVertex( x0,y1,s0,t1 )
  583. tx+=g.advance
  584. Next
  585. End
  586. #rem
  587. Method AddLight( tx:Float,ty:Float,radius:Radius )
  588. Local x:=_matrix.i.x * tx + _matrix.j.x * ty + _matrix.t.x
  589. Local y:=_matrix.i.y * tx + _matrix.j.y * ty + _matrix.t.y
  590. Local inst:=New LightInst
  591. inst.position=New Vec2f( x,y )
  592. inst.radius=radius
  593. inst.color=_color
  594. '_lights.Push( inst )
  595. End
  596. #end
  597. Private
  598. Struct LightInst
  599. Field position:Vec2f
  600. Field radius:Float
  601. Field color:Color
  602. End
  603. Enum Dirty
  604. Target=1
  605. Scissor=2
  606. EnvParams=4
  607. All=7
  608. End
  609. Global _inited:Bool
  610. Global _ambientEnv:ShaderEnv
  611. Global _nullShader:Shader
  612. Global _defaultFont:Font
  613. Field _dirty:Dirty
  614. Field _target:Texture
  615. Field _targetSize:Vec2i
  616. Field _targetRect:Recti
  617. Field _envParams:ParamBuffer
  618. Field _device:GraphicsDevice
  619. Field _viewport:Recti
  620. Field _scissor:Recti
  621. Field _viewMatrix:Mat4f
  622. Field _modelMatrix:Mat4f
  623. Field _ambientLight:Color
  624. Field _filter:Bool=True
  625. Field _renderColor:Color
  626. Field _renderMatrix:AffineMat3f
  627. Field _renderMatrixStack:=New Stack<AffineMat3f>
  628. Field _renderBounds:Recti
  629. Field _renderBoundsStack:=New Stack<Recti>
  630. Field _font:Font
  631. Field _alpha:Float
  632. Field _color:Color
  633. Field _pmcolor:UInt
  634. Field _matrix:AffineMat3f
  635. Field _blendMode:BlendMode
  636. Field _pointSize:Float
  637. Field _lineWidth:Float
  638. Field _matrixStack:=New Stack<AffineMat3f>
  639. Field _ops:=New Stack<DrawOp>
  640. Field _op:=New DrawOp
  641. Field _vertices:=New Stack<Vertex2f>
  642. Field _vertexData:Vertex2f[]
  643. Field _vertex:Int
  644. Field _materials:=New Material[6]
  645. Method Init( target:Texture,size:Vec2i,viewport:Recti )
  646. If Not _inited
  647. _inited=True
  648. Local env:=stringio.LoadString( "asset::mojo/shader_env.glsl" )
  649. _ambientEnv=New ShaderEnv( "#define RENDERPASS_AMBIENT~n"+env )
  650. ' _ambientEnv=New ShaderEnv( "#define RENDERPASS_NORMAL~n"+env )
  651. _defaultFont=Font.Load( "font::DejaVuSans.ttf",16 )
  652. _nullShader=Shader.GetShader( "null" )
  653. Endif
  654. _target=target
  655. _targetSize=size
  656. _targetRect=viewport
  657. _envParams=New ParamBuffer
  658. _device=New GraphicsDevice
  659. _viewport=New Recti( 0,0,_targetRect.Width,_targetRect.Height )
  660. _scissor=_viewport
  661. _viewMatrix=New Mat4f
  662. _modelMatrix=New Mat4f
  663. _ambientLight=Color.Black
  664. _filter=True
  665. _renderColor=Color.White
  666. _renderMatrix=New AffineMat3f
  667. _renderBounds=New Recti( 0,0,$40000000,$40000000 )
  668. _dirty=Dirty.All
  669. Font=Null
  670. Alpha=1
  671. Color=Color.White
  672. Matrix=New AffineMat3f
  673. BlendMode=BlendMode.Alpha
  674. PointSize=1
  675. LineWidth=1
  676. For Local i:=0 Until _materials.Length
  677. _materials[i]=New Material( _nullShader )
  678. Next
  679. End
  680. Method Validate()
  681. If Not _dirty Return
  682. If _dirty & Dirty.Target
  683. Local projMatrix:Mat4f
  684. Local viewport:=_targetRect
  685. If _target
  686. projMatrix=Mat4f.Ortho( 0,viewport.Width,0,viewport.Height,-1,1 )
  687. Else
  688. viewport.min.y=_targetSize.y-viewport.max.y
  689. viewport.max.y=viewport.min.y+viewport.Height
  690. projMatrix=Mat4f.Ortho( 0,viewport.Width,viewport.Height,0,-1,1 )
  691. Endif
  692. _device.RenderTarget=_target
  693. _device.Viewport=_targetRect
  694. _envParams.SetMatrix( "mx2_ProjectionMatrix",projMatrix )
  695. _dirty|=Dirty.EnvParams
  696. Endif
  697. If _dirty & Dirty.EnvParams
  698. Local renderMatrix:=_renderMatrix.Translate( New Vec2f( _viewport.X,_viewport.Y ) )
  699. Local modelViewMatrix:=_viewMatrix * _modelMatrix * New Mat4f( renderMatrix )
  700. _envParams.SetMatrix( "mx2_ModelViewMatrix",modelViewMatrix )
  701. _envParams.SetColor( "mx2_AmbientLight",_ambientLight )
  702. _envParams.SetColor( "mx2_RenderColor",_renderColor )
  703. _device.EnvParams=_envParams
  704. Endif
  705. If _dirty & Dirty.Scissor
  706. Local scissor:=TransformRecti( _viewport & (_scissor+_viewport.Origin),_renderMatrix )
  707. scissor=(scissor & _renderBounds)+_targetRect.Origin
  708. If Not _target
  709. Local h:=scissor.Height
  710. scissor.min.y=_targetSize.y-scissor.max.y
  711. scissor.max.y=scissor.min.y+h
  712. Endif
  713. _device.Scissor=scissor
  714. Endif
  715. _dirty=Null
  716. End
  717. Method RenderDrawOps()
  718. Local p:=_vertexData.Data
  719. _device.FilteringEnabled=_filter
  720. For Local op:=Eachin _ops
  721. _device.BlendMode=op.blendMode
  722. _device.Shader=op.material.Shader
  723. _device.Params=op.material.Params
  724. _device.Render( p,op.order,op.count )
  725. p=p+op.order*op.count
  726. Next
  727. End
  728. Method ClearDrawOps()
  729. _ops.Clear()
  730. _vertices.Clear()
  731. _vertexData=_vertices.Data
  732. _op=New DrawOp
  733. _vertex=0
  734. End
  735. Method AddDrawOp( material:Material,order:Int,count:Int )
  736. _vertices.Resize( _vertex+order*count )
  737. _vertexData=_vertices.Data
  738. If _blendMode=_op.blendMode And material=_op.material And order=_op.order
  739. _op.count+=count
  740. Return
  741. End
  742. _op=New DrawOp
  743. _op.blendMode=_blendMode
  744. _op.material=material
  745. _op.order=order
  746. _op.count=count
  747. _ops.Add( _op )
  748. End
  749. Method AddVertex( tx:Float,ty:Float,s0:Float,t0:Float )
  750. _vertexData[_vertex].x=_matrix.i.x * tx + _matrix.j.x * ty + _matrix.t.x
  751. _vertexData[_vertex].y=_matrix.i.y * tx + _matrix.j.y * ty + _matrix.t.y
  752. _vertexData[_vertex].s0=s0
  753. _vertexData[_vertex].t0=t0
  754. _vertexData[_vertex].ix=_matrix.i.x
  755. _vertexData[_vertex].iy=_matrix.i.y
  756. _vertexData[_vertex].color=_pmcolor
  757. _vertex+=1
  758. End
  759. End