Exemple #1
0
void LLDrawPoolWLSky::renderHeavenlyBodies()
{
	LLGLSPipelineSkyBox gls_skybox;
	LLGLEnable blend_on(GL_BLEND);
	gPipeline.disableLights();

#if 0 // when we want to re-add a texture sun disc, here's where to do it.
	LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_SUN];
	if (gSky.mVOSkyp->getSun().getDraw() && face->getGeomCount())
	{
		LLViewerTexture * tex  = face->getTexture();
		gGL.getTexUnit(0)->bind(tex);
		LLColor4 color(gSky.mVOSkyp->getSun().getInterpColor());
		LLFacePool::LLOverrideFaceColor color_override(this, color);
		face->renderIndexed();
	}
#endif

	LLFace * face = gSky.mVOSkyp->mFace[LLVOSky::FACE_MOON];

	if (gSky.mVOSkyp->getMoon().getDraw() && face->getGeomCount())
	{
		// *NOTE: even though we already bound this texture above for the
		// stars register combiners, we bind again here for defensive reasons,
		// since LLImageGL::bind detects that it's a noop, and optimizes it out.
		gGL.getTexUnit(0)->bind(face->getTexture());
		LLColor4 color(gSky.mVOSkyp->getMoon().getInterpColor());
		F32 a = gSky.mVOSkyp->getMoon().getDirection().mV[2];
		if (a > 0.f)
		{
			a = a*a*4.f;
		}
			
		color.mV[3] = llclamp(a, 0.f, 1.f);
		
		if (gPipeline.canUseVertexShaders())
		{
			gHighlightProgram.bind();
		}

		LLFacePool::LLOverrideFaceColor color_override(this, color);
		
		face->renderIndexed();

		if (gPipeline.canUseVertexShaders())
		{
			gHighlightProgram.unbind();
		}
	}
}
void LLParticlePartition::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;
			}
			
			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);
		}
		
		obj->mDepth /= count;
	}
}
void LLTerrainPartition::getGeometry(LLSpatialGroup* group)
{
	LLFastTimer ftm(FTM_REBUILD_TERRAIN_VB);

	LLVertexBuffer* buffer = group->mVertexBuffer;

	//get vertex buffer striders
	LLStrider<LLVector3> vertices;
	LLStrider<LLVector3> normals;
	LLStrider<LLVector2> texcoords2;
	LLStrider<LLVector2> texcoords;
	LLStrider<U16> indices;

	llassert_always(buffer->getVertexStrider(vertices));
	llassert_always(buffer->getNormalStrider(normals));
	llassert_always(buffer->getTexCoord0Strider(texcoords));
	llassert_always(buffer->getTexCoord1Strider(texcoords2));
	llassert_always(buffer->getIndexStrider(indices));

	U32 indices_index = 0;
	U32 index_offset = 0;

	for (std::vector<LLFace*>::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i)
	{
		LLFace* facep = *i;

		facep->setIndicesIndex(indices_index);
		facep->setGeomIndex(index_offset);
		facep->setVertexBuffer(buffer);

		LLVOSurfacePatch* patchp = (LLVOSurfacePatch*) facep->getViewerObject();
		patchp->getGeometry(vertices, normals, texcoords, texcoords2, indices);

		indices_index += facep->getIndicesCount();
		index_offset += facep->getGeomCount();
	}

	buffer->flush();
	mFaceList.clear();
}
void LLParticlePartition::getGeometry(LLSpatialGroup* group)
{
	LLFastTimer ftm(FTM_REBUILD_PARTICLE_GEOM);

	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;
	LLStrider<LLColor4U> emissivep;

	buffer->getVertexStrider(verticesp);
	buffer->getNormalStrider(normalsp);
	buffer->getColorStrider(colorsp);
	buffer->getEmissiveStrider(emissivep);

	
	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();

		if (!facep->isState(LLFace::PARTICLE))
		{ //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);
				facep->setState(LLFace::PARTICLE);
			}
			else
			{
				continue; //out of space in particle buffer
			}		
		}

		S32 geom_idx = (S32) facep->getGeomIndex();

		LLStrider<U16> cur_idx = indicesp + facep->getIndicesStart();
		LLStrider<LLVector4a> cur_vert = verticesp + geom_idx;
		LLStrider<LLVector3> cur_norm = normalsp + geom_idx;
		LLStrider<LLVector2> cur_tc = texcoordsp + geom_idx;
		LLStrider<LLColor4U> cur_col = colorsp + geom_idx;
		LLStrider<LLColor4U> cur_glow = emissivep + geom_idx;

		LLColor4U* start_glow = cur_glow.get();

		object->getGeometry(facep->getTEOffset(), cur_vert, cur_norm, cur_tc, cur_col, cur_glow, cur_idx);
		
		BOOL has_glow = FALSE;

		if (cur_glow.get() != start_glow)
		{
			has_glow = TRUE;
		}

		llassert(facep->getGeomCount() == 4);
		llassert(facep->getIndicesCount() == 6);


		vertex_count += facep->getGeomCount();
		index_count += facep->getIndicesCount();

		S32 idx = draw_vec.size()-1;

		BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
		F32 vsize = facep->getVirtualSize();

		bool batched = false;
	
		U32 bf_src = LLRender::BF_SOURCE_ALPHA;
		U32 bf_dst = LLRender::BF_ONE_MINUS_SOURCE_ALPHA;

		object->getBlendFunc(facep->getTEOffset(), bf_src, bf_dst);

		
		if (idx >= 0)
		{
			LLDrawInfo* info = draw_vec[idx];

			if (info->mTexture == facep->getTexture() &&
				info->mHasGlow == has_glow &&
				info->mFullbright == fullbright &&
				info->mBlendFuncDst == bf_dst &&
				info->mBlendFuncSrc == bf_src)
			{
				if (draw_vec[idx]->mEnd == facep->getGeomIndex()-1)
				{
					batched = true;
					info->mCount += facep->getIndicesCount();
					info->mEnd += facep->getGeomCount();
					info->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
				}
				else if (draw_vec[idx]->mStart == facep->getGeomIndex()+facep->getGeomCount()+1)
				{
					batched = true;
					info->mCount += facep->getIndicesCount();
					info->mStart -= facep->getGeomCount();
					info->mOffset = facep->getIndicesStart();
					info->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
				}
			}
		}


		if (!batched)
		{
			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); 
			const LLVector4a* bounds = group->getBounds();
			info->mExtents[0] = bounds[0];
			info->mExtents[1] = bounds[1];
			info->mVSize = vsize;
			info->mBlendFuncDst = bf_dst;
			info->mBlendFuncSrc = bf_src;
			info->mHasGlow = has_glow;
			info->mParticle = TRUE;
			draw_vec.push_back(info);
			//for alpha sorting
			facep->setDrawInfo(info);
		}

		if(facep->getGeomCount() > 0)
		{
			buffer->validateRange(facep->getGeomIndex(),  facep->getGeomIndex() + facep->getGeomCount() - 1, facep->getIndicesCount(), facep->getIndicesStart());
		}
	}

	mFaceList.clear();
}
void LLDrawPoolWater::render(S32 pass)
{
	LLFastTimer ftm(FTM_RENDER_WATER);
	if (mDrawFace.empty() || LLDrawable::getCurrentFrame() <= 1)
	{
		return;
	}

	//do a quick 'n dirty depth sort
	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
			 iter != mDrawFace.end(); iter++)
	{
		LLFace* facep = *iter;
		facep->mDistance = -facep->mCenterLocal.mV[2];
	}

	std::sort(mDrawFace.begin(), mDrawFace.end(), LLFace::CompareDistanceGreater());

	LLGLEnable blend(GL_BLEND);

	if ((mVertexShaderLevel > 0) && !sSkipScreenCopy)
	{
		shade();
		return;
	}

	LLVOSky *voskyp = gSky.mVOSkyp;

	stop_glerror();

	if (!gGLManager.mHasMultitexture)
	{
		// Ack!  No multitexture!  Bail!
		return;
	}

	LLFace* refl_face = voskyp->getReflFace();

	gPipeline.disableLights();
	
	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);

	LLGLDisable cullFace(GL_CULL_FACE);
	
	// Set up second pass first
	mWaterImagep->addTextureStats(1024.f*1024.f);
	gGL.getTexUnit(1)->activate();
	gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE);
	gGL.getTexUnit(1)->bind(mWaterImagep) ;

	LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis();
	F32 up_dot = camera_up * LLVector3::z_axis;

	LLColor4 water_color;
	if (LLViewerCamera::getInstance()->cameraUnderWater())
	{
		water_color.setVec(1.f, 1.f, 1.f, 0.4f);
	}
	else
	{
		water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot));
	}

	glColor4fv(water_color.mV);

	// Automatically generate texture coords for detail map
	glEnable(GL_TEXTURE_GEN_S); //texture unit 1
	glEnable(GL_TEXTURE_GEN_T); //texture unit 1
	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);

	// Slowly move over time.
	F32 offset = fmod(gFrameTimeSeconds*2.f, 100.f);
	F32 tp0[4] = {16.f/256.f, 0.0f, 0.0f, offset*0.01f};
	F32 tp1[4] = {0.0f, 16.f/256.f, 0.0f, offset*0.01f};
	glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0);
	glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1);

	gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
	gGL.getTexUnit(1)->setTextureAlphaBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_ALPHA);

	gGL.getTexUnit(0)->activate();
	
	glClearStencil(1);
	glClear(GL_STENCIL_BUFFER_BIT);
	LLGLEnable gls_stencil(GL_STENCIL_TEST);
	glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP);
	glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF);

	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
		 iter != mDrawFace.end(); iter++)
	{
		LLFace *face = *iter;
		if (voskyp->isReflFace(face))
		{
			continue;
		}
		gGL.getTexUnit(0)->bind(face->getTexture());
		face->renderIndexed();
	}

	// Now, disable texture coord generation on texture state 1
	gGL.getTexUnit(1)->activate();
	gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
	gGL.getTexUnit(1)->disable();
	glDisable(GL_TEXTURE_GEN_S); //texture unit 1
	glDisable(GL_TEXTURE_GEN_T); //texture unit 1

	// Disable texture coordinate and color arrays
	gGL.getTexUnit(0)->activate();
	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);

	stop_glerror();
	
	if (gSky.mVOSkyp->getCubeMap())
	{
		gSky.mVOSkyp->getCubeMap()->enable(0);
		gSky.mVOSkyp->getCubeMap()->bind();

		glMatrixMode(GL_TEXTURE);
		glLoadIdentity();
		LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview();
		LLMatrix4 camera_rot(camera_mat.getMat3());
		camera_rot.invert();

		glLoadMatrixf((F32 *)camera_rot.mMatrix);

		glMatrixMode(GL_MODELVIEW);
		LLOverrideFaceColor overrid(this, 1.f, 1.f, 1.f,  0.5f*up_dot);

		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);

		for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
			 iter != mDrawFace.end(); iter++)
		{
			LLFace *face = *iter;
			if (voskyp->isReflFace(face))
			{
				//refl_face = face;
				continue;
			}

			if (face->getGeomCount() > 0)
			{					
				face->renderIndexed();
			}
		}

		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);

		gSky.mVOSkyp->getCubeMap()->disable();
		
		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
		gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
		glMatrixMode(GL_TEXTURE);
		glLoadIdentity();
		glMatrixMode(GL_MODELVIEW);
		
	}

	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

    if (refl_face)
	{
		glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF);
		renderReflection(refl_face);
	}

	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
}
Exemple #6
0
void LLParticlePartition::getGeometry(LLSpatialGroup* group)
{
	LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
	LLFastTimer ftm(mDrawableType == LLPipeline::RENDER_TYPE_GRASS ?
					LLFastTimer::FTM_REBUILD_GRASS_VB :
					LLFastTimer::FTM_REBUILD_PARTICLE_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<LLVector3> 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->mVertexBuffer = 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(), 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->setBuffer(0);
	mFaceList.clear();
}
void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
{
	if (avatar->isSelf() && !gAgent.needsRenderAvatar() || !gMeshRepo.meshRezEnabled())
	{
		return;
	}

	stop_glerror();

	for (U32 i = 0; i < mRiggedFace[type].size(); ++i)
	{
		LLFace* face = mRiggedFace[type][i];
		LLDrawable* drawable = face->getDrawable();
		if (!drawable)
		{
			continue;
		}
		LLVOVolume* vobj = drawable->getVOVolume();

		if (!vobj)
		{
			continue;
		}
	
		LLVolume* volume = vobj->getVolume();
		S32 te = face->getTEOffset();

		if (!volume || volume->getNumVolumeFaces() <= te || !volume->isMeshAssetLoaded())
		{
			continue;
		}

		LLUUID mesh_id = volume->getParams().getSculptID();
		if (mesh_id.isNull())
		{
			continue;
		}

		const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(mesh_id, vobj);
		if (!skin)
		{
			continue;
		}

		stop_glerror();

		const LLVolumeFace& vol_face = volume->getVolumeFace(te);
		updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face, vobj);

		stop_glerror();

		U32 data_mask = LLFace::getRiggedDataMask(type);

		LLVertexBuffer* buff = face->getVertexBuffer();

		if (buff)
		{
			if (sShaderLevel > 0)
			{ //upload matrix palette to shader
				LLMatrix4 mat[64];

				for (U32 i = 0; i < skin->mJointNames.size(); ++i)
				{
					LLJoint* joint = avatar->getJoint(skin->mJointNames[i]);
					if (joint)
					{
						mat[i] = skin->mInvBindMatrix[i];
						mat[i] *= joint->getWorldMatrix();
					}
				}

				stop_glerror();

				LLDrawPoolAvatar::sVertexProgram->uniformMatrix4fv("matrixPalette",
																   skin->mJointNames.size(),
																   FALSE,
																   (GLfloat*) mat[0].mMatrix);

				stop_glerror();
			}
			else
			{
				data_mask &= ~LLVertexBuffer::MAP_WEIGHT4;
			}

			buff->setBuffer(data_mask);

			U16 start = face->getGeomStart();
			U16 end = start + face->getGeomCount()-1;
			S32 offset = face->getIndicesStart();
			U32 count = face->getIndicesCount();

			if (glow)
			{
				glColor4f(0,0,0,face->getTextureEntry()->getGlow());
			}

			gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture());
			if (normal_channel > -1)
			{
				LLDrawPoolBump::bindBumpMap(face, normal_channel);
			}

			if (face->mTextureMatrix)
			{
				glMatrixMode(GL_TEXTURE);
				glLoadMatrixf((F32*) face->mTextureMatrix->mMatrix);
				buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
				glLoadIdentity();
				glMatrixMode(GL_MODELVIEW);
			}
			else
			{
				buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
			}
		}
	}
}
void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
{
	if ((avatar->isSelf() && !gAgent.needsRenderAvatar()) || !gMeshRepo.meshRezEnabled())
	{
		return;
	}

	stop_glerror();

	for (U32 i = 0; i < mRiggedFace[type].size(); ++i)
	{
		LLFace* face = mRiggedFace[type][i];
		LLDrawable* drawable = face->getDrawable();
		if (!drawable)
		{
			continue;
		}

		LLVOVolume* vobj = drawable->getVOVolume();

		if (!vobj)
		{
			continue;
		}

		LLVolume* volume = vobj->getVolume();
		S32 te = face->getTEOffset();

		if (!volume || volume->getNumVolumeFaces() <= te || !volume->isMeshAssetLoaded())
		{
			continue;
		}

		LLUUID mesh_id = volume->getParams().getSculptID();
		if (mesh_id.isNull())
		{
			continue;
		}

		const LLMeshSkinInfo* skin = gMeshRepo.getSkinInfo(mesh_id, vobj);
		if (!skin)
		{
			continue;
		}

		//stop_glerror();

		//const LLVolumeFace& vol_face = volume->getVolumeFace(te);
		//updateRiggedFaceVertexBuffer(avatar, face, skin, volume, vol_face);
		
		//stop_glerror();

		U32 data_mask = LLFace::getRiggedDataMask(type);

		LLVertexBuffer* buff = face->getVertexBuffer();

		if (buff)
		{
			if (sShaderLevel > 0)
			{ //upload matrix palette to shader
				LLMatrix4 mat[JOINT_COUNT];

				U32 count = llmin((U32) skin->mJointNames.size(), (U32) JOINT_COUNT);

				for (U32 i = 0; i < count; ++i)
				{
					LLJoint* joint = avatar->getJoint(skin->mJointNames[i]);
					if(!joint)
					{
						joint = avatar->getJoint("mRoot");
					}
					if (joint)
					{
						LLMatrix4a tmp;
						tmp.loadu((F32*)skin->mInvBindMatrix[i].mMatrix);
						tmp.setMul(joint->getWorldMatrix(),tmp);
						mat[i] = LLMatrix4(tmp.getF32ptr());
					}
				}
				
				stop_glerror();

				F32 mp[JOINT_COUNT*12];

				for (U32 i = 0; i < count; ++i)
				{
					F32* m = (F32*) mat[i].mMatrix;

					U32 idx = i*12;

					mp[idx+0] = m[0];
					mp[idx+1] = m[1];
					mp[idx+2] = m[2];
					mp[idx+3] = m[12];

					mp[idx+4] = m[4];
					mp[idx+5] = m[5];
					mp[idx+6] = m[6];
					mp[idx+7] = m[13];

					mp[idx+8] = m[8];
					mp[idx+9] = m[9];
					mp[idx+10] = m[10];
					mp[idx+11] = m[14];
				}

				LLDrawPoolAvatar::sVertexProgram->uniformMatrix3x4fv(LLViewerShaderMgr::AVATAR_MATRIX, 
					count,
					FALSE,
					(GLfloat*) mp);

				LLDrawPoolAvatar::sVertexProgram->uniform1f(LLShaderMgr::AVATAR_MAX_WEIGHT, F32(count-1));
				
				stop_glerror();
			}
			else
			{
				data_mask &= ~LLVertexBuffer::MAP_WEIGHT4;
			}

			U16 start = face->getGeomStart();
			U16 end = start + face->getGeomCount()-1;
			S32 offset = face->getIndicesStart();
			U32 count = face->getIndicesCount();

			/*if (glow)
			{
				gGL.diffuseColor4f(0,0,0,face->getTextureEntry()->getGlow());
			}*/

			const LLTextureEntry* te = face->getTextureEntry();
			LLMaterial* mat = te->getMaterialParams().get();

			if (mat && is_deferred_render)
			{
				gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture(LLRender::DIFFUSE_MAP));
				gGL.getTexUnit(normal_channel)->bind(face->getTexture(LLRender::NORMAL_MAP));
				gGL.getTexUnit(specular_channel)->bind(face->getTexture(LLRender::SPECULAR_MAP));

				LLColor4 col = mat->getSpecularLightColor();
				F32 spec = llmax(0.0001f, mat->getSpecularLightExponent() / 255.f);

				F32 env = mat->getEnvironmentIntensity()/255.f;

				if (mat->getSpecularID().isNull())
				{
					env = te->getShiny()*0.25f;
					col.set(env,env,env,0);
					spec = env;
				}
		
				BOOL fullbright = te->getFullbright();

				sVertexProgram->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, fullbright ? 1.f : 0.f);
				sVertexProgram->uniform4f(LLShaderMgr::SPECULAR_COLOR, col.mV[0], col.mV[1], col.mV[2], spec);
				sVertexProgram->uniform1f(LLShaderMgr::ENVIRONMENT_INTENSITY, env);

				if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
				{
					sVertexProgram->setMinimumAlpha(mat->getAlphaMaskCutoff()/255.f);
				}
				else
				{
					sVertexProgram->setMinimumAlpha(0.004f);
				}

				for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i)
				{
					LLViewerTexture* tex = face->getTexture(i);
					if (tex)
					{
						tex->addTextureStats(avatar->getPixelArea());
					}
				}
			}
			else
			{
				gGL.getTexUnit(sDiffuseChannel)->bind(face->getTexture());

				if(sVertexProgram)
				{
					if (mat && mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
					{
						sVertexProgram->setMinimumAlpha(mat->getAlphaMaskCutoff()/255.f);
					}
					else
					{
						sVertexProgram->setMinimumAlpha(0.004f);
					}
				}

				if (normal_channel > -1)
				{
					LLDrawPoolBump::bindBumpMap(face, normal_channel);
				}
			}

			if (face->mTextureMatrix && vobj->mTexAnimMode)
			{
				gGL.matrixMode(LLRender::MM_TEXTURE);
				gGL.loadMatrix(*face->mTextureMatrix);
				buff->setBuffer(data_mask);
				buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);
				gGL.loadIdentity();
				gGL.matrixMode(LLRender::MM_MODELVIEW);
			}
			else
			{
				buff->setBuffer(data_mask);
				buff->drawRange(LLRender::TRIANGLES, start, end, count, offset);		
			}

			gPipeline.addTrianglesDrawn(count, LLRender::TRIANGLES);
		}
	}
}
BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
{
	LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WATER);
	LLFace *face;

	if (drawable->getNumFaces() < 1)
	{
		LLDrawPoolWater *poolp = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER);
		drawable->addFace(poolp, NULL);
	}
	face = drawable->getFace(0);

//	LLVector2 uvs[4];
//	LLVector3 vtx[4];

	LLStrider<LLVector3> verticesp, normalsp;
	LLStrider<LLVector2> texCoordsp;
	LLStrider<U16> indicesp;
	U16 index_offset;


	// A quad is 4 vertices and 6 indices (making 2 triangles)
	static const unsigned int vertices_per_quad = 4;
	static const unsigned int indices_per_quad = 6;

	static const LLCachedControl<bool> render_transparent_water("RenderTransparentWater",false);
	const S32 size = (render_transparent_water && !LLGLSLShader::sNoFixedFunction) ? 16 : 1;
	const S32 num_quads = size * size;
	face->setSize(vertices_per_quad * num_quads,
				  indices_per_quad * num_quads);
	
	LLVertexBuffer* buff = face->getVertexBuffer();
	if (!buff)
	{
		buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB);
		buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE);
		face->setIndicesIndex(0);
		face->setGeomIndex(0);
		face->setVertexBuffer(buff);
	}
	else
	{
		buff->resizeBuffer(face->getGeomCount(), face->getIndicesCount());
	}
		
	index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
		
	LLVector3 position_agent;
	position_agent = getPositionAgent();
	face->mCenterAgent = position_agent;
	face->mCenterLocal = position_agent;

	S32 x, y;
	F32 step_x = getScale().mV[0] / size;
	F32 step_y = getScale().mV[1] / size;

	const LLVector3 up(0.f, step_y * 0.5f, 0.f);
	const LLVector3 right(step_x * 0.5f, 0.f, 0.f);
	const LLVector3 normal(0.f, 0.f, 1.f);

	F32 size_inv = 1.f / size;

	for (y = 0; y < size; y++)
	{
		for (x = 0; x < size; x++)
		{
			S32 toffset = index_offset + 4*(y*size + x);
			position_agent = getPositionAgent() - getScale() * 0.5f;
			position_agent.mV[VX] += (x + 0.5f) * step_x;
			position_agent.mV[VY] += (y + 0.5f) * step_y;

			*verticesp++  = position_agent - right + up;
			*verticesp++  = position_agent - right - up;
			*verticesp++  = position_agent + right + up;
			*verticesp++  = position_agent + right - up;

			*texCoordsp++ = LLVector2(x*size_inv, (y+1)*size_inv);
			*texCoordsp++ = LLVector2(x*size_inv, y*size_inv);
			*texCoordsp++ = LLVector2((x+1)*size_inv, (y+1)*size_inv);
			*texCoordsp++ = LLVector2((x+1)*size_inv, y*size_inv);
			
			*normalsp++   = normal;
			*normalsp++   = normal;
			*normalsp++   = normal;
			*normalsp++   = normal;

			*indicesp++ = toffset + 0;
			*indicesp++ = toffset + 1;
			*indicesp++ = toffset + 2;

			*indicesp++ = toffset + 1;
			*indicesp++ = toffset + 3;
			*indicesp++ = toffset + 2;
		}
	}
	
	buff->flush();

	mDrawable->movePartition();
	LLPipeline::sCompiles++;
	return TRUE;
}
Exemple #10
0
BOOL LLVOGround::updateGeometry(LLDrawable *drawable)
{
	LLStrider<LLVector3> verticesp;
	LLStrider<LLVector3> normalsp;
	LLStrider<LLVector2> texCoordsp;
	LLStrider<U16> indicesp;
	S32 index_offset;
	LLFace *face;	

	LLDrawPoolGround *poolp = (LLDrawPoolGround*) gPipeline.getPool(LLDrawPool::POOL_GROUND);

	if (drawable->getNumFaces() < 1)
		drawable->addFace(poolp, NULL);
	face = drawable->getFace(0); 
		
	if (face->mVertexBuffer.isNull())
	{
		face->setSize(5, 12);
		face->mVertexBuffer = new LLVertexBuffer(LLDrawPoolGround::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB);
		face->mVertexBuffer->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE);
		face->setGeomIndex(0);
		face->setIndicesIndex(0);
	}
	
	index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
	if (-1 == index_offset)
	{
		return TRUE;
	}

	///////////////////////////////////////
	//
	//
	//
	LLVector3 at_dir = LLViewerCamera::getInstance()->getAtAxis();
	at_dir.mV[VZ] = 0.f;
	if (at_dir.normVec() < 0.01)
	{
		// We really don't care, as we're not looking anywhere near the horizon.
	}
	LLVector3 left_dir = LLViewerCamera::getInstance()->getLeftAxis();
	left_dir.mV[VZ] = 0.f;
	left_dir.normVec();

	// Our center top point
	LLColor4 ground_color = gSky.getFogColor();
	ground_color.mV[3] = 1.f;
	face->setFaceColor(ground_color);
	
	*(verticesp++)  = LLVector3(64, 64, 0);
	*(verticesp++)  = LLVector3(-64, 64, 0);
	*(verticesp++)  = LLVector3(-64, -64, 0);
	*(verticesp++)  = LLVector3(64, -64, 0);
	*(verticesp++)  = LLVector3(0, 0, -1024);
	
	
	// Triangles for each side
	*indicesp++ = index_offset + 0;
	*indicesp++ = index_offset + 1;
	*indicesp++ = index_offset + 4;

	*indicesp++ = index_offset + 1;
	*indicesp++ = index_offset + 2;
	*indicesp++ = index_offset + 4;

	*indicesp++ = index_offset + 2;
	*indicesp++ = index_offset + 3;
	*indicesp++ = index_offset + 4;

	*indicesp++ = index_offset + 3;
	*indicesp++ = index_offset + 0;
	*indicesp++ = index_offset + 4;

	*(texCoordsp++) = LLVector2(0.f, 0.f);
	*(texCoordsp++) = LLVector2(1.f, 0.f);
	*(texCoordsp++) = LLVector2(1.f, 1.f);
	*(texCoordsp++) = LLVector2(0.f, 1.f);
	*(texCoordsp++) = LLVector2(0.5f, 0.5f);
	
	face->mVertexBuffer->setBuffer(0);
	LLPipeline::sCompiles++;
	return TRUE;
}
void LLParticlePartition::getGeometry(LLSpatialGroup* group)
{
	LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION);
	LLFastTimer ftm(FTM_REBUILD_PARTICLE_GEOM);

	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);
	
	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();

		if (!facep->isState(LLFace::PARTICLE))
		{ //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);
				facep->setState(LLFace::PARTICLE);
			}
			else
			{
				continue; //out of space in particle buffer
			}		
		}

		S32 geom_idx = (S32) facep->getGeomIndex();

		LLStrider<U16> cur_idx = indicesp + facep->getIndicesStart();
		LLStrider<LLVector4a> cur_vert = verticesp + geom_idx;
		LLStrider<LLVector3> cur_norm = normalsp + geom_idx;
		LLStrider<LLVector2> cur_tc = texcoordsp + geom_idx;
		LLStrider<LLColor4U> cur_col = colorsp + geom_idx;

		object->getGeometry(facep->getTEOffset(), cur_vert, cur_norm, cur_tc, cur_col, cur_idx);
		
		llassert(facep->getGeomCount() == 4);
		llassert(facep->getIndicesCount() == 6);


		vertex_count += facep->getGeomCount();
		index_count += facep->getIndicesCount();

		S32 idx = draw_vec.size()-1;

		BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
		F32 vsize = facep->getVirtualSize();

		bool batched = false;
	
		if (idx >= 0 &&
			draw_vec[idx]->mTexture == facep->getTexture() &&
			draw_vec[idx]->mFullbright == fullbright)
		{
			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);
			}
		}


		if (!batched)
		{
			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);
		}
	}

	mFaceList.clear();
}
Exemple #12
0
BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
{
	LLFastTimer ftm(LLFastTimer::FTM_UPDATE_WATER);
	LLFace *face;

	if (drawable->getNumFaces() < 1)
	{
		LLDrawPoolWater *poolp = (LLDrawPoolWater*) gPipeline.getPool(LLDrawPool::POOL_WATER);
		drawable->addFace(poolp, NULL);
	}
	face = drawable->getFace(0);

//	LLVector2 uvs[4];
//	LLVector3 vtx[4];

	LLStrider<LLVector3> verticesp, normalsp;
	LLStrider<LLVector2> texCoordsp;
	LLStrider<U16> indicesp;
	U16 index_offset;

	S32 size = 16;

	S32 num_quads = size*size;	
	face->setSize(4*num_quads, 6*num_quads);

	if (face->mVertexBuffer.isNull())
	{
		face->mVertexBuffer = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB);
		face->mVertexBuffer->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE);
		face->setIndicesIndex(0);
		face->setGeomIndex(0);
	}
	else
	{
		face->mVertexBuffer->resizeBuffer(face->getGeomCount(), face->getIndicesCount());
	}
		
	index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp);
		
	LLVector3 position_agent;
	position_agent = getPositionAgent();
	face->mCenterAgent = position_agent;
	face->mCenterLocal = position_agent;

	S32 x, y;
	F32 step_x = getScale().mV[0] / size;
	F32 step_y = getScale().mV[1] / size;

	const LLVector3 up(0.f, step_y * 0.5f, 0.f);
	const LLVector3 right(step_x * 0.5f, 0.f, 0.f);
	const LLVector3 normal(0.f, 0.f, 1.f);

	F32 size_inv = 1.f / size;

	for (y = 0; y < size; y++)
	{
		for (x = 0; x < size; x++)
		{
			S32 toffset = index_offset + 4*(y*size + x);
			position_agent = getPositionAgent() - getScale() * 0.5f;
			position_agent.mV[VX] += (x + 0.5f) * step_x;
			position_agent.mV[VY] += (y + 0.5f) * step_y;

			*verticesp++  = position_agent - right + up;
			*verticesp++  = position_agent - right - up;
			*verticesp++  = position_agent + right + up;
			*verticesp++  = position_agent + right - up;

			*texCoordsp++ = LLVector2(x*size_inv, (y+1)*size_inv);
			*texCoordsp++ = LLVector2(x*size_inv, y*size_inv);
			*texCoordsp++ = LLVector2((x+1)*size_inv, (y+1)*size_inv);
			*texCoordsp++ = LLVector2((x+1)*size_inv, y*size_inv);
			
			*normalsp++   = normal;
			*normalsp++   = normal;
			*normalsp++   = normal;
			*normalsp++   = normal;

			*indicesp++ = toffset + 0;
			*indicesp++ = toffset + 1;
			*indicesp++ = toffset + 2;

			*indicesp++ = toffset + 1;
			*indicesp++ = toffset + 3;
			*indicesp++ = toffset + 2;
		}
	}
	
	face->mVertexBuffer->setBuffer(0);

	mDrawable->movePartition();
	LLPipeline::sCompiles++;
	return TRUE;
}