Ver código fonte

Added Canvas.TextureFilteringEnabled ; changed the TextureFlags system ; added managed dynamic texture support.

Mark Sibly 9 anos atrás
pai
commit
7d7ac1b925

+ 42 - 6
modules/mojo/graphics/canvas.monkey2

@@ -162,15 +162,20 @@ Class Canvas
 		_dirty|=Dirty.EnvParams
 	End
 	
-	Property FilteringEnabled:Bool()
+	#rem monkeydoc Texture filtering control.
+	
+	Set this to false to render cool 'pixel art' style graphics.
+	
+	#end
+	Property TextureFilteringEnabled:Bool()
 	
 		Return _filter
 	
-	Setter( filteringEnabled:Bool )
+	Setter( enabled:Bool )
 	
 		Flush()
 		
-		_filter=filteringEnabled
+		_filter=enabled
 	End
 	
 	#rem monkeydoc @hidden
@@ -217,7 +222,7 @@ Class Canvas
 		
 		Viewport=bounds
 		Scissor=New Recti( 0,0,bounds.Size )
-		FilteringEnabled=True
+		TextureFilteringEnabled=True
 		ClearMatrix()
 	End
 	
@@ -524,6 +529,8 @@ Class Canvas
 		DrawRect( New Rectf( x,y,x+width,y+height ),srcImage,New Recti( srcX,srcY,srcX+srcWidth,srcY+srcHeight ) )
 	End
 	
+	#rem monkeydoc Draws an oval.
+	#end
 	Method DrawOval( x:Float,y:Float,width:Float,height:Float )
 		Local xr:=width/2.0,yr:=height/2.0
 		
@@ -548,6 +555,20 @@ Class Canvas
 		Next
 	End
 	
+	#rem monkeydoc Draws an ellipse.
+	#end
+	Method DrawEllipse( x:Float,y:Float,xRadius:Float,yRadius:Float )
+		DrawOval( x-xRadius,y-yRadius,xRadius*2,yRadius*2 )
+	End
+	
+	#rem monkeydoc Draws a circle.
+	#end
+	Method DrawCircle( x:Float,y:Float,radius:Float )
+		DrawOval( x-radius,y-radius,radius*2,radius*2 )
+	End
+	
+	#rem monkeydoc Draws a polygon.
+	#end
 	Method DrawPoly( vertices:Float[] )
 		DebugAssert( vertices.Length>=6 And vertices.Length&1=0 )
 		
@@ -560,7 +581,22 @@ Class Canvas
 		Next
 	End
 	
-	#rem monkeydoc @hidden
+	#rem monkeydoc Draws a sequence of primtives.
+	
+	@param order The type of primitive: 1=points, 2=lines, 3=triangles, 4=quads, >4=n-gons.
+	
+	@param count The number of primitives to draw.
+	
+	@param vertices Pointer to the first vertex x,y pair.
+	
+	@param verticesPitch Number of bytes from one vertex x,y pair to the next - set to 8 for 'tightly packed' vertices.
+	
+	@param texCoords Pointer to the first texCoord s,t pair. This can be null.
+	
+	@param texCoordsPitch Number of bytes from one texCoord s,y to the next.
+	
+	@param indices Pointer to sequence of integer indices for indexed drawing. This can by null for non-indexed drawing.
+	
 	#end
 	Method DrawPrimitives( order:Int,count:Int,vertices:Float Ptr,verticesPitch:Int,texCoords:Float Ptr,texCoordsPitch:Int,indices:Int Ptr )
 		DebugAssert( order>0,"Illegal primtive type" )
@@ -645,7 +681,7 @@ Class Canvas
 		DrawImage( image,trans.x,trans.y,rz,scale.x,scale.y )
 	End
 	
-	#rem monkeydoc Draw text.
+	#rem monkeydoc Draws a string.
 	#end
 	Method DrawText( text:String,tx:Float,ty:Float,handleX:Float=0,handleY:Float=0 )
 	

+ 18 - 1
modules/mojo/graphics/device.monkey2

@@ -37,6 +37,8 @@ Class GraphicsDevice
 	
 	Setter( renderTarget:Texture )
 	
+		FlushTarget()
+		
 		_target=renderTarget
 		
 		_dirty|=Dirty.Target
@@ -48,6 +50,8 @@ Class GraphicsDevice
 	
 	Setter( viewport:Recti )
 	
+		FlushTarget()
+	
 		_viewport=viewport
 		
 		_dirty|=Dirty.Viewport|Dirty.Scissor
@@ -59,6 +63,8 @@ Class GraphicsDevice
 	
 	Setter( scissor:Recti )
 	
+		FlushTarget()
+	
 		_scissor=scissor
 		
 		_dirty|=Dirty.Scissor
@@ -153,6 +159,8 @@ Class GraphicsDevice
 		Else
 			glDisable( GL_SCISSOR_TEST )
 		Endif
+		
+		_modified=True
 	End
 	
 	Method Render( vertices:Vertex2f Ptr,order:Int,count:Int )
@@ -199,6 +207,7 @@ Class GraphicsDevice
 			Next
 		End
 		
+		_modified=True
 	End
 
 	Private
@@ -215,6 +224,7 @@ Class GraphicsDevice
 	End
 	
 	Field _dirty:Dirty=Dirty.All
+	Field _modified:Bool
 	Field _target:Texture
 	Field _windowRect:Recti
 	Field _viewport:Recti
@@ -241,6 +251,12 @@ Class GraphicsDevice
 		glGetIntegerv( GL_FRAMEBUFFER_BINDING,Varptr _defaultFbo )
 	End
 	
+	Method FlushTarget()
+		If Not _modified Return
+		If _target _target.Modified( Self )
+		_modified=False
+	End
+	
 	Method Validate()
 	
 		If _seq<>glGraphicsSeq
@@ -248,10 +264,11 @@ Class GraphicsDevice
 			_current=Null
 			InitGLState()
 		Endif
-	
+		
 		If _current=Self 
 			If Not _dirty Return
 		Else
+			If _current _current.FlushTarget()
 			_current=Self
 			_dirty=Dirty.All
 		Endif

+ 4 - 2
modules/mojo/graphics/font.monkey2

@@ -84,9 +84,11 @@ Class Font
 	End
 
 	'Make this ALWAYS work!	
-	Function Load:Font( path:String,height:Float,textureFlags:TextureFlags=TextureFlags.DefaultFlags )
+	Function Load:Font( path:String,height:Float,textureFlags:TextureFlags=TextureFlags.Filter|TextureFlags.Mipmap,shader:Shader=Null )
 	
-		Local font:=fontloader.LoadFont( path,height,textureFlags )
+		If Not shader shader=Shader.GetShader( "font" )
+		
+		Local font:=fontloader.LoadFont( path,height,textureFlags,shader )
 		
 		Return font
 	End

+ 2 - 2
modules/mojo/graphics/fontloader_freetype.monkey2

@@ -13,7 +13,7 @@ Public
 
 #rem monkeydoc @hidden
 #end
-Function LoadFont:Font( path:String,fheight:Float,textureFlags:TextureFlags )
+Function LoadFont:Font( path:String,fheight:Float,textureFlags:TextureFlags,shader:Shader )
 
 	If Not FreeType And FT_Init_FreeType( Varptr FreeType ) Return Null
 	
@@ -94,7 +94,7 @@ Function LoadFont:Font( path:String,fheight:Float,textureFlags:TextureFlags )
 	
 	data.Discard()
 	
-	Local image:=New Image( pixmap,textureFlags,Shader.GetShader( "font" ) )
+	Local image:=New Image( pixmap,textureFlags,shader )
 	
 	Local font:=New Font( image,height,firstChar,glyphs )
 	

+ 5 - 3
modules/mojo/graphics/image.monkey2

@@ -9,7 +9,7 @@ Class Image
 	#end
 	Field OnDiscarded:Void()
 
-	Method New( pixmap:Pixmap,textureFlags:TextureFlags=TextureFlags.DefaultFlags,shader:Shader=Null )
+	Method New( pixmap:Pixmap,textureFlags:TextureFlags=TextureFlags.Filter|TextureFlags.Mipmap,shader:Shader=Null )
 	
 		Local texture:=New Texture( pixmap,textureFlags )
 		
@@ -20,8 +20,10 @@ Class Image
 		End
 	End
 	
-	Method New( width:Int,height:Int,textureFormat:PixelFormat=PixelFormat.RGBA32,textureFlags:TextureFlags=TextureFlags.DefaultFlags,shader:Shader=Null )
+	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 )
@@ -133,7 +135,7 @@ Class Image
 		OnDiscarded()
 	End
 	
-	Function Load:Image( path:String,textureFlags:TextureFlags=TextureFlags.DefaultFlags,shader:Shader=Null )
+	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

+ 71 - 50
modules/mojo/graphics/texture.monkey2

@@ -5,28 +5,19 @@ Namespace mojo.graphics
 
 | TextureFlags	| Description
 |:--------------|:-----------
-| Filter		| Filter texture.
-| Mipmap		| Mipmap texture.
-| WrapS			| Wrap texture S coordinate.
-| WrapT			| Wrap texture T coordinate.
-| WrapST		| Wrap texture coordinates.
-| Managed		| Managed by mojo.
-| RenderTarget	| Texture can be used as a render target.
-| DefaultFlags	| Use default flags.
+| Filter		| Enable filtering. When the texture is magnified, texel colors are interpolated giving a smooth/blurred result.
+| Mipmap		| Enable mipmapping. When the texture is minified, automcatically generated 'mipmaps' are used.
+| Dynamic		| Texture is frequently updated.
 
 #end
 Enum TextureFlags
 
 	Filter=			$0001
 	Mipmap=			$0002
-	WrapS=			$0004
+	WrapS=			$0004			'wrap works, but hidden for now...
 	WrapT=			$0008
-	Managed=		$0010
-	RenderTarget=	$0020
-	
 	WrapST=			WrapS|WrapT
-
-	DefaultFlags=	$ffff
+	Dynamic=		$1000
 End
 
 Class Texture
@@ -35,13 +26,7 @@ Class Texture
 	#end
 	Field OnDiscarded:Void()
 
-	Method New( pixmap:Pixmap,flags:TextureFlags=TextureFlags.DefaultFlags )
-
-		If flags=TextureFlags.DefaultFlags 
-			flags=TextureFlags.Filter|TextureFlags.Mipmap
-		Endif
-		
-		flags|=TextureFlags.Managed
+	Method New( pixmap:Pixmap,flags:TextureFlags=TextureFlags.Filter|TextureFlags.Mipmap )
 		
 #If __TARGET__<>"desktop"
 		If flags & TextureFlags.Mipmap
@@ -49,28 +34,30 @@ Class Texture
 			If tw<>Round( tw ) Or th<>Round( th ) flags&=~TextureFlags.Mipmap
 		Endif
 #Endif
+
+		If flags & TextureFlags.Dynamic
+			PastePixmap( pixmap,0,0 )
+		Else
+			_rect=New Recti( 0,0,pixmap.Width,pixmap.Height )
+			_format=pixmap.Format
+			_flags=flags
+			_managed=pixmap
+		Endif
 		
-		_rect=New Recti( 0,0,pixmap.Width,pixmap.Height )
-		_format=pixmap.Format
-		_flags=flags
-		_managed=pixmap
 	End
 	
-	Method New( width:Int,height:Int,format:PixelFormat=PixelFormat.RGBA32,flags:TextureFlags=TextureFlags.DefaultFlags )
+	Method New( width:Int,height:Int,format:PixelFormat=PixelFormat.RGBA32,flags:TextureFlags=TextureFlags.Filter|TextureFlags.Mipmap )
 	
-		If flags=TextureFlags.DefaultFlags 
-			flags=TextureFlags.Filter|TextureFlags.RenderTarget
-		Endif
-
 		_rect=New Recti( 0,0,width,height )
 		_format=format
 		_flags=flags
 		
-		If _flags & TextureFlags.Managed
+		If Not (_flags & TextureFlags.Dynamic)
 			_managed=New Pixmap( width,height,format )
 			_managed.Clear( Color.Magenta )
 			OnDiscarded+=Lambda()
 				_managed.Discard()
+				_managed=Null
 			End
 		Endif
 	End
@@ -109,6 +96,8 @@ Class Texture
 
 			_managed.Paste( pixmap,x,y )
 			
+			_texDirty=True
+			
 		Else
 		
 			glPushTexture2d( GLTexture )
@@ -124,14 +113,14 @@ Class Texture
 			Endif
 			
 			glPopTexture2d()
+			
+			_mipsDirty=True
 		
 		Endif
-		
-		_texDirty=True
 	
 	End
 	
-	Function Load:Texture( path:String,flags:TextureFlags=TextureFlags.DefaultFlags )
+	Function Load:Texture( path:String,flags:TextureFlags=TextureFlags.Filter|TextureFlags.Mipmap )
 	
 		Local pixmap:=Pixmap.Load( path )
 		If Not pixmap Return Null
@@ -152,7 +141,7 @@ Class Texture
 		If Not texture
 			Local pixmap:=New Pixmap( 1,1 )
 			pixmap.Clear( color )
-			texture=New Texture( pixmap )
+			texture=New Texture( pixmap,Null )
 			_colorTextures[color]=texture
 		Endif
 		Return texture
@@ -163,17 +152,15 @@ Class Texture
 	Property GLTexture:GLuint()
 		DebugAssert( Not _discarded,"texture has been discarded" )
 	
-		If _texSeq=glGraphicsSeq And Not _texDirty Return _glTexture
+		If _texSeq=glGraphicsSeq And Not _texDirty And Not _mipsDirty Return _glTexture
 		
 		If _texSeq=glGraphicsSeq
 		
 			glPushTexture2d( _glTexture )
 		
 		Else
-			_texSeq=glGraphicsSeq
-		
 			glGenTextures( 1,Varptr _glTexture )
-			
+
 			glPushTexture2d( _glTexture )
 		
 			If _flags & TextureFlags.Filter
@@ -203,33 +190,51 @@ Class Texture
 			Else
 				glTexParameteri( GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE )
 			Endif
-		
+			
 			glTexImage2D( GL_TEXTURE_2D,0,glFormat( _format ),Width,Height,0,glFormat( _format ),GL_UNSIGNED_BYTE,Null )
 			
+			_texSeq=glGraphicsSeq
+			_texDirty=True
 		Endif
 		
-		If _managed
+		If _texDirty
 		
-			glPixelStorei( GL_UNPACK_ALIGNMENT,1 )
+			If _managed
 		
-			If _managed.Pitch=_managed.Width*_managed.Depth
-				glTexSubImage2D( GL_TEXTURE_2D,0,0,0,_managed.Width,_managed.Height,glFormat( _format ),GL_UNSIGNED_BYTE,_managed.Data )
+				glPixelStorei( GL_UNPACK_ALIGNMENT,1 )
+			
+				If _managed.Pitch=_managed.Width*_managed.Depth
+					glTexSubImage2D( GL_TEXTURE_2D,0,0,0,_managed.Width,_managed.Height,glFormat( _format ),GL_UNSIGNED_BYTE,_managed.Data )
+				Else
+					For Local iy:=0 Until Height
+						glTexSubImage2D( GL_TEXTURE_2D,0,0,iy,Width,1,glFormat( _format ),GL_UNSIGNED_BYTE,_managed.PixelPtr( 0,iy ) )
+					Next
+				Endif
+				
+				glFlush()	'macos nvidia bug!
+				
 			Else
+			
+				Local tmp:=New Pixmap( Width,1,Format )
+				tmp.Clear( Color.Red )
 				For Local iy:=0 Until Height
-					glTexSubImage2D( GL_TEXTURE_2D,0,0,iy,Width,1,glFormat( _format ),GL_UNSIGNED_BYTE,_managed.PixelPtr( 0,iy ) )
+					glTexSubImage2D( GL_TEXTURE_2D,0,0,iy,Width,1,glFormat( _format ),GL_UNSIGNED_BYTE,tmp.Data )
 				Next
+				tmp.Discard()
+			
 			Endif
 			
-			glFlush()	'macos nvidia bug!
+			_texDirty=False
+			_mipsDirty=True
+		Endif
 		
+		If _mipsDirty
 			If _flags & TextureFlags.Mipmap glGenerateMipmap( GL_TEXTURE_2D )
-			
-		Endif
+			_mipsDirty=False
+		End
 			
 		glPopTexture2d()
 		
-		_texDirty=False
-	
 		Return _glTexture
 	End
 	
@@ -256,6 +261,21 @@ Class Texture
 		Return _glFramebuffer
 	End
 	
+	'***** INTERNAL *****
+	
+	#rem monkeydoc @hidden
+	#end
+	Method Modified( device:GraphicsDevice )
+	
+		If _managed
+			Local r:=device.Viewport & device.Scissor
+			glPixelStorei( GL_PACK_ALIGNMENT,1 )
+			glReadPixels( r.X,r.Y,r.Width,r.Height,GL_RGBA,GL_UNSIGNED_BYTE,_managed.PixelPtr( r.X,r.Y ) )
+		Endif
+		
+		_mipsDirty=True
+	End
+	
 	Private
 	
 	Field _rect:Recti
@@ -266,6 +286,7 @@ Class Texture
 	
 	Field _texSeq:Int
 	Field _texDirty:Bool
+	Field _mipsDirty:Bool
 	Field _glTexture:GLuint
 	
 	Field _fbSeq:Int