CMeshBuffer()\r
: ChangedID_Vertex(1), ChangedID_Index(1)\r
, MappingHint_Vertex(EHM_NEVER), MappingHint_Index(EHM_NEVER)\r
+ , HWBuffer(NULL)\r
, PrimitiveType(EPT_TRIANGLES)\r
{\r
#ifdef _DEBUG\r
/** This shouldn't be used for anything outside the VideoDriver. */\r
virtual u32 getChangedID_Index() const _IRR_OVERRIDE_ {return ChangedID_Index;}\r
\r
+ virtual void setHWBuffer(void *ptr) const _IRR_OVERRIDE_ {\r
+ HWBuffer = ptr;\r
+ }\r
+\r
+ virtual void *getHWBuffer() const _IRR_OVERRIDE_ {\r
+ return HWBuffer;\r
+ }\r
+\r
+\r
u32 ChangedID_Vertex;\r
u32 ChangedID_Index;\r
\r
//! hardware mapping hint\r
E_HARDWARE_MAPPING MappingHint_Vertex;\r
E_HARDWARE_MAPPING MappingHint_Index;\r
+ mutable void *HWBuffer;\r
\r
//! Material for this meshbuffer.\r
video::SMaterial Material;\r
/** This shouldn't be used for anything outside the VideoDriver. */\r
virtual u32 getChangedID_Index() const = 0;\r
\r
+ //! Used by the VideoDriver to remember the buffer link.\r
+ virtual void setHWBuffer(void *ptr) const = 0;\r
+ virtual void *getHWBuffer() const = 0;\r
+\r
//! Describe what kind of primitive geometry is used by the meshbuffer\r
/** Note: Default is EPT_TRIANGLES. Using other types is fine for rendering.\r
But meshbuffer manipulation functions might expect type EPT_TRIANGLES\r
ChangedID_Vertex(1), ChangedID_Index(1), VertexType(vt),\r
PrimitiveType(EPT_TRIANGLES),\r
MappingHint_Vertex(EHM_NEVER), MappingHint_Index(EHM_NEVER),\r
+ HWBuffer(NULL),\r
BoundingBoxNeedsRecalculated(true)\r
{\r
#ifdef _DEBUG\r
\r
virtual u32 getChangedID_Index() const _IRR_OVERRIDE_ {return ChangedID_Index;}\r
\r
+ virtual void setHWBuffer(void *ptr) const _IRR_OVERRIDE_ {\r
+ HWBuffer = ptr;\r
+ }\r
+\r
+ virtual void *getHWBuffer() const _IRR_OVERRIDE_ {\r
+ return HWBuffer;\r
+ }\r
+\r
+\r
//! Call this after changing the positions of any vertex.\r
void boundingBoxNeedsRecalculated(void) { BoundingBoxNeedsRecalculated = true; }\r
\r
E_HARDWARE_MAPPING MappingHint_Vertex:3;\r
E_HARDWARE_MAPPING MappingHint_Index:3;\r
\r
+ mutable void *HWBuffer;\r
+\r
bool BoundingBoxNeedsRecalculated:1;\r
};\r
\r
return 0;\r
\r
//search for hardware links\r
- core::map< const scene::IMeshBuffer*,SHWBufferLink* >::Node* node = HWBufferMap.find(mb);\r
- if (node)\r
- return node->getValue();\r
+ SHWBufferLink *HWBuffer = reinterpret_cast<SHWBufferLink*>(mb->getHWBuffer());\r
+ if (HWBuffer)\r
+ return HWBuffer;\r
\r
return createHardwareBuffer(mb); //no hardware links, and mesh wants one, create it\r
}\r
//! Update all hardware buffers, remove unused ones\r
void CNullDriver::updateAllHardwareBuffers()\r
{\r
- core::map<const scene::IMeshBuffer*,SHWBufferLink*>::ParentFirstIterator Iterator=HWBufferMap.getParentFirstIterator();\r
-\r
- for (;!Iterator.atEnd();Iterator++)\r
- {\r
- SHWBufferLink *Link=Iterator.getNode()->getValue();\r
+ auto it = HWBufferList.begin();\r
+ while (it != HWBufferList.end()) {\r
+ SHWBufferLink *Link = *it;\r
+ ++it;\r
\r
- Link->LastUsed++;\r
- if (Link->LastUsed>20000)\r
- {\r
+ if (!Link->MeshBuffer || Link->MeshBuffer->getReferenceCount() == 1)\r
deleteHardwareBuffer(Link);\r
-\r
- // todo: needs better fix\r
- Iterator = HWBufferMap.getParentFirstIterator();\r
- }\r
}\r
}\r
\r
{\r
if (!HWBuffer)\r
return;\r
- HWBufferMap.remove(HWBuffer->MeshBuffer);\r
+ HWBufferList.erase(HWBuffer->listPosition);\r
delete HWBuffer;\r
}\r
\r
//! Remove hardware buffer\r
void CNullDriver::removeHardwareBuffer(const scene::IMeshBuffer* mb)\r
{\r
- core::map<const scene::IMeshBuffer*,SHWBufferLink*>::Node* node = HWBufferMap.find(mb);\r
- if (node)\r
- deleteHardwareBuffer(node->getValue());\r
+ if (!mb)\r
+ return;\r
+ SHWBufferLink *HWBuffer = reinterpret_cast<SHWBufferLink*>(mb->getHWBuffer());\r
+ if (HWBuffer)\r
+ deleteHardwareBuffer(HWBuffer);\r
}\r
\r
\r
//! Remove all hardware buffers\r
void CNullDriver::removeAllHardwareBuffers()\r
{\r
- while (HWBufferMap.size())\r
- deleteHardwareBuffer(HWBufferMap.getRoot()->getValue());\r
+ while (!HWBufferList.empty())\r
+ deleteHardwareBuffer(HWBufferList.front());\r
}\r
\r
\r
#include "SVertexIndex.h"\r
#include "SLight.h"\r
#include "SExposedVideoData.h"\r
+#include <list>\r
\r
namespace irr\r
{\r
{\r
SHWBufferLink(const scene::IMeshBuffer *_MeshBuffer)\r
:MeshBuffer(_MeshBuffer),\r
- ChangedID_Vertex(0),ChangedID_Index(0),LastUsed(0),\r
+ ChangedID_Vertex(0),ChangedID_Index(0),\r
Mapped_Vertex(scene::EHM_NEVER),Mapped_Index(scene::EHM_NEVER)\r
{\r
- if (MeshBuffer)\r
+ if (MeshBuffer) {\r
MeshBuffer->grab();\r
+ MeshBuffer->setHWBuffer(reinterpret_cast<void*>(this));\r
+ }\r
}\r
\r
virtual ~SHWBufferLink()\r
{\r
- if (MeshBuffer)\r
+ if (MeshBuffer) {\r
+ MeshBuffer->setHWBuffer(NULL);\r
MeshBuffer->drop();\r
+ }\r
}\r
\r
const scene::IMeshBuffer *MeshBuffer;\r
u32 ChangedID_Vertex;\r
u32 ChangedID_Index;\r
- u32 LastUsed;\r
scene::E_HARDWARE_MAPPING Mapped_Vertex;\r
scene::E_HARDWARE_MAPPING Mapped_Index;\r
+ std::list<SHWBufferLink*>::iterator listPosition;\r
};\r
\r
//! Gets hardware buffer link from a meshbuffer (may create or update buffer)\r
core::array<SLight> Lights;\r
core::array<SMaterialRenderer> MaterialRenderers;\r
\r
- //core::array<SHWBufferLink*> HWBufferLinks;\r
- core::map< const scene::IMeshBuffer* , SHWBufferLink* > HWBufferMap;\r
+ std::list<SHWBufferLink*> HWBufferList;\r
\r
io::IFileSystem* FileSystem;\r
\r
SHWBufferLink_opengl *HWBuffer = new SHWBufferLink_opengl(mb);\r
\r
//add to map\r
- HWBufferMap.insert(HWBuffer->MeshBuffer, HWBuffer);\r
+ HWBuffer->listPosition = HWBufferList.insert(HWBufferList.end(), HWBuffer);\r
\r
HWBuffer->ChangedID_Vertex = HWBuffer->MeshBuffer->getChangedID_Vertex();\r
HWBuffer->ChangedID_Index = HWBuffer->MeshBuffer->getChangedID_Index();\r
HWBuffer->Mapped_Vertex = mb->getHardwareMappingHint_Vertex();\r
HWBuffer->Mapped_Index = mb->getHardwareMappingHint_Index();\r
- HWBuffer->LastUsed = 0;\r
HWBuffer->vbo_verticesID = 0;\r
HWBuffer->vbo_indicesID = 0;\r
HWBuffer->vbo_verticesSize = 0;\r
\r
updateHardwareBuffer(HWBuffer); //check if update is needed\r
\r
- HWBuffer->LastUsed = 0;//reset count\r
-\r
const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer;\r
const void *vertices = mb->getVertices();\r
const void *indexList = mb->getIndices();\r
SHWBufferLink_opengl *HWBuffer=new SHWBufferLink_opengl(mb);\r
\r
//add to map\r
- HWBufferMap.insert(HWBuffer->MeshBuffer, HWBuffer);\r
+ HWBuffer->listPosition = HWBufferList.insert(HWBufferList.end(), HWBuffer);\r
\r
HWBuffer->ChangedID_Vertex=HWBuffer->MeshBuffer->getChangedID_Vertex();\r
HWBuffer->ChangedID_Index=HWBuffer->MeshBuffer->getChangedID_Index();\r
HWBuffer->Mapped_Vertex=mb->getHardwareMappingHint_Vertex();\r
HWBuffer->Mapped_Index=mb->getHardwareMappingHint_Index();\r
- HWBuffer->LastUsed=0;\r
HWBuffer->vbo_verticesID=0;\r
HWBuffer->vbo_indicesID=0;\r
HWBuffer->vbo_verticesSize=0;\r
\r
updateHardwareBuffer(HWBuffer); //check if update is needed\r
\r
- HWBuffer->LastUsed=0;//reset count\r
-\r
const scene::IMeshBuffer* mb = HWBuffer->MeshBuffer;\r
const void *vertices=mb->getVertices();\r
const void *indexList=mb->getIndices();\r
SHWBufferLink_opengl *HWBuffer=new SHWBufferLink_opengl(mb);\r
\r
//add to map\r
- HWBufferMap.insert(HWBuffer->MeshBuffer, HWBuffer);\r
+ HWBuffer->listPosition = HWBufferList.insert(HWBufferList.end(), HWBuffer);\r
\r
HWBuffer->ChangedID_Vertex=HWBuffer->MeshBuffer->getChangedID_Vertex();\r
HWBuffer->ChangedID_Index=HWBuffer->MeshBuffer->getChangedID_Index();\r
HWBuffer->Mapped_Vertex=mb->getHardwareMappingHint_Vertex();\r
HWBuffer->Mapped_Index=mb->getHardwareMappingHint_Index();\r
- HWBuffer->LastUsed=0;\r
HWBuffer->vbo_verticesID=0;\r
HWBuffer->vbo_indicesID=0;\r
HWBuffer->vbo_verticesSize=0;\r
return;\r
\r
updateHardwareBuffer(_HWBuffer); //check if update is needed\r
- _HWBuffer->LastUsed=0; //reset count\r
\r
#if defined(GL_ARB_vertex_buffer_object)\r
SHWBufferLink_opengl *HWBuffer=(SHWBufferLink_opengl*)_HWBuffer;\r