TGE water upgrade
by Manoel Neto · 07/03/2006 (11:33 am) · 347 comments
Download Code File
This resource adds basic pixel shader and vertex shader support to the TGE waterblock, using CG, and support for drawing a reflected view of the world into a texture and using it in the waterblock. Right now it's windows-only, but there's nothing stopping you from making it work on OSX and Linux, since CG is also avaliable in those platforms.
Note: For those worrying about Cg being Nvidia-only, fear not, I've personally tested it in different ATI cards and it's compatible with no visible performance problems. Just make sure your drivers aren't ancient.
Note2:
Alex Scarborough (of the TLK DRL fame) is working on porting this resource to GLSL and making it work on OSX. Might get some news soon.
Installing the source changes:
First you'll need the CG toolkit. You can get it here:
developer.nvidia.com/object/cg_toolkit.html
After installing it you must modify the TGE project to include the Cg/lib and Cg/include folders to the library paths and the include paths, respectively.
Important: you also need to open cgGL.h in the "Cg/include" folder and replace this:
Included in the zip file are the modified source files. To install into a unmodified TGE 1.4, just replace the TGE files by the ones included. To install in modified TGE sources, use a merge tool, or copy the changes by hand (all changes are comment-tagged), then compile.
Script changes and usage:
The example folder in the ZIP contains the script files you need to actually see the water in the game. The "example/CG" folder must be copied to the same folder as your executable. It contains the vertex and fragment shaders. The filenames are very hardcoded into the source code, unfortunally.
In "example/starter.fps", you'll find a modified playGui.cs and a normal map for using with the water (it's actually one of TSE's water textures).
The modified playGui.cs is required to render the reflection texture. The GameTSCtrl control was modified and now features a flag called "isReflection". Turning it on will make the gameTsCtrl render the world using a reflected camera matrix, based on the first existing waterblock.
Waterblocks will search for a GameTSCtrl called "reflectionGui". If it's found, they'll grab the refleciton texture from it.
Waterblocks also have a new field, called NormalMaptexture. You need a suitable normal map there, otherwise the reflection texture coordinates will be badly displaced.
Known bugs/limitations:
- No refraction support;
- No specular;
- No fog (at most times it looks like the water is fogged, because the reflected scene is fogged);
- No proper support for using a static envornment map instead of a full reflection (it does use the texture, but it remains fixed, and won't rotate along the view, as the original did);
- Sometimes the reflection can go strange and "melt away". Something to do with clip planes;
This resource adds basic pixel shader and vertex shader support to the TGE waterblock, using CG, and support for drawing a reflected view of the world into a texture and using it in the waterblock. Right now it's windows-only, but there's nothing stopping you from making it work on OSX and Linux, since CG is also avaliable in those platforms.
Note: For those worrying about Cg being Nvidia-only, fear not, I've personally tested it in different ATI cards and it's compatible with no visible performance problems. Just make sure your drivers aren't ancient.
Note2:
Alex Scarborough (of the TLK DRL fame) is working on porting this resource to GLSL and making it work on OSX. Might get some news soon.
Installing the source changes:
First you'll need the CG toolkit. You can get it here:
developer.nvidia.com/object/cg_toolkit.html
After installing it you must modify the TGE project to include the Cg/lib and Cg/include folders to the library paths and the include paths, respectively.
Important: you also need to open cgGL.h in the "Cg/include" folder and replace this:
#include <GL/gl.h>By this:
#include <dgl/dgl.h>Otherwise you'll get loads of compile errors.
Included in the zip file are the modified source files. To install into a unmodified TGE 1.4, just replace the TGE files by the ones included. To install in modified TGE sources, use a merge tool, or copy the changes by hand (all changes are comment-tagged), then compile.
Script changes and usage:
The example folder in the ZIP contains the script files you need to actually see the water in the game. The "example/CG" folder must be copied to the same folder as your executable. It contains the vertex and fragment shaders. The filenames are very hardcoded into the source code, unfortunally.
In "example/starter.fps", you'll find a modified playGui.cs and a normal map for using with the water (it's actually one of TSE's water textures).
The modified playGui.cs is required to render the reflection texture. The GameTSCtrl control was modified and now features a flag called "isReflection". Turning it on will make the gameTsCtrl render the world using a reflected camera matrix, based on the first existing waterblock.
Waterblocks will search for a GameTSCtrl called "reflectionGui". If it's found, they'll grab the refleciton texture from it.
Waterblocks also have a new field, called NormalMaptexture. You need a suitable normal map there, otherwise the reflection texture coordinates will be badly displaced.
Known bugs/limitations:
- No refraction support;
- No specular;
- No fog (at most times it looks like the water is fogged, because the reflected scene is fogged);
- No proper support for using a static envornment map instead of a full reflection (it does use the texture, but it remains fixed, and won't rotate along the view, as the original did);
- Sometimes the reflection can go strange and "melt away". Something to do with clip planes;
About the author
#2
04/28/2006 (10:48 am)
Great resource, but I get more than 100 errors in VC 2003 .NET. Most of them in GL.h...any idea how to fix this?
#3
04/28/2006 (10:52 am)
@ Kaya-Me too
#4
i think it's because nvidia's cgGL.h and other files are #including odd versions of things.
04/28/2006 (11:00 am)
ditto in VC8, tge 1.3.i think it's because nvidia's cgGL.h and other files are #including odd versions of things.
#5
Find this:
And replace by this:
I'll updated the resource instructions to include this info.
@Billy:
You'll need to modify the initShader calls from functions to methods specific to the classes which are using them, if you want somethng else other than the water to use shaders.
I suggest changing things so you have fluid::initShader and InteriorInstance::initShader.
Maybe I should update the resource in this way.
04/28/2006 (11:23 am)
Oops, forgot to tell, there is a change that must be made to cgGL.h:Find this:
#include <GL/gl.h>
And replace by this:
#include <dgl/dgl.h>
I'll updated the resource instructions to include this info.
@Billy:
You'll need to modify the initShader calls from functions to methods specific to the classes which are using them, if you want somethng else other than the water to use shaders.
I suggest changing things so you have fluid::initShader and InteriorInstance::initShader.
Maybe I should update the resource in this way.
#6
04/28/2006 (11:53 am)
i've got it running in TGE 1.3, but water simply doesn't render.. :D i'll keep plugging. it's stepping thru the water rendering code correctly, but obviously some settings are not right. unfortunately our codebase is pretty custom at this point, so my merge may've been bad.
#7
Are you sure the shaders are in the correct folder? The .CG files (water_fp20.cg and water_vp11.cg) must be in a folder called "Cg" in the same folder as your executable. The water simply won't render without those.
04/28/2006 (12:04 pm)
@Orion:Are you sure the shaders are in the correct folder? The .CG files (water_fp20.cg and water_vp11.cg) must be in a folder called "Cg" in the same folder as your executable. The water simply won't render without those.
#8
NormalMaptexture = "~/data/water/noise02";
04/28/2006 (12:07 pm)
Ok I got it to work...for those of you having issues with the reflection add the following line of code to the water datablock in your mission file:NormalMaptexture = "~/data/water/noise02";
#9
04/28/2006 (12:30 pm)
Hmm...still not working...I get errors like "WINGDIAPI - missing memory class or type specifier" (translated from German) or "void should follow after ';'"...any idea?
#10
anyhow, that was totally the issue, nice call!
i'm now getting reflections but they don't line up with their originals. maybe i'll go back to the stock TGE waterblock.. well that didn't do it.
i'm getting reflections and they're gorgeous except they're offset and.. stretched. it's as if the new GameTSCtrl has a bad notion of its origin..
here's a screenie - don't worry about it too much,
i probably just merged wrong, i'll try it again another day.

edit: friendlier image.
04/28/2006 (12:31 pm)
hey manoel - thanks for getting back. - i know how daunting it is to debug some remote person's setup.anyhow, that was totally the issue, nice call!
i'm now getting reflections but they don't line up with their originals. maybe i'll go back to the stock TGE waterblock.. well that didn't do it.
i'm getting reflections and they're gorgeous except they're offset and.. stretched. it's as if the new GameTSCtrl has a bad notion of its origin..
here's a screenie - don't worry about it too much,
i probably just merged wrong, i'll try it again another day.

edit: friendlier image.
#11
it was just that i ahdn't included NormalMaptexture = "~/data/water/noise02" in the waterblock.
thanks jon !
manoel, you rock. thanks for being so generous with the results of your hard work!
04/28/2006 (12:50 pm)
aha !it was just that i ahdn't included NormalMaptexture = "~/data/water/noise02" in the waterblock.
thanks jon !
manoel, you rock. thanks for being so generous with the results of your hard work!
#12
04/28/2006 (12:52 pm)
Compilation works now...I had to remove the 'CG' directory in The PlatformSDK/include folder...
#13
For a fast change i renamed the the init and other declaration and got them both working in my 1.3 code base !
And on my old fx5200 it works really well .
Thanks again !
04/28/2006 (12:55 pm)
Thanks Manoel !For a fast change i renamed the the init and other declaration and got them both working in my 1.3 code base !
And on my old fx5200 it works really well .
Thanks again !
#14
04/28/2006 (1:05 pm)
WOW!!!! This is AWESOME!!! Thanks Manoel - we really appreciate your work!
#15
Any ideas?
04/28/2006 (1:21 pm)
It certainly looks pretty but for some reason I drop from a solid 120 fps to around 10 fps (nvidia 6600GT).Any ideas?
#16
You got refelctions ?
Is my graphics card so bad or did i miss something ?
04/28/2006 (1:27 pm)
@OrionYou got refelctions ?
Is my graphics card so bad or did i miss something ?
#17
04/28/2006 (1:28 pm)
#18
I didn't have to do anything too involved in the merge, eg, no renaming declarations.
Basically to get it in TGE 1.3, i:
1. merged Manoel's engine code by hand - this took a while.
2. did the #include -> #include thing.
3. followed the rest of manoel's instructions, being careful about the location of the new "CG" folder.
4. added "~/data/water/noise02" to the waterblock in the mission file.
i'm running on an ATI Radeon X850.
04/28/2006 (1:33 pm)
@Billy - yeah, beautiful reflections.I didn't have to do anything too involved in the merge, eg, no renaming declarations.
Basically to get it in TGE 1.3, i:
1. merged Manoel's engine code by hand - this took a while.
2. did the #include
3. followed the rest of manoel's instructions, being careful about the location of the new "CG" folder.
4. added "~/data/water/noise02" to the waterblock in the mission file.
i'm running on an ATI Radeon X850.
#19
In shader mode, only the normal map, the reflection texture (in case the reflectionGui is not found) and the depth mask texture are used, the rest is ignored. But if you look in fluidRender.cc, where the code was changed, it is pretty straightforward to modify which textures are used, as well to pass new parameters to the shaders. The shader itself can be hacked to do pretty much anything, like lava and so on. Of course, the only problem is that a single shader is used for all waterblocks in the whole game, so having different waterblocks would require support for per-waterblock shaders.
The waterblock reverts to old style rendering when the videocard failed to load a valic CG profile, or if it has less than 4 texture units. But there isn't any kind of check for pixel shader version, so there's no guarantee the shaders will compile on 1.4 hardware (they'll surely NOT compile in 1.1 hardware, due to dependent texture coord lookups).
Also, the water color is actually explicitally set in the water_fp20.cg file, so you might want to mess with it to change it:
With a little coding you could make it read the color off the surface texture.
04/28/2006 (1:55 pm)
@Jon:In shader mode, only the normal map, the reflection texture (in case the reflectionGui is not found) and the depth mask texture are used, the rest is ignored. But if you look in fluidRender.cc, where the code was changed, it is pretty straightforward to modify which textures are used, as well to pass new parameters to the shaders. The shader itself can be hacked to do pretty much anything, like lava and so on. Of course, the only problem is that a single shader is used for all waterblocks in the whole game, so having different waterblocks would require support for per-waterblock shaders.
The waterblock reverts to old style rendering when the videocard failed to load a valic CG profile, or if it has less than 4 texture units. But there isn't any kind of check for pixel shader version, so there's no guarantee the shaders will compile on 1.4 hardware (they'll surely NOT compile in 1.1 hardware, due to dependent texture coord lookups).
Also, the water color is actually explicitally set in the water_fp20.cg file, so you might want to mess with it to change it:
float3 waterColor = float3(0.12, 0.22, 0.25); //HACK, should be exposed as parameter
With a little coding you could make it read the color off the surface texture.
Torque 3D Owner Billy L
Thanks alot im very happy about this .
But i got a problem , i use the shaders for the interiors.
And got 2 initShader calls , have you done any global init somewhere to get this to work together ?
Or do you have any hints Manoel before i start digging to much .