ImageBuffer Module (render to texture / fbo)

Monkey Programming Forums/User Modules/ImageBuffer Module (render to texture / fbo)

Skn3(Posted 2013) [#1]
So I spent a little time on this today. I have managed to get a render to texture module working. On GLFW at least.

https://github.com/skn3/imagebuffer

Enjoy, for free :D


Installation
It requires one modification to a monkey module:
Add...format_code('Method GetSurface:Surface()
Return surface
End')to the Class Image in modules/mojo/graphics.monkey



Its highly experimental and currently only supports GLFW. There is a bit of hacking in there to fake monkey into thinking it is rendering. Use at your own risk!

If you use this in OnRender() remember it will reset monkey graphics states (such as scissor and matrix) upon fbo.Start() and fbo.Finish()

This is a very rough-around-the-edges-module and I don't know if I will have time to implement for other targets. Would anyone like to contribute to this?




Skn3(Posted 2013) [#2]
Just adding some more stuff to this, should probably rename it from ImageBuffer...

Started adding shader support



Example syntax:
format_code(''create shader and shader program
shaderProgram = New ShaderProgram()
shaderFragment = New Shader(FRAGMENT_SHADER)
shaderFragment.SetSource(LoadString("path_here"))
shaderProgram.Attach(shaderFragment)
shaderProgram.Link()

'in render loop
shaderProgram.Start()
DrawImage(image, MouseX(), MouseY())
shaderProgram.Finish()')


AdamRedwoods(Posted 2013) [#3]
very nice.
so for GLFW, you are tapping into the possible extensions while using opengl 1.x? so i don't think this is possible on the other targets with openglES 1, because framebuffers/shaders are not allowed. it's when you enable opengles 2 that you can open this up.... but you can't use mojo in opengles 2.

if you want to extend mojo to use opengles2, it's not terribly difficult (extend GraphicsDevice and then set it in OnRender() ), and it can be done almost entirely in monkey.


Skn3(Posted 2013) [#4]
Hadn't thought about the es limitation. I am simply loading in the extensions if supported by the driver for glfw.

I'm not sure I have the time to support all platforms. It would be good if somone would like to contribute.

Do you have an example of enabling 2.0 and mojo?


Nobuyuki(Posted 2013) [#5]
this is pretty darn cool, but as you said, it seems rough around the edges -- I have yet to try it, though!

I want shaders in monkey sooooo bad. And access to both the main surface and individual image textures as surfaces, too. Hoo hoo. Gotta check this out.


ImmutableOctet(SKNG)(Posted 2013) [#6]
Hey Skn3, I think there's a small typo; "GRAPHICS_CAPABILITY_IMAGE_BUFFERS" was called "GRAPHICS_CAPABILITY_IMAGE_BUFFER" in "example_imagebuffer.monkey". Am I missing something, or was this just a simple typo?

Anyway, this looks great, and I may just use it for a project of mine. I just wish it had Android/Java support, that would be perfect.


Skn3(Posted 2013) [#7]
Hey Sonickid,

Thanks, I fixed the typo.

Did a little more on this just now, still implementing the shader api so monkey can get/set stuff. Repo has been updated, but the shader stuff is not fully usable yet.

I will continue on this when I next get some spare time.


Raz(Posted 2013) [#8]
Hey Skn3 : would it be potentially possible to have a blur or bloom shader? :D


Skn3(Posted 2013) [#9]
Hey Raz, it is probably possible at the moment with a combination of the frame buffers and shaders.

following something like:
http://stackoverflow.com/questions/11282394/what-kind-of-blurs-can-be-implemented-in-pixel-shaders

The shaders in the examples were just examples I found on the net, so it would be a good idea to try some existing ones out to see if they work.

I have still got to implement some more shader functionality so not sure if it would all be possible yet.

I worked on it a bit last night (the shader stuff) and its now possible to get/set uniforms. So for example in the ripple demo, I am speaking to the shader and modifying the time value, which animates the effect. You can get set ints/floats,vectors(2,3,4),arrays(of other data types) and matrices. These are all done through 2 overloaded methods, instead of the convoluted 1 function per gl call.

GetUniform(location.. instead of glGetUniform1v34v222(location..

I will try find some spare time to continue.


Skn3(Posted 2013) [#10]
Havn't had a chance to work any more on this as my graphics card is currently RMA to gigabyte. Boo! Will resume once I get it back.


Shinkiro1(Posted 2013) [#11]
This looks really cool.
If it could be made to work with mojo I would be willing to contribute (at least on ios, android and glfw).


skape(Posted 2013) [#12]
This is the single thing I've been missing lately. I was debating if I should attempt to work it out myself or not. So... this looks really cool to me too. Thanks for your work.


Skn3(Posted 2013) [#13]
This works fully with mojo/glfw. Would definitely be looking for help with ios/android bits of it. Perhaps once I get a stable version done for glfw you could do a port after that?


Skn3(Posted 2013) [#14]
I had a little spare time so I just updated the repo.

Updated to work with Monkey v71b+

FBO's are now working on OpenGL 2.0 (previously was using v3.0+ syntax)

FBO's tested and working on ati x1550 (6 year old graphics card)


Nobuyuki(Posted 2013) [#15]
I'm taking an initial look at the source, and I'm wondering --

Would it be nontrivial or a good idea to split the shader and FBO code into separate CPP files? They're both really good features, but the shader stuff alone is taking up over 1000 lines of code, which may complicate porting to ES devices, especially if shaders can't be hacked into ES 1.1 as extensions (I don't actually know for sure!)


Skn3(Posted 2013) [#16]
Hey Nobu,

Yeah that would make sense. Next time I have some spare time to work on this I will tidy up teh source and rename the module to something more fitting.


Skn3(Posted 2013) [#17]
I will probably halt dev of this module for the time being.
The new roadmap details sound like it will include this type of functionality, or if not, make it easier to do. There is no point me duplicating work that might be replicated in a few weeks time.

We shall wait and see!

For now this will be left as WIP.


Nobuyuki(Posted 2013) [#18]
Well, I certainly hope that this functionality gets included soon, at the very least, FBO access. I've been pretty much holding off writing a new font module because I've been wanting something like that in OnUpdate and am (mostly) unwilling to force users to bake alpha maps into their fonts just so they can have 'em in a "redraw only on invalidated context" font module. With the current system, redraws have to be queued for the next render cycle, and require chromakeying or alpha maps to restore alpha because alpha can't be sampled directly with ReadPixels().

Mark, if you're reading this, consider my personal plea to add this support! If shaders are trouble, then forget 'em, but I sooo want those texture pixels' data!


Skn3(Posted 2013) [#19]
I'll revisit this at some point when I have spare time. Incredibly busy at the moment with paid work.

Would definitely like to have a reliable solution for FBO on many targets.


Sicilica(Posted 2015) [#20]
Not to necro an old post, but I wanted to post the changes I had to make to make this work for me under v82b, in case it will help anyone else out. I could've created a pull request, but I'm not sure how elegant this solution is.

It seems that there was an update to String::ToCString() a few versions back to combat memory leaks, and I had to make changes to imagebuffer.glfw.cpp like this:

Change line 389 and add another line afterwards:
format_code('
String::CString<GLchar> theRawSource = source.ToCString<GLchar>();
const GLchar *theSource = theRawSource;
')

And comment out line 395, because for some reason the delete leads to a debugassert fail.

I don't know why that conversion from CString<GLchar> to GLchar* needs to happen on two lines instead of one, but without it I couldn't get any shaders to compile....


ImmutableOctet(SKNG)(Posted 2015) [#21]
@Sicilica: There was a discussion about this on the nDrawExts2 thread. SKN3's probably not going to maintain it further.


Sicilica(Posted 2015) [#22]
@ImmutableOctet(SKNG)

Yeah, I was aware that SKN3 wasn't planning on maintaining this anymore, but as far as I've found there's still isn't much in the way of shader support in Monkey. I actually hadn't seen nDrawExts2, I'll definitely look into that some, cause AFAIK this module doesn't give access to the stencil buffer, which would cover most use cases. I'm new to shader programming stuff, though, really.

It's interesting that the thread you pointed to made almost the exact changes I did! I remember changing that header now, it was such a simple change I'd forgotten it. I think the delete fails because you can't delete a const pointer, and maybe CString used to cast to a normal template C*? But I tried casting it before and it still had problems, so I decided I didn't care about a bit of memory lost one time at startup.

Actually, is anyone still working actively on framebuffers and shaders and things? At least as far as I can tell it's seemed like the monkey community is kinda on the decline, which is a shame since it's probably my favorite language I've ever used.


ImmutableOctet(SKNG)(Posted 2015) [#23]
Well, most people are using custom GL code for shaders, similar to what SKN3 was doing. On top of that, MiniB3D has its own shader support. But as far as new advancements go, Mungo's 'harmony' module has a different audience, but it can be used as a Mojo backend. That supports shaders, from what I've heard, at least. It's an new module, and it's targeted at Mungo, though. Here's the website. Devolonter's the main person working on that fork. Here's his forum thread for it; hasn't been touched in a while, but he's working on it. Last I heard, he's being funded by the 2Dark project, which uses his module. Here's the fork's main twitter account, and here's Devolonter's. Haven't been following his fork very much, but it looks good to me.

That's basically how shaders are going in the world of Monkey. At the end of the day, Monkey does have full OpenGL support, though.