### Author Topic: A Sprite2Mem and Mem2sprite question  (Read 3898 times)

#### backspace

• Mr. Drawsprite
• Posts: 53
##### A Sprite2Mem and Mem2sprite question
« on: 2013-Jan-11 »
Hi again,

This time it's my turn to ask a MEM2* question, but more to ask if anyone can see what I am wrong in my code.
This is my first attempt at using the MEM stuff, to see if I can actually use a dirty rectangle method in painting with a "brush". It's easy with drawsprite to a buffered screen, but the MEM thing is hopefully the start of a more complex  bit based process for painting.

I would really appreciate some educate eyes to see where I am messing up in my code. It's probably something very noobish, so please be gentle with that stick

Code: (glbasic) [Select]
`// --------------------------------- //// Project: mem2mem-paint-test// --------------------------------- ////we define our variables hereGLOBAL x,y,i,r,i, mx,my,mlb,mrb,c,cc,rrGLOBAL brush%[], bground%[], dirty%[]//we start with a white image to paint on - we stick to 640x480 with this testCREATESCREEN 30, 99, 640, 480    //screen 30, sprite 99, our work area//we now use our own screen to make our work area whiteUSESCREEN 30DRAWRECT 0,0,640,480, RGB(255,255,255)//we set up a new screen for a paintbrush imageCREATESCREEN 31, 100, 20, 20   //screen 31, sprite 100, brush size 20x20//we switch to our paintbrush screen to create the brushUSESCREEN 31//we use math to draw in circles FOR r = 1 TO 10                                 //for radius 1 to 10. Half width of our brush = radius FOR i = 0 TO 360                            //all around the compas x = SIN(i)*r                            //1st part of a circle formula y = COS(i)*r                            //2nd part of a circle formula SETPIXEL x+10,y+10,RGB(100,100,100)     //0,0 is top left corner, so we offset drawing to middle of image NEXTNEXT//our main game loopWHILE TRUE //we get the mouse state MOUSESTATE mx,my,mlb,mrb //if the left button is down, we MEM our brush onto the canvas IF mlb =1 THEN drawBrush() //we ensure that all final drawings go to the real screen USESCREEN -1 //we draw our work area sprite onto the real screen DRAWSPRITE 99, 0, 0 //use the brush as a mouse pointer DRAWSPRITE 100,mx,my SHOWSCREENWENDFUNCTION drawBrush:   //we could use parameter, but for this test we use globals LOCAL x = mx-9     //mouse x less half the brush width + center pixel LOCAL y = my-9     //mouse y less half the brush height + center pixel LOCAL w = x+19     //width of the brush less 1 LOCAL h = y+19     //height of the brush less 1 LOCAL r%,g%,b%,a% LOCAL BGabgr%      //Background alpha, red, green, blue . .that's why it has a funny name LOCAL DIRTYabgr%, BRUSHabgr% LOCAL rr,yy //grab the background work area SPRITE2MEM(bground%[], 99) //grab the brush SPRITE2MEM(brush%[], 100) //build the dirty rectangle rr = -1 //inner rows cc = -1                                                                          //inner columns FOR r = y TO h        //for each row     rr = rr + 1 //for each inner row     cc = -1                                                                         //reset inner column for new row FOR c = x TO w    //for each column     cc = cc + 1 //for each inner column BGabgr% = bground%[c + r*20]             //get a piece of our drawing buffer DIRTYabgr% = BGabgr% //get the buffer into the dirty rectangle BRUSHabgr% = brush%[cc + rr*20]          //get the brush BGabgr% = bOR(DIRTYabgr%,BRUSHabgr%)    //add the brush to the diry rectangle bground%[c + r*20] = BGabgr%                    //rebuild background from the rectangle NEXT NEXT //Replace background with changes MEM2SPRITE(bground%[], 99, 640, 480)ENDFUNCTION`
« Last Edit: 2013-Jan-12 by backspace »
I came, I saw, I coded.

#### Kitty Hello

• code monkey
• Prof. Inline
• Posts: 10851
• here on my island the sea says 'hello'
##### A Sprite2Mem and Mem2sprite question
« Reply #1 on: 2013-Jan-12 »
Hi
Draw both, brush and background to see if they are ok. The blending with bOR is also not perfect. It might just brighten up. Does it not work? Cant test atm.

#### backspace

• Mr. Drawsprite
• Posts: 53
##### Re: A Sprite2Mem and Mem2sprite question
« Reply #2 on: 2013-Jan-12 »
Hi Kitty,

Thanks for the reply. Yes that was a poor post I my part. I just dumped the code without an explanation. Sorry about that; frustration sometimes does get the upperhand and mess up the mind.

The problem was that I could not see any results from OR-ing the the two buffers together. The resulting buffer was "empty" for some unknown reason, and would not update anything onto the "screen".

I have however addressed the problem by passing the DGInt arrays to INLINE functions and using c to manipulate the byte data. All my pixel-magic algorithms are from c libraries anyway, so I can just INLINE the ones that I use. So I SPRITE2MEM in, do the INLINE stuff and MEM2SPRITE back again. This has solved all previous problems that I had.

« Last Edit: 2013-Jan-12 by backspace »
I came, I saw, I coded.

#### backspace

• Mr. Drawsprite
• Posts: 53
##### Re: A Sprite2Mem and Mem2sprite question
« Reply #3 on: 2013-Jan-12 »
Oh my. Just when I thought I had everything sorted out, I ran into another snag.
This has all got to do with my MEM2SPRITE paint-thing, so I am continuing the new question here.

This time it looks as if the MEM2SPRITE is actually the cause of all my problems.
I am able to get a sprites onto  PixelArray[]s with SPRITE2MEM. This works perfectly.
I am able to manipulate the array data against another with all sorts of 'magic" using INLINE with no problems
I can convert the PixelArray[]s back to sprites with MEM2SPRITE, with a big smile.

BUT.. here comes the issue:
If I drawsprite the image after a MEM2SPRITE, I see all my work on the image.
If I print, drawline, drawsprite, or any of the other commands to the "screen" that holds the image (after a MEM2SPRITE)... Nothing happens
If I remove the MEM2SPRITE command, then the other commands all draw to that "screen" without any problems.

So it seems as of the MEM2SPRITE somehow "locks up" the screen and image, and wont accept anything else done on it.
Here's a little test program to illustrate my point.

On first run you can see the image, but not the PRINT "hello" and another drawn image drawn onto the "memsprite"'s image screen
If you comment out the MEM2SPRITE, then you can see that all the other stuff actually works ok.

Why this is important, is that I want to be able to sometime add some text to the image, or maybe even draw some lines on them, which can't really be done with MEM buffers.

Code: (glbasic) [Select]
`// --------------------------------- //// Project: sprite2mem-test-12// --------------------------------- //SETCURRENTDIR("Media")LOCAL PX1%[]LOCAL argb%CREATESCREEN 1,1,320,240CREATESCREEN 2,2,320,240CREATESCREEN 3,3,50,50USESCREEN 3DRAWRECT 0,0,49,49,RGB(50,100,150)USESCREEN -1LOADSPRITE "dogncat1.png",1SPRITE2MEM(PX1[],1)MEM2SPRITE(PX1[], 2, 320, 240)   // <----------comment out this line and the rest works fineUSESCREEN 2DRAWSPRITE 3,200,100PRINT "HI",5,5USESCREEN -1DRAWSPRITE 2,0,0SHOWSCREENMOUSEWAIT`
Edit: I attached the image I used for the test. I kept it small for test purposes.

« Last Edit: 2013-Jan-12 by backspace »
I came, I saw, I coded.

#### backspace

• Mr. Drawsprite
• Posts: 53
##### Re: A Sprite2Mem and Mem2sprite question
« Reply #4 on: 2013-Jan-12 »
Luckily I don't give up easily. I've found a work-around, but this still does not solve the MEM2SPRITE "lockout" problem.

What I've done is create a new screen and sprite, and then draw my image and other stuff on that, then use the new sprite to display the results.

I'm a little concerned about the overhead of creating a new screen in a a game loop. since the paintbrush will need to continuously update the image via a new screen, 60 or more times a second. If it's a pointer to a newly created class instance, then that's ok, since that's what c+ is made to do anyway, but this does raise the possibility of memory leaks. (No offense to the programmers, it's one of the things about c++)

Here's the workaround. It does exactly what I need, but leaves me with performance and memory leak concerns.

Code: (glbasic) [Select]
`// --------------------------------- //// Project: sprite2mem-tes-13// --------------------------------- //SETCURRENTDIR("Media")LOCAL PX1%[]LOCAL argb%LOCAL r,yCREATESCREEN 1,1,320,240CREATESCREEN 2,2,320,240CREATESCREEN 3,3,50,50USESCREEN 3DRAWRECT 0,0,49,49,RGB(255,0,0)USESCREEN -1LOADSPRITE "dogncat1.png",1SPRITE2MEM(PX1[],1)MEM2SPRITE(PX1[], 2, 320, 240)   // Create a new screen and sprite to use as an intemediary step to publishCREATESCREEN 4,4,320,240USESCREEN 4DRAWSPRITE 2,0,0 DRAWSPRITE 3,200,100PRINT "HI",5,5USESCREEN -1DRAWSPRITE 4,0,0SHOWSCREENMOUSEWAIT`
I came, I saw, I coded.

#### mentalthink

• Prof. Inline
• Posts: 3375
• Integrated Brain
##### Re: A Sprite2Mem and Mem2sprite question
« Reply #5 on: 2013-Jan-13 »
hi BackSpace thanks for your code, very interesting... in fact I like use this technic for 3d... but.. if you want draw...
because don't draw the image and whit an dinamic array paint over, you can do layers, like photoshop, and when you finished the work, makes a grabsprite and you have the same like you do whit your code, but whitout troubles of speed... In PC Mem2Sprite for me runs very quickly but in mobile devices not...

But thanks it's very interesting playing whit the values os RGBA, can do very nice effects...

#### graffix989

• Mc. Print
• Posts: 12
##### Re: A Sprite2Mem and Mem2sprite question
« Reply #6 on: 2013-Feb-08 »
ive had simular problems with mem2sprite, used setpixel from array (for any changes)  then grabsprite as a workaround... my best guess is mem2sprite somehow fills the backbuffer with pixels that cannot be changed until cleared?? i also noticed mem2sprite has to be EXACTLY same size if replacing a current sprite... dunno, ive found a few quirks with GLBasic that all need their own workaround good luck

#### fuzzy70

• Community Developer
• Prof. Inline
• Posts: 828
• Look left, Look right, LOOK OUT!!
##### Re: A Sprite2Mem and Mem2sprite question
« Reply #7 on: 2013-Feb-08 »
Here is my version of your code which only uses 2 createscreens. I have just changed the mem2sprite ID to one which is not one been used by a screen & drew the sprite.

Only thing I can think of is some kind of conflict with created screens & mem2sprite using same sprite number  .

Lee

Code: (glbasic) [Select]
`// SETCURRENTDIR("Media") // go to media files// --------------------------------- //// Project: sprite2mem-test-12// --------------------------------- //SETCURRENTDIR("Media")LOCAL PX1%[]LOCAL argb%//CREATESCREEN 1,1,320,240   // Not neededCREATESCREEN 2,2,320,240CREATESCREEN 3,3,50,50USESCREEN 3DRAWRECT 0,0,49,49,RGB(50,100,150)USESCREEN -1LOADSPRITE "dogncat1.png",1SPRITE2MEM(PX1[],1)MEM2SPRITE(PX1[],4, 320, 240)   // Changed sprite ID to one that is not used by a create screenUSESCREEN 2DRAWSPRITE 4,0,0 // Draw the memspite 1st DRAWSPRITE 3,200,100PRINT "HI",5,5USESCREEN -1DRAWSPRITE 2,0,0SHOWSCREENMOUSEWAIT`
"Why don't you just make ten louder and make ten be the top number and make that a little louder?"
- "These go to eleven."

This Is Spinal Tap (1984)

#### Kitty Hello

• code monkey
• Prof. Inline
• Posts: 10851
• here on my island the sea says 'hello'
##### Re: A Sprite2Mem and Mem2sprite question
« Reply #8 on: 2013-May-06 »
That one was a hard nut to crack!
Wehn you do mem2sprite, the new sprite can be bigger than it was before. So mem2sprite is the same as loadsprite, internally.
When you lod a sprite, the old one gets dumped and you get a new one created.
However!!! You screen "2" is still assigned to the texture id you just deleted! Ha! So, in order to make it work, you'd re-createscreen for that sprite. ... which would clear the scprite with transparent pixels.

I try to fix it, so I re-assign the new sprite id to the screen.

aaaaaand fixxxxored! (For LOADSPRITE and MEM2SPRITE).
« Last Edit: 2013-May-06 by Kitty Hello »