d3d7max2d.bmx 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806
  1. Strict
  2. Rem
  3. bbdoc: Graphics/Direct3D7 Max2D
  4. about:
  5. The Direct3D7 Max2D module provides a Direct3D7 driver for #Max2D.
  6. End Rem
  7. Module BRL.D3D7Max2D
  8. ModuleInfo "Version: 1.19"
  9. ModuleInfo "Author: Simon Armstrong"
  10. ModuleInfo "License: zlib/libpng"
  11. ModuleInfo "Copyright: Blitz Research Ltd"
  12. ModuleInfo "Modserver: BRL"
  13. ModuleInfo "History: 1.19 Release"
  14. ModuleInfo "History: Fixed/cleaned up a few things"
  15. ModuleInfo "History: 1.18 Release"
  16. ModuleInfo "History: Updated to work with d3d7graphics rewrite"
  17. ModuleInfo "History: Removed buffered driver"
  18. ModuleInfo "History: 1.17 Release"
  19. ModuleInfo "History: Modified TD3D7Max2DDriver.SetGraphics for new dxgraphics commands"
  20. ModuleInfo "History: 1.16 Release"
  21. ModuleInfo "History: Fixed BufferedD3D7 vertex color errors"
  22. ModuleInfo "History: 1.15 Release"
  23. ModuleInfo "History: Changed DrawImage tristrip to trifan to fix subpixel cracking"
  24. ModuleInfo "History: 1.14 Release"
  25. ModuleInfo "History: Fixed MIPMAPPEDIMAGE flag effect on FILTEREDIMAGE setting"
  26. ModuleInfo "History: 1.14 Release"
  27. ModuleInfo "History: Fixed lost device from fullscreen tabbing"
  28. ModuleInfo "History: 1.13 Release"
  29. ModuleInfo "History: Fixed memory leak in TD3d7ImageFrame"
  30. ModuleInfo "History: 1.12 Release"
  31. ModuleInfo "History: Fixed default mipmap filtering for imageframes"
  32. ModuleInfo "History: 1.11 Release"
  33. ModuleInfo "History: Added flush to BufferedD3D7Max2DDriver for SetBlend and SetViewPort and Draw/GrabPixmap"
  34. ModuleInfo "History: 1.10 Release"
  35. ModuleInfo "History: Added new BufferedD3D7Max2DDriver for optimization testing"
  36. ModuleInfo "History: 1.09 Release"
  37. ModuleInfo "History: Replaced texture factor with vertex colors to improve compatability"
  38. ModuleInfo "History: 1.08 Release"
  39. ModuleInfo "History: Added GL fallback for DX device failure"
  40. ModuleInfo "History: 1.07 Release"
  41. ModuleInfo "History: Added line width support and tweaked line positioning"
  42. ModuleInfo "History: 1.06 Release"
  43. ModuleInfo "History: Added MIPMAPPEDIMAGE support"
  44. ModuleInfo "History: 1.05 Release"
  45. ModuleInfo "History: Added a bunch of redundant state change checks"
  46. ModuleInfo "History: 1.04 Release"
  47. ModuleInfo "History: Now default driver for Win32"
  48. ModuleInfo "History: 1.03 Release"
  49. ModuleInfo "History: Fixed negative scales"
  50. ModuleInfo "History: 1.02 Release"
  51. ModuleInfo "History: Fixed LIGHTBLEND"
  52. ModuleInfo "History: Clamped alpha/color/clsColor"
  53. ModuleInfo "History: Fixed viewport (now uses clip planes)"
  54. ModuleInfo "History: Fixed Mag filter"
  55. ?Win32
  56. Import BRL.DXGraphics
  57. Import BRL.GLMax2D
  58. Type TD3D7Max2DDriver Extends TMax2DDriver
  59. Field device:IDirect3DDevice7
  60. Field d3d7graphics:TD3D7Graphics
  61. Field drawalpha '0..255
  62. Field drawcolor
  63. Field clscolor
  64. Field ix#,iy#,jx#,jy#
  65. Field linewidth#
  66. Field cverts#[16]
  67. Field vrts:Int Ptr'=Int Ptr(Varptr cverts[0])
  68. Field vp_rect[]
  69. Field activeBlend
  70. Field activeFrame:TD3D7ImageFrame
  71. Field activeFrameFlags
  72. Method New()
  73. vrts=Int Ptr(Varptr cverts[0])
  74. End Method
  75. Method ToString$()
  76. Return "DirectX7"
  77. End Method
  78. Method IsValid()
  79. Return TD3D7graphicsDriver.IsValid
  80. End Method
  81. Method GraphicsModes:TGraphicsMode[]()
  82. Return D3D7GraphicsDriver().GraphicsModes()
  83. End Method
  84. Method AttachGraphics:TMax2DGraphics( widget,flags )
  85. Local g:TD3D7Graphics=D3D7GraphicsDriver().AttachGraphics( widget,flags )
  86. If g Return TMax2DGraphics.Create( g,Self )
  87. End Method
  88. Method CreateGraphics:TMax2DGraphics( width,height,depth,hertz,flags )
  89. Local g:TD3D7Graphics=D3D7GraphicsDriver().CreateGraphics( width,height,depth,hertz,flags )
  90. If g Return TMax2DGraphics.Create( g,Self )
  91. End Method
  92. Method SetGraphics( g:TGraphics )
  93. If Not g
  94. TMax2DGraphics.ClearCurrent
  95. D3D7GraphicsDriver().EndScene
  96. D3D7GraphicsDriver().SetGraphics Null
  97. Return
  98. EndIf
  99. Local t:TMax2DGraphics=TMax2DGraphics( g )
  100. Assert t And TD3D7Graphics( t._graphics )
  101. D3D7GraphicsDriver().SetGraphics t._graphics
  102. ResetD3DDevice t
  103. t.MakeCurrent
  104. D3D7GraphicsDriver().BeginScene
  105. End Method
  106. Method ResetD3DDevice( g:TGraphics )
  107. If Not IsValid() Return
  108. Local gw,gh,gd,gr,gf
  109. g.GetSettings gw,gh,gd,gr,gf
  110. device=D3D7GraphicsDriver().Direct3DDevice7()
  111. Local viewport:D3DVIEWPORT7=New D3DVIEWPORT7
  112. viewport.dwX=0
  113. viewport.dwY=0
  114. viewport.dwWidth=gw
  115. viewport.dwHeight=gh
  116. viewport.dvMinZ=0.0
  117. viewport.dvMaxZ=1.0
  118. device.SetViewport(viewport)
  119. device.SetTexture 0,Null
  120. device.SetRenderState D3DRS_ALPHAREF,$80
  121. device.SetRenderState D3DRS_ALPHAFUNC,D3DCMP_GREATEREQUAL
  122. device.SetRenderState D3DRS_ALPHATESTENABLE,False
  123. device.SetRenderState D3DRS_ALPHABLENDENABLE,False
  124. device.SetRenderState D3DRS_LIGHTING,False
  125. device.SetRenderState D3DRS_CULLMODE,D3DCULL_NONE
  126. device.SetTextureStageState 0,D3DTSS_COLOROP,D3DTOP_SELECTARG2
  127. device.SetTextureStageState 0,D3DTSS_COLORARG1,D3DTA_TEXTURE
  128. device.SetTextureStageState 0,D3DTSS_COLORARG2,D3DTA_DIFFUSE
  129. device.SetTextureStageState 0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG2
  130. device.SetTextureStageState 0,D3DTSS_ALPHAARG1,D3DTA_TEXTURE
  131. device.SetTextureStageState 0,D3DTSS_ALPHAARG2,D3DTA_DIFFUSE
  132. device.SetTextureStageState 0,D3DTSS_ADDRESS,D3DTADDRESS_CLAMP
  133. device.SetTextureStageState 0,D3DTSS_MAGFILTER,D3DTFG_POINT
  134. device.SetTextureStageState 0,D3DTSS_MINFILTER,D3DTFN_POINT
  135. device.SetTextureStageState 0,D3DTSS_MIPFILTER,D3DTFP_POINT
  136. activeFrame=Null
  137. activeFrameFlags=0
  138. activeBlend=SOLIDBLEND
  139. End Method
  140. Method Flip( sync )
  141. Local seq=GraphicsSeq
  142. Local wasValid=IsValid()
  143. D3D7GraphicsDriver().Flip sync
  144. If Not IsValid() Return
  145. If wasValid And seq=GraphicsSeq Return
  146. ResetD3DDevice TMax2DGraphics.Current()
  147. TMax2DGraphics.Current().Validate
  148. End Method
  149. Method CreateFrameWithSize:TImageFrame( width,height,flags )
  150. If Not IsValid() Return
  151. Local frame:TD3D7ImageFrame=TD3D7ImageFrame.Create(Self,width,height,flags)
  152. Return frame
  153. End Method
  154. Method CreateFrameFromPixmap:TImageFrame( pixmap:TPixmap,flags )
  155. If Not IsValid() Return
  156. Local frame:TD3D7ImageFrame=TD3D7ImageFrame.Create(Self,pixmap.Width,pixmap.Height,flags)
  157. Local locked:TPixmap=frame.Lock( False,True )
  158. locked.Paste pixmap,0,0
  159. frame.Unlock()
  160. Return frame
  161. End Method
  162. Method SetBlend( blend )
  163. If blend=activeBlend Return
  164. activeBlend=blend
  165. If Not IsValid() Return
  166. Select activeBlend
  167. Case SOLIDBLEND
  168. device.SetRenderState D3DRS_ALPHATESTENABLE,False
  169. device.SetRenderState D3DRS_ALPHABLENDENABLE,False
  170. Case MASKBLEND
  171. device.SetRenderState D3DRS_ALPHATESTENABLE,True
  172. device.SetRenderState D3DRS_ALPHABLENDENABLE,False
  173. Case ALPHABLEND
  174. device.SetRenderState D3DRS_ALPHATESTENABLE,False
  175. device.SetRenderState D3DRS_ALPHABLENDENABLE,True
  176. device.SetRenderState D3DRS_SRCBLEND,D3DBLEND_SRCALPHA
  177. device.SetRenderState D3DRS_DESTBLEND,D3DBLEND_INVSRCALPHA
  178. Case LIGHTBLEND
  179. device.SetRenderState D3DRS_ALPHATESTENABLE,False
  180. device.SetRenderState D3DRS_ALPHABLENDENABLE,True
  181. device.SetRenderState D3DRS_SRCBLEND,D3DBLEND_SRCALPHA
  182. device.SetRenderState D3DRS_DESTBLEND,D3DBLEND_ONE
  183. Case SHADEBLEND
  184. device.SetRenderState D3DRS_ALPHATESTENABLE,False
  185. device.SetRenderState D3DRS_ALPHABLENDENABLE,True
  186. device.SetRenderState D3DRS_SRCBLEND,D3DBLEND_ZERO
  187. device.SetRenderState D3DRS_DESTBLEND,D3DBLEND_SRCCOLOR
  188. End Select
  189. End Method
  190. Method SetAlpha( alpha# )
  191. alpha=Max(Min(alpha,1),0)
  192. drawcolor=(Int(255*alpha) Shl 24)|(drawcolor&$ffffff)
  193. vrts[3]=drawcolor
  194. vrts[7]=drawcolor
  195. vrts[11]=drawcolor
  196. vrts[15]=drawcolor
  197. End Method
  198. Method SetColor( red,green,blue )
  199. red=Max(Min(red,255),0)
  200. green=Max(Min(green,255),0)
  201. blue=Max(Min(blue,255),0)
  202. drawcolor=(drawcolor&$ff000000)|(red Shl 16)|(green Shl 8)|blue
  203. vrts[3]=drawcolor
  204. vrts[7]=drawcolor
  205. vrts[11]=drawcolor
  206. vrts[15]=drawcolor
  207. End Method
  208. Method SetClsColor( red,green,blue )
  209. red=Max(Min(red,255),0)
  210. green=Max(Min(green,255),0)
  211. blue=Max(Min(blue,255),0)
  212. clscolor=$ff000000|(red Shl 16)|(green Shl 8)|blue
  213. End Method
  214. Method SetViewport( x,y,width,height )
  215. vp_rect=[x,y,x+width,y+height]
  216. If Not IsValid() Return
  217. If x=0 And y=0 And width=GraphicsWidth() And height=GraphicsHeight()
  218. device.SetRenderState D3DRS_CLIPPLANEENABLE,0
  219. Else
  220. Local err
  221. If device.SetClipPlane(0,[1.0,0.0,0.0,-Float(x)]) err=True
  222. If device.SetClipPlane(1,[-1.0,0.0,0.0,Float(x+width)]) err=True
  223. If device.SetClipPlane(2,[0.0,1.0,0.0,-Float(y)]) err=True
  224. If device.SetClipPlane(3,[0.0,-1.0,0.0,Float(y+height)]) err=True
  225. If err Throw "device does not support clipplanes"
  226. device.SetRenderState D3DRS_CLIPPLANEENABLE,15
  227. EndIf
  228. End Method
  229. Method SetTransform( xx#,xy#,yx#,yy# )
  230. ix=xx
  231. iy=xy
  232. jx=yx
  233. jy=yy
  234. End Method
  235. Method SetLineWidth( width# )
  236. linewidth=width
  237. End Method
  238. Method Cls()
  239. If Not IsValid() Return
  240. device.Clear 1,vp_rect,D3DCLEAR_TARGET,clscolor,0,0
  241. End Method
  242. Method Plot( x#,y# )
  243. If Not IsValid() Return
  244. cverts[0]=x+.5001
  245. cverts[1]=y+.5001
  246. SetActiveFrame Null
  247. device.DrawPrimitive(D3DPT_POINTLIST,D3DFVF_XYZ|D3DFVF_DIFFUSE,cverts,1,0)
  248. End Method
  249. Method DrawLine( x0#,y0#,x1#,y1#,tx#,ty# )
  250. If Not IsValid() Return
  251. Local lx0#,ly0#,lx1#,ly1#
  252. lx0=x0*ix+y0*iy+tx
  253. ly0=x0*jx+y0*jy+ty
  254. lx1=x1*ix+y1*iy+tx
  255. ly1=x1*jx+y1*jy+ty
  256. If linewidth<=1
  257. cverts[0]=lx0+.5001
  258. cverts[1]=ly0+.5001
  259. cverts[4]=lx1+.5001
  260. cverts[5]=ly1+.5001
  261. SetActiveFrame Null
  262. device.DrawPrimitive(D3DPT_LINELIST,D3DFVF_XYZ|D3DFVF_DIFFUSE,cverts,2,0)
  263. Else
  264. Local lw#=linewidth*0.5
  265. If Abs(ly1-ly0)>Abs(lx1-lx0)
  266. cverts[0]=lx0-lw
  267. cverts[1]=ly0
  268. cverts[4]=lx0+lw
  269. cverts[5]=ly0
  270. cverts[8]=lx1-lw
  271. cverts[9]=ly1
  272. cverts[12]=lx1+lw
  273. cverts[13]=ly1
  274. Else
  275. cverts[0]=lx0
  276. cverts[1]=ly0-lw
  277. cverts[4]=lx0
  278. cverts[5]=ly0+lw
  279. cverts[8]=lx1
  280. cverts[9]=ly1-lw
  281. cverts[12]=lx1
  282. cverts[13]=ly1+lw
  283. EndIf
  284. SetActiveFrame Null
  285. device.DrawPrimitive(D3DPT_TRIANGLESTRIP,D3DFVF_XYZ|D3DFVF_DIFFUSE,cverts,4,0)
  286. EndIf
  287. End Method
  288. Method DrawRect( x0#,y0#,x1#,y1#,tx#,ty# )
  289. If Not IsValid() Return
  290. cverts[0]=x0*ix+y0*iy+tx
  291. cverts[1]=x0*jx+y0*jy+ty
  292. cverts[4]=x1*ix+y0*iy+tx
  293. cverts[5]=x1*jx+y0*jy+ty
  294. cverts[8]=x0*ix+y1*iy+tx
  295. cverts[9]=x0*jx+y1*jy+ty
  296. cverts[12]=x1*ix+y1*iy+tx
  297. cverts[13]=x1*jx+y1*jy+ty
  298. SetActiveFrame Null
  299. device.DrawPrimitive(D3DPT_TRIANGLESTRIP,D3DFVF_XYZ|D3DFVF_DIFFUSE,cverts,4,0)
  300. End Method
  301. Method DrawOval( x0#,y0#,x1#,y1#,tx#,ty# )
  302. If Not IsValid() Return
  303. Local xr#=(x1-x0)*.5
  304. Local yr#=(y1-y0)*.5
  305. Local segs=Abs(xr)+Abs(yr)
  306. segs=Max(segs,12)&~3
  307. x0:+xr
  308. y0:+yr
  309. Local vrts#[]=New Float[segs*4]
  310. Local c:Int Ptr=Int Ptr(Float Ptr(vrts))
  311. For Local i=0 Until segs
  312. Local th#=-i*360#/segs
  313. Local x#=x0+Cos(th)*xr
  314. Local y#=y0-Sin(th)*yr
  315. vrts[i*4+0]=x*ix+y*iy+tx
  316. vrts[i*4+1]=x*jx+y*jy+ty
  317. c[i*4+3]=drawcolor
  318. Next
  319. SetActiveFrame Null
  320. device.DrawPrimitive(D3DPT_TRIANGLEFAN,D3DFVF_XYZ|D3DFVF_DIFFUSE,vrts,segs,0)
  321. End Method
  322. Method DrawPoly( xy#[],handlex#,handley#,tx#,ty# )
  323. If Not IsValid() Return
  324. If xy.length<6 Or (xy.length&1) Return
  325. Local segs=xy.length/2
  326. Local vrts#[]=New Float[segs*4]
  327. Local c:Int Ptr=Int Ptr(Float Ptr(vrts))
  328. For Local i=0 Until Len xy Step 2
  329. Local x#=xy[i+0]+handlex
  330. Local y#=xy[i+1]+handley
  331. vrts[i*2+0]=x*ix+y*iy+tx
  332. vrts[i*2+1]=x*jx+y*jy+ty
  333. c[i*2+3]=drawcolor
  334. Next
  335. SetActiveFrame Null
  336. device.DrawPrimitive(D3DPT_TRIANGLEFAN,D3DFVF_XYZ|D3DFVF_DIFFUSE,vrts,segs,0)
  337. End Method
  338. Method DrawFrame( frame:TD3D7ImageFrame,x0#,y0#,x1#,y1#,tx#,ty#,sx#,sy#,sw#,sh# )
  339. If Not IsValid() Return
  340. Local u0#=sx * frame.uscale
  341. Local v0#=sy * frame.vscale
  342. Local u1#=(sx+sw) * frame.uscale
  343. Local v1#=(sy+sh) * frame.vscale
  344. frame.SetUV u0,v0,u1,v1
  345. Local uv:Float Ptr
  346. Local c:Int Ptr
  347. uv=frame.xyzuv
  348. c=Int Ptr(uv)
  349. uv[0]=x0*ix+y0*iy+tx
  350. uv[1]=x0*jx+y0*jy+ty
  351. c[3]=drawcolor
  352. uv[6]=x1*ix+y0*iy+tx
  353. uv[7]=x1*jx+y0*jy+ty
  354. c[9]=drawcolor
  355. uv[12]=x1*ix+y1*iy+tx
  356. uv[13]=x1*jx+y1*jy+ty
  357. c[15]=drawcolor
  358. uv[18]=x0*ix+y1*iy+tx
  359. uv[19]=x0*jx+y1*jy+ty
  360. c[21]=drawcolor
  361. SetActiveFrame frame
  362. device.DrawPrimitive(D3DPT_TRIANGLEFAN,D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1,uv,4,0)
  363. End Method
  364. Method DrawPixmap( pixmap:TPixmap,x,y )
  365. If Not IsValid() Return
  366. Local srcdc,destdc
  367. Local surf:IDirectDrawSurface7
  368. Local renderSurf:IDirectDrawSurface7
  369. D3D7GraphicsDriver().EndScene
  370. device.GetRenderTarget Varptr renderSurf
  371. renderSurf.GetDC Varptr destdc
  372. surf=surffrompixmap( pixmap )
  373. surf.GetDC Varptr srcdc
  374. BitBlt destdc,x,y,pixmap.width,pixmap.height,srcdc,0,0,ROP_SRCCOPY
  375. surf.ReleaseDC srcdc
  376. renderSurf.ReleaseDC destdc
  377. surf.Release_
  378. D3D7GraphicsDriver().BeginScene
  379. End Method
  380. Method GrabPixmap:TPixmap( x,y,width,height )
  381. If Not IsValid() Return
  382. Local pixmap:TPixmap
  383. Local srcdc,destdc
  384. Local surf:IDirectDrawSurface7
  385. Local renderSurf:IDirectDrawSurface7
  386. D3D7GraphicsDriver().EndScene
  387. device.GetRenderTarget Varptr renderSurf
  388. pixmap=TPixmap.Create( width,height,PF_BGR888 )
  389. renderSurf.GetDC Varptr srcdc
  390. surf=surffrompixmap( pixmap )
  391. surf.GetDC Varptr destdc
  392. BitBlt destdc,0,0,width,height,srcdc,x,y,ROP_SRCCOPY
  393. surf.ReleaseDC destdc
  394. renderSurf.ReleaseDC srcdc
  395. surf.Release_()
  396. D3D7GraphicsDriver().BeginScene
  397. Return pixmap
  398. End Method
  399. Method SetResolution( width#,height# )
  400. Local gw=GraphicsWidth()
  401. Local gh=GraphicsHeight()
  402. Local world#[]=[..
  403. gw/width,0.0,0.0,0.0,..
  404. 0.0,gh/height,0.0,0.0,..
  405. 0.0,0.0,1.0,0.0,..
  406. 0.0,0.0,0.0,1.0 ]
  407. device.SetTransform D3DTS_WORLD,world
  408. Local proj#[]=[..
  409. 2.0/gw,0.0,0.0,0.0,..
  410. 0.0,-2.0/gh,0.0,0.0,..
  411. 0.0,0.0,1.0,0.0,..
  412. -1-(1.0/gw),1+(1.0/gh),1.0,1.0]
  413. device.SetTransform D3DTS_PROJECTION,proj
  414. End Method
  415. Method surffrompixmap:IDirectDrawSurface7(pixmap:TPixmap)
  416. Local surf:IDirectDrawSurface7
  417. Local desc:DDSURFACEDESC2=New DDSURFACEDESC2
  418. Local res
  419. If pixmap.format=PF_I8 pixmap=pixmap.convert(PF_BGR888)
  420. If pixmap.format=PF_A8 pixmap=pixmap.convert(PF_BGRA8888)
  421. desc.dwSize=SizeOf(desc)
  422. desc.dwFlags=DDSD_CAPS|DDSD_WIDTH|DDSD_HEIGHT|DDSD_PITCH|DDSD_LPSURFACE|DDSD_PIXELFORMAT
  423. desc.dwWidth=pixmap.width
  424. desc.dwHeight=pixmap.height
  425. desc.lPitch=pixmap.pitch
  426. desc.lpSurface=pixmap.pixels
  427. desc.ddsCaps=DDSCAPS_SYSTEMMEMORY|DDSCAPS_OFFSCREENPLAIN
  428. desc.ddpf_dwSize=SizeOf(DDPIXELFORMAT)
  429. Select pixmap.format
  430. Case PF_BGR888
  431. desc.ddpf_dwFlags=DDPF_RGB
  432. desc.ddpf_BitCount=24
  433. desc.ddpf_BitMask_0=$ff0000
  434. desc.ddpf_BitMask_1=$00ff00
  435. desc.ddpf_BitMask_2=$0000ff
  436. Case PF_RGB888
  437. desc.ddpf_dwFlags=DDPF_RGB
  438. desc.ddpf_BitCount=24
  439. desc.ddpf_BitMask_0=$0000ff
  440. desc.ddpf_BitMask_1=$00ff00
  441. desc.ddpf_BitMask_2=$ff0000
  442. Case PF_BGRA8888
  443. desc.ddpf_dwFlags=DDPF_RGB|DDPF_ALPHAPIXELS
  444. desc.ddpf_BitCount=32
  445. desc.ddpf_BitMask_0=$ff0000
  446. desc.ddpf_BitMask_1=$00ff00
  447. desc.ddpf_BitMask_2=$0000ff
  448. desc.ddpf_BitMask_3=$ff000000
  449. Case PF_RGBA8888
  450. desc.ddpf_dwFlags=DDPF_RGB|DDPF_ALPHAPIXELS
  451. desc.ddpf_BitCount=32
  452. desc.ddpf_BitMask_0=$0000ff
  453. desc.ddpf_BitMask_1=$00ff00
  454. desc.ddpf_BitMask_2=$ff0000
  455. desc.ddpf_BitMask_3=$ff000000
  456. End Select
  457. res=D3D7GraphicsDriver().DirectDraw7().CreateSurface( desc,Varptr surf,Null )
  458. If res<>DD_OK RuntimeError "D3D7Max2D Create System Surface Failed"
  459. Return surf
  460. End Method
  461. Method SetActiveFrame( frame:TD3D7ImageFrame )
  462. If frame=activeFrame Return
  463. If frame
  464. device.SetTexture 0,frame.surface
  465. If Not activeFrame
  466. device.SetTextureStageState 0,D3DTSS_COLOROP,D3DTOP_MODULATE
  467. device.SetTextureStageState 0,D3DTSS_ALPHAOP,D3DTOP_MODULATE
  468. EndIf
  469. Local flags=frame.flags & FILTEREDIMAGE
  470. If flags<>activeFrameFlags
  471. If flags & FILTEREDIMAGE
  472. device.SetTextureStageState 0,D3DTSS_MAGFILTER,D3DTFG_LINEAR
  473. device.SetTextureStageState 0,D3DTSS_MINFILTER,D3DTFG_LINEAR
  474. device.SetTextureStageState 0,D3DTSS_MIPFILTER,D3DTFG_LINEAR
  475. Else
  476. device.SetTextureStageState 0,D3DTSS_MAGFILTER,D3DTFG_POINT
  477. device.SetTextureStageState 0,D3DTSS_MINFILTER,D3DTFG_POINT
  478. device.SetTextureStageState 0,D3DTSS_MIPFILTER,D3DTFG_POINT
  479. EndIf
  480. activeFrameFlags=flags
  481. EndIf
  482. Else
  483. device.SetTexture 0,Null
  484. device.SetTextureStageState 0,D3DTSS_COLOROP,D3DTOP_SELECTARG2
  485. device.SetTextureStageState 0,D3DTSS_ALPHAOP,D3DTOP_SELECTARG2
  486. EndIf
  487. activeFrame=frame
  488. End Method
  489. End Type
  490. Type TD3D7ImageFrame Extends TImageFrame
  491. Field seq
  492. Field driver:TD3D7Max2DDriver
  493. Field surface:IDirectDrawSurface7
  494. Field sinfo:DDSurfaceDesc2
  495. Field xyzuv#[24]
  496. Field width,height,flags
  497. Field uscale#,vscale#
  498. Method Delete()
  499. If Not surface Return
  500. If seq=GraphicsSeq D3D7GraphicsDriver().DestroySurface surface
  501. surface=Null
  502. End Method
  503. Method SetUV(u0#,v0#,u1#,v1#)
  504. xyzuv[4]=u0
  505. xyzuv[5]=v0
  506. xyzuv[10]=u1
  507. xyzuv[11]=v0
  508. xyzuv[16]=u1
  509. xyzuv[17]=v1
  510. xyzuv[22]=u0
  511. xyzuv[23]=v1
  512. End Method
  513. Function Create:TD3D7ImageFrame( driver:TD3D7Max2DDriver,width,height,flags )
  514. Function Pow2Size( n )
  515. Local t=1
  516. While t<n
  517. t:*2
  518. Wend
  519. Return t
  520. End Function
  521. Local swidth=Pow2Size(width)
  522. Local sheight=Pow2Size(height)
  523. Local desc:DDSURFACEDESC2=New DDSURFACEDESC2
  524. Local res
  525. desc.dwSize=SizeOf(desc)
  526. desc.dwFlags=DDSD_WIDTH|DDSD_HEIGHT|DDSD_CAPS|DDSD_PIXELFORMAT
  527. desc.dwWidth=swidth
  528. desc.dwHeight=sheight
  529. desc.ddsCaps=DDSCAPS_TEXTURE
  530. 'don't manage fast DYNAMICIMAGEs
  531. If flags<>DYNAMICIMAGE desc.ddsCaps2=DDSCAPS2_TEXTUREMANAGE
  532. desc.ddpf_dwSize=SizeOf(DDPIXELFORMAT)
  533. desc.ddpf_dwFlags=DDPF_RGB|DDPF_ALPHAPIXELS
  534. desc.ddpf_BitCount=32
  535. desc.ddpf_BitMask_0=$ff0000
  536. desc.ddpf_BitMask_1=$00ff00
  537. desc.ddpf_BitMask_2=$0000ff
  538. desc.ddpf_BitMask_3=$ff000000
  539. If flags & MIPMAPPEDIMAGE desc.ddsCaps:|DDSCAPS_MIPMAP|DDSCAPS_COMPLEX
  540. Local surf:IDirectDrawSurface7=D3D7GraphicsDriver().CreateSurface( desc )
  541. If Not surf Throw "Create DX7 surface Failed"
  542. Local frame:TD3D7ImageFrame=New TD3D7ImageFrame
  543. frame.seq=GraphicsSeq
  544. frame.driver=driver
  545. frame.surface=surf
  546. frame.sinfo=New DDSurfaceDesc2
  547. frame.sinfo.dwSize=SizeOf(frame.sinfo)
  548. frame.xyzuv=New Float[24]
  549. frame.width=width
  550. frame.height=height
  551. frame.flags=flags
  552. frame.uscale=1.0/swidth
  553. frame.vscale=1.0/sheight
  554. frame.SetUV 0.0,0.0,width * frame.uscale,height * frame.vscale
  555. Return frame
  556. End Function
  557. Method Lock:TPixmap( read_lock,write_lock )
  558. Local lflags=DDLOCK_WAIT|DDLOCK_SURFACEMEMORYPTR
  559. If read_lock And Not write_lock lflags:|DDLOCK_READONLY
  560. If write_lock And Not read_lock lflags:|DDLOCK_WRITEONLY
  561. Local res=surface.Lock(Null,sinfo,lflags,Null)
  562. If res<>DD_OK RuntimeError "DD3D7ImageFrame Lock failed" ' Return
  563. Return TPixmap.CreateStatic( sinfo.lpSurface,sinfo.dwWidth,sinfo.dwHeight,sinfo.lPitch,PF_BGRA8888 )
  564. End Method
  565. Method Unlock()
  566. SmearEdges
  567. surface.Unlock Null
  568. If flags & MIPMAPPEDIMAGE BuildMipMaps
  569. End Method
  570. Method Draw( x0#,y0#,x1#,y1#,tx#,ty#,sx#,sy#,sw#,sh# )
  571. driver.DrawFrame Self,x0#,y0#,x1#,y1#,tx#,ty#,sx,sy,sw,sh
  572. End Method
  573. Function Mix(c0,c1)
  574. Local c
  575. c=((c0 Shr 1)&$7f7f7f7f)+((c1 Shr 1)&$7f7f7f7f)
  576. c:+(c Shr 3)&$01010101
  577. Return c
  578. End Function
  579. Method SmearEdges()
  580. Local p:Byte Ptr
  581. Local n,x,y,c
  582. If width<>sinfo.dwWidth
  583. n=1
  584. If flags & MIPMAPPEDIMAGE n=sinfo.dwWidth-width
  585. For y=0 Until height
  586. p=sinfo.lpSurface+y*sinfo.lPitch
  587. c=Int Ptr(p)[width-1]
  588. For x=0 Until n
  589. Int Ptr(p)[width+x]=c
  590. Next
  591. Next
  592. EndIf
  593. If height<>sinfo.dwHeight
  594. n=1
  595. If flags & MIPMAPPEDIMAGE n=sinfo.dwHeight-height
  596. p=sinfo.lpSurface+(height-1)*sinfo.lPitch
  597. For y=1 To n
  598. MemCopy p+y*sinfo.lPitch,p,sinfo.dwWidth*4
  599. Next
  600. EndIf
  601. End Method
  602. Method BuildMipMaps()
  603. Type TMip
  604. Field surf:IDirectDrawSurface7
  605. Field info:DDSURFACEDESC2=New DDSURFACEDESC2
  606. Method Lock(srf:IDirectDrawSurface7)
  607. surf=srf
  608. info.dwSize=SizeOf(info)
  609. Return surf.Lock(Null,info,DDLOCK_WAIT,0)
  610. End Method
  611. Method Write(x,y,argb)
  612. Local p:Byte Ptr
  613. x=Min(x,info.dwWidth-1)
  614. y=Min(y,info.dwHeight-1)
  615. p=info.lpSurface+y*info.lPitch
  616. Int Ptr(p)[x]=argb
  617. End Method
  618. Method Read(x,y)
  619. Local p:Byte Ptr
  620. x=Min(x,info.dwWidth-1)
  621. y=Min(y,info.dwHeight-1)
  622. p=info.lpSurface+y*info.lPitch
  623. Return Int Ptr(p)[x]
  624. End Method
  625. Method Unlock()
  626. surf.Unlock Null
  627. End Method
  628. End Type
  629. Local caps2:DDSCAPS2
  630. Local src:IDirectDrawSurface7
  631. Local dest:IDirectDrawSurface7
  632. Local srcmip:TMip
  633. Local dstmip:TMip
  634. Local res,x,y,w,h,c0,c1,c2,c3
  635. caps2=New DDSCAPS2
  636. caps2.dwCaps=DDSCAPS_TEXTURE
  637. caps2.dwCaps2=DDSCAPS2_MIPMAPSUBLEVEL
  638. srcmip=New TMip
  639. dstmip=New TMip
  640. src=surface
  641. While True
  642. res=src.GetAttachedSurface(caps2,Varptr dest)
  643. If res Exit
  644. res=srcmip.Lock(src)
  645. If res RuntimeError "BuildMipMaps: lock failed"
  646. res=dstmip.Lock(dest)
  647. If res RuntimeError "BuildMipMaps: lock failed"
  648. w=dstmip.info.dwWidth
  649. h=dstmip.info.dwHeight
  650. For y=0 Until h
  651. For x=0 Until w
  652. c0=srcmip.read(x*2,y*2)
  653. c1=srcmip.read(x*2+1,y*2)
  654. c2=srcmip.read(x*2,y*2+1)
  655. c3=srcmip.read(x*2+1,y*2+1)
  656. dstmip.write x,y,mix(mix(c0,c1),mix(c2,c3))
  657. Next
  658. Next
  659. srcmip.Unlock
  660. dstmip.Unlock
  661. dest.Release_
  662. src=dest
  663. Wend
  664. End Method
  665. End Type
  666. Rem
  667. bbdoc: Get Direct3D7 Max2D Driver
  668. about:
  669. The returned driver can be used with #SetGraphicsDriver to enable Direct3D Max2D rendering.
  670. End Rem
  671. Function D3D7Max2DDriver:TD3D7Max2DDriver()
  672. If D3D7GraphicsDriver()
  673. Global _driver:TD3D7Max2DDriver=New TD3D7Max2DDriver
  674. Return _driver
  675. EndIf
  676. End Function
  677. Local driver:TD3D7Max2DDriver=D3D7Max2DDriver()
  678. If driver SetGraphicsDriver driver