[fixed]CTerrainSceneNode given Bad Touch by VBOs
Posted: Fri Feb 29, 2008 1:16 pm
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.
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 )