How to render to Texture

Monkey Forums/Monkey Programming/How to render to Texture

skavle(Posted 2012) [#1]
I'd like to save tracks, trails of units, save corpses, blood the floor and stuff like that.

Now I let the object remain, however it seems that will only work to a certain extent. Eventually 10 of 1000's of images will need to be rendered, I assume there is a limit here especially on mobile devices?

Do I need render to texture to do this? Is there another way?

Thanks


Beaker(Posted 2012) [#2]
I would recommend drawing less. Currently there is no render to texture in monkey. There might be a user module for some targets.


Beaker(Posted 2012) [#3]
http://www.monkeycoder.co.nz/Community/posts.php?topic=3130&


Landon(Posted 2012) [#4]
it would be nice in html5 if i could pull images from my website, then i'd just let php's Glib do all the work


Gerry Quinn(Posted 2012) [#5]
I think the standard approach is to only keep a certain number of such 'decorations'. You'll notice in many shooters that bullets leave marks on the wall, but if you keep spraying bullets in one place the old marks will start to disappear.

I don't believe there is any advantage rendering to texture for this, even if you can.


muddy_shoes(Posted 2012) [#6]
The advantage would come if you can keep re-rendering the "decorated" image. For example, if you put the whole background into a buffer and just render blood splatters or explosion marks or whatever into that buffer.


invaderJim(Posted 2012) [#7]
This is something I've been wrestling with off and on for quite a while now. It seems just about impossible to do this in real time in HTML5, because, and please correct me if I'm wrong, the Image objects are immutable. So any time you want to draw to an image, you have to draw the old image to a separate canvas, make all your additional draw calls to the canvas, create a new Image object with this canvas as its source, THEN wait for the image to load before you can do anything else to it.

I've been mulling over an idea in the past couple days that involves caching individual draw calls and only drawing the render target once it's finished loading. But that is a lot of work to appease one target, as the other targets are much more render-target friendly.

Anywho. That's my HTML5 rant. I will continue to take jabs at it and maybe I'll have something to show in the coming weeks, who knows. Really, they just need to make the API mo bettah.


muddy_shoes(Posted 2012) [#8]
What level of performance issues are you seeing? I don't use the technique to do much other than cache UI text but a quick test looks usable. Go here, click to switch to rendering from a buffer and then use the spacebar to add decals in random positions.


invaderJim(Posted 2012) [#9]
Yeah, that is a good way to do it. The challenge I'm facing is turning that off-screen canvas back into a mojo image without any hiccups.


muddy_shoes(Posted 2012) [#10]
Why do you need it to be a mojo Image instance?


invaderJim(Posted 2012) [#11]
Just for ease of use. Right now I'm trying to create a simple DrawImageToImage function using mojo images. As I said, it's a challenge. But I suppose that's the real reason I'm doing it; to see if it can even be done :P


AdamRedwoods(Posted 2012) [#12]
to see if it can even be done


Only if you hack it.

You see, Mark made "surface" private for the Image Class. So the monkey compiler won't touch it from any other monkey routine that you write. You need surface in order to pass from monkey to native code (which could then easily combine images).

The only way around this is to use the OpenGL monkey extension LoadImageData.


invaderJim(Posted 2012) [#13]
Hmm, I didn't realize the OpenGL module now supports HTML5.

Thanks, Adam! You've given my life new direction :P


marksibly(Posted 2012) [#14]
Hi,

Ok, I've made a bit of progress on this front lately.

I haven't implemented the whole render-to-texture thing, not only because I am concerned about getting it working reliably everywhere (I *have* tried before!) but also because there are issues with how to write arbitrary alpha values (which may or may not need to be pre-multiplied) which may be important depending on what you're doing.

Anyway, next release will have a few new commands for reading/writing pixels, ie:

'create a new image...single frame only?
Function CreateImage:Image( width,height,flags )

'read from 'backbuffer'...
Function ReadPixels:Void( pixels:Int[],x:Int,y:Int,width:Int,height:Int,arrayOffset:Int=0,arrayPitch:Int=0 )

'write to image...must be a CreateImage image.
Method Image.WritePixels( pixels:Int[],x:Int,y:Int,width:Int,height:Int,arrayOffset:Int=0,arrayPitch:Int=0 )


...so you can implement 'GrabImage' with something like:

Local buf:=new Int[w*h]      'probably want to use a cache
ReadPixels buf,0,0,w,h       'read from back buffer
img.WritePixels buf,0,0,w,h  'write to image


Since the pixels go through an array, you can mess with them on the way, eg: you could implement a 'mask color' etc.

Performance seems to be good on all targets, possibly not good enough for realtime 'every frame' image updates, but I guess that depends on your needs.

I've had to add an XNA_BACKBUFFER_ACCESS_ENABLED config setting for XNA, as to be able to read the backbuffer you need to do some tricky stuff. This does appear to slow things down a bit, but not massively.

This may in future be expanded for use with data buffers (although there's no such thing in XNA yet) but for now I think this approach provides a great deal of flexibility combined with reasonable performance.

I may also add WritePixels to back buffer and ReadPixels from image later, but you can sort of fake that with the existing additions already.


zoqfotpik(Posted 2012) [#15]
One way to do this sort of thing is with prerendered images containing a number of static bloodsplats or whatever, which you then set at random rotations and draw two of them on top of each other with transparency. This way, because of the combination of the two different images at different rotations, there are large numbers of possible final images. Lots of bloodsplats in unpredictable configurations.

This is obviously a hackaround and not ideal but in many applications I doubt if anyone would even notice.


BigAnd(Posted 2012) [#16]
This is great news Mark. Its was one of the biggest things (for me) that's missing from monkey. I look forward to the update :)


Midimaster(Posted 2012) [#17]
Thank you Mark,

this will be very helpful for fast rendering text. Ok, the building of an "text-image" will need more time at first, but will save a lot of performance during a game.

This could also be very helpful for a collision system, or?


marksibly(Posted 2012) [#18]
Hi,

> This could also be very helpful for a collision system, or?

Actually, I didn't think of that, but yes! You could theoretically draw/grab images and create precise collision data...


zoqfotpik(Posted 2012) [#19]
I agree by the way, it would have helped me (may still help me) on my present project.


Skn3(Posted 2012) [#20]
brilliant render to texture!


marksibly(Posted 2012) [#21]
(sort of)


DruggedBunny(Posted 2012) [#22]
Excellent, my most-wanted addition!


Skn3(Posted 2012) [#23]
haha yeah (sort of) is still good :D


Tibit(Posted 2012) [#24]
Great news!


vbnz(Posted 2012) [#25]
Thanks,Mark!
I am waiting for this too!
When the update will be available?

Sincerely, vbnz.


OvineByDesign(Posted 2012) [#26]
excellent news :)

StuC


Arthur(Posted 2012) [#27]
Best news! :) Most wanted feature.
So we'll be able to draw direct to alpha channel of image?


benmc(Posted 2012) [#28]
This is fantastic! It will allow me to port one of my most successful games to Monkey and finally release it on iOS!!!! Can't wait.


Gerry Quinn(Posted 2012) [#29]
Great news - this was my most wanted feature!


NoOdle(Posted 2012) [#30]
Thanks this is good news!

Image.ReadPixels will be a very handy future addition. Will this work on loaded images as well or only on images created with CreateImage? It would be very useful if there was a way to use WritePixels and ReadPixels on either.


Gerry Quinn(Posted 2012) [#31]
Will there be a direct load option also, to read into this type of image from a standard graphics format?


samowitsch(Posted 2013) [#32]
I am at the same point now. Can we expect a ReadPixels and WritePixels methods on an image created with LoadImage()?


Gerry Quinn(Posted 2013) [#33]
I doubt it. It would be nice to have a CreateImageArray:Int[]( filename ) though. [Actually you'd ideally want an ImageArray class that contained width and height as well as an array, though I guess a couple of globals that could be polled after loading would do too.]


Shinkiro1(Posted 2013) [#34]
If the CreateImage function could be passed an array of pixels that would open up a lot of things.
For now this stuff seems to assume you want to read everything via ReadPixels.


Gerry Quinn(Posted 2013) [#35]
It is in effect passed an array of pixels; it just happens in two steps. I think what you are looking for is a function like ReadPixels, only operating on a loaded Image instead of the back buffer.


AdamRedwoods(Posted 2013) [#36]
under the "opengl" module, there is a hidden function called LoadImageData(filename, info[]) that will return a buffer, then you can send the buffer to array to an image.WritePixels().


samowitsch(Posted 2013) [#37]
I think what you are looking for is a function like ReadPixels, only operating on a loaded Image instead of the back buffer.


Yes you are right. It would be a very good feature.


samowitsch(Posted 2013) [#38]
under the "opengl" module, there is a hidden function called LoadImageData(filename, info[]) that will return a buffer, then you can send the buffer to array to an image.WritePixels().



Thanks, i will look into it.