LOD Terrain setup

Coordinator
Oct 20, 2007 at 10:36 PM
Edited Oct 20, 2007 at 10:48 PM
Good news guys. I just finished an LOD mod for terrain and it works great. On a 256x256 terrain with water reflecting and refracting terrain, our framerate doubles! I'm working on some more optimizations that will be in the next version. But I will be testing all future versions on my older system for compatibility issues before any releases. By drawing the terrain in this LOD all the time, the framerate is 6 times as much on a 256x256!
Oct 21, 2007 at 7:19 AM
Excellent, when will we see it implemented? :evil:

Coordinator
Oct 21, 2007 at 7:35 AM
About.....now!
Oct 21, 2007 at 12:13 PM
Thank you :D
Oct 21, 2007 at 3:53 PM
Cool! Good job getting it working!
Coordinator
Oct 21, 2007 at 4:18 PM
I did test it a bit, but let me know if you guys find anything wrong with it.

Things that might need tested more thoroughly are very small or very large maps, like 8x8, or 1024x1024. Also, I setup a system that should allow for user error. For instance, if the user has setup in the code that they want the terrain's default LOD to be LOD.Low, and then the water is set to use the terrain at LOD.Med, then it should automatically default to the highest available LOD if Med is not available, which would be LOD.Low in this case.

However in the current version the Terrain is set to LOD.Med, but I also have another Terrain at LOD.Minimum created that the water is able to use.
Oct 21, 2007 at 10:59 PM
Edited Oct 21, 2007 at 11:38 PM
The first thing I have noticed; while it does improve performance slightly on my system, the physics seems to be a bit lost, compared to where it was, at least. Although, as far as FPS is concerned, it still drops down to 5/6 FPS. :(

For instance, the large sphere that is created at initialization literally bounces EVERYWHERE.. (Maybe the push down of gravity is too much(lol :p)? Any items I add just bounce like crazy now, not a 'problem' so much, as I'm sure you'll find a small tweak or something, but just letting you know how it reacts for me)

RainWeather no longer works, it appears turning off the weather system doesn't work either, in Water.cs, at the time of Draw() it looks for weather to reflect I'm guessing, but just doesn't find anything, here is the error from Water.cs (I tried using Rain instead of Snow, I have since tried with no weather, and yeah similar problem). Heh, I just copied the error to clipboard, sorry about lack of formatting for it.

System.NullReferenceException was unhandled
Message="Object reference not set to an instance of an object."
Source="TestsForFun"
StackTrace:
at QuickStartEngine.Water.DrawReflectionMap(GameTime gameTime, Matrix& ViewMatrix, Matrix& ProjectionMatrix, Light SceneLight, Camera CurrentCam) in C:\Users\Chu\Documents\Visual Studio 2005\Projects\XNA QuickStart Engine v0.176\TestsForFun\Code\Components\Water\Water.cs:line 454
at QuickStartEngine.Water.Draw(GameTime gameTime, Matrix& ViewMatrix, Matrix& ProjectionMatrix, Light SceneLight, Camera CurrentCam) in C:\Users\Chu\Documents\Visual Studio 2005\Projects\XNA QuickStart Engine v0.176\TestsForFun\Code\Components\Water\Water.cs:line 247
at QuickStartEngine.TestsMain.Draw(GameTime gameTime) in C:\Users\Chu\Documents\Visual Studio 2005\Projects\XNA QuickStart Engine v0.176\TestsForFun\Code\GameMain.cs:line 533
at Microsoft.Xna.Framework.Game.DrawFrame()
at Microsoft.Xna.Framework.Game.Paint(Object sender, EventArgs e)
at Microsoft.Xna.Framework.GameWindow.OnPaint()
at Microsoft.Xna.Framework.WindowsGameWindow.mainForm_Paint(Object sender, PaintEventArgs e)
at System.Windows.Forms.Control.OnPaint(PaintEventArgs e)
at System.Windows.Forms.Form.OnPaint(PaintEventArgs e)
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer, Boolean disposeEventArgs)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.ContainerControl.WndProc(Message& m)
at System.Windows.Forms.Form.WndProc(Message& m)
at Microsoft.Xna.Framework.WindowsGameForm.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at CallWindowProcW(IntPtr , HWND__* , UInt32 , UInt32 , Int32 )
at MouseSubClassFunc(HWND__* hWnd, UInt32 msg, UInt32 wParam, Int32 lParam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at Microsoft.Xna.Framework.WindowsGameHost.Run()
at Microsoft.Xna.Framework.Game.Run()
at QuickStartEngine.Program.Main(String[] args) in C:\Users\Chu\Documents\Visual Studio 2005\Projects\XNA QuickStart Engine v0.176\TestsForFun\Code\Program.cs:line 14

Umm yeah, still playing around with it, just wanted to give you some feedback.

Edit: This should probably be in the Issue Tracker, I notice you mention the physics in there, it's a known problem? Heh, this is all so far above me, but I'm having fun looking through this code.

Edit Again: I found LoadWater() in GameMain.cs - I need to set up an association between the water and the RainWeather, as done with SnowWeather I guess? What about with no weather?
*I Still get the error, after SceneWater.Associate(RainWeather, true, false);
Coordinator
Oct 21, 2007 at 11:39 PM
You need to make sure if you use a different weather system you need to go to LoadWeatherSystems() and uncomment the rainsystem and comment out the snow system. It is working on my system.

However, the framerate is definitely fluctuating wildly now, and that is causing the physics issues. Another day, another bug...... At least this one can be tested by everyone.
Oct 21, 2007 at 11:44 PM
Yep, I have uncommented the RainWeather, actually the first thing I usually do when you release a new version is either turn off the Weather systems all together, or replace the Snow with Rain, since Snow is quite heavy on my laptop (Which is why I posted this, it usually works flawlessly) :p
Coordinator
Oct 21, 2007 at 11:51 PM
I'm checking into the possibility that garbage collecting is causing this, and I don't think that is our problem. Garbage collecting is occuring every 10 seconds or so (which I believe is way too much), but the framerate issue is fairly constant.
Oct 22, 2007 at 12:01 AM
Well, to be honest, the introduction of this LODing algorithm hasn't 'improved' my frame rate at all, I still got 5/6 FPS on the earlier releases too. But what it DOES do, is just make the scene more 'crisper' I guess, everything flows better and definitely LOOKS more visually appealing, but it still runs like a dog :p

I haven't tested 0.176 on my PC though, all of this has been on my laptop.
Coordinator
Oct 22, 2007 at 12:15 AM
Ok, I believe the problem was due to unlocking the framerate, go into SetupGraphicsDevice() in GameMain.cs and comment these back out:

// Uncomment this to see the actual maximum attainable frames per second
//Graphics.SynchronizeWithVerticalRetrace = false;

// Uncomment to remove FPS limit
//IsFixedTimeStep = false;
Oct 22, 2007 at 12:29 AM
Edited Oct 22, 2007 at 12:55 AM
Ahh, I've ruined it somehow, I get the Water.cs error now with or without Snow :(

Apparently, the last component ReflectedComponents is null, and I'm too lazy to step through it and find where this last component should be set up :p

Edit: Worked it out actually, over a cigarette. It appears when I set the association between SceneWater and RainWeather, it adds RainWeather as a null component, thus in Water.cs when it tries to Draw() all ReflectedComponents it gives me an error.
Coordinator
Oct 22, 2007 at 3:19 AM
Yes, you need to go to LoadWeatherSystems() and make sure that the weather system you are associating is uncommented. Also, make sure you haven't commented out the LoadWeatherSystems() call in Initialize(). If all else fails just download the build again.
Oct 22, 2007 at 8:06 AM
lol

I feel stupid after working out how easy that is.

Surely there could in theory be a system in place that could dynamically control weather? I could look into it if you think it would be a good thing.
Coordinator
Oct 22, 2007 at 1:15 PM
Depends on what you mean by dynamic weather. Currently the intensity of the weather is adjustable, and each weather particle reacts dynamically to gravity and wind. I had considered randomly fluctuating wind speeds, like wind gusts, but I didn't think it would be noticable. We could have sound, like raindrops hitting water, or wind gusting.

What did you have in mind?
Oct 22, 2007 at 7:46 PM
Edited Oct 22, 2007 at 7:59 PM
If the physics is going crazy while fixed time step is off, its possible you are reading from gameTime.ElapsedGameTime instead of gameTime.ElapsedRealTime somewhere. I can't check the code now so im only guessing, but I once made that mistake and had the same symptoms.

Edit: I just checked and you are getting ElapsedGameTime, but this laptop doesn't have a SM2.0 compatible card, so I can't test if it fixed the problem.
Coordinator
Oct 22, 2007 at 8:14 PM
If I use real time then I don't believe the engine could have a pause feature. For instance, if the player paused while something was falling, when they got back the item would see a huge time lapse and compensate by "freaking out", so to speak.
Oct 22, 2007 at 8:41 PM
Edited Oct 22, 2007 at 8:47 PM
Well you could have the engine just stop calling Update() to anything that doesnt want to update during a pause, but still continue the game loop. Or have each component check if the game is paused and return if it shouldnt update. Then when the game unpauses things just carry on as usual, taking the time from the last update. At most the first frame will be too short (the previous frame wasnt doing much) but as you just came out of a pause it wouldn't be noticable.

As long as the game continues running its update loop (which it should :P), then the gameTime won't be accumilating and so there should be no jumping when you unpause.
Coordinator
Oct 23, 2007 at 12:51 AM
I'll look into this and see how it works, it would be nice to be able to lock and unlock framerates without adverse affects.
Oct 23, 2007 at 5:45 AM
I haven't really looked at the code just yet, but in a different project I've used elapsedTime which was passed to the update/render methods. In order to "pause" an entity, 0 was passed to the update method, though this never really made any sense and later refactored so that update simply wasn't invoked if an entity was paused. As the entities of the enging were divided into different groups in the graph, pausing the game would simply only pause specific branches of the root (Models/Terrain etc.). Weather/Menu/Etc weren't paused and would react to user input. Unpausing the game would simply reinvoke render and pass the elapsed time from the last render cycle. This made a seamless pause without any "weird" behavior.
Oct 23, 2007 at 1:14 PM
Could anyone check if the ElapsedGameTime is the cause of the physics issues?
Oct 25, 2007 at 8:34 PM
I finally got on a PC with a graphics card that supports SM2.0 :P

Changing ElapsedGameTime to ElapsedRealTime did seem to fix the phyics.
If you just skip the update() call to physics (and anything else that should stop) while the game is paused, but keep the main loop running (which you would want to do anyway, else you cant unpause xD) then there is no skipping forward in time when you unpause.
Coordinator
Oct 25, 2007 at 8:47 PM
Sweet, feel free to submit a patch if you've tested everything :op

Thanks!

While you're doing that, could you set a const bool in the Properties of GameMain.cs for FRAMERATEUNLOCKED = false; Then in SetupGraphicsDevice(), you can do an if statement for if FRAMERATEUNLOCKED.
Oct 26, 2007 at 1:03 PM
I tried to upload the patch last night, but codeplex kept giving errors. But it seems it doesn't matter, as when I looked at the code this morning it has broken itself again : /

Guess I'm going to have to take another look at it.