Skip to content

Commit acc74da

Browse files
W3DVolumetricShadow: Prevent crashes due to overflowing shadow vertex/index buffers
1 parent 4b359f0 commit acc74da

2 files changed

Lines changed: 40 additions & 32 deletions

File tree

Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DVolumetricShadow.cpp

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,19 +1254,24 @@ void W3DVolumetricShadow::RenderMeshVolume(Int meshIndex, Int lightIndex, const
12541254
W3DBufferManager::W3DVertexBufferSlot *vbSlot=m_shadowVolumeVB[lightIndex][ meshIndex ];
12551255
if (!vbSlot)
12561256
return;
1257+
1258+
// Check if buffer is too small - skip rendering if shadow is too complex
1259+
if (vbSlot->m_size < numVerts)
1260+
return;
1261+
12571262
if (vbSlot->m_VB->m_DX8VertexBuffer->Get_DX8_Vertex_Buffer() != lastActiveVertexBuffer)
12581263
{ lastActiveVertexBuffer=vbSlot->m_VB->m_DX8VertexBuffer->Get_DX8_Vertex_Buffer();
12591264
m_pDev->SetStreamSource(0,lastActiveVertexBuffer,
12601265
vbSlot->m_VB->m_DX8VertexBuffer->FVF_Info().Get_FVF_Size()); //12 bytes per vertex.
12611266
}
12621267

1263-
DEBUG_ASSERTCRASH(vbSlot->m_size >= numVerts,("Overflowing Shadow Vertex Buffer Slot"));
1264-
12651268
W3DBufferManager::W3DIndexBufferSlot *ibSlot=m_shadowVolumeIB[lightIndex][ meshIndex ];
12661269
if (!ibSlot)
12671270
return;
12681271

1269-
DEBUG_ASSERTCRASH(ibSlot->m_size >= numIndex,("Overflowing Shadow Index Buffer Slot"));
1272+
// Check if buffer is too small - skip rendering if shadow is too complex
1273+
if (ibSlot->m_size < numIndex)
1274+
return;
12701275

12711276
m_pDev->SetIndices(ibSlot->m_IB->m_DX8IndexBuffer->Get_DX8_Index_Buffer(),vbSlot->m_start);
12721277

@@ -2794,32 +2799,31 @@ void W3DVolumetricShadow::constructVolumeVB( Vector3 *lightPosObject,Real shadow
27942799
vbSlot=m_shadowVolumeVB[ volumeIndex ][meshIndex] = TheW3DBufferManager->getSlot(W3DBufferManager::VBM_FVF_XYZ,
27952800
vertexCount);
27962801

2797-
DEBUG_ASSERTCRASH(vbSlot != NULL, ("Can't allocate vertex buffer slot for shadow volume"));
2798-
if (vbSlot != NULL)
2802+
// Check if vertex buffer allocation failed or is too small
2803+
if (vbSlot == NULL || vbSlot->m_size < vertexCount)
27992804
{
2800-
DEBUG_ASSERTCRASH(vbSlot->m_size >= vertexCount,("Overflowing Shadow Vertex Buffer Slot"));
2805+
// Shadow volume too complex for available buffers - skip rendering instead of crashing
2806+
if (vbSlot)
2807+
TheW3DBufferManager->releaseSlot(vbSlot);
2808+
m_shadowVolumeVB[ volumeIndex ][meshIndex] = NULL;
2809+
return;
28012810
}
28022811

28032812
DEBUG_ASSERTCRASH(m_shadowVolume[ volumeIndex ][meshIndex]->GetNumPolygon() == 0,("Updating Existing Static Shadow Volume"));
28042813

28052814
DEBUG_ASSERTCRASH(m_shadowVolumeIB[ volumeIndex ][meshIndex] == NULL,("Updating Existing Static Index Buffer Shadow"));
28062815
ibSlot=m_shadowVolumeIB[ volumeIndex ][meshIndex] = TheW3DBufferManager->getSlot(polygonCount*3);
28072816

2808-
DEBUG_ASSERTCRASH(ibSlot != NULL, ("Can't allocate index buffer slot for shadow volume"));
2809-
if (ibSlot != NULL)
2817+
// Check if index buffer allocation failed or is too small
2818+
if (ibSlot == NULL || ibSlot->m_size < (polygonCount*3))
28102819
{
2811-
DEBUG_ASSERTCRASH(ibSlot->m_size >= (polygonCount*3),("Overflowing Shadow Index Buffer Slot"));
2812-
}
2813-
2814-
if (!ibSlot || !vbSlot)
2815-
{ //could not allocate storage to hold buffers
2820+
// Shadow volume too complex for available buffers - skip rendering instead of crashing
28162821
if (ibSlot)
28172822
TheW3DBufferManager->releaseSlot(ibSlot);
28182823
if (vbSlot)
28192824
TheW3DBufferManager->releaseSlot(vbSlot);
2820-
2821-
m_shadowVolumeIB[ volumeIndex ][meshIndex]=NULL;
2822-
m_shadowVolumeVB[ volumeIndex ][meshIndex]=NULL;
2825+
m_shadowVolumeIB[ volumeIndex ][meshIndex] = NULL;
2826+
m_shadowVolumeVB[ volumeIndex ][meshIndex] = NULL;
28232827
return;
28242828
}
28252829

GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DVolumetricShadow.cpp

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,19 +1360,24 @@ void W3DVolumetricShadow::RenderMeshVolume(Int meshIndex, Int lightIndex, const
13601360
W3DBufferManager::W3DVertexBufferSlot *vbSlot=m_shadowVolumeVB[lightIndex][ meshIndex ];
13611361
if (!vbSlot)
13621362
return;
1363+
1364+
// Check if buffer is too small - skip rendering if shadow is too complex
1365+
if (vbSlot->m_size < numVerts)
1366+
return;
1367+
13631368
if (vbSlot->m_VB->m_DX8VertexBuffer->Get_DX8_Vertex_Buffer() != lastActiveVertexBuffer)
13641369
{ lastActiveVertexBuffer=vbSlot->m_VB->m_DX8VertexBuffer->Get_DX8_Vertex_Buffer();
13651370
m_pDev->SetStreamSource(0,lastActiveVertexBuffer,
13661371
vbSlot->m_VB->m_DX8VertexBuffer->FVF_Info().Get_FVF_Size()); //12 bytes per vertex.
13671372
}
13681373

1369-
DEBUG_ASSERTCRASH(vbSlot->m_size >= numVerts,("Overflowing Shadow Vertex Buffer Slot"));
1370-
13711374
W3DBufferManager::W3DIndexBufferSlot *ibSlot=m_shadowVolumeIB[lightIndex][ meshIndex ];
13721375
if (!ibSlot)
13731376
return;
13741377

1375-
DEBUG_ASSERTCRASH(ibSlot->m_size >= numIndex,("Overflowing Shadow Index Buffer Slot"));
1378+
// Check if buffer is too small - skip rendering if shadow is too complex
1379+
if (ibSlot->m_size < numIndex)
1380+
return;
13761381

13771382
m_pDev->SetIndices(ibSlot->m_IB->m_DX8IndexBuffer->Get_DX8_Index_Buffer(),vbSlot->m_start);
13781383

@@ -2938,32 +2943,31 @@ void W3DVolumetricShadow::constructVolumeVB( Vector3 *lightPosObject,Real shadow
29382943
vbSlot=m_shadowVolumeVB[ volumeIndex ][meshIndex] = TheW3DBufferManager->getSlot(W3DBufferManager::VBM_FVF_XYZ,
29392944
vertexCount);
29402945

2941-
DEBUG_ASSERTCRASH(vbSlot != NULL, ("Can't allocate vertex buffer slot for shadow volume"));
2942-
if (vbSlot != NULL)
2946+
// Check if vertex buffer allocation failed or is too small
2947+
if (vbSlot == NULL || vbSlot->m_size < vertexCount)
29432948
{
2944-
DEBUG_ASSERTCRASH(vbSlot->m_size >= vertexCount,("Overflowing Shadow Vertex Buffer Slot"));
2949+
// Shadow volume too complex for available buffers - skip rendering instead of crashing
2950+
if (vbSlot)
2951+
TheW3DBufferManager->releaseSlot(vbSlot);
2952+
m_shadowVolumeVB[ volumeIndex ][meshIndex] = NULL;
2953+
return;
29452954
}
29462955

29472956
DEBUG_ASSERTCRASH(m_shadowVolume[ volumeIndex ][meshIndex]->GetNumPolygon() == 0,("Updating Existing Static Shadow Volume"));
29482957

29492958
DEBUG_ASSERTCRASH(m_shadowVolumeIB[ volumeIndex ][meshIndex] == NULL,("Updating Existing Static Index Buffer Shadow"));
29502959
ibSlot=m_shadowVolumeIB[ volumeIndex ][meshIndex] = TheW3DBufferManager->getSlot(polygonCount*3);
29512960

2952-
DEBUG_ASSERTCRASH(ibSlot != NULL, ("Can't allocate index buffer slot for shadow volume"));
2953-
if (ibSlot != NULL)
2961+
// Check if index buffer allocation failed or is too small
2962+
if (ibSlot == NULL || ibSlot->m_size < (polygonCount*3))
29542963
{
2955-
DEBUG_ASSERTCRASH(ibSlot->m_size >= (polygonCount*3),("Overflowing Shadow Index Buffer Slot"));
2956-
}
2957-
2958-
if (!ibSlot || !vbSlot)
2959-
{ //could not allocate storage to hold buffers
2964+
// Shadow volume too complex for available buffers - skip rendering instead of crashing
29602965
if (ibSlot)
29612966
TheW3DBufferManager->releaseSlot(ibSlot);
29622967
if (vbSlot)
29632968
TheW3DBufferManager->releaseSlot(vbSlot);
2964-
2965-
m_shadowVolumeIB[ volumeIndex ][meshIndex]=NULL;
2966-
m_shadowVolumeVB[ volumeIndex ][meshIndex]=NULL;
2969+
m_shadowVolumeIB[ volumeIndex ][meshIndex] = NULL;
2970+
m_shadowVolumeVB[ volumeIndex ][meshIndex] = NULL;
29672971
return;
29682972
}
29692973

0 commit comments

Comments
 (0)