PageRenderTime 45ms CodeModel.GetById 13ms app.highlight 28ms RepoModel.GetById 1ms app.codeStats 0ms

/indra/newview/lldrawpool.cpp

https://bitbucket.org/lindenlab/viewer-beta/
C++ | 530 lines | 391 code | 76 blank | 63 comment | 41 complexity | 238561d6ca9f8eecc50af2435db09247 MD5 | raw file
  1/** 
  2 * @file lldrawpool.cpp
  3 * @brief LLDrawPool class implementation
  4 *
  5 * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  6 * Second Life Viewer Source Code
  7 * Copyright (C) 2010, Linden Research, Inc.
  8 * 
  9 * This library is free software; you can redistribute it and/or
 10 * modify it under the terms of the GNU Lesser General Public
 11 * License as published by the Free Software Foundation;
 12 * version 2.1 of the License only.
 13 * 
 14 * This library is distributed in the hope that it will be useful,
 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 17 * Lesser General Public License for more details.
 18 * 
 19 * You should have received a copy of the GNU Lesser General Public
 20 * License along with this library; if not, write to the Free Software
 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 22 * 
 23 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 24 * $/LicenseInfo$
 25 */
 26
 27#include "llviewerprecompiledheaders.h"
 28
 29#include "lldrawpool.h"
 30#include "llrender.h"
 31#include "llfasttimer.h"
 32#include "llviewercontrol.h"
 33
 34#include "lldrawable.h"
 35#include "lldrawpoolalpha.h"
 36#include "lldrawpoolavatar.h"
 37#include "lldrawpoolbump.h"
 38#include "lldrawpoolground.h"
 39#include "lldrawpoolsimple.h"
 40#include "lldrawpoolsky.h"
 41#include "lldrawpooltree.h"
 42#include "lldrawpoolterrain.h"
 43#include "lldrawpoolwater.h"
 44#include "llface.h"
 45#include "llviewerobjectlist.h" // For debug listing.
 46#include "pipeline.h"
 47#include "llspatialpartition.h"
 48#include "llviewercamera.h"
 49#include "lldrawpoolwlsky.h"
 50
 51S32 LLDrawPool::sNumDrawPools = 0;
 52
 53//=============================
 54// Draw Pool Implementation
 55//=============================
 56LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerTexture *tex0)
 57{
 58	LLDrawPool *poolp = NULL;
 59	switch (type)
 60	{
 61	case POOL_SIMPLE:
 62		poolp = new LLDrawPoolSimple();
 63		break;
 64	case POOL_GRASS:
 65		poolp = new LLDrawPoolGrass();
 66		break;
 67	case POOL_FULLBRIGHT:
 68		poolp = new LLDrawPoolFullbright();
 69		break;
 70	case POOL_INVISIBLE:
 71		poolp = new LLDrawPoolInvisible();
 72		break;
 73	case POOL_GLOW:
 74		poolp = new LLDrawPoolGlow();
 75		break;
 76	case POOL_ALPHA:
 77		poolp = new LLDrawPoolAlpha();
 78		break;
 79	case POOL_AVATAR:
 80		poolp = new LLDrawPoolAvatar();
 81		break;
 82	case POOL_TREE:
 83		poolp = new LLDrawPoolTree(tex0);
 84		break;
 85	case POOL_TERRAIN:
 86		poolp = new LLDrawPoolTerrain(tex0);
 87		break;
 88	case POOL_SKY:
 89		poolp = new LLDrawPoolSky();
 90		break;
 91	case POOL_VOIDWATER:
 92	case POOL_WATER:
 93		poolp = new LLDrawPoolWater();
 94		break;
 95	case POOL_GROUND:
 96		poolp = new LLDrawPoolGround();
 97		break;
 98	case POOL_BUMP:
 99		poolp = new LLDrawPoolBump();
100		break;
101	case POOL_WL_SKY:
102		poolp = new LLDrawPoolWLSky();
103		break;
104	default:
105		llerrs << "Unknown draw pool type!" << llendl;
106		return NULL;
107	}
108
109	llassert(poolp->mType == type);
110	return poolp;
111}
112
113LLDrawPool::LLDrawPool(const U32 type)
114{
115	mType = type;
116	sNumDrawPools++;
117	mId = sNumDrawPools;
118	mVertexShaderLevel = 0;
119}
120
121LLDrawPool::~LLDrawPool()
122{
123
124}
125
126LLViewerTexture *LLDrawPool::getDebugTexture()
127{
128	return NULL;
129}
130
131//virtual
132void LLDrawPool::beginRenderPass( S32 pass )
133{
134}
135
136//virtual 
137S32	 LLDrawPool::getNumPasses()
138{
139	return 1;
140}
141	
142//virtual 
143void LLDrawPool::beginDeferredPass(S32 pass)
144{
145
146}
147
148//virtual 
149void LLDrawPool::endDeferredPass(S32 pass)
150{
151
152}
153
154//virtual 
155S32 LLDrawPool::getNumDeferredPasses()
156{
157	return 0;
158}
159
160//virtual 
161void LLDrawPool::renderDeferred(S32 pass)
162{
163
164}
165
166//virtual 
167void LLDrawPool::beginPostDeferredPass(S32 pass)
168{
169
170}
171
172//virtual 
173void LLDrawPool::endPostDeferredPass(S32 pass)
174{
175
176}
177
178//virtual 
179S32 LLDrawPool::getNumPostDeferredPasses()
180{
181	return 0;
182}
183
184//virtual 
185void LLDrawPool::renderPostDeferred(S32 pass)
186{
187
188}
189
190//virtual
191void LLDrawPool::endRenderPass( S32 pass )
192{
193	/*for (U32 i = 0; i < gGLManager.mNumTextureImageUnits; i++)
194	{ //dummy cleanup of any currently bound textures
195		if (gGL.getTexUnit(i)->getCurrType() != LLTexUnit::TT_NONE)
196		{
197			gGL.getTexUnit(i)->unbind(gGL.getTexUnit(i)->getCurrType());
198			gGL.getTexUnit(i)->disable();
199		}
200	}*/
201
202	//make sure channel 0 is active channel
203	gGL.getTexUnit(0)->activate();
204}
205
206//virtual 
207void LLDrawPool::beginShadowPass(S32 pass)
208{
209
210}
211
212//virtual 
213void LLDrawPool::endShadowPass(S32 pass)
214{
215
216}
217
218//virtual 
219S32 LLDrawPool::getNumShadowPasses()
220{
221	return 0;
222}
223
224//virtual 
225void LLDrawPool::renderShadow(S32 pass)
226{
227
228}
229
230//=============================
231// Face Pool Implementation
232//=============================
233LLFacePool::LLFacePool(const U32 type)
234: LLDrawPool(type)
235{
236	resetDrawOrders();
237}
238
239LLFacePool::~LLFacePool()
240{
241	destroy();
242}
243
244void LLFacePool::destroy()
245{
246	if (!mReferences.empty())
247	{
248		llinfos << mReferences.size() << " references left on deletion of draw pool!" << llendl;
249	}
250}
251
252void LLFacePool::dirtyTextures(const std::set<LLViewerFetchedTexture*>& textures)
253{
254}
255
256// static
257S32 LLFacePool::drawLoop(face_array_t& face_list)
258{
259	S32 res = 0;
260	if (!face_list.empty())
261	{
262		for (std::vector<LLFace*>::iterator iter = face_list.begin();
263			 iter != face_list.end(); iter++)
264		{
265			LLFace *facep = *iter;
266			res += facep->renderIndexed();
267		}
268	}
269	return res;
270}
271
272// static
273S32 LLFacePool::drawLoopSetTex(face_array_t& face_list, S32 stage)
274{
275	S32 res = 0;
276	if (!face_list.empty())
277	{
278		for (std::vector<LLFace*>::iterator iter = face_list.begin();
279			 iter != face_list.end(); iter++)
280		{
281			LLFace *facep = *iter;
282			gGL.getTexUnit(stage)->bind(facep->getTexture(), TRUE) ;
283			gGL.getTexUnit(0)->activate();
284			res += facep->renderIndexed();
285		}
286	}
287	return res;
288}
289
290void LLFacePool::drawLoop()
291{
292	if (!mDrawFace.empty())
293	{
294		drawLoop(mDrawFace);
295	}
296}
297
298void LLFacePool::enqueue(LLFace* facep)
299{
300	mDrawFace.push_back(facep);
301}
302
303// virtual
304BOOL LLFacePool::addFace(LLFace *facep)
305{
306	addFaceReference(facep);
307	return TRUE;
308}
309
310// virtual
311BOOL LLFacePool::removeFace(LLFace *facep)
312{
313	removeFaceReference(facep);
314
315	vector_replace_with_last(mDrawFace, facep);
316
317	return TRUE;
318}
319
320// Not absolutely sure if we should be resetting all of the chained pools as well - djs
321void LLFacePool::resetDrawOrders()
322{
323	mDrawFace.resize(0);
324}
325
326LLViewerTexture *LLFacePool::getTexture()
327{
328	return NULL;
329}
330
331void LLFacePool::removeFaceReference(LLFace *facep)
332{
333	if (facep->getReferenceIndex() != -1)
334	{
335		if (facep->getReferenceIndex() != (S32)mReferences.size())
336		{
337			LLFace *back = mReferences.back();
338			mReferences[facep->getReferenceIndex()] = back;
339			back->setReferenceIndex(facep->getReferenceIndex());
340		}
341		mReferences.pop_back();
342	}
343	facep->setReferenceIndex(-1);
344}
345
346void LLFacePool::addFaceReference(LLFace *facep)
347{
348	if (-1 == facep->getReferenceIndex())
349	{
350		facep->setReferenceIndex(mReferences.size());
351		mReferences.push_back(facep);
352	}
353}
354
355BOOL LLFacePool::verify() const
356{
357	BOOL ok = TRUE;
358	
359	for (std::vector<LLFace*>::const_iterator iter = mDrawFace.begin();
360		 iter != mDrawFace.end(); iter++)
361	{
362		const LLFace* facep = *iter;
363		if (facep->getPool() != this)
364		{
365			llinfos << "Face in wrong pool!" << llendl;
366			facep->printDebugInfo();
367			ok = FALSE;
368		}
369		else if (!facep->verify())
370		{
371			ok = FALSE;
372		}
373	}
374
375	return ok;
376}
377
378void LLFacePool::printDebugInfo() const
379{
380	llinfos << "Pool " << this << " Type: " << getType() << llendl;
381}
382
383BOOL LLFacePool::LLOverrideFaceColor::sOverrideFaceColor = FALSE;
384
385void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4& color)
386{
387	gGL.diffuseColor4fv(color.mV);
388}
389
390void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4U& color)
391{
392	glColor4ubv(color.mV);
393}
394
395void LLFacePool::LLOverrideFaceColor::setColor(F32 r, F32 g, F32 b, F32 a)
396{
397	gGL.diffuseColor4f(r,g,b,a);
398}
399
400
401//=============================
402// Render Pass Implementation
403//=============================
404LLRenderPass::LLRenderPass(const U32 type)
405: LLDrawPool(type)
406{
407
408}
409
410LLRenderPass::~LLRenderPass()
411{
412
413}
414
415LLDrawPool* LLRenderPass::instancePool()
416{
417#if LL_RELEASE_FOR_DOWNLOAD
418	llwarns << "Attempting to instance a render pass.  Invalid operation." << llendl;
419#else
420	llerrs << "Attempting to instance a render pass.  Invalid operation." << llendl;
421#endif
422	return NULL;
423}
424
425void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture)
426{					
427	LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
428	
429	for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)	
430	{
431		LLDrawInfo *pparams = *k;
432		if (pparams) {
433			pushBatch(*pparams, mask, texture);
434		}
435	}
436}
437
438void LLRenderPass::renderTexture(U32 type, U32 mask)
439{
440	pushBatches(type, mask, TRUE);
441}
442
443void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures)
444{
445	for (LLCullResult::drawinfo_list_t::iterator i = gPipeline.beginRenderMap(type); i != gPipeline.endRenderMap(type); ++i)	
446	{
447		LLDrawInfo* pparams = *i;
448		if (pparams) 
449		{
450			pushBatch(*pparams, mask, texture, batch_textures);
451		}
452	}
453}
454
455void LLRenderPass::applyModelMatrix(LLDrawInfo& params)
456{
457	if (params.mModelMatrix != gGLLastMatrix)
458	{
459		gGLLastMatrix = params.mModelMatrix;
460		gGL.loadMatrix(gGLModelView);
461		if (params.mModelMatrix)
462		{
463			gGL.multMatrix((GLfloat*) params.mModelMatrix->mMatrix);
464		}
465		gPipeline.mMatrixOpCount++;
466	}
467}
468
469void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures)
470{
471	applyModelMatrix(params);
472
473	bool tex_setup = false;
474
475	if (texture)
476	{
477		if (batch_textures && params.mTextureList.size() > 1)
478		{
479			for (U32 i = 0; i < params.mTextureList.size(); ++i)
480			{
481				if (params.mTextureList[i].notNull())
482				{
483					gGL.getTexUnit(i)->bind(params.mTextureList[i], TRUE);
484				}
485			}
486		}
487		else
488		{ //not batching textures or batch has only 1 texture -- might need a texture matrix
489			if (params.mTexture.notNull())
490			{
491				params.mTexture->addTextureStats(params.mVSize);
492				gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ;
493				if (params.mTextureMatrix)
494				{
495					tex_setup = true;
496					gGL.getTexUnit(0)->activate();
497					gGL.matrixMode(LLRender::MM_TEXTURE);
498					gGL.loadMatrix((GLfloat*) params.mTextureMatrix->mMatrix);
499					gPipeline.mTextureMatrixOps++;
500				}
501			}
502			else
503			{
504				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
505			}
506		}
507	}
508	
509	if (params.mVertexBuffer.notNull())
510	{
511		if (params.mGroup)
512		{
513			params.mGroup->rebuildMesh();
514		}
515		params.mVertexBuffer->setBuffer(mask);
516		params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
517		gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
518	}
519
520	if (tex_setup)
521	{
522		gGL.loadIdentity();
523		gGL.matrixMode(LLRender::MM_MODELVIEW);
524	}
525}
526
527void LLRenderPass::renderGroups(U32 type, U32 mask, BOOL texture)
528{
529	gPipeline.renderGroups(this, type, mask, texture);
530}