Преглед на файлове

Format Code and fix grabpixmap and overhaul gl2sdlmax

Ronny Otto преди 2 години
родител
ревизия
b9c7b98d32
променени са 3 файла, в които са добавени 510 реда и са изтрити 719 реда
  1. 280 452
      d3d9sdlmax2d.mod/d3d9sdlmax2d.bmx
  2. 24 65
      gl2sdlmax2d.mod/main.bmx
  3. 206 202
      glsdlmax2d.mod/glsdlmax2d.bmx

+ 280 - 452
d3d9sdlmax2d.mod/d3d9sdlmax2d.bmx

@@ -45,6 +45,10 @@ Global _d3dDev:IDirect3DDevice9
 Global _d3d9Graphics:TD3D9SDLGraphics
 Global _max2dGraphics:TMax2dGraphics
 
+Global _BackbufferRenderImageFrame:TD3D9RenderImageFrame
+Global _CurrentRenderImageFrame:TD3D9RenderImageFrame
+Global _D3D9Scissor_BMaxViewport:Rect = New Rect
+
 Function Pow2Size:Int( n:Int )
 	Local t:Int=1
 	While t<n
@@ -72,7 +76,7 @@ Type TD3D9ImageFrame Extends TImageFrame
 		If _texture
 			If _seq=GraphicsSeq
 				If _texture=_bound_texture
-					_d3dDev.SetTexture 0,nullBaseTexture9
+					_d3dDev.SetTexture 0,Null
 					_bound_texture=Null
 				EndIf
 				_d3d9Graphics.ReleaseNow _texture
@@ -100,7 +104,7 @@ Type TD3D9ImageFrame Extends TImageFrame
 				EndIf
 			EndIf
 		Else
-			If pixmap.Format<>PF_BGRA8888 pixmap=pixmap.Convert( PF_BGRA8888 )
+			If pixmap.format<>PF_BGRA8888 pixmap=pixmap.Convert( PF_BGRA8888 )
 		EndIf
 
 		Local levels:Int=(flags & MIPMAPPEDIMAGE)=0
@@ -183,206 +187,67 @@ Type TD3D9ImageFrame Extends TImageFrame
 		
 		Return Self
 	End Method
-	
+
 	Method Draw( x0:Float,y0:Float,x1:Float,y1:Float,tx:Float,ty:Float,sx:Float,sy:Float,sw:Float,sh:Float ) Override
-		Local u0:Float=sx * _uscale
-		Local v0:Float=sy * _vscale
-		Local u1:Float=(sx+sw) * _uscale
-		Local v1:Float=(sy+sh) * _vscale
-	
-		_fverts[0]=x0*_ix+y0*_iy+tx
-		_fverts[1]=x0*_jx+y0*_jy+ty
-		_iverts[3]=_color
-		_fverts[4]=u0
-		_fverts[5]=v0
-		
-		_fverts[6]=x1*_ix+y0*_iy+tx
-		_fverts[7]=x1*_jx+y0*_jy+ty
-		_iverts[9]=_color
-		_fverts[10]=u1
-		_fverts[11]=v0
-		
-		_fverts[12]=x1*_ix+y1*_iy+tx
-		_fverts[13]=x1*_jx+y1*_jy+ty
-		_iverts[15]=_color
-		_fverts[16]=u1
-		_fverts[17]=v1
-		
-		_fverts[18]=x0*_ix+y1*_iy+tx
-		_fverts[19]=x0*_jx+y1*_jy+ty
-		_iverts[21]=_color
-		_fverts[22]=u0
-		_fverts[23]=v1
+		Local u0:Float = sx * _uscale
+		Local v0:Float = sy * _vscale
+		Local u1:Float = (sx + sw) * _uscale
+		Local v1:Float = (sy + sh) * _vscale
+
+		_fverts[0] = x0 * _ix + y0 * _iy + tx
+		_fverts[1] = x0 * _jx + y0 * _jy + ty
+		_iverts[3] = _color
+		_fverts[4] = u0
+		_fverts[5] = v0
+		
+		_fverts[6] = x1 * _ix + y0 * _iy + tx
+		_fverts[7] = x1 * _jx + y0 * _jy + ty
+		_iverts[9] = _color
+		_fverts[10] = u1
+		_fverts[11] = v0
+		
+		_fverts[12] = x1 * _ix + y1 * _iy + tx
+		_fverts[13] = x1 * _jx + y1 * _jy + ty
+		_iverts[15] = _color
+		_fverts[16] = u1
+		_fverts[17] = v1
+		
+		_fverts[18] = x0 * _ix + y1 * _iy + tx
+		_fverts[19] = x0 * _jx + y1 * _jy + ty
+		_iverts[21] = _color
+		_fverts[22] = u0
+		_fverts[23] = v1
 		
 		If _texture<>_bound_texture
 			_d3dDev.SetTexture 0,_texture
-			_d3dDev.SetTextureStageState 0,D3DTSS_MAGFILTER,_magfilter
-			_d3dDev.SetTextureStageState 0,D3DTSS_MINFILTER,_minfilter
-			_d3dDev.SetTextureStageState 0,D3DTSS_MIPFILTER,_mipfilter
-			_bound_texture=_texture
+			_d3dDev.SetTextureStageState(0, D3DTSS_MAGFILTER, _magfilter)
+			_d3dDev.SetTextureStageState(0, D3DTSS_MINFILTER, _minfilter)
+			_d3dDev.SetTextureStageState(0, D3DTSS_MIPFILTER, _mipfilter)
+			_bound_texture = _texture
 		EndIf
 		
 		If Not _texture_enabled
-			_d3dDev.SetTextureStageState 0,D3DTSS_COLOROP,D3DTOP_MODULATE
-			_d3dDev.SetTextureStageState 0,D3DTSS_ALPHAOP,D3DTOP_MODULATE
-			_texture_enabled=True
+			_d3dDev.SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_MODULATE)
+			_d3dDev.SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_MODULATE)
+			_texture_enabled = True
 		EndIf
 		
-		_d3dDev.DrawPrimitiveUP D3DPT_TRIANGLEFAN,2,_fverts,24
+		_d3dDev.DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, _fverts, 24)
 	End Method
 	
-	Field _texture:IDirect3DTexture9,_seq:Int
-	
-	Field _magfilter:Int,_minfilter:Int,_mipfilter:Int,_uscale:Float,_vscale:Float
-	
-	Field _fverts:Float[24],_iverts:Int Ptr=Int Ptr( Varptr _fverts[0] )
-
+	Field _texture:IDirect3DTexture9, _seq:Int
+	Field _magfilter:Int, _minfilter:Int, _mipfilter:Int, _uscale:Float, _vscale:Float
+	Field _fverts:Float[24], _iverts:Int Ptr = Int Ptr( Varptr _fverts[0] )
 End Type
 
-
-Type TD3D9RenderImageContext Extends TRenderImageContext
-	Field _gc:TD3D9SDLGraphics
-	Field _d3ddev:IDirect3DDevice9
-	Field _backbuffer:IDirect3DSurface9
-	Field _matrix:Float[16]
-	Field _viewport:D3DVIEWPORT9
-	Field _renderimages:TList
-	Field _deviceok:Int = True
-
-	Method Delete()
-		ReleaseNow()
-	EndMethod
-	
-	Method ReleaseNow()
-		If _renderimages
-			For Local ri:TD3D9RenderImage = EachIn _renderimages
-				ri.DestroyRenderImage()
-			Next
-		EndIf
-
-		_renderimages = Null
-		_viewport = Null
-		_gc = Null
-
-		If _backbuffer
-			_backbuffer.release_
-			_backbuffer = Null
-		EndIf
-		If _d3ddev
-			_d3ddev.release_
-			_d3ddev = Null
-		EndIf
-	EndMethod
-
-	Method Create:TD3D9RenderimageContext(g:TGraphics, driver:TGraphicsDriver)
-		_gc = TD3D9SDLGraphics(g)
-
-		_d3ddev = _gc.GetDirect3DDevice()
-		_d3ddev.AddRef()
-
-		_d3ddev.GetRenderTarget(0, _backbuffer)
-
-		_viewport = New D3DVIEWPORT9
-		_d3ddev.GetViewport(_viewport)
-		_d3ddev.GetTransform(D3DTS_PROJECTION, _matrix)
-			
-		_renderimages = New TList
-
-		Return Self
-	EndMethod
-	
-	Method GraphicsContext:TGraphics()
-		Return _gc
-	EndMethod
-	
-	Method Destroy()
-		ReleaseNow()
-	EndMethod
-
-	Method CreateRenderImage:TRenderImage(width:Int, height:Int, UseImageFiltering:Int)
-		Local renderimage:TD3D9RenderImage = New TD3D9RenderImage.CreateRenderImage(width, height)
-		renderimage.Init(_d3ddev, UseImageFiltering)
-		_renderimages.AddLast(renderimage)
-
-		Return renderimage
-	EndMethod
-	
-	Method CreateRenderImageFromPixmap:TRenderImage(pixmap:TPixmap, UseImageFiltering:Int)
-		Local renderimage:TD3D9RenderImage = New TD3D9RenderImage.CreateRenderImage(pixmap.Width, pixmap.Height)
-		renderimage.InitFromPixmap(_d3ddev, pixmap, UseImageFiltering)
-		_renderimages.AddLast(renderimage)
-
-		Return renderimage
-	EndMethod
-	
-	Method DestroyRenderImage(renderImage:TRenderImage)
-		renderImage.DestroyRenderImage()
-		_renderimages.Remove(renderImage)
-	EndMethod
-
-	Method SetRenderImage(renderimage:TRenderimage)
-		If Not renderimage
-			_d3ddev.SetRenderTarget(0, _backbuffer)	
-			_d3ddev.SetTransform D3DTS_PROJECTION,_matrix
-			_d3ddev.SetViewport(_viewport)
-		Else
-			renderimage.SetRenderImage()
-		EndIf
-	EndMethod
-	
-	Method CreatePixmapFromRenderImage:TPixmap(renderImage:TRenderImage)
-		Return TD3D9RenderImage(renderImage).ToPixmap()
-	EndMethod
-
-	Method OnDeviceLost()
-		If _deviceok = False Return
-
-		For Local ri:TD3D9RenderImage = EachIn _renderimages
-			ri.OnDeviceLost()
-		Next
-		If _backbuffer
-			_backbuffer.release_
-			_backbuffer = Null
-		EndIf
-
-		_deviceok = False
-	EndMethod
-
-	Method OnDeviceReset()
-		If _deviceok = True Return
-
-		Local hr:Int = _d3ddev.GetRenderTarget(0, _backbuffer)
-		hr = _d3ddev.GetViewport(_viewport)
-
-		For Local ri:TD3D9RenderImage = EachIn _renderimages
-			ri.OnDeviceReset()
-		Next
-
-		_deviceok = True
-	EndMethod
-
-	Function fnOnDeviceLost(obj:Object)
-		Local ric:TD3D9RenderImageContext = TD3D9RenderImageContext(obj)
-		If Not ric Return
-		ric.OnDeviceLost()
-	EndFunction
-
-	Function fnOnDeviceReset(obj:Object)
-		Local ric:TD3D9RenderImageContext = TD3D9RenderImageContext(obj)
-		If Not ric Return
-		ric.OnDeviceReset()
-	EndFunction
-EndType
-
-
-
 Type TD3D9RenderImageFrame Extends TD3D9ImageFrame
 	Field _surface:IDirect3DSurface9
-	Field _persistpixmap:TPixmap
+	Field _stagingPixmap:TPixmap
+	Field _width:UInt, _height:UInt
 
 	Method Delete()
 		ReleaseNow()
-	EndMethod
+	End Method
 	
 	Method ReleaseNow()
 		If _surface
@@ -393,98 +258,132 @@ Type TD3D9RenderImageFrame Extends TD3D9ImageFrame
 			_texture.Release_
 			_texture = Null
 		EndIf
-	EndMethod
-	
-	Method Clear(d3ddev:IDirect3DDevice9, r:Int=0, g:Int=0, b:Int=0, a:Float=0.0)
-		If Not d3ddev Return
-
-		Local c:Int = (Int(a*255) Shl 24) | (r Shl 16) | (g Shl 8) | b
-		d3ddev.Clear(0, Null, D3DCLEAR_TARGET, c, 0.0, 0)
 	End Method
-	
-	Method CreateRenderTarget:TD3D9RenderImageFrame( d3ddev:IDirect3DDevice9, width:Int,height:Int )
-		d3ddev.CreateTexture(width,height,1,D3DUSAGE_RENDERTARGET,D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT,_texture,Null)
-		If _texture _texture.GetSurfaceLevel 0, _surface
+
+	Function Create:TD3D9RenderImageFrame(width:UInt, height:UInt, flags:Int )
+		Local D3D9Texture:IDirect3DTexture9
+		If _d3ddev.CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8,D3DPOOL_DEFAULT, D3D9Texture, Null) < 0
+			Throw "Could not create D3D9 Render Image : Width " + width + ", Height " + height + ", Flags " + flags
+			Return Null
+		EndIf
+
+		Local D3D9Surface:IDirect3DSurface9
+		If D3D9Texture
+			If D3D9Texture.GetSurfaceLevel(0, D3D9Surface) < 0
+				Throw "Could not get surface index 0 for D3D9 Render Image : Width " + width + ", Height " + height + ", Flags " + flags
+				Return Null
+			EndIf
+		EndIf
 		
-		_magfilter = D3DTFG_LINEAR
-		_minfilter = D3DTFG_LINEAR
-		_mipfilter = D3DTFG_LINEAR
+		Local RenderImage:TD3D9RenderImageFrame = New TD3D9RenderImageFrame
+		RenderImage._texture = D3D9Texture
+		RenderImage._surface = D3D9Surface
+		RenderImage._magfilter = D3DTFG_LINEAR
+		RenderImage._minfilter = D3DTFG_LINEAR
+		RenderImage._mipfilter = D3DTFG_LINEAR
 
-		_uscale = 1.0 / width
-		_vscale = 1.0 / height
+		RenderImage._uscale = 1.0 / width
+		RenderImage._vscale = 1.0 / height
+		RenderImage._width = width
+		RenderImage._height = height
 
-		Return Self
-	EndMethod
+		Return RenderImage
+	End Function
 	
 	Method DestroyRenderImage()
 		ReleaseNow()
-	EndMethod
+	End Method
 
-	Method OnDeviceLost(d3ddev:IDirect3DDevice9, width:Int, height:Int)
-		_persistpixmap = ToPixmap(d3ddev, width, height)
+	Method OnDeviceLost()
+		Local BackBuffer:TD3D9RenderImageFrame = _BackBufferRenderImageFrame
+		If Self <> BackBuffer And Not _stagingpixmap
+			If _surface
+				_stagingPixmap  = RenderTargetToPixmap()
+			EndIf
+		EndIf
 		ReleaseNow()
-	EndMethod
+	End Method
 
-	Method OnDeviceReset(d3ddev:IDirect3DDevice9)
-		If(_persistpixmap)
-			d3ddev.CreateTexture(_persistpixmap.width, _persistpixmap.height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, _texture, Null)
-			If _texture
-				_texture.GetSurfaceLevel(0, _surface)
+	Method OnDeviceReset()		
+		' dont re-create until the device is ready
+		If _d3dDev.TestCooperativeLevel() = 0
+			If(_stagingPixmap)
+				RecreateFromPixmap()
 			EndIf
+		EndIf
+	End Method
 
-			FromPixmap(d3ddev, _persistpixmap)
+Private
+	Method RecreateFromPixmap()
+		If _d3ddev.CreateTexture(_width, _height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, _texture, Null) < 0
+			Throw "Failed to create render target"
+			Return
+		EndIf
+		
+		If _texture.GetSurfaceLevel(0, _surface) < 0
+			Throw "Failed to get surface of render target"
+			ReleaseNow()
+			Return
 		EndIf
 
-		_persistpixmap = Null
-	EndMethod
-	
-	Method FromPixmap(d3ddev:IDirect3DDevice9, pixmap:TPixmap)
-		' use a staging surface to copy the pixmap into
-		Local stage:IDirect3DSurface9
-		d3ddev.CreateOffscreenPlainSurface(pixmap.width, pixmap.height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, stage, Null)
+		Local StagingSurface:IDirect3DSurface9
+		If _d3ddev.CreateOffscreenPlainSurface(_width, _height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, StagingSurface, Null) < 0
+			Throw "Failed to create a staging surface"
+			ReleaseNow()
+			Return
+		EndIf
 
 		Local lockedrect:D3DLOCKED_RECT = New D3DLOCKED_RECT
-		stage.LockRect(lockedrect, Null, 0)
+		If StagingSurface.LockRect(lockedrect, Null, 0) < 0
+			Throw "Failed to lock the staging surface"
+			ReleaseNow()
+			StagingSurface.Release_()
+			Return
+		EndIf
 
-		' copy the pixel data across
-		For Local y:Int = 0 Until pixmap.height
-			Local srcptr:Byte Ptr = pixmap.pixels + y * pixmap.pitch
+		For Local y:Int = 0 Until _height
+			Local srcptr:Byte Ptr = _stagingPixmap.pixels + y * _stagingPixmap.pitch
 			Local dstptr:Byte Ptr = lockedrect.pBits + y * lockedrect.Pitch
-			MemCopy dstptr, srcptr, Size_T(pixmap.width * 4)
+			MemCopy dstptr, srcptr, Size_T(_stagingPixmap.width * 4)
 		Next
-		stage.UnlockRect()
+		StagingSurface.UnlockRect()
 
-		' copy from the staging surface to the render surface
-		d3ddev.UpdateSurface(stage, Null, _surface, Null)
+		If _d3ddev.UpdateSurface(StagingSurface, Null, _surface, Null) < 0
+			Throw "Failed to copy the staging surface texture data to the render target"
+			ReleaseNow()
+			StagingSurface.Release_()
+			Return
+		EndIf
 
-		' cleanup
-		stage.release_
-	EndMethod
+		StagingSurface.Release_()
+		_stagingPixmap = Null
+	End Method
 	
-	Method ToPixmap:TPixmap(d3ddev:IDirect3DDevice9, width:Int, height:Int)
-		Local pixmap:TPixmap = CreatePixmap(width, height, PF_RGBA8888)
-
+	Method RenderTargetToPixmap:TPixmap()	
 		' use a staging surface to get the texture contents
-		Local stage:IDirect3DSurface9
-		d3ddev.CreateOffscreenPlainSurface(width, height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, stage, Null)
-
-		Local result:Int = d3ddev.GetRenderTargetData(_surface, stage)
-		If result < 0
-			If result = D3DERR_DRIVERINTERNALERROR
-				Throw "TD3D9RenderImageFrame:ToPixmap:GetRenderTargetData failed: D3DERR_DRIVERINTERNALERROR"
-			ElseIf result = D3DERR_DEVICELOST
-				'Throw "TD3D9RenderImageFrame:ToPixmap:GetRenderTargetData failed: D3DERR_DEVICELOST"
-			ElseIf result = D3DERR_INVALIDCALL
-				Throw "TD3D9RenderImageFrame:ToPixmap:GetRenderTargetData failed: D3DERR_INVALIDCALL"
-			Else
-				Throw "TD3D9RenderImageFrame:ToPixmap:GetRenderTargetData failed."
-			EndIf
+		Local StagingSurface:IDirect3DSurface9
+		If _d3ddev.CreateOffscreenPlainSurface(_width, _height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, StagingSurface, Null) < 0
+			Throw "Failed to create staging texture to receive render target data"
+			Return Null
 		EndIf
-
+		
+		If _d3ddev.GetRenderTargetData(_surface, StagingSurface) < 0
+			Throw "Failed to get render target data from render target into the staging buffer"
+			StagingSurface.Release_()
+			Return Null
+		EndIf
+		
 		' copy the pixel data across
 		Local lockedrect:D3DLOCKED_RECT = New D3DLOCKED_RECT
-		If stage.LockRect(lockedrect, Null, 0) < 0 Throw "TD3D9RenderImageFrame:ToPixmap:LockRect failed"
+		If StagingSurface.LockRect(lockedrect, Null, 0) < 0
+			StagingSurface.UnlockRect()
+			StagingSurface.Release_()
+			Throw "Failed to lock the staging buffer to get pixel data"
+			StagingSurface.Release_()
+			Return Null
+		EndIf
 
+		Local pixmap:TPixmap = CreatePixmap(_width, _height, PF_RGBA8888)
 		For Local y:Int = 0 Until pixmap.height
 			For Local x:Int = 0 Until pixmap.width
 				Local srcptr:Int Ptr = Int Ptr (lockedrect.pBits + x * 4 + y * lockedrect.Pitch)
@@ -493,176 +392,11 @@ Type TD3D9RenderImageFrame Extends TD3D9ImageFrame
 			Next
 		Next
 		
-		pixmap = ConvertPixmap(pixmap, PF_BGRA)
-		
-		' cleanup
-		stage.UnlockRect()
-		stage.release_
-		
-		Return pixmap
-	EndMethod
-EndType
-
-Type TD3D9RenderImage Extends TRenderImage
-	Field _d3ddev:IDirect3DDevice9
-	Field _viewport:D3DVIEWPORT9
-	Field _matrix:Float[]
-
-	Method Delete()
-		ReleaseNow()
-	EndMethod
-	
-	Method ReleaseNow()
-		If _d3ddev
-			_d3ddev.release_
-			_d3ddev = Null
-		EndIf
-	EndMethod
-
-	Method CreateRenderImage:TD3D9RenderImage(width:Int ,height:Int)
-		Self.width=width	' TImage.width
-		Self.height=height	' TImage.height
-	
-		_matrix = [	2.0/width, 0.0, 0.0, 0.0,..
-					0.0, -2.0/height, 0.0, 0.0,..
-					0.0, 0.0, 1.0, 0.0,..
-					-1-(1.0/width), 1+(1.0/height), 1.0, 1.0 ]
-
-		_viewport = New D3DVIEWPORT9
-		_viewport.width = width
-		_viewport.height = height
-		_viewport.MaxZ = 1.0
-
-		Return Self
-	EndMethod
-	
-	Method DestroyRenderImage()
-		ReleaseNow()
-		TD3D9RenderImageFrame(frames[0]).ReleaseNow()
-	EndMethod
-
-	Method Init(d3ddev:IDirect3DDevice9, UseImageFiltering:Int)
-		_d3ddev = d3ddev
-		_d3ddev.AddRef()
-
-		frames = New TD3D9RenderImageFrame[1]
-		frames[0] = New TD3D9RenderImageFrame.CreateRenderTarget(d3ddev, width, height)
-		If UseImageFiltering
-			TD3D9RenderImageFrame(frames[0])._magfilter=D3DTFG_LINEAR
-			TD3D9RenderImageFrame(frames[0])._minfilter=D3DTFG_LINEAR
-			TD3D9RenderImageFrame(frames[0])._mipfilter=D3DTFG_LINEAR
-		Else
-			TD3D9RenderImageFrame(frames[0])._magfilter=D3DTFG_POINT
-			TD3D9RenderImageFrame(frames[0])._minfilter=D3DTFG_POINT
-			TD3D9RenderImageFrame(frames[0])._mipfilter=D3DTFG_POINT
-		EndIf
-
-
-		'  clear the new render target surface
-		Local prevsurf:IDirect3DSurface9
-		Local prevmatrix:Float[16]
-		Local prevviewport:D3DVIEWPORT9 = New D3DVIEWPORT9
+		StagingSurface.UnlockRect()
+		StagingSurface.Release_()
 		
-		' get previous
-		d3ddev.GetRenderTarget(0, prevsurf)
-		d3ddev.GetTransform(D3DTS_PROJECTION, prevmatrix)
-		d3ddev.GetViewport(prevviewport)
-
-		' set and clear
-		d3ddev.SetRenderTarget(0, TD3D9RenderImageFrame(frames[0])._surface)
-		d3ddev.SetTransform(D3DTS_PROJECTION, _matrix)
-		d3ddev.Clear(0, Null, D3DCLEAR_TARGET, 0, 0.0, 0)
-
-		' reset to previous
-		_d3ddev.SetRenderTarget(0, prevsurf)
-		_d3ddev.SetTransform(D3DTS_PROJECTION, prevmatrix)
-		_d3ddev.SetViewport(prevviewport)
-
-		' cleanup
-		prevsurf.release_
-	EndMethod
-	
-	Method InitFromPixmap(d3ddev:IDirect3DDevice9, Pixmap:TPixmap, UseImageFiltering:Int)
-		_d3ddev = d3ddev
-		_d3ddev.AddRef()
-
-		Pixmap = ConvertPixmap(pixmap, PF_BGRA)
-
-		frames = New TD3D9RenderImageFrame[1]
-		frames[0] = New TD3D9RenderImageFrame.CreateRenderTarget(d3ddev, width, height)
-		If UseImageFiltering
-			TD3D9RenderImageFrame(frames[0])._magfilter=D3DTFG_LINEAR
-			TD3D9RenderImageFrame(frames[0])._minfilter=D3DTFG_LINEAR
-			TD3D9RenderImageFrame(frames[0])._mipfilter=D3DTFG_LINEAR
-		Else
-			TD3D9RenderImageFrame(frames[0])._magfilter=D3DTFG_POINT
-			TD3D9RenderImageFrame(frames[0])._minfilter=D3DTFG_POINT
-			TD3D9RenderImageFrame(frames[0])._mipfilter=D3DTFG_POINT
-		EndIf
-
-		TD3D9RenderImageFrame(frames[0]).FromPixmap(d3ddev, Pixmap)
-	EndMethod
-
-	Method Clear(r:Int=0, g:Int=0, b:Int=0, a:Float=0.0)
-		If frames[0] Then TD3D9RenderImageFrame(frames[0]).Clear(_d3ddev, r, g, b, a)
+		Return ConvertPixmap(pixmap, PF_BGRA)
 	End Method
-	
-	Method Frame:TImageFrame(index:Int=0)
-		If Not frames Return Null
-		If Not frames[0] Return Null
-		Return frames[0]
-	EndMethod
-	
-	Method SetRenderImage()
-		Local pTexture:IDirect3DTexture9
-		_d3ddev.GetTexture(0, pTexture)
-		
-		Local frame:TD3D9RenderImageFrame = TD3D9RenderImageFrame(frames[0])
-		If frame._texture <> pTexture
-			_d3ddev.SetTexture(0, pTexture)
-		EndIf
-		
-		If pTexture pTexture.Release_
-		
-		_d3ddev.SetRenderTarget(0, TD3D9RenderImageFrame(frames[0])._surface)
-		_d3ddev.SetTransform(D3DTS_PROJECTION,_matrix)
-		_d3ddev.SetViewport(_viewport)
-	EndMethod
-	
-	Method ToPixmap:TPixmap()
-		Return TD3D9RenderImageFrame(frames[0]).ToPixmap(_d3ddev, width, height)
-	EndMethod
-	
-	Method SetViewport(x:Int, y:Int, width:Int, height:Int)
-		If width = 0
-			width = Self.width
-			height = Self.height
-		EndIf
-
-		If x + width > Self.width
-			width:-(x + width - Self.width)
-		EndIf
-		If y + height > Self.height
-			height:-(y + height - Self.height)
-		EndIf
-
-		If x = 0 And y = 0 And width = Self.width And height = Self.height
-			_d3ddev.SetRenderState(D3DRS_SCISSORTESTENABLE, False)
-		Else
-			_d3ddev.SetRenderState(D3DRS_SCISSORTESTENABLE, True)
-			Local rect:Int[] = [x , y, x + width, y + height]
-			_d3ddev.SetScissorRect(rect)
-		EndIf
-
-	EndMethod
-
-	Method OnDeviceLost()
-		TD3D9RenderImageFrame(frames[0]).OnDeviceLost(_d3ddev, width, height)
-	EndMethod
-
-	Method OnDeviceReset()
-		TD3D9RenderImageFrame(frames[0]).OnDeviceReset(_d3ddev)
-	EndMethod
 EndType
 
 
@@ -676,7 +410,7 @@ Type TD3D9SDLMax2DDriver Extends TMax2dDriver
 
 		If Not D3D9SDLGraphicsDriver() Return Null
 
-		Local d3d:IDirect3D9=D3D9SDLGraphicsDriver().GetDirect3D()
+		Local d3d:IDirect3D9 = D3D9SDLGraphicsDriver().GetDirect3D()
 
 		If d3d.CheckDeviceFormat( D3DADAPTER_DEFAULT,D3DDEVTYPE_HAL,D3DFMT_X8R8G8B8,0,D3DRTYPE_TEXTURE,D3DFMT_A8R8G8B8 )<0
 			Return Null
@@ -717,7 +451,7 @@ Type TD3D9SDLMax2DDriver Extends TMax2dDriver
 
 		_max2dGraphics=TMax2dGraphics( g )
 
-		_d3d9graphics=TD3D9SDLGraphics( _max2dGraphics._graphics )
+		_d3d9graphics=TD3D9SDLGraphics( _max2dGraphics._backendGraphics )
 
 		If Not _max2dGraphics Or Not _d3d9graphics Then
 			Throw "SetGraphics failed for D3D9"
@@ -753,11 +487,11 @@ Type TD3D9SDLMax2DDriver Extends TMax2dDriver
 		Local viewport:D3DVIEWPORT9
 		viewport.X = 0
 		viewport.Y = 0
-		viewport.Width = _gw
-		viewport.Height = _gh
+		viewport.width = _gw
+		viewport.height = _gh
 		viewport.MinZ = 0.0
 		viewport.MaxZ = 1.0
-		_d3dDev.SetViewport viewport
+		_d3dDev.SetViewport(viewport)
 
 		_d3dDev.SetRenderState D3DRS_ALPHAREF,$80
 		_d3dDev.SetRenderState D3DRS_ALPHAFUNC,D3DCMP_GREATEREQUAL
@@ -769,7 +503,7 @@ Type TD3D9SDLMax2DDriver Extends TMax2dDriver
 		_d3dDev.SetRenderState D3DRS_LIGHTING,False
 		_d3dDev.SetRenderState D3DRS_CULLMODE,D3DCULL_NONE	
 		
-		_d3dDev.SetTexture 0,nullBaseTexture9
+		_d3dDev.SetTexture 0,Null
 		_bound_texture=Null
 
 		_d3dDev.SetFVF D3DFVF_XYZ|D3DFVF_DIFFUSE|D3DFVF_TEX1
@@ -789,14 +523,15 @@ Type TD3D9SDLMax2DDriver Extends TMax2dDriver
 		_d3dDev.SetTextureStageState 0,D3DTSS_MIPFILTER,D3DTFP_POINT
 		
 		_d3dDev.BeginScene
-
+		
+		_d3d9graphics.AddDeviceLostCallback(OnDeviceLost, Self)
+		_d3d9graphics.AddDeviceResetCallback(OnDeviceReset, Self)
+		
+		' Create default back buffer render image
+		AssignBackBufferRenderImage()
 	End Method
 
 	'***** TMax2DDriver *****
-	Method CreateRenderImageContext:Object(g:TGraphics) Override
-		Return New TD3D9RenderImageContext.Create(g, Self)
-	End Method
-
 	Method CreateFrameFromPixmap:TImageFrame( pixmap:TPixmap,flags:Int ) Override
 		Return New TD3D9ImageFrame.Create( pixmap,flags )
 	End Method
@@ -848,34 +583,21 @@ Type TD3D9SDLMax2DDriver Extends TMax2dDriver
 		_iverts[15]=_color
 		_iverts[21]=_color
 	End Method
-
-	Method SetColor( color:SColor8 ) Override
-		_color=(_color&$ff000000)|color.ToARGB()		
-		_iverts[3]=_color
-		_iverts[9]=_color
-		_iverts[15]=_color
-		_iverts[21]=_color
-	End Method
 	
-	Method SetClsColor( red:Int,green:Int,blue:Int ) Override
-		red=Max(Min(red,255),0)
-		green=Max(Min(green,255),0)
-		blue=Max(Min(blue,255),0)
-		_clscolor=$ff000000|(red Shl 16)|(green Shl 8)|blue
-	End Method
-
-	Method SetClsColor( color:SColor8 ) Override
-		_clscolor=$ff000000|color.ToARGB()
+	Method SetClsColor( red:Int,green:Int,blue:Int, alpha:Float ) Override
+		red = Max(Min(red, 255), 0)
+		green = Max(Min(green, 255), 0)
+		blue = Max(Min(blue, 255), 0)
+		Local a:Int = Max(Min(alpha * 255.0, 255), 0)
+		_clscolor = (a Shl 24) | (red Shl 16) | (green Shl 8) | blue
 	End Method
 	
 	Method SetViewport( x:Int,y:Int,width:Int,height:Int ) Override
-		If x=0 And y=0 And width=_gw And height=_gh 'GraphicsWidth() And height=GraphicsHeight()
-			_d3dDev.SetRenderState D3DRS_SCISSORTESTENABLE,False
-		Else
-			_d3dDev.SetRenderState D3DRS_SCISSORTESTENABLE,True
-			Local rect:Int[]=[x,y,x+width,y+height]
-			_d3dDev.SetScissorRect rect
-		EndIf
+		_D3D9Scissor_BMaxViewport.x = x
+		_D3D9Scissor_BMaxViewport.y = y
+		_D3D9Scissor_BMaxViewport.width = width
+		_D3D9Scissor_BMaxViewport.height = height
+		SetScissor(x, y, width, height)
 	End Method
 	
 	Method SetTransform( xx:Float,xy:Float,yx:Float,yy:Float ) Override
@@ -1021,6 +743,11 @@ Type TD3D9SDLMax2DDriver Extends TMax2dDriver
 
 	'GetDC/BitBlt MUCH faster than locking backbuffer!	
 	Method GrabPixmap:TPixmap( x:Int,y:Int,width:Int,height:Int ) Override
+		'for render targets we handle it differently to the backbuffer
+		If _CurrentRenderImageFrame <> _BackBufferRenderImageFrame
+			Return _CurrentRenderImageFrame.RenderTargetToPixmap()
+		EndIf
+
 	
 		Local srcsurf:IDirect3DSurface9
 		If _d3dDev.GetRenderTarget( 0,srcsurf )<0
@@ -1079,6 +806,107 @@ Type TD3D9SDLMax2DDriver Extends TMax2dDriver
 		_d3dDev.SetTransform D3DTS_PROJECTION,matrix
 	End Method
 	
+	' Render Image --------------------
+	Method AssignBackBufferRenderImage()
+		Local BackBufferRenderImageFrame:TD3D9RenderImageFrame = New TD3D9RenderImageFrame
+		BackBufferRenderImageFrame._width = _gw
+		BackBufferRenderImageFrame._height = _gh
+		_d3dDev.GetBackBuffer(0, 0, 0, Varptr BackBufferRenderImageFrame._surface)
+	
+		' cache it
+		_BackBufferRenderImageFrame = BackBufferRenderImageFrame
+		_CurrentRenderImageFrame = _BackBufferRenderImageFrame
+		
+		AddToRenderImageList(BackBufferRenderImageFrame)
+	EndMethod
+	
+	Method AddToRenderImageList(RenderImage:TD3D9RenderImageFrame)
+		_RenderImageList.AddLast(RenderImage)
+	EndMethod
+	
+	Method RemoveFromRenderImageList(RenderImage:TD3D9RenderImageFrame)
+		If(_RenderImageList.Contains(RenderImage))
+			_RenderImageList.Remove(RenderImage)
+		EndIf
+	EndMethod
+
+	Method CreateRenderImageFrame:TImageFrame(width:UInt, height:UInt, flags:Int) Override
+		Local RenderImage:TD3D9RenderImageFrame = TD3D9RenderImageFrame.Create(width, height, flags)
+		AddToRenderImageList(RenderImage)
+		Return RenderImage
+	EndMethod
+	
+	Method SetRenderImageFrame(RenderImageFrame:TImageFrame) Override
+		If RenderImageFrame = _CurrentRenderImageFrame
+			Return
+		EndIf
+
+		Local D3D9RenderImageFrame:TD3D9RenderImageFrame = TD3D9RenderImageFrame(RenderImageFrame)
+		_d3dDev.SetRenderTarget(0, D3D9RenderImageFrame._surface)
+		_CurrentRenderImageFrame = D3D9RenderImageFrame
+		
+		Local vp:Rect = _D3D9Scissor_BMaxViewport
+		SetScissor(vp.x, vp.y, vp.width, vp.height)
+		SetMatrixAndViewportToCurrentRenderImage()
+	EndMethod
+	
+	Method SetBackbuffer()
+		SetRenderImageFrame(_BackBufferRenderImageFrame)
+	EndMethod
+	
+	Function OnDeviceLost(obj:Object)
+		Local Driver:TD3D9SDLMax2DDriver = TD3D9SDLMax2DDriver(obj)
+		Local RenderImageList:TList = Driver._RenderImageList
+		
+		For Local RenderImage:TD3D9RenderImageFrame = EachIn RenderImageList
+			RenderImage.OnDeviceLost()
+		Next
+		Driver.RemoveFromRenderImageList(_BackBufferRenderImageFrame)
+	EndFunction
+	
+	Function OnDeviceReset(obj:Object)
+		Local Driver:TD3D9SDLMax2DDriver = TD3D9SDLMax2DDriver(obj)
+		Local RenderImageList:TList = Driver._RenderImageList
+
+		For Local RenderImage:TD3D9RenderImageFrame = EachIn RenderImageList
+			RenderImage.OnDeviceReset()
+		Next
+	EndFunction
+		
+Private
+	Field _RenderImageList:TList = New TList
+	
+	Method SetMatrixAndViewportToCurrentRenderImage()
+		Local width:Float = _CurrentRenderImageFrame._width
+		Local height:Float = _CurrentRenderImageFrame._height
+		
+		Local matrix#[] = [..
+		2.0 / width, 0.0, 0.0, 0.0,..
+		0.0, -2.0/height, 0.0, 0.0,..
+		0.0, 0.0, 1.0, 0.0,..
+		-1 - (1.0 / width), 1 + (1.0 / height), 1.0, 1.0]
+
+		_d3dDev.SetTransform D3DTS_PROJECTION,matrix
+		
+		Local Viewport:D3DViewport9 = New D3DViewport9
+		Viewport.X = 0
+		Viewport.Y = 0
+		Viewport.width = width
+		Viewport.height = height
+		Viewport.MinZ = 0.0
+		Viewport.MaxZ = 1.0
+		_d3dDev.SetViewport(Viewport)
+	EndMethod
+
+	Method SetScissor(x:Int, y:Int, width:Int, height:Int)
+		If x = 0 And y = 0 And width = _CurrentRenderImageFrame._width And height = _CurrentRenderImageFrame._height
+			_d3dDev.SetRenderState(D3DRS_SCISSORTESTENABLE, False)
+		Else
+			_d3dDev.SetRenderState(D3DRS_SCISSORTESTENABLE, True)
+			Local Scissor:Rect = New Rect(x, y, x + width, y + height)
+			_d3dDev.SetScissorRect(Varptr Scissor)
+		EndIf
+	EndMethod
 End Type
 
 Rem

+ 24 - 65
gl2sdlmax2d.mod/main.bmx

@@ -859,34 +859,25 @@ Type TGL2Max2DDriver Extends TMax2DDriver
 
 	'graphics driver overrides
 	Method GraphicsModes:TGraphicsMode[]() Override
-
 		Return SDLGraphicsDriver().GraphicsModes()
-
 	End Method
 
 	Method AttachGraphics:TMax2DGraphics( widget:Byte Ptr, flags:Long ) Override
-
 		Local g:TSDLGraphics = SDLGraphicsDriver().AttachGraphics( widget, flags )
 
 		If g Then Return TMax2DGraphics.Create( g, Self )
-
 	End Method
 	
 	Method CreateGraphics:TMax2DGraphics( width:Int, height:Int, depth:Int, hertz:Int, flags:Long, x:Int, y:Int ) Override
-
 		Local g:TSDLGraphics = SDLGraphicsDriver().CreateGraphics( width, height, depth, hertz, flags | SDL_GRAPHICS_GL, x, y )
 		
 		If g Then Return TMax2DGraphics.Create( g, Self )
-
 	End Method
 
 	Method SetGraphics( g:TGraphics ) Override
-
 		If Not g
-			TMax2DGraphics.ClearCurrent
-
-			SDLGraphicsDriver().SetGraphics Null
-			
+			TMax2DGraphics.ClearCurrent()
+			SDLGraphicsDriver().SetGraphics(Null)
 			inited = Null
 
 			Return
@@ -900,8 +891,8 @@ Type TGL2Max2DDriver Extends TMax2DDriver
 		SDLGraphicsDriver().SetGraphics(t._backendGraphics)
 
 		ResetGLContext(t)
-		t.MakeCurrent()
 
+		t.MakeCurrent()
 	End Method
 	
 	Method ResetGLContext( g:TGraphics )
@@ -937,34 +928,26 @@ Type TGL2Max2DDriver Extends TMax2DDriver
 		' cache it
 		_BackBufferRenderImageFrame = BackBufferRenderImageFrame
 		_CurrentRenderImageFrame = _BackBufferRenderImageFrame
-
 	End Method
 	
 	Method Flip:Int( sync:Int ) Override
-
 		Flush()
 
-		SDLGraphicsDriver().Flip sync
+		SDLGraphicsDriver().Flip(sync)
 ?ios
 		glViewport(0, 0, GraphicsWidth(), GraphicsHeight())
 ?
 	End Method
 
 	Method ToString:String() Override
-
 		Return "OpenGL"
-
 	End Method
-	
-	Method CreateFrameFromPixmap:TGLImageFrame( pixmap:TPixmap, flags:Int ) Override
-		Local frame:TGLImageFrame
-		frame = TGLImageFrame.CreateFromPixmap( pixmap, flags )
-		Return frame
 
+	Method CreateFrameFromPixmap:TGLImageFrame( pixmap:TPixmap, flags:Int ) Override
+		Return TGLImageFrame.CreateFromPixmap( pixmap, flags )
 	End Method
-	
-	Method SetBlend( blend:Int ) Override
 
+	Method SetBlend( blend:Int ) Override
 		If state_blend = blend Return
 
 		?opengles
@@ -973,7 +956,7 @@ Type TGL2Max2DDriver Extends TMax2DDriver
 		End If
 		?
 
-		state_blend=blend
+		state_blend = blend
 
 		Select blend
 		Case MASKBLEND
@@ -1015,21 +998,16 @@ Type TGL2Max2DDriver Extends TMax2DDriver
 			glDisable( GL_ALPHA_TEST )
 			?
 		End Select
-
 	End Method
 
 	Method SetAlpha( alpha:Float ) Override
-
 		If alpha > 1.0 Then alpha = 1.0
 		If alpha < 0.0 Then alpha = 0.0
 		color4f[3] = alpha
-
 	End Method
 
 	Method SetLineWidth( width:Float ) Override
-
 		glLineWidth( width )
-
 	End Method
 
 	Method SetColor( red:Int, green:Int, blue:Int ) Override
@@ -1058,12 +1036,10 @@ Type TGL2Max2DDriver Extends TMax2DDriver
 	End Method
 
 	Method SetTransform( xx:Float, xy:Float, yx:Float, yy:Float ) Override
-
 		ix = xx
 		iy = xy
 		jx = yx
 		jy = yy
-
 	End Method
 
 	Method Cls() Override
@@ -1072,17 +1048,15 @@ Type TGL2Max2DDriver Extends TMax2DDriver
 		FlushTest( PRIMITIVE_CLS )
 
 		glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
-
 	End Method
 
-	Method Plot( px:Float, py:Float ) Override
-
+	Method Plot( x:Float, y:Float ) Override
 		FlushTest( PRIMITIVE_DOT )
 
 		Local in:Int = vert_index * 2
 
-		vert_array[in + 0] = px
-		vert_array[in + 1] = py
+		vert_array[in + 0] = x
+		vert_array[in + 1] = y
 
 		in = vert_index * 4
 
@@ -1096,7 +1070,6 @@ Type TGL2Max2DDriver Extends TMax2DDriver
 	End Method
 
 	Method DrawLine( x0:Float, y0:Float, x1:Float, y1:Float, tx:Float, ty:Float ) Override
-
 		FlushTest( PRIMITIVE_LINE )
 
 		Local in:Int = vert_index * 2
@@ -1120,11 +1093,9 @@ Type TGL2Max2DDriver Extends TMax2DDriver
 		col_array[in + 7] = color4f[3] 'alpha
 
 		vert_index :+ 2
-
 	End Method
 
 	Method DrawRect( x0:Float, y0:Float, x1:Float, y1:Float, tx:Float, ty:Float ) Override
-
 		FlushTest( PRIMITIVE_PLAIN_TRIANGLE )
 
 		Local in:Int = vert_index * 2
@@ -1162,11 +1133,9 @@ Type TGL2Max2DDriver Extends TMax2DDriver
 
 		vert_index :+ 4
 		quad_index :+ 1
-
 	End Method
 
 	Method DrawOval( x0:Float, y0:Float, x1:Float, y1:Float, tx:Float, ty:Float ) Override
-
 		' TRIANGLE_FAN (no batching)
 		FlushTest( PRIMITIVE_TRIANGLE_FAN )
 
@@ -1213,11 +1182,9 @@ Type TGL2Max2DDriver Extends TMax2DDriver
 		Next
 
 		vert_index :+ segs + 2
-
 	End Method
 
 	Method DrawPoly( xy:Float[], handle_x:Float, handle_y:Float, origin_x:Float, origin_y:Float, indices:Int[] ) Override
-
 		If xy.length < 6 Or ( xy.length & 1 ) Then Return
 
 		' TRIANGLE_FAN (no batching)
@@ -1246,7 +1213,6 @@ Type TGL2Max2DDriver Extends TMax2DDriver
 	End Method
 
 	Method DrawPixmap( p:TPixmap, x:Int, y:Int ) Override
-
 		Local blend:Int = state_blend
 		SetBlend( SOLIDBLEND )
 
@@ -1254,14 +1220,12 @@ Type TGL2Max2DDriver Extends TMax2DDriver
 		If t.format <> PF_RGBA8888 Then t = ConvertPixmap( t, PF_RGBA8888 )
 
 		Local img:TImage = LoadImage(t)
-		DrawImage img, x, y
+		DrawImage( img, x, y )
 
 		SetBlend( blend )
-
 	End Method
 
 	Method DrawTexture( name:Int, u0:Float, v0:Float, u1:Float, v1:Float, x0:Float, y0:Float, x1:Float, y1:Float, tx:Float, ty:Float, img:TImageFrame = Null )
-
 		FlushTest( PRIMITIVE_TEXTURED_TRIANGLE, name )
 
 		Local in:Int = vert_index * 2
@@ -1312,31 +1276,32 @@ Type TGL2Max2DDriver Extends TMax2DDriver
 		If img Then
 			imgCache.AddLast(img)
 		End If
-
 	End Method
 
 	Method GrabPixmap:TPixmap( x:Int, y:Int, w:Int, h:Int ) Override
-
 		Local blend:Int = state_blend
 		SetBlend( SOLIDBLEND )
 		Local p:TPixmap = CreatePixmap( w, h, PF_RGBA8888 )
+
+		'The default backbuffer in Max2D was opaque so overwrote any
+		'trash data of a freshly created pixmap. Potentially transparent
+		'backbuffers require a complete transparent pixmap to start with.
+		p.ClearPixels(0)
+
 		' flush everything to ensure there's something to read
 		Flush()
-		glReadPixels( x, GraphicsHeight() - h - y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, p.pixels )
+		If _CurrentRenderImageFrame and _CurrentRenderImageFrame <> _BackbufferRenderImageFrame
+			glReadPixels(x, _CurrentRenderImageFrame.height - h - y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, p.pixels)
+		Else
+			glReadPixels(x, _BackbufferRenderImageFrame.height - h - y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, p.pixels)
+		EndIf
 		p = YFlipPixmap( p )
 		SetBlend( blend )
 		Return p
-
 	End Method
 
 	Method SetResolution( width:Float, height:Float ) Override
-
 		u_pmatrix.SetOrthographic( 0, width, 0, height, -1, 1 )
-		'glMatrixMode( GL_PROJECTION )
-		'glLoadIdentity()
-		'glOrtho( 0, width, height, 0, -1, 1 )
-		'glMatrixMode( GL_MODELVIEW )
-
 	End Method
 
 	Method Init()
@@ -1576,18 +1541,12 @@ Private
 
 	Method SetMatrixAndViewportToCurrentRenderImage()
 		u_pmatrix.SetOrthographic( 0, _CurrentRenderImageFrame.width, 0, _CurrentRenderImageFrame.height, -1, 1 )
-		
-		'glMatrixMode(GL_PROJECTION)
-		'glLoadIdentity()
-		'glOrtho(0, _CurrentRenderImageFrame.width, _CurrentRenderImageFrame.height, 0, -1, 1)
-		'glMatrixMode(GL_MODELVIEW)
-		'glLoadIdentity()
 		glViewport(0, 0, _CurrentRenderImageFrame.width, _CurrentRenderImageFrame.height)
 	EndMethod
 
 	Method SetScissor(x:Int, y:Int, w:Int, h:Int)
 		Local ri:TImageFrame = _CurrentRenderImageFrame
-		If x =0  And y = 0 And w = _CurrentRenderImageFrame.width And h = _CurrentRenderImageFrame.height
+		If x = 0  And y = 0 And w = _CurrentRenderImageFrame.width And h = _CurrentRenderImageFrame.height
 			glDisable(GL_SCISSOR_TEST)
 		Else
 			glEnable(GL_SCISSOR_TEST)

+ 206 - 202
glsdlmax2d.mod/glsdlmax2d.bmx

@@ -66,10 +66,10 @@ Global _CurrentRenderImageFrame:TGLSDLRenderImageFrame
 Global _GLScissor_BMaxViewport:Rect = New Rect
 
 'Naughty!
-Const GL_BGR:Int=$80E0
-Const GL_BGRA:Int=$80E1
-Const GL_CLAMP_TO_EDGE:Int=$812F
-Const GL_CLAMP_TO_BORDER:Int=$812D
+Const GL_BGR:Int = $80E0
+Const GL_BGRA:Int = $80E1
+Const GL_CLAMP_TO_EDGE:Int = $812F
+Const GL_CLAMP_TO_BORDER:Int = $812D
 
 Global ix:Float,iy:Float,jx:Float,jy:Float
 Global color4ub:Byte[4]
@@ -79,28 +79,28 @@ Global state_boundtex:Int
 Global state_texenabled:Int
 
 Function BindTex( name:Int )
-	If name=state_boundtex Return
-	glBindTexture GL_TEXTURE_2D,name
-	state_boundtex=name
+	If name = state_boundtex Return
+	glBindTexture( GL_TEXTURE_2D, name )
+	state_boundtex = name
 End Function
 
 Function EnableTex( name:Int )
-	BindTex name
+	BindTex( name )
 	If state_texenabled Return
-	glEnable GL_TEXTURE_2D
-	state_texenabled=True
+	glEnable( GL_TEXTURE_2D )
+	state_texenabled = True
 End Function
 
 Function DisableTex()
 	If Not state_texenabled Return
-	glDisable GL_TEXTURE_2D
-	state_texenabled=False
+	glDisable( GL_TEXTURE_2D )
+	state_texenabled = False
 End Function
 
 Function Pow2Size:Int( n:Int )
-	Local t:Int=1
-	While t<n
-		t:*2
+	Local t:Int = 1
+	While t < n
+		t :* 2
 	Wend
 	Return t
 End Function
@@ -117,11 +117,11 @@ End Function
 
 Function CreateTex:Int( width:Int,height:Int,flags:Int,pixmap:TPixmap )
 	If pixmap.dds_fmt<>0 Then Return pixmap.tex_name ' if dds texture already exists
-	
+
 	'alloc new tex
 	Local name:Int
 	glGenTextures( 1, Varptr name )
-	
+
 	'flush dead texs
 	If dead_tex_seq=GraphicsSeq
 		Local n:Int = dead_texs.RemoveLast()
@@ -170,29 +170,29 @@ Function CreateTex:Int( width:Int,height:Int,flags:Int,pixmap:TPixmap )
 End Function
 
 'NOTE: Assumes a bound texture.
-Function UploadTex( pixmap:TPixmap,flags:Int )
+Function UploadTex( pixmap:TPixmap, flags:Int )
 	Local mip_level:Int
 	If pixmap.dds_fmt <> 0 Then Return ' if dds texture already exists
 	Repeat
 		glPixelStorei GL_UNPACK_ROW_LENGTH,pixmap.pitch/BytesPerPixel[pixmap.format]
 		glTexSubImage2D GL_TEXTURE_2D,mip_level,0,0,pixmap.width,pixmap.height,GL_RGBA,GL_UNSIGNED_BYTE,pixmap.pixels
 
-		If Not (flags & MIPMAPPEDIMAGE) Then Exit
-		If pixmap.width>1 And pixmap.height>1
-			pixmap=ResizePixmap( pixmap,pixmap.width/2,pixmap.height/2 )
-		Else If pixmap.width>1
-			pixmap=ResizePixmap( pixmap,pixmap.width/2,pixmap.height )
-		Else If pixmap.height>1
-			pixmap=ResizePixmap( pixmap,pixmap.width,pixmap.height/2 )
+		If Not ( flags & MIPMAPPEDIMAGE ) Then Exit
+		If pixmap.width > 1 And pixmap.height > 1
+			pixmap = ResizePixmap( pixmap, pixmap.width / 2, pixmap.height / 2 )
+		Else If pixmap.width > 1
+			pixmap = ResizePixmap( pixmap, pixmap.width / 2, pixmap.height )
+		Else If pixmap.height > 1
+			pixmap = ResizePixmap( pixmap, pixmap.width, pixmap.height / 2 )
 		Else
 			Exit
 		EndIf
-		mip_level:+1
+		mip_level :+ 1
 	Forever
 	glPixelStorei GL_UNPACK_ROW_LENGTH,0
 End Function
 
-Function AdjustTexSize( width:Int Var,height:Int Var )
+Function AdjustTexSize( width:Int Var, height:Int Var )
 	'calc texture size
 	width = Pow2Size( width )
 	height = Pow2Size( height )
@@ -201,24 +201,24 @@ Function AdjustTexSize( width:Int Var,height:Int Var )
 		glTexImage2D GL_PROXY_TEXTURE_2D,0,4,width,height,0,GL_RGBA,GL_UNSIGNED_BYTE,Null
 		glGetTexLevelParameteriv GL_PROXY_TEXTURE_2D,0,GL_TEXTURE_WIDTH,Varptr t
 		If t Then Return
-		If width=1 And height=1 Then RuntimeError "Unable to calculate tex size"
-		If width>1 Then width :/ 2
-		If height>1 Then height :/ 2
+		If width = 1 And height = 1 Then RuntimeError "Unable to calculate tex size"
+		If width > 1 width :/ 2
+		If height > 1 height :/ 2
 	Forever
 End Function
 
 Type TDynamicArray
 
 	Private
-	
+
 	Field data:Int Ptr
 	Field size:Size_T
 	Field capacity:Size_T
-	
+
 	Field guard:TMutex
-	
+
 	Public
-	
+
 	Method New(initialCapacity:Int = 8)
 		capacity = initialCapacity
 		data = malloc_(Size_T(initialCapacity * 4))
@@ -235,25 +235,25 @@ Type TDynamicArray
 			End If
 			data = d
 		End If
-		
+
 		data[size] = value
 		size :+ 1
 		guard.Unlock()
 	End Method
-	
+
 	Method RemoveLast:Int()
 		guard.Lock()
 		Local v:Int
-		
+
 		If size > 0 Then
 			size :- 1
 			v = data[size]
 		Else
 			v = $FFFFFFFF
 		End If
-		
+
 		guard.Unlock()
-		
+
 		Return v
 	End Method
 
@@ -261,27 +261,26 @@ Type TDynamicArray
 		free_(data)
 		CloseMutex(guard)
 	End Method
-	
+
 End Type
 
 Global glewIsInit:Int
 
 Public
 
-Type TGLImageFrame Extends TImageFrame
 
-	Field u0:Float,v0:Float,u1:Float,v1:Float,uscale:Float,vscale:Float
+Type TGLImageFrame Extends TImageFrame
+	Field u0:Float, v0:Float, u1:Float, v1:Float, uscale:Float, vscale:Float
+	Field name:Int, seq:Int
 
-	Field name:Int,seq:Int
-	
 	Method New()
-		seq=GraphicsSeq
+		seq = GraphicsSeq
 	End Method
-	
+
 	Method Delete()
-		If Not seq Return
-		DeleteTex name,seq
-		seq=0
+		If Not seq Then Return
+		DeleteTex( name, seq )
+		seq = 0
 	End Method
 	
 	Method Draw( x0:Float,y0:Float,x1:Float,y1:Float,tx:Float,ty:Float,sx:Float,sy:Float,sw:Float,sh:Float ) Override
@@ -305,52 +304,52 @@ Type TGLImageFrame Extends TImageFrame
 		glEnd
 	End Method
 	
-	Function CreateFromPixmap:TGLImageFrame( src:TPixmap,flags:Int )
+	Function CreateFromPixmap:TGLImageFrame( src:TPixmap, flags:Int )
 		'determine tex size
-		Local tex_w:Int=src.width
-		Local tex_h:Int=src.height
-		AdjustTexSize tex_w,tex_h
+		Local tex_w:Int = src.width
+		Local tex_h:Int = src.height
+		AdjustTexSize( tex_w, tex_h )
 		
 		'make sure pixmap fits texture
-		Local width:Int=Min( src.width,tex_w )
-		Local height:Int=Min( src.height,tex_h )
-		If src.width<>width Or src.height<>height src=ResizePixmap( src,width,height )
+		Local width:Int = Min( src.width, tex_w )
+		Local height:Int = Min( src.height, tex_h )
+		If src.width <> width Or src.height <> height Then src = ResizePixmap( src, width, height )
 
 		'create texture pixmap
-		Local tex:TPixmap=src
+		Local tex:TPixmap = src
 		
 		'"smear" right/bottom edges if necessary
-		If width<tex_w Or height<tex_h
-			tex=TPixmap.Create( tex_w,tex_h,PF_RGBA8888 )
-			tex.Paste src,0,0
-			If width<tex_w
-				tex.Paste src.Window( width-1,0,1,height ),width,0
+		If width < tex_w Or height < tex_h
+			tex = TPixmap.Create( tex_w, tex_h, PF_RGBA8888 )
+			tex.Paste( src, 0, 0 )
+			If width < tex_w
+				tex.Paste( src.Window( width - 1, 0, 1, height ), width, 0 )
 			EndIf
-			If height<tex_h
-				tex.Paste src.Window( 0,height-1,width,1 ),0,height
-				If width<tex_w 
-					tex.Paste src.Window( width-1,height-1,1,1 ),width,height
+			If height < tex_h
+				tex.Paste( src.Window( 0, height - 1, width, 1 ), 0, height )
+				If width < tex_w 
+					tex.Paste( src.Window( width - 1, height - 1, 1, 1 ), width, height )
 				EndIf
 			EndIf
 		Else
-			If tex.dds_fmt=0 ' not dds
-				If tex.format<>PF_RGBA8888 tex=tex.Convert( PF_RGBA8888 )
+			If tex.dds_fmt = 0 ' not dds
+				If tex.format <> PF_RGBA8888 Then tex = tex.Convert( PF_RGBA8888 )
 			EndIf
 		EndIf
 		
 		'create tex
-		Local name:Int=CreateTex( tex_w,tex_h,flags,tex )
+		Local name:Int = CreateTex( tex_w, tex_h, flags, tex )
 		
 		'upload it
-		UploadTex tex,flags
+		UploadTex( tex, flags )
 
 		'done!
-		Local frame:TGLImageFrame=New TGLImageFrame
-		frame.name=name
-		frame.uscale=1.0/tex_w
-		frame.vscale=1.0/tex_h
-		frame.u1=width * frame.uscale
-		frame.v1=height * frame.vscale
+		Local frame:TGLImageFrame = New TGLImageFrame
+		frame.name = name
+		frame.uscale = 1.0 / tex_w
+		frame.vscale = 1.0 / tex_h
+		frame.u1 = width * frame.uscale
+		frame.v1 = height * frame.vscale
 		Return frame
 
 	End Function
@@ -369,7 +368,7 @@ Type TGLSDLRenderImageFrame Extends TGLImageFrame
 		Local u0:Float = sx * uscale
 		Local v0:Float = (sy + sh) * vscale
 		Local u1:Float = (sx + sw) * uscale
-		Local v1:Float = sy * vscale	
+		Local v1:Float = sy * vscale
 		
 		EnableTex name
 		glBegin GL_QUADS
@@ -446,8 +445,8 @@ EndType
 
 Type TGLMax2DDriver Extends TMax2DDriver
 	Method Create:TGLMax2DDriver()
-		If Not SDLGraphicsDriver() Return Null
-		
+		If Not SDLGraphicsDriver() Then Return Null
+	
 		Return Self
 	End Method
 
@@ -455,14 +454,14 @@ Type TGLMax2DDriver Extends TMax2DDriver
 	Method GraphicsModes:TGraphicsMode[]() Override
 		Return SDLGraphicsDriver().GraphicsModes()
 	End Method
-	
+
 	Method AttachGraphics:TMax2DGraphics( widget:Byte Ptr,flags:Long ) Override
-		Local g:TSDLGraphics=SDLGraphicsDriver().AttachGraphics( widget,flags )
+		Local g:TSDLGraphics = SDLGraphicsDriver().AttachGraphics( widget,flags )
 		If g Return TMax2DGraphics.Create( g,Self )
 	End Method
 	
 	Method CreateGraphics:TMax2DGraphics( width:Int,height:Int,depth:Int,hertz:Int,flags:Long,x:Int,y:Int ) Override
-		Local g:TSDLGraphics=SDLGraphicsDriver().CreateGraphics( width,height,depth,hertz,flags | SDL_GRAPHICS_GL,x,y )
+		Local g:TSDLGraphics = SDLGraphicsDriver().CreateGraphics( width,height,depth,hertz,flags | SDL_GRAPHICS_GL,x,y )
 		If g Return TMax2DGraphics.Create( g,Self )
 	End Method
 	
@@ -472,8 +471,8 @@ Type TGLMax2DDriver Extends TMax2DDriver
 			SDLGraphicsDriver().SetGraphics Null
 			Return
 		EndIf
-	
-		Local t:TMax2DGraphics=TMax2DGraphics(g)
+
+		Local t:TMax2DGraphics = TMax2DGraphics( g )
 		Assert t And TSDLGraphics( t._backendGraphics )
 
 		SDLGraphicsDriver().SetGraphics(t._backendGraphics)
@@ -484,13 +483,14 @@ Type TGLMax2DDriver Extends TMax2DDriver
 	End Method
 	
 	Method ResetGLContext( g:TGraphics )
-		Local gw:Int,gh:Int,gd:Int,gr:Int,gf:Long,gx:Int,gy:Int
-		g.GetSettings gw,gh,gd,gr,gf,gx,gy
+		Local gw:Int, gh:Int, gd:Int, gr:Int, gf:Long, gx:Int, gy:Int
+		g.GetSettings( gw, gh, gd, gr, gf, gx, gy )
 		
-		state_blend=0
-		state_boundtex=0
-		state_texenabled=0
-		glDisable GL_TEXTURE_2D
+		state_blend = 0
+		state_boundtex = 0
+		state_texenabled = 0
+		glDisable( GL_TEXTURE_2D )
+
 		glMatrixMode GL_PROJECTION
 		glLoadIdentity
 		glOrtho 0,gw,gh,0,-1,1
@@ -509,62 +509,64 @@ Type TGLMax2DDriver Extends TMax2DDriver
 	End Method
 	
 	Method Flip:Int( sync:Int ) Override
-		SDLGraphicsDriver().Flip sync
+		SDLGraphicsDriver().Flip(sync)
 	End Method
 	
 	Method ToString:String() Override
 		Return "OpenGL"
 	End Method
 
-	Method CreateFrameFromPixmap:TGLImageFrame( pixmap:TPixmap,flags:Int ) Override
-		Return TGLImageFrame.CreateFromPixmap( pixmap,flags )
+	Method CreateFrameFromPixmap:TGLImageFrame( pixmap:TPixmap, flags:Int ) Override
+		Return TGLImageFrame.CreateFromPixmap( pixmap, flags )
 	End Method
 
 	Method SetBlend( blend:Int ) Override
-		If blend=state_blend Return
-		state_blend=blend
+		If state_blend = blend Return
+
+		state_blend = blend
+
 		Select blend
 		Case MASKBLEND
-			glDisable GL_BLEND
-			glEnable GL_ALPHA_TEST
-			glAlphaFunc GL_GEQUAL,.5
+			glDisable( GL_BLEND )
+			glEnable( GL_ALPHA_TEST )
+			glAlphaFunc( GL_GEQUAL, 0.5 )
 		Case SOLIDBLEND
-			glDisable GL_BLEND
-			glDisable GL_ALPHA_TEST
+			glDisable( GL_BLEND )
+			glDisable( GL_ALPHA_TEST )
 		Case ALPHABLEND
-			glEnable GL_BLEND
-			glBlendFunc GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA
-			glDisable GL_ALPHA_TEST
+			glEnable( GL_BLEND )
+			glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA )
+			glDisable( GL_ALPHA_TEST )
 		Case LIGHTBLEND
-			glEnable GL_BLEND
-			glBlendFunc GL_SRC_ALPHA,GL_ONE
-			glDisable GL_ALPHA_TEST
+			glEnable( GL_BLEND )
+			glBlendFunc( GL_SRC_ALPHA, GL_ONE )
+			glDisable( GL_ALPHA_TEST )
 		Case SHADEBLEND
-			glEnable GL_BLEND
-			glBlendFunc GL_DST_COLOR,GL_ZERO
-			glDisable GL_ALPHA_TEST
+			glEnable( GL_BLEND )
+			glBlendFunc( GL_DST_COLOR, GL_ZERO )
+			glDisable( GL_ALPHA_TEST )
 		Default
-			glDisable GL_BLEND
-			glDisable GL_ALPHA_TEST
+			glDisable( GL_BLEND )
+			glDisable( GL_ALPHA_TEST )
 		End Select
 	End Method
 
 	Method SetAlpha( alpha:Float ) Override
-		If alpha>1.0 alpha=1.0
-		If alpha<0.0 alpha=0.0
-		color4ub[3]=alpha*255
-		glColor4ubv color4ub
+		If alpha > 1.0 Then alpha = 1.0
+		If alpha < 0.0 Then alpha = 0.0
+		color4ub[3] = alpha * 255
+		glColor4ubv( color4ub )
 	End Method
 
 	Method SetLineWidth( width:Float ) Override
-		glLineWidth width
+		glLineWidth( width )
 	End Method
 	
 	Method SetColor( red:Int,green:Int,blue:Int ) Override
-		color4ub[0]=Min(Max(red,0),255)
-		color4ub[1]=Min(Max(green,0),255)
-		color4ub[2]=Min(Max(blue,0),255)
-		glColor4ubv color4ub
+		color4ub[0] = Min( Max( red, 0 ), 255 )
+		color4ub[1] = Min( Max( green, 0 ), 255 )
+		color4ub[2] = Min( Max( blue, 0 ), 255 )
+		glColor4ubv( color4ub )
 	End Method
 
 	Method SetClsColor( red:Int, green:Int, blue:Int, alpha:Float ) Override
@@ -575,7 +577,7 @@ Type TGLMax2DDriver Extends TMax2DDriver
 		glClearColor(red/255.0, green/255.0, blue/255.0, alpha)
 	End Method
 	
-	Method SetViewport( x:Int,y:Int,w:Int,h:Int ) Override
+	Method SetViewport( x:Int, y:Int, w:Int, h:Int ) Override
 		_GLScissor_BMaxViewport.x = x
 		_GLScissor_BMaxViewport.y = y
 		_GLScissor_BMaxViewport.width = w
@@ -584,117 +586,119 @@ Type TGLMax2DDriver Extends TMax2DDriver
 	End Method
 
 	Method SetTransform( xx:Float,xy:Float,yx:Float,yy:Float ) Override
-		ix=xx
-		iy=xy
-		jx=yx
-		jy=yy
+		ix = xx
+		iy = xy
+		jx = yx
+		jy = yy
 	End Method
 
 	Method Cls() Override
-		glClear GL_COLOR_BUFFER_BIT
+		glClear( GL_COLOR_BUFFER_BIT )
 	End Method
 
-	Method Plot( x:Float,y:Float ) Override
-		DisableTex
-		glBegin GL_POINTS
-		glVertex2f x+.5,y+.5
-		glEnd
+	Method Plot( x:Float, y:Float ) Override
+		DisableTex()
+		glBegin( GL_POINTS )
+		glVertex2f( x+.5,y+.5 )
+		glEnd()
 	End Method
 
-	Method DrawLine( x0:Float,y0:Float,x1:Float,y1:Float,tx:Float,ty:Float ) Override
-		DisableTex
-		glBegin GL_LINES
-		glVertex2f x0*ix+y0*iy+tx+.5,x0*jx+y0*jy+ty+.5
-		glVertex2f x1*ix+y1*iy+tx+.5,x1*jx+y1*jy+ty+.5
-		glEnd
+	Method DrawLine( x0:Float, y0:Float, x1:Float, y1:Float, tx:Float, ty:Float ) Override
+		DisableTex()
+		glBegin( GL_LINES )
+		glVertex2f( x0 * ix + y0 * iy + tx + .5, x0 * jx + y0 * jy + ty + .5 )
+		glVertex2f( x1 * ix + y1 * iy + tx + .5, x1 * jx + y1 * jy + ty + .5 )
+		glEnd()
 	End Method
 
-	Method DrawRect( x0:Float,y0:Float,x1:Float,y1:Float,tx:Float,ty:Float ) Override
-		DisableTex
-		glBegin GL_QUADS
-		glVertex2f x0*ix+y0*iy+tx,x0*jx+y0*jy+ty
-		glVertex2f x1*ix+y0*iy+tx,x1*jx+y0*jy+ty
-		glVertex2f x1*ix+y1*iy+tx,x1*jx+y1*jy+ty
-		glVertex2f x0*ix+y1*iy+tx,x0*jx+y1*jy+ty
-		glEnd
+	Method DrawRect( x0:Float, y0:Float, x1:Float, y1:Float, tx:Float, ty:Float ) Override
+		DisableTex()
+		glBegin( GL_QUADS )
+		glVertex2f( x0 * ix + y0 * iy + tx, x0 * jx + y0 * jy + ty )
+		glVertex2f( x1 * ix + y0 * iy + tx, x1 * jx + y0 * jy + ty )
+		glVertex2f( x1 * ix + y1 * iy + tx, x1 * jx + y1 * jy + ty )
+		glVertex2f( x0 * ix + y1 * iy + tx, x0 * jx + y1 * jy + ty )
+		glEnd()
 	End Method
 	
 	Method DrawOval( x0:Float,y0:Float,x1:Float,y1:Float,tx:Float,ty:Float ) Override
-	
-		Local xr:Float=(x1-x0)*.5
-		Local yr:Float=(y1-y0)*.5
-		Local segs:Int=Abs(xr)+Abs(yr)
-		
-		segs=Max(segs,12)&~3
-
-		x0:+xr
-		y0:+yr
-		
-		DisableTex
-		glBegin GL_POLYGON
-		For Local i:Int=0 Until segs
-			Local th:Float=i*360:Float/segs
-			Local x:Float=x0+Cos(th)*xr
-			Local y:Float=y0-Sin(th)*yr
-			glVertex2f x*ix+y*iy+tx,x*jx+y*jy+ty
+		Local xr:Float = ( x1 - x0 ) * 0.5
+		Local yr:Float = ( y1 - y0 ) * 0.5
+		Local segs:Int = Abs( xr ) + Abs( yr )
+
+		segs = Max( segs, 12 ) &~ 3
+
+		x0 :+ xr
+		y0 :+ yr
+
+		DisableTex()
+		glBegin( GL_POLYGON )
+		For Local i:Int = 0 Until segs
+			Local th:Float = i * 360.0 / segs
+			Local x:Float = x0 +Cos(th) * xr
+			Local y:Float = y0 -Sin(th) * yr
+			glVertex2f( x * ix + y * iy + tx, x * jx + y * jy + ty )
 		Next
-		glEnd
-		
+		glEnd()
 	End Method
 	
-	Method DrawPoly( xy:Float[],handle_x:Float,handle_y:Float,origin_x:Float,origin_y:Float, indices:Int[] ) Override
-		If xy.length<6 Or (xy.length&1) Return
-		
-		DisableTex
-		glBegin GL_POLYGON
-		For Local i:Int=0 Until Len xy Step 2
-			Local x:Float=xy[i+0]+handle_x
-			Local y:Float=xy[i+1]+handle_y
-			glVertex2f x*ix+y*iy+origin_x,x*jx+y*jy+origin_y
+	Method DrawPoly( xy:Float[], handle_x:Float, handle_y:Float, origin_x:Float, origin_y:Float, indices:Int[] ) Override
+		If xy.length < 6 Or ( xy.length & 1 ) Then Return
+
+		DisableTex()
+		glBegin( GL_POLYGON )
+		For Local i:Int = 0 Until xy.length Step 2
+			Local x:Float = xy[i + 0] + handle_x
+			Local y:Float = xy[i + 1] + handle_y
+			glVertex2f( x * ix + y * iy + origin_x, x * jx + y * jy + origin_y )
 		Next
-		glEnd
+		glEnd()
 	End Method
-		
-	Method DrawPixmap( p:TPixmap,x:Int,y:Int ) Override
-		Local blend:Int=state_blend
-		DisableTex
-		SetBlend SOLIDBLEND
+
+	Method DrawPixmap( p:TPixmap, x:Int, y:Int ) Override
+		Local blend:Int = state_blend
+		DisableTex()
+		SetBlend( SOLIDBLEND )
 	
-		Local t:TPixmap=p
-		If t.format<>PF_RGBA8888 t=ConvertPixmap( t,PF_RGBA8888 )
-
-		glPixelZoom 1,-1
-		glRasterPos2i 0,0
-		glBitmap 0,0,0,0,x,-y,Null
-		glPixelStorei GL_UNPACK_ROW_LENGTH, t.pitch Shr 2
-		glDrawPixels t.width,t.height,GL_RGBA,GL_UNSIGNED_BYTE,t.pixels
-		glPixelStorei GL_UNPACK_ROW_LENGTH,0
-		glPixelZoom 1,1
+		Local t:TPixmap = p
+		If t.format <> PF_RGBA8888 Then t = ConvertPixmap( t, PF_RGBA8888 )
+
+		glPixelZoom( 1, -1 )
+		glRasterPos2i( 0, 0 )
+		glBitmap( 0, 0, 0, 0, x, -y, Null)
+		glPixelStorei( GL_UNPACK_ROW_LENGTH, t.pitch Shr 2 )
+		glDrawPixels( t.width, t.height, GL_RGBA, GL_UNSIGNED_BYTE, t.pixels )
+		glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 )
+		glPixelZoom( 1, 1 )
 		
-		SetBlend blend
+		SetBlend( blend )
 	End Method
 
-	Method GrabPixmap:TPixmap( x:Int,y:Int,w:Int,h:Int ) Override
-		Local blend:Int=state_blend
-		SetBlend SOLIDBLEND
-		Local p:TPixmap=CreatePixmap( w,h,PF_RGBA8888 )
+	Method GrabPixmap:TPixmap( x:Int, y:Int, w:Int, h:Int ) Override
+		Local blend:Int = state_blend
+		SetBlend( SOLIDBLEND )
+		Local p:TPixmap=CreatePixmap( w, h, PF_RGBA8888 )
 
 		'The default backbuffer in Max2D was opaque so overwrote any
 		'trash data of a freshly created pixmap. Potentially transparent
 		'backbuffers require a complete transparent pixmap to start with.
 		p.ClearPixels(0)
 		
-		glReadPixels x,GraphicsHeight()-h-y,w,h,GL_RGBA,GL_UNSIGNED_BYTE,p.pixels
-		p=YFlipPixmap( p )
-		SetBlend blend
+		If _CurrentRenderImageFrame and _CurrentRenderImageFrame <> _BackbufferRenderImageFrame
+			glReadPixels(x, _CurrentRenderImageFrame.height - h - y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, p.pixels)
+		Else
+			glReadPixels(x, _BackbufferRenderImageFrame.height - h - y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, p.pixels)
+		EndIf
+		p = YFlipPixmap( p )
+		SetBlend( blend )
 		Return p
 	End Method
 	
-	Method SetResolution( width:Float,height:Float ) Override
-		glMatrixMode GL_PROJECTION
-		glLoadIdentity
-		glOrtho 0,width,height,0,-1,1
-		glMatrixMode GL_MODELVIEW
+	Method SetResolution( width:Float, height:Float ) Override
+		glMatrixMode( GL_PROJECTION )
+		glLoadIdentity()
+		glOrtho( 0, width, height, 0, -1, 1 )
+		glMatrixMode( GL_MODELVIEW )
 	End Method
 
 	Method CreateRenderImageFrame:TImageFrame(width:UInt, height:UInt, flags:Int) Override