Piotrek
26-04-2015 22:19:51
Hi,
Very often, but not every frame I need to replace vertex and index buffers in SubMesh with new ones which contains new mesh data.
These new buffers are often much smaller or much bigger than previous.
This is my custom lod mechanism where new mesh data is generated dynamically (entity geometry changes very often) and old mesh data need to be removed from memory.
I am only replacing buffers because I don't want to allocated to many objects that will raise GarbageColletor too often.
In my current solution after few minutes I get exceptions. Mostly it is access violation exception or out of video memory exception (GPU-Z show only 400MB usage of 2GB).
So what I am doing wrong? If my approach is wrog how can I do it good ?
Can someone help me?
Currently I do it like this:
First I create Mesh with SubMesh
- For SubMesh i create new VertexData to which I inject cloned VertexDeclaration (that is prepared only once) and new VertexBufferBinding
- New buffers are created with flag HBU_STATIC_WRITE_ONLY and binded to SubMesh's vertexData and indexData
When mesh need to be updated (new lod level mesh is genereted), first I 'clean' SubMesh like this:
- reset current indexData's indexBuffer field and dispose current IndexBuffer
- unbind existing vertex buffer
- dispose current vertexBuffer
Then I create new buffers and attach them to SubMesh
Here is the code:
Exceptions I get:
Unhandled exception at 0x5F38AC50 (nvd3dum.dll) in SpaceTrek.exe: 0xC0000005: Access violation reading location 0x0000041C.
OGRE EXCEPTION(3:RenderingAPIException): Failed to DrawPrimitive : Out of video memory in D3D9RenderSystem::_render at D:\Mogre BUILD\MogreBuilder__Result_bugFixed\Main\OgreSrc\ogre\RenderSystems\Direct3D9\src\OgreD3D9RenderSystem.cpp (line 3139)
OGRE EXCEPTION(3:RenderingAPIException): Cannot restore D3D9 vertex buffer: Ran out of memory in D3D9HardwareVertexBuffer::createBuffer at D:\Mogre BUILD\MogreBuilder__Result_bugFixed\Main\OgreSrc\ogre\RenderSystems\Direct3D9\src\OgreD3D9HardwareVertexBuffer.cpp (line 264)
Very often, but not every frame I need to replace vertex and index buffers in SubMesh with new ones which contains new mesh data.
These new buffers are often much smaller or much bigger than previous.
This is my custom lod mechanism where new mesh data is generated dynamically (entity geometry changes very often) and old mesh data need to be removed from memory.
I am only replacing buffers because I don't want to allocated to many objects that will raise GarbageColletor too often.
In my current solution after few minutes I get exceptions. Mostly it is access violation exception or out of video memory exception (GPU-Z show only 400MB usage of 2GB).
So what I am doing wrong? If my approach is wrog how can I do it good ?
Can someone help me?
Currently I do it like this:
First I create Mesh with SubMesh
- For SubMesh i create new VertexData to which I inject cloned VertexDeclaration (that is prepared only once) and new VertexBufferBinding
- New buffers are created with flag HBU_STATIC_WRITE_ONLY and binded to SubMesh's vertexData and indexData
When mesh need to be updated (new lod level mesh is genereted), first I 'clean' SubMesh like this:
- reset current indexData's indexBuffer field and dispose current IndexBuffer
- unbind existing vertex buffer
- dispose current vertexBuffer
Then I create new buffers and attach them to SubMesh
Here is the code:
MeshPtr meshPtr = MeshManager.Singleton.CreateManual(name, mResourceGroup);
SubMesh subMesh = meshPtr.CreateSubMesh();
subMesh.useSharedVertices = false;
subMesh.vertexData = new VertexData(_vertexDeclaration.Clone(), new VertexBufferBinding());
public void ResetMesh(MeshPtr meshPtr)
{
Debug.Assert(meshPtr.NumSubMeshes == 1 || meshPtr.NumSubMeshes == 0);
if (meshPtr.NumSubMeshes > 0 && meshPtr.GetSubMesh(0).vertexData != null)
{
SubMesh submesh = meshPtr.GetSubMesh(0);
// Destroy IndexBuffer
submesh.indexData.indexCount = 0;
submesh.indexData.indexBuffer.Dispose();
submesh.indexData.indexBuffer = null;
// Destroy VertexBuffer
HardwareVertexBufferSharedPtr vertexBuffer = submesh.vertexData.vertexBufferBinding.GetBuffer(0);
VertexBufferBinding binding = submesh.vertexData.vertexBufferBinding;
submesh.vertexData.vertexCount = 0;
binding.UnsetBinding(0);
// binding.UnsetAllBindings();
submesh.vertexData.RemoveUnusedBuffers();
vertexBuffer.Dispose();
}
}
Exceptions I get:
Unhandled exception at 0x5F38AC50 (nvd3dum.dll) in SpaceTrek.exe: 0xC0000005: Access violation reading location 0x0000041C.
OGRE EXCEPTION(3:RenderingAPIException): Failed to DrawPrimitive : Out of video memory in D3D9RenderSystem::_render at D:\Mogre BUILD\MogreBuilder__Result_bugFixed\Main\OgreSrc\ogre\RenderSystems\Direct3D9\src\OgreD3D9RenderSystem.cpp (line 3139)
OGRE EXCEPTION(3:RenderingAPIException): Cannot restore D3D9 vertex buffer: Ran out of memory in D3D9HardwareVertexBuffer::createBuffer at D:\Mogre BUILD\MogreBuilder__Result_bugFixed\Main\OgreSrc\ogre\RenderSystems\Direct3D9\src\OgreD3D9HardwareVertexBuffer.cpp (line 264)