Page 1 of 1

[fixed]CTerrainSceneNode given Bad Touch by VBOs

Posted: Fri Feb 29, 2008 1:16 pm
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 )


Posted: Sat Mar 01, 2008 5:37 am
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

Posted: Sat Mar 01, 2008 10:20 am
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.