RTT for 1.26

BlitzMax Forums/BlitzMax Programming/RTT for 1.26

tonyg(Posted 2007) [#1]
I have edited Indiepath's RTT code to work at Bmax 1.26.
There are a couple of issues :
- OGL driver doesn't work with MIPMAPPED images (which has always been the case).
- Resulting image is smaller using the supplied examples. I can workaround this but not sure why it is happening. I asked before and it was due to a Viewport flag but that doesn't help now (plus Viewports have changed since 1.24).
So, if Tim can give the OK for me to post the source as Public Domain and license free I will do.


TartanTangerine (was Indiepath)(Posted 2007) [#2]
you have my permission.


tonyg(Posted 2007) [#3]
Thanks Tim
OK. At the moment it's not a module 'cos it's easier to work on.
The OGL Mipmap problem is avoided by not going into that bit of code.
The 'wrong scale' problem can be avoided by setting the render image to the graphicswidth/height.
Let me know if it works, any improvments and whether anybody can see what I am doing wrong to create a smaller output than input.
Finally, I have taken out the setmono from the original source.

If the problems can be solved I'll comment the code, add nicer variable names and make it a module again.

<edit> For those interested I fixed the scale issue. My theory was the 'camera' used in Bmax is offset a little (zoomed out?) so I was rendering something smaller then smaller again. A simple setscale fixed it.... I think.


altitudems(Posted 2007) [#4]
Nice, thank you. I'll have a play with this later.


Derron(Posted 2007) [#5]
Got some steps further?

May be some commands like glOrtho (with respective values) helps to get the right scale in openGL-mode ?!


bye
MB


tonyg(Posted 2007) [#6]
I must be missing something but it works OK for OGL. The DX driver works with the setscale although, for small images, the result is a bit blurred.


Derron(Posted 2007) [#7]
For OGL it's not working as expected on my machine.

My game uses a resolution of 800x600 and I'm drawing some interface-graphics (a bottom image displaying some other images/informations) - this is about 800x250 pixel but it's displayed with about 1000*400 pixels.

So if using OpenGL as driver its a setscale of about 0.78, 340.0/600 to fit it... but this depends on the dimensions of the images. That's why I mentioned glOrtho - there are some values which are also not 1:1 related to resolution or image-dimensions.
Next to the "wrong scale" aspect the images look very blurry here.

With DX no problems occour after all.


bye
MB


Grey Alien(Posted 2007) [#8]
As an aside, how have viewports changed since V1.24? Do they work on all PCs now?


tonyg(Posted 2007) [#9]
For OGL it's not working as expected on my machine.
. If anybody has the answer then please post as I never touched the OGL method in the module.


Dreamora(Posted 2007) [#10]
Viewports always have worked with systems fullfilling DX8+ specs.

DX7 has no scissor test (DX9+ and OpenGL have it), you need to do it through clip planes and 2D office cards (totally outdated intel/sis/s3 with Pre GMA900 technology so unable to run BM Max2D anyway) just support 2 of them (one for near clip, one for far, but none left for the side. all newer support 4+)


Derron(Posted 2007) [#11]
Try if you see all 4 Rects (Topleft,TopRight,BottomLeft,BottomRight) and all values from 50 to 750.

For doing this - exchange your example with:
SetBlend(ALPHABLEND)
	tRender.TextureRender_Begin(myImage,False)
	tRender.Cls	
	For Local i:Int = 0 To 16 'drawing 16 marks horizontally - from 0 to 800px
	  DrawLine(i*50,0,i*50,600)
	  DrawText("x="+(i*50),i*50, 50)
	Next
	SetColor 255,0,0
		DrawRect(0,0,11,11) 'top left
		DrawRect(790,0,11,11) 'top right
		DrawRect(790,590,11,11) 'bottom right
		DrawRect(0,590,11,11) 'bottom left
	SetColor 200,200,200	
		DrawRect(1,1,10,10) 'top left
		DrawRect(789,1,10,10) 'top right
		DrawRect(789,589,10,10) 'bottom right
		DrawRect(1,589,10,10) 'bottom left
	SetColor 255,255,255
	tRender.TextureRender_End()
	SetImageHandle(logo,0,0)
	tRender.BackBufferRender_Begin()
	tRender.Cls
	DrawImage myimage , 0,0
	DrawImage logo,300,0
	tRender.BackBufferRender_End()
	Flip
WaitKey()


and replace:
Graphics 800,600,0


with:
SetGraphicsDriver GLMax2DDriver()
Graphics 800,600,0



bye
MB


tonyg(Posted 2007) [#12]
Yep I get the same problem. If anybody has the answer then please post as I never touched the OGL method in the module.


Derron(Posted 2007) [#13]
Thanks University-lessons to give me some time on my laptop ;D ... what else is useful in "algorithms and programming".


think I got something which is usable...

Add function (or use the given one in the frame-create-function):

	Function NextPowSize(n) 
			Local t = 1
			While t<n
				t:*2
			Wend
			Return t
		End Function


and change TextureRender_End to:
	Function TextureRender_End()
	SetScale 1.0, 1.0

	?Win32
		If dx
			D3D7GraphicsDriver().Direct3DDevice7().EndScene()
		Else
	?
			glBindTexture GL_TEXTURE_2D, GLFrame.name
'			glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, Width, Height, 0)
			glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0, NextPowSize(width), NextPowSize(Height), 0) 
			glBindTexture GL_TEXTURE_2D, 0
	?Win32
		EndIf
	?
		ViewportSet(0,0,GraphicsWidth(),GraphicsHeight())
		DrawImageRect Image,-2000,-2000,1,1


	'	debuglog "tRender : TextureRender_End OK"
		Return True
	End Function


As you see I changed the width/height thing... Because Textures are surely saved with power of 2 and some sprites (eg when fullscreen-resolutions) aren't saved this way - the stretching occours.

If now the function nextpowsize returns the correct dimensions - for 800x600 its 1024x1024, all stretching is gone... and it looks smooth again ;D...


Hope it works for you too.

ah and... may be for OGL you can comment out:
		DrawImageRect Image,-2000,-2000,1,1

in the same function - for me commenting it out didnt change a thing in OGL.


bye
MB


Derron(Posted 2007) [#14]
Ok ... instead of this huge change you may also change

Just change the given width/height-variables to a new value:
	Function Create:TImage(Width:Int,Height:Int,Flags:Int=FILTEREDIMAGE)
		Local t:TImage=New TImage
		t.width=NextPowSize(width)
		t.height=NextPowSize(height)
...


would work too I think.


bye
MB


Tachyon(Posted 2007) [#15]
Sorry for the elementary question, but: what does this Render To Texture do? What can it achieve that standard BlitzMax commands can't?


Derron(Posted 2007) [#16]
with rtt you can manipulate an image the easy way...


imagine you have a part of your screen filled with a background image... and onto this image you draw other images (sprites). So you will have to draw them each time for each flip and so on...

Also if you only change the drawn-on-top-images every second this will save you the time for a whole second (60 flips or how your fps is set). When the images change you just rebuild the rtt-image and you will be able to draw this for a whole second.

short: ability to draw images on another image and use this "composition" for the next draw-loops until this image has to be changed again.
(huds may be a nice usage for this piece of code).


bye
MB


tonyg(Posted 2007) [#17]
You can also use it to blur/bloom images and create image feedback effects.
It can also be used to produce unique sprites from seperate images ("composite" sprites).


MGE(Posted 2007) [#18]
Is this a stable solution for OpenGL and DirectX?


tonyg(Posted 2007) [#19]
It's completely stable until somebody reports a problem with it.


Derron(Posted 2007) [#20]
Ok...
Now it seems to work when using a trender.create-command with values corresponding to app-resolution (eg. 800x600).

But I don't want to waste memory so I want it the way I'm able to create 500x200 too (which boosts to 512x256).
All tRenders I create are dependend on the overall applications resolution ... so up to now I'm only able to create tRender-images with 800x600 (my app is using this res) else it get's blurry.

So if I create a tRender-image with 800x400 and put it on 0,0 (with resolution of 800x600) all things drawn within this image are halfed-heigh - image at 200 is visually at 100 with half of height ... and so on.

Why do the functions above scale my objects?

At the moment the function only can be used as "composition layers" not as "compositable spritelayer".


bye
MB


tonyg(Posted 2007) [#21]
I put the scale commands in due to the scaling problem in my original post. Tim suggested this was due to the viewport parm used but I got the same with both.
I checked on GameDev as my own attempt at RTT had the same issue but with DX. The response was

I'd guess you are transforming the data twice. If the output to the texture looks right, then make sure you move it to the screen as already transformed data. Otherwise it's like using a camera to take a picture of a picture that's 5 feet away.

Same might be happening with OGL.


jkrankie(Posted 2007) [#22]
will this work in the 1.28 update? i'd like to know before i upgrade.

Cheers
Charlie


tonyg(Posted 2007) [#23]
It works for me but I have changed the code to fix the scaling issue and removed OGL. The code above works as well but is messy. For OGL I would use Diablo's HighGfx code.
Here is the DX code I use now :

<edit> Just realise I have removed all the module info which listed Tim 'Indiepath' as the code originator so thanks to Tim.
In addition, the code now uses the setviewport command. There have been reports of this not working on some graphics cards.


Jake L.(Posted 2008) [#24]
Using the above code, I can't save myImage to a file. Anyone knows how I can achieve this? When using
SavePixmapPNG(myImage.Lock(0,1,0),"tex.png") 

I got an empty PNG. The size is correct, it's just empty.

Thanks

PS: I got the same issues with Klepto's FBO code.


tonyg(Posted 2008) [#25]
It's probably because the image is outside Bmax control really so doesn't have a lock method. I could be wrong though.
<Edit> You might have to resort to drawing, grabbing and saving.


tonyg(Posted 2008) [#26]
Does this do what you're after?



Jake L.(Posted 2008) [#27]
Yes, grabpixmap works. But grabbing the backbuffer with alpha produces bad results (or I have to cheat and draw/grab multiple times), so I thought about using RTT.


tonyg(Posted 2008) [#28]
The problem is a pixmap is never created not the structure to create one. It's possible to do though... I'd expect.