void LLDrawPoolTree::render(S32 pass) { LLFastTimer t(LLPipeline::sShadowRender ? FTM_SHADOW_TREE : FTM_RENDER_TREES); if (mDrawFace.empty()) { return; } LLGLState test(GL_ALPHA_TEST, LLGLSLShader::sNoFixedFunction ? 0 : 1); LLOverrideFaceColor color(this, 1.f, 1.f, 1.f, 1.f); gGL.getTexUnit(sDiffTex)->bind(mTexturep); for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++) { LLFace *face = *iter; LLVertexBuffer* buff = face->getVertexBuffer(); if(buff) { buff->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); buff->drawRange(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0); gPipeline.addTrianglesDrawn(buff->getNumIndices()); } } }
void LLDrawPoolTree::render(S32 pass) { LLFastTimer t(LLPipeline::sShadowRender ? FTM_SHADOW_TREE : FTM_RENDER_TREES); if (mDrawFace.empty()) { return; } LLGLEnable test(GL_ALPHA_TEST); LLOverrideFaceColor color(this, 1.f, 1.f, 1.f, 1.f); if (gSavedSettings.getBOOL("RenderAnimateTrees")) { renderTree(); } else { gGL.getTexUnit(sDiffTex)->bind(mTexturep); for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++) { LLFace *face = *iter; LLVertexBuffer* buff = face->getVertexBuffer(); if(buff) { buff->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); buff->drawRange(LLRender::TRIANGLES, 0, buff->getRequestedVerts()-1, buff->getRequestedIndices(), 0); gPipeline.addTrianglesDrawn(buff->getRequestedIndices()); } } } }
void LLDrawPoolTree::render(S32 pass) { LLFastTimer t(LLPipeline::sShadowRender ? FTM_SHADOW_TREE : FTM_RENDER_TREES); if (mDrawFace.empty()) { return; } LLGLState test(GL_ALPHA_TEST, LLGLSLShader::sNoFixedFunction ? 0 : 1); LLOverrideFaceColor color(this, 1.f, 1.f, 1.f, 1.f); static LLCachedControl<bool> sRenderAnimateTrees("RenderAnimateTrees", false); if (sRenderAnimateTrees) { renderTree(); } else gGL.getTexUnit(sDiffTex)->bind(mTexturep); for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++) { LLFace *face = *iter; LLVertexBuffer* buff = face->getVertexBuffer(); if(buff) { LLMatrix4* model_matrix = &(face->getDrawable()->getRegion()->mRenderMatrix); if (model_matrix != gGLLastMatrix) { gGLLastMatrix = model_matrix; gGL.loadMatrix(gGLModelView); if (model_matrix) { llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW); gGL.multMatrix((GLfloat*) model_matrix->mMatrix); } gPipeline.mMatrixOpCount++; } buff->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); buff->drawRange(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0); gPipeline.addTrianglesDrawn(buff->getNumIndices()); } } }
void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face) { LLVector4a* weight = vol_face.mWeights; if (!weight) { return; } LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer(); LLDrawable* drawable = face->getDrawable(); U32 data_mask = face->getRiggedVertexBufferDataMask(); if (buffer.isNull() || buffer->getTypeMask() != data_mask || buffer->getNumVerts() != vol_face.mNumVertices || buffer->getNumIndices() != vol_face.mNumIndices || (drawable && drawable->isState(LLDrawable::REBUILD_ALL))) { if (drawable && drawable->isState(LLDrawable::REBUILD_ALL)) { //rebuild EVERY face in the drawable, not just this one, to avoid missing drawable wide rebuild issues for (S32 i = 0; i < drawable->getNumFaces(); ++i) { LLFace* facep = drawable->getFace(i); U32 face_data_mask = facep->getRiggedVertexBufferDataMask(); if (face_data_mask) { LLPointer<LLVertexBuffer> cur_buffer = facep->getVertexBuffer(); const LLVolumeFace& cur_vol_face = volume->getVolumeFace(i); getRiggedGeometry(facep, cur_buffer, face_data_mask, skin, volume, cur_vol_face); } } drawable->clearState(LLDrawable::REBUILD_ALL); buffer = face->getVertexBuffer(); } else { //just rebuild this face getRiggedGeometry(face, buffer, data_mask, skin, volume, vol_face); } } if (sShaderLevel <= 0 && face->mLastSkinTime < avatar->getLastSkinTime()) { avatar->updateSoftwareSkinnedVertices(skin, weight, vol_face, buffer); } }
void LLDrawPoolTree::renderTree(BOOL selecting) { LLGLState normalize(GL_NORMALIZE, TRUE); // Bind the texture for this tree. gGL.getTexUnit(sDiffTex)->bind(mTexturep.get(), TRUE); U32 indices_drawn = 0; glMatrixMode(GL_MODELVIEW); for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++) { LLFace *face = *iter; LLDrawable *drawablep = face->getDrawable(); if (drawablep->isDead() || !face->getVertexBuffer()) { continue; } face->getVertexBuffer()->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); U16* indicesp = (U16*) face->getVertexBuffer()->getIndicesPointer(); // Render each of the trees LLVOTree *treep = (LLVOTree *)drawablep->getVObj().get(); LLColor4U color(255,255,255,255); if (!selecting || treep->mGLName != 0) { if (selecting) { S32 name = treep->mGLName; color = LLColor4U((U8)(name >> 16), (U8)(name >> 8), (U8)name, 255); } gGLLastMatrix = NULL; glLoadMatrixd(gGLModelView); //glPushMatrix(); F32 mat[16]; for (U32 i = 0; i < 16; i++) mat[i] = (F32) gGLModelView[i]; LLMatrix4 matrix(mat); // Translate to tree base HACK - adjustment in Z plants tree underground const LLVector3 &pos_agent = treep->getPositionAgent(); //glTranslatef(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f); LLMatrix4 trans_mat; trans_mat.setTranslation(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ] - 0.1f); trans_mat *= matrix; // Rotate to tree position and bend for current trunk/wind // Note that trunk stiffness controls the amount of bend at the trunk as // opposed to the crown of the tree // const F32 TRUNK_STIFF = 22.f; LLQuaternion rot = LLQuaternion(treep->mTrunkBend.magVec()*TRUNK_STIFF*DEG_TO_RAD, LLVector4(treep->mTrunkBend.mV[VX], treep->mTrunkBend.mV[VY], 0)) * LLQuaternion(90.f*DEG_TO_RAD, LLVector4(0,0,1)) * treep->getRotation(); LLMatrix4 rot_mat(rot); rot_mat *= trans_mat; F32 radius = treep->getScale().magVec()*0.05f; LLMatrix4 scale_mat; scale_mat.mMatrix[0][0] = scale_mat.mMatrix[1][1] = scale_mat.mMatrix[2][2] = radius; scale_mat *= rot_mat; const F32 THRESH_ANGLE_FOR_BILLBOARD = 15.f; const F32 BLEND_RANGE_FOR_BILLBOARD = 3.f; F32 droop = treep->mDroop + 25.f*(1.f - treep->mTrunkBend.magVec()); S32 stop_depth = 0; F32 app_angle = treep->getAppAngle()*LLVOTree::sTreeFactor; F32 alpha = 1.0; S32 trunk_LOD = LLVOTree::sMAX_NUM_TREE_LOD_LEVELS; for (S32 j = 0; j < 4; j++) { if (app_angle > LLVOTree::sLODAngles[j]) { trunk_LOD = j; break; } } if(trunk_LOD >= LLVOTree::sMAX_NUM_TREE_LOD_LEVELS) { continue ; //do not render. } if (app_angle < (THRESH_ANGLE_FOR_BILLBOARD - BLEND_RANGE_FOR_BILLBOARD)) { // // Draw only the billboard // // Only the billboard, can use closer to normal alpha func. stop_depth = -1; LLFacePool::LLOverrideFaceColor clr(this, color); indices_drawn += treep->drawBranchPipeline(scale_mat, indicesp, trunk_LOD, stop_depth, treep->mDepth, treep->mTrunkDepth, 1.0, treep->mTwist, droop, treep->mBranches, alpha); } else // if (app_angle > (THRESH_ANGLE_FOR_BILLBOARD + BLEND_RANGE_FOR_BILLBOARD)) { // // Draw only the full geometry tree // //stop_depth = (app_angle < THRESH_ANGLE_FOR_RECURSION_REDUCTION); LLFacePool::LLOverrideFaceColor clr(this, color); indices_drawn += treep->drawBranchPipeline(scale_mat, indicesp, trunk_LOD, stop_depth, treep->mDepth, treep->mTrunkDepth, 1.0, treep->mTwist, droop, treep->mBranches, alpha); } //glPopMatrix(); } } }
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; }
void LLSprite::updateFace(LLFace &face) { LLViewerCamera &camera = *LLViewerCamera::getInstance(); // First, figure out how many vertices/indices we need. U32 num_vertices, num_indices; U32 vertex_count = 0; // Get the total number of vertices and indices if (mFollow) { num_vertices = 4; num_indices = 6; } else { num_vertices = 4; num_indices = 12; } face.setSize(num_vertices, num_indices); if (mFollow) { sCameraUp = camera.getUpAxis(); sCameraRight = -camera.getLeftAxis(); sCameraPosition = camera.getOrigin(); sNormal = -camera.getAtAxis(); if (mUseCameraUp) { // these need to live here because the height/width may change between render calls mScaledUp = sCameraUp; mScaledRight = sCameraRight; mScaledUp *= mHeightDiv2; mScaledRight *= mWidthDiv2; mA = mPosition + mScaledRight + mScaledUp; mB = mPosition - mScaledRight + mScaledUp; mC = mPosition - mScaledRight - mScaledUp; mD = mPosition + mScaledRight - mScaledUp; } else { // The up vector is perpendicular to the camera vector... LLVector3 camera_vec = mPosition - sCameraPosition; mScaledRight = camera_vec % LLVector3(0.f, 0.f, 1.f); mScaledUp = -(camera_vec % mScaledRight); mScaledUp.normalize(); mScaledRight.normalize(); mScaledUp *= mHeightDiv2; mScaledRight *= mWidthDiv2; mA = mPosition + mScaledRight + mScaledUp; mB = mPosition - mScaledRight + mScaledUp; mC = mPosition - mScaledRight - mScaledUp; mD = mPosition + mScaledRight - mScaledUp; } } else { // this is equivalent to how it was done before. . . // we need to establish a way to // identify the orientation of a particular sprite rather than // just banging it in on the x,z plane if it's not following the camera. LLVector3 x_axis; LLVector3 y_axis; F32 dot = sNormal * LLVector3(0.f, 1.f, 0.f); if (dot == 1.f || dot == -1.f) { x_axis.setVec(1.f, 0.f, 0.f); y_axis.setVec(0.f, 1.f, 0.f); } else { x_axis = sNormal % LLVector3(0.f, -1.f, 0.f); x_axis.normalize(); y_axis = sNormal % x_axis; } LLQuaternion yaw_rot(mYaw, sNormal); // rotate axes by specified yaw x_axis = x_axis * yaw_rot; y_axis = y_axis * yaw_rot; // rescale axes by width and height of sprite x_axis = x_axis * mWidthDiv2; y_axis = y_axis * mHeightDiv2; mA = -x_axis + y_axis; mB = x_axis + y_axis; mC = x_axis - y_axis; mD = -x_axis - y_axis; mA += mPosition; mB += mPosition; mC += mPosition; mD += mPosition; } face.setFaceColor(mColor); LLStrider<LLVector3> verticesp; LLStrider<LLVector3> normalsp; LLStrider<LLVector2> tex_coordsp; LLStrider<U16> indicesp; U16 index_offset; // Setup face if (!face.getVertexBuffer()) { LLVertexBuffer* buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, GL_STREAM_DRAW_ARB); buff->allocateBuffer(4, 12, TRUE); face.setGeomIndex(0); face.setIndicesIndex(0); face.setVertexBuffer(buff); } index_offset = face.getGeometry(verticesp,normalsp,tex_coordsp, indicesp); *tex_coordsp = LLVector2(0.f, 0.f); *verticesp = mC; tex_coordsp++; verticesp++; vertex_count++; *tex_coordsp = LLVector2(0.f, 1.f); *verticesp = mB; tex_coordsp++; verticesp++; vertex_count++; *tex_coordsp = LLVector2(1.f, 1.f); *verticesp = mA; tex_coordsp++; verticesp++; vertex_count++; *tex_coordsp = LLVector2(1.f, 0.0f); *verticesp = mD; tex_coordsp++; verticesp++; vertex_count++; // Generate indices, since they're easy. // Just a series of quads. *indicesp++ = index_offset; *indicesp++ = 2 + index_offset; *indicesp++ = 1 + index_offset; *indicesp++ = index_offset; *indicesp++ = 3 + index_offset; *indicesp++ = 2 + index_offset; if (!mFollow) { *indicesp++ = 0 + index_offset; *indicesp++ = 1 + index_offset; *indicesp++ = 2 + index_offset; *indicesp++ = 0 + index_offset; *indicesp++ = 2 + index_offset; *indicesp++ = 3 + index_offset; } face.getVertexBuffer()->setBuffer(0); face.mCenterAgent = mPosition; }
void LLDrawPoolTree::render(S32 pass) { LLFastTimer t(LLPipeline::sShadowRender ? FTM_SHADOW_TREE : FTM_RENDER_TREES); if (mDrawFace.empty()) { return; } LLGLState test(GL_ALPHA_TEST, LLGLSLShader::sNoFixedFunction ? 0 : 1); LLOverrideFaceColor color(this, 1.f, 1.f, 1.f, 1.f); gGL.getTexUnit(sDiffTex)->bind(mTexturep); for (std::vector<LLFace*>::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++) { LLFace *face = *iter; if(face->getViewerObject()) { LLVOTree* pTree = dynamic_cast<LLVOTree*>(face->getViewerObject()); if(pTree && !pTree->mDrawList.empty() ) { LLMatrix4a* model_matrix = &(face->getDrawable()->getRegion()->mRenderMatrix); gGL.loadMatrix(gGLModelView); gGL.multMatrix(*model_matrix); gPipeline.mMatrixOpCount++; for(std::vector<LLPointer<LLDrawInfo> >::iterator iter2 = pTree->mDrawList.begin(); iter2 != pTree->mDrawList.end(); iter2++) { LLDrawInfo& params = *iter2->get(); gGL.pushMatrix(); gGL.multMatrix(*params.mModelMatrix); gPipeline.mMatrixOpCount++; params.mVertexBuffer->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); gGL.popMatrix(); } continue; } } LLVertexBuffer* buff = face->getVertexBuffer(); if(buff) { LLMatrix4a* model_matrix = &(face->getDrawable()->getRegion()->mRenderMatrix); if(model_matrix && model_matrix->isIdentity()) { model_matrix = NULL; } if (model_matrix != gGLLastMatrix) { gGLLastMatrix = model_matrix; gGL.loadMatrix(gGLModelView); if (model_matrix) { llassert(gGL.getMatrixMode() == LLRender::MM_MODELVIEW); gGL.multMatrix(*model_matrix); } gPipeline.mMatrixOpCount++; } buff->setBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); buff->drawRange(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0); gPipeline.addTrianglesDrawn(buff->getNumIndices()); } } }
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->getVertexBuffer()) { face->setSize(5, 12); LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolGround::VERTEX_DATA_MASK, GL_STREAM_DRAW_ARB); buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE); face->setGeomIndex(0); face->setIndicesIndex(0); face->setVertexBuffer(buff); } 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->getVertexBuffer()->flush(); LLPipeline::sCompiles++; return TRUE; }