summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/llstrider.h10
-rw-r--r--indra/newview/llface.cpp19
-rw-r--r--indra/newview/llspatialpartition.h7
-rw-r--r--indra/newview/llviewerpartsim.cpp2
-rw-r--r--indra/newview/llviewerpartsim.h2
-rwxr-xr-xindra/newview/llviewerwindow.cpp6
-rw-r--r--indra/newview/llvograss.cpp139
-rw-r--r--indra/newview/llvopartgroup.cpp265
-rw-r--r--indra/newview/llvopartgroup.h13
-rw-r--r--indra/newview/pipeline.cpp26
10 files changed, 403 insertions, 86 deletions
diff --git a/indra/llcommon/llstrider.h b/indra/llcommon/llstrider.h
index f4c43bac61..ed9284d2c5 100644
--- a/indra/llcommon/llstrider.h
+++ b/indra/llcommon/llstrider.h
@@ -44,6 +44,15 @@ public:
const LLStrider<Object>& operator = (Object *first) { mObjectp = first; return *this;}
void setStride (S32 skipBytes) { mSkip = (skipBytes ? skipBytes : sizeof(Object));}
+ LLStrider<Object> operator+(const S32& index)
+ {
+ LLStrider<Object> ret;
+ ret.mBytep = mBytep + mSkip*index;
+ ret.mSkip = mSkip;
+
+ return ret;
+ }
+
void skip(const U32 index) { mBytep += mSkip*index;}
U32 getSkip() const { return mSkip; }
Object* get() { return mObjectp; }
@@ -51,6 +60,7 @@ public:
Object& operator *() { return *mObjectp; }
Object* operator ++(int) { Object* old = mObjectp; mBytep += mSkip; return old; }
Object* operator +=(int i) { mBytep += mSkip*i; return mObjectp; }
+
Object& operator[](U32 index) { return *(Object*)(mBytep + (mSkip * index)); }
};
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 4108d69e82..97b832520d 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -44,6 +44,7 @@
#include "llsky.h"
#include "llviewercamera.h"
#include "llviewertexturelist.h"
+#include "llvopartgroup.h"
#include "llvosky.h"
#include "llvovolume.h"
#include "pipeline.h"
@@ -161,7 +162,15 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp)
mGeomCount = 0;
mGeomIndex = 0;
mIndicesCount = 0;
- mIndicesIndex = 0;
+ if (drawablep->getRenderType() == LLPipeline::RENDER_TYPE_PARTICLES ||
+ drawablep->getRenderType() == LLPipeline::RENDER_TYPE_HUD_PARTICLES)
+ { //indicate to LLParticlePartition that this particle is uninitialized
+ mIndicesIndex = 0xFFFFFFFF;
+ }
+ else
+ {
+ mIndicesIndex = 0;
+ }
mIndexInTex = 0;
mTexture = NULL;
mTEOffset = -1;
@@ -203,6 +212,14 @@ void LLFace::destroy()
mTexture->removeFace(this) ;
}
+ if (mDrawablep.notNull() &&
+ (mDrawablep->getRenderType() == LLPipeline::RENDER_TYPE_PARTICLES ||
+ mDrawablep->getRenderType() == LLPipeline::RENDER_TYPE_HUD_PARTICLES) &&
+ mIndicesIndex != 0xFFFFFFFF)
+ {
+ LLVOPartGroup::freeVBSlot(getGeomIndex()/4);
+ }
+
if (mDrawPoolp)
{
if (this->isState(LLFace::RIGGED) && mDrawPoolp->getType() == LLDrawPool::POOL_AVATAR)
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index ccc65f3da0..65ae41eeee 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -657,6 +657,7 @@ class LLParticlePartition : public LLSpatialPartition
{
public:
LLParticlePartition();
+ virtual void rebuildGeom(LLSpatialGroup* group);
virtual void getGeometry(LLSpatialGroup* group);
virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count);
virtual F32 calcPixelArea(LLSpatialGroup* group, LLCamera& camera);
@@ -671,10 +672,14 @@ public:
};
//spatial partition for grass (implemented in LLVOGrass.cpp)
-class LLGrassPartition : public LLParticlePartition
+class LLGrassPartition : public LLSpatialPartition
{
public:
LLGrassPartition();
+ virtual void getGeometry(LLSpatialGroup* group);
+ virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32& index_count);
+protected:
+ U32 mRenderPass;
};
//class for wrangling geometry out of volumes (implemented in LLVOVolume.cpp)
diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index 6b3e04348a..345023dbfa 100644
--- a/indra/newview/llviewerpartsim.cpp
+++ b/indra/newview/llviewerpartsim.cpp
@@ -476,7 +476,7 @@ void LLViewerPartSim::checkParticleCount(U32 size)
LLViewerPartSim::LLViewerPartSim()
{
LLMemType mt(LLMemType::MTYPE_PARTICLES);
- sMaxParticleCount = gSavedSettings.getS32("RenderMaxPartCount");
+ sMaxParticleCount = llmin(gSavedSettings.getS32("RenderMaxPartCount"), LL_MAX_PARTICLE_COUNT);
static U32 id_seed = 0;
mID = ++id_seed;
}
diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h
index 3e20f999c0..c9959c63ec 100644
--- a/indra/newview/llviewerpartsim.h
+++ b/indra/newview/llviewerpartsim.h
@@ -39,6 +39,8 @@ class LLViewerRegion;
class LLViewerTexture;
class LLVOPartGroup;
+#define LL_MAX_PARTICLE_COUNT 8192
+
typedef void (*LLVPCallback)(LLViewerPart &part, const F32 dt);
///////////////////
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 35527d4977..0a582107af 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -175,6 +175,7 @@
#include "llviewershadermgr.h"
#include "llviewerstats.h"
#include "llvoavatarself.h"
+#include "llvopartgroup.h"
#include "llvovolume.h"
#include "llworld.h"
#include "llworldmapview.h"
@@ -4654,6 +4655,8 @@ void LLViewerWindow::stopGL(BOOL save_state)
LLVOAvatar::destroyGL();
stop_glerror();
+ LLVOPartGroup::destroyGL();
+
LLViewerDynamicTexture::destroyGL();
stop_glerror();
@@ -4707,7 +4710,8 @@ void LLViewerWindow::restoreGL(const std::string& progress_message)
gBumpImageList.restoreGL();
LLViewerDynamicTexture::restoreGL();
LLVOAvatar::restoreGL();
-
+ LLVOPartGroup::restoreGL();
+
gResizeScreenTexture = TRUE;
gWindowResized = TRUE;
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index 8a79d564d3..be3558aad1 100644
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -34,6 +34,7 @@
#include "llagentcamera.h"
#include "llnotificationsutil.h"
#include "lldrawable.h"
+#include "lldrawpoolalpha.h"
#include "llface.h"
#include "llsky.h"
#include "llsurface.h"
@@ -594,6 +595,7 @@ U32 LLVOGrass::getPartitionType() const
}
LLGrassPartition::LLGrassPartition()
+: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW_ARB)
{
mDrawableType = LLPipeline::RENDER_TYPE_GRASS;
mPartitionType = LLViewerRegion::PARTITION_GRASS;
@@ -604,6 +606,143 @@ LLGrassPartition::LLGrassPartition()
mBufferUsage = GL_DYNAMIC_DRAW_ARB;
}
+void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count)
+{
+ group->mBufferUsage = mBufferUsage;
+
+ mFaceList.clear();
+
+ LLViewerCamera* camera = LLViewerCamera::getInstance();
+ for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
+ {
+ LLDrawable* drawablep = *i;
+
+ if (drawablep->isDead())
+ {
+ continue;
+ }
+
+ LLAlphaObject* obj = (LLAlphaObject*) drawablep->getVObj().get();
+ obj->mDepth = 0.f;
+
+ if (drawablep->isAnimating())
+ {
+ group->mBufferUsage = GL_STREAM_DRAW_ARB;
+ }
+
+ U32 count = 0;
+ for (S32 j = 0; j < drawablep->getNumFaces(); ++j)
+ {
+ drawablep->updateFaceSize(j);
+
+ LLFace* facep = drawablep->getFace(j);
+ if ( !facep || !facep->hasGeometry())
+ {
+ continue;
+ }
+
+ if ((facep->getGeomCount() + vertex_count) <= 65536)
+ {
+ count++;
+ facep->mDistance = (facep->mCenterLocal - camera->getOrigin()) * camera->getAtAxis();
+ obj->mDepth += facep->mDistance;
+
+ mFaceList.push_back(facep);
+ vertex_count += facep->getGeomCount();
+ index_count += facep->getIndicesCount();
+ llassert(facep->getIndicesCount() < 65536);
+ }
+ else
+ {
+ facep->clearVertexBuffer();
+ }
+ }
+
+ obj->mDepth /= count;
+ }
+}
+
+static LLFastTimer::DeclareTimer FTM_REBUILD_GRASS_VB("Grass VB");
+
+void LLGrassPartition::getGeometry(LLSpatialGroup* group)
+{
+ LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
+ LLFastTimer ftm(FTM_REBUILD_GRASS_VB);
+
+ std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater());
+
+ U32 index_count = 0;
+ U32 vertex_count = 0;
+
+ group->clearDrawMap();
+
+ LLVertexBuffer* buffer = group->mVertexBuffer;
+
+ LLStrider<U16> indicesp;
+ LLStrider<LLVector4a> verticesp;
+ LLStrider<LLVector3> normalsp;
+ LLStrider<LLVector2> texcoordsp;
+ LLStrider<LLColor4U> colorsp;
+
+ buffer->getVertexStrider(verticesp);
+ buffer->getNormalStrider(normalsp);
+ buffer->getColorStrider(colorsp);
+ buffer->getTexCoord0Strider(texcoordsp);
+ buffer->getIndexStrider(indicesp);
+
+ LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[mRenderPass];
+
+ for (std::vector<LLFace*>::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i)
+ {
+ LLFace* facep = *i;
+ LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject();
+ facep->setGeomIndex(vertex_count);
+ facep->setIndicesIndex(index_count);
+ facep->setVertexBuffer(buffer);
+ facep->setPoolType(LLDrawPool::POOL_ALPHA);
+ object->getGeometry(facep->getTEOffset(), verticesp, normalsp, texcoordsp, colorsp, indicesp);
+
+ vertex_count += facep->getGeomCount();
+ index_count += facep->getIndicesCount();
+
+ S32 idx = draw_vec.size()-1;
+
+ BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
+ F32 vsize = facep->getVirtualSize();
+
+ if (idx >= 0 && draw_vec[idx]->mEnd == facep->getGeomIndex()-1 &&
+ draw_vec[idx]->mTexture == facep->getTexture() &&
+ (U16) (draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount()) <= (U32) gGLManager.mGLMaxVertexRange &&
+ //draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&
+ draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() < 4096 &&
+ draw_vec[idx]->mFullbright == fullbright)
+ {
+ draw_vec[idx]->mCount += facep->getIndicesCount();
+ draw_vec[idx]->mEnd += facep->getGeomCount();
+ draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
+ }
+ else
+ {
+ U32 start = facep->getGeomIndex();
+ U32 end = start + facep->getGeomCount()-1;
+ U32 offset = facep->getIndicesStart();
+ U32 count = facep->getIndicesCount();
+ LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(),
+ //facep->getTexture(),
+ buffer, fullbright);
+ info->mExtents[0] = group->mObjectExtents[0];
+ info->mExtents[1] = group->mObjectExtents[1];
+ info->mVSize = vsize;
+ draw_vec.push_back(info);
+ //for alpha sorting
+ facep->setDrawInfo(info);
+ }
+ }
+
+ buffer->flush();
+ mFaceList.clear();
+}
+
// virtual
void LLVOGrass::updateDrawable(BOOL force_damped)
{
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index 6ce93d641c..42b35ff7a7 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -48,6 +48,92 @@ const F32 MAX_PART_LIFETIME = 120.f;
extern U64 gFrameTime;
+LLPointer<LLVertexBuffer> LLVOPartGroup::sVB = NULL;
+S32 LLVOPartGroup::sVBSlotFree[];
+S32* LLVOPartGroup::sVBSlotCursor = NULL;
+
+//static
+void LLVOPartGroup::restoreGL()
+{
+ for (S32 i = 0; i < LL_MAX_PARTICLE_COUNT; ++i)
+ {
+ sVBSlotFree[i] = i;
+ }
+
+ sVBSlotCursor = sVBSlotFree;
+
+ sVB = new LLVertexBuffer(VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
+ U32 count = LL_MAX_PARTICLE_COUNT;
+ sVB->allocateBuffer(count*4, count*6, true);
+
+ //indices and texcoords are always the same, set once
+ LLStrider<U16> indicesp;
+
+ sVB->getIndexStrider(indicesp);
+
+ U16 vert_offset = 0;
+
+ for (U32 i = 0; i < LL_MAX_PARTICLE_COUNT; i++)
+ {
+ *indicesp++ = vert_offset + 0;
+ *indicesp++ = vert_offset + 1;
+ *indicesp++ = vert_offset + 2;
+
+ *indicesp++ = vert_offset + 1;
+ *indicesp++ = vert_offset + 3;
+ *indicesp++ = vert_offset + 2;
+
+ vert_offset += 4;
+ }
+
+ LLStrider<LLVector2> texcoordsp;
+ sVB->getTexCoord0Strider(texcoordsp);
+
+ for (U32 i = 0; i < LL_MAX_PARTICLE_COUNT; i++)
+ {
+ *texcoordsp++ = LLVector2(0.f, 1.f);
+ *texcoordsp++ = LLVector2(0.f, 0.f);
+ *texcoordsp++ = LLVector2(1.f, 1.f);
+ *texcoordsp++ = LLVector2(1.f, 0.f);
+ }
+
+ sVB->flush();
+
+}
+
+//static
+void LLVOPartGroup::destroyGL()
+{
+ sVB = NULL;
+}
+
+//static
+S32 LLVOPartGroup::findAvailableVBSlot()
+{
+ if (sVBSlotCursor >= sVBSlotFree+LL_MAX_PARTICLE_COUNT)
+ { //no more available slots
+ return -1;
+ }
+
+ S32 ret = *sVBSlotCursor;
+ sVBSlotCursor++;
+
+ return ret;
+}
+
+//static
+void LLVOPartGroup::freeVBSlot(S32 idx)
+{
+ llassert(idx < LL_MAX_PARTICLE_COUNT && idx >= 0);
+ llassert(sVBSlotCursor > sVBSlotFree);
+
+ if (sVBSlotCursor > sVBSlotFree)
+ {
+ sVBSlotCursor--;
+ *sVBSlotCursor = idx;
+ }
+}
+
LLVOPartGroup::LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
: LLAlphaObject(id, pcode, regionp),
mViewerPartGroupp(NULL)
@@ -62,7 +148,6 @@ LLVOPartGroup::~LLVOPartGroup()
{
}
-
BOOL LLVOPartGroup::isActive() const
{
return FALSE;
@@ -287,9 +372,6 @@ void LLVOPartGroup::getGeometry(S32 idx,
const LLViewerPart &part = *((LLViewerPart*) (mViewerPartGroupp->mParticles[idx]));
- U32 vert_offset = mDrawable->getFace(idx)->getGeomIndex();
-
-
LLVector4a part_pos_agent;
part_pos_agent.load3(part.mPosAgent.mV);
LLVector4a camera_agent;
@@ -361,33 +443,18 @@ void LLVOPartGroup::getGeometry(S32 idx,
verticesp->setAdd(ppamu, right);
(*verticesp++).getF32ptr()[3] = 0.f;
- //*verticesp++ = part_pos_agent + up - right;
- //*verticesp++ = part_pos_agent - up - right;
- //*verticesp++ = part_pos_agent + up + right;
- //*verticesp++ = part_pos_agent - up + right;
-
*colorsp++ = part.mColor;
*colorsp++ = part.mColor;
*colorsp++ = part.mColor;
*colorsp++ = part.mColor;
- *texcoordsp++ = LLVector2(0.f, 1.f);
- *texcoordsp++ = LLVector2(0.f, 0.f);
- *texcoordsp++ = LLVector2(1.f, 1.f);
- *texcoordsp++ = LLVector2(1.f, 0.f);
-
- *normalsp++ = normal;
- *normalsp++ = normal;
- *normalsp++ = normal;
- *normalsp++ = normal;
-
- *indicesp++ = vert_offset + 0;
- *indicesp++ = vert_offset + 1;
- *indicesp++ = vert_offset + 2;
-
- *indicesp++ = vert_offset + 1;
- *indicesp++ = vert_offset + 3;
- *indicesp++ = vert_offset + 2;
+ if (!(part.mFlags & LLPartData::LL_PART_EMISSIVE_MASK))
+ { //not fullbright, needs normal
+ *normalsp++ = normal;
+ *normalsp++ = normal;
+ *normalsp++ = normal;
+ *normalsp++ = normal;
+ }
}
U32 LLVOPartGroup::getPartitionType() const
@@ -412,6 +479,49 @@ LLHUDParticlePartition::LLHUDParticlePartition() :
mPartitionType = LLViewerRegion::PARTITION_HUD_PARTICLE;
}
+static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_VBO("Particle VBO");
+
+void LLParticlePartition::rebuildGeom(LLSpatialGroup* group)
+{
+ if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY))
+ {
+ return;
+ }
+
+ if (group->changeLOD())
+ {
+ group->mLastUpdateDistance = group->mDistance;
+ group->mLastUpdateViewAngle = group->mViewAngle;
+ }
+
+ LLFastTimer ftm(FTM_REBUILD_PARTICLE_VBO);
+
+ group->clearDrawMap();
+
+ //get geometry count
+ U32 index_count = 0;
+ U32 vertex_count = 0;
+
+ addGeometryCount(group, vertex_count, index_count);
+
+
+ if (vertex_count > 0 && index_count > 0)
+ {
+ group->mBuilt = 1.f;
+ //use one vertex buffer for all groups
+ group->mVertexBuffer = LLVOPartGroup::sVB;
+ getGeometry(group);
+ }
+ else
+ {
+ group->mVertexBuffer = NULL;
+ group->mBufferMap.clear();
+ }
+
+ group->mLastUpdateTime = gFrameTimeSeconds;
+ group->clearState(LLSpatialGroup::GEOM_DIRTY);
+}
+
void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count)
{
group->mBufferUsage = mBufferUsage;
@@ -431,11 +541,6 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co
LLAlphaObject* obj = (LLAlphaObject*) drawablep->getVObj().get();
obj->mDepth = 0.f;
- if (drawablep->isAnimating())
- {
- group->mBufferUsage = GL_STREAM_DRAW_ARB;
- }
-
U32 count = 0;
for (S32 j = 0; j < drawablep->getNumFaces(); ++j)
{
@@ -447,36 +552,28 @@ void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_co
continue;
}
- if ((facep->getGeomCount() + vertex_count) <= 65536)
- {
- count++;
- facep->mDistance = (facep->mCenterLocal - camera->getOrigin()) * camera->getAtAxis();
- obj->mDepth += facep->mDistance;
+ vertex_count += facep->getGeomCount();
+ index_count += facep->getIndicesCount();
+
+ count++;
+ facep->mDistance = (facep->mCenterLocal - camera->getOrigin()) * camera->getAtAxis();
+ obj->mDepth += facep->mDistance;
- mFaceList.push_back(facep);
- vertex_count += facep->getGeomCount();
- index_count += facep->getIndicesCount();
- llassert(facep->getIndicesCount() < 65536);
- }
- else
- {
- facep->clearVertexBuffer();
- }
+ mFaceList.push_back(facep);
+ llassert(facep->getIndicesCount() < 65536);
}
obj->mDepth /= count;
}
}
-static LLFastTimer::DeclareTimer FTM_REBUILD_GRASS_VB("Grass VB");
-static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_VB("Particle VB");
+
+static LLFastTimer::DeclareTimer FTM_REBUILD_PARTICLE_GEOM("Particle Geom");
void LLParticlePartition::getGeometry(LLSpatialGroup* group)
{
LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
- LLFastTimer ftm(mDrawableType == LLPipeline::RENDER_TYPE_GRASS ?
- FTM_REBUILD_GRASS_VB :
- FTM_REBUILD_PARTICLE_VB);
+ LLFastTimer ftm(FTM_REBUILD_PARTICLE_GEOM);
std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareDistanceGreater());
@@ -496,21 +593,43 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
buffer->getVertexStrider(verticesp);
buffer->getNormalStrider(normalsp);
buffer->getColorStrider(colorsp);
- buffer->getTexCoord0Strider(texcoordsp);
- buffer->getIndexStrider(indicesp);
-
+
LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[mRenderPass];
for (std::vector<LLFace*>::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i)
{
LLFace* facep = *i;
LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject();
- facep->setGeomIndex(vertex_count);
- facep->setIndicesIndex(index_count);
- facep->setVertexBuffer(buffer);
- facep->setPoolType(LLDrawPool::POOL_ALPHA);
- object->getGeometry(facep->getTEOffset(), verticesp, normalsp, texcoordsp, colorsp, indicesp);
+
+ if (facep->getIndicesStart() == 0xFFFFFFFF)
+ { //set the indices of this face
+ S32 idx = LLVOPartGroup::findAvailableVBSlot();
+ if (idx >= 0)
+ {
+ facep->setGeomIndex(idx*4);
+ facep->setIndicesIndex(idx*6);
+ facep->setVertexBuffer(LLVOPartGroup::sVB);
+ facep->setPoolType(LLDrawPool::POOL_ALPHA);
+ }
+ else
+ {
+ continue; //out of space in particle buffer
+ }
+ }
+
+ S32 geom_idx = (S32) facep->getGeomIndex();
+
+ object->getGeometry(facep->getTEOffset(),
+ verticesp+geom_idx,
+ normalsp+geom_idx,
+ texcoordsp+geom_idx,
+ colorsp+geom_idx,
+ indicesp+facep->getIndicesStart());
+ llassert(facep->getGeomCount() == 4);
+ llassert(facep->getIndicesCount() == 6);
+
+
vertex_count += facep->getGeomCount();
index_count += facep->getIndicesCount();
@@ -519,18 +638,31 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
F32 vsize = facep->getVirtualSize();
- if (idx >= 0 && draw_vec[idx]->mEnd == facep->getGeomIndex()-1 &&
+ bool batched = false;
+
+ if (idx >= 0 &&
draw_vec[idx]->mTexture == facep->getTexture() &&
- (U16) (draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount()) <= (U32) gGLManager.mGLMaxVertexRange &&
- //draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&
- draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() < 4096 &&
draw_vec[idx]->mFullbright == fullbright)
{
- draw_vec[idx]->mCount += facep->getIndicesCount();
- draw_vec[idx]->mEnd += facep->getGeomCount();
- draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
+ if (draw_vec[idx]->mEnd == facep->getGeomIndex()-1)
+ {
+ batched = true;
+ draw_vec[idx]->mCount += facep->getIndicesCount();
+ draw_vec[idx]->mEnd += facep->getGeomCount();
+ draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
+ }
+ else if (draw_vec[idx]->mStart == facep->getGeomIndex()+facep->getGeomCount()+1)
+ {
+ batched = true;
+ draw_vec[idx]->mCount += facep->getIndicesCount();
+ draw_vec[idx]->mStart -= facep->getGeomCount();
+ draw_vec[idx]->mOffset = facep->getIndicesStart();
+ draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
+ }
}
- else
+
+
+ if (!batched)
{
U32 start = facep->getGeomIndex();
U32 end = start + facep->getGeomCount()-1;
@@ -548,7 +680,6 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
}
}
- buffer->flush();
mFaceList.clear();
}
diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h
index e58fed86d9..dde0b0476d 100644
--- a/indra/newview/llvopartgroup.h
+++ b/indra/newview/llvopartgroup.h
@@ -31,12 +31,25 @@
#include "v3math.h"
#include "v3color.h"
#include "llframetimer.h"
+#include "llviewerpartsim.h"
+#include "llvertexbuffer.h"
class LLViewerPartGroup;
class LLVOPartGroup : public LLAlphaObject
{
public:
+
+ //vertex buffer for holding all particles
+ static LLPointer<LLVertexBuffer> sVB;
+ static S32 sVBSlotFree[LL_MAX_PARTICLE_COUNT];
+ static S32* sVBSlotCursor;
+
+ static void restoreGL();
+ static void destroyGL();
+ static S32 findAvailableVBSlot();
+ static void freeVBSlot(S32 idx);
+
enum
{
VERTEX_DATA_MASK = (1 << LLVertexBuffer::TYPE_VERTEX) |
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 93b6e9ae17..c40dafd433 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -3334,21 +3334,7 @@ void LLPipeline::postSort(LLCamera& camera)
rebuildPriorityGroups();
llpushcallstacks ;
- const S32 bin_count = 1024*8;
-
- static LLCullResult::drawinfo_list_t alpha_bins[bin_count];
- static U32 bin_size[bin_count];
-
- //clear one bin per frame to avoid memory bloat
- static S32 clear_idx = 0;
- clear_idx = (1+clear_idx)%bin_count;
- alpha_bins[clear_idx].clear();
-
- for (U32 j = 0; j < bin_count; j++)
- {
- bin_size[j] = 0;
- }
-
+
//build render map
for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
{
@@ -3425,6 +3411,10 @@ void LLPipeline::postSort(LLCamera& camera)
{
std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater());
}
+
+ //flush particle VB
+ LLVOPartGroup::sVB->flush();
+
llpushcallstacks ;
// only render if the flag is set. The flag is only set if we are in edit mode or the toggle is set in the menus
if (LLFloaterReg::instanceVisible("beacons") && !sShadowRender)
@@ -6239,11 +6229,15 @@ void LLPipeline::doResetVertexBuffers()
gSky.resetVertexBuffers();
+ LLVOPartGroup::destroyGL();
+
LLVertexBuffer::cleanupClass();
//delete all name pool caches
LLGLNamePool::cleanupPools();
+
+
if (LLVertexBuffer::sGLCount > 0)
{
llwarns << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << llendl;
@@ -6263,6 +6257,8 @@ void LLPipeline::doResetVertexBuffers()
LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind");
LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping);
+
+ LLVOPartGroup::restoreGL();
}
void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture, BOOL batch_texture)