d3d9max2d.bmx 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176
  1. SuperStrict
  2. Rem
  3. bbdoc: Graphics/Direct3D9 Max2D
  4. about:
  5. The Direct3D9 Max2D module provides a Direct3D9 driver for #Max2D.
  6. End Rem
  7. Module BRL.D3D9Max2D
  8. ModuleInfo "Version: 1.02"
  9. ModuleInfo "License: zlib/libpng"
  10. ModuleInfo "Copyright: Blitz Research Ltd"
  11. ModuleInfo "History: 1.02"
  12. ModuleInfo "History: Changed to SuperStrict"
  13. ModuleInfo "History: Extended flags to Long"
  14. ModuleInfo "History: 1.01"
  15. ModuleInfo "History: Changed Assert to Throw. One can at least catch a Throw."
  16. ?win32
  17. Import BRL.Max2D
  18. Import BRL.DXGraphics
  19. 'Import BRL.D3D7Max2D
  20. Const LOG_ERRS:Int=True'False
  21. Private
  22. Global _gw:Int,_gh:Int,_gd:Int,_gr:Int,_gf:Long,_gx:Int,_gy:Int
  23. Global _color:Int
  24. Global _clscolor:Int
  25. Global _ix:Float,_iy:Float,_jx:Float,_jy:Float
  26. Global _fverts:Float[24]
  27. Global _iverts:Int Ptr=Int Ptr( Varptr _fverts[0] )
  28. Global _lineWidth:Float
  29. Global _bound_texture:IDirect3DTexture9
  30. Global _texture_enabled:Int
  31. Global _active_blend:Int
  32. Global _driver:TD3D9Max2DDriver
  33. Global _d3dDev:IDirect3DDevice9
  34. Global _d3d9Graphics:TD3D9Graphics
  35. Global _max2dGraphics:TMax2dGraphics
  36. Function Pow2Size:Int( n:Int )
  37. Local t:Int=1
  38. While t<n
  39. t:*2
  40. Wend
  41. Return t
  42. End Function
  43. Function DisableTex()
  44. If Not _texture_enabled Return
  45. _d3dDev.SetTextureStageState 0,D3DTSS_COLOROP,D3DTOP_SELECTARG2
  46. _d3dDev.SetTextureStageState 0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG2
  47. _texture_enabled=False
  48. End Function
  49. Function d3derr( str:String )
  50. If LOG_ERRS WriteStdout "D3DERR: "+str+"~n"
  51. End Function
  52. Public
  53. Type TD3D9ImageFrame Extends TImageFrame
  54. Method Delete()
  55. If _texture
  56. If _seq=GraphicsSeq
  57. If _texture=_bound_texture
  58. _d3dDev.SetTexture 0,Null
  59. _bound_texture=Null
  60. EndIf
  61. _d3d9Graphics.ReleaseNow _texture
  62. EndIf
  63. _texture=Null
  64. EndIf
  65. End Method
  66. Method Create:TD3D9ImageFrame( pixmap:TPixmap,flags:Int )
  67. Local width:Int=pixmap.width,pow2width:Int=Pow2Size( width )
  68. Local height:Int=pixmap.height,pow2height:Int=Pow2Size( height )
  69. If width<pow2width Or height<pow2height
  70. Local src:TPixmap=pixmap
  71. pixmap=TPixmap.Create( pow2width,pow2height,PF_BGRA8888 )
  72. pixmap.Paste src,0,0
  73. If width<pow2width
  74. pixmap.Paste pixmap.Window( width-1,0,1,height ),width,0
  75. EndIf
  76. If height<pow2height
  77. pixmap.Paste pixmap.Window( 0,height-1,width,1 ),0,height
  78. If width<pow2width
  79. pixmap.Paste pixmap.Window( width-1,height-1,1,1 ),width,height
  80. EndIf
  81. EndIf
  82. Else
  83. If pixmap.Format<>PF_BGRA8888 pixmap=pixmap.Convert( PF_BGRA8888 )
  84. EndIf
  85. Local levels:Int=(flags & MIPMAPPEDIMAGE)=0
  86. Local format:Int=D3DFMT_A8R8G8B8
  87. Local usage:Int=0
  88. Local pool:Int=D3DPOOL_MANAGED
  89. '_texture = New IDirect3DTexture9
  90. If _d3dDev.CreateTexture( pow2width,pow2height,levels,usage,format,pool,_texture,Null )<0
  91. d3derr "Unable to create texture~n"
  92. _texture = Null
  93. Return null
  94. EndIf
  95. _d3d9Graphics.AutoRelease _texture
  96. Local level:Int
  97. Local dstsurf:IDirect3DSurface9' = New IDirect3DSurface9
  98. Repeat
  99. If _texture.GetSurfaceLevel( level,dstsurf )<0
  100. If level=0
  101. d3derr "_texture.GetSurfaceLevel failed~n"
  102. EndIf
  103. Exit
  104. EndIf
  105. Local lockedrect:D3DLOCKED_RECT=New D3DLOCKED_RECT
  106. If dstsurf.LockRect( lockedrect,Null,0 )<0
  107. d3derr "dstsurf.LockRect failed~n"
  108. EndIf
  109. For Local y:Int=0 Until pixmap.height
  110. Local src:Byte Ptr=pixmap.pixels+y*pixmap.pitch
  111. Local dst:Byte Ptr=lockedrect.pBits+y*lockedrect.Pitch
  112. MemCopy dst,src,Size_T(pixmap.width*4)
  113. Next
  114. dstsurf.UnlockRect
  115. dstsurf.Release_
  116. If (flags & MIPMAPPEDIMAGE)=0 Exit
  117. level:+1
  118. If pixmap.width>1 And pixmap.height>1
  119. pixmap=ResizePixmap( pixmap,pixmap.width/2,pixmap.height/2 )
  120. Else If pixmap.width>1
  121. pixmap=ResizePixmap( pixmap,pixmap.width/2,pixmap.height )
  122. Else If pixmap.height>1
  123. pixmap=ResizePixmap( pixmap,pixmap.width,pixmap.height/2 )
  124. EndIf
  125. Forever
  126. _uscale=1.0/pow2width
  127. _vscale=1.0/pow2height
  128. Local u0:Float,u1:Float=width * _uscale
  129. Local v0:Float,v1:Float=height * _vscale
  130. _fverts[4]=u0
  131. _fverts[5]=v0
  132. _fverts[10]=u1
  133. _fverts[11]=v0
  134. _fverts[16]=u1
  135. _fverts[17]=v1
  136. _fverts[22]=u0
  137. _fverts[23]=v1
  138. If flags & FILTEREDIMAGE
  139. _magfilter=D3DTFG_LINEAR
  140. _minfilter=D3DTFG_LINEAR
  141. _mipfilter=D3DTFG_LINEAR
  142. Else
  143. _magfilter=D3DTFG_POINT
  144. _minfilter=D3DTFG_POINT
  145. _mipfilter=D3DTFG_POINT
  146. EndIf
  147. _seq=GraphicsSeq
  148. Return Self
  149. End Method
  150. Method Draw( x0:Float,y0:Float,x1:Float,y1:Float,tx:Float,ty:Float,sx:Float,sy:Float,sw:Float,sh:Float ) Override
  151. Local u0:Float=sx * _uscale
  152. Local v0:Float=sy * _vscale
  153. Local u1:Float=(sx+sw) * _uscale
  154. Local v1:Float=(sy+sh) * _vscale
  155. _fverts[0]=x0*_ix+y0*_iy+tx
  156. _fverts[1]=x0*_jx+y0*_jy+ty
  157. _iverts[3]=_color
  158. _fverts[4]=u0
  159. _fverts[5]=v0
  160. _fverts[6]=x1*_ix+y0*_iy+tx
  161. _fverts[7]=x1*_jx+y0*_jy+ty
  162. _iverts[9]=_color
  163. _fverts[10]=u1
  164. _fverts[11]=v0
  165. _fverts[12]=x1*_ix+y1*_iy+tx
  166. _fverts[13]=x1*_jx+y1*_jy+ty
  167. _iverts[15]=_color
  168. _fverts[16]=u1
  169. _fverts[17]=v1
  170. _fverts[18]=x0*_ix+y1*_iy+tx
  171. _fverts[19]=x0*_jx+y1*_jy+ty
  172. _iverts[21]=_color
  173. _fverts[22]=u0
  174. _fverts[23]=v1
  175. If _texture<>_bound_texture
  176. _d3dDev.SetTexture 0,_texture
  177. _d3dDev.SetTextureStageState 0,D3DTSS_MAGFILTER,_magfilter
  178. _d3dDev.SetTextureStageState 0,D3DTSS_MINFILTER,_minfilter
  179. _d3dDev.SetTextureStageState 0,D3DTSS_MIPFILTER,_mipfilter
  180. _bound_texture=_texture
  181. EndIf
  182. If Not _texture_enabled
  183. _d3dDev.SetTextureStageState 0,D3DTSS_COLOROP,D3DTOP_MODULATE
  184. _d3dDev.SetTextureStageState 0,D3DTSS_ALPHAOP,D3DTOP_MODULATE
  185. _texture_enabled=True
  186. EndIf
  187. _d3dDev.DrawPrimitiveUP D3DPT_TRIANGLEFAN,2,_fverts,24
  188. End Method
  189. Field _texture:IDirect3DTexture9,_seq:Int
  190. Field _magfilter:Int,_minfilter:Int,_mipfilter:Int,_uscale:Float,_vscale:Float
  191. Field _fverts:Float[24],_iverts:Int Ptr=Int Ptr( Varptr _fverts[0] )
  192. End Type
  193. Type TD3D9RenderImageContext Extends TRenderImageContext
  194. Field _gc:TD3D9Graphics
  195. Field _d3ddev:IDirect3DDevice9
  196. Field _backbuffer:IDirect3DSurface9
  197. Field _matrix:Float[16]
  198. Field _viewport:D3DVIEWPORT9
  199. Field _renderImages:TList
  200. Field _deviceok:Int = True
  201. Method Delete()
  202. ReleaseNow()
  203. End Method
  204. Method ReleaseNow()
  205. If _renderImages
  206. For Local ri:TD3D9RenderImage = EachIn _renderImages
  207. ri.DestroyRenderImage()
  208. Next
  209. EndIf
  210. _renderImages = Null
  211. _viewport = Null
  212. _gc = Null
  213. If _backbuffer
  214. _backbuffer.release_
  215. _backbuffer = Null
  216. EndIf
  217. If _d3ddev
  218. _d3ddev.release_
  219. _d3ddev = Null
  220. EndIf
  221. End Method
  222. Method Create:TD3D9RenderimageContext(g:TGraphics, driver:TGraphicsDriver)
  223. _gc = TD3D9Graphics(g)
  224. ' _gc.AddDeviceMightGetLostCallback(fnOnDeviceMightGetLost, Self)
  225. _gc.AddDeviceLostCallback(fnOnDeviceLost, Self)
  226. _gc.AddDeviceResetCallback(fnOnDeviceReset, Self)
  227. _d3ddev = _gc.GetDirect3DDevice()
  228. _d3ddev.AddRef()
  229. _d3ddev.GetRenderTarget(0, _backbuffer)
  230. _viewport = New D3DVIEWPORT9
  231. _d3ddev.GetViewport(_viewport)
  232. _d3ddev.GetTransform(D3DTS_PROJECTION, _matrix)
  233. _renderImages = New TList
  234. Return Self
  235. End Method
  236. Method GraphicsContext:TGraphics()
  237. Return _gc
  238. End Method
  239. Method Destroy()
  240. ' _gc.RemoveDeviceMightGetLostCallback(fnOnDeviceMightGetLost)
  241. _gc.RemoveDeviceLostCallback(fnOnDeviceLost)
  242. _gc.RemoveDeviceResetCallback(fnOnDeviceReset)
  243. ReleaseNow()
  244. End Method
  245. Method CreateRenderImage:TRenderImage(width:Int, height:Int, UseImageFiltering:Int)
  246. Local renderimage:TD3D9RenderImage = New TD3D9RenderImage.CreateRenderImage(width, height)
  247. renderimage.Init(_d3ddev, UseImageFiltering)
  248. _renderImages.AddLast(renderimage)
  249. Return renderimage
  250. End Method
  251. Method CreateRenderImageFromPixmap:TRenderImage(pixmap:TPixmap, UseImageFiltering:Int)
  252. Local renderimage:TD3D9RenderImage = New TD3D9RenderImage.CreateRenderImage(pixmap.Width, pixmap.Height)
  253. renderimage.InitFromPixmap(_d3ddev, pixmap, UseImageFiltering)
  254. _renderImages.AddLast(renderimage)
  255. Return renderimage
  256. End Method
  257. Method DestroyRenderImage(renderImage:TRenderImage)
  258. renderImage.DestroyRenderImage()
  259. _renderImages.Remove(renderImage)
  260. End Method
  261. Method SetRenderImage(renderimage:TRenderimage)
  262. If Not renderimage
  263. _d3ddev.SetRenderTarget(0, _backbuffer)
  264. _d3ddev.SetTransform D3DTS_PROJECTION,_matrix
  265. _d3ddev.SetViewport(_viewport)
  266. Else
  267. renderimage.SetRenderImage()
  268. EndIf
  269. End Method
  270. Method CreatePixmapFromRenderImage:TPixmap(renderImage:TRenderImage)
  271. Return TD3D9RenderImage(renderImage).ToPixmap()
  272. End Method
  273. rem
  274. Method OnDeviceMightGetLost()
  275. For Local ri:TD3D9RenderImage = EachIn _renderImages
  276. ri.OnDeviceMightGetLost()
  277. Next
  278. End Method
  279. endrem
  280. Method OnDeviceLost()
  281. If _deviceok = False Then Return
  282. For Local ri:TD3D9RenderImage = EachIn _renderImages
  283. ri.OnDeviceLost()
  284. Next
  285. If _backbuffer
  286. _backbuffer.release_
  287. _backbuffer = Null
  288. EndIf
  289. _deviceok = False
  290. End Method
  291. Method OnDeviceReset()
  292. If _deviceok = True Then Return
  293. Local hr:Int = _d3ddev.GetRenderTarget(0, _backbuffer)
  294. if hr = D3D_OK
  295. ' print " _d3ddev.GetRenderTarget() result: D3D_OK"
  296. Elseif hr = D3DERR_INVALIDCALL
  297. print " _d3ddev.GetRenderTarget() result: D3DERR_INVALIDCALL"
  298. Elseif hr = D3DERR_NOTFOUND
  299. print " _d3ddev.GetRenderTarget() result: D3DERR_NOTFOUND"
  300. Else
  301. print " _d3ddev.GetRenderTarget() result: " + hr
  302. EndIf
  303. hr = _d3ddev.GetViewport(_viewport)
  304. For Local ri:TD3D9RenderImage = EachIn _renderImages
  305. ri.OnDeviceReset()
  306. Next
  307. _deviceok = True
  308. End Method
  309. rem
  310. Function fnOnDeviceMightGetLost(obj:Object)
  311. Local ric:TD3D9RenderImageContext = TD3D9RenderImageContext(obj)
  312. If Not ric Return
  313. ric.OnDeviceMightGetLost()
  314. EndFunction
  315. endrem
  316. Function fnOnDeviceLost(obj:Object)
  317. Local ric:TD3D9RenderImageContext = TD3D9RenderImageContext(obj)
  318. If Not ric Return
  319. ric.OnDeviceLost()
  320. EndFunction
  321. Function fnOnDeviceReset(obj:Object)
  322. Local ric:TD3D9RenderImageContext = TD3D9RenderImageContext(obj)
  323. If Not ric Return
  324. ric.OnDeviceReset()
  325. EndFunction
  326. EndType
  327. Type TD3D9RenderImageFrame Extends TD3D9ImageFrame
  328. Field _surface:IDirect3DSurface9
  329. Field _persistPixmap:TPixmap
  330. Method Delete()
  331. ReleaseNow()
  332. End Method
  333. 'ensure the GPU located render image would survive a "appsuspend"
  334. 'by eg. reading it into a TPixmap
  335. Method Persist:Int(d3ddev:IDirect3DDevice9, width:Int, height:Int)
  336. _persistPixmap = ToPixmap(d3ddev, width, height)
  337. Return True
  338. End Method
  339. Method ReleaseNow()
  340. If _surface
  341. _surface.Release_
  342. _surface = Null
  343. EndIf
  344. If _texture
  345. _texture.Release_
  346. _texture = Null
  347. EndIf
  348. End Method
  349. Method Clear(d3ddev:IDirect3DDevice9, r:Int=0, g:Int=0, b:Int=0, a:Float=0.0)
  350. If Not d3ddev Return
  351. Local c:Int = (int(a*255) Shl 24) | (r Shl 16) | (g Shl 8) | b
  352. d3ddev.Clear(0, Null, D3DCLEAR_TARGET, c, 0.0, 0)
  353. End Method
  354. Method CreateRenderTarget:TD3D9RenderImageFrame( d3ddev:IDirect3DDevice9, width:Int,height:Int )
  355. d3ddev.CreateTexture(width,height,1,D3DUSAGE_RENDERTARGET,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,_texture,Null)
  356. If _texture _texture.GetSurfaceLevel 0, _surface
  357. _magfilter = D3DTFG_LINEAR
  358. _minfilter = D3DTFG_LINEAR
  359. _mipfilter = D3DTFG_LINEAR
  360. _uscale = 1.0 / width
  361. _vscale = 1.0 / height
  362. Return Self
  363. End Method
  364. Method DestroyRenderImage()
  365. ReleaseNow()
  366. End Method
  367. rem
  368. 'once a device is lost we cannot simply backup a pixmap, so better
  369. 'do it any time we _could_ loose the device (eg. app suspend)
  370. Method OnDeviceMightGetLost(d3ddev:IDirect3DDevice9, width:Int, height:Int)
  371. print "TD3D9ImageFrame.OnDeviceMightGetLost(): persisting to pixmap"
  372. Persist()
  373. End Method
  374. endrem
  375. Method OnDeviceLost(d3ddev:IDirect3DDevice9, width:Int, height:Int)
  376. 'only read in a new pixmap if none was created before
  377. 'in case of "suspend and resum" this ToPixmap() call will return
  378. 'an empty pixmap (because of "D3DERR_DEVICELOST")
  379. If Not _persistPixmap
  380. _persistPixmap = ToPixmap(d3ddev, width, height)
  381. EndIf
  382. ReleaseNow()
  383. End Method
  384. Method OnDeviceReset(d3ddev:IDirect3DDevice9)
  385. If(_persistpixmap)
  386. d3ddev.CreateTexture(_persistPixmap.width, _persistPixmap.height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, _texture, Null)
  387. If _texture
  388. _texture.GetSurfaceLevel(0, _surface)
  389. EndIf
  390. FromPixmap(d3ddev, _persistPixmap)
  391. EndIf
  392. _persistPixmap = Null
  393. End Method
  394. Method FromPixmap(d3ddev:IDirect3DDevice9, pixmap:TPixmap)
  395. ' use a staging surface to copy the pixmap into
  396. Local stage:IDirect3DSurface9
  397. d3ddev.CreateOffscreenPlainSurface(pixmap.width, pixmap.height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, stage, Null)
  398. Local lockedrect:D3DLOCKED_RECT = New D3DLOCKED_RECT
  399. stage.LockRect(lockedrect, Null, 0)
  400. ' copy the pixel data across
  401. For Local y:Int = 0 Until pixmap.height
  402. Local srcptr:Byte Ptr = pixmap.pixels + y * pixmap.pitch
  403. Local dstptr:Byte Ptr = lockedrect.pBits + y * lockedrect.Pitch
  404. MemCopy dstptr, srcptr, size_t(pixmap.width * 4)
  405. Next
  406. stage.UnlockRect()
  407. ' copy from the staging surface to the render surface
  408. d3ddev.UpdateSurface(stage, Null, _surface, Null)
  409. ' cleanup
  410. stage.release_
  411. End Method
  412. Method ToPixmap:TPixmap(d3ddev:IDirect3DDevice9, width:Int, height:Int)
  413. Local pixmap:TPixmap = CreatePixmap(width, height, PF_RGBA8888)
  414. ' use a staging surface to get the texture contents
  415. Local stage:IDirect3DSurface9
  416. d3ddev.CreateOffscreenPlainSurface(width, height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, stage, Null)
  417. Local result:Int = d3ddev.GetRenderTargetData(_surface, stage)
  418. If result < 0
  419. If result = D3DERR_DRIVERINTERNALERROR
  420. Throw "TD3D9RenderImageFrame:ToPixmap:GetRenderTargetData failed: D3DERR_DRIVERINTERNALERROR"
  421. ElseIf result = D3DERR_DEVICELOST
  422. 'Throw "TD3D9RenderImageFrame:ToPixmap:GetRenderTargetData failed: D3DERR_DEVICELOST"
  423. ElseIf result = D3DERR_INVALIDCALL
  424. Throw "TD3D9RenderImageFrame:ToPixmap:GetRenderTargetData failed: D3DERR_INVALIDCALL"
  425. Else
  426. Throw "TD3D9RenderImageFrame:ToPixmap:GetRenderTargetData failed."
  427. EndIf
  428. EndIf
  429. ' copy the pixel data across
  430. Local lockedrect:D3DLOCKED_RECT = New D3DLOCKED_RECT
  431. If stage.LockRect(lockedrect, Null, 0) < 0 Throw "TD3D9RenderImageFrame:ToPixmap:LockRect failed"
  432. For Local y:Int = 0 Until pixmap.height
  433. For Local x:Int = 0 Until pixmap.width
  434. Local srcptr:Int Ptr = Int Ptr (lockedrect.pBits + x * 4 + y * lockedrect.Pitch)
  435. Local dstptr:Int Ptr = Int Ptr (pixmap.pixels + x * 4 + y * pixmap.pitch)
  436. dstptr[0] = ((srcptr[0] & $ff) Shl 16) | ((srcptr[0] & $ff0000) Shr 16)| (srcptr[0] & $ff00) | (srcptr[0] & $ff000000)
  437. Next
  438. Next
  439. pixmap = ConvertPixmap(pixmap, PF_BGRA)
  440. ' cleanup
  441. stage.UnlockRect()
  442. stage.release_
  443. Return pixmap
  444. End Method
  445. EndType
  446. Type TD3D9RenderImage Extends TRenderImage
  447. Field _d3ddev:IDirect3DDevice9
  448. Field _viewport:D3DVIEWPORT9
  449. Field _matrix:Float[]
  450. Method Delete()
  451. ReleaseNow()
  452. End Method
  453. 'ensure the GPU located render image would survive a "appsuspend"
  454. 'by eg. reading it into a TPixmap
  455. Method Persist:Int() Override
  456. if TD3D9RenderImageFrame(frames[0])
  457. Return TD3D9RenderImageFrame(frames[0]).Persist(_d3ddev, width, height)
  458. EndIf
  459. Return False
  460. End Method
  461. Method ReleaseNow()
  462. If _d3ddev
  463. _d3ddev.release_
  464. _d3ddev = Null
  465. EndIf
  466. End Method
  467. Method CreateRenderImage:TD3D9RenderImage(width:Int ,height:Int)
  468. Self.width=width ' TImage.width
  469. Self.height=height ' TImage.height
  470. _matrix = [ 2.0/width, 0.0, 0.0, 0.0,..
  471. 0.0, -2.0/height, 0.0, 0.0,..
  472. 0.0, 0.0, 1.0, 0.0,..
  473. -1-(1.0/width), 1+(1.0/height), 1.0, 1.0 ]
  474. _viewport = New D3DVIEWPORT9
  475. _viewport.width = width
  476. _viewport.height = height
  477. _viewport.MaxZ = 1.0
  478. Return Self
  479. End Method
  480. Method DestroyRenderImage()
  481. ReleaseNow()
  482. TD3D9RenderImageFrame(frames[0]).ReleaseNow()
  483. End Method
  484. Method Init(d3ddev:IDirect3DDevice9, UseImageFiltering:Int)
  485. _d3ddev = d3ddev
  486. _d3ddev.AddRef()
  487. frames = New TD3D9RenderImageFrame[1]
  488. frames[0] = New TD3D9RenderImageFrame.CreateRenderTarget(_d3ddev, width, height)
  489. If UseImageFiltering
  490. TD3D9RenderImageFrame(frames[0])._magfilter=D3DTFG_LINEAR
  491. TD3D9RenderImageFrame(frames[0])._minfilter=D3DTFG_LINEAR
  492. TD3D9RenderImageFrame(frames[0])._mipfilter=D3DTFG_LINEAR
  493. Else
  494. TD3D9RenderImageFrame(frames[0])._magfilter=D3DTFG_POINT
  495. TD3D9RenderImageFrame(frames[0])._minfilter=D3DTFG_POINT
  496. TD3D9RenderImageFrame(frames[0])._mipfilter=D3DTFG_POINT
  497. EndIf
  498. ' clear the new render target surface
  499. Local prevsurf:IDirect3DSurface9
  500. Local prevmatrix:Float[16]
  501. Local prevviewport:D3DVIEWPORT9 = New D3DVIEWPORT9
  502. ' get previous
  503. _d3ddev.GetRenderTarget(0, prevsurf)
  504. _d3ddev.GetTransform(D3DTS_PROJECTION, prevmatrix)
  505. _d3ddev.GetViewport(prevviewport)
  506. ' set and clear
  507. _d3ddev.SetRenderTarget(0, TD3D9RenderImageFrame(frames[0])._surface)
  508. _d3ddev.SetTransform(D3DTS_PROJECTION, _matrix)
  509. _d3ddev.Clear(0, Null, D3DCLEAR_TARGET, 0, 0.0, 0)
  510. ' reset to previous
  511. _d3ddev.SetRenderTarget(0, prevsurf)
  512. _d3ddev.SetTransform(D3DTS_PROJECTION, prevmatrix)
  513. _d3ddev.SetViewport(prevviewport)
  514. ' cleanup
  515. If prevsurf Then prevsurf.release_
  516. End Method
  517. Method InitFromPixmap(d3ddev:IDirect3DDevice9, Pixmap:TPixmap, UseImageFiltering:Int)
  518. _d3ddev = d3ddev
  519. _d3ddev.AddRef()
  520. Pixmap = ConvertPixmap(pixmap, PF_BGRA)
  521. frames = New TD3D9RenderImageFrame[1]
  522. frames[0] = New TD3D9RenderImageFrame.CreateRenderTarget(d3ddev, width, height)
  523. If UseImageFiltering
  524. TD3D9RenderImageFrame(frames[0])._magfilter=D3DTFG_LINEAR
  525. TD3D9RenderImageFrame(frames[0])._minfilter=D3DTFG_LINEAR
  526. TD3D9RenderImageFrame(frames[0])._mipfilter=D3DTFG_LINEAR
  527. Else
  528. TD3D9RenderImageFrame(frames[0])._magfilter=D3DTFG_POINT
  529. TD3D9RenderImageFrame(frames[0])._minfilter=D3DTFG_POINT
  530. TD3D9RenderImageFrame(frames[0])._mipfilter=D3DTFG_POINT
  531. EndIf
  532. TD3D9RenderImageFrame(frames[0]).FromPixmap(d3ddev, Pixmap)
  533. End Method
  534. Method Clear(r:Int=0, g:Int=0, b:Int=0, a:Float=0.0)
  535. If frames[0] Then TD3D9RenderImageFrame(frames[0]).Clear(_d3ddev, r, g, b, a)
  536. End Method
  537. Method Frame:TImageFrame(index:Int=0)
  538. If Not frames Return Null
  539. If Not frames[0] Return Null
  540. Return frames[0]
  541. End Method
  542. Method SetRenderImage()
  543. Local pTexture:IDirect3DTexture9
  544. _d3ddev.GetTexture(0, pTexture)
  545. Local frame:TD3D9RenderImageFrame = TD3D9RenderImageFrame(frames[0])
  546. If frame._texture <> pTexture
  547. _d3ddev.SetTexture(0, pTexture)
  548. EndIf
  549. If pTexture pTexture.Release_
  550. _d3ddev.SetRenderTarget(0, TD3D9RenderImageFrame(frames[0])._surface)
  551. _d3ddev.SetTransform(D3DTS_PROJECTION,_matrix)
  552. _d3ddev.SetViewport(_viewport)
  553. End Method
  554. Method ToPixmap:TPixmap()
  555. Return TD3D9RenderImageFrame(frames[0]).ToPixmap(_d3ddev, width, height)
  556. End Method
  557. Method SetViewport(x:Int, y:Int, width:Int, height:Int)
  558. If width = 0
  559. width = Self.width
  560. height = Self.height
  561. EndIf
  562. If x + width > Self.width
  563. width:-(x + width - Self.width)
  564. EndIf
  565. If y + height > Self.height
  566. height:-(y + height - Self.height)
  567. EndIf
  568. If x = 0 And y = 0 And width = Self.width And height = Self.height
  569. _d3ddev.SetRenderState(D3DRS_SCISSORTESTENABLE, False)
  570. Else
  571. _d3ddev.SetRenderState(D3DRS_SCISSORTESTENABLE, True)
  572. Local rect:Int[] = [x , y, x + width, y + height]
  573. _d3ddev.SetScissorRect(rect)
  574. EndIf
  575. End Method
  576. ' Method OnDeviceMightGetLost()
  577. ' TD3D9RenderImageFrame(frames[0]).OnDeviceMightGetLost(_d3ddev, width, height)
  578. ' End Method
  579. Method OnDeviceLost()
  580. 'invalidate (even with existing persistPixmap!)
  581. _valid = False
  582. TD3D9RenderImageFrame(frames[0]).OnDeviceLost(_d3ddev, width, height)
  583. End Method
  584. Method OnDeviceReset()
  585. TD3D9RenderImageFrame(frames[0]).OnDeviceReset(_d3ddev)
  586. End Method
  587. EndType
  588. Type TD3D9Max2DDriver Extends TMax2dDriver
  589. Method ToString:String() Override
  590. Return "DirectX9"
  591. End Method
  592. Method Create:TD3D9Max2DDriver()
  593. If Not D3D9GraphicsDriver() Return Null
  594. Local d3d:IDirect3D9 = D3D9GraphicsDriver().GetDirect3D()
  595. If d3d.CheckDeviceFormat( D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,D3DFMT_X8R8G8B8,0,D3DRTYPE_TEXTURE,D3DFMT_A8R8G8B8 )<0
  596. Return Null
  597. EndIf
  598. Return Self
  599. End Method
  600. '***** TGraphicsDriver *****
  601. Method GraphicsModes:TGraphicsMode[]() Override
  602. Return D3D9GraphicsDriver().GraphicsModes()
  603. End Method
  604. Method AttachGraphics:TGraphics( widget:Byte Ptr,flags:Long ) Override
  605. Local g:TD3D9Graphics=D3D9GraphicsDriver().AttachGraphics( widget,flags )
  606. If g Return TMax2DGraphics.Create( g,Self )
  607. End Method
  608. Method CreateGraphics:TGraphics( width:Int,height:Int,depth:Int,hertz:Int,flags:Long,x:Int,y:Int ) Override
  609. Local g:TD3D9Graphics=D3D9GraphicsDriver().CreateGraphics( width,height,depth,hertz,flags,x,y )
  610. If Not g Return Null
  611. Return TMax2DGraphics.Create( g,Self )
  612. End Method
  613. Method SetGraphics( g:TGraphics ) Override
  614. If Not g
  615. If _d3dDev
  616. _d3dDev.EndScene
  617. _d3dDev=Null
  618. EndIf
  619. _d3d9graphics=Null
  620. _max2dGraphics=Null
  621. TMax2DGraphics.ClearCurrent
  622. D3D9GraphicsDriver().SetGraphics Null
  623. Return
  624. EndIf
  625. _max2dGraphics=TMax2dGraphics( g )
  626. _d3d9graphics=TD3D9Graphics( _max2dGraphics._graphics )
  627. If Not _max2dGraphics Or Not _d3d9graphics Then
  628. Throw "SetGraphics failed for D3D9"
  629. End If
  630. _d3dDev=_d3d9Graphics.GetDirect3DDevice()
  631. D3D9GraphicsDriver().SetGraphics _d3d9Graphics
  632. If _d3dDev.TestCooperativeLevel()<>D3D_OK Return
  633. ResetDevice
  634. _max2dGraphics.MakeCurrent
  635. End Method
  636. Method Flip:Int( sync:Int ) Override
  637. _d3dDev.EndScene
  638. If D3D9GraphicsDriver().Flip( sync )
  639. _d3dDev.BeginScene
  640. Else If _d3dDev.TestCooperativeLevel()=D3D_OK
  641. ResetDevice
  642. _max2dGraphics.MakeCurrent
  643. EndIf
  644. End Method
  645. Method ResetDevice()
  646. _d3d9graphics.ValidateSize
  647. _d3d9graphics.GetSettings _gw,_gh,_gd,_gr,_gf,_gx,_gy
  648. Local viewport:D3DVIEWPORT9
  649. viewport.X = 0
  650. viewport.Y = 0
  651. viewport.Width = _gw
  652. viewport.Height = _gh
  653. viewport.MinZ = 0.0
  654. viewport.MaxZ = 1.0
  655. _d3dDev.SetViewport(viewport)
  656. _d3dDev.SetRenderState D3DRS_ALPHAREF,$80
  657. _d3dDev.SetRenderState D3DRS_ALPHAFUNC,D3DCMP_GREATEREQUAL
  658. _d3dDev.SetRenderState D3DRS_ALPHATESTENABLE,False
  659. _d3dDev.SetRenderState D3DRS_ALPHABLENDENABLE,False
  660. _active_blend=SOLIDBLEND
  661. _d3dDev.SetRenderState D3DRS_LIGHTING,False
  662. _d3dDev.SetRenderState D3DRS_CULLMODE,D3DCULL_NONE
  663. _d3dDev.SetTexture 0,Null
  664. _bound_texture=Null
  665. _d3dDev.SetFVF D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1
  666. _d3dDev.SetTextureStageState 0,D3DTSS_COLORARG1,D3DTA_TEXTURE
  667. _d3dDev.SetTextureStageState 0,D3DTSS_COLORARG2,D3DTA_DIFFUSE
  668. _d3dDev.SetTextureStageState 0,D3DTSS_COLOROP,D3DTOP_SELECTARG2
  669. _d3dDev.SetTextureStageState 0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE
  670. _d3dDev.SetTextureStageState 0,D3DTSS_ALPHAARG2,D3DTA_DIFFUSE
  671. _d3dDev.SetTextureStageState 0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG2
  672. _texture_enabled=False
  673. _d3dDev.SetTextureStageState 0,D3DTSS_ADDRESS,D3DTADDRESS_CLAMP
  674. _d3dDev.SetTextureStageState 0,D3DTSS_MAGFILTER,D3DTFG_POINT
  675. _d3dDev.SetTextureStageState 0,D3DTSS_MINFILTER,D3DTFN_POINT
  676. _d3dDev.SetTextureStageState 0,D3DTSS_MIPFILTER,D3DTFP_POINT
  677. _d3dDev.BeginScene
  678. End Method
  679. '***** TMax2DDriver *****
  680. Method CreateRenderImageContext:Object(g:TGraphics) Override
  681. Return New TD3D9RenderImageContext.Create(g, Self)
  682. End Method
  683. Method CreateFrameFromPixmap:TImageFrame( pixmap:TPixmap,flags:Int ) Override
  684. Return New TD3D9ImageFrame.Create( pixmap,flags )
  685. End Method
  686. Method SetBlend( blend:Int ) Override
  687. If blend=_active_blend Return
  688. Select blend
  689. Case SOLIDBLEND
  690. _d3dDev.SetRenderState D3DRS_ALPHATESTENABLE,False
  691. _d3dDev.SetRenderState D3DRS_ALPHABLENDENABLE,False
  692. Case MASKBLEND
  693. _d3dDev.SetRenderState D3DRS_ALPHATESTENABLE,True
  694. _d3dDev.SetRenderState D3DRS_ALPHABLENDENABLE,False
  695. Case ALPHABLEND
  696. _d3dDev.SetRenderState D3DRS_ALPHATESTENABLE,False
  697. _d3dDev.SetRenderState D3DRS_ALPHABLENDENABLE,True
  698. _d3dDev.SetRenderState D3DRS_SRCBLEND,D3DBLEND_SRCALPHA
  699. _d3dDev.SetRenderState D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA
  700. Case LIGHTBLEND
  701. _d3dDev.SetRenderState D3DRS_ALPHATESTENABLE,False
  702. _d3dDev.SetRenderState D3DRS_ALPHABLENDENABLE,True
  703. _d3dDev.SetRenderState D3DRS_SRCBLEND,D3DBLEND_SRCALPHA
  704. _d3dDev.SetRenderState D3DRS_DESTBLEND,D3DBLEND_ONE
  705. Case SHADEBLEND
  706. _d3dDev.SetRenderState D3DRS_ALPHATESTENABLE,False
  707. _d3dDev.SetRenderState D3DRS_ALPHABLENDENABLE,True
  708. _d3dDev.SetRenderState D3DRS_SRCBLEND,D3DBLEND_ZERO
  709. _d3dDev.SetRenderState D3DRS_DESTBLEND,D3DBLEND_SRCCOLOR
  710. End Select
  711. _active_blend=blend
  712. End Method
  713. Method SetAlpha( alpha:Float ) Override
  714. alpha=Max(Min(alpha,1),0)
  715. _color=(Int(255*alpha) Shl 24)|(_color&$ffffff)
  716. _iverts[3]=_color
  717. _iverts[9]=_color
  718. _iverts[15]=_color
  719. _iverts[21]=_color
  720. End Method
  721. Method SetColor( red:Int,green:Int,blue:Int ) Override
  722. red=Max(Min(red,255),0)
  723. green=Max(Min(green,255),0)
  724. blue=Max(Min(blue,255),0)
  725. _color=(_color&$ff000000)|(red Shl 16)|(green Shl 8)|blue
  726. _iverts[3]=_color
  727. _iverts[9]=_color
  728. _iverts[15]=_color
  729. _iverts[21]=_color
  730. End Method
  731. Method SetColor( color:SColor8 ) Override
  732. _color=(_color&$ff000000)|color.ToARGB()
  733. _iverts[3]=_color
  734. _iverts[9]=_color
  735. _iverts[15]=_color
  736. _iverts[21]=_color
  737. End Method
  738. Method SetClsColor( red:Int,green:Int,blue:Int ) Override
  739. red=Max(Min(red,255),0)
  740. green=Max(Min(green,255),0)
  741. blue=Max(Min(blue,255),0)
  742. _clscolor=$ff000000|(red Shl 16)|(green Shl 8)|blue
  743. End Method
  744. Method SetClsColor( color:SColor8 ) Override
  745. _clscolor=$ff000000|color.ToARGB()
  746. End Method
  747. Method SetViewport( x:Int,y:Int,width:Int,height:Int ) Override
  748. If x=0 And y=0 And width=_gw And height=_gh 'GraphicsWidth() And height=GraphicsHeight()
  749. _d3dDev.SetRenderState D3DRS_SCISSORTESTENABLE,False
  750. Else
  751. _d3dDev.SetRenderState D3DRS_SCISSORTESTENABLE,True
  752. Local rect:Int[]=[x,y,x+width,y+height]
  753. _d3dDev.SetScissorRect rect
  754. EndIf
  755. End Method
  756. Method SetTransform( xx:Float,xy:Float,yx:Float,yy:Float ) Override
  757. _ix=xx
  758. _iy=xy
  759. _jx=yx
  760. _jy=yy
  761. End Method
  762. Method SetLineWidth( width:Float ) Override
  763. _lineWidth=width
  764. End Method
  765. Method Cls() Override
  766. _d3dDev.Clear 0,Null,D3DCLEAR_TARGET,_clscolor,0,0
  767. End Method
  768. Method Plot( x:Float,y:Float ) Override
  769. _fverts[0]=x+.5
  770. _fverts[1]=y+.5
  771. DisableTex
  772. _d3dDev.DrawPrimitiveUP D3DPT_POINTLIST,1,_fverts,24
  773. End Method
  774. Method DrawLine( x0:Float,y0:Float,x1:Float,y1:Float,tx:Float,ty:Float ) Override
  775. Local lx0:Float = x0*_ix + y0*_iy + tx
  776. Local ly0:Float = x0*_jx + y0*_jy + ty
  777. Local lx1:Float = x1*_ix + y1*_iy + tx
  778. Local ly1:Float = x1*_jx + y1*_jy + ty
  779. If _lineWidth<=1
  780. _fverts[0]=lx0+.5
  781. _fverts[1]=ly0+.5
  782. _fverts[6]=lx1+.5
  783. _fverts[7]=ly1+.5
  784. DisableTex
  785. _d3dDev.DrawPrimitiveUP D3DPT_LINELIST,1,_fverts,24
  786. Return
  787. EndIf
  788. Local lw:Float=_lineWidth*.5
  789. If Abs(ly1-ly0)>Abs(lx1-lx0)
  790. _fverts[0]=lx0-lw
  791. _fverts[1]=ly0
  792. _fverts[6]=lx0+lw
  793. _fverts[7]=ly0
  794. _fverts[12]=lx1-lw
  795. _fverts[13]=ly1
  796. _fverts[18]=lx1+lw
  797. _fverts[19]=ly1
  798. Else
  799. _fverts[0]=lx0
  800. _fverts[1]=ly0-lw
  801. _fverts[6]=lx0
  802. _fverts[7]=ly0+lw
  803. _fverts[12]=lx1
  804. _fverts[13]=ly1-lw
  805. _fverts[18]=lx1
  806. _fverts[19]=ly1+lw
  807. EndIf
  808. DisableTex
  809. _d3dDev.DrawPrimitiveUP D3DPT_TRIANGLESTRIP,2,_fverts,24
  810. End Method
  811. Method DrawRect( x0:Float,y0:Float,x1:Float,y1:Float,tx:Float,ty:Float ) Override
  812. _fverts[0] = x0*_ix + y0*_iy + tx
  813. _fverts[1] = x0*_jx + y0*_jy + ty
  814. _fverts[6] = x1*_ix + y0*_iy + tx
  815. _fverts[7] = x1*_jx + y0*_jy + ty
  816. _fverts[12] = x0*_ix + y1*_iy + tx
  817. _fverts[13] = x0*_jx + y1*_jy + ty
  818. _fverts[18] = x1*_ix + y1*_iy + tx
  819. _fverts[19] = x1*_jx + y1*_jy + ty
  820. DisableTex
  821. _d3dDev.DrawPrimitiveUP D3DPT_TRIANGLESTRIP,2,_fverts,24
  822. End Method
  823. Method DrawOval( x0:Float,y0:Float,x1:Float,y1:Float,tx:Float,ty:Float ) Override
  824. Local xr:Float=(x1-x0)*.5
  825. Local yr:Float=(y1-y0)*.5
  826. Local segs:Int=Abs(xr)+Abs(yr)
  827. segs=Max(segs,12)&~3
  828. x0:+xr
  829. y0:+yr
  830. Local fverts:Float[segs*6]
  831. Local iverts:Int Ptr=Int Ptr( Varptr fverts[0] )
  832. For Local i:Int=0 Until segs
  833. Local th:Float=-i*360:Float/segs
  834. Local x:Float=x0+Cos(th)*xr
  835. Local y:Float=y0-Sin(th)*yr
  836. fverts[i*6+0]=x*_ix+y*_iy+tx
  837. fverts[i*6+1]=x*_jx+y*_jy+ty
  838. iverts[i*6+3]=_color
  839. Next
  840. DisableTex
  841. _d3dDev.DrawPrimitiveUP D3DPT_TRIANGLEFAN,segs-2,fverts,24
  842. End Method
  843. Method DrawPoly( verts:Float[],handlex:Float,handley:Float,tx:Float,ty:Float, indices:Int[] ) Override
  844. If verts.length<6 Or (verts.length&1) Return
  845. Local segs:Int=verts.length/2
  846. Local fverts:Float[segs*6]
  847. Local iverts:Int Ptr=Int Ptr( Varptr fverts[0] )
  848. For Local i:Int=0 Until segs
  849. Local x:Float=verts[i*2+0]+handlex
  850. Local y:Float=verts[i*2+1]+handley
  851. fverts[i*6+0]= x*_ix + y*_iy + tx
  852. fverts[i*6+1]= x*_jx + y*_jy + ty
  853. iverts[i*6+3]=_color
  854. Next
  855. DisableTex
  856. _d3dDev.DrawPrimitiveUP D3DPT_TRIANGLEFAN,segs-2,fverts,24
  857. End Method
  858. 'GetDC/BitBlt MUCH faster than locking backbuffer!
  859. Method DrawPixmap( pixmap:TPixmap,x:Int,y:Int ) Override
  860. Local width:Int=pixmap.width,height:Int=pixmap.height
  861. Local dstsurf:IDirect3DSurface9' = New IDirect3DSurface9
  862. If _d3dDev.GetRenderTarget( 0,dstsurf )<0
  863. d3derr "GetRenderTarget failed~n"
  864. Return
  865. EndIf
  866. Local desc:D3DSURFACE_DESC
  867. If dstsurf.GetDesc( desc )<0
  868. d3derr "GetDesc failed~n"
  869. EndIf
  870. Local rect:Int[]=[x,y,x+width,y+height]
  871. Local lockedrect:D3DLOCKED_RECT=New D3DLOCKED_RECT
  872. If dstsurf.LockRect( lockedrect,rect,0 )<0
  873. d3derr "Unable to lock render target surface~n"
  874. dstsurf.Release_
  875. Return
  876. EndIf
  877. Local dstpixmap:TPixmap=CreateStaticPixmap( lockedrect.pBits,width,height,lockedrect.Pitch,PF_BGRA8888 );
  878. dstpixmap.Paste pixmap,0,0
  879. dstsurf.UnlockRect
  880. dstsurf.Release_
  881. End Method
  882. 'GetDC/BitBlt MUCH faster than locking backbuffer!
  883. Method GrabPixmap:TPixmap( x:Int,y:Int,width:Int,height:Int ) Override
  884. Local srcsurf:IDirect3DSurface9
  885. If _d3dDev.GetRenderTarget( 0,srcsurf )<0
  886. d3derr "GetRenderTarget failed~n"
  887. EndIf
  888. Local dstsurf:IDirect3DSurface9
  889. If _d3dDev.CreateOffscreenPlainSurface( width,height,D3DFMT_X8R8G8B8,D3DPOOL_SYSTEMMEM,dstsurf,Null )<0
  890. d3derr "CreateOffscreenPlainSurface failed~n"
  891. EndIf
  892. Local srcdc:Byte Ptr
  893. If srcsurf.GetDC( srcdc )<0
  894. d3derr "srcsurf.GetDC failed~n"
  895. EndIf
  896. Local dstdc:Byte Ptr
  897. If dstsurf.GetDC( dstdc )<0
  898. d3derr "dstsurf.GetDC failed~n"
  899. EndIf
  900. BitBlt dstdc,0,0,width,height,srcdc,x,y,ROP_SRCCOPY
  901. srcsurf.ReleaseDC srcdc
  902. dstsurf.ReleaseDC dstdc
  903. Local lockedrect:D3DLOCKED_RECT=New D3DLOCKED_RECT
  904. If dstsurf.LockRect( lockedrect,Null,D3DLOCK_READONLY )<0
  905. d3derr "dstsurf.LockRect failed~n"
  906. EndIf
  907. Local pixmap:TPixmap=CreatePixmap( width,height,PF_BGRA8888 )
  908. 'Copy and set alpha in the process...
  909. For Local y:Int=0 Until height
  910. Local src:Int Ptr=Int Ptr( lockedrect.pBits+y*lockedrect.Pitch )
  911. Local dst:Int Ptr=Int Ptr( pixmap.PixelPtr( 0,y ) )
  912. For Local x:Int=0 Until width
  913. dst[x]=src[x] | $ff000000
  914. Next
  915. Next
  916. srcsurf.Release_
  917. dstsurf.Release_
  918. Return pixmap
  919. End Method
  920. Method SetResolution( width:Float,height:Float ) Override
  921. Local matrix:Float[]=[..
  922. 2.0/width,0.0,0.0,0.0,..
  923. 0.0,-2.0/height,0.0,0.0,..
  924. 0.0,0.0,1.0,0.0,..
  925. -1-(1.0/width),1+(1.0/height),1.0,1.0]
  926. _d3dDev.SetTransform D3DTS_PROJECTION,matrix
  927. End Method
  928. End Type
  929. Rem
  930. bbdoc: Get Direct3D9 Max2D Driver
  931. about:
  932. The returned driver can be used with #SetGraphicsDriver to enable Direct3D9 Max2D rendering.
  933. End Rem
  934. Function D3D9Max2DDriver:TD3D9Max2DDriver()
  935. Global _done:Int
  936. If Not _done
  937. _driver=New TD3D9Max2DDriver.Create()
  938. _done=True
  939. EndIf
  940. Return _driver
  941. End Function
  942. Local driver:TD3D9Max2DDriver=D3D9Max2DDriver()
  943. If driver SetGraphicsDriver driver
  944. ?