Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

AppGameKit Studio Chat / How to add holes to sprites?

Author
Message
haliop_New
User Banned
Posted: 8th Apr 2019 19:49
I am in the need of memblock usage.

let's say I have one sprite somewhere in the screen.
if I press on the mouse (pointerP) on that sprite.
I want to make a hole in its texture obviously it will be a new image since the original image has multiple uses.

what should I do?
I am kinda lost with memblocks, i can override the entire memblock but you need to consider the place where the pointerX and pointerY got pressed on that specific sprite using the size where the image is scaled to the sprite...

ahh
what should I do?!
also, there is a need to check if the pixel we are about the change is fully transparent since we don't want to create something where we don't need since its transparent.
any functions out there...
Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 8th Apr 2019 21:47 Edited at: 8th Apr 2019 21:48
You dont actually NEED to use memblocks for this.

You could simply copy the sprite image into a render image (one per sprite) then when a user clicks on the the sprite simply render a black circle(or any other image) on to the render image that the sprite uses and you can then cut out parts of the sprite if you wanted to.

1) Check if a sprite was clicked on (GetSpriteHitTest())
2) Get the location on the renderimage that was clicked on (use GetSpritePixelFromX/Y())
3) Set render target and draw to the render image
4) set render target back to the screen again and render as normal (Render() or sync())

Then you can have destructable/editable sprites


of course you could use memblocks if you wanted to but it would be slower and more code. There's plenty of examples on here on how to do that by editing pixels in the meblock and re creating the image from the memblock.
haliop_New
User Banned
Posted: 8th Apr 2019 23:15
I am always about Render to Image but there is a problem here.
since in a Render To Image, you cannot "Erase" pixels but just paint over them... that is a big issue since i want to make a hole in a texture. you know like shooting at wood so you'll see what is behind that wood in a small gap.
the current best solution is a memblock.
However, after suggested what you did, I am now thinking of a quick solution

check sprite with sprite hit
get the locations xy
set render to image
draw a circle sprite in unfamiliar color
turn image into memblock
remove all of the pixels of the unfamiliar colors. // however for this i will have to iterate through the pixels and if I'm already there then there is no real need for the render to image.

and then a different way and faster

check sprite with sprite hit
get the locations xy
set render to image
draw a circle sprite in unfamiliar color
now tell the new render image to use the unfamiliar color as a full alpha transparent color. then you don't need memblocks.




ABOUT MEMBLOCKS BEING SLOW, you just do not do it right. back in the day of DarkGDK we took huge resolution images and manipulate them on max FPS, thousands of them without any lag or anything because we called Sync from time to time as we loop through the memblock. (Trust me it works Flawlessly we actually created a new way of approaching textures )
Riusz
8
Years of Service
User Offline
Joined: 27th Feb 2016
Location:
Posted: 8th Apr 2019 23:46
Maybe using SetImageMask( iDstImage, iSrcImage, 4, 1, x, y ) with iSrcImage being an image with a red cercle, 4 for alpha channel to replace by the 1 for red channel on the x & y position.
I think it's the easiest solution if you use the command on a single frame.

haliop_New
User Banned
Posted: 9th Apr 2019 00:14
yeah but this still poses a problem... because I might have alpha transparent on the source image, which means that on these spots it should not do anything .... but this command will do and also it says in the document that this is a very slow command and should not be used too much ... I still know how to make Memblocks extremely fast. I just need the right function for this.
Raven
19
Years of Service
User Offline
Joined: 23rd Mar 2005
Location: Hertfordshire, England
Posted: 9th Apr 2019 00:26
Memory Block Images are 4 Bytes Per Pixel... R > G > B > A
Each Row of Pixels is: Image Width * 4 (this is typically called the 'Pitch')

As such to plot you will use:
Address = ( Pitch * Y + (X * 4) )
Address = Address + 3 // Select Alpha Byte
Then just write Byte at that Address.

0 = Transparent / 255 = Opaque
All the values between being Semi-Transparent.

It's fairly easy to draw an Alpha (Filled) Circle.


This Draws just a Circular Outline., but you can use this to essentially have a Draw Line From > To for a Fill.
FnPlot is basically the above Calculation at the Top.

To discover what you need for a precise Offset; you just need to check Sprite Collision; Subtract the Pointer Position from the Sprite Position; and you have exactly where it hit on the Sprite itself.
Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 9th Apr 2019 23:39 Edited at: 9th Apr 2019 23:51
Just to answer a few points....

Quote: "
since in a Render To Image, you cannot "Erase" pixels but just paint over them... that is a big issue since i want to make a hole in a texture. you know like shooting at wood so you'll see what is behind that wood in a small gap.
the current best solution is a memblock.
"


Sorry but that is not true you can write a new alpha value to a render target if you want to....See the attached example - simply uses a render target which has a transparent hole drawn on it when you click or drag the mouse.

Just like I said.

Quote: "
check sprite with sprite hit
get the locations xy
set render to image
draw a circle sprite in unfamiliar color
turn image into memblock
remove all of the pixels of the unfamiliar colors. // however for this i will have to iterate through the pixels and if I'm already there then there is no real need for the render to image.

and then a different way and faster
"


Sure - You could set a transparent colour then render that to the image but it gives you either a hole in your sprite or no hole....(its effectively alpha masking). With correct use of a render target you can apply a smooth edge if you wanted to and still no need for using a memblock at any time.

Quote: "
ABOUT MEMBLOCKS BEING SLOW, you just do not do it right. back in the day of DarkGDK we took huge resolution images and manipulate them on max FPS, thousands of them without any lag or anything because we called Sync from time to time as we loop through the memblock. (Trust me it works Flawlessly we actually created a new way of approaching textures ) "


Im sure I do know how to use memblocks perfectly fine thank you lol... And this isnt dark basic anymore...Its AGK....its a different engine.

You are very wrong.... filling large amounts of memory using interpreted basic is SLOW.
Just try this...
1) fill a 4k image with black using a memblock and measure the time it takes
2) Render black to an image with a black sprite or with a screen clear

Compare the two times..... using rendering on the GPU is 100+x faster every time

The loop speed in integrated basic is much much slower. Using a CPU to do graphics work is frankly outdated and slower....just ahuge loop of copy data that the GPU could do for you. Graphics cards are designed for this and do it much much quicker.

If you want to do it with the CPU thats fine, just dont claim its as quick when it isnt.

If you deffo do want to use a memblock...
Id recommend using one of the memblock image manipulation libraries available on here that scraggle did - it has image copying etc using memblocks
https://forum.thegamecreators.com/thread/218320

Attachments

Login to view attachments
blink0k
Moderator
11
Years of Service
User Offline
Joined: 22nd Feb 2013
Location: the land of oz
Posted: 10th Apr 2019 02:35 Edited at: 10th Apr 2019 02:36
If it is destructible land you want then it would be heaps easier to use a shader
haliop_New
User Banned
Posted: 10th Apr 2019 03:44
Hi Thank you guys for the answers!!!
Wow I did not know you can erase stuff in a render to image will check it right on !

True memblocks are old
But Bengismo I have proof somewhere on my PC where you copy thousands of fullhd images in seconds using a memblocks. I agree it is slower then render to image but still fast enough even on low end mobiles so I am no entirely wrong.

Actually using the same method on render to image and I guess you can increase the number to multi thousands full HD images .
Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 10th Apr 2019 10:31

Quote: "
True memblocks are old
"

Not old really....Im not having a go at memblocks, i use them all the time and they are necessary for certain things like getting data into an image in a way that isnt covered by other commands....my point was that they aren't always needed to do easy jobs and are slower then GPU based rendering...which really is true

Quote: "
But Bengismo I have proof somewhere on my PC where you copy thousands of fullhd images in seconds using a memblocks. I agree it is slower then render to image but still fast enough even on low end mobiles so I am no entirely wrong."


Really??? you have code that copies thousands of HD images in seconds using memblocks in AppGameKit??? ....im sure we would all like to see it



This code is a simple test just to fill a HD memblock with black ...if you do set every pixel then it takes an age. More than half a second per image on old machines!!

Render to a render image and call clearscreen takes microseconds!! Its similar results when rendering parts of images too.


Anyway...rather than argue it.... (theres no point in that we are all here to help and learn)

Here is an example of using memblocks where you can literally make holes on an image. Its actually in 3d but obviously it would work in 2d too. It only makes 5 pixels at a time transparent with the F key pressed so it keeps the speed high by only processing a few pixels each frame. Its based on a little example I did ages ago and posted on here



blink0k
Moderator
11
Years of Service
User Offline
Joined: 22nd Feb 2013
Location: the land of oz
Posted: 10th Apr 2019 11:16
Shader to poke holes in things (If destructible stuff is what you want)

Attachments

Login to view attachments
haliop_New
User Banned
Posted: 12th Apr 2019 07:33 Edited at: 12th Apr 2019 07:34
ok, so I am trying to use the render to image method.

so what I have now is:


the sprites which I want to make holes in, are dynamic sprites meaning they are moving inside the screen from place to place in an automated fashion.

each sprite had animation imgs attached to it and the sprite is running through the animation in an automated fashion.

I never want to draw on transparent pixels that sprite may have (these are characters with animation frames).

so I created a simple function but it does not really work... and when I draw a sprite with alpha on a render to image it does not remove the pixels in the main image... so I am doing something wrong.. here is the code... at this current stage the hole sprite is drawn at the center of the new image.



at the end it returns the same Ent to the same Ent...
i just see the blood hole overdrawned and thats it it does not removes any pixels behind it.

also can i check using render To Image where if there are any pixels which are not fully transparent there in order to draw the new pixels of the hole image...
after doing this i think Memblock is the way cause i can check the pixels... of the original cause i do not want to draw everywhere on that image just where there are Pixels
haliop_New
User Banned
Posted: 12th Apr 2019 07:41
one more thing I always find difficult to understand in RenderToImage...
is when I clear the screen to draw some sprites


the render command,
should not I draw only the sprites and text which you selected to draw between the commands of



so
if there are 1000 sprites on screen.
and I chose to render only a certain sprite in the rendered image that is the only one that should be drawn.

right now I am hiding all other sprites and reshowing them before and after the renderToImage function. Isn't there a better way to show hide all sprites when rendering to an image?
Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 12th Apr 2019 22:00 Edited at: 12th Apr 2019 22:08
If your animating your sprite the the bullet holes that you may have drawn onto your sprite image wont be in the next frame as that is a separate image...or at least...it is separate area of the sprite image. Only 1 single frame gets a bullet shot through it. So until you show that animation frame again...the bullet hole wont be there.

You could apply a render image over the whole sprite and then render bullet holes to that and mix it with the animating sprite - it works, but, the problem with this is that the bullet holes remain in one place on the sprite but the sprite itself is changing due to the animation - so it looks very odd and un-natural. If a character is shot in the arm then you would expect the bullet hole to stay in the same spot on his arm as his arm moves. Its hard to describe the effect if you dont do that properly



This is two frames of animation on the same sprite with the same bullet holes in it...clearly the bullet holes do allow you to see through them as we would like and the bullet holes are only rendered on top of sprite pixels that do not have an alpha of 0 (exactl as wanted). Its easy enough to use a shader to combine the render image full of bullet holes and the sprite. Blink did a very good of of describing that above in example code and I can proide the code that i used to make these images if really wanted.

The problem, as i have said above, is that the bullet holes would stay in the same place on the sprite even as the animation changes which looks odd.

It looks fine on a static sprite


but on an animated sprite it looks like your shooting holes in a cinema screen that you character is animating on. For it to work really well you would need to use skeleton animation and then make the bullet holes move with the characters limbs which is a fair bit more complicated.

And...
you can use DrawSprite to just render individual sprites instead of calling render(). Alternatively, you can hide a lot of sprites and call render() then unhide them again. Both options work.


Also....it works fine if the sprite is moving...you just have to convert screen coordinates to the image pixel coordinates. Something like this:

haliop_New
User Banned
Posted: 13th Apr 2019 07:41
Yeah i was wondering about the animation and how it should work... For now i am ok with it. As my characters do have the ability to load up in spriter and have a skeleton export from there a problem arises again... If ill move like 100 sprites on screen and each and everyone of them will have a dynamic extra sprite for the holes then the game might crush since there are 100 enemy sprites lets say 2 sprites for holes.in each , that's 300 sprites right there where 100 are moving and animating and 200 are moving with shaders. That could be a bit tough for a mobile to handle.

There must be something i can do without making the entire system lag or drop fps .. if this was to pc release then it would not matter but its not...

That is why i thought of memblocks why?
Cause i can identify the right or.the about right like 70 percent look a like pixels between frames...

Thoughts ?
Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 13th Apr 2019 07:55 Edited at: 13th Apr 2019 08:18
Memblocks dont get you out of the problem. They make it worse if anything.

If your character has 20 animation frames on the sprite sheet and you want to shoot a hole in him....then you would need to make 20 bullet holes in the original sprite sheet image. One for each frame of animation. Thats 20 x more work to do to add the holes.

The alternative is one additional image as a decal layer over the same sprite with a shader to mix it withe the animating spritesheet as i did above. Like i said...it technically works but looks odd as one layer is animating and the other is stationary.

If you think memblocks will solve it then write the code and show us. The rendertarget works fine...its what you think will work visually but doesnt that is an issue.

If you were to use skeletal animation the you would render a single hole and due to the animation system the hole follows the limb. You would not need any extra sprites at all??? Not sure why you thought that. None of the solutions presented above actually suggest any extra sprites are needed.
haliop_New
User Banned
Posted: 13th Apr 2019 08:21
ohh I get it now.
I am sorry my knowledge of using shaders is really low, I can hardly grasp the idea of it. wish there were more tutorials on that subject.
can someone present a shader for making the holes on a sprite? I saw here a shader for 3d but I need 2d.

TGC, WE NEED MORE SHADER PACKS BOTH FOR 2D and 3D. and tutorials about them.
haliop_New
User Banned
Posted: 13th Apr 2019 08:22
btw i did not know that you can use RenderToImage then DrawSprite and it will draw it on to it , i always thought a Render Command must be applied.
haliop_New
User Banned
Posted: 13th Apr 2019 08:24
for the last comment i made:


WOW JUST WOW I ALWAYS HIDE ALL SPRITES RENDER THEN SHOW THE AGAIN.
OMG, HOW DIDn't I KNOW THAT!!!! THANK YOU FOR SHOWING ME THAT.
Bengismo
6
Years of Service
User Offline
Joined: 20th Nov 2017
Location: Yorkshire, England
Posted: 13th Apr 2019 08:33
Quote: "can someone present a shader for making the holes on a sprite? I saw here a shader for 3d but I need 2d."


Blink posted one above quite clearly

Good luck
haliop_New
User Banned
Posted: 13th Apr 2019 08:52
I did not know we can use a 3d shader on a 2d sprite... checking it out right now.

REALLY THANKS FOR EVERYONE.

Login to post a reply

Server time is: 2024-04-19 14:00:22
Your offset time is: 2024-04-19 14:00:22