[fixed]CTerrainSceneNode given Bad Touch by VBOs

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

[fixed]CTerrainSceneNode given Bad Touch by VBOs

Post by rogerborg »

SVN 1270, example 12. TerrainRendering. Build and run, then move the camera around a bit and an array bound overflow is encountered in RenderBuffer.Indices[] in CTerrainSceneNode::preRenderIndicesCalculations().

It seems that the Indices need to be resized before being written to. That could either be done inside the TerrainData.PatchCount loop (fragmentastic) or by duplicating it.

The patch below demonstrates the latter fix, but it's for illustrative purposes only. I may be missing something about why this is happening, and hopefully Luke will have a smarter fix.

Code: Select all

Index: source/Irrlicht/CTerrainSceneNode.cpp
===================================================================
--- source/Irrlicht/CTerrainSceneNode.cpp	(revision 1270)
+++ source/Irrlicht/CTerrainSceneNode.cpp	(working copy)
@@ -486,6 +486,8 @@
 		s32 index22;
 
 		// Then generate the indices for all patches that are visible.
+
+		// Work out how big the index array needs to be
 		for( s32 i = 0; i < TerrainData.PatchCount; ++i )
 		{
 			for( s32 j = 0; j < TerrainData.PatchCount; ++j )
@@ -495,7 +497,37 @@
 				{
 					s32 x = 0;
 					s32 z = 0;
+					s32 step = 1 << TerrainData.Patches[index].CurrentLOD;
 
+					while( z < TerrainData.CalcPatchSize )
+					{
+						IndicesToRender += 6;
+
+						x += step;
+						if ( x >= TerrainData.CalcPatchSize ) // we've hit an edge
+						{
+							x = 0;
+							z += step;
+						}
+					}
+				}
+			}
+		}
+
+		RenderBuffer.Indices.set_used(IndicesToRender);
+
+		IndicesToRender = 0;
+
+		for( s32 i = 0; i < TerrainData.PatchCount; ++i )
+		{
+			for( s32 j = 0; j < TerrainData.PatchCount; ++j )
+			{
+				s32 index = i * TerrainData.PatchCount + j;
+				if( TerrainData.Patches[index].CurrentLOD >= 0 )
+				{
+					s32 x = 0;
+					s32 z = 0;
+
 					// calculate the step we take this patch, based on the patches current LOD
 					s32 step = 1 << TerrainData.Patches[index].CurrentLOD;
 
@@ -527,8 +559,6 @@
 			}
 		}
 
-		RenderBuffer.Indices.set_used(IndicesToRender);
-
 		RenderBuffer.setDirty(EBT_INDEX);
 
 		if ( DynamicSelectorUpdate && TriangleSelector )

Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Luke
Admin
Posts: 449
Joined: Fri Jul 14, 2006 7:55 am
Location: Australia
Contact:

Post by Luke »

sorry about that, didn't test with the debug build, so I didn't get that crash.

the array was allocated to the right size, but the array bounds check doesn't like it.

fixed now.

btw there are no problems with fragmentation as the array is never truly resized
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

Heh, you're right, it wasn't a crash anyway, it was just a warning. The bounds weren't being exceeded, but I didn't continue past the assert to check that. Small earthquake, not many hurt.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
Post Reply