mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-16 19:19:56 +00:00
Refactor BufferCache to allow caching buffers of different sizes
This commit is contained in:
parent
9a3a64f0c4
commit
274690f790
3 changed files with 24 additions and 27 deletions
|
@ -178,56 +178,56 @@ osg::ref_ptr<IndexArrayType> createIndexBuffer(unsigned int flags, unsigned int
|
|||
namespace Terrain
|
||||
{
|
||||
|
||||
osg::ref_ptr<osg::Vec2Array> BufferCache::getUVBuffer()
|
||||
osg::ref_ptr<osg::Vec2Array> BufferCache::getUVBuffer(unsigned int numVerts)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mUvBufferMutex);
|
||||
if (mUvBufferMap.find(mNumVerts) != mUvBufferMap.end())
|
||||
if (mUvBufferMap.find(numVerts) != mUvBufferMap.end())
|
||||
{
|
||||
return mUvBufferMap[mNumVerts];
|
||||
return mUvBufferMap[numVerts];
|
||||
}
|
||||
|
||||
int vertexCount = mNumVerts * mNumVerts;
|
||||
int vertexCount = numVerts * numVerts;
|
||||
|
||||
osg::ref_ptr<osg::Vec2Array> uvs (new osg::Vec2Array);
|
||||
uvs->reserve(vertexCount);
|
||||
|
||||
for (unsigned int col = 0; col < mNumVerts; ++col)
|
||||
for (unsigned int col = 0; col < numVerts; ++col)
|
||||
{
|
||||
for (unsigned int row = 0; row < mNumVerts; ++row)
|
||||
for (unsigned int row = 0; row < numVerts; ++row)
|
||||
{
|
||||
uvs->push_back(osg::Vec2f(col / static_cast<float>(mNumVerts-1),
|
||||
((mNumVerts-1) - row) / static_cast<float>(mNumVerts-1)));
|
||||
uvs->push_back(osg::Vec2f(col / static_cast<float>(numVerts-1),
|
||||
((numVerts-1) - row) / static_cast<float>(numVerts-1)));
|
||||
}
|
||||
}
|
||||
|
||||
// Assign a VBO here to enable state sharing between different Geometries.
|
||||
uvs->setVertexBufferObject(new osg::VertexBufferObject);
|
||||
|
||||
mUvBufferMap[mNumVerts] = uvs;
|
||||
mUvBufferMap[numVerts] = uvs;
|
||||
return uvs;
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::DrawElements> BufferCache::getIndexBuffer(unsigned int flags)
|
||||
osg::ref_ptr<osg::DrawElements> BufferCache::getIndexBuffer(unsigned int numVerts, unsigned int flags)
|
||||
{
|
||||
std::pair<int, int> id = std::make_pair(numVerts, flags);
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mIndexBufferMutex);
|
||||
unsigned int verts = mNumVerts;
|
||||
|
||||
if (mIndexBufferMap.find(flags) != mIndexBufferMap.end())
|
||||
if (mIndexBufferMap.find(id) != mIndexBufferMap.end())
|
||||
{
|
||||
return mIndexBufferMap[flags];
|
||||
return mIndexBufferMap[id];
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::DrawElements> buffer;
|
||||
|
||||
if (verts*verts <= (0xffffu))
|
||||
buffer = createIndexBuffer<osg::DrawElementsUShort>(flags, verts);
|
||||
if (numVerts*numVerts <= (0xffffu))
|
||||
buffer = createIndexBuffer<osg::DrawElementsUShort>(flags, numVerts);
|
||||
else
|
||||
buffer = createIndexBuffer<osg::DrawElementsUInt>(flags, verts);
|
||||
buffer = createIndexBuffer<osg::DrawElementsUInt>(flags, numVerts);
|
||||
|
||||
// Assign a EBO here to enable state sharing between different Geometries.
|
||||
buffer->setElementBufferObject(new osg::ElementBufferObject);
|
||||
|
||||
mIndexBufferMap[flags] = buffer;
|
||||
mIndexBufferMap[id] = buffer;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,28 +14,24 @@ namespace Terrain
|
|||
class BufferCache
|
||||
{
|
||||
public:
|
||||
BufferCache(unsigned int numVerts) : mNumVerts(numVerts) {}
|
||||
|
||||
/// @param flags first 4*4 bits are LOD deltas on each edge, respectively (4 bits each)
|
||||
/// next 4 bits are LOD level of the index buffer (LOD 0 = don't omit any vertices)
|
||||
/// @note Thread safe.
|
||||
osg::ref_ptr<osg::DrawElements> getIndexBuffer (unsigned int flags);
|
||||
osg::ref_ptr<osg::DrawElements> getIndexBuffer (unsigned int numVerts, unsigned int flags);
|
||||
|
||||
/// @note Thread safe.
|
||||
osg::ref_ptr<osg::Vec2Array> getUVBuffer();
|
||||
osg::ref_ptr<osg::Vec2Array> getUVBuffer(unsigned int numVerts);
|
||||
|
||||
// TODO: add releaseGLObjects() for our vertex/element buffer objects
|
||||
|
||||
private:
|
||||
// Index buffers are shared across terrain batches where possible. There is one index buffer for each
|
||||
// combination of LOD deltas and index buffer LOD we may need.
|
||||
std::map<int, osg::ref_ptr<osg::DrawElements> > mIndexBufferMap;
|
||||
std::map<std::pair<int, int>, osg::ref_ptr<osg::DrawElements> > mIndexBufferMap;
|
||||
OpenThreads::Mutex mIndexBufferMutex;
|
||||
|
||||
std::map<int, osg::ref_ptr<osg::Vec2Array> > mUvBufferMap;
|
||||
OpenThreads::Mutex mUvBufferMutex;
|
||||
|
||||
unsigned int mNumVerts;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -51,7 +51,6 @@ namespace Terrain
|
|||
TerrainGrid::TerrainGrid(osg::Group* parent, Resource::ResourceSystem* resourceSystem, osgUtil::IncrementalCompileOperation* ico, Storage* storage, int nodeMask, Shader::ShaderManager* shaderManager, SceneUtil::UnrefQueue* unrefQueue)
|
||||
: Terrain::World(parent, resourceSystem, ico, storage, nodeMask)
|
||||
, mNumSplits(4)
|
||||
, mCache((storage->getCellVertices()-1)/static_cast<float>(mNumSplits) + 1)
|
||||
, mUnrefQueue(unrefQueue)
|
||||
, mShaderManager(shaderManager)
|
||||
{
|
||||
|
@ -130,7 +129,9 @@ osg::ref_ptr<osg::Node> TerrainGrid::buildTerrain (osg::Group* parent, float chu
|
|||
geometry->setUseDisplayList(false);
|
||||
geometry->setUseVertexBufferObjects(true);
|
||||
|
||||
geometry->addPrimitiveSet(mCache.getIndexBuffer(0));
|
||||
unsigned int numVerts = (mStorage->getCellVertices()-1) * chunkSize + 1;
|
||||
|
||||
geometry->addPrimitiveSet(mCache.getIndexBuffer(numVerts, 0));
|
||||
|
||||
// we already know the bounding box, so no need to let OSG compute it.
|
||||
osg::Vec3f min(-0.5f*mStorage->getCellWorldSize()*chunkSize,
|
||||
|
@ -184,7 +185,7 @@ osg::ref_ptr<osg::Node> TerrainGrid::buildTerrain (osg::Group* parent, float chu
|
|||
|
||||
// use texture coordinates for both texture units, the layer texture and blend texture
|
||||
for (unsigned int i=0; i<2; ++i)
|
||||
geometry->setTexCoordArray(i, mCache.getUVBuffer());
|
||||
geometry->setTexCoordArray(i, mCache.getUVBuffer(numVerts));
|
||||
|
||||
float blendmapScale = ESM::Land::LAND_TEXTURE_SIZE*chunkSize;
|
||||
|
||||
|
|
Loading…
Reference in a new issue