odd2d.bmx 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. SuperStrict
  2. Rem
  3. bbdoc: Graphics/Odd2D
  4. about:
  5. All Max2D commands should work as intended with the Odd2D module.
  6. End Rem
  7. Module ODD.Odd2D
  8. ModuleInfo "Version: 1.03"
  9. ModuleInfo "Author: David Williamson"
  10. ModuleInfo "License: Public Domain"
  11. Import BRL.Max2D
  12. 'Const BORDER_KEEP:Int=1
  13. Const BORDER_NONE:Int=0
  14. Const BORDER_LETTERBOX_FILL:Int=2
  15. Const BORDER_LETTERBOX_SOLID:Int=3
  16. Const BORDER_BESTFIT_FILL:Int=4
  17. Const BORDER_BESTFIT_SOLID:Int=5
  18. Rem
  19. bbdoc: Modulate 2x blend mode
  20. about: Can be used with #SetBlend for mudulate 2x blending.
  21. End Rem
  22. Const MOD2XBLEND:Int=6
  23. Global _odd2dDriver:TOdd2DDriver
  24. Type TOdd2DDriver Extends TMax2DDriver
  25. Field _m2ddriver:TMax2DDriver
  26. Field border_red:Int, border_green:Int, border_blue:Int
  27. Field border_mode:Int, border_x:Float, border_y:Float
  28. Field full_width:Float, full_height:Float, virt_width:Float, virt_height:Float, ratio:Float
  29. Field tform_scr_rot:Float, tform_scr_zoom:Float
  30. Field tform_scr_ix#,tform_scr_iy#,tform_scr_jx#,tform_scr_jy#
  31. Field focus_x:Float, focus_y:Float
  32. Field adj_vp_x:Int, adj_vp_y:Int, adj_vp_width:Int, adj_vp_height:Int
  33. Field m2d_blend:Int, m2d_alpha:Float, m2d_linewidth:Float
  34. Field m2d_clsred:Int, m2d_clsgreen:Int, m2d_clsblue:Int,m2d_clsalpha:Float
  35. Field m2d_red:Int, m2d_green:Int, m2d_blue:Int
  36. Field m2d_ix:Float, m2d_iy:Float, m2d_jx:Float, m2d_jy:Float
  37. Method GraphicsModes:TGraphicsMode[]()
  38. Return _m2ddriver.GraphicsModes()
  39. End Method
  40. ' Method AttachGraphics:TGraphics( widget,flags ) Abstract
  41. ' Method CreateGraphics:TGraphics( width,height,depth,hertz,flags ) Abstract
  42. Method SetGraphics( g:TGraphics )
  43. _m2ddriver.SetGraphics g
  44. _odd2dDriver=TOdd2DDriver(_max2dDriver)
  45. End Method
  46. Method Flip:Int( sync:Int )
  47. ClearBorder
  48. _m2ddriver.Flip sync
  49. End Method
  50. ' Method CreateFrameFromPixmap:TImageFrame( pixmap:TPixmap,flags ) Abstract
  51. Method SetBlend( blend:Int )
  52. m2d_blend=blend
  53. _m2dDriver.SetBlend blend
  54. End Method
  55. Method SetAlpha( alpha:Float )
  56. m2d_alpha=alpha
  57. _m2dDriver.SetAlpha alpha
  58. End Method
  59. Method SetColor( red:Int, green:Int, blue:Int )
  60. m2d_red=red;m2d_green=green;m2d_blue=blue
  61. _m2dDriver.SetColor red,green,blue
  62. End Method
  63. Method SetClsColor( red:Int, green:Int, blue:Int, alpha:Float )
  64. m2d_clsred=red;m2d_clsgreen=green;m2d_clsblue=blue;m2d_clsalpha=alpha
  65. _m2dDriver.SetClsColor red,green,blue,alpha
  66. End Method
  67. Method SetViewport( x:Int, y:Int, width:Int, height:Int )
  68. Local xscale:Float=full_width/virt_width
  69. Local yscale:Float=full_height/virt_height
  70. adj_vp_x=border_x*ratio+x/xscale
  71. adj_vp_y=border_y*ratio+y/yscale
  72. adj_vp_width=width/xscale
  73. adj_vp_height=height/yscale
  74. _m2dDriver.SetViewport adj_vp_x,adj_vp_y,adj_vp_width,adj_vp_height
  75. End Method
  76. Method SetTransform( xx:Float, xy:Float, yx:Float, yy:Float )
  77. m2d_ix=xx;m2d_iy=xy;m2d_jx=yx;m2d_jy=yy
  78. _m2dDriver.SetTransform xx,xy,yx,yy
  79. End Method
  80. Method SetLineWidth( width:Float )
  81. m2d_linewidth=width
  82. _m2dDriver.SetLineWidth width
  83. End Method
  84. Method Cls()
  85. _m2dDriver.Cls
  86. End Method
  87. Method Plot( x#,y# )
  88. TransformPoint x,y
  89. x:+border_x+focus_x
  90. y:+border_y+focus_y
  91. _m2dDriver.Plot x,y
  92. End Method
  93. Method DrawLine( x0#,y0#,x1#,y1#,tx#,ty# )
  94. TransformPoint x0,y0
  95. TransformPoint x1,y1
  96. TransformPoint tx,ty
  97. tx:+border_x+focus_x
  98. ty:+border_y+focus_y
  99. _m2dDriver.DrawLine x0,y0,x1,y1,tx,ty
  100. End Method
  101. Method DrawRect( x0#,y0#,x1#,y1#,tx#,ty# )
  102. Local rot:Float=GetRotation()
  103. Local sclx:Float,scly:Float
  104. GetScale sclx,scly
  105. SetRotation rot-tform_scr_rot
  106. SetScale sclx*tform_scr_zoom,scly*tform_scr_zoom
  107. TransformPoint tx,ty
  108. tx:+focus_x+border_x
  109. ty:+focus_y+border_y
  110. _m2dDriver.DrawRect x0,y0,x1,y1,tx,ty
  111. SetRotation rot
  112. SetScale sclx,scly
  113. End Method
  114. Method DrawOval( x0#,y0#,x1#,y1#,tx#,ty# )
  115. Local rot:Float=GetRotation()
  116. Local sclx:Float,scly:Float
  117. GetScale sclx,scly
  118. SetRotation rot-tform_scr_rot
  119. SetScale sclx*tform_scr_zoom,scly*tform_scr_zoom
  120. TransformPoint tx,ty
  121. tx:+focus_x+border_x
  122. ty:+focus_y+border_y
  123. _m2dDriver.DrawOval x0,y0,x1,y1,tx,ty
  124. SetRotation rot
  125. SetScale sclx,scly
  126. End Method
  127. Method DrawPoly( xy#[],handlex#,handley#,originx#,originy#, indices:Int[] )
  128. Local rot:Float=GetRotation()
  129. Local sclx:Float,scly:Float
  130. GetScale sclx,scly
  131. SetRotation rot-tform_scr_rot
  132. SetScale sclx*tform_scr_zoom,scly*tform_scr_zoom
  133. TransformPoint originx,originy
  134. originx:+focus_x+border_x
  135. originy:+focus_y+border_y
  136. _m2dDriver.DrawPoly xy,handlex,handley,originx,originy,indices
  137. SetRotation rot
  138. SetScale sclx,scly
  139. End Method
  140. Method DrawPixmap( pixmap:TPixmap, x:Int, y:Int )
  141. _m2dDriver.DrawPixmap pixmap,x,y
  142. End Method
  143. Method GrabPixmap:TPixmap( x:Int, y:Int, width:Int, height:Int )
  144. Return _m2dDriver.GrabPixmap(x,y,width,height)
  145. End Method
  146. Method SetResolution( width#,height# )
  147. virt_width=width;virt_height=height
  148. Local gwidth:Int=GraphicsWidth()
  149. Local gheight:Int=GraphicsHeight()
  150. If border_mode=BORDER_NONE
  151. border_x=0;border_y=0;full_width=virt_width;full_height=virt_height;ratio=1
  152. adj_vp_x=0;adj_vp_y=0;adj_vp_width=Ceil(gwidth);adj_vp_height=Ceil(gheight)
  153. _m2dDriver.SetResolution(full_width,full_height)
  154. _m2dDriver.SetViewport adj_vp_x,adj_vp_y,adj_vp_width,adj_vp_height
  155. Return
  156. EndIf
  157. ratio=Min(gwidth/virt_width,gheight/virt_height)
  158. If border_mode&4
  159. ratio=Max(Floor(ratio),1)
  160. EndIf
  161. full_height=gheight/ratio
  162. full_width=gwidth/ratio
  163. border_x=(full_width-virt_width)*.5
  164. border_y=(full_height-virt_height)*.5
  165. If border_mode&4
  166. border_x=Floor(border_x)
  167. border_y=Floor(border_y)
  168. EndIf
  169. _m2dDriver.SetResolution full_width,full_height
  170. adj_vp_x=0;adj_vp_y=0;adj_vp_width=Ceil(full_width)*ratio;adj_vp_height=Ceil(full_height)*ratio
  171. _m2dDriver.SetViewport adj_vp_x,adj_vp_y,adj_vp_width,adj_vp_height
  172. End Method
  173. Method SetBorderMode( Mode:Int )
  174. border_mode=Mode
  175. SetResolution virt_width,virt_height
  176. End Method
  177. Method SetBorderColor( red:Int, green:Int, blue:Int )
  178. border_red=red
  179. border_green=green
  180. border_blue=blue
  181. End Method
  182. Method ClearBorder()
  183. If border_mode&1
  184. Local rot:Float=GetRotation()
  185. Local ox:Float,oy:Float;GetOrigin ox,oy
  186. Local hx:Float,hy:Float;GetHandle hx,hy
  187. Local sx:Float, sy:Float;GetScale sx,sy
  188. _m2dDriver.SetViewport 0,0,Int(Ceil(full_width)*ratio),Int(Ceil(full_height)*ratio)
  189. _m2dDriver.SetColor border_red,border_green,border_blue
  190. _m2dDriver.SetAlpha 1
  191. SetRotation 0
  192. SetOrigin 0,0
  193. SetHandle 0,0
  194. SetScale 1,1
  195. _m2dDriver.SetBlend SOLIDBLEND
  196. _m2dDriver.DrawRect -1,-1,full_width+1,border_y,0,0
  197. _m2dDriver.DrawRect -1,border_y+virt_height,full_width+1,full_height+1,0,0
  198. _m2dDriver.DrawRect -1,border_y-1,border_x,border_y+virt_height+1,0,0
  199. _m2dDriver.DrawRect border_x+virt_width,border_y-1,full_width+1,border_y+virt_height+1,0,0
  200. SetColor m2d_red,m2d_green,m2d_blue
  201. _m2dDriver.SetAlpha m2d_alpha
  202. SetRotation rot
  203. SetOrigin ox,oy
  204. SetHandle hx,hy
  205. SetScale sx,sy
  206. SetBlend m2d_blend
  207. _m2dDriver.SetViewport adj_vp_x,adj_vp_y,adj_vp_width,adj_vp_height
  208. EndIf
  209. End Method
  210. Method SetScreenRotation( rot:Float )
  211. tform_scr_rot=rot
  212. UpdateTransform
  213. End Method
  214. Method SetZoom( zoom:Float )
  215. tform_scr_zoom=zoom
  216. UpdateTransform
  217. End Method
  218. Method SetFocus( x:Float, y:Float )
  219. focus_x=x
  220. focus_y=y
  221. End Method
  222. Method SetMidFocus()
  223. focus_x=virt_width*.5
  224. focus_y=virt_height*.5
  225. End Method
  226. Method OddMouse( x:Float Var, y:Float Var )
  227. Local ox:Float,oy:Float;GetOrigin ox,oy
  228. Local s#=Sin(tform_scr_rot), c#=Cos(tform_scr_rot)
  229. Local ix#= c/tform_scr_zoom, jx#= s/tform_scr_zoom
  230. Local iy#=-s/tform_scr_zoom, jy#= c/tform_scr_zoom
  231. Local xscale:Float=full_width/virt_width
  232. Local yscale:Float=full_height/virt_height
  233. x=VirtualMouseX()*(full_width/virt_width)-border_x-focus_x
  234. y=VirtualMouseY()*(full_height/virt_height)-border_y-focus_y
  235. Local tmp_x:Float=x
  236. x=x*ix+y*iy-ox
  237. y=tmp_x*jx+y*jy-oy
  238. End Method
  239. Method DrawPolyImage( xyuv#[],iframe:TImageFrame,handlex#,handley#,originx#,originy# ) Abstract
  240. Method UpdateTransform()
  241. Local s#=Sin(-tform_scr_rot)
  242. Local c#=Cos(-tform_scr_rot)
  243. tform_scr_ix= c*tform_scr_zoom
  244. tform_scr_iy=-s*tform_scr_zoom
  245. tform_scr_jx= s*tform_scr_zoom
  246. tform_scr_jy= c*tform_scr_zoom
  247. End Method
  248. Method TransformPoint( x:Float Var, y:Float Var )
  249. Local tmp_x:Float=x
  250. x=x*tform_scr_ix+y*tform_scr_iy
  251. y=tmp_x*tform_scr_jx+y*tform_scr_jy
  252. End Method
  253. Method InitFields()
  254. border_red=0
  255. border_green=0
  256. border_blue=0
  257. border_mode=BORDER_NONE
  258. border_x=0
  259. border_y=0
  260. full_width=GraphicsWidth()
  261. full_height=GraphicsHeight()
  262. virt_width=full_width
  263. virt_height=full_height
  264. tform_scr_rot=0
  265. tform_scr_zoom=1
  266. UpdateTransform
  267. focus_x=0
  268. focus_y=0
  269. m2d_blend=MASKBLEND
  270. m2d_alpha=1
  271. m2d_linewidth=1
  272. m2d_clsred=0;m2d_clsgreen=0;m2d_clsblue=0;m2d_clsalpha=1
  273. m2d_red=255;m2d_green=255;m2d_blue=255
  274. End Method
  275. End Type
  276. Rem
  277. bbdoc: Sets how borders displayed
  278. about: Sets how borders will be displayed if the virtual aspect ratio is not the same as the screens aspect ratio.
  279. The available modes are:
  280. [ @BORDER_NONE | Stretches/distorts the display to fit the screen. This is the default Max2D behaviour
  281. * @BORDER_LETTERBOX_FILL | Scales the display to fit the screen but maintains it's aspect ratio. Any draw space left around it is @not clipped
  282. * @BORDER_LETTERBOX_SOLID | Scales the display to fit the screen but maintains it's aspect ratio. Any draw space left around it is clipped
  283. * @BORDER_BESTFIT_FILL | Scales the display by whole numbers only whilst maintaining it's aspect ratio. Any draw space left around it is @not clipped
  284. * @BORDER_BESTFIT_SOLID | Scales the display by whole numbers only whilst maintaining it's aspect ratio. Any draw space left around it is clipped
  285. ]
  286. End Rem
  287. Function SetBorderMode( Mode:Int )
  288. _odd2dDriver.SetBorderMode Mode
  289. End Function
  290. Rem
  291. bbdoc: Set current border color
  292. about:
  293. The @red, @green and @blue parameters should be in the range of 0 to 255.
  294. The default border color is black.
  295. End Rem
  296. Function SetBorderColor( red:Int, green:Int, blue:Int )
  297. _odd2dDriver.SetBorderColor red,green,blue
  298. End Function
  299. Rem
  300. bbdoc: Set screen rotation
  301. about:
  302. @rotation is given in degrees and should be in the range 0 to 360.
  303. #SetScreenRotation rotates the whole display around the focus.
  304. End Rem
  305. Function SetScreenRotation( rot:Float )
  306. _odd2dDriver.SetScreenRotation rot
  307. End Function
  308. Rem
  309. bbdoc: Set current screen zoom
  310. about:
  311. Zooms the display in or out centered upon the focus.
  312. End Rem
  313. Function SetZoom( zoom:Float )
  314. _odd2dDriver.SetZoom zoom
  315. End Function
  316. Rem
  317. bbdoc: Set display focus
  318. about:
  319. The screen focus is a 2D offset added to the x,y location of all
  320. drawing commands. It is applied after all other transforms and can be thought of as the screens handle.
  321. In Max2D the focus is allways the top lext of the screen meaning all other cammands ultimately take their origin from that,
  322. #SetScreenFocus allows you to change this behaviour.
  323. End Rem
  324. Function SetScreenFocus( x:Float, y:Float )
  325. _odd2dDriver.SetFocus x,y
  326. End Function
  327. Rem
  328. bbdoc: Sets the screen focus to the center of the display
  329. End Rem
  330. Function SetMidFocus()
  331. _odd2dDriver.SetMidFocus
  332. End Function
  333. Rem
  334. bbdoc: Gets the current position of the mouse
  335. about: Sets @x and @y to the current mouse position using the draw coordinates.
  336. EndRem
  337. Function OddMouse( x:Float Var, y:Float Var )
  338. _odd2dDriver.OddMouse x,y
  339. End Function
  340. Rem
  341. bbdoc: Draw a polygon using image as a texture
  342. about:
  343. #DrawPolyImage draws a polygon with corners defined by an array of x#,y# and u#,v# coordinate pairs.
  344. The u/v coordinates are measured in image pixels.
  345. BlitzMax commands that affect the drawing of polygons include #SetColor, #SetHandle,
  346. #SetScale, #SetRotation, #SetOrigin, #SetViewPort, #SetBlend and #SetAlpha.
  347. End Rem
  348. Function DrawPolyImage( xyuv:Float[], image:TImage, frame:Int=0 )
  349. Local iframe:TImageFrame=image.Frame(frame)
  350. If Not iframe Then Return
  351. Local handle_x:Float, handle_y:Float, origin_x:Float, origin_y:Float
  352. GetHandle handle_x,handle_y;GetOrigin origin_x,origin_y
  353. Local rot:Float=GetRotation()
  354. Local sclx:Float,scly:Float
  355. GetScale sclx,scly
  356. SetRotation rot-_odd2dDriver.tform_scr_rot
  357. SetScale sclx*_odd2dDriver.tform_scr_zoom,scly*_odd2dDriver.tform_scr_zoom
  358. _odd2dDriver.TransformPoint origin_x,origin_y
  359. origin_x:+_odd2dDriver.focus_x+_odd2dDriver.border_x
  360. origin_y:+_odd2dDriver.focus_y+_odd2dDriver.border_y
  361. _odd2ddriver.DrawPolyImage xyuv,iframe,handle_x,handle_y,origin_x,origin_y
  362. SetRotation rot
  363. SetScale sclx,scly
  364. End Function
  365. Rem
  366. bbdoc: Draw an image polygon to the back buffer
  367. about:
  368. #DrawImagePoly works the same as #DrawImage except instead of drawing the full image it draws a polygonal portion of it defined by the u,v coordinates.
  369. The u/v coordinates are measured in image pixels.
  370. Drawing is affected by the current blend mode, color, scale and rotation.
  371. If the blend mode is ALPHABLEND the image is affected by the current alpha value
  372. and images with alpha channels are blended correctly with the background.
  373. End Rem
  374. Function DrawImagePoly( image:TImage, x:Float, y:Float, uv:Float[], frame:Int=0 )
  375. Local iframe:TImageFrame=image.Frame(frame)
  376. If Not iframe Then Return
  377. Local handle_x:Float, handle_y:Float, origin_x:Float, origin_y:Float
  378. GetOrigin origin_x,origin_y
  379. origin_x:+x;origin_y:+y
  380. Local rot:Float=GetRotation()
  381. Local sclx:Float,scly:Float
  382. GetScale sclx,scly
  383. SetRotation rot-_odd2dDriver.tform_scr_rot
  384. SetScale sclx*_odd2dDriver.tform_scr_zoom,scly*_odd2dDriver.tform_scr_zoom
  385. _odd2dDriver.TransformPoint origin_x,origin_y
  386. origin_x:+_odd2dDriver.focus_x+_odd2dDriver.border_x
  387. origin_y:+_odd2dDriver.focus_y+_odd2dDriver.border_y
  388. Local segs:Int=uv.length/2
  389. Local xyuv:Float[segs*4]
  390. For Local i:Int=0 Until segs
  391. xyuv[i*4]=uv[i*2]
  392. xyuv[i*4+1]=uv[i*2+1]
  393. xyuv[i*4+2]=uv[i*2]
  394. xyuv[i*4+3]=uv[i*2+1]
  395. Next
  396. _odd2ddriver.DrawPolyImage xyuv,iframe,image.handle_x,image.handle_y,origin_x,origin_y
  397. SetRotation rot
  398. SetScale sclx,scly
  399. End Function