123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498 |
- ' Copyright (c) 2021-2022 Bruce A Henderson
- '
- ' This software is provided 'as-is', without any express or implied
- ' warranty. In no event will the authors be held liable for any damages
- ' arising from the use of this software.
- '
- ' Permission is granted to anyone to use this software for any purpose,
- ' including commercial applications, and to alter it and redistribute it
- ' freely, subject to the following restrictions:
- '
- ' 1. The origin of this software must not be misrepresented; you must not
- ' claim that you wrote the original software. If you use this software
- ' in a product, an acknowledgment in the product documentation would be
- ' appreciated but is not required.
- '
- ' 2. Altered source versions must be plainly marked as such, and must not be
- ' misrepresented as being the original software.
- '
- ' 3. This notice may not be removed or altered from any source
- ' distribution.
- '
- SuperStrict
- Rem
- bbdoc: Graphics/SDLRender Max2D
- about:
- The SDLRender Max2D module provides an SDL-backend SDLRender driver for #Max2D.
- End Rem
- Module SDL.SDLRenderMax2D
- ModuleInfo "Version: 1.00"
- ModuleInfo "License: zlib/libpng"
- ModuleInfo "History: 1.00"
- ModuleInfo "History: Initial release"
- Import BRL.Max2D
- Import SDL.SDLGraphics
- Import SDL.SDLRender
- Private
- Global _driver:TSDLRenderMax2DDriver
- Function Pow2Size:Int( n:Int )
- Local t:Int = 1
- While t < n
- t :* 2
- Wend
- Return t
- End Function
- Function AdjustTexSize( width:Int Var, height:Int Var )
- 'calc texture size
- width = Pow2Size( width )
- height = Pow2Size( height )
- End Function
- Public
- Type TSDLRenderImageFrame Extends TImageFrame
- Field u0#, v0#, u1#, v1#, uscale#, vscale#
- Field pixmap:TPixmap
- Field surface:TSDLSurface
- Field texture:TSDLTexture
- Field renderer:TSDLRenderer
-
- Method New()
- End Method
-
- Method Delete()
- If texture Then
- texture.Destroy()
- texture = Null
- End If
- If surface Then
- surface.Free()
- surface = Null
- End If
- pixmap = Null
- End Method
-
- Method Draw( x0#,y0#,x1#,y1#,tx#,ty#,sx#,sy#,sw#,sh# ) Override
- Local u0# = sx * uscale
- Local v0# = sy * vscale
- Local u1# = ( sx + sw ) * uscale
- Local v1# = ( sy + sh ) * vscale
- _driver.DrawTexture( texture, u0, v0, u1, v1, x0, y0, x1, y1, tx, ty, Self )
- End Method
-
- Function CreateFromPixmap:TSDLRenderImageFrame( src:TPixmap,flags:Int )
-
- Local tex_w:Int = src.width
- Local tex_h:Int = src.height
-
- Local width:Int = Min( src.width, tex_w )
- Local height:Int = Min( src.height, tex_h )
-
- If src.format <> PF_RGBA8888 And src.format <> PF_RGB888 Then
- src = src.Convert( PF_RGBA8888 )
- End If
- 'done!
- Local frame:TSDLRenderImageFrame=New TSDLRenderImageFrame
- frame.renderer = _driver.renderer
- frame.pixmap = src
- frame.surface = TSDLSurface.CreateRGBFrom(src.pixels, src.width, src.height, BitsPerPixel[src.format], src.pitch, $000000ff:UInt, $0000ff00:UInt, $00ff0000:UInt, $ff000000:UInt)
- frame.texture = frame.renderer.CreateTextureFromSurface(frame.surface)
- 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
- End Type
- Type TSDLRenderMax2DDriver Extends TMax2DDriver
- Field drawColor:SDLColor = New SDLColor(255, 255, 255, 255)
- Field clsColor:SDLColor = New SDLColor(0, 0, 0, 255)
- Field renderer:TSDLRenderer
- Field ix#,iy#,jx#,jy#
- Field state_blend:Int
- Method Create:TSDLRenderMax2DDriver()
- If Not SDLGraphicsDriver() Return Null
-
- Return Self
- End Method
- '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 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,x,y )
- If g Return TMax2DGraphics.Create( g,Self )
- End Method
-
- Method SetGraphics( g:TGraphics ) Override
- If Not g
- TMax2DGraphics.ClearCurrent
- SDLGraphicsDriver().SetGraphics Null
- Return
- EndIf
-
- Local t:TMax2DGraphics=TMax2DGraphics(g)
- Assert t And TSDLGraphics( t._graphics )
- Local gfx:TSDLGraphics = TSDLGraphics( t._graphics )
- SDLGraphicsDriver().SetGraphics gfx
- renderer = TSDLRenderer.Create(gfx._context.window)
- 'ResetGLContext t
-
- t.MakeCurrent
- End Method
- Method Flip:Int( sync:Int ) Override
- renderer.Present()
- End Method
-
- Method ToString$() Override
- Return "SDLRenderer"
- End Method
- Method CreateFrameFromPixmap:TSDLRenderImageFrame( pixmap:TPixmap,flags:Int ) Override
- Local frame:TSDLRenderImageFrame
- frame=TSDLRenderImageFrame.CreateFromPixmap( pixmap,flags )
- Return frame
- End Method
- Method SetBlend( blend:Int ) Override
- If blend=state_blend Return
- state_blend=blend
- Select blend
- Case MASKBLEND
- renderer.SetDrawBlendMode(SDL_BLENDMODE_BLEND)
- Case SOLIDBLEND
- renderer.SetDrawBlendMode(SDL_BLENDMODE_NONE)
- Case ALPHABLEND
- renderer.SetDrawBlendMode(SDL_BLENDMODE_BLEND)
- Case LIGHTBLEND
- renderer.SetDrawBlendMode(SDL_BLENDMODE_ADD)
- Case SHADEBLEND
- renderer.SetDrawBlendMode(SDL_BLENDMODE_MOD)
- Default
- renderer.SetDrawBlendMode(SDL_BLENDMODE_NONE)
- End Select
- End Method
- Method SetAlpha( alpha# ) Override
- If alpha>1.0 alpha=1.0
- If alpha<0.0 alpha=0.0
- drawColor.a=alpha*255
- End Method
- Method SetLineWidth( width# ) Override
- 'glLineWidth width
- End Method
-
- Method SetColor( red:Int,green:Int,blue:Int ) Override
- drawColor.r = Min(Max(red,0),255)
- drawColor.g = Min(Max(green,0),255)
- drawColor.b = Min(Max(blue,0),255)
- renderer.SetDrawColor(drawColor.r, drawColor.g, drawColor.b, drawColor.a)
- End Method
- Method SetColor( color:SColor8 ) Override
- drawColor.r=color.r
- drawColor.g=color.g
- drawColor.b=color.b
- renderer.SetDrawColor(drawColor.r, drawColor.g, drawColor.b, drawColor.a)
- End Method
- Method SetClsColor( red:Int,green:Int,blue:Int ) Override
- clsColor.r = Min(Max(red,0),255)
- clsColor.g = Min(Max(green,0),255)
- clsColor.b = Min(Max(blue,0),255)
- clsColor.a = 255
- End Method
- Method SetClsColor( color:SColor8 ) Override
- clsColor.r=color.r
- clsColor.g=color.g
- clsColor.b=color.b
- clsColor.a = 255
- End Method
-
- Method SetViewport( x:Int,y:Int,w:Int,h:Int ) Override
- If x=0 And y=0 And w=GraphicsWidth() And h=GraphicsHeight()
- renderer.SetViewport()
- Else
- renderer.SetViewport(x, y, w, h)
- EndIf
- End Method
- Method SetTransform( xx#,xy#,yx#,yy# ) Override
- ix=xx
- iy=xy
- jx=yx
- jy=yy
- End Method
- Method Cls() Override
- renderer.SetDrawColor(clsColor.r, clsColor.g, clsColor.b, clsColor.a)
- renderer.Clear()
- renderer.SetDrawColor(drawColor.r, drawColor.g, drawColor.b, drawColor.a)
- End Method
- Method Plot( x#,y# ) Override
- renderer.DrawPoint(Int(x+.5),Int(y+.5))
- End Method
- Method DrawLine( x0#,y0#,x1#,y1#,tx#,ty# ) Override
- renderer.DrawLine(Int(x0*ix+y0*iy+tx+.5), Int(x0*jx+y0*jy+ty+.5), Int(x1*ix+y1*iy+tx+.5), Int(x1*jx+y1*jy+ty+.5))
- End Method
- Method DrawRect( x0#,y0#,x1#,y1#,tx#,ty# ) Override
- Local StaticArray vertices:SDLVertex[4]
- Local vert:SDLVertex Ptr = vertices
- vert.position.x = x0 * ix + y0 * iy + tx
- vert.position.y = x0 * jx + y0 * jy + ty
- vert.color = _driver.drawColor
- vert :+ 1
- vert.position.x = x1 * ix + y0 * iy + tx
- vert.position.y = x1 * jx + y0 * jy + ty
- vert.color = _driver.drawColor
- vert :+ 1
- vert.position.x = x1 * ix + y1 * iy + tx
- vert.position.y = x1 * jx + y1 * jy + ty
- vert.color = _driver.drawColor
- vert :+ 1
- vert.position.x = x0 * ix + y1 * iy + tx
- vert.position.y = x0 * jx + y1 * jy + ty
- vert.color = _driver.drawColor
- Local StaticArray indices:Int[6]
- indices[0] = 0
- indices[1] = 2
- indices[2] = 1
- indices[3] = 0
- indices[4] = 3
- indices[5] = 2
- renderer.Geometry(Null, vertices, 4, indices, 6)
- End Method
-
- Method DrawOval( x0#,y0#,x1#,y1#,tx#,ty# ) Override
- Local StaticArray vertices:SDLVertex[50]
- Local vert:SDLVertex Ptr = vertices
- Local vc:int
- Local StaticArray indices:Int[147]
- local ic:int
- Local xr#=(x1-x0)*.5
- Local yr#=(y1-y0)*.5
- local r:Float = (xr + yr) * 0.5
- Local segs:Int = Min(49, 360 / acos(2 * (1 - 0.5 / r)^2 - 1))
- x0:+xr
- y0:+yr
- ' center
- vert.position.x = x0 * ix + y0 * iy + tx
- vert.position.y = x0 * jx + y0 * jy + ty
- vert.color = _driver.drawColor
- vert :+ 1
- vc :+ 1
-
- For Local i:Int=0 Until segs
- Local th#=i*360#/segs
- Local x#=x0+Cos(th)*xr
- Local y#=y0-Sin(th)*yr
- vert.position.x = x * ix + y * iy + tx
- vert.position.y = x * jx + y * jy + ty
- vert.color = _driver.drawColor
- vert :+ 1
- vc :+ 1
- Next
- For Local i:Int=0 Until segs - 1
- indices[i * 3] = 0
- indices[i * 3 + 1] = i + 1
- indices[i * 3 + 2] = i + 2
- ic :+ 3
- Next
- ' connect last & first
- Local i:Int = segs - 1
- indices[i * 3] = 0
- indices[i * 3 + 1] = i + 1
- indices[i * 3 + 2] = 1
- ic :+ 3
- renderer.Geometry(Null, vertices, vc, indices, ic)
- End Method
-
- Method DrawPoly( xy#[],handle_x#,handle_y#,origin_x#,origin_y# ) Override
- rem
- 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#=xy[i+0]+handle_x
- Local y#=xy[i+1]+handle_y
- glVertex2f x*ix+y*iy+origin_x,x*jx+y*jy+origin_y
- Next
- glEnd
- end rem
- End Method
-
- Method DrawPixmap( p:TPixmap,x:Int,y:Int ) Override
- rem
- 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
-
- SetBlend blend
- end rem
- End Method
- Method DrawTexture( texture:TSDLTexture, u0#, v0#, u1#, v1#, x0#, y0#, x1#, y1#, tx#, ty#, img:TImageFrame = Null )
- Local StaticArray vertices:SDLVertex[4]
- Local vert:SDLVertex Ptr = vertices
- vert.position.x = x0 * ix + y0 * iy + tx
- vert.position.y = x0 * jx + y0 * jy + ty
- vert.color = _driver.drawColor
- vert.texCoord.x = u0
- vert.texCoord.y = v0
- vert :+ 1
- vert.position.x = x1 * ix + y0 * iy + tx
- vert.position.y = x1 * jx + y0 * jy + ty
- vert.color = _driver.drawColor
- vert.texCoord.x = u1
- vert.texCoord.y = v0
- vert :+ 1
- vert.position.x = x1 * ix + y1 * iy + tx
- vert.position.y = x1 * jx + y1 * jy + ty
- vert.color = _driver.drawColor
- vert.texCoord.x = u1
- vert.texCoord.y = v1
- vert :+ 1
- vert.position.x = x0 * ix + y1 * iy + tx
- vert.position.y = x0 * jx + y1 * jy + ty
- vert.color = _driver.drawColor
- vert.texCoord.x = u0
- vert.texCoord.y = v1
- Local StaticArray indices:Int[6]
- indices[0] = 0
- indices[1] = 2
- indices[2] = 1
- indices[3] = 0
- indices[4] = 3
- indices[5] = 2
- Select state_blend
- Case ALPHABLEND
- texture.SetBlendMode(SDL_BLENDMODE_BLEND)
- Case MASKBLEND
- texture.SetBlendMode(SDL_BLENDMODE_BLEND)
- Case SOLIDBLEND
- texture.SetBlendMode(SDL_BLENDMODE_NONE)
- Case LIGHTBLEND
- texture.SetBlendMode(SDL_BLENDMODE_ADD)
- Case SHADEBLEND
- texture.SetBlendMode(SDL_BLENDMODE_MOD)
- Default
- texture.SetBlendMode(SDL_BLENDMODE_NONE)
- End Select
- renderer.Geometry(texture, vertices, 4, indices, 6)
- End Method
- Method GrabPixmap:TPixmap( x:Int,y:Int,w:Int,h:Int ) Override
- rem
- Local blend:Int=state_blend
- SetBlend SOLIDBLEND
- Local p:TPixmap=CreatePixmap( w,h,PF_RGBA8888 )
- glReadPixels x,GraphicsHeight()-h-y,w,h,GL_RGBA,GL_UNSIGNED_BYTE,p.pixels
- p=YFlipPixmap( p )
- SetBlend blend
- Return p
- end rem
- End Method
-
- Method SetResolution( width#,height# ) Override
- renderer.SetLogicalSize(Int(width), Int(height))
- End Method
-
- End Type
- Rem
- bbdoc: Get SDLRender Max2D Driver
- about:
- The returned driver can be used with #SetGraphicsDriver to enable SDLRender Max2D
- rendering.
- End Rem
- Function SDLRenderMax2DDriver:TSDLRenderMax2DDriver()
- Global _done:Int
- If Not _done
- _driver=New TSDLRenderMax2DDriver.Create()
- _done=True
- EndIf
- Return _driver
- End Function
- Local driver:TSDLRenderMax2DDriver=SDLRenderMax2DDriver()
- If driver SetGraphicsDriver driver
|