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