| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- Namespace mojo.graphics
- #rem monkeydoc The Image class.
- An image is a rectangular array of pixels that can be drawn using one of the [[Canvas.DrawImage]] methods.
- You can load an image from a file using the [[Load]].
- #end
- Class Image
- #rem monkeydoc @hidden
- #end
- Field OnDiscarded:Void()
- #rem monkeydoc Creates a new image.
-
- New( pixmap,... ) allows you to create a new image from an existing pixmap.
-
- New( width,height,... ) allows you to create a new image that can be rendered to using a canvas. For images that will be frequently updated, use `TextureFlags.Filter|TextureFlags.Dynamic' for the best performance.
-
- New( image,rect,... ) allows you to create an image from within an 'atlas' image.
-
- @example
-
- Namespace myapp
-
- #Import "<std>"
- #Import "<mojo>"
-
- Using std..
- Using mojo..
-
- Class MyWindow Extends Window
-
- Field image1:Image
- Field image2:Image
- Field image3:Image
-
- Method New()
-
- 'Create an image from a pixmap
- Local pixmap:=New Pixmap( 16,16 )
- pixmap.Clear( Color.Red )
- image1=New Image( pixmap )
-
- 'Create an image and render something to it
- image2=New Image( 16,16 )
- Local icanvas:=New Canvas( image2 )
- icanvas.Color=Color.Yellow
- icanvas.DrawRect( 0,0,8,8 )
- icanvas.DrawRect( 8,8,8,8 )
- icanvas.Color=Color.LightGrey
- icanvas.DrawRect( 8,0,8,8 )
- icanvas.DrawRect( 0,8,8,8 )
- icanvas.Flush() 'Important!
-
- 'Create a image from an atlas image
- image3=New Image( image2,New Recti( 4,4,12,12 ) )
-
- End
-
- Method OnRender( canvas:Canvas ) Override
-
- canvas.DrawText( "Image1",0,0 )
- canvas.DrawImage( image1,0,16 )
-
- canvas.DrawText( "Image2",0,40 )
- canvas.DrawImage( image2,0,56 )
-
- canvas.DrawText( "Image3",0,80 )
- canvas.DrawImage( image3,0,96 )
-
- End
-
- End
-
- Function Main()
-
- New AppInstance
-
- New MyWindow
-
- App.Run()
- End
-
- @end
-
- #end
- Method New( pixmap:Pixmap,textureFlags:TextureFlags=TextureFlags.Filter|TextureFlags.Mipmap,shader:Shader=Null )
-
- Local texture:=New Texture( pixmap,textureFlags )
-
- Init( Null,texture,texture.Rect,shader )
-
- OnDiscarded+=Lambda()
- texture.Discard()
- End
- End
-
- Method New( width:Int,height:Int,textureFlags:TextureFlags=TextureFlags.Filter|TextureFlags.Mipmap,shader:Shader=Null )
-
- Local textureFormat:PixelFormat=PixelFormat.RGBA32
-
- Local texture:=New Texture( width,height,textureFormat,textureFlags )
-
- Init( Null,texture,texture.Rect,shader )
- OnDiscarded+=Lambda()
- texture.Discard()
- End
- End
-
- Method New( image:Image,rect:Recti )
-
- Init( image._material,image._texture,rect,Null )
- End
- #rem monkeydoc @hidden
- #end
- Method New( texture:Texture,shader:Shader=Null )
-
- Init( Null,texture,texture.Rect,shader )
- End
-
- #rem monkeydoc @hidden
- #end
- Method New( material:Material,texture:Texture,rect:Recti )
-
- Init( material,texture,rect,Null )
- End
-
- #rem monkeydoc @hidden
- #end
- Property Material:Material()
-
- Return _material
- End
-
- #rem monkeydoc @hidden
- #end
- Property Texture:Texture()
-
- Return _texture
- End
-
- #rem monkeydoc @hidden The image's rect within its texture.
- #end
- Property Rect:Recti()
-
- Return _rect
- End
-
- #rem monkeydoc The width of the image's rect within its texture.
- #end
- Property Width:Int()
-
- Return _rect.Width
- End
-
- #rem monkeydoc The height of the image's rect within its texture.
- #end
- Property Height:Int()
-
- Return _rect.Height
- End
- #rem monkeydoc The image handle.
-
- Image handle values are fractional, where 0,0 is the top-left of the image and 1,1 is the bottom-right.
- #end
- Property Handle:Vec2f()
-
- Return _handle
-
- Setter( handle:Vec2f )
-
- _handle=handle
-
- UpdateVertices()
- End
- #rem monkeydoc The image scale.
-
- The scale property provides a simple way to 'pre-scale' an image.
-
- Scaling an image this way is faster than using one of the 'scale' parameters of [[Canvas.DrawImage]].
-
- #end
- Property Scale:Vec2f()
-
- Return _scale
-
- Setter( scale:Vec2f )
-
- _scale=scale
-
- UpdateVertices()
- End
-
- #rem monkeydoc The image bounds.
-
- The bounds rect represents the actual image vertices used when the image is drawn.
-
- Image bounds are affected by [[Scale]] and [[Handle]], and can be used for simple collision detection.
-
- #end
- Property Bounds:Rectf()
-
- Return _bounds
- End
- #rem monkeydoc Image radius.
-
- The radius property returns the radius of the [[Bounds]] rect.
-
- Image bounds are affected by [[Scale]] and [[Handle]], and can be used for simple collision detection.
-
- #end
- Property Radius:Float()
-
- Return _radius
- End
-
- #rem monkeydoc @hidden
- #end
- Property Vertices:Rectf()
-
- Return _vertices
- End
-
- #rem monkeydoc @hidden
- #end
- Property TexCoords:Rectf()
-
- Return _texCoords
- End
-
- #rem monkeydoc Releases the image and any resource it uses.
- #end
- Method Discard()
- If _discarded Return
- _discarded=True
- OnDiscarded()
- End
-
- #rem monkeydoc Loads an image from a file.
- #end
- Function Load:Image( path:String,textureFlags:TextureFlags=TextureFlags.Filter|TextureFlags.Mipmap,shader:Shader=Null )
-
- Local diffuse:=mojo.graphics.Texture.Load( path,textureFlags )
- If Not diffuse Return Null
-
- Local file:=StripExt( path )
- Local ext:=ExtractExt( path )
-
- Local specular:=mojo.graphics.Texture.Load( file+"_SPECULAR"+ext,textureFlags )
- Local normal:=mojo.graphics.Texture.Load( file+"_NORMALS"+ext,textureFlags )
-
- If specular Or normal
- If Not specular specular=mojo.graphics.Texture.ColorTexture( Color.Black )
- If Not normal normal=mojo.graphics.Texture.ColorTexture( New Color( .5,.5,.5 ) )
- Endif
-
- If Not shader
- If specular Or normal
- shader=Shader.GetShader( "phong" )
- Else
- shader=Shader.GetShader( "sprite" )
- Endif
- Endif
-
- Local material:=New Material( shader )
-
- If diffuse material.SetTexture( "DiffuseTexture",diffuse )
- If specular material.SetTexture( "SpecularTexture",specular )
- If normal material.SetTexture( "NormalTexture",normal )
-
- Local image:=New Image( material,diffuse,diffuse.Rect )
-
- image.OnDiscarded+=Lambda()
- If diffuse diffuse.Discard()
- If specular specular.Discard()
- If normal normal.Discard()
- End
-
- Return image
- End
-
- Private
-
- Field _material:Material
- Field _texture:Texture
- Field _rect:Recti
- Field _discarded:Bool
- Field _handle:=New Vec2f( 0,0 )
- Field _scale:=New Vec2f( 1,1 )
- Field _vertices:Rectf
- Field _texCoords:Rectf
- Field _bounds:Rectf
- Field _radius:Float
-
- Method Init( material:Material,texture:Texture,rect:Recti,shader:Shader )
-
- If Not material
- If Not shader shader=Shader.GetShader( "sprite" )
- material=New Material( shader )
- material.SetTexture( "DiffuseTexture",texture )
- Endif
-
- _material=material
- _texture=texture
- _rect=rect
-
- UpdateVertices()
- UpdateTexCoords()
- End
-
- Method UpdateVertices()
- _vertices.min.x=Float(_rect.Width)*(0-_handle.x)*_scale.x
- _vertices.min.y=Float(_rect.Height)*(0-_handle.y)*_scale.y
- _vertices.max.x=Float(_rect.Width)*(1-_handle.x)*_scale.x
- _vertices.max.y=Float(_rect.Height)*(1-_handle.y)*_scale.y
- _bounds.min.x=Min( _vertices.min.x,_vertices.max.x )
- _bounds.max.x=Max( _vertices.min.x,_vertices.max.x )
- _bounds.min.y=Min( _vertices.min.y,_vertices.max.y )
- _bounds.max.y=Max( _vertices.min.y,_vertices.max.y )
- _radius=_bounds.min.x*_bounds.min.x+_bounds.min.y*_bounds.min.y
- _radius=Max( _radius,_bounds.max.x*_bounds.max.x+_bounds.min.y*_bounds.min.y )
- _radius=Max( _radius,_bounds.max.x*_bounds.max.x+_bounds.max.y*_bounds.max.y )
- _radius=Max( _radius,_bounds.min.x*_bounds.min.x+_bounds.max.y*_bounds.max.y )
- _radius=Sqrt( _radius )
- End
-
- Method UpdateTexCoords()
- _texCoords.min.x=Float(_rect.min.x)/_texture.Width
- _texCoords.min.y=Float(_rect.min.y)/_texture.Height
- _texCoords.max.x=Float(_rect.max.x)/_texture.Width
- _texCoords.max.y=Float(_rect.max.y)/_texture.Height
- End
-
- End
|