Is render to texture the solution?

BlitzMax Forums/BlitzMax Beginners Area/Is render to texture the solution?

QuickSilva(Posted 2010) [#1]
Hi all, I`m looking for a way to draw several images to the screen using the lightblend mode.

I need to draw them all to an image and then draw this image on screen using the lighblend mode. I cannot simple set lightblend and draw the images individually as the blending does not work how I want it to resulting in some of the images, which overlap, being to bright.

Is there another way to achieve this or do I require a render to texture solution? I need it to be done in real time too.

Thanks for any help,

Jason.


Dreamora(Posted 2010) [#2]
render to texture or optimally pixel shaders are the way to go


ImaginaryHuman(Posted 2010) [#3]
No matter how you do it, if you're putting several images on top of each other with lightblend they're going to be too bright. Do you mean instead that you draw lots of images using alphablend, to one image, and then draw that lightblended?


ima747(Posted 2010) [#4]
perhaps draw them normally, grab the back buffer, and draw that with lightblend? not sure how that would work as it will crush the alpha layer... it's where I'd start though as it's easy.


QuickSilva(Posted 2010) [#5]
Ideally, I would just draw all of my images as normal, grab the back buffer (which now has all of the images drawn to it) and then redraw that with light blend enabled. I`m not quite sure how to do this in BMax though.

Could anyone provide a small example? I assumed that this method would be too slow but maybe I`m wrong? I`d be interested to see how to do it either way.

Jason.


ima747(Posted 2010) [#6]
See GrabImage() in Help->Modules->Graphics->Max2D.

Here is the associated example
' grabimage.bmx

' draws a small graphic then uses grabimage to make an image

' as mask color and cls color both default to black a mask is 
' created for the grabbed where any pixels unset on the backbuffer
' become transparent in the grabbed image

Graphics 640,480

Cls

DrawLine 0,0,32,32
DrawLine 32,0,0,32
DrawOval 0,0,32,32

Local image=CreateImage(640,480,1,DYNAMICIMAGE|MASKEDIMAGE)
GrabImage image,0,0

Cls
For i=1 To 100
	DrawImage image,Rnd(640),Rnd(480)
Next
Flip

WaitKey


I have found GrabImage to be VERY fast personally, but it depends on what you're doing I suppose.

I would try doing a CLS() draw your images as you need them, grabimage that area, then CLS again and start your real drawing being able to use the grabbed image as your lightblend. Can't guarantee it will do what you want but it's where I'd start :0)


QuickSilva(Posted 2010) [#7]
OK, thanks. I`ll go and give it a try. Thanks for providing the example.

Jason.


QuickSilva(Posted 2010) [#8]
Well I gave it a try and as expected it was just too slow which is a shame as otherwise it was nice and simple to implement.

Would a render to texture be hard to implement? I had a quick scan of the code archives and found an OpenGL version, are there any other useful examples about that I may have missed?

Jason.


DJWoodgate(Posted 2010) [#9]
If you are using opengl you could try using the depth buffer or stencil buffer if they are available. Looking at some old OPENGL code using the depth buffer is just a case of glenable GL_DEPTH_TEST and gldisable GL_DEPTH_TEST to return to normal rendering and using glClear GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT each loop instead of cls.

If you are doing simple 2d stuff then it should hopefully all be drawn at the same depth and enabling the depth test will stop pixels being drawn where other pixels have already been drawn while the test is enabled. I guess in your case you would then draw your images in front to back order.

Seemed to work at the time, but not sure how it would fare now, I do not have the latest version installed.