• Dear Cerberus X User!

    As we prepare to transition the forum ownership from Mike to Phil (TripleHead GmbH), we need your explicit consent to transfer your user data in accordance with our amended Terms and Rules in order to be compliant with data protection laws.

    Important: If you accept the amended Terms and Rules, you agree to the transfer of your user data to the future forum owner!

    Please read the new Terms and Rules below, check the box to agree, and click "Accept" to continue enjoying your Cerberus X Forum experience. The deadline for consent is April 5, 2024.

    Do not accept the amended Terms and Rules if you do not wish your personal data to be transferred to the future forum owner!

    Accepting ensures:

    - Continued access to your account with a short break for the actual transfer.

    - Retention of your data under the same terms.

    Without consent:

    - You don't have further access to your forum user account.

    - Your account and personal data will be deleted after April 5, 2024.

    - Public posts remain, but usernames indicating real identity will be anonymized. If you disagree with a fictitious name you have the option to contact us so we can find a name that is acceptable to you.

    We hope to keep you in our community and see you on the forum soon!

    All the best

    Your Cerberus X Team

Mojo1 test [SOLVED]

Wingnut

Well-known member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
1,414
I have problem with getting readpixels working on Mojo2. I dotn't read alot of memory so I know it is not the amount.

What follows first is the Mojo1 version and it works perfectly everywhere even on Android and with good speed.
Compare this with the Mojo2 version that locks up (On Android) and also the size of the square is half in size by some reason.

What am doing wrong with Mojo2?


Mojo1 version :

Code:
Strict
Import mojo
'

Function Main:int()
    New gamename()
    Return 0
End

Class gamename Extends App

Field log:Image
Field x:Float =50
Field y:Float = 50
Field pix:Int[40*40]
Field img:Image
'

        Method OnCreate:Int()
            '
            SetSwapInterval 1 ; SetUpdateRate 0
            log = LoadImage("log.png")
            img = CreateImage(40,40)
            Return 0
        End
       
         Method OnRender:int()
            Cls 0,0,250
            DrawImage log,0,0
            ReadPixels pix,MouseX(),MouseY(),40,40
            img.WritePixels pix,0,0,40,40
            DrawImage img,0,0
            '
            Return 0
        End
End

Mojo2 version :

Code:
Strict
Import mojo2
Import brl.databuffer

Function Main:int()
    New gamename()
    Return 0
End

Class gamename Extends App

Field log:Image
Field x:Float =50
Field y:Float = 50
Field pix:DataBuffer  = New DataBuffer(4 * 40 * 40)
Field img:Image
Field canvas:Canvas

        Method OnCreate:Int()
            canvas=New Canvas
            SetSwapInterval 1 ; SetUpdateRate 0
            log = Image.Load("log.png",0,0,0)
            img = New Image(40,40)
            Return 0
        End
       
         Method OnRender:int()
            canvas.Clear 0,0,250
            canvas.DrawImage log,0,0
            canvas.ReadPixels MouseX(),MouseY(),40,40, pix
            img.WritePixels 0,0,40,40,pix
            canvas.DrawImage img,0,0
            canvas.Flush
            Return 0
        End
End
 

Attachments

  • log.png
    log.png
    56.9 KB · Views: 114
I found that it's not as much a lockdown on Android as it seem to be something wrong with the coordinates.
Mojo2 simply becomes upsidedown and half the size for some reason and I cannot find what I am doing wrong.

You can't see the mouse pointer on these screenshots but on the 2nd way it's actually had to go way down to even show the graphics. It's not exactly upside down y & x coordinates but something weird seem to be happening.
 

Attachments

  • Mojo1.png
    Mojo1.png
    85.3 KB · Views: 120
  • Mojo2.png
    Mojo2.png
    82.9 KB · Views: 114
Havn't solved it yet but the mojo2 version is smaller because it wasn't told to use the upper left corner (so 0,0 would give you the lower right part, 1 25% of the square). So thats fixed here.

But still it is upside down in Mojo2? I looked through the manual but I couldn't' find anything.Have I missed something?


Cerberus:
Strict
Import mojo2
Import brl.databuffer

Function Main:int()
    New gamename()
    Return 0
End

Class gamename Extends App

 Field log:Image
 Field x:Float = 50
 Field y:Float = 50
 Field pix:DataBuffer = New DataBuffer(4 * 40 * 40)
 Field img:Image
 Field canvas:Canvas
 
        Method OnCreate:Int()
            canvas=New Canvas
            SetSwapInterval 1 ; SetUpdateRate 0
            log = Image.Load("log.png",0,0,0)
            img = New Image(40,40) ; img.SetHandle(0,0)
            Return 0
        End
          
         Method OnRender:Int()
            canvas.Clear 0,0,250
            canvas.DrawImage log,0,0
            canvas.ReadPixels MouseX(),MouseY(),40,40, pix
            img.WritePixels 0,0,40,40,pix
            canvas.DrawImage img,0,0 
            canvas.Flush
            Return 0
        End
End
 
Any ideas? See I'm building a lemming based game so I need to be able to read pixels.

Could I somehow mix Mojo1 instructions with Mojo2? I only need Mojo1 for the actual reading of the ground and Mojo2 for the moving graphics because it works so much better for my project.

Here's a test how Mojo2 reads pixels and writes them back to the same position whereever the mouse is.
It's slow and upside down on Android. It's also a *bit* slow on Safari actually. Chrome has no problem whatsoever when it comes to speed (still upside down though).


Screenshot 2020-10-14 at 08.51.02.png


Cerberus:
Strict
Import mojo2
Import brl.databuffer

Function Main:int()
    New gamename()
    Return 0
End

Class gamename Extends App

 Field log:Image
 Field x:Float = 50
 Field y:Float = 50
 Field pix:DataBuffer = New DataBuffer(4 * 256 * 256)
 Field img:Image
 Field canvas:Canvas
 
        Method OnCreate:Int()
            canvas=New Canvas
            SetSwapInterval 1 ; SetUpdateRate 0
            log = Image.Load("log.png",0,0,0)
            img = New Image(256,256) ; img.SetHandle(0,0)
            Return 0
        End
          
         Method OnRender:Int()
            canvas.Clear 0,0,250
            canvas.DrawImage log,0,0
   
            Local mx:Int = MouseX()
            Local my:Int = MouseY()
            canvas.ReadPixels(mx,my,8,8,pix)
            img.WritePixels(mx,my,8,8,pix)
    
            canvas.DrawImage img,0,0 
            canvas.Flush
            Return 0
        End
End
 
If you do 1x1 pixel at a time and read y as (height-1)-y (height being 480 here) it will give you a perfect result.

But as soo as you do more than one pixel like 8x8 those will becomes upside down tin that group.

View attachment 1032

Cerberus:
Strict
Import mojo2
Import brl.databuffer

Function Main:int()
    New gamename()
    Return 0
End

Class gamename Extends App

Field log:Image
Field x:Float = 50
Field y:Float = 50
Field pix:DataBuffer = New DataBuffer(4 * 256 * 256)
Field img:Image
Field canvas:Canvas

        Method OnCreate:Int()
            canvas=New Canvas
            SetSwapInterval 1 ; SetUpdateRate 0
            log = Image.Load("log.png",0,0,0)
            img = New Image(256,256) ; img.SetHandle(0,0)
            Return 0
        End
         
         Method OnRender:Int()
            canvas.Clear 0,0,250
            canvas.DrawImage log,0,0
   
           
            Local mx:Int = MouseX()
            Local my:Int = MouseY()
            canvas.ReadPixels(mx,479-my,1,1,pix)
            Local value:Int = pix.PeekInt(0)
            Print value
            img.WritePixels(mx,my,1,1,pix)
         
         
       
            canvas.DrawImage img,0,0
            canvas.Flush
            Return 0
        End
End
 
I read now that this is normal OpenGL behaviour (how Mojo1 solves it I do not know?!).
You could always read one pixel at a time in Mojo2 and use a y coordinate of (displayheight-1)-y (e.g. 479-y. but you have to keep it 1 pixel at a time for it to work sensibly. I guess it is no real problem.

I tried to rewrite readpixels inside mojo2 graphics.cxs, to loop inversly but It's more complex than I have strength to handle right now.
 
But it's something to think about and it's worth mention in the manual!

Mojo1 and Mojo2 has different behaviour in readpixels!
 
You could also just do a visual flip (but the image you created will still be upside down internally of course, you just don't see it).
And that is to use an scale or width/height parameter when you draw the image. You make it negative in Y.
If you use DrawImage you can use 1,-1 instead of 1,1 as the x & y scale.

If you use DrawRect you can just make the height negative to do the same.

Both are zero-cost.

Cerberus:
Strict
Import mojo2
Import brl.databuffer

Function Main:int()
    New gamename()
    Return 0
End

Class gamename Extends App

Field log:Image
Field x:Float = 50
Field y:Float = 50
Field pix:DataBuffer = New DataBuffer(4 * 256*256)
Field img:Image
Field canvas:Canvas

        Method OnCreate:Int()
            canvas=New Canvas
            SetSwapInterval 1 ; SetUpdateRate 0
            log = Image.Load("log.png",0,0,0)
            img = New Image(256,256) ; img.SetHandle(0,0)
            Return 0
        End
         
         Method OnRender:Int()
            canvas.Clear 0,0,250
            canvas.DrawImage log,0,0

            Local mx:Int = MouseX()
            Local my:Int = MouseY()
           
            canvas.ReadPixels(mx,my,8,8,pix)

            img.WritePixels(mx,my,8,8,pix)
       
            canvas.DrawImage img,0,0,0,1,-1 ' < here is the extended DrawImage command with x,y,rotation,xscale,yscale
            canvas.Flush
            Return 0
        End
End
 
Something to think about though is that Mojo1 has a readpixels command that works as you could expect
while Mojo2 reverses the y coordinate when doing a readpixels command.

Either you can :

* Use readpixels with a y coordinate of (displayheight-1)-y and read only 1 pixel at a time

* Or you read everything upside down all in one go and make sure that you draw it upside down (and if you want to access the databuffer you better deal with y like above, (displayheight-1)-y.
 
Maybe I was too quick because there could be something wrong, I'm not sure.

If you read the image and write it back and do the flip to correct it, it still offsets everything, you can't see the whole 256x256 picture?

Screenshot 2020-10-14 at 19.32.01.png


code.png



Cerberus:
Strict
Import mojo2
Import brl.databuffer

Function Main:int()
    New gamename()
    Return 0
End

Class gamename Extends App

Field log:Image
Field x:Float = 50
Field y:Float = 50
Field pix:DataBuffer = New DataBuffer(4 * 256*256)
Field img:Image
Field canvas:Canvas

        Method OnCreate:Int()
            canvas=New Canvas
            SetSwapInterval 1 ; SetUpdateRate 0
            log = Image.Load("log.png",0,0,0)
            img = New Image(256,256) ; img.SetHandle(0,0)
            Return 0
        End
         
         Method OnRender:Int()
            canvas.Clear 0,0,0
            canvas.DrawImage log,0,0
           
            ' If mouse button is pressed, read the full picture (256x256) and write it back and draw it.
          If MouseDown(0)      
                canvas.ReadPixels 0,0,256,256,pix
                img.WritePixels 0,0,256,256,pix
                canvas.DrawImage img,0,256,0,1,-1
            Endif
           
            canvas.Flush
            Return 0
        End
End
 
Wow that was an easy trap.

You have to remember the size of the canvas you are reading when you need to read upside down.
The default canvas is of course 640x480 so you have to change this line.

Cerberus:
canvas.ReadPixels 0,480-256,256,256,pix ' Canvas is 640x480 default size, not 256x256, so you read 256x256 using 480-256
 
Back
Top Bottom