Max2d bottle neck for caustic 2d effect

BlitzMax Forums/BlitzMax Programming/Max2d bottle neck for caustic 2d effect

Armitage 1982(Posted 2009) [#1]
Hi

Well I think I arrive to a point were Max2d drawing module is slowing down my game while my code is not necessary bad.
Since I can't do nothing about it I need to find quicker way to do this :



I'm blending 2 images in order to give this shiny caustic effect to my water.
The problem is that I'm using a height map and so I need to cut every columns into polygons.

Since those columns changing permanently I need to redraw every polygon each time TWICE :
One time with DrawPoly in order to get a blue shape for blending.
And then with a DrawTexturedPoly function that use my caustic texture with a GL_TEXTURE_WRAP option (GL_REPEAT and GL_CLAMP).

The second one is the most power consuming since I have to calculate every UV coordinate to render the texture correctly.

I was wondering if any of you know a better function in OpenGl to render such textured polygon or maybe if you know the old way in BlitzMax for doing this effect (you know, drawing a region of pixel in a buffer and then render a texture inside like a mask object then render the obtained texture).
I remember game using real time caustic effect like this but unfortunately with this method multiplayer splitscreen on low machine slowing down my FPS substantially !

It's only 2D, should be faster than reflecting water in 3D game huh ?
Thanks for any advices.


Armitage 1982(Posted 2009) [#2]
Hum... as a side note !

This current rendering allow me to achieve a nice effect were the caustic texture UV follow the height-map and give great result when object dive into.

This would probably not be possible with the old effect idea (as it's more intended to be a flat reflect in most of old game).

Is reducing the number of column in the height-map or removing the first step (see above) is the only possible way to speed-up this effect ?


Nate the Great(Posted 2009) [#3]
I would say just cut out the first step or optimize your uv coord finding code.


ImaginaryHuman(Posted 2009) [#4]
Could you just render a single quad of texture to the backbuffer, draw a mask of the water surface into the destination alpha channel, grab the image into a texture, render the texture as one quad.?


Tommo(Posted 2009) [#5]
I guess UV calculation may be not the main bottleneck, because it's just some simple instructions.
Did you try polygon culling£¿
If you are using GL only, maybe you can try vertex array, that would help a lot.


AlexO(Posted 2009) [#6]
While I can't really be certain what would be 'slow' about your approach, or what you deem as 'slow' but one thing I find a lot when I'm optimizing Bmax code is:

Make sure you aren't generating any garbage in the rendering code. If you're using anything like a Vector2 class, etc to help calculate things be sure to cache the object (ie make it a field in the object that uses it in the tight loop), or inline those method calls by doing the x/y calculations manually. Creating objects in tight loops is a big no-no in blitzmax if you want to stay performant.

But before that, I would measure, measure, measure. Be certain that there isn't anything in your code can can be inadvertently causing bmax's max2D modules to slow down (texture swapping, renderstate changes, etc, etc).


Armitage 1982(Posted 2009) [#7]
Could you just render a single quad of texture to the backbuffer, draw a mask of the water surface into the destination alpha channel, grab the image into a texture, render the texture as one quad.?


I would like to try this solution since I could add a true refracting feature with it.
Does that mean I must add a GRAPHICS_ALPHABUFFER and use some of the glewinit() advanced functions ?

If you are using GL only, maybe you can try vertex array, that would help a lot.

Vertex Array is a good idea, I will examine this possibilities to reduce overhead.
I find this example about OGL Vertex Array : http://www.blitzbasic.com/Community/posts.php?topic=66184
And you are right with the polygon culling I did it for the whole surrounding object but for each polygon. Could improve the performance a bit :)


When I talk about slowdown is mainly on a 800mhz with 1Go and old ATI radeon 9200 (my referral test machine to minimal config).
No problem at all with CPU above 1Ghz.


Armitage 1982(Posted 2009) [#8]
Damned !

As soon as I'm trying Vertex Array code my GL_QUADS turn to semi-transparent black and even disapear when I use Max2D functions elsewhere in my game !
This even if I setup or not a blending mode (cannot produce any color, only black or semi-transparent black !).

Local Colors:Float[] = [1.0, 0.2, 0.2, 1.0,  ..
			0.2, 0.2, 1.0, 1.0,  ..
			0.8, 1.0, 0.2, 1.0,  ..
			0.5, 1.0, 0.5, 1.0,  ..
			0.8, 0.8, 0.8, 1.0]

glEnableClientState(GL_VERTEX_ARRAY)
glEnableClientState(GL_COLOR_ARRAY)

glColorPointer(3, GL_FLOAT, 0, Colors)

For Local PolyArray:Float[] = EachIn Poly

	glVertexPointer(2, GL_FLOAT, 0, PolyArray)
	glDrawArrays(GL_QUADS, 0, 4)
				
Next

glDisableClientState(GL_VERTEX_ARRAY)
glDisableClientState(GL_COLOR_ARRAY)


I have several module using OpenGl like CEGUI or GLMAX2D obviously, and at this stage of my game I cannot switch to true OpenGl Driver.
Do you know what could produce this bug ??

I don't know much about All OpenGl Options.
I suppose later on If I get rid of that bug I would be able to pass the whole Array of VertexPointer to glVertexPointer ?
This would be faster than EachIn within max no ?

EDIT
I try this : http://blitzmax.com/Community/posts.php?topic=53361#596500
glEnable(GL_BLEND)
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

But won't help :( My Quads are still Black !

Also why is my glTexCoordPointer mess up with the correct MAX2D UV coordinate ?
My texture is all stretched like if the UV (or S,T) were at different places...


Armitage 1982(Posted 2009) [#9]
I discovered I was using too much of FILTEREDIMAGE for such a slow machine (800mhz, 1Go RAM, ATI radeon 9200).
But even knowing that I think this effect still use much performances !

I will add a level of details option which load special texture responsible of this slowdown with the desired flag.
But I still have no clues about the Black Quads rendering and UV problems...

I suppose using a single Vertex Array Drawing per splitscreen (in multiplayer mode) would really improve performances.


Armitage 1982(Posted 2009) [#10]
Okay !

I know the source of this major slow down on my old test machine !
I was testing the new Glew 1.5.1 last week and forgot to rebuild some of my mod folder like the brl.max2D

For more information consult this thread : http://blitzmax.com/Community/posts.php?topic=85518

(Should have try this in a new fresh installation of BlitzMax but without this I would never discover the slowdown differences).

Currently my code is enough optimized which is great :)
No need to read the full manual of OpenGl to find the Vertex Array bug today!

I will probably switch to a full openGl driver on my next project.
This one is too advanced with the Max2D module to change anything more deeply.

Thanks for your help :)


Arowx(Posted 2009) [#11]
Why even have a government, couldn't we replace most of the elected officials with a few Web 2.0 pages and a twitter feed, then all we would have to do was plug everyone into the internet and let the 'collective' decide....

Node Adjuct 345684391 of 8045637593

You know when you have too many IE windows open at once when this happens ;o)


markcw(Posted 2009) [#12]
I'll have whatever Merx has been eating.


TaskMaster(Posted 2009) [#13]
LOL

I'm guessing he accidentally posted in the wrong thread.