About Monkey 2 › Forums › Monkey 2 Programming Help › Mojo: GetPixel() since update 1.11
This topic contains 10 replies, has 4 voices, and was last updated by 
 Abe _King_
 1 year ago.
- 
		AuthorPosts
 - 
		
			
				
March 28, 2018 at 7:53 pm #14162
Hello,
Since 1.11 update, is there any change in Mojo (2D) ?
For me, GetPixel() and GetPixelARGB() return (0,0,0,0) and $0
Maybe I do it wrong now.I’m on Windows 10 – 64 bits.
Could you run this code on other configs with monkey 2 – 1.11 ?
GetPixel() returns Color(0,0,0,0) since update.Monkey12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970' ---------------------------------------' getpixel.monkey2' ---------------------------------------Namespace getpixel#Import "<std>"#Import "<mojo>"Using std..Using mojo..Class MyWindow Extends WindowField pxm:PixmapField img:ImageField imgcanvas:CanvasMethod New()Super.New( "GetPixel test",512, 512,WindowFlags.Resizable | WindowFlags.HighDPI )' Creates a pixmap, image, and canvaspxm = New Pixmap( 300,300,PixelFormat.RGBA8)img = New Image( pxm,TextureFlags.None,Null )imgcanvas = New Canvas( img )EndMethod OnRender( canvas:Canvas ) OverrideApp.RequestRender()' Draws your Screen background here (Red Circles)canvas.Clear(Color.Black)' draws a blue rectangle in the pixmapimgcanvas.Clear(Color.White) ' Clear the image in whiteimgcanvas.Color = Color.Blue ' And paint bottom half in blue and Alpha = 1.0imgcanvas.DrawRect(0,0,pxm.Width,pxm.Height/2)imgcanvas.Flush()' draws the pixmap on the screencanvas.Color = New Color( 1, 1, 1, 1 )canvas.Alpha = 1canvas.DrawImage( img,0,0 )' Shows pixmap colors if mouse is under the pixmapLocal ARGB:UIntLocal Ink:ColorIf (Mouse.X<pxm.Width) And (Mouse.Y<pxm.Height)ARGB = pxm.GetPixelARGB( Mouse.X,Mouse.Y )Ink = pxm.GetPixel( Mouse.X,Mouse.Y )canvas.DrawText( "image color ARGB $" + Hex(ARGB),0,Height-100 )canvas.DrawText( "Alpha " + Ink.A,0,Height-20 )canvas.DrawText( "Red " + Ink.R,0,Height-80 )canvas.DrawText( "Green " + Ink.G,0,Height-60 )canvas.DrawText( "Blue " + Ink.B,0,Height-40 )canvas.DrawText( "Alpha " + Ink.A,0,Height-20 )Endifcanvas.DrawText("Move the mouse on the Blue/White pixmap",0,Height-140)EndEndFunction Main()New AppInstanceNew MyWindowApp.Run()EndAlso any changes in Keyboard events ?
March 29, 2018 at 5:00 am #14166Yes, the behaviour of textures has changed a little here – they were never supposed to modify the pixmap they were created with in the first place, and it was causing all sorts of issues with something else I was trying to do in 1.1.11, so I ‘fixed’ it so that the initial pixmap is copied to an internal one if necessary and is never used again (by the texture anyway).
However, the old way is probably the most efficient way to do what you’re wanting so I think I’ll add some kind of new texture flag that preserves the old behaviour, not sure what I’ll call it yet. Should be in v1.1.12…
Also any changes in Keyboard events ?
There are always changes to everything! Could you be a little more specific?
March 29, 2018 at 5:31 am #14167Ok, I’m gonna revert this to pre 1.1.11 behaviour in the case of normal textures – my fixes were really only necessary for cubemap textures.
March 29, 2018 at 5:35 am #14168Thanks Mark,
Got it, i didn’t draw into the Pixmap.Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293' ---------------------------------------' getpixel.monkey2' ---------------------------------------Namespace getpixel#Import "<std>"#Import "<mojo>"Using std..Using mojo..Class MyWindow Extends WindowField pxm:PixmapField img:ImageField imgcanvas:CanvasMethod New()Super.New( "GetPixel test",512, 512,WindowFlags.Resizable | WindowFlags.HighDPI )' Creates a pixmap, image, and canvaspxm = New Pixmap( 300,300,PixelFormat.RGBA8)' Draws a pink square before linking image and pixmapFor Local y:Int=0 To 50For Local x:Int=0 To 50pxm.SetPixel(x,y,Color.HotPink)NextNext' Copy pixmap data into imageimg = New Image( pxm,TextureFlags.None,Null )' Here pxm.SetPixel() draws into the pixmap but not' Try to draw a red squareFor Local y:Int=0 To 50For Local x:Int=50 To 100pxm.SetPixel(x,y,Color.Red)NextNextpxm.PremultiplyAlpha()imgcanvas = New Canvas( img )EndMethod OnRender( canvas:Canvas ) OverrideApp.RequestRender()' Draws your Screen background herecanvas.Clear(Color.Black)' draws a blue rectangle in the pixmapFor Local y:Int=0 To 50For Local x:Int=100 To 150pxm.SetPixel(x,y,Color.Green)NextNextpxm.PremultiplyAlpha()' draws the image on the screencanvas.Color = New Color( 1, 1, 1, 1 )canvas.Alpha = 1canvas.DrawImage( img,0,0 )canvas.DrawLine(0,52,150,52)' Shows pixmap colors if mouse is under the pixmapLocal ARGB:UIntLocal Ink:ColorIf (Mouse.X<pxm.Width) And (Mouse.Y<pxm.Height)ARGB = pxm.GetPixelARGB( Mouse.X,Mouse.Y )Ink = pxm.GetPixel( Mouse.X,Mouse.Y )canvas.DrawText( "image color ARGB $" + Hex(ARGB),0,Height-100 )canvas.DrawText( "Alpha " + Ink.A,0,Height-20 )canvas.DrawText( "Red " + Ink.R,0,Height-80 )canvas.DrawText( "Green " + Ink.G,0,Height-60 )canvas.DrawText( "Blue " + Ink.B,0,Height-40 )canvas.DrawText( "Alpha " + Ink.A,0,Height-20 )Endifcanvas.DrawText("Move the mouse from 0,0 to 150,49",0,Height-140)canvas.DrawText("Mouse "+Mouse.X+"-"+Mouse.Y,0,Height-160)EndEndFunction Main()New AppInstanceNew MyWindowApp.Run()EndNow the question : How can i get the color of a pixel in the image ?
For Keyboard events, i must experiment, (2900 lines of code in my prog), to see if my code is faulty.
March 29, 2018 at 7:20 pm #14174Now the question : How can i get the color of a pixel in the image ?
The way you were doing it pre 1.1.11 is probably the most efficient so once 1.1.12 is out I’d suggest going back to that which will fix this issue.
But note that it’s still not all that efficient, because modern GPUs don’t like you ‘reading’ their memory. On PC’s, GPU’s generally have their own private graphics memory and moving data to/from graphics memory is relatively expensive.
Also, the OpenGLES API (used by mobile/web targets) doesn’t even support copying data from textures to system memory, only copying data from the ‘render target’. Desktop OpenGL does, but it wont be anymore efficient than the pre-1.1.11 method.
There is no easy way around this, it’s just something you’ve got to deal with if you want HW accelerated graphics. If anyone has any ideas here too please feel free to share.
For Keyboard events, i must experiment, (2900 lines of code in my prog), to see if my code is faulty.
Not even a hint?!?
March 29, 2018 at 11:04 pm #14177Ok,
I see a little difference after monkey 1.06
Keyboard.KeyPressed() , and Keyboard.KeyReleased() have a little buffer.
Run this code, with monkey 1.06 and later. Follow the instructions on screen.
It just moves a cursor, if the mouse is in a zone and a cursor keys is pressed.
see Method ProceedInput()Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133Namespace keyboardtest#Import "<std>"#Import "<mojo>"Using std..Using mojo..' -----------------------------------------------Class ZoneField x0:Int,y0:Int ' Zone positionField x1:Int,y1:IntField width:Int, height:Int ' Zone dimField backcolor:ColorField cursX:Int,cursY:Int ' Cursors positionMethod New( lx:Int, ly:Int, lw:Int, lh:Int, lco:Color )Self.x0 = lxSelf.y0 = lySelf.width = lwSelf.height= lhSelf.x1 = Self.x0 + Self.width - 1Self.y1 = Self.y0 + Self.height - 1Self.backcolor = lcoSelf.cursX = 150Self.cursY = 100EndMethod Draw( lcanvas : Canvas )' draws backgroundlcanvas.Color = backcolorlcanvas.DrawRect( x0, y0, width, height )' draws the cursorlcanvas.Color = Color.Whitelcanvas.DrawRect( x0+cursX-8 ,y0+cursY-8 ,16 ,16 )EndMethod ProceedInput()If MouseHere()If Keyboard.KeyPressed( Key.Up )Self.cursY = Self.cursY - 8Elseif Keyboard.KeyPressed( Key.Down )Self.cursY = Self.cursY + 8Elseif Keyboard.KeyPressed( Key.Right )Self.cursX = Self.cursX + 8Elseif Keyboard.KeyPressed( Key.Left )Self.cursX = Self.cursX - 8Endif' limits the cursors positioncursX = Clamp( cursX,8,width-8 )cursY = Clamp( cursY,8,height-8 )EndifEndMethod MouseHere:Bool()'return true if mouse is in the ZoneLocal lreturn:Bool = FalseIf (Mouse.X>=x0) And (Mouse.X<x1)If (Mouse.Y>=y0) And (Mouse.Y<y1)lreturn = TrueEndifEndifReturn lreturnEndEnd' ------------------------------------------------Class MyWindow Extends WindowField oZone:= New Zone[4]Method New( title:String="Test Fichiers",width:Int=1280,height:Int=768,flags:WindowFlags=WindowFlags.Resizable )Super.New( title,width,height,flags )' create zonesoZone[1] = New Zone( 10,10,300,200,Color.Blue)oZone[2] = New Zone(320,10,300,200,Color.DarkGrey)oZone[3] = New Zone(640,10,300,200,Color.Brown)EndMethod OnRender( canvas:Canvas ) OverrideLocal i:IntApp.RequestRender()' Proceed Keyboard inputs in each zoneFor i=1 To 3oZone[i].ProceedInput()Next' redraws the zonesFor i=1 To 3oZone[i].Draw( canvas )Nextcanvas.DrawText("put the mouse outside the rectangles ", 0 , 360)canvas.DrawText("use cursor key before entering coloured zones ", 0 , 380)canvas.DrawText("Move the mouse inside the one rectangle ", 0 , 400)canvas.DrawText("Keyboard.Keypressed is tested if mouse is in a zone ", 0 , 420)canvas.DrawText("and white square moves ", 0 , 440)canvas.DrawText("Try it in Monkey 1.06 --> no buffer", 0 , 460)canvas.DrawText("in later versions --> little buffer ", 0 , 480)canvas.DrawText("idem with Keyboard.KeyReleased" ,0, 500)canvas.DrawText("obviously no pb with KeyDown",0,520)EndEnd' ------------------------------------------------Function Main()New AppInstanceNew MyWindowApp.Run()EndMarch 30, 2018 at 1:13 am #14178Yep, the behaviour of Keyboard.KeyPressed has changed since v1.1.06.
Before v1.1.06 KeyPressed used use a ‘frame’ system, where KeyPressed returned true if a key was pressed in the current ‘frame’ (ie: the time between renders). However, this caused problems when people tried to use KeyPressed from within timers.
It now returns true if a key has been pressed since the last call to KeyPressed (with the same key). This affects your code because you only call KeyPressed if mouse is in zone.
The solution is to always check for KeyPressed, even if the mouse is not in any of the zones. I guess another possiblity would be to allow people to manually increment the ‘input frame’.
Or, you could instead use a KeyEvent handler, like this:
Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132Namespace keyboardtest#Import "<std>"#Import "<mojo>"Using std..Using mojo..' -----------------------------------------------Class ZoneField x0:Int,y0:Int ' Zone positionField x1:Int,y1:IntField width:Int, height:Int ' Zone dimField backcolor:ColorField cursX:Int,cursY:Int ' Cursors positionMethod New( lx:Int, ly:Int, lw:Int, lh:Int, lco:Color )Self.x0 = lxSelf.y0 = lySelf.width = lwSelf.height= lhSelf.x1 = Self.x0 + Self.width - 1Self.y1 = Self.y0 + Self.height - 1Self.backcolor = lcoSelf.cursX = 150Self.cursY = 100EndMethod Draw( lcanvas : Canvas )' draws backgroundlcanvas.Color = backcolorlcanvas.DrawRect( x0, y0, width, height )' draws the cursorlcanvas.Color = Color.Whitelcanvas.DrawRect( x0+cursX-8 ,y0+cursY-8 ,16 ,16 )EndMethod ProcessKeyDown( key:Key )Select keyCase Key.UpSelf.cursY = Self.cursY - 8Case Key.DownSelf.cursY = Self.cursY + 8Case Key.RightSelf.cursX = Self.cursX + 8Case Key.LeftSelf.cursX = Self.cursX - 8End' limits the cursors positioncursX = Clamp( cursX,8,width-8 )cursY = Clamp( cursY,8,height-8 )EndMethod MouseHere:Bool()'return true if mouse is in the ZoneLocal lreturn:Bool = FalseIf (Mouse.X>=x0) And (Mouse.X<x1)If (Mouse.Y>=y0) And (Mouse.Y<y1)lreturn = TrueEndifEndifReturn lreturnEndEnd' ------------------------------------------------Class MyWindow Extends WindowField oZone:= New Zone[4]Method New( title:String="Test Fichiers",width:Int=1280,height:Int=768,flags:WindowFlags=WindowFlags.Resizable )Super.New( title,width,height,flags )' create zonesoZone[1] = New Zone( 10,10,300,200,Color.Blue)oZone[2] = New Zone(320,10,300,200,Color.DarkGrey)oZone[3] = New Zone(640,10,300,200,Color.Brown)EndMethod OnRender( canvas:Canvas ) OverrideLocal i:IntApp.RequestRender()canvas.DrawText("put the mouse outside the rectangles ", 0 , 360)canvas.DrawText("use cursor key before entering coloured zones ", 0 , 380)canvas.DrawText("Move the mouse inside the one rectangle ", 0 , 400)canvas.DrawText("Keyboard.Keypressed is tested if mouse is in a zone ", 0 , 420)canvas.DrawText("and white square moves ", 0 , 440)canvas.DrawText("Try it in Monkey 1.06 --> no buffer", 0 , 460)canvas.DrawText("in later versions --> little buffer ", 0 , 480)canvas.DrawText("idem with Keyboard.KeyReleased" ,0, 500)canvas.DrawText("obviously no pb with KeyDown",0,520)' redraws the zonesFor i=1 To 3oZone[i].Draw( canvas )NextEndMethod OnKeyEvent( event:KeyEvent ) OverrideSelect event.TypeCase EventType.KeyDownFor Local i:=1 To 3If oZone[i].MouseHere() oZone[i].ProcessKeyDown( event.Key )NextEndEndEnd' ------------------------------------------------Function Main()New AppInstanceNew MyWindowApp.Run()EndMarch 30, 2018 at 1:56 am #14179What I think I’ll do here is resurrect b3d/bmx style Keyboard.FlushKeys() that can be called to ‘clear’ any keypresses that haven’t been checked for. Look out for it in v.1.12 in addition to the texture fix.
March 30, 2018 at 11:54 am #14183Exactly what i needed.
I will try to inject your KeyEvent handler in my project.
Many thanks for explanations.April 2, 2018 at 9:52 am #14193So you broke both pixmaps and keyboard scanning – way to go Mark!
I hear-by declare you a winner
Attachments:
April 5, 2018 at 5:55 pm #14260I am also now experiencing the exact same problem. I have no idea what it is I may be doing wrong but here is my code
mx2cc version:
Mx2cc version 1.1.12Monkey1234567891011121314151617181920212223Local img:= <replace with ur own image object>Local pixmap:=New Pixmap( img.Width, img.Height )Local tex:=New Texture( pixmap, TextureFlags.None )dynImage=New Image( tex )Local pcan:=New Canvas( dynImage )Local results:=New StringStack' Try to effect the pixel mappcan.Clear( Color.Black )pcan.DrawImage( img, 0, 0 )pcan.Flush()For Local y:=0 Until img.HeightFor Local x:=0 Until img.Widthresults.Push( "," + pixmap.GetPixel(x,y).A )Nextresults.Push( "~n" )If y Mod 50=0 Print "working..." + yNextPrint results.Join("")' no data is registerd, just an array of 0'sIt might not work if I copied my code wrong, but this is pretty much it. I don’t think I saw your updated flag either @admin!
 - 
		AuthorPosts
 
You must be logged in to reply to this topic.
